diff options
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/g4.rs | 23 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v3.rs | 22 | ||||
| -rw-r--r-- | embassy-stm32/src/sai/mod.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 13 | ||||
| -rw-r--r-- | examples/stm32h723/src/bin/spdifrx.rs | 2 |
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)] | ||
| 2 | use pac::adc::regs::Difsel as DifselReg; | ||
| 1 | #[allow(unused)] | 3 | #[allow(unused)] |
| 2 | #[cfg(stm32h7)] | 4 | #[cfg(stm32h7)] |
| 3 | use pac::adc::vals::{Adcaldif, Difsel, Exten}; | 5 | use 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))] |
| 67 | impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T { | 67 | impl<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)] |
| 71 | impl<T: Instance> super::SealedSpecialConverter<super::Vbat> for T { | 71 | impl<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); |
