Skip to content

Commit e15ae49

Browse files
authored
gpio: add validation for BASE generic
1 parent 0705ad1 commit e15ae49

File tree

2 files changed

+35
-39
lines changed

2 files changed

+35
-39
lines changed

hal/src/dma/mod.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515

1616
mod cr;
1717

18-
use core::{
19-
ops::Mul,
20-
ptr::{read_volatile, write_volatile},
21-
};
18+
use core::ops::Mul;
2219

2320
use super::pac;
2421

@@ -79,53 +76,53 @@ impl<const BASE: usize, const CH: u8> Dma<BASE, CH> {
7976

8077
#[inline]
8178
pub fn flags(&self) -> u8 {
82-
let raw: u32 = unsafe { read_volatile(Self::ISR) };
79+
let raw: u32 = unsafe { Self::ISR.read_volatile() };
8380
((raw >> CH.mul(4)) & 0xF) as u8
8481
}
8582

8683
#[inline]
8784
pub fn clear_flags(&mut self, flags: u8) {
8885
let val: u32 = u32::from(flags & 0xF) << CH.mul(4);
89-
unsafe { write_volatile(Self::IFCR, val) }
86+
unsafe { Self::IFCR.write_volatile(val) }
9087
}
9188

9289
#[inline]
9390
pub fn set_periph_addr(&mut self, pa: u32) {
94-
unsafe { write_volatile(Self::PA, pa) }
91+
unsafe { Self::PA.write_volatile(pa) }
9592
}
9693

9794
#[inline]
9895
pub fn set_mem_addr(&mut self, ma: u32) {
99-
unsafe { write_volatile(Self::MA, ma) }
96+
unsafe { Self::MA.write_volatile(ma) }
10097
}
10198

10299
#[inline]
103100
pub fn set_num_data_xfer(&mut self, ndt: u32) {
104-
unsafe { write_volatile(Self::NDT, ndt) }
101+
unsafe { Self::NDT.write_volatile(ndt) }
105102
}
106103

107104
#[inline]
108105
pub fn set_cr(&mut self, cr: Cr) {
109-
unsafe { write_volatile(Self::CR, cr.raw()) }
106+
unsafe { Self::CR.write_volatile(cr.raw()) }
110107
}
111108

112109
#[inline]
113110
pub fn set_mux_cr_reqid(&mut self, req_id: u8) {
114-
unsafe { write_volatile(Self::MUX_CR, req_id as u32) }
111+
unsafe { Self::MUX_CR.write_volatile(req_id as u32) }
115112
}
116113

117114
/// Returns `true` if the DMA MUX synchronization overrun bit is set for
118115
/// this channel.
119116
#[inline]
120117
pub fn sync_ovr(&self) -> bool {
121-
let csr: u32 = unsafe { read_volatile(MUX_CSR_ADDR as *const u32) };
118+
let csr: u32 = unsafe { (MUX_CSR_ADDR as *const u32).read_volatile() };
122119
csr >> Self::MUX_CH & 0b1 == 0b1
123120
}
124121

125122
#[inline]
126123
#[allow(dead_code)]
127124
pub fn clr_sync_ovr(&mut self) {
128-
unsafe { write_volatile(MUX_CCFR_ADDR as *mut u32, 1 << Self::MUX_CH) };
125+
unsafe { (MUX_CCFR_ADDR as *mut u32).write_volatile(1 << Self::MUX_CH) };
129126
}
130127
}
131128

hal/src/gpio.rs

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! General purpose input-output pins
22
33
use crate::{adc, pac};
4-
use core::ptr::{read_volatile, write_volatile};
54
use cortex_m::interrupt::CriticalSection;
65

