Skip to content

Commit 9879f8d

Browse files
authored
Merge pull request #4940 from xoviat/time
stm32: allow split irqs for time driver
2 parents 9fa4f73 + dfd0d31 commit 9879f8d

File tree

4 files changed

+47
-130
lines changed

4 files changed

+47
-130
lines changed

ci.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ rm out/tests/pimoroni-pico-plus-2/pwm
6565
# flaky
6666
rm out/tests/rpi-pico/pwm
6767
rm out/tests/rpi-pico/cyw43-perf
68+
rm out/tests/rpi-pico/uart_buffered
6869

6970
# tests are implemented but the HIL test farm doesn't actually have these boards, yet
7071
rm -rf out/tests/stm32c071rb

embassy-stm32/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased - ReleaseDate
99

10+
- fix: fix incorrect handling of split interrupts in timer driver
1011
- feat: allow granular stop for regular usart
1112
- feat: Add continuous waveform method to SimplePWM
1213
- change: remove waveform timer method

embassy-stm32/build.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use proc_macro2::{Ident, TokenStream};
99
use quote::{format_ident, quote};
1010
use stm32_metapac::metadata::ir::BitOffset;
1111
use stm32_metapac::metadata::{
12-
ALL_CHIPS, ALL_PERIPHERAL_VERSIONS, METADATA, MemoryRegion, MemoryRegionKind, PeripheralRccKernelClock,
12+
ALL_CHIPS, ALL_PERIPHERAL_VERSIONS, METADATA, MemoryRegion, MemoryRegionKind, Peripheral, PeripheralRccKernelClock,
1313
PeripheralRccRegister, PeripheralRegisters, StopMode,
1414
};
1515

@@ -133,6 +133,9 @@ fn main() {
133133
cfgs.enable("backup_sram")
134134
}
135135

136+
// compile a map of peripherals
137+
let peripheral_map: BTreeMap<&str, &Peripheral> = METADATA.peripherals.iter().map(|p| (p.name, p)).collect();
138+
136139
// generate one singleton per peripheral (with many exceptions...)
137140
for p in METADATA.peripherals {
138141
if let Some(r) = &p.registers {
@@ -319,9 +322,33 @@ fn main() {
319322
_ => panic!("unknown time_driver {:?}", time_driver),
320323
};
321324

322-
if !time_driver_singleton.is_empty() {
325+
let time_driver_irq_decl = if !time_driver_singleton.is_empty() {
323326
cfgs.enable(format!("time_driver_{}", time_driver_singleton.to_lowercase()));
324-
}
327+
328+
let p = peripheral_map.get(time_driver_singleton).unwrap();
329+
let irqs: BTreeSet<_> = p
330+
.interrupts
331+
.iter()
332+
.filter(|i| i.signal == "CC" || i.signal == "UP")
333+
.map(|i| i.interrupt.to_ascii_uppercase())
334+
.collect();
335+
336+
irqs.iter()
337+
.map(|i| {
338+
let irq = format_ident!("{}", i);
339+
quote! {
340+
#[cfg(feature = "rt")]
341+
#[interrupt]
342+
fn #irq() {
343+
crate::time_driver::get_driver().on_interrupt();
344+
}
345+
}
346+
})
347+
.collect()
348+
} else {
349+
TokenStream::new()
350+
};
351+
325352
for tim in [
326353
"tim1", "tim2", "tim3", "tim4", "tim5", "tim8", "tim9", "tim12", "tim15", "tim20", "tim21", "tim22", "tim23",
327354
"tim24",
@@ -371,6 +398,8 @@ fn main() {
371398
);
372399
});
373400

401+
g.extend(time_driver_irq_decl);
402+
374403
// ========
375404
// Generate FLASH regions
376405
cfgs.declare("flash");
@@ -1862,7 +1891,7 @@ fn main() {
18621891
flash_regions_table.push(row);
18631892
}
18641893

