STM32CUBEMX WITH TOUCHGFX LIBRARY WITH FSMC/FMC bus controller


 

 TouchGFX is a set of graphics middleware code, which belongs to the category of embedded software. It is inevitably related to the hardware resources of STM32. When using STM32CUBEMX to configure TouchGFX, it is necessary to configure FMC (FSMC), display interface like DSI or LTDC, QSPI, etc., is the reason.

 The MCU resources mainly used by TouchGFX are:

1) Memory (RAM): 

In order to process images, RAM is needed as a buffer for images. This RAM can be either on-chip or extended off-chip. LCD generally has more display pixels and requires more RAM, so TouchGFX applications basically require MCU to expand RAM, and the most convenient way to connect MCU and RAM is through the FMC (or FSMC) interface.


2) Display interface (DSI or LTDC, etc.).

This complete display consists of a liquid crystal display panel, a capacitive touch panel, and a PCB backplane. The touch panel in the picture has a touch control chip, which processes touch signals and communicates with external devices through the drawn signal lines. The middle of the touch panel is transparent, and it is attached to the liquid crystal panel to form the main body of the screen. The touch panel and the The cables drawn from the LCD panel are connected to the PCB backplane. According to actual needs, the PCB backplane may have an "LCD controller chip". The LCD screen PCB on the right in the figure has an RA8875 LCD controller. Because controlling the LCD panel requires more resources, most low-level microcontrollers cannot directly control the LCD panel, and an additional dedicated LCD controller is required to handle the display process. The external microcontroller only needs to send the data it wants to display directly to the Just give it to the LCD controller. Instead of the PCB backplane with the LCD controller, there is only a small part of the power management circuit, and the signal line of the LCD panel is connected to the external microcontroller for direct control. The STM32F429 series of chips do not need an additional LCD controller, which means that it integrates the functions of the dedicated LCD controller into the STM32F429 chip, which can be understood as the computer's CPU integrated graphics card , which saves additional controller costs. The STM32F1 series chip does not integrate the LCD controller into the chip, so it can only drive the screen with its own controller, which can be understood as the external graphics card of the computer 

3) Code and static graphics memory. 

In practical applications, more than one background graphics may be used, and these graphics resources are compiled into the code and stored in the flash. If the on-chip flash of the MCU is not enough, it needs to expand the flash. The commonly used interface is QSPI.

After understanding the above interfaces, it is much easier to configure TouchGFX using CUBEMX.  We'll start by configuring the FMC interface first, and we'll start with the FSMC that the F103 has since it's a bit simpler.

FSMC, Flexible Static Memory Controller, is a hardware structure in the MCU. Its function is to simplify the interface for connecting peripherals. If you have used the IIC bus, you will know that there are roughly two ways to use the IIC: one is to use two IO ports to simulate the timing of the IIC, and the user writes the relevant code. Another method is to use the IIC bus controller provided by the MCU, first configure some control registers related to the IIC (CUBEMX can be used), and then directly read and write the IIC data through the HAL function (or interrupt). The latter is "processed" and is the standard process of IIC operation, which is more convenient to use and more stable. FSMC is similar to this, it contains the interface signals necessary to connect peripherals (static RAM, NOR, NAND):

1) Chip select signal CS;

2) Data bus D0-D15 (16bit, also supports 8-bit);

3) Address bus (can be multiplexed with the data bus, and is often used to configure the command signal of the LCD when connecting to the LCD display screen, see the example below);

4) Read the signal;

5) Write signal.

In this example, we will implement the STM32F103 to drive the ILI9325 (ILI9320) display screen through the FSMC interface. The interface diagram is as follows:




For the ILI9325, a reset signal is also required, a GPIO of the MCU is configured as an output mode, and it can be connected to the LCD.

Let's take a look at the structure of the FSMC of STM32F103 (screenshot from the user manual of 103):




For simplicity, we only care about the NOR/SRAM part:

Among them, the marked signal line is used in the example. The usage of these signal lines is described below with a specific example. This example is an STM32F103 connected to an ILI9325 LCD via FSMC. On the STM32F103 board, the MCU and LCD interface circuit is shown in the figure:


MCU circuit





There is not much to say about the 16 data lines D0-D15. Here we focus on a few control signals:

The above table shows how the read, write and chip select signals correspond to the pin numbers of the MCU (it is the multiplexing function of the pins. When configuring the FSMC through CUBEMX, the multiplexing functions of these pins are automatically configured). The RS control signal needs to be explained separately: RS is used to tell the ILI9325 controller whether the data currently received from the MCU is "command" or "data" (see the ILI9325 data sheet for details), and there are two ways to connect the MCU to the RS signal. : One is to connect the RS with the GPIO of a MCU. Before each time the MCU sends data to the ILI9325, it sets the GPIO to 0 or 1 according to whether it is sending a command or data; the other method is to set an address of the MCU to The line (A16 in this case) is connected to RS, and the ILI9325 is accessed in the code using the "address" corresponding to that address line (A16) (the code below will detail how to do this). The corresponding pins of A16 are as follows:




