@@ -32,6 +32,8 @@ pub enum AppStatus {
3232 Demo4 ,
3333}
3434
35+ type SeqBuffer = & ' static mut [ u16 ; 48 ] ;
36+
3537#[ rtic:: app( device = crate :: hal:: pac, peripherals = true , monotonic = rtic:: cyccnt:: CYCCNT ) ]
3638const APP : ( ) = {
3739 struct Resources {
@@ -40,13 +42,16 @@ const APP: () = {
4042 btn2 : Pin < Input < PullUp > > ,
4143 btn3 : Pin < Input < PullUp > > ,
4244 btn4 : Pin < Input < PullUp > > ,
43- pwm : Pwm < PWM0 > ,
4445 #[ init( AppStatus :: Idle ) ]
4546 status : AppStatus ,
47+ pwm : Option < PwmSeq < PWM0 , SeqBuffer , SeqBuffer > > ,
4648 }
4749
4850 #[ init]
4951 fn init ( mut ctx : init:: Context ) -> init:: LateResources {
52+ static mut BUF0 : [ u16 ; 48 ] = [ 0u16 ; 48 ] ;
53+ static mut BUF1 : [ u16 ; 48 ] = [ 0u16 ; 48 ] ;
54+
5055 let _clocks = hal:: clocks:: Clocks :: new ( ctx. device . CLOCK ) . enable_ext_hfosc ( ) ;
5156 ctx. core . DCB . enable_trace ( ) ;
5257 ctx. core . DWT . enable_cycle_counter ( ) ;
@@ -84,7 +89,7 @@ const APP: () = {
8489 btn2,
8590 btn3,
8691 btn4,
87- pwm,
92+ pwm : pwm . load ( Some ( BUF0 ) , Some ( BUF1 ) , false ) . ok ( ) ,
8893 }
8994 }
9095
@@ -98,29 +103,30 @@ const APP: () = {
98103
99104 #[ task( binds = PWM0 , resources = [ pwm] ) ]
100105 fn on_pwm ( ctx : on_pwm:: Context ) {
101- let pwm = ctx. resources . pwm ;
102- if pwm . is_event_triggered ( PwmEvent :: Stopped ) {
103- pwm . reset_event ( PwmEvent :: Stopped ) ;
106+ let pwm_seq = ctx. resources . pwm . as_ref ( ) . unwrap ( ) ;
107+ if pwm_seq . is_event_triggered ( PwmEvent :: Stopped ) {
108+ pwm_seq . reset_event ( PwmEvent :: Stopped ) ;
104109 rprintln ! ( "PWM generation was stopped" ) ;
105110 }
106111 }
107112
108113 #[ task( binds = GPIOTE , resources = [ gpiote] , schedule = [ debounce] ) ]
109114 fn on_gpiote ( ctx : on_gpiote:: Context ) {
110115 ctx. resources . gpiote . reset_events ( ) ;
111- ctx. schedule . debounce ( ctx. start + 3_000_000 . cycles ( ) ) . ok ( ) ;
116+ ctx. schedule . debounce ( ctx. start + 2_500_000 . cycles ( ) ) . ok ( ) ;
112117 }
113118
114119 #[ task( resources = [ btn1, btn2, btn3, btn4, pwm, status] ) ]
115120 fn debounce ( ctx : debounce:: Context ) {
116- static mut BUF : [ u16 ; 48 ] = [ 0u16 ; 48 ] ;
117- let status = ctx. resources . status ;
121+ let ( buf0, buf1, pwm) = ctx. resources . pwm . take ( ) . unwrap ( ) . split ( ) ;
122+ let BUF0 = buf0. unwrap ( ) ;
123+ let BUF1 = buf1. unwrap ( ) ;
118124
119- let pwm = ctx. resources . pwm ;
120125 let max_duty = pwm. max_duty ( ) ;
121126 let ( ch0, ch1, ch2, ch3) = pwm. split_channels ( ) ;
122127 let ( grp0, grp1) = pwm. split_groups ( ) ;
123128
129+ let status = ctx. resources . status ;
124130 if ctx. resources . btn1 . is_low ( ) . unwrap ( ) {
125131 match status {
126132 AppStatus :: Demo1B => {
@@ -143,68 +149,65 @@ const APP: () = {
143149 pwm. set_duty_on_common ( max_duty / 10 ) ;
144150 }
145151 }
146- }
147- if ctx. resources . btn2 . is_low ( ) . unwrap ( ) {
152+ * ctx . resources . pwm = pwm . load ( Some ( BUF0 ) , Some ( BUF1 ) , false ) . ok ( ) ;
153+ } else if ctx. resources . btn2 . is_low ( ) . unwrap ( ) {
148154 match status {
149155 AppStatus :: Demo2B => {
150156 rprintln ! ( "DEMO 2C: Play grouped sequence 4 times" ) ;
151157 * status = AppStatus :: Demo2C ;
152158 let ampl = max_duty as i32 / 20 ;
153- let len: usize = 12 ;
159+ let len: usize = BUF0 . len ( ) / 2 ;
154160 // In `Grouped` mode, each step consists of two values [G0, G1]
155161 for x in 0 ..len {
156- BUF [ x * 2 ] = triangle_wave ( x, len, ampl, 6 , 0 ) as u16 ;
157- BUF [ x * 2 + 1 ] = triangle_wave ( x, len, ampl, 0 , 0 ) as u16 ;
162+ BUF0 [ x * 2 ] = triangle_wave ( x, len, ampl, 6 , 0 ) as u16 ;
163+ BUF0 [ x * 2 + 1 ] = triangle_wave ( x, len, ampl, 0 , 0 ) as u16 ;
158164 }
165+ BUF1 . copy_from_slice ( & BUF0 [ ..] ) ;
159166 pwm. set_load_mode ( LoadMode :: Grouped )
160167 . set_step_mode ( StepMode :: Auto )
161- . set_seq_refresh ( Seq :: Seq0 , 70 ) // Playback rate (periods per step)
162- . set_seq_refresh ( Seq :: Seq1 , 30 )
168+ . set_seq_refresh ( Seq :: Seq0 , 30 ) // Playback rate (periods per step)
169+ . set_seq_refresh ( Seq :: Seq1 , 10 )
163170 . repeat ( 4 ) ;
164- pwm. load_seq ( Seq :: Seq0 , & BUF [ ..len] ) . ok ( ) ;
165- pwm. load_seq ( Seq :: Seq1 , & BUF [ len..( 2 * len) ] ) . ok ( ) ;
166- pwm. start_seq ( Seq :: Seq0 ) ;
171+ * ctx. resources . pwm = pwm. load ( Some ( BUF0 ) , Some ( BUF1 ) , true ) . ok ( ) ;
167172 }
168173 AppStatus :: Demo2A => {
169174 rprintln ! ( "DEMO 2B: Loop individual sequences" ) ;
170175 * status = AppStatus :: Demo2B ;
171176 let ampl = max_duty as i32 / 5 ;
172177 let offset = max_duty as i32 / 300 ;
173- let len = 12 ;
178+ let len = BUF0 . len ( ) / 4 ;
174179 // In `Individual` mode, each step consists of four values [C0, C1, C2, C3]
175180 for x in 0 ..len {
176- BUF [ 4 * x] = triangle_wave ( x, len, ampl, 0 , offset) as u16 ;
177- BUF [ 4 * x + 1 ] = triangle_wave ( x, len, ampl, 3 , offset) as u16 ;
178- BUF [ 4 * x + 2 ] = triangle_wave ( x, len, ampl, 6 , offset) as u16 ;
179- BUF [ 4 * x + 3 ] = triangle_wave ( x, len, ampl, 9 , offset) as u16 ;
181+ BUF0 [ 4 * x] = triangle_wave ( x, len, ampl, 0 , offset) as u16 ;
182+ BUF0 [ 4 * x + 1 ] = triangle_wave ( x, len, ampl, 3 , offset) as u16 ;
183+ BUF0 [ 4 * x + 2 ] = triangle_wave ( x, len, ampl, 6 , offset) as u16 ;
184+ BUF0 [ 4 * x + 3 ] = triangle_wave ( x, len, ampl, 9 , offset) as u16 ;
180185 }
186+ BUF1 . copy_from_slice ( & BUF0 [ ..] ) ;
181187 pwm. set_load_mode ( LoadMode :: Individual )
182188 . set_seq_refresh ( Seq :: Seq0 , 30 )
183189 . set_seq_refresh ( Seq :: Seq1 , 30 )
184190 . loop_inf ( ) ;
185- pwm. load_seq ( Seq :: Seq0 , & BUF [ ..( 4 * len) ] ) . ok ( ) ;
186- pwm. load_seq ( Seq :: Seq1 , & BUF [ ..( 4 * len) ] ) . ok ( ) ;
187- pwm. start_seq ( Seq :: Seq0 ) ;
191+ * ctx. resources . pwm = pwm. load ( Some ( BUF0 ) , Some ( BUF1 ) , true ) . ok ( ) ;
188192 }
189193 _ => {
190194 rprintln ! ( "DEMO 2A: Play common sequence once" ) ;
191195 * status = AppStatus :: Demo2A ;
192- let len = 10 ;
196+ let len = BUF0 . len ( ) ;
193197 // In `Common` mode, each step consists of one value for all channels.
194198 for x in 0 ..len {
195- BUF [ x] = triangle_wave ( x, len, 2000 , 0 , 100 ) as u16 ;
199+ BUF0 [ x] = triangle_wave ( x, len, 2000 , 0 , 100 ) as u16 ;
196200 }
201+ BUF1 . copy_from_slice ( & BUF0 [ ..] ) ;
197202 pwm. set_load_mode ( LoadMode :: Common )
198203 . set_step_mode ( StepMode :: Auto )
199- . set_seq_refresh ( Seq :: Seq0 , 50 )
200- . one_shot ( )
201- . load_seq ( Seq :: Seq0 , & BUF [ ..len] )
202- . ok ( ) ;
203- pwm. start_seq ( Seq :: Seq0 ) ;
204+ . set_seq_refresh ( Seq :: Seq0 , 20 )
205+ . set_seq_refresh ( Seq :: Seq1 , 20 )
206+ . one_shot ( ) ;
207+ * ctx. resources . pwm = pwm. load ( Some ( BUF0 ) , Some ( BUF1 ) , true ) . ok ( ) ;
204208 }
205209 }
206- }
207- if ctx. resources . btn3 . is_low ( ) . unwrap ( ) {
210+ } else if ctx. resources . btn3 . is_low ( ) . unwrap ( ) {
208211 match status {
209212 AppStatus :: Demo3 => {
210213 rprintln ! ( "DEMO 3: Next step" ) ;
@@ -215,46 +218,46 @@ const APP: () = {
215218 pwm. stop ( ) ;
216219 * status = AppStatus :: Idle ;
217220 }
221+ * ctx. resources . pwm = pwm. load ( Some ( BUF0 ) , Some ( BUF1 ) , false ) . ok ( ) ;
218222 }
219223 _ => {
220224 rprintln ! ( "DEMO 3: Manually step through sequence" ) ;
221225 * status = AppStatus :: Demo3 ;
222226 let amplitude = max_duty as i32 / 20 ;
223227 let offset = max_duty as i32 / 300 ;
224- let len = 6 ;
228+ let len = BUF0 . len ( ) ;
225229 for x in 0 ..len {
226- BUF [ x] = triangle_wave ( x, len, amplitude, 0 , offset) as u16 ;
230+ BUF0 [ x] = triangle_wave ( x * 8 , len, amplitude, 0 , offset) as u16 ;
227231 }
232+ BUF1 . copy_from_slice ( & BUF0 [ ..] ) ;
228233 pwm. set_load_mode ( LoadMode :: Common )
229234 . set_step_mode ( StepMode :: NextStep )
230235 . loop_inf ( ) ;
231- pwm. load_seq ( Seq :: Seq0 , & BUF [ ..( len / 2 ) ] ) . ok ( ) ;
232- pwm. load_seq ( Seq :: Seq1 , & BUF [ ( len / 2 ) ..len] ) . ok ( ) ;
233- pwm. start_seq ( Seq :: Seq0 ) ;
236+ * ctx. resources . pwm = pwm. load ( Some ( BUF0 ) , Some ( BUF1 ) , true ) . ok ( ) ;
234237 }
235238 }
236- }
237- if ctx. resources . btn4 . is_low ( ) . unwrap ( ) {
239+ } else if ctx. resources . btn4 . is_low ( ) . unwrap ( ) {
238240 rprintln ! ( "DEMO 4: Waveform mode" ) ;
239241 * status = AppStatus :: Demo4 ;
240- let len = 12 ;
242+ let len = BUF0 . len ( ) / 4 ;
241243 // In `Waveform` mode, each step consists of four values [C0, C1, C2, MAX_DUTY]
242244 // So the maximum duty cycle can be set on a per step basis, affecting the PWM frequency
243245 for x in 0 ..len {
244246 let current_max = x * 2_200 + 5_000 ;
245- BUF [ 4 * x] = ( ( x % 3 ) * current_max / ( 5 * ( x + 1 ) ) ) as u16 ;
246- BUF [ 4 * x + 1 ] = ( ( ( x + 1 ) % 3 ) * current_max / ( 5 * ( x + 1 ) ) ) as u16 ;
247- BUF [ 4 * x + 2 ] = ( ( ( x + 2 ) % 3 ) * current_max / ( 5 * ( x + 1 ) ) ) as u16 ;
248- BUF [ 4 * x + 3 ] = current_max as u16 ;
247+ BUF0 [ 4 * x] = ( ( x % 3 ) * current_max / ( 5 * ( x + 1 ) ) ) as u16 ;
248+ BUF0 [ 4 * x + 1 ] = ( ( ( x + 1 ) % 3 ) * current_max / ( 5 * ( x + 1 ) ) ) as u16 ;
249+ BUF0 [ 4 * x + 2 ] = ( ( ( x + 2 ) % 3 ) * current_max / ( 5 * ( x + 1 ) ) ) as u16 ;
250+ BUF0 [ 4 * x + 3 ] = current_max as u16 ;
249251 }
252+ BUF1 . copy_from_slice ( & BUF0 [ ..] ) ;
250253 pwm. set_load_mode ( LoadMode :: Waveform )
251254 . set_step_mode ( StepMode :: Auto )
252255 . set_seq_refresh ( Seq :: Seq0 , 150 )
253256 . set_seq_refresh ( Seq :: Seq1 , 150 )
254257 . loop_inf ( ) ;
255- pwm. load_seq ( Seq :: Seq0 , & BUF [ .. ( 4 * len ) ] ) . ok ( ) ;
256- pwm . load_seq ( Seq :: Seq1 , & BUF [ .. ( 4 * len ) ] ) . ok ( ) ;
257- pwm. start_seq ( Seq :: Seq0 ) ;
258+ * ctx . resources . pwm = pwm . load ( Some ( BUF0 ) , Some ( BUF1 ) , true ) . ok ( ) ;
259+ } else {
260+ * ctx . resources . pwm = pwm . load ( Some ( BUF0 ) , Some ( BUF1 ) , false ) . ok ( ) ;
258261 }
259262 }
260263
0 commit comments