USB full speed device interface (USB) UM0306
426/519
Endpoint initialization
The first step to initialize an endpoint is to write appropriate values to the
ADDRn_TX/ADDRn_RX registers so that the USB Peripheral finds the data to be
transmitted already available and the data to be received can be buffered. The EP_TYPE
bits in the register must be set according to the endpoint type, eventually using the
EP_KIND bit to enable any special required feature. On the transmit side, the endpoint must
be enabled using the STAT_TX bits in the register and COUNTn_TX must be initialized. For
reception, STAT_RX bits must be set to enable reception and COUNTn_RX must be written
with the allocated buffer size using the BL_SIZE and NUM_BLOCK fields. Unidirectional
endpoints, except Isochronous and double-buffered bulk endpoints, need to initialize only
bits and registers related to the supported direction. Once the transmission and/or reception
are enabled, register and locations ADDRn_TX/ADDRn_RX, COUNTn_TX/COUNTn_RX
(respectively), should not be modified by the application software, as the hardware can
change their value on the fly. When the data transfer operation is completed, notified by a
CTR interrupt event, they can be accessed again to re-enable a new operation.
IN packets (data transmission)
When receiving an IN token packet, if the received address matches a configured and valid
endpoint one, the USB Peripheral accesses the contents of ADDRn_TX and COUNTn_TX
locations inside buffer descriptor table entry related to the addressed endpoint. The content
of these locations is stored in its internal 16 bit registers ADDR and COUNT (not accessible
by software). The packet memory is accessed again to read the first word to be transmitted
(Refer to Structure and usage of packet buffers on page 423) and starts sending a DATA0 or
DATA1 PID according to bit DTOG_TX. When the PID is completed, the first byte from the
word, read from buffer memory, is loaded into the output shift register to be transmitted on
the USB bus. After the last data byte is transmitted, the computed CRC is sent. If the
addressed endpoint is not valid, a NAK or STALL handshake packet is sent instead of the
data packet, according to STAT_TX bits in the register.
The ADDR internal register is used as a pointer to the current buffer memory location while
COUNT is used to count the number of remaining bytes to be transmitted. Each word read
from the packet buffer memory is transmitted over the USB bus starting from the least
significant byte. Transmission buffer memory is read starting from the address pointed by
ADDRn_TX for COUNTn_TX/2 words. If a transmitted packet is composed of an odd
number of bytes, only the lower half of the last word accessed will be used.
On receiving the ACK receipt by the host, the register is updated in the following way:
DTOG_TX bit is toggled, the endpoint is made invalid by setting STAT_TX=10 (NAK) and bit
CTR_TX is set. The application software must first identify the endpoint, which is requesting
microcontroller attention by examining the EP_ID and DIR bits in the register. Servicing of
the CTR_TX event starts clearing the interrupt bit; the application software then prepares
another buffer full of data to be sent, updates the COUNTn_TX table location with the
number of byte to be transmitted during the next transfer, and finally sets STAT_TX to ‘11’
(VALID) to re-enable transmissions. While the STAT_TX bits are equal to ‘10’ (NAK), any IN
request addressed to that endpoint is NAKed, indicating a flow control condition: the USB
host will retry the transaction until it succeeds. It is mandatory to execute the sequence of
operations in the above mentioned order to avoid losing the notification of a second IN
transaction addressed to the same endpoint immediately following the one which triggered
the CTR interrupt.