cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L011E4 Using DMA/DMA Burst for one pulse output

MKatz
Associate II

I have the need to send a serial data stream where each cycle may or may not have a different duty cycle. My frequency is 10 KHz.

The data stream to send a 0x5A with parity would look like this (1 cycle at each duty cycle)

Start Bit 90% Duty Cycle

Bit 7 (0) 60% Duty Cycle

Bit 6 (1) 30% Duty Cycle

Bit 5 (0) 60% Duty Cycle

Bit 4 (1) 30% Duty Cycle

Bit 3 (1) 30% Duty Cycle

Bit 2 (0) 30% Duty Cycle

Bit 1 (1) 30% Duty Cycle

Bit 0 (0) 60% Duty Cycle

Parity (0) 60% Duty Cycle

Since the STM32L0X1 does not have a repeat count register on the timer and i need only one cycle at each duty cycle my thought is to use one pulse mode and balance the pre delay for the next pulse and pulse width for the current pulse to accomplish my duty cycle changing.

How can I use DMA/DMA Burst to update the timer automatically so I don't have to tie up the CPU bit banging the waveform?

Thank you..

9 REPLIES 9

You could probably just drive the TIM->CCRx register from a 10 or 20 word pattern buffer, and have the idle state just set 0 or 100% for a LOW or HIGH state.

With the double size buffer you could use the DMA HT and TC interrupts to update the inactive half of the pattern buffer.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Is this for some of those one-wire-serially-controlled "intelligent" LEDs? There are certainly numerouse examples for that out in the wildernets...

JW

MKatz
Associate II

No, this is not for one wire LEDs. This is for proprietary in band wireless communication.

But the principle is the same, so you can go for them at least for inspiration.

Anyway, it's exactly how Clive said above: run the timer continuously with the bit duration and change only CCRx, best by a DMA (like in the basic TIM-with-DMA example in Cube), with the last value of the pattern driving the output to the idle level.

JW

MKatz
Associate II

It is my understanding that the one pulse mode needs to be started by a trigger (input or another timer). How do I do this and synchronize this with the DMA. There isn't a HAL_TIM_OnePulse_Start_DMA() function.

Thanks for your help.

Diagram the desired signal form, expand the buffer if multiple 10 KHz cycles used for each bit, or inter-symbol gap(s). PM if sensitive to public disclosure.

Or perhaps drive a pattern to a GPIO at 100 KHz, although that have more phase noise / jitter.

TIM gets complicated if phase and frequency modified, simpler if only one changes, and you've specified 10 KHz, so the assumption is you're just modulating the falling-edge of the wave form.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
MKatz
Associate II

Basically, this is just a simple Pulse Width Encoded Data stream, using a 10 bit word (Start bit, 8 bits of data & parity). One cycle per bit.

I could just bit bang it with very tight loops but that would require a blocking function during data transmission.

http://www.efton.sk/STM32/dma_pwm_l0.zip

Period set to 1s so that it can be seen by bare eye, on RED led. GREEN LED indicates "transmission active" from the point of view of main program (note that it lights on before the first bit and goes off before the last, as the real transmission lags due to being handled by the DMA and timer. First byte is 0x5A, second is 0x7F. Sorry for the poor quality of the video.

JW

MKatz
Associate II

Jan,

Thank you. I am checking this out now. I owe you a beer (or a caipirinha if you prefer).

Mike