Skip to content

Commit 1855486

Browse files
committed
rcc enable
1 parent 35e66be commit 1855486

File tree

4 files changed

+317
-2
lines changed

4 files changed

+317
-2
lines changed

src/i2c.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use crate::hal::blocking::i2c::{Read, Write, WriteRead};
66
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x2", feature = "stm32l4x6"))]
77
use crate::pac::I2C4;
88
use crate::pac::{i2c1, I2C1, I2C2, I2C3};
9+
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x2", feature = "stm32l4x6"))]
10+
use crate::rcc::APB1R2;
911

10-
use crate::rcc::{Clocks, APB1R1, APB1R2};
12+
use crate::rcc::{Clocks, APB1R1};
1113
use crate::time::Hertz;
1214
use cast::{u16, u8};
1315
use core::ops::Deref;

src/rcc.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::flash::ACR;
77
use crate::pwr::Pwr;
88
use crate::time::Hertz;
99

10+
mod enable;
11+
1012
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1113
pub enum MsiFreq {
1214
#[doc = "range 0 around 100 kHz"]
@@ -194,16 +196,19 @@ macro_rules! bus_struct {
194196
Self { _0: () }
195197
}
196198

199+
#[allow(unused)]
197200
pub(crate) fn enr(&self) -> &rcc::$EN {
198201
// NOTE(unsafe) this proxy grants exclusive access to this register
199202
unsafe { &(*RCC::ptr()).$en }
200203
}
201204

205+
#[allow(unused)]
202206
pub(crate) fn smenr(&self) -> &rcc::$SMEN {
203207
// NOTE(unsafe) this proxy grants exclusive access to this register
204208
unsafe { &(*RCC::ptr()).$smen }
205209
}
206210

211+
#[allow(unused)]
207212
pub(crate) fn rstr(&self) -> &rcc::$RST {
208213
// NOTE(unsafe) this proxy grants exclusive access to this register
209214
unsafe { &(*RCC::ptr()).$rst }
@@ -222,6 +227,73 @@ bus_struct! {
222227
APB2 => (APB2ENR, apb2enr, APB2SMENR, apb2smenr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
223228
}
224229

230+
/// Bus associated to peripheral
231+
pub trait RccBus: crate::Sealed {
232+
/// Bus type;
233+
type Bus;
234+
}
235+
236+
/// Enable/disable peripheral
237+
pub trait Enable: RccBus {
238+
/// Enables peripheral
239+
fn enable(bus: &mut Self::Bus);
240+
241+
/// Disables peripheral
242+
fn disable(bus: &mut Self::Bus);
243+
244+
/// Check if peripheral enabled
245+
fn is_enabled() -> bool;
246+
247+
/// Check if peripheral disabled
248+
fn is_disabled() -> bool;
249+
250+
/// # Safety
251+
///
252+
/// Enables peripheral. Takes access to RCC internally
253+
unsafe fn enable_unchecked();
254+
255+
/// # Safety
256+
///
257+
/// Disables peripheral. Takes access to RCC internally
258+
unsafe fn disable_unchecked();
259+
}
260+
261+
/// Enable/disable peripheral in sleep mode
262+
pub trait SMEnable: RccBus {
263+
/// Enables peripheral
264+
fn enable_in_sleep_mode(bus: &mut Self::Bus);
265+
266+
/// Disables peripheral
267+
fn disable_in_sleep_mode(bus: &mut Self::Bus);
268+
269+
/// Check if peripheral enabled
270+
fn is_enabled_in_sleep_mode() -> bool;
271+
272+
/// Check if peripheral disabled
273+
fn is_disabled_in_sleep_mode() -> bool;
274+
275+
/// # Safety
276+
///
277+
/// Enables peripheral. Takes access to RCC internally
278+
unsafe fn enable_in_sleep_mode_unchecked();
279+
280+
/// # Safety
281+
///
282+
/// Disables peripheral. Takes access to RCC internally
283+
unsafe fn disable_in_sleep_mode_unchecked();
284+
}
285+
286+
/// Reset peripheral
287+
pub trait Reset: RccBus {
288+
/// Resets peripheral
289+
fn reset(bus: &mut Self::Bus);
290+
291+
/// # Safety
292+
///
293+
/// Resets peripheral. Takes access to RCC internally
294+
unsafe fn reset_unchecked();
295+
}
296+
225297
#[derive(Debug, PartialEq)]
226298
/// HSE Configuration
227299
struct HseConfig {

src/rcc/enable.rs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
use super::*;
2+
3+
macro_rules! bus_enable {
4+
($PER:ident => $en:ident) => {
5+
impl Enable for crate::pac::$PER {
6+
#[inline(always)]
7+
fn enable(bus: &mut Self::Bus) {
8+
bus.enr().modify(|_, w| w.$en().set_bit());
9+
// Stall the pipeline to work around erratum 2.1.13 (DM00037591)
10+
cortex_m::asm::dsb(); // TODO: check if needed
11+
}
12+
#[inline(always)]
13+
fn disable(bus: &mut Self::Bus) {
14+
bus.enr().modify(|_, w| w.$en().clear_bit());
15+
}
16+
#[inline(always)]
17+
fn is_enabled() -> bool {
18+
Self::Bus::new().enr().read().$en().bit_is_set()
19+
}
20+
#[inline(always)]
21+
fn is_disabled() -> bool {
22+
Self::Bus::new().enr().read().$en().bit_is_clear()
23+
}
24+
#[inline(always)]
25+
unsafe fn enable_unchecked() {
26+
Self::enable(&mut Self::Bus::new());
27+
}
28+
#[inline(always)]
29+
unsafe fn disable_unchecked() {
30+
Self::disable(&mut Self::Bus::new());
31+
}
32+
}
33+
};
34+
}
35+
36+
macro_rules! bus_smenable {
37+
($PER:ident => $smen:ident) => {
38+
impl SMEnable for crate::pac::$PER {
39+
#[inline(always)]
40+
fn enable_in_sleep_mode(bus: &mut Self::Bus) {
41+
bus.smenr().modify(|_, w| w.$smen().set_bit());
42+
// Stall the pipeline to work around erratum 2.1.13 (DM00037591)
43+
cortex_m::asm::dsb();
44+
}
45+
#[inline(always)]
46+
fn disable_in_sleep_mode(bus: &mut Self::Bus) {
47+
bus.smenr().modify(|_, w| w.$smen().clear_bit());
48+
}
49+
#[inline(always)]
50+
fn is_enabled_in_sleep_mode() -> bool {
51+
Self::Bus::new().smenr().read().$smen().bit_is_set()
52+
}
53+
#[inline(always)]
54+
fn is_disabled_in_sleep_mode() -> bool {
55+
Self::Bus::new().smenr().read().$smen().bit_is_clear()
56+
}
57+
#[inline(always)]
58+
unsafe fn enable_in_sleep_mode_unchecked() {
59+
Self::enable(&mut Self::Bus::new());
60+
}
61+
#[inline(always)]
62+
unsafe fn disable_in_sleep_mode_unchecked() {
63+
Self::disable(&mut Self::Bus::new());
64+
}
65+
}
66+
};
67+
}
68+
macro_rules! bus_reset {
69+
($PER:ident => $rst:ident) => {
70+
impl Reset for crate::pac::$PER {
71+
#[inline(always)]
72+
fn reset(bus: &mut Self::Bus) {
73+
bus.rstr().modify(|_, w| w.$rst().set_bit());
74+
bus.rstr().modify(|_, w| w.$rst().clear_bit());
75+
}
76+
#[inline(always)]
77+
unsafe fn reset_unchecked() {
78+
Self::reset(&mut Self::Bus::new());
79+
}
80+
}
81+
};
82+
}
83+
84+
macro_rules! bus {
85+
($($PER:ident => ($busX:ty, $($en:ident)?, $($smen:ident)?, $($rst:ident)?),)+) => {
86+
$(
87+
impl crate::Sealed for crate::pac::$PER {}
88+
impl RccBus for crate::pac::$PER {
89+
type Bus = $busX;
90+
}
91+
$(bus_enable!($PER => $en);)?
92+
$(bus_smenable!($PER => $smen);)?
93+
$(bus_reset!($PER => $rst);)?
94+
)+
95+
};
96+
}
97+
98+
bus! {
99+
DMA1 => (AHB1, dma1en, dma1smen, dma1rst), // 0
100+
DMA2 => (AHB1, dma2en, dma2smen, dma2rst), // 1
101+
FLASH => (AHB1, flashen, flashsmen, flashrst), // 8
102+
CRC => (AHB1, crcen, crcsmen, crcrst), // 12
103+
TSC => (AHB1, tscen, tscsmen, tscrst), // 16
104+
105+
GPIOA => (AHB2, gpioaen, gpioasmen, gpioarst), // 0
106+
GPIOB => (AHB2, gpioben, gpiobsmen, gpiobrst), // 1
107+
GPIOC => (AHB2, gpiocen, gpiocsmen, gpiocrst), // 2
108+
GPIOD => (AHB2, gpioden, gpiodsmen, gpiodrst), // 3
109+
GPIOE => (AHB2, gpioeen, gpioesmen, gpioerst), // 4
110+
GPIOH => (AHB2, gpiohen, gpiohsmen, gpiohrst), // 7
111+
ADC1 => (AHB2, adcen, adcfssmen, adcrst), // 13
112+
AES => (AHB2, aesen, aessmen, aesrst), // 16
113+
RNG => (AHB2, rngen, rngsmen, rngrst), // 18
114+
115+
TIM2 => (APB1R1, tim2en, tim2smen, tim2rst), // 0
116+
TIM6 => (APB1R1, tim6en, tim6smen, tim6rst), // 4
117+
TIM7 => (APB1R1, tim7en, tim7smen, tim7rst), // 5
118+
LCD => (APB1R1, lcden, lcdsmen, lcdrst), // 9
119+
WWDG => (APB1R1, wwdgen, wwdgsmen,), // 11
120+
SPI2 => (APB1R1, spi2en, spi2smen, spi2rst), // 14
121+
SPI3 => (APB1R1, spi3en, sp3smen, spi3rst), // 15 // TODO: fix typo
122+
USART2 => (APB1R1, usart2en, usart2smen, usart2rst), // 17
123+
USART3 => (APB1R1, usart3en, usart3smen, usart3rst), // 18
124+
I2C1 => (APB1R1, i2c1en, i2c1smen, i2c1rst), // 21
125+
I2C2 => (APB1R1, i2c2en, i2c2smen, i2c2rst), // 22
126+
I2C3 => (APB1R1, i2c3en, i2c3smen, i2c3rst), // 23
127+
CAN1 => (APB1R1, can1en, can1smen, can1rst), // 25
128+
PWR => (APB1R1, pwren, pwrsmen, pwrrst), // 28
129+
OPAMP => (APB1R1, opampen, opampsmen, opamprst), // 30
130+
LPTIM1 => (APB1R1, lptim1en, lptim1smen, lptim1rst), // 31
131+
132+
LPUART1 => (APB1R2, lpuart1en, lpuart1smen, lpuart1rst), // 0
133+
SWPMI1 => (APB1R2, swpmi1en, swpmi1smen, swpmi1rst), // 2
134+
LPTIM2 => (APB1R2, lptim2en, lptim2smen, lptim2rst), // 5
135+
SYSCFG => (APB2, syscfgen, syscfgsmen, syscfgrst), // 0
136+
FIREWALL => (APB2, firewallen,,), // 7
137+
TIM1 => (APB2, tim1en, tim1smen, tim1rst), // 11
138+
SPI1 => (APB2, spi1en, spi1smen, spi1rst), // 12
139+
USART1 => (APB2, usart1en, usart1smen, usart1rst), // 14
140+
TIM15 => (APB2, tim15en, tim15smen, tim15rst), // 16
141+
TIM16 => (APB2, tim16en, tim16smen, tim16rst), // 17
142+
SAI1 => (APB2, sai1en, sai1smen, sai1rst), // 21
143+
}
144+
145+
#[cfg(any(feature = "stm32l4x5", feature = "stm32l4x6"))]
146+
bus! {
147+
GPIOF => (AHB2, gpiofen, gpiofsmen, gpiofrst), // 5
148+
GPIOG => (AHB2, gpiogen, gpiogsmen, gpiogrst), // 6
149+
150+
FMC => (AHB3, fmcen, fmcsmen, fmcrst), // 0
151+
152+
TIM3 => (APB1R1, tim3en, tim3smen, tim3rst), // 1
153+
TIM4 => (APB1R1, tim4en, tim4smen, tim4rst), // 2
154+
TIM5 => (APB1R1, tim5en, tim5smen, tim5rst), // 3
155+
UART4 => (APB1R1, uart4en, uart4smen, uart4rst), // 19
156+
UART5 => (APB1R1, uart5en, uart5smen, uart5rst), // 20
157+
158+
TIM8 => (APB2, tim8en, tim8smen, tim8rst), // 13
159+
TIM17 => (APB2, tim17en, tim17smen, tim17rst), // 18
160+
SAI2 => (APB2, sai2en, sai2smen, sai2rst), // 22
161+
}
162+
163+
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x2"))]
164+
bus! {
165+
UART4 => (APB1R1, uart4en, uart4smen, usart4rst), // 19 // TODO: fix typo
166+
167+
I2C4 => (APB1R2, i2c4en,, i2c4rst), // 1 // TODO: fix absent
168+
}
169+
170+
#[cfg(any(
171+
feature = "stm32l4x1",
172+
feature = "stm32l4x2",
173+
feature = "stm32l4x3",
174+
feature = "stm32l4x5"
175+
))]
176+
bus! {
177+
DAC1 => (APB1R1, dac1en, dac1smen, dac1rst), // 29
178+
179+
SDMMC => (APB2, sdmmcen, sdmmcsmen, sdmmcrst), // 10
180+
}
181+
182+
#[cfg(any(
183+
feature = "stm32l4x1",
184+
feature = "stm32l4x2",
185+
feature = "stm32l4x5",
186+
feature = "stm32l4x6"
187+
))]
188+
bus! {
189+
ADC2 => (AHB2, adcen, adcfssmen, adcrst), // 13
190+
QUADSPI => (AHB3, qspien, qspismen, qspirst), // 8
191+
}
192+
193+
#[cfg(any(
194+
feature = "stm32l4x1",
195+
feature = "stm32l4x2",
196+
feature = "stm32l4x3",
197+
feature = "stm32l4x6"
198+
))]
199+
bus! {
200+
CRS => (APB1R1, crsen,,), // 24 // TODO: fix absent
201+
}
202+
203+
#[cfg(any(feature = "stm32l4x2", feature = "stm32l4x3"))]
204+
bus! {
205+
USB => (APB1R1, usbfsen, usbfssmen, usbfsrst), // 26
206+
}
207+
#[cfg(feature = "stm32l4x1")]
208+
bus! {
209+
TIM3 => (APB1R1, tim3en,,), // 1 // TODO: absent smen, rst
210+
USB_FS => (APB1R1, usbf, usbfssmen, usbfsrst), // 26 // TODO: fix typo
211+
}
212+
213+
#[cfg(feature = "stm32l4x2")]
214+
bus! {
215+
TIM3 => (APB1R1, tim3en,, tim3rst), // 1 // TODO: fix absent
216+
}
217+
218+
#[cfg(feature = "stm32l4x5")]
219+
bus! {
220+
DFSDM => (APB2, dfsdmen, dfsdmsmen, dfsdmrst), // 24
221+
}
222+
223+
#[cfg(feature = "stm32l4x6")]
224+
bus! {
225+
DMA2D => (AHB1, dma2den, dma2dsmen, dma2drst), // 17
226+
227+
GPIOI => (AHB2, gpioien, gpioismen, gpioirst), // 8
228+
OTG_FS_GLOBAL => (AHB2, otgfsen, otgfssmen, otgfsrst), // 12 // TODO: absent in x5
229+
DCMI => (AHB2, dcmien, dcmismen, dcmirst), // 14
230+
HASH => (AHB2, hash1en, hash1smen, hash1rst), // 17
231+
232+
CAN2 => (APB1R1, can2en, can2smen, can2rst), // 26
233+
DAC => (APB1R1, dac1en, dac1smen, dac1rst), // 29
234+
235+
I2C4 => (APB1R2, i2c4en, i2c4smen, i2c4rst), // 1
236+
237+
SDMMC1 => (APB2, sdmmcen, sdmmcsmen, sdmmcrst), // 10
238+
DFSDM1 => (APB2, dfsdmen, dfsdmsmen, dfsdmrst), // 24
239+
}

src/spi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use core::ptr;
99
use core::sync::atomic;
1010
use core::sync::atomic::Ordering;
1111

12-
use crate::dma::{self, dma1, dma2, TransferPayload};
12+
#[cfg(not(feature = "stm32l4x3"))]
13+
use crate::dma::dma2;
14+
use crate::dma::{self, dma1, TransferPayload};
1315
use crate::gpio::{Alternate, PushPull};
1416
use crate::hal::spi::{FullDuplex, Mode, Phase, Polarity};
1517
use crate::rcc::{Clocks, APB1R1, APB2};

0 commit comments

Comments
 (0)