-
Notifications
You must be signed in to change notification settings - Fork 237
Adds parametrized duty for impl_pwm
macro
#136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: old
Are you sure you want to change the base?
Conversation
Note: 32u4 require closer look. Not sure what to do with 10 bit counter.
As I wrote in the other issue, this goes against what the That is the reason why all timers are configured for a If we were to change this as you propose here, downstream users would need to know what timer they are using for a specific pin and whether this timer is 8 or 16 (or 10) bits wide. I think this is not acceptable for an abstraction which tries to hide exactly those details and allow homogeneously treating all PWM pins the same. As I mentioned over in #132, the way forwards is a separate abstraction (or even multiple) for the different applications of the timer peripherals. Also ref. #44.
Are you sure? The timer is still configured for mode 5 (= "Fast PWM, 8-bit") and will wrap at 0xFF: avr-hal/chips/atmega328p-hal/src/pwm.rs Lines 95 to 97 in b1aedf8
Thus, calling |
@Rahix Code I was using #![feature(llvm_asm)]
#![no_std]
#![no_main]
#![feature(abi_avr_interrupt)]
use arduino_uno::{
delay_ms, prelude::*,
};
use panic_halt as _;
const MAX_CYCLES: u16 = 40_000; // 50 Hz
// SG 90 servo -90..90 angle mapping to 50..250 byte values
fn duty(value: u8) -> u16 {
20 * value as u16
}
#[arduino_uno::entry]
fn main() -> ! {
let pd = arduino_uno::Peripherals::take().unwrap();
let mut pins = arduino_uno::Pins::new(pd.PORTB, pd.PORTC, pd.PORTD);
let mut serial = arduino_uno::Serial::new(
pd.USART0, pins.d0, pins.d1.into_output(&mut pins.ddr),
9600.into_baudrate(),
);
let mut timer1 = arduino_uno::pwm::Timer1Pwm::new(
pd.TC1, arduino_uno::pwm::Prescaler::Prescale8);
// FIXME: can't export `avr_device::interrrupt::free`
{
let timer = unsafe { &*arduino_uno::pac::TC1::ptr() };
timer.tccr1a.modify(|_, w| w.wgm1().bits(0b10));
timer.tccr1b.modify(|_, w| w.wgm1().bits(0b11));
timer.icr1.modify(|_, w| unsafe { w.bits(MAX_CYCLES) });
}
let mut servo = pins.d9.into_output(&mut pins.ddr).into_pwm(&mut timer1);
servo.set_duty(duty(150));
servo.enable();
ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap();
loop {
let b: u8 = (serial.read_byte() - '0' as u8) * 100 +
(serial.read_byte() - '0' as u8) * 10 +
(serial.read_byte() - '0' as u8);
servo.set_duty(duty(b));
ufmt::uwriteln!(&mut serial, "duty set to {}\r", b).void_unwrap();
}
} Moving discussion to appropriate issues. |
32u4 require closer look. Not sure what to do with10 bit counter. Other chips verified with datasheets, at least timer1 on 328p works like a charm with 16 bit counter.
related to #134