Commit b462b4ddc4bfb0121314c636c02e325be579e7f0
1 parent
0e5eb62b
Exists in
master
added a keep_clock option to set_period_and_duty(), in order to aviod changing t…
…he clock when modifying the PWM period
Showing
1 changed file
with
126 additions
and
100 deletions
Show diff stats
pwm_lib.h
... | ... | @@ -57,20 +57,20 @@ namespace arduino_due |
57 | 57 | pwm& operator=(pwm&& the_pwm) = delete; |
58 | 58 | |
59 | 59 | bool start( |
60 | - uint32_t period, // hundredths of usecs (1e-8 secs) | |
61 | - uint32_t duty // // hundredths of usecs (1e-8 secs) | |
60 | + uint32_t period, // hundredths of usecs (1e-8 secs) | |
61 | + uint32_t duty // // hundredths of usecs (1e-8 secs) | |
62 | 62 | ) |
63 | 63 | { |
64 | 64 | uint32_t clock; |
65 | - if( | |
66 | - _started_ | |
67 | - || !pwm_core::find_clock(period,clock) | |
68 | - || (duty>period) | |
69 | - ) return false; | |
65 | + if( | |
66 | + _started_ | |
67 | + || !pwm_core::find_clock(period,clock) | |
68 | + || (duty>period) | |
69 | + ) return false; | |
70 | 70 | |
71 | - _start_(period,duty,clock); | |
71 | + _start_(period,duty,clock); | |
72 | 72 | |
73 | - return true; | |
73 | + return true; | |
74 | 74 | } |
75 | 75 | |
76 | 76 | void stop() { if(_started_) _stop_(); } |
... | ... | @@ -79,53 +79,71 @@ namespace arduino_due |
79 | 79 | |
80 | 80 | bool set_duty(uint32_t duty /* 1e-8 secs. */) |
81 | 81 | { |
82 | - if(!_started_ || (duty>_period_)) return false; | |
83 | - | |
84 | - _duty_=duty; | |
85 | - //PWMC_SetDutyCycle( | |
86 | - pwm_core::pwmc_setdutycycle( | |
87 | - PWM_INTERFACE, | |
88 | - pin_info::channel, | |
89 | - static_cast<uint32_t>( | |
90 | - (static_cast<double>(duty)/100000000)/ | |
91 | - pwm_core::tick_times[_clock_] | |
92 | - ) | |
93 | - ); | |
94 | - | |
95 | - return true; | |
82 | + if(!_started_ || (duty>_period_)) return false; | |
83 | + | |
84 | + _duty_=duty; | |
85 | + //PWMC_SetDutyCycle( | |
86 | + pwm_core::pwmc_setdutycycle( | |
87 | + PWM_INTERFACE, | |
88 | + pin_info::channel, | |
89 | + static_cast<uint32_t>( | |
90 | + (static_cast<double>(duty)/100000000)/ | |
91 | + pwm_core::tick_times[_clock_] | |
92 | + ) | |
93 | + ); | |
94 | + | |
95 | + return true; | |
96 | 96 | } |
97 | 97 | |
98 | 98 | bool set_period_and_duty( |
99 | 99 | uint32_t period, /* 1e-8 secs. */ |
100 | - uint32_t duty /* 1e-8 secs. */ | |
100 | + uint32_t duty, /* 1e-8 secs. */ | |
101 | + bool keep_clock = true | |
101 | 102 | ) |
102 | 103 | { |
103 | - uint32_t clock; | |
104 | - | |
105 | - if( | |
106 | - !_started_ | |
107 | - || !pwm_core::find_clock(period,clock) | |
108 | - || (duty>period) | |
109 | - ) return false; | |
110 | - | |
111 | - if(clock==_clock_) | |
112 | - { | |
113 | - _period_=period; | |
114 | - PWMC_SetPeriod( | |
115 | - PWM_INTERFACE, | |
116 | - pin_info::channel, | |
117 | - static_cast<uint32_t>( | |
118 | - (static_cast<double>(period)/100000000)/ | |
119 | - pwm_core::tick_times[_clock_] | |
120 | - ) | |
121 | - ); | |
122 | - | |
123 | - set_duty(duty); | |
124 | - } | |
125 | - else | |
126 | - { _stop_(); _start_(period,duty,clock); } | |
127 | - | |
128 | - return true; | |
104 | + if(!_started_ || (duty>period)) return false; | |
105 | + | |
106 | + if(keep_clock) | |
107 | + { | |
108 | + auto new_period=static_cast<double>(period)/100000000; | |
109 | + | |
110 | + if(new_period>pwm_core::max_periods[_clock_]) return false; | |
111 | + | |
112 | + _period_=period; | |
113 | + PWMC_SetPeriod( | |
114 | + PWM_INTERFACE, | |
115 | + pin_info::channel, | |
116 | + static_cast<uint32_t>( | |
117 | + new_period/pwm_core::tick_times[_clock_] | |
118 | + ) | |
119 | + ); | |
120 | + | |
121 | + set_duty(duty); | |
122 | + } | |
123 | + else | |
124 | + { | |
125 | + uint32_t clock; | |
126 | + if(!pwm_core::find_clock(period,clock)) return false; | |
127 | + | |
128 | + if(clock==_clock_) | |
129 | + { | |
130 | + _period_=period; | |
131 | + PWMC_SetPeriod( | |
132 | + PWM_INTERFACE, | |
133 | + pin_info::channel, | |
134 | + static_cast<uint32_t>( | |
135 | + (static_cast<double>(period)/100000000)/ | |
136 | + pwm_core::tick_times[_clock_] | |
137 | + ) | |
138 | + ); | |
139 | + | |
140 | + set_duty(duty); | |
141 | + } | |
142 | + else | |
143 | + { _stop_(); _start_(period,duty,clock); } | |
144 | + } | |
145 | + | |
146 | + return true; | |
129 | 147 | } |
130 | 148 | |
131 | 149 | uint32_t get_period() { return _period_; } |
... | ... | @@ -140,24 +158,24 @@ namespace arduino_due |
140 | 158 | bool _started_; |
141 | 159 | |
142 | 160 | void _start_( |
143 | - uint32_t period, // hundredths of usecs (1e-8 secs.) | |
144 | - uint32_t duty, // hundredths of usecs (1e-8 secs.) | |
145 | - uint32_t clock | |
161 | + uint32_t period, // hundredths of usecs (1e-8 secs.) | |
162 | + uint32_t duty, // hundredths of usecs (1e-8 secs.) | |
163 | + uint32_t clock | |
146 | 164 | ); |
147 | 165 | |
148 | 166 | void _stop_() |
149 | 167 | { |
150 | 168 | PWMC_DisableChannel( |
151 | - PWM_INTERFACE, | |
152 | - pin_info::channel | |
153 | - ); | |
169 | + PWM_INTERFACE, | |
170 | + pin_info::channel | |
171 | + ); | |
154 | 172 | |
155 | - while( | |
156 | - (PWM->PWM_SR & (1<<pin_info::channel)) | |
157 | - != 0 | |
158 | - ) { /* nothing */ } | |
173 | + while( | |
174 | + (PWM->PWM_SR & (1<<pin_info::channel)) | |
175 | + != 0 | |
176 | + ) { /* nothing */ } | |
159 | 177 | |
160 | - _started_=false; | |
178 | + _started_=false; | |
161 | 179 | } |
162 | 180 | }; |
163 | 181 | |
... | ... | @@ -200,8 +218,8 @@ namespace arduino_due |
200 | 218 | PWM_INTERFACE, |
201 | 219 | pin_info::channel, |
202 | 220 | static_cast<uint32_t>( |
203 | - (static_cast<double>(period)/100000000)/ | |
204 | - pwm_core::tick_times[_clock_] | |
221 | + (static_cast<double>(period)/100000000)/ | |
222 | + pwm_core::tick_times[_clock_] | |
205 | 223 | ) |
206 | 224 | ); |
207 | 225 | |
... | ... | @@ -213,8 +231,8 @@ namespace arduino_due |
213 | 231 | PWM_INTERFACE, |
214 | 232 | pin_info::channel, |
215 | 233 | static_cast<uint32_t>( |
216 | - (static_cast<double>(duty)/100000000)/ | |
217 | - pwm_core::tick_times[_clock_] | |
234 | + (static_cast<double>(duty)/100000000)/ | |
235 | + pwm_core::tick_times[_clock_] | |
218 | 236 | ) |
219 | 237 | ); |
220 | 238 | |
... | ... | @@ -230,7 +248,11 @@ namespace arduino_due |
230 | 248 | virtual void stop() = 0; |
231 | 249 | virtual uint32_t get_duty() = 0; |
232 | 250 | virtual bool set_duty(uint32_t duty) = 0; |
233 | - virtual bool set_period_and_duty(uint32_t period, uint32_t duty) = 0; | |
251 | + virtual bool set_period_and_duty( | |
252 | + uint32_t period, | |
253 | + uint32_t duty, | |
254 | + bool keep_clock = true | |
255 | + ) = 0; | |
234 | 256 | virtual uint32_t get_period() = 0; |
235 | 257 | |
236 | 258 | virtual uint32_t get_clock() = 0; |
... | ... | @@ -262,8 +284,12 @@ namespace arduino_due |
262 | 284 | bool set_duty(uint32_t duty) override |
263 | 285 | { return _pwm_obj_.set_duty(duty); } |
264 | 286 | |
265 | - bool set_period_and_duty(uint32_t period, uint32_t duty) override | |
266 | - { return _pwm_obj_.set_period_and_duty(period,duty); } | |
287 | + bool set_period_and_duty( | |
288 | + uint32_t period, | |
289 | + uint32_t duty, | |
290 | + bool keep_clock = true | |
291 | + ) override | |
292 | + { return _pwm_obj_.set_period_and_duty(period,duty,keep_clock); } | |
267 | 293 | |
268 | 294 | uint32_t get_period() override |
269 | 295 | { return _pwm_obj_.get_period(); } |
... | ... | @@ -292,12 +318,12 @@ namespace arduino_due |
292 | 318 | servo& operator=(servo&& the_servo) = delete; |
293 | 319 | |
294 | 320 | bool start( |
295 | - uint32_t period, // hundredths of usecs (1e-8 secs) | |
296 | - uint32_t time_min, // hundredths of usecs (1e-8 secs) | |
297 | - uint32_t time_max, // hundredths of usecs (1e-8 secs) | |
298 | - uint32_t angle_min, // degrees | |
299 | - uint32_t angle_max, // degress | |
300 | - uint32_t duty // degress | |
321 | + uint32_t period, // hundredths of usecs (1e-8 secs) | |
322 | + uint32_t time_min, // hundredths of usecs (1e-8 secs) | |
323 | + uint32_t time_max, // hundredths of usecs (1e-8 secs) | |
324 | + uint32_t angle_min, // degrees | |
325 | + uint32_t angle_max, // degress | |
326 | + uint32_t duty // degress | |
301 | 327 | ); |
302 | 328 | |
303 | 329 | void stop() { _pwm_obj_.stop(); } |
... | ... | @@ -306,11 +332,11 @@ namespace arduino_due |
306 | 332 | |
307 | 333 | bool set_angle(uint32_t angle /* degrees */) |
308 | 334 | { |
309 | - if( | |
310 | - !pwm_core::is_inside(_a_min_,_a_max_,angle) | |
311 | - ) return false; | |
335 | + if( | |
336 | + !pwm_core::is_inside(_a_min_,_a_max_,angle) | |
337 | + ) return false; | |
312 | 338 | |
313 | - _angle_=angle; | |
339 | + _angle_=angle; | |
314 | 340 | |
315 | 341 | uint32_t duty= |
316 | 342 | ( |
... | ... | @@ -318,9 +344,9 @@ namespace arduino_due |
318 | 344 | static_cast<double>(_a_max_-_a_min_) |
319 | 345 | )*(_t_max_-_t_min_) + _t_min_; |
320 | 346 | |
321 | - if(_pwm_obj_.set_duty(duty)) { _angle_=angle; return true; } | |
322 | - | |
323 | - return false; | |
347 | + if(_pwm_obj_.set_duty(duty)) { _angle_=angle; return true; } | |
348 | + | |
349 | + return false; | |
324 | 350 | } |
325 | 351 | |
326 | 352 | uint32_t get_period() { return _pwm_obj_.get_period(); } |
... | ... | @@ -384,12 +410,12 @@ namespace arduino_due |
384 | 410 | virtual ~servo_base() {} |
385 | 411 | |
386 | 412 | virtual bool start( |
387 | - uint32_t period, // hundredths of usecs (1e-8 secs) | |
388 | - uint32_t time_min, // hundredths of usecs (1e-8 secs) | |
389 | - uint32_t time_max, // hundredths of usecs (1e-8 secs) | |
390 | - uint32_t angle_min, // degrees | |
391 | - uint32_t angle_max, // degress | |
392 | - uint32_t duty // degress | |
413 | + uint32_t period, // hundredths of usecs (1e-8 secs) | |
414 | + uint32_t time_min, // hundredths of usecs (1e-8 secs) | |
415 | + uint32_t time_max, // hundredths of usecs (1e-8 secs) | |
416 | + uint32_t angle_min, // degrees | |
417 | + uint32_t angle_max, // degress | |
418 | + uint32_t duty // degress | |
393 | 419 | ) = 0; |
394 | 420 | virtual void stop() = 0; |
395 | 421 | virtual uint32_t get_angle() = 0; |
... | ... | @@ -410,22 +436,22 @@ namespace arduino_due |
410 | 436 | ~servo_wrapper() override {} |
411 | 437 | |
412 | 438 | bool start( |
413 | - uint32_t period, // hundredths of usecs (1e-8 secs) | |
414 | - uint32_t time_min, // hundredths of usecs (1e-8 secs) | |
415 | - uint32_t time_max, // hundredths of usecs (1e-8 secs) | |
416 | - uint32_t angle_min, // degrees | |
417 | - uint32_t angle_max, // degress | |
418 | - uint32_t duty // degress | |
439 | + uint32_t period, // hundredths of usecs (1e-8 secs) | |
440 | + uint32_t time_min, // hundredths of usecs (1e-8 secs) | |
441 | + uint32_t time_max, // hundredths of usecs (1e-8 secs) | |
442 | + uint32_t angle_min, // degrees | |
443 | + uint32_t angle_max, // degress | |
444 | + uint32_t duty // degress | |
419 | 445 | ) override |
420 | 446 | { |
421 | 447 | return _servo_obj_.start( |
422 | - period, | |
423 | - time_min, | |
424 | - time_max, | |
425 | - angle_min, | |
426 | - angle_max, | |
427 | - duty | |
428 | - ); | |
448 | + period, | |
449 | + time_min, | |
450 | + time_max, | |
451 | + angle_min, | |
452 | + angle_max, | |
453 | + duty | |
454 | + ); | |
429 | 455 | } |
430 | 456 | |
431 | 457 | void stop() override { _servo_obj_.stop(); } | ... | ... |