# STM32f103 DMA with PWM repeating values

I have a Blue Pill (STM32F103) and connected to it a ws2812b led strip. I am trying to send data to the led strip via PWM over the TIM2 peripheral (Pin A0). To change the duty cycle of the TIM2 PWM I use a DMA channel. This works perfectly at lower speeds (eg 100khz) but as soon as I get near to the required 800khz of the leds the MCU seems to send some pulses twice, this would make sense if I overload the bus, but from what I have gotten out of the datasheet it should be able to handle 800 kbyte/s.

What makes the entire thing more complicated, is that I am trying to write this in Rust and there is no code I could compare mine too. I will try to post the relevant parts of the code and explain it as good as I can.

Main Code:

// setup pwm
let mut pwm = p.TIM2
.pwm(
c1,
&mut afio.mapr,
800.khz(),
clocks,
&mut rcc.apb1,
);

let max = pwm.get_max_duty();

let one_duty = (max * 16 / 25) as u8;

let buf = singleton!(: [u8; 25] = [one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, one_duty, 0]).unwrap();

// set duty to zero
pwm.set_duty(0);
// enable pwm output
pwm.enable();
// enable the dma and wait for it to finish
pwm.write_all(channels.5, buf).wait();


WriteAll function code:

pub fn write_all<A, B>(
self,
mut chan: $c1_chan, buffer: B, ) -> Transfer<R, B,$c1_chan, Self>
where
A: Unsize<[u8]>,
B: Static<A>,
{
{
unsafe { (*$TIMX::ptr()).dier.modify(|_, w| { w .tde().set_bit() .cc1de().set_bit() }); } let buffer: &[u8] = buffer.borrow(); chan.cmar().write(|w| unsafe { w.ma().bits(buffer.as_ptr() as usize as u32) }); chan.cndtr().write(|w| unsafe{ w.ndt().bits(u16(buffer.len()).unwrap()) }); chan.cpar().write(|w| unsafe { w.pa().bits(&(*$TIMX::ptr()).ccr1 as *const _ as usize as u32)
});

atomic::compiler_fence(Ordering::SeqCst);

chan.ccr().modify(|_, w| {
w.mem2mem().clear_bit()
// priority
.pl().high()
// size in memory
.msize().bit8()
.psize().bit32()
.minc().set_bit()
.pinc().clear_bit()
.circ().clear_bit()
.dir().set_bit()
.teie().set_bit()
.htie().set_bit()
.tcie().set_bit()
// enable
.en().set_bit()
});
}
}


My question is: why is DMA not fast enough even though it should be as stated by the documentation?

• Welcome to EE.SE! Please clarify the question that you are asking. – Daniel Nov 6 '18 at 17:10