aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-11-19 22:02:57 +0100
committerDario Nieuwenhuis <[email protected]>2023-11-19 22:06:05 +0100
commit5221705495a46edeb6fc45a88dceff8200d339aa (patch)
tree10f2ae71b8881a751cfe778adbecce7b3a7d29b8 /embassy-stm32
parent5bc75578260f4c644cc060e6458a05d7fc0ffb41 (diff)
stm32/sai: fix build on chips with only SAI4 (like stm32h725re), improve sync config.
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/build.rs1
-rw-r--r--embassy-stm32/src/sai/mod.rs70
2 files changed, 39 insertions, 32 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 6b41cd397..a7dac5f9d 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -61,6 +61,7 @@ fn main() {
61 let mut singletons: Vec<String> = Vec::new(); 61 let mut singletons: Vec<String> = Vec::new();
62 for p in METADATA.peripherals { 62 for p in METADATA.peripherals {
63 if let Some(r) = &p.registers { 63 if let Some(r) = &p.registers {
64 println!("cargo:rustc-cfg=peri_{}", p.name.to_ascii_lowercase());
64 match r.kind { 65 match r.kind {
65 // Generate singletons per pin, not per port 66 // Generate singletons per pin, not per port
66 "gpio" => { 67 "gpio" => {
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index a0b4ddac7..a16d38af1 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -207,27 +207,40 @@ impl Protocol {
207} 207}
208 208
209#[derive(Copy, Clone, PartialEq)] 209#[derive(Copy, Clone, PartialEq)]
210pub enum SyncEnable { 210pub enum SyncInput {
211 Asynchronous, 211 /// Not synced to any other SAI unit.
212 None,
212 /// Syncs with the other A/B sub-block within the SAI unit 213 /// Syncs with the other A/B sub-block within the SAI unit
213 Internal, 214 Internal,
214 /// Syncs with a sub-block in the other SAI unit - use set_sync_output() and set_sync_input() 215 /// Syncs with a sub-block in the other SAI unit
215 #[cfg(any(sai_v4))] 216 #[cfg(sai_v4)]
216 External, 217 External(SyncInputInstance),
217} 218}
218 219
219impl SyncEnable { 220impl SyncInput {
220 #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
221 pub const fn syncen(&self) -> vals::Syncen { 221 pub const fn syncen(&self) -> vals::Syncen {
222 match self { 222 match self {
223 SyncEnable::Asynchronous => vals::Syncen::ASYNCHRONOUS, 223 SyncInput::None => vals::Syncen::ASYNCHRONOUS,
224 SyncEnable::Internal => vals::Syncen::INTERNAL, 224 SyncInput::Internal => vals::Syncen::INTERNAL,
225 #[cfg(any(sai_v4))] 225 #[cfg(any(sai_v4))]
226 SyncEnable::External => vals::Syncen::EXTERNAL, 226 SyncInput::External(_) => vals::Syncen::EXTERNAL,
227 } 227 }
228 } 228 }
229} 229}
230 230
231#[cfg(sai_v4)]
232#[derive(Copy, Clone, PartialEq)]
233pub enum SyncInputInstance {
234 #[cfg(peri_sai1)]
235 Sai1 = 0,
236 #[cfg(peri_sai2)]
237 Sai2 = 1,
238 #[cfg(peri_sai3)]
239 Sai3 = 2,
240 #[cfg(peri_sai4)]
241 Sai4 = 3,
242}
243
231#[derive(Copy, Clone, PartialEq)] 244#[derive(Copy, Clone, PartialEq)]
232pub enum StereoMono { 245pub enum StereoMono {
233 Stereo, 246 Stereo,
@@ -428,8 +441,8 @@ impl MasterClockDivider {
428pub struct Config { 441pub struct Config {
429 pub mode: Mode, 442 pub mode: Mode,
430 pub tx_rx: TxRx, 443 pub tx_rx: TxRx,
431 pub sync_enable: SyncEnable, 444 pub sync_input: SyncInput,
432 pub is_sync_output: bool, 445 pub sync_output: bool,
433 pub protocol: Protocol, 446 pub protocol: Protocol,
434 pub slot_size: SlotSize, 447 pub slot_size: SlotSize,
435 pub slot_count: word::U4, 448 pub slot_count: word::U4,
@@ -459,8 +472,8 @@ impl Default for Config {
459 Self { 472 Self {
460 mode: Mode::Master, 473 mode: Mode::Master,
461 tx_rx: TxRx::Transmitter, 474 tx_rx: TxRx::Transmitter,
462 is_sync_output: false, 475 sync_output: false,
463 sync_enable: SyncEnable::Asynchronous, 476 sync_input: SyncInput::None,
464 protocol: Protocol::Free, 477 protocol: Protocol::Free,
465 slot_size: SlotSize::DataSize, 478 slot_size: SlotSize::DataSize,
466 slot_count: word::U4(2), 479 slot_count: word::U4(2),
@@ -608,18 +621,18 @@ impl<'d, T: Instance> Sai<'d, T> {
608 621
609fn update_synchronous_config(config: &mut Config) { 622fn update_synchronous_config(config: &mut Config) {
610 config.mode = Mode::Slave; 623 config.mode = Mode::Slave;
611 config.is_sync_output = false; 624 config.sync_output = false;
612 625
613 #[cfg(any(sai_v1, sai_v2, sai_v3))] 626 #[cfg(any(sai_v1, sai_v2, sai_v3))]
614 { 627 {
615 config.sync_enable = SyncEnable::Internal; 628 config.sync_input = SyncInput::Internal;
616 } 629 }
617 630
618 #[cfg(any(sai_v4))] 631 #[cfg(any(sai_v4))]
619 { 632 {
620 //this must either be Internal or External 633 //this must either be Internal or External
621 //The asynchronous sub-block on the same SAI needs to enable is_sync_output 634 //The asynchronous sub-block on the same SAI needs to enable sync_output
622 assert!(config.sync_enable != SyncEnable::Asynchronous); 635 assert!(config.sync_input != SyncInput::None);
623 } 636 }
624} 637}
625 638
@@ -866,20 +879,13 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
866 879
867 #[cfg(any(sai_v4))] 880 #[cfg(any(sai_v4))]
868 { 881 {
869 // Not totally clear from the datasheet if this is right 882 if let SyncInput::External(i) = config.sync_input {
870 // This is only used if using SyncEnable::External on the other SAI unit 883 T::REGS.gcr().modify(|w| {
871 // Syncing from SAIX subblock A to subblock B does not require this 884 w.set_syncin(i as u8);
872 // Only syncing from SAI1 subblock A/B to SAI2 subblock A/B 885 });
873 let value: u8 = if T::REGS.as_ptr() == stm32_metapac::SAI1.as_ptr() { 886 }
874 1 //this is SAI1, so sync with SAI2
875 } else {
876 0 //this is SAI2, so sync with SAI1
877 };
878 T::REGS.gcr().modify(|w| {
879 w.set_syncin(value);
880 });
881 887
882 if config.is_sync_output { 888 if config.sync_output {
883 let syncout: u8 = match sub_block { 889 let syncout: u8 = match sub_block {
884 WhichSubBlock::A => 0b01, 890 WhichSubBlock::A => 0b01,
885 WhichSubBlock::B => 0b10, 891 WhichSubBlock::B => 0b10,
@@ -903,7 +909,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
903 w.set_ds(config.data_size.ds()); 909 w.set_ds(config.data_size.ds());
904 w.set_lsbfirst(config.bit_order.lsbfirst()); 910 w.set_lsbfirst(config.bit_order.lsbfirst());
905 w.set_ckstr(config.clock_strobe.ckstr()); 911 w.set_ckstr(config.clock_strobe.ckstr());
906 w.set_syncen(config.sync_enable.syncen()); 912 w.set_syncen(config.sync_input.syncen());
907 w.set_mono(config.stereo_mono.mono()); 913 w.set_mono(config.stereo_mono.mono());
908 w.set_outdriv(config.output_drive.outdriv()); 914 w.set_outdriv(config.output_drive.outdriv());
909 w.set_mckdiv(config.master_clock_divider.mckdiv()); 915 w.set_mckdiv(config.master_clock_divider.mckdiv());