Triggering DMA transfer using a Timer capture/compare

Post here all questions related to LibMaple core if you can't find a relevant section!
Post Reply
profdc9
Posts: 5
Joined: Sun Mar 08, 2020 11:21 pm

Triggering DMA transfer using a Timer capture/compare

Post by profdc9 »

Hello,

I am working on a TV output library for stm32duino (STM32F103CBT6 bluepill) 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

https://github.com/Tamakichi/ArduinoSTM32_TVout

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. and PS/2 keyboard input. 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 bit band 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 (fraction of a DMA pixel cycle) 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?

Do I need to set up a second timer that would be slaved to TIMER2 to clock every single sample to the SPI1 like would be necessary for the ADC? This is the closest example I can think of from typical use cases.

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!

Dan
User avatar
fpiSTM
Posts: 1754
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Triggering DMA transfer using a Timer capture/compare

Post by fpiSTM »

I move it to LibMaple core as I guess you use Roger's one.
I don't know how DMA is handle in this core so hard to help.
Ensure all address are corrects as they are defined manually in this core.
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: Triggering DMA transfer using a Timer capture/compare

Post by stevestrong »

I would suggest to start with a simple example to output some values from a buffer to GPIO using DMA triggered by a timer.
If it works, then go to a next step.
If not, you can eventually post it here so that we can help.
Post Reply

Return to “General discussion”