PSOC6 USB via DMA working example

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
GuGa_1322886
Level 4
Level 4
5 solutions authored 25 sign-ins First comment on KBA

HI, I'm trying to  configure the USB block in PSOC6 to operate correctly via DMA. The pieces of information are there, but I find obscure how to put them together. I seems that most of the configuration can be done in Modus Toolbox with Device Configurator, but what parts must be completed in user code to get it up and running?.

Also,I can't fine the answer of how to handle some comon situations, like, how to work with data blocks larger than the internal EP buffer, or, how to dynamically adjust for different message lengths.

Is there a working example somewhere ?

This AN228753_DMA_on_PSoC_6_MCU-ApplicationNotes is a good start to understand how DMA works, but it doesn't touch the case of a USB peripheral.  I think that this case deserves an application note by itself.

Thanks!

0 Likes
1 Solution
Ekta_N
Moderator
Moderator
Moderator
750 replies posted First like given 250 solutions authored

Hello @GuGa_1322886 

When using DMA with USB there can be two modes of operation:

1. DMA with Manual Buffer Management 
2. DMA with Automatic Buffer Management

In DMA with Automatic Buffer Management mode, the DMA transfers data between system SRAM and endpoint buffer automatically. The DMA automatically accesses the system SRAM while communicating via USB. This approach provides the ability to get the total endpoint buffer, which exceeds 512 bytes.

The automatic buffer management implies the special endpoint buffer allocation scheme. The 512 bytes USBFS buffer is divided between endpoints as follows:

  • 32 bytes are allocated for each active endpoint (endpoint which presents in the device descriptors).
  • Remaining space is left for the common area. The common area is used as FIFO to accept the data when endpoint buffer is full while communication. The USBFS block generates DMA requests as soon as communication starts to keep common area fully loaded for IN direction and keep common area empty for OUT direction. For example, device uses all 8 endpoints. The endpoint buffers consume 8 * 32 = 256 bytes, remaining bytes is common area 512 – 256 = 256 bytes. If only six endpoints are used, the common area size would then be 320 bytes (512 - (6 * 32)).

This mode is generally preferred for isochronous transfers (like audio data tranfer) in which data needs to be continuously transferred from Host to device or vice-versa.

You can refer to the following code example: https://github.com/Infineon/mtb-example-psoc6-usb-audio-recorder which uses DMA in automatic buffer management mode to see how configurations are made for this mode.

Best Regards
Ekta

View solution in original post

0 Likes
5 Replies
Ekta_N
Moderator
Moderator
Moderator
750 replies posted First like given 250 solutions authored

Hello @GuGa_1322886 

When using DMA with USB there can be two modes of operation:

1. DMA with Manual Buffer Management 
2. DMA with Automatic Buffer Management

In DMA with Automatic Buffer Management mode, the DMA transfers data between system SRAM and endpoint buffer automatically. The DMA automatically accesses the system SRAM while communicating via USB. This approach provides the ability to get the total endpoint buffer, which exceeds 512 bytes.

The automatic buffer management implies the special endpoint buffer allocation scheme. The 512 bytes USBFS buffer is divided between endpoints as follows:

  • 32 bytes are allocated for each active endpoint (endpoint which presents in the device descriptors).
  • Remaining space is left for the common area. The common area is used as FIFO to accept the data when endpoint buffer is full while communication. The USBFS block generates DMA requests as soon as communication starts to keep common area fully loaded for IN direction and keep common area empty for OUT direction. For example, device uses all 8 endpoints. The endpoint buffers consume 8 * 32 = 256 bytes, remaining bytes is common area 512 – 256 = 256 bytes. If only six endpoints are used, the common area size would then be 320 bytes (512 - (6 * 32)).

This mode is generally preferred for isochronous transfers (like audio data tranfer) in which data needs to be continuously transferred from Host to device or vice-versa.

