use core::convert::Infallible;
use crate::Pin;
#[derive(Copy, Clone)]
pub enum Pull {
None,
Up,
Down,
}
#[derive(Copy, Clone)]
pub struct PinMode(u8);
impl PinMode {
pub const INPUT_FLOATING: Self = Self(0b0100); pub const INPUT_PULL_UP: Self = Self(0b1000 | 0x80); pub const INPUT_PULL_DOWN: Self = Self(0b1000 | 0x40); pub const OUTPUT_PUSH_PULL: Self = Self(0b0001); pub const OUTPUT_OPEN_DRAIN: Self = Self(0b0101); pub const AF_PUSH_PULL: Self = Self(0b1001); pub const AF_OPEN_DRAIN: Self = Self(0b1101);
pub fn input_pull(pull: Pull) -> Self {
match pull {
Pull::Up => Self::INPUT_PULL_UP,
Pull::Down => Self::INPUT_PULL_DOWN,
Pull::None => Self::INPUT_FLOATING,
}
}
}
#[inline(always)]
pub fn configure(pin: Pin, mode: PinMode) {
let regs = pin.gpio_regs();
let n = pin.pin_number();
let shift = n * 4;
let mask = !(0xFu32 << shift);
let bits = ((mode.0 & 0x0F) as u32) << shift;
let prev = regs.cfglr().read().0;
regs.cfglr()
.write_value(ch32_metapac::gpio::regs::Cfglr(prev & mask | bits));
if mode.0 & 0xC0 != 0 {
let mut outdr = regs.outdr().read();
outdr.set_odr(n, mode.0 & 0x80 != 0);
regs.outdr().write_value(outdr);
}
}
pub fn set_high(pin: Pin) {
pin.gpio_regs()
.bshr()
.write(|w| w.0 = 1 << pin.pin_number());
}
pub fn set_low(pin: Pin) {
pin.gpio_regs().bcr().write(|w| w.0 = 1 << pin.pin_number());
}
impl embedded_hal::digital::ErrorType for Pin {
type Error = Infallible;
}
impl embedded_hal::digital::OutputPin for Pin {
fn set_high(&mut self) -> Result<(), Self::Error> {
set_high(*self);
Ok(())
}
fn set_low(&mut self) -> Result<(), Self::Error> {
set_low(*self);
Ok(())
}
}