diff options
206 files changed, 23136 insertions, 2546 deletions
| @@ -28,7 +28,7 @@ Rust's [async/await](https://rust-lang.github.io/async-book/) allows for unprece | |||
| 28 | No more messing with hardware timers. [embassy_time](https://docs.embassy.dev/embassy-time) provides Instant, Duration, and Timer types that are globally available and never overflow. | 28 | No more messing with hardware timers. [embassy_time](https://docs.embassy.dev/embassy-time) provides Instant, Duration, and Timer types that are globally available and never overflow. |
| 29 | 29 | ||
| 30 | - **Real-time ready** - | 30 | - **Real-time ready** - |
| 31 | Tasks on the same async executor run cooperatively, but you can create multiple executors with different priorities so that higher priority tasks preempt lower priority ones. See the [example](https://github.com/embassy-rs/embassy/blob/master/examples/nrf52840/src/bin/multiprio.rs). | 31 | Tasks on the same async executor run cooperatively, but you can create multiple executors with different priorities so that higher priority tasks preempt lower priority ones. See the [example](https://github.com/embassy-rs/embassy/blob/main/examples/nrf52840/src/bin/multiprio.rs). |
| 32 | 32 | ||
| 33 | - **Low-power ready** - | 33 | - **Low-power ready** - |
| 34 | Easily build devices with years of battery life. The async executor automatically puts the core to sleep when there's no work to do. Tasks are woken by interrupts, there is no busy-loop polling while waiting. | 34 | Easily build devices with years of battery life. The async executor automatically puts the core to sleep when there's no work to do. Tasks are woken by interrupts, there is no busy-loop polling while waiting. |
| @@ -49,7 +49,7 @@ Rust's [async/await](https://rust-lang.github.io/async-book/) allows for unprece | |||
| 49 | [embassy-usb](https://docs.embassy.dev/embassy-usb/) implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own. | 49 | [embassy-usb](https://docs.embassy.dev/embassy-usb/) implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own. |
| 50 | 50 | ||
| 51 | - **Bootloader and DFU** - | 51 | - **Bootloader and DFU** - |
| 52 | [embassy-boot](https://github.com/embassy-rs/embassy/tree/master/embassy-boot) is a lightweight bootloader supporting firmware application upgrades in a power-fail-safe way, with trial boots and rollbacks. | 52 | [embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) is a lightweight bootloader supporting firmware application upgrades in a power-fail-safe way, with trial boots and rollbacks. |
| 53 | 53 | ||
| 54 | ## Sneak peek | 54 | ## Sneak peek |
| 55 | 55 | ||
diff --git a/cyw43-pio/CHANGELOG.md b/cyw43-pio/CHANGELOG.md index ec38989e3..c2d18919c 100644 --- a/cyw43-pio/CHANGELOG.md +++ b/cyw43-pio/CHANGELOG.md | |||
| @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - Select pio program based on core clock speed #4792 | ||
| 12 | |||
| 11 | ## 0.8.0 - 2025-08-28 | 13 | ## 0.8.0 - 2025-08-28 |
| 12 | 14 | ||
| 13 | - Bump cyw43 version | 15 | - Bump cyw43 version |
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs index 41ac6816d..c8715e662 100644 --- a/cyw43-pio/src/lib.rs +++ b/cyw43-pio/src/lib.rs | |||
| @@ -7,6 +7,7 @@ use core::slice; | |||
| 7 | 7 | ||
| 8 | use cyw43::SpiBusCyw43; | 8 | use cyw43::SpiBusCyw43; |
| 9 | use embassy_rp::Peri; | 9 | use embassy_rp::Peri; |
| 10 | use embassy_rp::clocks::clk_sys_freq; | ||
| 10 | use embassy_rp::dma::Channel; | 11 | use embassy_rp::dma::Channel; |
| 11 | use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; | 12 | use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; |
| 12 | use embassy_rp::pio::program::pio_asm; | 13 | use embassy_rp::pio::program::pio_asm; |
| @@ -23,23 +24,24 @@ pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA: Channel> { | |||
| 23 | wrap_target: u8, | 24 | wrap_target: u8, |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | /// The default clock divider that works for Pico 1 and 2 W. As well as the RM2 on rp2040 devices. | 27 | /// Clock divider used for most applications |
| 27 | /// same speed as pico-sdk, 62.5Mhz | 28 | /// With default core clock configuration: |
| 28 | /// This is actually the fastest we can go without overclocking. | 29 | /// RP2350: 150Mhz / 2 = 75Mhz pio clock -> 37.5Mhz GSPI clock |
| 29 | /// According to data sheet, the theoretical maximum is 100Mhz Pio => 50Mhz SPI Freq. | 30 | /// RP2040: 133Mhz / 2 = 66.5Mhz pio clock -> 33.25Mhz GSPI clock |
| 30 | /// However, the PIO uses a fractional divider, which works by introducing jitter when | ||
| 31 | /// the divider is not an integer. It does some clocks at 125mhz and others at 62.5mhz | ||
| 32 | /// so that it averages out to the desired frequency of 100mhz. The 125mhz clock cycles | ||
| 33 | /// violate the maximum from the data sheet. | ||
| 34 | pub const DEFAULT_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0200); | 31 | pub const DEFAULT_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0200); |
| 35 | 32 | ||
| 36 | /// The overclock clock divider for the Pico 1 W. Does not work on any known RM2 devices. | 33 | /// Clock divider used to overclock the cyw43 |
| 37 | /// 125mhz Pio => 62.5Mhz SPI Freq. 25% higher than theoretical maximum according to | 34 | /// With default core clock configuration: |
| 38 | /// data sheet, but seems to work fine. | 35 | /// RP2350: 150Mhz / 1 = 150Mhz pio clock -> 75Mhz GSPI clock (50% greater that manufacturer |
| 36 | /// recommended 50Mhz) | ||
| 37 | /// RP2040: 133Mhz / 1 = 133Mhz pio clock -> 66.5Mhz GSPI clock (33% greater that manufacturer | ||
| 38 | /// recommended 50Mhz) | ||
| 39 | pub const OVERCLOCK_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0100); | 39 | pub const OVERCLOCK_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0100); |
| 40 | 40 | ||
| 41 | /// The clock divider for the RM2 module. Found to be needed for the Pimoroni Pico Plus 2 W, | 41 | /// Clock divider used with the RM2 |
| 42 | /// Pico Plus 2 Non w with the RM2 breakout module, and the Pico 2 with the RM2 breakout module. | 42 | /// With default core clock configuration: |
| 43 | /// RP2350: 150Mhz / 3 = 50Mhz pio clock -> 25Mhz GSPI clock | ||
| 44 | /// RP2040: 133Mhz / 3 = 44.33Mhz pio clock -> 22.16Mhz GSPI clock | ||
| 43 | pub const RM2_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0300); | 45 | pub const RM2_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0300); |
| 44 | 46 | ||
| 45 | impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> | 47 | impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> |
| @@ -58,7 +60,40 @@ where | |||
| 58 | clk: Peri<'d, impl PioPin>, | 60 | clk: Peri<'d, impl PioPin>, |
| 59 | dma: Peri<'d, DMA>, | 61 | dma: Peri<'d, DMA>, |
| 60 | ) -> Self { | 62 | ) -> Self { |
| 61 | let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER { | 63 | let effective_pio_frequency = (clk_sys_freq() as f32 / clock_divider.to_num::<f32>()) as u32; |
| 64 | |||
| 65 | #[cfg(feature = "defmt")] | ||
| 66 | defmt::trace!("Effective pio frequency: {}Hz", effective_pio_frequency); | ||
| 67 | |||
| 68 | // Non-integer pio clock dividers are achieved by introducing clock jitter resulting in a | ||
| 69 | // combination of long and short cycles. The long and short cycles average to achieve the | ||
| 70 | // requested clock speed. | ||
| 71 | // This can be a problem for peripherals that expect a consistent clock / have a clock | ||
| 72 | // speed upper bound that is violated by the short cycles. The cyw43 seems to handle the | ||
| 73 | // jitter well, but we emit a warning to recommend an integer divider anyway. | ||
| 74 | if clock_divider.frac() != FixedU32::<U8>::ZERO { | ||
| 75 | #[cfg(feature = "defmt")] | ||
| 76 | defmt::trace!( | ||
| 77 | "Configured clock divider is not a whole number. Some clock cycles may violate the maximum recommended GSPI speed. Use at your own risk." | ||
| 78 | ); | ||
| 79 | } | ||
| 80 | |||
| 81 | // Different pio programs must be used for different pio clock speeds. | ||
| 82 | // The programs used below are based on the pico SDK: https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.pio | ||
| 83 | // The clock speed cutoff for each program has been determined experimentally: | ||
| 84 | // > 100Mhz -> Overclock program | ||
| 85 | // [75Mhz, 100Mhz] -> High speed program | ||
| 86 | // [0, 75Mhz) -> Low speed program | ||
| 87 | let loaded_program = if effective_pio_frequency > 100_000_000 { | ||
| 88 | // Any frequency > 100Mhz is overclocking the chip (manufacturer recommends max 50Mhz GSPI | ||
| 89 | // clock) | ||
| 90 | // Example: | ||
| 91 | // * RP2040 @ 133Mhz (stock) with OVERCLOCK_CLOCK_DIVIDER (133MHz) | ||
| 92 | #[cfg(feature = "defmt")] | ||
| 93 | defmt::trace!( | ||
| 94 | "Configured clock divider results in a GSPI frequency greater than the manufacturer recommendation (50Mhz). Use at your own risk." | ||
| 95 | ); | ||
| 96 | |||
| 62 | let overclock_program = pio_asm!( | 97 | let overclock_program = pio_asm!( |
| 63 | ".side_set 1" | 98 | ".side_set 1" |
| 64 | 99 | ||
| @@ -69,7 +104,7 @@ where | |||
| 69 | "jmp x-- lp side 1" | 104 | "jmp x-- lp side 1" |
| 70 | // switch directions | 105 | // switch directions |
| 71 | "set pindirs, 0 side 0" | 106 | "set pindirs, 0 side 0" |
| 72 | "nop side 1" // necessary for clkdiv=1. | 107 | "nop side 1" |
| 73 | "nop side 0" | 108 | "nop side 0" |
| 74 | // read in y-1 bits | 109 | // read in y-1 bits |
| 75 | "lp2:" | 110 | "lp2:" |
| @@ -83,8 +118,47 @@ where | |||
| 83 | ".wrap" | 118 | ".wrap" |
| 84 | ); | 119 | ); |
| 85 | common.load_program(&overclock_program.program) | 120 | common.load_program(&overclock_program.program) |
| 121 | } else if effective_pio_frequency >= 75_000_000 { | ||
| 122 | // Experimentally determined cutoff. | ||
| 123 | // Notably includes the stock RP2350 configured with clk_div of 2 (150Mhz base clock / 2 = 75Mhz) | ||
| 124 | // but does not include stock RP2040 configured with clk_div of 2 (133Mhz base clock / 2 = 66.5Mhz) | ||
| 125 | // Example: | ||
| 126 | // * RP2350 @ 150Mhz (stock) with DEFAULT_CLOCK_DIVIDER (75Mhz) | ||
| 127 | // * RP2XXX @ 200Mhz with DEFAULT_CLOCK_DIVIDER (100Mhz) | ||
| 128 | #[cfg(feature = "defmt")] | ||
| 129 | defmt::trace!("Using high speed pio program."); | ||
| 130 | let high_speed_program = pio_asm!( | ||
| 131 | ".side_set 1" | ||
| 132 | |||
| 133 | ".wrap_target" | ||
| 134 | // write out x-1 bits | ||
| 135 | "lp:" | ||
| 136 | "out pins, 1 side 0" | ||
| 137 | "jmp x-- lp side 1" | ||
| 138 | // switch directions | ||
| 139 | "set pindirs, 0 side 0" | ||
| 140 | "nop side 1" | ||
| 141 | // read in y-1 bits | ||
| 142 | "lp2:" | ||
| 143 | "in pins, 1 side 0" | ||
| 144 | "jmp y-- lp2 side 1" | ||
| 145 | |||
| 146 | // wait for event and irq host | ||
| 147 | "wait 1 pin 0 side 0" | ||
| 148 | "irq 0 side 0" | ||
| 149 | |||
| 150 | ".wrap" | ||
| 151 | ); | ||
| 152 | common.load_program(&high_speed_program.program) | ||
| 86 | } else { | 153 | } else { |
| 87 | let default_program = pio_asm!( | 154 | // Low speed |
| 155 | // Examples: | ||
| 156 | // * RP2040 @ 133Mhz (stock) with DEFAULT_CLOCK_DIVIDER (66.5Mhz) | ||
| 157 | // * RP2040 @ 133Mhz (stock) with RM2_CLOCK_DIVIDER (44.3Mhz) | ||
| 158 | // * RP2350 @ 150Mhz (stock) with RM2_CLOCK_DIVIDER (50Mhz) | ||
| 159 | #[cfg(feature = "defmt")] | ||
| 160 | defmt::trace!("Using low speed pio program."); | ||
| 161 | let low_speed_program = pio_asm!( | ||
| 88 | ".side_set 1" | 162 | ".side_set 1" |
| 89 | 163 | ||
| 90 | ".wrap_target" | 164 | ".wrap_target" |
| @@ -106,7 +180,7 @@ where | |||
| 106 | 180 | ||
| 107 | ".wrap" | 181 | ".wrap" |
| 108 | ); | 182 | ); |
| 109 | common.load_program(&default_program.program) | 183 | common.load_program(&low_speed_program.program) |
| 110 | }; | 184 | }; |
| 111 | 185 | ||
| 112 | let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio); | 186 | let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio); |
diff --git a/docs/examples/basic/Cargo.toml b/docs/examples/basic/Cargo.toml index b90180853..fadda102b 100644 --- a/docs/examples/basic/Cargo.toml +++ b/docs/examples/basic/Cargo.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [package] | 1 | [package] |
| 2 | authors = ["Dario Nieuwenhuis <[email protected]>"] | 2 | authors = ["Dario Nieuwenhuis <[email protected]>"] |
| 3 | edition = "2018" | 3 | edition = "2024" |
| 4 | name = "embassy-basic-example" | 4 | name = "embassy-basic-example" |
| 5 | version = "0.1.0" | 5 | version = "0.1.0" |
| 6 | license = "MIT OR Apache-2.0" | 6 | license = "MIT OR Apache-2.0" |
diff --git a/docs/examples/basic/src/main.rs b/docs/examples/basic/src/main.rs index 6e274bacb..42797612c 100644 --- a/docs/examples/basic/src/main.rs +++ b/docs/examples/basic/src/main.rs | |||
| @@ -3,24 +3,41 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 6 | use embassy_nrf::Peri; |
| 7 | use embassy_time::{Duration, Timer}; | 7 | use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pull}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; // global logger | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | 10 | ||
| 11 | // Declare async tasks | ||
| 10 | #[embassy_executor::task] | 12 | #[embassy_executor::task] |
| 11 | async fn blinker(mut led: Output<'static>, interval: Duration) { | 13 | async fn blink(pin: Peri<'static, AnyPin>) { |
| 14 | let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); | ||
| 15 | |||
| 12 | loop { | 16 | loop { |
| 17 | // Timekeeping is globally available, no need to mess with hardware timers. | ||
| 13 | led.set_high(); | 18 | led.set_high(); |
| 14 | Timer::after(interval).await; | 19 | Timer::after_millis(150).await; |
| 15 | led.set_low(); | 20 | led.set_low(); |
| 16 | Timer::after(interval).await; | 21 | Timer::after_millis(150).await; |
| 17 | } | 22 | } |
| 18 | } | 23 | } |
| 19 | 24 | ||
| 25 | // Main is itself an async task as well. | ||
| 20 | #[embassy_executor::main] | 26 | #[embassy_executor::main] |
| 21 | async fn main(spawner: Spawner) { | 27 | async fn main(spawner: Spawner) { |
| 28 | // Initialize the embassy-nrf HAL. | ||
| 22 | let p = embassy_nrf::init(Default::default()); | 29 | let p = embassy_nrf::init(Default::default()); |
| 23 | 30 | ||
| 24 | let led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); | 31 | // Spawned tasks run in the background, concurrently. |
| 25 | spawner.spawn(unwrap!(blinker(led, Duration::from_millis(300)))); | 32 | spawner.spawn(blink(p.P0_13.into()).unwrap()); |
| 33 | |||
| 34 | let mut button = Input::new(p.P0_11, Pull::Up); | ||
| 35 | loop { | ||
| 36 | // Asynchronously wait for GPIO events, allowing other tasks | ||
| 37 | // to run, or the core to sleep. | ||
| 38 | button.wait_for_low().await; | ||
| 39 | info!("Button pressed!"); | ||
| 40 | button.wait_for_high().await; | ||
| 41 | info!("Button released!"); | ||
| 42 | } | ||
| 26 | } | 43 | } |
diff --git a/docs/pages/embassy_in_the_wild.adoc b/docs/pages/embassy_in_the_wild.adoc index 3b58bb9b4..0792130eb 100644 --- a/docs/pages/embassy_in_the_wild.adoc +++ b/docs/pages/embassy_in_the_wild.adoc | |||
| @@ -4,6 +4,10 @@ Here are known examples of real-world projects which make use of Embassy. Feel f | |||
| 4 | 4 | ||
| 5 | _newer entries at the top_ | 5 | _newer entries at the top_ |
| 6 | 6 | ||
| 7 | * link:https://github.com/thataquarel/protovolt[ProtoV MINI: A USB-C mini lab power supply] | ||
| 8 | ** A dual-channel USB PD powered breadboard power supply based on the RP2040, running embedded graphics. Open-source schematics and firmware. | ||
| 9 | * link:https://github.com/Dawson-HEP/opentrig/[Opentrig: A particle physics trigger and data acquisition system] | ||
| 10 | ** Digital event trigger with threshold, data acquisition system designed to interface with AIDA-2020 TLU systems, tested at the DESY II Test Beam Facility. Based on the RP2040, and Embassy's async event handling. | ||
| 7 | * link:https://github.com/1-rafael-1/air-quality-monitor[Air Quality Monitor] | 11 | * link:https://github.com/1-rafael-1/air-quality-monitor[Air Quality Monitor] |
| 8 | ** Air Quality Monitor based on rp2350 board, ens160 and aht21 sensors and ssd1306 display. Code and 3D printable enclosure included. | 12 | ** Air Quality Monitor based on rp2350 board, ens160 and aht21 sensors and ssd1306 display. Code and 3D printable enclosure included. |
| 9 | * link:https://github.com/CarlKCarlK/clock[Embassy Clock: Layered, modular bare-metal clock with emulation] | 13 | * link:https://github.com/CarlKCarlK/clock[Embassy Clock: Layered, modular bare-metal clock with emulation] |
diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index 47a8ae995..5fbb8cf13 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md | |||
| @@ -13,7 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 13 | - Upgraded rtos-trace | 13 | - Upgraded rtos-trace |
| 14 | - Added optional "highest priority" scheduling | 14 | - Added optional "highest priority" scheduling |
| 15 | - Added optional "earliest deadline first" EDF scheduling | 15 | - Added optional "earliest deadline first" EDF scheduling |
| 16 | - Bump `cortex-ar` to v0.3 | 16 | - Migrate `cortex-ar` to `aarch32-cpu`. The feature name `arch-cortex-ar` remains the same and |
| 17 | legacy ARM architectures are not supported. | ||
| 17 | 18 | ||
| 18 | ## 0.9.1 - 2025-08-31 | 19 | ## 0.9.1 - 2025-08-31 |
| 19 | 20 | ||
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index ecc4b6338..d3e5b241a 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml | |||
| @@ -30,6 +30,7 @@ build = [ | |||
| 30 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "embassy-time-driver", "scheduler-deadline"]}, | 30 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "embassy-time-driver", "scheduler-deadline"]}, |
| 31 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "scheduler-priority", "scheduler-deadline"]}, | 31 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "scheduler-priority", "scheduler-deadline"]}, |
| 32 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "scheduler-deadline"]}, | 32 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "scheduler-deadline"]}, |
| 33 | {target = "thumbv7em-none-eabi", features = ["arch-cortex-m", "executor-interrupt", "executor-thread", "embassy-time-driver", "scheduler-priority", "scheduler-deadline", "trace"]}, | ||
| 33 | {target = "thumbv7em-none-eabi", features = ["arch-spin"]}, | 34 | {target = "thumbv7em-none-eabi", features = ["arch-spin"]}, |
| 34 | {target = "thumbv7em-none-eabi", features = ["arch-spin", "scheduler-deadline"]}, | 35 | {target = "thumbv7em-none-eabi", features = ["arch-spin", "scheduler-deadline"]}, |
| 35 | {target = "armv7a-none-eabi", features = ["arch-cortex-ar", "executor-thread"]}, | 36 | {target = "armv7a-none-eabi", features = ["arch-cortex-ar", "executor-thread"]}, |
| @@ -37,6 +38,7 @@ build = [ | |||
| 37 | {target = "armv7r-none-eabihf", features = ["arch-cortex-ar", "executor-thread"]}, | 38 | {target = "armv7r-none-eabihf", features = ["arch-cortex-ar", "executor-thread"]}, |
| 38 | {target = "riscv32imac-unknown-none-elf", features = ["arch-riscv32"]}, | 39 | {target = "riscv32imac-unknown-none-elf", features = ["arch-riscv32"]}, |
| 39 | {target = "riscv32imac-unknown-none-elf", features = ["arch-riscv32", "executor-thread"]}, | 40 | {target = "riscv32imac-unknown-none-elf", features = ["arch-riscv32", "executor-thread"]}, |
| 41 | {target = "riscv32imac-unknown-none-elf", features = ["arch-riscv32", "executor-thread", "trace"]}, | ||
| 40 | # Nightly builds | 42 | # Nightly builds |
| 41 | {group = "nightly", target = "thumbv7em-none-eabi", features = ["nightly"]}, | 43 | {group = "nightly", target = "thumbv7em-none-eabi", features = ["nightly"]}, |
| 42 | {group = "nightly", target = "thumbv7em-none-eabi", features = ["nightly", "log"]}, | 44 | {group = "nightly", target = "thumbv7em-none-eabi", features = ["nightly", "log"]}, |
| @@ -100,7 +102,7 @@ portable-atomic = { version = "1.5", optional = true } | |||
| 100 | cortex-m = { version = "0.7.6", optional = true } | 102 | cortex-m = { version = "0.7.6", optional = true } |
| 101 | 103 | ||
| 102 | # arch-cortex-ar dependencies | 104 | # arch-cortex-ar dependencies |
| 103 | cortex-ar = { version = "0.3", optional = true } | 105 | aarch32-cpu = { version = "0.1", optional = true } |
| 104 | 106 | ||
| 105 | # arch-wasm dependencies | 107 | # arch-wasm dependencies |
| 106 | wasm-bindgen = { version = "0.2.82", optional = true } | 108 | wasm-bindgen = { version = "0.2.82", optional = true } |
| @@ -128,7 +130,7 @@ nightly = ["embassy-executor-macros/nightly"] | |||
| 128 | ## Enable defmt logging | 130 | ## Enable defmt logging |
| 129 | defmt = ["dep:defmt"] | 131 | defmt = ["dep:defmt"] |
| 130 | 132 | ||
| 131 | ## Enable log logging | 133 | ## Enable log logging |
| 132 | log = ["dep:log"] | 134 | log = ["dep:log"] |
| 133 | 135 | ||
| 134 | # Enables turbo wakers, which requires patching core. Not surfaced in the docs by default due to | 136 | # Enables turbo wakers, which requires patching core. Not surfaced in the docs by default due to |
| @@ -143,7 +145,7 @@ arch-std = ["_arch"] | |||
| 143 | ## Cortex-M | 145 | ## Cortex-M |
| 144 | arch-cortex-m = ["_arch", "dep:cortex-m"] | 146 | arch-cortex-m = ["_arch", "dep:cortex-m"] |
| 145 | ## Cortex-A/R | 147 | ## Cortex-A/R |
| 146 | arch-cortex-ar = ["_arch", "dep:cortex-ar"] | 148 | arch-cortex-ar = ["_arch", "dep:aarch32-cpu", "dep:arm-targets"] |
| 147 | ## RISC-V 32 | 149 | ## RISC-V 32 |
| 148 | arch-riscv32 = ["_arch"] | 150 | arch-riscv32 = ["_arch"] |
| 149 | ## WASM | 151 | ## WASM |
| @@ -180,3 +182,6 @@ scheduler-priority = [] | |||
| 180 | ## Enable the embassy_time_driver dependency. | 182 | ## Enable the embassy_time_driver dependency. |
| 181 | ## This can unlock extra APIs, for example for the `sheduler-deadline` | 183 | ## This can unlock extra APIs, for example for the `sheduler-deadline` |
| 182 | embassy-time-driver = ["dep:embassy-time-driver"] | 184 | embassy-time-driver = ["dep:embassy-time-driver"] |
| 185 | |||
| 186 | [build-dependencies] | ||
| 187 | arm-targets = { version = "0.4", optional = true } | ||
diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs index 37becde3e..36e23a632 100644 --- a/embassy-executor/build.rs +++ b/embassy-executor/build.rs | |||
| @@ -4,4 +4,9 @@ mod common; | |||
| 4 | fn main() { | 4 | fn main() { |
| 5 | let mut rustc_cfgs = common::CfgSet::new(); | 5 | let mut rustc_cfgs = common::CfgSet::new(); |
| 6 | common::set_target_cfgs(&mut rustc_cfgs); | 6 | common::set_target_cfgs(&mut rustc_cfgs); |
| 7 | |||
| 8 | // This is used to exclude legacy architecture support. The raw executor needs to be used for | ||
| 9 | // those architectures because SEV/WFE are not supported. | ||
| 10 | #[cfg(feature = "arch-cortex-ar")] | ||
| 11 | arm_targets::process(); | ||
| 7 | } | 12 | } |
diff --git a/embassy-executor/src/arch/cortex_ar.rs b/embassy-executor/src/arch/cortex_ar.rs index a9be3d323..ce572738a 100644 --- a/embassy-executor/src/arch/cortex_ar.rs +++ b/embassy-executor/src/arch/cortex_ar.rs | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | #[cfg(arm_profile = "legacy")] | ||
| 2 | compile_error!("`arch-cortex-ar` does not support the legacy ARM profile, WFE/SEV are not available."); | ||
| 3 | |||
| 1 | #[cfg(feature = "executor-interrupt")] | 4 | #[cfg(feature = "executor-interrupt")] |
| 2 | compile_error!("`executor-interrupt` is not supported with `arch-cortex-ar`."); | 5 | compile_error!("`executor-interrupt` is not supported with `arch-cortex-ar`."); |
| 3 | 6 | ||
| @@ -10,7 +13,7 @@ fn __pender(context: *mut ()) { | |||
| 10 | #[cfg(feature = "executor-thread")] | 13 | #[cfg(feature = "executor-thread")] |
| 11 | // Try to make Rust optimize the branching away if we only use thread mode. | 14 | // Try to make Rust optimize the branching away if we only use thread mode. |
| 12 | if !cfg!(feature = "executor-interrupt") || context == THREAD_PENDER { | 15 | if !cfg!(feature = "executor-interrupt") || context == THREAD_PENDER { |
| 13 | cortex_ar::asm::sev(); | 16 | aarch32_cpu::asm::sev(); |
| 14 | return; | 17 | return; |
| 15 | } | 18 | } |
| 16 | } | 19 | } |
| @@ -23,7 +26,7 @@ mod thread { | |||
| 23 | 26 | ||
| 24 | use core::marker::PhantomData; | 27 | use core::marker::PhantomData; |
| 25 | 28 | ||
| 26 | use cortex_ar::asm::wfe; | 29 | use aarch32_cpu::asm::wfe; |
| 27 | pub use embassy_executor_macros::main_cortex_ar as main; | 30 | pub use embassy_executor_macros::main_cortex_ar as main; |
| 28 | 31 | ||
| 29 | use crate::{Spawner, raw}; | 32 | use crate::{Spawner, raw}; |
diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs index 74519b927..830162039 100644 --- a/embassy-executor/src/raw/trace.rs +++ b/embassy-executor/src/raw/trace.rs | |||
| @@ -169,7 +169,7 @@ impl TaskTracker { | |||
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | #[cfg(feature = "trace")] | 171 | #[cfg(feature = "trace")] |
| 172 | extern "Rust" { | 172 | unsafe extern "Rust" { |
| 173 | /// This callback is called when the executor begins polling. This will always | 173 | /// This callback is called when the executor begins polling. This will always |
| 174 | /// be paired with a later call to `_embassy_trace_executor_idle`. | 174 | /// be paired with a later call to `_embassy_trace_executor_idle`. |
| 175 | /// | 175 | /// |
diff --git a/embassy-mspm0/CHANGELOG.md b/embassy-mspm0/CHANGELOG.md index 948f0205d..f0b5868f4 100644 --- a/embassy-mspm0/CHANGELOG.md +++ b/embassy-mspm0/CHANGELOG.md | |||
| @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 7 | 7 | ||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - feat: Add I2C Controller (blocking & async) + examples for mspm0l1306, mspm0g3507 (tested MCUs) (#4435) | 11 | - feat: Add I2C Controller (blocking & async) + examples for mspm0l1306, mspm0g3507 (tested MCUs) (#4435) |
| 12 | - fix gpio interrupt not being set for mspm0l110x | 12 | - fix gpio interrupt not being set for mspm0l110x |
| 13 | - feat: Add window watchdog implementation based on WWDT0, WWDT1 peripherals (#4574) | 13 | - feat: Add window watchdog implementation based on WWDT0, WWDT1 peripherals (#4574) |
| @@ -16,3 +16,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 16 | - fix: gpio OutputOpenDrain config (#4735) | 16 | - fix: gpio OutputOpenDrain config (#4735) |
| 17 | - fix: add MSPM0C1106 to build test matrix | 17 | - fix: add MSPM0C1106 to build test matrix |
| 18 | - feat: add MSPM0H3216 support | 18 | - feat: add MSPM0H3216 support |
| 19 | - feat: Add i2c target implementation (#4605) | ||
| 20 | - fix: group irq handlers must check for NO_INTR (#4785) | ||
| 21 | - feat: Add read_reset_cause function | ||
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index df6176ff6..b76bc7e41 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml | |||
| @@ -72,7 +72,7 @@ cortex-m = "0.7.6" | |||
| 72 | critical-section = "1.2.0" | 72 | critical-section = "1.2.0" |
| 73 | 73 | ||
| 74 | # mspm0-metapac = { version = "" } | 74 | # mspm0-metapac = { version = "" } |
| 75 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-e7de4103a0713772695ffcad52c3c2f07414dc29" } | 75 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-8542f260cc89645a983b7f1a874c87b21822279e" } |
| 76 | 76 | ||
| 77 | [build-dependencies] | 77 | [build-dependencies] |
| 78 | proc-macro2 = "1.0.94" | 78 | proc-macro2 = "1.0.94" |
| @@ -80,7 +80,7 @@ quote = "1.0.40" | |||
| 80 | cfg_aliases = "0.2.1" | 80 | cfg_aliases = "0.2.1" |
| 81 | 81 | ||
| 82 | # mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } | 82 | # mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } |
| 83 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-e7de4103a0713772695ffcad52c3c2f07414dc29", default-features = false, features = ["metadata"] } | 83 | mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-8542f260cc89645a983b7f1a874c87b21822279e", default-features = false, features = ["metadata"] } |
| 84 | 84 | ||
| 85 | [features] | 85 | [features] |
| 86 | default = ["rt"] | 86 | default = ["rt"] |
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs index 1d118ad66..4942364aa 100644 --- a/embassy-mspm0/build.rs +++ b/embassy-mspm0/build.rs | |||
| @@ -194,8 +194,15 @@ fn generate_groups() -> TokenStream { | |||
| 194 | use crate::pac::#group_enum; | 194 | use crate::pac::#group_enum; |
| 195 | 195 | ||
| 196 | let group = crate::pac::CPUSS.int_group(#group_number); | 196 | let group = crate::pac::CPUSS.int_group(#group_number); |
| 197 | // MUST subtract by 1 since 0 is NO_INTR | 197 | let stat = group.iidx().read().stat(); |
| 198 | let iidx = group.iidx().read().stat().to_bits() - 1; | 198 | |
| 199 | // check for spurious interrupts | ||
| 200 | if stat == crate::pac::cpuss::vals::Iidx::NO_INTR { | ||
| 201 | return; | ||
| 202 | } | ||
| 203 | |||
| 204 | // MUST subtract by 1 because NO_INTR offsets IIDX values. | ||
| 205 | let iidx = stat.to_bits() - 1; | ||
| 199 | 206 | ||
| 200 | let Ok(group) = #group_enum::try_from(iidx as u8) else { | 207 | let Ok(group) = #group_enum::try_from(iidx as u8) else { |
| 201 | return; | 208 | return; |
diff --git a/embassy-mspm0/src/i2c.rs b/embassy-mspm0/src/i2c.rs index 192527dd2..3067f4833 100644 --- a/embassy-mspm0/src/i2c.rs +++ b/embassy-mspm0/src/i2c.rs | |||
| @@ -56,7 +56,7 @@ pub enum ClockDiv { | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | impl ClockDiv { | 58 | impl ClockDiv { |
| 59 | fn into(self) -> vals::Ratio { | 59 | pub(crate) fn into(self) -> vals::Ratio { |
| 60 | match self { | 60 | match self { |
| 61 | Self::DivBy1 => vals::Ratio::DIV_BY_1, | 61 | Self::DivBy1 => vals::Ratio::DIV_BY_1, |
| 62 | Self::DivBy2 => vals::Ratio::DIV_BY_2, | 62 | Self::DivBy2 => vals::Ratio::DIV_BY_2, |
| @@ -133,6 +133,11 @@ pub enum ConfigError { | |||
| 133 | /// | 133 | /// |
| 134 | /// The clock soure is not enabled is SYSCTL. | 134 | /// The clock soure is not enabled is SYSCTL. |
| 135 | ClockSourceNotEnabled, | 135 | ClockSourceNotEnabled, |
| 136 | |||
| 137 | /// Invalid target address. | ||
| 138 | /// | ||
| 139 | /// The target address is not 7-bit. | ||
| 140 | InvalidTargetAddress, | ||
| 136 | } | 141 | } |
| 137 | 142 | ||
| 138 | #[non_exhaustive] | 143 | #[non_exhaustive] |
| @@ -140,7 +145,7 @@ pub enum ConfigError { | |||
| 140 | /// Config | 145 | /// Config |
| 141 | pub struct Config { | 146 | pub struct Config { |
| 142 | /// I2C clock source. | 147 | /// I2C clock source. |
| 143 | clock_source: ClockSel, | 148 | pub(crate) clock_source: ClockSel, |
| 144 | 149 | ||
| 145 | /// I2C clock divider. | 150 | /// I2C clock divider. |
| 146 | pub clock_div: ClockDiv, | 151 | pub clock_div: ClockDiv, |
| @@ -196,7 +201,7 @@ impl Config { | |||
| 196 | } | 201 | } |
| 197 | 202 | ||
| 198 | #[cfg(any(mspm0c110x, mspm0c1105_c1106))] | 203 | #[cfg(any(mspm0c110x, mspm0c1105_c1106))] |
| 199 | fn calculate_clock_source(&self) -> u32 { | 204 | pub(crate) fn calculate_clock_source(&self) -> u32 { |
| 200 | // Assume that BusClk has default value. | 205 | // Assume that BusClk has default value. |
| 201 | // TODO: calculate BusClk more precisely. | 206 | // TODO: calculate BusClk more precisely. |
| 202 | match self.clock_source { | 207 | match self.clock_source { |
| @@ -209,7 +214,7 @@ impl Config { | |||
| 209 | mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x, mspm0h321x, mspm0l110x, mspm0l122x, | 214 | mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x, mspm0h321x, mspm0l110x, mspm0l122x, |
| 210 | mspm0l130x, mspm0l134x, mspm0l222x | 215 | mspm0l130x, mspm0l134x, mspm0l222x |
| 211 | ))] | 216 | ))] |
| 212 | fn calculate_clock_source(&self) -> u32 { | 217 | pub(crate) fn calculate_clock_source(&self) -> u32 { |
| 213 | // Assume that BusClk has default value. | 218 | // Assume that BusClk has default value. |
| 214 | // TODO: calculate BusClk more precisely. | 219 | // TODO: calculate BusClk more precisely. |
| 215 | match self.clock_source { | 220 | match self.clock_source { |
diff --git a/embassy-mspm0/src/i2c_target.rs b/embassy-mspm0/src/i2c_target.rs new file mode 100644 index 000000000..86be91415 --- /dev/null +++ b/embassy-mspm0/src/i2c_target.rs | |||
| @@ -0,0 +1,509 @@ | |||
| 1 | //! Inter-Integrated-Circuit (I2C) Target | ||
| 2 | // The following code is modified from embassy-stm32 and embassy-rp | ||
| 3 | // https://github.com/embassy-rs/embassy/tree/main/embassy-stm32 | ||
| 4 | // https://github.com/embassy-rs/embassy/tree/main/embassy-rp | ||
| 5 | |||
| 6 | use core::future::poll_fn; | ||
| 7 | use core::marker::PhantomData; | ||
| 8 | use core::sync::atomic::Ordering; | ||
| 9 | use core::task::Poll; | ||
| 10 | |||
| 11 | use embassy_embedded_hal::SetConfig; | ||
| 12 | use mspm0_metapac::i2c::vals::CpuIntIidxStat; | ||
| 13 | |||
| 14 | use crate::gpio::{AnyPin, SealedPin}; | ||
| 15 | use crate::interrupt::InterruptExt; | ||
| 16 | use crate::mode::{Async, Blocking, Mode}; | ||
| 17 | use crate::pac::{self, i2c::vals}; | ||
| 18 | use crate::{i2c, i2c_target, interrupt, Peri}; | ||
| 19 | // Re-use I2c controller types | ||
| 20 | use crate::i2c::{ClockSel, ConfigError, Info, Instance, InterruptHandler, SclPin, SdaPin, State}; | ||
| 21 | |||
| 22 | #[non_exhaustive] | ||
| 23 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 24 | /// Config | ||
| 25 | pub struct Config { | ||
| 26 | /// 7-bit Target Address | ||
| 27 | pub target_addr: u8, | ||
| 28 | |||
| 29 | /// Control if the target should ack to and report general calls. | ||
| 30 | pub general_call: bool, | ||
| 31 | } | ||
| 32 | |||
| 33 | impl Default for Config { | ||
| 34 | fn default() -> Self { | ||
| 35 | Self { | ||
| 36 | target_addr: 0x48, | ||
| 37 | general_call: false, | ||
| 38 | } | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | /// I2C error | ||
| 43 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
| 44 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 45 | #[non_exhaustive] | ||
| 46 | pub enum Error { | ||
| 47 | /// User passed in a response buffer that was 0 length | ||
| 48 | InvalidResponseBufferLength, | ||
| 49 | /// The response buffer length was too short to contain the message | ||
| 50 | /// | ||
| 51 | /// The length parameter will always be the length of the buffer, and is | ||
| 52 | /// provided as a convenience for matching alongside `Command::Write`. | ||
| 53 | PartialWrite(usize), | ||
| 54 | /// The response buffer length was too short to contain the message | ||
| 55 | /// | ||
| 56 | /// The length parameter will always be the length of the buffer, and is | ||
| 57 | /// provided as a convenience for matching alongside `Command::GeneralCall`. | ||
| 58 | PartialGeneralCall(usize), | ||
| 59 | } | ||
| 60 | |||
| 61 | /// Received command from the controller. | ||
| 62 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||
| 63 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 64 | pub enum Command { | ||
| 65 | /// General Call Write: Controller sent the General Call address (0x00) followed by data. | ||
| 66 | /// Contains the number of bytes written by the controller. | ||
| 67 | GeneralCall(usize), | ||
| 68 | /// Read: Controller wants to read data from the target. | ||
| 69 | Read, | ||
| 70 | /// Write: Controller sent the target's address followed by data. | ||
| 71 | /// Contains the number of bytes written by the controller. | ||
| 72 | Write(usize), | ||
| 73 | /// Write followed by Read (Repeated Start): Controller wrote data, then issued a repeated | ||
| 74 | /// start and wants to read data. Contains the number of bytes written before the read. | ||
| 75 | WriteRead(usize), | ||
| 76 | } | ||
| 77 | |||
| 78 | /// Status after responding to a controller read request. | ||
| 79 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||
| 80 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 81 | pub enum ReadStatus { | ||
| 82 | /// Transaction completed successfully. The controller either NACKed the last byte | ||
| 83 | /// or sent a STOP condition. | ||
| 84 | Done, | ||
| 85 | /// Transaction incomplete, controller trying to read more bytes than were provided | ||
| 86 | NeedMoreBytes, | ||
| 87 | /// Transaction complete, but controller stopped reading bytes before we ran out | ||
| 88 | LeftoverBytes(u16), | ||
| 89 | } | ||
| 90 | |||
| 91 | /// I2C Target driver. | ||
| 92 | // Use the same Instance, SclPin, SdaPin traits as the controller | ||
| 93 | pub struct I2cTarget<'d, M: Mode> { | ||
| 94 | info: &'static Info, | ||
| 95 | state: &'static State, | ||
| 96 | scl: Option<Peri<'d, AnyPin>>, | ||
| 97 | sda: Option<Peri<'d, AnyPin>>, | ||
| 98 | config: i2c::Config, | ||
| 99 | target_config: i2c_target::Config, | ||
| 100 | _phantom: PhantomData<M>, | ||
| 101 | } | ||
| 102 | |||
| 103 | impl<'d> SetConfig for I2cTarget<'d, Async> { | ||
| 104 | type Config = (i2c::Config, i2c_target::Config); | ||
| 105 | type ConfigError = ConfigError; | ||
| 106 | |||
| 107 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { | ||
| 108 | self.info.interrupt.disable(); | ||
| 109 | |||
| 110 | if let Some(ref sda) = self.sda { | ||
| 111 | sda.update_pf(config.0.sda_pf()); | ||
| 112 | } | ||
| 113 | |||
| 114 | if let Some(ref scl) = self.scl { | ||
| 115 | scl.update_pf(config.0.scl_pf()); | ||
| 116 | } | ||
| 117 | |||
| 118 | self.config = config.0.clone(); | ||
| 119 | self.target_config = config.1.clone(); | ||
| 120 | |||
| 121 | self.reset() | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | impl<'d> SetConfig for I2cTarget<'d, Blocking> { | ||
| 126 | type Config = (i2c::Config, i2c_target::Config); | ||
| 127 | type ConfigError = ConfigError; | ||
| 128 | |||
| 129 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { | ||
| 130 | if let Some(ref sda) = self.sda { | ||
| 131 | sda.update_pf(config.0.sda_pf()); | ||
| 132 | } | ||
| 133 | |||
| 134 | if let Some(ref scl) = self.scl { | ||
| 135 | scl.update_pf(config.0.scl_pf()); | ||
| 136 | } | ||
| 137 | |||
| 138 | self.config = config.0.clone(); | ||
| 139 | self.target_config = config.1.clone(); | ||
| 140 | |||
| 141 | self.reset() | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | impl<'d> I2cTarget<'d, Async> { | ||
| 146 | /// Create a new asynchronous I2C target driver using interrupts | ||
| 147 | /// The `config` reuses the i2c controller config to setup the clock while `target_config` | ||
| 148 | /// configures i2c target specific parameters. | ||
| 149 | pub fn new<T: Instance>( | ||
| 150 | peri: Peri<'d, T>, | ||
| 151 | scl: Peri<'d, impl SclPin<T>>, | ||
| 152 | sda: Peri<'d, impl SdaPin<T>>, | ||
| 153 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||
| 154 | config: i2c::Config, | ||
| 155 | target_config: i2c_target::Config, | ||
| 156 | ) -> Result<Self, ConfigError> { | ||
| 157 | let mut this = Self::new_inner( | ||
| 158 | peri, | ||
| 159 | new_pin!(scl, config.scl_pf()), | ||
| 160 | new_pin!(sda, config.sda_pf()), | ||
| 161 | config, | ||
| 162 | target_config, | ||
| 163 | ); | ||
| 164 | this.reset()?; | ||
| 165 | Ok(this) | ||
| 166 | } | ||
| 167 | |||
| 168 | /// Reset the i2c peripheral. If you cancel a respond_to_read, you may stall the bus. | ||
| 169 | /// You can recover the bus by calling this function, but doing so will almost certainly cause | ||
| 170 | /// an i/o error in the controller. | ||
| 171 | pub fn reset(&mut self) -> Result<(), ConfigError> { | ||
| 172 | self.init()?; | ||
| 173 | unsafe { self.info.interrupt.enable() }; | ||
| 174 | Ok(()) | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | impl<'d> I2cTarget<'d, Blocking> { | ||
| 179 | /// Create a new blocking I2C target driver. | ||
| 180 | /// The `config` reuses the i2c controller config to setup the clock while `target_config` | ||
| 181 | /// configures i2c target specific parameters. | ||
| 182 | pub fn new_blocking<T: Instance>( | ||
| 183 | peri: Peri<'d, T>, | ||
| 184 | scl: Peri<'d, impl SclPin<T>>, | ||
| 185 | sda: Peri<'d, impl SdaPin<T>>, | ||
| 186 | config: i2c::Config, | ||
| 187 | target_config: i2c_target::Config, | ||
| 188 | ) -> Result<Self, ConfigError> { | ||
| 189 | let mut this = Self::new_inner( | ||
| 190 | peri, | ||
| 191 | new_pin!(scl, config.scl_pf()), | ||
| 192 | new_pin!(sda, config.sda_pf()), | ||
| 193 | config, | ||
| 194 | target_config, | ||
| 195 | ); | ||
| 196 | this.reset()?; | ||
| 197 | Ok(this) | ||
| 198 | } | ||
| 199 | |||
| 200 | /// Reset the i2c peripheral. If you cancel a respond_to_read, you may stall the bus. | ||
| 201 | /// You can recover the bus by calling this function, but doing so will almost certainly cause | ||
| 202 | /// an i/o error in the controller. | ||
| 203 | pub fn reset(&mut self) -> Result<(), ConfigError> { | ||
| 204 | self.init()?; | ||
| 205 | Ok(()) | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | impl<'d, M: Mode> I2cTarget<'d, M> { | ||
| 210 | fn new_inner<T: Instance>( | ||
| 211 | _peri: Peri<'d, T>, | ||
| 212 | scl: Option<Peri<'d, AnyPin>>, | ||
| 213 | sda: Option<Peri<'d, AnyPin>>, | ||
| 214 | config: i2c::Config, | ||
| 215 | target_config: i2c_target::Config, | ||
| 216 | ) -> Self { | ||
| 217 | if let Some(ref scl) = scl { | ||
| 218 | let pincm = pac::IOMUX.pincm(scl._pin_cm() as usize); | ||
| 219 | pincm.modify(|w| { | ||
| 220 | w.set_hiz1(true); | ||
| 221 | }); | ||
| 222 | } | ||
| 223 | if let Some(ref sda) = sda { | ||
| 224 | let pincm = pac::IOMUX.pincm(sda._pin_cm() as usize); | ||
| 225 | pincm.modify(|w| { | ||
| 226 | w.set_hiz1(true); | ||
| 227 | }); | ||
| 228 | } | ||
| 229 | |||
| 230 | Self { | ||
| 231 | info: T::info(), | ||
| 232 | state: T::state(), | ||
| 233 | scl, | ||
| 234 | sda, | ||
| 235 | config, | ||
| 236 | target_config, | ||
| 237 | _phantom: PhantomData, | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | fn init(&mut self) -> Result<(), ConfigError> { | ||
| 242 | let mut config = self.config; | ||
| 243 | let target_config = self.target_config; | ||
| 244 | let regs = self.info.regs; | ||
| 245 | |||
| 246 | config.check_config()?; | ||
| 247 | // Target address must be 7-bit | ||
| 248 | if !(target_config.target_addr < 0x80) { | ||
| 249 | return Err(ConfigError::InvalidTargetAddress); | ||
| 250 | } | ||
| 251 | |||
| 252 | regs.target(0).tctr().modify(|w| { | ||
| 253 | w.set_active(false); | ||
| 254 | }); | ||
| 255 | |||
| 256 | // Init power for I2C | ||
| 257 | regs.gprcm(0).rstctl().write(|w| { | ||
| 258 | w.set_resetstkyclr(true); | ||
| 259 | w.set_resetassert(true); | ||
| 260 | w.set_key(vals::ResetKey::KEY); | ||
| 261 | }); | ||
| 262 | |||
| 263 | regs.gprcm(0).pwren().write(|w| { | ||
| 264 | w.set_enable(true); | ||
| 265 | w.set_key(vals::PwrenKey::KEY); | ||
| 266 | }); | ||
| 267 | |||
| 268 | self.info.interrupt.disable(); | ||
| 269 | |||
| 270 | // Init delay from the M0 examples by TI in CCStudio (16 cycles) | ||
| 271 | cortex_m::asm::delay(16); | ||
| 272 | |||
| 273 | // Select and configure the I2C clock using the CLKSEL and CLKDIV registers | ||
| 274 | regs.clksel().write(|w| match config.clock_source { | ||
| 275 | ClockSel::BusClk => { | ||
| 276 | w.set_mfclk_sel(false); | ||
| 277 | w.set_busclk_sel(true); | ||
| 278 | } | ||
| 279 | ClockSel::MfClk => { | ||
| 280 | w.set_mfclk_sel(true); | ||
| 281 | w.set_busclk_sel(false); | ||
| 282 | } | ||
| 283 | }); | ||
| 284 | regs.clkdiv().write(|w| w.set_ratio(config.clock_div.into())); | ||
| 285 | |||
| 286 | // Configure at least one target address by writing the 7-bit address to I2Cx.SOAR register. The additional | ||
| 287 | // target address can be enabled and configured by using I2Cx.TOAR2 register. | ||
| 288 | regs.target(0).toar().modify(|w| { | ||
| 289 | w.set_oaren(true); | ||
| 290 | w.set_oar(target_config.target_addr as u16); | ||
| 291 | }); | ||
| 292 | |||
| 293 | self.state | ||
| 294 | .clock | ||
| 295 | .store(config.calculate_clock_source(), Ordering::Relaxed); | ||
| 296 | |||
| 297 | regs.target(0).tctr().modify(|w| { | ||
| 298 | w.set_gencall(target_config.general_call); | ||
| 299 | w.set_tclkstretch(true); | ||
| 300 | // Disable target wakeup, follow TI example. (TI note: Workaround for errata I2C_ERR_04.) | ||
| 301 | w.set_twuen(false); | ||
| 302 | w.set_txempty_on_treq(true); | ||
| 303 | }); | ||
| 304 | |||
| 305 | // Enable the I2C target mode by setting the ACTIVE bit in I2Cx.TCTR register. | ||
| 306 | regs.target(0).tctr().modify(|w| { | ||
| 307 | w.set_active(true); | ||
| 308 | }); | ||
| 309 | |||
| 310 | Ok(()) | ||
| 311 | } | ||
| 312 | |||
| 313 | #[inline(always)] | ||
| 314 | fn drain_fifo(&mut self, buffer: &mut [u8], offset: &mut usize) { | ||
| 315 | let regs = self.info.regs; | ||
| 316 | |||
| 317 | for b in &mut buffer[*offset..] { | ||
| 318 | if regs.target(0).tfifosr().read().rxfifocnt() == 0 { | ||
| 319 | break; | ||
| 320 | } | ||
| 321 | |||
| 322 | *b = regs.target(0).trxdata().read().value(); | ||
| 323 | *offset += 1; | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | /// Blocking function to empty the tx fifo | ||
| 328 | /// | ||
| 329 | /// This function can be used to empty the transmit FIFO if data remains after handling a 'read' command (LeftoverBytes). | ||
| 330 | pub fn flush_tx_fifo(&mut self) { | ||
| 331 | self.info.regs.target(0).tfifoctl().modify(|w| { | ||
| 332 | w.set_txflush(true); | ||
| 333 | }); | ||
| 334 | while self.info.regs.target(0).tfifosr().read().txfifocnt() as usize != self.info.fifo_size {} | ||
| 335 | self.info.regs.target(0).tfifoctl().modify(|w| { | ||
| 336 | w.set_txflush(false); | ||
| 337 | }); | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 341 | impl<'d> I2cTarget<'d, Async> { | ||
| 342 | /// Wait asynchronously for commands from an I2C controller. | ||
| 343 | /// `buffer` is provided in case controller does a 'write', 'write read', or 'general call' and is unused for 'read'. | ||
| 344 | pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> { | ||
| 345 | let regs = self.info.regs; | ||
| 346 | |||
| 347 | let mut len = 0; | ||
| 348 | |||
| 349 | // Set the rx fifo interrupt to avoid a fifo overflow | ||
| 350 | regs.target(0).tfifoctl().modify(|r| { | ||
| 351 | r.set_rxtrig(vals::TfifoctlRxtrig::LEVEL_6); | ||
| 352 | }); | ||
| 353 | |||
| 354 | self.wait_on( | ||
| 355 | |me| { | ||
| 356 | // Check if address matches the General Call address (0x00) | ||
| 357 | let is_gencall = regs.target(0).tsr().read().addrmatch() == 0; | ||
| 358 | |||
| 359 | if regs.target(0).tfifosr().read().rxfifocnt() > 0 { | ||
| 360 | me.drain_fifo(buffer, &mut len); | ||
| 361 | } | ||
| 362 | |||
| 363 | if buffer.len() == len && regs.target(0).tfifosr().read().rxfifocnt() > 0 { | ||
| 364 | if is_gencall { | ||
| 365 | return Poll::Ready(Err(Error::PartialGeneralCall(buffer.len()))); | ||
| 366 | } else { | ||
| 367 | return Poll::Ready(Err(Error::PartialWrite(buffer.len()))); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | let iidx = regs.cpu_int(0).iidx().read().stat(); | ||
| 372 | trace!("ls:{} len:{}", iidx as u8, len); | ||
| 373 | let result = match iidx { | ||
| 374 | CpuIntIidxStat::TTXEMPTY => match len { | ||
| 375 | 0 => Poll::Ready(Ok(Command::Read)), | ||
| 376 | w => Poll::Ready(Ok(Command::WriteRead(w))), | ||
| 377 | }, | ||
| 378 | CpuIntIidxStat::TSTOPFG => match (is_gencall, len) { | ||
| 379 | (_, 0) => Poll::Pending, | ||
| 380 | (true, w) => Poll::Ready(Ok(Command::GeneralCall(w))), | ||
| 381 | (false, w) => Poll::Ready(Ok(Command::Write(w))), | ||
| 382 | }, | ||
| 383 | _ => Poll::Pending, | ||
| 384 | }; | ||
| 385 | if !result.is_pending() { | ||
| 386 | regs.cpu_int(0).imask().write(|_| {}); | ||
| 387 | } | ||
| 388 | result | ||
| 389 | }, | ||
| 390 | |_me| { | ||
| 391 | regs.cpu_int(0).imask().write(|_| {}); | ||
| 392 | regs.cpu_int(0).imask().modify(|w| { | ||
| 393 | w.set_tgencall(true); | ||
| 394 | w.set_trxfifotrg(true); | ||
| 395 | w.set_tstop(true); | ||
| 396 | w.set_ttxempty(true); | ||
| 397 | }); | ||
| 398 | }, | ||
| 399 | ) | ||
| 400 | .await | ||
| 401 | } | ||
| 402 | |||
| 403 | /// Respond to an I2C controller 'read' command, asynchronously. | ||
| 404 | pub async fn respond_to_read(&mut self, buffer: &[u8]) -> Result<ReadStatus, Error> { | ||
| 405 | if buffer.is_empty() { | ||
| 406 | return Err(Error::InvalidResponseBufferLength); | ||
| 407 | } | ||
| 408 | |||
| 409 | let regs = self.info.regs; | ||
| 410 | let fifo_size = self.info.fifo_size; | ||
| 411 | let mut chunks = buffer.chunks(self.info.fifo_size); | ||
| 412 | |||
| 413 | self.wait_on( | ||
| 414 | |_me| { | ||
| 415 | if let Some(chunk) = chunks.next() { | ||
| 416 | for byte in chunk { | ||
| 417 | regs.target(0).ttxdata().write(|w| w.set_value(*byte)); | ||
| 418 | } | ||
| 419 | |||
| 420 | return Poll::Pending; | ||
| 421 | } | ||
| 422 | |||
| 423 | let iidx = regs.cpu_int(0).iidx().read().stat(); | ||
| 424 | let fifo_bytes = fifo_size - regs.target(0).tfifosr().read().txfifocnt() as usize; | ||
| 425 | trace!("rs:{}, fifo:{}", iidx as u8, fifo_bytes); | ||
| 426 | |||
| 427 | let result = match iidx { | ||
| 428 | CpuIntIidxStat::TTXEMPTY => Poll::Ready(Ok(ReadStatus::NeedMoreBytes)), | ||
| 429 | CpuIntIidxStat::TSTOPFG => match fifo_bytes { | ||
| 430 | 0 => Poll::Ready(Ok(ReadStatus::Done)), | ||
| 431 | w => Poll::Ready(Ok(ReadStatus::LeftoverBytes(w as u16))), | ||
| 432 | }, | ||
| 433 | _ => Poll::Pending, | ||
| 434 | }; | ||
| 435 | if !result.is_pending() { | ||
| 436 | regs.cpu_int(0).imask().write(|_| {}); | ||
| 437 | } | ||
| 438 | result | ||
| 439 | }, | ||
| 440 | |_me| { | ||
| 441 | regs.cpu_int(0).imask().write(|_| {}); | ||
| 442 | regs.cpu_int(0).imask().modify(|w| { | ||
| 443 | w.set_ttxempty(true); | ||
| 444 | w.set_tstop(true); | ||
| 445 | }); | ||
| 446 | }, | ||
| 447 | ) | ||
| 448 | .await | ||
| 449 | } | ||
| 450 | |||
| 451 | /// Respond to reads with the fill byte until the controller stops asking | ||
| 452 | pub async fn respond_till_stop(&mut self, fill: u8) -> Result<(), Error> { | ||
| 453 | // The buffer size could be increased to reduce interrupt noise but has higher probability | ||
| 454 | // of LeftoverBytes | ||
| 455 | let buff = [fill]; | ||
| 456 | loop { | ||
| 457 | match self.respond_to_read(&buff).await { | ||
| 458 | Ok(ReadStatus::NeedMoreBytes) => (), | ||
| 459 | Ok(_) => break Ok(()), | ||
| 460 | Err(e) => break Err(e), | ||
| 461 | } | ||
| 462 | } | ||
| 463 | } | ||
| 464 | |||
| 465 | /// Respond to a controller read, then fill any remaining read bytes with `fill` | ||
| 466 | pub async fn respond_and_fill(&mut self, buffer: &[u8], fill: u8) -> Result<ReadStatus, Error> { | ||
| 467 | let resp_stat = self.respond_to_read(buffer).await?; | ||
| 468 | |||
| 469 | if resp_stat == ReadStatus::NeedMoreBytes { | ||
| 470 | self.respond_till_stop(fill).await?; | ||
| 471 | Ok(ReadStatus::Done) | ||
| 472 | } else { | ||
| 473 | Ok(resp_stat) | ||
| 474 | } | ||
| 475 | } | ||
| 476 | |||
| 477 | /// Calls `f` to check if we are ready or not. | ||
| 478 | /// If not, `g` is called once(to eg enable the required interrupts). | ||
| 479 | /// The waker will always be registered prior to calling `f`. | ||
| 480 | #[inline(always)] | ||
| 481 | async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U | ||
| 482 | where | ||
| 483 | F: FnMut(&mut Self) -> Poll<U>, | ||
| 484 | G: FnMut(&mut Self), | ||
| 485 | { | ||
| 486 | poll_fn(|cx| { | ||
| 487 | // Register prior to checking the condition | ||
| 488 | self.state.waker.register(cx.waker()); | ||
| 489 | let r = f(self); | ||
| 490 | |||
| 491 | if r.is_pending() { | ||
| 492 | g(self); | ||
| 493 | } | ||
| 494 | |||
| 495 | r | ||
| 496 | }) | ||
| 497 | .await | ||
| 498 | } | ||
| 499 | } | ||
| 500 | |||
| 501 | impl<'d, M: Mode> Drop for I2cTarget<'d, M> { | ||
| 502 | fn drop(&mut self) { | ||
| 503 | // Ensure peripheral is disabled and pins are reset | ||
| 504 | self.info.regs.target(0).tctr().modify(|w| w.set_active(false)); | ||
| 505 | |||
| 506 | self.scl.as_ref().map(|x| x.set_as_disconnected()); | ||
| 507 | self.sda.as_ref().map(|x| x.set_as_disconnected()); | ||
| 508 | } | ||
| 509 | } | ||
diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index 55f3f9381..9f3e4d5e8 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs | |||
| @@ -18,6 +18,7 @@ pub mod adc; | |||
| 18 | pub mod dma; | 18 | pub mod dma; |
| 19 | pub mod gpio; | 19 | pub mod gpio; |
| 20 | pub mod i2c; | 20 | pub mod i2c; |
| 21 | pub mod i2c_target; | ||
| 21 | pub mod timer; | 22 | pub mod timer; |
| 22 | pub mod uart; | 23 | pub mod uart; |
| 23 | pub mod wwdt; | 24 | pub mod wwdt; |
| @@ -233,3 +234,114 @@ impl Iterator for BitIter { | |||
| 233 | } | 234 | } |
| 234 | } | 235 | } |
| 235 | } | 236 | } |
| 237 | |||
| 238 | /// Reset cause values from SYSCTL.RSTCAUSE register. | ||
| 239 | /// Based on MSPM0 L-series Technical Reference Manual Table 2-9 and | ||
| 240 | /// MSPM0 G-series Technical Reference Manual Table 2-12. | ||
| 241 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 242 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 243 | pub enum ResetCause { | ||
| 244 | /// No reset since last read | ||
| 245 | NoReset, | ||
| 246 | /// VDD < POR- violation, PMU trim parity fault, or SHUTDNSTOREx parity fault | ||
| 247 | PorHwFailure, | ||
| 248 | /// NRST pin reset (>1s) | ||
| 249 | PorExternalNrst, | ||
| 250 | /// Software-triggered POR | ||
| 251 | PorSwTriggered, | ||
| 252 | /// VDD < BOR- violation | ||
| 253 | BorSupplyFailure, | ||
| 254 | /// Wake from SHUTDOWN | ||
| 255 | BorWakeFromShutdown, | ||
| 256 | /// Non-PMU trim parity fault | ||
| 257 | #[cfg(not(any( | ||
| 258 | mspm0c110x, | ||
| 259 | mspm0c1105_c1106, | ||
| 260 | mspm0g110x, | ||
| 261 | mspm0g150x, | ||
| 262 | mspm0g151x, | ||
| 263 | mspm0g310x, | ||
| 264 | mspm0g350x, | ||
| 265 | mspm0g351x | ||
| 266 | )))] | ||
| 267 | BootrstNonPmuParityFault, | ||
| 268 | /// Fatal clock fault | ||
| 269 | BootrstClockFault, | ||
| 270 | /// Software-triggered BOOTRST | ||
| 271 | BootrstSwTriggered, | ||
| 272 | /// NRST pin reset (<1s) | ||
| 273 | BootrstExternalNrst, | ||
| 274 | /// WWDT0 violation | ||
| 275 | BootrstWwdt0Violation, | ||
| 276 | /// WWDT1 violation (G-series only) | ||
| 277 | #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x))] | ||
| 278 | SysrstWwdt1Violation, | ||
| 279 | /// BSL exit (if present) | ||
| 280 | SysrstBslExit, | ||
| 281 | /// BSL entry (if present) | ||
| 282 | SysrstBslEntry, | ||
| 283 | /// Uncorrectable flash ECC error (if present) | ||
| 284 | #[cfg(not(any(mspm0c110x, mspm0c1105_c1106, mspm0g351x, mspm0g151x)))] | ||
| 285 | SysrstFlashEccError, | ||
| 286 | /// CPU lockup violation | ||
| 287 | SysrstCpuLockupViolation, | ||
| 288 | /// Debug-triggered SYSRST | ||
| 289 | SysrstDebugTriggered, | ||
| 290 | /// Software-triggered SYSRST | ||
| 291 | SysrstSwTriggered, | ||
| 292 | /// Debug-triggered CPURST | ||
| 293 | CpurstDebugTriggered, | ||
| 294 | /// Software-triggered CPURST | ||
| 295 | CpurstSwTriggered, | ||
| 296 | } | ||
| 297 | |||
| 298 | /// Read the reset cause from the SYSCTL.RSTCAUSE register. | ||
| 299 | /// | ||
| 300 | /// This function reads the reset cause register which indicates why the last | ||
| 301 | /// system reset occurred. The register is automatically cleared after being read, | ||
| 302 | /// so this should be called only once per application startup. | ||
| 303 | /// | ||
| 304 | /// If the reset cause is not recognized, an `Err` containing the raw value is returned. | ||
| 305 | #[must_use = "Reading reset cause will clear it"] | ||
| 306 | pub fn read_reset_cause() -> Result<ResetCause, u8> { | ||
| 307 | let cause_raw = pac::SYSCTL.rstcause().read().id(); | ||
| 308 | |||
| 309 | use ResetCause::*; | ||
| 310 | use pac::sysctl::vals::Id; | ||
| 311 | |||
| 312 | match cause_raw { | ||
| 313 | Id::NORST => Ok(NoReset), | ||
| 314 | Id::PORHWFAIL => Ok(PorHwFailure), | ||
| 315 | Id::POREXNRST => Ok(PorExternalNrst), | ||
| 316 | Id::PORSW => Ok(PorSwTriggered), | ||
| 317 | Id::BORSUPPLY => Ok(BorSupplyFailure), | ||
| 318 | Id::BORWAKESHUTDN => Ok(BorWakeFromShutdown), | ||
| 319 | #[cfg(not(any( | ||
| 320 | mspm0c110x, | ||
| 321 | mspm0c1105_c1106, | ||
| 322 | mspm0g110x, | ||
| 323 | mspm0g150x, | ||
| 324 | mspm0g151x, | ||
| 325 | mspm0g310x, | ||
| 326 | mspm0g350x, | ||
| 327 | mspm0g351x | ||
| 328 | )))] | ||
| 329 | Id::BOOTNONPMUPARITY => Ok(BootrstNonPmuParityFault), | ||
| 330 | Id::BOOTCLKFAIL => Ok(BootrstClockFault), | ||
| 331 | Id::BOOTSW => Ok(BootrstSwTriggered), | ||
| 332 | Id::BOOTEXNRST => Ok(BootrstExternalNrst), | ||
| 333 | Id::BOOTWWDT0 => Ok(BootrstWwdt0Violation), | ||
| 334 | Id::SYSBSLEXIT => Ok(SysrstBslExit), | ||
| 335 | Id::SYSBSLENTRY => Ok(SysrstBslEntry), | ||
| 336 | #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x))] | ||
| 337 | Id::SYSWWDT1 => Ok(SysrstWwdt1Violation), | ||
| 338 | #[cfg(not(any(mspm0c110x, mspm0c1105_c1106, mspm0g351x, mspm0g151x)))] | ||
| 339 | Id::SYSFLASHECC => Ok(SysrstFlashEccError), | ||
| 340 | Id::SYSCPULOCK => Ok(SysrstCpuLockupViolation), | ||
| 341 | Id::SYSDBG => Ok(SysrstDebugTriggered), | ||
| 342 | Id::SYSSW => Ok(SysrstSwTriggered), | ||
| 343 | Id::CPUDBG => Ok(CpurstDebugTriggered), | ||
| 344 | Id::CPUSW => Ok(CpurstSwTriggered), | ||
| 345 | other => Err(other as u8), | ||
| 346 | } | ||
| 347 | } | ||
diff --git a/embassy-net-esp-hosted/CHANGELOG.md b/embassy-net-esp-hosted/CHANGELOG.md index 5153e3799..d8b912295 100644 --- a/embassy-net-esp-hosted/CHANGELOG.md +++ b/embassy-net-esp-hosted/CHANGELOG.md | |||
| @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - Add an `Interface` trait to allow using other interface transports. | ||
| 12 | - Switch to `micropb` for protobuf. | ||
| 13 | - Update protos to latest `esp-hosted-fg`. | ||
| 14 | |||
| 11 | ## 0.2.1 - 2025-08-26 | 15 | ## 0.2.1 - 2025-08-26 |
| 12 | 16 | ||
| 13 | - First release with changelog. | 17 | - First release with changelog. |
diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml index f148f4762..81096b024 100644 --- a/embassy-net-esp-hosted/Cargo.toml +++ b/embassy-net-esp-hosted/Cargo.toml | |||
| @@ -25,7 +25,7 @@ embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver- | |||
| 25 | embedded-hal = { version = "1.0" } | 25 | embedded-hal = { version = "1.0" } |
| 26 | embedded-hal-async = { version = "1.0" } | 26 | embedded-hal-async = { version = "1.0" } |
| 27 | 27 | ||
| 28 | noproto = "0.1.0" | 28 | micropb = { version = "0.4.0", default-features = false, features = ["container-heapless", "encode", "decode"] } |
| 29 | heapless = "0.8" | 29 | heapless = "0.8" |
| 30 | 30 | ||
| 31 | [package.metadata.embassy_docs] | 31 | [package.metadata.embassy_docs] |
diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs index cbc194877..38ec648b4 100644 --- a/embassy-net-esp-hosted/src/control.rs +++ b/embassy-net-esp-hosted/src/control.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use embassy_net_driver_channel as ch; | 1 | use embassy_net_driver_channel as ch; |
| 2 | use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; | 2 | use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; |
| 3 | use heapless::String; | 3 | use heapless::String; |
| 4 | use micropb::{MessageDecode, MessageEncode, PbEncoder}; | ||
| 4 | 5 | ||
| 5 | use crate::ioctl::Shared; | 6 | use crate::ioctl::Shared; |
| 6 | use crate::proto::{self, CtrlMsg}; | 7 | use crate::proto::{self, CtrlMsg}; |
| @@ -38,7 +39,7 @@ enum WifiMode { | |||
| 38 | ApSta = 3, | 39 | ApSta = 3, |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | pub use proto::CtrlWifiSecProt as Security; | 42 | pub use proto::Ctrl_WifiSecProt as Security; |
| 42 | 43 | ||
| 43 | /// WiFi status. | 44 | /// WiFi status. |
| 44 | #[derive(Clone, Debug)] | 45 | #[derive(Clone, Debug)] |
| @@ -59,18 +60,20 @@ pub struct Status { | |||
| 59 | macro_rules! ioctl { | 60 | macro_rules! ioctl { |
| 60 | ($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => { | 61 | ($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => { |
| 61 | let mut msg = proto::CtrlMsg { | 62 | let mut msg = proto::CtrlMsg { |
| 62 | msg_id: proto::CtrlMsgId::$req_variant as _, | 63 | msg_id: proto::CtrlMsgId::$req_variant, |
| 63 | msg_type: proto::CtrlMsgType::Req as _, | 64 | msg_type: proto::CtrlMsgType::Req, |
| 64 | payload: Some(proto::CtrlMsgPayload::$req_variant($req)), | 65 | payload: Some(proto::CtrlMsg_::Payload::$req_variant($req)), |
| 66 | req_resp_type: 0, | ||
| 67 | uid: 0, | ||
| 65 | }; | 68 | }; |
| 66 | $self.ioctl(&mut msg).await?; | 69 | $self.ioctl(&mut msg).await?; |
| 67 | #[allow(unused_mut)] | 70 | #[allow(unused_mut)] |
| 68 | let Some(proto::CtrlMsgPayload::$resp_variant(mut $resp)) = msg.payload else { | 71 | let Some(proto::CtrlMsg_::Payload::$resp_variant(mut $resp)) = msg.payload else { |
| 69 | warn!("unexpected response variant"); | 72 | warn!("unexpected response variant"); |
| 70 | return Err(Error::Internal); | 73 | return Err(Error::Internal); |
| 71 | }; | 74 | }; |
| 72 | if $resp.resp != 0 { | 75 | if $resp.resp != 0 { |
| 73 | return Err(Error::Failed($resp.resp)); | 76 | return Err(Error::Failed($resp.resp as u32)); |
| 74 | } | 77 | } |
| 75 | }; | 78 | }; |
| 76 | } | 79 | } |
| @@ -100,35 +103,44 @@ impl<'a> Control<'a> { | |||
| 100 | 103 | ||
| 101 | /// Get the current status. | 104 | /// Get the current status. |
| 102 | pub async fn get_status(&mut self) -> Result<Status, Error> { | 105 | pub async fn get_status(&mut self) -> Result<Status, Error> { |
| 103 | let req = proto::CtrlMsgReqGetApConfig {}; | 106 | let req = proto::CtrlMsg_Req_GetAPConfig {}; |
| 104 | ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); | 107 | ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); |
| 105 | trim_nulls(&mut resp.ssid); | 108 | let ssid = core::str::from_utf8(&resp.ssid).map_err(|_| Error::Internal)?; |
| 109 | let ssid = String::try_from(ssid.trim_end_matches('\0')).map_err(|_| Error::Internal)?; | ||
| 110 | let bssid_str = core::str::from_utf8(&resp.bssid).map_err(|_| Error::Internal)?; | ||
| 106 | Ok(Status { | 111 | Ok(Status { |
| 107 | ssid: resp.ssid, | 112 | ssid, |
| 108 | bssid: parse_mac(&resp.bssid)?, | 113 | bssid: parse_mac(bssid_str)?, |
| 109 | rssi: resp.rssi as _, | 114 | rssi: resp.rssi as _, |
| 110 | channel: resp.chnl, | 115 | channel: resp.chnl as u32, |
| 111 | security: resp.sec_prot, | 116 | security: resp.sec_prot, |
| 112 | }) | 117 | }) |
| 113 | } | 118 | } |
| 114 | 119 | ||
| 115 | /// Connect to the network identified by ssid using the provided password. | 120 | /// Connect to the network identified by ssid using the provided password. |
| 116 | pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { | 121 | pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { |
| 117 | let req = proto::CtrlMsgReqConnectAp { | 122 | const WIFI_BAND_MODE_AUTO: i32 = 3; // 2.4GHz + 5GHz |
| 123 | |||
| 124 | let req = proto::CtrlMsg_Req_ConnectAP { | ||
| 118 | ssid: unwrap!(String::try_from(ssid)), | 125 | ssid: unwrap!(String::try_from(ssid)), |
| 119 | pwd: unwrap!(String::try_from(password)), | 126 | pwd: unwrap!(String::try_from(password)), |
| 120 | bssid: String::new(), | 127 | bssid: String::new(), |
| 121 | listen_interval: 3, | 128 | listen_interval: 3, |
| 122 | is_wpa3_supported: true, | 129 | is_wpa3_supported: true, |
| 130 | band_mode: WIFI_BAND_MODE_AUTO, | ||
| 123 | }; | 131 | }; |
| 124 | ioctl!(self, ReqConnectAp, RespConnectAp, req, resp); | 132 | ioctl!(self, ReqConnectAp, RespConnectAp, req, resp); |
| 133 | |||
| 134 | // TODO: in newer esp-hosted firmwares that added EventStationConnectedToAp | ||
| 135 | // the connect ioctl seems to be async, so we shouldn't immediately set LinkState::Up here. | ||
| 125 | self.state_ch.set_link_state(LinkState::Up); | 136 | self.state_ch.set_link_state(LinkState::Up); |
| 137 | |||
| 126 | Ok(()) | 138 | Ok(()) |
| 127 | } | 139 | } |
| 128 | 140 | ||
| 129 | /// Disconnect from any currently connected network. | 141 | /// Disconnect from any currently connected network. |
| 130 | pub async fn disconnect(&mut self) -> Result<(), Error> { | 142 | pub async fn disconnect(&mut self) -> Result<(), Error> { |
| 131 | let req = proto::CtrlMsgReqGetStatus {}; | 143 | let req = proto::CtrlMsg_Req_GetStatus {}; |
| 132 | ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); | 144 | ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); |
| 133 | self.state_ch.set_link_state(LinkState::Down); | 145 | self.state_ch.set_link_state(LinkState::Down); |
| 134 | Ok(()) | 146 | Ok(()) |
| @@ -136,21 +148,25 @@ impl<'a> Control<'a> { | |||
| 136 | 148 | ||
| 137 | /// duration in seconds, clamped to [10, 3600] | 149 | /// duration in seconds, clamped to [10, 3600] |
| 138 | async fn set_heartbeat(&mut self, duration: u32) -> Result<(), Error> { | 150 | async fn set_heartbeat(&mut self, duration: u32) -> Result<(), Error> { |
| 139 | let req = proto::CtrlMsgReqConfigHeartbeat { enable: true, duration }; | 151 | let req = proto::CtrlMsg_Req_ConfigHeartbeat { |
| 152 | enable: true, | ||
| 153 | duration: duration as i32, | ||
| 154 | }; | ||
| 140 | ioctl!(self, ReqConfigHeartbeat, RespConfigHeartbeat, req, resp); | 155 | ioctl!(self, ReqConfigHeartbeat, RespConfigHeartbeat, req, resp); |
| 141 | Ok(()) | 156 | Ok(()) |
| 142 | } | 157 | } |
| 143 | 158 | ||
| 144 | async fn get_mac_addr(&mut self) -> Result<[u8; 6], Error> { | 159 | async fn get_mac_addr(&mut self) -> Result<[u8; 6], Error> { |
| 145 | let req = proto::CtrlMsgReqGetMacAddress { | 160 | let req = proto::CtrlMsg_Req_GetMacAddress { |
| 146 | mode: WifiMode::Sta as _, | 161 | mode: WifiMode::Sta as _, |
| 147 | }; | 162 | }; |
| 148 | ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp); | 163 | ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp); |
| 149 | parse_mac(&resp.mac) | 164 | let mac_str = core::str::from_utf8(&resp.mac).map_err(|_| Error::Internal)?; |
| 165 | parse_mac(mac_str) | ||
| 150 | } | 166 | } |
| 151 | 167 | ||
| 152 | async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> { | 168 | async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> { |
| 153 | let req = proto::CtrlMsgReqSetMode { mode }; | 169 | let req = proto::CtrlMsg_Req_SetMode { mode: mode as i32 }; |
| 154 | ioctl!(self, ReqSetWifiMode, RespSetWifiMode, req, resp); | 170 | ioctl!(self, ReqSetWifiMode, RespSetWifiMode, req, resp); |
| 155 | 171 | ||
| 156 | Ok(()) | 172 | Ok(()) |
| @@ -160,11 +176,15 @@ impl<'a> Control<'a> { | |||
| 160 | debug!("ioctl req: {:?}", &msg); | 176 | debug!("ioctl req: {:?}", &msg); |
| 161 | 177 | ||
| 162 | let mut buf = [0u8; 128]; | 178 | let mut buf = [0u8; 128]; |
| 179 | let buf_len = buf.len(); | ||
| 163 | 180 | ||
| 164 | let req_len = noproto::write(msg, &mut buf).map_err(|_| { | 181 | let mut encoder = PbEncoder::new(&mut buf[..]); |
| 182 | msg.encode(&mut encoder).map_err(|_| { | ||
| 165 | warn!("failed to serialize control request"); | 183 | warn!("failed to serialize control request"); |
| 166 | Error::Internal | 184 | Error::Internal |
| 167 | })?; | 185 | })?; |
| 186 | let remaining = encoder.into_writer(); | ||
| 187 | let req_len = buf_len - remaining.len(); | ||
| 168 | 188 | ||
| 169 | struct CancelOnDrop<'a>(&'a Shared); | 189 | struct CancelOnDrop<'a>(&'a Shared); |
| 170 | 190 | ||
| @@ -186,8 +206,8 @@ impl<'a> Control<'a> { | |||
| 186 | 206 | ||
| 187 | ioctl.defuse(); | 207 | ioctl.defuse(); |
| 188 | 208 | ||
| 189 | *msg = noproto::read(&buf[..resp_len]).map_err(|_| { | 209 | msg.decode_from_bytes(&buf[..resp_len]).map_err(|_| { |
| 190 | warn!("failed to serialize control request"); | 210 | warn!("failed to deserialize control response"); |
| 191 | Error::Internal | 211 | Error::Internal |
| 192 | })?; | 212 | })?; |
| 193 | debug!("ioctl resp: {:?}", msg); | 213 | debug!("ioctl resp: {:?}", msg); |
| @@ -221,9 +241,3 @@ fn parse_mac(mac: &str) -> Result<[u8; 6], Error> { | |||
| 221 | } | 241 | } |
| 222 | Ok(res) | 242 | Ok(res) |
| 223 | } | 243 | } |
| 224 | |||
| 225 | fn trim_nulls<const N: usize>(s: &mut String<N>) { | ||
| 226 | while s.chars().rev().next() == Some(0 as char) { | ||
| 227 | s.pop(); | ||
| 228 | } | ||
| 229 | } | ||
diff --git a/embassy-net-esp-hosted/src/esp_hosted_config.proto b/embassy-net-esp-hosted/src/esp_hosted_config.proto index aa1bfde64..7d626207e 100644 --- a/embassy-net-esp-hosted/src/esp_hosted_config.proto +++ b/embassy-net-esp-hosted/src/esp_hosted_config.proto | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | /* Copyright (C) 2015-2025 Espressif Systems (Shanghai) PTE LTD */ | ||
| 2 | /* SPDX-License-Identifier: GPL-2.0-only OR Apache-2.0 */ | ||
| 3 | |||
| 1 | syntax = "proto3"; | 4 | syntax = "proto3"; |
| 2 | 5 | ||
| 3 | /* Enums similar to ESP IDF */ | 6 | /* Enums similar to ESP IDF */ |
| @@ -28,9 +31,10 @@ enum Ctrl_WifiBw { | |||
| 28 | } | 31 | } |
| 29 | 32 | ||
| 30 | enum Ctrl_WifiPowerSave { | 33 | enum Ctrl_WifiPowerSave { |
| 31 | PS_Invalid = 0; | 34 | NO_PS = 0; |
| 32 | MIN_MODEM = 1; | 35 | MIN_MODEM = 1; |
| 33 | MAX_MODEM = 2; | 36 | MAX_MODEM = 2; |
| 37 | PS_Invalid = 3; | ||
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | enum Ctrl_WifiSecProt { | 40 | enum Ctrl_WifiSecProt { |
| @@ -96,9 +100,16 @@ enum CtrlMsgId { | |||
| 96 | Req_GetWifiCurrTxPower = 120; | 100 | Req_GetWifiCurrTxPower = 120; |
| 97 | 101 | ||
| 98 | Req_ConfigHeartbeat = 121; | 102 | Req_ConfigHeartbeat = 121; |
| 103 | Req_EnableDisable = 122; | ||
| 104 | Req_GetFwVersion = 123; | ||
| 105 | Req_SetCountryCode = 124; | ||
| 106 | Req_GetCountryCode = 125; | ||
| 107 | Req_SetDhcpDnsStatus = 126; | ||
| 108 | Req_GetDhcpDnsStatus = 127; | ||
| 109 | Req_Custom_RPC_Unserialised_Msg = 128; | ||
| 99 | /* Add new control path command response before Req_Max | 110 | /* Add new control path command response before Req_Max |
| 100 | * and update Req_Max */ | 111 | * and update Req_Max */ |
| 101 | Req_Max = 122; | 112 | Req_Max = 129; |
| 102 | 113 | ||
| 103 | /** Response Msgs **/ | 114 | /** Response Msgs **/ |
| 104 | Resp_Base = 200; | 115 | Resp_Base = 200; |
| @@ -130,9 +141,16 @@ enum CtrlMsgId { | |||
| 130 | Resp_GetWifiCurrTxPower = 220; | 141 | Resp_GetWifiCurrTxPower = 220; |
| 131 | 142 | ||
| 132 | Resp_ConfigHeartbeat = 221; | 143 | Resp_ConfigHeartbeat = 221; |
| 144 | Resp_EnableDisable = 222; | ||
| 145 | Resp_GetFwVersion = 223; | ||
| 146 | Resp_SetCountryCode = 224; | ||
| 147 | Resp_GetCountryCode = 225; | ||
| 148 | Resp_SetDhcpDnsStatus = 226; | ||
| 149 | Resp_GetDhcpDnsStatus = 227; | ||
| 150 | Resp_Custom_RPC_Unserialised_Msg = 228; | ||
| 133 | /* Add new control path command response before Resp_Max | 151 | /* Add new control path command response before Resp_Max |
| 134 | * and update Resp_Max */ | 152 | * and update Resp_Max */ |
| 135 | Resp_Max = 222; | 153 | Resp_Max = 229; |
| 136 | 154 | ||
| 137 | /** Event Msgs **/ | 155 | /** Event Msgs **/ |
| 138 | Event_Base = 300; | 156 | Event_Base = 300; |
| @@ -140,9 +158,22 @@ enum CtrlMsgId { | |||
| 140 | Event_Heartbeat = 302; | 158 | Event_Heartbeat = 302; |
| 141 | Event_StationDisconnectFromAP = 303; | 159 | Event_StationDisconnectFromAP = 303; |
| 142 | Event_StationDisconnectFromESPSoftAP = 304; | 160 | Event_StationDisconnectFromESPSoftAP = 304; |
| 161 | Event_StationConnectedToAP = 305; | ||
| 162 | Event_StationConnectedToESPSoftAP = 306; | ||
| 163 | Event_SetDhcpDnsStatus = 307; | ||
| 164 | Event_Custom_RPC_Unserialised_Msg = 308; | ||
| 143 | /* Add new control path command notification before Event_Max | 165 | /* Add new control path command notification before Event_Max |
| 144 | * and update Event_Max */ | 166 | * and update Event_Max */ |
| 145 | Event_Max = 305; | 167 | Event_Max = 309; |
| 168 | } | ||
| 169 | |||
| 170 | enum HostedFeature { | ||
| 171 | Hosted_InvalidFeature = 0; | ||
| 172 | Hosted_Wifi = 1; | ||
| 173 | Hosted_Bluetooth = 2; | ||
| 174 | Hosted_Is_Network_Split_On = 3; | ||
| 175 | |||
| 176 | /* Add your new features here and re-build prot using build_proto.sh */ | ||
| 146 | } | 177 | } |
| 147 | 178 | ||
| 148 | /* internal supporting structures for CtrlMsg */ | 179 | /* internal supporting structures for CtrlMsg */ |
| @@ -213,6 +244,7 @@ message CtrlMsg_Resp_GetAPConfig { | |||
| 213 | int32 chnl = 4; | 244 | int32 chnl = 4; |
| 214 | Ctrl_WifiSecProt sec_prot = 5; | 245 | Ctrl_WifiSecProt sec_prot = 5; |
| 215 | int32 resp = 6; | 246 | int32 resp = 6; |
| 247 | int32 band_mode = 7; | ||
| 216 | } | 248 | } |
| 217 | 249 | ||
| 218 | message CtrlMsg_Req_ConnectAP { | 250 | message CtrlMsg_Req_ConnectAP { |
| @@ -221,11 +253,13 @@ message CtrlMsg_Req_ConnectAP { | |||
| 221 | string bssid = 3; | 253 | string bssid = 3; |
| 222 | bool is_wpa3_supported = 4; | 254 | bool is_wpa3_supported = 4; |
| 223 | int32 listen_interval = 5; | 255 | int32 listen_interval = 5; |
| 256 | int32 band_mode = 6; | ||
| 224 | } | 257 | } |
| 225 | 258 | ||
| 226 | message CtrlMsg_Resp_ConnectAP { | 259 | message CtrlMsg_Resp_ConnectAP { |
| 227 | int32 resp = 1; | 260 | int32 resp = 1; |
| 228 | bytes mac = 2; | 261 | bytes mac = 2; |
| 262 | int32 band_mode = 3; | ||
| 229 | } | 263 | } |
| 230 | 264 | ||
| 231 | message CtrlMsg_Req_GetSoftAPConfig { | 265 | message CtrlMsg_Req_GetSoftAPConfig { |
| @@ -240,6 +274,7 @@ message CtrlMsg_Resp_GetSoftAPConfig { | |||
| 240 | bool ssid_hidden = 6; | 274 | bool ssid_hidden = 6; |
| 241 | int32 bw = 7; | 275 | int32 bw = 7; |
| 242 | int32 resp = 8; | 276 | int32 resp = 8; |
| 277 | int32 band_mode = 9; | ||
| 243 | } | 278 | } |
| 244 | 279 | ||
| 245 | message CtrlMsg_Req_StartSoftAP { | 280 | message CtrlMsg_Req_StartSoftAP { |
| @@ -250,11 +285,13 @@ message CtrlMsg_Req_StartSoftAP { | |||
| 250 | int32 max_conn = 5; | 285 | int32 max_conn = 5; |
| 251 | bool ssid_hidden = 6; | 286 | bool ssid_hidden = 6; |
| 252 | int32 bw = 7; | 287 | int32 bw = 7; |
| 288 | int32 band_mode = 8; | ||
| 253 | } | 289 | } |
| 254 | 290 | ||
| 255 | message CtrlMsg_Resp_StartSoftAP { | 291 | message CtrlMsg_Resp_StartSoftAP { |
| 256 | int32 resp = 1; | 292 | int32 resp = 1; |
| 257 | bytes mac = 2; | 293 | bytes mac = 2; |
| 294 | int32 band_mode = 3; | ||
| 258 | } | 295 | } |
| 259 | 296 | ||
| 260 | message CtrlMsg_Req_ScanResult { | 297 | message CtrlMsg_Req_ScanResult { |
| @@ -302,7 +339,7 @@ message CtrlMsg_Req_VendorIEData { | |||
| 302 | int32 length = 2; | 339 | int32 length = 2; |
| 303 | bytes vendor_oui = 3; | 340 | bytes vendor_oui = 3; |
| 304 | int32 vendor_oui_type = 4; | 341 | int32 vendor_oui_type = 4; |
| 305 | bytes payload = 5; | 342 | bytes payload = 5; |
| 306 | } | 343 | } |
| 307 | 344 | ||
| 308 | message CtrlMsg_Req_SetSoftAPVendorSpecificIE { | 345 | message CtrlMsg_Req_SetSoftAPVendorSpecificIE { |
| @@ -341,6 +378,81 @@ message CtrlMsg_Resp_ConfigHeartbeat { | |||
| 341 | int32 resp = 1; | 378 | int32 resp = 1; |
| 342 | } | 379 | } |
| 343 | 380 | ||
| 381 | message CtrlMsg_Req_EnableDisable { | ||
| 382 | uint32 feature = 1; | ||
| 383 | bool enable = 2; | ||
| 384 | } | ||
| 385 | |||
| 386 | message CtrlMsg_Resp_EnableDisable { | ||
| 387 | int32 resp = 1; | ||
| 388 | } | ||
| 389 | |||
| 390 | message CtrlMsg_Req_GetFwVersion { | ||
| 391 | } | ||
| 392 | |||
| 393 | message CtrlMsg_Resp_GetFwVersion { | ||
| 394 | int32 resp = 1; | ||
| 395 | string name = 2; | ||
| 396 | uint32 major1 = 3; | ||
| 397 | uint32 major2 = 4; | ||
| 398 | uint32 minor = 5; | ||
| 399 | uint32 rev_patch1 = 6; | ||
| 400 | uint32 rev_patch2 = 7; | ||
| 401 | } | ||
| 402 | |||
| 403 | message CtrlMsg_Req_SetCountryCode { | ||
| 404 | bytes country = 1; | ||
| 405 | bool ieee80211d_enabled = 2; | ||
| 406 | } | ||
| 407 | |||
| 408 | message CtrlMsg_Resp_SetCountryCode { | ||
| 409 | int32 resp = 1; | ||
| 410 | } | ||
| 411 | |||
| 412 | message CtrlMsg_Req_GetCountryCode { | ||
| 413 | } | ||
| 414 | |||
| 415 | message CtrlMsg_Resp_GetCountryCode { | ||
| 416 | int32 resp = 1; | ||
| 417 | bytes country = 2; | ||
| 418 | } | ||
| 419 | |||
| 420 | message CtrlMsg_Req_SetDhcpDnsStatus { | ||
| 421 | int32 iface = 1; | ||
| 422 | int32 net_link_up = 2; | ||
| 423 | |||
| 424 | int32 dhcp_up = 3; | ||
| 425 | bytes dhcp_ip = 4; | ||
| 426 | bytes dhcp_nm = 5; | ||
| 427 | bytes dhcp_gw = 6; | ||
| 428 | |||
| 429 | int32 dns_up = 7; | ||
| 430 | bytes dns_ip = 8; | ||
| 431 | int32 dns_type = 9; | ||
| 432 | } | ||
| 433 | |||
| 434 | message CtrlMsg_Resp_SetDhcpDnsStatus { | ||
| 435 | int32 resp = 1; | ||
| 436 | } | ||
| 437 | |||
| 438 | message CtrlMsg_Req_GetDhcpDnsStatus { | ||
| 439 | } | ||
| 440 | |||
| 441 | message CtrlMsg_Resp_GetDhcpDnsStatus { | ||
| 442 | int32 resp = 1; | ||
| 443 | int32 iface = 2; | ||
| 444 | int32 net_link_up = 3; | ||
| 445 | |||
| 446 | int32 dhcp_up = 4; | ||
| 447 | bytes dhcp_ip = 5; | ||
| 448 | bytes dhcp_nm = 6; | ||
| 449 | bytes dhcp_gw = 7; | ||
| 450 | |||
| 451 | int32 dns_up = 8; | ||
| 452 | bytes dns_ip = 9; | ||
| 453 | int32 dns_type = 10; | ||
| 454 | } | ||
| 455 | |||
| 344 | /** Event structure **/ | 456 | /** Event structure **/ |
| 345 | message CtrlMsg_Event_ESPInit { | 457 | message CtrlMsg_Event_ESPInit { |
| 346 | bytes init_data = 1; | 458 | bytes init_data = 1; |
| @@ -352,11 +464,70 @@ message CtrlMsg_Event_Heartbeat { | |||
| 352 | 464 | ||
| 353 | message CtrlMsg_Event_StationDisconnectFromAP { | 465 | message CtrlMsg_Event_StationDisconnectFromAP { |
| 354 | int32 resp = 1; | 466 | int32 resp = 1; |
| 467 | bytes ssid = 2; | ||
| 468 | uint32 ssid_len = 3; | ||
| 469 | bytes bssid = 4; | ||
| 470 | uint32 reason = 5; | ||
| 471 | int32 rssi = 6; | ||
| 355 | } | 472 | } |
| 356 | 473 | ||
| 474 | message CtrlMsg_Event_StationConnectedToAP { | ||
| 475 | int32 resp = 1; | ||
| 476 | bytes ssid = 2; | ||
| 477 | uint32 ssid_len = 3; | ||
| 478 | bytes bssid = 4; | ||
| 479 | uint32 channel = 5; | ||
| 480 | int32 authmode = 6; | ||
| 481 | int32 aid = 7; | ||
| 482 | } | ||
| 483 | |||
| 484 | |||
| 357 | message CtrlMsg_Event_StationDisconnectFromESPSoftAP { | 485 | message CtrlMsg_Event_StationDisconnectFromESPSoftAP { |
| 358 | int32 resp = 1; | 486 | int32 resp = 1; |
| 359 | bytes mac = 2; | 487 | bytes mac = 2; |
| 488 | uint32 aid = 3; | ||
| 489 | bool is_mesh_child = 4; | ||
| 490 | uint32 reason = 5; | ||
| 491 | } | ||
| 492 | |||
| 493 | message CtrlMsg_Event_StationConnectedToESPSoftAP { | ||
| 494 | int32 resp = 1; | ||
| 495 | bytes mac = 2; | ||
| 496 | uint32 aid = 3; | ||
| 497 | bool is_mesh_child = 4; | ||
| 498 | } | ||
| 499 | |||
| 500 | message CtrlMsg_Event_SetDhcpDnsStatus { | ||
| 501 | int32 iface = 1; | ||
| 502 | int32 net_link_up = 2; | ||
| 503 | |||
| 504 | int32 dhcp_up = 3; | ||
| 505 | bytes dhcp_ip = 4; | ||
| 506 | bytes dhcp_nm = 5; | ||
| 507 | bytes dhcp_gw = 6; | ||
| 508 | |||
| 509 | int32 dns_up = 7; | ||
| 510 | bytes dns_ip = 8; | ||
| 511 | int32 dns_type = 9; | ||
| 512 | int32 resp = 10; | ||
| 513 | } | ||
| 514 | |||
| 515 | /* Add Custom RPC message structures after existing message structures to make it easily notice */ | ||
| 516 | message CtrlMsg_Req_CustomRpcUnserialisedMsg { | ||
| 517 | uint32 custom_msg_id = 1; | ||
| 518 | bytes data = 2; | ||
| 519 | } | ||
| 520 | |||
| 521 | message CtrlMsg_Resp_CustomRpcUnserialisedMsg { | ||
| 522 | int32 resp = 1; | ||
| 523 | uint32 custom_msg_id = 2; | ||
| 524 | bytes data = 3; | ||
| 525 | } | ||
| 526 | |||
| 527 | message CtrlMsg_Event_CustomRpcUnserialisedMsg { | ||
| 528 | int32 resp = 1; | ||
| 529 | uint32 custom_evt_id = 2; | ||
| 530 | bytes data = 3; | ||
| 360 | } | 531 | } |
| 361 | 532 | ||
| 362 | message CtrlMsg { | 533 | message CtrlMsg { |
| @@ -366,6 +537,12 @@ message CtrlMsg { | |||
| 366 | /* msg id */ | 537 | /* msg id */ |
| 367 | CtrlMsgId msg_id = 2; | 538 | CtrlMsgId msg_id = 2; |
| 368 | 539 | ||
| 540 | /* UID of message */ | ||
| 541 | int32 uid = 3; | ||
| 542 | |||
| 543 | /* Request/response type: sync or async */ | ||
| 544 | uint32 req_resp_type = 4; | ||
| 545 | |||
| 369 | /* union of all msg ids */ | 546 | /* union of all msg ids */ |
| 370 | oneof payload { | 547 | oneof payload { |
| 371 | /** Requests **/ | 548 | /** Requests **/ |
| @@ -395,6 +572,13 @@ message CtrlMsg { | |||
| 395 | CtrlMsg_Req_SetWifiMaxTxPower req_set_wifi_max_tx_power = 119; | 572 | CtrlMsg_Req_SetWifiMaxTxPower req_set_wifi_max_tx_power = 119; |
| 396 | CtrlMsg_Req_GetWifiCurrTxPower req_get_wifi_curr_tx_power = 120; | 573 | CtrlMsg_Req_GetWifiCurrTxPower req_get_wifi_curr_tx_power = 120; |
| 397 | CtrlMsg_Req_ConfigHeartbeat req_config_heartbeat = 121; | 574 | CtrlMsg_Req_ConfigHeartbeat req_config_heartbeat = 121; |
| 575 | CtrlMsg_Req_EnableDisable req_enable_disable_feat = 122; | ||
| 576 | CtrlMsg_Req_GetFwVersion req_get_fw_version = 123; | ||
| 577 | CtrlMsg_Req_SetCountryCode req_set_country_code = 124; | ||
| 578 | CtrlMsg_Req_GetCountryCode req_get_country_code = 125; | ||
| 579 | CtrlMsg_Req_SetDhcpDnsStatus req_set_dhcp_dns_status = 126; | ||
| 580 | CtrlMsg_Req_GetDhcpDnsStatus req_get_dhcp_dns_status = 127; | ||
| 581 | CtrlMsg_Req_CustomRpcUnserialisedMsg req_custom_rpc_unserialised_msg = 128; | ||
| 398 | 582 | ||
| 399 | /** Responses **/ | 583 | /** Responses **/ |
| 400 | CtrlMsg_Resp_GetMacAddress resp_get_mac_address = 201; | 584 | CtrlMsg_Resp_GetMacAddress resp_get_mac_address = 201; |
| @@ -422,11 +606,22 @@ message CtrlMsg { | |||
| 422 | CtrlMsg_Resp_SetWifiMaxTxPower resp_set_wifi_max_tx_power = 219; | 606 | CtrlMsg_Resp_SetWifiMaxTxPower resp_set_wifi_max_tx_power = 219; |
| 423 | CtrlMsg_Resp_GetWifiCurrTxPower resp_get_wifi_curr_tx_power = 220; | 607 | CtrlMsg_Resp_GetWifiCurrTxPower resp_get_wifi_curr_tx_power = 220; |
| 424 | CtrlMsg_Resp_ConfigHeartbeat resp_config_heartbeat = 221; | 608 | CtrlMsg_Resp_ConfigHeartbeat resp_config_heartbeat = 221; |
| 609 | CtrlMsg_Resp_EnableDisable resp_enable_disable_feat = 222; | ||
| 610 | CtrlMsg_Resp_GetFwVersion resp_get_fw_version = 223; | ||
| 611 | CtrlMsg_Resp_SetCountryCode resp_set_country_code = 224; | ||
| 612 | CtrlMsg_Resp_GetCountryCode resp_get_country_code = 225; | ||
| 613 | CtrlMsg_Resp_SetDhcpDnsStatus resp_set_dhcp_dns_status = 226; | ||
| 614 | CtrlMsg_Resp_GetDhcpDnsStatus resp_get_dhcp_dns_status = 227; | ||
| 615 | CtrlMsg_Resp_CustomRpcUnserialisedMsg resp_custom_rpc_unserialised_msg = 228; | ||
| 425 | 616 | ||
| 426 | /** Notifications **/ | 617 | /** Notifications **/ |
| 427 | CtrlMsg_Event_ESPInit event_esp_init = 301; | 618 | CtrlMsg_Event_ESPInit event_esp_init = 301; |
| 428 | CtrlMsg_Event_Heartbeat event_heartbeat = 302; | 619 | CtrlMsg_Event_Heartbeat event_heartbeat = 302; |
| 429 | CtrlMsg_Event_StationDisconnectFromAP event_station_disconnect_from_AP = 303; | 620 | CtrlMsg_Event_StationDisconnectFromAP event_station_disconnect_from_AP = 303; |
| 430 | CtrlMsg_Event_StationDisconnectFromESPSoftAP event_station_disconnect_from_ESP_SoftAP = 304; | 621 | CtrlMsg_Event_StationDisconnectFromESPSoftAP event_station_disconnect_from_ESP_SoftAP = 304; |
| 622 | CtrlMsg_Event_StationConnectedToAP event_station_connected_to_AP = 305; | ||
| 623 | CtrlMsg_Event_StationConnectedToESPSoftAP event_station_connected_to_ESP_SoftAP = 306; | ||
| 624 | CtrlMsg_Event_SetDhcpDnsStatus event_set_dhcp_dns_status = 307; | ||
| 625 | CtrlMsg_Event_CustomRpcUnserialisedMsg event_custom_rpc_unserialised_msg = 308; | ||
| 431 | } | 626 | } |
| 432 | } | 627 | } |
diff --git a/embassy-net-esp-hosted/src/iface.rs b/embassy-net-esp-hosted/src/iface.rs new file mode 100644 index 000000000..1f57851e0 --- /dev/null +++ b/embassy-net-esp-hosted/src/iface.rs | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | use embassy_time::Timer; | ||
| 2 | use embedded_hal::digital::InputPin; | ||
| 3 | use embedded_hal_async::digital::Wait; | ||
| 4 | use embedded_hal_async::spi::SpiDevice; | ||
| 5 | |||
| 6 | /// Physical interface trait for communicating with the ESP chip. | ||
| 7 | pub trait Interface { | ||
| 8 | /// Wait for the HANDSHAKE signal indicating the ESP is ready for a new transaction. | ||
| 9 | async fn wait_for_handshake(&mut self); | ||
| 10 | |||
| 11 | /// Wait for the READY signal indicating the ESP has data to send. | ||
| 12 | async fn wait_for_ready(&mut self); | ||
| 13 | |||
| 14 | /// Perform a SPI transfer, exchanging data with the ESP chip. | ||
| 15 | async fn transfer(&mut self, rx: &mut [u8], tx: &[u8]); | ||
| 16 | } | ||
| 17 | |||
| 18 | /// Standard SPI interface. | ||
| 19 | /// | ||
| 20 | /// This interface is what's implemented in the upstream `esp-hosted-fg` firmware. It uses: | ||
| 21 | /// - An `SpiDevice` for SPI communication (CS is handled by the device) | ||
| 22 | /// - A handshake pin that signals when the ESP is ready for a new transaction | ||
| 23 | /// - A ready pin that indicates when the ESP has data to send | ||
| 24 | pub struct SpiInterface<SPI, IN> { | ||
| 25 | spi: SPI, | ||
| 26 | handshake: IN, | ||
| 27 | ready: IN, | ||
| 28 | } | ||
| 29 | |||
| 30 | impl<SPI, IN> SpiInterface<SPI, IN> | ||
| 31 | where | ||
| 32 | SPI: SpiDevice, | ||
| 33 | IN: InputPin + Wait, | ||
| 34 | { | ||
| 35 | /// Create a new SpiInterface. | ||
| 36 | pub fn new(spi: SPI, handshake: IN, ready: IN) -> Self { | ||
| 37 | Self { spi, handshake, ready } | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | impl<SPI, IN> Interface for SpiInterface<SPI, IN> | ||
| 42 | where | ||
| 43 | SPI: SpiDevice, | ||
| 44 | IN: InputPin + Wait, | ||
| 45 | { | ||
| 46 | async fn wait_for_handshake(&mut self) { | ||
| 47 | self.handshake.wait_for_high().await.unwrap(); | ||
| 48 | } | ||
| 49 | |||
| 50 | async fn wait_for_ready(&mut self) { | ||
| 51 | self.ready.wait_for_high().await.unwrap(); | ||
| 52 | } | ||
| 53 | |||
| 54 | async fn transfer(&mut self, rx: &mut [u8], tx: &[u8]) { | ||
| 55 | self.spi.transfer(rx, tx).await.unwrap(); | ||
| 56 | |||
| 57 | // The esp-hosted firmware deasserts the HANDSHAKE pin a few us AFTER ending the SPI transfer | ||
| 58 | // If we check it again too fast, we'll see it's high from the previous transfer, and if we send it | ||
| 59 | // data it will get lost. | ||
| 60 | Timer::after_micros(100).await; | ||
| 61 | } | ||
| 62 | } | ||
diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs index 4405d9f77..d882af8cf 100644 --- a/embassy-net-esp-hosted/src/lib.rs +++ b/embassy-net-esp-hosted/src/lib.rs | |||
| @@ -1,27 +1,34 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![doc = include_str!("../README.md")] | 2 | #![doc = include_str!("../README.md")] |
| 3 | #![warn(missing_docs)] | 3 | #![warn(missing_docs)] |
| 4 | #![allow(async_fn_in_trait)] | ||
| 4 | 5 | ||
| 5 | use embassy_futures::select::{Either4, select4}; | 6 | use embassy_futures::select::{Either4, select4}; |
| 6 | use embassy_net_driver_channel as ch; | 7 | use embassy_net_driver_channel as ch; |
| 7 | use embassy_net_driver_channel::driver::LinkState; | 8 | use embassy_net_driver_channel::driver::LinkState; |
| 8 | use embassy_time::{Duration, Instant, Timer}; | 9 | use embassy_time::{Duration, Instant, Timer}; |
| 9 | use embedded_hal::digital::{InputPin, OutputPin}; | 10 | use embedded_hal::digital::OutputPin; |
| 10 | use embedded_hal_async::digital::Wait; | ||
| 11 | use embedded_hal_async::spi::SpiDevice; | ||
| 12 | 11 | ||
| 13 | use crate::ioctl::{PendingIoctl, Shared}; | 12 | use crate::ioctl::{PendingIoctl, Shared}; |
| 14 | use crate::proto::{CtrlMsg, CtrlMsgPayload}; | 13 | use crate::proto::{CtrlMsg, CtrlMsg_}; |
| 15 | 14 | ||
| 15 | #[allow(unused)] | ||
| 16 | #[allow(non_snake_case)] | ||
| 17 | #[allow(non_camel_case_types)] | ||
| 18 | #[allow(non_upper_case_globals)] | ||
| 19 | #[allow(missing_docs)] | ||
| 20 | #[allow(clippy::all)] | ||
| 16 | mod proto; | 21 | mod proto; |
| 17 | 22 | ||
| 18 | // must be first | 23 | // must be first |
| 19 | mod fmt; | 24 | mod fmt; |
| 20 | 25 | ||
| 21 | mod control; | 26 | mod control; |
| 27 | mod iface; | ||
| 22 | mod ioctl; | 28 | mod ioctl; |
| 23 | 29 | ||
| 24 | pub use control::*; | 30 | pub use control::*; |
| 31 | pub use iface::*; | ||
| 25 | 32 | ||
| 26 | const MTU: usize = 1514; | 33 | const MTU: usize = 1514; |
| 27 | 34 | ||
| @@ -118,20 +125,17 @@ impl State { | |||
| 118 | /// Type alias for network driver. | 125 | /// Type alias for network driver. |
| 119 | pub type NetDriver<'a> = ch::Device<'a, MTU>; | 126 | pub type NetDriver<'a> = ch::Device<'a, MTU>; |
| 120 | 127 | ||
| 121 | /// Create a new esp-hosted driver using the provided state, SPI peripheral and pins. | 128 | /// Create a new esp-hosted driver using the provided state, interface, and reset pin. |
| 122 | /// | 129 | /// |
| 123 | /// Returns a device handle for interfacing with embassy-net, a control handle for | 130 | /// Returns a device handle for interfacing with embassy-net, a control handle for |
| 124 | /// interacting with the driver, and a runner for communicating with the WiFi device. | 131 | /// interacting with the driver, and a runner for communicating with the WiFi device. |
| 125 | pub async fn new<'a, SPI, IN, OUT>( | 132 | pub async fn new<'a, I, OUT>( |
| 126 | state: &'a mut State, | 133 | state: &'a mut State, |
| 127 | spi: SPI, | 134 | iface: I, |
| 128 | handshake: IN, | ||
| 129 | ready: IN, | ||
| 130 | reset: OUT, | 135 | reset: OUT, |
| 131 | ) -> (NetDriver<'a>, Control<'a>, Runner<'a, SPI, IN, OUT>) | 136 | ) -> (NetDriver<'a>, Control<'a>, Runner<'a, I, OUT>) |
| 132 | where | 137 | where |
| 133 | SPI: SpiDevice, | 138 | I: Interface, |
| 134 | IN: InputPin + Wait, | ||
| 135 | OUT: OutputPin, | 139 | OUT: OutputPin, |
| 136 | { | 140 | { |
| 137 | let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ethernet([0; 6])); | 141 | let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ethernet([0; 6])); |
| @@ -142,10 +146,8 @@ where | |||
| 142 | state_ch, | 146 | state_ch, |
| 143 | shared: &state.shared, | 147 | shared: &state.shared, |
| 144 | next_seq: 1, | 148 | next_seq: 1, |
| 145 | handshake, | ||
| 146 | ready, | ||
| 147 | reset, | 149 | reset, |
| 148 | spi, | 150 | iface, |
| 149 | heartbeat_deadline: Instant::now() + HEARTBEAT_MAX_GAP, | 151 | heartbeat_deadline: Instant::now() + HEARTBEAT_MAX_GAP, |
| 150 | }; | 152 | }; |
| 151 | 153 | ||
| @@ -153,7 +155,7 @@ where | |||
| 153 | } | 155 | } |
| 154 | 156 | ||
| 155 | /// Runner for communicating with the WiFi device. | 157 | /// Runner for communicating with the WiFi device. |
| 156 | pub struct Runner<'a, SPI, IN, OUT> { | 158 | pub struct Runner<'a, I, OUT> { |
| 157 | ch: ch::Runner<'a, MTU>, | 159 | ch: ch::Runner<'a, MTU>, |
| 158 | state_ch: ch::StateRunner<'a>, | 160 | state_ch: ch::StateRunner<'a>, |
| 159 | shared: &'a Shared, | 161 | shared: &'a Shared, |
| @@ -161,16 +163,13 @@ pub struct Runner<'a, SPI, IN, OUT> { | |||
| 161 | next_seq: u16, | 163 | next_seq: u16, |
| 162 | heartbeat_deadline: Instant, | 164 | heartbeat_deadline: Instant, |
| 163 | 165 | ||
| 164 | spi: SPI, | 166 | iface: I, |
| 165 | handshake: IN, | ||
| 166 | ready: IN, | ||
| 167 | reset: OUT, | 167 | reset: OUT, |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | impl<'a, SPI, IN, OUT> Runner<'a, SPI, IN, OUT> | 170 | impl<'a, I, OUT> Runner<'a, I, OUT> |
| 171 | where | 171 | where |
| 172 | SPI: SpiDevice, | 172 | I: Interface, |
| 173 | IN: InputPin + Wait, | ||
| 174 | OUT: OutputPin, | 173 | OUT: OutputPin, |
| 175 | { | 174 | { |
| 176 | /// Run the packet processing. | 175 | /// Run the packet processing. |
| @@ -185,11 +184,11 @@ where | |||
| 185 | let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; | 184 | let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE]; |
| 186 | 185 | ||
| 187 | loop { | 186 | loop { |
| 188 | self.handshake.wait_for_high().await.unwrap(); | 187 | self.iface.wait_for_handshake().await; |
| 189 | 188 | ||
| 190 | let ioctl = self.shared.ioctl_wait_pending(); | 189 | let ioctl = self.shared.ioctl_wait_pending(); |
| 191 | let tx = self.ch.tx_buf(); | 190 | let tx = self.ch.tx_buf(); |
| 192 | let ev = async { self.ready.wait_for_high().await.unwrap() }; | 191 | let ev = async { self.iface.wait_for_ready().await }; |
| 193 | let hb = Timer::at(self.heartbeat_deadline); | 192 | let hb = Timer::at(self.heartbeat_deadline); |
| 194 | 193 | ||
| 195 | match select4(ioctl, tx, ev, hb).await { | 194 | match select4(ioctl, tx, ev, hb).await { |
| @@ -243,15 +242,9 @@ where | |||
| 243 | trace!("tx: {:02x}", &tx_buf[..40]); | 242 | trace!("tx: {:02x}", &tx_buf[..40]); |
| 244 | } | 243 | } |
| 245 | 244 | ||
| 246 | self.spi.transfer(&mut rx_buf, &tx_buf).await.unwrap(); | 245 | self.iface.transfer(&mut rx_buf, &tx_buf).await; |
| 247 | 246 | ||
| 248 | // The esp-hosted firmware deasserts the HANSHAKE pin a few us AFTER ending the SPI transfer | ||
| 249 | // If we check it again too fast, we'll see it's high from the previous transfer, and if we send it | ||
| 250 | // data it will get lost. | ||
| 251 | // Make sure we check it after 100us at minimum. | ||
| 252 | let delay_until = Instant::now() + Duration::from_micros(100); | ||
| 253 | self.handle_rx(&mut rx_buf); | 247 | self.handle_rx(&mut rx_buf); |
| 254 | Timer::at(delay_until).await; | ||
| 255 | } | 248 | } |
| 256 | } | 249 | } |
| 257 | 250 | ||
| @@ -326,10 +319,12 @@ where | |||
| 326 | } | 319 | } |
| 327 | 320 | ||
| 328 | fn handle_event(&mut self, data: &[u8]) { | 321 | fn handle_event(&mut self, data: &[u8]) { |
| 329 | let Ok(event) = noproto::read::<CtrlMsg>(data) else { | 322 | use micropb::MessageDecode; |
| 323 | let mut event = CtrlMsg::default(); | ||
| 324 | if event.decode_from_bytes(data).is_err() { | ||
| 330 | warn!("failed to parse event"); | 325 | warn!("failed to parse event"); |
| 331 | return; | 326 | return; |
| 332 | }; | 327 | } |
| 333 | 328 | ||
| 334 | debug!("event: {:?}", &event); | 329 | debug!("event: {:?}", &event); |
| 335 | 330 | ||
| @@ -339,9 +334,13 @@ where | |||
| 339 | }; | 334 | }; |
| 340 | 335 | ||
| 341 | match payload { | 336 | match payload { |
| 342 | CtrlMsgPayload::EventEspInit(_) => self.shared.init_done(), | 337 | CtrlMsg_::Payload::EventEspInit(_) => self.shared.init_done(), |
| 343 | CtrlMsgPayload::EventHeartbeat(_) => self.heartbeat_deadline = Instant::now() + HEARTBEAT_MAX_GAP, | 338 | CtrlMsg_::Payload::EventHeartbeat(_) => self.heartbeat_deadline = Instant::now() + HEARTBEAT_MAX_GAP, |
| 344 | CtrlMsgPayload::EventStationDisconnectFromAp(e) => { | 339 | CtrlMsg_::Payload::EventStationConnectedToAp(e) => { |
| 340 | info!("connected, code {}", e.resp); | ||
| 341 | self.state_ch.set_link_state(LinkState::Up); | ||
| 342 | } | ||
| 343 | CtrlMsg_::Payload::EventStationDisconnectFromAp(e) => { | ||
| 345 | info!("disconnected, code {}", e.resp); | 344 | info!("disconnected, code {}", e.resp); |
| 346 | self.state_ch.set_link_state(LinkState::Down); | 345 | self.state_ch.set_link_state(LinkState::Down); |
| 347 | } | 346 | } |
diff --git a/embassy-net-esp-hosted/src/proto.rs b/embassy-net-esp-hosted/src/proto.rs index 089ded677..74c67bd61 100644 --- a/embassy-net-esp-hosted/src/proto.rs +++ b/embassy-net-esp-hosted/src/proto.rs | |||
| @@ -1,656 +1,13764 @@ | |||
| 1 | #![allow(unused)] | 1 | /* |
| 2 | Generated with the following snippet. | ||
| 3 | Switch to a proper script when https://github.com/YuhanLiin/micropb/issues/30 is done | ||
| 2 | 4 | ||
| 3 | use heapless::{String, Vec}; | 5 | let mut g = micropb_gen::Generator::new(); |
| 6 | g.use_container_heapless(); | ||
| 4 | 7 | ||
| 5 | /// internal supporting structures for CtrlMsg | 8 | g.configure( |
| 9 | ".", | ||
| 10 | micropb_gen::Config::new() | ||
| 11 | .max_bytes(32) // For ssid, mac, etc - strings | ||
| 12 | .max_len(16) // For repeated fields | ||
| 13 | .type_attributes("#[cfg_attr(feature = \"defmt\", derive(defmt::Format))]"), | ||
| 14 | ); | ||
| 6 | 15 | ||
| 7 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 16 | // Special config for things that need to be larger |
| 8 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 17 | g.configure( |
| 9 | pub(crate) struct ScanResult { | 18 | ".CtrlMsg_Req_OTAWrite.ota_data", |
| 10 | #[noproto(tag = "1")] | 19 | micropb_gen::Config::new().max_bytes(1024), |
| 11 | pub ssid: String<32>, | 20 | ); |
| 12 | #[noproto(tag = "2")] | 21 | g.configure( |
| 13 | pub chnl: u32, | 22 | ".CtrlMsg_Event_ESPInit.init_data", |
| 14 | #[noproto(tag = "3")] | 23 | micropb_gen::Config::new().max_bytes(64), |
| 15 | pub rssi: u32, | 24 | ); |
| 16 | #[noproto(tag = "4")] | 25 | g.configure( |
| 17 | pub bssid: String<32>, | 26 | ".CtrlMsg_Req_VendorIEData.payload", |
| 18 | #[noproto(tag = "5")] | 27 | micropb_gen::Config::new().max_bytes(64), |
| 19 | pub sec_prot: CtrlWifiSecProt, | 28 | ); |
| 20 | } | 29 | |
| 30 | g.compile_protos(&["src/esp_hosted_config.proto"], format!("{}/proto.rs", out_dir)) | ||
| 31 | .unwrap(); | ||
| 32 | |||
| 33 | */ | ||
| 21 | 34 | ||
| 22 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 35 | #[derive(Debug, Default, PartialEq, Clone)] |
| 23 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 36 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 24 | pub(crate) struct ConnectedStaList { | 37 | pub struct ScanResult { |
| 25 | #[noproto(tag = "1")] | 38 | pub r#ssid: ::micropb::heapless::Vec<u8, 32>, |
| 26 | pub mac: String<32>, | 39 | pub r#chnl: u32, |
| 27 | #[noproto(tag = "2")] | 40 | pub r#rssi: i32, |
| 28 | pub rssi: u32, | 41 | pub r#bssid: ::micropb::heapless::Vec<u8, 32>, |
| 42 | pub r#sec_prot: Ctrl_WifiSecProt, | ||
| 29 | } | 43 | } |
| 30 | /// * Req/Resp structure * | 44 | impl ScanResult { |
| 31 | 45 | ///Return a reference to `ssid` | |
| 32 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 46 | #[inline] |
| 47 | pub fn r#ssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 48 | &self.r#ssid | ||
| 49 | } | ||
| 50 | ///Return a mutable reference to `ssid` | ||
| 51 | #[inline] | ||
| 52 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 53 | &mut self.r#ssid | ||
| 54 | } | ||
| 55 | ///Set the value of `ssid` | ||
| 56 | #[inline] | ||
| 57 | pub fn set_ssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 58 | self.r#ssid = value.into(); | ||
| 59 | self | ||
| 60 | } | ||
| 61 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. | ||
| 62 | #[inline] | ||
| 63 | pub fn init_ssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 64 | self.r#ssid = value.into(); | ||
| 65 | self | ||
| 66 | } | ||
| 67 | ///Return a reference to `chnl` | ||
| 68 | #[inline] | ||
| 69 | pub fn r#chnl(&self) -> &u32 { | ||
| 70 | &self.r#chnl | ||
| 71 | } | ||
| 72 | ///Return a mutable reference to `chnl` | ||
| 73 | #[inline] | ||
| 74 | pub fn mut_chnl(&mut self) -> &mut u32 { | ||
| 75 | &mut self.r#chnl | ||
| 76 | } | ||
| 77 | ///Set the value of `chnl` | ||
| 78 | #[inline] | ||
| 79 | pub fn set_chnl(&mut self, value: u32) -> &mut Self { | ||
| 80 | self.r#chnl = value.into(); | ||
| 81 | self | ||
| 82 | } | ||
| 83 | ///Builder method that sets the value of `chnl`. Useful for initializing the message. | ||
| 84 | #[inline] | ||
| 85 | pub fn init_chnl(mut self, value: u32) -> Self { | ||
| 86 | self.r#chnl = value.into(); | ||
| 87 | self | ||
| 88 | } | ||
| 89 | ///Return a reference to `rssi` | ||
| 90 | #[inline] | ||
| 91 | pub fn r#rssi(&self) -> &i32 { | ||
| 92 | &self.r#rssi | ||
| 93 | } | ||
| 94 | ///Return a mutable reference to `rssi` | ||
| 95 | #[inline] | ||
| 96 | pub fn mut_rssi(&mut self) -> &mut i32 { | ||
| 97 | &mut self.r#rssi | ||
| 98 | } | ||
| 99 | ///Set the value of `rssi` | ||
| 100 | #[inline] | ||
| 101 | pub fn set_rssi(&mut self, value: i32) -> &mut Self { | ||
| 102 | self.r#rssi = value.into(); | ||
| 103 | self | ||
| 104 | } | ||
| 105 | ///Builder method that sets the value of `rssi`. Useful for initializing the message. | ||
| 106 | #[inline] | ||
| 107 | pub fn init_rssi(mut self, value: i32) -> Self { | ||
| 108 | self.r#rssi = value.into(); | ||
| 109 | self | ||
| 110 | } | ||
| 111 | ///Return a reference to `bssid` | ||
| 112 | #[inline] | ||
| 113 | pub fn r#bssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 114 | &self.r#bssid | ||
| 115 | } | ||
| 116 | ///Return a mutable reference to `bssid` | ||
| 117 | #[inline] | ||
| 118 | pub fn mut_bssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 119 | &mut self.r#bssid | ||
| 120 | } | ||
| 121 | ///Set the value of `bssid` | ||
| 122 | #[inline] | ||
| 123 | pub fn set_bssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 124 | self.r#bssid = value.into(); | ||
| 125 | self | ||
| 126 | } | ||
| 127 | ///Builder method that sets the value of `bssid`. Useful for initializing the message. | ||
| 128 | #[inline] | ||
| 129 | pub fn init_bssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 130 | self.r#bssid = value.into(); | ||
| 131 | self | ||
| 132 | } | ||
| 133 | ///Return a reference to `sec_prot` | ||
| 134 | #[inline] | ||
| 135 | pub fn r#sec_prot(&self) -> &Ctrl_WifiSecProt { | ||
| 136 | &self.r#sec_prot | ||
| 137 | } | ||
| 138 | ///Return a mutable reference to `sec_prot` | ||
| 139 | #[inline] | ||
| 140 | pub fn mut_sec_prot(&mut self) -> &mut Ctrl_WifiSecProt { | ||
| 141 | &mut self.r#sec_prot | ||
| 142 | } | ||
| 143 | ///Set the value of `sec_prot` | ||
| 144 | #[inline] | ||
| 145 | pub fn set_sec_prot(&mut self, value: Ctrl_WifiSecProt) -> &mut Self { | ||
| 146 | self.r#sec_prot = value.into(); | ||
| 147 | self | ||
| 148 | } | ||
| 149 | ///Builder method that sets the value of `sec_prot`. Useful for initializing the message. | ||
| 150 | #[inline] | ||
| 151 | pub fn init_sec_prot(mut self, value: Ctrl_WifiSecProt) -> Self { | ||
| 152 | self.r#sec_prot = value.into(); | ||
| 153 | self | ||
| 154 | } | ||
| 155 | } | ||
| 156 | impl ::micropb::MessageDecode for ScanResult { | ||
| 157 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 158 | &mut self, | ||
| 159 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 160 | len: usize, | ||
| 161 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 162 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 163 | let before = decoder.bytes_read(); | ||
| 164 | while decoder.bytes_read() - before < len { | ||
| 165 | let tag = decoder.decode_tag()?; | ||
| 166 | match tag.field_num() { | ||
| 167 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 168 | 1u32 => { | ||
| 169 | let mut_ref = &mut self.r#ssid; | ||
| 170 | { | ||
| 171 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 172 | }; | ||
| 173 | } | ||
| 174 | 2u32 => { | ||
| 175 | let mut_ref = &mut self.r#chnl; | ||
| 176 | { | ||
| 177 | let val = decoder.decode_varint32()?; | ||
| 178 | let val_ref = &val; | ||
| 179 | if *val_ref != 0 { | ||
| 180 | *mut_ref = val as _; | ||
| 181 | } | ||
| 182 | }; | ||
| 183 | } | ||
| 184 | 3u32 => { | ||
| 185 | let mut_ref = &mut self.r#rssi; | ||
| 186 | { | ||
| 187 | let val = decoder.decode_int32()?; | ||
| 188 | let val_ref = &val; | ||
| 189 | if *val_ref != 0 { | ||
| 190 | *mut_ref = val as _; | ||
| 191 | } | ||
| 192 | }; | ||
| 193 | } | ||
| 194 | 4u32 => { | ||
| 195 | let mut_ref = &mut self.r#bssid; | ||
| 196 | { | ||
| 197 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 198 | }; | ||
| 199 | } | ||
| 200 | 5u32 => { | ||
| 201 | let mut_ref = &mut self.r#sec_prot; | ||
| 202 | { | ||
| 203 | let val = decoder.decode_int32().map(|n| Ctrl_WifiSecProt(n as _))?; | ||
| 204 | let val_ref = &val; | ||
| 205 | if val_ref.0 != 0 { | ||
| 206 | *mut_ref = val as _; | ||
| 207 | } | ||
| 208 | }; | ||
| 209 | } | ||
| 210 | _ => { | ||
| 211 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 212 | } | ||
| 213 | } | ||
| 214 | } | ||
| 215 | Ok(()) | ||
| 216 | } | ||
| 217 | } | ||
| 218 | impl ::micropb::MessageEncode for ScanResult { | ||
| 219 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 220 | let mut max_size = 0; | ||
| 221 | if let ::core::option::Option::Some(size) = | ||
| 222 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 223 | { | ||
| 224 | max_size += size; | ||
| 225 | } else { | ||
| 226 | break 'msg (::core::option::Option::<usize>::None); | ||
| 227 | }; | ||
| 228 | if let ::core::option::Option::Some(size) = | ||
| 229 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 230 | { | ||
| 231 | max_size += size; | ||
| 232 | } else { | ||
| 233 | break 'msg (::core::option::Option::<usize>::None); | ||
| 234 | }; | ||
| 235 | if let ::core::option::Option::Some(size) = | ||
| 236 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 237 | { | ||
| 238 | max_size += size; | ||
| 239 | } else { | ||
| 240 | break 'msg (::core::option::Option::<usize>::None); | ||
| 241 | }; | ||
| 242 | if let ::core::option::Option::Some(size) = | ||
| 243 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 244 | { | ||
| 245 | max_size += size; | ||
| 246 | } else { | ||
| 247 | break 'msg (::core::option::Option::<usize>::None); | ||
| 248 | }; | ||
| 249 | if let ::core::option::Option::Some(size) = | ||
| 250 | ::micropb::const_map!(::core::option::Option::Some(Ctrl_WifiSecProt::_MAX_SIZE), |size| size | ||
| 251 | + 1usize) | ||
| 252 | { | ||
| 253 | max_size += size; | ||
| 254 | } else { | ||
| 255 | break 'msg (::core::option::Option::<usize>::None); | ||
| 256 | }; | ||
| 257 | ::core::option::Option::Some(max_size) | ||
| 258 | }; | ||
| 259 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 260 | &self, | ||
| 261 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 262 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 263 | use ::micropb::{FieldEncode, PbMap}; | ||
| 264 | { | ||
| 265 | let val_ref = &self.r#ssid; | ||
| 266 | if !val_ref.is_empty() { | ||
| 267 | encoder.encode_varint32(10u32)?; | ||
| 268 | encoder.encode_bytes(val_ref)?; | ||
| 269 | } | ||
| 270 | } | ||
| 271 | { | ||
| 272 | let val_ref = &self.r#chnl; | ||
| 273 | if *val_ref != 0 { | ||
| 274 | encoder.encode_varint32(16u32)?; | ||
| 275 | encoder.encode_varint32(*val_ref as _)?; | ||
| 276 | } | ||
| 277 | } | ||
| 278 | { | ||
| 279 | let val_ref = &self.r#rssi; | ||
| 280 | if *val_ref != 0 { | ||
| 281 | encoder.encode_varint32(24u32)?; | ||
| 282 | encoder.encode_int32(*val_ref as _)?; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | { | ||
| 286 | let val_ref = &self.r#bssid; | ||
| 287 | if !val_ref.is_empty() { | ||
| 288 | encoder.encode_varint32(34u32)?; | ||
| 289 | encoder.encode_bytes(val_ref)?; | ||
| 290 | } | ||
| 291 | } | ||
| 292 | { | ||
| 293 | let val_ref = &self.r#sec_prot; | ||
| 294 | if val_ref.0 != 0 { | ||
| 295 | encoder.encode_varint32(40u32)?; | ||
| 296 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 297 | } | ||
| 298 | } | ||
| 299 | Ok(()) | ||
| 300 | } | ||
| 301 | fn compute_size(&self) -> usize { | ||
| 302 | use ::micropb::{FieldEncode, PbMap}; | ||
| 303 | let mut size = 0; | ||
| 304 | { | ||
| 305 | let val_ref = &self.r#ssid; | ||
| 306 | if !val_ref.is_empty() { | ||
| 307 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | { | ||
| 311 | let val_ref = &self.r#chnl; | ||
| 312 | if *val_ref != 0 { | ||
| 313 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | { | ||
| 317 | let val_ref = &self.r#rssi; | ||
| 318 | if *val_ref != 0 { | ||
| 319 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 320 | } | ||
| 321 | } | ||
| 322 | { | ||
| 323 | let val_ref = &self.r#bssid; | ||
| 324 | if !val_ref.is_empty() { | ||
| 325 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 326 | } | ||
| 327 | } | ||
| 328 | { | ||
| 329 | let val_ref = &self.r#sec_prot; | ||
| 330 | if val_ref.0 != 0 { | ||
| 331 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | size | ||
| 335 | } | ||
| 336 | } | ||
| 337 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 33 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 338 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 34 | pub(crate) struct CtrlMsgReqGetMacAddress { | 339 | pub struct ConnectedSTAList { |
| 35 | #[noproto(tag = "1")] | 340 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, |
| 36 | pub mode: u32, | 341 | pub r#rssi: i32, |
| 37 | } | 342 | } |
| 38 | 343 | impl ConnectedSTAList { | |
| 39 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 344 | ///Return a reference to `mac` |
| 345 | #[inline] | ||
| 346 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 347 | &self.r#mac | ||
| 348 | } | ||
| 349 | ///Return a mutable reference to `mac` | ||
| 350 | #[inline] | ||
| 351 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 352 | &mut self.r#mac | ||
| 353 | } | ||
| 354 | ///Set the value of `mac` | ||
| 355 | #[inline] | ||
| 356 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 357 | self.r#mac = value.into(); | ||
| 358 | self | ||
| 359 | } | ||
| 360 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 361 | #[inline] | ||
| 362 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 363 | self.r#mac = value.into(); | ||
| 364 | self | ||
| 365 | } | ||
| 366 | ///Return a reference to `rssi` | ||
| 367 | #[inline] | ||
| 368 | pub fn r#rssi(&self) -> &i32 { | ||
| 369 | &self.r#rssi | ||
| 370 | } | ||
| 371 | ///Return a mutable reference to `rssi` | ||
| 372 | #[inline] | ||
| 373 | pub fn mut_rssi(&mut self) -> &mut i32 { | ||
| 374 | &mut self.r#rssi | ||
| 375 | } | ||
| 376 | ///Set the value of `rssi` | ||
| 377 | #[inline] | ||
| 378 | pub fn set_rssi(&mut self, value: i32) -> &mut Self { | ||
| 379 | self.r#rssi = value.into(); | ||
| 380 | self | ||
| 381 | } | ||
| 382 | ///Builder method that sets the value of `rssi`. Useful for initializing the message. | ||
| 383 | #[inline] | ||
| 384 | pub fn init_rssi(mut self, value: i32) -> Self { | ||
| 385 | self.r#rssi = value.into(); | ||
| 386 | self | ||
| 387 | } | ||
| 388 | } | ||
| 389 | impl ::micropb::MessageDecode for ConnectedSTAList { | ||
| 390 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 391 | &mut self, | ||
| 392 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 393 | len: usize, | ||
| 394 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 395 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 396 | let before = decoder.bytes_read(); | ||
| 397 | while decoder.bytes_read() - before < len { | ||
| 398 | let tag = decoder.decode_tag()?; | ||
| 399 | match tag.field_num() { | ||
| 400 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 401 | 1u32 => { | ||
| 402 | let mut_ref = &mut self.r#mac; | ||
| 403 | { | ||
| 404 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 405 | }; | ||
| 406 | } | ||
| 407 | 2u32 => { | ||
| 408 | let mut_ref = &mut self.r#rssi; | ||
| 409 | { | ||
| 410 | let val = decoder.decode_int32()?; | ||
| 411 | let val_ref = &val; | ||
| 412 | if *val_ref != 0 { | ||
| 413 | *mut_ref = val as _; | ||
| 414 | } | ||
| 415 | }; | ||
| 416 | } | ||
| 417 | _ => { | ||
| 418 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | } | ||
| 422 | Ok(()) | ||
| 423 | } | ||
| 424 | } | ||
| 425 | impl ::micropb::MessageEncode for ConnectedSTAList { | ||
| 426 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 427 | let mut max_size = 0; | ||
| 428 | if let ::core::option::Option::Some(size) = | ||
| 429 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 430 | { | ||
| 431 | max_size += size; | ||
| 432 | } else { | ||
| 433 | break 'msg (::core::option::Option::<usize>::None); | ||
| 434 | }; | ||
| 435 | if let ::core::option::Option::Some(size) = | ||
| 436 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 437 | { | ||
| 438 | max_size += size; | ||
| 439 | } else { | ||
| 440 | break 'msg (::core::option::Option::<usize>::None); | ||
| 441 | }; | ||
| 442 | ::core::option::Option::Some(max_size) | ||
| 443 | }; | ||
| 444 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 445 | &self, | ||
| 446 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 447 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 448 | use ::micropb::{FieldEncode, PbMap}; | ||
| 449 | { | ||
| 450 | let val_ref = &self.r#mac; | ||
| 451 | if !val_ref.is_empty() { | ||
| 452 | encoder.encode_varint32(10u32)?; | ||
| 453 | encoder.encode_bytes(val_ref)?; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | { | ||
| 457 | let val_ref = &self.r#rssi; | ||
| 458 | if *val_ref != 0 { | ||
| 459 | encoder.encode_varint32(16u32)?; | ||
| 460 | encoder.encode_int32(*val_ref as _)?; | ||
| 461 | } | ||
| 462 | } | ||
| 463 | Ok(()) | ||
| 464 | } | ||
| 465 | fn compute_size(&self) -> usize { | ||
| 466 | use ::micropb::{FieldEncode, PbMap}; | ||
| 467 | let mut size = 0; | ||
| 468 | { | ||
| 469 | let val_ref = &self.r#mac; | ||
| 470 | if !val_ref.is_empty() { | ||
| 471 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 472 | } | ||
| 473 | } | ||
| 474 | { | ||
| 475 | let val_ref = &self.r#rssi; | ||
| 476 | if *val_ref != 0 { | ||
| 477 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | size | ||
| 481 | } | ||
| 482 | } | ||
| 483 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 40 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 484 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 41 | pub(crate) struct CtrlMsgRespGetMacAddress { | 485 | pub struct CtrlMsg_Req_GetMacAddress { |
| 42 | #[noproto(tag = "1")] | 486 | pub r#mode: i32, |
| 43 | pub mac: String<32>, | ||
| 44 | #[noproto(tag = "2")] | ||
| 45 | pub resp: u32, | ||
| 46 | } | 487 | } |
| 47 | 488 | impl CtrlMsg_Req_GetMacAddress { | |
| 48 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 489 | ///Return a reference to `mode` |
| 490 | #[inline] | ||
| 491 | pub fn r#mode(&self) -> &i32 { | ||
| 492 | &self.r#mode | ||
| 493 | } | ||
| 494 | ///Return a mutable reference to `mode` | ||
| 495 | #[inline] | ||
| 496 | pub fn mut_mode(&mut self) -> &mut i32 { | ||
| 497 | &mut self.r#mode | ||
| 498 | } | ||
| 499 | ///Set the value of `mode` | ||
| 500 | #[inline] | ||
| 501 | pub fn set_mode(&mut self, value: i32) -> &mut Self { | ||
| 502 | self.r#mode = value.into(); | ||
| 503 | self | ||
| 504 | } | ||
| 505 | ///Builder method that sets the value of `mode`. Useful for initializing the message. | ||
| 506 | #[inline] | ||
| 507 | pub fn init_mode(mut self, value: i32) -> Self { | ||
| 508 | self.r#mode = value.into(); | ||
| 509 | self | ||
| 510 | } | ||
| 511 | } | ||
| 512 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetMacAddress { | ||
| 513 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 514 | &mut self, | ||
| 515 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 516 | len: usize, | ||
| 517 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 518 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 519 | let before = decoder.bytes_read(); | ||
| 520 | while decoder.bytes_read() - before < len { | ||
| 521 | let tag = decoder.decode_tag()?; | ||
| 522 | match tag.field_num() { | ||
| 523 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 524 | 1u32 => { | ||
| 525 | let mut_ref = &mut self.r#mode; | ||
| 526 | { | ||
| 527 | let val = decoder.decode_int32()?; | ||
| 528 | let val_ref = &val; | ||
| 529 | if *val_ref != 0 { | ||
| 530 | *mut_ref = val as _; | ||
| 531 | } | ||
| 532 | }; | ||
| 533 | } | ||
| 534 | _ => { | ||
| 535 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 536 | } | ||
| 537 | } | ||
| 538 | } | ||
| 539 | Ok(()) | ||
| 540 | } | ||
| 541 | } | ||
| 542 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetMacAddress { | ||
| 543 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 544 | let mut max_size = 0; | ||
| 545 | if let ::core::option::Option::Some(size) = | ||
| 546 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 547 | { | ||
| 548 | max_size += size; | ||
| 549 | } else { | ||
| 550 | break 'msg (::core::option::Option::<usize>::None); | ||
| 551 | }; | ||
| 552 | ::core::option::Option::Some(max_size) | ||
| 553 | }; | ||
| 554 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 555 | &self, | ||
| 556 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 557 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 558 | use ::micropb::{FieldEncode, PbMap}; | ||
| 559 | { | ||
| 560 | let val_ref = &self.r#mode; | ||
| 561 | if *val_ref != 0 { | ||
| 562 | encoder.encode_varint32(8u32)?; | ||
| 563 | encoder.encode_int32(*val_ref as _)?; | ||
| 564 | } | ||
| 565 | } | ||
| 566 | Ok(()) | ||
| 567 | } | ||
| 568 | fn compute_size(&self) -> usize { | ||
| 569 | use ::micropb::{FieldEncode, PbMap}; | ||
| 570 | let mut size = 0; | ||
| 571 | { | ||
| 572 | let val_ref = &self.r#mode; | ||
| 573 | if *val_ref != 0 { | ||
| 574 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 575 | } | ||
| 576 | } | ||
| 577 | size | ||
| 578 | } | ||
| 579 | } | ||
| 580 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 49 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 581 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 50 | pub(crate) struct CtrlMsgReqGetMode {} | 582 | pub struct CtrlMsg_Resp_GetMacAddress { |
| 51 | 583 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, | |
| 52 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 584 | pub r#resp: i32, |
| 585 | } | ||
| 586 | impl CtrlMsg_Resp_GetMacAddress { | ||
| 587 | ///Return a reference to `mac` | ||
| 588 | #[inline] | ||
| 589 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 590 | &self.r#mac | ||
| 591 | } | ||
| 592 | ///Return a mutable reference to `mac` | ||
| 593 | #[inline] | ||
| 594 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 595 | &mut self.r#mac | ||
| 596 | } | ||
| 597 | ///Set the value of `mac` | ||
| 598 | #[inline] | ||
| 599 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 600 | self.r#mac = value.into(); | ||
| 601 | self | ||
| 602 | } | ||
| 603 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 604 | #[inline] | ||
| 605 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 606 | self.r#mac = value.into(); | ||
| 607 | self | ||
| 608 | } | ||
| 609 | ///Return a reference to `resp` | ||
| 610 | #[inline] | ||
| 611 | pub fn r#resp(&self) -> &i32 { | ||
| 612 | &self.r#resp | ||
| 613 | } | ||
| 614 | ///Return a mutable reference to `resp` | ||
| 615 | #[inline] | ||
| 616 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 617 | &mut self.r#resp | ||
| 618 | } | ||
| 619 | ///Set the value of `resp` | ||
| 620 | #[inline] | ||
| 621 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 622 | self.r#resp = value.into(); | ||
| 623 | self | ||
| 624 | } | ||
| 625 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 626 | #[inline] | ||
| 627 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 628 | self.r#resp = value.into(); | ||
| 629 | self | ||
| 630 | } | ||
| 631 | } | ||
| 632 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetMacAddress { | ||
| 633 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 634 | &mut self, | ||
| 635 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 636 | len: usize, | ||
| 637 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 638 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 639 | let before = decoder.bytes_read(); | ||
| 640 | while decoder.bytes_read() - before < len { | ||
| 641 | let tag = decoder.decode_tag()?; | ||
| 642 | match tag.field_num() { | ||
| 643 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 644 | 1u32 => { | ||
| 645 | let mut_ref = &mut self.r#mac; | ||
| 646 | { | ||
| 647 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 648 | }; | ||
| 649 | } | ||
| 650 | 2u32 => { | ||
| 651 | let mut_ref = &mut self.r#resp; | ||
| 652 | { | ||
| 653 | let val = decoder.decode_int32()?; | ||
| 654 | let val_ref = &val; | ||
| 655 | if *val_ref != 0 { | ||
| 656 | *mut_ref = val as _; | ||
| 657 | } | ||
| 658 | }; | ||
| 659 | } | ||
| 660 | _ => { | ||
| 661 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 662 | } | ||
| 663 | } | ||
| 664 | } | ||
| 665 | Ok(()) | ||
| 666 | } | ||
| 667 | } | ||
| 668 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetMacAddress { | ||
| 669 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 670 | let mut max_size = 0; | ||
| 671 | if let ::core::option::Option::Some(size) = | ||
| 672 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 673 | { | ||
| 674 | max_size += size; | ||
| 675 | } else { | ||
| 676 | break 'msg (::core::option::Option::<usize>::None); | ||
| 677 | }; | ||
| 678 | if let ::core::option::Option::Some(size) = | ||
| 679 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 680 | { | ||
| 681 | max_size += size; | ||
| 682 | } else { | ||
| 683 | break 'msg (::core::option::Option::<usize>::None); | ||
| 684 | }; | ||
| 685 | ::core::option::Option::Some(max_size) | ||
| 686 | }; | ||
| 687 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 688 | &self, | ||
| 689 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 690 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 691 | use ::micropb::{FieldEncode, PbMap}; | ||
| 692 | { | ||
| 693 | let val_ref = &self.r#mac; | ||
| 694 | if !val_ref.is_empty() { | ||
| 695 | encoder.encode_varint32(10u32)?; | ||
| 696 | encoder.encode_bytes(val_ref)?; | ||
| 697 | } | ||
| 698 | } | ||
| 699 | { | ||
| 700 | let val_ref = &self.r#resp; | ||
| 701 | if *val_ref != 0 { | ||
| 702 | encoder.encode_varint32(16u32)?; | ||
| 703 | encoder.encode_int32(*val_ref as _)?; | ||
| 704 | } | ||
| 705 | } | ||
| 706 | Ok(()) | ||
| 707 | } | ||
| 708 | fn compute_size(&self) -> usize { | ||
| 709 | use ::micropb::{FieldEncode, PbMap}; | ||
| 710 | let mut size = 0; | ||
| 711 | { | ||
| 712 | let val_ref = &self.r#mac; | ||
| 713 | if !val_ref.is_empty() { | ||
| 714 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 715 | } | ||
| 716 | } | ||
| 717 | { | ||
| 718 | let val_ref = &self.r#resp; | ||
| 719 | if *val_ref != 0 { | ||
| 720 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 721 | } | ||
| 722 | } | ||
| 723 | size | ||
| 724 | } | ||
| 725 | } | ||
| 726 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 53 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 727 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 54 | pub(crate) struct CtrlMsgRespGetMode { | 728 | pub struct CtrlMsg_Req_GetMode {} |
| 55 | #[noproto(tag = "1")] | 729 | impl CtrlMsg_Req_GetMode {} |
| 56 | pub mode: u32, | 730 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetMode { |
| 57 | #[noproto(tag = "2")] | 731 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 58 | pub resp: u32, | 732 | &mut self, |
| 733 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 734 | len: usize, | ||
| 735 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 736 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 737 | let before = decoder.bytes_read(); | ||
| 738 | while decoder.bytes_read() - before < len { | ||
| 739 | let tag = decoder.decode_tag()?; | ||
| 740 | match tag.field_num() { | ||
| 741 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 742 | _ => { | ||
| 743 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 744 | } | ||
| 745 | } | ||
| 746 | } | ||
| 747 | Ok(()) | ||
| 748 | } | ||
| 59 | } | 749 | } |
| 60 | 750 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetMode { | |
| 61 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 751 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 752 | let mut max_size = 0; | ||
| 753 | ::core::option::Option::Some(max_size) | ||
| 754 | }; | ||
| 755 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 756 | &self, | ||
| 757 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 758 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 759 | use ::micropb::{FieldEncode, PbMap}; | ||
| 760 | Ok(()) | ||
| 761 | } | ||
| 762 | fn compute_size(&self) -> usize { | ||
| 763 | use ::micropb::{FieldEncode, PbMap}; | ||
| 764 | let mut size = 0; | ||
| 765 | size | ||
| 766 | } | ||
| 767 | } | ||
| 768 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 62 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 769 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 63 | pub(crate) struct CtrlMsgReqSetMode { | 770 | pub struct CtrlMsg_Resp_GetMode { |
| 64 | #[noproto(tag = "1")] | 771 | pub r#mode: i32, |
| 65 | pub mode: u32, | 772 | pub r#resp: i32, |
| 66 | } | 773 | } |
| 67 | 774 | impl CtrlMsg_Resp_GetMode { | |
| 68 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 775 | ///Return a reference to `mode` |
| 776 | #[inline] | ||
| 777 | pub fn r#mode(&self) -> &i32 { | ||
| 778 | &self.r#mode | ||
| 779 | } | ||
| 780 | ///Return a mutable reference to `mode` | ||
| 781 | #[inline] | ||
| 782 | pub fn mut_mode(&mut self) -> &mut i32 { | ||
| 783 | &mut self.r#mode | ||
| 784 | } | ||
| 785 | ///Set the value of `mode` | ||
| 786 | #[inline] | ||
| 787 | pub fn set_mode(&mut self, value: i32) -> &mut Self { | ||
| 788 | self.r#mode = value.into(); | ||
| 789 | self | ||
| 790 | } | ||
| 791 | ///Builder method that sets the value of `mode`. Useful for initializing the message. | ||
| 792 | #[inline] | ||
| 793 | pub fn init_mode(mut self, value: i32) -> Self { | ||
| 794 | self.r#mode = value.into(); | ||
| 795 | self | ||
| 796 | } | ||
| 797 | ///Return a reference to `resp` | ||
| 798 | #[inline] | ||
| 799 | pub fn r#resp(&self) -> &i32 { | ||
| 800 | &self.r#resp | ||
| 801 | } | ||
| 802 | ///Return a mutable reference to `resp` | ||
| 803 | #[inline] | ||
| 804 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 805 | &mut self.r#resp | ||
| 806 | } | ||
| 807 | ///Set the value of `resp` | ||
| 808 | #[inline] | ||
| 809 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 810 | self.r#resp = value.into(); | ||
| 811 | self | ||
| 812 | } | ||
| 813 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 814 | #[inline] | ||
| 815 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 816 | self.r#resp = value.into(); | ||
| 817 | self | ||
| 818 | } | ||
| 819 | } | ||
| 820 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetMode { | ||
| 821 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 822 | &mut self, | ||
| 823 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 824 | len: usize, | ||
| 825 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 826 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 827 | let before = decoder.bytes_read(); | ||
| 828 | while decoder.bytes_read() - before < len { | ||
| 829 | let tag = decoder.decode_tag()?; | ||
| 830 | match tag.field_num() { | ||
| 831 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 832 | 1u32 => { | ||
| 833 | let mut_ref = &mut self.r#mode; | ||
| 834 | { | ||
| 835 | let val = decoder.decode_int32()?; | ||
| 836 | let val_ref = &val; | ||
| 837 | if *val_ref != 0 { | ||
| 838 | *mut_ref = val as _; | ||
| 839 | } | ||
| 840 | }; | ||
| 841 | } | ||
| 842 | 2u32 => { | ||
| 843 | let mut_ref = &mut self.r#resp; | ||
| 844 | { | ||
| 845 | let val = decoder.decode_int32()?; | ||
| 846 | let val_ref = &val; | ||
| 847 | if *val_ref != 0 { | ||
| 848 | *mut_ref = val as _; | ||
| 849 | } | ||
| 850 | }; | ||
| 851 | } | ||
| 852 | _ => { | ||
| 853 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 854 | } | ||
| 855 | } | ||
| 856 | } | ||
| 857 | Ok(()) | ||
| 858 | } | ||
| 859 | } | ||
| 860 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetMode { | ||
| 861 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 862 | let mut max_size = 0; | ||
| 863 | if let ::core::option::Option::Some(size) = | ||
| 864 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 865 | { | ||
| 866 | max_size += size; | ||
| 867 | } else { | ||
| 868 | break 'msg (::core::option::Option::<usize>::None); | ||
| 869 | }; | ||
| 870 | if let ::core::option::Option::Some(size) = | ||
| 871 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 872 | { | ||
| 873 | max_size += size; | ||
| 874 | } else { | ||
| 875 | break 'msg (::core::option::Option::<usize>::None); | ||
| 876 | }; | ||
| 877 | ::core::option::Option::Some(max_size) | ||
| 878 | }; | ||
| 879 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 880 | &self, | ||
| 881 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 882 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 883 | use ::micropb::{FieldEncode, PbMap}; | ||
| 884 | { | ||
| 885 | let val_ref = &self.r#mode; | ||
| 886 | if *val_ref != 0 { | ||
| 887 | encoder.encode_varint32(8u32)?; | ||
| 888 | encoder.encode_int32(*val_ref as _)?; | ||
| 889 | } | ||
| 890 | } | ||
| 891 | { | ||
| 892 | let val_ref = &self.r#resp; | ||
| 893 | if *val_ref != 0 { | ||
| 894 | encoder.encode_varint32(16u32)?; | ||
| 895 | encoder.encode_int32(*val_ref as _)?; | ||
| 896 | } | ||
| 897 | } | ||
| 898 | Ok(()) | ||
| 899 | } | ||
| 900 | fn compute_size(&self) -> usize { | ||
| 901 | use ::micropb::{FieldEncode, PbMap}; | ||
| 902 | let mut size = 0; | ||
| 903 | { | ||
| 904 | let val_ref = &self.r#mode; | ||
| 905 | if *val_ref != 0 { | ||
| 906 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 907 | } | ||
| 908 | } | ||
| 909 | { | ||
| 910 | let val_ref = &self.r#resp; | ||
| 911 | if *val_ref != 0 { | ||
| 912 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 913 | } | ||
| 914 | } | ||
| 915 | size | ||
| 916 | } | ||
| 917 | } | ||
| 918 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 69 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 919 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 70 | pub(crate) struct CtrlMsgRespSetMode { | 920 | pub struct CtrlMsg_Req_SetMode { |
| 71 | #[noproto(tag = "1")] | 921 | pub r#mode: i32, |
| 72 | pub resp: u32, | ||
| 73 | } | 922 | } |
| 74 | 923 | impl CtrlMsg_Req_SetMode { | |
| 75 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 924 | ///Return a reference to `mode` |
| 925 | #[inline] | ||
| 926 | pub fn r#mode(&self) -> &i32 { | ||
| 927 | &self.r#mode | ||
| 928 | } | ||
| 929 | ///Return a mutable reference to `mode` | ||
| 930 | #[inline] | ||
| 931 | pub fn mut_mode(&mut self) -> &mut i32 { | ||
| 932 | &mut self.r#mode | ||
| 933 | } | ||
| 934 | ///Set the value of `mode` | ||
| 935 | #[inline] | ||
| 936 | pub fn set_mode(&mut self, value: i32) -> &mut Self { | ||
| 937 | self.r#mode = value.into(); | ||
| 938 | self | ||
| 939 | } | ||
| 940 | ///Builder method that sets the value of `mode`. Useful for initializing the message. | ||
| 941 | #[inline] | ||
| 942 | pub fn init_mode(mut self, value: i32) -> Self { | ||
| 943 | self.r#mode = value.into(); | ||
| 944 | self | ||
| 945 | } | ||
| 946 | } | ||
| 947 | impl ::micropb::MessageDecode for CtrlMsg_Req_SetMode { | ||
| 948 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 949 | &mut self, | ||
| 950 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 951 | len: usize, | ||
| 952 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 953 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 954 | let before = decoder.bytes_read(); | ||
| 955 | while decoder.bytes_read() - before < len { | ||
| 956 | let tag = decoder.decode_tag()?; | ||
| 957 | match tag.field_num() { | ||
| 958 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 959 | 1u32 => { | ||
| 960 | let mut_ref = &mut self.r#mode; | ||
| 961 | { | ||
| 962 | let val = decoder.decode_int32()?; | ||
| 963 | let val_ref = &val; | ||
| 964 | if *val_ref != 0 { | ||
| 965 | *mut_ref = val as _; | ||
| 966 | } | ||
| 967 | }; | ||
| 968 | } | ||
| 969 | _ => { | ||
| 970 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 971 | } | ||
| 972 | } | ||
| 973 | } | ||
| 974 | Ok(()) | ||
| 975 | } | ||
| 976 | } | ||
| 977 | impl ::micropb::MessageEncode for CtrlMsg_Req_SetMode { | ||
| 978 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 979 | let mut max_size = 0; | ||
| 980 | if let ::core::option::Option::Some(size) = | ||
| 981 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 982 | { | ||
| 983 | max_size += size; | ||
| 984 | } else { | ||
| 985 | break 'msg (::core::option::Option::<usize>::None); | ||
| 986 | }; | ||
| 987 | ::core::option::Option::Some(max_size) | ||
| 988 | }; | ||
| 989 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 990 | &self, | ||
| 991 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 992 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 993 | use ::micropb::{FieldEncode, PbMap}; | ||
| 994 | { | ||
| 995 | let val_ref = &self.r#mode; | ||
| 996 | if *val_ref != 0 { | ||
| 997 | encoder.encode_varint32(8u32)?; | ||
| 998 | encoder.encode_int32(*val_ref as _)?; | ||
| 999 | } | ||
| 1000 | } | ||
| 1001 | Ok(()) | ||
| 1002 | } | ||
| 1003 | fn compute_size(&self) -> usize { | ||
| 1004 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1005 | let mut size = 0; | ||
| 1006 | { | ||
| 1007 | let val_ref = &self.r#mode; | ||
| 1008 | if *val_ref != 0 { | ||
| 1009 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1010 | } | ||
| 1011 | } | ||
| 1012 | size | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 76 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1016 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 77 | pub(crate) struct CtrlMsgReqGetStatus {} | 1017 | pub struct CtrlMsg_Resp_SetMode { |
| 78 | 1018 | pub r#resp: i32, | |
| 79 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1019 | } |
| 1020 | impl CtrlMsg_Resp_SetMode { | ||
| 1021 | ///Return a reference to `resp` | ||
| 1022 | #[inline] | ||
| 1023 | pub fn r#resp(&self) -> &i32 { | ||
| 1024 | &self.r#resp | ||
| 1025 | } | ||
| 1026 | ///Return a mutable reference to `resp` | ||
| 1027 | #[inline] | ||
| 1028 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 1029 | &mut self.r#resp | ||
| 1030 | } | ||
| 1031 | ///Set the value of `resp` | ||
| 1032 | #[inline] | ||
| 1033 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 1034 | self.r#resp = value.into(); | ||
| 1035 | self | ||
| 1036 | } | ||
| 1037 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 1038 | #[inline] | ||
| 1039 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 1040 | self.r#resp = value.into(); | ||
| 1041 | self | ||
| 1042 | } | ||
| 1043 | } | ||
| 1044 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SetMode { | ||
| 1045 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 1046 | &mut self, | ||
| 1047 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1048 | len: usize, | ||
| 1049 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1050 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1051 | let before = decoder.bytes_read(); | ||
| 1052 | while decoder.bytes_read() - before < len { | ||
| 1053 | let tag = decoder.decode_tag()?; | ||
| 1054 | match tag.field_num() { | ||
| 1055 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1056 | 1u32 => { | ||
| 1057 | let mut_ref = &mut self.r#resp; | ||
| 1058 | { | ||
| 1059 | let val = decoder.decode_int32()?; | ||
| 1060 | let val_ref = &val; | ||
| 1061 | if *val_ref != 0 { | ||
| 1062 | *mut_ref = val as _; | ||
| 1063 | } | ||
| 1064 | }; | ||
| 1065 | } | ||
| 1066 | _ => { | ||
| 1067 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1068 | } | ||
| 1069 | } | ||
| 1070 | } | ||
| 1071 | Ok(()) | ||
| 1072 | } | ||
| 1073 | } | ||
| 1074 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SetMode { | ||
| 1075 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 1076 | let mut max_size = 0; | ||
| 1077 | if let ::core::option::Option::Some(size) = | ||
| 1078 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1079 | { | ||
| 1080 | max_size += size; | ||
| 1081 | } else { | ||
| 1082 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1083 | }; | ||
| 1084 | ::core::option::Option::Some(max_size) | ||
| 1085 | }; | ||
| 1086 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1087 | &self, | ||
| 1088 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1089 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1090 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1091 | { | ||
| 1092 | let val_ref = &self.r#resp; | ||
| 1093 | if *val_ref != 0 { | ||
| 1094 | encoder.encode_varint32(8u32)?; | ||
| 1095 | encoder.encode_int32(*val_ref as _)?; | ||
| 1096 | } | ||
| 1097 | } | ||
| 1098 | Ok(()) | ||
| 1099 | } | ||
| 1100 | fn compute_size(&self) -> usize { | ||
| 1101 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1102 | let mut size = 0; | ||
| 1103 | { | ||
| 1104 | let val_ref = &self.r#resp; | ||
| 1105 | if *val_ref != 0 { | ||
| 1106 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1107 | } | ||
| 1108 | } | ||
| 1109 | size | ||
| 1110 | } | ||
| 1111 | } | ||
| 1112 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 80 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1113 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 81 | pub(crate) struct CtrlMsgRespGetStatus { | 1114 | pub struct CtrlMsg_Req_GetStatus {} |
| 82 | #[noproto(tag = "1")] | 1115 | impl CtrlMsg_Req_GetStatus {} |
| 83 | pub resp: u32, | 1116 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetStatus { |
| 1117 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 1118 | &mut self, | ||
| 1119 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1120 | len: usize, | ||
| 1121 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1122 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1123 | let before = decoder.bytes_read(); | ||
| 1124 | while decoder.bytes_read() - before < len { | ||
| 1125 | let tag = decoder.decode_tag()?; | ||
| 1126 | match tag.field_num() { | ||
| 1127 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1128 | _ => { | ||
| 1129 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1130 | } | ||
| 1131 | } | ||
| 1132 | } | ||
| 1133 | Ok(()) | ||
| 1134 | } | ||
| 84 | } | 1135 | } |
| 85 | 1136 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetStatus { | |
| 86 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1137 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 1138 | let mut max_size = 0; | ||
| 1139 | ::core::option::Option::Some(max_size) | ||
| 1140 | }; | ||
| 1141 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1142 | &self, | ||
| 1143 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1144 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1145 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1146 | Ok(()) | ||
| 1147 | } | ||
| 1148 | fn compute_size(&self) -> usize { | ||
| 1149 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1150 | let mut size = 0; | ||
| 1151 | size | ||
| 1152 | } | ||
| 1153 | } | ||
| 1154 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 87 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1155 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 88 | pub(crate) struct CtrlMsgReqSetMacAddress { | 1156 | pub struct CtrlMsg_Resp_GetStatus { |
| 89 | #[noproto(tag = "1")] | 1157 | pub r#resp: i32, |
| 90 | pub mac: String<32>, | ||
| 91 | #[noproto(tag = "2")] | ||
| 92 | pub mode: u32, | ||
| 93 | } | 1158 | } |
| 94 | 1159 | impl CtrlMsg_Resp_GetStatus { | |
| 95 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1160 | ///Return a reference to `resp` |
| 1161 | #[inline] | ||
| 1162 | pub fn r#resp(&self) -> &i32 { | ||
| 1163 | &self.r#resp | ||
| 1164 | } | ||
| 1165 | ///Return a mutable reference to `resp` | ||
| 1166 | #[inline] | ||
| 1167 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 1168 | &mut self.r#resp | ||
| 1169 | } | ||
| 1170 | ///Set the value of `resp` | ||
| 1171 | #[inline] | ||
| 1172 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 1173 | self.r#resp = value.into(); | ||
| 1174 | self | ||
| 1175 | } | ||
| 1176 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 1177 | #[inline] | ||
| 1178 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 1179 | self.r#resp = value.into(); | ||
| 1180 | self | ||
| 1181 | } | ||
| 1182 | } | ||
| 1183 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetStatus { | ||
| 1184 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 1185 | &mut self, | ||
| 1186 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1187 | len: usize, | ||
| 1188 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1189 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1190 | let before = decoder.bytes_read(); | ||
| 1191 | while decoder.bytes_read() - before < len { | ||
| 1192 | let tag = decoder.decode_tag()?; | ||
| 1193 | match tag.field_num() { | ||
| 1194 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1195 | 1u32 => { | ||
| 1196 | let mut_ref = &mut self.r#resp; | ||
| 1197 | { | ||
| 1198 | let val = decoder.decode_int32()?; | ||
| 1199 | let val_ref = &val; | ||
| 1200 | if *val_ref != 0 { | ||
| 1201 | *mut_ref = val as _; | ||
| 1202 | } | ||
| 1203 | }; | ||
| 1204 | } | ||
| 1205 | _ => { | ||
| 1206 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1207 | } | ||
| 1208 | } | ||
| 1209 | } | ||
| 1210 | Ok(()) | ||
| 1211 | } | ||
| 1212 | } | ||
| 1213 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetStatus { | ||
| 1214 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 1215 | let mut max_size = 0; | ||
| 1216 | if let ::core::option::Option::Some(size) = | ||
| 1217 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1218 | { | ||
| 1219 | max_size += size; | ||
| 1220 | } else { | ||
| 1221 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1222 | }; | ||
| 1223 | ::core::option::Option::Some(max_size) | ||
| 1224 | }; | ||
| 1225 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1226 | &self, | ||
| 1227 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1228 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1229 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1230 | { | ||
| 1231 | let val_ref = &self.r#resp; | ||
| 1232 | if *val_ref != 0 { | ||
| 1233 | encoder.encode_varint32(8u32)?; | ||
| 1234 | encoder.encode_int32(*val_ref as _)?; | ||
| 1235 | } | ||
| 1236 | } | ||
| 1237 | Ok(()) | ||
| 1238 | } | ||
| 1239 | fn compute_size(&self) -> usize { | ||
| 1240 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1241 | let mut size = 0; | ||
| 1242 | { | ||
| 1243 | let val_ref = &self.r#resp; | ||
| 1244 | if *val_ref != 0 { | ||
| 1245 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1246 | } | ||
| 1247 | } | ||
| 1248 | size | ||
| 1249 | } | ||
| 1250 | } | ||
| 1251 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 96 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1252 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 97 | pub(crate) struct CtrlMsgRespSetMacAddress { | 1253 | pub struct CtrlMsg_Req_SetMacAddress { |
| 98 | #[noproto(tag = "1")] | 1254 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, |
| 99 | pub resp: u32, | 1255 | pub r#mode: i32, |
| 100 | } | 1256 | } |
| 101 | 1257 | impl CtrlMsg_Req_SetMacAddress { | |
| 102 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1258 | ///Return a reference to `mac` |
| 1259 | #[inline] | ||
| 1260 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 1261 | &self.r#mac | ||
| 1262 | } | ||
| 1263 | ///Return a mutable reference to `mac` | ||
| 1264 | #[inline] | ||
| 1265 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 1266 | &mut self.r#mac | ||
| 1267 | } | ||
| 1268 | ///Set the value of `mac` | ||
| 1269 | #[inline] | ||
| 1270 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 1271 | self.r#mac = value.into(); | ||
| 1272 | self | ||
| 1273 | } | ||
| 1274 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 1275 | #[inline] | ||
| 1276 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 1277 | self.r#mac = value.into(); | ||
| 1278 | self | ||
| 1279 | } | ||
| 1280 | ///Return a reference to `mode` | ||
| 1281 | #[inline] | ||
| 1282 | pub fn r#mode(&self) -> &i32 { | ||
| 1283 | &self.r#mode | ||
| 1284 | } | ||
| 1285 | ///Return a mutable reference to `mode` | ||
| 1286 | #[inline] | ||
| 1287 | pub fn mut_mode(&mut self) -> &mut i32 { | ||
| 1288 | &mut self.r#mode | ||
| 1289 | } | ||
| 1290 | ///Set the value of `mode` | ||
| 1291 | #[inline] | ||
| 1292 | pub fn set_mode(&mut self, value: i32) -> &mut Self { | ||
| 1293 | self.r#mode = value.into(); | ||
| 1294 | self | ||
| 1295 | } | ||
| 1296 | ///Builder method that sets the value of `mode`. Useful for initializing the message. | ||
| 1297 | #[inline] | ||
| 1298 | pub fn init_mode(mut self, value: i32) -> Self { | ||
| 1299 | self.r#mode = value.into(); | ||
| 1300 | self | ||
| 1301 | } | ||
| 1302 | } | ||
| 1303 | impl ::micropb::MessageDecode for CtrlMsg_Req_SetMacAddress { | ||
| 1304 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 1305 | &mut self, | ||
| 1306 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1307 | len: usize, | ||
| 1308 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1309 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1310 | let before = decoder.bytes_read(); | ||
| 1311 | while decoder.bytes_read() - before < len { | ||
| 1312 | let tag = decoder.decode_tag()?; | ||
| 1313 | match tag.field_num() { | ||
| 1314 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1315 | 1u32 => { | ||
| 1316 | let mut_ref = &mut self.r#mac; | ||
| 1317 | { | ||
| 1318 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 1319 | }; | ||
| 1320 | } | ||
| 1321 | 2u32 => { | ||
| 1322 | let mut_ref = &mut self.r#mode; | ||
| 1323 | { | ||
| 1324 | let val = decoder.decode_int32()?; | ||
| 1325 | let val_ref = &val; | ||
| 1326 | if *val_ref != 0 { | ||
| 1327 | *mut_ref = val as _; | ||
| 1328 | } | ||
| 1329 | }; | ||
| 1330 | } | ||
| 1331 | _ => { | ||
| 1332 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1333 | } | ||
| 1334 | } | ||
| 1335 | } | ||
| 1336 | Ok(()) | ||
| 1337 | } | ||
| 1338 | } | ||
| 1339 | impl ::micropb::MessageEncode for CtrlMsg_Req_SetMacAddress { | ||
| 1340 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 1341 | let mut max_size = 0; | ||
| 1342 | if let ::core::option::Option::Some(size) = | ||
| 1343 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 1344 | { | ||
| 1345 | max_size += size; | ||
| 1346 | } else { | ||
| 1347 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1348 | }; | ||
| 1349 | if let ::core::option::Option::Some(size) = | ||
| 1350 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1351 | { | ||
| 1352 | max_size += size; | ||
| 1353 | } else { | ||
| 1354 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1355 | }; | ||
| 1356 | ::core::option::Option::Some(max_size) | ||
| 1357 | }; | ||
| 1358 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1359 | &self, | ||
| 1360 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1361 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1362 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1363 | { | ||
| 1364 | let val_ref = &self.r#mac; | ||
| 1365 | if !val_ref.is_empty() { | ||
| 1366 | encoder.encode_varint32(10u32)?; | ||
| 1367 | encoder.encode_bytes(val_ref)?; | ||
| 1368 | } | ||
| 1369 | } | ||
| 1370 | { | ||
| 1371 | let val_ref = &self.r#mode; | ||
| 1372 | if *val_ref != 0 { | ||
| 1373 | encoder.encode_varint32(16u32)?; | ||
| 1374 | encoder.encode_int32(*val_ref as _)?; | ||
| 1375 | } | ||
| 1376 | } | ||
| 1377 | Ok(()) | ||
| 1378 | } | ||
| 1379 | fn compute_size(&self) -> usize { | ||
| 1380 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1381 | let mut size = 0; | ||
| 1382 | { | ||
| 1383 | let val_ref = &self.r#mac; | ||
| 1384 | if !val_ref.is_empty() { | ||
| 1385 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 1386 | } | ||
| 1387 | } | ||
| 1388 | { | ||
| 1389 | let val_ref = &self.r#mode; | ||
| 1390 | if *val_ref != 0 { | ||
| 1391 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1392 | } | ||
| 1393 | } | ||
| 1394 | size | ||
| 1395 | } | ||
| 1396 | } | ||
| 1397 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 103 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1398 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 104 | pub(crate) struct CtrlMsgReqGetApConfig {} | 1399 | pub struct CtrlMsg_Resp_SetMacAddress { |
| 105 | 1400 | pub r#resp: i32, | |
| 106 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||
| 107 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 108 | pub(crate) struct CtrlMsgRespGetApConfig { | ||
| 109 | #[noproto(tag = "1")] | ||
| 110 | pub ssid: String<32>, | ||
| 111 | #[noproto(tag = "2")] | ||
| 112 | pub bssid: String<32>, | ||
| 113 | #[noproto(tag = "3")] | ||
| 114 | pub rssi: u32, | ||
| 115 | #[noproto(tag = "4")] | ||
| 116 | pub chnl: u32, | ||
| 117 | #[noproto(tag = "5")] | ||
| 118 | pub sec_prot: CtrlWifiSecProt, | ||
| 119 | #[noproto(tag = "6")] | ||
| 120 | pub resp: u32, | ||
| 121 | } | 1401 | } |
| 122 | 1402 | impl CtrlMsg_Resp_SetMacAddress { | |
| 123 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1403 | ///Return a reference to `resp` |
| 124 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1404 | #[inline] |
| 125 | pub(crate) struct CtrlMsgReqConnectAp { | 1405 | pub fn r#resp(&self) -> &i32 { |
| 126 | #[noproto(tag = "1")] | 1406 | &self.r#resp |
| 127 | pub ssid: String<32>, | 1407 | } |
| 128 | #[noproto(tag = "2")] | 1408 | ///Return a mutable reference to `resp` |
| 129 | pub pwd: String<32>, | 1409 | #[inline] |
| 130 | #[noproto(tag = "3")] | 1410 | pub fn mut_resp(&mut self) -> &mut i32 { |
| 131 | pub bssid: String<32>, | 1411 | &mut self.r#resp |
| 132 | #[noproto(tag = "4")] | 1412 | } |
| 133 | pub is_wpa3_supported: bool, | 1413 | ///Set the value of `resp` |
| 134 | #[noproto(tag = "5")] | 1414 | #[inline] |
| 135 | pub listen_interval: u32, | 1415 | pub fn set_resp(&mut self, value: i32) -> &mut Self { |
| 1416 | self.r#resp = value.into(); | ||
| 1417 | self | ||
| 1418 | } | ||
| 1419 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 1420 | #[inline] | ||
| 1421 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 1422 | self.r#resp = value.into(); | ||
| 1423 | self | ||
| 1424 | } | ||
| 136 | } | 1425 | } |
| 137 | 1426 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SetMacAddress { | |
| 138 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1427 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 1428 | &mut self, | ||
| 1429 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1430 | len: usize, | ||
| 1431 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1432 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1433 | let before = decoder.bytes_read(); | ||
| 1434 | while decoder.bytes_read() - before < len { | ||
| 1435 | let tag = decoder.decode_tag()?; | ||
| 1436 | match tag.field_num() { | ||
| 1437 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1438 | 1u32 => { | ||
| 1439 | let mut_ref = &mut self.r#resp; | ||
| 1440 | { | ||
| 1441 | let val = decoder.decode_int32()?; | ||
| 1442 | let val_ref = &val; | ||
| 1443 | if *val_ref != 0 { | ||
| 1444 | *mut_ref = val as _; | ||
| 1445 | } | ||
| 1446 | }; | ||
| 1447 | } | ||
| 1448 | _ => { | ||
| 1449 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1450 | } | ||
| 1451 | } | ||
| 1452 | } | ||
| 1453 | Ok(()) | ||
| 1454 | } | ||
| 1455 | } | ||
| 1456 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SetMacAddress { | ||
| 1457 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 1458 | let mut max_size = 0; | ||
| 1459 | if let ::core::option::Option::Some(size) = | ||
| 1460 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1461 | { | ||
| 1462 | max_size += size; | ||
| 1463 | } else { | ||
| 1464 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1465 | }; | ||
| 1466 | ::core::option::Option::Some(max_size) | ||
| 1467 | }; | ||
| 1468 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1469 | &self, | ||
| 1470 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1471 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1472 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1473 | { | ||
| 1474 | let val_ref = &self.r#resp; | ||
| 1475 | if *val_ref != 0 { | ||
| 1476 | encoder.encode_varint32(8u32)?; | ||
| 1477 | encoder.encode_int32(*val_ref as _)?; | ||
| 1478 | } | ||
| 1479 | } | ||
| 1480 | Ok(()) | ||
| 1481 | } | ||
| 1482 | fn compute_size(&self) -> usize { | ||
| 1483 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1484 | let mut size = 0; | ||
| 1485 | { | ||
| 1486 | let val_ref = &self.r#resp; | ||
| 1487 | if *val_ref != 0 { | ||
| 1488 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1489 | } | ||
| 1490 | } | ||
| 1491 | size | ||
| 1492 | } | ||
| 1493 | } | ||
| 1494 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 139 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1495 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 140 | pub(crate) struct CtrlMsgRespConnectAp { | 1496 | pub struct CtrlMsg_Req_GetAPConfig {} |
| 141 | #[noproto(tag = "1")] | 1497 | impl CtrlMsg_Req_GetAPConfig {} |
| 142 | pub resp: u32, | 1498 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetAPConfig { |
| 143 | #[noproto(tag = "2")] | 1499 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 144 | pub mac: String<32>, | 1500 | &mut self, |
| 1501 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1502 | len: usize, | ||
| 1503 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1504 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1505 | let before = decoder.bytes_read(); | ||
| 1506 | while decoder.bytes_read() - before < len { | ||
| 1507 | let tag = decoder.decode_tag()?; | ||
| 1508 | match tag.field_num() { | ||
| 1509 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1510 | _ => { | ||
| 1511 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1512 | } | ||
| 1513 | } | ||
| 1514 | } | ||
| 1515 | Ok(()) | ||
| 1516 | } | ||
| 145 | } | 1517 | } |
| 146 | 1518 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetAPConfig { | |
| 147 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1519 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 1520 | let mut max_size = 0; | ||
| 1521 | ::core::option::Option::Some(max_size) | ||
| 1522 | }; | ||
| 1523 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1524 | &self, | ||
| 1525 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1526 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1527 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1528 | Ok(()) | ||
| 1529 | } | ||
| 1530 | fn compute_size(&self) -> usize { | ||
| 1531 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1532 | let mut size = 0; | ||
| 1533 | size | ||
| 1534 | } | ||
| 1535 | } | ||
| 1536 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 148 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1537 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 149 | pub(crate) struct CtrlMsgReqGetSoftApConfig {} | 1538 | pub struct CtrlMsg_Resp_GetAPConfig { |
| 150 | 1539 | pub r#ssid: ::micropb::heapless::Vec<u8, 32>, | |
| 151 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1540 | pub r#bssid: ::micropb::heapless::Vec<u8, 32>, |
| 152 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1541 | pub r#rssi: i32, |
| 153 | pub(crate) struct CtrlMsgRespGetSoftApConfig { | 1542 | pub r#chnl: i32, |
| 154 | #[noproto(tag = "1")] | 1543 | pub r#sec_prot: Ctrl_WifiSecProt, |
| 155 | pub ssid: String<32>, | 1544 | pub r#resp: i32, |
| 156 | #[noproto(tag = "2")] | 1545 | pub r#band_mode: i32, |
| 157 | pub pwd: String<32>, | ||
| 158 | #[noproto(tag = "3")] | ||
| 159 | pub chnl: u32, | ||
| 160 | #[noproto(tag = "4")] | ||
| 161 | pub sec_prot: CtrlWifiSecProt, | ||
| 162 | #[noproto(tag = "5")] | ||
| 163 | pub max_conn: u32, | ||
| 164 | #[noproto(tag = "6")] | ||
| 165 | pub ssid_hidden: bool, | ||
| 166 | #[noproto(tag = "7")] | ||
| 167 | pub bw: u32, | ||
| 168 | #[noproto(tag = "8")] | ||
| 169 | pub resp: u32, | ||
| 170 | } | 1546 | } |
| 171 | 1547 | impl CtrlMsg_Resp_GetAPConfig { | |
| 172 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1548 | ///Return a reference to `ssid` |
| 173 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1549 | #[inline] |
| 174 | pub(crate) struct CtrlMsgReqStartSoftAp { | 1550 | pub fn r#ssid(&self) -> &::micropb::heapless::Vec<u8, 32> { |
| 175 | #[noproto(tag = "1")] | 1551 | &self.r#ssid |
| 176 | pub ssid: String<32>, | 1552 | } |
| 177 | #[noproto(tag = "2")] | 1553 | ///Return a mutable reference to `ssid` |
| 178 | pub pwd: String<32>, | 1554 | #[inline] |
| 179 | #[noproto(tag = "3")] | 1555 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { |
| 180 | pub chnl: u32, | 1556 | &mut self.r#ssid |
| 181 | #[noproto(tag = "4")] | 1557 | } |
| 182 | pub sec_prot: CtrlWifiSecProt, | 1558 | ///Set the value of `ssid` |
| 183 | #[noproto(tag = "5")] | 1559 | #[inline] |
| 184 | pub max_conn: u32, | 1560 | pub fn set_ssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { |
| 185 | #[noproto(tag = "6")] | 1561 | self.r#ssid = value.into(); |
| 186 | pub ssid_hidden: bool, | 1562 | self |
| 187 | #[noproto(tag = "7")] | 1563 | } |
| 188 | pub bw: u32, | 1564 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. |
| 1565 | #[inline] | ||
| 1566 | pub fn init_ssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 1567 | self.r#ssid = value.into(); | ||
| 1568 | self | ||
| 1569 | } | ||
| 1570 | ///Return a reference to `bssid` | ||
| 1571 | #[inline] | ||
| 1572 | pub fn r#bssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 1573 | &self.r#bssid | ||
| 1574 | } | ||
| 1575 | ///Return a mutable reference to `bssid` | ||
| 1576 | #[inline] | ||
| 1577 | pub fn mut_bssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 1578 | &mut self.r#bssid | ||
| 1579 | } | ||
| 1580 | ///Set the value of `bssid` | ||
| 1581 | #[inline] | ||
| 1582 | pub fn set_bssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 1583 | self.r#bssid = value.into(); | ||
| 1584 | self | ||
| 1585 | } | ||
| 1586 | ///Builder method that sets the value of `bssid`. Useful for initializing the message. | ||
| 1587 | #[inline] | ||
| 1588 | pub fn init_bssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 1589 | self.r#bssid = value.into(); | ||
| 1590 | self | ||
| 1591 | } | ||
| 1592 | ///Return a reference to `rssi` | ||
| 1593 | #[inline] | ||
| 1594 | pub fn r#rssi(&self) -> &i32 { | ||
| 1595 | &self.r#rssi | ||
| 1596 | } | ||
| 1597 | ///Return a mutable reference to `rssi` | ||
| 1598 | #[inline] | ||
| 1599 | pub fn mut_rssi(&mut self) -> &mut i32 { | ||
| 1600 | &mut self.r#rssi | ||
| 1601 | } | ||
| 1602 | ///Set the value of `rssi` | ||
| 1603 | #[inline] | ||
| 1604 | pub fn set_rssi(&mut self, value: i32) -> &mut Self { | ||
| 1605 | self.r#rssi = value.into(); | ||
| 1606 | self | ||
| 1607 | } | ||
| 1608 | ///Builder method that sets the value of `rssi`. Useful for initializing the message. | ||
| 1609 | #[inline] | ||
| 1610 | pub fn init_rssi(mut self, value: i32) -> Self { | ||
| 1611 | self.r#rssi = value.into(); | ||
| 1612 | self | ||
| 1613 | } | ||
| 1614 | ///Return a reference to `chnl` | ||
| 1615 | #[inline] | ||
| 1616 | pub fn r#chnl(&self) -> &i32 { | ||
| 1617 | &self.r#chnl | ||
| 1618 | } | ||
| 1619 | ///Return a mutable reference to `chnl` | ||
| 1620 | #[inline] | ||
| 1621 | pub fn mut_chnl(&mut self) -> &mut i32 { | ||
| 1622 | &mut self.r#chnl | ||
| 1623 | } | ||
| 1624 | ///Set the value of `chnl` | ||
| 1625 | #[inline] | ||
| 1626 | pub fn set_chnl(&mut self, value: i32) -> &mut Self { | ||
| 1627 | self.r#chnl = value.into(); | ||
| 1628 | self | ||
| 1629 | } | ||
| 1630 | ///Builder method that sets the value of `chnl`. Useful for initializing the message. | ||
| 1631 | #[inline] | ||
| 1632 | pub fn init_chnl(mut self, value: i32) -> Self { | ||
| 1633 | self.r#chnl = value.into(); | ||
| 1634 | self | ||
| 1635 | } | ||
| 1636 | ///Return a reference to `sec_prot` | ||
| 1637 | #[inline] | ||
| 1638 | pub fn r#sec_prot(&self) -> &Ctrl_WifiSecProt { | ||
| 1639 | &self.r#sec_prot | ||
| 1640 | } | ||
| 1641 | ///Return a mutable reference to `sec_prot` | ||
| 1642 | #[inline] | ||
| 1643 | pub fn mut_sec_prot(&mut self) -> &mut Ctrl_WifiSecProt { | ||
| 1644 | &mut self.r#sec_prot | ||
| 1645 | } | ||
| 1646 | ///Set the value of `sec_prot` | ||
| 1647 | #[inline] | ||
| 1648 | pub fn set_sec_prot(&mut self, value: Ctrl_WifiSecProt) -> &mut Self { | ||
| 1649 | self.r#sec_prot = value.into(); | ||
| 1650 | self | ||
| 1651 | } | ||
| 1652 | ///Builder method that sets the value of `sec_prot`. Useful for initializing the message. | ||
| 1653 | #[inline] | ||
| 1654 | pub fn init_sec_prot(mut self, value: Ctrl_WifiSecProt) -> Self { | ||
| 1655 | self.r#sec_prot = value.into(); | ||
| 1656 | self | ||
| 1657 | } | ||
| 1658 | ///Return a reference to `resp` | ||
| 1659 | #[inline] | ||
| 1660 | pub fn r#resp(&self) -> &i32 { | ||
| 1661 | &self.r#resp | ||
| 1662 | } | ||
| 1663 | ///Return a mutable reference to `resp` | ||
| 1664 | #[inline] | ||
| 1665 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 1666 | &mut self.r#resp | ||
| 1667 | } | ||
| 1668 | ///Set the value of `resp` | ||
| 1669 | #[inline] | ||
| 1670 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 1671 | self.r#resp = value.into(); | ||
| 1672 | self | ||
| 1673 | } | ||
| 1674 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 1675 | #[inline] | ||
| 1676 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 1677 | self.r#resp = value.into(); | ||
| 1678 | self | ||
| 1679 | } | ||
| 1680 | ///Return a reference to `band_mode` | ||
| 1681 | #[inline] | ||
| 1682 | pub fn r#band_mode(&self) -> &i32 { | ||
| 1683 | &self.r#band_mode | ||
| 1684 | } | ||
| 1685 | ///Return a mutable reference to `band_mode` | ||
| 1686 | #[inline] | ||
| 1687 | pub fn mut_band_mode(&mut self) -> &mut i32 { | ||
| 1688 | &mut self.r#band_mode | ||
| 1689 | } | ||
| 1690 | ///Set the value of `band_mode` | ||
| 1691 | #[inline] | ||
| 1692 | pub fn set_band_mode(&mut self, value: i32) -> &mut Self { | ||
| 1693 | self.r#band_mode = value.into(); | ||
| 1694 | self | ||
| 1695 | } | ||
| 1696 | ///Builder method that sets the value of `band_mode`. Useful for initializing the message. | ||
| 1697 | #[inline] | ||
| 1698 | pub fn init_band_mode(mut self, value: i32) -> Self { | ||
| 1699 | self.r#band_mode = value.into(); | ||
| 1700 | self | ||
| 1701 | } | ||
| 189 | } | 1702 | } |
| 190 | 1703 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetAPConfig { | |
| 191 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1704 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 1705 | &mut self, | ||
| 1706 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 1707 | len: usize, | ||
| 1708 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 1709 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 1710 | let before = decoder.bytes_read(); | ||
| 1711 | while decoder.bytes_read() - before < len { | ||
| 1712 | let tag = decoder.decode_tag()?; | ||
| 1713 | match tag.field_num() { | ||
| 1714 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 1715 | 1u32 => { | ||
| 1716 | let mut_ref = &mut self.r#ssid; | ||
| 1717 | { | ||
| 1718 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 1719 | }; | ||
| 1720 | } | ||
| 1721 | 2u32 => { | ||
| 1722 | let mut_ref = &mut self.r#bssid; | ||
| 1723 | { | ||
| 1724 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 1725 | }; | ||
| 1726 | } | ||
| 1727 | 3u32 => { | ||
| 1728 | let mut_ref = &mut self.r#rssi; | ||
| 1729 | { | ||
| 1730 | let val = decoder.decode_int32()?; | ||
| 1731 | let val_ref = &val; | ||
| 1732 | if *val_ref != 0 { | ||
| 1733 | *mut_ref = val as _; | ||
| 1734 | } | ||
| 1735 | }; | ||
| 1736 | } | ||
| 1737 | 4u32 => { | ||
| 1738 | let mut_ref = &mut self.r#chnl; | ||
| 1739 | { | ||
| 1740 | let val = decoder.decode_int32()?; | ||
| 1741 | let val_ref = &val; | ||
| 1742 | if *val_ref != 0 { | ||
| 1743 | *mut_ref = val as _; | ||
| 1744 | } | ||
| 1745 | }; | ||
| 1746 | } | ||
| 1747 | 5u32 => { | ||
| 1748 | let mut_ref = &mut self.r#sec_prot; | ||
| 1749 | { | ||
| 1750 | let val = decoder.decode_int32().map(|n| Ctrl_WifiSecProt(n as _))?; | ||
| 1751 | let val_ref = &val; | ||
| 1752 | if val_ref.0 != 0 { | ||
| 1753 | *mut_ref = val as _; | ||
| 1754 | } | ||
| 1755 | }; | ||
| 1756 | } | ||
| 1757 | 6u32 => { | ||
| 1758 | let mut_ref = &mut self.r#resp; | ||
| 1759 | { | ||
| 1760 | let val = decoder.decode_int32()?; | ||
| 1761 | let val_ref = &val; | ||
| 1762 | if *val_ref != 0 { | ||
| 1763 | *mut_ref = val as _; | ||
| 1764 | } | ||
| 1765 | }; | ||
| 1766 | } | ||
| 1767 | 7u32 => { | ||
| 1768 | let mut_ref = &mut self.r#band_mode; | ||
| 1769 | { | ||
| 1770 | let val = decoder.decode_int32()?; | ||
| 1771 | let val_ref = &val; | ||
| 1772 | if *val_ref != 0 { | ||
| 1773 | *mut_ref = val as _; | ||
| 1774 | } | ||
| 1775 | }; | ||
| 1776 | } | ||
| 1777 | _ => { | ||
| 1778 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 1779 | } | ||
| 1780 | } | ||
| 1781 | } | ||
| 1782 | Ok(()) | ||
| 1783 | } | ||
| 1784 | } | ||
| 1785 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetAPConfig { | ||
| 1786 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 1787 | let mut max_size = 0; | ||
| 1788 | if let ::core::option::Option::Some(size) = | ||
| 1789 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 1790 | { | ||
| 1791 | max_size += size; | ||
| 1792 | } else { | ||
| 1793 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1794 | }; | ||
| 1795 | if let ::core::option::Option::Some(size) = | ||
| 1796 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 1797 | { | ||
| 1798 | max_size += size; | ||
| 1799 | } else { | ||
| 1800 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1801 | }; | ||
| 1802 | if let ::core::option::Option::Some(size) = | ||
| 1803 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1804 | { | ||
| 1805 | max_size += size; | ||
| 1806 | } else { | ||
| 1807 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1808 | }; | ||
| 1809 | if let ::core::option::Option::Some(size) = | ||
| 1810 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1811 | { | ||
| 1812 | max_size += size; | ||
| 1813 | } else { | ||
| 1814 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1815 | }; | ||
| 1816 | if let ::core::option::Option::Some(size) = | ||
| 1817 | ::micropb::const_map!(::core::option::Option::Some(Ctrl_WifiSecProt::_MAX_SIZE), |size| size | ||
| 1818 | + 1usize) | ||
| 1819 | { | ||
| 1820 | max_size += size; | ||
| 1821 | } else { | ||
| 1822 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1823 | }; | ||
| 1824 | if let ::core::option::Option::Some(size) = | ||
| 1825 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1826 | { | ||
| 1827 | max_size += size; | ||
| 1828 | } else { | ||
| 1829 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1830 | }; | ||
| 1831 | if let ::core::option::Option::Some(size) = | ||
| 1832 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 1833 | { | ||
| 1834 | max_size += size; | ||
| 1835 | } else { | ||
| 1836 | break 'msg (::core::option::Option::<usize>::None); | ||
| 1837 | }; | ||
| 1838 | ::core::option::Option::Some(max_size) | ||
| 1839 | }; | ||
| 1840 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 1841 | &self, | ||
| 1842 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 1843 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 1844 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1845 | { | ||
| 1846 | let val_ref = &self.r#ssid; | ||
| 1847 | if !val_ref.is_empty() { | ||
| 1848 | encoder.encode_varint32(10u32)?; | ||
| 1849 | encoder.encode_bytes(val_ref)?; | ||
| 1850 | } | ||
| 1851 | } | ||
| 1852 | { | ||
| 1853 | let val_ref = &self.r#bssid; | ||
| 1854 | if !val_ref.is_empty() { | ||
| 1855 | encoder.encode_varint32(18u32)?; | ||
| 1856 | encoder.encode_bytes(val_ref)?; | ||
| 1857 | } | ||
| 1858 | } | ||
| 1859 | { | ||
| 1860 | let val_ref = &self.r#rssi; | ||
| 1861 | if *val_ref != 0 { | ||
| 1862 | encoder.encode_varint32(24u32)?; | ||
| 1863 | encoder.encode_int32(*val_ref as _)?; | ||
| 1864 | } | ||
| 1865 | } | ||
| 1866 | { | ||
| 1867 | let val_ref = &self.r#chnl; | ||
| 1868 | if *val_ref != 0 { | ||
| 1869 | encoder.encode_varint32(32u32)?; | ||
| 1870 | encoder.encode_int32(*val_ref as _)?; | ||
| 1871 | } | ||
| 1872 | } | ||
| 1873 | { | ||
| 1874 | let val_ref = &self.r#sec_prot; | ||
| 1875 | if val_ref.0 != 0 { | ||
| 1876 | encoder.encode_varint32(40u32)?; | ||
| 1877 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 1878 | } | ||
| 1879 | } | ||
| 1880 | { | ||
| 1881 | let val_ref = &self.r#resp; | ||
| 1882 | if *val_ref != 0 { | ||
| 1883 | encoder.encode_varint32(48u32)?; | ||
| 1884 | encoder.encode_int32(*val_ref as _)?; | ||
| 1885 | } | ||
| 1886 | } | ||
| 1887 | { | ||
| 1888 | let val_ref = &self.r#band_mode; | ||
| 1889 | if *val_ref != 0 { | ||
| 1890 | encoder.encode_varint32(56u32)?; | ||
| 1891 | encoder.encode_int32(*val_ref as _)?; | ||
| 1892 | } | ||
| 1893 | } | ||
| 1894 | Ok(()) | ||
| 1895 | } | ||
| 1896 | fn compute_size(&self) -> usize { | ||
| 1897 | use ::micropb::{FieldEncode, PbMap}; | ||
| 1898 | let mut size = 0; | ||
| 1899 | { | ||
| 1900 | let val_ref = &self.r#ssid; | ||
| 1901 | if !val_ref.is_empty() { | ||
| 1902 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 1903 | } | ||
| 1904 | } | ||
| 1905 | { | ||
| 1906 | let val_ref = &self.r#bssid; | ||
| 1907 | if !val_ref.is_empty() { | ||
| 1908 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 1909 | } | ||
| 1910 | } | ||
| 1911 | { | ||
| 1912 | let val_ref = &self.r#rssi; | ||
| 1913 | if *val_ref != 0 { | ||
| 1914 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1915 | } | ||
| 1916 | } | ||
| 1917 | { | ||
| 1918 | let val_ref = &self.r#chnl; | ||
| 1919 | if *val_ref != 0 { | ||
| 1920 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1921 | } | ||
| 1922 | } | ||
| 1923 | { | ||
| 1924 | let val_ref = &self.r#sec_prot; | ||
| 1925 | if val_ref.0 != 0 { | ||
| 1926 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 1927 | } | ||
| 1928 | } | ||
| 1929 | { | ||
| 1930 | let val_ref = &self.r#resp; | ||
| 1931 | if *val_ref != 0 { | ||
| 1932 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1933 | } | ||
| 1934 | } | ||
| 1935 | { | ||
| 1936 | let val_ref = &self.r#band_mode; | ||
| 1937 | if *val_ref != 0 { | ||
| 1938 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 1939 | } | ||
| 1940 | } | ||
| 1941 | size | ||
| 1942 | } | ||
| 1943 | } | ||
| 1944 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 192 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 1945 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 193 | pub(crate) struct CtrlMsgRespStartSoftAp { | 1946 | pub struct CtrlMsg_Req_ConnectAP { |
| 194 | #[noproto(tag = "1")] | 1947 | pub r#ssid: ::micropb::heapless::String<32>, |
| 195 | pub resp: u32, | 1948 | pub r#pwd: ::micropb::heapless::String<32>, |
| 196 | #[noproto(tag = "2")] | 1949 | pub r#bssid: ::micropb::heapless::String<32>, |
| 197 | pub mac: String<32>, | 1950 | pub r#is_wpa3_supported: bool, |
| 1951 | pub r#listen_interval: i32, | ||
| 1952 | pub r#band_mode: i32, | ||
| 198 | } | 1953 | } |
| 199 | 1954 | impl CtrlMsg_Req_ConnectAP { | |
| 200 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 1955 | ///Return a reference to `ssid` |
| 1956 | #[inline] | ||
| 1957 | pub fn r#ssid(&self) -> &::micropb::heapless::String<32> { | ||
| 1958 | &self.r#ssid | ||
| 1959 | } | ||
| 1960 | ///Return a mutable reference to `ssid` | ||
| 1961 | #[inline] | ||
| 1962 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::String<32> { | ||
| 1963 | &mut self.r#ssid | ||
| 1964 | } | ||
| 1965 | ///Set the value of `ssid` | ||
| 1966 | #[inline] | ||
| 1967 | pub fn set_ssid(&mut self, value: ::micropb::heapless::String<32>) -> &mut Self { | ||
| 1968 | self.r#ssid = value.into(); | ||
| 1969 | self | ||
| 1970 | } | ||
| 1971 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. | ||
| 1972 | #[inline] | ||
| 1973 | pub fn init_ssid(mut self, value: ::micropb::heapless::String<32>) -> Self { | ||
| 1974 | self.r#ssid = value.into(); | ||
| 1975 | self | ||
| 1976 | } | ||
| 1977 | ///Return a reference to `pwd` | ||
| 1978 | #[inline] | ||
| 1979 | pub fn r#pwd(&self) -> &::micropb::heapless::String<32> { | ||
| 1980 | &self.r#pwd | ||
| 1981 | } | ||
| 1982 | ///Return a mutable reference to `pwd` | ||
| 1983 | #[inline] | ||
| 1984 | pub fn mut_pwd(&mut self) -> &mut ::micropb::heapless::String<32> { | ||
| 1985 | &mut self.r#pwd | ||
| 1986 | } | ||
| 1987 | ///Set the value of `pwd` | ||
| 1988 | #[inline] | ||
| 1989 | pub fn set_pwd(&mut self, value: ::micropb::heapless::String<32>) -> &mut Self { | ||
| 1990 | self.r#pwd = value.into(); | ||
| 1991 | self | ||
| 1992 | } | ||
| 1993 | ///Builder method that sets the value of `pwd`. Useful for initializing the message. | ||
| 1994 | #[inline] | ||
| 1995 | pub fn init_pwd(mut self, value: ::micropb::heapless::String<32>) -> Self { | ||
| 1996 | self.r#pwd = value.into(); | ||
| 1997 | self | ||
| 1998 | } | ||
| 1999 | ///Return a reference to `bssid` | ||
| 2000 | #[inline] | ||
| 2001 | pub fn r#bssid(&self) -> &::micropb::heapless::String<32> { | ||
| 2002 | &self.r#bssid | ||
| 2003 | } | ||
| 2004 | ///Return a mutable reference to `bssid` | ||
| 2005 | #[inline] | ||
| 2006 | pub fn mut_bssid(&mut self) -> &mut ::micropb::heapless::String<32> { | ||
| 2007 | &mut self.r#bssid | ||
| 2008 | } | ||
| 2009 | ///Set the value of `bssid` | ||
| 2010 | #[inline] | ||
| 2011 | pub fn set_bssid(&mut self, value: ::micropb::heapless::String<32>) -> &mut Self { | ||
| 2012 | self.r#bssid = value.into(); | ||
| 2013 | self | ||
| 2014 | } | ||
| 2015 | ///Builder method that sets the value of `bssid`. Useful for initializing the message. | ||
| 2016 | #[inline] | ||
| 2017 | pub fn init_bssid(mut self, value: ::micropb::heapless::String<32>) -> Self { | ||
| 2018 | self.r#bssid = value.into(); | ||
| 2019 | self | ||
| 2020 | } | ||
| 2021 | ///Return a reference to `is_wpa3_supported` | ||
| 2022 | #[inline] | ||
| 2023 | pub fn r#is_wpa3_supported(&self) -> &bool { | ||
| 2024 | &self.r#is_wpa3_supported | ||
| 2025 | } | ||
| 2026 | ///Return a mutable reference to `is_wpa3_supported` | ||
| 2027 | #[inline] | ||
| 2028 | pub fn mut_is_wpa3_supported(&mut self) -> &mut bool { | ||
| 2029 | &mut self.r#is_wpa3_supported | ||
| 2030 | } | ||
| 2031 | ///Set the value of `is_wpa3_supported` | ||
| 2032 | #[inline] | ||
| 2033 | pub fn set_is_wpa3_supported(&mut self, value: bool) -> &mut Self { | ||
| 2034 | self.r#is_wpa3_supported = value.into(); | ||
| 2035 | self | ||
| 2036 | } | ||
| 2037 | ///Builder method that sets the value of `is_wpa3_supported`. Useful for initializing the message. | ||
| 2038 | #[inline] | ||
| 2039 | pub fn init_is_wpa3_supported(mut self, value: bool) -> Self { | ||
| 2040 | self.r#is_wpa3_supported = value.into(); | ||
| 2041 | self | ||
| 2042 | } | ||
| 2043 | ///Return a reference to `listen_interval` | ||
| 2044 | #[inline] | ||
| 2045 | pub fn r#listen_interval(&self) -> &i32 { | ||
| 2046 | &self.r#listen_interval | ||
| 2047 | } | ||
| 2048 | ///Return a mutable reference to `listen_interval` | ||
| 2049 | #[inline] | ||
| 2050 | pub fn mut_listen_interval(&mut self) -> &mut i32 { | ||
| 2051 | &mut self.r#listen_interval | ||
| 2052 | } | ||
| 2053 | ///Set the value of `listen_interval` | ||
| 2054 | #[inline] | ||
| 2055 | pub fn set_listen_interval(&mut self, value: i32) -> &mut Self { | ||
| 2056 | self.r#listen_interval = value.into(); | ||
| 2057 | self | ||
| 2058 | } | ||
| 2059 | ///Builder method that sets the value of `listen_interval`. Useful for initializing the message. | ||
| 2060 | #[inline] | ||
| 2061 | pub fn init_listen_interval(mut self, value: i32) -> Self { | ||
| 2062 | self.r#listen_interval = value.into(); | ||
| 2063 | self | ||
| 2064 | } | ||
| 2065 | ///Return a reference to `band_mode` | ||
| 2066 | #[inline] | ||
| 2067 | pub fn r#band_mode(&self) -> &i32 { | ||
| 2068 | &self.r#band_mode | ||
| 2069 | } | ||
| 2070 | ///Return a mutable reference to `band_mode` | ||
| 2071 | #[inline] | ||
| 2072 | pub fn mut_band_mode(&mut self) -> &mut i32 { | ||
| 2073 | &mut self.r#band_mode | ||
| 2074 | } | ||
| 2075 | ///Set the value of `band_mode` | ||
| 2076 | #[inline] | ||
| 2077 | pub fn set_band_mode(&mut self, value: i32) -> &mut Self { | ||
| 2078 | self.r#band_mode = value.into(); | ||
| 2079 | self | ||
| 2080 | } | ||
| 2081 | ///Builder method that sets the value of `band_mode`. Useful for initializing the message. | ||
| 2082 | #[inline] | ||
| 2083 | pub fn init_band_mode(mut self, value: i32) -> Self { | ||
| 2084 | self.r#band_mode = value.into(); | ||
| 2085 | self | ||
| 2086 | } | ||
| 2087 | } | ||
| 2088 | impl ::micropb::MessageDecode for CtrlMsg_Req_ConnectAP { | ||
| 2089 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 2090 | &mut self, | ||
| 2091 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 2092 | len: usize, | ||
| 2093 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 2094 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 2095 | let before = decoder.bytes_read(); | ||
| 2096 | while decoder.bytes_read() - before < len { | ||
| 2097 | let tag = decoder.decode_tag()?; | ||
| 2098 | match tag.field_num() { | ||
| 2099 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 2100 | 1u32 => { | ||
| 2101 | let mut_ref = &mut self.r#ssid; | ||
| 2102 | { | ||
| 2103 | decoder.decode_string(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 2104 | }; | ||
| 2105 | } | ||
| 2106 | 2u32 => { | ||
| 2107 | let mut_ref = &mut self.r#pwd; | ||
| 2108 | { | ||
| 2109 | decoder.decode_string(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 2110 | }; | ||
| 2111 | } | ||
| 2112 | 3u32 => { | ||
| 2113 | let mut_ref = &mut self.r#bssid; | ||
| 2114 | { | ||
| 2115 | decoder.decode_string(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 2116 | }; | ||
| 2117 | } | ||
| 2118 | 4u32 => { | ||
| 2119 | let mut_ref = &mut self.r#is_wpa3_supported; | ||
| 2120 | { | ||
| 2121 | let val = decoder.decode_bool()?; | ||
| 2122 | let val_ref = &val; | ||
| 2123 | if *val_ref { | ||
| 2124 | *mut_ref = val as _; | ||
| 2125 | } | ||
| 2126 | }; | ||
| 2127 | } | ||
| 2128 | 5u32 => { | ||
| 2129 | let mut_ref = &mut self.r#listen_interval; | ||
| 2130 | { | ||
| 2131 | let val = decoder.decode_int32()?; | ||
| 2132 | let val_ref = &val; | ||
| 2133 | if *val_ref != 0 { | ||
| 2134 | *mut_ref = val as _; | ||
| 2135 | } | ||
| 2136 | }; | ||
| 2137 | } | ||
| 2138 | 6u32 => { | ||
| 2139 | let mut_ref = &mut self.r#band_mode; | ||
| 2140 | { | ||
| 2141 | let val = decoder.decode_int32()?; | ||
| 2142 | let val_ref = &val; | ||
| 2143 | if *val_ref != 0 { | ||
| 2144 | *mut_ref = val as _; | ||
| 2145 | } | ||
| 2146 | }; | ||
| 2147 | } | ||
| 2148 | _ => { | ||
| 2149 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 2150 | } | ||
| 2151 | } | ||
| 2152 | } | ||
| 2153 | Ok(()) | ||
| 2154 | } | ||
| 2155 | } | ||
| 2156 | impl ::micropb::MessageEncode for CtrlMsg_Req_ConnectAP { | ||
| 2157 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 2158 | let mut max_size = 0; | ||
| 2159 | if let ::core::option::Option::Some(size) = | ||
| 2160 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 2161 | { | ||
| 2162 | max_size += size; | ||
| 2163 | } else { | ||
| 2164 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2165 | }; | ||
| 2166 | if let ::core::option::Option::Some(size) = | ||
| 2167 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 2168 | { | ||
| 2169 | max_size += size; | ||
| 2170 | } else { | ||
| 2171 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2172 | }; | ||
| 2173 | if let ::core::option::Option::Some(size) = | ||
| 2174 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 2175 | { | ||
| 2176 | max_size += size; | ||
| 2177 | } else { | ||
| 2178 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2179 | }; | ||
| 2180 | if let ::core::option::Option::Some(size) = | ||
| 2181 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 2182 | { | ||
| 2183 | max_size += size; | ||
| 2184 | } else { | ||
| 2185 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2186 | }; | ||
| 2187 | if let ::core::option::Option::Some(size) = | ||
| 2188 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2189 | { | ||
| 2190 | max_size += size; | ||
| 2191 | } else { | ||
| 2192 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2193 | }; | ||
| 2194 | if let ::core::option::Option::Some(size) = | ||
| 2195 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2196 | { | ||
| 2197 | max_size += size; | ||
| 2198 | } else { | ||
| 2199 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2200 | }; | ||
| 2201 | ::core::option::Option::Some(max_size) | ||
| 2202 | }; | ||
| 2203 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 2204 | &self, | ||
| 2205 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 2206 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 2207 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2208 | { | ||
| 2209 | let val_ref = &self.r#ssid; | ||
| 2210 | if !val_ref.is_empty() { | ||
| 2211 | encoder.encode_varint32(10u32)?; | ||
| 2212 | encoder.encode_string(val_ref)?; | ||
| 2213 | } | ||
| 2214 | } | ||
| 2215 | { | ||
| 2216 | let val_ref = &self.r#pwd; | ||
| 2217 | if !val_ref.is_empty() { | ||
| 2218 | encoder.encode_varint32(18u32)?; | ||
| 2219 | encoder.encode_string(val_ref)?; | ||
| 2220 | } | ||
| 2221 | } | ||
| 2222 | { | ||
| 2223 | let val_ref = &self.r#bssid; | ||
| 2224 | if !val_ref.is_empty() { | ||
| 2225 | encoder.encode_varint32(26u32)?; | ||
| 2226 | encoder.encode_string(val_ref)?; | ||
| 2227 | } | ||
| 2228 | } | ||
| 2229 | { | ||
| 2230 | let val_ref = &self.r#is_wpa3_supported; | ||
| 2231 | if *val_ref { | ||
| 2232 | encoder.encode_varint32(32u32)?; | ||
| 2233 | encoder.encode_bool(*val_ref)?; | ||
| 2234 | } | ||
| 2235 | } | ||
| 2236 | { | ||
| 2237 | let val_ref = &self.r#listen_interval; | ||
| 2238 | if *val_ref != 0 { | ||
| 2239 | encoder.encode_varint32(40u32)?; | ||
| 2240 | encoder.encode_int32(*val_ref as _)?; | ||
| 2241 | } | ||
| 2242 | } | ||
| 2243 | { | ||
| 2244 | let val_ref = &self.r#band_mode; | ||
| 2245 | if *val_ref != 0 { | ||
| 2246 | encoder.encode_varint32(48u32)?; | ||
| 2247 | encoder.encode_int32(*val_ref as _)?; | ||
| 2248 | } | ||
| 2249 | } | ||
| 2250 | Ok(()) | ||
| 2251 | } | ||
| 2252 | fn compute_size(&self) -> usize { | ||
| 2253 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2254 | let mut size = 0; | ||
| 2255 | { | ||
| 2256 | let val_ref = &self.r#ssid; | ||
| 2257 | if !val_ref.is_empty() { | ||
| 2258 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 2259 | } | ||
| 2260 | } | ||
| 2261 | { | ||
| 2262 | let val_ref = &self.r#pwd; | ||
| 2263 | if !val_ref.is_empty() { | ||
| 2264 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 2265 | } | ||
| 2266 | } | ||
| 2267 | { | ||
| 2268 | let val_ref = &self.r#bssid; | ||
| 2269 | if !val_ref.is_empty() { | ||
| 2270 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 2271 | } | ||
| 2272 | } | ||
| 2273 | { | ||
| 2274 | let val_ref = &self.r#is_wpa3_supported; | ||
| 2275 | if *val_ref { | ||
| 2276 | size += 1usize + 1; | ||
| 2277 | } | ||
| 2278 | } | ||
| 2279 | { | ||
| 2280 | let val_ref = &self.r#listen_interval; | ||
| 2281 | if *val_ref != 0 { | ||
| 2282 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 2283 | } | ||
| 2284 | } | ||
| 2285 | { | ||
| 2286 | let val_ref = &self.r#band_mode; | ||
| 2287 | if *val_ref != 0 { | ||
| 2288 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 2289 | } | ||
| 2290 | } | ||
| 2291 | size | ||
| 2292 | } | ||
| 2293 | } | ||
| 2294 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 201 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 2295 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 202 | pub(crate) struct CtrlMsgReqScanResult {} | 2296 | pub struct CtrlMsg_Resp_ConnectAP { |
| 203 | 2297 | pub r#resp: i32, | |
| 204 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 2298 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, |
| 2299 | pub r#band_mode: i32, | ||
| 2300 | } | ||
| 2301 | impl CtrlMsg_Resp_ConnectAP { | ||
| 2302 | ///Return a reference to `resp` | ||
| 2303 | #[inline] | ||
| 2304 | pub fn r#resp(&self) -> &i32 { | ||
| 2305 | &self.r#resp | ||
| 2306 | } | ||
| 2307 | ///Return a mutable reference to `resp` | ||
| 2308 | #[inline] | ||
| 2309 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 2310 | &mut self.r#resp | ||
| 2311 | } | ||
| 2312 | ///Set the value of `resp` | ||
| 2313 | #[inline] | ||
| 2314 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 2315 | self.r#resp = value.into(); | ||
| 2316 | self | ||
| 2317 | } | ||
| 2318 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 2319 | #[inline] | ||
| 2320 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 2321 | self.r#resp = value.into(); | ||
| 2322 | self | ||
| 2323 | } | ||
| 2324 | ///Return a reference to `mac` | ||
| 2325 | #[inline] | ||
| 2326 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 2327 | &self.r#mac | ||
| 2328 | } | ||
| 2329 | ///Return a mutable reference to `mac` | ||
| 2330 | #[inline] | ||
| 2331 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 2332 | &mut self.r#mac | ||
| 2333 | } | ||
| 2334 | ///Set the value of `mac` | ||
| 2335 | #[inline] | ||
| 2336 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 2337 | self.r#mac = value.into(); | ||
| 2338 | self | ||
| 2339 | } | ||
| 2340 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 2341 | #[inline] | ||
| 2342 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 2343 | self.r#mac = value.into(); | ||
| 2344 | self | ||
| 2345 | } | ||
| 2346 | ///Return a reference to `band_mode` | ||
| 2347 | #[inline] | ||
| 2348 | pub fn r#band_mode(&self) -> &i32 { | ||
| 2349 | &self.r#band_mode | ||
| 2350 | } | ||
| 2351 | ///Return a mutable reference to `band_mode` | ||
| 2352 | #[inline] | ||
| 2353 | pub fn mut_band_mode(&mut self) -> &mut i32 { | ||
| 2354 | &mut self.r#band_mode | ||
| 2355 | } | ||
| 2356 | ///Set the value of `band_mode` | ||
| 2357 | #[inline] | ||
| 2358 | pub fn set_band_mode(&mut self, value: i32) -> &mut Self { | ||
| 2359 | self.r#band_mode = value.into(); | ||
| 2360 | self | ||
| 2361 | } | ||
| 2362 | ///Builder method that sets the value of `band_mode`. Useful for initializing the message. | ||
| 2363 | #[inline] | ||
| 2364 | pub fn init_band_mode(mut self, value: i32) -> Self { | ||
| 2365 | self.r#band_mode = value.into(); | ||
| 2366 | self | ||
| 2367 | } | ||
| 2368 | } | ||
| 2369 | impl ::micropb::MessageDecode for CtrlMsg_Resp_ConnectAP { | ||
| 2370 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 2371 | &mut self, | ||
| 2372 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 2373 | len: usize, | ||
| 2374 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 2375 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 2376 | let before = decoder.bytes_read(); | ||
| 2377 | while decoder.bytes_read() - before < len { | ||
| 2378 | let tag = decoder.decode_tag()?; | ||
| 2379 | match tag.field_num() { | ||
| 2380 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 2381 | 1u32 => { | ||
| 2382 | let mut_ref = &mut self.r#resp; | ||
| 2383 | { | ||
| 2384 | let val = decoder.decode_int32()?; | ||
| 2385 | let val_ref = &val; | ||
| 2386 | if *val_ref != 0 { | ||
| 2387 | *mut_ref = val as _; | ||
| 2388 | } | ||
| 2389 | }; | ||
| 2390 | } | ||
| 2391 | 2u32 => { | ||
| 2392 | let mut_ref = &mut self.r#mac; | ||
| 2393 | { | ||
| 2394 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 2395 | }; | ||
| 2396 | } | ||
| 2397 | 3u32 => { | ||
| 2398 | let mut_ref = &mut self.r#band_mode; | ||
| 2399 | { | ||
| 2400 | let val = decoder.decode_int32()?; | ||
| 2401 | let val_ref = &val; | ||
| 2402 | if *val_ref != 0 { | ||
| 2403 | *mut_ref = val as _; | ||
| 2404 | } | ||
| 2405 | }; | ||
| 2406 | } | ||
| 2407 | _ => { | ||
| 2408 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 2409 | } | ||
| 2410 | } | ||
| 2411 | } | ||
| 2412 | Ok(()) | ||
| 2413 | } | ||
| 2414 | } | ||
| 2415 | impl ::micropb::MessageEncode for CtrlMsg_Resp_ConnectAP { | ||
| 2416 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 2417 | let mut max_size = 0; | ||
| 2418 | if let ::core::option::Option::Some(size) = | ||
| 2419 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2420 | { | ||
| 2421 | max_size += size; | ||
| 2422 | } else { | ||
| 2423 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2424 | }; | ||
| 2425 | if let ::core::option::Option::Some(size) = | ||
| 2426 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 2427 | { | ||
| 2428 | max_size += size; | ||
| 2429 | } else { | ||
| 2430 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2431 | }; | ||
| 2432 | if let ::core::option::Option::Some(size) = | ||
| 2433 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2434 | { | ||
| 2435 | max_size += size; | ||
| 2436 | } else { | ||
| 2437 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2438 | }; | ||
| 2439 | ::core::option::Option::Some(max_size) | ||
| 2440 | }; | ||
| 2441 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 2442 | &self, | ||
| 2443 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 2444 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 2445 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2446 | { | ||
| 2447 | let val_ref = &self.r#resp; | ||
| 2448 | if *val_ref != 0 { | ||
| 2449 | encoder.encode_varint32(8u32)?; | ||
| 2450 | encoder.encode_int32(*val_ref as _)?; | ||
| 2451 | } | ||
| 2452 | } | ||
| 2453 | { | ||
| 2454 | let val_ref = &self.r#mac; | ||
| 2455 | if !val_ref.is_empty() { | ||
| 2456 | encoder.encode_varint32(18u32)?; | ||
| 2457 | encoder.encode_bytes(val_ref)?; | ||
| 2458 | } | ||
| 2459 | } | ||
| 2460 | { | ||
| 2461 | let val_ref = &self.r#band_mode; | ||
| 2462 | if *val_ref != 0 { | ||
| 2463 | encoder.encode_varint32(24u32)?; | ||
| 2464 | encoder.encode_int32(*val_ref as _)?; | ||
| 2465 | } | ||
| 2466 | } | ||
| 2467 | Ok(()) | ||
| 2468 | } | ||
| 2469 | fn compute_size(&self) -> usize { | ||
| 2470 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2471 | let mut size = 0; | ||
| 2472 | { | ||
| 2473 | let val_ref = &self.r#resp; | ||
| 2474 | if *val_ref != 0 { | ||
| 2475 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 2476 | } | ||
| 2477 | } | ||
| 2478 | { | ||
| 2479 | let val_ref = &self.r#mac; | ||
| 2480 | if !val_ref.is_empty() { | ||
| 2481 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 2482 | } | ||
| 2483 | } | ||
| 2484 | { | ||
| 2485 | let val_ref = &self.r#band_mode; | ||
| 2486 | if *val_ref != 0 { | ||
| 2487 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 2488 | } | ||
| 2489 | } | ||
| 2490 | size | ||
| 2491 | } | ||
| 2492 | } | ||
| 2493 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 205 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 2494 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 206 | pub(crate) struct CtrlMsgRespScanResult { | 2495 | pub struct CtrlMsg_Req_GetSoftAPConfig {} |
| 207 | #[noproto(tag = "1")] | 2496 | impl CtrlMsg_Req_GetSoftAPConfig {} |
| 208 | pub count: u32, | 2497 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetSoftAPConfig { |
| 209 | #[noproto(repeated, tag = "2")] | 2498 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 210 | pub entries: Vec<ScanResult, 16>, | 2499 | &mut self, |
| 211 | #[noproto(tag = "3")] | 2500 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, |
| 212 | pub resp: u32, | 2501 | len: usize, |
| 2502 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 2503 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 2504 | let before = decoder.bytes_read(); | ||
| 2505 | while decoder.bytes_read() - before < len { | ||
| 2506 | let tag = decoder.decode_tag()?; | ||
| 2507 | match tag.field_num() { | ||
| 2508 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 2509 | _ => { | ||
| 2510 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 2511 | } | ||
| 2512 | } | ||
| 2513 | } | ||
| 2514 | Ok(()) | ||
| 2515 | } | ||
| 213 | } | 2516 | } |
| 214 | 2517 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetSoftAPConfig { | |
| 215 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 2518 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 2519 | let mut max_size = 0; | ||
| 2520 | ::core::option::Option::Some(max_size) | ||
| 2521 | }; | ||
| 2522 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 2523 | &self, | ||
| 2524 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 2525 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 2526 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2527 | Ok(()) | ||
| 2528 | } | ||
| 2529 | fn compute_size(&self) -> usize { | ||
| 2530 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2531 | let mut size = 0; | ||
| 2532 | size | ||
| 2533 | } | ||
| 2534 | } | ||
| 2535 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 216 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 2536 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 217 | pub(crate) struct CtrlMsgReqSoftApConnectedSta {} | 2537 | pub struct CtrlMsg_Resp_GetSoftAPConfig { |
| 218 | 2538 | pub r#ssid: ::micropb::heapless::Vec<u8, 32>, | |
| 219 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 2539 | pub r#pwd: ::micropb::heapless::Vec<u8, 32>, |
| 2540 | pub r#chnl: i32, | ||
| 2541 | pub r#sec_prot: Ctrl_WifiSecProt, | ||
| 2542 | pub r#max_conn: i32, | ||
| 2543 | pub r#ssid_hidden: bool, | ||
| 2544 | pub r#bw: i32, | ||
| 2545 | pub r#resp: i32, | ||
| 2546 | pub r#band_mode: i32, | ||
| 2547 | } | ||
| 2548 | impl CtrlMsg_Resp_GetSoftAPConfig { | ||
| 2549 | ///Return a reference to `ssid` | ||
| 2550 | #[inline] | ||
| 2551 | pub fn r#ssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 2552 | &self.r#ssid | ||
| 2553 | } | ||
| 2554 | ///Return a mutable reference to `ssid` | ||
| 2555 | #[inline] | ||
| 2556 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 2557 | &mut self.r#ssid | ||
| 2558 | } | ||
| 2559 | ///Set the value of `ssid` | ||
| 2560 | #[inline] | ||
| 2561 | pub fn set_ssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 2562 | self.r#ssid = value.into(); | ||
| 2563 | self | ||
| 2564 | } | ||
| 2565 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. | ||
| 2566 | #[inline] | ||
| 2567 | pub fn init_ssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 2568 | self.r#ssid = value.into(); | ||
| 2569 | self | ||
| 2570 | } | ||
| 2571 | ///Return a reference to `pwd` | ||
| 2572 | #[inline] | ||
| 2573 | pub fn r#pwd(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 2574 | &self.r#pwd | ||
| 2575 | } | ||
| 2576 | ///Return a mutable reference to `pwd` | ||
| 2577 | #[inline] | ||
| 2578 | pub fn mut_pwd(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 2579 | &mut self.r#pwd | ||
| 2580 | } | ||
| 2581 | ///Set the value of `pwd` | ||
| 2582 | #[inline] | ||
| 2583 | pub fn set_pwd(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 2584 | self.r#pwd = value.into(); | ||
| 2585 | self | ||
| 2586 | } | ||
| 2587 | ///Builder method that sets the value of `pwd`. Useful for initializing the message. | ||
| 2588 | #[inline] | ||
| 2589 | pub fn init_pwd(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 2590 | self.r#pwd = value.into(); | ||
| 2591 | self | ||
| 2592 | } | ||
| 2593 | ///Return a reference to `chnl` | ||
| 2594 | #[inline] | ||
| 2595 | pub fn r#chnl(&self) -> &i32 { | ||
| 2596 | &self.r#chnl | ||
| 2597 | } | ||
| 2598 | ///Return a mutable reference to `chnl` | ||
| 2599 | #[inline] | ||
| 2600 | pub fn mut_chnl(&mut self) -> &mut i32 { | ||
| 2601 | &mut self.r#chnl | ||
| 2602 | } | ||
| 2603 | ///Set the value of `chnl` | ||
| 2604 | #[inline] | ||
| 2605 | pub fn set_chnl(&mut self, value: i32) -> &mut Self { | ||
| 2606 | self.r#chnl = value.into(); | ||
| 2607 | self | ||
| 2608 | } | ||
| 2609 | ///Builder method that sets the value of `chnl`. Useful for initializing the message. | ||
| 2610 | #[inline] | ||
| 2611 | pub fn init_chnl(mut self, value: i32) -> Self { | ||
| 2612 | self.r#chnl = value.into(); | ||
| 2613 | self | ||
| 2614 | } | ||
| 2615 | ///Return a reference to `sec_prot` | ||
| 2616 | #[inline] | ||
| 2617 | pub fn r#sec_prot(&self) -> &Ctrl_WifiSecProt { | ||
| 2618 | &self.r#sec_prot | ||
| 2619 | } | ||
| 2620 | ///Return a mutable reference to `sec_prot` | ||
| 2621 | #[inline] | ||
| 2622 | pub fn mut_sec_prot(&mut self) -> &mut Ctrl_WifiSecProt { | ||
| 2623 | &mut self.r#sec_prot | ||
| 2624 | } | ||
| 2625 | ///Set the value of `sec_prot` | ||
| 2626 | #[inline] | ||
| 2627 | pub fn set_sec_prot(&mut self, value: Ctrl_WifiSecProt) -> &mut Self { | ||
| 2628 | self.r#sec_prot = value.into(); | ||
| 2629 | self | ||
| 2630 | } | ||
| 2631 | ///Builder method that sets the value of `sec_prot`. Useful for initializing the message. | ||
| 2632 | #[inline] | ||
| 2633 | pub fn init_sec_prot(mut self, value: Ctrl_WifiSecProt) -> Self { | ||
| 2634 | self.r#sec_prot = value.into(); | ||
| 2635 | self | ||
| 2636 | } | ||
| 2637 | ///Return a reference to `max_conn` | ||
| 2638 | #[inline] | ||
| 2639 | pub fn r#max_conn(&self) -> &i32 { | ||
| 2640 | &self.r#max_conn | ||
| 2641 | } | ||
| 2642 | ///Return a mutable reference to `max_conn` | ||
| 2643 | #[inline] | ||
| 2644 | pub fn mut_max_conn(&mut self) -> &mut i32 { | ||
| 2645 | &mut self.r#max_conn | ||
| 2646 | } | ||
| 2647 | ///Set the value of `max_conn` | ||
| 2648 | #[inline] | ||
| 2649 | pub fn set_max_conn(&mut self, value: i32) -> &mut Self { | ||
| 2650 | self.r#max_conn = value.into(); | ||
| 2651 | self | ||
| 2652 | } | ||
| 2653 | ///Builder method that sets the value of `max_conn`. Useful for initializing the message. | ||
| 2654 | #[inline] | ||
| 2655 | pub fn init_max_conn(mut self, value: i32) -> Self { | ||
| 2656 | self.r#max_conn = value.into(); | ||
| 2657 | self | ||
| 2658 | } | ||
| 2659 | ///Return a reference to `ssid_hidden` | ||
| 2660 | #[inline] | ||
| 2661 | pub fn r#ssid_hidden(&self) -> &bool { | ||
| 2662 | &self.r#ssid_hidden | ||
| 2663 | } | ||
| 2664 | ///Return a mutable reference to `ssid_hidden` | ||
| 2665 | #[inline] | ||
| 2666 | pub fn mut_ssid_hidden(&mut self) -> &mut bool { | ||
| 2667 | &mut self.r#ssid_hidden | ||
| 2668 | } | ||
| 2669 | ///Set the value of `ssid_hidden` | ||
| 2670 | #[inline] | ||
| 2671 | pub fn set_ssid_hidden(&mut self, value: bool) -> &mut Self { | ||
| 2672 | self.r#ssid_hidden = value.into(); | ||
| 2673 | self | ||
| 2674 | } | ||
| 2675 | ///Builder method that sets the value of `ssid_hidden`. Useful for initializing the message. | ||
| 2676 | #[inline] | ||
| 2677 | pub fn init_ssid_hidden(mut self, value: bool) -> Self { | ||
| 2678 | self.r#ssid_hidden = value.into(); | ||
| 2679 | self | ||
| 2680 | } | ||
| 2681 | ///Return a reference to `bw` | ||
| 2682 | #[inline] | ||
| 2683 | pub fn r#bw(&self) -> &i32 { | ||
| 2684 | &self.r#bw | ||
| 2685 | } | ||
| 2686 | ///Return a mutable reference to `bw` | ||
| 2687 | #[inline] | ||
| 2688 | pub fn mut_bw(&mut self) -> &mut i32 { | ||
| 2689 | &mut self.r#bw | ||
| 2690 | } | ||
| 2691 | ///Set the value of `bw` | ||
| 2692 | #[inline] | ||
| 2693 | pub fn set_bw(&mut self, value: i32) -> &mut Self { | ||
| 2694 | self.r#bw = value.into(); | ||
| 2695 | self | ||
| 2696 | } | ||
| 2697 | ///Builder method that sets the value of `bw`. Useful for initializing the message. | ||
| 2698 | #[inline] | ||
| 2699 | pub fn init_bw(mut self, value: i32) -> Self { | ||
| 2700 | self.r#bw = value.into(); | ||
| 2701 | self | ||
| 2702 | } | ||
| 2703 | ///Return a reference to `resp` | ||
| 2704 | #[inline] | ||
| 2705 | pub fn r#resp(&self) -> &i32 { | ||
| 2706 | &self.r#resp | ||
| 2707 | } | ||
| 2708 | ///Return a mutable reference to `resp` | ||
| 2709 | #[inline] | ||
| 2710 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 2711 | &mut self.r#resp | ||
| 2712 | } | ||
| 2713 | ///Set the value of `resp` | ||
| 2714 | #[inline] | ||
| 2715 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 2716 | self.r#resp = value.into(); | ||
| 2717 | self | ||
| 2718 | } | ||
| 2719 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 2720 | #[inline] | ||
| 2721 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 2722 | self.r#resp = value.into(); | ||
| 2723 | self | ||
| 2724 | } | ||
| 2725 | ///Return a reference to `band_mode` | ||
| 2726 | #[inline] | ||
| 2727 | pub fn r#band_mode(&self) -> &i32 { | ||
| 2728 | &self.r#band_mode | ||
| 2729 | } | ||
| 2730 | ///Return a mutable reference to `band_mode` | ||
| 2731 | #[inline] | ||
| 2732 | pub fn mut_band_mode(&mut self) -> &mut i32 { | ||
| 2733 | &mut self.r#band_mode | ||
| 2734 | } | ||
| 2735 | ///Set the value of `band_mode` | ||
| 2736 | #[inline] | ||
| 2737 | pub fn set_band_mode(&mut self, value: i32) -> &mut Self { | ||
| 2738 | self.r#band_mode = value.into(); | ||
| 2739 | self | ||
| 2740 | } | ||
| 2741 | ///Builder method that sets the value of `band_mode`. Useful for initializing the message. | ||
| 2742 | #[inline] | ||
| 2743 | pub fn init_band_mode(mut self, value: i32) -> Self { | ||
| 2744 | self.r#band_mode = value.into(); | ||
| 2745 | self | ||
| 2746 | } | ||
| 2747 | } | ||
| 2748 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetSoftAPConfig { | ||
| 2749 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 2750 | &mut self, | ||
| 2751 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 2752 | len: usize, | ||
| 2753 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 2754 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 2755 | let before = decoder.bytes_read(); | ||
| 2756 | while decoder.bytes_read() - before < len { | ||
| 2757 | let tag = decoder.decode_tag()?; | ||
| 2758 | match tag.field_num() { | ||
| 2759 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 2760 | 1u32 => { | ||
| 2761 | let mut_ref = &mut self.r#ssid; | ||
| 2762 | { | ||
| 2763 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 2764 | }; | ||
| 2765 | } | ||
| 2766 | 2u32 => { | ||
| 2767 | let mut_ref = &mut self.r#pwd; | ||
| 2768 | { | ||
| 2769 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 2770 | }; | ||
| 2771 | } | ||
| 2772 | 3u32 => { | ||
| 2773 | let mut_ref = &mut self.r#chnl; | ||
| 2774 | { | ||
| 2775 | let val = decoder.decode_int32()?; | ||
| 2776 | let val_ref = &val; | ||
| 2777 | if *val_ref != 0 { | ||
| 2778 | *mut_ref = val as _; | ||
| 2779 | } | ||
| 2780 | }; | ||
| 2781 | } | ||
| 2782 | 4u32 => { | ||
| 2783 | let mut_ref = &mut self.r#sec_prot; | ||
| 2784 | { | ||
| 2785 | let val = decoder.decode_int32().map(|n| Ctrl_WifiSecProt(n as _))?; | ||
| 2786 | let val_ref = &val; | ||
| 2787 | if val_ref.0 != 0 { | ||
| 2788 | *mut_ref = val as _; | ||
| 2789 | } | ||
| 2790 | }; | ||
| 2791 | } | ||
| 2792 | 5u32 => { | ||
| 2793 | let mut_ref = &mut self.r#max_conn; | ||
| 2794 | { | ||
| 2795 | let val = decoder.decode_int32()?; | ||
| 2796 | let val_ref = &val; | ||
| 2797 | if *val_ref != 0 { | ||
| 2798 | *mut_ref = val as _; | ||
| 2799 | } | ||
| 2800 | }; | ||
| 2801 | } | ||
| 2802 | 6u32 => { | ||
| 2803 | let mut_ref = &mut self.r#ssid_hidden; | ||
| 2804 | { | ||
| 2805 | let val = decoder.decode_bool()?; | ||
| 2806 | let val_ref = &val; | ||
| 2807 | if *val_ref { | ||
| 2808 | *mut_ref = val as _; | ||
| 2809 | } | ||
| 2810 | }; | ||
| 2811 | } | ||
| 2812 | 7u32 => { | ||
| 2813 | let mut_ref = &mut self.r#bw; | ||
| 2814 | { | ||
| 2815 | let val = decoder.decode_int32()?; | ||
| 2816 | let val_ref = &val; | ||
| 2817 | if *val_ref != 0 { | ||
| 2818 | *mut_ref = val as _; | ||
| 2819 | } | ||
| 2820 | }; | ||
| 2821 | } | ||
| 2822 | 8u32 => { | ||
| 2823 | let mut_ref = &mut self.r#resp; | ||
| 2824 | { | ||
| 2825 | let val = decoder.decode_int32()?; | ||
| 2826 | let val_ref = &val; | ||
| 2827 | if *val_ref != 0 { | ||
| 2828 | *mut_ref = val as _; | ||
| 2829 | } | ||
| 2830 | }; | ||
| 2831 | } | ||
| 2832 | 9u32 => { | ||
| 2833 | let mut_ref = &mut self.r#band_mode; | ||
| 2834 | { | ||
| 2835 | let val = decoder.decode_int32()?; | ||
| 2836 | let val_ref = &val; | ||
| 2837 | if *val_ref != 0 { | ||
| 2838 | *mut_ref = val as _; | ||
| 2839 | } | ||
| 2840 | }; | ||
| 2841 | } | ||
| 2842 | _ => { | ||
| 2843 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 2844 | } | ||
| 2845 | } | ||
| 2846 | } | ||
| 2847 | Ok(()) | ||
| 2848 | } | ||
| 2849 | } | ||
| 2850 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetSoftAPConfig { | ||
| 2851 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 2852 | let mut max_size = 0; | ||
| 2853 | if let ::core::option::Option::Some(size) = | ||
| 2854 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 2855 | { | ||
| 2856 | max_size += size; | ||
| 2857 | } else { | ||
| 2858 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2859 | }; | ||
| 2860 | if let ::core::option::Option::Some(size) = | ||
| 2861 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 2862 | { | ||
| 2863 | max_size += size; | ||
| 2864 | } else { | ||
| 2865 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2866 | }; | ||
| 2867 | if let ::core::option::Option::Some(size) = | ||
| 2868 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2869 | { | ||
| 2870 | max_size += size; | ||
| 2871 | } else { | ||
| 2872 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2873 | }; | ||
| 2874 | if let ::core::option::Option::Some(size) = | ||
| 2875 | ::micropb::const_map!(::core::option::Option::Some(Ctrl_WifiSecProt::_MAX_SIZE), |size| size | ||
| 2876 | + 1usize) | ||
| 2877 | { | ||
| 2878 | max_size += size; | ||
| 2879 | } else { | ||
| 2880 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2881 | }; | ||
| 2882 | if let ::core::option::Option::Some(size) = | ||
| 2883 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2884 | { | ||
| 2885 | max_size += size; | ||
| 2886 | } else { | ||
| 2887 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2888 | }; | ||
| 2889 | if let ::core::option::Option::Some(size) = | ||
| 2890 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 2891 | { | ||
| 2892 | max_size += size; | ||
| 2893 | } else { | ||
| 2894 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2895 | }; | ||
| 2896 | if let ::core::option::Option::Some(size) = | ||
| 2897 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2898 | { | ||
| 2899 | max_size += size; | ||
| 2900 | } else { | ||
| 2901 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2902 | }; | ||
| 2903 | if let ::core::option::Option::Some(size) = | ||
| 2904 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2905 | { | ||
| 2906 | max_size += size; | ||
| 2907 | } else { | ||
| 2908 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2909 | }; | ||
| 2910 | if let ::core::option::Option::Some(size) = | ||
| 2911 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 2912 | { | ||
| 2913 | max_size += size; | ||
| 2914 | } else { | ||
| 2915 | break 'msg (::core::option::Option::<usize>::None); | ||
| 2916 | }; | ||
| 2917 | ::core::option::Option::Some(max_size) | ||
| 2918 | }; | ||
| 2919 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 2920 | &self, | ||
| 2921 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 2922 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 2923 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2924 | { | ||
| 2925 | let val_ref = &self.r#ssid; | ||
| 2926 | if !val_ref.is_empty() { | ||
| 2927 | encoder.encode_varint32(10u32)?; | ||
| 2928 | encoder.encode_bytes(val_ref)?; | ||
| 2929 | } | ||
| 2930 | } | ||
| 2931 | { | ||
| 2932 | let val_ref = &self.r#pwd; | ||
| 2933 | if !val_ref.is_empty() { | ||
| 2934 | encoder.encode_varint32(18u32)?; | ||
| 2935 | encoder.encode_bytes(val_ref)?; | ||
| 2936 | } | ||
| 2937 | } | ||
| 2938 | { | ||
| 2939 | let val_ref = &self.r#chnl; | ||
| 2940 | if *val_ref != 0 { | ||
| 2941 | encoder.encode_varint32(24u32)?; | ||
| 2942 | encoder.encode_int32(*val_ref as _)?; | ||
| 2943 | } | ||
| 2944 | } | ||
| 2945 | { | ||
| 2946 | let val_ref = &self.r#sec_prot; | ||
| 2947 | if val_ref.0 != 0 { | ||
| 2948 | encoder.encode_varint32(32u32)?; | ||
| 2949 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 2950 | } | ||
| 2951 | } | ||
| 2952 | { | ||
| 2953 | let val_ref = &self.r#max_conn; | ||
| 2954 | if *val_ref != 0 { | ||
| 2955 | encoder.encode_varint32(40u32)?; | ||
| 2956 | encoder.encode_int32(*val_ref as _)?; | ||
| 2957 | } | ||
| 2958 | } | ||
| 2959 | { | ||
| 2960 | let val_ref = &self.r#ssid_hidden; | ||
| 2961 | if *val_ref { | ||
| 2962 | encoder.encode_varint32(48u32)?; | ||
| 2963 | encoder.encode_bool(*val_ref)?; | ||
| 2964 | } | ||
| 2965 | } | ||
| 2966 | { | ||
| 2967 | let val_ref = &self.r#bw; | ||
| 2968 | if *val_ref != 0 { | ||
| 2969 | encoder.encode_varint32(56u32)?; | ||
| 2970 | encoder.encode_int32(*val_ref as _)?; | ||
| 2971 | } | ||
| 2972 | } | ||
| 2973 | { | ||
| 2974 | let val_ref = &self.r#resp; | ||
| 2975 | if *val_ref != 0 { | ||
| 2976 | encoder.encode_varint32(64u32)?; | ||
| 2977 | encoder.encode_int32(*val_ref as _)?; | ||
| 2978 | } | ||
| 2979 | } | ||
| 2980 | { | ||
| 2981 | let val_ref = &self.r#band_mode; | ||
| 2982 | if *val_ref != 0 { | ||
| 2983 | encoder.encode_varint32(72u32)?; | ||
| 2984 | encoder.encode_int32(*val_ref as _)?; | ||
| 2985 | } | ||
| 2986 | } | ||
| 2987 | Ok(()) | ||
| 2988 | } | ||
| 2989 | fn compute_size(&self) -> usize { | ||
| 2990 | use ::micropb::{FieldEncode, PbMap}; | ||
| 2991 | let mut size = 0; | ||
| 2992 | { | ||
| 2993 | let val_ref = &self.r#ssid; | ||
| 2994 | if !val_ref.is_empty() { | ||
| 2995 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 2996 | } | ||
| 2997 | } | ||
| 2998 | { | ||
| 2999 | let val_ref = &self.r#pwd; | ||
| 3000 | if !val_ref.is_empty() { | ||
| 3001 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 3002 | } | ||
| 3003 | } | ||
| 3004 | { | ||
| 3005 | let val_ref = &self.r#chnl; | ||
| 3006 | if *val_ref != 0 { | ||
| 3007 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3008 | } | ||
| 3009 | } | ||
| 3010 | { | ||
| 3011 | let val_ref = &self.r#sec_prot; | ||
| 3012 | if val_ref.0 != 0 { | ||
| 3013 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 3014 | } | ||
| 3015 | } | ||
| 3016 | { | ||
| 3017 | let val_ref = &self.r#max_conn; | ||
| 3018 | if *val_ref != 0 { | ||
| 3019 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3020 | } | ||
| 3021 | } | ||
| 3022 | { | ||
| 3023 | let val_ref = &self.r#ssid_hidden; | ||
| 3024 | if *val_ref { | ||
| 3025 | size += 1usize + 1; | ||
| 3026 | } | ||
| 3027 | } | ||
| 3028 | { | ||
| 3029 | let val_ref = &self.r#bw; | ||
| 3030 | if *val_ref != 0 { | ||
| 3031 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3032 | } | ||
| 3033 | } | ||
| 3034 | { | ||
| 3035 | let val_ref = &self.r#resp; | ||
| 3036 | if *val_ref != 0 { | ||
| 3037 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3038 | } | ||
| 3039 | } | ||
| 3040 | { | ||
| 3041 | let val_ref = &self.r#band_mode; | ||
| 3042 | if *val_ref != 0 { | ||
| 3043 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3044 | } | ||
| 3045 | } | ||
| 3046 | size | ||
| 3047 | } | ||
| 3048 | } | ||
| 3049 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 220 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3050 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 221 | pub(crate) struct CtrlMsgRespSoftApConnectedSta { | 3051 | pub struct CtrlMsg_Req_StartSoftAP { |
| 222 | #[noproto(tag = "1")] | 3052 | pub r#ssid: ::micropb::heapless::String<32>, |
| 223 | pub num: u32, | 3053 | pub r#pwd: ::micropb::heapless::String<32>, |
| 224 | #[noproto(repeated, tag = "2")] | 3054 | pub r#chnl: i32, |
| 225 | pub stations: Vec<ConnectedStaList, 16>, | 3055 | pub r#sec_prot: Ctrl_WifiSecProt, |
| 226 | #[noproto(tag = "3")] | 3056 | pub r#max_conn: i32, |
| 227 | pub resp: u32, | 3057 | pub r#ssid_hidden: bool, |
| 3058 | pub r#bw: i32, | ||
| 3059 | pub r#band_mode: i32, | ||
| 228 | } | 3060 | } |
| 229 | 3061 | impl CtrlMsg_Req_StartSoftAP { | |
| 230 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 3062 | ///Return a reference to `ssid` |
| 3063 | #[inline] | ||
| 3064 | pub fn r#ssid(&self) -> &::micropb::heapless::String<32> { | ||
| 3065 | &self.r#ssid | ||
| 3066 | } | ||
| 3067 | ///Return a mutable reference to `ssid` | ||
| 3068 | #[inline] | ||
| 3069 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::String<32> { | ||
| 3070 | &mut self.r#ssid | ||
| 3071 | } | ||
| 3072 | ///Set the value of `ssid` | ||
| 3073 | #[inline] | ||
| 3074 | pub fn set_ssid(&mut self, value: ::micropb::heapless::String<32>) -> &mut Self { | ||
| 3075 | self.r#ssid = value.into(); | ||
| 3076 | self | ||
| 3077 | } | ||
| 3078 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. | ||
| 3079 | #[inline] | ||
| 3080 | pub fn init_ssid(mut self, value: ::micropb::heapless::String<32>) -> Self { | ||
| 3081 | self.r#ssid = value.into(); | ||
| 3082 | self | ||
| 3083 | } | ||
| 3084 | ///Return a reference to `pwd` | ||
| 3085 | #[inline] | ||
| 3086 | pub fn r#pwd(&self) -> &::micropb::heapless::String<32> { | ||
| 3087 | &self.r#pwd | ||
| 3088 | } | ||
| 3089 | ///Return a mutable reference to `pwd` | ||
| 3090 | #[inline] | ||
| 3091 | pub fn mut_pwd(&mut self) -> &mut ::micropb::heapless::String<32> { | ||
| 3092 | &mut self.r#pwd | ||
| 3093 | } | ||
| 3094 | ///Set the value of `pwd` | ||
| 3095 | #[inline] | ||
| 3096 | pub fn set_pwd(&mut self, value: ::micropb::heapless::String<32>) -> &mut Self { | ||
| 3097 | self.r#pwd = value.into(); | ||
| 3098 | self | ||
| 3099 | } | ||
| 3100 | ///Builder method that sets the value of `pwd`. Useful for initializing the message. | ||
| 3101 | #[inline] | ||
| 3102 | pub fn init_pwd(mut self, value: ::micropb::heapless::String<32>) -> Self { | ||
| 3103 | self.r#pwd = value.into(); | ||
| 3104 | self | ||
| 3105 | } | ||
| 3106 | ///Return a reference to `chnl` | ||
| 3107 | #[inline] | ||
| 3108 | pub fn r#chnl(&self) -> &i32 { | ||
| 3109 | &self.r#chnl | ||
| 3110 | } | ||
| 3111 | ///Return a mutable reference to `chnl` | ||
| 3112 | #[inline] | ||
| 3113 | pub fn mut_chnl(&mut self) -> &mut i32 { | ||
| 3114 | &mut self.r#chnl | ||
| 3115 | } | ||
| 3116 | ///Set the value of `chnl` | ||
| 3117 | #[inline] | ||
| 3118 | pub fn set_chnl(&mut self, value: i32) -> &mut Self { | ||
| 3119 | self.r#chnl = value.into(); | ||
| 3120 | self | ||
| 3121 | } | ||
| 3122 | ///Builder method that sets the value of `chnl`. Useful for initializing the message. | ||
| 3123 | #[inline] | ||
| 3124 | pub fn init_chnl(mut self, value: i32) -> Self { | ||
| 3125 | self.r#chnl = value.into(); | ||
| 3126 | self | ||
| 3127 | } | ||
| 3128 | ///Return a reference to `sec_prot` | ||
| 3129 | #[inline] | ||
| 3130 | pub fn r#sec_prot(&self) -> &Ctrl_WifiSecProt { | ||
| 3131 | &self.r#sec_prot | ||
| 3132 | } | ||
| 3133 | ///Return a mutable reference to `sec_prot` | ||
| 3134 | #[inline] | ||
| 3135 | pub fn mut_sec_prot(&mut self) -> &mut Ctrl_WifiSecProt { | ||
| 3136 | &mut self.r#sec_prot | ||
| 3137 | } | ||
| 3138 | ///Set the value of `sec_prot` | ||
| 3139 | #[inline] | ||
| 3140 | pub fn set_sec_prot(&mut self, value: Ctrl_WifiSecProt) -> &mut Self { | ||
| 3141 | self.r#sec_prot = value.into(); | ||
| 3142 | self | ||
| 3143 | } | ||
| 3144 | ///Builder method that sets the value of `sec_prot`. Useful for initializing the message. | ||
| 3145 | #[inline] | ||
| 3146 | pub fn init_sec_prot(mut self, value: Ctrl_WifiSecProt) -> Self { | ||
| 3147 | self.r#sec_prot = value.into(); | ||
| 3148 | self | ||
| 3149 | } | ||
| 3150 | ///Return a reference to `max_conn` | ||
| 3151 | #[inline] | ||
| 3152 | pub fn r#max_conn(&self) -> &i32 { | ||
| 3153 | &self.r#max_conn | ||
| 3154 | } | ||
| 3155 | ///Return a mutable reference to `max_conn` | ||
| 3156 | #[inline] | ||
| 3157 | pub fn mut_max_conn(&mut self) -> &mut i32 { | ||
| 3158 | &mut self.r#max_conn | ||
| 3159 | } | ||
| 3160 | ///Set the value of `max_conn` | ||
| 3161 | #[inline] | ||
| 3162 | pub fn set_max_conn(&mut self, value: i32) -> &mut Self { | ||
| 3163 | self.r#max_conn = value.into(); | ||
| 3164 | self | ||
| 3165 | } | ||
| 3166 | ///Builder method that sets the value of `max_conn`. Useful for initializing the message. | ||
| 3167 | #[inline] | ||
| 3168 | pub fn init_max_conn(mut self, value: i32) -> Self { | ||
| 3169 | self.r#max_conn = value.into(); | ||
| 3170 | self | ||
| 3171 | } | ||
| 3172 | ///Return a reference to `ssid_hidden` | ||
| 3173 | #[inline] | ||
| 3174 | pub fn r#ssid_hidden(&self) -> &bool { | ||
| 3175 | &self.r#ssid_hidden | ||
| 3176 | } | ||
| 3177 | ///Return a mutable reference to `ssid_hidden` | ||
| 3178 | #[inline] | ||
| 3179 | pub fn mut_ssid_hidden(&mut self) -> &mut bool { | ||
| 3180 | &mut self.r#ssid_hidden | ||
| 3181 | } | ||
| 3182 | ///Set the value of `ssid_hidden` | ||
| 3183 | #[inline] | ||
| 3184 | pub fn set_ssid_hidden(&mut self, value: bool) -> &mut Self { | ||
| 3185 | self.r#ssid_hidden = value.into(); | ||
| 3186 | self | ||
| 3187 | } | ||
| 3188 | ///Builder method that sets the value of `ssid_hidden`. Useful for initializing the message. | ||
| 3189 | #[inline] | ||
| 3190 | pub fn init_ssid_hidden(mut self, value: bool) -> Self { | ||
| 3191 | self.r#ssid_hidden = value.into(); | ||
| 3192 | self | ||
| 3193 | } | ||
| 3194 | ///Return a reference to `bw` | ||
| 3195 | #[inline] | ||
| 3196 | pub fn r#bw(&self) -> &i32 { | ||
| 3197 | &self.r#bw | ||
| 3198 | } | ||
| 3199 | ///Return a mutable reference to `bw` | ||
| 3200 | #[inline] | ||
| 3201 | pub fn mut_bw(&mut self) -> &mut i32 { | ||
| 3202 | &mut self.r#bw | ||
| 3203 | } | ||
| 3204 | ///Set the value of `bw` | ||
| 3205 | #[inline] | ||
| 3206 | pub fn set_bw(&mut self, value: i32) -> &mut Self { | ||
| 3207 | self.r#bw = value.into(); | ||
| 3208 | self | ||
| 3209 | } | ||
| 3210 | ///Builder method that sets the value of `bw`. Useful for initializing the message. | ||
| 3211 | #[inline] | ||
| 3212 | pub fn init_bw(mut self, value: i32) -> Self { | ||
| 3213 | self.r#bw = value.into(); | ||
| 3214 | self | ||
| 3215 | } | ||
| 3216 | ///Return a reference to `band_mode` | ||
| 3217 | #[inline] | ||
| 3218 | pub fn r#band_mode(&self) -> &i32 { | ||
| 3219 | &self.r#band_mode | ||
| 3220 | } | ||
| 3221 | ///Return a mutable reference to `band_mode` | ||
| 3222 | #[inline] | ||
| 3223 | pub fn mut_band_mode(&mut self) -> &mut i32 { | ||
| 3224 | &mut self.r#band_mode | ||
| 3225 | } | ||
| 3226 | ///Set the value of `band_mode` | ||
| 3227 | #[inline] | ||
| 3228 | pub fn set_band_mode(&mut self, value: i32) -> &mut Self { | ||
| 3229 | self.r#band_mode = value.into(); | ||
| 3230 | self | ||
| 3231 | } | ||
| 3232 | ///Builder method that sets the value of `band_mode`. Useful for initializing the message. | ||
| 3233 | #[inline] | ||
| 3234 | pub fn init_band_mode(mut self, value: i32) -> Self { | ||
| 3235 | self.r#band_mode = value.into(); | ||
| 3236 | self | ||
| 3237 | } | ||
| 3238 | } | ||
| 3239 | impl ::micropb::MessageDecode for CtrlMsg_Req_StartSoftAP { | ||
| 3240 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 3241 | &mut self, | ||
| 3242 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 3243 | len: usize, | ||
| 3244 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 3245 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 3246 | let before = decoder.bytes_read(); | ||
| 3247 | while decoder.bytes_read() - before < len { | ||
| 3248 | let tag = decoder.decode_tag()?; | ||
| 3249 | match tag.field_num() { | ||
| 3250 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 3251 | 1u32 => { | ||
| 3252 | let mut_ref = &mut self.r#ssid; | ||
| 3253 | { | ||
| 3254 | decoder.decode_string(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 3255 | }; | ||
| 3256 | } | ||
| 3257 | 2u32 => { | ||
| 3258 | let mut_ref = &mut self.r#pwd; | ||
| 3259 | { | ||
| 3260 | decoder.decode_string(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 3261 | }; | ||
| 3262 | } | ||
| 3263 | 3u32 => { | ||
| 3264 | let mut_ref = &mut self.r#chnl; | ||
| 3265 | { | ||
| 3266 | let val = decoder.decode_int32()?; | ||
| 3267 | let val_ref = &val; | ||
| 3268 | if *val_ref != 0 { | ||
| 3269 | *mut_ref = val as _; | ||
| 3270 | } | ||
| 3271 | }; | ||
| 3272 | } | ||
| 3273 | 4u32 => { | ||
| 3274 | let mut_ref = &mut self.r#sec_prot; | ||
| 3275 | { | ||
| 3276 | let val = decoder.decode_int32().map(|n| Ctrl_WifiSecProt(n as _))?; | ||
| 3277 | let val_ref = &val; | ||
| 3278 | if val_ref.0 != 0 { | ||
| 3279 | *mut_ref = val as _; | ||
| 3280 | } | ||
| 3281 | }; | ||
| 3282 | } | ||
| 3283 | 5u32 => { | ||
| 3284 | let mut_ref = &mut self.r#max_conn; | ||
| 3285 | { | ||
| 3286 | let val = decoder.decode_int32()?; | ||
| 3287 | let val_ref = &val; | ||
| 3288 | if *val_ref != 0 { | ||
| 3289 | *mut_ref = val as _; | ||
| 3290 | } | ||
| 3291 | }; | ||
| 3292 | } | ||
| 3293 | 6u32 => { | ||
| 3294 | let mut_ref = &mut self.r#ssid_hidden; | ||
| 3295 | { | ||
| 3296 | let val = decoder.decode_bool()?; | ||
| 3297 | let val_ref = &val; | ||
| 3298 | if *val_ref { | ||
| 3299 | *mut_ref = val as _; | ||
| 3300 | } | ||
| 3301 | }; | ||
| 3302 | } | ||
| 3303 | 7u32 => { | ||
| 3304 | let mut_ref = &mut self.r#bw; | ||
| 3305 | { | ||
| 3306 | let val = decoder.decode_int32()?; | ||
| 3307 | let val_ref = &val; | ||
| 3308 | if *val_ref != 0 { | ||
| 3309 | *mut_ref = val as _; | ||
| 3310 | } | ||
| 3311 | }; | ||
| 3312 | } | ||
| 3313 | 8u32 => { | ||
| 3314 | let mut_ref = &mut self.r#band_mode; | ||
| 3315 | { | ||
| 3316 | let val = decoder.decode_int32()?; | ||
| 3317 | let val_ref = &val; | ||
| 3318 | if *val_ref != 0 { | ||
| 3319 | *mut_ref = val as _; | ||
| 3320 | } | ||
| 3321 | }; | ||
| 3322 | } | ||
| 3323 | _ => { | ||
| 3324 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 3325 | } | ||
| 3326 | } | ||
| 3327 | } | ||
| 3328 | Ok(()) | ||
| 3329 | } | ||
| 3330 | } | ||
| 3331 | impl ::micropb::MessageEncode for CtrlMsg_Req_StartSoftAP { | ||
| 3332 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 3333 | let mut max_size = 0; | ||
| 3334 | if let ::core::option::Option::Some(size) = | ||
| 3335 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 3336 | { | ||
| 3337 | max_size += size; | ||
| 3338 | } else { | ||
| 3339 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3340 | }; | ||
| 3341 | if let ::core::option::Option::Some(size) = | ||
| 3342 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 3343 | { | ||
| 3344 | max_size += size; | ||
| 3345 | } else { | ||
| 3346 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3347 | }; | ||
| 3348 | if let ::core::option::Option::Some(size) = | ||
| 3349 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3350 | { | ||
| 3351 | max_size += size; | ||
| 3352 | } else { | ||
| 3353 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3354 | }; | ||
| 3355 | if let ::core::option::Option::Some(size) = | ||
| 3356 | ::micropb::const_map!(::core::option::Option::Some(Ctrl_WifiSecProt::_MAX_SIZE), |size| size | ||
| 3357 | + 1usize) | ||
| 3358 | { | ||
| 3359 | max_size += size; | ||
| 3360 | } else { | ||
| 3361 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3362 | }; | ||
| 3363 | if let ::core::option::Option::Some(size) = | ||
| 3364 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3365 | { | ||
| 3366 | max_size += size; | ||
| 3367 | } else { | ||
| 3368 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3369 | }; | ||
| 3370 | if let ::core::option::Option::Some(size) = | ||
| 3371 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 3372 | { | ||
| 3373 | max_size += size; | ||
| 3374 | } else { | ||
| 3375 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3376 | }; | ||
| 3377 | if let ::core::option::Option::Some(size) = | ||
| 3378 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3379 | { | ||
| 3380 | max_size += size; | ||
| 3381 | } else { | ||
| 3382 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3383 | }; | ||
| 3384 | if let ::core::option::Option::Some(size) = | ||
| 3385 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3386 | { | ||
| 3387 | max_size += size; | ||
| 3388 | } else { | ||
| 3389 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3390 | }; | ||
| 3391 | ::core::option::Option::Some(max_size) | ||
| 3392 | }; | ||
| 3393 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 3394 | &self, | ||
| 3395 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 3396 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 3397 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3398 | { | ||
| 3399 | let val_ref = &self.r#ssid; | ||
| 3400 | if !val_ref.is_empty() { | ||
| 3401 | encoder.encode_varint32(10u32)?; | ||
| 3402 | encoder.encode_string(val_ref)?; | ||
| 3403 | } | ||
| 3404 | } | ||
| 3405 | { | ||
| 3406 | let val_ref = &self.r#pwd; | ||
| 3407 | if !val_ref.is_empty() { | ||
| 3408 | encoder.encode_varint32(18u32)?; | ||
| 3409 | encoder.encode_string(val_ref)?; | ||
| 3410 | } | ||
| 3411 | } | ||
| 3412 | { | ||
| 3413 | let val_ref = &self.r#chnl; | ||
| 3414 | if *val_ref != 0 { | ||
| 3415 | encoder.encode_varint32(24u32)?; | ||
| 3416 | encoder.encode_int32(*val_ref as _)?; | ||
| 3417 | } | ||
| 3418 | } | ||
| 3419 | { | ||
| 3420 | let val_ref = &self.r#sec_prot; | ||
| 3421 | if val_ref.0 != 0 { | ||
| 3422 | encoder.encode_varint32(32u32)?; | ||
| 3423 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 3424 | } | ||
| 3425 | } | ||
| 3426 | { | ||
| 3427 | let val_ref = &self.r#max_conn; | ||
| 3428 | if *val_ref != 0 { | ||
| 3429 | encoder.encode_varint32(40u32)?; | ||
| 3430 | encoder.encode_int32(*val_ref as _)?; | ||
| 3431 | } | ||
| 3432 | } | ||
| 3433 | { | ||
| 3434 | let val_ref = &self.r#ssid_hidden; | ||
| 3435 | if *val_ref { | ||
| 3436 | encoder.encode_varint32(48u32)?; | ||
| 3437 | encoder.encode_bool(*val_ref)?; | ||
| 3438 | } | ||
| 3439 | } | ||
| 3440 | { | ||
| 3441 | let val_ref = &self.r#bw; | ||
| 3442 | if *val_ref != 0 { | ||
| 3443 | encoder.encode_varint32(56u32)?; | ||
| 3444 | encoder.encode_int32(*val_ref as _)?; | ||
| 3445 | } | ||
| 3446 | } | ||
| 3447 | { | ||
| 3448 | let val_ref = &self.r#band_mode; | ||
| 3449 | if *val_ref != 0 { | ||
| 3450 | encoder.encode_varint32(64u32)?; | ||
| 3451 | encoder.encode_int32(*val_ref as _)?; | ||
| 3452 | } | ||
| 3453 | } | ||
| 3454 | Ok(()) | ||
| 3455 | } | ||
| 3456 | fn compute_size(&self) -> usize { | ||
| 3457 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3458 | let mut size = 0; | ||
| 3459 | { | ||
| 3460 | let val_ref = &self.r#ssid; | ||
| 3461 | if !val_ref.is_empty() { | ||
| 3462 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 3463 | } | ||
| 3464 | } | ||
| 3465 | { | ||
| 3466 | let val_ref = &self.r#pwd; | ||
| 3467 | if !val_ref.is_empty() { | ||
| 3468 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 3469 | } | ||
| 3470 | } | ||
| 3471 | { | ||
| 3472 | let val_ref = &self.r#chnl; | ||
| 3473 | if *val_ref != 0 { | ||
| 3474 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3475 | } | ||
| 3476 | } | ||
| 3477 | { | ||
| 3478 | let val_ref = &self.r#sec_prot; | ||
| 3479 | if val_ref.0 != 0 { | ||
| 3480 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 3481 | } | ||
| 3482 | } | ||
| 3483 | { | ||
| 3484 | let val_ref = &self.r#max_conn; | ||
| 3485 | if *val_ref != 0 { | ||
| 3486 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3487 | } | ||
| 3488 | } | ||
| 3489 | { | ||
| 3490 | let val_ref = &self.r#ssid_hidden; | ||
| 3491 | if *val_ref { | ||
| 3492 | size += 1usize + 1; | ||
| 3493 | } | ||
| 3494 | } | ||
| 3495 | { | ||
| 3496 | let val_ref = &self.r#bw; | ||
| 3497 | if *val_ref != 0 { | ||
| 3498 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3499 | } | ||
| 3500 | } | ||
| 3501 | { | ||
| 3502 | let val_ref = &self.r#band_mode; | ||
| 3503 | if *val_ref != 0 { | ||
| 3504 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3505 | } | ||
| 3506 | } | ||
| 3507 | size | ||
| 3508 | } | ||
| 3509 | } | ||
| 3510 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 231 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3511 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 232 | pub(crate) struct CtrlMsgReqOtaBegin {} | 3512 | pub struct CtrlMsg_Resp_StartSoftAP { |
| 233 | 3513 | pub r#resp: i32, | |
| 234 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 3514 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, |
| 3515 | pub r#band_mode: i32, | ||
| 3516 | } | ||
| 3517 | impl CtrlMsg_Resp_StartSoftAP { | ||
| 3518 | ///Return a reference to `resp` | ||
| 3519 | #[inline] | ||
| 3520 | pub fn r#resp(&self) -> &i32 { | ||
| 3521 | &self.r#resp | ||
| 3522 | } | ||
| 3523 | ///Return a mutable reference to `resp` | ||
| 3524 | #[inline] | ||
| 3525 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 3526 | &mut self.r#resp | ||
| 3527 | } | ||
| 3528 | ///Set the value of `resp` | ||
| 3529 | #[inline] | ||
| 3530 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 3531 | self.r#resp = value.into(); | ||
| 3532 | self | ||
| 3533 | } | ||
| 3534 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 3535 | #[inline] | ||
| 3536 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 3537 | self.r#resp = value.into(); | ||
| 3538 | self | ||
| 3539 | } | ||
| 3540 | ///Return a reference to `mac` | ||
| 3541 | #[inline] | ||
| 3542 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 3543 | &self.r#mac | ||
| 3544 | } | ||
| 3545 | ///Return a mutable reference to `mac` | ||
| 3546 | #[inline] | ||
| 3547 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 3548 | &mut self.r#mac | ||
| 3549 | } | ||
| 3550 | ///Set the value of `mac` | ||
| 3551 | #[inline] | ||
| 3552 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 3553 | self.r#mac = value.into(); | ||
| 3554 | self | ||
| 3555 | } | ||
| 3556 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 3557 | #[inline] | ||
| 3558 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 3559 | self.r#mac = value.into(); | ||
| 3560 | self | ||
| 3561 | } | ||
| 3562 | ///Return a reference to `band_mode` | ||
| 3563 | #[inline] | ||
| 3564 | pub fn r#band_mode(&self) -> &i32 { | ||
| 3565 | &self.r#band_mode | ||
| 3566 | } | ||
| 3567 | ///Return a mutable reference to `band_mode` | ||
| 3568 | #[inline] | ||
| 3569 | pub fn mut_band_mode(&mut self) -> &mut i32 { | ||
| 3570 | &mut self.r#band_mode | ||
| 3571 | } | ||
| 3572 | ///Set the value of `band_mode` | ||
| 3573 | #[inline] | ||
| 3574 | pub fn set_band_mode(&mut self, value: i32) -> &mut Self { | ||
| 3575 | self.r#band_mode = value.into(); | ||
| 3576 | self | ||
| 3577 | } | ||
| 3578 | ///Builder method that sets the value of `band_mode`. Useful for initializing the message. | ||
| 3579 | #[inline] | ||
| 3580 | pub fn init_band_mode(mut self, value: i32) -> Self { | ||
| 3581 | self.r#band_mode = value.into(); | ||
| 3582 | self | ||
| 3583 | } | ||
| 3584 | } | ||
| 3585 | impl ::micropb::MessageDecode for CtrlMsg_Resp_StartSoftAP { | ||
| 3586 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 3587 | &mut self, | ||
| 3588 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 3589 | len: usize, | ||
| 3590 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 3591 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 3592 | let before = decoder.bytes_read(); | ||
| 3593 | while decoder.bytes_read() - before < len { | ||
| 3594 | let tag = decoder.decode_tag()?; | ||
| 3595 | match tag.field_num() { | ||
| 3596 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 3597 | 1u32 => { | ||
| 3598 | let mut_ref = &mut self.r#resp; | ||
| 3599 | { | ||
| 3600 | let val = decoder.decode_int32()?; | ||
| 3601 | let val_ref = &val; | ||
| 3602 | if *val_ref != 0 { | ||
| 3603 | *mut_ref = val as _; | ||
| 3604 | } | ||
| 3605 | }; | ||
| 3606 | } | ||
| 3607 | 2u32 => { | ||
| 3608 | let mut_ref = &mut self.r#mac; | ||
| 3609 | { | ||
| 3610 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 3611 | }; | ||
| 3612 | } | ||
| 3613 | 3u32 => { | ||
| 3614 | let mut_ref = &mut self.r#band_mode; | ||
| 3615 | { | ||
| 3616 | let val = decoder.decode_int32()?; | ||
| 3617 | let val_ref = &val; | ||
| 3618 | if *val_ref != 0 { | ||
| 3619 | *mut_ref = val as _; | ||
| 3620 | } | ||
| 3621 | }; | ||
| 3622 | } | ||
| 3623 | _ => { | ||
| 3624 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 3625 | } | ||
| 3626 | } | ||
| 3627 | } | ||
| 3628 | Ok(()) | ||
| 3629 | } | ||
| 3630 | } | ||
| 3631 | impl ::micropb::MessageEncode for CtrlMsg_Resp_StartSoftAP { | ||
| 3632 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 3633 | let mut max_size = 0; | ||
| 3634 | if let ::core::option::Option::Some(size) = | ||
| 3635 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3636 | { | ||
| 3637 | max_size += size; | ||
| 3638 | } else { | ||
| 3639 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3640 | }; | ||
| 3641 | if let ::core::option::Option::Some(size) = | ||
| 3642 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 3643 | { | ||
| 3644 | max_size += size; | ||
| 3645 | } else { | ||
| 3646 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3647 | }; | ||
| 3648 | if let ::core::option::Option::Some(size) = | ||
| 3649 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3650 | { | ||
| 3651 | max_size += size; | ||
| 3652 | } else { | ||
| 3653 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3654 | }; | ||
| 3655 | ::core::option::Option::Some(max_size) | ||
| 3656 | }; | ||
| 3657 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 3658 | &self, | ||
| 3659 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 3660 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 3661 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3662 | { | ||
| 3663 | let val_ref = &self.r#resp; | ||
| 3664 | if *val_ref != 0 { | ||
| 3665 | encoder.encode_varint32(8u32)?; | ||
| 3666 | encoder.encode_int32(*val_ref as _)?; | ||
| 3667 | } | ||
| 3668 | } | ||
| 3669 | { | ||
| 3670 | let val_ref = &self.r#mac; | ||
| 3671 | if !val_ref.is_empty() { | ||
| 3672 | encoder.encode_varint32(18u32)?; | ||
| 3673 | encoder.encode_bytes(val_ref)?; | ||
| 3674 | } | ||
| 3675 | } | ||
| 3676 | { | ||
| 3677 | let val_ref = &self.r#band_mode; | ||
| 3678 | if *val_ref != 0 { | ||
| 3679 | encoder.encode_varint32(24u32)?; | ||
| 3680 | encoder.encode_int32(*val_ref as _)?; | ||
| 3681 | } | ||
| 3682 | } | ||
| 3683 | Ok(()) | ||
| 3684 | } | ||
| 3685 | fn compute_size(&self) -> usize { | ||
| 3686 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3687 | let mut size = 0; | ||
| 3688 | { | ||
| 3689 | let val_ref = &self.r#resp; | ||
| 3690 | if *val_ref != 0 { | ||
| 3691 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3692 | } | ||
| 3693 | } | ||
| 3694 | { | ||
| 3695 | let val_ref = &self.r#mac; | ||
| 3696 | if !val_ref.is_empty() { | ||
| 3697 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 3698 | } | ||
| 3699 | } | ||
| 3700 | { | ||
| 3701 | let val_ref = &self.r#band_mode; | ||
| 3702 | if *val_ref != 0 { | ||
| 3703 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3704 | } | ||
| 3705 | } | ||
| 3706 | size | ||
| 3707 | } | ||
| 3708 | } | ||
| 3709 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 235 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3710 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 236 | pub(crate) struct CtrlMsgRespOtaBegin { | 3711 | pub struct CtrlMsg_Req_ScanResult {} |
| 237 | #[noproto(tag = "1")] | 3712 | impl CtrlMsg_Req_ScanResult {} |
| 238 | pub resp: u32, | 3713 | impl ::micropb::MessageDecode for CtrlMsg_Req_ScanResult { |
| 3714 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 3715 | &mut self, | ||
| 3716 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 3717 | len: usize, | ||
| 3718 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 3719 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 3720 | let before = decoder.bytes_read(); | ||
| 3721 | while decoder.bytes_read() - before < len { | ||
| 3722 | let tag = decoder.decode_tag()?; | ||
| 3723 | match tag.field_num() { | ||
| 3724 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 3725 | _ => { | ||
| 3726 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 3727 | } | ||
| 3728 | } | ||
| 3729 | } | ||
| 3730 | Ok(()) | ||
| 3731 | } | ||
| 239 | } | 3732 | } |
| 240 | 3733 | impl ::micropb::MessageEncode for CtrlMsg_Req_ScanResult { | |
| 241 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 3734 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 3735 | let mut max_size = 0; | ||
| 3736 | ::core::option::Option::Some(max_size) | ||
| 3737 | }; | ||
| 3738 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 3739 | &self, | ||
| 3740 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 3741 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 3742 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3743 | Ok(()) | ||
| 3744 | } | ||
| 3745 | fn compute_size(&self) -> usize { | ||
| 3746 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3747 | let mut size = 0; | ||
| 3748 | size | ||
| 3749 | } | ||
| 3750 | } | ||
| 3751 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 242 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3752 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 243 | pub(crate) struct CtrlMsgReqOtaWrite { | 3753 | pub struct CtrlMsg_Resp_ScanResult { |
| 244 | #[noproto(tag = "1")] | 3754 | pub r#count: u32, |
| 245 | pub ota_data: Vec<u8, 1024>, | 3755 | pub r#entries: ::micropb::heapless::Vec<ScanResult, 16>, |
| 3756 | pub r#resp: i32, | ||
| 246 | } | 3757 | } |
| 247 | 3758 | impl CtrlMsg_Resp_ScanResult { | |
| 248 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 3759 | ///Return a reference to `count` |
| 3760 | #[inline] | ||
| 3761 | pub fn r#count(&self) -> &u32 { | ||
| 3762 | &self.r#count | ||
| 3763 | } | ||
| 3764 | ///Return a mutable reference to `count` | ||
| 3765 | #[inline] | ||
| 3766 | pub fn mut_count(&mut self) -> &mut u32 { | ||
| 3767 | &mut self.r#count | ||
| 3768 | } | ||
| 3769 | ///Set the value of `count` | ||
| 3770 | #[inline] | ||
| 3771 | pub fn set_count(&mut self, value: u32) -> &mut Self { | ||
| 3772 | self.r#count = value.into(); | ||
| 3773 | self | ||
| 3774 | } | ||
| 3775 | ///Builder method that sets the value of `count`. Useful for initializing the message. | ||
| 3776 | #[inline] | ||
| 3777 | pub fn init_count(mut self, value: u32) -> Self { | ||
| 3778 | self.r#count = value.into(); | ||
| 3779 | self | ||
| 3780 | } | ||
| 3781 | ///Return a reference to `resp` | ||
| 3782 | #[inline] | ||
| 3783 | pub fn r#resp(&self) -> &i32 { | ||
| 3784 | &self.r#resp | ||
| 3785 | } | ||
| 3786 | ///Return a mutable reference to `resp` | ||
| 3787 | #[inline] | ||
| 3788 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 3789 | &mut self.r#resp | ||
| 3790 | } | ||
| 3791 | ///Set the value of `resp` | ||
| 3792 | #[inline] | ||
| 3793 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 3794 | self.r#resp = value.into(); | ||
| 3795 | self | ||
| 3796 | } | ||
| 3797 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 3798 | #[inline] | ||
| 3799 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 3800 | self.r#resp = value.into(); | ||
| 3801 | self | ||
| 3802 | } | ||
| 3803 | } | ||
| 3804 | impl ::micropb::MessageDecode for CtrlMsg_Resp_ScanResult { | ||
| 3805 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 3806 | &mut self, | ||
| 3807 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 3808 | len: usize, | ||
| 3809 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 3810 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 3811 | let before = decoder.bytes_read(); | ||
| 3812 | while decoder.bytes_read() - before < len { | ||
| 3813 | let tag = decoder.decode_tag()?; | ||
| 3814 | match tag.field_num() { | ||
| 3815 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 3816 | 1u32 => { | ||
| 3817 | let mut_ref = &mut self.r#count; | ||
| 3818 | { | ||
| 3819 | let val = decoder.decode_varint32()?; | ||
| 3820 | let val_ref = &val; | ||
| 3821 | if *val_ref != 0 { | ||
| 3822 | *mut_ref = val as _; | ||
| 3823 | } | ||
| 3824 | }; | ||
| 3825 | } | ||
| 3826 | 2u32 => { | ||
| 3827 | let mut val: ScanResult = ::core::default::Default::default(); | ||
| 3828 | let mut_ref = &mut val; | ||
| 3829 | { | ||
| 3830 | mut_ref.decode_len_delimited(decoder)?; | ||
| 3831 | }; | ||
| 3832 | if let (Err(_), false) = (self.r#entries.pb_push(val), decoder.ignore_repeated_cap_err) { | ||
| 3833 | return Err(::micropb::DecodeError::Capacity); | ||
| 3834 | } | ||
| 3835 | } | ||
| 3836 | 3u32 => { | ||
| 3837 | let mut_ref = &mut self.r#resp; | ||
| 3838 | { | ||
| 3839 | let val = decoder.decode_int32()?; | ||
| 3840 | let val_ref = &val; | ||
| 3841 | if *val_ref != 0 { | ||
| 3842 | *mut_ref = val as _; | ||
| 3843 | } | ||
| 3844 | }; | ||
| 3845 | } | ||
| 3846 | _ => { | ||
| 3847 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 3848 | } | ||
| 3849 | } | ||
| 3850 | } | ||
| 3851 | Ok(()) | ||
| 3852 | } | ||
| 3853 | } | ||
| 3854 | impl ::micropb::MessageEncode for CtrlMsg_Resp_ScanResult { | ||
| 3855 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 3856 | let mut max_size = 0; | ||
| 3857 | if let ::core::option::Option::Some(size) = | ||
| 3858 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 3859 | { | ||
| 3860 | max_size += size; | ||
| 3861 | } else { | ||
| 3862 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3863 | }; | ||
| 3864 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 3865 | ::micropb::const_map!(<ScanResult as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 3866 | ::micropb::size::sizeof_len_record(size) | ||
| 3867 | }), | ||
| 3868 | |size| (size + 1usize) * 16usize | ||
| 3869 | ) { | ||
| 3870 | max_size += size; | ||
| 3871 | } else { | ||
| 3872 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3873 | }; | ||
| 3874 | if let ::core::option::Option::Some(size) = | ||
| 3875 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 3876 | { | ||
| 3877 | max_size += size; | ||
| 3878 | } else { | ||
| 3879 | break 'msg (::core::option::Option::<usize>::None); | ||
| 3880 | }; | ||
| 3881 | ::core::option::Option::Some(max_size) | ||
| 3882 | }; | ||
| 3883 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 3884 | &self, | ||
| 3885 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 3886 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 3887 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3888 | { | ||
| 3889 | let val_ref = &self.r#count; | ||
| 3890 | if *val_ref != 0 { | ||
| 3891 | encoder.encode_varint32(8u32)?; | ||
| 3892 | encoder.encode_varint32(*val_ref as _)?; | ||
| 3893 | } | ||
| 3894 | } | ||
| 3895 | { | ||
| 3896 | for val_ref in self.r#entries.iter() { | ||
| 3897 | encoder.encode_varint32(18u32)?; | ||
| 3898 | val_ref.encode_len_delimited(encoder)?; | ||
| 3899 | } | ||
| 3900 | } | ||
| 3901 | { | ||
| 3902 | let val_ref = &self.r#resp; | ||
| 3903 | if *val_ref != 0 { | ||
| 3904 | encoder.encode_varint32(24u32)?; | ||
| 3905 | encoder.encode_int32(*val_ref as _)?; | ||
| 3906 | } | ||
| 3907 | } | ||
| 3908 | Ok(()) | ||
| 3909 | } | ||
| 3910 | fn compute_size(&self) -> usize { | ||
| 3911 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3912 | let mut size = 0; | ||
| 3913 | { | ||
| 3914 | let val_ref = &self.r#count; | ||
| 3915 | if *val_ref != 0 { | ||
| 3916 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 3917 | } | ||
| 3918 | } | ||
| 3919 | { | ||
| 3920 | for val_ref in self.r#entries.iter() { | ||
| 3921 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 3922 | } | ||
| 3923 | } | ||
| 3924 | { | ||
| 3925 | let val_ref = &self.r#resp; | ||
| 3926 | if *val_ref != 0 { | ||
| 3927 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 3928 | } | ||
| 3929 | } | ||
| 3930 | size | ||
| 3931 | } | ||
| 3932 | } | ||
| 3933 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 249 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3934 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 250 | pub(crate) struct CtrlMsgRespOtaWrite { | 3935 | pub struct CtrlMsg_Req_SoftAPConnectedSTA {} |
| 251 | #[noproto(tag = "1")] | 3936 | impl CtrlMsg_Req_SoftAPConnectedSTA {} |
| 252 | pub resp: u32, | 3937 | impl ::micropb::MessageDecode for CtrlMsg_Req_SoftAPConnectedSTA { |
| 3938 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 3939 | &mut self, | ||
| 3940 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 3941 | len: usize, | ||
| 3942 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 3943 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 3944 | let before = decoder.bytes_read(); | ||
| 3945 | while decoder.bytes_read() - before < len { | ||
| 3946 | let tag = decoder.decode_tag()?; | ||
| 3947 | match tag.field_num() { | ||
| 3948 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 3949 | _ => { | ||
| 3950 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 3951 | } | ||
| 3952 | } | ||
| 3953 | } | ||
| 3954 | Ok(()) | ||
| 3955 | } | ||
| 253 | } | 3956 | } |
| 254 | 3957 | impl ::micropb::MessageEncode for CtrlMsg_Req_SoftAPConnectedSTA { | |
| 255 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 3958 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 3959 | let mut max_size = 0; | ||
| 3960 | ::core::option::Option::Some(max_size) | ||
| 3961 | }; | ||
| 3962 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 3963 | &self, | ||
| 3964 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 3965 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 3966 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3967 | Ok(()) | ||
| 3968 | } | ||
| 3969 | fn compute_size(&self) -> usize { | ||
| 3970 | use ::micropb::{FieldEncode, PbMap}; | ||
| 3971 | let mut size = 0; | ||
| 3972 | size | ||
| 3973 | } | ||
| 3974 | } | ||
| 3975 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 256 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 3976 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 257 | pub(crate) struct CtrlMsgReqOtaEnd {} | 3977 | pub struct CtrlMsg_Resp_SoftAPConnectedSTA { |
| 258 | 3978 | pub r#num: u32, | |
| 259 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 3979 | pub r#stations: ::micropb::heapless::Vec<ConnectedSTAList, 16>, |
| 3980 | pub r#resp: i32, | ||
| 3981 | } | ||
| 3982 | impl CtrlMsg_Resp_SoftAPConnectedSTA { | ||
| 3983 | ///Return a reference to `num` | ||
| 3984 | #[inline] | ||
| 3985 | pub fn r#num(&self) -> &u32 { | ||
| 3986 | &self.r#num | ||
| 3987 | } | ||
| 3988 | ///Return a mutable reference to `num` | ||
| 3989 | #[inline] | ||
| 3990 | pub fn mut_num(&mut self) -> &mut u32 { | ||
| 3991 | &mut self.r#num | ||
| 3992 | } | ||
| 3993 | ///Set the value of `num` | ||
| 3994 | #[inline] | ||
| 3995 | pub fn set_num(&mut self, value: u32) -> &mut Self { | ||
| 3996 | self.r#num = value.into(); | ||
| 3997 | self | ||
| 3998 | } | ||
| 3999 | ///Builder method that sets the value of `num`. Useful for initializing the message. | ||
| 4000 | #[inline] | ||
| 4001 | pub fn init_num(mut self, value: u32) -> Self { | ||
| 4002 | self.r#num = value.into(); | ||
| 4003 | self | ||
| 4004 | } | ||
| 4005 | ///Return a reference to `resp` | ||
| 4006 | #[inline] | ||
| 4007 | pub fn r#resp(&self) -> &i32 { | ||
| 4008 | &self.r#resp | ||
| 4009 | } | ||
| 4010 | ///Return a mutable reference to `resp` | ||
| 4011 | #[inline] | ||
| 4012 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 4013 | &mut self.r#resp | ||
| 4014 | } | ||
| 4015 | ///Set the value of `resp` | ||
| 4016 | #[inline] | ||
| 4017 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 4018 | self.r#resp = value.into(); | ||
| 4019 | self | ||
| 4020 | } | ||
| 4021 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 4022 | #[inline] | ||
| 4023 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 4024 | self.r#resp = value.into(); | ||
| 4025 | self | ||
| 4026 | } | ||
| 4027 | } | ||
| 4028 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SoftAPConnectedSTA { | ||
| 4029 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4030 | &mut self, | ||
| 4031 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4032 | len: usize, | ||
| 4033 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4034 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4035 | let before = decoder.bytes_read(); | ||
| 4036 | while decoder.bytes_read() - before < len { | ||
| 4037 | let tag = decoder.decode_tag()?; | ||
| 4038 | match tag.field_num() { | ||
| 4039 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4040 | 1u32 => { | ||
| 4041 | let mut_ref = &mut self.r#num; | ||
| 4042 | { | ||
| 4043 | let val = decoder.decode_varint32()?; | ||
| 4044 | let val_ref = &val; | ||
| 4045 | if *val_ref != 0 { | ||
| 4046 | *mut_ref = val as _; | ||
| 4047 | } | ||
| 4048 | }; | ||
| 4049 | } | ||
| 4050 | 2u32 => { | ||
| 4051 | let mut val: ConnectedSTAList = ::core::default::Default::default(); | ||
| 4052 | let mut_ref = &mut val; | ||
| 4053 | { | ||
| 4054 | mut_ref.decode_len_delimited(decoder)?; | ||
| 4055 | }; | ||
| 4056 | if let (Err(_), false) = (self.r#stations.pb_push(val), decoder.ignore_repeated_cap_err) { | ||
| 4057 | return Err(::micropb::DecodeError::Capacity); | ||
| 4058 | } | ||
| 4059 | } | ||
| 4060 | 3u32 => { | ||
| 4061 | let mut_ref = &mut self.r#resp; | ||
| 4062 | { | ||
| 4063 | let val = decoder.decode_int32()?; | ||
| 4064 | let val_ref = &val; | ||
| 4065 | if *val_ref != 0 { | ||
| 4066 | *mut_ref = val as _; | ||
| 4067 | } | ||
| 4068 | }; | ||
| 4069 | } | ||
| 4070 | _ => { | ||
| 4071 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4072 | } | ||
| 4073 | } | ||
| 4074 | } | ||
| 4075 | Ok(()) | ||
| 4076 | } | ||
| 4077 | } | ||
| 4078 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SoftAPConnectedSTA { | ||
| 4079 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 4080 | let mut max_size = 0; | ||
| 4081 | if let ::core::option::Option::Some(size) = | ||
| 4082 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 4083 | { | ||
| 4084 | max_size += size; | ||
| 4085 | } else { | ||
| 4086 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4087 | }; | ||
| 4088 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 4089 | ::micropb::const_map!(<ConnectedSTAList as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 4090 | ::micropb::size::sizeof_len_record(size) | ||
| 4091 | }), | ||
| 4092 | |size| (size + 1usize) * 16usize | ||
| 4093 | ) { | ||
| 4094 | max_size += size; | ||
| 4095 | } else { | ||
| 4096 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4097 | }; | ||
| 4098 | if let ::core::option::Option::Some(size) = | ||
| 4099 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4100 | { | ||
| 4101 | max_size += size; | ||
| 4102 | } else { | ||
| 4103 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4104 | }; | ||
| 4105 | ::core::option::Option::Some(max_size) | ||
| 4106 | }; | ||
| 4107 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4108 | &self, | ||
| 4109 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4110 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4111 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4112 | { | ||
| 4113 | let val_ref = &self.r#num; | ||
| 4114 | if *val_ref != 0 { | ||
| 4115 | encoder.encode_varint32(8u32)?; | ||
| 4116 | encoder.encode_varint32(*val_ref as _)?; | ||
| 4117 | } | ||
| 4118 | } | ||
| 4119 | { | ||
| 4120 | for val_ref in self.r#stations.iter() { | ||
| 4121 | encoder.encode_varint32(18u32)?; | ||
| 4122 | val_ref.encode_len_delimited(encoder)?; | ||
| 4123 | } | ||
| 4124 | } | ||
| 4125 | { | ||
| 4126 | let val_ref = &self.r#resp; | ||
| 4127 | if *val_ref != 0 { | ||
| 4128 | encoder.encode_varint32(24u32)?; | ||
| 4129 | encoder.encode_int32(*val_ref as _)?; | ||
| 4130 | } | ||
| 4131 | } | ||
| 4132 | Ok(()) | ||
| 4133 | } | ||
| 4134 | fn compute_size(&self) -> usize { | ||
| 4135 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4136 | let mut size = 0; | ||
| 4137 | { | ||
| 4138 | let val_ref = &self.r#num; | ||
| 4139 | if *val_ref != 0 { | ||
| 4140 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 4141 | } | ||
| 4142 | } | ||
| 4143 | { | ||
| 4144 | for val_ref in self.r#stations.iter() { | ||
| 4145 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 4146 | } | ||
| 4147 | } | ||
| 4148 | { | ||
| 4149 | let val_ref = &self.r#resp; | ||
| 4150 | if *val_ref != 0 { | ||
| 4151 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4152 | } | ||
| 4153 | } | ||
| 4154 | size | ||
| 4155 | } | ||
| 4156 | } | ||
| 4157 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 260 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4158 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 261 | pub(crate) struct CtrlMsgRespOtaEnd { | 4159 | pub struct CtrlMsg_Req_OTABegin {} |
| 262 | #[noproto(tag = "1")] | 4160 | impl CtrlMsg_Req_OTABegin {} |
| 263 | pub resp: u32, | 4161 | impl ::micropb::MessageDecode for CtrlMsg_Req_OTABegin { |
| 4162 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4163 | &mut self, | ||
| 4164 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4165 | len: usize, | ||
| 4166 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4167 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4168 | let before = decoder.bytes_read(); | ||
| 4169 | while decoder.bytes_read() - before < len { | ||
| 4170 | let tag = decoder.decode_tag()?; | ||
| 4171 | match tag.field_num() { | ||
| 4172 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4173 | _ => { | ||
| 4174 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4175 | } | ||
| 4176 | } | ||
| 4177 | } | ||
| 4178 | Ok(()) | ||
| 4179 | } | ||
| 264 | } | 4180 | } |
| 265 | 4181 | impl ::micropb::MessageEncode for CtrlMsg_Req_OTABegin { | |
| 266 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4182 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 267 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4183 | let mut max_size = 0; |
| 268 | pub(crate) struct CtrlMsgReqVendorIeData { | 4184 | ::core::option::Option::Some(max_size) |
| 269 | #[noproto(tag = "1")] | 4185 | }; |
| 270 | pub element_id: u32, | 4186 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( |
| 271 | #[noproto(tag = "2")] | 4187 | &self, |
| 272 | pub length: u32, | 4188 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, |
| 273 | #[noproto(tag = "3")] | 4189 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { |
| 274 | pub vendor_oui: Vec<u8, 8>, | 4190 | use ::micropb::{FieldEncode, PbMap}; |
| 275 | #[noproto(tag = "4")] | 4191 | Ok(()) |
| 276 | pub vendor_oui_type: u32, | 4192 | } |
| 277 | #[noproto(tag = "5")] | 4193 | fn compute_size(&self) -> usize { |
| 278 | pub payload: Vec<u8, 64>, | 4194 | use ::micropb::{FieldEncode, PbMap}; |
| 4195 | let mut size = 0; | ||
| 4196 | size | ||
| 4197 | } | ||
| 279 | } | 4198 | } |
| 280 | 4199 | #[derive(Debug, Default, PartialEq, Clone)] | |
| 281 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4200 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 282 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4201 | pub struct CtrlMsg_Resp_OTABegin { |
| 283 | pub(crate) struct CtrlMsgReqSetSoftApVendorSpecificIe { | 4202 | pub r#resp: i32, |
| 284 | #[noproto(tag = "1")] | ||
| 285 | pub enable: bool, | ||
| 286 | #[noproto(tag = "2")] | ||
| 287 | pub r#type: CtrlVendorIeType, | ||
| 288 | #[noproto(tag = "3")] | ||
| 289 | pub idx: CtrlVendorIeid, | ||
| 290 | #[noproto(optional, tag = "4")] | ||
| 291 | pub vendor_ie_data: Option<CtrlMsgReqVendorIeData>, | ||
| 292 | } | 4203 | } |
| 293 | 4204 | impl CtrlMsg_Resp_OTABegin { | |
| 294 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4205 | ///Return a reference to `resp` |
| 4206 | #[inline] | ||
| 4207 | pub fn r#resp(&self) -> &i32 { | ||
| 4208 | &self.r#resp | ||
| 4209 | } | ||
| 4210 | ///Return a mutable reference to `resp` | ||
| 4211 | #[inline] | ||
| 4212 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 4213 | &mut self.r#resp | ||
| 4214 | } | ||
| 4215 | ///Set the value of `resp` | ||
| 4216 | #[inline] | ||
| 4217 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 4218 | self.r#resp = value.into(); | ||
| 4219 | self | ||
| 4220 | } | ||
| 4221 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 4222 | #[inline] | ||
| 4223 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 4224 | self.r#resp = value.into(); | ||
| 4225 | self | ||
| 4226 | } | ||
| 4227 | } | ||
| 4228 | impl ::micropb::MessageDecode for CtrlMsg_Resp_OTABegin { | ||
| 4229 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4230 | &mut self, | ||
| 4231 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4232 | len: usize, | ||
| 4233 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4234 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4235 | let before = decoder.bytes_read(); | ||
| 4236 | while decoder.bytes_read() - before < len { | ||
| 4237 | let tag = decoder.decode_tag()?; | ||
| 4238 | match tag.field_num() { | ||
| 4239 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4240 | 1u32 => { | ||
| 4241 | let mut_ref = &mut self.r#resp; | ||
| 4242 | { | ||
| 4243 | let val = decoder.decode_int32()?; | ||
| 4244 | let val_ref = &val; | ||
| 4245 | if *val_ref != 0 { | ||
| 4246 | *mut_ref = val as _; | ||
| 4247 | } | ||
| 4248 | }; | ||
| 4249 | } | ||
| 4250 | _ => { | ||
| 4251 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4252 | } | ||
| 4253 | } | ||
| 4254 | } | ||
| 4255 | Ok(()) | ||
| 4256 | } | ||
| 4257 | } | ||
| 4258 | impl ::micropb::MessageEncode for CtrlMsg_Resp_OTABegin { | ||
| 4259 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 4260 | let mut max_size = 0; | ||
| 4261 | if let ::core::option::Option::Some(size) = | ||
| 4262 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4263 | { | ||
| 4264 | max_size += size; | ||
| 4265 | } else { | ||
| 4266 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4267 | }; | ||
| 4268 | ::core::option::Option::Some(max_size) | ||
| 4269 | }; | ||
| 4270 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4271 | &self, | ||
| 4272 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4273 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4274 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4275 | { | ||
| 4276 | let val_ref = &self.r#resp; | ||
| 4277 | if *val_ref != 0 { | ||
| 4278 | encoder.encode_varint32(8u32)?; | ||
| 4279 | encoder.encode_int32(*val_ref as _)?; | ||
| 4280 | } | ||
| 4281 | } | ||
| 4282 | Ok(()) | ||
| 4283 | } | ||
| 4284 | fn compute_size(&self) -> usize { | ||
| 4285 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4286 | let mut size = 0; | ||
| 4287 | { | ||
| 4288 | let val_ref = &self.r#resp; | ||
| 4289 | if *val_ref != 0 { | ||
| 4290 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4291 | } | ||
| 4292 | } | ||
| 4293 | size | ||
| 4294 | } | ||
| 4295 | } | ||
| 4296 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 295 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4297 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 296 | pub(crate) struct CtrlMsgRespSetSoftApVendorSpecificIe { | 4298 | pub struct CtrlMsg_Req_OTAWrite { |
| 297 | #[noproto(tag = "1")] | 4299 | pub r#ota_data: ::micropb::heapless::Vec<u8, 1024>, |
| 298 | pub resp: u32, | ||
| 299 | } | 4300 | } |
| 300 | 4301 | impl CtrlMsg_Req_OTAWrite { | |
| 301 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4302 | ///Return a reference to `ota_data` |
| 4303 | #[inline] | ||
| 4304 | pub fn r#ota_data(&self) -> &::micropb::heapless::Vec<u8, 1024> { | ||
| 4305 | &self.r#ota_data | ||
| 4306 | } | ||
| 4307 | ///Return a mutable reference to `ota_data` | ||
| 4308 | #[inline] | ||
| 4309 | pub fn mut_ota_data(&mut self) -> &mut ::micropb::heapless::Vec<u8, 1024> { | ||
| 4310 | &mut self.r#ota_data | ||
| 4311 | } | ||
| 4312 | ///Set the value of `ota_data` | ||
| 4313 | #[inline] | ||
| 4314 | pub fn set_ota_data(&mut self, value: ::micropb::heapless::Vec<u8, 1024>) -> &mut Self { | ||
| 4315 | self.r#ota_data = value.into(); | ||
| 4316 | self | ||
| 4317 | } | ||
| 4318 | ///Builder method that sets the value of `ota_data`. Useful for initializing the message. | ||
| 4319 | #[inline] | ||
| 4320 | pub fn init_ota_data(mut self, value: ::micropb::heapless::Vec<u8, 1024>) -> Self { | ||
| 4321 | self.r#ota_data = value.into(); | ||
| 4322 | self | ||
| 4323 | } | ||
| 4324 | } | ||
| 4325 | impl ::micropb::MessageDecode for CtrlMsg_Req_OTAWrite { | ||
| 4326 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4327 | &mut self, | ||
| 4328 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4329 | len: usize, | ||
| 4330 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4331 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4332 | let before = decoder.bytes_read(); | ||
| 4333 | while decoder.bytes_read() - before < len { | ||
| 4334 | let tag = decoder.decode_tag()?; | ||
| 4335 | match tag.field_num() { | ||
| 4336 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4337 | 1u32 => { | ||
| 4338 | let mut_ref = &mut self.r#ota_data; | ||
| 4339 | { | ||
| 4340 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 4341 | }; | ||
| 4342 | } | ||
| 4343 | _ => { | ||
| 4344 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4345 | } | ||
| 4346 | } | ||
| 4347 | } | ||
| 4348 | Ok(()) | ||
| 4349 | } | ||
| 4350 | } | ||
| 4351 | impl ::micropb::MessageEncode for CtrlMsg_Req_OTAWrite { | ||
| 4352 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 4353 | let mut max_size = 0; | ||
| 4354 | if let ::core::option::Option::Some(size) = | ||
| 4355 | ::micropb::const_map!(::core::option::Option::Some(1026usize), |size| size + 1usize) | ||
| 4356 | { | ||
| 4357 | max_size += size; | ||
| 4358 | } else { | ||
| 4359 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4360 | }; | ||
| 4361 | ::core::option::Option::Some(max_size) | ||
| 4362 | }; | ||
| 4363 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4364 | &self, | ||
| 4365 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4366 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4367 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4368 | { | ||
| 4369 | let val_ref = &self.r#ota_data; | ||
| 4370 | if !val_ref.is_empty() { | ||
| 4371 | encoder.encode_varint32(10u32)?; | ||
| 4372 | encoder.encode_bytes(val_ref)?; | ||
| 4373 | } | ||
| 4374 | } | ||
| 4375 | Ok(()) | ||
| 4376 | } | ||
| 4377 | fn compute_size(&self) -> usize { | ||
| 4378 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4379 | let mut size = 0; | ||
| 4380 | { | ||
| 4381 | let val_ref = &self.r#ota_data; | ||
| 4382 | if !val_ref.is_empty() { | ||
| 4383 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 4384 | } | ||
| 4385 | } | ||
| 4386 | size | ||
| 4387 | } | ||
| 4388 | } | ||
| 4389 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 302 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4390 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 303 | pub(crate) struct CtrlMsgReqSetWifiMaxTxPower { | 4391 | pub struct CtrlMsg_Resp_OTAWrite { |
| 304 | #[noproto(tag = "1")] | 4392 | pub r#resp: i32, |
| 305 | pub wifi_max_tx_power: u32, | ||
| 306 | } | 4393 | } |
| 307 | 4394 | impl CtrlMsg_Resp_OTAWrite { | |
| 308 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4395 | ///Return a reference to `resp` |
| 4396 | #[inline] | ||
| 4397 | pub fn r#resp(&self) -> &i32 { | ||
| 4398 | &self.r#resp | ||
| 4399 | } | ||
| 4400 | ///Return a mutable reference to `resp` | ||
| 4401 | #[inline] | ||
| 4402 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 4403 | &mut self.r#resp | ||
| 4404 | } | ||
| 4405 | ///Set the value of `resp` | ||
| 4406 | #[inline] | ||
| 4407 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 4408 | self.r#resp = value.into(); | ||
| 4409 | self | ||
| 4410 | } | ||
| 4411 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 4412 | #[inline] | ||
| 4413 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 4414 | self.r#resp = value.into(); | ||
| 4415 | self | ||
| 4416 | } | ||
| 4417 | } | ||
| 4418 | impl ::micropb::MessageDecode for CtrlMsg_Resp_OTAWrite { | ||
| 4419 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4420 | &mut self, | ||
| 4421 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4422 | len: usize, | ||
| 4423 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4424 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4425 | let before = decoder.bytes_read(); | ||
| 4426 | while decoder.bytes_read() - before < len { | ||
| 4427 | let tag = decoder.decode_tag()?; | ||
| 4428 | match tag.field_num() { | ||
| 4429 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4430 | 1u32 => { | ||
| 4431 | let mut_ref = &mut self.r#resp; | ||
| 4432 | { | ||
| 4433 | let val = decoder.decode_int32()?; | ||
| 4434 | let val_ref = &val; | ||
| 4435 | if *val_ref != 0 { | ||
| 4436 | *mut_ref = val as _; | ||
| 4437 | } | ||
| 4438 | }; | ||
| 4439 | } | ||
| 4440 | _ => { | ||
| 4441 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4442 | } | ||
| 4443 | } | ||
| 4444 | } | ||
| 4445 | Ok(()) | ||
| 4446 | } | ||
| 4447 | } | ||
| 4448 | impl ::micropb::MessageEncode for CtrlMsg_Resp_OTAWrite { | ||
| 4449 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 4450 | let mut max_size = 0; | ||
| 4451 | if let ::core::option::Option::Some(size) = | ||
| 4452 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4453 | { | ||
| 4454 | max_size += size; | ||
| 4455 | } else { | ||
| 4456 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4457 | }; | ||
| 4458 | ::core::option::Option::Some(max_size) | ||
| 4459 | }; | ||
| 4460 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4461 | &self, | ||
| 4462 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4463 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4464 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4465 | { | ||
| 4466 | let val_ref = &self.r#resp; | ||
| 4467 | if *val_ref != 0 { | ||
| 4468 | encoder.encode_varint32(8u32)?; | ||
| 4469 | encoder.encode_int32(*val_ref as _)?; | ||
| 4470 | } | ||
| 4471 | } | ||
| 4472 | Ok(()) | ||
| 4473 | } | ||
| 4474 | fn compute_size(&self) -> usize { | ||
| 4475 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4476 | let mut size = 0; | ||
| 4477 | { | ||
| 4478 | let val_ref = &self.r#resp; | ||
| 4479 | if *val_ref != 0 { | ||
| 4480 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4481 | } | ||
| 4482 | } | ||
| 4483 | size | ||
| 4484 | } | ||
| 4485 | } | ||
| 4486 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 309 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4487 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 310 | pub(crate) struct CtrlMsgRespSetWifiMaxTxPower { | 4488 | pub struct CtrlMsg_Req_OTAEnd {} |
| 311 | #[noproto(tag = "1")] | 4489 | impl CtrlMsg_Req_OTAEnd {} |
| 312 | pub resp: u32, | 4490 | impl ::micropb::MessageDecode for CtrlMsg_Req_OTAEnd { |
| 4491 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4492 | &mut self, | ||
| 4493 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4494 | len: usize, | ||
| 4495 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4496 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4497 | let before = decoder.bytes_read(); | ||
| 4498 | while decoder.bytes_read() - before < len { | ||
| 4499 | let tag = decoder.decode_tag()?; | ||
| 4500 | match tag.field_num() { | ||
| 4501 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4502 | _ => { | ||
| 4503 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4504 | } | ||
| 4505 | } | ||
| 4506 | } | ||
| 4507 | Ok(()) | ||
| 4508 | } | ||
| 313 | } | 4509 | } |
| 314 | 4510 | impl ::micropb::MessageEncode for CtrlMsg_Req_OTAEnd { | |
| 315 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4511 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 4512 | let mut max_size = 0; | ||
| 4513 | ::core::option::Option::Some(max_size) | ||
| 4514 | }; | ||
| 4515 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4516 | &self, | ||
| 4517 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4518 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4519 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4520 | Ok(()) | ||
| 4521 | } | ||
| 4522 | fn compute_size(&self) -> usize { | ||
| 4523 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4524 | let mut size = 0; | ||
| 4525 | size | ||
| 4526 | } | ||
| 4527 | } | ||
| 4528 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 316 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4529 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 317 | pub(crate) struct CtrlMsgReqGetWifiCurrTxPower {} | 4530 | pub struct CtrlMsg_Resp_OTAEnd { |
| 318 | 4531 | pub r#resp: i32, | |
| 319 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4532 | } |
| 4533 | impl CtrlMsg_Resp_OTAEnd { | ||
| 4534 | ///Return a reference to `resp` | ||
| 4535 | #[inline] | ||
| 4536 | pub fn r#resp(&self) -> &i32 { | ||
| 4537 | &self.r#resp | ||
| 4538 | } | ||
| 4539 | ///Return a mutable reference to `resp` | ||
| 4540 | #[inline] | ||
| 4541 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 4542 | &mut self.r#resp | ||
| 4543 | } | ||
| 4544 | ///Set the value of `resp` | ||
| 4545 | #[inline] | ||
| 4546 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 4547 | self.r#resp = value.into(); | ||
| 4548 | self | ||
| 4549 | } | ||
| 4550 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 4551 | #[inline] | ||
| 4552 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 4553 | self.r#resp = value.into(); | ||
| 4554 | self | ||
| 4555 | } | ||
| 4556 | } | ||
| 4557 | impl ::micropb::MessageDecode for CtrlMsg_Resp_OTAEnd { | ||
| 4558 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4559 | &mut self, | ||
| 4560 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4561 | len: usize, | ||
| 4562 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4563 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4564 | let before = decoder.bytes_read(); | ||
| 4565 | while decoder.bytes_read() - before < len { | ||
| 4566 | let tag = decoder.decode_tag()?; | ||
| 4567 | match tag.field_num() { | ||
| 4568 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4569 | 1u32 => { | ||
| 4570 | let mut_ref = &mut self.r#resp; | ||
| 4571 | { | ||
| 4572 | let val = decoder.decode_int32()?; | ||
| 4573 | let val_ref = &val; | ||
| 4574 | if *val_ref != 0 { | ||
| 4575 | *mut_ref = val as _; | ||
| 4576 | } | ||
| 4577 | }; | ||
| 4578 | } | ||
| 4579 | _ => { | ||
| 4580 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4581 | } | ||
| 4582 | } | ||
| 4583 | } | ||
| 4584 | Ok(()) | ||
| 4585 | } | ||
| 4586 | } | ||
| 4587 | impl ::micropb::MessageEncode for CtrlMsg_Resp_OTAEnd { | ||
| 4588 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 4589 | let mut max_size = 0; | ||
| 4590 | if let ::core::option::Option::Some(size) = | ||
| 4591 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4592 | { | ||
| 4593 | max_size += size; | ||
| 4594 | } else { | ||
| 4595 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4596 | }; | ||
| 4597 | ::core::option::Option::Some(max_size) | ||
| 4598 | }; | ||
| 4599 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4600 | &self, | ||
| 4601 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4602 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4603 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4604 | { | ||
| 4605 | let val_ref = &self.r#resp; | ||
| 4606 | if *val_ref != 0 { | ||
| 4607 | encoder.encode_varint32(8u32)?; | ||
| 4608 | encoder.encode_int32(*val_ref as _)?; | ||
| 4609 | } | ||
| 4610 | } | ||
| 4611 | Ok(()) | ||
| 4612 | } | ||
| 4613 | fn compute_size(&self) -> usize { | ||
| 4614 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4615 | let mut size = 0; | ||
| 4616 | { | ||
| 4617 | let val_ref = &self.r#resp; | ||
| 4618 | if *val_ref != 0 { | ||
| 4619 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4620 | } | ||
| 4621 | } | ||
| 4622 | size | ||
| 4623 | } | ||
| 4624 | } | ||
| 4625 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 320 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4626 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 321 | pub(crate) struct CtrlMsgRespGetWifiCurrTxPower { | 4627 | pub struct CtrlMsg_Req_VendorIEData { |
| 322 | #[noproto(tag = "1")] | 4628 | pub r#element_id: i32, |
| 323 | pub wifi_curr_tx_power: u32, | 4629 | pub r#length: i32, |
| 324 | #[noproto(tag = "2")] | 4630 | pub r#vendor_oui: ::micropb::heapless::Vec<u8, 32>, |
| 325 | pub resp: u32, | 4631 | pub r#vendor_oui_type: i32, |
| 4632 | pub r#payload: ::micropb::heapless::Vec<u8, 64>, | ||
| 326 | } | 4633 | } |
| 327 | 4634 | impl CtrlMsg_Req_VendorIEData { | |
| 328 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4635 | ///Return a reference to `element_id` |
| 4636 | #[inline] | ||
| 4637 | pub fn r#element_id(&self) -> &i32 { | ||
| 4638 | &self.r#element_id | ||
| 4639 | } | ||
| 4640 | ///Return a mutable reference to `element_id` | ||
| 4641 | #[inline] | ||
| 4642 | pub fn mut_element_id(&mut self) -> &mut i32 { | ||
| 4643 | &mut self.r#element_id | ||
| 4644 | } | ||
| 4645 | ///Set the value of `element_id` | ||
| 4646 | #[inline] | ||
| 4647 | pub fn set_element_id(&mut self, value: i32) -> &mut Self { | ||
| 4648 | self.r#element_id = value.into(); | ||
| 4649 | self | ||
| 4650 | } | ||
| 4651 | ///Builder method that sets the value of `element_id`. Useful for initializing the message. | ||
| 4652 | #[inline] | ||
| 4653 | pub fn init_element_id(mut self, value: i32) -> Self { | ||
| 4654 | self.r#element_id = value.into(); | ||
| 4655 | self | ||
| 4656 | } | ||
| 4657 | ///Return a reference to `length` | ||
| 4658 | #[inline] | ||
| 4659 | pub fn r#length(&self) -> &i32 { | ||
| 4660 | &self.r#length | ||
| 4661 | } | ||
| 4662 | ///Return a mutable reference to `length` | ||
| 4663 | #[inline] | ||
| 4664 | pub fn mut_length(&mut self) -> &mut i32 { | ||
| 4665 | &mut self.r#length | ||
| 4666 | } | ||
| 4667 | ///Set the value of `length` | ||
| 4668 | #[inline] | ||
| 4669 | pub fn set_length(&mut self, value: i32) -> &mut Self { | ||
| 4670 | self.r#length = value.into(); | ||
| 4671 | self | ||
| 4672 | } | ||
| 4673 | ///Builder method that sets the value of `length`. Useful for initializing the message. | ||
| 4674 | #[inline] | ||
| 4675 | pub fn init_length(mut self, value: i32) -> Self { | ||
| 4676 | self.r#length = value.into(); | ||
| 4677 | self | ||
| 4678 | } | ||
| 4679 | ///Return a reference to `vendor_oui` | ||
| 4680 | #[inline] | ||
| 4681 | pub fn r#vendor_oui(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 4682 | &self.r#vendor_oui | ||
| 4683 | } | ||
| 4684 | ///Return a mutable reference to `vendor_oui` | ||
| 4685 | #[inline] | ||
| 4686 | pub fn mut_vendor_oui(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 4687 | &mut self.r#vendor_oui | ||
| 4688 | } | ||
| 4689 | ///Set the value of `vendor_oui` | ||
| 4690 | #[inline] | ||
| 4691 | pub fn set_vendor_oui(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 4692 | self.r#vendor_oui = value.into(); | ||
| 4693 | self | ||
| 4694 | } | ||
| 4695 | ///Builder method that sets the value of `vendor_oui`. Useful for initializing the message. | ||
| 4696 | #[inline] | ||
| 4697 | pub fn init_vendor_oui(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 4698 | self.r#vendor_oui = value.into(); | ||
| 4699 | self | ||
| 4700 | } | ||
| 4701 | ///Return a reference to `vendor_oui_type` | ||
| 4702 | #[inline] | ||
| 4703 | pub fn r#vendor_oui_type(&self) -> &i32 { | ||
| 4704 | &self.r#vendor_oui_type | ||
| 4705 | } | ||
| 4706 | ///Return a mutable reference to `vendor_oui_type` | ||
| 4707 | #[inline] | ||
| 4708 | pub fn mut_vendor_oui_type(&mut self) -> &mut i32 { | ||
| 4709 | &mut self.r#vendor_oui_type | ||
| 4710 | } | ||
| 4711 | ///Set the value of `vendor_oui_type` | ||
| 4712 | #[inline] | ||
| 4713 | pub fn set_vendor_oui_type(&mut self, value: i32) -> &mut Self { | ||
| 4714 | self.r#vendor_oui_type = value.into(); | ||
| 4715 | self | ||
| 4716 | } | ||
| 4717 | ///Builder method that sets the value of `vendor_oui_type`. Useful for initializing the message. | ||
| 4718 | #[inline] | ||
| 4719 | pub fn init_vendor_oui_type(mut self, value: i32) -> Self { | ||
| 4720 | self.r#vendor_oui_type = value.into(); | ||
| 4721 | self | ||
| 4722 | } | ||
| 4723 | ///Return a reference to `payload` | ||
| 4724 | #[inline] | ||
| 4725 | pub fn r#payload(&self) -> &::micropb::heapless::Vec<u8, 64> { | ||
| 4726 | &self.r#payload | ||
| 4727 | } | ||
| 4728 | ///Return a mutable reference to `payload` | ||
| 4729 | #[inline] | ||
| 4730 | pub fn mut_payload(&mut self) -> &mut ::micropb::heapless::Vec<u8, 64> { | ||
| 4731 | &mut self.r#payload | ||
| 4732 | } | ||
| 4733 | ///Set the value of `payload` | ||
| 4734 | #[inline] | ||
| 4735 | pub fn set_payload(&mut self, value: ::micropb::heapless::Vec<u8, 64>) -> &mut Self { | ||
| 4736 | self.r#payload = value.into(); | ||
| 4737 | self | ||
| 4738 | } | ||
| 4739 | ///Builder method that sets the value of `payload`. Useful for initializing the message. | ||
| 4740 | #[inline] | ||
| 4741 | pub fn init_payload(mut self, value: ::micropb::heapless::Vec<u8, 64>) -> Self { | ||
| 4742 | self.r#payload = value.into(); | ||
| 4743 | self | ||
| 4744 | } | ||
| 4745 | } | ||
| 4746 | impl ::micropb::MessageDecode for CtrlMsg_Req_VendorIEData { | ||
| 4747 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 4748 | &mut self, | ||
| 4749 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 4750 | len: usize, | ||
| 4751 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 4752 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 4753 | let before = decoder.bytes_read(); | ||
| 4754 | while decoder.bytes_read() - before < len { | ||
| 4755 | let tag = decoder.decode_tag()?; | ||
| 4756 | match tag.field_num() { | ||
| 4757 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 4758 | 1u32 => { | ||
| 4759 | let mut_ref = &mut self.r#element_id; | ||
| 4760 | { | ||
| 4761 | let val = decoder.decode_int32()?; | ||
| 4762 | let val_ref = &val; | ||
| 4763 | if *val_ref != 0 { | ||
| 4764 | *mut_ref = val as _; | ||
| 4765 | } | ||
| 4766 | }; | ||
| 4767 | } | ||
| 4768 | 2u32 => { | ||
| 4769 | let mut_ref = &mut self.r#length; | ||
| 4770 | { | ||
| 4771 | let val = decoder.decode_int32()?; | ||
| 4772 | let val_ref = &val; | ||
| 4773 | if *val_ref != 0 { | ||
| 4774 | *mut_ref = val as _; | ||
| 4775 | } | ||
| 4776 | }; | ||
| 4777 | } | ||
| 4778 | 3u32 => { | ||
| 4779 | let mut_ref = &mut self.r#vendor_oui; | ||
| 4780 | { | ||
| 4781 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 4782 | }; | ||
| 4783 | } | ||
| 4784 | 4u32 => { | ||
| 4785 | let mut_ref = &mut self.r#vendor_oui_type; | ||
| 4786 | { | ||
| 4787 | let val = decoder.decode_int32()?; | ||
| 4788 | let val_ref = &val; | ||
| 4789 | if *val_ref != 0 { | ||
| 4790 | *mut_ref = val as _; | ||
| 4791 | } | ||
| 4792 | }; | ||
| 4793 | } | ||
| 4794 | 5u32 => { | ||
| 4795 | let mut_ref = &mut self.r#payload; | ||
| 4796 | { | ||
| 4797 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 4798 | }; | ||
| 4799 | } | ||
| 4800 | _ => { | ||
| 4801 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 4802 | } | ||
| 4803 | } | ||
| 4804 | } | ||
| 4805 | Ok(()) | ||
| 4806 | } | ||
| 4807 | } | ||
| 4808 | impl ::micropb::MessageEncode for CtrlMsg_Req_VendorIEData { | ||
| 4809 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 4810 | let mut max_size = 0; | ||
| 4811 | if let ::core::option::Option::Some(size) = | ||
| 4812 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4813 | { | ||
| 4814 | max_size += size; | ||
| 4815 | } else { | ||
| 4816 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4817 | }; | ||
| 4818 | if let ::core::option::Option::Some(size) = | ||
| 4819 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4820 | { | ||
| 4821 | max_size += size; | ||
| 4822 | } else { | ||
| 4823 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4824 | }; | ||
| 4825 | if let ::core::option::Option::Some(size) = | ||
| 4826 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 4827 | { | ||
| 4828 | max_size += size; | ||
| 4829 | } else { | ||
| 4830 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4831 | }; | ||
| 4832 | if let ::core::option::Option::Some(size) = | ||
| 4833 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 4834 | { | ||
| 4835 | max_size += size; | ||
| 4836 | } else { | ||
| 4837 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4838 | }; | ||
| 4839 | if let ::core::option::Option::Some(size) = | ||
| 4840 | ::micropb::const_map!(::core::option::Option::Some(65usize), |size| size + 1usize) | ||
| 4841 | { | ||
| 4842 | max_size += size; | ||
| 4843 | } else { | ||
| 4844 | break 'msg (::core::option::Option::<usize>::None); | ||
| 4845 | }; | ||
| 4846 | ::core::option::Option::Some(max_size) | ||
| 4847 | }; | ||
| 4848 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 4849 | &self, | ||
| 4850 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 4851 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 4852 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4853 | { | ||
| 4854 | let val_ref = &self.r#element_id; | ||
| 4855 | if *val_ref != 0 { | ||
| 4856 | encoder.encode_varint32(8u32)?; | ||
| 4857 | encoder.encode_int32(*val_ref as _)?; | ||
| 4858 | } | ||
| 4859 | } | ||
| 4860 | { | ||
| 4861 | let val_ref = &self.r#length; | ||
| 4862 | if *val_ref != 0 { | ||
| 4863 | encoder.encode_varint32(16u32)?; | ||
| 4864 | encoder.encode_int32(*val_ref as _)?; | ||
| 4865 | } | ||
| 4866 | } | ||
| 4867 | { | ||
| 4868 | let val_ref = &self.r#vendor_oui; | ||
| 4869 | if !val_ref.is_empty() { | ||
| 4870 | encoder.encode_varint32(26u32)?; | ||
| 4871 | encoder.encode_bytes(val_ref)?; | ||
| 4872 | } | ||
| 4873 | } | ||
| 4874 | { | ||
| 4875 | let val_ref = &self.r#vendor_oui_type; | ||
| 4876 | if *val_ref != 0 { | ||
| 4877 | encoder.encode_varint32(32u32)?; | ||
| 4878 | encoder.encode_int32(*val_ref as _)?; | ||
| 4879 | } | ||
| 4880 | } | ||
| 4881 | { | ||
| 4882 | let val_ref = &self.r#payload; | ||
| 4883 | if !val_ref.is_empty() { | ||
| 4884 | encoder.encode_varint32(42u32)?; | ||
| 4885 | encoder.encode_bytes(val_ref)?; | ||
| 4886 | } | ||
| 4887 | } | ||
| 4888 | Ok(()) | ||
| 4889 | } | ||
| 4890 | fn compute_size(&self) -> usize { | ||
| 4891 | use ::micropb::{FieldEncode, PbMap}; | ||
| 4892 | let mut size = 0; | ||
| 4893 | { | ||
| 4894 | let val_ref = &self.r#element_id; | ||
| 4895 | if *val_ref != 0 { | ||
| 4896 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4897 | } | ||
| 4898 | } | ||
| 4899 | { | ||
| 4900 | let val_ref = &self.r#length; | ||
| 4901 | if *val_ref != 0 { | ||
| 4902 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4903 | } | ||
| 4904 | } | ||
| 4905 | { | ||
| 4906 | let val_ref = &self.r#vendor_oui; | ||
| 4907 | if !val_ref.is_empty() { | ||
| 4908 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 4909 | } | ||
| 4910 | } | ||
| 4911 | { | ||
| 4912 | let val_ref = &self.r#vendor_oui_type; | ||
| 4913 | if *val_ref != 0 { | ||
| 4914 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 4915 | } | ||
| 4916 | } | ||
| 4917 | { | ||
| 4918 | let val_ref = &self.r#payload; | ||
| 4919 | if !val_ref.is_empty() { | ||
| 4920 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 4921 | } | ||
| 4922 | } | ||
| 4923 | size | ||
| 4924 | } | ||
| 4925 | } | ||
| 4926 | pub mod CtrlMsg_Req_SetSoftAPVendorSpecificIE_ { | ||
| 4927 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 4928 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 4929 | pub struct _Hazzer([u8; 1]); | ||
| 4930 | impl _Hazzer { | ||
| 4931 | ///New hazzer with all fields set to off | ||
| 4932 | #[inline] | ||
| 4933 | pub const fn _new() -> Self { | ||
| 4934 | Self([0; 1]) | ||
| 4935 | } | ||
| 4936 | ///Query presence of `vendor_ie_data` | ||
| 4937 | #[inline] | ||
| 4938 | pub const fn r#vendor_ie_data(&self) -> bool { | ||
| 4939 | (self.0[0] & 1) != 0 | ||
| 4940 | } | ||
| 4941 | ///Set presence of `vendor_ie_data` | ||
| 4942 | #[inline] | ||
| 4943 | pub const fn set_vendor_ie_data(&mut self) -> &mut Self { | ||
| 4944 | let elem = &mut self.0[0]; | ||
| 4945 | *elem |= 1; | ||
| 4946 | self | ||
| 4947 | } | ||
| 4948 | ///Clear presence of `vendor_ie_data` | ||
| 4949 | #[inline] | ||
| 4950 | pub const fn clear_vendor_ie_data(&mut self) -> &mut Self { | ||
| 4951 | let elem = &mut self.0[0]; | ||
| 4952 | *elem &= !1; | ||
| 4953 | self | ||
| 4954 | } | ||
| 4955 | ///Builder method that sets the presence of `vendor_ie_data`. Useful for initializing the Hazzer. | ||
| 4956 | #[inline] | ||
| 4957 | pub const fn init_vendor_ie_data(mut self) -> Self { | ||
| 4958 | self.set_vendor_ie_data(); | ||
| 4959 | self | ||
| 4960 | } | ||
| 4961 | } | ||
| 4962 | } | ||
| 4963 | #[derive(Debug, Default, Clone)] | ||
| 329 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 4964 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 330 | pub(crate) struct CtrlMsgReqConfigHeartbeat { | 4965 | pub struct CtrlMsg_Req_SetSoftAPVendorSpecificIE { |
| 331 | #[noproto(tag = "1")] | 4966 | pub r#enable: bool, |
| 332 | pub enable: bool, | 4967 | pub r#type: Ctrl_VendorIEType, |
| 333 | #[noproto(tag = "2")] | 4968 | pub r#idx: Ctrl_VendorIEID, |
| 334 | pub duration: u32, | 4969 | pub r#vendor_ie_data: CtrlMsg_Req_VendorIEData, |
| 4970 | pub _has: CtrlMsg_Req_SetSoftAPVendorSpecificIE_::_Hazzer, | ||
| 335 | } | 4971 | } |
| 336 | 4972 | impl ::core::cmp::PartialEq for CtrlMsg_Req_SetSoftAPVendorSpecificIE { | |
| 337 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 4973 | fn eq(&self, other: &Self) -> bool { |
| 4974 | let mut ret = true; | ||
| 4975 | ret &= (self.r#enable == other.r#enable); | ||
| 4976 | ret &= (self.r#type == other.r#type); | ||
| 4977 | ret &= (self.r#idx == other.r#idx); | ||
| 4978 | ret &= (self.r#vendor_ie_data() == other.r#vendor_ie_data()); | ||
| 4979 | ret | ||
| 4980 | } | ||
| 4981 | } | ||
| 4982 | impl CtrlMsg_Req_SetSoftAPVendorSpecificIE { | ||
| 4983 | ///Return a reference to `enable` | ||
| 4984 | #[inline] | ||
| 4985 | pub fn r#enable(&self) -> &bool { | ||
| 4986 | &self.r#enable | ||
| 4987 | } | ||
| 4988 | ///Return a mutable reference to `enable` | ||
| 4989 | #[inline] | ||
| 4990 | pub fn mut_enable(&mut self) -> &mut bool { | ||
| 4991 | &mut self.r#enable | ||
| 4992 | } | ||
| 4993 | ///Set the value of `enable` | ||
| 4994 | #[inline] | ||
| 4995 | pub fn set_enable(&mut self, value: bool) -> &mut Self { | ||
| 4996 | self.r#enable = value.into(); | ||
| 4997 | self | ||
| 4998 | } | ||
| 4999 | ///Builder method that sets the value of `enable`. Useful for initializing the message. | ||
| 5000 | #[inline] | ||
| 5001 | pub fn init_enable(mut self, value: bool) -> Self { | ||
| 5002 | self.r#enable = value.into(); | ||
| 5003 | self | ||
| 5004 | } | ||
| 5005 | ///Return a reference to `type` | ||
| 5006 | #[inline] | ||
| 5007 | pub fn r#type(&self) -> &Ctrl_VendorIEType { | ||
| 5008 | &self.r#type | ||
| 5009 | } | ||
| 5010 | ///Return a mutable reference to `type` | ||
| 5011 | #[inline] | ||
| 5012 | pub fn mut_type(&mut self) -> &mut Ctrl_VendorIEType { | ||
| 5013 | &mut self.r#type | ||
| 5014 | } | ||
| 5015 | ///Set the value of `type` | ||
| 5016 | #[inline] | ||
| 5017 | pub fn set_type(&mut self, value: Ctrl_VendorIEType) -> &mut Self { | ||
| 5018 | self.r#type = value.into(); | ||
| 5019 | self | ||
| 5020 | } | ||
| 5021 | ///Builder method that sets the value of `type`. Useful for initializing the message. | ||
| 5022 | #[inline] | ||
| 5023 | pub fn init_type(mut self, value: Ctrl_VendorIEType) -> Self { | ||
| 5024 | self.r#type = value.into(); | ||
| 5025 | self | ||
| 5026 | } | ||
| 5027 | ///Return a reference to `idx` | ||
| 5028 | #[inline] | ||
| 5029 | pub fn r#idx(&self) -> &Ctrl_VendorIEID { | ||
| 5030 | &self.r#idx | ||
| 5031 | } | ||
| 5032 | ///Return a mutable reference to `idx` | ||
| 5033 | #[inline] | ||
| 5034 | pub fn mut_idx(&mut self) -> &mut Ctrl_VendorIEID { | ||
| 5035 | &mut self.r#idx | ||
| 5036 | } | ||
| 5037 | ///Set the value of `idx` | ||
| 5038 | #[inline] | ||
| 5039 | pub fn set_idx(&mut self, value: Ctrl_VendorIEID) -> &mut Self { | ||
| 5040 | self.r#idx = value.into(); | ||
| 5041 | self | ||
| 5042 | } | ||
| 5043 | ///Builder method that sets the value of `idx`. Useful for initializing the message. | ||
| 5044 | #[inline] | ||
| 5045 | pub fn init_idx(mut self, value: Ctrl_VendorIEID) -> Self { | ||
| 5046 | self.r#idx = value.into(); | ||
| 5047 | self | ||
| 5048 | } | ||
| 5049 | ///Return a reference to `vendor_ie_data` as an `Option` | ||
| 5050 | #[inline] | ||
| 5051 | pub fn r#vendor_ie_data(&self) -> ::core::option::Option<&CtrlMsg_Req_VendorIEData> { | ||
| 5052 | self._has.r#vendor_ie_data().then_some(&self.r#vendor_ie_data) | ||
| 5053 | } | ||
| 5054 | ///Set the value and presence of `vendor_ie_data` | ||
| 5055 | #[inline] | ||
| 5056 | pub fn set_vendor_ie_data(&mut self, value: CtrlMsg_Req_VendorIEData) -> &mut Self { | ||
| 5057 | self._has.set_vendor_ie_data(); | ||
| 5058 | self.r#vendor_ie_data = value.into(); | ||
| 5059 | self | ||
| 5060 | } | ||
| 5061 | ///Return a mutable reference to `vendor_ie_data` as an `Option` | ||
| 5062 | #[inline] | ||
| 5063 | pub fn mut_vendor_ie_data(&mut self) -> ::core::option::Option<&mut CtrlMsg_Req_VendorIEData> { | ||
| 5064 | self._has.r#vendor_ie_data().then_some(&mut self.r#vendor_ie_data) | ||
| 5065 | } | ||
| 5066 | ///Clear the presence of `vendor_ie_data` | ||
| 5067 | #[inline] | ||
| 5068 | pub fn clear_vendor_ie_data(&mut self) -> &mut Self { | ||
| 5069 | self._has.clear_vendor_ie_data(); | ||
| 5070 | self | ||
| 5071 | } | ||
| 5072 | ///Take the value of `vendor_ie_data` and clear its presence | ||
| 5073 | #[inline] | ||
| 5074 | pub fn take_vendor_ie_data(&mut self) -> ::core::option::Option<CtrlMsg_Req_VendorIEData> { | ||
| 5075 | let val = self | ||
| 5076 | ._has | ||
| 5077 | .r#vendor_ie_data() | ||
| 5078 | .then(|| ::core::mem::take(&mut self.r#vendor_ie_data)); | ||
| 5079 | self._has.clear_vendor_ie_data(); | ||
| 5080 | val | ||
| 5081 | } | ||
| 5082 | ///Builder method that sets the value of `vendor_ie_data`. Useful for initializing the message. | ||
| 5083 | #[inline] | ||
| 5084 | pub fn init_vendor_ie_data(mut self, value: CtrlMsg_Req_VendorIEData) -> Self { | ||
| 5085 | self.set_vendor_ie_data(value); | ||
| 5086 | self | ||
| 5087 | } | ||
| 5088 | } | ||
| 5089 | impl ::micropb::MessageDecode for CtrlMsg_Req_SetSoftAPVendorSpecificIE { | ||
| 5090 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5091 | &mut self, | ||
| 5092 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5093 | len: usize, | ||
| 5094 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5095 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5096 | let before = decoder.bytes_read(); | ||
| 5097 | while decoder.bytes_read() - before < len { | ||
| 5098 | let tag = decoder.decode_tag()?; | ||
| 5099 | match tag.field_num() { | ||
| 5100 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5101 | 1u32 => { | ||
| 5102 | let mut_ref = &mut self.r#enable; | ||
| 5103 | { | ||
| 5104 | let val = decoder.decode_bool()?; | ||
| 5105 | let val_ref = &val; | ||
| 5106 | if *val_ref { | ||
| 5107 | *mut_ref = val as _; | ||
| 5108 | } | ||
| 5109 | }; | ||
| 5110 | } | ||
| 5111 | 2u32 => { | ||
| 5112 | let mut_ref = &mut self.r#type; | ||
| 5113 | { | ||
| 5114 | let val = decoder.decode_int32().map(|n| Ctrl_VendorIEType(n as _))?; | ||
| 5115 | let val_ref = &val; | ||
| 5116 | if val_ref.0 != 0 { | ||
| 5117 | *mut_ref = val as _; | ||
| 5118 | } | ||
| 5119 | }; | ||
| 5120 | } | ||
| 5121 | 3u32 => { | ||
| 5122 | let mut_ref = &mut self.r#idx; | ||
| 5123 | { | ||
| 5124 | let val = decoder.decode_int32().map(|n| Ctrl_VendorIEID(n as _))?; | ||
| 5125 | let val_ref = &val; | ||
| 5126 | if val_ref.0 != 0 { | ||
| 5127 | *mut_ref = val as _; | ||
| 5128 | } | ||
| 5129 | }; | ||
| 5130 | } | ||
| 5131 | 4u32 => { | ||
| 5132 | let mut_ref = &mut self.r#vendor_ie_data; | ||
| 5133 | { | ||
| 5134 | mut_ref.decode_len_delimited(decoder)?; | ||
| 5135 | }; | ||
| 5136 | self._has.set_vendor_ie_data(); | ||
| 5137 | } | ||
| 5138 | _ => { | ||
| 5139 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5140 | } | ||
| 5141 | } | ||
| 5142 | } | ||
| 5143 | Ok(()) | ||
| 5144 | } | ||
| 5145 | } | ||
| 5146 | impl ::micropb::MessageEncode for CtrlMsg_Req_SetSoftAPVendorSpecificIE { | ||
| 5147 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 5148 | let mut max_size = 0; | ||
| 5149 | if let ::core::option::Option::Some(size) = | ||
| 5150 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 5151 | { | ||
| 5152 | max_size += size; | ||
| 5153 | } else { | ||
| 5154 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5155 | }; | ||
| 5156 | if let ::core::option::Option::Some(size) = | ||
| 5157 | ::micropb::const_map!(::core::option::Option::Some(Ctrl_VendorIEType::_MAX_SIZE), |size| size | ||
| 5158 | + 1usize) | ||
| 5159 | { | ||
| 5160 | max_size += size; | ||
| 5161 | } else { | ||
| 5162 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5163 | }; | ||
| 5164 | if let ::core::option::Option::Some(size) = | ||
| 5165 | ::micropb::const_map!(::core::option::Option::Some(Ctrl_VendorIEID::_MAX_SIZE), |size| size | ||
| 5166 | + 1usize) | ||
| 5167 | { | ||
| 5168 | max_size += size; | ||
| 5169 | } else { | ||
| 5170 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5171 | }; | ||
| 5172 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 5173 | ::micropb::const_map!( | ||
| 5174 | <CtrlMsg_Req_VendorIEData as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 5175 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 5176 | ), | ||
| 5177 | |size| size + 1usize | ||
| 5178 | ) { | ||
| 5179 | max_size += size; | ||
| 5180 | } else { | ||
| 5181 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5182 | }; | ||
| 5183 | ::core::option::Option::Some(max_size) | ||
| 5184 | }; | ||
| 5185 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5186 | &self, | ||
| 5187 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5188 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5189 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5190 | { | ||
| 5191 | let val_ref = &self.r#enable; | ||
| 5192 | if *val_ref { | ||
| 5193 | encoder.encode_varint32(8u32)?; | ||
| 5194 | encoder.encode_bool(*val_ref)?; | ||
| 5195 | } | ||
| 5196 | } | ||
| 5197 | { | ||
| 5198 | let val_ref = &self.r#type; | ||
| 5199 | if val_ref.0 != 0 { | ||
| 5200 | encoder.encode_varint32(16u32)?; | ||
| 5201 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 5202 | } | ||
| 5203 | } | ||
| 5204 | { | ||
| 5205 | let val_ref = &self.r#idx; | ||
| 5206 | if val_ref.0 != 0 { | ||
| 5207 | encoder.encode_varint32(24u32)?; | ||
| 5208 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 5209 | } | ||
| 5210 | } | ||
| 5211 | { | ||
| 5212 | if let ::core::option::Option::Some(val_ref) = self.r#vendor_ie_data() { | ||
| 5213 | encoder.encode_varint32(34u32)?; | ||
| 5214 | val_ref.encode_len_delimited(encoder)?; | ||
| 5215 | } | ||
| 5216 | } | ||
| 5217 | Ok(()) | ||
| 5218 | } | ||
| 5219 | fn compute_size(&self) -> usize { | ||
| 5220 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5221 | let mut size = 0; | ||
| 5222 | { | ||
| 5223 | let val_ref = &self.r#enable; | ||
| 5224 | if *val_ref { | ||
| 5225 | size += 1usize + 1; | ||
| 5226 | } | ||
| 5227 | } | ||
| 5228 | { | ||
| 5229 | let val_ref = &self.r#type; | ||
| 5230 | if val_ref.0 != 0 { | ||
| 5231 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 5232 | } | ||
| 5233 | } | ||
| 5234 | { | ||
| 5235 | let val_ref = &self.r#idx; | ||
| 5236 | if val_ref.0 != 0 { | ||
| 5237 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 5238 | } | ||
| 5239 | } | ||
| 5240 | { | ||
| 5241 | if let ::core::option::Option::Some(val_ref) = self.r#vendor_ie_data() { | ||
| 5242 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 5243 | } | ||
| 5244 | } | ||
| 5245 | size | ||
| 5246 | } | ||
| 5247 | } | ||
| 5248 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 338 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5249 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 339 | pub(crate) struct CtrlMsgRespConfigHeartbeat { | 5250 | pub struct CtrlMsg_Resp_SetSoftAPVendorSpecificIE { |
| 340 | #[noproto(tag = "1")] | 5251 | pub r#resp: i32, |
| 341 | pub resp: u32, | ||
| 342 | } | 5252 | } |
| 343 | /// * Event structure * | 5253 | impl CtrlMsg_Resp_SetSoftAPVendorSpecificIE { |
| 344 | 5254 | ///Return a reference to `resp` | |
| 345 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 5255 | #[inline] |
| 5256 | pub fn r#resp(&self) -> &i32 { | ||
| 5257 | &self.r#resp | ||
| 5258 | } | ||
| 5259 | ///Return a mutable reference to `resp` | ||
| 5260 | #[inline] | ||
| 5261 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 5262 | &mut self.r#resp | ||
| 5263 | } | ||
| 5264 | ///Set the value of `resp` | ||
| 5265 | #[inline] | ||
| 5266 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 5267 | self.r#resp = value.into(); | ||
| 5268 | self | ||
| 5269 | } | ||
| 5270 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 5271 | #[inline] | ||
| 5272 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 5273 | self.r#resp = value.into(); | ||
| 5274 | self | ||
| 5275 | } | ||
| 5276 | } | ||
| 5277 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SetSoftAPVendorSpecificIE { | ||
| 5278 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5279 | &mut self, | ||
| 5280 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5281 | len: usize, | ||
| 5282 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5283 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5284 | let before = decoder.bytes_read(); | ||
| 5285 | while decoder.bytes_read() - before < len { | ||
| 5286 | let tag = decoder.decode_tag()?; | ||
| 5287 | match tag.field_num() { | ||
| 5288 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5289 | 1u32 => { | ||
| 5290 | let mut_ref = &mut self.r#resp; | ||
| 5291 | { | ||
| 5292 | let val = decoder.decode_int32()?; | ||
| 5293 | let val_ref = &val; | ||
| 5294 | if *val_ref != 0 { | ||
| 5295 | *mut_ref = val as _; | ||
| 5296 | } | ||
| 5297 | }; | ||
| 5298 | } | ||
| 5299 | _ => { | ||
| 5300 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5301 | } | ||
| 5302 | } | ||
| 5303 | } | ||
| 5304 | Ok(()) | ||
| 5305 | } | ||
| 5306 | } | ||
| 5307 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SetSoftAPVendorSpecificIE { | ||
| 5308 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 5309 | let mut max_size = 0; | ||
| 5310 | if let ::core::option::Option::Some(size) = | ||
| 5311 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 5312 | { | ||
| 5313 | max_size += size; | ||
| 5314 | } else { | ||
| 5315 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5316 | }; | ||
| 5317 | ::core::option::Option::Some(max_size) | ||
| 5318 | }; | ||
| 5319 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5320 | &self, | ||
| 5321 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5322 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5323 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5324 | { | ||
| 5325 | let val_ref = &self.r#resp; | ||
| 5326 | if *val_ref != 0 { | ||
| 5327 | encoder.encode_varint32(8u32)?; | ||
| 5328 | encoder.encode_int32(*val_ref as _)?; | ||
| 5329 | } | ||
| 5330 | } | ||
| 5331 | Ok(()) | ||
| 5332 | } | ||
| 5333 | fn compute_size(&self) -> usize { | ||
| 5334 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5335 | let mut size = 0; | ||
| 5336 | { | ||
| 5337 | let val_ref = &self.r#resp; | ||
| 5338 | if *val_ref != 0 { | ||
| 5339 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5340 | } | ||
| 5341 | } | ||
| 5342 | size | ||
| 5343 | } | ||
| 5344 | } | ||
| 5345 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 346 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5346 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 347 | pub(crate) struct CtrlMsgEventEspInit { | 5347 | pub struct CtrlMsg_Req_SetWifiMaxTxPower { |
| 348 | #[noproto(tag = "1")] | 5348 | pub r#wifi_max_tx_power: i32, |
| 349 | pub init_data: Vec<u8, 64>, | ||
| 350 | } | 5349 | } |
| 351 | 5350 | impl CtrlMsg_Req_SetWifiMaxTxPower { | |
| 352 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 5351 | ///Return a reference to `wifi_max_tx_power` |
| 5352 | #[inline] | ||
| 5353 | pub fn r#wifi_max_tx_power(&self) -> &i32 { | ||
| 5354 | &self.r#wifi_max_tx_power | ||
| 5355 | } | ||
| 5356 | ///Return a mutable reference to `wifi_max_tx_power` | ||
| 5357 | #[inline] | ||
| 5358 | pub fn mut_wifi_max_tx_power(&mut self) -> &mut i32 { | ||
| 5359 | &mut self.r#wifi_max_tx_power | ||
| 5360 | } | ||
| 5361 | ///Set the value of `wifi_max_tx_power` | ||
| 5362 | #[inline] | ||
| 5363 | pub fn set_wifi_max_tx_power(&mut self, value: i32) -> &mut Self { | ||
| 5364 | self.r#wifi_max_tx_power = value.into(); | ||
| 5365 | self | ||
| 5366 | } | ||
| 5367 | ///Builder method that sets the value of `wifi_max_tx_power`. Useful for initializing the message. | ||
| 5368 | #[inline] | ||
| 5369 | pub fn init_wifi_max_tx_power(mut self, value: i32) -> Self { | ||
| 5370 | self.r#wifi_max_tx_power = value.into(); | ||
| 5371 | self | ||
| 5372 | } | ||
| 5373 | } | ||
| 5374 | impl ::micropb::MessageDecode for CtrlMsg_Req_SetWifiMaxTxPower { | ||
| 5375 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5376 | &mut self, | ||
| 5377 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5378 | len: usize, | ||
| 5379 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5380 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5381 | let before = decoder.bytes_read(); | ||
| 5382 | while decoder.bytes_read() - before < len { | ||
| 5383 | let tag = decoder.decode_tag()?; | ||
| 5384 | match tag.field_num() { | ||
| 5385 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5386 | 1u32 => { | ||
| 5387 | let mut_ref = &mut self.r#wifi_max_tx_power; | ||
| 5388 | { | ||
| 5389 | let val = decoder.decode_int32()?; | ||
| 5390 | let val_ref = &val; | ||
| 5391 | if *val_ref != 0 { | ||
| 5392 | *mut_ref = val as _; | ||
| 5393 | } | ||
| 5394 | }; | ||
| 5395 | } | ||
| 5396 | _ => { | ||
| 5397 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5398 | } | ||
| 5399 | } | ||
| 5400 | } | ||
| 5401 | Ok(()) | ||
| 5402 | } | ||
| 5403 | } | ||
| 5404 | impl ::micropb::MessageEncode for CtrlMsg_Req_SetWifiMaxTxPower { | ||
| 5405 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 5406 | let mut max_size = 0; | ||
| 5407 | if let ::core::option::Option::Some(size) = | ||
| 5408 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 5409 | { | ||
| 5410 | max_size += size; | ||
| 5411 | } else { | ||
| 5412 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5413 | }; | ||
| 5414 | ::core::option::Option::Some(max_size) | ||
| 5415 | }; | ||
| 5416 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5417 | &self, | ||
| 5418 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5419 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5420 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5421 | { | ||
| 5422 | let val_ref = &self.r#wifi_max_tx_power; | ||
| 5423 | if *val_ref != 0 { | ||
| 5424 | encoder.encode_varint32(8u32)?; | ||
| 5425 | encoder.encode_int32(*val_ref as _)?; | ||
| 5426 | } | ||
| 5427 | } | ||
| 5428 | Ok(()) | ||
| 5429 | } | ||
| 5430 | fn compute_size(&self) -> usize { | ||
| 5431 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5432 | let mut size = 0; | ||
| 5433 | { | ||
| 5434 | let val_ref = &self.r#wifi_max_tx_power; | ||
| 5435 | if *val_ref != 0 { | ||
| 5436 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5437 | } | ||
| 5438 | } | ||
| 5439 | size | ||
| 5440 | } | ||
| 5441 | } | ||
| 5442 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 353 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5443 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 354 | pub(crate) struct CtrlMsgEventHeartbeat { | 5444 | pub struct CtrlMsg_Resp_SetWifiMaxTxPower { |
| 355 | #[noproto(tag = "1")] | 5445 | pub r#resp: i32, |
| 356 | pub hb_num: u32, | ||
| 357 | } | 5446 | } |
| 358 | 5447 | impl CtrlMsg_Resp_SetWifiMaxTxPower { | |
| 359 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 5448 | ///Return a reference to `resp` |
| 5449 | #[inline] | ||
| 5450 | pub fn r#resp(&self) -> &i32 { | ||
| 5451 | &self.r#resp | ||
| 5452 | } | ||
| 5453 | ///Return a mutable reference to `resp` | ||
| 5454 | #[inline] | ||
| 5455 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 5456 | &mut self.r#resp | ||
| 5457 | } | ||
| 5458 | ///Set the value of `resp` | ||
| 5459 | #[inline] | ||
| 5460 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 5461 | self.r#resp = value.into(); | ||
| 5462 | self | ||
| 5463 | } | ||
| 5464 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 5465 | #[inline] | ||
| 5466 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 5467 | self.r#resp = value.into(); | ||
| 5468 | self | ||
| 5469 | } | ||
| 5470 | } | ||
| 5471 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SetWifiMaxTxPower { | ||
| 5472 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5473 | &mut self, | ||
| 5474 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5475 | len: usize, | ||
| 5476 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5477 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5478 | let before = decoder.bytes_read(); | ||
| 5479 | while decoder.bytes_read() - before < len { | ||
| 5480 | let tag = decoder.decode_tag()?; | ||
| 5481 | match tag.field_num() { | ||
| 5482 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5483 | 1u32 => { | ||
| 5484 | let mut_ref = &mut self.r#resp; | ||
| 5485 | { | ||
| 5486 | let val = decoder.decode_int32()?; | ||
| 5487 | let val_ref = &val; | ||
| 5488 | if *val_ref != 0 { | ||
| 5489 | *mut_ref = val as _; | ||
| 5490 | } | ||
| 5491 | }; | ||
| 5492 | } | ||
| 5493 | _ => { | ||
| 5494 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5495 | } | ||
| 5496 | } | ||
| 5497 | } | ||
| 5498 | Ok(()) | ||
| 5499 | } | ||
| 5500 | } | ||
| 5501 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SetWifiMaxTxPower { | ||
| 5502 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 5503 | let mut max_size = 0; | ||
| 5504 | if let ::core::option::Option::Some(size) = | ||
| 5505 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 5506 | { | ||
| 5507 | max_size += size; | ||
| 5508 | } else { | ||
| 5509 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5510 | }; | ||
| 5511 | ::core::option::Option::Some(max_size) | ||
| 5512 | }; | ||
| 5513 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5514 | &self, | ||
| 5515 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5516 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5517 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5518 | { | ||
| 5519 | let val_ref = &self.r#resp; | ||
| 5520 | if *val_ref != 0 { | ||
| 5521 | encoder.encode_varint32(8u32)?; | ||
| 5522 | encoder.encode_int32(*val_ref as _)?; | ||
| 5523 | } | ||
| 5524 | } | ||
| 5525 | Ok(()) | ||
| 5526 | } | ||
| 5527 | fn compute_size(&self) -> usize { | ||
| 5528 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5529 | let mut size = 0; | ||
| 5530 | { | ||
| 5531 | let val_ref = &self.r#resp; | ||
| 5532 | if *val_ref != 0 { | ||
| 5533 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5534 | } | ||
| 5535 | } | ||
| 5536 | size | ||
| 5537 | } | ||
| 5538 | } | ||
| 5539 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 360 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5540 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 361 | pub(crate) struct CtrlMsgEventStationDisconnectFromAp { | 5541 | pub struct CtrlMsg_Req_GetWifiCurrTxPower {} |
| 362 | #[noproto(tag = "1")] | 5542 | impl CtrlMsg_Req_GetWifiCurrTxPower {} |
| 363 | pub resp: u32, | 5543 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetWifiCurrTxPower { |
| 5544 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5545 | &mut self, | ||
| 5546 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5547 | len: usize, | ||
| 5548 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5549 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5550 | let before = decoder.bytes_read(); | ||
| 5551 | while decoder.bytes_read() - before < len { | ||
| 5552 | let tag = decoder.decode_tag()?; | ||
| 5553 | match tag.field_num() { | ||
| 5554 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5555 | _ => { | ||
| 5556 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5557 | } | ||
| 5558 | } | ||
| 5559 | } | ||
| 5560 | Ok(()) | ||
| 5561 | } | ||
| 364 | } | 5562 | } |
| 365 | 5563 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetWifiCurrTxPower { | |
| 366 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 5564 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 5565 | let mut max_size = 0; | ||
| 5566 | ::core::option::Option::Some(max_size) | ||
| 5567 | }; | ||
| 5568 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5569 | &self, | ||
| 5570 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5571 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5572 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5573 | Ok(()) | ||
| 5574 | } | ||
| 5575 | fn compute_size(&self) -> usize { | ||
| 5576 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5577 | let mut size = 0; | ||
| 5578 | size | ||
| 5579 | } | ||
| 5580 | } | ||
| 5581 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 367 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5582 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 368 | pub(crate) struct CtrlMsgEventStationDisconnectFromEspSoftAp { | 5583 | pub struct CtrlMsg_Resp_GetWifiCurrTxPower { |
| 369 | #[noproto(tag = "1")] | 5584 | pub r#wifi_curr_tx_power: i32, |
| 370 | pub resp: u32, | 5585 | pub r#resp: i32, |
| 371 | #[noproto(tag = "2")] | ||
| 372 | pub mac: String<32>, | ||
| 373 | } | 5586 | } |
| 374 | 5587 | impl CtrlMsg_Resp_GetWifiCurrTxPower { | |
| 375 | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | 5588 | ///Return a reference to `wifi_curr_tx_power` |
| 376 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5589 | #[inline] |
| 377 | pub(crate) struct CtrlMsg { | 5590 | pub fn r#wifi_curr_tx_power(&self) -> &i32 { |
| 378 | /// msg_type could be req, resp or Event | 5591 | &self.r#wifi_curr_tx_power |
| 379 | #[noproto(tag = "1")] | 5592 | } |
| 380 | pub msg_type: CtrlMsgType, | 5593 | ///Return a mutable reference to `wifi_curr_tx_power` |
| 381 | /// msg id | 5594 | #[inline] |
| 382 | #[noproto(tag = "2")] | 5595 | pub fn mut_wifi_curr_tx_power(&mut self) -> &mut i32 { |
| 383 | pub msg_id: CtrlMsgId, | 5596 | &mut self.r#wifi_curr_tx_power |
| 384 | /// union of all msg ids | 5597 | } |
| 385 | #[noproto( | 5598 | ///Set the value of `wifi_curr_tx_power` |
| 386 | oneof, | 5599 | #[inline] |
| 387 | tags = "101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 301, 302, 303, 304" | 5600 | pub fn set_wifi_curr_tx_power(&mut self, value: i32) -> &mut Self { |
| 388 | )] | 5601 | self.r#wifi_curr_tx_power = value.into(); |
| 389 | pub payload: Option<CtrlMsgPayload>, | 5602 | self |
| 5603 | } | ||
| 5604 | ///Builder method that sets the value of `wifi_curr_tx_power`. Useful for initializing the message. | ||
| 5605 | #[inline] | ||
| 5606 | pub fn init_wifi_curr_tx_power(mut self, value: i32) -> Self { | ||
| 5607 | self.r#wifi_curr_tx_power = value.into(); | ||
| 5608 | self | ||
| 5609 | } | ||
| 5610 | ///Return a reference to `resp` | ||
| 5611 | #[inline] | ||
| 5612 | pub fn r#resp(&self) -> &i32 { | ||
| 5613 | &self.r#resp | ||
| 5614 | } | ||
| 5615 | ///Return a mutable reference to `resp` | ||
| 5616 | #[inline] | ||
| 5617 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 5618 | &mut self.r#resp | ||
| 5619 | } | ||
| 5620 | ///Set the value of `resp` | ||
| 5621 | #[inline] | ||
| 5622 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 5623 | self.r#resp = value.into(); | ||
| 5624 | self | ||
| 5625 | } | ||
| 5626 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 5627 | #[inline] | ||
| 5628 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 5629 | self.r#resp = value.into(); | ||
| 5630 | self | ||
| 5631 | } | ||
| 390 | } | 5632 | } |
| 391 | 5633 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetWifiCurrTxPower { | |
| 392 | /// union of all msg ids | 5634 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 393 | #[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)] | 5635 | &mut self, |
| 394 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5636 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, |
| 395 | pub(crate) enum CtrlMsgPayload { | 5637 | len: usize, |
| 396 | /// * Requests * | 5638 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { |
| 397 | #[noproto(tag = "101")] | 5639 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; |
| 398 | ReqGetMacAddress(CtrlMsgReqGetMacAddress), | 5640 | let before = decoder.bytes_read(); |
| 399 | #[noproto(tag = "102")] | 5641 | while decoder.bytes_read() - before < len { |
| 400 | ReqSetMacAddress(CtrlMsgReqSetMacAddress), | 5642 | let tag = decoder.decode_tag()?; |
| 401 | #[noproto(tag = "103")] | 5643 | match tag.field_num() { |
| 402 | ReqGetWifiMode(CtrlMsgReqGetMode), | 5644 | 0 => return Err(::micropb::DecodeError::ZeroField), |
| 403 | #[noproto(tag = "104")] | 5645 | 1u32 => { |
| 404 | ReqSetWifiMode(CtrlMsgReqSetMode), | 5646 | let mut_ref = &mut self.r#wifi_curr_tx_power; |
| 405 | #[noproto(tag = "105")] | 5647 | { |
| 406 | ReqScanApList(CtrlMsgReqScanResult), | 5648 | let val = decoder.decode_int32()?; |
| 407 | #[noproto(tag = "106")] | 5649 | let val_ref = &val; |
| 408 | ReqGetApConfig(CtrlMsgReqGetApConfig), | 5650 | if *val_ref != 0 { |
| 409 | #[noproto(tag = "107")] | 5651 | *mut_ref = val as _; |
| 410 | ReqConnectAp(CtrlMsgReqConnectAp), | 5652 | } |
| 411 | #[noproto(tag = "108")] | 5653 | }; |
| 412 | ReqDisconnectAp(CtrlMsgReqGetStatus), | 5654 | } |
| 413 | #[noproto(tag = "109")] | 5655 | 2u32 => { |
| 414 | ReqGetSoftapConfig(CtrlMsgReqGetSoftApConfig), | 5656 | let mut_ref = &mut self.r#resp; |
| 415 | #[noproto(tag = "110")] | 5657 | { |
| 416 | ReqSetSoftapVendorSpecificIe(CtrlMsgReqSetSoftApVendorSpecificIe), | 5658 | let val = decoder.decode_int32()?; |
| 417 | #[noproto(tag = "111")] | 5659 | let val_ref = &val; |
| 418 | ReqStartSoftap(CtrlMsgReqStartSoftAp), | 5660 | if *val_ref != 0 { |
| 419 | #[noproto(tag = "112")] | 5661 | *mut_ref = val as _; |
| 420 | ReqSoftapConnectedStasList(CtrlMsgReqSoftApConnectedSta), | 5662 | } |
| 421 | #[noproto(tag = "113")] | 5663 | }; |
| 422 | ReqStopSoftap(CtrlMsgReqGetStatus), | 5664 | } |
| 423 | #[noproto(tag = "114")] | 5665 | _ => { |
| 424 | ReqSetPowerSaveMode(CtrlMsgReqSetMode), | 5666 | decoder.skip_wire_value(tag.wire_type())?; |
| 425 | #[noproto(tag = "115")] | 5667 | } |
| 426 | ReqGetPowerSaveMode(CtrlMsgReqGetMode), | 5668 | } |
| 427 | #[noproto(tag = "116")] | 5669 | } |
| 428 | ReqOtaBegin(CtrlMsgReqOtaBegin), | 5670 | Ok(()) |
| 429 | #[noproto(tag = "117")] | 5671 | } |
| 430 | ReqOtaWrite(CtrlMsgReqOtaWrite), | ||
| 431 | #[noproto(tag = "118")] | ||
| 432 | ReqOtaEnd(CtrlMsgReqOtaEnd), | ||
| 433 | #[noproto(tag = "119")] | ||
| 434 | ReqSetWifiMaxTxPower(CtrlMsgReqSetWifiMaxTxPower), | ||
| 435 | #[noproto(tag = "120")] | ||
| 436 | ReqGetWifiCurrTxPower(CtrlMsgReqGetWifiCurrTxPower), | ||
| 437 | #[noproto(tag = "121")] | ||
| 438 | ReqConfigHeartbeat(CtrlMsgReqConfigHeartbeat), | ||
| 439 | /// * Responses * | ||
| 440 | #[noproto(tag = "201")] | ||
| 441 | RespGetMacAddress(CtrlMsgRespGetMacAddress), | ||
| 442 | #[noproto(tag = "202")] | ||
| 443 | RespSetMacAddress(CtrlMsgRespSetMacAddress), | ||
| 444 | #[noproto(tag = "203")] | ||
| 445 | RespGetWifiMode(CtrlMsgRespGetMode), | ||
| 446 | #[noproto(tag = "204")] | ||
| 447 | RespSetWifiMode(CtrlMsgRespSetMode), | ||
| 448 | #[noproto(tag = "205")] | ||
| 449 | RespScanApList(CtrlMsgRespScanResult), | ||
| 450 | #[noproto(tag = "206")] | ||
| 451 | RespGetApConfig(CtrlMsgRespGetApConfig), | ||
| 452 | #[noproto(tag = "207")] | ||
| 453 | RespConnectAp(CtrlMsgRespConnectAp), | ||
| 454 | #[noproto(tag = "208")] | ||
| 455 | RespDisconnectAp(CtrlMsgRespGetStatus), | ||
| 456 | #[noproto(tag = "209")] | ||
| 457 | RespGetSoftapConfig(CtrlMsgRespGetSoftApConfig), | ||
| 458 | #[noproto(tag = "210")] | ||
| 459 | RespSetSoftapVendorSpecificIe(CtrlMsgRespSetSoftApVendorSpecificIe), | ||
| 460 | #[noproto(tag = "211")] | ||
| 461 | RespStartSoftap(CtrlMsgRespStartSoftAp), | ||
| 462 | #[noproto(tag = "212")] | ||
| 463 | RespSoftapConnectedStasList(CtrlMsgRespSoftApConnectedSta), | ||
| 464 | #[noproto(tag = "213")] | ||
| 465 | RespStopSoftap(CtrlMsgRespGetStatus), | ||
| 466 | #[noproto(tag = "214")] | ||
| 467 | RespSetPowerSaveMode(CtrlMsgRespSetMode), | ||
| 468 | #[noproto(tag = "215")] | ||
| 469 | RespGetPowerSaveMode(CtrlMsgRespGetMode), | ||
| 470 | #[noproto(tag = "216")] | ||
| 471 | RespOtaBegin(CtrlMsgRespOtaBegin), | ||
| 472 | #[noproto(tag = "217")] | ||
| 473 | RespOtaWrite(CtrlMsgRespOtaWrite), | ||
| 474 | #[noproto(tag = "218")] | ||
| 475 | RespOtaEnd(CtrlMsgRespOtaEnd), | ||
| 476 | #[noproto(tag = "219")] | ||
| 477 | RespSetWifiMaxTxPower(CtrlMsgRespSetWifiMaxTxPower), | ||
| 478 | #[noproto(tag = "220")] | ||
| 479 | RespGetWifiCurrTxPower(CtrlMsgRespGetWifiCurrTxPower), | ||
| 480 | #[noproto(tag = "221")] | ||
| 481 | RespConfigHeartbeat(CtrlMsgRespConfigHeartbeat), | ||
| 482 | /// * Notifications * | ||
| 483 | #[noproto(tag = "301")] | ||
| 484 | EventEspInit(CtrlMsgEventEspInit), | ||
| 485 | #[noproto(tag = "302")] | ||
| 486 | EventHeartbeat(CtrlMsgEventHeartbeat), | ||
| 487 | #[noproto(tag = "303")] | ||
| 488 | EventStationDisconnectFromAp(CtrlMsgEventStationDisconnectFromAp), | ||
| 489 | #[noproto(tag = "304")] | ||
| 490 | EventStationDisconnectFromEspSoftAp(CtrlMsgEventStationDisconnectFromEspSoftAp), | ||
| 491 | } | 5672 | } |
| 492 | 5673 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetWifiCurrTxPower { | |
| 493 | /// Enums similar to ESP IDF | 5674 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 494 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 5675 | let mut max_size = 0; |
| 495 | #[repr(u32)] | 5676 | if let ::core::option::Option::Some(size) = |
| 496 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5677 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) |
| 497 | pub(crate) enum CtrlVendorIeType { | 5678 | { |
| 498 | #[default] | 5679 | max_size += size; |
| 499 | Beacon = 0, | 5680 | } else { |
| 500 | ProbeReq = 1, | 5681 | break 'msg (::core::option::Option::<usize>::None); |
| 501 | ProbeResp = 2, | 5682 | }; |
| 502 | AssocReq = 3, | 5683 | if let ::core::option::Option::Some(size) = |
| 503 | AssocResp = 4, | 5684 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) |
| 5685 | { | ||
| 5686 | max_size += size; | ||
| 5687 | } else { | ||
| 5688 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5689 | }; | ||
| 5690 | ::core::option::Option::Some(max_size) | ||
| 5691 | }; | ||
| 5692 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5693 | &self, | ||
| 5694 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5695 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5696 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5697 | { | ||
| 5698 | let val_ref = &self.r#wifi_curr_tx_power; | ||
| 5699 | if *val_ref != 0 { | ||
| 5700 | encoder.encode_varint32(8u32)?; | ||
| 5701 | encoder.encode_int32(*val_ref as _)?; | ||
| 5702 | } | ||
| 5703 | } | ||
| 5704 | { | ||
| 5705 | let val_ref = &self.r#resp; | ||
| 5706 | if *val_ref != 0 { | ||
| 5707 | encoder.encode_varint32(16u32)?; | ||
| 5708 | encoder.encode_int32(*val_ref as _)?; | ||
| 5709 | } | ||
| 5710 | } | ||
| 5711 | Ok(()) | ||
| 5712 | } | ||
| 5713 | fn compute_size(&self) -> usize { | ||
| 5714 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5715 | let mut size = 0; | ||
| 5716 | { | ||
| 5717 | let val_ref = &self.r#wifi_curr_tx_power; | ||
| 5718 | if *val_ref != 0 { | ||
| 5719 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5720 | } | ||
| 5721 | } | ||
| 5722 | { | ||
| 5723 | let val_ref = &self.r#resp; | ||
| 5724 | if *val_ref != 0 { | ||
| 5725 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5726 | } | ||
| 5727 | } | ||
| 5728 | size | ||
| 5729 | } | ||
| 504 | } | 5730 | } |
| 505 | 5731 | #[derive(Debug, Default, PartialEq, Clone)] | |
| 506 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||
| 507 | #[repr(u32)] | ||
| 508 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5732 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 509 | pub(crate) enum CtrlVendorIeid { | 5733 | pub struct CtrlMsg_Req_ConfigHeartbeat { |
| 510 | #[default] | 5734 | pub r#enable: bool, |
| 511 | Id0 = 0, | 5735 | pub r#duration: i32, |
| 512 | Id1 = 1, | ||
| 513 | } | 5736 | } |
| 514 | 5737 | impl CtrlMsg_Req_ConfigHeartbeat { | |
| 515 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 5738 | ///Return a reference to `enable` |
| 516 | #[repr(u32)] | 5739 | #[inline] |
| 5740 | pub fn r#enable(&self) -> &bool { | ||
| 5741 | &self.r#enable | ||
| 5742 | } | ||
| 5743 | ///Return a mutable reference to `enable` | ||
| 5744 | #[inline] | ||
| 5745 | pub fn mut_enable(&mut self) -> &mut bool { | ||
| 5746 | &mut self.r#enable | ||
| 5747 | } | ||
| 5748 | ///Set the value of `enable` | ||
| 5749 | #[inline] | ||
| 5750 | pub fn set_enable(&mut self, value: bool) -> &mut Self { | ||
| 5751 | self.r#enable = value.into(); | ||
| 5752 | self | ||
| 5753 | } | ||
| 5754 | ///Builder method that sets the value of `enable`. Useful for initializing the message. | ||
| 5755 | #[inline] | ||
| 5756 | pub fn init_enable(mut self, value: bool) -> Self { | ||
| 5757 | self.r#enable = value.into(); | ||
| 5758 | self | ||
| 5759 | } | ||
| 5760 | ///Return a reference to `duration` | ||
| 5761 | #[inline] | ||
| 5762 | pub fn r#duration(&self) -> &i32 { | ||
| 5763 | &self.r#duration | ||
| 5764 | } | ||
| 5765 | ///Return a mutable reference to `duration` | ||
| 5766 | #[inline] | ||
| 5767 | pub fn mut_duration(&mut self) -> &mut i32 { | ||
| 5768 | &mut self.r#duration | ||
| 5769 | } | ||
| 5770 | ///Set the value of `duration` | ||
| 5771 | #[inline] | ||
| 5772 | pub fn set_duration(&mut self, value: i32) -> &mut Self { | ||
| 5773 | self.r#duration = value.into(); | ||
| 5774 | self | ||
| 5775 | } | ||
| 5776 | ///Builder method that sets the value of `duration`. Useful for initializing the message. | ||
| 5777 | #[inline] | ||
| 5778 | pub fn init_duration(mut self, value: i32) -> Self { | ||
| 5779 | self.r#duration = value.into(); | ||
| 5780 | self | ||
| 5781 | } | ||
| 5782 | } | ||
| 5783 | impl ::micropb::MessageDecode for CtrlMsg_Req_ConfigHeartbeat { | ||
| 5784 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5785 | &mut self, | ||
| 5786 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5787 | len: usize, | ||
| 5788 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5789 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5790 | let before = decoder.bytes_read(); | ||
| 5791 | while decoder.bytes_read() - before < len { | ||
| 5792 | let tag = decoder.decode_tag()?; | ||
| 5793 | match tag.field_num() { | ||
| 5794 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5795 | 1u32 => { | ||
| 5796 | let mut_ref = &mut self.r#enable; | ||
| 5797 | { | ||
| 5798 | let val = decoder.decode_bool()?; | ||
| 5799 | let val_ref = &val; | ||
| 5800 | if *val_ref { | ||
| 5801 | *mut_ref = val as _; | ||
| 5802 | } | ||
| 5803 | }; | ||
| 5804 | } | ||
| 5805 | 2u32 => { | ||
| 5806 | let mut_ref = &mut self.r#duration; | ||
| 5807 | { | ||
| 5808 | let val = decoder.decode_int32()?; | ||
| 5809 | let val_ref = &val; | ||
| 5810 | if *val_ref != 0 { | ||
| 5811 | *mut_ref = val as _; | ||
| 5812 | } | ||
| 5813 | }; | ||
| 5814 | } | ||
| 5815 | _ => { | ||
| 5816 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5817 | } | ||
| 5818 | } | ||
| 5819 | } | ||
| 5820 | Ok(()) | ||
| 5821 | } | ||
| 5822 | } | ||
| 5823 | impl ::micropb::MessageEncode for CtrlMsg_Req_ConfigHeartbeat { | ||
| 5824 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 5825 | let mut max_size = 0; | ||
| 5826 | if let ::core::option::Option::Some(size) = | ||
| 5827 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 5828 | { | ||
| 5829 | max_size += size; | ||
| 5830 | } else { | ||
| 5831 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5832 | }; | ||
| 5833 | if let ::core::option::Option::Some(size) = | ||
| 5834 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 5835 | { | ||
| 5836 | max_size += size; | ||
| 5837 | } else { | ||
| 5838 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5839 | }; | ||
| 5840 | ::core::option::Option::Some(max_size) | ||
| 5841 | }; | ||
| 5842 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5843 | &self, | ||
| 5844 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5845 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5846 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5847 | { | ||
| 5848 | let val_ref = &self.r#enable; | ||
| 5849 | if *val_ref { | ||
| 5850 | encoder.encode_varint32(8u32)?; | ||
| 5851 | encoder.encode_bool(*val_ref)?; | ||
| 5852 | } | ||
| 5853 | } | ||
| 5854 | { | ||
| 5855 | let val_ref = &self.r#duration; | ||
| 5856 | if *val_ref != 0 { | ||
| 5857 | encoder.encode_varint32(16u32)?; | ||
| 5858 | encoder.encode_int32(*val_ref as _)?; | ||
| 5859 | } | ||
| 5860 | } | ||
| 5861 | Ok(()) | ||
| 5862 | } | ||
| 5863 | fn compute_size(&self) -> usize { | ||
| 5864 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5865 | let mut size = 0; | ||
| 5866 | { | ||
| 5867 | let val_ref = &self.r#enable; | ||
| 5868 | if *val_ref { | ||
| 5869 | size += 1usize + 1; | ||
| 5870 | } | ||
| 5871 | } | ||
| 5872 | { | ||
| 5873 | let val_ref = &self.r#duration; | ||
| 5874 | if *val_ref != 0 { | ||
| 5875 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5876 | } | ||
| 5877 | } | ||
| 5878 | size | ||
| 5879 | } | ||
| 5880 | } | ||
| 5881 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 517 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5882 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 518 | pub(crate) enum CtrlWifiMode { | 5883 | pub struct CtrlMsg_Resp_ConfigHeartbeat { |
| 519 | #[default] | 5884 | pub r#resp: i32, |
| 520 | None = 0, | ||
| 521 | Sta = 1, | ||
| 522 | Ap = 2, | ||
| 523 | Apsta = 3, | ||
| 524 | } | 5885 | } |
| 525 | 5886 | impl CtrlMsg_Resp_ConfigHeartbeat { | |
| 526 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 5887 | ///Return a reference to `resp` |
| 527 | #[repr(u32)] | 5888 | #[inline] |
| 5889 | pub fn r#resp(&self) -> &i32 { | ||
| 5890 | &self.r#resp | ||
| 5891 | } | ||
| 5892 | ///Return a mutable reference to `resp` | ||
| 5893 | #[inline] | ||
| 5894 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 5895 | &mut self.r#resp | ||
| 5896 | } | ||
| 5897 | ///Set the value of `resp` | ||
| 5898 | #[inline] | ||
| 5899 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 5900 | self.r#resp = value.into(); | ||
| 5901 | self | ||
| 5902 | } | ||
| 5903 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 5904 | #[inline] | ||
| 5905 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 5906 | self.r#resp = value.into(); | ||
| 5907 | self | ||
| 5908 | } | ||
| 5909 | } | ||
| 5910 | impl ::micropb::MessageDecode for CtrlMsg_Resp_ConfigHeartbeat { | ||
| 5911 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 5912 | &mut self, | ||
| 5913 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 5914 | len: usize, | ||
| 5915 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 5916 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 5917 | let before = decoder.bytes_read(); | ||
| 5918 | while decoder.bytes_read() - before < len { | ||
| 5919 | let tag = decoder.decode_tag()?; | ||
| 5920 | match tag.field_num() { | ||
| 5921 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 5922 | 1u32 => { | ||
| 5923 | let mut_ref = &mut self.r#resp; | ||
| 5924 | { | ||
| 5925 | let val = decoder.decode_int32()?; | ||
| 5926 | let val_ref = &val; | ||
| 5927 | if *val_ref != 0 { | ||
| 5928 | *mut_ref = val as _; | ||
| 5929 | } | ||
| 5930 | }; | ||
| 5931 | } | ||
| 5932 | _ => { | ||
| 5933 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 5934 | } | ||
| 5935 | } | ||
| 5936 | } | ||
| 5937 | Ok(()) | ||
| 5938 | } | ||
| 5939 | } | ||
| 5940 | impl ::micropb::MessageEncode for CtrlMsg_Resp_ConfigHeartbeat { | ||
| 5941 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 5942 | let mut max_size = 0; | ||
| 5943 | if let ::core::option::Option::Some(size) = | ||
| 5944 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 5945 | { | ||
| 5946 | max_size += size; | ||
| 5947 | } else { | ||
| 5948 | break 'msg (::core::option::Option::<usize>::None); | ||
| 5949 | }; | ||
| 5950 | ::core::option::Option::Some(max_size) | ||
| 5951 | }; | ||
| 5952 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 5953 | &self, | ||
| 5954 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 5955 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 5956 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5957 | { | ||
| 5958 | let val_ref = &self.r#resp; | ||
| 5959 | if *val_ref != 0 { | ||
| 5960 | encoder.encode_varint32(8u32)?; | ||
| 5961 | encoder.encode_int32(*val_ref as _)?; | ||
| 5962 | } | ||
| 5963 | } | ||
| 5964 | Ok(()) | ||
| 5965 | } | ||
| 5966 | fn compute_size(&self) -> usize { | ||
| 5967 | use ::micropb::{FieldEncode, PbMap}; | ||
| 5968 | let mut size = 0; | ||
| 5969 | { | ||
| 5970 | let val_ref = &self.r#resp; | ||
| 5971 | if *val_ref != 0 { | ||
| 5972 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 5973 | } | ||
| 5974 | } | ||
| 5975 | size | ||
| 5976 | } | ||
| 5977 | } | ||
| 5978 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 528 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5979 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 529 | pub(crate) enum CtrlWifiBw { | 5980 | pub struct CtrlMsg_Req_EnableDisable { |
| 530 | #[default] | 5981 | pub r#feature: u32, |
| 531 | BwInvalid = 0, | 5982 | pub r#enable: bool, |
| 532 | Ht20 = 1, | ||
| 533 | Ht40 = 2, | ||
| 534 | } | 5983 | } |
| 535 | 5984 | impl CtrlMsg_Req_EnableDisable { | |
| 536 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 5985 | ///Return a reference to `feature` |
| 537 | #[repr(u32)] | 5986 | #[inline] |
| 5987 | pub fn r#feature(&self) -> &u32 { | ||
| 5988 | &self.r#feature | ||
| 5989 | } | ||
| 5990 | ///Return a mutable reference to `feature` | ||
| 5991 | #[inline] | ||
| 5992 | pub fn mut_feature(&mut self) -> &mut u32 { | ||
| 5993 | &mut self.r#feature | ||
| 5994 | } | ||
| 5995 | ///Set the value of `feature` | ||
| 5996 | #[inline] | ||
| 5997 | pub fn set_feature(&mut self, value: u32) -> &mut Self { | ||
| 5998 | self.r#feature = value.into(); | ||
| 5999 | self | ||
| 6000 | } | ||
| 6001 | ///Builder method that sets the value of `feature`. Useful for initializing the message. | ||
| 6002 | #[inline] | ||
| 6003 | pub fn init_feature(mut self, value: u32) -> Self { | ||
| 6004 | self.r#feature = value.into(); | ||
| 6005 | self | ||
| 6006 | } | ||
| 6007 | ///Return a reference to `enable` | ||
| 6008 | #[inline] | ||
| 6009 | pub fn r#enable(&self) -> &bool { | ||
| 6010 | &self.r#enable | ||
| 6011 | } | ||
| 6012 | ///Return a mutable reference to `enable` | ||
| 6013 | #[inline] | ||
| 6014 | pub fn mut_enable(&mut self) -> &mut bool { | ||
| 6015 | &mut self.r#enable | ||
| 6016 | } | ||
| 6017 | ///Set the value of `enable` | ||
| 6018 | #[inline] | ||
| 6019 | pub fn set_enable(&mut self, value: bool) -> &mut Self { | ||
| 6020 | self.r#enable = value.into(); | ||
| 6021 | self | ||
| 6022 | } | ||
| 6023 | ///Builder method that sets the value of `enable`. Useful for initializing the message. | ||
| 6024 | #[inline] | ||
| 6025 | pub fn init_enable(mut self, value: bool) -> Self { | ||
| 6026 | self.r#enable = value.into(); | ||
| 6027 | self | ||
| 6028 | } | ||
| 6029 | } | ||
| 6030 | impl ::micropb::MessageDecode for CtrlMsg_Req_EnableDisable { | ||
| 6031 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 6032 | &mut self, | ||
| 6033 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 6034 | len: usize, | ||
| 6035 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 6036 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 6037 | let before = decoder.bytes_read(); | ||
| 6038 | while decoder.bytes_read() - before < len { | ||
| 6039 | let tag = decoder.decode_tag()?; | ||
| 6040 | match tag.field_num() { | ||
| 6041 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 6042 | 1u32 => { | ||
| 6043 | let mut_ref = &mut self.r#feature; | ||
| 6044 | { | ||
| 6045 | let val = decoder.decode_varint32()?; | ||
| 6046 | let val_ref = &val; | ||
| 6047 | if *val_ref != 0 { | ||
| 6048 | *mut_ref = val as _; | ||
| 6049 | } | ||
| 6050 | }; | ||
| 6051 | } | ||
| 6052 | 2u32 => { | ||
| 6053 | let mut_ref = &mut self.r#enable; | ||
| 6054 | { | ||
| 6055 | let val = decoder.decode_bool()?; | ||
| 6056 | let val_ref = &val; | ||
| 6057 | if *val_ref { | ||
| 6058 | *mut_ref = val as _; | ||
| 6059 | } | ||
| 6060 | }; | ||
| 6061 | } | ||
| 6062 | _ => { | ||
| 6063 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6064 | } | ||
| 6065 | } | ||
| 6066 | } | ||
| 6067 | Ok(()) | ||
| 6068 | } | ||
| 6069 | } | ||
| 6070 | impl ::micropb::MessageEncode for CtrlMsg_Req_EnableDisable { | ||
| 6071 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 6072 | let mut max_size = 0; | ||
| 6073 | if let ::core::option::Option::Some(size) = | ||
| 6074 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 6075 | { | ||
| 6076 | max_size += size; | ||
| 6077 | } else { | ||
| 6078 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6079 | }; | ||
| 6080 | if let ::core::option::Option::Some(size) = | ||
| 6081 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 6082 | { | ||
| 6083 | max_size += size; | ||
| 6084 | } else { | ||
| 6085 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6086 | }; | ||
| 6087 | ::core::option::Option::Some(max_size) | ||
| 6088 | }; | ||
| 6089 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 6090 | &self, | ||
| 6091 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 6092 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 6093 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6094 | { | ||
| 6095 | let val_ref = &self.r#feature; | ||
| 6096 | if *val_ref != 0 { | ||
| 6097 | encoder.encode_varint32(8u32)?; | ||
| 6098 | encoder.encode_varint32(*val_ref as _)?; | ||
| 6099 | } | ||
| 6100 | } | ||
| 6101 | { | ||
| 6102 | let val_ref = &self.r#enable; | ||
| 6103 | if *val_ref { | ||
| 6104 | encoder.encode_varint32(16u32)?; | ||
| 6105 | encoder.encode_bool(*val_ref)?; | ||
| 6106 | } | ||
| 6107 | } | ||
| 6108 | Ok(()) | ||
| 6109 | } | ||
| 6110 | fn compute_size(&self) -> usize { | ||
| 6111 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6112 | let mut size = 0; | ||
| 6113 | { | ||
| 6114 | let val_ref = &self.r#feature; | ||
| 6115 | if *val_ref != 0 { | ||
| 6116 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 6117 | } | ||
| 6118 | } | ||
| 6119 | { | ||
| 6120 | let val_ref = &self.r#enable; | ||
| 6121 | if *val_ref { | ||
| 6122 | size += 1usize + 1; | ||
| 6123 | } | ||
| 6124 | } | ||
| 6125 | size | ||
| 6126 | } | ||
| 6127 | } | ||
| 6128 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 538 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 6129 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 539 | pub(crate) enum CtrlWifiPowerSave { | 6130 | pub struct CtrlMsg_Resp_EnableDisable { |
| 540 | #[default] | 6131 | pub r#resp: i32, |
| 541 | PsInvalid = 0, | ||
| 542 | MinModem = 1, | ||
| 543 | MaxModem = 2, | ||
| 544 | } | 6132 | } |
| 545 | 6133 | impl CtrlMsg_Resp_EnableDisable { | |
| 546 | /// Wifi Security Settings | 6134 | ///Return a reference to `resp` |
| 547 | #[allow(missing_docs)] | 6135 | #[inline] |
| 548 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 6136 | pub fn r#resp(&self) -> &i32 { |
| 549 | #[repr(u32)] | 6137 | &self.r#resp |
| 550 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 6138 | } |
| 551 | pub enum CtrlWifiSecProt { | 6139 | ///Return a mutable reference to `resp` |
| 552 | #[default] | 6140 | #[inline] |
| 553 | Open = 0, | 6141 | pub fn mut_resp(&mut self) -> &mut i32 { |
| 554 | Wep = 1, | 6142 | &mut self.r#resp |
| 555 | WpaPsk = 2, | 6143 | } |
| 556 | Wpa2Psk = 3, | 6144 | ///Set the value of `resp` |
| 557 | WpaWpa2Psk = 4, | 6145 | #[inline] |
| 558 | Wpa2Enterprise = 5, | 6146 | pub fn set_resp(&mut self, value: i32) -> &mut Self { |
| 559 | Wpa3Psk = 6, | 6147 | self.r#resp = value.into(); |
| 560 | Wpa2Wpa3Psk = 7, | 6148 | self |
| 6149 | } | ||
| 6150 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 6151 | #[inline] | ||
| 6152 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 6153 | self.r#resp = value.into(); | ||
| 6154 | self | ||
| 6155 | } | ||
| 561 | } | 6156 | } |
| 562 | 6157 | impl ::micropb::MessageDecode for CtrlMsg_Resp_EnableDisable { | |
| 563 | /// enums for Control path | 6158 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 564 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 6159 | &mut self, |
| 565 | #[repr(u32)] | 6160 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, |
| 566 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 6161 | len: usize, |
| 567 | pub(crate) enum CtrlStatus { | 6162 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { |
| 568 | #[default] | 6163 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; |
| 569 | Connected = 0, | 6164 | let before = decoder.bytes_read(); |
| 570 | NotConnected = 1, | 6165 | while decoder.bytes_read() - before < len { |
| 571 | NoApFound = 2, | 6166 | let tag = decoder.decode_tag()?; |
| 572 | ConnectionFail = 3, | 6167 | match tag.field_num() { |
| 573 | InvalidArgument = 4, | 6168 | 0 => return Err(::micropb::DecodeError::ZeroField), |
| 574 | OutOfRange = 5, | 6169 | 1u32 => { |
| 6170 | let mut_ref = &mut self.r#resp; | ||
| 6171 | { | ||
| 6172 | let val = decoder.decode_int32()?; | ||
| 6173 | let val_ref = &val; | ||
| 6174 | if *val_ref != 0 { | ||
| 6175 | *mut_ref = val as _; | ||
| 6176 | } | ||
| 6177 | }; | ||
| 6178 | } | ||
| 6179 | _ => { | ||
| 6180 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6181 | } | ||
| 6182 | } | ||
| 6183 | } | ||
| 6184 | Ok(()) | ||
| 6185 | } | ||
| 575 | } | 6186 | } |
| 576 | 6187 | impl ::micropb::MessageEncode for CtrlMsg_Resp_EnableDisable { | |
| 577 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 6188 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 578 | #[repr(u32)] | 6189 | let mut max_size = 0; |
| 6190 | if let ::core::option::Option::Some(size) = | ||
| 6191 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 6192 | { | ||
| 6193 | max_size += size; | ||
| 6194 | } else { | ||
| 6195 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6196 | }; | ||
| 6197 | ::core::option::Option::Some(max_size) | ||
| 6198 | }; | ||
| 6199 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 6200 | &self, | ||
| 6201 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 6202 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 6203 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6204 | { | ||
| 6205 | let val_ref = &self.r#resp; | ||
| 6206 | if *val_ref != 0 { | ||
| 6207 | encoder.encode_varint32(8u32)?; | ||
| 6208 | encoder.encode_int32(*val_ref as _)?; | ||
| 6209 | } | ||
| 6210 | } | ||
| 6211 | Ok(()) | ||
| 6212 | } | ||
| 6213 | fn compute_size(&self) -> usize { | ||
| 6214 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6215 | let mut size = 0; | ||
| 6216 | { | ||
| 6217 | let val_ref = &self.r#resp; | ||
| 6218 | if *val_ref != 0 { | ||
| 6219 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 6220 | } | ||
| 6221 | } | ||
| 6222 | size | ||
| 6223 | } | ||
| 6224 | } | ||
| 6225 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 579 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 6226 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 580 | pub(crate) enum CtrlMsgType { | 6227 | pub struct CtrlMsg_Req_GetFwVersion {} |
| 581 | #[default] | 6228 | impl CtrlMsg_Req_GetFwVersion {} |
| 582 | MsgTypeInvalid = 0, | 6229 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetFwVersion { |
| 583 | Req = 1, | 6230 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( |
| 584 | Resp = 2, | 6231 | &mut self, |
| 585 | Event = 3, | 6232 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, |
| 586 | MsgTypeMax = 4, | 6233 | len: usize, |
| 6234 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 6235 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 6236 | let before = decoder.bytes_read(); | ||
| 6237 | while decoder.bytes_read() - before < len { | ||
| 6238 | let tag = decoder.decode_tag()?; | ||
| 6239 | match tag.field_num() { | ||
| 6240 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 6241 | _ => { | ||
| 6242 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6243 | } | ||
| 6244 | } | ||
| 6245 | } | ||
| 6246 | Ok(()) | ||
| 6247 | } | ||
| 587 | } | 6248 | } |
| 588 | 6249 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetFwVersion { | |
| 589 | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | 6250 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { |
| 590 | #[repr(u32)] | 6251 | let mut max_size = 0; |
| 591 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 6252 | ::core::option::Option::Some(max_size) |
| 592 | pub(crate) enum CtrlMsgId { | 6253 | }; |
| 593 | #[default] | 6254 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( |
| 594 | MsgIdInvalid = 0, | 6255 | &self, |
| 595 | /// * Request Msgs * | 6256 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, |
| 596 | ReqBase = 100, | 6257 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { |
| 597 | ReqGetMacAddress = 101, | 6258 | use ::micropb::{FieldEncode, PbMap}; |
| 598 | ReqSetMacAddress = 102, | 6259 | Ok(()) |
| 599 | ReqGetWifiMode = 103, | 6260 | } |
| 600 | ReqSetWifiMode = 104, | 6261 | fn compute_size(&self) -> usize { |
| 601 | ReqGetApScanList = 105, | 6262 | use ::micropb::{FieldEncode, PbMap}; |
| 602 | ReqGetApConfig = 106, | 6263 | let mut size = 0; |
| 603 | ReqConnectAp = 107, | 6264 | size |
| 604 | ReqDisconnectAp = 108, | 6265 | } |
| 605 | ReqGetSoftApConfig = 109, | 6266 | } |
| 606 | ReqSetSoftApVendorSpecificIe = 110, | 6267 | #[derive(Debug, Default, PartialEq, Clone)] |
| 607 | ReqStartSoftAp = 111, | 6268 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 608 | ReqGetSoftApConnectedStaList = 112, | 6269 | pub struct CtrlMsg_Resp_GetFwVersion { |
| 609 | ReqStopSoftAp = 113, | 6270 | pub r#resp: i32, |
| 610 | ReqSetPowerSaveMode = 114, | 6271 | pub r#name: ::micropb::heapless::String<32>, |
| 611 | ReqGetPowerSaveMode = 115, | 6272 | pub r#major1: u32, |
| 612 | ReqOtaBegin = 116, | 6273 | pub r#major2: u32, |
| 613 | ReqOtaWrite = 117, | 6274 | pub r#minor: u32, |
| 614 | ReqOtaEnd = 118, | 6275 | pub r#rev_patch1: u32, |
| 615 | ReqSetWifiMaxTxPower = 119, | 6276 | pub r#rev_patch2: u32, |
| 616 | ReqGetWifiCurrTxPower = 120, | 6277 | } |
| 617 | ReqConfigHeartbeat = 121, | 6278 | impl CtrlMsg_Resp_GetFwVersion { |
| 618 | /// Add new control path command response before Req_Max | 6279 | ///Return a reference to `resp` |
| 619 | /// and update Req_Max | 6280 | #[inline] |
| 620 | ReqMax = 122, | 6281 | pub fn r#resp(&self) -> &i32 { |
| 621 | /// * Response Msgs * | 6282 | &self.r#resp |
| 622 | RespBase = 200, | 6283 | } |
| 623 | RespGetMacAddress = 201, | 6284 | ///Return a mutable reference to `resp` |
| 624 | RespSetMacAddress = 202, | 6285 | #[inline] |
| 625 | RespGetWifiMode = 203, | 6286 | pub fn mut_resp(&mut self) -> &mut i32 { |
| 626 | RespSetWifiMode = 204, | 6287 | &mut self.r#resp |
| 627 | RespGetApScanList = 205, | 6288 | } |
| 628 | RespGetApConfig = 206, | 6289 | ///Set the value of `resp` |
| 629 | RespConnectAp = 207, | 6290 | #[inline] |
| 630 | RespDisconnectAp = 208, | 6291 | pub fn set_resp(&mut self, value: i32) -> &mut Self { |
| 631 | RespGetSoftApConfig = 209, | 6292 | self.r#resp = value.into(); |
| 632 | RespSetSoftApVendorSpecificIe = 210, | 6293 | self |
| 633 | RespStartSoftAp = 211, | 6294 | } |
| 634 | RespGetSoftApConnectedStaList = 212, | 6295 | ///Builder method that sets the value of `resp`. Useful for initializing the message. |
| 635 | RespStopSoftAp = 213, | 6296 | #[inline] |
| 636 | RespSetPowerSaveMode = 214, | 6297 | pub fn init_resp(mut self, value: i32) -> Self { |
| 637 | RespGetPowerSaveMode = 215, | 6298 | self.r#resp = value.into(); |
| 638 | RespOtaBegin = 216, | 6299 | self |
| 639 | RespOtaWrite = 217, | 6300 | } |
| 640 | RespOtaEnd = 218, | 6301 | ///Return a reference to `name` |
| 641 | RespSetWifiMaxTxPower = 219, | 6302 | #[inline] |
| 642 | RespGetWifiCurrTxPower = 220, | 6303 | pub fn r#name(&self) -> &::micropb::heapless::String<32> { |
| 643 | RespConfigHeartbeat = 221, | 6304 | &self.r#name |
| 644 | /// Add new control path command response before Resp_Max | 6305 | } |
| 645 | /// and update Resp_Max | 6306 | ///Return a mutable reference to `name` |
| 646 | RespMax = 222, | 6307 | #[inline] |
| 647 | /// * Event Msgs * | 6308 | pub fn mut_name(&mut self) -> &mut ::micropb::heapless::String<32> { |
| 648 | EventBase = 300, | 6309 | &mut self.r#name |
| 649 | EventEspInit = 301, | 6310 | } |
| 650 | EventHeartbeat = 302, | 6311 | ///Set the value of `name` |
| 651 | EventStationDisconnectFromAp = 303, | 6312 | #[inline] |
| 652 | EventStationDisconnectFromEspSoftAp = 304, | 6313 | pub fn set_name(&mut self, value: ::micropb::heapless::String<32>) -> &mut Self { |
| 653 | /// Add new control path command notification before Event_Max | 6314 | self.r#name = value.into(); |
| 654 | /// and update Event_Max | 6315 | self |
| 655 | EventMax = 305, | 6316 | } |
| 6317 | ///Builder method that sets the value of `name`. Useful for initializing the message. | ||
| 6318 | #[inline] | ||
| 6319 | pub fn init_name(mut self, value: ::micropb::heapless::String<32>) -> Self { | ||
| 6320 | self.r#name = value.into(); | ||
| 6321 | self | ||
| 6322 | } | ||
| 6323 | ///Return a reference to `major1` | ||
| 6324 | #[inline] | ||
| 6325 | pub fn r#major1(&self) -> &u32 { | ||
| 6326 | &self.r#major1 | ||
| 6327 | } | ||
| 6328 | ///Return a mutable reference to `major1` | ||
| 6329 | #[inline] | ||
| 6330 | pub fn mut_major1(&mut self) -> &mut u32 { | ||
| 6331 | &mut self.r#major1 | ||
| 6332 | } | ||
| 6333 | ///Set the value of `major1` | ||
| 6334 | #[inline] | ||
| 6335 | pub fn set_major1(&mut self, value: u32) -> &mut Self { | ||
| 6336 | self.r#major1 = value.into(); | ||
| 6337 | self | ||
| 6338 | } | ||
| 6339 | ///Builder method that sets the value of `major1`. Useful for initializing the message. | ||
| 6340 | #[inline] | ||
| 6341 | pub fn init_major1(mut self, value: u32) -> Self { | ||
| 6342 | self.r#major1 = value.into(); | ||
| 6343 | self | ||
| 6344 | } | ||
| 6345 | ///Return a reference to `major2` | ||
| 6346 | #[inline] | ||
| 6347 | pub fn r#major2(&self) -> &u32 { | ||
| 6348 | &self.r#major2 | ||
| 6349 | } | ||
| 6350 | ///Return a mutable reference to `major2` | ||
| 6351 | #[inline] | ||
| 6352 | pub fn mut_major2(&mut self) -> &mut u32 { | ||
| 6353 | &mut self.r#major2 | ||
| 6354 | } | ||
| 6355 | ///Set the value of `major2` | ||
| 6356 | #[inline] | ||
| 6357 | pub fn set_major2(&mut self, value: u32) -> &mut Self { | ||
| 6358 | self.r#major2 = value.into(); | ||
| 6359 | self | ||
| 6360 | } | ||
| 6361 | ///Builder method that sets the value of `major2`. Useful for initializing the message. | ||
| 6362 | #[inline] | ||
| 6363 | pub fn init_major2(mut self, value: u32) -> Self { | ||
| 6364 | self.r#major2 = value.into(); | ||
| 6365 | self | ||
| 6366 | } | ||
| 6367 | ///Return a reference to `minor` | ||
| 6368 | #[inline] | ||
| 6369 | pub fn r#minor(&self) -> &u32 { | ||
| 6370 | &self.r#minor | ||
| 6371 | } | ||
| 6372 | ///Return a mutable reference to `minor` | ||
| 6373 | #[inline] | ||
| 6374 | pub fn mut_minor(&mut self) -> &mut u32 { | ||
| 6375 | &mut self.r#minor | ||
| 6376 | } | ||
| 6377 | ///Set the value of `minor` | ||
| 6378 | #[inline] | ||
| 6379 | pub fn set_minor(&mut self, value: u32) -> &mut Self { | ||
| 6380 | self.r#minor = value.into(); | ||
| 6381 | self | ||
| 6382 | } | ||
| 6383 | ///Builder method that sets the value of `minor`. Useful for initializing the message. | ||
| 6384 | #[inline] | ||
| 6385 | pub fn init_minor(mut self, value: u32) -> Self { | ||
| 6386 | self.r#minor = value.into(); | ||
| 6387 | self | ||
| 6388 | } | ||
| 6389 | ///Return a reference to `rev_patch1` | ||
| 6390 | #[inline] | ||
| 6391 | pub fn r#rev_patch1(&self) -> &u32 { | ||
| 6392 | &self.r#rev_patch1 | ||
| 6393 | } | ||
| 6394 | ///Return a mutable reference to `rev_patch1` | ||
| 6395 | #[inline] | ||
| 6396 | pub fn mut_rev_patch1(&mut self) -> &mut u32 { | ||
| 6397 | &mut self.r#rev_patch1 | ||
| 6398 | } | ||
| 6399 | ///Set the value of `rev_patch1` | ||
| 6400 | #[inline] | ||
| 6401 | pub fn set_rev_patch1(&mut self, value: u32) -> &mut Self { | ||
| 6402 | self.r#rev_patch1 = value.into(); | ||
| 6403 | self | ||
| 6404 | } | ||
| 6405 | ///Builder method that sets the value of `rev_patch1`. Useful for initializing the message. | ||
| 6406 | #[inline] | ||
| 6407 | pub fn init_rev_patch1(mut self, value: u32) -> Self { | ||
| 6408 | self.r#rev_patch1 = value.into(); | ||
| 6409 | self | ||
| 6410 | } | ||
| 6411 | ///Return a reference to `rev_patch2` | ||
| 6412 | #[inline] | ||
| 6413 | pub fn r#rev_patch2(&self) -> &u32 { | ||
| 6414 | &self.r#rev_patch2 | ||
| 6415 | } | ||
| 6416 | ///Return a mutable reference to `rev_patch2` | ||
| 6417 | #[inline] | ||
| 6418 | pub fn mut_rev_patch2(&mut self) -> &mut u32 { | ||
| 6419 | &mut self.r#rev_patch2 | ||
| 6420 | } | ||
| 6421 | ///Set the value of `rev_patch2` | ||
| 6422 | #[inline] | ||
| 6423 | pub fn set_rev_patch2(&mut self, value: u32) -> &mut Self { | ||
| 6424 | self.r#rev_patch2 = value.into(); | ||
| 6425 | self | ||
| 6426 | } | ||
| 6427 | ///Builder method that sets the value of `rev_patch2`. Useful for initializing the message. | ||
| 6428 | #[inline] | ||
| 6429 | pub fn init_rev_patch2(mut self, value: u32) -> Self { | ||
| 6430 | self.r#rev_patch2 = value.into(); | ||
| 6431 | self | ||
| 6432 | } | ||
| 6433 | } | ||
| 6434 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetFwVersion { | ||
| 6435 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 6436 | &mut self, | ||
| 6437 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 6438 | len: usize, | ||
| 6439 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 6440 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 6441 | let before = decoder.bytes_read(); | ||
| 6442 | while decoder.bytes_read() - before < len { | ||
| 6443 | let tag = decoder.decode_tag()?; | ||
| 6444 | match tag.field_num() { | ||
| 6445 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 6446 | 1u32 => { | ||
| 6447 | let mut_ref = &mut self.r#resp; | ||
| 6448 | { | ||
| 6449 | let val = decoder.decode_int32()?; | ||
| 6450 | let val_ref = &val; | ||
| 6451 | if *val_ref != 0 { | ||
| 6452 | *mut_ref = val as _; | ||
| 6453 | } | ||
| 6454 | }; | ||
| 6455 | } | ||
| 6456 | 2u32 => { | ||
| 6457 | let mut_ref = &mut self.r#name; | ||
| 6458 | { | ||
| 6459 | decoder.decode_string(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 6460 | }; | ||
| 6461 | } | ||
| 6462 | 3u32 => { | ||
| 6463 | let mut_ref = &mut self.r#major1; | ||
| 6464 | { | ||
| 6465 | let val = decoder.decode_varint32()?; | ||
| 6466 | let val_ref = &val; | ||
| 6467 | if *val_ref != 0 { | ||
| 6468 | *mut_ref = val as _; | ||
| 6469 | } | ||
| 6470 | }; | ||
| 6471 | } | ||
| 6472 | 4u32 => { | ||
| 6473 | let mut_ref = &mut self.r#major2; | ||
| 6474 | { | ||
| 6475 | let val = decoder.decode_varint32()?; | ||
| 6476 | let val_ref = &val; | ||
| 6477 | if *val_ref != 0 { | ||
| 6478 | *mut_ref = val as _; | ||
| 6479 | } | ||
| 6480 | }; | ||
| 6481 | } | ||
| 6482 | 5u32 => { | ||
| 6483 | let mut_ref = &mut self.r#minor; | ||
| 6484 | { | ||
| 6485 | let val = decoder.decode_varint32()?; | ||
| 6486 | let val_ref = &val; | ||
| 6487 | if *val_ref != 0 { | ||
| 6488 | *mut_ref = val as _; | ||
| 6489 | } | ||
| 6490 | }; | ||
| 6491 | } | ||
| 6492 | 6u32 => { | ||
| 6493 | let mut_ref = &mut self.r#rev_patch1; | ||
| 6494 | { | ||
| 6495 | let val = decoder.decode_varint32()?; | ||
| 6496 | let val_ref = &val; | ||
| 6497 | if *val_ref != 0 { | ||
| 6498 | *mut_ref = val as _; | ||
| 6499 | } | ||
| 6500 | }; | ||
| 6501 | } | ||
| 6502 | 7u32 => { | ||
| 6503 | let mut_ref = &mut self.r#rev_patch2; | ||
| 6504 | { | ||
| 6505 | let val = decoder.decode_varint32()?; | ||
| 6506 | let val_ref = &val; | ||
| 6507 | if *val_ref != 0 { | ||
| 6508 | *mut_ref = val as _; | ||
| 6509 | } | ||
| 6510 | }; | ||
| 6511 | } | ||
| 6512 | _ => { | ||
| 6513 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6514 | } | ||
| 6515 | } | ||
| 6516 | } | ||
| 6517 | Ok(()) | ||
| 6518 | } | ||
| 6519 | } | ||
| 6520 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetFwVersion { | ||
| 6521 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 6522 | let mut max_size = 0; | ||
| 6523 | if let ::core::option::Option::Some(size) = | ||
| 6524 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 6525 | { | ||
| 6526 | max_size += size; | ||
| 6527 | } else { | ||
| 6528 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6529 | }; | ||
| 6530 | if let ::core::option::Option::Some(size) = | ||
| 6531 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 6532 | { | ||
| 6533 | max_size += size; | ||
| 6534 | } else { | ||
| 6535 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6536 | }; | ||
| 6537 | if let ::core::option::Option::Some(size) = | ||
| 6538 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 6539 | { | ||
| 6540 | max_size += size; | ||
| 6541 | } else { | ||
| 6542 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6543 | }; | ||
| 6544 | if let ::core::option::Option::Some(size) = | ||
| 6545 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 6546 | { | ||
| 6547 | max_size += size; | ||
| 6548 | } else { | ||
| 6549 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6550 | }; | ||
| 6551 | if let ::core::option::Option::Some(size) = | ||
| 6552 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 6553 | { | ||
| 6554 | max_size += size; | ||
| 6555 | } else { | ||
| 6556 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6557 | }; | ||
| 6558 | if let ::core::option::Option::Some(size) = | ||
| 6559 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 6560 | { | ||
| 6561 | max_size += size; | ||
| 6562 | } else { | ||
| 6563 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6564 | }; | ||
| 6565 | if let ::core::option::Option::Some(size) = | ||
| 6566 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 6567 | { | ||
| 6568 | max_size += size; | ||
| 6569 | } else { | ||
| 6570 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6571 | }; | ||
| 6572 | ::core::option::Option::Some(max_size) | ||
| 6573 | }; | ||
| 6574 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 6575 | &self, | ||
| 6576 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 6577 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 6578 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6579 | { | ||
| 6580 | let val_ref = &self.r#resp; | ||
| 6581 | if *val_ref != 0 { | ||
| 6582 | encoder.encode_varint32(8u32)?; | ||
| 6583 | encoder.encode_int32(*val_ref as _)?; | ||
| 6584 | } | ||
| 6585 | } | ||
| 6586 | { | ||
| 6587 | let val_ref = &self.r#name; | ||
| 6588 | if !val_ref.is_empty() { | ||
| 6589 | encoder.encode_varint32(18u32)?; | ||
| 6590 | encoder.encode_string(val_ref)?; | ||
| 6591 | } | ||
| 6592 | } | ||
| 6593 | { | ||
| 6594 | let val_ref = &self.r#major1; | ||
| 6595 | if *val_ref != 0 { | ||
| 6596 | encoder.encode_varint32(24u32)?; | ||
| 6597 | encoder.encode_varint32(*val_ref as _)?; | ||
| 6598 | } | ||
| 6599 | } | ||
| 6600 | { | ||
| 6601 | let val_ref = &self.r#major2; | ||
| 6602 | if *val_ref != 0 { | ||
| 6603 | encoder.encode_varint32(32u32)?; | ||
| 6604 | encoder.encode_varint32(*val_ref as _)?; | ||
| 6605 | } | ||
| 6606 | } | ||
| 6607 | { | ||
| 6608 | let val_ref = &self.r#minor; | ||
| 6609 | if *val_ref != 0 { | ||
| 6610 | encoder.encode_varint32(40u32)?; | ||
| 6611 | encoder.encode_varint32(*val_ref as _)?; | ||
| 6612 | } | ||
| 6613 | } | ||
| 6614 | { | ||
| 6615 | let val_ref = &self.r#rev_patch1; | ||
| 6616 | if *val_ref != 0 { | ||
| 6617 | encoder.encode_varint32(48u32)?; | ||
| 6618 | encoder.encode_varint32(*val_ref as _)?; | ||
| 6619 | } | ||
| 6620 | } | ||
| 6621 | { | ||
| 6622 | let val_ref = &self.r#rev_patch2; | ||
| 6623 | if *val_ref != 0 { | ||
| 6624 | encoder.encode_varint32(56u32)?; | ||
| 6625 | encoder.encode_varint32(*val_ref as _)?; | ||
| 6626 | } | ||
| 6627 | } | ||
| 6628 | Ok(()) | ||
| 6629 | } | ||
| 6630 | fn compute_size(&self) -> usize { | ||
| 6631 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6632 | let mut size = 0; | ||
| 6633 | { | ||
| 6634 | let val_ref = &self.r#resp; | ||
| 6635 | if *val_ref != 0 { | ||
| 6636 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 6637 | } | ||
| 6638 | } | ||
| 6639 | { | ||
| 6640 | let val_ref = &self.r#name; | ||
| 6641 | if !val_ref.is_empty() { | ||
| 6642 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 6643 | } | ||
| 6644 | } | ||
| 6645 | { | ||
| 6646 | let val_ref = &self.r#major1; | ||
| 6647 | if *val_ref != 0 { | ||
| 6648 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 6649 | } | ||
| 6650 | } | ||
| 6651 | { | ||
| 6652 | let val_ref = &self.r#major2; | ||
| 6653 | if *val_ref != 0 { | ||
| 6654 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 6655 | } | ||
| 6656 | } | ||
| 6657 | { | ||
| 6658 | let val_ref = &self.r#minor; | ||
| 6659 | if *val_ref != 0 { | ||
| 6660 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 6661 | } | ||
| 6662 | } | ||
| 6663 | { | ||
| 6664 | let val_ref = &self.r#rev_patch1; | ||
| 6665 | if *val_ref != 0 { | ||
| 6666 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 6667 | } | ||
| 6668 | } | ||
| 6669 | { | ||
| 6670 | let val_ref = &self.r#rev_patch2; | ||
| 6671 | if *val_ref != 0 { | ||
| 6672 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 6673 | } | ||
| 6674 | } | ||
| 6675 | size | ||
| 6676 | } | ||
| 6677 | } | ||
| 6678 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 6679 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 6680 | pub struct CtrlMsg_Req_SetCountryCode { | ||
| 6681 | pub r#country: ::micropb::heapless::Vec<u8, 32>, | ||
| 6682 | pub r#ieee80211d_enabled: bool, | ||
| 6683 | } | ||
| 6684 | impl CtrlMsg_Req_SetCountryCode { | ||
| 6685 | ///Return a reference to `country` | ||
| 6686 | #[inline] | ||
| 6687 | pub fn r#country(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 6688 | &self.r#country | ||
| 6689 | } | ||
| 6690 | ///Return a mutable reference to `country` | ||
| 6691 | #[inline] | ||
| 6692 | pub fn mut_country(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 6693 | &mut self.r#country | ||
| 6694 | } | ||
| 6695 | ///Set the value of `country` | ||
| 6696 | #[inline] | ||
| 6697 | pub fn set_country(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 6698 | self.r#country = value.into(); | ||
| 6699 | self | ||
| 6700 | } | ||
| 6701 | ///Builder method that sets the value of `country`. Useful for initializing the message. | ||
| 6702 | #[inline] | ||
| 6703 | pub fn init_country(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 6704 | self.r#country = value.into(); | ||
| 6705 | self | ||
| 6706 | } | ||
| 6707 | ///Return a reference to `ieee80211d_enabled` | ||
| 6708 | #[inline] | ||
| 6709 | pub fn r#ieee80211d_enabled(&self) -> &bool { | ||
| 6710 | &self.r#ieee80211d_enabled | ||
| 6711 | } | ||
| 6712 | ///Return a mutable reference to `ieee80211d_enabled` | ||
| 6713 | #[inline] | ||
| 6714 | pub fn mut_ieee80211d_enabled(&mut self) -> &mut bool { | ||
| 6715 | &mut self.r#ieee80211d_enabled | ||
| 6716 | } | ||
| 6717 | ///Set the value of `ieee80211d_enabled` | ||
| 6718 | #[inline] | ||
| 6719 | pub fn set_ieee80211d_enabled(&mut self, value: bool) -> &mut Self { | ||
| 6720 | self.r#ieee80211d_enabled = value.into(); | ||
| 6721 | self | ||
| 6722 | } | ||
| 6723 | ///Builder method that sets the value of `ieee80211d_enabled`. Useful for initializing the message. | ||
| 6724 | #[inline] | ||
| 6725 | pub fn init_ieee80211d_enabled(mut self, value: bool) -> Self { | ||
| 6726 | self.r#ieee80211d_enabled = value.into(); | ||
| 6727 | self | ||
| 6728 | } | ||
| 6729 | } | ||
| 6730 | impl ::micropb::MessageDecode for CtrlMsg_Req_SetCountryCode { | ||
| 6731 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 6732 | &mut self, | ||
| 6733 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 6734 | len: usize, | ||
| 6735 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 6736 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 6737 | let before = decoder.bytes_read(); | ||
| 6738 | while decoder.bytes_read() - before < len { | ||
| 6739 | let tag = decoder.decode_tag()?; | ||
| 6740 | match tag.field_num() { | ||
| 6741 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 6742 | 1u32 => { | ||
| 6743 | let mut_ref = &mut self.r#country; | ||
| 6744 | { | ||
| 6745 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 6746 | }; | ||
| 6747 | } | ||
| 6748 | 2u32 => { | ||
| 6749 | let mut_ref = &mut self.r#ieee80211d_enabled; | ||
| 6750 | { | ||
| 6751 | let val = decoder.decode_bool()?; | ||
| 6752 | let val_ref = &val; | ||
| 6753 | if *val_ref { | ||
| 6754 | *mut_ref = val as _; | ||
| 6755 | } | ||
| 6756 | }; | ||
| 6757 | } | ||
| 6758 | _ => { | ||
| 6759 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6760 | } | ||
| 6761 | } | ||
| 6762 | } | ||
| 6763 | Ok(()) | ||
| 6764 | } | ||
| 6765 | } | ||
| 6766 | impl ::micropb::MessageEncode for CtrlMsg_Req_SetCountryCode { | ||
| 6767 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 6768 | let mut max_size = 0; | ||
| 6769 | if let ::core::option::Option::Some(size) = | ||
| 6770 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 6771 | { | ||
| 6772 | max_size += size; | ||
| 6773 | } else { | ||
| 6774 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6775 | }; | ||
| 6776 | if let ::core::option::Option::Some(size) = | ||
| 6777 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 6778 | { | ||
| 6779 | max_size += size; | ||
| 6780 | } else { | ||
| 6781 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6782 | }; | ||
| 6783 | ::core::option::Option::Some(max_size) | ||
| 6784 | }; | ||
| 6785 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 6786 | &self, | ||
| 6787 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 6788 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 6789 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6790 | { | ||
| 6791 | let val_ref = &self.r#country; | ||
| 6792 | if !val_ref.is_empty() { | ||
| 6793 | encoder.encode_varint32(10u32)?; | ||
| 6794 | encoder.encode_bytes(val_ref)?; | ||
| 6795 | } | ||
| 6796 | } | ||
| 6797 | { | ||
| 6798 | let val_ref = &self.r#ieee80211d_enabled; | ||
| 6799 | if *val_ref { | ||
| 6800 | encoder.encode_varint32(16u32)?; | ||
| 6801 | encoder.encode_bool(*val_ref)?; | ||
| 6802 | } | ||
| 6803 | } | ||
| 6804 | Ok(()) | ||
| 6805 | } | ||
| 6806 | fn compute_size(&self) -> usize { | ||
| 6807 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6808 | let mut size = 0; | ||
| 6809 | { | ||
| 6810 | let val_ref = &self.r#country; | ||
| 6811 | if !val_ref.is_empty() { | ||
| 6812 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 6813 | } | ||
| 6814 | } | ||
| 6815 | { | ||
| 6816 | let val_ref = &self.r#ieee80211d_enabled; | ||
| 6817 | if *val_ref { | ||
| 6818 | size += 1usize + 1; | ||
| 6819 | } | ||
| 6820 | } | ||
| 6821 | size | ||
| 6822 | } | ||
| 6823 | } | ||
| 6824 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 6825 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 6826 | pub struct CtrlMsg_Resp_SetCountryCode { | ||
| 6827 | pub r#resp: i32, | ||
| 6828 | } | ||
| 6829 | impl CtrlMsg_Resp_SetCountryCode { | ||
| 6830 | ///Return a reference to `resp` | ||
| 6831 | #[inline] | ||
| 6832 | pub fn r#resp(&self) -> &i32 { | ||
| 6833 | &self.r#resp | ||
| 6834 | } | ||
| 6835 | ///Return a mutable reference to `resp` | ||
| 6836 | #[inline] | ||
| 6837 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 6838 | &mut self.r#resp | ||
| 6839 | } | ||
| 6840 | ///Set the value of `resp` | ||
| 6841 | #[inline] | ||
| 6842 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 6843 | self.r#resp = value.into(); | ||
| 6844 | self | ||
| 6845 | } | ||
| 6846 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 6847 | #[inline] | ||
| 6848 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 6849 | self.r#resp = value.into(); | ||
| 6850 | self | ||
| 6851 | } | ||
| 6852 | } | ||
| 6853 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SetCountryCode { | ||
| 6854 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 6855 | &mut self, | ||
| 6856 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 6857 | len: usize, | ||
| 6858 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 6859 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 6860 | let before = decoder.bytes_read(); | ||
| 6861 | while decoder.bytes_read() - before < len { | ||
| 6862 | let tag = decoder.decode_tag()?; | ||
| 6863 | match tag.field_num() { | ||
| 6864 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 6865 | 1u32 => { | ||
| 6866 | let mut_ref = &mut self.r#resp; | ||
| 6867 | { | ||
| 6868 | let val = decoder.decode_int32()?; | ||
| 6869 | let val_ref = &val; | ||
| 6870 | if *val_ref != 0 { | ||
| 6871 | *mut_ref = val as _; | ||
| 6872 | } | ||
| 6873 | }; | ||
| 6874 | } | ||
| 6875 | _ => { | ||
| 6876 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6877 | } | ||
| 6878 | } | ||
| 6879 | } | ||
| 6880 | Ok(()) | ||
| 6881 | } | ||
| 6882 | } | ||
| 6883 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SetCountryCode { | ||
| 6884 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 6885 | let mut max_size = 0; | ||
| 6886 | if let ::core::option::Option::Some(size) = | ||
| 6887 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 6888 | { | ||
| 6889 | max_size += size; | ||
| 6890 | } else { | ||
| 6891 | break 'msg (::core::option::Option::<usize>::None); | ||
| 6892 | }; | ||
| 6893 | ::core::option::Option::Some(max_size) | ||
| 6894 | }; | ||
| 6895 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 6896 | &self, | ||
| 6897 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 6898 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 6899 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6900 | { | ||
| 6901 | let val_ref = &self.r#resp; | ||
| 6902 | if *val_ref != 0 { | ||
| 6903 | encoder.encode_varint32(8u32)?; | ||
| 6904 | encoder.encode_int32(*val_ref as _)?; | ||
| 6905 | } | ||
| 6906 | } | ||
| 6907 | Ok(()) | ||
| 6908 | } | ||
| 6909 | fn compute_size(&self) -> usize { | ||
| 6910 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6911 | let mut size = 0; | ||
| 6912 | { | ||
| 6913 | let val_ref = &self.r#resp; | ||
| 6914 | if *val_ref != 0 { | ||
| 6915 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 6916 | } | ||
| 6917 | } | ||
| 6918 | size | ||
| 6919 | } | ||
| 6920 | } | ||
| 6921 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 6922 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 6923 | pub struct CtrlMsg_Req_GetCountryCode {} | ||
| 6924 | impl CtrlMsg_Req_GetCountryCode {} | ||
| 6925 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetCountryCode { | ||
| 6926 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 6927 | &mut self, | ||
| 6928 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 6929 | len: usize, | ||
| 6930 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 6931 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 6932 | let before = decoder.bytes_read(); | ||
| 6933 | while decoder.bytes_read() - before < len { | ||
| 6934 | let tag = decoder.decode_tag()?; | ||
| 6935 | match tag.field_num() { | ||
| 6936 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 6937 | _ => { | ||
| 6938 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 6939 | } | ||
| 6940 | } | ||
| 6941 | } | ||
| 6942 | Ok(()) | ||
| 6943 | } | ||
| 6944 | } | ||
| 6945 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetCountryCode { | ||
| 6946 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 6947 | let mut max_size = 0; | ||
| 6948 | ::core::option::Option::Some(max_size) | ||
| 6949 | }; | ||
| 6950 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 6951 | &self, | ||
| 6952 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 6953 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 6954 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6955 | Ok(()) | ||
| 6956 | } | ||
| 6957 | fn compute_size(&self) -> usize { | ||
| 6958 | use ::micropb::{FieldEncode, PbMap}; | ||
| 6959 | let mut size = 0; | ||
| 6960 | size | ||
| 6961 | } | ||
| 6962 | } | ||
| 6963 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 6964 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 6965 | pub struct CtrlMsg_Resp_GetCountryCode { | ||
| 6966 | pub r#resp: i32, | ||
| 6967 | pub r#country: ::micropb::heapless::Vec<u8, 32>, | ||
| 6968 | } | ||
| 6969 | impl CtrlMsg_Resp_GetCountryCode { | ||
| 6970 | ///Return a reference to `resp` | ||
| 6971 | #[inline] | ||
| 6972 | pub fn r#resp(&self) -> &i32 { | ||
| 6973 | &self.r#resp | ||
| 6974 | } | ||
| 6975 | ///Return a mutable reference to `resp` | ||
| 6976 | #[inline] | ||
| 6977 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 6978 | &mut self.r#resp | ||
| 6979 | } | ||
| 6980 | ///Set the value of `resp` | ||
| 6981 | #[inline] | ||
| 6982 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 6983 | self.r#resp = value.into(); | ||
| 6984 | self | ||
| 6985 | } | ||
| 6986 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 6987 | #[inline] | ||
| 6988 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 6989 | self.r#resp = value.into(); | ||
| 6990 | self | ||
| 6991 | } | ||
| 6992 | ///Return a reference to `country` | ||
| 6993 | #[inline] | ||
| 6994 | pub fn r#country(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 6995 | &self.r#country | ||
| 6996 | } | ||
| 6997 | ///Return a mutable reference to `country` | ||
| 6998 | #[inline] | ||
| 6999 | pub fn mut_country(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7000 | &mut self.r#country | ||
| 7001 | } | ||
| 7002 | ///Set the value of `country` | ||
| 7003 | #[inline] | ||
| 7004 | pub fn set_country(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7005 | self.r#country = value.into(); | ||
| 7006 | self | ||
| 7007 | } | ||
| 7008 | ///Builder method that sets the value of `country`. Useful for initializing the message. | ||
| 7009 | #[inline] | ||
| 7010 | pub fn init_country(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7011 | self.r#country = value.into(); | ||
| 7012 | self | ||
| 7013 | } | ||
| 7014 | } | ||
| 7015 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetCountryCode { | ||
| 7016 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 7017 | &mut self, | ||
| 7018 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 7019 | len: usize, | ||
| 7020 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 7021 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 7022 | let before = decoder.bytes_read(); | ||
| 7023 | while decoder.bytes_read() - before < len { | ||
| 7024 | let tag = decoder.decode_tag()?; | ||
| 7025 | match tag.field_num() { | ||
| 7026 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 7027 | 1u32 => { | ||
| 7028 | let mut_ref = &mut self.r#resp; | ||
| 7029 | { | ||
| 7030 | let val = decoder.decode_int32()?; | ||
| 7031 | let val_ref = &val; | ||
| 7032 | if *val_ref != 0 { | ||
| 7033 | *mut_ref = val as _; | ||
| 7034 | } | ||
| 7035 | }; | ||
| 7036 | } | ||
| 7037 | 2u32 => { | ||
| 7038 | let mut_ref = &mut self.r#country; | ||
| 7039 | { | ||
| 7040 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 7041 | }; | ||
| 7042 | } | ||
| 7043 | _ => { | ||
| 7044 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 7045 | } | ||
| 7046 | } | ||
| 7047 | } | ||
| 7048 | Ok(()) | ||
| 7049 | } | ||
| 7050 | } | ||
| 7051 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetCountryCode { | ||
| 7052 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 7053 | let mut max_size = 0; | ||
| 7054 | if let ::core::option::Option::Some(size) = | ||
| 7055 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7056 | { | ||
| 7057 | max_size += size; | ||
| 7058 | } else { | ||
| 7059 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7060 | }; | ||
| 7061 | if let ::core::option::Option::Some(size) = | ||
| 7062 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 7063 | { | ||
| 7064 | max_size += size; | ||
| 7065 | } else { | ||
| 7066 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7067 | }; | ||
| 7068 | ::core::option::Option::Some(max_size) | ||
| 7069 | }; | ||
| 7070 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 7071 | &self, | ||
| 7072 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 7073 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 7074 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7075 | { | ||
| 7076 | let val_ref = &self.r#resp; | ||
| 7077 | if *val_ref != 0 { | ||
| 7078 | encoder.encode_varint32(8u32)?; | ||
| 7079 | encoder.encode_int32(*val_ref as _)?; | ||
| 7080 | } | ||
| 7081 | } | ||
| 7082 | { | ||
| 7083 | let val_ref = &self.r#country; | ||
| 7084 | if !val_ref.is_empty() { | ||
| 7085 | encoder.encode_varint32(18u32)?; | ||
| 7086 | encoder.encode_bytes(val_ref)?; | ||
| 7087 | } | ||
| 7088 | } | ||
| 7089 | Ok(()) | ||
| 7090 | } | ||
| 7091 | fn compute_size(&self) -> usize { | ||
| 7092 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7093 | let mut size = 0; | ||
| 7094 | { | ||
| 7095 | let val_ref = &self.r#resp; | ||
| 7096 | if *val_ref != 0 { | ||
| 7097 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7098 | } | ||
| 7099 | } | ||
| 7100 | { | ||
| 7101 | let val_ref = &self.r#country; | ||
| 7102 | if !val_ref.is_empty() { | ||
| 7103 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 7104 | } | ||
| 7105 | } | ||
| 7106 | size | ||
| 7107 | } | ||
| 7108 | } | ||
| 7109 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 7110 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 7111 | pub struct CtrlMsg_Req_SetDhcpDnsStatus { | ||
| 7112 | pub r#iface: i32, | ||
| 7113 | pub r#net_link_up: i32, | ||
| 7114 | pub r#dhcp_up: i32, | ||
| 7115 | pub r#dhcp_ip: ::micropb::heapless::Vec<u8, 32>, | ||
| 7116 | pub r#dhcp_nm: ::micropb::heapless::Vec<u8, 32>, | ||
| 7117 | pub r#dhcp_gw: ::micropb::heapless::Vec<u8, 32>, | ||
| 7118 | pub r#dns_up: i32, | ||
| 7119 | pub r#dns_ip: ::micropb::heapless::Vec<u8, 32>, | ||
| 7120 | pub r#dns_type: i32, | ||
| 7121 | } | ||
| 7122 | impl CtrlMsg_Req_SetDhcpDnsStatus { | ||
| 7123 | ///Return a reference to `iface` | ||
| 7124 | #[inline] | ||
| 7125 | pub fn r#iface(&self) -> &i32 { | ||
| 7126 | &self.r#iface | ||
| 7127 | } | ||
| 7128 | ///Return a mutable reference to `iface` | ||
| 7129 | #[inline] | ||
| 7130 | pub fn mut_iface(&mut self) -> &mut i32 { | ||
| 7131 | &mut self.r#iface | ||
| 7132 | } | ||
| 7133 | ///Set the value of `iface` | ||
| 7134 | #[inline] | ||
| 7135 | pub fn set_iface(&mut self, value: i32) -> &mut Self { | ||
| 7136 | self.r#iface = value.into(); | ||
| 7137 | self | ||
| 7138 | } | ||
| 7139 | ///Builder method that sets the value of `iface`. Useful for initializing the message. | ||
| 7140 | #[inline] | ||
| 7141 | pub fn init_iface(mut self, value: i32) -> Self { | ||
| 7142 | self.r#iface = value.into(); | ||
| 7143 | self | ||
| 7144 | } | ||
| 7145 | ///Return a reference to `net_link_up` | ||
| 7146 | #[inline] | ||
| 7147 | pub fn r#net_link_up(&self) -> &i32 { | ||
| 7148 | &self.r#net_link_up | ||
| 7149 | } | ||
| 7150 | ///Return a mutable reference to `net_link_up` | ||
| 7151 | #[inline] | ||
| 7152 | pub fn mut_net_link_up(&mut self) -> &mut i32 { | ||
| 7153 | &mut self.r#net_link_up | ||
| 7154 | } | ||
| 7155 | ///Set the value of `net_link_up` | ||
| 7156 | #[inline] | ||
| 7157 | pub fn set_net_link_up(&mut self, value: i32) -> &mut Self { | ||
| 7158 | self.r#net_link_up = value.into(); | ||
| 7159 | self | ||
| 7160 | } | ||
| 7161 | ///Builder method that sets the value of `net_link_up`. Useful for initializing the message. | ||
| 7162 | #[inline] | ||
| 7163 | pub fn init_net_link_up(mut self, value: i32) -> Self { | ||
| 7164 | self.r#net_link_up = value.into(); | ||
| 7165 | self | ||
| 7166 | } | ||
| 7167 | ///Return a reference to `dhcp_up` | ||
| 7168 | #[inline] | ||
| 7169 | pub fn r#dhcp_up(&self) -> &i32 { | ||
| 7170 | &self.r#dhcp_up | ||
| 7171 | } | ||
| 7172 | ///Return a mutable reference to `dhcp_up` | ||
| 7173 | #[inline] | ||
| 7174 | pub fn mut_dhcp_up(&mut self) -> &mut i32 { | ||
| 7175 | &mut self.r#dhcp_up | ||
| 7176 | } | ||
| 7177 | ///Set the value of `dhcp_up` | ||
| 7178 | #[inline] | ||
| 7179 | pub fn set_dhcp_up(&mut self, value: i32) -> &mut Self { | ||
| 7180 | self.r#dhcp_up = value.into(); | ||
| 7181 | self | ||
| 7182 | } | ||
| 7183 | ///Builder method that sets the value of `dhcp_up`. Useful for initializing the message. | ||
| 7184 | #[inline] | ||
| 7185 | pub fn init_dhcp_up(mut self, value: i32) -> Self { | ||
| 7186 | self.r#dhcp_up = value.into(); | ||
| 7187 | self | ||
| 7188 | } | ||
| 7189 | ///Return a reference to `dhcp_ip` | ||
| 7190 | #[inline] | ||
| 7191 | pub fn r#dhcp_ip(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7192 | &self.r#dhcp_ip | ||
| 7193 | } | ||
| 7194 | ///Return a mutable reference to `dhcp_ip` | ||
| 7195 | #[inline] | ||
| 7196 | pub fn mut_dhcp_ip(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7197 | &mut self.r#dhcp_ip | ||
| 7198 | } | ||
| 7199 | ///Set the value of `dhcp_ip` | ||
| 7200 | #[inline] | ||
| 7201 | pub fn set_dhcp_ip(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7202 | self.r#dhcp_ip = value.into(); | ||
| 7203 | self | ||
| 7204 | } | ||
| 7205 | ///Builder method that sets the value of `dhcp_ip`. Useful for initializing the message. | ||
| 7206 | #[inline] | ||
| 7207 | pub fn init_dhcp_ip(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7208 | self.r#dhcp_ip = value.into(); | ||
| 7209 | self | ||
| 7210 | } | ||
| 7211 | ///Return a reference to `dhcp_nm` | ||
| 7212 | #[inline] | ||
| 7213 | pub fn r#dhcp_nm(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7214 | &self.r#dhcp_nm | ||
| 7215 | } | ||
| 7216 | ///Return a mutable reference to `dhcp_nm` | ||
| 7217 | #[inline] | ||
| 7218 | pub fn mut_dhcp_nm(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7219 | &mut self.r#dhcp_nm | ||
| 7220 | } | ||
| 7221 | ///Set the value of `dhcp_nm` | ||
| 7222 | #[inline] | ||
| 7223 | pub fn set_dhcp_nm(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7224 | self.r#dhcp_nm = value.into(); | ||
| 7225 | self | ||
| 7226 | } | ||
| 7227 | ///Builder method that sets the value of `dhcp_nm`. Useful for initializing the message. | ||
| 7228 | #[inline] | ||
| 7229 | pub fn init_dhcp_nm(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7230 | self.r#dhcp_nm = value.into(); | ||
| 7231 | self | ||
| 7232 | } | ||
| 7233 | ///Return a reference to `dhcp_gw` | ||
| 7234 | #[inline] | ||
| 7235 | pub fn r#dhcp_gw(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7236 | &self.r#dhcp_gw | ||
| 7237 | } | ||
| 7238 | ///Return a mutable reference to `dhcp_gw` | ||
| 7239 | #[inline] | ||
| 7240 | pub fn mut_dhcp_gw(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7241 | &mut self.r#dhcp_gw | ||
| 7242 | } | ||
| 7243 | ///Set the value of `dhcp_gw` | ||
| 7244 | #[inline] | ||
| 7245 | pub fn set_dhcp_gw(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7246 | self.r#dhcp_gw = value.into(); | ||
| 7247 | self | ||
| 7248 | } | ||
| 7249 | ///Builder method that sets the value of `dhcp_gw`. Useful for initializing the message. | ||
| 7250 | #[inline] | ||
| 7251 | pub fn init_dhcp_gw(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7252 | self.r#dhcp_gw = value.into(); | ||
| 7253 | self | ||
| 7254 | } | ||
| 7255 | ///Return a reference to `dns_up` | ||
| 7256 | #[inline] | ||
| 7257 | pub fn r#dns_up(&self) -> &i32 { | ||
| 7258 | &self.r#dns_up | ||
| 7259 | } | ||
| 7260 | ///Return a mutable reference to `dns_up` | ||
| 7261 | #[inline] | ||
| 7262 | pub fn mut_dns_up(&mut self) -> &mut i32 { | ||
| 7263 | &mut self.r#dns_up | ||
| 7264 | } | ||
| 7265 | ///Set the value of `dns_up` | ||
| 7266 | #[inline] | ||
| 7267 | pub fn set_dns_up(&mut self, value: i32) -> &mut Self { | ||
| 7268 | self.r#dns_up = value.into(); | ||
| 7269 | self | ||
| 7270 | } | ||
| 7271 | ///Builder method that sets the value of `dns_up`. Useful for initializing the message. | ||
| 7272 | #[inline] | ||
| 7273 | pub fn init_dns_up(mut self, value: i32) -> Self { | ||
| 7274 | self.r#dns_up = value.into(); | ||
| 7275 | self | ||
| 7276 | } | ||
| 7277 | ///Return a reference to `dns_ip` | ||
| 7278 | #[inline] | ||
| 7279 | pub fn r#dns_ip(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7280 | &self.r#dns_ip | ||
| 7281 | } | ||
| 7282 | ///Return a mutable reference to `dns_ip` | ||
| 7283 | #[inline] | ||
| 7284 | pub fn mut_dns_ip(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7285 | &mut self.r#dns_ip | ||
| 7286 | } | ||
| 7287 | ///Set the value of `dns_ip` | ||
| 7288 | #[inline] | ||
| 7289 | pub fn set_dns_ip(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7290 | self.r#dns_ip = value.into(); | ||
| 7291 | self | ||
| 7292 | } | ||
| 7293 | ///Builder method that sets the value of `dns_ip`. Useful for initializing the message. | ||
| 7294 | #[inline] | ||
| 7295 | pub fn init_dns_ip(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7296 | self.r#dns_ip = value.into(); | ||
| 7297 | self | ||
| 7298 | } | ||
| 7299 | ///Return a reference to `dns_type` | ||
| 7300 | #[inline] | ||
| 7301 | pub fn r#dns_type(&self) -> &i32 { | ||
| 7302 | &self.r#dns_type | ||
| 7303 | } | ||
| 7304 | ///Return a mutable reference to `dns_type` | ||
| 7305 | #[inline] | ||
| 7306 | pub fn mut_dns_type(&mut self) -> &mut i32 { | ||
| 7307 | &mut self.r#dns_type | ||
| 7308 | } | ||
| 7309 | ///Set the value of `dns_type` | ||
| 7310 | #[inline] | ||
| 7311 | pub fn set_dns_type(&mut self, value: i32) -> &mut Self { | ||
| 7312 | self.r#dns_type = value.into(); | ||
| 7313 | self | ||
| 7314 | } | ||
| 7315 | ///Builder method that sets the value of `dns_type`. Useful for initializing the message. | ||
| 7316 | #[inline] | ||
| 7317 | pub fn init_dns_type(mut self, value: i32) -> Self { | ||
| 7318 | self.r#dns_type = value.into(); | ||
| 7319 | self | ||
| 7320 | } | ||
| 7321 | } | ||
| 7322 | impl ::micropb::MessageDecode for CtrlMsg_Req_SetDhcpDnsStatus { | ||
| 7323 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 7324 | &mut self, | ||
| 7325 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 7326 | len: usize, | ||
| 7327 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 7328 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 7329 | let before = decoder.bytes_read(); | ||
| 7330 | while decoder.bytes_read() - before < len { | ||
| 7331 | let tag = decoder.decode_tag()?; | ||
| 7332 | match tag.field_num() { | ||
| 7333 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 7334 | 1u32 => { | ||
| 7335 | let mut_ref = &mut self.r#iface; | ||
| 7336 | { | ||
| 7337 | let val = decoder.decode_int32()?; | ||
| 7338 | let val_ref = &val; | ||
| 7339 | if *val_ref != 0 { | ||
| 7340 | *mut_ref = val as _; | ||
| 7341 | } | ||
| 7342 | }; | ||
| 7343 | } | ||
| 7344 | 2u32 => { | ||
| 7345 | let mut_ref = &mut self.r#net_link_up; | ||
| 7346 | { | ||
| 7347 | let val = decoder.decode_int32()?; | ||
| 7348 | let val_ref = &val; | ||
| 7349 | if *val_ref != 0 { | ||
| 7350 | *mut_ref = val as _; | ||
| 7351 | } | ||
| 7352 | }; | ||
| 7353 | } | ||
| 7354 | 3u32 => { | ||
| 7355 | let mut_ref = &mut self.r#dhcp_up; | ||
| 7356 | { | ||
| 7357 | let val = decoder.decode_int32()?; | ||
| 7358 | let val_ref = &val; | ||
| 7359 | if *val_ref != 0 { | ||
| 7360 | *mut_ref = val as _; | ||
| 7361 | } | ||
| 7362 | }; | ||
| 7363 | } | ||
| 7364 | 4u32 => { | ||
| 7365 | let mut_ref = &mut self.r#dhcp_ip; | ||
| 7366 | { | ||
| 7367 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 7368 | }; | ||
| 7369 | } | ||
| 7370 | 5u32 => { | ||
| 7371 | let mut_ref = &mut self.r#dhcp_nm; | ||
| 7372 | { | ||
| 7373 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 7374 | }; | ||
| 7375 | } | ||
| 7376 | 6u32 => { | ||
| 7377 | let mut_ref = &mut self.r#dhcp_gw; | ||
| 7378 | { | ||
| 7379 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 7380 | }; | ||
| 7381 | } | ||
| 7382 | 7u32 => { | ||
| 7383 | let mut_ref = &mut self.r#dns_up; | ||
| 7384 | { | ||
| 7385 | let val = decoder.decode_int32()?; | ||
| 7386 | let val_ref = &val; | ||
| 7387 | if *val_ref != 0 { | ||
| 7388 | *mut_ref = val as _; | ||
| 7389 | } | ||
| 7390 | }; | ||
| 7391 | } | ||
| 7392 | 8u32 => { | ||
| 7393 | let mut_ref = &mut self.r#dns_ip; | ||
| 7394 | { | ||
| 7395 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 7396 | }; | ||
| 7397 | } | ||
| 7398 | 9u32 => { | ||
| 7399 | let mut_ref = &mut self.r#dns_type; | ||
| 7400 | { | ||
| 7401 | let val = decoder.decode_int32()?; | ||
| 7402 | let val_ref = &val; | ||
| 7403 | if *val_ref != 0 { | ||
| 7404 | *mut_ref = val as _; | ||
| 7405 | } | ||
| 7406 | }; | ||
| 7407 | } | ||
| 7408 | _ => { | ||
| 7409 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 7410 | } | ||
| 7411 | } | ||
| 7412 | } | ||
| 7413 | Ok(()) | ||
| 7414 | } | ||
| 7415 | } | ||
| 7416 | impl ::micropb::MessageEncode for CtrlMsg_Req_SetDhcpDnsStatus { | ||
| 7417 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 7418 | let mut max_size = 0; | ||
| 7419 | if let ::core::option::Option::Some(size) = | ||
| 7420 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7421 | { | ||
| 7422 | max_size += size; | ||
| 7423 | } else { | ||
| 7424 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7425 | }; | ||
| 7426 | if let ::core::option::Option::Some(size) = | ||
| 7427 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7428 | { | ||
| 7429 | max_size += size; | ||
| 7430 | } else { | ||
| 7431 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7432 | }; | ||
| 7433 | if let ::core::option::Option::Some(size) = | ||
| 7434 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7435 | { | ||
| 7436 | max_size += size; | ||
| 7437 | } else { | ||
| 7438 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7439 | }; | ||
| 7440 | if let ::core::option::Option::Some(size) = | ||
| 7441 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 7442 | { | ||
| 7443 | max_size += size; | ||
| 7444 | } else { | ||
| 7445 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7446 | }; | ||
| 7447 | if let ::core::option::Option::Some(size) = | ||
| 7448 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 7449 | { | ||
| 7450 | max_size += size; | ||
| 7451 | } else { | ||
| 7452 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7453 | }; | ||
| 7454 | if let ::core::option::Option::Some(size) = | ||
| 7455 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 7456 | { | ||
| 7457 | max_size += size; | ||
| 7458 | } else { | ||
| 7459 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7460 | }; | ||
| 7461 | if let ::core::option::Option::Some(size) = | ||
| 7462 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7463 | { | ||
| 7464 | max_size += size; | ||
| 7465 | } else { | ||
| 7466 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7467 | }; | ||
| 7468 | if let ::core::option::Option::Some(size) = | ||
| 7469 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 7470 | { | ||
| 7471 | max_size += size; | ||
| 7472 | } else { | ||
| 7473 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7474 | }; | ||
| 7475 | if let ::core::option::Option::Some(size) = | ||
| 7476 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7477 | { | ||
| 7478 | max_size += size; | ||
| 7479 | } else { | ||
| 7480 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7481 | }; | ||
| 7482 | ::core::option::Option::Some(max_size) | ||
| 7483 | }; | ||
| 7484 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 7485 | &self, | ||
| 7486 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 7487 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 7488 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7489 | { | ||
| 7490 | let val_ref = &self.r#iface; | ||
| 7491 | if *val_ref != 0 { | ||
| 7492 | encoder.encode_varint32(8u32)?; | ||
| 7493 | encoder.encode_int32(*val_ref as _)?; | ||
| 7494 | } | ||
| 7495 | } | ||
| 7496 | { | ||
| 7497 | let val_ref = &self.r#net_link_up; | ||
| 7498 | if *val_ref != 0 { | ||
| 7499 | encoder.encode_varint32(16u32)?; | ||
| 7500 | encoder.encode_int32(*val_ref as _)?; | ||
| 7501 | } | ||
| 7502 | } | ||
| 7503 | { | ||
| 7504 | let val_ref = &self.r#dhcp_up; | ||
| 7505 | if *val_ref != 0 { | ||
| 7506 | encoder.encode_varint32(24u32)?; | ||
| 7507 | encoder.encode_int32(*val_ref as _)?; | ||
| 7508 | } | ||
| 7509 | } | ||
| 7510 | { | ||
| 7511 | let val_ref = &self.r#dhcp_ip; | ||
| 7512 | if !val_ref.is_empty() { | ||
| 7513 | encoder.encode_varint32(34u32)?; | ||
| 7514 | encoder.encode_bytes(val_ref)?; | ||
| 7515 | } | ||
| 7516 | } | ||
| 7517 | { | ||
| 7518 | let val_ref = &self.r#dhcp_nm; | ||
| 7519 | if !val_ref.is_empty() { | ||
| 7520 | encoder.encode_varint32(42u32)?; | ||
| 7521 | encoder.encode_bytes(val_ref)?; | ||
| 7522 | } | ||
| 7523 | } | ||
| 7524 | { | ||
| 7525 | let val_ref = &self.r#dhcp_gw; | ||
| 7526 | if !val_ref.is_empty() { | ||
| 7527 | encoder.encode_varint32(50u32)?; | ||
| 7528 | encoder.encode_bytes(val_ref)?; | ||
| 7529 | } | ||
| 7530 | } | ||
| 7531 | { | ||
| 7532 | let val_ref = &self.r#dns_up; | ||
| 7533 | if *val_ref != 0 { | ||
| 7534 | encoder.encode_varint32(56u32)?; | ||
| 7535 | encoder.encode_int32(*val_ref as _)?; | ||
| 7536 | } | ||
| 7537 | } | ||
| 7538 | { | ||
| 7539 | let val_ref = &self.r#dns_ip; | ||
| 7540 | if !val_ref.is_empty() { | ||
| 7541 | encoder.encode_varint32(66u32)?; | ||
| 7542 | encoder.encode_bytes(val_ref)?; | ||
| 7543 | } | ||
| 7544 | } | ||
| 7545 | { | ||
| 7546 | let val_ref = &self.r#dns_type; | ||
| 7547 | if *val_ref != 0 { | ||
| 7548 | encoder.encode_varint32(72u32)?; | ||
| 7549 | encoder.encode_int32(*val_ref as _)?; | ||
| 7550 | } | ||
| 7551 | } | ||
| 7552 | Ok(()) | ||
| 7553 | } | ||
| 7554 | fn compute_size(&self) -> usize { | ||
| 7555 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7556 | let mut size = 0; | ||
| 7557 | { | ||
| 7558 | let val_ref = &self.r#iface; | ||
| 7559 | if *val_ref != 0 { | ||
| 7560 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7561 | } | ||
| 7562 | } | ||
| 7563 | { | ||
| 7564 | let val_ref = &self.r#net_link_up; | ||
| 7565 | if *val_ref != 0 { | ||
| 7566 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7567 | } | ||
| 7568 | } | ||
| 7569 | { | ||
| 7570 | let val_ref = &self.r#dhcp_up; | ||
| 7571 | if *val_ref != 0 { | ||
| 7572 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7573 | } | ||
| 7574 | } | ||
| 7575 | { | ||
| 7576 | let val_ref = &self.r#dhcp_ip; | ||
| 7577 | if !val_ref.is_empty() { | ||
| 7578 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 7579 | } | ||
| 7580 | } | ||
| 7581 | { | ||
| 7582 | let val_ref = &self.r#dhcp_nm; | ||
| 7583 | if !val_ref.is_empty() { | ||
| 7584 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 7585 | } | ||
| 7586 | } | ||
| 7587 | { | ||
| 7588 | let val_ref = &self.r#dhcp_gw; | ||
| 7589 | if !val_ref.is_empty() { | ||
| 7590 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 7591 | } | ||
| 7592 | } | ||
| 7593 | { | ||
| 7594 | let val_ref = &self.r#dns_up; | ||
| 7595 | if *val_ref != 0 { | ||
| 7596 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7597 | } | ||
| 7598 | } | ||
| 7599 | { | ||
| 7600 | let val_ref = &self.r#dns_ip; | ||
| 7601 | if !val_ref.is_empty() { | ||
| 7602 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 7603 | } | ||
| 7604 | } | ||
| 7605 | { | ||
| 7606 | let val_ref = &self.r#dns_type; | ||
| 7607 | if *val_ref != 0 { | ||
| 7608 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7609 | } | ||
| 7610 | } | ||
| 7611 | size | ||
| 7612 | } | ||
| 7613 | } | ||
| 7614 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 7615 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 7616 | pub struct CtrlMsg_Resp_SetDhcpDnsStatus { | ||
| 7617 | pub r#resp: i32, | ||
| 7618 | } | ||
| 7619 | impl CtrlMsg_Resp_SetDhcpDnsStatus { | ||
| 7620 | ///Return a reference to `resp` | ||
| 7621 | #[inline] | ||
| 7622 | pub fn r#resp(&self) -> &i32 { | ||
| 7623 | &self.r#resp | ||
| 7624 | } | ||
| 7625 | ///Return a mutable reference to `resp` | ||
| 7626 | #[inline] | ||
| 7627 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 7628 | &mut self.r#resp | ||
| 7629 | } | ||
| 7630 | ///Set the value of `resp` | ||
| 7631 | #[inline] | ||
| 7632 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 7633 | self.r#resp = value.into(); | ||
| 7634 | self | ||
| 7635 | } | ||
| 7636 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 7637 | #[inline] | ||
| 7638 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 7639 | self.r#resp = value.into(); | ||
| 7640 | self | ||
| 7641 | } | ||
| 7642 | } | ||
| 7643 | impl ::micropb::MessageDecode for CtrlMsg_Resp_SetDhcpDnsStatus { | ||
| 7644 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 7645 | &mut self, | ||
| 7646 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 7647 | len: usize, | ||
| 7648 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 7649 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 7650 | let before = decoder.bytes_read(); | ||
| 7651 | while decoder.bytes_read() - before < len { | ||
| 7652 | let tag = decoder.decode_tag()?; | ||
| 7653 | match tag.field_num() { | ||
| 7654 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 7655 | 1u32 => { | ||
| 7656 | let mut_ref = &mut self.r#resp; | ||
| 7657 | { | ||
| 7658 | let val = decoder.decode_int32()?; | ||
| 7659 | let val_ref = &val; | ||
| 7660 | if *val_ref != 0 { | ||
| 7661 | *mut_ref = val as _; | ||
| 7662 | } | ||
| 7663 | }; | ||
| 7664 | } | ||
| 7665 | _ => { | ||
| 7666 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 7667 | } | ||
| 7668 | } | ||
| 7669 | } | ||
| 7670 | Ok(()) | ||
| 7671 | } | ||
| 7672 | } | ||
| 7673 | impl ::micropb::MessageEncode for CtrlMsg_Resp_SetDhcpDnsStatus { | ||
| 7674 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 7675 | let mut max_size = 0; | ||
| 7676 | if let ::core::option::Option::Some(size) = | ||
| 7677 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 7678 | { | ||
| 7679 | max_size += size; | ||
| 7680 | } else { | ||
| 7681 | break 'msg (::core::option::Option::<usize>::None); | ||
| 7682 | }; | ||
| 7683 | ::core::option::Option::Some(max_size) | ||
| 7684 | }; | ||
| 7685 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 7686 | &self, | ||
| 7687 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 7688 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 7689 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7690 | { | ||
| 7691 | let val_ref = &self.r#resp; | ||
| 7692 | if *val_ref != 0 { | ||
| 7693 | encoder.encode_varint32(8u32)?; | ||
| 7694 | encoder.encode_int32(*val_ref as _)?; | ||
| 7695 | } | ||
| 7696 | } | ||
| 7697 | Ok(()) | ||
| 7698 | } | ||
| 7699 | fn compute_size(&self) -> usize { | ||
| 7700 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7701 | let mut size = 0; | ||
| 7702 | { | ||
| 7703 | let val_ref = &self.r#resp; | ||
| 7704 | if *val_ref != 0 { | ||
| 7705 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 7706 | } | ||
| 7707 | } | ||
| 7708 | size | ||
| 7709 | } | ||
| 7710 | } | ||
| 7711 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 7712 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 7713 | pub struct CtrlMsg_Req_GetDhcpDnsStatus {} | ||
| 7714 | impl CtrlMsg_Req_GetDhcpDnsStatus {} | ||
| 7715 | impl ::micropb::MessageDecode for CtrlMsg_Req_GetDhcpDnsStatus { | ||
| 7716 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 7717 | &mut self, | ||
| 7718 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 7719 | len: usize, | ||
| 7720 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 7721 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 7722 | let before = decoder.bytes_read(); | ||
| 7723 | while decoder.bytes_read() - before < len { | ||
| 7724 | let tag = decoder.decode_tag()?; | ||
| 7725 | match tag.field_num() { | ||
| 7726 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 7727 | _ => { | ||
| 7728 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 7729 | } | ||
| 7730 | } | ||
| 7731 | } | ||
| 7732 | Ok(()) | ||
| 7733 | } | ||
| 7734 | } | ||
| 7735 | impl ::micropb::MessageEncode for CtrlMsg_Req_GetDhcpDnsStatus { | ||
| 7736 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 7737 | let mut max_size = 0; | ||
| 7738 | ::core::option::Option::Some(max_size) | ||
| 7739 | }; | ||
| 7740 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 7741 | &self, | ||
| 7742 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 7743 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 7744 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7745 | Ok(()) | ||
| 7746 | } | ||
| 7747 | fn compute_size(&self) -> usize { | ||
| 7748 | use ::micropb::{FieldEncode, PbMap}; | ||
| 7749 | let mut size = 0; | ||
| 7750 | size | ||
| 7751 | } | ||
| 7752 | } | ||
| 7753 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 7754 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 7755 | pub struct CtrlMsg_Resp_GetDhcpDnsStatus { | ||
| 7756 | pub r#resp: i32, | ||
| 7757 | pub r#iface: i32, | ||
| 7758 | pub r#net_link_up: i32, | ||
| 7759 | pub r#dhcp_up: i32, | ||
| 7760 | pub r#dhcp_ip: ::micropb::heapless::Vec<u8, 32>, | ||
| 7761 | pub r#dhcp_nm: ::micropb::heapless::Vec<u8, 32>, | ||
| 7762 | pub r#dhcp_gw: ::micropb::heapless::Vec<u8, 32>, | ||
| 7763 | pub r#dns_up: i32, | ||
| 7764 | pub r#dns_ip: ::micropb::heapless::Vec<u8, 32>, | ||
| 7765 | pub r#dns_type: i32, | ||
| 7766 | } | ||
| 7767 | impl CtrlMsg_Resp_GetDhcpDnsStatus { | ||
| 7768 | ///Return a reference to `resp` | ||
| 7769 | #[inline] | ||
| 7770 | pub fn r#resp(&self) -> &i32 { | ||
| 7771 | &self.r#resp | ||
| 7772 | } | ||
| 7773 | ///Return a mutable reference to `resp` | ||
| 7774 | #[inline] | ||
| 7775 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 7776 | &mut self.r#resp | ||
| 7777 | } | ||
| 7778 | ///Set the value of `resp` | ||
| 7779 | #[inline] | ||
| 7780 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 7781 | self.r#resp = value.into(); | ||
| 7782 | self | ||
| 7783 | } | ||
| 7784 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 7785 | #[inline] | ||
| 7786 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 7787 | self.r#resp = value.into(); | ||
| 7788 | self | ||
| 7789 | } | ||
| 7790 | ///Return a reference to `iface` | ||
| 7791 | #[inline] | ||
| 7792 | pub fn r#iface(&self) -> &i32 { | ||
| 7793 | &self.r#iface | ||
| 7794 | } | ||
| 7795 | ///Return a mutable reference to `iface` | ||
| 7796 | #[inline] | ||
| 7797 | pub fn mut_iface(&mut self) -> &mut i32 { | ||
| 7798 | &mut self.r#iface | ||
| 7799 | } | ||
| 7800 | ///Set the value of `iface` | ||
| 7801 | #[inline] | ||
| 7802 | pub fn set_iface(&mut self, value: i32) -> &mut Self { | ||
| 7803 | self.r#iface = value.into(); | ||
| 7804 | self | ||
| 7805 | } | ||
| 7806 | ///Builder method that sets the value of `iface`. Useful for initializing the message. | ||
| 7807 | #[inline] | ||
| 7808 | pub fn init_iface(mut self, value: i32) -> Self { | ||
| 7809 | self.r#iface = value.into(); | ||
| 7810 | self | ||
| 7811 | } | ||
| 7812 | ///Return a reference to `net_link_up` | ||
| 7813 | #[inline] | ||
| 7814 | pub fn r#net_link_up(&self) -> &i32 { | ||
| 7815 | &self.r#net_link_up | ||
| 7816 | } | ||
| 7817 | ///Return a mutable reference to `net_link_up` | ||
| 7818 | #[inline] | ||
| 7819 | pub fn mut_net_link_up(&mut self) -> &mut i32 { | ||
| 7820 | &mut self.r#net_link_up | ||
| 7821 | } | ||
| 7822 | ///Set the value of `net_link_up` | ||
| 7823 | #[inline] | ||
| 7824 | pub fn set_net_link_up(&mut self, value: i32) -> &mut Self { | ||
| 7825 | self.r#net_link_up = value.into(); | ||
| 7826 | self | ||
| 7827 | } | ||
| 7828 | ///Builder method that sets the value of `net_link_up`. Useful for initializing the message. | ||
| 7829 | #[inline] | ||
| 7830 | pub fn init_net_link_up(mut self, value: i32) -> Self { | ||
| 7831 | self.r#net_link_up = value.into(); | ||
| 7832 | self | ||
| 7833 | } | ||
| 7834 | ///Return a reference to `dhcp_up` | ||
| 7835 | #[inline] | ||
| 7836 | pub fn r#dhcp_up(&self) -> &i32 { | ||
| 7837 | &self.r#dhcp_up | ||
| 7838 | } | ||
| 7839 | ///Return a mutable reference to `dhcp_up` | ||
| 7840 | #[inline] | ||
| 7841 | pub fn mut_dhcp_up(&mut self) -> &mut i32 { | ||
| 7842 | &mut self.r#dhcp_up | ||
| 7843 | } | ||
| 7844 | ///Set the value of `dhcp_up` | ||
| 7845 | #[inline] | ||
| 7846 | pub fn set_dhcp_up(&mut self, value: i32) -> &mut Self { | ||
| 7847 | self.r#dhcp_up = value.into(); | ||
| 7848 | self | ||
| 7849 | } | ||
| 7850 | ///Builder method that sets the value of `dhcp_up`. Useful for initializing the message. | ||
| 7851 | #[inline] | ||
| 7852 | pub fn init_dhcp_up(mut self, value: i32) -> Self { | ||
| 7853 | self.r#dhcp_up = value.into(); | ||
| 7854 | self | ||
| 7855 | } | ||
| 7856 | ///Return a reference to `dhcp_ip` | ||
| 7857 | #[inline] | ||
| 7858 | pub fn r#dhcp_ip(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7859 | &self.r#dhcp_ip | ||
| 7860 | } | ||
| 7861 | ///Return a mutable reference to `dhcp_ip` | ||
| 7862 | #[inline] | ||
| 7863 | pub fn mut_dhcp_ip(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7864 | &mut self.r#dhcp_ip | ||
| 7865 | } | ||
| 7866 | ///Set the value of `dhcp_ip` | ||
| 7867 | #[inline] | ||
| 7868 | pub fn set_dhcp_ip(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7869 | self.r#dhcp_ip = value.into(); | ||
| 7870 | self | ||
| 7871 | } | ||
| 7872 | ///Builder method that sets the value of `dhcp_ip`. Useful for initializing the message. | ||
| 7873 | #[inline] | ||
| 7874 | pub fn init_dhcp_ip(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7875 | self.r#dhcp_ip = value.into(); | ||
| 7876 | self | ||
| 7877 | } | ||
| 7878 | ///Return a reference to `dhcp_nm` | ||
| 7879 | #[inline] | ||
| 7880 | pub fn r#dhcp_nm(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7881 | &self.r#dhcp_nm | ||
| 7882 | } | ||
| 7883 | ///Return a mutable reference to `dhcp_nm` | ||
| 7884 | #[inline] | ||
| 7885 | pub fn mut_dhcp_nm(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7886 | &mut self.r#dhcp_nm | ||
| 7887 | } | ||
| 7888 | ///Set the value of `dhcp_nm` | ||
| 7889 | #[inline] | ||
| 7890 | pub fn set_dhcp_nm(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7891 | self.r#dhcp_nm = value.into(); | ||
| 7892 | self | ||
| 7893 | } | ||
| 7894 | ///Builder method that sets the value of `dhcp_nm`. Useful for initializing the message. | ||
| 7895 | #[inline] | ||
| 7896 | pub fn init_dhcp_nm(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7897 | self.r#dhcp_nm = value.into(); | ||
| 7898 | self | ||
| 7899 | } | ||
| 7900 | ///Return a reference to `dhcp_gw` | ||
| 7901 | #[inline] | ||
| 7902 | pub fn r#dhcp_gw(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7903 | &self.r#dhcp_gw | ||
| 7904 | } | ||
| 7905 | ///Return a mutable reference to `dhcp_gw` | ||
| 7906 | #[inline] | ||
| 7907 | pub fn mut_dhcp_gw(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7908 | &mut self.r#dhcp_gw | ||
| 7909 | } | ||
| 7910 | ///Set the value of `dhcp_gw` | ||
| 7911 | #[inline] | ||
| 7912 | pub fn set_dhcp_gw(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7913 | self.r#dhcp_gw = value.into(); | ||
| 7914 | self | ||
| 7915 | } | ||
| 7916 | ///Builder method that sets the value of `dhcp_gw`. Useful for initializing the message. | ||
| 7917 | #[inline] | ||
| 7918 | pub fn init_dhcp_gw(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7919 | self.r#dhcp_gw = value.into(); | ||
| 7920 | self | ||
| 7921 | } | ||
| 7922 | ///Return a reference to `dns_up` | ||
| 7923 | #[inline] | ||
| 7924 | pub fn r#dns_up(&self) -> &i32 { | ||
| 7925 | &self.r#dns_up | ||
| 7926 | } | ||
| 7927 | ///Return a mutable reference to `dns_up` | ||
| 7928 | #[inline] | ||
| 7929 | pub fn mut_dns_up(&mut self) -> &mut i32 { | ||
| 7930 | &mut self.r#dns_up | ||
| 7931 | } | ||
| 7932 | ///Set the value of `dns_up` | ||
| 7933 | #[inline] | ||
| 7934 | pub fn set_dns_up(&mut self, value: i32) -> &mut Self { | ||
| 7935 | self.r#dns_up = value.into(); | ||
| 7936 | self | ||
| 7937 | } | ||
| 7938 | ///Builder method that sets the value of `dns_up`. Useful for initializing the message. | ||
| 7939 | #[inline] | ||
| 7940 | pub fn init_dns_up(mut self, value: i32) -> Self { | ||
| 7941 | self.r#dns_up = value.into(); | ||
| 7942 | self | ||
| 7943 | } | ||
| 7944 | ///Return a reference to `dns_ip` | ||
| 7945 | #[inline] | ||
| 7946 | pub fn r#dns_ip(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 7947 | &self.r#dns_ip | ||
| 7948 | } | ||
| 7949 | ///Return a mutable reference to `dns_ip` | ||
| 7950 | #[inline] | ||
| 7951 | pub fn mut_dns_ip(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 7952 | &mut self.r#dns_ip | ||
| 7953 | } | ||
| 7954 | ///Set the value of `dns_ip` | ||
| 7955 | #[inline] | ||
| 7956 | pub fn set_dns_ip(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 7957 | self.r#dns_ip = value.into(); | ||
| 7958 | self | ||
| 7959 | } | ||
| 7960 | ///Builder method that sets the value of `dns_ip`. Useful for initializing the message. | ||
| 7961 | #[inline] | ||
| 7962 | pub fn init_dns_ip(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 7963 | self.r#dns_ip = value.into(); | ||
| 7964 | self | ||
| 7965 | } | ||
| 7966 | ///Return a reference to `dns_type` | ||
| 7967 | #[inline] | ||
| 7968 | pub fn r#dns_type(&self) -> &i32 { | ||
| 7969 | &self.r#dns_type | ||
| 7970 | } | ||
| 7971 | ///Return a mutable reference to `dns_type` | ||
| 7972 | #[inline] | ||
| 7973 | pub fn mut_dns_type(&mut self) -> &mut i32 { | ||
| 7974 | &mut self.r#dns_type | ||
| 7975 | } | ||
| 7976 | ///Set the value of `dns_type` | ||
| 7977 | #[inline] | ||
| 7978 | pub fn set_dns_type(&mut self, value: i32) -> &mut Self { | ||
| 7979 | self.r#dns_type = value.into(); | ||
| 7980 | self | ||
| 7981 | } | ||
| 7982 | ///Builder method that sets the value of `dns_type`. Useful for initializing the message. | ||
| 7983 | #[inline] | ||
| 7984 | pub fn init_dns_type(mut self, value: i32) -> Self { | ||
| 7985 | self.r#dns_type = value.into(); | ||
| 7986 | self | ||
| 7987 | } | ||
| 7988 | } | ||
| 7989 | impl ::micropb::MessageDecode for CtrlMsg_Resp_GetDhcpDnsStatus { | ||
| 7990 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 7991 | &mut self, | ||
| 7992 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 7993 | len: usize, | ||
| 7994 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 7995 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 7996 | let before = decoder.bytes_read(); | ||
| 7997 | while decoder.bytes_read() - before < len { | ||
| 7998 | let tag = decoder.decode_tag()?; | ||
| 7999 | match tag.field_num() { | ||
| 8000 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 8001 | 1u32 => { | ||
| 8002 | let mut_ref = &mut self.r#resp; | ||
| 8003 | { | ||
| 8004 | let val = decoder.decode_int32()?; | ||
| 8005 | let val_ref = &val; | ||
| 8006 | if *val_ref != 0 { | ||
| 8007 | *mut_ref = val as _; | ||
| 8008 | } | ||
| 8009 | }; | ||
| 8010 | } | ||
| 8011 | 2u32 => { | ||
| 8012 | let mut_ref = &mut self.r#iface; | ||
| 8013 | { | ||
| 8014 | let val = decoder.decode_int32()?; | ||
| 8015 | let val_ref = &val; | ||
| 8016 | if *val_ref != 0 { | ||
| 8017 | *mut_ref = val as _; | ||
| 8018 | } | ||
| 8019 | }; | ||
| 8020 | } | ||
| 8021 | 3u32 => { | ||
| 8022 | let mut_ref = &mut self.r#net_link_up; | ||
| 8023 | { | ||
| 8024 | let val = decoder.decode_int32()?; | ||
| 8025 | let val_ref = &val; | ||
| 8026 | if *val_ref != 0 { | ||
| 8027 | *mut_ref = val as _; | ||
| 8028 | } | ||
| 8029 | }; | ||
| 8030 | } | ||
| 8031 | 4u32 => { | ||
| 8032 | let mut_ref = &mut self.r#dhcp_up; | ||
| 8033 | { | ||
| 8034 | let val = decoder.decode_int32()?; | ||
| 8035 | let val_ref = &val; | ||
| 8036 | if *val_ref != 0 { | ||
| 8037 | *mut_ref = val as _; | ||
| 8038 | } | ||
| 8039 | }; | ||
| 8040 | } | ||
| 8041 | 5u32 => { | ||
| 8042 | let mut_ref = &mut self.r#dhcp_ip; | ||
| 8043 | { | ||
| 8044 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8045 | }; | ||
| 8046 | } | ||
| 8047 | 6u32 => { | ||
| 8048 | let mut_ref = &mut self.r#dhcp_nm; | ||
| 8049 | { | ||
| 8050 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8051 | }; | ||
| 8052 | } | ||
| 8053 | 7u32 => { | ||
| 8054 | let mut_ref = &mut self.r#dhcp_gw; | ||
| 8055 | { | ||
| 8056 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8057 | }; | ||
| 8058 | } | ||
| 8059 | 8u32 => { | ||
| 8060 | let mut_ref = &mut self.r#dns_up; | ||
| 8061 | { | ||
| 8062 | let val = decoder.decode_int32()?; | ||
| 8063 | let val_ref = &val; | ||
| 8064 | if *val_ref != 0 { | ||
| 8065 | *mut_ref = val as _; | ||
| 8066 | } | ||
| 8067 | }; | ||
| 8068 | } | ||
| 8069 | 9u32 => { | ||
| 8070 | let mut_ref = &mut self.r#dns_ip; | ||
| 8071 | { | ||
| 8072 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8073 | }; | ||
| 8074 | } | ||
| 8075 | 10u32 => { | ||
| 8076 | let mut_ref = &mut self.r#dns_type; | ||
| 8077 | { | ||
| 8078 | let val = decoder.decode_int32()?; | ||
| 8079 | let val_ref = &val; | ||
| 8080 | if *val_ref != 0 { | ||
| 8081 | *mut_ref = val as _; | ||
| 8082 | } | ||
| 8083 | }; | ||
| 8084 | } | ||
| 8085 | _ => { | ||
| 8086 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 8087 | } | ||
| 8088 | } | ||
| 8089 | } | ||
| 8090 | Ok(()) | ||
| 8091 | } | ||
| 8092 | } | ||
| 8093 | impl ::micropb::MessageEncode for CtrlMsg_Resp_GetDhcpDnsStatus { | ||
| 8094 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 8095 | let mut max_size = 0; | ||
| 8096 | if let ::core::option::Option::Some(size) = | ||
| 8097 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8098 | { | ||
| 8099 | max_size += size; | ||
| 8100 | } else { | ||
| 8101 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8102 | }; | ||
| 8103 | if let ::core::option::Option::Some(size) = | ||
| 8104 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8105 | { | ||
| 8106 | max_size += size; | ||
| 8107 | } else { | ||
| 8108 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8109 | }; | ||
| 8110 | if let ::core::option::Option::Some(size) = | ||
| 8111 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8112 | { | ||
| 8113 | max_size += size; | ||
| 8114 | } else { | ||
| 8115 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8116 | }; | ||
| 8117 | if let ::core::option::Option::Some(size) = | ||
| 8118 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8119 | { | ||
| 8120 | max_size += size; | ||
| 8121 | } else { | ||
| 8122 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8123 | }; | ||
| 8124 | if let ::core::option::Option::Some(size) = | ||
| 8125 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 8126 | { | ||
| 8127 | max_size += size; | ||
| 8128 | } else { | ||
| 8129 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8130 | }; | ||
| 8131 | if let ::core::option::Option::Some(size) = | ||
| 8132 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 8133 | { | ||
| 8134 | max_size += size; | ||
| 8135 | } else { | ||
| 8136 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8137 | }; | ||
| 8138 | if let ::core::option::Option::Some(size) = | ||
| 8139 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 8140 | { | ||
| 8141 | max_size += size; | ||
| 8142 | } else { | ||
| 8143 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8144 | }; | ||
| 8145 | if let ::core::option::Option::Some(size) = | ||
| 8146 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8147 | { | ||
| 8148 | max_size += size; | ||
| 8149 | } else { | ||
| 8150 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8151 | }; | ||
| 8152 | if let ::core::option::Option::Some(size) = | ||
| 8153 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 8154 | { | ||
| 8155 | max_size += size; | ||
| 8156 | } else { | ||
| 8157 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8158 | }; | ||
| 8159 | if let ::core::option::Option::Some(size) = | ||
| 8160 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8161 | { | ||
| 8162 | max_size += size; | ||
| 8163 | } else { | ||
| 8164 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8165 | }; | ||
| 8166 | ::core::option::Option::Some(max_size) | ||
| 8167 | }; | ||
| 8168 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 8169 | &self, | ||
| 8170 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 8171 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 8172 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8173 | { | ||
| 8174 | let val_ref = &self.r#resp; | ||
| 8175 | if *val_ref != 0 { | ||
| 8176 | encoder.encode_varint32(8u32)?; | ||
| 8177 | encoder.encode_int32(*val_ref as _)?; | ||
| 8178 | } | ||
| 8179 | } | ||
| 8180 | { | ||
| 8181 | let val_ref = &self.r#iface; | ||
| 8182 | if *val_ref != 0 { | ||
| 8183 | encoder.encode_varint32(16u32)?; | ||
| 8184 | encoder.encode_int32(*val_ref as _)?; | ||
| 8185 | } | ||
| 8186 | } | ||
| 8187 | { | ||
| 8188 | let val_ref = &self.r#net_link_up; | ||
| 8189 | if *val_ref != 0 { | ||
| 8190 | encoder.encode_varint32(24u32)?; | ||
| 8191 | encoder.encode_int32(*val_ref as _)?; | ||
| 8192 | } | ||
| 8193 | } | ||
| 8194 | { | ||
| 8195 | let val_ref = &self.r#dhcp_up; | ||
| 8196 | if *val_ref != 0 { | ||
| 8197 | encoder.encode_varint32(32u32)?; | ||
| 8198 | encoder.encode_int32(*val_ref as _)?; | ||
| 8199 | } | ||
| 8200 | } | ||
| 8201 | { | ||
| 8202 | let val_ref = &self.r#dhcp_ip; | ||
| 8203 | if !val_ref.is_empty() { | ||
| 8204 | encoder.encode_varint32(42u32)?; | ||
| 8205 | encoder.encode_bytes(val_ref)?; | ||
| 8206 | } | ||
| 8207 | } | ||
| 8208 | { | ||
| 8209 | let val_ref = &self.r#dhcp_nm; | ||
| 8210 | if !val_ref.is_empty() { | ||
| 8211 | encoder.encode_varint32(50u32)?; | ||
| 8212 | encoder.encode_bytes(val_ref)?; | ||
| 8213 | } | ||
| 8214 | } | ||
| 8215 | { | ||
| 8216 | let val_ref = &self.r#dhcp_gw; | ||
| 8217 | if !val_ref.is_empty() { | ||
| 8218 | encoder.encode_varint32(58u32)?; | ||
| 8219 | encoder.encode_bytes(val_ref)?; | ||
| 8220 | } | ||
| 8221 | } | ||
| 8222 | { | ||
| 8223 | let val_ref = &self.r#dns_up; | ||
| 8224 | if *val_ref != 0 { | ||
| 8225 | encoder.encode_varint32(64u32)?; | ||
| 8226 | encoder.encode_int32(*val_ref as _)?; | ||
| 8227 | } | ||
| 8228 | } | ||
| 8229 | { | ||
| 8230 | let val_ref = &self.r#dns_ip; | ||
| 8231 | if !val_ref.is_empty() { | ||
| 8232 | encoder.encode_varint32(74u32)?; | ||
| 8233 | encoder.encode_bytes(val_ref)?; | ||
| 8234 | } | ||
| 8235 | } | ||
| 8236 | { | ||
| 8237 | let val_ref = &self.r#dns_type; | ||
| 8238 | if *val_ref != 0 { | ||
| 8239 | encoder.encode_varint32(80u32)?; | ||
| 8240 | encoder.encode_int32(*val_ref as _)?; | ||
| 8241 | } | ||
| 8242 | } | ||
| 8243 | Ok(()) | ||
| 8244 | } | ||
| 8245 | fn compute_size(&self) -> usize { | ||
| 8246 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8247 | let mut size = 0; | ||
| 8248 | { | ||
| 8249 | let val_ref = &self.r#resp; | ||
| 8250 | if *val_ref != 0 { | ||
| 8251 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8252 | } | ||
| 8253 | } | ||
| 8254 | { | ||
| 8255 | let val_ref = &self.r#iface; | ||
| 8256 | if *val_ref != 0 { | ||
| 8257 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8258 | } | ||
| 8259 | } | ||
| 8260 | { | ||
| 8261 | let val_ref = &self.r#net_link_up; | ||
| 8262 | if *val_ref != 0 { | ||
| 8263 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8264 | } | ||
| 8265 | } | ||
| 8266 | { | ||
| 8267 | let val_ref = &self.r#dhcp_up; | ||
| 8268 | if *val_ref != 0 { | ||
| 8269 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8270 | } | ||
| 8271 | } | ||
| 8272 | { | ||
| 8273 | let val_ref = &self.r#dhcp_ip; | ||
| 8274 | if !val_ref.is_empty() { | ||
| 8275 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8276 | } | ||
| 8277 | } | ||
| 8278 | { | ||
| 8279 | let val_ref = &self.r#dhcp_nm; | ||
| 8280 | if !val_ref.is_empty() { | ||
| 8281 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8282 | } | ||
| 8283 | } | ||
| 8284 | { | ||
| 8285 | let val_ref = &self.r#dhcp_gw; | ||
| 8286 | if !val_ref.is_empty() { | ||
| 8287 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8288 | } | ||
| 8289 | } | ||
| 8290 | { | ||
| 8291 | let val_ref = &self.r#dns_up; | ||
| 8292 | if *val_ref != 0 { | ||
| 8293 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8294 | } | ||
| 8295 | } | ||
| 8296 | { | ||
| 8297 | let val_ref = &self.r#dns_ip; | ||
| 8298 | if !val_ref.is_empty() { | ||
| 8299 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8300 | } | ||
| 8301 | } | ||
| 8302 | { | ||
| 8303 | let val_ref = &self.r#dns_type; | ||
| 8304 | if *val_ref != 0 { | ||
| 8305 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8306 | } | ||
| 8307 | } | ||
| 8308 | size | ||
| 8309 | } | ||
| 8310 | } | ||
| 8311 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 8312 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 8313 | pub struct CtrlMsg_Event_ESPInit { | ||
| 8314 | pub r#init_data: ::micropb::heapless::Vec<u8, 64>, | ||
| 8315 | } | ||
| 8316 | impl CtrlMsg_Event_ESPInit { | ||
| 8317 | ///Return a reference to `init_data` | ||
| 8318 | #[inline] | ||
| 8319 | pub fn r#init_data(&self) -> &::micropb::heapless::Vec<u8, 64> { | ||
| 8320 | &self.r#init_data | ||
| 8321 | } | ||
| 8322 | ///Return a mutable reference to `init_data` | ||
| 8323 | #[inline] | ||
| 8324 | pub fn mut_init_data(&mut self) -> &mut ::micropb::heapless::Vec<u8, 64> { | ||
| 8325 | &mut self.r#init_data | ||
| 8326 | } | ||
| 8327 | ///Set the value of `init_data` | ||
| 8328 | #[inline] | ||
| 8329 | pub fn set_init_data(&mut self, value: ::micropb::heapless::Vec<u8, 64>) -> &mut Self { | ||
| 8330 | self.r#init_data = value.into(); | ||
| 8331 | self | ||
| 8332 | } | ||
| 8333 | ///Builder method that sets the value of `init_data`. Useful for initializing the message. | ||
| 8334 | #[inline] | ||
| 8335 | pub fn init_init_data(mut self, value: ::micropb::heapless::Vec<u8, 64>) -> Self { | ||
| 8336 | self.r#init_data = value.into(); | ||
| 8337 | self | ||
| 8338 | } | ||
| 8339 | } | ||
| 8340 | impl ::micropb::MessageDecode for CtrlMsg_Event_ESPInit { | ||
| 8341 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 8342 | &mut self, | ||
| 8343 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 8344 | len: usize, | ||
| 8345 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 8346 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 8347 | let before = decoder.bytes_read(); | ||
| 8348 | while decoder.bytes_read() - before < len { | ||
| 8349 | let tag = decoder.decode_tag()?; | ||
| 8350 | match tag.field_num() { | ||
| 8351 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 8352 | 1u32 => { | ||
| 8353 | let mut_ref = &mut self.r#init_data; | ||
| 8354 | { | ||
| 8355 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8356 | }; | ||
| 8357 | } | ||
| 8358 | _ => { | ||
| 8359 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 8360 | } | ||
| 8361 | } | ||
| 8362 | } | ||
| 8363 | Ok(()) | ||
| 8364 | } | ||
| 8365 | } | ||
| 8366 | impl ::micropb::MessageEncode for CtrlMsg_Event_ESPInit { | ||
| 8367 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 8368 | let mut max_size = 0; | ||
| 8369 | if let ::core::option::Option::Some(size) = | ||
| 8370 | ::micropb::const_map!(::core::option::Option::Some(65usize), |size| size + 1usize) | ||
| 8371 | { | ||
| 8372 | max_size += size; | ||
| 8373 | } else { | ||
| 8374 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8375 | }; | ||
| 8376 | ::core::option::Option::Some(max_size) | ||
| 8377 | }; | ||
| 8378 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 8379 | &self, | ||
| 8380 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 8381 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 8382 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8383 | { | ||
| 8384 | let val_ref = &self.r#init_data; | ||
| 8385 | if !val_ref.is_empty() { | ||
| 8386 | encoder.encode_varint32(10u32)?; | ||
| 8387 | encoder.encode_bytes(val_ref)?; | ||
| 8388 | } | ||
| 8389 | } | ||
| 8390 | Ok(()) | ||
| 8391 | } | ||
| 8392 | fn compute_size(&self) -> usize { | ||
| 8393 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8394 | let mut size = 0; | ||
| 8395 | { | ||
| 8396 | let val_ref = &self.r#init_data; | ||
| 8397 | if !val_ref.is_empty() { | ||
| 8398 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8399 | } | ||
| 8400 | } | ||
| 8401 | size | ||
| 8402 | } | ||
| 8403 | } | ||
| 8404 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 8405 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 8406 | pub struct CtrlMsg_Event_Heartbeat { | ||
| 8407 | pub r#hb_num: i32, | ||
| 8408 | } | ||
| 8409 | impl CtrlMsg_Event_Heartbeat { | ||
| 8410 | ///Return a reference to `hb_num` | ||
| 8411 | #[inline] | ||
| 8412 | pub fn r#hb_num(&self) -> &i32 { | ||
| 8413 | &self.r#hb_num | ||
| 8414 | } | ||
| 8415 | ///Return a mutable reference to `hb_num` | ||
| 8416 | #[inline] | ||
| 8417 | pub fn mut_hb_num(&mut self) -> &mut i32 { | ||
| 8418 | &mut self.r#hb_num | ||
| 8419 | } | ||
| 8420 | ///Set the value of `hb_num` | ||
| 8421 | #[inline] | ||
| 8422 | pub fn set_hb_num(&mut self, value: i32) -> &mut Self { | ||
| 8423 | self.r#hb_num = value.into(); | ||
| 8424 | self | ||
| 8425 | } | ||
| 8426 | ///Builder method that sets the value of `hb_num`. Useful for initializing the message. | ||
| 8427 | #[inline] | ||
| 8428 | pub fn init_hb_num(mut self, value: i32) -> Self { | ||
| 8429 | self.r#hb_num = value.into(); | ||
| 8430 | self | ||
| 8431 | } | ||
| 8432 | } | ||
| 8433 | impl ::micropb::MessageDecode for CtrlMsg_Event_Heartbeat { | ||
| 8434 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 8435 | &mut self, | ||
| 8436 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 8437 | len: usize, | ||
| 8438 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 8439 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 8440 | let before = decoder.bytes_read(); | ||
| 8441 | while decoder.bytes_read() - before < len { | ||
| 8442 | let tag = decoder.decode_tag()?; | ||
| 8443 | match tag.field_num() { | ||
| 8444 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 8445 | 1u32 => { | ||
| 8446 | let mut_ref = &mut self.r#hb_num; | ||
| 8447 | { | ||
| 8448 | let val = decoder.decode_int32()?; | ||
| 8449 | let val_ref = &val; | ||
| 8450 | if *val_ref != 0 { | ||
| 8451 | *mut_ref = val as _; | ||
| 8452 | } | ||
| 8453 | }; | ||
| 8454 | } | ||
| 8455 | _ => { | ||
| 8456 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 8457 | } | ||
| 8458 | } | ||
| 8459 | } | ||
| 8460 | Ok(()) | ||
| 8461 | } | ||
| 8462 | } | ||
| 8463 | impl ::micropb::MessageEncode for CtrlMsg_Event_Heartbeat { | ||
| 8464 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 8465 | let mut max_size = 0; | ||
| 8466 | if let ::core::option::Option::Some(size) = | ||
| 8467 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8468 | { | ||
| 8469 | max_size += size; | ||
| 8470 | } else { | ||
| 8471 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8472 | }; | ||
| 8473 | ::core::option::Option::Some(max_size) | ||
| 8474 | }; | ||
| 8475 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 8476 | &self, | ||
| 8477 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 8478 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 8479 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8480 | { | ||
| 8481 | let val_ref = &self.r#hb_num; | ||
| 8482 | if *val_ref != 0 { | ||
| 8483 | encoder.encode_varint32(8u32)?; | ||
| 8484 | encoder.encode_int32(*val_ref as _)?; | ||
| 8485 | } | ||
| 8486 | } | ||
| 8487 | Ok(()) | ||
| 8488 | } | ||
| 8489 | fn compute_size(&self) -> usize { | ||
| 8490 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8491 | let mut size = 0; | ||
| 8492 | { | ||
| 8493 | let val_ref = &self.r#hb_num; | ||
| 8494 | if *val_ref != 0 { | ||
| 8495 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8496 | } | ||
| 8497 | } | ||
| 8498 | size | ||
| 8499 | } | ||
| 8500 | } | ||
| 8501 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 8502 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 8503 | pub struct CtrlMsg_Event_StationDisconnectFromAP { | ||
| 8504 | pub r#resp: i32, | ||
| 8505 | pub r#ssid: ::micropb::heapless::Vec<u8, 32>, | ||
| 8506 | pub r#ssid_len: u32, | ||
| 8507 | pub r#bssid: ::micropb::heapless::Vec<u8, 32>, | ||
| 8508 | pub r#reason: u32, | ||
| 8509 | pub r#rssi: i32, | ||
| 8510 | } | ||
| 8511 | impl CtrlMsg_Event_StationDisconnectFromAP { | ||
| 8512 | ///Return a reference to `resp` | ||
| 8513 | #[inline] | ||
| 8514 | pub fn r#resp(&self) -> &i32 { | ||
| 8515 | &self.r#resp | ||
| 8516 | } | ||
| 8517 | ///Return a mutable reference to `resp` | ||
| 8518 | #[inline] | ||
| 8519 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 8520 | &mut self.r#resp | ||
| 8521 | } | ||
| 8522 | ///Set the value of `resp` | ||
| 8523 | #[inline] | ||
| 8524 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 8525 | self.r#resp = value.into(); | ||
| 8526 | self | ||
| 8527 | } | ||
| 8528 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 8529 | #[inline] | ||
| 8530 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 8531 | self.r#resp = value.into(); | ||
| 8532 | self | ||
| 8533 | } | ||
| 8534 | ///Return a reference to `ssid` | ||
| 8535 | #[inline] | ||
| 8536 | pub fn r#ssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 8537 | &self.r#ssid | ||
| 8538 | } | ||
| 8539 | ///Return a mutable reference to `ssid` | ||
| 8540 | #[inline] | ||
| 8541 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 8542 | &mut self.r#ssid | ||
| 8543 | } | ||
| 8544 | ///Set the value of `ssid` | ||
| 8545 | #[inline] | ||
| 8546 | pub fn set_ssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 8547 | self.r#ssid = value.into(); | ||
| 8548 | self | ||
| 8549 | } | ||
| 8550 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. | ||
| 8551 | #[inline] | ||
| 8552 | pub fn init_ssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 8553 | self.r#ssid = value.into(); | ||
| 8554 | self | ||
| 8555 | } | ||
| 8556 | ///Return a reference to `ssid_len` | ||
| 8557 | #[inline] | ||
| 8558 | pub fn r#ssid_len(&self) -> &u32 { | ||
| 8559 | &self.r#ssid_len | ||
| 8560 | } | ||
| 8561 | ///Return a mutable reference to `ssid_len` | ||
| 8562 | #[inline] | ||
| 8563 | pub fn mut_ssid_len(&mut self) -> &mut u32 { | ||
| 8564 | &mut self.r#ssid_len | ||
| 8565 | } | ||
| 8566 | ///Set the value of `ssid_len` | ||
| 8567 | #[inline] | ||
| 8568 | pub fn set_ssid_len(&mut self, value: u32) -> &mut Self { | ||
| 8569 | self.r#ssid_len = value.into(); | ||
| 8570 | self | ||
| 8571 | } | ||
| 8572 | ///Builder method that sets the value of `ssid_len`. Useful for initializing the message. | ||
| 8573 | #[inline] | ||
| 8574 | pub fn init_ssid_len(mut self, value: u32) -> Self { | ||
| 8575 | self.r#ssid_len = value.into(); | ||
| 8576 | self | ||
| 8577 | } | ||
| 8578 | ///Return a reference to `bssid` | ||
| 8579 | #[inline] | ||
| 8580 | pub fn r#bssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 8581 | &self.r#bssid | ||
| 8582 | } | ||
| 8583 | ///Return a mutable reference to `bssid` | ||
| 8584 | #[inline] | ||
| 8585 | pub fn mut_bssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 8586 | &mut self.r#bssid | ||
| 8587 | } | ||
| 8588 | ///Set the value of `bssid` | ||
| 8589 | #[inline] | ||
| 8590 | pub fn set_bssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 8591 | self.r#bssid = value.into(); | ||
| 8592 | self | ||
| 8593 | } | ||
| 8594 | ///Builder method that sets the value of `bssid`. Useful for initializing the message. | ||
| 8595 | #[inline] | ||
| 8596 | pub fn init_bssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 8597 | self.r#bssid = value.into(); | ||
| 8598 | self | ||
| 8599 | } | ||
| 8600 | ///Return a reference to `reason` | ||
| 8601 | #[inline] | ||
| 8602 | pub fn r#reason(&self) -> &u32 { | ||
| 8603 | &self.r#reason | ||
| 8604 | } | ||
| 8605 | ///Return a mutable reference to `reason` | ||
| 8606 | #[inline] | ||
| 8607 | pub fn mut_reason(&mut self) -> &mut u32 { | ||
| 8608 | &mut self.r#reason | ||
| 8609 | } | ||
| 8610 | ///Set the value of `reason` | ||
| 8611 | #[inline] | ||
| 8612 | pub fn set_reason(&mut self, value: u32) -> &mut Self { | ||
| 8613 | self.r#reason = value.into(); | ||
| 8614 | self | ||
| 8615 | } | ||
| 8616 | ///Builder method that sets the value of `reason`. Useful for initializing the message. | ||
| 8617 | #[inline] | ||
| 8618 | pub fn init_reason(mut self, value: u32) -> Self { | ||
| 8619 | self.r#reason = value.into(); | ||
| 8620 | self | ||
| 8621 | } | ||
| 8622 | ///Return a reference to `rssi` | ||
| 8623 | #[inline] | ||
| 8624 | pub fn r#rssi(&self) -> &i32 { | ||
| 8625 | &self.r#rssi | ||
| 8626 | } | ||
| 8627 | ///Return a mutable reference to `rssi` | ||
| 8628 | #[inline] | ||
| 8629 | pub fn mut_rssi(&mut self) -> &mut i32 { | ||
| 8630 | &mut self.r#rssi | ||
| 8631 | } | ||
| 8632 | ///Set the value of `rssi` | ||
| 8633 | #[inline] | ||
| 8634 | pub fn set_rssi(&mut self, value: i32) -> &mut Self { | ||
| 8635 | self.r#rssi = value.into(); | ||
| 8636 | self | ||
| 8637 | } | ||
| 8638 | ///Builder method that sets the value of `rssi`. Useful for initializing the message. | ||
| 8639 | #[inline] | ||
| 8640 | pub fn init_rssi(mut self, value: i32) -> Self { | ||
| 8641 | self.r#rssi = value.into(); | ||
| 8642 | self | ||
| 8643 | } | ||
| 8644 | } | ||
| 8645 | impl ::micropb::MessageDecode for CtrlMsg_Event_StationDisconnectFromAP { | ||
| 8646 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 8647 | &mut self, | ||
| 8648 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 8649 | len: usize, | ||
| 8650 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 8651 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 8652 | let before = decoder.bytes_read(); | ||
| 8653 | while decoder.bytes_read() - before < len { | ||
| 8654 | let tag = decoder.decode_tag()?; | ||
| 8655 | match tag.field_num() { | ||
| 8656 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 8657 | 1u32 => { | ||
| 8658 | let mut_ref = &mut self.r#resp; | ||
| 8659 | { | ||
| 8660 | let val = decoder.decode_int32()?; | ||
| 8661 | let val_ref = &val; | ||
| 8662 | if *val_ref != 0 { | ||
| 8663 | *mut_ref = val as _; | ||
| 8664 | } | ||
| 8665 | }; | ||
| 8666 | } | ||
| 8667 | 2u32 => { | ||
| 8668 | let mut_ref = &mut self.r#ssid; | ||
| 8669 | { | ||
| 8670 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8671 | }; | ||
| 8672 | } | ||
| 8673 | 3u32 => { | ||
| 8674 | let mut_ref = &mut self.r#ssid_len; | ||
| 8675 | { | ||
| 8676 | let val = decoder.decode_varint32()?; | ||
| 8677 | let val_ref = &val; | ||
| 8678 | if *val_ref != 0 { | ||
| 8679 | *mut_ref = val as _; | ||
| 8680 | } | ||
| 8681 | }; | ||
| 8682 | } | ||
| 8683 | 4u32 => { | ||
| 8684 | let mut_ref = &mut self.r#bssid; | ||
| 8685 | { | ||
| 8686 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 8687 | }; | ||
| 8688 | } | ||
| 8689 | 5u32 => { | ||
| 8690 | let mut_ref = &mut self.r#reason; | ||
| 8691 | { | ||
| 8692 | let val = decoder.decode_varint32()?; | ||
| 8693 | let val_ref = &val; | ||
| 8694 | if *val_ref != 0 { | ||
| 8695 | *mut_ref = val as _; | ||
| 8696 | } | ||
| 8697 | }; | ||
| 8698 | } | ||
| 8699 | 6u32 => { | ||
| 8700 | let mut_ref = &mut self.r#rssi; | ||
| 8701 | { | ||
| 8702 | let val = decoder.decode_int32()?; | ||
| 8703 | let val_ref = &val; | ||
| 8704 | if *val_ref != 0 { | ||
| 8705 | *mut_ref = val as _; | ||
| 8706 | } | ||
| 8707 | }; | ||
| 8708 | } | ||
| 8709 | _ => { | ||
| 8710 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 8711 | } | ||
| 8712 | } | ||
| 8713 | } | ||
| 8714 | Ok(()) | ||
| 8715 | } | ||
| 8716 | } | ||
| 8717 | impl ::micropb::MessageEncode for CtrlMsg_Event_StationDisconnectFromAP { | ||
| 8718 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 8719 | let mut max_size = 0; | ||
| 8720 | if let ::core::option::Option::Some(size) = | ||
| 8721 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8722 | { | ||
| 8723 | max_size += size; | ||
| 8724 | } else { | ||
| 8725 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8726 | }; | ||
| 8727 | if let ::core::option::Option::Some(size) = | ||
| 8728 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 8729 | { | ||
| 8730 | max_size += size; | ||
| 8731 | } else { | ||
| 8732 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8733 | }; | ||
| 8734 | if let ::core::option::Option::Some(size) = | ||
| 8735 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 8736 | { | ||
| 8737 | max_size += size; | ||
| 8738 | } else { | ||
| 8739 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8740 | }; | ||
| 8741 | if let ::core::option::Option::Some(size) = | ||
| 8742 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 8743 | { | ||
| 8744 | max_size += size; | ||
| 8745 | } else { | ||
| 8746 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8747 | }; | ||
| 8748 | if let ::core::option::Option::Some(size) = | ||
| 8749 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 8750 | { | ||
| 8751 | max_size += size; | ||
| 8752 | } else { | ||
| 8753 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8754 | }; | ||
| 8755 | if let ::core::option::Option::Some(size) = | ||
| 8756 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 8757 | { | ||
| 8758 | max_size += size; | ||
| 8759 | } else { | ||
| 8760 | break 'msg (::core::option::Option::<usize>::None); | ||
| 8761 | }; | ||
| 8762 | ::core::option::Option::Some(max_size) | ||
| 8763 | }; | ||
| 8764 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 8765 | &self, | ||
| 8766 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 8767 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 8768 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8769 | { | ||
| 8770 | let val_ref = &self.r#resp; | ||
| 8771 | if *val_ref != 0 { | ||
| 8772 | encoder.encode_varint32(8u32)?; | ||
| 8773 | encoder.encode_int32(*val_ref as _)?; | ||
| 8774 | } | ||
| 8775 | } | ||
| 8776 | { | ||
| 8777 | let val_ref = &self.r#ssid; | ||
| 8778 | if !val_ref.is_empty() { | ||
| 8779 | encoder.encode_varint32(18u32)?; | ||
| 8780 | encoder.encode_bytes(val_ref)?; | ||
| 8781 | } | ||
| 8782 | } | ||
| 8783 | { | ||
| 8784 | let val_ref = &self.r#ssid_len; | ||
| 8785 | if *val_ref != 0 { | ||
| 8786 | encoder.encode_varint32(24u32)?; | ||
| 8787 | encoder.encode_varint32(*val_ref as _)?; | ||
| 8788 | } | ||
| 8789 | } | ||
| 8790 | { | ||
| 8791 | let val_ref = &self.r#bssid; | ||
| 8792 | if !val_ref.is_empty() { | ||
| 8793 | encoder.encode_varint32(34u32)?; | ||
| 8794 | encoder.encode_bytes(val_ref)?; | ||
| 8795 | } | ||
| 8796 | } | ||
| 8797 | { | ||
| 8798 | let val_ref = &self.r#reason; | ||
| 8799 | if *val_ref != 0 { | ||
| 8800 | encoder.encode_varint32(40u32)?; | ||
| 8801 | encoder.encode_varint32(*val_ref as _)?; | ||
| 8802 | } | ||
| 8803 | } | ||
| 8804 | { | ||
| 8805 | let val_ref = &self.r#rssi; | ||
| 8806 | if *val_ref != 0 { | ||
| 8807 | encoder.encode_varint32(48u32)?; | ||
| 8808 | encoder.encode_int32(*val_ref as _)?; | ||
| 8809 | } | ||
| 8810 | } | ||
| 8811 | Ok(()) | ||
| 8812 | } | ||
| 8813 | fn compute_size(&self) -> usize { | ||
| 8814 | use ::micropb::{FieldEncode, PbMap}; | ||
| 8815 | let mut size = 0; | ||
| 8816 | { | ||
| 8817 | let val_ref = &self.r#resp; | ||
| 8818 | if *val_ref != 0 { | ||
| 8819 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8820 | } | ||
| 8821 | } | ||
| 8822 | { | ||
| 8823 | let val_ref = &self.r#ssid; | ||
| 8824 | if !val_ref.is_empty() { | ||
| 8825 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8826 | } | ||
| 8827 | } | ||
| 8828 | { | ||
| 8829 | let val_ref = &self.r#ssid_len; | ||
| 8830 | if *val_ref != 0 { | ||
| 8831 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 8832 | } | ||
| 8833 | } | ||
| 8834 | { | ||
| 8835 | let val_ref = &self.r#bssid; | ||
| 8836 | if !val_ref.is_empty() { | ||
| 8837 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 8838 | } | ||
| 8839 | } | ||
| 8840 | { | ||
| 8841 | let val_ref = &self.r#reason; | ||
| 8842 | if *val_ref != 0 { | ||
| 8843 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 8844 | } | ||
| 8845 | } | ||
| 8846 | { | ||
| 8847 | let val_ref = &self.r#rssi; | ||
| 8848 | if *val_ref != 0 { | ||
| 8849 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 8850 | } | ||
| 8851 | } | ||
| 8852 | size | ||
| 8853 | } | ||
| 8854 | } | ||
| 8855 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 8856 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 8857 | pub struct CtrlMsg_Event_StationConnectedToAP { | ||
| 8858 | pub r#resp: i32, | ||
| 8859 | pub r#ssid: ::micropb::heapless::Vec<u8, 32>, | ||
| 8860 | pub r#ssid_len: u32, | ||
| 8861 | pub r#bssid: ::micropb::heapless::Vec<u8, 32>, | ||
| 8862 | pub r#channel: u32, | ||
| 8863 | pub r#authmode: i32, | ||
| 8864 | pub r#aid: i32, | ||
| 8865 | } | ||
| 8866 | impl CtrlMsg_Event_StationConnectedToAP { | ||
| 8867 | ///Return a reference to `resp` | ||
| 8868 | #[inline] | ||
| 8869 | pub fn r#resp(&self) -> &i32 { | ||
| 8870 | &self.r#resp | ||
| 8871 | } | ||
| 8872 | ///Return a mutable reference to `resp` | ||
| 8873 | #[inline] | ||
| 8874 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 8875 | &mut self.r#resp | ||
| 8876 | } | ||
| 8877 | ///Set the value of `resp` | ||
| 8878 | #[inline] | ||
| 8879 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 8880 | self.r#resp = value.into(); | ||
| 8881 | self | ||
| 8882 | } | ||
| 8883 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 8884 | #[inline] | ||
| 8885 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 8886 | self.r#resp = value.into(); | ||
| 8887 | self | ||
| 8888 | } | ||
| 8889 | ///Return a reference to `ssid` | ||
| 8890 | #[inline] | ||
| 8891 | pub fn r#ssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 8892 | &self.r#ssid | ||
| 8893 | } | ||
| 8894 | ///Return a mutable reference to `ssid` | ||
| 8895 | #[inline] | ||
| 8896 | pub fn mut_ssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 8897 | &mut self.r#ssid | ||
| 8898 | } | ||
| 8899 | ///Set the value of `ssid` | ||
| 8900 | #[inline] | ||
| 8901 | pub fn set_ssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 8902 | self.r#ssid = value.into(); | ||
| 8903 | self | ||
| 8904 | } | ||
| 8905 | ///Builder method that sets the value of `ssid`. Useful for initializing the message. | ||
| 8906 | #[inline] | ||
| 8907 | pub fn init_ssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 8908 | self.r#ssid = value.into(); | ||
| 8909 | self | ||
| 8910 | } | ||
| 8911 | ///Return a reference to `ssid_len` | ||
| 8912 | #[inline] | ||
| 8913 | pub fn r#ssid_len(&self) -> &u32 { | ||
| 8914 | &self.r#ssid_len | ||
| 8915 | } | ||
| 8916 | ///Return a mutable reference to `ssid_len` | ||
| 8917 | #[inline] | ||
| 8918 | pub fn mut_ssid_len(&mut self) -> &mut u32 { | ||
| 8919 | &mut self.r#ssid_len | ||
| 8920 | } | ||
| 8921 | ///Set the value of `ssid_len` | ||
| 8922 | #[inline] | ||
| 8923 | pub fn set_ssid_len(&mut self, value: u32) -> &mut Self { | ||
| 8924 | self.r#ssid_len = value.into(); | ||
| 8925 | self | ||
| 8926 | } | ||
| 8927 | ///Builder method that sets the value of `ssid_len`. Useful for initializing the message. | ||
| 8928 | #[inline] | ||
| 8929 | pub fn init_ssid_len(mut self, value: u32) -> Self { | ||
| 8930 | self.r#ssid_len = value.into(); | ||
| 8931 | self | ||
| 8932 | } | ||
| 8933 | ///Return a reference to `bssid` | ||
| 8934 | #[inline] | ||
| 8935 | pub fn r#bssid(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 8936 | &self.r#bssid | ||
| 8937 | } | ||
| 8938 | ///Return a mutable reference to `bssid` | ||
| 8939 | #[inline] | ||
| 8940 | pub fn mut_bssid(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 8941 | &mut self.r#bssid | ||
| 8942 | } | ||
| 8943 | ///Set the value of `bssid` | ||
| 8944 | #[inline] | ||
| 8945 | pub fn set_bssid(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 8946 | self.r#bssid = value.into(); | ||
| 8947 | self | ||
| 8948 | } | ||
| 8949 | ///Builder method that sets the value of `bssid`. Useful for initializing the message. | ||
| 8950 | #[inline] | ||
| 8951 | pub fn init_bssid(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 8952 | self.r#bssid = value.into(); | ||
| 8953 | self | ||
| 8954 | } | ||
| 8955 | ///Return a reference to `channel` | ||
| 8956 | #[inline] | ||
| 8957 | pub fn r#channel(&self) -> &u32 { | ||
| 8958 | &self.r#channel | ||
| 8959 | } | ||
| 8960 | ///Return a mutable reference to `channel` | ||
| 8961 | #[inline] | ||
| 8962 | pub fn mut_channel(&mut self) -> &mut u32 { | ||
| 8963 | &mut self.r#channel | ||
| 8964 | } | ||
| 8965 | ///Set the value of `channel` | ||
| 8966 | #[inline] | ||
| 8967 | pub fn set_channel(&mut self, value: u32) -> &mut Self { | ||
| 8968 | self.r#channel = value.into(); | ||
| 8969 | self | ||
| 8970 | } | ||
| 8971 | ///Builder method that sets the value of `channel`. Useful for initializing the message. | ||
| 8972 | #[inline] | ||
| 8973 | pub fn init_channel(mut self, value: u32) -> Self { | ||
| 8974 | self.r#channel = value.into(); | ||
| 8975 | self | ||
| 8976 | } | ||
| 8977 | ///Return a reference to `authmode` | ||
| 8978 | #[inline] | ||
| 8979 | pub fn r#authmode(&self) -> &i32 { | ||
| 8980 | &self.r#authmode | ||
| 8981 | } | ||
| 8982 | ///Return a mutable reference to `authmode` | ||
| 8983 | #[inline] | ||
| 8984 | pub fn mut_authmode(&mut self) -> &mut i32 { | ||
| 8985 | &mut self.r#authmode | ||
| 8986 | } | ||
| 8987 | ///Set the value of `authmode` | ||
| 8988 | #[inline] | ||
| 8989 | pub fn set_authmode(&mut self, value: i32) -> &mut Self { | ||
| 8990 | self.r#authmode = value.into(); | ||
| 8991 | self | ||
| 8992 | } | ||
| 8993 | ///Builder method that sets the value of `authmode`. Useful for initializing the message. | ||
| 8994 | #[inline] | ||
| 8995 | pub fn init_authmode(mut self, value: i32) -> Self { | ||
| 8996 | self.r#authmode = value.into(); | ||
| 8997 | self | ||
| 8998 | } | ||
| 8999 | ///Return a reference to `aid` | ||
| 9000 | #[inline] | ||
| 9001 | pub fn r#aid(&self) -> &i32 { | ||
| 9002 | &self.r#aid | ||
| 9003 | } | ||
| 9004 | ///Return a mutable reference to `aid` | ||
| 9005 | #[inline] | ||
| 9006 | pub fn mut_aid(&mut self) -> &mut i32 { | ||
| 9007 | &mut self.r#aid | ||
| 9008 | } | ||
| 9009 | ///Set the value of `aid` | ||
| 9010 | #[inline] | ||
| 9011 | pub fn set_aid(&mut self, value: i32) -> &mut Self { | ||
| 9012 | self.r#aid = value.into(); | ||
| 9013 | self | ||
| 9014 | } | ||
| 9015 | ///Builder method that sets the value of `aid`. Useful for initializing the message. | ||
| 9016 | #[inline] | ||
| 9017 | pub fn init_aid(mut self, value: i32) -> Self { | ||
| 9018 | self.r#aid = value.into(); | ||
| 9019 | self | ||
| 9020 | } | ||
| 9021 | } | ||
| 9022 | impl ::micropb::MessageDecode for CtrlMsg_Event_StationConnectedToAP { | ||
| 9023 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 9024 | &mut self, | ||
| 9025 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 9026 | len: usize, | ||
| 9027 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 9028 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 9029 | let before = decoder.bytes_read(); | ||
| 9030 | while decoder.bytes_read() - before < len { | ||
| 9031 | let tag = decoder.decode_tag()?; | ||
| 9032 | match tag.field_num() { | ||
| 9033 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 9034 | 1u32 => { | ||
| 9035 | let mut_ref = &mut self.r#resp; | ||
| 9036 | { | ||
| 9037 | let val = decoder.decode_int32()?; | ||
| 9038 | let val_ref = &val; | ||
| 9039 | if *val_ref != 0 { | ||
| 9040 | *mut_ref = val as _; | ||
| 9041 | } | ||
| 9042 | }; | ||
| 9043 | } | ||
| 9044 | 2u32 => { | ||
| 9045 | let mut_ref = &mut self.r#ssid; | ||
| 9046 | { | ||
| 9047 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 9048 | }; | ||
| 9049 | } | ||
| 9050 | 3u32 => { | ||
| 9051 | let mut_ref = &mut self.r#ssid_len; | ||
| 9052 | { | ||
| 9053 | let val = decoder.decode_varint32()?; | ||
| 9054 | let val_ref = &val; | ||
| 9055 | if *val_ref != 0 { | ||
| 9056 | *mut_ref = val as _; | ||
| 9057 | } | ||
| 9058 | }; | ||
| 9059 | } | ||
| 9060 | 4u32 => { | ||
| 9061 | let mut_ref = &mut self.r#bssid; | ||
| 9062 | { | ||
| 9063 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 9064 | }; | ||
| 9065 | } | ||
| 9066 | 5u32 => { | ||
| 9067 | let mut_ref = &mut self.r#channel; | ||
| 9068 | { | ||
| 9069 | let val = decoder.decode_varint32()?; | ||
| 9070 | let val_ref = &val; | ||
| 9071 | if *val_ref != 0 { | ||
| 9072 | *mut_ref = val as _; | ||
| 9073 | } | ||
| 9074 | }; | ||
| 9075 | } | ||
| 9076 | 6u32 => { | ||
| 9077 | let mut_ref = &mut self.r#authmode; | ||
| 9078 | { | ||
| 9079 | let val = decoder.decode_int32()?; | ||
| 9080 | let val_ref = &val; | ||
| 9081 | if *val_ref != 0 { | ||
| 9082 | *mut_ref = val as _; | ||
| 9083 | } | ||
| 9084 | }; | ||
| 9085 | } | ||
| 9086 | 7u32 => { | ||
| 9087 | let mut_ref = &mut self.r#aid; | ||
| 9088 | { | ||
| 9089 | let val = decoder.decode_int32()?; | ||
| 9090 | let val_ref = &val; | ||
| 9091 | if *val_ref != 0 { | ||
| 9092 | *mut_ref = val as _; | ||
| 9093 | } | ||
| 9094 | }; | ||
| 9095 | } | ||
| 9096 | _ => { | ||
| 9097 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 9098 | } | ||
| 9099 | } | ||
| 9100 | } | ||
| 9101 | Ok(()) | ||
| 9102 | } | ||
| 9103 | } | ||
| 9104 | impl ::micropb::MessageEncode for CtrlMsg_Event_StationConnectedToAP { | ||
| 9105 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 9106 | let mut max_size = 0; | ||
| 9107 | if let ::core::option::Option::Some(size) = | ||
| 9108 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 9109 | { | ||
| 9110 | max_size += size; | ||
| 9111 | } else { | ||
| 9112 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9113 | }; | ||
| 9114 | if let ::core::option::Option::Some(size) = | ||
| 9115 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 9116 | { | ||
| 9117 | max_size += size; | ||
| 9118 | } else { | ||
| 9119 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9120 | }; | ||
| 9121 | if let ::core::option::Option::Some(size) = | ||
| 9122 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 9123 | { | ||
| 9124 | max_size += size; | ||
| 9125 | } else { | ||
| 9126 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9127 | }; | ||
| 9128 | if let ::core::option::Option::Some(size) = | ||
| 9129 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 9130 | { | ||
| 9131 | max_size += size; | ||
| 9132 | } else { | ||
| 9133 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9134 | }; | ||
| 9135 | if let ::core::option::Option::Some(size) = | ||
| 9136 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 9137 | { | ||
| 9138 | max_size += size; | ||
| 9139 | } else { | ||
| 9140 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9141 | }; | ||
| 9142 | if let ::core::option::Option::Some(size) = | ||
| 9143 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 9144 | { | ||
| 9145 | max_size += size; | ||
| 9146 | } else { | ||
| 9147 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9148 | }; | ||
| 9149 | if let ::core::option::Option::Some(size) = | ||
| 9150 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 9151 | { | ||
| 9152 | max_size += size; | ||
| 9153 | } else { | ||
| 9154 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9155 | }; | ||
| 9156 | ::core::option::Option::Some(max_size) | ||
| 9157 | }; | ||
| 9158 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 9159 | &self, | ||
| 9160 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 9161 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 9162 | use ::micropb::{FieldEncode, PbMap}; | ||
| 9163 | { | ||
| 9164 | let val_ref = &self.r#resp; | ||
| 9165 | if *val_ref != 0 { | ||
| 9166 | encoder.encode_varint32(8u32)?; | ||
| 9167 | encoder.encode_int32(*val_ref as _)?; | ||
| 9168 | } | ||
| 9169 | } | ||
| 9170 | { | ||
| 9171 | let val_ref = &self.r#ssid; | ||
| 9172 | if !val_ref.is_empty() { | ||
| 9173 | encoder.encode_varint32(18u32)?; | ||
| 9174 | encoder.encode_bytes(val_ref)?; | ||
| 9175 | } | ||
| 9176 | } | ||
| 9177 | { | ||
| 9178 | let val_ref = &self.r#ssid_len; | ||
| 9179 | if *val_ref != 0 { | ||
| 9180 | encoder.encode_varint32(24u32)?; | ||
| 9181 | encoder.encode_varint32(*val_ref as _)?; | ||
| 9182 | } | ||
| 9183 | } | ||
| 9184 | { | ||
| 9185 | let val_ref = &self.r#bssid; | ||
| 9186 | if !val_ref.is_empty() { | ||
| 9187 | encoder.encode_varint32(34u32)?; | ||
| 9188 | encoder.encode_bytes(val_ref)?; | ||
| 9189 | } | ||
| 9190 | } | ||
| 9191 | { | ||
| 9192 | let val_ref = &self.r#channel; | ||
| 9193 | if *val_ref != 0 { | ||
| 9194 | encoder.encode_varint32(40u32)?; | ||
| 9195 | encoder.encode_varint32(*val_ref as _)?; | ||
| 9196 | } | ||
| 9197 | } | ||
| 9198 | { | ||
| 9199 | let val_ref = &self.r#authmode; | ||
| 9200 | if *val_ref != 0 { | ||
| 9201 | encoder.encode_varint32(48u32)?; | ||
| 9202 | encoder.encode_int32(*val_ref as _)?; | ||
| 9203 | } | ||
| 9204 | } | ||
| 9205 | { | ||
| 9206 | let val_ref = &self.r#aid; | ||
| 9207 | if *val_ref != 0 { | ||
| 9208 | encoder.encode_varint32(56u32)?; | ||
| 9209 | encoder.encode_int32(*val_ref as _)?; | ||
| 9210 | } | ||
| 9211 | } | ||
| 9212 | Ok(()) | ||
| 9213 | } | ||
| 9214 | fn compute_size(&self) -> usize { | ||
| 9215 | use ::micropb::{FieldEncode, PbMap}; | ||
| 9216 | let mut size = 0; | ||
| 9217 | { | ||
| 9218 | let val_ref = &self.r#resp; | ||
| 9219 | if *val_ref != 0 { | ||
| 9220 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 9221 | } | ||
| 9222 | } | ||
| 9223 | { | ||
| 9224 | let val_ref = &self.r#ssid; | ||
| 9225 | if !val_ref.is_empty() { | ||
| 9226 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 9227 | } | ||
| 9228 | } | ||
| 9229 | { | ||
| 9230 | let val_ref = &self.r#ssid_len; | ||
| 9231 | if *val_ref != 0 { | ||
| 9232 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 9233 | } | ||
| 9234 | } | ||
| 9235 | { | ||
| 9236 | let val_ref = &self.r#bssid; | ||
| 9237 | if !val_ref.is_empty() { | ||
| 9238 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 9239 | } | ||
| 9240 | } | ||
| 9241 | { | ||
| 9242 | let val_ref = &self.r#channel; | ||
| 9243 | if *val_ref != 0 { | ||
| 9244 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 9245 | } | ||
| 9246 | } | ||
| 9247 | { | ||
| 9248 | let val_ref = &self.r#authmode; | ||
| 9249 | if *val_ref != 0 { | ||
| 9250 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 9251 | } | ||
| 9252 | } | ||
| 9253 | { | ||
| 9254 | let val_ref = &self.r#aid; | ||
| 9255 | if *val_ref != 0 { | ||
| 9256 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 9257 | } | ||
| 9258 | } | ||
| 9259 | size | ||
| 9260 | } | ||
| 9261 | } | ||
| 9262 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 9263 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 9264 | pub struct CtrlMsg_Event_StationDisconnectFromESPSoftAP { | ||
| 9265 | pub r#resp: i32, | ||
| 9266 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, | ||
| 9267 | pub r#aid: u32, | ||
| 9268 | pub r#is_mesh_child: bool, | ||
| 9269 | pub r#reason: u32, | ||
| 9270 | } | ||
| 9271 | impl CtrlMsg_Event_StationDisconnectFromESPSoftAP { | ||
| 9272 | ///Return a reference to `resp` | ||
| 9273 | #[inline] | ||
| 9274 | pub fn r#resp(&self) -> &i32 { | ||
| 9275 | &self.r#resp | ||
| 9276 | } | ||
| 9277 | ///Return a mutable reference to `resp` | ||
| 9278 | #[inline] | ||
| 9279 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 9280 | &mut self.r#resp | ||
| 9281 | } | ||
| 9282 | ///Set the value of `resp` | ||
| 9283 | #[inline] | ||
| 9284 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 9285 | self.r#resp = value.into(); | ||
| 9286 | self | ||
| 9287 | } | ||
| 9288 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 9289 | #[inline] | ||
| 9290 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 9291 | self.r#resp = value.into(); | ||
| 9292 | self | ||
| 9293 | } | ||
| 9294 | ///Return a reference to `mac` | ||
| 9295 | #[inline] | ||
| 9296 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 9297 | &self.r#mac | ||
| 9298 | } | ||
| 9299 | ///Return a mutable reference to `mac` | ||
| 9300 | #[inline] | ||
| 9301 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 9302 | &mut self.r#mac | ||
| 9303 | } | ||
| 9304 | ///Set the value of `mac` | ||
| 9305 | #[inline] | ||
| 9306 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 9307 | self.r#mac = value.into(); | ||
| 9308 | self | ||
| 9309 | } | ||
| 9310 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 9311 | #[inline] | ||
| 9312 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 9313 | self.r#mac = value.into(); | ||
| 9314 | self | ||
| 9315 | } | ||
| 9316 | ///Return a reference to `aid` | ||
| 9317 | #[inline] | ||
| 9318 | pub fn r#aid(&self) -> &u32 { | ||
| 9319 | &self.r#aid | ||
| 9320 | } | ||
| 9321 | ///Return a mutable reference to `aid` | ||
| 9322 | #[inline] | ||
| 9323 | pub fn mut_aid(&mut self) -> &mut u32 { | ||
| 9324 | &mut self.r#aid | ||
| 9325 | } | ||
| 9326 | ///Set the value of `aid` | ||
| 9327 | #[inline] | ||
| 9328 | pub fn set_aid(&mut self, value: u32) -> &mut Self { | ||
| 9329 | self.r#aid = value.into(); | ||
| 9330 | self | ||
| 9331 | } | ||
| 9332 | ///Builder method that sets the value of `aid`. Useful for initializing the message. | ||
| 9333 | #[inline] | ||
| 9334 | pub fn init_aid(mut self, value: u32) -> Self { | ||
| 9335 | self.r#aid = value.into(); | ||
| 9336 | self | ||
| 9337 | } | ||
| 9338 | ///Return a reference to `is_mesh_child` | ||
| 9339 | #[inline] | ||
| 9340 | pub fn r#is_mesh_child(&self) -> &bool { | ||
| 9341 | &self.r#is_mesh_child | ||
| 9342 | } | ||
| 9343 | ///Return a mutable reference to `is_mesh_child` | ||
| 9344 | #[inline] | ||
| 9345 | pub fn mut_is_mesh_child(&mut self) -> &mut bool { | ||
| 9346 | &mut self.r#is_mesh_child | ||
| 9347 | } | ||
| 9348 | ///Set the value of `is_mesh_child` | ||
| 9349 | #[inline] | ||
| 9350 | pub fn set_is_mesh_child(&mut self, value: bool) -> &mut Self { | ||
| 9351 | self.r#is_mesh_child = value.into(); | ||
| 9352 | self | ||
| 9353 | } | ||
| 9354 | ///Builder method that sets the value of `is_mesh_child`. Useful for initializing the message. | ||
| 9355 | #[inline] | ||
| 9356 | pub fn init_is_mesh_child(mut self, value: bool) -> Self { | ||
| 9357 | self.r#is_mesh_child = value.into(); | ||
| 9358 | self | ||
| 9359 | } | ||
| 9360 | ///Return a reference to `reason` | ||
| 9361 | #[inline] | ||
| 9362 | pub fn r#reason(&self) -> &u32 { | ||
| 9363 | &self.r#reason | ||
| 9364 | } | ||
| 9365 | ///Return a mutable reference to `reason` | ||
| 9366 | #[inline] | ||
| 9367 | pub fn mut_reason(&mut self) -> &mut u32 { | ||
| 9368 | &mut self.r#reason | ||
| 9369 | } | ||
| 9370 | ///Set the value of `reason` | ||
| 9371 | #[inline] | ||
| 9372 | pub fn set_reason(&mut self, value: u32) -> &mut Self { | ||
| 9373 | self.r#reason = value.into(); | ||
| 9374 | self | ||
| 9375 | } | ||
| 9376 | ///Builder method that sets the value of `reason`. Useful for initializing the message. | ||
| 9377 | #[inline] | ||
| 9378 | pub fn init_reason(mut self, value: u32) -> Self { | ||
| 9379 | self.r#reason = value.into(); | ||
| 9380 | self | ||
| 9381 | } | ||
| 9382 | } | ||
| 9383 | impl ::micropb::MessageDecode for CtrlMsg_Event_StationDisconnectFromESPSoftAP { | ||
| 9384 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 9385 | &mut self, | ||
| 9386 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 9387 | len: usize, | ||
| 9388 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 9389 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 9390 | let before = decoder.bytes_read(); | ||
| 9391 | while decoder.bytes_read() - before < len { | ||
| 9392 | let tag = decoder.decode_tag()?; | ||
| 9393 | match tag.field_num() { | ||
| 9394 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 9395 | 1u32 => { | ||
| 9396 | let mut_ref = &mut self.r#resp; | ||
| 9397 | { | ||
| 9398 | let val = decoder.decode_int32()?; | ||
| 9399 | let val_ref = &val; | ||
| 9400 | if *val_ref != 0 { | ||
| 9401 | *mut_ref = val as _; | ||
| 9402 | } | ||
| 9403 | }; | ||
| 9404 | } | ||
| 9405 | 2u32 => { | ||
| 9406 | let mut_ref = &mut self.r#mac; | ||
| 9407 | { | ||
| 9408 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 9409 | }; | ||
| 9410 | } | ||
| 9411 | 3u32 => { | ||
| 9412 | let mut_ref = &mut self.r#aid; | ||
| 9413 | { | ||
| 9414 | let val = decoder.decode_varint32()?; | ||
| 9415 | let val_ref = &val; | ||
| 9416 | if *val_ref != 0 { | ||
| 9417 | *mut_ref = val as _; | ||
| 9418 | } | ||
| 9419 | }; | ||
| 9420 | } | ||
| 9421 | 4u32 => { | ||
| 9422 | let mut_ref = &mut self.r#is_mesh_child; | ||
| 9423 | { | ||
| 9424 | let val = decoder.decode_bool()?; | ||
| 9425 | let val_ref = &val; | ||
| 9426 | if *val_ref { | ||
| 9427 | *mut_ref = val as _; | ||
| 9428 | } | ||
| 9429 | }; | ||
| 9430 | } | ||
| 9431 | 5u32 => { | ||
| 9432 | let mut_ref = &mut self.r#reason; | ||
| 9433 | { | ||
| 9434 | let val = decoder.decode_varint32()?; | ||
| 9435 | let val_ref = &val; | ||
| 9436 | if *val_ref != 0 { | ||
| 9437 | *mut_ref = val as _; | ||
| 9438 | } | ||
| 9439 | }; | ||
| 9440 | } | ||
| 9441 | _ => { | ||
| 9442 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 9443 | } | ||
| 9444 | } | ||
| 9445 | } | ||
| 9446 | Ok(()) | ||
| 9447 | } | ||
| 9448 | } | ||
| 9449 | impl ::micropb::MessageEncode for CtrlMsg_Event_StationDisconnectFromESPSoftAP { | ||
| 9450 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 9451 | let mut max_size = 0; | ||
| 9452 | if let ::core::option::Option::Some(size) = | ||
| 9453 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 9454 | { | ||
| 9455 | max_size += size; | ||
| 9456 | } else { | ||
| 9457 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9458 | }; | ||
| 9459 | if let ::core::option::Option::Some(size) = | ||
| 9460 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 9461 | { | ||
| 9462 | max_size += size; | ||
| 9463 | } else { | ||
| 9464 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9465 | }; | ||
| 9466 | if let ::core::option::Option::Some(size) = | ||
| 9467 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 9468 | { | ||
| 9469 | max_size += size; | ||
| 9470 | } else { | ||
| 9471 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9472 | }; | ||
| 9473 | if let ::core::option::Option::Some(size) = | ||
| 9474 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 9475 | { | ||
| 9476 | max_size += size; | ||
| 9477 | } else { | ||
| 9478 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9479 | }; | ||
| 9480 | if let ::core::option::Option::Some(size) = | ||
| 9481 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 9482 | { | ||
| 9483 | max_size += size; | ||
| 9484 | } else { | ||
| 9485 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9486 | }; | ||
| 9487 | ::core::option::Option::Some(max_size) | ||
| 9488 | }; | ||
| 9489 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 9490 | &self, | ||
| 9491 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 9492 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 9493 | use ::micropb::{FieldEncode, PbMap}; | ||
| 9494 | { | ||
| 9495 | let val_ref = &self.r#resp; | ||
| 9496 | if *val_ref != 0 { | ||
| 9497 | encoder.encode_varint32(8u32)?; | ||
| 9498 | encoder.encode_int32(*val_ref as _)?; | ||
| 9499 | } | ||
| 9500 | } | ||
| 9501 | { | ||
| 9502 | let val_ref = &self.r#mac; | ||
| 9503 | if !val_ref.is_empty() { | ||
| 9504 | encoder.encode_varint32(18u32)?; | ||
| 9505 | encoder.encode_bytes(val_ref)?; | ||
| 9506 | } | ||
| 9507 | } | ||
| 9508 | { | ||
| 9509 | let val_ref = &self.r#aid; | ||
| 9510 | if *val_ref != 0 { | ||
| 9511 | encoder.encode_varint32(24u32)?; | ||
| 9512 | encoder.encode_varint32(*val_ref as _)?; | ||
| 9513 | } | ||
| 9514 | } | ||
| 9515 | { | ||
| 9516 | let val_ref = &self.r#is_mesh_child; | ||
| 9517 | if *val_ref { | ||
| 9518 | encoder.encode_varint32(32u32)?; | ||
| 9519 | encoder.encode_bool(*val_ref)?; | ||
| 9520 | } | ||
| 9521 | } | ||
| 9522 | { | ||
| 9523 | let val_ref = &self.r#reason; | ||
| 9524 | if *val_ref != 0 { | ||
| 9525 | encoder.encode_varint32(40u32)?; | ||
| 9526 | encoder.encode_varint32(*val_ref as _)?; | ||
| 9527 | } | ||
| 9528 | } | ||
| 9529 | Ok(()) | ||
| 9530 | } | ||
| 9531 | fn compute_size(&self) -> usize { | ||
| 9532 | use ::micropb::{FieldEncode, PbMap}; | ||
| 9533 | let mut size = 0; | ||
| 9534 | { | ||
| 9535 | let val_ref = &self.r#resp; | ||
| 9536 | if *val_ref != 0 { | ||
| 9537 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 9538 | } | ||
| 9539 | } | ||
| 9540 | { | ||
| 9541 | let val_ref = &self.r#mac; | ||
| 9542 | if !val_ref.is_empty() { | ||
| 9543 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 9544 | } | ||
| 9545 | } | ||
| 9546 | { | ||
| 9547 | let val_ref = &self.r#aid; | ||
| 9548 | if *val_ref != 0 { | ||
| 9549 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 9550 | } | ||
| 9551 | } | ||
| 9552 | { | ||
| 9553 | let val_ref = &self.r#is_mesh_child; | ||
| 9554 | if *val_ref { | ||
| 9555 | size += 1usize + 1; | ||
| 9556 | } | ||
| 9557 | } | ||
| 9558 | { | ||
| 9559 | let val_ref = &self.r#reason; | ||
| 9560 | if *val_ref != 0 { | ||
| 9561 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 9562 | } | ||
| 9563 | } | ||
| 9564 | size | ||
| 9565 | } | ||
| 9566 | } | ||
| 9567 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 9568 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 9569 | pub struct CtrlMsg_Event_StationConnectedToESPSoftAP { | ||
| 9570 | pub r#resp: i32, | ||
| 9571 | pub r#mac: ::micropb::heapless::Vec<u8, 32>, | ||
| 9572 | pub r#aid: u32, | ||
| 9573 | pub r#is_mesh_child: bool, | ||
| 9574 | } | ||
| 9575 | impl CtrlMsg_Event_StationConnectedToESPSoftAP { | ||
| 9576 | ///Return a reference to `resp` | ||
| 9577 | #[inline] | ||
| 9578 | pub fn r#resp(&self) -> &i32 { | ||
| 9579 | &self.r#resp | ||
| 9580 | } | ||
| 9581 | ///Return a mutable reference to `resp` | ||
| 9582 | #[inline] | ||
| 9583 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 9584 | &mut self.r#resp | ||
| 9585 | } | ||
| 9586 | ///Set the value of `resp` | ||
| 9587 | #[inline] | ||
| 9588 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 9589 | self.r#resp = value.into(); | ||
| 9590 | self | ||
| 9591 | } | ||
| 9592 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 9593 | #[inline] | ||
| 9594 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 9595 | self.r#resp = value.into(); | ||
| 9596 | self | ||
| 9597 | } | ||
| 9598 | ///Return a reference to `mac` | ||
| 9599 | #[inline] | ||
| 9600 | pub fn r#mac(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 9601 | &self.r#mac | ||
| 9602 | } | ||
| 9603 | ///Return a mutable reference to `mac` | ||
| 9604 | #[inline] | ||
| 9605 | pub fn mut_mac(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 9606 | &mut self.r#mac | ||
| 9607 | } | ||
| 9608 | ///Set the value of `mac` | ||
| 9609 | #[inline] | ||
| 9610 | pub fn set_mac(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 9611 | self.r#mac = value.into(); | ||
| 9612 | self | ||
| 9613 | } | ||
| 9614 | ///Builder method that sets the value of `mac`. Useful for initializing the message. | ||
| 9615 | #[inline] | ||
| 9616 | pub fn init_mac(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 9617 | self.r#mac = value.into(); | ||
| 9618 | self | ||
| 9619 | } | ||
| 9620 | ///Return a reference to `aid` | ||
| 9621 | #[inline] | ||
| 9622 | pub fn r#aid(&self) -> &u32 { | ||
| 9623 | &self.r#aid | ||
| 9624 | } | ||
| 9625 | ///Return a mutable reference to `aid` | ||
| 9626 | #[inline] | ||
| 9627 | pub fn mut_aid(&mut self) -> &mut u32 { | ||
| 9628 | &mut self.r#aid | ||
| 9629 | } | ||
| 9630 | ///Set the value of `aid` | ||
| 9631 | #[inline] | ||
| 9632 | pub fn set_aid(&mut self, value: u32) -> &mut Self { | ||
| 9633 | self.r#aid = value.into(); | ||
| 9634 | self | ||
| 9635 | } | ||
| 9636 | ///Builder method that sets the value of `aid`. Useful for initializing the message. | ||
| 9637 | #[inline] | ||
| 9638 | pub fn init_aid(mut self, value: u32) -> Self { | ||
| 9639 | self.r#aid = value.into(); | ||
| 9640 | self | ||
| 9641 | } | ||
| 9642 | ///Return a reference to `is_mesh_child` | ||
| 9643 | #[inline] | ||
| 9644 | pub fn r#is_mesh_child(&self) -> &bool { | ||
| 9645 | &self.r#is_mesh_child | ||
| 9646 | } | ||
| 9647 | ///Return a mutable reference to `is_mesh_child` | ||
| 9648 | #[inline] | ||
| 9649 | pub fn mut_is_mesh_child(&mut self) -> &mut bool { | ||
| 9650 | &mut self.r#is_mesh_child | ||
| 9651 | } | ||
| 9652 | ///Set the value of `is_mesh_child` | ||
| 9653 | #[inline] | ||
| 9654 | pub fn set_is_mesh_child(&mut self, value: bool) -> &mut Self { | ||
| 9655 | self.r#is_mesh_child = value.into(); | ||
| 9656 | self | ||
| 9657 | } | ||
| 9658 | ///Builder method that sets the value of `is_mesh_child`. Useful for initializing the message. | ||
| 9659 | #[inline] | ||
| 9660 | pub fn init_is_mesh_child(mut self, value: bool) -> Self { | ||
| 9661 | self.r#is_mesh_child = value.into(); | ||
| 9662 | self | ||
| 9663 | } | ||
| 9664 | } | ||
| 9665 | impl ::micropb::MessageDecode for CtrlMsg_Event_StationConnectedToESPSoftAP { | ||
| 9666 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 9667 | &mut self, | ||
| 9668 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 9669 | len: usize, | ||
| 9670 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 9671 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 9672 | let before = decoder.bytes_read(); | ||
| 9673 | while decoder.bytes_read() - before < len { | ||
| 9674 | let tag = decoder.decode_tag()?; | ||
| 9675 | match tag.field_num() { | ||
| 9676 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 9677 | 1u32 => { | ||
| 9678 | let mut_ref = &mut self.r#resp; | ||
| 9679 | { | ||
| 9680 | let val = decoder.decode_int32()?; | ||
| 9681 | let val_ref = &val; | ||
| 9682 | if *val_ref != 0 { | ||
| 9683 | *mut_ref = val as _; | ||
| 9684 | } | ||
| 9685 | }; | ||
| 9686 | } | ||
| 9687 | 2u32 => { | ||
| 9688 | let mut_ref = &mut self.r#mac; | ||
| 9689 | { | ||
| 9690 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 9691 | }; | ||
| 9692 | } | ||
| 9693 | 3u32 => { | ||
| 9694 | let mut_ref = &mut self.r#aid; | ||
| 9695 | { | ||
| 9696 | let val = decoder.decode_varint32()?; | ||
| 9697 | let val_ref = &val; | ||
| 9698 | if *val_ref != 0 { | ||
| 9699 | *mut_ref = val as _; | ||
| 9700 | } | ||
| 9701 | }; | ||
| 9702 | } | ||
| 9703 | 4u32 => { | ||
| 9704 | let mut_ref = &mut self.r#is_mesh_child; | ||
| 9705 | { | ||
| 9706 | let val = decoder.decode_bool()?; | ||
| 9707 | let val_ref = &val; | ||
| 9708 | if *val_ref { | ||
| 9709 | *mut_ref = val as _; | ||
| 9710 | } | ||
| 9711 | }; | ||
| 9712 | } | ||
| 9713 | _ => { | ||
| 9714 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 9715 | } | ||
| 9716 | } | ||
| 9717 | } | ||
| 9718 | Ok(()) | ||
| 9719 | } | ||
| 9720 | } | ||
| 9721 | impl ::micropb::MessageEncode for CtrlMsg_Event_StationConnectedToESPSoftAP { | ||
| 9722 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 9723 | let mut max_size = 0; | ||
| 9724 | if let ::core::option::Option::Some(size) = | ||
| 9725 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 9726 | { | ||
| 9727 | max_size += size; | ||
| 9728 | } else { | ||
| 9729 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9730 | }; | ||
| 9731 | if let ::core::option::Option::Some(size) = | ||
| 9732 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 9733 | { | ||
| 9734 | max_size += size; | ||
| 9735 | } else { | ||
| 9736 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9737 | }; | ||
| 9738 | if let ::core::option::Option::Some(size) = | ||
| 9739 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 9740 | { | ||
| 9741 | max_size += size; | ||
| 9742 | } else { | ||
| 9743 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9744 | }; | ||
| 9745 | if let ::core::option::Option::Some(size) = | ||
| 9746 | ::micropb::const_map!(::core::option::Option::Some(1usize), |size| size + 1usize) | ||
| 9747 | { | ||
| 9748 | max_size += size; | ||
| 9749 | } else { | ||
| 9750 | break 'msg (::core::option::Option::<usize>::None); | ||
| 9751 | }; | ||
| 9752 | ::core::option::Option::Some(max_size) | ||
| 9753 | }; | ||
| 9754 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 9755 | &self, | ||
| 9756 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 9757 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 9758 | use ::micropb::{FieldEncode, PbMap}; | ||
| 9759 | { | ||
| 9760 | let val_ref = &self.r#resp; | ||
| 9761 | if *val_ref != 0 { | ||
| 9762 | encoder.encode_varint32(8u32)?; | ||
| 9763 | encoder.encode_int32(*val_ref as _)?; | ||
| 9764 | } | ||
| 9765 | } | ||
| 9766 | { | ||
| 9767 | let val_ref = &self.r#mac; | ||
| 9768 | if !val_ref.is_empty() { | ||
| 9769 | encoder.encode_varint32(18u32)?; | ||
| 9770 | encoder.encode_bytes(val_ref)?; | ||
| 9771 | } | ||
| 9772 | } | ||
| 9773 | { | ||
| 9774 | let val_ref = &self.r#aid; | ||
| 9775 | if *val_ref != 0 { | ||
| 9776 | encoder.encode_varint32(24u32)?; | ||
| 9777 | encoder.encode_varint32(*val_ref as _)?; | ||
| 9778 | } | ||
| 9779 | } | ||
| 9780 | { | ||
| 9781 | let val_ref = &self.r#is_mesh_child; | ||
| 9782 | if *val_ref { | ||
| 9783 | encoder.encode_varint32(32u32)?; | ||
| 9784 | encoder.encode_bool(*val_ref)?; | ||
| 9785 | } | ||
| 9786 | } | ||
| 9787 | Ok(()) | ||
| 9788 | } | ||
| 9789 | fn compute_size(&self) -> usize { | ||
| 9790 | use ::micropb::{FieldEncode, PbMap}; | ||
| 9791 | let mut size = 0; | ||
| 9792 | { | ||
| 9793 | let val_ref = &self.r#resp; | ||
| 9794 | if *val_ref != 0 { | ||
| 9795 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 9796 | } | ||
| 9797 | } | ||
| 9798 | { | ||
| 9799 | let val_ref = &self.r#mac; | ||
| 9800 | if !val_ref.is_empty() { | ||
| 9801 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 9802 | } | ||
| 9803 | } | ||
| 9804 | { | ||
| 9805 | let val_ref = &self.r#aid; | ||
| 9806 | if *val_ref != 0 { | ||
| 9807 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 9808 | } | ||
| 9809 | } | ||
| 9810 | { | ||
| 9811 | let val_ref = &self.r#is_mesh_child; | ||
| 9812 | if *val_ref { | ||
| 9813 | size += 1usize + 1; | ||
| 9814 | } | ||
| 9815 | } | ||
| 9816 | size | ||
| 9817 | } | ||
| 9818 | } | ||
| 9819 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 9820 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 9821 | pub struct CtrlMsg_Event_SetDhcpDnsStatus { | ||
| 9822 | pub r#iface: i32, | ||
| 9823 | pub r#net_link_up: i32, | ||
| 9824 | pub r#dhcp_up: i32, | ||
| 9825 | pub r#dhcp_ip: ::micropb::heapless::Vec<u8, 32>, | ||
| 9826 | pub r#dhcp_nm: ::micropb::heapless::Vec<u8, 32>, | ||
| 9827 | pub r#dhcp_gw: ::micropb::heapless::Vec<u8, 32>, | ||
| 9828 | pub r#dns_up: i32, | ||
| 9829 | pub r#dns_ip: ::micropb::heapless::Vec<u8, 32>, | ||
| 9830 | pub r#dns_type: i32, | ||
| 9831 | pub r#resp: i32, | ||
| 9832 | } | ||
| 9833 | impl CtrlMsg_Event_SetDhcpDnsStatus { | ||
| 9834 | ///Return a reference to `iface` | ||
| 9835 | #[inline] | ||
| 9836 | pub fn r#iface(&self) -> &i32 { | ||
| 9837 | &self.r#iface | ||
| 9838 | } | ||
| 9839 | ///Return a mutable reference to `iface` | ||
| 9840 | #[inline] | ||
| 9841 | pub fn mut_iface(&mut self) -> &mut i32 { | ||
| 9842 | &mut self.r#iface | ||
| 9843 | } | ||
| 9844 | ///Set the value of `iface` | ||
| 9845 | #[inline] | ||
| 9846 | pub fn set_iface(&mut self, value: i32) -> &mut Self { | ||
| 9847 | self.r#iface = value.into(); | ||
| 9848 | self | ||
| 9849 | } | ||
| 9850 | ///Builder method that sets the value of `iface`. Useful for initializing the message. | ||
| 9851 | #[inline] | ||
| 9852 | pub fn init_iface(mut self, value: i32) -> Self { | ||
| 9853 | self.r#iface = value.into(); | ||
| 9854 | self | ||
| 9855 | } | ||
| 9856 | ///Return a reference to `net_link_up` | ||
| 9857 | #[inline] | ||
| 9858 | pub fn r#net_link_up(&self) -> &i32 { | ||
| 9859 | &self.r#net_link_up | ||
| 9860 | } | ||
| 9861 | ///Return a mutable reference to `net_link_up` | ||
| 9862 | #[inline] | ||
| 9863 | pub fn mut_net_link_up(&mut self) -> &mut i32 { | ||
| 9864 | &mut self.r#net_link_up | ||
| 9865 | } | ||
| 9866 | ///Set the value of `net_link_up` | ||
| 9867 | #[inline] | ||
| 9868 | pub fn set_net_link_up(&mut self, value: i32) -> &mut Self { | ||
| 9869 | self.r#net_link_up = value.into(); | ||
| 9870 | self | ||
| 9871 | } | ||
| 9872 | ///Builder method that sets the value of `net_link_up`. Useful for initializing the message. | ||
| 9873 | #[inline] | ||
| 9874 | pub fn init_net_link_up(mut self, value: i32) -> Self { | ||
| 9875 | self.r#net_link_up = value.into(); | ||
| 9876 | self | ||
| 9877 | } | ||
| 9878 | ///Return a reference to `dhcp_up` | ||
| 9879 | #[inline] | ||
| 9880 | pub fn r#dhcp_up(&self) -> &i32 { | ||
| 9881 | &self.r#dhcp_up | ||
| 9882 | } | ||
| 9883 | ///Return a mutable reference to `dhcp_up` | ||
| 9884 | #[inline] | ||
| 9885 | pub fn mut_dhcp_up(&mut self) -> &mut i32 { | ||
| 9886 | &mut self.r#dhcp_up | ||
| 9887 | } | ||
| 9888 | ///Set the value of `dhcp_up` | ||
| 9889 | #[inline] | ||
| 9890 | pub fn set_dhcp_up(&mut self, value: i32) -> &mut Self { | ||
| 9891 | self.r#dhcp_up = value.into(); | ||
| 9892 | self | ||
| 9893 | } | ||
| 9894 | ///Builder method that sets the value of `dhcp_up`. Useful for initializing the message. | ||
| 9895 | #[inline] | ||
| 9896 | pub fn init_dhcp_up(mut self, value: i32) -> Self { | ||
| 9897 | self.r#dhcp_up = value.into(); | ||
| 9898 | self | ||
| 9899 | } | ||
| 9900 | ///Return a reference to `dhcp_ip` | ||
| 9901 | #[inline] | ||
| 9902 | pub fn r#dhcp_ip(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 9903 | &self.r#dhcp_ip | ||
| 9904 | } | ||
| 9905 | ///Return a mutable reference to `dhcp_ip` | ||
| 9906 | #[inline] | ||
| 9907 | pub fn mut_dhcp_ip(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 9908 | &mut self.r#dhcp_ip | ||
| 9909 | } | ||
| 9910 | ///Set the value of `dhcp_ip` | ||
| 9911 | #[inline] | ||
| 9912 | pub fn set_dhcp_ip(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 9913 | self.r#dhcp_ip = value.into(); | ||
| 9914 | self | ||
| 9915 | } | ||
| 9916 | ///Builder method that sets the value of `dhcp_ip`. Useful for initializing the message. | ||
| 9917 | #[inline] | ||
| 9918 | pub fn init_dhcp_ip(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 9919 | self.r#dhcp_ip = value.into(); | ||
| 9920 | self | ||
| 9921 | } | ||
| 9922 | ///Return a reference to `dhcp_nm` | ||
| 9923 | #[inline] | ||
| 9924 | pub fn r#dhcp_nm(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 9925 | &self.r#dhcp_nm | ||
| 9926 | } | ||
| 9927 | ///Return a mutable reference to `dhcp_nm` | ||
| 9928 | #[inline] | ||
| 9929 | pub fn mut_dhcp_nm(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 9930 | &mut self.r#dhcp_nm | ||
| 9931 | } | ||
| 9932 | ///Set the value of `dhcp_nm` | ||
| 9933 | #[inline] | ||
| 9934 | pub fn set_dhcp_nm(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 9935 | self.r#dhcp_nm = value.into(); | ||
| 9936 | self | ||
| 9937 | } | ||
| 9938 | ///Builder method that sets the value of `dhcp_nm`. Useful for initializing the message. | ||
| 9939 | #[inline] | ||
| 9940 | pub fn init_dhcp_nm(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 9941 | self.r#dhcp_nm = value.into(); | ||
| 9942 | self | ||
| 9943 | } | ||
| 9944 | ///Return a reference to `dhcp_gw` | ||
| 9945 | #[inline] | ||
| 9946 | pub fn r#dhcp_gw(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 9947 | &self.r#dhcp_gw | ||
| 9948 | } | ||
| 9949 | ///Return a mutable reference to `dhcp_gw` | ||
| 9950 | #[inline] | ||
| 9951 | pub fn mut_dhcp_gw(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 9952 | &mut self.r#dhcp_gw | ||
| 9953 | } | ||
| 9954 | ///Set the value of `dhcp_gw` | ||
| 9955 | #[inline] | ||
| 9956 | pub fn set_dhcp_gw(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 9957 | self.r#dhcp_gw = value.into(); | ||
| 9958 | self | ||
| 9959 | } | ||
| 9960 | ///Builder method that sets the value of `dhcp_gw`. Useful for initializing the message. | ||
| 9961 | #[inline] | ||
| 9962 | pub fn init_dhcp_gw(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 9963 | self.r#dhcp_gw = value.into(); | ||
| 9964 | self | ||
| 9965 | } | ||
| 9966 | ///Return a reference to `dns_up` | ||
| 9967 | #[inline] | ||
| 9968 | pub fn r#dns_up(&self) -> &i32 { | ||
| 9969 | &self.r#dns_up | ||
| 9970 | } | ||
| 9971 | ///Return a mutable reference to `dns_up` | ||
| 9972 | #[inline] | ||
| 9973 | pub fn mut_dns_up(&mut self) -> &mut i32 { | ||
| 9974 | &mut self.r#dns_up | ||
| 9975 | } | ||
| 9976 | ///Set the value of `dns_up` | ||
| 9977 | #[inline] | ||
| 9978 | pub fn set_dns_up(&mut self, value: i32) -> &mut Self { | ||
| 9979 | self.r#dns_up = value.into(); | ||
| 9980 | self | ||
| 9981 | } | ||
| 9982 | ///Builder method that sets the value of `dns_up`. Useful for initializing the message. | ||
| 9983 | #[inline] | ||
| 9984 | pub fn init_dns_up(mut self, value: i32) -> Self { | ||
| 9985 | self.r#dns_up = value.into(); | ||
| 9986 | self | ||
| 9987 | } | ||
| 9988 | ///Return a reference to `dns_ip` | ||
| 9989 | #[inline] | ||
| 9990 | pub fn r#dns_ip(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 9991 | &self.r#dns_ip | ||
| 9992 | } | ||
| 9993 | ///Return a mutable reference to `dns_ip` | ||
| 9994 | #[inline] | ||
| 9995 | pub fn mut_dns_ip(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 9996 | &mut self.r#dns_ip | ||
| 9997 | } | ||
| 9998 | ///Set the value of `dns_ip` | ||
| 9999 | #[inline] | ||
| 10000 | pub fn set_dns_ip(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 10001 | self.r#dns_ip = value.into(); | ||
| 10002 | self | ||
| 10003 | } | ||
| 10004 | ///Builder method that sets the value of `dns_ip`. Useful for initializing the message. | ||
| 10005 | #[inline] | ||
| 10006 | pub fn init_dns_ip(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 10007 | self.r#dns_ip = value.into(); | ||
| 10008 | self | ||
| 10009 | } | ||
| 10010 | ///Return a reference to `dns_type` | ||
| 10011 | #[inline] | ||
| 10012 | pub fn r#dns_type(&self) -> &i32 { | ||
| 10013 | &self.r#dns_type | ||
| 10014 | } | ||
| 10015 | ///Return a mutable reference to `dns_type` | ||
| 10016 | #[inline] | ||
| 10017 | pub fn mut_dns_type(&mut self) -> &mut i32 { | ||
| 10018 | &mut self.r#dns_type | ||
| 10019 | } | ||
| 10020 | ///Set the value of `dns_type` | ||
| 10021 | #[inline] | ||
| 10022 | pub fn set_dns_type(&mut self, value: i32) -> &mut Self { | ||
| 10023 | self.r#dns_type = value.into(); | ||
| 10024 | self | ||
| 10025 | } | ||
| 10026 | ///Builder method that sets the value of `dns_type`. Useful for initializing the message. | ||
| 10027 | #[inline] | ||
| 10028 | pub fn init_dns_type(mut self, value: i32) -> Self { | ||
| 10029 | self.r#dns_type = value.into(); | ||
| 10030 | self | ||
| 10031 | } | ||
| 10032 | ///Return a reference to `resp` | ||
| 10033 | #[inline] | ||
| 10034 | pub fn r#resp(&self) -> &i32 { | ||
| 10035 | &self.r#resp | ||
| 10036 | } | ||
| 10037 | ///Return a mutable reference to `resp` | ||
| 10038 | #[inline] | ||
| 10039 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 10040 | &mut self.r#resp | ||
| 10041 | } | ||
| 10042 | ///Set the value of `resp` | ||
| 10043 | #[inline] | ||
| 10044 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 10045 | self.r#resp = value.into(); | ||
| 10046 | self | ||
| 10047 | } | ||
| 10048 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 10049 | #[inline] | ||
| 10050 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 10051 | self.r#resp = value.into(); | ||
| 10052 | self | ||
| 10053 | } | ||
| 10054 | } | ||
| 10055 | impl ::micropb::MessageDecode for CtrlMsg_Event_SetDhcpDnsStatus { | ||
| 10056 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 10057 | &mut self, | ||
| 10058 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 10059 | len: usize, | ||
| 10060 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 10061 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 10062 | let before = decoder.bytes_read(); | ||
| 10063 | while decoder.bytes_read() - before < len { | ||
| 10064 | let tag = decoder.decode_tag()?; | ||
| 10065 | match tag.field_num() { | ||
| 10066 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 10067 | 1u32 => { | ||
| 10068 | let mut_ref = &mut self.r#iface; | ||
| 10069 | { | ||
| 10070 | let val = decoder.decode_int32()?; | ||
| 10071 | let val_ref = &val; | ||
| 10072 | if *val_ref != 0 { | ||
| 10073 | *mut_ref = val as _; | ||
| 10074 | } | ||
| 10075 | }; | ||
| 10076 | } | ||
| 10077 | 2u32 => { | ||
| 10078 | let mut_ref = &mut self.r#net_link_up; | ||
| 10079 | { | ||
| 10080 | let val = decoder.decode_int32()?; | ||
| 10081 | let val_ref = &val; | ||
| 10082 | if *val_ref != 0 { | ||
| 10083 | *mut_ref = val as _; | ||
| 10084 | } | ||
| 10085 | }; | ||
| 10086 | } | ||
| 10087 | 3u32 => { | ||
| 10088 | let mut_ref = &mut self.r#dhcp_up; | ||
| 10089 | { | ||
| 10090 | let val = decoder.decode_int32()?; | ||
| 10091 | let val_ref = &val; | ||
| 10092 | if *val_ref != 0 { | ||
| 10093 | *mut_ref = val as _; | ||
| 10094 | } | ||
| 10095 | }; | ||
| 10096 | } | ||
| 10097 | 4u32 => { | ||
| 10098 | let mut_ref = &mut self.r#dhcp_ip; | ||
| 10099 | { | ||
| 10100 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10101 | }; | ||
| 10102 | } | ||
| 10103 | 5u32 => { | ||
| 10104 | let mut_ref = &mut self.r#dhcp_nm; | ||
| 10105 | { | ||
| 10106 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10107 | }; | ||
| 10108 | } | ||
| 10109 | 6u32 => { | ||
| 10110 | let mut_ref = &mut self.r#dhcp_gw; | ||
| 10111 | { | ||
| 10112 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10113 | }; | ||
| 10114 | } | ||
| 10115 | 7u32 => { | ||
| 10116 | let mut_ref = &mut self.r#dns_up; | ||
| 10117 | { | ||
| 10118 | let val = decoder.decode_int32()?; | ||
| 10119 | let val_ref = &val; | ||
| 10120 | if *val_ref != 0 { | ||
| 10121 | *mut_ref = val as _; | ||
| 10122 | } | ||
| 10123 | }; | ||
| 10124 | } | ||
| 10125 | 8u32 => { | ||
| 10126 | let mut_ref = &mut self.r#dns_ip; | ||
| 10127 | { | ||
| 10128 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10129 | }; | ||
| 10130 | } | ||
| 10131 | 9u32 => { | ||
| 10132 | let mut_ref = &mut self.r#dns_type; | ||
| 10133 | { | ||
| 10134 | let val = decoder.decode_int32()?; | ||
| 10135 | let val_ref = &val; | ||
| 10136 | if *val_ref != 0 { | ||
| 10137 | *mut_ref = val as _; | ||
| 10138 | } | ||
| 10139 | }; | ||
| 10140 | } | ||
| 10141 | 10u32 => { | ||
| 10142 | let mut_ref = &mut self.r#resp; | ||
| 10143 | { | ||
| 10144 | let val = decoder.decode_int32()?; | ||
| 10145 | let val_ref = &val; | ||
| 10146 | if *val_ref != 0 { | ||
| 10147 | *mut_ref = val as _; | ||
| 10148 | } | ||
| 10149 | }; | ||
| 10150 | } | ||
| 10151 | _ => { | ||
| 10152 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 10153 | } | ||
| 10154 | } | ||
| 10155 | } | ||
| 10156 | Ok(()) | ||
| 10157 | } | ||
| 10158 | } | ||
| 10159 | impl ::micropb::MessageEncode for CtrlMsg_Event_SetDhcpDnsStatus { | ||
| 10160 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 10161 | let mut max_size = 0; | ||
| 10162 | if let ::core::option::Option::Some(size) = | ||
| 10163 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10164 | { | ||
| 10165 | max_size += size; | ||
| 10166 | } else { | ||
| 10167 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10168 | }; | ||
| 10169 | if let ::core::option::Option::Some(size) = | ||
| 10170 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10171 | { | ||
| 10172 | max_size += size; | ||
| 10173 | } else { | ||
| 10174 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10175 | }; | ||
| 10176 | if let ::core::option::Option::Some(size) = | ||
| 10177 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10178 | { | ||
| 10179 | max_size += size; | ||
| 10180 | } else { | ||
| 10181 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10182 | }; | ||
| 10183 | if let ::core::option::Option::Some(size) = | ||
| 10184 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10185 | { | ||
| 10186 | max_size += size; | ||
| 10187 | } else { | ||
| 10188 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10189 | }; | ||
| 10190 | if let ::core::option::Option::Some(size) = | ||
| 10191 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10192 | { | ||
| 10193 | max_size += size; | ||
| 10194 | } else { | ||
| 10195 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10196 | }; | ||
| 10197 | if let ::core::option::Option::Some(size) = | ||
| 10198 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10199 | { | ||
| 10200 | max_size += size; | ||
| 10201 | } else { | ||
| 10202 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10203 | }; | ||
| 10204 | if let ::core::option::Option::Some(size) = | ||
| 10205 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10206 | { | ||
| 10207 | max_size += size; | ||
| 10208 | } else { | ||
| 10209 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10210 | }; | ||
| 10211 | if let ::core::option::Option::Some(size) = | ||
| 10212 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10213 | { | ||
| 10214 | max_size += size; | ||
| 10215 | } else { | ||
| 10216 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10217 | }; | ||
| 10218 | if let ::core::option::Option::Some(size) = | ||
| 10219 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10220 | { | ||
| 10221 | max_size += size; | ||
| 10222 | } else { | ||
| 10223 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10224 | }; | ||
| 10225 | if let ::core::option::Option::Some(size) = | ||
| 10226 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10227 | { | ||
| 10228 | max_size += size; | ||
| 10229 | } else { | ||
| 10230 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10231 | }; | ||
| 10232 | ::core::option::Option::Some(max_size) | ||
| 10233 | }; | ||
| 10234 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 10235 | &self, | ||
| 10236 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 10237 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 10238 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10239 | { | ||
| 10240 | let val_ref = &self.r#iface; | ||
| 10241 | if *val_ref != 0 { | ||
| 10242 | encoder.encode_varint32(8u32)?; | ||
| 10243 | encoder.encode_int32(*val_ref as _)?; | ||
| 10244 | } | ||
| 10245 | } | ||
| 10246 | { | ||
| 10247 | let val_ref = &self.r#net_link_up; | ||
| 10248 | if *val_ref != 0 { | ||
| 10249 | encoder.encode_varint32(16u32)?; | ||
| 10250 | encoder.encode_int32(*val_ref as _)?; | ||
| 10251 | } | ||
| 10252 | } | ||
| 10253 | { | ||
| 10254 | let val_ref = &self.r#dhcp_up; | ||
| 10255 | if *val_ref != 0 { | ||
| 10256 | encoder.encode_varint32(24u32)?; | ||
| 10257 | encoder.encode_int32(*val_ref as _)?; | ||
| 10258 | } | ||
| 10259 | } | ||
| 10260 | { | ||
| 10261 | let val_ref = &self.r#dhcp_ip; | ||
| 10262 | if !val_ref.is_empty() { | ||
| 10263 | encoder.encode_varint32(34u32)?; | ||
| 10264 | encoder.encode_bytes(val_ref)?; | ||
| 10265 | } | ||
| 10266 | } | ||
| 10267 | { | ||
| 10268 | let val_ref = &self.r#dhcp_nm; | ||
| 10269 | if !val_ref.is_empty() { | ||
| 10270 | encoder.encode_varint32(42u32)?; | ||
| 10271 | encoder.encode_bytes(val_ref)?; | ||
| 10272 | } | ||
| 10273 | } | ||
| 10274 | { | ||
| 10275 | let val_ref = &self.r#dhcp_gw; | ||
| 10276 | if !val_ref.is_empty() { | ||
| 10277 | encoder.encode_varint32(50u32)?; | ||
| 10278 | encoder.encode_bytes(val_ref)?; | ||
| 10279 | } | ||
| 10280 | } | ||
| 10281 | { | ||
| 10282 | let val_ref = &self.r#dns_up; | ||
| 10283 | if *val_ref != 0 { | ||
| 10284 | encoder.encode_varint32(56u32)?; | ||
| 10285 | encoder.encode_int32(*val_ref as _)?; | ||
| 10286 | } | ||
| 10287 | } | ||
| 10288 | { | ||
| 10289 | let val_ref = &self.r#dns_ip; | ||
| 10290 | if !val_ref.is_empty() { | ||
| 10291 | encoder.encode_varint32(66u32)?; | ||
| 10292 | encoder.encode_bytes(val_ref)?; | ||
| 10293 | } | ||
| 10294 | } | ||
| 10295 | { | ||
| 10296 | let val_ref = &self.r#dns_type; | ||
| 10297 | if *val_ref != 0 { | ||
| 10298 | encoder.encode_varint32(72u32)?; | ||
| 10299 | encoder.encode_int32(*val_ref as _)?; | ||
| 10300 | } | ||
| 10301 | } | ||
| 10302 | { | ||
| 10303 | let val_ref = &self.r#resp; | ||
| 10304 | if *val_ref != 0 { | ||
| 10305 | encoder.encode_varint32(80u32)?; | ||
| 10306 | encoder.encode_int32(*val_ref as _)?; | ||
| 10307 | } | ||
| 10308 | } | ||
| 10309 | Ok(()) | ||
| 10310 | } | ||
| 10311 | fn compute_size(&self) -> usize { | ||
| 10312 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10313 | let mut size = 0; | ||
| 10314 | { | ||
| 10315 | let val_ref = &self.r#iface; | ||
| 10316 | if *val_ref != 0 { | ||
| 10317 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10318 | } | ||
| 10319 | } | ||
| 10320 | { | ||
| 10321 | let val_ref = &self.r#net_link_up; | ||
| 10322 | if *val_ref != 0 { | ||
| 10323 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10324 | } | ||
| 10325 | } | ||
| 10326 | { | ||
| 10327 | let val_ref = &self.r#dhcp_up; | ||
| 10328 | if *val_ref != 0 { | ||
| 10329 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10330 | } | ||
| 10331 | } | ||
| 10332 | { | ||
| 10333 | let val_ref = &self.r#dhcp_ip; | ||
| 10334 | if !val_ref.is_empty() { | ||
| 10335 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10336 | } | ||
| 10337 | } | ||
| 10338 | { | ||
| 10339 | let val_ref = &self.r#dhcp_nm; | ||
| 10340 | if !val_ref.is_empty() { | ||
| 10341 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10342 | } | ||
| 10343 | } | ||
| 10344 | { | ||
| 10345 | let val_ref = &self.r#dhcp_gw; | ||
| 10346 | if !val_ref.is_empty() { | ||
| 10347 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10348 | } | ||
| 10349 | } | ||
| 10350 | { | ||
| 10351 | let val_ref = &self.r#dns_up; | ||
| 10352 | if *val_ref != 0 { | ||
| 10353 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10354 | } | ||
| 10355 | } | ||
| 10356 | { | ||
| 10357 | let val_ref = &self.r#dns_ip; | ||
| 10358 | if !val_ref.is_empty() { | ||
| 10359 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10360 | } | ||
| 10361 | } | ||
| 10362 | { | ||
| 10363 | let val_ref = &self.r#dns_type; | ||
| 10364 | if *val_ref != 0 { | ||
| 10365 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10366 | } | ||
| 10367 | } | ||
| 10368 | { | ||
| 10369 | let val_ref = &self.r#resp; | ||
| 10370 | if *val_ref != 0 { | ||
| 10371 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10372 | } | ||
| 10373 | } | ||
| 10374 | size | ||
| 10375 | } | ||
| 10376 | } | ||
| 10377 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 10378 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 10379 | pub struct CtrlMsg_Req_CustomRpcUnserialisedMsg { | ||
| 10380 | pub r#custom_msg_id: u32, | ||
| 10381 | pub r#data: ::micropb::heapless::Vec<u8, 32>, | ||
| 10382 | } | ||
| 10383 | impl CtrlMsg_Req_CustomRpcUnserialisedMsg { | ||
| 10384 | ///Return a reference to `custom_msg_id` | ||
| 10385 | #[inline] | ||
| 10386 | pub fn r#custom_msg_id(&self) -> &u32 { | ||
| 10387 | &self.r#custom_msg_id | ||
| 10388 | } | ||
| 10389 | ///Return a mutable reference to `custom_msg_id` | ||
| 10390 | #[inline] | ||
| 10391 | pub fn mut_custom_msg_id(&mut self) -> &mut u32 { | ||
| 10392 | &mut self.r#custom_msg_id | ||
| 10393 | } | ||
| 10394 | ///Set the value of `custom_msg_id` | ||
| 10395 | #[inline] | ||
| 10396 | pub fn set_custom_msg_id(&mut self, value: u32) -> &mut Self { | ||
| 10397 | self.r#custom_msg_id = value.into(); | ||
| 10398 | self | ||
| 10399 | } | ||
| 10400 | ///Builder method that sets the value of `custom_msg_id`. Useful for initializing the message. | ||
| 10401 | #[inline] | ||
| 10402 | pub fn init_custom_msg_id(mut self, value: u32) -> Self { | ||
| 10403 | self.r#custom_msg_id = value.into(); | ||
| 10404 | self | ||
| 10405 | } | ||
| 10406 | ///Return a reference to `data` | ||
| 10407 | #[inline] | ||
| 10408 | pub fn r#data(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 10409 | &self.r#data | ||
| 10410 | } | ||
| 10411 | ///Return a mutable reference to `data` | ||
| 10412 | #[inline] | ||
| 10413 | pub fn mut_data(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 10414 | &mut self.r#data | ||
| 10415 | } | ||
| 10416 | ///Set the value of `data` | ||
| 10417 | #[inline] | ||
| 10418 | pub fn set_data(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 10419 | self.r#data = value.into(); | ||
| 10420 | self | ||
| 10421 | } | ||
| 10422 | ///Builder method that sets the value of `data`. Useful for initializing the message. | ||
| 10423 | #[inline] | ||
| 10424 | pub fn init_data(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 10425 | self.r#data = value.into(); | ||
| 10426 | self | ||
| 10427 | } | ||
| 10428 | } | ||
| 10429 | impl ::micropb::MessageDecode for CtrlMsg_Req_CustomRpcUnserialisedMsg { | ||
| 10430 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 10431 | &mut self, | ||
| 10432 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 10433 | len: usize, | ||
| 10434 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 10435 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 10436 | let before = decoder.bytes_read(); | ||
| 10437 | while decoder.bytes_read() - before < len { | ||
| 10438 | let tag = decoder.decode_tag()?; | ||
| 10439 | match tag.field_num() { | ||
| 10440 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 10441 | 1u32 => { | ||
| 10442 | let mut_ref = &mut self.r#custom_msg_id; | ||
| 10443 | { | ||
| 10444 | let val = decoder.decode_varint32()?; | ||
| 10445 | let val_ref = &val; | ||
| 10446 | if *val_ref != 0 { | ||
| 10447 | *mut_ref = val as _; | ||
| 10448 | } | ||
| 10449 | }; | ||
| 10450 | } | ||
| 10451 | 2u32 => { | ||
| 10452 | let mut_ref = &mut self.r#data; | ||
| 10453 | { | ||
| 10454 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10455 | }; | ||
| 10456 | } | ||
| 10457 | _ => { | ||
| 10458 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 10459 | } | ||
| 10460 | } | ||
| 10461 | } | ||
| 10462 | Ok(()) | ||
| 10463 | } | ||
| 10464 | } | ||
| 10465 | impl ::micropb::MessageEncode for CtrlMsg_Req_CustomRpcUnserialisedMsg { | ||
| 10466 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 10467 | let mut max_size = 0; | ||
| 10468 | if let ::core::option::Option::Some(size) = | ||
| 10469 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 10470 | { | ||
| 10471 | max_size += size; | ||
| 10472 | } else { | ||
| 10473 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10474 | }; | ||
| 10475 | if let ::core::option::Option::Some(size) = | ||
| 10476 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10477 | { | ||
| 10478 | max_size += size; | ||
| 10479 | } else { | ||
| 10480 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10481 | }; | ||
| 10482 | ::core::option::Option::Some(max_size) | ||
| 10483 | }; | ||
| 10484 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 10485 | &self, | ||
| 10486 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 10487 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 10488 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10489 | { | ||
| 10490 | let val_ref = &self.r#custom_msg_id; | ||
| 10491 | if *val_ref != 0 { | ||
| 10492 | encoder.encode_varint32(8u32)?; | ||
| 10493 | encoder.encode_varint32(*val_ref as _)?; | ||
| 10494 | } | ||
| 10495 | } | ||
| 10496 | { | ||
| 10497 | let val_ref = &self.r#data; | ||
| 10498 | if !val_ref.is_empty() { | ||
| 10499 | encoder.encode_varint32(18u32)?; | ||
| 10500 | encoder.encode_bytes(val_ref)?; | ||
| 10501 | } | ||
| 10502 | } | ||
| 10503 | Ok(()) | ||
| 10504 | } | ||
| 10505 | fn compute_size(&self) -> usize { | ||
| 10506 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10507 | let mut size = 0; | ||
| 10508 | { | ||
| 10509 | let val_ref = &self.r#custom_msg_id; | ||
| 10510 | if *val_ref != 0 { | ||
| 10511 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 10512 | } | ||
| 10513 | } | ||
| 10514 | { | ||
| 10515 | let val_ref = &self.r#data; | ||
| 10516 | if !val_ref.is_empty() { | ||
| 10517 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10518 | } | ||
| 10519 | } | ||
| 10520 | size | ||
| 10521 | } | ||
| 10522 | } | ||
| 10523 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 10524 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 10525 | pub struct CtrlMsg_Resp_CustomRpcUnserialisedMsg { | ||
| 10526 | pub r#resp: i32, | ||
| 10527 | pub r#custom_msg_id: u32, | ||
| 10528 | pub r#data: ::micropb::heapless::Vec<u8, 32>, | ||
| 10529 | } | ||
| 10530 | impl CtrlMsg_Resp_CustomRpcUnserialisedMsg { | ||
| 10531 | ///Return a reference to `resp` | ||
| 10532 | #[inline] | ||
| 10533 | pub fn r#resp(&self) -> &i32 { | ||
| 10534 | &self.r#resp | ||
| 10535 | } | ||
| 10536 | ///Return a mutable reference to `resp` | ||
| 10537 | #[inline] | ||
| 10538 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 10539 | &mut self.r#resp | ||
| 10540 | } | ||
| 10541 | ///Set the value of `resp` | ||
| 10542 | #[inline] | ||
| 10543 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 10544 | self.r#resp = value.into(); | ||
| 10545 | self | ||
| 10546 | } | ||
| 10547 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 10548 | #[inline] | ||
| 10549 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 10550 | self.r#resp = value.into(); | ||
| 10551 | self | ||
| 10552 | } | ||
| 10553 | ///Return a reference to `custom_msg_id` | ||
| 10554 | #[inline] | ||
| 10555 | pub fn r#custom_msg_id(&self) -> &u32 { | ||
| 10556 | &self.r#custom_msg_id | ||
| 10557 | } | ||
| 10558 | ///Return a mutable reference to `custom_msg_id` | ||
| 10559 | #[inline] | ||
| 10560 | pub fn mut_custom_msg_id(&mut self) -> &mut u32 { | ||
| 10561 | &mut self.r#custom_msg_id | ||
| 10562 | } | ||
| 10563 | ///Set the value of `custom_msg_id` | ||
| 10564 | #[inline] | ||
| 10565 | pub fn set_custom_msg_id(&mut self, value: u32) -> &mut Self { | ||
| 10566 | self.r#custom_msg_id = value.into(); | ||
| 10567 | self | ||
| 10568 | } | ||
| 10569 | ///Builder method that sets the value of `custom_msg_id`. Useful for initializing the message. | ||
| 10570 | #[inline] | ||
| 10571 | pub fn init_custom_msg_id(mut self, value: u32) -> Self { | ||
| 10572 | self.r#custom_msg_id = value.into(); | ||
| 10573 | self | ||
| 10574 | } | ||
| 10575 | ///Return a reference to `data` | ||
| 10576 | #[inline] | ||
| 10577 | pub fn r#data(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 10578 | &self.r#data | ||
| 10579 | } | ||
| 10580 | ///Return a mutable reference to `data` | ||
| 10581 | #[inline] | ||
| 10582 | pub fn mut_data(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 10583 | &mut self.r#data | ||
| 10584 | } | ||
| 10585 | ///Set the value of `data` | ||
| 10586 | #[inline] | ||
| 10587 | pub fn set_data(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 10588 | self.r#data = value.into(); | ||
| 10589 | self | ||
| 10590 | } | ||
| 10591 | ///Builder method that sets the value of `data`. Useful for initializing the message. | ||
| 10592 | #[inline] | ||
| 10593 | pub fn init_data(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 10594 | self.r#data = value.into(); | ||
| 10595 | self | ||
| 10596 | } | ||
| 10597 | } | ||
| 10598 | impl ::micropb::MessageDecode for CtrlMsg_Resp_CustomRpcUnserialisedMsg { | ||
| 10599 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 10600 | &mut self, | ||
| 10601 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 10602 | len: usize, | ||
| 10603 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 10604 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 10605 | let before = decoder.bytes_read(); | ||
| 10606 | while decoder.bytes_read() - before < len { | ||
| 10607 | let tag = decoder.decode_tag()?; | ||
| 10608 | match tag.field_num() { | ||
| 10609 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 10610 | 1u32 => { | ||
| 10611 | let mut_ref = &mut self.r#resp; | ||
| 10612 | { | ||
| 10613 | let val = decoder.decode_int32()?; | ||
| 10614 | let val_ref = &val; | ||
| 10615 | if *val_ref != 0 { | ||
| 10616 | *mut_ref = val as _; | ||
| 10617 | } | ||
| 10618 | }; | ||
| 10619 | } | ||
| 10620 | 2u32 => { | ||
| 10621 | let mut_ref = &mut self.r#custom_msg_id; | ||
| 10622 | { | ||
| 10623 | let val = decoder.decode_varint32()?; | ||
| 10624 | let val_ref = &val; | ||
| 10625 | if *val_ref != 0 { | ||
| 10626 | *mut_ref = val as _; | ||
| 10627 | } | ||
| 10628 | }; | ||
| 10629 | } | ||
| 10630 | 3u32 => { | ||
| 10631 | let mut_ref = &mut self.r#data; | ||
| 10632 | { | ||
| 10633 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10634 | }; | ||
| 10635 | } | ||
| 10636 | _ => { | ||
| 10637 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 10638 | } | ||
| 10639 | } | ||
| 10640 | } | ||
| 10641 | Ok(()) | ||
| 10642 | } | ||
| 10643 | } | ||
| 10644 | impl ::micropb::MessageEncode for CtrlMsg_Resp_CustomRpcUnserialisedMsg { | ||
| 10645 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 10646 | let mut max_size = 0; | ||
| 10647 | if let ::core::option::Option::Some(size) = | ||
| 10648 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10649 | { | ||
| 10650 | max_size += size; | ||
| 10651 | } else { | ||
| 10652 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10653 | }; | ||
| 10654 | if let ::core::option::Option::Some(size) = | ||
| 10655 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 10656 | { | ||
| 10657 | max_size += size; | ||
| 10658 | } else { | ||
| 10659 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10660 | }; | ||
| 10661 | if let ::core::option::Option::Some(size) = | ||
| 10662 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10663 | { | ||
| 10664 | max_size += size; | ||
| 10665 | } else { | ||
| 10666 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10667 | }; | ||
| 10668 | ::core::option::Option::Some(max_size) | ||
| 10669 | }; | ||
| 10670 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 10671 | &self, | ||
| 10672 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 10673 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 10674 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10675 | { | ||
| 10676 | let val_ref = &self.r#resp; | ||
| 10677 | if *val_ref != 0 { | ||
| 10678 | encoder.encode_varint32(8u32)?; | ||
| 10679 | encoder.encode_int32(*val_ref as _)?; | ||
| 10680 | } | ||
| 10681 | } | ||
| 10682 | { | ||
| 10683 | let val_ref = &self.r#custom_msg_id; | ||
| 10684 | if *val_ref != 0 { | ||
| 10685 | encoder.encode_varint32(16u32)?; | ||
| 10686 | encoder.encode_varint32(*val_ref as _)?; | ||
| 10687 | } | ||
| 10688 | } | ||
| 10689 | { | ||
| 10690 | let val_ref = &self.r#data; | ||
| 10691 | if !val_ref.is_empty() { | ||
| 10692 | encoder.encode_varint32(26u32)?; | ||
| 10693 | encoder.encode_bytes(val_ref)?; | ||
| 10694 | } | ||
| 10695 | } | ||
| 10696 | Ok(()) | ||
| 10697 | } | ||
| 10698 | fn compute_size(&self) -> usize { | ||
| 10699 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10700 | let mut size = 0; | ||
| 10701 | { | ||
| 10702 | let val_ref = &self.r#resp; | ||
| 10703 | if *val_ref != 0 { | ||
| 10704 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10705 | } | ||
| 10706 | } | ||
| 10707 | { | ||
| 10708 | let val_ref = &self.r#custom_msg_id; | ||
| 10709 | if *val_ref != 0 { | ||
| 10710 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 10711 | } | ||
| 10712 | } | ||
| 10713 | { | ||
| 10714 | let val_ref = &self.r#data; | ||
| 10715 | if !val_ref.is_empty() { | ||
| 10716 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10717 | } | ||
| 10718 | } | ||
| 10719 | size | ||
| 10720 | } | ||
| 10721 | } | ||
| 10722 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 10723 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 10724 | pub struct CtrlMsg_Event_CustomRpcUnserialisedMsg { | ||
| 10725 | pub r#resp: i32, | ||
| 10726 | pub r#custom_evt_id: u32, | ||
| 10727 | pub r#data: ::micropb::heapless::Vec<u8, 32>, | ||
| 10728 | } | ||
| 10729 | impl CtrlMsg_Event_CustomRpcUnserialisedMsg { | ||
| 10730 | ///Return a reference to `resp` | ||
| 10731 | #[inline] | ||
| 10732 | pub fn r#resp(&self) -> &i32 { | ||
| 10733 | &self.r#resp | ||
| 10734 | } | ||
| 10735 | ///Return a mutable reference to `resp` | ||
| 10736 | #[inline] | ||
| 10737 | pub fn mut_resp(&mut self) -> &mut i32 { | ||
| 10738 | &mut self.r#resp | ||
| 10739 | } | ||
| 10740 | ///Set the value of `resp` | ||
| 10741 | #[inline] | ||
| 10742 | pub fn set_resp(&mut self, value: i32) -> &mut Self { | ||
| 10743 | self.r#resp = value.into(); | ||
| 10744 | self | ||
| 10745 | } | ||
| 10746 | ///Builder method that sets the value of `resp`. Useful for initializing the message. | ||
| 10747 | #[inline] | ||
| 10748 | pub fn init_resp(mut self, value: i32) -> Self { | ||
| 10749 | self.r#resp = value.into(); | ||
| 10750 | self | ||
| 10751 | } | ||
| 10752 | ///Return a reference to `custom_evt_id` | ||
| 10753 | #[inline] | ||
| 10754 | pub fn r#custom_evt_id(&self) -> &u32 { | ||
| 10755 | &self.r#custom_evt_id | ||
| 10756 | } | ||
| 10757 | ///Return a mutable reference to `custom_evt_id` | ||
| 10758 | #[inline] | ||
| 10759 | pub fn mut_custom_evt_id(&mut self) -> &mut u32 { | ||
| 10760 | &mut self.r#custom_evt_id | ||
| 10761 | } | ||
| 10762 | ///Set the value of `custom_evt_id` | ||
| 10763 | #[inline] | ||
| 10764 | pub fn set_custom_evt_id(&mut self, value: u32) -> &mut Self { | ||
| 10765 | self.r#custom_evt_id = value.into(); | ||
| 10766 | self | ||
| 10767 | } | ||
| 10768 | ///Builder method that sets the value of `custom_evt_id`. Useful for initializing the message. | ||
| 10769 | #[inline] | ||
| 10770 | pub fn init_custom_evt_id(mut self, value: u32) -> Self { | ||
| 10771 | self.r#custom_evt_id = value.into(); | ||
| 10772 | self | ||
| 10773 | } | ||
| 10774 | ///Return a reference to `data` | ||
| 10775 | #[inline] | ||
| 10776 | pub fn r#data(&self) -> &::micropb::heapless::Vec<u8, 32> { | ||
| 10777 | &self.r#data | ||
| 10778 | } | ||
| 10779 | ///Return a mutable reference to `data` | ||
| 10780 | #[inline] | ||
| 10781 | pub fn mut_data(&mut self) -> &mut ::micropb::heapless::Vec<u8, 32> { | ||
| 10782 | &mut self.r#data | ||
| 10783 | } | ||
| 10784 | ///Set the value of `data` | ||
| 10785 | #[inline] | ||
| 10786 | pub fn set_data(&mut self, value: ::micropb::heapless::Vec<u8, 32>) -> &mut Self { | ||
| 10787 | self.r#data = value.into(); | ||
| 10788 | self | ||
| 10789 | } | ||
| 10790 | ///Builder method that sets the value of `data`. Useful for initializing the message. | ||
| 10791 | #[inline] | ||
| 10792 | pub fn init_data(mut self, value: ::micropb::heapless::Vec<u8, 32>) -> Self { | ||
| 10793 | self.r#data = value.into(); | ||
| 10794 | self | ||
| 10795 | } | ||
| 10796 | } | ||
| 10797 | impl ::micropb::MessageDecode for CtrlMsg_Event_CustomRpcUnserialisedMsg { | ||
| 10798 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 10799 | &mut self, | ||
| 10800 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 10801 | len: usize, | ||
| 10802 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 10803 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 10804 | let before = decoder.bytes_read(); | ||
| 10805 | while decoder.bytes_read() - before < len { | ||
| 10806 | let tag = decoder.decode_tag()?; | ||
| 10807 | match tag.field_num() { | ||
| 10808 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 10809 | 1u32 => { | ||
| 10810 | let mut_ref = &mut self.r#resp; | ||
| 10811 | { | ||
| 10812 | let val = decoder.decode_int32()?; | ||
| 10813 | let val_ref = &val; | ||
| 10814 | if *val_ref != 0 { | ||
| 10815 | *mut_ref = val as _; | ||
| 10816 | } | ||
| 10817 | }; | ||
| 10818 | } | ||
| 10819 | 2u32 => { | ||
| 10820 | let mut_ref = &mut self.r#custom_evt_id; | ||
| 10821 | { | ||
| 10822 | let val = decoder.decode_varint32()?; | ||
| 10823 | let val_ref = &val; | ||
| 10824 | if *val_ref != 0 { | ||
| 10825 | *mut_ref = val as _; | ||
| 10826 | } | ||
| 10827 | }; | ||
| 10828 | } | ||
| 10829 | 3u32 => { | ||
| 10830 | let mut_ref = &mut self.r#data; | ||
| 10831 | { | ||
| 10832 | decoder.decode_bytes(mut_ref, ::micropb::Presence::Implicit)?; | ||
| 10833 | }; | ||
| 10834 | } | ||
| 10835 | _ => { | ||
| 10836 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 10837 | } | ||
| 10838 | } | ||
| 10839 | } | ||
| 10840 | Ok(()) | ||
| 10841 | } | ||
| 10842 | } | ||
| 10843 | impl ::micropb::MessageEncode for CtrlMsg_Event_CustomRpcUnserialisedMsg { | ||
| 10844 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 10845 | let mut max_size = 0; | ||
| 10846 | if let ::core::option::Option::Some(size) = | ||
| 10847 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 10848 | { | ||
| 10849 | max_size += size; | ||
| 10850 | } else { | ||
| 10851 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10852 | }; | ||
| 10853 | if let ::core::option::Option::Some(size) = | ||
| 10854 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 10855 | { | ||
| 10856 | max_size += size; | ||
| 10857 | } else { | ||
| 10858 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10859 | }; | ||
| 10860 | if let ::core::option::Option::Some(size) = | ||
| 10861 | ::micropb::const_map!(::core::option::Option::Some(33usize), |size| size + 1usize) | ||
| 10862 | { | ||
| 10863 | max_size += size; | ||
| 10864 | } else { | ||
| 10865 | break 'msg (::core::option::Option::<usize>::None); | ||
| 10866 | }; | ||
| 10867 | ::core::option::Option::Some(max_size) | ||
| 10868 | }; | ||
| 10869 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 10870 | &self, | ||
| 10871 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 10872 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 10873 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10874 | { | ||
| 10875 | let val_ref = &self.r#resp; | ||
| 10876 | if *val_ref != 0 { | ||
| 10877 | encoder.encode_varint32(8u32)?; | ||
| 10878 | encoder.encode_int32(*val_ref as _)?; | ||
| 10879 | } | ||
| 10880 | } | ||
| 10881 | { | ||
| 10882 | let val_ref = &self.r#custom_evt_id; | ||
| 10883 | if *val_ref != 0 { | ||
| 10884 | encoder.encode_varint32(16u32)?; | ||
| 10885 | encoder.encode_varint32(*val_ref as _)?; | ||
| 10886 | } | ||
| 10887 | } | ||
| 10888 | { | ||
| 10889 | let val_ref = &self.r#data; | ||
| 10890 | if !val_ref.is_empty() { | ||
| 10891 | encoder.encode_varint32(26u32)?; | ||
| 10892 | encoder.encode_bytes(val_ref)?; | ||
| 10893 | } | ||
| 10894 | } | ||
| 10895 | Ok(()) | ||
| 10896 | } | ||
| 10897 | fn compute_size(&self) -> usize { | ||
| 10898 | use ::micropb::{FieldEncode, PbMap}; | ||
| 10899 | let mut size = 0; | ||
| 10900 | { | ||
| 10901 | let val_ref = &self.r#resp; | ||
| 10902 | if *val_ref != 0 { | ||
| 10903 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 10904 | } | ||
| 10905 | } | ||
| 10906 | { | ||
| 10907 | let val_ref = &self.r#custom_evt_id; | ||
| 10908 | if *val_ref != 0 { | ||
| 10909 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 10910 | } | ||
| 10911 | } | ||
| 10912 | { | ||
| 10913 | let val_ref = &self.r#data; | ||
| 10914 | if !val_ref.is_empty() { | ||
| 10915 | size += 1usize + ::micropb::size::sizeof_len_record(val_ref.len()); | ||
| 10916 | } | ||
| 10917 | } | ||
| 10918 | size | ||
| 10919 | } | ||
| 10920 | } | ||
| 10921 | pub mod CtrlMsg_ { | ||
| 10922 | #[derive(Debug, PartialEq, Clone)] | ||
| 10923 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 10924 | pub enum Payload { | ||
| 10925 | ReqGetMacAddress(super::CtrlMsg_Req_GetMacAddress), | ||
| 10926 | ReqSetMacAddress(super::CtrlMsg_Req_SetMacAddress), | ||
| 10927 | ReqGetWifiMode(super::CtrlMsg_Req_GetMode), | ||
| 10928 | ReqSetWifiMode(super::CtrlMsg_Req_SetMode), | ||
| 10929 | ReqScanApList(super::CtrlMsg_Req_ScanResult), | ||
| 10930 | ReqGetApConfig(super::CtrlMsg_Req_GetAPConfig), | ||
| 10931 | ReqConnectAp(super::CtrlMsg_Req_ConnectAP), | ||
| 10932 | ReqDisconnectAp(super::CtrlMsg_Req_GetStatus), | ||
| 10933 | ReqGetSoftapConfig(super::CtrlMsg_Req_GetSoftAPConfig), | ||
| 10934 | ReqSetSoftapVendorSpecificIe(super::CtrlMsg_Req_SetSoftAPVendorSpecificIE), | ||
| 10935 | ReqStartSoftap(super::CtrlMsg_Req_StartSoftAP), | ||
| 10936 | ReqSoftapConnectedStasList(super::CtrlMsg_Req_SoftAPConnectedSTA), | ||
| 10937 | ReqStopSoftap(super::CtrlMsg_Req_GetStatus), | ||
| 10938 | ReqSetPowerSaveMode(super::CtrlMsg_Req_SetMode), | ||
| 10939 | ReqGetPowerSaveMode(super::CtrlMsg_Req_GetMode), | ||
| 10940 | ReqOtaBegin(super::CtrlMsg_Req_OTABegin), | ||
| 10941 | ReqOtaWrite(super::CtrlMsg_Req_OTAWrite), | ||
| 10942 | ReqOtaEnd(super::CtrlMsg_Req_OTAEnd), | ||
| 10943 | ReqSetWifiMaxTxPower(super::CtrlMsg_Req_SetWifiMaxTxPower), | ||
| 10944 | ReqGetWifiCurrTxPower(super::CtrlMsg_Req_GetWifiCurrTxPower), | ||
| 10945 | ReqConfigHeartbeat(super::CtrlMsg_Req_ConfigHeartbeat), | ||
| 10946 | ReqEnableDisableFeat(super::CtrlMsg_Req_EnableDisable), | ||
| 10947 | ReqGetFwVersion(super::CtrlMsg_Req_GetFwVersion), | ||
| 10948 | ReqSetCountryCode(super::CtrlMsg_Req_SetCountryCode), | ||
| 10949 | ReqGetCountryCode(super::CtrlMsg_Req_GetCountryCode), | ||
| 10950 | ReqSetDhcpDnsStatus(super::CtrlMsg_Req_SetDhcpDnsStatus), | ||
| 10951 | ReqGetDhcpDnsStatus(super::CtrlMsg_Req_GetDhcpDnsStatus), | ||
| 10952 | ReqCustomRpcUnserialisedMsg(super::CtrlMsg_Req_CustomRpcUnserialisedMsg), | ||
| 10953 | RespGetMacAddress(super::CtrlMsg_Resp_GetMacAddress), | ||
| 10954 | RespSetMacAddress(super::CtrlMsg_Resp_SetMacAddress), | ||
| 10955 | RespGetWifiMode(super::CtrlMsg_Resp_GetMode), | ||
| 10956 | RespSetWifiMode(super::CtrlMsg_Resp_SetMode), | ||
| 10957 | RespScanApList(super::CtrlMsg_Resp_ScanResult), | ||
| 10958 | RespGetApConfig(super::CtrlMsg_Resp_GetAPConfig), | ||
| 10959 | RespConnectAp(super::CtrlMsg_Resp_ConnectAP), | ||
| 10960 | RespDisconnectAp(super::CtrlMsg_Resp_GetStatus), | ||
| 10961 | RespGetSoftapConfig(super::CtrlMsg_Resp_GetSoftAPConfig), | ||
| 10962 | RespSetSoftapVendorSpecificIe(super::CtrlMsg_Resp_SetSoftAPVendorSpecificIE), | ||
| 10963 | RespStartSoftap(super::CtrlMsg_Resp_StartSoftAP), | ||
| 10964 | RespSoftapConnectedStasList(super::CtrlMsg_Resp_SoftAPConnectedSTA), | ||
| 10965 | RespStopSoftap(super::CtrlMsg_Resp_GetStatus), | ||
| 10966 | RespSetPowerSaveMode(super::CtrlMsg_Resp_SetMode), | ||
| 10967 | RespGetPowerSaveMode(super::CtrlMsg_Resp_GetMode), | ||
| 10968 | RespOtaBegin(super::CtrlMsg_Resp_OTABegin), | ||
| 10969 | RespOtaWrite(super::CtrlMsg_Resp_OTAWrite), | ||
| 10970 | RespOtaEnd(super::CtrlMsg_Resp_OTAEnd), | ||
| 10971 | RespSetWifiMaxTxPower(super::CtrlMsg_Resp_SetWifiMaxTxPower), | ||
| 10972 | RespGetWifiCurrTxPower(super::CtrlMsg_Resp_GetWifiCurrTxPower), | ||
| 10973 | RespConfigHeartbeat(super::CtrlMsg_Resp_ConfigHeartbeat), | ||
| 10974 | RespEnableDisableFeat(super::CtrlMsg_Resp_EnableDisable), | ||
| 10975 | RespGetFwVersion(super::CtrlMsg_Resp_GetFwVersion), | ||
| 10976 | RespSetCountryCode(super::CtrlMsg_Resp_SetCountryCode), | ||
| 10977 | RespGetCountryCode(super::CtrlMsg_Resp_GetCountryCode), | ||
| 10978 | RespSetDhcpDnsStatus(super::CtrlMsg_Resp_SetDhcpDnsStatus), | ||
| 10979 | RespGetDhcpDnsStatus(super::CtrlMsg_Resp_GetDhcpDnsStatus), | ||
| 10980 | RespCustomRpcUnserialisedMsg(super::CtrlMsg_Resp_CustomRpcUnserialisedMsg), | ||
| 10981 | EventEspInit(super::CtrlMsg_Event_ESPInit), | ||
| 10982 | EventHeartbeat(super::CtrlMsg_Event_Heartbeat), | ||
| 10983 | EventStationDisconnectFromAp(super::CtrlMsg_Event_StationDisconnectFromAP), | ||
| 10984 | EventStationDisconnectFromEspSoftAp(super::CtrlMsg_Event_StationDisconnectFromESPSoftAP), | ||
| 10985 | EventStationConnectedToAp(super::CtrlMsg_Event_StationConnectedToAP), | ||
| 10986 | EventStationConnectedToEspSoftAp(super::CtrlMsg_Event_StationConnectedToESPSoftAP), | ||
| 10987 | EventSetDhcpDnsStatus(super::CtrlMsg_Event_SetDhcpDnsStatus), | ||
| 10988 | EventCustomRpcUnserialisedMsg(super::CtrlMsg_Event_CustomRpcUnserialisedMsg), | ||
| 10989 | } | ||
| 10990 | } | ||
| 10991 | #[derive(Debug, Default, PartialEq, Clone)] | ||
| 10992 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 10993 | pub struct CtrlMsg { | ||
| 10994 | pub r#msg_type: CtrlMsgType, | ||
| 10995 | pub r#msg_id: CtrlMsgId, | ||
| 10996 | pub r#uid: i32, | ||
| 10997 | pub r#req_resp_type: u32, | ||
| 10998 | pub r#payload: ::core::option::Option<CtrlMsg_::Payload>, | ||
| 10999 | } | ||
| 11000 | impl CtrlMsg { | ||
| 11001 | ///Return a reference to `msg_type` | ||
| 11002 | #[inline] | ||
| 11003 | pub fn r#msg_type(&self) -> &CtrlMsgType { | ||
| 11004 | &self.r#msg_type | ||
| 11005 | } | ||
| 11006 | ///Return a mutable reference to `msg_type` | ||
| 11007 | #[inline] | ||
| 11008 | pub fn mut_msg_type(&mut self) -> &mut CtrlMsgType { | ||
| 11009 | &mut self.r#msg_type | ||
| 11010 | } | ||
| 11011 | ///Set the value of `msg_type` | ||
| 11012 | #[inline] | ||
| 11013 | pub fn set_msg_type(&mut self, value: CtrlMsgType) -> &mut Self { | ||
| 11014 | self.r#msg_type = value.into(); | ||
| 11015 | self | ||
| 11016 | } | ||
| 11017 | ///Builder method that sets the value of `msg_type`. Useful for initializing the message. | ||
| 11018 | #[inline] | ||
| 11019 | pub fn init_msg_type(mut self, value: CtrlMsgType) -> Self { | ||
| 11020 | self.r#msg_type = value.into(); | ||
| 11021 | self | ||
| 11022 | } | ||
| 11023 | ///Return a reference to `msg_id` | ||
| 11024 | #[inline] | ||
| 11025 | pub fn r#msg_id(&self) -> &CtrlMsgId { | ||
| 11026 | &self.r#msg_id | ||
| 11027 | } | ||
| 11028 | ///Return a mutable reference to `msg_id` | ||
| 11029 | #[inline] | ||
| 11030 | pub fn mut_msg_id(&mut self) -> &mut CtrlMsgId { | ||
| 11031 | &mut self.r#msg_id | ||
| 11032 | } | ||
| 11033 | ///Set the value of `msg_id` | ||
| 11034 | #[inline] | ||
| 11035 | pub fn set_msg_id(&mut self, value: CtrlMsgId) -> &mut Self { | ||
| 11036 | self.r#msg_id = value.into(); | ||
| 11037 | self | ||
| 11038 | } | ||
| 11039 | ///Builder method that sets the value of `msg_id`. Useful for initializing the message. | ||
| 11040 | #[inline] | ||
| 11041 | pub fn init_msg_id(mut self, value: CtrlMsgId) -> Self { | ||
| 11042 | self.r#msg_id = value.into(); | ||
| 11043 | self | ||
| 11044 | } | ||
| 11045 | ///Return a reference to `uid` | ||
| 11046 | #[inline] | ||
| 11047 | pub fn r#uid(&self) -> &i32 { | ||
| 11048 | &self.r#uid | ||
| 11049 | } | ||
| 11050 | ///Return a mutable reference to `uid` | ||
| 11051 | #[inline] | ||
| 11052 | pub fn mut_uid(&mut self) -> &mut i32 { | ||
| 11053 | &mut self.r#uid | ||
| 11054 | } | ||
| 11055 | ///Set the value of `uid` | ||
| 11056 | #[inline] | ||
| 11057 | pub fn set_uid(&mut self, value: i32) -> &mut Self { | ||
| 11058 | self.r#uid = value.into(); | ||
| 11059 | self | ||
| 11060 | } | ||
| 11061 | ///Builder method that sets the value of `uid`. Useful for initializing the message. | ||
| 11062 | #[inline] | ||
| 11063 | pub fn init_uid(mut self, value: i32) -> Self { | ||
| 11064 | self.r#uid = value.into(); | ||
| 11065 | self | ||
| 11066 | } | ||
| 11067 | ///Return a reference to `req_resp_type` | ||
| 11068 | #[inline] | ||
| 11069 | pub fn r#req_resp_type(&self) -> &u32 { | ||
| 11070 | &self.r#req_resp_type | ||
| 11071 | } | ||
| 11072 | ///Return a mutable reference to `req_resp_type` | ||
| 11073 | #[inline] | ||
| 11074 | pub fn mut_req_resp_type(&mut self) -> &mut u32 { | ||
| 11075 | &mut self.r#req_resp_type | ||
| 11076 | } | ||
| 11077 | ///Set the value of `req_resp_type` | ||
| 11078 | #[inline] | ||
| 11079 | pub fn set_req_resp_type(&mut self, value: u32) -> &mut Self { | ||
| 11080 | self.r#req_resp_type = value.into(); | ||
| 11081 | self | ||
| 11082 | } | ||
| 11083 | ///Builder method that sets the value of `req_resp_type`. Useful for initializing the message. | ||
| 11084 | #[inline] | ||
| 11085 | pub fn init_req_resp_type(mut self, value: u32) -> Self { | ||
| 11086 | self.r#req_resp_type = value.into(); | ||
| 11087 | self | ||
| 11088 | } | ||
| 11089 | } | ||
| 11090 | impl ::micropb::MessageDecode for CtrlMsg { | ||
| 11091 | fn decode<IMPL_MICROPB_READ: ::micropb::PbRead>( | ||
| 11092 | &mut self, | ||
| 11093 | decoder: &mut ::micropb::PbDecoder<IMPL_MICROPB_READ>, | ||
| 11094 | len: usize, | ||
| 11095 | ) -> Result<(), ::micropb::DecodeError<IMPL_MICROPB_READ::Error>> { | ||
| 11096 | use ::micropb::{FieldDecode, PbBytes, PbMap, PbString, PbVec}; | ||
| 11097 | let before = decoder.bytes_read(); | ||
| 11098 | while decoder.bytes_read() - before < len { | ||
| 11099 | let tag = decoder.decode_tag()?; | ||
| 11100 | match tag.field_num() { | ||
| 11101 | 0 => return Err(::micropb::DecodeError::ZeroField), | ||
| 11102 | 1u32 => { | ||
| 11103 | let mut_ref = &mut self.r#msg_type; | ||
| 11104 | { | ||
| 11105 | let val = decoder.decode_int32().map(|n| CtrlMsgType(n as _))?; | ||
| 11106 | let val_ref = &val; | ||
| 11107 | if val_ref.0 != 0 { | ||
| 11108 | *mut_ref = val as _; | ||
| 11109 | } | ||
| 11110 | }; | ||
| 11111 | } | ||
| 11112 | 2u32 => { | ||
| 11113 | let mut_ref = &mut self.r#msg_id; | ||
| 11114 | { | ||
| 11115 | let val = decoder.decode_int32().map(|n| CtrlMsgId(n as _))?; | ||
| 11116 | let val_ref = &val; | ||
| 11117 | if val_ref.0 != 0 { | ||
| 11118 | *mut_ref = val as _; | ||
| 11119 | } | ||
| 11120 | }; | ||
| 11121 | } | ||
| 11122 | 3u32 => { | ||
| 11123 | let mut_ref = &mut self.r#uid; | ||
| 11124 | { | ||
| 11125 | let val = decoder.decode_int32()?; | ||
| 11126 | let val_ref = &val; | ||
| 11127 | if *val_ref != 0 { | ||
| 11128 | *mut_ref = val as _; | ||
| 11129 | } | ||
| 11130 | }; | ||
| 11131 | } | ||
| 11132 | 4u32 => { | ||
| 11133 | let mut_ref = &mut self.r#req_resp_type; | ||
| 11134 | { | ||
| 11135 | let val = decoder.decode_varint32()?; | ||
| 11136 | let val_ref = &val; | ||
| 11137 | if *val_ref != 0 { | ||
| 11138 | *mut_ref = val as _; | ||
| 11139 | } | ||
| 11140 | }; | ||
| 11141 | } | ||
| 11142 | 101u32 => { | ||
| 11143 | let mut_ref = loop { | ||
| 11144 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11145 | if let CtrlMsg_::Payload::ReqGetMacAddress(variant) = &mut *variant { | ||
| 11146 | break &mut *variant; | ||
| 11147 | } | ||
| 11148 | } | ||
| 11149 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetMacAddress( | ||
| 11150 | ::core::default::Default::default(), | ||
| 11151 | )); | ||
| 11152 | }; | ||
| 11153 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11154 | } | ||
| 11155 | 102u32 => { | ||
| 11156 | let mut_ref = loop { | ||
| 11157 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11158 | if let CtrlMsg_::Payload::ReqSetMacAddress(variant) = &mut *variant { | ||
| 11159 | break &mut *variant; | ||
| 11160 | } | ||
| 11161 | } | ||
| 11162 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetMacAddress( | ||
| 11163 | ::core::default::Default::default(), | ||
| 11164 | )); | ||
| 11165 | }; | ||
| 11166 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11167 | } | ||
| 11168 | 103u32 => { | ||
| 11169 | let mut_ref = loop { | ||
| 11170 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11171 | if let CtrlMsg_::Payload::ReqGetWifiMode(variant) = &mut *variant { | ||
| 11172 | break &mut *variant; | ||
| 11173 | } | ||
| 11174 | } | ||
| 11175 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetWifiMode( | ||
| 11176 | ::core::default::Default::default(), | ||
| 11177 | )); | ||
| 11178 | }; | ||
| 11179 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11180 | } | ||
| 11181 | 104u32 => { | ||
| 11182 | let mut_ref = loop { | ||
| 11183 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11184 | if let CtrlMsg_::Payload::ReqSetWifiMode(variant) = &mut *variant { | ||
| 11185 | break &mut *variant; | ||
| 11186 | } | ||
| 11187 | } | ||
| 11188 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetWifiMode( | ||
| 11189 | ::core::default::Default::default(), | ||
| 11190 | )); | ||
| 11191 | }; | ||
| 11192 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11193 | } | ||
| 11194 | 105u32 => { | ||
| 11195 | let mut_ref = loop { | ||
| 11196 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11197 | if let CtrlMsg_::Payload::ReqScanApList(variant) = &mut *variant { | ||
| 11198 | break &mut *variant; | ||
| 11199 | } | ||
| 11200 | } | ||
| 11201 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqScanApList( | ||
| 11202 | ::core::default::Default::default(), | ||
| 11203 | )); | ||
| 11204 | }; | ||
| 11205 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11206 | } | ||
| 11207 | 106u32 => { | ||
| 11208 | let mut_ref = loop { | ||
| 11209 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11210 | if let CtrlMsg_::Payload::ReqGetApConfig(variant) = &mut *variant { | ||
| 11211 | break &mut *variant; | ||
| 11212 | } | ||
| 11213 | } | ||
| 11214 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetApConfig( | ||
| 11215 | ::core::default::Default::default(), | ||
| 11216 | )); | ||
| 11217 | }; | ||
| 11218 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11219 | } | ||
| 11220 | 107u32 => { | ||
| 11221 | let mut_ref = loop { | ||
| 11222 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11223 | if let CtrlMsg_::Payload::ReqConnectAp(variant) = &mut *variant { | ||
| 11224 | break &mut *variant; | ||
| 11225 | } | ||
| 11226 | } | ||
| 11227 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqConnectAp( | ||
| 11228 | ::core::default::Default::default(), | ||
| 11229 | )); | ||
| 11230 | }; | ||
| 11231 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11232 | } | ||
| 11233 | 108u32 => { | ||
| 11234 | let mut_ref = loop { | ||
| 11235 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11236 | if let CtrlMsg_::Payload::ReqDisconnectAp(variant) = &mut *variant { | ||
| 11237 | break &mut *variant; | ||
| 11238 | } | ||
| 11239 | } | ||
| 11240 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqDisconnectAp( | ||
| 11241 | ::core::default::Default::default(), | ||
| 11242 | )); | ||
| 11243 | }; | ||
| 11244 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11245 | } | ||
| 11246 | 109u32 => { | ||
| 11247 | let mut_ref = loop { | ||
| 11248 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11249 | if let CtrlMsg_::Payload::ReqGetSoftapConfig(variant) = &mut *variant { | ||
| 11250 | break &mut *variant; | ||
| 11251 | } | ||
| 11252 | } | ||
| 11253 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetSoftapConfig( | ||
| 11254 | ::core::default::Default::default(), | ||
| 11255 | )); | ||
| 11256 | }; | ||
| 11257 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11258 | } | ||
| 11259 | 110u32 => { | ||
| 11260 | let mut_ref = loop { | ||
| 11261 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11262 | if let CtrlMsg_::Payload::ReqSetSoftapVendorSpecificIe(variant) = &mut *variant { | ||
| 11263 | break &mut *variant; | ||
| 11264 | } | ||
| 11265 | } | ||
| 11266 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetSoftapVendorSpecificIe( | ||
| 11267 | ::core::default::Default::default(), | ||
| 11268 | )); | ||
| 11269 | }; | ||
| 11270 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11271 | } | ||
| 11272 | 111u32 => { | ||
| 11273 | let mut_ref = loop { | ||
| 11274 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11275 | if let CtrlMsg_::Payload::ReqStartSoftap(variant) = &mut *variant { | ||
| 11276 | break &mut *variant; | ||
| 11277 | } | ||
| 11278 | } | ||
| 11279 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqStartSoftap( | ||
| 11280 | ::core::default::Default::default(), | ||
| 11281 | )); | ||
| 11282 | }; | ||
| 11283 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11284 | } | ||
| 11285 | 112u32 => { | ||
| 11286 | let mut_ref = loop { | ||
| 11287 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11288 | if let CtrlMsg_::Payload::ReqSoftapConnectedStasList(variant) = &mut *variant { | ||
| 11289 | break &mut *variant; | ||
| 11290 | } | ||
| 11291 | } | ||
| 11292 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSoftapConnectedStasList( | ||
| 11293 | ::core::default::Default::default(), | ||
| 11294 | )); | ||
| 11295 | }; | ||
| 11296 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11297 | } | ||
| 11298 | 113u32 => { | ||
| 11299 | let mut_ref = loop { | ||
| 11300 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11301 | if let CtrlMsg_::Payload::ReqStopSoftap(variant) = &mut *variant { | ||
| 11302 | break &mut *variant; | ||
| 11303 | } | ||
| 11304 | } | ||
| 11305 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqStopSoftap( | ||
| 11306 | ::core::default::Default::default(), | ||
| 11307 | )); | ||
| 11308 | }; | ||
| 11309 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11310 | } | ||
| 11311 | 114u32 => { | ||
| 11312 | let mut_ref = loop { | ||
| 11313 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11314 | if let CtrlMsg_::Payload::ReqSetPowerSaveMode(variant) = &mut *variant { | ||
| 11315 | break &mut *variant; | ||
| 11316 | } | ||
| 11317 | } | ||
| 11318 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetPowerSaveMode( | ||
| 11319 | ::core::default::Default::default(), | ||
| 11320 | )); | ||
| 11321 | }; | ||
| 11322 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11323 | } | ||
| 11324 | 115u32 => { | ||
| 11325 | let mut_ref = loop { | ||
| 11326 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11327 | if let CtrlMsg_::Payload::ReqGetPowerSaveMode(variant) = &mut *variant { | ||
| 11328 | break &mut *variant; | ||
| 11329 | } | ||
| 11330 | } | ||
| 11331 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetPowerSaveMode( | ||
| 11332 | ::core::default::Default::default(), | ||
| 11333 | )); | ||
| 11334 | }; | ||
| 11335 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11336 | } | ||
| 11337 | 116u32 => { | ||
| 11338 | let mut_ref = loop { | ||
| 11339 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11340 | if let CtrlMsg_::Payload::ReqOtaBegin(variant) = &mut *variant { | ||
| 11341 | break &mut *variant; | ||
| 11342 | } | ||
| 11343 | } | ||
| 11344 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqOtaBegin( | ||
| 11345 | ::core::default::Default::default(), | ||
| 11346 | )); | ||
| 11347 | }; | ||
| 11348 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11349 | } | ||
| 11350 | 117u32 => { | ||
| 11351 | let mut_ref = loop { | ||
| 11352 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11353 | if let CtrlMsg_::Payload::ReqOtaWrite(variant) = &mut *variant { | ||
| 11354 | break &mut *variant; | ||
| 11355 | } | ||
| 11356 | } | ||
| 11357 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqOtaWrite( | ||
| 11358 | ::core::default::Default::default(), | ||
| 11359 | )); | ||
| 11360 | }; | ||
| 11361 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11362 | } | ||
| 11363 | 118u32 => { | ||
| 11364 | let mut_ref = loop { | ||
| 11365 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11366 | if let CtrlMsg_::Payload::ReqOtaEnd(variant) = &mut *variant { | ||
| 11367 | break &mut *variant; | ||
| 11368 | } | ||
| 11369 | } | ||
| 11370 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqOtaEnd( | ||
| 11371 | ::core::default::Default::default(), | ||
| 11372 | )); | ||
| 11373 | }; | ||
| 11374 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11375 | } | ||
| 11376 | 119u32 => { | ||
| 11377 | let mut_ref = loop { | ||
| 11378 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11379 | if let CtrlMsg_::Payload::ReqSetWifiMaxTxPower(variant) = &mut *variant { | ||
| 11380 | break &mut *variant; | ||
| 11381 | } | ||
| 11382 | } | ||
| 11383 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetWifiMaxTxPower( | ||
| 11384 | ::core::default::Default::default(), | ||
| 11385 | )); | ||
| 11386 | }; | ||
| 11387 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11388 | } | ||
| 11389 | 120u32 => { | ||
| 11390 | let mut_ref = loop { | ||
| 11391 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11392 | if let CtrlMsg_::Payload::ReqGetWifiCurrTxPower(variant) = &mut *variant { | ||
| 11393 | break &mut *variant; | ||
| 11394 | } | ||
| 11395 | } | ||
| 11396 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetWifiCurrTxPower( | ||
| 11397 | ::core::default::Default::default(), | ||
| 11398 | )); | ||
| 11399 | }; | ||
| 11400 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11401 | } | ||
| 11402 | 121u32 => { | ||
| 11403 | let mut_ref = loop { | ||
| 11404 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11405 | if let CtrlMsg_::Payload::ReqConfigHeartbeat(variant) = &mut *variant { | ||
| 11406 | break &mut *variant; | ||
| 11407 | } | ||
| 11408 | } | ||
| 11409 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqConfigHeartbeat( | ||
| 11410 | ::core::default::Default::default(), | ||
| 11411 | )); | ||
| 11412 | }; | ||
| 11413 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11414 | } | ||
| 11415 | 122u32 => { | ||
| 11416 | let mut_ref = loop { | ||
| 11417 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11418 | if let CtrlMsg_::Payload::ReqEnableDisableFeat(variant) = &mut *variant { | ||
| 11419 | break &mut *variant; | ||
| 11420 | } | ||
| 11421 | } | ||
| 11422 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqEnableDisableFeat( | ||
| 11423 | ::core::default::Default::default(), | ||
| 11424 | )); | ||
| 11425 | }; | ||
| 11426 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11427 | } | ||
| 11428 | 123u32 => { | ||
| 11429 | let mut_ref = loop { | ||
| 11430 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11431 | if let CtrlMsg_::Payload::ReqGetFwVersion(variant) = &mut *variant { | ||
| 11432 | break &mut *variant; | ||
| 11433 | } | ||
| 11434 | } | ||
| 11435 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetFwVersion( | ||
| 11436 | ::core::default::Default::default(), | ||
| 11437 | )); | ||
| 11438 | }; | ||
| 11439 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11440 | } | ||
| 11441 | 124u32 => { | ||
| 11442 | let mut_ref = loop { | ||
| 11443 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11444 | if let CtrlMsg_::Payload::ReqSetCountryCode(variant) = &mut *variant { | ||
| 11445 | break &mut *variant; | ||
| 11446 | } | ||
| 11447 | } | ||
| 11448 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetCountryCode( | ||
| 11449 | ::core::default::Default::default(), | ||
| 11450 | )); | ||
| 11451 | }; | ||
| 11452 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11453 | } | ||
| 11454 | 125u32 => { | ||
| 11455 | let mut_ref = loop { | ||
| 11456 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11457 | if let CtrlMsg_::Payload::ReqGetCountryCode(variant) = &mut *variant { | ||
| 11458 | break &mut *variant; | ||
| 11459 | } | ||
| 11460 | } | ||
| 11461 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetCountryCode( | ||
| 11462 | ::core::default::Default::default(), | ||
| 11463 | )); | ||
| 11464 | }; | ||
| 11465 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11466 | } | ||
| 11467 | 126u32 => { | ||
| 11468 | let mut_ref = loop { | ||
| 11469 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11470 | if let CtrlMsg_::Payload::ReqSetDhcpDnsStatus(variant) = &mut *variant { | ||
| 11471 | break &mut *variant; | ||
| 11472 | } | ||
| 11473 | } | ||
| 11474 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqSetDhcpDnsStatus( | ||
| 11475 | ::core::default::Default::default(), | ||
| 11476 | )); | ||
| 11477 | }; | ||
| 11478 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11479 | } | ||
| 11480 | 127u32 => { | ||
| 11481 | let mut_ref = loop { | ||
| 11482 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11483 | if let CtrlMsg_::Payload::ReqGetDhcpDnsStatus(variant) = &mut *variant { | ||
| 11484 | break &mut *variant; | ||
| 11485 | } | ||
| 11486 | } | ||
| 11487 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqGetDhcpDnsStatus( | ||
| 11488 | ::core::default::Default::default(), | ||
| 11489 | )); | ||
| 11490 | }; | ||
| 11491 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11492 | } | ||
| 11493 | 128u32 => { | ||
| 11494 | let mut_ref = loop { | ||
| 11495 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11496 | if let CtrlMsg_::Payload::ReqCustomRpcUnserialisedMsg(variant) = &mut *variant { | ||
| 11497 | break &mut *variant; | ||
| 11498 | } | ||
| 11499 | } | ||
| 11500 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::ReqCustomRpcUnserialisedMsg( | ||
| 11501 | ::core::default::Default::default(), | ||
| 11502 | )); | ||
| 11503 | }; | ||
| 11504 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11505 | } | ||
| 11506 | 201u32 => { | ||
| 11507 | let mut_ref = loop { | ||
| 11508 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11509 | if let CtrlMsg_::Payload::RespGetMacAddress(variant) = &mut *variant { | ||
| 11510 | break &mut *variant; | ||
| 11511 | } | ||
| 11512 | } | ||
| 11513 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetMacAddress( | ||
| 11514 | ::core::default::Default::default(), | ||
| 11515 | )); | ||
| 11516 | }; | ||
| 11517 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11518 | } | ||
| 11519 | 202u32 => { | ||
| 11520 | let mut_ref = loop { | ||
| 11521 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11522 | if let CtrlMsg_::Payload::RespSetMacAddress(variant) = &mut *variant { | ||
| 11523 | break &mut *variant; | ||
| 11524 | } | ||
| 11525 | } | ||
| 11526 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSetMacAddress( | ||
| 11527 | ::core::default::Default::default(), | ||
| 11528 | )); | ||
| 11529 | }; | ||
| 11530 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11531 | } | ||
| 11532 | 203u32 => { | ||
| 11533 | let mut_ref = loop { | ||
| 11534 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11535 | if let CtrlMsg_::Payload::RespGetWifiMode(variant) = &mut *variant { | ||
| 11536 | break &mut *variant; | ||
| 11537 | } | ||
| 11538 | } | ||
| 11539 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetWifiMode( | ||
| 11540 | ::core::default::Default::default(), | ||
| 11541 | )); | ||
| 11542 | }; | ||
| 11543 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11544 | } | ||
| 11545 | 204u32 => { | ||
| 11546 | let mut_ref = loop { | ||
| 11547 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11548 | if let CtrlMsg_::Payload::RespSetWifiMode(variant) = &mut *variant { | ||
| 11549 | break &mut *variant; | ||
| 11550 | } | ||
| 11551 | } | ||
| 11552 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSetWifiMode( | ||
| 11553 | ::core::default::Default::default(), | ||
| 11554 | )); | ||
| 11555 | }; | ||
| 11556 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11557 | } | ||
| 11558 | 205u32 => { | ||
| 11559 | let mut_ref = loop { | ||
| 11560 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11561 | if let CtrlMsg_::Payload::RespScanApList(variant) = &mut *variant { | ||
| 11562 | break &mut *variant; | ||
| 11563 | } | ||
| 11564 | } | ||
| 11565 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespScanApList( | ||
| 11566 | ::core::default::Default::default(), | ||
| 11567 | )); | ||
| 11568 | }; | ||
| 11569 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11570 | } | ||
| 11571 | 206u32 => { | ||
| 11572 | let mut_ref = loop { | ||
| 11573 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11574 | if let CtrlMsg_::Payload::RespGetApConfig(variant) = &mut *variant { | ||
| 11575 | break &mut *variant; | ||
| 11576 | } | ||
| 11577 | } | ||
| 11578 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetApConfig( | ||
| 11579 | ::core::default::Default::default(), | ||
| 11580 | )); | ||
| 11581 | }; | ||
| 11582 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11583 | } | ||
| 11584 | 207u32 => { | ||
| 11585 | let mut_ref = loop { | ||
| 11586 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11587 | if let CtrlMsg_::Payload::RespConnectAp(variant) = &mut *variant { | ||
| 11588 | break &mut *variant; | ||
| 11589 | } | ||
| 11590 | } | ||
| 11591 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespConnectAp( | ||
| 11592 | ::core::default::Default::default(), | ||
| 11593 | )); | ||
| 11594 | }; | ||
| 11595 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11596 | } | ||
| 11597 | 208u32 => { | ||
| 11598 | let mut_ref = loop { | ||
| 11599 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11600 | if let CtrlMsg_::Payload::RespDisconnectAp(variant) = &mut *variant { | ||
| 11601 | break &mut *variant; | ||
| 11602 | } | ||
| 11603 | } | ||
| 11604 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespDisconnectAp( | ||
| 11605 | ::core::default::Default::default(), | ||
| 11606 | )); | ||
| 11607 | }; | ||
| 11608 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11609 | } | ||
| 11610 | 209u32 => { | ||
| 11611 | let mut_ref = loop { | ||
| 11612 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11613 | if let CtrlMsg_::Payload::RespGetSoftapConfig(variant) = &mut *variant { | ||
| 11614 | break &mut *variant; | ||
| 11615 | } | ||
| 11616 | } | ||
| 11617 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetSoftapConfig( | ||
| 11618 | ::core::default::Default::default(), | ||
| 11619 | )); | ||
| 11620 | }; | ||
| 11621 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11622 | } | ||
| 11623 | 210u32 => { | ||
| 11624 | let mut_ref = loop { | ||
| 11625 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11626 | if let CtrlMsg_::Payload::RespSetSoftapVendorSpecificIe(variant) = &mut *variant { | ||
| 11627 | break &mut *variant; | ||
| 11628 | } | ||
| 11629 | } | ||
| 11630 | self.r#payload = ::core::option::Option::Some( | ||
| 11631 | CtrlMsg_::Payload::RespSetSoftapVendorSpecificIe(::core::default::Default::default()), | ||
| 11632 | ); | ||
| 11633 | }; | ||
| 11634 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11635 | } | ||
| 11636 | 211u32 => { | ||
| 11637 | let mut_ref = loop { | ||
| 11638 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11639 | if let CtrlMsg_::Payload::RespStartSoftap(variant) = &mut *variant { | ||
| 11640 | break &mut *variant; | ||
| 11641 | } | ||
| 11642 | } | ||
| 11643 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespStartSoftap( | ||
| 11644 | ::core::default::Default::default(), | ||
| 11645 | )); | ||
| 11646 | }; | ||
| 11647 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11648 | } | ||
| 11649 | 212u32 => { | ||
| 11650 | let mut_ref = loop { | ||
| 11651 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11652 | if let CtrlMsg_::Payload::RespSoftapConnectedStasList(variant) = &mut *variant { | ||
| 11653 | break &mut *variant; | ||
| 11654 | } | ||
| 11655 | } | ||
| 11656 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSoftapConnectedStasList( | ||
| 11657 | ::core::default::Default::default(), | ||
| 11658 | )); | ||
| 11659 | }; | ||
| 11660 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11661 | } | ||
| 11662 | 213u32 => { | ||
| 11663 | let mut_ref = loop { | ||
| 11664 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11665 | if let CtrlMsg_::Payload::RespStopSoftap(variant) = &mut *variant { | ||
| 11666 | break &mut *variant; | ||
| 11667 | } | ||
| 11668 | } | ||
| 11669 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespStopSoftap( | ||
| 11670 | ::core::default::Default::default(), | ||
| 11671 | )); | ||
| 11672 | }; | ||
| 11673 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11674 | } | ||
| 11675 | 214u32 => { | ||
| 11676 | let mut_ref = loop { | ||
| 11677 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11678 | if let CtrlMsg_::Payload::RespSetPowerSaveMode(variant) = &mut *variant { | ||
| 11679 | break &mut *variant; | ||
| 11680 | } | ||
| 11681 | } | ||
| 11682 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSetPowerSaveMode( | ||
| 11683 | ::core::default::Default::default(), | ||
| 11684 | )); | ||
| 11685 | }; | ||
| 11686 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11687 | } | ||
| 11688 | 215u32 => { | ||
| 11689 | let mut_ref = loop { | ||
| 11690 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11691 | if let CtrlMsg_::Payload::RespGetPowerSaveMode(variant) = &mut *variant { | ||
| 11692 | break &mut *variant; | ||
| 11693 | } | ||
| 11694 | } | ||
| 11695 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetPowerSaveMode( | ||
| 11696 | ::core::default::Default::default(), | ||
| 11697 | )); | ||
| 11698 | }; | ||
| 11699 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11700 | } | ||
| 11701 | 216u32 => { | ||
| 11702 | let mut_ref = loop { | ||
| 11703 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11704 | if let CtrlMsg_::Payload::RespOtaBegin(variant) = &mut *variant { | ||
| 11705 | break &mut *variant; | ||
| 11706 | } | ||
| 11707 | } | ||
| 11708 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespOtaBegin( | ||
| 11709 | ::core::default::Default::default(), | ||
| 11710 | )); | ||
| 11711 | }; | ||
| 11712 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11713 | } | ||
| 11714 | 217u32 => { | ||
| 11715 | let mut_ref = loop { | ||
| 11716 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11717 | if let CtrlMsg_::Payload::RespOtaWrite(variant) = &mut *variant { | ||
| 11718 | break &mut *variant; | ||
| 11719 | } | ||
| 11720 | } | ||
| 11721 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespOtaWrite( | ||
| 11722 | ::core::default::Default::default(), | ||
| 11723 | )); | ||
| 11724 | }; | ||
| 11725 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11726 | } | ||
| 11727 | 218u32 => { | ||
| 11728 | let mut_ref = loop { | ||
| 11729 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11730 | if let CtrlMsg_::Payload::RespOtaEnd(variant) = &mut *variant { | ||
| 11731 | break &mut *variant; | ||
| 11732 | } | ||
| 11733 | } | ||
| 11734 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespOtaEnd( | ||
| 11735 | ::core::default::Default::default(), | ||
| 11736 | )); | ||
| 11737 | }; | ||
| 11738 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11739 | } | ||
| 11740 | 219u32 => { | ||
| 11741 | let mut_ref = loop { | ||
| 11742 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11743 | if let CtrlMsg_::Payload::RespSetWifiMaxTxPower(variant) = &mut *variant { | ||
| 11744 | break &mut *variant; | ||
| 11745 | } | ||
| 11746 | } | ||
| 11747 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSetWifiMaxTxPower( | ||
| 11748 | ::core::default::Default::default(), | ||
| 11749 | )); | ||
| 11750 | }; | ||
| 11751 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11752 | } | ||
| 11753 | 220u32 => { | ||
| 11754 | let mut_ref = loop { | ||
| 11755 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11756 | if let CtrlMsg_::Payload::RespGetWifiCurrTxPower(variant) = &mut *variant { | ||
| 11757 | break &mut *variant; | ||
| 11758 | } | ||
| 11759 | } | ||
| 11760 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetWifiCurrTxPower( | ||
| 11761 | ::core::default::Default::default(), | ||
| 11762 | )); | ||
| 11763 | }; | ||
| 11764 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11765 | } | ||
| 11766 | 221u32 => { | ||
| 11767 | let mut_ref = loop { | ||
| 11768 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11769 | if let CtrlMsg_::Payload::RespConfigHeartbeat(variant) = &mut *variant { | ||
| 11770 | break &mut *variant; | ||
| 11771 | } | ||
| 11772 | } | ||
| 11773 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespConfigHeartbeat( | ||
| 11774 | ::core::default::Default::default(), | ||
| 11775 | )); | ||
| 11776 | }; | ||
| 11777 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11778 | } | ||
| 11779 | 222u32 => { | ||
| 11780 | let mut_ref = loop { | ||
| 11781 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11782 | if let CtrlMsg_::Payload::RespEnableDisableFeat(variant) = &mut *variant { | ||
| 11783 | break &mut *variant; | ||
| 11784 | } | ||
| 11785 | } | ||
| 11786 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespEnableDisableFeat( | ||
| 11787 | ::core::default::Default::default(), | ||
| 11788 | )); | ||
| 11789 | }; | ||
| 11790 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11791 | } | ||
| 11792 | 223u32 => { | ||
| 11793 | let mut_ref = loop { | ||
| 11794 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11795 | if let CtrlMsg_::Payload::RespGetFwVersion(variant) = &mut *variant { | ||
| 11796 | break &mut *variant; | ||
| 11797 | } | ||
| 11798 | } | ||
| 11799 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetFwVersion( | ||
| 11800 | ::core::default::Default::default(), | ||
| 11801 | )); | ||
| 11802 | }; | ||
| 11803 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11804 | } | ||
| 11805 | 224u32 => { | ||
| 11806 | let mut_ref = loop { | ||
| 11807 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11808 | if let CtrlMsg_::Payload::RespSetCountryCode(variant) = &mut *variant { | ||
| 11809 | break &mut *variant; | ||
| 11810 | } | ||
| 11811 | } | ||
| 11812 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSetCountryCode( | ||
| 11813 | ::core::default::Default::default(), | ||
| 11814 | )); | ||
| 11815 | }; | ||
| 11816 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11817 | } | ||
| 11818 | 225u32 => { | ||
| 11819 | let mut_ref = loop { | ||
| 11820 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11821 | if let CtrlMsg_::Payload::RespGetCountryCode(variant) = &mut *variant { | ||
| 11822 | break &mut *variant; | ||
| 11823 | } | ||
| 11824 | } | ||
| 11825 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetCountryCode( | ||
| 11826 | ::core::default::Default::default(), | ||
| 11827 | )); | ||
| 11828 | }; | ||
| 11829 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11830 | } | ||
| 11831 | 226u32 => { | ||
| 11832 | let mut_ref = loop { | ||
| 11833 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11834 | if let CtrlMsg_::Payload::RespSetDhcpDnsStatus(variant) = &mut *variant { | ||
| 11835 | break &mut *variant; | ||
| 11836 | } | ||
| 11837 | } | ||
| 11838 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespSetDhcpDnsStatus( | ||
| 11839 | ::core::default::Default::default(), | ||
| 11840 | )); | ||
| 11841 | }; | ||
| 11842 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11843 | } | ||
| 11844 | 227u32 => { | ||
| 11845 | let mut_ref = loop { | ||
| 11846 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11847 | if let CtrlMsg_::Payload::RespGetDhcpDnsStatus(variant) = &mut *variant { | ||
| 11848 | break &mut *variant; | ||
| 11849 | } | ||
| 11850 | } | ||
| 11851 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespGetDhcpDnsStatus( | ||
| 11852 | ::core::default::Default::default(), | ||
| 11853 | )); | ||
| 11854 | }; | ||
| 11855 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11856 | } | ||
| 11857 | 228u32 => { | ||
| 11858 | let mut_ref = loop { | ||
| 11859 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11860 | if let CtrlMsg_::Payload::RespCustomRpcUnserialisedMsg(variant) = &mut *variant { | ||
| 11861 | break &mut *variant; | ||
| 11862 | } | ||
| 11863 | } | ||
| 11864 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::RespCustomRpcUnserialisedMsg( | ||
| 11865 | ::core::default::Default::default(), | ||
| 11866 | )); | ||
| 11867 | }; | ||
| 11868 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11869 | } | ||
| 11870 | 301u32 => { | ||
| 11871 | let mut_ref = loop { | ||
| 11872 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11873 | if let CtrlMsg_::Payload::EventEspInit(variant) = &mut *variant { | ||
| 11874 | break &mut *variant; | ||
| 11875 | } | ||
| 11876 | } | ||
| 11877 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::EventEspInit( | ||
| 11878 | ::core::default::Default::default(), | ||
| 11879 | )); | ||
| 11880 | }; | ||
| 11881 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11882 | } | ||
| 11883 | 302u32 => { | ||
| 11884 | let mut_ref = loop { | ||
| 11885 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11886 | if let CtrlMsg_::Payload::EventHeartbeat(variant) = &mut *variant { | ||
| 11887 | break &mut *variant; | ||
| 11888 | } | ||
| 11889 | } | ||
| 11890 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::EventHeartbeat( | ||
| 11891 | ::core::default::Default::default(), | ||
| 11892 | )); | ||
| 11893 | }; | ||
| 11894 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11895 | } | ||
| 11896 | 303u32 => { | ||
| 11897 | let mut_ref = loop { | ||
| 11898 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11899 | if let CtrlMsg_::Payload::EventStationDisconnectFromAp(variant) = &mut *variant { | ||
| 11900 | break &mut *variant; | ||
| 11901 | } | ||
| 11902 | } | ||
| 11903 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::EventStationDisconnectFromAp( | ||
| 11904 | ::core::default::Default::default(), | ||
| 11905 | )); | ||
| 11906 | }; | ||
| 11907 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11908 | } | ||
| 11909 | 304u32 => { | ||
| 11910 | let mut_ref = loop { | ||
| 11911 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11912 | if let CtrlMsg_::Payload::EventStationDisconnectFromEspSoftAp(variant) = &mut *variant { | ||
| 11913 | break &mut *variant; | ||
| 11914 | } | ||
| 11915 | } | ||
| 11916 | self.r#payload = ::core::option::Option::Some( | ||
| 11917 | CtrlMsg_::Payload::EventStationDisconnectFromEspSoftAp(::core::default::Default::default()), | ||
| 11918 | ); | ||
| 11919 | }; | ||
| 11920 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11921 | } | ||
| 11922 | 305u32 => { | ||
| 11923 | let mut_ref = loop { | ||
| 11924 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11925 | if let CtrlMsg_::Payload::EventStationConnectedToAp(variant) = &mut *variant { | ||
| 11926 | break &mut *variant; | ||
| 11927 | } | ||
| 11928 | } | ||
| 11929 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::EventStationConnectedToAp( | ||
| 11930 | ::core::default::Default::default(), | ||
| 11931 | )); | ||
| 11932 | }; | ||
| 11933 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11934 | } | ||
| 11935 | 306u32 => { | ||
| 11936 | let mut_ref = loop { | ||
| 11937 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11938 | if let CtrlMsg_::Payload::EventStationConnectedToEspSoftAp(variant) = &mut *variant { | ||
| 11939 | break &mut *variant; | ||
| 11940 | } | ||
| 11941 | } | ||
| 11942 | self.r#payload = ::core::option::Option::Some( | ||
| 11943 | CtrlMsg_::Payload::EventStationConnectedToEspSoftAp(::core::default::Default::default()), | ||
| 11944 | ); | ||
| 11945 | }; | ||
| 11946 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11947 | } | ||
| 11948 | 307u32 => { | ||
| 11949 | let mut_ref = loop { | ||
| 11950 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11951 | if let CtrlMsg_::Payload::EventSetDhcpDnsStatus(variant) = &mut *variant { | ||
| 11952 | break &mut *variant; | ||
| 11953 | } | ||
| 11954 | } | ||
| 11955 | self.r#payload = ::core::option::Option::Some(CtrlMsg_::Payload::EventSetDhcpDnsStatus( | ||
| 11956 | ::core::default::Default::default(), | ||
| 11957 | )); | ||
| 11958 | }; | ||
| 11959 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11960 | } | ||
| 11961 | 308u32 => { | ||
| 11962 | let mut_ref = loop { | ||
| 11963 | if let ::core::option::Option::Some(variant) = &mut self.r#payload { | ||
| 11964 | if let CtrlMsg_::Payload::EventCustomRpcUnserialisedMsg(variant) = &mut *variant { | ||
| 11965 | break &mut *variant; | ||
| 11966 | } | ||
| 11967 | } | ||
| 11968 | self.r#payload = ::core::option::Option::Some( | ||
| 11969 | CtrlMsg_::Payload::EventCustomRpcUnserialisedMsg(::core::default::Default::default()), | ||
| 11970 | ); | ||
| 11971 | }; | ||
| 11972 | mut_ref.decode_len_delimited(decoder)?; | ||
| 11973 | } | ||
| 11974 | _ => { | ||
| 11975 | decoder.skip_wire_value(tag.wire_type())?; | ||
| 11976 | } | ||
| 11977 | } | ||
| 11978 | } | ||
| 11979 | Ok(()) | ||
| 11980 | } | ||
| 11981 | } | ||
| 11982 | impl ::micropb::MessageEncode for CtrlMsg { | ||
| 11983 | const MAX_SIZE: ::core::option::Option<usize> = 'msg: { | ||
| 11984 | let mut max_size = 0; | ||
| 11985 | if let ::core::option::Option::Some(size) = | ||
| 11986 | ::micropb::const_map!(::core::option::Option::Some(CtrlMsgType::_MAX_SIZE), |size| size | ||
| 11987 | + 1usize) | ||
| 11988 | { | ||
| 11989 | max_size += size; | ||
| 11990 | } else { | ||
| 11991 | break 'msg (::core::option::Option::<usize>::None); | ||
| 11992 | }; | ||
| 11993 | if let ::core::option::Option::Some(size) = | ||
| 11994 | ::micropb::const_map!(::core::option::Option::Some(CtrlMsgId::_MAX_SIZE), |size| size + 1usize) | ||
| 11995 | { | ||
| 11996 | max_size += size; | ||
| 11997 | } else { | ||
| 11998 | break 'msg (::core::option::Option::<usize>::None); | ||
| 11999 | }; | ||
| 12000 | if let ::core::option::Option::Some(size) = | ||
| 12001 | ::micropb::const_map!(::core::option::Option::Some(10usize), |size| size + 1usize) | ||
| 12002 | { | ||
| 12003 | max_size += size; | ||
| 12004 | } else { | ||
| 12005 | break 'msg (::core::option::Option::<usize>::None); | ||
| 12006 | }; | ||
| 12007 | if let ::core::option::Option::Some(size) = | ||
| 12008 | ::micropb::const_map!(::core::option::Option::Some(5usize), |size| size + 1usize) | ||
| 12009 | { | ||
| 12010 | max_size += size; | ||
| 12011 | } else { | ||
| 12012 | break 'msg (::core::option::Option::<usize>::None); | ||
| 12013 | }; | ||
| 12014 | if let ::core::option::Option::Some(size) = 'oneof: { | ||
| 12015 | let mut max_size = 0; | ||
| 12016 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12017 | ::micropb::const_map!( | ||
| 12018 | <CtrlMsg_Req_GetMacAddress as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12019 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12020 | ), | ||
| 12021 | |size| size + 2usize | ||
| 12022 | ) { | ||
| 12023 | if size > max_size { | ||
| 12024 | max_size = size; | ||
| 12025 | } | ||
| 12026 | } else { | ||
| 12027 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12028 | } | ||
| 12029 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12030 | ::micropb::const_map!( | ||
| 12031 | <CtrlMsg_Req_SetMacAddress as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12032 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12033 | ), | ||
| 12034 | |size| size + 2usize | ||
| 12035 | ) { | ||
| 12036 | if size > max_size { | ||
| 12037 | max_size = size; | ||
| 12038 | } | ||
| 12039 | } else { | ||
| 12040 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12041 | } | ||
| 12042 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12043 | ::micropb::const_map!(<CtrlMsg_Req_GetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12044 | ::micropb::size::sizeof_len_record(size) | ||
| 12045 | }), | ||
| 12046 | |size| size + 2usize | ||
| 12047 | ) { | ||
| 12048 | if size > max_size { | ||
| 12049 | max_size = size; | ||
| 12050 | } | ||
| 12051 | } else { | ||
| 12052 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12053 | } | ||
| 12054 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12055 | ::micropb::const_map!(<CtrlMsg_Req_SetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12056 | ::micropb::size::sizeof_len_record(size) | ||
| 12057 | }), | ||
| 12058 | |size| size + 2usize | ||
| 12059 | ) { | ||
| 12060 | if size > max_size { | ||
| 12061 | max_size = size; | ||
| 12062 | } | ||
| 12063 | } else { | ||
| 12064 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12065 | } | ||
| 12066 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12067 | ::micropb::const_map!(<CtrlMsg_Req_ScanResult as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12068 | ::micropb::size::sizeof_len_record(size) | ||
| 12069 | }), | ||
| 12070 | |size| size + 2usize | ||
| 12071 | ) { | ||
| 12072 | if size > max_size { | ||
| 12073 | max_size = size; | ||
| 12074 | } | ||
| 12075 | } else { | ||
| 12076 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12077 | } | ||
| 12078 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12079 | ::micropb::const_map!( | ||
| 12080 | <CtrlMsg_Req_GetAPConfig as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12081 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12082 | ), | ||
| 12083 | |size| size + 2usize | ||
| 12084 | ) { | ||
| 12085 | if size > max_size { | ||
| 12086 | max_size = size; | ||
| 12087 | } | ||
| 12088 | } else { | ||
| 12089 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12090 | } | ||
| 12091 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12092 | ::micropb::const_map!(<CtrlMsg_Req_ConnectAP as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12093 | ::micropb::size::sizeof_len_record(size) | ||
| 12094 | }), | ||
| 12095 | |size| size + 2usize | ||
| 12096 | ) { | ||
| 12097 | if size > max_size { | ||
| 12098 | max_size = size; | ||
| 12099 | } | ||
| 12100 | } else { | ||
| 12101 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12102 | } | ||
| 12103 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12104 | ::micropb::const_map!(<CtrlMsg_Req_GetStatus as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12105 | ::micropb::size::sizeof_len_record(size) | ||
| 12106 | }), | ||
| 12107 | |size| size + 2usize | ||
| 12108 | ) { | ||
| 12109 | if size > max_size { | ||
| 12110 | max_size = size; | ||
| 12111 | } | ||
| 12112 | } else { | ||
| 12113 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12114 | } | ||
| 12115 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12116 | ::micropb::const_map!( | ||
| 12117 | <CtrlMsg_Req_GetSoftAPConfig as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12118 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12119 | ), | ||
| 12120 | |size| size + 2usize | ||
| 12121 | ) { | ||
| 12122 | if size > max_size { | ||
| 12123 | max_size = size; | ||
| 12124 | } | ||
| 12125 | } else { | ||
| 12126 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12127 | } | ||
| 12128 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12129 | ::micropb::const_map!( | ||
| 12130 | <CtrlMsg_Req_SetSoftAPVendorSpecificIE as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12131 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12132 | ), | ||
| 12133 | |size| size + 2usize | ||
| 12134 | ) { | ||
| 12135 | if size > max_size { | ||
| 12136 | max_size = size; | ||
| 12137 | } | ||
| 12138 | } else { | ||
| 12139 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12140 | } | ||
| 12141 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12142 | ::micropb::const_map!( | ||
| 12143 | <CtrlMsg_Req_StartSoftAP as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12144 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12145 | ), | ||
| 12146 | |size| size + 2usize | ||
| 12147 | ) { | ||
| 12148 | if size > max_size { | ||
| 12149 | max_size = size; | ||
| 12150 | } | ||
| 12151 | } else { | ||
| 12152 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12153 | } | ||
| 12154 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12155 | ::micropb::const_map!( | ||
| 12156 | <CtrlMsg_Req_SoftAPConnectedSTA as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12157 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12158 | ), | ||
| 12159 | |size| size + 2usize | ||
| 12160 | ) { | ||
| 12161 | if size > max_size { | ||
| 12162 | max_size = size; | ||
| 12163 | } | ||
| 12164 | } else { | ||
| 12165 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12166 | } | ||
| 12167 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12168 | ::micropb::const_map!(<CtrlMsg_Req_GetStatus as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12169 | ::micropb::size::sizeof_len_record(size) | ||
| 12170 | }), | ||
| 12171 | |size| size + 2usize | ||
| 12172 | ) { | ||
| 12173 | if size > max_size { | ||
| 12174 | max_size = size; | ||
| 12175 | } | ||
| 12176 | } else { | ||
| 12177 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12178 | } | ||
| 12179 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12180 | ::micropb::const_map!(<CtrlMsg_Req_SetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12181 | ::micropb::size::sizeof_len_record(size) | ||
| 12182 | }), | ||
| 12183 | |size| size + 2usize | ||
| 12184 | ) { | ||
| 12185 | if size > max_size { | ||
| 12186 | max_size = size; | ||
| 12187 | } | ||
| 12188 | } else { | ||
| 12189 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12190 | } | ||
| 12191 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12192 | ::micropb::const_map!(<CtrlMsg_Req_GetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12193 | ::micropb::size::sizeof_len_record(size) | ||
| 12194 | }), | ||
| 12195 | |size| size + 2usize | ||
| 12196 | ) { | ||
| 12197 | if size > max_size { | ||
| 12198 | max_size = size; | ||
| 12199 | } | ||
| 12200 | } else { | ||
| 12201 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12202 | } | ||
| 12203 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12204 | ::micropb::const_map!(<CtrlMsg_Req_OTABegin as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12205 | ::micropb::size::sizeof_len_record(size) | ||
| 12206 | }), | ||
| 12207 | |size| size + 2usize | ||
| 12208 | ) { | ||
| 12209 | if size > max_size { | ||
| 12210 | max_size = size; | ||
| 12211 | } | ||
| 12212 | } else { | ||
| 12213 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12214 | } | ||
| 12215 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12216 | ::micropb::const_map!(<CtrlMsg_Req_OTAWrite as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12217 | ::micropb::size::sizeof_len_record(size) | ||
| 12218 | }), | ||
| 12219 | |size| size + 2usize | ||
| 12220 | ) { | ||
| 12221 | if size > max_size { | ||
| 12222 | max_size = size; | ||
| 12223 | } | ||
| 12224 | } else { | ||
| 12225 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12226 | } | ||
| 12227 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12228 | ::micropb::const_map!(<CtrlMsg_Req_OTAEnd as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12229 | ::micropb::size::sizeof_len_record(size) | ||
| 12230 | }), | ||
| 12231 | |size| size + 2usize | ||
| 12232 | ) { | ||
| 12233 | if size > max_size { | ||
| 12234 | max_size = size; | ||
| 12235 | } | ||
| 12236 | } else { | ||
| 12237 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12238 | } | ||
| 12239 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12240 | ::micropb::const_map!( | ||
| 12241 | <CtrlMsg_Req_SetWifiMaxTxPower as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12242 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12243 | ), | ||
| 12244 | |size| size + 2usize | ||
| 12245 | ) { | ||
| 12246 | if size > max_size { | ||
| 12247 | max_size = size; | ||
| 12248 | } | ||
| 12249 | } else { | ||
| 12250 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12251 | } | ||
| 12252 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12253 | ::micropb::const_map!( | ||
| 12254 | <CtrlMsg_Req_GetWifiCurrTxPower as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12255 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12256 | ), | ||
| 12257 | |size| size + 2usize | ||
| 12258 | ) { | ||
| 12259 | if size > max_size { | ||
| 12260 | max_size = size; | ||
| 12261 | } | ||
| 12262 | } else { | ||
| 12263 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12264 | } | ||
| 12265 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12266 | ::micropb::const_map!( | ||
| 12267 | <CtrlMsg_Req_ConfigHeartbeat as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12268 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12269 | ), | ||
| 12270 | |size| size + 2usize | ||
| 12271 | ) { | ||
| 12272 | if size > max_size { | ||
| 12273 | max_size = size; | ||
| 12274 | } | ||
| 12275 | } else { | ||
| 12276 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12277 | } | ||
| 12278 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12279 | ::micropb::const_map!( | ||
| 12280 | <CtrlMsg_Req_EnableDisable as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12281 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12282 | ), | ||
| 12283 | |size| size + 2usize | ||
| 12284 | ) { | ||
| 12285 | if size > max_size { | ||
| 12286 | max_size = size; | ||
| 12287 | } | ||
| 12288 | } else { | ||
| 12289 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12290 | } | ||
| 12291 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12292 | ::micropb::const_map!( | ||
| 12293 | <CtrlMsg_Req_GetFwVersion as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12294 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12295 | ), | ||
| 12296 | |size| size + 2usize | ||
| 12297 | ) { | ||
| 12298 | if size > max_size { | ||
| 12299 | max_size = size; | ||
| 12300 | } | ||
| 12301 | } else { | ||
| 12302 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12303 | } | ||
| 12304 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12305 | ::micropb::const_map!( | ||
| 12306 | <CtrlMsg_Req_SetCountryCode as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12307 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12308 | ), | ||
| 12309 | |size| size + 2usize | ||
| 12310 | ) { | ||
| 12311 | if size > max_size { | ||
| 12312 | max_size = size; | ||
| 12313 | } | ||
| 12314 | } else { | ||
| 12315 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12316 | } | ||
| 12317 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12318 | ::micropb::const_map!( | ||
| 12319 | <CtrlMsg_Req_GetCountryCode as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12320 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12321 | ), | ||
| 12322 | |size| size + 2usize | ||
| 12323 | ) { | ||
| 12324 | if size > max_size { | ||
| 12325 | max_size = size; | ||
| 12326 | } | ||
| 12327 | } else { | ||
| 12328 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12329 | } | ||
| 12330 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12331 | ::micropb::const_map!( | ||
| 12332 | <CtrlMsg_Req_SetDhcpDnsStatus as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12333 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12334 | ), | ||
| 12335 | |size| size + 2usize | ||
| 12336 | ) { | ||
| 12337 | if size > max_size { | ||
| 12338 | max_size = size; | ||
| 12339 | } | ||
| 12340 | } else { | ||
| 12341 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12342 | } | ||
| 12343 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12344 | ::micropb::const_map!( | ||
| 12345 | <CtrlMsg_Req_GetDhcpDnsStatus as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12346 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12347 | ), | ||
| 12348 | |size| size + 2usize | ||
| 12349 | ) { | ||
| 12350 | if size > max_size { | ||
| 12351 | max_size = size; | ||
| 12352 | } | ||
| 12353 | } else { | ||
| 12354 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12355 | } | ||
| 12356 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12357 | ::micropb::const_map!( | ||
| 12358 | <CtrlMsg_Req_CustomRpcUnserialisedMsg as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12359 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12360 | ), | ||
| 12361 | |size| size + 2usize | ||
| 12362 | ) { | ||
| 12363 | if size > max_size { | ||
| 12364 | max_size = size; | ||
| 12365 | } | ||
| 12366 | } else { | ||
| 12367 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12368 | } | ||
| 12369 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12370 | ::micropb::const_map!( | ||
| 12371 | <CtrlMsg_Resp_GetMacAddress as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12372 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12373 | ), | ||
| 12374 | |size| size + 2usize | ||
| 12375 | ) { | ||
| 12376 | if size > max_size { | ||
| 12377 | max_size = size; | ||
| 12378 | } | ||
| 12379 | } else { | ||
| 12380 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12381 | } | ||
| 12382 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12383 | ::micropb::const_map!( | ||
| 12384 | <CtrlMsg_Resp_SetMacAddress as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12385 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12386 | ), | ||
| 12387 | |size| size + 2usize | ||
| 12388 | ) { | ||
| 12389 | if size > max_size { | ||
| 12390 | max_size = size; | ||
| 12391 | } | ||
| 12392 | } else { | ||
| 12393 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12394 | } | ||
| 12395 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12396 | ::micropb::const_map!(<CtrlMsg_Resp_GetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12397 | ::micropb::size::sizeof_len_record(size) | ||
| 12398 | }), | ||
| 12399 | |size| size + 2usize | ||
| 12400 | ) { | ||
| 12401 | if size > max_size { | ||
| 12402 | max_size = size; | ||
| 12403 | } | ||
| 12404 | } else { | ||
| 12405 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12406 | } | ||
| 12407 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12408 | ::micropb::const_map!(<CtrlMsg_Resp_SetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12409 | ::micropb::size::sizeof_len_record(size) | ||
| 12410 | }), | ||
| 12411 | |size| size + 2usize | ||
| 12412 | ) { | ||
| 12413 | if size > max_size { | ||
| 12414 | max_size = size; | ||
| 12415 | } | ||
| 12416 | } else { | ||
| 12417 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12418 | } | ||
| 12419 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12420 | ::micropb::const_map!( | ||
| 12421 | <CtrlMsg_Resp_ScanResult as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12422 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12423 | ), | ||
| 12424 | |size| size + 2usize | ||
| 12425 | ) { | ||
| 12426 | if size > max_size { | ||
| 12427 | max_size = size; | ||
| 12428 | } | ||
| 12429 | } else { | ||
| 12430 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12431 | } | ||
| 12432 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12433 | ::micropb::const_map!( | ||
| 12434 | <CtrlMsg_Resp_GetAPConfig as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12435 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12436 | ), | ||
| 12437 | |size| size + 2usize | ||
| 12438 | ) { | ||
| 12439 | if size > max_size { | ||
| 12440 | max_size = size; | ||
| 12441 | } | ||
| 12442 | } else { | ||
| 12443 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12444 | } | ||
| 12445 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12446 | ::micropb::const_map!(<CtrlMsg_Resp_ConnectAP as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12447 | ::micropb::size::sizeof_len_record(size) | ||
| 12448 | }), | ||
| 12449 | |size| size + 2usize | ||
| 12450 | ) { | ||
| 12451 | if size > max_size { | ||
| 12452 | max_size = size; | ||
| 12453 | } | ||
| 12454 | } else { | ||
| 12455 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12456 | } | ||
| 12457 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12458 | ::micropb::const_map!(<CtrlMsg_Resp_GetStatus as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12459 | ::micropb::size::sizeof_len_record(size) | ||
| 12460 | }), | ||
| 12461 | |size| size + 2usize | ||
| 12462 | ) { | ||
| 12463 | if size > max_size { | ||
| 12464 | max_size = size; | ||
| 12465 | } | ||
| 12466 | } else { | ||
| 12467 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12468 | } | ||
| 12469 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12470 | ::micropb::const_map!( | ||
| 12471 | <CtrlMsg_Resp_GetSoftAPConfig as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12472 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12473 | ), | ||
| 12474 | |size| size + 2usize | ||
| 12475 | ) { | ||
| 12476 | if size > max_size { | ||
| 12477 | max_size = size; | ||
| 12478 | } | ||
| 12479 | } else { | ||
| 12480 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12481 | } | ||
| 12482 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12483 | ::micropb::const_map!( | ||
| 12484 | <CtrlMsg_Resp_SetSoftAPVendorSpecificIE as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12485 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12486 | ), | ||
| 12487 | |size| size + 2usize | ||
| 12488 | ) { | ||
| 12489 | if size > max_size { | ||
| 12490 | max_size = size; | ||
| 12491 | } | ||
| 12492 | } else { | ||
| 12493 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12494 | } | ||
| 12495 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12496 | ::micropb::const_map!( | ||
| 12497 | <CtrlMsg_Resp_StartSoftAP as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12498 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12499 | ), | ||
| 12500 | |size| size + 2usize | ||
| 12501 | ) { | ||
| 12502 | if size > max_size { | ||
| 12503 | max_size = size; | ||
| 12504 | } | ||
| 12505 | } else { | ||
| 12506 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12507 | } | ||
| 12508 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12509 | ::micropb::const_map!( | ||
| 12510 | <CtrlMsg_Resp_SoftAPConnectedSTA as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12511 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12512 | ), | ||
| 12513 | |size| size + 2usize | ||
| 12514 | ) { | ||
| 12515 | if size > max_size { | ||
| 12516 | max_size = size; | ||
| 12517 | } | ||
| 12518 | } else { | ||
| 12519 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12520 | } | ||
| 12521 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12522 | ::micropb::const_map!(<CtrlMsg_Resp_GetStatus as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12523 | ::micropb::size::sizeof_len_record(size) | ||
| 12524 | }), | ||
| 12525 | |size| size + 2usize | ||
| 12526 | ) { | ||
| 12527 | if size > max_size { | ||
| 12528 | max_size = size; | ||
| 12529 | } | ||
| 12530 | } else { | ||
| 12531 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12532 | } | ||
| 12533 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12534 | ::micropb::const_map!(<CtrlMsg_Resp_SetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12535 | ::micropb::size::sizeof_len_record(size) | ||
| 12536 | }), | ||
| 12537 | |size| size + 2usize | ||
| 12538 | ) { | ||
| 12539 | if size > max_size { | ||
| 12540 | max_size = size; | ||
| 12541 | } | ||
| 12542 | } else { | ||
| 12543 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12544 | } | ||
| 12545 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12546 | ::micropb::const_map!(<CtrlMsg_Resp_GetMode as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12547 | ::micropb::size::sizeof_len_record(size) | ||
| 12548 | }), | ||
| 12549 | |size| size + 2usize | ||
| 12550 | ) { | ||
| 12551 | if size > max_size { | ||
| 12552 | max_size = size; | ||
| 12553 | } | ||
| 12554 | } else { | ||
| 12555 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12556 | } | ||
| 12557 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12558 | ::micropb::const_map!(<CtrlMsg_Resp_OTABegin as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12559 | ::micropb::size::sizeof_len_record(size) | ||
| 12560 | }), | ||
| 12561 | |size| size + 2usize | ||
| 12562 | ) { | ||
| 12563 | if size > max_size { | ||
| 12564 | max_size = size; | ||
| 12565 | } | ||
| 12566 | } else { | ||
| 12567 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12568 | } | ||
| 12569 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12570 | ::micropb::const_map!(<CtrlMsg_Resp_OTAWrite as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12571 | ::micropb::size::sizeof_len_record(size) | ||
| 12572 | }), | ||
| 12573 | |size| size + 2usize | ||
| 12574 | ) { | ||
| 12575 | if size > max_size { | ||
| 12576 | max_size = size; | ||
| 12577 | } | ||
| 12578 | } else { | ||
| 12579 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12580 | } | ||
| 12581 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12582 | ::micropb::const_map!(<CtrlMsg_Resp_OTAEnd as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12583 | ::micropb::size::sizeof_len_record(size) | ||
| 12584 | }), | ||
| 12585 | |size| size + 2usize | ||
| 12586 | ) { | ||
| 12587 | if size > max_size { | ||
| 12588 | max_size = size; | ||
| 12589 | } | ||
| 12590 | } else { | ||
| 12591 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12592 | } | ||
| 12593 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12594 | ::micropb::const_map!( | ||
| 12595 | <CtrlMsg_Resp_SetWifiMaxTxPower as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12596 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12597 | ), | ||
| 12598 | |size| size + 2usize | ||
| 12599 | ) { | ||
| 12600 | if size > max_size { | ||
| 12601 | max_size = size; | ||
| 12602 | } | ||
| 12603 | } else { | ||
| 12604 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12605 | } | ||
| 12606 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12607 | ::micropb::const_map!( | ||
| 12608 | <CtrlMsg_Resp_GetWifiCurrTxPower as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12609 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12610 | ), | ||
| 12611 | |size| size + 2usize | ||
| 12612 | ) { | ||
| 12613 | if size > max_size { | ||
| 12614 | max_size = size; | ||
| 12615 | } | ||
| 12616 | } else { | ||
| 12617 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12618 | } | ||
| 12619 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12620 | ::micropb::const_map!( | ||
| 12621 | <CtrlMsg_Resp_ConfigHeartbeat as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12622 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12623 | ), | ||
| 12624 | |size| size + 2usize | ||
| 12625 | ) { | ||
| 12626 | if size > max_size { | ||
| 12627 | max_size = size; | ||
| 12628 | } | ||
| 12629 | } else { | ||
| 12630 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12631 | } | ||
| 12632 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12633 | ::micropb::const_map!( | ||
| 12634 | <CtrlMsg_Resp_EnableDisable as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12635 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12636 | ), | ||
| 12637 | |size| size + 2usize | ||
| 12638 | ) { | ||
| 12639 | if size > max_size { | ||
| 12640 | max_size = size; | ||
| 12641 | } | ||
| 12642 | } else { | ||
| 12643 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12644 | } | ||
| 12645 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12646 | ::micropb::const_map!( | ||
| 12647 | <CtrlMsg_Resp_GetFwVersion as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12648 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12649 | ), | ||
| 12650 | |size| size + 2usize | ||
| 12651 | ) { | ||
| 12652 | if size > max_size { | ||
| 12653 | max_size = size; | ||
| 12654 | } | ||
| 12655 | } else { | ||
| 12656 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12657 | } | ||
| 12658 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12659 | ::micropb::const_map!( | ||
| 12660 | <CtrlMsg_Resp_SetCountryCode as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12661 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12662 | ), | ||
| 12663 | |size| size + 2usize | ||
| 12664 | ) { | ||
| 12665 | if size > max_size { | ||
| 12666 | max_size = size; | ||
| 12667 | } | ||
| 12668 | } else { | ||
| 12669 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12670 | } | ||
| 12671 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12672 | ::micropb::const_map!( | ||
| 12673 | <CtrlMsg_Resp_GetCountryCode as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12674 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12675 | ), | ||
| 12676 | |size| size + 2usize | ||
| 12677 | ) { | ||
| 12678 | if size > max_size { | ||
| 12679 | max_size = size; | ||
| 12680 | } | ||
| 12681 | } else { | ||
| 12682 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12683 | } | ||
| 12684 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12685 | ::micropb::const_map!( | ||
| 12686 | <CtrlMsg_Resp_SetDhcpDnsStatus as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12687 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12688 | ), | ||
| 12689 | |size| size + 2usize | ||
| 12690 | ) { | ||
| 12691 | if size > max_size { | ||
| 12692 | max_size = size; | ||
| 12693 | } | ||
| 12694 | } else { | ||
| 12695 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12696 | } | ||
| 12697 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12698 | ::micropb::const_map!( | ||
| 12699 | <CtrlMsg_Resp_GetDhcpDnsStatus as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12700 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12701 | ), | ||
| 12702 | |size| size + 2usize | ||
| 12703 | ) { | ||
| 12704 | if size > max_size { | ||
| 12705 | max_size = size; | ||
| 12706 | } | ||
| 12707 | } else { | ||
| 12708 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12709 | } | ||
| 12710 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12711 | ::micropb::const_map!( | ||
| 12712 | <CtrlMsg_Resp_CustomRpcUnserialisedMsg as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12713 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12714 | ), | ||
| 12715 | |size| size + 2usize | ||
| 12716 | ) { | ||
| 12717 | if size > max_size { | ||
| 12718 | max_size = size; | ||
| 12719 | } | ||
| 12720 | } else { | ||
| 12721 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12722 | } | ||
| 12723 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12724 | ::micropb::const_map!(<CtrlMsg_Event_ESPInit as ::micropb::MessageEncode>::MAX_SIZE, |size| { | ||
| 12725 | ::micropb::size::sizeof_len_record(size) | ||
| 12726 | }), | ||
| 12727 | |size| size + 2usize | ||
| 12728 | ) { | ||
| 12729 | if size > max_size { | ||
| 12730 | max_size = size; | ||
| 12731 | } | ||
| 12732 | } else { | ||
| 12733 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12734 | } | ||
| 12735 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12736 | ::micropb::const_map!( | ||
| 12737 | <CtrlMsg_Event_Heartbeat as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12738 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12739 | ), | ||
| 12740 | |size| size + 2usize | ||
| 12741 | ) { | ||
| 12742 | if size > max_size { | ||
| 12743 | max_size = size; | ||
| 12744 | } | ||
| 12745 | } else { | ||
| 12746 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12747 | } | ||
| 12748 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12749 | ::micropb::const_map!( | ||
| 12750 | <CtrlMsg_Event_StationDisconnectFromAP as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12751 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12752 | ), | ||
| 12753 | |size| size + 2usize | ||
| 12754 | ) { | ||
| 12755 | if size > max_size { | ||
| 12756 | max_size = size; | ||
| 12757 | } | ||
| 12758 | } else { | ||
| 12759 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12760 | } | ||
| 12761 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12762 | ::micropb::const_map!( | ||
| 12763 | <CtrlMsg_Event_StationDisconnectFromESPSoftAP as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12764 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12765 | ), | ||
| 12766 | |size| size + 2usize | ||
| 12767 | ) { | ||
| 12768 | if size > max_size { | ||
| 12769 | max_size = size; | ||
| 12770 | } | ||
| 12771 | } else { | ||
| 12772 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12773 | } | ||
| 12774 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12775 | ::micropb::const_map!( | ||
| 12776 | <CtrlMsg_Event_StationConnectedToAP as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12777 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12778 | ), | ||
| 12779 | |size| size + 2usize | ||
| 12780 | ) { | ||
| 12781 | if size > max_size { | ||
| 12782 | max_size = size; | ||
| 12783 | } | ||
| 12784 | } else { | ||
| 12785 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12786 | } | ||
| 12787 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12788 | ::micropb::const_map!( | ||
| 12789 | <CtrlMsg_Event_StationConnectedToESPSoftAP as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12790 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12791 | ), | ||
| 12792 | |size| size + 2usize | ||
| 12793 | ) { | ||
| 12794 | if size > max_size { | ||
| 12795 | max_size = size; | ||
| 12796 | } | ||
| 12797 | } else { | ||
| 12798 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12799 | } | ||
| 12800 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12801 | ::micropb::const_map!( | ||
| 12802 | <CtrlMsg_Event_SetDhcpDnsStatus as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12803 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12804 | ), | ||
| 12805 | |size| size + 2usize | ||
| 12806 | ) { | ||
| 12807 | if size > max_size { | ||
| 12808 | max_size = size; | ||
| 12809 | } | ||
| 12810 | } else { | ||
| 12811 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12812 | } | ||
| 12813 | if let ::core::option::Option::Some(size) = ::micropb::const_map!( | ||
| 12814 | ::micropb::const_map!( | ||
| 12815 | <CtrlMsg_Event_CustomRpcUnserialisedMsg as ::micropb::MessageEncode>::MAX_SIZE, | ||
| 12816 | |size| ::micropb::size::sizeof_len_record(size) | ||
| 12817 | ), | ||
| 12818 | |size| size + 2usize | ||
| 12819 | ) { | ||
| 12820 | if size > max_size { | ||
| 12821 | max_size = size; | ||
| 12822 | } | ||
| 12823 | } else { | ||
| 12824 | break 'oneof (::core::option::Option::<usize>::None); | ||
| 12825 | } | ||
| 12826 | ::core::option::Option::Some(max_size) | ||
| 12827 | } { | ||
| 12828 | max_size += size; | ||
| 12829 | } else { | ||
| 12830 | break 'msg (::core::option::Option::<usize>::None); | ||
| 12831 | }; | ||
| 12832 | ::core::option::Option::Some(max_size) | ||
| 12833 | }; | ||
| 12834 | fn encode<IMPL_MICROPB_WRITE: ::micropb::PbWrite>( | ||
| 12835 | &self, | ||
| 12836 | encoder: &mut ::micropb::PbEncoder<IMPL_MICROPB_WRITE>, | ||
| 12837 | ) -> Result<(), IMPL_MICROPB_WRITE::Error> { | ||
| 12838 | use ::micropb::{FieldEncode, PbMap}; | ||
| 12839 | { | ||
| 12840 | let val_ref = &self.r#msg_type; | ||
| 12841 | if val_ref.0 != 0 { | ||
| 12842 | encoder.encode_varint32(8u32)?; | ||
| 12843 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 12844 | } | ||
| 12845 | } | ||
| 12846 | { | ||
| 12847 | let val_ref = &self.r#msg_id; | ||
| 12848 | if val_ref.0 != 0 { | ||
| 12849 | encoder.encode_varint32(16u32)?; | ||
| 12850 | encoder.encode_int32(val_ref.0 as _)?; | ||
| 12851 | } | ||
| 12852 | } | ||
| 12853 | { | ||
| 12854 | let val_ref = &self.r#uid; | ||
| 12855 | if *val_ref != 0 { | ||
| 12856 | encoder.encode_varint32(24u32)?; | ||
| 12857 | encoder.encode_int32(*val_ref as _)?; | ||
| 12858 | } | ||
| 12859 | } | ||
| 12860 | { | ||
| 12861 | let val_ref = &self.r#req_resp_type; | ||
| 12862 | if *val_ref != 0 { | ||
| 12863 | encoder.encode_varint32(32u32)?; | ||
| 12864 | encoder.encode_varint32(*val_ref as _)?; | ||
| 12865 | } | ||
| 12866 | } | ||
| 12867 | if let Some(oneof) = &self.r#payload { | ||
| 12868 | match &*oneof { | ||
| 12869 | CtrlMsg_::Payload::ReqGetMacAddress(val_ref) => { | ||
| 12870 | let val_ref = &*val_ref; | ||
| 12871 | encoder.encode_varint32(810u32)?; | ||
| 12872 | val_ref.encode_len_delimited(encoder)?; | ||
| 12873 | } | ||
| 12874 | CtrlMsg_::Payload::ReqSetMacAddress(val_ref) => { | ||
| 12875 | let val_ref = &*val_ref; | ||
| 12876 | encoder.encode_varint32(818u32)?; | ||
| 12877 | val_ref.encode_len_delimited(encoder)?; | ||
| 12878 | } | ||
| 12879 | CtrlMsg_::Payload::ReqGetWifiMode(val_ref) => { | ||
| 12880 | let val_ref = &*val_ref; | ||
| 12881 | encoder.encode_varint32(826u32)?; | ||
| 12882 | val_ref.encode_len_delimited(encoder)?; | ||
| 12883 | } | ||
| 12884 | CtrlMsg_::Payload::ReqSetWifiMode(val_ref) => { | ||
| 12885 | let val_ref = &*val_ref; | ||
| 12886 | encoder.encode_varint32(834u32)?; | ||
| 12887 | val_ref.encode_len_delimited(encoder)?; | ||
| 12888 | } | ||
| 12889 | CtrlMsg_::Payload::ReqScanApList(val_ref) => { | ||
| 12890 | let val_ref = &*val_ref; | ||
| 12891 | encoder.encode_varint32(842u32)?; | ||
| 12892 | val_ref.encode_len_delimited(encoder)?; | ||
| 12893 | } | ||
| 12894 | CtrlMsg_::Payload::ReqGetApConfig(val_ref) => { | ||
| 12895 | let val_ref = &*val_ref; | ||
| 12896 | encoder.encode_varint32(850u32)?; | ||
| 12897 | val_ref.encode_len_delimited(encoder)?; | ||
| 12898 | } | ||
| 12899 | CtrlMsg_::Payload::ReqConnectAp(val_ref) => { | ||
| 12900 | let val_ref = &*val_ref; | ||
| 12901 | encoder.encode_varint32(858u32)?; | ||
| 12902 | val_ref.encode_len_delimited(encoder)?; | ||
| 12903 | } | ||
| 12904 | CtrlMsg_::Payload::ReqDisconnectAp(val_ref) => { | ||
| 12905 | let val_ref = &*val_ref; | ||
| 12906 | encoder.encode_varint32(866u32)?; | ||
| 12907 | val_ref.encode_len_delimited(encoder)?; | ||
| 12908 | } | ||
| 12909 | CtrlMsg_::Payload::ReqGetSoftapConfig(val_ref) => { | ||
| 12910 | let val_ref = &*val_ref; | ||
| 12911 | encoder.encode_varint32(874u32)?; | ||
| 12912 | val_ref.encode_len_delimited(encoder)?; | ||
| 12913 | } | ||
| 12914 | CtrlMsg_::Payload::ReqSetSoftapVendorSpecificIe(val_ref) => { | ||
| 12915 | let val_ref = &*val_ref; | ||
| 12916 | encoder.encode_varint32(882u32)?; | ||
| 12917 | val_ref.encode_len_delimited(encoder)?; | ||
| 12918 | } | ||
| 12919 | CtrlMsg_::Payload::ReqStartSoftap(val_ref) => { | ||
| 12920 | let val_ref = &*val_ref; | ||
| 12921 | encoder.encode_varint32(890u32)?; | ||
| 12922 | val_ref.encode_len_delimited(encoder)?; | ||
| 12923 | } | ||
| 12924 | CtrlMsg_::Payload::ReqSoftapConnectedStasList(val_ref) => { | ||
| 12925 | let val_ref = &*val_ref; | ||
| 12926 | encoder.encode_varint32(898u32)?; | ||
| 12927 | val_ref.encode_len_delimited(encoder)?; | ||
| 12928 | } | ||
| 12929 | CtrlMsg_::Payload::ReqStopSoftap(val_ref) => { | ||
| 12930 | let val_ref = &*val_ref; | ||
| 12931 | encoder.encode_varint32(906u32)?; | ||
| 12932 | val_ref.encode_len_delimited(encoder)?; | ||
| 12933 | } | ||
| 12934 | CtrlMsg_::Payload::ReqSetPowerSaveMode(val_ref) => { | ||
| 12935 | let val_ref = &*val_ref; | ||
| 12936 | encoder.encode_varint32(914u32)?; | ||
| 12937 | val_ref.encode_len_delimited(encoder)?; | ||
| 12938 | } | ||
| 12939 | CtrlMsg_::Payload::ReqGetPowerSaveMode(val_ref) => { | ||
| 12940 | let val_ref = &*val_ref; | ||
| 12941 | encoder.encode_varint32(922u32)?; | ||
| 12942 | val_ref.encode_len_delimited(encoder)?; | ||
| 12943 | } | ||
| 12944 | CtrlMsg_::Payload::ReqOtaBegin(val_ref) => { | ||
| 12945 | let val_ref = &*val_ref; | ||
| 12946 | encoder.encode_varint32(930u32)?; | ||
| 12947 | val_ref.encode_len_delimited(encoder)?; | ||
| 12948 | } | ||
| 12949 | CtrlMsg_::Payload::ReqOtaWrite(val_ref) => { | ||
| 12950 | let val_ref = &*val_ref; | ||
| 12951 | encoder.encode_varint32(938u32)?; | ||
| 12952 | val_ref.encode_len_delimited(encoder)?; | ||
| 12953 | } | ||
| 12954 | CtrlMsg_::Payload::ReqOtaEnd(val_ref) => { | ||
| 12955 | let val_ref = &*val_ref; | ||
| 12956 | encoder.encode_varint32(946u32)?; | ||
| 12957 | val_ref.encode_len_delimited(encoder)?; | ||
| 12958 | } | ||
| 12959 | CtrlMsg_::Payload::ReqSetWifiMaxTxPower(val_ref) => { | ||
| 12960 | let val_ref = &*val_ref; | ||
| 12961 | encoder.encode_varint32(954u32)?; | ||
| 12962 | val_ref.encode_len_delimited(encoder)?; | ||
| 12963 | } | ||
| 12964 | CtrlMsg_::Payload::ReqGetWifiCurrTxPower(val_ref) => { | ||
| 12965 | let val_ref = &*val_ref; | ||
| 12966 | encoder.encode_varint32(962u32)?; | ||
| 12967 | val_ref.encode_len_delimited(encoder)?; | ||
| 12968 | } | ||
| 12969 | CtrlMsg_::Payload::ReqConfigHeartbeat(val_ref) => { | ||
| 12970 | let val_ref = &*val_ref; | ||
| 12971 | encoder.encode_varint32(970u32)?; | ||
| 12972 | val_ref.encode_len_delimited(encoder)?; | ||
| 12973 | } | ||
| 12974 | CtrlMsg_::Payload::ReqEnableDisableFeat(val_ref) => { | ||
| 12975 | let val_ref = &*val_ref; | ||
| 12976 | encoder.encode_varint32(978u32)?; | ||
| 12977 | val_ref.encode_len_delimited(encoder)?; | ||
| 12978 | } | ||
| 12979 | CtrlMsg_::Payload::ReqGetFwVersion(val_ref) => { | ||
| 12980 | let val_ref = &*val_ref; | ||
| 12981 | encoder.encode_varint32(986u32)?; | ||
| 12982 | val_ref.encode_len_delimited(encoder)?; | ||
| 12983 | } | ||
| 12984 | CtrlMsg_::Payload::ReqSetCountryCode(val_ref) => { | ||
| 12985 | let val_ref = &*val_ref; | ||
| 12986 | encoder.encode_varint32(994u32)?; | ||
| 12987 | val_ref.encode_len_delimited(encoder)?; | ||
| 12988 | } | ||
| 12989 | CtrlMsg_::Payload::ReqGetCountryCode(val_ref) => { | ||
| 12990 | let val_ref = &*val_ref; | ||
| 12991 | encoder.encode_varint32(1002u32)?; | ||
| 12992 | val_ref.encode_len_delimited(encoder)?; | ||
| 12993 | } | ||
| 12994 | CtrlMsg_::Payload::ReqSetDhcpDnsStatus(val_ref) => { | ||
| 12995 | let val_ref = &*val_ref; | ||
| 12996 | encoder.encode_varint32(1010u32)?; | ||
| 12997 | val_ref.encode_len_delimited(encoder)?; | ||
| 12998 | } | ||
| 12999 | CtrlMsg_::Payload::ReqGetDhcpDnsStatus(val_ref) => { | ||
| 13000 | let val_ref = &*val_ref; | ||
| 13001 | encoder.encode_varint32(1018u32)?; | ||
| 13002 | val_ref.encode_len_delimited(encoder)?; | ||
| 13003 | } | ||
| 13004 | CtrlMsg_::Payload::ReqCustomRpcUnserialisedMsg(val_ref) => { | ||
| 13005 | let val_ref = &*val_ref; | ||
| 13006 | encoder.encode_varint32(1026u32)?; | ||
| 13007 | val_ref.encode_len_delimited(encoder)?; | ||
| 13008 | } | ||
| 13009 | CtrlMsg_::Payload::RespGetMacAddress(val_ref) => { | ||
| 13010 | let val_ref = &*val_ref; | ||
| 13011 | encoder.encode_varint32(1610u32)?; | ||
| 13012 | val_ref.encode_len_delimited(encoder)?; | ||
| 13013 | } | ||
| 13014 | CtrlMsg_::Payload::RespSetMacAddress(val_ref) => { | ||
| 13015 | let val_ref = &*val_ref; | ||
| 13016 | encoder.encode_varint32(1618u32)?; | ||
| 13017 | val_ref.encode_len_delimited(encoder)?; | ||
| 13018 | } | ||
| 13019 | CtrlMsg_::Payload::RespGetWifiMode(val_ref) => { | ||
| 13020 | let val_ref = &*val_ref; | ||
| 13021 | encoder.encode_varint32(1626u32)?; | ||
| 13022 | val_ref.encode_len_delimited(encoder)?; | ||
| 13023 | } | ||
| 13024 | CtrlMsg_::Payload::RespSetWifiMode(val_ref) => { | ||
| 13025 | let val_ref = &*val_ref; | ||
| 13026 | encoder.encode_varint32(1634u32)?; | ||
| 13027 | val_ref.encode_len_delimited(encoder)?; | ||
| 13028 | } | ||
| 13029 | CtrlMsg_::Payload::RespScanApList(val_ref) => { | ||
| 13030 | let val_ref = &*val_ref; | ||
| 13031 | encoder.encode_varint32(1642u32)?; | ||
| 13032 | val_ref.encode_len_delimited(encoder)?; | ||
| 13033 | } | ||
| 13034 | CtrlMsg_::Payload::RespGetApConfig(val_ref) => { | ||
| 13035 | let val_ref = &*val_ref; | ||
| 13036 | encoder.encode_varint32(1650u32)?; | ||
| 13037 | val_ref.encode_len_delimited(encoder)?; | ||
| 13038 | } | ||
| 13039 | CtrlMsg_::Payload::RespConnectAp(val_ref) => { | ||
| 13040 | let val_ref = &*val_ref; | ||
| 13041 | encoder.encode_varint32(1658u32)?; | ||
| 13042 | val_ref.encode_len_delimited(encoder)?; | ||
| 13043 | } | ||
| 13044 | CtrlMsg_::Payload::RespDisconnectAp(val_ref) => { | ||
| 13045 | let val_ref = &*val_ref; | ||
| 13046 | encoder.encode_varint32(1666u32)?; | ||
| 13047 | val_ref.encode_len_delimited(encoder)?; | ||
| 13048 | } | ||
| 13049 | CtrlMsg_::Payload::RespGetSoftapConfig(val_ref) => { | ||
| 13050 | let val_ref = &*val_ref; | ||
| 13051 | encoder.encode_varint32(1674u32)?; | ||
| 13052 | val_ref.encode_len_delimited(encoder)?; | ||
| 13053 | } | ||
| 13054 | CtrlMsg_::Payload::RespSetSoftapVendorSpecificIe(val_ref) => { | ||
| 13055 | let val_ref = &*val_ref; | ||
| 13056 | encoder.encode_varint32(1682u32)?; | ||
| 13057 | val_ref.encode_len_delimited(encoder)?; | ||
| 13058 | } | ||
| 13059 | CtrlMsg_::Payload::RespStartSoftap(val_ref) => { | ||
| 13060 | let val_ref = &*val_ref; | ||
| 13061 | encoder.encode_varint32(1690u32)?; | ||
| 13062 | val_ref.encode_len_delimited(encoder)?; | ||
| 13063 | } | ||
| 13064 | CtrlMsg_::Payload::RespSoftapConnectedStasList(val_ref) => { | ||
| 13065 | let val_ref = &*val_ref; | ||
| 13066 | encoder.encode_varint32(1698u32)?; | ||
| 13067 | val_ref.encode_len_delimited(encoder)?; | ||
| 13068 | } | ||
| 13069 | CtrlMsg_::Payload::RespStopSoftap(val_ref) => { | ||
| 13070 | let val_ref = &*val_ref; | ||
| 13071 | encoder.encode_varint32(1706u32)?; | ||
| 13072 | val_ref.encode_len_delimited(encoder)?; | ||
| 13073 | } | ||
| 13074 | CtrlMsg_::Payload::RespSetPowerSaveMode(val_ref) => { | ||
| 13075 | let val_ref = &*val_ref; | ||
| 13076 | encoder.encode_varint32(1714u32)?; | ||
| 13077 | val_ref.encode_len_delimited(encoder)?; | ||
| 13078 | } | ||
| 13079 | CtrlMsg_::Payload::RespGetPowerSaveMode(val_ref) => { | ||
| 13080 | let val_ref = &*val_ref; | ||
| 13081 | encoder.encode_varint32(1722u32)?; | ||
| 13082 | val_ref.encode_len_delimited(encoder)?; | ||
| 13083 | } | ||
| 13084 | CtrlMsg_::Payload::RespOtaBegin(val_ref) => { | ||
| 13085 | let val_ref = &*val_ref; | ||
| 13086 | encoder.encode_varint32(1730u32)?; | ||
| 13087 | val_ref.encode_len_delimited(encoder)?; | ||
| 13088 | } | ||
| 13089 | CtrlMsg_::Payload::RespOtaWrite(val_ref) => { | ||
| 13090 | let val_ref = &*val_ref; | ||
| 13091 | encoder.encode_varint32(1738u32)?; | ||
| 13092 | val_ref.encode_len_delimited(encoder)?; | ||
| 13093 | } | ||
| 13094 | CtrlMsg_::Payload::RespOtaEnd(val_ref) => { | ||
| 13095 | let val_ref = &*val_ref; | ||
| 13096 | encoder.encode_varint32(1746u32)?; | ||
| 13097 | val_ref.encode_len_delimited(encoder)?; | ||
| 13098 | } | ||
| 13099 | CtrlMsg_::Payload::RespSetWifiMaxTxPower(val_ref) => { | ||
| 13100 | let val_ref = &*val_ref; | ||
| 13101 | encoder.encode_varint32(1754u32)?; | ||
| 13102 | val_ref.encode_len_delimited(encoder)?; | ||
| 13103 | } | ||
| 13104 | CtrlMsg_::Payload::RespGetWifiCurrTxPower(val_ref) => { | ||
| 13105 | let val_ref = &*val_ref; | ||
| 13106 | encoder.encode_varint32(1762u32)?; | ||
| 13107 | val_ref.encode_len_delimited(encoder)?; | ||
| 13108 | } | ||
| 13109 | CtrlMsg_::Payload::RespConfigHeartbeat(val_ref) => { | ||
| 13110 | let val_ref = &*val_ref; | ||
| 13111 | encoder.encode_varint32(1770u32)?; | ||
| 13112 | val_ref.encode_len_delimited(encoder)?; | ||
| 13113 | } | ||
| 13114 | CtrlMsg_::Payload::RespEnableDisableFeat(val_ref) => { | ||
| 13115 | let val_ref = &*val_ref; | ||
| 13116 | encoder.encode_varint32(1778u32)?; | ||
| 13117 | val_ref.encode_len_delimited(encoder)?; | ||
| 13118 | } | ||
| 13119 | CtrlMsg_::Payload::RespGetFwVersion(val_ref) => { | ||
| 13120 | let val_ref = &*val_ref; | ||
| 13121 | encoder.encode_varint32(1786u32)?; | ||
| 13122 | val_ref.encode_len_delimited(encoder)?; | ||
| 13123 | } | ||
| 13124 | CtrlMsg_::Payload::RespSetCountryCode(val_ref) => { | ||
| 13125 | let val_ref = &*val_ref; | ||
| 13126 | encoder.encode_varint32(1794u32)?; | ||
| 13127 | val_ref.encode_len_delimited(encoder)?; | ||
| 13128 | } | ||
| 13129 | CtrlMsg_::Payload::RespGetCountryCode(val_ref) => { | ||
| 13130 | let val_ref = &*val_ref; | ||
| 13131 | encoder.encode_varint32(1802u32)?; | ||
| 13132 | val_ref.encode_len_delimited(encoder)?; | ||
| 13133 | } | ||
| 13134 | CtrlMsg_::Payload::RespSetDhcpDnsStatus(val_ref) => { | ||
| 13135 | let val_ref = &*val_ref; | ||
| 13136 | encoder.encode_varint32(1810u32)?; | ||
| 13137 | val_ref.encode_len_delimited(encoder)?; | ||
| 13138 | } | ||
| 13139 | CtrlMsg_::Payload::RespGetDhcpDnsStatus(val_ref) => { | ||
| 13140 | let val_ref = &*val_ref; | ||
| 13141 | encoder.encode_varint32(1818u32)?; | ||
| 13142 | val_ref.encode_len_delimited(encoder)?; | ||
| 13143 | } | ||
| 13144 | CtrlMsg_::Payload::RespCustomRpcUnserialisedMsg(val_ref) => { | ||
| 13145 | let val_ref = &*val_ref; | ||
| 13146 | encoder.encode_varint32(1826u32)?; | ||
| 13147 | val_ref.encode_len_delimited(encoder)?; | ||
| 13148 | } | ||
| 13149 | CtrlMsg_::Payload::EventEspInit(val_ref) => { | ||
| 13150 | let val_ref = &*val_ref; | ||
| 13151 | encoder.encode_varint32(2410u32)?; | ||
| 13152 | val_ref.encode_len_delimited(encoder)?; | ||
| 13153 | } | ||
| 13154 | CtrlMsg_::Payload::EventHeartbeat(val_ref) => { | ||
| 13155 | let val_ref = &*val_ref; | ||
| 13156 | encoder.encode_varint32(2418u32)?; | ||
| 13157 | val_ref.encode_len_delimited(encoder)?; | ||
| 13158 | } | ||
| 13159 | CtrlMsg_::Payload::EventStationDisconnectFromAp(val_ref) => { | ||
| 13160 | let val_ref = &*val_ref; | ||
| 13161 | encoder.encode_varint32(2426u32)?; | ||
| 13162 | val_ref.encode_len_delimited(encoder)?; | ||
| 13163 | } | ||
| 13164 | CtrlMsg_::Payload::EventStationDisconnectFromEspSoftAp(val_ref) => { | ||
| 13165 | let val_ref = &*val_ref; | ||
| 13166 | encoder.encode_varint32(2434u32)?; | ||
| 13167 | val_ref.encode_len_delimited(encoder)?; | ||
| 13168 | } | ||
| 13169 | CtrlMsg_::Payload::EventStationConnectedToAp(val_ref) => { | ||
| 13170 | let val_ref = &*val_ref; | ||
| 13171 | encoder.encode_varint32(2442u32)?; | ||
| 13172 | val_ref.encode_len_delimited(encoder)?; | ||
| 13173 | } | ||
| 13174 | CtrlMsg_::Payload::EventStationConnectedToEspSoftAp(val_ref) => { | ||
| 13175 | let val_ref = &*val_ref; | ||
| 13176 | encoder.encode_varint32(2450u32)?; | ||
| 13177 | val_ref.encode_len_delimited(encoder)?; | ||
| 13178 | } | ||
| 13179 | CtrlMsg_::Payload::EventSetDhcpDnsStatus(val_ref) => { | ||
| 13180 | let val_ref = &*val_ref; | ||
| 13181 | encoder.encode_varint32(2458u32)?; | ||
| 13182 | val_ref.encode_len_delimited(encoder)?; | ||
| 13183 | } | ||
| 13184 | CtrlMsg_::Payload::EventCustomRpcUnserialisedMsg(val_ref) => { | ||
| 13185 | let val_ref = &*val_ref; | ||
| 13186 | encoder.encode_varint32(2466u32)?; | ||
| 13187 | val_ref.encode_len_delimited(encoder)?; | ||
| 13188 | } | ||
| 13189 | } | ||
| 13190 | } | ||
| 13191 | Ok(()) | ||
| 13192 | } | ||
| 13193 | fn compute_size(&self) -> usize { | ||
| 13194 | use ::micropb::{FieldEncode, PbMap}; | ||
| 13195 | let mut size = 0; | ||
| 13196 | { | ||
| 13197 | let val_ref = &self.r#msg_type; | ||
| 13198 | if val_ref.0 != 0 { | ||
| 13199 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 13200 | } | ||
| 13201 | } | ||
| 13202 | { | ||
| 13203 | let val_ref = &self.r#msg_id; | ||
| 13204 | if val_ref.0 != 0 { | ||
| 13205 | size += 1usize + ::micropb::size::sizeof_int32(val_ref.0 as _); | ||
| 13206 | } | ||
| 13207 | } | ||
| 13208 | { | ||
| 13209 | let val_ref = &self.r#uid; | ||
| 13210 | if *val_ref != 0 { | ||
| 13211 | size += 1usize + ::micropb::size::sizeof_int32(*val_ref as _); | ||
| 13212 | } | ||
| 13213 | } | ||
| 13214 | { | ||
| 13215 | let val_ref = &self.r#req_resp_type; | ||
| 13216 | if *val_ref != 0 { | ||
| 13217 | size += 1usize + ::micropb::size::sizeof_varint32(*val_ref as _); | ||
| 13218 | } | ||
| 13219 | } | ||
| 13220 | if let Some(oneof) = &self.r#payload { | ||
| 13221 | match &*oneof { | ||
| 13222 | CtrlMsg_::Payload::ReqGetMacAddress(val_ref) => { | ||
| 13223 | let val_ref = &*val_ref; | ||
| 13224 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13225 | } | ||
| 13226 | CtrlMsg_::Payload::ReqSetMacAddress(val_ref) => { | ||
| 13227 | let val_ref = &*val_ref; | ||
| 13228 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13229 | } | ||
| 13230 | CtrlMsg_::Payload::ReqGetWifiMode(val_ref) => { | ||
| 13231 | let val_ref = &*val_ref; | ||
| 13232 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13233 | } | ||
| 13234 | CtrlMsg_::Payload::ReqSetWifiMode(val_ref) => { | ||
| 13235 | let val_ref = &*val_ref; | ||
| 13236 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13237 | } | ||
| 13238 | CtrlMsg_::Payload::ReqScanApList(val_ref) => { | ||
| 13239 | let val_ref = &*val_ref; | ||
| 13240 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13241 | } | ||
| 13242 | CtrlMsg_::Payload::ReqGetApConfig(val_ref) => { | ||
| 13243 | let val_ref = &*val_ref; | ||
| 13244 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13245 | } | ||
| 13246 | CtrlMsg_::Payload::ReqConnectAp(val_ref) => { | ||
| 13247 | let val_ref = &*val_ref; | ||
| 13248 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13249 | } | ||
| 13250 | CtrlMsg_::Payload::ReqDisconnectAp(val_ref) => { | ||
| 13251 | let val_ref = &*val_ref; | ||
| 13252 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13253 | } | ||
| 13254 | CtrlMsg_::Payload::ReqGetSoftapConfig(val_ref) => { | ||
| 13255 | let val_ref = &*val_ref; | ||
| 13256 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13257 | } | ||
| 13258 | CtrlMsg_::Payload::ReqSetSoftapVendorSpecificIe(val_ref) => { | ||
| 13259 | let val_ref = &*val_ref; | ||
| 13260 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13261 | } | ||
| 13262 | CtrlMsg_::Payload::ReqStartSoftap(val_ref) => { | ||
| 13263 | let val_ref = &*val_ref; | ||
| 13264 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13265 | } | ||
| 13266 | CtrlMsg_::Payload::ReqSoftapConnectedStasList(val_ref) => { | ||
| 13267 | let val_ref = &*val_ref; | ||
| 13268 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13269 | } | ||
| 13270 | CtrlMsg_::Payload::ReqStopSoftap(val_ref) => { | ||
| 13271 | let val_ref = &*val_ref; | ||
| 13272 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13273 | } | ||
| 13274 | CtrlMsg_::Payload::ReqSetPowerSaveMode(val_ref) => { | ||
| 13275 | let val_ref = &*val_ref; | ||
| 13276 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13277 | } | ||
| 13278 | CtrlMsg_::Payload::ReqGetPowerSaveMode(val_ref) => { | ||
| 13279 | let val_ref = &*val_ref; | ||
| 13280 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13281 | } | ||
| 13282 | CtrlMsg_::Payload::ReqOtaBegin(val_ref) => { | ||
| 13283 | let val_ref = &*val_ref; | ||
| 13284 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13285 | } | ||
| 13286 | CtrlMsg_::Payload::ReqOtaWrite(val_ref) => { | ||
| 13287 | let val_ref = &*val_ref; | ||
| 13288 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13289 | } | ||
| 13290 | CtrlMsg_::Payload::ReqOtaEnd(val_ref) => { | ||
| 13291 | let val_ref = &*val_ref; | ||
| 13292 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13293 | } | ||
| 13294 | CtrlMsg_::Payload::ReqSetWifiMaxTxPower(val_ref) => { | ||
| 13295 | let val_ref = &*val_ref; | ||
| 13296 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13297 | } | ||
| 13298 | CtrlMsg_::Payload::ReqGetWifiCurrTxPower(val_ref) => { | ||
| 13299 | let val_ref = &*val_ref; | ||
| 13300 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13301 | } | ||
| 13302 | CtrlMsg_::Payload::ReqConfigHeartbeat(val_ref) => { | ||
| 13303 | let val_ref = &*val_ref; | ||
| 13304 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13305 | } | ||
| 13306 | CtrlMsg_::Payload::ReqEnableDisableFeat(val_ref) => { | ||
| 13307 | let val_ref = &*val_ref; | ||
| 13308 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13309 | } | ||
| 13310 | CtrlMsg_::Payload::ReqGetFwVersion(val_ref) => { | ||
| 13311 | let val_ref = &*val_ref; | ||
| 13312 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13313 | } | ||
| 13314 | CtrlMsg_::Payload::ReqSetCountryCode(val_ref) => { | ||
| 13315 | let val_ref = &*val_ref; | ||
| 13316 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13317 | } | ||
| 13318 | CtrlMsg_::Payload::ReqGetCountryCode(val_ref) => { | ||
| 13319 | let val_ref = &*val_ref; | ||
| 13320 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13321 | } | ||
| 13322 | CtrlMsg_::Payload::ReqSetDhcpDnsStatus(val_ref) => { | ||
| 13323 | let val_ref = &*val_ref; | ||
| 13324 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13325 | } | ||
| 13326 | CtrlMsg_::Payload::ReqGetDhcpDnsStatus(val_ref) => { | ||
| 13327 | let val_ref = &*val_ref; | ||
| 13328 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13329 | } | ||
| 13330 | CtrlMsg_::Payload::ReqCustomRpcUnserialisedMsg(val_ref) => { | ||
| 13331 | let val_ref = &*val_ref; | ||
| 13332 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13333 | } | ||
| 13334 | CtrlMsg_::Payload::RespGetMacAddress(val_ref) => { | ||
| 13335 | let val_ref = &*val_ref; | ||
| 13336 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13337 | } | ||
| 13338 | CtrlMsg_::Payload::RespSetMacAddress(val_ref) => { | ||
| 13339 | let val_ref = &*val_ref; | ||
| 13340 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13341 | } | ||
| 13342 | CtrlMsg_::Payload::RespGetWifiMode(val_ref) => { | ||
| 13343 | let val_ref = &*val_ref; | ||
| 13344 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13345 | } | ||
| 13346 | CtrlMsg_::Payload::RespSetWifiMode(val_ref) => { | ||
| 13347 | let val_ref = &*val_ref; | ||
| 13348 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13349 | } | ||
| 13350 | CtrlMsg_::Payload::RespScanApList(val_ref) => { | ||
| 13351 | let val_ref = &*val_ref; | ||
| 13352 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13353 | } | ||
| 13354 | CtrlMsg_::Payload::RespGetApConfig(val_ref) => { | ||
| 13355 | let val_ref = &*val_ref; | ||
| 13356 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13357 | } | ||
| 13358 | CtrlMsg_::Payload::RespConnectAp(val_ref) => { | ||
| 13359 | let val_ref = &*val_ref; | ||
| 13360 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13361 | } | ||
| 13362 | CtrlMsg_::Payload::RespDisconnectAp(val_ref) => { | ||
| 13363 | let val_ref = &*val_ref; | ||
| 13364 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13365 | } | ||
| 13366 | CtrlMsg_::Payload::RespGetSoftapConfig(val_ref) => { | ||
| 13367 | let val_ref = &*val_ref; | ||
| 13368 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13369 | } | ||
| 13370 | CtrlMsg_::Payload::RespSetSoftapVendorSpecificIe(val_ref) => { | ||
| 13371 | let val_ref = &*val_ref; | ||
| 13372 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13373 | } | ||
| 13374 | CtrlMsg_::Payload::RespStartSoftap(val_ref) => { | ||
| 13375 | let val_ref = &*val_ref; | ||
| 13376 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13377 | } | ||
| 13378 | CtrlMsg_::Payload::RespSoftapConnectedStasList(val_ref) => { | ||
| 13379 | let val_ref = &*val_ref; | ||
| 13380 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13381 | } | ||
| 13382 | CtrlMsg_::Payload::RespStopSoftap(val_ref) => { | ||
| 13383 | let val_ref = &*val_ref; | ||
| 13384 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13385 | } | ||
| 13386 | CtrlMsg_::Payload::RespSetPowerSaveMode(val_ref) => { | ||
| 13387 | let val_ref = &*val_ref; | ||
| 13388 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13389 | } | ||
| 13390 | CtrlMsg_::Payload::RespGetPowerSaveMode(val_ref) => { | ||
| 13391 | let val_ref = &*val_ref; | ||
| 13392 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13393 | } | ||
| 13394 | CtrlMsg_::Payload::RespOtaBegin(val_ref) => { | ||
| 13395 | let val_ref = &*val_ref; | ||
| 13396 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13397 | } | ||
| 13398 | CtrlMsg_::Payload::RespOtaWrite(val_ref) => { | ||
| 13399 | let val_ref = &*val_ref; | ||
| 13400 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13401 | } | ||
| 13402 | CtrlMsg_::Payload::RespOtaEnd(val_ref) => { | ||
| 13403 | let val_ref = &*val_ref; | ||
| 13404 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13405 | } | ||
| 13406 | CtrlMsg_::Payload::RespSetWifiMaxTxPower(val_ref) => { | ||
| 13407 | let val_ref = &*val_ref; | ||
| 13408 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13409 | } | ||
| 13410 | CtrlMsg_::Payload::RespGetWifiCurrTxPower(val_ref) => { | ||
| 13411 | let val_ref = &*val_ref; | ||
| 13412 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13413 | } | ||
| 13414 | CtrlMsg_::Payload::RespConfigHeartbeat(val_ref) => { | ||
| 13415 | let val_ref = &*val_ref; | ||
| 13416 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13417 | } | ||
| 13418 | CtrlMsg_::Payload::RespEnableDisableFeat(val_ref) => { | ||
| 13419 | let val_ref = &*val_ref; | ||
| 13420 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13421 | } | ||
| 13422 | CtrlMsg_::Payload::RespGetFwVersion(val_ref) => { | ||
| 13423 | let val_ref = &*val_ref; | ||
| 13424 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13425 | } | ||
| 13426 | CtrlMsg_::Payload::RespSetCountryCode(val_ref) => { | ||
| 13427 | let val_ref = &*val_ref; | ||
| 13428 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13429 | } | ||
| 13430 | CtrlMsg_::Payload::RespGetCountryCode(val_ref) => { | ||
| 13431 | let val_ref = &*val_ref; | ||
| 13432 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13433 | } | ||
| 13434 | CtrlMsg_::Payload::RespSetDhcpDnsStatus(val_ref) => { | ||
| 13435 | let val_ref = &*val_ref; | ||
| 13436 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13437 | } | ||
| 13438 | CtrlMsg_::Payload::RespGetDhcpDnsStatus(val_ref) => { | ||
| 13439 | let val_ref = &*val_ref; | ||
| 13440 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13441 | } | ||
| 13442 | CtrlMsg_::Payload::RespCustomRpcUnserialisedMsg(val_ref) => { | ||
| 13443 | let val_ref = &*val_ref; | ||
| 13444 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13445 | } | ||
| 13446 | CtrlMsg_::Payload::EventEspInit(val_ref) => { | ||
| 13447 | let val_ref = &*val_ref; | ||
| 13448 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13449 | } | ||
| 13450 | CtrlMsg_::Payload::EventHeartbeat(val_ref) => { | ||
| 13451 | let val_ref = &*val_ref; | ||
| 13452 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13453 | } | ||
| 13454 | CtrlMsg_::Payload::EventStationDisconnectFromAp(val_ref) => { | ||
| 13455 | let val_ref = &*val_ref; | ||
| 13456 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13457 | } | ||
| 13458 | CtrlMsg_::Payload::EventStationDisconnectFromEspSoftAp(val_ref) => { | ||
| 13459 | let val_ref = &*val_ref; | ||
| 13460 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13461 | } | ||
| 13462 | CtrlMsg_::Payload::EventStationConnectedToAp(val_ref) => { | ||
| 13463 | let val_ref = &*val_ref; | ||
| 13464 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13465 | } | ||
| 13466 | CtrlMsg_::Payload::EventStationConnectedToEspSoftAp(val_ref) => { | ||
| 13467 | let val_ref = &*val_ref; | ||
| 13468 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13469 | } | ||
| 13470 | CtrlMsg_::Payload::EventSetDhcpDnsStatus(val_ref) => { | ||
| 13471 | let val_ref = &*val_ref; | ||
| 13472 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13473 | } | ||
| 13474 | CtrlMsg_::Payload::EventCustomRpcUnserialisedMsg(val_ref) => { | ||
| 13475 | let val_ref = &*val_ref; | ||
| 13476 | size += 2usize + ::micropb::size::sizeof_len_record(val_ref.compute_size()); | ||
| 13477 | } | ||
| 13478 | } | ||
| 13479 | } | ||
| 13480 | size | ||
| 13481 | } | ||
| 13482 | } | ||
| 13483 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13484 | #[repr(transparent)] | ||
| 13485 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13486 | pub struct Ctrl_VendorIEType(pub i32); | ||
| 13487 | impl Ctrl_VendorIEType { | ||
| 13488 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13489 | pub const Beacon: Self = Self(0); | ||
| 13490 | pub const ProbeReq: Self = Self(1); | ||
| 13491 | pub const ProbeResp: Self = Self(2); | ||
| 13492 | pub const AssocReq: Self = Self(3); | ||
| 13493 | pub const AssocResp: Self = Self(4); | ||
| 13494 | } | ||
| 13495 | impl core::default::Default for Ctrl_VendorIEType { | ||
| 13496 | fn default() -> Self { | ||
| 13497 | Self(0) | ||
| 13498 | } | ||
| 13499 | } | ||
| 13500 | impl core::convert::From<i32> for Ctrl_VendorIEType { | ||
| 13501 | fn from(val: i32) -> Self { | ||
| 13502 | Self(val) | ||
| 13503 | } | ||
| 13504 | } | ||
| 13505 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13506 | #[repr(transparent)] | ||
| 13507 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13508 | pub struct Ctrl_VendorIEID(pub i32); | ||
| 13509 | impl Ctrl_VendorIEID { | ||
| 13510 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13511 | pub const Id0: Self = Self(0); | ||
| 13512 | pub const Id1: Self = Self(1); | ||
| 13513 | } | ||
| 13514 | impl core::default::Default for Ctrl_VendorIEID { | ||
| 13515 | fn default() -> Self { | ||
| 13516 | Self(0) | ||
| 13517 | } | ||
| 13518 | } | ||
| 13519 | impl core::convert::From<i32> for Ctrl_VendorIEID { | ||
| 13520 | fn from(val: i32) -> Self { | ||
| 13521 | Self(val) | ||
| 13522 | } | ||
| 13523 | } | ||
| 13524 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13525 | #[repr(transparent)] | ||
| 13526 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13527 | pub struct Ctrl_WifiMode(pub i32); | ||
| 13528 | impl Ctrl_WifiMode { | ||
| 13529 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13530 | pub const None: Self = Self(0); | ||
| 13531 | pub const Sta: Self = Self(1); | ||
| 13532 | pub const Ap: Self = Self(2); | ||
| 13533 | pub const Apsta: Self = Self(3); | ||
| 13534 | } | ||
| 13535 | impl core::default::Default for Ctrl_WifiMode { | ||
| 13536 | fn default() -> Self { | ||
| 13537 | Self(0) | ||
| 13538 | } | ||
| 13539 | } | ||
| 13540 | impl core::convert::From<i32> for Ctrl_WifiMode { | ||
| 13541 | fn from(val: i32) -> Self { | ||
| 13542 | Self(val) | ||
| 13543 | } | ||
| 13544 | } | ||
| 13545 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13546 | #[repr(transparent)] | ||
| 13547 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13548 | pub struct Ctrl_WifiBw(pub i32); | ||
| 13549 | impl Ctrl_WifiBw { | ||
| 13550 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13551 | pub const BwInvalid: Self = Self(0); | ||
| 13552 | pub const Ht20: Self = Self(1); | ||
| 13553 | pub const Ht40: Self = Self(2); | ||
| 13554 | } | ||
| 13555 | impl core::default::Default for Ctrl_WifiBw { | ||
| 13556 | fn default() -> Self { | ||
| 13557 | Self(0) | ||
| 13558 | } | ||
| 13559 | } | ||
| 13560 | impl core::convert::From<i32> for Ctrl_WifiBw { | ||
| 13561 | fn from(val: i32) -> Self { | ||
| 13562 | Self(val) | ||
| 13563 | } | ||
| 13564 | } | ||
| 13565 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13566 | #[repr(transparent)] | ||
| 13567 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13568 | pub struct Ctrl_WifiPowerSave(pub i32); | ||
| 13569 | impl Ctrl_WifiPowerSave { | ||
| 13570 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13571 | pub const NoPs: Self = Self(0); | ||
| 13572 | pub const MinModem: Self = Self(1); | ||
| 13573 | pub const MaxModem: Self = Self(2); | ||
| 13574 | pub const PsInvalid: Self = Self(3); | ||
| 13575 | } | ||
| 13576 | impl core::default::Default for Ctrl_WifiPowerSave { | ||
| 13577 | fn default() -> Self { | ||
| 13578 | Self(0) | ||
| 13579 | } | ||
| 13580 | } | ||
| 13581 | impl core::convert::From<i32> for Ctrl_WifiPowerSave { | ||
| 13582 | fn from(val: i32) -> Self { | ||
| 13583 | Self(val) | ||
| 13584 | } | ||
| 13585 | } | ||
| 13586 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13587 | #[repr(transparent)] | ||
| 13588 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13589 | pub struct Ctrl_WifiSecProt(pub i32); | ||
| 13590 | impl Ctrl_WifiSecProt { | ||
| 13591 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13592 | pub const Open: Self = Self(0); | ||
| 13593 | pub const Wep: Self = Self(1); | ||
| 13594 | pub const WpaPsk: Self = Self(2); | ||
| 13595 | pub const Wpa2Psk: Self = Self(3); | ||
| 13596 | pub const WpaWpa2Psk: Self = Self(4); | ||
| 13597 | pub const Wpa2Enterprise: Self = Self(5); | ||
| 13598 | pub const Wpa3Psk: Self = Self(6); | ||
| 13599 | pub const Wpa2Wpa3Psk: Self = Self(7); | ||
| 13600 | } | ||
| 13601 | impl core::default::Default for Ctrl_WifiSecProt { | ||
| 13602 | fn default() -> Self { | ||
| 13603 | Self(0) | ||
| 13604 | } | ||
| 13605 | } | ||
| 13606 | impl core::convert::From<i32> for Ctrl_WifiSecProt { | ||
| 13607 | fn from(val: i32) -> Self { | ||
| 13608 | Self(val) | ||
| 13609 | } | ||
| 13610 | } | ||
| 13611 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13612 | #[repr(transparent)] | ||
| 13613 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13614 | pub struct Ctrl_Status(pub i32); | ||
| 13615 | impl Ctrl_Status { | ||
| 13616 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13617 | pub const Connected: Self = Self(0); | ||
| 13618 | pub const NotConnected: Self = Self(1); | ||
| 13619 | pub const NoApFound: Self = Self(2); | ||
| 13620 | pub const ConnectionFail: Self = Self(3); | ||
| 13621 | pub const InvalidArgument: Self = Self(4); | ||
| 13622 | pub const OutOfRange: Self = Self(5); | ||
| 13623 | } | ||
| 13624 | impl core::default::Default for Ctrl_Status { | ||
| 13625 | fn default() -> Self { | ||
| 13626 | Self(0) | ||
| 13627 | } | ||
| 13628 | } | ||
| 13629 | impl core::convert::From<i32> for Ctrl_Status { | ||
| 13630 | fn from(val: i32) -> Self { | ||
| 13631 | Self(val) | ||
| 13632 | } | ||
| 13633 | } | ||
| 13634 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13635 | #[repr(transparent)] | ||
| 13636 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13637 | pub struct CtrlMsgType(pub i32); | ||
| 13638 | impl CtrlMsgType { | ||
| 13639 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13640 | pub const MsgTypeInvalid: Self = Self(0); | ||
| 13641 | pub const Req: Self = Self(1); | ||
| 13642 | pub const Resp: Self = Self(2); | ||
| 13643 | pub const Event: Self = Self(3); | ||
| 13644 | pub const MsgTypeMax: Self = Self(4); | ||
| 13645 | } | ||
| 13646 | impl core::default::Default for CtrlMsgType { | ||
| 13647 | fn default() -> Self { | ||
| 13648 | Self(0) | ||
| 13649 | } | ||
| 13650 | } | ||
| 13651 | impl core::convert::From<i32> for CtrlMsgType { | ||
| 13652 | fn from(val: i32) -> Self { | ||
| 13653 | Self(val) | ||
| 13654 | } | ||
| 13655 | } | ||
| 13656 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13657 | #[repr(transparent)] | ||
| 13658 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13659 | pub struct CtrlMsgId(pub i32); | ||
| 13660 | impl CtrlMsgId { | ||
| 13661 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13662 | pub const MsgIdInvalid: Self = Self(0); | ||
| 13663 | pub const ReqBase: Self = Self(100); | ||
| 13664 | pub const ReqGetMacAddress: Self = Self(101); | ||
| 13665 | pub const ReqSetMacAddress: Self = Self(102); | ||
| 13666 | pub const ReqGetWifiMode: Self = Self(103); | ||
| 13667 | pub const ReqSetWifiMode: Self = Self(104); | ||
| 13668 | pub const ReqGetApScanList: Self = Self(105); | ||
| 13669 | pub const ReqGetApConfig: Self = Self(106); | ||
| 13670 | pub const ReqConnectAp: Self = Self(107); | ||
| 13671 | pub const ReqDisconnectAp: Self = Self(108); | ||
| 13672 | pub const ReqGetSoftApConfig: Self = Self(109); | ||
| 13673 | pub const ReqSetSoftApVendorSpecificIe: Self = Self(110); | ||
| 13674 | pub const ReqStartSoftAp: Self = Self(111); | ||
| 13675 | pub const ReqGetSoftApConnectedStaList: Self = Self(112); | ||
| 13676 | pub const ReqStopSoftAp: Self = Self(113); | ||
| 13677 | pub const ReqSetPowerSaveMode: Self = Self(114); | ||
| 13678 | pub const ReqGetPowerSaveMode: Self = Self(115); | ||
| 13679 | pub const ReqOtaBegin: Self = Self(116); | ||
| 13680 | pub const ReqOtaWrite: Self = Self(117); | ||
| 13681 | pub const ReqOtaEnd: Self = Self(118); | ||
| 13682 | pub const ReqSetWifiMaxTxPower: Self = Self(119); | ||
| 13683 | pub const ReqGetWifiCurrTxPower: Self = Self(120); | ||
| 13684 | pub const ReqConfigHeartbeat: Self = Self(121); | ||
| 13685 | pub const ReqEnableDisable: Self = Self(122); | ||
| 13686 | pub const ReqGetFwVersion: Self = Self(123); | ||
| 13687 | pub const ReqSetCountryCode: Self = Self(124); | ||
| 13688 | pub const ReqGetCountryCode: Self = Self(125); | ||
| 13689 | pub const ReqSetDhcpDnsStatus: Self = Self(126); | ||
| 13690 | pub const ReqGetDhcpDnsStatus: Self = Self(127); | ||
| 13691 | pub const ReqCustomRpcUnserialisedMsg: Self = Self(128); | ||
| 13692 | pub const ReqMax: Self = Self(129); | ||
| 13693 | pub const RespBase: Self = Self(200); | ||
| 13694 | pub const RespGetMacAddress: Self = Self(201); | ||
| 13695 | pub const RespSetMacAddress: Self = Self(202); | ||
| 13696 | pub const RespGetWifiMode: Self = Self(203); | ||
| 13697 | pub const RespSetWifiMode: Self = Self(204); | ||
| 13698 | pub const RespGetApScanList: Self = Self(205); | ||
| 13699 | pub const RespGetApConfig: Self = Self(206); | ||
| 13700 | pub const RespConnectAp: Self = Self(207); | ||
| 13701 | pub const RespDisconnectAp: Self = Self(208); | ||
| 13702 | pub const RespGetSoftApConfig: Self = Self(209); | ||
| 13703 | pub const RespSetSoftApVendorSpecificIe: Self = Self(210); | ||
| 13704 | pub const RespStartSoftAp: Self = Self(211); | ||
| 13705 | pub const RespGetSoftApConnectedStaList: Self = Self(212); | ||
| 13706 | pub const RespStopSoftAp: Self = Self(213); | ||
| 13707 | pub const RespSetPowerSaveMode: Self = Self(214); | ||
| 13708 | pub const RespGetPowerSaveMode: Self = Self(215); | ||
| 13709 | pub const RespOtaBegin: Self = Self(216); | ||
| 13710 | pub const RespOtaWrite: Self = Self(217); | ||
| 13711 | pub const RespOtaEnd: Self = Self(218); | ||
| 13712 | pub const RespSetWifiMaxTxPower: Self = Self(219); | ||
| 13713 | pub const RespGetWifiCurrTxPower: Self = Self(220); | ||
| 13714 | pub const RespConfigHeartbeat: Self = Self(221); | ||
| 13715 | pub const RespEnableDisable: Self = Self(222); | ||
| 13716 | pub const RespGetFwVersion: Self = Self(223); | ||
| 13717 | pub const RespSetCountryCode: Self = Self(224); | ||
| 13718 | pub const RespGetCountryCode: Self = Self(225); | ||
| 13719 | pub const RespSetDhcpDnsStatus: Self = Self(226); | ||
| 13720 | pub const RespGetDhcpDnsStatus: Self = Self(227); | ||
| 13721 | pub const RespCustomRpcUnserialisedMsg: Self = Self(228); | ||
| 13722 | pub const RespMax: Self = Self(229); | ||
| 13723 | pub const EventBase: Self = Self(300); | ||
| 13724 | pub const EventEspInit: Self = Self(301); | ||
| 13725 | pub const EventHeartbeat: Self = Self(302); | ||
| 13726 | pub const EventStationDisconnectFromAp: Self = Self(303); | ||
| 13727 | pub const EventStationDisconnectFromEspSoftAp: Self = Self(304); | ||
| 13728 | pub const EventStationConnectedToAp: Self = Self(305); | ||
| 13729 | pub const EventStationConnectedToEspSoftAp: Self = Self(306); | ||
| 13730 | pub const EventSetDhcpDnsStatus: Self = Self(307); | ||
| 13731 | pub const EventCustomRpcUnserialisedMsg: Self = Self(308); | ||
| 13732 | pub const EventMax: Self = Self(309); | ||
| 13733 | } | ||
| 13734 | impl core::default::Default for CtrlMsgId { | ||
| 13735 | fn default() -> Self { | ||
| 13736 | Self(0) | ||
| 13737 | } | ||
| 13738 | } | ||
| 13739 | impl core::convert::From<i32> for CtrlMsgId { | ||
| 13740 | fn from(val: i32) -> Self { | ||
| 13741 | Self(val) | ||
| 13742 | } | ||
| 13743 | } | ||
| 13744 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 13745 | #[repr(transparent)] | ||
| 13746 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13747 | pub struct HostedFeature(pub i32); | ||
| 13748 | impl HostedFeature { | ||
| 13749 | pub const _MAX_SIZE: usize = 10usize; | ||
| 13750 | pub const HostedInvalidFeature: Self = Self(0); | ||
| 13751 | pub const HostedWifi: Self = Self(1); | ||
| 13752 | pub const HostedBluetooth: Self = Self(2); | ||
| 13753 | pub const HostedIsNetworkSplitOn: Self = Self(3); | ||
| 13754 | } | ||
| 13755 | impl core::default::Default for HostedFeature { | ||
| 13756 | fn default() -> Self { | ||
| 13757 | Self(0) | ||
| 13758 | } | ||
| 13759 | } | ||
| 13760 | impl core::convert::From<i32> for HostedFeature { | ||
| 13761 | fn from(val: i32) -> Self { | ||
| 13762 | Self(val) | ||
| 13763 | } | ||
| 656 | } | 13764 | } |
diff --git a/embassy-net-nrf91/CHANGELOG.md b/embassy-net-nrf91/CHANGELOG.md index 52cbf5ef3..11974ac04 100644 --- a/embassy-net-nrf91/CHANGELOG.md +++ b/embassy-net-nrf91/CHANGELOG.md | |||
| @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - changed: updated to nrf-pac with nrf52/nrf53/nrf91 register layout more similar to nrf54 | ||
| 12 | |||
| 11 | ## 0.1.1 - 2025-08-14 | 13 | ## 0.1.1 - 2025-08-14 |
| 12 | 14 | ||
| 13 | - First release with changelog. | 15 | - First release with changelog. |
diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml index ecb10246a..75b7aeeb2 100644 --- a/embassy-net-nrf91/Cargo.toml +++ b/embassy-net-nrf91/Cargo.toml | |||
| @@ -18,7 +18,7 @@ log = ["dep:log"] | |||
| 18 | defmt = { version = "1.0.1", optional = true } | 18 | defmt = { version = "1.0.1", optional = true } |
| 19 | log = { version = "0.4.14", optional = true } | 19 | log = { version = "0.4.14", optional = true } |
| 20 | 20 | ||
| 21 | nrf-pac = "0.1.0" | 21 | nrf-pac = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "58198c23bce72edc10b4e1656d1b54441fc74e7c" } |
| 22 | cortex-m = "0.7.7" | 22 | cortex-m = "0.7.7" |
| 23 | 23 | ||
| 24 | embassy-time = { version = "0.5.0", path = "../embassy-time" } | 24 | embassy-time = { version = "0.5.0", path = "../embassy-time" } |
diff --git a/embassy-net/CHANGELOG.md b/embassy-net/CHANGELOG.md index 1ae4f2a68..40f720d0d 100644 --- a/embassy-net/CHANGELOG.md +++ b/embassy-net/CHANGELOG.md | |||
| @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - tcp: Add `set_nagle_enabled()` to control TcpSocket nagle algorithm. | ||
| 12 | |||
| 11 | ## 0.7.1 - 2025-08-26 | 13 | ## 0.7.1 - 2025-08-26 |
| 12 | 14 | ||
| 13 | No unreleased changes yet... Quick, go send a PR! | 15 | No unreleased changes yet... Quick, go send a PR! |
diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 6792c5526..b4db7b88c 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs | |||
| @@ -373,6 +373,20 @@ impl<'a> TcpSocket<'a> { | |||
| 373 | self.io.with_mut(|s, _| s.set_hop_limit(hop_limit)) | 373 | self.io.with_mut(|s, _| s.set_hop_limit(hop_limit)) |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | /// Enable or disable Nagles's algorithm. | ||
| 377 | /// | ||
| 378 | /// By default, Nagle's algorithm is enabled. | ||
| 379 | /// When enabled, Nagle’s Algorithm prevents sending segments smaller | ||
| 380 | /// than MSS if there is data in flight (sent but not acknowledged). | ||
| 381 | /// In other words, it ensures at most only one segment smaller than | ||
| 382 | /// MSS is in flight at a time. | ||
| 383 | /// It ensures better network utilization by preventing sending many | ||
| 384 | /// very small packets, at the cost of increased latency in some | ||
| 385 | /// situations, particularly when the remote peer has ACK delay enabled. | ||
| 386 | pub fn set_nagle_enabled(&mut self, enabled: bool) { | ||
| 387 | self.io.with_mut(|s, _| s.set_nagle_enabled(enabled)) | ||
| 388 | } | ||
| 389 | |||
| 376 | /// Get the local endpoint of the socket. | 390 | /// Get the local endpoint of the socket. |
| 377 | /// | 391 | /// |
| 378 | /// Returns `None` if the socket is not bound (listening) or not connected. | 392 | /// Returns `None` if the socket is not bound (listening) or not connected. |
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md index 0244dedab..72ecb116a 100644 --- a/embassy-nrf/CHANGELOG.md +++ b/embassy-nrf/CHANGELOG.md | |||
| @@ -7,7 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 7 | 7 | ||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | |||
| 11 | - added: Add basic RTC support for nRF54L | ||
| 10 | - changed: apply trimming values from FICR.TRIMCNF on nrf53/54l | 12 | - changed: apply trimming values from FICR.TRIMCNF on nrf53/54l |
| 13 | - changed: do not panic on BufferedUarte overrun | ||
| 14 | - added: allow direct access to the input pin of `gpiote::InputChannel` | ||
| 15 | - bugfix: use DETECTMODE_SEC in GPIOTE in secure mode | ||
| 16 | - added: allow configuring the idle state of GPIO pins connected to PWM channels | ||
| 17 | - changed: allow configuring the PWM peripheral in the constructor of `SimplePwm` | ||
| 18 | - changed: support setting duty cycles with inverted polarity in `SimplePwm` | ||
| 19 | - added: support setting the duty cycles of all channels at once in `SimplePwm` | ||
| 20 | - changed: updated to nrf-pac with nrf52/nrf53/nrf91 register layout more similar to nrf54 | ||
| 21 | - added: support for nrf54l peripherals: uart, gpiote, twim, twis, spim, spis, dppi, pwm, saadc, cracen | ||
| 22 | - added: support for changing nrf54l clock speed | ||
| 23 | - bugfix: Do not write to UICR from non-secure code on nrf53 | ||
| 24 | - bugfix: Add delay to uart init anomaly fix | ||
| 25 | - changed: `BufferedUarte::read_ready` now uses the same definition for 'empty' so following read calls will not block when true is returned | ||
| 11 | 26 | ||
| 12 | ## 0.8.0 - 2025-09-30 | 27 | ## 0.8.0 - 2025-09-30 |
| 13 | 28 | ||
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 17ffaf439..08f4b280b 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -80,6 +80,8 @@ unstable-pac = [] | |||
| 80 | gpiote = [] | 80 | gpiote = [] |
| 81 | 81 | ||
| 82 | ## Use RTC1 as the time driver for `embassy-time`, with a tick rate of 32.768khz | 82 | ## Use RTC1 as the time driver for `embassy-time`, with a tick rate of 32.768khz |
| 83 | ## | ||
| 84 | ## Note: For nRF54L, it's actually RTC30 | ||
| 83 | time-driver-rtc1 = ["_time-driver"] | 85 | time-driver-rtc1 = ["_time-driver"] |
| 84 | 86 | ||
| 85 | ## Enable embassy-net 802.15.4 driver | 87 | ## Enable embassy-net 802.15.4 driver |
| @@ -102,17 +104,17 @@ qspi-multiwrite-flash = [] | |||
| 102 | 104 | ||
| 103 | #! ### Chip selection features | 105 | #! ### Chip selection features |
| 104 | ## nRF51 | 106 | ## nRF51 |
| 105 | nrf51 = ["nrf-pac/nrf51", "_nrf51"] | 107 | nrf51 = ["nrf-pac/nrf51", "_nrf51", "_spi-v1"] |
| 106 | ## nRF52805 | 108 | ## nRF52805 |
| 107 | nrf52805 = ["nrf-pac/nrf52805", "_nrf52"] | 109 | nrf52805 = ["nrf-pac/nrf52805", "_nrf52", "_spi-v1"] |
| 108 | ## nRF52810 | 110 | ## nRF52810 |
| 109 | nrf52810 = ["nrf-pac/nrf52810", "_nrf52"] | 111 | nrf52810 = ["nrf-pac/nrf52810", "_nrf52", "_spi-v1"] |
| 110 | ## nRF52811 | 112 | ## nRF52811 |
| 111 | nrf52811 = ["nrf-pac/nrf52811", "_nrf52"] | 113 | nrf52811 = ["nrf-pac/nrf52811", "_nrf52", "_spi-v1"] |
| 112 | ## nRF52820 | 114 | ## nRF52820 |
| 113 | nrf52820 = ["nrf-pac/nrf52820", "_nrf52"] | 115 | nrf52820 = ["nrf-pac/nrf52820", "_nrf52", "_spi-v1"] |
| 114 | ## nRF52832 | 116 | ## nRF52832 |
| 115 | nrf52832 = ["nrf-pac/nrf52832", "_nrf52", "_nrf52832_anomaly_109"] | 117 | nrf52832 = ["nrf-pac/nrf52832", "_nrf52", "_nrf52832_anomaly_109", "_spi-v1"] |
| 116 | ## nRF52833 | 118 | ## nRF52833 |
| 117 | nrf52833 = ["nrf-pac/nrf52833", "_nrf52", "_gpio-p1"] | 119 | nrf52833 = ["nrf-pac/nrf52833", "_nrf52", "_gpio-p1"] |
| 118 | ## nRF52840 | 120 | ## nRF52840 |
| @@ -152,10 +154,10 @@ _nrf54l15-app = ["_nrf54l15", "nrf-pac/nrf54l15-app"] | |||
| 152 | _nrf54l15 = ["_nrf54l", "_gpio-p1", "_gpio-p2"] | 154 | _nrf54l15 = ["_nrf54l", "_gpio-p1", "_gpio-p2"] |
| 153 | _nrf54l = ["_dppi"] | 155 | _nrf54l = ["_dppi"] |
| 154 | 156 | ||
| 155 | _nrf9160 = ["nrf-pac/nrf9160", "_dppi"] | 157 | _nrf9160 = ["nrf-pac/nrf9160", "_dppi", "_spi-v1"] |
| 156 | _nrf9120 = ["nrf-pac/nrf9120", "_dppi"] | 158 | _nrf9120 = ["nrf-pac/nrf9120", "_dppi", "_spi-v1"] |
| 157 | _nrf52 = ["_ppi"] | 159 | _nrf52 = ["_ppi"] |
| 158 | _nrf51 = ["_ppi"] | 160 | _nrf51 = ["_ppi", "_spi-v1"] |
| 159 | _nrf91 = [] | 161 | _nrf91 = [] |
| 160 | 162 | ||
| 161 | _time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-32_768", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] | 163 | _time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-32_768", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] |
| @@ -170,6 +172,7 @@ _ppi = [] | |||
| 170 | _dppi = [] | 172 | _dppi = [] |
| 171 | _gpio-p1 = [] | 173 | _gpio-p1 = [] |
| 172 | _gpio-p2 = [] | 174 | _gpio-p2 = [] |
| 175 | _spi-v1 = [] | ||
| 173 | 176 | ||
| 174 | # Errata workarounds | 177 | # Errata workarounds |
| 175 | _nrf52832_anomaly_109 = [] | 178 | _nrf52832_anomaly_109 = [] |
| @@ -197,7 +200,7 @@ embedded-io-async = { version = "0.6.1" } | |||
| 197 | rand-core-06 = { package = "rand_core", version = "0.6" } | 200 | rand-core-06 = { package = "rand_core", version = "0.6" } |
| 198 | rand-core-09 = { package = "rand_core", version = "0.9" } | 201 | rand-core-09 = { package = "rand_core", version = "0.9" } |
| 199 | 202 | ||
| 200 | nrf-pac = "0.1.0" | 203 | nrf-pac = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "58198c23bce72edc10b4e1656d1b54441fc74e7c" } |
| 201 | 204 | ||
| 202 | defmt = { version = "1.0.1", optional = true } | 205 | defmt = { version = "1.0.1", optional = true } |
| 203 | bitflags = "2.4.2" | 206 | bitflags = "2.4.2" |
diff --git a/embassy-nrf/src/buffered_uarte/mod.rs b/embassy-nrf/src/buffered_uarte/mod.rs new file mode 100644 index 000000000..75d84baac --- /dev/null +++ b/embassy-nrf/src/buffered_uarte/mod.rs | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | //! Async buffered UART driver. | ||
| 2 | //! | ||
| 3 | //! Note that discarding a future from a read or write operation may lead to losing | ||
| 4 | //! data. For example, when using `futures_util::future::select` and completion occurs | ||
| 5 | //! on the "other" future, you should capture the incomplete future and continue to use | ||
| 6 | //! it for the next read or write. This pattern is a consideration for all IO, and not | ||
| 7 | //! just serial communications. | ||
| 8 | //! | ||
| 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. | ||
| 10 | #[cfg_attr(not(feature = "_nrf54l"), path = "v1.rs")] | ||
| 11 | #[cfg_attr(feature = "_nrf54l", path = "v2.rs")] | ||
| 12 | mod _version; | ||
| 13 | |||
| 14 | pub use _version::*; | ||
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte/v1.rs index 4c946497d..ec360f7d0 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte/v1.rs | |||
| @@ -40,6 +40,7 @@ pub(crate) struct State { | |||
| 40 | rx_started_count: AtomicU8, | 40 | rx_started_count: AtomicU8, |
| 41 | rx_ended_count: AtomicU8, | 41 | rx_ended_count: AtomicU8, |
| 42 | rx_ppi_ch: AtomicU8, | 42 | rx_ppi_ch: AtomicU8, |
| 43 | rx_overrun: AtomicBool, | ||
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | /// UART error. | 46 | /// UART error. |
| @@ -47,7 +48,8 @@ pub(crate) struct State { | |||
| 47 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 48 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 48 | #[non_exhaustive] | 49 | #[non_exhaustive] |
| 49 | pub enum Error { | 50 | pub enum Error { |
| 50 | // No errors for now | 51 | /// Buffer Overrun |
| 52 | Overrun, | ||
| 51 | } | 53 | } |
| 52 | 54 | ||
| 53 | impl State { | 55 | impl State { |
| @@ -61,6 +63,7 @@ impl State { | |||
| 61 | rx_started_count: AtomicU8::new(0), | 63 | rx_started_count: AtomicU8::new(0), |
| 62 | rx_ended_count: AtomicU8::new(0), | 64 | rx_ended_count: AtomicU8::new(0), |
| 63 | rx_ppi_ch: AtomicU8::new(0), | 65 | rx_ppi_ch: AtomicU8::new(0), |
| 66 | rx_overrun: AtomicBool::new(false), | ||
| 64 | } | 67 | } |
| 65 | } | 68 | } |
| 66 | } | 69 | } |
| @@ -87,7 +90,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 87 | r.errorsrc().write_value(errs); | 90 | r.errorsrc().write_value(errs); |
| 88 | 91 | ||
| 89 | if errs.overrun() { | 92 | if errs.overrun() { |
| 90 | panic!("BufferedUarte overrun"); | 93 | s.rx_overrun.store(true, Ordering::Release); |
| 94 | ss.rx_waker.wake(); | ||
| 91 | } | 95 | } |
| 92 | } | 96 | } |
| 93 | 97 | ||
| @@ -98,25 +102,25 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 98 | ss.rx_waker.wake(); | 102 | ss.rx_waker.wake(); |
| 99 | } | 103 | } |
| 100 | 104 | ||
| 101 | if r.events_endrx().read() != 0 { | 105 | if r.events_dma().rx().end().read() != 0 { |
| 102 | //trace!(" irq_rx: endrx"); | 106 | //trace!(" irq_rx: endrx"); |
| 103 | r.events_endrx().write_value(0); | 107 | r.events_dma().rx().end().write_value(0); |
| 104 | 108 | ||
| 105 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 109 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 106 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 110 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| 107 | } | 111 | } |
| 108 | 112 | ||
| 109 | if r.events_rxstarted().read() != 0 || !s.rx_started.load(Ordering::Relaxed) { | 113 | if r.events_dma().rx().ready().read() != 0 || !s.rx_started.load(Ordering::Relaxed) { |
| 110 | //trace!(" irq_rx: rxstarted"); | 114 | //trace!(" irq_rx: rxstarted"); |
| 111 | let (ptr, len) = rx.push_buf(); | 115 | let (ptr, len) = rx.push_buf(); |
| 112 | if len >= half_len { | 116 | if len >= half_len { |
| 113 | r.events_rxstarted().write_value(0); | 117 | r.events_dma().rx().ready().write_value(0); |
| 114 | 118 | ||
| 115 | //trace!(" irq_rx: starting second {:?}", half_len); | 119 | //trace!(" irq_rx: starting second {:?}", half_len); |
| 116 | 120 | ||
| 117 | // Set up the DMA read | 121 | // Set up the DMA read |
| 118 | r.rxd().ptr().write_value(ptr as u32); | 122 | r.dma().rx().ptr().write_value(ptr as u32); |
| 119 | r.rxd().maxcnt().write(|w| w.set_maxcnt(half_len as _)); | 123 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(half_len as _)); |
| 120 | 124 | ||
| 121 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); | 125 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); |
| 122 | 126 | ||
| @@ -129,9 +133,9 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 129 | // and manually start. | 133 | // and manually start. |
| 130 | 134 | ||
| 131 | // check again in case endrx has happened between the last check and now. | 135 | // check again in case endrx has happened between the last check and now. |
| 132 | if r.events_endrx().read() != 0 { | 136 | if r.events_dma().rx().end().read() != 0 { |
| 133 | //trace!(" irq_rx: endrx"); | 137 | //trace!(" irq_rx: endrx"); |
| 134 | r.events_endrx().write_value(0); | 138 | r.events_dma().rx().end().write_value(0); |
| 135 | 139 | ||
| 136 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 140 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 137 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 141 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| @@ -157,7 +161,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 157 | ppi::regs().chenclr().write(|w| w.set_ch(chn as _, true)); | 161 | ppi::regs().chenclr().write(|w| w.set_ch(chn as _, true)); |
| 158 | 162 | ||
| 159 | // manually start | 163 | // manually start |
| 160 | r.tasks_startrx().write_value(1); | 164 | r.tasks_dma().rx().start().write_value(1); |
| 161 | } | 165 | } |
| 162 | 166 | ||
| 163 | rx.push_done(half_len); | 167 | rx.push_done(half_len); |
| @@ -166,7 +170,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 166 | s.rx_started.store(true, Ordering::Relaxed); | 170 | s.rx_started.store(true, Ordering::Relaxed); |
| 167 | } else { | 171 | } else { |
| 168 | //trace!(" irq_rx: rxstarted no buf"); | 172 | //trace!(" irq_rx: rxstarted no buf"); |
| 169 | r.intenclr().write(|w| w.set_rxstarted(true)); | 173 | r.intenclr().write(|w| w.set_dmarxready(true)); |
| 170 | } | 174 | } |
| 171 | } | 175 | } |
| 172 | } | 176 | } |
| @@ -175,8 +179,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 175 | 179 | ||
| 176 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { | 180 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { |
| 177 | // TX end | 181 | // TX end |
| 178 | if r.events_endtx().read() != 0 { | 182 | if r.events_dma().tx().end().read() != 0 { |
| 179 | r.events_endtx().write_value(0); | 183 | r.events_dma().tx().end().write_value(0); |
| 180 | 184 | ||
| 181 | let n = s.tx_count.load(Ordering::Relaxed); | 185 | let n = s.tx_count.load(Ordering::Relaxed); |
| 182 | //trace!(" irq_tx: endtx {:?}", n); | 186 | //trace!(" irq_tx: endtx {:?}", n); |
| @@ -194,11 +198,11 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 194 | s.tx_count.store(len, Ordering::Relaxed); | 198 | s.tx_count.store(len, Ordering::Relaxed); |
| 195 | 199 | ||
| 196 | // Set up the DMA write | 200 | // Set up the DMA write |
| 197 | r.txd().ptr().write_value(ptr as u32); | 201 | r.dma().tx().ptr().write_value(ptr as u32); |
| 198 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 202 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 199 | 203 | ||
| 200 | // Start UARTE Transmit transaction | 204 | // Start UARTE Transmit transaction |
| 201 | r.tasks_starttx().write_value(1); | 205 | r.tasks_dma().tx().start().write_value(1); |
| 202 | } | 206 | } |
| 203 | } | 207 | } |
| 204 | } | 208 | } |
| @@ -452,11 +456,11 @@ impl<'d> BufferedUarteTx<'d> { | |||
| 452 | let len = tx_buffer.len(); | 456 | let len = tx_buffer.len(); |
| 453 | unsafe { buffered_state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | 457 | unsafe { buffered_state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; |
| 454 | 458 | ||
| 455 | r.events_txstarted().write_value(0); | 459 | r.events_dma().tx().ready().write_value(0); |
| 456 | 460 | ||
| 457 | // Enable interrupts | 461 | // Enable interrupts |
| 458 | r.intenset().write(|w| { | 462 | r.intenset().write(|w| { |
| 459 | w.set_endtx(true); | 463 | w.set_dmatxend(true); |
| 460 | }); | 464 | }); |
| 461 | 465 | ||
| 462 | Self { | 466 | Self { |
| @@ -547,11 +551,11 @@ impl<'a> Drop for BufferedUarteTx<'a> { | |||
| 547 | 551 | ||
| 548 | r.intenclr().write(|w| { | 552 | r.intenclr().write(|w| { |
| 549 | w.set_txdrdy(true); | 553 | w.set_txdrdy(true); |
| 550 | w.set_txstarted(true); | 554 | w.set_dmatxready(true); |
| 551 | w.set_txstopped(true); | 555 | w.set_txstopped(true); |
| 552 | }); | 556 | }); |
| 553 | r.events_txstopped().write_value(0); | 557 | r.events_txstopped().write_value(0); |
| 554 | r.tasks_stoptx().write_value(1); | 558 | r.tasks_dma().tx().stop().write_value(1); |
| 555 | while r.events_txstopped().read() == 0 {} | 559 | while r.events_txstopped().read() == 0 {} |
| 556 | 560 | ||
| 557 | let s = self.buffered_state; | 561 | let s = self.buffered_state; |
| @@ -689,6 +693,7 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 689 | buffered_state.rx_started_count.store(0, Ordering::Relaxed); | 693 | buffered_state.rx_started_count.store(0, Ordering::Relaxed); |
| 690 | buffered_state.rx_ended_count.store(0, Ordering::Relaxed); | 694 | buffered_state.rx_ended_count.store(0, Ordering::Relaxed); |
| 691 | buffered_state.rx_started.store(false, Ordering::Relaxed); | 695 | buffered_state.rx_started.store(false, Ordering::Relaxed); |
| 696 | buffered_state.rx_overrun.store(false, Ordering::Relaxed); | ||
| 692 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); | 697 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); |
| 693 | unsafe { buffered_state.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; | 698 | unsafe { buffered_state.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; |
| 694 | 699 | ||
| @@ -696,16 +701,16 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 696 | let errors = r.errorsrc().read(); | 701 | let errors = r.errorsrc().read(); |
| 697 | r.errorsrc().write_value(errors); | 702 | r.errorsrc().write_value(errors); |
| 698 | 703 | ||
| 699 | r.events_rxstarted().write_value(0); | 704 | r.events_dma().rx().ready().write_value(0); |
| 700 | r.events_error().write_value(0); | 705 | r.events_error().write_value(0); |
| 701 | r.events_endrx().write_value(0); | 706 | r.events_dma().rx().end().write_value(0); |
| 702 | 707 | ||
| 703 | // Enable interrupts | 708 | // Enable interrupts |
| 704 | r.intenset().write(|w| { | 709 | r.intenset().write(|w| { |
| 705 | w.set_endtx(true); | 710 | w.set_dmatxend(true); |
| 706 | w.set_rxstarted(true); | 711 | w.set_dmarxready(true); |
| 707 | w.set_error(true); | 712 | w.set_error(true); |
| 708 | w.set_endrx(true); | 713 | w.set_dmarxend(true); |
| 709 | }); | 714 | }); |
| 710 | 715 | ||
| 711 | // Configure byte counter. | 716 | // Configure byte counter. |
| @@ -724,8 +729,8 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 724 | let mut ppi_group = PpiGroup::new(ppi_group); | 729 | let mut ppi_group = PpiGroup::new(ppi_group); |
| 725 | let mut ppi_ch2 = Ppi::new_one_to_two( | 730 | let mut ppi_ch2 = Ppi::new_one_to_two( |
| 726 | ppi_ch2, | 731 | ppi_ch2, |
| 727 | Event::from_reg(r.events_endrx()), | 732 | Event::from_reg(r.events_dma().rx().end()), |
| 728 | Task::from_reg(r.tasks_startrx()), | 733 | Task::from_reg(r.tasks_dma().rx().start()), |
| 729 | ppi_group.task_disable_all(), | 734 | ppi_group.task_disable_all(), |
| 730 | ); | 735 | ); |
| 731 | ppi_ch2.disable(); | 736 | ppi_ch2.disable(); |
| @@ -743,6 +748,30 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 743 | } | 748 | } |
| 744 | } | 749 | } |
| 745 | 750 | ||
| 751 | fn get_rxdrdy_counter(&self) -> usize { | ||
| 752 | let s = self.buffered_state; | ||
| 753 | let timer = &self.timer; | ||
| 754 | |||
| 755 | // Read the RXDRDY counter. | ||
| 756 | timer.cc(0).capture(); | ||
| 757 | let mut rxdrdy = timer.cc(0).read() as usize; | ||
| 758 | //trace!(" rxdrdy count = {:?}", rxdrdy); | ||
| 759 | |||
| 760 | // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. | ||
| 761 | // However, it's unclear if that's instant, or there's a small window where you can | ||
| 762 | // still read `len()*2`. | ||
| 763 | // This could happen if in one clock cycle the counter is updated, and in the next the | ||
| 764 | // clear takes effect. The docs are very sparse, they just say "Task delays: After TIMER | ||
| 765 | // is started, the CLEAR, COUNT, and STOP tasks are guaranteed to take effect within one | ||
| 766 | // clock cycle of the PCLK16M." :shrug: | ||
| 767 | // So, we wrap the counter ourselves, just in case. | ||
| 768 | if rxdrdy > s.rx_buf.len() * 2 { | ||
| 769 | rxdrdy = 0; | ||
| 770 | } | ||
| 771 | |||
| 772 | rxdrdy | ||
| 773 | } | ||
| 774 | |||
| 746 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | 775 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. |
| 747 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 776 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
| 748 | let data = self.fill_buf().await?; | 777 | let data = self.fill_buf().await?; |
| @@ -757,28 +786,17 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 757 | let r = self.r; | 786 | let r = self.r; |
| 758 | let s = self.buffered_state; | 787 | let s = self.buffered_state; |
| 759 | let ss = self.state; | 788 | let ss = self.state; |
| 760 | let timer = &self.timer; | 789 | |
| 761 | poll_fn(move |cx| { | 790 | poll_fn(move |cx| { |
| 762 | compiler_fence(Ordering::SeqCst); | 791 | compiler_fence(Ordering::SeqCst); |
| 763 | //trace!("poll_read"); | 792 | //trace!("poll_read"); |
| 764 | 793 | ||
| 765 | // Read the RXDRDY counter. | 794 | if s.rx_overrun.swap(false, Ordering::Acquire) { |
| 766 | timer.cc(0).capture(); | 795 | return Poll::Ready(Err(Error::Overrun)); |
| 767 | let mut end = timer.cc(0).read() as usize; | ||
| 768 | //trace!(" rxdrdy count = {:?}", end); | ||
| 769 | |||
| 770 | // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. | ||
| 771 | // However, it's unclear if that's instant, or there's a small window where you can | ||
| 772 | // still read `len()*2`. | ||
| 773 | // This could happen if in one clock cycle the counter is updated, and in the next the | ||
| 774 | // clear takes effect. The docs are very sparse, they just say "Task delays: After TIMER | ||
| 775 | // is started, the CLEAR, COUNT, and STOP tasks are guaranteed to take effect within one | ||
| 776 | // clock cycle of the PCLK16M." :shrug: | ||
| 777 | // So, we wrap the counter ourselves, just in case. | ||
| 778 | if end > s.rx_buf.len() * 2 { | ||
| 779 | end = 0 | ||
| 780 | } | 796 | } |
| 781 | 797 | ||
| 798 | let mut end = self.get_rxdrdy_counter(); | ||
| 799 | |||
| 782 | // This logic mirrors `atomic_ring_buffer::Reader::pop_buf()` | 800 | // This logic mirrors `atomic_ring_buffer::Reader::pop_buf()` |
| 783 | let mut start = s.rx_buf.start.load(Ordering::Relaxed); | 801 | let mut start = s.rx_buf.start.load(Ordering::Relaxed); |
| 784 | let len = s.rx_buf.len(); | 802 | let len = s.rx_buf.len(); |
| @@ -814,13 +832,20 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 814 | let s = self.buffered_state; | 832 | let s = self.buffered_state; |
| 815 | let mut rx = unsafe { s.rx_buf.reader() }; | 833 | let mut rx = unsafe { s.rx_buf.reader() }; |
| 816 | rx.pop_done(amt); | 834 | rx.pop_done(amt); |
| 817 | self.r.intenset().write(|w| w.set_rxstarted(true)); | 835 | self.r.intenset().write(|w| w.set_dmarxready(true)); |
| 818 | } | 836 | } |
| 819 | 837 | ||
| 820 | /// we are ready to read if there is data in the buffer | 838 | /// we are ready to read if there is data in the buffer |
| 821 | fn read_ready(&self) -> Result<bool, Error> { | 839 | fn read_ready(&self) -> Result<bool, Error> { |
| 822 | let state = self.buffered_state; | 840 | let state = self.buffered_state; |
| 823 | Ok(!state.rx_buf.is_empty()) | 841 | if state.rx_overrun.swap(false, Ordering::Acquire) { |
| 842 | return Err(Error::Overrun); | ||
| 843 | } | ||
| 844 | |||
| 845 | let start = state.rx_buf.start.load(Ordering::Relaxed); | ||
| 846 | let end = self.get_rxdrdy_counter(); | ||
| 847 | |||
| 848 | Ok(start != end) | ||
| 824 | } | 849 | } |
| 825 | } | 850 | } |
| 826 | 851 | ||
| @@ -834,11 +859,11 @@ impl<'a> Drop for BufferedUarteRx<'a> { | |||
| 834 | 859 | ||
| 835 | r.intenclr().write(|w| { | 860 | r.intenclr().write(|w| { |
| 836 | w.set_rxdrdy(true); | 861 | w.set_rxdrdy(true); |
| 837 | w.set_rxstarted(true); | 862 | w.set_dmarxready(true); |
| 838 | w.set_rxto(true); | 863 | w.set_rxto(true); |
| 839 | }); | 864 | }); |
| 840 | r.events_rxto().write_value(0); | 865 | r.events_rxto().write_value(0); |
| 841 | r.tasks_stoprx().write_value(1); | 866 | r.tasks_dma().rx().stop().write_value(1); |
| 842 | while r.events_rxto().read() == 0 {} | 867 | while r.events_rxto().read() == 0 {} |
| 843 | 868 | ||
| 844 | let s = self.buffered_state; | 869 | let s = self.buffered_state; |
| @@ -854,7 +879,9 @@ mod _embedded_io { | |||
| 854 | 879 | ||
| 855 | impl embedded_io_async::Error for Error { | 880 | impl embedded_io_async::Error for Error { |
| 856 | fn kind(&self) -> embedded_io_async::ErrorKind { | 881 | fn kind(&self) -> embedded_io_async::ErrorKind { |
| 857 | match *self {} | 882 | match *self { |
| 883 | Error::Overrun => embedded_io_async::ErrorKind::OutOfMemory, | ||
| 884 | } | ||
| 858 | } | 885 | } |
| 859 | } | 886 | } |
| 860 | 887 | ||
diff --git a/embassy-nrf/src/buffered_uarte/v2.rs b/embassy-nrf/src/buffered_uarte/v2.rs new file mode 100644 index 000000000..d0d2d97d1 --- /dev/null +++ b/embassy-nrf/src/buffered_uarte/v2.rs | |||
| @@ -0,0 +1,687 @@ | |||
| 1 | //! Async buffered UART driver. | ||
| 2 | //! | ||
| 3 | //! Note that discarding a future from a read or write operation may lead to losing | ||
| 4 | //! data. For example, when using `futures_util::future::select` and completion occurs | ||
| 5 | //! on the "other" future, you should capture the incomplete future and continue to use | ||
| 6 | //! it for the next read or write. This pattern is a consideration for all IO, and not | ||
| 7 | //! just serial communications. | ||
| 8 | //! | ||
| 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. | ||
| 10 | //! | ||
| 11 | //! The code is based on the generic buffered_uarte implementation but uses the nrf54l | ||
| 12 | //! frame timeout event to correctly determine the size of transferred data. | ||
| 13 | //! Counting of rxrdy events, used in the generic implementation, cannot be applied | ||
| 14 | //! to nrf54l chips, as they buffer up to 4 bytes in a single DMA transaction. | ||
| 15 | //! The only reliable way to find the number of bytes received is to stop the transfer, | ||
| 16 | //! wait for the DMA stopped event, and read the value in the rx.dma.amount register. | ||
| 17 | //! This also flushes all in-flight data to RAM. | ||
| 18 | |||
| 19 | use core::cmp::min; | ||
| 20 | use core::future::{Future, poll_fn}; | ||
| 21 | use core::marker::PhantomData; | ||
| 22 | use core::slice; | ||
| 23 | use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering, compiler_fence}; | ||
| 24 | use core::task::Poll; | ||
| 25 | |||
| 26 | use embassy_hal_internal::Peri; | ||
| 27 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | ||
| 28 | use pac::uarte::vals; | ||
| 29 | // Re-export SVD variants to allow user to directly set values | ||
| 30 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; | ||
| 31 | |||
| 32 | use crate::gpio::{AnyPin, Pin as GpioPin}; | ||
| 33 | use crate::interrupt::typelevel::Interrupt; | ||
| 34 | use crate::uarte::{Config, Instance as UarteInstance, configure, configure_rx_pins, configure_tx_pins, drop_tx_rx}; | ||
| 35 | use crate::{EASY_DMA_SIZE, interrupt, pac}; | ||
| 36 | |||
| 37 | pub(crate) struct State { | ||
| 38 | tx_buf: RingBuffer, | ||
| 39 | tx_count: AtomicUsize, | ||
| 40 | |||
| 41 | rx_buf: RingBuffer, | ||
| 42 | rx_started: AtomicBool, | ||
| 43 | } | ||
| 44 | |||
| 45 | /// UART error. | ||
| 46 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| 47 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 48 | #[non_exhaustive] | ||
| 49 | pub enum Error { | ||
| 50 | // No errors for now | ||
| 51 | } | ||
| 52 | |||
| 53 | impl State { | ||
| 54 | pub(crate) const fn new() -> Self { | ||
| 55 | Self { | ||
| 56 | tx_buf: RingBuffer::new(), | ||
| 57 | tx_count: AtomicUsize::new(0), | ||
| 58 | |||
| 59 | rx_buf: RingBuffer::new(), | ||
| 60 | rx_started: AtomicBool::new(false), | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | /// Interrupt handler. | ||
| 66 | pub struct InterruptHandler<U: UarteInstance> { | ||
| 67 | _phantom: PhantomData<U>, | ||
| 68 | } | ||
| 69 | |||
| 70 | impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for InterruptHandler<U> { | ||
| 71 | unsafe fn on_interrupt() { | ||
| 72 | info!("irq: start"); | ||
| 73 | let r = U::regs(); | ||
| 74 | let ss = U::state(); | ||
| 75 | let s = U::buffered_state(); | ||
| 76 | |||
| 77 | if let Some(mut rx) = unsafe { s.rx_buf.try_writer() } { | ||
| 78 | let buf_len = s.rx_buf.len(); | ||
| 79 | let half_len = buf_len / 2; | ||
| 80 | |||
| 81 | if r.events_error().read() != 0 { | ||
| 82 | r.events_error().write_value(0); | ||
| 83 | let errs = r.errorsrc().read(); | ||
| 84 | r.errorsrc().write_value(errs); | ||
| 85 | |||
| 86 | if errs.overrun() { | ||
| 87 | panic!("BufferedUarte UART overrun"); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | let first_run = !s.rx_started.swap(true, Ordering::Relaxed); | ||
| 92 | if r.events_dma().rx().end().read() != 0 || first_run { | ||
| 93 | //trace!(" irq_rx: endrx"); | ||
| 94 | r.events_dma().rx().end().write_value(0); | ||
| 95 | |||
| 96 | if !first_run { | ||
| 97 | // Received some bytes, wake task. | ||
| 98 | let rxed = r.dma().rx().amount().read().amount() as usize; | ||
| 99 | rx.push_done(rxed); | ||
| 100 | ss.rx_waker.wake(); | ||
| 101 | } | ||
| 102 | |||
| 103 | let (ptr, len) = rx.push_buf(); | ||
| 104 | if len == 0 { | ||
| 105 | panic!("BufferedUarte buffer overrun"); | ||
| 106 | } | ||
| 107 | |||
| 108 | let len = if len > half_len { half_len } else { len }; | ||
| 109 | |||
| 110 | // Set up the DMA read | ||
| 111 | r.dma().rx().ptr().write_value(ptr as u32); | ||
| 112 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); | ||
| 113 | |||
| 114 | // manually start | ||
| 115 | r.tasks_dma().rx().start().write_value(1); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | // ============================= | ||
| 120 | |||
| 121 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { | ||
| 122 | // TX end | ||
| 123 | if r.events_dma().tx().end().read() != 0 { | ||
| 124 | r.events_dma().tx().end().write_value(0); | ||
| 125 | |||
| 126 | let n = s.tx_count.load(Ordering::Relaxed); | ||
| 127 | //trace!(" irq_tx: endtx {:?}", n); | ||
| 128 | tx.pop_done(n); | ||
| 129 | ss.tx_waker.wake(); | ||
| 130 | s.tx_count.store(0, Ordering::Relaxed); | ||
| 131 | } | ||
| 132 | |||
| 133 | // If not TXing, start. | ||
| 134 | if s.tx_count.load(Ordering::Relaxed) == 0 { | ||
| 135 | let (ptr, len) = tx.pop_buf(); | ||
| 136 | let len = len.min(EASY_DMA_SIZE); | ||
| 137 | if len != 0 { | ||
| 138 | //trace!(" irq_tx: starting {:?}", len); | ||
| 139 | s.tx_count.store(len, Ordering::Relaxed); | ||
| 140 | |||
| 141 | // Set up the DMA write | ||
| 142 | r.dma().tx().ptr().write_value(ptr as u32); | ||
| 143 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); | ||
| 144 | |||
| 145 | // Start UARTE Transmit transaction | ||
| 146 | r.tasks_dma().tx().start().write_value(1); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | //trace!("irq: end"); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | /// Buffered UARTE driver. | ||
| 156 | pub struct BufferedUarte<'d, U: UarteInstance> { | ||
| 157 | tx: BufferedUarteTx<'d, U>, | ||
| 158 | rx: BufferedUarteRx<'d, U>, | ||
| 159 | } | ||
| 160 | |||
| 161 | impl<'d, U: UarteInstance> Unpin for BufferedUarte<'d, U> {} | ||
| 162 | |||
| 163 | impl<'d, U: UarteInstance> BufferedUarte<'d, U> { | ||
| 164 | /// Create a new BufferedUarte without hardware flow control. | ||
| 165 | #[allow(clippy::too_many_arguments)] | ||
| 166 | pub fn new( | ||
| 167 | uarte: Peri<'d, U>, | ||
| 168 | rxd: Peri<'d, impl GpioPin>, | ||
| 169 | txd: Peri<'d, impl GpioPin>, | ||
| 170 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 171 | config: Config, | ||
| 172 | rx_buffer: &'d mut [u8], | ||
| 173 | tx_buffer: &'d mut [u8], | ||
| 174 | ) -> Self { | ||
| 175 | Self::new_inner(uarte, rxd.into(), txd.into(), None, None, config, rx_buffer, tx_buffer) | ||
| 176 | } | ||
| 177 | |||
| 178 | /// Create a new BufferedUarte with hardware flow control (RTS/CTS) | ||
| 179 | #[allow(clippy::too_many_arguments)] | ||
| 180 | pub fn new_with_rtscts( | ||
| 181 | uarte: Peri<'d, U>, | ||
| 182 | rxd: Peri<'d, impl GpioPin>, | ||
| 183 | txd: Peri<'d, impl GpioPin>, | ||
| 184 | cts: Peri<'d, impl GpioPin>, | ||
| 185 | rts: Peri<'d, impl GpioPin>, | ||
| 186 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 187 | config: Config, | ||
| 188 | rx_buffer: &'d mut [u8], | ||
| 189 | tx_buffer: &'d mut [u8], | ||
| 190 | ) -> Self { | ||
| 191 | Self::new_inner( | ||
| 192 | uarte, | ||
| 193 | rxd.into(), | ||
| 194 | txd.into(), | ||
| 195 | Some(cts.into()), | ||
| 196 | Some(rts.into()), | ||
| 197 | config, | ||
| 198 | rx_buffer, | ||
| 199 | tx_buffer, | ||
| 200 | ) | ||
| 201 | } | ||
| 202 | |||
| 203 | #[allow(clippy::too_many_arguments)] | ||
| 204 | fn new_inner( | ||
| 205 | peri: Peri<'d, U>, | ||
| 206 | rxd: Peri<'d, AnyPin>, | ||
| 207 | txd: Peri<'d, AnyPin>, | ||
| 208 | cts: Option<Peri<'d, AnyPin>>, | ||
| 209 | rts: Option<Peri<'d, AnyPin>>, | ||
| 210 | config: Config, | ||
| 211 | rx_buffer: &'d mut [u8], | ||
| 212 | tx_buffer: &'d mut [u8], | ||
| 213 | ) -> Self { | ||
| 214 | configure(U::regs(), config, cts.is_some()); | ||
| 215 | |||
| 216 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); | ||
| 217 | let rx = BufferedUarteRx::new_innerer(peri, rxd, rts, rx_buffer); | ||
| 218 | |||
| 219 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | ||
| 220 | U::Interrupt::pend(); | ||
| 221 | unsafe { U::Interrupt::enable() }; | ||
| 222 | |||
| 223 | U::state().tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 224 | |||
| 225 | Self { tx, rx } | ||
| 226 | } | ||
| 227 | |||
| 228 | /// Adjust the baud rate to the provided value. | ||
| 229 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | ||
| 230 | let r = U::regs(); | ||
| 231 | r.baudrate().write(|w| w.set_baudrate(baudrate)); | ||
| 232 | } | ||
| 233 | |||
| 234 | /// Split the UART in reader and writer parts. | ||
| 235 | /// | ||
| 236 | /// This allows reading and writing concurrently from independent tasks. | ||
| 237 | pub fn split(self) -> (BufferedUarteRx<'d, U>, BufferedUarteTx<'d, U>) { | ||
| 238 | (self.rx, self.tx) | ||
| 239 | } | ||
| 240 | |||
| 241 | /// Split the UART in reader and writer parts, by reference. | ||
| 242 | /// | ||
| 243 | /// The returned halves borrow from `self`, so you can drop them and go back to using | ||
| 244 | /// the "un-split" `self`. This allows temporarily splitting the UART. | ||
| 245 | pub fn split_by_ref(&mut self) -> (&mut BufferedUarteRx<'d, U>, &mut BufferedUarteTx<'d, U>) { | ||
| 246 | (&mut self.rx, &mut self.tx) | ||
| 247 | } | ||
| 248 | |||
| 249 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 250 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 251 | self.rx.read(buf).await | ||
| 252 | } | ||
| 253 | |||
| 254 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 255 | pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { | ||
| 256 | self.rx.fill_buf().await | ||
| 257 | } | ||
| 258 | |||
| 259 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | ||
| 260 | pub fn consume(&mut self, amt: usize) { | ||
| 261 | self.rx.consume(amt) | ||
| 262 | } | ||
| 263 | |||
| 264 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 265 | pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 266 | self.tx.write(buf).await | ||
| 267 | } | ||
| 268 | |||
| 269 | /// Try writing a buffer without waiting, returning how many bytes were written. | ||
| 270 | pub fn try_write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 271 | self.tx.try_write(buf) | ||
| 272 | } | ||
| 273 | |||
| 274 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | ||
| 275 | pub async fn flush(&mut self) -> Result<(), Error> { | ||
| 276 | self.tx.flush().await | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | /// Reader part of the buffered UARTE driver. | ||
| 281 | pub struct BufferedUarteTx<'d, U: UarteInstance> { | ||
| 282 | _peri: Peri<'d, U>, | ||
| 283 | } | ||
| 284 | |||
| 285 | impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | ||
| 286 | /// Create a new BufferedUarteTx without hardware flow control. | ||
| 287 | pub fn new( | ||
| 288 | uarte: Peri<'d, U>, | ||
| 289 | txd: Peri<'d, impl GpioPin>, | ||
| 290 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 291 | config: Config, | ||
| 292 | tx_buffer: &'d mut [u8], | ||
| 293 | ) -> Self { | ||
| 294 | Self::new_inner(uarte, txd.into(), None, config, tx_buffer) | ||
| 295 | } | ||
| 296 | |||
| 297 | /// Create a new BufferedUarte with hardware flow control (RTS/CTS) | ||
| 298 | pub fn new_with_cts( | ||
| 299 | uarte: Peri<'d, U>, | ||
| 300 | txd: Peri<'d, impl GpioPin>, | ||
| 301 | cts: Peri<'d, impl GpioPin>, | ||
| 302 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 303 | config: Config, | ||
| 304 | tx_buffer: &'d mut [u8], | ||
| 305 | ) -> Self { | ||
| 306 | Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer) | ||
| 307 | } | ||
| 308 | |||
| 309 | fn new_inner( | ||
| 310 | peri: Peri<'d, U>, | ||
| 311 | txd: Peri<'d, AnyPin>, | ||
| 312 | cts: Option<Peri<'d, AnyPin>>, | ||
| 313 | config: Config, | ||
| 314 | tx_buffer: &'d mut [u8], | ||
| 315 | ) -> Self { | ||
| 316 | configure(U::regs(), config, cts.is_some()); | ||
| 317 | |||
| 318 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); | ||
| 319 | |||
| 320 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | ||
| 321 | U::Interrupt::pend(); | ||
| 322 | unsafe { U::Interrupt::enable() }; | ||
| 323 | |||
| 324 | U::state().tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 325 | |||
| 326 | this | ||
| 327 | } | ||
| 328 | |||
| 329 | fn new_innerer( | ||
| 330 | peri: Peri<'d, U>, | ||
| 331 | txd: Peri<'d, AnyPin>, | ||
| 332 | cts: Option<Peri<'d, AnyPin>>, | ||
| 333 | tx_buffer: &'d mut [u8], | ||
| 334 | ) -> Self { | ||
| 335 | let r = U::regs(); | ||
| 336 | |||
| 337 | configure_tx_pins(r, txd, cts); | ||
| 338 | |||
| 339 | // Initialize state | ||
| 340 | let s = U::buffered_state(); | ||
| 341 | s.tx_count.store(0, Ordering::Relaxed); | ||
| 342 | let len = tx_buffer.len(); | ||
| 343 | unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 344 | |||
| 345 | r.events_dma().tx().ready().write_value(0); | ||
| 346 | |||
| 347 | // Enable interrupts | ||
| 348 | r.intenset().write(|w| { | ||
| 349 | w.set_dmatxend(true); | ||
| 350 | }); | ||
| 351 | |||
| 352 | Self { _peri: peri } | ||
| 353 | } | ||
| 354 | |||
| 355 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 356 | pub fn write<'a>(&'a mut self, buf: &'a [u8]) -> impl Future<Output = Result<usize, Error>> + 'a { | ||
| 357 | poll_fn(move |cx| { | ||
| 358 | //trace!("poll_write: {:?}", buf.len()); | ||
| 359 | let ss = U::state(); | ||
| 360 | let s = U::buffered_state(); | ||
| 361 | let mut tx = unsafe { s.tx_buf.writer() }; | ||
| 362 | |||
| 363 | let tx_buf = tx.push_slice(); | ||
| 364 | if tx_buf.is_empty() { | ||
| 365 | //trace!("poll_write: pending"); | ||
| 366 | ss.tx_waker.register(cx.waker()); | ||
| 367 | return Poll::Pending; | ||
| 368 | } | ||
| 369 | |||
| 370 | let n = min(tx_buf.len(), buf.len()); | ||
| 371 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 372 | tx.push_done(n); | ||
| 373 | |||
| 374 | //trace!("poll_write: queued {:?}", n); | ||
| 375 | |||
| 376 | compiler_fence(Ordering::SeqCst); | ||
| 377 | U::Interrupt::pend(); | ||
| 378 | |||
| 379 | Poll::Ready(Ok(n)) | ||
| 380 | }) | ||
| 381 | } | ||
| 382 | |||
| 383 | /// Try writing a buffer without waiting, returning how many bytes were written. | ||
| 384 | pub fn try_write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 385 | //trace!("poll_write: {:?}", buf.len()); | ||
| 386 | let s = U::buffered_state(); | ||
| 387 | let mut tx = unsafe { s.tx_buf.writer() }; | ||
| 388 | |||
| 389 | let tx_buf = tx.push_slice(); | ||
| 390 | if tx_buf.is_empty() { | ||
| 391 | return Ok(0); | ||
| 392 | } | ||
| 393 | |||
| 394 | let n = min(tx_buf.len(), buf.len()); | ||
| 395 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 396 | tx.push_done(n); | ||
| 397 | |||
| 398 | //trace!("poll_write: queued {:?}", n); | ||
| 399 | |||
| 400 | compiler_fence(Ordering::SeqCst); | ||
| 401 | U::Interrupt::pend(); | ||
| 402 | |||
| 403 | Ok(n) | ||
| 404 | } | ||
| 405 | |||
| 406 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | ||
| 407 | pub fn flush(&mut self) -> impl Future<Output = Result<(), Error>> + '_ { | ||
| 408 | poll_fn(move |cx| { | ||
| 409 | //trace!("poll_flush"); | ||
| 410 | let ss = U::state(); | ||
| 411 | let s = U::buffered_state(); | ||
| 412 | if !s.tx_buf.is_empty() { | ||
| 413 | //trace!("poll_flush: pending"); | ||
| 414 | ss.tx_waker.register(cx.waker()); | ||
| 415 | return Poll::Pending; | ||
| 416 | } | ||
| 417 | |||
| 418 | Poll::Ready(Ok(())) | ||
| 419 | }) | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { | ||
| 424 | fn drop(&mut self) { | ||
| 425 | let r = U::regs(); | ||
| 426 | |||
| 427 | r.intenclr().write(|w| { | ||
| 428 | w.set_txdrdy(true); | ||
| 429 | w.set_dmatxready(true); | ||
| 430 | w.set_txstopped(true); | ||
| 431 | }); | ||
| 432 | r.events_txstopped().write_value(0); | ||
| 433 | r.tasks_dma().tx().stop().write_value(1); | ||
| 434 | while r.events_txstopped().read() == 0 {} | ||
| 435 | |||
| 436 | let s = U::buffered_state(); | ||
| 437 | unsafe { s.tx_buf.deinit() } | ||
| 438 | |||
| 439 | let s = U::state(); | ||
| 440 | drop_tx_rx(r, s); | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | /// Reader part of the buffered UARTE driver. | ||
| 445 | pub struct BufferedUarteRx<'d, U: UarteInstance> { | ||
| 446 | _peri: Peri<'d, U>, | ||
| 447 | } | ||
| 448 | |||
| 449 | impl<'d, U: UarteInstance> BufferedUarteRx<'d, U> { | ||
| 450 | /// Create a new BufferedUarte without hardware flow control. | ||
| 451 | #[allow(clippy::too_many_arguments)] | ||
| 452 | pub fn new( | ||
| 453 | uarte: Peri<'d, U>, | ||
| 454 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 455 | rxd: Peri<'d, impl GpioPin>, | ||
| 456 | config: Config, | ||
| 457 | rx_buffer: &'d mut [u8], | ||
| 458 | ) -> Self { | ||
| 459 | Self::new_inner(uarte, rxd.into(), None, config, rx_buffer) | ||
| 460 | } | ||
| 461 | |||
| 462 | /// Create a new BufferedUarte with hardware flow control (RTS/CTS) | ||
| 463 | #[allow(clippy::too_many_arguments)] | ||
| 464 | pub fn new_with_rts( | ||
| 465 | uarte: Peri<'d, U>, | ||
| 466 | rxd: Peri<'d, impl GpioPin>, | ||
| 467 | rts: Peri<'d, impl GpioPin>, | ||
| 468 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 469 | config: Config, | ||
| 470 | rx_buffer: &'d mut [u8], | ||
| 471 | ) -> Self { | ||
| 472 | Self::new_inner(uarte, rxd.into(), Some(rts.into()), config, rx_buffer) | ||
| 473 | } | ||
| 474 | |||
| 475 | #[allow(clippy::too_many_arguments)] | ||
| 476 | fn new_inner( | ||
| 477 | peri: Peri<'d, U>, | ||
| 478 | rxd: Peri<'d, AnyPin>, | ||
| 479 | rts: Option<Peri<'d, AnyPin>>, | ||
| 480 | config: Config, | ||
| 481 | rx_buffer: &'d mut [u8], | ||
| 482 | ) -> Self { | ||
| 483 | configure(U::regs(), config, rts.is_some()); | ||
| 484 | |||
| 485 | let this = Self::new_innerer(peri, rxd, rts, rx_buffer); | ||
| 486 | |||
| 487 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | ||
| 488 | U::Interrupt::pend(); | ||
| 489 | unsafe { U::Interrupt::enable() }; | ||
| 490 | |||
| 491 | U::state().tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 492 | |||
| 493 | this | ||
| 494 | } | ||
| 495 | |||
| 496 | #[allow(clippy::too_many_arguments)] | ||
| 497 | fn new_innerer( | ||
| 498 | peri: Peri<'d, U>, | ||
| 499 | rxd: Peri<'d, AnyPin>, | ||
| 500 | rts: Option<Peri<'d, AnyPin>>, | ||
| 501 | rx_buffer: &'d mut [u8], | ||
| 502 | ) -> Self { | ||
| 503 | let r = U::regs(); | ||
| 504 | |||
| 505 | configure_rx_pins(r, rxd, rts); | ||
| 506 | |||
| 507 | // Initialize state | ||
| 508 | let s = U::buffered_state(); | ||
| 509 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); | ||
| 510 | let rx_ptr = rx_buffer.as_mut_ptr(); | ||
| 511 | unsafe { s.rx_buf.init(rx_ptr, rx_len) }; | ||
| 512 | |||
| 513 | // clear errors | ||
| 514 | let errors = r.errorsrc().read(); | ||
| 515 | r.errorsrc().write_value(errors); | ||
| 516 | |||
| 517 | r.events_error().write_value(0); | ||
| 518 | r.events_dma().rx().end().write_value(0); | ||
| 519 | |||
| 520 | // set timeout-to-stop short | ||
| 521 | r.shorts().write(|w| { | ||
| 522 | w.set_frametimeout_dma_rx_stop(true); | ||
| 523 | }); | ||
| 524 | |||
| 525 | // set default timeout | ||
| 526 | r.frametimeout().write_value(pac::uarte::regs::Frametimeout(0x10)); | ||
| 527 | |||
| 528 | // Enable interrupts | ||
| 529 | r.intenset().write(|w| { | ||
| 530 | w.set_dmatxend(true); | ||
| 531 | w.set_error(true); | ||
| 532 | w.set_dmarxend(true); | ||
| 533 | }); | ||
| 534 | |||
| 535 | Self { _peri: peri } | ||
| 536 | } | ||
| 537 | |||
| 538 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 539 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 540 | let data = self.fill_buf().await?; | ||
| 541 | let n = data.len().min(buf.len()); | ||
| 542 | buf[..n].copy_from_slice(&data[..n]); | ||
| 543 | self.consume(n); | ||
| 544 | Ok(n) | ||
| 545 | } | ||
| 546 | |||
| 547 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 548 | pub fn fill_buf(&mut self) -> impl Future<Output = Result<&'_ [u8], Error>> { | ||
| 549 | poll_fn(move |cx| { | ||
| 550 | compiler_fence(Ordering::SeqCst); | ||
| 551 | //trace!("poll_read"); | ||
| 552 | |||
| 553 | let s = U::buffered_state(); | ||
| 554 | let ss = U::state(); | ||
| 555 | let mut rx = unsafe { s.rx_buf.reader() }; | ||
| 556 | |||
| 557 | let (ptr, n) = rx.pop_buf(); | ||
| 558 | if n == 0 { | ||
| 559 | //trace!(" empty"); | ||
| 560 | ss.rx_waker.register(cx.waker()); | ||
| 561 | Poll::Pending | ||
| 562 | } else { | ||
| 563 | Poll::Ready(Ok(unsafe { slice::from_raw_parts(ptr, n) })) | ||
| 564 | } | ||
| 565 | }) | ||
| 566 | } | ||
| 567 | |||
| 568 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | ||
| 569 | pub fn consume(&mut self, amt: usize) { | ||
| 570 | if amt == 0 { | ||
| 571 | return; | ||
| 572 | } | ||
| 573 | |||
| 574 | let s = U::buffered_state(); | ||
| 575 | let mut rx = unsafe { s.rx_buf.reader() }; | ||
| 576 | rx.pop_done(amt); | ||
| 577 | } | ||
| 578 | |||
| 579 | /// we are ready to read if there is data in the buffer | ||
| 580 | fn read_ready() -> Result<bool, Error> { | ||
| 581 | let state = U::buffered_state(); | ||
| 582 | Ok(!state.rx_buf.is_empty()) | ||
| 583 | } | ||
| 584 | } | ||
| 585 | |||
| 586 | impl<'a, U: UarteInstance> Drop for BufferedUarteRx<'a, U> { | ||
| 587 | fn drop(&mut self) { | ||
| 588 | let r = U::regs(); | ||
| 589 | |||
| 590 | r.intenclr().write(|w| { | ||
| 591 | w.set_rxto(true); | ||
| 592 | }); | ||
| 593 | r.events_rxto().write_value(0); | ||
| 594 | |||
| 595 | let s = U::buffered_state(); | ||
| 596 | unsafe { s.rx_buf.deinit() } | ||
| 597 | |||
| 598 | let s = U::state(); | ||
| 599 | drop_tx_rx(r, s); | ||
| 600 | } | ||
| 601 | } | ||
| 602 | |||
| 603 | mod _embedded_io { | ||
| 604 | use super::*; | ||
| 605 | |||
| 606 | impl embedded_io_async::Error for Error { | ||
| 607 | fn kind(&self) -> embedded_io_async::ErrorKind { | ||
| 608 | match *self {} | ||
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 612 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarte<'d, U> { | ||
| 613 | type Error = Error; | ||
| 614 | } | ||
| 615 | |||
| 616 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteRx<'d, U> { | ||
| 617 | type Error = Error; | ||
| 618 | } | ||
| 619 | |||
| 620 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteTx<'d, U> { | ||
| 621 | type Error = Error; | ||
| 622 | } | ||
| 623 | |||
| 624 | impl<'d, U: UarteInstance> embedded_io_async::Read for BufferedUarte<'d, U> { | ||
| 625 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | ||
| 626 | self.read(buf).await | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 630 | impl<'d: 'd, U: UarteInstance> embedded_io_async::Read for BufferedUarteRx<'d, U> { | ||
| 631 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | ||
| 632 | self.read(buf).await | ||
| 633 | } | ||
| 634 | } | ||
| 635 | |||
| 636 | impl<'d, U: UarteInstance> embedded_io_async::ReadReady for BufferedUarte<'d, U> { | ||
| 637 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | ||
| 638 | BufferedUarteRx::<'d, U>::read_ready() | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 642 | impl<'d, U: UarteInstance> embedded_io_async::ReadReady for BufferedUarteRx<'d, U> { | ||
| 643 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | ||
| 644 | Self::read_ready() | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | impl<'d, U: UarteInstance> embedded_io_async::BufRead for BufferedUarte<'d, U> { | ||
| 649 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | ||
| 650 | self.fill_buf().await | ||
| 651 | } | ||
| 652 | |||
| 653 | fn consume(&mut self, amt: usize) { | ||
| 654 | self.consume(amt) | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | impl<'d: 'd, U: UarteInstance> embedded_io_async::BufRead for BufferedUarteRx<'d, U> { | ||
| 659 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | ||
| 660 | self.fill_buf().await | ||
| 661 | } | ||
| 662 | |||
| 663 | fn consume(&mut self, amt: usize) { | ||
| 664 | self.consume(amt) | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | impl<'d, U: UarteInstance> embedded_io_async::Write for BufferedUarte<'d, U> { | ||
| 669 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | ||
| 670 | self.write(buf).await | ||
| 671 | } | ||
| 672 | |||
| 673 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 674 | self.flush().await | ||
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 | impl<'d: 'd, U: UarteInstance> embedded_io_async::Write for BufferedUarteTx<'d, U> { | ||
| 679 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | ||
| 680 | self.write(buf).await | ||
| 681 | } | ||
| 682 | |||
| 683 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 684 | self.flush().await | ||
| 685 | } | ||
| 686 | } | ||
| 687 | } | ||
diff --git a/embassy-nrf/src/chips/nrf51.rs b/embassy-nrf/src/chips/nrf51.rs index 3976e8ff0..1184c4409 100644 --- a/embassy-nrf/src/chips/nrf51.rs +++ b/embassy-nrf/src/chips/nrf51.rs | |||
| @@ -115,6 +115,11 @@ impl_rtc!(RTC0, RTC0, RTC0); | |||
| 115 | #[cfg(not(feature = "time-driver-rtc1"))] | 115 | #[cfg(not(feature = "time-driver-rtc1"))] |
| 116 | impl_rtc!(RTC1, RTC1, RTC1); | 116 | impl_rtc!(RTC1, RTC1, RTC1); |
| 117 | 117 | ||
| 118 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 119 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 120 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 121 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 122 | |||
| 118 | impl_pin!(P0_00, 0, 0); | 123 | impl_pin!(P0_00, 0, 0); |
| 119 | impl_pin!(P0_01, 0, 1); | 124 | impl_pin!(P0_01, 0, 1); |
| 120 | impl_pin!(P0_02, 0, 2); | 125 | impl_pin!(P0_02, 0, 2); |
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index 63ba6999a..dd2e66927 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs | |||
| @@ -195,28 +195,35 @@ impl_pin!(P0_29, 0, 29); | |||
| 195 | impl_pin!(P0_30, 0, 30); | 195 | impl_pin!(P0_30, 0, 30); |
| 196 | impl_pin!(P0_31, 0, 31); | 196 | impl_pin!(P0_31, 0, 31); |
| 197 | 197 | ||
| 198 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 198 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 199 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 199 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 200 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 200 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 201 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 201 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 202 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 202 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 203 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 203 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 204 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 204 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 205 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 205 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 206 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 206 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 207 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 207 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 208 | impl_ppi_channel!(PPI_CH20, 20 => static); | 208 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 209 | impl_ppi_channel!(PPI_CH21, 21 => static); | 209 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 210 | impl_ppi_channel!(PPI_CH22, 22 => static); | 210 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 211 | impl_ppi_channel!(PPI_CH23, 23 => static); | 211 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 212 | impl_ppi_channel!(PPI_CH24, 24 => static); | 212 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 213 | impl_ppi_channel!(PPI_CH25, 25 => static); | 213 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 214 | impl_ppi_channel!(PPI_CH26, 26 => static); | 214 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 215 | impl_ppi_channel!(PPI_CH27, 27 => static); | 215 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 216 | impl_ppi_channel!(PPI_CH28, 28 => static); | 216 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 217 | impl_ppi_channel!(PPI_CH29, 29 => static); | 217 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 218 | impl_ppi_channel!(PPI_CH30, 30 => static); | 218 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 219 | impl_ppi_channel!(PPI_CH31, 31 => static); | 219 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 220 | |||
| 221 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 222 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 223 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 224 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 225 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 226 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 220 | 227 | ||
| 221 | impl_saadc_input!(P0_04, ANALOG_INPUT2); | 228 | impl_saadc_input!(P0_04, ANALOG_INPUT2); |
| 222 | impl_saadc_input!(P0_05, ANALOG_INPUT3); | 229 | impl_saadc_input!(P0_05, ANALOG_INPUT3); |
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 7f744f9fb..7acb53a03 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -205,38 +205,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 205 | impl_pin!(P0_30, 0, 30); | 205 | impl_pin!(P0_30, 0, 30); |
| 206 | impl_pin!(P0_31, 0, 31); | 206 | impl_pin!(P0_31, 0, 31); |
| 207 | 207 | ||
| 208 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 208 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 209 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 209 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 210 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 210 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 211 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 211 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 212 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 212 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 213 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 213 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 214 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 214 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 215 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 215 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 216 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 216 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 217 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 217 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 218 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 218 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 219 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 219 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 220 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 220 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 221 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 221 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 222 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 222 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 223 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 223 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 224 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 224 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 225 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 225 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 226 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 226 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 227 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 227 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 228 | impl_ppi_channel!(PPI_CH20, 20 => static); | 228 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 229 | impl_ppi_channel!(PPI_CH21, 21 => static); | 229 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 230 | impl_ppi_channel!(PPI_CH22, 22 => static); | 230 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 231 | impl_ppi_channel!(PPI_CH23, 23 => static); | 231 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 232 | impl_ppi_channel!(PPI_CH24, 24 => static); | 232 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 233 | impl_ppi_channel!(PPI_CH25, 25 => static); | 233 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 234 | impl_ppi_channel!(PPI_CH26, 26 => static); | 234 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 235 | impl_ppi_channel!(PPI_CH27, 27 => static); | 235 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 236 | impl_ppi_channel!(PPI_CH28, 28 => static); | 236 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 237 | impl_ppi_channel!(PPI_CH29, 29 => static); | 237 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 238 | impl_ppi_channel!(PPI_CH30, 30 => static); | 238 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 239 | impl_ppi_channel!(PPI_CH31, 31 => static); | 239 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 240 | |||
| 241 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 242 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 243 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 244 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 245 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 246 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 240 | 247 | ||
| 241 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 248 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 242 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 249 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 908167e31..4178ef6cd 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -207,38 +207,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 207 | impl_pin!(P0_30, 0, 30); | 207 | impl_pin!(P0_30, 0, 30); |
| 208 | impl_pin!(P0_31, 0, 31); | 208 | impl_pin!(P0_31, 0, 31); |
| 209 | 209 | ||
| 210 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 210 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 211 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 211 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 212 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 212 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 213 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 213 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 214 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 214 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 215 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 215 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 216 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 216 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 217 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 217 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 218 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 218 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 219 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 219 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 220 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 220 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 221 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 221 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 222 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 222 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 223 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 223 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 224 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 224 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 225 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 225 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 226 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 226 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 227 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 227 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 228 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 228 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 229 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 229 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 230 | impl_ppi_channel!(PPI_CH20, 20 => static); | 230 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 231 | impl_ppi_channel!(PPI_CH21, 21 => static); | 231 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 232 | impl_ppi_channel!(PPI_CH22, 22 => static); | 232 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 233 | impl_ppi_channel!(PPI_CH23, 23 => static); | 233 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 234 | impl_ppi_channel!(PPI_CH24, 24 => static); | 234 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 235 | impl_ppi_channel!(PPI_CH25, 25 => static); | 235 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 236 | impl_ppi_channel!(PPI_CH26, 26 => static); | 236 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 237 | impl_ppi_channel!(PPI_CH27, 27 => static); | 237 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 238 | impl_ppi_channel!(PPI_CH28, 28 => static); | 238 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 239 | impl_ppi_channel!(PPI_CH29, 29 => static); | 239 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 240 | impl_ppi_channel!(PPI_CH30, 30 => static); | 240 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 241 | impl_ppi_channel!(PPI_CH31, 31 => static); | 241 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 242 | |||
| 243 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 244 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 245 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 246 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 247 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 248 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 242 | 249 | ||
| 243 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 250 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 244 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 251 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 22360575b..32304b3ea 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs | |||
| @@ -207,38 +207,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 207 | impl_pin!(P0_30, 0, 30); | 207 | impl_pin!(P0_30, 0, 30); |
| 208 | impl_pin!(P0_31, 0, 31); | 208 | impl_pin!(P0_31, 0, 31); |
| 209 | 209 | ||
| 210 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 210 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 211 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 211 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 212 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 212 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 213 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 213 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 214 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 214 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 215 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 215 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 216 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 216 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 217 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 217 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 218 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 218 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 219 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 219 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 220 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 220 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 221 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 221 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 222 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 222 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 223 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 223 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 224 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 224 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 225 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 225 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 226 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 226 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 227 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 227 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 228 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 228 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 229 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 229 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 230 | impl_ppi_channel!(PPI_CH20, 20 => static); | 230 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 231 | impl_ppi_channel!(PPI_CH21, 21 => static); | 231 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 232 | impl_ppi_channel!(PPI_CH22, 22 => static); | 232 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 233 | impl_ppi_channel!(PPI_CH23, 23 => static); | 233 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 234 | impl_ppi_channel!(PPI_CH24, 24 => static); | 234 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 235 | impl_ppi_channel!(PPI_CH25, 25 => static); | 235 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 236 | impl_ppi_channel!(PPI_CH26, 26 => static); | 236 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 237 | impl_ppi_channel!(PPI_CH27, 27 => static); | 237 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 238 | impl_ppi_channel!(PPI_CH28, 28 => static); | 238 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 239 | impl_ppi_channel!(PPI_CH29, 29 => static); | 239 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 240 | impl_ppi_channel!(PPI_CH30, 30 => static); | 240 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 241 | impl_ppi_channel!(PPI_CH31, 31 => static); | 241 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 242 | |||
| 243 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 244 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 245 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 246 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 247 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 248 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 242 | 249 | ||
| 243 | impl_radio!(RADIO, RADIO, RADIO); | 250 | impl_radio!(RADIO, RADIO, RADIO); |
| 244 | 251 | ||
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 1598df3fe..06363a467 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -240,38 +240,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 240 | impl_pin!(P0_30, 0, 30); | 240 | impl_pin!(P0_30, 0, 30); |
| 241 | impl_pin!(P0_31, 0, 31); | 241 | impl_pin!(P0_31, 0, 31); |
| 242 | 242 | ||
| 243 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 243 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 244 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 244 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 245 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 245 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 246 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 246 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 247 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 247 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 248 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 248 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 249 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 249 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 250 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 250 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 251 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 251 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 252 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 252 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 253 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 253 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 254 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 254 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 255 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 255 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 256 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 256 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 257 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 257 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 258 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 258 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 259 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 259 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 260 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 260 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 261 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 261 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 262 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 262 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 263 | impl_ppi_channel!(PPI_CH20, 20 => static); | 263 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 264 | impl_ppi_channel!(PPI_CH21, 21 => static); | 264 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 265 | impl_ppi_channel!(PPI_CH22, 22 => static); | 265 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 266 | impl_ppi_channel!(PPI_CH23, 23 => static); | 266 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 267 | impl_ppi_channel!(PPI_CH24, 24 => static); | 267 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 268 | impl_ppi_channel!(PPI_CH25, 25 => static); | 268 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 269 | impl_ppi_channel!(PPI_CH26, 26 => static); | 269 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 270 | impl_ppi_channel!(PPI_CH27, 27 => static); | 270 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 271 | impl_ppi_channel!(PPI_CH28, 28 => static); | 271 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 272 | impl_ppi_channel!(PPI_CH29, 29 => static); | 272 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 273 | impl_ppi_channel!(PPI_CH30, 30 => static); | 273 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 274 | impl_ppi_channel!(PPI_CH31, 31 => static); | 274 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 275 | |||
| 276 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 277 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 278 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 279 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 280 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 281 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 275 | 282 | ||
| 276 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 283 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 277 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 284 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 6931fb064..754943d33 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -282,38 +282,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 282 | impl_pin!(P1_14, 1, 14); | 282 | impl_pin!(P1_14, 1, 14); |
| 283 | impl_pin!(P1_15, 1, 15); | 283 | impl_pin!(P1_15, 1, 15); |
| 284 | 284 | ||
| 285 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 285 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 286 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 286 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 287 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 287 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 288 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 288 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 289 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 289 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 290 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 290 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 291 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 291 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 292 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 292 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 293 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 293 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 294 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 294 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 295 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 295 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 296 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 296 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 297 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 297 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 298 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 298 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 299 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 299 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 300 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 300 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 301 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 301 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 302 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 302 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 303 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 303 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 304 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 304 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 305 | impl_ppi_channel!(PPI_CH20, 20 => static); | 305 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 306 | impl_ppi_channel!(PPI_CH21, 21 => static); | 306 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 307 | impl_ppi_channel!(PPI_CH22, 22 => static); | 307 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 308 | impl_ppi_channel!(PPI_CH23, 23 => static); | 308 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 309 | impl_ppi_channel!(PPI_CH24, 24 => static); | 309 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 310 | impl_ppi_channel!(PPI_CH25, 25 => static); | 310 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 311 | impl_ppi_channel!(PPI_CH26, 26 => static); | 311 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 312 | impl_ppi_channel!(PPI_CH27, 27 => static); | 312 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 313 | impl_ppi_channel!(PPI_CH28, 28 => static); | 313 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 314 | impl_ppi_channel!(PPI_CH29, 29 => static); | 314 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 315 | impl_ppi_channel!(PPI_CH30, 30 => static); | 315 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 316 | impl_ppi_channel!(PPI_CH31, 31 => static); | 316 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 317 | |||
| 318 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 319 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 320 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 321 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 322 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 323 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 317 | 324 | ||
| 318 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 325 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 319 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 326 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 5fa521aae..ac07cd820 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -287,38 +287,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 287 | impl_pin!(P1_14, 1, 14); | 287 | impl_pin!(P1_14, 1, 14); |
| 288 | impl_pin!(P1_15, 1, 15); | 288 | impl_pin!(P1_15, 1, 15); |
| 289 | 289 | ||
| 290 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 290 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 291 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 291 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 292 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 292 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 293 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 293 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 294 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 294 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 295 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 295 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 296 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 296 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 297 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 297 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 298 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 298 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 299 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 299 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 300 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 300 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 301 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 301 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 302 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 302 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 303 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 303 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 304 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 304 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 305 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 305 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 306 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 306 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 307 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 307 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 308 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 308 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 309 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 309 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 310 | impl_ppi_channel!(PPI_CH20, 20 => static); | 310 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 311 | impl_ppi_channel!(PPI_CH21, 21 => static); | 311 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 312 | impl_ppi_channel!(PPI_CH22, 22 => static); | 312 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 313 | impl_ppi_channel!(PPI_CH23, 23 => static); | 313 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 314 | impl_ppi_channel!(PPI_CH24, 24 => static); | 314 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 315 | impl_ppi_channel!(PPI_CH25, 25 => static); | 315 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 316 | impl_ppi_channel!(PPI_CH26, 26 => static); | 316 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 317 | impl_ppi_channel!(PPI_CH27, 27 => static); | 317 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 318 | impl_ppi_channel!(PPI_CH28, 28 => static); | 318 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 319 | impl_ppi_channel!(PPI_CH29, 29 => static); | 319 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 320 | impl_ppi_channel!(PPI_CH30, 30 => static); | 320 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 321 | impl_ppi_channel!(PPI_CH31, 31 => static); | 321 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 322 | |||
| 323 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 324 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 325 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 326 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 327 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 328 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 322 | 329 | ||
| 323 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 330 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 324 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 331 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index 730c9842d..aa51527fb 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs | |||
| @@ -435,38 +435,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 435 | impl_pin!(P1_14, 1, 14); | 435 | impl_pin!(P1_14, 1, 14); |
| 436 | impl_pin!(P1_15, 1, 15); | 436 | impl_pin!(P1_15, 1, 15); |
| 437 | 437 | ||
| 438 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 438 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 439 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 439 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 440 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 440 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 441 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 441 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 442 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 442 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 443 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 443 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 444 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 444 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 445 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 445 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 446 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 446 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 447 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 447 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 448 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 448 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 449 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 449 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 450 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 450 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 451 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 451 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 452 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 452 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 453 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 453 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 454 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 454 | impl_ppi_channel!(PPI_CH16, DPPIC, 16 => configurable); |
| 455 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 455 | impl_ppi_channel!(PPI_CH17, DPPIC, 17 => configurable); |
| 456 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 456 | impl_ppi_channel!(PPI_CH18, DPPIC, 18 => configurable); |
| 457 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 457 | impl_ppi_channel!(PPI_CH19, DPPIC, 19 => configurable); |
| 458 | impl_ppi_channel!(PPI_CH20, 20 => configurable); | 458 | impl_ppi_channel!(PPI_CH20, DPPIC, 20 => configurable); |
| 459 | impl_ppi_channel!(PPI_CH21, 21 => configurable); | 459 | impl_ppi_channel!(PPI_CH21, DPPIC, 21 => configurable); |
| 460 | impl_ppi_channel!(PPI_CH22, 22 => configurable); | 460 | impl_ppi_channel!(PPI_CH22, DPPIC, 22 => configurable); |
| 461 | impl_ppi_channel!(PPI_CH23, 23 => configurable); | 461 | impl_ppi_channel!(PPI_CH23, DPPIC, 23 => configurable); |
| 462 | impl_ppi_channel!(PPI_CH24, 24 => configurable); | 462 | impl_ppi_channel!(PPI_CH24, DPPIC, 24 => configurable); |
| 463 | impl_ppi_channel!(PPI_CH25, 25 => configurable); | 463 | impl_ppi_channel!(PPI_CH25, DPPIC, 25 => configurable); |
| 464 | impl_ppi_channel!(PPI_CH26, 26 => configurable); | 464 | impl_ppi_channel!(PPI_CH26, DPPIC, 26 => configurable); |
| 465 | impl_ppi_channel!(PPI_CH27, 27 => configurable); | 465 | impl_ppi_channel!(PPI_CH27, DPPIC, 27 => configurable); |
| 466 | impl_ppi_channel!(PPI_CH28, 28 => configurable); | 466 | impl_ppi_channel!(PPI_CH28, DPPIC, 28 => configurable); |
| 467 | impl_ppi_channel!(PPI_CH29, 29 => configurable); | 467 | impl_ppi_channel!(PPI_CH29, DPPIC, 29 => configurable); |
| 468 | impl_ppi_channel!(PPI_CH30, 30 => configurable); | 468 | impl_ppi_channel!(PPI_CH30, DPPIC, 30 => configurable); |
| 469 | impl_ppi_channel!(PPI_CH31, 31 => configurable); | 469 | impl_ppi_channel!(PPI_CH31, DPPIC, 31 => configurable); |
| 470 | |||
| 471 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 472 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 473 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 474 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 475 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 476 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 470 | 477 | ||
| 471 | impl_saadc_input!(P0_04, ANALOG_INPUT0); | 478 | impl_saadc_input!(P0_04, ANALOG_INPUT0); |
| 472 | impl_saadc_input!(P0_05, ANALOG_INPUT1); | 479 | impl_saadc_input!(P0_05, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index 413afc5c5..2207e7bda 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs | |||
| @@ -275,38 +275,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 275 | impl_pin!(P1_14, 1, 14); | 275 | impl_pin!(P1_14, 1, 14); |
| 276 | impl_pin!(P1_15, 1, 15); | 276 | impl_pin!(P1_15, 1, 15); |
| 277 | 277 | ||
| 278 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 278 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 279 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 279 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 280 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 280 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 281 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 281 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 282 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 282 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 283 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 283 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 284 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 284 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 285 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 285 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 286 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 286 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 287 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 287 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 288 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 288 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 289 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 289 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 290 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 290 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 291 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 291 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 292 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 292 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 293 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 293 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 294 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 294 | impl_ppi_channel!(PPI_CH16, DPPIC, 16 => configurable); |
| 295 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 295 | impl_ppi_channel!(PPI_CH17, DPPIC, 17 => configurable); |
| 296 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 296 | impl_ppi_channel!(PPI_CH18, DPPIC, 18 => configurable); |
| 297 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 297 | impl_ppi_channel!(PPI_CH19, DPPIC, 19 => configurable); |
| 298 | impl_ppi_channel!(PPI_CH20, 20 => configurable); | 298 | impl_ppi_channel!(PPI_CH20, DPPIC, 20 => configurable); |
| 299 | impl_ppi_channel!(PPI_CH21, 21 => configurable); | 299 | impl_ppi_channel!(PPI_CH21, DPPIC, 21 => configurable); |
| 300 | impl_ppi_channel!(PPI_CH22, 22 => configurable); | 300 | impl_ppi_channel!(PPI_CH22, DPPIC, 22 => configurable); |
| 301 | impl_ppi_channel!(PPI_CH23, 23 => configurable); | 301 | impl_ppi_channel!(PPI_CH23, DPPIC, 23 => configurable); |
| 302 | impl_ppi_channel!(PPI_CH24, 24 => configurable); | 302 | impl_ppi_channel!(PPI_CH24, DPPIC, 24 => configurable); |
| 303 | impl_ppi_channel!(PPI_CH25, 25 => configurable); | 303 | impl_ppi_channel!(PPI_CH25, DPPIC, 25 => configurable); |
| 304 | impl_ppi_channel!(PPI_CH26, 26 => configurable); | 304 | impl_ppi_channel!(PPI_CH26, DPPIC, 26 => configurable); |
| 305 | impl_ppi_channel!(PPI_CH27, 27 => configurable); | 305 | impl_ppi_channel!(PPI_CH27, DPPIC, 27 => configurable); |
| 306 | impl_ppi_channel!(PPI_CH28, 28 => configurable); | 306 | impl_ppi_channel!(PPI_CH28, DPPIC, 28 => configurable); |
| 307 | impl_ppi_channel!(PPI_CH29, 29 => configurable); | 307 | impl_ppi_channel!(PPI_CH29, DPPIC, 29 => configurable); |
| 308 | impl_ppi_channel!(PPI_CH30, 30 => configurable); | 308 | impl_ppi_channel!(PPI_CH30, DPPIC, 30 => configurable); |
| 309 | impl_ppi_channel!(PPI_CH31, 31 => configurable); | 309 | impl_ppi_channel!(PPI_CH31, DPPIC, 31 => configurable); |
| 310 | |||
| 311 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 312 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 313 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 314 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 315 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 316 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 310 | 317 | ||
| 311 | impl_radio!(RADIO, RADIO, RADIO); | 318 | impl_radio!(RADIO, RADIO, RADIO); |
| 312 | 319 | ||
diff --git a/embassy-nrf/src/chips/nrf54l15_app.rs b/embassy-nrf/src/chips/nrf54l15_app.rs index 82d30104f..0724f2ff6 100644 --- a/embassy-nrf/src/chips/nrf54l15_app.rs +++ b/embassy-nrf/src/chips/nrf54l15_app.rs | |||
| @@ -200,13 +200,180 @@ pub mod pac { | |||
| 200 | 200 | ||
| 201 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 201 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 202 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; | 202 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; |
| 203 | //pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; | 203 | pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; |
| 204 | 204 | ||
| 205 | // 1.5 MB NVM | 205 | // 1.5 MB NVM |
| 206 | #[allow(unused)] | 206 | #[allow(unused)] |
| 207 | pub const FLASH_SIZE: usize = 1536 * 1024; | 207 | pub const FLASH_SIZE: usize = 1536 * 1024; |
| 208 | 208 | ||
| 209 | embassy_hal_internal::peripherals! { | 209 | embassy_hal_internal::peripherals! { |
| 210 | // PPI | ||
| 211 | PPI00_CH0, | ||
| 212 | PPI00_CH1, | ||
| 213 | PPI00_CH2, | ||
| 214 | PPI00_CH3, | ||
| 215 | PPI00_CH4, | ||
| 216 | PPI00_CH5, | ||
| 217 | PPI00_CH6, | ||
| 218 | PPI00_CH7, | ||
| 219 | |||
| 220 | PPI10_CH0, | ||
| 221 | PPI10_CH1, | ||
| 222 | PPI10_CH2, | ||
| 223 | PPI10_CH3, | ||
| 224 | PPI10_CH4, | ||
| 225 | PPI10_CH5, | ||
| 226 | PPI10_CH6, | ||
| 227 | PPI10_CH7, | ||
| 228 | PPI10_CH8, | ||
| 229 | PPI10_CH9, | ||
| 230 | PPI10_CH10, | ||
| 231 | PPI10_CH11, | ||
| 232 | PPI10_CH12, | ||
| 233 | PPI10_CH13, | ||
| 234 | PPI10_CH14, | ||
| 235 | PPI10_CH15, | ||
| 236 | PPI10_CH16, | ||
| 237 | PPI10_CH17, | ||
| 238 | PPI10_CH18, | ||
| 239 | PPI10_CH19, | ||
| 240 | PPI10_CH20, | ||
| 241 | PPI10_CH21, | ||
| 242 | PPI10_CH22, | ||
| 243 | PPI10_CH23, | ||
| 244 | |||
| 245 | PPI20_CH0, | ||
| 246 | PPI20_CH1, | ||
| 247 | PPI20_CH2, | ||
| 248 | PPI20_CH3, | ||
| 249 | PPI20_CH4, | ||
| 250 | PPI20_CH5, | ||
| 251 | PPI20_CH6, | ||
| 252 | PPI20_CH7, | ||
| 253 | PPI20_CH8, | ||
| 254 | PPI20_CH9, | ||
| 255 | PPI20_CH10, | ||
| 256 | PPI20_CH11, | ||
| 257 | PPI20_CH12, | ||
| 258 | PPI20_CH13, | ||
| 259 | PPI20_CH14, | ||
| 260 | PPI20_CH15, | ||
| 261 | |||
| 262 | PPI30_CH0, | ||
| 263 | PPI30_CH1, | ||
| 264 | PPI30_CH2, | ||
| 265 | PPI30_CH3, | ||
| 266 | |||
| 267 | PPI00_GROUP0, | ||
| 268 | PPI00_GROUP1, | ||
| 269 | |||
| 270 | PPI10_GROUP0, | ||
| 271 | PPI10_GROUP1, | ||
| 272 | PPI10_GROUP2, | ||
| 273 | PPI10_GROUP3, | ||
| 274 | PPI10_GROUP4, | ||
| 275 | PPI10_GROUP5, | ||
| 276 | |||
| 277 | PPI20_GROUP0, | ||
| 278 | PPI20_GROUP1, | ||
| 279 | PPI20_GROUP2, | ||
| 280 | PPI20_GROUP3, | ||
| 281 | PPI20_GROUP4, | ||
| 282 | PPI20_GROUP5, | ||
| 283 | |||
| 284 | PPI30_GROUP0, | ||
| 285 | PPI30_GROUP1, | ||
| 286 | |||
| 287 | // PPI BRIDGE channels | ||
| 288 | PPIB00_CH0, | ||
| 289 | PPIB00_CH1, | ||
| 290 | PPIB00_CH2, | ||
| 291 | PPIB00_CH3, | ||
| 292 | PPIB00_CH4, | ||
| 293 | PPIB00_CH5, | ||
| 294 | PPIB00_CH6, | ||
| 295 | PPIB00_CH7, | ||
| 296 | |||
| 297 | PPIB01_CH0, | ||
| 298 | PPIB01_CH1, | ||
| 299 | PPIB01_CH2, | ||
| 300 | PPIB01_CH3, | ||
| 301 | PPIB01_CH4, | ||
| 302 | PPIB01_CH5, | ||
| 303 | PPIB01_CH6, | ||
| 304 | PPIB01_CH7, | ||
| 305 | |||
| 306 | PPIB10_CH0, | ||
| 307 | PPIB10_CH1, | ||
| 308 | PPIB10_CH2, | ||
| 309 | PPIB10_CH3, | ||
| 310 | PPIB10_CH4, | ||
| 311 | PPIB10_CH5, | ||
| 312 | PPIB10_CH6, | ||
| 313 | PPIB10_CH7, | ||
| 314 | |||
| 315 | PPIB11_CH0, | ||
| 316 | PPIB11_CH1, | ||
| 317 | PPIB11_CH2, | ||
| 318 | PPIB11_CH3, | ||
| 319 | PPIB11_CH4, | ||
| 320 | PPIB11_CH5, | ||
| 321 | PPIB11_CH6, | ||
| 322 | PPIB11_CH7, | ||
| 323 | PPIB11_CH8, | ||
| 324 | PPIB11_CH9, | ||
| 325 | PPIB11_CH10, | ||
| 326 | PPIB11_CH11, | ||
| 327 | PPIB11_CH12, | ||
| 328 | PPIB11_CH13, | ||
| 329 | PPIB11_CH14, | ||
| 330 | PPIB11_CH15, | ||
| 331 | |||
| 332 | PPIB20_CH0, | ||
| 333 | PPIB20_CH1, | ||
| 334 | PPIB20_CH2, | ||
| 335 | PPIB20_CH3, | ||
| 336 | PPIB20_CH4, | ||
| 337 | PPIB20_CH5, | ||
| 338 | PPIB20_CH6, | ||
| 339 | PPIB20_CH7, | ||
| 340 | |||
| 341 | PPIB21_CH0, | ||
| 342 | PPIB21_CH1, | ||
| 343 | PPIB21_CH2, | ||
| 344 | PPIB21_CH3, | ||
| 345 | PPIB21_CH4, | ||
| 346 | PPIB21_CH5, | ||
| 347 | PPIB21_CH6, | ||
| 348 | PPIB21_CH7, | ||
| 349 | PPIB21_CH8, | ||
| 350 | PPIB21_CH9, | ||
| 351 | PPIB21_CH10, | ||
| 352 | PPIB21_CH11, | ||
| 353 | PPIB21_CH12, | ||
| 354 | PPIB21_CH13, | ||
| 355 | PPIB21_CH14, | ||
| 356 | PPIB21_CH15, | ||
| 357 | |||
| 358 | PPIB22_CH0, | ||
| 359 | PPIB22_CH1, | ||
| 360 | PPIB22_CH2, | ||
| 361 | PPIB22_CH3, | ||
| 362 | |||
| 363 | PPIB30_CH0, | ||
| 364 | PPIB30_CH1, | ||
| 365 | PPIB30_CH2, | ||
| 366 | PPIB30_CH3, | ||
| 367 | |||
| 368 | // Timers | ||
| 369 | TIMER00, | ||
| 370 | TIMER10, | ||
| 371 | TIMER20, | ||
| 372 | TIMER21, | ||
| 373 | TIMER22, | ||
| 374 | TIMER23, | ||
| 375 | TIMER24, | ||
| 376 | |||
| 210 | // GPIO port 0 | 377 | // GPIO port 0 |
| 211 | P0_00, | 378 | P0_00, |
| 212 | P0_01, | 379 | P0_01, |
| @@ -249,6 +416,54 @@ embassy_hal_internal::peripherals! { | |||
| 249 | P2_09, | 416 | P2_09, |
| 250 | P2_10, | 417 | P2_10, |
| 251 | 418 | ||
| 419 | // GRTC | ||
| 420 | GRTC, | ||
| 421 | |||
| 422 | // RTC | ||
| 423 | RTC10, | ||
| 424 | RTC30, | ||
| 425 | |||
| 426 | // PWM | ||
| 427 | PWM20, | ||
| 428 | PWM21, | ||
| 429 | PWM22, | ||
| 430 | |||
| 431 | // SERIAL | ||
| 432 | SERIAL00, | ||
| 433 | SERIAL20, | ||
| 434 | SERIAL21, | ||
| 435 | SERIAL22, | ||
| 436 | SERIAL30, | ||
| 437 | |||
| 438 | // SAADC | ||
| 439 | SAADC, | ||
| 440 | |||
| 441 | // RADIO | ||
| 442 | RADIO, | ||
| 443 | |||
| 444 | |||
| 445 | // GPIOTE instances | ||
| 446 | GPIOTE20, | ||
| 447 | GPIOTE30, | ||
| 448 | |||
| 449 | // GPIOTE channels | ||
| 450 | GPIOTE20_CH0, | ||
| 451 | GPIOTE20_CH1, | ||
| 452 | GPIOTE20_CH2, | ||
| 453 | GPIOTE20_CH3, | ||
| 454 | GPIOTE20_CH4, | ||
| 455 | GPIOTE20_CH5, | ||
| 456 | GPIOTE20_CH6, | ||
| 457 | GPIOTE20_CH7, | ||
| 458 | GPIOTE30_CH0, | ||
| 459 | GPIOTE30_CH1, | ||
| 460 | GPIOTE30_CH2, | ||
| 461 | GPIOTE30_CH3, | ||
| 462 | |||
| 463 | // CRACEN | ||
| 464 | #[cfg(feature = "_s")] | ||
| 465 | CRACEN, | ||
| 466 | |||
| 252 | #[cfg(feature = "_s")] | 467 | #[cfg(feature = "_s")] |
| 253 | // RRAMC | 468 | // RRAMC |
| 254 | RRAMC, | 469 | RRAMC, |
| @@ -303,12 +518,173 @@ impl_pin!(P2_08, 2, 8); | |||
| 303 | impl_pin!(P2_09, 2, 9); | 518 | impl_pin!(P2_09, 2, 9); |
| 304 | impl_pin!(P2_10, 2, 10); | 519 | impl_pin!(P2_10, 2, 10); |
| 305 | 520 | ||
| 521 | cfg_if::cfg_if! { | ||
| 522 | if #[cfg(feature = "gpiote")] { | ||
| 523 | impl_gpiote_pin!(P0_00, GPIOTE30); | ||
| 524 | impl_gpiote_pin!(P0_01, GPIOTE30); | ||
| 525 | impl_gpiote_pin!(P0_02, GPIOTE30); | ||
| 526 | impl_gpiote_pin!(P0_03, GPIOTE30); | ||
| 527 | impl_gpiote_pin!(P0_04, GPIOTE30); | ||
| 528 | impl_gpiote_pin!(P0_05, GPIOTE30); | ||
| 529 | impl_gpiote_pin!(P0_06, GPIOTE30); | ||
| 530 | |||
| 531 | impl_gpiote_pin!(P1_00, GPIOTE20); | ||
| 532 | impl_gpiote_pin!(P1_01, GPIOTE20); | ||
| 533 | impl_gpiote_pin!(P1_02, GPIOTE20); | ||
| 534 | impl_gpiote_pin!(P1_03, GPIOTE20); | ||
| 535 | impl_gpiote_pin!(P1_04, GPIOTE20); | ||
| 536 | impl_gpiote_pin!(P1_05, GPIOTE20); | ||
| 537 | impl_gpiote_pin!(P1_06, GPIOTE20); | ||
| 538 | impl_gpiote_pin!(P1_07, GPIOTE20); | ||
| 539 | impl_gpiote_pin!(P1_08, GPIOTE20); | ||
| 540 | impl_gpiote_pin!(P1_09, GPIOTE20); | ||
| 541 | impl_gpiote_pin!(P1_10, GPIOTE20); | ||
| 542 | impl_gpiote_pin!(P1_11, GPIOTE20); | ||
| 543 | impl_gpiote_pin!(P1_12, GPIOTE20); | ||
| 544 | impl_gpiote_pin!(P1_13, GPIOTE20); | ||
| 545 | impl_gpiote_pin!(P1_14, GPIOTE20); | ||
| 546 | impl_gpiote_pin!(P1_15, GPIOTE20); | ||
| 547 | impl_gpiote_pin!(P1_16, GPIOTE20); | ||
| 548 | } | ||
| 549 | } | ||
| 550 | |||
| 551 | impl_rtc!(RTC10, RTC10, RTC10); | ||
| 552 | impl_rtc!(RTC30, RTC30, RTC30); | ||
| 553 | |||
| 306 | #[cfg(feature = "_ns")] | 554 | #[cfg(feature = "_ns")] |
| 307 | impl_wdt!(WDT, WDT31, WDT31, 0); | 555 | impl_wdt!(WDT, WDT31, WDT31, 0); |
| 308 | #[cfg(feature = "_s")] | 556 | #[cfg(feature = "_s")] |
| 309 | impl_wdt!(WDT0, WDT31, WDT31, 0); | 557 | impl_wdt!(WDT0, WDT31, WDT31, 0); |
| 310 | #[cfg(feature = "_s")] | 558 | #[cfg(feature = "_s")] |
| 311 | impl_wdt!(WDT1, WDT30, WDT30, 1); | 559 | impl_wdt!(WDT1, WDT30, WDT30, 1); |
| 560 | // DPPI00 channels | ||
| 561 | impl_ppi_channel!(PPI00_CH0, DPPIC00, 0 => configurable); | ||
| 562 | impl_ppi_channel!(PPI00_CH1, DPPIC00, 1 => configurable); | ||
| 563 | impl_ppi_channel!(PPI00_CH2, DPPIC00, 2 => configurable); | ||
| 564 | impl_ppi_channel!(PPI00_CH3, DPPIC00, 3 => configurable); | ||
| 565 | impl_ppi_channel!(PPI00_CH4, DPPIC00, 4 => configurable); | ||
| 566 | impl_ppi_channel!(PPI00_CH5, DPPIC00, 5 => configurable); | ||
| 567 | impl_ppi_channel!(PPI00_CH6, DPPIC00, 6 => configurable); | ||
| 568 | impl_ppi_channel!(PPI00_CH7, DPPIC00, 7 => configurable); | ||
| 569 | |||
| 570 | // DPPI10 channels | ||
| 571 | impl_ppi_channel!(PPI10_CH0, DPPIC10, 0 => static); | ||
| 572 | |||
| 573 | // DPPI20 channels | ||
| 574 | impl_ppi_channel!(PPI20_CH0, DPPIC20, 0 => configurable); | ||
| 575 | impl_ppi_channel!(PPI20_CH1, DPPIC20, 1 => configurable); | ||
| 576 | impl_ppi_channel!(PPI20_CH2, DPPIC20, 2 => configurable); | ||
| 577 | impl_ppi_channel!(PPI20_CH3, DPPIC20, 3 => configurable); | ||
| 578 | impl_ppi_channel!(PPI20_CH4, DPPIC20, 4 => configurable); | ||
| 579 | impl_ppi_channel!(PPI20_CH5, DPPIC20, 5 => configurable); | ||
| 580 | impl_ppi_channel!(PPI20_CH6, DPPIC20, 6 => configurable); | ||
| 581 | impl_ppi_channel!(PPI20_CH7, DPPIC20, 7 => configurable); | ||
| 582 | impl_ppi_channel!(PPI20_CH8, DPPIC20, 8 => configurable); | ||
| 583 | impl_ppi_channel!(PPI20_CH9, DPPIC20, 9 => configurable); | ||
| 584 | impl_ppi_channel!(PPI20_CH10, DPPIC20, 10 => configurable); | ||
| 585 | impl_ppi_channel!(PPI20_CH11, DPPIC20, 11 => configurable); | ||
| 586 | impl_ppi_channel!(PPI20_CH12, DPPIC20, 12 => configurable); | ||
| 587 | impl_ppi_channel!(PPI20_CH13, DPPIC20, 13 => configurable); | ||
| 588 | impl_ppi_channel!(PPI20_CH14, DPPIC20, 14 => configurable); | ||
| 589 | impl_ppi_channel!(PPI20_CH15, DPPIC20, 15 => configurable); | ||
| 590 | |||
| 591 | // DPPI30 channels | ||
| 592 | impl_ppi_channel!(PPI30_CH0, DPPIC30, 0 => configurable); | ||
| 593 | impl_ppi_channel!(PPI30_CH1, DPPIC30, 1 => configurable); | ||
| 594 | impl_ppi_channel!(PPI30_CH2, DPPIC30, 2 => configurable); | ||
| 595 | impl_ppi_channel!(PPI30_CH3, DPPIC30, 3 => configurable); | ||
| 596 | |||
| 597 | // DPPI00 groups | ||
| 598 | impl_ppi_group!(PPI00_GROUP0, DPPIC00, 0); | ||
| 599 | impl_ppi_group!(PPI00_GROUP1, DPPIC00, 1); | ||
| 600 | |||
| 601 | // DPPI10 groups | ||
| 602 | impl_ppi_group!(PPI10_GROUP0, DPPIC10, 0); | ||
| 603 | |||
| 604 | // DPPI20 groups | ||
| 605 | impl_ppi_group!(PPI20_GROUP0, DPPIC20, 0); | ||
| 606 | impl_ppi_group!(PPI20_GROUP1, DPPIC20, 1); | ||
| 607 | impl_ppi_group!(PPI20_GROUP2, DPPIC20, 2); | ||
| 608 | impl_ppi_group!(PPI20_GROUP3, DPPIC20, 3); | ||
| 609 | impl_ppi_group!(PPI20_GROUP4, DPPIC20, 4); | ||
| 610 | impl_ppi_group!(PPI20_GROUP5, DPPIC20, 5); | ||
| 611 | |||
| 612 | // DPPI30 groups | ||
| 613 | impl_ppi_group!(PPI30_GROUP0, DPPIC30, 0); | ||
| 614 | impl_ppi_group!(PPI30_GROUP1, DPPIC30, 1); | ||
| 615 | |||
| 616 | impl_timer!(TIMER00, TIMER00, TIMER00); | ||
| 617 | impl_timer!(TIMER10, TIMER10, TIMER10); | ||
| 618 | impl_timer!(TIMER20, TIMER20, TIMER20); | ||
| 619 | impl_timer!(TIMER21, TIMER21, TIMER21); | ||
| 620 | impl_timer!(TIMER22, TIMER22, TIMER22); | ||
| 621 | impl_timer!(TIMER23, TIMER23, TIMER23); | ||
| 622 | impl_timer!(TIMER24, TIMER24, TIMER24); | ||
| 623 | |||
| 624 | impl_twim!(SERIAL20, TWIM20, SERIAL20); | ||
| 625 | impl_twim!(SERIAL21, TWIM21, SERIAL21); | ||
| 626 | impl_twim!(SERIAL22, TWIM22, SERIAL22); | ||
| 627 | impl_twim!(SERIAL30, TWIM30, SERIAL30); | ||
| 628 | |||
| 629 | impl_twis!(SERIAL20, TWIS20, SERIAL20); | ||
| 630 | impl_twis!(SERIAL21, TWIS21, SERIAL21); | ||
| 631 | impl_twis!(SERIAL22, TWIS22, SERIAL22); | ||
| 632 | impl_twis!(SERIAL30, TWIS30, SERIAL30); | ||
| 633 | |||
| 634 | impl_pwm!(PWM20, PWM20, PWM20); | ||
| 635 | impl_pwm!(PWM21, PWM21, PWM21); | ||
| 636 | impl_pwm!(PWM22, PWM22, PWM22); | ||
| 637 | |||
| 638 | #[cfg(feature = "_s")] | ||
| 639 | impl_spim!( | ||
| 640 | SERIAL00, | ||
| 641 | SPIM00, | ||
| 642 | SERIAL00, | ||
| 643 | match pac::OSCILLATORS_S.pll().currentfreq().read().currentfreq() { | ||
| 644 | pac::oscillators::vals::Currentfreq::CK128M => 128_000_000, | ||
| 645 | pac::oscillators::vals::Currentfreq::CK64M => 64_000_000, | ||
| 646 | _ => unreachable!(), | ||
| 647 | } | ||
| 648 | ); | ||
| 649 | #[cfg(feature = "_ns")] | ||
| 650 | impl_spim!( | ||
| 651 | SERIAL00, | ||
| 652 | SPIM00, | ||
| 653 | SERIAL00, | ||
| 654 | match pac::OSCILLATORS_NS.pll().currentfreq().read().currentfreq() { | ||
| 655 | pac::oscillators::vals::Currentfreq::CK128M => 128_000_000, | ||
| 656 | pac::oscillators::vals::Currentfreq::CK64M => 64_000_000, | ||
| 657 | _ => unreachable!(), | ||
| 658 | } | ||
| 659 | ); | ||
| 660 | impl_spim!(SERIAL20, SPIM20, SERIAL20, 16_000_000); | ||
| 661 | impl_spim!(SERIAL21, SPIM21, SERIAL21, 16_000_000); | ||
| 662 | impl_spim!(SERIAL22, SPIM22, SERIAL22, 16_000_000); | ||
| 663 | impl_spim!(SERIAL30, SPIM30, SERIAL30, 16_000_000); | ||
| 664 | |||
| 665 | impl_spis!(SERIAL20, SPIS20, SERIAL20); | ||
| 666 | impl_spis!(SERIAL21, SPIS21, SERIAL21); | ||
| 667 | impl_spis!(SERIAL22, SPIS22, SERIAL22); | ||
| 668 | impl_spis!(SERIAL30, SPIS30, SERIAL30); | ||
| 669 | |||
| 670 | impl_uarte!(SERIAL00, UARTE00, SERIAL00); | ||
| 671 | impl_uarte!(SERIAL20, UARTE20, SERIAL20); | ||
| 672 | impl_uarte!(SERIAL21, UARTE21, SERIAL21); | ||
| 673 | impl_uarte!(SERIAL22, UARTE22, SERIAL22); | ||
| 674 | impl_uarte!(SERIAL30, UARTE30, SERIAL30); | ||
| 675 | |||
| 676 | // NB: SAADC uses "pin" abstraction, not "AIN" | ||
| 677 | impl_saadc_input!(P1_04, 1, 4); | ||
| 678 | impl_saadc_input!(P1_05, 1, 5); | ||
| 679 | impl_saadc_input!(P1_06, 1, 6); | ||
| 680 | impl_saadc_input!(P1_07, 1, 7); | ||
| 681 | impl_saadc_input!(P1_11, 1, 11); | ||
| 682 | impl_saadc_input!(P1_12, 1, 12); | ||
| 683 | impl_saadc_input!(P1_13, 1, 13); | ||
| 684 | impl_saadc_input!(P1_14, 1, 14); | ||
| 685 | |||
| 686 | #[cfg(feature = "_s")] | ||
| 687 | impl_cracen!(CRACEN, CRACEN, CRACEN); | ||
| 312 | 688 | ||
| 313 | embassy_hal_internal::interrupt_mod!( | 689 | embassy_hal_internal::interrupt_mod!( |
| 314 | SWI00, | 690 | SWI00, |
diff --git a/embassy-nrf/src/chips/nrf9120.rs b/embassy-nrf/src/chips/nrf9120.rs index 5aee19d97..e9f313fef 100644 --- a/embassy-nrf/src/chips/nrf9120.rs +++ b/embassy-nrf/src/chips/nrf9120.rs | |||
| @@ -314,22 +314,29 @@ impl_pin!(P0_29, 0, 29); | |||
| 314 | impl_pin!(P0_30, 0, 30); | 314 | impl_pin!(P0_30, 0, 30); |
| 315 | impl_pin!(P0_31, 0, 31); | 315 | impl_pin!(P0_31, 0, 31); |
| 316 | 316 | ||
| 317 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 317 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 318 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 318 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 319 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 319 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 320 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 320 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 321 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 321 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 322 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 322 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 323 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 323 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 324 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 324 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 325 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 325 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 326 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 326 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 327 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 327 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 328 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 328 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 329 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 329 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 330 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 330 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 331 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 331 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 332 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 332 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 333 | |||
| 334 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 335 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 336 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 337 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 338 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 339 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 333 | 340 | ||
| 334 | impl_saadc_input!(P0_13, ANALOG_INPUT0); | 341 | impl_saadc_input!(P0_13, ANALOG_INPUT0); |
| 335 | impl_saadc_input!(P0_14, ANALOG_INPUT1); | 342 | impl_saadc_input!(P0_14, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 64aec217c..4c6f055dd 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs | |||
| @@ -314,22 +314,29 @@ impl_pin!(P0_29, 0, 29); | |||
| 314 | impl_pin!(P0_30, 0, 30); | 314 | impl_pin!(P0_30, 0, 30); |
| 315 | impl_pin!(P0_31, 0, 31); | 315 | impl_pin!(P0_31, 0, 31); |
| 316 | 316 | ||
| 317 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 317 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 318 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 318 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 319 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 319 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 320 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 320 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 321 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 321 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 322 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 322 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 323 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 323 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 324 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 324 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 325 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 325 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 326 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 326 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 327 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 327 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 328 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 328 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 329 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 329 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 330 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 330 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 331 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 331 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 332 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 332 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 333 | |||
| 334 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 335 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 336 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 337 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 338 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 339 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 333 | 340 | ||
| 334 | impl_saadc_input!(P0_13, ANALOG_INPUT0); | 341 | impl_saadc_input!(P0_13, ANALOG_INPUT0); |
| 335 | impl_saadc_input!(P0_14, ANALOG_INPUT1); | 342 | impl_saadc_input!(P0_14, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/cracen.rs b/embassy-nrf/src/cracen.rs new file mode 100644 index 000000000..47ef1cd87 --- /dev/null +++ b/embassy-nrf/src/cracen.rs | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | //! CRACEN - Cryptographic Accelerator Engine driver. | ||
| 2 | |||
| 3 | #![macro_use] | ||
| 4 | |||
| 5 | use core::marker::PhantomData; | ||
| 6 | |||
| 7 | use crate::mode::{Blocking, Mode}; | ||
| 8 | use crate::{Peri, interrupt, pac, peripherals}; | ||
| 9 | |||
| 10 | /// A wrapper around an nRF54 CRACEN peripheral. | ||
| 11 | /// | ||
| 12 | /// It has a blocking api through `rand`. | ||
| 13 | pub struct Cracen<'d, M: Mode> { | ||
| 14 | _peri: Peri<'d, peripherals::CRACEN>, | ||
| 15 | _p: PhantomData<M>, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<'d> Cracen<'d, Blocking> { | ||
| 19 | /// Create a new CRACEN driver. | ||
| 20 | pub fn new_blocking(_peri: Peri<'d, peripherals::CRACEN>) -> Self { | ||
| 21 | let me = Self { _peri, _p: PhantomData }; | ||
| 22 | |||
| 23 | me.stop(); | ||
| 24 | me | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | impl<'d, M: Mode> Cracen<'d, M> { | ||
| 29 | fn regs() -> pac::cracen::Cracen { | ||
| 30 | pac::CRACEN | ||
| 31 | } | ||
| 32 | |||
| 33 | fn core() -> pac::cracencore::Cracencore { | ||
| 34 | pac::CRACENCORE | ||
| 35 | } | ||
| 36 | |||
| 37 | fn start_rng(&self) { | ||
| 38 | let r = Self::regs(); | ||
| 39 | r.enable().write(|w| { | ||
| 40 | w.set_rng(true); | ||
| 41 | }); | ||
| 42 | |||
| 43 | let r = Self::core(); | ||
| 44 | r.rngcontrol().control().write(|w| { | ||
| 45 | w.set_enable(true); | ||
| 46 | }); | ||
| 47 | |||
| 48 | while r.rngcontrol().status().read().state() == pac::cracencore::vals::State::STARTUP {} | ||
| 49 | } | ||
| 50 | |||
| 51 | fn stop(&self) { | ||
| 52 | let r = Self::regs(); | ||
| 53 | r.enable().write(|w| { | ||
| 54 | w.set_cryptomaster(false); | ||
| 55 | w.set_rng(false); | ||
| 56 | w.set_pkeikg(false); | ||
| 57 | }); | ||
| 58 | } | ||
| 59 | |||
| 60 | /// Fill the buffer with random bytes, blocking version. | ||
| 61 | pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) { | ||
| 62 | self.start_rng(); | ||
| 63 | |||
| 64 | let r = Self::core(); | ||
| 65 | for chunk in dest.chunks_mut(4) { | ||
| 66 | while r.rngcontrol().fifolevel().read() == 0 {} | ||
| 67 | let word = r.rngcontrol().fifo(0).read().to_ne_bytes(); | ||
| 68 | let to_copy = word.len().min(chunk.len()); | ||
| 69 | chunk[..to_copy].copy_from_slice(&word[..to_copy]); | ||
| 70 | } | ||
| 71 | |||
| 72 | self.stop(); | ||
| 73 | } | ||
| 74 | |||
| 75 | /// Generate a random u32 | ||
| 76 | pub fn blocking_next_u32(&mut self) -> u32 { | ||
| 77 | let mut bytes = [0; 4]; | ||
| 78 | self.blocking_fill_bytes(&mut bytes); | ||
| 79 | // We don't care about the endianness, so just use the native one. | ||
| 80 | u32::from_ne_bytes(bytes) | ||
| 81 | } | ||
| 82 | |||
| 83 | /// Generate a random u64 | ||
| 84 | pub fn blocking_next_u64(&mut self) -> u64 { | ||
| 85 | let mut bytes = [0; 8]; | ||
| 86 | self.blocking_fill_bytes(&mut bytes); | ||
| 87 | u64::from_ne_bytes(bytes) | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | impl<'d, M: Mode> Drop for Cracen<'d, M> { | ||
| 92 | fn drop(&mut self) { | ||
| 93 | let r = Self::core(); | ||
| 94 | r.rngcontrol().control().write(|w| { | ||
| 95 | w.set_enable(false); | ||
| 96 | }); | ||
| 97 | |||
| 98 | while r.rngcontrol().status().read().state() != pac::cracencore::vals::State::RESET {} | ||
| 99 | |||
| 100 | let r = Self::regs(); | ||
| 101 | r.enable().write(|w| { | ||
| 102 | w.set_cryptomaster(false); | ||
| 103 | w.set_rng(false); | ||
| 104 | w.set_pkeikg(false); | ||
| 105 | }); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | impl<'d, M: Mode> rand_core_06::RngCore for Cracen<'d, M> { | ||
| 110 | fn fill_bytes(&mut self, dest: &mut [u8]) { | ||
| 111 | self.blocking_fill_bytes(dest); | ||
| 112 | } | ||
| 113 | fn next_u32(&mut self) -> u32 { | ||
| 114 | self.blocking_next_u32() | ||
| 115 | } | ||
| 116 | fn next_u64(&mut self) -> u64 { | ||
| 117 | self.blocking_next_u64() | ||
| 118 | } | ||
| 119 | fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { | ||
| 120 | self.blocking_fill_bytes(dest); | ||
| 121 | Ok(()) | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | impl<'d, M: Mode> rand_core_06::CryptoRng for Cracen<'d, M> {} | ||
| 126 | |||
| 127 | impl<'d, M: Mode> rand_core_09::RngCore for Cracen<'d, M> { | ||
| 128 | fn fill_bytes(&mut self, dest: &mut [u8]) { | ||
| 129 | self.blocking_fill_bytes(dest); | ||
| 130 | } | ||
| 131 | fn next_u32(&mut self) -> u32 { | ||
| 132 | self.blocking_next_u32() | ||
| 133 | } | ||
| 134 | fn next_u64(&mut self) -> u64 { | ||
| 135 | self.blocking_next_u64() | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | impl<'d, M: Mode> rand_core_09::CryptoRng for Cracen<'d, M> {} | ||
| 140 | |||
| 141 | pub(crate) trait SealedInstance {} | ||
| 142 | |||
| 143 | /// CRACEN peripheral instance. | ||
| 144 | #[allow(private_bounds)] | ||
| 145 | pub trait Instance: SealedInstance + 'static + Send { | ||
| 146 | /// Interrupt for this peripheral. | ||
| 147 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 148 | } | ||
| 149 | |||
| 150 | macro_rules! impl_cracen { | ||
| 151 | ($type:ident, $pac_type:ident, $irq:ident) => { | ||
| 152 | impl crate::cracen::SealedInstance for peripherals::$type {} | ||
| 153 | impl crate::cracen::Instance for peripherals::$type { | ||
| 154 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 155 | } | ||
| 156 | }; | ||
| 157 | } | ||
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 7ed3a7927..43d1b9cb2 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -585,7 +585,6 @@ impl SealedPin for AnyPin { | |||
| 585 | // ==================== | 585 | // ==================== |
| 586 | 586 | ||
| 587 | #[cfg(not(feature = "_nrf51"))] | 587 | #[cfg(not(feature = "_nrf51"))] |
| 588 | #[cfg_attr(feature = "_nrf54l", allow(unused))] // TODO | ||
| 589 | pub(crate) trait PselBits { | 588 | pub(crate) trait PselBits { |
| 590 | fn psel_bits(&self) -> pac::shared::regs::Psel; | 589 | fn psel_bits(&self) -> pac::shared::regs::Psel; |
| 591 | } | 590 | } |
| @@ -602,7 +601,6 @@ impl<'a, P: Pin> PselBits for Option<Peri<'a, P>> { | |||
| 602 | } | 601 | } |
| 603 | 602 | ||
| 604 | #[cfg(not(feature = "_nrf51"))] | 603 | #[cfg(not(feature = "_nrf51"))] |
| 605 | #[cfg_attr(feature = "_nrf54l", allow(unused))] // TODO | ||
| 606 | pub(crate) const DISCONNECTED: Psel = Psel(1 << 31); | 604 | pub(crate) const DISCONNECTED: Psel = Psel(1 << 31); |
| 607 | 605 | ||
| 608 | #[cfg(not(feature = "_nrf51"))] | 606 | #[cfg(not(feature = "_nrf51"))] |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index a490d5b60..91944d8cd 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | //! GPIO task/event (GPIOTE) driver. | 1 | //! GPIO task/event (GPIOTE) driver. |
| 2 | #![macro_use] | ||
| 2 | 3 | ||
| 3 | use core::convert::Infallible; | 4 | use core::convert::Infallible; |
| 4 | use core::future::{Future, poll_fn}; | 5 | use core::future::{Future, poll_fn}; |
| @@ -7,7 +8,7 @@ use core::task::{Context, Poll}; | |||
| 7 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; | 8 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 10 | ||
| 10 | use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; | 11 | use crate::gpio::{AnyPin, Flex, Input, Level, Output, OutputDrive, Pin as GpioPin, Pull, SealedPin as _}; |
| 11 | use crate::interrupt::InterruptExt; | 12 | use crate::interrupt::InterruptExt; |
| 12 | #[cfg(not(feature = "_nrf51"))] | 13 | #[cfg(not(feature = "_nrf51"))] |
| 13 | use crate::pac::gpio::vals::Detectmode; | 14 | use crate::pac::gpio::vals::Detectmode; |
| @@ -19,13 +20,28 @@ use crate::{interrupt, pac, peripherals}; | |||
| 19 | #[cfg(feature = "_nrf51")] | 20 | #[cfg(feature = "_nrf51")] |
| 20 | /// Amount of GPIOTE channels in the chip. | 21 | /// Amount of GPIOTE channels in the chip. |
| 21 | const CHANNEL_COUNT: usize = 4; | 22 | const CHANNEL_COUNT: usize = 4; |
| 22 | #[cfg(not(feature = "_nrf51"))] | 23 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] |
| 23 | /// Amount of GPIOTE channels in the chip. | 24 | /// Amount of GPIOTE channels in the chip. |
| 24 | const CHANNEL_COUNT: usize = 8; | 25 | const CHANNEL_COUNT: usize = 8; |
| 25 | 26 | #[cfg(any(feature = "_nrf54l"))] | |
| 26 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 27 | /// Amount of GPIOTE channels in the chip. |
| 28 | const CHANNEL_COUNT: usize = 12; | ||
| 29 | /// Max channels per port | ||
| 30 | const CHANNELS_PER_PORT: usize = 8; | ||
| 31 | |||
| 32 | #[cfg(any( | ||
| 33 | feature = "nrf52833", | ||
| 34 | feature = "nrf52840", | ||
| 35 | feature = "_nrf5340", | ||
| 36 | feature = "_nrf54l" | ||
| 37 | ))] | ||
| 27 | const PIN_COUNT: usize = 48; | 38 | const PIN_COUNT: usize = 48; |
| 28 | #[cfg(not(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] | 39 | #[cfg(not(any( |
| 40 | feature = "nrf52833", | ||
| 41 | feature = "nrf52840", | ||
| 42 | feature = "_nrf5340", | ||
| 43 | feature = "_nrf54l" | ||
| 44 | )))] | ||
| 29 | const PIN_COUNT: usize = 32; | 45 | const PIN_COUNT: usize = 32; |
| 30 | 46 | ||
| 31 | #[allow(clippy::declare_interior_mutable_const)] | 47 | #[allow(clippy::declare_interior_mutable_const)] |
| @@ -54,18 +70,6 @@ pub enum OutputChannelPolarity { | |||
| 54 | Toggle, | 70 | Toggle, |
| 55 | } | 71 | } |
| 56 | 72 | ||
| 57 | fn regs() -> pac::gpiote::Gpiote { | ||
| 58 | cfg_if::cfg_if! { | ||
| 59 | if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s", feature="nrf9120-s"))] { | ||
| 60 | pac::GPIOTE0 | ||
| 61 | } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns", feature="nrf9120-ns"))] { | ||
| 62 | pac::GPIOTE1 | ||
| 63 | } else { | ||
| 64 | pac::GPIOTE | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | 73 | pub(crate) fn init(irq_prio: crate::interrupt::Priority) { |
| 70 | // no latched GPIO detect in nrf51. | 74 | // no latched GPIO detect in nrf51. |
| 71 | #[cfg(not(feature = "_nrf51"))] | 75 | #[cfg(not(feature = "_nrf51"))] |
| @@ -77,6 +81,9 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | |||
| 77 | 81 | ||
| 78 | for &p in ports { | 82 | for &p in ports { |
| 79 | // Enable latched detection | 83 | // Enable latched detection |
| 84 | #[cfg(all(feature = "_s", not(feature = "_nrf54l")))] | ||
| 85 | p.detectmode_sec().write(|w| w.set_detectmode(Detectmode::LDETECT)); | ||
| 86 | #[cfg(any(not(feature = "_s"), all(feature = "_s", feature = "_nrf54l")))] | ||
| 80 | p.detectmode().write(|w| w.set_detectmode(Detectmode::LDETECT)); | 87 | p.detectmode().write(|w| w.set_detectmode(Detectmode::LDETECT)); |
| 81 | // Clear latch | 88 | // Clear latch |
| 82 | p.latch().write(|w| w.0 = 0xFFFFFFFF) | 89 | p.latch().write(|w| w.0 = 0xFFFFFFFF) |
| @@ -85,57 +92,130 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | |||
| 85 | 92 | ||
| 86 | // Enable interrupts | 93 | // Enable interrupts |
| 87 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] | 94 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] |
| 88 | let irq = interrupt::GPIOTE0; | 95 | let irqs = &[(pac::GPIOTE0, interrupt::GPIOTE0)]; |
| 89 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] | 96 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] |
| 90 | let irq = interrupt::GPIOTE1; | 97 | let irqs = &[(pac::GPIOTE1, interrupt::GPIOTE1)]; |
| 91 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] | 98 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] |
| 92 | let irq = interrupt::GPIOTE; | 99 | let irqs = &[(pac::GPIOTE, interrupt::GPIOTE)]; |
| 100 | #[cfg(any(feature = "_nrf54l"))] | ||
| 101 | let irqs = &[ | ||
| 102 | #[cfg(feature = "_s")] | ||
| 103 | (pac::GPIOTE20, interrupt::GPIOTE20_0), | ||
| 104 | #[cfg(feature = "_s")] | ||
| 105 | (pac::GPIOTE30, interrupt::GPIOTE30_0), | ||
| 106 | #[cfg(feature = "_ns")] | ||
| 107 | (pac::GPIOTE20, interrupt::GPIOTE20_1), | ||
| 108 | #[cfg(feature = "_ns")] | ||
| 109 | (pac::GPIOTE30, interrupt::GPIOTE30_1), | ||
| 110 | ]; | ||
| 111 | |||
| 112 | for (inst, irq) in irqs { | ||
| 113 | irq.unpend(); | ||
| 114 | irq.set_priority(irq_prio); | ||
| 115 | unsafe { irq.enable() }; | ||
| 93 | 116 | ||
| 94 | irq.unpend(); | 117 | let g = inst; |
| 95 | irq.set_priority(irq_prio); | 118 | #[cfg(not(feature = "_nrf54l"))] |
| 96 | unsafe { irq.enable() }; | 119 | g.intenset(INTNUM).write(|w| w.set_port(true)); |
| 97 | 120 | ||
| 98 | let g = regs(); | 121 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] |
| 99 | g.intenset().write(|w| w.set_port(true)); | 122 | g.intenset(INTNUM).write(|w| w.set_port0nonsecure(true)); |
| 123 | |||
| 124 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | ||
| 125 | g.intenset(INTNUM).write(|w| w.set_port0secure(true)); | ||
| 126 | } | ||
| 100 | } | 127 | } |
| 101 | 128 | ||
| 129 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] | ||
| 130 | const INTNUM: usize = 1; | ||
| 131 | |||
| 132 | #[cfg(any(not(feature = "_nrf54l"), feature = "_s"))] | ||
| 133 | const INTNUM: usize = 0; | ||
| 134 | |||
| 102 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] | 135 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] |
| 103 | #[cfg(feature = "rt")] | 136 | #[cfg(feature = "rt")] |
| 104 | #[interrupt] | 137 | #[interrupt] |
| 105 | fn GPIOTE0() { | 138 | fn GPIOTE0() { |
| 106 | unsafe { handle_gpiote_interrupt() }; | 139 | unsafe { handle_gpiote_interrupt(pac::GPIOTE0) }; |
| 107 | } | 140 | } |
| 108 | 141 | ||
| 109 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] | 142 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] |
| 110 | #[cfg(feature = "rt")] | 143 | #[cfg(feature = "rt")] |
| 111 | #[interrupt] | 144 | #[interrupt] |
| 112 | fn GPIOTE1() { | 145 | fn GPIOTE1() { |
| 113 | unsafe { handle_gpiote_interrupt() }; | 146 | unsafe { handle_gpiote_interrupt(pac::GPIOTE1) }; |
| 114 | } | 147 | } |
| 115 | 148 | ||
| 116 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] | 149 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] |
| 117 | #[cfg(feature = "rt")] | 150 | #[cfg(feature = "rt")] |
| 118 | #[interrupt] | 151 | #[interrupt] |
| 119 | fn GPIOTE() { | 152 | fn GPIOTE() { |
| 120 | unsafe { handle_gpiote_interrupt() }; | 153 | unsafe { handle_gpiote_interrupt(pac::GPIOTE) }; |
| 121 | } | 154 | } |
| 122 | 155 | ||
| 123 | unsafe fn handle_gpiote_interrupt() { | 156 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 124 | let g = regs(); | 157 | #[cfg(feature = "rt")] |
| 158 | #[interrupt] | ||
| 159 | fn GPIOTE20_0() { | ||
| 160 | unsafe { handle_gpiote_interrupt(pac::GPIOTE20) }; | ||
| 161 | } | ||
| 125 | 162 | ||
| 126 | for i in 0..CHANNEL_COUNT { | 163 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 164 | #[cfg(feature = "rt")] | ||
| 165 | #[interrupt] | ||
| 166 | fn GPIOTE30_0() { | ||
| 167 | unsafe { handle_gpiote_interrupt(pac::GPIOTE30) }; | ||
| 168 | } | ||
| 169 | |||
| 170 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] | ||
| 171 | #[cfg(feature = "rt")] | ||
| 172 | #[interrupt] | ||
| 173 | fn GPIOTE20_1() { | ||
| 174 | unsafe { handle_gpiote_interrupt(pac::GPIOTE20) }; | ||
| 175 | } | ||
| 176 | |||
| 177 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] | ||
| 178 | #[cfg(feature = "rt")] | ||
| 179 | #[interrupt] | ||
| 180 | fn GPIOTE30_1() { | ||
| 181 | unsafe { handle_gpiote_interrupt(pac::GPIOTE30) }; | ||
| 182 | } | ||
| 183 | |||
| 184 | unsafe fn handle_gpiote_interrupt(g: pac::gpiote::Gpiote) { | ||
| 185 | for c in 0..CHANNEL_COUNT { | ||
| 186 | let i = c % CHANNELS_PER_PORT; | ||
| 127 | if g.events_in(i).read() != 0 { | 187 | if g.events_in(i).read() != 0 { |
| 128 | g.intenclr().write(|w| w.0 = 1 << i); | 188 | g.intenclr(INTNUM).write(|w| w.0 = 1 << i); |
| 129 | CHANNEL_WAKERS[i].wake(); | 189 | CHANNEL_WAKERS[c].wake(); |
| 130 | } | 190 | } |
| 131 | } | 191 | } |
| 132 | 192 | ||
| 133 | if g.events_port().read() != 0 { | 193 | #[cfg(not(feature = "_nrf54l"))] |
| 134 | g.events_port().write_value(0); | 194 | let eport = g.events_port(0); |
| 135 | 195 | ||
| 136 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 196 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] |
| 197 | let eport = g.events_port(0).nonsecure(); | ||
| 198 | |||
| 199 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | ||
| 200 | let eport = g.events_port(0).secure(); | ||
| 201 | |||
| 202 | if eport.read() != 0 { | ||
| 203 | eport.write_value(0); | ||
| 204 | |||
| 205 | #[cfg(any( | ||
| 206 | feature = "nrf52833", | ||
| 207 | feature = "nrf52840", | ||
| 208 | feature = "_nrf5340", | ||
| 209 | feature = "_nrf54l" | ||
| 210 | ))] | ||
| 137 | let ports = &[pac::P0, pac::P1]; | 211 | let ports = &[pac::P0, pac::P1]; |
| 138 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] | 212 | #[cfg(not(any( |
| 213 | feature = "_nrf51", | ||
| 214 | feature = "nrf52833", | ||
| 215 | feature = "nrf52840", | ||
| 216 | feature = "_nrf5340", | ||
| 217 | feature = "_nrf54l" | ||
| 218 | )))] | ||
| 139 | let ports = &[pac::P0]; | 219 | let ports = &[pac::P0]; |
| 140 | #[cfg(feature = "_nrf51")] | 220 | #[cfg(feature = "_nrf51")] |
| 141 | let ports = &[pac::GPIO]; | 221 | let ports = &[pac::GPIO]; |
| @@ -204,19 +284,43 @@ impl InputChannel<'static> { | |||
| 204 | 284 | ||
| 205 | impl<'d> Drop for InputChannel<'d> { | 285 | impl<'d> Drop for InputChannel<'d> { |
| 206 | fn drop(&mut self) { | 286 | fn drop(&mut self) { |
| 207 | let g = regs(); | 287 | let g = self.ch.regs(); |
| 208 | let num = self.ch.number(); | 288 | let num = self.ch.number(); |
| 209 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); | 289 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); |
| 210 | g.intenclr().write(|w| w.0 = 1 << num); | 290 | g.intenclr(INTNUM).write(|w| w.0 = 1 << num); |
| 211 | } | 291 | } |
| 212 | } | 292 | } |
| 213 | 293 | ||
| 214 | impl<'d> InputChannel<'d> { | 294 | impl<'d> InputChannel<'d> { |
| 215 | /// Create a new GPIOTE input channel driver. | 295 | /// Create a new GPIOTE input channel driver. |
| 216 | pub fn new(ch: Peri<'d, impl Channel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { | 296 | #[cfg(feature = "_nrf54l")] |
| 217 | let g = regs(); | 297 | pub fn new<C: Channel, T: GpiotePin<Instance = C::Instance>>( |
| 218 | let num = ch.number(); | 298 | ch: Peri<'d, C>, |
| 299 | pin: Peri<'d, T>, | ||
| 300 | pull: Pull, | ||
| 301 | polarity: InputChannelPolarity, | ||
| 302 | ) -> Self { | ||
| 303 | let pin = Input::new(pin, pull); | ||
| 304 | let ch = ch.into(); | ||
| 305 | Self::new_inner(ch, pin, polarity) | ||
| 306 | } | ||
| 219 | 307 | ||
| 308 | /// Create a new GPIOTE output channel driver. | ||
| 309 | #[cfg(not(feature = "_nrf54l"))] | ||
| 310 | pub fn new<C: Channel, T: GpioPin>( | ||
| 311 | ch: Peri<'d, C>, | ||
| 312 | pin: Peri<'d, T>, | ||
| 313 | pull: Pull, | ||
| 314 | polarity: InputChannelPolarity, | ||
| 315 | ) -> Self { | ||
| 316 | let pin = Input::new(pin, pull); | ||
| 317 | let ch = ch.into(); | ||
| 318 | Self::new_inner(ch, pin, polarity) | ||
| 319 | } | ||
| 320 | |||
| 321 | fn new_inner(ch: Peri<'d, AnyChannel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { | ||
| 322 | let g = ch.regs(); | ||
| 323 | let num = ch.number(); | ||
| 220 | g.config(num).write(|w| { | 324 | g.config(num).write(|w| { |
| 221 | w.set_mode(Mode::EVENT); | 325 | w.set_mode(Mode::EVENT); |
| 222 | match polarity { | 326 | match polarity { |
| @@ -225,30 +329,37 @@ impl<'d> InputChannel<'d> { | |||
| 225 | InputChannelPolarity::None => w.set_polarity(Polarity::NONE), | 329 | InputChannelPolarity::None => w.set_polarity(Polarity::NONE), |
| 226 | InputChannelPolarity::Toggle => w.set_polarity(Polarity::TOGGLE), | 330 | InputChannelPolarity::Toggle => w.set_polarity(Polarity::TOGGLE), |
| 227 | }; | 331 | }; |
| 228 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 332 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340",))] |
| 229 | w.set_port(match pin.pin.pin.port() { | 333 | w.set_port(match pin.pin.pin.port() { |
| 230 | crate::gpio::Port::Port0 => false, | 334 | crate::gpio::Port::Port0 => false, |
| 231 | crate::gpio::Port::Port1 => true, | 335 | crate::gpio::Port::Port1 => true, |
| 232 | }); | 336 | }); |
| 337 | #[cfg(any(feature = "_nrf54l"))] | ||
| 338 | w.set_port(match pin.pin.pin.port() { | ||
| 339 | crate::gpio::Port::Port0 => 0, | ||
| 340 | crate::gpio::Port::Port1 => 1, | ||
| 341 | crate::gpio::Port::Port2 => 2, | ||
| 342 | }); | ||
| 233 | w.set_psel(pin.pin.pin.pin()); | 343 | w.set_psel(pin.pin.pin.pin()); |
| 234 | }); | 344 | }); |
| 235 | 345 | ||
| 236 | g.events_in(num).write_value(0); | 346 | g.events_in(num).write_value(0); |
| 237 | 347 | ||
| 238 | InputChannel { ch: ch.into(), pin } | 348 | InputChannel { ch, pin } |
| 239 | } | 349 | } |
| 240 | 350 | ||
| 241 | /// Asynchronously wait for an event in this channel. | 351 | /// Asynchronously wait for an event in this channel. |
| 242 | pub async fn wait(&self) { | 352 | pub async fn wait(&self) { |
| 243 | let g = regs(); | 353 | let g = self.ch.regs(); |
| 244 | let num = self.ch.number(); | 354 | let num = self.ch.number(); |
| 355 | let waker = self.ch.waker(); | ||
| 245 | 356 | ||
| 246 | // Enable interrupt | 357 | // Enable interrupt |
| 247 | g.events_in(num).write_value(0); | 358 | g.events_in(num).write_value(0); |
| 248 | g.intenset().write(|w| w.0 = 1 << num); | 359 | g.intenset(INTNUM).write(|w| w.0 = 1 << num); |
| 249 | 360 | ||
| 250 | poll_fn(|cx| { | 361 | poll_fn(|cx| { |
| 251 | CHANNEL_WAKERS[num].register(cx.waker()); | 362 | CHANNEL_WAKERS[waker].register(cx.waker()); |
| 252 | 363 | ||
| 253 | if g.events_in(num).read() != 0 { | 364 | if g.events_in(num).read() != 0 { |
| 254 | Poll::Ready(()) | 365 | Poll::Ready(()) |
| @@ -259,9 +370,14 @@ impl<'d> InputChannel<'d> { | |||
| 259 | .await; | 370 | .await; |
| 260 | } | 371 | } |
| 261 | 372 | ||
| 373 | /// Get the associated input pin. | ||
| 374 | pub fn pin(&self) -> &Input<'_> { | ||
| 375 | &self.pin | ||
| 376 | } | ||
| 377 | |||
| 262 | /// Returns the IN event, for use with PPI. | 378 | /// Returns the IN event, for use with PPI. |
| 263 | pub fn event_in(&self) -> Event<'d> { | 379 | pub fn event_in(&self) -> Event<'d> { |
| 264 | let g = regs(); | 380 | let g = self.ch.regs(); |
| 265 | Event::from_reg(g.events_in(self.ch.number())) | 381 | Event::from_reg(g.events_in(self.ch.number())) |
| 266 | } | 382 | } |
| 267 | } | 383 | } |
| @@ -283,17 +399,44 @@ impl OutputChannel<'static> { | |||
| 283 | 399 | ||
| 284 | impl<'d> Drop for OutputChannel<'d> { | 400 | impl<'d> Drop for OutputChannel<'d> { |
| 285 | fn drop(&mut self) { | 401 | fn drop(&mut self) { |
| 286 | let g = regs(); | 402 | let g = self.ch.regs(); |
| 287 | let num = self.ch.number(); | 403 | let num = self.ch.number(); |
| 288 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); | 404 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); |
| 289 | g.intenclr().write(|w| w.0 = 1 << num); | 405 | g.intenclr(INTNUM).write(|w| w.0 = 1 << num); |
| 290 | } | 406 | } |
| 291 | } | 407 | } |
| 292 | 408 | ||
| 293 | impl<'d> OutputChannel<'d> { | 409 | impl<'d> OutputChannel<'d> { |
| 294 | /// Create a new GPIOTE output channel driver. | 410 | /// Create a new GPIOTE output channel driver. |
| 295 | pub fn new(ch: Peri<'d, impl Channel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { | 411 | #[cfg(feature = "_nrf54l")] |
| 296 | let g = regs(); | 412 | pub fn new<C: Channel, T: GpiotePin<Instance = C::Instance>>( |
| 413 | ch: Peri<'d, C>, | ||
| 414 | pin: Peri<'d, T>, | ||
| 415 | initial_output: Level, | ||
| 416 | drive: OutputDrive, | ||
| 417 | polarity: OutputChannelPolarity, | ||
| 418 | ) -> Self { | ||
| 419 | let pin = Output::new(pin, initial_output, drive); | ||
| 420 | let ch = ch.into(); | ||
| 421 | Self::new_inner(ch, pin, polarity) | ||
| 422 | } | ||
| 423 | |||
| 424 | /// Create a new GPIOTE output channel driver. | ||
| 425 | #[cfg(not(feature = "_nrf54l"))] | ||
| 426 | pub fn new<C: Channel, T: GpioPin>( | ||
| 427 | ch: Peri<'d, C>, | ||
| 428 | pin: Peri<'d, T>, | ||
| 429 | initial_output: Level, | ||
| 430 | drive: OutputDrive, | ||
| 431 | polarity: OutputChannelPolarity, | ||
| 432 | ) -> Self { | ||
| 433 | let pin = Output::new(pin, initial_output, drive); | ||
| 434 | let ch = ch.into(); | ||
| 435 | Self::new_inner(ch, pin, polarity) | ||
| 436 | } | ||
| 437 | |||
| 438 | fn new_inner(ch: Peri<'d, AnyChannel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { | ||
| 439 | let g = ch.regs(); | ||
| 297 | let num = ch.number(); | 440 | let num = ch.number(); |
| 298 | 441 | ||
| 299 | g.config(num).write(|w| { | 442 | g.config(num).write(|w| { |
| @@ -312,52 +455,55 @@ impl<'d> OutputChannel<'d> { | |||
| 312 | crate::gpio::Port::Port0 => false, | 455 | crate::gpio::Port::Port0 => false, |
| 313 | crate::gpio::Port::Port1 => true, | 456 | crate::gpio::Port::Port1 => true, |
| 314 | }); | 457 | }); |
| 458 | #[cfg(any(feature = "_nrf54l"))] | ||
| 459 | w.set_port(match pin.pin.pin.port() { | ||
| 460 | crate::gpio::Port::Port0 => 0, | ||
| 461 | crate::gpio::Port::Port1 => 1, | ||
| 462 | crate::gpio::Port::Port2 => 2, | ||
| 463 | }); | ||
| 315 | w.set_psel(pin.pin.pin.pin()); | 464 | w.set_psel(pin.pin.pin.pin()); |
| 316 | }); | 465 | }); |
| 317 | 466 | ||
| 318 | OutputChannel { | 467 | OutputChannel { ch, _pin: pin } |
| 319 | ch: ch.into(), | ||
| 320 | _pin: pin, | ||
| 321 | } | ||
| 322 | } | 468 | } |
| 323 | 469 | ||
| 324 | /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle). | 470 | /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle). |
| 325 | pub fn out(&self) { | 471 | pub fn out(&self) { |
| 326 | let g = regs(); | 472 | let g = self.ch.regs(); |
| 327 | g.tasks_out(self.ch.number()).write_value(1); | 473 | g.tasks_out(self.ch.number()).write_value(1); |
| 328 | } | 474 | } |
| 329 | 475 | ||
| 330 | /// Triggers the SET task (set associated pin high). | 476 | /// Triggers the SET task (set associated pin high). |
| 331 | #[cfg(not(feature = "_nrf51"))] | 477 | #[cfg(not(feature = "_nrf51"))] |
| 332 | pub fn set(&self) { | 478 | pub fn set(&self) { |
| 333 | let g = regs(); | 479 | let g = self.ch.regs(); |
| 334 | g.tasks_set(self.ch.number()).write_value(1); | 480 | g.tasks_set(self.ch.number()).write_value(1); |
| 335 | } | 481 | } |
| 336 | 482 | ||
| 337 | /// Triggers the CLEAR task (set associated pin low). | 483 | /// Triggers the CLEAR task (set associated pin low). |
| 338 | #[cfg(not(feature = "_nrf51"))] | 484 | #[cfg(not(feature = "_nrf51"))] |
| 339 | pub fn clear(&self) { | 485 | pub fn clear(&self) { |
| 340 | let g = regs(); | 486 | let g = self.ch.regs(); |
| 341 | g.tasks_clr(self.ch.number()).write_value(1); | 487 | g.tasks_clr(self.ch.number()).write_value(1); |
| 342 | } | 488 | } |
| 343 | 489 | ||
| 344 | /// Returns the OUT task, for use with PPI. | 490 | /// Returns the OUT task, for use with PPI. |
| 345 | pub fn task_out(&self) -> Task<'d> { | 491 | pub fn task_out(&self) -> Task<'d> { |
| 346 | let g = regs(); | 492 | let g = self.ch.regs(); |
| 347 | Task::from_reg(g.tasks_out(self.ch.number())) | 493 | Task::from_reg(g.tasks_out(self.ch.number())) |
| 348 | } | 494 | } |
| 349 | 495 | ||
| 350 | /// Returns the CLR task, for use with PPI. | 496 | /// Returns the CLR task, for use with PPI. |
| 351 | #[cfg(not(feature = "_nrf51"))] | 497 | #[cfg(not(feature = "_nrf51"))] |
| 352 | pub fn task_clr(&self) -> Task<'d> { | 498 | pub fn task_clr(&self) -> Task<'d> { |
| 353 | let g = regs(); | 499 | let g = self.ch.regs(); |
| 354 | Task::from_reg(g.tasks_clr(self.ch.number())) | 500 | Task::from_reg(g.tasks_clr(self.ch.number())) |
| 355 | } | 501 | } |
| 356 | 502 | ||
| 357 | /// Returns the SET task, for use with PPI. | 503 | /// Returns the SET task, for use with PPI. |
| 358 | #[cfg(not(feature = "_nrf51"))] | 504 | #[cfg(not(feature = "_nrf51"))] |
| 359 | pub fn task_set(&self) -> Task<'d> { | 505 | pub fn task_set(&self) -> Task<'d> { |
| 360 | let g = regs(); | 506 | let g = self.ch.regs(); |
| 361 | Task::from_reg(g.tasks_set(self.ch.number())) | 507 | Task::from_reg(g.tasks_set(self.ch.number())) |
| 362 | } | 508 | } |
| 363 | } | 509 | } |
| @@ -459,31 +605,52 @@ impl<'d> Flex<'d> { | |||
| 459 | PortInputFuture::new(self.pin.reborrow()).await | 605 | PortInputFuture::new(self.pin.reborrow()).await |
| 460 | } | 606 | } |
| 461 | } | 607 | } |
| 462 | |||
| 463 | // ======================= | 608 | // ======================= |
| 609 | // | ||
| 464 | 610 | ||
| 465 | trait SealedChannel {} | 611 | trait SealedChannel { |
| 612 | fn waker(&self) -> usize; | ||
| 613 | fn regs(&self) -> pac::gpiote::Gpiote; | ||
| 614 | } | ||
| 466 | 615 | ||
| 467 | /// GPIOTE channel trait. | 616 | /// GPIOTE channel trait. |
| 468 | /// | 617 | /// |
| 469 | /// Implemented by all GPIOTE channels. | 618 | /// Implemented by all GPIOTE channels. |
| 470 | #[allow(private_bounds)] | 619 | #[allow(private_bounds)] |
| 471 | pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static { | 620 | pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static { |
| 621 | #[cfg(feature = "_nrf54l")] | ||
| 622 | /// GPIOTE instance this channel belongs to. | ||
| 623 | type Instance: GpioteInstance; | ||
| 472 | /// Get the channel number. | 624 | /// Get the channel number. |
| 473 | fn number(&self) -> usize; | 625 | fn number(&self) -> usize; |
| 474 | } | 626 | } |
| 475 | 627 | ||
| 476 | /// Type-erased channel. | 628 | struct AnyChannel { |
| 477 | /// | ||
| 478 | /// Obtained by calling `Channel::into()`. | ||
| 479 | /// | ||
| 480 | /// This allows using several channels in situations that might require | ||
| 481 | /// them to be the same type, like putting them in an array. | ||
| 482 | pub struct AnyChannel { | ||
| 483 | number: u8, | 629 | number: u8, |
| 630 | regs: pac::gpiote::Gpiote, | ||
| 631 | waker: u8, | ||
| 484 | } | 632 | } |
| 633 | |||
| 485 | impl_peripheral!(AnyChannel); | 634 | impl_peripheral!(AnyChannel); |
| 486 | impl SealedChannel for AnyChannel {} | 635 | |
| 636 | impl SealedChannel for AnyChannel { | ||
| 637 | fn waker(&self) -> usize { | ||
| 638 | self.waker as usize | ||
| 639 | } | ||
| 640 | |||
| 641 | fn regs(&self) -> pac::gpiote::Gpiote { | ||
| 642 | self.regs | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | #[cfg(feature = "_nrf54l")] | ||
| 647 | impl AnyChannel { | ||
| 648 | fn number(&self) -> usize { | ||
| 649 | self.number as usize | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | #[cfg(not(feature = "_nrf54l"))] | ||
| 487 | impl Channel for AnyChannel { | 654 | impl Channel for AnyChannel { |
| 488 | fn number(&self) -> usize { | 655 | fn number(&self) -> usize { |
| 489 | self.number as usize | 656 | self.number as usize |
| @@ -491,9 +658,19 @@ impl Channel for AnyChannel { | |||
| 491 | } | 658 | } |
| 492 | 659 | ||
| 493 | macro_rules! impl_channel { | 660 | macro_rules! impl_channel { |
| 494 | ($type:ident, $number:expr) => { | 661 | ($type:ident, $inst:ident, $number:expr, $waker:expr) => { |
| 495 | impl SealedChannel for peripherals::$type {} | 662 | impl SealedChannel for peripherals::$type { |
| 663 | fn waker(&self) -> usize { | ||
| 664 | $waker as usize | ||
| 665 | } | ||
| 666 | |||
| 667 | fn regs(&self) -> pac::gpiote::Gpiote { | ||
| 668 | pac::$inst | ||
| 669 | } | ||
| 670 | } | ||
| 496 | impl Channel for peripherals::$type { | 671 | impl Channel for peripherals::$type { |
| 672 | #[cfg(feature = "_nrf54l")] | ||
| 673 | type Instance = peripherals::$inst; | ||
| 497 | fn number(&self) -> usize { | 674 | fn number(&self) -> usize { |
| 498 | $number as usize | 675 | $number as usize |
| 499 | } | 676 | } |
| @@ -503,24 +680,95 @@ macro_rules! impl_channel { | |||
| 503 | fn from(val: peripherals::$type) -> Self { | 680 | fn from(val: peripherals::$type) -> Self { |
| 504 | Self { | 681 | Self { |
| 505 | number: val.number() as u8, | 682 | number: val.number() as u8, |
| 683 | waker: val.waker() as u8, | ||
| 684 | regs: val.regs(), | ||
| 506 | } | 685 | } |
| 507 | } | 686 | } |
| 508 | } | 687 | } |
| 509 | }; | 688 | }; |
| 510 | } | 689 | } |
| 511 | 690 | ||
| 512 | impl_channel!(GPIOTE_CH0, 0); | 691 | cfg_if::cfg_if! { |
| 513 | impl_channel!(GPIOTE_CH1, 1); | 692 | if #[cfg(feature = "_nrf54l")] { |
| 514 | impl_channel!(GPIOTE_CH2, 2); | 693 | trait SealedGpioteInstance {} |
| 515 | impl_channel!(GPIOTE_CH3, 3); | 694 | /// Represents a GPIOTE instance. |
| 516 | #[cfg(not(feature = "_nrf51"))] | 695 | #[allow(private_bounds)] |
| 517 | impl_channel!(GPIOTE_CH4, 4); | 696 | pub trait GpioteInstance: PeripheralType + SealedGpioteInstance + Sized + 'static {} |
| 518 | #[cfg(not(feature = "_nrf51"))] | 697 | |
| 519 | impl_channel!(GPIOTE_CH5, 5); | 698 | macro_rules! impl_gpiote { |
| 520 | #[cfg(not(feature = "_nrf51"))] | 699 | ($type:ident) => { |
| 521 | impl_channel!(GPIOTE_CH6, 6); | 700 | impl SealedGpioteInstance for peripherals::$type {} |
| 522 | #[cfg(not(feature = "_nrf51"))] | 701 | impl GpioteInstance for peripherals::$type {} |
| 523 | impl_channel!(GPIOTE_CH7, 7); | 702 | }; |
| 703 | } | ||
| 704 | |||
| 705 | pub(crate) trait SealedGpiotePin {} | ||
| 706 | |||
| 707 | /// Represents a GPIO pin that can be used with GPIOTE. | ||
| 708 | #[allow(private_bounds)] | ||
| 709 | pub trait GpiotePin: GpioPin + SealedGpiotePin { | ||
| 710 | /// The GPIOTE instance this pin belongs to. | ||
| 711 | type Instance: GpioteInstance; | ||
| 712 | } | ||
| 713 | |||
| 714 | macro_rules! impl_gpiote_pin { | ||
| 715 | ($type:ident, $inst:ident) => { | ||
| 716 | impl crate::gpiote::SealedGpiotePin for peripherals::$type {} | ||
| 717 | impl crate::gpiote::GpiotePin for peripherals::$type { | ||
| 718 | type Instance = peripherals::$inst; | ||
| 719 | } | ||
| 720 | }; | ||
| 721 | } | ||
| 722 | |||
| 723 | impl_gpiote!(GPIOTE20); | ||
| 724 | impl_gpiote!(GPIOTE30); | ||
| 725 | impl_channel!(GPIOTE20_CH0, GPIOTE20, 0, 0); | ||
| 726 | impl_channel!(GPIOTE20_CH1, GPIOTE20, 1, 1); | ||
| 727 | impl_channel!(GPIOTE20_CH2, GPIOTE20, 2, 2); | ||
| 728 | impl_channel!(GPIOTE20_CH3, GPIOTE20, 3, 3); | ||
| 729 | impl_channel!(GPIOTE20_CH4, GPIOTE20, 4, 4); | ||
| 730 | impl_channel!(GPIOTE20_CH5, GPIOTE20, 5, 5); | ||
| 731 | impl_channel!(GPIOTE20_CH6, GPIOTE20, 6, 6); | ||
| 732 | impl_channel!(GPIOTE20_CH7, GPIOTE20, 7, 7); | ||
| 733 | |||
| 734 | impl_channel!(GPIOTE30_CH0, GPIOTE30, 0, 8); | ||
| 735 | impl_channel!(GPIOTE30_CH1, GPIOTE30, 1, 9); | ||
| 736 | impl_channel!(GPIOTE30_CH2, GPIOTE30, 2, 10); | ||
| 737 | impl_channel!(GPIOTE30_CH3, GPIOTE30, 3, 11); | ||
| 738 | } else if #[cfg(feature = "_nrf51")] { | ||
| 739 | impl_channel!(GPIOTE_CH0, GPIOTE, 0, 0); | ||
| 740 | impl_channel!(GPIOTE_CH1, GPIOTE, 1, 1); | ||
| 741 | impl_channel!(GPIOTE_CH2, GPIOTE, 2, 2); | ||
| 742 | impl_channel!(GPIOTE_CH3, GPIOTE, 3, 3); | ||
| 743 | } else if #[cfg(all(feature = "_s", any(feature = "_nrf91", feature = "_nrf5340")))] { | ||
| 744 | impl_channel!(GPIOTE_CH0, GPIOTE0, 0, 0); | ||
| 745 | impl_channel!(GPIOTE_CH1, GPIOTE0, 1, 1); | ||
| 746 | impl_channel!(GPIOTE_CH2, GPIOTE0, 2, 2); | ||
| 747 | impl_channel!(GPIOTE_CH3, GPIOTE0, 3, 3); | ||
| 748 | impl_channel!(GPIOTE_CH4, GPIOTE0, 4, 4); | ||
| 749 | impl_channel!(GPIOTE_CH5, GPIOTE0, 5, 5); | ||
| 750 | impl_channel!(GPIOTE_CH6, GPIOTE0, 6, 6); | ||
| 751 | impl_channel!(GPIOTE_CH7, GPIOTE0, 7, 7); | ||
| 752 | } else if #[cfg(all(feature = "_ns", any(feature = "_nrf91", feature = "_nrf5340")))] { | ||
| 753 | impl_channel!(GPIOTE_CH0, GPIOTE1, 0, 0); | ||
| 754 | impl_channel!(GPIOTE_CH1, GPIOTE1, 1, 1); | ||
| 755 | impl_channel!(GPIOTE_CH2, GPIOTE1, 2, 2); | ||
| 756 | impl_channel!(GPIOTE_CH3, GPIOTE1, 3, 3); | ||
| 757 | impl_channel!(GPIOTE_CH4, GPIOTE1, 4, 4); | ||
| 758 | impl_channel!(GPIOTE_CH5, GPIOTE1, 5, 5); | ||
| 759 | impl_channel!(GPIOTE_CH6, GPIOTE1, 6, 6); | ||
| 760 | impl_channel!(GPIOTE_CH7, GPIOTE1, 7, 7); | ||
| 761 | } else { | ||
| 762 | impl_channel!(GPIOTE_CH0, GPIOTE, 0, 0); | ||
| 763 | impl_channel!(GPIOTE_CH1, GPIOTE, 1, 1); | ||
| 764 | impl_channel!(GPIOTE_CH2, GPIOTE, 2, 2); | ||
| 765 | impl_channel!(GPIOTE_CH3, GPIOTE, 3, 3); | ||
| 766 | impl_channel!(GPIOTE_CH4, GPIOTE, 4, 4); | ||
| 767 | impl_channel!(GPIOTE_CH5, GPIOTE, 5, 5); | ||
| 768 | impl_channel!(GPIOTE_CH6, GPIOTE, 6, 6); | ||
| 769 | impl_channel!(GPIOTE_CH7, GPIOTE, 7, 7); | ||
| 770 | } | ||
| 771 | } | ||
| 524 | 772 | ||
| 525 | // ==================== | 773 | // ==================== |
| 526 | 774 | ||
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 1b7fb7e7f..2f5ad352f 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -76,14 +76,12 @@ pub(crate) mod util; | |||
| 76 | #[cfg(feature = "_time-driver")] | 76 | #[cfg(feature = "_time-driver")] |
| 77 | mod time_driver; | 77 | mod time_driver; |
| 78 | 78 | ||
| 79 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 80 | #[cfg(not(feature = "_nrf51"))] | 79 | #[cfg(not(feature = "_nrf51"))] |
| 81 | pub mod buffered_uarte; | 80 | pub mod buffered_uarte; |
| 82 | #[cfg(not(feature = "_nrf54l"))] // TODO | 81 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 83 | #[cfg(not(feature = "_nrf51"))] | 82 | #[cfg(not(feature = "_nrf51"))] |
| 84 | pub mod egu; | 83 | pub mod egu; |
| 85 | pub mod gpio; | 84 | pub mod gpio; |
| 86 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 87 | #[cfg(feature = "gpiote")] | 85 | #[cfg(feature = "gpiote")] |
| 88 | pub mod gpiote; | 86 | pub mod gpiote; |
| 89 | #[cfg(not(feature = "_nrf54l"))] // TODO | 87 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| @@ -119,9 +117,7 @@ pub mod pdm; | |||
| 119 | #[cfg(not(feature = "_nrf54l"))] // TODO | 117 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 120 | #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))] | 118 | #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))] |
| 121 | pub mod power; | 119 | pub mod power; |
| 122 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 123 | pub mod ppi; | 120 | pub mod ppi; |
| 124 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 125 | #[cfg(not(any( | 121 | #[cfg(not(any( |
| 126 | feature = "_nrf51", | 122 | feature = "_nrf51", |
| 127 | feature = "nrf52805", | 123 | feature = "nrf52805", |
| @@ -149,34 +145,28 @@ pub mod radio; | |||
| 149 | #[cfg(feature = "_net-driver")] | 145 | #[cfg(feature = "_net-driver")] |
| 150 | pub mod embassy_net_802154_driver; | 146 | pub mod embassy_net_802154_driver; |
| 151 | 147 | ||
| 148 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | ||
| 149 | pub mod cracen; | ||
| 152 | #[cfg(not(feature = "_nrf54l"))] // TODO | 150 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 153 | #[cfg(feature = "_nrf5340")] | 151 | #[cfg(feature = "_nrf5340")] |
| 154 | pub mod reset; | 152 | pub mod reset; |
| 155 | #[cfg(not(feature = "_nrf54l"))] // TODO | 153 | #[cfg(not(feature = "_nrf54l"))] |
| 156 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 154 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 157 | pub mod rng; | 155 | pub mod rng; |
| 158 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 159 | pub mod rtc; | 156 | pub mod rtc; |
| 160 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 161 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] | 157 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] |
| 162 | pub mod saadc; | 158 | pub mod saadc; |
| 163 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 164 | #[cfg(not(feature = "_nrf51"))] | 159 | #[cfg(not(feature = "_nrf51"))] |
| 165 | pub mod spim; | 160 | pub mod spim; |
| 166 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 167 | #[cfg(not(feature = "_nrf51"))] | 161 | #[cfg(not(feature = "_nrf51"))] |
| 168 | pub mod spis; | 162 | pub mod spis; |
| 169 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 163 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 170 | pub mod temp; | 164 | pub mod temp; |
| 171 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 172 | pub mod timer; | 165 | pub mod timer; |
| 173 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 174 | #[cfg(not(feature = "_nrf51"))] | 166 | #[cfg(not(feature = "_nrf51"))] |
| 175 | pub mod twim; | 167 | pub mod twim; |
| 176 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 177 | #[cfg(not(feature = "_nrf51"))] | 168 | #[cfg(not(feature = "_nrf51"))] |
| 178 | pub mod twis; | 169 | pub mod twis; |
| 179 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 180 | #[cfg(not(feature = "_nrf51"))] | 170 | #[cfg(not(feature = "_nrf51"))] |
| 181 | pub mod uarte; | 171 | pub mod uarte; |
| 182 | #[cfg(not(feature = "_nrf54l"))] // TODO | 172 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| @@ -295,6 +285,15 @@ pub use crate::pac::NVIC_PRIO_BITS; | |||
| 295 | pub mod config { | 285 | pub mod config { |
| 296 | //! Configuration options used when initializing the HAL. | 286 | //! Configuration options used when initializing the HAL. |
| 297 | 287 | ||
| 288 | /// Clock speed | ||
| 289 | #[cfg(feature = "_nrf54l")] | ||
| 290 | pub enum ClockSpeed { | ||
| 291 | /// Run at 128 MHz. | ||
| 292 | CK128, | ||
| 293 | /// Run at 64 MHz. | ||
| 294 | CK64, | ||
| 295 | } | ||
| 296 | |||
| 298 | /// High frequency clock source. | 297 | /// High frequency clock source. |
| 299 | pub enum HfclkSource { | 298 | pub enum HfclkSource { |
| 300 | /// Internal source | 299 | /// Internal source |
| @@ -564,6 +563,9 @@ pub mod config { | |||
| 564 | pub time_interrupt_priority: crate::interrupt::Priority, | 563 | pub time_interrupt_priority: crate::interrupt::Priority, |
| 565 | /// Enable or disable the debug port. | 564 | /// Enable or disable the debug port. |
| 566 | pub debug: Debug, | 565 | pub debug: Debug, |
| 566 | /// Clock speed configuration. | ||
| 567 | #[cfg(feature = "_nrf54l")] | ||
| 568 | pub clock_speed: ClockSpeed, | ||
| 567 | } | 569 | } |
| 568 | 570 | ||
| 569 | impl Default for Config { | 571 | impl Default for Config { |
| @@ -604,6 +606,8 @@ pub mod config { | |||
| 604 | debug: Debug::NotConfigured, | 606 | debug: Debug::NotConfigured, |
| 605 | #[cfg(not(feature = "_ns"))] | 607 | #[cfg(not(feature = "_ns"))] |
| 606 | debug: Debug::Allowed, | 608 | debug: Debug::Allowed, |
| 609 | #[cfg(feature = "_nrf54l")] | ||
| 610 | clock_speed: ClockSpeed::CK64, | ||
| 607 | } | 611 | } |
| 608 | } | 612 | } |
| 609 | } | 613 | } |
| @@ -710,6 +714,23 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 710 | #[allow(unused_mut)] | 714 | #[allow(unused_mut)] |
| 711 | let mut needs_reset = false; | 715 | let mut needs_reset = false; |
| 712 | 716 | ||
| 717 | // set clock speed | ||
| 718 | #[cfg(feature = "_nrf54l")] | ||
| 719 | { | ||
| 720 | #[cfg(feature = "_s")] | ||
| 721 | let regs = pac::OSCILLATORS_S; | ||
| 722 | #[cfg(feature = "_ns")] | ||
| 723 | let regs = pac::OSCILLATORS_NS; | ||
| 724 | |||
| 725 | use pac::oscillators::vals::Freq; | ||
| 726 | regs.pll().freq().write(|w| { | ||
| 727 | w.set_freq(match config.clock_speed { | ||
| 728 | config::ClockSpeed::CK64 => Freq::CK64M, | ||
| 729 | config::ClockSpeed::CK128 => Freq::CK128M, | ||
| 730 | }); | ||
| 731 | }); | ||
| 732 | } | ||
| 733 | |||
| 713 | // Workaround used in the nrf mdk: file system_nrf91.c , function SystemInit(), after `#if !defined(NRF_SKIP_UICR_HFXO_WORKAROUND)` | 734 | // Workaround used in the nrf mdk: file system_nrf91.c , function SystemInit(), after `#if !defined(NRF_SKIP_UICR_HFXO_WORKAROUND)` |
| 714 | #[cfg(all(feature = "_nrf91", feature = "_s"))] | 735 | #[cfg(all(feature = "_nrf91", feature = "_s"))] |
| 715 | { | 736 | { |
| @@ -934,7 +955,7 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 934 | } | 955 | } |
| 935 | } | 956 | } |
| 936 | 957 | ||
| 937 | #[cfg(any(feature = "_nrf52", feature = "_nrf5340-app"))] | 958 | #[cfg(any(feature = "_nrf52", all(feature = "_nrf5340-app", feature = "_s")))] |
| 938 | unsafe { | 959 | unsafe { |
| 939 | let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { 1 }; | 960 | let value = if cfg!(feature = "nfc-pins-as-gpio") { 0 } else { 1 }; |
| 940 | let res = uicr_write_masked(consts::UICR_NFCPINS, value, 1); | 961 | let res = uicr_write_masked(consts::UICR_NFCPINS, value, 1); |
| @@ -1154,7 +1175,6 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 1154 | } | 1175 | } |
| 1155 | 1176 | ||
| 1156 | // Init GPIOTE | 1177 | // Init GPIOTE |
| 1157 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 1158 | #[cfg(feature = "gpiote")] | 1178 | #[cfg(feature = "gpiote")] |
| 1159 | gpiote::init(config.gpiote_interrupt_priority); | 1179 | gpiote::init(config.gpiote_interrupt_priority); |
| 1160 | 1180 | ||
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 168647be3..d43a25c4e 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 2 | use crate::{Peri, pac}; | 2 | use crate::Peri; |
| 3 | 3 | ||
| 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; |
| 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; |
| 6 | 6 | ||
| 7 | pub(crate) fn regs() -> pac::dppic::Dppic { | 7 | #[cfg(not(feature = "_nrf54l"))] |
| 8 | pac::DPPIC | 8 | pub(crate) fn regs() -> crate::pac::dppic::Dppic { |
| 9 | crate::pac::DPPIC | ||
| 9 | } | 10 | } |
| 10 | 11 | ||
| 11 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { | 12 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { |
| @@ -49,13 +50,13 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, | |||
| 49 | /// Enables the channel. | 50 | /// Enables the channel. |
| 50 | pub fn enable(&mut self) { | 51 | pub fn enable(&mut self) { |
| 51 | let n = self.ch.number(); | 52 | let n = self.ch.number(); |
| 52 | regs().chenset().write(|w| w.0 = 1 << n); | 53 | self.ch.regs().chenset().write(|w| w.0 = 1 << n); |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | /// Disables the channel. | 56 | /// Disables the channel. |
| 56 | pub fn disable(&mut self) { | 57 | pub fn disable(&mut self) { |
| 57 | let n = self.ch.number(); | 58 | let n = self.ch.number(); |
| 58 | regs().chenclr().write(|w| w.0 = 1 << n); | 59 | self.ch.regs().chenclr().write(|w| w.0 = 1 << n); |
| 59 | } | 60 | } |
| 60 | } | 61 | } |
| 61 | 62 | ||
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index f30c2218d..a880d3188 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs | |||
| @@ -21,11 +21,13 @@ use core::ptr::NonNull; | |||
| 21 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; | 21 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 22 | 22 | ||
| 23 | use crate::pac::common::{RW, Reg, W}; | 23 | use crate::pac::common::{RW, Reg, W}; |
| 24 | use crate::peripherals; | 24 | use crate::pac::{self}; |
| 25 | 25 | ||
| 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] | 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] |
| 27 | #[cfg_attr(feature = "_ppi", path = "ppi.rs")] | 27 | #[cfg_attr(feature = "_ppi", path = "ppi.rs")] |
| 28 | mod _version; | 28 | mod _version; |
| 29 | |||
| 30 | #[allow(unused_imports)] | ||
| 29 | pub(crate) use _version::*; | 31 | pub(crate) use _version::*; |
| 30 | 32 | ||
| 31 | /// PPI channel driver. | 33 | /// PPI channel driver. |
| @@ -47,7 +49,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 47 | /// | 49 | /// |
| 48 | /// The group is initialized as containing no channels. | 50 | /// The group is initialized as containing no channels. |
| 49 | pub fn new(g: Peri<'d, G>) -> Self { | 51 | pub fn new(g: Peri<'d, G>) -> Self { |
| 50 | let r = regs(); | 52 | let r = g.regs(); |
| 51 | let n = g.number(); | 53 | let n = g.number(); |
| 52 | r.chg(n).write(|_| ()); | 54 | r.chg(n).write(|_| ()); |
| 53 | 55 | ||
| @@ -61,7 +63,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 61 | &mut self, | 63 | &mut self, |
| 62 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, | 64 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, |
| 63 | ) { | 65 | ) { |
| 64 | let r = regs(); | 66 | let r = self.g.regs(); |
| 65 | let ng = self.g.number(); | 67 | let ng = self.g.number(); |
| 66 | let nc = ch.ch.number(); | 68 | let nc = ch.ch.number(); |
| 67 | r.chg(ng).modify(|w| w.set_ch(nc, true)); | 69 | r.chg(ng).modify(|w| w.set_ch(nc, true)); |
| @@ -74,7 +76,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 74 | &mut self, | 76 | &mut self, |
| 75 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, | 77 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, |
| 76 | ) { | 78 | ) { |
| 77 | let r = regs(); | 79 | let r = self.g.regs(); |
| 78 | let ng = self.g.number(); | 80 | let ng = self.g.number(); |
| 79 | let nc = ch.ch.number(); | 81 | let nc = ch.ch.number(); |
| 80 | r.chg(ng).modify(|w| w.set_ch(nc, false)); | 82 | r.chg(ng).modify(|w| w.set_ch(nc, false)); |
| @@ -83,13 +85,13 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 83 | /// Enable all the channels in this group. | 85 | /// Enable all the channels in this group. |
| 84 | pub fn enable_all(&mut self) { | 86 | pub fn enable_all(&mut self) { |
| 85 | let n = self.g.number(); | 87 | let n = self.g.number(); |
| 86 | regs().tasks_chg(n).en().write_value(1); | 88 | self.g.regs().tasks_chg(n).en().write_value(1); |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | /// Disable all the channels in this group. | 91 | /// Disable all the channels in this group. |
| 90 | pub fn disable_all(&mut self) { | 92 | pub fn disable_all(&mut self) { |
| 91 | let n = self.g.number(); | 93 | let n = self.g.number(); |
| 92 | regs().tasks_chg(n).dis().write_value(1); | 94 | self.g.regs().tasks_chg(n).dis().write_value(1); |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | /// Get a reference to the "enable all" task. | 97 | /// Get a reference to the "enable all" task. |
| @@ -97,7 +99,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 97 | /// When triggered, it will enable all the channels in this group. | 99 | /// When triggered, it will enable all the channels in this group. |
| 98 | pub fn task_enable_all(&self) -> Task<'d> { | 100 | pub fn task_enable_all(&self) -> Task<'d> { |
| 99 | let n = self.g.number(); | 101 | let n = self.g.number(); |
| 100 | Task::from_reg(regs().tasks_chg(n).en()) | 102 | Task::from_reg(self.g.regs().tasks_chg(n).en()) |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | /// Get a reference to the "disable all" task. | 105 | /// Get a reference to the "disable all" task. |
| @@ -105,7 +107,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 105 | /// When triggered, it will disable all the channels in this group. | 107 | /// When triggered, it will disable all the channels in this group. |
| 106 | pub fn task_disable_all(&self) -> Task<'d> { | 108 | pub fn task_disable_all(&self) -> Task<'d> { |
| 107 | let n = self.g.number(); | 109 | let n = self.g.number(); |
| 108 | Task::from_reg(regs().tasks_chg(n).dis()) | 110 | Task::from_reg(self.g.regs().tasks_chg(n).dis()) |
| 109 | } | 111 | } |
| 110 | } | 112 | } |
| 111 | impl<G: Group> PpiGroup<'static, G> { | 113 | impl<G: Group> PpiGroup<'static, G> { |
| @@ -119,7 +121,7 @@ impl<G: Group> PpiGroup<'static, G> { | |||
| 119 | 121 | ||
| 120 | impl<'d, G: Group> Drop for PpiGroup<'d, G> { | 122 | impl<'d, G: Group> Drop for PpiGroup<'d, G> { |
| 121 | fn drop(&mut self) { | 123 | fn drop(&mut self) { |
| 122 | let r = regs(); | 124 | let r = self.g.regs(); |
| 123 | let n = self.g.number(); | 125 | let n = self.g.number(); |
| 124 | r.chg(n).write(|_| ()); | 126 | r.chg(n).write(|_| ()); |
| 125 | } | 127 | } |
| @@ -211,8 +213,16 @@ unsafe impl Send for Event<'_> {} | |||
| 211 | // ====================== | 213 | // ====================== |
| 212 | // traits | 214 | // traits |
| 213 | 215 | ||
| 214 | pub(crate) trait SealedChannel {} | 216 | pub(crate) trait SealedChannel { |
| 215 | pub(crate) trait SealedGroup {} | 217 | #[cfg(feature = "_dppi")] |
| 218 | fn regs(&self) -> pac::dppic::Dppic; | ||
| 219 | } | ||
| 220 | pub(crate) trait SealedGroup { | ||
| 221 | #[cfg(feature = "_dppi")] | ||
| 222 | fn regs(&self) -> pac::dppic::Dppic; | ||
| 223 | #[cfg(not(feature = "_dppi"))] | ||
| 224 | fn regs(&self) -> pac::ppi::Ppi; | ||
| 225 | } | ||
| 216 | 226 | ||
| 217 | /// Interface for PPI channels. | 227 | /// Interface for PPI channels. |
| 218 | #[allow(private_bounds)] | 228 | #[allow(private_bounds)] |
| @@ -241,9 +251,16 @@ pub trait Group: SealedGroup + PeripheralType + Into<AnyGroup> + Sized + 'static | |||
| 241 | /// This can be used to have fewer generic parameters in some places. | 251 | /// This can be used to have fewer generic parameters in some places. |
| 242 | pub struct AnyStaticChannel { | 252 | pub struct AnyStaticChannel { |
| 243 | pub(crate) number: u8, | 253 | pub(crate) number: u8, |
| 254 | #[cfg(feature = "_dppi")] | ||
| 255 | pub(crate) regs: pac::dppic::Dppic, | ||
| 244 | } | 256 | } |
| 245 | impl_peripheral!(AnyStaticChannel); | 257 | impl_peripheral!(AnyStaticChannel); |
| 246 | impl SealedChannel for AnyStaticChannel {} | 258 | impl SealedChannel for AnyStaticChannel { |
| 259 | #[cfg(feature = "_dppi")] | ||
| 260 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 261 | self.regs | ||
| 262 | } | ||
| 263 | } | ||
| 247 | impl Channel for AnyStaticChannel { | 264 | impl Channel for AnyStaticChannel { |
| 248 | fn number(&self) -> usize { | 265 | fn number(&self) -> usize { |
| 249 | self.number as usize | 266 | self.number as usize |
| @@ -255,9 +272,16 @@ impl StaticChannel for AnyStaticChannel {} | |||
| 255 | /// This can be used to have fewer generic parameters in some places. | 272 | /// This can be used to have fewer generic parameters in some places. |
| 256 | pub struct AnyConfigurableChannel { | 273 | pub struct AnyConfigurableChannel { |
| 257 | pub(crate) number: u8, | 274 | pub(crate) number: u8, |
| 275 | #[cfg(feature = "_dppi")] | ||
| 276 | pub(crate) regs: pac::dppic::Dppic, | ||
| 258 | } | 277 | } |
| 259 | impl_peripheral!(AnyConfigurableChannel); | 278 | impl_peripheral!(AnyConfigurableChannel); |
| 260 | impl SealedChannel for AnyConfigurableChannel {} | 279 | impl SealedChannel for AnyConfigurableChannel { |
| 280 | #[cfg(feature = "_dppi")] | ||
| 281 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 282 | self.regs | ||
| 283 | } | ||
| 284 | } | ||
| 261 | impl Channel for AnyConfigurableChannel { | 285 | impl Channel for AnyConfigurableChannel { |
| 262 | fn number(&self) -> usize { | 286 | fn number(&self) -> usize { |
| 263 | self.number as usize | 287 | self.number as usize |
| @@ -267,32 +291,41 @@ impl ConfigurableChannel for AnyConfigurableChannel {} | |||
| 267 | 291 | ||
| 268 | #[cfg(not(feature = "_nrf51"))] | 292 | #[cfg(not(feature = "_nrf51"))] |
| 269 | macro_rules! impl_ppi_channel { | 293 | macro_rules! impl_ppi_channel { |
| 270 | ($type:ident, $number:expr) => { | 294 | ($type:ident, $inst:ident, $number:expr) => { |
| 271 | impl crate::ppi::SealedChannel for peripherals::$type {} | 295 | impl crate::ppi::SealedChannel for peripherals::$type { |
| 296 | #[cfg(feature = "_dppi")] | ||
| 297 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 298 | pac::$inst | ||
| 299 | } | ||
| 300 | } | ||
| 272 | impl crate::ppi::Channel for peripherals::$type { | 301 | impl crate::ppi::Channel for peripherals::$type { |
| 273 | fn number(&self) -> usize { | 302 | fn number(&self) -> usize { |
| 274 | $number | 303 | $number |
| 275 | } | 304 | } |
| 276 | } | 305 | } |
| 277 | }; | 306 | }; |
| 278 | ($type:ident, $number:expr => static) => { | 307 | ($type:ident, $inst:ident, $number:expr => static) => { |
| 279 | impl_ppi_channel!($type, $number); | 308 | impl_ppi_channel!($type, $inst, $number); |
| 280 | impl crate::ppi::StaticChannel for peripherals::$type {} | 309 | impl crate::ppi::StaticChannel for peripherals::$type {} |
| 281 | impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { | 310 | impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { |
| 282 | fn from(val: peripherals::$type) -> Self { | 311 | fn from(val: peripherals::$type) -> Self { |
| 283 | Self { | 312 | Self { |
| 284 | number: crate::ppi::Channel::number(&val) as u8, | 313 | number: crate::ppi::Channel::number(&val) as u8, |
| 314 | #[cfg(feature = "_dppi")] | ||
| 315 | regs: pac::$inst, | ||
| 285 | } | 316 | } |
| 286 | } | 317 | } |
| 287 | } | 318 | } |
| 288 | }; | 319 | }; |
| 289 | ($type:ident, $number:expr => configurable) => { | 320 | ($type:ident, $inst:ident, $number:expr => configurable) => { |
| 290 | impl_ppi_channel!($type, $number); | 321 | impl_ppi_channel!($type, $inst, $number); |
| 291 | impl crate::ppi::ConfigurableChannel for peripherals::$type {} | 322 | impl crate::ppi::ConfigurableChannel for peripherals::$type {} |
| 292 | impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { | 323 | impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { |
| 293 | fn from(val: peripherals::$type) -> Self { | 324 | fn from(val: peripherals::$type) -> Self { |
| 294 | Self { | 325 | Self { |
| 295 | number: crate::ppi::Channel::number(&val) as u8, | 326 | number: crate::ppi::Channel::number(&val) as u8, |
| 327 | #[cfg(feature = "_dppi")] | ||
| 328 | regs: pac::$inst, | ||
| 296 | } | 329 | } |
| 297 | } | 330 | } |
| 298 | } | 331 | } |
| @@ -304,40 +337,54 @@ macro_rules! impl_ppi_channel { | |||
| 304 | 337 | ||
| 305 | /// A type erased PPI group. | 338 | /// A type erased PPI group. |
| 306 | pub struct AnyGroup { | 339 | pub struct AnyGroup { |
| 307 | number: u8, | 340 | pub(crate) number: u8, |
| 341 | #[cfg(feature = "_dppi")] | ||
| 342 | pub(crate) regs: pac::dppic::Dppic, | ||
| 343 | #[cfg(not(feature = "_dppi"))] | ||
| 344 | pub(crate) regs: pac::ppi::Ppi, | ||
| 308 | } | 345 | } |
| 309 | impl_peripheral!(AnyGroup); | 346 | impl_peripheral!(AnyGroup); |
| 310 | impl SealedGroup for AnyGroup {} | 347 | impl SealedGroup for AnyGroup { |
| 348 | #[cfg(feature = "_dppi")] | ||
| 349 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 350 | self.regs | ||
| 351 | } | ||
| 352 | #[cfg(not(feature = "_dppi"))] | ||
| 353 | fn regs(&self) -> pac::ppi::Ppi { | ||
| 354 | self.regs | ||
| 355 | } | ||
| 356 | } | ||
| 311 | impl Group for AnyGroup { | 357 | impl Group for AnyGroup { |
| 312 | fn number(&self) -> usize { | 358 | fn number(&self) -> usize { |
| 313 | self.number as usize | 359 | self.number as usize |
| 314 | } | 360 | } |
| 315 | } | 361 | } |
| 316 | 362 | ||
| 317 | macro_rules! impl_group { | 363 | macro_rules! impl_ppi_group { |
| 318 | ($type:ident, $number:expr) => { | 364 | ($type:ident, $inst:ident, $number:expr) => { |
| 319 | impl SealedGroup for peripherals::$type {} | 365 | impl crate::ppi::SealedGroup for crate::peripherals::$type { |
| 320 | impl Group for peripherals::$type { | 366 | #[cfg(feature = "_dppi")] |
| 367 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 368 | pac::$inst | ||
| 369 | } | ||
| 370 | #[cfg(not(feature = "_dppi"))] | ||
| 371 | fn regs(&self) -> pac::ppi::Ppi { | ||
| 372 | pac::$inst | ||
| 373 | } | ||
| 374 | } | ||
| 375 | impl crate::ppi::Group for crate::peripherals::$type { | ||
| 321 | fn number(&self) -> usize { | 376 | fn number(&self) -> usize { |
| 322 | $number | 377 | $number |
| 323 | } | 378 | } |
| 324 | } | 379 | } |
| 325 | 380 | ||
| 326 | impl From<peripherals::$type> for crate::ppi::AnyGroup { | 381 | impl From<crate::peripherals::$type> for crate::ppi::AnyGroup { |
| 327 | fn from(val: peripherals::$type) -> Self { | 382 | fn from(val: crate::peripherals::$type) -> Self { |
| 328 | Self { | 383 | Self { |
| 329 | number: crate::ppi::Group::number(&val) as u8, | 384 | number: crate::ppi::Group::number(&val) as u8, |
| 385 | regs: pac::$inst, | ||
| 330 | } | 386 | } |
| 331 | } | 387 | } |
| 332 | } | 388 | } |
| 333 | }; | 389 | }; |
| 334 | } | 390 | } |
| 335 | |||
| 336 | impl_group!(PPI_GROUP0, 0); | ||
| 337 | impl_group!(PPI_GROUP1, 1); | ||
| 338 | impl_group!(PPI_GROUP2, 2); | ||
| 339 | impl_group!(PPI_GROUP3, 3); | ||
| 340 | #[cfg(not(feature = "_nrf51"))] | ||
| 341 | impl_group!(PPI_GROUP4, 4); | ||
| 342 | #[cfg(not(feature = "_nrf51"))] | ||
| 343 | impl_group!(PPI_GROUP5, 5); | ||
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index e038f44b8..04eb14a77 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -6,7 +6,7 @@ use core::sync::atomic::{Ordering, compiler_fence}; | |||
| 6 | 6 | ||
| 7 | use embassy_hal_internal::{Peri, PeripheralType}; | 7 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 8 | 8 | ||
| 9 | use crate::gpio::{AnyPin, DISCONNECTED, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; | 9 | use crate::gpio::{AnyPin, DISCONNECTED, Level, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; |
| 10 | use crate::pac::gpio::vals as gpiovals; | 10 | use crate::pac::gpio::vals as gpiovals; |
| 11 | use crate::pac::pwm::vals; | 11 | use crate::pac::pwm::vals; |
| 12 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| @@ -17,7 +17,7 @@ use crate::{interrupt, pac}; | |||
| 17 | /// to simply set a duty cycle across up to four channels. | 17 | /// to simply set a duty cycle across up to four channels. |
| 18 | pub struct SimplePwm<'d> { | 18 | pub struct SimplePwm<'d> { |
| 19 | r: pac::pwm::Pwm, | 19 | r: pac::pwm::Pwm, |
| 20 | duty: [u16; 4], | 20 | duty: [DutyCycle; 4], |
| 21 | ch0: Option<Peri<'d, AnyPin>>, | 21 | ch0: Option<Peri<'d, AnyPin>>, |
| 22 | ch1: Option<Peri<'d, AnyPin>>, | 22 | ch1: Option<Peri<'d, AnyPin>>, |
| 23 | ch2: Option<Peri<'d, AnyPin>>, | 23 | ch2: Option<Peri<'d, AnyPin>>, |
| @@ -53,13 +53,11 @@ pub const PWM_CLK_HZ: u32 = 16_000_000; | |||
| 53 | 53 | ||
| 54 | impl<'d> SequencePwm<'d> { | 54 | impl<'d> SequencePwm<'d> { |
| 55 | /// Create a new 1-channel PWM | 55 | /// Create a new 1-channel PWM |
| 56 | #[allow(unused_unsafe)] | ||
| 57 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> { | 56 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> { |
| 58 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) | 57 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) |
| 59 | } | 58 | } |
| 60 | 59 | ||
| 61 | /// Create a new 2-channel PWM | 60 | /// Create a new 2-channel PWM |
| 62 | #[allow(unused_unsafe)] | ||
| 63 | pub fn new_2ch<T: Instance>( | 61 | pub fn new_2ch<T: Instance>( |
| 64 | pwm: Peri<'d, T>, | 62 | pwm: Peri<'d, T>, |
| 65 | ch0: Peri<'d, impl GpioPin>, | 63 | ch0: Peri<'d, impl GpioPin>, |
| @@ -70,7 +68,6 @@ impl<'d> SequencePwm<'d> { | |||
| 70 | } | 68 | } |
| 71 | 69 | ||
| 72 | /// Create a new 3-channel PWM | 70 | /// Create a new 3-channel PWM |
| 73 | #[allow(unused_unsafe)] | ||
| 74 | pub fn new_3ch<T: Instance>( | 71 | pub fn new_3ch<T: Instance>( |
| 75 | pwm: Peri<'d, T>, | 72 | pwm: Peri<'d, T>, |
| 76 | ch0: Peri<'d, impl GpioPin>, | 73 | ch0: Peri<'d, impl GpioPin>, |
| @@ -82,7 +79,6 @@ impl<'d> SequencePwm<'d> { | |||
| 82 | } | 79 | } |
| 83 | 80 | ||
| 84 | /// Create a new 4-channel PWM | 81 | /// Create a new 4-channel PWM |
| 85 | #[allow(unused_unsafe)] | ||
| 86 | pub fn new_4ch<T: Instance>( | 82 | pub fn new_4ch<T: Instance>( |
| 87 | pwm: Peri<'d, T>, | 83 | pwm: Peri<'d, T>, |
| 88 | ch0: Peri<'d, impl GpioPin>, | 84 | ch0: Peri<'d, impl GpioPin>, |
| @@ -111,44 +107,27 @@ impl<'d> SequencePwm<'d> { | |||
| 111 | ) -> Result<Self, Error> { | 107 | ) -> Result<Self, Error> { |
| 112 | let r = T::regs(); | 108 | let r = T::regs(); |
| 113 | 109 | ||
| 114 | if let Some(pin) = &ch0 { | 110 | let channels = [ |
| 115 | pin.set_low(); | 111 | (&ch0, config.ch0_drive, config.ch0_idle_level), |
| 116 | pin.conf().write(|w| { | 112 | (&ch1, config.ch1_drive, config.ch1_idle_level), |
| 117 | w.set_dir(gpiovals::Dir::OUTPUT); | 113 | (&ch2, config.ch2_drive, config.ch2_idle_level), |
| 118 | w.set_input(gpiovals::Input::DISCONNECT); | 114 | (&ch3, config.ch3_drive, config.ch3_idle_level), |
| 119 | convert_drive(w, config.ch0_drive); | 115 | ]; |
| 120 | }); | 116 | for (i, (pin, drive, idle_level)) in channels.into_iter().enumerate() { |
| 121 | } | 117 | if let Some(pin) = pin { |
| 122 | if let Some(pin) = &ch1 { | 118 | match idle_level { |
| 123 | pin.set_low(); | 119 | Level::Low => pin.set_low(), |
| 124 | pin.conf().write(|w| { | 120 | Level::High => pin.set_high(), |
| 125 | w.set_dir(gpiovals::Dir::OUTPUT); | 121 | } |
| 126 | w.set_input(gpiovals::Input::DISCONNECT); | 122 | pin.conf().write(|w| { |
| 127 | convert_drive(w, config.ch1_drive); | 123 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 128 | }); | 124 | w.set_input(gpiovals::Input::DISCONNECT); |
| 129 | } | 125 | convert_drive(w, drive); |
| 130 | if let Some(pin) = &ch2 { | 126 | }); |
| 131 | pin.set_low(); | 127 | } |
| 132 | pin.conf().write(|w| { | 128 | r.psel().out(i).write_value(pin.psel_bits()); |
| 133 | w.set_dir(gpiovals::Dir::OUTPUT); | ||
| 134 | w.set_input(gpiovals::Input::DISCONNECT); | ||
| 135 | convert_drive(w, config.ch2_drive); | ||
| 136 | }); | ||
| 137 | } | ||
| 138 | if let Some(pin) = &ch3 { | ||
| 139 | pin.set_low(); | ||
| 140 | pin.conf().write(|w| { | ||
| 141 | w.set_dir(gpiovals::Dir::OUTPUT); | ||
| 142 | w.set_input(gpiovals::Input::DISCONNECT); | ||
| 143 | convert_drive(w, config.ch3_drive); | ||
| 144 | }); | ||
| 145 | } | 129 | } |
| 146 | 130 | ||
| 147 | r.psel().out(0).write_value(ch0.psel_bits()); | ||
| 148 | r.psel().out(1).write_value(ch1.psel_bits()); | ||
| 149 | r.psel().out(2).write_value(ch2.psel_bits()); | ||
| 150 | r.psel().out(3).write_value(ch3.psel_bits()); | ||
| 151 | |||
| 152 | // Disable all interrupts | 131 | // Disable all interrupts |
| 153 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); | 132 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 154 | r.shorts().write(|_| ()); | 133 | r.shorts().write(|_| ()); |
| @@ -173,13 +152,7 @@ impl<'d> SequencePwm<'d> { | |||
| 173 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(config.prescaler as u8))); | 152 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(config.prescaler as u8))); |
| 174 | r.countertop().write(|w| w.set_countertop(config.max_duty)); | 153 | r.countertop().write(|w| w.set_countertop(config.max_duty)); |
| 175 | 154 | ||
| 176 | Ok(Self { | 155 | Ok(Self { r, ch0, ch1, ch2, ch3 }) |
| 177 | r: T::regs(), | ||
| 178 | ch0, | ||
| 179 | ch1, | ||
| 180 | ch2, | ||
| 181 | ch3, | ||
| 182 | }) | ||
| 183 | } | 156 | } |
| 184 | 157 | ||
| 185 | /// Returns reference to `Stopped` event endpoint for PPI. | 158 | /// Returns reference to `Stopped` event endpoint for PPI. |
| @@ -230,7 +203,7 @@ impl<'d> SequencePwm<'d> { | |||
| 230 | /// Interacting with the sequence while it runs puts it in an unknown state | 203 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 231 | #[inline(always)] | 204 | #[inline(always)] |
| 232 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { | 205 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { |
| 233 | Task::from_reg(self.r.tasks_seqstart(0)) | 206 | Task::from_reg(self.r.tasks_dma().seq(0).start()) |
| 234 | } | 207 | } |
| 235 | 208 | ||
| 236 | /// Returns reference to `Seq1 Started` task endpoint for PPI. | 209 | /// Returns reference to `Seq1 Started` task endpoint for PPI. |
| @@ -239,7 +212,7 @@ impl<'d> SequencePwm<'d> { | |||
| 239 | /// Interacting with the sequence while it runs puts it in an unknown state | 212 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 240 | #[inline(always)] | 213 | #[inline(always)] |
| 241 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { | 214 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { |
| 242 | Task::from_reg(self.r.tasks_seqstart(1)) | 215 | Task::from_reg(self.r.tasks_dma().seq(1).start()) |
| 243 | } | 216 | } |
| 244 | 217 | ||
| 245 | /// Returns reference to `NextStep` task endpoint for PPI. | 218 | /// Returns reference to `NextStep` task endpoint for PPI. |
| @@ -289,6 +262,8 @@ impl<'a> Drop for SequencePwm<'a> { | |||
| 289 | } | 262 | } |
| 290 | 263 | ||
| 291 | /// Configuration for the PWM as a whole. | 264 | /// Configuration for the PWM as a whole. |
| 265 | #[derive(Debug, Clone)] | ||
| 266 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 292 | #[non_exhaustive] | 267 | #[non_exhaustive] |
| 293 | pub struct Config { | 268 | pub struct Config { |
| 294 | /// Selects up mode or up-and-down mode for the counter | 269 | /// Selects up mode or up-and-down mode for the counter |
| @@ -307,11 +282,19 @@ pub struct Config { | |||
| 307 | pub ch2_drive: OutputDrive, | 282 | pub ch2_drive: OutputDrive, |
| 308 | /// Drive strength for the channel 3 line. | 283 | /// Drive strength for the channel 3 line. |
| 309 | pub ch3_drive: OutputDrive, | 284 | pub ch3_drive: OutputDrive, |
| 285 | /// Output level for the channel 0 line when PWM if disabled. | ||
| 286 | pub ch0_idle_level: Level, | ||
| 287 | /// Output level for the channel 1 line when PWM if disabled. | ||
| 288 | pub ch1_idle_level: Level, | ||
| 289 | /// Output level for the channel 2 line when PWM if disabled. | ||
| 290 | pub ch2_idle_level: Level, | ||
| 291 | /// Output level for the channel 3 line when PWM if disabled. | ||
| 292 | pub ch3_idle_level: Level, | ||
| 310 | } | 293 | } |
| 311 | 294 | ||
| 312 | impl Default for Config { | 295 | impl Default for Config { |
| 313 | fn default() -> Config { | 296 | fn default() -> Self { |
| 314 | Config { | 297 | Self { |
| 315 | counter_mode: CounterMode::Up, | 298 | counter_mode: CounterMode::Up, |
| 316 | max_duty: 1000, | 299 | max_duty: 1000, |
| 317 | prescaler: Prescaler::Div16, | 300 | prescaler: Prescaler::Div16, |
| @@ -320,13 +303,65 @@ impl Default for Config { | |||
| 320 | ch1_drive: OutputDrive::Standard, | 303 | ch1_drive: OutputDrive::Standard, |
| 321 | ch2_drive: OutputDrive::Standard, | 304 | ch2_drive: OutputDrive::Standard, |
| 322 | ch3_drive: OutputDrive::Standard, | 305 | ch3_drive: OutputDrive::Standard, |
| 306 | ch0_idle_level: Level::Low, | ||
| 307 | ch1_idle_level: Level::Low, | ||
| 308 | ch2_idle_level: Level::Low, | ||
| 309 | ch3_idle_level: Level::Low, | ||
| 310 | } | ||
| 311 | } | ||
| 312 | } | ||
| 313 | |||
| 314 | /// Configuration for the simple PWM driver. | ||
| 315 | #[derive(Debug, Clone)] | ||
| 316 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 317 | #[non_exhaustive] | ||
| 318 | pub struct SimpleConfig { | ||
| 319 | /// Selects up mode or up-and-down mode for the counter | ||
| 320 | pub counter_mode: CounterMode, | ||
| 321 | /// Top value to be compared against buffer values | ||
| 322 | pub max_duty: u16, | ||
| 323 | /// Configuration for PWM_CLK | ||
| 324 | pub prescaler: Prescaler, | ||
| 325 | /// Drive strength for the channel 0 line. | ||
| 326 | pub ch0_drive: OutputDrive, | ||
| 327 | /// Drive strength for the channel 1 line. | ||
| 328 | pub ch1_drive: OutputDrive, | ||
| 329 | /// Drive strength for the channel 2 line. | ||
| 330 | pub ch2_drive: OutputDrive, | ||
| 331 | /// Drive strength for the channel 3 line. | ||
| 332 | pub ch3_drive: OutputDrive, | ||
| 333 | /// Output level for the channel 0 line when PWM if disabled. | ||
| 334 | pub ch0_idle_level: Level, | ||
| 335 | /// Output level for the channel 1 line when PWM if disabled. | ||
| 336 | pub ch1_idle_level: Level, | ||
| 337 | /// Output level for the channel 2 line when PWM if disabled. | ||
| 338 | pub ch2_idle_level: Level, | ||
| 339 | /// Output level for the channel 3 line when PWM if disabled. | ||
| 340 | pub ch3_idle_level: Level, | ||
| 341 | } | ||
| 342 | |||
| 343 | impl Default for SimpleConfig { | ||
| 344 | fn default() -> Self { | ||
| 345 | Self { | ||
| 346 | counter_mode: CounterMode::Up, | ||
| 347 | max_duty: 1000, | ||
| 348 | prescaler: Prescaler::Div16, | ||
| 349 | ch0_drive: OutputDrive::Standard, | ||
| 350 | ch1_drive: OutputDrive::Standard, | ||
| 351 | ch2_drive: OutputDrive::Standard, | ||
| 352 | ch3_drive: OutputDrive::Standard, | ||
| 353 | ch0_idle_level: Level::Low, | ||
| 354 | ch1_idle_level: Level::Low, | ||
| 355 | ch2_idle_level: Level::Low, | ||
| 356 | ch3_idle_level: Level::Low, | ||
| 323 | } | 357 | } |
| 324 | } | 358 | } |
| 325 | } | 359 | } |
| 326 | 360 | ||
| 327 | /// Configuration per sequence | 361 | /// Configuration per sequence |
| 328 | #[non_exhaustive] | 362 | #[non_exhaustive] |
| 329 | #[derive(Clone)] | 363 | #[derive(Debug, Clone)] |
| 364 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 330 | pub struct SequenceConfig { | 365 | pub struct SequenceConfig { |
| 331 | /// Number of PWM periods to delay between each sequence sample | 366 | /// Number of PWM periods to delay between each sequence sample |
| 332 | pub refresh: u32, | 367 | pub refresh: u32, |
| @@ -345,6 +380,8 @@ impl Default for SequenceConfig { | |||
| 345 | 380 | ||
| 346 | /// A composition of a sequence buffer and its configuration. | 381 | /// A composition of a sequence buffer and its configuration. |
| 347 | #[non_exhaustive] | 382 | #[non_exhaustive] |
| 383 | #[derive(Debug, Clone)] | ||
| 384 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 348 | pub struct Sequence<'s> { | 385 | pub struct Sequence<'s> { |
| 349 | /// The words comprising the sequence. Must not exceed 32767 words. | 386 | /// The words comprising the sequence. Must not exceed 32767 words. |
| 350 | pub words: &'s [u16], | 387 | pub words: &'s [u16], |
| @@ -407,6 +444,21 @@ pub struct Sequencer<'d, 's> { | |||
| 407 | sequence1: Option<Sequence<'s>>, | 444 | sequence1: Option<Sequence<'s>>, |
| 408 | } | 445 | } |
| 409 | 446 | ||
| 447 | #[cfg(feature = "_nrf54l")] | ||
| 448 | fn pwmseq(r: pac::pwm::Pwm, n: usize) -> pac::pwm::PwmSeq { | ||
| 449 | r.seq(n) | ||
| 450 | } | ||
| 451 | |||
| 452 | #[cfg(not(feature = "_nrf54l"))] | ||
| 453 | fn pwmseq(r: pac::pwm::Pwm, n: usize) -> pac::pwm::DmaSeq { | ||
| 454 | r.dma().seq(n) | ||
| 455 | } | ||
| 456 | |||
| 457 | #[cfg(feature = "_nrf54l")] | ||
| 458 | const CNT_UNIT: u32 = 2; | ||
| 459 | #[cfg(not(feature = "_nrf54l"))] | ||
| 460 | const CNT_UNIT: u32 = 1; | ||
| 461 | |||
| 410 | impl<'d, 's> Sequencer<'d, 's> { | 462 | impl<'d, 's> Sequencer<'d, 's> { |
| 411 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 | 463 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 |
| 412 | /// will be used twice in the one loop. | 464 | /// will be used twice in the one loop. |
| @@ -439,15 +491,21 @@ impl<'d, 's> Sequencer<'d, 's> { | |||
| 439 | 491 | ||
| 440 | let r = self._pwm.r; | 492 | let r = self._pwm.r; |
| 441 | 493 | ||
| 442 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); | 494 | pwmseq(r, 0).refresh().write(|w| w.0 = sequence0.config.refresh); |
| 443 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); | 495 | pwmseq(r, 0).enddelay().write(|w| w.0 = sequence0.config.end_delay); |
| 444 | r.seq(0).ptr().write_value(sequence0.words.as_ptr() as u32); | 496 | r.dma().seq(0).ptr().write_value(sequence0.words.as_ptr() as u32); |
| 445 | r.seq(0).cnt().write(|w| w.0 = sequence0.words.len() as u32); | 497 | r.dma() |
| 446 | 498 | .seq(0) | |
| 447 | r.seq(1).refresh().write(|w| w.0 = alt_sequence.config.refresh); | 499 | .maxcnt() |
| 448 | r.seq(1).enddelay().write(|w| w.0 = alt_sequence.config.end_delay); | 500 | .write(|w| w.0 = sequence0.words.len() as u32 * CNT_UNIT); |
| 449 | r.seq(1).ptr().write_value(alt_sequence.words.as_ptr() as u32); | 501 | |
| 450 | r.seq(1).cnt().write(|w| w.0 = alt_sequence.words.len() as u32); | 502 | pwmseq(r, 1).refresh().write(|w| w.0 = alt_sequence.config.refresh); |
| 503 | pwmseq(r, 1).enddelay().write(|w| w.0 = alt_sequence.config.end_delay); | ||
| 504 | r.dma().seq(1).ptr().write_value(alt_sequence.words.as_ptr() as u32); | ||
| 505 | r.dma() | ||
| 506 | .seq(1) | ||
| 507 | .maxcnt() | ||
| 508 | .write(|w| w.0 = alt_sequence.words.len() as u32 * CNT_UNIT); | ||
| 451 | 509 | ||
| 452 | r.enable().write(|w| w.set_enable(true)); | 510 | r.enable().write(|w| w.set_enable(true)); |
| 453 | 511 | ||
| @@ -463,11 +521,11 @@ impl<'d, 's> Sequencer<'d, 's> { | |||
| 463 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again | 521 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again |
| 464 | SequenceMode::Infinite => { | 522 | SequenceMode::Infinite => { |
| 465 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::from_bits(1))); | 523 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::from_bits(1))); |
| 466 | r.shorts().write(|w| w.set_loopsdone_seqstart0(true)); | 524 | r.shorts().write(|w| w.set_loopsdone_dma_seq0_start(true)); |
| 467 | } | 525 | } |
| 468 | } | 526 | } |
| 469 | 527 | ||
| 470 | r.tasks_seqstart(seqstart_index).write_value(1); | 528 | r.tasks_dma().seq(seqstart_index).start().write_value(1); |
| 471 | 529 | ||
| 472 | Ok(()) | 530 | Ok(()) |
| 473 | } | 531 | } |
| @@ -496,6 +554,7 @@ impl<'d, 's> Drop for Sequencer<'d, 's> { | |||
| 496 | 554 | ||
| 497 | /// How many times to run a single sequence | 555 | /// How many times to run a single sequence |
| 498 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 556 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 557 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 499 | pub enum SingleSequenceMode { | 558 | pub enum SingleSequenceMode { |
| 500 | /// Run a single sequence n Times total. | 559 | /// Run a single sequence n Times total. |
| 501 | Times(u16), | 560 | Times(u16), |
| @@ -505,6 +564,7 @@ pub enum SingleSequenceMode { | |||
| 505 | 564 | ||
| 506 | /// Which sequence to start a loop with | 565 | /// Which sequence to start a loop with |
| 507 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 566 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 567 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 508 | pub enum StartSequence { | 568 | pub enum StartSequence { |
| 509 | /// Start with Sequence 0 | 569 | /// Start with Sequence 0 |
| 510 | Zero, | 570 | Zero, |
| @@ -514,6 +574,7 @@ pub enum StartSequence { | |||
| 514 | 574 | ||
| 515 | /// How many loops to run two sequences | 575 | /// How many loops to run two sequences |
| 516 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 576 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 577 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 517 | pub enum SequenceMode { | 578 | pub enum SequenceMode { |
| 518 | /// Run two sequences n loops i.e. (n * (seq0 + seq1.unwrap_or(seq0))) | 579 | /// Run two sequences n loops i.e. (n * (seq0 + seq1.unwrap_or(seq0))) |
| 519 | Loop(u16), | 580 | Loop(u16), |
| @@ -523,6 +584,7 @@ pub enum SequenceMode { | |||
| 523 | 584 | ||
| 524 | /// PWM Base clock is system clock (16MHz) divided by prescaler | 585 | /// PWM Base clock is system clock (16MHz) divided by prescaler |
| 525 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 586 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 587 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 526 | pub enum Prescaler { | 588 | pub enum Prescaler { |
| 527 | /// Divide by 1 | 589 | /// Divide by 1 |
| 528 | Div1, | 590 | Div1, |
| @@ -544,6 +606,7 @@ pub enum Prescaler { | |||
| 544 | 606 | ||
| 545 | /// How the sequence values are distributed across the channels | 607 | /// How the sequence values are distributed across the channels |
| 546 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 608 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 609 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 547 | pub enum SequenceLoad { | 610 | pub enum SequenceLoad { |
| 548 | /// Provided sequence will be used across all channels | 611 | /// Provided sequence will be used across all channels |
| 549 | Common, | 612 | Common, |
| @@ -560,6 +623,7 @@ pub enum SequenceLoad { | |||
| 560 | 623 | ||
| 561 | /// Selects up mode or up-and-down mode for the counter | 624 | /// Selects up mode or up-and-down mode for the counter |
| 562 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 625 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 626 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 563 | pub enum CounterMode { | 627 | pub enum CounterMode { |
| 564 | /// Up counter (edge-aligned PWM duty cycle) | 628 | /// Up counter (edge-aligned PWM duty cycle) |
| 565 | Up, | 629 | Up, |
| @@ -567,48 +631,128 @@ pub enum CounterMode { | |||
| 567 | UpAndDown, | 631 | UpAndDown, |
| 568 | } | 632 | } |
| 569 | 633 | ||
| 634 | /// Duty value and polarity for a single channel. | ||
| 635 | /// | ||
| 636 | /// If the channel has inverted polarity, the output is set high as long as the counter is below the duty value. | ||
| 637 | #[repr(transparent)] | ||
| 638 | #[derive(Eq, PartialEq, Clone, Copy)] | ||
| 639 | pub struct DutyCycle { | ||
| 640 | /// The raw duty cycle valuea. | ||
| 641 | /// | ||
| 642 | /// This has the duty cycle in the lower 15 bits. | ||
| 643 | /// The highest bit indicates that the duty cycle has inverted polarity. | ||
| 644 | raw: u16, | ||
| 645 | } | ||
| 646 | |||
| 647 | impl DutyCycle { | ||
| 648 | /// Make a new duty value with normal polarity. | ||
| 649 | /// | ||
| 650 | /// The value is truncated to 15 bits. | ||
| 651 | /// | ||
| 652 | /// The output is set high if the counter is at or above the duty value. | ||
| 653 | pub const fn normal(value: u16) -> Self { | ||
| 654 | let raw = value & 0x7FFF; | ||
| 655 | Self { raw } | ||
| 656 | } | ||
| 657 | |||
| 658 | /// Make a new duty cycle with inverted polarity. | ||
| 659 | /// | ||
| 660 | /// The value is truncated to 15 bits. | ||
| 661 | /// | ||
| 662 | /// The output is set high if the counter is below the duty value. | ||
| 663 | pub const fn inverted(value: u16) -> Self { | ||
| 664 | let raw = value | 0x8000; | ||
| 665 | Self { raw } | ||
| 666 | } | ||
| 667 | |||
| 668 | /// Adjust the polarity of the duty cycle (returns a new object). | ||
| 669 | #[must_use = "this function return a new object, it does not modify self"] | ||
| 670 | pub const fn with_inverted(self, inverted_polarity: bool) -> Self { | ||
| 671 | if inverted_polarity { | ||
| 672 | Self::inverted(self.value()) | ||
| 673 | } else { | ||
| 674 | Self::normal(self.value()) | ||
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 | /// Gets the 15-bit value of the duty cycle. | ||
| 679 | pub const fn value(&self) -> u16 { | ||
| 680 | self.raw & 0x7FFF | ||
| 681 | } | ||
| 682 | |||
| 683 | /// Checks if the duty period has inverted polarity. | ||
| 684 | /// | ||
| 685 | /// If the channel has inverted polarity, the output is set high as long as the counter is below the duty value. | ||
| 686 | pub const fn is_inverted(&self) -> bool { | ||
| 687 | self.raw & 0x8000 != 0 | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | impl core::fmt::Debug for DutyCycle { | ||
| 692 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { | ||
| 693 | f.debug_struct("DutyCycle") | ||
| 694 | .field("value", &self.value()) | ||
| 695 | .field("inverted", &self.is_inverted()) | ||
| 696 | .finish() | ||
| 697 | } | ||
| 698 | } | ||
| 699 | |||
| 700 | #[cfg(feature = "defmt")] | ||
| 701 | impl defmt::Format for DutyCycle { | ||
| 702 | fn format(&self, f: defmt::Formatter) { | ||
| 703 | defmt::write!( | ||
| 704 | f, | ||
| 705 | "DutyCycle {{ value: {=u16}, inverted: {=bool} }}", | ||
| 706 | self.value(), | ||
| 707 | self.is_inverted(), | ||
| 708 | ); | ||
| 709 | } | ||
| 710 | } | ||
| 711 | |||
| 570 | impl<'d> SimplePwm<'d> { | 712 | impl<'d> SimplePwm<'d> { |
| 571 | /// Create a new 1-channel PWM | 713 | /// Create a new 1-channel PWM |
| 572 | #[allow(unused_unsafe)] | 714 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: &SimpleConfig) -> Self { |
| 573 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self { | 715 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) |
| 574 | unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) } | ||
| 575 | } | 716 | } |
| 576 | 717 | ||
| 577 | /// Create a new 2-channel PWM | 718 | /// Create a new 2-channel PWM |
| 578 | #[allow(unused_unsafe)] | 719 | pub fn new_2ch<T: Instance>( |
| 579 | pub fn new_2ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self { | 720 | pwm: Peri<'d, T>, |
| 580 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None) | 721 | ch0: Peri<'d, impl GpioPin>, |
| 722 | ch1: Peri<'d, impl GpioPin>, | ||
| 723 | config: &SimpleConfig, | ||
| 724 | ) -> Self { | ||
| 725 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None, config) | ||
| 581 | } | 726 | } |
| 582 | 727 | ||
| 583 | /// Create a new 3-channel PWM | 728 | /// Create a new 3-channel PWM |
| 584 | #[allow(unused_unsafe)] | ||
| 585 | pub fn new_3ch<T: Instance>( | 729 | pub fn new_3ch<T: Instance>( |
| 586 | pwm: Peri<'d, T>, | 730 | pwm: Peri<'d, T>, |
| 587 | ch0: Peri<'d, impl GpioPin>, | 731 | ch0: Peri<'d, impl GpioPin>, |
| 588 | ch1: Peri<'d, impl GpioPin>, | 732 | ch1: Peri<'d, impl GpioPin>, |
| 589 | ch2: Peri<'d, impl GpioPin>, | 733 | ch2: Peri<'d, impl GpioPin>, |
| 734 | config: &SimpleConfig, | ||
| 590 | ) -> Self { | 735 | ) -> Self { |
| 591 | unsafe { Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None) } | 736 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None, config) |
| 592 | } | 737 | } |
| 593 | 738 | ||
| 594 | /// Create a new 4-channel PWM | 739 | /// Create a new 4-channel PWM |
| 595 | #[allow(unused_unsafe)] | ||
| 596 | pub fn new_4ch<T: Instance>( | 740 | pub fn new_4ch<T: Instance>( |
| 597 | pwm: Peri<'d, T>, | 741 | pwm: Peri<'d, T>, |
| 598 | ch0: Peri<'d, impl GpioPin>, | 742 | ch0: Peri<'d, impl GpioPin>, |
| 599 | ch1: Peri<'d, impl GpioPin>, | 743 | ch1: Peri<'d, impl GpioPin>, |
| 600 | ch2: Peri<'d, impl GpioPin>, | 744 | ch2: Peri<'d, impl GpioPin>, |
| 601 | ch3: Peri<'d, impl GpioPin>, | 745 | ch3: Peri<'d, impl GpioPin>, |
| 746 | config: &SimpleConfig, | ||
| 602 | ) -> Self { | 747 | ) -> Self { |
| 603 | unsafe { | 748 | Self::new_inner( |
| 604 | Self::new_inner( | 749 | pwm, |
| 605 | pwm, | 750 | Some(ch0.into()), |
| 606 | Some(ch0.into()), | 751 | Some(ch1.into()), |
| 607 | Some(ch1.into()), | 752 | Some(ch2.into()), |
| 608 | Some(ch2.into()), | 753 | Some(ch3.into()), |
| 609 | Some(ch3.into()), | 754 | config, |
| 610 | ) | 755 | ) |
| 611 | } | ||
| 612 | } | 756 | } |
| 613 | 757 | ||
| 614 | fn new_inner<T: Instance>( | 758 | fn new_inner<T: Instance>( |
| @@ -617,29 +761,38 @@ impl<'d> SimplePwm<'d> { | |||
| 617 | ch1: Option<Peri<'d, AnyPin>>, | 761 | ch1: Option<Peri<'d, AnyPin>>, |
| 618 | ch2: Option<Peri<'d, AnyPin>>, | 762 | ch2: Option<Peri<'d, AnyPin>>, |
| 619 | ch3: Option<Peri<'d, AnyPin>>, | 763 | ch3: Option<Peri<'d, AnyPin>>, |
| 764 | config: &SimpleConfig, | ||
| 620 | ) -> Self { | 765 | ) -> Self { |
| 621 | let r = T::regs(); | 766 | let r = T::regs(); |
| 622 | 767 | ||
| 623 | for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() { | 768 | let channels = [ |
| 624 | if let Some(pin) = ch { | 769 | (&ch0, config.ch0_drive, config.ch0_idle_level), |
| 625 | pin.set_low(); | 770 | (&ch1, config.ch1_drive, config.ch1_idle_level), |
| 626 | 771 | (&ch2, config.ch2_drive, config.ch2_idle_level), | |
| 772 | (&ch3, config.ch3_drive, config.ch3_idle_level), | ||
| 773 | ]; | ||
| 774 | for (i, (pin, drive, idle_level)) in channels.into_iter().enumerate() { | ||
| 775 | if let Some(pin) = pin { | ||
| 776 | match idle_level { | ||
| 777 | Level::Low => pin.set_low(), | ||
| 778 | Level::High => pin.set_high(), | ||
| 779 | } | ||
| 627 | pin.conf().write(|w| { | 780 | pin.conf().write(|w| { |
| 628 | w.set_dir(gpiovals::Dir::OUTPUT); | 781 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 629 | w.set_input(gpiovals::Input::DISCONNECT); | 782 | w.set_input(gpiovals::Input::DISCONNECT); |
| 630 | w.set_drive(gpiovals::Drive::S0S1); | 783 | convert_drive(w, drive); |
| 631 | }); | 784 | }); |
| 632 | } | 785 | } |
| 633 | r.psel().out(i).write_value(ch.psel_bits()); | 786 | r.psel().out(i).write_value(pin.psel_bits()); |
| 634 | } | 787 | } |
| 635 | 788 | ||
| 636 | let pwm = Self { | 789 | let pwm = Self { |
| 637 | r: T::regs(), | 790 | r, |
| 638 | ch0, | 791 | ch0, |
| 639 | ch1, | 792 | ch1, |
| 640 | ch2, | 793 | ch2, |
| 641 | ch3, | 794 | ch3, |
| 642 | duty: [0; 4], | 795 | duty: [const { DutyCycle::normal(0) }; 4], |
| 643 | }; | 796 | }; |
| 644 | 797 | ||
| 645 | // Disable all interrupts | 798 | // Disable all interrupts |
| @@ -649,18 +802,22 @@ impl<'d> SimplePwm<'d> { | |||
| 649 | // Enable | 802 | // Enable |
| 650 | r.enable().write(|w| w.set_enable(true)); | 803 | r.enable().write(|w| w.set_enable(true)); |
| 651 | 804 | ||
| 652 | r.seq(0).ptr().write_value((pwm.duty).as_ptr() as u32); | 805 | r.dma().seq(0).ptr().write_value((pwm.duty).as_ptr() as u32); |
| 653 | r.seq(0).cnt().write(|w| w.0 = 4); | 806 | r.dma().seq(0).maxcnt().write(|w| w.0 = 4 * CNT_UNIT); |
| 654 | r.seq(0).refresh().write(|w| w.0 = 0); | 807 | pwmseq(r, 0).refresh().write(|w| w.0 = 0); |
| 655 | r.seq(0).enddelay().write(|w| w.0 = 0); | 808 | pwmseq(r, 0).enddelay().write(|w| w.0 = 0); |
| 656 | 809 | ||
| 657 | r.decoder().write(|w| { | 810 | r.decoder().write(|w| { |
| 658 | w.set_load(vals::Load::INDIVIDUAL); | 811 | w.set_load(vals::Load::INDIVIDUAL); |
| 659 | w.set_mode(vals::Mode::REFRESH_COUNT); | 812 | w.set_mode(vals::Mode::REFRESH_COUNT); |
| 660 | }); | 813 | }); |
| 661 | r.mode().write(|w| w.set_updown(vals::Updown::UP)); | 814 | r.mode().write(|w| match config.counter_mode { |
| 662 | r.prescaler().write(|w| w.set_prescaler(vals::Prescaler::DIV_16)); | 815 | CounterMode::UpAndDown => w.set_updown(vals::Updown::UP_AND_DOWN), |
| 663 | r.countertop().write(|w| w.set_countertop(1000)); | 816 | CounterMode::Up => w.set_updown(vals::Updown::UP), |
| 817 | }); | ||
| 818 | r.prescaler() | ||
| 819 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(config.prescaler as u8))); | ||
| 820 | r.countertop().write(|w| w.set_countertop(config.max_duty)); | ||
| 664 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::DISABLED)); | 821 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::DISABLED)); |
| 665 | 822 | ||
| 666 | pwm | 823 | pwm |
| @@ -684,17 +841,33 @@ impl<'d> SimplePwm<'d> { | |||
| 684 | self.r.enable().write(|w| w.set_enable(false)); | 841 | self.r.enable().write(|w| w.set_enable(false)); |
| 685 | } | 842 | } |
| 686 | 843 | ||
| 687 | /// Returns the current duty of the channel | 844 | /// Returns the current duty of the channel. |
| 688 | pub fn duty(&self, channel: usize) -> u16 { | 845 | pub fn duty(&self, channel: usize) -> DutyCycle { |
| 689 | self.duty[channel] | 846 | self.duty[channel] |
| 690 | } | 847 | } |
| 691 | 848 | ||
| 692 | /// Sets duty cycle (15 bit) for a PWM channel. | 849 | /// Sets duty cycle (15 bit) and polarity for a PWM channel. |
| 693 | pub fn set_duty(&mut self, channel: usize, duty: u16) { | 850 | pub fn set_duty(&mut self, channel: usize, duty: DutyCycle) { |
| 694 | self.duty[channel] = duty & 0x7FFF; | 851 | self.duty[channel] = duty; |
| 852 | self.sync_duty_cyles_to_peripheral(); | ||
| 853 | } | ||
| 854 | |||
| 855 | /// Sets the duty cycle (15 bit) and polarity for all PWM channels. | ||
| 856 | /// | ||
| 857 | /// You can safely set the duty cycle of disabled PWM channels. | ||
| 858 | /// | ||
| 859 | /// When using this function, a single DMA transfer sets all the duty cycles. | ||
| 860 | /// If you call [`Self::set_duty()`] multiple times, | ||
| 861 | /// each duty cycle will be set by a separate DMA transfer. | ||
| 862 | pub fn set_all_duties(&mut self, duty: [DutyCycle; 4]) { | ||
| 863 | self.duty = duty; | ||
| 864 | self.sync_duty_cyles_to_peripheral(); | ||
| 865 | } | ||
| 695 | 866 | ||
| 867 | /// Transfer the duty cycles from `self` to the peripheral. | ||
| 868 | fn sync_duty_cyles_to_peripheral(&self) { | ||
| 696 | // reload ptr in case self was moved | 869 | // reload ptr in case self was moved |
| 697 | self.r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); | 870 | self.r.dma().seq(0).ptr().write_value((self.duty).as_ptr() as u32); |
| 698 | 871 | ||
| 699 | // defensive before seqstart | 872 | // defensive before seqstart |
| 700 | compiler_fence(Ordering::SeqCst); | 873 | compiler_fence(Ordering::SeqCst); |
| @@ -702,7 +875,7 @@ impl<'d> SimplePwm<'d> { | |||
| 702 | self.r.events_seqend(0).write_value(0); | 875 | self.r.events_seqend(0).write_value(0); |
| 703 | 876 | ||
| 704 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 877 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 705 | self.r.tasks_seqstart(0).write_value(1); | 878 | self.r.tasks_dma().seq(0).start().write_value(1); |
| 706 | 879 | ||
| 707 | // defensive wait until waveform is loaded after seqstart so set_duty | 880 | // defensive wait until waveform is loaded after seqstart so set_duty |
| 708 | // can't be called again while dma is still reading | 881 | // can't be called again while dma is still reading |
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index a199c1c4d..ca8cbd73e 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -10,6 +10,7 @@ use core::task::Poll; | |||
| 10 | use embassy_hal_internal::drop::OnDrop; | 10 | use embassy_hal_internal::drop::OnDrop; |
| 11 | use embassy_hal_internal::{Peri, impl_peripheral}; | 11 | use embassy_hal_internal::{Peri, impl_peripheral}; |
| 12 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 13 | #[cfg(not(feature = "_nrf54l"))] | ||
| 13 | pub(crate) use vals::Psel as InputChannel; | 14 | pub(crate) use vals::Psel as InputChannel; |
| 14 | 15 | ||
| 15 | use crate::interrupt::InterruptExt; | 16 | use crate::interrupt::InterruptExt; |
| @@ -84,6 +85,7 @@ pub struct ChannelConfig<'d> { | |||
| 84 | /// Gain used to control the effective input range of the SAADC. | 85 | /// Gain used to control the effective input range of the SAADC. |
| 85 | pub gain: Gain, | 86 | pub gain: Gain, |
| 86 | /// Positive channel resistor control. | 87 | /// Positive channel resistor control. |
| 88 | #[cfg(not(feature = "_nrf54l"))] | ||
| 87 | pub resistor: Resistor, | 89 | pub resistor: Resistor, |
| 88 | /// Acquisition time in microseconds. | 90 | /// Acquisition time in microseconds. |
| 89 | pub time: Time, | 91 | pub time: Time, |
| @@ -98,7 +100,11 @@ impl<'d> ChannelConfig<'d> { | |||
| 98 | pub fn single_ended(input: impl Input + 'd) -> Self { | 100 | pub fn single_ended(input: impl Input + 'd) -> Self { |
| 99 | Self { | 101 | Self { |
| 100 | reference: Reference::INTERNAL, | 102 | reference: Reference::INTERNAL, |
| 103 | #[cfg(not(feature = "_nrf54l"))] | ||
| 101 | gain: Gain::GAIN1_6, | 104 | gain: Gain::GAIN1_6, |
| 105 | #[cfg(feature = "_nrf54l")] | ||
| 106 | gain: Gain::GAIN2_8, | ||
| 107 | #[cfg(not(feature = "_nrf54l"))] | ||
| 102 | resistor: Resistor::BYPASS, | 108 | resistor: Resistor::BYPASS, |
| 103 | time: Time::_10US, | 109 | time: Time::_10US, |
| 104 | p_channel: input.degrade_saadc(), | 110 | p_channel: input.degrade_saadc(), |
| @@ -109,7 +115,11 @@ impl<'d> ChannelConfig<'d> { | |||
| 109 | pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { | 115 | pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { |
| 110 | Self { | 116 | Self { |
| 111 | reference: Reference::INTERNAL, | 117 | reference: Reference::INTERNAL, |
| 118 | #[cfg(not(feature = "_nrf54l"))] | ||
| 112 | gain: Gain::GAIN1_6, | 119 | gain: Gain::GAIN1_6, |
| 120 | #[cfg(feature = "_nrf54l")] | ||
| 121 | gain: Gain::GAIN2_8, | ||
| 122 | #[cfg(not(feature = "_nrf54l"))] | ||
| 113 | resistor: Resistor::BYPASS, | 123 | resistor: Resistor::BYPASS, |
| 114 | time: Time::_10US, | 124 | time: Time::_10US, |
| 115 | p_channel: p_input.degrade_saadc(), | 125 | p_channel: p_input.degrade_saadc(), |
| @@ -118,6 +128,8 @@ impl<'d> ChannelConfig<'d> { | |||
| 118 | } | 128 | } |
| 119 | } | 129 | } |
| 120 | 130 | ||
| 131 | const CNT_UNIT: usize = if cfg!(feature = "_nrf54l") { 2 } else { 1 }; | ||
| 132 | |||
| 121 | /// Value returned by the SAADC callback, deciding what happens next. | 133 | /// Value returned by the SAADC callback, deciding what happens next. |
| 122 | #[derive(PartialEq)] | 134 | #[derive(PartialEq)] |
| 123 | pub enum CallbackResult { | 135 | pub enum CallbackResult { |
| @@ -150,19 +162,38 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 150 | r.oversample().write(|w| w.set_oversample(oversample.into())); | 162 | r.oversample().write(|w| w.set_oversample(oversample.into())); |
| 151 | 163 | ||
| 152 | for (i, cc) in channel_configs.iter().enumerate() { | 164 | for (i, cc) in channel_configs.iter().enumerate() { |
| 165 | #[cfg(not(feature = "_nrf54l"))] | ||
| 153 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); | 166 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); |
| 167 | #[cfg(feature = "_nrf54l")] | ||
| 168 | r.ch(i).pselp().write(|w| { | ||
| 169 | w.set_port(cc.p_channel.port()); | ||
| 170 | w.set_pin(cc.p_channel.pin()); | ||
| 171 | w.set_internal(cc.p_channel.internal()); | ||
| 172 | w.set_connect(cc.p_channel.connect()); | ||
| 173 | }); | ||
| 154 | if let Some(n_channel) = &cc.n_channel { | 174 | if let Some(n_channel) = &cc.n_channel { |
| 175 | #[cfg(not(feature = "_nrf54l"))] | ||
| 155 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); | 176 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); |
| 177 | #[cfg(feature = "_nrf54l")] | ||
| 178 | r.ch(i).pseln().write(|w| { | ||
| 179 | w.set_port(n_channel.port()); | ||
| 180 | w.set_pin(n_channel.pin()); | ||
| 181 | w.set_connect(n_channel.connect().to_bits().into()); | ||
| 182 | }); | ||
| 156 | } | 183 | } |
| 157 | r.ch(i).config().write(|w| { | 184 | r.ch(i).config().write(|w| { |
| 158 | w.set_refsel(cc.reference.into()); | 185 | w.set_refsel(cc.reference.into()); |
| 159 | w.set_gain(cc.gain.into()); | 186 | w.set_gain(cc.gain.into()); |
| 160 | w.set_tacq(cc.time.into()); | 187 | w.set_tacq(cc.time.into()); |
| 188 | #[cfg(feature = "_nrf54l")] | ||
| 189 | w.set_tconv(7); // 7 is the default from the Nordic C driver | ||
| 161 | w.set_mode(match cc.n_channel { | 190 | w.set_mode(match cc.n_channel { |
| 162 | None => vals::ConfigMode::SE, | 191 | None => vals::ConfigMode::SE, |
| 163 | Some(_) => vals::ConfigMode::DIFF, | 192 | Some(_) => vals::ConfigMode::DIFF, |
| 164 | }); | 193 | }); |
| 194 | #[cfg(not(feature = "_nrf54l"))] | ||
| 165 | w.set_resp(cc.resistor.into()); | 195 | w.set_resp(cc.resistor.into()); |
| 196 | #[cfg(not(feature = "_nrf54l"))] | ||
| 166 | w.set_resn(vals::Resn::BYPASS); | 197 | w.set_resn(vals::Resn::BYPASS); |
| 167 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); | 198 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); |
| 168 | }); | 199 | }); |
| @@ -222,7 +253,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 222 | 253 | ||
| 223 | // Set up the DMA | 254 | // Set up the DMA |
| 224 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); | 255 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); |
| 225 | r.result().maxcnt().write(|w| w.set_maxcnt(N as _)); | 256 | r.result().maxcnt().write(|w| w.set_maxcnt((N * CNT_UNIT) as _)); |
| 226 | 257 | ||
| 227 | // Reset and enable the end event | 258 | // Reset and enable the end event |
| 228 | r.events_end().write_value(0); | 259 | r.events_end().write_value(0); |
| @@ -354,7 +385,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 354 | 385 | ||
| 355 | // Set up the initial DMA | 386 | // Set up the initial DMA |
| 356 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); | 387 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); |
| 357 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N) as _)); | 388 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N * CNT_UNIT) as _)); |
| 358 | 389 | ||
| 359 | // Reset and enable the events | 390 | // Reset and enable the events |
| 360 | r.events_end().write_value(0); | 391 | r.events_end().write_value(0); |
| @@ -473,12 +504,21 @@ impl<'d, const N: usize> Drop for Saadc<'d, N> { | |||
| 473 | let r = Self::regs(); | 504 | let r = Self::regs(); |
| 474 | r.enable().write(|w| w.set_enable(false)); | 505 | r.enable().write(|w| w.set_enable(false)); |
| 475 | for i in 0..N { | 506 | for i in 0..N { |
| 476 | r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); | 507 | #[cfg(not(feature = "_nrf54l"))] |
| 477 | r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); | 508 | { |
| 509 | r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); | ||
| 510 | r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); | ||
| 511 | } | ||
| 512 | #[cfg(feature = "_nrf54l")] | ||
| 513 | { | ||
| 514 | r.ch(i).pselp().write(|w| w.set_connect(vals::PselpConnect::NC)); | ||
| 515 | r.ch(i).pseln().write(|w| w.set_connect(vals::PselnConnect::NC)); | ||
| 516 | } | ||
| 478 | } | 517 | } |
| 479 | } | 518 | } |
| 480 | } | 519 | } |
| 481 | 520 | ||
| 521 | #[cfg(not(feature = "_nrf54l"))] | ||
| 482 | impl From<Gain> for vals::Gain { | 522 | impl From<Gain> for vals::Gain { |
| 483 | fn from(gain: Gain) -> Self { | 523 | fn from(gain: Gain) -> Self { |
| 484 | match gain { | 524 | match gain { |
| @@ -494,7 +534,24 @@ impl From<Gain> for vals::Gain { | |||
| 494 | } | 534 | } |
| 495 | } | 535 | } |
| 496 | 536 | ||
| 537 | #[cfg(feature = "_nrf54l")] | ||
| 538 | impl From<Gain> for vals::Gain { | ||
| 539 | fn from(gain: Gain) -> Self { | ||
| 540 | match gain { | ||
| 541 | Gain::GAIN2_8 => vals::Gain::GAIN2_8, | ||
| 542 | Gain::GAIN2_7 => vals::Gain::GAIN2_7, | ||
| 543 | Gain::GAIN2_6 => vals::Gain::GAIN2_6, | ||
| 544 | Gain::GAIN2_5 => vals::Gain::GAIN2_5, | ||
| 545 | Gain::GAIN2_4 => vals::Gain::GAIN2_4, | ||
| 546 | Gain::GAIN2_3 => vals::Gain::GAIN2_3, | ||
| 547 | Gain::GAIN1 => vals::Gain::GAIN1, | ||
| 548 | Gain::GAIN2 => vals::Gain::GAIN2, | ||
| 549 | } | ||
| 550 | } | ||
| 551 | } | ||
| 552 | |||
| 497 | /// Gain control | 553 | /// Gain control |
| 554 | #[cfg(not(feature = "_nrf54l"))] | ||
| 498 | #[non_exhaustive] | 555 | #[non_exhaustive] |
| 499 | #[derive(Clone, Copy)] | 556 | #[derive(Clone, Copy)] |
| 500 | pub enum Gain { | 557 | pub enum Gain { |
| @@ -516,11 +573,37 @@ pub enum Gain { | |||
| 516 | GAIN4 = 7, | 573 | GAIN4 = 7, |
| 517 | } | 574 | } |
| 518 | 575 | ||
| 576 | /// Gain control | ||
| 577 | #[cfg(feature = "_nrf54l")] | ||
| 578 | #[non_exhaustive] | ||
| 579 | #[derive(Clone, Copy)] | ||
| 580 | pub enum Gain { | ||
| 581 | /// 2/8 | ||
| 582 | GAIN2_8 = 0, | ||
| 583 | /// 2/7 | ||
| 584 | GAIN2_7 = 1, | ||
| 585 | /// 2/6 | ||
| 586 | GAIN2_6 = 2, | ||
| 587 | /// 2/5 | ||
| 588 | GAIN2_5 = 3, | ||
| 589 | /// 2/4 | ||
| 590 | GAIN2_4 = 4, | ||
| 591 | /// 2/3 | ||
| 592 | GAIN2_3 = 5, | ||
| 593 | /// 1 | ||
| 594 | GAIN1 = 6, | ||
| 595 | /// 2 | ||
| 596 | GAIN2 = 7, | ||
| 597 | } | ||
| 598 | |||
| 519 | impl From<Reference> for vals::Refsel { | 599 | impl From<Reference> for vals::Refsel { |
| 520 | fn from(reference: Reference) -> Self { | 600 | fn from(reference: Reference) -> Self { |
| 521 | match reference { | 601 | match reference { |
| 522 | Reference::INTERNAL => vals::Refsel::INTERNAL, | 602 | Reference::INTERNAL => vals::Refsel::INTERNAL, |
| 603 | #[cfg(not(feature = "_nrf54l"))] | ||
| 523 | Reference::VDD1_4 => vals::Refsel::VDD1_4, | 604 | Reference::VDD1_4 => vals::Refsel::VDD1_4, |
| 605 | #[cfg(feature = "_nrf54l")] | ||
| 606 | Reference::EXTERNAL => vals::Refsel::EXTERNAL, | ||
| 524 | } | 607 | } |
| 525 | } | 608 | } |
| 526 | } | 609 | } |
| @@ -531,10 +614,15 @@ impl From<Reference> for vals::Refsel { | |||
| 531 | pub enum Reference { | 614 | pub enum Reference { |
| 532 | /// Internal reference (0.6 V) | 615 | /// Internal reference (0.6 V) |
| 533 | INTERNAL = 0, | 616 | INTERNAL = 0, |
| 617 | #[cfg(not(feature = "_nrf54l"))] | ||
| 534 | /// VDD/4 as reference | 618 | /// VDD/4 as reference |
| 535 | VDD1_4 = 1, | 619 | VDD1_4 = 1, |
| 620 | /// PADC_EXT_REF_1V2 as reference | ||
| 621 | #[cfg(feature = "_nrf54l")] | ||
| 622 | EXTERNAL = 1, | ||
| 536 | } | 623 | } |
| 537 | 624 | ||
| 625 | #[cfg(not(feature = "_nrf54l"))] | ||
| 538 | impl From<Resistor> for vals::Resp { | 626 | impl From<Resistor> for vals::Resp { |
| 539 | fn from(resistor: Resistor) -> Self { | 627 | fn from(resistor: Resistor) -> Self { |
| 540 | match resistor { | 628 | match resistor { |
| @@ -549,6 +637,7 @@ impl From<Resistor> for vals::Resp { | |||
| 549 | /// Positive channel resistor control | 637 | /// Positive channel resistor control |
| 550 | #[non_exhaustive] | 638 | #[non_exhaustive] |
| 551 | #[derive(Clone, Copy)] | 639 | #[derive(Clone, Copy)] |
| 640 | #[cfg(not(feature = "_nrf54l"))] | ||
| 552 | pub enum Resistor { | 641 | pub enum Resistor { |
| 553 | /// Bypass resistor ladder | 642 | /// Bypass resistor ladder |
| 554 | BYPASS = 0, | 643 | BYPASS = 0, |
| @@ -560,6 +649,7 @@ pub enum Resistor { | |||
| 560 | VDD1_2 = 3, | 649 | VDD1_2 = 3, |
| 561 | } | 650 | } |
| 562 | 651 | ||
| 652 | #[cfg(not(feature = "_nrf54l"))] | ||
| 563 | impl From<Time> for vals::Tacq { | 653 | impl From<Time> for vals::Tacq { |
| 564 | fn from(time: Time) -> Self { | 654 | fn from(time: Time) -> Self { |
| 565 | match time { | 655 | match time { |
| @@ -573,6 +663,20 @@ impl From<Time> for vals::Tacq { | |||
| 573 | } | 663 | } |
| 574 | } | 664 | } |
| 575 | 665 | ||
| 666 | #[cfg(feature = "_nrf54l")] | ||
| 667 | impl From<Time> for u16 { | ||
| 668 | fn from(time: Time) -> Self { | ||
| 669 | match time { | ||
| 670 | Time::_3US => (3000 / 125) - 1, | ||
| 671 | Time::_5US => (5000 / 125) - 1, | ||
| 672 | Time::_10US => (10000 / 125) - 1, | ||
| 673 | Time::_15US => (15000 / 125) - 1, | ||
| 674 | Time::_20US => (20000 / 125) - 1, | ||
| 675 | Time::_40US => (40000 / 125) - 1, | ||
| 676 | } | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 576 | /// Acquisition time, the time the SAADC uses to sample the input voltage | 680 | /// Acquisition time, the time the SAADC uses to sample the input voltage |
| 577 | #[non_exhaustive] | 681 | #[non_exhaustive] |
| 578 | #[derive(Clone, Copy)] | 682 | #[derive(Clone, Copy)] |
| @@ -657,7 +761,20 @@ pub enum Resolution { | |||
| 657 | } | 761 | } |
| 658 | 762 | ||
| 659 | pub(crate) trait SealedInput { | 763 | pub(crate) trait SealedInput { |
| 764 | #[cfg(not(feature = "_nrf54l"))] | ||
| 660 | fn channel(&self) -> InputChannel; | 765 | fn channel(&self) -> InputChannel; |
| 766 | |||
| 767 | #[cfg(feature = "_nrf54l")] | ||
| 768 | fn pin(&self) -> u8; | ||
| 769 | |||
| 770 | #[cfg(feature = "_nrf54l")] | ||
| 771 | fn port(&self) -> u8; | ||
| 772 | |||
| 773 | #[cfg(feature = "_nrf54l")] | ||
| 774 | fn internal(&self) -> vals::Internal; | ||
| 775 | |||
| 776 | #[cfg(feature = "_nrf54l")] | ||
| 777 | fn connect(&self) -> vals::PselpConnect; | ||
| 661 | } | 778 | } |
| 662 | 779 | ||
| 663 | /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. | 780 | /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. |
| @@ -667,6 +784,7 @@ pub trait Input: SealedInput + Sized { | |||
| 667 | /// | 784 | /// |
| 668 | /// This allows using several inputs in situations that might require | 785 | /// This allows using several inputs in situations that might require |
| 669 | /// them to be the same type, like putting them in an array. | 786 | /// them to be the same type, like putting them in an array. |
| 787 | #[cfg(not(feature = "_nrf54l"))] | ||
| 670 | fn degrade_saadc<'a>(self) -> AnyInput<'a> | 788 | fn degrade_saadc<'a>(self) -> AnyInput<'a> |
| 671 | where | 789 | where |
| 672 | Self: 'a, | 790 | Self: 'a, |
| @@ -676,17 +794,49 @@ pub trait Input: SealedInput + Sized { | |||
| 676 | _phantom: core::marker::PhantomData, | 794 | _phantom: core::marker::PhantomData, |
| 677 | } | 795 | } |
| 678 | } | 796 | } |
| 797 | |||
| 798 | /// Convert this SAADC input to a type-erased `AnyInput`. | ||
| 799 | /// | ||
| 800 | /// This allows using several inputs in situations that might require | ||
| 801 | /// them to be the same type, like putting them in an array. | ||
| 802 | #[cfg(feature = "_nrf54l")] | ||
| 803 | fn degrade_saadc<'a>(self) -> AnyInput<'a> | ||
| 804 | where | ||
| 805 | Self: 'a, | ||
| 806 | { | ||
| 807 | AnyInput { | ||
| 808 | pin: self.pin(), | ||
| 809 | port: self.port(), | ||
| 810 | internal: self.internal(), | ||
| 811 | connect: self.connect(), | ||
| 812 | _phantom: core::marker::PhantomData, | ||
| 813 | } | ||
| 814 | } | ||
| 679 | } | 815 | } |
| 680 | 816 | ||
| 681 | /// A type-erased SAADC input. | 817 | /// A type-erased SAADC input. |
| 682 | /// | 818 | /// |
| 683 | /// This allows using several inputs in situations that might require | 819 | /// This allows using several inputs in situations that might require |
| 684 | /// them to be the same type, like putting them in an array. | 820 | /// them to be the same type, like putting them in an array. |
| 821 | #[cfg(not(feature = "_nrf54l"))] | ||
| 685 | pub struct AnyInput<'a> { | 822 | pub struct AnyInput<'a> { |
| 686 | channel: InputChannel, | 823 | channel: InputChannel, |
| 687 | _phantom: PhantomData<&'a ()>, | 824 | _phantom: PhantomData<&'a ()>, |
| 688 | } | 825 | } |
| 689 | 826 | ||
| 827 | /// A type-erased SAADC input. | ||
| 828 | /// | ||
| 829 | /// This allows using several inputs in situations that might require | ||
| 830 | /// them to be the same type, like putting them in an array. | ||
| 831 | #[cfg(feature = "_nrf54l")] | ||
| 832 | pub struct AnyInput<'a> { | ||
| 833 | pin: u8, | ||
| 834 | port: u8, | ||
| 835 | internal: vals::Internal, | ||
| 836 | connect: vals::PselpConnect, | ||
| 837 | _phantom: PhantomData<&'a ()>, | ||
| 838 | } | ||
| 839 | |||
| 690 | impl<'a> AnyInput<'a> { | 840 | impl<'a> AnyInput<'a> { |
| 691 | /// Reborrow into a "child" AnyInput. | 841 | /// Reborrow into a "child" AnyInput. |
| 692 | /// | 842 | /// |
| @@ -694,21 +844,56 @@ impl<'a> AnyInput<'a> { | |||
| 694 | pub fn reborrow(&mut self) -> AnyInput<'_> { | 844 | pub fn reborrow(&mut self) -> AnyInput<'_> { |
| 695 | // safety: we're returning the clone inside a new Peripheral that borrows | 845 | // safety: we're returning the clone inside a new Peripheral that borrows |
| 696 | // self, so user code can't use both at the same time. | 846 | // self, so user code can't use both at the same time. |
| 697 | Self { | 847 | #[cfg(not(feature = "_nrf54l"))] |
| 698 | channel: self.channel, | 848 | { |
| 699 | _phantom: PhantomData, | 849 | Self { |
| 850 | channel: self.channel, | ||
| 851 | _phantom: PhantomData, | ||
| 852 | } | ||
| 853 | } | ||
| 854 | #[cfg(feature = "_nrf54l")] | ||
| 855 | { | ||
| 856 | Self { | ||
| 857 | pin: self.pin, | ||
| 858 | port: self.port, | ||
| 859 | internal: self.internal, | ||
| 860 | connect: self.connect, | ||
| 861 | _phantom: PhantomData, | ||
| 862 | } | ||
| 700 | } | 863 | } |
| 701 | } | 864 | } |
| 702 | } | 865 | } |
| 703 | 866 | ||
| 704 | impl SealedInput for AnyInput<'_> { | 867 | impl SealedInput for AnyInput<'_> { |
| 868 | #[cfg(not(feature = "_nrf54l"))] | ||
| 705 | fn channel(&self) -> InputChannel { | 869 | fn channel(&self) -> InputChannel { |
| 706 | self.channel | 870 | self.channel |
| 707 | } | 871 | } |
| 872 | |||
| 873 | #[cfg(feature = "_nrf54l")] | ||
| 874 | fn pin(&self) -> u8 { | ||
| 875 | self.pin | ||
| 876 | } | ||
| 877 | |||
| 878 | #[cfg(feature = "_nrf54l")] | ||
| 879 | fn port(&self) -> u8 { | ||
| 880 | self.port | ||
| 881 | } | ||
| 882 | |||
| 883 | #[cfg(feature = "_nrf54l")] | ||
| 884 | fn internal(&self) -> vals::Internal { | ||
| 885 | self.internal | ||
| 886 | } | ||
| 887 | |||
| 888 | #[cfg(feature = "_nrf54l")] | ||
| 889 | fn connect(&self) -> vals::PselpConnect { | ||
| 890 | self.connect | ||
| 891 | } | ||
| 708 | } | 892 | } |
| 709 | 893 | ||
| 710 | impl Input for AnyInput<'_> {} | 894 | impl Input for AnyInput<'_> {} |
| 711 | 895 | ||
| 896 | #[cfg(not(feature = "_nrf54l"))] | ||
| 712 | macro_rules! impl_saadc_input { | 897 | macro_rules! impl_saadc_input { |
| 713 | ($pin:ident, $ch:ident) => { | 898 | ($pin:ident, $ch:ident) => { |
| 714 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); | 899 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); |
| @@ -723,15 +908,45 @@ macro_rules! impl_saadc_input { | |||
| 723 | }; | 908 | }; |
| 724 | } | 909 | } |
| 725 | 910 | ||
| 911 | #[cfg(feature = "_nrf54l")] | ||
| 912 | macro_rules! impl_saadc_input { | ||
| 913 | ($pin:ident, $port:expr, $ain:expr) => { | ||
| 914 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $port, $ain, AVDD, ANALOG_INPUT); | ||
| 915 | }; | ||
| 916 | (@local, $pin:ty, $port:expr, $ain:expr, $internal:ident, $connect:ident) => { | ||
| 917 | impl crate::saadc::SealedInput for $pin { | ||
| 918 | fn pin(&self) -> u8 { | ||
| 919 | $ain | ||
| 920 | } | ||
| 921 | |||
| 922 | fn port(&self) -> u8 { | ||
| 923 | $port | ||
| 924 | } | ||
| 925 | |||
| 926 | fn internal(&self) -> crate::pac::saadc::vals::Internal { | ||
| 927 | crate::pac::saadc::vals::Internal::$internal | ||
| 928 | } | ||
| 929 | |||
| 930 | fn connect(&self) -> crate::pac::saadc::vals::PselpConnect { | ||
| 931 | crate::pac::saadc::vals::PselpConnect::$connect | ||
| 932 | } | ||
| 933 | } | ||
| 934 | impl crate::saadc::Input for $pin {} | ||
| 935 | }; | ||
| 936 | } | ||
| 937 | |||
| 726 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 938 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 727 | /// internal voltage. | 939 | /// internal voltage. |
| 728 | pub struct VddInput; | 940 | pub struct VddInput; |
| 729 | 941 | ||
| 730 | impl_peripheral!(VddInput); | 942 | impl_peripheral!(VddInput); |
| 943 | #[cfg(not(feature = "_nrf54l"))] | ||
| 731 | #[cfg(not(feature = "_nrf91"))] | 944 | #[cfg(not(feature = "_nrf91"))] |
| 732 | impl_saadc_input!(@local, VddInput, VDD); | 945 | impl_saadc_input!(@local, VddInput, VDD); |
| 733 | #[cfg(feature = "_nrf91")] | 946 | #[cfg(feature = "_nrf91")] |
| 734 | impl_saadc_input!(@local, VddInput, VDD_GPIO); | 947 | impl_saadc_input!(@local, VddInput, VDD_GPIO); |
| 948 | #[cfg(feature = "_nrf54l")] | ||
| 949 | impl_saadc_input!(@local, VddInput, 0, 0, VDD, INTERNAL); | ||
| 735 | 950 | ||
| 736 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 951 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 737 | /// VDDH / 5 voltage. | 952 | /// VDDH / 5 voltage. |
| @@ -743,3 +958,21 @@ impl_peripheral!(VddhDiv5Input); | |||
| 743 | 958 | ||
| 744 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | 959 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] |
| 745 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); | 960 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); |
| 961 | |||
| 962 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | ||
| 963 | /// AVDD internal voltage of the nrf54l chip family. | ||
| 964 | #[cfg(feature = "_nrf54l")] | ||
| 965 | pub struct AVddInput; | ||
| 966 | #[cfg(feature = "_nrf54l")] | ||
| 967 | embassy_hal_internal::impl_peripheral!(AVddInput); | ||
| 968 | #[cfg(feature = "_nrf54l")] | ||
| 969 | impl_saadc_input!(@local, AVddInput, 0, 0, AVDD, INTERNAL); | ||
| 970 | |||
| 971 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | ||
| 972 | /// DVDD internal voltage of the nrf54l chip family. | ||
| 973 | #[cfg(feature = "_nrf54l")] | ||
| 974 | pub struct DVddInput; | ||
| 975 | #[cfg(feature = "_nrf54l")] | ||
| 976 | embassy_hal_internal::impl_peripheral!(DVddInput); | ||
| 977 | #[cfg(feature = "_nrf54l")] | ||
| 978 | impl_saadc_input!(@local, DVddInput, 0, 0, DVDD, INTERNAL); | ||
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index ce994dbc9..34485609b 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -13,7 +13,7 @@ use embassy_embedded_hal::SetConfig; | |||
| 13 | use embassy_hal_internal::{Peri, PeripheralType}; | 13 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 14 | use embassy_sync::waitqueue::AtomicWaker; | 14 | use embassy_sync::waitqueue::AtomicWaker; |
| 15 | pub use embedded_hal_02::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode, Phase, Polarity}; | 15 | pub use embedded_hal_02::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode, Phase, Polarity}; |
| 16 | pub use pac::spim::vals::{Frequency, Order as BitOrder}; | 16 | pub use pac::spim::vals::Order as BitOrder; |
| 17 | 17 | ||
| 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 19 | use crate::gpio::{self, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; | 19 | use crate::gpio::{self, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; |
| @@ -23,6 +23,110 @@ use crate::pac::spim::vals; | |||
| 23 | use crate::util::slice_in_ram_or; | 23 | use crate::util::slice_in_ram_or; |
| 24 | use crate::{interrupt, pac}; | 24 | use crate::{interrupt, pac}; |
| 25 | 25 | ||
| 26 | /// SPI frequencies. | ||
| 27 | #[repr(transparent)] | ||
| 28 | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] | ||
| 29 | pub struct Frequency(u32); | ||
| 30 | impl Frequency { | ||
| 31 | #[doc = "125 kbps"] | ||
| 32 | pub const K125: Self = Self(0x0200_0000); | ||
| 33 | #[doc = "250 kbps"] | ||
| 34 | pub const K250: Self = Self(0x0400_0000); | ||
| 35 | #[doc = "500 kbps"] | ||
| 36 | pub const K500: Self = Self(0x0800_0000); | ||
| 37 | #[doc = "1 Mbps"] | ||
| 38 | pub const M1: Self = Self(0x1000_0000); | ||
| 39 | #[doc = "2 Mbps"] | ||
| 40 | pub const M2: Self = Self(0x2000_0000); | ||
| 41 | #[doc = "4 Mbps"] | ||
| 42 | pub const M4: Self = Self(0x4000_0000); | ||
| 43 | #[doc = "8 Mbps"] | ||
| 44 | pub const M8: Self = Self(0x8000_0000); | ||
| 45 | #[cfg(not(feature = "_spi-v1"))] | ||
| 46 | #[doc = "16 Mbps"] | ||
| 47 | pub const M16: Self = Self(0x0a00_0000); | ||
| 48 | #[cfg(not(feature = "_spi-v1"))] | ||
| 49 | #[doc = "32 Mbps"] | ||
| 50 | pub const M32: Self = Self(0x1400_0000); | ||
| 51 | } | ||
| 52 | |||
| 53 | impl Frequency { | ||
| 54 | #[cfg(feature = "_nrf54l")] | ||
| 55 | fn to_divisor(&self, clk: u32) -> u8 { | ||
| 56 | let frequency = match *self { | ||
| 57 | #[cfg(not(feature = "_spi-v1"))] | ||
| 58 | Self::M32 => 32_000_000, | ||
| 59 | #[cfg(not(feature = "_spi-v1"))] | ||
| 60 | Self::M16 => 16_000_000, | ||
| 61 | Self::M8 => 8_000_000, | ||
| 62 | Self::M4 => 4_000_000, | ||
| 63 | Self::M2 => 2_000_000, | ||
| 64 | Self::M1 => 1_000_000, | ||
| 65 | Self::K500 => 500_000, | ||
| 66 | Self::K250 => 250_000, | ||
| 67 | Self::K125 => 125_000, | ||
| 68 | _ => unreachable!(), | ||
| 69 | }; | ||
| 70 | let divisor = (clk / frequency) as u8; | ||
| 71 | divisor | ||
| 72 | } | ||
| 73 | } | ||
| 74 | impl core::fmt::Debug for Frequency { | ||
| 75 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { | ||
| 76 | match self.0 { | ||
| 77 | 0x0200_0000 => f.write_str("K125"), | ||
| 78 | 0x0400_0000 => f.write_str("K250"), | ||
| 79 | 0x0800_0000 => f.write_str("K500"), | ||
| 80 | 0x0a00_0000 => f.write_str("M16"), | ||
| 81 | 0x1000_0000 => f.write_str("M1"), | ||
| 82 | 0x1400_0000 => f.write_str("M32"), | ||
| 83 | 0x2000_0000 => f.write_str("M2"), | ||
| 84 | 0x4000_0000 => f.write_str("M4"), | ||
| 85 | 0x8000_0000 => f.write_str("M8"), | ||
| 86 | other => core::write!(f, "0x{:02X}", other), | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | #[cfg(feature = "defmt")] | ||
| 92 | impl defmt::Format for Frequency { | ||
| 93 | fn format(&self, f: defmt::Formatter) { | ||
| 94 | match self.0 { | ||
| 95 | 0x0200_0000 => defmt::write!(f, "K125"), | ||
| 96 | 0x0400_0000 => defmt::write!(f, "K250"), | ||
| 97 | 0x0800_0000 => defmt::write!(f, "K500"), | ||
| 98 | 0x0a00_0000 => defmt::write!(f, "M16"), | ||
| 99 | 0x1000_0000 => defmt::write!(f, "M1"), | ||
| 100 | 0x1400_0000 => defmt::write!(f, "M32"), | ||
| 101 | 0x2000_0000 => defmt::write!(f, "M2"), | ||
| 102 | 0x4000_0000 => defmt::write!(f, "M4"), | ||
| 103 | 0x8000_0000 => defmt::write!(f, "M8"), | ||
| 104 | other => defmt::write!(f, "0x{:02X}", other), | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | #[cfg(not(feature = "_nrf54l"))] | ||
| 110 | impl Into<pac::spim::vals::Frequency> for Frequency { | ||
| 111 | fn into(self) -> pac::spim::vals::Frequency { | ||
| 112 | use pac::spim::vals::Frequency as Freq; | ||
| 113 | match self { | ||
| 114 | #[cfg(not(feature = "_spi-v1"))] | ||
| 115 | Self::M32 => Freq::M32, | ||
| 116 | #[cfg(not(feature = "_spi-v1"))] | ||
| 117 | Self::M16 => Freq::M16, | ||
| 118 | Self::M8 => Freq::M8, | ||
| 119 | Self::M4 => Freq::M4, | ||
| 120 | Self::M2 => Freq::M2, | ||
| 121 | Self::M1 => Freq::M1, | ||
| 122 | Self::K500 => Freq::K500, | ||
| 123 | Self::K250 => Freq::K250, | ||
| 124 | Self::K125 => Freq::K125, | ||
| 125 | _ => unreachable!(), | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 26 | /// SPIM error | 130 | /// SPIM error |
| 27 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 131 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 28 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 132 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -103,6 +207,8 @@ pub struct Spim<'d> { | |||
| 103 | r: pac::spim::Spim, | 207 | r: pac::spim::Spim, |
| 104 | irq: interrupt::Interrupt, | 208 | irq: interrupt::Interrupt, |
| 105 | state: &'static State, | 209 | state: &'static State, |
| 210 | #[cfg(feature = "_nrf54l")] | ||
| 211 | clk: u32, | ||
| 106 | _p: PhantomData<&'d ()>, | 212 | _p: PhantomData<&'d ()>, |
| 107 | } | 213 | } |
| 108 | 214 | ||
| @@ -208,6 +314,8 @@ impl<'d> Spim<'d> { | |||
| 208 | r: T::regs(), | 314 | r: T::regs(), |
| 209 | irq: T::Interrupt::IRQ, | 315 | irq: T::Interrupt::IRQ, |
| 210 | state: T::state(), | 316 | state: T::state(), |
| 317 | #[cfg(feature = "_nrf54l")] | ||
| 318 | clk: T::clk(), | ||
| 211 | _p: PhantomData {}, | 319 | _p: PhantomData {}, |
| 212 | }; | 320 | }; |
| 213 | 321 | ||
| @@ -238,13 +346,13 @@ impl<'d> Spim<'d> { | |||
| 238 | 346 | ||
| 239 | // Set up the DMA read. | 347 | // Set up the DMA read. |
| 240 | let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length); | 348 | let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length); |
| 241 | r.rxd().ptr().write_value(rx_ptr); | 349 | r.dma().rx().ptr().write_value(rx_ptr); |
| 242 | r.rxd().maxcnt().write(|w| w.set_maxcnt(rx_len as _)); | 350 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(rx_len as _)); |
| 243 | 351 | ||
| 244 | // Set up the DMA write. | 352 | // Set up the DMA write. |
| 245 | let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length); | 353 | let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length); |
| 246 | r.txd().ptr().write_value(tx_ptr); | 354 | r.dma().tx().ptr().write_value(tx_ptr); |
| 247 | r.txd().maxcnt().write(|w| w.set_maxcnt(tx_len as _)); | 355 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(tx_len as _)); |
| 248 | 356 | ||
| 249 | /* | 357 | /* |
| 250 | trace!("XFER: offset: {}, length: {}", offset, length); | 358 | trace!("XFER: offset: {}, length: {}", offset, length); |
| @@ -259,8 +367,8 @@ impl<'d> Spim<'d> { | |||
| 259 | r.events_started().write_value(0); | 367 | r.events_started().write_value(0); |
| 260 | 368 | ||
| 261 | // Set rx/tx buffer lengths to 0... | 369 | // Set rx/tx buffer lengths to 0... |
| 262 | r.txd().maxcnt().write(|_| ()); | 370 | r.dma().tx().maxcnt().write(|_| ()); |
| 263 | r.rxd().maxcnt().write(|_| ()); | 371 | r.dma().rx().maxcnt().write(|_| ()); |
| 264 | 372 | ||
| 265 | // ...and keep track of original buffer lengths... | 373 | // ...and keep track of original buffer lengths... |
| 266 | s.tx.store(tx_len as _, Ordering::Relaxed); | 374 | s.tx.store(tx_len as _, Ordering::Relaxed); |
| @@ -447,8 +555,14 @@ impl<'d> Spim<'d> { | |||
| 447 | r.events_end().write_value(0); | 555 | r.events_end().write_value(0); |
| 448 | 556 | ||
| 449 | // Update DMA registers with correct rx/tx buffer sizes | 557 | // Update DMA registers with correct rx/tx buffer sizes |
| 450 | r.rxd().maxcnt().write(|w| w.set_maxcnt(s.rx.load(Ordering::Relaxed))); | 558 | r.dma() |
| 451 | r.txd().maxcnt().write(|w| w.set_maxcnt(s.tx.load(Ordering::Relaxed))); | 559 | .rx() |
| 560 | .maxcnt() | ||
| 561 | .write(|w| w.set_maxcnt(s.rx.load(Ordering::Relaxed))); | ||
| 562 | r.dma() | ||
| 563 | .tx() | ||
| 564 | .maxcnt() | ||
| 565 | .write(|w| w.set_maxcnt(s.tx.load(Ordering::Relaxed))); | ||
| 452 | 566 | ||
| 453 | r.intenset().write(|w| w.set_end(true)); | 567 | r.intenset().write(|w| w.set_end(true)); |
| 454 | // ... and start actual, hopefully glitch-free transmission | 568 | // ... and start actual, hopefully glitch-free transmission |
| @@ -503,6 +617,8 @@ impl State { | |||
| 503 | pub(crate) trait SealedInstance { | 617 | pub(crate) trait SealedInstance { |
| 504 | fn regs() -> pac::spim::Spim; | 618 | fn regs() -> pac::spim::Spim; |
| 505 | fn state() -> &'static State; | 619 | fn state() -> &'static State; |
| 620 | #[cfg(feature = "_nrf54l")] | ||
| 621 | fn clk() -> u32; | ||
| 506 | } | 622 | } |
| 507 | 623 | ||
| 508 | /// SPIM peripheral instance | 624 | /// SPIM peripheral instance |
| @@ -512,6 +628,28 @@ pub trait Instance: SealedInstance + PeripheralType + 'static { | |||
| 512 | type Interrupt: interrupt::typelevel::Interrupt; | 628 | type Interrupt: interrupt::typelevel::Interrupt; |
| 513 | } | 629 | } |
| 514 | 630 | ||
| 631 | #[cfg(feature = "_nrf54l")] | ||
| 632 | macro_rules! impl_spim { | ||
| 633 | ($type:ident, $pac_type:ident, $irq:ident, $clk:expr) => { | ||
| 634 | impl crate::spim::SealedInstance for peripherals::$type { | ||
| 635 | fn regs() -> pac::spim::Spim { | ||
| 636 | pac::$pac_type | ||
| 637 | } | ||
| 638 | fn state() -> &'static crate::spim::State { | ||
| 639 | static STATE: crate::spim::State = crate::spim::State::new(); | ||
| 640 | &STATE | ||
| 641 | } | ||
| 642 | fn clk() -> u32 { | ||
| 643 | $clk | ||
| 644 | } | ||
| 645 | } | ||
| 646 | impl crate::spim::Instance for peripherals::$type { | ||
| 647 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 648 | } | ||
| 649 | }; | ||
| 650 | } | ||
| 651 | |||
| 652 | #[cfg(not(feature = "_nrf54l"))] | ||
| 515 | macro_rules! impl_spim { | 653 | macro_rules! impl_spim { |
| 516 | ($type:ident, $pac_type:ident, $irq:ident) => { | 654 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 517 | impl crate::spim::SealedInstance for peripherals::$type { | 655 | impl crate::spim::SealedInstance for peripherals::$type { |
| @@ -638,7 +776,12 @@ impl<'d> SetConfig for Spim<'d> { | |||
| 638 | 776 | ||
| 639 | // Configure frequency. | 777 | // Configure frequency. |
| 640 | let frequency = config.frequency; | 778 | let frequency = config.frequency; |
| 641 | r.frequency().write(|w| w.set_frequency(frequency)); | 779 | #[cfg(not(feature = "_nrf54l"))] |
| 780 | r.frequency().write(|w| w.set_frequency(frequency.into())); | ||
| 781 | #[cfg(feature = "_nrf54l")] | ||
| 782 | { | ||
| 783 | r.prescaler().write(|w| w.set_divisor(frequency.to_divisor(self.clk))); | ||
| 784 | } | ||
| 642 | 785 | ||
| 643 | // Set over-read character | 786 | // Set over-read character |
| 644 | let orc = config.orc; | 787 | let orc = config.orc; |
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 885821146..96a9c0ae0 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -224,15 +224,15 @@ impl<'d> Spis<'d> { | |||
| 224 | if tx.len() > EASY_DMA_SIZE { | 224 | if tx.len() > EASY_DMA_SIZE { |
| 225 | return Err(Error::TxBufferTooLong); | 225 | return Err(Error::TxBufferTooLong); |
| 226 | } | 226 | } |
| 227 | r.txd().ptr().write_value(tx as *const u8 as _); | 227 | r.dma().tx().ptr().write_value(tx as *const u8 as _); |
| 228 | r.txd().maxcnt().write(|w| w.set_maxcnt(tx.len() as _)); | 228 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(tx.len() as _)); |
| 229 | 229 | ||
| 230 | // Set up the DMA read. | 230 | // Set up the DMA read. |
| 231 | if rx.len() > EASY_DMA_SIZE { | 231 | if rx.len() > EASY_DMA_SIZE { |
| 232 | return Err(Error::RxBufferTooLong); | 232 | return Err(Error::RxBufferTooLong); |
| 233 | } | 233 | } |
| 234 | r.rxd().ptr().write_value(rx as *mut u8 as _); | 234 | r.dma().rx().ptr().write_value(rx as *mut u8 as _); |
| 235 | r.rxd().maxcnt().write(|w| w.set_maxcnt(rx.len() as _)); | 235 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(rx.len() as _)); |
| 236 | 236 | ||
| 237 | // Reset end event. | 237 | // Reset end event. |
| 238 | r.events_end().write_value(0); | 238 | r.events_end().write_value(0); |
| @@ -260,8 +260,8 @@ impl<'d> Spis<'d> { | |||
| 260 | // Wait for 'end' event. | 260 | // Wait for 'end' event. |
| 261 | while r.events_end().read() == 0 {} | 261 | while r.events_end().read() == 0 {} |
| 262 | 262 | ||
| 263 | let n_rx = r.rxd().amount().read().0 as usize; | 263 | let n_rx = r.dma().rx().amount().read().0 as usize; |
| 264 | let n_tx = r.txd().amount().read().0 as usize; | 264 | let n_tx = r.dma().tx().amount().read().0 as usize; |
| 265 | 265 | ||
| 266 | compiler_fence(Ordering::SeqCst); | 266 | compiler_fence(Ordering::SeqCst); |
| 267 | 267 | ||
| @@ -326,8 +326,8 @@ impl<'d> Spis<'d> { | |||
| 326 | }) | 326 | }) |
| 327 | .await; | 327 | .await; |
| 328 | 328 | ||
| 329 | let n_rx = r.rxd().amount().read().0 as usize; | 329 | let n_rx = r.dma().rx().amount().read().0 as usize; |
| 330 | let n_tx = r.txd().amount().read().0 as usize; | 330 | let n_tx = r.dma().tx().amount().read().0 as usize; |
| 331 | 331 | ||
| 332 | compiler_fence(Ordering::SeqCst); | 332 | compiler_fence(Ordering::SeqCst); |
| 333 | 333 | ||
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 93255c832..abf9a923f 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -141,10 +141,19 @@ impl<'d> Twim<'d> { | |||
| 141 | sda.conf().write(|w| { | 141 | sda.conf().write(|w| { |
| 142 | w.set_dir(gpiovals::Dir::OUTPUT); | 142 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 143 | w.set_input(gpiovals::Input::CONNECT); | 143 | w.set_input(gpiovals::Input::CONNECT); |
| 144 | #[cfg(not(feature = "_nrf54l"))] | ||
| 144 | w.set_drive(match config.sda_high_drive { | 145 | w.set_drive(match config.sda_high_drive { |
| 145 | true => gpiovals::Drive::H0D1, | 146 | true => gpiovals::Drive::H0D1, |
| 146 | false => gpiovals::Drive::S0D1, | 147 | false => gpiovals::Drive::S0D1, |
| 147 | }); | 148 | }); |
| 149 | #[cfg(feature = "_nrf54l")] | ||
| 150 | { | ||
| 151 | w.set_drive0(match config.sda_high_drive { | ||
| 152 | true => gpiovals::Drive::H, | ||
| 153 | false => gpiovals::Drive::S, | ||
| 154 | }); | ||
| 155 | w.set_drive1(gpiovals::Drive::D); | ||
| 156 | } | ||
| 148 | if config.sda_pullup { | 157 | if config.sda_pullup { |
| 149 | w.set_pull(gpiovals::Pull::PULLUP); | 158 | w.set_pull(gpiovals::Pull::PULLUP); |
| 150 | } | 159 | } |
| @@ -152,10 +161,19 @@ impl<'d> Twim<'d> { | |||
| 152 | scl.conf().write(|w| { | 161 | scl.conf().write(|w| { |
| 153 | w.set_dir(gpiovals::Dir::OUTPUT); | 162 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 154 | w.set_input(gpiovals::Input::CONNECT); | 163 | w.set_input(gpiovals::Input::CONNECT); |
| 164 | #[cfg(not(feature = "_nrf54l"))] | ||
| 155 | w.set_drive(match config.scl_high_drive { | 165 | w.set_drive(match config.scl_high_drive { |
| 156 | true => gpiovals::Drive::H0D1, | 166 | true => gpiovals::Drive::H0D1, |
| 157 | false => gpiovals::Drive::S0D1, | 167 | false => gpiovals::Drive::S0D1, |
| 158 | }); | 168 | }); |
| 169 | #[cfg(feature = "_nrf54l")] | ||
| 170 | { | ||
| 171 | w.set_drive0(match config.scl_high_drive { | ||
| 172 | true => gpiovals::Drive::H, | ||
| 173 | false => gpiovals::Drive::S, | ||
| 174 | }); | ||
| 175 | w.set_drive1(gpiovals::Drive::D); | ||
| 176 | } | ||
| 159 | if config.sda_pullup { | 177 | if config.sda_pullup { |
| 160 | w.set_pull(gpiovals::Pull::PULLUP); | 178 | w.set_pull(gpiovals::Pull::PULLUP); |
| 161 | } | 179 | } |
| @@ -210,8 +228,8 @@ impl<'d> Twim<'d> { | |||
| 210 | // We're giving the register a pointer to the stack. Since we're | 228 | // We're giving the register a pointer to the stack. Since we're |
| 211 | // waiting for the I2C transaction to end before this stack pointer | 229 | // waiting for the I2C transaction to end before this stack pointer |
| 212 | // becomes invalid, there's nothing wrong here. | 230 | // becomes invalid, there's nothing wrong here. |
| 213 | r.txd().ptr().write_value(buffer.as_ptr() as u32); | 231 | r.dma().tx().ptr().write_value(buffer.as_ptr() as u32); |
| 214 | r.txd().maxcnt().write(|w| | 232 | r.dma().tx().maxcnt().write(|w| |
| 215 | // We're giving it the length of the buffer, so no danger of | 233 | // We're giving it the length of the buffer, so no danger of |
| 216 | // accessing invalid memory. We have verified that the length of the | 234 | // accessing invalid memory. We have verified that the length of the |
| 217 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | 235 | // buffer fits in an `u8`, so the cast to `u8` is also fine. |
| @@ -237,8 +255,8 @@ impl<'d> Twim<'d> { | |||
| 237 | // We're giving the register a pointer to the stack. Since we're | 255 | // We're giving the register a pointer to the stack. Since we're |
| 238 | // waiting for the I2C transaction to end before this stack pointer | 256 | // waiting for the I2C transaction to end before this stack pointer |
| 239 | // becomes invalid, there's nothing wrong here. | 257 | // becomes invalid, there's nothing wrong here. |
| 240 | r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32); | 258 | r.dma().rx().ptr().write_value(buffer.as_mut_ptr() as u32); |
| 241 | r.rxd().maxcnt().write(|w| | 259 | r.dma().rx().maxcnt().write(|w| |
| 242 | // We're giving it the length of the buffer, so no danger of | 260 | // We're giving it the length of the buffer, so no danger of |
| 243 | // accessing invalid memory. We have verified that the length of the | 261 | // accessing invalid memory. We have verified that the length of the |
| 244 | // buffer fits in an `u8`, so the cast to the type of maxcnt | 262 | // buffer fits in an `u8`, so the cast to the type of maxcnt |
| @@ -281,7 +299,7 @@ impl<'d> Twim<'d> { | |||
| 281 | 299 | ||
| 282 | fn check_rx(&self, len: usize) -> Result<(), Error> { | 300 | fn check_rx(&self, len: usize) -> Result<(), Error> { |
| 283 | let r = self.r; | 301 | let r = self.r; |
| 284 | if r.rxd().amount().read().0 != len as u32 { | 302 | if r.dma().rx().amount().read().0 != len as u32 { |
| 285 | Err(Error::Receive) | 303 | Err(Error::Receive) |
| 286 | } else { | 304 | } else { |
| 287 | Ok(()) | 305 | Ok(()) |
| @@ -290,7 +308,7 @@ impl<'d> Twim<'d> { | |||
| 290 | 308 | ||
| 291 | fn check_tx(&self, len: usize) -> Result<(), Error> { | 309 | fn check_tx(&self, len: usize) -> Result<(), Error> { |
| 292 | let r = self.r; | 310 | let r = self.r; |
| 293 | if r.txd().amount().read().0 != len as u32 { | 311 | if r.dma().tx().amount().read().0 != len as u32 { |
| 294 | Err(Error::Transmit) | 312 | Err(Error::Transmit) |
| 295 | } else { | 313 | } else { |
| 296 | Ok(()) | 314 | Ok(()) |
| @@ -412,7 +430,7 @@ impl<'d> Twim<'d> { | |||
| 412 | } | 430 | } |
| 413 | 431 | ||
| 414 | r.shorts().write(|w| { | 432 | r.shorts().write(|w| { |
| 415 | w.set_lastrx_starttx(true); | 433 | w.set_lastrx_dma_tx_start(true); |
| 416 | if stop { | 434 | if stop { |
| 417 | w.set_lasttx_stop(true); | 435 | w.set_lasttx_stop(true); |
| 418 | } else { | 436 | } else { |
| @@ -421,7 +439,7 @@ impl<'d> Twim<'d> { | |||
| 421 | }); | 439 | }); |
| 422 | 440 | ||
| 423 | // Start read+write operation. | 441 | // Start read+write operation. |
| 424 | r.tasks_startrx().write_value(1); | 442 | r.tasks_dma().rx().start().write_value(1); |
| 425 | if last_op.is_some() { | 443 | if last_op.is_some() { |
| 426 | r.tasks_resume().write_value(1); | 444 | r.tasks_resume().write_value(1); |
| 427 | } | 445 | } |
| @@ -429,7 +447,7 @@ impl<'d> Twim<'d> { | |||
| 429 | // TODO: Handle empty write buffer | 447 | // TODO: Handle empty write buffer |
| 430 | if rd_buffer.is_empty() { | 448 | if rd_buffer.is_empty() { |
| 431 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves. | 449 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves. |
| 432 | r.tasks_starttx().write_value(1); | 450 | r.tasks_dma().tx().start().write_value(1); |
| 433 | } | 451 | } |
| 434 | 452 | ||
| 435 | Ok(2) | 453 | Ok(2) |
| @@ -443,7 +461,7 @@ impl<'d> Twim<'d> { | |||
| 443 | r.shorts().write(|w| w.set_lastrx_stop(true)); | 461 | r.shorts().write(|w| w.set_lastrx_stop(true)); |
| 444 | 462 | ||
| 445 | // Start read operation. | 463 | // Start read operation. |
| 446 | r.tasks_startrx().write_value(1); | 464 | r.tasks_dma().rx().start().write_value(1); |
| 447 | if last_op.is_some() { | 465 | if last_op.is_some() { |
| 448 | r.tasks_resume().write_value(1); | 466 | r.tasks_resume().write_value(1); |
| 449 | } | 467 | } |
| @@ -466,11 +484,11 @@ impl<'d> Twim<'d> { | |||
| 466 | 484 | ||
| 467 | // Start write+read operation. | 485 | // Start write+read operation. |
| 468 | r.shorts().write(|w| { | 486 | r.shorts().write(|w| { |
| 469 | w.set_lasttx_startrx(true); | 487 | w.set_lasttx_dma_rx_start(true); |
| 470 | w.set_lastrx_stop(true); | 488 | w.set_lastrx_stop(true); |
| 471 | }); | 489 | }); |
| 472 | 490 | ||
| 473 | r.tasks_starttx().write_value(1); | 491 | r.tasks_dma().tx().start().write_value(1); |
| 474 | if last_op.is_some() { | 492 | if last_op.is_some() { |
| 475 | r.tasks_resume().write_value(1); | 493 | r.tasks_resume().write_value(1); |
| 476 | } | 494 | } |
| @@ -494,7 +512,7 @@ impl<'d> Twim<'d> { | |||
| 494 | } | 512 | } |
| 495 | }); | 513 | }); |
| 496 | 514 | ||
| 497 | r.tasks_starttx().write_value(1); | 515 | r.tasks_dma().tx().start().write_value(1); |
| 498 | if last_op.is_some() { | 516 | if last_op.is_some() { |
| 499 | r.tasks_resume().write_value(1); | 517 | r.tasks_resume().write_value(1); |
| 500 | } | 518 | } |
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index 2bc0a5c13..b3a699f71 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs | |||
| @@ -161,10 +161,19 @@ impl<'d> Twis<'d> { | |||
| 161 | sda.conf().write(|w| { | 161 | sda.conf().write(|w| { |
| 162 | w.set_dir(gpiovals::Dir::INPUT); | 162 | w.set_dir(gpiovals::Dir::INPUT); |
| 163 | w.set_input(gpiovals::Input::CONNECT); | 163 | w.set_input(gpiovals::Input::CONNECT); |
| 164 | #[cfg(not(feature = "_nrf54l"))] | ||
| 164 | w.set_drive(match config.sda_high_drive { | 165 | w.set_drive(match config.sda_high_drive { |
| 165 | true => gpiovals::Drive::H0D1, | 166 | true => gpiovals::Drive::H0D1, |
| 166 | false => gpiovals::Drive::S0D1, | 167 | false => gpiovals::Drive::S0D1, |
| 167 | }); | 168 | }); |
| 169 | #[cfg(feature = "_nrf54l")] | ||
| 170 | { | ||
| 171 | w.set_drive0(match config.sda_high_drive { | ||
| 172 | true => gpiovals::Drive::H, | ||
| 173 | false => gpiovals::Drive::S, | ||
| 174 | }); | ||
| 175 | w.set_drive1(gpiovals::Drive::D); | ||
| 176 | } | ||
| 168 | if config.sda_pullup { | 177 | if config.sda_pullup { |
| 169 | w.set_pull(gpiovals::Pull::PULLUP); | 178 | w.set_pull(gpiovals::Pull::PULLUP); |
| 170 | } | 179 | } |
| @@ -172,10 +181,19 @@ impl<'d> Twis<'d> { | |||
| 172 | scl.conf().write(|w| { | 181 | scl.conf().write(|w| { |
| 173 | w.set_dir(gpiovals::Dir::INPUT); | 182 | w.set_dir(gpiovals::Dir::INPUT); |
| 174 | w.set_input(gpiovals::Input::CONNECT); | 183 | w.set_input(gpiovals::Input::CONNECT); |
| 184 | #[cfg(not(feature = "_nrf54l"))] | ||
| 175 | w.set_drive(match config.scl_high_drive { | 185 | w.set_drive(match config.scl_high_drive { |
| 176 | true => gpiovals::Drive::H0D1, | 186 | true => gpiovals::Drive::H0D1, |
| 177 | false => gpiovals::Drive::S0D1, | 187 | false => gpiovals::Drive::S0D1, |
| 178 | }); | 188 | }); |
| 189 | #[cfg(feature = "_nrf54l")] | ||
| 190 | { | ||
| 191 | w.set_drive0(match config.scl_high_drive { | ||
| 192 | true => gpiovals::Drive::H, | ||
| 193 | false => gpiovals::Drive::S, | ||
| 194 | }); | ||
| 195 | w.set_drive1(gpiovals::Drive::D); | ||
| 196 | } | ||
| 179 | if config.sda_pullup { | 197 | if config.sda_pullup { |
| 180 | w.set_pull(gpiovals::Pull::PULLUP); | 198 | w.set_pull(gpiovals::Pull::PULLUP); |
| 181 | } | 199 | } |
| @@ -228,8 +246,8 @@ impl<'d> Twis<'d> { | |||
| 228 | // We're giving the register a pointer to the stack. Since we're | 246 | // We're giving the register a pointer to the stack. Since we're |
| 229 | // waiting for the I2C transaction to end before this stack pointer | 247 | // waiting for the I2C transaction to end before this stack pointer |
| 230 | // becomes invalid, there's nothing wrong here. | 248 | // becomes invalid, there's nothing wrong here. |
| 231 | r.txd().ptr().write_value(buffer.as_ptr() as u32); | 249 | r.dma().tx().ptr().write_value(buffer.as_ptr() as u32); |
| 232 | r.txd().maxcnt().write(|w| | 250 | r.dma().tx().maxcnt().write(|w| |
| 233 | // We're giving it the length of the buffer, so no danger of | 251 | // We're giving it the length of the buffer, so no danger of |
| 234 | // accessing invalid memory. We have verified that the length of the | 252 | // accessing invalid memory. We have verified that the length of the |
| 235 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | 253 | // buffer fits in an `u8`, so the cast to `u8` is also fine. |
| @@ -255,8 +273,8 @@ impl<'d> Twis<'d> { | |||
| 255 | // We're giving the register a pointer to the stack. Since we're | 273 | // We're giving the register a pointer to the stack. Since we're |
| 256 | // waiting for the I2C transaction to end before this stack pointer | 274 | // waiting for the I2C transaction to end before this stack pointer |
| 257 | // becomes invalid, there's nothing wrong here. | 275 | // becomes invalid, there's nothing wrong here. |
| 258 | r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32); | 276 | r.dma().rx().ptr().write_value(buffer.as_mut_ptr() as u32); |
| 259 | r.rxd().maxcnt().write(|w| | 277 | r.dma().rx().maxcnt().write(|w| |
| 260 | // We're giving it the length of the buffer, so no danger of | 278 | // We're giving it the length of the buffer, so no danger of |
| 261 | // accessing invalid memory. We have verified that the length of the | 279 | // accessing invalid memory. We have verified that the length of the |
| 262 | // buffer fits in an `u8`, so the cast to the type of maxcnt | 280 | // buffer fits in an `u8`, so the cast to the type of maxcnt |
| @@ -330,13 +348,13 @@ impl<'d> Twis<'d> { | |||
| 330 | return match status { | 348 | return match status { |
| 331 | Status::Read => Ok(Command::Read), | 349 | Status::Read => Ok(Command::Read), |
| 332 | Status::Write => { | 350 | Status::Write => { |
| 333 | let n = r.rxd().amount().read().0 as usize; | 351 | let n = r.dma().rx().amount().read().0 as usize; |
| 334 | Ok(Command::Write(n)) | 352 | Ok(Command::Write(n)) |
| 335 | } | 353 | } |
| 336 | }; | 354 | }; |
| 337 | } else if r.events_read().read() != 0 { | 355 | } else if r.events_read().read() != 0 { |
| 338 | r.events_read().write_value(0); | 356 | r.events_read().write_value(0); |
| 339 | let n = r.rxd().amount().read().0 as usize; | 357 | let n = r.dma().rx().amount().read().0 as usize; |
| 340 | return Ok(Command::WriteRead(n)); | 358 | return Ok(Command::WriteRead(n)); |
| 341 | } | 359 | } |
| 342 | } | 360 | } |
| @@ -360,7 +378,7 @@ impl<'d> Twis<'d> { | |||
| 360 | } | 378 | } |
| 361 | } else if r.events_stopped().read() != 0 { | 379 | } else if r.events_stopped().read() != 0 { |
| 362 | r.events_stopped().write_value(0); | 380 | r.events_stopped().write_value(0); |
| 363 | let n = r.txd().amount().read().0 as usize; | 381 | let n = r.dma().tx().amount().read().0 as usize; |
| 364 | return Ok(n); | 382 | return Ok(n); |
| 365 | } | 383 | } |
| 366 | } | 384 | } |
| @@ -386,7 +404,7 @@ impl<'d> Twis<'d> { | |||
| 386 | } | 404 | } |
| 387 | } else if r.events_stopped().read() != 0 { | 405 | } else if r.events_stopped().read() != 0 { |
| 388 | r.events_stopped().write_value(0); | 406 | r.events_stopped().write_value(0); |
| 389 | let n = r.txd().amount().read().0 as usize; | 407 | let n = r.dma().tx().amount().read().0 as usize; |
| 390 | return Ok(n); | 408 | return Ok(n); |
| 391 | } else if Instant::now() > deadline { | 409 | } else if Instant::now() > deadline { |
| 392 | r.tasks_stop().write_value(1); | 410 | r.tasks_stop().write_value(1); |
| @@ -442,13 +460,13 @@ impl<'d> Twis<'d> { | |||
| 442 | return match status { | 460 | return match status { |
| 443 | Status::Read => Ok(Command::Read), | 461 | Status::Read => Ok(Command::Read), |
| 444 | Status::Write => { | 462 | Status::Write => { |
| 445 | let n = r.rxd().amount().read().0 as usize; | 463 | let n = r.dma().rx().amount().read().0 as usize; |
| 446 | Ok(Command::Write(n)) | 464 | Ok(Command::Write(n)) |
| 447 | } | 465 | } |
| 448 | }; | 466 | }; |
| 449 | } else if r.events_read().read() != 0 { | 467 | } else if r.events_read().read() != 0 { |
| 450 | r.events_read().write_value(0); | 468 | r.events_read().write_value(0); |
| 451 | let n = r.rxd().amount().read().0 as usize; | 469 | let n = r.dma().rx().amount().read().0 as usize; |
| 452 | return Ok(Command::WriteRead(n)); | 470 | return Ok(Command::WriteRead(n)); |
| 453 | } else if Instant::now() > deadline { | 471 | } else if Instant::now() > deadline { |
| 454 | r.tasks_stop().write_value(1); | 472 | r.tasks_stop().write_value(1); |
| @@ -478,7 +496,7 @@ impl<'d> Twis<'d> { | |||
| 478 | } | 496 | } |
| 479 | } else if r.events_stopped().read() != 0 { | 497 | } else if r.events_stopped().read() != 0 { |
| 480 | r.events_stopped().write_value(0); | 498 | r.events_stopped().write_value(0); |
| 481 | let n = r.txd().amount().read().0 as usize; | 499 | let n = r.dma().tx().amount().read().0 as usize; |
| 482 | return Poll::Ready(Ok(n)); | 500 | return Poll::Ready(Ok(n)); |
| 483 | } | 501 | } |
| 484 | 502 | ||
| @@ -529,13 +547,13 @@ impl<'d> Twis<'d> { | |||
| 529 | return match status { | 547 | return match status { |
| 530 | Status::Read => Poll::Ready(Ok(Command::Read)), | 548 | Status::Read => Poll::Ready(Ok(Command::Read)), |
| 531 | Status::Write => { | 549 | Status::Write => { |
| 532 | let n = r.rxd().amount().read().0 as usize; | 550 | let n = r.dma().rx().amount().read().0 as usize; |
| 533 | Poll::Ready(Ok(Command::Write(n))) | 551 | Poll::Ready(Ok(Command::Write(n))) |
| 534 | } | 552 | } |
| 535 | }; | 553 | }; |
| 536 | } else if r.events_read().read() != 0 { | 554 | } else if r.events_read().read() != 0 { |
| 537 | r.events_read().write_value(0); | 555 | r.events_read().write_value(0); |
| 538 | let n = r.rxd().amount().read().0 as usize; | 556 | let n = r.dma().rx().amount().read().0 as usize; |
| 539 | return Poll::Ready(Ok(Command::WriteRead(n))); | 557 | return Poll::Ready(Ok(Command::WriteRead(n))); |
| 540 | } | 558 | } |
| 541 | Poll::Pending | 559 | Poll::Pending |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 1ee452173..049830aed 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -113,20 +113,20 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 113 | let r = T::regs(); | 113 | let r = T::regs(); |
| 114 | let s = T::state(); | 114 | let s = T::state(); |
| 115 | 115 | ||
| 116 | let endrx = r.events_endrx().read(); | 116 | let endrx = r.events_dma().rx().end().read(); |
| 117 | let error = r.events_error().read(); | 117 | let error = r.events_error().read(); |
| 118 | if endrx != 0 || error != 0 { | 118 | if endrx != 0 || error != 0 { |
| 119 | s.rx_waker.wake(); | 119 | s.rx_waker.wake(); |
| 120 | if endrx != 0 { | 120 | if endrx != 0 { |
| 121 | r.intenclr().write(|w| w.set_endrx(true)); | 121 | r.intenclr().write(|w| w.set_dmarxend(true)); |
| 122 | } | 122 | } |
| 123 | if error != 0 { | 123 | if error != 0 { |
| 124 | r.intenclr().write(|w| w.set_error(true)); | 124 | r.intenclr().write(|w| w.set_error(true)); |
| 125 | } | 125 | } |
| 126 | } | 126 | } |
| 127 | if r.events_endtx().read() != 0 { | 127 | if r.events_dma().tx().end().read() != 0 { |
| 128 | s.tx_waker.wake(); | 128 | s.tx_waker.wake(); |
| 129 | r.intenclr().write(|w| w.set_endtx(true)); | 129 | r.intenclr().write(|w| w.set_dmatxend(true)); |
| 130 | } | 130 | } |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
| @@ -257,7 +257,7 @@ impl<'d> Uarte<'d> { | |||
| 257 | /// Return the endtx event for use with PPI | 257 | /// Return the endtx event for use with PPI |
| 258 | pub fn event_endtx(&self) -> Event<'_> { | 258 | pub fn event_endtx(&self) -> Event<'_> { |
| 259 | let r = self.tx.r; | 259 | let r = self.tx.r; |
| 260 | Event::from_reg(r.events_endtx()) | 260 | Event::from_reg(r.events_dma().tx().end()) |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | /// Read bytes until the buffer is filled. | 263 | /// Read bytes until the buffer is filled. |
| @@ -296,7 +296,13 @@ pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts | |||
| 296 | txd.conf().write(|w| { | 296 | txd.conf().write(|w| { |
| 297 | w.set_dir(gpiovals::Dir::OUTPUT); | 297 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 298 | w.set_input(gpiovals::Input::DISCONNECT); | 298 | w.set_input(gpiovals::Input::DISCONNECT); |
| 299 | #[cfg(not(feature = "_nrf54l"))] | ||
| 299 | w.set_drive(gpiovals::Drive::H0H1); | 300 | w.set_drive(gpiovals::Drive::H0H1); |
| 301 | #[cfg(feature = "_nrf54l")] | ||
| 302 | { | ||
| 303 | w.set_drive0(gpiovals::Drive::H); | ||
| 304 | w.set_drive1(gpiovals::Drive::H); | ||
| 305 | } | ||
| 300 | }); | 306 | }); |
| 301 | r.psel().txd().write_value(txd.psel_bits()); | 307 | r.psel().txd().write_value(txd.psel_bits()); |
| 302 | 308 | ||
| @@ -304,7 +310,13 @@ pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts | |||
| 304 | pin.conf().write(|w| { | 310 | pin.conf().write(|w| { |
| 305 | w.set_dir(gpiovals::Dir::INPUT); | 311 | w.set_dir(gpiovals::Dir::INPUT); |
| 306 | w.set_input(gpiovals::Input::CONNECT); | 312 | w.set_input(gpiovals::Input::CONNECT); |
| 313 | #[cfg(not(feature = "_nrf54l"))] | ||
| 307 | w.set_drive(gpiovals::Drive::H0H1); | 314 | w.set_drive(gpiovals::Drive::H0H1); |
| 315 | #[cfg(feature = "_nrf54l")] | ||
| 316 | { | ||
| 317 | w.set_drive0(gpiovals::Drive::H); | ||
| 318 | w.set_drive1(gpiovals::Drive::H); | ||
| 319 | } | ||
| 308 | }); | 320 | }); |
| 309 | } | 321 | } |
| 310 | r.psel().cts().write_value(cts.psel_bits()); | 322 | r.psel().cts().write_value(cts.psel_bits()); |
| @@ -314,7 +326,13 @@ pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts | |||
| 314 | rxd.conf().write(|w| { | 326 | rxd.conf().write(|w| { |
| 315 | w.set_dir(gpiovals::Dir::INPUT); | 327 | w.set_dir(gpiovals::Dir::INPUT); |
| 316 | w.set_input(gpiovals::Input::CONNECT); | 328 | w.set_input(gpiovals::Input::CONNECT); |
| 329 | #[cfg(not(feature = "_nrf54l"))] | ||
| 317 | w.set_drive(gpiovals::Drive::H0H1); | 330 | w.set_drive(gpiovals::Drive::H0H1); |
| 331 | #[cfg(feature = "_nrf54l")] | ||
| 332 | { | ||
| 333 | w.set_drive0(gpiovals::Drive::H); | ||
| 334 | w.set_drive1(gpiovals::Drive::H); | ||
| 335 | } | ||
| 318 | }); | 336 | }); |
| 319 | r.psel().rxd().write_value(rxd.psel_bits()); | 337 | r.psel().rxd().write_value(rxd.psel_bits()); |
| 320 | 338 | ||
| @@ -323,7 +341,13 @@ pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts | |||
| 323 | pin.conf().write(|w| { | 341 | pin.conf().write(|w| { |
| 324 | w.set_dir(gpiovals::Dir::OUTPUT); | 342 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 325 | w.set_input(gpiovals::Input::DISCONNECT); | 343 | w.set_input(gpiovals::Input::DISCONNECT); |
| 344 | #[cfg(not(feature = "_nrf54l"))] | ||
| 326 | w.set_drive(gpiovals::Drive::H0H1); | 345 | w.set_drive(gpiovals::Drive::H0H1); |
| 346 | #[cfg(feature = "_nrf54l")] | ||
| 347 | { | ||
| 348 | w.set_drive0(gpiovals::Drive::H); | ||
| 349 | w.set_drive1(gpiovals::Drive::H); | ||
| 350 | } | ||
| 327 | }); | 351 | }); |
| 328 | } | 352 | } |
| 329 | r.psel().rts().write_value(rts.psel_bits()); | 353 | r.psel().rts().write_value(rts.psel_bits()); |
| @@ -333,6 +357,10 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont | |||
| 333 | r.config().write(|w| { | 357 | r.config().write(|w| { |
| 334 | w.set_hwfc(hardware_flow_control); | 358 | w.set_hwfc(hardware_flow_control); |
| 335 | w.set_parity(config.parity); | 359 | w.set_parity(config.parity); |
| 360 | #[cfg(feature = "_nrf54l")] | ||
| 361 | w.set_framesize(vals::Framesize::_8BIT); | ||
| 362 | #[cfg(feature = "_nrf54l")] | ||
| 363 | w.set_frametimeout(true); | ||
| 336 | }); | 364 | }); |
| 337 | r.baudrate().write(|w| w.set_baudrate(config.baudrate)); | 365 | r.baudrate().write(|w| w.set_baudrate(config.baudrate)); |
| 338 | 366 | ||
| @@ -341,8 +369,8 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont | |||
| 341 | 369 | ||
| 342 | // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was | 370 | // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was |
| 343 | // stopped midway or not. | 371 | // stopped midway or not. |
| 344 | r.events_rxstarted().write_value(0); | 372 | r.events_dma().rx().ready().write_value(0); |
| 345 | r.events_txstarted().write_value(0); | 373 | r.events_dma().tx().ready().write_value(0); |
| 346 | 374 | ||
| 347 | // reset all pins | 375 | // reset all pins |
| 348 | r.psel().txd().write_value(DISCONNECTED); | 376 | r.psel().txd().write_value(DISCONNECTED); |
| @@ -434,29 +462,29 @@ impl<'d> UarteTx<'d> { | |||
| 434 | let drop = OnDrop::new(move || { | 462 | let drop = OnDrop::new(move || { |
| 435 | trace!("write drop: stopping"); | 463 | trace!("write drop: stopping"); |
| 436 | 464 | ||
| 437 | r.intenclr().write(|w| w.set_endtx(true)); | 465 | r.intenclr().write(|w| w.set_dmatxend(true)); |
| 438 | r.events_txstopped().write_value(0); | 466 | r.events_txstopped().write_value(0); |
| 439 | r.tasks_stoptx().write_value(1); | 467 | r.tasks_dma().tx().stop().write_value(1); |
| 440 | 468 | ||
| 441 | // TX is stopped almost instantly, spinning is fine. | 469 | // TX is stopped almost instantly, spinning is fine. |
| 442 | while r.events_endtx().read() == 0 {} | 470 | while r.events_dma().tx().end().read() == 0 {} |
| 443 | trace!("write drop: stopped"); | 471 | trace!("write drop: stopped"); |
| 444 | }); | 472 | }); |
| 445 | 473 | ||
| 446 | r.txd().ptr().write_value(ptr as u32); | 474 | r.dma().tx().ptr().write_value(ptr as u32); |
| 447 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 475 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 448 | 476 | ||
| 449 | r.events_endtx().write_value(0); | 477 | r.events_dma().tx().end().write_value(0); |
| 450 | r.intenset().write(|w| w.set_endtx(true)); | 478 | r.intenset().write(|w| w.set_dmatxend(true)); |
| 451 | 479 | ||
| 452 | compiler_fence(Ordering::SeqCst); | 480 | compiler_fence(Ordering::SeqCst); |
| 453 | 481 | ||
| 454 | trace!("starttx"); | 482 | trace!("starttx"); |
| 455 | r.tasks_starttx().write_value(1); | 483 | r.tasks_dma().tx().start().write_value(1); |
| 456 | 484 | ||
| 457 | poll_fn(|cx| { | 485 | poll_fn(|cx| { |
| 458 | s.tx_waker.register(cx.waker()); | 486 | s.tx_waker.register(cx.waker()); |
| 459 | if r.events_endtx().read() != 0 { | 487 | if r.events_dma().tx().end().read() != 0 { |
| 460 | return Poll::Ready(()); | 488 | return Poll::Ready(()); |
| 461 | } | 489 | } |
| 462 | Poll::Pending | 490 | Poll::Pending |
| @@ -464,7 +492,7 @@ impl<'d> UarteTx<'d> { | |||
| 464 | .await; | 492 | .await; |
| 465 | 493 | ||
| 466 | compiler_fence(Ordering::SeqCst); | 494 | compiler_fence(Ordering::SeqCst); |
| 467 | r.events_txstarted().write_value(0); | 495 | r.events_dma().tx().ready().write_value(0); |
| 468 | drop.defuse(); | 496 | drop.defuse(); |
| 469 | 497 | ||
| 470 | Ok(()) | 498 | Ok(()) |
| @@ -500,21 +528,21 @@ impl<'d> UarteTx<'d> { | |||
| 500 | 528 | ||
| 501 | let r = self.r; | 529 | let r = self.r; |
| 502 | 530 | ||
| 503 | r.txd().ptr().write_value(ptr as u32); | 531 | r.dma().tx().ptr().write_value(ptr as u32); |
| 504 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 532 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 505 | 533 | ||
| 506 | r.events_endtx().write_value(0); | 534 | r.events_dma().tx().end().write_value(0); |
| 507 | r.intenclr().write(|w| w.set_endtx(true)); | 535 | r.intenclr().write(|w| w.set_dmatxend(true)); |
| 508 | 536 | ||
| 509 | compiler_fence(Ordering::SeqCst); | 537 | compiler_fence(Ordering::SeqCst); |
| 510 | 538 | ||
| 511 | trace!("starttx"); | 539 | trace!("starttx"); |
| 512 | r.tasks_starttx().write_value(1); | 540 | r.tasks_dma().tx().start().write_value(1); |
| 513 | 541 | ||
| 514 | while r.events_endtx().read() == 0 {} | 542 | while r.events_dma().tx().end().read() == 0 {} |
| 515 | 543 | ||
| 516 | compiler_fence(Ordering::SeqCst); | 544 | compiler_fence(Ordering::SeqCst); |
| 517 | r.events_txstarted().write_value(0); | 545 | r.events_dma().tx().ready().write_value(0); |
| 518 | 546 | ||
| 519 | Ok(()) | 547 | Ok(()) |
| 520 | } | 548 | } |
| @@ -526,7 +554,7 @@ impl<'a> Drop for UarteTx<'a> { | |||
| 526 | 554 | ||
| 527 | let r = self.r; | 555 | let r = self.r; |
| 528 | 556 | ||
| 529 | let did_stoptx = r.events_txstarted().read() != 0; | 557 | let did_stoptx = r.events_dma().tx().ready().read() != 0; |
| 530 | trace!("did_stoptx {}", did_stoptx); | 558 | trace!("did_stoptx {}", did_stoptx); |
| 531 | 559 | ||
| 532 | // Wait for txstopped, if needed. | 560 | // Wait for txstopped, if needed. |
| @@ -629,7 +657,7 @@ impl<'d> UarteRx<'d> { | |||
| 629 | let mut ppi_ch2 = Ppi::new_one_to_one( | 657 | let mut ppi_ch2 = Ppi::new_one_to_one( |
| 630 | ppi_ch2.into(), | 658 | ppi_ch2.into(), |
| 631 | timer.cc(0).event_compare(), | 659 | timer.cc(0).event_compare(), |
| 632 | Task::from_reg(r.tasks_stoprx()), | 660 | Task::from_reg(r.tasks_dma().rx().stop()), |
| 633 | ); | 661 | ); |
| 634 | ppi_ch2.enable(); | 662 | ppi_ch2.enable(); |
| 635 | 663 | ||
| @@ -664,41 +692,41 @@ impl<'d> UarteRx<'d> { | |||
| 664 | trace!("read drop: stopping"); | 692 | trace!("read drop: stopping"); |
| 665 | 693 | ||
| 666 | r.intenclr().write(|w| { | 694 | r.intenclr().write(|w| { |
| 667 | w.set_endrx(true); | 695 | w.set_dmarxend(true); |
| 668 | w.set_error(true); | 696 | w.set_error(true); |
| 669 | }); | 697 | }); |
| 670 | r.events_rxto().write_value(0); | 698 | r.events_rxto().write_value(0); |
| 671 | r.events_error().write_value(0); | 699 | r.events_error().write_value(0); |
| 672 | r.tasks_stoprx().write_value(1); | 700 | r.tasks_dma().rx().stop().write_value(1); |
| 673 | 701 | ||
| 674 | while r.events_endrx().read() == 0 {} | 702 | while r.events_dma().rx().end().read() == 0 {} |
| 675 | 703 | ||
| 676 | trace!("read drop: stopped"); | 704 | trace!("read drop: stopped"); |
| 677 | }); | 705 | }); |
| 678 | 706 | ||
| 679 | r.rxd().ptr().write_value(ptr as u32); | 707 | r.dma().rx().ptr().write_value(ptr as u32); |
| 680 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 708 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 681 | 709 | ||
| 682 | r.events_endrx().write_value(0); | 710 | r.events_dma().rx().end().write_value(0); |
| 683 | r.events_error().write_value(0); | 711 | r.events_error().write_value(0); |
| 684 | r.intenset().write(|w| { | 712 | r.intenset().write(|w| { |
| 685 | w.set_endrx(true); | 713 | w.set_dmarxend(true); |
| 686 | w.set_error(true); | 714 | w.set_error(true); |
| 687 | }); | 715 | }); |
| 688 | 716 | ||
| 689 | compiler_fence(Ordering::SeqCst); | 717 | compiler_fence(Ordering::SeqCst); |
| 690 | 718 | ||
| 691 | trace!("startrx"); | 719 | trace!("startrx"); |
| 692 | r.tasks_startrx().write_value(1); | 720 | r.tasks_dma().rx().start().write_value(1); |
| 693 | 721 | ||
| 694 | let result = poll_fn(|cx| { | 722 | let result = poll_fn(|cx| { |
| 695 | s.rx_waker.register(cx.waker()); | 723 | s.rx_waker.register(cx.waker()); |
| 696 | 724 | ||
| 697 | if let Err(e) = self.check_and_clear_errors() { | 725 | if let Err(e) = self.check_and_clear_errors() { |
| 698 | r.tasks_stoprx().write_value(1); | 726 | r.tasks_dma().rx().stop().write_value(1); |
| 699 | return Poll::Ready(Err(e)); | 727 | return Poll::Ready(Err(e)); |
| 700 | } | 728 | } |
| 701 | if r.events_endrx().read() != 0 { | 729 | if r.events_dma().rx().end().read() != 0 { |
| 702 | return Poll::Ready(Ok(())); | 730 | return Poll::Ready(Ok(())); |
| 703 | } | 731 | } |
| 704 | Poll::Pending | 732 | Poll::Pending |
| @@ -706,7 +734,7 @@ impl<'d> UarteRx<'d> { | |||
| 706 | .await; | 734 | .await; |
| 707 | 735 | ||
| 708 | compiler_fence(Ordering::SeqCst); | 736 | compiler_fence(Ordering::SeqCst); |
| 709 | r.events_rxstarted().write_value(0); | 737 | r.events_dma().rx().ready().write_value(0); |
| 710 | drop.defuse(); | 738 | drop.defuse(); |
| 711 | 739 | ||
| 712 | result | 740 | result |
| @@ -726,25 +754,25 @@ impl<'d> UarteRx<'d> { | |||
| 726 | 754 | ||
| 727 | let r = self.r; | 755 | let r = self.r; |
| 728 | 756 | ||
| 729 | r.rxd().ptr().write_value(ptr as u32); | 757 | r.dma().rx().ptr().write_value(ptr as u32); |
| 730 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 758 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 731 | 759 | ||
| 732 | r.events_endrx().write_value(0); | 760 | r.events_dma().rx().end().write_value(0); |
| 733 | r.events_error().write_value(0); | 761 | r.events_error().write_value(0); |
| 734 | r.intenclr().write(|w| { | 762 | r.intenclr().write(|w| { |
| 735 | w.set_endrx(true); | 763 | w.set_dmarxend(true); |
| 736 | w.set_error(true); | 764 | w.set_error(true); |
| 737 | }); | 765 | }); |
| 738 | 766 | ||
| 739 | compiler_fence(Ordering::SeqCst); | 767 | compiler_fence(Ordering::SeqCst); |
| 740 | 768 | ||
| 741 | trace!("startrx"); | 769 | trace!("startrx"); |
| 742 | r.tasks_startrx().write_value(1); | 770 | r.tasks_dma().rx().start().write_value(1); |
| 743 | 771 | ||
| 744 | while r.events_endrx().read() == 0 && r.events_error().read() == 0 {} | 772 | while r.events_dma().rx().end().read() == 0 && r.events_error().read() == 0 {} |
| 745 | 773 | ||
| 746 | compiler_fence(Ordering::SeqCst); | 774 | compiler_fence(Ordering::SeqCst); |
| 747 | r.events_rxstarted().write_value(0); | 775 | r.events_dma().rx().ready().write_value(0); |
| 748 | 776 | ||
| 749 | self.check_and_clear_errors() | 777 | self.check_and_clear_errors() |
| 750 | } | 778 | } |
| @@ -756,7 +784,7 @@ impl<'a> Drop for UarteRx<'a> { | |||
| 756 | 784 | ||
| 757 | let r = self.r; | 785 | let r = self.r; |
| 758 | 786 | ||
| 759 | let did_stoprx = r.events_rxstarted().read() != 0; | 787 | let did_stoprx = r.events_dma().rx().ready().read() != 0; |
| 760 | trace!("did_stoprx {}", did_stoprx); | 788 | trace!("did_stoprx {}", did_stoprx); |
| 761 | 789 | ||
| 762 | // Wait for rxto, if needed. | 790 | // Wait for rxto, if needed. |
| @@ -816,38 +844,38 @@ impl<'d> UarteRxWithIdle<'d> { | |||
| 816 | self.timer.stop(); | 844 | self.timer.stop(); |
| 817 | 845 | ||
| 818 | r.intenclr().write(|w| { | 846 | r.intenclr().write(|w| { |
| 819 | w.set_endrx(true); | 847 | w.set_dmarxend(true); |
| 820 | w.set_error(true); | 848 | w.set_error(true); |
| 821 | }); | 849 | }); |
| 822 | r.events_rxto().write_value(0); | 850 | r.events_rxto().write_value(0); |
| 823 | r.events_error().write_value(0); | 851 | r.events_error().write_value(0); |
| 824 | r.tasks_stoprx().write_value(1); | 852 | r.tasks_dma().rx().stop().write_value(1); |
| 825 | 853 | ||
| 826 | while r.events_endrx().read() == 0 {} | 854 | while r.events_dma().rx().end().read() == 0 {} |
| 827 | }); | 855 | }); |
| 828 | 856 | ||
| 829 | r.rxd().ptr().write_value(ptr as u32); | 857 | r.dma().rx().ptr().write_value(ptr as u32); |
| 830 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 858 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 831 | 859 | ||
| 832 | r.events_endrx().write_value(0); | 860 | r.events_dma().rx().end().write_value(0); |
| 833 | r.events_error().write_value(0); | 861 | r.events_error().write_value(0); |
| 834 | r.intenset().write(|w| { | 862 | r.intenset().write(|w| { |
| 835 | w.set_endrx(true); | 863 | w.set_dmarxend(true); |
| 836 | w.set_error(true); | 864 | w.set_error(true); |
| 837 | }); | 865 | }); |
| 838 | 866 | ||
| 839 | compiler_fence(Ordering::SeqCst); | 867 | compiler_fence(Ordering::SeqCst); |
| 840 | 868 | ||
| 841 | r.tasks_startrx().write_value(1); | 869 | r.tasks_dma().rx().start().write_value(1); |
| 842 | 870 | ||
| 843 | let result = poll_fn(|cx| { | 871 | let result = poll_fn(|cx| { |
| 844 | s.rx_waker.register(cx.waker()); | 872 | s.rx_waker.register(cx.waker()); |
| 845 | 873 | ||
| 846 | if let Err(e) = self.rx.check_and_clear_errors() { | 874 | if let Err(e) = self.rx.check_and_clear_errors() { |
| 847 | r.tasks_stoprx().write_value(1); | 875 | r.tasks_dma().rx().stop().write_value(1); |
| 848 | return Poll::Ready(Err(e)); | 876 | return Poll::Ready(Err(e)); |
| 849 | } | 877 | } |
| 850 | if r.events_endrx().read() != 0 { | 878 | if r.events_dma().rx().end().read() != 0 { |
| 851 | return Poll::Ready(Ok(())); | 879 | return Poll::Ready(Ok(())); |
| 852 | } | 880 | } |
| 853 | 881 | ||
| @@ -856,10 +884,10 @@ impl<'d> UarteRxWithIdle<'d> { | |||
| 856 | .await; | 884 | .await; |
| 857 | 885 | ||
| 858 | compiler_fence(Ordering::SeqCst); | 886 | compiler_fence(Ordering::SeqCst); |
| 859 | let n = r.rxd().amount().read().0 as usize; | 887 | let n = r.dma().rx().amount().read().0 as usize; |
| 860 | 888 | ||
| 861 | self.timer.stop(); | 889 | self.timer.stop(); |
| 862 | r.events_rxstarted().write_value(0); | 890 | r.events_dma().rx().ready().write_value(0); |
| 863 | 891 | ||
| 864 | drop.defuse(); | 892 | drop.defuse(); |
| 865 | 893 | ||
| @@ -884,27 +912,27 @@ impl<'d> UarteRxWithIdle<'d> { | |||
| 884 | 912 | ||
| 885 | self.ppi_ch1.enable(); | 913 | self.ppi_ch1.enable(); |
| 886 | 914 | ||
| 887 | r.rxd().ptr().write_value(ptr as u32); | 915 | r.dma().rx().ptr().write_value(ptr as u32); |
| 888 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 916 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 889 | 917 | ||
| 890 | r.events_endrx().write_value(0); | 918 | r.events_dma().rx().end().write_value(0); |
| 891 | r.events_error().write_value(0); | 919 | r.events_error().write_value(0); |
| 892 | r.intenclr().write(|w| { | 920 | r.intenclr().write(|w| { |
| 893 | w.set_endrx(true); | 921 | w.set_dmarxend(true); |
| 894 | w.set_error(true); | 922 | w.set_error(true); |
| 895 | }); | 923 | }); |
| 896 | 924 | ||
| 897 | compiler_fence(Ordering::SeqCst); | 925 | compiler_fence(Ordering::SeqCst); |
| 898 | 926 | ||
| 899 | r.tasks_startrx().write_value(1); | 927 | r.tasks_dma().rx().start().write_value(1); |
| 900 | 928 | ||
| 901 | while r.events_endrx().read() == 0 && r.events_error().read() == 0 {} | 929 | while r.events_dma().rx().end().read() == 0 && r.events_error().read() == 0 {} |
| 902 | 930 | ||
| 903 | compiler_fence(Ordering::SeqCst); | 931 | compiler_fence(Ordering::SeqCst); |
| 904 | let n = r.rxd().amount().read().0 as usize; | 932 | let n = r.dma().rx().amount().read().0 as usize; |
| 905 | 933 | ||
| 906 | self.timer.stop(); | 934 | self.timer.stop(); |
| 907 | r.events_rxstarted().write_value(0); | 935 | r.events_dma().rx().ready().write_value(0); |
| 908 | 936 | ||
| 909 | self.rx.check_and_clear_errors().map(|_| n) | 937 | self.rx.check_and_clear_errors().map(|_| n) |
| 910 | } | 938 | } |
| @@ -927,14 +955,14 @@ pub(crate) fn apply_workaround_for_enable_anomaly(r: pac::uarte::Uarte) { | |||
| 927 | // NB Safety: This is taken from Nordic's driver - | 955 | // NB Safety: This is taken from Nordic's driver - |
| 928 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | 956 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 |
| 929 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { | 957 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { |
| 930 | r.tasks_stoptx().write_value(1); | 958 | r.tasks_dma().tx().stop().write_value(1); |
| 931 | } | 959 | } |
| 932 | 960 | ||
| 933 | // NB Safety: This is taken from Nordic's driver - | 961 | // NB Safety: This is taken from Nordic's driver - |
| 934 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | 962 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 |
| 935 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { | 963 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { |
| 936 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 964 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 937 | r.tasks_stoprx().write_value(1); | 965 | r.tasks_dma().rx().stop().write_value(1); |
| 938 | 966 | ||
| 939 | let mut workaround_succeded = false; | 967 | let mut workaround_succeded = false; |
| 940 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. | 968 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. |
| @@ -948,6 +976,14 @@ pub(crate) fn apply_workaround_for_enable_anomaly(r: pac::uarte::Uarte) { | |||
| 948 | break; | 976 | break; |
| 949 | } else { | 977 | } else { |
| 950 | // Need to sleep for 1us here | 978 | // Need to sleep for 1us here |
| 979 | |||
| 980 | // Get the worst case clock speed | ||
| 981 | #[cfg(feature = "_nrf9160")] | ||
| 982 | const CLOCK_SPEED: u32 = 64_000_000; | ||
| 983 | #[cfg(feature = "_nrf5340")] | ||
| 984 | const CLOCK_SPEED: u32 = 128_000_000; | ||
| 985 | |||
| 986 | cortex_m::asm::delay(CLOCK_SPEED / 1_000_000); | ||
| 951 | } | 987 | } |
| 952 | } | 988 | } |
| 953 | 989 | ||
diff --git a/embassy-nxp/CHANGELOG.md b/embassy-nxp/CHANGELOG.md index 0fb677cd8..39f5c75bd 100644 --- a/embassy-nxp/CHANGELOG.md +++ b/embassy-nxp/CHANGELOG.md | |||
| @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 7 | 7 | ||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | - LPC55: PWM simple | ||
| 11 | - LPC55: Move ALT definitions for USART to TX/RX pin impls. | ||
| 12 | - LPC55: Remove internal match_iocon macro | ||
| 10 | - LPC55: DMA Controller and asynchronous version of USART | 13 | - LPC55: DMA Controller and asynchronous version of USART |
| 11 | - Moved NXP LPC55S69 from `lpc55-pac` to `nxp-pac` | 14 | - Moved NXP LPC55S69 from `lpc55-pac` to `nxp-pac` |
| 12 | - First release with changelog. | 15 | - First release with changelog. |
diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml index 33f0f2dff..f8c63ba29 100644 --- a/embassy-nxp/Cargo.toml +++ b/embassy-nxp/Cargo.toml | |||
| @@ -38,13 +38,13 @@ embassy-time-queue-utils = { version = "0.3.0", path = "../embassy-time-queue-ut | |||
| 38 | embedded-io = "0.6.1" | 38 | embedded-io = "0.6.1" |
| 39 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } | 39 | embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } |
| 40 | ## Chip dependencies | 40 | ## Chip dependencies |
| 41 | nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "b736e3038254d593024aaa1a5a7b1f95a5728538"} | 41 | nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "477dfdbfd5e6c75c0730c56494b601c1b2257263"} |
| 42 | 42 | ||
| 43 | imxrt-rt = { version = "0.1.7", optional = true, features = ["device"] } | 43 | imxrt-rt = { version = "0.1.7", optional = true, features = ["device"] } |
| 44 | 44 | ||
| 45 | [build-dependencies] | 45 | [build-dependencies] |
| 46 | cfg_aliases = "0.2.1" | 46 | cfg_aliases = "0.2.1" |
| 47 | nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "b736e3038254d593024aaa1a5a7b1f95a5728538", features = ["metadata"], optional = true } | 47 | nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "477dfdbfd5e6c75c0730c56494b601c1b2257263", features = ["metadata"], optional = true } |
| 48 | proc-macro2 = "1.0.95" | 48 | proc-macro2 = "1.0.95" |
| 49 | quote = "1.0.15" | 49 | quote = "1.0.15" |
| 50 | 50 | ||
diff --git a/embassy-nxp/src/chips/lpc55.rs b/embassy-nxp/src/chips/lpc55.rs index 9f4e7269f..e9addddb6 100644 --- a/embassy-nxp/src/chips/lpc55.rs +++ b/embassy-nxp/src/chips/lpc55.rs | |||
| @@ -97,6 +97,18 @@ embassy_hal_internal::peripherals! { | |||
| 97 | DMA_CH21, | 97 | DMA_CH21, |
| 98 | DMA_CH22, | 98 | DMA_CH22, |
| 99 | 99 | ||
| 100 | // Pulse-Width Modulation Outputs. | ||
| 101 | PWM_OUTPUT0, | ||
| 102 | PWM_OUTPUT1, | ||
| 103 | PWM_OUTPUT2, | ||
| 104 | PWM_OUTPUT3, | ||
| 105 | PWM_OUTPUT4, | ||
| 106 | PWM_OUTPUT5, | ||
| 107 | PWM_OUTPUT6, | ||
| 108 | PWM_OUTPUT7, | ||
| 109 | PWM_OUTPUT8, | ||
| 110 | PWM_OUTPUT9, | ||
| 111 | |||
| 100 | // Universal Synchronous/Asynchronous Receiver/Transmitter (USART) instances. | 112 | // Universal Synchronous/Asynchronous Receiver/Transmitter (USART) instances. |
| 101 | USART0, | 113 | USART0, |
| 102 | USART1, | 114 | USART1, |
diff --git a/embassy-nxp/src/fmt.rs b/embassy-nxp/src/fmt.rs index 27d41ace6..11275235e 100644 --- a/embassy-nxp/src/fmt.rs +++ b/embassy-nxp/src/fmt.rs | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | //! Copied from embassy-rp | 1 | //! Copied from embassy-rp |
| 2 | |||
| 3 | #![macro_use] | 2 | #![macro_use] |
| 4 | #![allow(unused)] | 3 | #![allow(unused)] |
| 5 | 4 | ||
diff --git a/embassy-nxp/src/gpio/lpc55.rs b/embassy-nxp/src/gpio/lpc55.rs index ac8a27d4f..6039d8ca8 100644 --- a/embassy-nxp/src/gpio/lpc55.rs +++ b/embassy-nxp/src/gpio/lpc55.rs | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; | 1 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; |
| 2 | 2 | ||
| 3 | use crate::pac::common::{RW, Reg}; | ||
| 3 | use crate::pac::iocon::vals::{PioDigimode, PioMode}; | 4 | use crate::pac::iocon::vals::{PioDigimode, PioMode}; |
| 4 | use crate::pac::{GPIO, IOCON, SYSCON}; | 5 | use crate::pac::{GPIO, IOCON, SYSCON, iocon}; |
| 5 | use crate::{Peri, peripherals}; | 6 | use crate::{Peri, peripherals}; |
| 6 | 7 | ||
| 7 | pub(crate) fn init() { | 8 | pub(crate) fn init() { |
| @@ -109,13 +110,7 @@ impl<'d> Input<'d> { | |||
| 109 | 110 | ||
| 110 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | 111 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. |
| 111 | pub fn set_pull(&mut self, pull: Pull) { | 112 | pub fn set_pull(&mut self, pull: Pull) { |
| 112 | match_iocon!(register, self.pin.pin_bank(), self.pin.pin_number(), { | 113 | self.pin.set_pull(pull); |
| 113 | register.modify(|w| match pull { | ||
| 114 | Pull::None => w.set_mode(PioMode::INACTIVE), | ||
| 115 | Pull::Up => w.set_mode(PioMode::PULL_UP), | ||
| 116 | Pull::Down => w.set_mode(PioMode::PULL_DOWN), | ||
| 117 | }); | ||
| 118 | }); | ||
| 119 | } | 114 | } |
| 120 | 115 | ||
| 121 | /// Get the current input level of the pin. | 116 | /// Get the current input level of the pin. |
| @@ -193,11 +188,20 @@ impl<'d> Flex<'d> { | |||
| 193 | 1 << self.pin.pin_number() | 188 | 1 << self.pin.pin_number() |
| 194 | } | 189 | } |
| 195 | 190 | ||
| 191 | /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. | ||
| 192 | pub fn set_pull(&mut self, pull: Pull) { | ||
| 193 | self.pin.pio().modify(|w| match pull { | ||
| 194 | Pull::None => w.set_mode(PioMode::INACTIVE), | ||
| 195 | Pull::Up => w.set_mode(PioMode::PULL_UP), | ||
| 196 | Pull::Down => w.set_mode(PioMode::PULL_DOWN), | ||
| 197 | }); | ||
| 198 | } | ||
| 199 | |||
| 196 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default | 200 | /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default |
| 197 | /// setting for pins is (usually) non-digital. | 201 | /// setting for pins is (usually) non-digital. |
| 198 | fn set_as_digital(&mut self) { | 202 | fn set_as_digital(&mut self) { |
| 199 | match_iocon!(register, self.pin_bank(), self.pin_number(), { | 203 | self.pin.pio().modify(|w| { |
| 200 | register.modify(|w| w.set_digimode(PioDigimode::DIGITAL)); | 204 | w.set_digimode(PioDigimode::DIGITAL); |
| 201 | }); | 205 | }); |
| 202 | } | 206 | } |
| 203 | 207 | ||
| @@ -220,6 +224,14 @@ impl<'d> Flex<'d> { | |||
| 220 | pub(crate) trait SealedPin: Sized { | 224 | pub(crate) trait SealedPin: Sized { |
| 221 | fn pin_bank(&self) -> Bank; | 225 | fn pin_bank(&self) -> Bank; |
| 222 | fn pin_number(&self) -> u8; | 226 | fn pin_number(&self) -> u8; |
| 227 | |||
| 228 | #[inline] | ||
| 229 | fn pio(&self) -> Reg<iocon::regs::Pio, RW> { | ||
| 230 | match self.pin_bank() { | ||
| 231 | Bank::Bank0 => IOCON.pio0(self.pin_number() as usize), | ||
| 232 | Bank::Bank1 => IOCON.pio1(self.pin_number() as usize), | ||
| 233 | } | ||
| 234 | } | ||
| 223 | } | 235 | } |
| 224 | 236 | ||
| 225 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an | 237 | /// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an |
| @@ -272,40 +284,6 @@ impl SealedPin for AnyPin { | |||
| 272 | } | 284 | } |
| 273 | } | 285 | } |
| 274 | 286 | ||
| 275 | /// Match the pin bank and number of a pin to the corresponding IOCON register. | ||
| 276 | /// | ||
| 277 | /// # Example | ||
| 278 | /// ``` | ||
| 279 | /// use embassy_nxp::gpio::Bank; | ||
| 280 | /// use embassy_nxp::pac_utils::{iocon_reg, match_iocon}; | ||
| 281 | /// | ||
| 282 | /// // Make pin PIO1_6 digital and set it to pull-down mode. | ||
| 283 | /// match_iocon!(register, Bank::Bank1, 6, { | ||
| 284 | /// register.modify(|w|{ | ||
| 285 | /// w.set_mode(PioMode::PULL_DOWN); | ||
| 286 | /// w.set_digimode(PioDigimode::DIGITAL); | ||
| 287 | /// | ||
| 288 | /// } | ||
| 289 | /// }); | ||
| 290 | /// ``` | ||
| 291 | macro_rules! match_iocon { | ||
| 292 | ($register:ident, $pin_bank:expr, $pin_number:expr, $action:expr) => { | ||
| 293 | match $pin_bank { | ||
| 294 | Bank::Bank0 => { | ||
| 295 | let $register = IOCON.pio0($pin_number as usize); | ||
| 296 | $action; | ||
| 297 | } | ||
| 298 | |||
| 299 | Bank::Bank1 => { | ||
| 300 | let $register = IOCON.pio1($pin_number as usize); | ||
| 301 | $action; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | }; | ||
| 305 | } | ||
| 306 | |||
| 307 | pub(crate) use match_iocon; | ||
| 308 | |||
| 309 | macro_rules! impl_pin { | 287 | macro_rules! impl_pin { |
| 310 | ($name:ident, $bank:expr, $pin_num:expr) => { | 288 | ($name:ident, $bank:expr, $pin_num:expr) => { |
| 311 | impl Pin for peripherals::$name {} | 289 | impl Pin for peripherals::$name {} |
diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs index 9576f02b1..4058881a5 100644 --- a/embassy-nxp/src/lib.rs +++ b/embassy-nxp/src/lib.rs | |||
| @@ -10,6 +10,8 @@ pub mod gpio; | |||
| 10 | #[cfg(feature = "lpc55-core0")] | 10 | #[cfg(feature = "lpc55-core0")] |
| 11 | pub mod pint; | 11 | pub mod pint; |
| 12 | #[cfg(feature = "lpc55-core0")] | 12 | #[cfg(feature = "lpc55-core0")] |
| 13 | pub mod pwm; | ||
| 14 | #[cfg(feature = "lpc55-core0")] | ||
| 13 | pub mod usart; | 15 | pub mod usart; |
| 14 | 16 | ||
| 15 | #[cfg(feature = "_time_driver")] | 17 | #[cfg(feature = "_time_driver")] |
| @@ -154,7 +156,10 @@ pub fn init(_config: config::Config) -> Peripherals { | |||
| 154 | gpio::init(); | 156 | gpio::init(); |
| 155 | 157 | ||
| 156 | #[cfg(feature = "lpc55-core0")] | 158 | #[cfg(feature = "lpc55-core0")] |
| 157 | pint::init(); | 159 | { |
| 160 | pint::init(); | ||
| 161 | pwm::Pwm::reset(); | ||
| 162 | } | ||
| 158 | 163 | ||
| 159 | #[cfg(feature = "_time_driver")] | 164 | #[cfg(feature = "_time_driver")] |
| 160 | time_driver::init(); | 165 | time_driver::init(); |
diff --git a/embassy-nxp/src/pwm.rs b/embassy-nxp/src/pwm.rs new file mode 100644 index 000000000..68980924a --- /dev/null +++ b/embassy-nxp/src/pwm.rs | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | //! Pulse-Width Modulation (PWM) driver. | ||
| 2 | |||
| 3 | #[cfg_attr(feature = "lpc55-core0", path = "./pwm/lpc55.rs")] | ||
| 4 | mod inner; | ||
| 5 | pub use inner::*; | ||
diff --git a/embassy-nxp/src/pwm/lpc55.rs b/embassy-nxp/src/pwm/lpc55.rs new file mode 100644 index 000000000..197184ad6 --- /dev/null +++ b/embassy-nxp/src/pwm/lpc55.rs | |||
| @@ -0,0 +1,325 @@ | |||
| 1 | use core::sync::atomic::{AtomicU8, AtomicU32, Ordering}; | ||
| 2 | |||
| 3 | use embassy_hal_internal::{Peri, PeripheralType}; | ||
| 4 | |||
| 5 | use crate::gpio::AnyPin; | ||
| 6 | use crate::pac::iocon::vals::{PioDigimode, PioFunc, PioMode, PioOd, PioSlew}; | ||
| 7 | use crate::pac::sct0::vals; | ||
| 8 | use crate::pac::syscon::vals::{SctRst, SctclkselSel}; | ||
| 9 | use crate::pac::{SCT0, SYSCON}; | ||
| 10 | |||
| 11 | // Since for now the counter is shared, the TOP value has to be kept. | ||
| 12 | static TOP_VALUE: AtomicU32 = AtomicU32::new(0); | ||
| 13 | // To check if there are still active instances. | ||
| 14 | static REF_COUNT: AtomicU8 = AtomicU8::new(0); | ||
| 15 | |||
| 16 | /// The configuration of a PWM output. | ||
| 17 | /// Note the period in clock cycles of an output can be computed as: | ||
| 18 | /// `(top + 1) * (phase_correct ? 1 : 2) * divider * prescale_factor` | ||
| 19 | /// By default, the clock used is 96 MHz. | ||
| 20 | #[non_exhaustive] | ||
| 21 | #[derive(Clone)] | ||
| 22 | pub struct Config { | ||
| 23 | /// Inverts the PWM output signal. | ||
| 24 | pub invert: bool, | ||
| 25 | /// Enables phase-correct mode for PWM operation. | ||
| 26 | /// In phase-correct mode, the PWM signal is generated in such a way that | ||
| 27 | /// the pulse is always centered regardless of the duty cycle. | ||
| 28 | /// The output frequency is halved when phase-correct mode is enabled. | ||
| 29 | pub phase_correct: bool, | ||
| 30 | /// Enables the PWM output, allowing it to generate an output. | ||
| 31 | pub enable: bool, | ||
| 32 | /// A SYSCON clock divider allows precise control over | ||
| 33 | /// the PWM output frequency by gating the PWM counter increment. | ||
| 34 | /// A higher value will result in a slower output frequency. | ||
| 35 | /// The clock is divided by `divider + 1`. | ||
| 36 | pub divider: u8, | ||
| 37 | /// Specifies the factor by which the SCT clock is prescaled to produce the unified | ||
| 38 | /// counter clock. The counter clock is clocked at the rate of the SCT clock divided by | ||
| 39 | /// `PRE + 1`. | ||
| 40 | pub prescale_factor: u8, | ||
| 41 | /// The output goes high when `compare` is higher than the | ||
| 42 | /// counter. A compare of 0 will produce an always low output, while a | ||
| 43 | /// compare of `top` will produce an always high output. | ||
| 44 | pub compare: u32, | ||
| 45 | /// The point at which the counter resets, representing the maximum possible | ||
| 46 | /// period. The counter will either wrap to 0 or reverse depending on the | ||
| 47 | /// setting of `phase_correct`. | ||
| 48 | pub top: u32, | ||
| 49 | } | ||
| 50 | |||
| 51 | impl Config { | ||
| 52 | pub fn new(compare: u32, top: u32) -> Self { | ||
| 53 | Self { | ||
| 54 | invert: false, | ||
| 55 | phase_correct: false, | ||
| 56 | enable: true, | ||
| 57 | divider: 255, | ||
| 58 | prescale_factor: 255, | ||
| 59 | compare, | ||
| 60 | top, | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | /// PWM driver. | ||
| 66 | pub struct Pwm<'d> { | ||
| 67 | _pin: Peri<'d, AnyPin>, | ||
| 68 | output: usize, | ||
| 69 | } | ||
| 70 | |||
| 71 | impl<'d> Pwm<'d> { | ||
| 72 | pub(crate) fn reset() { | ||
| 73 | // Reset SCTimer => Reset counter and halt it. | ||
| 74 | // It should be done only once during the initialization of the board. | ||
| 75 | SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::ASSERTED)); | ||
| 76 | SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::RELEASED)); | ||
| 77 | } | ||
| 78 | fn new_inner<T: Output>(output: usize, channel: Peri<'d, impl OutputChannelPin<T>>, config: Config) -> Self { | ||
| 79 | // Enable clocks (Syscon is enabled by default) | ||
| 80 | critical_section::with(|_cs| { | ||
| 81 | if !SYSCON.ahbclkctrl0().read().iocon() { | ||
| 82 | SYSCON.ahbclkctrl0().modify(|w| w.set_iocon(true)); | ||
| 83 | } | ||
| 84 | if !SYSCON.ahbclkctrl1().read().sct() { | ||
| 85 | SYSCON.ahbclkctrl1().modify(|w| w.set_sct(true)); | ||
| 86 | } | ||
| 87 | }); | ||
| 88 | |||
| 89 | // Choose the clock for PWM. | ||
| 90 | SYSCON.sctclksel().modify(|w| w.set_sel(SctclkselSel::ENUM_0X3)); | ||
| 91 | // For now, 96 MHz. | ||
| 92 | |||
| 93 | // IOCON Setup | ||
| 94 | channel.pio().modify(|w| { | ||
| 95 | w.set_func(channel.pin_func()); | ||
| 96 | w.set_digimode(PioDigimode::DIGITAL); | ||
| 97 | w.set_slew(PioSlew::STANDARD); | ||
| 98 | w.set_mode(PioMode::INACTIVE); | ||
| 99 | w.set_od(PioOd::NORMAL); | ||
| 100 | }); | ||
| 101 | |||
| 102 | Self::configure(output, &config); | ||
| 103 | REF_COUNT.fetch_add(1, Ordering::Relaxed); | ||
| 104 | Self { | ||
| 105 | _pin: channel.into(), | ||
| 106 | output, | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | /// Create PWM driver with a single 'a' pin as output. | ||
| 111 | #[inline] | ||
| 112 | pub fn new_output<T: Output>( | ||
| 113 | output: Peri<'d, T>, | ||
| 114 | channel: Peri<'d, impl OutputChannelPin<T>>, | ||
| 115 | config: Config, | ||
| 116 | ) -> Self { | ||
| 117 | Self::new_inner(output.number(), channel, config) | ||
| 118 | } | ||
| 119 | |||
| 120 | /// Set the PWM config. | ||
| 121 | pub fn set_config(&mut self, config: &Config) { | ||
| 122 | Self::configure(self.output, config); | ||
| 123 | } | ||
| 124 | |||
| 125 | fn configure(output_number: usize, config: &Config) { | ||
| 126 | // Stop and reset the counter | ||
| 127 | SCT0.ctrl().modify(|w| { | ||
| 128 | if config.phase_correct { | ||
| 129 | w.set_bidir_l(vals::Bidir::UP_DOWN); | ||
| 130 | } else { | ||
| 131 | w.set_bidir_l(vals::Bidir::UP); | ||
| 132 | } | ||
| 133 | w.set_halt_l(true); // halt the counter to make new changes | ||
| 134 | w.set_clrctr_l(true); // clear the counter | ||
| 135 | }); | ||
| 136 | // Divides clock by 1-255 | ||
| 137 | SYSCON.sctclkdiv().modify(|w| w.set_div(config.divider)); | ||
| 138 | |||
| 139 | SCT0.config().modify(|w| { | ||
| 140 | w.set_unify(vals::Unify::UNIFIED_COUNTER); | ||
| 141 | w.set_clkmode(vals::Clkmode::SYSTEM_CLOCK_MODE); | ||
| 142 | w.set_noreload_l(true); | ||
| 143 | w.set_autolimit_l(true); | ||
| 144 | }); | ||
| 145 | |||
| 146 | // Before setting the match registers, we have to make sure that `compare` is lower or equal to `top`, | ||
| 147 | // otherwise the counter will not reach the match and, therefore, no events will happen. | ||
| 148 | assert!(config.compare <= config.top); | ||
| 149 | |||
| 150 | if TOP_VALUE.load(Ordering::Relaxed) == 0 { | ||
| 151 | // Match 0 will reset the timer using TOP value | ||
| 152 | SCT0.match_(0).modify(|w| { | ||
| 153 | w.set_matchn_l((config.top & 0xFFFF) as u16); | ||
| 154 | w.set_matchn_h((config.top >> 16) as u16); | ||
| 155 | }); | ||
| 156 | } else { | ||
| 157 | panic!("The top value cannot be changed after the initialization."); | ||
| 158 | } | ||
| 159 | // The actual matches that are used for event logic | ||
| 160 | SCT0.match_(output_number + 1).modify(|w| { | ||
| 161 | w.set_matchn_l((config.compare & 0xFFFF) as u16); | ||
| 162 | w.set_matchn_h((config.compare >> 16) as u16); | ||
| 163 | }); | ||
| 164 | |||
| 165 | SCT0.match_(15).modify(|w| { | ||
| 166 | w.set_matchn_l(0); | ||
| 167 | w.set_matchn_h(0); | ||
| 168 | }); | ||
| 169 | |||
| 170 | // Event configuration | ||
| 171 | critical_section::with(|_cs| { | ||
| 172 | // If it is already set, don't change | ||
| 173 | if SCT0.ev(0).ev_ctrl().read().matchsel() != 15 { | ||
| 174 | SCT0.ev(0).ev_ctrl().modify(|w| { | ||
| 175 | w.set_matchsel(15); | ||
| 176 | w.set_combmode(vals::Combmode::MATCH); | ||
| 177 | // STATE + statev, where STATE is a on-board variable. | ||
| 178 | w.set_stateld(vals::Stateld::ADD); | ||
| 179 | w.set_statev(0); | ||
| 180 | }); | ||
| 181 | } | ||
| 182 | }); | ||
| 183 | SCT0.ev(output_number + 1).ev_ctrl().modify(|w| { | ||
| 184 | w.set_matchsel((output_number + 1) as u8); | ||
| 185 | w.set_combmode(vals::Combmode::MATCH); | ||
| 186 | w.set_stateld(vals::Stateld::ADD); | ||
| 187 | // STATE + statev, where STATE is a on-board variable. | ||
| 188 | w.set_statev(0); | ||
| 189 | }); | ||
| 190 | |||
| 191 | // Assign events to states | ||
| 192 | SCT0.ev(0).ev_state().modify(|w| w.set_statemskn(1 << 0)); | ||
| 193 | SCT0.ev(output_number + 1) | ||
| 194 | .ev_state() | ||
| 195 | .modify(|w| w.set_statemskn(1 << 0)); | ||
| 196 | // TODO(frihetselsker): optimize nxp-pac so that `set_clr` and `set_set` are turned into a bit array. | ||
| 197 | if config.invert { | ||
| 198 | // Low when event 0 is active | ||
| 199 | SCT0.out(output_number).out_clr().modify(|w| w.set_clr(1 << 0)); | ||
| 200 | // High when event `output_number + 1` is active | ||
| 201 | SCT0.out(output_number) | ||
| 202 | .out_set() | ||
| 203 | .modify(|w| w.set_set(1 << (output_number + 1))); | ||
| 204 | } else { | ||
| 205 | // High when event 0 is active | ||
| 206 | SCT0.out(output_number).out_set().modify(|w| w.set_set(1 << 0)); | ||
| 207 | // Low when event `output_number + 1` is active | ||
| 208 | SCT0.out(output_number) | ||
| 209 | .out_clr() | ||
| 210 | .modify(|w| w.set_clr(1 << (output_number + 1))); | ||
| 211 | } | ||
| 212 | |||
| 213 | if config.phase_correct { | ||
| 214 | // Take into account the set matches and reverse their actions while counting back. | ||
| 215 | SCT0.outputdirctrl() | ||
| 216 | .modify(|w| w.set_setclr(output_number, vals::Setclr::L_REVERSED)); | ||
| 217 | } | ||
| 218 | |||
| 219 | // State 0 by default | ||
| 220 | SCT0.state().modify(|w| w.set_state_l(0)); | ||
| 221 | // Remove halt and start the actual counter | ||
| 222 | SCT0.ctrl().modify(|w| { | ||
| 223 | w.set_halt_l(!config.enable); | ||
| 224 | }); | ||
| 225 | } | ||
| 226 | |||
| 227 | /// Read PWM counter. | ||
| 228 | #[inline] | ||
| 229 | pub fn counter(&self) -> u32 { | ||
| 230 | SCT0.count().read().0 | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | impl<'d> Drop for Pwm<'d> { | ||
| 235 | fn drop(&mut self) { | ||
| 236 | REF_COUNT.fetch_sub(1, Ordering::AcqRel); | ||
| 237 | if REF_COUNT.load(Ordering::Acquire) == 0 { | ||
| 238 | TOP_VALUE.store(0, Ordering::Release); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | trait SealedOutput { | ||
| 244 | /// Output number. | ||
| 245 | fn number(&self) -> usize; | ||
| 246 | } | ||
| 247 | |||
| 248 | /// PWM Output. | ||
| 249 | #[allow(private_bounds)] | ||
| 250 | pub trait Output: PeripheralType + SealedOutput {} | ||
| 251 | |||
| 252 | macro_rules! output { | ||
| 253 | ($name:ident, $num:expr) => { | ||
| 254 | impl SealedOutput for crate::peripherals::$name { | ||
| 255 | fn number(&self) -> usize { | ||
| 256 | $num | ||
| 257 | } | ||
| 258 | } | ||
| 259 | impl Output for crate::peripherals::$name {} | ||
| 260 | }; | ||
| 261 | } | ||
| 262 | |||
| 263 | output!(PWM_OUTPUT0, 0); | ||
| 264 | output!(PWM_OUTPUT1, 1); | ||
| 265 | output!(PWM_OUTPUT2, 2); | ||
| 266 | output!(PWM_OUTPUT3, 3); | ||
| 267 | output!(PWM_OUTPUT4, 4); | ||
| 268 | output!(PWM_OUTPUT5, 5); | ||
| 269 | output!(PWM_OUTPUT6, 6); | ||
| 270 | output!(PWM_OUTPUT7, 7); | ||
| 271 | output!(PWM_OUTPUT8, 8); | ||
| 272 | output!(PWM_OUTPUT9, 9); | ||
| 273 | |||
| 274 | /// PWM Output Channel. | ||
| 275 | pub trait OutputChannelPin<T: Output>: crate::gpio::Pin { | ||
| 276 | fn pin_func(&self) -> PioFunc; | ||
| 277 | } | ||
| 278 | |||
| 279 | macro_rules! impl_pin { | ||
| 280 | ($pin:ident, $output:ident, $func:ident) => { | ||
| 281 | impl crate::pwm::inner::OutputChannelPin<crate::peripherals::$output> for crate::peripherals::$pin { | ||
| 282 | fn pin_func(&self) -> PioFunc { | ||
| 283 | PioFunc::$func | ||
| 284 | } | ||
| 285 | } | ||
| 286 | }; | ||
| 287 | } | ||
| 288 | |||
| 289 | impl_pin!(PIO0_2, PWM_OUTPUT0, ALT3); | ||
| 290 | impl_pin!(PIO0_17, PWM_OUTPUT0, ALT4); | ||
| 291 | impl_pin!(PIO1_4, PWM_OUTPUT0, ALT4); | ||
| 292 | impl_pin!(PIO1_23, PWM_OUTPUT0, ALT2); | ||
| 293 | |||
| 294 | impl_pin!(PIO0_3, PWM_OUTPUT1, ALT3); | ||
| 295 | impl_pin!(PIO0_18, PWM_OUTPUT1, ALT4); | ||
| 296 | impl_pin!(PIO1_8, PWM_OUTPUT1, ALT4); | ||
| 297 | impl_pin!(PIO1_24, PWM_OUTPUT1, ALT2); | ||
| 298 | |||
| 299 | impl_pin!(PIO0_10, PWM_OUTPUT2, ALT5); | ||
| 300 | impl_pin!(PIO0_15, PWM_OUTPUT2, ALT4); | ||
| 301 | impl_pin!(PIO0_19, PWM_OUTPUT2, ALT4); | ||
| 302 | impl_pin!(PIO1_9, PWM_OUTPUT2, ALT4); | ||
| 303 | impl_pin!(PIO1_25, PWM_OUTPUT2, ALT2); | ||
| 304 | |||
| 305 | impl_pin!(PIO0_22, PWM_OUTPUT3, ALT4); | ||
| 306 | impl_pin!(PIO0_31, PWM_OUTPUT3, ALT4); | ||
| 307 | impl_pin!(PIO1_10, PWM_OUTPUT3, ALT4); | ||
| 308 | impl_pin!(PIO1_26, PWM_OUTPUT3, ALT2); | ||
| 309 | |||
| 310 | impl_pin!(PIO0_23, PWM_OUTPUT4, ALT4); | ||
| 311 | impl_pin!(PIO1_3, PWM_OUTPUT4, ALT4); | ||
| 312 | impl_pin!(PIO1_17, PWM_OUTPUT4, ALT4); | ||
| 313 | |||
| 314 | impl_pin!(PIO0_26, PWM_OUTPUT5, ALT4); | ||
| 315 | impl_pin!(PIO1_18, PWM_OUTPUT5, ALT4); | ||
| 316 | |||
| 317 | impl_pin!(PIO0_27, PWM_OUTPUT6, ALT4); | ||
| 318 | impl_pin!(PIO1_31, PWM_OUTPUT6, ALT4); | ||
| 319 | |||
| 320 | impl_pin!(PIO0_28, PWM_OUTPUT7, ALT4); | ||
| 321 | impl_pin!(PIO1_19, PWM_OUTPUT7, ALT2); | ||
| 322 | |||
| 323 | impl_pin!(PIO0_29, PWM_OUTPUT8, ALT4); | ||
| 324 | |||
| 325 | impl_pin!(PIO0_30, PWM_OUTPUT9, ALT4); | ||
diff --git a/embassy-nxp/src/usart/lpc55.rs b/embassy-nxp/src/usart/lpc55.rs index 0be5a8ce7..d54927b25 100644 --- a/embassy-nxp/src/usart/lpc55.rs +++ b/embassy-nxp/src/usart/lpc55.rs | |||
| @@ -11,7 +11,7 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 11 | use embedded_io::{self, ErrorKind}; | 11 | use embedded_io::{self, ErrorKind}; |
| 12 | 12 | ||
| 13 | use crate::dma::{AnyChannel, Channel}; | 13 | use crate::dma::{AnyChannel, Channel}; |
| 14 | use crate::gpio::{AnyPin, Bank, SealedPin, match_iocon}; | 14 | use crate::gpio::{AnyPin, SealedPin}; |
| 15 | use crate::interrupt::Interrupt; | 15 | use crate::interrupt::Interrupt; |
| 16 | use crate::interrupt::typelevel::{Binding, Interrupt as _}; | 16 | use crate::interrupt::typelevel::{Binding, Interrupt as _}; |
| 17 | use crate::pac::flexcomm::Flexcomm as FlexcommReg; | 17 | use crate::pac::flexcomm::Flexcomm as FlexcommReg; |
| @@ -146,7 +146,8 @@ impl<'d, M: Mode> UsartTx<'d, M> { | |||
| 146 | tx_dma: Peri<'d, impl Channel>, | 146 | tx_dma: Peri<'d, impl Channel>, |
| 147 | config: Config, | 147 | config: Config, |
| 148 | ) -> Self { | 148 | ) -> Self { |
| 149 | Usart::<M>::init::<T>(Some(tx.into()), None, config); | 149 | let tx_func = tx.pin_func(); |
| 150 | Usart::<M>::init::<T>(Some((tx.into(), tx_func)), None, config); | ||
| 150 | Self::new_inner(T::info(), Some(tx_dma.into())) | 151 | Self::new_inner(T::info(), Some(tx_dma.into())) |
| 151 | } | 152 | } |
| 152 | 153 | ||
| @@ -179,7 +180,8 @@ impl<'d, M: Mode> UsartTx<'d, M> { | |||
| 179 | 180 | ||
| 180 | impl<'d> UsartTx<'d, Blocking> { | 181 | impl<'d> UsartTx<'d, Blocking> { |
| 181 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { | 182 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { |
| 182 | Usart::<Blocking>::init::<T>(Some(tx.into()), None, config); | 183 | let tx_func = tx.pin_func(); |
| 184 | Usart::<Blocking>::init::<T>(Some((tx.into(), tx_func)), None, config); | ||
| 183 | Self::new_inner(T::info(), None) | 185 | Self::new_inner(T::info(), None) |
| 184 | } | 186 | } |
| 185 | } | 187 | } |
| @@ -208,7 +210,8 @@ impl<'d, M: Mode> UsartRx<'d, M> { | |||
| 208 | rx_dma: Peri<'d, impl Channel>, | 210 | rx_dma: Peri<'d, impl Channel>, |
| 209 | config: Config, | 211 | config: Config, |
| 210 | ) -> Self { | 212 | ) -> Self { |
| 211 | Usart::<M>::init::<T>(None, Some(rx.into()), config); | 213 | let rx_func = rx.pin_func(); |
| 214 | Usart::<M>::init::<T>(None, Some((rx.into(), rx_func)), config); | ||
| 212 | Self::new_inner(T::info(), T::dma_state(), has_irq, Some(rx_dma.into())) | 215 | Self::new_inner(T::info(), T::dma_state(), has_irq, Some(rx_dma.into())) |
| 213 | } | 216 | } |
| 214 | 217 | ||
| @@ -280,7 +283,8 @@ impl<'d, M: Mode> UsartRx<'d, M> { | |||
| 280 | 283 | ||
| 281 | impl<'d> UsartRx<'d, Blocking> { | 284 | impl<'d> UsartRx<'d, Blocking> { |
| 282 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { | 285 | pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { |
| 283 | Usart::<Blocking>::init::<T>(None, Some(rx.into()), config); | 286 | let rx_func = rx.pin_func(); |
| 287 | Usart::<Blocking>::init::<T>(None, Some((rx.into(), rx_func)), config); | ||
| 284 | Self::new_inner(T::info(), T::dma_state(), false, None) | 288 | Self::new_inner(T::info(), T::dma_state(), false, None) |
| 285 | } | 289 | } |
| 286 | } | 290 | } |
| @@ -405,7 +409,10 @@ impl<'d> Usart<'d, Blocking> { | |||
| 405 | rx: Peri<'d, impl RxPin<T>>, | 409 | rx: Peri<'d, impl RxPin<T>>, |
| 406 | config: Config, | 410 | config: Config, |
| 407 | ) -> Self { | 411 | ) -> Self { |
| 408 | Self::new_inner(usart, tx.into(), rx.into(), false, None, None, config) | 412 | let tx_func = tx.pin_func(); |
| 413 | let rx_func = rx.pin_func(); | ||
| 414 | |||
| 415 | Self::new_inner(usart, tx.into(), tx_func, rx.into(), rx_func, false, None, None, config) | ||
| 409 | } | 416 | } |
| 410 | } | 417 | } |
| 411 | 418 | ||
| @@ -419,10 +426,15 @@ impl<'d> Usart<'d, Async> { | |||
| 419 | rx_dma: Peri<'d, impl RxChannel<T>>, | 426 | rx_dma: Peri<'d, impl RxChannel<T>>, |
| 420 | config: Config, | 427 | config: Config, |
| 421 | ) -> Self { | 428 | ) -> Self { |
| 429 | let tx_func = tx.pin_func(); | ||
| 430 | let rx_func = rx.pin_func(); | ||
| 431 | |||
| 422 | Self::new_inner( | 432 | Self::new_inner( |
| 423 | uart, | 433 | uart, |
| 424 | tx.into(), | 434 | tx.into(), |
| 435 | tx_func, | ||
| 425 | rx.into(), | 436 | rx.into(), |
| 437 | rx_func, | ||
| 426 | true, | 438 | true, |
| 427 | Some(tx_dma.into()), | 439 | Some(tx_dma.into()), |
| 428 | Some(rx_dma.into()), | 440 | Some(rx_dma.into()), |
| @@ -435,20 +447,26 @@ impl<'d, M: Mode> Usart<'d, M> { | |||
| 435 | fn new_inner<T: Instance>( | 447 | fn new_inner<T: Instance>( |
| 436 | _usart: Peri<'d, T>, | 448 | _usart: Peri<'d, T>, |
| 437 | mut tx: Peri<'d, AnyPin>, | 449 | mut tx: Peri<'d, AnyPin>, |
| 450 | tx_func: PioFunc, | ||
| 438 | mut rx: Peri<'d, AnyPin>, | 451 | mut rx: Peri<'d, AnyPin>, |
| 452 | rx_func: PioFunc, | ||
| 439 | has_irq: bool, | 453 | has_irq: bool, |
| 440 | tx_dma: Option<Peri<'d, AnyChannel>>, | 454 | tx_dma: Option<Peri<'d, AnyChannel>>, |
| 441 | rx_dma: Option<Peri<'d, AnyChannel>>, | 455 | rx_dma: Option<Peri<'d, AnyChannel>>, |
| 442 | config: Config, | 456 | config: Config, |
| 443 | ) -> Self { | 457 | ) -> Self { |
| 444 | Self::init::<T>(Some(tx.reborrow()), Some(rx.reborrow()), config); | 458 | Self::init::<T>(Some((tx.reborrow(), tx_func)), Some((rx.reborrow(), rx_func)), config); |
| 445 | Self { | 459 | Self { |
| 446 | tx: UsartTx::new_inner(T::info(), tx_dma), | 460 | tx: UsartTx::new_inner(T::info(), tx_dma), |
| 447 | rx: UsartRx::new_inner(T::info(), T::dma_state(), has_irq, rx_dma), | 461 | rx: UsartRx::new_inner(T::info(), T::dma_state(), has_irq, rx_dma), |
| 448 | } | 462 | } |
| 449 | } | 463 | } |
| 450 | 464 | ||
| 451 | fn init<T: Instance>(tx: Option<Peri<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>, config: Config) { | 465 | fn init<T: Instance>( |
| 466 | tx: Option<(Peri<'_, AnyPin>, PioFunc)>, | ||
| 467 | rx: Option<(Peri<'_, AnyPin>, PioFunc)>, | ||
| 468 | config: Config, | ||
| 469 | ) { | ||
| 452 | Self::configure_flexcomm(T::info().fc_reg, T::instance_number()); | 470 | Self::configure_flexcomm(T::info().fc_reg, T::instance_number()); |
| 453 | Self::configure_clock::<T>(&config); | 471 | Self::configure_clock::<T>(&config); |
| 454 | Self::pin_config::<T>(tx, rx); | 472 | Self::pin_config::<T>(tx, rx); |
| @@ -553,31 +571,27 @@ impl<'d, M: Mode> Usart<'d, M> { | |||
| 553 | .modify(|w| w.set_brgval((brg_value - 1) as u16)); | 571 | .modify(|w| w.set_brgval((brg_value - 1) as u16)); |
| 554 | } | 572 | } |
| 555 | 573 | ||
| 556 | fn pin_config<T: Instance>(tx: Option<Peri<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>) { | 574 | fn pin_config<T: Instance>(tx: Option<(Peri<'_, AnyPin>, PioFunc)>, rx: Option<(Peri<'_, AnyPin>, PioFunc)>) { |
| 557 | if let Some(tx_pin) = tx { | 575 | if let Some((tx_pin, func)) = tx { |
| 558 | match_iocon!(register, tx_pin.pin_bank(), tx_pin.pin_number(), { | 576 | tx_pin.pio().modify(|w| { |
| 559 | register.modify(|w| { | 577 | w.set_func(func); |
| 560 | w.set_func(T::tx_pin_func()); | 578 | w.set_mode(iocon::vals::PioMode::INACTIVE); |
| 561 | w.set_mode(iocon::vals::PioMode::INACTIVE); | 579 | w.set_slew(iocon::vals::PioSlew::STANDARD); |
| 562 | w.set_slew(iocon::vals::PioSlew::STANDARD); | 580 | w.set_invert(false); |
| 563 | w.set_invert(false); | 581 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); |
| 564 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); | 582 | w.set_od(iocon::vals::PioOd::NORMAL); |
| 565 | w.set_od(iocon::vals::PioOd::NORMAL); | 583 | }); |
| 566 | }); | ||
| 567 | }) | ||
| 568 | } | 584 | } |
| 569 | 585 | ||
| 570 | if let Some(rx_pin) = rx { | 586 | if let Some((rx_pin, func)) = rx { |
| 571 | match_iocon!(register, rx_pin.pin_bank(), rx_pin.pin_number(), { | 587 | rx_pin.pio().modify(|w| { |
| 572 | register.modify(|w| { | 588 | w.set_func(func); |
| 573 | w.set_func(T::rx_pin_func()); | 589 | w.set_mode(iocon::vals::PioMode::INACTIVE); |
| 574 | w.set_mode(iocon::vals::PioMode::INACTIVE); | 590 | w.set_slew(iocon::vals::PioSlew::STANDARD); |
| 575 | w.set_slew(iocon::vals::PioSlew::STANDARD); | 591 | w.set_invert(false); |
| 576 | w.set_invert(false); | 592 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); |
| 577 | w.set_digimode(iocon::vals::PioDigimode::DIGITAL); | 593 | w.set_od(iocon::vals::PioOd::NORMAL); |
| 578 | w.set_od(iocon::vals::PioOd::NORMAL); | 594 | }); |
| 579 | }); | ||
| 580 | }) | ||
| 581 | }; | 595 | }; |
| 582 | } | 596 | } |
| 583 | 597 | ||
| @@ -814,8 +828,6 @@ trait SealedInstance { | |||
| 814 | fn info() -> &'static Info; | 828 | fn info() -> &'static Info; |
| 815 | fn dma_state() -> &'static DmaState; | 829 | fn dma_state() -> &'static DmaState; |
| 816 | fn instance_number() -> usize; | 830 | fn instance_number() -> usize; |
| 817 | fn tx_pin_func() -> PioFunc; | ||
| 818 | fn rx_pin_func() -> PioFunc; | ||
| 819 | } | 831 | } |
| 820 | 832 | ||
| 821 | /// UART instance. | 833 | /// UART instance. |
| @@ -826,7 +838,7 @@ pub trait Instance: SealedInstance + PeripheralType { | |||
| 826 | } | 838 | } |
| 827 | 839 | ||
| 828 | macro_rules! impl_instance { | 840 | macro_rules! impl_instance { |
| 829 | ($inst:ident, $fc:ident, $tx_pin:ident, $rx_pin:ident, $fc_num:expr) => { | 841 | ($inst:ident, $fc:ident, $fc_num:expr) => { |
| 830 | impl $crate::usart::inner::SealedInstance for $crate::peripherals::$inst { | 842 | impl $crate::usart::inner::SealedInstance for $crate::peripherals::$inst { |
| 831 | fn info() -> &'static Info { | 843 | fn info() -> &'static Info { |
| 832 | static INFO: Info = Info { | 844 | static INFO: Info = Info { |
| @@ -848,14 +860,6 @@ macro_rules! impl_instance { | |||
| 848 | fn instance_number() -> usize { | 860 | fn instance_number() -> usize { |
| 849 | $fc_num | 861 | $fc_num |
| 850 | } | 862 | } |
| 851 | #[inline] | ||
| 852 | fn tx_pin_func() -> PioFunc { | ||
| 853 | PioFunc::$tx_pin | ||
| 854 | } | ||
| 855 | #[inline] | ||
| 856 | fn rx_pin_func() -> PioFunc { | ||
| 857 | PioFunc::$rx_pin | ||
| 858 | } | ||
| 859 | } | 863 | } |
| 860 | impl $crate::usart::Instance for $crate::peripherals::$inst { | 864 | impl $crate::usart::Instance for $crate::peripherals::$inst { |
| 861 | type Interrupt = crate::interrupt::typelevel::$fc; | 865 | type Interrupt = crate::interrupt::typelevel::$fc; |
| @@ -863,45 +867,72 @@ macro_rules! impl_instance { | |||
| 863 | }; | 867 | }; |
| 864 | } | 868 | } |
| 865 | 869 | ||
| 866 | impl_instance!(USART0, FLEXCOMM0, ALT1, ALT1, 0); | 870 | impl_instance!(USART0, FLEXCOMM0, 0); |
| 867 | impl_instance!(USART1, FLEXCOMM1, ALT2, ALT2, 1); | 871 | impl_instance!(USART1, FLEXCOMM1, 1); |
| 868 | impl_instance!(USART2, FLEXCOMM2, ALT1, ALT1, 2); | 872 | impl_instance!(USART2, FLEXCOMM2, 2); |
| 869 | impl_instance!(USART3, FLEXCOMM3, ALT1, ALT1, 3); | 873 | impl_instance!(USART3, FLEXCOMM3, 3); |
| 870 | impl_instance!(USART4, FLEXCOMM4, ALT1, ALT2, 4); | 874 | impl_instance!(USART4, FLEXCOMM4, 4); |
| 871 | impl_instance!(USART5, FLEXCOMM5, ALT3, ALT3, 5); | 875 | impl_instance!(USART5, FLEXCOMM5, 5); |
| 872 | impl_instance!(USART6, FLEXCOMM6, ALT2, ALT2, 6); | 876 | impl_instance!(USART6, FLEXCOMM6, 6); |
| 873 | impl_instance!(USART7, FLEXCOMM7, ALT7, ALT7, 7); | 877 | impl_instance!(USART7, FLEXCOMM7, 7); |
| 878 | |||
| 879 | pub(crate) trait SealedTxPin<T: Instance>: crate::gpio::Pin { | ||
| 880 | fn pin_func(&self) -> PioFunc; | ||
| 881 | } | ||
| 882 | |||
| 883 | pub(crate) trait SealedRxPin<T: Instance>: crate::gpio::Pin { | ||
| 884 | fn pin_func(&self) -> PioFunc; | ||
| 885 | } | ||
| 874 | 886 | ||
| 875 | /// Trait for TX pins. | 887 | /// Trait for TX pins. |
| 876 | pub trait TxPin<T: Instance>: crate::gpio::Pin {} | 888 | #[allow(private_bounds)] |
| 889 | pub trait TxPin<T: Instance>: SealedTxPin<T> + crate::gpio::Pin {} | ||
| 890 | |||
| 877 | /// Trait for RX pins. | 891 | /// Trait for RX pins. |
| 878 | pub trait RxPin<T: Instance>: crate::gpio::Pin {} | 892 | #[allow(private_bounds)] |
| 893 | pub trait RxPin<T: Instance>: SealedRxPin<T> + crate::gpio::Pin {} | ||
| 894 | |||
| 895 | macro_rules! impl_tx_pin { | ||
| 896 | ($pin:ident, $instance:ident, $func: ident) => { | ||
| 897 | impl SealedTxPin<crate::peripherals::$instance> for crate::peripherals::$pin { | ||
| 898 | fn pin_func(&self) -> PioFunc { | ||
| 899 | PioFunc::$func | ||
| 900 | } | ||
| 901 | } | ||
| 879 | 902 | ||
| 880 | macro_rules! impl_pin { | ||
| 881 | ($pin:ident, $instance:ident, Tx) => { | ||
| 882 | impl TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} | 903 | impl TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} |
| 883 | }; | 904 | }; |
| 884 | ($pin:ident, $instance:ident, Rx) => { | 905 | } |
| 906 | |||
| 907 | macro_rules! impl_rx_pin { | ||
| 908 | ($pin:ident, $instance:ident, $func: ident) => { | ||
| 909 | impl SealedRxPin<crate::peripherals::$instance> for crate::peripherals::$pin { | ||
| 910 | fn pin_func(&self) -> PioFunc { | ||
| 911 | PioFunc::$func | ||
| 912 | } | ||
| 913 | } | ||
| 914 | |||
| 885 | impl RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} | 915 | impl RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} |
| 886 | }; | 916 | }; |
| 887 | } | 917 | } |
| 888 | 918 | ||
| 889 | impl_pin!(PIO1_6, USART0, Tx); | 919 | impl_tx_pin!(PIO1_6, USART0, ALT1); |
| 890 | impl_pin!(PIO1_5, USART0, Rx); | 920 | impl_tx_pin!(PIO1_11, USART1, ALT2); |
| 891 | impl_pin!(PIO1_11, USART1, Tx); | 921 | impl_tx_pin!(PIO0_27, USART2, ALT1); |
| 892 | impl_pin!(PIO1_10, USART1, Rx); | 922 | impl_tx_pin!(PIO0_2, USART3, ALT1); |
| 893 | impl_pin!(PIO0_27, USART2, Tx); | 923 | impl_tx_pin!(PIO0_16, USART4, ALT1); |
| 894 | impl_pin!(PIO1_24, USART2, Rx); | 924 | impl_tx_pin!(PIO0_9, USART5, ALT3); |
| 895 | impl_pin!(PIO0_2, USART3, Tx); | 925 | impl_tx_pin!(PIO1_16, USART6, ALT2); |
| 896 | impl_pin!(PIO0_3, USART3, Rx); | 926 | impl_tx_pin!(PIO0_19, USART7, ALT7); |
| 897 | impl_pin!(PIO0_16, USART4, Tx); | 927 | |
| 898 | impl_pin!(PIO0_5, USART4, Rx); | 928 | impl_rx_pin!(PIO1_5, USART0, ALT1); |
| 899 | impl_pin!(PIO0_9, USART5, Tx); | 929 | impl_rx_pin!(PIO1_10, USART1, ALT2); |
| 900 | impl_pin!(PIO0_8, USART5, Rx); | 930 | impl_rx_pin!(PIO1_24, USART2, ALT1); |
| 901 | impl_pin!(PIO1_16, USART6, Tx); | 931 | impl_rx_pin!(PIO0_3, USART3, ALT1); |
| 902 | impl_pin!(PIO1_13, USART6, Rx); | 932 | impl_rx_pin!(PIO0_5, USART4, ALT2); |
| 903 | impl_pin!(PIO0_19, USART7, Tx); | 933 | impl_rx_pin!(PIO0_8, USART5, ALT3); |
| 904 | impl_pin!(PIO0_20, USART7, Rx); | 934 | impl_rx_pin!(PIO1_13, USART6, ALT2); |
| 935 | impl_rx_pin!(PIO0_20, USART7, ALT7); | ||
| 905 | 936 | ||
| 906 | /// Trait for TX DMA channels. | 937 | /// Trait for TX DMA channels. |
| 907 | pub trait TxChannel<T: Instance>: crate::dma::Channel {} | 938 | pub trait TxChannel<T: Instance>: crate::dma::Channel {} |
diff --git a/embassy-rp/CHANGELOG.md b/embassy-rp/CHANGELOG.md index e932bcaa3..3b3cb5351 100644 --- a/embassy-rp/CHANGELOG.md +++ b/embassy-rp/CHANGELOG.md | |||
| @@ -8,12 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - Fix several minor typos in documentation | ||
| 11 | - Add PIO SPI | 12 | - Add PIO SPI |
| 12 | - Add PIO I2S input | 13 | - Add PIO I2S input |
| 13 | - Add PIO onewire parasite power strong pullup | 14 | - Add PIO onewire parasite power strong pullup |
| 14 | - add `wait_for_alarm` and `alarm_scheduled` methods to rtc module ([#4216](https://github.com/embassy-rs/embassy/pull/4216)) | 15 | - add `wait_for_alarm` and `alarm_scheduled` methods to rtc module ([#4216](https://github.com/embassy-rs/embassy/pull/4216)) |
| 15 | - rp235x: use msplim for stack guard instead of MPU | 16 | - rp235x: use msplim for stack guard instead of MPU |
| 16 | - Add reset_to_usb_boot for rp235x ([#4705](https://github.com/embassy-rs/embassy/pull/4705)) | 17 | - Add reset_to_usb_boot for rp235x ([#4705](https://github.com/embassy-rs/embassy/pull/4705)) |
| 18 | - Add fix #4822 in PIO onewire. Change to disable the state machine before setting y register ([#4824](https://github.com/embassy-rs/embassy/pull/4824)) | ||
| 19 | - Add PIO::Ws2812 color order support | ||
| 17 | 20 | ||
| 18 | ## 0.8.0 - 2025-08-26 | 21 | ## 0.8.0 - 2025-08-26 |
| 19 | 22 | ||
diff --git a/embassy-rp/src/block.rs b/embassy-rp/src/block.rs index a3e1ad925..745883b83 100644 --- a/embassy-rp/src/block.rs +++ b/embassy-rp/src/block.rs | |||
| @@ -240,7 +240,7 @@ impl UnpartitionedSpace { | |||
| 240 | } | 240 | } |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | /// Create a new unpartition space from run-time values. | 243 | /// Create a new unpartitioned space from run-time values. |
| 244 | /// | 244 | /// |
| 245 | /// Get these from the ROM function `get_partition_table_info` with an argument of `PT_INFO`. | 245 | /// Get these from the ROM function `get_partition_table_info` with an argument of `PT_INFO`. |
| 246 | pub const fn from_raw(permissions_and_location: u32, permissions_and_flags: u32) -> Self { | 246 | pub const fn from_raw(permissions_and_location: u32, permissions_and_flags: u32) -> Self { |
| @@ -714,7 +714,7 @@ impl PartitionTableBlock { | |||
| 714 | new_table | 714 | new_table |
| 715 | } | 715 | } |
| 716 | 716 | ||
| 717 | /// Add a a SHA256 hash of the Block | 717 | /// Add a SHA256 hash of the Block |
| 718 | /// | 718 | /// |
| 719 | /// Adds a `HASH_DEF` covering all the previous items in the Block, and a | 719 | /// Adds a `HASH_DEF` covering all the previous items in the Block, and a |
| 720 | /// `HASH_VALUE` with a SHA-256 hash of them. | 720 | /// `HASH_VALUE` with a SHA-256 hash of them. |
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 56892d7a2..8bfb5129a 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs | |||
| @@ -267,7 +267,7 @@ impl CoreVoltage { | |||
| 267 | } | 267 | } |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | /// CLock configuration. | 270 | /// Clock configuration. |
| 271 | #[non_exhaustive] | 271 | #[non_exhaustive] |
| 272 | pub struct ClockConfig { | 272 | pub struct ClockConfig { |
| 273 | /// Ring oscillator configuration. | 273 | /// Ring oscillator configuration. |
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index c15e0e41b..154fc1585 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs | |||
| @@ -300,7 +300,7 @@ impl<'d> InputFuture<'d> { | |||
| 300 | 300 | ||
| 301 | // Each INTR register is divided into 8 groups, one group for each | 301 | // Each INTR register is divided into 8 groups, one group for each |
| 302 | // pin, and each group consists of LEVEL_LOW, LEVEL_HIGH, EDGE_LOW, | 302 | // pin, and each group consists of LEVEL_LOW, LEVEL_HIGH, EDGE_LOW, |
| 303 | // and EGDE_HIGH. | 303 | // and EDGE_HIGH. |
| 304 | pin.int_proc() | 304 | pin.int_proc() |
| 305 | .inte((pin.pin() / 8) as usize) | 305 | .inte((pin.pin() / 8) as usize) |
| 306 | .write_set(|w| match level { | 306 | .write_set(|w| match level { |
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index 770087bc8..0853709df 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs | |||
| @@ -52,7 +52,7 @@ pub enum ReadStatus { | |||
| 52 | Done, | 52 | Done, |
| 53 | /// Transaction Incomplete, controller trying to read more bytes than were provided | 53 | /// Transaction Incomplete, controller trying to read more bytes than were provided |
| 54 | NeedMoreBytes, | 54 | NeedMoreBytes, |
| 55 | /// Transaction Complere, but controller stopped reading bytes before we ran out | 55 | /// Transaction Complete, but controller stopped reading bytes before we ran out |
| 56 | LeftoverBytes(u16), | 56 | LeftoverBytes(u16), |
| 57 | } | 57 | } |
| 58 | 58 | ||
| @@ -240,7 +240,7 @@ impl<'d, T: Instance> I2cSlave<'d, T> { | |||
| 240 | 240 | ||
| 241 | if p.ic_rxflr().read().rxflr() > 0 || me.pending_byte.is_some() { | 241 | if p.ic_rxflr().read().rxflr() > 0 || me.pending_byte.is_some() { |
| 242 | me.drain_fifo(buffer, &mut len); | 242 | me.drain_fifo(buffer, &mut len); |
| 243 | // we're recieving data, set rx fifo watermark to 12 bytes (3/4 full) to reduce interrupt noise | 243 | // we're receiving data, set rx fifo watermark to 12 bytes (3/4 full) to reduce interrupt noise |
| 244 | p.ic_rx_tl().write(|w| w.set_rx_tl(11)); | 244 | p.ic_rx_tl().write(|w| w.set_rx_tl(11)); |
| 245 | } | 245 | } |
| 246 | 246 | ||
diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs index 3b120e349..572d8db91 100644 --- a/embassy-rp/src/multicore.rs +++ b/embassy-rp/src/multicore.rs | |||
| @@ -58,7 +58,7 @@ const PAUSE_TOKEN: u32 = 0xDEADBEEF; | |||
| 58 | const RESUME_TOKEN: u32 = !0xDEADBEEF; | 58 | const RESUME_TOKEN: u32 = !0xDEADBEEF; |
| 59 | static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false); | 59 | static IS_CORE1_INIT: AtomicBool = AtomicBool::new(false); |
| 60 | 60 | ||
| 61 | /// Represents a partiticular CPU core (SIO_CPUID) | 61 | /// Represents a particular CPU core (SIO_CPUID) |
| 62 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] | 62 | #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] |
| 63 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 63 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 64 | #[repr(u8)] | 64 | #[repr(u8)] |
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs index 38ee1f97c..92b2c603e 100644 --- a/embassy-rp/src/pio/mod.rs +++ b/embassy-rp/src/pio/mod.rs | |||
| @@ -62,7 +62,7 @@ pub enum FifoJoin { | |||
| 62 | #[cfg(feature = "_rp235x")] | 62 | #[cfg(feature = "_rp235x")] |
| 63 | RxAsControl, | 63 | RxAsControl, |
| 64 | /// FJOIN_RX_PUT | FJOIN_RX_GET: RX can be used as a scratch register, | 64 | /// FJOIN_RX_PUT | FJOIN_RX_GET: RX can be used as a scratch register, |
| 65 | /// not accesible from the CPU | 65 | /// not accessible from the CPU |
| 66 | #[cfg(feature = "_rp235x")] | 66 | #[cfg(feature = "_rp235x")] |
| 67 | PioScratch, | 67 | PioScratch, |
| 68 | } | 68 | } |
diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs index 7e5f68ad6..5c49beecb 100644 --- a/embassy-rp/src/pio_programs/i2s.rs +++ b/embassy-rp/src/pio_programs/i2s.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | //! Pio backed I2s output and output drivers | 1 | //! Pio backed I2S output and output drivers |
| 2 | 2 | ||
| 3 | use fixed::traits::ToFixed; | 3 | use fixed::traits::ToFixed; |
| 4 | 4 | ||
| @@ -9,7 +9,7 @@ use crate::pio::{ | |||
| 9 | Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, | 9 | Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, |
| 10 | }; | 10 | }; |
| 11 | 11 | ||
| 12 | /// This struct represents an i2s receiver & controller driver program | 12 | /// This struct represents an I2S receiver & controller driver program |
| 13 | pub struct PioI2sInProgram<'d, PIO: Instance> { | 13 | pub struct PioI2sInProgram<'d, PIO: Instance> { |
| 14 | prg: LoadedProgram<'d, PIO>, | 14 | prg: LoadedProgram<'d, PIO>, |
| 15 | } | 15 | } |
| @@ -35,7 +35,7 @@ impl<'d, PIO: Instance> PioI2sInProgram<'d, PIO> { | |||
| 35 | } | 35 | } |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | /// Pio backed I2s input driver | 38 | /// Pio backed I2S input driver |
| 39 | pub struct PioI2sIn<'d, P: Instance, const S: usize> { | 39 | pub struct PioI2sIn<'d, P: Instance, const S: usize> { |
| 40 | dma: Peri<'d, AnyChannel>, | 40 | dma: Peri<'d, AnyChannel>, |
| 41 | sm: StateMachine<'d, P, S>, | 41 | sm: StateMachine<'d, P, S>, |
| @@ -50,7 +50,7 @@ impl<'d, P: Instance, const S: usize> PioI2sIn<'d, P, S> { | |||
| 50 | // Whether or not to use the MCU's internal pull-down resistor, as the | 50 | // Whether or not to use the MCU's internal pull-down resistor, as the |
| 51 | // Pico 2 is known to have problems with the inbuilt pulldowns, many | 51 | // Pico 2 is known to have problems with the inbuilt pulldowns, many |
| 52 | // opt to just use an external pull down resistor to meet requirements of common | 52 | // opt to just use an external pull down resistor to meet requirements of common |
| 53 | // i2s microphones such as the INMP441 | 53 | // I2S microphones such as the INMP441 |
| 54 | data_pulldown: bool, | 54 | data_pulldown: bool, |
| 55 | data_pin: Peri<'d, impl PioPin>, | 55 | data_pin: Peri<'d, impl PioPin>, |
| 56 | bit_clock_pin: Peri<'d, impl PioPin>, | 56 | bit_clock_pin: Peri<'d, impl PioPin>, |
| @@ -90,13 +90,13 @@ impl<'d, P: Instance, const S: usize> PioI2sIn<'d, P, S> { | |||
| 90 | Self { dma: dma.into(), sm } | 90 | Self { dma: dma.into(), sm } |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer. | 93 | /// Return an in-progress dma transfer future. Awaiting it will guarantee a complete transfer. |
| 94 | pub fn read<'b>(&'b mut self, buff: &'b mut [u32]) -> Transfer<'b, AnyChannel> { | 94 | pub fn read<'b>(&'b mut self, buff: &'b mut [u32]) -> Transfer<'b, AnyChannel> { |
| 95 | self.sm.rx().dma_pull(self.dma.reborrow(), buff, false) | 95 | self.sm.rx().dma_pull(self.dma.reborrow(), buff, false) |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | /// This struct represents an i2s output driver program | 99 | /// This struct represents an I2S output driver program |
| 100 | /// | 100 | /// |
| 101 | /// The sample bit-depth is set through scratch register `Y`. | 101 | /// The sample bit-depth is set through scratch register `Y`. |
| 102 | /// `Y` has to be set to sample bit-depth - 2. | 102 | /// `Y` has to be set to sample bit-depth - 2. |
| @@ -128,14 +128,14 @@ impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> { | |||
| 128 | } | 128 | } |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | /// Pio backed I2s output driver | 131 | /// Pio backed I2S output driver |
| 132 | pub struct PioI2sOut<'d, P: Instance, const S: usize> { | 132 | pub struct PioI2sOut<'d, P: Instance, const S: usize> { |
| 133 | dma: Peri<'d, AnyChannel>, | 133 | dma: Peri<'d, AnyChannel>, |
| 134 | sm: StateMachine<'d, P, S>, | 134 | sm: StateMachine<'d, P, S>, |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { | 137 | impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { |
| 138 | /// Configure a state machine to output I2s | 138 | /// Configure a state machine to output I2S |
| 139 | pub fn new( | 139 | pub fn new( |
| 140 | common: &mut Common<'d, P>, | 140 | common: &mut Common<'d, P>, |
| 141 | mut sm: StateMachine<'d, P, S>, | 141 | mut sm: StateMachine<'d, P, S>, |
| @@ -179,7 +179,7 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { | |||
| 179 | Self { dma: dma.into(), sm } | 179 | Self { dma: dma.into(), sm } |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer. | 182 | /// Return an in-progress dma transfer future. Awaiting it will guarantee a complete transfer. |
| 183 | pub fn write<'b>(&'b mut self, buff: &'b [u32]) -> Transfer<'b, AnyChannel> { | 183 | pub fn write<'b>(&'b mut self, buff: &'b [u32]) -> Transfer<'b, AnyChannel> { |
| 184 | self.sm.tx().dma_push(self.dma.reborrow(), buff, false) | 184 | self.sm.tx().dma_push(self.dma.reborrow(), buff, false) |
| 185 | } | 185 | } |
diff --git a/embassy-rp/src/pio_programs/onewire.rs b/embassy-rp/src/pio_programs/onewire.rs index 09babc229..3adab3b79 100644 --- a/embassy-rp/src/pio_programs/onewire.rs +++ b/embassy-rp/src/pio_programs/onewire.rs | |||
| @@ -163,7 +163,11 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> { | |||
| 163 | 163 | ||
| 164 | /// Write bytes to the onewire bus | 164 | /// Write bytes to the onewire bus |
| 165 | pub async fn write_bytes(&mut self, data: &[u8]) { | 165 | pub async fn write_bytes(&mut self, data: &[u8]) { |
| 166 | unsafe { self.sm.set_y(u32::MAX as u32) }; | 166 | unsafe { |
| 167 | self.sm.set_enable(false); | ||
| 168 | self.sm.set_y(u32::MAX as u32); | ||
| 169 | self.sm.set_enable(true); | ||
| 170 | } | ||
| 167 | let (rx, tx) = self.sm.rx_tx(); | 171 | let (rx, tx) = self.sm.rx_tx(); |
| 168 | for b in data { | 172 | for b in data { |
| 169 | tx.wait_push(*b as u32).await; | 173 | tx.wait_push(*b as u32).await; |
| @@ -175,7 +179,11 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> { | |||
| 175 | 179 | ||
| 176 | /// Write bytes to the onewire bus, then apply a strong pullup | 180 | /// Write bytes to the onewire bus, then apply a strong pullup |
| 177 | pub async fn write_bytes_pullup(&mut self, data: &[u8], pullup_time: embassy_time::Duration) { | 181 | pub async fn write_bytes_pullup(&mut self, data: &[u8], pullup_time: embassy_time::Duration) { |
| 178 | unsafe { self.sm.set_y(data.len() as u32 * 8 - 1) }; | 182 | unsafe { |
| 183 | self.sm.set_enable(false); | ||
| 184 | self.sm.set_y(data.len() as u32 * 8 - 1); | ||
| 185 | self.sm.set_enable(true); | ||
| 186 | }; | ||
| 179 | let (rx, tx) = self.sm.rx_tx(); | 187 | let (rx, tx) = self.sm.rx_tx(); |
| 180 | for b in data { | 188 | for b in data { |
| 181 | tx.wait_push(*b as u32).await; | 189 | tx.wait_push(*b as u32).await; |
| @@ -195,7 +203,11 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> { | |||
| 195 | 203 | ||
| 196 | /// Read bytes from the onewire bus | 204 | /// Read bytes from the onewire bus |
| 197 | pub async fn read_bytes(&mut self, data: &mut [u8]) { | 205 | pub async fn read_bytes(&mut self, data: &mut [u8]) { |
| 198 | unsafe { self.sm.set_y(u32::MAX as u32) }; | 206 | unsafe { |
| 207 | self.sm.set_enable(false); | ||
| 208 | self.sm.set_y(u32::MAX as u32); | ||
| 209 | self.sm.set_enable(true); | ||
| 210 | }; | ||
| 199 | let (rx, tx) = self.sm.rx_tx(); | 211 | let (rx, tx) = self.sm.rx_tx(); |
| 200 | for b in data { | 212 | for b in data { |
| 201 | // Write all 1's so that we can read what the device responds | 213 | // Write all 1's so that we can read what the device responds |
diff --git a/embassy-rp/src/pio_programs/pwm.rs b/embassy-rp/src/pio_programs/pwm.rs index ba06bb3c1..e4ad4a6f0 100644 --- a/embassy-rp/src/pio_programs/pwm.rs +++ b/embassy-rp/src/pio_programs/pwm.rs | |||
| @@ -67,7 +67,7 @@ impl<'d, T: Instance, const SM: usize> PioPwm<'d, T, SM> { | |||
| 67 | Self { sm, pin } | 67 | Self { sm, pin } |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | /// Enable's the PIO program, continuing the wave generation from the PIO program. | 70 | /// Enables the PIO program, continuing the wave generation from the PIO program. |
| 71 | pub fn start(&mut self) { | 71 | pub fn start(&mut self) { |
| 72 | self.sm.set_enable(true); | 72 | self.sm.set_enable(true); |
| 73 | } | 73 | } |
diff --git a/embassy-rp/src/pio_programs/spi.rs b/embassy-rp/src/pio_programs/spi.rs index b10fc6628..765ffaa06 100644 --- a/embassy-rp/src/pio_programs/spi.rs +++ b/embassy-rp/src/pio_programs/spi.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | //! PIO backed SPi drivers | 1 | //! PIO backed SPI drivers |
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | 4 | ||
| @@ -83,7 +83,7 @@ pub enum Error { | |||
| 83 | // No errors for now | 83 | // No errors for now |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /// PIO based Spi driver. | 86 | /// PIO based SPI driver. |
| 87 | /// Unlike other PIO programs, the PIO SPI driver owns and holds a reference to | 87 | /// Unlike other PIO programs, the PIO SPI driver owns and holds a reference to |
| 88 | /// the PIO memory it uses. This is so that it can be reconfigured at runtime if | 88 | /// the PIO memory it uses. This is so that it can be reconfigured at runtime if |
| 89 | /// desired. | 89 | /// desired. |
diff --git a/embassy-rp/src/pio_programs/uart.rs b/embassy-rp/src/pio_programs/uart.rs index 444efb5db..d59596dd1 100644 --- a/embassy-rp/src/pio_programs/uart.rs +++ b/embassy-rp/src/pio_programs/uart.rs | |||
| @@ -130,7 +130,7 @@ impl<'d, PIO: Instance> PioUartRxProgram<'d, PIO> { | |||
| 130 | } | 130 | } |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | /// PIO backed Uart reciever | 133 | /// PIO backed Uart receiver |
| 134 | pub struct PioUartRx<'d, PIO: Instance, const SM: usize> { | 134 | pub struct PioUartRx<'d, PIO: Instance, const SM: usize> { |
| 135 | sm_rx: StateMachine<'d, PIO, SM>, | 135 | sm_rx: StateMachine<'d, PIO, SM>, |
| 136 | } | 136 | } |
diff --git a/embassy-rp/src/pio_programs/ws2812.rs b/embassy-rp/src/pio_programs/ws2812.rs index e6851b1a6..0b6035316 100644 --- a/embassy-rp/src/pio_programs/ws2812.rs +++ b/embassy-rp/src/pio_programs/ws2812.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | //! [ws2812](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) | 1 | //! [ws2812](https://www.sparkfun.com/categories/tags/ws2812) |
| 2 | 2 | ||
| 3 | use embassy_time::Timer; | 3 | use embassy_time::Timer; |
| 4 | use fixed::types::U24F8; | 4 | use fixed::types::U24F8; |
| @@ -16,6 +16,54 @@ const T2: u8 = 5; // data bit | |||
| 16 | const T3: u8 = 3; // stop bit | 16 | const T3: u8 = 3; // stop bit |
| 17 | const CYCLES_PER_BIT: u32 = (T1 + T2 + T3) as u32; | 17 | const CYCLES_PER_BIT: u32 = (T1 + T2 + T3) as u32; |
| 18 | 18 | ||
| 19 | /// Color orders for WS2812B, type RGB8 | ||
| 20 | pub trait RgbColorOrder { | ||
| 21 | /// Pack an 8-bit RGB color into a u32 | ||
| 22 | fn pack(color: RGB8) -> u32; | ||
| 23 | } | ||
| 24 | |||
| 25 | /// Green, Red, Blue order is the common default for WS2812B | ||
| 26 | pub struct Grb; | ||
| 27 | impl RgbColorOrder for Grb { | ||
| 28 | /// Pack an 8-bit RGB color into a u32 in GRB order | ||
| 29 | fn pack(color: RGB8) -> u32 { | ||
| 30 | (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8) | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | /// Red, Green, Blue is used by some WS2812B implementations | ||
| 35 | pub struct Rgb; | ||
| 36 | impl RgbColorOrder for Rgb { | ||
| 37 | /// Pack an 8-bit RGB color into a u32 in RGB order | ||
| 38 | fn pack(color: RGB8) -> u32 { | ||
| 39 | (u32::from(color.r) << 24) | (u32::from(color.g) << 16) | (u32::from(color.b) << 8) | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | /// Color orders RGBW strips | ||
| 44 | pub trait RgbwColorOrder { | ||
| 45 | /// Pack an RGB+W color into a u32 | ||
| 46 | fn pack(color: RGBW<u8>) -> u32; | ||
| 47 | } | ||
| 48 | |||
| 49 | /// Green, Red, Blue, White order is the common default for RGBW strips | ||
| 50 | pub struct Grbw; | ||
| 51 | impl RgbwColorOrder for Grbw { | ||
| 52 | /// Pack an RGB+W color into a u32 in GRBW order | ||
| 53 | fn pack(color: RGBW<u8>) -> u32 { | ||
| 54 | (u32::from(color.g) << 24) | (u32::from(color.r) << 16) | (u32::from(color.b) << 8) | u32::from(color.a.0) | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | /// Red, Green, Blue, White order | ||
| 59 | pub struct Rgbw; | ||
| 60 | impl RgbwColorOrder for Rgbw { | ||
| 61 | /// Pack an RGB+W color into a u32 in RGBW order | ||
| 62 | fn pack(color: RGBW<u8>) -> u32 { | ||
| 63 | (u32::from(color.r) << 24) | (u32::from(color.g) << 16) | (u32::from(color.b) << 8) | u32::from(color.a.0) | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 19 | /// This struct represents a ws2812 program loaded into pio instruction memory. | 67 | /// This struct represents a ws2812 program loaded into pio instruction memory. |
| 20 | pub struct PioWs2812Program<'a, PIO: Instance> { | 68 | pub struct PioWs2812Program<'a, PIO: Instance> { |
| 21 | prg: LoadedProgram<'a, PIO>, | 69 | prg: LoadedProgram<'a, PIO>, |
| @@ -52,15 +100,37 @@ impl<'a, PIO: Instance> PioWs2812Program<'a, PIO> { | |||
| 52 | 100 | ||
| 53 | /// Pio backed RGB ws2812 driver | 101 | /// Pio backed RGB ws2812 driver |
| 54 | /// Const N is the number of ws2812 leds attached to this pin | 102 | /// Const N is the number of ws2812 leds attached to this pin |
| 55 | pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> { | 103 | pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize, ORDER> |
| 104 | where | ||
| 105 | ORDER: RgbColorOrder, | ||
| 106 | { | ||
| 56 | dma: Peri<'d, AnyChannel>, | 107 | dma: Peri<'d, AnyChannel>, |
| 57 | sm: StateMachine<'d, P, S>, | 108 | sm: StateMachine<'d, P, S>, |
| 109 | _order: core::marker::PhantomData<ORDER>, | ||
| 58 | } | 110 | } |
| 59 | 111 | ||
| 60 | impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> { | 112 | impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N, Grb> { |
| 61 | /// Configure a pio state machine to use the loaded ws2812 program. | 113 | /// Configure a pio state machine to use the loaded ws2812 program. |
| 114 | /// Uses the default GRB order. | ||
| 62 | pub fn new( | 115 | pub fn new( |
| 63 | pio: &mut Common<'d, P>, | 116 | pio: &mut Common<'d, P>, |
| 117 | sm: StateMachine<'d, P, S>, | ||
| 118 | dma: Peri<'d, impl Channel>, | ||
| 119 | pin: Peri<'d, impl PioPin>, | ||
| 120 | program: &PioWs2812Program<'d, P>, | ||
| 121 | ) -> Self { | ||
| 122 | Self::with_color_order(pio, sm, dma, pin, program) | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | impl<'d, P: Instance, const S: usize, const N: usize, ORDER> PioWs2812<'d, P, S, N, ORDER> | ||
| 127 | where | ||
| 128 | ORDER: RgbColorOrder, | ||
| 129 | { | ||
| 130 | /// Configure a pio state machine to use the loaded ws2812 program. | ||
| 131 | /// Uses the specified color order. | ||
| 132 | pub fn with_color_order( | ||
| 133 | pio: &mut Common<'d, P>, | ||
| 64 | mut sm: StateMachine<'d, P, S>, | 134 | mut sm: StateMachine<'d, P, S>, |
| 65 | dma: Peri<'d, impl Channel>, | 135 | dma: Peri<'d, impl Channel>, |
| 66 | pin: Peri<'d, impl PioPin>, | 136 | pin: Peri<'d, impl PioPin>, |
| @@ -93,7 +163,11 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> { | |||
| 93 | sm.set_config(&cfg); | 163 | sm.set_config(&cfg); |
| 94 | sm.set_enable(true); | 164 | sm.set_enable(true); |
| 95 | 165 | ||
| 96 | Self { dma: dma.into(), sm } | 166 | Self { |
| 167 | dma: dma.into(), | ||
| 168 | sm, | ||
| 169 | _order: core::marker::PhantomData, | ||
| 170 | } | ||
| 97 | } | 171 | } |
| 98 | 172 | ||
| 99 | /// Write a buffer of [smart_leds::RGB8] to the ws2812 string | 173 | /// Write a buffer of [smart_leds::RGB8] to the ws2812 string |
| @@ -101,8 +175,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> { | |||
| 101 | // Precompute the word bytes from the colors | 175 | // Precompute the word bytes from the colors |
| 102 | let mut words = [0u32; N]; | 176 | let mut words = [0u32; N]; |
| 103 | for i in 0..N { | 177 | for i in 0..N { |
| 104 | let word = (u32::from(colors[i].g) << 24) | (u32::from(colors[i].r) << 16) | (u32::from(colors[i].b) << 8); | 178 | words[i] = ORDER::pack(colors[i]); |
| 105 | words[i] = word; | ||
| 106 | } | 179 | } |
| 107 | 180 | ||
| 108 | // DMA transfer | 181 | // DMA transfer |
| @@ -115,15 +188,37 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> { | |||
| 115 | /// Pio backed RGBW ws2812 driver | 188 | /// Pio backed RGBW ws2812 driver |
| 116 | /// This version is intended for ws2812 leds with 4 addressable lights | 189 | /// This version is intended for ws2812 leds with 4 addressable lights |
| 117 | /// Const N is the number of ws2812 leds attached to this pin | 190 | /// Const N is the number of ws2812 leds attached to this pin |
| 118 | pub struct RgbwPioWs2812<'d, P: Instance, const S: usize, const N: usize> { | 191 | pub struct RgbwPioWs2812<'d, P: Instance, const S: usize, const N: usize, ORDER> |
| 192 | where | ||
| 193 | ORDER: RgbwColorOrder, | ||
| 194 | { | ||
| 119 | dma: Peri<'d, AnyChannel>, | 195 | dma: Peri<'d, AnyChannel>, |
| 120 | sm: StateMachine<'d, P, S>, | 196 | sm: StateMachine<'d, P, S>, |
| 197 | _order: core::marker::PhantomData<ORDER>, | ||
| 121 | } | 198 | } |
| 122 | 199 | ||
| 123 | impl<'d, P: Instance, const S: usize, const N: usize> RgbwPioWs2812<'d, P, S, N> { | 200 | impl<'d, P: Instance, const S: usize, const N: usize> RgbwPioWs2812<'d, P, S, N, Grbw> { |
| 124 | /// Configure a pio state machine to use the loaded ws2812 program. | 201 | /// Configure a pio state machine to use the loaded ws2812 program. |
| 202 | /// Uses the default GRBW color order | ||
| 125 | pub fn new( | 203 | pub fn new( |
| 126 | pio: &mut Common<'d, P>, | 204 | pio: &mut Common<'d, P>, |
| 205 | sm: StateMachine<'d, P, S>, | ||
| 206 | dma: Peri<'d, impl Channel>, | ||
| 207 | pin: Peri<'d, impl PioPin>, | ||
| 208 | program: &PioWs2812Program<'d, P>, | ||
| 209 | ) -> Self { | ||
| 210 | Self::with_color_order(pio, sm, dma, pin, program) | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | impl<'d, P: Instance, const S: usize, const N: usize, ORDER> RgbwPioWs2812<'d, P, S, N, ORDER> | ||
| 215 | where | ||
| 216 | ORDER: RgbwColorOrder, | ||
| 217 | { | ||
| 218 | /// Configure a pio state machine to use the loaded ws2812 program. | ||
| 219 | /// Uses the specified color order | ||
| 220 | pub fn with_color_order( | ||
| 221 | pio: &mut Common<'d, P>, | ||
| 127 | mut sm: StateMachine<'d, P, S>, | 222 | mut sm: StateMachine<'d, P, S>, |
| 128 | dma: Peri<'d, impl Channel>, | 223 | dma: Peri<'d, impl Channel>, |
| 129 | pin: Peri<'d, impl PioPin>, | 224 | pin: Peri<'d, impl PioPin>, |
| @@ -156,7 +251,11 @@ impl<'d, P: Instance, const S: usize, const N: usize> RgbwPioWs2812<'d, P, S, N> | |||
| 156 | sm.set_config(&cfg); | 251 | sm.set_config(&cfg); |
| 157 | sm.set_enable(true); | 252 | sm.set_enable(true); |
| 158 | 253 | ||
| 159 | Self { dma: dma.into(), sm } | 254 | Self { |
| 255 | dma: dma.into(), | ||
| 256 | sm, | ||
| 257 | _order: core::marker::PhantomData, | ||
| 258 | } | ||
| 160 | } | 259 | } |
| 161 | 260 | ||
| 162 | /// Write a buffer of [smart_leds::RGBW] to the ws2812 string | 261 | /// Write a buffer of [smart_leds::RGBW] to the ws2812 string |
| @@ -164,11 +263,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> RgbwPioWs2812<'d, P, S, N> | |||
| 164 | // Precompute the word bytes from the colors | 263 | // Precompute the word bytes from the colors |
| 165 | let mut words = [0u32; N]; | 264 | let mut words = [0u32; N]; |
| 166 | for i in 0..N { | 265 | for i in 0..N { |
| 167 | let word = (u32::from(colors[i].g) << 24) | 266 | words[i] = ORDER::pack(colors[i]); |
| 168 | | (u32::from(colors[i].r) << 16) | ||
| 169 | | (u32::from(colors[i].b) << 8) | ||
| 170 | | u32::from(colors[i].a.0); | ||
| 171 | words[i] = word; | ||
| 172 | } | 267 | } |
| 173 | 268 | ||
| 174 | // DMA transfer | 269 | // DMA transfer |
diff --git a/embassy-rp/src/rom_data/rp2040.rs b/embassy-rp/src/rom_data/rp2040.rs index 5a74eddd6..27a8d8981 100644 --- a/embassy-rp/src/rom_data/rp2040.rs +++ b/embassy-rp/src/rom_data/rp2040.rs | |||
| @@ -30,7 +30,7 @@ const DATA_TABLE: *const u16 = 0x0000_0016 as _; | |||
| 30 | /// Address of the version number of the ROM. | 30 | /// Address of the version number of the ROM. |
| 31 | const VERSION_NUMBER: *const u8 = 0x0000_0013 as _; | 31 | const VERSION_NUMBER: *const u8 = 0x0000_0013 as _; |
| 32 | 32 | ||
| 33 | /// Retrive rom content from a table using a code. | 33 | /// Retrieve rom content from a table using a code. |
| 34 | fn rom_table_lookup<T>(table: *const u16, tag: RomFnTableCode) -> T { | 34 | fn rom_table_lookup<T>(table: *const u16, tag: RomFnTableCode) -> T { |
| 35 | unsafe { | 35 | unsafe { |
| 36 | let rom_table_lookup_ptr: *const u32 = rom_hword_as_ptr(ROM_TABLE_LOOKUP_PTR); | 36 | let rom_table_lookup_ptr: *const u32 = rom_hword_as_ptr(ROM_TABLE_LOOKUP_PTR); |
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs index 68fb3b765..054572903 100644 --- a/embassy-rp/src/rtc/mod.rs +++ b/embassy-rp/src/rtc/mod.rs | |||
| @@ -47,7 +47,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 47 | Self { inner } | 47 | Self { inner } |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | /// Enable or disable the leap year check. The rp2040 chip will always add a Feb 29th on every year that is divisable by 4, but this may be incorrect (e.g. on century years). This function allows you to disable this check. | 50 | /// Enable or disable the leap year check. The rp2040 chip will always add a Feb 29th on every year that is divisible by 4, but this may be incorrect (e.g. on century years). This function allows you to disable this check. |
| 51 | /// | 51 | /// |
| 52 | /// Leap year checking is enabled by default. | 52 | /// Leap year checking is enabled by default. |
| 53 | pub fn set_leap_year_check(&mut self, leap_year_check_enabled: bool) { | 53 | pub fn set_leap_year_check(&mut self, leap_year_check_enabled: bool) { |
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 559b3b909..d9410e78d 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs | |||
| @@ -157,7 +157,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 157 | 157 | ||
| 158 | /// Private function to apply SPI configuration (phase, polarity, frequency) settings. | 158 | /// Private function to apply SPI configuration (phase, polarity, frequency) settings. |
| 159 | /// | 159 | /// |
| 160 | /// Driver should be disabled before making changes and reenabled after the modifications | 160 | /// Driver should be disabled before making changes and re-enabled after the modifications |
| 161 | /// are applied. | 161 | /// are applied. |
| 162 | fn apply_config(inner: &Peri<'d, T>, config: &Config) { | 162 | fn apply_config(inner: &Peri<'d, T>, config: &Config) { |
| 163 | let p = inner.regs(); | 163 | let p = inner.regs(); |
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 43187df2d..8be87a5d2 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs | |||
| @@ -315,7 +315,7 @@ impl<'d, M: Mode> UartRx<'d, M> { | |||
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | /// Returns Ok(len) if no errors occurred. Returns Err((len, err)) if an error was | 317 | /// Returns Ok(len) if no errors occurred. Returns Err((len, err)) if an error was |
| 318 | /// encountered. in both cases, `len` is the number of *good* bytes copied into | 318 | /// encountered. In both cases, `len` is the number of *good* bytes copied into |
| 319 | /// `buffer`. | 319 | /// `buffer`. |
| 320 | fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, (usize, Error)> { | 320 | fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, (usize, Error)> { |
| 321 | let r = self.info.regs; | 321 | let r = self.info.regs; |
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index a6ee5c4b8..f85fd82ef 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -5,9 +5,13 @@ All notable changes to this project will be documented in this file. | |||
| 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), |
| 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 7 | 7 | ||
| 8 | <!-- next-header --> | ||
| 9 | ## Unreleased - ReleaseDate | 8 | ## Unreleased - ReleaseDate |
| 10 | 9 | ||
| 10 | - feat: Add support for injected ADC measurements for g4 ([#4840](https://github.com/embassy-rs/embassy/pull/4840)) | ||
| 11 | - feat: Implement into_ring_buffered for g4 ([#4840](https://github.com/embassy-rs/embassy/pull/4840)) | ||
| 12 | - feat: Add support for 13-bit address and 16-bit data SDRAM chips | ||
| 13 | - feat: stm32/hrtim add new_chx_with_config to provide pin configuration | ||
| 14 | - fix flash erase on L4 & L5 | ||
| 11 | - fix: Fixed STM32H5 builds requiring time feature | 15 | - fix: Fixed STM32H5 builds requiring time feature |
| 12 | - feat: Derive Clone, Copy for QSPI Config | 16 | - feat: Derive Clone, Copy for QSPI Config |
| 13 | - fix: stm32/i2c in master mode (blocking): subsequent transmissions failed after a NACK was received | 17 | - fix: stm32/i2c in master mode (blocking): subsequent transmissions failed after a NACK was received |
| @@ -31,10 +35,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 31 | - feat: stm32/usart: add `eager_reads` option to control if buffered readers return as soon as possible or after more data is available ([#4668](https://github.com/embassy-rs/embassy/pull/4668)) | 35 | - feat: stm32/usart: add `eager_reads` option to control if buffered readers return as soon as possible or after more data is available ([#4668](https://github.com/embassy-rs/embassy/pull/4668)) |
| 32 | - feat: stm32/usart: add `de_assertion_time` and `de_deassertion_time` config options | 36 | - feat: stm32/usart: add `de_assertion_time` and `de_deassertion_time` config options |
| 33 | - change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer | 37 | - change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer |
| 38 | - fix: Prevent a HardFault crash on STM32H5 devices by changing `uid()` to return `[u8; 12]` by value instead of a reference. (Fixes #2696) | ||
| 39 | - change: timer: added output compare values | ||
| 40 | - feat: timer: add ability to set master mode | ||
| 41 | - fix: sdmmc: don't wait for DBCKEND flag on sdmmc_v2 devices as it never fires (Fixes #4723) | ||
| 42 | - fix: usart: fix race condition in ringbuffered usart | ||
| 43 | - feat: Add backup_sram::init() for H5 devices to access BKPSRAM | ||
| 44 | - feat: Add I2C MultiMaster (Slave) support for I2C v1 | ||
| 45 | - feat: stm32/fdcan: add ability to control automatic recovery from bus off ([#4821](https://github.com/embassy-rs/embassy/pull/4821)) | ||
| 46 | - low-power: update rtc api to allow reconfig | ||
| 47 | - adc: consolidate ringbuffer | ||
| 48 | - feat: Added RTC low-power support for STM32WLEx ([#4716](https://github.com/embassy-rs/embassy/pull/4716)) | ||
| 49 | - fix: Correct STM32WBA VREFBUFTRIM values | ||
| 50 | - low_power: remove stop_with rtc and initialize in init if low-power feature enabled. | ||
| 51 | - feat: stm32/dsi support zero parameter commands in `write_cmd` ([#4847](https://github.com/embassy-rs/embassy/pull/4847)) | ||
| 52 | - feat: stm32/spi: added support for slave mode ([#4388](https://github.com/embassy-rs/embassy/pull/4388)) | ||
| 53 | - chore: Updated stm32-metapac and stm32-data dependencies | ||
| 34 | 54 | ||
| 35 | ## 0.4.0 - 2025-08-26 | 55 | ## 0.4.0 - 2025-08-26 |
| 36 | 56 | ||
| 37 | - feat: stm32/sai: make NODIV independent of MCKDIV | 57 | - feat: stm32/sai: make NODIV independent of MCKDIV |
| 38 | - fix: stm32/sai: fix WB MCKDIV | 58 | - fix: stm32/sai: fix WB MCKDIV |
| 39 | - fix: stm32/i2c: pull-down was enabled instead of pull-none when no internal pull-up was needed. | 59 | - fix: stm32/i2c: pull-down was enabled instead of pull-none when no internal pull-up was needed. |
| 40 | - feat: Improve blocking hash speed | 60 | - feat: Improve blocking hash speed |
| @@ -43,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 43 | - chore: Updated stm32-metapac and stm32-data dependencies | 63 | - chore: Updated stm32-metapac and stm32-data dependencies |
| 44 | - feat: stm32/adc/v3: allow DMA reads to loop through enable channels | 64 | - feat: stm32/adc/v3: allow DMA reads to loop through enable channels |
| 45 | - fix: Fix XSPI not disabling alternate bytes when they were previously enabled | 65 | - fix: Fix XSPI not disabling alternate bytes when they were previously enabled |
| 66 | - feat: stm32/adc/v3: added support for Continuous DMA configuration | ||
| 46 | - fix: Fix stm32h7rs init when using external flash via XSPI | 67 | - fix: Fix stm32h7rs init when using external flash via XSPI |
| 47 | - feat: Add Adc::new_with_clock() to configure analog clock | 68 | - feat: Add Adc::new_with_clock() to configure analog clock |
| 48 | - feat: Add GPDMA linked-list + ringbuffer support ([#3923](https://github.com/embassy-rs/embassy/pull/3923)) | 69 | - feat: Add GPDMA linked-list + ringbuffer support ([#3923](https://github.com/embassy-rs/embassy/pull/3923)) |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 7c243b350..108321d0a 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -177,12 +177,10 @@ cortex-m = "0.7.6" | |||
| 177 | futures-util = { version = "0.3.30", default-features = false } | 177 | futures-util = { version = "0.3.30", default-features = false } |
| 178 | sdio-host = "0.9.0" | 178 | sdio-host = "0.9.0" |
| 179 | critical-section = "1.1" | 179 | critical-section = "1.1" |
| 180 | #stm32-metapac = { version = "18" } | ||
| 181 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-b9f6b0c542d85ee695d71c35ced195e0cef51ac0" } | ||
| 182 | 180 | ||
| 183 | vcell = "0.1.3" | 181 | vcell = "0.1.3" |
| 184 | nb = "1.0.0" | 182 | nb = "1.0.0" |
| 185 | stm32-fmc = "0.3.0" | 183 | stm32-fmc = "0.4.0" |
| 186 | cfg-if = "1.0.0" | 184 | cfg-if = "1.0.0" |
| 187 | embedded-io = { version = "0.6.0" } | 185 | embedded-io = { version = "0.6.0" } |
| 188 | embedded-io-async = { version = "0.6.1" } | 186 | embedded-io-async = { version = "0.6.1" } |
| @@ -198,17 +196,23 @@ block-device-driver = { version = "0.2" } | |||
| 198 | aligned = "0.4.1" | 196 | aligned = "0.4.1" |
| 199 | heapless = "0.9.1" | 197 | heapless = "0.9.1" |
| 200 | 198 | ||
| 199 | #stm32-metapac = { version = "18" } | ||
| 200 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-22374e3344a2c9150b9b3d4da45c03f398fdc54e" } | ||
| 201 | |||
| 202 | [build-dependencies] | ||
| 203 | #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} | ||
| 204 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-22374e3344a2c9150b9b3d4da45c03f398fdc54e", default-features = false, features = ["metadata"] } | ||
| 205 | |||
| 206 | proc-macro2 = "1.0.36" | ||
| 207 | quote = "1.0.15" | ||
| 208 | |||
| 209 | |||
| 201 | [dev-dependencies] | 210 | [dev-dependencies] |
| 202 | critical-section = { version = "1.1", features = ["std"] } | 211 | critical-section = { version = "1.1", features = ["std"] } |
| 203 | proptest = "1.5.0" | 212 | proptest = "1.5.0" |
| 204 | proptest-state-machine = "0.3.0" | 213 | proptest-state-machine = "0.3.0" |
| 205 | 214 | ||
| 206 | [build-dependencies] | ||
| 207 | proc-macro2 = "1.0.36" | ||
| 208 | quote = "1.0.15" | ||
| 209 | 215 | ||
| 210 | #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} | ||
| 211 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-b9f6b0c542d85ee695d71c35ced195e0cef51ac0", default-features = false, features = ["metadata"] } | ||
| 212 | 216 | ||
| 213 | [features] | 217 | [features] |
| 214 | default = ["rt"] | 218 | default = ["rt"] |
| @@ -313,6 +317,7 @@ single-bank = [] | |||
| 313 | 317 | ||
| 314 | ## internal use only | 318 | ## internal use only |
| 315 | _split-pins-enabled = [] | 319 | _split-pins-enabled = [] |
| 320 | _allow-disable-rtc = [] | ||
| 316 | 321 | ||
| 317 | ## internal use only | 322 | ## internal use only |
| 318 | _dual-core = [] | 323 | _dual-core = [] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index eea1acf68..940e29417 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -114,6 +114,8 @@ fn main() { | |||
| 114 | } | 114 | } |
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | let has_bkpsram = memory.iter().any(|m| m.name == "BKPSRAM"); | ||
| 118 | |||
| 117 | // ======== | 119 | // ======== |
| 118 | // Generate singletons | 120 | // Generate singletons |
| 119 | 121 | ||
| @@ -124,6 +126,13 @@ fn main() { | |||
| 124 | singletons.push(p.name.to_string()); | 126 | singletons.push(p.name.to_string()); |
| 125 | } | 127 | } |
| 126 | 128 | ||
| 129 | cfgs.declare("backup_sram"); | ||
| 130 | |||
| 131 | if has_bkpsram { | ||
| 132 | singletons.push("BKPSRAM".to_string()); | ||
| 133 | cfgs.enable("backup_sram") | ||
| 134 | } | ||
| 135 | |||
| 127 | // generate one singleton per peripheral (with many exceptions...) | 136 | // generate one singleton per peripheral (with many exceptions...) |
| 128 | for p in METADATA.peripherals { | 137 | for p in METADATA.peripherals { |
| 129 | if let Some(r) = &p.registers { | 138 | if let Some(r) = &p.registers { |
| @@ -1985,6 +1994,18 @@ fn main() { | |||
| 1985 | )); | 1994 | )); |
| 1986 | 1995 | ||
| 1987 | // ======== | 1996 | // ======== |
| 1997 | // Generate backup sram constants | ||
| 1998 | if let Some(m) = memory.iter().find(|m| m.name == "BKPSRAM") { | ||
| 1999 | let bkpsram_base = m.address as usize; | ||
| 2000 | let bkpsram_size = m.size as usize; | ||
| 2001 | |||
| 2002 | g.extend(quote!( | ||
| 2003 | pub const BKPSRAM_BASE: usize = #bkpsram_base; | ||
| 2004 | pub const BKPSRAM_SIZE: usize = #bkpsram_size; | ||
| 2005 | )); | ||
| 2006 | } | ||
| 2007 | |||
| 2008 | // ======== | ||
| 1988 | // Generate flash constants | 2009 | // Generate flash constants |
| 1989 | 2010 | ||
| 1990 | let flash_regions: Vec<&MemoryRegion> = memory | 2011 | let flash_regions: Vec<&MemoryRegion> = memory |
| @@ -2311,6 +2332,10 @@ fn mem_filter(chip: &str, region: &str) -> bool { | |||
| 2311 | return false; | 2332 | return false; |
| 2312 | } | 2333 | } |
| 2313 | 2334 | ||
| 2335 | if region.starts_with("SDRAM_") || region.starts_with("FMC_") || region.starts_with("OCTOSPI_") { | ||
| 2336 | return false; | ||
| 2337 | } | ||
| 2338 | |||
| 2314 | true | 2339 | true |
| 2315 | } | 2340 | } |
| 2316 | 2341 | ||
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index 5098aadd8..3767820cf 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs | |||
| @@ -1,11 +1,14 @@ | |||
| 1 | use core::mem; | ||
| 2 | |||
| 1 | #[allow(unused)] | 3 | #[allow(unused)] |
| 2 | #[cfg(stm32h7)] | 4 | #[cfg(stm32h7)] |
| 3 | use pac::adc::vals::{Adcaldif, Difsel, Exten}; | 5 | use pac::adc::vals::{Adcaldif, Difsel, Exten}; |
| 4 | #[allow(unused)] | 6 | #[allow(unused)] |
| 5 | #[cfg(stm32g4)] | 7 | #[cfg(stm32g4)] |
| 6 | use pac::adc::vals::{Adcaldif, Difsel, Exten, Rovsm, Trovs}; | 8 | pub use pac::adc::vals::{Adcaldif, Difsel, Exten, Rovsm, Trovs}; |
| 7 | use pac::adccommon::vals::Presc; | 9 | pub use pac::adccommon::vals::Presc; |
| 8 | use stm32_metapac::adc::vals::{Adstp, Dmacfg, Dmaen}; | 10 | pub use stm32_metapac::adc::vals::{Adstp, Dmacfg, Dmaen}; |
| 11 | pub use stm32_metapac::adccommon::vals::Dual; | ||
| 9 | 12 | ||
| 10 | use super::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, blocking_delay_us}; | 13 | use super::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, blocking_delay_us}; |
| 11 | use crate::adc::SealedAdcChannel; | 14 | use crate::adc::SealedAdcChannel; |
| @@ -13,11 +16,19 @@ use crate::dma::Transfer; | |||
| 13 | use crate::time::Hertz; | 16 | use crate::time::Hertz; |
| 14 | use crate::{Peri, pac, rcc}; | 17 | use crate::{Peri, pac, rcc}; |
| 15 | 18 | ||
| 19 | mod ringbuffered; | ||
| 20 | pub use ringbuffered::RingBufferedAdc; | ||
| 21 | |||
| 22 | mod injected; | ||
| 23 | pub use injected::InjectedAdc; | ||
| 24 | |||
| 16 | /// Default VREF voltage used for sample conversion to millivolts. | 25 | /// Default VREF voltage used for sample conversion to millivolts. |
| 17 | pub const VREF_DEFAULT_MV: u32 = 3300; | 26 | pub const VREF_DEFAULT_MV: u32 = 3300; |
| 18 | /// VREF voltage used for factory calibration of VREFINTCAL register. | 27 | /// VREF voltage used for factory calibration of VREFINTCAL register. |
| 19 | pub const VREF_CALIB_MV: u32 = 3300; | 28 | pub const VREF_CALIB_MV: u32 = 3300; |
| 20 | 29 | ||
| 30 | const NR_INJECTED_RANKS: usize = 4; | ||
| 31 | |||
| 21 | /// Max single ADC operation clock frequency | 32 | /// Max single ADC operation clock frequency |
| 22 | #[cfg(stm32g4)] | 33 | #[cfg(stm32g4)] |
| 23 | const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60); | 34 | const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60); |
| @@ -120,6 +131,24 @@ impl Prescaler { | |||
| 120 | } | 131 | } |
| 121 | } | 132 | } |
| 122 | 133 | ||
| 134 | // Trigger source for ADC conversions¨ | ||
| 135 | #[derive(Copy, Clone)] | ||
| 136 | pub struct ConversionTrigger { | ||
| 137 | // See Table 166 and 167 in RM0440 Rev 9 for ADC1/2 External triggers | ||
| 138 | // Note that Injected and Regular channels uses different mappings | ||
| 139 | pub channel: u8, | ||
| 140 | pub edge: Exten, | ||
| 141 | } | ||
| 142 | |||
| 143 | // Conversion mode for regular ADC channels | ||
| 144 | #[derive(Copy, Clone)] | ||
| 145 | pub enum RegularConversionMode { | ||
| 146 | // Samples as fast as possible | ||
| 147 | Continuous, | ||
| 148 | // Sample at rate determined by external trigger | ||
| 149 | Triggered(ConversionTrigger), | ||
| 150 | } | ||
| 151 | |||
| 123 | impl<'d, T: Instance> Adc<'d, T> { | 152 | impl<'d, T: Instance> Adc<'d, T> { |
| 124 | /// Create a new ADC driver. | 153 | /// Create a new ADC driver. |
| 125 | pub fn new(adc: Peri<'d, T>) -> Self { | 154 | pub fn new(adc: Peri<'d, T>) -> Self { |
| @@ -357,7 +386,29 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 357 | self.read_channel(channel) | 386 | self.read_channel(channel) |
| 358 | } | 387 | } |
| 359 | 388 | ||
| 360 | /// Read one or multiple ADC channels using DMA. | 389 | /// Start regular adc conversion |
| 390 | pub(super) fn start() { | ||
| 391 | T::regs().cr().modify(|reg| { | ||
| 392 | reg.set_adstart(true); | ||
| 393 | }); | ||
| 394 | } | ||
| 395 | |||
| 396 | /// Stop regular conversions | ||
| 397 | pub(super) fn stop() { | ||
| 398 | Self::stop_regular_conversions(); | ||
| 399 | } | ||
| 400 | |||
| 401 | /// Teardown method for stopping regular ADC conversions | ||
| 402 | pub(super) fn teardown_adc() { | ||
| 403 | Self::stop_regular_conversions(); | ||
| 404 | |||
| 405 | // Disable dma control | ||
| 406 | T::regs().cfgr().modify(|reg| { | ||
| 407 | reg.set_dmaen(Dmaen::DISABLE); | ||
| 408 | }); | ||
| 409 | } | ||
| 410 | |||
| 411 | /// Read one or multiple ADC regular channels using DMA. | ||
| 361 | /// | 412 | /// |
| 362 | /// `sequence` iterator and `readings` must have the same length. | 413 | /// `sequence` iterator and `readings` must have the same length. |
| 363 | /// | 414 | /// |
| @@ -382,6 +433,9 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 382 | /// .await; | 433 | /// .await; |
| 383 | /// defmt::info!("measurements: {}", measurements); | 434 | /// defmt::info!("measurements: {}", measurements); |
| 384 | /// ``` | 435 | /// ``` |
| 436 | /// | ||
| 437 | /// Note: This is not very efficient as the ADC needs to be reconfigured for each read. Use | ||
| 438 | /// `into_ring_buffered`, `into_ring_buffered_and_injected` | ||
| 385 | pub async fn read( | 439 | pub async fn read( |
| 386 | &mut self, | 440 | &mut self, |
| 387 | rx_dma: Peri<'_, impl RxDma<T>>, | 441 | rx_dma: Peri<'_, impl RxDma<T>>, |
| @@ -399,18 +453,16 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 399 | ); | 453 | ); |
| 400 | 454 | ||
| 401 | // Ensure no conversions are ongoing and ADC is enabled. | 455 | // Ensure no conversions are ongoing and ADC is enabled. |
| 402 | Self::cancel_conversions(); | 456 | Self::stop_regular_conversions(); |
| 403 | self.enable(); | 457 | self.enable(); |
| 404 | 458 | ||
| 405 | // Set sequence length | 459 | // Set sequence length |
| 406 | T::regs().sqr1().modify(|w| { | 460 | T::regs().sqr1().modify(|w| { |
| 407 | w.set_l(sequence.len() as u8 - 1); | 461 | w.set_l(sequence.len() as u8 - 1); |
| 408 | }); | 462 | }); |
| 409 | |||
| 410 | // Configure channels and ranks | 463 | // Configure channels and ranks |
| 411 | for (_i, (channel, sample_time)) in sequence.enumerate() { | 464 | for (_i, (channel, sample_time)) in sequence.enumerate() { |
| 412 | Self::configure_channel(channel, sample_time); | 465 | Self::configure_channel(channel, sample_time); |
| 413 | |||
| 414 | match _i { | 466 | match _i { |
| 415 | 0..=3 => { | 467 | 0..=3 => { |
| 416 | T::regs().sqr1().modify(|w| { | 468 | T::regs().sqr1().modify(|w| { |
| @@ -469,7 +521,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 469 | transfer.await; | 521 | transfer.await; |
| 470 | 522 | ||
| 471 | // Ensure conversions are finished. | 523 | // Ensure conversions are finished. |
| 472 | Self::cancel_conversions(); | 524 | Self::stop_regular_conversions(); |
| 473 | 525 | ||
| 474 | // Reset configuration. | 526 | // Reset configuration. |
| 475 | T::regs().cfgr().modify(|reg| { | 527 | T::regs().cfgr().modify(|reg| { |
| @@ -477,6 +529,277 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 477 | }); | 529 | }); |
| 478 | } | 530 | } |
| 479 | 531 | ||
| 532 | /// Set external trigger for regular conversion sequence | ||
| 533 | fn set_regular_conversion_trigger(&mut self, trigger: ConversionTrigger) { | ||
| 534 | T::regs().cfgr().modify(|r| { | ||
| 535 | r.set_extsel(trigger.channel); | ||
| 536 | r.set_exten(trigger.edge); | ||
| 537 | }); | ||
| 538 | // Regular conversions uses DMA so no need to generate interrupt | ||
| 539 | T::regs().ier().modify(|r| r.set_eosie(false)); | ||
| 540 | } | ||
| 541 | |||
| 542 | // Dual ADC mode selection | ||
| 543 | pub fn configure_dual_mode(&mut self, val: Dual) { | ||
| 544 | T::common_regs().ccr().modify(|reg| { | ||
| 545 | reg.set_dual(val); | ||
| 546 | }) | ||
| 547 | } | ||
| 548 | |||
| 549 | /// Configures the ADC to use a DMA ring buffer for continuous data acquisition. | ||
| 550 | /// | ||
| 551 | /// Use the [`read`] method to retrieve measurements from the DMA ring buffer. The read buffer | ||
| 552 | /// should be exactly half the size of `dma_buf`. When using triggered mode, it is recommended | ||
| 553 | /// to configure `dma_buf` as a double buffer so that one half can be read while the other half | ||
| 554 | /// is being filled by the DMA, preventing data loss. The trigger period of the ADC effectively | ||
| 555 | /// defines the period at which the buffer should be read. | ||
| 556 | /// | ||
| 557 | /// If continous conversion mode is selected, the provided `dma_buf` must be large enough to prevent | ||
| 558 | /// DMA buffer overruns. Its length should be a multiple of the number of ADC channels being measured. | ||
| 559 | /// For example, if 3 channels are measured and you want to store 40 samples per channel, | ||
| 560 | /// the buffer length should be `3 * 40 = 120`. | ||
| 561 | /// | ||
| 562 | /// # Parameters | ||
| 563 | /// - `dma`: The DMA peripheral used to transfer ADC data into the buffer. | ||
| 564 | /// - `dma_buf`: The buffer where DMA stores ADC samples. | ||
| 565 | /// - `regular_sequence`: Sequence of channels and sample times for regular ADC conversions. | ||
| 566 | /// - `regular_conversion_mode`: Mode for regular conversions (continuous or triggered). | ||
| 567 | /// | ||
| 568 | /// # Returns | ||
| 569 | /// A `RingBufferedAdc<'a, T>` instance configured for continuous DMA-based sampling. | ||
| 570 | pub fn into_ring_buffered<'a>( | ||
| 571 | mut self, | ||
| 572 | dma: Peri<'a, impl RxDma<T>>, | ||
| 573 | dma_buf: &'a mut [u16], | ||
| 574 | sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<T>, SampleTime)>, | ||
| 575 | mode: RegularConversionMode, | ||
| 576 | ) -> RingBufferedAdc<'a, T> { | ||
| 577 | assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); | ||
| 578 | assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); | ||
| 579 | assert!( | ||
| 580 | sequence.len() <= 16, | ||
| 581 | "Asynchronous read sequence cannot be more than 16 in length" | ||
| 582 | ); | ||
| 583 | // reset conversions and enable the adc | ||
| 584 | Self::stop_regular_conversions(); | ||
| 585 | self.enable(); | ||
| 586 | |||
| 587 | //adc side setup | ||
| 588 | |||
| 589 | // Set sequence length | ||
| 590 | T::regs().sqr1().modify(|w| { | ||
| 591 | w.set_l(sequence.len() as u8 - 1); | ||
| 592 | }); | ||
| 593 | |||
| 594 | // Configure channels and ranks | ||
| 595 | for (_i, (mut channel, sample_time)) in sequence.enumerate() { | ||
| 596 | Self::configure_channel(&mut channel, sample_time); | ||
| 597 | |||
| 598 | match _i { | ||
| 599 | 0..=3 => { | ||
| 600 | T::regs().sqr1().modify(|w| { | ||
| 601 | w.set_sq(_i, channel.channel()); | ||
| 602 | }); | ||
| 603 | } | ||
| 604 | 4..=8 => { | ||
| 605 | T::regs().sqr2().modify(|w| { | ||
| 606 | w.set_sq(_i - 4, channel.channel()); | ||
| 607 | }); | ||
| 608 | } | ||
| 609 | 9..=13 => { | ||
| 610 | T::regs().sqr3().modify(|w| { | ||
| 611 | w.set_sq(_i - 9, channel.channel()); | ||
| 612 | }); | ||
| 613 | } | ||
| 614 | 14..=15 => { | ||
| 615 | T::regs().sqr4().modify(|w| { | ||
| 616 | w.set_sq(_i - 14, channel.channel()); | ||
| 617 | }); | ||
| 618 | } | ||
| 619 | _ => unreachable!(), | ||
| 620 | } | ||
| 621 | } | ||
| 622 | |||
| 623 | // Clear overrun flag before starting transfer. | ||
| 624 | T::regs().isr().modify(|reg| { | ||
| 625 | reg.set_ovr(true); | ||
| 626 | }); | ||
| 627 | |||
| 628 | T::regs().cfgr().modify(|reg| { | ||
| 629 | reg.set_discen(false); // Convert all channels for each trigger | ||
| 630 | reg.set_dmacfg(Dmacfg::CIRCULAR); | ||
| 631 | reg.set_dmaen(Dmaen::ENABLE); | ||
| 632 | }); | ||
| 633 | |||
| 634 | match mode { | ||
| 635 | RegularConversionMode::Continuous => { | ||
| 636 | T::regs().cfgr().modify(|reg| { | ||
| 637 | reg.set_cont(true); | ||
| 638 | }); | ||
| 639 | } | ||
| 640 | RegularConversionMode::Triggered(trigger) => { | ||
| 641 | T::regs().cfgr().modify(|r| { | ||
| 642 | r.set_cont(false); // New trigger is neede for each sample to be read | ||
| 643 | }); | ||
| 644 | self.set_regular_conversion_trigger(trigger); | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | mem::forget(self); | ||
| 649 | |||
| 650 | RingBufferedAdc::new(dma, dma_buf) | ||
| 651 | } | ||
| 652 | |||
| 653 | /// Configures the ADC for injected conversions. | ||
| 654 | /// | ||
| 655 | /// Injected conversions are separate from the regular conversion sequence and are typically | ||
| 656 | /// triggered by software or an external event. This method sets up a fixed-length sequence of | ||
| 657 | /// injected channels with specified sample times, the trigger source, and whether the end-of-sequence | ||
| 658 | /// interrupt should be enabled. | ||
| 659 | /// | ||
| 660 | /// # Parameters | ||
| 661 | /// - `sequence`: An array of tuples containing the ADC channels and their sample times. The length | ||
| 662 | /// `N` determines the number of injected ranks to configure (maximum 4 for STM32). | ||
| 663 | /// - `trigger`: The trigger source that starts the injected conversion sequence. | ||
| 664 | /// - `interrupt`: If `true`, enables the end-of-sequence (JEOS) interrupt for injected conversions. | ||
| 665 | /// | ||
| 666 | /// # Returns | ||
| 667 | /// An `InjectedAdc<T, N>` instance that represents the configured injected sequence. The returned | ||
| 668 | /// type encodes the sequence length `N` in its type, ensuring that reads return exactly `N` samples. | ||
| 669 | /// | ||
| 670 | /// # Panics | ||
| 671 | /// This function will panic if: | ||
| 672 | /// - `sequence` is empty. | ||
| 673 | /// - `sequence` length exceeds the maximum number of injected ranks (`NR_INJECTED_RANKS`). | ||
| 674 | /// | ||
| 675 | /// # Notes | ||
| 676 | /// - Injected conversions can run independently of regular ADC conversions. | ||
| 677 | /// - The order of channels in `sequence` determines the rank order in the injected sequence. | ||
| 678 | /// - Accessing samples beyond `N` will result in a panic; use the returned type | ||
| 679 | /// `InjectedAdc<T, N>` to enforce bounds at compile time. | ||
| 680 | pub fn setup_injected_conversions<'a, const N: usize>( | ||
| 681 | mut self, | ||
| 682 | sequence: [(AnyAdcChannel<T>, SampleTime); N], | ||
| 683 | trigger: ConversionTrigger, | ||
| 684 | interrupt: bool, | ||
| 685 | ) -> InjectedAdc<T, N> { | ||
| 686 | assert!(N != 0, "Read sequence cannot be empty"); | ||
| 687 | assert!( | ||
| 688 | N <= NR_INJECTED_RANKS, | ||
| 689 | "Read sequence cannot be more than {} in length", | ||
| 690 | NR_INJECTED_RANKS | ||
| 691 | ); | ||
| 692 | |||
| 693 | Self::stop_regular_conversions(); | ||
| 694 | self.enable(); | ||
| 695 | |||
| 696 | T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1)); | ||
| 697 | |||
| 698 | for (n, (mut channel, sample_time)) in sequence.into_iter().enumerate() { | ||
| 699 | Self::configure_channel(&mut channel, sample_time); | ||
| 700 | |||
| 701 | let idx = match n { | ||
| 702 | 0..=3 => n, | ||
| 703 | 4..=8 => n - 4, | ||
| 704 | 9..=13 => n - 9, | ||
| 705 | 14..=15 => n - 14, | ||
| 706 | _ => unreachable!(), | ||
| 707 | }; | ||
| 708 | |||
| 709 | T::regs().jsqr().modify(|w| w.set_jsq(idx, channel.channel())); | ||
| 710 | } | ||
| 711 | |||
| 712 | T::regs().cfgr().modify(|reg| reg.set_jdiscen(false)); | ||
| 713 | |||
| 714 | self.set_injected_conversion_trigger(trigger); | ||
| 715 | self.enable_injected_eos_interrupt(interrupt); | ||
| 716 | Self::start_injected_conversions(); | ||
| 717 | |||
| 718 | InjectedAdc::new(sequence) // InjectedAdc<'a, T, N> now borrows the channels | ||
| 719 | } | ||
| 720 | |||
| 721 | /// Configures ADC for both regular conversions with a ring-buffered DMA and injected conversions. | ||
| 722 | /// | ||
| 723 | /// # Parameters | ||
| 724 | /// - `dma`: The DMA peripheral to use for the ring-buffered ADC transfers. | ||
| 725 | /// - `dma_buf`: The buffer to store DMA-transferred samples for regular conversions. | ||
| 726 | /// - `regular_sequence`: The sequence of channels and their sample times for regular conversions. | ||
| 727 | /// - `regular_conversion_mode`: The mode for regular conversions (e.g., continuous or triggered). | ||
| 728 | /// - `injected_sequence`: An array of channels and sample times for injected conversions (length `N`). | ||
| 729 | /// - `injected_trigger`: The trigger source for injected conversions. | ||
| 730 | /// - `injected_interrupt`: Whether to enable the end-of-sequence interrupt for injected conversions. | ||
| 731 | /// | ||
| 732 | /// Injected conversions are typically used with interrupts. If ADC1 and ADC2 are used in dual mode, | ||
| 733 | /// it is recommended to enable interrupts only for the ADC whose sequence takes the longest to complete. | ||
| 734 | /// | ||
| 735 | /// # Returns | ||
| 736 | /// A tuple containing: | ||
| 737 | /// 1. `RingBufferedAdc<'a, T>` — the configured ADC for regular conversions using DMA. | ||
| 738 | /// 2. `InjectedAdc<T, N>` — the configured ADC for injected conversions. | ||
| 739 | /// | ||
| 740 | /// # Safety | ||
| 741 | /// This function is `unsafe` because it clones the ADC peripheral handle unchecked. Both the | ||
| 742 | /// `RingBufferedAdc` and `InjectedAdc` take ownership of the handle and drop it independently. | ||
| 743 | /// Ensure no other code concurrently accesses the same ADC instance in a conflicting way. | ||
| 744 | pub fn into_ring_buffered_and_injected<'a, const N: usize>( | ||
| 745 | self, | ||
| 746 | dma: Peri<'a, impl RxDma<T>>, | ||
| 747 | dma_buf: &'a mut [u16], | ||
| 748 | regular_sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<T>, SampleTime)>, | ||
| 749 | regular_conversion_mode: RegularConversionMode, | ||
| 750 | injected_sequence: [(AnyAdcChannel<T>, SampleTime); N], | ||
| 751 | injected_trigger: ConversionTrigger, | ||
| 752 | injected_interrupt: bool, | ||
| 753 | ) -> (RingBufferedAdc<'a, T>, InjectedAdc<T, N>) { | ||
| 754 | unsafe { | ||
| 755 | ( | ||
| 756 | Self { | ||
| 757 | adc: self.adc.clone_unchecked(), | ||
| 758 | sample_time: self.sample_time, | ||
| 759 | } | ||
| 760 | .into_ring_buffered(dma, dma_buf, regular_sequence, regular_conversion_mode), | ||
| 761 | Self { | ||
| 762 | adc: self.adc.clone_unchecked(), | ||
| 763 | sample_time: self.sample_time, | ||
| 764 | } | ||
| 765 | .setup_injected_conversions(injected_sequence, injected_trigger, injected_interrupt), | ||
| 766 | ) | ||
| 767 | } | ||
| 768 | } | ||
| 769 | |||
| 770 | /// Stop injected conversions | ||
| 771 | pub(super) fn stop_injected_conversions() { | ||
| 772 | if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { | ||
| 773 | T::regs().cr().modify(|reg| { | ||
| 774 | reg.set_jadstp(Adstp::STOP); | ||
| 775 | }); | ||
| 776 | // The software must poll JADSTART until the bit is reset before assuming the | ||
| 777 | // ADC is completely stopped | ||
| 778 | while T::regs().cr().read().jadstart() {} | ||
| 779 | } | ||
| 780 | } | ||
| 781 | |||
| 782 | /// Start injected ADC conversion | ||
| 783 | pub(super) fn start_injected_conversions() { | ||
| 784 | T::regs().cr().modify(|reg| { | ||
| 785 | reg.set_jadstart(true); | ||
| 786 | }); | ||
| 787 | } | ||
| 788 | |||
| 789 | /// Set external trigger for injected conversion sequence | ||
| 790 | /// Possible trigger values are seen in Table 167 in RM0440 Rev 9 | ||
| 791 | fn set_injected_conversion_trigger(&mut self, trigger: ConversionTrigger) { | ||
| 792 | T::regs().jsqr().modify(|r| { | ||
| 793 | r.set_jextsel(trigger.channel); | ||
| 794 | r.set_jexten(trigger.edge); | ||
| 795 | }); | ||
| 796 | } | ||
| 797 | |||
| 798 | /// Enable end of injected sequence interrupt | ||
| 799 | fn enable_injected_eos_interrupt(&mut self, enable: bool) { | ||
| 800 | T::regs().ier().modify(|r| r.set_jeosie(enable)); | ||
| 801 | } | ||
| 802 | |||
| 480 | fn configure_channel(channel: &mut impl AdcChannel<T>, sample_time: SampleTime) { | 803 | fn configure_channel(channel: &mut impl AdcChannel<T>, sample_time: SampleTime) { |
| 481 | // Configure channel | 804 | // Configure channel |
| 482 | Self::set_channel_sample_time(channel.channel(), sample_time); | 805 | Self::set_channel_sample_time(channel.channel(), sample_time); |
| @@ -509,16 +832,34 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 509 | } | 832 | } |
| 510 | } | 833 | } |
| 511 | 834 | ||
| 512 | fn cancel_conversions() { | 835 | // Stop regular conversions |
| 836 | fn stop_regular_conversions() { | ||
| 513 | if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { | 837 | if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { |
| 514 | T::regs().cr().modify(|reg| { | 838 | T::regs().cr().modify(|reg| { |
| 515 | reg.set_adstp(Adstp::STOP); | 839 | reg.set_adstp(Adstp::STOP); |
| 516 | }); | 840 | }); |
| 841 | // The software must poll ADSTART until the bit is reset before assuming the | ||
| 842 | // ADC is completely stopped | ||
| 517 | while T::regs().cr().read().adstart() {} | 843 | while T::regs().cr().read().adstart() {} |
| 518 | } | 844 | } |
| 519 | } | 845 | } |
| 520 | } | 846 | } |
| 521 | 847 | ||
| 848 | impl<T: Instance, const N: usize> InjectedAdc<T, N> { | ||
| 849 | /// Read sampled data from all injected ADC injected ranks | ||
| 850 | /// Clear the JEOS flag to allow a new injected sequence | ||
| 851 | pub(super) fn read_injected_data() -> [u16; N] { | ||
| 852 | let mut data = [0u16; N]; | ||
| 853 | for i in 0..N { | ||
| 854 | data[i] = T::regs().jdr(i).read().jdata(); | ||
| 855 | } | ||
| 856 | |||
| 857 | // Clear JEOS by writing 1 | ||
| 858 | T::regs().isr().modify(|r| r.set_jeos(true)); | ||
| 859 | data | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 522 | /// Implemented for ADCs that have a Temperature channel | 863 | /// Implemented for ADCs that have a Temperature channel |
| 523 | pub trait TemperatureChannel { | 864 | pub trait TemperatureChannel { |
| 524 | const CHANNEL: u8; | 865 | const CHANNEL: u8; |
diff --git a/embassy-stm32/src/adc/injected.rs b/embassy-stm32/src/adc/injected.rs new file mode 100644 index 000000000..0e4fe5847 --- /dev/null +++ b/embassy-stm32/src/adc/injected.rs | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | use core::sync::atomic::{Ordering, compiler_fence}; | ||
| 3 | |||
| 4 | #[allow(unused_imports)] | ||
| 5 | use embassy_hal_internal::Peri; | ||
| 6 | |||
| 7 | use super::{AnyAdcChannel, SampleTime}; | ||
| 8 | use crate::adc::Adc; | ||
| 9 | #[allow(unused_imports)] | ||
| 10 | use crate::adc::Instance; | ||
| 11 | |||
| 12 | /// Injected ADC sequence with owned channels. | ||
| 13 | pub struct InjectedAdc<T: Instance, const N: usize> { | ||
| 14 | _channels: [(AnyAdcChannel<T>, SampleTime); N], | ||
| 15 | _phantom: PhantomData<T>, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<T: Instance, const N: usize> InjectedAdc<T, N> { | ||
| 19 | pub(crate) fn new(channels: [(AnyAdcChannel<T>, SampleTime); N]) -> Self { | ||
| 20 | Self { | ||
| 21 | _channels: channels, | ||
| 22 | _phantom: PhantomData, | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | pub fn stop_injected_conversions(&mut self) { | ||
| 27 | Adc::<T>::stop_injected_conversions() | ||
| 28 | } | ||
| 29 | |||
| 30 | pub fn start_injected_conversions(&mut self) { | ||
| 31 | Adc::<T>::start_injected_conversions() | ||
| 32 | } | ||
| 33 | |||
| 34 | pub fn read_injected_samples(&mut self) -> [u16; N] { | ||
| 35 | InjectedAdc::<T, N>::read_injected_data() | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | impl<T: Instance, const N: usize> Drop for InjectedAdc<T, N> { | ||
| 40 | fn drop(&mut self) { | ||
| 41 | Adc::<T>::teardown_adc(); | ||
| 42 | compiler_fence(Ordering::SeqCst); | ||
| 43 | } | ||
| 44 | } | ||
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 22ed8295f..ea7341f75 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -87,14 +87,18 @@ pub(crate) trait SealedAdcChannel<T> { | |||
| 87 | /// Performs a busy-wait delay for a specified number of microseconds. | 87 | /// Performs a busy-wait delay for a specified number of microseconds. |
| 88 | #[allow(unused)] | 88 | #[allow(unused)] |
| 89 | pub(crate) fn blocking_delay_us(us: u32) { | 89 | pub(crate) fn blocking_delay_us(us: u32) { |
| 90 | #[cfg(feature = "time")] | 90 | cfg_if::cfg_if! { |
| 91 | embassy_time::block_for(embassy_time::Duration::from_micros(us as u64)); | 91 | // this does strange things on stm32wlx in low power mode depending on exactly when it's called |
| 92 | #[cfg(not(feature = "time"))] | 92 | // as in sometimes 15 us (1 tick) would take > 20 seconds. |
| 93 | { | 93 | if #[cfg(all(feature = "time", all(not(feature = "low-power"), not(stm32wlex))))] { |
| 94 | let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64; | 94 | let duration = embassy_time::Duration::from_micros(us as u64); |
| 95 | let us = us as u64; | 95 | embassy_time::block_for(duration); |
| 96 | let cycles = freq * us / 1_000_000; | 96 | } else { |
| 97 | cortex_m::asm::delay(cycles as u32); | 97 | let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64; |
| 98 | let us = us as u64; | ||
| 99 | let cycles = freq * us / 1_000_000; | ||
| 100 | cortex_m::asm::delay(cycles as u32); | ||
| 101 | } | ||
| 98 | } | 102 | } |
| 99 | } | 103 | } |
| 100 | 104 | ||
diff --git a/embassy-stm32/src/adc/ringbuffered.rs b/embassy-stm32/src/adc/ringbuffered.rs new file mode 100644 index 000000000..971c8195c --- /dev/null +++ b/embassy-stm32/src/adc/ringbuffered.rs | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | use core::sync::atomic::{Ordering, compiler_fence}; | ||
| 3 | |||
| 4 | #[allow(unused_imports)] | ||
| 5 | use embassy_hal_internal::Peri; | ||
| 6 | |||
| 7 | use crate::adc::Adc; | ||
| 8 | #[allow(unused_imports)] | ||
| 9 | use crate::adc::{Instance, RxDma}; | ||
| 10 | #[allow(unused_imports)] | ||
| 11 | use crate::dma::{ReadableRingBuffer, TransferOptions}; | ||
| 12 | use crate::rcc; | ||
| 13 | |||
| 14 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 15 | pub struct OverrunError; | ||
| 16 | |||
| 17 | pub struct RingBufferedAdc<'d, T: Instance> { | ||
| 18 | _phantom: PhantomData<T>, | ||
| 19 | ring_buf: ReadableRingBuffer<'d, u16>, | ||
| 20 | } | ||
| 21 | |||
| 22 | impl<'d, T: Instance> RingBufferedAdc<'d, T> { | ||
| 23 | pub(crate) fn new(dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> Self { | ||
| 24 | //dma side setup | ||
| 25 | let opts = TransferOptions { | ||
| 26 | half_transfer_ir: true, | ||
| 27 | circular: true, | ||
| 28 | ..Default::default() | ||
| 29 | }; | ||
| 30 | |||
| 31 | // Safety: we forget the struct before this function returns. | ||
| 32 | let request = dma.request(); | ||
| 33 | |||
| 34 | let ring_buf = | ||
| 35 | unsafe { ReadableRingBuffer::new(dma, request, T::regs().dr().as_ptr() as *mut u16, dma_buf, opts) }; | ||
| 36 | |||
| 37 | Self { | ||
| 38 | _phantom: PhantomData, | ||
| 39 | ring_buf, | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | /// Turns on ADC if it is not already turned on and starts continuous DMA transfer. | ||
| 44 | pub fn start(&mut self) { | ||
| 45 | compiler_fence(Ordering::SeqCst); | ||
| 46 | self.ring_buf.start(); | ||
| 47 | |||
| 48 | Adc::<T>::start(); | ||
| 49 | } | ||
| 50 | |||
| 51 | pub fn stop(&mut self) { | ||
| 52 | Adc::<T>::stop(); | ||
| 53 | |||
| 54 | self.ring_buf.request_pause(); | ||
| 55 | |||
| 56 | compiler_fence(Ordering::SeqCst); | ||
| 57 | } | ||
| 58 | |||
| 59 | pub fn clear(&mut self) { | ||
| 60 | self.ring_buf.clear(); | ||
| 61 | } | ||
| 62 | |||
| 63 | /// Reads measurements from the DMA ring buffer. | ||
| 64 | /// | ||
| 65 | /// This method fills the provided `measurements` array with ADC readings from the DMA buffer. | ||
| 66 | /// The length of the `measurements` array should be exactly half of the DMA buffer length. | ||
| 67 | /// Because interrupts are only generated if half or full DMA transfer completes. | ||
| 68 | /// | ||
| 69 | /// Each call to `read` will populate the `measurements` array in the same order as the channels | ||
| 70 | /// defined with `sequence`. There will be many sequences worth of measurements in this array | ||
| 71 | /// because it only returns if at least half of the DMA buffer is filled. For example if 2 | ||
| 72 | /// channels are sampled `measurements` contain: `[sq0 sq1 sq0 sq1 sq0 sq1 ..]`. | ||
| 73 | /// | ||
| 74 | /// Note that the ADC Datarate can be very fast, it is suggested to use DMA mode inside tightly | ||
| 75 | /// running tasks. Otherwise, you'll see constant Overrun errors occurring, this means that | ||
| 76 | /// you're sampling too quickly for the task to handle, and you may need to increase the buffer size. | ||
| 77 | /// Example: | ||
| 78 | /// ```rust,ignore | ||
| 79 | /// const DMA_BUF_LEN: usize = 120; | ||
| 80 | /// use embassy_stm32::adc::{Adc, AdcChannel} | ||
| 81 | /// | ||
| 82 | /// let mut adc = Adc::new(p.ADC1); | ||
| 83 | /// let mut adc_pin0 = p.PA0.degrade_adc(); | ||
| 84 | /// let mut adc_pin1 = p.PA1.degrade_adc(); | ||
| 85 | /// let adc_dma_buf = [0u16; DMA_BUF_LEN]; | ||
| 86 | /// | ||
| 87 | /// let mut ring_buffered_adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered( | ||
| 88 | /// p.DMA2_CH0, | ||
| 89 | /// adc_dma_buf, [ | ||
| 90 | /// (&mut *adc_pin0, SampleTime::CYCLES160_5), | ||
| 91 | /// (&mut *adc_pin1, SampleTime::CYCLES160_5), | ||
| 92 | /// ].into_iter()); | ||
| 93 | /// | ||
| 94 | /// | ||
| 95 | /// let mut measurements = [0u16; DMA_BUF_LEN / 2]; | ||
| 96 | /// loop { | ||
| 97 | /// match ring_buffered_adc.read(&mut measurements).await { | ||
| 98 | /// Ok(_) => { | ||
| 99 | /// defmt::info!("adc1: {}", measurements); | ||
| 100 | /// } | ||
| 101 | /// Err(e) => { | ||
| 102 | /// defmt::warn!("Error: {:?}", e); | ||
| 103 | /// } | ||
| 104 | /// } | ||
| 105 | /// } | ||
| 106 | /// ``` | ||
| 107 | /// | ||
| 108 | /// | ||
| 109 | /// [`teardown_adc`]: #method.teardown_adc | ||
| 110 | /// [`start_continuous_sampling`]: #method.start_continuous_sampling | ||
| 111 | pub async fn read(&mut self, measurements: &mut [u16]) -> Result<usize, OverrunError> { | ||
| 112 | assert_eq!( | ||
| 113 | self.ring_buf.capacity() / 2, | ||
| 114 | measurements.len(), | ||
| 115 | "Buffer size must be half the size of the ring buffer" | ||
| 116 | ); | ||
| 117 | |||
| 118 | if !self.ring_buf.is_running() { | ||
| 119 | self.start(); | ||
| 120 | } | ||
| 121 | |||
| 122 | #[cfg(adc_v2)] | ||
| 123 | { | ||
| 124 | // Clear overrun flag if set. | ||
| 125 | if T::regs().sr().read().ovr() { | ||
| 126 | self.stop(); | ||
| 127 | |||
| 128 | return Err(OverrunError); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | self.ring_buf.read_exact(measurements).await.map_err(|_| OverrunError) | ||
| 133 | } | ||
| 134 | |||
| 135 | /// Read bytes that are readily available in the ring buffer. | ||
| 136 | /// If no bytes are currently available in the buffer the call waits until the some | ||
| 137 | /// bytes are available (at least one byte and at most half the buffer size) | ||
| 138 | /// | ||
| 139 | /// Background receive is started if `start_continuous_sampling()` has not been previously called. | ||
| 140 | /// | ||
| 141 | /// Receive in the background is terminated if an error is returned. | ||
| 142 | /// It must then manually be started again by calling `start_continuous_sampling()` or by re-calling `blocking_read()`. | ||
| 143 | pub fn blocking_read(&mut self, buf: &mut [u16]) -> Result<usize, OverrunError> { | ||
| 144 | if !self.ring_buf.is_running() { | ||
| 145 | self.start(); | ||
| 146 | } | ||
| 147 | |||
| 148 | #[cfg(adc_v2)] | ||
| 149 | { | ||
| 150 | // Clear overrun flag if set. | ||
| 151 | if T::regs().sr().read().ovr() { | ||
| 152 | self.stop(); | ||
| 153 | |||
| 154 | return Err(OverrunError); | ||
| 155 | } | ||
| 156 | } | ||
| 157 | loop { | ||
| 158 | match self.ring_buf.read(buf) { | ||
| 159 | Ok((0, _)) => {} | ||
| 160 | Ok((len, _)) => { | ||
| 161 | return Ok(len); | ||
| 162 | } | ||
| 163 | Err(_) => { | ||
| 164 | self.stop(); | ||
| 165 | |||
| 166 | return Err(OverrunError); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | } | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | impl<T: Instance> Drop for RingBufferedAdc<'_, T> { | ||
| 174 | fn drop(&mut self) { | ||
| 175 | Adc::<T>::teardown_adc(); | ||
| 176 | |||
| 177 | compiler_fence(Ordering::SeqCst); | ||
| 178 | |||
| 179 | self.ring_buf.request_pause(); | ||
| 180 | rcc::disable::<T>(); | ||
| 181 | } | ||
| 182 | } | ||
diff --git a/embassy-stm32/src/adc/ringbuffered_v2.rs b/embassy-stm32/src/adc/ringbuffered_v2.rs deleted file mode 100644 index 9b2e5b8fe..000000000 --- a/embassy-stm32/src/adc/ringbuffered_v2.rs +++ /dev/null | |||
| @@ -1,432 +0,0 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | use core::mem; | ||
| 3 | use core::sync::atomic::{Ordering, compiler_fence}; | ||
| 4 | |||
| 5 | use stm32_metapac::adc::vals::SampleTime; | ||
| 6 | |||
| 7 | use crate::adc::{Adc, AdcChannel, Instance, RxDma}; | ||
| 8 | use crate::dma::{Priority, ReadableRingBuffer, TransferOptions}; | ||
| 9 | use crate::pac::adc::vals; | ||
| 10 | use crate::{Peri, rcc}; | ||
| 11 | |||
| 12 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13 | pub struct OverrunError; | ||
| 14 | |||
| 15 | fn clear_interrupt_flags(r: crate::pac::adc::Adc) { | ||
| 16 | r.sr().modify(|regs| { | ||
| 17 | regs.set_eoc(false); | ||
| 18 | regs.set_ovr(false); | ||
| 19 | }); | ||
| 20 | } | ||
| 21 | |||
| 22 | #[derive(PartialOrd, PartialEq, Debug, Clone, Copy)] | ||
| 23 | pub enum Sequence { | ||
| 24 | One, | ||
| 25 | Two, | ||
| 26 | Three, | ||
| 27 | Four, | ||
| 28 | Five, | ||
| 29 | Six, | ||
| 30 | Seven, | ||
| 31 | Eight, | ||
| 32 | Nine, | ||
| 33 | Ten, | ||
| 34 | Eleven, | ||
| 35 | Twelve, | ||
| 36 | Thirteen, | ||
| 37 | Fourteen, | ||
| 38 | Fifteen, | ||
| 39 | Sixteen, | ||
| 40 | } | ||
| 41 | |||
| 42 | impl From<Sequence> for u8 { | ||
| 43 | fn from(s: Sequence) -> u8 { | ||
| 44 | match s { | ||
| 45 | Sequence::One => 0, | ||
| 46 | Sequence::Two => 1, | ||
| 47 | Sequence::Three => 2, | ||
| 48 | Sequence::Four => 3, | ||
| 49 | Sequence::Five => 4, | ||
| 50 | Sequence::Six => 5, | ||
| 51 | Sequence::Seven => 6, | ||
| 52 | Sequence::Eight => 7, | ||
| 53 | Sequence::Nine => 8, | ||
| 54 | Sequence::Ten => 9, | ||
| 55 | Sequence::Eleven => 10, | ||
| 56 | Sequence::Twelve => 11, | ||
| 57 | Sequence::Thirteen => 12, | ||
| 58 | Sequence::Fourteen => 13, | ||
| 59 | Sequence::Fifteen => 14, | ||
| 60 | Sequence::Sixteen => 15, | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | impl From<u8> for Sequence { | ||
| 66 | fn from(val: u8) -> Self { | ||
| 67 | match val { | ||
| 68 | 0 => Sequence::One, | ||
| 69 | 1 => Sequence::Two, | ||
| 70 | 2 => Sequence::Three, | ||
| 71 | 3 => Sequence::Four, | ||
| 72 | 4 => Sequence::Five, | ||
| 73 | 5 => Sequence::Six, | ||
| 74 | 6 => Sequence::Seven, | ||
| 75 | 7 => Sequence::Eight, | ||
| 76 | 8 => Sequence::Nine, | ||
| 77 | 9 => Sequence::Ten, | ||
| 78 | 10 => Sequence::Eleven, | ||
| 79 | 11 => Sequence::Twelve, | ||
| 80 | 12 => Sequence::Thirteen, | ||
| 81 | 13 => Sequence::Fourteen, | ||
| 82 | 14 => Sequence::Fifteen, | ||
| 83 | 15 => Sequence::Sixteen, | ||
| 84 | _ => panic!("Invalid sequence number"), | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | pub struct RingBufferedAdc<'d, T: Instance> { | ||
| 90 | _phantom: PhantomData<T>, | ||
| 91 | ring_buf: ReadableRingBuffer<'d, u16>, | ||
| 92 | } | ||
| 93 | |||
| 94 | impl<'d, T: Instance> Adc<'d, T> { | ||
| 95 | /// Configures the ADC to use a DMA ring buffer for continuous data acquisition. | ||
| 96 | /// | ||
| 97 | /// The `dma_buf` should be large enough to prevent DMA buffer overrun. | ||
| 98 | /// The length of the `dma_buf` should be a multiple of the ADC channel count. | ||
| 99 | /// For example, if 3 channels are measured, its length can be 3 * 40 = 120 measurements. | ||
| 100 | /// | ||
| 101 | /// `read` method is used to read out measurements from the DMA ring buffer, and its buffer should be exactly half of the `dma_buf` length. | ||
| 102 | /// It is critical to call `read` frequently to prevent DMA buffer overrun. | ||
| 103 | /// | ||
| 104 | /// [`read`]: #method.read | ||
| 105 | pub fn into_ring_buffered(self, dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> RingBufferedAdc<'d, T> { | ||
| 106 | assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); | ||
| 107 | |||
| 108 | let opts: crate::dma::TransferOptions = TransferOptions { | ||
| 109 | half_transfer_ir: true, | ||
| 110 | priority: Priority::VeryHigh, | ||
| 111 | ..Default::default() | ||
| 112 | }; | ||
| 113 | |||
| 114 | // Safety: we forget the struct before this function returns. | ||
| 115 | let rx_src = T::regs().dr().as_ptr() as *mut u16; | ||
| 116 | let request = dma.request(); | ||
| 117 | |||
| 118 | let ring_buf = unsafe { ReadableRingBuffer::new(dma, request, rx_src, dma_buf, opts) }; | ||
| 119 | |||
| 120 | // Don't disable the clock | ||
| 121 | mem::forget(self); | ||
| 122 | |||
| 123 | RingBufferedAdc { | ||
| 124 | _phantom: PhantomData, | ||
| 125 | ring_buf, | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | impl<'d, T: Instance> RingBufferedAdc<'d, T> { | ||
| 131 | fn is_on() -> bool { | ||
| 132 | T::regs().cr2().read().adon() | ||
| 133 | } | ||
| 134 | |||
| 135 | fn stop_adc() { | ||
| 136 | T::regs().cr2().modify(|reg| { | ||
| 137 | reg.set_adon(false); | ||
| 138 | }); | ||
| 139 | } | ||
| 140 | |||
| 141 | fn start_adc() { | ||
| 142 | T::regs().cr2().modify(|reg| { | ||
| 143 | reg.set_adon(true); | ||
| 144 | }); | ||
| 145 | } | ||
| 146 | |||
| 147 | /// Sets the channel sample time | ||
| 148 | /// | ||
| 149 | /// ## SAFETY: | ||
| 150 | /// - ADON == 0 i.e ADC must not be enabled when this is called. | ||
| 151 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { | ||
| 152 | if ch <= 9 { | ||
| 153 | T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time)); | ||
| 154 | } else { | ||
| 155 | T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | fn set_channels_sample_time(&mut self, ch: &[u8], sample_time: SampleTime) { | ||
| 160 | let ch_iter = ch.iter(); | ||
| 161 | for idx in ch_iter { | ||
| 162 | unsafe { | ||
| 163 | Self::set_channel_sample_time(*idx, sample_time); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | pub fn set_sample_sequence( | ||
| 169 | &mut self, | ||
| 170 | sequence: Sequence, | ||
| 171 | channel: &mut impl AdcChannel<T>, | ||
| 172 | sample_time: SampleTime, | ||
| 173 | ) { | ||
| 174 | let was_on = Self::is_on(); | ||
| 175 | if !was_on { | ||
| 176 | Self::start_adc(); | ||
| 177 | } | ||
| 178 | |||
| 179 | // Check the sequence is long enough | ||
| 180 | T::regs().sqr1().modify(|r| { | ||
| 181 | let prev: Sequence = r.l().into(); | ||
| 182 | if prev < sequence { | ||
| 183 | let new_l: Sequence = sequence; | ||
| 184 | trace!("Setting sequence length from {:?} to {:?}", prev as u8, new_l as u8); | ||
| 185 | r.set_l(sequence.into()) | ||
| 186 | } else { | ||
| 187 | r.set_l(prev.into()) | ||
| 188 | } | ||
| 189 | }); | ||
| 190 | |||
| 191 | // Set this GPIO as an analog input. | ||
| 192 | channel.setup(); | ||
| 193 | |||
| 194 | // Set the channel in the right sequence field. | ||
| 195 | match sequence { | ||
| 196 | Sequence::One => T::regs().sqr3().modify(|w| w.set_sq(0, channel.channel())), | ||
| 197 | Sequence::Two => T::regs().sqr3().modify(|w| w.set_sq(1, channel.channel())), | ||
| 198 | Sequence::Three => T::regs().sqr3().modify(|w| w.set_sq(2, channel.channel())), | ||
| 199 | Sequence::Four => T::regs().sqr3().modify(|w| w.set_sq(3, channel.channel())), | ||
| 200 | Sequence::Five => T::regs().sqr3().modify(|w| w.set_sq(4, channel.channel())), | ||
| 201 | Sequence::Six => T::regs().sqr3().modify(|w| w.set_sq(5, channel.channel())), | ||
| 202 | Sequence::Seven => T::regs().sqr2().modify(|w| w.set_sq(0, channel.channel())), | ||
| 203 | Sequence::Eight => T::regs().sqr2().modify(|w| w.set_sq(1, channel.channel())), | ||
| 204 | Sequence::Nine => T::regs().sqr2().modify(|w| w.set_sq(2, channel.channel())), | ||
| 205 | Sequence::Ten => T::regs().sqr2().modify(|w| w.set_sq(3, channel.channel())), | ||
| 206 | Sequence::Eleven => T::regs().sqr2().modify(|w| w.set_sq(4, channel.channel())), | ||
| 207 | Sequence::Twelve => T::regs().sqr2().modify(|w| w.set_sq(5, channel.channel())), | ||
| 208 | Sequence::Thirteen => T::regs().sqr1().modify(|w| w.set_sq(0, channel.channel())), | ||
| 209 | Sequence::Fourteen => T::regs().sqr1().modify(|w| w.set_sq(1, channel.channel())), | ||
| 210 | Sequence::Fifteen => T::regs().sqr1().modify(|w| w.set_sq(2, channel.channel())), | ||
| 211 | Sequence::Sixteen => T::regs().sqr1().modify(|w| w.set_sq(3, channel.channel())), | ||
| 212 | }; | ||
| 213 | |||
| 214 | if !was_on { | ||
| 215 | Self::stop_adc(); | ||
| 216 | } | ||
| 217 | |||
| 218 | self.set_channels_sample_time(&[channel.channel()], sample_time); | ||
| 219 | |||
| 220 | Self::start_adc(); | ||
| 221 | } | ||
| 222 | |||
| 223 | /// Turns on ADC if it is not already turned on and starts continuous DMA transfer. | ||
| 224 | pub fn start(&mut self) -> Result<(), OverrunError> { | ||
| 225 | self.setup_adc(); | ||
| 226 | self.ring_buf.clear(); | ||
| 227 | |||
| 228 | Ok(()) | ||
| 229 | } | ||
| 230 | |||
| 231 | fn stop(&mut self, err: OverrunError) -> Result<usize, OverrunError> { | ||
| 232 | self.teardown_adc(); | ||
| 233 | Err(err) | ||
| 234 | } | ||
| 235 | |||
| 236 | /// Stops DMA transfer. | ||
| 237 | /// It does not turn off ADC. | ||
| 238 | /// Calling `start` restarts continuous DMA transfer. | ||
| 239 | /// | ||
| 240 | /// [`start`]: #method.start | ||
| 241 | pub fn teardown_adc(&mut self) { | ||
| 242 | // Stop the DMA transfer | ||
| 243 | self.ring_buf.request_pause(); | ||
| 244 | |||
| 245 | let r = T::regs(); | ||
| 246 | |||
| 247 | // Stop ADC | ||
| 248 | r.cr2().modify(|reg| { | ||
| 249 | // Stop ADC | ||
| 250 | reg.set_swstart(false); | ||
| 251 | // Stop DMA | ||
| 252 | reg.set_dma(false); | ||
| 253 | }); | ||
| 254 | |||
| 255 | r.cr1().modify(|w| { | ||
| 256 | // Disable interrupt for end of conversion | ||
| 257 | w.set_eocie(false); | ||
| 258 | // Disable interrupt for overrun | ||
| 259 | w.set_ovrie(false); | ||
| 260 | }); | ||
| 261 | |||
| 262 | clear_interrupt_flags(r); | ||
| 263 | |||
| 264 | compiler_fence(Ordering::SeqCst); | ||
| 265 | } | ||
| 266 | |||
| 267 | fn setup_adc(&mut self) { | ||
| 268 | compiler_fence(Ordering::SeqCst); | ||
| 269 | |||
| 270 | self.ring_buf.start(); | ||
| 271 | |||
| 272 | let r = T::regs(); | ||
| 273 | |||
| 274 | // Enable ADC | ||
| 275 | let was_on = Self::is_on(); | ||
| 276 | if !was_on { | ||
| 277 | r.cr2().modify(|reg| { | ||
| 278 | reg.set_adon(false); | ||
| 279 | reg.set_swstart(false); | ||
| 280 | }); | ||
| 281 | } | ||
| 282 | |||
| 283 | // Clear all interrupts | ||
| 284 | r.sr().modify(|regs| { | ||
| 285 | regs.set_eoc(false); | ||
| 286 | regs.set_ovr(false); | ||
| 287 | regs.set_strt(false); | ||
| 288 | }); | ||
| 289 | |||
| 290 | r.cr1().modify(|w| { | ||
| 291 | // Enable interrupt for end of conversion | ||
| 292 | w.set_eocie(true); | ||
| 293 | // Enable interrupt for overrun | ||
| 294 | w.set_ovrie(true); | ||
| 295 | // Scanning converisons of multiple channels | ||
| 296 | w.set_scan(true); | ||
| 297 | // Continuous conversion mode | ||
| 298 | w.set_discen(false); | ||
| 299 | }); | ||
| 300 | |||
| 301 | r.cr2().modify(|w| { | ||
| 302 | // Enable DMA mode | ||
| 303 | w.set_dma(true); | ||
| 304 | // Enable continuous conversions | ||
| 305 | w.set_cont(true); | ||
| 306 | // DMA requests are issues as long as DMA=1 and data are converted. | ||
| 307 | w.set_dds(vals::Dds::CONTINUOUS); | ||
| 308 | // EOC flag is set at the end of each conversion. | ||
| 309 | w.set_eocs(vals::Eocs::EACH_CONVERSION); | ||
| 310 | }); | ||
| 311 | |||
| 312 | // Begin ADC conversions | ||
| 313 | T::regs().cr2().modify(|reg| { | ||
| 314 | reg.set_adon(true); | ||
| 315 | reg.set_swstart(true); | ||
| 316 | }); | ||
| 317 | |||
| 318 | super::blocking_delay_us(3); | ||
| 319 | } | ||
| 320 | |||
| 321 | /// Read bytes that are readily available in the ring buffer. | ||
| 322 | /// If no bytes are currently available in the buffer the call waits until the some | ||
| 323 | /// bytes are available (at least one byte and at most half the buffer size) | ||
| 324 | /// | ||
| 325 | /// Background receive is started if `start()` has not been previously called. | ||
| 326 | /// | ||
| 327 | /// Receive in the background is terminated if an error is returned. | ||
| 328 | /// It must then manually be started again by calling `start()` or by re-calling `read()`. | ||
| 329 | pub fn blocking_read<const N: usize>(&mut self, buf: &mut [u16; N]) -> Result<usize, OverrunError> { | ||
| 330 | let r = T::regs(); | ||
| 331 | |||
| 332 | // Start background receive if it was not already started | ||
| 333 | if !r.cr2().read().dma() { | ||
| 334 | self.start()?; | ||
| 335 | } | ||
| 336 | |||
| 337 | // Clear overrun flag if set. | ||
| 338 | if r.sr().read().ovr() { | ||
| 339 | return self.stop(OverrunError); | ||
| 340 | } | ||
| 341 | |||
| 342 | loop { | ||
| 343 | match self.ring_buf.read(buf) { | ||
| 344 | Ok((0, _)) => {} | ||
| 345 | Ok((len, _)) => { | ||
| 346 | return Ok(len); | ||
| 347 | } | ||
| 348 | Err(_) => { | ||
| 349 | return self.stop(OverrunError); | ||
| 350 | } | ||
| 351 | } | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /// Reads measurements from the DMA ring buffer. | ||
| 356 | /// | ||
| 357 | /// This method fills the provided `measurements` array with ADC readings from the DMA buffer. | ||
| 358 | /// The length of the `measurements` array should be exactly half of the DMA buffer length. Because interrupts are only generated if half or full DMA transfer completes. | ||
| 359 | /// | ||
| 360 | /// Each call to `read` will populate the `measurements` array in the same order as the channels defined with `set_sample_sequence`. | ||
| 361 | /// There will be many sequences worth of measurements in this array because it only returns if at least half of the DMA buffer is filled. | ||
| 362 | /// For example if 3 channels are sampled `measurements` contain: `[sq0 sq1 sq3 sq0 sq1 sq3 sq0 sq1 sq3 sq0 sq1 sq3..]`. | ||
| 363 | /// | ||
| 364 | /// If an error is returned, it indicates a DMA overrun, and the process must be restarted by calling `start` or `read` again. | ||
| 365 | /// | ||
| 366 | /// By default, the ADC fills the DMA buffer as quickly as possible. To control the sample rate, call `teardown_adc` after each readout, and then start the DMA again at the desired interval. | ||
| 367 | /// Note that even if using `teardown_adc` to control the sample rate, with each call to `read`, measurements equivalent to half the size of the DMA buffer are still collected. | ||
| 368 | /// | ||
| 369 | /// Example: | ||
| 370 | /// ```rust,ignore | ||
| 371 | /// const DMA_BUF_LEN: usize = 120; | ||
| 372 | /// let adc_dma_buf = [0u16; DMA_BUF_LEN]; | ||
| 373 | /// let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_dma_buf); | ||
| 374 | /// | ||
| 375 | /// adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112); | ||
| 376 | /// adc.set_sample_sequence(Sequence::Two, &mut p.PA1, SampleTime::CYCLES112); | ||
| 377 | /// adc.set_sample_sequence(Sequence::Three, &mut p.PA2, SampleTime::CYCLES112); | ||
| 378 | /// | ||
| 379 | /// let mut measurements = [0u16; DMA_BUF_LEN / 2]; | ||
| 380 | /// loop { | ||
| 381 | /// match adc.read(&mut measurements).await { | ||
| 382 | /// Ok(_) => { | ||
| 383 | /// defmt::info!("adc1: {}", measurements); | ||
| 384 | /// // Only needed to manually control sample rate. | ||
| 385 | /// adc.teardown_adc(); | ||
| 386 | /// } | ||
| 387 | /// Err(e) => { | ||
| 388 | /// defmt::warn!("Error: {:?}", e); | ||
| 389 | /// // DMA overrun, next call to `read` restarts ADC. | ||
| 390 | /// } | ||
| 391 | /// } | ||
| 392 | /// | ||
| 393 | /// // Manually control sample rate. | ||
| 394 | /// Timer::after_millis(100).await; | ||
| 395 | /// } | ||
| 396 | /// ``` | ||
| 397 | /// | ||
| 398 | /// | ||
| 399 | /// [`set_sample_sequence`]: #method.set_sample_sequence | ||
| 400 | /// [`teardown_adc`]: #method.teardown_adc | ||
| 401 | /// [`start`]: #method.start | ||
| 402 | pub async fn read<const N: usize>(&mut self, measurements: &mut [u16; N]) -> Result<usize, OverrunError> { | ||
| 403 | assert_eq!( | ||
| 404 | self.ring_buf.capacity() / 2, | ||
| 405 | N, | ||
| 406 | "Buffer size must be half the size of the ring buffer" | ||
| 407 | ); | ||
| 408 | |||
| 409 | let r = T::regs(); | ||
| 410 | |||
| 411 | // Start background receive if it was not already started | ||
| 412 | if !r.cr2().read().dma() { | ||
| 413 | self.start()?; | ||
| 414 | } | ||
| 415 | |||
| 416 | // Clear overrun flag if set. | ||
| 417 | if r.sr().read().ovr() { | ||
| 418 | return self.stop(OverrunError); | ||
| 419 | } | ||
| 420 | match self.ring_buf.read_exact(measurements).await { | ||
| 421 | Ok(len) => Ok(len), | ||
| 422 | Err(_) => self.stop(OverrunError), | ||
| 423 | } | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | impl<T: Instance> Drop for RingBufferedAdc<'_, T> { | ||
| 428 | fn drop(&mut self) { | ||
| 429 | self.teardown_adc(); | ||
| 430 | rcc::disable::<T>(); | ||
| 431 | } | ||
| 432 | } | ||
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 93ec78548..90c6294d2 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs | |||
| @@ -1,11 +1,22 @@ | |||
| 1 | use core::mem; | ||
| 2 | use core::sync::atomic::{Ordering, compiler_fence}; | ||
| 3 | |||
| 1 | use super::blocking_delay_us; | 4 | use super::blocking_delay_us; |
| 2 | use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; | 5 | use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel}; |
| 6 | use crate::pac::adc::vals; | ||
| 3 | use crate::peripherals::ADC1; | 7 | use crate::peripherals::ADC1; |
| 4 | use crate::time::Hertz; | 8 | use crate::time::Hertz; |
| 5 | use crate::{Peri, rcc}; | 9 | use crate::{Peri, rcc}; |
| 6 | 10 | ||
| 7 | mod ringbuffered_v2; | 11 | mod ringbuffered; |
| 8 | pub use ringbuffered_v2::{RingBufferedAdc, Sequence}; | 12 | pub use ringbuffered::RingBufferedAdc; |
| 13 | |||
| 14 | fn clear_interrupt_flags(r: crate::pac::adc::Adc) { | ||
| 15 | r.sr().modify(|regs| { | ||
| 16 | regs.set_eoc(false); | ||
| 17 | regs.set_ovr(false); | ||
| 18 | }); | ||
| 19 | } | ||
| 9 | 20 | ||
| 10 | /// Default VREF voltage used for sample conversion to millivolts. | 21 | /// Default VREF voltage used for sample conversion to millivolts. |
| 11 | pub const VREF_DEFAULT_MV: u32 = 3300; | 22 | pub const VREF_DEFAULT_MV: u32 = 3300; |
| @@ -112,6 +123,98 @@ where | |||
| 112 | } | 123 | } |
| 113 | } | 124 | } |
| 114 | 125 | ||
| 126 | /// Configures the ADC to use a DMA ring buffer for continuous data acquisition. | ||
| 127 | /// | ||
| 128 | /// The `dma_buf` should be large enough to prevent DMA buffer overrun. | ||
| 129 | /// The length of the `dma_buf` should be a multiple of the ADC channel count. | ||
| 130 | /// For example, if 3 channels are measured, its length can be 3 * 40 = 120 measurements. | ||
| 131 | /// | ||
| 132 | /// `read` method is used to read out measurements from the DMA ring buffer, and its buffer should be exactly half of the `dma_buf` length. | ||
| 133 | /// It is critical to call `read` frequently to prevent DMA buffer overrun. | ||
| 134 | /// | ||
| 135 | /// [`read`]: #method.read | ||
| 136 | pub fn into_ring_buffered<'a>( | ||
| 137 | self, | ||
| 138 | dma: Peri<'d, impl RxDma<T>>, | ||
| 139 | dma_buf: &'d mut [u16], | ||
| 140 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | ||
| 141 | ) -> RingBufferedAdc<'d, T> { | ||
| 142 | assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); | ||
| 143 | |||
| 144 | T::regs().cr2().modify(|reg| { | ||
| 145 | reg.set_adon(true); | ||
| 146 | }); | ||
| 147 | |||
| 148 | // Check the sequence is long enough | ||
| 149 | T::regs().sqr1().modify(|r| { | ||
| 150 | r.set_l((sequence.len() - 1).try_into().unwrap()); | ||
| 151 | }); | ||
| 152 | |||
| 153 | for (i, (channel, sample_time)) in sequence.enumerate() { | ||
| 154 | // Set this GPIO as an analog input. | ||
| 155 | channel.setup(); | ||
| 156 | |||
| 157 | // Set the channel in the right sequence field. | ||
| 158 | T::regs().sqr3().modify(|w| w.set_sq(i, channel.channel())); | ||
| 159 | |||
| 160 | Self::set_channel_sample_time(channel.channel(), sample_time); | ||
| 161 | } | ||
| 162 | |||
| 163 | compiler_fence(Ordering::SeqCst); | ||
| 164 | |||
| 165 | let r = T::regs(); | ||
| 166 | |||
| 167 | // Clear all interrupts | ||
| 168 | r.sr().modify(|regs| { | ||
| 169 | regs.set_eoc(false); | ||
| 170 | regs.set_ovr(false); | ||
| 171 | regs.set_strt(false); | ||
| 172 | }); | ||
| 173 | |||
| 174 | r.cr1().modify(|w| { | ||
| 175 | // Enable interrupt for end of conversion | ||
| 176 | w.set_eocie(true); | ||
| 177 | // Enable interrupt for overrun | ||
| 178 | w.set_ovrie(true); | ||
| 179 | // Scanning converisons of multiple channels | ||
| 180 | w.set_scan(true); | ||
| 181 | // Continuous conversion mode | ||
| 182 | w.set_discen(false); | ||
| 183 | }); | ||
| 184 | |||
| 185 | r.cr2().modify(|w| { | ||
| 186 | // Enable DMA mode | ||
| 187 | w.set_dma(true); | ||
| 188 | // Enable continuous conversions | ||
| 189 | w.set_cont(true); | ||
| 190 | // DMA requests are issues as long as DMA=1 and data are converted. | ||
| 191 | w.set_dds(vals::Dds::CONTINUOUS); | ||
| 192 | // EOC flag is set at the end of each conversion. | ||
| 193 | w.set_eocs(vals::Eocs::EACH_CONVERSION); | ||
| 194 | }); | ||
| 195 | |||
| 196 | // Don't disable the clock | ||
| 197 | mem::forget(self); | ||
| 198 | |||
| 199 | RingBufferedAdc::new(dma, dma_buf) | ||
| 200 | } | ||
| 201 | |||
| 202 | pub(super) fn start() { | ||
| 203 | // Begin ADC conversions | ||
| 204 | T::regs().cr2().modify(|reg| { | ||
| 205 | reg.set_adon(true); | ||
| 206 | reg.set_swstart(true); | ||
| 207 | }); | ||
| 208 | } | ||
| 209 | |||
| 210 | pub(super) fn stop() { | ||
| 211 | // Stop ADC | ||
| 212 | T::regs().cr2().modify(|reg| { | ||
| 213 | // Stop ADC | ||
| 214 | reg.set_swstart(false); | ||
| 215 | }); | ||
| 216 | } | ||
| 217 | |||
| 115 | pub fn set_sample_time(&mut self, sample_time: SampleTime) { | 218 | pub fn set_sample_time(&mut self, sample_time: SampleTime) { |
| 116 | self.sample_time = sample_time; | 219 | self.sample_time = sample_time; |
| 117 | } | 220 | } |
| @@ -198,6 +301,31 @@ where | |||
| 198 | T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); | 301 | T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); |
| 199 | } | 302 | } |
| 200 | } | 303 | } |
| 304 | |||
| 305 | pub(super) fn teardown_adc() { | ||
| 306 | let r = T::regs(); | ||
| 307 | |||
| 308 | // Stop ADC | ||
| 309 | r.cr2().modify(|reg| { | ||
| 310 | // Stop ADC | ||
| 311 | reg.set_swstart(false); | ||
| 312 | // Stop ADC | ||
| 313 | reg.set_adon(false); | ||
| 314 | // Stop DMA | ||
| 315 | reg.set_dma(false); | ||
| 316 | }); | ||
| 317 | |||
| 318 | r.cr1().modify(|w| { | ||
| 319 | // Disable interrupt for end of conversion | ||
| 320 | w.set_eocie(false); | ||
| 321 | // Disable interrupt for overrun | ||
| 322 | w.set_ovrie(false); | ||
| 323 | }); | ||
| 324 | |||
| 325 | clear_interrupt_flags(r); | ||
| 326 | |||
| 327 | compiler_fence(Ordering::SeqCst); | ||
| 328 | } | ||
| 201 | } | 329 | } |
| 202 | 330 | ||
| 203 | impl<'d, T: Instance> Drop for Adc<'d, T> { | 331 | impl<'d, T: Instance> Drop for Adc<'d, T> { |
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 47632263b..170b08a25 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs | |||
| @@ -12,6 +12,13 @@ pub use pac::adc::vals::{Ovsr, Ovss, Presc}; | |||
| 12 | use super::{ | 12 | use super::{ |
| 13 | Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, | 13 | Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, |
| 14 | }; | 14 | }; |
| 15 | |||
| 16 | #[cfg(any(adc_v3, adc_g0, adc_u0))] | ||
| 17 | mod ringbuffered; | ||
| 18 | |||
| 19 | #[cfg(any(adc_v3, adc_g0, adc_u0))] | ||
| 20 | use ringbuffered::RingBufferedAdc; | ||
| 21 | |||
| 15 | use crate::dma::Transfer; | 22 | use crate::dma::Transfer; |
| 16 | use crate::{Peri, pac, rcc}; | 23 | use crate::{Peri, pac, rcc}; |
| 17 | 24 | ||
| @@ -174,6 +181,38 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 174 | blocking_delay_us(1); | 181 | blocking_delay_us(1); |
| 175 | } | 182 | } |
| 176 | 183 | ||
| 184 | #[cfg(any(adc_v3, adc_g0, adc_u0))] | ||
| 185 | pub(super) fn start() { | ||
| 186 | // Start adc conversion | ||
| 187 | T::regs().cr().modify(|reg| { | ||
| 188 | reg.set_adstart(true); | ||
| 189 | }); | ||
| 190 | } | ||
| 191 | |||
| 192 | #[cfg(any(adc_v3, adc_g0, adc_u0))] | ||
| 193 | pub(super) fn stop() { | ||
| 194 | // Stop adc conversion | ||
| 195 | if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { | ||
| 196 | T::regs().cr().modify(|reg| { | ||
| 197 | reg.set_adstp(true); | ||
| 198 | }); | ||
| 199 | while T::regs().cr().read().adstart() {} | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | #[cfg(any(adc_v3, adc_g0, adc_u0))] | ||
| 204 | pub(super) fn teardown_adc() { | ||
| 205 | //disable dma control | ||
| 206 | #[cfg(not(any(adc_g0, adc_u0)))] | ||
| 207 | T::regs().cfgr().modify(|reg| { | ||
| 208 | reg.set_dmaen(false); | ||
| 209 | }); | ||
| 210 | #[cfg(any(adc_g0, adc_u0))] | ||
| 211 | T::regs().cfgr1().modify(|reg| { | ||
| 212 | reg.set_dmaen(false); | ||
| 213 | }); | ||
| 214 | } | ||
| 215 | |||
| 177 | /// Initialize the ADC leaving any analog clock at reset value. | 216 | /// Initialize the ADC leaving any analog clock at reset value. |
| 178 | /// For G0 and WL, this is the async clock without prescaler. | 217 | /// For G0 and WL, this is the async clock without prescaler. |
| 179 | pub fn new(adc: Peri<'d, T>) -> Self { | 218 | pub fn new(adc: Peri<'d, T>) -> Self { |
| @@ -423,6 +462,9 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 423 | "Asynchronous read sequence cannot be more than 16 in length" | 462 | "Asynchronous read sequence cannot be more than 16 in length" |
| 424 | ); | 463 | ); |
| 425 | 464 | ||
| 465 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 466 | let _device_busy = crate::low_power::DeviceBusy::new_stop1(); | ||
| 467 | |||
| 426 | // Ensure no conversions are ongoing and ADC is enabled. | 468 | // Ensure no conversions are ongoing and ADC is enabled. |
| 427 | Self::cancel_conversions(); | 469 | Self::cancel_conversions(); |
| 428 | self.enable(); | 470 | self.enable(); |
| @@ -559,6 +601,137 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 559 | }); | 601 | }); |
| 560 | } | 602 | } |
| 561 | 603 | ||
| 604 | /// Configures the ADC to use a DMA ring buffer for continuous data acquisition. | ||
| 605 | /// | ||
| 606 | /// The `dma_buf` should be large enough to prevent DMA buffer overrun. | ||
| 607 | /// The length of the `dma_buf` should be a multiple of the ADC channel count. | ||
| 608 | /// For example, if 3 channels are measured, its length can be 3 * 40 = 120 measurements. | ||
| 609 | /// | ||
| 610 | /// `read` method is used to read out measurements from the DMA ring buffer, and its buffer should be exactly half of the `dma_buf` length. | ||
| 611 | /// It is critical to call `read` frequently to prevent DMA buffer overrun. | ||
| 612 | /// | ||
| 613 | /// [`read`]: #method.read | ||
| 614 | #[cfg(any(adc_v3, adc_g0, adc_u0))] | ||
| 615 | pub fn into_ring_buffered<'a>( | ||
| 616 | &mut self, | ||
| 617 | dma: Peri<'a, impl RxDma<T>>, | ||
| 618 | dma_buf: &'a mut [u16], | ||
| 619 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | ||
| 620 | ) -> RingBufferedAdc<'a, T> { | ||
| 621 | assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); | ||
| 622 | assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); | ||
| 623 | assert!( | ||
| 624 | sequence.len() <= 16, | ||
| 625 | "Asynchronous read sequence cannot be more than 16 in length" | ||
| 626 | ); | ||
| 627 | // reset conversions and enable the adc | ||
| 628 | Self::cancel_conversions(); | ||
| 629 | self.enable(); | ||
| 630 | |||
| 631 | //adc side setup | ||
| 632 | |||
| 633 | // Set sequence length | ||
| 634 | #[cfg(not(any(adc_g0, adc_u0)))] | ||
| 635 | T::regs().sqr1().modify(|w| { | ||
| 636 | w.set_l(sequence.len() as u8 - 1); | ||
| 637 | }); | ||
| 638 | |||
| 639 | #[cfg(adc_g0)] | ||
| 640 | { | ||
| 641 | let mut sample_times = Vec::<SampleTime, SAMPLE_TIMES_CAPACITY>::new(); | ||
| 642 | |||
| 643 | T::regs().chselr().write(|chselr| { | ||
| 644 | T::regs().smpr().write(|smpr| { | ||
| 645 | for (channel, sample_time) in sequence { | ||
| 646 | chselr.set_chsel(channel.channel.into(), true); | ||
| 647 | if let Some(i) = sample_times.iter().position(|&t| t == sample_time) { | ||
| 648 | smpr.set_smpsel(channel.channel.into(), (i as u8).into()); | ||
| 649 | } else { | ||
| 650 | smpr.set_sample_time(sample_times.len(), sample_time); | ||
| 651 | if let Err(_) = sample_times.push(sample_time) { | ||
| 652 | panic!( | ||
| 653 | "Implementation is limited to {} unique sample times among all channels.", | ||
| 654 | SAMPLE_TIMES_CAPACITY | ||
| 655 | ); | ||
| 656 | } | ||
| 657 | } | ||
| 658 | } | ||
| 659 | }) | ||
| 660 | }); | ||
| 661 | } | ||
| 662 | #[cfg(not(adc_g0))] | ||
| 663 | { | ||
| 664 | #[cfg(adc_u0)] | ||
| 665 | let mut channel_mask = 0; | ||
| 666 | |||
| 667 | // Configure channels and ranks | ||
| 668 | for (_i, (channel, sample_time)) in sequence.enumerate() { | ||
| 669 | Self::configure_channel(channel, sample_time); | ||
| 670 | |||
| 671 | // Each channel is sampled according to sequence | ||
| 672 | #[cfg(not(any(adc_g0, adc_u0)))] | ||
| 673 | match _i { | ||
| 674 | 0..=3 => { | ||
| 675 | T::regs().sqr1().modify(|w| { | ||
| 676 | w.set_sq(_i, channel.channel()); | ||
| 677 | }); | ||
| 678 | } | ||
| 679 | 4..=8 => { | ||
| 680 | T::regs().sqr2().modify(|w| { | ||
| 681 | w.set_sq(_i - 4, channel.channel()); | ||
| 682 | }); | ||
| 683 | } | ||
| 684 | 9..=13 => { | ||
| 685 | T::regs().sqr3().modify(|w| { | ||
| 686 | w.set_sq(_i - 9, channel.channel()); | ||
| 687 | }); | ||
| 688 | } | ||
| 689 | 14..=15 => { | ||
| 690 | T::regs().sqr4().modify(|w| { | ||
| 691 | w.set_sq(_i - 14, channel.channel()); | ||
| 692 | }); | ||
| 693 | } | ||
| 694 | _ => unreachable!(), | ||
| 695 | } | ||
| 696 | |||
| 697 | #[cfg(adc_u0)] | ||
| 698 | { | ||
| 699 | channel_mask |= 1 << channel.channel(); | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | // On G0 and U0 enabled channels are sampled from 0 to last channel. | ||
| 704 | // It is possible to add up to 8 sequences if CHSELRMOD = 1. | ||
| 705 | // However for supporting more than 8 channels alternative CHSELRMOD = 0 approach is used. | ||
| 706 | #[cfg(adc_u0)] | ||
| 707 | T::regs().chselr().modify(|reg| { | ||
| 708 | reg.set_chsel(channel_mask); | ||
| 709 | }); | ||
| 710 | } | ||
| 711 | // Set continuous mode with Circular dma. | ||
| 712 | // Clear overrun flag before starting transfer. | ||
| 713 | T::regs().isr().modify(|reg| { | ||
| 714 | reg.set_ovr(true); | ||
| 715 | }); | ||
| 716 | |||
| 717 | #[cfg(not(any(adc_g0, adc_u0)))] | ||
| 718 | T::regs().cfgr().modify(|reg| { | ||
| 719 | reg.set_discen(false); | ||
| 720 | reg.set_cont(true); | ||
| 721 | reg.set_dmacfg(Dmacfg::CIRCULAR); | ||
| 722 | reg.set_dmaen(true); | ||
| 723 | }); | ||
| 724 | #[cfg(any(adc_g0, adc_u0))] | ||
| 725 | T::regs().cfgr1().modify(|reg| { | ||
| 726 | reg.set_discen(false); | ||
| 727 | reg.set_cont(true); | ||
| 728 | reg.set_dmacfg(Dmacfg::CIRCULAR); | ||
| 729 | reg.set_dmaen(true); | ||
| 730 | }); | ||
| 731 | |||
| 732 | RingBufferedAdc::new(dma, dma_buf) | ||
| 733 | } | ||
| 734 | |||
| 562 | #[cfg(not(adc_g0))] | 735 | #[cfg(not(adc_g0))] |
| 563 | fn configure_channel(channel: &mut impl AdcChannel<T>, sample_time: SampleTime) { | 736 | fn configure_channel(channel: &mut impl AdcChannel<T>, sample_time: SampleTime) { |
| 564 | // RM0492, RM0481, etc. | 737 | // RM0492, RM0481, etc. |
diff --git a/embassy-stm32/src/backup_sram.rs b/embassy-stm32/src/backup_sram.rs new file mode 100644 index 000000000..31b373c6c --- /dev/null +++ b/embassy-stm32/src/backup_sram.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | //! Battary backed SRAM | ||
| 2 | |||
| 3 | use core::slice; | ||
| 4 | |||
| 5 | use embassy_hal_internal::Peri; | ||
| 6 | |||
| 7 | use crate::_generated::{BKPSRAM_BASE, BKPSRAM_SIZE}; | ||
| 8 | use crate::peripherals::BKPSRAM; | ||
| 9 | |||
| 10 | /// Struct used to initilize backup sram | ||
| 11 | pub struct BackupMemory {} | ||
| 12 | |||
| 13 | impl BackupMemory { | ||
| 14 | /// Setup battery backed sram | ||
| 15 | /// | ||
| 16 | /// Returns slice to sram and whether the sram was retained | ||
| 17 | pub fn new(_backup_sram: Peri<'static, BKPSRAM>) -> (&'static mut [u8], bool) { | ||
| 18 | // Assert bksram has been enabled in rcc | ||
| 19 | assert!(crate::pac::PWR.bdcr().read().bren() == crate::pac::pwr::vals::Retention::PRESERVED); | ||
| 20 | |||
| 21 | unsafe { | ||
| 22 | ( | ||
| 23 | slice::from_raw_parts_mut(BKPSRAM_BASE as *mut u8, BKPSRAM_SIZE), | ||
| 24 | critical_section::with(|_| crate::rcc::BKSRAM_RETAINED), | ||
| 25 | ) | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/embassy-stm32/src/can/fd/config.rs b/embassy-stm32/src/can/fd/config.rs index e08349f02..4fe634ce4 100644 --- a/embassy-stm32/src/can/fd/config.rs +++ b/embassy-stm32/src/can/fd/config.rs | |||
| @@ -360,6 +360,8 @@ pub struct FdCanConfig { | |||
| 360 | pub global_filter: GlobalFilter, | 360 | pub global_filter: GlobalFilter, |
| 361 | /// TX buffer mode (FIFO or priority queue) | 361 | /// TX buffer mode (FIFO or priority queue) |
| 362 | pub tx_buffer_mode: TxBufferMode, | 362 | pub tx_buffer_mode: TxBufferMode, |
| 363 | /// Automatic recovery from bus off state | ||
| 364 | pub automatic_bus_off_recovery: bool, | ||
| 363 | } | 365 | } |
| 364 | 366 | ||
| 365 | impl FdCanConfig { | 367 | impl FdCanConfig { |
| @@ -456,6 +458,16 @@ impl FdCanConfig { | |||
| 456 | self.tx_buffer_mode = txbm; | 458 | self.tx_buffer_mode = txbm; |
| 457 | self | 459 | self |
| 458 | } | 460 | } |
| 461 | |||
| 462 | /// Enables or disables automatic recovery from bus off state | ||
| 463 | /// | ||
| 464 | /// Automatic recovery is performed by clearing the INIT bit in the CCCR register if | ||
| 465 | /// the BO bit is active in the IR register in the IT0 interrupt. | ||
| 466 | #[inline] | ||
| 467 | pub const fn set_automatic_bus_off_recovery(mut self, enabled: bool) -> Self { | ||
| 468 | self.automatic_bus_off_recovery = enabled; | ||
| 469 | self | ||
| 470 | } | ||
| 459 | } | 471 | } |
| 460 | 472 | ||
| 461 | impl Default for FdCanConfig { | 473 | impl Default for FdCanConfig { |
| @@ -474,6 +486,7 @@ impl Default for FdCanConfig { | |||
| 474 | timestamp_source: TimestampSource::None, | 486 | timestamp_source: TimestampSource::None, |
| 475 | global_filter: GlobalFilter::default(), | 487 | global_filter: GlobalFilter::default(), |
| 476 | tx_buffer_mode: TxBufferMode::Priority, | 488 | tx_buffer_mode: TxBufferMode::Priority, |
| 489 | automatic_bus_off_recovery: true, | ||
| 477 | } | 490 | } |
| 478 | } | 491 | } |
| 479 | } | 492 | } |
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index a142a6d63..9883aff57 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs | |||
| @@ -53,7 +53,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup | |||
| 53 | regs.ir().write(|w| w.set_tefn(true)); | 53 | regs.ir().write(|w| w.set_tefn(true)); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | T::info().state.lock(|s| { | 56 | let recover_from_bo = T::info().state.lock(|s| { |
| 57 | let state = s.borrow_mut(); | 57 | let state = s.borrow_mut(); |
| 58 | match &state.tx_mode { | 58 | match &state.tx_mode { |
| 59 | TxMode::NonBuffered(waker) => waker.wake(), | 59 | TxMode::NonBuffered(waker) => waker.wake(), |
| @@ -85,11 +85,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup | |||
| 85 | if ir.rfn(1) { | 85 | if ir.rfn(1) { |
| 86 | state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick); | 86 | state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick); |
| 87 | } | 87 | } |
| 88 | |||
| 89 | state.automatic_bus_off_recovery | ||
| 88 | }); | 90 | }); |
| 89 | 91 | ||
| 90 | if ir.bo() { | 92 | if ir.bo() { |
| 91 | regs.ir().write(|w| w.set_bo(true)); | 93 | regs.ir().write(|w| w.set_bo(true)); |
| 92 | if regs.psr().read().bo() { | 94 | if let Some(true) = recover_from_bo |
| 95 | && regs.psr().read().bo() | ||
| 96 | { | ||
| 93 | // Initiate bus-off recovery sequence by resetting CCCR.INIT | 97 | // Initiate bus-off recovery sequence by resetting CCCR.INIT |
| 94 | regs.cccr().modify(|w| w.set_init(false)); | 98 | regs.cccr().modify(|w| w.set_init(false)); |
| 95 | } | 99 | } |
| @@ -263,7 +267,9 @@ impl<'d> CanConfigurator<'d> { | |||
| 263 | pub fn start(self, mode: OperatingMode) -> Can<'d> { | 267 | pub fn start(self, mode: OperatingMode) -> Can<'d> { |
| 264 | let ns_per_timer_tick = calc_ns_per_timer_tick(&self.info, self.periph_clock, self.config.frame_transmit); | 268 | let ns_per_timer_tick = calc_ns_per_timer_tick(&self.info, self.periph_clock, self.config.frame_transmit); |
| 265 | self.info.state.lock(|s| { | 269 | self.info.state.lock(|s| { |
| 266 | s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick; | 270 | let mut state = s.borrow_mut(); |
| 271 | state.ns_per_timer_tick = ns_per_timer_tick; | ||
| 272 | state.automatic_bus_off_recovery = Some(self.config.automatic_bus_off_recovery); | ||
| 267 | }); | 273 | }); |
| 268 | self.info.regs.into_mode(self.config, mode); | 274 | self.info.regs.into_mode(self.config, mode); |
| 269 | Can { | 275 | Can { |
| @@ -861,7 +867,7 @@ struct State { | |||
| 861 | sender_instance_count: usize, | 867 | sender_instance_count: usize, |
| 862 | tx_pin_port: Option<u8>, | 868 | tx_pin_port: Option<u8>, |
| 863 | rx_pin_port: Option<u8>, | 869 | rx_pin_port: Option<u8>, |
| 864 | 870 | automatic_bus_off_recovery: Option<bool>, // controlled by CanConfigurator::start() | |
| 865 | pub err_waker: AtomicWaker, | 871 | pub err_waker: AtomicWaker, |
| 866 | } | 872 | } |
| 867 | 873 | ||
| @@ -876,6 +882,7 @@ impl State { | |||
| 876 | sender_instance_count: 0, | 882 | sender_instance_count: 0, |
| 877 | tx_pin_port: None, | 883 | tx_pin_port: None, |
| 878 | rx_pin_port: None, | 884 | rx_pin_port: None, |
| 885 | automatic_bus_off_recovery: None, | ||
| 879 | } | 886 | } |
| 880 | } | 887 | } |
| 881 | } | 888 | } |
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs index fd1682d2b..59a2cbcdb 100644 --- a/embassy-stm32/src/dsihost.rs +++ b/embassy-stm32/src/dsihost.rs | |||
| @@ -121,17 +121,15 @@ impl<'d, T: Instance> DsiHost<'d, T> { | |||
| 121 | 121 | ||
| 122 | /// DCS or Generic short/long write command | 122 | /// DCS or Generic short/long write command |
| 123 | pub fn write_cmd(&mut self, channel_id: u8, address: u8, data: &[u8]) -> Result<(), Error> { | 123 | pub fn write_cmd(&mut self, channel_id: u8, address: u8, data: &[u8]) -> Result<(), Error> { |
| 124 | assert!(data.len() > 0); | 124 | match data.len() { |
| 125 | 125 | 0 => self.short_write(channel_id, PacketType::DcsShortPktWriteP0, address, 0), | |
| 126 | if data.len() == 1 { | 126 | 1 => self.short_write(channel_id, PacketType::DcsShortPktWriteP1, address, data[0]), |
| 127 | self.short_write(channel_id, PacketType::DcsShortPktWriteP1, address, data[0]) | 127 | _ => self.long_write( |
| 128 | } else { | ||
| 129 | self.long_write( | ||
| 130 | channel_id, | 128 | channel_id, |
| 131 | PacketType::DcsLongPktWrite, // FIXME: This might be a generic long packet, as well... | 129 | PacketType::DcsLongPktWrite, // FIXME: This might be a generic long packet, as well... |
| 132 | address, | 130 | address, |
| 133 | data, | 131 | data, |
| 134 | ) | 132 | ), |
| 135 | } | 133 | } |
| 136 | } | 134 | } |
| 137 | 135 | ||
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 12600d4eb..2f5c3406a 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -71,7 +71,7 @@ unsafe fn on_irq() { | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | #[cfg(feature = "low-power")] | 73 | #[cfg(feature = "low-power")] |
| 74 | crate::low_power::on_wakeup_irq(); | 74 | crate::low_power::Executor::on_wakeup_irq(); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | struct BitIter(u32); | 77 | struct BitIter(u32); |
diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs index cd23cda5c..b3281f2d5 100644 --- a/embassy-stm32/src/flash/l.rs +++ b/embassy-stm32/src/flash/l.rs | |||
| @@ -96,14 +96,20 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E | |||
| 96 | #[cfg(any(flash_wl, flash_wb, flash_l4, flash_l5))] | 96 | #[cfg(any(flash_wl, flash_wb, flash_l4, flash_l5))] |
| 97 | { | 97 | { |
| 98 | let idx = (sector.start - super::FLASH_BASE as u32) / super::BANK1_REGION.erase_size as u32; | 98 | let idx = (sector.start - super::FLASH_BASE as u32) / super::BANK1_REGION.erase_size as u32; |
| 99 | #[cfg(any(flash_l4, flash_l5))] | ||
| 100 | let pgn = super::BANK1_REGION.size as u32 / super::BANK1_REGION.erase_size as u32; | ||
| 99 | 101 | ||
| 100 | #[cfg(flash_l4)] | 102 | #[cfg(flash_l4)] |
| 101 | let (idx, bank) = if idx > 255 { (idx - 256, true) } else { (idx, false) }; | 103 | let (idx, bank) = if idx > (pgn - 1) { |
| 104 | (idx - pgn, true) | ||
| 105 | } else { | ||
| 106 | (idx, false) | ||
| 107 | }; | ||
| 102 | 108 | ||
| 103 | #[cfg(flash_l5)] | 109 | #[cfg(flash_l5)] |
| 104 | let (idx, bank) = if pac::FLASH.optr().read().dbank() { | 110 | let (idx, bank) = if pac::FLASH.optr().read().dbank() { |
| 105 | if idx > 255 { | 111 | if idx > (pgn - 1) { |
| 106 | (idx - 256, Some(true)) | 112 | (idx - pgn, Some(true)) |
| 107 | } else { | 113 | } else { |
| 108 | (idx, Some(false)) | 114 | (idx, Some(false)) |
| 109 | } | 115 | } |
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 8ecfbc522..a7c6c90bb 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs | |||
| @@ -236,6 +236,42 @@ impl<'d, T: Instance> Fmc<'d, T> { | |||
| 236 | (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin) | 236 | (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin) |
| 237 | ] | 237 | ] |
| 238 | )); | 238 | )); |
| 239 | |||
| 240 | fmc_sdram_constructor!(sdram_a13bits_d16bits_4banks_bank1: ( | ||
| 241 | bank: stm32_fmc::SdramTargetBank::Bank1, | ||
| 242 | addr: [ | ||
| 243 | (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin), (a12: A12Pin) | ||
| 244 | ], | ||
| 245 | ba: [(ba0: BA0Pin), (ba1: BA1Pin)], | ||
| 246 | d: [ | ||
| 247 | (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin), | ||
| 248 | (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin) | ||
| 249 | ], | ||
| 250 | nbl: [ | ||
| 251 | (nbl0: NBL0Pin), (nbl1: NBL1Pin) | ||
| 252 | ], | ||
| 253 | ctrl: [ | ||
| 254 | (sdcke: SDCKE0Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE0Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin) | ||
| 255 | ] | ||
| 256 | )); | ||
| 257 | |||
| 258 | fmc_sdram_constructor!(sdram_a13bits_d16bits_4banks_bank2: ( | ||
| 259 | bank: stm32_fmc::SdramTargetBank::Bank2, | ||
| 260 | addr: [ | ||
| 261 | (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin), (a12: A12Pin) | ||
| 262 | ], | ||
| 263 | ba: [(ba0: BA0Pin), (ba1: BA1Pin)], | ||
| 264 | d: [ | ||
| 265 | (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin), | ||
| 266 | (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin) | ||
| 267 | ], | ||
| 268 | nbl: [ | ||
| 269 | (nbl0: NBL0Pin), (nbl1: NBL1Pin) | ||
| 270 | ], | ||
| 271 | ctrl: [ | ||
| 272 | (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin) | ||
| 273 | ] | ||
| 274 | )); | ||
| 239 | } | 275 | } |
| 240 | 276 | ||
| 241 | trait SealedInstance: crate::rcc::RccPeripheral { | 277 | trait SealedInstance: crate::rcc::RccPeripheral { |
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index 6fece5eb2..6c6807479 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs | |||
| @@ -10,6 +10,7 @@ pub use traits::Instance; | |||
| 10 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 10 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; |
| 11 | use crate::rcc; | 11 | use crate::rcc; |
| 12 | use crate::time::Hertz; | 12 | use crate::time::Hertz; |
| 13 | pub use crate::timer::simple_pwm::PwmPinConfig; | ||
| 13 | 14 | ||
| 14 | /// HRTIM burst controller instance. | 15 | /// HRTIM burst controller instance. |
| 15 | pub struct BurstController<T: Instance> { | 16 | pub struct BurstController<T: Instance> { |
| @@ -73,7 +74,7 @@ pub struct ComplementaryPwmPin<'d, T, C> { | |||
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | macro_rules! advanced_channel_impl { | 76 | macro_rules! advanced_channel_impl { |
| 76 | ($new_chx:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => { | 77 | ($new_chx:ident, $new_chx_with_config:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => { |
| 77 | impl<'d, T: Instance> PwmPin<'d, T, $channel<T>> { | 78 | impl<'d, T: Instance> PwmPin<'d, T, $channel<T>> { |
| 78 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] | 79 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] |
| 79 | pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self { | 80 | pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self { |
| @@ -86,6 +87,21 @@ macro_rules! advanced_channel_impl { | |||
| 86 | phantom: PhantomData, | 87 | phantom: PhantomData, |
| 87 | } | 88 | } |
| 88 | } | 89 | } |
| 90 | |||
| 91 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with a specific configuration.")] | ||
| 92 | pub fn $new_chx_with_config( | ||
| 93 | pin: Peri<'d, impl $pin_trait<T>>, | ||
| 94 | pin_config: PwmPinConfig, | ||
| 95 | ) -> Self { | ||
| 96 | critical_section::with(|_| { | ||
| 97 | pin.set_low(); | ||
| 98 | set_as_af!(pin, AfType::output(pin_config.output_type, pin_config.speed)); | ||
| 99 | }); | ||
| 100 | PwmPin { | ||
| 101 | _pin: pin.into(), | ||
| 102 | phantom: PhantomData, | ||
| 103 | } | ||
| 104 | } | ||
| 89 | } | 105 | } |
| 90 | 106 | ||
| 91 | impl<'d, T: Instance> ComplementaryPwmPin<'d, T, $channel<T>> { | 107 | impl<'d, T: Instance> ComplementaryPwmPin<'d, T, $channel<T>> { |
| @@ -100,6 +116,21 @@ macro_rules! advanced_channel_impl { | |||
| 100 | phantom: PhantomData, | 116 | phantom: PhantomData, |
| 101 | } | 117 | } |
| 102 | } | 118 | } |
| 119 | |||
| 120 | #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance with a specific configuration.")] | ||
| 121 | pub fn $new_chx_with_config( | ||
| 122 | pin: Peri<'d, impl $complementary_pin_trait<T>>, | ||
| 123 | pin_config: PwmPinConfig, | ||
| 124 | ) -> Self { | ||
| 125 | critical_section::with(|_| { | ||
| 126 | pin.set_low(); | ||
| 127 | set_as_af!(pin, AfType::output(pin_config.output_type, pin_config.speed)); | ||
| 128 | }); | ||
| 129 | ComplementaryPwmPin { | ||
| 130 | _pin: pin.into(), | ||
| 131 | phantom: PhantomData, | ||
| 132 | } | ||
| 133 | } | ||
| 103 | } | 134 | } |
| 104 | 135 | ||
| 105 | impl<T: Instance> SealedAdvancedChannel<T> for $channel<T> { | 136 | impl<T: Instance> SealedAdvancedChannel<T> for $channel<T> { |
| @@ -111,13 +142,55 @@ macro_rules! advanced_channel_impl { | |||
| 111 | }; | 142 | }; |
| 112 | } | 143 | } |
| 113 | 144 | ||
| 114 | advanced_channel_impl!(new_cha, ChA, 0, ChannelAPin, ChannelAComplementaryPin); | 145 | advanced_channel_impl!( |
| 115 | advanced_channel_impl!(new_chb, ChB, 1, ChannelBPin, ChannelBComplementaryPin); | 146 | new_cha, |
| 116 | advanced_channel_impl!(new_chc, ChC, 2, ChannelCPin, ChannelCComplementaryPin); | 147 | new_cha_with_config, |
| 117 | advanced_channel_impl!(new_chd, ChD, 3, ChannelDPin, ChannelDComplementaryPin); | 148 | ChA, |
| 118 | advanced_channel_impl!(new_che, ChE, 4, ChannelEPin, ChannelEComplementaryPin); | 149 | 0, |
| 150 | ChannelAPin, | ||
| 151 | ChannelAComplementaryPin | ||
| 152 | ); | ||
| 153 | advanced_channel_impl!( | ||
| 154 | new_chb, | ||
| 155 | new_chb_with_config, | ||
| 156 | ChB, | ||
| 157 | 1, | ||
| 158 | ChannelBPin, | ||
| 159 | ChannelBComplementaryPin | ||
| 160 | ); | ||
| 161 | advanced_channel_impl!( | ||
| 162 | new_chc, | ||
| 163 | new_chc_with_config, | ||
| 164 | ChC, | ||
| 165 | 2, | ||
| 166 | ChannelCPin, | ||
| 167 | ChannelCComplementaryPin | ||
| 168 | ); | ||
| 169 | advanced_channel_impl!( | ||
| 170 | new_chd, | ||
| 171 | new_chd_with_config, | ||
| 172 | ChD, | ||
| 173 | 3, | ||
| 174 | ChannelDPin, | ||
| 175 | ChannelDComplementaryPin | ||
| 176 | ); | ||
| 177 | advanced_channel_impl!( | ||
| 178 | new_che, | ||
| 179 | new_che_with_config, | ||
| 180 | ChE, | ||
| 181 | 4, | ||
| 182 | ChannelEPin, | ||
| 183 | ChannelEComplementaryPin | ||
| 184 | ); | ||
| 119 | #[cfg(hrtim_v2)] | 185 | #[cfg(hrtim_v2)] |
| 120 | advanced_channel_impl!(new_chf, ChF, 5, ChannelFPin, ChannelFComplementaryPin); | 186 | advanced_channel_impl!( |
| 187 | new_chf, | ||
| 188 | new_chf_with_config, | ||
| 189 | ChF, | ||
| 190 | 5, | ||
| 191 | ChannelFPin, | ||
| 192 | ChannelFComplementaryPin | ||
| 193 | ); | ||
| 121 | 194 | ||
| 122 | /// Struct used to divide a high resolution timer into multiple channels | 195 | /// Struct used to divide a high resolution timer into multiple channels |
| 123 | pub struct AdvancedPwm<'d, T: Instance> { | 196 | pub struct AdvancedPwm<'d, T: Instance> { |
diff --git a/embassy-stm32/src/i2c/config.rs b/embassy-stm32/src/i2c/config.rs index 4e3b736c7..74fac14b2 100644 --- a/embassy-stm32/src/i2c/config.rs +++ b/embassy-stm32/src/i2c/config.rs | |||
| @@ -4,7 +4,7 @@ use crate::gpio::{AfType, OutputType, Speed}; | |||
| 4 | use crate::time::Hertz; | 4 | use crate::time::Hertz; |
| 5 | 5 | ||
| 6 | #[repr(u8)] | 6 | #[repr(u8)] |
| 7 | #[derive(Copy, Clone)] | 7 | #[derive(Debug, Copy, Clone)] |
| 8 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 8 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 9 | /// Bits of the I2C OA2 register to mask out. | 9 | /// Bits of the I2C OA2 register to mask out. |
| 10 | pub enum AddrMask { | 10 | pub enum AddrMask { |
| @@ -60,7 +60,7 @@ impl Address { | |||
| 60 | } | 60 | } |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | #[derive(Copy, Clone)] | 63 | #[derive(Debug, Copy, Clone)] |
| 64 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 64 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 65 | /// The second Own Address register. | 65 | /// The second Own Address register. |
| 66 | pub struct OA2 { | 66 | pub struct OA2 { |
| @@ -70,7 +70,7 @@ pub struct OA2 { | |||
| 70 | pub mask: AddrMask, | 70 | pub mask: AddrMask, |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | #[derive(Copy, Clone)] | 73 | #[derive(Debug, Copy, Clone)] |
| 74 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 74 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 75 | /// The Own Address(es) of the I2C peripheral. | 75 | /// The Own Address(es) of the I2C peripheral. |
| 76 | pub enum OwnAddresses { | 76 | pub enum OwnAddresses { |
| @@ -88,7 +88,7 @@ pub enum OwnAddresses { | |||
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | /// Slave Configuration | 90 | /// Slave Configuration |
| 91 | #[derive(Copy, Clone)] | 91 | #[derive(Debug, Copy, Clone)] |
| 92 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 92 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 93 | pub struct SlaveAddrConfig { | 93 | pub struct SlaveAddrConfig { |
| 94 | /// Target Address(es) | 94 | /// Target Address(es) |
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index f4bf55d34..ee60c3f44 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs | |||
| @@ -219,6 +219,7 @@ impl<'d, M: Mode> I2c<'d, M, Master> { | |||
| 219 | sda, | 219 | sda, |
| 220 | }, | 220 | }, |
| 221 | }; | 221 | }; |
| 222 | |||
| 222 | this.enable_and_init(config); | 223 | this.enable_and_init(config); |
| 223 | 224 | ||
| 224 | this | 225 | this |
| @@ -437,15 +438,15 @@ impl<'d, IM: MasterMode> embedded_hal_async::i2c::I2c for I2c<'d, Async, IM> { | |||
| 437 | 438 | ||
| 438 | /// Frame type in I2C transaction. | 439 | /// Frame type in I2C transaction. |
| 439 | /// | 440 | /// |
| 440 | /// This tells each method what kind of framing to use, to generate a (repeated) start condition (ST | 441 | /// This tells each method what kind of frame to use, to generate a (repeated) start condition (ST |
| 441 | /// or SR), and/or a stop condition (SP). For read operations, this also controls whether to send an | 442 | /// or SR), and/or a stop condition (SP). For read operations, this also controls whether to send an |
| 442 | /// ACK or NACK after the last byte received. | 443 | /// ACK or NACK after the last byte received. |
| 443 | /// | 444 | /// |
| 444 | /// For write operations, the following options are identical because they differ only in the (N)ACK | 445 | /// For write operations, the following options are identical because they differ only in the (N)ACK |
| 445 | /// treatment relevant for read operations: | 446 | /// treatment relevant for read operations: |
| 446 | /// | 447 | /// |
| 447 | /// - `FirstFrame` and `FirstAndNextFrame` | 448 | /// - `FirstFrame` and `FirstAndNextFrame` behave identically for writes |
| 448 | /// - `NextFrame` and `LastFrameNoStop` | 449 | /// - `NextFrame` and `LastFrameNoStop` behave identically for writes |
| 449 | /// | 450 | /// |
| 450 | /// Abbreviations used below: | 451 | /// Abbreviations used below: |
| 451 | /// | 452 | /// |
| @@ -474,7 +475,7 @@ enum FrameOptions { | |||
| 474 | 475 | ||
| 475 | #[allow(dead_code)] | 476 | #[allow(dead_code)] |
| 476 | impl FrameOptions { | 477 | impl FrameOptions { |
| 477 | /// Sends start or repeated start condition before transfer. | 478 | /// Returns true if a start or repeated start condition should be generated before this operation. |
| 478 | fn send_start(self) -> bool { | 479 | fn send_start(self) -> bool { |
| 479 | match self { | 480 | match self { |
| 480 | Self::FirstAndLastFrame | Self::FirstFrame | Self::FirstAndNextFrame => true, | 481 | Self::FirstAndLastFrame | Self::FirstFrame | Self::FirstAndNextFrame => true, |
| @@ -482,7 +483,7 @@ impl FrameOptions { | |||
| 482 | } | 483 | } |
| 483 | } | 484 | } |
| 484 | 485 | ||
| 485 | /// Sends stop condition after transfer. | 486 | /// Returns true if a stop condition should be generated after this operation. |
| 486 | fn send_stop(self) -> bool { | 487 | fn send_stop(self) -> bool { |
| 487 | match self { | 488 | match self { |
| 488 | Self::FirstAndLastFrame | Self::LastFrame => true, | 489 | Self::FirstAndLastFrame | Self::LastFrame => true, |
| @@ -490,7 +491,10 @@ impl FrameOptions { | |||
| 490 | } | 491 | } |
| 491 | } | 492 | } |
| 492 | 493 | ||
| 493 | /// Sends NACK after last byte received, indicating end of read operation. | 494 | /// Returns true if NACK should be sent after the last byte received in a read operation. |
| 495 | /// | ||
| 496 | /// This signals the end of a read sequence and releases the bus for the master's | ||
| 497 | /// next transmission (or stop condition). | ||
| 494 | fn send_nack(self) -> bool { | 498 | fn send_nack(self) -> bool { |
| 495 | match self { | 499 | match self { |
| 496 | Self::FirstAndLastFrame | Self::FirstFrame | Self::LastFrame | Self::LastFrameNoStop => true, | 500 | Self::FirstAndLastFrame | Self::FirstFrame | Self::LastFrame | Self::LastFrameNoStop => true, |
| @@ -499,24 +503,44 @@ impl FrameOptions { | |||
| 499 | } | 503 | } |
| 500 | } | 504 | } |
| 501 | 505 | ||
| 502 | /// Iterates over operations in transaction. | 506 | /// Analyzes I2C transaction operations and assigns appropriate frame to each. |
| 507 | /// | ||
| 508 | /// This function processes a sequence of I2C operations and determines the correct | ||
| 509 | /// frame configuration for each operation to ensure proper I2C protocol compliance. | ||
| 510 | /// It handles the complex logic of: | ||
| 511 | /// | ||
| 512 | /// - Generating start conditions for the first operation of each type (read/write) | ||
| 513 | /// - Generating stop conditions for the final operation in the entire transaction | ||
| 514 | /// - Managing ACK/NACK behavior for read operations, including merging consecutive reads | ||
| 515 | /// - Ensuring proper bus handoff between different operation types | ||
| 516 | /// | ||
| 517 | /// **Transaction Contract Compliance:** | ||
| 518 | /// The frame assignments ensure compliance with the embedded-hal I2C transaction contract, | ||
| 519 | /// where consecutive operations of the same type are logically merged while maintaining | ||
| 520 | /// proper protocol boundaries. | ||
| 503 | /// | 521 | /// |
| 504 | /// Returns necessary frame options for each operation to uphold the [transaction contract] and have | 522 | /// **Error Handling:** |
| 505 | /// the right start/stop/(N)ACK conditions on the wire. | 523 | /// Returns an error if any read operation has an empty buffer, as this would create |
| 524 | /// an invalid I2C transaction that could halt mid-execution. | ||
| 525 | /// | ||
| 526 | /// # Arguments | ||
| 527 | /// * `operations` - Mutable slice of I2C operations from embedded-hal | ||
| 528 | /// | ||
| 529 | /// # Returns | ||
| 530 | /// An iterator over (operation, frame) pairs, or an error if the transaction is invalid | ||
| 506 | /// | 531 | /// |
| 507 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction | ||
| 508 | #[allow(dead_code)] | 532 | #[allow(dead_code)] |
| 509 | fn operation_frames<'a, 'b: 'a>( | 533 | fn operation_frames<'a, 'b: 'a>( |
| 510 | operations: &'a mut [embedded_hal_1::i2c::Operation<'b>], | 534 | operations: &'a mut [embedded_hal_1::i2c::Operation<'b>], |
| 511 | ) -> Result<impl IntoIterator<Item = (&'a mut embedded_hal_1::i2c::Operation<'b>, FrameOptions)>, Error> { | 535 | ) -> Result<impl IntoIterator<Item = (&'a mut embedded_hal_1::i2c::Operation<'b>, FrameOptions)>, Error> { |
| 512 | use embedded_hal_1::i2c::Operation::{Read, Write}; | 536 | use embedded_hal_1::i2c::Operation::{Read, Write}; |
| 513 | 537 | ||
| 514 | // Check empty read buffer before starting transaction. Otherwise, we would risk halting with an | 538 | // Validate that no read operations have empty buffers before starting the transaction. |
| 515 | // error in the middle of the transaction. | 539 | // Empty read operations would risk halting with an error mid-transaction. |
| 516 | // | 540 | // |
| 517 | // In principle, we could allow empty read frames within consecutive read operations, as long as | 541 | // Note: We could theoretically allow empty read operations within consecutive read |
| 518 | // at least one byte remains in the final (merged) read operation, but that makes the logic more | 542 | // sequences as long as the final merged read has at least one byte, but this would |
| 519 | // complicated and error-prone. | 543 | // complicate the logic significantly and create error-prone edge cases. |
| 520 | if operations.iter().any(|op| match op { | 544 | if operations.iter().any(|op| match op { |
| 521 | Read(read) => read.is_empty(), | 545 | Read(read) => read.is_empty(), |
| 522 | Write(_) => false, | 546 | Write(_) => false, |
| @@ -525,46 +549,52 @@ fn operation_frames<'a, 'b: 'a>( | |||
| 525 | } | 549 | } |
| 526 | 550 | ||
| 527 | let mut operations = operations.iter_mut().peekable(); | 551 | let mut operations = operations.iter_mut().peekable(); |
| 528 | 552 | let mut next_first_operation = true; | |
| 529 | let mut next_first_frame = true; | ||
| 530 | 553 | ||
| 531 | Ok(iter::from_fn(move || { | 554 | Ok(iter::from_fn(move || { |
| 532 | let op = operations.next()?; | 555 | let current_op = operations.next()?; |
| 533 | 556 | ||
| 534 | // Is `op` first frame of its type? | 557 | // Determine if this is the first operation of its type (read or write) |
| 535 | let first_frame = next_first_frame; | 558 | let is_first_of_type = next_first_operation; |
| 536 | let next_op = operations.peek(); | 559 | let next_op = operations.peek(); |
| 537 | 560 | ||
| 538 | // Get appropriate frame options as combination of the following properties: | 561 | // Compute the appropriate frame based on three key properties: |
| 539 | // | 562 | // |
| 540 | // - For each first operation of its type, generate a (repeated) start condition. | 563 | // 1. **Start Condition**: Generate (repeated) start for first operation of each type |
| 541 | // - For the last operation overall in the entire transaction, generate a stop condition. | 564 | // 2. **Stop Condition**: Generate stop for the final operation in the entire transaction |
| 542 | // - For read operations, check the next operation: if it is also a read operation, we merge | 565 | // 3. **ACK/NACK for Reads**: For read operations, send ACK if more reads follow in the |
| 543 | // these and send ACK for all bytes in the current operation; send NACK only for the final | 566 | // sequence, or NACK for the final read in a sequence (before write or transaction end) |
| 544 | // read operation's last byte (before write or end of entire transaction) to indicate last | ||
| 545 | // byte read and release the bus for transmission of the bus master's next byte (or stop). | ||
| 546 | // | 567 | // |
| 547 | // We check the third property unconditionally, i.e. even for write opeartions. This is okay | 568 | // The third property is checked for all operations since the resulting frame |
| 548 | // because the resulting frame options are identical for write operations. | 569 | // configurations are identical for write operations regardless of ACK/NACK treatment. |
| 549 | let frame = match (first_frame, next_op) { | 570 | let frame = match (is_first_of_type, next_op) { |
| 571 | // First operation of type, and it's also the final operation overall | ||
| 550 | (true, None) => FrameOptions::FirstAndLastFrame, | 572 | (true, None) => FrameOptions::FirstAndLastFrame, |
| 573 | // First operation of type, next operation is also a read (continue read sequence) | ||
| 551 | (true, Some(Read(_))) => FrameOptions::FirstAndNextFrame, | 574 | (true, Some(Read(_))) => FrameOptions::FirstAndNextFrame, |
| 575 | // First operation of type, next operation is write (end current sequence) | ||
| 552 | (true, Some(Write(_))) => FrameOptions::FirstFrame, | 576 | (true, Some(Write(_))) => FrameOptions::FirstFrame, |
| 553 | // | 577 | |
| 578 | // Continuation operation, and it's the final operation overall | ||
| 554 | (false, None) => FrameOptions::LastFrame, | 579 | (false, None) => FrameOptions::LastFrame, |
| 580 | // Continuation operation, next operation is also a read (continue read sequence) | ||
| 555 | (false, Some(Read(_))) => FrameOptions::NextFrame, | 581 | (false, Some(Read(_))) => FrameOptions::NextFrame, |
| 582 | // Continuation operation, next operation is write (end current sequence, no stop) | ||
| 556 | (false, Some(Write(_))) => FrameOptions::LastFrameNoStop, | 583 | (false, Some(Write(_))) => FrameOptions::LastFrameNoStop, |
| 557 | }; | 584 | }; |
| 558 | 585 | ||
| 559 | // Pre-calculate if `next_op` is the first operation of its type. We do this here and not at | 586 | // Pre-calculate whether the next operation will be the first of its type. |
| 560 | // the beginning of the loop because we hand out `op` as iterator value and cannot access it | 587 | // This is done here because we consume `current_op` as the iterator value |
| 561 | // anymore in the next iteration. | 588 | // and cannot access it in the next iteration. |
| 562 | next_first_frame = match (&op, next_op) { | 589 | next_first_operation = match (¤t_op, next_op) { |
| 590 | // No next operation | ||
| 563 | (_, None) => false, | 591 | (_, None) => false, |
| 592 | // Operation type changes: next will be first of its type | ||
| 564 | (Read(_), Some(Write(_))) | (Write(_), Some(Read(_))) => true, | 593 | (Read(_), Some(Write(_))) | (Write(_), Some(Read(_))) => true, |
| 594 | // Operation type continues: next will not be first of its type | ||
| 565 | (Read(_), Some(Read(_))) | (Write(_), Some(Write(_))) => false, | 595 | (Read(_), Some(Read(_))) | (Write(_), Some(Write(_))) => false, |
| 566 | }; | 596 | }; |
| 567 | 597 | ||
| 568 | Some((op, frame)) | 598 | Some((current_op, frame)) |
| 569 | })) | 599 | })) |
| 570 | } | 600 | } |
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index e6b6c7c42..128a58db7 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -30,6 +30,7 @@ use crate::pac::i2c; | |||
| 30 | // hit a case like this! | 30 | // hit a case like this! |
| 31 | pub unsafe fn on_interrupt<T: Instance>() { | 31 | pub unsafe fn on_interrupt<T: Instance>() { |
| 32 | let regs = T::info().regs; | 32 | let regs = T::info().regs; |
| 33 | trace!("I2C interrupt triggered"); | ||
| 33 | // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of | 34 | // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of |
| 34 | // other stuff, so we wake the task on every interrupt. | 35 | // other stuff, so we wake the task on every interrupt. |
| 35 | T::state().waker.wake(); | 36 | T::state().waker.wake(); |
| @@ -92,6 +93,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 92 | self.info.regs.cr1().modify(|reg| { | 93 | self.info.regs.cr1().modify(|reg| { |
| 93 | reg.set_pe(true); | 94 | reg.set_pe(true); |
| 94 | }); | 95 | }); |
| 96 | trace!("i2c v1 init complete"); | ||
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { | 99 | fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { |
| @@ -151,7 +153,13 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 151 | Ok(sr1) | 153 | Ok(sr1) |
| 152 | } | 154 | } |
| 153 | 155 | ||
| 154 | fn write_bytes(&mut self, addr: u8, bytes: &[u8], timeout: Timeout, frame: FrameOptions) -> Result<(), Error> { | 156 | fn write_bytes( |
| 157 | &mut self, | ||
| 158 | address: u8, | ||
| 159 | write_buffer: &[u8], | ||
| 160 | timeout: Timeout, | ||
| 161 | frame: FrameOptions, | ||
| 162 | ) -> Result<(), Error> { | ||
| 155 | if frame.send_start() { | 163 | if frame.send_start() { |
| 156 | // Send a START condition | 164 | // Send a START condition |
| 157 | 165 | ||
| @@ -170,7 +178,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 170 | } | 178 | } |
| 171 | 179 | ||
| 172 | // Set up current address we're trying to talk to | 180 | // Set up current address we're trying to talk to |
| 173 | self.info.regs.dr().write(|reg| reg.set_dr(addr << 1)); | 181 | self.info.regs.dr().write(|reg| reg.set_dr(address << 1)); |
| 174 | 182 | ||
| 175 | // Wait until address was sent | 183 | // Wait until address was sent |
| 176 | // Wait for the address to be acknowledged | 184 | // Wait for the address to be acknowledged |
| @@ -184,7 +192,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 184 | } | 192 | } |
| 185 | 193 | ||
| 186 | // Send bytes | 194 | // Send bytes |
| 187 | for c in bytes { | 195 | for c in write_buffer { |
| 188 | self.send_byte(*c, timeout)?; | 196 | self.send_byte(*c, timeout)?; |
| 189 | } | 197 | } |
| 190 | 198 | ||
| @@ -236,12 +244,12 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 236 | 244 | ||
| 237 | fn blocking_read_timeout( | 245 | fn blocking_read_timeout( |
| 238 | &mut self, | 246 | &mut self, |
| 239 | addr: u8, | 247 | address: u8, |
| 240 | buffer: &mut [u8], | 248 | read_buffer: &mut [u8], |
| 241 | timeout: Timeout, | 249 | timeout: Timeout, |
| 242 | frame: FrameOptions, | 250 | frame: FrameOptions, |
| 243 | ) -> Result<(), Error> { | 251 | ) -> Result<(), Error> { |
| 244 | let Some((last, buffer)) = buffer.split_last_mut() else { | 252 | let Some((last_byte, read_buffer)) = read_buffer.split_last_mut() else { |
| 245 | return Err(Error::Overrun); | 253 | return Err(Error::Overrun); |
| 246 | }; | 254 | }; |
| 247 | 255 | ||
| @@ -263,7 +271,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 263 | } | 271 | } |
| 264 | 272 | ||
| 265 | // Set up current address we're trying to talk to | 273 | // Set up current address we're trying to talk to |
| 266 | self.info.regs.dr().write(|reg| reg.set_dr((addr << 1) + 1)); | 274 | self.info.regs.dr().write(|reg| reg.set_dr((address << 1) + 1)); |
| 267 | 275 | ||
| 268 | // Wait until address was sent | 276 | // Wait until address was sent |
| 269 | // Wait for the address to be acknowledged | 277 | // Wait for the address to be acknowledged |
| @@ -276,7 +284,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 276 | } | 284 | } |
| 277 | 285 | ||
| 278 | // Receive bytes into buffer | 286 | // Receive bytes into buffer |
| 279 | for c in buffer { | 287 | for c in read_buffer { |
| 280 | *c = self.recv_byte(timeout)?; | 288 | *c = self.recv_byte(timeout)?; |
| 281 | } | 289 | } |
| 282 | 290 | ||
| @@ -291,37 +299,42 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 291 | }); | 299 | }); |
| 292 | 300 | ||
| 293 | // Receive last byte | 301 | // Receive last byte |
| 294 | *last = self.recv_byte(timeout)?; | 302 | *last_byte = self.recv_byte(timeout)?; |
| 295 | 303 | ||
| 296 | // Fallthrough is success | 304 | // Fallthrough is success |
| 297 | Ok(()) | 305 | Ok(()) |
| 298 | } | 306 | } |
| 299 | 307 | ||
| 300 | /// Blocking read. | 308 | /// Blocking read. |
| 301 | pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> { | 309 | pub fn blocking_read(&mut self, address: u8, read_buffer: &mut [u8]) -> Result<(), Error> { |
| 302 | self.blocking_read_timeout(addr, read, self.timeout(), FrameOptions::FirstAndLastFrame) | 310 | self.blocking_read_timeout(address, read_buffer, self.timeout(), FrameOptions::FirstAndLastFrame) |
| 303 | } | 311 | } |
| 304 | 312 | ||
| 305 | /// Blocking write. | 313 | /// Blocking write. |
| 306 | pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> { | 314 | pub fn blocking_write(&mut self, address: u8, write_buffer: &[u8]) -> Result<(), Error> { |
| 307 | self.write_bytes(addr, write, self.timeout(), FrameOptions::FirstAndLastFrame)?; | 315 | self.write_bytes(address, write_buffer, self.timeout(), FrameOptions::FirstAndLastFrame)?; |
| 308 | 316 | ||
| 309 | // Fallthrough is success | 317 | // Fallthrough is success |
| 310 | Ok(()) | 318 | Ok(()) |
| 311 | } | 319 | } |
| 312 | 320 | ||
| 313 | /// Blocking write, restart, read. | 321 | /// Blocking write, restart, read. |
| 314 | pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { | 322 | pub fn blocking_write_read( |
| 323 | &mut self, | ||
| 324 | address: u8, | ||
| 325 | write_buffer: &[u8], | ||
| 326 | read_buffer: &mut [u8], | ||
| 327 | ) -> Result<(), Error> { | ||
| 315 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the | 328 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the |
| 316 | // stop condition below. | 329 | // stop condition below. |
| 317 | if read.is_empty() { | 330 | if read_buffer.is_empty() { |
| 318 | return Err(Error::Overrun); | 331 | return Err(Error::Overrun); |
| 319 | } | 332 | } |
| 320 | 333 | ||
| 321 | let timeout = self.timeout(); | 334 | let timeout = self.timeout(); |
| 322 | 335 | ||
| 323 | self.write_bytes(addr, write, timeout, FrameOptions::FirstFrame)?; | 336 | self.write_bytes(address, write_buffer, timeout, FrameOptions::FirstFrame)?; |
| 324 | self.blocking_read_timeout(addr, read, timeout, FrameOptions::FirstAndLastFrame)?; | 337 | self.blocking_read_timeout(address, read_buffer, timeout, FrameOptions::FirstAndLastFrame)?; |
| 325 | 338 | ||
| 326 | Ok(()) | 339 | Ok(()) |
| 327 | } | 340 | } |
| @@ -331,32 +344,43 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 331 | /// Consecutive operations of same type are merged. See [transaction contract] for details. | 344 | /// Consecutive operations of same type are merged. See [transaction contract] for details. |
| 332 | /// | 345 | /// |
| 333 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction | 346 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction |
| 334 | pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { | 347 | pub fn blocking_transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { |
| 335 | let timeout = self.timeout(); | 348 | let timeout = self.timeout(); |
| 336 | 349 | ||
| 337 | for (op, frame) in operation_frames(operations)? { | 350 | for (op, frame) in operation_frames(operations)? { |
| 338 | match op { | 351 | match op { |
| 339 | Operation::Read(read) => self.blocking_read_timeout(addr, read, timeout, frame)?, | 352 | Operation::Read(read_buffer) => self.blocking_read_timeout(address, read_buffer, timeout, frame)?, |
| 340 | Operation::Write(write) => self.write_bytes(addr, write, timeout, frame)?, | 353 | Operation::Write(write_buffer) => self.write_bytes(address, write_buffer, timeout, frame)?, |
| 341 | } | 354 | } |
| 342 | } | 355 | } |
| 343 | 356 | ||
| 344 | Ok(()) | 357 | Ok(()) |
| 345 | } | 358 | } |
| 346 | 359 | ||
| 347 | // Async | 360 | /// Can be used by both blocking and async implementations |
| 348 | |||
| 349 | #[inline] // pretty sure this should always be inlined | 361 | #[inline] // pretty sure this should always be inlined |
| 350 | fn enable_interrupts(info: &'static Info) -> () { | 362 | fn enable_interrupts(info: &'static Info) { |
| 351 | info.regs.cr2().modify(|w| { | 363 | // The interrupt handler disables interrupts globally, so we need to re-enable them |
| 352 | w.set_iterren(true); | 364 | // This must be done in a critical section to avoid races |
| 353 | w.set_itevten(true); | 365 | critical_section::with(|_| { |
| 366 | info.regs.cr2().modify(|w| { | ||
| 367 | w.set_iterren(true); | ||
| 368 | w.set_itevten(true); | ||
| 369 | }); | ||
| 354 | }); | 370 | }); |
| 355 | } | 371 | } |
| 372 | |||
| 373 | /// Can be used by both blocking and async implementations | ||
| 374 | fn clear_stop_flag(info: &'static Info) { | ||
| 375 | trace!("I2C slave: clearing STOPF flag (v1 sequence)"); | ||
| 376 | // v1 requires: READ SR1 then WRITE CR1 to clear STOPF | ||
| 377 | let _ = info.regs.sr1().read(); | ||
| 378 | info.regs.cr1().modify(|_| {}); // Dummy write to clear STOPF | ||
| 379 | } | ||
| 356 | } | 380 | } |
| 357 | 381 | ||
| 358 | impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | 382 | impl<'d, IM: MasterMode> I2c<'d, Async, IM> { |
| 359 | async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> { | 383 | async fn write_frame(&mut self, address: u8, write_buffer: &[u8], frame: FrameOptions) -> Result<(), Error> { |
| 360 | self.info.regs.cr2().modify(|w| { | 384 | self.info.regs.cr2().modify(|w| { |
| 361 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for | 385 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for |
| 362 | // reception. | 386 | // reception. |
| @@ -439,7 +463,10 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 439 | // this address from the memory after each TxE event. | 463 | // this address from the memory after each TxE event. |
| 440 | let dst = self.info.regs.dr().as_ptr() as *mut u8; | 464 | let dst = self.info.regs.dr().as_ptr() as *mut u8; |
| 441 | 465 | ||
| 442 | self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) | 466 | self.tx_dma |
| 467 | .as_mut() | ||
| 468 | .unwrap() | ||
| 469 | .write(write_buffer, dst, Default::default()) | ||
| 443 | }; | 470 | }; |
| 444 | 471 | ||
| 445 | // Wait for bytes to be sent, or an error to occur. | 472 | // Wait for bytes to be sent, or an error to occur. |
| @@ -501,28 +528,28 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 501 | } | 528 | } |
| 502 | 529 | ||
| 503 | /// Write. | 530 | /// Write. |
| 504 | pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { | 531 | pub async fn write(&mut self, address: u8, write_buffer: &[u8]) -> Result<(), Error> { |
| 505 | self.write_frame(address, write, FrameOptions::FirstAndLastFrame) | 532 | self.write_frame(address, write_buffer, FrameOptions::FirstAndLastFrame) |
| 506 | .await?; | 533 | .await?; |
| 507 | 534 | ||
| 508 | Ok(()) | 535 | Ok(()) |
| 509 | } | 536 | } |
| 510 | 537 | ||
| 511 | /// Read. | 538 | /// Read. |
| 512 | pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { | 539 | pub async fn read(&mut self, address: u8, read_buffer: &mut [u8]) -> Result<(), Error> { |
| 513 | self.read_frame(address, buffer, FrameOptions::FirstAndLastFrame) | 540 | self.read_frame(address, read_buffer, FrameOptions::FirstAndLastFrame) |
| 514 | .await?; | 541 | .await?; |
| 515 | 542 | ||
| 516 | Ok(()) | 543 | Ok(()) |
| 517 | } | 544 | } |
| 518 | 545 | ||
| 519 | async fn read_frame(&mut self, address: u8, buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> { | 546 | async fn read_frame(&mut self, address: u8, read_buffer: &mut [u8], frame: FrameOptions) -> Result<(), Error> { |
| 520 | if buffer.is_empty() { | 547 | if read_buffer.is_empty() { |
| 521 | return Err(Error::Overrun); | 548 | return Err(Error::Overrun); |
| 522 | } | 549 | } |
| 523 | 550 | ||
| 524 | // Some branches below depend on whether the buffer contains only a single byte. | 551 | // Some branches below depend on whether the buffer contains only a single byte. |
| 525 | let single_byte = buffer.len() == 1; | 552 | let single_byte = read_buffer.len() == 1; |
| 526 | 553 | ||
| 527 | self.info.regs.cr2().modify(|w| { | 554 | self.info.regs.cr2().modify(|w| { |
| 528 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for | 555 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for |
| @@ -612,7 +639,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 612 | self.info.regs.sr2().read(); | 639 | self.info.regs.sr2().read(); |
| 613 | } else { | 640 | } else { |
| 614 | // Before starting reception of single byte (but without START condition, i.e. in case | 641 | // Before starting reception of single byte (but without START condition, i.e. in case |
| 615 | // of continued frame), program NACK to emit at end of this byte. | 642 | // of merged operations), program NACK to emit at end of this byte. |
| 616 | if frame.send_nack() && single_byte { | 643 | if frame.send_nack() && single_byte { |
| 617 | self.info.regs.cr1().modify(|w| { | 644 | self.info.regs.cr1().modify(|w| { |
| 618 | w.set_ack(false); | 645 | w.set_ack(false); |
| @@ -634,7 +661,7 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 634 | // from this address from the memory after each RxE event. | 661 | // from this address from the memory after each RxE event. |
| 635 | let src = self.info.regs.dr().as_ptr() as *mut u8; | 662 | let src = self.info.regs.dr().as_ptr() as *mut u8; |
| 636 | 663 | ||
| 637 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) | 664 | self.rx_dma.as_mut().unwrap().read(src, read_buffer, Default::default()) |
| 638 | }; | 665 | }; |
| 639 | 666 | ||
| 640 | // Wait for bytes to be received, or an error to occur. | 667 | // Wait for bytes to be received, or an error to occur. |
| @@ -673,15 +700,17 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 673 | } | 700 | } |
| 674 | 701 | ||
| 675 | /// Write, restart, read. | 702 | /// Write, restart, read. |
| 676 | pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { | 703 | pub async fn write_read(&mut self, address: u8, write_buffer: &[u8], read_buffer: &mut [u8]) -> Result<(), Error> { |
| 677 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the | 704 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the |
| 678 | // stop condition below. | 705 | // stop condition below. |
| 679 | if read.is_empty() { | 706 | if read_buffer.is_empty() { |
| 680 | return Err(Error::Overrun); | 707 | return Err(Error::Overrun); |
| 681 | } | 708 | } |
| 682 | 709 | ||
| 683 | self.write_frame(address, write, FrameOptions::FirstFrame).await?; | 710 | self.write_frame(address, write_buffer, FrameOptions::FirstFrame) |
| 684 | self.read_frame(address, read, FrameOptions::FirstAndLastFrame).await | 711 | .await?; |
| 712 | self.read_frame(address, read_buffer, FrameOptions::FirstAndLastFrame) | ||
| 713 | .await | ||
| 685 | } | 714 | } |
| 686 | 715 | ||
| 687 | /// Transaction with operations. | 716 | /// Transaction with operations. |
| @@ -689,11 +718,11 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 689 | /// Consecutive operations of same type are merged. See [transaction contract] for details. | 718 | /// Consecutive operations of same type are merged. See [transaction contract] for details. |
| 690 | /// | 719 | /// |
| 691 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction | 720 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction |
| 692 | pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { | 721 | pub async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { |
| 693 | for (op, frame) in operation_frames(operations)? { | 722 | for (op, frame) in operation_frames(operations)? { |
| 694 | match op { | 723 | match op { |
| 695 | Operation::Read(read) => self.read_frame(addr, read, frame).await?, | 724 | Operation::Read(read_buffer) => self.read_frame(address, read_buffer, frame).await?, |
| 696 | Operation::Write(write) => self.write_frame(addr, write, frame).await?, | 725 | Operation::Write(write_buffer) => self.write_frame(address, write_buffer, frame).await?, |
| 697 | } | 726 | } |
| 698 | } | 727 | } |
| 699 | 728 | ||
| @@ -729,12 +758,956 @@ impl Duty { | |||
| 729 | } | 758 | } |
| 730 | } | 759 | } |
| 731 | 760 | ||
| 761 | /// Result of attempting to send a byte in slave transmitter mode | ||
| 762 | #[derive(Debug, PartialEq)] | ||
| 763 | enum TransmitResult { | ||
| 764 | /// Byte sent and ACKed by master - continue transmission | ||
| 765 | Acknowledged, | ||
| 766 | /// Byte sent but NACKed by master - normal end of read transaction | ||
| 767 | NotAcknowledged, | ||
| 768 | /// STOP condition detected - master terminated transaction | ||
| 769 | Stopped, | ||
| 770 | /// RESTART condition detected - master starting new transaction | ||
| 771 | Restarted, | ||
| 772 | } | ||
| 773 | |||
| 774 | /// Result of attempting to receive a byte in slave receiver mode | ||
| 775 | #[derive(Debug, PartialEq)] | ||
| 776 | enum ReceiveResult { | ||
| 777 | /// Data byte successfully received | ||
| 778 | Data(u8), | ||
| 779 | /// STOP condition detected - end of write transaction | ||
| 780 | Stopped, | ||
| 781 | /// RESTART condition detected - master starting new transaction | ||
| 782 | Restarted, | ||
| 783 | } | ||
| 784 | |||
| 785 | /// Enumeration of slave transaction termination conditions | ||
| 786 | #[derive(Debug, Clone, Copy, PartialEq)] | ||
| 787 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 788 | enum SlaveTermination { | ||
| 789 | /// STOP condition received - normal end of transaction | ||
| 790 | Stop, | ||
| 791 | /// RESTART condition received - master starting new transaction | ||
| 792 | Restart, | ||
| 793 | /// NACK received - normal end of read transaction | ||
| 794 | Nack, | ||
| 795 | } | ||
| 796 | |||
| 797 | impl<'d, M: PeriMode> I2c<'d, M, Master> { | ||
| 798 | /// Configure the I2C driver for slave operations, allowing for the driver to be used as a slave and a master (multimaster) | ||
| 799 | pub fn into_slave_multimaster(mut self, slave_addr_config: SlaveAddrConfig) -> I2c<'d, M, MultiMaster> { | ||
| 800 | let mut slave = I2c { | ||
| 801 | info: self.info, | ||
| 802 | state: self.state, | ||
| 803 | kernel_clock: self.kernel_clock, | ||
| 804 | tx_dma: self.tx_dma.take(), // Use take() to move ownership | ||
| 805 | rx_dma: self.rx_dma.take(), // Use take() to move ownership | ||
| 806 | #[cfg(feature = "time")] | ||
| 807 | timeout: self.timeout, | ||
| 808 | _phantom: PhantomData, | ||
| 809 | _phantom2: PhantomData, | ||
| 810 | _drop_guard: self._drop_guard, // Move the drop guard | ||
| 811 | }; | ||
| 812 | slave.init_slave(slave_addr_config); | ||
| 813 | slave | ||
| 814 | } | ||
| 815 | } | ||
| 816 | |||
| 817 | // Address configuration methods | ||
| 818 | impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | ||
| 819 | /// Initialize slave mode with address configuration | ||
| 820 | pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) { | ||
| 821 | trace!("I2C slave: initializing with config={:?}", config); | ||
| 822 | |||
| 823 | // Disable peripheral for configuration | ||
| 824 | self.info.regs.cr1().modify(|reg| reg.set_pe(false)); | ||
| 825 | |||
| 826 | // Configure slave addresses | ||
| 827 | self.apply_address_configuration(config); | ||
| 828 | |||
| 829 | // Enable peripheral with slave settings | ||
| 830 | self.info.regs.cr1().modify(|reg| { | ||
| 831 | reg.set_pe(true); | ||
| 832 | reg.set_ack(true); // Enable acknowledgment for slave mode | ||
| 833 | reg.set_nostretch(false); // Allow clock stretching for processing time | ||
| 834 | }); | ||
| 835 | |||
| 836 | trace!("I2C slave: initialization complete"); | ||
| 837 | } | ||
| 838 | |||
| 839 | /// Apply the complete address configuration for slave mode | ||
| 840 | fn apply_address_configuration(&mut self, config: SlaveAddrConfig) { | ||
| 841 | match config.addr { | ||
| 842 | OwnAddresses::OA1(addr) => { | ||
| 843 | self.configure_primary_address(addr); | ||
| 844 | self.disable_secondary_address(); | ||
| 845 | } | ||
| 846 | OwnAddresses::OA2(oa2) => { | ||
| 847 | self.configure_default_primary_address(); | ||
| 848 | self.configure_secondary_address(oa2.addr); // v1 ignores mask | ||
| 849 | } | ||
| 850 | OwnAddresses::Both { oa1, oa2 } => { | ||
| 851 | self.configure_primary_address(oa1); | ||
| 852 | self.configure_secondary_address(oa2.addr); // v1 ignores mask | ||
| 853 | } | ||
| 854 | } | ||
| 855 | |||
| 856 | // Configure general call detection | ||
| 857 | if config.general_call { | ||
| 858 | self.info.regs.cr1().modify(|w| w.set_engc(true)); | ||
| 859 | } | ||
| 860 | } | ||
| 861 | |||
| 862 | /// Configure the primary address (OA1) register | ||
| 863 | fn configure_primary_address(&mut self, addr: Address) { | ||
| 864 | match addr { | ||
| 865 | Address::SevenBit(addr) => { | ||
| 866 | self.info.regs.oar1().write(|reg| { | ||
| 867 | let hw_addr = (addr as u16) << 1; // Address in bits [7:1] | ||
| 868 | reg.set_add(hw_addr); | ||
| 869 | reg.set_addmode(i2c::vals::Addmode::BIT7); | ||
| 870 | }); | ||
| 871 | } | ||
| 872 | Address::TenBit(addr) => { | ||
| 873 | self.info.regs.oar1().write(|reg| { | ||
| 874 | reg.set_add(addr); | ||
| 875 | reg.set_addmode(i2c::vals::Addmode::BIT10); | ||
| 876 | }); | ||
| 877 | } | ||
| 878 | } | ||
| 879 | |||
| 880 | // Set required bit 14 as per reference manual | ||
| 881 | self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14); | ||
| 882 | } | ||
| 883 | |||
| 884 | /// Configure the secondary address (OA2) register | ||
| 885 | fn configure_secondary_address(&mut self, addr: u8) { | ||
| 886 | self.info.regs.oar2().write(|reg| { | ||
| 887 | reg.set_add2(addr); | ||
| 888 | reg.set_endual(i2c::vals::Endual::DUAL); | ||
| 889 | }); | ||
| 890 | } | ||
| 891 | |||
| 892 | /// Set a default primary address when using OA2-only mode | ||
| 893 | fn configure_default_primary_address(&mut self) { | ||
| 894 | self.info.regs.oar1().write(|reg| { | ||
| 895 | reg.set_add(0); // Reserved address, safe to use | ||
| 896 | reg.set_addmode(i2c::vals::Addmode::BIT7); | ||
| 897 | }); | ||
| 898 | self.info.regs.oar1().modify(|reg| reg.0 |= 1 << 14); | ||
| 899 | } | ||
| 900 | |||
| 901 | /// Disable secondary address when not needed | ||
| 902 | fn disable_secondary_address(&mut self) { | ||
| 903 | self.info.regs.oar2().write(|reg| { | ||
| 904 | reg.set_endual(i2c::vals::Endual::SINGLE); | ||
| 905 | }); | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | impl<'d, M: PeriMode> I2c<'d, M, MultiMaster> { | ||
| 910 | /// Listen for incoming I2C address match and return the command type | ||
| 911 | /// | ||
| 912 | /// This method blocks until the slave address is matched by a master. | ||
| 913 | /// Returns the command type (Read/Write) and the matched address. | ||
| 914 | pub fn blocking_listen(&mut self) -> Result<SlaveCommand, Error> { | ||
| 915 | trace!("I2C slave: starting blocking listen for address match"); | ||
| 916 | let result = self.blocking_listen_with_timeout(self.timeout()); | ||
| 917 | trace!("I2C slave: blocking listen complete, result={:?}", result); | ||
| 918 | result | ||
| 919 | } | ||
| 920 | |||
| 921 | /// Respond to a master read request by transmitting data | ||
| 922 | /// | ||
| 923 | /// Sends the provided data to the master. If the master requests more bytes | ||
| 924 | /// than available, padding bytes (0x00) are sent until the master terminates | ||
| 925 | /// the transaction with NACK. | ||
| 926 | /// | ||
| 927 | /// Returns the total number of bytes transmitted (including padding). | ||
| 928 | pub fn blocking_respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { | ||
| 929 | trace!("I2C slave: starting blocking respond_to_read, data_len={}", data.len()); | ||
| 930 | |||
| 931 | if let Some(zero_length_result) = self.detect_zero_length_read(self.timeout())? { | ||
| 932 | trace!("I2C slave: zero-length read detected"); | ||
| 933 | return Ok(zero_length_result); | ||
| 934 | } | ||
| 935 | |||
| 936 | let result = self.transmit_to_master(data, self.timeout()); | ||
| 937 | trace!("I2C slave: blocking respond_to_read complete, result={:?}", result); | ||
| 938 | result | ||
| 939 | } | ||
| 940 | |||
| 941 | /// Respond to a master write request by receiving data | ||
| 942 | /// | ||
| 943 | /// Receives data from the master into the provided buffer. If the master | ||
| 944 | /// sends more bytes than the buffer can hold, excess bytes are acknowledged | ||
| 945 | /// but discarded. | ||
| 946 | /// | ||
| 947 | /// Returns the number of bytes stored in the buffer (not total received). | ||
| 948 | pub fn blocking_respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { | ||
| 949 | trace!( | ||
| 950 | "I2C slave: starting blocking respond_to_write, buffer_len={}", | ||
| 951 | buffer.len() | ||
| 952 | ); | ||
| 953 | let result = self.receive_from_master(buffer, self.timeout()); | ||
| 954 | trace!("I2C slave: blocking respond_to_write complete, result={:?}", result); | ||
| 955 | result | ||
| 956 | } | ||
| 957 | |||
| 958 | // Private implementation methods | ||
| 959 | |||
| 960 | /// Wait for address match and determine transaction type | ||
| 961 | fn blocking_listen_with_timeout(&mut self, timeout: Timeout) -> Result<SlaveCommand, Error> { | ||
| 962 | // Ensure interrupts are disabled for blocking operation | ||
| 963 | self.disable_i2c_interrupts(); | ||
| 964 | |||
| 965 | // Wait for address match (ADDR flag) | ||
| 966 | loop { | ||
| 967 | let sr1 = Self::read_status_and_handle_errors(self.info)?; | ||
| 968 | |||
| 969 | if sr1.addr() { | ||
| 970 | // Address matched - read SR2 to get direction and clear ADDR flag | ||
| 971 | let sr2 = self.info.regs.sr2().read(); | ||
| 972 | let direction = if sr2.tra() { | ||
| 973 | SlaveCommandKind::Read | ||
| 974 | } else { | ||
| 975 | SlaveCommandKind::Write | ||
| 976 | }; | ||
| 977 | |||
| 978 | // Use the static method instead of the instance method | ||
| 979 | let matched_address = Self::decode_matched_address(sr2, self.info)?; | ||
| 980 | trace!( | ||
| 981 | "I2C slave: address matched, direction={:?}, addr={:?}", | ||
| 982 | direction, matched_address | ||
| 983 | ); | ||
| 984 | |||
| 985 | return Ok(SlaveCommand { | ||
| 986 | kind: direction, | ||
| 987 | address: matched_address, | ||
| 988 | }); | ||
| 989 | } | ||
| 990 | |||
| 991 | timeout.check()?; | ||
| 992 | } | ||
| 993 | } | ||
| 994 | |||
| 995 | /// Transmit data to master in response to read request | ||
| 996 | fn transmit_to_master(&mut self, data: &[u8], timeout: Timeout) -> Result<usize, Error> { | ||
| 997 | let mut bytes_transmitted = 0; | ||
| 998 | let mut padding_count = 0; | ||
| 999 | |||
| 1000 | loop { | ||
| 1001 | let byte_to_send = if bytes_transmitted < data.len() { | ||
| 1002 | data[bytes_transmitted] | ||
| 1003 | } else { | ||
| 1004 | padding_count += 1; | ||
| 1005 | 0x00 // Send padding bytes when data is exhausted | ||
| 1006 | }; | ||
| 1007 | |||
| 1008 | match self.transmit_byte(byte_to_send, timeout)? { | ||
| 1009 | TransmitResult::Acknowledged => { | ||
| 1010 | bytes_transmitted += 1; | ||
| 1011 | } | ||
| 1012 | TransmitResult::NotAcknowledged => { | ||
| 1013 | bytes_transmitted += 1; // Count the NACKed byte | ||
| 1014 | break; | ||
| 1015 | } | ||
| 1016 | TransmitResult::Stopped | TransmitResult::Restarted => { | ||
| 1017 | break; | ||
| 1018 | } | ||
| 1019 | } | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | if padding_count > 0 { | ||
| 1023 | trace!( | ||
| 1024 | "I2C slave: sent {} data bytes + {} padding bytes = {} total", | ||
| 1025 | data.len(), | ||
| 1026 | padding_count, | ||
| 1027 | bytes_transmitted | ||
| 1028 | ); | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | Ok(bytes_transmitted) | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | /// Receive data from master during write request | ||
| 1035 | fn receive_from_master(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> { | ||
| 1036 | let mut bytes_stored = 0; | ||
| 1037 | |||
| 1038 | // Receive bytes that fit in buffer | ||
| 1039 | while bytes_stored < buffer.len() { | ||
| 1040 | match self.receive_byte(timeout)? { | ||
| 1041 | ReceiveResult::Data(byte) => { | ||
| 1042 | buffer[bytes_stored] = byte; | ||
| 1043 | bytes_stored += 1; | ||
| 1044 | } | ||
| 1045 | ReceiveResult::Stopped | ReceiveResult::Restarted => { | ||
| 1046 | return Ok(bytes_stored); | ||
| 1047 | } | ||
| 1048 | } | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | // Handle buffer overflow by discarding excess bytes | ||
| 1052 | if bytes_stored == buffer.len() { | ||
| 1053 | trace!("I2C slave: buffer full, discarding excess bytes"); | ||
| 1054 | self.discard_excess_bytes(timeout)?; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | Ok(bytes_stored) | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | /// Detect zero-length read pattern early | ||
| 1061 | /// | ||
| 1062 | /// Zero-length reads occur when a master sends START+ADDR+R followed immediately | ||
| 1063 | /// by NACK+STOP without wanting any data. This must be detected before attempting | ||
| 1064 | /// to transmit any bytes to avoid SDA line issues. | ||
| 1065 | fn detect_zero_length_read(&mut self, _timeout: Timeout) -> Result<Option<usize>, Error> { | ||
| 1066 | // Quick check for immediate termination signals | ||
| 1067 | let sr1 = self.info.regs.sr1().read(); | ||
| 1068 | |||
| 1069 | // Check for immediate NACK (fastest zero-length pattern) | ||
| 1070 | if sr1.af() { | ||
| 1071 | self.clear_acknowledge_failure(); | ||
| 1072 | return Ok(Some(0)); | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | // Check for immediate STOP (alternative zero-length pattern) | ||
| 1076 | if sr1.stopf() { | ||
| 1077 | Self::clear_stop_flag(self.info); | ||
| 1078 | return Ok(Some(0)); | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | // Give a brief window for master to send termination signals | ||
| 1082 | // This handles masters that have slight delays between address ACK and NACK | ||
| 1083 | const ZERO_LENGTH_DETECTION_CYCLES: u32 = 20; // ~5-10µs window | ||
| 1084 | |||
| 1085 | for _ in 0..ZERO_LENGTH_DETECTION_CYCLES { | ||
| 1086 | let sr1 = self.info.regs.sr1().read(); | ||
| 1087 | |||
| 1088 | // Immediate NACK indicates zero-length read | ||
| 1089 | if sr1.af() { | ||
| 1090 | self.clear_acknowledge_failure(); | ||
| 1091 | return Ok(Some(0)); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | // Immediate STOP indicates zero-length read | ||
| 1095 | if sr1.stopf() { | ||
| 1096 | Self::clear_stop_flag(self.info); | ||
| 1097 | return Ok(Some(0)); | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | // If TXE becomes ready, master is waiting for data - not zero-length | ||
| 1101 | if sr1.txe() { | ||
| 1102 | return Ok(None); // Proceed with normal transmission | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | // If RESTART detected, handle as zero-length | ||
| 1106 | if sr1.addr() { | ||
| 1107 | return Ok(Some(0)); | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | // No zero-length pattern detected within the window | ||
| 1112 | Ok(None) | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | /// Discard excess bytes when buffer is full | ||
| 1116 | fn discard_excess_bytes(&mut self, timeout: Timeout) -> Result<(), Error> { | ||
| 1117 | let mut discarded_count = 0; | ||
| 1118 | |||
| 1119 | loop { | ||
| 1120 | match self.receive_byte(timeout)? { | ||
| 1121 | ReceiveResult::Data(_) => { | ||
| 1122 | discarded_count += 1; | ||
| 1123 | continue; | ||
| 1124 | } | ||
| 1125 | ReceiveResult::Stopped | ReceiveResult::Restarted => { | ||
| 1126 | if discarded_count > 0 { | ||
| 1127 | trace!("I2C slave: discarded {} excess bytes", discarded_count); | ||
| 1128 | } | ||
| 1129 | break; | ||
| 1130 | } | ||
| 1131 | } | ||
| 1132 | } | ||
| 1133 | Ok(()) | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | /// Send a single byte and wait for master's response | ||
| 1137 | fn transmit_byte(&mut self, byte: u8, timeout: Timeout) -> Result<TransmitResult, Error> { | ||
| 1138 | // Wait for transmit buffer ready | ||
| 1139 | self.wait_for_transmit_ready(timeout)?; | ||
| 1140 | |||
| 1141 | // Send the byte | ||
| 1142 | self.info.regs.dr().write(|w| w.set_dr(byte)); | ||
| 1143 | |||
| 1144 | // Wait for transmission completion or master response | ||
| 1145 | self.wait_for_transmit_completion(timeout) | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | /// Wait until transmit buffer is ready (TXE flag set) | ||
| 1149 | fn wait_for_transmit_ready(&mut self, timeout: Timeout) -> Result<(), Error> { | ||
| 1150 | loop { | ||
| 1151 | let sr1 = Self::read_status_and_handle_errors(self.info)?; | ||
| 1152 | |||
| 1153 | // Check for early termination conditions | ||
| 1154 | if let Some(result) = Self::check_early_termination(sr1) { | ||
| 1155 | return Err(self.handle_early_termination(result)); | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | if sr1.txe() { | ||
| 1159 | return Ok(()); // Ready to transmit | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | timeout.check()?; | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | /// Wait for byte transmission completion or master response | ||
| 1167 | fn wait_for_transmit_completion(&mut self, timeout: Timeout) -> Result<TransmitResult, Error> { | ||
| 1168 | loop { | ||
| 1169 | let sr1 = self.info.regs.sr1().read(); | ||
| 1170 | |||
| 1171 | // Check flags in priority order | ||
| 1172 | if sr1.af() { | ||
| 1173 | self.clear_acknowledge_failure(); | ||
| 1174 | return Ok(TransmitResult::NotAcknowledged); | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | if sr1.btf() { | ||
| 1178 | return Ok(TransmitResult::Acknowledged); | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | if sr1.stopf() { | ||
| 1182 | Self::clear_stop_flag(self.info); | ||
| 1183 | return Ok(TransmitResult::Stopped); | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | if sr1.addr() { | ||
| 1187 | return Ok(TransmitResult::Restarted); | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | // Check for other error conditions | ||
| 1191 | self.check_for_hardware_errors(sr1)?; | ||
| 1192 | |||
| 1193 | timeout.check()?; | ||
| 1194 | } | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | /// Receive a single byte or detect transaction termination | ||
| 1198 | fn receive_byte(&mut self, timeout: Timeout) -> Result<ReceiveResult, Error> { | ||
| 1199 | loop { | ||
| 1200 | let sr1 = Self::read_status_and_handle_errors(self.info)?; | ||
| 1201 | |||
| 1202 | // Check for received data first (prioritize data over control signals) | ||
| 1203 | if sr1.rxne() { | ||
| 1204 | let byte = self.info.regs.dr().read().dr(); | ||
| 1205 | return Ok(ReceiveResult::Data(byte)); | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | // Check for transaction termination | ||
| 1209 | if sr1.addr() { | ||
| 1210 | return Ok(ReceiveResult::Restarted); | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | if sr1.stopf() { | ||
| 1214 | Self::clear_stop_flag(self.info); | ||
| 1215 | return Ok(ReceiveResult::Stopped); | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | timeout.check()?; | ||
| 1219 | } | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | /// Determine which slave address was matched based on SR2 flags | ||
| 1223 | fn decode_matched_address(sr2: i2c::regs::Sr2, info: &'static Info) -> Result<Address, Error> { | ||
| 1224 | if sr2.gencall() { | ||
| 1225 | Ok(Address::SevenBit(0x00)) // General call address | ||
| 1226 | } else if sr2.dualf() { | ||
| 1227 | // OA2 (secondary address) was matched | ||
| 1228 | let oar2 = info.regs.oar2().read(); | ||
| 1229 | if oar2.endual() != i2c::vals::Endual::DUAL { | ||
| 1230 | return Err(Error::Bus); // Hardware inconsistency | ||
| 1231 | } | ||
| 1232 | Ok(Address::SevenBit(oar2.add2())) | ||
| 1233 | } else { | ||
| 1234 | // OA1 (primary address) was matched | ||
| 1235 | let oar1 = info.regs.oar1().read(); | ||
| 1236 | match oar1.addmode() { | ||
| 1237 | i2c::vals::Addmode::BIT7 => { | ||
| 1238 | let addr = (oar1.add() >> 1) as u8; | ||
| 1239 | Ok(Address::SevenBit(addr)) | ||
| 1240 | } | ||
| 1241 | i2c::vals::Addmode::BIT10 => Ok(Address::TenBit(oar1.add())), | ||
| 1242 | } | ||
| 1243 | } | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | // Helper methods for hardware interaction | ||
| 1247 | |||
| 1248 | /// Read status register and handle I2C errors (except NACK in slave mode) | ||
| 1249 | fn read_status_and_handle_errors(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { | ||
| 1250 | match Self::check_and_clear_error_flags(info) { | ||
| 1251 | Ok(sr1) => Ok(sr1), | ||
| 1252 | Err(Error::Nack) => { | ||
| 1253 | // In slave mode, NACK is normal protocol behavior, not an error | ||
| 1254 | Ok(info.regs.sr1().read()) | ||
| 1255 | } | ||
| 1256 | Err(other_error) => Err(other_error), | ||
| 1257 | } | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | /// Check for conditions that cause early termination of operations | ||
| 1261 | fn check_early_termination(sr1: i2c::regs::Sr1) -> Option<TransmitResult> { | ||
| 1262 | if sr1.stopf() { | ||
| 1263 | Some(TransmitResult::Stopped) | ||
| 1264 | } else if sr1.addr() { | ||
| 1265 | Some(TransmitResult::Restarted) | ||
| 1266 | } else if sr1.af() { | ||
| 1267 | Some(TransmitResult::NotAcknowledged) | ||
| 1268 | } else { | ||
| 1269 | None | ||
| 1270 | } | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | /// Convert early termination to appropriate error | ||
| 1274 | fn handle_early_termination(&mut self, result: TransmitResult) -> Error { | ||
| 1275 | match result { | ||
| 1276 | TransmitResult::Stopped => { | ||
| 1277 | Self::clear_stop_flag(self.info); | ||
| 1278 | Error::Bus // Unexpected STOP during setup | ||
| 1279 | } | ||
| 1280 | TransmitResult::Restarted => { | ||
| 1281 | Error::Bus // Unexpected RESTART during setup | ||
| 1282 | } | ||
| 1283 | TransmitResult::NotAcknowledged => { | ||
| 1284 | self.clear_acknowledge_failure(); | ||
| 1285 | Error::Bus // Unexpected NACK during setup | ||
| 1286 | } | ||
| 1287 | TransmitResult::Acknowledged => { | ||
| 1288 | unreachable!() // This should never be passed to this function | ||
| 1289 | } | ||
| 1290 | } | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | /// Check for hardware-level I2C errors during transmission | ||
| 1294 | fn check_for_hardware_errors(&self, sr1: i2c::regs::Sr1) -> Result<(), Error> { | ||
| 1295 | if sr1.timeout() || sr1.ovr() || sr1.arlo() || sr1.berr() { | ||
| 1296 | // Delegate to existing error handling | ||
| 1297 | Self::check_and_clear_error_flags(self.info)?; | ||
| 1298 | } | ||
| 1299 | Ok(()) | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /// Disable I2C event and error interrupts for blocking operations | ||
| 1303 | fn disable_i2c_interrupts(&mut self) { | ||
| 1304 | self.info.regs.cr2().modify(|w| { | ||
| 1305 | w.set_itevten(false); | ||
| 1306 | w.set_iterren(false); | ||
| 1307 | }); | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | /// Clear the acknowledge failure flag | ||
| 1311 | fn clear_acknowledge_failure(&mut self) { | ||
| 1312 | self.info.regs.sr1().write(|reg| { | ||
| 1313 | reg.0 = !0; | ||
| 1314 | reg.set_af(false); | ||
| 1315 | }); | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | /// Configure DMA settings for slave operations (shared between read/write) | ||
| 1319 | fn setup_slave_dma_base(&mut self) { | ||
| 1320 | self.info.regs.cr2().modify(|w| { | ||
| 1321 | w.set_itbufen(false); // Always disable buffer interrupts when using DMA | ||
| 1322 | w.set_dmaen(true); // Enable DMA requests | ||
| 1323 | w.set_last(false); // LAST bit not used in slave mode for v1 hardware | ||
| 1324 | }); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /// Disable DMA and interrupts in a critical section | ||
| 1328 | fn disable_dma_and_interrupts(info: &'static Info) { | ||
| 1329 | critical_section::with(|_| { | ||
| 1330 | info.regs.cr2().modify(|w| { | ||
| 1331 | w.set_dmaen(false); | ||
| 1332 | w.set_iterren(false); | ||
| 1333 | w.set_itevten(false); | ||
| 1334 | }); | ||
| 1335 | }); | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | /// Check for early termination conditions during slave operations | ||
| 1339 | /// Returns Some(result) if termination detected, None to continue | ||
| 1340 | fn check_slave_termination_conditions(sr1: i2c::regs::Sr1) -> Option<SlaveTermination> { | ||
| 1341 | if sr1.stopf() { | ||
| 1342 | Some(SlaveTermination::Stop) | ||
| 1343 | } else if sr1.addr() { | ||
| 1344 | Some(SlaveTermination::Restart) | ||
| 1345 | } else if sr1.af() { | ||
| 1346 | Some(SlaveTermination::Nack) | ||
| 1347 | } else { | ||
| 1348 | None | ||
| 1349 | } | ||
| 1350 | } | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | impl<'d> I2c<'d, Async, MultiMaster> { | ||
| 1354 | /// Async listen for incoming I2C messages using interrupts | ||
| 1355 | /// | ||
| 1356 | /// Waits for a master to address this slave and returns the command type | ||
| 1357 | /// (Read/Write) and the matched address. This method will suspend until | ||
| 1358 | /// an address match occurs. | ||
| 1359 | pub async fn listen(&mut self) -> Result<SlaveCommand, Error> { | ||
| 1360 | trace!("I2C slave: starting async listen for address match"); | ||
| 1361 | let state = self.state; | ||
| 1362 | let info = self.info; | ||
| 1363 | |||
| 1364 | Self::enable_interrupts(info); | ||
| 1365 | |||
| 1366 | let on_drop = OnDrop::new(|| { | ||
| 1367 | Self::disable_dma_and_interrupts(info); | ||
| 1368 | }); | ||
| 1369 | |||
| 1370 | let result = poll_fn(|cx| { | ||
| 1371 | state.waker.register(cx.waker()); | ||
| 1372 | |||
| 1373 | match Self::check_and_clear_error_flags(info) { | ||
| 1374 | Err(e) => { | ||
| 1375 | error!("I2C slave: error during listen: {:?}", e); | ||
| 1376 | Poll::Ready(Err(e)) | ||
| 1377 | } | ||
| 1378 | Ok(sr1) => { | ||
| 1379 | if sr1.addr() { | ||
| 1380 | let sr2 = info.regs.sr2().read(); | ||
| 1381 | let direction = if sr2.tra() { | ||
| 1382 | SlaveCommandKind::Read | ||
| 1383 | } else { | ||
| 1384 | SlaveCommandKind::Write | ||
| 1385 | }; | ||
| 1386 | |||
| 1387 | let matched_address = match Self::decode_matched_address(sr2, info) { | ||
| 1388 | Ok(addr) => { | ||
| 1389 | trace!("I2C slave: address matched, direction={:?}, addr={:?}", direction, addr); | ||
| 1390 | addr | ||
| 1391 | } | ||
| 1392 | Err(e) => { | ||
| 1393 | error!("I2C slave: failed to decode matched address: {:?}", e); | ||
| 1394 | return Poll::Ready(Err(e)); | ||
| 1395 | } | ||
| 1396 | }; | ||
| 1397 | |||
| 1398 | Poll::Ready(Ok(SlaveCommand { | ||
| 1399 | kind: direction, | ||
| 1400 | address: matched_address, | ||
| 1401 | })) | ||
| 1402 | } else { | ||
| 1403 | Self::enable_interrupts(info); | ||
| 1404 | Poll::Pending | ||
| 1405 | } | ||
| 1406 | } | ||
| 1407 | } | ||
| 1408 | }) | ||
| 1409 | .await; | ||
| 1410 | |||
| 1411 | drop(on_drop); | ||
| 1412 | trace!("I2C slave: listen complete, result={:?}", result); | ||
| 1413 | result | ||
| 1414 | } | ||
| 1415 | |||
| 1416 | /// Async respond to write command using RX DMA | ||
| 1417 | /// | ||
| 1418 | /// Receives data from the master into the provided buffer using DMA. | ||
| 1419 | /// If the master sends more bytes than the buffer can hold, excess bytes | ||
| 1420 | /// are acknowledged but discarded to prevent interrupt flooding. | ||
| 1421 | /// | ||
| 1422 | /// Returns the number of bytes stored in the buffer (not total received). | ||
| 1423 | pub async fn respond_to_write(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { | ||
| 1424 | trace!("I2C slave: starting respond_to_write, buffer_len={}", buffer.len()); | ||
| 1425 | |||
| 1426 | if buffer.is_empty() { | ||
| 1427 | warn!("I2C slave: respond_to_write called with empty buffer"); | ||
| 1428 | return Err(Error::Overrun); | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | let state = self.state; | ||
| 1432 | let info = self.info; | ||
| 1433 | |||
| 1434 | self.setup_slave_dma_base(); | ||
| 1435 | |||
| 1436 | let on_drop = OnDrop::new(|| { | ||
| 1437 | Self::disable_dma_and_interrupts(info); | ||
| 1438 | }); | ||
| 1439 | |||
| 1440 | info.regs.sr2().read(); | ||
| 1441 | |||
| 1442 | let result = self.execute_slave_receive_transfer(buffer, state, info).await; | ||
| 1443 | |||
| 1444 | drop(on_drop); | ||
| 1445 | trace!("I2C slave: respond_to_write complete, result={:?}", result); | ||
| 1446 | result | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | /// Async respond to read command using TX DMA | ||
| 1450 | /// | ||
| 1451 | /// Transmits data to the master using DMA. If the master requests more bytes | ||
| 1452 | /// than available in the data buffer, padding bytes (0x00) are sent until | ||
| 1453 | /// the master terminates the transaction with NACK, STOP, or RESTART. | ||
| 1454 | /// | ||
| 1455 | /// Returns the total number of bytes transmitted (data + padding). | ||
| 1456 | pub async fn respond_to_read(&mut self, data: &[u8]) -> Result<usize, Error> { | ||
| 1457 | trace!("I2C slave: starting respond_to_read, data_len={}", data.len()); | ||
| 1458 | |||
| 1459 | if data.is_empty() { | ||
| 1460 | warn!("I2C slave: respond_to_read called with empty data"); | ||
| 1461 | return Err(Error::Overrun); | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | let state = self.state; | ||
| 1465 | let info = self.info; | ||
| 1466 | |||
| 1467 | self.setup_slave_dma_base(); | ||
| 1468 | |||
| 1469 | let on_drop = OnDrop::new(|| { | ||
| 1470 | Self::disable_dma_and_interrupts(info); | ||
| 1471 | }); | ||
| 1472 | |||
| 1473 | info.regs.sr2().read(); | ||
| 1474 | |||
| 1475 | let result = self.execute_slave_transmit_transfer(data, state, info).await; | ||
| 1476 | |||
| 1477 | drop(on_drop); | ||
| 1478 | trace!("I2C slave: respond_to_read complete, result={:?}", result); | ||
| 1479 | result | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | // === Private Transfer Execution Methods === | ||
| 1483 | |||
| 1484 | /// Execute complete slave receive transfer with excess byte handling | ||
| 1485 | async fn execute_slave_receive_transfer( | ||
| 1486 | &mut self, | ||
| 1487 | buffer: &mut [u8], | ||
| 1488 | state: &'static State, | ||
| 1489 | info: &'static Info, | ||
| 1490 | ) -> Result<usize, Error> { | ||
| 1491 | let dma_transfer = unsafe { | ||
| 1492 | let src = info.regs.dr().as_ptr() as *mut u8; | ||
| 1493 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) | ||
| 1494 | }; | ||
| 1495 | |||
| 1496 | let i2c_monitor = | ||
| 1497 | Self::create_termination_monitor(state, info, &[SlaveTermination::Stop, SlaveTermination::Restart]); | ||
| 1498 | |||
| 1499 | match select(dma_transfer, i2c_monitor).await { | ||
| 1500 | Either::Second(Err(e)) => { | ||
| 1501 | error!("I2C slave: error during receive transfer: {:?}", e); | ||
| 1502 | Self::disable_dma_and_interrupts(info); | ||
| 1503 | Err(e) | ||
| 1504 | } | ||
| 1505 | Either::First(_) => { | ||
| 1506 | trace!("I2C slave: DMA receive completed, handling excess bytes"); | ||
| 1507 | Self::disable_dma_and_interrupts(info); | ||
| 1508 | self.handle_excess_bytes(state, info).await?; | ||
| 1509 | Ok(buffer.len()) | ||
| 1510 | } | ||
| 1511 | Either::Second(Ok(termination)) => { | ||
| 1512 | trace!("I2C slave: receive terminated by I2C event: {:?}", termination); | ||
| 1513 | Self::disable_dma_and_interrupts(info); | ||
| 1514 | Ok(buffer.len()) | ||
| 1515 | } | ||
| 1516 | } | ||
| 1517 | } | ||
| 1518 | |||
| 1519 | /// Execute complete slave transmit transfer with padding byte handling | ||
| 1520 | async fn execute_slave_transmit_transfer( | ||
| 1521 | &mut self, | ||
| 1522 | data: &[u8], | ||
| 1523 | state: &'static State, | ||
| 1524 | info: &'static Info, | ||
| 1525 | ) -> Result<usize, Error> { | ||
| 1526 | let dma_transfer = unsafe { | ||
| 1527 | let dst = info.regs.dr().as_ptr() as *mut u8; | ||
| 1528 | self.tx_dma.as_mut().unwrap().write(data, dst, Default::default()) | ||
| 1529 | }; | ||
| 1530 | |||
| 1531 | let i2c_monitor = Self::create_termination_monitor( | ||
| 1532 | state, | ||
| 1533 | info, | ||
| 1534 | &[ | ||
| 1535 | SlaveTermination::Stop, | ||
| 1536 | SlaveTermination::Restart, | ||
| 1537 | SlaveTermination::Nack, | ||
| 1538 | ], | ||
| 1539 | ); | ||
| 1540 | |||
| 1541 | match select(dma_transfer, i2c_monitor).await { | ||
| 1542 | Either::Second(Err(e)) => { | ||
| 1543 | error!("I2C slave: error during transmit transfer: {:?}", e); | ||
| 1544 | Self::disable_dma_and_interrupts(info); | ||
| 1545 | Err(e) | ||
| 1546 | } | ||
| 1547 | Either::First(_) => { | ||
| 1548 | trace!("I2C slave: DMA transmit completed, handling padding bytes"); | ||
| 1549 | Self::disable_dma_and_interrupts(info); | ||
| 1550 | let padding_count = self.handle_padding_bytes(state, info).await?; | ||
| 1551 | let total_bytes = data.len() + padding_count; | ||
| 1552 | trace!( | ||
| 1553 | "I2C slave: sent {} data bytes + {} padding bytes = {} total", | ||
| 1554 | data.len(), | ||
| 1555 | padding_count, | ||
| 1556 | total_bytes | ||
| 1557 | ); | ||
| 1558 | Ok(total_bytes) | ||
| 1559 | } | ||
| 1560 | Either::Second(Ok(termination)) => { | ||
| 1561 | trace!("I2C slave: transmit terminated by I2C event: {:?}", termination); | ||
| 1562 | Self::disable_dma_and_interrupts(info); | ||
| 1563 | Ok(data.len()) | ||
| 1564 | } | ||
| 1565 | } | ||
| 1566 | } | ||
| 1567 | |||
| 1568 | /// Create a future that monitors for specific slave termination conditions | ||
| 1569 | fn create_termination_monitor( | ||
| 1570 | state: &'static State, | ||
| 1571 | info: &'static Info, | ||
| 1572 | allowed_terminations: &'static [SlaveTermination], | ||
| 1573 | ) -> impl Future<Output = Result<SlaveTermination, Error>> { | ||
| 1574 | poll_fn(move |cx| { | ||
| 1575 | state.waker.register(cx.waker()); | ||
| 1576 | |||
| 1577 | match Self::check_and_clear_error_flags(info) { | ||
| 1578 | Err(Error::Nack) if allowed_terminations.contains(&SlaveTermination::Nack) => { | ||
| 1579 | Poll::Ready(Ok(SlaveTermination::Nack)) | ||
| 1580 | } | ||
| 1581 | Err(e) => Poll::Ready(Err(e)), | ||
| 1582 | Ok(sr1) => { | ||
| 1583 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { | ||
| 1584 | if allowed_terminations.contains(&termination) { | ||
| 1585 | // Handle the specific termination condition | ||
| 1586 | match termination { | ||
| 1587 | SlaveTermination::Stop => Self::clear_stop_flag(info), | ||
| 1588 | SlaveTermination::Nack => { | ||
| 1589 | info.regs.sr1().write(|reg| { | ||
| 1590 | reg.0 = !0; | ||
| 1591 | reg.set_af(false); | ||
| 1592 | }); | ||
| 1593 | } | ||
| 1594 | SlaveTermination::Restart => { | ||
| 1595 | // ADDR flag will be handled by next listen() call | ||
| 1596 | } | ||
| 1597 | } | ||
| 1598 | Poll::Ready(Ok(termination)) | ||
| 1599 | } else { | ||
| 1600 | // Unexpected termination condition | ||
| 1601 | Poll::Ready(Err(Error::Bus)) | ||
| 1602 | } | ||
| 1603 | } else { | ||
| 1604 | Self::enable_interrupts(info); | ||
| 1605 | Poll::Pending | ||
| 1606 | } | ||
| 1607 | } | ||
| 1608 | } | ||
| 1609 | }) | ||
| 1610 | } | ||
| 1611 | |||
| 1612 | /// Handle excess bytes after DMA buffer is full | ||
| 1613 | /// | ||
| 1614 | /// Reads and discards bytes until transaction termination to prevent interrupt flooding | ||
| 1615 | async fn handle_excess_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<(), Error> { | ||
| 1616 | let mut discarded_count = 0; | ||
| 1617 | |||
| 1618 | poll_fn(|cx| { | ||
| 1619 | state.waker.register(cx.waker()); | ||
| 1620 | |||
| 1621 | match Self::check_and_clear_error_flags(info) { | ||
| 1622 | Err(e) => { | ||
| 1623 | error!("I2C slave: error while discarding excess bytes: {:?}", e); | ||
| 1624 | Poll::Ready(Err(e)) | ||
| 1625 | } | ||
| 1626 | Ok(sr1) => { | ||
| 1627 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { | ||
| 1628 | match termination { | ||
| 1629 | SlaveTermination::Stop => Self::clear_stop_flag(info), | ||
| 1630 | SlaveTermination::Restart => {} | ||
| 1631 | SlaveTermination::Nack => unreachable!("NACK not expected during receive"), | ||
| 1632 | } | ||
| 1633 | if discarded_count > 0 { | ||
| 1634 | trace!("I2C slave: discarded {} excess bytes", discarded_count); | ||
| 1635 | } | ||
| 1636 | return Poll::Ready(Ok(())); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | if sr1.rxne() { | ||
| 1640 | let _discarded_byte = info.regs.dr().read().dr(); | ||
| 1641 | discarded_count += 1; | ||
| 1642 | Self::enable_interrupts(info); | ||
| 1643 | return Poll::Pending; | ||
| 1644 | } | ||
| 1645 | |||
| 1646 | Self::enable_interrupts(info); | ||
| 1647 | Poll::Pending | ||
| 1648 | } | ||
| 1649 | } | ||
| 1650 | }) | ||
| 1651 | .await | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | /// Handle padding bytes after DMA data is exhausted | ||
| 1655 | /// | ||
| 1656 | /// Sends 0x00 bytes until transaction termination to prevent interrupt flooding | ||
| 1657 | async fn handle_padding_bytes(&mut self, state: &'static State, info: &'static Info) -> Result<usize, Error> { | ||
| 1658 | let mut padding_count = 0; | ||
| 1659 | |||
| 1660 | poll_fn(|cx| { | ||
| 1661 | state.waker.register(cx.waker()); | ||
| 1662 | |||
| 1663 | match Self::check_and_clear_error_flags(info) { | ||
| 1664 | Err(Error::Nack) => Poll::Ready(Ok(padding_count)), | ||
| 1665 | Err(e) => { | ||
| 1666 | error!("I2C slave: error while sending padding bytes: {:?}", e); | ||
| 1667 | Poll::Ready(Err(e)) | ||
| 1668 | } | ||
| 1669 | Ok(sr1) => { | ||
| 1670 | if let Some(termination) = Self::check_slave_termination_conditions(sr1) { | ||
| 1671 | match termination { | ||
| 1672 | SlaveTermination::Stop => Self::clear_stop_flag(info), | ||
| 1673 | SlaveTermination::Restart => {} | ||
| 1674 | SlaveTermination::Nack => { | ||
| 1675 | info.regs.sr1().write(|reg| { | ||
| 1676 | reg.0 = !0; | ||
| 1677 | reg.set_af(false); | ||
| 1678 | }); | ||
| 1679 | } | ||
| 1680 | } | ||
| 1681 | return Poll::Ready(Ok(padding_count)); | ||
| 1682 | } | ||
| 1683 | |||
| 1684 | if sr1.txe() { | ||
| 1685 | info.regs.dr().write(|w| w.set_dr(0x00)); | ||
| 1686 | padding_count += 1; | ||
| 1687 | Self::enable_interrupts(info); | ||
| 1688 | return Poll::Pending; | ||
| 1689 | } | ||
| 1690 | |||
| 1691 | Self::enable_interrupts(info); | ||
| 1692 | Poll::Pending | ||
| 1693 | } | ||
| 1694 | } | ||
| 1695 | }) | ||
| 1696 | .await | ||
| 1697 | } | ||
| 1698 | } | ||
| 1699 | |||
| 1700 | /// Timing configuration for I2C v1 hardware | ||
| 1701 | /// | ||
| 1702 | /// This struct encapsulates the complex timing calculations required for STM32 I2C v1 | ||
| 1703 | /// peripherals, which use three separate registers (CR2.FREQ, CCR, TRISE) instead of | ||
| 1704 | /// the unified TIMINGR register found in v2 hardware. | ||
| 732 | struct Timings { | 1705 | struct Timings { |
| 733 | freq: u8, | 1706 | freq: u8, // APB frequency in MHz for CR2.FREQ register |
| 734 | mode: Mode, | 1707 | mode: Mode, // Standard or Fast mode selection |
| 735 | trise: u8, | 1708 | trise: u8, // Rise time compensation value |
| 736 | ccr: u16, | 1709 | ccr: u16, // Clock control register value |
| 737 | duty: Duty, | 1710 | duty: Duty, // Fast mode duty cycle selection |
| 738 | } | 1711 | } |
| 739 | 1712 | ||
| 740 | impl Timings { | 1713 | impl Timings { |
| @@ -771,14 +1744,10 @@ impl Timings { | |||
| 771 | duty = Duty::Duty2_1; | 1744 | duty = Duty::Duty2_1; |
| 772 | ccr = clock / (frequency * 3); | 1745 | ccr = clock / (frequency * 3); |
| 773 | ccr = if ccr < 1 { 1 } else { ccr }; | 1746 | ccr = if ccr < 1 { 1 } else { ccr }; |
| 774 | |||
| 775 | // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle) | ||
| 776 | } else { | 1747 | } else { |
| 777 | duty = Duty::Duty16_9; | 1748 | duty = Duty::Duty16_9; |
| 778 | ccr = clock / (frequency * 25); | 1749 | ccr = clock / (frequency * 25); |
| 779 | ccr = if ccr < 1 { 1 } else { ccr }; | 1750 | ccr = if ccr < 1 { 1 } else { ccr }; |
| 780 | |||
| 781 | // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle) | ||
| 782 | } | 1751 | } |
| 783 | } | 1752 | } |
| 784 | 1753 | ||
| @@ -788,11 +1757,6 @@ impl Timings { | |||
| 788 | ccr: ccr as u16, | 1757 | ccr: ccr as u16, |
| 789 | duty, | 1758 | duty, |
| 790 | mode, | 1759 | mode, |
| 791 | //prescale: presc_reg, | ||
| 792 | //scll, | ||
| 793 | //sclh, | ||
| 794 | //sdadel, | ||
| 795 | //scldel, | ||
| 796 | } | 1760 | } |
| 797 | } | 1761 | } |
| 798 | } | 1762 | } |
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 01b6b8800..57a7acee7 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -70,6 +70,11 @@ fn debug_print_interrupts(isr: stm32_metapac::i2c::regs::Isr) { | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | pub(crate) unsafe fn on_interrupt<T: Instance>() { | 72 | pub(crate) unsafe fn on_interrupt<T: Instance>() { |
| 73 | // restore the clocks to their last configured state as | ||
| 74 | // much is lost in STOP modes | ||
| 75 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 76 | crate::low_power::Executor::on_wakeup_irq(); | ||
| 77 | |||
| 73 | let regs = T::info().regs; | 78 | let regs = T::info().regs; |
| 74 | let isr = regs.isr().read(); | 79 | let isr = regs.isr().read(); |
| 75 | 80 | ||
| @@ -814,6 +819,8 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 814 | 819 | ||
| 815 | /// Write. | 820 | /// Write. |
| 816 | pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { | 821 | pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { |
| 822 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 823 | let _device_busy = crate::low_power::DeviceBusy::new_stop1(); | ||
| 817 | let timeout = self.timeout(); | 824 | let timeout = self.timeout(); |
| 818 | if write.is_empty() { | 825 | if write.is_empty() { |
| 819 | self.write_internal(address.into(), write, true, timeout) | 826 | self.write_internal(address.into(), write, true, timeout) |
| @@ -828,6 +835,8 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 828 | /// | 835 | /// |
| 829 | /// The buffers are concatenated in a single write transaction. | 836 | /// The buffers are concatenated in a single write transaction. |
| 830 | pub async fn write_vectored(&mut self, address: Address, write: &[&[u8]]) -> Result<(), Error> { | 837 | pub async fn write_vectored(&mut self, address: Address, write: &[&[u8]]) -> Result<(), Error> { |
| 838 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 839 | let _device_busy = crate::low_power::DeviceBusy::new_stop1(); | ||
| 831 | let timeout = self.timeout(); | 840 | let timeout = self.timeout(); |
| 832 | 841 | ||
| 833 | if write.is_empty() { | 842 | if write.is_empty() { |
| @@ -851,6 +860,8 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 851 | 860 | ||
| 852 | /// Read. | 861 | /// Read. |
| 853 | pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { | 862 | pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { |
| 863 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 864 | let _device_busy = crate::low_power::DeviceBusy::new_stop1(); | ||
| 854 | let timeout = self.timeout(); | 865 | let timeout = self.timeout(); |
| 855 | 866 | ||
| 856 | if buffer.is_empty() { | 867 | if buffer.is_empty() { |
| @@ -863,6 +874,8 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 863 | 874 | ||
| 864 | /// Write, restart, read. | 875 | /// Write, restart, read. |
| 865 | pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { | 876 | pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { |
| 877 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 878 | let _device_busy = crate::low_power::DeviceBusy::new_stop1(); | ||
| 866 | let timeout = self.timeout(); | 879 | let timeout = self.timeout(); |
| 867 | 880 | ||
| 868 | if write.is_empty() { | 881 | if write.is_empty() { |
| @@ -888,6 +901,8 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 888 | /// | 901 | /// |
| 889 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction | 902 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction |
| 890 | pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { | 903 | pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { |
| 904 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 905 | let _device_busy = crate::low_power::DeviceBusy::new_stop1(); | ||
| 891 | let _ = addr; | 906 | let _ = addr; |
| 892 | let _ = operations; | 907 | let _ = operations; |
| 893 | todo!() | 908 | todo!() |
| @@ -1181,7 +1196,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1181 | 1196 | ||
| 1182 | let regs = self.info.regs; | 1197 | let regs = self.info.regs; |
| 1183 | 1198 | ||
| 1184 | let dma_transfer = unsafe { | 1199 | let mut dma_transfer = unsafe { |
| 1185 | regs.cr1().modify(|w| { | 1200 | regs.cr1().modify(|w| { |
| 1186 | w.set_rxdmaen(true); | 1201 | w.set_rxdmaen(true); |
| 1187 | w.set_stopie(true); | 1202 | w.set_stopie(true); |
| @@ -1229,6 +1244,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1229 | }) | 1244 | }) |
| 1230 | .await?; | 1245 | .await?; |
| 1231 | 1246 | ||
| 1247 | dma_transfer.request_pause(); | ||
| 1232 | dma_transfer.await; | 1248 | dma_transfer.await; |
| 1233 | 1249 | ||
| 1234 | drop(on_drop); | 1250 | drop(on_drop); |
| @@ -1294,6 +1310,7 @@ impl<'d> I2c<'d, Async, MultiMaster> { | |||
| 1294 | }) | 1310 | }) |
| 1295 | .await?; | 1311 | .await?; |
| 1296 | 1312 | ||
| 1313 | dma_transfer.request_pause(); | ||
| 1297 | dma_transfer.await; | 1314 | dma_transfer.await; |
| 1298 | 1315 | ||
| 1299 | drop(on_drop); | 1316 | drop(on_drop); |
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index db22cfa11..df077a3ae 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs | |||
| @@ -7,6 +7,7 @@ use crate::Peri; | |||
| 7 | use crate::dma::{ChannelAndRequest, ReadableRingBuffer, TransferOptions, WritableRingBuffer, ringbuffer}; | 7 | use crate::dma::{ChannelAndRequest, ReadableRingBuffer, TransferOptions, WritableRingBuffer, ringbuffer}; |
| 8 | use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; | 8 | use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; |
| 9 | use crate::mode::Async; | 9 | use crate::mode::Async; |
| 10 | use crate::spi::mode::Master; | ||
| 10 | use crate::spi::{Config as SpiConfig, RegsExt as _, *}; | 11 | use crate::spi::{Config as SpiConfig, RegsExt as _, *}; |
| 11 | use crate::time::Hertz; | 12 | use crate::time::Hertz; |
| 12 | 13 | ||
| @@ -225,7 +226,7 @@ impl<'s, 'd, W: Word> Reader<'s, 'd, W> { | |||
| 225 | pub struct I2S<'d, W: Word> { | 226 | pub struct I2S<'d, W: Word> { |
| 226 | #[allow(dead_code)] | 227 | #[allow(dead_code)] |
| 227 | mode: Mode, | 228 | mode: Mode, |
| 228 | spi: Spi<'d, Async>, | 229 | spi: Spi<'d, Async, Master>, |
| 229 | txsd: Option<Peri<'d, AnyPin>>, | 230 | txsd: Option<Peri<'d, AnyPin>>, |
| 230 | rxsd: Option<Peri<'d, AnyPin>>, | 231 | rxsd: Option<Peri<'d, AnyPin>>, |
| 231 | ws: Option<Peri<'d, AnyPin>>, | 232 | ws: Option<Peri<'d, AnyPin>>, |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index dbf0fe620..e08ab30e6 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -54,6 +54,8 @@ pub mod timer; | |||
| 54 | 54 | ||
| 55 | #[cfg(adc)] | 55 | #[cfg(adc)] |
| 56 | pub mod adc; | 56 | pub mod adc; |
| 57 | #[cfg(backup_sram)] | ||
| 58 | pub mod backup_sram; | ||
| 57 | #[cfg(can)] | 59 | #[cfg(can)] |
| 58 | pub mod can; | 60 | pub mod can; |
| 59 | // FIXME: Cordic driver cause stm32u5a5zj crash | 61 | // FIXME: Cordic driver cause stm32u5a5zj crash |
| @@ -241,6 +243,14 @@ pub struct Config { | |||
| 241 | /// RCC config. | 243 | /// RCC config. |
| 242 | pub rcc: rcc::Config, | 244 | pub rcc: rcc::Config, |
| 243 | 245 | ||
| 246 | #[cfg(feature = "low-power")] | ||
| 247 | /// RTC config | ||
| 248 | pub rtc: rtc::RtcConfig, | ||
| 249 | |||
| 250 | #[cfg(feature = "low-power")] | ||
| 251 | /// Minimum time to stop | ||
| 252 | pub min_stop_pause: embassy_time::Duration, | ||
| 253 | |||
| 244 | /// Enable debug during sleep and stop. | 254 | /// Enable debug during sleep and stop. |
| 245 | /// | 255 | /// |
| 246 | /// May increase power consumption. Defaults to true. | 256 | /// May increase power consumption. Defaults to true. |
| @@ -294,6 +304,10 @@ impl Default for Config { | |||
| 294 | fn default() -> Self { | 304 | fn default() -> Self { |
| 295 | Self { | 305 | Self { |
| 296 | rcc: Default::default(), | 306 | rcc: Default::default(), |
| 307 | #[cfg(feature = "low-power")] | ||
| 308 | rtc: Default::default(), | ||
| 309 | #[cfg(feature = "low-power")] | ||
| 310 | min_stop_pause: embassy_time::Duration::from_millis(250), | ||
| 297 | #[cfg(dbgmcu)] | 311 | #[cfg(dbgmcu)] |
| 298 | enable_debug_during_sleep: true, | 312 | enable_debug_during_sleep: true, |
| 299 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba))] | 313 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba))] |
| @@ -623,6 +637,12 @@ fn init_hw(config: Config) -> Peripherals { | |||
| 623 | exti::init(cs); | 637 | exti::init(cs); |
| 624 | 638 | ||
| 625 | rcc::init_rcc(cs, config.rcc); | 639 | rcc::init_rcc(cs, config.rcc); |
| 640 | |||
| 641 | #[cfg(feature = "low-power")] | ||
| 642 | crate::rtc::init_rtc(cs, config.rtc); | ||
| 643 | |||
| 644 | #[cfg(feature = "low-power")] | ||
| 645 | crate::time_driver::get_driver().set_min_stop_pause(cs, config.min_stop_pause); | ||
| 626 | } | 646 | } |
| 627 | 647 | ||
| 628 | p | 648 | p |
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index 1b66ca680..696dfe83f 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs | |||
| @@ -41,12 +41,6 @@ | |||
| 41 | //! config.enable_debug_during_sleep = false; | 41 | //! config.enable_debug_during_sleep = false; |
| 42 | //! let p = embassy_stm32::init(config); | 42 | //! let p = embassy_stm32::init(config); |
| 43 | //! | 43 | //! |
| 44 | //! // give the RTC to the executor... | ||
| 45 | //! let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 46 | //! static RTC: StaticCell<Rtc> = StaticCell::new(); | ||
| 47 | //! let rtc = RTC.init(rtc); | ||
| 48 | //! embassy_stm32::low_power::stop_with_rtc(rtc); | ||
| 49 | //! | ||
| 50 | //! // your application here... | 44 | //! // your application here... |
| 51 | //! } | 45 | //! } |
| 52 | //! ``` | 46 | //! ``` |
| @@ -59,24 +53,69 @@ use core::marker::PhantomData; | |||
| 59 | use core::sync::atomic::{Ordering, compiler_fence}; | 53 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 60 | 54 | ||
| 61 | use cortex_m::peripheral::SCB; | 55 | use cortex_m::peripheral::SCB; |
| 56 | use critical_section::CriticalSection; | ||
| 62 | use embassy_executor::*; | 57 | use embassy_executor::*; |
| 63 | 58 | ||
| 64 | use crate::interrupt; | 59 | use crate::interrupt; |
| 65 | use crate::time_driver::{RtcDriver, get_driver}; | 60 | use crate::time_driver::get_driver; |
| 66 | 61 | ||
| 67 | const THREAD_PENDER: usize = usize::MAX; | 62 | const THREAD_PENDER: usize = usize::MAX; |
| 68 | 63 | ||
| 69 | use crate::rtc::Rtc; | ||
| 70 | |||
| 71 | static mut EXECUTOR: Option<Executor> = None; | 64 | static mut EXECUTOR: Option<Executor> = None; |
| 72 | 65 | ||
| 66 | /// Prevent the device from going into the stop mode if held | ||
| 67 | pub struct DeviceBusy(StopMode); | ||
| 68 | |||
| 69 | impl DeviceBusy { | ||
| 70 | /// Create a new DeviceBusy with stop1. | ||
| 71 | pub fn new_stop1() -> Self { | ||
| 72 | Self::new(StopMode::Stop1) | ||
| 73 | } | ||
| 74 | |||
| 75 | /// Create a new DeviceBusy with stop2. | ||
| 76 | pub fn new_stop2() -> Self { | ||
| 77 | Self::new(StopMode::Stop2) | ||
| 78 | } | ||
| 79 | |||
| 80 | /// Create a new DeviceBusy. | ||
| 81 | pub fn new(stop_mode: StopMode) -> Self { | ||
| 82 | critical_section::with(|_| unsafe { | ||
| 83 | match stop_mode { | ||
| 84 | StopMode::Stop1 => { | ||
| 85 | crate::rcc::REFCOUNT_STOP1 += 1; | ||
| 86 | } | ||
| 87 | StopMode::Stop2 => { | ||
| 88 | crate::rcc::REFCOUNT_STOP2 += 1; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | }); | ||
| 92 | |||
| 93 | Self(stop_mode) | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | impl Drop for DeviceBusy { | ||
| 98 | fn drop(&mut self) { | ||
| 99 | critical_section::with(|_| unsafe { | ||
| 100 | match self.0 { | ||
| 101 | StopMode::Stop1 => { | ||
| 102 | crate::rcc::REFCOUNT_STOP1 -= 1; | ||
| 103 | } | ||
| 104 | StopMode::Stop2 => { | ||
| 105 | crate::rcc::REFCOUNT_STOP2 -= 1; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | }); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 73 | #[cfg(not(stm32u0))] | 112 | #[cfg(not(stm32u0))] |
| 74 | foreach_interrupt! { | 113 | foreach_interrupt! { |
| 75 | (RTC, rtc, $block:ident, WKUP, $irq:ident) => { | 114 | (RTC, rtc, $block:ident, WKUP, $irq:ident) => { |
| 76 | #[interrupt] | 115 | #[interrupt] |
| 77 | #[allow(non_snake_case)] | 116 | #[allow(non_snake_case)] |
| 78 | unsafe fn $irq() { | 117 | unsafe fn $irq() { |
| 79 | EXECUTOR.as_mut().unwrap().on_wakeup_irq(); | 118 | Executor::on_wakeup_irq(); |
| 80 | } | 119 | } |
| 81 | }; | 120 | }; |
| 82 | } | 121 | } |
| @@ -87,31 +126,21 @@ foreach_interrupt! { | |||
| 87 | #[interrupt] | 126 | #[interrupt] |
| 88 | #[allow(non_snake_case)] | 127 | #[allow(non_snake_case)] |
| 89 | unsafe fn $irq() { | 128 | unsafe fn $irq() { |
| 90 | EXECUTOR.as_mut().unwrap().on_wakeup_irq(); | 129 | Executor::on_wakeup_irq(); |
| 91 | } | 130 | } |
| 92 | }; | 131 | }; |
| 93 | } | 132 | } |
| 94 | 133 | ||
| 95 | #[allow(dead_code)] | ||
| 96 | pub(crate) unsafe fn on_wakeup_irq() { | ||
| 97 | EXECUTOR.as_mut().unwrap().on_wakeup_irq(); | ||
| 98 | } | ||
| 99 | |||
| 100 | /// Configure STOP mode with RTC. | ||
| 101 | pub fn stop_with_rtc(rtc: &'static Rtc) { | ||
| 102 | unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc) | ||
| 103 | } | ||
| 104 | |||
| 105 | /// Get whether the core is ready to enter the given stop mode. | 134 | /// Get whether the core is ready to enter the given stop mode. |
| 106 | /// | 135 | /// |
| 107 | /// This will return false if some peripheral driver is in use that | 136 | /// This will return false if some peripheral driver is in use that |
| 108 | /// prevents entering the given stop mode. | 137 | /// prevents entering the given stop mode. |
| 109 | pub fn stop_ready(stop_mode: StopMode) -> bool { | 138 | pub fn stop_ready(stop_mode: StopMode) -> bool { |
| 110 | match unsafe { EXECUTOR.as_mut().unwrap() }.stop_mode() { | 139 | critical_section::with(|cs| match Executor::stop_mode(cs) { |
| 111 | Some(StopMode::Stop2) => true, | 140 | Some(StopMode::Stop2) => true, |
| 112 | Some(StopMode::Stop1) => stop_mode == StopMode::Stop1, | 141 | Some(StopMode::Stop1) => stop_mode == StopMode::Stop1, |
| 113 | None => false, | 142 | None => false, |
| 114 | } | 143 | }) |
| 115 | } | 144 | } |
| 116 | 145 | ||
| 117 | /// Available Stop modes. | 146 | /// Available Stop modes. |
| @@ -124,10 +153,10 @@ pub enum StopMode { | |||
| 124 | Stop2, | 153 | Stop2, |
| 125 | } | 154 | } |
| 126 | 155 | ||
| 127 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32u0))] | 156 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wlex, stm32u0))] |
| 128 | use stm32_metapac::pwr::vals::Lpms; | 157 | use stm32_metapac::pwr::vals::Lpms; |
| 129 | 158 | ||
| 130 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32u0))] | 159 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32wba, stm32wlex, stm32u0))] |
| 131 | impl Into<Lpms> for StopMode { | 160 | impl Into<Lpms> for StopMode { |
| 132 | fn into(self) -> Lpms { | 161 | fn into(self) -> Lpms { |
| 133 | match self { | 162 | match self { |
| @@ -154,7 +183,6 @@ pub struct Executor { | |||
| 154 | inner: raw::Executor, | 183 | inner: raw::Executor, |
| 155 | not_send: PhantomData<*mut ()>, | 184 | not_send: PhantomData<*mut ()>, |
| 156 | scb: SCB, | 185 | scb: SCB, |
| 157 | time_driver: &'static RtcDriver, | ||
| 158 | } | 186 | } |
| 159 | 187 | ||
| 160 | impl Executor { | 188 | impl Executor { |
| @@ -167,7 +195,6 @@ impl Executor { | |||
| 167 | inner: raw::Executor::new(THREAD_PENDER as *mut ()), | 195 | inner: raw::Executor::new(THREAD_PENDER as *mut ()), |
| 168 | not_send: PhantomData, | 196 | not_send: PhantomData, |
| 169 | scb: cortex_m::Peripherals::steal().SCB, | 197 | scb: cortex_m::Peripherals::steal().SCB, |
| 170 | time_driver: get_driver(), | ||
| 171 | }); | 198 | }); |
| 172 | 199 | ||
| 173 | let executor = EXECUTOR.as_mut().unwrap(); | 200 | let executor = EXECUTOR.as_mut().unwrap(); |
| @@ -176,21 +203,31 @@ impl Executor { | |||
| 176 | }) | 203 | }) |
| 177 | } | 204 | } |
| 178 | 205 | ||
| 179 | unsafe fn on_wakeup_irq(&mut self) { | 206 | pub(crate) unsafe fn on_wakeup_irq() { |
| 180 | self.time_driver.resume_time(); | 207 | critical_section::with(|cs| { |
| 181 | trace!("low power: resume"); | 208 | #[cfg(stm32wlex)] |
| 182 | } | 209 | { |
| 183 | 210 | let extscr = crate::pac::PWR.extscr().read(); | |
| 184 | pub(self) fn stop_with_rtc(&mut self, rtc: &'static Rtc) { | 211 | if extscr.c1stop2f() || extscr.c1stopf() { |
| 185 | self.time_driver.set_rtc(rtc); | 212 | // when we wake from any stop mode we need to re-initialize the rcc |
| 186 | 213 | crate::rcc::apply_resume_config(); | |
| 187 | rtc.enable_wakeup_line(); | 214 | if extscr.c1stop2f() { |
| 188 | 215 | // when we wake from STOP2, we need to re-initialize the time driver | |
| 189 | trace!("low power: stop with rtc configured"); | 216 | crate::time_driver::init_timer(cs); |
| 217 | // reset the refcounts for STOP2 and STOP1 (initializing the time driver will increment one of them for the timer) | ||
| 218 | // and given that we just woke from STOP2, we can reset them | ||
| 219 | crate::rcc::REFCOUNT_STOP2 = 0; | ||
| 220 | crate::rcc::REFCOUNT_STOP1 = 0; | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | get_driver().resume_time(cs); | ||
| 225 | trace!("low power: resume"); | ||
| 226 | }); | ||
| 190 | } | 227 | } |
| 191 | 228 | ||
| 192 | fn stop_mode(&self) -> Option<StopMode> { | 229 | fn stop_mode(_cs: CriticalSection) -> Option<StopMode> { |
| 193 | if unsafe { crate::rcc::REFCOUNT_STOP2 == 0 } && unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } { | 230 | if unsafe { crate::rcc::REFCOUNT_STOP2 == 0 && crate::rcc::REFCOUNT_STOP1 == 0 } { |
| 194 | Some(StopMode::Stop2) | 231 | Some(StopMode::Stop2) |
| 195 | } else if unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } { | 232 | } else if unsafe { crate::rcc::REFCOUNT_STOP1 == 0 } { |
| 196 | Some(StopMode::Stop1) | 233 | Some(StopMode::Stop1) |
| @@ -201,7 +238,7 @@ impl Executor { | |||
| 201 | 238 | ||
| 202 | #[allow(unused_variables)] | 239 | #[allow(unused_variables)] |
| 203 | fn configure_stop(&mut self, stop_mode: StopMode) { | 240 | fn configure_stop(&mut self, stop_mode: StopMode) { |
| 204 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wba))] | 241 | #[cfg(any(stm32l4, stm32l5, stm32u5, stm32u0, stm32wba, stm32wlex))] |
| 205 | crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); | 242 | crate::pac::PWR.cr1().modify(|m| m.set_lpms(stop_mode.into())); |
| 206 | #[cfg(stm32h5)] | 243 | #[cfg(stm32h5)] |
| 207 | crate::pac::PWR.pmcr().modify(|v| { | 244 | crate::pac::PWR.pmcr().modify(|v| { |
| @@ -213,17 +250,22 @@ impl Executor { | |||
| 213 | 250 | ||
| 214 | fn configure_pwr(&mut self) { | 251 | fn configure_pwr(&mut self) { |
| 215 | self.scb.clear_sleepdeep(); | 252 | self.scb.clear_sleepdeep(); |
| 253 | // Clear any previous stop flags | ||
| 254 | #[cfg(stm32wlex)] | ||
| 255 | crate::pac::PWR.extscr().modify(|w| { | ||
| 256 | w.set_c1cssf(true); | ||
| 257 | }); | ||
| 216 | 258 | ||
| 217 | compiler_fence(Ordering::SeqCst); | 259 | compiler_fence(Ordering::SeqCst); |
| 218 | 260 | ||
| 219 | let stop_mode = self.stop_mode(); | 261 | let stop_mode = critical_section::with(|cs| Self::stop_mode(cs)); |
| 220 | 262 | ||
| 221 | if stop_mode.is_none() { | 263 | if stop_mode.is_none() { |
| 222 | trace!("low power: not ready to stop"); | 264 | trace!("low power: not ready to stop"); |
| 223 | return; | 265 | return; |
| 224 | } | 266 | } |
| 225 | 267 | ||
| 226 | if self.time_driver.pause_time().is_err() { | 268 | if get_driver().pause_time().is_err() { |
| 227 | trace!("low power: failed to pause time"); | 269 | trace!("low power: failed to pause time"); |
| 228 | return; | 270 | return; |
| 229 | } | 271 | } |
| @@ -266,6 +308,19 @@ impl Executor { | |||
| 266 | executor.inner.poll(); | 308 | executor.inner.poll(); |
| 267 | self.configure_pwr(); | 309 | self.configure_pwr(); |
| 268 | asm!("wfe"); | 310 | asm!("wfe"); |
| 311 | #[cfg(stm32wlex)] | ||
| 312 | { | ||
| 313 | let es = crate::pac::PWR.extscr().read(); | ||
| 314 | match (es.c1stopf(), es.c1stop2f()) { | ||
| 315 | (true, false) => debug!("low power: wake from STOP1"), | ||
| 316 | (false, true) => debug!("low power: wake from STOP2"), | ||
| 317 | (true, true) => debug!("low power: wake from STOP1 and STOP2 ???"), | ||
| 318 | (false, false) => trace!("low power: stop mode not entered"), | ||
| 319 | }; | ||
| 320 | crate::pac::PWR.extscr().modify(|w| { | ||
| 321 | w.set_c1cssf(false); | ||
| 322 | }); | ||
| 323 | } | ||
| 269 | }; | 324 | }; |
| 270 | } | 325 | } |
| 271 | } | 326 | } |
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 3b2a10581..5b367c043 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | use core::sync::atomic::{Ordering, compiler_fence}; | 1 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 2 | 2 | ||
| 3 | use crate::pac::common::{RW, Reg}; | 3 | use crate::pac::common::{RW, Reg}; |
| 4 | #[cfg(backup_sram)] | ||
| 5 | use crate::pac::pwr::vals::Retention; | ||
| 4 | pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource; | 6 | pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource; |
| 5 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| 6 | 8 | ||
| @@ -89,6 +91,8 @@ pub struct LsConfig { | |||
| 89 | pub rtc: RtcClockSource, | 91 | pub rtc: RtcClockSource, |
| 90 | pub lsi: bool, | 92 | pub lsi: bool, |
| 91 | pub lse: Option<LseConfig>, | 93 | pub lse: Option<LseConfig>, |
| 94 | #[cfg(backup_sram)] | ||
| 95 | pub enable_backup_sram: bool, | ||
| 92 | } | 96 | } |
| 93 | 97 | ||
| 94 | impl LsConfig { | 98 | impl LsConfig { |
| @@ -113,6 +117,8 @@ impl LsConfig { | |||
| 113 | peripherals_clocked: false, | 117 | peripherals_clocked: false, |
| 114 | }), | 118 | }), |
| 115 | lsi: false, | 119 | lsi: false, |
| 120 | #[cfg(backup_sram)] | ||
| 121 | enable_backup_sram: false, | ||
| 116 | } | 122 | } |
| 117 | } | 123 | } |
| 118 | 124 | ||
| @@ -121,6 +127,8 @@ impl LsConfig { | |||
| 121 | rtc: RtcClockSource::LSI, | 127 | rtc: RtcClockSource::LSI, |
| 122 | lsi: true, | 128 | lsi: true, |
| 123 | lse: None, | 129 | lse: None, |
| 130 | #[cfg(backup_sram)] | ||
| 131 | enable_backup_sram: false, | ||
| 124 | } | 132 | } |
| 125 | } | 133 | } |
| 126 | 134 | ||
| @@ -129,6 +137,8 @@ impl LsConfig { | |||
| 129 | rtc: RtcClockSource::DISABLE, | 137 | rtc: RtcClockSource::DISABLE, |
| 130 | lsi: false, | 138 | lsi: false, |
| 131 | lse: None, | 139 | lse: None, |
| 140 | #[cfg(backup_sram)] | ||
| 141 | enable_backup_sram: false, | ||
| 132 | } | 142 | } |
| 133 | } | 143 | } |
| 134 | } | 144 | } |
| @@ -193,6 +203,22 @@ impl LsConfig { | |||
| 193 | while !csr.read().lsi1rdy() {} | 203 | while !csr.read().lsi1rdy() {} |
| 194 | } | 204 | } |
| 195 | 205 | ||
| 206 | // Enable backup regulator for peristent battery backed sram | ||
| 207 | #[cfg(backup_sram)] | ||
| 208 | { | ||
| 209 | unsafe { super::BKSRAM_RETAINED = crate::pac::PWR.bdcr().read().bren() == Retention::PRESERVED }; | ||
| 210 | |||
| 211 | crate::pac::PWR.bdcr().modify(|w| { | ||
| 212 | w.set_bren(match self.enable_backup_sram { | ||
| 213 | true => Retention::PRESERVED, | ||
| 214 | false => Retention::LOST, | ||
| 215 | }); | ||
| 216 | }); | ||
| 217 | |||
| 218 | // Wait for backup regulator voltage to stabilize | ||
| 219 | while self.enable_backup_sram && !crate::pac::PWR.bdsr().read().brrdy() {} | ||
| 220 | } | ||
| 221 | |||
| 196 | // backup domain configuration (LSEON, RTCEN, RTCSEL) is kept across resets. | 222 | // backup domain configuration (LSEON, RTCEN, RTCSEL) is kept across resets. |
| 197 | // once set, changing it requires a backup domain reset. | 223 | // once set, changing it requires a backup domain reset. |
| 198 | // first check if the configuration matches what we want. | 224 | // first check if the configuration matches what we want. |
diff --git a/embassy-stm32/src/rcc/l.rs b/embassy-stm32/src/rcc/l.rs index 2e1cbd702..584957c6d 100644 --- a/embassy-stm32/src/rcc/l.rs +++ b/embassy-stm32/src/rcc/l.rs | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 2 | use core::mem::MaybeUninit; | ||
| 3 | |||
| 1 | #[cfg(any(stm32l0, stm32l1))] | 4 | #[cfg(any(stm32l0, stm32l1))] |
| 2 | pub use crate::pac::pwr::vals::Vos as VoltageScale; | 5 | pub use crate::pac::pwr::vals::Vos as VoltageScale; |
| 3 | use crate::pac::rcc::regs::Cfgr; | 6 | use crate::pac::rcc::regs::Cfgr; |
| @@ -11,6 +14,42 @@ use crate::time::Hertz; | |||
| 11 | /// HSI speed | 14 | /// HSI speed |
| 12 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | 15 | pub const HSI_FREQ: Hertz = Hertz(16_000_000); |
| 13 | 16 | ||
| 17 | /// Saved RCC Config | ||
| 18 | /// | ||
| 19 | /// Used when exiting STOP2 to re-enable clocks to their last configured state | ||
| 20 | /// for chips that need it. | ||
| 21 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 22 | static mut RESUME_RCC_CONFIG: MaybeUninit<Config> = MaybeUninit::uninit(); | ||
| 23 | |||
| 24 | /// Set the rcc config to be restored when exiting STOP2 | ||
| 25 | /// | ||
| 26 | /// Safety: Sets a mutable global. | ||
| 27 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 28 | pub(crate) unsafe fn set_resume_config(config: Config) { | ||
| 29 | trace!("rcc set_resume_config()"); | ||
| 30 | RESUME_RCC_CONFIG = MaybeUninit::new(config); | ||
| 31 | } | ||
| 32 | |||
| 33 | /// Get the rcc config to be restored when exiting STOP2 | ||
| 34 | /// | ||
| 35 | /// Safety: Reads a mutable global. | ||
| 36 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 37 | pub(crate) unsafe fn get_resume_config() -> Config { | ||
| 38 | *(*core::ptr::addr_of_mut!(RESUME_RCC_CONFIG)).assume_init_ref() | ||
| 39 | } | ||
| 40 | |||
| 41 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 42 | /// Safety: should only be called from low power executable just after resuming from STOP2 | ||
| 43 | pub(crate) unsafe fn apply_resume_config() { | ||
| 44 | trace!("rcc apply_resume_config()"); | ||
| 45 | |||
| 46 | while RCC.cfgr().read().sws() != Sysclk::MSI {} | ||
| 47 | |||
| 48 | let config = get_resume_config(); | ||
| 49 | |||
| 50 | init(config); | ||
| 51 | } | ||
| 52 | |||
| 14 | #[derive(Clone, Copy, Eq, PartialEq)] | 53 | #[derive(Clone, Copy, Eq, PartialEq)] |
| 15 | pub enum HseMode { | 54 | pub enum HseMode { |
| 16 | /// crystal/ceramic oscillator (HSEBYP=0) | 55 | /// crystal/ceramic oscillator (HSEBYP=0) |
| @@ -154,6 +193,10 @@ fn msi_enable(range: MSIRange) { | |||
| 154 | } | 193 | } |
| 155 | 194 | ||
| 156 | pub(crate) unsafe fn init(config: Config) { | 195 | pub(crate) unsafe fn init(config: Config) { |
| 196 | // save the rcc config because if we enter stop 2 we need to re-apply it on wakeup | ||
| 197 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 198 | set_resume_config(config); | ||
| 199 | |||
| 157 | // Switch to MSI to prevent problems with PLL configuration. | 200 | // Switch to MSI to prevent problems with PLL configuration. |
| 158 | if !RCC.cr().read().msion() { | 201 | if !RCC.cr().read().msion() { |
| 159 | // Turn on MSI and configure it to 4MHz. | 202 | // Turn on MSI and configure it to 4MHz. |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index addfca3c3..01fa3a475 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -48,6 +48,9 @@ pub(crate) static mut REFCOUNT_STOP1: u32 = 0; | |||
| 48 | /// May be read without a critical section | 48 | /// May be read without a critical section |
| 49 | pub(crate) static mut REFCOUNT_STOP2: u32 = 0; | 49 | pub(crate) static mut REFCOUNT_STOP2: u32 = 0; |
| 50 | 50 | ||
| 51 | #[cfg(backup_sram)] | ||
| 52 | pub(crate) static mut BKSRAM_RETAINED: bool = false; | ||
| 53 | |||
| 51 | #[cfg(not(feature = "_dual-core"))] | 54 | #[cfg(not(feature = "_dual-core"))] |
| 52 | /// Frozen clock frequencies | 55 | /// Frozen clock frequencies |
| 53 | /// | 56 | /// |
| @@ -390,7 +393,7 @@ pub fn disable<T: RccPeripheral>() { | |||
| 390 | /// | 393 | /// |
| 391 | /// This should only be called after `init`. | 394 | /// This should only be called after `init`. |
| 392 | #[cfg(not(feature = "_dual-core"))] | 395 | #[cfg(not(feature = "_dual-core"))] |
| 393 | pub fn reinit<'a>(config: Config, _rcc: &'a mut crate::Peri<'a, crate::peripherals::RCC>) { | 396 | pub fn reinit(config: Config, _rcc: &'_ mut crate::Peri<'_, crate::peripherals::RCC>) { |
| 394 | critical_section::with(|cs| init_rcc(cs, config)) | 397 | critical_section::with(|cs| init_rcc(cs, config)) |
| 395 | } | 398 | } |
| 396 | 399 | ||
diff --git a/embassy-stm32/src/rtc/low_power.rs b/embassy-stm32/src/rtc/low_power.rs index 999f24714..e5bf30927 100644 --- a/embassy-stm32/src/rtc/low_power.rs +++ b/embassy-stm32/src/rtc/low_power.rs | |||
| @@ -4,7 +4,7 @@ use embassy_time::{Duration, TICK_HZ}; | |||
| 4 | use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; | 4 | use super::{DateTimeError, Rtc, RtcError, bcd2_to_byte}; |
| 5 | use crate::interrupt::typelevel::Interrupt; | 5 | use crate::interrupt::typelevel::Interrupt; |
| 6 | use crate::peripherals::RTC; | 6 | use crate::peripherals::RTC; |
| 7 | use crate::rtc::SealedInstance; | 7 | use crate::rtc::{RtcTimeProvider, SealedInstance}; |
| 8 | 8 | ||
| 9 | /// Represents an instant in time that can be substracted to compute a duration | 9 | /// Represents an instant in time that can be substracted to compute a duration |
| 10 | pub(super) struct RtcInstant { | 10 | pub(super) struct RtcInstant { |
| @@ -68,7 +68,7 @@ pub(crate) enum WakeupPrescaler { | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | #[cfg(any( | 70 | #[cfg(any( |
| 71 | stm32f4, stm32l0, stm32g4, stm32l4, stm32l5, stm32wb, stm32h5, stm32g0, stm32u5, stm32u0, stm32wba | 71 | stm32f4, stm32l0, stm32g4, stm32l4, stm32l5, stm32wb, stm32h5, stm32g0, stm32u5, stm32u0, stm32wba, stm32wlex |
| 72 | ))] | 72 | ))] |
| 73 | impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { | 73 | impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { |
| 74 | fn from(val: WakeupPrescaler) -> Self { | 74 | fn from(val: WakeupPrescaler) -> Self { |
| @@ -84,7 +84,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | #[cfg(any( | 86 | #[cfg(any( |
| 87 | stm32f4, stm32l0, stm32g4, stm32l4, stm32l5, stm32wb, stm32h5, stm32g0, stm32u5, stm32u0, stm32wba | 87 | stm32f4, stm32l0, stm32g4, stm32l4, stm32l5, stm32wb, stm32h5, stm32g0, stm32u5, stm32u0, stm32wba, stm32wlex |
| 88 | ))] | 88 | ))] |
| 89 | impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { | 89 | impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { |
| 90 | fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { | 90 | fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { |
| @@ -117,7 +117,7 @@ impl WakeupPrescaler { | |||
| 117 | impl Rtc { | 117 | impl Rtc { |
| 118 | /// Return the current instant. | 118 | /// Return the current instant. |
| 119 | fn instant(&self) -> Result<RtcInstant, RtcError> { | 119 | fn instant(&self) -> Result<RtcInstant, RtcError> { |
| 120 | self.time_provider().read(|_, tr, ss| { | 120 | RtcTimeProvider::new().read(|_, tr, ss| { |
| 121 | let second = bcd2_to_byte((tr.st(), tr.su())); | 121 | let second = bcd2_to_byte((tr.st(), tr.su())); |
| 122 | 122 | ||
| 123 | RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) | 123 | RtcInstant::from(second, ss).map_err(RtcError::InvalidDateTime) |
| @@ -127,7 +127,7 @@ impl Rtc { | |||
| 127 | /// start the wakeup alarm and with a duration that is as close to but less than | 127 | /// start the wakeup alarm and with a duration that is as close to but less than |
| 128 | /// the requested duration, and record the instant the wakeup alarm was started | 128 | /// the requested duration, and record the instant the wakeup alarm was started |
| 129 | pub(crate) fn start_wakeup_alarm( | 129 | pub(crate) fn start_wakeup_alarm( |
| 130 | &self, | 130 | &mut self, |
| 131 | requested_duration: embassy_time::Duration, | 131 | requested_duration: embassy_time::Duration, |
| 132 | cs: critical_section::CriticalSection, | 132 | cs: critical_section::CriticalSection, |
| 133 | ) { | 133 | ) { |
| @@ -179,7 +179,10 @@ impl Rtc { | |||
| 179 | 179 | ||
| 180 | /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` | 180 | /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` |
| 181 | /// was called, otherwise none | 181 | /// was called, otherwise none |
| 182 | pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> { | 182 | pub(crate) fn stop_wakeup_alarm( |
| 183 | &mut self, | ||
| 184 | cs: critical_section::CriticalSection, | ||
| 185 | ) -> Option<embassy_time::Duration> { | ||
| 183 | let instant = self.instant().unwrap(); | 186 | let instant = self.instant().unwrap(); |
| 184 | if RTC::regs().cr().read().wute() { | 187 | if RTC::regs().cr().read().wute() { |
| 185 | trace!("rtc: stop wakeup alarm at {}", instant); | 188 | trace!("rtc: stop wakeup alarm at {}", instant); |
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index bc6df528b..116b3c7ed 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -5,9 +5,13 @@ mod datetime; | |||
| 5 | mod low_power; | 5 | mod low_power; |
| 6 | 6 | ||
| 7 | #[cfg(feature = "low-power")] | 7 | #[cfg(feature = "low-power")] |
| 8 | use core::cell::Cell; | 8 | use core::cell::{Cell, RefCell, RefMut}; |
| 9 | #[cfg(feature = "low-power")] | ||
| 10 | use core::ops; | ||
| 9 | 11 | ||
| 10 | #[cfg(feature = "low-power")] | 12 | #[cfg(feature = "low-power")] |
| 13 | use critical_section::CriticalSection; | ||
| 14 | #[cfg(feature = "low-power")] | ||
| 11 | use embassy_sync::blocking_mutex::Mutex; | 15 | use embassy_sync::blocking_mutex::Mutex; |
| 12 | #[cfg(feature = "low-power")] | 16 | #[cfg(feature = "low-power")] |
| 13 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 17 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| @@ -44,11 +48,17 @@ pub enum RtcError { | |||
| 44 | } | 48 | } |
| 45 | 49 | ||
| 46 | /// Provides immutable access to the current time of the RTC. | 50 | /// Provides immutable access to the current time of the RTC. |
| 51 | #[derive(Clone)] | ||
| 47 | pub struct RtcTimeProvider { | 52 | pub struct RtcTimeProvider { |
| 48 | _private: (), | 53 | _private: (), |
| 49 | } | 54 | } |
| 50 | 55 | ||
| 51 | impl RtcTimeProvider { | 56 | impl RtcTimeProvider { |
| 57 | /// Create a new RTC time provider instance. | ||
| 58 | pub(self) const fn new() -> Self { | ||
| 59 | Self { _private: () } | ||
| 60 | } | ||
| 61 | |||
| 52 | /// Return the current datetime. | 62 | /// Return the current datetime. |
| 53 | /// | 63 | /// |
| 54 | /// # Errors | 64 | /// # Errors |
| @@ -106,6 +116,50 @@ impl RtcTimeProvider { | |||
| 106 | } | 116 | } |
| 107 | } | 117 | } |
| 108 | 118 | ||
| 119 | #[cfg(feature = "low-power")] | ||
| 120 | /// Contains an RTC driver. | ||
| 121 | pub struct RtcContainer { | ||
| 122 | pub(self) mutex: &'static Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc>>>, | ||
| 123 | } | ||
| 124 | |||
| 125 | #[cfg(feature = "low-power")] | ||
| 126 | impl RtcContainer { | ||
| 127 | pub(self) const fn new() -> Self { | ||
| 128 | Self { | ||
| 129 | mutex: &crate::time_driver::get_driver().rtc, | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | /// Acquire an RTC borrow. | ||
| 134 | pub fn borrow_mut<'a>(&self, cs: CriticalSection<'a>) -> RtcBorrow<'a> { | ||
| 135 | RtcBorrow { | ||
| 136 | ref_mut: self.mutex.borrow(cs).borrow_mut(), | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | #[cfg(feature = "low-power")] | ||
| 142 | /// Contains an RTC borrow. | ||
| 143 | pub struct RtcBorrow<'a> { | ||
| 144 | pub(self) ref_mut: RefMut<'a, Option<Rtc>>, | ||
| 145 | } | ||
| 146 | |||
| 147 | #[cfg(feature = "low-power")] | ||
| 148 | impl<'a> ops::Deref for RtcBorrow<'a> { | ||
| 149 | type Target = Rtc; | ||
| 150 | |||
| 151 | fn deref(&self) -> &Self::Target { | ||
| 152 | self.ref_mut.as_ref().unwrap() | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | #[cfg(feature = "low-power")] | ||
| 157 | impl<'a> ops::DerefMut for RtcBorrow<'a> { | ||
| 158 | fn deref_mut(&mut self) -> &mut Self::Target { | ||
| 159 | self.ref_mut.as_mut().unwrap() | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 109 | /// RTC driver. | 163 | /// RTC driver. |
| 110 | pub struct Rtc { | 164 | pub struct Rtc { |
| 111 | #[cfg(feature = "low-power")] | 165 | #[cfg(feature = "low-power")] |
| @@ -121,13 +175,21 @@ pub struct RtcConfig { | |||
| 121 | /// | 175 | /// |
| 122 | /// A high counter frequency may impact stop power consumption | 176 | /// A high counter frequency may impact stop power consumption |
| 123 | pub frequency: Hertz, | 177 | pub frequency: Hertz, |
| 178 | |||
| 179 | #[cfg(feature = "_allow-disable-rtc")] | ||
| 180 | /// Allow disabling the rtc, even when stop is configured | ||
| 181 | pub _disable_rtc: bool, | ||
| 124 | } | 182 | } |
| 125 | 183 | ||
| 126 | impl Default for RtcConfig { | 184 | impl Default for RtcConfig { |
| 127 | /// LSI with prescalers assuming 32.768 kHz. | 185 | /// LSI with prescalers assuming 32.768 kHz. |
| 128 | /// Raw sub-seconds in 1/256. | 186 | /// Raw sub-seconds in 1/256. |
| 129 | fn default() -> Self { | 187 | fn default() -> Self { |
| 130 | RtcConfig { frequency: Hertz(256) } | 188 | RtcConfig { |
| 189 | frequency: Hertz(256), | ||
| 190 | #[cfg(feature = "_allow-disable-rtc")] | ||
| 191 | _disable_rtc: false, | ||
| 192 | } | ||
| 131 | } | 193 | } |
| 132 | } | 194 | } |
| 133 | 195 | ||
| @@ -145,8 +207,19 @@ pub enum RtcCalibrationCyclePeriod { | |||
| 145 | } | 207 | } |
| 146 | 208 | ||
| 147 | impl Rtc { | 209 | impl Rtc { |
| 210 | #[cfg(not(feature = "low-power"))] | ||
| 211 | /// Create a new RTC instance. | ||
| 212 | pub fn new(_rtc: Peri<'static, RTC>, rtc_config: RtcConfig) -> (Self, RtcTimeProvider) { | ||
| 213 | (Self::new_inner(rtc_config), RtcTimeProvider::new()) | ||
| 214 | } | ||
| 215 | |||
| 216 | #[cfg(feature = "low-power")] | ||
| 148 | /// Create a new RTC instance. | 217 | /// Create a new RTC instance. |
| 149 | pub fn new(_rtc: Peri<'static, RTC>, rtc_config: RtcConfig) -> Self { | 218 | pub fn new(_rtc: Peri<'static, RTC>) -> (RtcContainer, RtcTimeProvider) { |
| 219 | (RtcContainer::new(), RtcTimeProvider::new()) | ||
| 220 | } | ||
| 221 | |||
| 222 | pub(self) fn new_inner(rtc_config: RtcConfig) -> Self { | ||
| 150 | #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] | 223 | #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] |
| 151 | crate::rcc::enable_and_reset::<RTC>(); | 224 | crate::rcc::enable_and_reset::<RTC>(); |
| 152 | 225 | ||
| @@ -165,10 +238,13 @@ impl Rtc { | |||
| 165 | // Wait for the clock to update after initialization | 238 | // Wait for the clock to update after initialization |
| 166 | #[cfg(not(rtc_v2_f2))] | 239 | #[cfg(not(rtc_v2_f2))] |
| 167 | { | 240 | { |
| 168 | let now = this.time_provider().read(|_, _, ss| Ok(ss)).unwrap(); | 241 | let now = RtcTimeProvider::new().read(|_, _, ss| Ok(ss)).unwrap(); |
| 169 | while now == this.time_provider().read(|_, _, ss| Ok(ss)).unwrap() {} | 242 | while now == RtcTimeProvider::new().read(|_, _, ss| Ok(ss)).unwrap() {} |
| 170 | } | 243 | } |
| 171 | 244 | ||
| 245 | #[cfg(feature = "low-power")] | ||
| 246 | this.enable_wakeup_line(); | ||
| 247 | |||
| 172 | this | 248 | this |
| 173 | } | 249 | } |
| 174 | 250 | ||
| @@ -177,11 +253,6 @@ impl Rtc { | |||
| 177 | freqs.rtc.to_hertz().unwrap() | 253 | freqs.rtc.to_hertz().unwrap() |
| 178 | } | 254 | } |
| 179 | 255 | ||
| 180 | /// Acquire a [`RtcTimeProvider`] instance. | ||
| 181 | pub const fn time_provider(&self) -> RtcTimeProvider { | ||
| 182 | RtcTimeProvider { _private: () } | ||
| 183 | } | ||
| 184 | |||
| 185 | /// Set the datetime to a new value. | 256 | /// Set the datetime to a new value. |
| 186 | /// | 257 | /// |
| 187 | /// # Errors | 258 | /// # Errors |
| @@ -225,15 +296,6 @@ impl Rtc { | |||
| 225 | Ok(()) | 296 | Ok(()) |
| 226 | } | 297 | } |
| 227 | 298 | ||
| 228 | /// Return the current datetime. | ||
| 229 | /// | ||
| 230 | /// # Errors | ||
| 231 | /// | ||
| 232 | /// Will return an `RtcError::InvalidDateTime` if the stored value in the system is not a valid [`DayOfWeek`]. | ||
| 233 | pub fn now(&self) -> Result<DateTime, RtcError> { | ||
| 234 | self.time_provider().now() | ||
| 235 | } | ||
| 236 | |||
| 237 | /// Check if daylight savings time is active. | 299 | /// Check if daylight savings time is active. |
| 238 | pub fn get_daylight_savings(&self) -> bool { | 300 | pub fn get_daylight_savings(&self) -> bool { |
| 239 | let cr = RTC::regs().cr().read(); | 301 | let cr = RTC::regs().cr().read(); |
| @@ -315,3 +377,15 @@ trait SealedInstance { | |||
| 315 | 377 | ||
| 316 | // fn apply_config(&mut self, rtc_config: RtcConfig); | 378 | // fn apply_config(&mut self, rtc_config: RtcConfig); |
| 317 | } | 379 | } |
| 380 | |||
| 381 | #[cfg(feature = "low-power")] | ||
| 382 | pub(crate) fn init_rtc(cs: CriticalSection, config: RtcConfig) { | ||
| 383 | #[cfg(feature = "_allow-disable-rtc")] | ||
| 384 | if config._disable_rtc { | ||
| 385 | return; | ||
| 386 | } | ||
| 387 | |||
| 388 | crate::time_driver::get_driver().set_rtc(cs, Rtc::new_inner(config)); | ||
| 389 | |||
| 390 | trace!("low power: stop with rtc configured"); | ||
| 391 | } | ||
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 23f6ccb0c..8ac022536 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -93,7 +93,7 @@ impl super::Rtc { | |||
| 93 | }) | 93 | }) |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | pub(super) fn write<F, R>(&self, init_mode: bool, f: F) -> R | 96 | pub(super) fn write<F, R>(&mut self, init_mode: bool, f: F) -> R |
| 97 | where | 97 | where |
| 98 | F: FnOnce(crate::pac::rtc::Rtc) -> R, | 98 | F: FnOnce(crate::pac::rtc::Rtc) -> R, |
| 99 | { | 99 | { |
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 01da5d70a..f7ebea73e 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs | |||
| @@ -95,7 +95,7 @@ impl super::Rtc { | |||
| 95 | }) | 95 | }) |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | pub(super) fn write<F, R>(&self, init_mode: bool, f: F) -> R | 98 | pub(super) fn write<F, R>(&mut self, init_mode: bool, f: F) -> R |
| 99 | where | 99 | where |
| 100 | F: FnOnce(crate::pac::rtc::Rtc) -> R, | 100 | F: FnOnce(crate::pac::rtc::Rtc) -> R, |
| 101 | { | 101 | { |
| @@ -131,7 +131,7 @@ impl SealedInstance for crate::peripherals::RTC { | |||
| 131 | 131 | ||
| 132 | #[cfg(feature = "low-power")] | 132 | #[cfg(feature = "low-power")] |
| 133 | cfg_if::cfg_if!( | 133 | cfg_if::cfg_if!( |
| 134 | if #[cfg(stm32g4)] { | 134 | if #[cfg(any(stm32g4, stm32wlex))] { |
| 135 | const EXTI_WAKEUP_LINE: usize = 20; | 135 | const EXTI_WAKEUP_LINE: usize = 20; |
| 136 | } else if #[cfg(stm32g0)] { | 136 | } else if #[cfg(stm32g0)] { |
| 137 | const EXTI_WAKEUP_LINE: usize = 19; | 137 | const EXTI_WAKEUP_LINE: usize = 19; |
| @@ -142,7 +142,7 @@ impl SealedInstance for crate::peripherals::RTC { | |||
| 142 | 142 | ||
| 143 | #[cfg(feature = "low-power")] | 143 | #[cfg(feature = "low-power")] |
| 144 | cfg_if::cfg_if!( | 144 | cfg_if::cfg_if!( |
| 145 | if #[cfg(stm32g4)] { | 145 | if #[cfg(any(stm32g4, stm32wlex))] { |
| 146 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; | 146 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; |
| 147 | } else if #[cfg(any(stm32g0, stm32u0))] { | 147 | } else if #[cfg(any(stm32g0, stm32u0))] { |
| 148 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; | 148 | type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; |
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index 408d1b764..e05131040 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -1032,12 +1032,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> { | |||
| 1032 | 1032 | ||
| 1033 | /// Wait for a previously started datapath transfer to complete from an interrupt. | 1033 | /// Wait for a previously started datapath transfer to complete from an interrupt. |
| 1034 | #[inline] | 1034 | #[inline] |
| 1035 | #[allow(unused)] | ||
| 1035 | async fn complete_datapath_transfer(block: bool) -> Result<(), Error> { | 1036 | async fn complete_datapath_transfer(block: bool) -> Result<(), Error> { |
| 1036 | let regs = T::regs(); | ||
| 1037 | |||
| 1038 | let res = poll_fn(|cx| { | 1037 | let res = poll_fn(|cx| { |
| 1038 | // Compiler might not be sufficiently constrained here | ||
| 1039 | // https://github.com/embassy-rs/embassy/issues/4723 | ||
| 1039 | T::state().register(cx.waker()); | 1040 | T::state().register(cx.waker()); |
| 1040 | let status = regs.star().read(); | 1041 | let status = T::regs().star().read(); |
| 1041 | 1042 | ||
| 1042 | if status.dcrcfail() { | 1043 | if status.dcrcfail() { |
| 1043 | return Poll::Ready(Err(Error::Crc)); | 1044 | return Poll::Ready(Err(Error::Crc)); |
| @@ -1052,10 +1053,13 @@ impl<'d, T: Instance> Sdmmc<'d, T> { | |||
| 1052 | if status.stbiterr() { | 1053 | if status.stbiterr() { |
| 1053 | return Poll::Ready(Err(Error::StBitErr)); | 1054 | return Poll::Ready(Err(Error::StBitErr)); |
| 1054 | } | 1055 | } |
| 1056 | #[cfg(sdmmc_v1)] | ||
| 1055 | let done = match block { | 1057 | let done = match block { |
| 1056 | true => status.dbckend(), | 1058 | true => status.dbckend(), |
| 1057 | false => status.dataend(), | 1059 | false => status.dataend(), |
| 1058 | }; | 1060 | }; |
| 1061 | #[cfg(sdmmc_v2)] | ||
| 1062 | let done = status.dataend(); | ||
| 1059 | if done { | 1063 | if done { |
| 1060 | return Poll::Ready(Ok(())); | 1064 | return Poll::Ready(Ok(())); |
| 1061 | } | 1065 | } |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index c27d09ea7..abb80ed26 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -125,26 +125,69 @@ impl Config { | |||
| 125 | ) | 125 | ) |
| 126 | } | 126 | } |
| 127 | } | 127 | } |
| 128 | |||
| 129 | /// SPI communication mode | ||
| 130 | pub mod mode { | ||
| 131 | use stm32_metapac::spi::vals; | ||
| 132 | |||
| 133 | trait SealedMode {} | ||
| 134 | |||
| 135 | /// Trait for SPI communication mode operations. | ||
| 136 | #[allow(private_bounds)] | ||
| 137 | pub trait CommunicationMode: SealedMode { | ||
| 138 | /// Spi communication mode | ||
| 139 | #[cfg(not(any(spi_v4, spi_v5, spi_v6)))] | ||
| 140 | const MASTER: vals::Mstr; | ||
| 141 | /// Spi communication mode | ||
| 142 | #[cfg(any(spi_v4, spi_v5, spi_v6))] | ||
| 143 | const MASTER: vals::Master; | ||
| 144 | } | ||
| 145 | |||
| 146 | /// Mode allowing for SPI master operations. | ||
| 147 | pub struct Master; | ||
| 148 | /// Mode allowing for SPI slave operations. | ||
| 149 | pub struct Slave; | ||
| 150 | |||
| 151 | impl SealedMode for Master {} | ||
| 152 | impl CommunicationMode for Master { | ||
| 153 | #[cfg(not(any(spi_v4, spi_v5, spi_v6)))] | ||
| 154 | const MASTER: vals::Mstr = vals::Mstr::MASTER; | ||
| 155 | #[cfg(any(spi_v4, spi_v5, spi_v6))] | ||
| 156 | const MASTER: vals::Master = vals::Master::MASTER; | ||
| 157 | } | ||
| 158 | |||
| 159 | impl SealedMode for Slave {} | ||
| 160 | impl CommunicationMode for Slave { | ||
| 161 | #[cfg(not(any(spi_v4, spi_v5, spi_v6)))] | ||
| 162 | const MASTER: vals::Mstr = vals::Mstr::SLAVE; | ||
| 163 | #[cfg(any(spi_v4, spi_v5, spi_v6))] | ||
| 164 | const MASTER: vals::Master = vals::Master::SLAVE; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | use mode::{CommunicationMode, Master, Slave}; | ||
| 168 | |||
| 128 | /// SPI driver. | 169 | /// SPI driver. |
| 129 | pub struct Spi<'d, M: PeriMode> { | 170 | pub struct Spi<'d, M: PeriMode, CM: CommunicationMode> { |
| 130 | pub(crate) info: &'static Info, | 171 | pub(crate) info: &'static Info, |
| 131 | kernel_clock: Hertz, | 172 | kernel_clock: Hertz, |
| 132 | sck: Option<Peri<'d, AnyPin>>, | 173 | sck: Option<Peri<'d, AnyPin>>, |
| 133 | mosi: Option<Peri<'d, AnyPin>>, | 174 | mosi: Option<Peri<'d, AnyPin>>, |
| 134 | miso: Option<Peri<'d, AnyPin>>, | 175 | miso: Option<Peri<'d, AnyPin>>, |
| 176 | nss: Option<Peri<'d, AnyPin>>, | ||
| 135 | tx_dma: Option<ChannelAndRequest<'d>>, | 177 | tx_dma: Option<ChannelAndRequest<'d>>, |
| 136 | rx_dma: Option<ChannelAndRequest<'d>>, | 178 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 137 | _phantom: PhantomData<M>, | 179 | _phantom: PhantomData<(M, CM)>, |
| 138 | current_word_size: word_impl::Config, | 180 | current_word_size: word_impl::Config, |
| 139 | gpio_speed: Speed, | 181 | gpio_speed: Speed, |
| 140 | } | 182 | } |
| 141 | 183 | ||
| 142 | impl<'d, M: PeriMode> Spi<'d, M> { | 184 | impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> { |
| 143 | fn new_inner<T: Instance>( | 185 | fn new_inner<T: Instance>( |
| 144 | _peri: Peri<'d, T>, | 186 | _peri: Peri<'d, T>, |
| 145 | sck: Option<Peri<'d, AnyPin>>, | 187 | sck: Option<Peri<'d, AnyPin>>, |
| 146 | mosi: Option<Peri<'d, AnyPin>>, | 188 | mosi: Option<Peri<'d, AnyPin>>, |
| 147 | miso: Option<Peri<'d, AnyPin>>, | 189 | miso: Option<Peri<'d, AnyPin>>, |
| 190 | nss: Option<Peri<'d, AnyPin>>, | ||
| 148 | tx_dma: Option<ChannelAndRequest<'d>>, | 191 | tx_dma: Option<ChannelAndRequest<'d>>, |
| 149 | rx_dma: Option<ChannelAndRequest<'d>>, | 192 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 150 | config: Config, | 193 | config: Config, |
| @@ -155,6 +198,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 155 | sck, | 198 | sck, |
| 156 | mosi, | 199 | mosi, |
| 157 | miso, | 200 | miso, |
| 201 | nss, | ||
| 158 | tx_dma, | 202 | tx_dma, |
| 159 | rx_dma, | 203 | rx_dma, |
| 160 | current_word_size: <u8 as SealedWord>::CONFIG, | 204 | current_word_size: <u8 as SealedWord>::CONFIG, |
| @@ -183,12 +227,12 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 183 | w.set_cpha(cpha); | 227 | w.set_cpha(cpha); |
| 184 | w.set_cpol(cpol); | 228 | w.set_cpol(cpol); |
| 185 | 229 | ||
| 186 | w.set_mstr(vals::Mstr::MASTER); | 230 | w.set_mstr(CM::MASTER); |
| 187 | w.set_br(br); | 231 | w.set_br(br); |
| 188 | w.set_spe(true); | 232 | w.set_spe(true); |
| 189 | w.set_lsbfirst(lsbfirst); | 233 | w.set_lsbfirst(lsbfirst); |
| 190 | w.set_ssi(true); | 234 | w.set_ssi(CM::MASTER == vals::Mstr::MASTER); |
| 191 | w.set_ssm(true); | 235 | w.set_ssm(CM::MASTER == vals::Mstr::MASTER); |
| 192 | w.set_crcen(false); | 236 | w.set_crcen(false); |
| 193 | w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); | 237 | w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); |
| 194 | // we're doing "fake rxonly", by actually writing one | 238 | // we're doing "fake rxonly", by actually writing one |
| @@ -210,11 +254,11 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 210 | w.set_cpha(cpha); | 254 | w.set_cpha(cpha); |
| 211 | w.set_cpol(cpol); | 255 | w.set_cpol(cpol); |
| 212 | 256 | ||
| 213 | w.set_mstr(vals::Mstr::MASTER); | 257 | w.set_mstr(CM::MASTER); |
| 214 | w.set_br(br); | 258 | w.set_br(br); |
| 215 | w.set_lsbfirst(lsbfirst); | 259 | w.set_lsbfirst(lsbfirst); |
| 216 | w.set_ssi(true); | 260 | w.set_ssi(CM::MASTER == vals::Mstr::MASTER); |
| 217 | w.set_ssm(true); | 261 | w.set_ssm(CM::MASTER == vals::Mstr::MASTER); |
| 218 | w.set_crcen(false); | 262 | w.set_crcen(false); |
| 219 | w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); | 263 | w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL); |
| 220 | w.set_spe(true); | 264 | w.set_spe(true); |
| @@ -229,8 +273,8 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 229 | w.set_cpha(cpha); | 273 | w.set_cpha(cpha); |
| 230 | w.set_cpol(cpol); | 274 | w.set_cpol(cpol); |
| 231 | w.set_lsbfirst(lsbfirst); | 275 | w.set_lsbfirst(lsbfirst); |
| 232 | w.set_ssm(true); | 276 | w.set_ssm(CM::MASTER == vals::Master::MASTER); |
| 233 | w.set_master(vals::Master::MASTER); | 277 | w.set_master(CM::MASTER); |
| 234 | w.set_comm(vals::Comm::FULL_DUPLEX); | 278 | w.set_comm(vals::Comm::FULL_DUPLEX); |
| 235 | w.set_ssom(vals::Ssom::ASSERTED); | 279 | w.set_ssom(vals::Ssom::ASSERTED); |
| 236 | w.set_midi(0); | 280 | w.set_midi(0); |
| @@ -469,7 +513,30 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 469 | } | 513 | } |
| 470 | } | 514 | } |
| 471 | 515 | ||
| 472 | impl<'d> Spi<'d, Blocking> { | 516 | impl<'d> Spi<'d, Blocking, Slave> { |
| 517 | /// Create a new blocking SPI slave driver. | ||
| 518 | pub fn new_blocking_slave<T: Instance, #[cfg(afio)] A>( | ||
| 519 | peri: Peri<'d, T>, | ||
| 520 | sck: Peri<'d, if_afio!(impl SckPin<T, A>)>, | ||
| 521 | mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>, | ||
| 522 | miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>, | ||
| 523 | cs: Peri<'d, if_afio!(impl CsPin<T, A>)>, | ||
| 524 | config: Config, | ||
| 525 | ) -> Self { | ||
| 526 | Self::new_inner( | ||
| 527 | peri, | ||
| 528 | new_pin!(sck, config.sck_af()), | ||
| 529 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), | ||
| 530 | new_pin!(miso, AfType::input(config.miso_pull)), | ||
| 531 | new_pin!(cs, AfType::input(Pull::None)), | ||
| 532 | None, | ||
| 533 | None, | ||
| 534 | config, | ||
| 535 | ) | ||
| 536 | } | ||
| 537 | } | ||
| 538 | |||
| 539 | impl<'d> Spi<'d, Blocking, Master> { | ||
| 473 | /// Create a new blocking SPI driver. | 540 | /// Create a new blocking SPI driver. |
| 474 | pub fn new_blocking<T: Instance, #[cfg(afio)] A>( | 541 | pub fn new_blocking<T: Instance, #[cfg(afio)] A>( |
| 475 | peri: Peri<'d, T>, | 542 | peri: Peri<'d, T>, |
| @@ -485,6 +552,7 @@ impl<'d> Spi<'d, Blocking> { | |||
| 485 | new_pin!(miso, AfType::input(config.miso_pull)), | 552 | new_pin!(miso, AfType::input(config.miso_pull)), |
| 486 | None, | 553 | None, |
| 487 | None, | 554 | None, |
| 555 | None, | ||
| 488 | config, | 556 | config, |
| 489 | ) | 557 | ) |
| 490 | } | 558 | } |
| @@ -503,6 +571,7 @@ impl<'d> Spi<'d, Blocking> { | |||
| 503 | new_pin!(miso, AfType::input(config.miso_pull)), | 571 | new_pin!(miso, AfType::input(config.miso_pull)), |
| 504 | None, | 572 | None, |
| 505 | None, | 573 | None, |
| 574 | None, | ||
| 506 | config, | 575 | config, |
| 507 | ) | 576 | ) |
| 508 | } | 577 | } |
| @@ -521,6 +590,7 @@ impl<'d> Spi<'d, Blocking> { | |||
| 521 | None, | 590 | None, |
| 522 | None, | 591 | None, |
| 523 | None, | 592 | None, |
| 593 | None, | ||
| 524 | config, | 594 | config, |
| 525 | ) | 595 | ) |
| 526 | } | 596 | } |
| @@ -540,12 +610,38 @@ impl<'d> Spi<'d, Blocking> { | |||
| 540 | None, | 610 | None, |
| 541 | None, | 611 | None, |
| 542 | None, | 612 | None, |
| 613 | None, | ||
| 614 | config, | ||
| 615 | ) | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | impl<'d> Spi<'d, Async, Slave> { | ||
| 620 | /// Create a new SPI slave driver. | ||
| 621 | pub fn new_slave<T: Instance, #[cfg(afio)] A>( | ||
| 622 | peri: Peri<'d, T>, | ||
| 623 | sck: Peri<'d, if_afio!(impl SckPin<T, A>)>, | ||
| 624 | mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>, | ||
| 625 | miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>, | ||
| 626 | cs: Peri<'d, if_afio!(impl CsPin<T, A>)>, | ||
| 627 | tx_dma: Peri<'d, impl TxDma<T>>, | ||
| 628 | rx_dma: Peri<'d, impl RxDma<T>>, | ||
| 629 | config: Config, | ||
| 630 | ) -> Self { | ||
| 631 | Self::new_inner( | ||
| 632 | peri, | ||
| 633 | new_pin!(sck, config.sck_af()), | ||
| 634 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), | ||
| 635 | new_pin!(miso, AfType::input(config.miso_pull)), | ||
| 636 | new_pin!(cs, AfType::input(Pull::None)), | ||
| 637 | new_dma!(tx_dma), | ||
| 638 | new_dma!(rx_dma), | ||
| 543 | config, | 639 | config, |
| 544 | ) | 640 | ) |
| 545 | } | 641 | } |
| 546 | } | 642 | } |
| 547 | 643 | ||
| 548 | impl<'d> Spi<'d, Async> { | 644 | impl<'d> Spi<'d, Async, Master> { |
| 549 | /// Create a new SPI driver. | 645 | /// Create a new SPI driver. |
| 550 | pub fn new<T: Instance, #[cfg(afio)] A>( | 646 | pub fn new<T: Instance, #[cfg(afio)] A>( |
| 551 | peri: Peri<'d, T>, | 647 | peri: Peri<'d, T>, |
| @@ -561,6 +657,7 @@ impl<'d> Spi<'d, Async> { | |||
| 561 | new_pin!(sck, config.sck_af()), | 657 | new_pin!(sck, config.sck_af()), |
| 562 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), | 658 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), |
| 563 | new_pin!(miso, AfType::input(config.miso_pull)), | 659 | new_pin!(miso, AfType::input(config.miso_pull)), |
| 660 | None, | ||
| 564 | new_dma!(tx_dma), | 661 | new_dma!(tx_dma), |
| 565 | new_dma!(rx_dma), | 662 | new_dma!(rx_dma), |
| 566 | config, | 663 | config, |
| @@ -581,6 +678,7 @@ impl<'d> Spi<'d, Async> { | |||
| 581 | new_pin!(sck, config.sck_af()), | 678 | new_pin!(sck, config.sck_af()), |
| 582 | None, | 679 | None, |
| 583 | new_pin!(miso, AfType::input(config.miso_pull)), | 680 | new_pin!(miso, AfType::input(config.miso_pull)), |
| 681 | None, | ||
| 584 | #[cfg(any(spi_v1, spi_v2, spi_v3))] | 682 | #[cfg(any(spi_v1, spi_v2, spi_v3))] |
| 585 | new_dma!(tx_dma), | 683 | new_dma!(tx_dma), |
| 586 | #[cfg(any(spi_v4, spi_v5, spi_v6))] | 684 | #[cfg(any(spi_v4, spi_v5, spi_v6))] |
| @@ -603,6 +701,7 @@ impl<'d> Spi<'d, Async> { | |||
| 603 | new_pin!(sck, config.sck_af()), | 701 | new_pin!(sck, config.sck_af()), |
| 604 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), | 702 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), |
| 605 | None, | 703 | None, |
| 704 | None, | ||
| 606 | new_dma!(tx_dma), | 705 | new_dma!(tx_dma), |
| 607 | None, | 706 | None, |
| 608 | config, | 707 | config, |
| @@ -623,6 +722,7 @@ impl<'d> Spi<'d, Async> { | |||
| 623 | None, | 722 | None, |
| 624 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), | 723 | new_pin!(mosi, AfType::output(OutputType::PushPull, config.gpio_speed)), |
| 625 | None, | 724 | None, |
| 725 | None, | ||
| 626 | new_dma!(tx_dma), | 726 | new_dma!(tx_dma), |
| 627 | None, | 727 | None, |
| 628 | config, | 728 | config, |
| @@ -646,7 +746,7 @@ impl<'d> Spi<'d, Async> { | |||
| 646 | config.bit_order = BitOrder::MsbFirst; | 746 | config.bit_order = BitOrder::MsbFirst; |
| 647 | config.frequency = freq; | 747 | config.frequency = freq; |
| 648 | 748 | ||
| 649 | Self::new_inner(peri, None, None, None, new_dma!(tx_dma), new_dma!(rx_dma), config) | 749 | Self::new_inner(peri, None, None, None, None, new_dma!(tx_dma), new_dma!(rx_dma), config) |
| 650 | } | 750 | } |
| 651 | 751 | ||
| 652 | #[allow(dead_code)] | 752 | #[allow(dead_code)] |
| @@ -656,9 +756,11 @@ impl<'d> Spi<'d, Async> { | |||
| 656 | rx_dma: Option<ChannelAndRequest<'d>>, | 756 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 657 | config: Config, | 757 | config: Config, |
| 658 | ) -> Self { | 758 | ) -> Self { |
| 659 | Self::new_inner(peri, None, None, None, tx_dma, rx_dma, config) | 759 | Self::new_inner(peri, None, None, None, None, tx_dma, rx_dma, config) |
| 660 | } | 760 | } |
| 761 | } | ||
| 661 | 762 | ||
| 763 | impl<'d, CM: CommunicationMode> Spi<'d, Async, CM> { | ||
| 662 | /// SPI write, using DMA. | 764 | /// SPI write, using DMA. |
| 663 | pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error> { | 765 | pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error> { |
| 664 | if data.is_empty() { | 766 | if data.is_empty() { |
| @@ -888,11 +990,12 @@ impl<'d> Spi<'d, Async> { | |||
| 888 | } | 990 | } |
| 889 | } | 991 | } |
| 890 | 992 | ||
| 891 | impl<'d, M: PeriMode> Drop for Spi<'d, M> { | 993 | impl<'d, M: PeriMode, CM: CommunicationMode> Drop for Spi<'d, M, CM> { |
| 892 | fn drop(&mut self) { | 994 | fn drop(&mut self) { |
| 893 | self.sck.as_ref().map(|x| x.set_as_disconnected()); | 995 | self.sck.as_ref().map(|x| x.set_as_disconnected()); |
| 894 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); | 996 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); |
| 895 | self.miso.as_ref().map(|x| x.set_as_disconnected()); | 997 | self.miso.as_ref().map(|x| x.set_as_disconnected()); |
| 998 | self.nss.as_ref().map(|x| x.set_as_disconnected()); | ||
| 896 | 999 | ||
| 897 | self.info.rcc.disable(); | 1000 | self.info.rcc.disable(); |
| 898 | } | 1001 | } |
| @@ -1127,7 +1230,7 @@ fn write_word<W: Word>(regs: Regs, tx_word: W) -> Result<(), Error> { | |||
| 1127 | // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 | 1230 | // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 |
| 1128 | macro_rules! impl_blocking { | 1231 | macro_rules! impl_blocking { |
| 1129 | ($w:ident) => { | 1232 | ($w:ident) => { |
| 1130 | impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, M> { | 1233 | impl<'d, M: PeriMode, CM: CommunicationMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, M, CM> { |
| 1131 | type Error = Error; | 1234 | type Error = Error; |
| 1132 | 1235 | ||
| 1133 | fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { | 1236 | fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { |
| @@ -1135,7 +1238,7 @@ macro_rules! impl_blocking { | |||
| 1135 | } | 1238 | } |
| 1136 | } | 1239 | } |
| 1137 | 1240 | ||
| 1138 | impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, M> { | 1241 | impl<'d, M: PeriMode, CM: CommunicationMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, M, CM> { |
| 1139 | type Error = Error; | 1242 | type Error = Error; |
| 1140 | 1243 | ||
| 1141 | fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { | 1244 | fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { |
| @@ -1149,11 +1252,11 @@ macro_rules! impl_blocking { | |||
| 1149 | impl_blocking!(u8); | 1252 | impl_blocking!(u8); |
| 1150 | impl_blocking!(u16); | 1253 | impl_blocking!(u16); |
| 1151 | 1254 | ||
| 1152 | impl<'d, M: PeriMode> embedded_hal_1::spi::ErrorType for Spi<'d, M> { | 1255 | impl<'d, M: PeriMode, CM: CommunicationMode> embedded_hal_1::spi::ErrorType for Spi<'d, M, CM> { |
| 1153 | type Error = Error; | 1256 | type Error = Error; |
| 1154 | } | 1257 | } |
| 1155 | 1258 | ||
| 1156 | impl<'d, W: Word, M: PeriMode> embedded_hal_1::spi::SpiBus<W> for Spi<'d, M> { | 1259 | impl<'d, W: Word, M: PeriMode, CM: CommunicationMode> embedded_hal_1::spi::SpiBus<W> for Spi<'d, M, CM> { |
| 1157 | fn flush(&mut self) -> Result<(), Self::Error> { | 1260 | fn flush(&mut self) -> Result<(), Self::Error> { |
| 1158 | Ok(()) | 1261 | Ok(()) |
| 1159 | } | 1262 | } |
| @@ -1186,7 +1289,7 @@ impl embedded_hal_1::spi::Error for Error { | |||
| 1186 | } | 1289 | } |
| 1187 | } | 1290 | } |
| 1188 | 1291 | ||
| 1189 | impl<'d, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, Async> { | 1292 | impl<'d, W: Word, CM: CommunicationMode> embedded_hal_async::spi::SpiBus<W> for Spi<'d, Async, CM> { |
| 1190 | async fn flush(&mut self) -> Result<(), Self::Error> { | 1293 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 1191 | Ok(()) | 1294 | Ok(()) |
| 1192 | } | 1295 | } |
| @@ -1328,7 +1431,7 @@ foreach_peripheral!( | |||
| 1328 | }; | 1431 | }; |
| 1329 | ); | 1432 | ); |
| 1330 | 1433 | ||
| 1331 | impl<'d, M: PeriMode> SetConfig for Spi<'d, M> { | 1434 | impl<'d, M: PeriMode, CM: CommunicationMode> SetConfig for Spi<'d, M, CM> { |
| 1332 | type Config = Config; | 1435 | type Config = Config; |
| 1333 | type ConfigError = (); | 1436 | type ConfigError = (); |
| 1334 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { | 1437 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { |
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 74b10a183..7db51d72e 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #![allow(non_snake_case)] | 1 | #![allow(non_snake_case)] |
| 2 | 2 | ||
| 3 | use core::cell::{Cell, RefCell}; | 3 | use core::cell::{Cell, RefCell}; |
| 4 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 5 | use core::sync::atomic::AtomicU16; | ||
| 4 | use core::sync::atomic::{AtomicU32, Ordering, compiler_fence}; | 6 | use core::sync::atomic::{AtomicU32, Ordering, compiler_fence}; |
| 5 | 7 | ||
| 6 | use critical_section::CriticalSection; | 8 | use critical_section::CriticalSection; |
| @@ -213,7 +215,13 @@ pub(crate) struct RtcDriver { | |||
| 213 | period: AtomicU32, | 215 | period: AtomicU32, |
| 214 | alarm: Mutex<CriticalSectionRawMutex, AlarmState>, | 216 | alarm: Mutex<CriticalSectionRawMutex, AlarmState>, |
| 215 | #[cfg(feature = "low-power")] | 217 | #[cfg(feature = "low-power")] |
| 216 | rtc: Mutex<CriticalSectionRawMutex, Cell<Option<&'static Rtc>>>, | 218 | pub(crate) rtc: Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc>>>, |
| 219 | #[cfg(feature = "low-power")] | ||
| 220 | /// The minimum pause time beyond which the executor will enter a low-power state. | ||
| 221 | min_stop_pause: Mutex<CriticalSectionRawMutex, Cell<embassy_time::Duration>>, | ||
| 222 | /// Saved count for the timer (its value is lost when entering STOP2) | ||
| 223 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 224 | saved_count: AtomicU16, | ||
| 217 | queue: Mutex<CriticalSectionRawMutex, RefCell<Queue>>, | 225 | queue: Mutex<CriticalSectionRawMutex, RefCell<Queue>>, |
| 218 | } | 226 | } |
| 219 | 227 | ||
| @@ -221,12 +229,18 @@ embassy_time_driver::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver { | |||
| 221 | period: AtomicU32::new(0), | 229 | period: AtomicU32::new(0), |
| 222 | alarm: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), | 230 | alarm: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), |
| 223 | #[cfg(feature = "low-power")] | 231 | #[cfg(feature = "low-power")] |
| 224 | rtc: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), | 232 | rtc: Mutex::const_new(CriticalSectionRawMutex::new(), RefCell::new(None)), |
| 233 | #[cfg(feature = "low-power")] | ||
| 234 | min_stop_pause: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(embassy_time::Duration::from_millis(0))), | ||
| 235 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 236 | saved_count: AtomicU16::new(0), | ||
| 225 | queue: Mutex::new(RefCell::new(Queue::new())) | 237 | queue: Mutex::new(RefCell::new(Queue::new())) |
| 226 | }); | 238 | }); |
| 227 | 239 | ||
| 228 | impl RtcDriver { | 240 | impl RtcDriver { |
| 229 | fn init(&'static self, cs: critical_section::CriticalSection) { | 241 | /// initialize the timer, but don't start it. Used for chips like stm32wle5 |
| 242 | /// for low power where the timer config is lost in STOP2. | ||
| 243 | fn init_timer(&'static self, cs: critical_section::CriticalSection) { | ||
| 230 | let r = regs_gp16(); | 244 | let r = regs_gp16(); |
| 231 | 245 | ||
| 232 | rcc::enable_and_reset_with_cs::<T>(cs); | 246 | rcc::enable_and_reset_with_cs::<T>(cs); |
| @@ -259,10 +273,16 @@ impl RtcDriver { | |||
| 259 | w.set_ccie(0, true); | 273 | w.set_ccie(0, true); |
| 260 | }); | 274 | }); |
| 261 | 275 | ||
| 276 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 277 | r.cnt().write(|w| w.set_cnt(self.saved_count.load(Ordering::SeqCst))); | ||
| 278 | |||
| 262 | <T as GeneralInstance1Channel>::CaptureCompareInterrupt::unpend(); | 279 | <T as GeneralInstance1Channel>::CaptureCompareInterrupt::unpend(); |
| 263 | unsafe { <T as GeneralInstance1Channel>::CaptureCompareInterrupt::enable() }; | 280 | unsafe { <T as GeneralInstance1Channel>::CaptureCompareInterrupt::enable() }; |
| 281 | } | ||
| 264 | 282 | ||
| 265 | r.cr1().modify(|w| w.set_cen(true)); | 283 | fn init(&'static self, cs: CriticalSection) { |
| 284 | self.init_timer(cs); | ||
| 285 | regs_gp16().cr1().modify(|w| w.set_cen(true)); | ||
| 266 | } | 286 | } |
| 267 | 287 | ||
| 268 | fn on_interrupt(&self) { | 288 | fn on_interrupt(&self) { |
| @@ -379,27 +399,26 @@ impl RtcDriver { | |||
| 379 | #[cfg(feature = "low-power")] | 399 | #[cfg(feature = "low-power")] |
| 380 | /// Stop the wakeup alarm, if enabled, and add the appropriate offset | 400 | /// Stop the wakeup alarm, if enabled, and add the appropriate offset |
| 381 | fn stop_wakeup_alarm(&self, cs: CriticalSection) { | 401 | fn stop_wakeup_alarm(&self, cs: CriticalSection) { |
| 382 | if let Some(offset) = self.rtc.borrow(cs).get().unwrap().stop_wakeup_alarm(cs) { | 402 | if let Some(offset) = self.rtc.borrow(cs).borrow_mut().as_mut().unwrap().stop_wakeup_alarm(cs) { |
| 383 | self.add_time(offset, cs); | 403 | self.add_time(offset, cs); |
| 384 | } | 404 | } |
| 385 | } | 405 | } |
| 386 | 406 | ||
| 387 | /* | 407 | /* |
| 388 | Low-power public functions: all create a critical section | 408 | Low-power public functions: all create or require a critical section |
| 389 | */ | 409 | */ |
| 390 | #[cfg(feature = "low-power")] | 410 | #[cfg(feature = "low-power")] |
| 391 | /// Set the rtc but panic if it's already been set | 411 | pub(crate) fn set_min_stop_pause(&self, cs: CriticalSection, min_stop_pause: embassy_time::Duration) { |
| 392 | pub(crate) fn set_rtc(&self, rtc: &'static Rtc) { | 412 | self.min_stop_pause.borrow(cs).replace(min_stop_pause); |
| 393 | critical_section::with(|cs| { | ||
| 394 | rtc.stop_wakeup_alarm(cs); | ||
| 395 | |||
| 396 | assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()) | ||
| 397 | }); | ||
| 398 | } | 413 | } |
| 399 | 414 | ||
| 400 | #[cfg(feature = "low-power")] | 415 | #[cfg(feature = "low-power")] |
| 401 | /// The minimum pause time beyond which the executor will enter a low-power state. | 416 | /// Set the rtc but panic if it's already been set |
| 402 | pub(crate) const MIN_STOP_PAUSE: embassy_time::Duration = embassy_time::Duration::from_millis(250); | 417 | pub(crate) fn set_rtc(&self, cs: CriticalSection, mut rtc: Rtc) { |
| 418 | rtc.stop_wakeup_alarm(cs); | ||
| 419 | |||
| 420 | assert!(self.rtc.borrow(cs).replace(Some(rtc)).is_none()); | ||
| 421 | } | ||
| 403 | 422 | ||
| 404 | #[cfg(feature = "low-power")] | 423 | #[cfg(feature = "low-power")] |
| 405 | /// Pause the timer if ready; return err if not | 424 | /// Pause the timer if ready; return err if not |
| @@ -413,17 +432,25 @@ impl RtcDriver { | |||
| 413 | self.stop_wakeup_alarm(cs); | 432 | self.stop_wakeup_alarm(cs); |
| 414 | 433 | ||
| 415 | let time_until_next_alarm = self.time_until_next_alarm(cs); | 434 | let time_until_next_alarm = self.time_until_next_alarm(cs); |
| 416 | if time_until_next_alarm < Self::MIN_STOP_PAUSE { | 435 | if time_until_next_alarm < self.min_stop_pause.borrow(cs).get() { |
| 436 | trace!( | ||
| 437 | "time_until_next_alarm < self.min_stop_pause ({})", | ||
| 438 | time_until_next_alarm | ||
| 439 | ); | ||
| 417 | Err(()) | 440 | Err(()) |
| 418 | } else { | 441 | } else { |
| 419 | self.rtc | 442 | self.rtc |
| 420 | .borrow(cs) | 443 | .borrow(cs) |
| 421 | .get() | 444 | .borrow_mut() |
| 445 | .as_mut() | ||
| 422 | .unwrap() | 446 | .unwrap() |
| 423 | .start_wakeup_alarm(time_until_next_alarm, cs); | 447 | .start_wakeup_alarm(time_until_next_alarm, cs); |
| 424 | 448 | ||
| 425 | regs_gp16().cr1().modify(|w| w.set_cen(false)); | 449 | regs_gp16().cr1().modify(|w| w.set_cen(false)); |
| 426 | 450 | // save the count for the timer as its lost in STOP2 for stm32wlex | |
| 451 | #[cfg(stm32wlex)] | ||
| 452 | self.saved_count | ||
| 453 | .store(regs_gp16().cnt().read().cnt() as u16, Ordering::SeqCst); | ||
| 427 | Ok(()) | 454 | Ok(()) |
| 428 | } | 455 | } |
| 429 | }) | 456 | }) |
| @@ -431,18 +458,16 @@ impl RtcDriver { | |||
| 431 | 458 | ||
| 432 | #[cfg(feature = "low-power")] | 459 | #[cfg(feature = "low-power")] |
| 433 | /// Resume the timer with the given offset | 460 | /// Resume the timer with the given offset |
| 434 | pub(crate) fn resume_time(&self) { | 461 | pub(crate) fn resume_time(&self, cs: CriticalSection) { |
| 435 | if regs_gp16().cr1().read().cen() { | 462 | if regs_gp16().cr1().read().cen() { |
| 436 | // Time isn't currently stopped | 463 | // Time isn't currently stopped |
| 437 | 464 | ||
| 438 | return; | 465 | return; |
| 439 | } | 466 | } |
| 440 | 467 | ||
| 441 | critical_section::with(|cs| { | 468 | self.stop_wakeup_alarm(cs); |
| 442 | self.stop_wakeup_alarm(cs); | ||
| 443 | 469 | ||
| 444 | regs_gp16().cr1().modify(|w| w.set_cen(true)); | 470 | regs_gp16().cr1().modify(|w| w.set_cen(true)); |
| 445 | }) | ||
| 446 | } | 471 | } |
| 447 | 472 | ||
| 448 | fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { | 473 | fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { |
| @@ -514,10 +539,15 @@ impl Driver for RtcDriver { | |||
| 514 | } | 539 | } |
| 515 | 540 | ||
| 516 | #[cfg(feature = "low-power")] | 541 | #[cfg(feature = "low-power")] |
| 517 | pub(crate) fn get_driver() -> &'static RtcDriver { | 542 | pub(crate) const fn get_driver() -> &'static RtcDriver { |
| 518 | &DRIVER | 543 | &DRIVER |
| 519 | } | 544 | } |
| 520 | 545 | ||
| 521 | pub(crate) fn init(cs: CriticalSection) { | 546 | pub(crate) fn init(cs: CriticalSection) { |
| 522 | DRIVER.init(cs) | 547 | DRIVER.init(cs) |
| 523 | } | 548 | } |
| 549 | |||
| 550 | #[cfg(all(feature = "low-power", stm32wlex))] | ||
| 551 | pub(crate) fn init_timer(cs: CriticalSection) { | ||
| 552 | DRIVER.init_timer(cs) | ||
| 553 | } | ||
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 75a83629c..9a56a41fb 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | 4 | ||
| 5 | pub use stm32_metapac::timer::vals::{Ckd, Ossi, Ossr}; | 5 | pub use stm32_metapac::timer::vals::{Ckd, Mms2, Ossi, Ossr}; |
| 6 | 6 | ||
| 7 | use super::low_level::{CountingMode, OutputPolarity, Timer}; | 7 | use super::low_level::{CountingMode, OutputPolarity, Timer}; |
| 8 | use super::simple_pwm::PwmPin; | 8 | use super::simple_pwm::PwmPin; |
| @@ -136,6 +136,16 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | |||
| 136 | self.inner.get_moe() | 136 | self.inner.get_moe() |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | /// Set Master Slave Mode 2 | ||
| 140 | pub fn set_mms2(&mut self, mms2: Mms2) { | ||
| 141 | self.inner.set_mms2_selection(mms2); | ||
| 142 | } | ||
| 143 | |||
| 144 | /// Set Repetition Counter | ||
| 145 | pub fn set_repetition_counter(&mut self, val: u16) { | ||
| 146 | self.inner.set_repetition_counter(val); | ||
| 147 | } | ||
| 148 | |||
| 139 | /// Enable the given channel. | 149 | /// Enable the given channel. |
| 140 | pub fn enable(&mut self, channel: Channel) { | 150 | pub fn enable(&mut self, channel: Channel) { |
| 141 | self.inner.enable_channel(channel, true); | 151 | self.inner.enable_channel(channel, true); |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index ac039bb0d..0122fe4f7 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -10,7 +10,7 @@ use core::mem::ManuallyDrop; | |||
| 10 | 10 | ||
| 11 | use embassy_hal_internal::Peri; | 11 | use embassy_hal_internal::Peri; |
| 12 | // Re-export useful enums | 12 | // Re-export useful enums |
| 13 | pub use stm32_metapac::timer::vals::{FilterValue, Sms as SlaveMode, Ts as TriggerSource}; | 13 | pub use stm32_metapac::timer::vals::{FilterValue, Mms as MasterMode, Sms as SlaveMode, Ts as TriggerSource}; |
| 14 | 14 | ||
| 15 | use super::*; | 15 | use super::*; |
| 16 | use crate::pac::timer::vals; | 16 | use crate::pac::timer::vals; |
| @@ -143,20 +143,69 @@ pub enum OutputCompareMode { | |||
| 143 | /// TIMx_CNT<TIMx_CCRx else active. In downcounting, channel is active as long as | 143 | /// TIMx_CNT<TIMx_CCRx else active. In downcounting, channel is active as long as |
| 144 | /// TIMx_CNT>TIMx_CCRx else inactive. | 144 | /// TIMx_CNT>TIMx_CCRx else inactive. |
| 145 | PwmMode2, | 145 | PwmMode2, |
| 146 | // TODO: there's more modes here depending on the chip family. | 146 | |
| 147 | #[cfg(timer_v2)] | ||
| 148 | /// In up-counting mode, the channel is active until a trigger | ||
| 149 | /// event is detected (on tim_trgi signal). Then, a comparison is performed as in PWM | ||
| 150 | /// mode 1 and the channels becomes active again at the next update. In down-counting | ||
| 151 | /// mode, the channel is inactive until a trigger event is detected (on tim_trgi signal). | ||
| 152 | /// Then, a comparison is performed as in PWM mode 1 and the channels becomes | ||
| 153 | /// inactive again at the next update. | ||
| 154 | OnePulseMode1, | ||
| 155 | |||
| 156 | #[cfg(timer_v2)] | ||
| 157 | /// In up-counting mode, the channel is inactive until a | ||
| 158 | /// trigger event is detected (on tim_trgi signal). Then, a comparison is performed as in | ||
| 159 | /// PWM mode 2 and the channels becomes inactive again at the next update. In down | ||
| 160 | /// counting mode, the channel is active until a trigger event is detected (on tim_trgi | ||
| 161 | /// signal). Then, a comparison is performed as in PWM mode 1 and the channels | ||
| 162 | /// becomes active again at the next update. | ||
| 163 | OnePulseMode2, | ||
| 164 | |||
| 165 | #[cfg(timer_v2)] | ||
| 166 | /// Combined PWM mode 1 - tim_oc1ref has the same behavior as in PWM mode 1. | ||
| 167 | /// tim_oc1refc is the logical OR between tim_oc1ref and tim_oc2ref. | ||
| 168 | CombinedPwmMode1, | ||
| 169 | |||
| 170 | #[cfg(timer_v2)] | ||
| 171 | /// Combined PWM mode 2 - tim_oc1ref has the same behavior as in PWM mode 2. | ||
| 172 | /// tim_oc1refc is the logical AND between tim_oc1ref and tim_oc2ref. | ||
| 173 | CombinedPwmMode2, | ||
| 174 | |||
| 175 | #[cfg(timer_v2)] | ||
| 176 | /// tim_oc1ref has the same behavior as in PWM mode 1. tim_oc1refc outputs tim_oc1ref | ||
| 177 | /// when the counter is counting up, tim_oc2ref when it is counting down. | ||
| 178 | AsymmetricPwmMode1, | ||
| 179 | |||
| 180 | #[cfg(timer_v2)] | ||
| 181 | /// tim_oc1ref has the same behavior as in PWM mode 2. tim_oc1refc outputs tim_oc1ref | ||
| 182 | /// when the counter is counting up, tim_oc2ref when it is counting down. | ||
| 183 | AsymmetricPwmMode2, | ||
| 147 | } | 184 | } |
| 148 | 185 | ||
| 149 | impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm { | 186 | impl From<OutputCompareMode> for crate::pac::timer::vals::Ocm { |
| 150 | fn from(mode: OutputCompareMode) -> Self { | 187 | fn from(mode: OutputCompareMode) -> Self { |
| 151 | match mode { | 188 | match mode { |
| 152 | OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN, | 189 | OutputCompareMode::Frozen => crate::pac::timer::vals::Ocm::FROZEN, |
| 153 | OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVE_ON_MATCH, | 190 | OutputCompareMode::ActiveOnMatch => crate::pac::timer::vals::Ocm::ACTIVE_ON_MATCH, |
| 154 | OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVE_ON_MATCH, | 191 | OutputCompareMode::InactiveOnMatch => crate::pac::timer::vals::Ocm::INACTIVE_ON_MATCH, |
| 155 | OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE, | 192 | OutputCompareMode::Toggle => crate::pac::timer::vals::Ocm::TOGGLE, |
| 156 | OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCE_INACTIVE, | 193 | OutputCompareMode::ForceInactive => crate::pac::timer::vals::Ocm::FORCE_INACTIVE, |
| 157 | OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCE_ACTIVE, | 194 | OutputCompareMode::ForceActive => crate::pac::timer::vals::Ocm::FORCE_ACTIVE, |
| 158 | OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWM_MODE1, | 195 | OutputCompareMode::PwmMode1 => crate::pac::timer::vals::Ocm::PWM_MODE1, |
| 159 | OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWM_MODE2, | 196 | OutputCompareMode::PwmMode2 => crate::pac::timer::vals::Ocm::PWM_MODE2, |
| 197 | #[cfg(timer_v2)] | ||
| 198 | OutputCompareMode::OnePulseMode1 => crate::pac::timer::vals::Ocm::RETRIGERRABLE_OPM_MODE_1, | ||
| 199 | #[cfg(timer_v2)] | ||
| 200 | OutputCompareMode::OnePulseMode2 => crate::pac::timer::vals::Ocm::RETRIGERRABLE_OPM_MODE_2, | ||
| 201 | #[cfg(timer_v2)] | ||
| 202 | OutputCompareMode::CombinedPwmMode1 => crate::pac::timer::vals::Ocm::COMBINED_PWM_MODE_1, | ||
| 203 | #[cfg(timer_v2)] | ||
| 204 | OutputCompareMode::CombinedPwmMode2 => crate::pac::timer::vals::Ocm::COMBINED_PWM_MODE_2, | ||
| 205 | #[cfg(timer_v2)] | ||
| 206 | OutputCompareMode::AsymmetricPwmMode1 => crate::pac::timer::vals::Ocm::ASYMMETRIC_PWM_MODE_1, | ||
| 207 | #[cfg(timer_v2)] | ||
| 208 | OutputCompareMode::AsymmetricPwmMode2 => crate::pac::timer::vals::Ocm::ASYMMETRIC_PWM_MODE_2, | ||
| 160 | } | 209 | } |
| 161 | } | 210 | } |
| 162 | } | 211 | } |
| @@ -640,6 +689,11 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 640 | self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) | 689 | self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) |
| 641 | } | 690 | } |
| 642 | 691 | ||
| 692 | /// Set Timer Master Mode | ||
| 693 | pub fn set_master_mode(&self, mms: MasterMode) { | ||
| 694 | self.regs_gp16().cr2().modify(|w| w.set_mms(mms)); | ||
| 695 | } | ||
| 696 | |||
| 643 | /// Set Timer Slave Mode | 697 | /// Set Timer Slave Mode |
| 644 | pub fn set_slave_mode(&self, sms: SlaveMode) { | 698 | pub fn set_slave_mode(&self, sms: SlaveMode) { |
| 645 | self.regs_gp16().smcr().modify(|r| r.set_sms(sms)); | 699 | self.regs_gp16().smcr().modify(|r| r.set_sms(sms)); |
| @@ -760,6 +814,16 @@ impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> { | |||
| 760 | self.regs_advanced().cr2().modify(|w| w.set_oisn(channel.index(), val)); | 814 | self.regs_advanced().cr2().modify(|w| w.set_oisn(channel.index(), val)); |
| 761 | } | 815 | } |
| 762 | 816 | ||
| 817 | /// Set master mode selection 2 | ||
| 818 | pub fn set_mms2_selection(&self, mms2: vals::Mms2) { | ||
| 819 | self.regs_advanced().cr2().modify(|w| w.set_mms2(mms2)); | ||
| 820 | } | ||
| 821 | |||
| 822 | /// Set repetition counter | ||
| 823 | pub fn set_repetition_counter(&self, val: u16) { | ||
| 824 | self.regs_advanced().rcr().modify(|w| w.set_rep(val)); | ||
| 825 | } | ||
| 826 | |||
| 763 | /// Trigger software break 1 or 2 | 827 | /// Trigger software break 1 or 2 |
| 764 | /// Setting this bit generates a break event. This bit is automatically cleared by the hardware. | 828 | /// Setting this bit generates a break event. This bit is automatically cleared by the hardware. |
| 765 | pub fn trigger_software_break(&self, n: usize) { | 829 | pub fn trigger_software_break(&self, n: usize) { |
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index b09bc7166..804d1ef37 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -399,7 +399,7 @@ pub struct UpdateInterruptHandler<T: CoreInstance> { | |||
| 399 | impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> { | 399 | impl<T: CoreInstance> interrupt::typelevel::Handler<T::UpdateInterrupt> for UpdateInterruptHandler<T> { |
| 400 | unsafe fn on_interrupt() { | 400 | unsafe fn on_interrupt() { |
| 401 | #[cfg(feature = "low-power")] | 401 | #[cfg(feature = "low-power")] |
| 402 | crate::low_power::on_wakeup_irq(); | 402 | crate::low_power::Executor::on_wakeup_irq(); |
| 403 | 403 | ||
| 404 | let regs = crate::pac::timer::TimCore::from_ptr(T::regs()); | 404 | let regs = crate::pac::timer::TimCore::from_ptr(T::regs()); |
| 405 | 405 | ||
| @@ -429,7 +429,7 @@ impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompare | |||
| 429 | { | 429 | { |
| 430 | unsafe fn on_interrupt() { | 430 | unsafe fn on_interrupt() { |
| 431 | #[cfg(feature = "low-power")] | 431 | #[cfg(feature = "low-power")] |
| 432 | crate::low_power::on_wakeup_irq(); | 432 | crate::low_power::Executor::on_wakeup_irq(); |
| 433 | 433 | ||
| 434 | let regs = crate::pac::timer::TimGp16::from_ptr(T::regs()); | 434 | let regs = crate::pac::timer::TimGp16::from_ptr(T::regs()); |
| 435 | 435 | ||
diff --git a/embassy-stm32/src/uid.rs b/embassy-stm32/src/uid.rs index 5e38532bd..2d3e2b972 100644 --- a/embassy-stm32/src/uid.rs +++ b/embassy-stm32/src/uid.rs | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | //! Unique ID (UID) | 1 | //! Unique ID (UID) |
| 2 | 2 | ||
| 3 | /// Get this device's unique 96-bit ID. | 3 | /// Get this device's unique 96-bit ID. |
| 4 | pub fn uid() -> &'static [u8; 12] { | 4 | pub fn uid() -> [u8; 12] { |
| 5 | unsafe { &*crate::pac::UID.uid(0).as_ptr().cast::<[u8; 12]>() } | 5 | unsafe { *crate::pac::UID.uid(0).as_ptr().cast::<[u8; 12]>() } |
| 6 | } | 6 | } |
| 7 | 7 | ||
| 8 | /// Get this device's unique 96-bit ID, encoded into a string of 24 hexadecimal ASCII digits. | 8 | /// Get this device's unique 96-bit ID, encoded into a string of 24 hexadecimal ASCII digits. |
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 20bfefd9e..bac570d27 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -7,7 +7,9 @@ use embassy_embedded_hal::SetConfig; | |||
| 7 | use embedded_io_async::ReadReady; | 7 | use embedded_io_async::ReadReady; |
| 8 | use futures_util::future::{Either, select}; | 8 | use futures_util::future::{Either, select}; |
| 9 | 9 | ||
| 10 | use super::{Config, ConfigError, Error, Info, State, UartRx, rdr, reconfigure, set_baudrate, sr}; | 10 | use super::{ |
| 11 | Config, ConfigError, Error, Info, State, UartRx, clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, | ||
| 12 | }; | ||
| 11 | use crate::Peri; | 13 | use crate::Peri; |
| 12 | use crate::dma::ReadableRingBuffer; | 14 | use crate::dma::ReadableRingBuffer; |
| 13 | use crate::gpio::{AnyPin, SealedPin as _}; | 15 | use crate::gpio::{AnyPin, SealedPin as _}; |
| @@ -338,26 +340,16 @@ impl Drop for RingBufferedUartRx<'_> { | |||
| 338 | /// For usart_v1 and usart_v2, all status flags must be handled together anyway because all flags | 340 | /// For usart_v1 and usart_v2, all status flags must be handled together anyway because all flags |
| 339 | /// are cleared by a single read to the RDR register. | 341 | /// are cleared by a single read to the RDR register. |
| 340 | fn check_idle_and_errors(r: Regs) -> Result<bool, Error> { | 342 | fn check_idle_and_errors(r: Regs) -> Result<bool, Error> { |
| 341 | // Critical section is required so that the flags aren't set after read and before clear | 343 | // SAFETY: read only and we only use Rx related flags |
| 342 | let sr = critical_section::with(|_| { | 344 | let sr = sr(r).read(); |
| 343 | // SAFETY: read only and we only use Rx related flags | 345 | |
| 344 | let sr = sr(r).read(); | 346 | #[cfg(not(any(usart_v3, usart_v4)))] |
| 345 | 347 | unsafe { | |
| 346 | #[cfg(any(usart_v3, usart_v4))] | 348 | // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) |
| 347 | r.icr().write(|w| { | 349 | rdr(r).read_volatile() |
| 348 | w.set_idle(true); | 350 | }; |
| 349 | w.set_pe(true); | 351 | clear_interrupt_flags(r, sr); |
| 350 | w.set_fe(true); | 352 | |
| 351 | w.set_ne(true); | ||
| 352 | w.set_ore(true); | ||
| 353 | }); | ||
| 354 | #[cfg(not(any(usart_v3, usart_v4)))] | ||
| 355 | unsafe { | ||
| 356 | // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) | ||
| 357 | rdr(r).read_volatile() | ||
| 358 | }; | ||
| 359 | sr | ||
| 360 | }); | ||
| 361 | if sr.pe() { | 353 | if sr.pe() { |
| 362 | Err(Error::Parity) | 354 | Err(Error::Parity) |
| 363 | } else if sr.fe() { | 355 | } else if sr.fe() { |
diff --git a/embassy-stm32/src/vrefbuf/mod.rs b/embassy-stm32/src/vrefbuf/mod.rs index b061306a0..43dd9c800 100644 --- a/embassy-stm32/src/vrefbuf/mod.rs +++ b/embassy-stm32/src/vrefbuf/mod.rs | |||
| @@ -14,10 +14,10 @@ pub struct VoltageReferenceBuffer<'d, T: Instance> { | |||
| 14 | #[cfg(rcc_wba)] | 14 | #[cfg(rcc_wba)] |
| 15 | fn get_refbuf_trim(voltage_scale: Vrs) -> usize { | 15 | fn get_refbuf_trim(voltage_scale: Vrs) -> usize { |
| 16 | match voltage_scale { | 16 | match voltage_scale { |
| 17 | Vrs::VREF0 => 0x0BFA_07A8usize, | 17 | Vrs::VREF0 => 0x0BFA_07ABusize, |
| 18 | Vrs::VREF1 => 0x0BFA_07A9usize, | 18 | Vrs::VREF1 => 0x0BFA_07AAusize, |
| 19 | Vrs::VREF2 => 0x0BFA_07AAusize, | 19 | Vrs::VREF2 => 0x0BFA_07A9usize, |
| 20 | Vrs::VREF3 => 0x0BFA_07ABusize, | 20 | Vrs::VREF3 => 0x0BFA_07A8usize, |
| 21 | _ => panic!("Incorrect Vrs setting!"), | 21 | _ => panic!("Incorrect Vrs setting!"), |
| 22 | } | 22 | } |
| 23 | } | 23 | } |
diff --git a/embassy-usb-logger/CHANGELOG.md b/embassy-usb-logger/CHANGELOG.md index 4ea0e8871..3ba140b1f 100644 --- a/embassy-usb-logger/CHANGELOG.md +++ b/embassy-usb-logger/CHANGELOG.md | |||
| @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - Fixed panic in `UsbLogger` when usb is disconnected | ||
| 12 | |||
| 11 | ## 0.5.1 - 2025-08-26 | 13 | ## 0.5.1 - 2025-08-26 |
| 12 | 14 | ||
| 13 | ## 0.5.0 - 2025-07-22 | 15 | ## 0.5.0 - 2025-07-22 |
diff --git a/embassy-usb-logger/src/lib.rs b/embassy-usb-logger/src/lib.rs index de25abce1..7c3c5e709 100644 --- a/embassy-usb-logger/src/lib.rs +++ b/embassy-usb-logger/src/lib.rs | |||
| @@ -8,7 +8,7 @@ use core::future::Future; | |||
| 8 | use embassy_futures::join::join; | 8 | use embassy_futures::join::join; |
| 9 | use embassy_sync::pipe::Pipe; | 9 | use embassy_sync::pipe::Pipe; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State}; |
| 11 | use embassy_usb::driver::Driver; | 11 | use embassy_usb::driver::{Driver, EndpointError}; |
| 12 | use embassy_usb::{Builder, Config}; | 12 | use embassy_usb::{Builder, Config}; |
| 13 | use log::{Metadata, Record}; | 13 | use log::{Metadata, Record}; |
| 14 | 14 | ||
| @@ -133,17 +133,25 @@ impl<const N: usize, T: ReceiverHandler + Send + Sync> UsbLogger<N, T> { | |||
| 133 | sender.wait_connection().await; | 133 | sender.wait_connection().await; |
| 134 | loop { | 134 | loop { |
| 135 | let len = self.buffer.read(&mut rx[..]).await; | 135 | let len = self.buffer.read(&mut rx[..]).await; |
| 136 | let _ = sender.write_packet(&rx[..len]).await; | 136 | if Err(EndpointError::Disabled) == sender.write_packet(&rx[..len]).await |
| 137 | if len as u8 == MAX_PACKET_SIZE { | 137 | || len as u8 == MAX_PACKET_SIZE && Err(EndpointError::Disabled) == sender.write_packet(&[]).await |
| 138 | let _ = sender.write_packet(&[]).await; | 138 | { |
| 139 | } | 139 | sender.wait_connection().await; |
| 140 | }; | ||
| 140 | } | 141 | } |
| 141 | }; | 142 | }; |
| 142 | let reciever_fut = async { | 143 | let reciever_fut = async { |
| 143 | let mut reciever_buf: [u8; MAX_PACKET_SIZE as usize] = [0; MAX_PACKET_SIZE as usize]; | 144 | let mut reciever_buf: [u8; MAX_PACKET_SIZE as usize] = [0; MAX_PACKET_SIZE as usize]; |
| 144 | receiver.wait_connection().await; | 145 | receiver.wait_connection().await; |
| 145 | loop { | 146 | loop { |
| 146 | let n = receiver.read_packet(&mut reciever_buf).await.unwrap(); | 147 | let n = match receiver.read_packet(&mut reciever_buf).await { |
| 148 | Err(EndpointError::Disabled) => { | ||
| 149 | receiver.wait_connection().await; | ||
| 150 | continue; | ||
| 151 | } | ||
| 152 | Err(_) => continue, | ||
| 153 | Ok(n) => n, | ||
| 154 | }; | ||
| 147 | match &self.recieve_handler { | 155 | match &self.recieve_handler { |
| 148 | Some(handler) => { | 156 | Some(handler) => { |
| 149 | let data = &reciever_buf[..n]; | 157 | let data = &reciever_buf[..n]; |
diff --git a/examples/lpc55s69/src/bin/pwm.rs b/examples/lpc55s69/src/bin/pwm.rs new file mode 100644 index 000000000..93b898b9d --- /dev/null +++ b/examples/lpc55s69/src/bin/pwm.rs | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nxp::pwm::{Config, Pwm}; | ||
| 7 | use embassy_time::Timer; | ||
| 8 | use {defmt_rtt as _, panic_halt as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let p = embassy_nxp::init(Default::default()); | ||
| 13 | let pwm = Pwm::new_output(p.PWM_OUTPUT1, p.PIO0_18, Config::new(1_000_000_000, 2_000_000_000)); | ||
| 14 | loop { | ||
| 15 | info!("Counter: {}", pwm.counter()); | ||
| 16 | Timer::after_millis(50).await; | ||
| 17 | } | ||
| 18 | } | ||
diff --git a/examples/mspm0g3507/src/bin/i2c_target.rs b/examples/mspm0g3507/src/bin/i2c_target.rs new file mode 100644 index 000000000..5dd718eaf --- /dev/null +++ b/examples/mspm0g3507/src/bin/i2c_target.rs | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | //! Example of using async I2C target | ||
| 2 | //! | ||
| 3 | //! This uses the virtual COM port provided on the LP-MSPM0G3507 board. | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_mspm0::i2c::Config; | ||
| 11 | use embassy_mspm0::i2c_target::{Command, Config as TargetConfig, I2cTarget, ReadStatus}; | ||
| 12 | use embassy_mspm0::peripherals::I2C1; | ||
| 13 | use embassy_mspm0::{bind_interrupts, i2c}; | ||
| 14 | use {defmt_rtt as _, panic_halt as _}; | ||
| 15 | |||
| 16 | bind_interrupts!(struct Irqs { | ||
| 17 | I2C1 => i2c::InterruptHandler<I2C1>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(_spawner: Spawner) -> ! { | ||
| 22 | let p = embassy_mspm0::init(Default::default()); | ||
| 23 | |||
| 24 | let instance = p.I2C1; | ||
| 25 | let scl = p.PB2; | ||
| 26 | let sda = p.PB3; | ||
| 27 | |||
| 28 | let config = Config::default(); | ||
| 29 | let mut target_config = TargetConfig::default(); | ||
| 30 | target_config.target_addr = 0x48; | ||
| 31 | target_config.general_call = true; | ||
| 32 | let mut i2c = I2cTarget::new(instance, scl, sda, Irqs, config, target_config).unwrap(); | ||
| 33 | |||
| 34 | let mut read = [0u8; 8]; | ||
| 35 | let data = [8u8; 2]; | ||
| 36 | let data_wr = [9u8; 2]; | ||
| 37 | |||
| 38 | loop { | ||
| 39 | match i2c.listen(&mut read).await { | ||
| 40 | Ok(Command::GeneralCall(_)) => info!("General call received"), | ||
| 41 | Ok(Command::Read) => { | ||
| 42 | info!("Read command received"); | ||
| 43 | match i2c.respond_to_read(&data).await.unwrap() { | ||
| 44 | ReadStatus::Done => info!("Finished reading"), | ||
| 45 | ReadStatus::NeedMoreBytes => { | ||
| 46 | info!("Read needs more bytes - will reset"); | ||
| 47 | i2c.reset().unwrap(); | ||
| 48 | } | ||
| 49 | ReadStatus::LeftoverBytes(_) => { | ||
| 50 | info!("Leftover bytes received"); | ||
| 51 | i2c.flush_tx_fifo(); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | Ok(Command::Write(_)) => info!("Write command received"), | ||
| 56 | Ok(Command::WriteRead(_)) => { | ||
| 57 | info!("Write-Read command received"); | ||
| 58 | i2c.respond_and_fill(&data_wr, 0xFE).await.unwrap(); | ||
| 59 | } | ||
| 60 | Err(e) => info!("Got error {}", e), | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
diff --git a/examples/mspm0l1306/src/bin/i2c_target.rs b/examples/mspm0l1306/src/bin/i2c_target.rs new file mode 100644 index 000000000..4d147d08b --- /dev/null +++ b/examples/mspm0l1306/src/bin/i2c_target.rs | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | //! Example of using async I2C target | ||
| 2 | //! | ||
| 3 | //! This uses the virtual COM port provided on the LP-MSPM0L1306 board. | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_mspm0::i2c::Config; | ||
| 11 | use embassy_mspm0::i2c_target::{Command, Config as TargetConfig, I2cTarget, ReadStatus}; | ||
| 12 | use embassy_mspm0::peripherals::I2C0; | ||
| 13 | use embassy_mspm0::{bind_interrupts, i2c}; | ||
| 14 | use {defmt_rtt as _, panic_halt as _}; | ||
| 15 | |||
| 16 | bind_interrupts!(struct Irqs { | ||
| 17 | I2C0 => i2c::InterruptHandler<I2C0>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(_spawner: Spawner) -> ! { | ||
| 22 | let p = embassy_mspm0::init(Default::default()); | ||
| 23 | |||
| 24 | let instance = p.I2C0; | ||
| 25 | let scl = p.PA1; | ||
| 26 | let sda = p.PA0; | ||
| 27 | |||
| 28 | let config = Config::default(); | ||
| 29 | let mut target_config = TargetConfig::default(); | ||
| 30 | target_config.target_addr = 0x48; | ||
| 31 | target_config.general_call = true; | ||
| 32 | let mut i2c = I2cTarget::new(instance, scl, sda, Irqs, config, target_config).unwrap(); | ||
| 33 | |||
| 34 | let mut read = [0u8; 8]; | ||
| 35 | let data = [8u8; 2]; | ||
| 36 | let data_wr = [9u8; 2]; | ||
| 37 | |||
| 38 | loop { | ||
| 39 | match i2c.listen(&mut read).await { | ||
| 40 | Ok(Command::GeneralCall(_)) => info!("General call received"), | ||
| 41 | Ok(Command::Read) => { | ||
| 42 | info!("Read command received"); | ||
| 43 | match i2c.respond_to_read(&data).await.unwrap() { | ||
| 44 | ReadStatus::Done => info!("Finished reading"), | ||
| 45 | ReadStatus::NeedMoreBytes => { | ||
| 46 | info!("Read needs more bytes - will reset"); | ||
| 47 | i2c.reset().unwrap(); | ||
| 48 | } | ||
| 49 | ReadStatus::LeftoverBytes(_) => { | ||
| 50 | info!("Leftover bytes received"); | ||
| 51 | i2c.flush_tx_fifo(); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | Ok(Command::Write(_)) => info!("Write command received"), | ||
| 56 | Ok(Command::WriteRead(_)) => { | ||
| 57 | info!("Write-Read command received"); | ||
| 58 | i2c.respond_and_fill(&data_wr, 0xFE).await.unwrap(); | ||
| 59 | } | ||
| 60 | Err(e) => info!("Got error {}", e), | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
diff --git a/examples/nrf52840/src/bin/egu.rs b/examples/nrf52840/src/bin/egu.rs index 8bf712697..36eba8084 100644 --- a/examples/nrf52840/src/bin/egu.rs +++ b/examples/nrf52840/src/bin/egu.rs | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::egu::{Egu, TriggerNumber}; | 8 | use embassy_nrf::egu::{Egu, TriggerNumber}; |
| 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 9 | use embassy_nrf::gpio::{Level, OutputDrive, Pull}; |
| 10 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity}; | 10 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity}; |
| 11 | use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2}; | 11 | use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2}; |
| 12 | use embassy_nrf::ppi::Ppi; | 12 | use embassy_nrf::ppi::Ppi; |
| @@ -17,12 +17,15 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_nrf::init(Default::default()); | 18 | let p = embassy_nrf::init(Default::default()); |
| 19 | 19 | ||
| 20 | let led1 = Output::new(p.P0_13, Level::High, OutputDrive::Standard); | ||
| 21 | let btn1 = Input::new(p.P0_11, Pull::Up); | ||
| 22 | |||
| 23 | let mut egu1 = Egu::new(p.EGU0); | 20 | let mut egu1 = Egu::new(p.EGU0); |
| 24 | let led1 = OutputChannel::new(p.GPIOTE_CH0, led1, OutputChannelPolarity::Toggle); | 21 | let led1 = OutputChannel::new( |
| 25 | let btn1 = InputChannel::new(p.GPIOTE_CH1, btn1, InputChannelPolarity::LoToHi); | 22 | p.GPIOTE_CH0, |
| 23 | p.P0_13, | ||
| 24 | Level::High, | ||
| 25 | OutputDrive::Standard, | ||
| 26 | OutputChannelPolarity::Toggle, | ||
| 27 | ); | ||
| 28 | let btn1 = InputChannel::new(p.GPIOTE_CH1, p.P0_11, Pull::Up, InputChannelPolarity::LoToHi); | ||
| 26 | 29 | ||
| 27 | let trigger0 = egu1.trigger(TriggerNumber::Trigger0); | 30 | let trigger0 = egu1.trigger(TriggerNumber::Trigger0); |
| 28 | let trigger1 = egu1.trigger(TriggerNumber::Trigger1); | 31 | let trigger1 = egu1.trigger(TriggerNumber::Trigger1); |
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs index dcfe7723a..c7ddc1d8d 100644 --- a/examples/nrf52840/src/bin/gpiote_channel.rs +++ b/examples/nrf52840/src/bin/gpiote_channel.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{Input, Pull}; | 6 | use embassy_nrf::gpio::Pull; |
| 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -12,26 +12,10 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_nrf::init(Default::default()); | 12 | let p = embassy_nrf::init(Default::default()); |
| 13 | info!("Starting!"); | 13 | info!("Starting!"); |
| 14 | 14 | ||
| 15 | let ch1 = InputChannel::new( | 15 | let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); |
| 16 | p.GPIOTE_CH0, | 16 | let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi); |
| 17 | Input::new(p.P0_11, Pull::Up), | 17 | let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle); |
| 18 | InputChannelPolarity::HiToLo, | 18 | let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle); |
| 19 | ); | ||
| 20 | let ch2 = InputChannel::new( | ||
| 21 | p.GPIOTE_CH1, | ||
| 22 | Input::new(p.P0_12, Pull::Up), | ||
| 23 | InputChannelPolarity::LoToHi, | ||
| 24 | ); | ||
| 25 | let ch3 = InputChannel::new( | ||
| 26 | p.GPIOTE_CH2, | ||
| 27 | Input::new(p.P0_24, Pull::Up), | ||
| 28 | InputChannelPolarity::Toggle, | ||
| 29 | ); | ||
| 30 | let ch4 = InputChannel::new( | ||
| 31 | p.GPIOTE_CH3, | ||
| 32 | Input::new(p.P0_25, Pull::Up), | ||
| 33 | InputChannelPolarity::Toggle, | ||
| 34 | ); | ||
| 35 | 19 | ||
| 36 | let button1 = async { | 20 | let button1 = async { |
| 37 | loop { | 21 | loop { |
diff --git a/examples/nrf52840/src/bin/i2s_monitor.rs b/examples/nrf52840/src/bin/i2s_monitor.rs index 66b429b09..a54659101 100644 --- a/examples/nrf52840/src/bin/i2s_monitor.rs +++ b/examples/nrf52840/src/bin/i2s_monitor.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::{debug, error, info}; | 4 | use defmt::{debug, error, info}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::i2s::{self, Channels, Config, DoubleBuffering, I2S, MasterClock, Sample as _, SampleWidth}; | 6 | use embassy_nrf::i2s::{self, Channels, Config, DoubleBuffering, I2S, MasterClock, Sample as _, SampleWidth}; |
| 7 | use embassy_nrf::pwm::{Prescaler, SimplePwm}; | 7 | use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm}; |
| 8 | use embassy_nrf::{bind_interrupts, peripherals}; | 8 | use embassy_nrf::{bind_interrupts, peripherals}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) { | |||
| 34 | I2S::new_master(p.I2S, Irqs, p.P0_25, p.P0_26, p.P0_27, master_clock, config).input(p.P0_29, buffers); | 34 | I2S::new_master(p.I2S, Irqs, p.P0_25, p.P0_26, p.P0_27, master_clock, config).input(p.P0_29, buffers); |
| 35 | 35 | ||
| 36 | // Configure the PWM to use the pins corresponding to the RGB leds | 36 | // Configure the PWM to use the pins corresponding to the RGB leds |
| 37 | let mut pwm = SimplePwm::new_3ch(p.PWM0, p.P0_23, p.P0_22, p.P0_24); | 37 | let mut pwm = SimplePwm::new_3ch(p.PWM0, p.P0_23, p.P0_22, p.P0_24, &Default::default()); |
| 38 | pwm.set_prescaler(Prescaler::Div1); | 38 | pwm.set_prescaler(Prescaler::Div1); |
| 39 | pwm.set_max_duty(255); | 39 | pwm.set_max_duty(255); |
| 40 | 40 | ||
| @@ -47,9 +47,8 @@ async fn main(_spawner: Spawner) { | |||
| 47 | let rgb = rgb_from_rms(rms); | 47 | let rgb = rgb_from_rms(rms); |
| 48 | 48 | ||
| 49 | debug!("RMS: {}, RGB: {:?}", rms, rgb); | 49 | debug!("RMS: {}, RGB: {:?}", rms, rgb); |
| 50 | for i in 0..3 { | 50 | let duties = rgb.map(|byte| DutyCycle::normal(u16::from(byte))); |
| 51 | pwm.set_duty(i, rgb[i].into()); | 51 | pwm.set_all_duties([duties[0], duties[1], duties[2], DutyCycle::normal(0)]); |
| 52 | } | ||
| 53 | 52 | ||
| 54 | if let Err(err) = input_stream.receive().await { | 53 | if let Err(err) = input_stream.receive().await { |
| 55 | error!("{}", err); | 54 | error!("{}", err); |
diff --git a/examples/nrf52840/src/bin/ppi.rs b/examples/nrf52840/src/bin/ppi.rs index 129ad06e7..177f6a06d 100644 --- a/examples/nrf52840/src/bin/ppi.rs +++ b/examples/nrf52840/src/bin/ppi.rs | |||
| @@ -5,7 +5,7 @@ use core::future::pending; | |||
| 5 | 5 | ||
| 6 | use defmt::info; | 6 | use defmt::info; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 8 | use embassy_nrf::gpio::{Level, OutputDrive, Pull}; |
| 9 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; | 9 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; |
| 10 | use embassy_nrf::ppi::Ppi; | 10 | use embassy_nrf::ppi::Ppi; |
| 11 | use gpiote::{OutputChannel, OutputChannelPolarity}; | 11 | use gpiote::{OutputChannel, OutputChannelPolarity}; |
| @@ -16,36 +16,24 @@ async fn main(_spawner: Spawner) { | |||
| 16 | let p = embassy_nrf::init(Default::default()); | 16 | let p = embassy_nrf::init(Default::default()); |
| 17 | info!("Starting!"); | 17 | info!("Starting!"); |
| 18 | 18 | ||
| 19 | let button1 = InputChannel::new( | 19 | let button1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); |
| 20 | p.GPIOTE_CH0, | 20 | let button2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::HiToLo); |
| 21 | Input::new(p.P0_11, Pull::Up), | 21 | let button3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::HiToLo); |
| 22 | InputChannelPolarity::HiToLo, | 22 | let button4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::HiToLo); |
| 23 | ); | ||
| 24 | let button2 = InputChannel::new( | ||
| 25 | p.GPIOTE_CH1, | ||
| 26 | Input::new(p.P0_12, Pull::Up), | ||
| 27 | InputChannelPolarity::HiToLo, | ||
| 28 | ); | ||
| 29 | let button3 = InputChannel::new( | ||
| 30 | p.GPIOTE_CH2, | ||
| 31 | Input::new(p.P0_24, Pull::Up), | ||
| 32 | InputChannelPolarity::HiToLo, | ||
| 33 | ); | ||
| 34 | let button4 = InputChannel::new( | ||
| 35 | p.GPIOTE_CH3, | ||
| 36 | Input::new(p.P0_25, Pull::Up), | ||
| 37 | InputChannelPolarity::HiToLo, | ||
| 38 | ); | ||
| 39 | 23 | ||
| 40 | let led1 = OutputChannel::new( | 24 | let led1 = OutputChannel::new( |
| 41 | p.GPIOTE_CH4, | 25 | p.GPIOTE_CH4, |
| 42 | Output::new(p.P0_13, Level::Low, OutputDrive::Standard), | 26 | p.P0_13, |
| 27 | Level::Low, | ||
| 28 | OutputDrive::Standard, | ||
| 43 | OutputChannelPolarity::Toggle, | 29 | OutputChannelPolarity::Toggle, |
| 44 | ); | 30 | ); |
| 45 | 31 | ||
| 46 | let led2 = OutputChannel::new( | 32 | let led2 = OutputChannel::new( |
| 47 | p.GPIOTE_CH5, | 33 | p.GPIOTE_CH5, |
| 48 | Output::new(p.P0_14, Level::Low, OutputDrive::Standard), | 34 | p.P0_14, |
| 35 | Level::Low, | ||
| 36 | OutputDrive::Standard, | ||
| 49 | OutputChannelPolarity::Toggle, | 37 | OutputChannelPolarity::Toggle, |
| 50 | ); | 38 | ); |
| 51 | 39 | ||
diff --git a/examples/nrf52840/src/bin/pwm.rs b/examples/nrf52840/src/bin/pwm.rs index a5bb1347a..02f9b4191 100644 --- a/examples/nrf52840/src/bin/pwm.rs +++ b/examples/nrf52840/src/bin/pwm.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::pwm::{Prescaler, SimplePwm}; | 6 | use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm}; |
| 7 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -71,7 +71,7 @@ static DUTY: [u16; 1024] = [ | |||
| 71 | #[embassy_executor::main] | 71 | #[embassy_executor::main] |
| 72 | async fn main(_spawner: Spawner) { | 72 | async fn main(_spawner: Spawner) { |
| 73 | let p = embassy_nrf::init(Default::default()); | 73 | let p = embassy_nrf::init(Default::default()); |
| 74 | let mut pwm = SimplePwm::new_4ch(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15); | 74 | let mut pwm = SimplePwm::new_4ch(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15, &Default::default()); |
| 75 | pwm.set_prescaler(Prescaler::Div1); | 75 | pwm.set_prescaler(Prescaler::Div1); |
| 76 | pwm.set_max_duty(32767); | 76 | pwm.set_max_duty(32767); |
| 77 | info!("pwm initialized!"); | 77 | info!("pwm initialized!"); |
| @@ -79,10 +79,12 @@ async fn main(_spawner: Spawner) { | |||
| 79 | let mut i = 0; | 79 | let mut i = 0; |
| 80 | loop { | 80 | loop { |
| 81 | i += 1; | 81 | i += 1; |
| 82 | pwm.set_duty(0, DUTY[i % 1024]); | 82 | pwm.set_all_duties([ |
| 83 | pwm.set_duty(1, DUTY[(i + 256) % 1024]); | 83 | DutyCycle::normal(DUTY[i % 1024]), |
| 84 | pwm.set_duty(2, DUTY[(i + 512) % 1024]); | 84 | DutyCycle::normal(DUTY[(i + 256) % 1024]), |
| 85 | pwm.set_duty(3, DUTY[(i + 768) % 1024]); | 85 | DutyCycle::normal(DUTY[(i + 512) % 1024]), |
| 86 | DutyCycle::normal(DUTY[(i + 768) % 1024]), | ||
| 87 | ]); | ||
| 86 | Timer::after_millis(3).await; | 88 | Timer::after_millis(3).await; |
| 87 | } | 89 | } |
| 88 | } | 90 | } |
diff --git a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs index 60ea712b5..fff7decb2 100644 --- a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs +++ b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs | |||
| @@ -5,7 +5,7 @@ use core::future::pending; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::gpio::{Input, Pull}; | 8 | use embassy_nrf::gpio::Pull; |
| 9 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | 9 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 10 | use embassy_nrf::ppi::Ppi; | 10 | use embassy_nrf::ppi::Ppi; |
| 11 | use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; | 11 | use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; |
| @@ -30,17 +30,9 @@ async fn main(_spawner: Spawner) { | |||
| 30 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work | 30 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work |
| 31 | // so its going to have to start running in order load the configuration | 31 | // so its going to have to start running in order load the configuration |
| 32 | 32 | ||
| 33 | let button1 = InputChannel::new( | 33 | let button1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); |
| 34 | p.GPIOTE_CH0, | ||
| 35 | Input::new(p.P0_11, Pull::Up), | ||
| 36 | InputChannelPolarity::HiToLo, | ||
| 37 | ); | ||
| 38 | 34 | ||
| 39 | let button2 = InputChannel::new( | 35 | let button2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::HiToLo); |
| 40 | p.GPIOTE_CH1, | ||
| 41 | Input::new(p.P0_12, Pull::Up), | ||
| 42 | InputChannelPolarity::HiToLo, | ||
| 43 | ); | ||
| 44 | 36 | ||
| 45 | // messing with the pwm tasks is ill advised | 37 | // messing with the pwm tasks is ill advised |
| 46 | // Times::Ininite and Times even are seq0, Times odd is seq1 | 38 | // Times::Ininite and Times even are seq0, Times odd is seq1 |
diff --git a/examples/nrf52840/src/bin/pwm_servo.rs b/examples/nrf52840/src/bin/pwm_servo.rs index d772d2f5d..93cb984e6 100644 --- a/examples/nrf52840/src/bin/pwm_servo.rs +++ b/examples/nrf52840/src/bin/pwm_servo.rs | |||
| @@ -3,14 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::pwm::{Prescaler, SimplePwm}; | 6 | use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm}; |
| 7 | use embassy_time::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] |
| 11 | async fn main(_spawner: Spawner) { | 11 | async fn main(_spawner: Spawner) { |
| 12 | let p = embassy_nrf::init(Default::default()); | 12 | let p = embassy_nrf::init(Default::default()); |
| 13 | let mut pwm = SimplePwm::new_1ch(p.PWM0, p.P0_05); | 13 | let mut pwm = SimplePwm::new_1ch(p.PWM0, p.P0_05, &Default::default()); |
| 14 | // sg90 microervo requires 50hz or 20ms period | 14 | // sg90 microervo requires 50hz or 20ms period |
| 15 | // set_period can only set down to 125khz so we cant use it directly | 15 | // set_period can only set down to 125khz so we cant use it directly |
| 16 | // Div128 is 125khz or 0.000008s or 0.008ms, 20/0.008 is 2500 is top | 16 | // Div128 is 125khz or 0.000008s or 0.008ms, 20/0.008 is 2500 is top |
| @@ -24,23 +24,23 @@ async fn main(_spawner: Spawner) { | |||
| 24 | loop { | 24 | loop { |
| 25 | info!("45 deg"); | 25 | info!("45 deg"); |
| 26 | // poor mans inverting, subtract our value from max_duty | 26 | // poor mans inverting, subtract our value from max_duty |
| 27 | pwm.set_duty(0, 2500 - 156); | 27 | pwm.set_duty(0, DutyCycle::normal(2500 - 156)); |
| 28 | Timer::after_millis(5000).await; | 28 | Timer::after_millis(5000).await; |
| 29 | 29 | ||
| 30 | info!("90 deg"); | 30 | info!("90 deg"); |
| 31 | pwm.set_duty(0, 2500 - 187); | 31 | pwm.set_duty(0, DutyCycle::normal(2500 - 187)); |
| 32 | Timer::after_millis(5000).await; | 32 | Timer::after_millis(5000).await; |
| 33 | 33 | ||
| 34 | info!("135 deg"); | 34 | info!("135 deg"); |
| 35 | pwm.set_duty(0, 2500 - 218); | 35 | pwm.set_duty(0, DutyCycle::normal(2500 - 218)); |
| 36 | Timer::after_millis(5000).await; | 36 | Timer::after_millis(5000).await; |
| 37 | 37 | ||
| 38 | info!("180 deg"); | 38 | info!("180 deg"); |
| 39 | pwm.set_duty(0, 2500 - 250); | 39 | pwm.set_duty(0, DutyCycle::normal(2500 - 250)); |
| 40 | Timer::after_millis(5000).await; | 40 | Timer::after_millis(5000).await; |
| 41 | 41 | ||
| 42 | info!("0 deg"); | 42 | info!("0 deg"); |
| 43 | pwm.set_duty(0, 2500 - 125); | 43 | pwm.set_duty(0, DutyCycle::normal(2500 - 125)); |
| 44 | Timer::after_millis(5000).await; | 44 | Timer::after_millis(5000).await; |
| 45 | } | 45 | } |
| 46 | } | 46 | } |
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs index 07752ffc4..2f9c06b56 100644 --- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs +++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs | |||
| @@ -27,14 +27,12 @@ bind_interrupts!(struct Irqs { | |||
| 27 | async fn wifi_task( | 27 | async fn wifi_task( |
| 28 | runner: hosted::Runner< | 28 | runner: hosted::Runner< |
| 29 | 'static, | 29 | 'static, |
| 30 | ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, | 30 | hosted::SpiInterface<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Input<'static>>, |
| 31 | Input<'static>, | ||
| 32 | Output<'static>, | 31 | Output<'static>, |
| 33 | >, | 32 | >, |
| 34 | ) -> ! { | 33 | ) -> ! { |
| 35 | runner.run().await | 34 | runner.run().await |
| 36 | } | 35 | } |
| 37 | |||
| 38 | #[embassy_executor::task] | 36 | #[embassy_executor::task] |
| 39 | async fn net_task(mut runner: embassy_net::Runner<'static, hosted::NetDriver<'static>>) -> ! { | 37 | async fn net_task(mut runner: embassy_net::Runner<'static, hosted::NetDriver<'static>>) -> ! { |
| 40 | runner.run().await | 38 | runner.run().await |
| @@ -60,15 +58,11 @@ async fn main(spawner: Spawner) { | |||
| 60 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); | 58 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); |
| 61 | let spi = ExclusiveDevice::new(spi, cs, Delay); | 59 | let spi = ExclusiveDevice::new(spi, cs, Delay); |
| 62 | 60 | ||
| 61 | let iface = hosted::SpiInterface::new(spi, handshake, ready); | ||
| 62 | |||
| 63 | static ESP_STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); | 63 | static ESP_STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); |
| 64 | let (device, mut control, runner) = embassy_net_esp_hosted::new( | 64 | let (device, mut control, runner) = |
| 65 | ESP_STATE.init(embassy_net_esp_hosted::State::new()), | 65 | embassy_net_esp_hosted::new(ESP_STATE.init(embassy_net_esp_hosted::State::new()), iface, reset).await; |
| 66 | spi, | ||
| 67 | handshake, | ||
| 68 | ready, | ||
| 69 | reset, | ||
| 70 | ) | ||
| 71 | .await; | ||
| 72 | 66 | ||
| 73 | spawner.spawn(unwrap!(wifi_task(runner))); | 67 | spawner.spawn(unwrap!(wifi_task(runner))); |
| 74 | 68 | ||
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs index 23f6fca98..a085310ce 100644 --- a/examples/nrf5340/src/bin/gpiote_channel.rs +++ b/examples/nrf5340/src/bin/gpiote_channel.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{Input, Pull}; | 6 | use embassy_nrf::gpio::Pull; |
| 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -12,26 +12,10 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_nrf::init(Default::default()); | 12 | let p = embassy_nrf::init(Default::default()); |
| 13 | info!("Starting!"); | 13 | info!("Starting!"); |
| 14 | 14 | ||
| 15 | let ch1 = InputChannel::new( | 15 | let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo); |
| 16 | p.GPIOTE_CH0, | 16 | let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi); |
| 17 | Input::new(p.P0_23, Pull::Up), | 17 | let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle); |
| 18 | InputChannelPolarity::HiToLo, | 18 | let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle); |
| 19 | ); | ||
| 20 | let ch2 = InputChannel::new( | ||
| 21 | p.GPIOTE_CH1, | ||
| 22 | Input::new(p.P0_24, Pull::Up), | ||
| 23 | InputChannelPolarity::LoToHi, | ||
| 24 | ); | ||
| 25 | let ch3 = InputChannel::new( | ||
| 26 | p.GPIOTE_CH2, | ||
| 27 | Input::new(p.P0_08, Pull::Up), | ||
| 28 | InputChannelPolarity::Toggle, | ||
| 29 | ); | ||
| 30 | let ch4 = InputChannel::new( | ||
| 31 | p.GPIOTE_CH3, | ||
| 32 | Input::new(p.P0_09, Pull::Up), | ||
| 33 | InputChannelPolarity::Toggle, | ||
| 34 | ); | ||
| 35 | 19 | ||
| 36 | let button1 = async { | 20 | let button1 = async { |
| 37 | loop { | 21 | loop { |
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml index a053dd0ec..4ef77279f 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml | |||
| @@ -6,9 +6,15 @@ license = "MIT OR Apache-2.0" | |||
| 6 | publish = false | 6 | publish = false |
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | ||
| 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | ||
| 11 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 13 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 14 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | |||
| 17 | rand = { version = "0.9.0", default-features = false } | ||
| 12 | 18 | ||
| 13 | defmt = "1.0.1" | 19 | defmt = "1.0.1" |
| 14 | defmt-rtt = "1.0.0" | 20 | defmt-rtt = "1.0.0" |
| @@ -18,6 +24,9 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 18 | cortex-m-rt = "0.7.0" | 24 | cortex-m-rt = "0.7.0" |
| 19 | 25 | ||
| 20 | embedded-storage = "0.3.1" | 26 | embedded-storage = "0.3.1" |
| 27 | portable-atomic = "1" | ||
| 28 | |||
| 29 | static_cell = "2" | ||
| 21 | 30 | ||
| 22 | [profile.release] | 31 | [profile.release] |
| 23 | debug = 2 | 32 | debug = 2 |
diff --git a/examples/nrf54l15/src/bin/buffered_uart.rs b/examples/nrf54l15/src/bin/buffered_uart.rs new file mode 100644 index 000000000..41fa1ca4e --- /dev/null +++ b/examples/nrf54l15/src/bin/buffered_uart.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | ||
| 7 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 8 | use embedded_io_async::Write; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | SERIAL20 => buffered_uarte::InterruptHandler<peripherals::SERIAL20>; | ||
| 13 | }); | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD115200; | ||
| 21 | |||
| 22 | let mut tx_buffer = [0u8; 4096]; | ||
| 23 | let mut rx_buffer = [0u8; 4096]; | ||
| 24 | |||
| 25 | let mut u = BufferedUarte::new( | ||
| 26 | p.SERIAL20, | ||
| 27 | p.P1_12, | ||
| 28 | p.P1_13, | ||
| 29 | Irqs, | ||
| 30 | config, | ||
| 31 | &mut rx_buffer, | ||
| 32 | &mut tx_buffer, | ||
| 33 | ); | ||
| 34 | |||
| 35 | info!("uarte initialized!"); | ||
| 36 | |||
| 37 | unwrap!(u.write_all(b"Hello!\r\n").await); | ||
| 38 | info!("wrote hello in uart!"); | ||
| 39 | |||
| 40 | loop { | ||
| 41 | info!("reading..."); | ||
| 42 | let buf = unwrap!(u.fill_buf().await); | ||
| 43 | info!("read done, got {}", buf); | ||
| 44 | |||
| 45 | // Read bytes have to be explicitly consumed, otherwise fill_buf() will return them again | ||
| 46 | let n = buf.len(); | ||
| 47 | u.consume(n); | ||
| 48 | } | ||
| 49 | } | ||
diff --git a/examples/nrf54l15/src/bin/gpiote_channel.rs b/examples/nrf54l15/src/bin/gpiote_channel.rs new file mode 100644 index 000000000..6333250ba --- /dev/null +++ b/examples/nrf54l15/src/bin/gpiote_channel.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::info; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::gpio::Pull; | ||
| 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let p = embassy_nrf::init(Default::default()); | ||
| 13 | info!("Starting!"); | ||
| 14 | |||
| 15 | let ch1 = InputChannel::new(p.GPIOTE20_CH0, p.P1_13, Pull::Up, InputChannelPolarity::HiToLo); | ||
| 16 | let ch2 = InputChannel::new(p.GPIOTE20_CH1, p.P1_09, Pull::Up, InputChannelPolarity::LoToHi); | ||
| 17 | let ch3 = InputChannel::new(p.GPIOTE20_CH2, p.P1_08, Pull::Up, InputChannelPolarity::Toggle); | ||
| 18 | let ch4 = InputChannel::new(p.GPIOTE30_CH0, p.P0_04, Pull::Up, InputChannelPolarity::Toggle); | ||
| 19 | |||
| 20 | let button1 = async { | ||
| 21 | loop { | ||
| 22 | ch1.wait().await; | ||
| 23 | info!("Button 1 pressed") | ||
| 24 | } | ||
| 25 | }; | ||
| 26 | |||
| 27 | let button2 = async { | ||
| 28 | loop { | ||
| 29 | ch2.wait().await; | ||
| 30 | info!("Button 2 released") | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 34 | let button3 = async { | ||
| 35 | loop { | ||
| 36 | ch3.wait().await; | ||
| 37 | info!("Button 3 toggled") | ||
| 38 | } | ||
| 39 | }; | ||
| 40 | |||
| 41 | let button4 = async { | ||
| 42 | loop { | ||
| 43 | ch4.wait().await; | ||
| 44 | info!("Button 4 toggled") | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | |||
| 48 | embassy_futures::join::join4(button1, button2, button3, button4).await; | ||
| 49 | } | ||
diff --git a/examples/nrf54l15/src/bin/gpiote_port.rs b/examples/nrf54l15/src/bin/gpiote_port.rs new file mode 100644 index 000000000..620cb2435 --- /dev/null +++ b/examples/nrf54l15/src/bin/gpiote_port.rs | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{info, unwrap}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::gpio::{Input, Pull}; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[embassy_executor::task(pool_size = 4)] | ||
| 10 | async fn button_task(n: usize, mut pin: Input<'static>) { | ||
| 11 | loop { | ||
| 12 | pin.wait_for_low().await; | ||
| 13 | info!("Button {:?} pressed!", n); | ||
| 14 | pin.wait_for_high().await; | ||
| 15 | info!("Button {:?} released!", n); | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(spawner: Spawner) { | ||
| 21 | let p = embassy_nrf::init(Default::default()); | ||
| 22 | info!("Starting!"); | ||
| 23 | |||
| 24 | let btn1 = Input::new(p.P1_13, Pull::Up); | ||
| 25 | let btn2 = Input::new(p.P1_09, Pull::Up); | ||
| 26 | let btn3 = Input::new(p.P1_08, Pull::Up); | ||
| 27 | let btn4 = Input::new(p.P0_04, Pull::Up); | ||
| 28 | |||
| 29 | spawner.spawn(unwrap!(button_task(1, btn1))); | ||
| 30 | spawner.spawn(unwrap!(button_task(2, btn2))); | ||
| 31 | spawner.spawn(unwrap!(button_task(3, btn3))); | ||
| 32 | spawner.spawn(unwrap!(button_task(4, btn4))); | ||
| 33 | } | ||
diff --git a/examples/nrf54l15/src/bin/pwm.rs b/examples/nrf54l15/src/bin/pwm.rs new file mode 100644 index 000000000..b438978f1 --- /dev/null +++ b/examples/nrf54l15/src/bin/pwm.rs | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm}; | ||
| 7 | use embassy_time::Timer; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | // for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='') | ||
| 11 | static DUTY: [u16; 1024] = [ | ||
| 12 | 8191, 8272, 8353, 8434, 8516, 8598, 8681, 8764, 8847, 8931, 9015, 9099, 9184, 9269, 9354, 9440, 9526, 9613, 9700, | ||
| 13 | 9787, 9874, 9962, 10050, 10139, 10227, 10316, 10406, 10495, 10585, 10675, 10766, 10857, 10948, 11039, 11131, 11223, | ||
| 14 | 11315, 11407, 11500, 11592, 11685, 11779, 11872, 11966, 12060, 12154, 12248, 12343, 12438, 12533, 12628, 12723, | ||
| 15 | 12818, 12914, 13010, 13106, 13202, 13298, 13394, 13491, 13587, 13684, 13781, 13878, 13975, 14072, 14169, 14266, | ||
| 16 | 14364, 14461, 14558, 14656, 14754, 14851, 14949, 15046, 15144, 15242, 15339, 15437, 15535, 15632, 15730, 15828, | ||
| 17 | 15925, 16023, 16120, 16218, 16315, 16412, 16510, 16607, 16704, 16801, 16898, 16995, 17091, 17188, 17284, 17380, | ||
| 18 | 17477, 17572, 17668, 17764, 17859, 17955, 18050, 18145, 18239, 18334, 18428, 18522, 18616, 18710, 18803, 18896, | ||
| 19 | 18989, 19082, 19174, 19266, 19358, 19449, 19540, 19631, 19722, 19812, 19902, 19991, 20081, 20169, 20258, 20346, | ||
| 20 | 20434, 20521, 20608, 20695, 20781, 20867, 20952, 21037, 21122, 21206, 21290, 21373, 21456, 21538, 21620, 21701, | ||
| 21 | 21782, 21863, 21943, 22022, 22101, 22179, 22257, 22335, 22412, 22488, 22564, 22639, 22714, 22788, 22861, 22934, | ||
| 22 | 23007, 23079, 23150, 23220, 23290, 23360, 23429, 23497, 23564, 23631, 23698, 23763, 23828, 23892, 23956, 24019, | ||
| 23 | 24081, 24143, 24204, 24264, 24324, 24383, 24441, 24499, 24555, 24611, 24667, 24721, 24775, 24828, 24881, 24933, | ||
| 24 | 24983, 25034, 25083, 25132, 25180, 25227, 25273, 25319, 25363, 25407, 25451, 25493, 25535, 25575, 25615, 25655, | ||
| 25 | 25693, 25731, 25767, 25803, 25838, 25873, 25906, 25939, 25971, 26002, 26032, 26061, 26089, 26117, 26144, 26170, | ||
| 26 | 26195, 26219, 26242, 26264, 26286, 26307, 26327, 26346, 26364, 26381, 26397, 26413, 26427, 26441, 26454, 26466, | ||
| 27 | 26477, 26487, 26496, 26505, 26512, 26519, 26525, 26530, 26534, 26537, 26539, 26540, 26541, 26540, 26539, 26537, | ||
| 28 | 26534, 26530, 26525, 26519, 26512, 26505, 26496, 26487, 26477, 26466, 26454, 26441, 26427, 26413, 26397, 26381, | ||
| 29 | 26364, 26346, 26327, 26307, 26286, 26264, 26242, 26219, 26195, 26170, 26144, 26117, 26089, 26061, 26032, 26002, | ||
| 30 | 25971, 25939, 25906, 25873, 25838, 25803, 25767, 25731, 25693, 25655, 25615, 25575, 25535, 25493, 25451, 25407, | ||
| 31 | 25363, 25319, 25273, 25227, 25180, 25132, 25083, 25034, 24983, 24933, 24881, 24828, 24775, 24721, 24667, 24611, | ||
| 32 | 24555, 24499, 24441, 24383, 24324, 24264, 24204, 24143, 24081, 24019, 23956, 23892, 23828, 23763, 23698, 23631, | ||
| 33 | 23564, 23497, 23429, 23360, 23290, 23220, 23150, 23079, 23007, 22934, 22861, 22788, 22714, 22639, 22564, 22488, | ||
| 34 | 22412, 22335, 22257, 22179, 22101, 22022, 21943, 21863, 21782, 21701, 21620, 21538, 21456, 21373, 21290, 21206, | ||
| 35 | 21122, 21037, 20952, 20867, 20781, 20695, 20608, 20521, 20434, 20346, 20258, 20169, 20081, 19991, 19902, 19812, | ||
| 36 | 19722, 19631, 19540, 19449, 19358, 19266, 19174, 19082, 18989, 18896, 18803, 18710, 18616, 18522, 18428, 18334, | ||
| 37 | 18239, 18145, 18050, 17955, 17859, 17764, 17668, 17572, 17477, 17380, 17284, 17188, 17091, 16995, 16898, 16801, | ||
| 38 | 16704, 16607, 16510, 16412, 16315, 16218, 16120, 16023, 15925, 15828, 15730, 15632, 15535, 15437, 15339, 15242, | ||
| 39 | 15144, 15046, 14949, 14851, 14754, 14656, 14558, 14461, 14364, 14266, 14169, 14072, 13975, 13878, 13781, 13684, | ||
| 40 | 13587, 13491, 13394, 13298, 13202, 13106, 13010, 12914, 12818, 12723, 12628, 12533, 12438, 12343, 12248, 12154, | ||
| 41 | 12060, 11966, 11872, 11779, 11685, 11592, 11500, 11407, 11315, 11223, 11131, 11039, 10948, 10857, 10766, 10675, | ||
| 42 | 10585, 10495, 10406, 10316, 10227, 10139, 10050, 9962, 9874, 9787, 9700, 9613, 9526, 9440, 9354, 9269, 9184, 9099, | ||
| 43 | 9015, 8931, 8847, 8764, 8681, 8598, 8516, 8434, 8353, 8272, 8191, 8111, 8031, 7952, 7873, 7794, 7716, 7638, 7561, | ||
| 44 | 7484, 7407, 7331, 7255, 7180, 7105, 7031, 6957, 6883, 6810, 6738, 6665, 6594, 6522, 6451, 6381, 6311, 6241, 6172, | ||
| 45 | 6104, 6036, 5968, 5901, 5834, 5767, 5702, 5636, 5571, 5507, 5443, 5379, 5316, 5253, 5191, 5130, 5068, 5008, 4947, | ||
| 46 | 4888, 4828, 4769, 4711, 4653, 4596, 4539, 4482, 4426, 4371, 4316, 4261, 4207, 4153, 4100, 4047, 3995, 3943, 3892, | ||
| 47 | 3841, 3791, 3741, 3691, 3642, 3594, 3546, 3498, 3451, 3404, 3358, 3312, 3267, 3222, 3178, 3134, 3090, 3047, 3005, | ||
| 48 | 2962, 2921, 2879, 2839, 2798, 2758, 2719, 2680, 2641, 2603, 2565, 2528, 2491, 2454, 2418, 2382, 2347, 2312, 2278, | ||
| 49 | 2244, 2210, 2177, 2144, 2112, 2080, 2048, 2017, 1986, 1956, 1926, 1896, 1867, 1838, 1810, 1781, 1754, 1726, 1699, | ||
| 50 | 1673, 1646, 1620, 1595, 1570, 1545, 1520, 1496, 1472, 1449, 1426, 1403, 1380, 1358, 1336, 1315, 1294, 1273, 1252, | ||
| 51 | 1232, 1212, 1192, 1173, 1154, 1135, 1117, 1099, 1081, 1063, 1046, 1029, 1012, 996, 980, 964, 948, 933, 918, 903, | ||
| 52 | 888, 874, 860, 846, 833, 819, 806, 793, 781, 768, 756, 744, 733, 721, 710, 699, 688, 677, 667, 657, 647, 637, 627, | ||
| 53 | 618, 609, 599, 591, 582, 574, 565, 557, 549, 541, 534, 526, 519, 512, 505, 498, 492, 485, 479, 473, 467, 461, 455, | ||
| 54 | 450, 444, 439, 434, 429, 424, 419, 415, 410, 406, 402, 398, 394, 390, 386, 383, 379, 376, 373, 370, 367, 364, 361, | ||
| 55 | 359, 356, 354, 351, 349, 347, 345, 343, 342, 340, 338, 337, 336, 334, 333, 332, 331, 330, 330, 329, 328, 328, 328, | ||
| 56 | 327, 327, 327, 327, 327, 328, 328, 328, 329, 330, 330, 331, 332, 333, 334, 336, 337, 338, 340, 342, 343, 345, 347, | ||
| 57 | 349, 351, 354, 356, 359, 361, 364, 367, 370, 373, 376, 379, 383, 386, 390, 394, 398, 402, 406, 410, 415, 419, 424, | ||
| 58 | 429, 434, 439, 444, 450, 455, 461, 467, 473, 479, 485, 492, 498, 505, 512, 519, 526, 534, 541, 549, 557, 565, 574, | ||
| 59 | 582, 591, 599, 609, 618, 627, 637, 647, 657, 667, 677, 688, 699, 710, 721, 733, 744, 756, 768, 781, 793, 806, 819, | ||
| 60 | 833, 846, 860, 874, 888, 903, 918, 933, 948, 964, 980, 996, 1012, 1029, 1046, 1063, 1081, 1099, 1117, 1135, 1154, | ||
| 61 | 1173, 1192, 1212, 1232, 1252, 1273, 1294, 1315, 1336, 1358, 1380, 1403, 1426, 1449, 1472, 1496, 1520, 1545, 1570, | ||
| 62 | 1595, 1620, 1646, 1673, 1699, 1726, 1754, 1781, 1810, 1838, 1867, 1896, 1926, 1956, 1986, 2017, 2048, 2080, 2112, | ||
| 63 | 2144, 2177, 2210, 2244, 2278, 2312, 2347, 2382, 2418, 2454, 2491, 2528, 2565, 2603, 2641, 2680, 2719, 2758, 2798, | ||
| 64 | 2839, 2879, 2921, 2962, 3005, 3047, 3090, 3134, 3178, 3222, 3267, 3312, 3358, 3404, 3451, 3498, 3546, 3594, 3642, | ||
| 65 | 3691, 3741, 3791, 3841, 3892, 3943, 3995, 4047, 4100, 4153, 4207, 4261, 4316, 4371, 4426, 4482, 4539, 4596, 4653, | ||
| 66 | 4711, 4769, 4828, 4888, 4947, 5008, 5068, 5130, 5191, 5253, 5316, 5379, 5443, 5507, 5571, 5636, 5702, 5767, 5834, | ||
| 67 | 5901, 5968, 6036, 6104, 6172, 6241, 6311, 6381, 6451, 6522, 6594, 6665, 6738, 6810, 6883, 6957, 7031, 7105, 7180, | ||
| 68 | 7255, 7331, 7407, 7484, 7561, 7638, 7716, 7794, 7873, 7952, 8031, 8111, | ||
| 69 | ]; | ||
| 70 | |||
| 71 | #[embassy_executor::main] | ||
| 72 | async fn main(_spawner: Spawner) { | ||
| 73 | let p = embassy_nrf::init(Default::default()); | ||
| 74 | let mut pwm = SimplePwm::new_2ch(p.PWM20, p.P1_10, p.P1_14, &Default::default()); | ||
| 75 | pwm.set_prescaler(Prescaler::Div1); | ||
| 76 | pwm.set_max_duty(32767); | ||
| 77 | info!("pwm initialized!"); | ||
| 78 | |||
| 79 | let mut i = 0; | ||
| 80 | loop { | ||
| 81 | i += 1; | ||
| 82 | pwm.set_duty(0, DutyCycle::normal(DUTY[i % 1024])); | ||
| 83 | pwm.set_duty(1, DutyCycle::normal(DUTY[(i + 512) % 1024])); | ||
| 84 | Timer::after_millis(3).await; | ||
| 85 | } | ||
| 86 | } | ||
diff --git a/examples/nrf54l15/src/bin/rng.rs b/examples/nrf54l15/src/bin/rng.rs new file mode 100644 index 000000000..b2d7f906b --- /dev/null +++ b/examples/nrf54l15/src/bin/rng.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::cracen::Cracen; | ||
| 6 | use rand::Rng as _; | ||
| 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 rng = Cracen::new_blocking(p.CRACEN); | ||
| 13 | |||
| 14 | // Async API | ||
| 15 | let mut bytes = [0; 4]; | ||
| 16 | rng.blocking_fill_bytes(&mut bytes); | ||
| 17 | defmt::info!("Some random bytes: {:?}", bytes); | ||
| 18 | |||
| 19 | // Sync API with `rand` | ||
| 20 | defmt::info!("A random number from 1 to 10: {:?}", rng.random_range(1..=10)); | ||
| 21 | |||
| 22 | let mut bytes = [0; 1024]; | ||
| 23 | rng.blocking_fill_bytes(&mut bytes); | ||
| 24 | let zero_count: u32 = bytes.iter().fold(0, |acc, val| acc + val.count_zeros()); | ||
| 25 | let one_count: u32 = bytes.iter().fold(0, |acc, val| acc + val.count_ones()); | ||
| 26 | defmt::info!("Chance of zero: {}%", zero_count * 100 / (bytes.len() as u32 * 8)); | ||
| 27 | defmt::info!("Chance of one: {}%", one_count * 100 / (bytes.len() as u32 * 8)); | ||
| 28 | } | ||
diff --git a/examples/nrf54l15/src/bin/rtc.rs b/examples/nrf54l15/src/bin/rtc.rs new file mode 100644 index 000000000..a45aaca52 --- /dev/null +++ b/examples/nrf54l15/src/bin/rtc.rs | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::cell::RefCell; | ||
| 5 | |||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 8 | use embassy_nrf::interrupt; | ||
| 9 | use embassy_nrf::rtc::Rtc; | ||
| 10 | use embassy_sync::blocking_mutex::Mutex; | ||
| 11 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 12 | use portable_atomic::AtomicU64; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | // 64 bit counter which will never overflow. | ||
| 16 | static TICK_COUNTER: AtomicU64 = AtomicU64::new(0); | ||
| 17 | static RTC: Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc<'static>>>> = Mutex::new(RefCell::new(None)); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | defmt::println!("nRF54L15 RTC example"); | ||
| 22 | let p = embassy_nrf::init(Default::default()); | ||
| 23 | let mut led = Output::new(p.P2_09, Level::High, OutputDrive::Standard); | ||
| 24 | // Counter resolution is 125 ms. | ||
| 25 | let mut rtc = Rtc::new(p.RTC10, (1 << 12) - 1).unwrap(); | ||
| 26 | rtc.enable_interrupt(embassy_nrf::rtc::Interrupt::Tick, true); | ||
| 27 | rtc.enable_event(embassy_nrf::rtc::Interrupt::Tick); | ||
| 28 | rtc.enable(); | ||
| 29 | RTC.lock(|r| { | ||
| 30 | let mut rtc_borrow = r.borrow_mut(); | ||
| 31 | *rtc_borrow = Some(rtc); | ||
| 32 | }); | ||
| 33 | |||
| 34 | let mut last_counter_val = 0; | ||
| 35 | loop { | ||
| 36 | let current = TICK_COUNTER.load(core::sync::atomic::Ordering::Relaxed); | ||
| 37 | if current != last_counter_val { | ||
| 38 | led.toggle(); | ||
| 39 | last_counter_val = current; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | #[interrupt] | ||
| 45 | fn RTC10() { | ||
| 46 | // For 64-bit, we do not need to worry about overflowing, at least not for realistic program | ||
| 47 | // lifetimes. | ||
| 48 | TICK_COUNTER.fetch_add(1, core::sync::atomic::Ordering::Relaxed); | ||
| 49 | RTC.lock(|r| { | ||
| 50 | let mut rtc_borrow = r.borrow_mut(); | ||
| 51 | rtc_borrow | ||
| 52 | .as_mut() | ||
| 53 | .unwrap() | ||
| 54 | .reset_event(embassy_nrf::rtc::Interrupt::Tick); | ||
| 55 | }); | ||
| 56 | } | ||
diff --git a/examples/nrf54l15/src/bin/saadc.rs b/examples/nrf54l15/src/bin/saadc.rs new file mode 100644 index 000000000..567177894 --- /dev/null +++ b/examples/nrf54l15/src/bin/saadc.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::info; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; | ||
| 7 | use embassy_nrf::{bind_interrupts, saadc}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | SAADC => saadc::InterruptHandler; | ||
| 13 | }); | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_p: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let config = Config::default(); | ||
| 19 | let channel_config = ChannelConfig::single_ended(p.P1_04.reborrow()); | ||
| 20 | let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]); | ||
| 21 | |||
| 22 | loop { | ||
| 23 | let mut buf = [0; 1]; | ||
| 24 | saadc.sample(&mut buf).await; | ||
| 25 | info!("sample: {=i16}", &buf[0]); | ||
| 26 | Timer::after_millis(100).await; | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/examples/nrf54l15/src/bin/spim.rs b/examples/nrf54l15/src/bin/spim.rs new file mode 100644 index 000000000..3f5980647 --- /dev/null +++ b/examples/nrf54l15/src/bin/spim.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::{bind_interrupts, peripherals, spim}; | ||
| 6 | use {defmt_rtt as _, panic_probe as _}; | ||
| 7 | |||
| 8 | bind_interrupts!(struct Irqs { | ||
| 9 | SERIAL00 => spim::InterruptHandler<peripherals::SERIAL00>; | ||
| 10 | }); | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | let p = embassy_nrf::init(Default::default()); | ||
| 15 | let mut config = spim::Config::default(); | ||
| 16 | config.frequency = spim::Frequency::M32; | ||
| 17 | let mut spim = spim::Spim::new(p.SERIAL00, Irqs, p.P2_05, p.P2_09, p.P2_08, config.clone()); | ||
| 18 | let data = [ | ||
| 19 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 20 | ]; | ||
| 21 | let mut buf = [0u8; 16]; | ||
| 22 | |||
| 23 | buf.fill(0); | ||
| 24 | spim.blocking_transfer(&mut buf, &data).unwrap(); | ||
| 25 | assert_eq!(data, buf); | ||
| 26 | |||
| 27 | buf.fill(0); | ||
| 28 | spim.transfer(&mut buf, &data).await.unwrap(); | ||
| 29 | assert_eq!(data, buf); | ||
| 30 | } | ||
diff --git a/examples/nrf54l15/src/bin/twim.rs b/examples/nrf54l15/src/bin/twim.rs new file mode 100644 index 000000000..53b85034e --- /dev/null +++ b/examples/nrf54l15/src/bin/twim.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | //! Example on how to read a 24C/24LC i2c eeprom. | ||
| 2 | //! | ||
| 3 | //! Connect SDA to P0.03, SCL to P0.04 | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_nrf::twim::{self, Twim}; | ||
| 11 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 12 | use static_cell::ConstStaticCell; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | const ADDRESS: u8 = 0x18; | ||
| 16 | const WHOAMI: u8 = 0x0F; | ||
| 17 | |||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | SERIAL20 => twim::InterruptHandler<peripherals::SERIAL20>; | ||
| 20 | }); | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async fn main(_spawner: Spawner) { | ||
| 24 | let p = embassy_nrf::init(Default::default()); | ||
| 25 | info!("Initializing TWI..."); | ||
| 26 | let config = twim::Config::default(); | ||
| 27 | static RAM_BUFFER: ConstStaticCell<[u8; 16]> = ConstStaticCell::new([0; 16]); | ||
| 28 | let mut twi = Twim::new(p.SERIAL20, Irqs, p.P1_13, p.P1_12, config, RAM_BUFFER.take()); | ||
| 29 | |||
| 30 | info!("Reading..."); | ||
| 31 | |||
| 32 | let mut data = [0u8; 1]; | ||
| 33 | match twi.write_read(ADDRESS, &[WHOAMI], &mut data).await { | ||
| 34 | Ok(()) => info!("Whoami: {}", data[0]), | ||
| 35 | Err(e) => error!("I2c Error: {:?}", e), | ||
| 36 | } | ||
| 37 | } | ||
diff --git a/examples/nrf54l15/src/bin/twis.rs b/examples/nrf54l15/src/bin/twis.rs new file mode 100644 index 000000000..34c04aee3 --- /dev/null +++ b/examples/nrf54l15/src/bin/twis.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | //! TWIS example | ||
| 2 | |||
| 3 | #![no_std] | ||
| 4 | #![no_main] | ||
| 5 | |||
| 6 | use defmt::*; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_nrf::twis::{self, Command, Twis}; | ||
| 9 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | SERIAL20 => twis::InterruptHandler<peripherals::SERIAL20>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let p = embassy_nrf::init(Default::default()); | ||
| 19 | |||
| 20 | let mut config = twis::Config::default(); | ||
| 21 | config.address0 = 0x55; // Set i2c address | ||
| 22 | let mut i2c = Twis::new(p.SERIAL20, Irqs, p.P0_03, p.P0_04, config); | ||
| 23 | |||
| 24 | info!("Listening..."); | ||
| 25 | loop { | ||
| 26 | let response = [1, 2, 3, 4, 5, 6, 7, 8]; | ||
| 27 | // This buffer is used if the i2c master performs a Write or WriteRead | ||
| 28 | let mut buf = [0u8; 16]; | ||
| 29 | match i2c.listen(&mut buf).await { | ||
| 30 | Ok(Command::Read) => { | ||
| 31 | info!("Got READ command. Respond with data:\n{:?}\n", response); | ||
| 32 | if let Err(e) = i2c.respond_to_read(&response).await { | ||
| 33 | error!("{:?}", e); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | Ok(Command::Write(n)) => info!("Got WRITE command with data:\n{:?}\n", buf[..n]), | ||
| 37 | Ok(Command::WriteRead(n)) => { | ||
| 38 | info!("Got WRITE/READ command with data:\n{:?}", buf[..n]); | ||
| 39 | info!("Respond with data:\n{:?}\n", response); | ||
| 40 | if let Err(e) = i2c.respond_to_read(&response).await { | ||
| 41 | error!("{:?}", e); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | Err(e) => error!("{:?}", e), | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/examples/nrf54l15/src/bin/uart.rs b/examples/nrf54l15/src/bin/uart.rs new file mode 100644 index 000000000..cc6528a6f --- /dev/null +++ b/examples/nrf54l15/src/bin/uart.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | bind_interrupts!(struct Irqs { | ||
| 10 | SERIAL20 => uarte::InterruptHandler<peripherals::SERIAL20>; | ||
| 11 | }); | ||
| 12 | |||
| 13 | #[embassy_executor::main] | ||
| 14 | async fn main(_spawner: Spawner) { | ||
| 15 | let p = embassy_nrf::init(Default::default()); | ||
| 16 | let mut config = uarte::Config::default(); | ||
| 17 | config.parity = uarte::Parity::EXCLUDED; | ||
| 18 | config.baudrate = uarte::Baudrate::BAUD115200; | ||
| 19 | |||
| 20 | let mut uart = uarte::Uarte::new(p.SERIAL20, p.P1_12, p.P1_13, Irqs, config); | ||
| 21 | |||
| 22 | info!("uarte initialized!"); | ||
| 23 | |||
| 24 | // Message must be in SRAM | ||
| 25 | let mut buf = [0; 8]; | ||
| 26 | buf.copy_from_slice(b"Hello!\r\n"); | ||
| 27 | |||
| 28 | unwrap!(uart.write(&buf).await); | ||
| 29 | info!("wrote hello in uart!"); | ||
| 30 | |||
| 31 | loop { | ||
| 32 | info!("reading..."); | ||
| 33 | unwrap!(uart.read(&mut buf).await); | ||
| 34 | info!("writing..."); | ||
| 35 | unwrap!(uart.write(&buf).await); | ||
| 36 | } | ||
| 37 | } | ||
diff --git a/examples/rp/src/bin/pio_onewire.rs b/examples/rp/src/bin/pio_onewire.rs index 102f13c45..6432edb8a 100644 --- a/examples/rp/src/bin/pio_onewire.rs +++ b/examples/rp/src/bin/pio_onewire.rs | |||
| @@ -61,7 +61,7 @@ async fn main(_spawner: Spawner) { | |||
| 61 | let mut data = [0; 9]; | 61 | let mut data = [0; 9]; |
| 62 | onewire.read_bytes(&mut data).await; | 62 | onewire.read_bytes(&mut data).await; |
| 63 | if crc8(&data) == 0 { | 63 | if crc8(&data) == 0 { |
| 64 | let temp = ((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.; | 64 | let temp = ((data[1] as i16) << 8 | data[0] as i16) as f32 / 16.; |
| 65 | info!("Read device {:x}: {} deg C", device, temp); | 65 | info!("Read device {:x}: {} deg C", device, temp); |
| 66 | } else { | 66 | } else { |
| 67 | warn!("Reading device {:x} failed", device); | 67 | warn!("Reading device {:x} failed", device); |
diff --git a/examples/rp/src/bin/pio_onewire_parasite.rs b/examples/rp/src/bin/pio_onewire_parasite.rs index fd076dee0..78fb94b18 100644 --- a/examples/rp/src/bin/pio_onewire_parasite.rs +++ b/examples/rp/src/bin/pio_onewire_parasite.rs | |||
| @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { | |||
| 63 | let mut data = [0; 9]; | 63 | let mut data = [0; 9]; |
| 64 | onewire.read_bytes(&mut data).await; | 64 | onewire.read_bytes(&mut data).await; |
| 65 | if crc8(&data) == 0 { | 65 | if crc8(&data) == 0 { |
| 66 | let temp = ((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.; | 66 | let temp = ((data[1] as i16) << 8 | data[0] as i16) as f32 / 16.; |
| 67 | info!("Read device {:x}: {} deg C", device, temp); | 67 | info!("Read device {:x}: {} deg C", device, temp); |
| 68 | } else { | 68 | } else { |
| 69 | warn!("Reading device {:x} failed. {:02x}", device, data); | 69 | warn!("Reading device {:x} failed. {:02x}", device, data); |
diff --git a/examples/rp235x/src/bin/pio_onewire.rs b/examples/rp235x/src/bin/pio_onewire.rs index 102f13c45..6432edb8a 100644 --- a/examples/rp235x/src/bin/pio_onewire.rs +++ b/examples/rp235x/src/bin/pio_onewire.rs | |||
| @@ -61,7 +61,7 @@ async fn main(_spawner: Spawner) { | |||
| 61 | let mut data = [0; 9]; | 61 | let mut data = [0; 9]; |
| 62 | onewire.read_bytes(&mut data).await; | 62 | onewire.read_bytes(&mut data).await; |
| 63 | if crc8(&data) == 0 { | 63 | if crc8(&data) == 0 { |
| 64 | let temp = ((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.; | 64 | let temp = ((data[1] as i16) << 8 | data[0] as i16) as f32 / 16.; |
| 65 | info!("Read device {:x}: {} deg C", device, temp); | 65 | info!("Read device {:x}: {} deg C", device, temp); |
| 66 | } else { | 66 | } else { |
| 67 | warn!("Reading device {:x} failed", device); | 67 | warn!("Reading device {:x} failed", device); |
diff --git a/examples/rp235x/src/bin/pio_onewire_parasite.rs b/examples/rp235x/src/bin/pio_onewire_parasite.rs index fd076dee0..78fb94b18 100644 --- a/examples/rp235x/src/bin/pio_onewire_parasite.rs +++ b/examples/rp235x/src/bin/pio_onewire_parasite.rs | |||
| @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { | |||
| 63 | let mut data = [0; 9]; | 63 | let mut data = [0; 9]; |
| 64 | onewire.read_bytes(&mut data).await; | 64 | onewire.read_bytes(&mut data).await; |
| 65 | if crc8(&data) == 0 { | 65 | if crc8(&data) == 0 { |
| 66 | let temp = ((data[1] as u32) << 8 | data[0] as u32) as f32 / 16.; | 66 | let temp = ((data[1] as i16) << 8 | data[0] as i16) as f32 / 16.; |
| 67 | info!("Read device {:x}: {} deg C", device, temp); | 67 | info!("Read device {:x}: {} deg C", device, temp); |
| 68 | } else { | 68 | } else { |
| 69 | warn!("Reading device {:x} failed. {:02x}", device, data); | 69 | warn!("Reading device {:x} failed. {:02x}", device, data); |
diff --git a/examples/stm32c0/src/bin/rtc.rs b/examples/stm32c0/src/bin/rtc.rs index feb27f6d9..5ff705ca2 100644 --- a/examples/stm32c0/src/bin/rtc.rs +++ b/examples/stm32c0/src/bin/rtc.rs | |||
| @@ -21,12 +21,12 @@ async fn main(_spawner: Spawner) { | |||
| 21 | .and_hms_opt(10, 30, 15) | 21 | .and_hms_opt(10, 30, 15) |
| 22 | .unwrap(); | 22 | .unwrap(); |
| 23 | 23 | ||
| 24 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 24 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 25 | 25 | ||
| 26 | rtc.set_datetime(now.into()).expect("datetime not set"); | 26 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 27 | 27 | ||
| 28 | loop { | 28 | loop { |
| 29 | let now: NaiveDateTime = rtc.now().unwrap().into(); | 29 | let now: NaiveDateTime = time_provider.now().unwrap().into(); |
| 30 | 30 | ||
| 31 | info!("{}", now.and_utc().timestamp()); | 31 | info!("{}", now.and_utc().timestamp()); |
| 32 | 32 | ||
diff --git a/examples/stm32f4/src/bin/adc_dma.rs b/examples/stm32f4/src/bin/adc_dma.rs index c24f01753..f8da91336 100644 --- a/examples/stm32f4/src/bin/adc_dma.rs +++ b/examples/stm32f4/src/bin/adc_dma.rs | |||
| @@ -4,7 +4,7 @@ use cortex_m::singleton; | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::Peripherals; | 6 | use embassy_stm32::Peripherals; |
| 7 | use embassy_stm32::adc::{Adc, RingBufferedAdc, SampleTime, Sequence}; | 7 | use embassy_stm32::adc::{Adc, AdcChannel, RingBufferedAdc, SampleTime}; |
| 8 | use embassy_time::Instant; | 8 | use embassy_time::Instant; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -15,7 +15,7 @@ async fn main(spawner: Spawner) { | |||
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | #[embassy_executor::task] | 17 | #[embassy_executor::task] |
| 18 | async fn adc_task(mut p: Peripherals) { | 18 | async fn adc_task(p: Peripherals) { |
| 19 | const ADC_BUF_SIZE: usize = 1024; | 19 | const ADC_BUF_SIZE: usize = 1024; |
| 20 | let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); | 20 | let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); |
| 21 | let adc_data2: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT2 : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); | 21 | let adc_data2: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT2 : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); |
| @@ -23,13 +23,24 @@ async fn adc_task(mut p: Peripherals) { | |||
| 23 | let adc = Adc::new(p.ADC1); | 23 | let adc = Adc::new(p.ADC1); |
| 24 | let adc2 = Adc::new(p.ADC2); | 24 | let adc2 = Adc::new(p.ADC2); |
| 25 | 25 | ||
| 26 | let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(p.DMA2_CH0, adc_data); | 26 | let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered( |
| 27 | let mut adc2: RingBufferedAdc<embassy_stm32::peripherals::ADC2> = adc2.into_ring_buffered(p.DMA2_CH2, adc_data2); | 27 | p.DMA2_CH0, |
| 28 | 28 | adc_data, | |
| 29 | adc.set_sample_sequence(Sequence::One, &mut p.PA0, SampleTime::CYCLES112); | 29 | [ |
| 30 | adc.set_sample_sequence(Sequence::Two, &mut p.PA2, SampleTime::CYCLES112); | 30 | (&mut p.PA0.degrade_adc(), SampleTime::CYCLES112), |
| 31 | adc2.set_sample_sequence(Sequence::One, &mut p.PA1, SampleTime::CYCLES112); | 31 | (&mut p.PA2.degrade_adc(), SampleTime::CYCLES112), |
| 32 | adc2.set_sample_sequence(Sequence::Two, &mut p.PA3, SampleTime::CYCLES112); | 32 | ] |
| 33 | .into_iter(), | ||
| 34 | ); | ||
| 35 | let mut adc2: RingBufferedAdc<embassy_stm32::peripherals::ADC2> = adc2.into_ring_buffered( | ||
| 36 | p.DMA2_CH2, | ||
| 37 | adc_data2, | ||
| 38 | [ | ||
| 39 | (&mut p.PA1.degrade_adc(), SampleTime::CYCLES112), | ||
| 40 | (&mut p.PA3.degrade_adc(), SampleTime::CYCLES112), | ||
| 41 | ] | ||
| 42 | .into_iter(), | ||
| 43 | ); | ||
| 33 | 44 | ||
| 34 | // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around | 45 | // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around |
| 35 | // to the adc.read() call before the DMA buffer is wrapped around > 1 time. At this point, the overrun is so significant that the context of | 46 | // to the adc.read() call before the DMA buffer is wrapped around > 1 time. At this point, the overrun is so significant that the context of |
diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs index cccf20949..0adcda614 100644 --- a/examples/stm32f4/src/bin/eth_w5500.rs +++ b/examples/stm32f4/src/bin/eth_w5500.rs | |||
| @@ -12,6 +12,7 @@ use embassy_stm32::gpio::{Level, Output, Pull, Speed}; | |||
| 12 | use embassy_stm32::mode::Async; | 12 | use embassy_stm32::mode::Async; |
| 13 | use embassy_stm32::rng::Rng; | 13 | use embassy_stm32::rng::Rng; |
| 14 | use embassy_stm32::spi::Spi; | 14 | use embassy_stm32::spi::Spi; |
| 15 | use embassy_stm32::spi::mode::Master; | ||
| 15 | use embassy_stm32::time::Hertz; | 16 | use embassy_stm32::time::Hertz; |
| 16 | use embassy_stm32::{Config, bind_interrupts, peripherals, rng, spi}; | 17 | use embassy_stm32::{Config, bind_interrupts, peripherals, rng, spi}; |
| 17 | use embassy_time::{Delay, Timer}; | 18 | use embassy_time::{Delay, Timer}; |
| @@ -24,7 +25,7 @@ bind_interrupts!(struct Irqs { | |||
| 24 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; | 25 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; |
| 25 | }); | 26 | }); |
| 26 | 27 | ||
| 27 | type EthernetSPI = ExclusiveDevice<Spi<'static, Async>, Output<'static>, Delay>; | 28 | type EthernetSPI = ExclusiveDevice<Spi<'static, Async, Master>, Output<'static>, Delay>; |
| 28 | #[embassy_executor::task] | 29 | #[embassy_executor::task] |
| 29 | async fn ethernet_task(runner: Runner<'static, W5500, EthernetSPI, ExtiInput<'static>, Output<'static>>) -> ! { | 30 | async fn ethernet_task(runner: Runner<'static, W5500, EthernetSPI, ExtiInput<'static>, Output<'static>>) -> ! { |
| 30 | runner.run().await | 31 | runner.run().await |
diff --git a/examples/stm32f4/src/bin/i2c_slave_async.rs b/examples/stm32f4/src/bin/i2c_slave_async.rs new file mode 100644 index 000000000..5065bcdd8 --- /dev/null +++ b/examples/stm32f4/src/bin/i2c_slave_async.rs | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | //! I2C slave example using async operations with DMA | ||
| 2 | //! | ||
| 3 | //! This example demonstrates DMA-accelerated I2C slave operations, | ||
| 4 | //! which provide better performance and lower CPU overhead for | ||
| 5 | //! high-frequency I2C transactions. | ||
| 6 | |||
| 7 | #![no_std] | ||
| 8 | #![no_main] | ||
| 9 | |||
| 10 | use defmt::{error, info}; | ||
| 11 | use embassy_executor::Spawner; | ||
| 12 | use embassy_stm32::i2c::{self, Address, I2c, SlaveAddrConfig, SlaveCommand, SlaveCommandKind}; | ||
| 13 | use embassy_stm32::time::Hertz; | ||
| 14 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 15 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
| 16 | use embassy_sync::mutex::Mutex; | ||
| 17 | use embassy_time::{Duration, Timer}; | ||
| 18 | use {defmt_rtt as _, panic_probe as _}; | ||
| 19 | |||
| 20 | pub const I2C_SLAVE_ADDR: u8 = 0x42; | ||
| 21 | pub const BUFFER_SIZE: usize = 8; | ||
| 22 | static I2C_BUFFER: Mutex<ThreadModeRawMutex, [u8; BUFFER_SIZE]> = Mutex::new([0; BUFFER_SIZE]); | ||
| 23 | |||
| 24 | bind_interrupts!(struct Irqs { | ||
| 25 | I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; | ||
| 26 | I2C1_ER => i2c::ErrorInterruptHandler<peripherals::I2C1>; | ||
| 27 | }); | ||
| 28 | |||
| 29 | #[embassy_executor::main] | ||
| 30 | async fn main(spawner: Spawner) { | ||
| 31 | let p = embassy_stm32::init(Default::default()); | ||
| 32 | |||
| 33 | // Configure I2C | ||
| 34 | let mut i2c_config = i2c::Config::default(); | ||
| 35 | i2c_config.sda_pullup = false; | ||
| 36 | i2c_config.scl_pullup = false; | ||
| 37 | i2c_config.frequency = Hertz(100_000); // 100kHz I2C speed | ||
| 38 | |||
| 39 | // Initialize I2C as master first | ||
| 40 | let i2c_master = I2c::new( | ||
| 41 | p.I2C1, p.PB8, // SCL | ||
| 42 | p.PB9, // SDA | ||
| 43 | Irqs, p.DMA1_CH6, // TX DMA | ||
| 44 | p.DMA1_CH0, // RX DMA | ||
| 45 | i2c_config, | ||
| 46 | ); | ||
| 47 | |||
| 48 | // Convert to MultiMaster mode | ||
| 49 | let slave_config = SlaveAddrConfig::basic(I2C_SLAVE_ADDR); | ||
| 50 | let i2c_slave = i2c_master.into_slave_multimaster(slave_config); | ||
| 51 | |||
| 52 | spawner.spawn(i2c_slave_task(i2c_slave).unwrap()); | ||
| 53 | } | ||
| 54 | |||
| 55 | #[embassy_executor::task] | ||
| 56 | pub async fn i2c_slave_task(mut i2c_slave: I2c<'static, embassy_stm32::mode::Async, i2c::mode::MultiMaster>) { | ||
| 57 | info!("Async I2C slave ready at address 0x{:02X}", I2C_SLAVE_ADDR); | ||
| 58 | |||
| 59 | loop { | ||
| 60 | match i2c_slave.listen().await { | ||
| 61 | Ok(SlaveCommand { | ||
| 62 | kind: SlaveCommandKind::Write, | ||
| 63 | address, | ||
| 64 | }) => { | ||
| 65 | let addr_val = match address { | ||
| 66 | Address::SevenBit(addr) => addr, | ||
| 67 | Address::TenBit(addr) => (addr & 0xFF) as u8, | ||
| 68 | }; | ||
| 69 | |||
| 70 | info!("I2C: Received write command - Address 0x{:02X}", addr_val); | ||
| 71 | |||
| 72 | let mut data_buffer = I2C_BUFFER.lock().await; | ||
| 73 | |||
| 74 | match i2c_slave.respond_to_write(&mut *data_buffer).await { | ||
| 75 | Ok(_) => { | ||
| 76 | info!( | ||
| 77 | "I2C: Data received - Buffer now contains: 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}", | ||
| 78 | data_buffer[0], | ||
| 79 | data_buffer[1], | ||
| 80 | data_buffer[2], | ||
| 81 | data_buffer[3], | ||
| 82 | data_buffer[4], | ||
| 83 | data_buffer[5], | ||
| 84 | data_buffer[6], | ||
| 85 | data_buffer[7] | ||
| 86 | ); | ||
| 87 | } | ||
| 88 | Err(e) => { | ||
| 89 | error!("I2C: Write error: {}", format_i2c_error(&e)); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | Ok(SlaveCommand { | ||
| 95 | kind: SlaveCommandKind::Read, | ||
| 96 | address, | ||
| 97 | }) => { | ||
| 98 | let addr_val = match address { | ||
| 99 | Address::SevenBit(addr) => addr, | ||
| 100 | Address::TenBit(addr) => (addr & 0xFF) as u8, // Show low byte for 10-bit | ||
| 101 | }; | ||
| 102 | |||
| 103 | info!("I2C: Received read command - Address 0x{:02X}", addr_val); | ||
| 104 | |||
| 105 | let data_buffer = I2C_BUFFER.lock().await; | ||
| 106 | |||
| 107 | match i2c_slave.respond_to_read(&data_buffer[..BUFFER_SIZE]).await { | ||
| 108 | Ok(_) => { | ||
| 109 | info!("I2C: Responded to read command"); | ||
| 110 | } | ||
| 111 | Err(e) => { | ||
| 112 | error!("I2C: Read error: {}", format_i2c_error(&e)); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | Err(e) => { | ||
| 118 | error!("I2C: Listen error: {}", format_i2c_error(&e)); | ||
| 119 | Timer::after(Duration::from_millis(100)).await; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | fn format_i2c_error(e: &embassy_stm32::i2c::Error) -> &'static str { | ||
| 126 | match e { | ||
| 127 | embassy_stm32::i2c::Error::Bus => "Bus", | ||
| 128 | embassy_stm32::i2c::Error::Arbitration => "Arbitration", | ||
| 129 | embassy_stm32::i2c::Error::Nack => "Nack", | ||
| 130 | embassy_stm32::i2c::Error::Timeout => "Timeout", | ||
| 131 | embassy_stm32::i2c::Error::Crc => "Crc", | ||
| 132 | embassy_stm32::i2c::Error::Overrun => "Overrun", | ||
| 133 | embassy_stm32::i2c::Error::ZeroLengthTransfer => "ZeroLengthTransfer", | ||
| 134 | } | ||
| 135 | } | ||
diff --git a/examples/stm32f4/src/bin/i2c_slave_blocking.rs b/examples/stm32f4/src/bin/i2c_slave_blocking.rs new file mode 100644 index 000000000..ee06d4ac4 --- /dev/null +++ b/examples/stm32f4/src/bin/i2c_slave_blocking.rs | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | //! Complete I2C slave example using blocking operations | ||
| 2 | //! | ||
| 3 | //! This example shows how to set up an STM32F4 as an I2C slave device | ||
| 4 | //! that can handle both read and write transactions from master devices. | ||
| 5 | |||
| 6 | #![no_std] | ||
| 7 | #![no_main] | ||
| 8 | |||
| 9 | use defmt::{error, info}; | ||
| 10 | use embassy_executor::Spawner; | ||
| 11 | use embassy_stm32::i2c::{self, Address, I2c, SlaveAddrConfig, SlaveCommand, SlaveCommandKind}; | ||
| 12 | use embassy_stm32::time::Hertz; | ||
| 13 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 14 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
| 15 | use embassy_sync::mutex::Mutex; | ||
| 16 | use embassy_time::{Duration, Timer}; | ||
| 17 | use {defmt_rtt as _, panic_probe as _}; | ||
| 18 | |||
| 19 | pub const I2C_SLAVE_ADDR: u8 = 0x42; | ||
| 20 | pub const BUFFER_SIZE: usize = 8; | ||
| 21 | static I2C_BUFFER: Mutex<ThreadModeRawMutex, [u8; BUFFER_SIZE]> = Mutex::new([0; BUFFER_SIZE]); | ||
| 22 | |||
| 23 | bind_interrupts!(struct Irqs { | ||
| 24 | I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; | ||
| 25 | I2C1_ER => i2c::ErrorInterruptHandler<peripherals::I2C1>; | ||
| 26 | }); | ||
| 27 | |||
| 28 | #[embassy_executor::main] | ||
| 29 | async fn main(spawner: Spawner) { | ||
| 30 | let p = embassy_stm32::init(Default::default()); | ||
| 31 | |||
| 32 | // Configure I2C | ||
| 33 | let mut i2c_config = i2c::Config::default(); | ||
| 34 | i2c_config.sda_pullup = false; | ||
| 35 | i2c_config.scl_pullup = false; | ||
| 36 | i2c_config.frequency = Hertz(100_000); | ||
| 37 | i2c_config.timeout = embassy_time::Duration::from_millis(30000); | ||
| 38 | |||
| 39 | // Initialize I2C as master first | ||
| 40 | let i2c_master = I2c::new_blocking( | ||
| 41 | p.I2C1, p.PB8, // SCL | ||
| 42 | p.PB9, // SDA | ||
| 43 | i2c_config, | ||
| 44 | ); | ||
| 45 | |||
| 46 | // Convert to slave+master mode | ||
| 47 | let slave_config = SlaveAddrConfig::basic(I2C_SLAVE_ADDR); | ||
| 48 | let i2c_slave = i2c_master.into_slave_multimaster(slave_config); | ||
| 49 | |||
| 50 | spawner.spawn(i2c_slave_task(i2c_slave).unwrap()); | ||
| 51 | } | ||
| 52 | |||
| 53 | #[embassy_executor::task] | ||
| 54 | pub async fn i2c_slave_task(mut i2c_slave: I2c<'static, embassy_stm32::mode::Blocking, i2c::mode::MultiMaster>) { | ||
| 55 | info!("Blocking I2C slave ready at address 0x{:02X}", I2C_SLAVE_ADDR); | ||
| 56 | |||
| 57 | loop { | ||
| 58 | match i2c_slave.blocking_listen() { | ||
| 59 | Ok(SlaveCommand { | ||
| 60 | kind: SlaveCommandKind::Write, | ||
| 61 | address, | ||
| 62 | }) => { | ||
| 63 | let addr_val = match address { | ||
| 64 | Address::SevenBit(addr) => addr, | ||
| 65 | Address::TenBit(addr) => (addr & 0xFF) as u8, | ||
| 66 | }; | ||
| 67 | |||
| 68 | info!("I2C: Received write command - Address 0x{:02X}", addr_val); | ||
| 69 | let mut data_buffer = I2C_BUFFER.lock().await; | ||
| 70 | |||
| 71 | match i2c_slave.blocking_respond_to_write(&mut *data_buffer) { | ||
| 72 | Ok(bytes_received) => { | ||
| 73 | info!( | ||
| 74 | "I2C: Received {} bytes - Buffer now contains: 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}, 0x{:02X}", | ||
| 75 | bytes_received, | ||
| 76 | data_buffer[0], | ||
| 77 | data_buffer[1], | ||
| 78 | data_buffer[2], | ||
| 79 | data_buffer[3], | ||
| 80 | data_buffer[4], | ||
| 81 | data_buffer[5], | ||
| 82 | data_buffer[6], | ||
| 83 | data_buffer[7] | ||
| 84 | ); | ||
| 85 | } | ||
| 86 | Err(e) => { | ||
| 87 | error!("I2C: Write error: {}", format_i2c_error(&e)); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | Ok(SlaveCommand { | ||
| 93 | kind: SlaveCommandKind::Read, | ||
| 94 | address, | ||
| 95 | }) => { | ||
| 96 | let addr_val = match address { | ||
| 97 | Address::SevenBit(addr) => addr, | ||
| 98 | Address::TenBit(addr) => (addr & 0xFF) as u8, // Show low byte for 10-bit | ||
| 99 | }; | ||
| 100 | |||
| 101 | info!("I2C: Received read command - Address 0x{:02X}", addr_val); | ||
| 102 | let data_buffer = I2C_BUFFER.lock().await; | ||
| 103 | |||
| 104 | match i2c_slave.blocking_respond_to_read(&data_buffer[..BUFFER_SIZE]) { | ||
| 105 | Ok(bytes_sent) => { | ||
| 106 | info!("I2C: Responded to read - {} bytes sent", bytes_sent); | ||
| 107 | } | ||
| 108 | Err(e) => { | ||
| 109 | error!("I2C: Read error: {}", format_i2c_error(&e)); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | Err(e) => { | ||
| 115 | error!("I2C: Listen error: {}", format_i2c_error(&e)); | ||
| 116 | Timer::after(Duration::from_millis(100)).await; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | fn format_i2c_error(e: &embassy_stm32::i2c::Error) -> &'static str { | ||
| 123 | match e { | ||
| 124 | embassy_stm32::i2c::Error::Bus => "Bus", | ||
| 125 | embassy_stm32::i2c::Error::Arbitration => "Arbitration", | ||
| 126 | embassy_stm32::i2c::Error::Nack => "Nack", | ||
| 127 | embassy_stm32::i2c::Error::Timeout => "Timeout", | ||
| 128 | embassy_stm32::i2c::Error::Crc => "Crc", | ||
| 129 | embassy_stm32::i2c::Error::Overrun => "Overrun", | ||
| 130 | embassy_stm32::i2c::Error::ZeroLengthTransfer => "ZeroLengthTransfer", | ||
| 131 | } | ||
| 132 | } | ||
diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs index feb27f6d9..5ff705ca2 100644 --- a/examples/stm32f4/src/bin/rtc.rs +++ b/examples/stm32f4/src/bin/rtc.rs | |||
| @@ -21,12 +21,12 @@ async fn main(_spawner: Spawner) { | |||
| 21 | .and_hms_opt(10, 30, 15) | 21 | .and_hms_opt(10, 30, 15) |
| 22 | .unwrap(); | 22 | .unwrap(); |
| 23 | 23 | ||
| 24 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 24 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 25 | 25 | ||
| 26 | rtc.set_datetime(now.into()).expect("datetime not set"); | 26 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 27 | 27 | ||
| 28 | loop { | 28 | loop { |
| 29 | let now: NaiveDateTime = rtc.now().unwrap().into(); | 29 | let now: NaiveDateTime = time_provider.now().unwrap().into(); |
| 30 | 30 | ||
| 31 | info!("{}", now.and_utc().timestamp()); | 31 | info!("{}", now.and_utc().timestamp()); |
| 32 | 32 | ||
diff --git a/examples/stm32g0/src/bin/onewire_ds18b20.rs b/examples/stm32g0/src/bin/onewire_ds18b20.rs index 62f8711a6..43ecca8c4 100644 --- a/examples/stm32g0/src/bin/onewire_ds18b20.rs +++ b/examples/stm32g0/src/bin/onewire_ds18b20.rs | |||
| @@ -267,7 +267,7 @@ where | |||
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | match Self::crc8(&data) == 0 { | 269 | match Self::crc8(&data) == 0 { |
| 270 | true => Ok(((data[1] as u16) << 8 | data[0] as u16) as f32 / 16.), | 270 | true => Ok(((data[1] as i16) << 8 | data[0] as i16) as f32 / 16.), |
| 271 | false => Err(()), | 271 | false => Err(()), |
| 272 | } | 272 | } |
| 273 | } | 273 | } |
diff --git a/examples/stm32g0/src/bin/rtc.rs b/examples/stm32g0/src/bin/rtc.rs index 21da204cc..d8b58de22 100644 --- a/examples/stm32g0/src/bin/rtc.rs +++ b/examples/stm32g0/src/bin/rtc.rs | |||
| @@ -17,12 +17,12 @@ async fn main(_spawner: Spawner) { | |||
| 17 | 17 | ||
| 18 | let now = DateTime::from(2023, 6, 14, DayOfWeek::Friday, 15, 59, 10, 0); | 18 | let now = DateTime::from(2023, 6, 14, DayOfWeek::Friday, 15, 59, 10, 0); |
| 19 | 19 | ||
| 20 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 20 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 21 | 21 | ||
| 22 | rtc.set_datetime(now.unwrap()).expect("datetime not set"); | 22 | rtc.set_datetime(now.unwrap()).expect("datetime not set"); |
| 23 | 23 | ||
| 24 | loop { | 24 | loop { |
| 25 | let now: DateTime = rtc.now().unwrap().into(); | 25 | let now: DateTime = time_provider.now().unwrap().into(); |
| 26 | 26 | ||
| 27 | info!("{}:{}:{}", now.hour(), now.minute(), now.second()); | 27 | info!("{}:{}:{}", now.hour(), now.minute(), now.second()); |
| 28 | 28 | ||
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 6fd282d6d..8bbeb594c 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -7,12 +7,12 @@ publish = false | |||
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | # Change stm32g491re to your chip name, if necessary. | 9 | # Change stm32g491re to your chip name, if necessary. |
| 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } | 10 | embassy-stm32 = { path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } |
| 11 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 11 | embassy-sync = { path = "../../embassy-sync", features = ["defmt"] } |
| 12 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 12 | embassy-executor = { path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 13 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 13 | embassy-time = { path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 14 | embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = ["defmt"] } | 14 | embassy-usb = { path = "../../embassy-usb", features = ["defmt"] } |
| 15 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | 15 | embassy-futures = { path = "../../embassy-futures" } |
| 16 | usbd-hid = "0.8.1" | 16 | usbd-hid = "0.8.1" |
| 17 | 17 | ||
| 18 | defmt = "1.0.1" | 18 | defmt = "1.0.1" |
| @@ -25,6 +25,7 @@ embedded-can = { version = "0.4" } | |||
| 25 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | 25 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } |
| 26 | heapless = { version = "0.8", default-features = false } | 26 | heapless = { version = "0.8", default-features = false } |
| 27 | static_cell = "2.0.0" | 27 | static_cell = "2.0.0" |
| 28 | critical-section = "1.1" | ||
| 28 | 29 | ||
| 29 | [profile.release] | 30 | [profile.release] |
| 30 | debug = 2 | 31 | debug = 2 |
diff --git a/examples/stm32g4/src/bin/adc_dma.rs b/examples/stm32g4/src/bin/adc_dma.rs index a82067049..ef8b0c3c2 100644 --- a/examples/stm32g4/src/bin/adc_dma.rs +++ b/examples/stm32g4/src/bin/adc_dma.rs | |||
| @@ -12,7 +12,7 @@ static mut DMA_BUF: [u16; 2] = [0; 2]; | |||
| 12 | 12 | ||
| 13 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 15 | let mut read_buffer = unsafe { &mut DMA_BUF[..] }; | 15 | let read_buffer = unsafe { &mut DMA_BUF[..] }; |
| 16 | 16 | ||
| 17 | let mut config = Config::default(); | 17 | let mut config = Config::default(); |
| 18 | { | 18 | { |
| @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { | |||
| 47 | (&mut pa0, SampleTime::CYCLES247_5), | 47 | (&mut pa0, SampleTime::CYCLES247_5), |
| 48 | ] | 48 | ] |
| 49 | .into_iter(), | 49 | .into_iter(), |
| 50 | &mut read_buffer, | 50 | read_buffer, |
| 51 | ) | 51 | ) |
| 52 | .await; | 52 | .await; |
| 53 | 53 | ||
diff --git a/examples/stm32g4/src/bin/adc_injected_and_regular.rs b/examples/stm32g4/src/bin/adc_injected_and_regular.rs new file mode 100644 index 000000000..3ae2ff064 --- /dev/null +++ b/examples/stm32g4/src/bin/adc_injected_and_regular.rs | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | //! adc injected and regular conversions | ||
| 2 | //! | ||
| 3 | //! This example both regular and injected ADC conversions at the same time | ||
| 4 | //! p:pa0 n:pa2 | ||
| 5 | |||
| 6 | #![no_std] | ||
| 7 | #![no_main] | ||
| 8 | |||
| 9 | use core::cell::RefCell; | ||
| 10 | |||
| 11 | use defmt::info; | ||
| 12 | use embassy_stm32::adc::{ | ||
| 13 | Adc, AdcChannel as _, ConversionTrigger, Exten, InjectedAdc, RegularConversionMode, SampleTime, | ||
| 14 | }; | ||
| 15 | use embassy_stm32::interrupt::typelevel::{ADC1_2, Interrupt}; | ||
| 16 | use embassy_stm32::peripherals::ADC1; | ||
| 17 | use embassy_stm32::time::Hertz; | ||
| 18 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, Mms2}; | ||
| 19 | use embassy_stm32::timer::low_level::CountingMode; | ||
| 20 | use embassy_stm32::{Config, interrupt}; | ||
| 21 | use embassy_sync::blocking_mutex::CriticalSectionMutex; | ||
| 22 | use {defmt_rtt as _, panic_probe as _}; | ||
| 23 | |||
| 24 | static ADC1_HANDLE: CriticalSectionMutex<RefCell<Option<InjectedAdc<ADC1, 1>>>> = | ||
| 25 | CriticalSectionMutex::new(RefCell::new(None)); | ||
| 26 | |||
| 27 | /// This example showcases how to use both regular ADC conversions with DMA and injected ADC | ||
| 28 | /// conversions with ADC interrupt simultaneously. Both conversion types can be configured with | ||
| 29 | /// different triggers and thanks to DMA it is possible to use the measurements in different task | ||
| 30 | /// without needing to access the ADC peripheral. | ||
| 31 | /// | ||
| 32 | /// If you don't need both regular and injected conversions the example code can easily be reworked | ||
| 33 | /// to only include one of the ADC conversion types. | ||
| 34 | #[embassy_executor::main] | ||
| 35 | async fn main(_spawner: embassy_executor::Spawner) { | ||
| 36 | // See Table 166 and 167 in RM0440 Rev 9 for ADC1/2 External triggers | ||
| 37 | // Note: Regular and Injected channels use different tables!! | ||
| 38 | const ADC1_INJECTED_TRIGGER_TIM1_TRGO2: u8 = 8; | ||
| 39 | const ADC1_REGULAR_TRIGGER_TIM1_TRGO2: u8 = 10; | ||
| 40 | |||
| 41 | // --- RCC config --- | ||
| 42 | let mut config = Config::default(); | ||
| 43 | { | ||
| 44 | use embassy_stm32::rcc::*; | ||
| 45 | config.rcc.pll = Some(Pll { | ||
| 46 | source: PllSource::HSI, | ||
| 47 | prediv: PllPreDiv::DIV4, | ||
| 48 | mul: PllMul::MUL85, | ||
| 49 | divp: None, | ||
| 50 | divq: None, | ||
| 51 | divr: Some(PllRDiv::DIV2), | ||
| 52 | }); | ||
| 53 | config.rcc.mux.adc12sel = mux::Adcsel::SYS; | ||
| 54 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 55 | } | ||
| 56 | let p = embassy_stm32::init(config); | ||
| 57 | |||
| 58 | // In this example we use tim1_trgo2 event to trigger the ADC conversions | ||
| 59 | let tim1 = p.TIM1; | ||
| 60 | let pwm_freq = 1; | ||
| 61 | let mut pwm = ComplementaryPwm::new( | ||
| 62 | tim1, | ||
| 63 | None, | ||
| 64 | None, | ||
| 65 | None, | ||
| 66 | None, | ||
| 67 | None, | ||
| 68 | None, | ||
| 69 | None, | ||
| 70 | None, | ||
| 71 | Hertz::hz(pwm_freq), | ||
| 72 | CountingMode::EdgeAlignedUp, | ||
| 73 | ); | ||
| 74 | pwm.set_master_output_enable(false); | ||
| 75 | // Mms2 is used to configure which timer event that is connected to tim1_trgo2. | ||
| 76 | // In this case we use the update event of the timer. | ||
| 77 | pwm.set_mms2(Mms2::UPDATE); | ||
| 78 | |||
| 79 | // Configure regular conversions with DMA | ||
| 80 | let adc1 = Adc::new(p.ADC1); | ||
| 81 | |||
| 82 | let vrefint_channel = adc1.enable_vrefint().degrade_adc(); | ||
| 83 | let pa0 = p.PC1.degrade_adc(); | ||
| 84 | let regular_sequence = [ | ||
| 85 | (vrefint_channel, SampleTime::CYCLES247_5), | ||
| 86 | (pa0, SampleTime::CYCLES247_5), | ||
| 87 | ] | ||
| 88 | .into_iter(); | ||
| 89 | |||
| 90 | // Configurations of Injected ADC measurements | ||
| 91 | let pa2 = p.PA2.degrade_adc(); | ||
| 92 | let injected_sequence = [(pa2, SampleTime::CYCLES247_5)]; | ||
| 93 | |||
| 94 | // Configure DMA for retrieving regular ADC measurements | ||
| 95 | let dma1_ch1 = p.DMA1_CH1; | ||
| 96 | // Using buffer of double size means the half-full interrupts will generate at the expected rate | ||
| 97 | let mut readings = [0u16; 4]; | ||
| 98 | |||
| 99 | let injected_trigger = ConversionTrigger { | ||
| 100 | channel: ADC1_INJECTED_TRIGGER_TIM1_TRGO2, | ||
| 101 | edge: Exten::RISING_EDGE, | ||
| 102 | }; | ||
| 103 | let regular_trigger = ConversionTrigger { | ||
| 104 | channel: ADC1_REGULAR_TRIGGER_TIM1_TRGO2, | ||
| 105 | edge: Exten::RISING_EDGE, | ||
| 106 | }; | ||
| 107 | |||
| 108 | let (mut ring_buffered_adc, injected_adc) = adc1.into_ring_buffered_and_injected( | ||
| 109 | dma1_ch1, | ||
| 110 | &mut readings, | ||
| 111 | regular_sequence, | ||
| 112 | RegularConversionMode::Triggered(regular_trigger), | ||
| 113 | injected_sequence, | ||
| 114 | injected_trigger, | ||
| 115 | true, | ||
| 116 | ); | ||
| 117 | |||
| 118 | // Store ADC globally to allow access from ADC interrupt | ||
| 119 | critical_section::with(|cs| { | ||
| 120 | ADC1_HANDLE.borrow(cs).replace(Some(injected_adc)); | ||
| 121 | }); | ||
| 122 | // Enable interrupt for ADC1_2 | ||
| 123 | unsafe { ADC1_2::enable() }; | ||
| 124 | |||
| 125 | // Main loop for reading regular ADC measurements periodically | ||
| 126 | let mut data = [0u16; 2]; | ||
| 127 | loop { | ||
| 128 | { | ||
| 129 | match ring_buffered_adc.read(&mut data).await { | ||
| 130 | Ok(n) => { | ||
| 131 | defmt::info!("Regular ADC reading, VrefInt: {}, PA0: {}", data[0], data[1]); | ||
| 132 | defmt::info!("Remaining samples: {}", n,); | ||
| 133 | } | ||
| 134 | Err(e) => { | ||
| 135 | defmt::error!("DMA error: {:?}", e); | ||
| 136 | ring_buffered_adc.clear(); | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | /// Use ADC1_2 interrupt to retrieve injected ADC measurements | ||
| 144 | /// Interrupt must be unsafe as hardware can invoke it any-time. Critical sections ensure safety | ||
| 145 | /// within the interrupt. | ||
| 146 | #[interrupt] | ||
| 147 | unsafe fn ADC1_2() { | ||
| 148 | critical_section::with(|cs| { | ||
| 149 | if let Some(injected_adc) = ADC1_HANDLE.borrow(cs).borrow_mut().as_mut() { | ||
| 150 | let injected_data = injected_adc.read_injected_samples(); | ||
| 151 | info!("Injected reading of PA2: {}", injected_data[0]); | ||
| 152 | } | ||
| 153 | }); | ||
| 154 | } | ||
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml index 475ba7e8a..512186c3d 100644 --- a/examples/stm32h5/Cargo.toml +++ b/examples/stm32h5/Cargo.toml | |||
| @@ -29,7 +29,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
| 31 | micromath = "2.0.0" | 31 | micromath = "2.0.0" |
| 32 | stm32-fmc = "0.3.0" | 32 | stm32-fmc = "0.4.0" |
| 33 | embedded-storage = "0.3.1" | 33 | embedded-storage = "0.3.1" |
| 34 | static_cell = "2" | 34 | static_cell = "2" |
| 35 | 35 | ||
diff --git a/examples/stm32h5/src/bin/backup_sram.rs b/examples/stm32h5/src/bin/backup_sram.rs new file mode 100644 index 000000000..f8db1853e --- /dev/null +++ b/examples/stm32h5/src/bin/backup_sram.rs | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::Config; | ||
| 7 | use embassy_stm32::backup_sram::BackupMemory; | ||
| 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 mut config = Config::default(); | ||
| 14 | config.rcc.ls.enable_backup_sram = true; | ||
| 15 | |||
| 16 | let p = embassy_stm32::init(config); | ||
| 17 | info!("Started!"); | ||
| 18 | |||
| 19 | let (bytes, status) = BackupMemory::new(p.BKPSRAM); | ||
| 20 | |||
| 21 | match status { | ||
| 22 | false => info!("BKPSRAM just enabled"), | ||
| 23 | true => info!("BKPSRAM already enabled"), | ||
| 24 | } | ||
| 25 | |||
| 26 | loop { | ||
| 27 | info!("byte0: {}", bytes[0]); | ||
| 28 | bytes[0] = bytes[0].wrapping_add(1); | ||
| 29 | Timer::after_millis(500).await; | ||
| 30 | } | ||
| 31 | } | ||
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs index 3c4f49f64..caebc9daf 100644 --- a/examples/stm32h5/src/bin/stop.rs +++ b/examples/stm32h5/src/bin/stop.rs | |||
| @@ -9,10 +9,8 @@ use embassy_executor::Spawner; | |||
| 9 | use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; | 9 | use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; |
| 10 | use embassy_stm32::low_power::Executor; | 10 | use embassy_stm32::low_power::Executor; |
| 11 | use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; | 11 | use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; |
| 12 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 13 | use embassy_stm32::{Config, Peri}; | 12 | use embassy_stm32::{Config, Peri}; |
| 14 | use embassy_time::Timer; | 13 | use embassy_time::Timer; |
| 15 | use static_cell::StaticCell; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| 17 | 15 | ||
| 18 | #[cortex_m_rt::entry] | 16 | #[cortex_m_rt::entry] |
| @@ -37,12 +35,6 @@ async fn async_main(spawner: Spawner) { | |||
| 37 | // config.enable_debug_during_sleep = false; | 35 | // config.enable_debug_during_sleep = false; |
| 38 | let p = embassy_stm32::init(config); | 36 | let p = embassy_stm32::init(config); |
| 39 | 37 | ||
| 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 | spawner.spawn(unwrap!(blinky(p.PB4.into()))); | 38 | spawner.spawn(unwrap!(blinky(p.PB4.into()))); |
| 47 | spawner.spawn(unwrap!(timeout())); | 39 | spawner.spawn(unwrap!(timeout())); |
| 48 | } | 40 | } |
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index 5993110de..09b734054 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml | |||
| @@ -30,7 +30,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
| 31 | critical-section = "1.1" | 31 | critical-section = "1.1" |
| 32 | micromath = "2.0.0" | 32 | micromath = "2.0.0" |
| 33 | stm32-fmc = "0.3.0" | 33 | stm32-fmc = "0.4.0" |
| 34 | embedded-storage = "0.3.1" | 34 | embedded-storage = "0.3.1" |
| 35 | static_cell = "2" | 35 | static_cell = "2" |
| 36 | chrono = { version = "^0.4", default-features = false } | 36 | chrono = { version = "^0.4", default-features = false } |
diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs index 1bd71637b..965716d23 100644 --- a/examples/stm32h7/src/bin/rtc.rs +++ b/examples/stm32h7/src/bin/rtc.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | .and_hms_opt(10, 30, 15) | 23 | .and_hms_opt(10, 30, 15) |
| 24 | .unwrap(); | 24 | .unwrap(); |
| 25 | 25 | ||
| 26 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 26 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 27 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | 27 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 28 | 28 | ||
| 29 | rtc.set_datetime(now.into()).expect("datetime not set"); | 29 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| @@ -31,6 +31,6 @@ async fn main(_spawner: Spawner) { | |||
| 31 | // In reality the delay would be much longer | 31 | // In reality the delay would be much longer |
| 32 | Timer::after_millis(20000).await; | 32 | Timer::after_millis(20000).await; |
| 33 | 33 | ||
| 34 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 34 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 35 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | 35 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 36 | } | 36 | } |
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index 61f31be24..f7ab20cdd 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs | |||
| @@ -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, Blocking>) { | 18 | async fn main_task(mut spi: spi::Spi<'static, Blocking, spi::mode::Master>) { |
| 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 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); | 21 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); |
diff --git a/examples/stm32h7/src/bin/spi_bdma.rs b/examples/stm32h7/src/bin/spi_bdma.rs index be6a26d82..cd9d6c789 100644 --- a/examples/stm32h7/src/bin/spi_bdma.rs +++ b/examples/stm32h7/src/bin/spi_bdma.rs | |||
| @@ -20,7 +20,7 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 20 | static mut RAM_D3: GroundedArrayCell<u8, 256> = GroundedArrayCell::uninit(); | 20 | static mut RAM_D3: GroundedArrayCell<u8, 256> = GroundedArrayCell::uninit(); |
| 21 | 21 | ||
| 22 | #[embassy_executor::task] | 22 | #[embassy_executor::task] |
| 23 | async fn main_task(mut spi: spi::Spi<'static, Async>) { | 23 | async fn main_task(mut spi: spi::Spi<'static, Async, spi::mode::Master>) { |
| 24 | let (read_buffer, write_buffer) = unsafe { | 24 | let (read_buffer, write_buffer) = unsafe { |
| 25 | let ram = &mut *core::ptr::addr_of_mut!(RAM_D3); | 25 | let ram = &mut *core::ptr::addr_of_mut!(RAM_D3); |
| 26 | ram.initialize_all_copied(0); | 26 | ram.initialize_all_copied(0); |
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 20cb67ba0..3d3c2f43e 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs | |||
| @@ -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, Async>) { | 18 | async fn main_task(mut spi: spi::Spi<'static, Async, spi::mode::Master>) { |
| 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/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml index b5c313523..d69f0228e 100644 --- a/examples/stm32h755cm4/Cargo.toml +++ b/examples/stm32h755cm4/Cargo.toml | |||
| @@ -30,7 +30,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
| 31 | critical-section = "1.1" | 31 | critical-section = "1.1" |
| 32 | micromath = "2.0.0" | 32 | micromath = "2.0.0" |
| 33 | stm32-fmc = "0.3.0" | 33 | stm32-fmc = "0.4.0" |
| 34 | embedded-storage = "0.3.1" | 34 | embedded-storage = "0.3.1" |
| 35 | static_cell = "2" | 35 | static_cell = "2" |
| 36 | chrono = { version = "^0.4", default-features = false } | 36 | chrono = { version = "^0.4", default-features = false } |
diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml index 7a1519aae..f4e1e53b7 100644 --- a/examples/stm32h755cm7/Cargo.toml +++ b/examples/stm32h755cm7/Cargo.toml | |||
| @@ -30,7 +30,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 30 | heapless = { version = "0.8", default-features = false } | 30 | heapless = { version = "0.8", default-features = false } |
| 31 | critical-section = "1.1" | 31 | critical-section = "1.1" |
| 32 | micromath = "2.0.0" | 32 | micromath = "2.0.0" |
| 33 | stm32-fmc = "0.3.0" | 33 | stm32-fmc = "0.4.0" |
| 34 | embedded-storage = "0.3.1" | 34 | embedded-storage = "0.3.1" |
| 35 | static_cell = "2" | 35 | static_cell = "2" |
| 36 | chrono = { version = "^0.4", default-features = false } | 36 | chrono = { version = "^0.4", default-features = false } |
diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml index 4cd7b84e5..0509d394d 100644 --- a/examples/stm32h7b0/Cargo.toml +++ b/examples/stm32h7b0/Cargo.toml | |||
| @@ -29,7 +29,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
| 31 | micromath = "2.0.0" | 31 | micromath = "2.0.0" |
| 32 | stm32-fmc = "0.3.0" | 32 | stm32-fmc = "0.4.0" |
| 33 | embedded-storage = "0.3.1" | 33 | embedded-storage = "0.3.1" |
| 34 | static_cell = "2" | 34 | static_cell = "2" |
| 35 | chrono = { version = "^0.4", default-features = false } | 35 | chrono = { version = "^0.4", default-features = false } |
diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml index 445916972..ab525ad91 100644 --- a/examples/stm32h7rs/Cargo.toml +++ b/examples/stm32h7rs/Cargo.toml | |||
| @@ -29,7 +29,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] } | |||
| 29 | heapless = { version = "0.8", default-features = false } | 29 | heapless = { version = "0.8", default-features = false } |
| 30 | critical-section = "1.1" | 30 | critical-section = "1.1" |
| 31 | micromath = "2.0.0" | 31 | micromath = "2.0.0" |
| 32 | stm32-fmc = "0.3.0" | 32 | stm32-fmc = "0.4.0" |
| 33 | embedded-storage = "0.3.1" | 33 | embedded-storage = "0.3.1" |
| 34 | static_cell = "2" | 34 | static_cell = "2" |
| 35 | chrono = { version = "^0.4", default-features = false } | 35 | chrono = { version = "^0.4", default-features = false } |
diff --git a/examples/stm32h7rs/src/bin/rtc.rs b/examples/stm32h7rs/src/bin/rtc.rs index 1bd71637b..965716d23 100644 --- a/examples/stm32h7rs/src/bin/rtc.rs +++ b/examples/stm32h7rs/src/bin/rtc.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | .and_hms_opt(10, 30, 15) | 23 | .and_hms_opt(10, 30, 15) |
| 24 | .unwrap(); | 24 | .unwrap(); |
| 25 | 25 | ||
| 26 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 26 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 27 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | 27 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 28 | 28 | ||
| 29 | rtc.set_datetime(now.into()).expect("datetime not set"); | 29 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| @@ -31,6 +31,6 @@ async fn main(_spawner: Spawner) { | |||
| 31 | // In reality the delay would be much longer | 31 | // In reality the delay would be much longer |
| 32 | Timer::after_millis(20000).await; | 32 | Timer::after_millis(20000).await; |
| 33 | 33 | ||
| 34 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 34 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 35 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | 35 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 36 | } | 36 | } |
diff --git a/examples/stm32h7rs/src/bin/spi.rs b/examples/stm32h7rs/src/bin/spi.rs index 8c280fdae..3253304eb 100644 --- a/examples/stm32h7rs/src/bin/spi.rs +++ b/examples/stm32h7rs/src/bin/spi.rs | |||
| @@ -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, Blocking>) { | 18 | async fn main_task(mut spi: spi::Spi<'static, Blocking, spi::mode::Master>) { |
| 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 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); | 21 | core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap(); |
diff --git a/examples/stm32h7rs/src/bin/spi_dma.rs b/examples/stm32h7rs/src/bin/spi_dma.rs index 3fa69fd15..ca644c6a8 100644 --- a/examples/stm32h7rs/src/bin/spi_dma.rs +++ b/examples/stm32h7rs/src/bin/spi_dma.rs | |||
| @@ -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, Async>) { | 18 | async fn main_task(mut spi: spi::Spi<'static, Async, spi::mode::Master>) { |
| 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/stm32l4/src/bin/adc_dma.rs b/examples/stm32l4/src/bin/adc_dma.rs new file mode 100644 index 000000000..7a9200edd --- /dev/null +++ b/examples/stm32l4/src/bin/adc_dma.rs | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::Config; | ||
| 7 | use embassy_stm32::adc::{Adc, AdcChannel, SampleTime}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | const DMA_BUF_LEN: usize = 512; | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let mut config = Config::default(); | ||
| 17 | { | ||
| 18 | use embassy_stm32::rcc::*; | ||
| 19 | config.rcc.mux.adcsel = mux::Adcsel::SYS; | ||
| 20 | } | ||
| 21 | let p = embassy_stm32::init(config); | ||
| 22 | |||
| 23 | let mut adc = Adc::new(p.ADC1); | ||
| 24 | let mut adc_pin0 = p.PA0.degrade_adc(); | ||
| 25 | let mut adc_pin1 = p.PA1.degrade_adc(); | ||
| 26 | let mut adc_dma_buf = [0u16; DMA_BUF_LEN]; | ||
| 27 | let mut measurements = [0u16; DMA_BUF_LEN / 2]; | ||
| 28 | let mut ring_buffered_adc = adc.into_ring_buffered( | ||
| 29 | p.DMA1_CH1, | ||
| 30 | &mut adc_dma_buf, | ||
| 31 | [ | ||
| 32 | (&mut adc_pin0, SampleTime::CYCLES640_5), | ||
| 33 | (&mut adc_pin1, SampleTime::CYCLES640_5), | ||
| 34 | ] | ||
| 35 | .into_iter(), | ||
| 36 | ); | ||
| 37 | |||
| 38 | info!("starting measurement loop"); | ||
| 39 | loop { | ||
| 40 | match ring_buffered_adc.read(&mut measurements).await { | ||
| 41 | Ok(_) => { | ||
| 42 | //note: originally there was a print here showing all the samples, | ||
| 43 | //but even that takes too much time and would cause adc overruns | ||
| 44 | info!("adc1 first 10 samples: {}", measurements[0..10]); | ||
| 45 | } | ||
| 46 | Err(e) => { | ||
| 47 | warn!("Error: {:?}", e); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 1d26cd008..8b92075cc 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs | |||
| @@ -39,7 +39,7 @@ async fn main(_spawner: Spawner) { | |||
| 39 | .and_hms_opt(10, 30, 15) | 39 | .and_hms_opt(10, 30, 15) |
| 40 | .unwrap(); | 40 | .unwrap(); |
| 41 | 41 | ||
| 42 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 42 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 43 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | 43 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 44 | 44 | ||
| 45 | rtc.set_datetime(now.into()).expect("datetime not set"); | 45 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| @@ -47,6 +47,6 @@ async fn main(_spawner: Spawner) { | |||
| 47 | // In reality the delay would be much longer | 47 | // In reality the delay would be much longer |
| 48 | Timer::after_millis(20000).await; | 48 | Timer::after_millis(20000).await; |
| 49 | 49 | ||
| 50 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 50 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 51 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | 51 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 52 | } | 52 | } |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 8e54938d1..0dbf515cf 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -28,6 +28,7 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | |||
| 28 | use embassy_stm32::i2c::{self, Config as I2C_Config, I2c}; | 28 | use embassy_stm32::i2c::{self, Config as I2C_Config, I2c}; |
| 29 | use embassy_stm32::mode::Async; | 29 | use embassy_stm32::mode::Async; |
| 30 | use embassy_stm32::rng::{self, Rng}; | 30 | use embassy_stm32::rng::{self, Rng}; |
| 31 | use embassy_stm32::spi::mode::Master; | ||
| 31 | use embassy_stm32::spi::{Config as SPI_Config, Spi}; | 32 | use embassy_stm32::spi::{Config as SPI_Config, Spi}; |
| 32 | use embassy_stm32::time::Hertz; | 33 | use embassy_stm32::time::Hertz; |
| 33 | use embassy_stm32::{bind_interrupts, exti, pac, peripherals}; | 34 | use embassy_stm32::{bind_interrupts, exti, pac, peripherals}; |
| @@ -54,7 +55,7 @@ const IP_ADDRESS: Ipv4Cidr = Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 5), 24) | |||
| 54 | // Listen port for the webserver | 55 | // Listen port for the webserver |
| 55 | const HTTP_LISTEN_PORT: u16 = 80; | 56 | const HTTP_LISTEN_PORT: u16 = 80; |
| 56 | 57 | ||
| 57 | pub type SpeSpi = Spi<'static, Async>; | 58 | pub type SpeSpi = Spi<'static, Async, Master>; |
| 58 | pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; | 59 | pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; |
| 59 | pub type SpeInt = exti::ExtiInput<'static>; | 60 | pub type SpeInt = exti::ExtiInput<'static>; |
| 60 | pub type SpeRst = Output<'static>; | 61 | pub type SpeRst = Output<'static>; |
diff --git a/examples/stm32l5/src/bin/stop.rs b/examples/stm32l5/src/bin/stop.rs index c34053190..3d119f90f 100644 --- a/examples/stm32l5/src/bin/stop.rs +++ b/examples/stm32l5/src/bin/stop.rs | |||
| @@ -6,10 +6,8 @@ use embassy_executor::Spawner; | |||
| 6 | use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; |
| 7 | use embassy_stm32::low_power::Executor; | 7 | use embassy_stm32::low_power::Executor; |
| 8 | use embassy_stm32::rcc::LsConfig; | 8 | use embassy_stm32::rcc::LsConfig; |
| 9 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 10 | use embassy_stm32::{Config, Peri}; | 9 | use embassy_stm32::{Config, Peri}; |
| 11 | use embassy_time::Timer; | 10 | use embassy_time::Timer; |
| 12 | use static_cell::StaticCell; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 12 | ||
| 15 | #[cortex_m_rt::entry] | 13 | #[cortex_m_rt::entry] |
| @@ -28,12 +26,6 @@ async fn async_main(spawner: Spawner) { | |||
| 28 | // config.enable_debug_during_sleep = false; | 26 | // config.enable_debug_during_sleep = false; |
| 29 | let p = embassy_stm32::init(config); | 27 | let p = embassy_stm32::init(config); |
| 30 | 28 | ||
| 31 | // give the RTC to the executor... | ||
| 32 | let rtc = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 33 | static RTC: StaticCell<Rtc> = StaticCell::new(); | ||
| 34 | let rtc = RTC.init(rtc); | ||
| 35 | embassy_stm32::low_power::stop_with_rtc(rtc); | ||
| 36 | |||
| 37 | spawner.spawn(unwrap!(blinky(p.PC7.into()))); | 29 | spawner.spawn(unwrap!(blinky(p.PC7.into()))); |
| 38 | spawner.spawn(unwrap!(timeout())); | 30 | spawner.spawn(unwrap!(timeout())); |
| 39 | } | 31 | } |
diff --git a/examples/stm32u0/src/bin/rtc.rs b/examples/stm32u0/src/bin/rtc.rs index d071cfbc7..56d16ccf7 100644 --- a/examples/stm32u0/src/bin/rtc.rs +++ b/examples/stm32u0/src/bin/rtc.rs | |||
| @@ -36,7 +36,7 @@ async fn main(_spawner: Spawner) { | |||
| 36 | .and_hms_opt(10, 30, 15) | 36 | .and_hms_opt(10, 30, 15) |
| 37 | .unwrap(); | 37 | .unwrap(); |
| 38 | 38 | ||
| 39 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 39 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 40 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | 40 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 41 | 41 | ||
| 42 | rtc.set_datetime(now.into()).expect("datetime not set"); | 42 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| @@ -44,6 +44,6 @@ async fn main(_spawner: Spawner) { | |||
| 44 | // In reality the delay would be much longer | 44 | // In reality the delay would be much longer |
| 45 | Timer::after_millis(20000).await; | 45 | Timer::after_millis(20000).await; |
| 46 | 46 | ||
| 47 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 47 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 48 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | 48 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 49 | } | 49 | } |
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index d3709120f..2185142c9 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs | |||
| @@ -44,7 +44,7 @@ async fn main(_spawner: Spawner) { | |||
| 44 | .and_hms_opt(10, 30, 15) | 44 | .and_hms_opt(10, 30, 15) |
| 45 | .unwrap(); | 45 | .unwrap(); |
| 46 | 46 | ||
| 47 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 47 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); |
| 48 | info!("Got RTC! {:?}", now.and_utc().timestamp()); | 48 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 49 | 49 | ||
| 50 | rtc.set_datetime(now.into()).expect("datetime not set"); | 50 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| @@ -52,6 +52,6 @@ async fn main(_spawner: Spawner) { | |||
| 52 | // In reality the delay would be much longer | 52 | // In reality the delay would be much longer |
| 53 | Timer::after_millis(20000).await; | 53 | Timer::after_millis(20000).await; |
| 54 | 54 | ||
| 55 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 55 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 56 | info!("Got RTC! {:?}", then.and_utc().timestamp()); | 56 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 57 | } | 57 | } |
diff --git a/examples/stm32wle5/.cargo/config.toml b/examples/stm32wle5/.cargo/config.toml new file mode 100644 index 000000000..0178d377c --- /dev/null +++ b/examples/stm32wle5/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --chip STM32WLE5JCIx --connect-under-reset" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "info" | ||
diff --git a/examples/stm32wle5/Cargo.toml b/examples/stm32wle5/Cargo.toml new file mode 100644 index 000000000..f2fc4dd3d --- /dev/null +++ b/examples/stm32wle5/Cargo.toml | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2024" | ||
| 3 | name = "embassy-stm32wl-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | publish = false | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | # Change stm32wl55jc-cm4 to your chip name, if necessary. | ||
| 10 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = ["defmt", "stm32wle5jc", "time-driver-any", "memory-x", "unstable-pac", "exti", "low-power"] } | ||
| 11 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | ||
| 12 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | ||
| 13 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-1_000"] } | ||
| 14 | embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal" } | ||
| 15 | |||
| 16 | defmt = "1.0.1" | ||
| 17 | defmt-rtt = { version = "1.1.0", optional = true } | ||
| 18 | defmt-serial = { version = "0.10.0", optional = true } | ||
| 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 = "1.0.0" | ||
| 23 | embedded-storage = "0.3.1" | ||
| 24 | panic-probe = { version = "1.0.0", features = ["print-defmt"] } | ||
| 25 | static_cell = { version = "2.1.1", default-features = false } | ||
| 26 | |||
| 27 | [profile.release] | ||
| 28 | debug = 2 | ||
| 29 | |||
| 30 | [package.metadata.embassy] | ||
| 31 | build = [ | ||
| 32 | { target = "thumbv7em-none-eabi", artifact-dir = "out/examples/stm32wl" } | ||
| 33 | ] | ||
| 34 | |||
| 35 | [features] | ||
| 36 | default = ["defmt-serial"] | ||
| 37 | defmt-rtt = ["dep:defmt-rtt"] | ||
| 38 | defmt-serial = ["dep:defmt-serial"] | ||
diff --git a/examples/stm32wle5/README.md b/examples/stm32wle5/README.md new file mode 100644 index 000000000..18c3b5071 --- /dev/null +++ b/examples/stm32wle5/README.md | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | # Low Power Examples for STM32WLEx family | ||
| 2 | |||
| 3 | Examples in this repo should work with [LoRa-E5 Dev Board](https://www.st.com/en/partner-products-and-services/lora-e5-development-kit.html) board. | ||
| 4 | |||
| 5 | ## Prerequsits | ||
| 6 | |||
| 7 | - Connect a usb serial adapter to LPUart1 (this is where ALL logging will go) | ||
| 8 | - Optional: Connect an amp meter that ran measure down to 0.1uA to the power test pins | ||
| 9 | - `cargo install defmt-print` so you can print log messahes from LPUart1 | ||
| 10 | |||
| 11 | ## Example Notes | ||
| 12 | |||
| 13 | All examples will set all pins to analog mode before configuring pins for the example, if any. This saves about 500uA!!!! | ||
| 14 | |||
| 15 | - the `adc` example will sleep in STOP1 betwen samples and the chip will only draw about 13uA while sleeping | ||
| 16 | - the `blinky` example will sleep in STOP2 and the chip will only draw 1uA or less while sleeping | ||
| 17 | - the `button_exti` example will sleep in STOP2 and the chip will only draw 1uA or less while sleeping | ||
| 18 | - the `i2c` examples will sleep in STOP1 between reads and the chip only draw about 10uA while sleeping | ||
| 19 | |||
| 20 | For each example you will need to start `defmt-print` with the example binary and the correct serial port in a seperate terminal. Example: | ||
| 21 | ``` | ||
| 22 | defmt-print -w -v -e target/thumbv7em-none-eabi/debug/<module-name> serial --path /dev/cu.usbserial-00000000 --baud 115200 | ||
| 23 | ``` | ||
| 24 | |||
| 25 | Run individual examples with | ||
| 26 | ``` | ||
| 27 | cargo flash --chip STM32WLE5JCIx --connect-under-reset --bin <module-name> | ||
| 28 | ``` | ||
| 29 | for example | ||
| 30 | ``` | ||
| 31 | cargo flash --chip STM32WLE5JCIx --connect-under-reset --bin blinky | ||
| 32 | ``` | ||
| 33 | |||
| 34 | You can also run them with with `run`. However in this case expect probe-rs to be disconnected as soon as flashing is done as all IO pins are set to analog input! | ||
| 35 | ``` | ||
| 36 | cargo run --bin blinky | ||
| 37 | ``` | ||
| 38 | |||
| 39 | ## Checklist before running examples | ||
| 40 | You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using. | ||
| 41 | |||
| 42 | * [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L432KCU6 it should be `probe-rs run --chip STM32L432KCUx`. (use `probe-rs chip list` to find your chip) | ||
| 43 | * [ ] Update Cargo.toml to have the correct `embassy-stm32` feature. For example for L432KCU6 it should be `stm32l432kc`. Look in the `Cargo.toml` file of the `embassy-stm32` project to find the correct feature flag for your chip. | ||
| 44 | * [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately. | ||
| 45 | * [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic | ||
| 46 | |||
| 47 | If you are unsure, please drop by the Embassy Matrix chat for support, and let us know: | ||
| 48 | |||
| 49 | * Which example you are trying to run | ||
| 50 | * Which chip and board you are using | ||
| 51 | |||
| 52 | Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org | ||
diff --git a/examples/stm32wle5/build.rs b/examples/stm32wle5/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32wle5/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/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs new file mode 100644 index 000000000..8b830a1e6 --- /dev/null +++ b/examples/stm32wle5/src/bin/adc.rs | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | #[cfg(feature = "defmt-rtt")] | ||
| 6 | use defmt_rtt as _; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_stm32::adc::{Adc, SampleTime}; | ||
| 9 | use embassy_stm32::low_power::Executor; | ||
| 10 | use embassy_time::Timer; | ||
| 11 | use panic_probe as _; | ||
| 12 | use static_cell::StaticCell; | ||
| 13 | |||
| 14 | #[cortex_m_rt::entry] | ||
| 15 | fn main() -> ! { | ||
| 16 | info!("main: Starting!"); | ||
| 17 | Executor::take().run(|spawner| { | ||
| 18 | spawner.spawn(unwrap!(async_main(spawner))); | ||
| 19 | }); | ||
| 20 | } | ||
| 21 | |||
| 22 | #[embassy_executor::task] | ||
| 23 | async fn async_main(_spawner: Spawner) { | ||
| 24 | let mut config = embassy_stm32::Config::default(); | ||
| 25 | // enable HSI clock | ||
| 26 | config.rcc.hsi = true; | ||
| 27 | // enable LSI clock for RTC | ||
| 28 | config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi(); | ||
| 29 | config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M); | ||
| 30 | config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI; | ||
| 31 | // enable ADC with HSI clock | ||
| 32 | config.rcc.mux.adcsel = embassy_stm32::pac::rcc::vals::Adcsel::HSI; | ||
| 33 | #[cfg(feature = "defmt-serial")] | ||
| 34 | { | ||
| 35 | // disable debug during sleep to reduce power consumption since we are | ||
| 36 | // using defmt-serial on LPUART1. | ||
| 37 | config.enable_debug_during_sleep = false; | ||
| 38 | // if we are using defmt-serial on LPUART1, we need to use HSI for the clock | ||
| 39 | // so that its registers are preserved during STOP modes. | ||
| 40 | config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI; | ||
| 41 | } | ||
| 42 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | ||
| 43 | let p = embassy_stm32::init(config); | ||
| 44 | |||
| 45 | // start with all GPIOs as analog to reduce power consumption | ||
| 46 | for r in [ | ||
| 47 | embassy_stm32::pac::GPIOA, | ||
| 48 | embassy_stm32::pac::GPIOB, | ||
| 49 | embassy_stm32::pac::GPIOC, | ||
| 50 | embassy_stm32::pac::GPIOH, | ||
| 51 | ] { | ||
| 52 | r.moder().modify(|w| { | ||
| 53 | for i in 0..16 { | ||
| 54 | // don't reset these if probe-rs should stay connected! | ||
| 55 | #[cfg(feature = "defmt-rtt")] | ||
| 56 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 57 | continue; | ||
| 58 | } | ||
| 59 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 60 | } | ||
| 61 | }); | ||
| 62 | } | ||
| 63 | #[cfg(feature = "defmt-serial")] | ||
| 64 | { | ||
| 65 | use embassy_stm32::mode::Blocking; | ||
| 66 | use embassy_stm32::usart::Uart; | ||
| 67 | let config = embassy_stm32::usart::Config::default(); | ||
| 68 | let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!"); | ||
| 69 | static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new(); | ||
| 70 | defmt_serial::defmt_serial(SERIAL.init(uart)); | ||
| 71 | } | ||
| 72 | |||
| 73 | info!("Hello World!"); | ||
| 74 | |||
| 75 | let mut adc = Adc::new(p.ADC1); | ||
| 76 | adc.set_sample_time(SampleTime::CYCLES79_5); | ||
| 77 | let mut pin = p.PA10; | ||
| 78 | |||
| 79 | let mut vrefint = adc.enable_vrefint(); | ||
| 80 | let vrefint_sample = adc.blocking_read(&mut vrefint); | ||
| 81 | let convert_to_millivolts = |sample| { | ||
| 82 | // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf | ||
| 83 | // 6.3.3 Embedded internal reference voltage | ||
| 84 | const VREFINT_MV: u32 = 1212; // mV | ||
| 85 | |||
| 86 | (u32::from(sample) * VREFINT_MV / u32::from(vrefint_sample)) as u16 | ||
| 87 | }; | ||
| 88 | |||
| 89 | loop { | ||
| 90 | let v = adc.blocking_read(&mut pin); | ||
| 91 | info!("--> {} - {} mV", v, convert_to_millivolts(v)); | ||
| 92 | Timer::after_secs(1).await; | ||
| 93 | } | ||
| 94 | } | ||
diff --git a/examples/stm32wle5/src/bin/blinky.rs b/examples/stm32wle5/src/bin/blinky.rs new file mode 100644 index 000000000..b2745fdaf --- /dev/null +++ b/examples/stm32wle5/src/bin/blinky.rs | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | #[cfg(feature = "defmt-rtt")] | ||
| 6 | use defmt_rtt as _; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 9 | use embassy_stm32::low_power::Executor; | ||
| 10 | use embassy_time::Timer; | ||
| 11 | use panic_probe as _; | ||
| 12 | use static_cell::StaticCell; | ||
| 13 | |||
| 14 | #[cortex_m_rt::entry] | ||
| 15 | fn main() -> ! { | ||
| 16 | info!("main: Starting!"); | ||
| 17 | Executor::take().run(|spawner| { | ||
| 18 | spawner.spawn(unwrap!(async_main(spawner))); | ||
| 19 | }); | ||
| 20 | } | ||
| 21 | |||
| 22 | #[embassy_executor::task] | ||
| 23 | async fn async_main(_spawner: Spawner) { | ||
| 24 | let mut config = embassy_stm32::Config::default(); | ||
| 25 | // enable HSI clock | ||
| 26 | config.rcc.hsi = true; | ||
| 27 | // enable LSI clock for RTC | ||
| 28 | config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi(); | ||
| 29 | config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M); | ||
| 30 | config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI; | ||
| 31 | #[cfg(feature = "defmt-serial")] | ||
| 32 | { | ||
| 33 | // disable debug during sleep to reduce power consumption since we are | ||
| 34 | // using defmt-serial on LPUART1. | ||
| 35 | config.enable_debug_during_sleep = false; | ||
| 36 | // if we are using defmt-serial on LPUART1, we need to use HSI for the clock | ||
| 37 | // so that its registers are preserved during STOP modes. | ||
| 38 | config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI; | ||
| 39 | } | ||
| 40 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | ||
| 41 | let p = embassy_stm32::init(config); | ||
| 42 | |||
| 43 | // start with all GPIOs as analog to reduce power consumption | ||
| 44 | for r in [ | ||
| 45 | embassy_stm32::pac::GPIOA, | ||
| 46 | embassy_stm32::pac::GPIOB, | ||
| 47 | embassy_stm32::pac::GPIOC, | ||
| 48 | embassy_stm32::pac::GPIOH, | ||
| 49 | ] { | ||
| 50 | r.moder().modify(|w| { | ||
| 51 | for i in 0..16 { | ||
| 52 | // don't reset these if probe-rs should stay connected! | ||
| 53 | #[cfg(feature = "defmt-rtt")] | ||
| 54 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 55 | continue; | ||
| 56 | } | ||
| 57 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 58 | } | ||
| 59 | }); | ||
| 60 | } | ||
| 61 | #[cfg(feature = "defmt-serial")] | ||
| 62 | { | ||
| 63 | use embassy_stm32::mode::Blocking; | ||
| 64 | use embassy_stm32::usart::Uart; | ||
| 65 | let config = embassy_stm32::usart::Config::default(); | ||
| 66 | let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!"); | ||
| 67 | static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new(); | ||
| 68 | defmt_serial::defmt_serial(SERIAL.init(uart)); | ||
| 69 | } | ||
| 70 | |||
| 71 | info!("Hello World!"); | ||
| 72 | |||
| 73 | let mut led = Output::new(p.PB5, Level::High, Speed::Low); | ||
| 74 | |||
| 75 | loop { | ||
| 76 | info!("low"); | ||
| 77 | led.set_low(); | ||
| 78 | Timer::after_millis(500).await; | ||
| 79 | |||
| 80 | info!("high"); | ||
| 81 | led.set_high(); | ||
| 82 | Timer::after_millis(500).await; | ||
| 83 | } | ||
| 84 | } | ||
diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs new file mode 100644 index 000000000..db1bff0be --- /dev/null +++ b/examples/stm32wle5/src/bin/button_exti.rs | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | #[cfg(feature = "defmt-rtt")] | ||
| 6 | use defmt_rtt as _; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_stm32::exti::ExtiInput; | ||
| 9 | use embassy_stm32::gpio::Pull; | ||
| 10 | use embassy_stm32::low_power::Executor; | ||
| 11 | use panic_probe as _; | ||
| 12 | use static_cell::StaticCell; | ||
| 13 | |||
| 14 | #[cortex_m_rt::entry] | ||
| 15 | fn main() -> ! { | ||
| 16 | info!("main: Starting!"); | ||
| 17 | Executor::take().run(|spawner| { | ||
| 18 | spawner.spawn(unwrap!(async_main(spawner))); | ||
| 19 | }); | ||
| 20 | } | ||
| 21 | |||
| 22 | #[embassy_executor::task] | ||
| 23 | async fn async_main(_spawner: Spawner) { | ||
| 24 | let mut config = embassy_stm32::Config::default(); | ||
| 25 | // enable HSI clock | ||
| 26 | config.rcc.hsi = true; | ||
| 27 | // enable LSI clock for RTC | ||
| 28 | config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi(); | ||
| 29 | config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M); | ||
| 30 | config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI; | ||
| 31 | // enable ADC with HSI clock | ||
| 32 | config.rcc.mux.adcsel = embassy_stm32::pac::rcc::vals::Adcsel::HSI; | ||
| 33 | #[cfg(feature = "defmt-serial")] | ||
| 34 | { | ||
| 35 | // disable debug during sleep to reduce power consumption since we are | ||
| 36 | // using defmt-serial on LPUART1. | ||
| 37 | config.enable_debug_during_sleep = false; | ||
| 38 | // if we are using defmt-serial on LPUART1, we need to use HSI for the clock | ||
| 39 | // so that its registers are preserved during STOP modes. | ||
| 40 | config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI; | ||
| 41 | } | ||
| 42 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | ||
| 43 | let p = embassy_stm32::init(config); | ||
| 44 | |||
| 45 | // start with all GPIOs as analog to reduce power consumption | ||
| 46 | for r in [ | ||
| 47 | embassy_stm32::pac::GPIOA, | ||
| 48 | embassy_stm32::pac::GPIOB, | ||
| 49 | embassy_stm32::pac::GPIOC, | ||
| 50 | embassy_stm32::pac::GPIOH, | ||
| 51 | ] { | ||
| 52 | r.moder().modify(|w| { | ||
| 53 | for i in 0..16 { | ||
| 54 | // don't reset these if probe-rs should stay connected! | ||
| 55 | #[cfg(feature = "defmt-rtt")] | ||
| 56 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 57 | continue; | ||
| 58 | } | ||
| 59 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 60 | } | ||
| 61 | }); | ||
| 62 | } | ||
| 63 | #[cfg(feature = "defmt-serial")] | ||
| 64 | { | ||
| 65 | use embassy_stm32::mode::Blocking; | ||
| 66 | use embassy_stm32::usart::Uart; | ||
| 67 | let config = embassy_stm32::usart::Config::default(); | ||
| 68 | let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!"); | ||
| 69 | static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new(); | ||
| 70 | defmt_serial::defmt_serial(SERIAL.init(uart)); | ||
| 71 | } | ||
| 72 | |||
| 73 | info!("Hello World!"); | ||
| 74 | |||
| 75 | let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); | ||
| 76 | |||
| 77 | info!("Press the USER button..."); | ||
| 78 | |||
| 79 | loop { | ||
| 80 | button.wait_for_falling_edge().await; | ||
| 81 | info!("Pressed!"); | ||
| 82 | button.wait_for_rising_edge().await; | ||
| 83 | info!("Released!"); | ||
| 84 | } | ||
| 85 | } | ||
diff --git a/examples/stm32wle5/src/bin/i2c.rs b/examples/stm32wle5/src/bin/i2c.rs new file mode 100644 index 000000000..c31c673c9 --- /dev/null +++ b/examples/stm32wle5/src/bin/i2c.rs | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | #[cfg(feature = "defmt-rtt")] | ||
| 6 | use defmt_rtt as _; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_stm32::i2c::I2c; | ||
| 9 | use embassy_stm32::low_power::Executor; | ||
| 10 | use embassy_stm32::time::Hertz; | ||
| 11 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 12 | use embassy_time::{Duration, Timer}; | ||
| 13 | use panic_probe as _; | ||
| 14 | use static_cell::StaticCell; | ||
| 15 | |||
| 16 | bind_interrupts!(struct IrqsI2C{ | ||
| 17 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 18 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 19 | }); | ||
| 20 | |||
| 21 | #[cortex_m_rt::entry] | ||
| 22 | fn main() -> ! { | ||
| 23 | info!("main: Starting!"); | ||
| 24 | Executor::take().run(|spawner| { | ||
| 25 | spawner.spawn(unwrap!(async_main(spawner))); | ||
| 26 | }); | ||
| 27 | } | ||
| 28 | |||
| 29 | #[embassy_executor::task] | ||
| 30 | async fn async_main(_spawner: Spawner) { | ||
| 31 | let mut config = embassy_stm32::Config::default(); | ||
| 32 | // enable HSI clock | ||
| 33 | config.rcc.hsi = true; | ||
| 34 | // enable LSI clock for RTC | ||
| 35 | config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi(); | ||
| 36 | config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M); | ||
| 37 | config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI; | ||
| 38 | // enable ADC with HSI clock | ||
| 39 | config.rcc.mux.i2c2sel = embassy_stm32::pac::rcc::vals::I2c2sel::HSI; | ||
| 40 | #[cfg(feature = "defmt-serial")] | ||
| 41 | { | ||
| 42 | // disable debug during sleep to reduce power consumption since we are | ||
| 43 | // using defmt-serial on LPUART1. | ||
| 44 | config.enable_debug_during_sleep = false; | ||
| 45 | // if we are using defmt-serial on LPUART1, we need to use HSI for the clock | ||
| 46 | // so that its registers are preserved during STOP modes. | ||
| 47 | config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI; | ||
| 48 | } | ||
| 49 | // Initialize STM32WL peripherals (use default config like wio-e5-async example) | ||
| 50 | let p = embassy_stm32::init(config); | ||
| 51 | |||
| 52 | // start with all GPIOs as analog to reduce power consumption | ||
| 53 | for r in [ | ||
| 54 | embassy_stm32::pac::GPIOA, | ||
| 55 | embassy_stm32::pac::GPIOB, | ||
| 56 | embassy_stm32::pac::GPIOC, | ||
| 57 | embassy_stm32::pac::GPIOH, | ||
| 58 | ] { | ||
| 59 | r.moder().modify(|w| { | ||
| 60 | for i in 0..16 { | ||
| 61 | // don't reset these if probe-rs should stay connected! | ||
| 62 | #[cfg(feature = "defmt-rtt")] | ||
| 63 | if config.enable_debug_during_sleep && r == embassy_stm32::pac::GPIOA && [13, 14].contains(&i) { | ||
| 64 | continue; | ||
| 65 | } | ||
| 66 | w.set_moder(i, embassy_stm32::pac::gpio::vals::Moder::ANALOG); | ||
| 67 | } | ||
| 68 | }); | ||
| 69 | } | ||
| 70 | #[cfg(feature = "defmt-serial")] | ||
| 71 | { | ||
| 72 | use embassy_stm32::mode::Blocking; | ||
| 73 | use embassy_stm32::usart::Uart; | ||
| 74 | let config = embassy_stm32::usart::Config::default(); | ||
| 75 | let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!"); | ||
| 76 | static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new(); | ||
| 77 | defmt_serial::defmt_serial(SERIAL.init(uart)); | ||
| 78 | } | ||
| 79 | |||
| 80 | info!("Hello World!"); | ||
| 81 | let en3v3 = embassy_stm32::gpio::Output::new( | ||
| 82 | p.PA9, | ||
| 83 | embassy_stm32::gpio::Level::High, | ||
| 84 | embassy_stm32::gpio::Speed::High, | ||
| 85 | ); | ||
| 86 | core::mem::forget(en3v3); // keep the output pin enabled | ||
| 87 | |||
| 88 | let mut i2c = I2c::new(p.I2C2, p.PB15, p.PA15, IrqsI2C, p.DMA1_CH6, p.DMA1_CH7, { | ||
| 89 | let mut config = i2c::Config::default(); | ||
| 90 | config.frequency = Hertz::khz(100); | ||
| 91 | config.timeout = Duration::from_millis(500); | ||
| 92 | config | ||
| 93 | }); | ||
| 94 | |||
| 95 | loop { | ||
| 96 | let mut buffer = [0; 2]; | ||
| 97 | // read the temperature register of the onboard lm75 | ||
| 98 | match i2c.read(0x48, &mut buffer).await { | ||
| 99 | Ok(_) => info!("--> {:?}", buffer), | ||
| 100 | Err(e) => info!("--> Error: {:?}", e), | ||
| 101 | } | ||
| 102 | Timer::after_secs(5).await; | ||
| 103 | } | ||
| 104 | } | ||
diff --git a/examples/stm32wle5/stm32wle5.code-workspace b/examples/stm32wle5/stm32wle5.code-workspace new file mode 100644 index 000000000..a7c4a0ebd --- /dev/null +++ b/examples/stm32wle5/stm32wle5.code-workspace | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | { | ||
| 2 | "folders": [ | ||
| 3 | { | ||
| 4 | "path": "." | ||
| 5 | } | ||
| 6 | ], | ||
| 7 | "settings": { | ||
| 8 | "rust-analyzer.cargo.target": "thumbv7em-none-eabi", | ||
| 9 | "rust-analyzer.cargo.allTargets": false, | ||
| 10 | "rust-analyzer.cargo.targetDir": "target/rust-analyzer", | ||
| 11 | "rust-analyzer.checkOnSave": true, | ||
| 12 | } | ||
| 13 | } | ||
diff --git a/tests/nrf/.cargo/config.toml b/tests/nrf/.cargo/config.toml index 8f9bccbc0..0192c10ae 100644 --- a/tests/nrf/.cargo/config.toml +++ b/tests/nrf/.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 | #runner = "teleprobe local run --chip nRF52840_xxAA --elf" | 2 | runner = "teleprobe local run --chip nRF52840_xxAA --elf" |
| 3 | runner = "teleprobe client run" | 3 | #runner = "teleprobe client run" |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | #target = "thumbv6m-none-eabi" | 6 | #target = "thumbv6m-none-eabi" |
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 24ddd06f3..6d862e19d 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs | |||
| @@ -55,14 +55,14 @@ async fn main(_spawner: Spawner) { | |||
| 55 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | 55 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 56 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); | 56 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); |
| 57 | let spam_peri = pac::UARTE1; | 57 | let spam_peri = pac::UARTE1; |
| 58 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_endtx().as_ptr())) }; | 58 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_dma().tx().end().as_ptr())) }; |
| 59 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_starttx().as_ptr())) }; | 59 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_dma().tx().start().as_ptr())) }; |
| 60 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); | 60 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); |
| 61 | spam_ppi.enable(); | 61 | spam_ppi.enable(); |
| 62 | let p = (&raw mut TX_BUF) as *mut u8; | 62 | let p = (&raw mut TX_BUF) as *mut u8; |
| 63 | spam_peri.txd().ptr().write_value(p as u32); | 63 | spam_peri.dma().tx().ptr().write_value(p as u32); |
| 64 | spam_peri.txd().maxcnt().write(|w| w.set_maxcnt(NSPAM as _)); | 64 | spam_peri.dma().tx().maxcnt().write(|w| w.set_maxcnt(NSPAM as _)); |
| 65 | spam_peri.tasks_starttx().write_value(1); | 65 | spam_peri.tasks_dma().tx().start().write_value(1); |
| 66 | 66 | ||
| 67 | let mut i = 0; | 67 | let mut i = 0; |
| 68 | let mut total = 0; | 68 | let mut total = 0; |
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs index 091a70ce9..ac082dbb8 100644 --- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs +++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs | |||
| @@ -29,8 +29,7 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | |||
| 29 | async fn wifi_task( | 29 | async fn wifi_task( |
| 30 | runner: hosted::Runner< | 30 | runner: hosted::Runner< |
| 31 | 'static, | 31 | 'static, |
| 32 | ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, | 32 | hosted::SpiInterface<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Input<'static>>, |
| 33 | Input<'static>, | ||
| 34 | Output<'static>, | 33 | Output<'static>, |
| 35 | >, | 34 | >, |
| 36 | ) -> ! { | 35 | ) -> ! { |
| @@ -64,15 +63,11 @@ async fn main(spawner: Spawner) { | |||
| 64 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); | 63 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); |
| 65 | let spi = ExclusiveDevice::new(spi, cs, Delay); | 64 | let spi = ExclusiveDevice::new(spi, cs, Delay); |
| 66 | 65 | ||
| 66 | let iface = hosted::SpiInterface::new(spi, handshake, ready); | ||
| 67 | |||
| 67 | static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); | 68 | static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); |
| 68 | let (device, mut control, runner) = embassy_net_esp_hosted::new( | 69 | let (device, mut control, runner) = |
| 69 | STATE.init(embassy_net_esp_hosted::State::new()), | 70 | embassy_net_esp_hosted::new(STATE.init(embassy_net_esp_hosted::State::new()), iface, reset).await; |
| 70 | spi, | ||
| 71 | handshake, | ||
| 72 | ready, | ||
| 73 | reset, | ||
| 74 | ) | ||
| 75 | .await; | ||
| 76 | 71 | ||
| 77 | spawner.spawn(unwrap!(wifi_task(runner))); | 72 | spawner.spawn(unwrap!(wifi_task(runner))); |
| 78 | 73 | ||
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 1161e827b..b92b47be2 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -73,7 +73,7 @@ teleprobe-meta = "1" | |||
| 73 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 73 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 74 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } | 74 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] } |
| 75 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } | 75 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } |
| 76 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } | 76 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any", "_allow-disable-rtc"] } |
| 77 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | 77 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 78 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } | 78 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } |
| 79 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 79 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| @@ -94,6 +94,7 @@ rand_core = { version = "0.9.1", default-features = false } | |||
| 94 | rand_chacha = { version = "0.9.0", default-features = false } | 94 | rand_chacha = { version = "0.9.0", default-features = false } |
| 95 | static_cell = "2" | 95 | static_cell = "2" |
| 96 | portable-atomic = { version = "1.5", features = [] } | 96 | portable-atomic = { version = "1.5", features = [] } |
| 97 | critical-section = "1.1" | ||
| 97 | 98 | ||
| 98 | chrono = { version = "^0.4", default-features = false, optional = true} | 99 | chrono = { version = "^0.4", default-features = false, optional = true} |
| 99 | sha2 = { version = "0.10.8", default-features = false } | 100 | sha2 = { version = "0.10.8", default-features = false } |
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index 5fe98d807..eb27af4ca 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs | |||
| @@ -10,13 +10,19 @@ use common::*; | |||
| 10 | use defmt::assert; | 10 | use defmt::assert; |
| 11 | use embassy_executor::Spawner; | 11 | use embassy_executor::Spawner; |
| 12 | use embassy_stm32::rcc::LsConfig; | 12 | use embassy_stm32::rcc::LsConfig; |
| 13 | #[cfg(feature = "stop")] | ||
| 14 | use embassy_stm32::rtc::Rtc; | ||
| 15 | #[cfg(not(feature = "stop"))] | ||
| 13 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 16 | use embassy_stm32::rtc::{Rtc, RtcConfig}; |
| 14 | use embassy_time::Timer; | 17 | use embassy_time::Timer; |
| 15 | |||
| 16 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 18 | let mut config = config(); | 20 | let mut config = config(); |
| 19 | config.rcc.ls = LsConfig::default_lse(); | 21 | config.rcc.ls = LsConfig::default_lse(); |
| 22 | #[cfg(feature = "stop")] | ||
| 23 | { | ||
| 24 | config.rtc._disable_rtc = false; | ||
| 25 | } | ||
| 20 | 26 | ||
| 21 | let p = init_with_config(config); | 27 | let p = init_with_config(config); |
| 22 | info!("Hello World!"); | 28 | info!("Hello World!"); |
| @@ -26,14 +32,25 @@ async fn main(_spawner: Spawner) { | |||
| 26 | .and_hms_opt(10, 30, 15) | 32 | .and_hms_opt(10, 30, 15) |
| 27 | .unwrap(); | 33 | .unwrap(); |
| 28 | 34 | ||
| 29 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 35 | #[cfg(not(feature = "stop"))] |
| 36 | let (mut rtc, time_provider) = Rtc::new(p.RTC, RtcConfig::default()); | ||
| 37 | |||
| 38 | #[cfg(feature = "stop")] | ||
| 39 | let (rtc, time_provider) = Rtc::new(p.RTC); | ||
| 30 | 40 | ||
| 41 | #[cfg(not(feature = "stop"))] | ||
| 31 | rtc.set_datetime(now.into()).expect("datetime not set"); | 42 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 32 | 43 | ||
| 44 | #[cfg(feature = "stop")] | ||
| 45 | critical_section::with(|cs| { | ||
| 46 | rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); | ||
| 47 | }); | ||
| 48 | |||
| 33 | info!("Waiting 5 seconds"); | 49 | info!("Waiting 5 seconds"); |
| 34 | Timer::after_millis(5000).await; | 50 | Timer::after_millis(5000).await; |
| 35 | 51 | ||
| 36 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 52 | let then: NaiveDateTime = time_provider.now().unwrap().into(); |
| 53 | |||
| 37 | let seconds = (then - now).num_seconds(); | 54 | let seconds = (then - now).num_seconds(); |
| 38 | 55 | ||
| 39 | info!("measured = {}", seconds); | 56 | info!("measured = {}", seconds); |
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs index e8310866a..cedff772c 100644 --- a/tests/stm32/src/bin/spi.rs +++ b/tests/stm32/src/bin/spi.rs | |||
| @@ -8,6 +8,7 @@ use defmt::assert_eq; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::gpio::{Level, Output, Speed}; | 9 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 10 | use embassy_stm32::mode::Blocking; | 10 | use embassy_stm32::mode::Blocking; |
| 11 | use embassy_stm32::spi::mode::Master; | ||
| 11 | use embassy_stm32::spi::{self, Spi, Word}; | 12 | use embassy_stm32::spi::{self, Spi, Word}; |
| 12 | use embassy_stm32::time::Hertz; | 13 | use embassy_stm32::time::Hertz; |
| 13 | 14 | ||
| @@ -65,7 +66,7 @@ async fn main(_spawner: Spawner) { | |||
| 65 | cortex_m::asm::bkpt(); | 66 | cortex_m::asm::bkpt(); |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>) | 69 | fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>) |
| 69 | where | 70 | where |
| 70 | W: core::ops::Not<Output = W>, | 71 | W: core::ops::Not<Output = W>, |
| 71 | { | 72 | { |
| @@ -109,7 +110,7 @@ where | |||
| 109 | spi.blocking_write::<u8>(&[]).unwrap(); | 110 | spi.blocking_write::<u8>(&[]).unwrap(); |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>, mosi_out: &mut Output<'_>) | 113 | fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>, mosi_out: &mut Output<'_>) |
| 113 | where | 114 | where |
| 114 | W: core::ops::Not<Output = W>, | 115 | W: core::ops::Not<Output = W>, |
| 115 | { | 116 | { |
| @@ -125,7 +126,7 @@ where | |||
| 125 | spi.blocking_read::<u8>(&mut []).unwrap(); | 126 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 126 | } | 127 | } |
| 127 | 128 | ||
| 128 | fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking>) | 129 | fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Blocking, Master>) |
| 129 | where | 130 | where |
| 130 | W: core::ops::Not<Output = W>, | 131 | W: core::ops::Not<Output = W>, |
| 131 | { | 132 | { |
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs index b4fdb8faa..c8cd92401 100644 --- a/tests/stm32/src/bin/spi_dma.rs +++ b/tests/stm32/src/bin/spi_dma.rs | |||
| @@ -8,6 +8,7 @@ use defmt::assert_eq; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::gpio::{Level, Output, Speed}; | 9 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 10 | use embassy_stm32::mode::Async; | 10 | use embassy_stm32::mode::Async; |
| 11 | use embassy_stm32::spi::mode::Master; | ||
| 11 | use embassy_stm32::spi::{self, Spi, Word}; | 12 | use embassy_stm32::spi::{self, Spi, Word}; |
| 12 | use embassy_stm32::time::Hertz; | 13 | use embassy_stm32::time::Hertz; |
| 13 | 14 | ||
| @@ -78,7 +79,7 @@ async fn main(_spawner: Spawner) { | |||
| 78 | cortex_m::asm::bkpt(); | 79 | cortex_m::asm::bkpt(); |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | async fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>) | 82 | async fn test_txrx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>) |
| 82 | where | 83 | where |
| 83 | W: core::ops::Not<Output = W>, | 84 | W: core::ops::Not<Output = W>, |
| 84 | { | 85 | { |
| @@ -142,7 +143,7 @@ where | |||
| 142 | spi.write(&buf).await.unwrap(); | 143 | spi.write(&buf).await.unwrap(); |
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | async fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>, mosi_out: &mut Output<'_>) | 146 | async fn test_rx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>, mosi_out: &mut Output<'_>) |
| 146 | where | 147 | where |
| 147 | W: core::ops::Not<Output = W>, | 148 | W: core::ops::Not<Output = W>, |
| 148 | { | 149 | { |
| @@ -168,7 +169,7 @@ where | |||
| 168 | spi.blocking_read::<u8>(&mut []).unwrap(); | 169 | spi.blocking_read::<u8>(&mut []).unwrap(); |
| 169 | } | 170 | } |
| 170 | 171 | ||
| 171 | async fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async>) | 172 | async fn test_tx<W: Word + From<u8> + defmt::Format + Eq>(spi: &mut Spi<'_, Async, Master>) |
| 172 | where | 173 | where |
| 173 | W: core::ops::Not<Output = W>, | 174 | W: core::ops::Not<Output = W>, |
| 174 | { | 175 | { |
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 833ca05d0..1fe65d867 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -10,11 +10,10 @@ use common::*; | |||
| 10 | use cortex_m_rt::entry; | 10 | use cortex_m_rt::entry; |
| 11 | use embassy_executor::Spawner; | 11 | use embassy_executor::Spawner; |
| 12 | use embassy_stm32::Config; | 12 | use embassy_stm32::Config; |
| 13 | use embassy_stm32::low_power::{Executor, StopMode, stop_ready, stop_with_rtc}; | 13 | use embassy_stm32::low_power::{Executor, StopMode, stop_ready}; |
| 14 | use embassy_stm32::rcc::LsConfig; | 14 | use embassy_stm32::rcc::LsConfig; |
| 15 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 15 | use embassy_stm32::rtc::Rtc; |
| 16 | use embassy_time::Timer; | 16 | use embassy_time::Timer; |
| 17 | use static_cell::StaticCell; | ||
| 18 | 17 | ||
| 19 | #[entry] | 18 | #[entry] |
| 20 | fn main() -> ! { | 19 | fn main() -> ! { |
| @@ -50,6 +49,7 @@ async fn async_main(spawner: Spawner) { | |||
| 50 | 49 | ||
| 51 | let mut config = Config::default(); | 50 | let mut config = Config::default(); |
| 52 | config.rcc.ls = LsConfig::default_lse(); | 51 | config.rcc.ls = LsConfig::default_lse(); |
| 52 | config.rtc._disable_rtc = false; | ||
| 53 | 53 | ||
| 54 | // System Clock seems cannot be greater than 16 MHz | 54 | // System Clock seems cannot be greater than 16 MHz |
| 55 | #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] | 55 | #[cfg(any(feature = "stm32h563zi", feature = "stm32h503rb"))] |
| @@ -66,14 +66,11 @@ async fn async_main(spawner: Spawner) { | |||
| 66 | .and_hms_opt(10, 30, 15) | 66 | .and_hms_opt(10, 30, 15) |
| 67 | .unwrap(); | 67 | .unwrap(); |
| 68 | 68 | ||
| 69 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 69 | let (rtc, _time_provider) = Rtc::new(p.RTC); |
| 70 | 70 | ||
| 71 | rtc.set_datetime(now.into()).expect("datetime not set"); | 71 | critical_section::with(|cs| { |
| 72 | 72 | rtc.borrow_mut(cs).set_datetime(now.into()).expect("datetime not set"); | |
| 73 | static RTC: StaticCell<Rtc> = StaticCell::new(); | 73 | }); |
| 74 | let rtc = RTC.init(rtc); | ||
| 75 | |||
| 76 | stop_with_rtc(rtc); | ||
| 77 | 74 | ||
| 78 | spawner.spawn(task_1().unwrap()); | 75 | spawner.spawn(task_1().unwrap()); |
| 79 | spawner.spawn(task_2().unwrap()); | 76 | spawner.spawn(task_2().unwrap()); |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 2bd934d6f..096cce947 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -468,6 +468,8 @@ pub fn config() -> Config { | |||
| 468 | config.rcc.apb3_pre = APBPrescaler::DIV1; | 468 | config.rcc.apb3_pre = APBPrescaler::DIV1; |
| 469 | config.rcc.sys = Sysclk::PLL1_P; | 469 | config.rcc.sys = Sysclk::PLL1_P; |
| 470 | config.rcc.voltage_scale = VoltageScale::Scale0; | 470 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 471 | |||
| 472 | config.rtc._disable_rtc = true; | ||
| 471 | } | 473 | } |
| 472 | 474 | ||
| 473 | #[cfg(feature = "stm32h503rb")] | 475 | #[cfg(feature = "stm32h503rb")] |
