py32f030_hal 0.1.0

Peripheral Hal Crate for Puya's PY32F030 microcontroller
pub(crate) mod sealed {
    use super::super::*;
    use crate::bit::*;
    use crate::pac;

    pub trait Pin {
        fn port_pin(&self) -> u8;

        #[inline]
        fn port(&self) -> GpioPort {
            let port = (self.port_pin() >> 4) as usize;
            assert!(port < 3);
            port.into()
        }

        #[inline]
        fn pin(&self) -> usize {
            (self.port_pin() & 0x0f) as usize
        }

        #[inline]
        fn block(&self) -> &'static pac::gpioa::RegisterBlock {
            match self.port() {
                GpioPort::GPIOA => unsafe { pac::GPIOA::PTR.as_ref().unwrap() },
                GpioPort::GPIOB => unsafe {
                    (pac::GPIOB::PTR as *const pac::gpioa::RegisterBlock)
                        .as_ref()
                        .unwrap()
                },
                GpioPort::GPIOF => unsafe {
                    (pac::GPIOF::PTR as *const pac::gpioa::RegisterBlock)
                        .as_ref()
                        .unwrap()
                },
            }
        }

        #[inline]
        fn set_mode(&self, mode: PinMode) {
            let block = self.block();

            block.moder.modify(|r, w| unsafe {
                w.bits(bit_mask_idx_modify::<2>(
                    self.pin() * 2,
                    r.bits(),
                    mode as u32,
                ))
            })
        }

        #[inline]
        fn set_output_type(&self, output_type: PinOutputType) {
            self.block().otyper.modify(|r, w| unsafe {
                w.bits(bit_mask_idx_modify::<1>(
                    self.pin(),
                    r.bits(),
                    output_type as u32,
                ))
            })
        }

        #[inline]
        fn set_io_type(&self, io_type: PinIoType) {
            let (pushpull, output_type) = io_type.split();
            self.set_push_pull(pushpull);
            self.set_output_type(output_type)
        }

        #[inline]
        fn set_push_pull(&self, push_pull: PinPullUpDown) {
            self.block().pupdr.modify(|r, w| unsafe {
                w.bits(bit_mask_idx_modify::<2>(
                    self.pin() * 2,
                    r.bits(),
                    push_pull as u32,
                ))
            })
        }

        #[inline]
        fn read(&self) -> PinLevel {
            let r = self.block().idr.read().bits();
            bit_mask_idx_get::<1>(self.pin(), r).into()
        }

        #[inline]
        fn write(&self, level: PinLevel) {
            self.block().odr.modify(|r, w| unsafe {
                w.bits(bit_mask_idx_modify::<1>(self.pin(), r.bits(), level as u32))
            })
        }

        #[inline]
        fn lock(&self, _lock: bool) {
            todo!()
        }

        #[inline]
        fn set_af(&self, af: PinAF) {
            let block = self.block();

            if self.pin() < 8 {
                block.afrl.modify(|r, w| unsafe {
                    w.bits(bit_mask_idx_modify::<4>(
                        self.pin() * 4,
                        r.bits(),
                        af as u32,
                    ))
                })
            } else {
                block.afrh.modify(|r, w| unsafe {
                    w.bits(bit_mask_idx_modify::<4>(
                        (self.pin() - 8) * 4,
                        r.bits(),
                        af as u32,
                    ))
                })
            }
        }

        #[inline]
        fn clear(&self) {
            self.block()
                .bsrr
                .write(|w| unsafe { w.bits(bit_mask_idx::<1>(self.pin() + 16)) })
        }

        #[inline]
        fn set(&self) {
            self.block()
                .bsrr
                .write(|w| unsafe { w.bits(bit_mask_idx::<1>(self.pin())) })
        }

        #[inline]
        fn reset(&self) {
            self.block()
                .brr
                .write(|w| unsafe { w.bits(1 << self.pin()) })
        }

        #[inline]
        fn set_speed(&self, speed: PinSpeed) {
            self.block().ospeedr.modify(|r, w| unsafe {
                w.bits(bit_mask_idx_modify::<2>(
                    self.pin() * 2,
                    r.bits(),
                    speed as u32,
                ))
            })
        }
    }
}