cancel
Showing results for 
Search instead for 
Did you mean: 

How to read and write form/to SDRAM MEMORY in STM32f429 controller

ashwinidigajerla
Associate II
Posted on April 25, 2014 at 08:27

stm32f429-DISCO board have 8MB of on chip SDRAM module.I want to interface SDRAM chip to microcontroller.I finished the initilization part.Now I wish to write and read data from it.

8MB SDRAM memory was organized as 4 internal banks 1MB each.How i write/read to total

 8MB with Single write/read command to SDRAM instead of individual internal bank Access.

Thank you

#whiskey-tango-foxtrot
25 REPLIES 25
glory_man
Associate II
Posted on April 25, 2014 at 09:04

http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF259090

you can find documents and software examples for your board. For example,

http://www.st.com/web/en/catalog/tools/PF259429

,

contains

an example

of SDRAM manipulation -

stsw-stm32138.zip\STM32F429I-Discovery_FW_V1.0.1\Projects\Peripheral_Examples\FMC_SDRAM. This examples uses FMC-controller to interface with the SDRAM memory. After SDRAM initialization you can read/write/erase data in to any memory cell.

Posted on April 25, 2014 at 18:43

It accesses just like ANY other memory space within the microprocessors purview.

For the STM32F429I-DISCO, the SDRAM is situated at 0xD0000000

unsigned char *sdram = (unsigned char *)0xD0000000;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ashwinidigajerla
Associate II
Posted on April 26, 2014 at 07:05

Thank you.I got clarity reading and wriring from base address.

By reading the sdram data sheet I understood that total memory is bank oriented with 4 internal banks in rows and column format ,to aceess any memory location  we need to send internal bank address,row and colum address with GPIO pins in alternate fun mode.

My doubt is to aceess any location every time do i need to send all above address or is there any AUTO INCREMENT OF BASE ADDRESS WHILE READ/WRITE.YOUR ANSWER WILL MORE HELP ME.

Posted on April 26, 2014 at 14:40

The SDRAM Geometry is configured in the initialization code, it appears to the programmer as a linear 8MB region.

