Commit b462b4ddc4bfb0121314c636c02e325be579e7f0

Authored by Antonio Carlos Domínguez Brito
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
@@ -57,20 +57,20 @@ namespace arduino_due @@ -57,20 +57,20 @@ namespace arduino_due
57 pwm& operator=(pwm&& the_pwm) = delete; 57 pwm& operator=(pwm&& the_pwm) = delete;
58 58
59 bool start( 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 uint32_t clock; 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 void stop() { if(_started_) _stop_(); } 76 void stop() { if(_started_) _stop_(); }
@@ -79,53 +79,71 @@ namespace arduino_due @@ -79,53 +79,71 @@ namespace arduino_due
79 79
80 bool set_duty(uint32_t duty /* 1e-8 secs. */) 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 bool set_period_and_duty( 98 bool set_period_and_duty(
99 uint32_t period, /* 1e-8 secs. */ 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 uint32_t get_period() { return _period_; } 149 uint32_t get_period() { return _period_; }
@@ -140,24 +158,24 @@ namespace arduino_due @@ -140,24 +158,24 @@ namespace arduino_due
140 bool _started_; 158 bool _started_;
141 159
142 void _start_( 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 void _stop_() 166 void _stop_()
149 { 167 {
150 PWMC_DisableChannel( 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,8 +218,8 @@ namespace arduino_due
200 PWM_INTERFACE, 218 PWM_INTERFACE,
201 pin_info::channel, 219 pin_info::channel,
202 static_cast<uint32_t>( 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,8 +231,8 @@ namespace arduino_due
213 PWM_INTERFACE, 231 PWM_INTERFACE,
214 pin_info::channel, 232 pin_info::channel,
215 static_cast<uint32_t>( 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,7 +248,11 @@ namespace arduino_due
230 virtual void stop() = 0; 248 virtual void stop() = 0;
231 virtual uint32_t get_duty() = 0; 249 virtual uint32_t get_duty() = 0;
232 virtual bool set_duty(uint32_t duty) = 0; 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 virtual uint32_t get_period() = 0; 256 virtual uint32_t get_period() = 0;
235 257
236 virtual uint32_t get_clock() = 0; 258 virtual uint32_t get_clock() = 0;
@@ -262,8 +284,12 @@ namespace arduino_due @@ -262,8 +284,12 @@ namespace arduino_due
262 bool set_duty(uint32_t duty) override 284 bool set_duty(uint32_t duty) override
263 { return _pwm_obj_.set_duty(duty); } 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 uint32_t get_period() override 294 uint32_t get_period() override
269 { return _pwm_obj_.get_period(); } 295 { return _pwm_obj_.get_period(); }
@@ -292,12 +318,12 @@ namespace arduino_due @@ -292,12 +318,12 @@ namespace arduino_due
292 servo& operator=(servo&& the_servo) = delete; 318 servo& operator=(servo&& the_servo) = delete;
293 319
294 bool start( 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 void stop() { _pwm_obj_.stop(); } 329 void stop() { _pwm_obj_.stop(); }
@@ -306,11 +332,11 @@ namespace arduino_due @@ -306,11 +332,11 @@ namespace arduino_due
306 332
307 bool set_angle(uint32_t angle /* degrees */) 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 uint32_t duty= 341 uint32_t duty=
316 ( 342 (
@@ -318,9 +344,9 @@ namespace arduino_due @@ -318,9 +344,9 @@ namespace arduino_due
318 static_cast<double>(_a_max_-_a_min_) 344 static_cast<double>(_a_max_-_a_min_)
319 )*(_t_max_-_t_min_) + _t_min_; 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 uint32_t get_period() { return _pwm_obj_.get_period(); } 352 uint32_t get_period() { return _pwm_obj_.get_period(); }
@@ -384,12 +410,12 @@ namespace arduino_due @@ -384,12 +410,12 @@ namespace arduino_due
384 virtual ~servo_base() {} 410 virtual ~servo_base() {}
385 411
386 virtual bool start( 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 ) = 0; 419 ) = 0;
394 virtual void stop() = 0; 420 virtual void stop() = 0;
395 virtual uint32_t get_angle() = 0; 421 virtual uint32_t get_angle() = 0;
@@ -410,22 +436,22 @@ namespace arduino_due @@ -410,22 +436,22 @@ namespace arduino_due
410 ~servo_wrapper() override {} 436 ~servo_wrapper() override {}
411 437
412 bool start( 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 ) override 445 ) override
420 { 446 {
421 return _servo_obj_.start( 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 void stop() override { _servo_obj_.stop(); } 457 void stop() override { _servo_obj_.stop(); }