attiny_hal/
simple_pwm.rs

1pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps};
2
3#[cfg(any(feature = "attiny85", feature = "attiny84", feature = "attiny88"))]
4use crate::port::*;
5
6#[cfg(feature = "attiny84")]
7avr_hal_generic::impl_simple_pwm! {
8    /// Use `TC0` for PWM (pins `PB2`, `PA7`)
9    pub struct Timer0Pwm {
10        timer: crate::pac::TC0,
11        init: |tim, prescaler| {
12            tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast());
13            tim.tccr0b.modify(|_r, w| match prescaler {
14                Prescaler::Direct => w.cs0().direct(),
15                Prescaler::Prescale8 => w.cs0().prescale_8(),
16                Prescaler::Prescale64 => w.cs0().prescale_64(),
17                Prescaler::Prescale256 => w.cs0().prescale_256(),
18                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
19            });
20        },
21        pins: {
22            PB2: {
23                ocr: ocr0a,
24                into_pwm: |tim| if enable {
25                    tim.tccr0a.modify(|_r, w| w.com0a().match_clear());
26                } else {
27                    tim.tccr0a.modify(|_r, w| w.com0a().disconnected());
28                },
29            },
30
31            PA7: {
32                ocr: ocr0b,
33                into_pwm: |tim| if enable {
34                    tim.tccr0a.modify(|_r, w| w.com0b().match_clear());
35                } else {
36                    tim.tccr0a.modify(|_r, w| w.com0b().disconnected());
37                },
38            },
39        },
40    }
41}
42
43#[cfg(feature = "attiny84")]
44avr_hal_generic::impl_simple_pwm! {
45    /// Use `TC1` for PWM (pins `PA6`, 'PA5')
46    pub struct Timer1Pwm {
47        timer: crate::pac::TC1,
48        init: |tim, prescaler| {
49            tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01));
50            tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01));
51
52            tim.tccr1b.modify(|_r, w| match prescaler {
53                Prescaler::Direct => w.cs1().direct(),
54                Prescaler::Prescale8 => w.cs1().prescale_8(),
55                Prescaler::Prescale64 => w.cs1().prescale_64(),
56                Prescaler::Prescale256 => w.cs1().prescale_256(),
57                Prescaler::Prescale1024 => w.cs1().prescale_1024(),
58            });
59        },
60        pins: {
61            PA6: {
62                ocr: ocr1a,
63                into_pwm: |tim| if enable {
64                    tim.tccr1a.modify(|_, w| w.com1a().bits(0b10));
65                } else {
66                    tim.tccr1a.modify(|_, w| w.com1a().disconnected());
67                },
68            },
69
70            PA5: {
71                ocr: ocr1b,
72                into_pwm: |tim| if enable {
73                    tim.tccr1a.modify(|_, w| w.com1b().bits(0b10));
74                } else {
75                    tim.tccr1a.modify(|_, w| w.com1b().disconnected());
76                },
77            },
78        },
79    }
80}
81
82#[cfg(feature = "attiny85")]
83avr_hal_generic::impl_simple_pwm! {
84    /// Use `TC0` for PWM (pins `PB0`, `PB1`)
85    ///
86    /// # Example
87    /// ```
88    /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
89    ///
90    /// let mut d0 = pins.d0.into_output().into_pwm(&mut timer0);
91    /// let mut d1 = pins.d1.into_output().into_pwm(&mut timer0);
92    ///
93    /// d0.set_duty(128);
94    /// d0.enable();
95    /// ```
96    pub struct Timer0Pwm {
97        timer: crate::pac::TC0,
98        init: |tim, prescaler| {
99            tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast());
100            tim.tccr0b.modify(|_r, w| match prescaler {
101                Prescaler::Direct => w.cs0().direct(),
102                Prescaler::Prescale8 => w.cs0().prescale_8(),
103                Prescaler::Prescale64 => w.cs0().prescale_64(),
104                Prescaler::Prescale256 => w.cs0().prescale_256(),
105                Prescaler::Prescale1024 => w.cs0().prescale_1024(),
106            });
107        },
108        pins: {
109            PB0: {
110                ocr: ocr0a,
111                into_pwm: |tim| if enable {
112                    tim.tccr0a.modify(|_r, w| w.com0a().match_clear());
113                } else {
114                    tim.tccr0a.modify(|_r, w| w.com0a().disconnected());
115                },
116            },
117
118            PB1: {
119                ocr: ocr0b,
120                into_pwm: |tim| if enable {
121                    tim.tccr0a.modify(|_r, w| w.com0b().match_clear());
122                } else {
123                    tim.tccr0a.modify(|_r, w| w.com0b().disconnected());
124                },
125            },
126        },
127    }
128}
129
130#[cfg(feature = "attiny85")]
131avr_hal_generic::impl_simple_pwm! {
132    /// Use `TC1` for PWM (pins `PB4`)
133    ///
134    /// # Example
135    /// ```
136    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
137    ///
138    /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1);
139    ///
140    /// d4.set_duty(128);
141    /// d4.enable();
142    /// ```
143    pub struct Timer1Pwm {
144        timer: crate::pac::TC1,
145        init: |tim, prescaler| {
146            tim.gtccr.modify(|_, w| w.pwm1b().bit(true));
147
148            tim.tccr1.modify(|_r, w| match prescaler {
149                Prescaler::Direct => w.cs1().direct(),
150                Prescaler::Prescale8 => w.cs1().prescale_8(),
151                Prescaler::Prescale64 => w.cs1().prescale_64(),
152                Prescaler::Prescale256 => w.cs1().prescale_256(),
153                Prescaler::Prescale1024 => w.cs1().prescale_1024(),
154            });
155        },
156        pins: {
157            PB4: {
158                ocr: ocr1b,
159                into_pwm: |tim| if enable {
160                    tim.gtccr.modify(|_, w| w.com1b().bits(0b10));
161                } else {
162                    tim.gtccr.modify(|_, w| w.com1b().disconnected());
163                },
164            },
165        },
166    }
167}
168
169#[cfg(feature = "attiny88")]
170avr_hal_generic::impl_simple_pwm! {
171    /// Use `TC1` for PWM (pins `PB1`, 'PB2')
172    ///
173    /// # Example
174    /// ```
175    /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64);
176    ///
177    /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1);
178    /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1);
179    ///
180    /// d9.set_duty(128);
181    /// d9.enable();
182    /// ```
183    pub struct Timer1Pwm {
184        timer: crate::pac::TC1,
185        init: |tim, prescaler| {
186            tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01));
187            tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01));
188
189            tim.tccr1b.modify(|_r, w| match prescaler {
190                Prescaler::Direct => w.cs1().direct(),
191                Prescaler::Prescale8 => w.cs1().prescale_8(),
192                Prescaler::Prescale64 => w.cs1().prescale_64(),
193                Prescaler::Prescale256 => w.cs1().prescale_256(),
194                Prescaler::Prescale1024 => w.cs1().prescale_1024(),
195            });
196        },
197        pins: {
198            PB1: {
199                ocr: ocr1a,
200                into_pwm: |tim| if enable {
201                    tim.tccr1a.modify(|_, w| w.com1a().bits(0b10));
202                } else {
203                    tim.tccr1a.modify(|_, w| w.com1a().disconnected());
204                },
205            },
206
207            PB2: {
208                ocr: ocr1b,
209                into_pwm: |tim| if enable {
210                    tim.tccr1a.modify(|_, w| w.com1b().bits(0b10));
211                } else {
212                    tim.tccr1a.modify(|_, w| w.com1b().disconnected());
213                },
214            },
215        },
216    }
217}