STM32F103 stm32duino trigger start of DMA using timer capture compare - Page 1
Forum section: electronics / general

author: profdc9
author_rank: Frequent Contributor
timestamp: March 07, 2020, 03:24:13 am
content: 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 TNTSChttps://github.com/Tamakichi/ArduinoSTM32_TVoutwhich 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

author: iMo
author_rank: Super Contributor
timestamp: March 07, 2020, 10:51:55 am
content: FYI- some knowledgeable veterans sit herehttps://www.stm32duino.comhttps://mcu.selfip.com

author: ozcar
author_rank: Frequent Contributor
timestamp: March 07, 2020, 09:19:29 pm
content: I see that TNTSC allows you to use SPI2 instead of SPI1 (output then on PB15 instead of PA7), and SPI2 happens to use DMA1 channel 5. However, I don't see how that would help. Figure 50 in RM0008 shows the various peripheral DMA requests are just ORed together and they specifically warn against enabling more than one of them at the same time. Also, enabling the DMA request for a peripheral, say by setting CC1DE in the timer DIER, does not turn on EN in the DMA_CCR.Perhaps you could just get TIMER2 to trigger DMA1 channel 5, and use that to turn on the EN bit in the DMA_CCR for channel 3 (as I understand it, DMA can't use bit band though, so you'd have to preserve the other bits in the DMA_CCR).