tinyboot_ch32_hal/gpio/
v0.rs1use core::convert::Infallible;
2
3use crate::Pin;
4
5#[derive(Copy, Clone)]
6pub enum Pull {
7 None,
8 Up,
9 Down,
10}
11
12#[derive(Copy, Clone, PartialEq)]
13pub enum Level {
14 Low,
15 High,
16}
17
18#[derive(Copy, Clone)]
23pub struct PinMode(u8);
24
25impl PinMode {
28 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 {
37 match pull {
38 Pull::Up => Self::INPUT_PULL_UP,
39 Pull::Down => Self::INPUT_PULL_DOWN,
40 Pull::None => Self::INPUT_FLOATING,
41 }
42 }
43}
44
45#[inline(always)]
46pub fn configure(pin: Pin, mode: PinMode) {
47 let regs = pin.gpio_regs();
48 let n = pin.pin_number();
49
50 let shift = n * 4;
51 let mask = !(0xFu32 << shift);
52 let bits = ((mode.0 & 0x0F) as u32) << shift;
53 let prev = regs.cfglr().read().0;
54 regs.cfglr()
55 .write_value(ch32_metapac::gpio::regs::Cfglr(prev & mask | bits));
56
57 if mode.0 & 0xC0 != 0 {
58 let mut outdr = regs.outdr().read();
59 outdr.set_odr(n, mode.0 & 0x80 != 0);
60 regs.outdr().write_value(outdr);
61 }
62}
63
64pub fn set_level(pin: Pin, level: Level) {
65 if level == Level::High {
66 pin.gpio_regs()
67 .bshr()
68 .write(|w| w.0 = 1 << pin.pin_number());
69 } else {
70 pin.gpio_regs().bcr().write(|w| w.0 = 1 << pin.pin_number());
71 }
72}
73
74impl embedded_hal::digital::ErrorType for Pin {
75 type Error = Infallible;
76}
77
78impl embedded_hal::digital::OutputPin for Pin {
79 fn set_high(&mut self) -> Result<(), Self::Error> {
80 set_level(*self, Level::High);
81 Ok(())
82 }
83
84 fn set_low(&mut self) -> Result<(), Self::Error> {
85 set_level(*self, Level::Low);
86 Ok(())
87 }
88}