aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-04-14 20:09:30 +0000
committerGitHub <[email protected]>2024-04-14 20:09:30 +0000
commitb6d06661bdb924951ded57db007460cebcc7849a (patch)
tree4f1867f6764be36dcedc023a7043fd81c0f83a9a
parentb1902957c99ff59b10c74ca7607299ddf14217ca (diff)
parent4079a8acf8d0d33dc1ca815475492cbf33407464 (diff)
Merge pull request #2791 from taunusflieger/feature/fix-spi
Fix for SPI and CRC reg changes in stm32-data
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs2
-rw-r--r--embassy-stm32/src/adc/g4.rs304
-rw-r--r--embassy-stm32/src/adc/mod.rs29
-rw-r--r--embassy-stm32/src/crc/v1.rs12
-rw-r--r--embassy-stm32/src/crc/v2v3.rs16
-rw-r--r--embassy-stm32/src/flash/f4.rs5
-rw-r--r--embassy-stm32/src/flash/h50.rs6
-rw-r--r--embassy-stm32/src/flash/mod.rs2
-rw-r--r--embassy-stm32/src/spi/mod.rs17
-rw-r--r--examples/stm32g4/src/bin/adc.rs2
11 files changed, 369 insertions, 30 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 89b24f0eb..93792ecf8 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -70,7 +70,7 @@ rand_core = "0.6.3"
70sdio-host = "0.5.0" 70sdio-host = "0.5.0"
71critical-section = "1.1" 71critical-section = "1.1"
72#stm32-metapac = { version = "15" } 72#stm32-metapac = { version = "15" }
73stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b7ec569a5510c324693f0515ac8ea20b12917a9" } 73stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-0c4baf478324e19741c7a9795ab0aa8217c3691c" }
74 74
75vcell = "0.1.3" 75vcell = "0.1.3"
76nb = "1.0.0" 76nb = "1.0.0"
@@ -96,7 +96,7 @@ proc-macro2 = "1.0.36"
96quote = "1.0.15" 96quote = "1.0.15"
97 97
98#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} 98#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
99stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b7ec569a5510c324693f0515ac8ea20b12917a9", default-features = false, features = ["metadata"]} 99stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-0c4baf478324e19741c7a9795ab0aa8217c3691c", default-features = false, features = ["metadata"]}
100 100
101[features] 101[features]
102default = ["rt"] 102default = ["rt"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 38b6c480c..0f87dd8ac 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -272,8 +272,6 @@ fn main() {
272 "Bank1" 272 "Bank1"
273 } else if region.name.starts_with("BANK_2") { 273 } else if region.name.starts_with("BANK_2") {
274 "Bank2" 274 "Bank2"
275 } else if region.name == "OTP" {
276 "Otp"
277 } else { 275 } else {
278 continue; 276 continue;
279 } 277 }
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
new file mode 100644
index 000000000..f6741f019
--- /dev/null
+++ b/embassy-stm32/src/adc/g4.rs
@@ -0,0 +1,304 @@
1#[allow(unused)]
2use pac::adc::vals::{Adcaldif, Difsel, Exten};
3use pac::adccommon::vals::Presc;
4
5use super::{blocking_delay_us, Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
6use crate::time::Hertz;
7use crate::{pac, Peripheral};
8
9/// Default VREF voltage used for sample conversion to millivolts.
10pub const VREF_DEFAULT_MV: u32 = 3300;
11/// VREF voltage used for factory calibration of VREFINTCAL register.
12pub const VREF_CALIB_MV: u32 = 3300;
13
14/// Max single ADC operation clock frequency
15#[cfg(stm32g4)]
16const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60);
17#[cfg(stm32h7)]
18const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50);
19
20#[cfg(stm32g4)]
21const VREF_CHANNEL: u8 = 18;
22#[cfg(stm32g4)]
23const TEMP_CHANNEL: u8 = 16;
24
25#[cfg(stm32h7)]
26const VREF_CHANNEL: u8 = 19;
27#[cfg(stm32h7)]
28const TEMP_CHANNEL: u8 = 18;
29
30// TODO this should be 14 for H7a/b/35
31const VBAT_CHANNEL: u8 = 17;
32
33// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs
34/// Internal voltage reference channel.
35pub struct VrefInt;
36impl<T: Instance> InternalChannel<T> for VrefInt {}
37impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
38 fn channel(&self) -> u8 {
39 VREF_CHANNEL
40 }
41}
42
43/// Internal temperature channel.
44pub struct Temperature;
45impl<T: Instance> InternalChannel<T> for Temperature {}
46impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
47 fn channel(&self) -> u8 {
48 TEMP_CHANNEL
49 }
50}
51
52/// Internal battery voltage channel.
53pub struct Vbat;
54impl<T: Instance> InternalChannel<T> for Vbat {}
55impl<T: Instance> super::SealedInternalChannel<T> for Vbat {
56 fn channel(&self) -> u8 {
57 VBAT_CHANNEL
58 }
59}
60
61// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
62// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
63#[allow(unused)]
64enum Prescaler {
65 NotDivided,
66 DividedBy2,
67 DividedBy4,
68 DividedBy6,
69 DividedBy8,
70 DividedBy10,
71 DividedBy12,
72 DividedBy16,
73 DividedBy32,
74 DividedBy64,
75 DividedBy128,
76 DividedBy256,
77}
78
79impl Prescaler {
80 fn from_ker_ck(frequency: Hertz) -> Self {
81 let raw_prescaler = frequency.0 / MAX_ADC_CLK_FREQ.0;
82 match raw_prescaler {
83 0 => Self::NotDivided,
84 1 => Self::DividedBy2,
85 2..=3 => Self::DividedBy4,
86 4..=5 => Self::DividedBy6,
87 6..=7 => Self::DividedBy8,
88 8..=9 => Self::DividedBy10,
89 10..=11 => Self::DividedBy12,
90 _ => unimplemented!(),
91 }
92 }
93
94 fn divisor(&self) -> u32 {
95 match self {
96 Prescaler::NotDivided => 1,
97 Prescaler::DividedBy2 => 2,
98 Prescaler::DividedBy4 => 4,
99 Prescaler::DividedBy6 => 6,
100 Prescaler::DividedBy8 => 8,
101 Prescaler::DividedBy10 => 10,
102 Prescaler::DividedBy12 => 12,
103 Prescaler::DividedBy16 => 16,
104 Prescaler::DividedBy32 => 32,
105 Prescaler::DividedBy64 => 64,
106 Prescaler::DividedBy128 => 128,
107 Prescaler::DividedBy256 => 256,
108 }
109 }
110
111 fn presc(&self) -> Presc {
112 match self {
113 Prescaler::NotDivided => Presc::DIV1,
114 Prescaler::DividedBy2 => Presc::DIV2,
115 Prescaler::DividedBy4 => Presc::DIV4,
116 Prescaler::DividedBy6 => Presc::DIV6,
117 Prescaler::DividedBy8 => Presc::DIV8,
118 Prescaler::DividedBy10 => Presc::DIV10,
119 Prescaler::DividedBy12 => Presc::DIV12,
120 Prescaler::DividedBy16 => Presc::DIV16,
121 Prescaler::DividedBy32 => Presc::DIV32,
122 Prescaler::DividedBy64 => Presc::DIV64,
123 Prescaler::DividedBy128 => Presc::DIV128,
124 Prescaler::DividedBy256 => Presc::DIV256,
125 }
126 }
127}
128
129impl<'d, T: Instance> Adc<'d, T> {
130 /// Create a new ADC driver.
131 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
132 embassy_hal_internal::into_ref!(adc);
133 T::enable_and_reset();
134
135 let prescaler = Prescaler::from_ker_ck(T::frequency());
136
137 T::common_regs().ccr().modify(|w| w.set_presc(prescaler.presc()));
138
139 let frequency = Hertz(T::frequency().0 / prescaler.divisor());
140 info!("ADC frequency set to {} Hz", frequency.0);
141
142 if frequency > MAX_ADC_CLK_FREQ {
143 panic!("Maximal allowed frequency for the ADC is {} MHz and it varies with different packages, refer to ST docs for more information.", MAX_ADC_CLK_FREQ.0 / 1_000_000 );
144 }
145
146 let mut s = Self {
147 adc,
148 sample_time: SampleTime::from_bits(0),
149 };
150 s.power_up();
151 s.configure_differential_inputs();
152
153 s.calibrate();
154 blocking_delay_us(1);
155
156 s.enable();
157 s.configure();
158
159 s
160 }
161
162 fn power_up(&mut self) {
163 T::regs().cr().modify(|reg| {
164 reg.set_deeppwd(false);
165 reg.set_advregen(true);
166 });
167
168 blocking_delay_us(10);
169 }
170
171 fn configure_differential_inputs(&mut self) {
172 T::regs().difsel().modify(|w| {
173 for n in 0..20 {
174 w.set_difsel(n, Difsel::SINGLEENDED);
175 }
176 });
177 }
178
179 fn calibrate(&mut self) {
180 T::regs().cr().modify(|w| {
181 w.set_adcaldif(Adcaldif::SINGLEENDED);
182 });
183
184 T::regs().cr().modify(|w| w.set_adcal(true));
185
186 while T::regs().cr().read().adcal() {}
187 }
188
189 fn enable(&mut self) {
190 T::regs().isr().write(|w| w.set_adrdy(true));
191 T::regs().cr().modify(|w| w.set_aden(true));
192 while !T::regs().isr().read().adrdy() {}
193 T::regs().isr().write(|w| w.set_adrdy(true));
194 }
195
196 fn configure(&mut self) {
197 // single conversion mode, software trigger
198 T::regs().cfgr().modify(|w| {
199 w.set_cont(false);
200 w.set_exten(Exten::DISABLED);
201 });
202 }
203
204 /// Enable reading the voltage reference internal channel.
205 pub fn enable_vrefint(&self) -> VrefInt {
206 T::common_regs().ccr().modify(|reg| {
207 reg.set_vrefen(true);
208 });
209
210 VrefInt {}
211 }
212
213 /// Enable reading the temperature internal channel.
214 pub fn enable_temperature(&self) -> Temperature {
215 T::common_regs().ccr().modify(|reg| {
216 reg.set_vsenseen(true);
217 });
218
219 Temperature {}
220 }
221
222 /// Enable reading the vbat internal channel.
223 pub fn enable_vbat(&self) -> Vbat {
224 T::common_regs().ccr().modify(|reg| {
225 reg.set_vbaten(true);
226 });
227
228 Vbat {}
229 }
230
231 /// Set the ADC sample time.
232 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
233 self.sample_time = sample_time;
234 }
235
236 /// Set the ADC resolution.
237 pub fn set_resolution(&mut self, resolution: Resolution) {
238 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
239 }
240
241 /// Perform a single conversion.
242 fn convert(&mut self) -> u16 {
243 T::regs().isr().modify(|reg| {
244 reg.set_eos(true);
245 reg.set_eoc(true);
246 });
247
248 // Start conversion
249 T::regs().cr().modify(|reg| {
250 reg.set_adstart(true);
251 });
252
253 while !T::regs().isr().read().eos() {
254 // spin
255 }
256
257 T::regs().dr().read().0 as u16
258 }
259
260 /// Read an ADC pin.
261 pub fn read<P>(&mut self, pin: &mut P) -> u16
262 where
263 P: AdcPin<T>,
264 P: crate::gpio::Pin,
265 {
266 pin.set_as_analog();
267
268 self.read_channel(pin.channel())
269 }
270
271 /// Read an ADC internal channel.
272 pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
273 self.read_channel(channel.channel())
274 }
275
276 fn read_channel(&mut self, channel: u8) -> u16 {
277 // Configure channel
278 Self::set_channel_sample_time(channel, self.sample_time);
279
280 #[cfg(stm32h7)]
281 {
282 T::regs().cfgr2().modify(|w| w.set_lshift(0));
283 T::regs()
284 .pcsel()
285 .write(|w| w.set_pcsel(channel as _, Pcsel::PRESELECTED));
286 }
287
288 T::regs().sqr1().write(|reg| {
289 reg.set_sq(0, channel);
290 reg.set_l(0);
291 });
292
293 self.convert()
294 }
295
296 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
297 let sample_time = sample_time.into();
298 if ch <= 9 {
299 T::regs().smpr().modify(|reg| reg.set_smp(ch as _, sample_time));
300 } else {
301 T::regs().smpr2().modify(|reg| reg.set_smp((ch - 10) as _, sample_time));
302 }
303 }
304}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 24dd7cc3c..12c5751bd 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -12,6 +12,7 @@
12#[cfg_attr(adc_v2, path = "v2.rs")] 12#[cfg_attr(adc_v2, path = "v2.rs")]
13#[cfg_attr(any(adc_v3, adc_g0, adc_h5), path = "v3.rs")] 13#[cfg_attr(any(adc_v3, adc_g0, adc_h5), path = "v3.rs")]
14#[cfg_attr(adc_v4, path = "v4.rs")] 14#[cfg_attr(adc_v4, path = "v4.rs")]
15#[cfg_attr(adc_g4, path = "g4.rs")]
15mod _version; 16mod _version;
16 17
17#[allow(unused)] 18#[allow(unused)]
@@ -79,13 +80,37 @@ pub(crate) fn blocking_delay_us(us: u32) {
79} 80}
80 81
81/// ADC instance. 82/// ADC instance.
82#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))] 83#[cfg(not(any(
84 adc_f1,
85 adc_v1,
86 adc_l0,
87 adc_v2,
88 adc_v3,
89 adc_v4,
90 adc_g4,
91 adc_f3,
92 adc_f3_v1_1,
93 adc_g0,
94 adc_h5
95)))]
83#[allow(private_bounds)] 96#[allow(private_bounds)]
84pub trait Instance: SealedInstance + crate::Peripheral<P = Self> { 97pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
85 type Interrupt: crate::interrupt::typelevel::Interrupt; 98 type Interrupt: crate::interrupt::typelevel::Interrupt;
86} 99}
87/// ADC instance. 100/// ADC instance.
88#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))] 101#[cfg(any(
102 adc_f1,
103 adc_v1,
104 adc_l0,
105 adc_v2,
106 adc_v3,
107 adc_v4,
108 adc_g4,
109 adc_f3,
110 adc_f3_v1_1,
111 adc_g0,
112 adc_h5
113))]
89#[allow(private_bounds)] 114#[allow(private_bounds)]
90pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { 115pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {
91 type Interrupt: crate::interrupt::typelevel::Interrupt; 116 type Interrupt: crate::interrupt::typelevel::Interrupt;
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs
index f8909d438..e8e0270af 100644
--- a/embassy-stm32/src/crc/v1.rs
+++ b/embassy-stm32/src/crc/v1.rs
@@ -32,6 +32,9 @@ impl<'d> Crc<'d> {
32 /// Feeds a word to the peripheral and returns the current CRC value 32 /// Feeds a word to the peripheral and returns the current CRC value
33 pub fn feed_word(&mut self, word: u32) -> u32 { 33 pub fn feed_word(&mut self, word: u32) -> u32 {
34 // write a single byte to the device, and return the result 34 // write a single byte to the device, and return the result
35 #[cfg(not(crc_v1))]
36 PAC_CRC.dr32().write_value(word);
37 #[cfg(crc_v1)]
35 PAC_CRC.dr().write_value(word); 38 PAC_CRC.dr().write_value(word);
36 self.read() 39 self.read()
37 } 40 }
@@ -39,6 +42,9 @@ impl<'d> Crc<'d> {
39 /// Feed a slice of words to the peripheral and return the result. 42 /// Feed a slice of words to the peripheral and return the result.
40 pub fn feed_words(&mut self, words: &[u32]) -> u32 { 43 pub fn feed_words(&mut self, words: &[u32]) -> u32 {
41 for word in words { 44 for word in words {
45 #[cfg(not(crc_v1))]
46 PAC_CRC.dr32().write_value(*word);
47 #[cfg(crc_v1)]
42 PAC_CRC.dr().write_value(*word); 48 PAC_CRC.dr().write_value(*word);
43 } 49 }
44 50
@@ -46,6 +52,12 @@ impl<'d> Crc<'d> {
46 } 52 }
47 53
48 /// Read the CRC result value. 54 /// Read the CRC result value.
55 #[cfg(not(crc_v1))]
56 pub fn read(&self) -> u32 {
57 PAC_CRC.dr32().read()
58 }
59 /// Read the CRC result value.
60 #[cfg(crc_v1)]
49 pub fn read(&self) -> u32 { 61 pub fn read(&self) -> u32 {
50 PAC_CRC.dr().read() 62 PAC_CRC.dr().read()
51 } 63 }
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs
index 46f5ea1be..13fb6778c 100644
--- a/embassy-stm32/src/crc/v2v3.rs
+++ b/embassy-stm32/src/crc/v2v3.rs
@@ -136,7 +136,7 @@ impl<'d> Crc<'d> {
136 /// Feeds a byte into the CRC peripheral. Returns the computed checksum. 136 /// Feeds a byte into the CRC peripheral. Returns the computed checksum.
137 pub fn feed_byte(&mut self, byte: u8) -> u32 { 137 pub fn feed_byte(&mut self, byte: u8) -> u32 {
138 PAC_CRC.dr8().write_value(byte); 138 PAC_CRC.dr8().write_value(byte);
139 PAC_CRC.dr().read() 139 PAC_CRC.dr32().read()
140 } 140 }
141 141
142 /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum. 142 /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum.
@@ -144,30 +144,30 @@ impl<'d> Crc<'d> {
144 for byte in bytes { 144 for byte in bytes {
145 PAC_CRC.dr8().write_value(*byte); 145 PAC_CRC.dr8().write_value(*byte);
146 } 146 }
147 PAC_CRC.dr().read() 147 PAC_CRC.dr32().read()
148 } 148 }
149 /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. 149 /// Feeds a halfword into the CRC peripheral. Returns the computed checksum.
150 pub fn feed_halfword(&mut self, halfword: u16) -> u32 { 150 pub fn feed_halfword(&mut self, halfword: u16) -> u32 {
151 PAC_CRC.dr16().write_value(halfword); 151 PAC_CRC.dr16().write_value(halfword);
152 PAC_CRC.dr().read() 152 PAC_CRC.dr32().read()
153 } 153 }
154 /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. 154 /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum.
155 pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 { 155 pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 {
156 for halfword in halfwords { 156 for halfword in halfwords {
157 PAC_CRC.dr16().write_value(*halfword); 157 PAC_CRC.dr16().write_value(*halfword);
158 } 158 }
159 PAC_CRC.dr().read() 159 PAC_CRC.dr32().read()
160 } 160 }
161 /// Feeds a words into the CRC peripheral. Returns the computed checksum. 161 /// Feeds a words into the CRC peripheral. Returns the computed checksum.
162 pub fn feed_word(&mut self, word: u32) -> u32 { 162 pub fn feed_word(&mut self, word: u32) -> u32 {
163 PAC_CRC.dr().write_value(word as u32); 163 PAC_CRC.dr32().write_value(word as u32);
164 PAC_CRC.dr().read() 164 PAC_CRC.dr32().read()
165 } 165 }
166 /// Feeds an slice of words into the CRC peripheral. Returns the computed checksum. 166 /// Feeds an slice of words into the CRC peripheral. Returns the computed checksum.
167 pub fn feed_words(&mut self, words: &[u32]) -> u32 { 167 pub fn feed_words(&mut self, words: &[u32]) -> u32 {
168 for word in words { 168 for word in words {
169 PAC_CRC.dr().write_value(*word as u32); 169 PAC_CRC.dr32().write_value(*word as u32);
170 } 170 }
171 PAC_CRC.dr().read() 171 PAC_CRC.dr32().read()
172 } 172 }
173} 173}
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index 00e61f2d2..90f13ff29 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -16,7 +16,7 @@ mod alt_regions {
16 use embassy_hal_internal::PeripheralRef; 16 use embassy_hal_internal::PeripheralRef;
17 use stm32_metapac::FLASH_SIZE; 17 use stm32_metapac::FLASH_SIZE;
18 18
19 use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; 19 use crate::_generated::flash_regions::{BANK1_REGION1, BANK1_REGION2, BANK1_REGION3};
20 use crate::flash::{asynch, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion}; 20 use crate::flash::{asynch, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion};
21 use crate::peripherals::FLASH; 21 use crate::peripherals::FLASH;
22 22
@@ -62,7 +62,6 @@ mod alt_regions {
62 pub bank2_region1: AltBank2Region1<'d, MODE>, 62 pub bank2_region1: AltBank2Region1<'d, MODE>,
63 pub bank2_region2: AltBank2Region2<'d, MODE>, 63 pub bank2_region2: AltBank2Region2<'d, MODE>,
64 pub bank2_region3: AltBank2Region3<'d, MODE>, 64 pub bank2_region3: AltBank2Region3<'d, MODE>,
65 pub otp_region: OTPRegion<'d, MODE>,
66 } 65 }
67 66
68 impl<'d> Flash<'d> { 67 impl<'d> Flash<'d> {
@@ -79,7 +78,6 @@ mod alt_regions {
79 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData), 78 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData),
80 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData), 79 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData),
81 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData), 80 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData),
82 otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }, PhantomData),
83 } 81 }
84 } 82 }
85 83
@@ -96,7 +94,6 @@ mod alt_regions {
96 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData), 94 bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }, PhantomData),
97 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData), 95 bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }, PhantomData),
98 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData), 96 bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }, PhantomData),
99 otp_region: OTPRegion(&OTP_REGION, unsafe { p.clone_unchecked() }, PhantomData),
100 } 97 }
101 } 98 }
102 } 99 }
diff --git a/embassy-stm32/src/flash/h50.rs b/embassy-stm32/src/flash/h50.rs
index db05bef5d..5b15be261 100644
--- a/embassy-stm32/src/flash/h50.rs
+++ b/embassy-stm32/src/flash/h50.rs
@@ -55,7 +55,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
55} 55}
56 56
57pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { 57pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> {
58 assert!(sector.bank != FlashBank::Otp);
59 assert!(sector.index_in_bank < 8); 58 assert!(sector.index_in_bank < 8);
60 59
61 while busy() {} 60 while busy() {}
@@ -63,9 +62,8 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E
63 interrupt::free(|_| { 62 interrupt::free(|_| {
64 pac::FLASH.nscr().modify(|w| { 63 pac::FLASH.nscr().modify(|w| {
65 w.set_bksel(match sector.bank { 64 w.set_bksel(match sector.bank {
66 FlashBank::Bank1 => Bksel::B_0X0, 65 FlashBank::Bank1 => Bksel::BANK1,
67 FlashBank::Bank2 => Bksel::B_0X1, 66 FlashBank::Bank2 => Bksel::BANK2,
68 _ => unreachable!(),
69 }); 67 });
70 w.set_snb(sector.index_in_bank); 68 w.set_snb(sector.index_in_bank);
71 w.set_ser(true); 69 w.set_ser(true);
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index 1d8031e82..9d7861816 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -89,8 +89,6 @@ pub enum FlashBank {
89 Bank1 = 0, 89 Bank1 = 0,
90 /// Bank 2 90 /// Bank 2
91 Bank2 = 1, 91 Bank2 = 1,
92 /// OTP region
93 Otp,
94} 92}
95 93
96#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")] 94#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")]
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 0b38c4288..450975f18 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -735,18 +735,22 @@ trait RegsExt {
735 735
736impl RegsExt for Regs { 736impl RegsExt for Regs {
737 fn tx_ptr<W>(&self) -> *mut W { 737 fn tx_ptr<W>(&self) -> *mut W {
738 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 738 #[cfg(any(spi_v1, spi_f1))]
739 let dr = self.dr(); 739 let dr = self.dr();
740 #[cfg(spi_v2)]
741 let dr = self.dr16();
740 #[cfg(any(spi_v3, spi_v4, spi_v5))] 742 #[cfg(any(spi_v3, spi_v4, spi_v5))]
741 let dr = self.txdr(); 743 let dr = self.txdr32();
742 dr.as_ptr() as *mut W 744 dr.as_ptr() as *mut W
743 } 745 }
744 746
745 fn rx_ptr<W>(&self) -> *mut W { 747 fn rx_ptr<W>(&self) -> *mut W {
746 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 748 #[cfg(any(spi_v1, spi_f1))]
747 let dr = self.dr(); 749 let dr = self.dr();
750 #[cfg(spi_v2)]
751 let dr = self.dr16();
748 #[cfg(any(spi_v3, spi_v4, spi_v5))] 752 #[cfg(any(spi_v3, spi_v4, spi_v5))]
749 let dr = self.rxdr(); 753 let dr = self.rxdr32();
750 dr.as_ptr() as *mut W 754 dr.as_ptr() as *mut W
751 } 755 }
752} 756}
@@ -815,11 +819,14 @@ fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> {
815fn flush_rx_fifo(regs: Regs) { 819fn flush_rx_fifo(regs: Regs) {
816 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 820 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))]
817 while regs.sr().read().rxne() { 821 while regs.sr().read().rxne() {
822 #[cfg(not(spi_v2))]
818 let _ = regs.dr().read(); 823 let _ = regs.dr().read();
824 #[cfg(spi_v2)]
825 let _ = regs.dr16().read();
819 } 826 }
820 #[cfg(any(spi_v3, spi_v4, spi_v5))] 827 #[cfg(any(spi_v3, spi_v4, spi_v5))]
821 while regs.sr().read().rxp() { 828 while regs.sr().read().rxp() {
822 let _ = regs.rxdr().read(); 829 let _ = regs.rxdr32().read();
823 } 830 }
824} 831}
825 832
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 68b54e406..3de38cbd6 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -29,7 +29,7 @@ async fn main(_spawner: Spawner) {
29 info!("Hello World!"); 29 info!("Hello World!");
30 30
31 let mut adc = Adc::new(p.ADC2); 31 let mut adc = Adc::new(p.ADC2);
32 adc.set_sample_time(SampleTime::CYCLES32_5); 32 adc.set_sample_time(SampleTime::CYCLES24_5);
33 33
34 loop { 34 loop {
35 let measured = adc.read(&mut p.PA7); 35 let measured = adc.read(&mut p.PA7);