aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/CHANGELOG.md3
-rw-r--r--embassy-stm32/src/adc/g4.rs23
-rw-r--r--embassy-stm32/src/adc/v3.rs22
-rw-r--r--embassy-stm32/src/sai/mod.rs4
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs13
-rw-r--r--examples/stm32h723/src/bin/spdifrx.rs2
6 files changed, 51 insertions, 16 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md
index cb846588e..72fe1c7a8 100644
--- a/embassy-stm32/CHANGELOG.md
+++ b/embassy-stm32/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8## Unreleased - ReleaseDate 8## Unreleased - ReleaseDate
9 9
10- chore: cleanup low-power add time 10- chore: cleanup low-power add time
11- fix: Allow setting SAI peripheral `frame_length` to `256`
11- fix: flash erase on dual-bank STM32Gxxx 12- fix: flash erase on dual-bank STM32Gxxx
12- feat: Add support for STM32N657X0 13- feat: Add support for STM32N657X0
13- feat: timer: Add 32-bit timer support to SimplePwm waveform_up method following waveform pattern ([#4717](https://github.com/embassy-rs/embassy/pull/4717)) 14- feat: timer: Add 32-bit timer support to SimplePwm waveform_up method following waveform pattern ([#4717](https://github.com/embassy-rs/embassy/pull/4717))
@@ -59,6 +60,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
59- adc: reogranize and cleanup somewhat. require sample_time to be passed on conversion 60- adc: reogranize and cleanup somewhat. require sample_time to be passed on conversion
60- fix: stm32/i2c v2 slave: prevent misaligned reads, error false positives, and incorrect counts of bytes read/written 61- fix: stm32/i2c v2 slave: prevent misaligned reads, error false positives, and incorrect counts of bytes read/written
61- feat: add flash support for c0 family ([#4874](https://github.com/embassy-rs/embassy/pull/4874)) 62- feat: add flash support for c0 family ([#4874](https://github.com/embassy-rs/embassy/pull/4874))
63- fix: fixing channel numbers on vbat and vddcore for adc on adc
64- adc: adding disable to vbat
62 65
63## 0.4.0 - 2025-08-26 66## 0.4.0 - 2025-08-26
64 67
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 514734017..bd8ccbf17 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -1,3 +1,5 @@
1#[cfg(stm32g4)]
2use pac::adc::regs::Difsel as DifselReg;
1#[allow(unused)] 3#[allow(unused)]
2#[cfg(stm32h7)] 4#[cfg(stm32h7)]
3use pac::adc::vals::{Adcaldif, Difsel, Exten}; 5use pac::adc::vals::{Adcaldif, Difsel, Exten};
@@ -179,6 +181,9 @@ impl<T: Instance> super::SealedAnyInstance for T {
179 w.set_l(sequence.len() as u8 - 1); 181 w.set_l(sequence.len() as u8 - 1);
180 }); 182 });
181 183
184 #[cfg(stm32g4)]
185 let mut difsel = DifselReg::default();
186
182 // Configure channels and ranks 187 // Configure channels and ranks
183 for (_i, ((ch, is_differential), sample_time)) in sequence.enumerate() { 188 for (_i, ((ch, is_differential), sample_time)) in sequence.enumerate() {
184 let sample_time = sample_time.into(); 189 let sample_time = sample_time.into();
@@ -214,10 +219,8 @@ impl<T: Instance> super::SealedAnyInstance for T {
214 219
215 #[cfg(stm32g4)] 220 #[cfg(stm32g4)]
216 { 221 {
217 T::regs().cr().modify(|w| w.set_aden(false)); // disable adc 222 if ch < 18 {
218 223 difsel.set_difsel(
219 T::regs().difsel().modify(|w| {
220 w.set_difsel(
221 ch.into(), 224 ch.into(),
222 if is_differential { 225 if is_differential {
223 Difsel::DIFFERENTIAL 226 Difsel::DIFFERENTIAL
@@ -225,11 +228,16 @@ impl<T: Instance> super::SealedAnyInstance for T {
225 Difsel::SINGLE_ENDED 228 Difsel::SINGLE_ENDED
226 }, 229 },
227 ); 230 );
228 }); 231 }
229
230 T::regs().cr().modify(|w| w.set_aden(true)); // enable adc
231 } 232 }
232 } 233 }
234
235 #[cfg(stm32g4)]
236 {
237 T::regs().cr().modify(|w| w.set_aden(false));
238 T::regs().difsel().write_value(difsel);
239 T::enable();
240 }
233 } 241 }
234} 242}
235 243
@@ -412,7 +420,6 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
412 NR_INJECTED_RANKS 420 NR_INJECTED_RANKS
413 ); 421 );
414 422
415 T::stop();
416 T::enable(); 423 T::enable();
417 424
418 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1)); 425 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1));
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 288bd77ce..81eb1e3ee 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -65,7 +65,7 @@ impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T {
65} 65}
66#[cfg(any(adc_h5, adc_h7rs))] 66#[cfg(any(adc_h5, adc_h7rs))]
67impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T { 67impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T {
68 const CHANNEL: u8 = 2; 68 const CHANNEL: u8 = 16;
69} 69}
70#[cfg(adc_u0)] 70#[cfg(adc_u0)]
71impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T { 71impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T {
@@ -82,7 +82,7 @@ cfg_if! {
82 impl<T: Instance> super::AdcChannel<T> for VddCore {} 82 impl<T: Instance> super::AdcChannel<T> for VddCore {}
83 impl<T: Instance> super::SealedAdcChannel<T> for VddCore { 83 impl<T: Instance> super::SealedAdcChannel<T> for VddCore {
84 fn channel(&self) -> u8 { 84 fn channel(&self) -> u8 {
85 6 85 17
86 } 86 }
87 } 87 }
88 } 88 }
@@ -575,6 +575,24 @@ impl<'d, T: Instance> Adc<'d, T> {
575 Vbat {} 575 Vbat {}
576 } 576 }
577 577
578 pub fn disable_vbat(&self) {
579 cfg_if! {
580 if #[cfg(any(adc_g0, adc_u0))] {
581 T::regs().ccr().modify(|reg| {
582 reg.set_vbaten(false);
583 });
584 } else if #[cfg(any(adc_h5, adc_h7rs))] {
585 T::common_regs().ccr().modify(|reg| {
586 reg.set_vbaten(false);
587 });
588 } else {
589 T::common_regs().ccr().modify(|reg| {
590 reg.set_ch18sel(false);
591 });
592 }
593 }
594 }
595
578 /* 596 /*
579 /// Convert a raw sample from the `Temperature` to deg C 597 /// Convert a raw sample from the `Temperature` to deg C
580 pub fn to_degrees_centigrade(sample: u16) -> f32 { 598 pub fn to_degrees_centigrade(sample: u16) -> f32 {
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 726d1729a..ce4bc43c3 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -391,7 +391,7 @@ pub struct Config {
391 pub frame_sync_polarity: FrameSyncPolarity, 391 pub frame_sync_polarity: FrameSyncPolarity,
392 pub frame_sync_active_level_length: word::U7, 392 pub frame_sync_active_level_length: word::U7,
393 pub frame_sync_definition: FrameSyncDefinition, 393 pub frame_sync_definition: FrameSyncDefinition,
394 pub frame_length: u8, 394 pub frame_length: u16,
395 pub clock_strobe: ClockStrobe, 395 pub clock_strobe: ClockStrobe,
396 pub output_drive: OutputDrive, 396 pub output_drive: OutputDrive,
397 pub master_clock_divider: Option<MasterClockDivider>, 397 pub master_clock_divider: Option<MasterClockDivider>,
@@ -696,7 +696,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
696 w.set_fspol(config.frame_sync_polarity.fspol()); 696 w.set_fspol(config.frame_sync_polarity.fspol());
697 w.set_fsdef(config.frame_sync_definition.fsdef()); 697 w.set_fsdef(config.frame_sync_definition.fsdef());
698 w.set_fsall(config.frame_sync_active_level_length.0 as u8 - 1); 698 w.set_fsall(config.frame_sync_active_level_length.0 as u8 - 1);
699 w.set_frl(config.frame_length - 1); 699 w.set_frl((config.frame_length - 1).try_into().unwrap());
700 }); 700 });
701 701
702 ch.slotr().modify(|w| { 702 ch.slotr().modify(|w| {
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index 36303aeb4..c338b0fd4 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -309,7 +309,9 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
309 /// Generate a sequence of PWM waveform 309 /// Generate a sequence of PWM waveform
310 /// 310 ///
311 /// Note: 311 /// Note:
312 /// you will need to provide corresponding TIMx_UP DMA channel to use this method. 312 /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method.
313 /// Also be aware that embassy timers use one of timers internally. It is possible to
314 /// switch this timer by using `time-driver-timX` feature.
313 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) { 315 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) {
314 #[allow(clippy::let_unit_value)] // eg. stm32f334 316 #[allow(clippy::let_unit_value)] // eg. stm32f334
315 let req = dma.request(); 317 let req = dma.request();
@@ -397,18 +399,23 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
397 /// 399 ///
398 /// For example, if using channels 1 through 4, a buffer of 4 update steps might look like: 400 /// For example, if using channels 1 through 4, a buffer of 4 update steps might look like:
399 /// 401 ///
402 /// ```rust,ignore
400 /// let dma_buf: [u16; 16] = [ 403 /// let dma_buf: [u16; 16] = [
401 /// ch1_duty_1, ch2_duty_1, ch3_duty_1, ch4_duty_1, // update 1 404 /// ch1_duty_1, ch2_duty_1, ch3_duty_1, ch4_duty_1, // update 1
402 /// ch1_duty_2, ch2_duty_2, ch3_duty_2, ch4_duty_2, // update 2 405 /// ch1_duty_2, ch2_duty_2, ch3_duty_2, ch4_duty_2, // update 2
403 /// ch1_duty_3, ch2_duty_3, ch3_duty_3, ch4_duty_3, // update 3 406 /// ch1_duty_3, ch2_duty_3, ch3_duty_3, ch4_duty_3, // update 3
404 /// ch1_duty_4, ch2_duty_4, ch3_duty_4, ch4_duty_4, // update 4 407 /// ch1_duty_4, ch2_duty_4, ch3_duty_4, ch4_duty_4, // update 4
405 /// ]; 408 /// ];
409 /// ```
406 /// 410 ///
407 /// Each group of N values (where N = number of channels) is transferred on one update event, 411 /// Each group of `N` values (where `N` is number of channels) is transferred on one update event,
408 /// updating the duty cycles of all selected channels simultaneously. 412 /// updating the duty cycles of all selected channels simultaneously.
409 /// 413 ///
410 /// Note: 414 /// Note:
411 /// you will need to provide corresponding TIMx_UP DMA channel to use this method. 415 /// You will need to provide corresponding `TIMx_UP` DMA channel to use this method.
416 /// Also be aware that embassy timers use one of timers internally. It is possible to
417 /// switch this timer by using `time-driver-timX` feature.
418 ///
412 pub async fn waveform_up_multi_channel( 419 pub async fn waveform_up_multi_channel(
413 &mut self, 420 &mut self,
414 dma: Peri<'_, impl super::UpDma<T>>, 421 dma: Peri<'_, impl super::UpDma<T>>,
diff --git a/examples/stm32h723/src/bin/spdifrx.rs b/examples/stm32h723/src/bin/spdifrx.rs
index cdbd69b89..5c29602c6 100644
--- a/examples/stm32h723/src/bin/spdifrx.rs
+++ b/examples/stm32h723/src/bin/spdifrx.rs
@@ -167,7 +167,7 @@ fn new_sai_transmitter<'d>(
167 sai_config.slot_count = hal::sai::word::U4(CHANNEL_COUNT as u8); 167 sai_config.slot_count = hal::sai::word::U4(CHANNEL_COUNT as u8);
168 sai_config.slot_enable = 0xFFFF; // All slots 168 sai_config.slot_enable = 0xFFFF; // All slots
169 sai_config.data_size = sai::DataSize::Data32; 169 sai_config.data_size = sai::DataSize::Data32;
170 sai_config.frame_length = (CHANNEL_COUNT * 32) as u8; 170 sai_config.frame_length = (CHANNEL_COUNT * 32) as u16;
171 sai_config.master_clock_divider = None; 171 sai_config.master_clock_divider = None;
172 172
173 let (sub_block_tx, _) = hal::sai::split_subblocks(sai); 173 let (sub_block_tx, _) = hal::sai::split_subblocks(sai);