1865-
let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as u32;
1894+
let gpio_base = peripheral_map.get("GPIOA").unwrap().address as u32;
18661895
let gpio_stride = 0x400;
18671896

18681897
for pin in METADATA.pins {
@@ -1980,11 +2009,11 @@ fn main() {
19802009
continue;
19812010
}
19822011

1983-
let stop_mode = METADATA
1984-
.peripherals
1985-
.iter()
1986-
.find(|p| p.name == ch.dma)
1987-
.map(|p| p.rcc.as_ref().map(|rcc| rcc.stop_mode.clone()).unwrap_or_default())
2012+
let dma_peri = peripheral_map.get(ch.dma).unwrap();
2013+
let stop_mode = dma_peri
2014+
.rcc
2015+
.as_ref()
2016+
.map(|rcc| rcc.stop_mode.clone())
19882017
.unwrap_or_default();
19892018

19902019
let stop_mode = match stop_mode {
@@ -2009,8 +2038,6 @@ fn main() {
20092038

20102039
let dma = format_ident!("{}", ch.dma);
20112040
let ch_num = ch.channel as usize;
2012-
2013-
let dma_peri = METADATA.peripherals.iter().find(|p| p.name == ch.dma).unwrap();
20142041
let bi = dma_peri.registers.as_ref().unwrap();
20152042

20162043
let dma_info = match bi.kind {

embassy-stm32/src/time_driver.rs

Lines changed: 7 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use stm32_metapac::timer::{TimGp16, regs};
1414

1515
use crate::interrupt::typelevel::Interrupt;
1616
use crate::pac::timer::vals;
17+
use crate::peripherals;
1718
use crate::rcc::{self, SealedRccPeripheral};
1819
#[cfg(feature = "low-power")]
1920
use crate::rtc::Rtc;
2021
use crate::timer::{CoreInstance, GeneralInstance1Channel};
21-
use crate::{interrupt, peripherals};
2222

2323
// NOTE regarding ALARM_COUNT:
2424
//
@@ -56,121 +56,6 @@ type T = peripherals::TIM23;
5656
#[cfg(time_driver_tim24)]
5757
type T = peripherals::TIM24;
5858

59-
foreach_interrupt! {
60-
(TIM1, timer, $block:ident, CC, $irq:ident) => {
61-
#[cfg(time_driver_tim1)]
62-
#[cfg(feature = "rt")]
63-
#[interrupt]
64-
fn $irq() {
65-
DRIVER.on_interrupt()
66-
}
67-
};
68-
(TIM2, timer, $block:ident, CC, $irq:ident) => {
69-
#[cfg(time_driver_tim2)]
70-
#[cfg(feature = "rt")]
71-
#[interrupt]
72-
fn $irq() {
73-
DRIVER.on_interrupt()
74-
}
75-
};
76-
(TIM3, timer, $block:ident, CC, $irq:ident) => {
77-
#[cfg(time_driver_tim3)]
78-
#[cfg(feature = "rt")]
79-
#[interrupt]
80-
fn $irq() {
81-
DRIVER.on_interrupt()
82-
}
83-
};
84-
(TIM4, timer, $block:ident, CC, $irq:ident) => {
85-
#[cfg(time_driver_tim4)]
86-
#[cfg(feature = "rt")]
87-
#[interrupt]
88-
fn $irq() {
89-
DRIVER.on_interrupt()
90-
}
91-
};
92-
(TIM5, timer, $block:ident, CC, $irq:ident) => {
93-
#[cfg(time_driver_tim5)]
94-
#[cfg(feature = "rt")]
95-
#[interrupt]
96-
fn $irq() {
97-
DRIVER.on_interrupt()
98-
}
99-
};
100-
(TIM8, timer, $block:ident, CC, $irq:ident) => {
101-
#[cfg(time_driver_tim8)]
102-
#[cfg(feature = "rt")]
103-
#[interrupt]
104-
fn $irq() {
105-
DRIVER.on_interrupt()
106-
}
107-
};
108-
(TIM9, timer, $block:ident, CC, $irq:ident) => {
109-
#[cfg(time_driver_tim9)]
110-
#[cfg(feature = "rt")]
111-
#[interrupt]
112-
fn $irq() {
113-
DRIVER.on_interrupt()
114-
}
115-
};
116-
(TIM12, timer, $block:ident, CC, $irq:ident) => {
117-
#[cfg(time_driver_tim12)]
118-
#[cfg(feature = "rt")]
119-
#[interrupt]
120-
fn $irq() {
121-
DRIVER.on_interrupt()
122-
}
123-
};
124-
(TIM15, timer, $block:ident, CC, $irq:ident) => {
125-
#[cfg(time_driver_tim15)]
126-
#[cfg(feature = "rt")]
127-
#[interrupt]
128-
fn $irq() {
129-
DRIVER.on_interrupt()
130-
}
131-
};
132-
(TIM20, timer, $block:ident, CC, $irq:ident) => {
133-
#[cfg(time_driver_tim20)]
134-
#[cfg(feature = "rt")]
135-
#[interrupt]
136-
fn $irq() {
137-
DRIVER.on_interrupt()
138-
}
139-
};
140-
(TIM21, timer, $block:ident, CC, $irq:ident) => {
141-
#[cfg(time_driver_tim21)]
142-
#[cfg(feature = "rt")]
143-
#[interrupt]
144-
fn $irq() {
145-
DRIVER.on_interrupt()
146-
}
147-
};
148-
(TIM22, timer, $block:ident, CC, $irq:ident) => {
149-
#[cfg(time_driver_tim22)]
150-
#[cfg(feature = "rt")]
151-
#[interrupt]
152-
fn $irq() {
153-
DRIVER.on_interrupt()
154-
}
155-
};
156-
(TIM23, timer, $block:ident, CC, $irq:ident) => {
157-
#[cfg(time_driver_tim23)]
158-
#[cfg(feature = "rt")]
159-
#[interrupt]
160-
fn $irq() {
161-
DRIVER.on_interrupt()
162-
}
163-
};
164-
(TIM24, timer, $block:ident, CC, $irq:ident) => {
165-
#[cfg(time_driver_tim24)]
166-
#[cfg(feature = "rt")]
167-
#[interrupt]
168-
fn $irq() {
169-
DRIVER.on_interrupt()
170-
}
171-
};
172-
}
173-
17459
fn regs_gp16() -> TimGp16 {
17560
unsafe { TimGp16::from_ptr(T::regs()) }
17661
}
@@ -282,15 +167,19 @@ impl RtcDriver {
282167
r.cnt().write(|w| w.set_cnt(self.saved_count.load(Ordering::SeqCst)));
283168

284169
<T as GeneralInstance1Channel>::CaptureCompareInterrupt::unpend();
285-
unsafe { <T as GeneralInstance1Channel>::CaptureCompareInterrupt::enable() };
170+
<T as CoreInstance>::UpdateInterrupt::unpend();
171+
unsafe {
172+
<T as GeneralInstance1Channel>::CaptureCompareInterrupt::enable();
173+
<T as CoreInstance>::UpdateInterrupt::enable();
174+
}
286175
}
287176

288177
fn init(&'static self, cs: CriticalSection) {
289178
self.init_timer(cs);
290179
regs_gp16().cr1().modify(|w| w.set_cen(true));
291180
}
292181

293-
fn on_interrupt(&self) {
182+
pub(crate) fn on_interrupt(&self) {
294183
let r = regs_gp16();
295184

296185
critical_section::with(|cs| {
@@ -508,7 +397,6 @@ impl Driver for RtcDriver {
508397
}
509398
}
510399

511-
#[cfg(feature = "low-power")]
512400
pub(crate) const fn get_driver() -> &'static RtcDriver {
513401
&DRIVER
514402
}

0 commit comments

Comments
 (0)