Skip to content

Commit 8350d5f

Browse files
Merge #289
289: Improve error diagnostics when kernel clocks are stopped r=richardeoin a=richardeoin * More helpful panic messages that name the consumer and the stopped clock * Expose more of these methods in the public API * Standardise around `kernel_clk`/`kernel_clk_unwrap` naming (excluding timers) Co-authored-by: Richard Meadows <[email protected]>
2 parents 99d7ad7 + 4403f65 commit 8350d5f

File tree

15 files changed

+285
-80
lines changed

15 files changed

+285
-80
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
* Rename the PeripheralREC object for BDMA2 on 7B3, 7B0, 7A3 parts from BDMA to BDMA2
1414
* pac: Upgrade to stm32-rs v0.14.0
1515
* Add "rt" to the default features
16+
* **Breaking**: `qspi` flag renamed to `xspi`
17+
* **Breaking**: SAI `sai_[ab]_ker_ck` methods now return `Hertz` rather than
18+
`Option<Hertz>` and if the clock is stopped they panic with a message.
1619

1720
* ethernet: `ethernet::DesRing` and `ethernet::EthernetDMA` require generic
1821
constants to specify how many transmit / receive buffers to include in

src/adc.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,17 @@ pub struct StoredConfig(AdcSampleTime, Resolution, AdcLshift);
330330
fn check_clock(prec: &impl AdcClkSelGetter, clocks: &CoreClocks) -> Hertz {
331331
// Select Kernel Clock
332332
let adc_clock = match prec.get_kernel_clk_mux() {
333-
Some(rec::AdcClkSel::PLL2_P) => clocks.pll2_p_ck(),
334-
Some(rec::AdcClkSel::PLL3_R) => clocks.pll3_r_ck(),
335-
Some(rec::AdcClkSel::PER) => clocks.per_ck(),
333+
Some(rec::AdcClkSel::PLL2_P) => {
334+
clocks.pll2_p_ck().expect("ADC: PLL2_P must be enabled")
335+
}
336+
Some(rec::AdcClkSel::PLL3_R) => {
337+
clocks.pll3_r_ck().expect("ADC: PLL3_R must be enabled")
338+
}
339+
Some(rec::AdcClkSel::PER) => {
340+
clocks.per_ck().expect("ADC: PER clock must be enabled")
341+
}
336342
_ => unreachable!(),
337-
}
338-
.expect("adc_ker_ck_input is not running!");
343+
};
339344

