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.

TMS320C5535: USB endpoint control registers not working as expected.

Part Number: TMS320C5535

I tried a simple test and the behavior of the PERI_TXCSR register does not seem to follow the spec.

I'm using address 0x8512 for non-indexed version of endpoint 1 register.

TXMAXP is set to 800 and the FIFO is configured for 2048 bytes (SZ = 7, DPB = 1) and ISOUPDATE bit is set in POWER register.

With no IN packets being requested from host.

I write a packet to the FIFO and set the TXPKTRDY bit in PERI_TXCSR

    - this generates an unexpected interrupt on endpoint 1 and a readback of PERI_TXCSR shows FIFONOTEMPTY and TXPKTRDY bits both clear

    - after some amount of time (less than 1ms but I didn't poll it to measure), FIFONOTEMPTY comes back set but TXPKTRDY bit still clear

I write a second packet to the FIFO (for double buffering)

    - does not generate an interrupt

    - after some amount of time both FIFONOTEMPTY and TXPKTRDY bits read as set (as expected)

At this point I try clearing the FIFO by FLUSHING but setting the FLUSH bit in PERI_TXCSR (twice at least, actually tried several times) seems to have no effect at all.

   - both FIFONOTEMPTY and TXPKTRDY remain set even if written as zeros, no interrupts are generated

Starting a transfer from the host confirms (via bus analyzer) that the two packets written to the FIFO above are sent to the host.

So it seems that:

  1. When double buffering is enabled you get an interrupt the first time you set the TXPKTRDY bit (because TXPKTRDY was then cleared??)
  2. When double buffering is enabled you only see TXPKTRDY bit set when two packets have been written to the FIFO
  3. FLUSH bit appears to have no effect when 2 packets are in the FIFO

But if you set the FLUSH bit when only one packet is in the FIFO, and after the FIFONOTEMPTY bit reads 1 then you do get an interrupt and the FIFONOTEMPTY bit comes back as clear.  Despite the fact that the spec says the FLUSH bit has no effect if the TXPKTRDY bit is clear.

  • Hi Thomas,

    Before I answer your questions, can you tell us more about your settings:

    How do you write a packet to the FIFO, are you using CDMA or CPU copy?

    Which CSL USB example your code is based on?

    What program is running on the USB host?

    Since you said that the USB host never issued and IN token, so there should be no IN data from C5535 to the USB host, unless the USB host program does something behind the scenes.

    Best regards,

    Ming

  • I write the packet to the FIFO using CPU writes (ioport writes directly to fifo registers)

    We started with the code from the C55x connected audio framework as a basis but rewrote it.  We did, for the most part, retain the same sequencea for initialization and endpoint setup from a register read/write perspective but retained none of the data structures and code of the CAF.

    Host is running ubuntu, but apart from discovery the tests I mention are done with nothing running on host.   I mention that there is no IN request from host (none was expected) because that makes it seem that the interrupt generated when writing the first packet is anomolous.

    I'm just trying to test the FIFO double buffering by writing 2 packets then clearing them with a FIFO flush.

  • Hi Thomas,

    The only thing seems strange to me is that when the first packet is sent to the FIFO, the FIFONOTEMPTY and TXPKTRDY are cleared, and the interrupt is generated. Do you know what interrupt has been generated?

    In theory, since there is no packet have been sent out, there should be no interrupt to generated. Also since the TX FIFO still has a packet, so the FIFONOTEMPTY and TXPKTRDY should be 1.

    Can you try the same with the single buffer setting?

    Thanks!

    Ming

  • Actually, after writing one packet the FIFONOTEMPTY flag is set, just not immediately.  The interrupt generated is the endpoint 1 tx interrupt (bit 0 of INTMASKEDR1, 0x8038)

    The only way the interrupt makes sense to me is that, when double buffering, the peripheral clears the TXPKTRDY flag when moving the packet to the "on-deck" position in the FIFO to be ready to send.  So when the second packet is written which cannot be advanced in the FIFO the TXPKTRDY bit stays set and no interrupt is generated.

    IMO, the troubling part is the fact that the FIFO cannot be cleared by writing the FLUSHFIFO flag, no matter how many times you set it.

    I did run a test without double buffering and after writing a packet both FIFONOTEMPTY and TXPKTRDY flags came back set (again, not immediately) and no interrupt is generated when setting TXPKTRDY.  Also, when both bits are set the FIFO can be cleared by setting FLUSHFIFO (though I did find that I had to write FIFONOTEMPTY and TXPKTRDY flags to zero when setting FIFONOTEMPTY).  This write  also generates an interrupt (as expected with a 1 to 0 transition of TXPKTRDY).

    We are testing a workaround where, instead of flushing the FIFO between ISO input streams, we don't start pushing data to the tx FIFO until the underflow bit is set, thus confirming the FIFO is empty.  Though not ideal because it results in the sending of stale data when the ISO IN requests start for the new stream, it's better than risking overflowing the FIFO.  When this occurs, on the next ISO IN request the device will send a double-sized packet which in our case is larger than the maximum allowable for a fullspeed device and the host immediately suspends the device.

  • Hi Thomas,

    The TRM is not very clear about the INTMASKEDR1. In fact, the bit 0 is for EP0 (IN/OUT). Bit 1-4 are for TXEP[n], bit 8 - 12 are for RXEP[n], so the bit 0 is not for EP1 TX.

    As of the FLUSHFIFO bit does not clear the FIFO, according to the TRM, FlushFIFO has no effect unless the TXPKTRDY bit is set. After you set the TXPKTRDY, it will be cleared automatically. You do not need to set TXPKTRDY. On the other hand, you do not need to set FIFONOTEMPTY, it will set to 1 automatically, but you do need to clear it manually.

      

    Since you are using the ISO transfer, have you set the ISO (bit 14) of PERI_TXCSR?

    Best regards,

    Ming

  • I misstated the INTMASKEDR1 bit I test to determine the ep1 tx interrupt.  I'm testing bit 1 not 0.

    >  if(wIntSource1 & 0x0002){ // endpoint 1 tx
    >      epEvt = ASI_USB_ENDPOINT_EVENT_INTERRUPT;
    >      MBX_post(&MBX_asi_usb_ep1tx, &epEvt, 0);
    > }

    I was setting the FLUSHFIFO bit when the TXPKTRDY bit was set but it wasn't getting cleared in double buffered mode.

    I do have bit 14 of PERI_TXCSR set and I keep it set when flushing.

  • Hi Thomas,

    I just noticed that in your first post:

    "TXMAXP is set to 800 and the FIFO is configured for 2048 bytes (SZ = 7, DPB = 1) and ISOUPDATE bit is set in POWER register."

    According to C5535 TRM, 

    "The value written to this register should match the wMaxPacketSize
    field of the Standard Endpoint Descriptor for the associated endpoint. A mismatch
    could cause unexpected results."

    Can you check that TXMAXP matches the wMaxPacketSize or not?

    The other thing worth attention is that there is only 4KB FIFO memory in total. You have used 2KB for EP1 TX. EP0 needed 64 byte for TX and 64 byte for RX. Please make sure no other EPs are using the FIFO memory at the same time.

    Best regards,

    Ming

  • Ming,

    Thank you for your replies, by the way.  I do appreciate it.

    I do use 800 in the endpiont descriptor for ep1 tx (ID 0x81) as well as TXMAXP and there are no other FIFOs currently (it's configured as a record only device) so the total allocations do not exceed 4K.

    -Tom

  • Hi Tom,

    I am running out of ideas for further debugging. Is it possible for you to share your test code and CCS project with us?

    Maybe we can debug from our side try to reproduce the problem and root cause it.

    Best regards,

    Ming