Let's start using CUBEMX to configure the FSMC of STM32F103:






Using an external crystal:


Configuration of FSMC:



The NOR (here used to drive the LCD) block part of the FSMC is divided into 4 "sub-blocks":

 




Here we should pay attention to the address occupied by FSMC. This is a 32-bit address. Connect to different peripherals. FSMC uses different addresses accordingly. For example, if you connect NOR, the internal address of MCU starts from 0x6000 0000. If the connection is NAND , the address is 0x7000 0000 . The interior of NOR is divided into 4 parts. The starting address is determined by bit[27:26] of the 32-bit address, which is expressed in binary as:





Bank1: 0110-0000 0000-0000 0000-0000 0000-0000 , that is, 60 00 00 00;

Bank1: 0110-0100 0000-0000 0000-0000 0000-0000 , that is, 64 00 00 00;

Bank2: 0110-1000 0000-0000 0000-0000 0000-0000, that is, 68 00 00 00;

Bank3: 0110-1100 0000-0000 0000-0000 0000-0000 , that is, 6c 00 00 00;

In this example, Bank1 is used, and the address range is 0x6000 0000-0x63ff ffff (a total of 64M byte addresses). Correspondingly, when accessing this address space, FSMC automatically outputs the NE1 chip select signal (ie, PD7 outputs 0, see Figure 6).Let's look at a special address: 0x6002 0000, which is 0110-0000 0000-0010 0000-0000 0000-0000 in binary. Note that bit[17] here is deliberately set to 1. The address of the FSMC is the "byte address", and the addresses from low to high are:

0x6000 0000, 0x6000 0001, 0x6000 0002, ..., a total of 64M addresses.



However, when the FSMC is configured as 16-bit "address mode" (configured by the MWID bit of the FSMC control register FSMC_BCR1), obviously there should be only 32M addresses. At this time, FSMC makes a special process: "discard" the bit-0 of the address, and start counting the address from bit-1 (equivalent to only counting even addresses, there are 32M addresses in total), when the FSMC actually outputs the address, it will The value of the address is shifted to the right by one (equivalent to dividing by 2, which becomes an even address) and output to the actual address line. The F103 documentation says this:





Taking the address: 0x6002 0000 as an example, when the FSMC is in 16-bit mode, the 1 of the address bit[17] is shifted to the right by one bit and then output to the address line, that is, the pin corresponding to A16 (PD11, see Figure 7) will output 1, and also That is, the RS signal line will be 1. After talking so much, I actually want to explain one thing: when writing data to ILI9325, use address 0x6002 0000 to access; when writing commands to ILI9325, use address 0x6000 0000 to access!


Finally configure the reset pin of the LCD:


Generate STM32IDE created  code in CUBEMX, and add functions for ILI9325 read and write in main.c:

   
#define LCD_Data_Addr ((uint32_t)0x60020000) //write data address

#define LCD_Reg_Addr ((uint32_t)0x60000000) //write command address

//write index (command) register

void LCD_WriteIndex(unsigned int index)

{

    *(volatile uint16_t *)(LCD_Reg_Addr) = index;

}

//read register

uint16_t LCD_ReadReg(uint16_t reg)

{

    uint16_t ret;

    LCD_WriteIndex(reg);

    ret = *(volatile uint16_t *)(LCD_Data_Addr);

    return ret;

}

After the program is initialized, reset the LCD, and then read the version of ILI9325. If the data "9325" can be read correctly, it means that the FSMC configuration is correct:
   
// reset LCD

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);

HAL_Delay(500);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);



//read

tmp = LCD_ReadReg(0x0000); //0000 is the code, see ILI9325 manual for details

//tmp should be 0x9325 now!!!

if(tmp == 0x9325)

{

    //led1 on

    HAL_GPIO_WritePin(GPIOB , GPIO_PIN_8, GPIO_PIN_RESET);

} else

{

    //led2 on

     HAL_GPIO_WritePin(GPIOB , GPIO_PIN_9, GPIO_PIN_RESET);

}

printf("ret=0x%x\n", tmp);

//Observe the variable value in KEIL through TM_SendChar(), see " STM32's ITM Tracking and Debugging Function Introduction and Implementation (1) KEIL " and " STM32's ITM Tracking and Debugging Function Introduction and Implementation (4) printf() " . ...... operation result:




This example is only to illustrate how to configure the FSMC, so only the read data to ILI9325 is implemented. After adding the initialization code for ILI9325, ILI9325 can easily display images.

With the basic knowledge of FSMC configuration, it will be convenient for us to further understand the configuration process of using FMC to access external DRAM on the STM32F746G-DISCO board. This content will be introduced in the next section-- STM32