Author Topic: Accessing external memory  (Read 13011 times)

Offline Henry

  • Newbie
  • *
  • Posts: 6
    • View Profile
Accessing external memory
« on: August 03, 2010, 01:18:33 PM »
Hi,

I am using the Rowley-(LPC2378)-project with the LPC2468-16 OEM board from Embedded Artists.
The problem is that I cannot write to external SDRAM located in the range of 0xA0000000...0xAFFFFFFF.

I have modified the linker script like this, which is similar to a modification for the internal USB RAM, which is ok:
Code: [Select]
MEMORY
{
/*
Some other memory segments here  ....
*/
  EXTERNAL_SDRAM (wx) : ORIGIN = 0xA0000000, LENGTH = 0x02000000  /* für EA-Board hinzugefügt, bss2-Segment am  Dateiende */
}

SECTIONS
{
/*
Some other sections here ....
*/
  __EXTERNAL_SDRAM_segment_start__ = 0xA0000000;              
  __EXTERNAL_SDRAM_segment_end__  =  0xA2000000;
/*----------------------------------------------------------------*/
  __bss2_load_start__ = ALIGN(__EXTERNAL_SDRAM_segment_start__ , 4);
  .bss2 ALIGN(__EXTERNAL_SDRAM_segment_start__ , 4) (NOLOAD) :
  {
    __bss2_start__ = .;
    *(.bss2 .bss2.* .gnu.linkonce.b.*) *(COMMON)
  }
  __bss2_end__ = __bss2_start__ + SIZEOF(.bss2);

  . = ASSERT(__bss2_end__ <= __EXTERNAL_SDRAM_segment_end__ && __bss2_end__ >= (__EXTERNAL_SDRAM_segment_start__) , "error: .bss2 is too large to fit in EXTERNAL_SDRAM memory segment");

}


Are additional considerations required for external memory?

While the structures / buffers are assigned to the correct memory range, it is not possible to write to that memory.
I suppose that the reason for this has something to do with the specific project, because there is another project (ARM, not THUMB mode) which does fine.

Does anybody know how to solve this problem?

Regards,

Henry

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3238
    • View Profile
    • uTasker
Re: Accessing external memory
« Reply #1 on: August 03, 2010, 03:02:52 PM »
Hi Henry

