72.6.9.3 Data IN

  • Bulk IN or Interrupt IN

    Data IN packets are sent by the device during the data or the status stage of a control transfer or during an (interrupt/bulk/isochronous) IN transfer. Data buffers are sent packet by packet under the control of the application or under the control of the DMA channel.

    There are three ways for an application to transfer a buffer in several packets over the USB:

  • Bulk IN or Interrupt IN: Sending a Packet Under Application Control (Device to Host)

    The application can write one or several banks.

    A simple algorithm can be used by the application to send packets regardless of the number of banks associated to the endpoint.

    Algorithm description for each packet:
    • The application waits for the TXRDY flag to be cleared in the UDPHS_EPTSTAx register before it can perform a write access to the DPR.
    • The application writes one USB packet of data in the DPR through the 64 Kbytes endpoint logical memory window.
    • The application sets TXRDY flag in the UDPHS_EPTSETSTAx register.

    The application is notified that it is possible to write a new packet to the DPR by the TXRDY interrupt. This interrupt can be enabled or masked by setting the TXRDY bit in the UDPHS_EPTCTLENB/UDPHS_EPTCTLDIS register.

    Algorithm description to fill several packets:

    Using the previous algorithm, the application is interrupted for each packet. It is possible to reduce the application overhead by writing linearly several banks at the same time. The AUTO_VALID bit in the UDPHS_EPTCTLx must be set by writing the AUTO_VALID bit in the UDPHS_EPTCTLENBx register.

    The auto-valid-bank mechanism allows the transfer of data (IN and OUT) without the intervention of the CPU. This means that bank validation (set TXRDY or clear the RXRDY_TXKL bit) is done by hardware.
    • The application checks the BUSY_BANK_STA field in the UDPHS_EPTSTAx register. The application must wait that at least one bank is free.
    • The application writes a number of bytes inferior to the number of free DPR banks for the endpoint. Each time the application writes the last byte of a bank, the TXRDY signal is automatically set by the UDPHS.
    • If the last packet is incomplete (i.e., the last byte of the bank has not been written) the application must set the TXRDY bit in the UDPHS_EPTSETSTAx register.

    The application is notified that all banks are free, so that it is possible to write another burst of packets by the BUSY_BANK interrupt. This interrupt can be enabled or masked by setting the BUSY_BANK flag in the UDPHS_EPTCTLENB and UDPHS_EPTCTLDIS registers.

    This algorithm must not be used for isochronous transfer. In this case, the ping-pong mechanism does not operate.

    A Zero Length Packet can be sent by setting just the TXRDY flag in the UDPHS_EPTSETSTAx register.

  • Bulk IN or Interrupt IN: Sending a Buffer Using DMA (Device to Host)

    The UDPHS integrates a DMA host controller. This DMA controller can be used to transfer a buffer from the memory to the DPR or from the DPR to the processor memory under the UDPHS control. The DMA can be used for all transfer types except control transfer.

    Example DMA configuration:
    • 1. Program UDPHS_DMAADDRESS x with the address of the buffer that should be transferred.
    • 2. Enable the interrupt of the DMA in UDPHS_IEN.
    • 3. Program UDPHS_ DMACONTROLx:
      • Size of buffer to send: size of the buffer to be sent to the host.
      • END_B_EN: the endpoint can validate the packet (according to the values programmed in the AUTO_VALID and SHRT_PCKT fields of UDPHS_EPTCTLx) (see UDPHS_EPTCTLDISx and the figure Autovalid with DMA).
      • END_BUFFIT: generate an interrupt when the BUFF_COUNT field in the UDPHS DMA Channel Status register (UDPHS_DMASTATUSx) reaches 0.
      • CHANN_ENB: run and stop at end of buffer.

The auto-valid-bank mechanism allows the transfer of data (IN & OUT) without the intervention of the CPU. This means that bank validation (set TXRDY or clear RXRDY_TXKL) is done by hardware.

A transfer descriptor can be used. Instead of programming the register directly, a descriptor should be programmed and the address of this descriptor is then given to UDPHS_DMANXTDSC to be processed after setting the LDNXT_DSC field (Load Next Descriptor Now) in UDPHS_DMACONTROLx register.

The structure that defines this transfer descriptor must be aligned.

Each buffer to be transferred must be described by a DMA Transfer descriptor (see UDPHS DMA Channel Transfer Descriptor). Transfer descriptors are chained. Before executing transfer of the buffer, the UDPHS may fetch a new transfer descriptor from the memory address pointed by the UDPHS_DMANXTDSCx register. Once the transfer is complete, the transfer status is updated in the UDPHS_DMASTATUSx register.

To chain a new transfer descriptor with the current DMA transfer, the DMA channel must be stopped. To do so, INTDIS_DMA and TXRDY may be set in the UDPHS_EPTCTLENBx register. It is also possible for the application to wait for the completion of all transfers. In this case the LDNXT_DSC bit in the last transfer descriptor UDPHS_DMACONTROLx register must be set to 0 and the CHANN_ENB bit set to 1.

