diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-11-27 02:21:53 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-11-27 02:34:23 +0100 |
| commit | 88d4b0c00d5164f2fe6307bacce74887b3f8d4da (patch) | |
| tree | a74fe2a9024167880d4ee4c7ac4f748ce5415f76 | |
| parent | c7d97290284d2637c1eb89f65ff18f913342a71b (diff) | |
stm32: add stm32g4 support.
| -rw-r--r-- | .vscode/settings.json | 9 | ||||
| -rwxr-xr-x | ci.sh | 1 | ||||
| -rw-r--r-- | embassy-stm32/Cargo.toml | 93 | ||||
| -rw-r--r-- | embassy-stm32/src/pwr/g4.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/pwr/mod.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/g4/mod.rs | 219 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 7 | ||||
| -rw-r--r-- | examples/stm32g0/Cargo.toml | 2 | ||||
| -rw-r--r-- | examples/stm32g4/.cargo/config.toml | 6 | ||||
| -rw-r--r-- | examples/stm32g4/Cargo.toml | 22 | ||||
| -rw-r--r-- | examples/stm32g4/build.rs | 5 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/blinky.rs | 29 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/button.rs | 27 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/button_exti.rs | 29 | ||||
| -rw-r--r-- | examples/stm32g4/src/example_common.rs | 17 | ||||
| m--------- | stm32-data | 0 | ||||
| -rw-r--r-- | stm32-gen-features/src/lib.rs | 5 |
17 files changed, 465 insertions, 8 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index 2be7ffbe0..0e67ab824 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json | |||
| @@ -10,9 +10,12 @@ | |||
| 10 | "rust-analyzer.cargo.target": "thumbv7em-none-eabi", | 10 | "rust-analyzer.cargo.target": "thumbv7em-none-eabi", |
| 11 | "rust-analyzer.cargo.features": [ | 11 | "rust-analyzer.cargo.features": [ |
| 12 | // These are needed to prevent embassy-net from failing to build | 12 | // These are needed to prevent embassy-net from failing to build |
| 13 | "embassy-net/medium-ethernet", | 13 | //"embassy-net/medium-ethernet", |
| 14 | "embassy-net/tcp", | 14 | //"embassy-net/tcp", |
| 15 | "embassy-net/pool-16", | 15 | //"embassy-net/pool-16", |
| 16 | ], | ||
| 17 | "rust-analyzer.linkedProjects": [ | ||
| 18 | "examples/stm32g4/Cargo.toml" | ||
| 16 | ], | 19 | ], |
| 17 | "rust-analyzer.procMacro.enable": true, | 20 | "rust-analyzer.procMacro.enable": true, |
| 18 | "rust-analyzer.cargo.runBuildScripts": true, | 21 | "rust-analyzer.cargo.runBuildScripts": true, |
| @@ -47,6 +47,7 @@ cargo batch \ | |||
| 47 | --- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \ | 47 | --- build --release --manifest-path examples/stm32f4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32f4 \ |
| 48 | --- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \ | 48 | --- build --release --manifest-path examples/stm32f7/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32f7 \ |
| 49 | --- build --release --manifest-path examples/stm32g0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32g0 \ | 49 | --- build --release --manifest-path examples/stm32g0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32g0 \ |
| 50 | --- build --release --manifest-path examples/stm32g4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32g4 \ | ||
| 50 | --- build --release --manifest-path examples/stm32h7/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h7 \ | 51 | --- build --release --manifest-path examples/stm32h7/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/stm32h7 \ |
| 51 | --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32l0 \ | 52 | --- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32l0 \ |
| 52 | --- build --release --manifest-path examples/stm32l1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32l1 \ | 53 | --- build --release --manifest-path examples/stm32l1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/stm32l1 \ |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 364c48f60..74903de0b 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -564,6 +564,99 @@ stm32g0c1rc = [ "stm32-metapac/stm32g0c1rc" ] | |||
| 564 | stm32g0c1re = [ "stm32-metapac/stm32g0c1re" ] | 564 | stm32g0c1re = [ "stm32-metapac/stm32g0c1re" ] |
| 565 | stm32g0c1vc = [ "stm32-metapac/stm32g0c1vc" ] | 565 | stm32g0c1vc = [ "stm32-metapac/stm32g0c1vc" ] |
| 566 | stm32g0c1ve = [ "stm32-metapac/stm32g0c1ve" ] | 566 | stm32g0c1ve = [ "stm32-metapac/stm32g0c1ve" ] |
| 567 | stm32g431c6 = [ "stm32-metapac/stm32g431c6" ] | ||
| 568 | stm32g431c8 = [ "stm32-metapac/stm32g431c8" ] | ||
| 569 | stm32g431cb = [ "stm32-metapac/stm32g431cb" ] | ||
| 570 | stm32g431k6 = [ "stm32-metapac/stm32g431k6" ] | ||
| 571 | stm32g431k8 = [ "stm32-metapac/stm32g431k8" ] | ||
| 572 | stm32g431kb = [ "stm32-metapac/stm32g431kb" ] | ||
| 573 | stm32g431m6 = [ "stm32-metapac/stm32g431m6" ] | ||
| 574 | stm32g431m8 = [ "stm32-metapac/stm32g431m8" ] | ||
| 575 | stm32g431mb = [ "stm32-metapac/stm32g431mb" ] | ||
| 576 | stm32g431r6 = [ "stm32-metapac/stm32g431r6" ] | ||
| 577 | stm32g431r8 = [ "stm32-metapac/stm32g431r8" ] | ||
| 578 | stm32g431rb = [ "stm32-metapac/stm32g431rb" ] | ||
| 579 | stm32g431v6 = [ "stm32-metapac/stm32g431v6" ] | ||
| 580 | stm32g431v8 = [ "stm32-metapac/stm32g431v8" ] | ||
| 581 | stm32g431vb = [ "stm32-metapac/stm32g431vb" ] | ||
| 582 | stm32g441cb = [ "stm32-metapac/stm32g441cb" ] | ||
| 583 | stm32g441kb = [ "stm32-metapac/stm32g441kb" ] | ||
| 584 | stm32g441mb = [ "stm32-metapac/stm32g441mb" ] | ||
| 585 | stm32g441rb = [ "stm32-metapac/stm32g441rb" ] | ||
| 586 | stm32g441vb = [ "stm32-metapac/stm32g441vb" ] | ||
| 587 | stm32g471cc = [ "stm32-metapac/stm32g471cc" ] | ||
| 588 | stm32g471ce = [ "stm32-metapac/stm32g471ce" ] | ||
| 589 | stm32g471mc = [ "stm32-metapac/stm32g471mc" ] | ||
| 590 | stm32g471me = [ "stm32-metapac/stm32g471me" ] | ||
| 591 | stm32g471qc = [ "stm32-metapac/stm32g471qc" ] | ||
| 592 | stm32g471qe = [ "stm32-metapac/stm32g471qe" ] | ||
| 593 | stm32g471rc = [ "stm32-metapac/stm32g471rc" ] | ||
| 594 | stm32g471re = [ "stm32-metapac/stm32g471re" ] | ||
| 595 | stm32g471vc = [ "stm32-metapac/stm32g471vc" ] | ||
| 596 | stm32g471ve = [ "stm32-metapac/stm32g471ve" ] | ||
| 597 | stm32g473cb = [ "stm32-metapac/stm32g473cb" ] | ||
| 598 | stm32g473cc = [ "stm32-metapac/stm32g473cc" ] | ||
| 599 | stm32g473ce = [ "stm32-metapac/stm32g473ce" ] | ||
| 600 | stm32g473mb = [ "stm32-metapac/stm32g473mb" ] | ||
| 601 | stm32g473mc = [ "stm32-metapac/stm32g473mc" ] | ||
| 602 | stm32g473me = [ "stm32-metapac/stm32g473me" ] | ||
| 603 | stm32g473pb = [ "stm32-metapac/stm32g473pb" ] | ||
| 604 | stm32g473pc = [ "stm32-metapac/stm32g473pc" ] | ||
| 605 | stm32g473pe = [ "stm32-metapac/stm32g473pe" ] | ||
| 606 | stm32g473qb = [ "stm32-metapac/stm32g473qb" ] | ||
| 607 | stm32g473qc = [ "stm32-metapac/stm32g473qc" ] | ||
| 608 | stm32g473qe = [ "stm32-metapac/stm32g473qe" ] | ||
| 609 | stm32g473rb = [ "stm32-metapac/stm32g473rb" ] | ||
| 610 | stm32g473rc = [ "stm32-metapac/stm32g473rc" ] | ||
| 611 | stm32g473re = [ "stm32-metapac/stm32g473re" ] | ||
| 612 | stm32g473vb = [ "stm32-metapac/stm32g473vb" ] | ||
| 613 | stm32g473vc = [ "stm32-metapac/stm32g473vc" ] | ||
| 614 | stm32g473ve = [ "stm32-metapac/stm32g473ve" ] | ||
| 615 | stm32g474cb = [ "stm32-metapac/stm32g474cb" ] | ||
| 616 | stm32g474cc = [ "stm32-metapac/stm32g474cc" ] | ||
| 617 | stm32g474ce = [ "stm32-metapac/stm32g474ce" ] | ||
| 618 | stm32g474mb = [ "stm32-metapac/stm32g474mb" ] | ||
| 619 | stm32g474mc = [ "stm32-metapac/stm32g474mc" ] | ||
| 620 | stm32g474me = [ "stm32-metapac/stm32g474me" ] | ||
| 621 | stm32g474pb = [ "stm32-metapac/stm32g474pb" ] | ||
| 622 | stm32g474pc = [ "stm32-metapac/stm32g474pc" ] | ||
| 623 | stm32g474pe = [ "stm32-metapac/stm32g474pe" ] | ||
| 624 | stm32g474qb = [ "stm32-metapac/stm32g474qb" ] | ||
| 625 | stm32g474qc = [ "stm32-metapac/stm32g474qc" ] | ||
| 626 | stm32g474qe = [ "stm32-metapac/stm32g474qe" ] | ||
| 627 | stm32g474rb = [ "stm32-metapac/stm32g474rb" ] | ||
| 628 | stm32g474rc = [ "stm32-metapac/stm32g474rc" ] | ||
| 629 | stm32g474re = [ "stm32-metapac/stm32g474re" ] | ||
| 630 | stm32g474vb = [ "stm32-metapac/stm32g474vb" ] | ||
| 631 | stm32g474vc = [ "stm32-metapac/stm32g474vc" ] | ||
| 632 | stm32g474ve = [ "stm32-metapac/stm32g474ve" ] | ||
| 633 | stm32g483ce = [ "stm32-metapac/stm32g483ce" ] | ||
| 634 | stm32g483me = [ "stm32-metapac/stm32g483me" ] | ||
| 635 | stm32g483pe = [ "stm32-metapac/stm32g483pe" ] | ||
| 636 | stm32g483qe = [ "stm32-metapac/stm32g483qe" ] | ||
| 637 | stm32g483re = [ "stm32-metapac/stm32g483re" ] | ||
| 638 | stm32g483ve = [ "stm32-metapac/stm32g483ve" ] | ||
| 639 | stm32g484ce = [ "stm32-metapac/stm32g484ce" ] | ||
| 640 | stm32g484me = [ "stm32-metapac/stm32g484me" ] | ||
| 641 | stm32g484pe = [ "stm32-metapac/stm32g484pe" ] | ||
| 642 | stm32g484qe = [ "stm32-metapac/stm32g484qe" ] | ||
| 643 | stm32g484re = [ "stm32-metapac/stm32g484re" ] | ||
| 644 | stm32g484ve = [ "stm32-metapac/stm32g484ve" ] | ||
| 645 | stm32g491cc = [ "stm32-metapac/stm32g491cc" ] | ||
| 646 | stm32g491ce = [ "stm32-metapac/stm32g491ce" ] | ||
| 647 | stm32g491kc = [ "stm32-metapac/stm32g491kc" ] | ||
| 648 | stm32g491ke = [ "stm32-metapac/stm32g491ke" ] | ||
| 649 | stm32g491mc = [ "stm32-metapac/stm32g491mc" ] | ||
| 650 | stm32g491me = [ "stm32-metapac/stm32g491me" ] | ||
| 651 | stm32g491rc = [ "stm32-metapac/stm32g491rc" ] | ||
| 652 | stm32g491re = [ "stm32-metapac/stm32g491re" ] | ||
| 653 | stm32g491vc = [ "stm32-metapac/stm32g491vc" ] | ||
| 654 | stm32g491ve = [ "stm32-metapac/stm32g491ve" ] | ||
| 655 | stm32g4a1ce = [ "stm32-metapac/stm32g4a1ce" ] | ||
| 656 | stm32g4a1ke = [ "stm32-metapac/stm32g4a1ke" ] | ||
| 657 | stm32g4a1me = [ "stm32-metapac/stm32g4a1me" ] | ||
| 658 | stm32g4a1re = [ "stm32-metapac/stm32g4a1re" ] | ||
| 659 | stm32g4a1ve = [ "stm32-metapac/stm32g4a1ve" ] | ||
| 567 | stm32h723ve = [ "stm32-metapac/stm32h723ve" ] | 660 | stm32h723ve = [ "stm32-metapac/stm32h723ve" ] |
| 568 | stm32h723vg = [ "stm32-metapac/stm32h723vg" ] | 661 | stm32h723vg = [ "stm32-metapac/stm32h723vg" ] |
| 569 | stm32h723ze = [ "stm32-metapac/stm32h723ze" ] | 662 | stm32h723ze = [ "stm32-metapac/stm32h723ze" ] |
diff --git a/embassy-stm32/src/pwr/g4.rs b/embassy-stm32/src/pwr/g4.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/embassy-stm32/src/pwr/g4.rs | |||
| @@ -0,0 +1 @@ | |||
diff --git a/embassy-stm32/src/pwr/mod.rs b/embassy-stm32/src/pwr/mod.rs index bd3d23cac..a71ce8f3c 100644 --- a/embassy-stm32/src/pwr/mod.rs +++ b/embassy-stm32/src/pwr/mod.rs | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #[cfg_attr(pwr_f7, path = "f7.rs")] | 3 | #[cfg_attr(pwr_f7, path = "f7.rs")] |
| 4 | #[cfg_attr(pwr_wl5, path = "wl5.rs")] | 4 | #[cfg_attr(pwr_wl5, path = "wl5.rs")] |
| 5 | #[cfg_attr(pwr_g0, path = "g0.rs")] | 5 | #[cfg_attr(pwr_g0, path = "g0.rs")] |
| 6 | #[cfg_attr(pwr_g4, path = "g4.rs")] | ||
| 6 | #[cfg_attr(pwr_l1, path = "l1.rs")] | 7 | #[cfg_attr(pwr_l1, path = "l1.rs")] |
| 7 | #[cfg_attr(pwr_u5, path = "u5.rs")] | 8 | #[cfg_attr(pwr_u5, path = "u5.rs")] |
| 8 | mod _version; | 9 | mod _version; |
diff --git a/embassy-stm32/src/rcc/g4/mod.rs b/embassy-stm32/src/rcc/g4/mod.rs new file mode 100644 index 000000000..b0338e725 --- /dev/null +++ b/embassy-stm32/src/rcc/g4/mod.rs | |||
| @@ -0,0 +1,219 @@ | |||
| 1 | pub use super::types::*; | ||
| 2 | use crate::pac; | ||
| 3 | use crate::peripherals::{self, RCC}; | ||
| 4 | use crate::rcc::{get_freqs, set_freqs, Clocks}; | ||
| 5 | use crate::time::Hertz; | ||
| 6 | use crate::time::U32Ext; | ||
| 7 | use core::marker::PhantomData; | ||
| 8 | use embassy::util::Unborrow; | ||
| 9 | use embassy_hal_common::unborrow; | ||
| 10 | |||
| 11 | /// HSI speed | ||
| 12 | pub const HSI_FREQ: u32 = 16_000_000; | ||
| 13 | |||
| 14 | /// LSI speed | ||
| 15 | pub const LSI_FREQ: u32 = 32_000; | ||
| 16 | |||
| 17 | /// System clock mux source | ||
| 18 | #[derive(Clone, Copy)] | ||
| 19 | pub enum ClockSrc { | ||
| 20 | HSE(Hertz), | ||
| 21 | HSI16, | ||
| 22 | } | ||
| 23 | |||
| 24 | impl Into<u8> for APBPrescaler { | ||
| 25 | fn into(self) -> u8 { | ||
| 26 | match self { | ||
| 27 | APBPrescaler::NotDivided => 1, | ||
| 28 | APBPrescaler::Div2 => 0x04, | ||
| 29 | APBPrescaler::Div4 => 0x05, | ||
| 30 | APBPrescaler::Div8 => 0x06, | ||
| 31 | APBPrescaler::Div16 => 0x07, | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | impl Into<u8> for AHBPrescaler { | ||
| 37 | fn into(self) -> u8 { | ||
| 38 | match self { | ||
| 39 | AHBPrescaler::NotDivided => 1, | ||
| 40 | AHBPrescaler::Div2 => 0x08, | ||
| 41 | AHBPrescaler::Div4 => 0x09, | ||
| 42 | AHBPrescaler::Div8 => 0x0a, | ||
| 43 | AHBPrescaler::Div16 => 0x0b, | ||
| 44 | AHBPrescaler::Div64 => 0x0c, | ||
| 45 | AHBPrescaler::Div128 => 0x0d, | ||
| 46 | AHBPrescaler::Div256 => 0x0e, | ||
| 47 | AHBPrescaler::Div512 => 0x0f, | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Clocks configutation | ||
| 53 | pub struct Config { | ||
| 54 | mux: ClockSrc, | ||
| 55 | ahb_pre: AHBPrescaler, | ||
| 56 | apb1_pre: APBPrescaler, | ||
| 57 | apb2_pre: APBPrescaler, | ||
| 58 | low_power_run: bool, | ||
| 59 | } | ||
| 60 | |||
| 61 | impl Default for Config { | ||
| 62 | #[inline] | ||
| 63 | fn default() -> Config { | ||
| 64 | Config { | ||
| 65 | mux: ClockSrc::HSI16, | ||
| 66 | ahb_pre: AHBPrescaler::NotDivided, | ||
| 67 | apb1_pre: APBPrescaler::NotDivided, | ||
| 68 | apb2_pre: APBPrescaler::NotDivided, | ||
| 69 | low_power_run: false, | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | impl Config { | ||
| 75 | #[inline] | ||
| 76 | pub fn clock_src(mut self, mux: ClockSrc) -> Self { | ||
| 77 | self.mux = mux; | ||
| 78 | self | ||
| 79 | } | ||
| 80 | |||
| 81 | #[inline] | ||
| 82 | pub fn ahb_pre(mut self, pre: AHBPrescaler) -> Self { | ||
| 83 | self.ahb_pre = pre; | ||
| 84 | self | ||
| 85 | } | ||
| 86 | |||
| 87 | #[inline] | ||
| 88 | pub fn apb1_pre(mut self, pre: APBPrescaler) -> Self { | ||
| 89 | self.apb1_pre = pre; | ||
| 90 | self | ||
| 91 | } | ||
| 92 | |||
| 93 | #[inline] | ||
| 94 | pub fn apb2_pre(mut self, pre: APBPrescaler) -> Self { | ||
| 95 | self.apb2_pre = pre; | ||
| 96 | self | ||
| 97 | } | ||
| 98 | |||
| 99 | #[inline] | ||
| 100 | pub fn low_power_run(mut self, on: bool) -> Self { | ||
| 101 | self.low_power_run = on; | ||
| 102 | self | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | /// RCC peripheral | ||
| 107 | pub struct Rcc<'d> { | ||
| 108 | _rb: peripherals::RCC, | ||
| 109 | phantom: PhantomData<&'d mut peripherals::RCC>, | ||
| 110 | } | ||
| 111 | |||
| 112 | impl<'d> Rcc<'d> { | ||
| 113 | pub fn new(rcc: impl Unborrow<Target = peripherals::RCC> + 'd) -> Self { | ||
| 114 | unborrow!(rcc); | ||
| 115 | Self { | ||
| 116 | _rb: rcc, | ||
| 117 | phantom: PhantomData, | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | // Safety: RCC init must have been called | ||
| 122 | pub fn clocks(&self) -> &'static Clocks { | ||
| 123 | unsafe { get_freqs() } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | /// Extension trait that freezes the `RCC` peripheral with provided clocks configuration | ||
| 128 | pub trait RccExt { | ||
| 129 | fn freeze(self, config: Config) -> Clocks; | ||
| 130 | } | ||
| 131 | |||
| 132 | impl RccExt for RCC { | ||
| 133 | #[inline] | ||
| 134 | fn freeze(self, cfgr: Config) -> Clocks { | ||
| 135 | let rcc = pac::RCC; | ||
| 136 | let (sys_clk, sw) = match cfgr.mux { | ||
| 137 | ClockSrc::HSI16 => { | ||
| 138 | // Enable HSI16 | ||
| 139 | unsafe { | ||
| 140 | rcc.cr().write(|w| w.set_hsion(true)); | ||
| 141 | while !rcc.cr().read().hsirdy() {} | ||
| 142 | } | ||
| 143 | |||
| 144 | (HSI_FREQ, 0x01) | ||
| 145 | } | ||
| 146 | ClockSrc::HSE(freq) => { | ||
| 147 | // Enable HSE | ||
| 148 | unsafe { | ||
| 149 | rcc.cr().write(|w| w.set_hseon(true)); | ||
| 150 | while !rcc.cr().read().hserdy() {} | ||
| 151 | } | ||
| 152 | |||
| 153 | (freq.0, 0x02) | ||
| 154 | } | ||
| 155 | }; | ||
| 156 | |||
| 157 | unsafe { | ||
| 158 | rcc.cfgr().modify(|w| { | ||
| 159 | w.set_sw(sw.into()); | ||
| 160 | w.set_hpre(cfgr.ahb_pre.into()); | ||
| 161 | w.set_ppre1(cfgr.apb1_pre.into()); | ||
| 162 | w.set_ppre2(cfgr.apb2_pre.into()); | ||
| 163 | }); | ||
| 164 | } | ||
| 165 | |||
| 166 | let ahb_freq: u32 = match cfgr.ahb_pre { | ||
| 167 | AHBPrescaler::NotDivided => sys_clk, | ||
| 168 | pre => { | ||
| 169 | let pre: u8 = pre.into(); | ||
| 170 | let pre = 1 << (pre as u32 - 7); | ||
| 171 | sys_clk / pre | ||
| 172 | } | ||
| 173 | }; | ||
| 174 | |||
| 175 | let (apb1_freq, apb1_tim_freq) = match cfgr.apb1_pre { | ||
| 176 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | ||
| 177 | pre => { | ||
| 178 | let pre: u8 = pre.into(); | ||
| 179 | let pre: u8 = 1 << (pre - 3); | ||
| 180 | let freq = ahb_freq / pre as u32; | ||
| 181 | (freq, freq * 2) | ||
| 182 | } | ||
| 183 | }; | ||
| 184 | |||
| 185 | let (apb2_freq, apb2_tim_freq) = match cfgr.apb2_pre { | ||
| 186 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | ||
| 187 | pre => { | ||
| 188 | let pre: u8 = pre.into(); | ||
| 189 | let pre: u8 = 1 << (pre - 3); | ||
| 190 | let freq = ahb_freq / pre as u32; | ||
| 191 | (freq, freq * 2) | ||
| 192 | } | ||
| 193 | }; | ||
| 194 | |||
| 195 | let pwr = pac::PWR; | ||
| 196 | if cfgr.low_power_run { | ||
| 197 | assert!(sys_clk.hz() <= 2_000_000.hz()); | ||
| 198 | unsafe { | ||
| 199 | pwr.cr1().modify(|w| w.set_lpr(true)); | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | Clocks { | ||
| 204 | sys: sys_clk.hz(), | ||
| 205 | ahb1: ahb_freq.hz(), | ||
| 206 | ahb2: ahb_freq.hz(), | ||
| 207 | apb1: apb1_freq.hz(), | ||
| 208 | apb1_tim: apb1_tim_freq.hz(), | ||
| 209 | apb2: apb2_freq.hz(), | ||
| 210 | apb2_tim: apb2_tim_freq.hz(), | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | pub unsafe fn init(config: Config) { | ||
| 216 | let r = <peripherals::RCC as embassy::util::Steal>::steal(); | ||
| 217 | let clocks = r.freeze(config); | ||
| 218 | set_freqs(clocks); | ||
| 219 | } | ||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 8db2f10ea..cdcbd2afc 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -30,10 +30,10 @@ pub struct Clocks { | |||
| 30 | #[cfg(any(rcc_l0, rcc_l1, rcc_f0, rcc_f1, rcc_f0x0, rcc_g0))] | 30 | #[cfg(any(rcc_l0, rcc_l1, rcc_f0, rcc_f1, rcc_f0x0, rcc_g0))] |
| 31 | pub ahb: Hertz, | 31 | pub ahb: Hertz, |
| 32 | 32 | ||
| 33 | #[cfg(any(rcc_l4, rcc_f4, rcc_f7, rcc_h7, rcc_u5, rcc_wb, rcc_wl5))] | 33 | #[cfg(any(rcc_l4, rcc_f4, rcc_f7, rcc_h7, rcc_g4, rcc_u5, rcc_wb, rcc_wl5))] |
| 34 | pub ahb1: Hertz, | 34 | pub ahb1: Hertz, |
| 35 | 35 | ||
| 36 | #[cfg(any(rcc_l4, rcc_f4, rcc_f7, rcc_h7, rcc_u5, rcc_wb, rcc_wl5))] | 36 | #[cfg(any(rcc_l4, rcc_f4, rcc_f7, rcc_h7, rcc_g4, rcc_u5, rcc_wb, rcc_wl5))] |
| 37 | pub ahb2: Hertz, | 37 | pub ahb2: Hertz, |
| 38 | 38 | ||
| 39 | #[cfg(any(rcc_l4, rcc_f4, rcc_f7, rcc_h7, rcc_u5, rcc_wb, rcc_wl5))] | 39 | #[cfg(any(rcc_l4, rcc_f4, rcc_f7, rcc_h7, rcc_u5, rcc_wb, rcc_wl5))] |
| @@ -100,6 +100,9 @@ cfg_if::cfg_if! { | |||
| 100 | } else if #[cfg(any(rcc_g0))] { | 100 | } else if #[cfg(any(rcc_g0))] { |
| 101 | mod g0; | 101 | mod g0; |
| 102 | pub use g0::*; | 102 | pub use g0::*; |
| 103 | } else if #[cfg(any(rcc_g4))] { | ||
| 104 | mod g4; | ||
| 105 | pub use g4::*; | ||
| 103 | } else if #[cfg(any(rcc_u5))] { | 106 | } else if #[cfg(any(rcc_u5))] { |
| 104 | mod u5; | 107 | mod u5; |
| 105 | pub use u5::*; | 108 | pub use u5::*; |
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 203cdad99..731116c32 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml | |||
| @@ -8,7 +8,7 @@ resolver = "2" | |||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | 9 | embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } |
| 10 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | 10 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "time-driver-tim2", "stm32g071rb", "unstable-pac"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "time-driver-tim2", "stm32g071rb", "memory-x", "unstable-pac"] } |
| 12 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } | 12 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } |
| 13 | 13 | ||
| 14 | defmt = "0.3" | 14 | defmt = "0.3" |
diff --git a/examples/stm32g4/.cargo/config.toml b/examples/stm32g4/.cargo/config.toml new file mode 100644 index 000000000..62003c2a4 --- /dev/null +++ b/examples/stm32g4/.cargo/config.toml | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace STM32G071C8Rx with your chip as listed in `probe-run --list-chips` | ||
| 3 | runner = "probe-run --chip STM32G484VETx" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabi" | ||
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml new file mode 100644 index 000000000..0f9d77f5e --- /dev/null +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | [package] | ||
| 2 | authors = ["Dario Nieuwenhuis <[email protected]>", "Ben Gamari <[email protected]>"] | ||
| 3 | edition = "2018" | ||
| 4 | name = "embassy-stm32g4-examples" | ||
| 5 | version = "0.1.0" | ||
| 6 | resolver = "2" | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | ||
| 10 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | ||
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "time-driver-tim2", "stm32g491re", "memory-x", "unstable-pac"] } | ||
| 12 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } | ||
| 13 | |||
| 14 | defmt = "0.3" | ||
| 15 | defmt-rtt = "0.3" | ||
| 16 | |||
| 17 | cortex-m = "0.7.3" | ||
| 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.7.5", default-features = false } | ||
diff --git a/examples/stm32g4/build.rs b/examples/stm32g4/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32g4/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/stm32g4/src/bin/blinky.rs b/examples/stm32g4/src/bin/blinky.rs new file mode 100644 index 000000000..a43922a63 --- /dev/null +++ b/examples/stm32g4/src/bin/blinky.rs | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | #[path = "../example_common.rs"] | ||
| 6 | mod example_common; | ||
| 7 | use embassy::executor::Spawner; | ||
| 8 | use embassy::time::{Duration, Timer}; | ||
| 9 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 10 | use embassy_stm32::Peripherals; | ||
| 11 | use embedded_hal::digital::v2::OutputPin; | ||
| 12 | use example_common::*; | ||
| 13 | |||
| 14 | #[embassy::main] | ||
| 15 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 16 | info!("Hello World!"); | ||
| 17 | |||
| 18 | let mut led = Output::new(p.PA5, Level::High, Speed::Low); | ||
| 19 | |||
| 20 | loop { | ||
| 21 | info!("high"); | ||
| 22 | unwrap!(led.set_high()); | ||
| 23 | Timer::after(Duration::from_millis(300)).await; | ||
| 24 | |||
| 25 | info!("low"); | ||
| 26 | unwrap!(led.set_low()); | ||
| 27 | Timer::after(Duration::from_millis(300)).await; | ||
| 28 | } | ||
| 29 | } | ||
diff --git a/examples/stm32g4/src/bin/button.rs b/examples/stm32g4/src/bin/button.rs new file mode 100644 index 000000000..f0a4c8745 --- /dev/null +++ b/examples/stm32g4/src/bin/button.rs | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | #[path = "../example_common.rs"] | ||
| 6 | mod example_common; | ||
| 7 | use cortex_m_rt::entry; | ||
| 8 | use embassy_stm32::gpio::{Input, Pull}; | ||
| 9 | use embedded_hal::digital::v2::InputPin; | ||
| 10 | use example_common::*; | ||
| 11 | |||
| 12 | #[entry] | ||
| 13 | fn main() -> ! { | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let p = embassy_stm32::init(Default::default()); | ||
| 17 | |||
| 18 | let button = Input::new(p.PC13, Pull::Down); | ||
| 19 | |||
| 20 | loop { | ||
| 21 | if unwrap!(button.is_high()) { | ||
| 22 | info!("high"); | ||
| 23 | } else { | ||
| 24 | info!("low"); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs new file mode 100644 index 000000000..2c4318d64 --- /dev/null +++ b/examples/stm32g4/src/bin/button_exti.rs | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | #[path = "../example_common.rs"] | ||
| 6 | mod example_common; | ||
| 7 | use embassy::executor::Spawner; | ||
| 8 | use embassy_stm32::exti::ExtiInput; | ||
| 9 | use embassy_stm32::gpio::{Input, Pull}; | ||
| 10 | use embassy_stm32::Peripherals; | ||
| 11 | use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge}; | ||
| 12 | use example_common::*; | ||
| 13 | |||
| 14 | #[embassy::main] | ||
| 15 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 16 | info!("Hello World!"); | ||
| 17 | |||
| 18 | let button = Input::new(p.PC13, Pull::Down); | ||
| 19 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 20 | |||
| 21 | info!("Press the USER button..."); | ||
| 22 | |||
| 23 | loop { | ||
| 24 | button.wait_for_rising_edge().await; | ||
| 25 | info!("Pressed!"); | ||
| 26 | button.wait_for_falling_edge().await; | ||
| 27 | info!("Released!"); | ||
| 28 | } | ||
| 29 | } | ||
diff --git a/examples/stm32g4/src/example_common.rs b/examples/stm32g4/src/example_common.rs new file mode 100644 index 000000000..54d633837 --- /dev/null +++ b/examples/stm32g4/src/example_common.rs | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use defmt_rtt as _; // global logger | ||
| 4 | use panic_probe as _; | ||
| 5 | |||
| 6 | pub use defmt::*; | ||
| 7 | |||
| 8 | use core::sync::atomic::{AtomicUsize, Ordering}; | ||
| 9 | |||
| 10 | defmt::timestamp! {"{=u64}", { | ||
| 11 | static COUNT: AtomicUsize = AtomicUsize::new(0); | ||
| 12 | // NOTE(no-CAS) `timestamps` runs with interrupts disabled | ||
| 13 | let n = COUNT.load(Ordering::Relaxed); | ||
| 14 | COUNT.store(n + 1, Ordering::Relaxed); | ||
| 15 | n as u64 | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/stm32-data b/stm32-data | |||
| Subproject 0b75cf54e0836673cf4eee8273befb15e22637c | Subproject e60ce40e6f9d29e9a8b45ea7b9118e0d55b3092 | ||
diff --git a/stm32-gen-features/src/lib.rs b/stm32-gen-features/src/lib.rs index 29ea94a46..50c334852 100644 --- a/stm32-gen-features/src/lib.rs +++ b/stm32-gen-features/src/lib.rs | |||
| @@ -2,12 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | use std::{iter::FilterMap, path::Path, slice::Iter}; | 3 | use std::{iter::FilterMap, path::Path, slice::Iter}; |
| 4 | 4 | ||
| 5 | const SUPPORTED_FAMILIES: [&str; 12] = [ | 5 | const SUPPORTED_FAMILIES: &[&str] = &[ |
| 6 | "stm32f0", | 6 | "stm32f0", |
| 7 | "stm32f1", | 7 | "stm32f1", |
| 8 | "stm32f4", | 8 | "stm32f4", |
| 9 | "stm32f7", | 9 | "stm32f7", |
| 10 | "stm32g0", | 10 | "stm32g0", |
| 11 | "stm32g4", | ||
| 11 | "stm32l0", | 12 | "stm32l0", |
| 12 | "stm32l1", | 13 | "stm32l1", |
| 13 | "stm32l4", | 14 | "stm32l4", |
| @@ -99,7 +100,7 @@ pub fn embassy_stm32_needed_data(names_and_cores: &[(String, Vec<String>)]) -> S | |||
| 99 | if cores.len() > 1 { | 100 | if cores.len() > 1 { |
| 100 | for core_name in cores.iter() { | 101 | for core_name in cores.iter() { |
| 101 | result += &format!( | 102 | result += &format!( |
| 102 | "{chip}_{core} = [ \"stm32-metapac/{chip}_{core}\" ]\n", | 103 | "{chip}-{core} = [ \"stm32-metapac/{chip}-{core}\" ]\n", |
| 103 | chip = chip_name, | 104 | chip = chip_name, |
| 104 | core = core_name | 105 | core = core_name |
| 105 | ); | 106 | ); |
