# Writing to FSMC is extremely slow

I have an ARM Cortex M3 STMF32F103VE http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00191185.pdf, and I'm using an LCD with ILI9320 controller http://www.densitron.com/uploadedFiles/Displays/Support/ILI9320AN_V0.92.pdf

I'm using controlling the LCD using the FSMC, and I'm trying to write for example 240*100*16bit bytes and it takes about 0.1Seconds for that operation and the clock is 72Mhz.

for(i=0;i<240*100;i++)
{
*(__IO uint16_t *) (Bank1_LCD_D) = frameBuffer[i];
}


The code for initializing the FSMC is copied and paste from the STMF32 application note for using an LCD TFT with FSMC:

#define Bank1_LCD_D    ((uint32_t)0x60020000)    //disp Data ADDR
#define Bank1_LCD_C    ((uint32_t)0x60000000)    //disp Reg ADDR

/**
* @brief  Configures the FSMC and GPIOs to interface with the SRAM memory.
*         This function must be called before any write/read operation
*         on the SRAM.
* @param  None
* @retval : None
*/
void FSMC_LCD_Init(void)
{
FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef  p;
//GPIO_InitTypeDef GPIO_InitStructure;

p.FSMC_DataSetupTime = 0x05;
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_CLKDivision = 0x00;
p.FSMC_DataLatency = 0x00;
p.FSMC_AccessMode = FSMC_AccessMode_B;

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

/* Enable FSMC Bank1_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}


and in main init code:

just a call to SystemInit(); and RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

How are you transferring the data into the FSMC address space? Are you manually copying it from RAM? Constructing it on the fly and writing it to the address space?

To transfer it in the minimum possible time and without CPU intervention, I would:

1. Reserve the 48kB of RAM necessary to store a complete LCD frame (a "frame buffer").
2. Use DMA in a continuous loop to transfer the frame buffer into the FSMC address space.
3. Manually update the contents of the frame buffer as needed; DMA/CPU contention will sort itself out.

The biggest problem with this approach is that you may not have 48kB of RAM spare, given that the STM32F1 has at most 64kB of RAM.

• I have an array of framebuffer[24000] then I get a byte and write it. Then its from RAM to address space. The same slow transfer happens too even If I write 240*100 bytes directly to the address space. – Ahmed Saleh Apr 26 '14 at 7:56
• but why its slow to write >10000 times to the FSMC addres space, what is the transfer rate of it ? I tried to find a lot but couldn't find any information. – Ahmed Saleh Apr 26 '14 at 8:13
• Your problem is, at least partially, that you're doing it manually. Inspect the assembly code; the transfers don't take a single clock cycle. By contrast, using DMA will let you transfer 24,000 16-bit words (not bytes!) in 12,000 clock cycles if you use 32-bit transfers and the CPU will be available during that period to do other useful work. Also, 100ms is way too long even for a manual transfer; I'd be checking whether your system clock is running at the frequency you expect. – markt Apr 26 '14 at 8:14
• Sadly, no. What you might be able to do is flash a LED at a frequency that you think should be 0.5Hz (1s on, 1s off) and if it's much faster or much slower then you know something's wrong. – markt Apr 26 '14 at 9:53
• You can work out how many clock cycles are required per word transfer by inspecting the assembly code and cross-referencing to the programming manual, available on ST's website ; I'd expect 6-8 in a nice tight loop, but it could be up to perhaps 20. Multiply that by 24000 and divide by 72000000; that will tell you how many seconds are required for the entire transfer. – markt Apr 26 '14 at 11:32