SDRAM framebuffer causing USB FS to suspend? Interoperability issue.
Hello!
I am having an interesting problem and I was wondering if someone could help point me in the right direction. Thanks in advance kind people. Dust off your magnifying glass and get ready for some clues!
Problem description:
I can successfully jointly run the USB OTG FS (acting as a Virtual COM Port) with the 480x272 RGB interface LCD if I store the (single) framebuffer for the LCD in internal SRAM. If I try to store the framebuffer (single or double) in external SDRAM, then the LCD continues to operate but the USB will suspend. From what I have observed, the other peripherals continue to function normally apart from an increased rate of garbling of the Serial Wire Viewer data.
Project background:
My project is running on a STM32F767NIH. The board includes an LCD, USB FS, and several other peripherals. From the profiling I have done the CPU spends ~95% in idle. For the LCD, I am using the LTDC driver, DMA2D, an external flash chip to store graphic assets (QSPI connection), and an external SDRAM is also available on the board via FMC. For the USB, it is running at 48MHz and is not set for DMA operation. The processor is running at 200MHz so the FMC/SDRAM can operate at 100MHz (max speed).
Here are the relevant NVIC interrupt priorities:
OTG_FS (5) > (LTDC (6) == DMA2D (6)) > (QUADSPI (0xf) == SDRAM_DMA (0xf))
While testing, the only peripherals I enabled were the USB, LCD related peripherals, and the Serial Wire Viewer ITM output.
Operability Notes:
Without the SDRAM framebuffer enabled (the internal SRAM is used for the framebuffer), the USB enumeration always succeeds. With the SDRAM framebuffer enabled, the USB enumeration -sometimes- enumerates but then PC may display ‘USB device not recognized’. The USB can sometimes even transmit a few packets before it suspends. With a terminal I can -sometimes- see a message or two successfully sent before the USB on the chip gets stuck in ‘suspend’. (I’d suspect this timing of whether the USB enumerates or not has to do with the timing of the initialization of the FMC/SDRAM). Again, this problem only occurs when the SDRAM framebuffer is used.
If I enable the FMC/SDRAM but continue to store the framebuffer in internal SRAM, then the USB seems to continue to function. If the framebuffer is set in SDRAM but the touchgfx task is disabled (but the LTDC is still running), then still USB does not work.
My suspicion is that this issue is the result of a bandwidth problem. Even with the internal SRAM buffer, if I increase the pixel clock 25% then the USB will also suspend. The lower the pixel clock the longer the USB can run without suspending. As for the bpp, when using internal SRAM, I can only use 16bpp due to memory size constraints. Using 16 or 24bpp with external SDRAM still breaks the USB. Reducing the pixel clock when using external SDRAM does not stop the USB from suspending. Additionally, I also tried disabling DMA2D but that also had no effect on the problem. In case it is relevant I’ll point out that I have disabled the d-cache (using the MPU) for the DTCM (unnecessary)/SRAM1/SRAM2 to prevent any peripheral DMA buffer issues. I have enabled caching and prevented unaligned access for SDRAM using the MPU. And following the respective appnote, I also deactivate speculative/cache access to the first FMC bank to save FMC bandwidth. Lastly, I’ll note that when I tried to use double buffering in external SDRAM, I made sure the framebuffers were in different banks.
Please let me know if you would like any additional information. And if you are thinking at this point “By Jove! How could this knucklehead miss ___�?, I would be appreciative for you letting me know!
Thanks for your time!
