SPI Master and Slave using DMA

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

cross mob
User11041
Level 1
Level 1
Hi all,

I have a question how to set up a SPI communication between 2 microcontrollers. On a PCB I have one XMC4500 and one XMC4400 connected by a SPI bus. The task is to transmit data of a certain data structure from the 4500 to the 4400 and, at the same time, other data of the same data structure back. The data structure is called IO_DATA_t. The data are located at defined addresses inside the two controllers, and for not loading the CPU too much, I thought that DMA would be a good way to transmit and receive the data. On the 4500, I added a SPI_MASTER app, configuring it in DMA transmit/receive mode, full duplex, 10kHz bus speed, and left all other settings to default. I did not forget to specify the actual pins mapped to this app. On the 4400, I configured a SPI_SLAVE app in DMA receive/transmit mode, full duplex, a slave select input event callback named "spi_request_handler" and all other settings as default.

When I try to initiate a communication, I want the master to transmit a struct of type IO_DATA_t to the slave (it is called IO_OUTPUT_DATA) and receive simultaneously data into the IO_INPUT_DATA struct (of the same data type) - therefore I call in a systimer handler every one second:

SPI_MASTER_Transfer(&SPI_MASTER_0, (uint8_t*)(&IO_OUTPUT_DATA), (uint8_t*)(&IO_INPUT_DATA), sizeof(IO_DATA_t));

On the 4400, I would now expect the slave select input event callback to execute and I want the 4400 to receive the data from the 4500 and to transmit some other data:

void spi_request_handler(void)
{
SPI_SLAVE_Transfer(&SPI_SLAVE_0, (uint8_t*)(&IO_OUTPUT_DATA), (uint8_t*)(&IO_INPUT_DATA), sizeof(IO_DATA_t));
}

All of this does not seem to work. My oscilloscope tells me that the SCK line is working as expected (every one second it pulses at 10kHz for a short time), the slave select line does not seem to do anything (it is continuously low), the MOSI line is continuously low and the MISO line is continuously high. Therefore I'm not surprised that the callback on the 4400 does not execute, but why is the slave select line continuously low?

Then I started debugging the software, and surprisingly on the 4500, the transfer routine always exits with SUCCESS code. Even more surprisingly, the very first transfer after initialization is successful, I receive sensible data from the 4400 - after that, I always receive only ones (as the MISO line is continuously high). So the first transmission actually works! On the 4400, I enter the callback routine once when I press the reset button for the 4500 (the first transmission), but it is not good to debug if the 4500 keeps sending data and I'm halting the 4400 with my debugger. After this, the callback routine is never again entered.

Which routines do I have to call on both microcontrollers to get it right? Do I have to use another routine? Or reset some flag or some status for the next transmission? I have the feeling that I'm doing quite a bit wrong, so maybe you can help me.

Thank you very much and kind regards
Niklas
0 Likes
2 Replies
User11041
Level 1
Level 1
Can anyone help?
0 Likes
User10969
Level 1
Level 1
Hi Niklas,

...not sure if you have already got it in the meantime. Otherwise please take a look here:

https://www.infineonforums.com/threads/3315-GPDMA-with-USIC-(SPI)-Data-transfer-Master-to-Slave
0 Likes