cancel
Showing results for 
Search instead for 
Did you mean: 

Enabling the UCPD DMA

RHelv.1
Associate II

Hello. I'm using an STM32G071KBU6N in a USBPD application. My application uses both internal UCPD ports.

I'm working on enabling the DMA and DMAMUX for use with the UCPD peripheral, for both Rx and Tx of both ports. I'm focusing on Tx right now, and can't seem to get it to work.

The reference manual has a great section "Use of DMA for Transmission" in section 38.4.11. I have the TXDMAEN bit set in the UCPD_CR register. I have the whole message programmed in memory. Right now, it's a dummy message consisting of two header bytes plus one data object consisting of four bytes, for a total of six bytes.

My DMAMUX is setup with the following register values:

DMAMUX_C0CR = 0x3A (DMAREQ_ID = UCPD1_RX)

DMAMUX_C1CR = 0x3B (DMAREQ_ID = UCPD1_TX)

DMAMUX_C2CR = 0x3C (DMAREQ_ID = UCPD2_RX)

DMAMUX_C3CR = 0x3D (DMAREQ_ID = UCPD2_TX)

No other DMAMUX registers have anything other than zeroes in them.

I setup DMA properly. For the UCPD1_TX channel, I setup:

DMA_CCR2 = 0x92

DMA_CNDTR2 = 0x6 (6 bytes)

DMA_CPAR2 = 0x4000A024 (The address of the UCPD1_TXDR register)

DMA_CMAR2 = The address of the memory for the data array

DMA_ISR = DMA_IFCR = 0

After that is setup I enable the DMA by setting the DMA_CCR2.EN bit to 1 (register = 0x93).

I write TXSEND to initiate the message transfer. However, the entire message isn't sent. I have to continually write TXSEND until the DMA buffer is empty (DMA_CNDTR2 = 0), which tells me the DMA is not implemented correctly.

Can someone let me know what step I am missing? I think the DMAMUX is not setup properly, but I'm unfamiliar with that peripheral and how to set it up. Ideally I would like to write TXSEND once, and my entire data is sent via DMA out the UCPD peripheral.

Thanks,

Rob

3 REPLIES 3
Yohann M.
ST Employee

Dear Rob

I advice you to check into our source code to understand how configure a TX DMA transfer for UCPD.

All the configurations are done into the STM32G0xx Devices:

DMA initialization is done thanks to the function USBPD_HW_Init_DMATxInstance.

As soon as our USB-PD stack needs to send data, it will call the function 'USBPD_HW_IF_SendBuffer'.

You could also check and try different applications available in this STM32CubeG0 package to test our complete solution:

  • List of different applications available in our Wiki page

Regards,

Yohann

RHelv.1
Associate II

Thanks @Yohann M.​ ,

This did answer my question regarding TX DMA transfer for UCPD. Is writing to register UCPD_TX_ORDSETR required for every UCPD transfer of data? Or is this something hardware does for us (similar to the CRC and EOP)?

Thanks,

Rob

Dear @RHelv.1​ 

UCPD_TX_ORDSETR is to set the Ordered sets type managed by the HW like EOP/CRC (K-code sequence before the data) and you should indicate in the UCPD_TX_PAYSZ, the size of the packet.

Simple scenario to send a SOP data (defined in  'USBPD_HW_IF_SendBuffer'):

     LL_UCPD_WriteTxOrderSet(UCPD1, LL_UCPD_ORDERED_SET_SOP);
     LL_UCPD_SetTxMode(UCPD1, LL_UCPD_TXMODE_NORMAL);
 
      WRITE_REG(Ports[PortNum].hdmatx->CMAR, (uint32_t)pBuffer);
      WRITE_REG(Ports[PortNum].hdmatx->CNDTR, Size);
      Ports[PortNum].hdmatx->CCR |= DMA_CCR_EN;
 
      LL_UCPD_WriteTxPaySize(UCPD1, Size);
      LL_UCPD_SendMessage(UCPD1);

You should find answers to your questions into our device driver.

Regards

Yohann