use anyhow::{Context, Result};
use rppal::gpio::{self, Gpio};
const BOARD_TYPE: u8 = 12;
fn check_board_type() -> Result<bool> {
let type_pin = Gpio::new()?.get(BOARD_TYPE)?.into_input();
Ok(type_pin.is_low())
}
#[derive(Copy, Clone, Debug)]
pub enum PinType {
D0,
D1,
D2,
D3,
D4,
D5,
D6,
D7,
D8,
D9,
D10,
D11,
D12,
D13,
D14,
D15,
D16,
A0,
A1,
A2,
A3,
A4,
A5,
A6,
A7,
P0,
P1,
P2,
P3,
P4,
P5,
P6,
P7,
P8,
P9,
P10,
P11,
P12,
P13,
SW,
User,
Led,
BoardType,
Rst,
BleInt,
BleRst,
McuRst,
}
impl PinType {
fn bcm_num(&self, board_type: bool) -> u8 {
match self {
PinType::D0 => 17,
PinType::D1 => {
if board_type {
18
} else {
4
}
}
PinType::D2 => 27,
PinType::D3 => 22,
PinType::D4 => 23,
PinType::D5 => 24,
PinType::D6 => 25,
PinType::D7 => 4,
PinType::D8 => 5,
PinType::D9 => 6,
PinType::D10 => 12,
PinType::D11 => 13,
PinType::D12 => 19,
PinType::D13 => 16,
PinType::D14 => 26,
PinType::D15 => 20,
PinType::D16 => 21,
PinType::SW => {
if board_type {
19
} else {
25
}
}
PinType::User => {
if board_type {
19
} else {
25
}
}
PinType::Led => 26,
PinType::BoardType => 12,
PinType::Rst => 16,
PinType::BleInt => 13,
PinType::BleRst => 20,
PinType::McuRst => {
if board_type {
21
} else {
5
}
}
_ => panic!("Cannot find bcm number for {:?}", self),
}
}
pub fn is_digital_pin(&self) -> bool {
matches!(
self,
PinType::D0
| PinType::D1
| PinType::D2
| PinType::D3
| PinType::D4
| PinType::D5
| PinType::D6
| PinType::D7
| PinType::D8
| PinType::D9
| PinType::D10
| PinType::D11
| PinType::D12
| PinType::D13
| PinType::D14
| PinType::D15
| PinType::D16
)
}
pub fn is_adc_pin(&self) -> bool {
matches!(
self,
PinType::D0
| PinType::A0
| PinType::A1
| PinType::A2
| PinType::A3
| PinType::A4
| PinType::A5
| PinType::A6
| PinType::A7
)
}
pub fn is_pwm_pin(&self) -> bool {
matches!(
self,
PinType::P0
| PinType::P1
| PinType::P2
| PinType::P3
| PinType::P4
| PinType::P5
| PinType::P6
| PinType::P7
| PinType::P8
| PinType::P9
| PinType::P10
| PinType::P11
| PinType::P12
| PinType::P13
)
}
pub fn adc_channel(&self) -> u8 {
match self {
PinType::A0 => 0,
PinType::A1 => 1,
PinType::A2 => 2,
PinType::A3 => 3,
PinType::A4 => 4,
PinType::A5 => 5,
PinType::A6 => 6,
PinType::A7 => 7,
_ => panic!("pin should be one of PinType::A0-P7, but passed {:?}", self),
}
}
pub fn pwm_channel(&self) -> u8 {
match self {
PinType::P0 => 0,
PinType::P1 => 1,
PinType::P2 => 2,
PinType::P3 => 3,
PinType::P4 => 4,
PinType::P5 => 5,
PinType::P6 => 6,
PinType::P7 => 7,
PinType::P8 => 8,
PinType::P9 => 9,
PinType::P10 => 10,
PinType::P11 => 11,
PinType::P12 => 12,
PinType::P13 => 13,
_ => panic!(
"pin should be one of PinType::P0-P13, but passed {:?}",
self
),
}
}
}
#[derive(Debug)]
pub struct RHPin {
pub gpio_pin: gpio::Pin,
pub bcm_num: u8,
}
impl RHPin {
pub fn new(pin_type: PinType) -> Result<Self> {
let board_type = check_board_type().context("Checking Board type failed")?;
let bcm_num = pin_type.bcm_num(board_type);
let gpio_pin = Gpio::new()?.get(bcm_num)?;
Ok(Self { gpio_pin, bcm_num })
}
}