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.

TM4C1294KCPDT: EPI in XFIFO mode

Part Number: TM4C1294KCPDT
Other Parts Discussed in Thread: TM4C1294NCPDT

Hi,

I am upgrading a design that previously used a UART to dump a lot of data to a PC, to an EPI-based interface. The EPI is in 8-bit Host-Bus mode, submode is XFIFO.  The EPI bus is externally connected to an FT2232H USB Bridge which works in FT245 mode (async FIFO mode, with RD, WR, FFULL and FEMPTY signals). I am just starting out with the EPI module and I have a bunch of beginner questions:

1.  It is not clear to me if the EPI's write FIFO is always used, or if there are separate procedures to write through the FIFO vs to write directly to the bus. Looking at Figure "11-1. EPI Block Diagram" in the TM4C1294KCPDT datasheet, it seems that the AHB bus can access the Host Bus interface either directly or through the FIFO. However I have no idea what's the software mechanisms to do either.

2.  same question as #1 but for the read-FIFO.

3.  I also don't understand the relationship / priority between reads and writes. obviously, at any given point in time the bus can only do one of the two (half-duplex). So, what happens if the EPI's write FIFO currently has some filled entries that "want" to go out into the external bus, but there is also a non-blocking ready underway... what will happen? reads, writes, errors...? To put the question more constructively: What would be a good approach that will allow me to both constantly dump a lot of data (writes) out of the bus, but also be monitoring any occasional incoming data that comes in from time to time?

4.  a question that relates specifically to using the XFIFO mode: is it meaningless to have an address mapping to the MCU's RAM, considering that the concept of address does not exist in an external FIFO? If I map it anyway, will only one address be effective? for that matter, is it mandatory to have memory mapping to the MCU in order to use the EPI?

5.  just to make sure: in XFIFO mode, the EPIBAUD register value is meaningless, right? considering that the rate of transaction is dictated by the FFULL & FEMPTY "flow control" signals.

I will probably have a few more questions, especially when I start using the DMA for this, but that's quite long already for now...

