AnsweredAssumed Answered

STM32F746 FMC missing bus accesses

Question asked by Andrew Berry on Jul 13, 2017
Latest reply on Sep 28, 2017 by Andrew Berry

I'm working with an LCD with an ILI9341 controller, and attempting to use the FMC to control it.  I've had the LCD working in SPI mode, so I know that my configuration commands are correct.  I've checked the timings between the MCU and the LCD and all appears to be in order.  I can even get the LCD to display things correctly *when the FMC output is correct*.  That last part is proving to be a problem, though.  In certain situations where the program writes to the LCD in rapid succession certain writes either don't happen at all or happen in the wrong order.

 

For example, the below is part of the initialization:

 ILI9341_writeCommand(ILI9341_CMD_PWRCTLB); //0xCF
ILI9341_writeDataU8(0x00);
ILI9341_writeDataU8(0xC3);
ILI9341_writeDataU8(0x30);

This should output 0xCF, 0x00, 0xC3, 0x30, but looking at the activity on the bus, I'm only seeing 0xCF, 0xC3, 0x30.  There'es no gap in transmission, it's as if the second write simply doesn't happen!  This happens at several places during initialization.  But if I step through the program, or add a short spinloop to the write functions, every write happens correctly. So it seems to be a result of how rapidly the program writes to the FMC.  If I disable the FMC write FIFO, I get similar behavior, but different writes are skipped, and again, slowing down the accesses seems to make everything work.  

 

Any suggestions?  Relevant portions of my program are below.  I've looked at what CubeMX provides for using the FMC to drive an LCD (including the HAL_SRAM_Write_ family of functions) and haven't seen anything amiss.

 

FMC setup:

 FMC_Bank1->BTCR[0] =
     FMC_BCR1_WREN |
     FMC_BCR1_WFDIS |
     FMC_BCR1_WREN |
     FMC_BCR1_MBKEN;
FMC_Bank1->BTCR[1] =
     FMC_BTR1_DATLAT |
     (1<<20) | //clkdiv
     FMC_BTR1_BUSTURN |
     FMC_BTR1_DATAST |
     FMC_BTR1_ADDHLD |
     FMC_BTR1_ADDSET;

Write functions (including delay loops):

void ILI9341_writeCommand(uint8_t cmd){
for (uint16_t i=0; i<10; i++);

*((__IO uint8_t*)(0x60000000)) = cmd;
}

void ILI9341_writeDataU8(volatile uint8_t data){
for (uint16_t i=0; i<10; i++);

*((__IO uint8_t*)(0x60010000)) = data;
}

Outcomes