diff options
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/build.rs | 11 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f4.rs | 54 |
4 files changed, 63 insertions, 8 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 150014afe..612a54f25 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -58,7 +58,7 @@ sdio-host = "0.5.0" | |||
| 58 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 58 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 59 | critical-section = "1.1" | 59 | critical-section = "1.1" |
| 60 | atomic-polyfill = "1.0.1" | 60 | atomic-polyfill = "1.0.1" |
| 61 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7" } | 61 | stm32-metapac = "12" |
| 62 | vcell = "0.1.3" | 62 | vcell = "0.1.3" |
| 63 | bxcan = "0.7.0" | 63 | bxcan = "0.7.0" |
| 64 | nb = "1.0.0" | 64 | nb = "1.0.0" |
| @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 77 | [build-dependencies] | 77 | [build-dependencies] |
| 78 | proc-macro2 = "1.0.36" | 78 | proc-macro2 = "1.0.36" |
| 79 | quote = "1.0.15" | 79 | quote = "1.0.15" |
| 80 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7", default-features = false, features = ["metadata"]} | 80 | stm32-metapac = { path = "../../stm32-data-generated/stm32-metapac", default-features = false, features = ["metadata"]} |
| 81 | 81 | ||
| 82 | [features] | 82 | [features] |
| 83 | default = ["rt"] | 83 | default = ["rt"] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 6c364f7bb..1b86dad7a 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -425,6 +425,15 @@ fn main() { | |||
| 425 | (("lpuart", "RTS"), quote!(crate::usart::RtsPin)), | 425 | (("lpuart", "RTS"), quote!(crate::usart::RtsPin)), |
| 426 | (("lpuart", "CK"), quote!(crate::usart::CkPin)), | 426 | (("lpuart", "CK"), quote!(crate::usart::CkPin)), |
| 427 | (("lpuart", "DE"), quote!(crate::usart::DePin)), | 427 | (("lpuart", "DE"), quote!(crate::usart::DePin)), |
| 428 | (("sai", "SCK_A"), quote!(crate::sai::SckAPin)), | ||
| 429 | (("sai", "SCK_B"), quote!(crate::sai::SckBPin)), | ||
| 430 | (("sai", "FS_A"), quote!(crate::sai::FsAPin)), | ||
| 431 | (("sai", "FS_B"), quote!(crate::sai::FsBPin)), | ||
| 432 | (("sai", "SD_A"), quote!(crate::sai::SdAPin)), | ||
| 433 | (("sai", "SD_B"), quote!(crate::sai::SdBPin)), | ||
| 434 | (("sai", "MCLK_A"), quote!(crate::sai::MclkAPin)), | ||
| 435 | (("sai", "MCLK_B"), quote!(crate::sai::MclkBPin)), | ||
| 436 | (("sai", "WS"), quote!(crate::sai::WsPin)), | ||
| 428 | (("spi", "SCK"), quote!(crate::spi::SckPin)), | 437 | (("spi", "SCK"), quote!(crate::spi::SckPin)), |
| 429 | (("spi", "MOSI"), quote!(crate::spi::MosiPin)), | 438 | (("spi", "MOSI"), quote!(crate::spi::MosiPin)), |
| 430 | (("spi", "MISO"), quote!(crate::spi::MisoPin)), | 439 | (("spi", "MISO"), quote!(crate::spi::MisoPin)), |
| @@ -708,6 +717,8 @@ fn main() { | |||
| 708 | (("usart", "TX"), quote!(crate::usart::TxDma)), | 717 | (("usart", "TX"), quote!(crate::usart::TxDma)), |
| 709 | (("lpuart", "RX"), quote!(crate::usart::RxDma)), | 718 | (("lpuart", "RX"), quote!(crate::usart::RxDma)), |
| 710 | (("lpuart", "TX"), quote!(crate::usart::TxDma)), | 719 | (("lpuart", "TX"), quote!(crate::usart::TxDma)), |
| 720 | (("sai", "A"), quote!(crate::sai::DmaA)), | ||
| 721 | (("sai", "B"), quote!(crate::sai::DmaB)), | ||
| 711 | (("spi", "RX"), quote!(crate::spi::RxDma)), | 722 | (("spi", "RX"), quote!(crate::spi::RxDma)), |
| 712 | (("spi", "TX"), quote!(crate::spi::TxDma)), | 723 | (("spi", "TX"), quote!(crate::spi::TxDma)), |
| 713 | (("i2c", "RX"), quote!(crate::i2c::RxDma)), | 724 | (("i2c", "RX"), quote!(crate::i2c::RxDma)), |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 8c87ea7d5..b5a128596 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -55,6 +55,8 @@ pub mod qspi; | |||
| 55 | pub mod rng; | 55 | pub mod rng; |
| 56 | #[cfg(all(rtc, not(rtc_v1)))] | 56 | #[cfg(all(rtc, not(rtc_v1)))] |
| 57 | pub mod rtc; | 57 | pub mod rtc; |
| 58 | #[cfg(sai)] | ||
| 59 | pub mod sai; | ||
| 58 | #[cfg(sdmmc)] | 60 | #[cfg(sdmmc)] |
| 59 | pub mod sdmmc; | 61 | pub mod sdmmc; |
| 60 | #[cfg(spi)] | 62 | #[cfg(spi)] |
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index ee9cb2897..72bdbd5db 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs | |||
| @@ -33,6 +33,9 @@ pub struct Config { | |||
| 33 | #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] | 33 | #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] |
| 34 | pub plli2s: Option<Hertz>, | 34 | pub plli2s: Option<Hertz>, |
| 35 | 35 | ||
| 36 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] | ||
| 37 | pub pllsai: Option<Hertz>, | ||
| 38 | |||
| 36 | pub pll48: bool, | 39 | pub pll48: bool, |
| 37 | pub rtc: Option<RtcClockSource>, | 40 | pub rtc: Option<RtcClockSource>, |
| 38 | } | 41 | } |
| @@ -48,11 +51,9 @@ fn setup_i2s_pll(_vco_in: u32, _plli2s: Option<u32>) -> Option<u32> { | |||
| 48 | None | 51 | None |
| 49 | } | 52 | } |
| 50 | 53 | ||
| 51 | #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] | 54 | fn calculate_sai_i2s_pll_values(vco_in: u32, max_div: u32, target: Option<u32>, ) -> Option<(u32, u32, u32)> { |
| 52 | fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> { | ||
| 53 | let min_div = 2; | 55 | let min_div = 2; |
| 54 | let max_div = 7; | 56 | let target = match target { |
| 55 | let target = match plli2s { | ||
| 56 | Some(target) => target, | 57 | Some(target) => target, |
| 57 | None => return None, | 58 | None => return None, |
| 58 | }; | 59 | }; |
| @@ -76,15 +77,41 @@ fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> { | |||
| 76 | }) | 77 | }) |
| 77 | .min_by_key(|(_, _, _, error)| *error)?; | 78 | .min_by_key(|(_, _, _, error)| *error)?; |
| 78 | 79 | ||
| 80 | Some((n, outdiv, output)) | ||
| 81 | } | ||
| 82 | |||
| 83 | #[cfg(not(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446)))] | ||
| 84 | fn setup_i2s_pll(vco_in: u32, plli2s: Option<u32>) -> Option<u32> { | ||
| 85 | let (n, outdiv, output) = calculate_sai_i2s_pll_values(vco_in, 7, plli2s)?; | ||
| 86 | |||
| 79 | RCC.plli2scfgr().modify(|w| { | 87 | RCC.plli2scfgr().modify(|w| { |
| 80 | w.set_plli2sn(n as u16); | 88 | w.set_plli2sn(n as u16); |
| 81 | w.set_plli2sr(outdiv as u8); | 89 | w.set_plli2sr(outdiv as u8); |
| 90 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] | ||
| 91 | w.set_plli2sq(outdiv as u8); //set sai divider same as i2s | ||
| 82 | }); | 92 | }); |
| 83 | 93 | ||
| 84 | Some(output) | 94 | Some(output) |
| 85 | } | 95 | } |
| 86 | 96 | ||
| 87 | fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, plli2s: Option<u32>, pll48clk: bool) -> PllResults { | 97 | #[cfg(not(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479)))] |
| 98 | fn setup_sai_pll(vco_in: u32, pllsai: Option<u32>) -> Option<u32> { | ||
| 99 | None | ||
| 100 | } | ||
| 101 | |||
| 102 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] | ||
| 103 | fn setup_sai_pll(vco_in: u32, pllsai: Option<u32>) -> Option<u32> { | ||
| 104 | let (n, outdiv, output) = calculate_sai_i2s_pll_values(vco_in, 15, pllsai)?; | ||
| 105 | |||
| 106 | RCC.pllsaicfgr().modify(|w| { | ||
| 107 | w.set_pllsain(n as u16); | ||
| 108 | w.set_pllsaiq(outdiv as u8); | ||
| 109 | }); | ||
| 110 | |||
| 111 | Some(output) | ||
| 112 | } | ||
| 113 | |||
| 114 | fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, plli2s: Option<u32>, pllsai: Option<u32>, pll48clk: bool) -> PllResults { | ||
| 88 | use crate::pac::rcc::vals::{Pllp, Pllsrc}; | 115 | use crate::pac::rcc::vals::{Pllp, Pllsrc}; |
| 89 | 116 | ||
| 90 | let sysclk = pllsysclk.unwrap_or(pllsrcclk); | 117 | let sysclk = pllsysclk.unwrap_or(pllsrcclk); |
| @@ -96,6 +123,7 @@ fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, plli2s: Opti | |||
| 96 | pllsysclk: None, | 123 | pllsysclk: None, |
| 97 | pll48clk: None, | 124 | pll48clk: None, |
| 98 | plli2sclk: None, | 125 | plli2sclk: None, |
| 126 | pllsaiclk: None, | ||
| 99 | }; | 127 | }; |
| 100 | } | 128 | } |
| 101 | // Input divisor from PLL source clock, must result to frequency in | 129 | // Input divisor from PLL source clock, must result to frequency in |
| @@ -146,6 +174,7 @@ fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, plli2s: Opti | |||
| 146 | w.set_pllp(Pllp::from_bits(pllp as u8)); | 174 | w.set_pllp(Pllp::from_bits(pllp as u8)); |
| 147 | w.set_pllq(pllq as u8); | 175 | w.set_pllq(pllq as u8); |
| 148 | w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); | 176 | w.set_pllsrc(Pllsrc::from_bits(use_hse as u8)); |
| 177 | w.set_pllr(0); | ||
| 149 | }); | 178 | }); |
| 150 | 179 | ||
| 151 | let real_pllsysclk = vco_in * plln / sysclk_div; | 180 | let real_pllsysclk = vco_in * plln / sysclk_div; |
| @@ -155,6 +184,7 @@ fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, plli2s: Opti | |||
| 155 | pllsysclk: Some(real_pllsysclk), | 184 | pllsysclk: Some(real_pllsysclk), |
| 156 | pll48clk: if pll48clk { Some(real_pll48clk) } else { None }, | 185 | pll48clk: if pll48clk { Some(real_pll48clk) } else { None }, |
| 157 | plli2sclk: setup_i2s_pll(vco_in, plli2s), | 186 | plli2sclk: setup_i2s_pll(vco_in, plli2s), |
| 187 | pllsaiclk: setup_sai_pll(vco_in, pllsai), | ||
| 158 | } | 188 | } |
| 159 | } | 189 | } |
| 160 | 190 | ||
| @@ -344,6 +374,10 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 344 | config.plli2s.map(|i2s| i2s.0), | 374 | config.plli2s.map(|i2s| i2s.0), |
| 345 | #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))] | 375 | #[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423, stm32f446))] |
| 346 | None, | 376 | None, |
| 377 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] | ||
| 378 | config.pllsai.map(|sai| sai.0), | ||
| 379 | #[cfg(not(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479)))] | ||
| 380 | None, | ||
| 347 | config.pll48, | 381 | config.pll48, |
| 348 | ); | 382 | ); |
| 349 | 383 | ||
| @@ -441,6 +475,12 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 441 | while !RCC.cr().read().plli2srdy() {} | 475 | while !RCC.cr().read().plli2srdy() {} |
| 442 | } | 476 | } |
| 443 | 477 | ||
| 478 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] | ||
| 479 | if plls.pllsaiclk.is_some() { | ||
| 480 | RCC.cr().modify(|w| w.set_pllsaion(true)); | ||
| 481 | while !RCC.cr().read().pllsairdy() {} | ||
| 482 | } | ||
| 483 | |||
| 444 | RCC.cfgr().modify(|w| { | 484 | RCC.cfgr().modify(|w| { |
| 445 | w.set_ppre2(Ppre::from_bits(ppre2_bits)); | 485 | w.set_ppre2(Ppre::from_bits(ppre2_bits)); |
| 446 | w.set_ppre1(Ppre::from_bits(ppre1_bits)); | 486 | w.set_ppre1(Ppre::from_bits(ppre1_bits)); |
| @@ -496,7 +536,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 496 | plli2s: plls.plli2sclk.map(Hertz), | 536 | plli2s: plls.plli2sclk.map(Hertz), |
| 497 | 537 | ||
| 498 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] | 538 | #[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] |
| 499 | pllsai: None, | 539 | pllsai: plls.pllsaiclk.map(Hertz), |
| 500 | 540 | ||
| 501 | rtc: rtc, | 541 | rtc: rtc, |
| 502 | }); | 542 | }); |
| @@ -508,6 +548,8 @@ struct PllResults { | |||
| 508 | pll48clk: Option<u32>, | 548 | pll48clk: Option<u32>, |
| 509 | #[allow(dead_code)] | 549 | #[allow(dead_code)] |
| 510 | plli2sclk: Option<u32>, | 550 | plli2sclk: Option<u32>, |
| 551 | #[allow(dead_code)] | ||
| 552 | pllsaiclk: Option<u32>, | ||
| 511 | } | 553 | } |
| 512 | 554 | ||
| 513 | mod max { | 555 | mod max { |
