10.3.5.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:
- packet by packet (see Bulk IN or Interrupt IN: Sending a Packet Under Application Control (Device to Host) below)
- 64 Kbytes (see Bulk IN or Interrupt IN: Sending a Packet Under Application Control (Device to Host) below)
- DMA (see Bulk IN or Interrupt IN: Sending a Buffer Using DMA (Device to Host) below)
- 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).
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.