use core::convert::Infallible;
use crate::{
pac::{self, EXTI, RCC},
rcc_en_reset,
};
#[cfg(not(any(feature = "l5", feature = "g0")))]
use crate::pac::SYSCFG;
use embedded_hal::digital::v2::{InputPin, OutputPin, ToggleableOutputPin};
use cfg_if::cfg_if;
use paste::paste;
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum PinMode {
Input,
Output,
Alt(AltFn),
Analog,
}
impl PinMode {
fn val(&self) -> u8 {
match self {
Self::Input => 0b00,
Self::Output => 0b01,
Self::Alt(_) => 0b10,
Self::Analog => 0b11,
}
}
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum OutputType {
PushPull = 0,
OpenDrain = 1,
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum OutputSpeed {
Low = 0,
Medium = 0b01,
High = 0b11,
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum Pull {
Floating = 0b00,
Up = 0b01,
Dn = 0b10,
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum PinState {
High = 1,
Low = 0,
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum CfgLock {
NotLocked = 0,
Locked = 1,
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum AltFn {
Af0 = 0b0000,
Af1 = 0b0001,
Af2 = 0b0010,
Af3 = 0b0011,
Af4 = 0b0100,
Af5 = 0b0101,
Af6 = 0b0110,
Af7 = 0b0111,
Af8 = 0b1000,
Af9 = 0b1001,
Af10 = 0b1010,
Af11 = 0b1011,
Af12 = 0b1100,
Af13 = 0b1101,
Af14 = 0b1110,
Af15 = 0b1111,
}
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum ResetState {
NoAction = 0,
Reset = 1,
}
#[derive(Copy, Clone)]
pub enum PortLetter {
A,
B,
C,
D,
E,
F,
G,
H,
}
impl PortLetter {
fn cr_val(&self) -> u8 {
match self {
Self::A => 0,
Self::B => 1,
Self::C => 2,
Self::D => 3,
Self::E => 4,
Self::F => 5,
Self::G => 6,
Self::H => 7,
}
}
}
#[derive(Copy, Clone)]
pub enum PinNum {
P0,
P1,
P2,
P3,
P4,
P5,
P6,
P7,
P8,
P9,
P10,
P11,
P12,
P13,
P14,
P15,
}
#[derive(Copy, Clone, Debug)]
pub enum Edge {
Rising,
Falling,
}
macro_rules! make_port {
($Port:ident, $port:ident) => {
paste! {
pub struct [<Gpio $Port>] {
pub regs: pac::[<GPIO $Port>],
}
impl [<Gpio $Port>] {
pub fn new(regs: pac::[<GPIO $Port>], rcc: &mut RCC) -> Self {
cfg_if! {
if #[cfg(feature = "f3")] {
rcc_en_reset!(ahb1, [<iop $port>], rcc);
} else if #[cfg(feature = "h7")] {
rcc.ahb4enr.modify(|_, w| w.[<gpio $port en>]().set_bit());
rcc.ahb4rstr.modify(|_, w| w.[<gpio $port rst>]().set_bit());
rcc.ahb4rstr.modify(|_, w| w.[<gpio $port rst>]().clear_bit());
} else if #[cfg(feature = "f4")] {
rcc_en_reset!(ahb1, [<gpio $port>], rcc);
} else if #[cfg(feature = "g0")] {
rcc.iopenr.modify(|_, w| w.[<iop $port en>]().set_bit());
rcc.ioprstr.modify(|_, w| w.[<iop $port rst>]().set_bit());
rcc.ioprstr.modify(|_, w| w.[<iop $port rst>]().clear_bit());
} else {
rcc_en_reset!(ahb2, [<gpio $port>], rcc);
}
}
Self { regs }
}
pub fn new_pin(&mut self, pin: PinNum, mode: PinMode) -> [<Gpio $Port Pin>] {
let mut result = [<Gpio $Port Pin>] {
port: PortLetter::[<$Port>],
pin,
};
result.mode(mode, &mut self.regs);
result
}
}
}
};
}
macro_rules! set_field {
($pin:expr, $regs:expr, $reg:ident, $field:ident, $bit:ident, $val:expr, [$($num:expr),+]) => {
paste! {
unsafe {
match $pin {
$(
PinNum::[<P $num>] => $regs.$reg.modify(|_, w| w.[<$field $num>]().$bit($val)),
)+
}
}
}
}
}
macro_rules! set_exti {
($pin:expr, $exti:expr, $syscfg:expr, $trigger:expr, $val:expr, [$(($num:expr, $crnum:expr)),+]) => {
paste! {
match $pin {
$(
PinNum::[<P $num>] => {
cfg_if! {
if #[cfg(all(feature = "h7", not(any(feature = "h747cm4", feature = "h747cm7"))))] {
$exti.cpuimr1.modify(|_, w| w.[<mr $num>]().unmasked());
} else if #[cfg(any(feature = "h747cm4", feature = "h747cm7"))] {
$exti.c1imr1.modify(|_, w| w.[<mr $num>]().unmasked());
}else if #[cfg(feature = "g4")] {
$exti.imr1.modify(|_, w| w.[<im $num>]().unmasked());
} else {
$exti.imr1.modify(|_, w| w.[<mr $num>]().unmasked());
}
}
cfg_if! {
if #[cfg(feature = "g4")] {
$exti.rtsr1.modify(|_, w| w.[<rt $num>]().bit($trigger));
$exti.ftsr1.modify(|_, w| w.[<ft $num>]().bit(!$trigger));
} else {
$exti.rtsr1.modify(|_, w| w.[<tr $num>]().bit($trigger));
$exti.ftsr1.modify(|_, w| w.[<tr $num>]().bit(!$trigger));
}
}
$syscfg
.[<exticr $crnum>]
.modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
}
)+
}
}
}
}
#[cfg(feature = "f4")]
macro_rules! set_exti_f4 {
($pin:expr, $exti:expr, $syscfg:expr, $trigger:expr, $val:expr, [$(($num:expr, $crnum:expr)),+]) => {
paste! {
match $pin {
$(
PinNum::[<P $num>] => {
$exti.imr.modify(|_, w| w.[<mr $num>]().unmasked());
$exti.rtsr.modify(|_, w| w.[<tr $num>]().bit($trigger));
$exti.ftsr.modify(|_, w| w.[<tr $num>]().bit(!$trigger));
$syscfg
.[<exticr $crnum>]
.modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
}
)+
}
}
}
}
#[cfg(feature = "l5")]
macro_rules! set_exti_l5 {
($pin:expr, $exti:expr, $trigger:expr, $val:expr, [$(($num:expr, $crnum:expr, $num2:expr)),+]) => {
paste! {
match $pin {
$(
PinNum::[<P $num>] => {
$exti.imr1.modify(|_, w| w.[<im $num>]().set_bit());
$exti.rtsr1.modify(|_, w| w.[<rt $num>]().bit($trigger));
$exti.ftsr1.modify(|_, w| w.[<ft $num>]().bit(!$trigger));
$exti
.[<exticr $crnum>]
.modify(|_, w| unsafe { w.[<exti $num2>]().bits($val) });
}
)+
}
}
}
}
#[cfg(feature = "g0")]
macro_rules! set_exti_g0 {
($pin:expr, $exti:expr, $trigger:expr, $val:expr, [$(($num:expr, $crnum:expr, $num2:expr)),+]) => {
paste! {
match $pin {
$(
PinNum::[<P $num>] => {
$exti.imr1.modify(|_, w| w.[<im $num>]().set_bit());
$exti.rtsr1.modify(|_, w| w.[<tr $num>]().bit($trigger));
$exti.ftsr1.modify(|_, w| w.[<tr $num>]().bit(!$trigger));
$exti
.[<exticr $crnum>]
.modify(|_, w| unsafe { w.[<exti $num2>]().bits($val) });
}
)+
}
}
}
}
macro_rules! set_alt {
($pin:expr, $regs:expr, $field_af:ident, $val:expr, [$(($num:expr, $lh:ident)),+]) => {
paste! {
unsafe {
match $pin {
$(
PinNum::[<P $num>] => {
$regs.moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(AltFn::Af0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7"))]
$regs.[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val as u8));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7")))]
$regs.[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val as u8));
}
)+
}
}
}
}
}
macro_rules! make_pin {
($Port:ident) => {
paste! {
pub struct [<Gpio $Port Pin>] {
pub port: PortLetter,
pub pin: PinNum,
}
impl [<Gpio $Port Pin>] {
pub fn mode(&mut self, value: PinMode, regs: &mut pac::[<GPIO $Port>]) {
set_field!(self.pin, regs, moder, moder, bits, value.val(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
if let PinMode::Alt(alt) = value {
self.alt_fn(alt, regs);
}
}
pub fn output_type(&mut self, value: OutputType, regs: &mut pac::[<GPIO $Port>]) {
set_field!(self.pin, regs, otyper, ot, bit, value as u8 != 0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
pub fn output_speed(&mut self, value: OutputSpeed, regs: &mut pac::[<GPIO $Port>]) {
set_field!(self.pin, regs, ospeedr, ospeedr, bits, value as u8, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
pub fn pull(&mut self, value: Pull, regs: &mut pac::[<GPIO $Port>]) {
set_field!(self.pin, regs, pupdr, pupdr, bits, value as u8, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
pub fn output_data(&mut self, value: PinState, regs: &mut pac::[<GPIO $Port>]) {
set_field!(self.pin, regs, odr, odr, bit, value as u8 != 0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
#[cfg(not(feature = "f373"))]
pub fn cfg_lock(&mut self, value: CfgLock, regs: &mut pac::[<GPIO $Port>]) {
set_field!(self.pin, regs, lckr, lck, bit, value as u8 != 0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
pub fn input_data(&mut self, regs: &mut pac::[<GPIO $Port>]) -> PinState {
let val = match self.pin {
PinNum::P0 => regs.idr.read().idr0().bit(),
PinNum::P1 => regs.idr.read().idr1().bit(),
PinNum::P2 => regs.idr.read().idr2().bit(),
PinNum::P3 => regs.idr.read().idr3().bit(),
PinNum::P4 => regs.idr.read().idr4().bit(),
PinNum::P5 => regs.idr.read().idr5().bit(),
PinNum::P6 => regs.idr.read().idr6().bit(),
PinNum::P7 => regs.idr.read().idr7().bit(),
PinNum::P8 => regs.idr.read().idr8().bit(),
PinNum::P9 => regs.idr.read().idr9().bit(),
PinNum::P10 => regs.idr.read().idr10().bit(),
PinNum::P11 => regs.idr.read().idr11().bit(),
PinNum::P12 => regs.idr.read().idr12().bit(),
PinNum::P13 => regs.idr.read().idr13().bit(),
PinNum::P14 => regs.idr.read().idr14().bit(),
PinNum::P15 => regs.idr.read().idr15().bit(),
};
if val {
PinState::High
} else {
PinState::Low
}
}
pub fn set_state(&mut self, value: PinState, regs: &mut pac::[<GPIO $Port>]) {
let offset = match value {
PinState::Low => 16,
PinState::High => 0,
};
unsafe {
match self.pin {
PinNum::P0 => regs.bsrr.write(|w| w.bits(1 << (offset + 0))),
PinNum::P1 => regs.bsrr.write(|w| w.bits(1 << (offset + 1))),
PinNum::P2 => regs.bsrr.write(|w| w.bits(1 << (offset + 2))),
PinNum::P3 => regs.bsrr.write(|w| w.bits(1 << (offset + 3))),
PinNum::P4 => regs.bsrr.write(|w| w.bits(1 << (offset + 4))),
PinNum::P5 => regs.bsrr.write(|w| w.bits(1 << (offset + 5))),
PinNum::P6 => regs.bsrr.write(|w| w.bits(1 << (offset + 6))),
PinNum::P7 => regs.bsrr.write(|w| w.bits(1 << (offset + 7))),
PinNum::P8 => regs.bsrr.write(|w| w.bits(1 << (offset + 8))),
PinNum::P9 => regs.bsrr.write(|w| w.bits(1 << (offset + 9))),
PinNum::P10 => regs.bsrr.write(|w| w.bits(1 << (offset + 10))),
PinNum::P11 => regs.bsrr.write(|w| w.bits(1 << (offset + 11))),
PinNum::P12 => regs.bsrr.write(|w| w.bits(1 << (offset + 12))),
PinNum::P13 => regs.bsrr.write(|w| w.bits(1 << (offset + 13))),
PinNum::P14 => regs.bsrr.write(|w| w.bits(1 << (offset + 14))),
PinNum::P15 => regs.bsrr.write(|w| w.bits(1 << (offset + 15))),
};
}
}
fn alt_fn(&mut self, value: AltFn, regs: &mut pac::[<GPIO $Port>]) {
cfg_if! {
if #[cfg(any(feature = "l5", feature = "g0"))] {
set_alt!(self.pin, regs, afsel, value, [(0, l), (1, l), (2, l),
(3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
(13, h), (14, h), (15, h)])
} else if #[cfg(feature = "h7")] {
set_alt!(self.pin, regs, afr, value, [(0, l), (1, l), (2, l),
(3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
(13, h), (14, h), (15, h)])
} else {
set_alt!(self.pin, regs, afr, value, [(0, l), (1, l), (2, l),
(3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
(13, h), (14, h), (15, h)])
}
}
}
#[cfg(not(any(feature = "l4", feature = "h7", feature = "f4")))]
pub fn reset(&mut self, value: ResetState, regs: &mut pac::[<GPIO $Port>]) {
let offset = match value {
ResetState::NoAction => 16,
ResetState::Reset => 0,
};
unsafe {
match self.pin {
PinNum::P0 => regs.brr.write(|w| w.bits(1 << (offset + 0))),
PinNum::P1 => regs.brr.write(|w| w.bits(1 << (offset + 1))),
PinNum::P2 => regs.brr.write(|w| w.bits(1 << (offset + 2))),
PinNum::P3 => regs.brr.write(|w| w.bits(1 << (offset + 3))),
PinNum::P4 => regs.brr.write(|w| w.bits(1 << (offset + 4))),
PinNum::P5 => regs.brr.write(|w| w.bits(1 << (offset + 5))),
PinNum::P6 => regs.brr.write(|w| w.bits(1 << (offset + 6))),
PinNum::P7 => regs.brr.write(|w| w.bits(1 << (offset + 7))),
PinNum::P8 => regs.brr.write(|w| w.bits(1 << (offset + 8))),
PinNum::P9 => regs.brr.write(|w| w.bits(1 << (offset + 9))),
PinNum::P10 => regs.brr.write(|w| w.bits(1 << (offset + 10))),
PinNum::P11 => regs.brr.write(|w| w.bits(1 << (offset + 11))),
PinNum::P12 => regs.brr.write(|w| w.bits(1 << (offset + 12))),
PinNum::P13 => regs.brr.write(|w| w.bits(1 << (offset + 13))),
PinNum::P14 => regs.brr.write(|w| w.bits(1 << (offset + 14))),
PinNum::P15 => regs.brr.write(|w| w.bits(1 << (offset + 15))),
};
}
}
cfg_if! {
if #[cfg(any(feature = "g0", feature = "l5"))] {
pub fn enable_interrupt(&mut self, edge: Edge, exti: &mut EXTI) {
let rise_trigger = match edge {
Edge::Rising => {
true
}
Edge::Falling => {
false
}
};
#[cfg(feature = "g0")]
set_exti_g0!(self.pin, exti, rise_trigger, self.port.cr_val(), [(0, 1, 0_7), (1, 1, 0_7), (2, 1, 0_7),
(3, 1, 0_7), (4, 2, 0_7), (5, 2, 0_7), (6, 2, 0_7), (7, 2, 0_7), (8, 3, 8_15),
(9, 3, 8_15), (10, 3, 8_15), (11, 3, 8_15), (12, 4, 8_15),
(13, 4, 8_15), (14, 4, 8_15), (15, 4, 8_15)]);
#[cfg(feature = "l5")]
set_exti_l5!(self.pin, exti, rise_trigger, self.port.cr_val(), [(0, 1, 0_7), (1, 1, 0_7), (2, 1, 0_7),
(3, 1, 0_7), (4, 2, 0_7), (5, 2, 0_7), (6, 2, 0_7), (7, 2, 0_7), (8, 3, 8_15),
(9, 3, 8_15), (10, 3, 8_15), (11, 3, 8_15), (12, 4, 8_15),
(13, 4, 8_15), (14, 4, 8_15), (15, 4, 8_15)]);
}
} else if #[cfg(not(feature = "f373"))] {
pub fn enable_interrupt(&mut self, edge: Edge, exti: &mut EXTI, syscfg: &mut SYSCFG) {
let rise_trigger = match edge {
Edge::Rising => {
true
}
Edge::Falling => {
false
}
};
cfg_if! {
if #[cfg(feature = "f4")] {
set_exti_f4!(self.pin, exti, syscfg, rise_trigger, self.port.cr_val(), [(0, 1), (1, 1), (2, 1),
(3, 1), (4, 2), (5, 2), (6, 2), (7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 4),
(13, 4), (14, 4), (15, 4)])
} else {
set_exti!(self.pin, exti, syscfg, rise_trigger, self.port.cr_val(), [(0, 1), (1, 1), (2, 1),
(3, 1), (4, 2), (5, 2), (6, 2), (7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 4),
(13, 4), (14, 4), (15, 4)])
}
}
}
}
}
pub fn is_high(&self) -> bool {
unsafe {
match self.pin {
PinNum::P0 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr0().bit(),
PinNum::P1 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr1().bit(),
PinNum::P2 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr2().bit(),
PinNum::P3 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr3().bit(),
PinNum::P4 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr4().bit(),
PinNum::P5 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr5().bit(),
PinNum::P6 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr6().bit(),
PinNum::P7 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr7().bit(),
PinNum::P8 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr8().bit(),
PinNum::P9 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr9().bit(),
PinNum::P10 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr10().bit(),
PinNum::P11 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr11().bit(),
PinNum::P12 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr12().bit(),
PinNum::P13 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr13().bit(),
PinNum::P14 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr14().bit(),
PinNum::P15 => (*pac::[<GPIO $Port>]::ptr()).idr.read().idr15().bit(),
}
}
}
pub fn is_low(&self) -> bool {
!self.is_high()
}
pub fn set_high(&self) {
let offset = 0;
unsafe {
match self.pin {
PinNum::P0 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 0))),
PinNum::P1 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 1))),
PinNum::P2 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 2))),
PinNum::P3 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 3))),
PinNum::P4 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 4))),
PinNum::P5 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 5))),
PinNum::P6 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 6))),
PinNum::P7 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 7))),
PinNum::P8 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 8))),
PinNum::P9 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 9))),
PinNum::P10 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 10))),
PinNum::P11 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 11))),
PinNum::P12 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 12))),
PinNum::P13 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 13))),
PinNum::P14 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 14))),
PinNum::P15 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 15))),
}
}
}
pub fn set_low(&self) {
let offset = 16;
unsafe {
match self.pin {
PinNum::P0 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 0))),
PinNum::P1 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 1))),
PinNum::P2 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 2))),
PinNum::P3 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 3))),
PinNum::P4 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 4))),
PinNum::P5 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 5))),
PinNum::P6 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 6))),
PinNum::P7 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 7))),
PinNum::P8 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 8))),
PinNum::P9 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 9))),
PinNum::P10 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 10))),
PinNum::P11 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 11))),
PinNum::P12 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 12))),
PinNum::P13 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 13))),
PinNum::P14 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 14))),
PinNum::P15 => (*pac::[<GPIO $Port>]::ptr()).bsrr.write(|w| w.bits(1 << (offset + 15))),
}
}
}
}
impl InputPin for [<Gpio $Port Pin>] {
type Error = Infallible;
fn is_high(&self) -> Result<bool, Self::Error> {
Ok([<Gpio $Port Pin>]::is_high(self))
}
fn is_low(&self) -> Result<bool, Self::Error> {
Ok([<Gpio $Port Pin>]::is_low(self))
}
}
impl OutputPin for [<Gpio $Port Pin>] {
type Error = Infallible;
fn set_low(&mut self) -> Result<(), Self::Error> {
[<Gpio $Port Pin>]::set_low(self);
Ok(())
}
fn set_high(&mut self) -> Result<(), Self::Error> {
[<Gpio $Port Pin>]::set_high(self);
Ok(())
}
}
impl ToggleableOutputPin for [<Gpio $Port Pin>] {
type Error = Infallible;
fn toggle(&mut self) -> Result<(), Self::Error> {
if self.is_high() {
[<Gpio $Port Pin>]::set_low(self);
} else {
[<Gpio $Port Pin>]::set_high(self);
}
Ok(())
}
}
}
};
}
make_port!(A, a);
make_port!(B, b);
make_port!(C, c);
make_pin!(A);
make_pin!(B);
make_pin!(C);
cfg_if! {
if #[cfg(not(any(feature = "f410")))] {
make_port! (D, d);
make_pin!(D);
}
}
cfg_if! {
if #[cfg(not(any(feature = "f301", feature = "f3x4", feature = "f410", feature = "g0")))] {
make_port!(E, e);
make_pin!(E);
}
}
cfg_if! {
if #[cfg(not(any(feature = "f401", feature = "f410", feature = "f411", feature = "l4x1", feature = "l4x2", feature = "l4x3")))] {
make_port!(F, f);
make_pin!(F);
}
}
cfg_if! {
if #[cfg(not(any(
feature = "f373",
feature = "f301",
feature = "f3x4",
feature = "f410",
feature = "l4",
feature = "g0",
feature = "g4"
)))] {
make_port!(H, h);
make_pin!(H);
}
}