AnsweredAssumed Answered

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

Question asked by kotev.kostadin on Jun 25, 2014
Latest reply on Jun 27, 2014 by kotev.kostadin
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

Outcomes