diff options
| author | Gustav Toft <[email protected]> | 2024-05-30 09:56:09 +0200 |
|---|---|---|
| committer | Gustav Toft <[email protected]> | 2024-05-30 09:56:09 +0200 |
| commit | d3c3670a966cd68b8d2d46a732ab971390ec3006 (patch) | |
| tree | e0815debd51e1baa5b019049e0ea1b1a286f7742 /examples | |
| parent | ab36329dce653a2ee20d32e9a5345799d9595202 (diff) | |
| parent | 50210e8cdc95c3c8bea150541cd8f15482450b1e (diff) | |
Merge branch 'main' of https://github.com/embassy-rs/embassy into fix_main
Diffstat (limited to 'examples')
172 files changed, 4257 insertions, 422 deletions
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 86f6676cb..f0a710335 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] } |
| 11 | embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } | 11 | embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } |
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 70741a0ce..2ddcbffee 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] } |
| 11 | embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", ] } | 11 | embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", ] } |
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index 1cb143820..fe1a6f5b1 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } |
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index c4ae461a5..37e362824 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } |
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index 995487cdd..52cd0b546 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } |
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index b2abc005c..0f3cbe654 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } |
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 7203e6350..3e964df9c 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } |
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index ec134f394..b154403ac 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } |
diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml index 0bdf94331..bb83ae049 100644 --- a/examples/boot/application/stm32wb-dfu/Cargo.toml +++ b/examples/boot/application/stm32wb-dfu/Cargo.toml | |||
| @@ -5,13 +5,13 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } | 12 | embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } |
| 13 | embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } | 13 | embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../../../embassy-usb" } | 14 | embassy-usb = { version = "0.2.0", path = "../../../../embassy-usb" } |
| 15 | embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] } | 15 | embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] } |
| 16 | 16 | ||
| 17 | defmt = { version = "0.3", optional = true } | 17 | defmt = { version = "0.3", optional = true } |
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index e38e9f3af..93ead617c 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } |
diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml index 3e41d1479..980149bea 100644 --- a/examples/boot/bootloader/nrf/Cargo.toml +++ b/examples/boot/bootloader/nrf/Cargo.toml | |||
| @@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true } | |||
| 12 | embassy-nrf = { path = "../../../../embassy-nrf", features = [] } | 12 | embassy-nrf = { path = "../../../../embassy-nrf", features = [] } |
| 13 | embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" } | 13 | embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" } |
| 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 15 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 15 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 16 | cortex-m-rt = { version = "0.7" } | 16 | cortex-m-rt = { version = "0.7" } |
| 17 | cfg-if = "1.0.0" | 17 | cfg-if = "1.0.0" |
| 18 | 18 | ||
diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml index 3cf61a002..7eec3df1b 100644 --- a/examples/boot/bootloader/rp/Cargo.toml +++ b/examples/boot/bootloader/rp/Cargo.toml | |||
| @@ -11,7 +11,7 @@ defmt-rtt = { version = "0.4", optional = true } | |||
| 11 | 11 | ||
| 12 | embassy-rp = { path = "../../../../embassy-rp", features = [] } | 12 | embassy-rp = { path = "../../../../embassy-rp", features = [] } |
| 13 | embassy-boot-rp = { path = "../../../../embassy-boot-rp" } | 13 | embassy-boot-rp = { path = "../../../../embassy-boot-rp" } |
| 14 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 14 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 15 | embassy-time = { path = "../../../../embassy-time", features = [] } | 15 | embassy-time = { path = "../../../../embassy-time", features = [] } |
| 16 | 16 | ||
| 17 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 17 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml index 313187adc..55adf84d7 100644 --- a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml +++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml | |||
| @@ -15,7 +15,7 @@ cortex-m = { version = "0.7.6", features = [ | |||
| 15 | "inline-asm", | 15 | "inline-asm", |
| 16 | "critical-section-single-core", | 16 | "critical-section-single-core", |
| 17 | ] } | 17 | ] } |
| 18 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 18 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 19 | cortex-m-rt = { version = "0.7" } | 19 | cortex-m-rt = { version = "0.7" } |
| 20 | embedded-storage = "0.3.1" | 20 | embedded-storage = "0.3.1" |
| 21 | embedded-storage-async = "0.4.0" | 21 | embedded-storage-async = "0.4.0" |
diff --git a/examples/boot/bootloader/stm32-dual-bank/README.md b/examples/boot/bootloader/stm32-dual-bank/README.md index 3de3171cd..cd6c0bc84 100644 --- a/examples/boot/bootloader/stm32-dual-bank/README.md +++ b/examples/boot/bootloader/stm32-dual-bank/README.md | |||
| @@ -2,16 +2,16 @@ | |||
| 2 | 2 | ||
| 3 | ## Overview | 3 | ## Overview |
| 4 | 4 | ||
| 5 | This bootloader leverages `embassy-boot` to interact with the flash. | 5 | This bootloader leverages `embassy-boot` to interact with the flash. |
| 6 | This example targets STM32 devices with dual-bank flash memory, with a primary focus on the STM32H747XI series. | 6 | This example targets STM32 devices with dual-bank flash memory, with a primary focus on the STM32H747XI series. |
| 7 | Users must modify the `memory.x` configuration file to match with the memory layout of their specific STM32 device. | 7 | Users must modify the `memory.x` configuration file to match with the memory layout of their specific STM32 device. |
| 8 | 8 | ||
| 9 | Additionally, this example can be extended to utilize external flash memory, such as QSPI, for storing partitions. | 9 | Additionally, this example can be extended to utilize external flash memory, such as QSPI, for storing partitions. |
| 10 | 10 | ||
| 11 | ## Memory Configuration | 11 | ## Memory Configuration |
| 12 | 12 | ||
| 13 | In this example's `memory.x` file, various symbols are defined to assist in effective memory management within the bootloader environment. | 13 | In this example's `memory.x` file, various symbols are defined to assist in effective memory management within the bootloader environment. |
| 14 | For dual-bank STM32 devices, it's crucial to assign these symbols correctly to their respective memory banks. | 14 | For dual-bank STM32 devices, it's crucial to assign these symbols correctly to their respective memory banks. |
| 15 | 15 | ||
| 16 | ### Symbol Definitions | 16 | ### Symbol Definitions |
| 17 | 17 | ||
diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml index 74c01b0f4..ef2b99404 100644 --- a/examples/boot/bootloader/stm32/Cargo.toml +++ b/examples/boot/bootloader/stm32/Cargo.toml | |||
| @@ -12,7 +12,7 @@ defmt-rtt = { version = "0.4", optional = true } | |||
| 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } | 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } |
| 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } | 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } |
| 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 15 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 15 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 16 | cortex-m-rt = { version = "0.7" } | 16 | cortex-m-rt = { version = "0.7" } |
| 17 | embedded-storage = "0.3.1" | 17 | embedded-storage = "0.3.1" |
| 18 | embedded-storage-async = "0.4.0" | 18 | embedded-storage-async = "0.4.0" |
diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml index 854f94d85..93b5d8b34 100644 --- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml +++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml | |||
| @@ -12,13 +12,13 @@ defmt-rtt = { version = "0.4", optional = true } | |||
| 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } | 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } |
| 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } | 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } |
| 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 15 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 15 | embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } |
| 16 | cortex-m-rt = { version = "0.7" } | 16 | cortex-m-rt = { version = "0.7" } |
| 17 | embedded-storage = "0.3.1" | 17 | embedded-storage = "0.3.1" |
| 18 | embedded-storage-async = "0.4.0" | 18 | embedded-storage-async = "0.4.0" |
| 19 | cfg-if = "1.0.0" | 19 | cfg-if = "1.0.0" |
| 20 | embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] } | 20 | embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] } |
| 21 | embassy-usb = { version = "0.1.0", path = "../../../../embassy-usb", default-features = false } | 21 | embassy-usb = { version = "0.2.0", path = "../../../../embassy-usb", default-features = false } |
| 22 | embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" } | 22 | embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" } |
| 23 | 23 | ||
| 24 | [features] | 24 | [features] |
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index 17210994b..147bb40dc 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml | |||
| @@ -15,7 +15,7 @@ log = [ | |||
| 15 | ] | 15 | ] |
| 16 | 16 | ||
| 17 | [dependencies] | 17 | [dependencies] |
| 18 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } | 18 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync" } |
| 19 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "integrated-timers"] } | 19 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "integrated-timers"] } |
| 20 | embassy-time = { version = "0.3.0", path = "../../embassy-time" } | 20 | embassy-time = { version = "0.3.0", path = "../../embassy-time" } |
| 21 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 21 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| @@ -23,7 +23,6 @@ embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf5 | |||
| 23 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 23 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 24 | cortex-m-rt = "0.7.0" | 24 | cortex-m-rt = "0.7.0" |
| 25 | panic-probe = { version = "0.3" } | 25 | panic-probe = { version = "0.3" } |
| 26 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 27 | rand = { version = "0.8.4", default-features = false } | 26 | rand = { version = "0.8.4", default-features = false } |
| 28 | serde = { version = "1.0.136", default-features = false } | 27 | serde = { version = "1.0.136", default-features = false } |
| 29 | rtos-trace = "0.1.3" | 28 | rtos-trace = "0.1.3" |
diff --git a/examples/nrf52810/.cargo/config.toml b/examples/nrf52810/.cargo/config.toml new file mode 100644 index 000000000..917a5364a --- /dev/null +++ b/examples/nrf52810/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace nRF82810_xxAA with your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --chip nRF52810_xxAA" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace" | ||
diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml new file mode 100644 index 000000000..faec9a263 --- /dev/null +++ b/examples/nrf52810/Cargo.toml | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf52810-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 9 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } | ||
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
| 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | ||
| 13 | |||
| 14 | defmt = "0.3" | ||
| 15 | defmt-rtt = "0.4" | ||
| 16 | |||
| 17 | fixed = "1.10.0" | ||
| 18 | static_cell = { version = "2" } | ||
| 19 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 20 | cortex-m-rt = "0.7.0" | ||
| 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 22 | |||
| 23 | [profile.release] | ||
| 24 | debug = 2 | ||
diff --git a/examples/nrf52810/build.rs b/examples/nrf52810/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/nrf52810/build.rs | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | //! This build script copies the `memory.x` file from the crate root into | ||
| 2 | //! a directory where the linker can always find it at build time. | ||
| 3 | //! For many projects this is optional, as the linker always searches the | ||
| 4 | //! project root directory -- wherever `Cargo.toml` is. However, if you | ||
| 5 | //! are using a workspace or have a more complicated build setup, this | ||
| 6 | //! build script becomes required. Additionally, by requesting that | ||
| 7 | //! Cargo re-run the build script whenever `memory.x` is changed, | ||
| 8 | //! updating `memory.x` ensures a rebuild of the application with the | ||
| 9 | //! new memory settings. | ||
| 10 | |||
| 11 | use std::env; | ||
| 12 | use std::fs::File; | ||
| 13 | use std::io::Write; | ||
| 14 | use std::path::PathBuf; | ||
| 15 | |||
| 16 | fn main() { | ||
| 17 | // Put `memory.x` in our output directory and ensure it's | ||
| 18 | // on the linker search path. | ||
| 19 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
| 20 | File::create(out.join("memory.x")) | ||
| 21 | .unwrap() | ||
| 22 | .write_all(include_bytes!("memory.x")) | ||
| 23 | .unwrap(); | ||
| 24 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 25 | |||
| 26 | // By default, Cargo will re-run a build script whenever | ||
| 27 | // any file in the project changes. By specifying `memory.x` | ||
| 28 | // here, we ensure the build script is only re-run when | ||
| 29 | // `memory.x` is changed. | ||
| 30 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 31 | |||
| 32 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 33 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 34 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 35 | } | ||
diff --git a/examples/nrf52810/memory.x b/examples/nrf52810/memory.x new file mode 100644 index 000000000..7cf560e44 --- /dev/null +++ b/examples/nrf52810/memory.x | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | ||
| 4 | FLASH : ORIGIN = 0x00000000, LENGTH = 256K | ||
| 5 | RAM : ORIGIN = 0x20000000, LENGTH = 24K | ||
| 6 | |||
| 7 | } | ||
diff --git a/examples/nrf52810/src/bin/blinky.rs b/examples/nrf52810/src/bin/blinky.rs new file mode 100644 index 000000000..1da039f7d --- /dev/null +++ b/examples/nrf52810/src/bin/blinky.rs | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 6 | use embassy_time::Timer; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[embassy_executor::main] | ||
| 10 | async fn main(_spawner: Spawner) { | ||
| 11 | let p = embassy_nrf::init(Default::default()); | ||
| 12 | let mut led = Output::new(p.P0_18, Level::Low, OutputDrive::Standard); | ||
| 13 | |||
| 14 | loop { | ||
| 15 | led.set_high(); | ||
| 16 | Timer::after_millis(300).await; | ||
| 17 | led.set_low(); | ||
| 18 | Timer::after_millis(300).await; | ||
| 19 | } | ||
| 20 | } | ||
diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml index d91f58d0e..041c779a5 100644 --- a/examples/nrf52840-rtic/Cargo.toml +++ b/examples/nrf52840-rtic/Cargo.toml | |||
| @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" | |||
| 8 | rtic = { version = "2", features = ["thumbv7-backend"] } | 8 | rtic = { version = "2", features = ["thumbv7-backend"] } |
| 9 | 9 | ||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 11 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "generic-queue"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "generic-queue"] } |
| 13 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 13 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 14 | 14 | ||
| @@ -18,7 +18,6 @@ defmt-rtt = "0.4" | |||
| 18 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 18 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 19 | cortex-m-rt = "0.7.0" | 19 | cortex-m-rt = "0.7.0" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 21 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 22 | 21 | ||
| 23 | [profile.release] | 22 | [profile.release] |
| 24 | debug = 2 | 23 | debug = 2 |
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 4ab5c7b7c..79d9e4e1a 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml | |||
| @@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 9 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 9 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 14 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 15 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | 15 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } |
| 16 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 16 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } |
| 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } |
| @@ -25,7 +25,6 @@ static_cell = { version = "2" } | |||
| 25 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 25 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 26 | cortex-m-rt = "0.7.0" | 26 | cortex-m-rt = "0.7.0" |
| 27 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 27 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 28 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 29 | rand = { version = "0.8.4", default-features = false } | 28 | rand = { version = "0.8.4", default-features = false } |
| 30 | embedded-storage = "0.3.1" | 29 | embedded-storage = "0.3.1" |
| 31 | usbd-hid = "0.7.0" | 30 | usbd-hid = "0.7.0" |
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs index e254d613d..dcfe7723a 100644 --- a/examples/nrf52840/src/bin/gpiote_channel.rs +++ b/examples/nrf52840/src/bin/gpiote_channel.rs | |||
| @@ -61,5 +61,5 @@ async fn main(_spawner: Spawner) { | |||
| 61 | } | 61 | } |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | futures::join!(button1, button2, button3, button4); | 64 | embassy_futures::join::join4(button1, button2, button3, button4).await; |
| 65 | } | 65 | } |
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs index 52f081487..e33ee5866 100644 --- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs | |||
| @@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) { | |||
| 54 | let mut bos_descriptor = [0; 256]; | 54 | let mut bos_descriptor = [0; 256]; |
| 55 | let mut msos_descriptor = [0; 256]; | 55 | let mut msos_descriptor = [0; 256]; |
| 56 | let mut control_buf = [0; 64]; | 56 | let mut control_buf = [0; 64]; |
| 57 | let request_handler = MyRequestHandler {}; | 57 | let mut request_handler = MyRequestHandler {}; |
| 58 | let mut device_handler = MyDeviceHandler::new(); | 58 | let mut device_handler = MyDeviceHandler::new(); |
| 59 | 59 | ||
| 60 | let mut state = State::new(); | 60 | let mut state = State::new(); |
| @@ -73,7 +73,7 @@ async fn main(_spawner: Spawner) { | |||
| 73 | // Create classes on the builder. | 73 | // Create classes on the builder. |
| 74 | let config = embassy_usb::class::hid::Config { | 74 | let config = embassy_usb::class::hid::Config { |
| 75 | report_descriptor: KeyboardReport::desc(), | 75 | report_descriptor: KeyboardReport::desc(), |
| 76 | request_handler: Some(&request_handler), | 76 | request_handler: None, |
| 77 | poll_ms: 60, | 77 | poll_ms: 60, |
| 78 | max_packet_size: 64, | 78 | max_packet_size: 64, |
| 79 | }; | 79 | }; |
| @@ -137,7 +137,7 @@ async fn main(_spawner: Spawner) { | |||
| 137 | }; | 137 | }; |
| 138 | 138 | ||
| 139 | let out_fut = async { | 139 | let out_fut = async { |
| 140 | reader.run(false, &request_handler).await; | 140 | reader.run(false, &mut request_handler).await; |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| 143 | // Run everything concurrently. | 143 | // Run everything concurrently. |
| @@ -148,21 +148,21 @@ async fn main(_spawner: Spawner) { | |||
| 148 | struct MyRequestHandler {} | 148 | struct MyRequestHandler {} |
| 149 | 149 | ||
| 150 | impl RequestHandler for MyRequestHandler { | 150 | impl RequestHandler for MyRequestHandler { |
| 151 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 151 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 152 | info!("Get report for {:?}", id); | 152 | info!("Get report for {:?}", id); |
| 153 | None | 153 | None |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 156 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 157 | info!("Set report for {:?}: {=[u8]}", id, data); | 157 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 158 | OutResponse::Accepted | 158 | OutResponse::Accepted |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 161 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 162 | info!("Set idle rate for {:?} to {:?}", id, dur); | 162 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 165 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 166 | info!("Get idle rate for {:?}", id); | 166 | info!("Get idle rate for {:?}", id); |
| 167 | None | 167 | None |
| 168 | } | 168 | } |
diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index 5d2837793..8076ac283 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs | |||
| @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { | |||
| 47 | let mut bos_descriptor = [0; 256]; | 47 | let mut bos_descriptor = [0; 256]; |
| 48 | let mut msos_descriptor = [0; 256]; | 48 | let mut msos_descriptor = [0; 256]; |
| 49 | let mut control_buf = [0; 64]; | 49 | let mut control_buf = [0; 64]; |
| 50 | let request_handler = MyRequestHandler {}; | 50 | let mut request_handler = MyRequestHandler {}; |
| 51 | 51 | ||
| 52 | let mut state = State::new(); | 52 | let mut state = State::new(); |
| 53 | 53 | ||
| @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { | |||
| 63 | // Create classes on the builder. | 63 | // Create classes on the builder. |
| 64 | let config = embassy_usb::class::hid::Config { | 64 | let config = embassy_usb::class::hid::Config { |
| 65 | report_descriptor: MouseReport::desc(), | 65 | report_descriptor: MouseReport::desc(), |
| 66 | request_handler: Some(&request_handler), | 66 | request_handler: Some(&mut request_handler), |
| 67 | poll_ms: 60, | 67 | poll_ms: 60, |
| 68 | max_packet_size: 8, | 68 | max_packet_size: 8, |
| 69 | }; | 69 | }; |
| @@ -105,21 +105,21 @@ async fn main(_spawner: Spawner) { | |||
| 105 | struct MyRequestHandler {} | 105 | struct MyRequestHandler {} |
| 106 | 106 | ||
| 107 | impl RequestHandler for MyRequestHandler { | 107 | impl RequestHandler for MyRequestHandler { |
| 108 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 108 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 109 | info!("Get report for {:?}", id); | 109 | info!("Get report for {:?}", id); |
| 110 | None | 110 | None |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 113 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 114 | info!("Set report for {:?}: {=[u8]}", id, data); | 114 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 115 | OutResponse::Accepted | 115 | OutResponse::Accepted |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 118 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 119 | info!("Set idle rate for {:?} to {:?}", id, dur); | 119 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 122 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 123 | info!("Get idle rate for {:?}", id); | 123 | info!("Get idle rate for {:?}", id); |
| 124 | None | 124 | None |
| 125 | } | 125 | } |
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 24aa560d5..e560a3dbb 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml | |||
| @@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 9 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 9 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 14 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 15 | embedded-io-async = { version = "0.6.1" } | 15 | embedded-io-async = { version = "0.6.1" } |
| 16 | 16 | ||
| 17 | defmt = "0.3" | 17 | defmt = "0.3" |
| @@ -21,7 +21,6 @@ static_cell = "2" | |||
| 21 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 21 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 22 | cortex-m-rt = "0.7.0" | 22 | cortex-m-rt = "0.7.0" |
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 25 | rand = { version = "0.8.4", default-features = false } | 24 | rand = { version = "0.8.4", default-features = false } |
| 26 | embedded-storage = "0.3.1" | 25 | embedded-storage = "0.3.1" |
| 27 | usbd-hid = "0.7.0" | 26 | usbd-hid = "0.7.0" |
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs index c0a55142f..23f6fca98 100644 --- a/examples/nrf5340/src/bin/gpiote_channel.rs +++ b/examples/nrf5340/src/bin/gpiote_channel.rs | |||
| @@ -61,5 +61,5 @@ async fn main(_spawner: Spawner) { | |||
| 61 | } | 61 | } |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | futures::join!(button1, button2, button3, button4); | 64 | embassy_futures::join::join4(button1, button2, button3, button4).await; |
| 65 | } | 65 | } |
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 0f58f143c..726df29cb 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml | |||
| @@ -7,15 +7,15 @@ license = "MIT OR Apache-2.0" | |||
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } | 9 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] } | 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 14 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 15 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet"] } | 15 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet"] } |
| 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } | 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } |
| 17 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 17 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 18 | embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } | 18 | embassy-usb-logger = { version = "0.2.0", path = "../../embassy-usb-logger" } |
| 19 | cyw43 = { version = "0.1.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } | 19 | cyw43 = { version = "0.1.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] } |
| 20 | cyw43-pio = { version = "0.1.0", path = "../../cyw43-pio", features = ["defmt", "overclock"] } | 20 | cyw43-pio = { version = "0.1.0", path = "../../cyw43-pio", features = ["defmt", "overclock"] } |
| 21 | 21 | ||
| @@ -27,8 +27,8 @@ fixed-macro = "1.2" | |||
| 27 | #cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | 27 | #cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } |
| 28 | cortex-m = { version = "0.7.6", features = ["inline-asm"] } | 28 | cortex-m = { version = "0.7.6", features = ["inline-asm"] } |
| 29 | cortex-m-rt = "0.7.0" | 29 | cortex-m-rt = "0.7.0" |
| 30 | critical-section = "1.1" | ||
| 30 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 31 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 31 | futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] } | ||
| 32 | display-interface-spi = "0.4.1" | 32 | display-interface-spi = "0.4.1" |
| 33 | embedded-graphics = "0.7.1" | 33 | embedded-graphics = "0.7.1" |
| 34 | st7789 = "0.6.1" | 34 | st7789 = "0.6.1" |
| @@ -49,6 +49,7 @@ log = "0.4" | |||
| 49 | pio-proc = "0.2" | 49 | pio-proc = "0.2" |
| 50 | pio = "0.2.1" | 50 | pio = "0.2.1" |
| 51 | rand = { version = "0.8.5", default-features = false } | 51 | rand = { version = "0.8.5", default-features = false } |
| 52 | embedded-sdmmc = "0.7.0" | ||
| 52 | 53 | ||
| 53 | [profile.release] | 54 | [profile.release] |
| 54 | debug = 2 | 55 | debug = 2 |
diff --git a/examples/rp/src/bin/interrupt.rs b/examples/rp/src/bin/interrupt.rs new file mode 100644 index 000000000..5b9d7027e --- /dev/null +++ b/examples/rp/src/bin/interrupt.rs | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | //! This example shows how you can use raw interrupt handlers alongside embassy. | ||
| 2 | //! The example also showcases some of the options available for sharing resources/data. | ||
| 3 | //! | ||
| 4 | //! In the example, an ADC reading is triggered every time the PWM wraps around. | ||
| 5 | //! The sample data is sent down a channel, to be processed inside a low priority task. | ||
| 6 | //! The processed data is then used to adjust the PWM duty cycle, once every second. | ||
| 7 | |||
| 8 | #![no_std] | ||
| 9 | #![no_main] | ||
| 10 | |||
| 11 | use core::cell::{Cell, RefCell}; | ||
| 12 | |||
| 13 | use defmt::*; | ||
| 14 | use embassy_executor::Spawner; | ||
| 15 | use embassy_rp::adc::{self, Adc, Blocking}; | ||
| 16 | use embassy_rp::gpio::Pull; | ||
| 17 | use embassy_rp::interrupt; | ||
| 18 | use embassy_rp::pwm::{Config, Pwm}; | ||
| 19 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 20 | use embassy_sync::blocking_mutex::Mutex; | ||
| 21 | use embassy_sync::channel::Channel; | ||
| 22 | use embassy_time::{Duration, Ticker}; | ||
| 23 | use portable_atomic::{AtomicU32, Ordering}; | ||
| 24 | use static_cell::StaticCell; | ||
| 25 | use {defmt_rtt as _, panic_probe as _}; | ||
| 26 | |||
| 27 | static COUNTER: AtomicU32 = AtomicU32::new(0); | ||
| 28 | static PWM: Mutex<CriticalSectionRawMutex, RefCell<Option<Pwm>>> = Mutex::new(RefCell::new(None)); | ||
| 29 | static ADC: Mutex<CriticalSectionRawMutex, RefCell<Option<(Adc<Blocking>, adc::Channel)>>> = | ||
| 30 | Mutex::new(RefCell::new(None)); | ||
| 31 | static ADC_VALUES: Channel<CriticalSectionRawMutex, u16, 2048> = Channel::new(); | ||
| 32 | |||
| 33 | #[embassy_executor::main] | ||
| 34 | async fn main(spawner: Spawner) { | ||
| 35 | embassy_rp::pac::SIO.spinlock(31).write_value(1); | ||
| 36 | let p = embassy_rp::init(Default::default()); | ||
| 37 | |||
| 38 | let adc = Adc::new_blocking(p.ADC, Default::default()); | ||
| 39 | let p26 = adc::Channel::new_pin(p.PIN_26, Pull::None); | ||
| 40 | ADC.lock(|a| a.borrow_mut().replace((adc, p26))); | ||
| 41 | |||
| 42 | let pwm = Pwm::new_output_b(p.PWM_SLICE4, p.PIN_25, Default::default()); | ||
| 43 | PWM.lock(|p| p.borrow_mut().replace(pwm)); | ||
| 44 | |||
| 45 | // Enable the interrupt for pwm slice 4 | ||
| 46 | embassy_rp::pac::PWM.inte().modify(|w| w.set_ch4(true)); | ||
| 47 | unsafe { | ||
| 48 | cortex_m::peripheral::NVIC::unmask(interrupt::PWM_IRQ_WRAP); | ||
| 49 | } | ||
| 50 | |||
| 51 | // Tasks require their resources to have 'static lifetime | ||
| 52 | // No Mutex needed when sharing within the same executor/prio level | ||
| 53 | static AVG: StaticCell<Cell<u32>> = StaticCell::new(); | ||
| 54 | let avg = AVG.init(Default::default()); | ||
| 55 | spawner.must_spawn(processing(avg)); | ||
| 56 | |||
| 57 | let mut ticker = Ticker::every(Duration::from_secs(1)); | ||
| 58 | loop { | ||
| 59 | ticker.next().await; | ||
| 60 | let freq = COUNTER.swap(0, Ordering::Relaxed); | ||
| 61 | info!("pwm freq: {:?} Hz", freq); | ||
| 62 | info!("adc average: {:?}", avg.get()); | ||
| 63 | |||
| 64 | // Update the pwm duty cycle, based on the averaged adc reading | ||
| 65 | let mut config = Config::default(); | ||
| 66 | config.compare_b = ((avg.get() as f32 / 4095.0) * config.top as f32) as _; | ||
| 67 | PWM.lock(|p| p.borrow_mut().as_mut().unwrap().set_config(&config)); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | #[embassy_executor::task] | ||
| 72 | async fn processing(avg: &'static Cell<u32>) { | ||
| 73 | let mut buffer: heapless::HistoryBuffer<u16, 100> = Default::default(); | ||
| 74 | loop { | ||
| 75 | let val = ADC_VALUES.receive().await; | ||
| 76 | buffer.write(val); | ||
| 77 | let sum: u32 = buffer.iter().map(|x| *x as u32).sum(); | ||
| 78 | avg.set(sum / buffer.len() as u32); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | #[interrupt] | ||
| 83 | fn PWM_IRQ_WRAP() { | ||
| 84 | critical_section::with(|cs| { | ||
| 85 | let mut adc = ADC.borrow(cs).borrow_mut(); | ||
| 86 | let (adc, p26) = adc.as_mut().unwrap(); | ||
| 87 | let val = adc.blocking_read(p26).unwrap(); | ||
| 88 | ADC_VALUES.try_send(val).ok(); | ||
| 89 | |||
| 90 | // Clear the interrupt, so we don't immediately re-enter this irq handler | ||
| 91 | PWM.borrow(cs).borrow_mut().as_mut().unwrap().clear_wrapped(); | ||
| 92 | }); | ||
| 93 | COUNTER.fetch_add(1, Ordering::Relaxed); | ||
| 94 | } | ||
diff --git a/examples/rp/src/bin/pio_pwm.rs b/examples/rp/src/bin/pio_pwm.rs new file mode 100644 index 000000000..23d63d435 --- /dev/null +++ b/examples/rp/src/bin/pio_pwm.rs | |||
| @@ -0,0 +1,118 @@ | |||
| 1 | //! This example shows how to create a pwm using the PIO module in the RP2040 chip. | ||
| 2 | |||
| 3 | #![no_std] | ||
| 4 | #![no_main] | ||
| 5 | use core::time::Duration; | ||
| 6 | |||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_rp::gpio::Level; | ||
| 9 | use embassy_rp::peripherals::PIO0; | ||
| 10 | use embassy_rp::pio::{Common, Config, Direction, Instance, InterruptHandler, Pio, PioPin, StateMachine}; | ||
| 11 | use embassy_rp::{bind_interrupts, clocks}; | ||
| 12 | use embassy_time::Timer; | ||
| 13 | use pio::InstructionOperands; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | const REFRESH_INTERVAL: u64 = 20000; | ||
| 17 | |||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 20 | }); | ||
| 21 | |||
| 22 | pub fn to_pio_cycles(duration: Duration) -> u32 { | ||
| 23 | (clocks::clk_sys_freq() / 1_000_000) / 3 * duration.as_micros() as u32 // parentheses are required to prevent overflow | ||
| 24 | } | ||
| 25 | |||
| 26 | pub struct PwmPio<'d, T: Instance, const SM: usize> { | ||
| 27 | sm: StateMachine<'d, T, SM>, | ||
| 28 | } | ||
| 29 | |||
| 30 | impl<'d, T: Instance, const SM: usize> PwmPio<'d, T, SM> { | ||
| 31 | pub fn new(pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, pin: impl PioPin) -> Self { | ||
| 32 | let prg = pio_proc::pio_asm!( | ||
| 33 | ".side_set 1 opt" | ||
| 34 | "pull noblock side 0" | ||
| 35 | "mov x, osr" | ||
| 36 | "mov y, isr" | ||
| 37 | "countloop:" | ||
| 38 | "jmp x!=y noset" | ||
| 39 | "jmp skip side 1" | ||
| 40 | "noset:" | ||
| 41 | "nop" | ||
| 42 | "skip:" | ||
| 43 | "jmp y-- countloop" | ||
| 44 | ); | ||
| 45 | |||
| 46 | pio.load_program(&prg.program); | ||
| 47 | let pin = pio.make_pio_pin(pin); | ||
| 48 | sm.set_pins(Level::High, &[&pin]); | ||
| 49 | sm.set_pin_dirs(Direction::Out, &[&pin]); | ||
| 50 | |||
| 51 | let mut cfg = Config::default(); | ||
| 52 | cfg.use_program(&pio.load_program(&prg.program), &[&pin]); | ||
| 53 | |||
| 54 | sm.set_config(&cfg); | ||
| 55 | |||
| 56 | Self { sm } | ||
| 57 | } | ||
| 58 | |||
| 59 | pub fn start(&mut self) { | ||
| 60 | self.sm.set_enable(true); | ||
| 61 | } | ||
| 62 | |||
| 63 | pub fn stop(&mut self) { | ||
| 64 | self.sm.set_enable(false); | ||
| 65 | } | ||
| 66 | |||
| 67 | pub fn set_period(&mut self, duration: Duration) { | ||
| 68 | let is_enabled = self.sm.is_enabled(); | ||
| 69 | while !self.sm.tx().empty() {} // Make sure that the queue is empty | ||
| 70 | self.sm.set_enable(false); | ||
| 71 | self.sm.tx().push(to_pio_cycles(duration)); | ||
| 72 | unsafe { | ||
| 73 | self.sm.exec_instr( | ||
| 74 | InstructionOperands::PULL { | ||
| 75 | if_empty: false, | ||
| 76 | block: false, | ||
| 77 | } | ||
| 78 | .encode(), | ||
| 79 | ); | ||
| 80 | self.sm.exec_instr( | ||
| 81 | InstructionOperands::OUT { | ||
| 82 | destination: ::pio::OutDestination::ISR, | ||
| 83 | bit_count: 32, | ||
| 84 | } | ||
| 85 | .encode(), | ||
| 86 | ); | ||
| 87 | }; | ||
| 88 | if is_enabled { | ||
| 89 | self.sm.set_enable(true) // Enable if previously enabled | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | pub fn set_level(&mut self, level: u32) { | ||
| 94 | self.sm.tx().push(level); | ||
| 95 | } | ||
| 96 | |||
| 97 | pub fn write(&mut self, duration: Duration) { | ||
| 98 | self.set_level(to_pio_cycles(duration)); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | #[embassy_executor::main] | ||
| 103 | async fn main(_spawner: Spawner) { | ||
| 104 | let p = embassy_rp::init(Default::default()); | ||
| 105 | let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs); | ||
| 106 | |||
| 107 | // Note that PIN_25 is the led pin on the Pico | ||
| 108 | let mut pwm_pio = PwmPio::new(&mut common, sm0, p.PIN_25); | ||
| 109 | pwm_pio.set_period(Duration::from_micros(REFRESH_INTERVAL)); | ||
| 110 | pwm_pio.start(); | ||
| 111 | |||
| 112 | let mut duration = 0; | ||
| 113 | loop { | ||
| 114 | duration = (duration + 1) % 1000; | ||
| 115 | pwm_pio.write(Duration::from_micros(duration)); | ||
| 116 | Timer::after_millis(1).await; | ||
| 117 | } | ||
| 118 | } | ||
diff --git a/examples/rp/src/bin/pio_servo.rs b/examples/rp/src/bin/pio_servo.rs new file mode 100644 index 000000000..a79540479 --- /dev/null +++ b/examples/rp/src/bin/pio_servo.rs | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | //! This example shows how to create a pwm using the PIO module in the RP2040 chip. | ||
| 2 | |||
| 3 | #![no_std] | ||
| 4 | #![no_main] | ||
| 5 | use core::time::Duration; | ||
| 6 | |||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_rp::gpio::Level; | ||
| 9 | use embassy_rp::peripherals::PIO0; | ||
| 10 | use embassy_rp::pio::{Common, Config, Direction, Instance, InterruptHandler, Pio, PioPin, StateMachine}; | ||
| 11 | use embassy_rp::{bind_interrupts, clocks}; | ||
| 12 | use embassy_time::Timer; | ||
| 13 | use pio::InstructionOperands; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | const DEFAULT_MIN_PULSE_WIDTH: u64 = 1000; // uncalibrated default, the shortest duty cycle sent to a servo | ||
| 17 | const DEFAULT_MAX_PULSE_WIDTH: u64 = 2000; // uncalibrated default, the longest duty cycle sent to a servo | ||
| 18 | const DEFAULT_MAX_DEGREE_ROTATION: u64 = 160; // 160 degrees is typical | ||
| 19 | const REFRESH_INTERVAL: u64 = 20000; // The period of each cycle | ||
| 20 | |||
| 21 | bind_interrupts!(struct Irqs { | ||
| 22 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 23 | }); | ||
| 24 | |||
| 25 | pub fn to_pio_cycles(duration: Duration) -> u32 { | ||
| 26 | (clocks::clk_sys_freq() / 1_000_000) / 3 * duration.as_micros() as u32 // parentheses are required to prevent overflow | ||
| 27 | } | ||
| 28 | |||
| 29 | pub struct PwmPio<'d, T: Instance, const SM: usize> { | ||
| 30 | sm: StateMachine<'d, T, SM>, | ||
| 31 | } | ||
| 32 | |||
| 33 | impl<'d, T: Instance, const SM: usize> PwmPio<'d, T, SM> { | ||
| 34 | pub fn new(pio: &mut Common<'d, T>, mut sm: StateMachine<'d, T, SM>, pin: impl PioPin) -> Self { | ||
| 35 | let prg = pio_proc::pio_asm!( | ||
| 36 | ".side_set 1 opt" | ||
| 37 | "pull noblock side 0" | ||
| 38 | "mov x, osr" | ||
| 39 | "mov y, isr" | ||
| 40 | "countloop:" | ||
| 41 | "jmp x!=y noset" | ||
| 42 | "jmp skip side 1" | ||
| 43 | "noset:" | ||
| 44 | "nop" | ||
| 45 | "skip:" | ||
| 46 | "jmp y-- countloop" | ||
| 47 | ); | ||
| 48 | |||
| 49 | pio.load_program(&prg.program); | ||
| 50 | let pin = pio.make_pio_pin(pin); | ||
| 51 | sm.set_pins(Level::High, &[&pin]); | ||
| 52 | sm.set_pin_dirs(Direction::Out, &[&pin]); | ||
| 53 | |||
| 54 | let mut cfg = Config::default(); | ||
| 55 | cfg.use_program(&pio.load_program(&prg.program), &[&pin]); | ||
| 56 | |||
| 57 | sm.set_config(&cfg); | ||
| 58 | |||
| 59 | Self { sm } | ||
| 60 | } | ||
| 61 | |||
| 62 | pub fn start(&mut self) { | ||
| 63 | self.sm.set_enable(true); | ||
| 64 | } | ||
| 65 | |||
| 66 | pub fn stop(&mut self) { | ||
| 67 | self.sm.set_enable(false); | ||
| 68 | } | ||
| 69 | |||
| 70 | pub fn set_period(&mut self, duration: Duration) { | ||
| 71 | let is_enabled = self.sm.is_enabled(); | ||
| 72 | while !self.sm.tx().empty() {} // Make sure that the queue is empty | ||
| 73 | self.sm.set_enable(false); | ||
| 74 | self.sm.tx().push(to_pio_cycles(duration)); | ||
| 75 | unsafe { | ||
| 76 | self.sm.exec_instr( | ||
| 77 | InstructionOperands::PULL { | ||
| 78 | if_empty: false, | ||
| 79 | block: false, | ||
| 80 | } | ||
| 81 | .encode(), | ||
| 82 | ); | ||
| 83 | self.sm.exec_instr( | ||
| 84 | InstructionOperands::OUT { | ||
| 85 | destination: ::pio::OutDestination::ISR, | ||
| 86 | bit_count: 32, | ||
| 87 | } | ||
| 88 | .encode(), | ||
| 89 | ); | ||
| 90 | }; | ||
| 91 | if is_enabled { | ||
| 92 | self.sm.set_enable(true) // Enable if previously enabled | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | pub fn set_level(&mut self, level: u32) { | ||
| 97 | self.sm.tx().push(level); | ||
| 98 | } | ||
| 99 | |||
| 100 | pub fn write(&mut self, duration: Duration) { | ||
| 101 | self.set_level(to_pio_cycles(duration)); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | pub struct ServoBuilder<'d, T: Instance, const SM: usize> { | ||
| 106 | pwm: PwmPio<'d, T, SM>, | ||
| 107 | period: Duration, | ||
| 108 | min_pulse_width: Duration, | ||
| 109 | max_pulse_width: Duration, | ||
| 110 | max_degree_rotation: u64, | ||
| 111 | } | ||
| 112 | |||
| 113 | impl<'d, T: Instance, const SM: usize> ServoBuilder<'d, T, SM> { | ||
| 114 | pub fn new(pwm: PwmPio<'d, T, SM>) -> Self { | ||
| 115 | Self { | ||
| 116 | pwm, | ||
| 117 | period: Duration::from_micros(REFRESH_INTERVAL), | ||
| 118 | min_pulse_width: Duration::from_micros(DEFAULT_MIN_PULSE_WIDTH), | ||
| 119 | max_pulse_width: Duration::from_micros(DEFAULT_MAX_PULSE_WIDTH), | ||
| 120 | max_degree_rotation: DEFAULT_MAX_DEGREE_ROTATION, | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | pub fn set_period(mut self, duration: Duration) -> Self { | ||
| 125 | self.period = duration; | ||
| 126 | self | ||
| 127 | } | ||
| 128 | |||
| 129 | pub fn set_min_pulse_width(mut self, duration: Duration) -> Self { | ||
| 130 | self.min_pulse_width = duration; | ||
| 131 | self | ||
| 132 | } | ||
| 133 | |||
| 134 | pub fn set_max_pulse_width(mut self, duration: Duration) -> Self { | ||
| 135 | self.max_pulse_width = duration; | ||
| 136 | self | ||
| 137 | } | ||
| 138 | |||
| 139 | pub fn set_max_degree_rotation(mut self, degree: u64) -> Self { | ||
| 140 | self.max_degree_rotation = degree; | ||
| 141 | self | ||
| 142 | } | ||
| 143 | |||
| 144 | pub fn build(mut self) -> Servo<'d, T, SM> { | ||
| 145 | self.pwm.set_period(self.period); | ||
| 146 | Servo { | ||
| 147 | pwm: self.pwm, | ||
| 148 | min_pulse_width: self.min_pulse_width, | ||
| 149 | max_pulse_width: self.max_pulse_width, | ||
| 150 | max_degree_rotation: self.max_degree_rotation, | ||
| 151 | } | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | pub struct Servo<'d, T: Instance, const SM: usize> { | ||
| 156 | pwm: PwmPio<'d, T, SM>, | ||
| 157 | min_pulse_width: Duration, | ||
| 158 | max_pulse_width: Duration, | ||
| 159 | max_degree_rotation: u64, | ||
| 160 | } | ||
| 161 | |||
| 162 | impl<'d, T: Instance, const SM: usize> Servo<'d, T, SM> { | ||
| 163 | pub fn start(&mut self) { | ||
| 164 | self.pwm.start(); | ||
| 165 | } | ||
| 166 | |||
| 167 | pub fn stop(&mut self) { | ||
| 168 | self.pwm.stop(); | ||
| 169 | } | ||
| 170 | |||
| 171 | pub fn write_time(&mut self, duration: Duration) { | ||
| 172 | self.pwm.write(duration); | ||
| 173 | } | ||
| 174 | |||
| 175 | pub fn rotate(&mut self, degree: u64) { | ||
| 176 | let degree_per_nano_second = (self.max_pulse_width.as_nanos() as u64 - self.min_pulse_width.as_nanos() as u64) | ||
| 177 | / self.max_degree_rotation; | ||
| 178 | let mut duration = | ||
| 179 | Duration::from_nanos(degree * degree_per_nano_second + self.min_pulse_width.as_nanos() as u64); | ||
| 180 | if self.max_pulse_width < duration { | ||
| 181 | duration = self.max_pulse_width; | ||
| 182 | } | ||
| 183 | |||
| 184 | self.pwm.write(duration); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | #[embassy_executor::main] | ||
| 189 | async fn main(_spawner: Spawner) { | ||
| 190 | let p = embassy_rp::init(Default::default()); | ||
| 191 | let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs); | ||
| 192 | |||
| 193 | let pwm_pio = PwmPio::new(&mut common, sm0, p.PIN_1); | ||
| 194 | let mut servo = ServoBuilder::new(pwm_pio) | ||
| 195 | .set_max_degree_rotation(120) // Example of adjusting values for MG996R servo | ||
| 196 | .set_min_pulse_width(Duration::from_micros(350)) // This value was detemined by a rough experiment. | ||
| 197 | .set_max_pulse_width(Duration::from_micros(2600)) // Along with this value. | ||
| 198 | .build(); | ||
| 199 | |||
| 200 | servo.start(); | ||
| 201 | |||
| 202 | let mut degree = 0; | ||
| 203 | loop { | ||
| 204 | degree = (degree + 1) % 120; | ||
| 205 | servo.rotate(degree); | ||
| 206 | Timer::after_millis(50).await; | ||
| 207 | } | ||
| 208 | } | ||
diff --git a/examples/rp/src/bin/spi_sdmmc.rs b/examples/rp/src/bin/spi_sdmmc.rs new file mode 100644 index 000000000..4cbc82f7b --- /dev/null +++ b/examples/rp/src/bin/spi_sdmmc.rs | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | //! This example shows how to use `embedded-sdmmc` with the RP2040 chip, over SPI. | ||
| 2 | //! | ||
| 3 | //! The example will attempt to read a file `MY_FILE.TXT` from the root directory | ||
| 4 | //! of the SD card and print its contents. | ||
| 5 | |||
| 6 | #![no_std] | ||
| 7 | #![no_main] | ||
| 8 | |||
| 9 | use defmt::*; | ||
| 10 | use embassy_embedded_hal::SetConfig; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_rp::spi::Spi; | ||
| 13 | use embassy_rp::{gpio, spi}; | ||
| 14 | use embedded_hal_bus::spi::ExclusiveDevice; | ||
| 15 | use embedded_sdmmc::sdcard::{DummyCsPin, SdCard}; | ||
| 16 | use gpio::{Level, Output}; | ||
| 17 | use {defmt_rtt as _, panic_probe as _}; | ||
| 18 | |||
| 19 | struct DummyTimesource(); | ||
| 20 | |||
| 21 | impl embedded_sdmmc::TimeSource for DummyTimesource { | ||
| 22 | fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { | ||
| 23 | embedded_sdmmc::Timestamp { | ||
| 24 | year_since_1970: 0, | ||
| 25 | zero_indexed_month: 0, | ||
| 26 | zero_indexed_day: 0, | ||
| 27 | hours: 0, | ||
| 28 | minutes: 0, | ||
| 29 | seconds: 0, | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | #[embassy_executor::main] | ||
| 35 | async fn main(_spawner: Spawner) { | ||
| 36 | embassy_rp::pac::SIO.spinlock(31).write_value(1); | ||
| 37 | let p = embassy_rp::init(Default::default()); | ||
| 38 | |||
| 39 | // SPI clock needs to be running at <= 400kHz during initialization | ||
| 40 | let mut config = spi::Config::default(); | ||
| 41 | config.frequency = 400_000; | ||
| 42 | let spi = Spi::new_blocking(p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, config); | ||
| 43 | // Use a dummy cs pin here, for embedded-hal SpiDevice compatibility reasons | ||
| 44 | let spi_dev = ExclusiveDevice::new_no_delay(spi, DummyCsPin); | ||
| 45 | // Real cs pin | ||
| 46 | let cs = Output::new(p.PIN_16, Level::High); | ||
| 47 | |||
| 48 | let sdcard = SdCard::new(spi_dev, cs, embassy_time::Delay); | ||
| 49 | info!("Card size is {} bytes", sdcard.num_bytes().unwrap()); | ||
| 50 | |||
| 51 | // Now that the card is initialized, the SPI clock can go faster | ||
| 52 | let mut config = spi::Config::default(); | ||
| 53 | config.frequency = 16_000_000; | ||
| 54 | sdcard.spi(|dev| dev.bus_mut().set_config(&config)).ok(); | ||
| 55 | |||
| 56 | // Now let's look for volumes (also known as partitions) on our block device. | ||
| 57 | // To do this we need a Volume Manager. It will take ownership of the block device. | ||
| 58 | let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, DummyTimesource()); | ||
| 59 | |||
| 60 | // Try and access Volume 0 (i.e. the first partition). | ||
| 61 | // The volume object holds information about the filesystem on that volume. | ||
| 62 | let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0)).unwrap(); | ||
| 63 | info!("Volume 0: {:?}", defmt::Debug2Format(&volume0)); | ||
| 64 | |||
| 65 | // Open the root directory (mutably borrows from the volume). | ||
| 66 | let mut root_dir = volume0.open_root_dir().unwrap(); | ||
| 67 | |||
| 68 | // Open a file called "MY_FILE.TXT" in the root directory | ||
| 69 | // This mutably borrows the directory. | ||
| 70 | let mut my_file = root_dir | ||
| 71 | .open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly) | ||
| 72 | .unwrap(); | ||
| 73 | |||
| 74 | // Print the contents of the file | ||
| 75 | while !my_file.is_eof() { | ||
| 76 | let mut buf = [0u8; 32]; | ||
| 77 | if let Ok(n) = my_file.read(&mut buf) { | ||
| 78 | info!("{:a}", buf[..n]); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | loop {} | ||
| 83 | } | ||
diff --git a/examples/rp/src/bin/uart_r503.rs b/examples/rp/src/bin/uart_r503.rs new file mode 100644 index 000000000..085be280b --- /dev/null +++ b/examples/rp/src/bin/uart_r503.rs | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{debug, error, info}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_rp::bind_interrupts; | ||
| 7 | use embassy_rp::peripherals::UART0; | ||
| 8 | use embassy_rp::uart::{Config, DataBits, InterruptHandler as UARTInterruptHandler, Parity, StopBits, Uart}; | ||
| 9 | use embassy_time::{with_timeout, Duration, Timer}; | ||
| 10 | use heapless::Vec; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | bind_interrupts!(pub struct Irqs { | ||
| 14 | UART0_IRQ => UARTInterruptHandler<UART0>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | const START: u16 = 0xEF01; | ||
| 18 | const ADDRESS: u32 = 0xFFFFFFFF; | ||
| 19 | |||
| 20 | // ================================================================================ | ||
| 21 | |||
| 22 | // Data package format | ||
| 23 | // Name Length Description | ||
| 24 | // ========================================================================================================== | ||
| 25 | // Start 2 bytes Fixed value of 0xEF01; High byte transferred first. | ||
| 26 | // Address 4 bytes Default value is 0xFFFFFFFF, which can be modified by command. | ||
| 27 | // High byte transferred first and at wrong adder value, module | ||
| 28 | // will reject to transfer. | ||
| 29 | // PID 1 byte 01H Command packet; | ||
| 30 | // 02H Data packet; Data packet shall not appear alone in executing | ||
| 31 | // processs, must follow command packet or acknowledge packet. | ||
| 32 | // 07H Acknowledge packet; | ||
| 33 | // 08H End of Data packet. | ||
| 34 | // LENGTH 2 bytes Refers to the length of package content (command packets and data packets) | ||
| 35 | // plus the length of Checksum (2 bytes). Unit is byte. Max length is 256 bytes. | ||
| 36 | // And high byte is transferred first. | ||
| 37 | // DATA - It can be commands, data, command’s parameters, acknowledge result, etc. | ||
| 38 | // (fingerprint character value, template are all deemed as data); | ||
| 39 | // SUM 2 bytes The arithmetic sum of package identifier, package length and all package | ||
| 40 | // contens. Overflowing bits are omitted. high byte is transferred first. | ||
| 41 | |||
| 42 | // ================================================================================ | ||
| 43 | |||
| 44 | // Checksum is calculated on 'length (2 bytes) + data (??)'. | ||
| 45 | fn compute_checksum(buf: Vec<u8, 32>) -> u16 { | ||
| 46 | let mut checksum = 0u16; | ||
| 47 | |||
| 48 | let check_end = buf.len(); | ||
| 49 | let checked_bytes = &buf[6..check_end]; | ||
| 50 | for byte in checked_bytes { | ||
| 51 | checksum += (*byte) as u16; | ||
| 52 | } | ||
| 53 | return checksum; | ||
| 54 | } | ||
| 55 | |||
| 56 | #[embassy_executor::main] | ||
| 57 | async fn main(_spawner: Spawner) { | ||
| 58 | info!("Start"); | ||
| 59 | |||
| 60 | let p = embassy_rp::init(Default::default()); | ||
| 61 | |||
| 62 | // Initialize the fingerprint scanner. | ||
| 63 | let mut config = Config::default(); | ||
| 64 | config.baudrate = 57600; | ||
| 65 | config.stop_bits = StopBits::STOP1; | ||
| 66 | config.data_bits = DataBits::DataBits8; | ||
| 67 | config.parity = Parity::ParityNone; | ||
| 68 | |||
| 69 | let (uart, tx_pin, tx_dma, rx_pin, rx_dma) = (p.UART0, p.PIN_16, p.DMA_CH0, p.PIN_17, p.DMA_CH1); | ||
| 70 | let uart = Uart::new(uart, tx_pin, rx_pin, Irqs, tx_dma, rx_dma, config); | ||
| 71 | let (mut tx, mut rx) = uart.split(); | ||
| 72 | |||
| 73 | let mut vec_buf: Vec<u8, 32> = heapless::Vec::new(); | ||
| 74 | let mut data: Vec<u8, 32> = heapless::Vec::new(); | ||
| 75 | |||
| 76 | let mut speeds: Vec<u8, 3> = heapless::Vec::new(); | ||
| 77 | let _ = speeds.push(0xC8); // Slow | ||
| 78 | let _ = speeds.push(0x20); // Medium | ||
| 79 | let _ = speeds.push(0x02); // Fast | ||
| 80 | |||
| 81 | // Cycle through the three colours Red, Blue and Purple forever. | ||
| 82 | loop { | ||
| 83 | for colour in 1..=3 { | ||
| 84 | for speed in &speeds { | ||
| 85 | // Set the data first, because the length is dependent on that. | ||
| 86 | // However, we write the length bits before we do the data. | ||
| 87 | data.clear(); | ||
| 88 | let _ = data.push(0x01); // ctrl=Breathing light | ||
| 89 | let _ = data.push(*speed); | ||
| 90 | let _ = data.push(colour as u8); // colour=Red, Blue, Purple | ||
| 91 | let _ = data.push(0x00); // times=Infinite | ||
| 92 | |||
| 93 | // Clear buffers | ||
| 94 | vec_buf.clear(); | ||
| 95 | |||
| 96 | // START | ||
| 97 | let _ = vec_buf.extend_from_slice(&START.to_be_bytes()[..]); | ||
| 98 | |||
| 99 | // ADDRESS | ||
| 100 | let _ = vec_buf.extend_from_slice(&ADDRESS.to_be_bytes()[..]); | ||
| 101 | |||
| 102 | // PID | ||
| 103 | let _ = vec_buf.extend_from_slice(&[0x01]); | ||
| 104 | |||
| 105 | // LENGTH | ||
| 106 | let len: u16 = (1 + data.len() + 2).try_into().unwrap(); | ||
| 107 | let _ = vec_buf.extend_from_slice(&len.to_be_bytes()[..]); | ||
| 108 | |||
| 109 | // COMMAND | ||
| 110 | let _ = vec_buf.push(0x35); // Command: AuraLedConfig | ||
| 111 | |||
| 112 | // DATA | ||
| 113 | let _ = vec_buf.extend_from_slice(&data); | ||
| 114 | |||
| 115 | // SUM | ||
| 116 | let chk = compute_checksum(vec_buf.clone()); | ||
| 117 | let _ = vec_buf.extend_from_slice(&chk.to_be_bytes()[..]); | ||
| 118 | |||
| 119 | // ===== | ||
| 120 | |||
| 121 | // Send command buffer. | ||
| 122 | let data_write: [u8; 16] = vec_buf.clone().into_array().unwrap(); | ||
| 123 | debug!(" write='{:?}'", data_write[..]); | ||
| 124 | match tx.write(&data_write).await { | ||
| 125 | Ok(..) => info!("Write successful."), | ||
| 126 | Err(e) => error!("Write error: {:?}", e), | ||
| 127 | } | ||
| 128 | |||
| 129 | // ===== | ||
| 130 | |||
| 131 | // Read command buffer. | ||
| 132 | let mut read_buf: [u8; 1] = [0; 1]; // Can only read one byte at a time! | ||
| 133 | let mut data_read: Vec<u8, 32> = heapless::Vec::new(); // Save buffer. | ||
| 134 | |||
| 135 | info!("Attempting read."); | ||
| 136 | loop { | ||
| 137 | // Some commands, like `Img2Tz()` needs longer, but we hard-code this to 200ms | ||
| 138 | // for this command. | ||
| 139 | match with_timeout(Duration::from_millis(200), rx.read(&mut read_buf)).await { | ||
| 140 | Ok(..) => { | ||
| 141 | // Extract and save read byte. | ||
| 142 | debug!(" r='{=u8:#04x}H' ({:03}D)", read_buf[0], read_buf[0]); | ||
| 143 | let _ = data_read.push(read_buf[0]).unwrap(); | ||
| 144 | } | ||
| 145 | Err(..) => break, // TimeoutError -> Ignore. | ||
| 146 | } | ||
| 147 | } | ||
| 148 | info!("Read successful"); | ||
| 149 | debug!(" read='{:?}'", data_read[..]); | ||
| 150 | |||
| 151 | Timer::after_secs(3).await; | ||
| 152 | info!("Changing speed."); | ||
| 153 | } | ||
| 154 | |||
| 155 | info!("Changing colour."); | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs index 710be8d13..a7cb322d8 100644 --- a/examples/rp/src/bin/usb_hid_keyboard.rs +++ b/examples/rp/src/bin/usb_hid_keyboard.rs | |||
| @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) { | |||
| 41 | // You can also add a Microsoft OS descriptor. | 41 | // You can also add a Microsoft OS descriptor. |
| 42 | let mut msos_descriptor = [0; 256]; | 42 | let mut msos_descriptor = [0; 256]; |
| 43 | let mut control_buf = [0; 64]; | 43 | let mut control_buf = [0; 64]; |
| 44 | let request_handler = MyRequestHandler {}; | 44 | let mut request_handler = MyRequestHandler {}; |
| 45 | let mut device_handler = MyDeviceHandler::new(); | 45 | let mut device_handler = MyDeviceHandler::new(); |
| 46 | 46 | ||
| 47 | let mut state = State::new(); | 47 | let mut state = State::new(); |
| @@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) { | |||
| 60 | // Create classes on the builder. | 60 | // Create classes on the builder. |
| 61 | let config = embassy_usb::class::hid::Config { | 61 | let config = embassy_usb::class::hid::Config { |
| 62 | report_descriptor: KeyboardReport::desc(), | 62 | report_descriptor: KeyboardReport::desc(), |
| 63 | request_handler: Some(&request_handler), | 63 | request_handler: None, |
| 64 | poll_ms: 60, | 64 | poll_ms: 60, |
| 65 | max_packet_size: 64, | 65 | max_packet_size: 64, |
| 66 | }; | 66 | }; |
| @@ -114,7 +114,7 @@ async fn main(_spawner: Spawner) { | |||
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | let out_fut = async { | 116 | let out_fut = async { |
| 117 | reader.run(false, &request_handler).await; | 117 | reader.run(false, &mut request_handler).await; |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | // Run everything concurrently. | 120 | // Run everything concurrently. |
| @@ -125,21 +125,21 @@ async fn main(_spawner: Spawner) { | |||
| 125 | struct MyRequestHandler {} | 125 | struct MyRequestHandler {} |
| 126 | 126 | ||
| 127 | impl RequestHandler for MyRequestHandler { | 127 | impl RequestHandler for MyRequestHandler { |
| 128 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 128 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 129 | info!("Get report for {:?}", id); | 129 | info!("Get report for {:?}", id); |
| 130 | None | 130 | None |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 133 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 134 | info!("Set report for {:?}: {=[u8]}", id, data); | 134 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 135 | OutResponse::Accepted | 135 | OutResponse::Accepted |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 138 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 139 | info!("Set idle rate for {:?} to {:?}", id, dur); | 139 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 142 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 143 | info!("Get idle rate for {:?}", id); | 143 | info!("Get idle rate for {:?}", id); |
| 144 | None | 144 | None |
| 145 | } | 145 | } |
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs index e8b399cb1..cce344fb0 100644 --- a/examples/rp/src/bin/usb_hid_mouse.rs +++ b/examples/rp/src/bin/usb_hid_mouse.rs | |||
| @@ -44,7 +44,7 @@ async fn main(_spawner: Spawner) { | |||
| 44 | // You can also add a Microsoft OS descriptor. | 44 | // You can also add a Microsoft OS descriptor. |
| 45 | let mut msos_descriptor = [0; 256]; | 45 | let mut msos_descriptor = [0; 256]; |
| 46 | let mut control_buf = [0; 64]; | 46 | let mut control_buf = [0; 64]; |
| 47 | let request_handler = MyRequestHandler {}; | 47 | let mut request_handler = MyRequestHandler {}; |
| 48 | let mut device_handler = MyDeviceHandler::new(); | 48 | let mut device_handler = MyDeviceHandler::new(); |
| 49 | 49 | ||
| 50 | let mut state = State::new(); | 50 | let mut state = State::new(); |
| @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { | |||
| 63 | // Create classes on the builder. | 63 | // Create classes on the builder. |
| 64 | let config = embassy_usb::class::hid::Config { | 64 | let config = embassy_usb::class::hid::Config { |
| 65 | report_descriptor: MouseReport::desc(), | 65 | report_descriptor: MouseReport::desc(), |
| 66 | request_handler: Some(&request_handler), | 66 | request_handler: None, |
| 67 | poll_ms: 60, | 67 | poll_ms: 60, |
| 68 | max_packet_size: 64, | 68 | max_packet_size: 64, |
| 69 | }; | 69 | }; |
| @@ -106,7 +106,7 @@ async fn main(_spawner: Spawner) { | |||
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | let out_fut = async { | 108 | let out_fut = async { |
| 109 | reader.run(false, &request_handler).await; | 109 | reader.run(false, &mut request_handler).await; |
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| 112 | // Run everything concurrently. | 112 | // Run everything concurrently. |
| @@ -117,21 +117,21 @@ async fn main(_spawner: Spawner) { | |||
| 117 | struct MyRequestHandler {} | 117 | struct MyRequestHandler {} |
| 118 | 118 | ||
| 119 | impl RequestHandler for MyRequestHandler { | 119 | impl RequestHandler for MyRequestHandler { |
| 120 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 120 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 121 | info!("Get report for {:?}", id); | 121 | info!("Get report for {:?}", id); |
| 122 | None | 122 | None |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 125 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 126 | info!("Set report for {:?}: {=[u8]}", id, data); | 126 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 127 | OutResponse::Accepted | 127 | OutResponse::Accepted |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 130 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 131 | info!("Set idle rate for {:?} to {:?}", id, dur); | 131 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 134 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 135 | info!("Get idle rate for {:?}", id); | 135 | info!("Get idle rate for {:?}", id); |
| 136 | None | 136 | None |
| 137 | } | 137 | } |
diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index 3c9bc96dd..4a802994a 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs | |||
| @@ -5,15 +5,15 @@ | |||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | 7 | ||
| 8 | use defmt::{info, panic}; | 8 | use defmt::{info, panic, unwrap}; |
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_rp::bind_interrupts; | 10 | use embassy_rp::bind_interrupts; |
| 12 | use embassy_rp::peripherals::USB; | 11 | use embassy_rp::peripherals::USB; |
| 13 | use embassy_rp::usb::{Driver, Instance, InterruptHandler}; | 12 | use embassy_rp::usb::{Driver, Instance, InterruptHandler}; |
| 14 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 13 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 15 | use embassy_usb::driver::EndpointError; | 14 | use embassy_usb::driver::EndpointError; |
| 16 | use embassy_usb::{Builder, Config}; | 15 | use embassy_usb::UsbDevice; |
| 16 | use static_cell::StaticCell; | ||
| 17 | use {defmt_rtt as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _}; |
| 18 | 18 | ||
| 19 | bind_interrupts!(struct Irqs { | 19 | bind_interrupts!(struct Irqs { |
| @@ -21,7 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 21 | }); | 21 | }); |
| 22 | 22 | ||
| 23 | #[embassy_executor::main] | 23 | #[embassy_executor::main] |
| 24 | async fn main(_spawner: Spawner) { | 24 | async fn main(spawner: Spawner) { |
| 25 | info!("Hello there!"); | 25 | info!("Hello there!"); |
| 26 | 26 | ||
| 27 | let p = embassy_rp::init(Default::default()); | 27 | let p = embassy_rp::init(Default::default()); |
| @@ -30,59 +30,69 @@ async fn main(_spawner: Spawner) { | |||
| 30 | let driver = Driver::new(p.USB, Irqs); | 30 | let driver = Driver::new(p.USB, Irqs); |
| 31 | 31 | ||
| 32 | // Create embassy-usb Config | 32 | // Create embassy-usb Config |
| 33 | let mut config = Config::new(0xc0de, 0xcafe); | 33 | let config = { |
| 34 | config.manufacturer = Some("Embassy"); | 34 | let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); |
| 35 | config.product = Some("USB-serial example"); | 35 | config.manufacturer = Some("Embassy"); |
| 36 | config.serial_number = Some("12345678"); | 36 | config.product = Some("USB-serial example"); |
| 37 | config.max_power = 100; | 37 | config.serial_number = Some("12345678"); |
| 38 | config.max_packet_size_0 = 64; | 38 | config.max_power = 100; |
| 39 | 39 | config.max_packet_size_0 = 64; | |
| 40 | // Required for windows compatibility. | 40 | |
| 41 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | 41 | // Required for windows compatibility. |
| 42 | config.device_class = 0xEF; | 42 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help |
| 43 | config.device_sub_class = 0x02; | 43 | config.device_class = 0xEF; |
| 44 | config.device_protocol = 0x01; | 44 | config.device_sub_class = 0x02; |
| 45 | config.composite_with_iads = true; | 45 | config.device_protocol = 0x01; |
| 46 | config.composite_with_iads = true; | ||
| 47 | config | ||
| 48 | }; | ||
| 46 | 49 | ||
| 47 | // Create embassy-usb DeviceBuilder using the driver and config. | 50 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 48 | // It needs some buffers for building the descriptors. | 51 | // It needs some buffers for building the descriptors. |
| 49 | let mut config_descriptor = [0; 256]; | 52 | let mut builder = { |
| 50 | let mut bos_descriptor = [0; 256]; | 53 | static CONFIG_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); |
| 51 | let mut control_buf = [0; 64]; | 54 | static BOS_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); |
| 52 | 55 | static CONTROL_BUF: StaticCell<[u8; 64]> = StaticCell::new(); | |
| 53 | let mut state = State::new(); | 56 | |
| 54 | 57 | let builder = embassy_usb::Builder::new( | |
| 55 | let mut builder = Builder::new( | 58 | driver, |
| 56 | driver, | 59 | config, |
| 57 | config, | 60 | CONFIG_DESCRIPTOR.init([0; 256]), |
| 58 | &mut config_descriptor, | 61 | BOS_DESCRIPTOR.init([0; 256]), |
| 59 | &mut bos_descriptor, | 62 | &mut [], // no msos descriptors |
| 60 | &mut [], // no msos descriptors | 63 | CONTROL_BUF.init([0; 64]), |
| 61 | &mut control_buf, | 64 | ); |
| 62 | ); | 65 | builder |
| 66 | }; | ||
| 63 | 67 | ||
| 64 | // Create classes on the builder. | 68 | // Create classes on the builder. |
| 65 | let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); | 69 | let mut class = { |
| 70 | static STATE: StaticCell<State> = StaticCell::new(); | ||
| 71 | let state = STATE.init(State::new()); | ||
| 72 | CdcAcmClass::new(&mut builder, state, 64) | ||
| 73 | }; | ||
| 66 | 74 | ||
| 67 | // Build the builder. | 75 | // Build the builder. |
| 68 | let mut usb = builder.build(); | 76 | let usb = builder.build(); |
| 69 | 77 | ||
| 70 | // Run the USB device. | 78 | // Run the USB device. |
| 71 | let usb_fut = usb.run(); | 79 | unwrap!(spawner.spawn(usb_task(usb))); |
| 72 | 80 | ||
| 73 | // Do stuff with the class! | 81 | // Do stuff with the class! |
| 74 | let echo_fut = async { | 82 | loop { |
| 75 | loop { | 83 | class.wait_connection().await; |
| 76 | class.wait_connection().await; | 84 | info!("Connected"); |
| 77 | info!("Connected"); | 85 | let _ = echo(&mut class).await; |
| 78 | let _ = echo(&mut class).await; | 86 | info!("Disconnected"); |
| 79 | info!("Disconnected"); | 87 | } |
| 80 | } | 88 | } |
| 81 | }; | 89 | |
| 90 | type MyUsbDriver = Driver<'static, USB>; | ||
| 91 | type MyUsbDevice = UsbDevice<'static, MyUsbDriver>; | ||
| 82 | 92 | ||
| 83 | // Run everything concurrently. | 93 | #[embassy_executor::task] |
| 84 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | 94 | async fn usb_task(mut usb: MyUsbDevice) -> ! { |
| 85 | join(usb_fut, echo_fut).await; | 95 | usb.run().await |
| 86 | } | 96 | } |
| 87 | 97 | ||
| 88 | struct Disconnected {} | 98 | struct Disconnected {} |
diff --git a/examples/rp/src/bin/usb_webusb.rs b/examples/rp/src/bin/usb_webusb.rs new file mode 100644 index 000000000..e73938ac9 --- /dev/null +++ b/examples/rp/src/bin/usb_webusb.rs | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | //! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. | ||
| 2 | //! | ||
| 3 | //! This creates a WebUSB capable device that echoes data back to the host. | ||
| 4 | //! | ||
| 5 | //! To test this in the browser (ideally host this on localhost:8080, to test the landing page | ||
| 6 | //! feature): | ||
| 7 | //! ```js | ||
| 8 | //! (async () => { | ||
| 9 | //! const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0xf569 }] }); | ||
| 10 | //! await device.open(); | ||
| 11 | //! await device.claimInterface(1); | ||
| 12 | //! device.transferIn(1, 64).then(data => console.log(data)); | ||
| 13 | //! await device.transferOut(1, new Uint8Array([1,2,3])); | ||
| 14 | //! })(); | ||
| 15 | //! ``` | ||
| 16 | |||
| 17 | #![no_std] | ||
| 18 | #![no_main] | ||
| 19 | |||
| 20 | use defmt::info; | ||
| 21 | use embassy_executor::Spawner; | ||
| 22 | use embassy_futures::join::join; | ||
| 23 | use embassy_rp::bind_interrupts; | ||
| 24 | use embassy_rp::peripherals::USB; | ||
| 25 | use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler}; | ||
| 26 | use embassy_usb::class::web_usb::{Config as WebUsbConfig, State, Url, WebUsb}; | ||
| 27 | use embassy_usb::driver::{Driver, Endpoint, EndpointIn, EndpointOut}; | ||
| 28 | use embassy_usb::msos::{self, windows_version}; | ||
| 29 | use embassy_usb::{Builder, Config}; | ||
| 30 | use {defmt_rtt as _, panic_probe as _}; | ||
| 31 | |||
| 32 | bind_interrupts!(struct Irqs { | ||
| 33 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 34 | }); | ||
| 35 | |||
| 36 | // This is a randomly generated GUID to allow clients on Windows to find our device | ||
| 37 | const DEVICE_INTERFACE_GUIDS: &[&str] = &["{AFB9A6FB-30BA-44BC-9232-806CFC875321}"]; | ||
| 38 | |||
| 39 | #[embassy_executor::main] | ||
| 40 | async fn main(_spawner: Spawner) { | ||
| 41 | let p = embassy_rp::init(Default::default()); | ||
| 42 | |||
| 43 | // Create the driver, from the HAL. | ||
| 44 | let driver = UsbDriver::new(p.USB, Irqs); | ||
| 45 | |||
| 46 | // Create embassy-usb Config | ||
| 47 | let mut config = Config::new(0xf569, 0x0001); | ||
| 48 | config.manufacturer = Some("Embassy"); | ||
| 49 | config.product = Some("WebUSB example"); | ||
| 50 | config.serial_number = Some("12345678"); | ||
| 51 | config.max_power = 100; | ||
| 52 | config.max_packet_size_0 = 64; | ||
| 53 | |||
| 54 | // Required for windows compatibility. | ||
| 55 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
| 56 | config.device_class = 0xff; | ||
| 57 | config.device_sub_class = 0x00; | ||
| 58 | config.device_protocol = 0x00; | ||
| 59 | |||
| 60 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 61 | // It needs some buffers for building the descriptors. | ||
| 62 | let mut config_descriptor = [0; 256]; | ||
| 63 | let mut bos_descriptor = [0; 256]; | ||
| 64 | let mut control_buf = [0; 64]; | ||
| 65 | let mut msos_descriptor = [0; 256]; | ||
| 66 | |||
| 67 | let webusb_config = WebUsbConfig { | ||
| 68 | max_packet_size: 64, | ||
| 69 | vendor_code: 1, | ||
| 70 | // If defined, shows a landing page which the device manufacturer would like the user to visit in order to control their device. Suggest the user to navigate to this URL when the device is connected. | ||
| 71 | landing_url: Some(Url::new("http://localhost:8080")), | ||
| 72 | }; | ||
| 73 | |||
| 74 | let mut state = State::new(); | ||
| 75 | |||
| 76 | let mut builder = Builder::new( | ||
| 77 | driver, | ||
| 78 | config, | ||
| 79 | &mut config_descriptor, | ||
| 80 | &mut bos_descriptor, | ||
| 81 | &mut msos_descriptor, | ||
| 82 | &mut control_buf, | ||
| 83 | ); | ||
| 84 | |||
| 85 | // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. | ||
| 86 | // We tell Windows that this entire device is compatible with the "WINUSB" feature, | ||
| 87 | // which causes it to use the built-in WinUSB driver automatically, which in turn | ||
| 88 | // can be used by libusb/rusb software without needing a custom driver or INF file. | ||
| 89 | // In principle you might want to call msos_feature() just on a specific function, | ||
| 90 | // if your device also has other functions that still use standard class drivers. | ||
| 91 | builder.msos_descriptor(windows_version::WIN8_1, 0); | ||
| 92 | builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); | ||
| 93 | builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( | ||
| 94 | "DeviceInterfaceGUIDs", | ||
| 95 | msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), | ||
| 96 | )); | ||
| 97 | |||
| 98 | // Create classes on the builder (WebUSB just needs some setup, but doesn't return anything) | ||
| 99 | WebUsb::configure(&mut builder, &mut state, &webusb_config); | ||
| 100 | // Create some USB bulk endpoints for testing. | ||
| 101 | let mut endpoints = WebEndpoints::new(&mut builder, &webusb_config); | ||
| 102 | |||
| 103 | // Build the builder. | ||
| 104 | let mut usb = builder.build(); | ||
| 105 | |||
| 106 | // Run the USB device. | ||
| 107 | let usb_fut = usb.run(); | ||
| 108 | |||
| 109 | // Do some WebUSB transfers. | ||
| 110 | let webusb_fut = async { | ||
| 111 | loop { | ||
| 112 | endpoints.wait_connected().await; | ||
| 113 | info!("Connected"); | ||
| 114 | endpoints.echo().await; | ||
| 115 | } | ||
| 116 | }; | ||
| 117 | |||
| 118 | // Run everything concurrently. | ||
| 119 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 120 | join(usb_fut, webusb_fut).await; | ||
| 121 | } | ||
| 122 | |||
| 123 | struct WebEndpoints<'d, D: Driver<'d>> { | ||
| 124 | write_ep: D::EndpointIn, | ||
| 125 | read_ep: D::EndpointOut, | ||
| 126 | } | ||
| 127 | |||
| 128 | impl<'d, D: Driver<'d>> WebEndpoints<'d, D> { | ||
| 129 | fn new(builder: &mut Builder<'d, D>, config: &'d WebUsbConfig<'d>) -> Self { | ||
| 130 | let mut func = builder.function(0xff, 0x00, 0x00); | ||
| 131 | let mut iface = func.interface(); | ||
| 132 | let mut alt = iface.alt_setting(0xff, 0x00, 0x00, None); | ||
| 133 | |||
| 134 | let write_ep = alt.endpoint_bulk_in(config.max_packet_size); | ||
| 135 | let read_ep = alt.endpoint_bulk_out(config.max_packet_size); | ||
| 136 | |||
| 137 | WebEndpoints { write_ep, read_ep } | ||
| 138 | } | ||
| 139 | |||
| 140 | // Wait until the device's endpoints are enabled. | ||
| 141 | async fn wait_connected(&mut self) { | ||
| 142 | self.read_ep.wait_enabled().await | ||
| 143 | } | ||
| 144 | |||
| 145 | // Echo data back to the host. | ||
| 146 | async fn echo(&mut self) { | ||
| 147 | let mut buf = [0; 64]; | ||
| 148 | loop { | ||
| 149 | let n = self.read_ep.read(&mut buf).await.unwrap(); | ||
| 150 | let data = &buf[..n]; | ||
| 151 | info!("Data read: {:x}", data); | ||
| 152 | self.write_ep.write(data).await.unwrap(); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | } | ||
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index f05565e84..77c479d3b 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml | |||
| @@ -5,7 +5,7 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] } | 8 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["log"] } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "std", ] } | 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "std", ] } |
| 11 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } | 11 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } |
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 7a3e03b75..6fdcdce5f 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml | |||
| @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32c031c6 to your chip name, if necessary. | 8 | # Change stm32c031c6 to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.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"] } | 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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | 13 | ||
| @@ -18,7 +18,6 @@ cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | |||
| 18 | cortex-m-rt = "0.7.0" | 18 | cortex-m-rt = "0.7.0" |
| 19 | embedded-hal = "0.2.6" | 19 | embedded-hal = "0.2.6" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 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 } | 21 | heapless = { version = "0.8", default-features = false } |
| 23 | 22 | ||
| 24 | [profile.release] | 23 | [profile.release] |
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index c74980dc4..5b648e58a 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml | |||
| @@ -4,8 +4,6 @@ version = "0.1.0" | |||
| 4 | edition = "2021" | 4 | edition = "2021" |
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
| 8 | |||
| 9 | [dependencies] | 7 | [dependencies] |
| 10 | # Change stm32f091rc to your chip name, if necessary. | 8 | # Change stm32f091rc to your chip name, if necessary. |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] } |
| @@ -14,7 +12,7 @@ cortex-m-rt = "0.7.0" | |||
| 14 | defmt = "0.3" | 12 | defmt = "0.3" |
| 15 | defmt-rtt = "0.4" | 13 | defmt-rtt = "0.4" |
| 16 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 14 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 17 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 15 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 18 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 16 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 19 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 17 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 20 | static_cell = "2" | 18 | static_cell = "2" |
diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs index c2fb143cd..8825e2687 100644 --- a/examples/stm32f0/src/bin/adc.rs +++ b/examples/stm32f0/src/bin/adc.rs | |||
| @@ -4,13 +4,13 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::peripherals::ADC; | 7 | use embassy_stm32::peripherals::ADC1; |
| 8 | use embassy_stm32::{adc, bind_interrupts}; | 8 | use embassy_stm32::{adc, bind_interrupts}; |
| 9 | use embassy_time::{Delay, Timer}; | 9 | use embassy_time::Timer; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | 12 | bind_interrupts!(struct Irqs { |
| 13 | ADC1_COMP => adc::InterruptHandler<ADC>; | 13 | ADC1_COMP => adc::InterruptHandler<ADC1>; |
| 14 | }); | 14 | }); |
| 15 | 15 | ||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| @@ -18,11 +18,11 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let p = embassy_stm32::init(Default::default()); | 18 | let p = embassy_stm32::init(Default::default()); |
| 19 | info!("Hello World!"); | 19 | info!("Hello World!"); |
| 20 | 20 | ||
| 21 | let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); | 21 | let mut adc = Adc::new(p.ADC1, Irqs); |
| 22 | adc.set_sample_time(SampleTime::CYCLES71_5); | 22 | adc.set_sample_time(SampleTime::CYCLES71_5); |
| 23 | let mut pin = p.PA1; | 23 | let mut pin = p.PA1; |
| 24 | 24 | ||
| 25 | let mut vrefint = adc.enable_vref(&mut Delay); | 25 | let mut vrefint = adc.enable_vref(); |
| 26 | let vrefint_sample = adc.read(&mut vrefint).await; | 26 | let vrefint_sample = adc.read(&mut vrefint).await; |
| 27 | let convert_to_millivolts = |sample| { | 27 | let convert_to_millivolts = |sample| { |
| 28 | // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf | 28 | // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf |
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 4f282f326..51723ac6d 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml | |||
| @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f103c8 to your chip name, if necessary. | 8 | # Change stm32f103c8 to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.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"] } | 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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | 15 | ||
| 16 | defmt = "0.3" | 16 | defmt = "0.3" |
| @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 20 | cortex-m-rt = "0.7.0" | 20 | cortex-m-rt = "0.7.0" |
| 21 | embedded-hal = "0.2.6" | 21 | embedded-hal = "0.2.6" |
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 24 | heapless = { version = "0.8", default-features = false } | 23 | heapless = { version = "0.8", default-features = false } |
| 25 | nb = "1.0.0" | 24 | nb = "1.0.0" |
| 26 | static_cell = "2.0.0" | 25 | static_cell = "2.0.0" |
diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs index 1440460a9..541ff159e 100644 --- a/examples/stm32f1/src/bin/adc.rs +++ b/examples/stm32f1/src/bin/adc.rs | |||
| @@ -6,7 +6,7 @@ use embassy_executor::Spawner; | |||
| 6 | use embassy_stm32::adc::Adc; | 6 | use embassy_stm32::adc::Adc; |
| 7 | use embassy_stm32::peripherals::ADC1; | 7 | use embassy_stm32::peripherals::ADC1; |
| 8 | use embassy_stm32::{adc, bind_interrupts}; | 8 | use embassy_stm32::{adc, bind_interrupts}; |
| 9 | use embassy_time::{Delay, Timer}; | 9 | use embassy_time::Timer; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | 12 | bind_interrupts!(struct Irqs { |
| @@ -18,10 +18,10 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let p = embassy_stm32::init(Default::default()); | 18 | let p = embassy_stm32::init(Default::default()); |
| 19 | info!("Hello World!"); | 19 | info!("Hello World!"); |
| 20 | 20 | ||
| 21 | let mut adc = Adc::new(p.ADC1, &mut Delay); | 21 | let mut adc = Adc::new(p.ADC1); |
| 22 | let mut pin = p.PB1; | 22 | let mut pin = p.PB1; |
| 23 | 23 | ||
| 24 | let mut vrefint = adc.enable_vref(&mut Delay); | 24 | let mut vrefint = adc.enable_vref(); |
| 25 | let vrefint_sample = adc.read(&mut vrefint).await; | 25 | let vrefint_sample = adc.read(&mut vrefint).await; |
| 26 | let convert_to_millivolts = |sample| { | 26 | let convert_to_millivolts = |sample| { |
| 27 | // From http://www.st.com/resource/en/datasheet/CD00161566.pdf | 27 | // From http://www.st.com/resource/en/datasheet/CD00161566.pdf |
diff --git a/examples/stm32f1/src/bin/can.rs b/examples/stm32f1/src/bin/can.rs index 1c13d623d..ad0c8a5a5 100644 --- a/examples/stm32f1/src/bin/can.rs +++ b/examples/stm32f1/src/bin/can.rs | |||
| @@ -85,7 +85,7 @@ async fn main(_spawner: Spawner) { | |||
| 85 | defmt::println!("Error {}", err); | 85 | defmt::println!("Error {}", err); |
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | i += 1; | 88 | i = i.wrapping_add(1); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | */ | 91 | */ |
| @@ -135,6 +135,6 @@ async fn main(_spawner: Spawner) { | |||
| 135 | defmt::println!("Error {}", err); | 135 | defmt::println!("Error {}", err); |
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| 138 | i += 1; | 138 | i = i.wrapping_add(1); |
| 139 | } | 139 | } |
| 140 | } | 140 | } |
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index 4cbf1dc84..5d07b0e04 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml | |||
| @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f207zg to your chip name, if necessary. | 8 | # Change stm32f207zg to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.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"] } | 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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | 13 | ||
| @@ -18,7 +18,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 18 | cortex-m-rt = "0.7.0" | 18 | cortex-m-rt = "0.7.0" |
| 19 | embedded-hal = "0.2.6" | 19 | embedded-hal = "0.2.6" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 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 } | 21 | heapless = { version = "0.8", default-features = false } |
| 23 | nb = "1.0.0" | 22 | nb = "1.0.0" |
| 24 | 23 | ||
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 64bb2e560..848a6b331 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml | |||
| @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f303ze to your chip name, if necessary. | 8 | # Change stm32f303ze to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | 15 | ||
| 16 | defmt = "0.3" | 16 | defmt = "0.3" |
| @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 20 | cortex-m-rt = "0.7.0" | 20 | cortex-m-rt = "0.7.0" |
| 21 | embedded-hal = "0.2.6" | 21 | embedded-hal = "0.2.6" |
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 24 | heapless = { version = "0.8", default-features = false } | 23 | heapless = { version = "0.8", default-features = false } |
| 25 | nb = "1.0.0" | 24 | nb = "1.0.0" |
| 26 | embedded-storage = "0.3.1" | 25 | embedded-storage = "0.3.1" |
diff --git a/examples/stm32f3/src/bin/usart_dma.rs b/examples/stm32f3/src/bin/usart_dma.rs index 5234e53b9..573a49f19 100644 --- a/examples/stm32f3/src/bin/usart_dma.rs +++ b/examples/stm32f3/src/bin/usart_dma.rs | |||
| @@ -5,7 +5,6 @@ use core::fmt::Write; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::dma::NoDma; | ||
| 9 | use embassy_stm32::usart::{Config, Uart}; | 8 | use embassy_stm32::usart::{Config, Uart}; |
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 11 | use heapless::String; | 10 | use heapless::String; |
| @@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) { | |||
| 21 | info!("Hello World!"); | 20 | info!("Hello World!"); |
| 22 | 21 | ||
| 23 | let config = Config::default(); | 22 | let config = Config::default(); |
| 24 | let mut usart = Uart::new(p.USART1, p.PE1, p.PE0, Irqs, p.DMA1_CH4, NoDma, config).unwrap(); | 23 | let mut usart = Uart::new(p.USART1, p.PE1, p.PE0, Irqs, p.DMA1_CH4, p.DMA1_CH5, config).unwrap(); |
| 25 | 24 | ||
| 26 | for n in 0u32.. { | 25 | for n in 0u32.. { |
| 27 | let mut s: String<128> = String::new(); | 26 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32f334/.cargo/config.toml b/examples/stm32f334/.cargo/config.toml index caf947be6..f38c90a31 100644 --- a/examples/stm32f334/.cargo/config.toml +++ b/examples/stm32f334/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs-cli chip list` | 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs-cli chip list` |
| 3 | runner = "probe-run --chip STM32F334R8" | 3 | runner = "probe-rs run --chip STM32F334R8" |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | target = "thumbv7em-none-eabihf" | 6 | target = "thumbv7em-none-eabihf" |
diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml index 3e5a7cc8c..50046de56 100644 --- a/examples/stm32f334/Cargo.toml +++ b/examples/stm32f334/Cargo.toml | |||
| @@ -5,11 +5,11 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 13 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 13 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 14 | 14 | ||
| 15 | defmt = "0.3" | 15 | defmt = "0.3" |
| @@ -19,7 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 19 | cortex-m-rt = "0.7.0" | 19 | cortex-m-rt = "0.7.0" |
| 20 | embedded-hal = "0.2.6" | 20 | embedded-hal = "0.2.6" |
| 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 22 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 23 | heapless = { version = "0.8", default-features = false } | 22 | heapless = { version = "0.8", default-features = false } |
| 24 | nb = "1.0.0" | 23 | nb = "1.0.0" |
| 25 | embedded-storage = "0.3.1" | 24 | embedded-storage = "0.3.1" |
diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index bd126ce68..0528a9637 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs | |||
| @@ -7,7 +7,7 @@ use embassy_stm32::adc::{Adc, SampleTime}; | |||
| 7 | use embassy_stm32::peripherals::ADC1; | 7 | use embassy_stm32::peripherals::ADC1; |
| 8 | use embassy_stm32::time::mhz; | 8 | use embassy_stm32::time::mhz; |
| 9 | use embassy_stm32::{adc, bind_interrupts, Config}; | 9 | use embassy_stm32::{adc, bind_interrupts, Config}; |
| 10 | use embassy_time::{Delay, Timer}; | 10 | use embassy_time::Timer; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 12 | ||
| 13 | bind_interrupts!(struct Irqs { | 13 | bind_interrupts!(struct Irqs { |
| @@ -38,13 +38,13 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 38 | 38 | ||
| 39 | info!("create adc..."); | 39 | info!("create adc..."); |
| 40 | 40 | ||
| 41 | let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay); | 41 | let mut adc = Adc::new(p.ADC1, Irqs); |
| 42 | 42 | ||
| 43 | adc.set_sample_time(SampleTime::CYCLES601_5); | 43 | adc.set_sample_time(SampleTime::CYCLES601_5); |
| 44 | 44 | ||
| 45 | info!("enable vrefint..."); | 45 | info!("enable vrefint..."); |
| 46 | 46 | ||
| 47 | let mut vrefint = adc.enable_vref(&mut Delay); | 47 | let mut vrefint = adc.enable_vref(); |
| 48 | let mut temperature = adc.enable_temperature(); | 48 | let mut temperature = adc.enable_temperature(); |
| 49 | 49 | ||
| 50 | loop { | 50 | loop { |
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index a5c710aa2..2dbf1bdab 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs | |||
| @@ -8,7 +8,7 @@ use embassy_stm32::opamp::{OpAmp, OpAmpGain}; | |||
| 8 | use embassy_stm32::peripherals::ADC2; | 8 | use embassy_stm32::peripherals::ADC2; |
| 9 | use embassy_stm32::time::mhz; | 9 | use embassy_stm32::time::mhz; |
| 10 | use embassy_stm32::{adc, bind_interrupts, Config}; | 10 | use embassy_stm32::{adc, bind_interrupts, Config}; |
| 11 | use embassy_time::{Delay, Timer}; | 11 | use embassy_time::Timer; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 13 | ||
| 14 | bind_interrupts!(struct Irqs { | 14 | bind_interrupts!(struct Irqs { |
| @@ -39,14 +39,14 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 39 | 39 | ||
| 40 | info!("create adc..."); | 40 | info!("create adc..."); |
| 41 | 41 | ||
| 42 | let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay); | 42 | let mut adc = Adc::new(p.ADC2, Irqs); |
| 43 | let mut opamp = OpAmp::new(p.OPAMP2); | 43 | let mut opamp = OpAmp::new(p.OPAMP2); |
| 44 | 44 | ||
| 45 | adc.set_sample_time(SampleTime::CYCLES601_5); | 45 | adc.set_sample_time(SampleTime::CYCLES601_5); |
| 46 | 46 | ||
| 47 | info!("enable vrefint..."); | 47 | info!("enable vrefint..."); |
| 48 | 48 | ||
| 49 | let mut vrefint = adc.enable_vref(&mut Delay); | 49 | let mut vrefint = adc.enable_vref(); |
| 50 | let mut temperature = adc.enable_temperature(); | 50 | let mut temperature = adc.enable_temperature(); |
| 51 | let mut buffer = opamp.buffer_ext(&mut p.PA7, &mut p.PA6, OpAmpGain::Mul1); | 51 | let mut buffer = opamp.buffer_ext(&mut p.PA7, &mut p.PA6, OpAmpGain::Mul1); |
| 52 | 52 | ||
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 512158bef..52b7ce9e8 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml | |||
| @@ -6,12 +6,13 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f429zi to your chip name, if necessary. | 8 | # Change stm32f429zi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt" ] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt" ] } |
| 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } |
| 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 15 | 16 | ||
| 16 | defmt = "0.3" | 17 | defmt = "0.3" |
| 17 | defmt-rtt = "0.4" | 18 | defmt-rtt = "0.4" |
| @@ -22,7 +23,7 @@ embedded-hal = "0.2.6" | |||
| 22 | embedded-io = { version = "0.6.0" } | 23 | embedded-io = { version = "0.6.0" } |
| 23 | embedded-io-async = { version = "0.6.1" } | 24 | embedded-io-async = { version = "0.6.1" } |
| 24 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 25 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 25 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 26 | futures-util = { version = "0.3.30", default-features = false } |
| 26 | heapless = { version = "0.8", default-features = false } | 27 | heapless = { version = "0.8", default-features = false } |
| 27 | nb = "1.0.0" | 28 | nb = "1.0.0" |
| 28 | embedded-storage = "0.3.1" | 29 | embedded-storage = "0.3.1" |
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs index 699c29c05..9473b7b7f 100644 --- a/examples/stm32f4/src/bin/adc.rs +++ b/examples/stm32f4/src/bin/adc.rs | |||
| @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { | |||
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 16 | let mut delay = Delay; | 16 | let mut delay = Delay; |
| 17 | let mut adc = Adc::new(p.ADC1, &mut delay); | 17 | let mut adc = Adc::new(p.ADC1); |
| 18 | let mut pin = p.PC1; | 18 | let mut pin = p.PC1; |
| 19 | 19 | ||
| 20 | let mut vrefint = adc.enable_vrefint(); | 20 | let mut vrefint = adc.enable_vrefint(); |
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs index cedc057a7..8e3beee24 100644 --- a/examples/stm32f4/src/bin/can.rs +++ b/examples/stm32f4/src/bin/can.rs | |||
| @@ -63,6 +63,6 @@ async fn main(_spawner: Spawner) { | |||
| 63 | envelope.frame.data()[0], | 63 | envelope.frame.data()[0], |
| 64 | latency.as_micros() | 64 | latency.as_micros() |
| 65 | ); | 65 | ); |
| 66 | i += 1; | 66 | i = i.wrapping_add(1); |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs index 9c7754c4f..dd2a45718 100644 --- a/examples/stm32f4/src/bin/dac.rs +++ b/examples/stm32f4/src/bin/dac.rs | |||
| @@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World, dude!"); | 13 | info!("Hello World, dude!"); |
| 14 | 14 | ||
| 15 | let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); | 15 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); |
| 16 | 16 | ||
| 17 | loop { | 17 | loop { |
| 18 | for v in 0..=255 { | 18 | for v in 0..=255 { |
diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 7f5c8fdb1..648c45bbd 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs | |||
| @@ -62,9 +62,9 @@ async fn main(spawner: Spawner) -> ! { | |||
| 62 | 62 | ||
| 63 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 63 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 64 | 64 | ||
| 65 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | 65 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); |
| 66 | let device = Ethernet::new( | 66 | let device = Ethernet::new( |
| 67 | PACKETS.init(PacketQueue::<16, 16>::new()), | 67 | PACKETS.init(PacketQueue::<4, 4>::new()), |
| 68 | p.ETH, | 68 | p.ETH, |
| 69 | Irqs, | 69 | Irqs, |
| 70 | p.PA1, | 70 | p.PA1, |
diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs index 4b5da774d..4a96357a4 100644 --- a/examples/stm32f4/src/bin/i2c.rs +++ b/examples/stm32f4/src/bin/i2c.rs | |||
| @@ -3,35 +3,19 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::i2c::{Error, I2c}; | 6 | use embassy_stm32::i2c::{Error, I2c}; |
| 8 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 9 | ||
| 12 | const ADDRESS: u8 = 0x5F; | 10 | const ADDRESS: u8 = 0x5F; |
| 13 | const WHOAMI: u8 = 0x0F; | 11 | const WHOAMI: u8 = 0x0F; |
| 14 | 12 | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 17 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 22 | info!("Hello world!"); | 15 | info!("Hello world!"); |
| 23 | let p = embassy_stm32::init(Default::default()); | 16 | let p = embassy_stm32::init(Default::default()); |
| 24 | 17 | ||
| 25 | let mut i2c = I2c::new( | 18 | let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); |
| 26 | p.I2C2, | ||
| 27 | p.PB10, | ||
| 28 | p.PB11, | ||
| 29 | Irqs, | ||
| 30 | NoDma, | ||
| 31 | NoDma, | ||
| 32 | Hertz(100_000), | ||
| 33 | Default::default(), | ||
| 34 | ); | ||
| 35 | 19 | ||
| 36 | let mut data = [0u8; 1]; | 20 | let mut data = [0u8; 1]; |
| 37 | 21 | ||
diff --git a/examples/stm32f4/src/bin/i2c_comparison.rs b/examples/stm32f4/src/bin/i2c_comparison.rs index 30cfbdf57..55c4891e3 100644 --- a/examples/stm32f4/src/bin/i2c_comparison.rs +++ b/examples/stm32f4/src/bin/i2c_comparison.rs | |||
| @@ -13,7 +13,7 @@ use embassy_stm32::i2c::I2c; | |||
| 13 | use embassy_stm32::time::Hertz; | 13 | use embassy_stm32::time::Hertz; |
| 14 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | 14 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; |
| 15 | use embassy_time::Instant; | 15 | use embassy_time::Instant; |
| 16 | use futures::future::try_join3; | 16 | use futures_util::future::try_join3; |
| 17 | use {defmt_rtt as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _}; |
| 18 | 18 | ||
| 19 | const ADDRESS: u8 = 96; | 19 | const ADDRESS: u8 = 96; |
diff --git a/examples/stm32f4/src/bin/input_capture.rs b/examples/stm32f4/src/bin/input_capture.rs new file mode 100644 index 000000000..49de33d2b --- /dev/null +++ b/examples/stm32f4/src/bin/input_capture.rs | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; | ||
| 7 | use embassy_stm32::time::khz; | ||
| 8 | use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; | ||
| 9 | use embassy_stm32::timer::{self, Channel}; | ||
| 10 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 11 | use embassy_time::Timer; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | /// Connect PB2 and PB10 with a 1k Ohm resistor | ||
| 15 | |||
| 16 | #[embassy_executor::task] | ||
| 17 | async fn blinky(led: peripherals::PB2) { | ||
| 18 | let mut led = Output::new(led, Level::High, Speed::Low); | ||
| 19 | |||
| 20 | loop { | ||
| 21 | info!("high"); | ||
| 22 | led.set_high(); | ||
| 23 | Timer::after_millis(300).await; | ||
| 24 | |||
| 25 | info!("low"); | ||
| 26 | led.set_low(); | ||
| 27 | Timer::after_millis(300).await; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | bind_interrupts!(struct Irqs { | ||
| 32 | TIM2 => timer::CaptureCompareInterruptHandler<peripherals::TIM2>; | ||
| 33 | }); | ||
| 34 | |||
| 35 | #[embassy_executor::main] | ||
| 36 | async fn main(spawner: Spawner) { | ||
| 37 | let p = embassy_stm32::init(Default::default()); | ||
| 38 | info!("Hello World!"); | ||
| 39 | |||
| 40 | unwrap!(spawner.spawn(blinky(p.PB2))); | ||
| 41 | |||
| 42 | let ch3 = CapturePin::new_ch3(p.PB10, Pull::None); | ||
| 43 | let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default()); | ||
| 44 | |||
| 45 | loop { | ||
| 46 | info!("wait for risign edge"); | ||
| 47 | ic.wait_for_rising_edge(Channel::Ch3).await; | ||
| 48 | |||
| 49 | let capture_value = ic.get_capture_value(Channel::Ch3); | ||
| 50 | info!("new capture! {}", capture_value); | ||
| 51 | } | ||
| 52 | } | ||
diff --git a/examples/stm32f4/src/bin/spi.rs b/examples/stm32f4/src/bin/spi.rs index dc9141c62..970d819fc 100644 --- a/examples/stm32f4/src/bin/spi.rs +++ b/examples/stm32f4/src/bin/spi.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | use cortex_m_rt::entry; | 4 | use cortex_m_rt::entry; |
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 8 | use embassy_stm32::spi::{Config, Spi}; | 7 | use embassy_stm32::spi::{Config, Spi}; |
| 9 | use embassy_stm32::time::Hertz; | 8 | use embassy_stm32::time::Hertz; |
| @@ -18,7 +17,7 @@ fn main() -> ! { | |||
| 18 | let mut spi_config = Config::default(); | 17 | let mut spi_config = Config::default(); |
| 19 | spi_config.frequency = Hertz(1_000_000); | 18 | spi_config.frequency = Hertz(1_000_000); |
| 20 | 19 | ||
| 21 | let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); | 20 | let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); |
| 22 | 21 | ||
| 23 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); | 22 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); |
| 24 | 23 | ||
diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs index 40d9d70f1..991bf6673 100644 --- a/examples/stm32f4/src/bin/usart.rs +++ b/examples/stm32f4/src/bin/usart.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | use cortex_m_rt::entry; | 4 | use cortex_m_rt::entry; |
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::usart::{Config, Uart}; | 6 | use embassy_stm32::usart::{Config, Uart}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 7 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -19,7 +18,7 @@ fn main() -> ! { | |||
| 19 | let p = embassy_stm32::init(Default::default()); | 18 | let p = embassy_stm32::init(Default::default()); |
| 20 | 19 | ||
| 21 | let config = Config::default(); | 20 | let config = Config::default(); |
| 22 | let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, NoDma, NoDma, config).unwrap(); | 21 | let mut usart = Uart::new_blocking(p.USART3, p.PD9, p.PD8, config).unwrap(); |
| 23 | 22 | ||
| 24 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | 23 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); |
| 25 | info!("wrote Hello, starting echo"); | 24 | info!("wrote Hello, starting echo"); |
diff --git a/examples/stm32f4/src/bin/usart_dma.rs b/examples/stm32f4/src/bin/usart_dma.rs index dd6de599c..aaf8d6c4f 100644 --- a/examples/stm32f4/src/bin/usart_dma.rs +++ b/examples/stm32f4/src/bin/usart_dma.rs | |||
| @@ -5,7 +5,6 @@ use core::fmt::Write; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::dma::NoDma; | ||
| 9 | use embassy_stm32::usart::{Config, Uart}; | 8 | use embassy_stm32::usart::{Config, Uart}; |
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 11 | use heapless::String; | 10 | use heapless::String; |
| @@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) { | |||
| 21 | info!("Hello World!"); | 20 | info!("Hello World!"); |
| 22 | 21 | ||
| 23 | let config = Config::default(); | 22 | let config = Config::default(); |
| 24 | let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, p.DMA1_CH3, NoDma, config).unwrap(); | 23 | let mut usart = Uart::new(p.USART3, p.PD9, p.PD8, Irqs, p.DMA1_CH3, p.DMA1_CH1, config).unwrap(); |
| 25 | 24 | ||
| 26 | for n in 0u32.. { | 25 | for n in 0u32.. { |
| 27 | let mut s: String<128> = String::new(); | 26 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index d2cbeea1b..19ae16e8b 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs | |||
| @@ -40,6 +40,11 @@ bind_interrupts!(struct Irqs { | |||
| 40 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; | 40 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| 43 | // If you are trying this and your USB device doesn't connect, the most | ||
| 44 | // common issues are the RCC config and vbus_detection | ||
| 45 | // | ||
| 46 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 47 | // for more information. | ||
| 43 | #[embassy_executor::main] | 48 | #[embassy_executor::main] |
| 44 | async fn main(spawner: Spawner) { | 49 | async fn main(spawner: Spawner) { |
| 45 | info!("Hello World!"); | 50 | info!("Hello World!"); |
| @@ -71,7 +76,13 @@ async fn main(spawner: Spawner) { | |||
| 71 | static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); | 76 | static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); |
| 72 | let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; | 77 | let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; |
| 73 | let mut config = embassy_stm32::usb::Config::default(); | 78 | let mut config = embassy_stm32::usb::Config::default(); |
| 74 | config.vbus_detection = true; | 79 | |
| 80 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 81 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 82 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 83 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 84 | config.vbus_detection = false; | ||
| 85 | |||
| 75 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); | 86 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); |
| 76 | 87 | ||
| 77 | // Create embassy-usb Config | 88 | // Create embassy-usb Config |
diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index d6e0be5ea..537ff63ea 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs | |||
| @@ -5,6 +5,7 @@ use core::sync::atomic::{AtomicBool, Ordering}; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | ||
| 8 | use embassy_stm32::exti::ExtiInput; | 9 | use embassy_stm32::exti::ExtiInput; |
| 9 | use embassy_stm32::gpio::Pull; | 10 | use embassy_stm32::gpio::Pull; |
| 10 | use embassy_stm32::time::Hertz; | 11 | use embassy_stm32::time::Hertz; |
| @@ -13,7 +14,6 @@ use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | |||
| 13 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; | 14 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; |
| 14 | use embassy_usb::control::OutResponse; | 15 | use embassy_usb::control::OutResponse; |
| 15 | use embassy_usb::{Builder, Handler}; | 16 | use embassy_usb::{Builder, Handler}; |
| 16 | use futures::future::join; | ||
| 17 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | 17 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 19 | ||
| @@ -21,6 +21,11 @@ bind_interrupts!(struct Irqs { | |||
| 21 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 21 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 22 | }); | 22 | }); |
| 23 | 23 | ||
| 24 | // If you are trying this and your USB device doesn't connect, the most | ||
| 25 | // common issues are the RCC config and vbus_detection | ||
| 26 | // | ||
| 27 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 28 | // for more information. | ||
| 24 | #[embassy_executor::main] | 29 | #[embassy_executor::main] |
| 25 | async fn main(_spawner: Spawner) { | 30 | async fn main(_spawner: Spawner) { |
| 26 | let mut config = Config::default(); | 31 | let mut config = Config::default(); |
| @@ -49,8 +54,13 @@ async fn main(_spawner: Spawner) { | |||
| 49 | // Create the driver, from the HAL. | 54 | // Create the driver, from the HAL. |
| 50 | let mut ep_out_buffer = [0u8; 256]; | 55 | let mut ep_out_buffer = [0u8; 256]; |
| 51 | let mut config = embassy_stm32::usb::Config::default(); | 56 | let mut config = embassy_stm32::usb::Config::default(); |
| 52 | // If the board you’re using doesn’t have the VBUS pin wired up correctly for detecting the USB bus voltage (e.g. on the f4 blackpill board), set this to false | 57 | |
| 53 | config.vbus_detection = true; | 58 | // Do not enable vbus_detection. This is a safe default that works in all boards. |
| 59 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 60 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 61 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 62 | config.vbus_detection = false; | ||
| 63 | |||
| 54 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 64 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 55 | 65 | ||
| 56 | // Create embassy-usb Config | 66 | // Create embassy-usb Config |
| @@ -76,7 +86,7 @@ async fn main(_spawner: Spawner) { | |||
| 76 | let mut msos_descriptor = [0; 256]; | 86 | let mut msos_descriptor = [0; 256]; |
| 77 | let mut control_buf = [0; 64]; | 87 | let mut control_buf = [0; 64]; |
| 78 | 88 | ||
| 79 | let request_handler = MyRequestHandler {}; | 89 | let mut request_handler = MyRequestHandler {}; |
| 80 | let mut device_handler = MyDeviceHandler::new(); | 90 | let mut device_handler = MyDeviceHandler::new(); |
| 81 | 91 | ||
| 82 | let mut state = State::new(); | 92 | let mut state = State::new(); |
| @@ -95,7 +105,7 @@ async fn main(_spawner: Spawner) { | |||
| 95 | // Create classes on the builder. | 105 | // Create classes on the builder. |
| 96 | let config = embassy_usb::class::hid::Config { | 106 | let config = embassy_usb::class::hid::Config { |
| 97 | report_descriptor: KeyboardReport::desc(), | 107 | report_descriptor: KeyboardReport::desc(), |
| 98 | request_handler: Some(&request_handler), | 108 | request_handler: None, |
| 99 | poll_ms: 60, | 109 | poll_ms: 60, |
| 100 | max_packet_size: 8, | 110 | max_packet_size: 8, |
| 101 | }; | 111 | }; |
| @@ -148,7 +158,7 @@ async fn main(_spawner: Spawner) { | |||
| 148 | }; | 158 | }; |
| 149 | 159 | ||
| 150 | let out_fut = async { | 160 | let out_fut = async { |
| 151 | reader.run(false, &request_handler).await; | 161 | reader.run(false, &mut request_handler).await; |
| 152 | }; | 162 | }; |
| 153 | 163 | ||
| 154 | // Run everything concurrently. | 164 | // Run everything concurrently. |
| @@ -159,21 +169,21 @@ async fn main(_spawner: Spawner) { | |||
| 159 | struct MyRequestHandler {} | 169 | struct MyRequestHandler {} |
| 160 | 170 | ||
| 161 | impl RequestHandler for MyRequestHandler { | 171 | impl RequestHandler for MyRequestHandler { |
| 162 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 172 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 163 | info!("Get report for {:?}", id); | 173 | info!("Get report for {:?}", id); |
| 164 | None | 174 | None |
| 165 | } | 175 | } |
| 166 | 176 | ||
| 167 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 177 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 168 | info!("Set report for {:?}: {=[u8]}", id, data); | 178 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 169 | OutResponse::Accepted | 179 | OutResponse::Accepted |
| 170 | } | 180 | } |
| 171 | 181 | ||
| 172 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 182 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 173 | info!("Set idle rate for {:?} to {:?}", id, dur); | 183 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 174 | } | 184 | } |
| 175 | 185 | ||
| 176 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 186 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 177 | info!("Get idle rate for {:?}", id); | 187 | info!("Get idle rate for {:?}", id); |
| 178 | None | 188 | None |
| 179 | } | 189 | } |
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs index 0bc236119..df4b7426c 100644 --- a/examples/stm32f4/src/bin/usb_hid_mouse.rs +++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::Driver; | 8 | use embassy_stm32::usb::Driver; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| @@ -10,7 +11,6 @@ use embassy_time::Timer; | |||
| 10 | use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; | 11 | use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; |
| 11 | use embassy_usb::control::OutResponse; | 12 | use embassy_usb::control::OutResponse; |
| 12 | use embassy_usb::Builder; | 13 | use embassy_usb::Builder; |
| 13 | use futures::future::join; | ||
| 14 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; | 14 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; |
| 15 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 16 | 16 | ||
| @@ -18,6 +18,11 @@ bind_interrupts!(struct Irqs { | |||
| 18 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 18 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 19 | }); | 19 | }); |
| 20 | 20 | ||
| 21 | // If you are trying this and your USB device doesn't connect, the most | ||
| 22 | // common issues are the RCC config and vbus_detection | ||
| 23 | // | ||
| 24 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 25 | // for more information. | ||
| 21 | #[embassy_executor::main] | 26 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 27 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 28 | let mut config = Config::default(); |
| @@ -46,7 +51,13 @@ async fn main(_spawner: Spawner) { | |||
| 46 | // Create the driver, from the HAL. | 51 | // Create the driver, from the HAL. |
| 47 | let mut ep_out_buffer = [0u8; 256]; | 52 | let mut ep_out_buffer = [0u8; 256]; |
| 48 | let mut config = embassy_stm32::usb::Config::default(); | 53 | let mut config = embassy_stm32::usb::Config::default(); |
| 49 | config.vbus_detection = true; | 54 | |
| 55 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 56 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 57 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 58 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 59 | config.vbus_detection = false; | ||
| 60 | |||
| 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 61 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 51 | 62 | ||
| 52 | // Create embassy-usb Config | 63 | // Create embassy-usb Config |
| @@ -68,7 +79,7 @@ async fn main(_spawner: Spawner) { | |||
| 68 | let mut bos_descriptor = [0; 256]; | 79 | let mut bos_descriptor = [0; 256]; |
| 69 | let mut control_buf = [0; 64]; | 80 | let mut control_buf = [0; 64]; |
| 70 | 81 | ||
| 71 | let request_handler = MyRequestHandler {}; | 82 | let mut request_handler = MyRequestHandler {}; |
| 72 | 83 | ||
| 73 | let mut state = State::new(); | 84 | let mut state = State::new(); |
| 74 | 85 | ||
| @@ -84,7 +95,7 @@ async fn main(_spawner: Spawner) { | |||
| 84 | // Create classes on the builder. | 95 | // Create classes on the builder. |
| 85 | let config = embassy_usb::class::hid::Config { | 96 | let config = embassy_usb::class::hid::Config { |
| 86 | report_descriptor: MouseReport::desc(), | 97 | report_descriptor: MouseReport::desc(), |
| 87 | request_handler: Some(&request_handler), | 98 | request_handler: Some(&mut request_handler), |
| 88 | poll_ms: 60, | 99 | poll_ms: 60, |
| 89 | max_packet_size: 8, | 100 | max_packet_size: 8, |
| 90 | }; | 101 | }; |
| @@ -126,21 +137,21 @@ async fn main(_spawner: Spawner) { | |||
| 126 | struct MyRequestHandler {} | 137 | struct MyRequestHandler {} |
| 127 | 138 | ||
| 128 | impl RequestHandler for MyRequestHandler { | 139 | impl RequestHandler for MyRequestHandler { |
| 129 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 140 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 130 | info!("Get report for {:?}", id); | 141 | info!("Get report for {:?}", id); |
| 131 | None | 142 | None |
| 132 | } | 143 | } |
| 133 | 144 | ||
| 134 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 145 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 135 | info!("Set report for {:?}: {=[u8]}", id, data); | 146 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 136 | OutResponse::Accepted | 147 | OutResponse::Accepted |
| 137 | } | 148 | } |
| 138 | 149 | ||
| 139 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 150 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 140 | info!("Set idle rate for {:?} to {:?}", id, dur); | 151 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 141 | } | 152 | } |
| 142 | 153 | ||
| 143 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 154 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 144 | info!("Get idle rate for {:?}", id); | 155 | info!("Get idle rate for {:?}", id); |
| 145 | None | 156 | None |
| 146 | } | 157 | } |
diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index 4e583aeb8..1452e7c5f 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs | |||
| @@ -69,6 +69,11 @@ bind_interrupts!(struct Irqs { | |||
| 69 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 69 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 70 | }); | 70 | }); |
| 71 | 71 | ||
| 72 | // If you are trying this and your USB device doesn't connect, the most | ||
| 73 | // common issues are the RCC config and vbus_detection | ||
| 74 | // | ||
| 75 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 76 | // for more information. | ||
| 72 | #[embassy_executor::main] | 77 | #[embassy_executor::main] |
| 73 | async fn main(_spawner: Spawner) { | 78 | async fn main(_spawner: Spawner) { |
| 74 | info!("Hello World!"); | 79 | info!("Hello World!"); |
| @@ -99,7 +104,13 @@ async fn main(_spawner: Spawner) { | |||
| 99 | // Create the driver, from the HAL. | 104 | // Create the driver, from the HAL. |
| 100 | let mut ep_out_buffer = [0u8; 256]; | 105 | let mut ep_out_buffer = [0u8; 256]; |
| 101 | let mut config = embassy_stm32::usb::Config::default(); | 106 | let mut config = embassy_stm32::usb::Config::default(); |
| 102 | config.vbus_detection = true; | 107 | |
| 108 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 109 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 110 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 111 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 112 | config.vbus_detection = false; | ||
| 113 | |||
| 103 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 114 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 104 | 115 | ||
| 105 | // Create embassy-usb Config | 116 | // Create embassy-usb Config |
diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index f3a375d31..b2bd390b6 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs | |||
| @@ -3,19 +3,24 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 8 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 12 | use embassy_usb::Builder; |
| 12 | use futures::future::join; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | // If you are trying this and your USB device doesn't connect, the most | ||
| 20 | // common issues are the RCC config and vbus_detection | ||
| 21 | // | ||
| 22 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 23 | // for more information. | ||
| 19 | #[embassy_executor::main] | 24 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) { | 25 | async fn main(_spawner: Spawner) { |
| 21 | info!("Hello World!"); | 26 | info!("Hello World!"); |
| @@ -46,7 +51,13 @@ async fn main(_spawner: Spawner) { | |||
| 46 | // Create the driver, from the HAL. | 51 | // Create the driver, from the HAL. |
| 47 | let mut ep_out_buffer = [0u8; 256]; | 52 | let mut ep_out_buffer = [0u8; 256]; |
| 48 | let mut config = embassy_stm32::usb::Config::default(); | 53 | let mut config = embassy_stm32::usb::Config::default(); |
| 49 | config.vbus_detection = true; | 54 | |
| 55 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 56 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 57 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 58 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 59 | config.vbus_detection = false; | ||
| 60 | |||
| 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 61 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 51 | 62 | ||
| 52 | // Create embassy-usb Config | 63 | // Create embassy-usb Config |
diff --git a/examples/stm32f4/src/bin/ws2812_spi.rs b/examples/stm32f4/src/bin/ws2812_spi.rs index a280a3b77..e00d14327 100644 --- a/examples/stm32f4/src/bin/ws2812_spi.rs +++ b/examples/stm32f4/src/bin/ws2812_spi.rs | |||
| @@ -8,13 +8,13 @@ | |||
| 8 | // If you want to save SPI for other purpose, you may want to take a look at `ws2812_pwm_dma.rs` file, which make use of TIM and DMA. | 8 | // If you want to save SPI for other purpose, you may want to take a look at `ws2812_pwm_dma.rs` file, which make use of TIM and DMA. |
| 9 | // | 9 | // |
| 10 | // Warning: | 10 | // Warning: |
| 11 | // DO NOT stare at ws2812 directy (especially after each MCU Reset), its (max) brightness could easily make your eyes feel burn. | 11 | // DO NOT stare at ws2812 directly (especially after each MCU Reset), its (max) brightness could easily make your eyes feel burn. |
| 12 | 12 | ||
| 13 | #![no_std] | 13 | #![no_std] |
| 14 | #![no_main] | 14 | #![no_main] |
| 15 | 15 | ||
| 16 | use embassy_stm32::spi; | ||
| 16 | use embassy_stm32::time::khz; | 17 | use embassy_stm32::time::khz; |
| 17 | use embassy_stm32::{dma, spi}; | ||
| 18 | use embassy_time::{Duration, Ticker, Timer}; | 18 | use embassy_time::{Duration, Ticker, Timer}; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | 20 | ||
| @@ -78,7 +78,7 @@ async fn main(_spawner: embassy_executor::Spawner) { | |||
| 78 | spi_config.frequency = khz(12_800); | 78 | spi_config.frequency = khz(12_800); |
| 79 | 79 | ||
| 80 | // Since we only output waveform, then the Rx and Sck and RxDma it is not considered | 80 | // Since we only output waveform, then the Rx and Sck and RxDma it is not considered |
| 81 | let mut ws2812_spi = spi::Spi::new_txonly_nosck(dp.SPI1, dp.PB5, dp.DMA2_CH3, dma::NoDma, spi_config); | 81 | let mut ws2812_spi = spi::Spi::new_txonly_nosck(dp.SPI1, dp.PB5, dp.DMA2_CH3, spi_config); |
| 82 | 82 | ||
| 83 | // flip color at 2 Hz | 83 | // flip color at 2 Hz |
| 84 | let mut ticker = Ticker::every(Duration::from_millis(500)); | 84 | let mut ticker = Ticker::every(Duration::from_millis(500)); |
diff --git a/examples/stm32f469/.cargo/config.toml b/examples/stm32f469/.cargo/config.toml new file mode 100644 index 000000000..05250954f --- /dev/null +++ b/examples/stm32f469/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --chip STM32F469NIHx" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace" | ||
diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml new file mode 100644 index 000000000..7718a46c1 --- /dev/null +++ b/examples/stm32f469/Cargo.toml | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-stm32f469-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | # Specific examples only for stm32f469 | ||
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } | ||
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
| 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | ||
| 12 | |||
| 13 | defmt = "0.3" | ||
| 14 | defmt-rtt = "0.4" | ||
| 15 | |||
| 16 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 17 | cortex-m-rt = "0.7.0" | ||
| 18 | embedded-hal = "1.0.0" | ||
| 19 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 20 | |||
| 21 | [profile.release] | ||
| 22 | debug = 2 | ||
diff --git a/examples/stm32f469/build.rs b/examples/stm32f469/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32f469/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/stm32f469/src/bin/dsi_bsp.rs b/examples/stm32f469/src/bin/dsi_bsp.rs new file mode 100644 index 000000000..e4e9e9c01 --- /dev/null +++ b/examples/stm32f469/src/bin/dsi_bsp.rs | |||
| @@ -0,0 +1,694 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::dsihost::{blocking_delay_ms, DsiHost, PacketType}; | ||
| 7 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 8 | use embassy_stm32::ltdc::Ltdc; | ||
| 9 | use embassy_stm32::pac::dsihost::regs::{Ier0, Ier1}; | ||
| 10 | use embassy_stm32::pac::ltdc::vals::{Bf1, Bf2, Depol, Hspol, Imr, Pcpol, Pf, Vspol}; | ||
| 11 | use embassy_stm32::pac::{DSIHOST, LTDC}; | ||
| 12 | use embassy_stm32::rcc::{ | ||
| 13 | AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk, | ||
| 14 | }; | ||
| 15 | use embassy_stm32::time::mhz; | ||
| 16 | use embassy_time::Timer; | ||
| 17 | use {defmt_rtt as _, panic_probe as _}; | ||
| 18 | |||
| 19 | enum _Orientation { | ||
| 20 | Landscape, | ||
| 21 | Portrait, | ||
| 22 | } | ||
| 23 | |||
| 24 | const _LCD_ORIENTATION: _Orientation = _Orientation::Landscape; | ||
| 25 | const LCD_X_SIZE: u16 = 800; | ||
| 26 | const LCD_Y_SIZE: u16 = 480; | ||
| 27 | |||
| 28 | static FERRIS_IMAGE: &[u8; 1536000] = include_bytes!("ferris.bin"); | ||
| 29 | |||
| 30 | // This example allows to display an image on the STM32F469NI-DISCO boards | ||
| 31 | // with the Revision C, that is at least the boards marked DK32F469I$AU1. | ||
| 32 | // These boards have the NT35510 display driver. This example does not work | ||
| 33 | // for the older revisions with OTM8009A, though there are lots of C-examples | ||
| 34 | // available online where the correct config for the OTM8009A could be gotten from. | ||
| 35 | #[embassy_executor::main] | ||
| 36 | async fn main(_spawner: Spawner) { | ||
| 37 | let mut config = embassy_stm32::Config::default(); | ||
| 38 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 39 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 40 | config.rcc.apb1_pre = APBPrescaler::DIV4; | ||
| 41 | config.rcc.apb2_pre = APBPrescaler::DIV2; | ||
| 42 | |||
| 43 | // HSE is on and ready | ||
| 44 | config.rcc.hse = Some(Hse { | ||
| 45 | freq: mhz(8), | ||
| 46 | mode: HseMode::Oscillator, | ||
| 47 | }); | ||
| 48 | config.rcc.pll_src = PllSource::HSE; | ||
| 49 | |||
| 50 | config.rcc.pll = Some(Pll { | ||
| 51 | prediv: PllPreDiv::DIV8, // PLLM | ||
| 52 | mul: PllMul::MUL360, // PLLN | ||
| 53 | divp: Some(PllPDiv::DIV2), | ||
| 54 | divq: Some(PllQDiv::DIV7), // was DIV4, but STM BSP example uses 7 | ||
| 55 | divr: Some(PllRDiv::DIV6), | ||
| 56 | }); | ||
| 57 | |||
| 58 | // This seems to be working, the values in the RCC.PLLSAICFGR are correct according to the debugger. Also on and ready according to CR | ||
| 59 | config.rcc.pllsai = Some(Pll { | ||
| 60 | prediv: PllPreDiv::DIV8, // Actually ignored | ||
| 61 | mul: PllMul::MUL384, // PLLN | ||
| 62 | divp: None, // PLLP | ||
| 63 | divq: None, // PLLQ | ||
| 64 | divr: Some(PllRDiv::DIV7), // PLLR (Sai actually has special clockdiv register) | ||
| 65 | }); | ||
| 66 | |||
| 67 | let p = embassy_stm32::init(config); | ||
| 68 | info!("Starting..."); | ||
| 69 | |||
| 70 | let mut led = Output::new(p.PG6, Level::High, Speed::Low); | ||
| 71 | |||
| 72 | // According to UM for the discovery kit, PH7 is an active-low reset for the LCD and touchsensor | ||
| 73 | let mut reset = Output::new(p.PH7, Level::Low, Speed::High); | ||
| 74 | |||
| 75 | // CubeMX example waits 20 ms before de-asserting reset | ||
| 76 | embassy_time::block_for(embassy_time::Duration::from_millis(20)); | ||
| 77 | |||
| 78 | // Disable the reset signal and wait 140ms as in the Linux driver (CubeMX waits only 20) | ||
| 79 | reset.set_high(); | ||
| 80 | embassy_time::block_for(embassy_time::Duration::from_millis(140)); | ||
| 81 | |||
| 82 | let mut ltdc = Ltdc::new(p.LTDC); | ||
| 83 | let mut dsi = DsiHost::new(p.DSIHOST, p.PJ2); | ||
| 84 | let version = dsi.get_version(); | ||
| 85 | defmt::warn!("en: {:x}", version); | ||
| 86 | |||
| 87 | // Disable the DSI wrapper | ||
| 88 | dsi.disable_wrapper_dsi(); | ||
| 89 | |||
| 90 | // Disable the DSI host | ||
| 91 | dsi.disable(); | ||
| 92 | |||
| 93 | // D-PHY clock and digital disable | ||
| 94 | DSIHOST.pctlr().modify(|w| { | ||
| 95 | w.set_cke(false); | ||
| 96 | w.set_den(false) | ||
| 97 | }); | ||
| 98 | |||
| 99 | // Turn off the DSI PLL | ||
| 100 | DSIHOST.wrpcr().modify(|w| w.set_pllen(false)); | ||
| 101 | |||
| 102 | // Disable the regulator | ||
| 103 | DSIHOST.wrpcr().write(|w| w.set_regen(false)); | ||
| 104 | |||
| 105 | // Enable regulator | ||
| 106 | info!("DSIHOST: enabling regulator"); | ||
| 107 | DSIHOST.wrpcr().write(|w| w.set_regen(true)); | ||
| 108 | |||
| 109 | for _ in 1..1000 { | ||
| 110 | // The regulator status (ready or not) can be monitored with the RRS flag in the DSI_WISR register. | ||
| 111 | // Once it is set, we stop waiting. | ||
| 112 | if DSIHOST.wisr().read().rrs() { | ||
| 113 | info!("DSIHOST Regulator ready"); | ||
| 114 | break; | ||
| 115 | } | ||
| 116 | embassy_time::block_for(embassy_time::Duration::from_millis(1)); | ||
| 117 | } | ||
| 118 | |||
| 119 | if !DSIHOST.wisr().read().rrs() { | ||
| 120 | defmt::panic!("DSIHOST: enabling regulator FAILED"); | ||
| 121 | } | ||
| 122 | |||
| 123 | // Set up PLL and enable it | ||
| 124 | DSIHOST.wrpcr().modify(|w| { | ||
| 125 | w.set_pllen(true); | ||
| 126 | w.set_ndiv(125); // PLL loop division factor set to 125 | ||
| 127 | w.set_idf(2); // PLL input divided by 2 | ||
| 128 | w.set_odf(0); // PLL output divided by 1 | ||
| 129 | }); | ||
| 130 | |||
| 131 | /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */ | ||
| 132 | const LANE_BYTE_CLK_K_HZ: u16 = 62500; // https://github.com/STMicroelectronics/32f469idiscovery-bsp/blob/ec051de2bff3e1b73a9ccd49c9b85abf7320add9/stm32469i_discovery_lcd.c#L224C21-L224C26 | ||
| 133 | |||
| 134 | const _LCD_CLOCK: u16 = 27429; // https://github.com/STMicroelectronics/32f469idiscovery-bsp/blob/ec051de2bff3e1b73a9ccd49c9b85abf7320add9/stm32469i_discovery_lcd.c#L183 | ||
| 135 | |||
| 136 | /* TX_ESCAPE_CKDIV = f(LaneByteClk)/15.62 = 4 */ | ||
| 137 | const TX_ESCAPE_CKDIV: u8 = (LANE_BYTE_CLK_K_HZ / 15620) as u8; // https://github.com/STMicroelectronics/32f469idiscovery-bsp/blob/ec051de2bff3e1b73a9ccd49c9b85abf7320add9/stm32469i_discovery_lcd.c#L230 | ||
| 138 | |||
| 139 | for _ in 1..1000 { | ||
| 140 | embassy_time::block_for(embassy_time::Duration::from_millis(1)); | ||
| 141 | // The PLL status (lock or unlock) can be monitored with the PLLLS flag in the DSI_WISR register. | ||
| 142 | // Once it is set, we stop waiting. | ||
| 143 | if DSIHOST.wisr().read().pllls() { | ||
| 144 | info!("DSIHOST PLL locked"); | ||
| 145 | break; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | if !DSIHOST.wisr().read().pllls() { | ||
| 150 | defmt::panic!("DSIHOST: enabling PLL FAILED"); | ||
| 151 | } | ||
| 152 | |||
| 153 | // Set the PHY parameters | ||
| 154 | |||
| 155 | // D-PHY clock and digital enable | ||
| 156 | DSIHOST.pctlr().write(|w| { | ||
| 157 | w.set_cke(true); | ||
| 158 | w.set_den(true); | ||
| 159 | }); | ||
| 160 | |||
| 161 | // Set Clock lane to high-speed mode and disable automatic clock lane control | ||
| 162 | DSIHOST.clcr().modify(|w| { | ||
| 163 | w.set_dpcc(true); | ||
| 164 | w.set_acr(false); | ||
| 165 | }); | ||
| 166 | |||
| 167 | // Set number of active data lanes to two (lanes 0 and 1) | ||
| 168 | DSIHOST.pconfr().modify(|w| w.set_nl(1)); | ||
| 169 | |||
| 170 | // Set the DSI clock parameters | ||
| 171 | |||
| 172 | // Set the TX escape clock division factor to 4 | ||
| 173 | DSIHOST.ccr().modify(|w| w.set_txeckdiv(TX_ESCAPE_CKDIV)); | ||
| 174 | |||
| 175 | // Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) | ||
| 176 | // The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 ) | ||
| 177 | // Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF) | ||
| 178 | // Set the bit period in high-speed mode | ||
| 179 | DSIHOST.wpcr0().modify(|w| w.set_uix4(8)); // 8 is set in the BSP example (confirmed with Debugger) | ||
| 180 | |||
| 181 | // Disable all error interrupts and reset the Error Mask | ||
| 182 | DSIHOST.ier0().write_value(Ier0(0)); | ||
| 183 | DSIHOST.ier1().write_value(Ier1(0)); | ||
| 184 | |||
| 185 | // Enable this to fix read timeout | ||
| 186 | DSIHOST.pcr().modify(|w| w.set_btae(true)); | ||
| 187 | |||
| 188 | const DSI_PIXEL_FORMAT_RGB888: u8 = 0x05; | ||
| 189 | const _DSI_PIXEL_FORMAT_ARGB888: u8 = 0x00; | ||
| 190 | |||
| 191 | const HACT: u16 = LCD_X_SIZE; | ||
| 192 | const VACT: u16 = LCD_Y_SIZE; | ||
| 193 | |||
| 194 | const VSA: u16 = 120; | ||
| 195 | const VBP: u16 = 150; | ||
| 196 | const VFP: u16 = 150; | ||
| 197 | const HSA: u16 = 2; | ||
| 198 | const HBP: u16 = 34; | ||
| 199 | const HFP: u16 = 34; | ||
| 200 | |||
| 201 | const VIRTUAL_CHANNEL_ID: u8 = 0; | ||
| 202 | |||
| 203 | const COLOR_CODING: u8 = DSI_PIXEL_FORMAT_RGB888; | ||
| 204 | const VS_POLARITY: bool = false; // DSI_VSYNC_ACTIVE_HIGH == 0 | ||
| 205 | const HS_POLARITY: bool = false; // DSI_HSYNC_ACTIVE_HIGH == 0 | ||
| 206 | const DE_POLARITY: bool = false; // DSI_DATA_ENABLE_ACTIVE_HIGH == 0 | ||
| 207 | const MODE: u8 = 2; // DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */ | ||
| 208 | const NULL_PACKET_SIZE: u16 = 0xFFF; | ||
| 209 | const NUMBER_OF_CHUNKS: u16 = 0; | ||
| 210 | const PACKET_SIZE: u16 = HACT; /* Value depending on display orientation choice portrait/landscape */ | ||
| 211 | const HORIZONTAL_SYNC_ACTIVE: u16 = 4; // ((HSA as u32 * LANE_BYTE_CLK_K_HZ as u32 ) / LCD_CLOCK as u32 ) as u16; | ||
| 212 | const HORIZONTAL_BACK_PORCH: u16 = 77; //((HBP as u32 * LANE_BYTE_CLK_K_HZ as u32 ) / LCD_CLOCK as u32) as u16; | ||
| 213 | const HORIZONTAL_LINE: u16 = 1982; //(((HACT + HSA + HBP + HFP) as u32 * LANE_BYTE_CLK_K_HZ as u32 ) / LCD_CLOCK as u32 ) as u16; /* Value depending on display orientation choice portrait/landscape */ | ||
| 214 | // FIXME: Make depend on orientation | ||
| 215 | const VERTICAL_SYNC_ACTIVE: u16 = VSA; | ||
| 216 | const VERTICAL_BACK_PORCH: u16 = VBP; | ||
| 217 | const VERTICAL_FRONT_PORCH: u16 = VFP; | ||
| 218 | const VERTICAL_ACTIVE: u16 = VACT; | ||
| 219 | const LP_COMMAND_ENABLE: bool = true; /* Enable sending commands in mode LP (Low Power) */ | ||
| 220 | |||
| 221 | /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */ | ||
| 222 | /* Only useful when sending LP packets is allowed while streaming is active in video mode */ | ||
| 223 | const LP_LARGEST_PACKET_SIZE: u8 = 16; | ||
| 224 | |||
| 225 | /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */ | ||
| 226 | /* Only useful when sending LP packets is allowed while streaming is active in video mode */ | ||
| 227 | const LPVACT_LARGEST_PACKET_SIZE: u8 = 0; | ||
| 228 | |||
| 229 | const LPHORIZONTAL_FRONT_PORCH_ENABLE: bool = true; /* Allow sending LP commands during HFP period */ | ||
| 230 | const LPHORIZONTAL_BACK_PORCH_ENABLE: bool = true; /* Allow sending LP commands during HBP period */ | ||
| 231 | const LPVERTICAL_ACTIVE_ENABLE: bool = true; /* Allow sending LP commands during VACT period */ | ||
| 232 | const LPVERTICAL_FRONT_PORCH_ENABLE: bool = true; /* Allow sending LP commands during VFP period */ | ||
| 233 | const LPVERTICAL_BACK_PORCH_ENABLE: bool = true; /* Allow sending LP commands during VBP period */ | ||
| 234 | const LPVERTICAL_SYNC_ACTIVE_ENABLE: bool = true; /* Allow sending LP commands during VSync = VSA period */ | ||
| 235 | const FRAME_BTAACKNOWLEDGE_ENABLE: bool = false; /* Frame bus-turn-around acknowledge enable => false according to debugger */ | ||
| 236 | |||
| 237 | /* Select video mode by resetting CMDM and DSIM bits */ | ||
| 238 | DSIHOST.mcr().modify(|w| w.set_cmdm(false)); | ||
| 239 | DSIHOST.wcfgr().modify(|w| w.set_dsim(false)); | ||
| 240 | |||
| 241 | /* Configure the video mode transmission type */ | ||
| 242 | DSIHOST.vmcr().modify(|w| w.set_vmt(MODE)); | ||
| 243 | |||
| 244 | /* Configure the video packet size */ | ||
| 245 | DSIHOST.vpcr().modify(|w| w.set_vpsize(PACKET_SIZE)); | ||
| 246 | |||
| 247 | /* Set the chunks number to be transmitted through the DSI link */ | ||
| 248 | DSIHOST.vccr().modify(|w| w.set_numc(NUMBER_OF_CHUNKS)); | ||
| 249 | |||
| 250 | /* Set the size of the null packet */ | ||
| 251 | DSIHOST.vnpcr().modify(|w| w.set_npsize(NULL_PACKET_SIZE)); | ||
| 252 | |||
| 253 | /* Select the virtual channel for the LTDC interface traffic */ | ||
| 254 | DSIHOST.lvcidr().modify(|w| w.set_vcid(VIRTUAL_CHANNEL_ID)); | ||
| 255 | |||
| 256 | /* Configure the polarity of control signals */ | ||
| 257 | DSIHOST.lpcr().modify(|w| { | ||
| 258 | w.set_dep(DE_POLARITY); | ||
| 259 | w.set_hsp(HS_POLARITY); | ||
| 260 | w.set_vsp(VS_POLARITY); | ||
| 261 | }); | ||
| 262 | |||
| 263 | /* Select the color coding for the host */ | ||
| 264 | DSIHOST.lcolcr().modify(|w| w.set_colc(COLOR_CODING)); | ||
| 265 | |||
| 266 | /* Select the color coding for the wrapper */ | ||
| 267 | DSIHOST.wcfgr().modify(|w| w.set_colmux(COLOR_CODING)); | ||
| 268 | |||
| 269 | /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */ | ||
| 270 | DSIHOST.vhsacr().modify(|w| w.set_hsa(HORIZONTAL_SYNC_ACTIVE)); | ||
| 271 | |||
| 272 | /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */ | ||
| 273 | DSIHOST.vhbpcr().modify(|w| w.set_hbp(HORIZONTAL_BACK_PORCH)); | ||
| 274 | |||
| 275 | /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */ | ||
| 276 | DSIHOST.vlcr().modify(|w| w.set_hline(HORIZONTAL_LINE)); | ||
| 277 | |||
| 278 | /* Set the Vertical Synchronization Active (VSA) */ | ||
| 279 | DSIHOST.vvsacr().modify(|w| w.set_vsa(VERTICAL_SYNC_ACTIVE)); | ||
| 280 | |||
| 281 | /* Set the Vertical Back Porch (VBP)*/ | ||
| 282 | DSIHOST.vvbpcr().modify(|w| w.set_vbp(VERTICAL_BACK_PORCH)); | ||
| 283 | |||
| 284 | /* Set the Vertical Front Porch (VFP)*/ | ||
| 285 | DSIHOST.vvfpcr().modify(|w| w.set_vfp(VERTICAL_FRONT_PORCH)); | ||
| 286 | |||
| 287 | /* Set the Vertical Active period*/ | ||
| 288 | DSIHOST.vvacr().modify(|w| w.set_va(VERTICAL_ACTIVE)); | ||
| 289 | |||
| 290 | /* Configure the command transmission mode */ | ||
| 291 | DSIHOST.vmcr().modify(|w| w.set_lpce(LP_COMMAND_ENABLE)); | ||
| 292 | |||
| 293 | /* Low power largest packet size */ | ||
| 294 | DSIHOST.lpmcr().modify(|w| w.set_lpsize(LP_LARGEST_PACKET_SIZE)); | ||
| 295 | |||
| 296 | /* Low power VACT largest packet size */ | ||
| 297 | DSIHOST.lpmcr().modify(|w| w.set_lpsize(LP_LARGEST_PACKET_SIZE)); | ||
| 298 | DSIHOST.lpmcr().modify(|w| w.set_vlpsize(LPVACT_LARGEST_PACKET_SIZE)); | ||
| 299 | |||
| 300 | /* Enable LP transition in HFP period */ | ||
| 301 | DSIHOST.vmcr().modify(|w| w.set_lphfpe(LPHORIZONTAL_FRONT_PORCH_ENABLE)); | ||
| 302 | |||
| 303 | /* Enable LP transition in HBP period */ | ||
| 304 | DSIHOST.vmcr().modify(|w| w.set_lphbpe(LPHORIZONTAL_BACK_PORCH_ENABLE)); | ||
| 305 | |||
| 306 | /* Enable LP transition in VACT period */ | ||
| 307 | DSIHOST.vmcr().modify(|w| w.set_lpvae(LPVERTICAL_ACTIVE_ENABLE)); | ||
| 308 | |||
| 309 | /* Enable LP transition in VFP period */ | ||
| 310 | DSIHOST.vmcr().modify(|w| w.set_lpvfpe(LPVERTICAL_FRONT_PORCH_ENABLE)); | ||
| 311 | |||
| 312 | /* Enable LP transition in VBP period */ | ||
| 313 | DSIHOST.vmcr().modify(|w| w.set_lpvbpe(LPVERTICAL_BACK_PORCH_ENABLE)); | ||
| 314 | |||
| 315 | /* Enable LP transition in vertical sync period */ | ||
| 316 | DSIHOST.vmcr().modify(|w| w.set_lpvsae(LPVERTICAL_SYNC_ACTIVE_ENABLE)); | ||
| 317 | |||
| 318 | /* Enable the request for an acknowledge response at the end of a frame */ | ||
| 319 | DSIHOST.vmcr().modify(|w| w.set_fbtaae(FRAME_BTAACKNOWLEDGE_ENABLE)); | ||
| 320 | |||
| 321 | /* Configure DSI PHY HS2LP and LP2HS timings */ | ||
| 322 | const CLOCK_LANE_HS2_LPTIME: u16 = 35; | ||
| 323 | const CLOCK_LANE_LP2_HSTIME: u16 = 35; | ||
| 324 | const DATA_LANE_HS2_LPTIME: u8 = 35; | ||
| 325 | const DATA_LANE_LP2_HSTIME: u8 = 35; | ||
| 326 | const DATA_LANE_MAX_READ_TIME: u16 = 0; | ||
| 327 | const STOP_WAIT_TIME: u8 = 10; | ||
| 328 | |||
| 329 | const MAX_TIME: u16 = if CLOCK_LANE_HS2_LPTIME > CLOCK_LANE_LP2_HSTIME { | ||
| 330 | CLOCK_LANE_HS2_LPTIME | ||
| 331 | } else { | ||
| 332 | CLOCK_LANE_LP2_HSTIME | ||
| 333 | }; | ||
| 334 | |||
| 335 | /* Clock lane timer configuration */ | ||
| 336 | |||
| 337 | /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two | ||
| 338 | High-Speed transmission. | ||
| 339 | To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed | ||
| 340 | to Low-Power and from Low-Power to High-Speed. | ||
| 341 | This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration | ||
| 342 | Register (DSI_CLTCR). | ||
| 343 | But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME. | ||
| 344 | |||
| 345 | Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME. | ||
| 346 | */ | ||
| 347 | |||
| 348 | DSIHOST.cltcr().modify(|w| { | ||
| 349 | w.set_hs2lp_time(MAX_TIME); | ||
| 350 | w.set_lp2hs_time(MAX_TIME) | ||
| 351 | }); | ||
| 352 | |||
| 353 | // Data lane timer configuration | ||
| 354 | DSIHOST.dltcr().modify(|w| { | ||
| 355 | w.set_hs2lp_time(DATA_LANE_HS2_LPTIME); | ||
| 356 | w.set_lp2hs_time(DATA_LANE_LP2_HSTIME); | ||
| 357 | w.set_mrd_time(DATA_LANE_MAX_READ_TIME); | ||
| 358 | }); | ||
| 359 | |||
| 360 | // Configure the wait period to request HS transmission after a stop state | ||
| 361 | DSIHOST.pconfr().modify(|w| w.set_sw_time(STOP_WAIT_TIME)); | ||
| 362 | |||
| 363 | const _PCPOLARITY: bool = false; // LTDC_PCPOLARITY_IPC == 0 | ||
| 364 | |||
| 365 | const LTDC_DE_POLARITY: Depol = if !DE_POLARITY { | ||
| 366 | Depol::ACTIVELOW | ||
| 367 | } else { | ||
| 368 | Depol::ACTIVEHIGH | ||
| 369 | }; | ||
| 370 | const LTDC_VS_POLARITY: Vspol = if !VS_POLARITY { | ||
| 371 | Vspol::ACTIVEHIGH | ||
| 372 | } else { | ||
| 373 | Vspol::ACTIVELOW | ||
| 374 | }; | ||
| 375 | |||
| 376 | const LTDC_HS_POLARITY: Hspol = if !HS_POLARITY { | ||
| 377 | Hspol::ACTIVEHIGH | ||
| 378 | } else { | ||
| 379 | Hspol::ACTIVELOW | ||
| 380 | }; | ||
| 381 | |||
| 382 | /* Timing Configuration */ | ||
| 383 | const HORIZONTAL_SYNC: u16 = HSA - 1; | ||
| 384 | const VERTICAL_SYNC: u16 = VERTICAL_SYNC_ACTIVE - 1; | ||
| 385 | const ACCUMULATED_HBP: u16 = HSA + HBP - 1; | ||
| 386 | const ACCUMULATED_VBP: u16 = VERTICAL_SYNC_ACTIVE + VERTICAL_BACK_PORCH - 1; | ||
| 387 | const ACCUMULATED_ACTIVE_W: u16 = LCD_X_SIZE + HSA + HBP - 1; | ||
| 388 | const ACCUMULATED_ACTIVE_H: u16 = VERTICAL_SYNC_ACTIVE + VERTICAL_BACK_PORCH + VERTICAL_ACTIVE - 1; | ||
| 389 | const TOTAL_WIDTH: u16 = LCD_X_SIZE + HSA + HBP + HFP - 1; | ||
| 390 | const TOTAL_HEIGHT: u16 = VERTICAL_SYNC_ACTIVE + VERTICAL_BACK_PORCH + VERTICAL_ACTIVE + VERTICAL_FRONT_PORCH - 1; | ||
| 391 | |||
| 392 | // DISABLE LTDC before making changes | ||
| 393 | ltdc.disable(); | ||
| 394 | |||
| 395 | // Configure the HS, VS, DE and PC polarity | ||
| 396 | LTDC.gcr().modify(|w| { | ||
| 397 | w.set_hspol(LTDC_HS_POLARITY); | ||
| 398 | w.set_vspol(LTDC_VS_POLARITY); | ||
| 399 | w.set_depol(LTDC_DE_POLARITY); | ||
| 400 | w.set_pcpol(Pcpol::RISINGEDGE); | ||
| 401 | }); | ||
| 402 | |||
| 403 | // Set Synchronization size | ||
| 404 | LTDC.sscr().modify(|w| { | ||
| 405 | w.set_hsw(HORIZONTAL_SYNC); | ||
| 406 | w.set_vsh(VERTICAL_SYNC) | ||
| 407 | }); | ||
| 408 | |||
| 409 | // Set Accumulated Back porch | ||
| 410 | LTDC.bpcr().modify(|w| { | ||
| 411 | w.set_ahbp(ACCUMULATED_HBP); | ||
| 412 | w.set_avbp(ACCUMULATED_VBP); | ||
| 413 | }); | ||
| 414 | |||
| 415 | // Set Accumulated Active Width | ||
| 416 | LTDC.awcr().modify(|w| { | ||
| 417 | w.set_aah(ACCUMULATED_ACTIVE_H); | ||
| 418 | w.set_aaw(ACCUMULATED_ACTIVE_W); | ||
| 419 | }); | ||
| 420 | |||
| 421 | // Set Total Width | ||
| 422 | LTDC.twcr().modify(|w| { | ||
| 423 | w.set_totalh(TOTAL_HEIGHT); | ||
| 424 | w.set_totalw(TOTAL_WIDTH); | ||
| 425 | }); | ||
| 426 | |||
| 427 | // Set the background color value | ||
| 428 | LTDC.bccr().modify(|w| { | ||
| 429 | w.set_bcred(0); | ||
| 430 | w.set_bcgreen(0); | ||
| 431 | w.set_bcblue(0) | ||
| 432 | }); | ||
| 433 | |||
| 434 | // Enable the Transfer Error and FIFO underrun interrupts | ||
| 435 | LTDC.ier().modify(|w| { | ||
| 436 | w.set_terrie(true); | ||
| 437 | w.set_fuie(true); | ||
| 438 | }); | ||
| 439 | |||
| 440 | // ENABLE LTDC after making changes | ||
| 441 | ltdc.enable(); | ||
| 442 | |||
| 443 | dsi.enable(); | ||
| 444 | dsi.enable_wrapper_dsi(); | ||
| 445 | |||
| 446 | // First, delay 120 ms (reason unknown, STM32 Cube Example does it) | ||
| 447 | blocking_delay_ms(120); | ||
| 448 | |||
| 449 | // 1 to 26 | ||
| 450 | dsi.write_cmd(0, NT35510_WRITES_0[0], &NT35510_WRITES_0[1..]).unwrap(); | ||
| 451 | dsi.write_cmd(0, NT35510_WRITES_1[0], &NT35510_WRITES_1[1..]).unwrap(); | ||
| 452 | dsi.write_cmd(0, NT35510_WRITES_2[0], &NT35510_WRITES_2[1..]).unwrap(); | ||
| 453 | dsi.write_cmd(0, NT35510_WRITES_3[0], &NT35510_WRITES_3[1..]).unwrap(); | ||
| 454 | dsi.write_cmd(0, NT35510_WRITES_4[0], &NT35510_WRITES_4[1..]).unwrap(); | ||
| 455 | dsi.write_cmd(0, NT35510_WRITES_5[0], &NT35510_WRITES_5[1..]).unwrap(); | ||
| 456 | dsi.write_cmd(0, NT35510_WRITES_6[0], &NT35510_WRITES_6[1..]).unwrap(); | ||
| 457 | dsi.write_cmd(0, NT35510_WRITES_7[0], &NT35510_WRITES_7[1..]).unwrap(); | ||
| 458 | dsi.write_cmd(0, NT35510_WRITES_8[0], &NT35510_WRITES_8[1..]).unwrap(); | ||
| 459 | dsi.write_cmd(0, NT35510_WRITES_9[0], &NT35510_WRITES_9[1..]).unwrap(); | ||
| 460 | dsi.write_cmd(0, NT35510_WRITES_10[0], &NT35510_WRITES_10[1..]).unwrap(); | ||
| 461 | // 11 missing | ||
| 462 | dsi.write_cmd(0, NT35510_WRITES_12[0], &NT35510_WRITES_12[1..]).unwrap(); | ||
| 463 | dsi.write_cmd(0, NT35510_WRITES_13[0], &NT35510_WRITES_13[1..]).unwrap(); | ||
| 464 | dsi.write_cmd(0, NT35510_WRITES_14[0], &NT35510_WRITES_14[1..]).unwrap(); | ||
| 465 | dsi.write_cmd(0, NT35510_WRITES_15[0], &NT35510_WRITES_15[1..]).unwrap(); | ||
| 466 | dsi.write_cmd(0, NT35510_WRITES_16[0], &NT35510_WRITES_16[1..]).unwrap(); | ||
| 467 | dsi.write_cmd(0, NT35510_WRITES_17[0], &NT35510_WRITES_17[1..]).unwrap(); | ||
| 468 | dsi.write_cmd(0, NT35510_WRITES_18[0], &NT35510_WRITES_18[1..]).unwrap(); | ||
| 469 | dsi.write_cmd(0, NT35510_WRITES_19[0], &NT35510_WRITES_19[1..]).unwrap(); | ||
| 470 | dsi.write_cmd(0, NT35510_WRITES_20[0], &NT35510_WRITES_20[1..]).unwrap(); | ||
| 471 | dsi.write_cmd(0, NT35510_WRITES_21[0], &NT35510_WRITES_21[1..]).unwrap(); | ||
| 472 | dsi.write_cmd(0, NT35510_WRITES_22[0], &NT35510_WRITES_22[1..]).unwrap(); | ||
| 473 | dsi.write_cmd(0, NT35510_WRITES_23[0], &NT35510_WRITES_23[1..]).unwrap(); | ||
| 474 | dsi.write_cmd(0, NT35510_WRITES_24[0], &NT35510_WRITES_24[1..]).unwrap(); | ||
| 475 | |||
| 476 | // Tear on | ||
| 477 | dsi.write_cmd(0, NT35510_WRITES_26[0], &NT35510_WRITES_26[1..]).unwrap(); | ||
| 478 | |||
| 479 | // Set Pixel color format to RGB888 | ||
| 480 | dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); | ||
| 481 | |||
| 482 | // Add a delay, otherwise MADCTL not taken | ||
| 483 | blocking_delay_ms(200); | ||
| 484 | |||
| 485 | // Configure orientation as landscape | ||
| 486 | dsi.write_cmd(0, NT35510_MADCTL_LANDSCAPE[0], &NT35510_MADCTL_LANDSCAPE[1..]) | ||
| 487 | .unwrap(); | ||
| 488 | dsi.write_cmd(0, NT35510_CASET_LANDSCAPE[0], &NT35510_CASET_LANDSCAPE[1..]) | ||
| 489 | .unwrap(); | ||
| 490 | dsi.write_cmd(0, NT35510_RASET_LANDSCAPE[0], &NT35510_RASET_LANDSCAPE[1..]) | ||
| 491 | .unwrap(); | ||
| 492 | |||
| 493 | // Sleep out | ||
| 494 | dsi.write_cmd(0, NT35510_WRITES_27[0], &NT35510_WRITES_27[1..]).unwrap(); | ||
| 495 | |||
| 496 | // Wait for sleep out exit | ||
| 497 | blocking_delay_ms(120); | ||
| 498 | |||
| 499 | // Configure COLOR_CODING | ||
| 500 | dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); | ||
| 501 | |||
| 502 | /* CABC : Content Adaptive Backlight Control section start >> */ | ||
| 503 | /* Note : defaut is 0 (lowest Brightness), 0xFF is highest Brightness, try 0x7F : intermediate value */ | ||
| 504 | dsi.write_cmd(0, NT35510_WRITES_31[0], &NT35510_WRITES_31[1..]).unwrap(); | ||
| 505 | /* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */ | ||
| 506 | dsi.write_cmd(0, NT35510_WRITES_32[0], &NT35510_WRITES_32[1..]).unwrap(); | ||
| 507 | /* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */ | ||
| 508 | dsi.write_cmd(0, NT35510_WRITES_33[0], &NT35510_WRITES_33[1..]).unwrap(); | ||
| 509 | /* defaut is 0 (lowest Brightness), 0xFF is highest Brightness */ | ||
| 510 | dsi.write_cmd(0, NT35510_WRITES_34[0], &NT35510_WRITES_34[1..]).unwrap(); | ||
| 511 | /* CABC : Content Adaptive Backlight Control section end << */ | ||
| 512 | /* Display on */ | ||
| 513 | dsi.write_cmd(0, NT35510_WRITES_30[0], &NT35510_WRITES_30[1..]).unwrap(); | ||
| 514 | |||
| 515 | /* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */ | ||
| 516 | /* DSI host from LTDC incoming pixels in video mode */ | ||
| 517 | dsi.write_cmd(0, NT35510_WRITES_35[0], &NT35510_WRITES_35[1..]).unwrap(); | ||
| 518 | |||
| 519 | /* Initialize the LCD pixel width and pixel height */ | ||
| 520 | const WINDOW_X0: u16 = 0; | ||
| 521 | const WINDOW_X1: u16 = LCD_X_SIZE; // 480 for ferris | ||
| 522 | const WINDOW_Y0: u16 = 0; | ||
| 523 | const WINDOW_Y1: u16 = LCD_Y_SIZE; // 800 for ferris | ||
| 524 | const PIXEL_FORMAT: Pf = Pf::ARGB8888; | ||
| 525 | //const FBStartAdress: u16 = FB_Address; | ||
| 526 | const ALPHA: u8 = 255; | ||
| 527 | const ALPHA0: u8 = 0; | ||
| 528 | const BACKCOLOR_BLUE: u8 = 0; | ||
| 529 | const BACKCOLOR_GREEN: u8 = 0; | ||
| 530 | const BACKCOLOR_RED: u8 = 0; | ||
| 531 | const IMAGE_WIDTH: u16 = LCD_X_SIZE; // 480 for ferris | ||
| 532 | const IMAGE_HEIGHT: u16 = LCD_Y_SIZE; // 800 for ferris | ||
| 533 | |||
| 534 | const PIXEL_SIZE: u8 = match PIXEL_FORMAT { | ||
| 535 | Pf::ARGB8888 => 4, | ||
| 536 | Pf::RGB888 => 3, | ||
| 537 | Pf::ARGB4444 | Pf::RGB565 | Pf::ARGB1555 | Pf::AL88 => 2, | ||
| 538 | _ => 1, | ||
| 539 | }; | ||
| 540 | |||
| 541 | // Configure the horizontal start and stop position | ||
| 542 | LTDC.layer(0).whpcr().write(|w| { | ||
| 543 | w.set_whstpos(LTDC.bpcr().read().ahbp() + 1 + WINDOW_X0); | ||
| 544 | w.set_whsppos(LTDC.bpcr().read().ahbp() + WINDOW_X1); | ||
| 545 | }); | ||
| 546 | |||
| 547 | // Configures the vertical start and stop position | ||
| 548 | LTDC.layer(0).wvpcr().write(|w| { | ||
| 549 | w.set_wvstpos(LTDC.bpcr().read().avbp() + 1 + WINDOW_Y0); | ||
| 550 | w.set_wvsppos(LTDC.bpcr().read().avbp() + WINDOW_Y1); | ||
| 551 | }); | ||
| 552 | |||
| 553 | // Specify the pixel format | ||
| 554 | LTDC.layer(0).pfcr().write(|w| w.set_pf(PIXEL_FORMAT)); | ||
| 555 | |||
| 556 | // Configures the default color values as zero | ||
| 557 | LTDC.layer(0).dccr().modify(|w| { | ||
| 558 | w.set_dcblue(BACKCOLOR_BLUE); | ||
| 559 | w.set_dcgreen(BACKCOLOR_GREEN); | ||
| 560 | w.set_dcred(BACKCOLOR_RED); | ||
| 561 | w.set_dcalpha(ALPHA0); | ||
| 562 | }); | ||
| 563 | |||
| 564 | // Specifies the constant ALPHA value | ||
| 565 | LTDC.layer(0).cacr().write(|w| w.set_consta(ALPHA)); | ||
| 566 | |||
| 567 | // Specifies the blending factors | ||
| 568 | LTDC.layer(0).bfcr().write(|w| { | ||
| 569 | w.set_bf1(Bf1::CONSTANT); | ||
| 570 | w.set_bf2(Bf2::CONSTANT); | ||
| 571 | }); | ||
| 572 | |||
| 573 | // Configure the color frame buffer start address | ||
| 574 | let fb_start_address: u32 = &FERRIS_IMAGE[0] as *const _ as u32; | ||
| 575 | info!("Setting Framebuffer Start Address: {:010x}", fb_start_address); | ||
| 576 | LTDC.layer(0).cfbar().write(|w| w.set_cfbadd(fb_start_address)); | ||
| 577 | |||
| 578 | // Configures the color frame buffer pitch in byte | ||
| 579 | LTDC.layer(0).cfblr().write(|w| { | ||
| 580 | w.set_cfbp(IMAGE_WIDTH * PIXEL_SIZE as u16); | ||
| 581 | w.set_cfbll(((WINDOW_X1 - WINDOW_X0) * PIXEL_SIZE as u16) + 3); | ||
| 582 | }); | ||
| 583 | |||
| 584 | // Configures the frame buffer line number | ||
| 585 | LTDC.layer(0).cfblnr().write(|w| w.set_cfblnbr(IMAGE_HEIGHT)); | ||
| 586 | |||
| 587 | // Enable LTDC_Layer by setting LEN bit | ||
| 588 | LTDC.layer(0).cr().modify(|w| w.set_len(true)); | ||
| 589 | |||
| 590 | //LTDC->SRCR = LTDC_SRCR_IMR; | ||
| 591 | LTDC.srcr().modify(|w| w.set_imr(Imr::RELOAD)); | ||
| 592 | |||
| 593 | blocking_delay_ms(5000); | ||
| 594 | |||
| 595 | const READ_SIZE: u16 = 1; | ||
| 596 | let mut data = [1u8; READ_SIZE as usize]; | ||
| 597 | dsi.read(0, PacketType::DcsShortPktRead(0xDA), READ_SIZE, &mut data) | ||
| 598 | .unwrap(); | ||
| 599 | info!("Display ID1: {:#04x}", data); | ||
| 600 | |||
| 601 | dsi.read(0, PacketType::DcsShortPktRead(0xDB), READ_SIZE, &mut data) | ||
| 602 | .unwrap(); | ||
| 603 | info!("Display ID2: {:#04x}", data); | ||
| 604 | |||
| 605 | dsi.read(0, PacketType::DcsShortPktRead(0xDC), READ_SIZE, &mut data) | ||
| 606 | .unwrap(); | ||
| 607 | info!("Display ID3: {:#04x}", data); | ||
| 608 | |||
| 609 | blocking_delay_ms(500); | ||
| 610 | |||
| 611 | info!("Config done, start blinking LED"); | ||
| 612 | loop { | ||
| 613 | led.set_high(); | ||
| 614 | Timer::after_millis(1000).await; | ||
| 615 | |||
| 616 | // Increase screen brightness | ||
| 617 | dsi.write_cmd(0, NT35510_CMD_WRDISBV, &[0xFF]).unwrap(); | ||
| 618 | |||
| 619 | led.set_low(); | ||
| 620 | Timer::after_millis(1000).await; | ||
| 621 | |||
| 622 | // Reduce screen brightness | ||
| 623 | dsi.write_cmd(0, NT35510_CMD_WRDISBV, &[0x50]).unwrap(); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | const NT35510_WRITES_0: &[u8] = &[0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01]; // LV2: Page 1 enable | ||
| 628 | const NT35510_WRITES_1: &[u8] = &[0xB0, 0x03, 0x03, 0x03]; // AVDD: 5.2V | ||
| 629 | const NT35510_WRITES_2: &[u8] = &[0xB6, 0x46, 0x46, 0x46]; // AVDD: Ratio | ||
| 630 | const NT35510_WRITES_3: &[u8] = &[0xB1, 0x03, 0x03, 0x03]; // AVEE: -5.2V | ||
| 631 | const NT35510_WRITES_4: &[u8] = &[0xB7, 0x36, 0x36, 0x36]; // AVEE: Ratio | ||
| 632 | const NT35510_WRITES_5: &[u8] = &[0xB2, 0x00, 0x00, 0x02]; // VCL: -2.5V | ||
| 633 | const NT35510_WRITES_6: &[u8] = &[0xB8, 0x26, 0x26, 0x26]; // VCL: Ratio | ||
| 634 | const NT35510_WRITES_7: &[u8] = &[0xBF, 0x01]; // VGH: 15V (Free Pump) | ||
| 635 | const NT35510_WRITES_8: &[u8] = &[0xB3, 0x09, 0x09, 0x09]; | ||
| 636 | const NT35510_WRITES_9: &[u8] = &[0xB9, 0x36, 0x36, 0x36]; // VGH: Ratio | ||
| 637 | const NT35510_WRITES_10: &[u8] = &[0xB5, 0x08, 0x08, 0x08]; // VGL_REG: -10V | ||
| 638 | const NT35510_WRITES_12: &[u8] = &[0xBA, 0x26, 0x26, 0x26]; // VGLX: Ratio | ||
| 639 | const NT35510_WRITES_13: &[u8] = &[0xBC, 0x00, 0x80, 0x00]; // VGMP/VGSP: 4.5V/0V | ||
| 640 | const NT35510_WRITES_14: &[u8] = &[0xBD, 0x00, 0x80, 0x00]; // VGMN/VGSN:-4.5V/0V | ||
| 641 | const NT35510_WRITES_15: &[u8] = &[0xBE, 0x00, 0x50]; // VCOM: -1.325V | ||
| 642 | const NT35510_WRITES_16: &[u8] = &[0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00]; // LV2: Page 0 enable | ||
| 643 | const NT35510_WRITES_17: &[u8] = &[0xB1, 0xFC, 0x00]; // Display control | ||
| 644 | const NT35510_WRITES_18: &[u8] = &[0xB6, 0x03]; // Src hold time | ||
| 645 | const NT35510_WRITES_19: &[u8] = &[0xB5, 0x51]; | ||
| 646 | const NT35510_WRITES_20: &[u8] = &[0x00, 0x00, 0xB7]; // Gate EQ control | ||
| 647 | const NT35510_WRITES_21: &[u8] = &[0xB8, 0x01, 0x02, 0x02, 0x02]; // Src EQ control(Mode2) | ||
| 648 | const NT35510_WRITES_22: &[u8] = &[0xBC, 0x00, 0x00, 0x00]; // Inv. mode(2-dot) | ||
| 649 | const NT35510_WRITES_23: &[u8] = &[0xCC, 0x03, 0x00, 0x00]; | ||
| 650 | const NT35510_WRITES_24: &[u8] = &[0xBA, 0x01]; | ||
| 651 | |||
| 652 | const _NT35510_MADCTL_PORTRAIT: &[u8] = &[NT35510_CMD_MADCTL, 0x00]; | ||
| 653 | const _NT35510_CASET_PORTRAIT: &[u8] = &[NT35510_CMD_CASET, 0x00, 0x00, 0x01, 0xDF]; | ||
| 654 | const _NT35510_RASET_PORTRAIT: &[u8] = &[NT35510_CMD_RASET, 0x00, 0x00, 0x03, 0x1F]; | ||
| 655 | const NT35510_MADCTL_LANDSCAPE: &[u8] = &[NT35510_CMD_MADCTL, 0x60]; | ||
| 656 | const NT35510_CASET_LANDSCAPE: &[u8] = &[NT35510_CMD_CASET, 0x00, 0x00, 0x03, 0x1F]; | ||
| 657 | const NT35510_RASET_LANDSCAPE: &[u8] = &[NT35510_CMD_RASET, 0x00, 0x00, 0x01, 0xDF]; | ||
| 658 | |||
| 659 | const NT35510_WRITES_26: &[u8] = &[NT35510_CMD_TEEON, 0x00]; // Tear on | ||
| 660 | const NT35510_WRITES_27: &[u8] = &[NT35510_CMD_SLPOUT, 0x00]; // Sleep out | ||
| 661 | // 28,29 missing | ||
| 662 | const NT35510_WRITES_30: &[u8] = &[NT35510_CMD_DISPON, 0x00]; // Display on | ||
| 663 | |||
| 664 | const NT35510_WRITES_31: &[u8] = &[NT35510_CMD_WRDISBV, 0x7F]; | ||
| 665 | const NT35510_WRITES_32: &[u8] = &[NT35510_CMD_WRCTRLD, 0x2C]; | ||
| 666 | const NT35510_WRITES_33: &[u8] = &[NT35510_CMD_WRCABC, 0x02]; | ||
| 667 | const NT35510_WRITES_34: &[u8] = &[NT35510_CMD_WRCABCMB, 0xFF]; | ||
| 668 | const NT35510_WRITES_35: &[u8] = &[NT35510_CMD_RAMWR, 0x00]; | ||
| 669 | |||
| 670 | //const NT35510_WRITES_36: &[u8] = &[NT35510_CMD_COLMOD, NT35510_COLMOD_RGB565]; // FIXME: Example sets it to 888 but rest of the code seems to configure DSI for 565 | ||
| 671 | const NT35510_WRITES_37: &[u8] = &[NT35510_CMD_COLMOD, NT35510_COLMOD_RGB888]; | ||
| 672 | |||
| 673 | // More of these: https://elixir.bootlin.com/linux/latest/source/include/video/mipi_display.h#L83 | ||
| 674 | const _NT35510_CMD_TEEON_GET_DISPLAY_ID: u8 = 0x04; | ||
| 675 | |||
| 676 | const NT35510_CMD_TEEON: u8 = 0x35; | ||
| 677 | const NT35510_CMD_MADCTL: u8 = 0x36; | ||
| 678 | |||
| 679 | const NT35510_CMD_SLPOUT: u8 = 0x11; | ||
| 680 | const NT35510_CMD_DISPON: u8 = 0x29; | ||
| 681 | const NT35510_CMD_CASET: u8 = 0x2A; | ||
| 682 | const NT35510_CMD_RASET: u8 = 0x2B; | ||
| 683 | const NT35510_CMD_RAMWR: u8 = 0x2C; /* Memory write */ | ||
| 684 | const NT35510_CMD_COLMOD: u8 = 0x3A; | ||
| 685 | |||
| 686 | const NT35510_CMD_WRDISBV: u8 = 0x51; /* Write display brightness */ | ||
| 687 | const _NT35510_CMD_RDDISBV: u8 = 0x52; /* Read display brightness */ | ||
| 688 | const NT35510_CMD_WRCTRLD: u8 = 0x53; /* Write CTRL display */ | ||
| 689 | const _NT35510_CMD_RDCTRLD: u8 = 0x54; /* Read CTRL display value */ | ||
| 690 | const NT35510_CMD_WRCABC: u8 = 0x55; /* Write content adaptative brightness control */ | ||
| 691 | const NT35510_CMD_WRCABCMB: u8 = 0x5E; /* Write CABC minimum brightness */ | ||
| 692 | |||
| 693 | const _NT35510_COLMOD_RGB565: u8 = 0x55; | ||
| 694 | const NT35510_COLMOD_RGB888: u8 = 0x77; | ||
diff --git a/examples/stm32f469/src/bin/ferris.bin b/examples/stm32f469/src/bin/ferris.bin new file mode 100644 index 000000000..ae1c466be --- /dev/null +++ b/examples/stm32f469/src/bin/ferris.bin | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������f���2��� | ||
| 2 | ��� | ||
| 3 | ��� | ||
| 4 | �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������=��� | ||
| 5 | �������������������������������������������������������������������������������������������������������������������������������I��� | ||
| 6 | ��� | ||
| 7 | �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%��� | ||
| 8 | ��� | ||
| 9 | ��� | ||
| 10 | ��� | ||
| 11 | ���������������������������������������������������������������������������������������������������������������������������T��� | ||
| 12 | ���������������������������������������������������������������������������������������������������2��� | ||
| 13 | ���=���c�����������������������������������G��� | ||
| 14 | |||
| 15 | |||
| 16 | � | ||
| 17 | e�� | ||
| 18 | |||
| 19 | |||
| 20 | �������������������������������������������������������������������������������������������������������������������������hhh� | ||
| 21 | _�� | ||
| 22 | _�� | ||
| 23 | � | ||
| 24 | (� | ||
| 25 | � | ||
| 26 | .� | ||
| 27 | 1� | ||
| 28 | -� | ||
| 29 | � | ||
| 30 | .�� | ||
| 31 | .��Yb�������������� | ||
| 32 | M�� | ||
| 33 | .��S]���������������������������������� | ||
| 34 | .�� | ||
| 35 | .�� | ||
| 36 | -� | ||
| 37 | .�� | ||
| 38 | .�� | ||
| 39 | .��v{������������������������������_f��%9��,�� | ||
| 40 | 5� | ||
| 41 | .�� | ||
| 42 | L���������������������������������������������������������������������������������������������� | ||
| 43 | .��|������������������������������������������������������������������ | ||
| 44 | -� | ||
| 45 | .�� | ||
| 46 | � | ||
| 47 | � | ||
| 48 | M�� | ||
| 49 | 3� | ||
| 50 | -� | ||
| 51 | 0� | ||
| 52 | 2� | ||
| 53 | .� | ||
| 54 | '� | ||
| 55 | .����������������������������������������������������������������������������������������������%T�� | ||
| 56 | M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������lx�� | ||
| 57 | 6� | ||
| 58 | M��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������fu�� | ||
| 59 | 3� | ||
| 60 | M�� | ||
| 61 | /� | ||
| 62 | 2� | ||
| 63 | J�� | ||
| 64 | .�� | ||
| 65 | .����������������������������������������������������������������������������������������������������������Sl�� | ||
| 66 | H�� | ||
| 67 | M�� | ||
| 68 | .�� | ||
| 69 | M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������q|��O�� | ||
| 70 | M������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(T�� | ||
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 305816a2b..b55c4e127 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml | |||
| @@ -7,12 +7,13 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f777zi to your chip name, if necessary. | 8 | # Change stm32f777zi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 14 | embedded-io-async = { version = "0.6.1" } | 14 | embedded-io-async = { version = "0.6.1" } |
| 15 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 15 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 16 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 16 | 17 | ||
| 17 | defmt = "0.3" | 18 | defmt = "0.3" |
| 18 | defmt-rtt = "0.4" | 19 | defmt-rtt = "0.4" |
| @@ -21,7 +22,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 21 | cortex-m-rt = "0.7.0" | 22 | cortex-m-rt = "0.7.0" |
| 22 | embedded-hal = "0.2.6" | 23 | embedded-hal = "0.2.6" |
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 24 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 25 | heapless = { version = "0.8", default-features = false } | 25 | heapless = { version = "0.8", default-features = false } |
| 26 | nb = "1.0.0" | 26 | nb = "1.0.0" |
| 27 | rand_core = "0.6.3" | 27 | rand_core = "0.6.3" |
diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs index f8d7b691f..641157960 100644 --- a/examples/stm32f7/src/bin/adc.rs +++ b/examples/stm32f7/src/bin/adc.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::Adc; | 6 | use embassy_stm32::adc::Adc; |
| 7 | use embassy_time::{Delay, Timer}; | 7 | use embassy_time::Timer; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let mut adc = Adc::new(p.ADC1, &mut Delay); | 15 | let mut adc = Adc::new(p.ADC1); |
| 16 | let mut pin = p.PA3; | 16 | let mut pin = p.PA3; |
| 17 | 17 | ||
| 18 | let mut vrefint = adc.enable_vrefint(); | 18 | let mut vrefint = adc.enable_vrefint(); |
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 9a608e909..41e2a6061 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs | |||
| @@ -63,9 +63,9 @@ async fn main(spawner: Spawner) -> ! { | |||
| 63 | 63 | ||
| 64 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 64 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 65 | 65 | ||
| 66 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | 66 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); |
| 67 | let device = Ethernet::new( | 67 | let device = Ethernet::new( |
| 68 | PACKETS.init(PacketQueue::<16, 16>::new()), | 68 | PACKETS.init(PacketQueue::<4, 4>::new()), |
| 69 | p.ETH, | 69 | p.ETH, |
| 70 | Irqs, | 70 | Irqs, |
| 71 | p.PA1, | 71 | p.PA1, |
diff --git a/examples/stm32f7/src/bin/qspi.rs b/examples/stm32f7/src/bin/qspi.rs new file mode 100644 index 000000000..90d319b7a --- /dev/null +++ b/examples/stm32f7/src/bin/qspi.rs | |||
| @@ -0,0 +1,301 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![allow(dead_code)] // Allow dead code as not all commands are used in the example | ||
| 4 | |||
| 5 | use defmt::info; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::mode::Async; | ||
| 8 | use embassy_stm32::qspi::enums::{AddressSize, ChipSelectHighTime, FIFOThresholdLevel, MemorySize, *}; | ||
| 9 | use embassy_stm32::qspi::{Config as QspiCfg, Instance, Qspi, TransferConfig}; | ||
| 10 | use embassy_stm32::time::mhz; | ||
| 11 | use embassy_stm32::Config as StmCfg; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | const MEMORY_PAGE_SIZE: usize = 256; | ||
| 15 | |||
| 16 | const CMD_READ: u8 = 0x03; | ||
| 17 | const CMD_HS_READ: u8 = 0x0B; | ||
| 18 | const CMD_QUAD_READ: u8 = 0x6B; | ||
| 19 | |||
| 20 | const CMD_WRITE_PG: u8 = 0xF2; | ||
| 21 | const CMD_QUAD_WRITE_PG: u8 = 0x32; | ||
| 22 | |||
| 23 | const CMD_READ_ID: u8 = 0x9F; | ||
| 24 | const CMD_READ_UUID: u8 = 0x4B; | ||
| 25 | |||
| 26 | const CMD_ENABLE_RESET: u8 = 0x66; | ||
| 27 | const CMD_RESET: u8 = 0x99; | ||
| 28 | |||
| 29 | const CMD_WRITE_ENABLE: u8 = 0x06; | ||
| 30 | const CMD_WRITE_DISABLE: u8 = 0x04; | ||
| 31 | |||
| 32 | const CMD_CHIP_ERASE: u8 = 0xC7; | ||
| 33 | const CMD_SECTOR_ERASE: u8 = 0x20; | ||
| 34 | const CMD_BLOCK_ERASE_32K: u8 = 0x52; | ||
| 35 | const CMD_BLOCK_ERASE_64K: u8 = 0xD8; | ||
| 36 | |||
| 37 | const CMD_READ_SR: u8 = 0x05; | ||
| 38 | const CMD_READ_CR: u8 = 0x35; | ||
| 39 | |||
| 40 | const CMD_WRITE_SR: u8 = 0x01; | ||
| 41 | const CMD_WRITE_CR: u8 = 0x31; | ||
| 42 | const MEMORY_ADDR: u32 = 0x00000000u32; | ||
| 43 | |||
| 44 | /// Implementation of access to flash chip. | ||
| 45 | /// Chip commands are hardcoded as it depends on used chip. | ||
| 46 | /// This implementation is using chip GD25Q64C from Giga Device | ||
| 47 | pub struct FlashMemory<I: Instance> { | ||
| 48 | qspi: Qspi<'static, I, Async>, | ||
| 49 | } | ||
| 50 | |||
| 51 | impl<I: Instance> FlashMemory<I> { | ||
| 52 | pub fn new(qspi: Qspi<'static, I, Async>) -> Self { | ||
| 53 | let mut memory = Self { qspi }; | ||
| 54 | |||
| 55 | memory.reset_memory(); | ||
| 56 | memory.enable_quad(); | ||
| 57 | |||
| 58 | memory | ||
| 59 | } | ||
| 60 | |||
| 61 | fn enable_quad(&mut self) { | ||
| 62 | let cr = self.read_cr(); | ||
| 63 | self.write_cr(cr | 0x02); | ||
| 64 | } | ||
| 65 | |||
| 66 | fn exec_command(&mut self, cmd: u8) { | ||
| 67 | let transaction = TransferConfig { | ||
| 68 | iwidth: QspiWidth::SING, | ||
| 69 | awidth: QspiWidth::NONE, | ||
| 70 | dwidth: QspiWidth::NONE, | ||
| 71 | instruction: cmd, | ||
| 72 | address: None, | ||
| 73 | dummy: DummyCycles::_0, | ||
| 74 | }; | ||
| 75 | self.qspi.command(transaction); | ||
| 76 | } | ||
| 77 | |||
| 78 | pub fn reset_memory(&mut self) { | ||
| 79 | self.exec_command(CMD_ENABLE_RESET); | ||
| 80 | self.exec_command(CMD_RESET); | ||
| 81 | self.wait_write_finish(); | ||
| 82 | } | ||
| 83 | |||
| 84 | pub fn enable_write(&mut self) { | ||
| 85 | self.exec_command(CMD_WRITE_ENABLE); | ||
| 86 | } | ||
| 87 | |||
| 88 | pub fn read_id(&mut self) -> [u8; 3] { | ||
| 89 | let mut buffer = [0; 3]; | ||
| 90 | let transaction: TransferConfig = TransferConfig { | ||
| 91 | iwidth: QspiWidth::SING, | ||
| 92 | awidth: QspiWidth::NONE, | ||
| 93 | dwidth: QspiWidth::SING, | ||
| 94 | instruction: CMD_READ_ID, | ||
| 95 | address: None, | ||
| 96 | dummy: DummyCycles::_0, | ||
| 97 | }; | ||
| 98 | self.qspi.blocking_read(&mut buffer, transaction); | ||
| 99 | buffer | ||
| 100 | } | ||
| 101 | |||
| 102 | pub fn read_uuid(&mut self) -> [u8; 16] { | ||
| 103 | let mut buffer = [0; 16]; | ||
| 104 | let transaction: TransferConfig = TransferConfig { | ||
| 105 | iwidth: QspiWidth::SING, | ||
| 106 | awidth: QspiWidth::SING, | ||
| 107 | dwidth: QspiWidth::SING, | ||
| 108 | instruction: CMD_READ_UUID, | ||
| 109 | address: Some(0), | ||
| 110 | dummy: DummyCycles::_8, | ||
| 111 | }; | ||
| 112 | self.qspi.blocking_read(&mut buffer, transaction); | ||
| 113 | buffer | ||
| 114 | } | ||
| 115 | |||
| 116 | pub fn read_memory(&mut self, addr: u32, buffer: &mut [u8], use_dma: bool) { | ||
| 117 | let transaction = TransferConfig { | ||
| 118 | iwidth: QspiWidth::SING, | ||
| 119 | awidth: QspiWidth::SING, | ||
| 120 | dwidth: QspiWidth::QUAD, | ||
| 121 | instruction: CMD_QUAD_READ, | ||
| 122 | address: Some(addr), | ||
| 123 | dummy: DummyCycles::_8, | ||
| 124 | }; | ||
| 125 | if use_dma { | ||
| 126 | self.qspi.blocking_read_dma(buffer, transaction); | ||
| 127 | } else { | ||
| 128 | self.qspi.blocking_read(buffer, transaction); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | fn wait_write_finish(&mut self) { | ||
| 133 | while (self.read_sr() & 0x01) != 0 {} | ||
| 134 | } | ||
| 135 | |||
| 136 | fn perform_erase(&mut self, addr: u32, cmd: u8) { | ||
| 137 | let transaction = TransferConfig { | ||
| 138 | iwidth: QspiWidth::SING, | ||
| 139 | awidth: QspiWidth::SING, | ||
| 140 | dwidth: QspiWidth::NONE, | ||
| 141 | instruction: cmd, | ||
| 142 | address: Some(addr), | ||
| 143 | dummy: DummyCycles::_0, | ||
| 144 | }; | ||
| 145 | self.enable_write(); | ||
| 146 | self.qspi.command(transaction); | ||
| 147 | self.wait_write_finish(); | ||
| 148 | } | ||
| 149 | |||
| 150 | pub fn erase_sector(&mut self, addr: u32) { | ||
| 151 | self.perform_erase(addr, CMD_SECTOR_ERASE); | ||
| 152 | } | ||
| 153 | |||
| 154 | pub fn erase_block_32k(&mut self, addr: u32) { | ||
| 155 | self.perform_erase(addr, CMD_BLOCK_ERASE_32K); | ||
| 156 | } | ||
| 157 | |||
| 158 | pub fn erase_block_64k(&mut self, addr: u32) { | ||
| 159 | self.perform_erase(addr, CMD_BLOCK_ERASE_64K); | ||
| 160 | } | ||
| 161 | |||
| 162 | pub fn erase_chip(&mut self) { | ||
| 163 | self.exec_command(CMD_CHIP_ERASE); | ||
| 164 | } | ||
| 165 | |||
| 166 | fn write_page(&mut self, addr: u32, buffer: &[u8], len: usize, use_dma: bool) { | ||
| 167 | assert!( | ||
| 168 | (len as u32 + (addr & 0x000000ff)) <= MEMORY_PAGE_SIZE as u32, | ||
| 169 | "write_page(): page write length exceeds page boundary (len = {}, addr = {:X}", | ||
| 170 | len, | ||
| 171 | addr | ||
| 172 | ); | ||
| 173 | |||
| 174 | let transaction = TransferConfig { | ||
| 175 | iwidth: QspiWidth::SING, | ||
| 176 | awidth: QspiWidth::SING, | ||
| 177 | dwidth: QspiWidth::QUAD, | ||
| 178 | instruction: CMD_QUAD_WRITE_PG, | ||
| 179 | address: Some(addr), | ||
| 180 | dummy: DummyCycles::_0, | ||
| 181 | }; | ||
| 182 | self.enable_write(); | ||
| 183 | if use_dma { | ||
| 184 | self.qspi.blocking_write_dma(buffer, transaction); | ||
| 185 | } else { | ||
| 186 | self.qspi.blocking_write(buffer, transaction); | ||
| 187 | } | ||
| 188 | self.wait_write_finish(); | ||
| 189 | } | ||
| 190 | |||
| 191 | pub fn write_memory(&mut self, addr: u32, buffer: &[u8], use_dma: bool) { | ||
| 192 | let mut left = buffer.len(); | ||
| 193 | let mut place = addr; | ||
| 194 | let mut chunk_start = 0; | ||
| 195 | |||
| 196 | while left > 0 { | ||
| 197 | let max_chunk_size = MEMORY_PAGE_SIZE - (place & 0x000000ff) as usize; | ||
| 198 | let chunk_size = if left >= max_chunk_size { max_chunk_size } else { left }; | ||
| 199 | let chunk = &buffer[chunk_start..(chunk_start + chunk_size)]; | ||
| 200 | self.write_page(place, chunk, chunk_size, use_dma); | ||
| 201 | place += chunk_size as u32; | ||
| 202 | left -= chunk_size; | ||
| 203 | chunk_start += chunk_size; | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | fn read_register(&mut self, cmd: u8) -> u8 { | ||
| 208 | let mut buffer = [0; 1]; | ||
| 209 | let transaction: TransferConfig = TransferConfig { | ||
| 210 | iwidth: QspiWidth::SING, | ||
| 211 | awidth: QspiWidth::NONE, | ||
| 212 | dwidth: QspiWidth::SING, | ||
| 213 | instruction: cmd, | ||
| 214 | address: None, | ||
| 215 | dummy: DummyCycles::_0, | ||
| 216 | }; | ||
| 217 | self.qspi.blocking_read(&mut buffer, transaction); | ||
| 218 | buffer[0] | ||
| 219 | } | ||
| 220 | |||
| 221 | fn write_register(&mut self, cmd: u8, value: u8) { | ||
| 222 | let buffer = [value; 1]; | ||
| 223 | let transaction: TransferConfig = TransferConfig { | ||
| 224 | iwidth: QspiWidth::SING, | ||
| 225 | awidth: QspiWidth::NONE, | ||
| 226 | dwidth: QspiWidth::SING, | ||
| 227 | instruction: cmd, | ||
| 228 | address: None, | ||
| 229 | dummy: DummyCycles::_0, | ||
| 230 | }; | ||
| 231 | self.qspi.blocking_write(&buffer, transaction); | ||
| 232 | } | ||
| 233 | |||
| 234 | pub fn read_sr(&mut self) -> u8 { | ||
| 235 | self.read_register(CMD_READ_SR) | ||
| 236 | } | ||
| 237 | |||
| 238 | pub fn read_cr(&mut self) -> u8 { | ||
| 239 | self.read_register(CMD_READ_CR) | ||
| 240 | } | ||
| 241 | |||
| 242 | pub fn write_sr(&mut self, value: u8) { | ||
| 243 | self.write_register(CMD_WRITE_SR, value); | ||
| 244 | } | ||
| 245 | |||
| 246 | pub fn write_cr(&mut self, value: u8) { | ||
| 247 | self.write_register(CMD_WRITE_CR, value); | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | #[embassy_executor::main] | ||
| 252 | async fn main(_spawner: Spawner) -> ! { | ||
| 253 | let mut config = StmCfg::default(); | ||
| 254 | { | ||
| 255 | use embassy_stm32::rcc::*; | ||
| 256 | config.rcc.hse = Some(Hse { | ||
| 257 | freq: mhz(8), | ||
| 258 | mode: HseMode::Oscillator, | ||
| 259 | }); | ||
| 260 | config.rcc.pll_src = PllSource::HSE; | ||
| 261 | config.rcc.pll = Some(Pll { | ||
| 262 | prediv: PllPreDiv::DIV4, | ||
| 263 | mul: PllMul::MUL216, | ||
| 264 | divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 216 / 2 = 216Mhz | ||
| 265 | divq: None, | ||
| 266 | divr: None, | ||
| 267 | }); | ||
| 268 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 269 | config.rcc.apb1_pre = APBPrescaler::DIV4; | ||
| 270 | config.rcc.apb2_pre = APBPrescaler::DIV2; | ||
| 271 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 272 | } | ||
| 273 | let p = embassy_stm32::init(config); | ||
| 274 | info!("Embassy initialized"); | ||
| 275 | |||
| 276 | let config = QspiCfg { | ||
| 277 | memory_size: MemorySize::_8MiB, | ||
| 278 | address_size: AddressSize::_24bit, | ||
| 279 | prescaler: 16, | ||
| 280 | cs_high_time: ChipSelectHighTime::_1Cycle, | ||
| 281 | fifo_threshold: FIFOThresholdLevel::_16Bytes, | ||
| 282 | }; | ||
| 283 | let driver = Qspi::new_bank1( | ||
| 284 | p.QUADSPI, p.PF8, p.PF9, p.PE2, p.PF6, p.PF10, p.PB10, p.DMA2_CH7, config, | ||
| 285 | ); | ||
| 286 | let mut flash = FlashMemory::new(driver); | ||
| 287 | let flash_id = flash.read_id(); | ||
| 288 | info!("FLASH ID: {:?}", flash_id); | ||
| 289 | let mut wr_buf = [0u8; 256]; | ||
| 290 | for i in 0..256 { | ||
| 291 | wr_buf[i] = i as u8; | ||
| 292 | } | ||
| 293 | let mut rd_buf = [0u8; 256]; | ||
| 294 | flash.erase_sector(MEMORY_ADDR); | ||
| 295 | flash.write_memory(MEMORY_ADDR, &wr_buf, true); | ||
| 296 | flash.read_memory(MEMORY_ADDR, &mut rd_buf, true); | ||
| 297 | info!("WRITE BUF: {:?}", wr_buf); | ||
| 298 | info!("READ BUF: {:?}", rd_buf); | ||
| 299 | info!("End of Program, proceed to empty endless loop"); | ||
| 300 | loop {} | ||
| 301 | } | ||
diff --git a/examples/stm32f7/src/bin/usart_dma.rs b/examples/stm32f7/src/bin/usart_dma.rs index fb604b34f..47456adf2 100644 --- a/examples/stm32f7/src/bin/usart_dma.rs +++ b/examples/stm32f7/src/bin/usart_dma.rs | |||
| @@ -5,7 +5,6 @@ use core::fmt::Write; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::dma::NoDma; | ||
| 9 | use embassy_stm32::usart::{Config, Uart}; | 8 | use embassy_stm32::usart::{Config, Uart}; |
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 11 | use heapless::String; | 10 | use heapless::String; |
| @@ -19,7 +18,7 @@ bind_interrupts!(struct Irqs { | |||
| 19 | async fn main(_spawner: Spawner) { | 18 | async fn main(_spawner: Spawner) { |
| 20 | let p = embassy_stm32::init(Default::default()); | 19 | let p = embassy_stm32::init(Default::default()); |
| 21 | let config = Config::default(); | 20 | let config = Config::default(); |
| 22 | let mut usart = Uart::new(p.UART7, p.PA8, p.PA15, Irqs, p.DMA1_CH1, NoDma, config).unwrap(); | 21 | let mut usart = Uart::new(p.UART7, p.PA8, p.PA15, Irqs, p.DMA1_CH1, p.DMA1_CH3, config).unwrap(); |
| 23 | 22 | ||
| 24 | for n in 0u32.. { | 23 | for n in 0u32.. { |
| 25 | let mut s: String<128> = String::new(); | 24 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index 39a5512f4..0e5cc7c5c 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs | |||
| @@ -3,19 +3,24 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 8 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 12 | use embassy_usb::Builder; |
| 12 | use futures::future::join; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | // If you are trying this and your USB device doesn't connect, the most | ||
| 20 | // common issues are the RCC config and vbus_detection | ||
| 21 | // | ||
| 22 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 23 | // for more information. | ||
| 19 | #[embassy_executor::main] | 24 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) { | 25 | async fn main(_spawner: Spawner) { |
| 21 | info!("Hello World!"); | 26 | info!("Hello World!"); |
| @@ -46,7 +51,13 @@ async fn main(_spawner: Spawner) { | |||
| 46 | // Create the driver, from the HAL. | 51 | // Create the driver, from the HAL. |
| 47 | let mut ep_out_buffer = [0u8; 256]; | 52 | let mut ep_out_buffer = [0u8; 256]; |
| 48 | let mut config = embassy_stm32::usb::Config::default(); | 53 | let mut config = embassy_stm32::usb::Config::default(); |
| 49 | config.vbus_detection = true; | 54 | |
| 55 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 56 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 57 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 58 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 59 | config.vbus_detection = false; | ||
| 60 | |||
| 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 61 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 51 | 62 | ||
| 52 | // Create embassy-usb Config | 63 | // Create embassy-usb Config |
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index 6ce3418e5..122a996e5 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml | |||
| @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32g0b1re to your chip name, if necessary. | 8 | # Change stm32g0b1re to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.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"] } | 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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | 15 | ||
| 16 | defmt = "0.3" | 16 | defmt = "0.3" |
| @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 20 | cortex-m-rt = "0.7.0" | 20 | cortex-m-rt = "0.7.0" |
| 21 | embedded-hal = "0.2.6" | 21 | embedded-hal = "0.2.6" |
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 24 | heapless = { version = "0.8", default-features = false } | 23 | heapless = { version = "0.8", default-features = false } |
| 25 | portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } | 24 | portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } |
| 26 | 25 | ||
diff --git a/examples/stm32g0/src/bin/i2c_async.rs b/examples/stm32g0/src/bin/i2c_async.rs new file mode 100644 index 000000000..7e3189b05 --- /dev/null +++ b/examples/stm32g0/src/bin/i2c_async.rs | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::i2c::{self, I2c}; | ||
| 7 | use embassy_stm32::time::Hertz; | ||
| 8 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 9 | use embassy_time::{Duration, Timer}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | I2C1 => i2c::EventInterruptHandler<peripherals::I2C1>, i2c::ErrorInterruptHandler<peripherals::I2C1>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | const TMP117_ADDR: u8 = 0x48; | ||
| 17 | const TMP117_TEMP_RESULT: u8 = 0x00; | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | info!("Hello world"); | ||
| 22 | |||
| 23 | let p = embassy_stm32::init(Default::default()); | ||
| 24 | |||
| 25 | let mut data = [0u8; 2]; | ||
| 26 | let mut i2c = I2c::new( | ||
| 27 | p.I2C1, | ||
| 28 | p.PB8, | ||
| 29 | p.PB9, | ||
| 30 | Irqs, | ||
| 31 | p.DMA1_CH1, | ||
| 32 | p.DMA1_CH2, | ||
| 33 | Hertz(100_000), | ||
| 34 | Default::default(), | ||
| 35 | ); | ||
| 36 | |||
| 37 | loop { | ||
| 38 | match i2c.write_read(TMP117_ADDR, &[TMP117_TEMP_RESULT], &mut data).await { | ||
| 39 | Ok(()) => { | ||
| 40 | let temp = f32::from(i16::from_be_bytes(data)) * 7.8125 / 1000.0; | ||
| 41 | info!("Temperature {}", temp); | ||
| 42 | } | ||
| 43 | Err(_) => error!("I2C Error"), | ||
| 44 | } | ||
| 45 | |||
| 46 | Timer::after(Duration::from_millis(1000)).await; | ||
| 47 | } | ||
| 48 | } | ||
diff --git a/examples/stm32g0/src/bin/spi_neopixel.rs b/examples/stm32g0/src/bin/spi_neopixel.rs index c5ea51721..2deee271d 100644 --- a/examples/stm32g0/src/bin/spi_neopixel.rs +++ b/examples/stm32g0/src/bin/spi_neopixel.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::word::U5; | 6 | use embassy_stm32::dma::word::U5; |
| 7 | use embassy_stm32::dma::NoDma; | ||
| 8 | use embassy_stm32::spi::{Config, Spi}; | 7 | use embassy_stm32::spi::{Config, Spi}; |
| 9 | use embassy_stm32::time::Hertz; | 8 | use embassy_stm32::time::Hertz; |
| 10 | use embassy_time::Timer; | 9 | use embassy_time::Timer; |
| @@ -77,7 +76,7 @@ async fn main(_spawner: Spawner) { | |||
| 77 | 76 | ||
| 78 | let mut config = Config::default(); | 77 | let mut config = Config::default(); |
| 79 | config.frequency = Hertz(4_000_000); | 78 | config.frequency = Hertz(4_000_000); |
| 80 | let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, NoDma, config); | 79 | let mut spi = Spi::new_txonly_nosck(p.SPI1, p.PB5, p.DMA1_CH3, config); |
| 81 | 80 | ||
| 82 | let mut neopixels = Ws2812::new(); | 81 | let mut neopixels = Ws2812::new(); |
| 83 | 82 | ||
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 64c749b9b..9a34ba19d 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32g491re to your chip name, if necessary. | 8 | # Change stm32g491re to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.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"] } | 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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | usbd-hid = "0.7.0" | 15 | usbd-hid = "0.7.0" |
| 16 | 16 | ||
| @@ -22,7 +22,6 @@ cortex-m-rt = "0.7.0" | |||
| 22 | embedded-hal = "0.2.6" | 22 | embedded-hal = "0.2.6" |
| 23 | embedded-can = { version = "0.4" } | 23 | embedded-can = { version = "0.4" } |
| 24 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 24 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 25 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 26 | heapless = { version = "0.8", default-features = false } | 25 | heapless = { version = "0.8", default-features = false } |
| 27 | static_cell = "2.0.0" | 26 | static_cell = "2.0.0" |
| 28 | 27 | ||
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index ae64bc8e4..3de38cbd6 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs | |||
| @@ -5,7 +5,7 @@ use defmt::*; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::Config; | 7 | use embassy_stm32::Config; |
| 8 | use embassy_time::{Delay, Timer}; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| @@ -28,8 +28,8 @@ async fn main(_spawner: Spawner) { | |||
| 28 | let mut p = embassy_stm32::init(config); | 28 | let mut p = embassy_stm32::init(config); |
| 29 | info!("Hello World!"); | 29 | info!("Hello World!"); |
| 30 | 30 | ||
| 31 | let mut adc = Adc::new(p.ADC2, &mut Delay); | 31 | let mut adc = Adc::new(p.ADC2); |
| 32 | adc.set_sample_time(SampleTime::CYCLES32_5); | 32 | adc.set_sample_time(SampleTime::CYCLES24_5); |
| 33 | 33 | ||
| 34 | loop { | 34 | loop { |
| 35 | let measured = adc.read(&mut p.PA7); | 35 | let measured = adc.read(&mut p.PA7); |
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs index 2ed632a93..90004f874 100644 --- a/examples/stm32g4/src/bin/can.rs +++ b/examples/stm32g4/src/bin/can.rs | |||
| @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { | |||
| 38 | 38 | ||
| 39 | let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | 39 | let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); |
| 40 | 40 | ||
| 41 | can.set_extended_filter( | 41 | can.properties().set_extended_filter( |
| 42 | can::filter::ExtendedFilterSlot::_0, | 42 | can::filter::ExtendedFilterSlot::_0, |
| 43 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | 43 | can::filter::ExtendedFilter::accept_all_into_fifo1(), |
| 44 | ); | 44 | ); |
| @@ -128,7 +128,7 @@ async fn main(_spawner: Spawner) { | |||
| 128 | } | 128 | } |
| 129 | } | 129 | } |
| 130 | i = 0; | 130 | i = 0; |
| 131 | let (mut tx, mut rx) = can.split(); | 131 | let (mut tx, mut rx, _props) = can.split(); |
| 132 | // With split | 132 | // With split |
| 133 | loop { | 133 | loop { |
| 134 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); | 134 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| @@ -192,7 +192,7 @@ async fn main(_spawner: Spawner) { | |||
| 192 | 192 | ||
| 193 | Timer::after_millis(250).await; | 193 | Timer::after_millis(250).await; |
| 194 | 194 | ||
| 195 | i += 1; | 195 | i = i.wrapping_add(1); |
| 196 | } | 196 | } |
| 197 | } else { | 197 | } else { |
| 198 | static TX_BUF: StaticCell<can::TxBuf<8>> = StaticCell::new(); | 198 | static TX_BUF: StaticCell<can::TxBuf<8>> = StaticCell::new(); |
| @@ -228,7 +228,7 @@ async fn main(_spawner: Spawner) { | |||
| 228 | 228 | ||
| 229 | Timer::after_millis(250).await; | 229 | Timer::after_millis(250).await; |
| 230 | 230 | ||
| 231 | i += 1; | 231 | i = i.wrapping_add(1); |
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| 234 | } | 234 | } |
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index dbe8f27c1..ed2ac7fac 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs | |||
| @@ -3,13 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::{self, Driver, Instance}; | 8 | use embassy_stm32::usb::{self, Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 12 | use embassy_usb::Builder; |
| 12 | use futures::future::join; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index c9f08d24e..87de9f3a4 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml | |||
| @@ -6,12 +6,13 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32h563zi to your chip name, if necessary. | 8 | # Change stm32h563zi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } | 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 14 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 15 | 16 | ||
| 16 | defmt = "0.3" | 17 | defmt = "0.3" |
| 17 | defmt-rtt = "0.4" | 18 | defmt-rtt = "0.4" |
| @@ -24,7 +25,6 @@ embedded-hal-async = { version = "1.0" } | |||
| 24 | embedded-io-async = { version = "0.6.1" } | 25 | embedded-io-async = { version = "0.6.1" } |
| 25 | embedded-nal-async = { version = "0.7.1" } | 26 | embedded-nal-async = { version = "0.7.1" } |
| 26 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 27 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 27 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 28 | heapless = { version = "0.8", default-features = false } | 28 | heapless = { version = "0.8", default-features = false } |
| 29 | rand_core = "0.6.3" | 29 | rand_core = "0.6.3" |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs index dd625c90a..194239d47 100644 --- a/examples/stm32h5/src/bin/can.rs +++ b/examples/stm32h5/src/bin/can.rs | |||
| @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { | |||
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | let (mut tx, mut rx) = can.split(); | 70 | let (mut tx, mut rx, _props) = can.split(); |
| 71 | // With split | 71 | // With split |
| 72 | loop { | 72 | loop { |
| 73 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); | 73 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| @@ -93,6 +93,6 @@ async fn main(_spawner: Spawner) { | |||
| 93 | 93 | ||
| 94 | Timer::after_millis(250).await; | 94 | Timer::after_millis(250).await; |
| 95 | 95 | ||
| 96 | i += 1; | 96 | i = i.wrapping_add(1); |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs new file mode 100644 index 000000000..0d14c0668 --- /dev/null +++ b/examples/stm32h5/src/bin/stop.rs | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | // Notice: | ||
| 2 | // the MCU might need an extra reset to make the code actually running | ||
| 3 | |||
| 4 | #![no_std] | ||
| 5 | #![no_main] | ||
| 6 | |||
| 7 | use defmt::*; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; | ||
| 10 | use embassy_stm32::low_power::Executor; | ||
| 11 | use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; | ||
| 12 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 13 | use embassy_stm32::Config; | ||
| 14 | use embassy_time::Timer; | ||
| 15 | use static_cell::StaticCell; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | #[cortex_m_rt::entry] | ||
| 19 | fn main() -> ! { | ||
| 20 | Executor::take().run(|spawner| { | ||
| 21 | unwrap!(spawner.spawn(async_main(spawner))); | ||
| 22 | }) | ||
| 23 | } | ||
| 24 | |||
| 25 | #[embassy_executor::task] | ||
| 26 | async fn async_main(spawner: Spawner) { | ||
| 27 | defmt::info!("Program Start"); | ||
| 28 | |||
| 29 | let mut config = Config::default(); | ||
| 30 | |||
| 31 | // System Clock seems need to be equal or lower than 16 MHz | ||
| 32 | config.rcc.hsi = Some(HSIPrescaler::DIV4); | ||
| 33 | |||
| 34 | config.rcc.ls = LsConfig::default_lsi(); | ||
| 35 | // when enabled the power-consumption is much higher during stop, but debugging and RTT is working | ||
| 36 | // if you wan't to measure the power-consumption, or for production: uncomment this line | ||
| 37 | // config.enable_debug_during_sleep = false; | ||
| 38 | let p = embassy_stm32::init(config); | ||
| 39 | |||
| 40 | // give the RTC to the executor... | ||
| 41 | let rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 42 | static RTC: StaticCell<Rtc> = StaticCell::new(); | ||
| 43 | let rtc = RTC.init(rtc); | ||
| 44 | embassy_stm32::low_power::stop_with_rtc(rtc); | ||
| 45 | |||
| 46 | unwrap!(spawner.spawn(blinky(p.PB4.into()))); | ||
| 47 | unwrap!(spawner.spawn(timeout())); | ||
| 48 | } | ||
| 49 | |||
| 50 | #[embassy_executor::task] | ||
| 51 | async fn blinky(led: AnyPin) { | ||
| 52 | let mut led = Output::new(led, Level::Low, Speed::Low); | ||
| 53 | loop { | ||
| 54 | info!("high"); | ||
| 55 | led.set_high(); | ||
| 56 | Timer::after_millis(300).await; | ||
| 57 | |||
| 58 | info!("low"); | ||
| 59 | led.set_low(); | ||
| 60 | Timer::after_millis(300).await; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | // when enable_debug_during_sleep is false, it is more difficult to reprogram the MCU | ||
| 65 | // therefore we block the MCU after 30s to be able to reprogram it easily | ||
| 66 | #[embassy_executor::task] | ||
| 67 | async fn timeout() -> ! { | ||
| 68 | Timer::after_secs(30).await; | ||
| 69 | #[allow(clippy::empty_loop)] | ||
| 70 | loop {} | ||
| 71 | } | ||
diff --git a/examples/stm32h5/src/bin/usart.rs b/examples/stm32h5/src/bin/usart.rs index f9cbad6af..cc49c2fdb 100644 --- a/examples/stm32h5/src/bin/usart.rs +++ b/examples/stm32h5/src/bin/usart.rs | |||
| @@ -4,22 +4,16 @@ | |||
| 4 | use cortex_m_rt::entry; | 4 | use cortex_m_rt::entry; |
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Executor; | 6 | use embassy_executor::Executor; |
| 7 | use embassy_stm32::dma::NoDma; | ||
| 8 | use embassy_stm32::usart::{Config, Uart}; | 7 | use embassy_stm32::usart::{Config, Uart}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 10 | use static_cell::StaticCell; | 8 | use static_cell::StaticCell; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 10 | ||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::task] | 11 | #[embassy_executor::task] |
| 18 | async fn main_task() { | 12 | async fn main_task() { |
| 19 | let p = embassy_stm32::init(Default::default()); | 13 | let p = embassy_stm32::init(Default::default()); |
| 20 | 14 | ||
| 21 | let config = Config::default(); | 15 | let config = Config::default(); |
| 22 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config).unwrap(); | 16 | let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap(); |
| 23 | 17 | ||
| 24 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | 18 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); |
| 25 | info!("wrote Hello, starting echo"); | 19 | info!("wrote Hello, starting echo"); |
diff --git a/examples/stm32h5/src/bin/usart_dma.rs b/examples/stm32h5/src/bin/usart_dma.rs index caae0dd18..c644e84bd 100644 --- a/examples/stm32h5/src/bin/usart_dma.rs +++ b/examples/stm32h5/src/bin/usart_dma.rs | |||
| @@ -6,7 +6,6 @@ use core::fmt::Write; | |||
| 6 | use cortex_m_rt::entry; | 6 | use cortex_m_rt::entry; |
| 7 | use defmt::*; | 7 | use defmt::*; |
| 8 | use embassy_executor::Executor; | 8 | use embassy_executor::Executor; |
| 9 | use embassy_stm32::dma::NoDma; | ||
| 10 | use embassy_stm32::usart::{Config, Uart}; | 9 | use embassy_stm32::usart::{Config, Uart}; |
| 11 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 12 | use heapless::String; | 11 | use heapless::String; |
| @@ -22,7 +21,7 @@ async fn main_task() { | |||
| 22 | let p = embassy_stm32::init(Default::default()); | 21 | let p = embassy_stm32::init(Default::default()); |
| 23 | 22 | ||
| 24 | let config = Config::default(); | 23 | let config = Config::default(); |
| 25 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, NoDma, config).unwrap(); | 24 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap(); |
| 26 | 25 | ||
| 27 | for n in 0u32.. { | 26 | for n in 0u32.. { |
| 28 | let mut s: String<128> = String::new(); | 27 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32h5/src/bin/usart_split.rs b/examples/stm32h5/src/bin/usart_split.rs index 92047de8d..d26c5003c 100644 --- a/examples/stm32h5/src/bin/usart_split.rs +++ b/examples/stm32h5/src/bin/usart_split.rs | |||
| @@ -3,8 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | 6 | use embassy_stm32::mode::Async; |
| 7 | use embassy_stm32::peripherals::{GPDMA1_CH1, UART7}; | ||
| 8 | use embassy_stm32::usart::{Config, Uart, UartRx}; | 7 | use embassy_stm32::usart::{Config, Uart, UartRx}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 10 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | 9 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; |
| @@ -15,18 +14,6 @@ bind_interrupts!(struct Irqs { | |||
| 15 | UART7 => usart::InterruptHandler<peripherals::UART7>; | 14 | UART7 => usart::InterruptHandler<peripherals::UART7>; |
| 16 | }); | 15 | }); |
| 17 | 16 | ||
| 18 | #[embassy_executor::task] | ||
| 19 | async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { | ||
| 20 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | ||
| 21 | info!("wrote Hello, starting echo"); | ||
| 22 | |||
| 23 | let mut buf = [0u8; 1]; | ||
| 24 | loop { | ||
| 25 | unwrap!(usart.blocking_read(&mut buf)); | ||
| 26 | unwrap!(usart.blocking_write(&buf)); | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); | 17 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); |
| 31 | 18 | ||
| 32 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| @@ -50,7 +37,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 50 | } | 37 | } |
| 51 | 38 | ||
| 52 | #[embassy_executor::task] | 39 | #[embassy_executor::task] |
| 53 | async fn reader(mut rx: UartRx<'static, UART7, GPDMA1_CH1>) { | 40 | async fn reader(mut rx: UartRx<'static, Async>) { |
| 54 | let mut buf = [0; 8]; | 41 | let mut buf = [0; 8]; |
| 55 | loop { | 42 | loop { |
| 56 | info!("reading..."); | 43 | info!("reading..."); |
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 4f86bb342..fbcbdb5f9 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs | |||
| @@ -3,13 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 8 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 12 | use embassy_usb::Builder; |
| 12 | use futures::future::join; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 84a89b378..14125f819 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml | |||
| @@ -7,11 +7,13 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32h743bi to your chip name, if necessary. | 8 | # Change stm32h743bi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } | ||
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } | 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 15 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 16 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 15 | 17 | ||
| 16 | defmt = "0.3" | 18 | defmt = "0.3" |
| 17 | defmt-rtt = "0.4" | 19 | defmt-rtt = "0.4" |
| @@ -24,7 +26,6 @@ embedded-hal-async = { version = "1.0" } | |||
| 24 | embedded-nal-async = { version = "0.7.1" } | 26 | embedded-nal-async = { version = "0.7.1" } |
| 25 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.6.1" } |
| 26 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 28 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 27 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 28 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 29 | rand_core = "0.6.3" | 30 | rand_core = "0.6.3" |
| 30 | critical-section = "1.1" | 31 | critical-section = "1.1" |
diff --git a/examples/stm32h7/build.rs b/examples/stm32h7/build.rs index 8cd32d7ed..30691aa97 100644 --- a/examples/stm32h7/build.rs +++ b/examples/stm32h7/build.rs | |||
| @@ -1,4 +1,34 @@ | |||
| 1 | //! This build script copies the `memory.x` file from the crate root into | ||
| 2 | //! a directory where the linker can always find it at build time. | ||
| 3 | //! For many projects this is optional, as the linker always searches the | ||
| 4 | //! project root directory -- wherever `Cargo.toml` is. However, if you | ||
| 5 | //! are using a workspace or have a more complicated build setup, this | ||
| 6 | //! build script becomes required. Additionally, by requesting that | ||
| 7 | //! Cargo re-run the build script whenever `memory.x` is changed, | ||
| 8 | //! updating `memory.x` ensures a rebuild of the application with the | ||
| 9 | //! new memory settings. | ||
| 10 | |||
| 11 | use std::env; | ||
| 12 | use std::fs::File; | ||
| 13 | use std::io::Write; | ||
| 14 | use std::path::PathBuf; | ||
| 15 | |||
| 1 | fn main() { | 16 | fn main() { |
| 17 | // Put `memory.x` in our output directory and ensure it's | ||
| 18 | // on the linker search path. | ||
| 19 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
| 20 | File::create(out.join("memory.x")) | ||
| 21 | .unwrap() | ||
| 22 | .write_all(include_bytes!("memory.x")) | ||
| 23 | .unwrap(); | ||
| 24 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 25 | |||
| 26 | // By default, Cargo will re-run a build script whenever | ||
| 27 | // any file in the project changes. By specifying `memory.x` | ||
| 28 | // here, we ensure the build script is only re-run when | ||
| 29 | // `memory.x` is changed. | ||
| 30 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 31 | |||
| 2 | println!("cargo:rustc-link-arg-bins=--nmagic"); | 32 | println!("cargo:rustc-link-arg-bins=--nmagic"); |
| 3 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | 33 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); |
| 4 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | 34 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); |
diff --git a/examples/stm32h7/memory.x b/examples/stm32h7/memory.x new file mode 100644 index 000000000..e5ab1f62c --- /dev/null +++ b/examples/stm32h7/memory.x | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x08000000, LENGTH = 2048K /* BANK_1 + BANK_2 */ | ||
| 4 | RAM : ORIGIN = 0x24000000, LENGTH = 512K /* SRAM */ | ||
| 5 | RAM_D3 : ORIGIN = 0x38000000, LENGTH = 64K /* SRAM4 */ | ||
| 6 | } | ||
| 7 | |||
| 8 | SECTIONS | ||
| 9 | { | ||
| 10 | .ram_d3 : | ||
| 11 | { | ||
| 12 | *(.ram_d3) | ||
| 13 | } > RAM_D3 | ||
| 14 | } \ No newline at end of file | ||
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index a5594d10c..e9a857a74 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs | |||
| @@ -5,7 +5,7 @@ use defmt::*; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::Config; | 7 | use embassy_stm32::Config; |
| 8 | use embassy_time::{Delay, Timer}; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| @@ -44,14 +44,14 @@ async fn main(_spawner: Spawner) { | |||
| 44 | 44 | ||
| 45 | info!("Hello World!"); | 45 | info!("Hello World!"); |
| 46 | 46 | ||
| 47 | let mut adc = Adc::new(p.ADC3, &mut Delay); | 47 | let mut adc = Adc::new(p.ADC3); |
| 48 | 48 | ||
| 49 | adc.set_sample_time(SampleTime::CYCLES32_5); | 49 | adc.set_sample_time(SampleTime::CYCLES32_5); |
| 50 | 50 | ||
| 51 | let mut vrefint_channel = adc.enable_vrefint(); | 51 | let mut vrefint_channel = adc.enable_vrefint(); |
| 52 | 52 | ||
| 53 | loop { | 53 | loop { |
| 54 | let vrefint = adc.read_internal(&mut vrefint_channel); | 54 | let vrefint = adc.read(&mut vrefint_channel); |
| 55 | info!("vrefint: {}", vrefint); | 55 | info!("vrefint: {}", vrefint); |
| 56 | let measured = adc.read(&mut p.PC0); | 56 | let measured = adc.read(&mut p.PC0); |
| 57 | info!("measured: {}", measured); | 57 | info!("measured: {}", measured); |
diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs index 22cb27481..0af11ef3e 100644 --- a/examples/stm32h7/src/bin/can.rs +++ b/examples/stm32h7/src/bin/can.rs | |||
| @@ -67,7 +67,7 @@ async fn main(_spawner: Spawner) { | |||
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | let (mut tx, mut rx) = can.split(); | 70 | let (mut tx, mut rx, _props) = can.split(); |
| 71 | // With split | 71 | // With split |
| 72 | loop { | 72 | loop { |
| 73 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); | 73 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| @@ -93,6 +93,6 @@ async fn main(_spawner: Spawner) { | |||
| 93 | 93 | ||
| 94 | Timer::after_millis(250).await; | 94 | Timer::after_millis(250).await; |
| 95 | 95 | ||
| 96 | i += 1; | 96 | i = i.wrapping_add(1); |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index aeb169e19..0639fb99f 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs | |||
| @@ -64,10 +64,10 @@ async fn main(spawner: Spawner) -> ! { | |||
| 64 | 64 | ||
| 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 66 | 66 | ||
| 67 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | 67 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); |
| 68 | 68 | ||
| 69 | let device = Ethernet::new( | 69 | let device = Ethernet::new( |
| 70 | PACKETS.init(PacketQueue::<16, 16>::new()), | 70 | PACKETS.init(PacketQueue::<4, 4>::new()), |
| 71 | p.ETH, | 71 | p.ETH, |
| 72 | Irqs, | 72 | Irqs, |
| 73 | p.PA1, | 73 | p.PA1, |
diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs index de6ea522a..9a52e8d3b 100644 --- a/examples/stm32h7/src/bin/eth_client_mii.rs +++ b/examples/stm32h7/src/bin/eth_client_mii.rs | |||
| @@ -64,10 +64,10 @@ async fn main(spawner: Spawner) -> ! { | |||
| 64 | 64 | ||
| 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 66 | 66 | ||
| 67 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | 67 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); |
| 68 | 68 | ||
| 69 | let device = Ethernet::new_mii( | 69 | let device = Ethernet::new_mii( |
| 70 | PACKETS.init(PacketQueue::<16, 16>::new()), | 70 | PACKETS.init(PacketQueue::<4, 4>::new()), |
| 71 | p.ETH, | 71 | p.ETH, |
| 72 | Irqs, | 72 | Irqs, |
| 73 | p.PA1, | 73 | p.PA1, |
diff --git a/examples/stm32h7/src/bin/i2c_shared.rs b/examples/stm32h7/src/bin/i2c_shared.rs new file mode 100644 index 000000000..6f4815582 --- /dev/null +++ b/examples/stm32h7/src/bin/i2c_shared.rs | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::cell::RefCell; | ||
| 5 | |||
| 6 | use defmt::*; | ||
| 7 | use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_stm32::i2c::{self, I2c}; | ||
| 10 | use embassy_stm32::mode::Async; | ||
| 11 | use embassy_stm32::time::Hertz; | ||
| 12 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 13 | use embassy_sync::blocking_mutex::NoopMutex; | ||
| 14 | use embassy_time::{Duration, Timer}; | ||
| 15 | use static_cell::StaticCell; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | const TMP117_ADDR: u8 = 0x48; | ||
| 19 | const TMP117_TEMP_RESULT: u8 = 0x00; | ||
| 20 | |||
| 21 | const SHTC3_ADDR: u8 = 0x70; | ||
| 22 | const SHTC3_WAKEUP: [u8; 2] = [0x35, 0x17]; | ||
| 23 | const SHTC3_MEASURE_RH_FIRST: [u8; 2] = [0x5c, 0x24]; | ||
| 24 | const SHTC3_SLEEP: [u8; 2] = [0xb0, 0x98]; | ||
| 25 | |||
| 26 | static I2C_BUS: StaticCell<NoopMutex<RefCell<I2c<'static, Async>>>> = StaticCell::new(); | ||
| 27 | |||
| 28 | bind_interrupts!(struct Irqs { | ||
| 29 | I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; | ||
| 30 | I2C1_ER => i2c::ErrorInterruptHandler<peripherals::I2C1>; | ||
| 31 | }); | ||
| 32 | |||
| 33 | #[embassy_executor::task] | ||
| 34 | async fn temperature(mut i2c: impl embedded_hal_1::i2c::I2c + 'static) { | ||
| 35 | let mut data = [0u8; 2]; | ||
| 36 | |||
| 37 | loop { | ||
| 38 | match i2c.write_read(TMP117_ADDR, &[TMP117_TEMP_RESULT], &mut data) { | ||
| 39 | Ok(()) => { | ||
| 40 | let temp = f32::from(i16::from_be_bytes(data)) * 7.8125 / 1000.0; | ||
| 41 | info!("Temperature {}", temp); | ||
| 42 | } | ||
| 43 | Err(_) => error!("I2C Error"), | ||
| 44 | } | ||
| 45 | |||
| 46 | Timer::after(Duration::from_millis(1000)).await; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | #[embassy_executor::task] | ||
| 51 | async fn humidity(mut i2c: impl embedded_hal_1::i2c::I2c + 'static) { | ||
| 52 | let mut data = [0u8; 6]; | ||
| 53 | |||
| 54 | loop { | ||
| 55 | // Wakeup | ||
| 56 | match i2c.write(SHTC3_ADDR, &SHTC3_WAKEUP) { | ||
| 57 | Ok(()) => Timer::after(Duration::from_millis(20)).await, | ||
| 58 | Err(_) => error!("I2C Error"), | ||
| 59 | } | ||
| 60 | |||
| 61 | // Measurement | ||
| 62 | match i2c.write(SHTC3_ADDR, &SHTC3_MEASURE_RH_FIRST) { | ||
| 63 | Ok(()) => Timer::after(Duration::from_millis(5)).await, | ||
| 64 | Err(_) => error!("I2C Error"), | ||
| 65 | } | ||
| 66 | |||
| 67 | // Result | ||
| 68 | match i2c.read(SHTC3_ADDR, &mut data) { | ||
| 69 | Ok(()) => Timer::after(Duration::from_millis(5)).await, | ||
| 70 | Err(_) => error!("I2C Error"), | ||
| 71 | } | ||
| 72 | |||
| 73 | // Sleep | ||
| 74 | match i2c.write(SHTC3_ADDR, &SHTC3_SLEEP) { | ||
| 75 | Ok(()) => { | ||
| 76 | let (bytes, _) = data.split_at(core::mem::size_of::<i16>()); | ||
| 77 | let rh = f32::from(u16::from_be_bytes(bytes.try_into().unwrap())) * 100.0 / 65536.0; | ||
| 78 | info!("Humidity: {}", rh); | ||
| 79 | } | ||
| 80 | Err(_) => error!("I2C Error"), | ||
| 81 | } | ||
| 82 | |||
| 83 | Timer::after(Duration::from_millis(1000)).await; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | #[embassy_executor::main] | ||
| 88 | async fn main(spawner: Spawner) { | ||
| 89 | let p = embassy_stm32::init(Default::default()); | ||
| 90 | |||
| 91 | let i2c = I2c::new( | ||
| 92 | p.I2C1, | ||
| 93 | p.PB8, | ||
| 94 | p.PB9, | ||
| 95 | Irqs, | ||
| 96 | p.DMA1_CH4, | ||
| 97 | p.DMA1_CH5, | ||
| 98 | Hertz(100_000), | ||
| 99 | Default::default(), | ||
| 100 | ); | ||
| 101 | let i2c_bus = NoopMutex::new(RefCell::new(i2c)); | ||
| 102 | let i2c_bus = I2C_BUS.init(i2c_bus); | ||
| 103 | |||
| 104 | // Device 1, using embedded-hal-async compatible driver for TMP117 | ||
| 105 | let i2c_dev1 = I2cDevice::new(i2c_bus); | ||
| 106 | spawner.spawn(temperature(i2c_dev1)).unwrap(); | ||
| 107 | |||
| 108 | // Device 2, using embedded-hal-async compatible driver for SHTC3 | ||
| 109 | let i2c_dev2 = I2cDevice::new(i2c_bus); | ||
| 110 | spawner.spawn(humidity(i2c_dev2)).unwrap(); | ||
| 111 | } | ||
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index aed27723a..ad4a8aaf7 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs | |||
| @@ -7,8 +7,7 @@ use core::str::from_utf8; | |||
| 7 | use cortex_m_rt::entry; | 7 | use cortex_m_rt::entry; |
| 8 | use defmt::*; | 8 | use defmt::*; |
| 9 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 10 | use embassy_stm32::dma::NoDma; | 10 | use embassy_stm32::mode::Blocking; |
| 11 | use embassy_stm32::peripherals::SPI3; | ||
| 12 | use embassy_stm32::time::mhz; | 11 | use embassy_stm32::time::mhz; |
| 13 | use embassy_stm32::{spi, Config}; | 12 | use embassy_stm32::{spi, Config}; |
| 14 | use heapless::String; | 13 | use heapless::String; |
| @@ -16,7 +15,7 @@ use static_cell::StaticCell; | |||
| 16 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 17 | 16 | ||
| 18 | #[embassy_executor::task] | 17 | #[embassy_executor::task] |
| 19 | async fn main_task(mut spi: spi::Spi<'static, SPI3, NoDma, NoDma>) { | 18 | async fn main_task(mut spi: spi::Spi<'static, Blocking>) { |
| 20 | for n in 0u32.. { | 19 | for n in 0u32.. { |
| 21 | let mut write: String<128> = String::new(); | 20 | let mut write: String<128> = String::new(); |
| 22 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); | 21 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); |
| @@ -62,7 +61,7 @@ fn main() -> ! { | |||
| 62 | let mut spi_config = spi::Config::default(); | 61 | let mut spi_config = spi::Config::default(); |
| 63 | spi_config.frequency = mhz(1); | 62 | spi_config.frequency = mhz(1); |
| 64 | 63 | ||
| 65 | let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, NoDma, NoDma, spi_config); | 64 | let spi = spi::Spi::new_blocking(p.SPI3, p.PB3, p.PB5, p.PB4, spi_config); |
| 66 | 65 | ||
| 67 | let executor = EXECUTOR.init(Executor::new()); | 66 | let executor = EXECUTOR.init(Executor::new()); |
| 68 | 67 | ||
diff --git a/examples/stm32h7/src/bin/spi_bdma.rs b/examples/stm32h7/src/bin/spi_bdma.rs new file mode 100644 index 000000000..b2e941078 --- /dev/null +++ b/examples/stm32h7/src/bin/spi_bdma.rs | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::fmt::Write; | ||
| 5 | use core::str::from_utf8; | ||
| 6 | |||
| 7 | use cortex_m_rt::entry; | ||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Executor; | ||
| 10 | use embassy_stm32::mode::Async; | ||
| 11 | use embassy_stm32::time::mhz; | ||
| 12 | use embassy_stm32::{spi, Config}; | ||
| 13 | use heapless::String; | ||
| 14 | use static_cell::StaticCell; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | // Defined in memory.x | ||
| 18 | #[link_section = ".ram_d3"] | ||
| 19 | static mut RAM_D3: [u8; 64 * 1024] = [0u8; 64 * 1024]; | ||
| 20 | |||
| 21 | #[embassy_executor::task] | ||
| 22 | async fn main_task(mut spi: spi::Spi<'static, Async>) { | ||
| 23 | let read_buffer = unsafe { &mut RAM_D3[0..128] }; | ||
| 24 | let write_buffer = unsafe { &mut RAM_D3[128..256] }; | ||
| 25 | |||
| 26 | for n in 0u32.. { | ||
| 27 | let mut write: String<128> = String::new(); | ||
| 28 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); | ||
| 29 | let read_buffer = &mut read_buffer[..write.len()]; | ||
| 30 | let write_buffer = &mut write_buffer[..write.len()]; | ||
| 31 | // copy data to write_buffer which is located in D3 domain, accessable by BDMA | ||
| 32 | write_buffer.clone_from_slice(write.as_bytes()); | ||
| 33 | |||
| 34 | spi.transfer(read_buffer, write_buffer).await.ok(); | ||
| 35 | info!("read via spi+dma: {}", from_utf8(read_buffer).unwrap()); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | static EXECUTOR: StaticCell<Executor> = StaticCell::new(); | ||
| 40 | |||
| 41 | #[entry] | ||
| 42 | fn main() -> ! { | ||
| 43 | info!("Hello World!"); | ||
| 44 | |||
| 45 | let mut config = Config::default(); | ||
| 46 | { | ||
| 47 | use embassy_stm32::rcc::*; | ||
| 48 | config.rcc.hsi = Some(HSIPrescaler::DIV1); | ||
| 49 | config.rcc.csi = true; | ||
| 50 | config.rcc.pll1 = Some(Pll { | ||
| 51 | source: PllSource::HSI, | ||
| 52 | prediv: PllPreDiv::DIV4, | ||
| 53 | mul: PllMul::MUL50, | ||
| 54 | divp: Some(PllDiv::DIV2), | ||
| 55 | divq: Some(PllDiv::DIV8), // used by SPI3. 100Mhz. | ||
| 56 | divr: None, | ||
| 57 | }); | ||
| 58 | config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz | ||
| 59 | config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz | ||
| 60 | config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 61 | config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 62 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 63 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 64 | config.rcc.voltage_scale = VoltageScale::Scale1; | ||
| 65 | } | ||
| 66 | let p = embassy_stm32::init(config); | ||
| 67 | |||
| 68 | let mut spi_config = spi::Config::default(); | ||
| 69 | spi_config.frequency = mhz(1); | ||
| 70 | |||
| 71 | let spi = spi::Spi::new(p.SPI6, p.PA5, p.PA7, p.PA6, p.BDMA_CH1, p.BDMA_CH0, spi_config); | ||
| 72 | |||
| 73 | let executor = EXECUTOR.init(Executor::new()); | ||
| 74 | |||
| 75 | executor.run(|spawner| { | ||
| 76 | unwrap!(spawner.spawn(main_task(spi))); | ||
| 77 | }) | ||
| 78 | } | ||
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 54d4d7656..731c7fef5 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs | |||
| @@ -7,7 +7,7 @@ use core::str::from_utf8; | |||
| 7 | use cortex_m_rt::entry; | 7 | use cortex_m_rt::entry; |
| 8 | use defmt::*; | 8 | use defmt::*; |
| 9 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 10 | use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3}; | 10 | use embassy_stm32::mode::Async; |
| 11 | use embassy_stm32::time::mhz; | 11 | use embassy_stm32::time::mhz; |
| 12 | use embassy_stm32::{spi, Config}; | 12 | use embassy_stm32::{spi, Config}; |
| 13 | use heapless::String; | 13 | use heapless::String; |
| @@ -15,7 +15,7 @@ use static_cell::StaticCell; | |||
| 15 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 16 | 16 | ||
| 17 | #[embassy_executor::task] | 17 | #[embassy_executor::task] |
| 18 | async fn main_task(mut spi: spi::Spi<'static, SPI3, DMA1_CH3, DMA1_CH4>) { | 18 | async fn main_task(mut spi: spi::Spi<'static, Async>) { |
| 19 | for n in 0u32.. { | 19 | for n in 0u32.. { |
| 20 | let mut write: String<128> = String::new(); | 20 | let mut write: String<128> = String::new(); |
| 21 | let mut read = [0; 128]; | 21 | let mut read = [0; 128]; |
diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs index f9cbad6af..cc49c2fdb 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs | |||
| @@ -4,22 +4,16 @@ | |||
| 4 | use cortex_m_rt::entry; | 4 | use cortex_m_rt::entry; |
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Executor; | 6 | use embassy_executor::Executor; |
| 7 | use embassy_stm32::dma::NoDma; | ||
| 8 | use embassy_stm32::usart::{Config, Uart}; | 7 | use embassy_stm32::usart::{Config, Uart}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 10 | use static_cell::StaticCell; | 8 | use static_cell::StaticCell; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 10 | ||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::task] | 11 | #[embassy_executor::task] |
| 18 | async fn main_task() { | 12 | async fn main_task() { |
| 19 | let p = embassy_stm32::init(Default::default()); | 13 | let p = embassy_stm32::init(Default::default()); |
| 20 | 14 | ||
| 21 | let config = Config::default(); | 15 | let config = Config::default(); |
| 22 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config).unwrap(); | 16 | let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap(); |
| 23 | 17 | ||
| 24 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | 18 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); |
| 25 | info!("wrote Hello, starting echo"); | 19 | info!("wrote Hello, starting echo"); |
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs index ae1f3a2e9..6f340d40a 100644 --- a/examples/stm32h7/src/bin/usart_dma.rs +++ b/examples/stm32h7/src/bin/usart_dma.rs | |||
| @@ -6,7 +6,6 @@ use core::fmt::Write; | |||
| 6 | use cortex_m_rt::entry; | 6 | use cortex_m_rt::entry; |
| 7 | use defmt::*; | 7 | use defmt::*; |
| 8 | use embassy_executor::Executor; | 8 | use embassy_executor::Executor; |
| 9 | use embassy_stm32::dma::NoDma; | ||
| 10 | use embassy_stm32::usart::{Config, Uart}; | 9 | use embassy_stm32::usart::{Config, Uart}; |
| 11 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 12 | use heapless::String; | 11 | use heapless::String; |
| @@ -22,7 +21,7 @@ async fn main_task() { | |||
| 22 | let p = embassy_stm32::init(Default::default()); | 21 | let p = embassy_stm32::init(Default::default()); |
| 23 | 22 | ||
| 24 | let config = Config::default(); | 23 | let config = Config::default(); |
| 25 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, NoDma, config).unwrap(); | 24 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, p.DMA1_CH1, config).unwrap(); |
| 26 | 25 | ||
| 27 | for n in 0u32.. { | 26 | for n in 0u32.. { |
| 28 | let mut s: String<128> = String::new(); | 27 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs index b98c40877..2bb58be5e 100644 --- a/examples/stm32h7/src/bin/usart_split.rs +++ b/examples/stm32h7/src/bin/usart_split.rs | |||
| @@ -3,8 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | 6 | use embassy_stm32::mode::Async; |
| 7 | use embassy_stm32::peripherals::{DMA1_CH1, UART7}; | ||
| 8 | use embassy_stm32::usart::{Config, Uart, UartRx}; | 7 | use embassy_stm32::usart::{Config, Uart, UartRx}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 10 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | 9 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; |
| @@ -15,18 +14,6 @@ bind_interrupts!(struct Irqs { | |||
| 15 | UART7 => usart::InterruptHandler<peripherals::UART7>; | 14 | UART7 => usart::InterruptHandler<peripherals::UART7>; |
| 16 | }); | 15 | }); |
| 17 | 16 | ||
| 18 | #[embassy_executor::task] | ||
| 19 | async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { | ||
| 20 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | ||
| 21 | info!("wrote Hello, starting echo"); | ||
| 22 | |||
| 23 | let mut buf = [0u8; 1]; | ||
| 24 | loop { | ||
| 25 | unwrap!(usart.blocking_read(&mut buf)); | ||
| 26 | unwrap!(usart.blocking_write(&buf)); | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); | 17 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); |
| 31 | 18 | ||
| 32 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| @@ -50,7 +37,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 50 | } | 37 | } |
| 51 | 38 | ||
| 52 | #[embassy_executor::task] | 39 | #[embassy_executor::task] |
| 53 | async fn reader(mut rx: UartRx<'static, UART7, DMA1_CH1>) { | 40 | async fn reader(mut rx: UartRx<'static, Async>) { |
| 54 | let mut buf = [0; 8]; | 41 | let mut buf = [0; 8]; |
| 55 | loop { | 42 | loop { |
| 56 | info!("reading..."); | 43 | info!("reading..."); |
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index 576506ad3..1c50fc1c8 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs | |||
| @@ -3,18 +3,23 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::usb::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 7 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 8 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 9 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 10 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| 11 | use futures::future::join; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 13 | ||
| 14 | bind_interrupts!(struct Irqs { | 14 | bind_interrupts!(struct Irqs { |
| 15 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 15 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 16 | }); | 16 | }); |
| 17 | 17 | ||
| 18 | // If you are trying this and your USB device doesn't connect, the most | ||
| 19 | // common issues are the RCC config and vbus_detection | ||
| 20 | // | ||
| 21 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 22 | // for more information. | ||
| 18 | #[embassy_executor::main] | 23 | #[embassy_executor::main] |
| 19 | async fn main(_spawner: Spawner) { | 24 | async fn main(_spawner: Spawner) { |
| 20 | info!("Hello World!"); | 25 | info!("Hello World!"); |
| @@ -47,7 +52,13 @@ async fn main(_spawner: Spawner) { | |||
| 47 | // Create the driver, from the HAL. | 52 | // Create the driver, from the HAL. |
| 48 | let mut ep_out_buffer = [0u8; 256]; | 53 | let mut ep_out_buffer = [0u8; 256]; |
| 49 | let mut config = embassy_stm32::usb::Config::default(); | 54 | let mut config = embassy_stm32::usb::Config::default(); |
| 50 | config.vbus_detection = true; | 55 | |
| 56 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 57 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 58 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 59 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 60 | config.vbus_detection = false; | ||
| 61 | |||
| 51 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 62 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 52 | 63 | ||
| 53 | // Create embassy-usb Config | 64 | // Create embassy-usb Config |
diff --git a/examples/stm32h7rs/.cargo/config.toml b/examples/stm32h7rs/.cargo/config.toml new file mode 100644 index 000000000..44dbda94f --- /dev/null +++ b/examples/stm32h7rs/.cargo/config.toml | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | [target.thumbv7em-none-eabihf] | ||
| 2 | runner = 'probe-rs run --chip STM32H7S3L8Hx' | ||
| 3 | |||
| 4 | [build] | ||
| 5 | target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) | ||
| 6 | |||
| 7 | [env] | ||
| 8 | DEFMT_LOG = "trace" | ||
diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml new file mode 100644 index 000000000..f8c49f3d1 --- /dev/null +++ b/examples/stm32h7rs/Cargo.toml | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-stm32h7rs-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | # Change stm32h743bi to your chip name, if necessary. | ||
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } | ||
| 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } | ||
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | ||
| 13 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } | ||
| 14 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } | ||
| 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 16 | |||
| 17 | defmt = "0.3" | ||
| 18 | defmt-rtt = "0.4" | ||
| 19 | |||
| 20 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 21 | cortex-m-rt = "0.7.0" | ||
| 22 | embedded-hal = "0.2.6" | ||
| 23 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | ||
| 24 | embedded-hal-async = { version = "1.0" } | ||
| 25 | embedded-nal-async = { version = "0.7.1" } | ||
| 26 | embedded-io-async = { version = "0.6.1" } | ||
| 27 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 28 | heapless = { version = "0.8", default-features = false } | ||
| 29 | rand_core = "0.6.3" | ||
| 30 | critical-section = "1.1" | ||
| 31 | micromath = "2.0.0" | ||
| 32 | stm32-fmc = "0.3.0" | ||
| 33 | embedded-storage = "0.3.1" | ||
| 34 | static_cell = "2" | ||
| 35 | chrono = { version = "^0.4", default-features = false } | ||
| 36 | |||
| 37 | # cargo build/run | ||
| 38 | [profile.dev] | ||
| 39 | codegen-units = 1 | ||
| 40 | debug = 2 | ||
| 41 | debug-assertions = true # <- | ||
| 42 | incremental = false | ||
| 43 | opt-level = 3 # <- | ||
| 44 | overflow-checks = true # <- | ||
| 45 | |||
| 46 | # cargo test | ||
| 47 | [profile.test] | ||
| 48 | codegen-units = 1 | ||
| 49 | debug = 2 | ||
| 50 | debug-assertions = true # <- | ||
| 51 | incremental = false | ||
| 52 | opt-level = 3 # <- | ||
| 53 | overflow-checks = true # <- | ||
| 54 | |||
| 55 | # cargo build/run --release | ||
| 56 | [profile.release] | ||
| 57 | codegen-units = 1 | ||
| 58 | debug = 2 | ||
| 59 | debug-assertions = false # <- | ||
| 60 | incremental = false | ||
| 61 | lto = 'fat' | ||
| 62 | opt-level = 3 # <- | ||
| 63 | overflow-checks = false # <- | ||
| 64 | |||
| 65 | # cargo test --release | ||
| 66 | [profile.bench] | ||
| 67 | codegen-units = 1 | ||
| 68 | debug = 2 | ||
| 69 | debug-assertions = false # <- | ||
| 70 | incremental = false | ||
| 71 | lto = 'fat' | ||
| 72 | opt-level = 3 # <- | ||
| 73 | overflow-checks = false # <- | ||
diff --git a/examples/stm32h7rs/build.rs b/examples/stm32h7rs/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32h7rs/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/stm32h7rs/src/bin/blinky.rs b/examples/stm32h7rs/src/bin/blinky.rs new file mode 100644 index 000000000..137c585b7 --- /dev/null +++ b/examples/stm32h7rs/src/bin/blinky.rs | |||
| @@ -0,0 +1,51 @@ | |||
| 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_stm32::time::Hertz; | ||
| 8 | use embassy_stm32::Config; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | let mut config = Config::default(); | ||
| 15 | { | ||
| 16 | use embassy_stm32::rcc::*; | ||
| 17 | config.rcc.hse = Some(Hse { | ||
| 18 | freq: Hertz(24_000_000), | ||
| 19 | mode: HseMode::Oscillator, | ||
| 20 | }); | ||
| 21 | config.rcc.pll1 = Some(Pll { | ||
| 22 | source: PllSource::HSE, | ||
| 23 | prediv: PllPreDiv::DIV3, | ||
| 24 | mul: PllMul::MUL150, | ||
| 25 | divp: Some(PllDiv::DIV2), | ||
| 26 | divq: None, | ||
| 27 | divr: None, | ||
| 28 | }); | ||
| 29 | config.rcc.sys = Sysclk::PLL1_P; // 600 Mhz | ||
| 30 | config.rcc.ahb_pre = AHBPrescaler::DIV2; // 300 Mhz | ||
| 31 | config.rcc.apb1_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 32 | config.rcc.apb2_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 33 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 34 | config.rcc.apb5_pre = APBPrescaler::DIV2; // 150 Mhz | ||
| 35 | config.rcc.voltage_scale = VoltageScale::HIGH; | ||
| 36 | } | ||
| 37 | let p = embassy_stm32::init(config); | ||
| 38 | info!("Hello World!"); | ||
| 39 | |||
| 40 | let mut led = Output::new(p.PD10, Level::High, Speed::Low); | ||
| 41 | |||
| 42 | loop { | ||
| 43 | info!("high"); | ||
| 44 | led.set_high(); | ||
| 45 | Timer::after_millis(500).await; | ||
| 46 | |||
| 47 | info!("low"); | ||
| 48 | led.set_low(); | ||
| 49 | Timer::after_millis(500).await; | ||
| 50 | } | ||
| 51 | } | ||
diff --git a/examples/stm32h7rs/src/bin/button_exti.rs b/examples/stm32h7rs/src/bin/button_exti.rs new file mode 100644 index 000000000..34a08bbc6 --- /dev/null +++ b/examples/stm32h7rs/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 | } | ||
diff --git a/examples/stm32h7rs/src/bin/can.rs b/examples/stm32h7rs/src/bin/can.rs new file mode 100644 index 000000000..0af11ef3e --- /dev/null +++ b/examples/stm32h7rs/src/bin/can.rs | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::peripherals::*; | ||
| 7 | use embassy_stm32::{bind_interrupts, can, rcc, Config}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; | ||
| 13 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut config = Config::default(); | ||
| 19 | config.rcc.hse = Some(rcc::Hse { | ||
| 20 | freq: embassy_stm32::time::Hertz(25_000_000), | ||
| 21 | mode: rcc::HseMode::Oscillator, | ||
| 22 | }); | ||
| 23 | config.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; | ||
| 24 | |||
| 25 | let peripherals = embassy_stm32::init(config); | ||
| 26 | |||
| 27 | let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | ||
| 28 | |||
| 29 | // 250k bps | ||
| 30 | can.set_bitrate(250_000); | ||
| 31 | |||
| 32 | //let mut can = can.into_internal_loopback_mode(); | ||
| 33 | let mut can = can.into_normal_mode(); | ||
| 34 | |||
| 35 | info!("CAN Configured"); | ||
| 36 | |||
| 37 | let mut i = 0; | ||
| 38 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 39 | |||
| 40 | loop { | ||
| 41 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 42 | info!("Writing frame"); | ||
| 43 | _ = can.write(&frame).await; | ||
| 44 | |||
| 45 | match can.read().await { | ||
| 46 | Ok(envelope) => { | ||
| 47 | let (rx_frame, ts) = envelope.parts(); | ||
| 48 | let delta = (ts - last_read_ts).as_millis(); | ||
| 49 | last_read_ts = ts; | ||
| 50 | info!( | ||
| 51 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 52 | rx_frame.data()[0], | ||
| 53 | rx_frame.data()[1], | ||
| 54 | rx_frame.data()[2], | ||
| 55 | rx_frame.data()[3], | ||
| 56 | delta, | ||
| 57 | ) | ||
| 58 | } | ||
| 59 | Err(_err) => error!("Error in frame"), | ||
| 60 | } | ||
| 61 | |||
| 62 | Timer::after_millis(250).await; | ||
| 63 | |||
| 64 | i += 1; | ||
| 65 | if i > 3 { | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | let (mut tx, mut rx, _props) = can.split(); | ||
| 71 | // With split | ||
| 72 | loop { | ||
| 73 | let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 74 | info!("Writing frame"); | ||
| 75 | _ = tx.write(&frame).await; | ||
| 76 | |||
| 77 | match rx.read().await { | ||
| 78 | Ok(envelope) => { | ||
| 79 | let (rx_frame, ts) = envelope.parts(); | ||
| 80 | let delta = (ts - last_read_ts).as_millis(); | ||
| 81 | last_read_ts = ts; | ||
| 82 | info!( | ||
| 83 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 84 | rx_frame.data()[0], | ||
| 85 | rx_frame.data()[1], | ||
| 86 | rx_frame.data()[2], | ||
| 87 | rx_frame.data()[3], | ||
| 88 | delta, | ||
| 89 | ) | ||
| 90 | } | ||
| 91 | Err(_err) => error!("Error in frame"), | ||
| 92 | } | ||
| 93 | |||
| 94 | Timer::after_millis(250).await; | ||
| 95 | |||
| 96 | i = i.wrapping_add(1); | ||
| 97 | } | ||
| 98 | } | ||
diff --git a/examples/stm32h7rs/src/bin/i2c.rs b/examples/stm32h7rs/src/bin/i2c.rs new file mode 100644 index 000000000..31e83cbb5 --- /dev/null +++ b/examples/stm32h7rs/src/bin/i2c.rs | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::i2c::{Error, I2c}; | ||
| 7 | use embassy_stm32::time::Hertz; | ||
| 8 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | const ADDRESS: u8 = 0x5F; | ||
| 12 | const WHOAMI: u8 = 0x0F; | ||
| 13 | |||
| 14 | bind_interrupts!(struct Irqs { | ||
| 15 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 16 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | info!("Hello world!"); | ||
| 22 | let p = embassy_stm32::init(Default::default()); | ||
| 23 | |||
| 24 | let mut i2c = I2c::new( | ||
| 25 | p.I2C2, | ||
| 26 | p.PB10, | ||
| 27 | p.PB11, | ||
| 28 | Irqs, | ||
| 29 | p.GPDMA1_CH4, | ||
| 30 | p.GPDMA1_CH5, | ||
| 31 | Hertz(100_000), | ||
| 32 | Default::default(), | ||
| 33 | ); | ||
| 34 | |||
| 35 | let mut data = [0u8; 1]; | ||
| 36 | |||
| 37 | match i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { | ||
| 38 | Ok(()) => info!("Whoami: {}", data[0]), | ||
| 39 | Err(Error::Timeout) => error!("Operation timed out"), | ||
| 40 | Err(e) => error!("I2c Error: {:?}", e), | ||
| 41 | } | ||
| 42 | } | ||
diff --git a/examples/stm32h7rs/src/bin/mco.rs b/examples/stm32h7rs/src/bin/mco.rs new file mode 100644 index 000000000..a6ee27625 --- /dev/null +++ b/examples/stm32h7rs/src/bin/mco.rs | |||
| @@ -0,0 +1,29 @@ | |||
| 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_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) { | ||
| 13 | let p = embassy_stm32::init(Default::default()); | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); | ||
| 17 | |||
| 18 | let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV8); | ||
| 19 | |||
| 20 | loop { | ||
| 21 | info!("high"); | ||
| 22 | led.set_high(); | ||
| 23 | Timer::after_millis(500).await; | ||
| 24 | |||
| 25 | info!("low"); | ||
| 26 | led.set_low(); | ||
| 27 | Timer::after_millis(500).await; | ||
| 28 | } | ||
| 29 | } | ||
diff --git a/examples/stm32h7rs/src/bin/multiprio.rs b/examples/stm32h7rs/src/bin/multiprio.rs new file mode 100644 index 000000000..fcbb6c653 --- /dev/null +++ b/examples/stm32h7rs/src/bin/multiprio.rs | |||
| @@ -0,0 +1,150 @@ | |||
| 1 | //! This example showcases how to create multiple Executor instances to run tasks at | ||
| 2 | //! different priority levels. | ||
| 3 | //! | ||
| 4 | //! Low priority executor runs in thread mode (not interrupt), and uses `sev` for signaling | ||
| 5 | //! there's work in the queue, and `wfe` for waiting for work. | ||
| 6 | //! | ||
| 7 | //! Medium and high priority executors run in two interrupts with different priorities. | ||
| 8 | //! Signaling work is done by pending the interrupt. No "waiting" needs to be done explicitly, since | ||
| 9 | //! when there's work the interrupt will trigger and run the executor. | ||
| 10 | //! | ||
| 11 | //! Sample output below. Note that high priority ticks can interrupt everything else, and | ||
| 12 | //! medium priority computations can interrupt low priority computations, making them to appear | ||
| 13 | //! to take significantly longer time. | ||
| 14 | //! | ||
| 15 | //! ```not_rust | ||
| 16 | //! [med] Starting long computation | ||
| 17 | //! [med] done in 992 ms | ||
| 18 | //! [high] tick! | ||
| 19 | //! [low] Starting long computation | ||
| 20 | //! [med] Starting long computation | ||
| 21 | //! [high] tick! | ||
| 22 | //! [high] tick! | ||
| 23 | //! [med] done in 993 ms | ||
| 24 | //! [med] Starting long computation | ||
| 25 | //! [high] tick! | ||
| 26 | //! [high] tick! | ||
| 27 | //! [med] done in 993 ms | ||
| 28 | //! [low] done in 3972 ms | ||
| 29 | //! [med] Starting long computation | ||
| 30 | //! [high] tick! | ||
| 31 | //! [high] tick! | ||
| 32 | //! [med] done in 993 ms | ||
| 33 | //! ``` | ||
| 34 | //! | ||
| 35 | //! For comparison, try changing the code so all 3 tasks get spawned on the low priority executor. | ||
| 36 | //! You will get an output like the following. Note that no computation is ever interrupted. | ||
| 37 | //! | ||
| 38 | //! ```not_rust | ||
| 39 | //! [high] tick! | ||
| 40 | //! [med] Starting long computation | ||
| 41 | //! [med] done in 496 ms | ||
| 42 | //! [low] Starting long computation | ||
| 43 | //! [low] done in 992 ms | ||
| 44 | //! [med] Starting long computation | ||
| 45 | //! [med] done in 496 ms | ||
| 46 | //! [high] tick! | ||
| 47 | //! [low] Starting long computation | ||
| 48 | //! [low] done in 992 ms | ||
| 49 | //! [high] tick! | ||
| 50 | //! [med] Starting long computation | ||
| 51 | //! [med] done in 496 ms | ||
| 52 | //! [high] tick! | ||
| 53 | //! ``` | ||
| 54 | //! | ||
| 55 | |||
| 56 | #![no_std] | ||
| 57 | #![no_main] | ||
| 58 | |||
| 59 | use cortex_m_rt::entry; | ||
| 60 | use defmt::*; | ||
| 61 | use embassy_executor::{Executor, InterruptExecutor}; | ||
| 62 | use embassy_stm32::interrupt; | ||
| 63 | use embassy_stm32::interrupt::{InterruptExt, Priority}; | ||
| 64 | use embassy_time::{Instant, Timer}; | ||
| 65 | use static_cell::StaticCell; | ||
| 66 | use {defmt_rtt as _, panic_probe as _}; | ||
| 67 | |||
| 68 | #[embassy_executor::task] | ||
| 69 | async fn run_high() { | ||
| 70 | loop { | ||
| 71 | info!(" [high] tick!"); | ||
| 72 | Timer::after_ticks(27374).await; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | #[embassy_executor::task] | ||
| 77 | async fn run_med() { | ||
| 78 | loop { | ||
| 79 | let start = Instant::now(); | ||
| 80 | info!(" [med] Starting long computation"); | ||
| 81 | |||
| 82 | // Spin-wait to simulate a long CPU computation | ||
| 83 | cortex_m::asm::delay(128_000_000); // ~1 second | ||
| 84 | |||
| 85 | let end = Instant::now(); | ||
| 86 | let ms = end.duration_since(start).as_ticks() / 33; | ||
| 87 | info!(" [med] done in {} ms", ms); | ||
| 88 | |||
| 89 | Timer::after_ticks(23421).await; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | #[embassy_executor::task] | ||
| 94 | async fn run_low() { | ||
| 95 | loop { | ||
| 96 | let start = Instant::now(); | ||
| 97 | info!("[low] Starting long computation"); | ||
| 98 | |||
| 99 | // Spin-wait to simulate a long CPU computation | ||
| 100 | cortex_m::asm::delay(256_000_000); // ~2 seconds | ||
| 101 | |||
| 102 | let end = Instant::now(); | ||
| 103 | let ms = end.duration_since(start).as_ticks() / 33; | ||
| 104 | info!("[low] done in {} ms", ms); | ||
| 105 | |||
| 106 | Timer::after_ticks(32983).await; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | static EXECUTOR_HIGH: InterruptExecutor = InterruptExecutor::new(); | ||
| 111 | static EXECUTOR_MED: InterruptExecutor = InterruptExecutor::new(); | ||
| 112 | static EXECUTOR_LOW: StaticCell<Executor> = StaticCell::new(); | ||
| 113 | |||
| 114 | #[interrupt] | ||
| 115 | unsafe fn UART4() { | ||
| 116 | EXECUTOR_HIGH.on_interrupt() | ||
| 117 | } | ||
| 118 | |||
| 119 | #[interrupt] | ||
| 120 | unsafe fn UART5() { | ||
| 121 | EXECUTOR_MED.on_interrupt() | ||
| 122 | } | ||
| 123 | |||
| 124 | #[entry] | ||
| 125 | fn main() -> ! { | ||
| 126 | info!("Hello World!"); | ||
| 127 | |||
| 128 | let _p = embassy_stm32::init(Default::default()); | ||
| 129 | |||
| 130 | // STM32s don’t have any interrupts exclusively for software use, but they can all be triggered by software as well as | ||
| 131 | // by the peripheral, so we can just use any free interrupt vectors which aren’t used by the rest of your application. | ||
| 132 | // In this case we’re using UART4 and UART5, but there’s nothing special about them. Any otherwise unused interrupt | ||
| 133 | // vector would work exactly the same. | ||
| 134 | |||
| 135 | // High-priority executor: UART4, priority level 6 | ||
| 136 | interrupt::UART4.set_priority(Priority::P6); | ||
| 137 | let spawner = EXECUTOR_HIGH.start(interrupt::UART4); | ||
| 138 | unwrap!(spawner.spawn(run_high())); | ||
| 139 | |||
| 140 | // Medium-priority executor: UART5, priority level 7 | ||
| 141 | interrupt::UART5.set_priority(Priority::P7); | ||
| 142 | let spawner = EXECUTOR_MED.start(interrupt::UART5); | ||
| 143 | unwrap!(spawner.spawn(run_med())); | ||
| 144 | |||
| 145 | // Low priority executor: runs in thread mode, using WFE/SEV | ||
| 146 | let executor = EXECUTOR_LOW.init(Executor::new()); | ||
| 147 | executor.run(|spawner| { | ||
| 148 | unwrap!(spawner.spawn(run_low())); | ||
| 149 | }); | ||
| 150 | } | ||
diff --git a/examples/stm32h7rs/src/bin/rng.rs b/examples/stm32h7rs/src/bin/rng.rs new file mode 100644 index 000000000..a9ef7200d --- /dev/null +++ b/examples/stm32h7rs/src/bin/rng.rs | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::rng::Rng; | ||
| 7 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | bind_interrupts!(struct Irqs { | ||
| 11 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 12 | }); | ||
| 13 | |||
| 14 | #[embassy_executor::main] | ||
| 15 | async fn main(_spawner: Spawner) { | ||
| 16 | let mut config = Config::default(); | ||
| 17 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | ||
| 18 | let p = embassy_stm32::init(config); | ||
| 19 | info!("Hello World!"); | ||
| 20 | |||
| 21 | let mut rng = Rng::new(p.RNG, Irqs); | ||
| 22 | |||
| 23 | let mut buf = [0u8; 16]; | ||
| 24 | unwrap!(rng.async_fill_bytes(&mut buf).await); | ||
| 25 | info!("random bytes: {:02x}", buf); | ||
| 26 | } | ||
diff --git a/examples/stm32h7rs/src/bin/rtc.rs b/examples/stm32h7rs/src/bin/rtc.rs new file mode 100644 index 000000000..0adb48877 --- /dev/null +++ b/examples/stm32h7rs/src/bin/rtc.rs | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use chrono::{NaiveDate, NaiveDateTime}; | ||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::rcc::LsConfig; | ||
| 8 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 9 | use embassy_stm32::Config; | ||
| 10 | use embassy_time::Timer; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | #[embassy_executor::main] | ||
| 14 | async fn main(_spawner: Spawner) { | ||
| 15 | let mut config = Config::default(); | ||
| 16 | config.rcc.ls = LsConfig::default_lse(); | ||
| 17 | |||
| 18 | let p = embassy_stm32::init(config); | ||
| 19 | info!("Hello World!"); | ||
| 20 | |||
| 21 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | ||
| 22 | .unwrap() | ||
| 23 | .and_hms_opt(10, 30, 15) | ||
| 24 | .unwrap(); | ||
| 25 | |||
| 26 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 27 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | ||
| 28 | |||
| 29 | rtc.set_datetime(now.into()).expect("datetime not set"); | ||
| 30 | |||
| 31 | // In reality the delay would be much longer | ||
| 32 | Timer::after_millis(20000).await; | ||
| 33 | |||
| 34 | let then: NaiveDateTime = rtc.now().unwrap().into(); | ||
| 35 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | ||
| 36 | } | ||
diff --git a/examples/stm32h7rs/src/bin/signal.rs b/examples/stm32h7rs/src/bin/signal.rs new file mode 100644 index 000000000..b73360f32 --- /dev/null +++ b/examples/stm32h7rs/src/bin/signal.rs | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{info, unwrap}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 7 | use embassy_sync::signal::Signal; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | static SIGNAL: Signal<CriticalSectionRawMutex, u32> = Signal::new(); | ||
| 12 | |||
| 13 | #[embassy_executor::task] | ||
| 14 | async fn my_sending_task() { | ||
| 15 | let mut counter: u32 = 0; | ||
| 16 | |||
| 17 | loop { | ||
| 18 | Timer::after_secs(1).await; | ||
| 19 | |||
| 20 | SIGNAL.signal(counter); | ||
| 21 | |||
| 22 | counter = counter.wrapping_add(1); | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | #[embassy_executor::main] | ||
| 27 | async fn main(spawner: Spawner) { | ||
| 28 | let _p = embassy_stm32::init(Default::default()); | ||
| 29 | unwrap!(spawner.spawn(my_sending_task())); | ||
| 30 | |||
| 31 | loop { | ||
| 32 | let received_counter = SIGNAL.wait().await; | ||
| 33 | |||
| 34 | info!("signalled, counter: {}", received_counter); | ||
| 35 | } | ||
| 36 | } | ||
diff --git a/examples/stm32h7rs/src/bin/spi.rs b/examples/stm32h7rs/src/bin/spi.rs new file mode 100644 index 000000000..8d6ccc58b --- /dev/null +++ b/examples/stm32h7rs/src/bin/spi.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::fmt::Write; | ||
| 5 | use core::str::from_utf8; | ||
| 6 | |||
| 7 | use cortex_m_rt::entry; | ||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Executor; | ||
| 10 | use embassy_stm32::mode::Blocking; | ||
| 11 | use embassy_stm32::spi; | ||
| 12 | use embassy_stm32::time::mhz; | ||
| 13 | use heapless::String; | ||
| 14 | use static_cell::StaticCell; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | #[embassy_executor::task] | ||
| 18 | async fn main_task(mut spi: spi::Spi<'static, Blocking>) { | ||
| 19 | for n in 0u32.. { | ||
| 20 | let mut write: String<128> = String::new(); | ||
| 21 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); | ||
| 22 | unsafe { | ||
| 23 | let result = spi.blocking_transfer_in_place(write.as_bytes_mut()); | ||
| 24 | if let Err(_) = result { | ||
| 25 | defmt::panic!("crap"); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | info!("read via spi: {}", from_utf8(write.as_bytes()).unwrap()); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | static EXECUTOR: StaticCell<Executor> = StaticCell::new(); | ||
| 33 | |||
| 34 | #[entry] | ||
| 35 | fn main() -> ! { | ||
| 36 | info!("Hello World!"); | ||
| 37 | let p = embassy_stm32::init(Default::default()); | ||
| 38 | |||
| 39 | let mut spi_config = spi::Config::default(); | ||
| 40 | spi_config.frequency = mhz(1); | ||
| 41 | |||
| 42 | let spi = spi::Spi::new_blocking(p.SPI3, p.PB3, p.PB5, p.PB4, spi_config); | ||
| 43 | |||
| 44 | let executor = EXECUTOR.init(Executor::new()); | ||
| 45 | |||
| 46 | executor.run(|spawner| { | ||
| 47 | unwrap!(spawner.spawn(main_task(spi))); | ||
| 48 | }) | ||
| 49 | } | ||
diff --git a/examples/stm32h7rs/src/bin/spi_dma.rs b/examples/stm32h7rs/src/bin/spi_dma.rs new file mode 100644 index 000000000..cb305351b --- /dev/null +++ b/examples/stm32h7rs/src/bin/spi_dma.rs | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::fmt::Write; | ||
| 5 | use core::str::from_utf8; | ||
| 6 | |||
| 7 | use cortex_m_rt::entry; | ||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Executor; | ||
| 10 | use embassy_stm32::mode::Async; | ||
| 11 | use embassy_stm32::spi; | ||
| 12 | use embassy_stm32::time::mhz; | ||
| 13 | use heapless::String; | ||
| 14 | use static_cell::StaticCell; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | #[embassy_executor::task] | ||
| 18 | async fn main_task(mut spi: spi::Spi<'static, Async>) { | ||
| 19 | for n in 0u32.. { | ||
| 20 | let mut write: String<128> = String::new(); | ||
| 21 | let mut read = [0; 128]; | ||
| 22 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); | ||
| 23 | // transfer will slice the &mut read down to &write's actual length. | ||
| 24 | spi.transfer(&mut read, write.as_bytes()).await.ok(); | ||
| 25 | info!("read via spi+dma: {}", from_utf8(&read).unwrap()); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | static EXECUTOR: StaticCell<Executor> = StaticCell::new(); | ||
| 30 | |||
| 31 | #[entry] | ||
| 32 | fn main() -> ! { | ||
| 33 | info!("Hello World!"); | ||
| 34 | let p = embassy_stm32::init(Default::default()); | ||
| 35 | |||
| 36 | let mut spi_config = spi::Config::default(); | ||
| 37 | spi_config.frequency = mhz(1); | ||
| 38 | |||
| 39 | let spi = spi::Spi::new(p.SPI3, p.PB3, p.PB5, p.PB4, p.GPDMA1_CH0, p.GPDMA1_CH1, spi_config); | ||
| 40 | |||
| 41 | let executor = EXECUTOR.init(Executor::new()); | ||
| 42 | |||
| 43 | executor.run(|spawner| { | ||
| 44 | unwrap!(spawner.spawn(main_task(spi))); | ||
| 45 | }) | ||
| 46 | } | ||
diff --git a/examples/stm32h7rs/src/bin/usart.rs b/examples/stm32h7rs/src/bin/usart.rs new file mode 100644 index 000000000..cc49c2fdb --- /dev/null +++ b/examples/stm32h7rs/src/bin/usart.rs | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use cortex_m_rt::entry; | ||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Executor; | ||
| 7 | use embassy_stm32::usart::{Config, Uart}; | ||
| 8 | use static_cell::StaticCell; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::task] | ||
| 12 | async fn main_task() { | ||
| 13 | let p = embassy_stm32::init(Default::default()); | ||
| 14 | |||
| 15 | let config = Config::default(); | ||
| 16 | let mut usart = Uart::new_blocking(p.UART7, p.PF6, p.PF7, config).unwrap(); | ||
| 17 | |||
| 18 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | ||
| 19 | info!("wrote Hello, starting echo"); | ||
| 20 | |||
| 21 | let mut buf = [0u8; 1]; | ||
| 22 | loop { | ||
| 23 | unwrap!(usart.blocking_read(&mut buf)); | ||
| 24 | unwrap!(usart.blocking_write(&buf)); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | static EXECUTOR: StaticCell<Executor> = StaticCell::new(); | ||
| 29 | |||
| 30 | #[entry] | ||
| 31 | fn main() -> ! { | ||
| 32 | info!("Hello World!"); | ||
| 33 | |||
| 34 | let executor = EXECUTOR.init(Executor::new()); | ||
| 35 | |||
| 36 | executor.run(|spawner| { | ||
| 37 | unwrap!(spawner.spawn(main_task())); | ||
| 38 | }) | ||
| 39 | } | ||
diff --git a/examples/stm32h7rs/src/bin/usart_dma.rs b/examples/stm32h7rs/src/bin/usart_dma.rs new file mode 100644 index 000000000..c644e84bd --- /dev/null +++ b/examples/stm32h7rs/src/bin/usart_dma.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::fmt::Write; | ||
| 5 | |||
| 6 | use cortex_m_rt::entry; | ||
| 7 | use defmt::*; | ||
| 8 | use embassy_executor::Executor; | ||
| 9 | use embassy_stm32::usart::{Config, Uart}; | ||
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 11 | use heapless::String; | ||
| 12 | use static_cell::StaticCell; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::task] | ||
| 20 | async fn main_task() { | ||
| 21 | let p = embassy_stm32::init(Default::default()); | ||
| 22 | |||
| 23 | let config = Config::default(); | ||
| 24 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap(); | ||
| 25 | |||
| 26 | for n in 0u32.. { | ||
| 27 | let mut s: String<128> = String::new(); | ||
| 28 | core::write!(&mut s, "Hello DMA World {}!\r\n", n).unwrap(); | ||
| 29 | |||
| 30 | usart.write(s.as_bytes()).await.ok(); | ||
| 31 | |||
| 32 | info!("wrote DMA"); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | static EXECUTOR: StaticCell<Executor> = StaticCell::new(); | ||
| 37 | |||
| 38 | #[entry] | ||
| 39 | fn main() -> ! { | ||
| 40 | info!("Hello World!"); | ||
| 41 | |||
| 42 | let executor = EXECUTOR.init(Executor::new()); | ||
| 43 | |||
| 44 | executor.run(|spawner| { | ||
| 45 | unwrap!(spawner.spawn(main_task())); | ||
| 46 | }) | ||
| 47 | } | ||
diff --git a/examples/stm32h7rs/src/bin/usart_split.rs b/examples/stm32h7rs/src/bin/usart_split.rs new file mode 100644 index 000000000..d26c5003c --- /dev/null +++ b/examples/stm32h7rs/src/bin/usart_split.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::mode::Async; | ||
| 7 | use embassy_stm32::usart::{Config, Uart, UartRx}; | ||
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 9 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
| 10 | use embassy_sync::channel::Channel; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new(); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(spawner: Spawner) -> ! { | ||
| 21 | let p = embassy_stm32::init(Default::default()); | ||
| 22 | info!("Hello World!"); | ||
| 23 | |||
| 24 | let config = Config::default(); | ||
| 25 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1, config).unwrap(); | ||
| 26 | unwrap!(usart.blocking_write(b"Type 8 chars to echo!\r\n")); | ||
| 27 | |||
| 28 | let (mut tx, rx) = usart.split(); | ||
| 29 | |||
| 30 | unwrap!(spawner.spawn(reader(rx))); | ||
| 31 | |||
| 32 | loop { | ||
| 33 | let buf = CHANNEL.receive().await; | ||
| 34 | info!("writing..."); | ||
| 35 | unwrap!(tx.write(&buf).await); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | #[embassy_executor::task] | ||
| 40 | async fn reader(mut rx: UartRx<'static, Async>) { | ||
| 41 | let mut buf = [0; 8]; | ||
| 42 | loop { | ||
| 43 | info!("reading..."); | ||
| 44 | unwrap!(rx.read(&mut buf).await); | ||
| 45 | CHANNEL.send(buf).await; | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index dd9097c9b..b6de182e1 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml | |||
| @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32l072cz to your chip name, if necessary. | 8 | # Change stm32l072cz to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.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"] } | 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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | 13 | ||
| @@ -21,7 +21,6 @@ embedded-io-async = { version = "0.6.1" } | |||
| 21 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 21 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 22 | cortex-m-rt = "0.7.0" | 22 | cortex-m-rt = "0.7.0" |
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 25 | heapless = { version = "0.8", default-features = false } | 24 | heapless = { version = "0.8", default-features = false } |
| 26 | embedded-hal = "0.2.6" | 25 | embedded-hal = "0.2.6" |
| 27 | static_cell = { version = "2" } | 26 | static_cell = { version = "2" } |
diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs index 97d41ca4b..9dd09bc45 100644 --- a/examples/stm32l0/src/bin/adc.rs +++ b/examples/stm32l0/src/bin/adc.rs | |||
| @@ -4,13 +4,13 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::peripherals::ADC; | 7 | use embassy_stm32::peripherals::ADC1; |
| 8 | use embassy_stm32::{adc, bind_interrupts}; | 8 | use embassy_stm32::{adc, bind_interrupts}; |
| 9 | use embassy_time::{Delay, Timer}; | 9 | use embassy_time::Timer; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | 12 | bind_interrupts!(struct Irqs { |
| 13 | ADC1_COMP => adc::InterruptHandler<ADC>; | 13 | ADC1_COMP => adc::InterruptHandler<ADC1>; |
| 14 | }); | 14 | }); |
| 15 | 15 | ||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| @@ -18,11 +18,11 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let p = embassy_stm32::init(Default::default()); | 18 | let p = embassy_stm32::init(Default::default()); |
| 19 | info!("Hello World!"); | 19 | info!("Hello World!"); |
| 20 | 20 | ||
| 21 | let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); | 21 | let mut adc = Adc::new(p.ADC1, Irqs); |
| 22 | adc.set_sample_time(SampleTime::CYCLES79_5); | 22 | adc.set_sample_time(SampleTime::CYCLES79_5); |
| 23 | let mut pin = p.PA1; | 23 | let mut pin = p.PA1; |
| 24 | 24 | ||
| 25 | let mut vrefint = adc.enable_vref(&mut Delay); | 25 | let mut vrefint = adc.enable_vref(); |
| 26 | let vrefint_sample = adc.read(&mut vrefint).await; | 26 | let vrefint_sample = adc.read(&mut vrefint).await; |
| 27 | let convert_to_millivolts = |sample| { | 27 | let convert_to_millivolts = |sample| { |
| 28 | // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf | 28 | // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf |
diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs index f23a537b8..8e0cfdedb 100644 --- a/examples/stm32l0/src/bin/spi.rs +++ b/examples/stm32l0/src/bin/spi.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 8 | use embassy_stm32::spi::{Config, Spi}; | 7 | use embassy_stm32::spi::{Config, Spi}; |
| 9 | use embassy_stm32::time::Hertz; | 8 | use embassy_stm32::time::Hertz; |
| @@ -17,7 +16,7 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let mut spi_config = Config::default(); | 16 | let mut spi_config = Config::default(); |
| 18 | spi_config.frequency = Hertz(1_000_000); | 17 | spi_config.frequency = Hertz(1_000_000); |
| 19 | 18 | ||
| 20 | let mut spi = Spi::new(p.SPI1, p.PB3, p.PA7, p.PA6, NoDma, NoDma, spi_config); | 19 | let mut spi = Spi::new_blocking(p.SPI1, p.PB3, p.PA7, p.PA6, spi_config); |
| 21 | 20 | ||
| 22 | let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); | 21 | let mut cs = Output::new(p.PA15, Level::High, Speed::VeryHigh); |
| 23 | 22 | ||
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 322c41262..17887bc14 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml | |||
| @@ -5,11 +5,12 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 13 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 13 | 14 | ||
| 14 | defmt = "0.3" | 15 | defmt = "0.3" |
| 15 | defmt-rtt = "0.4" | 16 | defmt-rtt = "0.4" |
| @@ -18,7 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 18 | cortex-m-rt = "0.7.0" | 19 | cortex-m-rt = "0.7.0" |
| 19 | embedded-hal = "0.2.6" | 20 | embedded-hal = "0.2.6" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 21 | 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 } | 22 | heapless = { version = "0.8", default-features = false } |
| 23 | embedded-storage = "0.3.1" | 23 | embedded-storage = "0.3.1" |
| 24 | 24 | ||
diff --git a/examples/stm32l1/src/bin/spi.rs b/examples/stm32l1/src/bin/spi.rs index 8be686c5a..eabf1bac2 100644 --- a/examples/stm32l1/src/bin/spi.rs +++ b/examples/stm32l1/src/bin/spi.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 8 | use embassy_stm32::spi::{Config, Spi}; | 7 | use embassy_stm32::spi::{Config, Spi}; |
| 9 | use embassy_stm32::time::Hertz; | 8 | use embassy_stm32::time::Hertz; |
| @@ -17,7 +16,7 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let mut spi_config = Config::default(); | 16 | let mut spi_config = Config::default(); |
| 18 | spi_config.frequency = Hertz(1_000_000); | 17 | spi_config.frequency = Hertz(1_000_000); |
| 19 | 18 | ||
| 20 | let mut spi = Spi::new(p.SPI1, p.PA5, p.PA7, p.PA6, NoDma, NoDma, spi_config); | 19 | let mut spi = Spi::new_blocking(p.SPI1, p.PA5, p.PA7, p.PA6, spi_config); |
| 21 | 20 | ||
| 22 | let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); | 21 | let mut cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); |
| 23 | 22 | ||
diff --git a/examples/stm32l1/src/bin/usb_serial.rs b/examples/stm32l1/src/bin/usb_serial.rs index 653bbd6d2..837f7fa57 100644 --- a/examples/stm32l1/src/bin/usb_serial.rs +++ b/examples/stm32l1/src/bin/usb_serial.rs | |||
| @@ -3,12 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | ||
| 6 | use embassy_stm32::usb::{self, Driver, Instance}; | 7 | use embassy_stm32::usb::{self, Driver, Instance}; |
| 7 | use embassy_stm32::{bind_interrupts, peripherals}; | 8 | use embassy_stm32::{bind_interrupts, peripherals}; |
| 8 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 9 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 10 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| 11 | use futures::future::join; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 13 | ||
| 14 | bind_interrupts!(struct Irqs { | 14 | bind_interrupts!(struct Irqs { |
diff --git a/examples/stm32l4/.cargo/config.toml b/examples/stm32l4/.cargo/config.toml index db3a7ceff..83fc6d6f8 100644 --- a/examples/stm32l4/.cargo/config.toml +++ b/examples/stm32l4/.cargo/config.toml | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs chip list` | 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs chip list` |
| 3 | #runner = "probe-rs run --chip STM32L475VGT6" | 3 | #runner = "probe-rs run --chip STM32L475VGT6" |
| 4 | #runner = "probe-rs run --chip STM32L475VG" | 4 | #runner = "probe-rs run --chip STM32L475VG" |
| 5 | runner = "probe-run --chip STM32L4S5QI" | 5 | runner = "probe-rs run --chip STM32L4S5QI" |
| 6 | 6 | ||
| 7 | [build] | 7 | [build] |
| 8 | target = "thumbv7em-none-eabi" | 8 | target = "thumbv7em-none-eabi" |
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index d42e69578..37f09bbcc 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml | |||
| @@ -7,11 +7,11 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32l4s5vi to your chip name, if necessary. | 8 | # Change stm32l4s5vi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "chrono"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "chrono"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "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", ] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] } |
| 13 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } | 13 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } |
| 14 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 14 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 15 | embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } | 15 | embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } |
| 16 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] } | 16 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] } |
| 17 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 17 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| @@ -28,7 +28,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | |||
| 28 | embedded-hal-async = { version = "1.0" } | 28 | embedded-hal-async = { version = "1.0" } |
| 29 | embedded-hal-bus = { version = "0.1", features = ["async"] } | 29 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 30 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 30 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 31 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 32 | heapless = { version = "0.8", default-features = false } | 31 | heapless = { version = "0.8", default-features = false } |
| 33 | chrono = { version = "^0.4", default-features = false } | 32 | chrono = { version = "^0.4", default-features = false } |
| 34 | rand = { version = "0.8.5", default-features = false } | 33 | rand = { version = "0.8.5", default-features = false } |
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index a9f4604aa..7a89334e0 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_stm32::adc::{Adc, Resolution}; | 5 | use embassy_stm32::adc::{Adc, Resolution}; |
| 6 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 7 | use embassy_time::Delay; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | 7 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 8 | ||
| 10 | #[cortex_m_rt::entry] | 9 | #[cortex_m_rt::entry] |
| @@ -18,7 +17,7 @@ fn main() -> ! { | |||
| 18 | } | 17 | } |
| 19 | let p = embassy_stm32::init(config); | 18 | let p = embassy_stm32::init(config); |
| 20 | 19 | ||
| 21 | let mut adc = Adc::new(p.ADC1, &mut Delay); | 20 | let mut adc = Adc::new(p.ADC1); |
| 22 | //adc.enable_vref(); | 21 | //adc.enable_vref(); |
| 23 | adc.set_resolution(Resolution::BITS8); | 22 | adc.set_resolution(Resolution::BITS8); |
| 24 | let mut channel = p.PC0; | 23 | let mut channel = p.PC0; |
diff --git a/examples/stm32l4/src/bin/can.rs b/examples/stm32l4/src/bin/can.rs new file mode 100644 index 000000000..3c4cdac24 --- /dev/null +++ b/examples/stm32l4/src/bin/can.rs | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::can::filter::Mask32; | ||
| 7 | use embassy_stm32::can::{ | ||
| 8 | Can, Fifo, Frame, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler, | ||
| 9 | }; | ||
| 10 | use embassy_stm32::peripherals::CAN1; | ||
| 11 | use embassy_stm32::{bind_interrupts, Config}; | ||
| 12 | use embassy_time::Timer; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | CAN1_RX0 => Rx0InterruptHandler<CAN1>; | ||
| 17 | CAN1_RX1 => Rx1InterruptHandler<CAN1>; | ||
| 18 | CAN1_SCE => SceInterruptHandler<CAN1>; | ||
| 19 | CAN1_TX => TxInterruptHandler<CAN1>; | ||
| 20 | }); | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async fn main(_spawner: Spawner) { | ||
| 24 | let p = embassy_stm32::init(Config::default()); | ||
| 25 | |||
| 26 | let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs); | ||
| 27 | |||
| 28 | can.modify_filters().enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); | ||
| 29 | |||
| 30 | can.modify_config() | ||
| 31 | .set_loopback(true) // Receive own frames | ||
| 32 | .set_silent(true) | ||
| 33 | .set_bitrate(250_000); | ||
| 34 | |||
| 35 | can.enable().await; | ||
| 36 | println!("CAN enabled"); | ||
| 37 | |||
| 38 | let mut i = 0; | ||
| 39 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 40 | loop { | ||
| 41 | let frame = Frame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 42 | info!("Writing frame"); | ||
| 43 | |||
| 44 | _ = can.write(&frame).await; | ||
| 45 | |||
| 46 | match can.read().await { | ||
| 47 | Ok(envelope) => { | ||
| 48 | let (ts, rx_frame) = (envelope.ts, envelope.frame); | ||
| 49 | let delta = (ts - last_read_ts).as_millis(); | ||
| 50 | last_read_ts = ts; | ||
| 51 | info!( | ||
| 52 | "Rx: {} {:02x} --- {}ms", | ||
| 53 | rx_frame.header().len(), | ||
| 54 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 55 | delta, | ||
| 56 | ) | ||
| 57 | } | ||
| 58 | Err(err) => error!("Error in frame: {}", err), | ||
| 59 | } | ||
| 60 | |||
| 61 | Timer::after_millis(250).await; | ||
| 62 | |||
| 63 | i += 1; | ||
| 64 | if i > 2 { | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs index f553deb82..2861bc091 100644 --- a/examples/stm32l4/src/bin/i2c.rs +++ b/examples/stm32l4/src/bin/i2c.rs | |||
| @@ -3,33 +3,17 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::i2c::I2c; | 6 | use embassy_stm32::i2c::I2c; |
| 8 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 9 | ||
| 12 | const ADDRESS: u8 = 0x5F; | 10 | const ADDRESS: u8 = 0x5F; |
| 13 | const WHOAMI: u8 = 0x0F; | 11 | const WHOAMI: u8 = 0x0F; |
| 14 | 12 | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 17 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 22 | let p = embassy_stm32::init(Default::default()); | 15 | let p = embassy_stm32::init(Default::default()); |
| 23 | let mut i2c = I2c::new( | 16 | let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); |
| 24 | p.I2C2, | ||
| 25 | p.PB10, | ||
| 26 | p.PB11, | ||
| 27 | Irqs, | ||
| 28 | NoDma, | ||
| 29 | NoDma, | ||
| 30 | Hertz(100_000), | ||
| 31 | Default::default(), | ||
| 32 | ); | ||
| 33 | 17 | ||
| 34 | let mut data = [0u8; 1]; | 18 | let mut data = [0u8; 1]; |
| 35 | unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); | 19 | unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); |
diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs index 1b8652bcc..a014b23e0 100644 --- a/examples/stm32l4/src/bin/i2c_blocking_async.rs +++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs | |||
| @@ -4,34 +4,18 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_embedded_hal::adapter::BlockingAsync; | 5 | use embassy_embedded_hal::adapter::BlockingAsync; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::dma::NoDma; | ||
| 8 | use embassy_stm32::i2c::I2c; | 7 | use embassy_stm32::i2c::I2c; |
| 9 | use embassy_stm32::time::Hertz; | 8 | use embassy_stm32::time::Hertz; |
| 10 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 11 | use embedded_hal_async::i2c::I2c as I2cTrait; | 9 | use embedded_hal_async::i2c::I2c as I2cTrait; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 11 | ||
| 14 | const ADDRESS: u8 = 0x5F; | 12 | const ADDRESS: u8 = 0x5F; |
| 15 | const WHOAMI: u8 = 0x0F; | 13 | const WHOAMI: u8 = 0x0F; |
| 16 | 14 | ||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 19 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 20 | }); | ||
| 21 | |||
| 22 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 23 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 24 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 25 | let i2c = I2c::new( | 18 | let i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); |
| 26 | p.I2C2, | ||
| 27 | p.PB10, | ||
| 28 | p.PB11, | ||
| 29 | Irqs, | ||
| 30 | NoDma, | ||
| 31 | NoDma, | ||
| 32 | Hertz(100_000), | ||
| 33 | Default::default(), | ||
| 34 | ); | ||
| 35 | let mut i2c = BlockingAsync::new(i2c); | 19 | let mut i2c = BlockingAsync::new(i2c); |
| 36 | 20 | ||
| 37 | let mut data = [0u8; 1]; | 21 | let mut data = [0u8; 1]; |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 77aa929ab..33149144c 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -23,18 +23,23 @@ use embassy_futures::select::{select, Either}; | |||
| 23 | use embassy_futures::yield_now; | 23 | use embassy_futures::yield_now; |
| 24 | use embassy_net::tcp::TcpSocket; | 24 | use embassy_net::tcp::TcpSocket; |
| 25 | use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources, StaticConfigV4}; | 25 | use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources, StaticConfigV4}; |
| 26 | use embassy_net_adin1110::{Device, Runner, ADIN1110}; | ||
| 27 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | ||
| 28 | use embassy_stm32::i2c::{self, Config as I2C_Config, I2c}; | ||
| 29 | use embassy_stm32::mode::Async; | ||
| 30 | use embassy_stm32::rng::{self, Rng}; | ||
| 31 | use embassy_stm32::spi::{Config as SPI_Config, Spi}; | ||
| 32 | use embassy_stm32::time::Hertz; | ||
| 33 | use embassy_stm32::{bind_interrupts, exti, pac, peripherals}; | ||
| 26 | use embassy_time::{Delay, Duration, Ticker, Timer}; | 34 | use embassy_time::{Delay, Duration, Ticker, Timer}; |
| 27 | use embedded_hal_async::i2c::I2c as I2cBus; | 35 | use embedded_hal_async::i2c::I2c as I2cBus; |
| 36 | use embedded_hal_bus::spi::ExclusiveDevice; | ||
| 28 | use embedded_io::Write as bWrite; | 37 | use embedded_io::Write as bWrite; |
| 29 | use embedded_io_async::Write; | 38 | use embedded_io_async::Write; |
| 30 | use hal::gpio::{Input, Level, Output, Speed}; | ||
| 31 | use hal::i2c::{self, I2c}; | ||
| 32 | use hal::rng::{self, Rng}; | ||
| 33 | use hal::{bind_interrupts, exti, pac, peripherals}; | ||
| 34 | use heapless::Vec; | 39 | use heapless::Vec; |
| 40 | use panic_probe as _; | ||
| 35 | use rand::RngCore; | 41 | use rand::RngCore; |
| 36 | use static_cell::StaticCell; | 42 | use static_cell::StaticCell; |
| 37 | use {embassy_stm32 as hal, panic_probe as _}; | ||
| 38 | 43 | ||
| 39 | bind_interrupts!(struct Irqs { | 44 | bind_interrupts!(struct Irqs { |
| 40 | I2C3_EV => i2c::EventInterruptHandler<peripherals::I2C3>; | 45 | I2C3_EV => i2c::EventInterruptHandler<peripherals::I2C3>; |
| @@ -42,13 +47,6 @@ bind_interrupts!(struct Irqs { | |||
| 42 | RNG => rng::InterruptHandler<peripherals::RNG>; | 47 | RNG => rng::InterruptHandler<peripherals::RNG>; |
| 43 | }); | 48 | }); |
| 44 | 49 | ||
| 45 | use embassy_net_adin1110::{Device, Runner, ADIN1110}; | ||
| 46 | use embedded_hal_bus::spi::ExclusiveDevice; | ||
| 47 | use hal::gpio::Pull; | ||
| 48 | use hal::i2c::Config as I2C_Config; | ||
| 49 | use hal::spi::{Config as SPI_Config, Spi}; | ||
| 50 | use hal::time::Hertz; | ||
| 51 | |||
| 52 | // Basic settings | 50 | // Basic settings |
| 53 | // MAC-address used by the adin1110 | 51 | // MAC-address used by the adin1110 |
| 54 | const MAC: [u8; 6] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; | 52 | const MAC: [u8; 6] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; |
| @@ -57,12 +55,12 @@ const IP_ADDRESS: Ipv4Cidr = Ipv4Cidr::new(Ipv4Address([192, 168, 1, 5]), 24); | |||
| 57 | // Listen port for the webserver | 55 | // Listen port for the webserver |
| 58 | const HTTP_LISTEN_PORT: u16 = 80; | 56 | const HTTP_LISTEN_PORT: u16 = 80; |
| 59 | 57 | ||
| 60 | pub type SpeSpi = Spi<'static, peripherals::SPI2, peripherals::DMA1_CH1, peripherals::DMA1_CH2>; | 58 | pub type SpeSpi = Spi<'static, Async>; |
| 61 | pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; | 59 | pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; |
| 62 | pub type SpeInt = exti::ExtiInput<'static>; | 60 | pub type SpeInt = exti::ExtiInput<'static>; |
| 63 | pub type SpeRst = Output<'static>; | 61 | pub type SpeRst = Output<'static>; |
| 64 | pub type Adin1110T = ADIN1110<SpeSpiCs>; | 62 | pub type Adin1110T = ADIN1110<SpeSpiCs>; |
| 65 | pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>; | 63 | pub type TempSensI2c = I2c<'static, Async>; |
| 66 | 64 | ||
| 67 | static TEMP: AtomicI32 = AtomicI32::new(0); | 65 | static TEMP: AtomicI32 = AtomicI32::new(0); |
| 68 | 66 | ||
diff --git a/examples/stm32l4/src/bin/spi.rs b/examples/stm32l4/src/bin/spi.rs index 6653e4516..5693a3765 100644 --- a/examples/stm32l4/src/bin/spi.rs +++ b/examples/stm32l4/src/bin/spi.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_stm32::dma::NoDma; | ||
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | 5 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 7 | use embassy_stm32::spi::{Config, Spi}; | 6 | use embassy_stm32::spi::{Config, Spi}; |
| 8 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| @@ -17,7 +16,7 @@ fn main() -> ! { | |||
| 17 | let mut spi_config = Config::default(); | 16 | let mut spi_config = Config::default(); |
| 18 | spi_config.frequency = Hertz(1_000_000); | 17 | spi_config.frequency = Hertz(1_000_000); |
| 19 | 18 | ||
| 20 | let mut spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); | 19 | let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); |
| 21 | 20 | ||
| 22 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); | 21 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); |
| 23 | 22 | ||
diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs index 68dbb70ad..1f1089101 100644 --- a/examples/stm32l4/src/bin/spi_blocking_async.rs +++ b/examples/stm32l4/src/bin/spi_blocking_async.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_embedded_hal::adapter::BlockingAsync; | 5 | use embassy_embedded_hal::adapter::BlockingAsync; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::dma::NoDma; | ||
| 8 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 7 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; |
| 9 | use embassy_stm32::spi::{Config, Spi}; | 8 | use embassy_stm32::spi::{Config, Spi}; |
| 10 | use embassy_stm32::time::Hertz; | 9 | use embassy_stm32::time::Hertz; |
| @@ -19,7 +18,7 @@ async fn main(_spawner: Spawner) { | |||
| 19 | let mut spi_config = Config::default(); | 18 | let mut spi_config = Config::default(); |
| 20 | spi_config.frequency = Hertz(1_000_000); | 19 | spi_config.frequency = Hertz(1_000_000); |
| 21 | 20 | ||
| 22 | let spi = Spi::new(p.SPI3, p.PC10, p.PC12, p.PC11, NoDma, NoDma, spi_config); | 21 | let spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); |
| 23 | 22 | ||
| 24 | let mut spi = BlockingAsync::new(spi); | 23 | let mut spi = BlockingAsync::new(spi); |
| 25 | 24 | ||
diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs index 7bab23950..d9b388026 100644 --- a/examples/stm32l4/src/bin/usart.rs +++ b/examples/stm32l4/src/bin/usart.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_stm32::dma::NoDma; | ||
| 6 | use embassy_stm32::usart::{Config, Uart}; | 5 | use embassy_stm32::usart::{Config, Uart}; |
| 7 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 6 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 7 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -18,7 +17,7 @@ fn main() -> ! { | |||
| 18 | let p = embassy_stm32::init(Default::default()); | 17 | let p = embassy_stm32::init(Default::default()); |
| 19 | 18 | ||
| 20 | let config = Config::default(); | 19 | let config = Config::default(); |
| 21 | let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, NoDma, NoDma, config).unwrap(); | 20 | let mut usart = Uart::new_blocking(p.UART4, p.PA1, p.PA0, config).unwrap(); |
| 22 | 21 | ||
| 23 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | 22 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); |
| 24 | info!("wrote Hello, starting echo"); | 23 | info!("wrote Hello, starting echo"); |
diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs index 031888f70..b4f7a1643 100644 --- a/examples/stm32l4/src/bin/usart_dma.rs +++ b/examples/stm32l4/src/bin/usart_dma.rs | |||
| @@ -5,7 +5,6 @@ use core::fmt::Write; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::dma::NoDma; | ||
| 9 | use embassy_stm32::usart::{Config, Uart}; | 8 | use embassy_stm32::usart::{Config, Uart}; |
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usart}; |
| 11 | use heapless::String; | 10 | use heapless::String; |
| @@ -21,7 +20,7 @@ async fn main(_spawner: Spawner) { | |||
| 21 | info!("Hello World!"); | 20 | info!("Hello World!"); |
| 22 | 21 | ||
| 23 | let config = Config::default(); | 22 | let config = Config::default(); |
| 24 | let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, p.DMA1_CH3, NoDma, config).unwrap(); | 23 | let mut usart = Uart::new(p.UART4, p.PA1, p.PA0, Irqs, p.DMA1_CH3, p.DMA1_CH4, config).unwrap(); |
| 25 | 24 | ||
| 26 | for n in 0u32.. { | 25 | for n in 0u32.. { |
| 27 | let mut s: String<128> = String::new(); | 26 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 198504b59..ed9671d0f 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs | |||
| @@ -4,18 +4,23 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use defmt_rtt as _; // global logger | 5 | use defmt_rtt as _; // global logger |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_futures::join::join; | ||
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 8 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 12 | use embassy_usb::Builder; |
| 12 | use futures::future::join; | ||
| 13 | use panic_probe as _; | 13 | use panic_probe as _; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | // If you are trying this and your USB device doesn't connect, the most | ||
| 20 | // common issues are the RCC config and vbus_detection | ||
| 21 | // | ||
| 22 | // See https://embassy.dev/book/dev/faq.html#_the_usb_examples_are_not_working_on_my_board_is_there_anything_else_i_need_to_configure | ||
| 23 | // for more information. | ||
| 19 | #[embassy_executor::main] | 24 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) { | 25 | async fn main(_spawner: Spawner) { |
| 21 | info!("Hello World!"); | 26 | info!("Hello World!"); |
| @@ -41,7 +46,13 @@ async fn main(_spawner: Spawner) { | |||
| 41 | // Create the driver, from the HAL. | 46 | // Create the driver, from the HAL. |
| 42 | let mut ep_out_buffer = [0u8; 256]; | 47 | let mut ep_out_buffer = [0u8; 256]; |
| 43 | let mut config = embassy_stm32::usb::Config::default(); | 48 | let mut config = embassy_stm32::usb::Config::default(); |
| 44 | config.vbus_detection = true; | 49 | |
| 50 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 51 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 52 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 53 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 54 | config.vbus_detection = false; | ||
| 55 | |||
| 45 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 56 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 46 | 57 | ||
| 47 | // Create embassy-usb Config | 58 | // Create embassy-usb Config |
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 5bcee178f..910b8e6d1 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml | |||
| @@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32l552ze to your chip name, if necessary. | 8 | # Change stm32l552ze to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 16 | usbd-hid = "0.7.0" | 16 | usbd-hid = "0.7.0" |
| @@ -22,7 +22,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 22 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 22 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 23 | cortex-m-rt = "0.7.0" | 23 | cortex-m-rt = "0.7.0" |
| 24 | embedded-hal = "0.2.6" | 24 | embedded-hal = "0.2.6" |
| 25 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 26 | heapless = { version = "0.8", default-features = false } | 25 | heapless = { version = "0.8", default-features = false } |
| 27 | rand_core = { version = "0.6.3", default-features = false } | 26 | rand_core = { version = "0.6.3", default-features = false } |
| 28 | embedded-io-async = { version = "0.6.1" } | 27 | embedded-io-async = { version = "0.6.1" } |
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 9d30205bb..3f8c52b82 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs | |||
| @@ -54,7 +54,7 @@ async fn main(_spawner: Spawner) { | |||
| 54 | let mut config_descriptor = [0; 256]; | 54 | let mut config_descriptor = [0; 256]; |
| 55 | let mut bos_descriptor = [0; 256]; | 55 | let mut bos_descriptor = [0; 256]; |
| 56 | let mut control_buf = [0; 64]; | 56 | let mut control_buf = [0; 64]; |
| 57 | let request_handler = MyRequestHandler {}; | 57 | let mut request_handler = MyRequestHandler {}; |
| 58 | 58 | ||
| 59 | let mut state = State::new(); | 59 | let mut state = State::new(); |
| 60 | 60 | ||
| @@ -70,7 +70,7 @@ async fn main(_spawner: Spawner) { | |||
| 70 | // Create classes on the builder. | 70 | // Create classes on the builder. |
| 71 | let config = embassy_usb::class::hid::Config { | 71 | let config = embassy_usb::class::hid::Config { |
| 72 | report_descriptor: MouseReport::desc(), | 72 | report_descriptor: MouseReport::desc(), |
| 73 | request_handler: Some(&request_handler), | 73 | request_handler: Some(&mut request_handler), |
| 74 | poll_ms: 60, | 74 | poll_ms: 60, |
| 75 | max_packet_size: 8, | 75 | max_packet_size: 8, |
| 76 | }; | 76 | }; |
| @@ -112,21 +112,21 @@ async fn main(_spawner: Spawner) { | |||
| 112 | struct MyRequestHandler {} | 112 | struct MyRequestHandler {} |
| 113 | 113 | ||
| 114 | impl RequestHandler for MyRequestHandler { | 114 | impl RequestHandler for MyRequestHandler { |
| 115 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | 115 | fn get_report(&mut self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { |
| 116 | info!("Get report for {:?}", id); | 116 | info!("Get report for {:?}", id); |
| 117 | None | 117 | None |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | 120 | fn set_report(&mut self, id: ReportId, data: &[u8]) -> OutResponse { |
| 121 | info!("Set report for {:?}: {=[u8]}", id, data); | 121 | info!("Set report for {:?}: {=[u8]}", id, data); |
| 122 | OutResponse::Accepted | 122 | OutResponse::Accepted |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | 125 | fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { |
| 126 | info!("Set idle rate for {:?} to {:?}", id, dur); | 126 | info!("Set idle rate for {:?} to {:?}", id, dur); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | 129 | fn get_idle_ms(&mut self, id: Option<ReportId>) -> Option<u32> { |
| 130 | info!("Get idle rate for {:?}", id); | 130 | info!("Get idle rate for {:?}", id); |
| 131 | None | 131 | None |
| 132 | } | 132 | } |
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..e67856853 --- /dev/null +++ b/examples/stm32u0/Cargo.toml | |||
| @@ -0,0 +1,29 @@ | |||
| 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", "chrono"] } | ||
| 10 | embassy-sync = { version = "0.6.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 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] } | ||
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 15 | |||
| 16 | defmt = "0.3" | ||
| 17 | defmt-rtt = "0.4" | ||
| 18 | |||
| 19 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 20 | cortex-m-rt = "0.7.0" | ||
| 21 | embedded-hal = "0.2.6" | ||
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 23 | heapless = { version = "0.8", default-features = false } | ||
| 24 | |||
| 25 | micromath = "2.0.0" | ||
| 26 | chrono = { version = "0.4.38", default-features = false } | ||
| 27 | |||
| 28 | [profile.release] | ||
| 29 | 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/adc.rs b/examples/stm32u0/src/bin/adc.rs new file mode 100644 index 000000000..4410448f1 --- /dev/null +++ b/examples/stm32u0/src/bin/adc.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_stm32::adc::{Adc, Resolution}; | ||
| 6 | use embassy_stm32::Config; | ||
| 7 | use embassy_time::Duration; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[cortex_m_rt::entry] | ||
| 11 | fn main() -> ! { | ||
| 12 | info!("Hello World!"); | ||
| 13 | |||
| 14 | let mut config = Config::default(); | ||
| 15 | { | ||
| 16 | use embassy_stm32::rcc::*; | ||
| 17 | config.rcc.mux.adcsel = mux::Adcsel::SYS; | ||
| 18 | } | ||
| 19 | let p = embassy_stm32::init(config); | ||
| 20 | |||
| 21 | let mut adc = Adc::new(p.ADC1); | ||
| 22 | adc.set_resolution(Resolution::BITS8); | ||
| 23 | let mut channel = p.PC0; | ||
| 24 | |||
| 25 | loop { | ||
| 26 | let v = adc.read(&mut channel); | ||
| 27 | info!("--> {}", v); | ||
| 28 | embassy_time::block_for(Duration::from_millis(200)); | ||
| 29 | } | ||
| 30 | } | ||
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 | } | ||
diff --git a/examples/stm32u0/src/bin/crc.rs b/examples/stm32u0/src/bin/crc.rs new file mode 100644 index 000000000..d1b545d5b --- /dev/null +++ b/examples/stm32u0/src/bin/crc.rs | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::crc::{Config, Crc, InputReverseConfig, PolySize}; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[embassy_executor::main] | ||
| 10 | async fn main(_spawner: Spawner) { | ||
| 11 | let p = embassy_stm32::init(Default::default()); | ||
| 12 | info!("Hello World!"); | ||
| 13 | |||
| 14 | // Setup for: https://crccalc.com/?crc=Life, it never dieWomen are my favorite guy&method=crc32&datatype=ascii&outtype=0 | ||
| 15 | let mut crc = Crc::new( | ||
| 16 | p.CRC, | ||
| 17 | unwrap!(Config::new( | ||
| 18 | InputReverseConfig::Byte, | ||
| 19 | true, | ||
| 20 | PolySize::Width32, | ||
| 21 | 0xFFFFFFFF, | ||
| 22 | 0x04C11DB7 | ||
| 23 | )), | ||
| 24 | ); | ||
| 25 | |||
| 26 | let output = crc.feed_bytes(b"Life, it never die\nWomen are my favorite guy") ^ 0xFFFFFFFF; | ||
| 27 | |||
| 28 | defmt::assert_eq!(output, 0x33F0E26B); | ||
| 29 | |||
| 30 | cortex_m::asm::bkpt(); | ||
| 31 | } | ||
diff --git a/examples/stm32u0/src/bin/dac.rs b/examples/stm32u0/src/bin/dac.rs new file mode 100644 index 000000000..fdbf1d374 --- /dev/null +++ b/examples/stm32u0/src/bin/dac.rs | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_stm32::dac::{DacCh1, Value}; | ||
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[cortex_m_rt::entry] | ||
| 10 | fn main() -> ! { | ||
| 11 | let p = embassy_stm32::init(Default::default()); | ||
| 12 | info!("Hello World!"); | ||
| 13 | |||
| 14 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); | ||
| 15 | |||
| 16 | loop { | ||
| 17 | for v in 0..=255 { | ||
| 18 | dac.set(Value::Bit8(to_sine_wave(v))); | ||
| 19 | } | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | use micromath::F32Ext; | ||
| 24 | |||
| 25 | fn to_sine_wave(v: u8) -> u8 { | ||
| 26 | if v >= 128 { | ||
| 27 | // top half | ||
| 28 | let r = 3.14 * ((v - 128) as f32 / 128.0); | ||
| 29 | (r.sin() * 128.0 + 127.0) as u8 | ||
| 30 | } else { | ||
| 31 | // bottom half | ||
| 32 | let r = 3.14 + 3.14 * (v as f32 / 128.0); | ||
| 33 | (r.sin() * 128.0 + 127.0) as u8 | ||
| 34 | } | ||
| 35 | } | ||
diff --git a/examples/stm32u0/src/bin/flash.rs b/examples/stm32u0/src/bin/flash.rs new file mode 100644 index 000000000..01b80a76b --- /dev/null +++ b/examples/stm32u0/src/bin/flash.rs | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::flash::Flash; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[embassy_executor::main] | ||
| 10 | async fn main(_spawner: Spawner) { | ||
| 11 | let p = embassy_stm32::init(Default::default()); | ||
| 12 | info!("Hello World!"); | ||
| 13 | |||
| 14 | let addr: u32 = 0x40000 - 2 * 1024; | ||
| 15 | |||
| 16 | let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank1_region; | ||
| 17 | |||
| 18 | info!("Reading..."); | ||
| 19 | let mut buf = [0u8; 32]; | ||
| 20 | unwrap!(f.blocking_read(addr, &mut buf)); | ||
| 21 | info!("Read: {=[u8]:x}", buf); | ||
| 22 | info!("Erasing..."); | ||
| 23 | unwrap!(f.blocking_erase(addr, addr + 2 * 1024)); | ||
| 24 | |||
| 25 | info!("Reading..."); | ||
| 26 | let mut buf = [0u8; 32]; | ||
| 27 | unwrap!(f.blocking_read(addr, &mut buf)); | ||
| 28 | info!("Read after erase: {=[u8]:x}", buf); | ||
| 29 | |||
| 30 | info!("Writing..."); | ||
| 31 | unwrap!(f.blocking_write( | ||
| 32 | addr, | ||
| 33 | &[ | ||
| 34 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | ||
| 35 | 30, 31, 32 | ||
| 36 | ] | ||
| 37 | )); | ||
| 38 | |||
| 39 | info!("Reading..."); | ||
| 40 | let mut buf = [0u8; 32]; | ||
| 41 | unwrap!(f.blocking_read(addr, &mut buf)); | ||
| 42 | info!("Read: {=[u8]:x}", buf); | ||
| 43 | } | ||
diff --git a/examples/stm32u0/src/bin/i2c.rs b/examples/stm32u0/src/bin/i2c.rs new file mode 100644 index 000000000..2861bc091 --- /dev/null +++ b/examples/stm32u0/src/bin/i2c.rs | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::i2c::I2c; | ||
| 7 | use embassy_stm32::time::Hertz; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | const ADDRESS: u8 = 0x5F; | ||
| 11 | const WHOAMI: u8 = 0x0F; | ||
| 12 | |||
| 13 | #[embassy_executor::main] | ||
| 14 | async fn main(_spawner: Spawner) { | ||
| 15 | let p = embassy_stm32::init(Default::default()); | ||
| 16 | let mut i2c = I2c::new_blocking(p.I2C2, p.PB10, p.PB11, Hertz(100_000), Default::default()); | ||
| 17 | |||
| 18 | let mut data = [0u8; 1]; | ||
| 19 | unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); | ||
| 20 | info!("Whoami: {}", data[0]); | ||
| 21 | } | ||
diff --git a/examples/stm32u0/src/bin/rng.rs b/examples/stm32u0/src/bin/rng.rs new file mode 100644 index 000000000..89445b042 --- /dev/null +++ b/examples/stm32u0/src/bin/rng.rs | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::rcc::mux::Clk48sel; | ||
| 7 | use embassy_stm32::rng::Rng; | ||
| 8 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | RNG_CRYP => rng::InterruptHandler<peripherals::RNG>; | ||
| 13 | }); | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let mut config = Config::default(); | ||
| 18 | { | ||
| 19 | use embassy_stm32::rcc::*; | ||
| 20 | config.rcc.hsi = true; | ||
| 21 | config.rcc.pll = Some(Pll { | ||
| 22 | source: PllSource::HSI, // 16 MHz | ||
| 23 | prediv: PllPreDiv::DIV1, | ||
| 24 | mul: PllMul::MUL7, // 16 * 7 = 112 MHz | ||
| 25 | divp: None, | ||
| 26 | divq: None, | ||
| 27 | divr: Some(PllRDiv::DIV2), // 112 / 2 = 56 MHz | ||
| 28 | }); | ||
| 29 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 30 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: false }); // needed for RNG | ||
| 31 | config.rcc.mux.clk48sel = Clk48sel::HSI48; // needed for RNG (or use MSI or PLLQ if you want) | ||
| 32 | } | ||
| 33 | |||
| 34 | let p = embassy_stm32::init(config); | ||
| 35 | |||
| 36 | info!("Hello World!"); | ||
| 37 | |||
| 38 | let mut rng = Rng::new(p.RNG, Irqs); | ||
| 39 | |||
| 40 | let mut buf = [0u8; 16]; | ||
| 41 | unwrap!(rng.async_fill_bytes(&mut buf).await); | ||
| 42 | info!("random bytes: {:02x}", buf); | ||
| 43 | } | ||
diff --git a/examples/stm32u0/src/bin/rtc.rs b/examples/stm32u0/src/bin/rtc.rs new file mode 100644 index 000000000..72fa0fde4 --- /dev/null +++ b/examples/stm32u0/src/bin/rtc.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use chrono::{NaiveDate, NaiveDateTime}; | ||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 8 | use embassy_stm32::Config; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | let mut config = Config::default(); | ||
| 15 | { | ||
| 16 | use embassy_stm32::rcc::*; | ||
| 17 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 18 | config.rcc.hsi = true; | ||
| 19 | config.rcc.pll = Some(Pll { | ||
| 20 | source: PllSource::HSI, // 16 MHz | ||
| 21 | prediv: PllPreDiv::DIV1, | ||
| 22 | mul: PllMul::MUL7, // 16 * 7 = 112 MHz | ||
| 23 | divp: None, | ||
| 24 | divq: None, | ||
| 25 | divr: Some(PllRDiv::DIV2), // 112 / 2 = 56 MHz | ||
| 26 | }); | ||
| 27 | config.rcc.ls = LsConfig::default(); | ||
| 28 | } | ||
| 29 | |||
| 30 | let p = embassy_stm32::init(config); | ||
| 31 | |||
| 32 | info!("Hello World!"); | ||
| 33 | |||
| 34 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | ||
| 35 | .unwrap() | ||
| 36 | .and_hms_opt(10, 30, 15) | ||
| 37 | .unwrap(); | ||
| 38 | |||
| 39 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 40 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | ||
| 41 | |||
| 42 | rtc.set_datetime(now.into()).expect("datetime not set"); | ||
| 43 | |||
| 44 | // In reality the delay would be much longer | ||
| 45 | Timer::after_millis(20000).await; | ||
| 46 | |||
| 47 | let then: NaiveDateTime = rtc.now().unwrap().into(); | ||
| 48 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | ||
| 49 | } | ||
diff --git a/examples/stm32u0/src/bin/spi.rs b/examples/stm32u0/src/bin/spi.rs new file mode 100644 index 000000000..5693a3765 --- /dev/null +++ b/examples/stm32u0/src/bin/spi.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 6 | use embassy_stm32::spi::{Config, Spi}; | ||
| 7 | use embassy_stm32::time::Hertz; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[cortex_m_rt::entry] | ||
| 11 | fn main() -> ! { | ||
| 12 | info!("Hello World!"); | ||
| 13 | |||
| 14 | let p = embassy_stm32::init(Default::default()); | ||
| 15 | |||
| 16 | let mut spi_config = Config::default(); | ||
| 17 | spi_config.frequency = Hertz(1_000_000); | ||
| 18 | |||
| 19 | let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config); | ||
| 20 | |||
| 21 | let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh); | ||
| 22 | |||
| 23 | loop { | ||
| 24 | let mut buf = [0x0Au8; 4]; | ||
| 25 | cs.set_low(); | ||
| 26 | unwrap!(spi.blocking_transfer_in_place(&mut buf)); | ||
| 27 | cs.set_high(); | ||
| 28 | info!("xfer {=[u8]:x}", buf); | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/examples/stm32u0/src/bin/usart.rs b/examples/stm32u0/src/bin/usart.rs new file mode 100644 index 000000000..037a5c833 --- /dev/null +++ b/examples/stm32u0/src/bin/usart.rs | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_stm32::usart::{Config, Uart}; | ||
| 6 | use {defmt_rtt as _, panic_probe as _}; | ||
| 7 | |||
| 8 | #[cortex_m_rt::entry] | ||
| 9 | fn main() -> ! { | ||
| 10 | info!("Hello World!"); | ||
| 11 | |||
| 12 | let p = embassy_stm32::init(Default::default()); | ||
| 13 | |||
| 14 | let config = Config::default(); | ||
| 15 | let mut usart = Uart::new_blocking(p.USART2, p.PA3, p.PA2, config).unwrap(); | ||
| 16 | |||
| 17 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | ||
| 18 | info!("wrote Hello, starting echo"); | ||
| 19 | |||
| 20 | let mut buf = [0u8; 1]; | ||
| 21 | loop { | ||
| 22 | unwrap!(usart.blocking_read(&mut buf)); | ||
| 23 | unwrap!(usart.blocking_write(&buf)); | ||
| 24 | } | ||
| 25 | } | ||
diff --git a/examples/stm32u0/src/bin/usb_serial.rs b/examples/stm32u0/src/bin/usb_serial.rs new file mode 100644 index 000000000..273f40643 --- /dev/null +++ b/examples/stm32u0/src/bin/usb_serial.rs | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{panic, *}; | ||
| 5 | use defmt_rtt as _; // global logger | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_futures::join::join; | ||
| 8 | use embassy_stm32::usb::{Driver, Instance}; | ||
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | ||
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | ||
| 11 | use embassy_usb::driver::EndpointError; | ||
| 12 | use embassy_usb::Builder; | ||
| 13 | use panic_probe as _; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | USB_DRD_FS => usb::InterruptHandler<peripherals::USB>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | let mut config = Config::default(); | ||
| 22 | { | ||
| 23 | use embassy_stm32::rcc::*; | ||
| 24 | config.rcc.hsi = true; | ||
| 25 | config.rcc.pll = Some(Pll { | ||
| 26 | source: PllSource::HSI, // 16 MHz | ||
| 27 | prediv: PllPreDiv::DIV1, | ||
| 28 | mul: PllMul::MUL7, | ||
| 29 | divp: None, | ||
| 30 | divq: None, | ||
| 31 | divr: Some(PllRDiv::DIV2), // 56 MHz | ||
| 32 | }); | ||
| 33 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 34 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 35 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; // USB uses ICLK | ||
| 36 | } | ||
| 37 | |||
| 38 | let p = embassy_stm32::init(config); | ||
| 39 | |||
| 40 | info!("Hello World!"); | ||
| 41 | |||
| 42 | // Create the driver, from the HAL. | ||
| 43 | let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); | ||
| 44 | |||
| 45 | // Create embassy-usb Config | ||
| 46 | let config = embassy_usb::Config::new(0xc0de, 0xcafe); | ||
| 47 | //config.max_packet_size_0 = 64; | ||
| 48 | |||
| 49 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 50 | // It needs some buffers for building the descriptors. | ||
| 51 | let mut config_descriptor = [0; 256]; | ||
| 52 | let mut bos_descriptor = [0; 256]; | ||
| 53 | let mut control_buf = [0; 7]; | ||
| 54 | |||
| 55 | let mut state = State::new(); | ||
| 56 | |||
| 57 | let mut builder = Builder::new( | ||
| 58 | driver, | ||
| 59 | config, | ||
| 60 | &mut config_descriptor, | ||
| 61 | &mut bos_descriptor, | ||
| 62 | &mut [], // no msos descriptors | ||
| 63 | &mut control_buf, | ||
| 64 | ); | ||
| 65 | |||
| 66 | // Create classes on the builder. | ||
| 67 | let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); | ||
| 68 | |||
| 69 | // Build the builder. | ||
| 70 | let mut usb = builder.build(); | ||
| 71 | |||
| 72 | // Run the USB device. | ||
| 73 | let usb_fut = usb.run(); | ||
| 74 | |||
| 75 | // Do stuff with the class! | ||
| 76 | let echo_fut = async { | ||
| 77 | loop { | ||
| 78 | class.wait_connection().await; | ||
| 79 | info!("Connected"); | ||
| 80 | let _ = echo(&mut class).await; | ||
| 81 | info!("Disconnected"); | ||
| 82 | } | ||
| 83 | }; | ||
| 84 | |||
| 85 | // Run everything concurrently. | ||
| 86 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 87 | join(usb_fut, echo_fut).await; | ||
| 88 | } | ||
| 89 | |||
| 90 | struct Disconnected {} | ||
| 91 | |||
| 92 | impl From<EndpointError> for Disconnected { | ||
| 93 | fn from(val: EndpointError) -> Self { | ||
| 94 | match val { | ||
| 95 | EndpointError::BufferOverflow => panic!("Buffer overflow"), | ||
| 96 | EndpointError::Disabled => Disconnected {}, | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { | ||
| 102 | let mut buf = [0; 64]; | ||
| 103 | loop { | ||
| 104 | let n = class.read_packet(&mut buf).await?; | ||
| 105 | let data = &buf[..n]; | ||
| 106 | info!("data: {:x}", data); | ||
| 107 | class.write_packet(data).await?; | ||
| 108 | } | ||
| 109 | } | ||
diff --git a/examples/stm32u0/src/bin/wdt.rs b/examples/stm32u0/src/bin/wdt.rs new file mode 100644 index 000000000..f6276e2e9 --- /dev/null +++ b/examples/stm32u0/src/bin/wdt.rs | |||
| @@ -0,0 +1,41 @@ | |||
| 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_stm32::wdg::IndependentWatchdog; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) { | ||
| 13 | let p = embassy_stm32::init(Default::default()); | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let mut led = Output::new(p.PA5, Level::High, Speed::Low); | ||
| 17 | |||
| 18 | let mut wdt = IndependentWatchdog::new(p.IWDG, 1_000_000); | ||
| 19 | wdt.unleash(); | ||
| 20 | |||
| 21 | let mut i = 0; | ||
| 22 | |||
| 23 | loop { | ||
| 24 | info!("high"); | ||
| 25 | led.set_high(); | ||
| 26 | Timer::after_millis(300).await; | ||
| 27 | |||
| 28 | info!("low"); | ||
| 29 | led.set_low(); | ||
| 30 | Timer::after_millis(300).await; | ||
| 31 | |||
| 32 | // Pet watchdog for 5 iterations and then stop. | ||
| 33 | // MCU should restart in 1 second after the last pet. | ||
| 34 | if i < 5 { | ||
| 35 | info!("Petting watchdog"); | ||
| 36 | wdt.pet(); | ||
| 37 | } | ||
| 38 | |||
| 39 | i += 1; | ||
| 40 | } | ||
| 41 | } | ||
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 03294339d..24c9263a3 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml | |||
| @@ -7,10 +7,11 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32u585ai to your chip name, if necessary. | 8 | # Change stm32u585ai to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 14 | 15 | ||
| 15 | defmt = "0.3" | 16 | defmt = "0.3" |
| 16 | defmt-rtt = "0.4" | 17 | defmt-rtt = "0.4" |
| @@ -19,10 +20,13 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 19 | cortex-m-rt = "0.7.0" | 20 | cortex-m-rt = "0.7.0" |
| 20 | embedded-hal = "0.2.6" | 21 | embedded-hal = "0.2.6" |
| 21 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 22 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 23 | heapless = { version = "0.8", default-features = false } | 23 | heapless = { version = "0.8", default-features = false } |
| 24 | 24 | ||
| 25 | micromath = "2.0.0" | 25 | micromath = "2.0.0" |
| 26 | 26 | ||
| 27 | [features] | ||
| 28 | ## Use secure registers when TrustZone is enabled | ||
| 29 | trustzone-secure = ["embassy-stm32/trustzone-secure"] | ||
| 30 | |||
| 27 | [profile.release] | 31 | [profile.release] |
| 28 | debug = 2 | 32 | debug = 2 |
diff --git a/examples/stm32u5/src/bin/i2c.rs b/examples/stm32u5/src/bin/i2c.rs index e376c6bc8..19a78eac9 100644 --- a/examples/stm32u5/src/bin/i2c.rs +++ b/examples/stm32u5/src/bin/i2c.rs | |||
| @@ -3,33 +3,17 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{info, unwrap}; | 4 | use defmt::{info, unwrap}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::i2c::I2c; | 6 | use embassy_stm32::i2c::I2c; |
| 8 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 9 | ||
| 12 | const HTS221_ADDRESS: u8 = 0x5F; | 10 | const HTS221_ADDRESS: u8 = 0x5F; |
| 13 | const WHOAMI: u8 = 0x0F; | 11 | const WHOAMI: u8 = 0x0F; |
| 14 | 12 | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 17 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 22 | let p = embassy_stm32::init(Default::default()); | 15 | let p = embassy_stm32::init(Default::default()); |
| 23 | let mut i2c = I2c::new( | 16 | let mut i2c = I2c::new_blocking(p.I2C2, p.PH4, p.PH5, Hertz(100_000), Default::default()); |
| 24 | p.I2C2, | ||
| 25 | p.PH4, | ||
| 26 | p.PH5, | ||
| 27 | Irqs, | ||
| 28 | NoDma, | ||
| 29 | NoDma, | ||
| 30 | Hertz(100_000), | ||
| 31 | Default::default(), | ||
| 32 | ); | ||
| 33 | 17 | ||
| 34 | let mut data = [0u8; 1]; | 18 | let mut data = [0u8; 1]; |
| 35 | unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data)); | 19 | unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data)); |
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 6a313efb0..4d56395da 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs | |||
| @@ -4,12 +4,12 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use defmt_rtt as _; // global logger | 5 | use defmt_rtt as _; // global logger |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_futures::join::join; | ||
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 8 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 12 | use embassy_usb::Builder; |
| 12 | use futures::future::join; | ||
| 13 | use panic_probe as _; | 13 | use panic_probe as _; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| @@ -43,6 +43,10 @@ async fn main(_spawner: Spawner) { | |||
| 43 | // Create the driver, from the HAL. | 43 | // Create the driver, from the HAL. |
| 44 | let mut ep_out_buffer = [0u8; 256]; | 44 | let mut ep_out_buffer = [0u8; 256]; |
| 45 | let mut config = embassy_stm32::usb::Config::default(); | 45 | let mut config = embassy_stm32::usb::Config::default(); |
| 46 | // Do not enable vbus_detection. This is a safe default that works in all boards. | ||
| 47 | // However, if your USB device is self-powered (can stay powered on if USB is unplugged), you need | ||
| 48 | // to enable vbus_detection to comply with the USB spec. If you enable it, the board | ||
| 49 | // has to support it or USB won't work at all. See docs on `vbus_detection` for details. | ||
| 46 | config.vbus_detection = false; | 50 | config.vbus_detection = false; |
| 47 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 51 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 48 | 52 | ||
diff --git a/examples/stm32wb/.cargo/config.toml b/examples/stm32wb/.cargo/config.toml index 51c499ee7..8b6d6d754 100644 --- a/examples/stm32wb/.cargo/config.toml +++ b/examples/stm32wb/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | # replace STM32WB55CCUx with your chip as listed in `probe-rs chip list` | 2 | # replace STM32WB55CCUx with your chip as listed in `probe-rs chip list` |
| 3 | # runner = "probe-run --chip STM32WB55RGVx --speed 1000 --connect-under-reset" | 3 | # runner = "probe-rs run --chip STM32WB55RGVx --speed 1000 --connect-under-reset" |
| 4 | runner = "teleprobe local run --chip STM32WB55RG --elf" | 4 | runner = "teleprobe local run --chip STM32WB55RG --elf" |
| 5 | 5 | ||
| 6 | [build] | 6 | [build] |
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 94a5141f5..92865b41c 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" | |||
| 8 | # Change stm32wb55rg to your chip name in both dependencies, if necessary. | 8 | # Change stm32wb55rg to your chip name in both dependencies, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } |
| 10 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } | 10 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } |
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 11 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } | 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } |
| @@ -20,7 +20,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 20 | cortex-m-rt = "0.7.0" | 20 | cortex-m-rt = "0.7.0" |
| 21 | embedded-hal = "0.2.6" | 21 | embedded-hal = "0.2.6" |
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 24 | heapless = { version = "0.8", default-features = false } | 23 | heapless = { version = "0.8", default-features = false } |
| 25 | static_cell = "2" | 24 | static_cell = "2" |
| 26 | 25 | ||
diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml index 47279a012..60f6e9201 100644 --- a/examples/stm32wba/Cargo.toml +++ b/examples/stm32wba/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } | 8 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } |
| 9 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 9 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 12 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } | 12 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } |
| @@ -18,7 +18,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 18 | cortex-m-rt = "0.7.0" | 18 | cortex-m-rt = "0.7.0" |
| 19 | embedded-hal = "0.2.6" | 19 | embedded-hal = "0.2.6" |
| 20 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 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 } | 21 | heapless = { version = "0.8", default-features = false } |
| 23 | static_cell = "2" | 22 | static_cell = "2" |
| 24 | 23 | ||
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 4cb55930b..29cd4d466 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml | |||
| @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32wl55jc-cm4 to your chip name, if necessary. | 8 | # Change stm32wl55jc-cm4 to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "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"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } | 13 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } |
| @@ -20,7 +20,6 @@ cortex-m-rt = "0.7.0" | |||
| 20 | embedded-hal = "0.2.6" | 20 | embedded-hal = "0.2.6" |
| 21 | embedded-storage = "0.3.1" | 21 | embedded-storage = "0.3.1" |
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 24 | heapless = { version = "0.8", default-features = false } | 23 | heapless = { version = "0.8", default-features = false } |
| 25 | chrono = { version = "^0.4", default-features = false } | 24 | chrono = { version = "^0.4", default-features = false } |
| 26 | 25 | ||
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index 3d2300b59..e7840d52e 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml | |||
| @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" | |||
| 8 | crate-type = ["cdylib"] | 8 | crate-type = ["cdylib"] |
| 9 | 9 | ||
| 10 | [dependencies] | 10 | [dependencies] |
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] } | 11 | embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["log"] } |
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "integrated-timers"] } | 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "integrated-timers"] } |
| 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "wasm", ] } | 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "wasm", ] } |
| 14 | 14 | ||
