2017-08-11 06:07 AM
Hello Community,
I have configured a STM32F429ZIT to communicate through SPI (SPI6) as slave and using DMA, see attached file.
The transmission works very well during 1 - 5 min but suddenly some transmission errors ocurs and HAL_SPI_ErrorCallback is called.
/***********************************************************************/
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{ if(hspi -> Instance == SPI6) { HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET); memcpy((uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_TX_working_buffer, 8); HAL_SPI_TransmitReceive_DMA(&hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data, 8); //--- initiate HMI communication } }/********************************************************************/
Then the communications is still there but the string 'HMI_slave_TX_data' sent by the STM32 is shifted or delayed 8bits, I have seen this on the oscilloscope. But the content of this string is correct, i can see the transmission delayed on the oscilloscope and HMI_slave_TX_data values using debut (and also using STMStudio) and their values are OK!!!!
So, at the beginning the transmission is perfect but suddenly the GPIOG PIN 1 is set and the transimion is shifted...
So i don’t understand what is happening with DMA, memory address or something related to the transmission...
Some similar it happens using DMA in circular mode instead normal mode...
Could anyone help me on this issue???
Thanks in advance and best regards.
AlejandroSolved! Go to Solution.
2017-11-17 01:33 AM
Hello,
I finally got the solution, I found what the problem was!
Usually, the CS signal goes from 1 to 0, then MISO and MOSI communicates, and once the communication finishes CS signal goes from 0 to 1, and the STM32F429 continues with the rest of the tasks...
This was happening every 150 ms, that's the period of thime both uC are communicating. But the STM32 uC has another tasks with more priority than SPI communication.
When one of this higher priority starts during SPI communication, and once this higher priority is done then the uC continues with the task was doing ( it was SPI),
obviously
this frame is lost and 'HAL_SPI_ErrorCallback' is executed, and then SPI is restarted.If SPI is restarted when CS signal is 1, (spi idle), then there is no problem, SPI is restarted properly and the next frame will be received without problem. BUT if SPI is restarted when CS signal is 0 (STM32 SPI is selected and ready to communicate) then the STM32 is waiting to send and receive an amount of bytes but it will receives less, so an a mismatch of communication bytes is the key of the PROBLEM.I have solved this issue just adding:
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{ if(hspi -> Instance == SPI6) {while(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_8) != GPIO_PIN_SET) // CS signal
{ }HAL_SPI_TransmitReceive_DMA(&hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data,10);
}}I have to modify 'WHILE' in order to not stop the processor , but it is the first approximation.
Now the communication is working all the time, but some times a frame is lost (and ' HAL_SPI_ErrorCallback' is called) due to higher priority task. But it is normal, a CRC is implemented to note that.
Thansk JW to help me and support.
I hope this helps to other people.
Best regards.
Alejandro.
2017-08-11 09:26 AM
but the string 'HMI_slave_TX_data' sent by the STM32 is shifted or delayed 8bits
Shifted or delayed compared to what? Can you post pictures of good and bad waveform?
You should also investigate what caused the error (read SPI flags).
JW
2017-08-14 06:28 AM
I can't tell for sure as the code you provided isn't complete but I suspect at least some of your problems may be due to the DMA-accessed buffers not being aligned to a cache-line boundary, sized to an integral number of cache lines, and actively flushed/invalidated.
2017-08-14 08:35 AM
There's no data cache in STM32F429ZIT.
JW
2017-08-14 08:47 AM
Ah, thanks for the clarification. Sorry for the disruption.
2017-08-16 12:35 AM
First of all, thanks for all replies and sorry for not answering earlier... i had a bank holiday and i couldn't continue with this...
I add more information related to this issue i am still having...
Here you can see the 8 bytes sent from slave to master (green), the clock signal (yellow) consist in 8 groups of 8 bits, this is what i m sending with :
HAL_SPI_TransmitReceive_DMA(&hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data, 8);
uint8_t HMI_slave_TX_data[8]; this is buffer i use to send datas from slave to master.
As you can see in the image, according to green signal, the first 8 bits and the last 8 bits, the HMI_slave_TX_data[0] and HMI_slave_TX_data[7] values are 0x00.
This correct comunication is working each 100ms. Master send to slave the chip select signal, the clock signal and the MOSI signal each 100ms, and the slave send this MISO signal properly.
BUT after between 1min or 2 min randomly, the communication suddenly changed. The MISO signal is delayed as yo can see in the next capture:As you can see, the MISO signal should be exactly the same as prevous capture becasue HMI_slave_TX_data buffer is exactly the same all the time, but i dont understand why suddely the signal has being delayed to the next clock signal!! And as i mentioned, i checked the HMI_slave_TX_data buffer (using debug mode and also STM32 ST-LINK Utility in run mode) and the buffer was OK (only HMI_slave_TX_data[0] and HMI_slave_TX_data[7] values are 0x00), so in both captures the buffer is the same (it contains the same 8 values), but in the second capture is delayed or moved to left one byte!!
This wrong communication keeps all the time unless i reset the uC.
I am not 100% sure, but I thing it is related to the next function:
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{ if(hspi -> Instance == SPI6) { HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET); memcpy((uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_TX_working_buffer, 8); HAL_SPI_TransmitReceive_DMA(&hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data, 8); //--- initiate HMI communication }}Becasue as soon as the comunication change from correct one to wrong mode, the GPIO F pin 1 is set. So i guess that it is due to this function or also due to a communication error this funtion is called... (this GPIO F pin 1 is set only in this part of the code).
I am not an expert on uC, and maybe i am doing something wrong, but from my pont of view, i think that the error is related to DMA synchronization...
Thanks in advance and best regards.
PD. sorry for a long email!
2017-08-16 12:51 AM
Apparently you don't have any explicit synchronisation mechanism between master and slave, relying on the fact that all 'packets' are 8 bytes long. But if the slave for some reasone misses a 'packet' it starts to transmit exactly like you've shown.
Best thing is eliminating the root cause.
Find out the reason why HAL_SPI_ErrorCallback() is called at all. I don't use Cube so I don't know what exactly this is, but if it's triggered by some of SPI states, read out the SPI status register at that moment. If you use a debugger, can do it by placing a breakpoint in that function and then observing the SPI registers (and, if needed, the DMA status registers too) in the debugger.
You may also want to see what has happened on the scope - if your scope has an 'external trigger' input, connect it to PF1 and set it to trigger on the edge on this input.
JW
2017-08-16 02:37 AM
Thanks for reply! any comment it is appreciate! I have added pictures and more explanation about the error!
It maybe can help
2017-08-16 02:40 AM
Thanks for comments! all replies are appreciated.
2017-08-16 03:46 AM
If the master continues to transmit, and the DMA is not circular, when you stop the slave's program execution in debugger (either manually or because the breakpoint is reached), the SPI continues to receive and eventually overflows.
JW