This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Starterware/TM4C129XNCZAD: EPI Bus Read and Write Priority

Part Number: TM4C129XNCZAD
Other Parts Discussed in Thread: TIDM-TM4C129XSDRAM

Tool/software: Starterware

I am reaching some timing limit for my LCD display. The TM4C129X LCD module is set to read from external SRAM through the EPI bus. The graphics libarary is configured to write to the same SRAM through the EPI bus.

Writing 1200 pixels seems to be my problem. Trying to writing this number of pixels results in an LCD interrupt, LCD_INT_UNDERFLOW. Writing 1,100 pixels give no problems. I am using 4BPP so writing a pixel is actually a read-modify-write because I only change 4 bits of a byte at a time.

Is there a way to prioritize reads from the EPI bus? Rendering the current frame is much more important than drawing the next frame. I would like a way to tell the writes to "chill" with the read FIFO is running low.

Other ideas are welcome.

  • The EPI has a read and write FIFO. Is it possible to have the LCD controller read from the EPI FIFO, and have the pixel drawing functions poll the read FIFO first to ensure there is data available to the LCD controller before sending data on the bus?

    This is tricking because the LCD controller must read from the FIFO, but the graphics library's read-modify-write function needs to read a different addresses.
  • The LCD controller has a FIFO too. Perhaps a simpler approach would be to poll the LCD FIFO and forgo drawing to SRAM until the LCD FIFO is at a healthy number?

    I do not see a way to read the LCD FIFO count in the datasheet...
  • Hello Peter,

    I don't believe from my read over of the LCD Controller section and the DriverLib guide for the LCD Controller that it is possible to change the prioritization of the LCD controller tasks or read out the FIFO count.

    When you say 1200 pixel, I assume you mean as a count of width? You could be hitting performance limits of the LCD controller if so. I know we have interfaced with 800x480 displays for dev kits and such, but I don't know if we ever interface a displayed large than 1000 pixel width. Not sure exactly where the limit is drawn (such is screen and application dependent and thus not spec'd for the wide array of possibilities) and if such a limit may apply to your choice of resolution and other features, but if you think you are reaching a time limit then you may indeed be accurate about the assumption.

    If a workaround does exist, I don't believe that has been investigated or uncovered not just by our team but even on the forum as a whole from my attempted searches (though E2E's search mechanism still leaves much to be desired...)
  • Hi Ralph,

    1200 pixels means a 50x24 rectangle somewhere on my 800x480 screen.

    I believe the LCD controller works very well. The EPI is the bottleneck. The frame buffer lives in off chip SRAM. The SRAM reads and writes occur through the EPI.

    Things fall apart when the frame buffer is edited. The input FIFO gets empty because the SRAM bus (EPI) is being shared between the LCD controller who reads the pixel data and the processor who sets the pixel data.

    You can tell because once the widgets are done being processed, everything appears on the LCD correctly. You can also tell because the LCD controller is giving the underflow interrupt when the frame buffer is written to.



    On paper my setup should work. The LCD clock is at 24MHz, and two pixels are defined by 1 byte (4BPP). So the LCD is consuming 1 byte at a rate of 12MHz.

    The EPI set to host-bus 8 going at 60MHz. The EPI bus is providing bytes at 60MHz. This is 5x the need of the LCD.

    How do I weave the frame buffer edits in between the LCD reads?

    I have hacked a wait loop between every pixel write with for(i = 0; i < 145; i++); Everything runs smoothly with this wait loop, but the screen renders extremely slow. Imagine having to wait 5 seconds to switch between screens on your phone. That's trash. A wait loop is no good.

    A wait loop is also bad because we know most writes don't cause problems. rendering 1,000 pixels works well, but you are gradually beading the FIFO dry, and eventually we have problems when trying to write ~1,200 pixels.
  • Hi Peter,

    Oh I see. That dimensioning should be no problem for the controller then. The wait loop definitely doesn't sound like a workaround, agreed that is a garbage solution.

    That the frame buffer is in SRAM is common practice for Raster Mode, so that shouldn't be an issue either. But with that in mind, I did some more poking and found an errata item, LCD#02, which may be affecting you possibly: http://www.ti.com/lit/er/spmz850g/spmz850g.pdf

    Description: If the EPI controller is mapped to allow indirect access to SDRAM where the ECADR bit field is 0x0 and the ERADR bit field is not 0x0 in the EPI Address Map (EPIADDRMAP) register, a DMA FIFO underflow interrupt occurs. This is a result of the LCD being a lower priority than the CPU when they both try to access the SDRAM.

    While the errata calls out SDRAM specifically, perhaps it is also affecting you SRAM as it is access address map based. Think this may explain what is occurring?

  • That was worth a shot.

  • Is there a way to get the LCD DMA to read from the EPI read FIFO? There is a way to poll the read FIFO count and pause writing to the frame buffer, but it is not clear how to make the LCD read from the EPI FIFO.

    What determines EPI priority? It is not clear how setting ECADR is supposed to make LCD reads higher priority.

  • Can the EPI WRFIFO be accessd any way other than the uDMA? The data sheet says "For blocking reads, the μDMA software channel (or another unused channel) is used for memory-to-memory transfers (or memory to peripheral, where some other peripheral is used). In this situation, the μDMA stalls until the read is complete and is not able to service another channel until the read is done."

    Does the LCD controller perform blocking reads? This is the only thing I see that can priorities the LCD controller.
  • I have temporally giving up on the EPI. For now, the LCD buffer will live in on chip SRAM. This gobbles up 192KB of the 256KB SRAM.

    64KB is remaining. If TI-RTOS + NDK TCP/IP stack can work with 64KB, then this is a fine resolution. The demo app running on the DK-TM4C129X uses ~59KB so this is a reasonable squeeze.

    In the original plan, 2 frame buffers with ping-pong require 384KB, but rendering happens very quickly with on chip SRAM so I think this is acceptable.
  • Hello Peter,

    Sorry for the delay in getting back to you, had to confer with another expert.

    The issue with your attempted application is due to using SRAM and not SDRAM for the external memory. External SRAM communication is very slow and thus have such limitations - especially for Raster mode. I have been informed that using a good SDRAM chip will be no problem though. You will be able to do 800x480 in Raster Mode with the external memory. SDRAM will let you get 8x2 bytes (16 total) per comm cycle which should then (if coded right) keep the FIFO from ever hitting underflow conditions etc.
  • Hi Ralph,

    Could you seek out a more objective answer? Everything is slow or fast compared to something else. 30 miles an hour is fast for a bicycles, but slow for a car on the interstate. These terms don't mean anything without context. If you insist a more expensive chip is essential, then I need an objective bandwidth to justify cost and effort.

    The RAM speed should work by the numbers. The LCD screen needs 12 megabytes per second to avoid underflow. The EPI bus is configured for 60 megabytes per second. The EPI bus spends ~80% of its time idle while the screen is being fed pixel data. Why can this idle time not be used efficiently for writing new data?

    This idle time can be used for writing ~500 bytes before the FIFO runs dry. Why can't I pend on a semaphore when the FIFO is low? What is stopping this configuration from working?

  • Hi Peter,

    SRAM access speed via EPI with TM4C will depend on the device being used, so it would be specific to your system. For a setup like yours though the Asynchronous nature of SRAM results in latency which slows the process from peak speed. Also you are limited to the 60MHz EPI clock.

    As far as helping to provide a objective bandwidth to compare/contrast (fully understand the need for justification) I will need a bit of help on your end to help us understand the interaction between your SRAM and the TM4C.

    Can you measure the data access timing on the EPI bus? The signals of most interest will be the CSn and RDn signals.

    I am still following up on the EPI and FIFO specific questions, they haven't fallen deaf on my ears.
  • Ralph,

    Looking at the RAM timing on a scope relieved that the signals were not going as fast as I thought they were.

    Changing EPIDividerSet(EPI0_BASE, 1); to EPIDividerSet(EPI0_BASE, 0); speeds up the bus and makes everything work.

    I am not sure what this line of code is doing because the API documentation seems to contradict the data sheet. The Tiva C API description says the function sets the EPI clock to the system clock, but the data sheet says you can only run up to 60MHz. What is actually happening when the system clock is faster than 60MHz and you write EPIDividerSet(EPI0_BASE, 0);?

    The 60MHz limit is mentioned in table 32-40 and 32-43 for modes other than Host Bus 8.

    The datasheet says in table 32-41 that the write signal is 1 EPI clocks. The RAM data sheet says it needs a write pulse width of 7ns. Therefore the board would work even if the EPI bus was set to 120MHz (8.3ns pulse width). On the scope, I see 22ns. I assume this means I am running near the max 60MHz. I feel safe regardless of how the divider is being set, but a through understanding would be appreciated.
  • Hello Peter,

    Sorry for the delay, wanted to fully verify the following information before commenting.

    The TivaWare API is correct and also is in line with the datasheet if you look at the EPIBAUD register on Page 895.

    Peter Borenstein said:
    What is actually happening when the system clock is faster than 60MHz and you write EPIDividerSet(EPI0_BASE, 0);?

    Unfortunately, by doing this you are actually causing the device to operate out of specification in this situation. The dividers must be utilized correctly to get the correct frequency per data sheet specifications. The way the library API's are setup make this dependent on the user to do so (whether that's the right approach is a different story, but that is just how it is setup with the API). So that line is actually forcing the EPI Clock to operate at 120MHz and thus out of specification.

    While it may be the case that one device still works with the out of spec configuration, there is absolutely no guarantee such operation would be retained across devices in production. Therefore, I'm sorry to say but that is not a reliable solution to the issue you are facing with the timing constraints...

  • That's depressing to read, but I'm glad you said it...
  • Ralph,

    Could you clarify the timing retirements? The datasheet gives different EPI max speeds for different modes and doesn't specify Host Bus 8 mode, which is what I use.

    From the datasheet,
    Table 32-39 says SDRAM mode has max 60MHz.
    Table 32-42 says General Purpose has max 60MHz
    Table 32-43 says PSRAM has max 50MHz.
    Table 32-41 discusses Host-Bus 8, but gives no max.

    Host Bus 8 mode may not share this limit because the clock signal is not used in the external interface. Compare figure 32-20 with figure 32-21. There clock signal is not used! I think this reasoning is my saving grace.

    The lower 4 bits of EPICFG define these modes.

  • Hello Peter,

    The EPI interface as a whole is not specified to operate at a clock speed higher than 60MHz. On Page 858, Table 11-2 shows all EPI Interface Options and what the Maximum Frequency's permitted are. Even for a single SRAM, the limit of maximum frequency is 60MHz. The datasheet does a poor job at connecting the dots on this, but the single SRAM mention on this table refers to both Host Bus Mode for 8 and 16 bits (which are detailed in Section 11.4.3).
  • Well then back to the original issue.

    How can chip writes to EPI not impact the LCD controller's reads from EPI?
  • I was able to confirm the EPI clock through the ALE. Table 32-41 says this signal should be 1 EPI clock.

    The duration is ~17ns or 60MHz with EPIDividerSet(EPI0_BASE, 1);
    The duration is ~8ns or 120MHz with EPIDividerSet(EPI0_BASE, 0); //too fast

    This 60MHz limit casts doubt on the SDRAM speed. TI's TIDM-TM4C129XSDRAM dev kit features the SDRAM chip ISSI S42S16320D . I use the SRAM chip, Cypress' CY7C1049GN30.

    The SDRAM chip has 5.4ns access time, but we know that doesn't matter due to the EPI's max clock limit. You cannot strobe faster than 16ns when running at 60MHz. The TM4C129X chip is incapable of leveraging the speed that makes SDRAM and SRAM different. There is a speed difference between these chips, but the TM4C129X does not use it.

    Both chips read out 8 bits at a time.

    I still want to understand the minimum bandwidth that makes SDRAM a necessity, but by these numbers, SDRAM wouldn't be faster...
  • Hello Peter,

    Our expert who had past success with the SDRAM for this sort of application used 16-bit SDRAM, so whether 8-bit SDRAM would work for that size of a display isn't 100% clear. Furthermore, he stated that while the access times are the same, SDRAM does burst support which therefore allows it to read and write longer data sequences and that results in getting better throughput compared to SRAM (tested with 16-bit SRAM vs 16-bit SDRAM).
  • Do any of these throughput options actually prioritize the LCD controller over core access?

    A bandwidth solution seems to avoid this problem. If you are fast enough, prioritization doesn't matter.

    Both your SDRAM suggest and my overclocked bus do nothing to give LCD preference.

    Keep in mind that I'm open to SDRAM, but since it takes extra $$$, I would like to prove the value I am getting. Only buy the Ferrari after qualifying that the Honda can't do the job.

  • Hello Peter,

    I am not sure what you mean by prioritize the LCD controller over core access. I think your problem would be the other way around would it not? That your LCD screen is reading out data faster than can be loaded into the buffers from SRAM by the CPU?

    Basically what is occurring is that the LCD has priority over the CPU when it comes to buffer access. The CPU can only access it when the LCD is going through V-Sync. That's when an interrupt is fired to alert the CPU and it can then get into the buffer and fill in data.

    Regarding the case for SDRAM, the data access time to SRAM/SDRAM isn't the only spec to look for in this situation. The LCD Data/Clock Rate also are important. This is because of how the EPI works. If the LCD refresh is fast then because the buffer access is limited the SDRAM burst mode is needed to provide enough data quick enough. And no, there is no way to change the functionality of the EPI in terms of prioritization, so how it functions is what you have to work with. It can't be re-configured for different priorities so when you get an Underflow interrupt you will still be limited to only being able to fill the buffer when you receive the V-Sync interrupt and the LCD relinquishes the buffer access.

    Can you provide details on the LCD screen (esp. data/clock rate)?

    Also, using 8-bit SRAM or SDRAM is not optimal as the EPI is a 16-bit bus. This will further reduce the rate in which data is accessed unless you have a chip which does special handling to optimize for 16-bit, which your SRAM doesn't seem like it would from a glance through the datasheet.

    As far as our experience with LCD panels go using the EPI, to do an 800x480 display with 60FPS, the SDRAM burst mode is needed due to how the EPI functions with LCD having priority over the CPU for access. If you can find a way to get an SRAM to work for your application, all the power to you, but that is going into an application specific territory that we simply don't have expertise to provide detailed support in.

    Just to throw this out there as another option for optimizations, another method to help offload some of the CPU burden would be to have 2 frame buffers which the LCD accesses and then use the DMA to fill the frame buffer not being used, and then when one buffer empties, switch to the other buffer. However, this is not expected to be enough on it's own to get an 8-bit SRAM working with such a large display.

    Lastly, another aspect that you should be aware of is make sure some optimizations are being used, as without optimizations the access times can get slowed. All LCD examples were done with optimization level = 2.
  • A second frame is an essential part of the master plan. Otherwise you would show half rendered widgets. This frame alternating method works, but at unsafe EPI speeds and we can't have that...

    We defiantly want the LCD controller to have priority. Once the current frame exists in memory, we do not need to write anything. The LCD control continuously reads out this buffer and refreshes the screen. The core can get suck in a while(1); loop for all we care, and the LCD controller will be just fine. Blocking the core's writes and reads does not cause us any trouble.

    The LCD clock is at 24MHz, and pixels are defined by 4BPP (1 byte defines 2 pixels). So the LCD is consuming 1 byte at a rate of 12MHz.

    How do I weave the frame #2 edits in between the LCD reads from frame #1?

    We know that writes can occur without indecent up do some amount. When writing about ~1,200 pixels or more, the core hogs the EPI, and the LCD FIFO under flows.
  • "It can't be re-configured for different priorities so when you get an Underflow interrupt you will still be limited to only being able to fill the buffer when you receive the V-Sync interrupt and the LCD relinquishes the buffer access."

    I don't think this is true. For one my screen doesn't have a V-sync signal.

    Second, I put the SRAM's write enable (/We) on the scope. My screen refreshes every ~20ms. The screen write do not seem to occur at this interval.

    The writes don't seem to follow any pattern.
  • A new board with SDRAM seems to work just fine. Thanks for the help.