DMA to SPI peripheral dropping second byte

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

cross mob
jamesk
Level 3
Level 3
First solution authored 5 replies posted 5 sign-ins

I am calling SPI_MASTER_StartTransmitDMA() to transfer from memory to peripheral device.

Host is XMC4700 and Peripheral is a radio device.

I can sniff the packets out of the radio and see that the 2nd byte is always missing and a garbage byte is inserted at the end.

If I call SPI_MASTER_Transmit() to do a direct transfer all the bytes are transmitted correctly.

The DAVe generated code shows the following.

XMC_DMA_CH_CONFIG_t SPI_MASTER_RADIO_dma_ch_tx_config =
{
.src_transfer_width = (uint32_t)XMC_DMA_CH_TRANSFER_WIDTH_8,
.dst_transfer_width = (uint32_t)XMC_DMA_CH_TRANSFER_WIDTH_8,
.src_address_count_mode = (uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT,
.dst_address_count_mode = (uint32_t)XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE,
.src_burst_length = (uint32_t)XMC_DMA_CH_BURST_LENGTH_8,
.dst_burst_length = (uint32_t)XMC_DMA_CH_BURST_LENGTH_1,
.transfer_flow = (uint32_t)XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA,
.transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK,
.dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_HARDWARE,
.dst_peripheral_request = DMA_PERIPHERAL_REQUEST(2, 12),
.enable_interrupt = true
};

And in SPI_MASTER_RADIO_lInit()

XMC_USIC_CH_SetInterruptNodePointer(XMC_SPI1_CH1,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER,
(uint32_t)SPI_MASTER_SR_ID_1);

XMC_USIC_CH_TriggerServiceRequest(XMC_SPI1_CH1, (uint32_t)SPI_MASTER_SR_ID_1);

Any ideas of what could be happening here that can cause the second byte to be dropped?

0 Likes
1 Solution
jamesk
Level 3
Level 3
First solution authored 5 replies posted 5 sign-ins

Looks like I figured it out through some additional reading on the Service Requests and USIC TX/RX Interrupts.

The SPI_MASTER_StartTransmitDMA on its own wasn't starting the DMA transfer correctly.

The SR is configured to use XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER and XMC_SPI_CH_EVENT_RECEIVE_START to trigger the start of the DMA but it doesn't work for SPI.  The AP32303 suggest that only works for UART and I2C.

I changed it to XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_SHIFT and XMC_SPI_CH_EVENT_TRANSMIT_SHIFT and manually wrote the command's last byte before the DMA manually to TBUF.   When the DSU has shifted out the TBUF, TSIF is raised and TCSR.TDV is cleared on the SPI. Then TBUF is ready for next DMA byte.

I also called added

XMC_DMA_CH_ClearDestinationPeripheralRequest(SPI_MASTER_RADIO.global_dma->dma, SPI_MASTER_RADIO.dma_ch_tx_number);

to make sure the DMA wasn't started prematurely.

View solution in original post

0 Likes
6 Replies
lock attach
Attachments are accessible only for community members.
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @jamesk ,

    You can refer to the example below and check your codes. Base the situation you mentioned above, here I think of two possible reasons:

    1) If you use the codes without DAVE APP, maybe you only modified the transmit mode, but not the receive mode;

    2) If you use the codes with DAVE APP, you can modify the mode directly through APP without changing the codes, maybe you still select 'INTERRUPT' mode.

Owen_Su_0-1663556307026.png

    Please let us know if you have any other questions, hope this can help you.

Regards,

Owen_Su

0 Likes
jamesk
Level 3
Level 3
First solution authored 5 replies posted 5 sign-ins

For TransmitDMA I'm not interested in the MISO data.  Receive is configured for direct only.

 

I think the peripheral address is correct or I wouldn't get any valid data.

 

I will examine the examples provided and compare it to what I have.

 

I am also not using the fifo as the radio has its own.

0 Likes
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @jamesk ,

    Here I found another example in ModusbusTool: xmc-spi-dma .

    1) According to the codes, maybe your destination peripheral request address  ".dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_0," does not match;

    2) And the initialization of SPI_MASTER  refer to the example below.

Owen_Su_0-1663575775603.png

Regards,

Owen_Su

 

0 Likes
jamesk
Level 3
Level 3
First solution authored 5 replies posted 5 sign-ins

I've examined the examples but much of it doesn't apply.  I'm not using the FIFO so none of that setup is required and I'm not interested doing DMA reception so those events aren't setup.  The radio has a limited packet buffer so FIFO adds nothing, and reception size is variable so DMA RX isn't useful.

From what I understand the DMA writes to the TBUF[0] and that is then clocked into the SPI peripheral.  Is there some other interaction with the TBUF I'm missing?

The typical radio packet transfer is a direct write of 2 bytes (command+ length) followed by DMA write of the packet bytes.

0 Likes
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @jamesk ,

    This is the transmission process related to TBUF:

Owen_Su_0-1663752424502.png

 

0 Likes
jamesk
Level 3
Level 3
First solution authored 5 replies posted 5 sign-ins

Looks like I figured it out through some additional reading on the Service Requests and USIC TX/RX Interrupts.

The SPI_MASTER_StartTransmitDMA on its own wasn't starting the DMA transfer correctly.

The SR is configured to use XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER and XMC_SPI_CH_EVENT_RECEIVE_START to trigger the start of the DMA but it doesn't work for SPI.  The AP32303 suggest that only works for UART and I2C.

I changed it to XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_SHIFT and XMC_SPI_CH_EVENT_TRANSMIT_SHIFT and manually wrote the command's last byte before the DMA manually to TBUF.   When the DSU has shifted out the TBUF, TSIF is raised and TCSR.TDV is cleared on the SPI. Then TBUF is ready for next DMA byte.

I also called added

XMC_DMA_CH_ClearDestinationPeripheralRequest(SPI_MASTER_RADIO.global_dma->dma, SPI_MASTER_RADIO.dma_ch_tx_number);

to make sure the DMA wasn't started prematurely.

0 Likes