Triggering DMA transfer using a Timer capture/compare

Post here first, or if you can't find a relevant section!
Post Reply
Posts: 14
Joined: Mon Mar 25, 2019 1:01 am
OS: Linux & Windows 10
IDE: Arduino
Core: Roger & Official
Board: Bluepill mostly

Triggering DMA transfer using a Timer capture/compare

Post by profdc9 » Fri Mar 06, 2020 7:09 pm


Thought I would pop my head in and ask a question. I am working on a TV output library for stm32duino for a project. The project is a monochrome character-based text output to a NTSC television (though it could probably be modified for PAL pretty easily). It is based on TNTSC

which I have working fine. In fact, I have the whole thing working mostly ok, with a 40X24 or 80X24 characters displayed on the television, and I even have it so that it interprets ANSI escape codes for character positioning, scrolling, etc. I will share the code on a github repository when I am ready.

The only annoyance is this. There is a slight shimmering on the text. The way the library works is by using TIMER2 in conjunction with SPI1. Since you're probably not familiar with the NTSC video format, I'll summarize. TIMER2 generates a PWM signal on PA1 that corresponds to the horizontal sync pulse (a negative going pulse). An capture-compare interrupt is generated for each sync pulse. Each pulse, picture pixels from the current scan line are streamed out of the MOSI pin of SPI1 on PA7. The data for the next scan line is generated during the TIMER2 CC interrupt. When the DMA completed interrupt is received, the DMA1 controller is set up to stream out the next scan line.

Now here lies the problem. The TIMER2 capture-compare interrupt routine first instruction is a bb_peripheral bit update to the DMA1/channel 3 controller to enable the DMA. The immediately starts the DMA from the scan line memory to the SPI1. The problem I think is that there is a little timing jitter between when the capture-compare event occurs (which is due to the edge of the sync pulse) and the interrupt call for which the scan line DMA transfer is initiated. This manifests itself as slight but mildly annoying jitter of the text.

So what I would like to do is have the timer capture compare directly trigger the start of the DMA. According to the STM32 RM0008 manual, TIMER2 CC1 is connected to channel 5 on DMA1 (page 282). So I assume I must use this channel instead of channel 3 which is for the SPI1 initiating transfer. Though honestly I am very confused about how this works. Secondly, the timer has a DIER (DMA/interrupt enable register) for which I can set the CC1DE bit (page 409) so that when the capture compare event happens the DMA1 enable is triggered. I may also need so the the Master/Slave mode (MSM) bit in the SMCR register (page 408) and the the MMS bits to 100 (OC1REF) in the CR2 register (page 406). I am probably missing something here.

But if I change the channel to 5 from 3, the DMA no longer initiates and the sync pulses still arrive but the screen is blank. Perhaps there's something I don't understand about what the channel means? Is the channel used to select the device that the data is transferred from, or is it used to select the device that triggers the transfer, or both? Or does the CPAR (channel x peripheral address, page 288) register in the DMA channel select the peripheral?

I know this question goes down the rabbit hole a bit but if someone has experience with triggering DMA with timers, that would be helpful. Thanks!


User avatar
Posts: 182
Joined: Wed Feb 27, 2019 5:09 pm
Answers: 2
Location: Thessaloniki, Greece
OS: Linux, Win10, MacOS
IDE: Arduino 1.8.9
Core: Roger, STM official
Board: Bluepill, Maple mini, STM32F4xx

Re: Triggering DMA transfer using a Timer capture/compare

Post by Vassilis » Sun Mar 08, 2020 10:35 am

Hi Dan
Maybe you should consider posting your question on the forum
-Vassilis Serasidis

Post Reply