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
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(); }
... ...