You can refer to the following code example: https://github.com/Infineon/mtb-example-psoc6-usb-audio-recorder which uses DMA in automatic buffer management mode to see how configurations are made for this mode.

Best Regards
Ekta

0 Likes

Hi Ekta,

Aftter reading the documentation and your comments, it seems that Automatic Buffer Management is the way to go.  Thanks for the example link. That was the final piece of the puzzle that I needed.

Incidentally, this project doesn't show up in MTB Project Creator when I search for it with keywords USB, DMA or Audio.

0 Likes
GuGa_1322886
Level 4
Level 4
5 solutions authored 25 sign-ins First comment on KBA

Hi Ekta,

I'm afraid that this is still not solved.  I couldn't  do much with the Audio example. I'm trying to reproduce the settings with a USB CDC class.  But it turns out that the audio example doesn't make use of the following functions, that according to the documentation must be called in user code:

Cy_DMA_Descriptor_Init() for each descriptor

Cy_DMA_Descriptor_SetSrcAddress()   - For the IN end poit address is memory buffer,  for the OUT end point I couldn't figure out where is the USB source. In the UART device is KIT_UART_HW->TX_FIFO_WR (from the Uart with DMA example).

Cy_DMA_Descriptor_SetDstAddress() - same problem as above, what is the USB hook?

Cy_DMA_Channel_Init()

Cy_DMA_Descriptor_SetNextDescriptor()

And a few others for interrupt and DMA enable.  This are the only two initialization functions that you find in the audio example:

void usb_comm_init(void)
{
    /* Start the USB Block */
    Cy_USB_Dev_Init(CYBSP_USBDEV_HW,
                    &CYBSP_USBDEV_config,
                    &usb_drvContext,
                    &usb_devices[USBCOMM_DEVICE_ID],
                    &usb_devConfig,
                    &usb_devContext);

    Cy_USB_Dev_Audio_Init(NULL,
                          &usb_audioContext,
                          &usb_devContext);

    /* Initialize the USB interrupts */
    Cy_SysInt_Init(&usb_high_interrupt_cfg,   &usb_high_isr);
    Cy_SysInt_Init(&usb_medium_interrupt_cfg, &usb_medium_isr);
    Cy_SysInt_Init(&usb_low_interrupt_cfg,    &usb_low_isr);   
}
void audio_in_init(void)
{
    /* Register Data Endpoint Callbacks */
    Cy_USBFS_Dev_Drv_RegisterEndpointCallback(CYBSP_USBDEV_HW, 
                                              AUDIO_STREAMING_IN_ENDPOINT, 
                                              audio_in_endpoint_callback, 
                                              &usb_drvContext);

    /* Initialize the PDM PCM block */
    cyhal_pdm_pcm_init(&pdm_pcm, PDM_DATA, PDM_CLK, NULL, &pdm_pcm_cfg);
}

The DMA initialization must be done somewhere deep in the Cy_USB_Dev_Audio_Init() but I couldn't find it. The code above suggests that all the hooks are done with  Cy_USB_Dev_Init() but obviously something is missing in my case, probably all the user code calls!.

I need to setup USB CDC with DMA for transmit strings of arbitrary lenght (2 bytes to 8kb or more) setup the buffer, start the send, and have DMA take care of the whole transmission. Can this be done with a USB CDC with DMA?

 

0 Likes
lock attach
Attachments are accessible only for community members.
GuGa_1322886
Level 4
Level 4
5 solutions authored 25 sign-ins First comment on KBA

UPDATE

The answer to my message of June 30 is that in fact the sample provided does not use DMA at all. After much digging and head scratching of where the magic happens. It turns out that disabling DMA in device configurator and changing the USB device from DMA automatic to CPU control it compiles and runs as good as before without any code modification. I have attached the modified example here that shows that no DMA is involved in this project.

0 Likes
Ekta_N
Moderator
Moderator
Moderator
750 replies posted First like given 250 solutions authored
0 Likes