Then the application can chain a new transfer descriptor.

The INTDIS_DMA can be used to stop the current DMA transfer if an enabled interrupt is triggered. This can be used to stop DMA transfers in case of errors.

The application can be notified at the end of any buffer transfer (via UDPHS_DMACONTROLx.ENB_BUFFIT).

Figure 72-6. Data IN Transfer for Endpoint with One Bank

Figure 72-7. Data IN Transfer for Endpoint with Two Banks
Figure 72-8. Data IN Followed By Status OUT Transfer at the End of a Control Transfer
Note: A NAK handshake is always generated at the first status stage token.

Figure 72-9. Data OUT Followed by Status IN Transfer
Note: Before proceeding to the status stage, the software should determine that there is no risk of extra data from the host (data stage). If not certain (non-predictable data stage length), then the software should wait for a NAK-IN interrupt before proceeding to the status stage. This precaution should be taken to avoid collision in the FIFO.
Figure 72-10. Autovalid with DMA
Note: In the illustration above, Autovalid validates a bank as full, although this might not be the case, in order to continue processing data and to send to DMA.
  • Isochronous IN

    Isochronous-IN is used to transmit a stream of data whose timing is implied by the delivery rate. Isochronous transfer provides periodic, continuous communication between host and device.

    It ensures bandwidth and low latencies appropriate for telephony, audio, video, etc.

    If the endpoint is not available (TXRDY_TRER = 0), then the device does not answer the host. An ERR_FL_ISO interrupt is generated in the UDPHS_EPTSTAx register and, once enabled, sent to the CPU.

    The STALL_SNT command bit is not used for an ISO-IN endpoint.

  • High Bandwidth Isochronous Endpoint Handling: IN Example

    For high bandwidth isochronous endpoints, the DMA can be programmed with the number of transactions (UDPHS_DMACONTROLx.BUFF_LENGTH) and the system should provide the required number of packets per microframe, otherwise, the host will notice a sequencing problem.

    A response should be made to the first token IN recognized inside a microframe under the following conditions:
    • If at least one bank has been validated, the correct DATAx corresponding to the programmed Number Of Transactions per Microframe (NB_TRANS) should be answered. In case of a subsequent missed or corrupted token IN inside the microframe, the USB 2.0 Core available data bank(s) that should normally have been transmitted during that microframe shall be flushed at its end. If this flush occurs, an error condition is flagged (UDPHS_EPTSTAx.ERR_FLUSH is set).
    • If no bank is validated yet, the default DATA0 ZLP is answered and underflow is flagged (UDPHS_EPTSTAx.ERR_FL_ISO is set). Then, no data bank is flushed at the microframe end.
    • If no data bank has been validated at the time when a response should be made for the second transaction of NB_TRANS = 3 transactions microframe, a DATA1 ZLP is answered and underflow is flagged (UDPHS_EPTSTAx.ERR_FL_ISO is set). If and only if remaining untransmitted banks for that microframe are available at its end, they are flushed and an error condition is flagged (UDPHS_EPTSTAx.ERR_FLUSH is set).
    • If no data bank has been validated at the time when a response should be made for the last programmed transaction of a microframe, a DATA0 ZLP is answered and underflow is flagged (UDPHS_EPTSTAx.ERR_FL_ISO is set). If and only if the remaining untransmitted data bank for that microframe is available at its end, it is flushed and an error condition is flagged (UDPHS_EPTSTAx.ERR_FLUSH is set).

If at the end of a microframe no valid token IN has been recognized, no data bank is flushed and no error condition is reported.

At the end of a microframe in which at least one data bank has been transmitted, if less than NB_TRANS banks have been validated for that microframe, an error condition is flagged (UDPHS_EPTSTAx.ERR_TRANS is set).

Error cases (in UDPHS_EPTSTAx):

  • ERR_FL_ISO: There was no data to transmit inside a microframe, so a ZLP is answered by default.
  • ERR_FLUSH: At least one packet has been sent inside the microframe, but the number of token INs received is less than the number of transactions actually validated (TXRDY_TRER) and likewise with the NB_TRANS programmed.
  • ERR_TRANS: At least one packet has been sent inside the microframe, but the number of token INs received is less than the number of programmed NB_TRANS transactions and the packets not requested were not validated.
  • ERR_FL_ISO + ERR_FLUSH: At least one packet has been sent inside the microframe, but the data has not been validated in time to answer one of the following token INs.
  • ERR_FL_ISO + ERR_TRANS: At least one packet has been sent inside the microframe, but the data has not been validated in time to answer one of the following token INs and the data can be discarded at the microframe end.
  • ERR_FLUSH + ERR_TRANS: The first token IN has been answered and it was the only one received, a second bank has been validated but not the third, whereas NB_TRANS was waiting for three transactions.
  • ERR_FL_ISO + ERR_FLUSH + ERR_TRANS: The first token IN has been treated, the data for the second Token IN was not available in time, but the second bank has been validated before the end of the microframe. The third bank has not been validated, but three transactions have been set in NB_TRANS.