340345
// Check against datasheet requirements
341346
assert!(

src/fmc.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ use crate::gpio::{Alternate, AF12, AF9};
7070
/// AHB access to the FMC peripheral must be enabled
7171
pub struct FMC {
7272
fmc: stm32::FMC,
73-
fmc_ker_ck: Option<Hertz>,
73+
fmc_ker_ck: Hertz,
7474
}
7575

7676
/// Extension trait for FMC controller
@@ -114,10 +114,18 @@ impl FmcExt for stm32::FMC {
114114

115115
// Calculate kernel clock
116116
let fmc_ker_ck = match clk_sel {
117-
rec::FmcClkSel::RCC_HCLK3 => Some(clocks.hclk()),
118-
rec::FmcClkSel::PLL1_Q => clocks.pll1_q_ck(),
119-
rec::FmcClkSel::PLL2_R => clocks.pll2_r_ck(),
120-
rec::FmcClkSel::PER => clocks.per_ck(),
117+
rec::FmcClkSel::RCC_HCLK3 => {
118+
Some(clocks.hclk()).expect("FMC: HCLK must be enabled")
119+
}
120+
rec::FmcClkSel::PLL1_Q => {
121+
clocks.pll1_q_ck().expect("FMC: PLL1_Q must be enabled")
122+
}
123+
rec::FmcClkSel::PLL2_R => {
124+
clocks.pll2_r_ck().expect("FMC: PLL2_R must be enabled")
125+
}
126+
rec::FmcClkSel::PER => {
127+
clocks.per_ck().expect("FMC: PER clock must be enabled")
128+
}
121129
};
122130

123131
// Enable AHB access and reset peripheral
@@ -144,8 +152,7 @@ unsafe impl FmcPeripheral for FMC {
144152
}
145153

146154
fn source_clock_hz(&self) -> u32 {
147-
// Check that it runs
148-
self.fmc_ker_ck.expect("FMC kernel clock is not running!").0
155+
self.fmc_ker_ck.0
149156
}
150157
}
151158

src/pwm.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ macro_rules! tim_hal {
10521052
prec.enable().reset();
10531053

10541054
let clk = $TIMX::get_clk(clocks)
1055-
.expect("Timer input clock not running!");
1055+
.expect(concat!(stringify!($TIMX), ": Input clock not running!"));
10561056

10571057
let (period, prescale) = match $bits {
10581058
16 => calculate_frequency_16bit(clk, freq, Alignment::Left),
@@ -1096,7 +1096,7 @@ macro_rules! tim_hal {
10961096
prec.enable().reset();
10971097

10981098
let clk = $TIMX::get_clk(clocks)
1099-
.expect("Timer input clock not running!")
1099+
.expect(concat!(stringify!($TIMX), ": Input clock not running!"))
11001100
.0;
11011101

11021102
PwmBuilder {
@@ -1645,7 +1645,9 @@ macro_rules! lptim_hal {
16451645
{
16461646
prec.enable().reset();
16471647

1648-
let clk = $TIMX::get_clk(clocks).unwrap().0;
1648+
let clk = $TIMX::get_clk(clocks)
1649+
.expect(concat!(stringify!($TIMX), ": Input clock not running!"))
1650+
.0;
16491651
let freq = freq.0;
16501652
let reload = clk / freq;
16511653
assert!(reload < 128 * (1 << 16));

src/rng.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,28 @@ pub enum ErrorKind {
1919
SeedError = 1,
2020
}
2121

22-
trait KerClk {
23-
fn kernel_clk(prec: rec::Rng, clocks: &CoreClocks) -> Option<Hertz>;
22+
pub trait KerClk {
23+
/// Return the kernel clock for the Random Number Generator
24+
///
25+
/// # Panics
26+
///
27+
/// Panics if the kernel clock is not running
28+
fn kernel_clk_unwrap(prec: rec::Rng, clocks: &CoreClocks) -> Hertz;
2429
}
2530

2631
impl KerClk for RNG {
27-
fn kernel_clk(prec: rec::Rng, clocks: &CoreClocks) -> Option<Hertz> {
32+
fn kernel_clk_unwrap(prec: rec::Rng, clocks: &CoreClocks) -> Hertz {
2833
match prec.get_kernel_clk_mux() {
29-
RngClkSel::HSI48 => clocks.hsi48_ck(),
30-
RngClkSel::PLL1_Q => clocks.pll1_q_ck(),
34+
RngClkSel::HSI48 => {
35+
clocks.hsi48_ck().expect("RNG: HSI48 must be enabled")
36+
}
37+
RngClkSel::PLL1_Q => {
38+
clocks.pll1_q_ck().expect("RNG: PLL1_Q must be enabled")
39+
}
3140
RngClkSel::LSE => unimplemented!(),
32-
RngClkSel::LSI => unimplemented!(),
41+
RngClkSel::LSI => {
42+
clocks.lsi_ck().expect("RNG: LSI must be enabled")
43+
}
3344
}
3445
}
3546
}
@@ -43,12 +54,11 @@ impl RngExt for RNG {
4354
let prec = prec.enable().reset();
4455

4556
let hclk = clocks.hclk();
46-
let rng_clk = Self::kernel_clk(prec, clocks)
47-
.expect("RNG input clock not running!");
57+
let rng_clk = Self::kernel_clk_unwrap(prec, clocks);
4858

4959
// Otherwise clock checker will always flag an error
5060
// See RM0433 Rev 6 Section 33.3.6
51-
assert!(rng_clk.0 > hclk.0 / 32);
61+
assert!(rng_clk.0 > hclk.0 / 32, "RNG: Clock too slow");
5262

5363
self.cr.modify(|_, w| w.ced().enabled().rngen().enabled());
5464

src/sai/i2s.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,7 @@ macro_rules! i2s {
457457
}
458458

459459
// Clock config
460-
let ker_ck_a = $SAIX::sai_a_ker_ck(&prec, clocks)
461-
.expect("SAI kernel clock must run!");
460+
let ker_ck_a = $SAIX::sai_a_ker_ck(&prec, clocks);
462461
let clock_ratio = if users.master.oversampling {
463462
512
464463
} else {
@@ -468,7 +467,9 @@ macro_rules! i2s {
468467
(ker_ck_a.0) / (audio_freq.0 * clock_ratio);
469468
let mclk_div: u8 = mclk_div
470469
.try_into()
471-
.expect("SAI kernel clock is out of range for required MCLK");
470+
.expect(concat!(stringify!($SAIX),
471+
" A: Kernel clock is out of range for required MCLK"
472+
));
472473

473474
// Configure SAI peripheral
474475
let mut per_sai = Sai {
@@ -523,8 +524,7 @@ macro_rules! i2s {
523524
}
524525

525526
// Clock config
526-
let ker_ck_a = $SAIX::sai_b_ker_ck(&prec, clocks)
527-
.expect("SAI kernel clock must run!");
527+
let ker_ck_a = $SAIX::sai_b_ker_ck(&prec, clocks);
528528
let clock_ratio = if users.master.oversampling {
529529
512
530530
} else {
@@ -534,7 +534,10 @@ macro_rules! i2s {
534534
(ker_ck_a.0) / (audio_freq.0 * clock_ratio);
535535
let mclk_div: u8 = mclk_div
536536
.try_into()
537-
.expect("SAI kernel clock is out of range for required MCLK");
537+
.expect(concat!(stringify!($SAIX),
538+
" B: Kernel clock is out of range for required MCLK"
539+
));
540+
538541

539542
// Configure SAI peripheral
540543
let mut per_sai = Sai {

src/sai/mod.rs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,18 @@ pub use i2s::{
4545
pub trait GetClkSAI {
4646
type Rec: ResetEnable;
4747

48-
fn sai_a_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Option<Hertz>;
49-
fn sai_b_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Option<Hertz>;
48+
/// Return the kernel clock for the SAI - A
49+
///
50+
/// # Panics
51+
///
52+
/// Panics if the kernel clock is not running
53+
fn sai_a_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Hertz;
54+
/// Return the kernel clock for the SAI - B
55+
///
56+
/// # Panics
57+
///
58+
/// Panics if the kernel clock is not running
59+
fn sai_b_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Hertz;
5060
}
5161

5262
// Return kernel clocks for this SAI
@@ -59,24 +69,56 @@ macro_rules! impl_sai_ker_ck {
5969
type Rec = rec::$Rec;
6070

6171
/// Current kernel clock - A
62-
fn sai_a_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Option<Hertz> {
72+
fn sai_a_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Hertz {
6373
match prec.$get_mux_A() {
64-
Some(rec::$AccessA::PLL1_Q) => clocks.pll1_q_ck(),
65-
Some(rec::$AccessA::PLL2_P) => clocks.pll2_p_ck(),
66-
Some(rec::$AccessA::PLL3_P) => clocks.pll3_p_ck(),
74+
Some(rec::$AccessA::PLL1_Q) => {
75+
clocks.pll1_q_ck().expect(
76+
concat!(stringify!($SAIX), " A: PLL1_Q must be enabled")
77+
)
78+
}
79+
Some(rec::$AccessA::PLL2_P) => {
80+
clocks.pll2_p_ck().expect(
81+
concat!(stringify!($SAIX), " A: PLL2_P must be enabled")
82+
)
83+
}
84+
Some(rec::$AccessA::PLL3_P) => {
85+
clocks.pll3_p_ck().expect(
86+
concat!(stringify!($SAIX), " A: PLL3_P must be enabled")
87+
)
88+
}
6789
Some(rec::$AccessA::I2S_CKIN) => unimplemented!(),
68-
Some(rec::$AccessA::PER) => clocks.per_ck(),
90+
Some(rec::$AccessA::PER) => {
91+
clocks.per_ck().expect(
92+
concat!(stringify!($SAIX), " A: PER clock must be enabled")
93+
)
94+
}
6995
_ => unreachable!(),
7096
}
7197
}
7298
/// Current kernel clock - B
73-
fn sai_b_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Option<Hertz> {
99+
fn sai_b_ker_ck(prec: &Self::Rec, clocks: &CoreClocks) -> Hertz {
74100
match prec.$get_mux_B() {
75-
Some(rec::$AccessB::PLL1_Q) => clocks.pll1_q_ck(),
76-
Some(rec::$AccessB::PLL2_P) => clocks.pll2_p_ck(),
77-
Some(rec::$AccessB::PLL3_P) => clocks.pll3_p_ck(),
101+
Some(rec::$AccessB::PLL1_Q) => {
102+
clocks.pll1_q_ck().expect(
103+
concat!(stringify!($SAIX), " B: PLL1_Q must be enabled")
104+
)
105+
}
106+
Some(rec::$AccessB::PLL2_P) => {
107+
clocks.pll2_p_ck().expect(
108+
concat!(stringify!($SAIX), " B: PLL2_P must be enabled")
109+
)
110+
}
111+
Some(rec::$AccessB::PLL3_P) => {
112+
clocks.pll3_p_ck().expect(
113+
concat!(stringify!($SAIX), " B: PLL3_P must be enabled")
114+
)
115+
}
78116
Some(rec::$AccessB::I2S_CKIN) => unimplemented!(),
79-
Some(rec::$AccessB::PER) => clocks.per_ck(),
117+
Some(rec::$AccessB::PER) => {
118+
clocks.per_ck().expect(
119+
concat!(stringify!($SAIX), " B: PER clock must be enabled")
120+
)
121+
}
80122
_ => unreachable!(),
81123
}
82124
}

src/sai/pdm.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,13 @@ macro_rules! hal {
250250
let mclk_a_hz = sck_a_hz; // For NODIV = 1, SCK_a = MCLK_a
251251

252252
// Calculate divider
253-
let ker_ck_a =
254-
$SAIX::sai_a_ker_ck(&prec, clocks).expect("SAI kernel clock must run!");
253+
let ker_ck_a = $SAIX::sai_a_ker_ck(&prec, clocks);
255254
let kernel_clock_divider: u8 = (ker_ck_a.0 / mclk_a_hz)
256255
.try_into()
257-
.expect("SAI kernel clock is out of range for required MCLK");
256+
.expect(concat!(stringify!($SAIX),
257+
": Kernel clock is out of range for required MCLK"
258+
));
259+
258260

259261
// Configure SAI peripeheral
260262
let mut s = Sai {

src/sdmmc.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,10 +454,18 @@ macro_rules! sdmmc {
454454

455455
let hclk = clocks.hclk();
456456
let ker_ck = match prec.get_kernel_clk_mux() {
457-
rec::SdmmcClkSel::PLL1_Q => clocks.pll1_q_ck(),
458-
rec::SdmmcClkSel::PLL2_R => clocks.pll2_r_ck(),
459-
}
460-
.expect("sdmmc_ker_ck not running!");
457+
rec::SdmmcClkSel::PLL1_Q => {
458+
clocks.pll1_q_ck().expect(
459+
concat!(stringify!($SDMMCX), ": PLL1_Q must be enabled")
460+
)
461+
}
462+
rec::SdmmcClkSel::PLL2_R => {
463+
clocks.pll2_r_ck().expect(
464+
concat!(stringify!($SDMMCX), ": PLL2_R must be enabled")
465+
)
466+
}
467+
};
468+
461469

462470
// For tuning the phase of the receive sampling clock, a
463471
// DLYB block can be connected between sdmmc_io_in_ck and

src/serial.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,10 +514,7 @@ macro_rules! usart {
514514
prec.enable().reset();
515515

516516
// Get kernel clock
517-
let usart_ker_ck = match Self::kernel_clk(clocks) {
518-
Some(ker_hz) => ker_hz.0,
519-
_ => panic!("$USARTX kernel clock not running!")
520-
};
517+
let usart_ker_ck = Self::kernel_clk_unwrap(clocks).0;
521518

522519
// Prescaler not used for now
523520
let usart_ker_ck_presc = usart_ker_ck;
@@ -954,7 +951,7 @@ macro_rules! usart_sel {
954951
impl Serial<$USARTX> {
955952
/// Returns the frequency of the current kernel clock for
956953
#[doc=$doc]
957-
fn kernel_clk(clocks: &CoreClocks) -> Option<Hertz> {
954+
pub fn kernel_clk(clocks: &CoreClocks) -> Option<Hertz> {
958955
// unsafe: read only
959956
let ccip = unsafe { (*stm32::RCC::ptr()).$ccip.read() };
960957

@@ -968,6 +965,42 @@ macro_rules! usart_sel {
968965
_ => unreachable!(),
969966
}
970967
}
968+
/// Returns the frequency of the current kernel clock for
969+
#[doc=$doc]
970+
///
971+
/// # Panics
972+
///
973+
/// Panics if the kernel clock is not running
974+
pub fn kernel_clk_unwrap(clocks: &CoreClocks) -> Hertz {
975+
// unsafe: read only
976+
let ccip = unsafe { (*stm32::RCC::ptr()).$ccip.read() };
977+
978+
match ccip.$sel().variant() {
979+
Some($SEL::$PCLK) => clocks.$pclk(),
980+
Some($SEL::PLL2_Q) => {
981+
clocks.pll2_q_ck().expect(
982+
concat!(stringify!($USARTX), ": PLL2_Q must be enabled")
983+
)
984+
}
985+
Some($SEL::PLL3_Q) => {
986+
clocks.pll3_q_ck().expect(
987+
concat!(stringify!($USARTX), ": PLL3_Q must be enabled")
988+
)
989+
}
990+
Some($SEL::HSI_KER) => {
991+
clocks.hsi_ck().expect(
992+
concat!(stringify!($USARTX), ": HSI clock must be enabled")
993+
)
994+
}
995+
Some($SEL::CSI_KER) => {
996+
clocks.csi_ck().expect(
997+
concat!(stringify!($USARTX), ": CSI clock must be enabled")
998+
)
999+
}
1000+
Some($SEL::LSE) => unimplemented!(),
1001+
_ => unreachable!(),
1002+
}
1003+
}
9711004
}
9721005
)+
9731006
}

0 commit comments

Comments
 (0)