// STM32F429 SDRAM - sourcer32@gmail.com
#include <
stdio.h
>
#include <
stdlib.h
>
#include <
string.h
>
#include ''stm32f429i_discovery.h''
#include ''stm32f429i_discovery_sdram.h''
#define BANK2 // DISCO
// STM32F429I-DISCO Bank2
// STM32F4x9I-EVAL Bank1
// Bank1 Bank2
// 0xC0000000 0xD0000000 256MB
// 0xCFFFFFFF 0xDFFFFFFF
// 0x00000000 0x04000000 64MB
// 0x03FFFFFF 0x07FFFFFF
#define IS42S16400J_SIZE 0x400000
#ifdef BANK1
#define SDRAM_ADDR 0xC0000000
#define SDRAM_ADDR_SWP 0x80000000
#define SDRAM_BANK FMC_Bank1_SDRAM
#endif // BANK1
#ifdef BANK2
#define SDRAM_ADDR 0xD0000000
#define SDRAM_ADDR_SWP 0x90000000
#define SDRAM_BANK FMC_Bank2_SDRAM
#endif // BANK2
/**************************************************************************/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
int i;
unsigned long *sdram = (unsigned long *)SDRAM_ADDR;
/*!< 
At
this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
files (startup_stm32f429_439xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* Add your application code here */
/* SDRAM Initialization */
SDRAM_Init();
// /* FMC SDRAM GPIOs Configuration */
// SDRAM_GPIOConfig(); // SDRAM_Init() should do this
/* Disable write protection */
FMC_SDRAMWriteProtectionConfig(SDRAM_BANK, DISABLE);
for(
i
=
0
; i<10; i++) // Front, Random
{
printf(''%08X '', sdram[i]);
if ((i % 5) == 4)
putchar('
');
}
putchar('
');
for(
i
=
0
; i<0x200000; i++) // 8MB in 32-bit words
sdram[i] = i;
for(
i
=
0
; i<10; i++) // Front
{
printf(''%08X '', sdram[i]);
if ((i % 5) == 4)
putchar('
');
}
putchar('
');
for(
i
=
0
; i<10; i++) // Back
{
printf(''%08X '', sdram[i+0x1FFFF6]);
if ((i % 5) == 4)
putchar('
');
}
putchar('
');
// Check SDRAM Read-back
for(
i
=
0
; i<0x200000; i++) // 8MB in 32-bit words
if (sdram[i] != i)
{
puts(''SDRAM Fails!!'');
break;
}
/* Infinite loop */
while (1)
{
}
}
//******************************************************************************
// Hosting of stdio functionality through ITM/SWV
//******************************************************************************
#include <rt_misc.h>
#pragma import(__use_no_semihosting_swi)
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
ITM_SendChar(ch);
return(ch);
}
int fgetc(FILE *f)
{
char ch = 0;
return((int)ch);
}
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
ITM_SendChar(ch);
}
void _sys_exit(int return_code)
{
label: goto label; /* endless loop */
}
//******************************************************************************
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
//******************************************************************************

See also STM32F429I-Discovery_FW_V1.0.1\Projects\Peripheral_Examples\FMC_SDRAM eadme.txt STM32F429I-Discovery_FW_V1.0.1\Utilities\STM32F429I-Discovery\stm32f429i_discovery_sdram.c STM32F4xx_DSP_StdPeriph_Lib_V1.3.0\Project\STM32F4xx_StdPeriph_Examples\FMC\FMC_SDRAM_xxxx
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ashwinidigajerla
Associate II
Posted on April 28, 2014 at 13:55

thank you very much clive1.

I am the beginner of  writing micro controller programming .

->All the gpio pins used for SDRAM ,I configured as the FMC alternate function mode.

     I choosen Alternate function mode,pushpull,speed,pullpu/pull down for PINS.Is it enough         or Shall I do set/reset to the pins.

   How i send prechrege ,self refresh,nooperation commands to the SDRAM.By using                   command  register or by controlling  gpio pins

THANK YOU IN ADVANCE

Posted on April 28, 2014 at 15:53

Please review the cited code.

Like all SDRAM the internal parameters are configured by writing to specific address/data spaces of the device.

The geometry and timing parameters are programmed into the controller.

STM32F4xx_DSP_StdPeriph_Lib_V1.3.0\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval_fmc_sdram.c

SDRAM_Init(); // Pins, Clocks, Controller, Chip

SDRAM_GPIOConfig(); // Pins

SDRAM_InitSequence(); // SDRAM Chip Internals
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ashwinidigajerla
Associate II
Posted on May 05, 2014 at 14:24

hai clave here i am attached my sdram code.will u please check it and give any information  if possible.

reading and writing from base address 0xd0000000.Then what is the use of address and data pins.

do i need to send row address,column address,bank address using pins?

please clarify me.

void FMC_SDRAM_Init(UINT8 U8_Bank)

{

UINT32 temp1=0,temp2=0,temp3=0;

UINT8 u8_i = 0;

ST_pFMC_REGS_Ptr_t->FMC_SDCR1 = FMCSDRAM_CR1_CR2_REG_RESET;

ST_pFMC_REGS_Ptr_t->FMC_SDCR2 = FMCSDRAM_CR1_CR2_REG_RESET;

ST_pFMC_REGS_Ptr_t->FMC_SDTR1 = FMCSDRAM_TR1_TR2_REG_RESET ;

    ST_pFMC_REGS_Ptr_t->FMC_SDTR2 = FMCSDRAM_TR1_TR2_REG_RESET;

                    Gpioclk_Init(GPIO_PORTA);

   Gpioclk_Init(GPIO_PORTB);

   Gpioclk_Init(GPIO_PORTC);

   Gpioclk_Init(GPIO_PORTD);

   Gpioclk_Init(GPIO_PORTE);

   Gpioclk_Init(GPIO_PORTF);

   Gpioclk_Init(GPIO_PORTG);

   Gpioclk_Init(GPIO_PORTH);

   Gpioclk_Init(GPIO_PORTI);

   RCC_AHBPeripheralEnable(AHB_FSMC);

while(En_SDRAM_ConfigPort_List_t[u8_i] != 0)

{

Sdram_Gpio_Pin_Config(En_SDRAM_ConfigPort_List_t[u8_i],SDRAM_ConfigPin_List[u8_i],GPIO_MODER_ALTFUN_MASK,GPIO_OTYPE_PP,GPIO_OSPEEDR_MEDIUM_MASK,GPIO_PUPD_NOPULL,ALTFUN_FMC);

u8_i++;

}

           temp1 = (UINT32)(FMC_SDCR1_ROW_ADDRWIDTH_12|FMC_SDCR1_COLUM_ADDRWIDTH_8|FMC_SDCR1_MWIDTH_16|FMC_SDCR1_INTRNLBANKS_4|

        FMC_SDCR1_3CAS_LATENCY|FMC_SDCR1_WP_EN|FMC_SDCR1_RPIPE_1HCLK|FMC_SDCR1_RBURST_ENABLE|FMC_SDCR1_2HCLKPERIOD);

       temp2= (UINT32)(FMC_SDTR1_TRCD_2|FMC_SDTR1_TRP_2|FMC_SDTR1_TWR_2|FMC_SDTR1_TRC_6|FMC_SDTR1_TRAS_4|FMC_SDTR1_TXSR_7

        |FMC_SDTR1_TMRD_2);

           if(U8_Bank ==SDRAM_BANK1)

           {

       ST_pFMC_REGS_Ptr_t->FMC_SDCR1 = temp1;

                ST_pFMC_REGS_Ptr_t->FMC_SDTR1 = temp2;

           }

           else

           {

                ST_pFMC_REGS_Ptr_t->FMC_SDCR1 = FMC_SDCR1_2HCLKPERIOD|FMC_SDCR1_RBURST_ENABLE|FMC_SDCR1_RPIPE_1HCLK;

                ST_pFMC_REGS_Ptr_t->FMC_SDCR2 = (UINT32)(FMC_SDCR1_ROW_ADDRWIDTH_12|FMC_SDCR1_COLUM_ADDRWIDTH_8|FMC_SDCR1_MWIDTH_16|FMC_SDCR1_INTRNLBANKS_4|

                                FMC_SDCR1_3CAS_LATENCY);

                ST_pFMC_REGS_Ptr_t->FMC_SDTR1 = FMC_SDTR1_TRC_6|FMC_SDTR1_TRP_2;

                ST_pFMC_REGS_Ptr_t->FMC_SDTR2 = FMC_SDTR1_TRCD_2 |FMC_SDTR1_TWR_2|FMC_SDTR1_TRAS_4|FMC_SDTR1_TXSR_7|FMC_SDTR1_TMRD_2;

       }

           while( ST_pFMC_REGS_Ptr_t->FMC_SDSR & (FMC_SDSR_BUSY_FLOG));

           ST_pFMC_REGS_Ptr_t->FMC_SDCMR = FMC_SDCMD_CTB2_EN|FMC_SDCMD_NORMAL_CMDMODE|FMC_SDCMD_NRFS_2;

           while( ST_pFMC_REGS_Ptr_t->FMC_SDSR & (FMC_SDSR_BUSY_FLOG));

           ST_pFMC_REGS_Ptr_t->FMC_SDCMR = FMC_SDCMD_CTB2_EN|FMC_SDCMD_CLK_CNFIGD_CMDMODE|FMC_SDCMD_NRFS_2;

           //for(temp3=0;temp3<10000;temp3++);

           while( ST_pFMC_REGS_Ptr_t->FMC_SDSR & (FMC_SDSR_BUSY_FLOG));

           ST_pFMC_REGS_Ptr_t->FMC_SDCMR = FMC_SDCMD_CTB2_EN|FMC_SDCMD_ALBANK_PRCHRG_CMDMODE| FMC_SDCMD_NRFS_2;

           while( ST_pFMC_REGS_Ptr_t->FMC_SDSR &(FMC_SDSR_BUSY_FLOG));

           ST_pFMC_REGS_Ptr_t->FMC_SDCMR = FMC_SDCMD_CTB2_EN|FMC_SDCMD_AUTOREFRESH_CMDMODE| FMC_SDCMD_NRFS_5;

           while( ST_pFMC_REGS_Ptr_t->FMC_SDSR &(FMC_SDSR_BUSY_FLOG));

           ST_pFMC_REGS_Ptr_t->FMC_SDCMR = FMC_SDCMD_CTB2_EN|FMC_SDCMD_LOADMODEREG_CMDMODE| (SDRAM_CMDMODEREG_DEFINATION<<9)|FMC_SDCMD_NRFS_2;

           while( ST_pFMC_REGS_Ptr_t->FMC_SDSR &(FMC_SDSR_BUSY_FLOG));

           ST_pFMC_REGS_Ptr_t->FMC_SDRTR  = (FMC_SDRAM_REFRESH_COUNT<<1);

}

void FMC_SDRAMWRITEPROTECTION_CONFIG(UINT8 U8_Bank,UINT8 u8_writeprotect_enable)

{

ST_pFMC_REGS_Ptr_t->FMC_SDCR1 &= u8_writeprotect_enable;

}

/******IN MAIN**************************/

#define SDRAM_BASE_ADDRESS  0XD0000000

#define SDRAM_SIZE          0x00400000

static void Delay(INT32U u32_fdly)

{

UINT16 u16_ldly;

for( ;u32_fdly>0 ; u32_fdly--)

for(u16_ldly=0; u16_ldly<1275 ; u16_ldly++);

}

int main(void)

{

UINT16 u16_lWrite_Buffer = 0XAAAA,u16_lRead_Buffer ;

UINT32 u32_count ;

UINT16 *u16_sdram_baseaddress = (UINT16 *)SDRAM_BASE_ADDRESS;

UINT32 u32_sdram_size =  (UINT16)SDRAM_SIZE;

    GPIO_ConfigurePin(&st_gPORTG_PIN13_LEDGREEN);

    GPIO_ConfigurePin(&st_gPORTG_PIN14_LEDRED);

FMC_SDRAM_Init(SDRAM_BANK2);

FMC_SDRAMWRITEPROTECTION_CONFIG(SDRAM_BANK2,FMC_SDCR1_WP_EN);

/* *****************writing 16bit data to Sdram memory*************************/

    for(u32_count =0;u32_count <u32_sdram_size;u32_count++)

    {

    *(UINT16 *)(u16_sdram_baseaddress+u32_count) =  (UINT16)(u16_lWrite_Buffer);

    }

    

Posted on May 05, 2014 at 15:27

hai clave here i am attached my sdram code.will u please check it and give any information  if possible. reading and writing from base address 0xd0000000.Then what is the use of address and data pins.do i need to send row address,column address,bank address using pins?

I'm sure you can review SDRAM documentation to understand the purpose of the pins, the FMC has an SDRAM controller which manages the Cortex-M4 memory accesses into interactions with the SDRAM device, this includes the address, bank, data, ras, cas, clock, etc. Once you have configured the controller the interaction is transparent to the programmer.

Half your code is missing, and it uses a library I'm not familiar with, if you want me to review code it will need to use the standard library.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ashwinidigajerla
Associate II
Posted on May 06, 2014 at 06:47

 good morning clive1

So cortex-M4 follows memory mapped I/O for external access.And in the case of SDRAM External aceess, memory address is 0xD000000.Am I right?