FMC STM32: SDRAM Integration Guide FOR STM32 Cube Mx

FMC STM32: SDRAM Integration Guide FOR STM32 Cube Mx


4 minute read

STM32 SDRAM Programming

While STM32 microcontrollers offer enough RAM for various embedded applications, there are scenarios—such as image processing—where additional memory is required. In these cases, having an extra memory unit is essential for storing extensive frame data, ensuring the smooth operation of resource-intensive applications. In this guide, we delve into the STM32 SDRAM (Synchronous Dynamic RAM) integration to provide the microcontroller with the additional memory unit. For that purpose, we will cover the configuration of the FMC Interface using the STM32 CubeMx Graphical tool and a simple example of accessing SDRAM using the FMC Interface.

Hardware

In this tutorial, I use STM32F769 Discovery Board. This board already incorporates a 16-MByte SDRAM memory (IS42S32400F) and necessary wirings. However, this tutorial applies to other SDRAM memory units with small modifications. Additional resources related to the hardware and firmware are specified at the end of the article.

STM32F769 Discovery Board

FMC SDRAM CubeMX configuration

First, we configure the Flexible Memory Controller (FMC) using the STM32CubeMx Graphical Tool. Within the connectivity, choose FMC and SDRAM among different options as shown in the picture below.

STM32 FMC SDRAM Cubemx Configuration

Then, we have to specify the number of banks, address bits, and data bits. You can use the datasheet of the SDRAM unit you are using to find these specifications. For example, in my case, IS42S32400F memory has the following characteristics:

SDRAM Functional Diagram

Once we have specified these general parameters, an additional window (SDRAM 1) will pop up to configure even finer details of the protocol. Again, using the blog diagram, we can define the number of column address bits and row address bits. Next in turn is CAS (Column address strobe) latency which defines the time takes for a memory unit to prepare the data to be read. In my case, I set its value to 2.

Another important thing is to set the operating frequency of the FMC protocol. It is essential to set the frequency below a frequency specified in the datasheet. As shown in the picture below, the maximum frequency is 100 MHz for CAS equal to 2.

IS42S32400F CAS latency

In my microcontroller, FMC is driven by the HCLK of the microcontroller. In some cases, The FMC is driven by a separate block which will require configuring the clock of it. In the SDRAM control configuration, I set the common clock to 3 HCLK clock cycles resulting in 72 MHz frequency, because HCLK frequency is 216 MHZ as shown in Figure below.

stm32_clock_sdram_configuration

The next important is to set up SDRAM timing details. For that purpose, I used the datasheet of the memory unit. Other than that, the specifications in the datasheet have to be converted into clock cycles. Considering a 72 MHz clock, I obtained the following values:

1. Load mode register (tmrd): 14 ns - 2 clock cycles.

2. Exit self-refresh delay(txsr): 70 ns - 10 clock cycles.

3. Self-refresh time (tras): 42 ns - 6 clock cycles

4. SDRAM common row cycle delay (trc) - 9 clock cycles

5. Write recovery time(tdpl) - 2 clock cycles

6. SDRAM common row precharge delay(trp) - 3 clock cycles

7. Row to column delay(trcd) - 3 clock cycles

After all these steps, I obtained the following configurations:

stm32 fmc sdram cubemx configuration

Finally, we can save this file and generate code. The next great deal is to find a memory bank corresponding to SDRAM 1. We refer to the reference manual of the MCU we are using to find this information: just search for ’FMC memory bank’ and you should find a table similar to the one presented below.

STM32 SDRAM Memory banks

From this table, we find that 0xC0000000-0xCFFFFFFF is an address range of SDRAM 1. So, whenever we store data within this range, it will be automatically stored inside of the SDRAM memory unit. To test it, I added the following code to my project:

// outside the main function
#define SDRAM_START_ADDRESS 0xC0000000
// inside the main function, after peripherals configuration:
for(int i = 0; i< 256;i++)
{
    *(__IO uint8_t*)(SDRAM_START_ADDRESS + i) = i;
}

After all these steps, the STM32 MCU has an additional 16 MBits of Memory space to store images and other data.

STM32 SDRAM Article Resources

STM32 Course

IS42S32400F SDRAM Datasheet

STM32F769 Discovery Board User Manual

« Back to Blog