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().bits(0b01));
84            tim.tccr1b.modify(|_r, w| {
85                w.wgm1().bits(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().bits(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().bits(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().bits(0b01));
321            tim.tccr1b.modify(|_r, w| match prescaler {
322                Prescaler::Direct => w.cs1().direct(),
323                Prescaler::Prescale8 => w.cs1().prescale_8(),
324                Prescaler::Prescale64 => w.cs1().prescale_64(),
325                Prescaler::Prescale256 => w.cs1().prescale_256(),
326                Prescaler::Prescale1024 => w.cs1().prescale_1024(),
327            });
328        },
329        pins: {
330            PB5: {
331                ocr: ocr1a,
332                into_pwm: |tim| if enable {
333                    tim.tccr1a.modify(|_r, w| w.com1a().match_clear());
334                } else {
335                    tim.tccr1a.modify(|_r, w| w.com1a().disconnected());
336                },
337            },
338
339            PB6: {
340                ocr: ocr1b,
341                into_pwm: |tim| if enable {
342                    tim.tccr1a.modify(|_r, w| w.com1b().match_clear());
343                } else {
344                    tim.tccr1a.modify(|_r, w| w.com1b().disconnected());
345                },
346            },
347
348            PB7: {
349                ocr: ocr1c,
350                into_pwm: |tim| if enable {
351                    tim.tccr1a.modify(|_r, w| w.com1c().match_clear());
352                } else {
353                    tim.tccr1a.modify(|_r, w| w.com1c().disconnected());
354                },
355            },
356        },
357    }
358}
359
360#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
361avr_hal_generic::impl_simple_pwm! {
362    /// Use `TC2` for PWM (pins `PB4`, `PH6`)
363    ///
364    /// # Example
365    /// ```
366    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
367    ///
368    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer2);
369    /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer2);
370    ///
371    /// d10.set_duty(128);
372    /// d10.enable();
373    /// ```
374
375    pub struct Timer2Pwm {
376        timer: crate::pac::TC2,
377        init: |tim, prescaler| {
378            tim.tccr2a.modify(|_r, w| w.wgm2().bits(0b01));
379            tim.tccr2b.modify(|_r, w| {
380                w.wgm22().clear_bit();
381
382                match prescaler {
383                    Prescaler::Direct => w.cs2().direct(),
384                    Prescaler::Prescale8 => w.cs2().prescale_8(),
385                    Prescaler::Prescale64 => w.cs2().prescale_64(),
386                    Prescaler::Prescale256 => w.cs2().prescale_256(),
387                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
388                }
389            });
390        },
391        pins: {
392            PB4: {
393                ocr: ocr2a,
394                into_pwm: |tim| if enable {
395                    tim.tccr2a.modify(|_r, w| w.com2a().match_clear());
396                } else {
397                    tim.tccr2a.modify(|_r, w| w.com2a().disconnected());
398                },
399            },
400
401            PH6: {
402                ocr: ocr2b,
403                into_pwm: |tim| if enable {
404                    tim.tccr2a.modify(|_r, w| w.com2b().match_clear());
405                } else {
406                    tim.tccr2a.modify(|_r, w| w.com2b().disconnected());
407                },
408            },
409        },
410    }
411}
412
413#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
414avr_hal_generic::impl_simple_pwm! {
415    /// Use `TC3` for PWM (pins `PE3`, `PE4`, `PE5`)
416    ///
417    /// # Example
418    /// ```
419    /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64);
420    ///
421    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3);
422    /// let mut d2 = pins.d2.into_output().into_pwm(&mut timer3);
423    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer3);
424    ///
425    /// d5.set_duty(128);
426    /// d5.enable();
427    /// ```
428    pub struct Timer3Pwm {
429        timer: crate::pac::TC3,
430        init: |tim, prescaler| {
431            tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01));
432            tim.tccr3b.modify(|_r, w| {
433                w.wgm3().bits(0b01);
434
435                match prescaler {
436                    Prescaler::Direct => w.cs3().direct(),
437                    Prescaler::Prescale8 => w.cs3().prescale_8(),
438                    Prescaler::Prescale64 => w.cs3().prescale_64(),
439                    Prescaler::Prescale256 => w.cs3().prescale_256(),
440                    Prescaler::Prescale1024 => w.cs3().prescale_1024(),
441                }
442            });
443        },
444        pins: {
445            PE3: {
446                ocr: ocr3a,
447                into_pwm: |tim| if enable {
448                    tim.tccr3a.modify(|_r, w| w.com3a().match_clear());
449                } else {
450                    tim.tccr3a.modify(|_r, w| w.com3a().disconnected());
451                },
452            },
453
454            PE4: {
455                ocr: ocr3b,
456                into_pwm: |tim| if enable {
457                    tim.tccr3a.modify(|_r, w| w.com3b().match_clear());
458                } else {
459                    tim.tccr3a.modify(|_r, w| w.com3b().disconnected());
460                },
461            },
462
463            PE5: {
464                ocr: ocr3c,
465                into_pwm: |tim| if enable {
466                    tim.tccr3a.modify(|_r, w| w.com3c().match_clear());
467                } else {
468                    tim.tccr3a.modify(|_r, w| w.com3c().disconnected());
469                },
470            },
471
472        },
473    }
474}
475
476#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
477avr_hal_generic::impl_simple_pwm! {
478    /// Use `TC4` for PWM (pins `PH3`, `PH4`, `PH5`)
479    ///
480    /// # Example
481    /// ```
482    /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64);
483    ///
484    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4);
485    /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer4);
486    /// let mut d8 = pins.d8.into_output().into_pwm(&mut timer4);
487    ///
488    /// d6.set_duty(128);
489    /// d6.enable();
490    /// ```
491    pub struct Timer4Pwm {
492        timer: crate::pac::TC4,
493        init: |tim, prescaler| {
494            tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01));
495            tim.tccr4b.modify(|_r, w| {
496                w.wgm4().bits(0b01);
497
498                match prescaler {
499                    Prescaler::Direct => w.cs4().direct(),
500                    Prescaler::Prescale8 => w.cs4().prescale_8(),
501                    Prescaler::Prescale64 => w.cs4().prescale_64(),
502                    Prescaler::Prescale256 => w.cs4().prescale_256(),
503                    Prescaler::Prescale1024 => w.cs4().prescale_1024(),
504                }
505            });
506        },
507        pins: {
508            PH3: {
509                ocr: ocr4a,
510                into_pwm: |tim| if enable {
511                    tim.tccr4a.modify(|_r, w| w.com4a().match_clear());
512                } else {
513                    tim.tccr4a.modify(|_r, w| w.com4a().disconnected());
514                },
515            },
516
517            PH4: {
518                ocr: ocr4b,
519                into_pwm: |tim| if enable {
520                    tim.tccr4a.modify(|_r, w| w.com4b().match_clear());
521                } else {
522                    tim.tccr4a.modify(|_r, w| w.com4b().disconnected());
523                },
524            },
525
526            PH5: {
527                ocr: ocr4c,
528                into_pwm: |tim| if enable {
529                    tim.tccr4a.modify(|_r, w| w.com4c().match_clear());
530                } else {
531                    tim.tccr4a.modify(|_r, w| w.com4c().disconnected());
532                },
533            },
534
535        },
536    }
537}
538
539#[cfg(any(feature = "atmega1280", feature = "atmega2560"))]
540avr_hal_generic::impl_simple_pwm! {
541    /// Use `TC5` for PWM (pins `PL3`, `PL4`, `PL5`)
542    ///
543    /// # Example
544    /// ```
545    /// let mut timer5 = Timer5Pwm::new(dp.TC5, Prescaler::Prescale64);
546    ///
547    /// let mut d46 = pins.d46.into_output().into_pwm(&mut timer5);
548    /// let mut d45 = pins.d45.into_output().into_pwm(&mut timer5);
549    /// let mut d44 = pins.d44.into_output().into_pwm(&mut timer5);
550    ///
551    /// d46.set_duty(128);
552    /// d46.enable();
553    /// ```
554    pub struct Timer5Pwm {
555        timer: crate::pac::TC5,
556        init: |tim, prescaler| {
557            tim.tccr5a.modify(|_r, w| w.wgm5().bits(0b01));
558            tim.tccr5b.modify(|_r, w| {
559                w.wgm5().bits(0b01);
560
561                match prescaler {
562                    Prescaler::Direct => w.cs5().direct(),
563                    Prescaler::Prescale8 => w.cs5().prescale_8(),
564                    Prescaler::Prescale64 => w.cs5().prescale_64(),
565                    Prescaler::Prescale256 => w.cs5().prescale_256(),
566                    Prescaler::Prescale1024 => w.cs5().prescale_1024(),
567                }
568            });
569        },
570        pins: {
571            PL3: {
572                ocr: ocr5a,
573                into_pwm: |tim| if enable {
574                    tim.tccr5a.modify(|_r, w| w.com5a().match_clear());
575                } else {
576                    tim.tccr5a.modify(|_r, w| w.com5a().disconnected());
577                },
578            },
579
580            PL4: {
581                ocr: ocr5b,
582                into_pwm: |tim| if enable {
583                    tim.tccr5a.modify(|_r, w| w.com5b().match_clear());
584                } else {
585                    tim.tccr5a.modify(|_r, w| w.com5b().disconnected());
586                },
587            },
588
589            PL5: {
590                ocr: ocr5c,
591                into_pwm: |tim| if enable {
592                    tim.tccr5a.modify(|_r, w| w.com5c().match_clear());
593                } else {
594                    tim.tccr5a.modify(|_r, w| w.com5c().disconnected());
595                },
596            },
597
598        },
599    }
600}
601
602#[cfg(any(feature = "atmega32u4"))]
603avr_hal_generic::impl_simple_pwm! {
604    /// Use `TC0` for PWM (pins `PB7`, `PD0`)
605    ///
606    /// # Example
607    /// ```
608    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
609    ///
610    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer0);
611    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer0);
612    ///
613    /// d11.set_duty(128);
614    /// d11.enable();
615    /// ```
616    pub struct Timer0Pwm {
617        timer: crate::pac::TC0,
618        init: |tim, prescaler| {
619            tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast());
620            tim.tccr0b.modify(|_r, w| match prescaler {
621                Prescaler::Direct => w.cs0().direct(),
622                Prescaler::Prescale8 => w.cs0().prescale_8(),
623                Prescaler::Prescale64 => w.cs0().prescale_64(),
624                Prescaler::Prescale256 => w.cs0().prescale_256(),
625                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
626            });
627        },
628        pins: {
629            PB7: {
630                ocr: ocr0a,
631                into_pwm: |tim| if enable {
632                    tim.tccr0a.modify(|_r, w| w.com0a().match_clear());
633                } else {
634                    tim.tccr0a.modify(|_r, w| w.com0a().disconnected());
635                },
636            },
637
638            PD0: {
639                ocr: ocr0b,
640                into_pwm: |tim| if enable {
641                    tim.tccr0a.modify(|_r, w| w.com0b().match_clear());
642                } else {
643                    tim.tccr0a.modify(|_r, w| w.com0b().disconnected());
644                },
645            },
646        },
647    }
648}
649
650#[cfg(any(feature = "atmega32u4"))]
651avr_hal_generic::impl_simple_pwm! {
652    /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`)
653    ///
654    /// # Example
655    /// ```
656    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
657    ///
658    /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1);
659    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1);
660    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1);
661    ///
662    /// d9.set_duty(128);
663    /// d9.enable();
664    /// ```
665    pub struct Timer1Pwm {
666        timer: crate::pac::TC1,
667        init: |tim, prescaler| {
668            tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01));
669            tim.tccr1b.modify(|_r, w| w.wgm1().bits(0b01));
670
671            tim.tccr1b.modify(|_r, w| match prescaler {
672                Prescaler::Direct => w.cs1().direct(),
673                Prescaler::Prescale8 => w.cs1().prescale_8(),
674                Prescaler::Prescale64 => w.cs1().prescale_64(),
675                Prescaler::Prescale256 => w.cs1().prescale_256(),
676                Prescaler::Prescale1024 => w.cs1().prescale_1024(),
677            });
678        },
679        pins: {
680            PB5: {
681                ocr: ocr1a,
682                into_pwm: |tim| if enable {
683                    tim.tccr1a.modify(|_r, w| w.com1a().match_clear());
684                } else {
685                    tim.tccr1a.modify(|_r, w| w.com1a().disconnected());
686                },
687            },
688
689            PB6: {
690                ocr: ocr1b,
691                into_pwm: |tim| if enable {
692                    tim.tccr1a.modify(|_r, w| w.com1b().match_clear());
693                } else {
694                    tim.tccr1a.modify(|_r, w| w.com1b().disconnected());
695                },
696            },
697
698            PB7: {
699                ocr: ocr1c,
700                into_pwm: |tim| if enable {
701                    tim.tccr1a.modify(|_r, w| w.com1c().match_clear());
702                } else {
703                    tim.tccr1a.modify(|_r, w| w.com1c().disconnected());
704                },
705            },
706        },
707    }
708}
709
710#[cfg(any(feature = "atmega32u4"))]
711avr_hal_generic::impl_simple_pwm! {
712    /// Use `TC3` for PWM (pins `PC6`)
713    ///
714    /// # Example
715    /// ```
716    /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64);
717    ///
718    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3);
719    ///
720    /// d5.set_duty(128);
721    /// d5.enable();
722    /// ```
723    pub struct Timer3Pwm {
724        timer: crate::pac::TC3,
725        init: |tim, prescaler| {
726            tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01));
727            tim.tccr3b.modify(|_r, w| w.wgm3().bits(0b01));
728
729            tim.tccr3b.modify(|_r, w| match prescaler {
730                Prescaler::Direct => w.cs3().direct(),
731                Prescaler::Prescale8 => w.cs3().prescale_8(),
732                Prescaler::Prescale64 => w.cs3().prescale_64(),
733                Prescaler::Prescale256 => w.cs3().prescale_256(),
734                Prescaler::Prescale1024 => w.cs3().prescale_1024(),
735            });
736        },
737        pins: {
738            PC6: {
739                ocr: ocr3a,
740                into_pwm: |tim| if enable {
741                    tim.tccr3a.modify(|_r, w| w.com3a().match_clear());
742                } else {
743                    tim.tccr3a.modify(|_r, w| w.com3a().disconnected());
744                },
745            },
746        },
747    }
748}
749
750#[cfg(any(feature = "atmega32u4"))]
751avr_hal_generic::impl_simple_pwm! {
752    /// Use `TC4` for PWM (pins `PB6`, `PC7`, `PD7`)
753    ///
754    /// # Example
755    /// ```
756    /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64);
757    ///
758    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4);
759    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer4);
760    /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer4);
761    ///
762    /// d6.set_duty(128);
763    /// d6.enable();
764    /// ```
765    pub struct Timer4Pwm {
766        timer: crate::pac::TC4,
767        init: |tim, prescaler| {
768            tim.tccr4a.modify(|_r, w| w.pwm4a().set_bit());
769            tim.tccr4a.modify(|_r, w| w.pwm4b().set_bit());
770            tim.tccr4c.modify(|_r, w| w.pwm4d().set_bit());
771
772            tim.tccr4b.modify(|_r, w| match prescaler {
773                Prescaler::Direct => w.cs4().direct(),
774                Prescaler::Prescale8 => w.cs4().prescale_8(),
775                Prescaler::Prescale64 => w.cs4().prescale_64(),
776                Prescaler::Prescale256 => w.cs4().prescale_256(),
777                Prescaler::Prescale1024 => w.cs4().prescale_1024(),
778            });
779        },
780        pins: {
781            PB6: {
782                ocr: ocr4b,
783                into_pwm: |tim| if enable {
784                    tim.tccr4a.modify(|_r, w| w.com4b().match_clear());
785                } else {
786                    tim.tccr4a.modify(|_r, w| w.com4b().disconnected());
787                },
788            },
789
790            PC7: {
791                ocr: ocr4a,
792                into_pwm: |tim| if enable {
793                    tim.tccr4a.modify(|_r, w| w.com4a().match_clear());
794                } else {
795                    tim.tccr4a.modify(|_r, w| w.com4a().disconnected());
796                },
797            },
798
799            PD7: {
800                ocr: ocr4d,
801                into_pwm: |tim| if enable {
802                    tim.tccr4c.modify(|_r, w| w.com4d().match_clear());
803                } else {
804                    tim.tccr4c.modify(|_r, w| w.com4d().disconnected());
805                },
806            },
807        },
808    }
809}
810
811#[cfg(any(feature = "atmega1284p"))]
812avr_hal_generic::impl_simple_pwm! {
813    /// Use `TC0` for PWM (pins `PB3`, `PB4`)
814    ///
815    /// # Example
816    /// ```
817    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
818    ///
819    /// let mut b3 = pins.b3.into_output().into_pwm(&mut timer0);
820    /// let mut b4 = pins.b4.into_output().into_pwm(&mut timer0);
821    ///
822    /// b3.set_duty(128);
823    /// b4.enable();
824    /// ```
825    pub struct Timer0Pwm {
826        timer: crate::pac::TC0,
827        init: |tim, prescaler| {
828            tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast());
829            tim.tccr0b.modify(|_r, w| match prescaler {
830                Prescaler::Direct => w.cs0().direct(),
831                Prescaler::Prescale8 => w.cs0().prescale_8(),
832                Prescaler::Prescale64 => w.cs0().prescale_64(),
833                Prescaler::Prescale256 => w.cs0().prescale_256(),
834                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
835            });
836        },
837        pins: {
838            PB3: {
839                ocr: ocr0a,
840                into_pwm: |tim| if enable {
841                    tim.tccr0a.modify(|_r, w| w.com0a().match_clear());
842                } else {
843                    tim.tccr0a.modify(|_r, w| w.com0a().disconnected());
844                },
845            },
846
847            PB4: {
848                ocr: ocr0b,
849                into_pwm: |tim| if enable {
850                    tim.tccr0a.modify(|_r, w| w.com0b().match_clear());
851                } else {
852                    tim.tccr0a.modify(|_r, w| w.com0b().disconnected());
853                },
854            },
855        },
856    }
857}
858
859#[cfg(any(feature = "atmega1284p"))]
860avr_hal_generic::impl_simple_pwm! {
861    /// Use `TC1` for PWM (pins `PD5`, `PD4`)
862    ///
863    /// # Example
864    /// ```
865    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
866    ///
867    /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer1);
868    /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1);
869    ///
870    /// d5.set_duty(128);
871    /// d5.enable();
872    /// ```
873    pub struct Timer1Pwm {
874        timer: crate::pac::TC1,
875        init: |tim, prescaler| {
876            tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01));
877            tim.tccr1b.modify(|_r, w| {
878                w.wgm1().bits(0b01);
879
880                match prescaler {
881                    Prescaler::Direct => w.cs1().direct(),
882                    Prescaler::Prescale8 => w.cs1().prescale_8(),
883                    Prescaler::Prescale64 => w.cs1().prescale_64(),
884                    Prescaler::Prescale256 => w.cs1().prescale_256(),
885                    Prescaler::Prescale1024 => w.cs1().prescale_1024(),
886                }
887            });
888        },
889        pins: {
890            PD5: {
891                ocr: ocr1a,
892                into_pwm: |tim| if enable {
893                    tim.tccr1a.modify(|_r, w| w.com1a().match_clear());
894                } else {
895                    tim.tccr1a.modify(|_r, w| w.com1a().disconnected());
896                },
897            },
898
899            PD4: {
900                ocr: ocr1b,
901                into_pwm: |tim| if enable {
902                    tim.tccr1a.modify(|_r, w| w.com1b().match_clear());
903                } else {
904                    tim.tccr1a.modify(|_r, w| w.com1b().disconnected());
905                },
906            },
907        },
908    }
909}
910
911#[cfg(any(feature = "atmega1284p"))]
912avr_hal_generic::impl_simple_pwm! {
913    /// Use `TC2` for PWM (pins `PD7`, `PD6`)
914    ///
915    /// # Example
916    /// ```
917    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
918    ///
919    /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer2);
920    /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer2);
921    ///
922    /// d7.set_duty(128);
923    /// d7.enable();
924    /// ```
925    pub struct Timer2Pwm {
926        timer: crate::pac::TC2,
927        init: |tim, prescaler| {
928            tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast());
929            tim.tccr2b.modify(|_r, w| match prescaler {
930                    Prescaler::Direct => w.cs2().direct(),
931                    Prescaler::Prescale8 => w.cs2().prescale_8(),
932                    Prescaler::Prescale64 => w.cs2().prescale_64(),
933                    Prescaler::Prescale256 => w.cs2().prescale_256(),
934                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
935            });
936        },
937        pins: {
938            PD7: {
939                ocr: ocr2a,
940                into_pwm: |tim| if enable {
941                    tim.tccr2a.modify(|_r, w| w.com2a().match_clear());
942                } else {
943                    tim.tccr2a.modify(|_r, w| w.com2a().disconnected());
944                },
945            },
946
947            PD6: {
948                ocr: ocr2b,
949                into_pwm: |tim| if enable {
950                    tim.tccr2a.modify(|_r, w| w.com2b().match_clear());
951                } else {
952                    tim.tccr2a.modify(|_r, w| w.com2b().disconnected());
953                },
954            },
955        },
956    }
957}
958
959#[cfg(any(feature = "atmega1284p"))]
960avr_hal_generic::impl_simple_pwm! {
961    /// Use `TC3` for PWM (pins `PB6`, `PB7`)
962    pub struct Timer3Pwm {
963        timer: crate::pac::TC3,
964        init: |tim, prescaler| {
965            tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01));
966            tim.tccr3b.modify(|_r, w| {
967                w.wgm3().bits(0b01);
968
969                match prescaler {
970                    Prescaler::Direct => w.cs3().direct(),
971                    Prescaler::Prescale8 => w.cs3().prescale_8(),
972                    Prescaler::Prescale64 => w.cs3().prescale_64(),
973                    Prescaler::Prescale256 => w.cs3().prescale_256(),
974                    Prescaler::Prescale1024 => w.cs3().prescale_1024(),
975                }
976            });
977        },
978        pins: {
979            PB6: {
980                ocr: ocr3a,
981                into_pwm: |tim| if enable {
982                    tim.tccr3a.modify(|_r, w| w.com3a().match_clear());
983                } else {
984                    tim.tccr3a.modify(|_r, w| w.com3a().disconnected());
985                },
986            },
987
988            PB7: {
989                ocr: ocr3b,
990                into_pwm: |tim| if enable {
991                    tim.tccr3a.modify(|_r, w| w.com3b().match_clear());
992                } else {
993                    tim.tccr3a.modify(|_r, w| w.com3b().disconnected());
994                },
995            },
996        },
997    }
998}
999
1000#[cfg(any(feature = "atmega8",))]
1001avr_hal_generic::impl_simple_pwm! {
1002    /// Use `TC1` for PWM (pins `PB1`, `PB2`)
1003    ///
1004    /// # Example
1005    /// ```
1006    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
1007    ///
1008    /// let mut b1 = pins.b1.into_output().into_pwm(&mut timer1);
1009    /// let mut b2 = pins.b2.into_output().into_pwm(&mut timer1);
1010    ///
1011    /// d9.set_duty(128);
1012    /// d9.enable();
1013    /// ```
1014    pub struct Timer1Pwm {
1015        timer: crate::pac::TC1,
1016        init: |tim, prescaler| {
1017            tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01));
1018            tim.tccr1b.modify(|_r, w| {
1019                w.wgm1().bits(0b01);
1020
1021                match prescaler {
1022                    Prescaler::Direct => w.cs1().direct(),
1023                    Prescaler::Prescale8 => w.cs1().prescale_8(),
1024                    Prescaler::Prescale64 => w.cs1().prescale_64(),
1025                    Prescaler::Prescale256 => w.cs1().prescale_256(),
1026                    Prescaler::Prescale1024 => w.cs1().prescale_1024(),
1027                }
1028            });
1029        },
1030        pins: {
1031            PB1: {
1032                ocr: ocr1a,
1033                into_pwm: |tim| if enable {
1034                    tim.tccr1a.modify(|_r, w| w.com1a().match_clear());
1035                } else {
1036                    tim.tccr1a.modify(|_r, w| w.com1a().disconnected());
1037                },
1038            },
1039
1040            PB2: {
1041                ocr: ocr1b,
1042                into_pwm: |tim| if enable {
1043                    tim.tccr1a.modify(|_r, w| w.com1b().match_clear());
1044                } else {
1045                    tim.tccr1a.modify(|_r, w| w.com1b().disconnected());
1046                },
1047            },
1048        },
1049    }
1050}
1051
1052#[cfg(any(feature = "atmega8",))]
1053avr_hal_generic::impl_simple_pwm! {
1054    /// Use `TC2` for PWM (pins `PB3`, `PD3`)
1055    ///
1056    /// # Example
1057    /// ```
1058    /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
1059    ///
1060    /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2);
1061    /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2);
1062    ///
1063    /// d11.set_duty(128);
1064    /// d11.enable();
1065    /// ```
1066    pub struct Timer2Pwm {
1067        timer: crate::pac::TC2,
1068        init: |tim, prescaler| {
1069            tim.tccr2.modify(|_r, w| w.wgm20().set_bit().wgm21().set_bit());
1070            tim.tccr2.modify(|_r, w| match prescaler {
1071                    Prescaler::Direct => w.cs2().direct(),
1072                    Prescaler::Prescale8 => w.cs2().prescale_8(),
1073                    Prescaler::Prescale64 => w.cs2().prescale_64(),
1074                    Prescaler::Prescale256 => w.cs2().prescale_256(),
1075                    Prescaler::Prescale1024 => w.cs2().prescale_1024(),
1076            });
1077        },
1078        pins: {
1079            PB3: {
1080                ocr: ocr2,
1081                into_pwm: |tim| if enable {
1082                    tim.tccr2.modify(|_r, w| w.com2().match_clear());
1083                } else {
1084                    tim.tccr2.modify(|_r, w| w.com2().disconnected());
1085                },
1086            },
1087        },
1088    }
1089}
1090
1091#[cfg(any(feature = "atmega164pa"))]
1092avr_hal_generic::impl_simple_pwm! {
1093    /// Use `TC0` for PWM (pins `PB3`)
1094    ///
1095    /// # Example
1096    /// ```
1097    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
1098    ///
1099    /// let mut b3 = pins.pb3.into_output().into_pwm(&mut timer0);
1100    ///
1101    /// b3.set_duty(128);
1102    /// b3.enable();
1103    /// ```
1104    pub struct Timer0Pwm {
1105        timer: crate::pac::TC0,
1106        init: |tim, prescaler| {
1107            tim.tccr0a.modify(|_r, w| w.wgm0().bits(0b11));
1108            tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00));
1109
1110            tim.tccr0b.modify(|_r, w| match prescaler {
1111                Prescaler::Direct => w.cs0().running_no_prescaling(),
1112                Prescaler::Prescale8 => w.cs0().running_clk_8(),
1113                Prescaler::Prescale64 => w.cs0().running_clk_64(),
1114                Prescaler::Prescale256 => w.cs0().running_clk_256(),
1115                Prescaler::Prescale1024 => w.cs0().running_clk_1024(),
1116            });
1117        },
1118        pins: {
1119            PB3: {
1120                ocr: ocr0a,
1121                into_pwm: |tim| if enable {
1122                    tim.tccr0a.modify(|_r, w| w.com0a().bits(0b11));
1123                } else {
1124                    tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00));
1125                },
1126            },
1127        },
1128    }
1129}
1130
1131#[cfg(any(feature = "atmega16", feature = "atmega164pa"))]
1132avr_hal_generic::impl_simple_pwm! {
1133    /// Use `TC1` for PWM (pins `PD4`, `PD5`)
1134    ///
1135    /// # Example
1136    /// ```
1137    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
1138    ///
1139    /// let mut d4 = pins.pd4.into_output().into_pwm(&mut timer1);
1140    /// let mut d5 = pins.pd5.into_output().into_pwm(&mut timer1);
1141    ///
1142    /// d4.set_duty(128);
1143    /// d4.enable();
1144    /// d5.set_duty(64);
1145    /// d5.enable();
1146    /// ```
1147    pub struct Timer1Pwm {
1148        timer: crate::pac::TC1,
1149        init: |tim, prescaler| {
1150            tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01));
1151            tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00));
1152            tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00));
1153            #[cfg(any(feature = "atmega164pa"))]
1154            tim.tccr1b.modify(|_r, w| match prescaler {
1155                Prescaler::Direct => w.cs1().running_no_prescaling(),
1156                Prescaler::Prescale8 => w.cs1().running_clk_8(),
1157                Prescaler::Prescale64 => w.cs1().running_clk_64(),
1158                Prescaler::Prescale256 => w.cs1().running_clk_256(),
1159                Prescaler::Prescale1024 => w.cs1().running_clk_1024(),
1160            });
1161            #[cfg(any(feature = "atmega16"))]
1162            tim.tccr1b.modify(|_r, w| match prescaler {
1163                Prescaler::Direct => w.cs1().val_0x01(),
1164                Prescaler::Prescale8 => w.cs1().val_0x02(),
1165                Prescaler::Prescale64 => w.cs1().val_0x03(),
1166                Prescaler::Prescale256 => w.cs1().val_0x04(),
1167                Prescaler::Prescale1024 => w.cs1().val_0x05(),
1168            });
1169        },
1170        pins: {
1171            PD4: {
1172                ocr: ocr1a,
1173                into_pwm: |tim| if enable {
1174                    tim.tccr1a.modify(|_r, w| w.com1a().bits(0b11));
1175                } else {
1176                    tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00));
1177                },
1178            },
1179            PD5: {
1180                ocr: ocr1b,
1181                into_pwm: |tim| if enable {
1182                    tim.tccr1a.modify(|_r, w| w.com1b().bits(0b11));
1183                } else {
1184                    tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00));
1185                },
1186            },
1187        },
1188    }
1189}