aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorokhsunrog <[email protected]>2025-05-21 17:10:49 +0300
committerokhsunrog <[email protected]>2025-05-21 17:10:49 +0300
commitbe831d0e7990ab07cc805f440d3814ae47c6dfcc (patch)
treed5f4bd3fe88f5457e9b1e6e5112d5986ea582c99
parent27ca627fc83974d926630b4a1bfc9783c3c86bb9 (diff)
parent7134e1a3a5b858958e2b4c6911036e4a86dcb095 (diff)
Merge remote-tracking branch 'origin/main' into adding_eeprom
-rw-r--r--embassy-mspm0/Cargo.toml4
-rw-r--r--embassy-mspm0/build.rs88
-rw-r--r--embassy-mspm0/src/gpio.rs24
-rw-r--r--embassy-mspm0/src/int_group/c110x.rs25
-rw-r--r--embassy-mspm0/src/int_group/g110x.rs47
-rw-r--r--embassy-mspm0/src/int_group/g150x.rs51
-rw-r--r--embassy-mspm0/src/int_group/g151x.rs52
-rw-r--r--embassy-mspm0/src/int_group/g310x.rs48
-rw-r--r--embassy-mspm0/src/int_group/g350x.rs51
-rw-r--r--embassy-mspm0/src/int_group/g351x.rs52
-rw-r--r--embassy-mspm0/src/int_group/l11xx.rs25
-rw-r--r--embassy-mspm0/src/int_group/l12xx.rs49
-rw-r--r--embassy-mspm0/src/int_group/l13xx.rs46
-rw-r--r--embassy-mspm0/src/int_group/l222x.rs49
-rw-r--r--embassy-mspm0/src/lib.rs14
-rw-r--r--embassy-nrf/src/lib.rs24
-rw-r--r--embassy-nrf/src/rng.rs78
-rw-r--r--embassy-stm32/src/rtc/mod.rs2
-rw-r--r--examples/mspm0c1104/build.rs2
-rw-r--r--examples/mspm0g3507/build.rs2
-rw-r--r--examples/mspm0g3519/build.rs2
-rw-r--r--examples/mspm0l1306/build.rs2
-rw-r--r--examples/mspm0l2228/build.rs2
-rw-r--r--tests/mspm0/build.rs2
24 files changed, 196 insertions, 545 deletions
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml
index 1b189e05a..6f767a3c0 100644
--- a/embassy-mspm0/Cargo.toml
+++ b/embassy-mspm0/Cargo.toml
@@ -46,14 +46,14 @@ cortex-m = "0.7.6"
46critical-section = "1.2.0" 46critical-section = "1.2.0"
47 47
48# mspm0-metapac = { version = "" } 48# mspm0-metapac = { version = "" }
49mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-66a55c7bf38a2201ff48c299843e741f2d537f0b" } 49mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-26a6f681eda4ef120e8cb614a1631727c848590f" }
50 50
51[build-dependencies] 51[build-dependencies]
52proc-macro2 = "1.0.94" 52proc-macro2 = "1.0.94"
53quote = "1.0.40" 53quote = "1.0.40"
54 54
55# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } 55# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] }
56mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-66a55c7bf38a2201ff48c299843e741f2d537f0b", default-features = false, features = ["metadata"] } 56mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-26a6f681eda4ef120e8cb614a1631727c848590f", default-features = false, features = ["metadata"] }
57 57
58[features] 58[features]
59default = ["rt"] 59default = ["rt"]
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs
index 094769992..6cd62895b 100644
--- a/embassy-mspm0/build.rs
+++ b/embassy-mspm0/build.rs
@@ -1,6 +1,7 @@
1use std::cmp::Ordering; 1use std::cmp::Ordering;
2use std::collections::{BTreeSet, HashMap}; 2use std::collections::{BTreeSet, HashMap};
3use std::io::Write; 3use std::fmt::Write;
4use std::io::Write as _;
4use std::path::{Path, PathBuf}; 5use std::path::{Path, PathBuf};
5use std::process::Command; 6use std::process::Command;
6use std::sync::LazyLock; 7use std::sync::LazyLock;
@@ -16,12 +17,19 @@ mod common;
16 17
17fn main() { 18fn main() {
18 generate_code(); 19 generate_code();
20 interrupt_group_linker_magic();
19} 21}
20 22
21fn generate_code() { 23fn generate_code() {
22 let mut cfgs = common::CfgSet::new(); 24 let mut cfgs = common::CfgSet::new();
23 common::set_target_cfgs(&mut cfgs); 25 common::set_target_cfgs(&mut cfgs);
24 26
27 #[cfg(any(feature = "rt"))]
28 println!(
29 "cargo:rustc-link-search={}",
30 PathBuf::from(env::var_os("OUT_DIR").unwrap()).display(),
31 );
32
25 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); 33 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]);
26 34
27 let chip_name = match env::vars() 35 let chip_name = match env::vars()
@@ -58,6 +66,7 @@ fn generate_code() {
58 g.extend(generate_interrupts()); 66 g.extend(generate_interrupts());
59 g.extend(generate_peripheral_instances()); 67 g.extend(generate_peripheral_instances());
60 g.extend(generate_pin_trait_impls()); 68 g.extend(generate_pin_trait_impls());
69 g.extend(generate_groups());
61 70
62 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 71 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
63 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); 72 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
@@ -123,6 +132,83 @@ fn get_chip_cfgs(chip_name: &str) -> Vec<String> {
123 cfgs 132 cfgs
124} 133}
125 134
135/// Interrupt groups use a weakly linked symbols and #[linkage = "extern_weak"] is nightly we need to
136/// do some linker magic to create weak linkage.
137fn interrupt_group_linker_magic() {
138 let mut file = String::new();
139
140 for group in METADATA.interrupt_groups {
141 for interrupt in group.interrupts.iter() {
142 let name = interrupt.name;
143
144 writeln!(&mut file, "PROVIDE({name} = DefaultHandler);").unwrap();
145 }
146 }
147
148 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
149 let out_file = out_dir.join("interrupt_group.x");
150 fs::write(&out_file, file).unwrap();
151}
152
153fn generate_groups() -> TokenStream {
154 let group_vectors = METADATA.interrupt_groups.iter().map(|group| {
155 let vectors = group.interrupts.iter().map(|interrupt| {
156 let fn_name = Ident::new(interrupt.name, Span::call_site());
157
158 quote! {
159 pub(crate) fn #fn_name();
160 }
161 });
162
163 quote! { #(#vectors)* }
164 });
165
166 let groups = METADATA.interrupt_groups.iter().map(|group| {
167 let interrupt_group_name = Ident::new(group.name, Span::call_site());
168 let group_enum = Ident::new(&format!("Group{}", &group.name[5..]), Span::call_site());
169 let group_number = Literal::u32_unsuffixed(group.number);
170
171 let matches = group.interrupts.iter().map(|interrupt| {
172 let variant = Ident::new(&interrupt.name, Span::call_site());
173
174 quote! {
175 #group_enum::#variant => unsafe { group_vectors::#variant() },
176 }
177 });
178
179 quote! {
180 #[cfg(feature = "rt")]
181 #[crate::pac::interrupt]
182 fn #interrupt_group_name() {
183 use crate::pac::#group_enum;
184
185 let group = crate::pac::CPUSS.int_group(#group_number);
186 // MUST subtract by 1 since 0 is NO_INTR
187 let iidx = group.iidx().read().stat().to_bits() - 1;
188
189 let Ok(group) = #group_enum::try_from(iidx as u8) else {
190 return;
191 };
192
193 match group {
194 #(#matches)*
195 }
196 }
197 }
198 });
199
200 quote! {
201 #(#groups)*
202
203 #[cfg(feature = "rt")]
204 mod group_vectors {
205 extern "Rust" {
206 #(#group_vectors)*
207 }
208 }
209 }
210}
211
126#[derive(Debug, Clone)] 212#[derive(Debug, Clone)]
127struct Singleton { 213struct Singleton {
128 name: String, 214 name: String,
diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs
index 19a6230b6..738d51928 100644
--- a/embassy-mspm0/src/gpio.rs
+++ b/embassy-mspm0/src/gpio.rs
@@ -1119,24 +1119,36 @@ impl Iterator for BitIter {
1119 } 1119 }
1120} 1120}
1121 1121
1122// C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt. 1122// C110x and L110x have a dedicated interrupts just for GPIOA.
1123//
1124// These chips do not have a GROUP1 interrupt.
1123#[cfg(all(feature = "rt", any(mspm0c110x, mspm0l110x)))] 1125#[cfg(all(feature = "rt", any(mspm0c110x, mspm0l110x)))]
1124#[interrupt] 1126#[interrupt]
1125fn GPIOA() { 1127fn GPIOA() {
1126 gpioa_interrupt(); 1128 irq_handler(pac::GPIOA, &PORTA_WAKERS);
1127} 1129}
1128 1130
1129#[cfg(feature = "rt")] 1131// These symbols are weakly defined as DefaultHandler and are called by the interrupt group implementation.
1130pub(crate) fn gpioa_interrupt() { 1132//
1133// Defining these as no_mangle is required so that the linker will pick these over the default handler.
1134
1135#[cfg(all(feature = "rt", not(any(mspm0c110x, mspm0l110x))))]
1136#[no_mangle]
1137#[allow(non_snake_case)]
1138fn GPIOA() {
1131 irq_handler(pac::GPIOA, &PORTA_WAKERS); 1139 irq_handler(pac::GPIOA, &PORTA_WAKERS);
1132} 1140}
1133 1141
1134#[cfg(all(feature = "rt", gpio_pb))] 1142#[cfg(all(feature = "rt", gpio_pb))]
1135pub(crate) fn gpiob_interrupt() { 1143#[no_mangle]
1144#[allow(non_snake_case)]
1145fn GPIOB() {
1136 irq_handler(pac::GPIOB, &PORTB_WAKERS); 1146 irq_handler(pac::GPIOB, &PORTB_WAKERS);
1137} 1147}
1138 1148
1139#[cfg(all(feature = "rt", gpio_pc))] 1149#[cfg(all(feature = "rt", gpio_pc))]
1140pub(crate) fn gpioc_interrupt() { 1150#[allow(non_snake_case)]
1151#[no_mangle]
1152fn GPIOC() {
1141 irq_handler(pac::GPIOC, &PORTC_WAKERS); 1153 irq_handler(pac::GPIOC, &PORTC_WAKERS);
1142} 1154}
diff --git a/embassy-mspm0/src/int_group/c110x.rs b/embassy-mspm0/src/int_group/c110x.rs
deleted file mode 100644
index e6a9ddb99..000000000
--- a/embassy-mspm0/src/int_group/c110x.rs
+++ /dev/null
@@ -1,25 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // TODO: Decompose to direct u8
12 let iidx = group.iidx().read().stat().to_bits();
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
diff --git a/embassy-mspm0/src/int_group/g110x.rs b/embassy-mspm0/src/int_group/g110x.rs
deleted file mode 100644
index 9f8ac4d7b..000000000
--- a/embassy-mspm0/src/int_group/g110x.rs
+++ /dev/null
@@ -1,47 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 }
47}
diff --git a/embassy-mspm0/src/int_group/g150x.rs b/embassy-mspm0/src/int_group/g150x.rs
deleted file mode 100644
index 706ba2078..000000000
--- a/embassy-mspm0/src/int_group/g150x.rs
+++ /dev/null
@@ -1,51 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 }
51}
diff --git a/embassy-mspm0/src/int_group/g151x.rs b/embassy-mspm0/src/int_group/g151x.rs
deleted file mode 100644
index e785018a7..000000000
--- a/embassy-mspm0/src/int_group/g151x.rs
+++ /dev/null
@@ -1,52 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
51 }
52}
diff --git a/embassy-mspm0/src/int_group/g310x.rs b/embassy-mspm0/src/int_group/g310x.rs
deleted file mode 100644
index ad508d3a2..000000000
--- a/embassy-mspm0/src/int_group/g310x.rs
+++ /dev/null
@@ -1,48 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::TRNG => todo!("implement TRNG"),
47 }
48}
diff --git a/embassy-mspm0/src/int_group/g350x.rs b/embassy-mspm0/src/int_group/g350x.rs
deleted file mode 100644
index 706ba2078..000000000
--- a/embassy-mspm0/src/int_group/g350x.rs
+++ /dev/null
@@ -1,51 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 }
51}
diff --git a/embassy-mspm0/src/int_group/g351x.rs b/embassy-mspm0/src/int_group/g351x.rs
deleted file mode 100644
index e785018a7..000000000
--- a/embassy-mspm0/src/int_group/g351x.rs
+++ /dev/null
@@ -1,52 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
51 }
52}
diff --git a/embassy-mspm0/src/int_group/l11xx.rs b/embassy-mspm0/src/int_group/l11xx.rs
deleted file mode 100644
index 426a80c13..000000000
--- a/embassy-mspm0/src/int_group/l11xx.rs
+++ /dev/null
@@ -1,25 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
diff --git a/embassy-mspm0/src/int_group/l12xx.rs b/embassy-mspm0/src/int_group/l12xx.rs
deleted file mode 100644
index eeb2ce70d..000000000
--- a/embassy-mspm0/src/int_group/l12xx.rs
+++ /dev/null
@@ -1,49 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
26
27#[cfg(feature = "rt")]
28#[interrupt]
29fn GROUP1() {
30 use mspm0_metapac::Group1;
31
32 let group = pac::CPUSS.int_group(1);
33
34 // Must subtract by 1 since NO_INTR is value 0
35 let iidx = group.iidx().read().stat().to_bits() - 1;
36
37 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
38 debug!("Invalid IIDX for group 1: {}", iidx);
39 return;
40 };
41
42 match group {
43 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
44 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
45 Group1::COMP0 => todo!("implement COMP0"),
46 Group1::TRNG => todo!("implement TRNG"),
47 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
48 }
49}
diff --git a/embassy-mspm0/src/int_group/l13xx.rs b/embassy-mspm0/src/int_group/l13xx.rs
deleted file mode 100644
index 8be5adcad..000000000
--- a/embassy-mspm0/src/int_group/l13xx.rs
+++ /dev/null
@@ -1,46 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
26
27#[cfg(feature = "rt")]
28#[interrupt]
29fn GROUP1() {
30 use mspm0_metapac::Group1;
31
32 let group = pac::CPUSS.int_group(1);
33
34 // Must subtract by 1 since NO_INTR is value 0
35 let iidx = group.iidx().read().stat().to_bits() - 1;
36
37 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
38 debug!("Invalid IIDX for group 1: {}", iidx);
39 return;
40 };
41
42 match group {
43 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
44 Group1::COMP0 => todo!("implement COMP0"),
45 }
46}
diff --git a/embassy-mspm0/src/int_group/l222x.rs b/embassy-mspm0/src/int_group/l222x.rs
deleted file mode 100644
index eeb2ce70d..000000000
--- a/embassy-mspm0/src/int_group/l222x.rs
+++ /dev/null
@@ -1,49 +0,0 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
26
27#[cfg(feature = "rt")]
28#[interrupt]
29fn GROUP1() {
30 use mspm0_metapac::Group1;
31
32 let group = pac::CPUSS.int_group(1);
33
34 // Must subtract by 1 since NO_INTR is value 0
35 let iidx = group.iidx().read().stat().to_bits() - 1;
36
37 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
38 debug!("Invalid IIDX for group 1: {}", iidx);
39 return;
40 };
41
42 match group {
43 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
44 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
45 Group1::COMP0 => todo!("implement COMP0"),
46 Group1::TRNG => todo!("implement TRNG"),
47 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
48 }
49}
diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs
index f129e221b..7ff60e946 100644
--- a/embassy-mspm0/src/lib.rs
+++ b/embassy-mspm0/src/lib.rs
@@ -39,20 +39,6 @@ pub mod mode {
39#[cfg(feature = "_time-driver")] 39#[cfg(feature = "_time-driver")]
40mod time_driver; 40mod time_driver;
41 41
42// Interrupt group handlers.
43#[cfg_attr(mspm0c110x, path = "int_group/c110x.rs")]
44#[cfg_attr(mspm0g110x, path = "int_group/g110x.rs")]
45#[cfg_attr(mspm0g150x, path = "int_group/g150x.rs")]
46#[cfg_attr(mspm0g350x, path = "int_group/g350x.rs")]
47#[cfg_attr(mspm0g151x, path = "int_group/g151x.rs")]
48#[cfg_attr(mspm0g351x, path = "int_group/g351x.rs")]
49#[cfg_attr(mspm0g310x, path = "int_group/g310x.rs")]
50#[cfg_attr(mspm0l110x, path = "int_group/l11xx.rs")]
51#[cfg_attr(mspm0l122x, path = "int_group/l12xx.rs")]
52#[cfg_attr(any(mspm0l130x, mspm0l134x), path = "int_group/l13xx.rs")]
53#[cfg_attr(mspm0l222x, path = "int_group/l222x.rs")]
54mod int_group;
55
56pub(crate) mod _generated { 42pub(crate) mod _generated {
57 #![allow(dead_code)] 43 #![allow(dead_code)]
58 #![allow(unused_imports)] 44 #![allow(unused_imports)]
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 0c5dd059d..398bfed48 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -1039,3 +1039,27 @@ pub fn init(config: config::Config) -> Peripherals {
1039 1039
1040 peripherals 1040 peripherals
1041} 1041}
1042
1043/// Operating modes for peripherals.
1044pub mod mode {
1045 trait SealedMode {}
1046
1047 /// Operating mode for a peripheral.
1048 #[allow(private_bounds)]
1049 pub trait Mode: SealedMode {}
1050
1051 macro_rules! impl_mode {
1052 ($name:ident) => {
1053 impl SealedMode for $name {}
1054 impl Mode for $name {}
1055 };
1056 }
1057
1058 /// Blocking mode.
1059 pub struct Blocking;
1060 /// Async mode.
1061 pub struct Async;
1062
1063 impl_mode!(Blocking);
1064 impl_mode!(Async);
1065}
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index 7e42dc938..9d3130e6e 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -14,6 +14,7 @@ use embassy_hal_internal::{Peri, PeripheralType};
14use embassy_sync::waitqueue::WakerRegistration; 14use embassy_sync::waitqueue::WakerRegistration;
15 15
16use crate::interrupt::typelevel::Interrupt; 16use crate::interrupt::typelevel::Interrupt;
17use crate::mode::{Async, Blocking, Mode};
17use crate::{interrupt, pac}; 18use crate::{interrupt, pac};
18 19
19/// Interrupt handler. 20/// Interrupt handler.
@@ -55,11 +56,31 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
55/// A wrapper around an nRF RNG peripheral. 56/// A wrapper around an nRF RNG peripheral.
56/// 57///
57/// It has a non-blocking API, and a blocking api through `rand`. 58/// It has a non-blocking API, and a blocking api through `rand`.
58pub struct Rng<'d, T: Instance> { 59pub struct Rng<'d, T: Instance, M: Mode> {
59 _peri: Peri<'d, T>, 60 _peri: Peri<'d, T>,
61 _phantom: PhantomData<M>,
60} 62}
61 63
62impl<'d, T: Instance> Rng<'d, T> { 64impl<'d, T: Instance> Rng<'d, T, Blocking> {
65 /// Creates a new RNG driver from the `RNG` peripheral and interrupt.
66 ///
67 /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor,
68 /// e.g. using `mem::forget`.
69 ///
70 /// The synchronous API is safe.
71 pub fn new_blocking(rng: Peri<'d, T>) -> Self {
72 let this = Self {
73 _peri: rng,
74 _phantom: PhantomData,
75 };
76
77 this.stop();
78
79 this
80 }
81}
82
83impl<'d, T: Instance> Rng<'d, T, Async> {
63 /// Creates a new RNG driver from the `RNG` peripheral and interrupt. 84 /// Creates a new RNG driver from the `RNG` peripheral and interrupt.
64 /// 85 ///
65 /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor, 86 /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor,
@@ -70,7 +91,10 @@ impl<'d, T: Instance> Rng<'d, T> {
70 rng: Peri<'d, T>, 91 rng: Peri<'d, T>,
71 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 92 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
72 ) -> Self { 93 ) -> Self {
73 let this = Self { _peri: rng }; 94 let this = Self {
95 _peri: rng,
96 _phantom: PhantomData,
97 };
74 98
75 this.stop(); 99 this.stop();
76 this.disable_irq(); 100 this.disable_irq();
@@ -81,14 +105,6 @@ impl<'d, T: Instance> Rng<'d, T> {
81 this 105 this
82 } 106 }
83 107
84 fn stop(&self) {
85 T::regs().tasks_stop().write_value(1)
86 }
87
88 fn start(&self) {
89 T::regs().tasks_start().write_value(1)
90 }
91
92 fn enable_irq(&self) { 108 fn enable_irq(&self) {
93 T::regs().intenset().write(|w| w.set_valrdy(true)); 109 T::regs().intenset().write(|w| w.set_valrdy(true));
94 } 110 }
@@ -97,16 +113,6 @@ impl<'d, T: Instance> Rng<'d, T> {
97 T::regs().intenclr().write(|w| w.set_valrdy(true)); 113 T::regs().intenclr().write(|w| w.set_valrdy(true));
98 } 114 }
99 115
100 /// Enable or disable the RNG's bias correction.
101 ///
102 /// Bias correction removes any bias towards a '1' or a '0' in the bits generated.
103 /// However, this makes the generation of numbers slower.
104 ///
105 /// Defaults to disabled.
106 pub fn set_bias_correction(&self, enable: bool) {
107 T::regs().config().write(|w| w.set_dercen(enable))
108 }
109
110 /// Fill the buffer with random bytes. 116 /// Fill the buffer with random bytes.
111 pub async fn fill_bytes(&mut self, dest: &mut [u8]) { 117 pub async fn fill_bytes(&mut self, dest: &mut [u8]) {
112 if dest.is_empty() { 118 if dest.is_empty() {
@@ -153,6 +159,26 @@ impl<'d, T: Instance> Rng<'d, T> {
153 // Trigger the teardown 159 // Trigger the teardown
154 drop(on_drop); 160 drop(on_drop);
155 } 161 }
162}
163
164impl<'d, T: Instance, M: Mode> Rng<'d, T, M> {
165 fn stop(&self) {
166 T::regs().tasks_stop().write_value(1)
167 }
168
169 fn start(&self) {
170 T::regs().tasks_start().write_value(1)
171 }
172
173 /// Enable or disable the RNG's bias correction.
174 ///
175 /// Bias correction removes any bias towards a '1' or a '0' in the bits generated.
176 /// However, this makes the generation of numbers slower.
177 ///
178 /// Defaults to disabled.
179 pub fn set_bias_correction(&self, enable: bool) {
180 T::regs().config().write(|w| w.set_dercen(enable))
181 }
156 182
157 /// Fill the buffer with random bytes, blocking version. 183 /// Fill the buffer with random bytes, blocking version.
158 pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) { 184 pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) {
@@ -184,7 +210,7 @@ impl<'d, T: Instance> Rng<'d, T> {
184 } 210 }
185} 211}
186 212
187impl<'d, T: Instance> Drop for Rng<'d, T> { 213impl<'d, T: Instance, M: Mode> Drop for Rng<'d, T, M> {
188 fn drop(&mut self) { 214 fn drop(&mut self) {
189 self.stop(); 215 self.stop();
190 critical_section::with(|cs| { 216 critical_section::with(|cs| {
@@ -195,7 +221,7 @@ impl<'d, T: Instance> Drop for Rng<'d, T> {
195 } 221 }
196} 222}
197 223
198impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> { 224impl<'d, T: Instance, M: Mode> rand_core_06::RngCore for Rng<'d, T, M> {
199 fn fill_bytes(&mut self, dest: &mut [u8]) { 225 fn fill_bytes(&mut self, dest: &mut [u8]) {
200 self.blocking_fill_bytes(dest); 226 self.blocking_fill_bytes(dest);
201 } 227 }
@@ -211,9 +237,9 @@ impl<'d, T: Instance> rand_core_06::RngCore for Rng<'d, T> {
211 } 237 }
212} 238}
213 239
214impl<'d, T: Instance> rand_core_06::CryptoRng for Rng<'d, T> {} 240impl<'d, T: Instance, M: Mode> rand_core_06::CryptoRng for Rng<'d, T, M> {}
215 241
216impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> { 242impl<'d, T: Instance, M: Mode> rand_core_09::RngCore for Rng<'d, T, M> {
217 fn fill_bytes(&mut self, dest: &mut [u8]) { 243 fn fill_bytes(&mut self, dest: &mut [u8]) {
218 self.blocking_fill_bytes(dest); 244 self.blocking_fill_bytes(dest);
219 } 245 }
@@ -225,7 +251,7 @@ impl<'d, T: Instance> rand_core_09::RngCore for Rng<'d, T> {
225 } 251 }
226} 252}
227 253
228impl<'d, T: Instance> rand_core_09::CryptoRng for Rng<'d, T> {} 254impl<'d, T: Instance, M: Mode> rand_core_09::CryptoRng for Rng<'d, T, M> {}
229 255
230/// Peripheral static state 256/// Peripheral static state
231pub(crate) struct State { 257pub(crate) struct State {
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index b16c6fdca..49f423f37 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -25,7 +25,7 @@ use crate::time::Hertz;
25 ), 25 ),
26 path = "v2.rs" 26 path = "v2.rs"
27)] 27)]
28#[cfg_attr(any(rtc_v3, rtc_v3u5, rtc_v3l5), path = "v3.rs")] 28#[cfg_attr(any(rtc_v3, rtc_v3u5, rtc_v3l5, rtc_v3h7rs), path = "v3.rs")]
29mod _version; 29mod _version;
30#[allow(unused_imports)] 30#[allow(unused_imports)]
31pub use _version::*; 31pub use _version::*;
diff --git a/examples/mspm0c1104/build.rs b/examples/mspm0c1104/build.rs
index 30691aa97..2d777c2d3 100644
--- a/examples/mspm0c1104/build.rs
+++ b/examples/mspm0c1104/build.rs
@@ -32,4 +32,6 @@ fn main() {
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35 // You must tell cargo to link interrupt groups if the rt feature is enabled.
36 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
35} 37}
diff --git a/examples/mspm0g3507/build.rs b/examples/mspm0g3507/build.rs
index 30691aa97..2d777c2d3 100644
--- a/examples/mspm0g3507/build.rs
+++ b/examples/mspm0g3507/build.rs
@@ -32,4 +32,6 @@ fn main() {
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35 // You must tell cargo to link interrupt groups if the rt feature is enabled.
36 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
35} 37}
diff --git a/examples/mspm0g3519/build.rs b/examples/mspm0g3519/build.rs
index 30691aa97..2d777c2d3 100644
--- a/examples/mspm0g3519/build.rs
+++ b/examples/mspm0g3519/build.rs
@@ -32,4 +32,6 @@ fn main() {
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35 // You must tell cargo to link interrupt groups if the rt feature is enabled.
36 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
35} 37}
diff --git a/examples/mspm0l1306/build.rs b/examples/mspm0l1306/build.rs
index 30691aa97..2d777c2d3 100644
--- a/examples/mspm0l1306/build.rs
+++ b/examples/mspm0l1306/build.rs
@@ -32,4 +32,6 @@ fn main() {
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35 // You must tell cargo to link interrupt groups if the rt feature is enabled.
36 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
35} 37}
diff --git a/examples/mspm0l2228/build.rs b/examples/mspm0l2228/build.rs
index 30691aa97..2d777c2d3 100644
--- a/examples/mspm0l2228/build.rs
+++ b/examples/mspm0l2228/build.rs
@@ -32,4 +32,6 @@ fn main() {
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35 // You must tell cargo to link interrupt groups if the rt feature is enabled.
36 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
35} 37}
diff --git a/tests/mspm0/build.rs b/tests/mspm0/build.rs
index 57b592abf..0b58fb9e9 100644
--- a/tests/mspm0/build.rs
+++ b/tests/mspm0/build.rs
@@ -19,6 +19,8 @@ fn main() -> Result<(), Box<dyn Error>> {
19 println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); 19 println!("cargo:rustc-link-arg-bins=-Tlink_ram.x");
20 println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); 20 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
21 println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); 21 println!("cargo:rustc-link-arg-bins=-Tteleprobe.x");
22 // You must tell cargo to link interrupt groups if the rt feature is enabled.
23 println!("cargo:rustc-link-arg-bins=-Tinterrupt_group.x");
22 24
23 Ok(()) 25 Ok(())
24} 26}