EZ-USB FX3 Technical Reference Manual, Document Number: 001-76074 Rev. *F 72
FX3 DMA Subsystem
The Global SCK_INTR register is read-only and the interrupt bits are cleared by clearing the interrupt cause or bit in the per-
socket SCK_INTR register itself. Once the CPU finds the socket number, it can find the source of the interrupt from the per-
socket SCK_INTR register of the corresponding socket.
5.6 Programming Sequence
5.6.1 Initialization
The default state of most sockets is indicated in the register map. Briefly, in the default state the socket is disabled and holds
no descriptor. Sockets are initialized as described in the 5.5.5.2 Initializing a Socket on page 68 .The same steps are detailed
below.
1. Initialize and allocate descriptor(s) in the main memory. The base address for descriptor allocation starts at 0x40000010.
In addition to specifying where the data buffer is located, each descriptor data structure must be configured properly with
its associated peripherals, sockets, and event/interrupt flags for both consumer and producer halves. If a list of descriptors
is used, descriptors can be chained with DSCR_CHAIN field of the descriptor structure. The DSCR_CHAIN specifies the
next descriptor number in the chain for both consumer and producer. A value of 0xFFFF terminates the descriptor chain.
2. Initialize sockets with SCK_xxx registers. In addition to specifying the associated descriptor (or top of the descriptor chain)
for the socket, these registers control how the socket behaves during the transfer, that is, ., interrupt/event generation and
current status of the socket.
3. Enable socket(s). Sockets can be enabled by writing the SCK_STATUS.go_enable bit. Once socket is enabled, it loads
the descriptor specified in SCK_DSCR register (top of descriptor chain) and starts the transfer accordingly.
5.6.1.1 Producer Half
When the socket for the producer half is enabled, it loads the descriptor specified in the SCK_DSCR register and makes it
active. With a valid buffer specified by the active descriptor, the socket goes to the active state and starts to fill the data buffer.
When the producer socket has filled the buffer, it updates the active descriptor associated with the buffer in main memory and
then sends a produce event to its peer consuming socket defined in the dscr_sync field of the descriptor structure along with
the descriptor number itself.
If there is a valid peripheral consumer socket specified in the descriptor, the producer notifies the consumer socket by writing
to the EVENT register in the consumer socket. The EVENT value will indicate the DMA descriptor that has been updated and
specify that a PRODUCE event is being sent.
If the descriptor does not specify a valid consumer socket, it is the firmware's responsibility to identify and work on the
descriptor that has been produced. The SCK_INTR_MASK.PRODUCE_EVENT bit can be set to enable notification of
produce events to the CPU through the DMA interrupt. The firmware can then take appropriate actions to use the data that
has been received.
The producer socket then loads the next descriptor in the chain and makes it active. If the descriptor indicates its buffer space
is not available, the socket goes to the stall state. When the buffer is available as indicated from the socket's EVENT register,
the socket becomes active again and starts to fill the buffer pointed by the active descriptor.
If a consume event is received for the current descriptor, the descriptor is either updated using data in the EVENT register or
reloaded from memory.
If no descriptor is available (next_dscr=0xFFFF), the socket goes to the suspend state.
A DMA transfer from a peripheral to the system memory involves only the producer half.
5.6.1.2 Consumer Half
Similar to the producer half, when the socket for the consumer half is enabled, it loads the descriptor specified in the
SCK_DSCR register and makes it active. If the consumer socket is enabled at the same time as the producer socket, most
likely the buffer is waiting to be filled by the producer and is not available for the consumer socket. In this case, the consumer
socket goes to the stall state and waits for the buffer to become available upon a produce event.