The LPC24XX has an external memory interface which can also be used with SDRAM.
Before it is used it needs to be initialised (the external memory pins configured and the SD RAM controller set up to match the RAM used - are you sure that this configuration has taken place?

Below is an example of configuration taken from the LPC2478 TFT project. This initialises for the Olimex board, which may be the same but may also need adjustments(?)

Regards

Mark

Code: [Select]
// SDRAM initialisation
//
static void fnInit_SDRAM(void)
{
    volatile unsigned long ulDelay;

    // Configure the SDRAM pins
    //
    PINSEL5  |= (PINSEL5_P2_16_CAS | PINSEL5_P2_17_RAS | PINSEL5_P2_18_CLKOUT0 | PINSEL5_P2_20_DYCS0 | PINSEL5_P2_24_CKEOUT1 | PINSEL5_P2_28_DQMOUT0 | PINSEL5_P2_29_DQMOUT1); // assign the pins required by the SDRAM controller
    PINMODE5 |= (PINMODE_NO_PULLS_16 | PINMODE_NO_PULLS_17 | PINMODE_NO_PULLS_18 | PINMODE_NO_PULLS_20 | PINMODE_NO_PULLS_24 | PINMODE_NO_PULLS_28 | PINMODE_NO_PULLS_29);
    PINSEL6   = (PINSEL6_P3_0_D0 | PINSEL6_P3_1_D1 | PINSEL6_P3_2_D2 | PINSEL6_P3_3_D3 | PINSEL6_P3_4_D4 | PINSEL6_P3_5_D5 | PINSEL6_P3_6_D6 | PINSEL6_P3_7_D7 | PINSEL6_P3_8_D8 | PINSEL6_P3_9_D9 | PINSEL6_P3_10_D10 | PINSEL6_P3_11_D11 | PINSEL6_P3_12_D12 | PINSEL6_P3_13_D13 | PINSEL6_P3_14_D14 | PINSEL6_P3_15_D15); // data lines D0..D15
    PINMODE6  = (PINMODE_NO_PULLS_0 | PINMODE_NO_PULLS_1 | PINMODE_NO_PULLS_2 | PINMODE_NO_PULLS_3 | PINMODE_NO_PULLS_4 | PINMODE_NO_PULLS_5 | PINMODE_NO_PULLS_6 | PINMODE_NO_PULLS_7 | PINMODE_NO_PULLS_8 | PINMODE_NO_PULLS_9 | PINMODE_NO_PULLS_10 | PINMODE_NO_PULLS_11 | PINMODE_NO_PULLS_12 | PINMODE_NO_PULLS_13 | PINMODE_NO_PULLS_14 | PINMODE_NO_PULLS_15);
    PINSEL8  |= (PINSEL8_P4_0_A0 | PINSEL8_P4_1_A1 | PINSEL8_P4_2_A2 | PINSEL8_P4_3_A3 | PINSEL8_P4_4_A4 | PINSEL8_P4_5_A5 | PINSEL8_P4_6_A6 | PINSEL8_P4_7_A7 | PINSEL8_P4_8_A8 | PINSEL8_P4_9_A9 | PINSEL8_P4_10_A10 | PINSEL8_P4_11_A11 | PINSEL8_P4_12_A12 | PINSEL8_P4_13_A13 | PINSEL8_P4_14_A14); // address lines A0..A14
    PINMODE8 |= (PINMODE_NO_PULLS_0 | PINMODE_NO_PULLS_1 | PINMODE_NO_PULLS_2 | PINMODE_NO_PULLS_3 | PINMODE_NO_PULLS_4 | PINMODE_NO_PULLS_5 | PINMODE_NO_PULLS_6 | PINMODE_NO_PULLS_7 | PINMODE_NO_PULLS_8 | PINMODE_NO_PULLS_9 | PINMODE_NO_PULLS_10 | PINMODE_NO_PULLS_11 | PINMODE_NO_PULLS_12 | PINMODE_NO_PULLS_13 | PINMODE_NO_PULLS_14);
    PINSEL9  |= (PINSEL9_P4_25_WE);
    PINMODE9 |= (PINMODE_NO_PULLS_25);
   
    EMCControl           = EMC_ENABLE;                                   // initialise the SDRAM controller and enable EMC clock
    EMCDynamicReadConfig = READ_DATA_STRATEGY_CMD_DLY;
    EMCDynamicRasCas0    = (RAS_LATENCY_THREE_CCLK | CAS_LATENCY_THREE_CCLK);
    EMCDynamicRP         = CALC_PERIOD(SDRAM_TRP);
    EMCDynamicRAS        = CALC_PERIOD(SDRAM_TRAS);
    EMCDynamicSREX       = CALC_PERIOD(SDRAM_TXSR);
    EMCDynamicAPR        = SDRAM_TAPR;
    EMCDynamicDAL        = SDRAM_TDAL + CALC_PERIOD(SDRAM_TRP);
    EMCDynamicWR         = SDRAM_TWR;
    EMCDynamicRC         = CALC_PERIOD(SDRAM_TRC);
    EMCDynamicRFC        = CALC_PERIOD(SDRAM_TRFC);
    EMCDynamicXSR        = CALC_PERIOD(SDRAM_TXSR);
    EMCDynamicRRD        = CALC_PERIOD(SDRAM_TRRD);
    EMCDynamicMRD        = SDRAM_TMRD;
    EMCDynamicConfig0    = ADDRESS_MAP_16M_16BIT;                        // 13 row, 9 - col, SDRAM

    // SDRAM initialisation sequence
    //
    EMCDynamicControl = (SDRAM_NOP_CMD | DYNAMIC_CLKOUT_CONTINUOUS | DYNAMIC_MEM_CLK_EN);
    ulDelay = (200*30);
    while (ulDelay--) {}
    EMCDynamicControl = (SDRAM_PRECHARGE_ALL_CMD | DYNAMIC_CLKOUT_CONTINUOUS | DYNAMIC_MEM_CLK_EN); // PALL
    EMCDynamicRefresh = 1;
    ulDelay = 128;
    while (ulDelay--) {}                                                 // 128 clock delay
    EMCDynamicRefresh = CALC_PERIOD(SDRAM_REFRESH) >> 4;
    EMCDynamicControl = (SDRAM_MODE_CMD | DYNAMIC_CLKOUT_CONTINUOUS | DYNAMIC_MEM_CLK_EN); // COMM
    ulDelay = *(volatile unsigned short *)fnGetSDRAM((unsigned char *)(SDRAM_ADDR + (0x33UL << (12)))); // burst 8, sequential, CAS-2
    EMCDynamicControl = 0;                                               // NORM
    EMCDynamicConfig0 |= CS_BUFFER_ENABLE;
}

Offline Henry

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Accessing external memory
« Reply #2 on: August 04, 2010, 01:57:43 PM »
Hi Mark,

this routine is identical to the one in TFT.c of the Rowley project.
I added
  PCONP |=  PCEMC;
and now the problem is solved.

Thank you very much for your immediate help!

Regards,
Henry