2019-08-23 06:13 AM
Hello!
I use SPI DMA (NSS always down) communication between 2pcs H743ZI.
Everything work fine, till I don't change SPI speed to higher frequency (6MBits/s)
It seems like, the DMA interrupts don't let enough time for While() to run.
EXAMPLE:
...
uint8_t pnSPI2Values_rx[8] = {100, 0, 0, 0, 0, 0, 0, 0};
uint8_t pnSPI2Values_tx[8] = {100, 1, 2, 3, 4, 5, 6, 7};
int main(void)
{
...
if(HAL_SPI_TransmitReceive_DMA(&hspi2, (uint8_t*)pnSPI2Values_tx, (uint8_t
*)pnSPI2Values_rx, 8) != HAL_OK)
{
Error_Handler();
}
...
while (1)
{
function();
}
}
With prescaler 256 = 1.562 Mbits/s I can do my While() funcion too.
The function() do a lot of things, and also handle SPI RX values and change the TX array values.
For example from:
- function() STEP1 to STEP10 the time is 7.8ms - prescaler 256 = 1.562 Mbits/s
- function() STEP1 to STEP10 the time is 12.5ms - prescaler 128 = 3.125 Mbits/s
- function() STEP1 to STEP10 the time is NEVER - prescaler 64 = 6.25 Mbits/s
The communication is still stable with good values, only I can't change any TX values under runtime, because it happens in While() and I think its by the DMA interrupts.
In the end I want to run SPI with 50MBits/s and the whole program with 400MHz core clock.
I use STM32CubeIDE
Here are some pictrues:
The main thing is that I do some measurement with ADC DMA on processor 1 (slave), and sending it with SPI DMA to processor 2 (master), then it changing PWM duty cycle. And this change happening in While() loop.
-What is the best solution?
-Does it help if I disable the half interrupt in SPI? (I don't know how to do it, but its possible)
-Disable both interrupts? Does it will occur sync problem with the data flow?
-Using SPI with timer?
Thanks for any help!
Szilveszter
2019-08-23 08:12 AM
The HAL abstraction is pretty heavy, but would have thought it would still function.
Not sure how the DMA vs while() loop interacts for a single firing.
Toggle a GPIO in the IRQHandler and see if it is saturating there. Perhaps signal on entry/exit so you can see if you're eating too much time in those routines.
Watch for things in your call-back functions which take excessive time, or BLOCK.
For high rates you might want to hand-craft the code with an eye to cycles, interactions, and DMA HT/TC appropriateness.
2019-08-23 09:49 AM
no NSS means no synchronisation in case of bus glitches occuring.
I would build ADC in a cyclic DMA buffer and use the half/full transfer interrupt to use another DMA channel to push a block of data by SPI.
The SPI throughput (MHz) must be fast enough to flush faster than the ADC fills half buffer.
Toggle NSS to tell this is a new block of data.
SPI Slave should run a cirular mode with same buffer and get interrupt in half/full transfer received, or use EXTI on NSS rise edge to save the incoming block.
2019-08-28 05:31 AM
Thanks! I would try these.