2024-02-12 07:55 AM
Hi!
I'm using STM32H745 dual core. The reason behind it is as I have to do very fast measurement on one core (M7) and the rest of the slower things on the M4. The M4 is mostly used for communicating with the external world.
I have setup SPI3 and SPI4. SPI3 is on the M7 and the SPI4 is on the M4.
SPI3 is the slave. SPI4 is the master.
I have used this example to get the cores to communicate, which works!
What I'm trying to achieve is for the M4 (master) to use the transmitreceive function (it can be in any mode - polling, it or dma) to send config data and receive measurement data from the M7. For now I can use the given example.
What I'm trying to do is to move the SPI receiving, packing the data and sending it back to the master in an interrupt routine on the M7. Is that possible to do? Or is it done by setting a flag and computing it in the main while loop?
Thanks!
Solved! Go to Solution.
2024-02-13 01:13 AM
https://github.com/MaJerle/stm32h7-dual-core-inter-cpu-async-communication/tree/main
This works very well! Closing!
2024-02-12 08:04 AM
Hello,
Note: it's not recommended to handle a huge calculation in an interrupt routine. Better to handle that in the main loop.
2024-02-12 08:06 AM
To clarify. I'm doing sampling and calculations in the main loop.
In the interrupt routine I would just pack the already calculated data into a buffer that I would send out to the SPI master. Masking bits and simple operations like that. Basically I just want to send data out when I get a message from the master.
2024-02-12 08:13 AM - edited 2024-02-12 08:13 AM
You need to stay at the interrupt handler less time as possible. This is the recommendation.
Pack/Unpack data could be influenced by the length of the data. More you have data to tranceive more you're blocking the interrupt.
2024-02-12 08:16 AM
Okay, then what is the recommended setup for this?
If I do DMA and in the RX callback I set a flag, which will be read by the while loop, process the data and send back spi data? Is that the way this is done or?
2024-02-12 08:26 AM
In my opinion yes .. and manage this in a ring in order to keep a correct synchronization and coherent tranceived data ..
2024-02-12 08:27 AM
Is this example as a good follow up?
I guess the changes I have to make is to the slave, where it will do the above with the rx callback and flag setting.
2024-02-12 09:06 AM
HAL_SPI_Receive_DMA(&hspi3, aRxBuffer, BUFFERSIZE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
if(flagz == 1) {
HAL_Delay(10); // simulating some processing
flagz = 0;
HAL_SPI_Transmit_DMA(&hspi3, aTxBuffer, BUFFERSIZE);
}
}
The flag is being set by the Receive DMA
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)
{
// RX Done .. Do Something ...
if(hspi->Instance == SPI3) {
flagz = 1;
}
}
But the DMA transmit is not sending anything...
2024-02-12 09:19 AM
I figured out that if I put a
while(hspi3.State != HAL_SPI_STATE_READY) {}
before the DMA transmission, it stays there and it blocks it. Why can this happen?
const uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on IT **** SPI Message ********* SPI Message *********";
#define BUFFER_ALIGNED_SIZE (((BUFFERSIZE+31)/32)*32)
//ALIGN_32BYTES(uint8_t aRxBuffer[BUFFER_ALIGNED_SIZE]);
uint8_t aRxBuffer[BUFFERSIZE];
I'm doing receive like this
HAL_SPI_Receive_DMA(&hspi3, aRxBuffer, BUFFERSIZE);
2024-02-12 01:01 PM
Let's change the approach:
If you want to share data between two cores, dedicate a section of AXI SRAM as shared memory and have one core write it and the other read. This will be hundreds of times faster than sending/receiving over SPI and will be easier to code.