COSA
An Object-Oriented Platform for Arduino Programming
PWMPin.cpp
Go to the documentation of this file.
1 
21 #include "Cosa/PWMPin.hh"
22 #include "Cosa/Power.hh"
23 
24 #if defined(BOARD_ATMEGA328P)
25 
26 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
27  OutputPin((Board::DigitalPin) pin)
28 {
29  switch (pin) {
30  case Board::PWM1:
31  case Board::PWM2:
32  // PWM1(0B), PMW2(0A), Fast PWM, prescale 64
33  TCCR0A |= _BV(WGM01) | _BV(WGM00);
34  TCCR0B |= _BV(CS01) | _BV(CS00);
35  break;
36 
37  case Board::PWM3:
38  case Board::PWM4:
39  // PWM3(1A), PWM4(1B), PWM phase correct, 8-bit, prescale 64
40  TCCR1A |= _BV(WGM10);
41  TCCR1B |= _BV(CS11) | _BV(CS10);
42  break;
43 
44  case Board::PWM0:
45  case Board::PWM5:
46  // PWM0(2B), PWM5(2A), PWM phase correct, prescale 64
47  TCCR2A |= _BV(WGM20);
48  TCCR2B |= _BV(CS22);
49  break;
50  }
51  set(duty);
52 }
53 
54 void
56 {
57  switch (m_pin) {
58  case Board::PWM0:
59  case Board::PWM5:
60  Power::timer2_enable();
61  break;
62  case Board::PWM1:
63  case Board::PWM2:
65  break;
66  case Board::PWM3:
67  case Board::PWM4:
69  break;
70  default:
71  ;
72  }
73 }
74 
75 uint8_t
77 {
78  switch (m_pin) {
79  case Board::PWM0: return (OCR2B);
80  case Board::PWM1: return (OCR0B);
81  case Board::PWM2: return (OCR0A);
82  case Board::PWM3: return (OCR1A);
83  case Board::PWM4: return (OCR1B);
84  case Board::PWM5: return (OCR2A);
85  default:
86  return (is_set());
87  }
88 }
89 
90 void
91 PWMPin::set(uint8_t duty)
92 {
93  switch (m_pin) {
94  case Board::PWM0:
95  bit_set(TCCR2A, COM2B1);
96  OCR2B = duty;
97  return;
98  case Board::PWM1:
99  bit_set(TCCR0A, COM0B1);
100  OCR0B = duty;
101  return;
102  case Board::PWM2:
103  bit_set(TCCR0A, COM0A1);
104  OCR0A = duty;
105  return;
106  case Board::PWM3:
107  bit_set(TCCR1A, COM1A1);
108  OCR1A = duty;
109  return;
110  case Board::PWM4:
111  bit_set(TCCR1A, COM1B1);
112  OCR1B = duty;
113  return;
114  case Board::PWM5:
115  bit_set(TCCR2A, COM2A1);
116  OCR2A = duty;
117  return;
118  default:
119  OutputPin::set(duty);
120  }
121 }
122 
123 #elif defined(BOARD_ATMEGA32U4)
124 
125 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
126  OutputPin((Board::DigitalPin) pin)
127 {
128  switch (pin) {
129  case Board::PWM0:
130  case Board::PWM1:
131  // PWM0(0A), PMW1(0B), Fast PWM, prescale 64
132  TCCR0A |= _BV(WGM01) | _BV(WGM00);
133  TCCR0B |= _BV(CS01) | _BV(CS00);
134  break;
135 
136  case Board::PWM2:
137  case Board::PWM3:
138  // PWM2(1A), PWM3(1B), PWM phase correct, 10-bit, prescale 64
139  TCCR1A |= _BV(WGM11) | _BV(WGM10);
140  TCCR1B |= _BV(CS11) | _BV(CS10);
141  break;
142 
143  case Board::PWM4:
144  // PWM4(3A), PWM phase correct, 10-bit, prescale 64
145  TCCR3A |= _BV(WGM31) | _BV(WGM30);
146  TCCR3B |= _BV(CS31) | _BV(CS30);
147  break;
148 
149  case Board::PWM5:
150  case Board::PWM6:
151  // PWM5(4A), PMW6(4D), Fast PWM, prescale 64
152  TCCR4A |= _BV(PWM4A);
153  TCCR4B |= _BV(CS42) | _BV(CS41) | _BV(CS40);
154  TCCR4C |= _BV(PWM4D);
155  break;
156  }
157  set(duty);
158 }
159 
160 void
162 {
163  switch (m_pin) {
164  case Board::PWM0:
165  case Board::PWM1:
167  break;
168  case Board::PWM2:
169  case Board::PWM3:
171  break;
172  case Board::PWM4:
173  Power::timer3_enable();
174  break;
175  case Board::PWM5:
176  case Board::PWM6:
177  // Not supported by avr/power.h
178  // Power::timer4_enable();
179  break;
180  default:
181  ;
182  }
183 }
184 
185 uint8_t
186 PWMPin::duty()
187 {
188  switch (m_pin) {
189  case Board::PWM0: return (OCR0A);
190  case Board::PWM1: return (OCR0B);
191  case Board::PWM2: return (OCR1A);
192  case Board::PWM3: return (OCR1B);
193  case Board::PWM4: return (OCR3A);
194  case Board::PWM5: return (OCR4A);
195  case Board::PWM6: return (OCR4D);
196  default:
197  return (is_set());
198  }
199 }
200 
201 void
202 PWMPin::set(uint8_t duty)
203 {
204  switch (m_pin) {
205  case Board::PWM0:
206  bit_set(TCCR0A, COM0A1);
207  OCR0A = duty;
208  return;
209  case Board::PWM1:
210  bit_set(TCCR0A, COM0B1);
211  OCR0B = duty;
212  return;
213  case Board::PWM2:
214  bit_set(TCCR1A, COM1A1);
215  OCR1A = duty;
216  return;
217  case Board::PWM3:
218  bit_set(TCCR1A, COM1B1);
219  OCR1B = duty;
220  return;
221  case Board::PWM4:
222  bit_set(TCCR3A, COM3A1);
223  OCR3A = duty;
224  return;
225  case Board::PWM5:
226  bit_set(TCCR4A, COM4A1);
227  bit_clear(TCCR4A, COM4A0);
228  OCR4A = duty;
229  return;
230  case Board::PWM6:
231  bit_set(TCCR4C, COM4D1);
232  OCR4D = duty;
233  return;
234  default:
235  OutputPin::set(duty);
236  }
237 }
238 
239 #elif defined(BOARD_ATMEGA1248P)
240 
241 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
242  OutputPin((Board::DigitalPin) pin)
243 {
244  switch (pin) {
245  case Board::PWM0:
246  case Board::PWM1:
247  // PWM0(0A), PMW1(0A), Fast PWM, prescale 64
248  TCCR0A |= _BV(WGM01) | _BV(WGM00);
249  TCCR0B |= _BV(CS01) | _BV(CS00);
250  break;
251 
252 #if defined(__AVR_ATmega1284P__)
253  case Board::PWM2:
254  case Board::PWM3:
255  // PWM2(3A), PWM3(3B) PWM phase correct, 8-bit, prescale 64
256  TCCR3A |= _BV(WGM30);
257  TCCR3B |= _BV(CS31) | _BV(CS30);
258 #endif
259  break;
260 
261  case Board::PWM4:
262  case Board::PWM5:
263  // PWM5(1A), PWM4(1B), PWM phase correct, 8-bit, prescale 64
264  TCCR1A |= _BV(WGM10);
265  TCCR1B |= _BV(CS11) | _BV(CS10);
266  break;
267 
268  case Board::PWM6:
269  case Board::PWM7:
270  // PWM6(2B), PWM7(2A), PWM phase correct, prescale 64
271  TCCR2A |= _BV(WGM20);
272  TCCR2B |= _BV(CS22);
273  break;
274  default:
275  break;
276  }
277  set(duty);
278 }
279 
280 void
282 {
283  switch (m_pin) {
284  case Board::PWM0:
285  case Board::PWM1:
287  break;
288 #if defined(__AVR_ATmega1284P__)
289  case Board::PWM2:
290  case Board::PWM3:
291  Power::timer3_enable();
292 #endif
293  case Board::PWM4:
294  case Board::PWM5:
296  break;
297  case Board::PWM6:
298  case Board::PWM7:
299  Power::timer2_enable();
300  break;
301  default:
302  ;
303  }
304 }
305 
306 uint8_t
307 PWMPin::duty()
308 {
309  switch (m_pin) {
310  case Board::PWM0: return (OCR0A);
311  case Board::PWM1: return (OCR0B);
312 #if defined(__AVR_ATmega1284P__)
313  case Board::PWM2: return (OCR3A);
314  case Board::PWM3: return (OCR3B);
315 #endif
316  case Board::PWM4: return (OCR1B);
317  case Board::PWM5: return (OCR1A);
318  case Board::PWM6: return (OCR2B);
319  case Board::PWM7: return (OCR2A);
320  default:
321  return (is_set());
322  }
323 }
324 
325 void
326 PWMPin::set(uint8_t duty)
327 {
328  switch (m_pin) {
329  case Board::PWM0:
330  bit_set(TCCR0A, COM0A1);
331  OCR0A = duty;
332  return;
333  case Board::PWM1:
334  bit_set(TCCR0B, COM0B1);
335  OCR0B = duty;
336  return;
337 #if defined(__AVR_ATmega1284P__)
338  case Board::PWM2:
339  bit_set(TCCR3A, COM3A1);
340  OCR3A = duty;
341  return;
342  case Board::PWM3:
343  bit_set(TCCR3B, COM3B1);
344  OCR3B = duty;
345  return;
346 #endif
347  case Board::PWM4:
348  bit_set(TCCR1B, COM1B1);
349  OCR1B = duty;
350  return;
351  case Board::PWM5:
352  bit_set(TCCR1A, COM1A1);
353  OCR1A = duty;
354  return;
355  case Board::PWM6:
356  bit_set(TCCR2B, COM2B1);
357  OCR2B = duty;
358  return;
359  case Board::PWM7:
360  bit_set(TCCR2A, COM2A1);
361  OCR2A = duty;
362  return;
363  default:
364  OutputPin::set(duty);
365  }
366 }
367 
368 #elif defined(BOARD_ATMEGA2560)
369 
370 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
371  OutputPin((Board::DigitalPin) pin)
372 {
373  switch (pin) {
374  case Board::PWM2:
375  case Board::PWM11:
376  // PWM2(0B), PMW11(0A), Fast PWM, prescale 64
377  TCCR0A |= _BV(WGM01) | _BV(WGM00);
378  TCCR0B |= _BV(CS01) | _BV(CS00);
379  break;
380 
381  case Board::PWM9:
382  case Board::PWM10:
383  // PWM9(1A), PWM10(1B), PWM phase correct, 8-bit, prescale 64
384  TCCR1A |= _BV(WGM10);
385  TCCR1B |= _BV(CS11) | _BV(CS10);
386  break;
387 
388  case Board::PWM7:
389  case Board::PWM8:
390  // PWM7(2B), PWM8(2A), PWM phase correct, prescale 64
391  TCCR2A |= _BV(WGM20);
392  TCCR2B |= _BV(CS22);
393  break;
394 
395  case Board::PWM3:
396  case Board::PWM0:
397  case Board::PWM1:
398  // PWM3(3A), PWM0(3B), PWM1(3C) PWM phase correct, 8-bit, prescale 64
399  TCCR3A |= _BV(WGM30);
400  TCCR3B |= _BV(CS31) | _BV(CS30);
401  break;
402 
403  case Board::PWM4:
404  case Board::PWM5:
405  case Board::PWM6:
406  // PWM4(3A), PWM5(3B), PWM6(3C) PWM phase correct, 8-bit, prescale 64
407  TCCR4A |= _BV(WGM40);
408  TCCR4B |= _BV(CS41) | _BV(CS40);
409  break;
410  }
411  set(duty);
412 }
413 
414 void
416 {
417  switch (m_pin) {
418  case Board::PWM0:
419  case Board::PWM1:
420  case Board::PWM3:
421  Power::timer3_enable();
422  break;
423  case Board::PWM2:
424  case Board::PWM11:
426  break;
427  case Board::PWM4:
428  case Board::PWM5:
429  case Board::PWM6:
430  Power::timer4_enable();
431  break;
432  case Board::PWM7:
433  case Board::PWM8:
434  Power::timer2_enable();
435  break;
436  case Board::PWM9:
437  case Board::PWM10:
439  break;
440  default:
441  ;
442  }
443 }
444 
445 uint8_t
446 PWMPin::duty()
447 {
448  switch (m_pin) {
449  case Board::PWM0: return (OCR3B);
450  case Board::PWM1: return (OCR3C);
451  case Board::PWM2: return (OCR0B);
452  case Board::PWM3: return (OCR3A);
453  case Board::PWM4: return (OCR4A);
454  case Board::PWM5: return (OCR4B);
455  case Board::PWM6: return (OCR4C);
456  case Board::PWM7: return (OCR2B);
457  case Board::PWM8: return (OCR2A);
458  case Board::PWM9: return (OCR1A);
459  case Board::PWM10: return (OCR1B);
460  case Board::PWM11: return (OCR0A);
461  default:
462  return (is_set());
463  }
464 }
465 
466 void
467 PWMPin::set(uint8_t duty)
468 {
469  switch (m_pin) {
470  case Board::PWM0:
471  bit_set(TCCR3A, COM3B1);
472  OCR3B = duty;
473  return;
474  case Board::PWM1:
475  bit_set(TCCR3A, COM3C1);
476  OCR3C = duty;
477  return;
478  case Board::PWM2:
479  bit_set(TCCR0A, COM0B1);
480  OCR0B = duty;
481  return;
482  case Board::PWM3:
483  bit_set(TCCR3A, COM3A1);
484  OCR3A = duty;
485  return;
486  case Board::PWM4:
487  bit_set(TCCR4A, COM4A1);
488  OCR4A = duty;
489  return;
490  case Board::PWM5:
491  bit_set(TCCR4A, COM4B1);
492  OCR4B = duty;
493  return;
494  case Board::PWM6:
495  bit_set(TCCR4A, COM4C1);
496  OCR4C = duty;
497  return;
498  case Board::PWM7:
499  bit_set(TCCR2A, COM2B1);
500  OCR2B = duty;
501  return;
502  case Board::PWM8:
503  bit_set(TCCR2A, COM2A1);
504  OCR2A = duty;
505  return;
506  case Board::PWM9:
507  bit_set(TCCR1A, COM1A1);
508  OCR1A = duty;
509  return;
510  case Board::PWM10:
511  bit_set(TCCR1A, COM1B1);
512  OCR1B = duty;
513  return;
514  case Board::PWM11:
515  bit_set(TCCR0A, COM0A1);
516  OCR0A = duty;
517  return;
518  default:
519  OutputPin::set(duty);
520  }
521 }
522 
523 #elif defined(BOARD_ATTINYX4)
524 
525 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
526  OutputPin((Board::DigitalPin) pin)
527 {
528  switch (pin) {
529  case Board::PWM0:
530  case Board::PWM1:
531  TCCR0A |= _BV(WGM01) | _BV(WGM00);
532  TCCR0B |= _BV(CS01) | _BV(CS00);
533  break;
534  case Board::PWM2:
535  case Board::PWM3:
536  TCCR1A |= _BV(WGM10);
537  TCCR1B |= _BV(CS11) | _BV(CS10);
538  break;
539  }
540  set(duty);
541 }
542 
543 void
545 {
546  switch (m_pin) {
547  case Board::PWM0:
548  case Board::PWM1:
550  break;
551  case Board::PWM2:
552  case Board::PWM3:
554  break;
555  default:
556  ;
557  }
558 }
559 
560 uint8_t
561 PWMPin::duty()
562 {
563  switch (m_pin) {
564  case Board::PWM0: return (OCR0A);
565  case Board::PWM1: return (OCR0B);
566  case Board::PWM2: return (OCR1A);
567  case Board::PWM3: return (OCR1B);
568  default:
569  return (is_set());
570  }
571 }
572 
573 void
574 PWMPin::set(uint8_t duty)
575 {
576  switch (m_pin) {
577  case Board::PWM0:
578  bit_set(TCCR0A, COM0A1);
579  OCR0A = duty;
580  return;
581  case Board::PWM1:
582  bit_set(TCCR0A, COM0B1);
583  OCR0B = duty;
584  return;
585  case Board::PWM2:
586  bit_set(TCCR1A, COM1A1);
587  OCR1A = duty;
588  return;
589  case Board::PWM3:
590  bit_set(TCCR1A, COM1B1);
591  OCR1B = duty;
592  return;
593  default:
594  OutputPin::set(duty);
595  }
596 }
597 
598 #elif defined(BOARD_ATTINYX5)
599 
600 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
601  OutputPin((Board::DigitalPin) pin)
602 {
603  TCCR0A |= _BV(WGM01) | _BV(WGM00);
604  TCCR0B |= _BV(CS01) | _BV(CS00);
605  set(duty);
606 }
607 
608 void
610 {
611  switch (m_pin) {
612  case Board::PWM0:
613  case Board::PWM1:
615  break;
616  default:
617  ;
618  }
619 }
620 
621 uint8_t
622 PWMPin::duty()
623 {
624  switch (m_pin) {
625  case Board::PWM0: return (OCR0A);
626  case Board::PWM1: return (OCR0B);
627  default:
628  return (is_set());
629  }
630 }
631 
632 void
633 PWMPin::set(uint8_t duty)
634 {
635  switch (m_pin) {
636  case Board::PWM0:
637  bit_set(TCCR0A, COM0A1);
638  OCR0A = duty;
639  return;
640  case Board::PWM1:
641  bit_set(TCCR0A, COM0B1);
642  OCR0B = duty;
643  return;
644  default:
645  OutputPin::set(duty);
646  }
647 }
648 
649 #elif defined(BOARD_ATTINYX61)
650 
651 PWMPin::PWMPin(Board::PWMPin pin, uint8_t duty) :
652  OutputPin((Board::DigitalPin) pin)
653 {
654  // Prescale(64)
655  TCCR1B |= _BV(CS12) | _BV(CS11) | _BV(CS10);
656 
657  // PWM mode
658  switch (m_pin) {
659  case Board::PWM0:
660  TCCR1A |= _BV(PWM1A);
661  break;
662  case Board::PWM1:
663  TCCR1A |= _BV(PWM1B);
664  break;
665  case Board::PWM2:
666  TCCR1C |= _BV(PWM1D);
667  break;
668  }
669  set(duty);
670 }
671 
672 void
674 {
675  switch (m_pin) {
676  case Board::PWM0:
677  case Board::PWM1:
678  case Board::PWM2:
680  break;
681  default:
682  ;
683  }
684 }
685 
686 uint8_t
687 PWMPin::duty()
688 {
689  switch (m_pin) {
690  case Board::PWM0: return (OCR1A);
691  case Board::PWM1: return (OCR1B);
692  case Board::PWM2: return (OCR1D);
693  default:
694  return (is_set());
695  }
696 }
697 
698 void
699 PWMPin::set(uint8_t duty)
700 {
701  switch (m_pin) {
702  case Board::PWM0:
703  bit_set(TCCR1C, COM1A1);
704  OCR1A = duty;
705  return;
706  case Board::PWM1:
707  bit_set(TCCR1C, COM1B1);
708  OCR1B = duty;
709  return;
710  case Board::PWM2:
711  bit_set(TCCR1C, COM1D1);
712  OCR1D = duty;
713  return;
714  default:
715  OutputPin::set(duty);
716  }
717 }
718 
719 #endif
720 
721 void
722 PWMPin::set(uint16_t value, uint16_t min, uint16_t max)
723 {
724  uint8_t duty;
725  if (UNLIKELY(value <= min)) duty = 0;
726  else if (UNLIKELY(value >= max)) duty = 255;
727  else duty = (((uint32_t) (value - min)) << 8) / (max - min);
728  set(duty);
729 }
730 
void begin()
#define bit_set(p, b)
Definition: Bits.h:35
void set() const
Definition: OutputPin.hh:85
#define bit_clear(p, b)
Definition: Bits.h:36
PWMPin(Board::PWMPin pin, uint8_t duty=0)
#define WGM01
Definition: ATtinyX61.hh:253
static void timer1_enable()
Definition: Power.hh:81
static void timer0_enable()
Definition: Power.hh:69
#define UNLIKELY(x)
Definition: Types.h:153
uint8_t duty()