2013-10-17 12:31 PM
The code shipped in the FW library either says it's not implemented, or is in fact the code for the STM324x9I-EVAL with or without the name changed. The code was for Bank1 SDRAM at 0xC0000000, it will not work with the different part at Bank2 0xD0000000 on the STM32F429I-DISCO board!!
#ifdef DATA_IN_ExtSDRAM
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f429_439xx.s before jump to main.
* This function configures the external SDRAM mounted on STM32F429I-DISCO board
* This SDRAM will be used as program data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
/* This function will be implemented in next versions */
}
#endif /* DATA_IN_ExtSDRAM */
This annoyed me, so I fixed it. This now allows SystemInit() to bring up the SDRAM, and for it to be used by the C Run-time library code. If this helps you, please send your appreciation.
https://docs.google.com/file/d/0B7OY5pub_GfISU9vOTlZa3ItMDQ/edit?usp=sharing
#this-annoyed-me #so-i-fixed-it2014-01-08 01:05 PM
This is AWESOME Clive. I will use this in my startup scripts for my ST32F4 design.
2014-01-10 06:00 PM
I wondered why the included method didn't work for me and assumed I had done something wrong.
Here is my quick and dirty method… (called from main). OK, so not optimised to run at 180MHz (I presume it’s designed to run at 168MHz). Also some interesting differences i.e. why the extra bits in GPIOB->MODER when only PB5&6 used (on the 429 Discovery board)?/*----------------------------------------------------------------------------
SDRAM Initialisation - 4194304 Bytes
*----------------------------------------------------------------------------*/
void SDRAM_Init (void) {
uint32_t temp32;
// GPIOB Configuration - PB.6&5
GPIOB->MODER = GPIOB->MODER | 0x2800; // Alt Fn
GPIOB->OSPEEDR = GPIOB->OSPEEDR | 0x2800; // 50MHz
GPIOB->AFR[0] = GPIOB->AFR[0] | 0x0CC00000; // SDRAM
// GPIOC Configuration - PC.0
GPIOC->MODER = GPIOC->MODER | 0x2; // Alt Fn
GPIOC->OSPEEDR = GPIOC->OSPEEDR | 0x2; // 50MHz
GPIOC->AFR[0] = GPIOC->AFR[0] | 0xC; // SDRAM
// GPIOD Configuration - PD.15,14,10,9,8,1,0
GPIOD->MODER = GPIOD->MODER | 0xA02A000A; // Alt Fn
GPIOD->OSPEEDR = GPIOD->OSPEEDR | 0xA02A000A; // 50MHz
GPIOD->AFR[0] = GPIOD->AFR[0] | 0xCC; // SDRAM AFRL
GPIOD->AFR[1] = GPIOD->AFR[1] | 0xCC000CCC; // SDRAM AFRH
// GPIOE Configuration - PE.15,14,13,12,11,10,9,8,7,1,0
GPIOE->MODER = GPIOE->MODER | 0xAAAA800A; // Alt Fn
GPIOE->OSPEEDR = GPIOE->OSPEEDR | 0xAAAA800A; // 50MHz
GPIOE->AFR[0] = GPIOE->AFR[0] | 0xC00000CC; // SDRAM AFRL
GPIOE->AFR[1] = GPIOE->AFR[1] | 0xCCCCCCCC; // SDRAM AFRH
// GPIOF Configuration - PE.15,14,13,12,11,5,4,3,2,1,0
GPIOF->MODER = GPIOF->MODER | 0xAA800AAA; // Alt Fn
GPIOF->OSPEEDR = GPIOF->OSPEEDR | 0xAA800AAA; // 50MHz
GPIOF->AFR[0] = GPIOF->AFR[0] | 0xCCCCCC; // SDRAM AFRL
GPIOF->AFR[1] = GPIOF->AFR[1] | 0xCCCCC000; // SDRAM AFRH
// GPIOG Configuration - PG.15,8,5,4,1,0
GPIOG->MODER = GPIOG->MODER | 0x80020A0A; // Alt Fn
GPIOG->OSPEEDR = GPIOG->OSPEEDR | 0x80020A0A; // 50MHz
GPIOG->AFR[0] = GPIOG->AFR[0] | 0xCC00CC; // SDRAM AFRL
GPIOG->AFR[1] = GPIOG->AFR[1] | 0xC000000C; // SDRAM AFRH
// Enable Peripheral Clock
RCC->AHB3ENR = RCC->AHB3ENR | 0x1; // Enable FMC
// FMC SDRAM bank initialization
FMC_Bank5_6->SDCR[0] = 0x2800;
FMC_Bank5_6->SDCR[1] = 0x1D4;
FMC_Bank5_6->SDTR[0] = 0x106000;
FMC_Bank5_6->SDTR[1] = 0x10361;
// FMC SDRAM device initialisation sequence
// Configure a clock configuration enable command
while (FMC_Bank5_6->SDSR & 0x20) { // Controller not ready for new request
};
FMC_Bank5_6->SDCMR = 0x9; // Send Command
//need 100ms delay
for (temp32 = 0x00; temp32 <
0xD0000
; temp32++) {
}
// PALL (precharge all) command
while (FMC_Bank5_6->SDSR & 0x20) { // Controller not ready for new request
};
FMC_Bank5_6->SDCMR = 0xA; // Send Command
// Auto-Refresh command
while (FMC_Bank5_6->SDSR & 0x20) { // Controller not ready for new request
};
FMC_Bank5_6->SDCMR = 0x6B; // Send First Command
while (FMC_Bank5_6->SDSR & 0x20) { // Controller not ready for new request
};
FMC_Bank5_6->SDCMR = 0x6B; // Send Second Command
// Load Mode Register command
while (FMC_Bank5_6->SDSR & 0x20) { // Controller not ready for new request
};
FMC_Bank5_6->SDCMR = 0x4620C; // Send Command
// Set the refresh rate counter
FMC_Bank5_6->SDRTR = 0x556;
while (FMC_Bank5_6->SDSR & 0x20) { // Controller not ready for new request
};
/* Disable write protection */
temp32 = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (temp32 & 0xFFFFFDFF);
}
2014-01-10 10:17 PM
The GPIOB stuff related to post Reset defaults for register, and modified STM324x9I-EVAL code to work on second bank. Had tested memory against this, but will revisit.