atmega_hal/
simple_pwm.rs

1pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps};
2
3#[allow(unused_imports)]
4use crate::port::*;
5
6#[cfg(any(
7    feature = "atmega48p",
8    feature = "atmega88p",
9    feature = "atmega168",
10    feature = "atmega328p",
11    feature = "atmega328pb"
12))]
13avr_hal_generic::impl_simple_pwm! {
14    /// Use `TC0` for PWM (pins `PD5`, `PD6`)
15    ///
16    /// # Example
17    /// ```
18    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
19    ///
20    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer0);
21    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer0);
22    ///
23    /// d5.set_duty(128);
24    /// d5.enable();
25    /// ```
26    pub struct Timer0Pwm {
27        timer: crate::pac::TC0,
28        init: |tim, prescaler| {
29            tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast());
30            tim.tccr0b().modify(|_r, w| match prescaler {
31                Prescaler::Direct => w.cs0().direct(),
32                Prescaler::Prescale8 => w.cs0().prescale_8(),
33                Prescaler::Prescale64 => w.cs0().prescale_64(),
34                Prescaler::Prescale256 => w.cs0().prescale_256(),
35                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
36            });
37        },
38        pins: {
39            PD6: {
40                ocr: ocr0a,
41                into_pwm: |tim| if enable {
42                    tim.tccr0a().modify(|_r, w| w.com0a().match_clear());
43                } else {
44                    tim.tccr0a().modify(|_r, w| w.com0a().disconnected());
45                },
46            },
47
48            PD5: {
49                ocr: ocr0b,
50                into_pwm: |tim| if enable {
51                    tim.tccr0a().modify(|_r, w| w.com0b().match_clear());
52                } else {
53                    tim.tccr0a().modify(|_r, w| w.com0b().disconnected());
54                },
55            },
56        },
57    }
58}
59
60#[cfg(any(
61    feature = "atmega48p",
62    feature = "atmega88p",
63    feature = "atmega168",
64    feature = "atmega328p",
65    feature = "atmega328pb"
66))]
67avr_hal_generic::impl_simple_pwm! {
68    /// Use `TC1` for PWM (pins `PB1`, `PB2`)
69    ///
70    /// # Example
71    /// ```
72    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
73    ///
74    /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1);
75    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1);
76    ///
77    /// d9.set_duty(128);
78    /// d9.enable();
79    /// ```
80    pub struct Timer1Pwm {
81        timer: crate::pac::TC1,
82        init: |tim, prescaler| {
83            tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01));
84            tim.tccr1b().modify(|_r, w| {
85                w.wgm1().set(0b01);
86
87                match prescaler {
88                    Prescaler::Direct => w.cs1().direct(),
89                    Prescaler::Prescale8 => w.cs1().prescale_8(),
90                    Prescaler::Prescale64 => w.cs1().prescale_64(),
91                    Prescaler::Prescale256 => w.cs1().prescale_256(),
92                    Prescaler::Prescale1024 => w.cs1().prescale_1024(),
93                }
94            });
95        },
96        pins: {
97            PB1: {
98                ocr: ocr1a,
99                into_pwm: |tim| if enable {
100                    tim.tccr1a().modify(|_r, w| w.com1a().match_clear());
101                } else {
102                    tim.tccr1a().modify(|_r, w| w.com1a().disconnected());
103                },
104            },
105
106            PB2: {
107                ocr: ocr1b,
108                into_pwm: |tim| if enable {
109                    tim.tccr1a().modify(|_r, w| w.com1b().match_clear());
110                } else {
111                    tim.tccr1a().modify(|_r, w| w.com1b().disconnected());
112                },
113            },
114        },
115    }
116}
117
118#[cfg(any(
119    feature = "atmega48p",
120    feature = "atmega88p",
121    feature = "atmega168",
122    feature = "atmega328p",
123    feature = "atmega328pb"
124))]
125avr_hal_generic::impl_simple_pwm! {
126    /// Use `TC2` for PWM (pins `PB3`, `PD3`)
127    ///
128    /// # Example
129    /// ```
130    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
131    ///
132    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2);
133    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2);
134    ///
135    /// d11.set_duty(128);
136    /// d11.enable();
137    /// ```
138    pub struct Timer2Pwm {
139        timer: crate::pac::TC2,
140        init: |tim, prescaler| {
141            tim.tccr2a().modify(|_r, w| w.wgm2().pwm_fast());
142            tim.tccr2b().modify(|_r, w| match prescaler {
143                    Prescaler::Direct => w.cs2().direct(),
144                    Prescaler::Prescale8 => w.cs2().prescale_8(),
145                    Prescaler::Prescale64 => w.cs2().prescale_64(),
146                    Prescaler::Prescale256 => w.cs2().prescale_256(),
147                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
148            });
149        },
150        pins: {
151            PB3: {
152                ocr: ocr2a,
153                into_pwm: |tim| if enable {
154                    tim.tccr2a().modify(|_r, w| w.com2a().match_clear());
155                } else {
156                    tim.tccr2a().modify(|_r, w| w.com2a().disconnected());
157                },
158            },
159
160            PD3: {
161                ocr: ocr2b,
162                into_pwm: |tim| if enable {
163                    tim.tccr2a().modify(|_r, w| w.com2b().match_clear());
164                } else {
165                    tim.tccr2a().modify(|_r, w| w.com2b().disconnected());
166                },
167            },
168        },
169    }
170}
171
172#[cfg(feature = "atmega328pb")]
173avr_hal_generic::impl_simple_pwm! {
174    /// Use `TC3` for PWM (pins `PD0`, `PD2`)
175    pub struct Timer3Pwm {
176        timer: crate::pac::TC3,
177        init: |tim, prescaler| {
178            tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01));
179            tim.tccr3b().modify(|_r, w| {
180                unsafe { w.wgm3().bits(0b01) };
181
182                match prescaler {
183                    Prescaler::Direct => w.cs3().direct(),
184                    Prescaler::Prescale8 => w.cs3().prescale_8(),
185                    Prescaler::Prescale64 => w.cs3().prescale_64(),
186                    Prescaler::Prescale256 => w.cs3().prescale_256(),
187                    Prescaler::Prescale1024 => w.cs3().prescale_1024(),
188                }
189            });
190        },
191        pins: {
192            PD0: {
193                ocr: ocr3a,
194                into_pwm: |tim| if enable {
195                    tim.tccr3a().modify(|_r, w| w.com3a().match_clear());
196                } else {
197                    tim.tccr3a().modify(|_r, w| w.com3a().disconnected());
198                },
199            },
200
201            PD2: {
202                ocr: ocr3b,
203                into_pwm: |tim| if enable {
204                    tim.tccr3a().modify(|_r, w| w.com3b().match_clear());
205                } else {
206                    tim.tccr3a().modify(|_r, w| w.com3b().disconnected());
207                },
208            },
209        },
210    }
211}
212
213#[cfg(feature = "atmega328pb")]
214avr_hal_generic::impl_simple_pwm! {
215    /// Use `TC4` for PWM (pins `PD1`, `PD2`)
216    pub struct Timer4Pwm {
217        timer: crate::pac::TC4,
218        init: |tim, prescaler| {
219            tim.tccr4a().modify(|_r, w| w.wgm4().set(0b01));
220            tim.tccr4b().modify(|_r, w| {
221                unsafe { w.wgm4().bits(0b01) };
222
223                match prescaler {
224                    Prescaler::Direct => w.cs4().direct(),
225                    Prescaler::Prescale8 => w.cs4().prescale_8(),
226                    Prescaler::Prescale64 => w.cs4().prescale_64(),
227                    Prescaler::Prescale256 => w.cs4().prescale_256(),
228                    Prescaler::Prescale1024 => w.cs4().prescale_1024(),
229                }
230            });
231        },
232        pins: {
233            PD1: {
234                ocr: ocr4a,
235                into_pwm: |tim| if enable {
236                    tim.tccr4a().modify(|_r, w| w.com4a().match_clear());
237                } else {
238                    tim.tccr4a().modify(|_r, w| w.com4a().disconnected());
239                },
240            },
241
242            PD2: {
243                ocr: ocr4b,
244                into_pwm: |tim| if enable {
245                    tim.tccr4a().modify(|_r, w| w.com4b().match_clear());
246                } else {
247                    tim.tccr4a().modify(|_r, w| w.com4b().disconnected());
248                },
249            },
250        },
251    }
252}
253
254#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
255avr_hal_generic::impl_simple_pwm! {
256    /// Use `TC0` for PWM (pins `PB7`, `PG5`)
257    ///
258    /// # Example
259    /// ```
260    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
261    ///
262    /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer0);
263    /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer0);
264    ///
265    /// d13.set_duty(128);
266    /// d13.enable();
267    /// ```
268    pub struct Timer0Pwm {
269        timer: crate::pac::TC0,
270        init: |tim, prescaler| {
271            tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast());
272            tim.tccr0b().modify(|_r, w| match prescaler {
273                Prescaler::Direct => w.cs0().direct(),
274                Prescaler::Prescale8 => w.cs0().prescale_8(),
275                Prescaler::Prescale64 => w.cs0().prescale_64(),
276                Prescaler::Prescale256 => w.cs0().prescale_256(),
277                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
278            });
279        },
280        pins: {
281            PB7: {
282                ocr: ocr0a,
283                into_pwm: |tim| if enable {
284                    tim.tccr0a().modify(|_r, w| w.com0a().match_clear());
285                } else {
286                    tim.tccr0a().modify(|_r, w| w.com0a().disconnected());
287                },
288            },
289
290            PG5: {
291                ocr: ocr0b,
292                into_pwm: |tim| if enable {
293                    tim.tccr0a().modify(|_r, w| w.com0b().match_clear());
294                } else {
295                    tim.tccr0a().modify(|_r, w| w.com0b().disconnected());
296                },
297            },
298        },
299    }
300}
301
302#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
303avr_hal_generic::impl_simple_pwm! {
304    /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`)
305    ///
306    /// # Example
307    /// ```
308    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
309    ///
310    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1);
311    /// let mut d12 = pins.d12.into_output().into_pwm(&mut timer1);
312    /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer1);
313    ///
314    /// d11.set_duty(128);
315    /// d11.enable();
316    /// ```
317    pub struct Timer1Pwm {
318        timer: crate::pac::TC1,
319        init: |tim, prescaler| {
320            tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01));
321            tim.tccr1b().modify(|_r, w| {
322                w.wgm1().set(0b01);
323
324                match prescaler {
325                    Prescaler::Direct => w.cs1().direct(),
326                    Prescaler::Prescale8 => w.cs1().prescale_8(),
327                    Prescaler::Prescale64 => w.cs1().prescale_64(),
328                    Prescaler::Prescale256 => w.cs1().prescale_256(),
329                    Prescaler::Prescale1024 => w.cs1().prescale_1024(),
330                }
331            });
332        },
333        pins: {
334            PB5: {
335                ocr: ocr1a,
336                into_pwm: |tim| if enable {
337                    tim.tccr1a().modify(|_r, w| w.com1a().match_clear());
338                } else {
339                    tim.tccr1a().modify(|_r, w| w.com1a().disconnected());
340                },
341            },
342
343            PB6: {
344                ocr: ocr1b,
345                into_pwm: |tim| if enable {
346                    tim.tccr1a().modify(|_r, w| w.com1b().match_clear());
347                } else {
348                    tim.tccr1a().modify(|_r, w| w.com1b().disconnected());
349                },
350            },
351
352            PB7: {
353                ocr: ocr1c,
354                into_pwm: |tim| if enable {
355                    tim.tccr1a().modify(|_r, w| w.com1c().match_clear());
356                } else {
357                    tim.tccr1a().modify(|_r, w| w.com1c().disconnected());
358                },
359            },
360        },
361    }
362}
363
364#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
365avr_hal_generic::impl_simple_pwm! {
366    /// Use `TC2` for PWM (pins `PB4`, `PH6`)
367    ///
368    /// # Example
369    /// ```
370    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
371    ///
372    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer2);
373    /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer2);
374    ///
375    /// d10.set_duty(128);
376    /// d10.enable();
377    /// ```
378
379    pub struct Timer2Pwm {
380        timer: crate::pac::TC2,
381        init: |tim, prescaler| {
382            tim.tccr2a().modify(|_r, w| w.wgm2().set(0b01));
383            tim.tccr2b().modify(|_r, w| {
384                w.wgm22().clear_bit();
385
386                match prescaler {
387                    Prescaler::Direct => w.cs2().direct(),
388                    Prescaler::Prescale8 => w.cs2().prescale_8(),
389                    Prescaler::Prescale64 => w.cs2().prescale_64(),
390                    Prescaler::Prescale256 => w.cs2().prescale_256(),
391                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
392                }
393            });
394        },
395        pins: {
396            PB4: {
397                ocr: ocr2a,
398                into_pwm: |tim| if enable {
399                    tim.tccr2a().modify(|_r, w| w.com2a().match_clear());
400                } else {
401                    tim.tccr2a().modify(|_r, w| w.com2a().disconnected());
402                },
403            },
404
405            PH6: {
406                ocr: ocr2b,
407                into_pwm: |tim| if enable {
408                    tim.tccr2a().modify(|_r, w| w.com2b().match_clear());
409                } else {
410                    tim.tccr2a().modify(|_r, w| w.com2b().disconnected());
411                },
412            },
413        },
414    }
415}
416
417#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
418avr_hal_generic::impl_simple_pwm! {
419    /// Use `TC3` for PWM (pins `PE3`, `PE4`, `PE5`)
420    ///
421    /// # Example
422    /// ```
423    /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64);
424    ///
425    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3);
426    /// let mut d2 = pins.d2.into_output().into_pwm(&mut timer3);
427    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer3);
428    ///
429    /// d5.set_duty(128);
430    /// d5.enable();
431    /// ```
432    pub struct Timer3Pwm {
433        timer: crate::pac::TC3,
434        init: |tim, prescaler| {
435            tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01));
436            tim.tccr3b().modify(|_r, w| {
437                w.wgm3().set(0b01);
438
439                match prescaler {
440                    Prescaler::Direct => w.cs3().direct(),
441                    Prescaler::Prescale8 => w.cs3().prescale_8(),
442                    Prescaler::Prescale64 => w.cs3().prescale_64(),
443                    Prescaler::Prescale256 => w.cs3().prescale_256(),
444                    Prescaler::Prescale1024 => w.cs3().prescale_1024(),
445                }
446            });
447        },
448        pins: {
449            PE3: {
450                ocr: ocr3a,
451                into_pwm: |tim| if enable {
452                    tim.tccr3a().modify(|_r, w| w.com3a().match_clear());
453                } else {
454                    tim.tccr3a().modify(|_r, w| w.com3a().disconnected());
455                },
456            },
457
458            PE4: {
459                ocr: ocr3b,
460                into_pwm: |tim| if enable {
461                    tim.tccr3a().modify(|_r, w| w.com3b().match_clear());
462                } else {
463                    tim.tccr3a().modify(|_r, w| w.com3b().disconnected());
464                },
465            },
466
467            PE5: {
468                ocr: ocr3c,
469                into_pwm: |tim| if enable {
470                    tim.tccr3a().modify(|_r, w| w.com3c().match_clear());
471                } else {
472                    tim.tccr3a().modify(|_r, w| w.com3c().disconnected());
473                },
474            },
475
476        },
477    }
478}
479
480#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
481avr_hal_generic::impl_simple_pwm! {
482    /// Use `TC4` for PWM (pins `PH3`, `PH4`, `PH5`)
483    ///
484    /// # Example
485    /// ```
486    /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64);
487    ///
488    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4);
489    /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer4);
490    /// let mut d8 = pins.d8.into_output().into_pwm(&mut timer4);
491    ///
492    /// d6.set_duty(128);
493    /// d6.enable();
494    /// ```
495    pub struct Timer4Pwm {
496        timer: crate::pac::TC4,
497        init: |tim, prescaler| {
498            tim.tccr4a().modify(|_r, w| w.wgm4().set(0b01));
499            tim.tccr4b().modify(|_r, w| {
500                w.wgm4().set(0b01);
501
502                match prescaler {
503                    Prescaler::Direct => w.cs4().direct(),
504                    Prescaler::Prescale8 => w.cs4().prescale_8(),
505                    Prescaler::Prescale64 => w.cs4().prescale_64(),
506                    Prescaler::Prescale256 => w.cs4().prescale_256(),
507                    Prescaler::Prescale1024 => w.cs4().prescale_1024(),
508                }
509            });
510        },
511        pins: {
512            PH3: {
513                ocr: ocr4a,
514                into_pwm: |tim| if enable {
515                    tim.tccr4a().modify(|_r, w| w.com4a().match_clear());
516                } else {
517                    tim.tccr4a().modify(|_r, w| w.com4a().disconnected());
518                },
519            },
520
521            PH4: {
522                ocr: ocr4b,
523                into_pwm: |tim| if enable {
524                    tim.tccr4a().modify(|_r, w| w.com4b().match_clear());
525                } else {
526                    tim.tccr4a().modify(|_r, w| w.com4b().disconnected());
527                },
528            },
529
530            PH5: {
531                ocr: ocr4c,
532                into_pwm: |tim| if enable {
533                    tim.tccr4a().modify(|_r, w| w.com4c().match_clear());
534                } else {
535                    tim.tccr4a().modify(|_r, w| w.com4c().disconnected());
536                },
537            },
538
539        },
540    }
541}
542
543#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
544avr_hal_generic::impl_simple_pwm! {
545    /// Use `TC5` for PWM (pins `PL3`, `PL4`, `PL5`)
546    ///
547    /// # Example
548    /// ```
549    /// let mut timer5 = Timer5Pwm::new(dp.TC5, Prescaler::Prescale64);
550    ///
551    /// let mut d46 = pins.d46.into_output().into_pwm(&mut timer5);
552    /// let mut d45 = pins.d45.into_output().into_pwm(&mut timer5);
553    /// let mut d44 = pins.d44.into_output().into_pwm(&mut timer5);
554    ///
555    /// d46.set_duty(128);
556    /// d46.enable();
557    /// ```
558    pub struct Timer5Pwm {
559        timer: crate::pac::TC5,
560        init: |tim, prescaler| {
561            tim.tccr5a().modify(|_r, w| w.wgm5().set(0b01));
562            tim.tccr5b().modify(|_r, w| {
563                w.wgm5().set(0b01);
564
565                match prescaler {
566                    Prescaler::Direct => w.cs5().direct(),
567                    Prescaler::Prescale8 => w.cs5().prescale_8(),
568                    Prescaler::Prescale64 => w.cs5().prescale_64(),
569                    Prescaler::Prescale256 => w.cs5().prescale_256(),
570                    Prescaler::Prescale1024 => w.cs5().prescale_1024(),
571                }
572            });
573        },
574        pins: {
575            PL3: {
576                ocr: ocr5a,
577                into_pwm: |tim| if enable {
578                    tim.tccr5a().modify(|_r, w| w.com5a().match_clear());
579                } else {
580                    tim.tccr5a().modify(|_r, w| w.com5a().disconnected());
581                },
582            },
583
584            PL4: {
585                ocr: ocr5b,
586                into_pwm: |tim| if enable {
587                    tim.tccr5a().modify(|_r, w| w.com5b().match_clear());
588                } else {
589                    tim.tccr5a().modify(|_r, w| w.com5b().disconnected());
590                },
591            },
592
593            PL5: {
594                ocr: ocr5c,
595                into_pwm: |tim| if enable {
596                    tim.tccr5a().modify(|_r, w| w.com5c().match_clear());
597                } else {
598                    tim.tccr5a().modify(|_r, w| w.com5c().disconnected());
599                },
600            },
601
602        },
603    }
604}
605
606#[cfg(any(feature = "atmega32u4"))]
607avr_hal_generic::impl_simple_pwm! {
608    /// Use `TC0` for PWM (pins `PB7`, `PD0`)
609    ///
610    /// # Example
611    /// ```
612    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
613    ///
614    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer0);
615    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer0);
616    ///
617    /// d11.set_duty(128);
618    /// d11.enable();
619    /// ```
620    pub struct Timer0Pwm {
621        timer: crate::pac::TC0,
622        init: |tim, prescaler| {
623            tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast());
624            tim.tccr0b().modify(|_r, w| match prescaler {
625                Prescaler::Direct => w.cs0().direct(),
626                Prescaler::Prescale8 => w.cs0().prescale_8(),
627                Prescaler::Prescale64 => w.cs0().prescale_64(),
628                Prescaler::Prescale256 => w.cs0().prescale_256(),
629                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
630            });
631        },
632        pins: {
633            PB7: {
634                ocr: ocr0a,
635                into_pwm: |tim| if enable {
636                    tim.tccr0a().modify(|_r, w| w.com0a().match_clear());
637                } else {
638                    tim.tccr0a().modify(|_r, w| w.com0a().disconnected());
639                },
640            },
641
642            PD0: {
643                ocr: ocr0b,
644                into_pwm: |tim| if enable {
645                    tim.tccr0a().modify(|_r, w| w.com0b().match_clear());
646                } else {
647                    tim.tccr0a().modify(|_r, w| w.com0b().disconnected());
648                },
649            },
650        },
651    }
652}
653
654#[cfg(any(feature = "atmega32u4"))]
655avr_hal_generic::impl_simple_pwm! {
656    /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`)
657    ///
658    /// # Example
659    /// ```
660    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
661    ///
662    /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1);
663    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1);
664    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1);
665    ///
666    /// d9.set_duty(128);
667    /// d9.enable();
668    /// ```
669    pub struct Timer1Pwm {
670        timer: crate::pac::TC1,
671        init: |tim, prescaler| {
672            tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01));
673            tim.tccr1b().modify(|_r, w| w.wgm1().set(0b01));
674
675            tim.tccr1b().modify(|_r, w| match prescaler {
676                Prescaler::Direct => w.cs1().direct(),
677                Prescaler::Prescale8 => w.cs1().prescale_8(),
678                Prescaler::Prescale64 => w.cs1().prescale_64(),
679                Prescaler::Prescale256 => w.cs1().prescale_256(),
680                Prescaler::Prescale1024 => w.cs1().prescale_1024(),
681            });
682        },
683        pins: {
684            PB5: {
685                ocr: ocr1a,
686                into_pwm: |tim| if enable {
687                    tim.tccr1a().modify(|_r, w| w.com1a().match_clear());
688                } else {
689                    tim.tccr1a().modify(|_r, w| w.com1a().disconnected());
690                },
691            },
692
693            PB6: {
694                ocr: ocr1b,
695                into_pwm: |tim| if enable {
696                    tim.tccr1a().modify(|_r, w| w.com1b().match_clear());
697                } else {
698                    tim.tccr1a().modify(|_r, w| w.com1b().disconnected());
699                },
700            },
701
702            PB7: {
703                ocr: ocr1c,
704                into_pwm: |tim| if enable {
705                    tim.tccr1a().modify(|_r, w| w.com1c().match_clear());
706                } else {
707                    tim.tccr1a().modify(|_r, w| w.com1c().disconnected());
708                },
709            },
710        },
711    }
712}
713
714#[cfg(any(feature = "atmega32u4"))]
715avr_hal_generic::impl_simple_pwm! {
716    /// Use `TC3` for PWM (pins `PC6`)
717    ///
718    /// # Example
719    /// ```
720    /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64);
721    ///
722    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3);
723    ///
724    /// d5.set_duty(128);
725    /// d5.enable();
726    /// ```
727    pub struct Timer3Pwm {
728        timer: crate::pac::TC3,
729        init: |tim, prescaler| {
730            tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01));
731            tim.tccr3b().modify(|_r, w| w.wgm3().set(0b01));
732
733            tim.tccr3b().modify(|_r, w| match prescaler {
734                Prescaler::Direct => w.cs3().direct(),
735                Prescaler::Prescale8 => w.cs3().prescale_8(),
736                Prescaler::Prescale64 => w.cs3().prescale_64(),
737                Prescaler::Prescale256 => w.cs3().prescale_256(),
738                Prescaler::Prescale1024 => w.cs3().prescale_1024(),
739            });
740        },
741        pins: {
742            PC6: {
743                ocr: ocr3a,
744                into_pwm: |tim| if enable {
745                    tim.tccr3a().modify(|_r, w| w.com3a().match_clear());
746                } else {
747                    tim.tccr3a().modify(|_r, w| w.com3a().disconnected());
748                },
749            },
750        },
751    }
752}
753
754#[cfg(any(feature = "atmega32u4"))]
755avr_hal_generic::impl_simple_pwm! {
756    /// Use `TC4` for PWM (pins `PB6`, `PC7`, `PD7`)
757    ///
758    /// # Example
759    /// ```
760    /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64);
761    ///
762    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4);
763    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer4);
764    /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer4);
765    ///
766    /// d6.set_duty(128);
767    /// d6.enable();
768    /// ```
769    pub struct Timer4Pwm {
770        timer: crate::pac::TC4,
771        init: |tim, prescaler| {
772            tim.tccr4a().modify(|_r, w| w.pwm4a().set_bit());
773            tim.tccr4a().modify(|_r, w| w.pwm4b().set_bit());
774            tim.tccr4c().modify(|_r, w| w.pwm4d().set_bit());
775
776            tim.tccr4b().modify(|_r, w| match prescaler {
777                Prescaler::Direct => w.cs4().direct(),
778                Prescaler::Prescale8 => w.cs4().prescale_8(),
779                Prescaler::Prescale64 => w.cs4().prescale_64(),
780                Prescaler::Prescale256 => w.cs4().prescale_256(),
781                Prescaler::Prescale1024 => w.cs4().prescale_1024(),
782            });
783        },
784        pins: {
785            PB6: {
786                ocr: ocr4b,
787                into_pwm: |tim| if enable {
788                    tim.tccr4a().modify(|_r, w| w.com4b().match_clear());
789                } else {
790                    tim.tccr4a().modify(|_r, w| w.com4b().disconnected());
791                },
792            },
793
794            PC7: {
795                ocr: ocr4a,
796                into_pwm: |tim| if enable {
797                    tim.tccr4a().modify(|_r, w| w.com4a().match_clear());
798                } else {
799                    tim.tccr4a().modify(|_r, w| w.com4a().disconnected());
800                },
801            },
802
803            PD7: {
804                ocr: ocr4d,
805                into_pwm: |tim| if enable {
806                    tim.tccr4c().modify(|_r, w| w.com4d().match_clear());
807                } else {
808                    tim.tccr4c().modify(|_r, w| w.com4d().disconnected());
809                },
810            },
811        },
812    }
813}
814
815#[cfg(any(feature = "atmega1284p"))]
816avr_hal_generic::impl_simple_pwm! {
817    /// Use `TC0` for PWM (pins `PB3`, `PB4`)
818    ///
819    /// # Example
820    /// ```
821    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
822    ///
823    /// let mut b3 = pins.b3.into_output().into_pwm(&mut timer0);
824    /// let mut b4 = pins.b4.into_output().into_pwm(&mut timer0);
825    ///
826    /// b3.set_duty(128);
827    /// b4.enable();
828    /// ```
829    pub struct Timer0Pwm {
830        timer: crate::pac::TC0,
831        init: |tim, prescaler| {
832            tim.tccr0a().modify(|_r, w| w.wgm0().pwm_fast());
833            tim.tccr0b().modify(|_r, w| match prescaler {
834                Prescaler::Direct => w.cs0().direct(),
835                Prescaler::Prescale8 => w.cs0().prescale_8(),
836                Prescaler::Prescale64 => w.cs0().prescale_64(),
837                Prescaler::Prescale256 => w.cs0().prescale_256(),
838                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
839            });
840        },
841        pins: {
842            PB3: {
843                ocr: ocr0a,
844                into_pwm: |tim| if enable {
845                    tim.tccr0a().modify(|_r, w| w.com0a().match_clear());
846                } else {
847                    tim.tccr0a().modify(|_r, w| w.com0a().disconnected());
848                },
849            },
850
851            PB4: {
852                ocr: ocr0b,
853                into_pwm: |tim| if enable {
854                    tim.tccr0a().modify(|_r, w| w.com0b().match_clear());
855                } else {
856                    tim.tccr0a().modify(|_r, w| w.com0b().disconnected());
857                },
858            },
859        },
860    }
861}
862
863#[cfg(any(feature = "atmega1284p"))]
864avr_hal_generic::impl_simple_pwm! {
865    /// Use `TC1` for PWM (pins `PD5`, `PD4`)
866    ///
867    /// # Example
868    /// ```
869    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
870    ///
871    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer1);
872    /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1);
873    ///
874    /// d5.set_duty(128);
875    /// d5.enable();
876    /// ```
877    pub struct Timer1Pwm {
878        timer: crate::pac::TC1,
879        init: |tim, prescaler| {
880            tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01));
881            tim.tccr1b().modify(|_r, w| {
882                w.wgm1().set(0b01);
883
884                match prescaler {
885                    Prescaler::Direct => w.cs1().direct(),
886                    Prescaler::Prescale8 => w.cs1().prescale_8(),
887                    Prescaler::Prescale64 => w.cs1().prescale_64(),
888                    Prescaler::Prescale256 => w.cs1().prescale_256(),
889                    Prescaler::Prescale1024 => w.cs1().prescale_1024(),
890                }
891            });
892        },
893        pins: {
894            PD5: {
895                ocr: ocr1a,
896                into_pwm: |tim| if enable {
897                    tim.tccr1a().modify(|_r, w| w.com1a().match_clear());
898                } else {
899                    tim.tccr1a().modify(|_r, w| w.com1a().disconnected());
900                },
901            },
902
903            PD4: {
904                ocr: ocr1b,
905                into_pwm: |tim| if enable {
906                    tim.tccr1a().modify(|_r, w| w.com1b().match_clear());
907                } else {
908                    tim.tccr1a().modify(|_r, w| w.com1b().disconnected());
909                },
910            },
911        },
912    }
913}
914
915#[cfg(any(feature = "atmega1284p"))]
916avr_hal_generic::impl_simple_pwm! {
917    /// Use `TC2` for PWM (pins `PD7`, `PD6`)
918    ///
919    /// # Example
920    /// ```
921    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
922    ///
923    /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer2);
924    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer2);
925    ///
926    /// d7.set_duty(128);
927    /// d7.enable();
928    /// ```
929    pub struct Timer2Pwm {
930        timer: crate::pac::TC2,
931        init: |tim, prescaler| {
932            tim.tccr2a().modify(|_r, w| w.wgm2().pwm_fast());
933            tim.tccr2b().modify(|_r, w| match prescaler {
934                    Prescaler::Direct => w.cs2().direct(),
935                    Prescaler::Prescale8 => w.cs2().prescale_8(),
936                    Prescaler::Prescale64 => w.cs2().prescale_64(),
937                    Prescaler::Prescale256 => w.cs2().prescale_256(),
938                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
939            });
940        },
941        pins: {
942            PD7: {
943                ocr: ocr2a,
944                into_pwm: |tim| if enable {
945                    tim.tccr2a().modify(|_r, w| w.com2a().match_clear());
946                } else {
947                    tim.tccr2a().modify(|_r, w| w.com2a().disconnected());
948                },
949            },
950
951            PD6: {
952                ocr: ocr2b,
953                into_pwm: |tim| if enable {
954                    tim.tccr2a().modify(|_r, w| w.com2b().match_clear());
955                } else {
956                    tim.tccr2a().modify(|_r, w| w.com2b().disconnected());
957                },
958            },
959        },
960    }
961}
962
963#[cfg(any(feature = "atmega1284p"))]
964avr_hal_generic::impl_simple_pwm! {
965    /// Use `TC3` for PWM (pins `PB6`, `PB7`)
966    pub struct Timer3Pwm {
967        timer: crate::pac::TC3,
968        init: |tim, prescaler| {
969            tim.tccr3a().modify(|_r, w| w.wgm3().set(0b01));
970            tim.tccr3b().modify(|_r, w| {
971                w.wgm3().set(0b01);
972
973                match prescaler {
974                    Prescaler::Direct => w.cs3().direct(),
975                    Prescaler::Prescale8 => w.cs3().prescale_8(),
976                    Prescaler::Prescale64 => w.cs3().prescale_64(),
977                    Prescaler::Prescale256 => w.cs3().prescale_256(),
978                    Prescaler::Prescale1024 => w.cs3().prescale_1024(),
979                }
980            });
981        },
982        pins: {
983            PB6: {
984                ocr: ocr3a,
985                into_pwm: |tim| if enable {
986                    tim.tccr3a().modify(|_r, w| w.com3a().match_clear());
987                } else {
988                    tim.tccr3a().modify(|_r, w| w.com3a().disconnected());
989                },
990            },
991
992            PB7: {
993                ocr: ocr3b,
994                into_pwm: |tim| if enable {
995                    tim.tccr3a().modify(|_r, w| w.com3b().match_clear());
996                } else {
997                    tim.tccr3a().modify(|_r, w| w.com3b().disconnected());
998                },
999            },
1000        },
1001    }
1002}
1003
1004#[cfg(any(feature = "atmega8",))]
1005avr_hal_generic::impl_simple_pwm! {
1006    /// Use `TC1` for PWM (pins `PB1`, `PB2`)
1007    ///
1008    /// # Example
1009    /// ```
1010    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
1011    ///
1012    /// let mut b1 = pins.b1.into_output().into_pwm(&mut timer1);
1013    /// let mut b2 = pins.b2.into_output().into_pwm(&mut timer1);
1014    ///
1015    /// d9.set_duty(128);
1016    /// d9.enable();
1017    /// ```
1018    pub struct Timer1Pwm {
1019        timer: crate::pac::TC1,
1020        init: |tim, prescaler| {
1021            tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01));
1022            tim.tccr1b().modify(|_r, w| {
1023                w.wgm1().set(0b01);
1024
1025                match prescaler {
1026                    Prescaler::Direct => w.cs1().direct(),
1027                    Prescaler::Prescale8 => w.cs1().prescale_8(),
1028                    Prescaler::Prescale64 => w.cs1().prescale_64(),
1029                    Prescaler::Prescale256 => w.cs1().prescale_256(),
1030                    Prescaler::Prescale1024 => w.cs1().prescale_1024(),
1031                }
1032            });
1033        },
1034        pins: {
1035            PB1: {
1036                ocr: ocr1a,
1037                into_pwm: |tim| if enable {
1038                    tim.tccr1a().modify(|_r, w| w.com1a().match_clear());
1039                } else {
1040                    tim.tccr1a().modify(|_r, w| w.com1a().disconnected());
1041                },
1042            },
1043
1044            PB2: {
1045                ocr: ocr1b,
1046                into_pwm: |tim| if enable {
1047                    tim.tccr1a().modify(|_r, w| w.com1b().match_clear());
1048                } else {
1049                    tim.tccr1a().modify(|_r, w| w.com1b().disconnected());
1050                },
1051            },
1052        },
1053    }
1054}
1055
1056#[cfg(any(feature = "atmega8",))]
1057avr_hal_generic::impl_simple_pwm! {
1058    /// Use `TC2` for PWM (pins `PB3`, `PD3`)
1059    ///
1060    /// # Example
1061    /// ```
1062    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
1063    ///
1064    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2);
1065    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2);
1066    ///
1067    /// d11.set_duty(128);
1068    /// d11.enable();
1069    /// ```
1070    pub struct Timer2Pwm {
1071        timer: crate::pac::TC2,
1072        init: |tim, prescaler| {
1073            tim.tccr2().modify(|_r, w| w.wgm20().set_bit().wgm21().set_bit());
1074            tim.tccr2().modify(|_r, w| match prescaler {
1075                    Prescaler::Direct => w.cs2().direct(),
1076                    Prescaler::Prescale8 => w.cs2().prescale_8(),
1077                    Prescaler::Prescale64 => w.cs2().prescale_64(),
1078                    Prescaler::Prescale256 => w.cs2().prescale_256(),
1079                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
1080            });
1081        },
1082        pins: {
1083            PB3: {
1084                ocr: ocr2,
1085                into_pwm: |tim| if enable {
1086                    tim.tccr2().modify(|_r, w| w.com2().match_clear());
1087                } else {
1088                    tim.tccr2().modify(|_r, w| w.com2().disconnected());
1089                },
1090            },
1091        },
1092    }
1093}
1094
1095#[cfg(any(feature = "atmega164pa"))]
1096avr_hal_generic::impl_simple_pwm! {
1097    /// Use `TC0` for PWM (pins `PB3`)
1098    ///
1099    /// # Example
1100    /// ```
1101    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
1102    ///
1103    /// let mut b3 = pins.pb3.into_output().into_pwm(&mut timer0);
1104    ///
1105    /// b3.set_duty(128);
1106    /// b3.enable();
1107    /// ```
1108    pub struct Timer0Pwm {
1109        timer: crate::pac::TC0,
1110        init: |tim, prescaler| {
1111            tim.tccr0a().modify(|_r, w| w.wgm0().set(0b11));
1112            tim.tccr0a().modify(|_r, w| w.com0a().set(0b00));
1113
1114            tim.tccr0b().modify(|_r, w| match prescaler {
1115                Prescaler::Direct => w.cs0().running_no_prescaling(),
1116                Prescaler::Prescale8 => w.cs0().running_clk_8(),
1117                Prescaler::Prescale64 => w.cs0().running_clk_64(),
1118                Prescaler::Prescale256 => w.cs0().running_clk_256(),
1119                Prescaler::Prescale1024 => w.cs0().running_clk_1024(),
1120            });
1121        },
1122        pins: {
1123            PB3: {
1124                ocr: ocr0a,
1125                into_pwm: |tim| if enable {
1126                    tim.tccr0a().modify(|_r, w| w.com0a().set(0b11));
1127                } else {
1128                    tim.tccr0a().modify(|_r, w| w.com0a().set(0b00));
1129                },
1130            },
1131        },
1132    }
1133}
1134
1135#[cfg(any(feature = "atmega16", feature = "atmega164pa"))]
1136avr_hal_generic::impl_simple_pwm! {
1137    /// Use `TC1` for PWM (pins `PD4`, `PD5`)
1138    ///
1139    /// # Example
1140    /// ```
1141    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
1142    ///
1143    /// let mut d4 = pins.pd4.into_output().into_pwm(&mut timer1);
1144    /// let mut d5 = pins.pd5.into_output().into_pwm(&mut timer1);
1145    ///
1146    /// d4.set_duty(128);
1147    /// d4.enable();
1148    /// d5.set_duty(64);
1149    /// d5.enable();
1150    /// ```
1151    pub struct Timer1Pwm {
1152        timer: crate::pac::TC1,
1153        init: |tim, prescaler| {
1154            tim.tccr1a().modify(|_r, w| w.wgm1().set(0b01));
1155            tim.tccr1a().modify(|_r, w| w.com1a().set(0b00));
1156            tim.tccr1a().modify(|_r, w| w.com1b().set(0b00));
1157            #[cfg(any(feature = "atmega164pa"))]
1158            tim.tccr1b().modify(|_r, w| match prescaler {
1159                Prescaler::Direct => w.cs1().running_no_prescaling(),
1160                Prescaler::Prescale8 => w.cs1().running_clk_8(),
1161                Prescaler::Prescale64 => w.cs1().running_clk_64(),
1162                Prescaler::Prescale256 => w.cs1().running_clk_256(),
1163                Prescaler::Prescale1024 => w.cs1().running_clk_1024(),
1164            });
1165            #[cfg(any(feature = "atmega16"))]
1166            tim.tccr1b.modify(|_r, w| match prescaler {
1167                Prescaler::Direct => w.cs1().val_0x01(),
1168                Prescaler::Prescale8 => w.cs1().val_0x02(),
1169                Prescaler::Prescale64 => w.cs1().val_0x03(),
1170                Prescaler::Prescale256 => w.cs1().val_0x04(),
1171                Prescaler::Prescale1024 => w.cs1().val_0x05(),
1172            });
1173        },
1174        pins: {
1175            PD4: {
1176                ocr: ocr1a,
1177                into_pwm: |tim| if enable {
1178                    tim.tccr1a().modify(|_r, w| w.com1a().set(0b11));
1179                } else {
1180                    tim.tccr1a().modify(|_r, w| w.com1a().set(0b00));
1181                },
1182            },
1183            PD5: {
1184                ocr: ocr1b,
1185                into_pwm: |tim| if enable {
1186                    tim.tccr1a().modify(|_r, w| w.com1b().set(0b11));
1187                } else {
1188                    tim.tccr1a().modify(|_r, w| w.com1b().set(0b00));
1189                },
1190            },
1191        },
1192    }
1193}