76
pub use embedded_hal::digital::v2::PinState;
@@ -55,7 +54,6 @@ pub enum Speed {
5554
#[repr(u8)]
5655
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
5756
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
58-
5957
pub enum Pull {
6058
/// No pull-up, no pull-down.
6159
None = 0b00,
@@ -65,6 +63,10 @@ pub enum Pull {
6563
Down = 0b10,
6664
}
6765

66+
const GPIOA_BASE: usize = 0x4800_0000;
67+
const GPIOB_BASE: usize = 0x4800_0400;
68+
const GPIOC_BASE: usize = 0x4800_0800;
69+
6870
#[derive(Debug)]
6971
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
7072
struct Pin<const BASE: usize, const N: u8> {}
@@ -73,6 +75,10 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
7375
const _NPANIC: () = if N > 15 {
7476
core::panic!("Pin index is out of range")
7577
};
78+
const _BASEPANIC: () = match BASE {
79+
GPIOA_BASE | GPIOB_BASE | GPIOC_BASE => (),
80+
_ => core::panic!("Base address is invalid"),
81+
};
7682

7783
const MODER_R: *const u32 = BASE as *const u32;
7884
const MODER_W: *mut u32 = BASE as *mut u32;
@@ -97,41 +103,41 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
97103

98104
#[inline(always)]
99105
pub(crate) fn set_mode(&mut self, _cs: &CriticalSection, mode: sealed::Mode) {
100-
let mut val: u32 = unsafe { read_volatile(Self::MODER_R) };
106+
let mut val: u32 = unsafe { Self::MODER_R.read_volatile() };
101107
val &= !(0b11 << (N * 2));
102108
val |= (mode as u8 as u32) << (N * 2);
103-
unsafe { write_volatile(Self::MODER_W, val) };
109+
unsafe { Self::MODER_W.write_volatile(val) };
104110
}
105111

106112
#[inline(always)]
107113
pub(crate) fn set_output_type(&mut self, _cs: &CriticalSection, ot: OutputType) {
108-
let mut val: u32 = unsafe { read_volatile(Self::OTYPER_R) };
114+
let mut val: u32 = unsafe { Self::OTYPER_R.read_volatile() };
109115
match ot {
110116
OutputType::PushPull => val &= !(1 << N),
111117
OutputType::OpenDrain => val |= 1 << N,
112118
}
113-
unsafe { write_volatile(Self::OTYPER_W, val) };
119+
unsafe { Self::OTYPER_W.write_volatile(val) };
114120
}
115121

116122
#[inline(always)]
117123
pub(crate) fn set_speed(&mut self, _cs: &CriticalSection, speed: Speed) {
118-
let mut val: u32 = unsafe { read_volatile(Self::OSPEEDR_R) };
124+
let mut val: u32 = unsafe { Self::OSPEEDR_R.read_volatile() };
119125
val &= !(0b11 << (N * 2));
120126
val |= (speed as u8 as u32) << (N * 2);
121-
unsafe { write_volatile(Self::OSPEEDR_W, val) };
127+
unsafe { Self::OSPEEDR_W.write_volatile(val) };
122128
}
123129

124130
#[inline(always)]
125131
pub(crate) fn set_pull(&mut self, _cs: &CriticalSection, pull: Pull) {
126-
let mut val: u32 = unsafe { read_volatile(Self::PUPDR_R) };
132+
let mut val: u32 = unsafe { Self::PUPDR_R.read_volatile() };
127133
val &= !(0b11 << (N * 2));
128134
val |= (pull as u8 as u32) << (N * 2);
129-
unsafe { write_volatile(Self::PUPDR_W, val) };
135+
unsafe { Self::PUPDR_W.write_volatile(val) };
130136
}
131137

132138
#[inline(always)]
133139
pub(crate) fn input_level(&self) -> PinState {
134-
if unsafe { read_volatile(Self::IDR) } & (1 << N) == 0 {
140+
if unsafe { Self::IDR.read_volatile() } & (1 << N) == 0 {
135141
PinState::Low
136142
} else {
137143
PinState::High
@@ -140,7 +146,7 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
140146

141147
#[inline(always)]
142148
pub(crate) fn output_level(&self) -> PinState {
143-
if unsafe { read_volatile(Self::ODR) } & (1 << N) == 0 {
149+
if unsafe { Self::ODR.read_volatile() } & (1 << N) == 0 {
144150
PinState::Low
145151
} else {
146152
PinState::High
@@ -153,16 +159,16 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
153159
PinState::Low => 1 << (N + 16),
154160
PinState::High => 1 << N,
155161
};
156-
unsafe { write_volatile(Self::BSRR, val) }
162+
unsafe { Self::BSRR.write_volatile(val) }
157163
}
158164

159165
#[inline(always)]
160166
pub(crate) fn set_alternate_function(&mut self, cs: &CriticalSection, af: u8) {
161167
self.set_mode(cs, sealed::Mode::Alternate);
162-
let mut val: u32 = unsafe { read_volatile(Self::AF_R) };
168+
let mut val: u32 = unsafe { Self::AF_R.read_volatile() };
163169
val &= !(0b1111 << Self::AF_SHIFT);
164170
val |= (af as u8 as u32) << Self::AF_SHIFT;
165-
unsafe { write_volatile(Self::AF_W, val) };
171+
unsafe { Self::AF_W.write_volatile(val) };
166172
}
167173
}
168174

@@ -442,17 +448,10 @@ pub trait Exti {
442448

443449
/// GPIO pins
444450
pub mod pins {
445-
// Switch to this when avaliable on stable
446-
// https://github.com/rust-lang/rust/issues/51910
447-
// const GPIOA_BASE: usize = pac::GPIOA::PTR as *const _ as usize;
448-
// const GPIOB_BASE: usize = pac::GPIOB::PTR as *const _ as usize;
449-
// const GPIOC_BASE: usize = pac::GPIOC::PTR as *const _ as usize;
450-
451-
const GPIOA_BASE: usize = 0x4800_0000;
452-
const GPIOB_BASE: usize = 0x4800_0400;
453-
const GPIOC_BASE: usize = 0x4800_0800;
454-
455-
use super::{adc, pac, CriticalSection, OutputType, Pin, PinState, Pull, Speed};
451+
use super::{
452+
adc, pac, CriticalSection, OutputType, Pin, PinState, Pull, Speed, GPIOA_BASE, GPIOB_BASE,
453+
GPIOC_BASE,
454+
};
456455

457456
macro_rules! gpio_struct {
458457
($name:ident, $base:expr, $n:expr, $doc:expr) => {

0 commit comments

Comments
 (0)