cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronize DMA to GPIO transfer on 2 distant MCU by external signal.

Dyst
Associate

Hello, community. I have a task to transfer a value from the buffer of 64 values in memory to 7 GPIO by DMA every 1us. I solved it by setting a TIM2 timer Channel1 to Output Compare mode and TRGO to Update event. Then, I mapped the DMA request to TIM2_UP and set the mode to Circular so that I could use HAL_DMA_CallbackIDTypeDef to copy new data to half of the buffer while transferring another half. 

The challenge is that I must perform this on two separate STM32H7 MCUs with precise timing. To achieve this, I have a VSYNC signal that's essentially a basic PWM with a 64us period and a 5us pulse width.

So, for every rising edge of VSYNC, I need to start transferring the data buffer of 64 values. One value for 1us. And start transferring another 64 values right at the start of the next sync pulse.

I was trying to Enable Synchronization in DMA Request Synchronisation settings and set the Sync signal to EXTI (which is my PWM VSYNC) but it doesn't work as I expected. 

Is there any other approach I can take to synchronize the DMA transfers?

2 REPLIES 2
MasterT
Lead

What jitter is acceptable?

I don't thing tim->dma may ever be more accurate than 40 nsec, likely worse. For good timing couple of 595 shift registers is the solution

> setting a TIM2 timer Channel1 to Output Compare mode

What's the purpose of doing that?

---

I would sync the timer.

I would connect the incoming pulse to TIM2_CH2 (if CH1 is not available) or TIM2_ETR pin, set TIM2_SMCR.TS to TI2FP2 or ETRF respectively, and set the slave-mode controller to combined Reset+Trigger (TIM2_SMCR.SMS=0b1000, note that SMS is not a continguous bitfield).

Then, I would set up DMA triggered by TIM2's Update (with the 1us period) to transfer 64 values in Normal (non-circular) way.

I would set up a DMA Transfer Complete interrupt, in which I would stop TIM2 (TIM2_CR1.CEN=0) so that the Reset+Trigger setting would have chance to act properly, and I would swap DMA's memory-side address to a new buffer with data for the next period prepared in previous step, and would enable DMA. At this point, there must be less than 1us elapsed from the DMA Transfer Complete event, and even with 'H7's brutal computing power you are quite likely not to be able to pull this out using Cube/HAL due to its extensive interrupt processing (and of course this interrupt must have set the highest priority, too). After that, still in the interrupt but not that timing critical, the new 64-value buffer would be prepared, to be swapped to in the next TC interrupt.

Using TIM1/TIM8 auto-disabling after the 64 transfers through TIMx_RCR might allow to avoid the time-critical interrupt.

JW