hk32-partial-hal 0.3.1

HK32 partial HAL
use crate::gpio::{AltFunc, AnyPin, Pin, Pull};
use embassy_hal_internal::Peri;
use hk32f005_pac::gpio::regs::Cfgy;

/// GPIO flexible pin.
///
/// This pin can either be a disconnected, input, or output pin, or both. The level register bit will remain
/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
/// mode.
pub struct Flex<'d> {
    pub(crate) pin: Peri<'d, AnyPin>,
}

impl<'d> Flex<'d> {
    /// Wrap the pin in a `Flex`.
    ///
    /// The pin remains disconnected. The initial output level is unspecified, but can be changed
    /// before the pin is put into output mode.
    ///
    pub fn new(pin: Peri<'d, impl Pin>) -> Self {
        // Pin will be in disconnected state.
        Self { pin: pin.into() }
    }

    /// Put the pin into input mode.
    ///
    /// The internal weak pull-up and pull-down resistors will be enabled according to `pull`.
    #[inline(never)]
    pub fn set_as_input(&mut self, pull: Pull) {
        let r = self.pin.block();
        let pin = self.pin.pin();
        let cfgy = r.cfgx(pin);
        let mut value: Cfgy = Default::default();
        value.set_oty(true);

        match pull {
            Pull::None => {}
            Pull::Up => {
                value.set_puy(true);
            }
            Pull::Down => {
                value.set_pdy(true);
            }
        }
        cfgy.write_value(value);
    }

    /// Put the pin into push-pull output mode.
    ///
    /// The pin level will be whatever was set before (or low by default). If you want it to begin
    /// at a specific level, call `set_high`/`set_low` on the pin first.
    ///
    /// The internal weak pull-up and pull-down resistors will be disabled.
    #[inline(never)]
    pub fn set_as_output(&self) {
        let r = self.pin.block();
        let pin = self.pin.pin();
        let cfgy = r.cfgx(pin);
        let mut value: Cfgy = Default::default();
        value.set_modery(0b_01);

        cfgy.write_value(value);
    }

    #[inline(never)]
    pub fn set_as_input_output_pull(&self, pull: Pull) {
        let r = self.pin.block();
        let pin = self.pin.pin();
        let cfgy = r.cfgx(pin);
        let mut value: Cfgy = Default::default();
        value.set_oty(true);
        value.set_modery(0b_01);
        match pull {
            Pull::None => {}
            Pull::Up => {
                value.set_puy(true);
            }
            Pull::Down => {
                value.set_pdy(true);
            }
        }
        cfgy.write_value(value);
    }

    /// Put the pin into alternate function mode.
    #[inline(never)]
    pub fn set_as_alternate(&self, mode: AltFunc) {
        let r = self.pin.block();
        let pin = self.pin.pin();
        let cfgy = r.cfgx(pin);
        cfgy.modify(|w| {
            w.set_afsely(mode as u8);
            w.set_modery(0b_10);
        });
    }
    /// Put the pin into analog mode.
    #[inline(never)]
    pub fn set_as_analog(&mut self) {
        let r = self.pin.block();
        let pin = self.pin.pin();
        let cfgy = r.cfgx(pin);
        let mut value: Cfgy = Default::default();
        value.set_oty(true);
        value.set_modery(0b_11);

        cfgy.write_value(value);
    }
}