cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4: FSMC cannot write to SRAM, NWE signal always low

kostadin
Associate II
Posted on June 25, 2014 at 07:41

Hello there,

I am trying to access an external SRAM, but I have some difficulties to get it right. I am using an STM32F4 microcontroller and an external SRAM - IS61WV102416BLL. The problem is that I cannot write data to the SRAM. I tried using different timings and different settings, but with no success. Reading from the memory is however working. I am using the first bank (NE1). In the library files from stm32 the address was set to 0x00000000, but I set it to 0x60000000. I also tried sniffing the control pins using an oscilloscope and saw that the NWE stays always low (0V) for some reason. My understanding is that it should be always high until I want to write something to the memory. Other signals such as NCE or NOE were visible. The board I am using is a custom one, but I did not develop it. May be the problem is in wrong settings of the pins. I appreciate if someone could give me a hint on that. Also, I would appreciate if someone can confirm the timings I calculated from the datasheet of the SRAM (The HCLK is 168 MHz). Here is my initialization function:

/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);
/* Enable FSMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
/*--- begining of gpio init ---*/
/* GPIOD */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC); 
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* GPIOE */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource3, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FSMC);
//GPIO_InitStructure.GPIO_Pin &= 0;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_7 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | 
GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* GPIOF */
GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource5, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource12, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource13, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource14, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource15, GPIO_AF_FSMC);
//GPIO_InitStructure.GPIO_Pin &= 0;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | 
GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOF, &GPIO_InitStructure);
/* GPIOG */
GPIO_PinAFConfig(GPIOG, GPIO_PinSource0, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource1, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource2, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource3, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource4, GPIO_AF_FSMC);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource5, GPIO_AF_FSMC);
//GPIO_InitStructure.GPIO_Pin &= 0;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOG, &GPIO_InitStructure);
/*--- end of gpio init ---*/
/*--- Initialize FSMC controller ---*/
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 1;
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0; // does not matter in case of an async SRAM
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0; // does not matter in case of an async SRAM
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0; // does not matter in case of an asynchronous SRAM
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Enable;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; //different timings for reading and writing
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* Enable the SRAM bank1 */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); 
/*--- end of FSMC init ---*/

and here are the read and write functions:

/**
* @brief Writes a buffer to the external SRAM 
* @param pBuffer: pointer to the buffer 
* @param address: start address in the SRAM
* @param num: number of half words to be written (16 bit mode)
* @retval None
*/
void sramWriteBuffer(uint16_t * pBuffer, uint32_t address, uint16_t num){
// here should be implemented some test routine for the address
/* until there is data to write, save it to the sram address */
for(;num != 0; num--){
*(volatile uint16_t*) (FSMC_Bank1_NORSRAM1 + address) = *pBuffer++;
address += 2;
}
}
/**
* @brief Reads data from the SRAM to a buffer
* @param pBuffer: pointer to the buffer 
* @param address: start address in the SRAM
* @param num: number of half words to be read (16 bit mode)
* @retval None
*/
void sramReadBuffer(uint16_t * pBuffer, uint32_t address, uint16_t num){
// here should be implemented some test routine for the address
/* until there is data to write, save it to the sram address */
for(;num != 0; num--){
*pBuffer++ = *(uint16_t*) (FSMC_Bank1_NORSRAM1 + address);
address += 2;
}
}

Thank you very much in advance! I am waiting for suggestions. Kind regards, Kostadin #stm32f4 #stm32f4-fsmc-sram #fsmc
2 REPLIES 2
Posted on June 26, 2014 at 09:05

Try to set the NWE pin as GPIO and toggle  it ''manually'' in a loop, observing it by oscilloscope, to exclude hardware problem.

JW
kostadin
Associate II
Posted on June 27, 2014 at 06:15

Nice idea. Yesterday I received a new hardware and tested the software with it and...it worked like a charm! 🙂

It turned out that the PD5 pin on the old board has some problems and cannot be set high (toggled), even in the normal manual output mode. It always stays low.

Thank you very much for your suggestion!

Best regards,

KK