From 3deedf7a78d0fb7c6ff8dcc1bfcaa8fdf6d14c2a Mon Sep 17 00:00:00 2001 From: Oskar Munz Date: Fri, 15 Jul 2022 17:54:58 +0200 Subject: [PATCH] atmega164pa: Add simple_pwm implementation --- mcu/atmega-hal/src/simple_pwm.rs | 93 +++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/mcu/atmega-hal/src/simple_pwm.rs b/mcu/atmega-hal/src/simple_pwm.rs index 5adb959ad4..33c77cc7d4 100644 --- a/mcu/atmega-hal/src/simple_pwm.rs +++ b/mcu/atmega-hal/src/simple_pwm.rs @@ -1,4 +1,4 @@ -pub use avr_hal_generic::simple_pwm::{PwmPinOps, Prescaler}; +pub use avr_hal_generic::simple_pwm::{IntoPwmPin, PwmPinOps, Prescaler}; #[allow(unused_imports)] use crate::port::*; @@ -1088,3 +1088,94 @@ avr_hal_generic::impl_simple_pwm! { }, } } + +#[cfg(any(feature = "atmega164pa"))] +avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB3`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut b3 = pins.pb3.into_output().into_pwm(&mut timer0); + /// + /// b3.set_duty(128); + /// b3.enable(); + /// ``` + pub struct Timer0Pwm { + timer: crate::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().bits(0b11)); + tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); + + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().running_no_prescaling(), + Prescaler::Prescale8 => w.cs0().running_clk_8(), + Prescaler::Prescale64 => w.cs0().running_clk_64(), + Prescaler::Prescale256 => w.cs0().running_clk_256(), + Prescaler::Prescale1024 => w.cs0().running_clk_1024(), + }); + }, + pins: { + PB3: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().bits(0b11)); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); + }, + }, + }, + } +} + +#[cfg(any(feature = "atmega164pa"))] +avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PD4`, `PD5`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d4 = pins.pd4.into_output().into_pwm(&mut timer1); + /// let mut d5 = pins.pd5.into_output().into_pwm(&mut timer1); + /// + /// d4.set_duty(128); + /// d4.enable(); + /// d5.set_duty(64); + /// d5.enable(); + /// ``` + pub struct Timer1Pwm { + timer: crate::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); + tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); + tim.tccr1b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().running_no_prescaling(), + Prescaler::Prescale8 => w.cs1().running_clk_8(), + Prescaler::Prescale64 => w.cs1().running_clk_64(), + Prescaler::Prescale256 => w.cs1().running_clk_256(), + Prescaler::Prescale1024 => w.cs1().running_clk_1024(), + }); + }, + pins: { + PD4: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().bits(0b11)); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); + }, + }, + PD5: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().bits(0b11)); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); + }, + }, + }, + } +}