aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authoreZio Pan <[email protected]>2023-12-22 01:24:31 +0800
committereZio Pan <[email protected]>2023-12-22 01:24:31 +0800
commit53fc344e4d46388cc742c139a263c1cdf0c16589 (patch)
treed4797fa86832c261dfe50a3257d54aab02fe7bfc /examples
parentd7e517e2d32c590e62e3e3339e191d19ce764c12 (diff)
fix timing, turn TIM UDE on only necessary, clean DMA FEIF after each Transfer
Diffstat (limited to 'examples')
-rw-r--r--examples/stm32f4/src/bin/ws2812_pwm_dma.rs16
1 files changed, 12 insertions, 4 deletions
diff --git a/examples/stm32f4/src/bin/ws2812_pwm_dma.rs b/examples/stm32f4/src/bin/ws2812_pwm_dma.rs
index dc397eff1..c4181d024 100644
--- a/examples/stm32f4/src/bin/ws2812_pwm_dma.rs
+++ b/examples/stm32f4/src/bin/ws2812_pwm_dma.rs
@@ -64,9 +64,6 @@ async fn main(_spawner: Spawner) {
64 CountingMode::EdgeAlignedUp, 64 CountingMode::EdgeAlignedUp,
65 ); 65 );
66 66
67 // PAC level hacking, enable timer-update-event trigger DMA
68 pac::TIM3.dier().modify(|v| v.set_ude(true));
69
70 // construct ws2812 non-return-to-zero (NRZ) code bit by bit 67 // construct ws2812 non-return-to-zero (NRZ) code bit by bit
71 // ws2812 only need 24 bits for each LED, but we add one bit more to keep PWM output low 68 // ws2812 only need 24 bits for each LED, but we add one bit more to keep PWM output low
72 69
@@ -104,13 +101,16 @@ async fn main(_spawner: Spawner) {
104 dma_transfer_option.mburst = Burst::Incr8; 101 dma_transfer_option.mburst = Burst::Incr8;
105 102
106 // flip color at 2 Hz 103 // flip color at 2 Hz
107 let mut ticker = Ticker::every(Duration::from_micros(500)); 104 let mut ticker = Ticker::every(Duration::from_millis(500));
108 105
109 loop { 106 loop {
110 for &color in color_list { 107 for &color in color_list {
111 // start PWM output 108 // start PWM output
112 ws2812_pwm.enable(pwm_channel); 109 ws2812_pwm.enable(pwm_channel);
113 110
111 // PAC level hacking, enable timer-update-event trigger DMA
112 pac::TIM3.dier().modify(|v| v.set_ude(true));
113
114 unsafe { 114 unsafe {
115 Transfer::new_write( 115 Transfer::new_write(
116 // with &mut, we can easily reuse same DMA channel multiple times 116 // with &mut, we can easily reuse same DMA channel multiple times
@@ -121,6 +121,14 @@ async fn main(_spawner: Spawner) {
121 dma_transfer_option, 121 dma_transfer_option,
122 ) 122 )
123 .await; 123 .await;
124
125 // Turn off timer-update-event trigger DMA as soon as possible.
126 // Then clean the FIFO Error Flag if set.
127 pac::TIM3.dier().modify(|v| v.set_ude(false));
128 if pac::DMA1.isr(0).read().feif(2) {
129 pac::DMA1.ifcr(0).write(|v| v.set_feif(2, true));
130 }
131
124 // ws2812 need at least 50 us low level input to confirm the input data and change it's state 132 // ws2812 need at least 50 us low level input to confirm the input data and change it's state
125 Timer::after_micros(50).await; 133 Timer::after_micros(50).await;
126 } 134 }