aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/rust.yml5
-rw-r--r--embassy-stm32/Cargo.toml87
-rw-r--r--embassy-stm32/build.rs25
-rw-r--r--embassy-stm32/src/rcc/l1/mod.rs235
-rw-r--r--embassy-stm32/src/rcc/mod.rs5
-rw-r--r--examples/stm32l1/.cargo/config.toml18
-rw-r--r--examples/stm32l1/Cargo.toml35
-rw-r--r--examples/stm32l1/build.rs31
-rw-r--r--examples/stm32l1/memory.x5
-rw-r--r--examples/stm32l1/src/bin/blinky.rs30
-rw-r--r--examples/stm32l1/src/bin/spi.rs43
-rw-r--r--examples/stm32l1/src/example_common.rs17
-rw-r--r--examples/stm32l4/.cargo/config.toml3
-rw-r--r--rust-toolchain.toml2
m---------stm32-data0
-rw-r--r--stm32-gen-features/src/lib.rs3
-rw-r--r--stm32-metapac-gen/src/assets/build.rs11
-rw-r--r--stm32-metapac-gen/src/lib.rs2
-rw-r--r--stm32-metapac/build.rs11
19 files changed, 558 insertions, 10 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 79a5ad796..5cdf75d7b 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -78,6 +78,9 @@ jobs:
78 - package: embassy-stm32 78 - package: embassy-stm32
79 target: thumbv6m-none-eabi 79 target: thumbv6m-none-eabi
80 features: stm32l072cz,defmt 80 features: stm32l072cz,defmt
81 - package: embassy-stm32
82 target: thumbv7m-none-eabi
83 features: stm32l151cb-a,defmt
81 - package: examples/stm32f4 84 - package: examples/stm32f4
82 target: thumbv7em-none-eabi 85 target: thumbv7em-none-eabi
83 - package: examples/stm32l4 86 - package: examples/stm32l4
@@ -86,6 +89,8 @@ jobs:
86 target: thumbv7em-none-eabi 89 target: thumbv7em-none-eabi
87 - package: examples/stm32l0 90 - package: examples/stm32l0
88 target: thumbv6m-none-eabi 91 target: thumbv6m-none-eabi
92 - package: examples/stm32l1
93 target: thumbv7m-none-eabi
89 - package: examples/stm32wb55 94 - package: examples/stm32wb55
90 target: thumbv7em-none-eabihf 95 target: thumbv7em-none-eabihf
91 - package: examples/stm32wl55 96 - package: examples/stm32wl55
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index dec336588..3e91040f0 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -625,6 +625,93 @@ stm32l083rz = [ "stm32-metapac/stm32l083rz" ]
625stm32l083v8 = [ "stm32-metapac/stm32l083v8" ] 625stm32l083v8 = [ "stm32-metapac/stm32l083v8" ]
626stm32l083vb = [ "stm32-metapac/stm32l083vb" ] 626stm32l083vb = [ "stm32-metapac/stm32l083vb" ]
627stm32l083vz = [ "stm32-metapac/stm32l083vz" ] 627stm32l083vz = [ "stm32-metapac/stm32l083vz" ]
628stm32l100c6-a = [ "stm32-metapac/stm32l100c6-a" ]
629stm32l100c6 = [ "stm32-metapac/stm32l100c6" ]
630stm32l100r8-a = [ "stm32-metapac/stm32l100r8-a" ]
631stm32l100r8 = [ "stm32-metapac/stm32l100r8" ]
632stm32l100rb-a = [ "stm32-metapac/stm32l100rb-a" ]
633stm32l100rb = [ "stm32-metapac/stm32l100rb" ]
634stm32l100rc = [ "stm32-metapac/stm32l100rc" ]
635stm32l151c6-a = [ "stm32-metapac/stm32l151c6-a" ]
636stm32l151c6 = [ "stm32-metapac/stm32l151c6" ]
637stm32l151c8-a = [ "stm32-metapac/stm32l151c8-a" ]
638stm32l151c8 = [ "stm32-metapac/stm32l151c8" ]
639stm32l151cb-a = [ "stm32-metapac/stm32l151cb-a" ]
640stm32l151cb = [ "stm32-metapac/stm32l151cb" ]
641stm32l151cc = [ "stm32-metapac/stm32l151cc" ]
642stm32l151qc = [ "stm32-metapac/stm32l151qc" ]
643stm32l151qd = [ "stm32-metapac/stm32l151qd" ]
644stm32l151qe = [ "stm32-metapac/stm32l151qe" ]
645stm32l151r6-a = [ "stm32-metapac/stm32l151r6-a" ]
646stm32l151r6 = [ "stm32-metapac/stm32l151r6" ]
647stm32l151r8-a = [ "stm32-metapac/stm32l151r8-a" ]
648stm32l151r8 = [ "stm32-metapac/stm32l151r8" ]
649stm32l151rb-a = [ "stm32-metapac/stm32l151rb-a" ]
650stm32l151rb = [ "stm32-metapac/stm32l151rb" ]
651stm32l151rc-a = [ "stm32-metapac/stm32l151rc-a" ]
652stm32l151rc = [ "stm32-metapac/stm32l151rc" ]
653stm32l151rd = [ "stm32-metapac/stm32l151rd" ]
654stm32l151re = [ "stm32-metapac/stm32l151re" ]
655stm32l151uc = [ "stm32-metapac/stm32l151uc" ]
656stm32l151v8-a = [ "stm32-metapac/stm32l151v8-a" ]
657stm32l151v8 = [ "stm32-metapac/stm32l151v8" ]
658stm32l151vb-a = [ "stm32-metapac/stm32l151vb-a" ]
659stm32l151vb = [ "stm32-metapac/stm32l151vb" ]
660stm32l151vc-a = [ "stm32-metapac/stm32l151vc-a" ]
661stm32l151vc = [ "stm32-metapac/stm32l151vc" ]
662stm32l151vd-x = [ "stm32-metapac/stm32l151vd-x" ]
663stm32l151vd = [ "stm32-metapac/stm32l151vd" ]
664stm32l151ve = [ "stm32-metapac/stm32l151ve" ]
665stm32l151zc = [ "stm32-metapac/stm32l151zc" ]
666stm32l151zd = [ "stm32-metapac/stm32l151zd" ]
667stm32l151ze = [ "stm32-metapac/stm32l151ze" ]
668stm32l152c6-a = [ "stm32-metapac/stm32l152c6-a" ]
669stm32l152c6 = [ "stm32-metapac/stm32l152c6" ]
670stm32l152c8-a = [ "stm32-metapac/stm32l152c8-a" ]
671stm32l152c8 = [ "stm32-metapac/stm32l152c8" ]
672stm32l152cb-a = [ "stm32-metapac/stm32l152cb-a" ]
673stm32l152cb = [ "stm32-metapac/stm32l152cb" ]
674stm32l152cc = [ "stm32-metapac/stm32l152cc" ]
675stm32l152qc = [ "stm32-metapac/stm32l152qc" ]
676stm32l152qd = [ "stm32-metapac/stm32l152qd" ]
677stm32l152qe = [ "stm32-metapac/stm32l152qe" ]
678stm32l152r6-a = [ "stm32-metapac/stm32l152r6-a" ]
679stm32l152r6 = [ "stm32-metapac/stm32l152r6" ]
680stm32l152r8-a = [ "stm32-metapac/stm32l152r8-a" ]
681stm32l152r8 = [ "stm32-metapac/stm32l152r8" ]
682stm32l152rb-a = [ "stm32-metapac/stm32l152rb-a" ]
683stm32l152rb = [ "stm32-metapac/stm32l152rb" ]
684stm32l152rc-a = [ "stm32-metapac/stm32l152rc-a" ]
685stm32l152rc = [ "stm32-metapac/stm32l152rc" ]
686stm32l152rd = [ "stm32-metapac/stm32l152rd" ]
687stm32l152re = [ "stm32-metapac/stm32l152re" ]
688stm32l152uc = [ "stm32-metapac/stm32l152uc" ]
689stm32l152v8-a = [ "stm32-metapac/stm32l152v8-a" ]
690stm32l152v8 = [ "stm32-metapac/stm32l152v8" ]
691stm32l152vb-a = [ "stm32-metapac/stm32l152vb-a" ]
692stm32l152vb = [ "stm32-metapac/stm32l152vb" ]
693stm32l152vc-a = [ "stm32-metapac/stm32l152vc-a" ]
694stm32l152vc = [ "stm32-metapac/stm32l152vc" ]
695stm32l152vd-x = [ "stm32-metapac/stm32l152vd-x" ]
696stm32l152vd = [ "stm32-metapac/stm32l152vd" ]
697stm32l152ve = [ "stm32-metapac/stm32l152ve" ]
698stm32l152zc = [ "stm32-metapac/stm32l152zc" ]
699stm32l152zd = [ "stm32-metapac/stm32l152zd" ]
700stm32l152ze = [ "stm32-metapac/stm32l152ze" ]
701stm32l162qc = [ "stm32-metapac/stm32l162qc" ]
702stm32l162qd = [ "stm32-metapac/stm32l162qd" ]
703stm32l162rc-a = [ "stm32-metapac/stm32l162rc-a" ]
704stm32l162rc = [ "stm32-metapac/stm32l162rc" ]
705stm32l162rd = [ "stm32-metapac/stm32l162rd" ]
706stm32l162re = [ "stm32-metapac/stm32l162re" ]
707stm32l162vc-a = [ "stm32-metapac/stm32l162vc-a" ]
708stm32l162vc = [ "stm32-metapac/stm32l162vc" ]
709stm32l162vd-x = [ "stm32-metapac/stm32l162vd-x" ]
710stm32l162vd = [ "stm32-metapac/stm32l162vd" ]
711stm32l162ve = [ "stm32-metapac/stm32l162ve" ]
712stm32l162zc = [ "stm32-metapac/stm32l162zc" ]
713stm32l162zd = [ "stm32-metapac/stm32l162zd" ]
714stm32l162ze = [ "stm32-metapac/stm32l162ze" ]
628stm32l412c8 = [ "stm32-metapac/stm32l412c8" ] 715stm32l412c8 = [ "stm32-metapac/stm32l412c8" ]
629stm32l412cb = [ "stm32-metapac/stm32l412cb" ] 716stm32l412cb = [ "stm32-metapac/stm32l412cb" ]
630stm32l412k8 = [ "stm32-metapac/stm32l412k8" ] 717stm32l412k8 = [ "stm32-metapac/stm32l412k8" ]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 8bb78a6f2..32115f9a8 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -85,13 +85,28 @@ fn main() {
85 }; 85 };
86 ); 86 );
87 87
88 let mut chip_and_core = chip_name.split('_'); 88 let mut s = chip_name.split('_');
89 let chip = chip_and_core.next().expect("Unexpected stm32xx feature"); 89 let mut chip_name: String = s.next().unwrap().to_string();
90 let core_name = if let Some(c) = s.next() {
91 if !c.starts_with("CM") {
92 chip_name.push('_');
93 chip_name.push_str(c);
94 None
95 } else {
96 Some(c)
97 }
98 } else {
99 None
100 };
90 101
91 if let Some(core) = chip_and_core.next() { 102 if let Some(core) = core_name {
92 println!("cargo:rustc-cfg={}_{}", &chip[..(chip.len() - 2)], core); 103 println!(
104 "cargo:rustc-cfg={}_{}",
105 &chip_name[..chip_name.len() - 2],
106 core
107 );
93 } else { 108 } else {
94 println!("cargo:rustc-cfg={}", &chip[..(chip.len() - 2)]); 109 println!("cargo:rustc-cfg={}", &chip_name[..chip_name.len() - 2]);
95 } 110 }
96 111
97 println!("cargo:rerun-if-changed=build.rs"); 112 println!("cargo:rerun-if-changed=build.rs");
diff --git a/embassy-stm32/src/rcc/l1/mod.rs b/embassy-stm32/src/rcc/l1/mod.rs
new file mode 100644
index 000000000..25b5609c4
--- /dev/null
+++ b/embassy-stm32/src/rcc/l1/mod.rs
@@ -0,0 +1,235 @@
1pub use super::types::*;
2use crate::pac;
3use crate::peripherals::{self, RCC};
4use crate::rcc::{get_freqs, set_freqs, Clocks};
5use crate::time::Hertz;
6use crate::time::U32Ext;
7use core::marker::PhantomData;
8use embassy::util::Unborrow;
9use embassy_hal_common::unborrow;
10use pac::rcc::vals::{Hpre, Ppre, Sw};
11
12/// Most of clock setup is copied from rcc/l0
13
14/// HSI speed
15pub const HSI_FREQ: u32 = 16_000_000;
16
17/// System clock mux source
18#[derive(Clone, Copy)]
19pub enum ClockSrc {
20 MSI(MSIRange),
21 HSE(Hertz),
22 HSI,
23}
24
25impl Into<Ppre> for APBPrescaler {
26 fn into(self) -> Ppre {
27 match self {
28 APBPrescaler::NotDivided => Ppre::DIV1,
29 APBPrescaler::Div2 => Ppre::DIV2,
30 APBPrescaler::Div4 => Ppre::DIV4,
31 APBPrescaler::Div8 => Ppre::DIV8,
32 APBPrescaler::Div16 => Ppre::DIV16,
33 }
34 }
35}
36
37impl Into<Hpre> for AHBPrescaler {
38 fn into(self) -> Hpre {
39 match self {
40 AHBPrescaler::NotDivided => Hpre::DIV1,
41 AHBPrescaler::Div2 => Hpre::DIV2,
42 AHBPrescaler::Div4 => Hpre::DIV4,
43 AHBPrescaler::Div8 => Hpre::DIV8,
44 AHBPrescaler::Div16 => Hpre::DIV16,
45 AHBPrescaler::Div64 => Hpre::DIV64,
46 AHBPrescaler::Div128 => Hpre::DIV128,
47 AHBPrescaler::Div256 => Hpre::DIV256,
48 AHBPrescaler::Div512 => Hpre::DIV512,
49 }
50 }
51}
52
53impl Into<u8> for MSIRange {
54 fn into(self) -> u8 {
55 match self {
56 MSIRange::Range0 => 0b000,
57 MSIRange::Range1 => 0b001,
58 MSIRange::Range2 => 0b010,
59 MSIRange::Range3 => 0b011,
60 MSIRange::Range4 => 0b100,
61 MSIRange::Range5 => 0b101,
62 MSIRange::Range6 => 0b110,
63 }
64 }
65}
66
67/// Clocks configutation
68pub struct Config {
69 mux: ClockSrc,
70 ahb_pre: AHBPrescaler,
71 apb1_pre: APBPrescaler,
72 apb2_pre: APBPrescaler,
73}
74
75impl Default for Config {
76 #[inline]
77 fn default() -> Config {
78 Config {
79 mux: ClockSrc::MSI(MSIRange::default()),
80 ahb_pre: AHBPrescaler::NotDivided,
81 apb1_pre: APBPrescaler::NotDivided,
82 apb2_pre: APBPrescaler::NotDivided,
83 }
84 }
85}
86
87impl Config {
88 #[inline]
89 pub fn clock_src(mut self, mux: ClockSrc) -> Self {
90 self.mux = mux;
91 self
92 }
93
94 #[inline]
95 pub fn ahb_pre(mut self, pre: AHBPrescaler) -> Self {
96 self.ahb_pre = pre;
97 self
98 }
99
100 #[inline]
101 pub fn apb1_pre(mut self, pre: APBPrescaler) -> Self {
102 self.apb1_pre = pre;
103 self
104 }
105
106 #[inline]
107 pub fn apb2_pre(mut self, pre: APBPrescaler) -> Self {
108 self.apb2_pre = pre;
109 self
110 }
111}
112
113/// RCC peripheral
114pub struct Rcc<'d> {
115 _rb: peripherals::RCC,
116 phantom: PhantomData<&'d mut peripherals::RCC>,
117}
118
119impl<'d> Rcc<'d> {
120 pub fn new(rcc: impl Unborrow<Target = peripherals::RCC> + 'd) -> Self {
121 unborrow!(rcc);
122 Self {
123 _rb: rcc,
124 phantom: PhantomData,
125 }
126 }
127
128 // Safety: RCC init must have been called
129 pub fn clocks(&self) -> &'static Clocks {
130 unsafe { get_freqs() }
131 }
132}
133
134/// Extension trait that freezes the `RCC` peripheral with provided clocks configuration
135pub trait RccExt {
136 fn freeze(self, config: Config) -> Clocks;
137}
138
139impl RccExt for RCC {
140 // `cfgr` is almost always a constant, so make sure it can be constant-propagated properly by
141 // marking this function and all `Config` constructors and setters as `#[inline]`.
142 // This saves ~900 Bytes for the `pwr.rs` example.
143 #[inline]
144 fn freeze(self, cfgr: Config) -> Clocks {
145 let rcc = pac::RCC;
146 let (sys_clk, sw) = match cfgr.mux {
147 ClockSrc::MSI(range) => {
148 // Set MSI range
149 unsafe {
150 rcc.icscr().write(|w| w.set_msirange(range.into()));
151 }
152
153 // Enable MSI
154 unsafe {
155 rcc.cr().write(|w| w.set_msion(true));
156 while !rcc.cr().read().msirdy() {}
157 }
158
159 let freq = 32_768 * (1 << (range as u8 + 1));
160 (freq, Sw::MSI)
161 }
162 ClockSrc::HSI => {
163 // Enable HSI
164 unsafe {
165 rcc.cr().write(|w| w.set_hsion(true));
166 while !rcc.cr().read().hsirdy() {}
167 }
168
169 (HSI_FREQ, Sw::HSI)
170 }
171 ClockSrc::HSE(freq) => {
172 // Enable HSE
173 unsafe {
174 rcc.cr().write(|w| w.set_hseon(true));
175 while !rcc.cr().read().hserdy() {}
176 }
177
178 (freq.0, Sw::HSE)
179 }
180 };
181
182 unsafe {
183 rcc.cfgr().modify(|w| {
184 w.set_sw(sw.into());
185 w.set_hpre(cfgr.ahb_pre.into());
186 w.set_ppre1(cfgr.apb1_pre.into());
187 w.set_ppre2(cfgr.apb2_pre.into());
188 });
189 }
190
191 let ahb_freq: u32 = match cfgr.ahb_pre {
192 AHBPrescaler::NotDivided => sys_clk,
193 pre => {
194 let pre: Hpre = pre.into();
195 let pre = 1 << (pre.0 as u32 - 7);
196 sys_clk / pre
197 }
198 };
199
200 let (apb1_freq, apb1_tim_freq) = match cfgr.apb1_pre {
201 APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
202 pre => {
203 let pre: Ppre = pre.into();
204 let pre: u8 = 1 << (pre.0 - 3);
205 let freq = ahb_freq / pre as u32;
206 (freq, freq * 2)
207 }
208 };
209
210 let (apb2_freq, apb2_tim_freq) = match cfgr.apb2_pre {
211 APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
212 pre => {
213 let pre: Ppre = pre.into();
214 let pre: u8 = 1 << (pre.0 - 3);
215 let freq = ahb_freq / (1 << (pre as u8 - 3));
216 (freq, freq * 2)
217 }
218 };
219
220 Clocks {
221 sys: sys_clk.hz(),
222 ahb: ahb_freq.hz(),
223 apb1: apb1_freq.hz(),
224 apb2: apb2_freq.hz(),
225 apb1_tim: apb1_tim_freq.hz(),
226 apb2_tim: apb2_tim_freq.hz(),
227 }
228 }
229}
230
231pub unsafe fn init(config: Config) {
232 let r = <peripherals::RCC as embassy::util::Steal>::steal();
233 let clocks = r.freeze(config);
234 set_freqs(clocks);
235}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 791b86c0d..d6b4bec5f 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -27,7 +27,7 @@ pub struct Clocks {
27 #[cfg(rcc_wl5)] 27 #[cfg(rcc_wl5)]
28 pub apb3: Hertz, 28 pub apb3: Hertz,
29 29
30 #[cfg(any(rcc_l0, rcc_f0, rcc_f0x0, rcc_g0))] 30 #[cfg(any(rcc_l0, rcc_l1, rcc_f0, rcc_f0x0, rcc_g0))]
31 pub ahb: Hertz, 31 pub ahb: Hertz,
32 32
33 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))] 33 #[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb, rcc_wl5))]
@@ -73,6 +73,9 @@ cfg_if::cfg_if! {
73 } else if #[cfg(rcc_l0)] { 73 } else if #[cfg(rcc_l0)] {
74 mod l0; 74 mod l0;
75 pub use l0::*; 75 pub use l0::*;
76 } else if #[cfg(rcc_l1)] {
77 mod l1;
78 pub use l1::*;
76 } else if #[cfg(rcc_l4)] { 79 } else if #[cfg(rcc_l4)] {
77 mod l4; 80 mod l4;
78 pub use l4::*; 81 pub use l4::*;
diff --git a/examples/stm32l1/.cargo/config.toml b/examples/stm32l1/.cargo/config.toml
new file mode 100644
index 000000000..e0d2bddf0
--- /dev/null
+++ b/examples/stm32l1/.cargo/config.toml
@@ -0,0 +1,18 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-run --list-chips`
3runner = "probe-run --chip STM32L151CBxxA"
4
5rustflags = [
6 # LLD (shipped with the Rust toolchain) is used as the default linker
7 "-C", "link-arg=--nmagic",
8 "-C", "link-arg=-Tlink.x",
9 "-C", "link-arg=-Tdefmt.x",
10
11 # Code-size optimizations.
12 "-Z", "trap-unreachable=no",
13 "-C", "inline-threshold=5",
14 "-C", "no-vectorize-loops",
15]
16
17[build]
18target = "thumbv7m-none-eabi"
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
new file mode 100644
index 000000000..e4dd7186a
--- /dev/null
+++ b/examples/stm32l1/Cargo.toml
@@ -0,0 +1,35 @@
1[package]
2authors = ["Dario Nieuwenhuis <[email protected]>", "Ulf Lilleengen <[email protected]>"]
3edition = "2018"
4name = "embassy-stm32l1-examples"
5version = "0.1.0"
6resolver = "2"
7
8[features]
9default = [
10 "defmt-default",
11]
12defmt-default = []
13defmt-trace = []
14defmt-debug = []
15defmt-info = []
16defmt-warn = []
17defmt-error = []
18
19[dependencies]
20embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-trace"] }
21embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
22embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "defmt-trace", "stm32l151cb-a", "time-driver-tim2", "memory-x"] }
23embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" }
24embassy-macros = { path = "../../embassy-macros" }
25
26defmt = "0.2.3"
27defmt-rtt = "0.2.0"
28
29cortex-m = "0.7.3"
30cortex-m-rt = "0.7.0"
31embedded-hal = "0.2.6"
32panic-probe = { version = "0.2.0", features = ["print-defmt"] }
33futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
34rtt-target = { version = "0.3.1", features = ["cortex-m"] }
35heapless = { version = "0.7.5", default-features = false }
diff --git a/examples/stm32l1/build.rs b/examples/stm32l1/build.rs
new file mode 100644
index 000000000..d534cc3df
--- /dev/null
+++ b/examples/stm32l1/build.rs
@@ -0,0 +1,31 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31}
diff --git a/examples/stm32l1/memory.x b/examples/stm32l1/memory.x
new file mode 100644
index 000000000..c94d395c8
--- /dev/null
+++ b/examples/stm32l1/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x08000000, LENGTH = 128K
4 RAM : ORIGIN = 0x20000000, LENGTH = 32K
5}
diff --git a/examples/stm32l1/src/bin/blinky.rs b/examples/stm32l1/src/bin/blinky.rs
new file mode 100644
index 000000000..deabdddba
--- /dev/null
+++ b/examples/stm32l1/src/bin/blinky.rs
@@ -0,0 +1,30 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5#[path = "../example_common.rs"]
6mod example_common;
7
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy_stm32::gpio::{Level, Output, Speed};
11use embassy_stm32::Peripherals;
12use embedded_hal::digital::v2::OutputPin;
13use example_common::*;
14
15#[embassy::main]
16async fn main(_spawner: Spawner, p: Peripherals) {
17 info!("Hello World!");
18
19 let mut led = Output::new(p.PA12, Level::High, Speed::Low);
20
21 loop {
22 info!("high");
23 unwrap!(led.set_high());
24 Timer::after(Duration::from_millis(1000)).await;
25
26 info!("low");
27 unwrap!(led.set_low());
28 Timer::after(Duration::from_millis(1000)).await;
29 }
30}
diff --git a/examples/stm32l1/src/bin/spi.rs b/examples/stm32l1/src/bin/spi.rs
new file mode 100644
index 000000000..3cfbe3fc4
--- /dev/null
+++ b/examples/stm32l1/src/bin/spi.rs
@@ -0,0 +1,43 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5#[path = "../example_common.rs"]
6mod example_common;
7
8use embassy::executor::Spawner;
9use embassy_stm32::gpio::{Level, Output, Speed};
10use embedded_hal::digital::v2::OutputPin;
11use example_common::*;
12
13use embassy_stm32::dma::NoDma;
14use embassy_stm32::spi::{Config, Spi};
15use embassy_stm32::time::Hertz;
16use embassy_stm32::Peripherals;
17use embedded_hal::blocking::spi::Transfer;
18
19#[embassy::main]
20async fn main(_spawner: Spawner, p: Peripherals) {
21 info!("Hello World, folks!");
22
23 let mut spi = Spi::new(
24 p.SPI1,
25 p.PA5,
26 p.PA7,
27 p.PA6,
28 NoDma,
29 NoDma,
30 Hertz(1_000_000),
31 Config::default(),
32 );
33
34 let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh);
35
36 loop {
37 let mut buf = [0x0Au8; 4];
38 unwrap!(cs.set_low());
39 unwrap!(spi.transfer(&mut buf));
40 unwrap!(cs.set_high());
41 info!("xfer {=[u8]:x}", buf);
42 }
43}
diff --git a/examples/stm32l1/src/example_common.rs b/examples/stm32l1/src/example_common.rs
new file mode 100644
index 000000000..54d633837
--- /dev/null
+++ b/examples/stm32l1/src/example_common.rs
@@ -0,0 +1,17 @@
1#![macro_use]
2
3use defmt_rtt as _; // global logger
4use panic_probe as _;
5
6pub use defmt::*;
7
8use core::sync::atomic::{AtomicUsize, Ordering};
9
10defmt::timestamp! {"{=u64}", {
11 static COUNT: AtomicUsize = AtomicUsize::new(0);
12 // NOTE(no-CAS) `timestamps` runs with interrupts disabled
13 let n = COUNT.load(Ordering::Relaxed);
14 COUNT.store(n + 1, Ordering::Relaxed);
15 n as u64
16 }
17}
diff --git a/examples/stm32l4/.cargo/config.toml b/examples/stm32l4/.cargo/config.toml
index 38dd98d1e..b157e3aeb 100644
--- a/examples/stm32l4/.cargo/config.toml
+++ b/examples/stm32l4/.cargo/config.toml
@@ -1,6 +1,7 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32F429ZITx with your chip as listed in `probe-run --list-chips` 2# replace STM32F429ZITx with your chip as listed in `probe-run --list-chips`
3runner = "probe-run --chip STM32L4S5VI" 3#runner = "probe-run --chip STM32L475VGT6"
4runner = "probe-run --chip STM32L475VG"
4 5
5rustflags = [ 6rustflags = [
6 # LLD (shipped with the Rust toolchain) is used as the default linker 7 # LLD (shipped with the Rust toolchain) is used as the default linker
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index d7ad907fd..8f3473433 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -3,4 +3,4 @@
3[toolchain] 3[toolchain]
4channel = "nightly-2021-08-18" 4channel = "nightly-2021-08-18"
5components = [ "rust-src", "rustfmt" ] 5components = [ "rust-src", "rustfmt" ]
6targets = [ "thumbv7em-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "wasm32-unknown-unknown" ] 6targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "wasm32-unknown-unknown" ]
diff --git a/stm32-data b/stm32-data
Subproject 3fb217ad3eebe2d8808b8af4d04ce051c69ecb7 Subproject 7f5f8e7c641d74a0e97e2d84bac61b7c6c267a7
diff --git a/stm32-gen-features/src/lib.rs b/stm32-gen-features/src/lib.rs
index 597d78b07..75eb7d756 100644
--- a/stm32-gen-features/src/lib.rs
+++ b/stm32-gen-features/src/lib.rs
@@ -2,11 +2,12 @@
2 2
3use std::{iter::FilterMap, path::Path, slice::Iter}; 3use std::{iter::FilterMap, path::Path, slice::Iter};
4 4
5const SUPPORTED_FAMILIES: [&str; 8] = [ 5const SUPPORTED_FAMILIES: [&str; 9] = [
6 "stm32f0", 6 "stm32f0",
7 "stm32f4", 7 "stm32f4",
8 "stm32g0", 8 "stm32g0",
9 "stm32l0", 9 "stm32l0",
10 "stm32l1",
10 "stm32l4", 11 "stm32l4",
11 "stm32h7", 12 "stm32h7",
12 "stm32wb55", 13 "stm32wb55",
diff --git a/stm32-metapac-gen/src/assets/build.rs b/stm32-metapac-gen/src/assets/build.rs
index 4110fe485..1c9411151 100644
--- a/stm32-metapac-gen/src/assets/build.rs
+++ b/stm32-metapac-gen/src/assets/build.rs
@@ -9,6 +9,17 @@ fn main() {
9 .unwrap() 9 .unwrap()
10 .to_ascii_lowercase(); 10 .to_ascii_lowercase();
11 11
12 let mut s = chip_name.split('_');
13 let mut chip_name: String = s.next().unwrap().to_string();
14 if let Some(c) = s.next() {
15 if !c.starts_with("CM") {
16 chip_name.push('-');
17 } else {
18 chip_name.push('_');
19 }
20 chip_name.push_str(c);
21 }
22
12 #[cfg(feature = "memory-x")] 23 #[cfg(feature = "memory-x")]
13 println!("cargo:rustc-link-search=src/chips/{}/memory_x/", _chip_name); 24 println!("cargo:rustc-link-search=src/chips/{}/memory_x/", _chip_name);
14 25
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index 3bfd5297f..5c0f1d00c 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -218,7 +218,7 @@ pub fn gen(options: Options) {
218 let core_name: Option<&str> = if let Some(c) = s.next() { 218 let core_name: Option<&str> = if let Some(c) = s.next() {
219 if !c.starts_with("CM") { 219 if !c.starts_with("CM") {
220 println!("Core not detected, adding as variant"); 220 println!("Core not detected, adding as variant");
221 chip_name.push_str("-"); 221 chip_name.push('-');
222 chip_name.push_str(c); 222 chip_name.push_str(c);
223 None 223 None
224 } else { 224 } else {
diff --git a/stm32-metapac/build.rs b/stm32-metapac/build.rs
index ca964c9ec..d840d8fe0 100644
--- a/stm32-metapac/build.rs
+++ b/stm32-metapac/build.rs
@@ -22,6 +22,17 @@ fn main() {
22 chips: vec![chip_name.clone()], 22 chips: vec![chip_name.clone()],
23 }); 23 });
24 24
25 let mut s = chip_name.split('_');
26 let mut chip_name: String = s.next().unwrap().to_string();
27 if let Some(c) = s.next() {
28 if !c.starts_with("CM") {
29 chip_name.push('-');
30 } else {
31 chip_name.push('_');
32 }
33 chip_name.push_str(c);
34 }
35
25 println!( 36 println!(
26 "cargo:rustc-link-search={}/src/chips/{}", 37 "cargo:rustc-link-search={}/src/chips/{}",
27 out_dir.display(), 38 out_dir.display(),