Author: KandlaguntaR_36 Version: **
Translation - Japanese: FX3/CX3のオーバーライドモードのDMAチャネル - KBA229098 - Community Translated (JA)
Why should a DMA channel be configured in override mode FX3/CX3?
Applications/Use case of DMA Channel in Override Mode
DMA channel can be used in override mode when the user-defined buffer is to be sent along with the data, which will be transferred through the DMA channel.
Configuring a DMA channel in override mode means sending and receiving the contents of user-defined buffer to and from the consumer socket and the producer socket of the DMA channel respectively.
Consider an example where the DMA channel is configured from processor interface block (PIB) to USB interface block (UIB) and you want to send data, which does not come from the PIB socket, to UIB. In this case, user-defined buffer can be sent by configuring this DMA channel in override mode.
The other application of DMA channel in override mode can be a USB Video Class Device application where you want to send independent buffers for header and footer without changing the GPIF II state machine. See the threads, https://community.cypress.com/thread/49788, https://community.cypress.com/thread/50601 for similar applications.
Mass storage class examples in the SDK also implement DMA channel in override mode.
How can a DMA channel be configured in override mode in FX3/CX3?
A DMA channel is created between a producer socket and a consumer socket. A DMA channel can be in either of the following DMA states:
- CY_U3P_DMA_NOT_CONFIGURED: DMA channel is unconfigured. This state occurs only when using a stale/uninitialized channel structure. This channel state is set to this when a channel is destroyed.
- CY_U3P_DMA_CONFIGURED: DMA channel has been configured successfully. The channel reaches this state through the following conditions:
- Channel is successfully created.
- Channel is reset.
- A finite transfer has been successfully completed.
- One of the override modes have completed successfully.
- CY_U3P_DMA_ACTIVE: DMA channel has an active ongoing transaction. This state is reached when a SetXfer call is invoked and the transfer is ongoing.
- CY_U3P_DMA_ERROR: DMA channel has encountered an error. This state is reached when a DMA hardware error is detected.
- CY_U3P_DMA_IN_COMPLETION: DMA channel is waiting for all data to drain out. This state is reached when transfer is complete from the producer side, but the channel is waiting for the consumer to drain all data.
- CY_U3P_DMA_ABORTED: The channel is in aborted state. This state is reached when an Abort call is made.
- CY_U3P_DMA_NUM_STATES: Number of states of the DMA channel. This is not a valid state and is just a place holder.
- CY_U3P_DMA_PROD_OVERRIDE: DMA channel is working in producer socket override mode. This state is reached when a SetupSend call is invoked and the transfer is ongoing.
- CY_U3P_DMA_CONS_OVERRIDE: DMA channel working in consumer socket override mode. This state is reached when a SetupRecv call is invoked and the transfer is ongoing.
Table 1. APIs to Configure DMA Channel in Override Mode
CyU3PDmaChannelSetupRecvBuffer (CyU3PDmaChannel *handle, CyU3PDmaBuffer_t * buffer_p)
CyU3PDmaMultiChannelSetupRecvBuffer (CyU3PDmaMultiChannel *handle, CyU3PDmaBuffer_t * buffer_p, uint16_t multiSckOffset)
This function initiates the reading of data incoming from a DMA producer to the user defined buffer
CyU3PDmaChannelSetupSendBuffer (CyU3PDmaChannel *handle, CyU3PDmaBuffer_t *buffer_p)
CyU3PDmaMultiChannelSetupSendBuffer (CyU3PDmaMultiChannel *handle, CyU3PDmaBuffer_t * buffer_p, uint16_t multiSckOffset)
This function initiates the sending of the content of a user-provided buffer to the consumer of a DMA channel.
Note: For more details of these APIs, see the FX3APIGuide available in the SDK.
- The buffers used for DMA operations are expected to be allocated using the CyU3PDmaBufferAlloc call. If this is not the case, the buffer must be over allocated in such a way that the full buffer should be 32-byte aligned and should be a multiple of 32 bytes in size.
- The APIs listed in Table 1 can only be called when the DMA channel is in the CY_U3P_DMA_CONFIGURED state.
- These APIs cannot be called after the CyU3PDmaChannelSetXfer/CyU3PDmaMultiChannelSetXfer API, if this API is configured for infinite transfers, the DMA channel will be configured in the CY_U3P_DMA_ACTIVE state. If these APIs are called after the CyU3PDmaChannelSetXfer/CyU3PDmaMultiChannelSetXfer API, it will return an error 0x44
- If these APIs need to be called after the CyU3PDmaChannelSetXfer/CyU3PDmaMultiChannelSetXfer API, the transfers should be finite. After the completion of finite transfers, the DMA channel would get into the CY_U3P_DMA_CONFIGURED state, and then these APIs can be called.
- The DMA channel remains in either the CY_U3P_DMA_PROD_OVERRIDEstate or the CY_U3P_DMA_CONS_OVERRIDE state until the transfer is complete.
- When the DMA channel is in override mode and the transfer is yet not completed, the CyU3PDmaChannelSetXfer / CyU3PDmaMultiChannelSetXfer API cannot be called, as this API can only be called when DMA channel is in the CY_U3P_DMA_CONFIGURED state. If the API is called when the DMA channel is not in the CY_U3P_DMA_CONFIGURED state, the API will return an error 0x44.
Table 2. APIs to Check Completion of Data Transfers in Override Mode
CyU3PDmaMultiChannelWaitForCompletion (CyU3PDmaMultiChannel * handle, uint32_t waitOption )
CyU3PDmaChannelWaitForCompletion (CyU3PDmaChannel _ handle, uint32_t waitOption )
This function waits for the current DMA transaction to complete.
CyU3PDmaChannelWaitForRecvBuffer (CyU3PDmaChannel *handle, CyU3PDmaBuffer_t *buffer_p, uint32_t waitOption )
CyU3PDmaMultiChannelWaitForRecvBuffer (CyU3PDmaMultiChannel *handle, CyU3PDmaBuffer_t * buffer_p, uint32_t waitOption )
This function waits until an override read operation is completed.
Note: For more details of these APIs, see the FX3APIGuide available in the SDK.
CY_U3P_DMA_CB_SEND_CPLTorCY_U3P_DMA_CB_RECV_CPLT callback events can be registered in the DMA channel configuration while creating the DMA channel. These events can be handled in the callback function, which would be called when SendBuffer or ReceiveBuffer (transfer) call has been completed respectively.
Is there any FX3 example to configure DMA channel in override mode?
See the GpifToUsb example attached with this knowledge base article (KBA), which overrides the DMA channel to send user-defined buffer in addition to the normal data transfer, that is from GPIF block to USB block.
The functionality of this example is to send a user-defined buffer through the DMA channel in the override mode during the normal data transfers from GPIF to USB.
The CY_U3P_DMA_TYPE_MANUAL channel is created between the PIB block and the UIB block. PIB socket is configured as producer and one UIB socket is configured as the consumer.
The user-defined buffer is sent by calling the SendDebugMessage() function before calling the CyU3PDmaChannelSetXfer API.
The second parameter of the CyU3PDmaChannelSetXfer and CyU3PDmaMultiChannelSetXfer APIs indicate the desired transaction size in units, associated with the selected DMA mode. Channel will revert to idle state after the specified amount of data has been transferred.
There is a difference in the implementation of these APIs:
- CyU3PDmaChannelSetXfer: Both the sockets, consumer socket and producer socket, are configured for the desired transaction size.
- CyU3PDmaMultiChannelSetXfer: Only the consumer socket is configured for desire size and the producer socket, by default, is configured for infinite transfers.
Completion of the transfer of data in user-defined buffer can be checked using CY_U3P_DMA_CB_SEND_CPLT. This event is registered for the callback. This would register a callback when the user-provided buffer is sent. On receiving this event, the CyU3PDmaChannelSetXfer API is called with the fixed amount of data transfer (32).
In the CyFxAppThread_Entry function, DMA_Override variable is tracked. When the DMA channel is switched from DMA override mode to normal mode, the CyU3PDmaChannelWaitForCompletion API is called to wait for the transfers through the CyU3PDmaChannelSetXfer API to complete. When these transfers are completed, the DMA channel is switched back to DMA override mode by calling the SendDebugMessage() function
For more details, see the msc_examples which implement the DMA channel in override mode. You can find msc_examples at C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\msc_examples.