thanks!

  • Hi Guy,
    I think according to the datasheet with the below excerpt the WFIFO and the NBRFIFO only pertain to GPIO mode, not the HB-8 with XFIFO submode. I hope that will address your first three questions.

    In XFIFO mode, I think any addresses that are in the range bound by the CS connected to your external FIFO device can be used.

    The EPIBAUD is still needed because it is used to derive the wait states for the WR and RD signals.
  • Hi Charles,

    thank you for your reply. However, It really doesn't look true to me that the WFIFO and NBRFIFO are unused in the Host-Bus (HB-8) mode of the EPI. I just went through ALL occurrences of "FIFO" in the EPI section of the datasheet, and there is no mention of this. Usually the datasheet is quite explicit specifying things like that. Another hint is that all the talk about DMA says the DMA transfers data only to/from the WFIFO and NBRFIFO, so if those FIFOs were really not used in HB-8 mode, would you say you can't use the DMA with HB-8 mode...? in your reply you said something about a 'below excerpt' from the datasheet but it doesn't look like you provided an excerpt. If this could be double-checked I'd be very glad, as this completely changes how I'm going to go about this section of my project.

    about the additional points: can you please clarify this -

    "In XFIFO mode, I think any addresses that are in the range bound by the CS connected to your external FIFO device can be used."

    I didn't understand this reply. as I've noted, there is no concept of address in an XFIFO. It's like talking about addresses in a UART transmission... it makes no sense. an external FIFO is just a byte-wide (in my case) port where you dump data, which is sampled on the edge of the WR or RD signals. No concept of address is involved. no CS either, for that matter.

    I understand the last point about the EPIBAUD, thanks.

  • Hi Guy,

      Let me answer the question regarding the address. I'm referring to address range bounded by the EPADR and EPSZ field in the EPIADDRMAP register. These two fields determine the base address of the external peripheral and the size of it. 

      Going back to the other three questions, I will need to get back. 

  • thanks for the follow-up. so about the address, how exactly would it work? let's say I map the external FIFO using EPADR = 0x1 (base address 0xA000.0000), and EPSZ = 0x0 (size is 256 bytes).

    Now I do a write to the MCU memory at address 0xA000.0000. I expect I'll get a write transaction on the external EPI bus. And if I now do a write to 0xA000.0004, what will I get? the exact same transaction as before? or nothing at all? after all, there is no concept of address in a FIFO, it's not like an external RAM or whatever where the bus will transmit the address bits to the external device.

    so, is only one address of the mapped memory area really active? or, are all active and it doen't matter which one you choose? or am I missing something here...?

    thanks,

    Guy.

  • Hi Guy,

      Your understanding is correct. If the address range is configured with 256 bytes then any address within this range starting from 0xA0000000 can be used to access the external FIFO. There is no address pins connected to to the external device in the XFIFO mode.

  • thanks, I now understand that part. So, the only issue that remains from my original post is about the internal FIFOs usage in XFIFO mode (you said you'll check and get back to me about that).

    Meanwhile, I have perhaps a more basic question though: are there any additional ways to read/write data to the EPI besides the DMA and the (optional) memory mapping to the MCU's address space? i.e. does the EPI have any register that if I write data to it, it comes out as a transaction on the EPI bus? I'm thinking of something analogous to the UART's UARTDR register, where I only need to write a byte to that register and it would immediately be transmitted automatically.

    thanks,

    Guy.

  • Staff/I have been following this thread w/interest - note that we do not employ the '129 family.     (instead use 168MHz (and up) Cortex M4s and 200MHz+ M7s)

    Pardon - yet at least to my mind - a significant question remains unanswered (or just tangentially answered.)

    Poster Guy: "What would be a good approach that will allow me to both constantly dump a lot of data (writes) out of the bus, but also be monitoring any occasional incoming data?"     Cb1: "Pardonnez-moi - Monsieur Charles..."

    That 'strategic read' represents a (very) real requirement - and to my mind - appears to 'suffer' under a  FIFO regime.    (especially when the FIFO is 'deep.')    Now it is realized that much of this poster's issue has resulted from - and is governed by - the choice of the 'FT2232H USB Bridge' which 'ties' to the '129 MCU's EPI.    

    Would not the 'best/fastest response' to 'Incoming Data' - result from a (near) standard, 'Parallel Bus Transaction'  - which 'escapes' the necessity for the 'FIFO to (disgorge) all of its contents?'    (as I recall - the 'FT245' (device or mode) enables such parallel bus capability.)

    It seems (also) useful to compare/contrast the 'Execution Speed' of the 'FIFO' - versus the 'EPI' - when placed into 'parallel bus mode.'    (again - I am an admitted '129 feeb' - yet believe such general questions - and redirected focus -  to (hopefully) prove of value...)

  • Hi Guy,

     I'm still waiting for my colleague to confirm my understanding. I read the datasheet again and it still seems to me the intention of the internal FIFO is used during uDMA operation or for non-blocking operations in GPIO mode. I will get back once my colleague confirms. Below are some of the excerpts from the datasheet that that leads to think the internal FIFOs are used along with uDMA and in GPIO mode. 

    11.3 Functional Description
    The EPI controller provides a glueless, programmable interface to a variety of common external
    peripherals such as SDRAM x 16, Host Bus x8 and x16 devices, RAM, NOR Flash memory, CPLDs
    and FPGAs. In addition, the EPI controller provides custom GPIO that can use a FIFO with speed
    control by using either the internal write FIFO (WFIFO) or the non-blocking read FIFO (NBRFIFO).
    The WFIFO can hold 4 words of data that are written to the external interface at the rate controlled
    by the EPI Main Baud Rate (EPIBAUD) registers.

    11.3.3 DMA Operation
    The μDMA can be used to achieve maximum transfer rates on the EPI through the NBRFIFO and
    the WFIFO.

    A μDMA request is asserted by the EPI WRFIFO when the TXCNT
    value of the EPIDMATXCNT register is greater than zero and the WTAV bit field of the EPIWFIFOCNT
    register is less than the programmed threshold trigger, WRFIFO, of the EPIFIFOLVL register.

    ■ When using the EPI controller as a GPIO interface, writes are FIFOed (up to 4 can be held at
    any time), and up to 32 pins are changed using the EPIBAUD clock rate specified by COUNT0.
    As a result, output pin control can be very precisely controlled as a function of time.

     As far as your second question about creating a 'write' transaction other than using memory mapped access or DMA, I don't think that is possible. However, for read transactions, you can employ the non-blocking read where you specify the starting address for read and the size and count of the read. After each read is completed, the result is written to the NBRFIFO. The NBRFIFO can be configured to interrupt the processor when the threshold of the NBRFIFO is reached. 

  • thank you Charles. My understanding from reading those lines was different than yours - namely, I only gather that the uDMA uses the FIFO and that the GPIO mode uses the WRFIFO and NBRFIFO - I didn't read into it that other modes do NOT use the FIFOs. but I suppose we better wait for a definitive word from your colleague.

    as for your second point: if I can employ non-blocking read in my XFIFO mode, wouldn't this imply that the NBRFIFO is, indeed, used in XFIFO mode?
  • cb1, thank you for the interest in my questions about the EPI.

    I, too, use other vendor Cortex M4 in some newer projects (and there are pros and cons to both TI and that vendor). However, this current project remains 'wed' to the TIVA series for the time being. The FT2232H bridge must also remain for now.

    I am interested in what you say about using standard Parallel Bus Transaction instead of FIFO. I am trying to figure which FT2232H mode you refer to and which EPI mode should be used to interface it. I see two "MCU bus" related modes for the FT2232H:
    1. "MCU Host Bus Emulation Mode".
    2. "CPU-style FIFO Interface Mode" (note this is different than what I try to use today, which is " FT245-Style Asynchronous FIFO Interface Mode").

    now, mode #1 above means the FT2232H is the host. I think this won't work, since (If I am reading the EPI documentation correctly ), the EPI of the TIVA must be the host of the bus in all of its modes, and you can't have two hosts (i.e. in this mode, both the FT2232H and the TIVA chip want to have the WR and RD pins as outputs...). so, I guess you mean #2, "CPU-style FIFO Interface Mode".

    now, looking at the description of this FT2232H mode, it seems it is not much different than the FT245 style FIFO mode I use today. The main difference is that the FT245 style has 2 pins dedicated for flow control(TXE and RXF), while the "CPU-style FIFO" mode uses these pins as CS and A0 bits. to learn if you have more data to read (or more room to write), you perform a read transaction with A0 high, and the response is a status byte from the FT2232H, which tells you essentially the same info as TXE and RXF did in the FT245 mode.

    To sum this up, I don't see a relevant difference in using this mode, anything that will help me with the dilemma you quoted, namely something that will help me design the system to be both able to do lots of writes, as well as be able to interrupt those writes for the occasional read.
  • Thank you - my primary concern was your (seeming) focus upon the FIFO - and my concern that a 'deep FIFO' - appears to (substantially) hinder your MCU's recognition of 'critical data which must be read quickly!'

    If time allows - I'll have staff review how our firm manages such 'high priority' data arrivals - which, 'Are recognized & responded' - via the high-speed, external bus. (note this is done on (another's) M4 (and M7) - we (may) have (earlier) employed an FTDI device - another (faster) device has upgraded this system...)
  • thanks!
    I suppose one way would be to monitor the FEMPTY signal which, when low, means a new byte arrived from the FT2232H. Then, when it's high, I can cancel the outgoing transfer (which will likely be DMA based) and do a read. I feel it is a bit ugly, don't you think?

    It would be great to hear how you got that working in your system (on whichever MCU). also, if you care to share what was the faster communications device you upgraded from FTDI, this will also be interesting...
  • Hi Guy,

      I have not heard back from my colleague yet. 

    Guy Ovadia said:
    1.  It is not clear to me if the EPI's write FIFO is always used, or if there are separate procedures to write through the FIFO vs to write directly to the bus. Looking at Figure "11-1. EPI Block Diagram" in the TM4C1294KCPDT datasheet, it seems that the AHB bus can access the Host Bus interface either directly or through the FIFO. However I have no idea what's the software mechanisms to do either.

    Assuming the WFIFO is implicitly used in all operations then your application could follow the below recommendation to avoid write or read stalls. The EPIWFIFOCNT indicates the number of spaces available in the WFIFO. When zero, it has no space to buffer another write. 

    I think one way to find out if the WFIFO is used implicitly is to first set a GPIO pin before making 4 writes to the EPI interface and then clear the pin. If the WFIFO is used, then you should see the pin clear before the 4 writes are complete. If not, the pin will be clear after the 4 writes are complete. Note that there is still write buffer inside the Cortex-M4 CPU so you may still see the pin clear slightly before the 4 EPI writes are complete.

    Guy Ovadia said:

    2.  same question as #1 but for the read-FIFO.

    The NBRFIFO is for non-blocking reads. You should be able to use it in the XFIFO as well. Please refer to the Non-blocking read section in the datasheet for detail such as the starting address of the read, the size and the count of the reads and NBRFIFO threshold upon which to interrupt the CPU to read the data. 

    Guy Ovadia said:
    3.  I also don't understand the relationship / priority between reads and writes. obviously, at any given point in time the bus can only do one of the two (half-duplex). So, what happens if the EPI's write FIFO currently has some filled entries that "want" to go out into the external bus, but there is also a non-blocking ready underway... what will happen? reads, writes, errors...? To put the question more constructively: What would be a good approach that will allow me to both constantly dump a lot of data (writes) out of the bus, but also be monitoring any occasional incoming data that comes in from time to time?

    Register 27: EPI FIFO Level Selects (EPIFIFOLVL), offset 0x200
    This register allows selection of the FIFO levels which trigger an interrupt to the interrupt controller
    or, more efficiently, a DMA request to the μDMA. The NBRFIFO select triggers on fullness such
    that it triggers on match or above (more full) in order for the processor or the μDMA to extract the
    read data. The WFIFO triggers on emptiness such that it triggers on match or below (less entries)
    in order for the processor or the μDMA to insert more write data.
    It should be noted that the FIFO triggers are not identical to other such FIFOs in TM4C1294NCPDT
    peripherals. In particular, empty and full triggers are provided to avoid wait states when using blocking
    operations.
    The settings in this register are only meaningful if the μDMA is active or the interrupt is enabled.
    Additionally, this register allows protection against writes stalling and notification of performing
    blocking reads which stall for extra time due to preceding writes. The two functions behave in a
    non-orthogonal way because read and write are not orthogonal.
    The write error bit configures the system such that an attempted write to an already full WFIFO
    abandons the write and signals an error interrupt to prevent accidental latencies due to stalling
    writes.
    The read error bit configures the system such that after a read has been stalled due to any preceding
    writes in the WFIFO, the error interrupt is generated. Note that the excess stall is not prevented,
    but an interrupt is generated after the fact to notify that it has happened.

  • Hi Charles,

    thanks, those excerpts were very helpful. I didn't figure that the register descriptions had such crucial information about the behavior of the EPI, usually the preceding textual sections deliver all the core info. In particular, this excerpt:

    "Additionally, this register allows protection against writes stalling and notification of performing
    blocking reads which stall for extra time due to preceding writes."

    as well as this (from the actual RSERR bit description):

    "The Read Stalled error interrupt is disabled. Reads behave as
    normal and are stalled until any preceding writes have completed
    and the read has returned a result. "

    answer my question:

    "So, what happens if the EPI's write FIFO currently has some filled entries that "want" to go out into the external bus, but there is also a non-blocking ready underway... what will happen? reads, writes, errors...?"

    the answer is: writes will happen. apparently they have a priority over reads.

    p.s. I'll try to do the test you suggested to determine if the WFIFO is used in XFIFO mode, I'll report the results here.

  • Hi Guy,
    Hopefully it clarifies a lot of your doubts and do share with us what you see. It will greatly benefit the community who will use EPI XFIFO in the future. Thanks.
  • OK, I tried the test Charles suggested. Here is the code:

    if ((HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_XFEMPTY) == 0) {  // not empty: there's stuff to read
        in_char = HWREGB(0xA0000000);
        while (EPIWriteFIFOCountGet(EPI0_BASE) < 4);  // wait until there's room to transmit
        set_yellow_led(ON);
        HWREGB(0xA0000000) = in_char;
        HWREGB(0xA0000000) = in_char;
        HWREGB(0xA0000000) = in_char;
        HWREGB(0xA0000000) = in_char;
        set_yellow_led(OFF);
    }
    

    and this is the result, showing a logic analyzer trace of the WR line (signal 00) along with the I/O toggled during the writes to the mapped RAM (signal 01).

    It can be clearly seen that the 4 writes to the mapped RAM return immediately and the actual EPI bus transactions happen a bit later. This suggests that the XFIFO mode does use the Write-FIFO of the EPI.

  • Hi Guy,

      Thanks for sharing the results. The WIFO is implicitly used and hence disprove my earlier interpretation.