diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-04-13 02:13:41 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-04-14 22:29:07 +0200 |
| commit | 65c085ce910f50903bc5c41ca82eda989810f855 (patch) | |
| tree | 2dde97f356234411a1c5d780eba9e55a7f90f8ff | |
| parent | 87b79d449916b26d0d29b6247ae366a80c02cfa5 (diff) | |
Add stm32u0 support.
| -rwxr-xr-x | ci.sh | 3 | ||||
| -rw-r--r-- | embassy-stm32/Cargo.toml | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/exti.rs | 16 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l.rs | 28 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mco.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 2 | ||||
| -rw-r--r-- | examples/stm32u0/.cargo/config.toml | 9 | ||||
| -rw-r--r-- | examples/stm32u0/Cargo.toml | 25 | ||||
| -rw-r--r-- | examples/stm32u0/build.rs | 5 | ||||
| -rw-r--r-- | examples/stm32u0/src/bin/blinky.rs | 26 | ||||
| -rw-r--r-- | examples/stm32u0/src/bin/button.rs | 24 | ||||
| -rw-r--r-- | examples/stm32u0/src/bin/button_exti.rs | 25 |
12 files changed, 187 insertions, 16 deletions
| @@ -149,6 +149,9 @@ cargo batch \ | |||
| 149 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h503rb,defmt,exti,time-driver-any,time \ | 149 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h503rb,defmt,exti,time-driver-any,time \ |
| 150 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h562ag,defmt,exti,time-driver-any,time \ | 150 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32h562ag,defmt,exti,time-driver-any,time \ |
| 151 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb35ce,defmt,exti,time-driver-any,time \ | 151 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb35ce,defmt,exti,time-driver-any,time \ |
| 152 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u031r8,defmt,exti,time-driver-any,time \ | ||
| 153 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ | ||
| 154 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ | ||
| 152 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ | 155 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ |
| 153 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ | 156 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ |
| 154 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ | 157 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 93792ecf8..459d2e370 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -30,6 +30,7 @@ flavors = [ | |||
| 30 | { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, | 30 | { regex_feature = "stm32l1.*", target = "thumbv7m-none-eabi" }, |
| 31 | { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, | 31 | { regex_feature = "stm32l4.*", target = "thumbv7em-none-eabi" }, |
| 32 | { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, | 32 | { regex_feature = "stm32l5.*", target = "thumbv8m.main-none-eabihf", features = ["low-power"] }, |
| 33 | { regex_feature = "stm32u0.*", target = "thumbv6m-none-eabi" }, | ||
| 33 | { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, | 34 | { regex_feature = "stm32u5.*", target = "thumbv8m.main-none-eabihf" }, |
| 34 | { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" }, | 35 | { regex_feature = "stm32wb.*", target = "thumbv7em-none-eabi" }, |
| 35 | { regex_feature = "stm32wba.*", target = "thumbv8m.main-none-eabihf" }, | 36 | { regex_feature = "stm32wba.*", target = "thumbv8m.main-none-eabihf" }, |
| @@ -70,7 +71,7 @@ rand_core = "0.6.3" | |||
| 70 | sdio-host = "0.5.0" | 71 | sdio-host = "0.5.0" |
| 71 | critical-section = "1.1" | 72 | critical-section = "1.1" |
| 72 | #stm32-metapac = { version = "15" } | 73 | #stm32-metapac = { version = "15" } |
| 73 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-0c4baf478324e19741c7a9795ab0aa8217c3691c" } | 74 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d674277b78ca7400ecfeeb1b5af4e460a65c1a61" } |
| 74 | 75 | ||
| 75 | vcell = "0.1.3" | 76 | vcell = "0.1.3" |
| 76 | nb = "1.0.0" | 77 | nb = "1.0.0" |
| @@ -96,7 +97,7 @@ proc-macro2 = "1.0.36" | |||
| 96 | quote = "1.0.15" | 97 | quote = "1.0.15" |
| 97 | 98 | ||
| 98 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} | 99 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} |
| 99 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-0c4baf478324e19741c7a9795ab0aa8217c3691c", default-features = false, features = ["metadata"]} | 100 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d674277b78ca7400ecfeeb1b5af4e460a65c1a61", default-features = false, features = ["metadata"]} |
| 100 | 101 | ||
| 101 | [features] | 102 | [features] |
| 102 | default = ["rt"] | 103 | default = ["rt"] |
| @@ -1419,6 +1420,38 @@ stm32l562qe = [ "stm32-metapac/stm32l562qe" ] | |||
| 1419 | stm32l562re = [ "stm32-metapac/stm32l562re" ] | 1420 | stm32l562re = [ "stm32-metapac/stm32l562re" ] |
| 1420 | stm32l562ve = [ "stm32-metapac/stm32l562ve" ] | 1421 | stm32l562ve = [ "stm32-metapac/stm32l562ve" ] |
| 1421 | stm32l562ze = [ "stm32-metapac/stm32l562ze" ] | 1422 | stm32l562ze = [ "stm32-metapac/stm32l562ze" ] |
| 1423 | stm32u031c6 = [ "stm32-metapac/stm32u031c6" ] | ||
| 1424 | stm32u031c8 = [ "stm32-metapac/stm32u031c8" ] | ||
| 1425 | stm32u031f4 = [ "stm32-metapac/stm32u031f4" ] | ||
| 1426 | stm32u031f6 = [ "stm32-metapac/stm32u031f6" ] | ||
| 1427 | stm32u031f8 = [ "stm32-metapac/stm32u031f8" ] | ||
| 1428 | stm32u031g6 = [ "stm32-metapac/stm32u031g6" ] | ||
| 1429 | stm32u031g8 = [ "stm32-metapac/stm32u031g8" ] | ||
| 1430 | stm32u031k4 = [ "stm32-metapac/stm32u031k4" ] | ||
| 1431 | stm32u031k6 = [ "stm32-metapac/stm32u031k6" ] | ||
| 1432 | stm32u031k8 = [ "stm32-metapac/stm32u031k8" ] | ||
| 1433 | stm32u031r6 = [ "stm32-metapac/stm32u031r6" ] | ||
| 1434 | stm32u031r8 = [ "stm32-metapac/stm32u031r8" ] | ||
| 1435 | stm32u073c8 = [ "stm32-metapac/stm32u073c8" ] | ||
| 1436 | stm32u073cb = [ "stm32-metapac/stm32u073cb" ] | ||
| 1437 | stm32u073cc = [ "stm32-metapac/stm32u073cc" ] | ||
| 1438 | stm32u073h8 = [ "stm32-metapac/stm32u073h8" ] | ||
| 1439 | stm32u073hb = [ "stm32-metapac/stm32u073hb" ] | ||
| 1440 | stm32u073hc = [ "stm32-metapac/stm32u073hc" ] | ||
| 1441 | stm32u073k8 = [ "stm32-metapac/stm32u073k8" ] | ||
| 1442 | stm32u073kb = [ "stm32-metapac/stm32u073kb" ] | ||
| 1443 | stm32u073kc = [ "stm32-metapac/stm32u073kc" ] | ||
| 1444 | stm32u073m8 = [ "stm32-metapac/stm32u073m8" ] | ||
| 1445 | stm32u073mb = [ "stm32-metapac/stm32u073mb" ] | ||
| 1446 | stm32u073mc = [ "stm32-metapac/stm32u073mc" ] | ||
| 1447 | stm32u073r8 = [ "stm32-metapac/stm32u073r8" ] | ||
| 1448 | stm32u073rb = [ "stm32-metapac/stm32u073rb" ] | ||
| 1449 | stm32u073rc = [ "stm32-metapac/stm32u073rc" ] | ||
| 1450 | stm32u083cc = [ "stm32-metapac/stm32u083cc" ] | ||
| 1451 | stm32u083hc = [ "stm32-metapac/stm32u083hc" ] | ||
| 1452 | stm32u083kc = [ "stm32-metapac/stm32u083kc" ] | ||
| 1453 | stm32u083mc = [ "stm32-metapac/stm32u083mc" ] | ||
| 1454 | stm32u083rc = [ "stm32-metapac/stm32u083rc" ] | ||
| 1422 | stm32u535cb = [ "stm32-metapac/stm32u535cb" ] | 1455 | stm32u535cb = [ "stm32-metapac/stm32u535cb" ] |
| 1423 | stm32u535cc = [ "stm32-metapac/stm32u535cc" ] | 1456 | stm32u535cc = [ "stm32-metapac/stm32u535cc" ] |
| 1424 | stm32u535ce = [ "stm32-metapac/stm32u535ce" ] | 1457 | stm32u535ce = [ "stm32-metapac/stm32u535ce" ] |
| @@ -1474,6 +1507,7 @@ stm32u599vj = [ "stm32-metapac/stm32u599vj" ] | |||
| 1474 | stm32u599zi = [ "stm32-metapac/stm32u599zi" ] | 1507 | stm32u599zi = [ "stm32-metapac/stm32u599zi" ] |
| 1475 | stm32u599zj = [ "stm32-metapac/stm32u599zj" ] | 1508 | stm32u599zj = [ "stm32-metapac/stm32u599zj" ] |
| 1476 | stm32u5a5aj = [ "stm32-metapac/stm32u5a5aj" ] | 1509 | stm32u5a5aj = [ "stm32-metapac/stm32u5a5aj" ] |
| 1510 | stm32u5a5qi = [ "stm32-metapac/stm32u5a5qi" ] | ||
| 1477 | stm32u5a5qj = [ "stm32-metapac/stm32u5a5qj" ] | 1511 | stm32u5a5qj = [ "stm32-metapac/stm32u5a5qj" ] |
| 1478 | stm32u5a5rj = [ "stm32-metapac/stm32u5a5rj" ] | 1512 | stm32u5a5rj = [ "stm32-metapac/stm32u5a5rj" ] |
| 1479 | stm32u5a5vj = [ "stm32-metapac/stm32u5a5vj" ] | 1513 | stm32u5a5vj = [ "stm32-metapac/stm32u5a5vj" ] |
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 8d5dae436..224d51b84 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -27,11 +27,11 @@ fn cpu_regs() -> pac::exti::Exti { | |||
| 27 | EXTI | 27 | EXTI |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | #[cfg(not(any(exti_c0, exti_g0, exti_l5, gpio_v1, exti_u5, exti_h5, exti_h50)))] | 30 | #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, gpio_v1, exti_u5, exti_h5, exti_h50)))] |
| 31 | fn exticr_regs() -> pac::syscfg::Syscfg { | 31 | fn exticr_regs() -> pac::syscfg::Syscfg { |
| 32 | pac::SYSCFG | 32 | pac::SYSCFG |
| 33 | } | 33 | } |
| 34 | #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] | 34 | #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] |
| 35 | fn exticr_regs() -> pac::exti::Exti { | 35 | fn exticr_regs() -> pac::exti::Exti { |
| 36 | EXTI | 36 | EXTI |
| 37 | } | 37 | } |
| @@ -44,9 +44,9 @@ unsafe fn on_irq() { | |||
| 44 | #[cfg(feature = "low-power")] | 44 | #[cfg(feature = "low-power")] |
| 45 | crate::low_power::on_wakeup_irq(); | 45 | crate::low_power::on_wakeup_irq(); |
| 46 | 46 | ||
| 47 | #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] | 47 | #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50)))] |
| 48 | let bits = EXTI.pr(0).read().0; | 48 | let bits = EXTI.pr(0).read().0; |
| 49 | #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] | 49 | #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] |
| 50 | let bits = EXTI.rpr(0).read().0 | EXTI.fpr(0).read().0; | 50 | let bits = EXTI.rpr(0).read().0 | EXTI.fpr(0).read().0; |
| 51 | 51 | ||
| 52 | // We don't handle or change any EXTI lines above 16. | 52 | // We don't handle or change any EXTI lines above 16. |
| @@ -61,9 +61,9 @@ unsafe fn on_irq() { | |||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | // Clear pending | 63 | // Clear pending |
| 64 | #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] | 64 | #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50)))] |
| 65 | EXTI.pr(0).write_value(Lines(bits)); | 65 | EXTI.pr(0).write_value(Lines(bits)); |
| 66 | #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] | 66 | #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] |
| 67 | { | 67 | { |
| 68 | EXTI.rpr(0).write_value(Lines(bits)); | 68 | EXTI.rpr(0).write_value(Lines(bits)); |
| 69 | EXTI.fpr(0).write_value(Lines(bits)); | 69 | EXTI.fpr(0).write_value(Lines(bits)); |
| @@ -241,9 +241,9 @@ impl<'a> ExtiInputFuture<'a> { | |||
| 241 | EXTI.ftsr(0).modify(|w| w.set_line(pin, falling)); | 241 | EXTI.ftsr(0).modify(|w| w.set_line(pin, falling)); |
| 242 | 242 | ||
| 243 | // clear pending bit | 243 | // clear pending bit |
| 244 | #[cfg(not(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50)))] | 244 | #[cfg(not(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50)))] |
| 245 | EXTI.pr(0).write(|w| w.set_line(pin, true)); | 245 | EXTI.pr(0).write(|w| w.set_line(pin, true)); |
| 246 | #[cfg(any(exti_c0, exti_g0, exti_l5, exti_u5, exti_h5, exti_h50))] | 246 | #[cfg(any(exti_c0, exti_g0, exti_u0, exti_l5, exti_u5, exti_h5, exti_h50))] |
| 247 | { | 247 | { |
| 248 | EXTI.rpr(0).write(|w| w.set_line(pin, true)); | 248 | EXTI.rpr(0).write(|w| w.set_line(pin, true)); |
| 249 | EXTI.fpr(0).write(|w| w.set_line(pin, true)); | 249 | EXTI.fpr(0).write(|w| w.set_line(pin, true)); |
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs index 9079ddd41..d7235ac7f 100644 --- a/embassy-stm32/src/rcc/l.rs +++ b/embassy-stm32/src/rcc/l.rs | |||
| @@ -49,6 +49,7 @@ pub struct Config { | |||
| 49 | pub sys: Sysclk, | 49 | pub sys: Sysclk, |
| 50 | pub ahb_pre: AHBPrescaler, | 50 | pub ahb_pre: AHBPrescaler, |
| 51 | pub apb1_pre: APBPrescaler, | 51 | pub apb1_pre: APBPrescaler, |
| 52 | #[cfg(not(stm32u0))] | ||
| 52 | pub apb2_pre: APBPrescaler, | 53 | pub apb2_pre: APBPrescaler, |
| 53 | #[cfg(any(stm32wl5x, stm32wb))] | 54 | #[cfg(any(stm32wl5x, stm32wb))] |
| 54 | pub core2_ahb_pre: AHBPrescaler, | 55 | pub core2_ahb_pre: AHBPrescaler, |
| @@ -75,6 +76,7 @@ impl Default for Config { | |||
| 75 | sys: Sysclk::MSI, | 76 | sys: Sysclk::MSI, |
| 76 | ahb_pre: AHBPrescaler::DIV1, | 77 | ahb_pre: AHBPrescaler::DIV1, |
| 77 | apb1_pre: APBPrescaler::DIV1, | 78 | apb1_pre: APBPrescaler::DIV1, |
| 79 | #[cfg(not(stm32u0))] | ||
| 78 | apb2_pre: APBPrescaler::DIV1, | 80 | apb2_pre: APBPrescaler::DIV1, |
| 79 | #[cfg(any(stm32wl5x, stm32wb))] | 81 | #[cfg(any(stm32wl5x, stm32wb))] |
| 80 | core2_ahb_pre: AHBPrescaler::DIV1, | 82 | core2_ahb_pre: AHBPrescaler::DIV1, |
| @@ -130,7 +132,7 @@ pub const WPAN_DEFAULT: Config = Config { | |||
| 130 | }; | 132 | }; |
| 131 | 133 | ||
| 132 | fn msi_enable(range: MSIRange) { | 134 | fn msi_enable(range: MSIRange) { |
| 133 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] | 135 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] |
| 134 | RCC.cr().modify(|w| { | 136 | RCC.cr().modify(|w| { |
| 135 | #[cfg(not(stm32wb))] | 137 | #[cfg(not(stm32wb))] |
| 136 | w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); | 138 | w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); |
| @@ -240,7 +242,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 240 | let pll_input = PllInput { | 242 | let pll_input = PllInput { |
| 241 | hse, | 243 | hse, |
| 242 | hsi, | 244 | hsi, |
| 243 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] | 245 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] |
| 244 | msi, | 246 | msi, |
| 245 | }; | 247 | }; |
| 246 | let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); | 248 | let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); |
| @@ -254,6 +256,10 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 254 | Sysclk::HSI => hsi.unwrap(), | 256 | Sysclk::HSI => hsi.unwrap(), |
| 255 | Sysclk::MSI => msi.unwrap(), | 257 | Sysclk::MSI => msi.unwrap(), |
| 256 | Sysclk::PLL1_R => pll.r.unwrap(), | 258 | Sysclk::PLL1_R => pll.r.unwrap(), |
| 259 | #[cfg(stm32u0)] | ||
| 260 | Sysclk::LSI | Sysclk::LSE => todo!(), | ||
| 261 | #[cfg(stm32u0)] | ||
| 262 | Sysclk::_RESERVED_6 | Sysclk::_RESERVED_7 => unreachable!(), | ||
| 257 | }; | 263 | }; |
| 258 | 264 | ||
| 259 | #[cfg(rcc_l4plus)] | 265 | #[cfg(rcc_l4plus)] |
| @@ -263,6 +269,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 263 | 269 | ||
| 264 | let hclk1 = sys_clk / config.ahb_pre; | 270 | let hclk1 = sys_clk / config.ahb_pre; |
| 265 | let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); | 271 | let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); |
| 272 | #[cfg(not(stm32u0))] | ||
| 266 | let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); | 273 | let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); |
| 267 | #[cfg(any(stm32l4, stm32l5, stm32wlex))] | 274 | #[cfg(any(stm32l4, stm32l5, stm32wlex))] |
| 268 | let hclk2 = hclk1; | 275 | let hclk2 = hclk1; |
| @@ -315,6 +322,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 315 | ..=64_000_000 => 3, | 322 | ..=64_000_000 => 3, |
| 316 | _ => 4, | 323 | _ => 4, |
| 317 | }; | 324 | }; |
| 325 | #[cfg(stm32u0)] | ||
| 326 | let latency = match hclk1.0 { | ||
| 327 | // VOS RANGE1, others TODO. | ||
| 328 | ..=24_000_000 => 0, | ||
| 329 | ..=48_000_000 => 1, | ||
| 330 | _ => 2, | ||
| 331 | }; | ||
| 318 | 332 | ||
| 319 | #[cfg(stm32l1)] | 333 | #[cfg(stm32l1)] |
| 320 | FLASH.acr().write(|w| w.set_acc64(true)); | 334 | FLASH.acr().write(|w| w.set_acc64(true)); |
| @@ -326,7 +340,11 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 326 | RCC.cfgr().modify(|w| { | 340 | RCC.cfgr().modify(|w| { |
| 327 | w.set_sw(config.sys); | 341 | w.set_sw(config.sys); |
| 328 | w.set_hpre(config.ahb_pre); | 342 | w.set_hpre(config.ahb_pre); |
| 343 | #[cfg(stm32u0)] | ||
| 344 | w.set_ppre(config.apb1_pre); | ||
| 345 | #[cfg(not(stm32u0))] | ||
| 329 | w.set_ppre1(config.apb1_pre); | 346 | w.set_ppre1(config.apb1_pre); |
| 347 | #[cfg(not(stm32u0))] | ||
| 330 | w.set_ppre2(config.apb2_pre); | 348 | w.set_ppre2(config.apb2_pre); |
| 331 | }); | 349 | }); |
| 332 | while RCC.cfgr().read().sws() != config.sys {} | 350 | while RCC.cfgr().read().sws() != config.sys {} |
| @@ -353,8 +371,10 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 353 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] | 371 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] |
| 354 | hclk3: Some(hclk3), | 372 | hclk3: Some(hclk3), |
| 355 | pclk1: Some(pclk1), | 373 | pclk1: Some(pclk1), |
| 374 | #[cfg(not(stm32u0))] | ||
| 356 | pclk2: Some(pclk2), | 375 | pclk2: Some(pclk2), |
| 357 | pclk1_tim: Some(pclk1_tim), | 376 | pclk1_tim: Some(pclk1_tim), |
| 377 | #[cfg(not(stm32u0))] | ||
| 358 | pclk2_tim: Some(pclk2_tim), | 378 | pclk2_tim: Some(pclk2_tim), |
| 359 | #[cfg(stm32wl)] | 379 | #[cfg(stm32wl)] |
| 360 | pclk3: Some(hclk3), | 380 | pclk3: Some(hclk3), |
| @@ -408,7 +428,7 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { | |||
| 408 | Hertz(32_768 * (1 << (range as u8 + 1))) | 428 | Hertz(32_768 * (1 << (range as u8 + 1))) |
| 409 | } | 429 | } |
| 410 | 430 | ||
| 411 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] | 431 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] |
| 412 | fn msirange_to_hertz(range: MSIRange) -> Hertz { | 432 | fn msirange_to_hertz(range: MSIRange) -> Hertz { |
| 413 | match range { | 433 | match range { |
| 414 | MSIRange::RANGE100K => Hertz(100_000), | 434 | MSIRange::RANGE100K => Hertz(100_000), |
| @@ -521,7 +541,7 @@ mod pll { | |||
| 521 | } | 541 | } |
| 522 | } | 542 | } |
| 523 | 543 | ||
| 524 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] | 544 | #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl, stm32u0))] |
| 525 | mod pll { | 545 | mod pll { |
| 526 | use super::{pll_enable, PllInstance}; | 546 | use super::{pll_enable, PllInstance}; |
| 527 | pub use crate::pac::rcc::vals::{ | 547 | pub use crate::pac::rcc::vals::{ |
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index d8604e07e..4b22a099d 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs | |||
| @@ -52,7 +52,7 @@ macro_rules! impl_peri { | |||
| 52 | }; | 52 | }; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | #[cfg(any(rcc_c0, rcc_g0))] | 55 | #[cfg(any(rcc_c0, rcc_g0, rcc_u0))] |
| 56 | #[allow(unused_imports)] | 56 | #[allow(unused_imports)] |
| 57 | use self::{McoSource as Mco1Source, McoSource as Mco2Source}; | 57 | use self::{McoSource as Mco1Source, McoSource as Mco2Source}; |
| 58 | 58 | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 5497bba07..a4e497fe7 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -25,7 +25,7 @@ pub use hsi48::*; | |||
| 25 | #[cfg_attr(stm32g0, path = "g0.rs")] | 25 | #[cfg_attr(stm32g0, path = "g0.rs")] |
| 26 | #[cfg_attr(stm32g4, path = "g4.rs")] | 26 | #[cfg_attr(stm32g4, path = "g4.rs")] |
| 27 | #[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")] | 27 | #[cfg_attr(any(stm32h5, stm32h7), path = "h.rs")] |
| 28 | #[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] | 28 | #[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl, stm32u0), path = "l.rs")] |
| 29 | #[cfg_attr(stm32u5, path = "u5.rs")] | 29 | #[cfg_attr(stm32u5, path = "u5.rs")] |
| 30 | #[cfg_attr(stm32wba, path = "wba.rs")] | 30 | #[cfg_attr(stm32wba, path = "wba.rs")] |
| 31 | mod _version; | 31 | mod _version; |
diff --git a/examples/stm32u0/.cargo/config.toml b/examples/stm32u0/.cargo/config.toml new file mode 100644 index 000000000..688347084 --- /dev/null +++ b/examples/stm32u0/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace stm32u083rctx with your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --chip stm32u083rctx" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv6m-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace" | ||
diff --git a/examples/stm32u0/Cargo.toml b/examples/stm32u0/Cargo.toml new file mode 100644 index 000000000..495be3e75 --- /dev/null +++ b/examples/stm32u0/Cargo.toml | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-stm32u0-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | # Change stm32u083rc to your chip name, if necessary. | ||
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32u083rc", "memory-x", "unstable-pac", "exti"] } | ||
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | ||
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | ||
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | ||
| 13 | |||
| 14 | defmt = "0.3" | ||
| 15 | defmt-rtt = "0.4" | ||
| 16 | |||
| 17 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 18 | cortex-m-rt = "0.7.0" | ||
| 19 | embedded-hal = "0.2.6" | ||
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 22 | heapless = { version = "0.8", default-features = false } | ||
| 23 | |||
| 24 | [profile.release] | ||
| 25 | debug = 2 | ||
diff --git a/examples/stm32u0/build.rs b/examples/stm32u0/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32u0/build.rs | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | fn main() { | ||
| 2 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 3 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 4 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 5 | } | ||
diff --git a/examples/stm32u0/src/bin/blinky.rs b/examples/stm32u0/src/bin/blinky.rs new file mode 100644 index 000000000..90e479aae --- /dev/null +++ b/examples/stm32u0/src/bin/blinky.rs | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 7 | use embassy_time::Timer; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let p = embassy_stm32::init(Default::default()); | ||
| 13 | info!("Hello World!"); | ||
| 14 | |||
| 15 | let mut led = Output::new(p.PA5, Level::High, Speed::Low); | ||
| 16 | |||
| 17 | loop { | ||
| 18 | info!("high"); | ||
| 19 | led.set_high(); | ||
| 20 | Timer::after_millis(300).await; | ||
| 21 | |||
| 22 | info!("low"); | ||
| 23 | led.set_low(); | ||
| 24 | Timer::after_millis(300).await; | ||
| 25 | } | ||
| 26 | } | ||
diff --git a/examples/stm32u0/src/bin/button.rs b/examples/stm32u0/src/bin/button.rs new file mode 100644 index 000000000..8017f0274 --- /dev/null +++ b/examples/stm32u0/src/bin/button.rs | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use cortex_m_rt::entry; | ||
| 5 | use defmt::*; | ||
| 6 | use embassy_stm32::gpio::{Input, Pull}; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[entry] | ||
| 10 | fn main() -> ! { | ||
| 11 | info!("Hello World!"); | ||
| 12 | |||
| 13 | let p = embassy_stm32::init(Default::default()); | ||
| 14 | |||
| 15 | let button = Input::new(p.PC13, Pull::Up); | ||
| 16 | |||
| 17 | loop { | ||
| 18 | if button.is_high() { | ||
| 19 | info!("high"); | ||
| 20 | } else { | ||
| 21 | info!("low"); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | } | ||
diff --git a/examples/stm32u0/src/bin/button_exti.rs b/examples/stm32u0/src/bin/button_exti.rs new file mode 100644 index 000000000..34a08bbc6 --- /dev/null +++ b/examples/stm32u0/src/bin/button_exti.rs | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::exti::ExtiInput; | ||
| 7 | use embassy_stm32::gpio::Pull; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let p = embassy_stm32::init(Default::default()); | ||
| 13 | info!("Hello World!"); | ||
| 14 | |||
| 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); | ||
| 16 | |||
| 17 | info!("Press the USER button..."); | ||
| 18 | |||
| 19 | loop { | ||
| 20 | button.wait_for_falling_edge().await; | ||
| 21 | info!("Pressed!"); | ||
| 22 | button.wait_for_rising_edge().await; | ||
| 23 | info!("Released!"); | ||
| 24 | } | ||
| 25 | } | ||
