diff options
| author | eZio Pan <[email protected]> | 2023-12-22 01:24:31 +0800 |
|---|---|---|
| committer | eZio Pan <[email protected]> | 2023-12-22 01:24:31 +0800 |
| commit | 53fc344e4d46388cc742c139a263c1cdf0c16589 (patch) | |
| tree | d4797fa86832c261dfe50a3257d54aab02fe7bfc /examples | |
| parent | d7e517e2d32c590e62e3e3339e191d19ce764c12 (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.rs | 16 |
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 | } |
