2016-05-02 07:41 AM
Hi,
I have a conceptual question about DMA data transfer and timers. I'm using an STM32f103RBT6 and would like to output a square wave signal that is non repeating. What I would like to do is to create a buffer of capture compare values, the first of which would placed into the relevant CCR and the timer enabled. Once the CCR value is reached the timer would enable a digital output and place the next value into the CCR and the timer would be enabled again. Once reached, the digital output would be disabled, a new CCR value placed into the register etc... Is it worth using the DMA for this or just would it not be worth it? Also is it possible to use the DMA in this way? The timing in question would ideally be a minimum of ~0.2us, which I'm not sure would be possible. Any info would be greatly appreciated, Thanks2016-05-02 09:52 AM
You can't enable/disable the timer. DMA will allow you to do one thing effectively, you can modulate the ARR or CCRx, and create a pattern buffer to do that.
200ns is likely doable, but you want a reasonable deep buffer, so you're interrupting below a few hundred KHz.DMA+TIM can also drive a pattern buffer to GPIO pins (BSRR, or ODR)2016-05-02 11:49 PM
Thanks for that, if I have understood correctly, then it was very insightful.
Correct me if I have misunderstood.
- Calculate my timing values and place them into a relatively large array (TIM_buffer), the length of which should be set in DMA_BufferSize.
- Configure a timer to generate an interrupt in output compare active mode once CCR value is reached. (Using TIM_OCMode_Active) - Set required GPIO ODR inside timer OC interrupt. - Configure TIM_DMAUpdate on the timer to trigger a DMA transfer on update event, i.e. when OC value is reached. - Configure DMA channel to transfer data from timing buffer (TIM_buffer) to timer CCR, with DMA_MemoryInc enabled in order to increment to next buffer index one transfer is completed. (This is a memory to peripheral transfer so DMA_M2M should be disabled??) - While the DMA is working its way through the TIM_buffer, I can be calculating my next set of timing data in the main loop ready to transfer. - In order to make this as seamless as possible, could I use the DMA half transfer interrupt to work out which half of the TIM_buffer has been used and then replace it with new data while the DMA continues with the rest of the buffer?Have I understood correctly?
Thanks for the help.
You can't enable/disable the timer. DMA will allow you to do one thing effectively, you can modulate the ARR or CCRx, and create a pattern buffer to do that.
200ns is likely doable, but you want a reasonable deep buffer, so you're interrupting below a few hundred KHz. DMA+TIM can also drive a pattern buffer to GPIO pins (BSRR, or ODR)2016-05-03 12:29 AM
2016-05-03 01:13 AM
No, the period is not constant.
Try again.
- Calculate my timing values (on timing and off timing) and place them into a relatively large (TIM_buffer), in a alternating fashion, e.g. TIM_ON, TIM_OFF, TIM_ON, TIM_OFF etc... The length of which should be set in DMA_BufferSize.
- Configure DMA channel transfer data from TIM_buffer to timer CCRx and ARRx, with DMA_MemoryInc and DM_PeripheralInc enabled in order to increment to next buffer index one transfer is completed and flick between transfering to CCRx and ARR registers. (This is a memory to peripheral transfer so DMA_M2M should be disabled??) - Configure the timer to enable GPIO pin when CCRx value is reached, and disable pin and reset timer when ARR value is reached. This can be done using TIM_OCMode_PWM1. This should remove the requirement for and ISR on overflow or update. - Enable TIMx_DIER->CCxDE and TIMx_DIER->UDE to trigger DMA transfer on update AND overflow. (Not sure if this is possible) - While the DMA is working its way through the TIM_buffer, I can be calculating my next set of timing data in the main loop ready to transfer. - In order to make this as seamless as possible, could I use the DMA half transfer interrupt to work out which half of the TIM_buffer has been used and then replace it with new data while the DMA continues with the rest of the buffer?Thanks again