diff options
185 files changed, 3071 insertions, 2824 deletions
| @@ -124,6 +124,7 @@ cargo batch \ | |||
| 124 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \ | 124 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \ |
| 125 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h725re,defmt,exti,time-driver-any,time \ | 125 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h725re,defmt,exti,time-driver-any,time \ |
| 126 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-any,time \ | 126 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-any,time \ |
| 127 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-tim1,time \ | ||
| 127 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l431cb,defmt,exti,time-driver-any,time \ | 128 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l431cb,defmt,exti,time-driver-any,time \ |
| 128 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \ | 129 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \ |
| 129 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l422cb,defmt,exti,time-driver-any,time \ | 130 | --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l422cb,defmt,exti,time-driver-any,time \ |
diff --git a/cyw43/src/fmt.rs b/cyw43/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/cyw43/src/fmt.rs +++ b/cyw43/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-boot-nrf/src/fmt.rs b/embassy-boot-nrf/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-boot-nrf/src/fmt.rs +++ b/embassy-boot-nrf/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-boot-rp/src/fmt.rs b/embassy-boot-rp/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-boot-rp/src/fmt.rs +++ b/embassy-boot-rp/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-boot-stm32/src/fmt.rs b/embassy-boot-stm32/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-boot-stm32/src/fmt.rs +++ b/embassy-boot-stm32/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-boot/src/boot_loader.rs b/embassy-boot/src/boot_loader.rs index ca1a1b10c..a38558056 100644 --- a/embassy-boot/src/boot_loader.rs +++ b/embassy-boot/src/boot_loader.rs | |||
| @@ -183,29 +183,29 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S | |||
| 183 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | | 183 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 184 | /// |-----------|------------|--------|--------|--------|--------| | 184 | /// |-----------|------------|--------|--------|--------|--------| |
| 185 | /// | Active | 0 | 1 | 2 | 3 | - | | 185 | /// | Active | 0 | 1 | 2 | 3 | - | |
| 186 | /// | DFU | 0 | 3 | 2 | 1 | X | | 186 | /// | DFU | 0 | 4 | 5 | 6 | X | |
| 187 | /// | 187 | /// |
| 188 | /// The algorithm starts by copying 'backwards', and after the first step, the layout is | 188 | /// The algorithm starts by copying 'backwards', and after the first step, the layout is |
| 189 | /// as follows: | 189 | /// as follows: |
| 190 | /// | 190 | /// |
| 191 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | | 191 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 192 | /// |-----------|------------|--------|--------|--------|--------| | 192 | /// |-----------|------------|--------|--------|--------|--------| |
| 193 | /// | Active | 1 | 1 | 2 | 1 | - | | 193 | /// | Active | 1 | 1 | 2 | 6 | - | |
| 194 | /// | DFU | 1 | 3 | 2 | 1 | 3 | | 194 | /// | DFU | 1 | 4 | 5 | 6 | 3 | |
| 195 | /// | 195 | /// |
| 196 | /// The next iteration performs the same steps | 196 | /// The next iteration performs the same steps |
| 197 | /// | 197 | /// |
| 198 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | | 198 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 199 | /// |-----------|------------|--------|--------|--------|--------| | 199 | /// |-----------|------------|--------|--------|--------|--------| |
| 200 | /// | Active | 2 | 1 | 2 | 1 | - | | 200 | /// | Active | 2 | 1 | 5 | 6 | - | |
| 201 | /// | DFU | 2 | 3 | 2 | 2 | 3 | | 201 | /// | DFU | 2 | 4 | 5 | 2 | 3 | |
| 202 | /// | 202 | /// |
| 203 | /// And again until we're done | 203 | /// And again until we're done |
| 204 | /// | 204 | /// |
| 205 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | | 205 | /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 206 | /// |-----------|------------|--------|--------|--------|--------| | 206 | /// |-----------|------------|--------|--------|--------|--------| |
| 207 | /// | Active | 3 | 3 | 2 | 1 | - | | 207 | /// | Active | 3 | 4 | 5 | 6 | - | |
| 208 | /// | DFU | 3 | 3 | 1 | 2 | 3 | | 208 | /// | DFU | 3 | 4 | 1 | 2 | 3 | |
| 209 | /// | 209 | /// |
| 210 | /// ## REVERTING | 210 | /// ## REVERTING |
| 211 | /// | 211 | /// |
| @@ -220,19 +220,19 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S | |||
| 220 | /// | 220 | /// |
| 221 | /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | | 221 | /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 222 | /// |-----------|--------------|--------|--------|--------|--------| | 222 | /// |-----------|--------------|--------|--------|--------|--------| |
| 223 | /// | Active | 3 | 1 | 2 | 1 | - | | 223 | /// | Active | 3 | 1 | 5 | 6 | - | |
| 224 | /// | DFU | 3 | 3 | 1 | 2 | 3 | | 224 | /// | DFU | 3 | 4 | 1 | 2 | 3 | |
| 225 | /// | 225 | /// |
| 226 | /// | 226 | /// |
| 227 | /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | | 227 | /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 228 | /// |-----------|--------------|--------|--------|--------|--------| | 228 | /// |-----------|--------------|--------|--------|--------|--------| |
| 229 | /// | Active | 3 | 1 | 2 | 1 | - | | 229 | /// | Active | 3 | 1 | 2 | 6 | - | |
| 230 | /// | DFU | 3 | 3 | 2 | 2 | 3 | | 230 | /// | DFU | 3 | 4 | 5 | 2 | 3 | |
| 231 | /// | 231 | /// |
| 232 | /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | | 232 | /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | |
| 233 | /// |-----------|--------------|--------|--------|--------|--------| | 233 | /// |-----------|--------------|--------|--------|--------|--------| |
| 234 | /// | Active | 3 | 1 | 2 | 3 | - | | 234 | /// | Active | 3 | 1 | 2 | 3 | - | |
| 235 | /// | DFU | 3 | 3 | 2 | 1 | 3 | | 235 | /// | DFU | 3 | 4 | 5 | 6 | 3 | |
| 236 | /// | 236 | /// |
| 237 | pub fn prepare_boot(&mut self, aligned_buf: &mut [u8]) -> Result<State, BootError> { | 237 | pub fn prepare_boot(&mut self, aligned_buf: &mut [u8]) -> Result<State, BootError> { |
| 238 | // Ensure we have enough progress pages to store copy progress | 238 | // Ensure we have enough progress pages to store copy progress |
diff --git a/embassy-boot/src/fmt.rs b/embassy-boot/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-boot/src/fmt.rs +++ b/embassy-boot/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs index 779c04263..71ce09def 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs | |||
| @@ -106,6 +106,11 @@ impl<'a, M: RawMutex, BUS: SetConfig> I2cDeviceWithConfig<'a, M, BUS> { | |||
| 106 | pub fn new(bus: &'a Mutex<M, BUS>, config: BUS::Config) -> Self { | 106 | pub fn new(bus: &'a Mutex<M, BUS>, config: BUS::Config) -> Self { |
| 107 | Self { bus, config } | 107 | Self { bus, config } |
| 108 | } | 108 | } |
| 109 | |||
| 110 | /// Change the device's config at runtime | ||
| 111 | pub fn set_config(&mut self, config: BUS::Config) { | ||
| 112 | self.config = config; | ||
| 113 | } | ||
| 109 | } | 114 | } |
| 110 | 115 | ||
| 111 | impl<'a, M, BUS> i2c::ErrorType for I2cDeviceWithConfig<'a, M, BUS> | 116 | impl<'a, M, BUS> i2c::ErrorType for I2cDeviceWithConfig<'a, M, BUS> |
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index 62b2c92a0..9890f218d 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs | |||
| @@ -122,6 +122,11 @@ impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiDeviceWithConfig<'a, M, BUS, CS> { | |||
| 122 | pub fn new(bus: &'a Mutex<M, BUS>, cs: CS, config: BUS::Config) -> Self { | 122 | pub fn new(bus: &'a Mutex<M, BUS>, cs: CS, config: BUS::Config) -> Self { |
| 123 | Self { bus, cs, config } | 123 | Self { bus, cs, config } |
| 124 | } | 124 | } |
| 125 | |||
| 126 | /// Change the device's config at runtime | ||
| 127 | pub fn set_config(&mut self, config: BUS::Config) { | ||
| 128 | self.config = config; | ||
| 129 | } | ||
| 125 | } | 130 | } |
| 126 | 131 | ||
| 127 | impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS> | 132 | impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS> |
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs index 233c9e1fd..627767c8a 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs | |||
| @@ -67,9 +67,11 @@ where | |||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> { | 69 | fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> { |
| 70 | let _ = address; | 70 | self.bus.lock(|bus| { |
| 71 | let _ = operations; | 71 | bus.borrow_mut() |
| 72 | todo!() | 72 | .transaction(address, operations) |
| 73 | .map_err(I2cDeviceError::I2c) | ||
| 74 | }) | ||
| 73 | } | 75 | } |
| 74 | } | 76 | } |
| 75 | 77 | ||
| @@ -130,6 +132,11 @@ impl<'a, M: RawMutex, BUS: SetConfig> I2cDeviceWithConfig<'a, M, BUS> { | |||
| 130 | pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, config: BUS::Config) -> Self { | 132 | pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, config: BUS::Config) -> Self { |
| 131 | Self { bus, config } | 133 | Self { bus, config } |
| 132 | } | 134 | } |
| 135 | |||
| 136 | /// Change the device's config at runtime | ||
| 137 | pub fn set_config(&mut self, config: BUS::Config) { | ||
| 138 | self.config = config; | ||
| 139 | } | ||
| 133 | } | 140 | } |
| 134 | 141 | ||
| 135 | impl<'a, M, BUS> ErrorType for I2cDeviceWithConfig<'a, M, BUS> | 142 | impl<'a, M, BUS> ErrorType for I2cDeviceWithConfig<'a, M, BUS> |
| @@ -171,8 +178,10 @@ where | |||
| 171 | } | 178 | } |
| 172 | 179 | ||
| 173 | fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> { | 180 | fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> { |
| 174 | let _ = address; | 181 | self.bus.lock(|bus| { |
| 175 | let _ = operations; | 182 | let mut bus = bus.borrow_mut(); |
| 176 | todo!() | 183 | bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; |
| 184 | bus.transaction(address, operations).map_err(I2cDeviceError::I2c) | ||
| 185 | }) | ||
| 177 | } | 186 | } |
| 178 | } | 187 | } |
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index 59b65bfbd..801899f9f 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs | |||
| @@ -147,6 +147,11 @@ impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiDeviceWithConfig<'a, M, BUS, CS> { | |||
| 147 | pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: BUS::Config) -> Self { | 147 | pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: BUS::Config) -> Self { |
| 148 | Self { bus, cs, config } | 148 | Self { bus, cs, config } |
| 149 | } | 149 | } |
| 150 | |||
| 151 | /// Change the device's config at runtime | ||
| 152 | pub fn set_config(&mut self, config: BUS::Config) { | ||
| 153 | self.config = config; | ||
| 154 | } | ||
| 150 | } | 155 | } |
| 151 | 156 | ||
| 152 | impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS> | 157 | impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS> |
diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index 1efb2788b..96c6267b2 100644 --- a/embassy-executor-macros/src/macros/task.rs +++ b/embassy-executor-macros/src/macros/task.rs | |||
| @@ -93,10 +93,21 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre | |||
| 93 | #[cfg(feature = "nightly")] | 93 | #[cfg(feature = "nightly")] |
| 94 | let mut task_outer: ItemFn = parse_quote! { | 94 | let mut task_outer: ItemFn = parse_quote! { |
| 95 | #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> { | 95 | #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> { |
| 96 | type Fut = impl ::core::future::Future + 'static; | 96 | trait _EmbassyInternalTaskTrait { |
| 97 | type Fut: ::core::future::Future + 'static; | ||
| 98 | fn construct(#fargs) -> Self::Fut; | ||
| 99 | } | ||
| 100 | |||
| 101 | impl _EmbassyInternalTaskTrait for () { | ||
| 102 | type Fut = impl core::future::Future + 'static; | ||
| 103 | fn construct(#fargs) -> Self::Fut { | ||
| 104 | #task_inner_ident(#(#full_args,)*) | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 97 | const POOL_SIZE: usize = #pool_size; | 108 | const POOL_SIZE: usize = #pool_size; |
| 98 | static POOL: ::embassy_executor::raw::TaskPool<Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new(); | 109 | static POOL: ::embassy_executor::raw::TaskPool<<() as _EmbassyInternalTaskTrait>::Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new(); |
| 99 | unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } | 110 | unsafe { POOL._spawn_async_fn(move || <() as _EmbassyInternalTaskTrait>::construct(#(#full_args,)*)) } |
| 100 | } | 111 | } |
| 101 | }; | 112 | }; |
| 102 | #[cfg(not(feature = "nightly"))] | 113 | #[cfg(not(feature = "nightly"))] |
diff --git a/embassy-executor-macros/src/util/ctxt.rs b/embassy-executor-macros/src/util/ctxt.rs index 74c872c3c..9c78cda01 100644 --- a/embassy-executor-macros/src/util/ctxt.rs +++ b/embassy-executor-macros/src/util/ctxt.rs | |||
| @@ -7,7 +7,6 @@ use std::thread; | |||
| 7 | 7 | ||
| 8 | use proc_macro2::TokenStream; | 8 | use proc_macro2::TokenStream; |
| 9 | use quote::{quote, ToTokens}; | 9 | use quote::{quote, ToTokens}; |
| 10 | use syn; | ||
| 11 | 10 | ||
| 12 | /// A type to collect errors together and format them. | 11 | /// A type to collect errors together and format them. |
| 13 | /// | 12 | /// |
diff --git a/embassy-executor/src/fmt.rs b/embassy-executor/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-executor/src/fmt.rs +++ b/embassy-executor/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 3d5e3ab9f..d9ea5c005 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -30,7 +30,7 @@ use core::ptr::NonNull; | |||
| 30 | use core::task::{Context, Poll}; | 30 | use core::task::{Context, Poll}; |
| 31 | 31 | ||
| 32 | #[cfg(feature = "integrated-timers")] | 32 | #[cfg(feature = "integrated-timers")] |
| 33 | use embassy_time_driver::{self, AlarmHandle}; | 33 | use embassy_time_driver::AlarmHandle; |
| 34 | #[cfg(feature = "rtos-trace")] | 34 | #[cfg(feature = "rtos-trace")] |
| 35 | use rtos_trace::trace; | 35 | use rtos_trace::trace; |
| 36 | 36 | ||
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs index 2c2441dd5..348cc7dc4 100644 --- a/embassy-executor/tests/test.rs +++ b/embassy-executor/tests/test.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))] | 1 | #![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] |
| 2 | 2 | ||
| 3 | use std::boxed::Box; | 3 | use std::boxed::Box; |
| 4 | use std::future::poll_fn; | 4 | use std::future::poll_fn; |
diff --git a/embassy-futures/src/fmt.rs b/embassy-futures/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-futures/src/fmt.rs +++ b/embassy-futures/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-hal-internal/src/fmt.rs b/embassy-hal-internal/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-hal-internal/src/fmt.rs +++ b/embassy-hal-internal/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-hal-internal/src/interrupt.rs b/embassy-hal-internal/src/interrupt.rs index 19dabcf6f..5e64dce9d 100644 --- a/embassy-hal-internal/src/interrupt.rs +++ b/embassy-hal-internal/src/interrupt.rs | |||
| @@ -30,14 +30,12 @@ macro_rules! interrupt_mod { | |||
| 30 | pub mod typelevel { | 30 | pub mod typelevel { |
| 31 | use super::InterruptExt; | 31 | use super::InterruptExt; |
| 32 | 32 | ||
| 33 | mod sealed { | 33 | trait SealedInterrupt {} |
| 34 | pub trait Interrupt {} | ||
| 35 | } | ||
| 36 | 34 | ||
| 37 | /// Type-level interrupt. | 35 | /// Type-level interrupt. |
| 38 | /// | 36 | /// |
| 39 | /// This trait is implemented for all typelevel interrupt types in this module. | 37 | /// This trait is implemented for all typelevel interrupt types in this module. |
| 40 | pub trait Interrupt: sealed::Interrupt { | 38 | pub trait Interrupt: SealedInterrupt { |
| 41 | 39 | ||
| 42 | /// Interrupt enum variant. | 40 | /// Interrupt enum variant. |
| 43 | /// | 41 | /// |
| @@ -105,7 +103,7 @@ macro_rules! interrupt_mod { | |||
| 105 | #[doc=stringify!($irqs)] | 103 | #[doc=stringify!($irqs)] |
| 106 | #[doc=" typelevel interrupt."] | 104 | #[doc=" typelevel interrupt."] |
| 107 | pub enum $irqs {} | 105 | pub enum $irqs {} |
| 108 | impl sealed::Interrupt for $irqs{} | 106 | impl SealedInterrupt for $irqs{} |
| 109 | impl Interrupt for $irqs { | 107 | impl Interrupt for $irqs { |
| 110 | const IRQ: super::Interrupt = super::Interrupt::$irqs; | 108 | const IRQ: super::Interrupt = super::Interrupt::$irqs; |
| 111 | } | 109 | } |
diff --git a/embassy-net-adin1110/src/fmt.rs b/embassy-net-adin1110/src/fmt.rs index 12737c690..2ac42c557 100644 --- a/embassy-net-adin1110/src/fmt.rs +++ b/embassy-net-adin1110/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -83,14 +83,17 @@ macro_rules! todo { | |||
| 83 | }; | 83 | }; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | #[cfg(not(feature = "defmt"))] | ||
| 86 | macro_rules! unreachable { | 87 | macro_rules! unreachable { |
| 87 | ($($x:tt)*) => { | 88 | ($($x:tt)*) => { |
| 88 | { | 89 | ::core::unreachable!($($x)*) |
| 89 | #[cfg(not(feature = "defmt"))] | 90 | }; |
| 90 | ::core::unreachable!($($x)*); | 91 | } |
| 91 | #[cfg(feature = "defmt")] | 92 | |
| 92 | ::defmt::unreachable!($($x)*); | 93 | #[cfg(feature = "defmt")] |
| 93 | } | 94 | macro_rules! unreachable { |
| 95 | ($($x:tt)*) => { | ||
| 96 | ::defmt::unreachable!($($x)*) | ||
| 94 | }; | 97 | }; |
| 95 | } | 98 | } |
| 96 | 99 | ||
| @@ -113,7 +116,7 @@ macro_rules! trace { | |||
| 113 | #[cfg(feature = "defmt")] | 116 | #[cfg(feature = "defmt")] |
| 114 | ::defmt::trace!($s $(, $x)*); | 117 | ::defmt::trace!($s $(, $x)*); |
| 115 | #[cfg(not(any(feature = "log", feature="defmt")))] | 118 | #[cfg(not(any(feature = "log", feature="defmt")))] |
| 116 | let _ignored = ($( & $x ),*); | 119 | let _ = ($( & $x ),*); |
| 117 | } | 120 | } |
| 118 | }; | 121 | }; |
| 119 | } | 122 | } |
| @@ -126,7 +129,7 @@ macro_rules! debug { | |||
| 126 | #[cfg(feature = "defmt")] | 129 | #[cfg(feature = "defmt")] |
| 127 | ::defmt::debug!($s $(, $x)*); | 130 | ::defmt::debug!($s $(, $x)*); |
| 128 | #[cfg(not(any(feature = "log", feature="defmt")))] | 131 | #[cfg(not(any(feature = "log", feature="defmt")))] |
| 129 | let _ignored = ($( & $x ),*); | 132 | let _ = ($( & $x ),*); |
| 130 | } | 133 | } |
| 131 | }; | 134 | }; |
| 132 | } | 135 | } |
| @@ -139,7 +142,7 @@ macro_rules! info { | |||
| 139 | #[cfg(feature = "defmt")] | 142 | #[cfg(feature = "defmt")] |
| 140 | ::defmt::info!($s $(, $x)*); | 143 | ::defmt::info!($s $(, $x)*); |
| 141 | #[cfg(not(any(feature = "log", feature="defmt")))] | 144 | #[cfg(not(any(feature = "log", feature="defmt")))] |
| 142 | let _ignored = ($( & $x ),*); | 145 | let _ = ($( & $x ),*); |
| 143 | } | 146 | } |
| 144 | }; | 147 | }; |
| 145 | } | 148 | } |
| @@ -152,7 +155,7 @@ macro_rules! warn { | |||
| 152 | #[cfg(feature = "defmt")] | 155 | #[cfg(feature = "defmt")] |
| 153 | ::defmt::warn!($s $(, $x)*); | 156 | ::defmt::warn!($s $(, $x)*); |
| 154 | #[cfg(not(any(feature = "log", feature="defmt")))] | 157 | #[cfg(not(any(feature = "log", feature="defmt")))] |
| 155 | let _ignored = ($( & $x ),*); | 158 | let _ = ($( & $x ),*); |
| 156 | } | 159 | } |
| 157 | }; | 160 | }; |
| 158 | } | 161 | } |
| @@ -165,7 +168,7 @@ macro_rules! error { | |||
| 165 | #[cfg(feature = "defmt")] | 168 | #[cfg(feature = "defmt")] |
| 166 | ::defmt::error!($s $(, $x)*); | 169 | ::defmt::error!($s $(, $x)*); |
| 167 | #[cfg(not(any(feature = "log", feature="defmt")))] | 170 | #[cfg(not(any(feature = "log", feature="defmt")))] |
| 168 | let _ignored = ($( & $x ),*); | 171 | let _ = ($( & $x ),*); |
| 169 | } | 172 | } |
| 170 | }; | 173 | }; |
| 171 | } | 174 | } |
| @@ -226,7 +229,7 @@ impl<T, E> Try for Result<T, E> { | |||
| 226 | } | 229 | } |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 229 | pub struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 230 | 233 | ||
| 231 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
| 232 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | 235 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
diff --git a/embassy-net-driver-channel/src/fmt.rs b/embassy-net-driver-channel/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-net-driver-channel/src/fmt.rs +++ b/embassy-net-driver-channel/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-net-enc28j60/src/fmt.rs b/embassy-net-enc28j60/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-net-enc28j60/src/fmt.rs +++ b/embassy-net-enc28j60/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-net-enc28j60/src/lib.rs b/embassy-net-enc28j60/src/lib.rs index f18134927..dda35f498 100644 --- a/embassy-net-enc28j60/src/lib.rs +++ b/embassy-net-enc28j60/src/lib.rs | |||
| @@ -17,7 +17,6 @@ mod phy; | |||
| 17 | mod traits; | 17 | mod traits; |
| 18 | 18 | ||
| 19 | use core::cmp; | 19 | use core::cmp; |
| 20 | use core::convert::TryInto; | ||
| 21 | 20 | ||
| 22 | use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; | 21 | use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; |
| 23 | use embassy_time::Duration; | 22 | use embassy_time::Duration; |
| @@ -645,8 +644,8 @@ where | |||
| 645 | Self: 'a; | 644 | Self: 'a; |
| 646 | 645 | ||
| 647 | fn receive(&mut self, cx: &mut core::task::Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { | 646 | fn receive(&mut self, cx: &mut core::task::Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { |
| 648 | let rx_buf = unsafe { &mut RX_BUF }; | 647 | let rx_buf = unsafe { &mut *core::ptr::addr_of_mut!(RX_BUF) }; |
| 649 | let tx_buf = unsafe { &mut TX_BUF }; | 648 | let tx_buf = unsafe { &mut *core::ptr::addr_of_mut!(TX_BUF) }; |
| 650 | if let Some(n) = self.receive(rx_buf) { | 649 | if let Some(n) = self.receive(rx_buf) { |
| 651 | Some((RxToken { buf: &mut rx_buf[..n] }, TxToken { buf: tx_buf, eth: self })) | 650 | Some((RxToken { buf: &mut rx_buf[..n] }, TxToken { buf: tx_buf, eth: self })) |
| 652 | } else { | 651 | } else { |
| @@ -656,7 +655,7 @@ where | |||
| 656 | } | 655 | } |
| 657 | 656 | ||
| 658 | fn transmit(&mut self, _cx: &mut core::task::Context) -> Option<Self::TxToken<'_>> { | 657 | fn transmit(&mut self, _cx: &mut core::task::Context) -> Option<Self::TxToken<'_>> { |
| 659 | let tx_buf = unsafe { &mut TX_BUF }; | 658 | let tx_buf = unsafe { &mut *core::ptr::addr_of_mut!(TX_BUF) }; |
| 660 | Some(TxToken { buf: tx_buf, eth: self }) | 659 | Some(TxToken { buf: tx_buf, eth: self }) |
| 661 | } | 660 | } |
| 662 | 661 | ||
diff --git a/embassy-net-esp-hosted/src/fmt.rs b/embassy-net-esp-hosted/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-net-esp-hosted/src/fmt.rs +++ b/embassy-net-esp-hosted/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-net-ppp/src/fmt.rs b/embassy-net-ppp/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-net-ppp/src/fmt.rs +++ b/embassy-net-ppp/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-net-tuntap/src/lib.rs b/embassy-net-tuntap/src/lib.rs index de30934eb..56f55fba1 100644 --- a/embassy-net-tuntap/src/lib.rs +++ b/embassy-net-tuntap/src/lib.rs | |||
| @@ -6,7 +6,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; | |||
| 6 | use std::task::Context; | 6 | use std::task::Context; |
| 7 | 7 | ||
| 8 | use async_io::Async; | 8 | use async_io::Async; |
| 9 | use embassy_net_driver::{self, Capabilities, Driver, HardwareAddress, LinkState}; | 9 | use embassy_net_driver::{Capabilities, Driver, HardwareAddress, LinkState}; |
| 10 | use log::*; | 10 | use log::*; |
| 11 | 11 | ||
| 12 | /// Get the MTU of the given interface. | 12 | /// Get the MTU of the given interface. |
diff --git a/embassy-net-wiznet/src/chip/mod.rs b/embassy-net-wiznet/src/chip/mod.rs index b987c2b36..e1f963d95 100644 --- a/embassy-net-wiznet/src/chip/mod.rs +++ b/embassy-net-wiznet/src/chip/mod.rs | |||
| @@ -2,49 +2,40 @@ | |||
| 2 | mod w5500; | 2 | mod w5500; |
| 3 | pub use w5500::W5500; | 3 | pub use w5500::W5500; |
| 4 | mod w5100s; | 4 | mod w5100s; |
| 5 | use embedded_hal_async::spi::SpiDevice; | ||
| 5 | pub use w5100s::W5100S; | 6 | pub use w5100s::W5100S; |
| 6 | 7 | ||
| 7 | pub(crate) mod sealed { | 8 | pub(crate) trait SealedChip { |
| 8 | use embedded_hal_async::spi::SpiDevice; | 9 | type Address; |
| 9 | 10 | ||
| 10 | pub trait Chip { | 11 | const COMMON_MODE: Self::Address; |
| 11 | type Address; | 12 | const COMMON_MAC: Self::Address; |
| 12 | 13 | const COMMON_SOCKET_INTR: Self::Address; | |
| 13 | const COMMON_MODE: Self::Address; | 14 | const COMMON_PHY_CFG: Self::Address; |
| 14 | const COMMON_MAC: Self::Address; | 15 | const SOCKET_MODE: Self::Address; |
| 15 | const COMMON_SOCKET_INTR: Self::Address; | 16 | const SOCKET_COMMAND: Self::Address; |
| 16 | const COMMON_PHY_CFG: Self::Address; | 17 | const SOCKET_RXBUF_SIZE: Self::Address; |
| 17 | const SOCKET_MODE: Self::Address; | 18 | const SOCKET_TXBUF_SIZE: Self::Address; |
| 18 | const SOCKET_COMMAND: Self::Address; | 19 | const SOCKET_TX_FREE_SIZE: Self::Address; |
| 19 | const SOCKET_RXBUF_SIZE: Self::Address; | 20 | const SOCKET_TX_DATA_WRITE_PTR: Self::Address; |
| 20 | const SOCKET_TXBUF_SIZE: Self::Address; | 21 | const SOCKET_RECVD_SIZE: Self::Address; |
| 21 | const SOCKET_TX_FREE_SIZE: Self::Address; | 22 | const SOCKET_RX_DATA_READ_PTR: Self::Address; |
| 22 | const SOCKET_TX_DATA_WRITE_PTR: Self::Address; | 23 | const SOCKET_INTR_MASK: Self::Address; |
| 23 | const SOCKET_RECVD_SIZE: Self::Address; | 24 | const SOCKET_INTR: Self::Address; |
| 24 | const SOCKET_RX_DATA_READ_PTR: Self::Address; | 25 | |
| 25 | const SOCKET_INTR_MASK: Self::Address; | 26 | const SOCKET_MODE_VALUE: u8; |
| 26 | const SOCKET_INTR: Self::Address; | 27 | |
| 27 | 28 | const BUF_SIZE: u16; | |
| 28 | const SOCKET_MODE_VALUE: u8; | 29 | const AUTO_WRAP: bool; |
| 29 | 30 | ||
| 30 | const BUF_SIZE: u16; | 31 | fn rx_addr(addr: u16) -> Self::Address; |
| 31 | const AUTO_WRAP: bool; | 32 | fn tx_addr(addr: u16) -> Self::Address; |
| 32 | 33 | ||
| 33 | fn rx_addr(addr: u16) -> Self::Address; | 34 | async fn bus_read<SPI: SpiDevice>(spi: &mut SPI, address: Self::Address, data: &mut [u8]) |
| 34 | fn tx_addr(addr: u16) -> Self::Address; | 35 | -> Result<(), SPI::Error>; |
| 35 | 36 | async fn bus_write<SPI: SpiDevice>(spi: &mut SPI, address: Self::Address, data: &[u8]) -> Result<(), SPI::Error>; | |
| 36 | async fn bus_read<SPI: SpiDevice>( | ||
| 37 | spi: &mut SPI, | ||
| 38 | address: Self::Address, | ||
| 39 | data: &mut [u8], | ||
| 40 | ) -> Result<(), SPI::Error>; | ||
| 41 | async fn bus_write<SPI: SpiDevice>( | ||
| 42 | spi: &mut SPI, | ||
| 43 | address: Self::Address, | ||
| 44 | data: &[u8], | ||
| 45 | ) -> Result<(), SPI::Error>; | ||
| 46 | } | ||
| 47 | } | 37 | } |
| 48 | 38 | ||
| 49 | /// Trait for Wiznet chips. | 39 | /// Trait for Wiznet chips. |
| 50 | pub trait Chip: sealed::Chip {} | 40 | #[allow(private_bounds)] |
| 41 | pub trait Chip: SealedChip {} | ||
diff --git a/embassy-net-wiznet/src/chip/w5100s.rs b/embassy-net-wiznet/src/chip/w5100s.rs index 7d328bce5..23ce3ed83 100644 --- a/embassy-net-wiznet/src/chip/w5100s.rs +++ b/embassy-net-wiznet/src/chip/w5100s.rs | |||
| @@ -8,7 +8,7 @@ const RX_BASE: u16 = 0x6000; | |||
| 8 | pub enum W5100S {} | 8 | pub enum W5100S {} |
| 9 | 9 | ||
| 10 | impl super::Chip for W5100S {} | 10 | impl super::Chip for W5100S {} |
| 11 | impl super::sealed::Chip for W5100S { | 11 | impl super::SealedChip for W5100S { |
| 12 | type Address = u16; | 12 | type Address = u16; |
| 13 | 13 | ||
| 14 | const COMMON_MODE: Self::Address = 0x00; | 14 | const COMMON_MODE: Self::Address = 0x00; |
diff --git a/embassy-net-wiznet/src/chip/w5500.rs b/embassy-net-wiznet/src/chip/w5500.rs index 16236126d..12e610ea2 100644 --- a/embassy-net-wiznet/src/chip/w5500.rs +++ b/embassy-net-wiznet/src/chip/w5500.rs | |||
| @@ -12,7 +12,7 @@ pub enum RegisterBlock { | |||
| 12 | pub enum W5500 {} | 12 | pub enum W5500 {} |
| 13 | 13 | ||
| 14 | impl super::Chip for W5500 {} | 14 | impl super::Chip for W5500 {} |
| 15 | impl super::sealed::Chip for W5500 { | 15 | impl super::SealedChip for W5500 { |
| 16 | type Address = (RegisterBlock, u16); | 16 | type Address = (RegisterBlock, u16); |
| 17 | 17 | ||
| 18 | const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00); | 18 | const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00); |
diff --git a/embassy-net/src/fmt.rs b/embassy-net/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-net/src/fmt.rs +++ b/embassy-net/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-nrf/src/fmt.rs b/embassy-nrf/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-nrf/src/fmt.rs +++ b/embassy-nrf/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 3649ea61a..f2353f21d 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -473,10 +473,12 @@ impl sealed::Pin for AnyPin { | |||
| 473 | 473 | ||
| 474 | // ==================== | 474 | // ==================== |
| 475 | 475 | ||
| 476 | #[cfg(not(feature = "_nrf51"))] | ||
| 476 | pub(crate) trait PselBits { | 477 | pub(crate) trait PselBits { |
| 477 | fn psel_bits(&self) -> u32; | 478 | fn psel_bits(&self) -> u32; |
| 478 | } | 479 | } |
| 479 | 480 | ||
| 481 | #[cfg(not(feature = "_nrf51"))] | ||
| 480 | impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> { | 482 | impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> { |
| 481 | #[inline] | 483 | #[inline] |
| 482 | fn psel_bits(&self) -> u32 { | 484 | fn psel_bits(&self) -> u32 { |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 12f4ed0a0..4a28279a9 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -167,8 +167,10 @@ unsafe fn handle_gpiote_interrupt() { | |||
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | #[cfg(not(feature = "_nrf51"))] | ||
| 170 | struct BitIter(u32); | 171 | struct BitIter(u32); |
| 171 | 172 | ||
| 173 | #[cfg(not(feature = "_nrf51"))] | ||
| 172 | impl Iterator for BitIter { | 174 | impl Iterator for BitIter { |
| 173 | type Item = u32; | 175 | type Item = u32; |
| 174 | 176 | ||
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 718f229a3..3457dd933 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -225,10 +225,31 @@ pub mod config { | |||
| 225 | /// Config for the first stage DCDC (VDDH -> VDD), if disabled LDO will be used. | 225 | /// Config for the first stage DCDC (VDDH -> VDD), if disabled LDO will be used. |
| 226 | #[cfg(feature = "nrf52840")] | 226 | #[cfg(feature = "nrf52840")] |
| 227 | pub reg0: bool, | 227 | pub reg0: bool, |
| 228 | /// Configure the voltage of the first stage DCDC. It is stored in non-volatile memory (UICR.REGOUT0 register); pass None to not touch it. | ||
| 229 | #[cfg(feature = "nrf52840")] | ||
| 230 | pub reg0_voltage: Option<Reg0Voltage>, | ||
| 228 | /// Config for the second stage DCDC (VDD -> DEC4), if disabled LDO will be used. | 231 | /// Config for the second stage DCDC (VDD -> DEC4), if disabled LDO will be used. |
| 229 | pub reg1: bool, | 232 | pub reg1: bool, |
| 230 | } | 233 | } |
| 231 | 234 | ||
| 235 | /// Output voltage setting for REG0 regulator stage. | ||
| 236 | #[cfg(feature = "nrf52840")] | ||
| 237 | pub enum Reg0Voltage { | ||
| 238 | /// 1.8 V | ||
| 239 | _1V8 = 0, | ||
| 240 | /// 2.1 V | ||
| 241 | _2V1 = 1, | ||
| 242 | /// 2.4 V | ||
| 243 | _2V4 = 2, | ||
| 244 | /// 2.7 V | ||
| 245 | _2V7 = 3, | ||
| 246 | /// 3.0 V | ||
| 247 | _3V0 = 4, | ||
| 248 | /// 3.3 V | ||
| 249 | _3v3 = 5, | ||
| 250 | //ERASED = 7, means 1.8V | ||
| 251 | } | ||
| 252 | |||
| 232 | /// Settings for enabling the built in DCDC converters. | 253 | /// Settings for enabling the built in DCDC converters. |
| 233 | #[cfg(feature = "_nrf5340-app")] | 254 | #[cfg(feature = "_nrf5340-app")] |
| 234 | pub struct DcdcConfig { | 255 | pub struct DcdcConfig { |
| @@ -279,6 +300,8 @@ pub mod config { | |||
| 279 | dcdc: DcdcConfig { | 300 | dcdc: DcdcConfig { |
| 280 | #[cfg(feature = "nrf52840")] | 301 | #[cfg(feature = "nrf52840")] |
| 281 | reg0: false, | 302 | reg0: false, |
| 303 | #[cfg(feature = "nrf52840")] | ||
| 304 | reg0_voltage: None, | ||
| 282 | reg1: false, | 305 | reg1: false, |
| 283 | }, | 306 | }, |
| 284 | #[cfg(feature = "_nrf5340-app")] | 307 | #[cfg(feature = "_nrf5340-app")] |
| @@ -337,6 +360,7 @@ mod consts { | |||
| 337 | pub const UICR_PSELRESET2: *mut u32 = 0x10001204 as *mut u32; | 360 | pub const UICR_PSELRESET2: *mut u32 = 0x10001204 as *mut u32; |
| 338 | pub const UICR_NFCPINS: *mut u32 = 0x1000120C as *mut u32; | 361 | pub const UICR_NFCPINS: *mut u32 = 0x1000120C as *mut u32; |
| 339 | pub const UICR_APPROTECT: *mut u32 = 0x10001208 as *mut u32; | 362 | pub const UICR_APPROTECT: *mut u32 = 0x10001208 as *mut u32; |
| 363 | pub const UICR_REGOUT0: *mut u32 = 0x10001304 as *mut u32; | ||
| 340 | pub const APPROTECT_ENABLED: u32 = 0x0000_0000; | 364 | pub const APPROTECT_ENABLED: u32 = 0x0000_0000; |
| 341 | pub const APPROTECT_DISABLED: u32 = 0x0000_005a; | 365 | pub const APPROTECT_DISABLED: u32 = 0x0000_005a; |
| 342 | } | 366 | } |
| @@ -493,6 +517,21 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 493 | } | 517 | } |
| 494 | } | 518 | } |
| 495 | 519 | ||
| 520 | #[cfg(feature = "nrf52840")] | ||
| 521 | unsafe { | ||
| 522 | if let Some(value) = config.dcdc.reg0_voltage { | ||
| 523 | let value = value as u32; | ||
| 524 | let res = uicr_write_masked(consts::UICR_REGOUT0, value, 0b00000000_00000000_00000000_00000111); | ||
| 525 | needs_reset |= res == WriteResult::Written; | ||
| 526 | if res == WriteResult::Failed { | ||
| 527 | warn!( | ||
| 528 | "Failed to set regulator voltage, as UICR is already programmed to some other setting, and can't be changed without erasing it.\n\ | ||
| 529 | To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`." | ||
| 530 | ); | ||
| 531 | } | ||
| 532 | } | ||
| 533 | } | ||
| 534 | |||
| 496 | if needs_reset { | 535 | if needs_reset { |
| 497 | cortex_m::peripheral::SCB::sys_reset(); | 536 | cortex_m::peripheral::SCB::sys_reset(); |
| 498 | } | 537 | } |
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 3c35baee5..2970ad3f2 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -21,8 +21,6 @@ pub(crate) mod sealed { | |||
| 21 | fn regs() -> &'static pac::timer0::RegisterBlock; | 21 | fn regs() -> &'static pac::timer0::RegisterBlock; |
| 22 | } | 22 | } |
| 23 | pub trait ExtendedInstance {} | 23 | pub trait ExtendedInstance {} |
| 24 | |||
| 25 | pub trait TimerType {} | ||
| 26 | } | 24 | } |
| 27 | 25 | ||
| 28 | /// Basic Timer instance. | 26 | /// Basic Timer instance. |
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 088a842a1..44aabce6b 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs | |||
| @@ -96,7 +96,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>( | |||
| 96 | ) -> Transfer<'a, C> { | 96 | ) -> Transfer<'a, C> { |
| 97 | copy_inner( | 97 | copy_inner( |
| 98 | ch, | 98 | ch, |
| 99 | &mut DUMMY as *const u32, | 99 | core::ptr::addr_of_mut!(DUMMY) as *const u32, |
| 100 | to as *mut u32, | 100 | to as *mut u32, |
| 101 | len, | 101 | len, |
| 102 | W::size(), | 102 | W::size(), |
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 8bac93684..422b77400 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs | |||
| @@ -420,8 +420,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash | |||
| 420 | 420 | ||
| 421 | #[allow(dead_code)] | 421 | #[allow(dead_code)] |
| 422 | mod ram_helpers { | 422 | mod ram_helpers { |
| 423 | use core::marker::PhantomData; | ||
| 424 | |||
| 425 | use super::*; | 423 | use super::*; |
| 426 | use crate::rom_data; | 424 | use crate::rom_data; |
| 427 | 425 | ||
diff --git a/embassy-rp/src/float/mod.rs b/embassy-rp/src/float/mod.rs index 945afff90..3ad6f1c50 100644 --- a/embassy-rp/src/float/mod.rs +++ b/embassy-rp/src/float/mod.rs | |||
| @@ -89,6 +89,7 @@ pub(crate) trait Float: | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | /// Returns true if `self` is infinity | 91 | /// Returns true if `self` is infinity |
| 92 | #[allow(unused)] | ||
| 92 | fn is_infinity(self) -> bool { | 93 | fn is_infinity(self) -> bool { |
| 93 | (self.repr() & (Self::EXPONENT_MASK | Self::SIGNIFICAND_MASK)) == Self::EXPONENT_MASK | 94 | (self.repr() & (Self::EXPONENT_MASK | Self::SIGNIFICAND_MASK)) == Self::EXPONENT_MASK |
| 94 | } | 95 | } |
diff --git a/embassy-rp/src/fmt.rs b/embassy-rp/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-rp/src/fmt.rs +++ b/embassy-rp/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index 405bddfd8..a84c00a2c 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs | |||
| @@ -976,8 +976,6 @@ impl_pin!(PIN_QSPI_SD3, Bank::Qspi, 5); | |||
| 976 | // ==================== | 976 | // ==================== |
| 977 | 977 | ||
| 978 | mod eh02 { | 978 | mod eh02 { |
| 979 | use core::convert::Infallible; | ||
| 980 | |||
| 981 | use super::*; | 979 | use super::*; |
| 982 | 980 | ||
| 983 | impl<'d> embedded_hal_02::digital::v2::InputPin for Input<'d> { | 981 | impl<'d> embedded_hal_02::digital::v2::InputPin for Input<'d> { |
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 7092b3fab..d91cea410 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs | |||
| @@ -274,7 +274,7 @@ pub fn install_core0_stack_guard() -> Result<(), ()> { | |||
| 274 | extern "C" { | 274 | extern "C" { |
| 275 | static mut _stack_end: usize; | 275 | static mut _stack_end: usize; |
| 276 | } | 276 | } |
| 277 | unsafe { install_stack_guard(&mut _stack_end as *mut usize) } | 277 | unsafe { install_stack_guard(core::ptr::addr_of_mut!(_stack_end)) } |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | #[inline(always)] | 280 | #[inline(always)] |
| @@ -354,6 +354,7 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 354 | 354 | ||
| 355 | /// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes. | 355 | /// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes. |
| 356 | trait RegExt<T: Copy> { | 356 | trait RegExt<T: Copy> { |
| 357 | #[allow(unused)] | ||
| 357 | fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; | 358 | fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; |
| 358 | fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; | 359 | fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; |
| 359 | fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; | 360 | fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R; |
diff --git a/embassy-rp/src/relocate.rs b/embassy-rp/src/relocate.rs index 40cb2667b..34487819f 100644 --- a/embassy-rp/src/relocate.rs +++ b/embassy-rp/src/relocate.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use core::iter::Iterator; | ||
| 2 | |||
| 3 | use pio::{Program, SideSet, Wrap}; | 1 | use pio::{Program, SideSet, Wrap}; |
| 4 | 2 | ||
| 5 | pub struct CodeIterator<'a, I> | 3 | pub struct CodeIterator<'a, I> |
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index 7622539f1..da1157984 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs | |||
| @@ -1,17 +1,11 @@ | |||
| 1 | //! Buffered UART driver. | 1 | //! Buffered UART driver. |
| 2 | use core::future::{poll_fn, Future}; | 2 | use core::future::Future; |
| 3 | use core::slice; | 3 | use core::slice; |
| 4 | use core::task::Poll; | ||
| 5 | 4 | ||
| 6 | use atomic_polyfill::{AtomicU8, Ordering}; | 5 | use atomic_polyfill::AtomicU8; |
| 7 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | 6 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | 7 | ||
| 11 | use super::*; | 8 | use super::*; |
| 12 | use crate::clocks::clk_peri_freq; | ||
| 13 | use crate::interrupt::typelevel::{Binding, Interrupt}; | ||
| 14 | use crate::{interrupt, RegExt}; | ||
| 15 | 9 | ||
| 16 | pub struct State { | 10 | pub struct State { |
| 17 | tx_waker: AtomicWaker, | 11 | tx_waker: AtomicWaker, |
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs index 905661d64..d68dee4a3 100644 --- a/embassy-rp/src/usb.rs +++ b/embassy-rp/src/usb.rs | |||
| @@ -465,7 +465,6 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 465 | 465 | ||
| 466 | trait Dir { | 466 | trait Dir { |
| 467 | fn dir() -> Direction; | 467 | fn dir() -> Direction; |
| 468 | fn waker(i: usize) -> &'static AtomicWaker; | ||
| 469 | } | 468 | } |
| 470 | 469 | ||
| 471 | /// Type for In direction. | 470 | /// Type for In direction. |
| @@ -474,11 +473,6 @@ impl Dir for In { | |||
| 474 | fn dir() -> Direction { | 473 | fn dir() -> Direction { |
| 475 | Direction::In | 474 | Direction::In |
| 476 | } | 475 | } |
| 477 | |||
| 478 | #[inline] | ||
| 479 | fn waker(i: usize) -> &'static AtomicWaker { | ||
| 480 | &EP_IN_WAKERS[i] | ||
| 481 | } | ||
| 482 | } | 476 | } |
| 483 | 477 | ||
| 484 | /// Type for Out direction. | 478 | /// Type for Out direction. |
| @@ -487,11 +481,6 @@ impl Dir for Out { | |||
| 487 | fn dir() -> Direction { | 481 | fn dir() -> Direction { |
| 488 | Direction::Out | 482 | Direction::Out |
| 489 | } | 483 | } |
| 490 | |||
| 491 | #[inline] | ||
| 492 | fn waker(i: usize) -> &'static AtomicWaker { | ||
| 493 | &EP_OUT_WAKERS[i] | ||
| 494 | } | ||
| 495 | } | 484 | } |
| 496 | 485 | ||
| 497 | /// Endpoint for RP USB driver. | 486 | /// Endpoint for RP USB driver. |
diff --git a/embassy-stm32-wpan/src/consts.rs b/embassy-stm32-wpan/src/consts.rs index bd70851ea..6aaef1d35 100644 --- a/embassy-stm32-wpan/src/consts.rs +++ b/embassy-stm32-wpan/src/consts.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use core::convert::TryFrom; | ||
| 2 | |||
| 3 | use crate::evt::CsEvt; | 1 | use crate::evt::CsEvt; |
| 4 | use crate::PacketHeader; | 2 | use crate::PacketHeader; |
| 5 | 3 | ||
diff --git a/embassy-stm32-wpan/src/fmt.rs b/embassy-stm32-wpan/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-stm32-wpan/src/fmt.rs +++ b/embassy-stm32-wpan/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index d3626610e..7c6312f6c 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -70,7 +70,7 @@ rand_core = "0.6.3" | |||
| 70 | sdio-host = "0.5.0" | 70 | sdio-host = "0.5.0" |
| 71 | critical-section = "1.1" | 71 | critical-section = "1.1" |
| 72 | #stm32-metapac = { version = "15" } | 72 | #stm32-metapac = { version = "15" } |
| 73 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c8b32ecae7d70cea2705095c4fc6bd5f59d238d5" } | 73 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f84633553331c2d154ee72de779a40cbb10fd1bd" } |
| 74 | vcell = "0.1.3" | 74 | vcell = "0.1.3" |
| 75 | nb = "1.0.0" | 75 | nb = "1.0.0" |
| 76 | stm32-fmc = "0.3.0" | 76 | stm32-fmc = "0.3.0" |
| @@ -94,7 +94,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 94 | proc-macro2 = "1.0.36" | 94 | proc-macro2 = "1.0.36" |
| 95 | quote = "1.0.15" | 95 | quote = "1.0.15" |
| 96 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} | 96 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} |
| 97 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c8b32ecae7d70cea2705095c4fc6bd5f59d238d5", default-features = false, features = ["metadata"]} | 97 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f84633553331c2d154ee72de779a40cbb10fd1bd", default-features = false, features = ["metadata"]} |
| 98 | 98 | ||
| 99 | 99 | ||
| 100 | [features] | 100 | [features] |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index fe5236ed6..15bb8ea62 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -584,7 +584,7 @@ fn main() { | |||
| 584 | }; | 584 | }; |
| 585 | 585 | ||
| 586 | g.extend(quote! { | 586 | g.extend(quote! { |
| 587 | impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { | 587 | impl crate::rcc::SealedRccPeripheral for peripherals::#pname { |
| 588 | fn frequency() -> crate::time::Hertz { | 588 | fn frequency() -> crate::time::Hertz { |
| 589 | #clock_frequency | 589 | #clock_frequency |
| 590 | } | 590 | } |
| @@ -826,20 +826,20 @@ fn main() { | |||
| 826 | (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)), | 826 | (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)), |
| 827 | (("usb", "DP"), quote!(crate::usb::DpPin)), | 827 | (("usb", "DP"), quote!(crate::usb::DpPin)), |
| 828 | (("usb", "DM"), quote!(crate::usb::DmPin)), | 828 | (("usb", "DM"), quote!(crate::usb::DmPin)), |
| 829 | (("otg", "DP"), quote!(crate::usb_otg::DpPin)), | 829 | (("otg", "DP"), quote!(crate::usb::DpPin)), |
| 830 | (("otg", "DM"), quote!(crate::usb_otg::DmPin)), | 830 | (("otg", "DM"), quote!(crate::usb::DmPin)), |
| 831 | (("otg", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)), | 831 | (("otg", "ULPI_CK"), quote!(crate::usb::UlpiClkPin)), |
| 832 | (("otg", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)), | 832 | (("otg", "ULPI_DIR"), quote!(crate::usb::UlpiDirPin)), |
| 833 | (("otg", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)), | 833 | (("otg", "ULPI_NXT"), quote!(crate::usb::UlpiNxtPin)), |
| 834 | (("otg", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)), | 834 | (("otg", "ULPI_STP"), quote!(crate::usb::UlpiStpPin)), |
| 835 | (("otg", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)), | 835 | (("otg", "ULPI_D0"), quote!(crate::usb::UlpiD0Pin)), |
| 836 | (("otg", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)), | 836 | (("otg", "ULPI_D1"), quote!(crate::usb::UlpiD1Pin)), |
| 837 | (("otg", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)), | 837 | (("otg", "ULPI_D2"), quote!(crate::usb::UlpiD2Pin)), |
| 838 | (("otg", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)), | 838 | (("otg", "ULPI_D3"), quote!(crate::usb::UlpiD3Pin)), |
| 839 | (("otg", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)), | 839 | (("otg", "ULPI_D4"), quote!(crate::usb::UlpiD4Pin)), |
| 840 | (("otg", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)), | 840 | (("otg", "ULPI_D5"), quote!(crate::usb::UlpiD5Pin)), |
| 841 | (("otg", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)), | 841 | (("otg", "ULPI_D6"), quote!(crate::usb::UlpiD6Pin)), |
| 842 | (("otg", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)), | 842 | (("otg", "ULPI_D7"), quote!(crate::usb::UlpiD7Pin)), |
| 843 | (("can", "TX"), quote!(crate::can::TxPin)), | 843 | (("can", "TX"), quote!(crate::can::TxPin)), |
| 844 | (("can", "RX"), quote!(crate::can::RxPin)), | 844 | (("can", "RX"), quote!(crate::can::RxPin)), |
| 845 | (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)), | 845 | (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)), |
| @@ -1486,7 +1486,7 @@ fn main() { | |||
| 1486 | #[crate::interrupt] | 1486 | #[crate::interrupt] |
| 1487 | unsafe fn #irq () { | 1487 | unsafe fn #irq () { |
| 1488 | #( | 1488 | #( |
| 1489 | <crate::peripherals::#channels as crate::dma::sealed::ChannelInterrupt>::on_irq(); | 1489 | <crate::peripherals::#channels as crate::dma::ChannelInterrupt>::on_irq(); |
| 1490 | )* | 1490 | )* |
| 1491 | } | 1491 | } |
| 1492 | } | 1492 | } |
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index b27b99827..cecf67947 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs | |||
| @@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 33 | 33 | ||
| 34 | pub struct Vref; | 34 | pub struct Vref; |
| 35 | impl<T: Instance> AdcPin<T> for Vref {} | 35 | impl<T: Instance> AdcPin<T> for Vref {} |
| 36 | impl<T: Instance> super::sealed::AdcPin<T> for Vref { | 36 | impl<T: Instance> super::SealedAdcPin<T> for Vref { |
| 37 | fn channel(&self) -> u8 { | 37 | fn channel(&self) -> u8 { |
| 38 | 17 | 38 | 17 |
| 39 | } | 39 | } |
| @@ -41,7 +41,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vref { | |||
| 41 | 41 | ||
| 42 | pub struct Temperature; | 42 | pub struct Temperature; |
| 43 | impl<T: Instance> AdcPin<T> for Temperature {} | 43 | impl<T: Instance> AdcPin<T> for Temperature {} |
| 44 | impl<T: Instance> super::sealed::AdcPin<T> for Temperature { | 44 | impl<T: Instance> super::SealedAdcPin<T> for Temperature { |
| 45 | fn channel(&self) -> u8 { | 45 | fn channel(&self) -> u8 { |
| 46 | 16 | 46 | 16 |
| 47 | } | 47 | } |
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index efade1f64..c5581dba1 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs | |||
| @@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 33 | 33 | ||
| 34 | pub struct Vref; | 34 | pub struct Vref; |
| 35 | impl<T: Instance> AdcPin<T> for Vref {} | 35 | impl<T: Instance> AdcPin<T> for Vref {} |
| 36 | impl<T: Instance> super::sealed::AdcPin<T> for Vref { | 36 | impl<T: Instance> super::SealedAdcPin<T> for Vref { |
| 37 | fn channel(&self) -> u8 { | 37 | fn channel(&self) -> u8 { |
| 38 | 18 | 38 | 18 |
| 39 | } | 39 | } |
| @@ -48,7 +48,7 @@ impl Vref { | |||
| 48 | 48 | ||
| 49 | pub struct Temperature; | 49 | pub struct Temperature; |
| 50 | impl<T: Instance> AdcPin<T> for Temperature {} | 50 | impl<T: Instance> AdcPin<T> for Temperature {} |
| 51 | impl<T: Instance> super::sealed::AdcPin<T> for Temperature { | 51 | impl<T: Instance> super::SealedAdcPin<T> for Temperature { |
| 52 | fn channel(&self) -> u8 { | 52 | fn channel(&self) -> u8 { |
| 53 | 16 | 53 | 16 |
| 54 | } | 54 | } |
| @@ -102,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | fn freq() -> Hertz { | 104 | fn freq() -> Hertz { |
| 105 | <T as crate::rcc::sealed::RccPeripheral>::frequency() | 105 | <T as crate::rcc::SealedRccPeripheral>::frequency() |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | pub fn sample_time_for_us(&self, us: u32) -> SampleTime { | 108 | pub fn sample_time_for_us(&self, us: u32) -> SampleTime { |
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs index f842893fa..672ace04f 100644 --- a/embassy-stm32/src/adc/f3_v1_1.rs +++ b/embassy-stm32/src/adc/f3_v1_1.rs | |||
| @@ -65,7 +65,7 @@ fn update_vref<T: Instance>(op: i8) { | |||
| 65 | 65 | ||
| 66 | pub struct Vref<T: Instance>(core::marker::PhantomData<T>); | 66 | pub struct Vref<T: Instance>(core::marker::PhantomData<T>); |
| 67 | impl<T: Instance> AdcPin<T> for Vref<T> {} | 67 | impl<T: Instance> AdcPin<T> for Vref<T> {} |
| 68 | impl<T: Instance> super::sealed::AdcPin<T> for Vref<T> { | 68 | impl<T: Instance> super::SealedAdcPin<T> for Vref<T> { |
| 69 | fn channel(&self) -> u8 { | 69 | fn channel(&self) -> u8 { |
| 70 | 17 | 70 | 17 |
| 71 | } | 71 | } |
| @@ -124,7 +124,7 @@ impl<T: Instance> Drop for Vref<T> { | |||
| 124 | 124 | ||
| 125 | pub struct Temperature<T: Instance>(core::marker::PhantomData<T>); | 125 | pub struct Temperature<T: Instance>(core::marker::PhantomData<T>); |
| 126 | impl<T: Instance> AdcPin<T> for Temperature<T> {} | 126 | impl<T: Instance> AdcPin<T> for Temperature<T> {} |
| 127 | impl<T: Instance> super::sealed::AdcPin<T> for Temperature<T> { | 127 | impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> { |
| 128 | fn channel(&self) -> u8 { | 128 | fn channel(&self) -> u8 { |
| 129 | 16 | 129 | 16 |
| 130 | } | 130 | } |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 0d0d40549..ead2357ce 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -17,6 +17,8 @@ mod _version; | |||
| 17 | #[allow(unused)] | 17 | #[allow(unused)] |
| 18 | #[cfg(not(adc_f3_v2))] | 18 | #[cfg(not(adc_f3_v2))] |
| 19 | pub use _version::*; | 19 | pub use _version::*; |
| 20 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] | ||
| 21 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 20 | 22 | ||
| 21 | #[cfg(not(any(adc_f1, adc_f3_v2)))] | 23 | #[cfg(not(any(adc_f1, adc_f3_v2)))] |
| 22 | pub use crate::pac::adc::vals::Res as Resolution; | 24 | pub use crate::pac::adc::vals::Res as Resolution; |
| @@ -31,63 +33,65 @@ pub struct Adc<'d, T: Instance> { | |||
| 31 | sample_time: SampleTime, | 33 | sample_time: SampleTime, |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | pub(crate) mod sealed { | 36 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 35 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] | 37 | pub struct State { |
| 36 | use embassy_sync::waitqueue::AtomicWaker; | 38 | pub waker: AtomicWaker, |
| 37 | 39 | } | |
| 38 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] | ||
| 39 | pub struct State { | ||
| 40 | pub waker: AtomicWaker, | ||
| 41 | } | ||
| 42 | 40 | ||
| 43 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] | 41 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 44 | impl State { | 42 | impl State { |
| 45 | pub const fn new() -> Self { | 43 | pub const fn new() -> Self { |
| 46 | Self { | 44 | Self { |
| 47 | waker: AtomicWaker::new(), | 45 | waker: AtomicWaker::new(), |
| 48 | } | ||
| 49 | } | 46 | } |
| 50 | } | 47 | } |
| 48 | } | ||
| 51 | 49 | ||
| 52 | pub trait InterruptableInstance { | 50 | trait SealedInstance { |
| 53 | type Interrupt: crate::interrupt::typelevel::Interrupt; | 51 | #[allow(unused)] |
| 54 | } | 52 | fn regs() -> crate::pac::adc::Adc; |
| 55 | 53 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] | |
| 56 | pub trait Instance: InterruptableInstance { | 54 | fn common_regs() -> crate::pac::adccommon::AdcCommon; |
| 57 | fn regs() -> crate::pac::adc::Adc; | 55 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 58 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] | 56 | fn state() -> &'static State; |
| 59 | fn common_regs() -> crate::pac::adccommon::AdcCommon; | 57 | } |
| 60 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] | ||
| 61 | fn state() -> &'static State; | ||
| 62 | } | ||
| 63 | 58 | ||
| 64 | pub trait AdcPin<T: Instance> { | 59 | pub(crate) trait SealedAdcPin<T: Instance> { |
| 65 | #[cfg(any(adc_v1, adc_l0, adc_v2))] | 60 | #[cfg(any(adc_v1, adc_l0, adc_v2))] |
| 66 | fn set_as_analog(&mut self) {} | 61 | fn set_as_analog(&mut self) {} |
| 67 | 62 | ||
| 68 | fn channel(&self) -> u8; | 63 | #[allow(unused)] |
| 69 | } | 64 | fn channel(&self) -> u8; |
| 65 | } | ||
| 70 | 66 | ||
| 71 | pub trait InternalChannel<T> { | 67 | trait SealedInternalChannel<T> { |
| 72 | fn channel(&self) -> u8; | 68 | #[allow(unused)] |
| 73 | } | 69 | fn channel(&self) -> u8; |
| 74 | } | 70 | } |
| 75 | 71 | ||
| 76 | /// ADC instance. | 72 | /// ADC instance. |
| 77 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))] | 73 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))] |
| 78 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} | 74 | #[allow(private_bounds)] |
| 75 | pub trait Instance: SealedInstance + crate::Peripheral<P = Self> { | ||
| 76 | type Interrupt: crate::interrupt::typelevel::Interrupt; | ||
| 77 | } | ||
| 79 | /// ADC instance. | 78 | /// ADC instance. |
| 80 | #[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))] | 79 | #[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))] |
| 81 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} | 80 | #[allow(private_bounds)] |
| 81 | pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { | ||
| 82 | type Interrupt: crate::interrupt::typelevel::Interrupt; | ||
| 83 | } | ||
| 82 | 84 | ||
| 83 | /// ADC pin. | 85 | /// ADC pin. |
| 84 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} | 86 | #[allow(private_bounds)] |
| 87 | pub trait AdcPin<T: Instance>: SealedAdcPin<T> {} | ||
| 85 | /// ADC internal channel. | 88 | /// ADC internal channel. |
| 86 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} | 89 | #[allow(private_bounds)] |
| 90 | pub trait InternalChannel<T>: SealedInternalChannel<T> {} | ||
| 87 | 91 | ||
| 88 | foreach_adc!( | 92 | foreach_adc!( |
| 89 | ($inst:ident, $common_inst:ident, $clock:ident) => { | 93 | ($inst:ident, $common_inst:ident, $clock:ident) => { |
| 90 | impl crate::adc::sealed::Instance for peripherals::$inst { | 94 | impl crate::adc::SealedInstance for peripherals::$inst { |
| 91 | fn regs() -> crate::pac::adc::Adc { | 95 | fn regs() -> crate::pac::adc::Adc { |
| 92 | crate::pac::$inst | 96 | crate::pac::$inst |
| 93 | } | 97 | } |
| @@ -98,21 +102,15 @@ foreach_adc!( | |||
| 98 | } | 102 | } |
| 99 | 103 | ||
| 100 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] | 104 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 101 | fn state() -> &'static sealed::State { | 105 | fn state() -> &'static State { |
| 102 | static STATE: sealed::State = sealed::State::new(); | 106 | static STATE: State = State::new(); |
| 103 | &STATE | 107 | &STATE |
| 104 | } | 108 | } |
| 105 | } | 109 | } |
| 106 | 110 | ||
| 107 | foreach_interrupt!( | 111 | impl crate::adc::Instance for peripherals::$inst { |
| 108 | ($inst,adc,ADC,GLOBAL,$irq:ident) => { | 112 | type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL; |
| 109 | impl sealed::InterruptableInstance for peripherals::$inst { | 113 | } |
| 110 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 111 | } | ||
| 112 | }; | ||
| 113 | ); | ||
| 114 | |||
| 115 | impl crate::adc::Instance for peripherals::$inst {} | ||
| 116 | }; | 114 | }; |
| 117 | ); | 115 | ); |
| 118 | 116 | ||
| @@ -120,10 +118,10 @@ macro_rules! impl_adc_pin { | |||
| 120 | ($inst:ident, $pin:ident, $ch:expr) => { | 118 | ($inst:ident, $pin:ident, $ch:expr) => { |
| 121 | impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} | 119 | impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} |
| 122 | 120 | ||
| 123 | impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin { | 121 | impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin { |
| 124 | #[cfg(any(adc_v1, adc_l0, adc_v2))] | 122 | #[cfg(any(adc_v1, adc_l0, adc_v2))] |
| 125 | fn set_as_analog(&mut self) { | 123 | fn set_as_analog(&mut self) { |
| 126 | <Self as crate::gpio::sealed::Pin>::set_as_analog(self); | 124 | <Self as crate::gpio::SealedPin>::set_as_analog(self); |
| 127 | } | 125 | } |
| 128 | 126 | ||
| 129 | fn channel(&self) -> u8 { | 127 | fn channel(&self) -> u8 { |
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index a8dc6ce98..e9b46be80 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs | |||
| @@ -39,7 +39,7 @@ pub struct Vbat; | |||
| 39 | impl AdcPin<ADC> for Vbat {} | 39 | impl AdcPin<ADC> for Vbat {} |
| 40 | 40 | ||
| 41 | #[cfg(not(adc_l0))] | 41 | #[cfg(not(adc_l0))] |
| 42 | impl super::sealed::AdcPin<ADC> for Vbat { | 42 | impl super::SealedAdcPin<ADC> for Vbat { |
| 43 | fn channel(&self) -> u8 { | 43 | fn channel(&self) -> u8 { |
| 44 | 18 | 44 | 18 |
| 45 | } | 45 | } |
| @@ -47,7 +47,7 @@ impl super::sealed::AdcPin<ADC> for Vbat { | |||
| 47 | 47 | ||
| 48 | pub struct Vref; | 48 | pub struct Vref; |
| 49 | impl AdcPin<ADC> for Vref {} | 49 | impl AdcPin<ADC> for Vref {} |
| 50 | impl super::sealed::AdcPin<ADC> for Vref { | 50 | impl super::SealedAdcPin<ADC> for Vref { |
| 51 | fn channel(&self) -> u8 { | 51 | fn channel(&self) -> u8 { |
| 52 | 17 | 52 | 17 |
| 53 | } | 53 | } |
| @@ -55,7 +55,7 @@ impl super::sealed::AdcPin<ADC> for Vref { | |||
| 55 | 55 | ||
| 56 | pub struct Temperature; | 56 | pub struct Temperature; |
| 57 | impl AdcPin<ADC> for Temperature {} | 57 | impl AdcPin<ADC> for Temperature {} |
| 58 | impl super::sealed::AdcPin<ADC> for Temperature { | 58 | impl super::SealedAdcPin<ADC> for Temperature { |
| 59 | fn channel(&self) -> u8 { | 59 | fn channel(&self) -> u8 { |
| 60 | 16 | 60 | 16 |
| 61 | } | 61 | } |
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index f6f7dbfcc..a43eb72db 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs | |||
| @@ -16,7 +16,7 @@ pub const ADC_POWERUP_TIME_US: u32 = 3; | |||
| 16 | 16 | ||
| 17 | pub struct VrefInt; | 17 | pub struct VrefInt; |
| 18 | impl AdcPin<ADC1> for VrefInt {} | 18 | impl AdcPin<ADC1> for VrefInt {} |
| 19 | impl super::sealed::AdcPin<ADC1> for VrefInt { | 19 | impl super::SealedAdcPin<ADC1> for VrefInt { |
| 20 | fn channel(&self) -> u8 { | 20 | fn channel(&self) -> u8 { |
| 21 | 17 | 21 | 17 |
| 22 | } | 22 | } |
| @@ -31,7 +31,7 @@ impl VrefInt { | |||
| 31 | 31 | ||
| 32 | pub struct Temperature; | 32 | pub struct Temperature; |
| 33 | impl AdcPin<ADC1> for Temperature {} | 33 | impl AdcPin<ADC1> for Temperature {} |
| 34 | impl super::sealed::AdcPin<ADC1> for Temperature { | 34 | impl super::SealedAdcPin<ADC1> for Temperature { |
| 35 | fn channel(&self) -> u8 { | 35 | fn channel(&self) -> u8 { |
| 36 | cfg_if::cfg_if! { | 36 | cfg_if::cfg_if! { |
| 37 | if #[cfg(any(stm32f2, stm32f40, stm32f41))] { | 37 | if #[cfg(any(stm32f2, stm32f40, stm32f41))] { |
| @@ -52,7 +52,7 @@ impl Temperature { | |||
| 52 | 52 | ||
| 53 | pub struct Vbat; | 53 | pub struct Vbat; |
| 54 | impl AdcPin<ADC1> for Vbat {} | 54 | impl AdcPin<ADC1> for Vbat {} |
| 55 | impl super::sealed::AdcPin<ADC1> for Vbat { | 55 | impl super::SealedAdcPin<ADC1> for Vbat { |
| 56 | fn channel(&self) -> u8 { | 56 | fn channel(&self) -> u8 { |
| 57 | 18 | 57 | 18 |
| 58 | } | 58 | } |
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 5f3512cad..8c9b47197 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs | |||
| @@ -12,7 +12,7 @@ pub const VREF_CALIB_MV: u32 = 3000; | |||
| 12 | 12 | ||
| 13 | pub struct VrefInt; | 13 | pub struct VrefInt; |
| 14 | impl<T: Instance> AdcPin<T> for VrefInt {} | 14 | impl<T: Instance> AdcPin<T> for VrefInt {} |
| 15 | impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { | 15 | impl<T: Instance> super::SealedAdcPin<T> for VrefInt { |
| 16 | fn channel(&self) -> u8 { | 16 | fn channel(&self) -> u8 { |
| 17 | cfg_if! { | 17 | cfg_if! { |
| 18 | if #[cfg(adc_g0)] { | 18 | if #[cfg(adc_g0)] { |
| @@ -29,7 +29,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { | |||
| 29 | 29 | ||
| 30 | pub struct Temperature; | 30 | pub struct Temperature; |
| 31 | impl<T: Instance> AdcPin<T> for Temperature {} | 31 | impl<T: Instance> AdcPin<T> for Temperature {} |
| 32 | impl<T: Instance> super::sealed::AdcPin<T> for Temperature { | 32 | impl<T: Instance> super::SealedAdcPin<T> for Temperature { |
| 33 | fn channel(&self) -> u8 { | 33 | fn channel(&self) -> u8 { |
| 34 | cfg_if! { | 34 | cfg_if! { |
| 35 | if #[cfg(adc_g0)] { | 35 | if #[cfg(adc_g0)] { |
| @@ -46,7 +46,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature { | |||
| 46 | 46 | ||
| 47 | pub struct Vbat; | 47 | pub struct Vbat; |
| 48 | impl<T: Instance> AdcPin<T> for Vbat {} | 48 | impl<T: Instance> AdcPin<T> for Vbat {} |
| 49 | impl<T: Instance> super::sealed::AdcPin<T> for Vbat { | 49 | impl<T: Instance> super::SealedAdcPin<T> for Vbat { |
| 50 | fn channel(&self) -> u8 { | 50 | fn channel(&self) -> u8 { |
| 51 | cfg_if! { | 51 | cfg_if! { |
| 52 | if #[cfg(adc_g0)] { | 52 | if #[cfg(adc_g0)] { |
| @@ -65,7 +65,7 @@ cfg_if! { | |||
| 65 | if #[cfg(adc_h5)] { | 65 | if #[cfg(adc_h5)] { |
| 66 | pub struct VddCore; | 66 | pub struct VddCore; |
| 67 | impl<T: Instance> AdcPin<T> for VddCore {} | 67 | impl<T: Instance> AdcPin<T> for VddCore {} |
| 68 | impl<T: Instance> super::sealed::AdcPin<T> for VddCore { | 68 | impl<T: Instance> super::SealedAdcPin<T> for VddCore { |
| 69 | fn channel(&self) -> u8 { | 69 | fn channel(&self) -> u8 { |
| 70 | 6 | 70 | 6 |
| 71 | } | 71 | } |
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index 3fd047375..1ae25bea2 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs | |||
| @@ -35,7 +35,7 @@ const VBAT_CHANNEL: u8 = 17; | |||
| 35 | /// Internal voltage reference channel. | 35 | /// Internal voltage reference channel. |
| 36 | pub struct VrefInt; | 36 | pub struct VrefInt; |
| 37 | impl<T: Instance> InternalChannel<T> for VrefInt {} | 37 | impl<T: Instance> InternalChannel<T> for VrefInt {} |
| 38 | impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt { | 38 | impl<T: Instance> super::SealedInternalChannel<T> for VrefInt { |
| 39 | fn channel(&self) -> u8 { | 39 | fn channel(&self) -> u8 { |
| 40 | VREF_CHANNEL | 40 | VREF_CHANNEL |
| 41 | } | 41 | } |
| @@ -44,7 +44,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt { | |||
| 44 | /// Internal temperature channel. | 44 | /// Internal temperature channel. |
| 45 | pub struct Temperature; | 45 | pub struct Temperature; |
| 46 | impl<T: Instance> InternalChannel<T> for Temperature {} | 46 | impl<T: Instance> InternalChannel<T> for Temperature {} |
| 47 | impl<T: Instance> super::sealed::InternalChannel<T> for Temperature { | 47 | impl<T: Instance> super::SealedInternalChannel<T> for Temperature { |
| 48 | fn channel(&self) -> u8 { | 48 | fn channel(&self) -> u8 { |
| 49 | TEMP_CHANNEL | 49 | TEMP_CHANNEL |
| 50 | } | 50 | } |
| @@ -53,7 +53,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Temperature { | |||
| 53 | /// Internal battery voltage channel. | 53 | /// Internal battery voltage channel. |
| 54 | pub struct Vbat; | 54 | pub struct Vbat; |
| 55 | impl<T: Instance> InternalChannel<T> for Vbat {} | 55 | impl<T: Instance> InternalChannel<T> for Vbat {} |
| 56 | impl<T: Instance> super::sealed::InternalChannel<T> for Vbat { | 56 | impl<T: Instance> super::SealedInternalChannel<T> for Vbat { |
| 57 | fn channel(&self) -> u8 { | 57 | fn channel(&self) -> u8 { |
| 58 | VBAT_CHANNEL | 58 | VBAT_CHANNEL |
| 59 | } | 59 | } |
| @@ -276,7 +276,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 276 | pub fn read<P>(&mut self, pin: &mut P) -> u16 | 276 | pub fn read<P>(&mut self, pin: &mut P) -> u16 |
| 277 | where | 277 | where |
| 278 | P: AdcPin<T>, | 278 | P: AdcPin<T>, |
| 279 | P: crate::gpio::sealed::Pin, | 279 | P: crate::gpio::Pin, |
| 280 | { | 280 | { |
| 281 | pin.set_as_analog(); | 281 | pin.set_as_analog(); |
| 282 | 282 | ||
diff --git a/embassy-stm32/src/can/bx/mod.rs b/embassy-stm32/src/can/bx/mod.rs index 33e702c6e..a369ae6fd 100644 --- a/embassy-stm32/src/can/bx/mod.rs +++ b/embassy-stm32/src/can/bx/mod.rs | |||
| @@ -28,7 +28,7 @@ pub mod filter; | |||
| 28 | 28 | ||
| 29 | #[allow(clippy::all)] // generated code | 29 | #[allow(clippy::all)] // generated code |
| 30 | use core::cmp::{Ord, Ordering}; | 30 | use core::cmp::{Ord, Ordering}; |
| 31 | use core::convert::{Infallible, Into, TryInto}; | 31 | use core::convert::Infallible; |
| 32 | use core::marker::PhantomData; | 32 | use core::marker::PhantomData; |
| 33 | use core::mem; | 33 | use core::mem; |
| 34 | 34 | ||
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index bb7cc3d7f..017c5110d 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::AsMut; | ||
| 2 | use core::future::poll_fn; | 1 | use core::future::poll_fn; |
| 3 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 4 | use core::ops::{Deref, DerefMut}; | 3 | use core::ops::{Deref, DerefMut}; |
| @@ -8,9 +7,12 @@ pub mod bx; | |||
| 8 | 7 | ||
| 9 | pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId}; | 8 | pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId}; |
| 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 11 | use embassy_sync::channel::Channel; | ||
| 12 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 11 | use futures::FutureExt; | 13 | use futures::FutureExt; |
| 12 | 14 | ||
| 13 | use crate::gpio::sealed::AFType; | 15 | use crate::gpio::AFType; |
| 14 | use crate::interrupt::typelevel::Interrupt; | 16 | use crate::interrupt::typelevel::Interrupt; |
| 15 | use crate::pac::can::vals::{Ide, Lec}; | 17 | use crate::pac::can::vals::{Ide, Lec}; |
| 16 | use crate::rcc::RccPeripheral; | 18 | use crate::rcc::RccPeripheral; |
| @@ -486,37 +488,30 @@ impl<'d, T: Instance> DerefMut for Can<'d, T> { | |||
| 486 | } | 488 | } |
| 487 | } | 489 | } |
| 488 | 490 | ||
| 489 | pub(crate) mod sealed { | 491 | struct State { |
| 490 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 492 | pub tx_waker: AtomicWaker, |
| 491 | use embassy_sync::channel::Channel; | 493 | pub err_waker: AtomicWaker, |
| 492 | use embassy_sync::waitqueue::AtomicWaker; | 494 | pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>, |
| 493 | 495 | } | |
| 494 | use super::Envelope; | ||
| 495 | |||
| 496 | pub struct State { | ||
| 497 | pub tx_waker: AtomicWaker, | ||
| 498 | pub err_waker: AtomicWaker, | ||
| 499 | pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>, | ||
| 500 | } | ||
| 501 | 496 | ||
| 502 | impl State { | 497 | impl State { |
| 503 | pub const fn new() -> Self { | 498 | pub const fn new() -> Self { |
| 504 | Self { | 499 | Self { |
| 505 | tx_waker: AtomicWaker::new(), | 500 | tx_waker: AtomicWaker::new(), |
| 506 | err_waker: AtomicWaker::new(), | 501 | err_waker: AtomicWaker::new(), |
| 507 | rx_queue: Channel::new(), | 502 | rx_queue: Channel::new(), |
| 508 | } | ||
| 509 | } | 503 | } |
| 510 | } | 504 | } |
| 505 | } | ||
| 511 | 506 | ||
| 512 | pub trait Instance { | 507 | trait SealedInstance { |
| 513 | fn regs() -> crate::pac::can::Can; | 508 | fn regs() -> crate::pac::can::Can; |
| 514 | fn state() -> &'static State; | 509 | fn state() -> &'static State; |
| 515 | } | ||
| 516 | } | 510 | } |
| 517 | 511 | ||
| 518 | /// CAN instance trait. | 512 | /// CAN instance trait. |
| 519 | pub trait Instance: sealed::Instance + RccPeripheral + 'static { | 513 | #[allow(private_bounds)] |
| 514 | pub trait Instance: SealedInstance + RccPeripheral + 'static { | ||
| 520 | /// TX interrupt for this instance. | 515 | /// TX interrupt for this instance. |
| 521 | type TXInterrupt: crate::interrupt::typelevel::Interrupt; | 516 | type TXInterrupt: crate::interrupt::typelevel::Interrupt; |
| 522 | /// RX0 interrupt for this instance. | 517 | /// RX0 interrupt for this instance. |
| @@ -534,14 +529,14 @@ unsafe impl<'d, T: Instance> crate::can::bx::Instance for BxcanInstance<'d, T> { | |||
| 534 | 529 | ||
| 535 | foreach_peripheral!( | 530 | foreach_peripheral!( |
| 536 | (can, $inst:ident) => { | 531 | (can, $inst:ident) => { |
| 537 | impl sealed::Instance for peripherals::$inst { | 532 | impl SealedInstance for peripherals::$inst { |
| 538 | 533 | ||
| 539 | fn regs() -> crate::pac::can::Can { | 534 | fn regs() -> crate::pac::can::Can { |
| 540 | crate::pac::$inst | 535 | crate::pac::$inst |
| 541 | } | 536 | } |
| 542 | 537 | ||
| 543 | fn state() -> &'static sealed::State { | 538 | fn state() -> &'static State { |
| 544 | static STATE: sealed::State = sealed::State::new(); | 539 | static STATE: State = State::new(); |
| 545 | &STATE | 540 | &STATE |
| 546 | } | 541 | } |
| 547 | } | 542 | } |
diff --git a/embassy-stm32/src/can/fd/message_ram/mod.rs b/embassy-stm32/src/can/fd/message_ram/mod.rs index 830edf3bb..040a999b4 100644 --- a/embassy-stm32/src/can/fd/message_ram/mod.rs +++ b/embassy-stm32/src/can/fd/message_ram/mod.rs | |||
| @@ -140,26 +140,6 @@ pub(crate) struct _TxBufferElement; | |||
| 140 | impl generic::Readable for TxBufferElementHeader {} | 140 | impl generic::Readable for TxBufferElementHeader {} |
| 141 | impl generic::Writable for TxBufferElementHeader {} | 141 | impl generic::Writable for TxBufferElementHeader {} |
| 142 | 142 | ||
| 143 | /// FdCan Message RAM instance. | ||
| 144 | /// | ||
| 145 | /// # Safety | ||
| 146 | /// | ||
| 147 | /// It is only safe to implement this trait, when: | ||
| 148 | /// | ||
| 149 | /// * The implementing type has ownership of the Message RAM, preventing any | ||
| 150 | /// other accesses to the register block. | ||
| 151 | /// * `MSG_RAM` is a pointer to the Message RAM block and can be safely accessed | ||
| 152 | /// for as long as ownership or a borrow of the implementing type is present. | ||
| 153 | pub unsafe trait Instance { | ||
| 154 | const MSG_RAM: *mut RegisterBlock; | ||
| 155 | fn msg_ram(&self) -> &RegisterBlock { | ||
| 156 | unsafe { &*Self::MSG_RAM } | ||
| 157 | } | ||
| 158 | fn msg_ram_mut(&mut self) -> &mut RegisterBlock { | ||
| 159 | unsafe { &mut *Self::MSG_RAM } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | // Ensure the RegisterBlock is the same size as on pg 1957 of RM0440. | 143 | // Ensure the RegisterBlock is the same size as on pg 1957 of RM0440. |
| 164 | static_assertions::assert_eq_size!(Filters, [u32; 28 + 16]); | 144 | static_assertions::assert_eq_size!(Filters, [u32; 28 + 16]); |
| 165 | static_assertions::assert_eq_size!(Receive, [u32; 54]); | 145 | static_assertions::assert_eq_size!(Receive, [u32; 54]); |
diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs index 682e13f4b..76b76afe1 100644 --- a/embassy-stm32/src/can/fd/peripheral.rs +++ b/embassy-stm32/src/can/fd/peripheral.rs | |||
| @@ -325,17 +325,6 @@ impl Registers { | |||
| 325 | */ | 325 | */ |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | /// Disables the CAN interface and returns back the raw peripheral it was created from. | ||
| 329 | #[inline] | ||
| 330 | pub fn free(mut self) { | ||
| 331 | //self.disable_interrupts(Interrupts::all()); | ||
| 332 | |||
| 333 | //TODO check this! | ||
| 334 | self.enter_init_mode(); | ||
| 335 | self.set_power_down_mode(true); | ||
| 336 | //self.control.instance | ||
| 337 | } | ||
| 338 | |||
| 339 | /// Applies the settings of a new FdCanConfig See [`FdCanConfig`] | 328 | /// Applies the settings of a new FdCanConfig See [`FdCanConfig`] |
| 340 | #[inline] | 329 | #[inline] |
| 341 | pub fn apply_config(&mut self, config: FdCanConfig) { | 330 | pub fn apply_config(&mut self, config: FdCanConfig) { |
| @@ -419,55 +408,6 @@ impl Registers { | |||
| 419 | self.leave_init_mode(config); | 408 | self.leave_init_mode(config); |
| 420 | } | 409 | } |
| 421 | 410 | ||
| 422 | /// Moves out of ConfigMode and into InternalLoopbackMode | ||
| 423 | #[inline] | ||
| 424 | pub fn into_internal_loopback(mut self, config: FdCanConfig) { | ||
| 425 | self.set_loopback_mode(LoopbackMode::Internal); | ||
| 426 | self.leave_init_mode(config); | ||
| 427 | } | ||
| 428 | |||
| 429 | /// Moves out of ConfigMode and into ExternalLoopbackMode | ||
| 430 | #[inline] | ||
| 431 | pub fn into_external_loopback(mut self, config: FdCanConfig) { | ||
| 432 | self.set_loopback_mode(LoopbackMode::External); | ||
| 433 | self.leave_init_mode(config); | ||
| 434 | } | ||
| 435 | |||
| 436 | /// Moves out of ConfigMode and into RestrictedOperationMode | ||
| 437 | #[inline] | ||
| 438 | pub fn into_restricted(mut self, config: FdCanConfig) { | ||
| 439 | self.set_restricted_operations(true); | ||
| 440 | self.leave_init_mode(config); | ||
| 441 | } | ||
| 442 | |||
| 443 | /// Moves out of ConfigMode and into NormalOperationMode | ||
| 444 | #[inline] | ||
| 445 | pub fn into_normal(mut self, config: FdCanConfig) { | ||
| 446 | self.set_normal_operations(true); | ||
| 447 | self.leave_init_mode(config); | ||
| 448 | } | ||
| 449 | |||
| 450 | /// Moves out of ConfigMode and into BusMonitoringMode | ||
| 451 | #[inline] | ||
| 452 | pub fn into_bus_monitoring(mut self, config: FdCanConfig) { | ||
| 453 | self.set_bus_monitoring_mode(true); | ||
| 454 | self.leave_init_mode(config); | ||
| 455 | } | ||
| 456 | |||
| 457 | /// Moves out of ConfigMode and into Testmode | ||
| 458 | #[inline] | ||
| 459 | pub fn into_test_mode(mut self, config: FdCanConfig) { | ||
| 460 | self.set_test_mode(true); | ||
| 461 | self.leave_init_mode(config); | ||
| 462 | } | ||
| 463 | |||
| 464 | /// Moves out of ConfigMode and into PoweredDownmode | ||
| 465 | #[inline] | ||
| 466 | pub fn into_powered_down(mut self, config: FdCanConfig) { | ||
| 467 | self.set_power_down_mode(true); | ||
| 468 | self.leave_init_mode(config); | ||
| 469 | } | ||
| 470 | |||
| 471 | /// Configures the bit timings. | 411 | /// Configures the bit timings. |
| 472 | /// | 412 | /// |
| 473 | /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter | 413 | /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter |
| @@ -565,6 +505,7 @@ impl Registers { | |||
| 565 | 505 | ||
| 566 | /// Configures and resets the timestamp counter | 506 | /// Configures and resets the timestamp counter |
| 567 | #[inline] | 507 | #[inline] |
| 508 | #[allow(unused)] | ||
| 568 | pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) { | 509 | pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) { |
| 569 | #[cfg(stm32h7)] | 510 | #[cfg(stm32h7)] |
| 570 | let (tcp, tss) = match select { | 511 | let (tcp, tss) = match select { |
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index fe8969a5a..4ea036ab4 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs | |||
| @@ -5,10 +5,11 @@ use core::task::Poll; | |||
| 5 | 5 | ||
| 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 6 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 7 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 7 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 8 | use embassy_sync::channel::Channel; | 8 | use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 9 | 10 | ||
| 10 | use crate::can::fd::peripheral::Registers; | 11 | use crate::can::fd::peripheral::Registers; |
| 11 | use crate::gpio::sealed::AFType; | 12 | use crate::gpio::AFType; |
| 12 | use crate::interrupt::typelevel::Interrupt; | 13 | use crate::interrupt::typelevel::Interrupt; |
| 13 | use crate::rcc::RccPeripheral; | 14 | use crate::rcc::RccPeripheral; |
| 14 | use crate::{interrupt, peripherals, Peripheral}; | 15 | use crate::{interrupt, peripherals, Peripheral}; |
| @@ -53,8 +54,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup | |||
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | match &T::state().tx_mode { | 56 | match &T::state().tx_mode { |
| 56 | sealed::TxMode::NonBuffered(waker) => waker.wake(), | 57 | TxMode::NonBuffered(waker) => waker.wake(), |
| 57 | sealed::TxMode::ClassicBuffered(buf) => { | 58 | TxMode::ClassicBuffered(buf) => { |
| 58 | if !T::registers().tx_queue_is_full() { | 59 | if !T::registers().tx_queue_is_full() { |
| 59 | match buf.tx_receiver.try_receive() { | 60 | match buf.tx_receiver.try_receive() { |
| 60 | Ok(frame) => { | 61 | Ok(frame) => { |
| @@ -64,7 +65,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup | |||
| 64 | } | 65 | } |
| 65 | } | 66 | } |
| 66 | } | 67 | } |
| 67 | sealed::TxMode::FdBuffered(buf) => { | 68 | TxMode::FdBuffered(buf) => { |
| 68 | if !T::registers().tx_queue_is_full() { | 69 | if !T::registers().tx_queue_is_full() { |
| 69 | match buf.tx_receiver.try_receive() { | 70 | match buf.tx_receiver.try_receive() { |
| 70 | Ok(frame) => { | 71 | Ok(frame) => { |
| @@ -467,14 +468,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 467 | fn setup(self) -> Self { | 468 | fn setup(self) -> Self { |
| 468 | // We don't want interrupts being processed while we change modes. | 469 | // We don't want interrupts being processed while we change modes. |
| 469 | critical_section::with(|_| unsafe { | 470 | critical_section::with(|_| unsafe { |
| 470 | let rx_inner = sealed::ClassicBufferedRxInner { | 471 | let rx_inner = ClassicBufferedRxInner { |
| 471 | rx_sender: self.rx_buf.sender().into(), | 472 | rx_sender: self.rx_buf.sender().into(), |
| 472 | }; | 473 | }; |
| 473 | let tx_inner = sealed::ClassicBufferedTxInner { | 474 | let tx_inner = ClassicBufferedTxInner { |
| 474 | tx_receiver: self.tx_buf.receiver().into(), | 475 | tx_receiver: self.tx_buf.receiver().into(), |
| 475 | }; | 476 | }; |
| 476 | T::mut_state().rx_mode = sealed::RxMode::ClassicBuffered(rx_inner); | 477 | T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner); |
| 477 | T::mut_state().tx_mode = sealed::TxMode::ClassicBuffered(tx_inner); | 478 | T::mut_state().tx_mode = TxMode::ClassicBuffered(tx_inner); |
| 478 | }); | 479 | }); |
| 479 | self | 480 | self |
| 480 | } | 481 | } |
| @@ -509,8 +510,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr | |||
| 509 | { | 510 | { |
| 510 | fn drop(&mut self) { | 511 | fn drop(&mut self) { |
| 511 | critical_section::with(|_| unsafe { | 512 | critical_section::with(|_| unsafe { |
| 512 | T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | 513 | T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); |
| 513 | T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | 514 | T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); |
| 514 | }); | 515 | }); |
| 515 | } | 516 | } |
| 516 | } | 517 | } |
| @@ -585,14 +586,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 585 | fn setup(self) -> Self { | 586 | fn setup(self) -> Self { |
| 586 | // We don't want interrupts being processed while we change modes. | 587 | // We don't want interrupts being processed while we change modes. |
| 587 | critical_section::with(|_| unsafe { | 588 | critical_section::with(|_| unsafe { |
| 588 | let rx_inner = sealed::FdBufferedRxInner { | 589 | let rx_inner = FdBufferedRxInner { |
| 589 | rx_sender: self.rx_buf.sender().into(), | 590 | rx_sender: self.rx_buf.sender().into(), |
| 590 | }; | 591 | }; |
| 591 | let tx_inner = sealed::FdBufferedTxInner { | 592 | let tx_inner = FdBufferedTxInner { |
| 592 | tx_receiver: self.tx_buf.receiver().into(), | 593 | tx_receiver: self.tx_buf.receiver().into(), |
| 593 | }; | 594 | }; |
| 594 | T::mut_state().rx_mode = sealed::RxMode::FdBuffered(rx_inner); | 595 | T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner); |
| 595 | T::mut_state().tx_mode = sealed::TxMode::FdBuffered(tx_inner); | 596 | T::mut_state().tx_mode = TxMode::FdBuffered(tx_inner); |
| 596 | }); | 597 | }); |
| 597 | self | 598 | self |
| 598 | } | 599 | } |
| @@ -627,8 +628,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr | |||
| 627 | { | 628 | { |
| 628 | fn drop(&mut self) { | 629 | fn drop(&mut self) { |
| 629 | critical_section::with(|_| unsafe { | 630 | critical_section::with(|_| unsafe { |
| 630 | T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | 631 | T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); |
| 631 | T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); | 632 | T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); |
| 632 | }); | 633 | }); |
| 633 | } | 634 | } |
| 634 | } | 635 | } |
| @@ -677,192 +678,180 @@ impl<'c, 'd, T: Instance> FdcanRx<'d, T> { | |||
| 677 | } | 678 | } |
| 678 | } | 679 | } |
| 679 | 680 | ||
| 680 | pub(crate) mod sealed { | 681 | struct ClassicBufferedRxInner { |
| 681 | use core::future::poll_fn; | 682 | rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>, |
| 682 | use core::task::Poll; | 683 | } |
| 683 | 684 | struct ClassicBufferedTxInner { | |
| 684 | use embassy_sync::channel::{DynamicReceiver, DynamicSender}; | 685 | tx_receiver: DynamicReceiver<'static, ClassicFrame>, |
| 685 | use embassy_sync::waitqueue::AtomicWaker; | 686 | } |
| 686 | |||
| 687 | use super::CanHeader; | ||
| 688 | use crate::can::_version::{BusError, Timestamp}; | ||
| 689 | use crate::can::frame::{ClassicFrame, FdFrame}; | ||
| 690 | |||
| 691 | pub struct ClassicBufferedRxInner { | ||
| 692 | pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>, | ||
| 693 | } | ||
| 694 | pub struct ClassicBufferedTxInner { | ||
| 695 | pub tx_receiver: DynamicReceiver<'static, ClassicFrame>, | ||
| 696 | } | ||
| 697 | 687 | ||
| 698 | pub struct FdBufferedRxInner { | 688 | struct FdBufferedRxInner { |
| 699 | pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>, | 689 | rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>, |
| 700 | } | 690 | } |
| 701 | pub struct FdBufferedTxInner { | 691 | struct FdBufferedTxInner { |
| 702 | pub tx_receiver: DynamicReceiver<'static, FdFrame>, | 692 | tx_receiver: DynamicReceiver<'static, FdFrame>, |
| 703 | } | 693 | } |
| 704 | 694 | ||
| 705 | pub enum RxMode { | 695 | enum RxMode { |
| 706 | NonBuffered(AtomicWaker), | 696 | NonBuffered(AtomicWaker), |
| 707 | ClassicBuffered(ClassicBufferedRxInner), | 697 | ClassicBuffered(ClassicBufferedRxInner), |
| 708 | FdBuffered(FdBufferedRxInner), | 698 | FdBuffered(FdBufferedRxInner), |
| 709 | } | 699 | } |
| 710 | 700 | ||
| 711 | impl RxMode { | 701 | impl RxMode { |
| 712 | pub fn register(&self, arg: &core::task::Waker) { | 702 | fn register(&self, arg: &core::task::Waker) { |
| 713 | match self { | 703 | match self { |
| 714 | RxMode::NonBuffered(waker) => waker.register(arg), | 704 | RxMode::NonBuffered(waker) => waker.register(arg), |
| 715 | _ => { | 705 | _ => { |
| 716 | panic!("Bad Mode") | 706 | panic!("Bad Mode") |
| 717 | } | ||
| 718 | } | 707 | } |
| 719 | } | 708 | } |
| 709 | } | ||
| 720 | 710 | ||
| 721 | pub fn on_interrupt<T: Instance>(&self, fifonr: usize) { | 711 | fn on_interrupt<T: Instance>(&self, fifonr: usize) { |
| 722 | T::regs().ir().write(|w| w.set_rfn(fifonr, true)); | 712 | T::regs().ir().write(|w| w.set_rfn(fifonr, true)); |
| 723 | match self { | 713 | match self { |
| 724 | RxMode::NonBuffered(waker) => { | 714 | RxMode::NonBuffered(waker) => { |
| 725 | waker.wake(); | 715 | waker.wake(); |
| 726 | } | 716 | } |
| 727 | RxMode::ClassicBuffered(buf) => { | 717 | RxMode::ClassicBuffered(buf) => { |
| 728 | if let Some(result) = self.read::<T, _>() { | 718 | if let Some(result) = self.read::<T, _>() { |
| 729 | let _ = buf.rx_sender.try_send(result); | 719 | let _ = buf.rx_sender.try_send(result); |
| 730 | } | ||
| 731 | } | ||
| 732 | RxMode::FdBuffered(buf) => { | ||
| 733 | if let Some(result) = self.read::<T, _>() { | ||
| 734 | let _ = buf.rx_sender.try_send(result); | ||
| 735 | } | ||
| 736 | } | 720 | } |
| 737 | } | 721 | } |
| 738 | } | 722 | RxMode::FdBuffered(buf) => { |
| 739 | 723 | if let Some(result) = self.read::<T, _>() { | |
| 740 | fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> { | 724 | let _ = buf.rx_sender.try_send(result); |
| 741 | if let Some((msg, ts)) = T::registers().read(0) { | 725 | } |
| 742 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | ||
| 743 | Some(Ok((msg, ts))) | ||
| 744 | } else if let Some((msg, ts)) = T::registers().read(1) { | ||
| 745 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | ||
| 746 | Some(Ok((msg, ts))) | ||
| 747 | } else if let Some(err) = T::registers().curr_error() { | ||
| 748 | // TODO: this is probably wrong | ||
| 749 | Some(Err(err)) | ||
| 750 | } else { | ||
| 751 | None | ||
| 752 | } | 726 | } |
| 753 | } | 727 | } |
| 728 | } | ||
| 754 | 729 | ||
| 755 | async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> { | 730 | fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> { |
| 756 | poll_fn(|cx| { | 731 | if let Some((msg, ts)) = T::registers().read(0) { |
| 757 | T::state().err_waker.register(cx.waker()); | 732 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); |
| 758 | self.register(cx.waker()); | 733 | Some(Ok((msg, ts))) |
| 759 | match self.read::<T, _>() { | 734 | } else if let Some((msg, ts)) = T::registers().read(1) { |
| 760 | Some(result) => Poll::Ready(result), | 735 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); |
| 761 | None => Poll::Pending, | 736 | Some(Ok((msg, ts))) |
| 762 | } | 737 | } else if let Some(err) = T::registers().curr_error() { |
| 763 | }) | 738 | // TODO: this is probably wrong |
| 764 | .await | 739 | Some(Err(err)) |
| 740 | } else { | ||
| 741 | None | ||
| 765 | } | 742 | } |
| 743 | } | ||
| 766 | 744 | ||
| 767 | pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> { | 745 | async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> { |
| 768 | self.read_async::<T, _>().await | 746 | poll_fn(|cx| { |
| 769 | } | 747 | T::state().err_waker.register(cx.waker()); |
| 748 | self.register(cx.waker()); | ||
| 749 | match self.read::<T, _>() { | ||
| 750 | Some(result) => Poll::Ready(result), | ||
| 751 | None => Poll::Pending, | ||
| 752 | } | ||
| 753 | }) | ||
| 754 | .await | ||
| 755 | } | ||
| 770 | 756 | ||
| 771 | pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> { | 757 | async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> { |
| 772 | self.read_async::<T, _>().await | 758 | self.read_async::<T, _>().await |
| 773 | } | ||
| 774 | } | 759 | } |
| 775 | 760 | ||
| 776 | pub enum TxMode { | 761 | async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> { |
| 777 | NonBuffered(AtomicWaker), | 762 | self.read_async::<T, _>().await |
| 778 | ClassicBuffered(ClassicBufferedTxInner), | ||
| 779 | FdBuffered(FdBufferedTxInner), | ||
| 780 | } | 763 | } |
| 764 | } | ||
| 781 | 765 | ||
| 782 | impl TxMode { | 766 | enum TxMode { |
| 783 | pub fn register(&self, arg: &core::task::Waker) { | 767 | NonBuffered(AtomicWaker), |
| 784 | match self { | 768 | ClassicBuffered(ClassicBufferedTxInner), |
| 785 | TxMode::NonBuffered(waker) => { | 769 | FdBuffered(FdBufferedTxInner), |
| 786 | waker.register(arg); | 770 | } |
| 787 | } | 771 | |
| 788 | _ => { | 772 | impl TxMode { |
| 789 | panic!("Bad mode"); | 773 | fn register(&self, arg: &core::task::Waker) { |
| 790 | } | 774 | match self { |
| 775 | TxMode::NonBuffered(waker) => { | ||
| 776 | waker.register(arg); | ||
| 777 | } | ||
| 778 | _ => { | ||
| 779 | panic!("Bad mode"); | ||
| 791 | } | 780 | } |
| 792 | } | 781 | } |
| 782 | } | ||
| 793 | 783 | ||
| 794 | /// Queues the message to be sent but exerts backpressure. If a lower-priority | 784 | /// Queues the message to be sent but exerts backpressure. If a lower-priority |
| 795 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames | 785 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames |
| 796 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 786 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 797 | /// transmitted, then tries again. | 787 | /// transmitted, then tries again. |
| 798 | async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> { | 788 | async fn write_generic<T: Instance, F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> Option<F> { |
| 799 | poll_fn(|cx| { | 789 | poll_fn(|cx| { |
| 800 | self.register(cx.waker()); | 790 | self.register(cx.waker()); |
| 801 | 791 | ||
| 802 | if let Ok(dropped) = T::registers().write(frame) { | 792 | if let Ok(dropped) = T::registers().write(frame) { |
| 803 | return Poll::Ready(dropped); | 793 | return Poll::Ready(dropped); |
| 804 | } | 794 | } |
| 805 | 795 | ||
| 806 | // Couldn't replace any lower priority frames. Need to wait for some mailboxes | 796 | // Couldn't replace any lower priority frames. Need to wait for some mailboxes |
| 807 | // to clear. | 797 | // to clear. |
| 808 | Poll::Pending | 798 | Poll::Pending |
| 809 | }) | 799 | }) |
| 810 | .await | 800 | .await |
| 811 | } | 801 | } |
| 812 | 802 | ||
| 813 | /// Queues the message to be sent but exerts backpressure. If a lower-priority | 803 | /// Queues the message to be sent but exerts backpressure. If a lower-priority |
| 814 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames | 804 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames |
| 815 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 805 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 816 | /// transmitted, then tries again. | 806 | /// transmitted, then tries again. |
| 817 | pub async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> { | 807 | async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> { |
| 818 | self.write_generic::<T, _>(frame).await | 808 | self.write_generic::<T, _>(frame).await |
| 819 | } | 809 | } |
| 820 | 810 | ||
| 821 | /// Queues the message to be sent but exerts backpressure. If a lower-priority | 811 | /// Queues the message to be sent but exerts backpressure. If a lower-priority |
| 822 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames | 812 | /// frame is dropped from the mailbox, it is returned. If no lower-priority frames |
| 823 | /// can be replaced, this call asynchronously waits for a frame to be successfully | 813 | /// can be replaced, this call asynchronously waits for a frame to be successfully |
| 824 | /// transmitted, then tries again. | 814 | /// transmitted, then tries again. |
| 825 | pub async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> { | 815 | async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> { |
| 826 | self.write_generic::<T, _>(frame).await | 816 | self.write_generic::<T, _>(frame).await |
| 827 | } | ||
| 828 | } | 817 | } |
| 818 | } | ||
| 829 | 819 | ||
| 830 | pub struct State { | 820 | struct State { |
| 831 | pub rx_mode: RxMode, | 821 | pub rx_mode: RxMode, |
| 832 | pub tx_mode: TxMode, | 822 | pub tx_mode: TxMode, |
| 833 | pub ns_per_timer_tick: u64, | 823 | pub ns_per_timer_tick: u64, |
| 834 | 824 | ||
| 835 | pub err_waker: AtomicWaker, | 825 | pub err_waker: AtomicWaker, |
| 836 | } | 826 | } |
| 837 | 827 | ||
| 838 | impl State { | 828 | impl State { |
| 839 | pub const fn new() -> Self { | 829 | const fn new() -> Self { |
| 840 | Self { | 830 | Self { |
| 841 | rx_mode: RxMode::NonBuffered(AtomicWaker::new()), | 831 | rx_mode: RxMode::NonBuffered(AtomicWaker::new()), |
| 842 | tx_mode: TxMode::NonBuffered(AtomicWaker::new()), | 832 | tx_mode: TxMode::NonBuffered(AtomicWaker::new()), |
| 843 | ns_per_timer_tick: 0, | 833 | ns_per_timer_tick: 0, |
| 844 | err_waker: AtomicWaker::new(), | 834 | err_waker: AtomicWaker::new(), |
| 845 | } | ||
| 846 | } | 835 | } |
| 847 | } | 836 | } |
| 837 | } | ||
| 848 | 838 | ||
| 849 | pub trait Instance { | 839 | trait SealedInstance { |
| 850 | const MSG_RAM_OFFSET: usize; | 840 | const MSG_RAM_OFFSET: usize; |
| 851 | 841 | ||
| 852 | fn regs() -> &'static crate::pac::can::Fdcan; | 842 | fn regs() -> &'static crate::pac::can::Fdcan; |
| 853 | fn registers() -> crate::can::fd::peripheral::Registers; | 843 | fn registers() -> crate::can::fd::peripheral::Registers; |
| 854 | fn ram() -> &'static crate::pac::fdcanram::Fdcanram; | 844 | fn state() -> &'static State; |
| 855 | fn state() -> &'static State; | 845 | unsafe fn mut_state() -> &'static mut State; |
| 856 | unsafe fn mut_state() -> &'static mut State; | 846 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; |
| 857 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; | ||
| 858 | } | ||
| 859 | } | 847 | } |
| 860 | 848 | ||
| 861 | /// Instance trait | 849 | /// Instance trait |
| 862 | pub trait Instance: sealed::Instance + RccPeripheral + 'static { | 850 | #[allow(private_bounds)] |
| 851 | pub trait Instance: SealedInstance + RccPeripheral + 'static { | ||
| 863 | /// Interrupt 0 | 852 | /// Interrupt 0 |
| 864 | type IT0Interrupt: crate::interrupt::typelevel::Interrupt; | 853 | type IT0Interrupt: crate::interrupt::typelevel::Interrupt; |
| 865 | /// Interrupt 0 | 854 | /// Interrupt 1 |
| 866 | type IT1Interrupt: crate::interrupt::typelevel::Interrupt; | 855 | type IT1Interrupt: crate::interrupt::typelevel::Interrupt; |
| 867 | } | 856 | } |
| 868 | 857 | ||
| @@ -871,7 +860,7 @@ pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); | |||
| 871 | 860 | ||
| 872 | macro_rules! impl_fdcan { | 861 | macro_rules! impl_fdcan { |
| 873 | ($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => { | 862 | ($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => { |
| 874 | impl sealed::Instance for peripherals::$inst { | 863 | impl SealedInstance for peripherals::$inst { |
| 875 | const MSG_RAM_OFFSET: usize = $msg_ram_offset; | 864 | const MSG_RAM_OFFSET: usize = $msg_ram_offset; |
| 876 | 865 | ||
| 877 | fn regs() -> &'static crate::pac::can::Fdcan { | 866 | fn regs() -> &'static crate::pac::can::Fdcan { |
| @@ -880,14 +869,11 @@ macro_rules! impl_fdcan { | |||
| 880 | fn registers() -> Registers { | 869 | fn registers() -> Registers { |
| 881 | Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} | 870 | Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} |
| 882 | } | 871 | } |
| 883 | fn ram() -> &'static crate::pac::fdcanram::Fdcanram { | 872 | unsafe fn mut_state() -> &'static mut State { |
| 884 | &crate::pac::$msg_ram_inst | 873 | static mut STATE: State = State::new(); |
| 885 | } | 874 | &mut *core::ptr::addr_of_mut!(STATE) |
| 886 | unsafe fn mut_state() -> & 'static mut sealed::State { | ||
| 887 | static mut STATE: sealed::State = sealed::State::new(); | ||
| 888 | & mut STATE | ||
| 889 | } | 875 | } |
| 890 | fn state() -> &'static sealed::State { | 876 | fn state() -> &'static State { |
| 891 | unsafe { peripherals::$inst::mut_state() } | 877 | unsafe { peripherals::$inst::mut_state() } |
| 892 | } | 878 | } |
| 893 | 879 | ||
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index 0166ab819..f8909d438 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs | |||
| @@ -2,7 +2,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 2 | 2 | ||
| 3 | use crate::pac::CRC as PAC_CRC; | 3 | use crate::pac::CRC as PAC_CRC; |
| 4 | use crate::peripherals::CRC; | 4 | use crate::peripherals::CRC; |
| 5 | use crate::rcc::sealed::RccPeripheral; | 5 | use crate::rcc::SealedRccPeripheral; |
| 6 | use crate::Peripheral; | 6 | use crate::Peripheral; |
| 7 | 7 | ||
| 8 | /// CRC driver. | 8 | /// CRC driver. |
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs index 0c4ae55ce..46f5ea1be 100644 --- a/embassy-stm32/src/crc/v2v3.rs +++ b/embassy-stm32/src/crc/v2v3.rs | |||
| @@ -3,7 +3,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 3 | use crate::pac::crc::vals; | 3 | use crate::pac::crc::vals; |
| 4 | use crate::pac::CRC as PAC_CRC; | 4 | use crate::pac::CRC as PAC_CRC; |
| 5 | use crate::peripherals::CRC; | 5 | use crate::peripherals::CRC; |
| 6 | use crate::rcc::sealed::RccPeripheral; | 6 | use crate::rcc::SealedRccPeripheral; |
| 7 | use crate::Peripheral; | 7 | use crate::Peripheral; |
| 8 | 8 | ||
| 9 | /// CRC driver. | 9 | /// CRC driver. |
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs index 74b095b6f..18b5ec918 100644 --- a/embassy-stm32/src/cryp/mod.rs +++ b/embassy-stm32/src/cryp/mod.rs | |||
| @@ -1885,16 +1885,13 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { | |||
| 1885 | } | 1885 | } |
| 1886 | } | 1886 | } |
| 1887 | 1887 | ||
| 1888 | pub(crate) mod sealed { | 1888 | trait SealedInstance { |
| 1889 | use super::*; | 1889 | fn regs() -> pac::cryp::Cryp; |
| 1890 | |||
| 1891 | pub trait Instance { | ||
| 1892 | fn regs() -> pac::cryp::Cryp; | ||
| 1893 | } | ||
| 1894 | } | 1890 | } |
| 1895 | 1891 | ||
| 1896 | /// CRYP instance trait. | 1892 | /// CRYP instance trait. |
| 1897 | pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { | 1893 | #[allow(private_bounds)] |
| 1894 | pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { | ||
| 1898 | /// Interrupt for this CRYP instance. | 1895 | /// Interrupt for this CRYP instance. |
| 1899 | type Interrupt: interrupt::typelevel::Interrupt; | 1896 | type Interrupt: interrupt::typelevel::Interrupt; |
| 1900 | } | 1897 | } |
| @@ -1905,7 +1902,7 @@ foreach_interrupt!( | |||
| 1905 | type Interrupt = crate::interrupt::typelevel::$irq; | 1902 | type Interrupt = crate::interrupt::typelevel::$irq; |
| 1906 | } | 1903 | } |
| 1907 | 1904 | ||
| 1908 | impl sealed::Instance for peripherals::$inst { | 1905 | impl SealedInstance for peripherals::$inst { |
| 1909 | fn regs() -> crate::pac::cryp::Cryp { | 1906 | fn regs() -> crate::pac::cryp::Cryp { |
| 1910 | crate::pac::$inst | 1907 | crate::pac::$inst |
| 1911 | } | 1908 | } |
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 60f9404c2..acfed8356 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs | |||
| @@ -127,7 +127,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { | |||
| 127 | pub fn new( | 127 | pub fn new( |
| 128 | _peri: impl Peripheral<P = T> + 'd, | 128 | _peri: impl Peripheral<P = T> + 'd, |
| 129 | dma: impl Peripheral<P = DMA> + 'd, | 129 | dma: impl Peripheral<P = DMA> + 'd, |
| 130 | pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::sealed::Pin> + 'd, | 130 | pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::Pin> + 'd, |
| 131 | ) -> Self { | 131 | ) -> Self { |
| 132 | into_ref!(dma, pin); | 132 | into_ref!(dma, pin); |
| 133 | pin.set_as_analog(); | 133 | pin.set_as_analog(); |
| @@ -392,8 +392,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { | |||
| 392 | _peri: impl Peripheral<P = T> + 'd, | 392 | _peri: impl Peripheral<P = T> + 'd, |
| 393 | dma_ch1: impl Peripheral<P = DMACh1> + 'd, | 393 | dma_ch1: impl Peripheral<P = DMACh1> + 'd, |
| 394 | dma_ch2: impl Peripheral<P = DMACh2> + 'd, | 394 | dma_ch2: impl Peripheral<P = DMACh2> + 'd, |
| 395 | pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::sealed::Pin> + 'd, | 395 | pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::Pin> + 'd, |
| 396 | pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::sealed::Pin> + 'd, | 396 | pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::Pin> + 'd, |
| 397 | ) -> Self { | 397 | ) -> Self { |
| 398 | into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); | 398 | into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2); |
| 399 | pin_ch1.set_as_analog(); | 399 | pin_ch1.set_as_analog(); |
| @@ -488,14 +488,13 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { | |||
| 488 | } | 488 | } |
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | pub(crate) mod sealed { | 491 | trait SealedInstance { |
| 492 | pub trait Instance { | 492 | fn regs() -> &'static crate::pac::dac::Dac; |
| 493 | fn regs() -> &'static crate::pac::dac::Dac; | ||
| 494 | } | ||
| 495 | } | 493 | } |
| 496 | 494 | ||
| 497 | /// DAC instance. | 495 | /// DAC instance. |
| 498 | pub trait Instance: sealed::Instance + RccPeripheral + 'static {} | 496 | #[allow(private_bounds)] |
| 497 | pub trait Instance: SealedInstance + RccPeripheral + 'static {} | ||
| 499 | dma_trait!(DacDma1, Instance); | 498 | dma_trait!(DacDma1, Instance); |
| 500 | dma_trait!(DacDma2, Instance); | 499 | dma_trait!(DacDma2, Instance); |
| 501 | 500 | ||
| @@ -504,7 +503,7 @@ pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {} | |||
| 504 | 503 | ||
| 505 | foreach_peripheral!( | 504 | foreach_peripheral!( |
| 506 | (dac, $inst:ident) => { | 505 | (dac, $inst:ident) => { |
| 507 | impl crate::dac::sealed::Instance for peripherals::$inst { | 506 | impl crate::dac::SealedInstance for peripherals::$inst { |
| 508 | fn regs() -> &'static crate::pac::dac::Dac { | 507 | fn regs() -> &'static crate::pac::dac::Dac { |
| 509 | &crate::pac::$inst | 508 | &crate::pac::$inst |
| 510 | } | 509 | } |
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs index 826b04a4b..646ee2ce2 100644 --- a/embassy-stm32/src/dcmi.rs +++ b/embassy-stm32/src/dcmi.rs | |||
| @@ -7,8 +7,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | 8 | ||
| 9 | use crate::dma::Transfer; | 9 | use crate::dma::Transfer; |
| 10 | use crate::gpio::sealed::AFType; | 10 | use crate::gpio::{AFType, Speed}; |
| 11 | use crate::gpio::Speed; | ||
| 12 | use crate::interrupt::typelevel::Interrupt; | 11 | use crate::interrupt::typelevel::Interrupt; |
| 13 | use crate::{interrupt, Peripheral}; | 12 | use crate::{interrupt, Peripheral}; |
| 14 | 13 | ||
| @@ -431,14 +430,13 @@ where | |||
| 431 | } | 430 | } |
| 432 | } | 431 | } |
| 433 | 432 | ||
| 434 | mod sealed { | 433 | trait SealedInstance: crate::rcc::RccPeripheral { |
| 435 | pub trait Instance: crate::rcc::RccPeripheral { | 434 | fn regs(&self) -> crate::pac::dcmi::Dcmi; |
| 436 | fn regs(&self) -> crate::pac::dcmi::Dcmi; | ||
| 437 | } | ||
| 438 | } | 435 | } |
| 439 | 436 | ||
| 440 | /// DCMI instance. | 437 | /// DCMI instance. |
| 441 | pub trait Instance: sealed::Instance + 'static { | 438 | #[allow(private_bounds)] |
| 439 | pub trait Instance: SealedInstance + 'static { | ||
| 442 | /// Interrupt for this instance. | 440 | /// Interrupt for this instance. |
| 443 | type Interrupt: interrupt::typelevel::Interrupt; | 441 | type Interrupt: interrupt::typelevel::Interrupt; |
| 444 | } | 442 | } |
| @@ -465,7 +463,7 @@ pin_trait!(PixClkPin, Instance); | |||
| 465 | #[allow(unused)] | 463 | #[allow(unused)] |
| 466 | macro_rules! impl_peripheral { | 464 | macro_rules! impl_peripheral { |
| 467 | ($inst:ident, $irq:ident) => { | 465 | ($inst:ident, $irq:ident) => { |
| 468 | impl sealed::Instance for crate::peripherals::$inst { | 466 | impl SealedInstance for crate::peripherals::$inst { |
| 469 | fn regs(&self) -> crate::pac::dcmi::Dcmi { | 467 | fn regs(&self) -> crate::pac::dcmi::Dcmi { |
| 470 | crate::pac::$inst | 468 | crate::pac::$inst |
| 471 | } | 469 | } |
diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs index 1e9ab5944..dc7cd3a66 100644 --- a/embassy-stm32/src/dma/dmamux.rs +++ b/embassy-stm32/src/dma/dmamux.rs | |||
| @@ -19,9 +19,7 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) { | |||
| 19 | }); | 19 | }); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | pub(crate) mod dmamux_sealed { | 22 | pub(crate) trait SealedMuxChannel {} |
| 23 | pub trait MuxChannel {} | ||
| 24 | } | ||
| 25 | 23 | ||
| 26 | /// DMAMUX1 instance. | 24 | /// DMAMUX1 instance. |
| 27 | pub struct DMAMUX1; | 25 | pub struct DMAMUX1; |
| @@ -30,14 +28,15 @@ pub struct DMAMUX1; | |||
| 30 | pub struct DMAMUX2; | 28 | pub struct DMAMUX2; |
| 31 | 29 | ||
| 32 | /// DMAMUX channel trait. | 30 | /// DMAMUX channel trait. |
| 33 | pub trait MuxChannel: dmamux_sealed::MuxChannel { | 31 | #[allow(private_bounds)] |
| 32 | pub trait MuxChannel: SealedMuxChannel { | ||
| 34 | /// DMAMUX instance this channel is on. | 33 | /// DMAMUX instance this channel is on. |
| 35 | type Mux; | 34 | type Mux; |
| 36 | } | 35 | } |
| 37 | 36 | ||
| 38 | macro_rules! dmamux_channel_impl { | 37 | macro_rules! dmamux_channel_impl { |
| 39 | ($channel_peri:ident, $dmamux:ident) => { | 38 | ($channel_peri:ident, $dmamux:ident) => { |
| 40 | impl crate::dma::dmamux_sealed::MuxChannel for crate::peripherals::$channel_peri {} | 39 | impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {} |
| 41 | impl crate::dma::MuxChannel for crate::peripherals::$channel_peri { | 40 | impl crate::dma::MuxChannel for crate::peripherals::$channel_peri { |
| 42 | type Mux = crate::dma::$dmamux; | 41 | type Mux = crate::dma::$dmamux; |
| 43 | } | 42 | } |
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index d5e88a20a..7e3681469 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs | |||
| @@ -39,17 +39,18 @@ pub type Request = u8; | |||
| 39 | #[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))] | 39 | #[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))] |
| 40 | pub type Request = (); | 40 | pub type Request = (); |
| 41 | 41 | ||
| 42 | pub(crate) mod sealed { | 42 | pub(crate) trait SealedChannel { |
| 43 | pub trait Channel { | 43 | fn id(&self) -> u8; |
| 44 | fn id(&self) -> u8; | 44 | } |
| 45 | } | 45 | |
| 46 | pub trait ChannelInterrupt { | 46 | pub(crate) trait ChannelInterrupt { |
| 47 | unsafe fn on_irq(); | 47 | #[cfg_attr(not(feature = "rt"), allow(unused))] |
| 48 | } | 48 | unsafe fn on_irq(); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /// DMA channel. | 51 | /// DMA channel. |
| 52 | pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + 'static { | 52 | #[allow(private_bounds)] |
| 53 | pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static { | ||
| 53 | /// Type-erase (degrade) this pin into an `AnyChannel`. | 54 | /// Type-erase (degrade) this pin into an `AnyChannel`. |
| 54 | /// | 55 | /// |
| 55 | /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which | 56 | /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which |
| @@ -63,12 +64,12 @@ pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + ' | |||
| 63 | 64 | ||
| 64 | macro_rules! dma_channel_impl { | 65 | macro_rules! dma_channel_impl { |
| 65 | ($channel_peri:ident, $index:expr) => { | 66 | ($channel_peri:ident, $index:expr) => { |
| 66 | impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { | 67 | impl crate::dma::SealedChannel for crate::peripherals::$channel_peri { |
| 67 | fn id(&self) -> u8 { | 68 | fn id(&self) -> u8 { |
| 68 | $index | 69 | $index |
| 69 | } | 70 | } |
| 70 | } | 71 | } |
| 71 | impl crate::dma::sealed::ChannelInterrupt for crate::peripherals::$channel_peri { | 72 | impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri { |
| 72 | unsafe fn on_irq() { | 73 | unsafe fn on_irq() { |
| 73 | crate::dma::AnyChannel { id: $index }.on_irq(); | 74 | crate::dma::AnyChannel { id: $index }.on_irq(); |
| 74 | } | 75 | } |
| @@ -96,7 +97,7 @@ impl AnyChannel { | |||
| 96 | } | 97 | } |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 99 | impl sealed::Channel for AnyChannel { | 100 | impl SealedChannel for AnyChannel { |
| 100 | fn id(&self) -> u8 { | 101 | fn id(&self) -> u8 { |
| 101 | self.id | 102 | self.id |
| 102 | } | 103 | } |
diff --git a/embassy-stm32/src/dma/word.rs b/embassy-stm32/src/dma/word.rs index a72c4b7d9..fb1bde860 100644 --- a/embassy-stm32/src/dma/word.rs +++ b/embassy-stm32/src/dma/word.rs | |||
| @@ -20,14 +20,13 @@ impl WordSize { | |||
| 20 | } | 20 | } |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | mod sealed { | 23 | trait SealedWord {} |
| 24 | pub trait Word {} | ||
| 25 | } | ||
| 26 | 24 | ||
| 27 | /// DMA word trait. | 25 | /// DMA word trait. |
| 28 | /// | 26 | /// |
| 29 | /// This is implemented for u8, u16, u32, etc. | 27 | /// This is implemented for u8, u16, u32, etc. |
| 30 | pub trait Word: sealed::Word + Default + Copy + 'static { | 28 | #[allow(private_bounds)] |
| 29 | pub trait Word: SealedWord + Default + Copy + 'static { | ||
| 31 | /// Word size | 30 | /// Word size |
| 32 | fn size() -> WordSize; | 31 | fn size() -> WordSize; |
| 33 | /// Amount of bits of this word size. | 32 | /// Amount of bits of this word size. |
| @@ -36,7 +35,7 @@ pub trait Word: sealed::Word + Default + Copy + 'static { | |||
| 36 | 35 | ||
| 37 | macro_rules! impl_word { | 36 | macro_rules! impl_word { |
| 38 | (_, $T:ident, $bits:literal, $size:ident) => { | 37 | (_, $T:ident, $bits:literal, $size:ident) => { |
| 39 | impl sealed::Word for $T {} | 38 | impl SealedWord for $T {} |
| 40 | impl Word for $T { | 39 | impl Word for $T { |
| 41 | fn bits() -> usize { | 40 | fn bits() -> usize { |
| 42 | $bits | 41 | $bits |
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs index 71fe09c3f..bfe8a60d6 100644 --- a/embassy-stm32/src/eth/mod.rs +++ b/embassy-stm32/src/eth/mod.rs | |||
| @@ -177,16 +177,15 @@ pub unsafe trait PHY { | |||
| 177 | fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; | 177 | fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | pub(crate) mod sealed { | 180 | trait SealedInstance { |
| 181 | pub trait Instance { | 181 | fn regs() -> crate::pac::eth::Eth; |
| 182 | fn regs() -> crate::pac::eth::Eth; | ||
| 183 | } | ||
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | /// Ethernet instance. | 184 | /// Ethernet instance. |
| 187 | pub trait Instance: sealed::Instance + RccPeripheral + Send + 'static {} | 185 | #[allow(private_bounds)] |
| 186 | pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} | ||
| 188 | 187 | ||
| 189 | impl sealed::Instance for crate::peripherals::ETH { | 188 | impl SealedInstance for crate::peripherals::ETH { |
| 190 | fn regs() -> crate::pac::eth::Eth { | 189 | fn regs() -> crate::pac::eth::Eth { |
| 191 | crate::pac::ETH | 190 | crate::pac::ETH |
| 192 | } | 191 | } |
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index e5b7b0452..6f0174def 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs | |||
| @@ -12,15 +12,14 @@ use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress | |||
| 12 | pub(crate) use self::rx_desc::{RDes, RDesRing}; | 12 | pub(crate) use self::rx_desc::{RDes, RDesRing}; |
| 13 | pub(crate) use self::tx_desc::{TDes, TDesRing}; | 13 | pub(crate) use self::tx_desc::{TDes, TDesRing}; |
| 14 | use super::*; | 14 | use super::*; |
| 15 | use crate::gpio::sealed::{AFType, Pin as __GpioPin}; | 15 | use crate::gpio::{AFType, AnyPin, SealedPin}; |
| 16 | use crate::gpio::AnyPin; | ||
| 17 | use crate::interrupt::InterruptExt; | 16 | use crate::interrupt::InterruptExt; |
| 18 | #[cfg(eth_v1a)] | 17 | #[cfg(eth_v1a)] |
| 19 | use crate::pac::AFIO; | 18 | use crate::pac::AFIO; |
| 20 | #[cfg(any(eth_v1b, eth_v1c))] | 19 | #[cfg(any(eth_v1b, eth_v1c))] |
| 21 | use crate::pac::SYSCFG; | 20 | use crate::pac::SYSCFG; |
| 22 | use crate::pac::{ETH, RCC}; | 21 | use crate::pac::{ETH, RCC}; |
| 23 | use crate::rcc::sealed::RccPeripheral; | 22 | use crate::rcc::SealedRccPeripheral; |
| 24 | use crate::{interrupt, Peripheral}; | 23 | use crate::{interrupt, Peripheral}; |
| 25 | 24 | ||
| 26 | /// Interrupt handler. | 25 | /// Interrupt handler. |
| @@ -149,8 +148,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 149 | #[cfg(any(eth_v1b, eth_v1c))] | 148 | #[cfg(any(eth_v1b, eth_v1c))] |
| 150 | config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); | 149 | config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); |
| 151 | 150 | ||
| 152 | let dma = ETH.ethernet_dma(); | 151 | let dma = T::regs().ethernet_dma(); |
| 153 | let mac = ETH.ethernet_mac(); | 152 | let mac = T::regs().ethernet_mac(); |
| 154 | 153 | ||
| 155 | // Reset and wait | 154 | // Reset and wait |
| 156 | dma.dmabmr().modify(|w| w.set_sr(true)); | 155 | dma.dmabmr().modify(|w| w.set_sr(true)); |
| @@ -192,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 192 | 191 | ||
| 193 | // TODO MTU size setting not found for v1 ethernet, check if correct | 192 | // TODO MTU size setting not found for v1 ethernet, check if correct |
| 194 | 193 | ||
| 195 | let hclk = <T as RccPeripheral>::frequency(); | 194 | let hclk = <T as SealedRccPeripheral>::frequency(); |
| 196 | let hclk_mhz = hclk.0 / 1_000_000; | 195 | let hclk_mhz = hclk.0 / 1_000_000; |
| 197 | 196 | ||
| 198 | // Set the MDC clock frequency in the range 1MHz - 2.5MHz | 197 | // Set the MDC clock frequency in the range 1MHz - 2.5MHz |
| @@ -235,8 +234,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 235 | 234 | ||
| 236 | fence(Ordering::SeqCst); | 235 | fence(Ordering::SeqCst); |
| 237 | 236 | ||
| 238 | let mac = ETH.ethernet_mac(); | 237 | let mac = T::regs().ethernet_mac(); |
| 239 | let dma = ETH.ethernet_dma(); | 238 | let dma = T::regs().ethernet_dma(); |
| 240 | 239 | ||
| 241 | mac.maccr().modify(|w| { | 240 | mac.maccr().modify(|w| { |
| 242 | w.set_re(true); | 241 | w.set_re(true); |
| @@ -275,7 +274,7 @@ pub struct EthernetStationManagement<T: Instance> { | |||
| 275 | 274 | ||
| 276 | unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | 275 | unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { |
| 277 | fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { | 276 | fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { |
| 278 | let mac = ETH.ethernet_mac(); | 277 | let mac = T::regs().ethernet_mac(); |
| 279 | 278 | ||
| 280 | mac.macmiiar().modify(|w| { | 279 | mac.macmiiar().modify(|w| { |
| 281 | w.set_pa(phy_addr); | 280 | w.set_pa(phy_addr); |
| @@ -289,7 +288,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | |||
| 289 | } | 288 | } |
| 290 | 289 | ||
| 291 | fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { | 290 | fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { |
| 292 | let mac = ETH.ethernet_mac(); | 291 | let mac = T::regs().ethernet_mac(); |
| 293 | 292 | ||
| 294 | mac.macmiidr().write(|w| w.set_md(val)); | 293 | mac.macmiidr().write(|w| w.set_md(val)); |
| 295 | mac.macmiiar().modify(|w| { | 294 | mac.macmiiar().modify(|w| { |
| @@ -305,8 +304,8 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | |||
| 305 | 304 | ||
| 306 | impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { | 305 | impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { |
| 307 | fn drop(&mut self) { | 306 | fn drop(&mut self) { |
| 308 | let dma = ETH.ethernet_dma(); | 307 | let dma = T::regs().ethernet_dma(); |
| 309 | let mac = ETH.ethernet_mac(); | 308 | let mac = T::regs().ethernet_mac(); |
| 310 | 309 | ||
| 311 | // Disable the TX DMA and wait for any previous transmissions to be completed | 310 | // Disable the TX DMA and wait for any previous transmissions to be completed |
| 312 | dma.dmaomr().modify(|w| w.set_st(St::STOPPED)); | 311 | dma.dmaomr().modify(|w| w.set_st(St::STOPPED)); |
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 8d69561d4..c6e015022 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs | |||
| @@ -7,11 +7,10 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 7 | 7 | ||
| 8 | pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; | 8 | pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; |
| 9 | use super::*; | 9 | use super::*; |
| 10 | use crate::gpio::sealed::{AFType, Pin as _}; | 10 | use crate::gpio::{AFType, AnyPin, SealedPin as _, Speed}; |
| 11 | use crate::gpio::{AnyPin, Speed}; | ||
| 12 | use crate::interrupt::InterruptExt; | 11 | use crate::interrupt::InterruptExt; |
| 13 | use crate::pac::ETH; | 12 | use crate::pac::ETH; |
| 14 | use crate::rcc::sealed::RccPeripheral; | 13 | use crate::rcc::SealedRccPeripheral; |
| 15 | use crate::{interrupt, Peripheral}; | 14 | use crate::{interrupt, Peripheral}; |
| 16 | 15 | ||
| 17 | /// Interrupt handler. | 16 | /// Interrupt handler. |
| @@ -207,9 +206,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 207 | phy: P, | 206 | phy: P, |
| 208 | mac_addr: [u8; 6], | 207 | mac_addr: [u8; 6], |
| 209 | ) -> Self { | 208 | ) -> Self { |
| 210 | let dma = ETH.ethernet_dma(); | 209 | let dma = T::regs().ethernet_dma(); |
| 211 | let mac = ETH.ethernet_mac(); | 210 | let mac = T::regs().ethernet_mac(); |
| 212 | let mtl = ETH.ethernet_mtl(); | 211 | let mtl = T::regs().ethernet_mtl(); |
| 213 | 212 | ||
| 214 | // Reset and wait | 213 | // Reset and wait |
| 215 | dma.dmamr().modify(|w| w.set_swr(true)); | 214 | dma.dmamr().modify(|w| w.set_swr(true)); |
| @@ -265,7 +264,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 265 | w.set_rbsz(RX_BUFFER_SIZE as u16); | 264 | w.set_rbsz(RX_BUFFER_SIZE as u16); |
| 266 | }); | 265 | }); |
| 267 | 266 | ||
| 268 | let hclk = <T as RccPeripheral>::frequency(); | 267 | let hclk = <T as SealedRccPeripheral>::frequency(); |
| 269 | let hclk_mhz = hclk.0 / 1_000_000; | 268 | let hclk_mhz = hclk.0 / 1_000_000; |
| 270 | 269 | ||
| 271 | // Set the MDC clock frequency in the range 1MHz - 2.5MHz | 270 | // Set the MDC clock frequency in the range 1MHz - 2.5MHz |
| @@ -296,9 +295,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 296 | 295 | ||
| 297 | fence(Ordering::SeqCst); | 296 | fence(Ordering::SeqCst); |
| 298 | 297 | ||
| 299 | let mac = ETH.ethernet_mac(); | 298 | let mac = T::regs().ethernet_mac(); |
| 300 | let mtl = ETH.ethernet_mtl(); | 299 | let mtl = T::regs().ethernet_mtl(); |
| 301 | let dma = ETH.ethernet_dma(); | 300 | let dma = T::regs().ethernet_dma(); |
| 302 | 301 | ||
| 303 | mac.maccr().modify(|w| { | 302 | mac.maccr().modify(|w| { |
| 304 | w.set_re(true); | 303 | w.set_re(true); |
| @@ -334,7 +333,7 @@ pub struct EthernetStationManagement<T: Instance> { | |||
| 334 | 333 | ||
| 335 | unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | 334 | unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { |
| 336 | fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { | 335 | fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 { |
| 337 | let mac = ETH.ethernet_mac(); | 336 | let mac = T::regs().ethernet_mac(); |
| 338 | 337 | ||
| 339 | mac.macmdioar().modify(|w| { | 338 | mac.macmdioar().modify(|w| { |
| 340 | w.set_pa(phy_addr); | 339 | w.set_pa(phy_addr); |
| @@ -348,7 +347,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | |||
| 348 | } | 347 | } |
| 349 | 348 | ||
| 350 | fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { | 349 | fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) { |
| 351 | let mac = ETH.ethernet_mac(); | 350 | let mac = T::regs().ethernet_mac(); |
| 352 | 351 | ||
| 353 | mac.macmdiodr().write(|w| w.set_md(val)); | 352 | mac.macmdiodr().write(|w| w.set_md(val)); |
| 354 | mac.macmdioar().modify(|w| { | 353 | mac.macmdioar().modify(|w| { |
| @@ -364,9 +363,9 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | |||
| 364 | 363 | ||
| 365 | impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { | 364 | impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> { |
| 366 | fn drop(&mut self) { | 365 | fn drop(&mut self) { |
| 367 | let dma = ETH.ethernet_dma(); | 366 | let dma = T::regs().ethernet_dma(); |
| 368 | let mac = ETH.ethernet_mac(); | 367 | let mac = T::regs().ethernet_mac(); |
| 369 | let mtl = ETH.ethernet_mtl(); | 368 | let mtl = T::regs().ethernet_mtl(); |
| 370 | 369 | ||
| 371 | // Disable the TX DMA and wait for any previous transmissions to be completed | 370 | // Disable the TX DMA and wait for any previous transmissions to be completed |
| 372 | dma.dmactx_cr().modify(|w| w.set_st(false)); | 371 | dma.dmactx_cr().modify(|w| w.set_st(false)); |
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index bd10ba158..8d5dae436 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -330,12 +330,11 @@ macro_rules! impl_irq { | |||
| 330 | 330 | ||
| 331 | foreach_exti_irq!(impl_irq); | 331 | foreach_exti_irq!(impl_irq); |
| 332 | 332 | ||
| 333 | pub(crate) mod sealed { | 333 | trait SealedChannel {} |
| 334 | pub trait Channel {} | ||
| 335 | } | ||
| 336 | 334 | ||
| 337 | /// EXTI channel trait. | 335 | /// EXTI channel trait. |
| 338 | pub trait Channel: sealed::Channel + Sized { | 336 | #[allow(private_bounds)] |
| 337 | pub trait Channel: SealedChannel + Sized { | ||
| 339 | /// Get the EXTI channel number. | 338 | /// Get the EXTI channel number. |
| 340 | fn number(&self) -> u8; | 339 | fn number(&self) -> u8; |
| 341 | 340 | ||
| @@ -359,7 +358,7 @@ pub struct AnyChannel { | |||
| 359 | } | 358 | } |
| 360 | 359 | ||
| 361 | impl_peripheral!(AnyChannel); | 360 | impl_peripheral!(AnyChannel); |
| 362 | impl sealed::Channel for AnyChannel {} | 361 | impl SealedChannel for AnyChannel {} |
| 363 | impl Channel for AnyChannel { | 362 | impl Channel for AnyChannel { |
| 364 | fn number(&self) -> u8 { | 363 | fn number(&self) -> u8 { |
| 365 | self.number | 364 | self.number |
| @@ -368,7 +367,7 @@ impl Channel for AnyChannel { | |||
| 368 | 367 | ||
| 369 | macro_rules! impl_exti { | 368 | macro_rules! impl_exti { |
| 370 | ($type:ident, $number:expr) => { | 369 | ($type:ident, $number:expr) => { |
| 371 | impl sealed::Channel for peripherals::$type {} | 370 | impl SealedChannel for peripherals::$type {} |
| 372 | impl Channel for peripherals::$type { | 371 | impl Channel for peripherals::$type { |
| 373 | fn number(&self) -> u8 { | 372 | fn number(&self) -> u8 { |
| 374 | $number | 373 | $number |
diff --git a/embassy-stm32/src/flash/f0.rs b/embassy-stm32/src/flash/f0.rs index e0c76e6b2..e2f135208 100644 --- a/embassy-stm32/src/flash/f0.rs +++ b/embassy-stm32/src/flash/f0.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/flash/f1f3.rs b/embassy-stm32/src/flash/f1f3.rs index e7790369a..b16354a74 100644 --- a/embassy-stm32/src/flash/f1f3.rs +++ b/embassy-stm32/src/flash/f1f3.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 57447bea5..00e61f2d2 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, AtomicBool, Ordering}; | 2 | use core::sync::atomic::{fence, AtomicBool, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs index 0f512bbc4..72de0b445 100644 --- a/embassy-stm32/src/flash/f7.rs +++ b/embassy-stm32/src/flash/f7.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/flash/g.rs b/embassy-stm32/src/flash/g.rs index b69c4343b..6a5adc941 100644 --- a/embassy-stm32/src/flash/g.rs +++ b/embassy-stm32/src/flash/g.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs index 743925e17..e32a82eef 100644 --- a/embassy-stm32/src/flash/h7.rs +++ b/embassy-stm32/src/flash/h7.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/flash/u5.rs b/embassy-stm32/src/flash/u5.rs index 3787082f9..580c490da 100644 --- a/embassy-stm32/src/flash/u5.rs +++ b/embassy-stm32/src/flash/u5.rs | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | use core::convert::TryInto; | ||
| 2 | use core::ptr::write_volatile; | 1 | use core::ptr::write_volatile; |
| 3 | use core::sync::atomic::{fence, Ordering}; | 2 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 3 | ||
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs index 9d731a512..aced69878 100644 --- a/embassy-stm32/src/fmc.rs +++ b/embassy-stm32/src/fmc.rs | |||
| @@ -3,8 +3,7 @@ use core::marker::PhantomData; | |||
| 3 | 3 | ||
| 4 | use embassy_hal_internal::into_ref; | 4 | use embassy_hal_internal::into_ref; |
| 5 | 5 | ||
| 6 | use crate::gpio::sealed::AFType; | 6 | use crate::gpio::{AFType, Pull, Speed}; |
| 7 | use crate::gpio::{Pull, Speed}; | ||
| 8 | use crate::Peripheral; | 7 | use crate::Peripheral; |
| 9 | 8 | ||
| 10 | /// FMC driver | 9 | /// FMC driver |
| @@ -44,7 +43,7 @@ where | |||
| 44 | 43 | ||
| 45 | /// Get the kernel clock currently in use for this FMC instance. | 44 | /// Get the kernel clock currently in use for this FMC instance. |
| 46 | pub fn source_clock_hz(&self) -> u32 { | 45 | pub fn source_clock_hz(&self) -> u32 { |
| 47 | <T as crate::rcc::sealed::RccPeripheral>::frequency().0 | 46 | <T as crate::rcc::SealedRccPeripheral>::frequency().0 |
| 48 | } | 47 | } |
| 49 | } | 48 | } |
| 50 | 49 | ||
| @@ -69,7 +68,7 @@ where | |||
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | fn source_clock_hz(&self) -> u32 { | 70 | fn source_clock_hz(&self) -> u32 { |
| 72 | <T as crate::rcc::sealed::RccPeripheral>::frequency().0 | 71 | <T as crate::rcc::SealedRccPeripheral>::frequency().0 |
| 73 | } | 72 | } |
| 74 | } | 73 | } |
| 75 | 74 | ||
| @@ -201,18 +200,17 @@ impl<'d, T: Instance> Fmc<'d, T> { | |||
| 201 | )); | 200 | )); |
| 202 | } | 201 | } |
| 203 | 202 | ||
| 204 | pub(crate) mod sealed { | 203 | trait SealedInstance: crate::rcc::SealedRccPeripheral { |
| 205 | pub trait Instance: crate::rcc::sealed::RccPeripheral { | 204 | const REGS: crate::pac::fmc::Fmc; |
| 206 | const REGS: crate::pac::fmc::Fmc; | ||
| 207 | } | ||
| 208 | } | 205 | } |
| 209 | 206 | ||
| 210 | /// FMC instance trait. | 207 | /// FMC instance trait. |
| 211 | pub trait Instance: sealed::Instance + 'static {} | 208 | #[allow(private_bounds)] |
| 209 | pub trait Instance: SealedInstance + 'static {} | ||
| 212 | 210 | ||
| 213 | foreach_peripheral!( | 211 | foreach_peripheral!( |
| 214 | (fmc, $inst:ident) => { | 212 | (fmc, $inst:ident) => { |
| 215 | impl crate::fmc::sealed::Instance for crate::peripherals::$inst { | 213 | impl crate::fmc::SealedInstance for crate::peripherals::$inst { |
| 216 | const REGS: crate::pac::fmc::Fmc = crate::pac::$inst; | 214 | const REGS: crate::pac::fmc::Fmc = crate::pac::$inst; |
| 217 | } | 215 | } |
| 218 | impl crate::fmc::Instance for crate::peripherals::$inst {} | 216 | impl crate::fmc::Instance for crate::peripherals::$inst {} |
diff --git a/embassy-stm32/src/fmt.rs b/embassy-stm32/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-stm32/src/fmt.rs +++ b/embassy-stm32/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 00e3e1727..33f22f676 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -6,7 +6,6 @@ use core::convert::Infallible; | |||
| 6 | use critical_section::CriticalSection; | 6 | use critical_section::CriticalSection; |
| 7 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 8 | 8 | ||
| 9 | use self::sealed::Pin as _; | ||
| 10 | use crate::pac::gpio::{self, vals}; | 9 | use crate::pac::gpio::{self, vals}; |
| 11 | use crate::{pac, peripherals, Peripheral}; | 10 | use crate::{pac, peripherals, Peripheral}; |
| 12 | 11 | ||
| @@ -129,6 +128,18 @@ impl<'d> Flex<'d> { | |||
| 129 | }); | 128 | }); |
| 130 | } | 129 | } |
| 131 | 130 | ||
| 131 | /// Put the pin into AF mode, unchecked. | ||
| 132 | /// | ||
| 133 | /// This puts the pin into the AF mode, with the requested number, pull and speed. This is | ||
| 134 | /// completely unchecked, it can attach the pin to literally any peripheral, so use with care. | ||
| 135 | #[inline] | ||
| 136 | pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AFType, pull: Pull, speed: Speed) { | ||
| 137 | critical_section::with(|_| { | ||
| 138 | self.pin.set_as_af_pull(af_num, af_type, pull); | ||
| 139 | self.pin.set_speed(speed); | ||
| 140 | }); | ||
| 141 | } | ||
| 142 | |||
| 132 | /// Get whether the pin input level is high. | 143 | /// Get whether the pin input level is high. |
| 133 | #[inline] | 144 | #[inline] |
| 134 | pub fn is_high(&self) -> bool { | 145 | pub fn is_high(&self) -> bool { |
| @@ -508,172 +519,168 @@ pub enum OutputType { | |||
| 508 | OpenDrain, | 519 | OpenDrain, |
| 509 | } | 520 | } |
| 510 | 521 | ||
| 511 | impl From<OutputType> for sealed::AFType { | 522 | impl From<OutputType> for AFType { |
| 512 | fn from(value: OutputType) -> Self { | 523 | fn from(value: OutputType) -> Self { |
| 513 | match value { | 524 | match value { |
| 514 | OutputType::OpenDrain => sealed::AFType::OutputOpenDrain, | 525 | OutputType::OpenDrain => AFType::OutputOpenDrain, |
| 515 | OutputType::PushPull => sealed::AFType::OutputPushPull, | 526 | OutputType::PushPull => AFType::OutputPushPull, |
| 516 | } | 527 | } |
| 517 | } | 528 | } |
| 518 | } | 529 | } |
| 519 | 530 | ||
| 520 | #[allow(missing_docs)] | 531 | /// Alternate function type settings |
| 521 | pub(crate) mod sealed { | 532 | #[derive(Debug, Copy, Clone)] |
| 522 | use super::*; | 533 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 523 | 534 | pub enum AFType { | |
| 524 | /// Alternate function type settings | 535 | /// Input |
| 525 | #[derive(Debug, Copy, Clone)] | 536 | Input, |
| 526 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 537 | /// Output, drive the pin both high or low. |
| 527 | pub enum AFType { | 538 | OutputPushPull, |
| 528 | /// Input | 539 | /// Output, drive the pin low, or don't drive it at all if the output level is high. |
| 529 | Input, | 540 | OutputOpenDrain, |
| 530 | /// Output, drive the pin both high or low. | 541 | } |
| 531 | OutputPushPull, | ||
| 532 | /// Output, drive the pin low, or don't drive it at all if the output level is high. | ||
| 533 | OutputOpenDrain, | ||
| 534 | } | ||
| 535 | |||
| 536 | pub trait Pin { | ||
| 537 | fn pin_port(&self) -> u8; | ||
| 538 | |||
| 539 | #[inline] | ||
| 540 | fn _pin(&self) -> u8 { | ||
| 541 | self.pin_port() % 16 | ||
| 542 | } | ||
| 543 | #[inline] | ||
| 544 | fn _port(&self) -> u8 { | ||
| 545 | self.pin_port() / 16 | ||
| 546 | } | ||
| 547 | 542 | ||
| 548 | #[inline] | 543 | pub(crate) trait SealedPin { |
| 549 | fn block(&self) -> gpio::Gpio { | 544 | fn pin_port(&self) -> u8; |
| 550 | pac::GPIO(self._port() as _) | ||
| 551 | } | ||
| 552 | 545 | ||
| 553 | /// Set the output as high. | 546 | #[inline] |
| 554 | #[inline] | 547 | fn _pin(&self) -> u8 { |
| 555 | fn set_high(&self) { | 548 | self.pin_port() % 16 |
| 556 | let n = self._pin() as _; | 549 | } |
| 557 | self.block().bsrr().write(|w| w.set_bs(n, true)); | 550 | #[inline] |
| 558 | } | 551 | fn _port(&self) -> u8 { |
| 552 | self.pin_port() / 16 | ||
| 553 | } | ||
| 559 | 554 | ||
| 560 | /// Set the output as low. | 555 | #[inline] |
| 561 | #[inline] | 556 | fn block(&self) -> gpio::Gpio { |
| 562 | fn set_low(&self) { | 557 | pac::GPIO(self._port() as _) |
| 563 | let n = self._pin() as _; | 558 | } |
| 564 | self.block().bsrr().write(|w| w.set_br(n, true)); | ||
| 565 | } | ||
| 566 | 559 | ||
| 567 | #[inline] | 560 | /// Set the output as high. |
| 568 | fn set_as_af(&self, af_num: u8, af_type: AFType) { | 561 | #[inline] |
| 569 | self.set_as_af_pull(af_num, af_type, Pull::None); | 562 | fn set_high(&self) { |
| 570 | } | 563 | let n = self._pin() as _; |
| 564 | self.block().bsrr().write(|w| w.set_bs(n, true)); | ||
| 565 | } | ||
| 571 | 566 | ||
| 572 | #[cfg(gpio_v1)] | 567 | /// Set the output as low. |
| 573 | #[inline] | 568 | #[inline] |
| 574 | fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) { | 569 | fn set_low(&self) { |
| 575 | // F1 uses the AFIO register for remapping. | 570 | let n = self._pin() as _; |
| 576 | // For now, this is not implemented, so af_num is ignored | 571 | self.block().bsrr().write(|w| w.set_br(n, true)); |
| 577 | // _af_num should be zero here, since it is not set by stm32-data | 572 | } |
| 578 | let r = self.block(); | ||
| 579 | let n = self._pin() as usize; | ||
| 580 | let crlh = if n < 8 { 0 } else { 1 }; | ||
| 581 | match af_type { | ||
| 582 | AFType::Input => { | ||
| 583 | let cnf = match pull { | ||
| 584 | Pull::Up => { | ||
| 585 | r.bsrr().write(|w| w.set_bs(n, true)); | ||
| 586 | vals::CnfIn::PULL | ||
| 587 | } | ||
| 588 | Pull::Down => { | ||
| 589 | r.bsrr().write(|w| w.set_br(n, true)); | ||
| 590 | vals::CnfIn::PULL | ||
| 591 | } | ||
| 592 | Pull::None => vals::CnfIn::FLOATING, | ||
| 593 | }; | ||
| 594 | |||
| 595 | r.cr(crlh).modify(|w| { | ||
| 596 | w.set_mode(n % 8, vals::Mode::INPUT); | ||
| 597 | w.set_cnf_in(n % 8, cnf); | ||
| 598 | }); | ||
| 599 | } | ||
| 600 | AFType::OutputPushPull => { | ||
| 601 | r.cr(crlh).modify(|w| { | ||
| 602 | w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ); | ||
| 603 | w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL); | ||
| 604 | }); | ||
| 605 | } | ||
| 606 | AFType::OutputOpenDrain => { | ||
| 607 | r.cr(crlh).modify(|w| { | ||
| 608 | w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ); | ||
| 609 | w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN); | ||
| 610 | }); | ||
| 611 | } | ||
| 612 | } | ||
| 613 | } | ||
| 614 | 573 | ||
| 615 | #[cfg(gpio_v2)] | 574 | #[inline] |
| 616 | #[inline] | 575 | fn set_as_af(&self, af_num: u8, af_type: AFType) { |
| 617 | fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) { | 576 | self.set_as_af_pull(af_num, af_type, Pull::None); |
| 618 | let pin = self._pin() as usize; | 577 | } |
| 619 | let block = self.block(); | ||
| 620 | block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num)); | ||
| 621 | match af_type { | ||
| 622 | AFType::Input => {} | ||
| 623 | AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)), | ||
| 624 | AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), | ||
| 625 | } | ||
| 626 | block.pupdr().modify(|w| w.set_pupdr(pin, pull.into())); | ||
| 627 | 578 | ||
| 628 | block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE)); | 579 | #[cfg(gpio_v1)] |
| 629 | } | 580 | #[inline] |
| 581 | fn set_as_af_pull(&self, _af_num: u8, af_type: AFType, pull: Pull) { | ||
| 582 | // F1 uses the AFIO register for remapping. | ||
| 583 | // For now, this is not implemented, so af_num is ignored | ||
| 584 | // _af_num should be zero here, since it is not set by stm32-data | ||
| 585 | let r = self.block(); | ||
| 586 | let n = self._pin() as usize; | ||
| 587 | let crlh = if n < 8 { 0 } else { 1 }; | ||
| 588 | match af_type { | ||
| 589 | AFType::Input => { | ||
| 590 | let cnf = match pull { | ||
| 591 | Pull::Up => { | ||
| 592 | r.bsrr().write(|w| w.set_bs(n, true)); | ||
| 593 | vals::CnfIn::PULL | ||
| 594 | } | ||
| 595 | Pull::Down => { | ||
| 596 | r.bsrr().write(|w| w.set_br(n, true)); | ||
| 597 | vals::CnfIn::PULL | ||
| 598 | } | ||
| 599 | Pull::None => vals::CnfIn::FLOATING, | ||
| 600 | }; | ||
| 630 | 601 | ||
| 631 | #[inline] | 602 | r.cr(crlh).modify(|w| { |
| 632 | fn set_as_analog(&self) { | 603 | w.set_mode(n % 8, vals::Mode::INPUT); |
| 633 | let pin = self._pin() as usize; | 604 | w.set_cnf_in(n % 8, cnf); |
| 634 | let block = self.block(); | 605 | }); |
| 635 | #[cfg(gpio_v1)] | 606 | } |
| 636 | { | 607 | AFType::OutputPushPull => { |
| 637 | let crlh = if pin < 8 { 0 } else { 1 }; | 608 | r.cr(crlh).modify(|w| { |
| 638 | block.cr(crlh).modify(|w| { | 609 | w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ); |
| 639 | w.set_mode(pin % 8, vals::Mode::INPUT); | 610 | w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL); |
| 640 | w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG); | 611 | }); |
| 612 | } | ||
| 613 | AFType::OutputOpenDrain => { | ||
| 614 | r.cr(crlh).modify(|w| { | ||
| 615 | w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ); | ||
| 616 | w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN); | ||
| 641 | }); | 617 | }); |
| 642 | } | 618 | } |
| 643 | #[cfg(gpio_v2)] | ||
| 644 | block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); | ||
| 645 | } | 619 | } |
| 620 | } | ||
| 646 | 621 | ||
| 647 | /// Set the pin as "disconnected", ie doing nothing and consuming the lowest | 622 | #[cfg(gpio_v2)] |
| 648 | /// amount of power possible. | 623 | #[inline] |
| 649 | /// | 624 | fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) { |
| 650 | /// This is currently the same as set_as_analog but is semantically different really. | 625 | let pin = self._pin() as usize; |
| 651 | /// Drivers should set_as_disconnected pins when dropped. | 626 | let block = self.block(); |
| 652 | #[inline] | 627 | block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num)); |
| 653 | fn set_as_disconnected(&self) { | 628 | match af_type { |
| 654 | self.set_as_analog(); | 629 | AFType::Input => {} |
| 630 | AFType::OutputPushPull => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL)), | ||
| 631 | AFType::OutputOpenDrain => block.otyper().modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), | ||
| 655 | } | 632 | } |
| 633 | block.pupdr().modify(|w| w.set_pupdr(pin, pull.into())); | ||
| 656 | 634 | ||
| 657 | #[inline] | 635 | block.moder().modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE)); |
| 658 | fn set_speed(&self, speed: Speed) { | 636 | } |
| 659 | let pin = self._pin() as usize; | ||
| 660 | 637 | ||
| 661 | #[cfg(gpio_v1)] | 638 | #[inline] |
| 662 | { | 639 | fn set_as_analog(&self) { |
| 663 | let crlh = if pin < 8 { 0 } else { 1 }; | 640 | let pin = self._pin() as usize; |
| 664 | self.block().cr(crlh).modify(|w| { | 641 | let block = self.block(); |
| 665 | w.set_mode(pin % 8, speed.into()); | 642 | #[cfg(gpio_v1)] |
| 666 | }); | 643 | { |
| 667 | } | 644 | let crlh = if pin < 8 { 0 } else { 1 }; |
| 645 | block.cr(crlh).modify(|w| { | ||
| 646 | w.set_mode(pin % 8, vals::Mode::INPUT); | ||
| 647 | w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG); | ||
| 648 | }); | ||
| 649 | } | ||
| 650 | #[cfg(gpio_v2)] | ||
| 651 | block.moder().modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); | ||
| 652 | } | ||
| 668 | 653 | ||
| 669 | #[cfg(gpio_v2)] | 654 | /// Set the pin as "disconnected", ie doing nothing and consuming the lowest |
| 670 | self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into())); | 655 | /// amount of power possible. |
| 656 | /// | ||
| 657 | /// This is currently the same as set_as_analog but is semantically different really. | ||
| 658 | /// Drivers should set_as_disconnected pins when dropped. | ||
| 659 | #[inline] | ||
| 660 | fn set_as_disconnected(&self) { | ||
| 661 | self.set_as_analog(); | ||
| 662 | } | ||
| 663 | |||
| 664 | #[inline] | ||
| 665 | fn set_speed(&self, speed: Speed) { | ||
| 666 | let pin = self._pin() as usize; | ||
| 667 | |||
| 668 | #[cfg(gpio_v1)] | ||
| 669 | { | ||
| 670 | let crlh = if pin < 8 { 0 } else { 1 }; | ||
| 671 | self.block().cr(crlh).modify(|w| { | ||
| 672 | w.set_mode(pin % 8, speed.into()); | ||
| 673 | }); | ||
| 671 | } | 674 | } |
| 675 | |||
| 676 | #[cfg(gpio_v2)] | ||
| 677 | self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into())); | ||
| 672 | } | 678 | } |
| 673 | } | 679 | } |
| 674 | 680 | ||
| 675 | /// GPIO pin trait. | 681 | /// GPIO pin trait. |
| 676 | pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static { | 682 | #[allow(private_bounds)] |
| 683 | pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { | ||
| 677 | /// EXTI channel assigned to this pin. | 684 | /// EXTI channel assigned to this pin. |
| 678 | /// | 685 | /// |
| 679 | /// For example, PC4 uses EXTI4. | 686 | /// For example, PC4 uses EXTI4. |
| @@ -737,7 +744,7 @@ impl Pin for AnyPin { | |||
| 737 | #[cfg(feature = "exti")] | 744 | #[cfg(feature = "exti")] |
| 738 | type ExtiChannel = crate::exti::AnyChannel; | 745 | type ExtiChannel = crate::exti::AnyChannel; |
| 739 | } | 746 | } |
| 740 | impl sealed::Pin for AnyPin { | 747 | impl SealedPin for AnyPin { |
| 741 | #[inline] | 748 | #[inline] |
| 742 | fn pin_port(&self) -> u8 { | 749 | fn pin_port(&self) -> u8 { |
| 743 | self.pin_port | 750 | self.pin_port |
| @@ -752,7 +759,7 @@ foreach_pin!( | |||
| 752 | #[cfg(feature = "exti")] | 759 | #[cfg(feature = "exti")] |
| 753 | type ExtiChannel = peripherals::$exti_ch; | 760 | type ExtiChannel = peripherals::$exti_ch; |
| 754 | } | 761 | } |
| 755 | impl sealed::Pin for peripherals::$pin_name { | 762 | impl SealedPin for peripherals::$pin_name { |
| 756 | #[inline] | 763 | #[inline] |
| 757 | fn pin_port(&self) -> u8 { | 764 | fn pin_port(&self) -> u8 { |
| 758 | $port_num * 16 + $pin_num | 765 | $port_num * 16 + $pin_num |
| @@ -769,7 +776,7 @@ foreach_pin!( | |||
| 769 | 776 | ||
| 770 | pub(crate) unsafe fn init(_cs: CriticalSection) { | 777 | pub(crate) unsafe fn init(_cs: CriticalSection) { |
| 771 | #[cfg(afio)] | 778 | #[cfg(afio)] |
| 772 | <crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(_cs); | 779 | <crate::peripherals::AFIO as crate::rcc::SealedRccPeripheral>::enable_and_reset_with_cs(_cs); |
| 773 | 780 | ||
| 774 | crate::_generated::init_gpio(); | 781 | crate::_generated::init_gpio(); |
| 775 | 782 | ||
| @@ -833,6 +840,18 @@ impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'d> { | |||
| 833 | } | 840 | } |
| 834 | } | 841 | } |
| 835 | 842 | ||
| 843 | impl<'d> embedded_hal_02::digital::v2::InputPin for OutputOpenDrain<'d> { | ||
| 844 | type Error = Infallible; | ||
| 845 | |||
| 846 | fn is_high(&self) -> Result<bool, Self::Error> { | ||
| 847 | Ok(self.is_high()) | ||
| 848 | } | ||
| 849 | |||
| 850 | fn is_low(&self) -> Result<bool, Self::Error> { | ||
| 851 | Ok(self.is_low()) | ||
| 852 | } | ||
| 853 | } | ||
| 854 | |||
| 836 | impl<'d> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d> { | 855 | impl<'d> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d> { |
| 837 | type Error = Infallible; | 856 | type Error = Infallible; |
| 838 | 857 | ||
| @@ -1049,9 +1068,3 @@ impl<'d> embedded_hal_1::digital::StatefulOutputPin for Flex<'d> { | |||
| 1049 | Ok((*self).is_set_low()) | 1068 | Ok((*self).is_set_low()) |
| 1050 | } | 1069 | } |
| 1051 | } | 1070 | } |
| 1052 | |||
| 1053 | /// Low-level GPIO manipulation. | ||
| 1054 | #[cfg(feature = "unstable-pac")] | ||
| 1055 | pub mod low_level { | ||
| 1056 | pub use super::sealed::*; | ||
| 1057 | } | ||
diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs index b47814f8b..787d5b1c9 100644 --- a/embassy-stm32/src/hash/mod.rs +++ b/embassy-stm32/src/hash/mod.rs | |||
| @@ -17,7 +17,7 @@ use crate::dma::NoDma; | |||
| 17 | use crate::dma::Transfer; | 17 | use crate::dma::Transfer; |
| 18 | use crate::interrupt::typelevel::Interrupt; | 18 | use crate::interrupt::typelevel::Interrupt; |
| 19 | use crate::peripherals::HASH; | 19 | use crate::peripherals::HASH; |
| 20 | use crate::rcc::sealed::RccPeripheral; | 20 | use crate::rcc::SealedRccPeripheral; |
| 21 | use crate::{interrupt, pac, peripherals, Peripheral}; | 21 | use crate::{interrupt, pac, peripherals, Peripheral}; |
| 22 | 22 | ||
| 23 | #[cfg(hash_v1)] | 23 | #[cfg(hash_v1)] |
| @@ -561,16 +561,13 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { | |||
| 561 | } | 561 | } |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | pub(crate) mod sealed { | 564 | trait SealedInstance { |
| 565 | use super::*; | 565 | fn regs() -> pac::hash::Hash; |
| 566 | |||
| 567 | pub trait Instance { | ||
| 568 | fn regs() -> pac::hash::Hash; | ||
| 569 | } | ||
| 570 | } | 566 | } |
| 571 | 567 | ||
| 572 | /// HASH instance trait. | 568 | /// HASH instance trait. |
| 573 | pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { | 569 | #[allow(private_bounds)] |
| 570 | pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { | ||
| 574 | /// Interrupt for this HASH instance. | 571 | /// Interrupt for this HASH instance. |
| 575 | type Interrupt: interrupt::typelevel::Interrupt; | 572 | type Interrupt: interrupt::typelevel::Interrupt; |
| 576 | } | 573 | } |
| @@ -581,7 +578,7 @@ foreach_interrupt!( | |||
| 581 | type Interrupt = crate::interrupt::typelevel::$irq; | 578 | type Interrupt = crate::interrupt::typelevel::$irq; |
| 582 | } | 579 | } |
| 583 | 580 | ||
| 584 | impl sealed::Instance for peripherals::$inst { | 581 | impl SealedInstance for peripherals::$inst { |
| 585 | fn regs() -> crate::pac::hash::Hash { | 582 | fn regs() -> crate::pac::hash::Hash { |
| 586 | crate::pac::$inst | 583 | crate::pac::$inst |
| 587 | } | 584 | } |
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs index 3ec646fc3..02e45819c 100644 --- a/embassy-stm32/src/hrtim/mod.rs +++ b/embassy-stm32/src/hrtim/mod.rs | |||
| @@ -7,9 +7,7 @@ use core::marker::PhantomData; | |||
| 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | pub use traits::Instance; | 8 | pub use traits::Instance; |
| 9 | 9 | ||
| 10 | #[allow(unused_imports)] | 10 | use crate::gpio::{AFType, AnyPin}; |
| 11 | use crate::gpio::sealed::{AFType, Pin}; | ||
| 12 | use crate::gpio::AnyPin; | ||
| 13 | use crate::time::Hertz; | 11 | use crate::time::Hertz; |
| 14 | use crate::Peripheral; | 12 | use crate::Peripheral; |
| 15 | 13 | ||
| @@ -54,16 +52,13 @@ pub struct ChF<T: Instance> { | |||
| 54 | phantom: PhantomData<T>, | 52 | phantom: PhantomData<T>, |
| 55 | } | 53 | } |
| 56 | 54 | ||
| 57 | mod sealed { | 55 | trait SealedAdvancedChannel<T: Instance> { |
| 58 | use super::Instance; | 56 | fn raw() -> usize; |
| 59 | |||
| 60 | pub trait AdvancedChannel<T: Instance> { | ||
| 61 | fn raw() -> usize; | ||
| 62 | } | ||
| 63 | } | 57 | } |
| 64 | 58 | ||
| 65 | /// Advanced channel instance trait. | 59 | /// Advanced channel instance trait. |
| 66 | pub trait AdvancedChannel<T: Instance>: sealed::AdvancedChannel<T> {} | 60 | #[allow(private_bounds)] |
| 61 | pub trait AdvancedChannel<T: Instance>: SealedAdvancedChannel<T> {} | ||
| 67 | 62 | ||
| 68 | /// HRTIM PWM pin. | 63 | /// HRTIM PWM pin. |
| 69 | pub struct PwmPin<'d, T, C> { | 64 | pub struct PwmPin<'d, T, C> { |
| @@ -113,7 +108,7 @@ macro_rules! advanced_channel_impl { | |||
| 113 | } | 108 | } |
| 114 | } | 109 | } |
| 115 | 110 | ||
| 116 | impl<T: Instance> sealed::AdvancedChannel<T> for $channel<T> { | 111 | impl<T: Instance> SealedAdvancedChannel<T> for $channel<T> { |
| 117 | fn raw() -> usize { | 112 | fn raw() -> usize { |
| 118 | $ch_num | 113 | $ch_num |
| 119 | } | 114 | } |
diff --git a/embassy-stm32/src/hrtim/traits.rs b/embassy-stm32/src/hrtim/traits.rs index dcc2b9ef4..75f9971e2 100644 --- a/embassy-stm32/src/hrtim/traits.rs +++ b/embassy-stm32/src/hrtim/traits.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use crate::rcc::sealed::RccPeripheral; | 1 | use crate::rcc::RccPeripheral; |
| 2 | use crate::time::Hertz; | 2 | use crate::time::Hertz; |
| 3 | 3 | ||
| 4 | #[repr(u8)] | 4 | #[repr(u8)] |
| @@ -72,94 +72,92 @@ impl Prescaler { | |||
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | pub(crate) mod sealed { | 75 | pub(crate) trait SealedInstance: RccPeripheral { |
| 76 | use super::*; | 76 | fn regs() -> crate::pac::hrtim::Hrtim; |
| 77 | 77 | ||
| 78 | pub trait Instance: RccPeripheral { | 78 | #[allow(unused)] |
| 79 | fn regs() -> crate::pac::hrtim::Hrtim; | 79 | fn set_master_frequency(frequency: Hertz) { |
| 80 | let f = frequency.0; | ||
| 80 | 81 | ||
| 81 | fn set_master_frequency(frequency: Hertz) { | 82 | // TODO: wire up HRTIM to the RCC mux infra. |
| 82 | let f = frequency.0; | 83 | //#[cfg(stm32f334)] |
| 84 | //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; | ||
| 85 | //#[cfg(not(stm32f334))] | ||
| 86 | let timer_f = Self::frequency().0; | ||
| 83 | 87 | ||
| 84 | // TODO: wire up HRTIM to the RCC mux infra. | 88 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); |
| 85 | //#[cfg(stm32f334)] | 89 | let psc = if Self::regs().isr().read().dllrdy() { |
| 86 | //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; | 90 | Prescaler::compute_min_high_res(psc_min) |
| 87 | //#[cfg(not(stm32f334))] | 91 | } else { |
| 88 | let timer_f = Self::frequency().0; | 92 | Prescaler::compute_min_low_res(psc_min) |
| 93 | }; | ||
| 89 | 94 | ||
| 90 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | 95 | let timer_f = 32 * (timer_f / psc as u32); |
| 91 | let psc = if Self::regs().isr().read().dllrdy() { | 96 | let per: u16 = (timer_f / f) as u16; |
| 92 | Prescaler::compute_min_high_res(psc_min) | ||
| 93 | } else { | ||
| 94 | Prescaler::compute_min_low_res(psc_min) | ||
| 95 | }; | ||
| 96 | 97 | ||
| 97 | let timer_f = 32 * (timer_f / psc as u32); | 98 | let regs = Self::regs(); |
| 98 | let per: u16 = (timer_f / f) as u16; | ||
| 99 | 99 | ||
| 100 | let regs = Self::regs(); | 100 | regs.mcr().modify(|w| w.set_ckpsc(psc.into())); |
| 101 | 101 | regs.mper().modify(|w| w.set_mper(per)); | |
| 102 | regs.mcr().modify(|w| w.set_ckpsc(psc.into())); | 102 | } |
| 103 | regs.mper().modify(|w| w.set_mper(per)); | ||
| 104 | } | ||
| 105 | 103 | ||
| 106 | fn set_channel_frequency(channel: usize, frequency: Hertz) { | 104 | fn set_channel_frequency(channel: usize, frequency: Hertz) { |
| 107 | let f = frequency.0; | 105 | let f = frequency.0; |
| 108 | 106 | ||
| 109 | // TODO: wire up HRTIM to the RCC mux infra. | 107 | // TODO: wire up HRTIM to the RCC mux infra. |
| 110 | //#[cfg(stm32f334)] | 108 | //#[cfg(stm32f334)] |
| 111 | //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; | 109 | //let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0; |
| 112 | //#[cfg(not(stm32f334))] | 110 | //#[cfg(not(stm32f334))] |
| 113 | let timer_f = Self::frequency().0; | 111 | let timer_f = Self::frequency().0; |
| 114 | 112 | ||
| 115 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); | 113 | let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); |
| 116 | let psc = if Self::regs().isr().read().dllrdy() { | 114 | let psc = if Self::regs().isr().read().dllrdy() { |
| 117 | Prescaler::compute_min_high_res(psc_min) | 115 | Prescaler::compute_min_high_res(psc_min) |
| 118 | } else { | 116 | } else { |
| 119 | Prescaler::compute_min_low_res(psc_min) | 117 | Prescaler::compute_min_low_res(psc_min) |
| 120 | }; | 118 | }; |
| 121 | 119 | ||
| 122 | let timer_f = 32 * (timer_f / psc as u32); | 120 | let timer_f = 32 * (timer_f / psc as u32); |
| 123 | let per: u16 = (timer_f / f) as u16; | 121 | let per: u16 = (timer_f / f) as u16; |
| 124 | 122 | ||
| 125 | let regs = Self::regs(); | 123 | let regs = Self::regs(); |
| 126 | 124 | ||
| 127 | regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); | 125 | regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into())); |
| 128 | regs.tim(channel).per().modify(|w| w.set_per(per)); | 126 | regs.tim(channel).per().modify(|w| w.set_per(per)); |
| 129 | } | 127 | } |
| 130 | 128 | ||
| 131 | /// Set the dead time as a proportion of max_duty | 129 | /// Set the dead time as a proportion of max_duty |
| 132 | fn set_channel_dead_time(channel: usize, dead_time: u16) { | 130 | fn set_channel_dead_time(channel: usize, dead_time: u16) { |
| 133 | let regs = Self::regs(); | 131 | let regs = Self::regs(); |
| 134 | 132 | ||
| 135 | let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into(); | 133 | let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into(); |
| 136 | 134 | ||
| 137 | // The dead-time base clock runs 4 times slower than the hrtim base clock | 135 | // The dead-time base clock runs 4 times slower than the hrtim base clock |
| 138 | // u9::MAX = 511 | 136 | // u9::MAX = 511 |
| 139 | let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511); | 137 | let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511); |
| 140 | let psc = if Self::regs().isr().read().dllrdy() { | 138 | let psc = if Self::regs().isr().read().dllrdy() { |
| 141 | Prescaler::compute_min_high_res(psc_min) | 139 | Prescaler::compute_min_high_res(psc_min) |
| 142 | } else { | 140 | } else { |
| 143 | Prescaler::compute_min_low_res(psc_min) | 141 | Prescaler::compute_min_low_res(psc_min) |
| 144 | }; | 142 | }; |
| 145 | 143 | ||
| 146 | let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32); | 144 | let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32); |
| 147 | 145 | ||
| 148 | regs.tim(channel).dt().modify(|w| { | 146 | regs.tim(channel).dt().modify(|w| { |
| 149 | w.set_dtprsc(psc.into()); | 147 | w.set_dtprsc(psc.into()); |
| 150 | w.set_dtf(dt_val as u16); | 148 | w.set_dtf(dt_val as u16); |
| 151 | w.set_dtr(dt_val as u16); | 149 | w.set_dtr(dt_val as u16); |
| 152 | }); | 150 | }); |
| 153 | } | ||
| 154 | } | 151 | } |
| 155 | } | 152 | } |
| 156 | 153 | ||
| 157 | /// HRTIM instance trait. | 154 | /// HRTIM instance trait. |
| 158 | pub trait Instance: sealed::Instance + 'static {} | 155 | #[allow(private_bounds)] |
| 156 | pub trait Instance: SealedInstance + 'static {} | ||
| 159 | 157 | ||
| 160 | foreach_interrupt! { | 158 | foreach_interrupt! { |
| 161 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { | 159 | ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { |
| 162 | impl sealed::Instance for crate::peripherals::$inst { | 160 | impl SealedInstance for crate::peripherals::$inst { |
| 163 | fn regs() -> crate::pac::hrtim::Hrtim { | 161 | fn regs() -> crate::pac::hrtim::Hrtim { |
| 164 | crate::pac::$inst | 162 | crate::pac::$inst |
| 165 | } | 163 | } |
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 2416005b5..f1b11cc44 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs | |||
| @@ -14,8 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 14 | use embassy_time::{Duration, Instant}; | 14 | use embassy_time::{Duration, Instant}; |
| 15 | 15 | ||
| 16 | use crate::dma::NoDma; | 16 | use crate::dma::NoDma; |
| 17 | use crate::gpio::sealed::AFType; | 17 | use crate::gpio::{AFType, Pull}; |
| 18 | use crate::gpio::Pull; | ||
| 19 | use crate::interrupt::typelevel::Interrupt; | 18 | use crate::interrupt::typelevel::Interrupt; |
| 20 | use crate::time::Hertz; | 19 | use crate::time::Hertz; |
| 21 | use crate::{interrupt, peripherals}; | 20 | use crate::{interrupt, peripherals}; |
| @@ -175,30 +174,27 @@ impl Timeout { | |||
| 175 | } | 174 | } |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | pub(crate) mod sealed { | 177 | struct State { |
| 179 | use super::*; | 178 | #[allow(unused)] |
| 180 | 179 | waker: AtomicWaker, | |
| 181 | pub struct State { | 180 | } |
| 182 | #[allow(unused)] | ||
| 183 | pub waker: AtomicWaker, | ||
| 184 | } | ||
| 185 | 181 | ||
| 186 | impl State { | 182 | impl State { |
| 187 | pub const fn new() -> Self { | 183 | const fn new() -> Self { |
| 188 | Self { | 184 | Self { |
| 189 | waker: AtomicWaker::new(), | 185 | waker: AtomicWaker::new(), |
| 190 | } | ||
| 191 | } | 186 | } |
| 192 | } | 187 | } |
| 188 | } | ||
| 193 | 189 | ||
| 194 | pub trait Instance: crate::rcc::RccPeripheral { | 190 | trait SealedInstance: crate::rcc::RccPeripheral { |
| 195 | fn regs() -> crate::pac::i2c::I2c; | 191 | fn regs() -> crate::pac::i2c::I2c; |
| 196 | fn state() -> &'static State; | 192 | fn state() -> &'static State; |
| 197 | } | ||
| 198 | } | 193 | } |
| 199 | 194 | ||
| 200 | /// I2C peripheral instance | 195 | /// I2C peripheral instance |
| 201 | pub trait Instance: sealed::Instance + 'static { | 196 | #[allow(private_bounds)] |
| 197 | pub trait Instance: SealedInstance + 'static { | ||
| 202 | /// Event interrupt for this instance | 198 | /// Event interrupt for this instance |
| 203 | type EventInterrupt: interrupt::typelevel::Interrupt; | 199 | type EventInterrupt: interrupt::typelevel::Interrupt; |
| 204 | /// Error interrupt for this instance | 200 | /// Error interrupt for this instance |
| @@ -234,13 +230,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte | |||
| 234 | 230 | ||
| 235 | foreach_peripheral!( | 231 | foreach_peripheral!( |
| 236 | (i2c, $inst:ident) => { | 232 | (i2c, $inst:ident) => { |
| 237 | impl sealed::Instance for peripherals::$inst { | 233 | impl SealedInstance for peripherals::$inst { |
| 238 | fn regs() -> crate::pac::i2c::I2c { | 234 | fn regs() -> crate::pac::i2c::I2c { |
| 239 | crate::pac::$inst | 235 | crate::pac::$inst |
| 240 | } | 236 | } |
| 241 | 237 | ||
| 242 | fn state() -> &'static sealed::State { | 238 | fn state() -> &'static State { |
| 243 | static STATE: sealed::State = sealed::State::new(); | 239 | static STATE: State = State::new(); |
| 244 | &STATE | 240 | &STATE |
| 245 | } | 241 | } |
| 246 | } | 242 | } |
| @@ -311,10 +307,10 @@ impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> { | |||
| 311 | 307 | ||
| 312 | fn transaction( | 308 | fn transaction( |
| 313 | &mut self, | 309 | &mut self, |
| 314 | _address: u8, | 310 | address: u8, |
| 315 | _operations: &mut [embedded_hal_1::i2c::Operation<'_>], | 311 | operations: &mut [embedded_hal_1::i2c::Operation<'_>], |
| 316 | ) -> Result<(), Self::Error> { | 312 | ) -> Result<(), Self::Error> { |
| 317 | todo!(); | 313 | self.blocking_transaction(address, operations) |
| 318 | } | 314 | } |
| 319 | } | 315 | } |
| 320 | 316 | ||
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index cbbc201de..9f29ed5e0 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -10,11 +10,11 @@ use core::task::Poll; | |||
| 10 | use embassy_embedded_hal::SetConfig; | 10 | use embassy_embedded_hal::SetConfig; |
| 11 | use embassy_futures::select::{select, Either}; | 11 | use embassy_futures::select::{select, Either}; |
| 12 | use embassy_hal_internal::drop::OnDrop; | 12 | use embassy_hal_internal::drop::OnDrop; |
| 13 | use embedded_hal_1::i2c::Operation; | ||
| 13 | 14 | ||
| 14 | use super::*; | 15 | use super::*; |
| 15 | use crate::dma::Transfer; | 16 | use crate::dma::Transfer; |
| 16 | use crate::pac::i2c; | 17 | use crate::pac::i2c; |
| 17 | use crate::time::Hertz; | ||
| 18 | 18 | ||
| 19 | // /!\ /!\ | 19 | // /!\ /!\ |
| 20 | // /!\ Implementation note! /!\ | 20 | // /!\ Implementation note! /!\ |
| @@ -41,6 +41,68 @@ pub unsafe fn on_interrupt<T: Instance>() { | |||
| 41 | }); | 41 | }); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | /// Frame type in I2C transaction. | ||
| 45 | /// | ||
| 46 | /// This tells each method what kind of framing to use, to generate a (repeated) start condition (ST | ||
| 47 | /// or SR), and/or a stop condition (SP). For read operations, this also controls whether to send an | ||
| 48 | /// ACK or NACK after the last byte received. | ||
| 49 | /// | ||
| 50 | /// For write operations, the following options are identical because they differ only in the (N)ACK | ||
| 51 | /// treatment relevant for read operations: | ||
| 52 | /// | ||
| 53 | /// - `FirstFrame` and `FirstAndNextFrame` | ||
| 54 | /// - `NextFrame` and `LastFrameNoStop` | ||
| 55 | /// | ||
| 56 | /// Abbreviations used below: | ||
| 57 | /// | ||
| 58 | /// - `ST` = start condition | ||
| 59 | /// - `SR` = repeated start condition | ||
| 60 | /// - `SP` = stop condition | ||
| 61 | #[derive(Copy, Clone)] | ||
| 62 | enum FrameOptions { | ||
| 63 | /// `[ST/SR]+[NACK]+[SP]` First frame (of this type) in operation and last frame overall in this | ||
| 64 | /// transaction. | ||
| 65 | FirstAndLastFrame, | ||
| 66 | /// `[ST/SR]+[NACK]` First frame of this type in transaction, last frame in a read operation but | ||
| 67 | /// not the last frame overall. | ||
| 68 | FirstFrame, | ||
| 69 | /// `[ST/SR]+[ACK]` First frame of this type in transaction, neither last frame overall nor last | ||
| 70 | /// frame in a read operation. | ||
| 71 | FirstAndNextFrame, | ||
| 72 | /// `[ACK]` Middle frame in a read operation (neither first nor last). | ||
| 73 | NextFrame, | ||
| 74 | /// `[NACK]+[SP]` Last frame overall in this transaction but not the first frame. | ||
| 75 | LastFrame, | ||
| 76 | /// `[NACK]` Last frame in a read operation but not last frame overall in this transaction. | ||
| 77 | LastFrameNoStop, | ||
| 78 | } | ||
| 79 | |||
| 80 | impl FrameOptions { | ||
| 81 | /// Sends start or repeated start condition before transfer. | ||
| 82 | fn send_start(self) -> bool { | ||
| 83 | match self { | ||
| 84 | Self::FirstAndLastFrame | Self::FirstFrame | Self::FirstAndNextFrame => true, | ||
| 85 | Self::NextFrame | Self::LastFrame | Self::LastFrameNoStop => false, | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /// Sends stop condition after transfer. | ||
| 90 | fn send_stop(self) -> bool { | ||
| 91 | match self { | ||
| 92 | Self::FirstAndLastFrame | Self::LastFrame => true, | ||
| 93 | Self::FirstFrame | Self::FirstAndNextFrame | Self::NextFrame | Self::LastFrameNoStop => false, | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | /// Sends NACK after last byte received, indicating end of read operation. | ||
| 98 | fn send_nack(self) -> bool { | ||
| 99 | match self { | ||
| 100 | Self::FirstAndLastFrame | Self::FirstFrame | Self::LastFrame | Self::LastFrameNoStop => true, | ||
| 101 | Self::FirstAndNextFrame | Self::NextFrame => false, | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 44 | impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | 106 | impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { |
| 45 | pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { | 107 | pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { |
| 46 | T::regs().cr1().modify(|reg| { | 108 | T::regs().cr1().modify(|reg| { |
| @@ -124,46 +186,57 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 124 | Ok(sr1) | 186 | Ok(sr1) |
| 125 | } | 187 | } |
| 126 | 188 | ||
| 127 | fn write_bytes(&mut self, addr: u8, bytes: &[u8], timeout: Timeout) -> Result<(), Error> { | 189 | fn write_bytes(&mut self, addr: u8, bytes: &[u8], timeout: Timeout, frame: FrameOptions) -> Result<(), Error> { |
| 128 | // Send a START condition | 190 | if frame.send_start() { |
| 191 | // Send a START condition | ||
| 129 | 192 | ||
| 130 | T::regs().cr1().modify(|reg| { | 193 | T::regs().cr1().modify(|reg| { |
| 131 | reg.set_start(true); | 194 | reg.set_start(true); |
| 132 | }); | 195 | }); |
| 133 | 196 | ||
| 134 | // Wait until START condition was generated | 197 | // Wait until START condition was generated |
| 135 | while !Self::check_and_clear_error_flags()?.start() { | 198 | while !Self::check_and_clear_error_flags()?.start() { |
| 136 | timeout.check()?; | 199 | timeout.check()?; |
| 137 | } | 200 | } |
| 138 | 201 | ||
| 139 | // Also wait until signalled we're master and everything is waiting for us | 202 | // Also wait until signalled we're master and everything is waiting for us |
| 140 | while { | 203 | while { |
| 141 | Self::check_and_clear_error_flags()?; | 204 | Self::check_and_clear_error_flags()?; |
| 142 | 205 | ||
| 143 | let sr2 = T::regs().sr2().read(); | 206 | let sr2 = T::regs().sr2().read(); |
| 144 | !sr2.msl() && !sr2.busy() | 207 | !sr2.msl() && !sr2.busy() |
| 145 | } { | 208 | } { |
| 146 | timeout.check()?; | 209 | timeout.check()?; |
| 147 | } | 210 | } |
| 148 | 211 | ||
| 149 | // Set up current address, we're trying to talk to | 212 | // Set up current address, we're trying to talk to |
| 150 | T::regs().dr().write(|reg| reg.set_dr(addr << 1)); | 213 | T::regs().dr().write(|reg| reg.set_dr(addr << 1)); |
| 151 | 214 | ||
| 152 | // Wait until address was sent | 215 | // Wait until address was sent |
| 153 | // Wait for the address to be acknowledged | 216 | // Wait for the address to be acknowledged |
| 154 | // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. | 217 | // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. |
| 155 | while !Self::check_and_clear_error_flags()?.addr() { | 218 | while !Self::check_and_clear_error_flags()?.addr() { |
| 156 | timeout.check()?; | 219 | timeout.check()?; |
| 157 | } | 220 | } |
| 158 | 221 | ||
| 159 | // Clear condition by reading SR2 | 222 | // Clear condition by reading SR2 |
| 160 | let _ = T::regs().sr2().read(); | 223 | let _ = T::regs().sr2().read(); |
| 224 | } | ||
| 161 | 225 | ||
| 162 | // Send bytes | 226 | // Send bytes |
| 163 | for c in bytes { | 227 | for c in bytes { |
| 164 | self.send_byte(*c, timeout)?; | 228 | self.send_byte(*c, timeout)?; |
| 165 | } | 229 | } |
| 166 | 230 | ||
| 231 | if frame.send_stop() { | ||
| 232 | // Send a STOP condition | ||
| 233 | T::regs().cr1().modify(|reg| reg.set_stop(true)); | ||
| 234 | // Wait for STOP condition to transmit. | ||
| 235 | while T::regs().cr1().read().stop() { | ||
| 236 | timeout.check()?; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 167 | // Fallthrough is success | 240 | // Fallthrough is success |
| 168 | Ok(()) | 241 | Ok(()) |
| 169 | } | 242 | } |
| @@ -205,8 +278,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 205 | Ok(value) | 278 | Ok(value) |
| 206 | } | 279 | } |
| 207 | 280 | ||
| 208 | fn blocking_read_timeout(&mut self, addr: u8, buffer: &mut [u8], timeout: Timeout) -> Result<(), Error> { | 281 | fn blocking_read_timeout( |
| 209 | if let Some((last, buffer)) = buffer.split_last_mut() { | 282 | &mut self, |
| 283 | addr: u8, | ||
| 284 | buffer: &mut [u8], | ||
| 285 | timeout: Timeout, | ||
| 286 | frame: FrameOptions, | ||
| 287 | ) -> Result<(), Error> { | ||
| 288 | let Some((last, buffer)) = buffer.split_last_mut() else { | ||
| 289 | return Err(Error::Overrun); | ||
| 290 | }; | ||
| 291 | |||
| 292 | if frame.send_start() { | ||
| 210 | // Send a START condition and set ACK bit | 293 | // Send a START condition and set ACK bit |
| 211 | T::regs().cr1().modify(|reg| { | 294 | T::regs().cr1().modify(|reg| { |
| 212 | reg.set_start(true); | 295 | reg.set_start(true); |
| @@ -237,49 +320,45 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 237 | 320 | ||
| 238 | // Clear condition by reading SR2 | 321 | // Clear condition by reading SR2 |
| 239 | let _ = T::regs().sr2().read(); | 322 | let _ = T::regs().sr2().read(); |
| 323 | } | ||
| 240 | 324 | ||
| 241 | // Receive bytes into buffer | 325 | // Receive bytes into buffer |
| 242 | for c in buffer { | 326 | for c in buffer { |
| 243 | *c = self.recv_byte(timeout)?; | 327 | *c = self.recv_byte(timeout)?; |
| 244 | } | 328 | } |
| 245 | 329 | ||
| 246 | // Prepare to send NACK then STOP after next byte | 330 | // Prepare to send NACK then STOP after next byte |
| 247 | T::regs().cr1().modify(|reg| { | 331 | T::regs().cr1().modify(|reg| { |
| 332 | if frame.send_nack() { | ||
| 248 | reg.set_ack(false); | 333 | reg.set_ack(false); |
| 334 | } | ||
| 335 | if frame.send_stop() { | ||
| 249 | reg.set_stop(true); | 336 | reg.set_stop(true); |
| 250 | }); | 337 | } |
| 338 | }); | ||
| 251 | 339 | ||
| 252 | // Receive last byte | 340 | // Receive last byte |
| 253 | *last = self.recv_byte(timeout)?; | 341 | *last = self.recv_byte(timeout)?; |
| 254 | 342 | ||
| 343 | if frame.send_stop() { | ||
| 255 | // Wait for the STOP to be sent. | 344 | // Wait for the STOP to be sent. |
| 256 | while T::regs().cr1().read().stop() { | 345 | while T::regs().cr1().read().stop() { |
| 257 | timeout.check()?; | 346 | timeout.check()?; |
| 258 | } | 347 | } |
| 259 | |||
| 260 | // Fallthrough is success | ||
| 261 | Ok(()) | ||
| 262 | } else { | ||
| 263 | Err(Error::Overrun) | ||
| 264 | } | 348 | } |
| 349 | |||
| 350 | // Fallthrough is success | ||
| 351 | Ok(()) | ||
| 265 | } | 352 | } |
| 266 | 353 | ||
| 267 | /// Blocking read. | 354 | /// Blocking read. |
| 268 | pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> { | 355 | pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> { |
| 269 | self.blocking_read_timeout(addr, read, self.timeout()) | 356 | self.blocking_read_timeout(addr, read, self.timeout(), FrameOptions::FirstAndLastFrame) |
| 270 | } | 357 | } |
| 271 | 358 | ||
| 272 | /// Blocking write. | 359 | /// Blocking write. |
| 273 | pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> { | 360 | pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> { |
| 274 | let timeout = self.timeout(); | 361 | self.write_bytes(addr, write, self.timeout(), FrameOptions::FirstAndLastFrame)?; |
| 275 | |||
| 276 | self.write_bytes(addr, write, timeout)?; | ||
| 277 | // Send a STOP condition | ||
| 278 | T::regs().cr1().modify(|reg| reg.set_stop(true)); | ||
| 279 | // Wait for STOP condition to transmit. | ||
| 280 | while T::regs().cr1().read().stop() { | ||
| 281 | timeout.check()?; | ||
| 282 | } | ||
| 283 | 362 | ||
| 284 | // Fallthrough is success | 363 | // Fallthrough is success |
| 285 | Ok(()) | 364 | Ok(()) |
| @@ -287,10 +366,85 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 287 | 366 | ||
| 288 | /// Blocking write, restart, read. | 367 | /// Blocking write, restart, read. |
| 289 | pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { | 368 | pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { |
| 369 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the | ||
| 370 | // stop condition below. | ||
| 371 | if read.is_empty() { | ||
| 372 | return Err(Error::Overrun); | ||
| 373 | } | ||
| 374 | |||
| 290 | let timeout = self.timeout(); | 375 | let timeout = self.timeout(); |
| 291 | 376 | ||
| 292 | self.write_bytes(addr, write, timeout)?; | 377 | self.write_bytes(addr, write, timeout, FrameOptions::FirstFrame)?; |
| 293 | self.blocking_read_timeout(addr, read, timeout)?; | 378 | self.blocking_read_timeout(addr, read, timeout, FrameOptions::FirstAndLastFrame)?; |
| 379 | |||
| 380 | Ok(()) | ||
| 381 | } | ||
| 382 | |||
| 383 | /// Blocking transaction with operations. | ||
| 384 | /// | ||
| 385 | /// Consecutive operations of same type are merged. See [transaction contract] for details. | ||
| 386 | /// | ||
| 387 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction | ||
| 388 | pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { | ||
| 389 | // Check empty read buffer before starting transaction. Otherwise, we would not generate the | ||
| 390 | // stop condition below. | ||
| 391 | if operations.iter().any(|op| match op { | ||
| 392 | Operation::Read(read) => read.is_empty(), | ||
| 393 | Operation::Write(_) => false, | ||
| 394 | }) { | ||
| 395 | return Err(Error::Overrun); | ||
| 396 | } | ||
| 397 | |||
| 398 | let timeout = self.timeout(); | ||
| 399 | |||
| 400 | let mut operations = operations.iter_mut(); | ||
| 401 | |||
| 402 | let mut prev_op: Option<&mut Operation<'_>> = None; | ||
| 403 | let mut next_op = operations.next(); | ||
| 404 | |||
| 405 | while let Some(op) = next_op { | ||
| 406 | next_op = operations.next(); | ||
| 407 | |||
| 408 | // Check if this is the first frame of this type. This is the case for the first overall | ||
| 409 | // frame in the transaction and whenever the type of operation changes. | ||
| 410 | let first_frame = | ||
| 411 | match (prev_op.as_ref(), &op) { | ||
| 412 | (None, _) => true, | ||
| 413 | (Some(Operation::Read(_)), Operation::Write(_)) | ||
| 414 | | (Some(Operation::Write(_)), Operation::Read(_)) => true, | ||
| 415 | (Some(Operation::Read(_)), Operation::Read(_)) | ||
| 416 | | (Some(Operation::Write(_)), Operation::Write(_)) => false, | ||
| 417 | }; | ||
| 418 | |||
| 419 | let frame = match (first_frame, next_op.as_ref()) { | ||
| 420 | // If this is the first frame of this type, we generate a (repeated) start condition | ||
| 421 | // but have to consider the next operation: if it is the last, we generate the final | ||
| 422 | // stop condition. Otherwise, we branch on the operation: with read operations, only | ||
| 423 | // the last byte overall (before a write operation or the end of the transaction) is | ||
| 424 | // to be NACK'd, i.e. if another read operation follows, we must ACK this last byte. | ||
| 425 | (true, None) => FrameOptions::FirstAndLastFrame, | ||
| 426 | // Make sure to keep sending ACK for last byte in read operation when it is followed | ||
| 427 | // by another consecutive read operation. If the current operation is write, this is | ||
| 428 | // identical to `FirstFrame`. | ||
| 429 | (true, Some(Operation::Read(_))) => FrameOptions::FirstAndNextFrame, | ||
| 430 | // Otherwise, send NACK for last byte (in read operation). (For write, this does not | ||
| 431 | // matter and could also be `FirstAndNextFrame`.) | ||
| 432 | (true, Some(Operation::Write(_))) => FrameOptions::FirstFrame, | ||
| 433 | |||
| 434 | // If this is not the first frame of its type, we do not generate a (repeated) start | ||
| 435 | // condition. Otherwise, we branch the same way as above. | ||
| 436 | (false, None) => FrameOptions::LastFrame, | ||
| 437 | (false, Some(Operation::Read(_))) => FrameOptions::NextFrame, | ||
| 438 | (false, Some(Operation::Write(_))) => FrameOptions::LastFrameNoStop, | ||
| 439 | }; | ||
| 440 | |||
| 441 | match op { | ||
| 442 | Operation::Read(read) => self.blocking_read_timeout(addr, read, timeout, frame)?, | ||
| 443 | Operation::Write(write) => self.write_bytes(addr, write, timeout, frame)?, | ||
| 444 | } | ||
| 445 | |||
| 446 | prev_op = Some(op); | ||
| 447 | } | ||
| 294 | 448 | ||
| 295 | Ok(()) | 449 | Ok(()) |
| 296 | } | 450 | } |
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index bd3abaac1..8baf2849d 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -4,11 +4,11 @@ use core::task::Poll; | |||
| 4 | 4 | ||
| 5 | use embassy_embedded_hal::SetConfig; | 5 | use embassy_embedded_hal::SetConfig; |
| 6 | use embassy_hal_internal::drop::OnDrop; | 6 | use embassy_hal_internal::drop::OnDrop; |
| 7 | use embedded_hal_1::i2c::Operation; | ||
| 7 | 8 | ||
| 8 | use super::*; | 9 | use super::*; |
| 9 | use crate::dma::Transfer; | 10 | use crate::dma::Transfer; |
| 10 | use crate::pac::i2c; | 11 | use crate::pac::i2c; |
| 11 | use crate::time::Hertz; | ||
| 12 | 12 | ||
| 13 | pub(crate) unsafe fn on_interrupt<T: Instance>() { | 13 | pub(crate) unsafe fn on_interrupt<T: Instance>() { |
| 14 | let regs = T::regs(); | 14 | let regs = T::regs(); |
| @@ -579,6 +579,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 579 | // Automatic Stop | 579 | // Automatic Stop |
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | /// Blocking transaction with operations. | ||
| 583 | /// | ||
| 584 | /// Consecutive operations of same type are merged. See [transaction contract] for details. | ||
| 585 | /// | ||
| 586 | /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction | ||
| 587 | pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { | ||
| 588 | let _ = addr; | ||
| 589 | let _ = operations; | ||
| 590 | todo!() | ||
| 591 | } | ||
| 592 | |||
| 582 | /// Blocking write multiple buffers. | 593 | /// Blocking write multiple buffers. |
| 583 | /// | 594 | /// |
| 584 | /// The buffers are concatenated in a single write transaction. | 595 | /// The buffers are concatenated in a single write transaction. |
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index fa9ec0532..c5a606b21 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | //! Inter-IC Sound (I2S) | 1 | //! Inter-IC Sound (I2S) |
| 2 | use embassy_hal_internal::into_ref; | 2 | use embassy_hal_internal::into_ref; |
| 3 | 3 | ||
| 4 | use crate::gpio::sealed::{AFType, Pin as _}; | 4 | use crate::gpio::{AFType, AnyPin, SealedPin}; |
| 5 | use crate::gpio::AnyPin; | ||
| 6 | use crate::pac::spi::vals; | 5 | use crate::pac::spi::vals; |
| 7 | use crate::spi::{Config as SpiConfig, *}; | 6 | use crate::spi::{Config as SpiConfig, *}; |
| 8 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 523719bb9..4d535cce2 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs | |||
| @@ -4,11 +4,12 @@ use core::future::poll_fn; | |||
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 5 | use core::task::Poll; | 5 | use core::task::Poll; |
| 6 | 6 | ||
| 7 | use self::sealed::Instance; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | |||
| 8 | use crate::interrupt; | 9 | use crate::interrupt; |
| 9 | use crate::interrupt::typelevel::Interrupt; | 10 | use crate::interrupt::typelevel::Interrupt; |
| 10 | use crate::peripherals::IPCC; | 11 | use crate::peripherals::IPCC; |
| 11 | use crate::rcc::sealed::RccPeripheral; | 12 | use crate::rcc::SealedRccPeripheral; |
| 12 | 13 | ||
| 13 | /// Interrupt handler. | 14 | /// Interrupt handler. |
| 14 | pub struct ReceiveInterruptHandler {} | 15 | pub struct ReceiveInterruptHandler {} |
| @@ -207,7 +208,7 @@ impl Ipcc { | |||
| 207 | } | 208 | } |
| 208 | } | 209 | } |
| 209 | 210 | ||
| 210 | impl sealed::Instance for crate::peripherals::IPCC { | 211 | impl SealedInstance for crate::peripherals::IPCC { |
| 211 | fn regs() -> crate::pac::ipcc::Ipcc { | 212 | fn regs() -> crate::pac::ipcc::Ipcc { |
| 212 | crate::pac::IPCC | 213 | crate::pac::IPCC |
| 213 | } | 214 | } |
| @@ -216,58 +217,52 @@ impl sealed::Instance for crate::peripherals::IPCC { | |||
| 216 | crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled)); | 217 | crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled)); |
| 217 | } | 218 | } |
| 218 | 219 | ||
| 219 | fn state() -> &'static self::sealed::State { | 220 | fn state() -> &'static State { |
| 220 | static STATE: self::sealed::State = self::sealed::State::new(); | 221 | static STATE: State = State::new(); |
| 221 | &STATE | 222 | &STATE |
| 222 | } | 223 | } |
| 223 | } | 224 | } |
| 224 | 225 | ||
| 225 | pub(crate) mod sealed { | 226 | struct State { |
| 226 | use embassy_sync::waitqueue::AtomicWaker; | 227 | rx_wakers: [AtomicWaker; 6], |
| 227 | 228 | tx_wakers: [AtomicWaker; 6], | |
| 228 | use super::*; | 229 | } |
| 229 | |||
| 230 | pub struct State { | ||
| 231 | rx_wakers: [AtomicWaker; 6], | ||
| 232 | tx_wakers: [AtomicWaker; 6], | ||
| 233 | } | ||
| 234 | 230 | ||
| 235 | impl State { | 231 | impl State { |
| 236 | pub const fn new() -> Self { | 232 | const fn new() -> Self { |
| 237 | const WAKER: AtomicWaker = AtomicWaker::new(); | 233 | const WAKER: AtomicWaker = AtomicWaker::new(); |
| 238 | 234 | ||
| 239 | Self { | 235 | Self { |
| 240 | rx_wakers: [WAKER; 6], | 236 | rx_wakers: [WAKER; 6], |
| 241 | tx_wakers: [WAKER; 6], | 237 | tx_wakers: [WAKER; 6], |
| 242 | } | ||
| 243 | } | 238 | } |
| 239 | } | ||
| 244 | 240 | ||
| 245 | pub const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { | 241 | const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { |
| 246 | match channel { | 242 | match channel { |
| 247 | IpccChannel::Channel1 => &self.rx_wakers[0], | 243 | IpccChannel::Channel1 => &self.rx_wakers[0], |
| 248 | IpccChannel::Channel2 => &self.rx_wakers[1], | 244 | IpccChannel::Channel2 => &self.rx_wakers[1], |
| 249 | IpccChannel::Channel3 => &self.rx_wakers[2], | 245 | IpccChannel::Channel3 => &self.rx_wakers[2], |
| 250 | IpccChannel::Channel4 => &self.rx_wakers[3], | 246 | IpccChannel::Channel4 => &self.rx_wakers[3], |
| 251 | IpccChannel::Channel5 => &self.rx_wakers[4], | 247 | IpccChannel::Channel5 => &self.rx_wakers[4], |
| 252 | IpccChannel::Channel6 => &self.rx_wakers[5], | 248 | IpccChannel::Channel6 => &self.rx_wakers[5], |
| 253 | } | ||
| 254 | } | 249 | } |
| 250 | } | ||
| 255 | 251 | ||
| 256 | pub const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { | 252 | const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { |
| 257 | match channel { | 253 | match channel { |
| 258 | IpccChannel::Channel1 => &self.tx_wakers[0], | 254 | IpccChannel::Channel1 => &self.tx_wakers[0], |
| 259 | IpccChannel::Channel2 => &self.tx_wakers[1], | 255 | IpccChannel::Channel2 => &self.tx_wakers[1], |
| 260 | IpccChannel::Channel3 => &self.tx_wakers[2], | 256 | IpccChannel::Channel3 => &self.tx_wakers[2], |
| 261 | IpccChannel::Channel4 => &self.tx_wakers[3], | 257 | IpccChannel::Channel4 => &self.tx_wakers[3], |
| 262 | IpccChannel::Channel5 => &self.tx_wakers[4], | 258 | IpccChannel::Channel5 => &self.tx_wakers[4], |
| 263 | IpccChannel::Channel6 => &self.tx_wakers[5], | 259 | IpccChannel::Channel6 => &self.tx_wakers[5], |
| 264 | } | ||
| 265 | } | 260 | } |
| 266 | } | 261 | } |
| 262 | } | ||
| 267 | 263 | ||
| 268 | pub trait Instance: crate::rcc::RccPeripheral { | 264 | trait SealedInstance: crate::rcc::RccPeripheral { |
| 269 | fn regs() -> crate::pac::ipcc::Ipcc; | 265 | fn regs() -> crate::pac::ipcc::Ipcc; |
| 270 | fn set_cpu2(enabled: bool); | 266 | fn set_cpu2(enabled: bool); |
| 271 | fn state() -> &'static State; | 267 | fn state() -> &'static State; |
| 272 | } | ||
| 273 | } | 268 | } |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index b38b5c29d..6a3d1c463 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -79,10 +79,8 @@ pub mod ucpd; | |||
| 79 | pub mod uid; | 79 | pub mod uid; |
| 80 | #[cfg(usart)] | 80 | #[cfg(usart)] |
| 81 | pub mod usart; | 81 | pub mod usart; |
| 82 | #[cfg(usb)] | 82 | #[cfg(any(usb, otg))] |
| 83 | pub mod usb; | 83 | pub mod usb; |
| 84 | #[cfg(otg)] | ||
| 85 | pub mod usb_otg; | ||
| 86 | #[cfg(iwdg)] | 84 | #[cfg(iwdg)] |
| 87 | pub mod wdg; | 85 | pub mod wdg; |
| 88 | 86 | ||
| @@ -107,10 +105,10 @@ pub use crate::_generated::interrupt; | |||
| 107 | /// Example of how to bind one interrupt: | 105 | /// Example of how to bind one interrupt: |
| 108 | /// | 106 | /// |
| 109 | /// ```rust,ignore | 107 | /// ```rust,ignore |
| 110 | /// use embassy_stm32::{bind_interrupts, usb_otg, peripherals}; | 108 | /// use embassy_stm32::{bind_interrupts, usb, peripherals}; |
| 111 | /// | 109 | /// |
| 112 | /// bind_interrupts!(struct Irqs { | 110 | /// bind_interrupts!(struct Irqs { |
| 113 | /// OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 111 | /// OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 114 | /// }); | 112 | /// }); |
| 115 | /// ``` | 113 | /// ``` |
| 116 | /// | 114 | /// |
| @@ -160,7 +158,7 @@ pub(crate) use stm32_metapac as pac; | |||
| 160 | use crate::interrupt::Priority; | 158 | use crate::interrupt::Priority; |
| 161 | #[cfg(feature = "rt")] | 159 | #[cfg(feature = "rt")] |
| 162 | pub use crate::pac::NVIC_PRIO_BITS; | 160 | pub use crate::pac::NVIC_PRIO_BITS; |
| 163 | use crate::rcc::sealed::RccPeripheral; | 161 | use crate::rcc::SealedRccPeripheral; |
| 164 | 162 | ||
| 165 | /// `embassy-stm32` global configuration. | 163 | /// `embassy-stm32` global configuration. |
| 166 | #[non_exhaustive] | 164 | #[non_exhaustive] |
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index cf531e266..a3b4352c0 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs | |||
| @@ -81,8 +81,8 @@ impl<'d, T: Instance> OpAmp<'d, T> { | |||
| 81 | /// [`OpAmpOutput`] is dropped. | 81 | /// [`OpAmpOutput`] is dropped. |
| 82 | pub fn buffer_ext( | 82 | pub fn buffer_ext( |
| 83 | &'d mut self, | 83 | &'d mut self, |
| 84 | in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>, | 84 | in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>, |
| 85 | out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::sealed::Pin> + 'd, | 85 | out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::Pin> + 'd, |
| 86 | gain: OpAmpGain, | 86 | gain: OpAmpGain, |
| 87 | ) -> OpAmpOutput<'d, T> { | 87 | ) -> OpAmpOutput<'d, T> { |
| 88 | into_ref!(in_pin); | 88 | into_ref!(in_pin); |
| @@ -122,7 +122,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { | |||
| 122 | #[cfg(opamp_g4)] | 122 | #[cfg(opamp_g4)] |
| 123 | pub fn buffer_int( | 123 | pub fn buffer_int( |
| 124 | &'d mut self, | 124 | &'d mut self, |
| 125 | pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>, | 125 | pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>, |
| 126 | gain: OpAmpGain, | 126 | gain: OpAmpGain, |
| 127 | ) -> OpAmpInternalOutput<'d, T> { | 127 | ) -> OpAmpInternalOutput<'d, T> { |
| 128 | into_ref!(pin); | 128 | into_ref!(pin); |
| @@ -166,37 +166,39 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> { | |||
| 166 | } | 166 | } |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | /// Opamp instance trait. | 169 | pub(crate) trait SealedInstance { |
| 170 | pub trait Instance: sealed::Instance + 'static {} | 170 | fn regs() -> crate::pac::opamp::Opamp; |
| 171 | 171 | } | |
| 172 | pub(crate) mod sealed { | ||
| 173 | pub trait Instance { | ||
| 174 | fn regs() -> crate::pac::opamp::Opamp; | ||
| 175 | } | ||
| 176 | |||
| 177 | pub trait NonInvertingPin<T: Instance> { | ||
| 178 | fn channel(&self) -> u8; | ||
| 179 | } | ||
| 180 | 172 | ||
| 181 | pub trait InvertingPin<T: Instance> { | 173 | pub(crate) trait SealedNonInvertingPin<T: Instance> { |
| 182 | fn channel(&self) -> u8; | 174 | fn channel(&self) -> u8; |
| 183 | } | 175 | } |
| 184 | 176 | ||
| 185 | pub trait OutputPin<T: Instance> {} | 177 | pub(crate) trait SealedInvertingPin<T: Instance> { |
| 178 | #[allow(unused)] | ||
| 179 | fn channel(&self) -> u8; | ||
| 186 | } | 180 | } |
| 187 | 181 | ||
| 182 | pub(crate) trait SealedOutputPin<T: Instance> {} | ||
| 183 | |||
| 184 | /// Opamp instance trait. | ||
| 185 | #[allow(private_bounds)] | ||
| 186 | pub trait Instance: SealedInstance + 'static {} | ||
| 188 | /// Non-inverting pin trait. | 187 | /// Non-inverting pin trait. |
| 189 | pub trait NonInvertingPin<T: Instance>: sealed::NonInvertingPin<T> {} | 188 | #[allow(private_bounds)] |
| 189 | pub trait NonInvertingPin<T: Instance>: SealedNonInvertingPin<T> {} | ||
| 190 | /// Inverting pin trait. | 190 | /// Inverting pin trait. |
| 191 | pub trait InvertingPin<T: Instance>: sealed::InvertingPin<T> {} | 191 | #[allow(private_bounds)] |
| 192 | pub trait InvertingPin<T: Instance>: SealedInvertingPin<T> {} | ||
| 192 | /// Output pin trait. | 193 | /// Output pin trait. |
| 193 | pub trait OutputPin<T: Instance>: sealed::OutputPin<T> {} | 194 | #[allow(private_bounds)] |
| 195 | pub trait OutputPin<T: Instance>: SealedOutputPin<T> {} | ||
| 194 | 196 | ||
| 195 | macro_rules! impl_opamp_external_output { | 197 | macro_rules! impl_opamp_external_output { |
| 196 | ($inst:ident, $adc:ident, $ch:expr) => { | 198 | ($inst:ident, $adc:ident, $ch:expr) => { |
| 197 | foreach_adc!( | 199 | foreach_adc!( |
| 198 | ($adc, $common_inst:ident, $adc_clock:ident) => { | 200 | ($adc, $common_inst:ident, $adc_clock:ident) => { |
| 199 | impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc> | 201 | impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc> |
| 200 | for OpAmpOutput<'d, crate::peripherals::$inst> | 202 | for OpAmpOutput<'d, crate::peripherals::$inst> |
| 201 | { | 203 | { |
| 202 | fn channel(&self) -> u8 { | 204 | fn channel(&self) -> u8 { |
| @@ -242,7 +244,7 @@ macro_rules! impl_opamp_internal_output { | |||
| 242 | ($inst:ident, $adc:ident, $ch:expr) => { | 244 | ($inst:ident, $adc:ident, $ch:expr) => { |
| 243 | foreach_adc!( | 245 | foreach_adc!( |
| 244 | ($adc, $common_inst:ident, $adc_clock:ident) => { | 246 | ($adc, $common_inst:ident, $adc_clock:ident) => { |
| 245 | impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc> | 247 | impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc> |
| 246 | for OpAmpInternalOutput<'d, crate::peripherals::$inst> | 248 | for OpAmpInternalOutput<'d, crate::peripherals::$inst> |
| 247 | { | 249 | { |
| 248 | fn channel(&self) -> u8 { | 250 | fn channel(&self) -> u8 { |
| @@ -291,7 +293,7 @@ foreach_peripheral!( | |||
| 291 | 293 | ||
| 292 | foreach_peripheral! { | 294 | foreach_peripheral! { |
| 293 | (opamp, $inst:ident) => { | 295 | (opamp, $inst:ident) => { |
| 294 | impl sealed::Instance for crate::peripherals::$inst { | 296 | impl SealedInstance for crate::peripherals::$inst { |
| 295 | fn regs() -> crate::pac::opamp::Opamp { | 297 | fn regs() -> crate::pac::opamp::Opamp { |
| 296 | crate::pac::$inst | 298 | crate::pac::$inst |
| 297 | } | 299 | } |
| @@ -306,7 +308,7 @@ foreach_peripheral! { | |||
| 306 | macro_rules! impl_opamp_vp_pin { | 308 | macro_rules! impl_opamp_vp_pin { |
| 307 | ($inst:ident, $pin:ident, $ch:expr) => { | 309 | ($inst:ident, $pin:ident, $ch:expr) => { |
| 308 | impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {} | 310 | impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {} |
| 309 | impl crate::opamp::sealed::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin { | 311 | impl crate::opamp::SealedNonInvertingPin<peripherals::$inst> for crate::peripherals::$pin { |
| 310 | fn channel(&self) -> u8 { | 312 | fn channel(&self) -> u8 { |
| 311 | $ch | 313 | $ch |
| 312 | } | 314 | } |
| @@ -318,6 +320,6 @@ macro_rules! impl_opamp_vp_pin { | |||
| 318 | macro_rules! impl_opamp_vout_pin { | 320 | macro_rules! impl_opamp_vout_pin { |
| 319 | ($inst:ident, $pin:ident) => { | 321 | ($inst:ident, $pin:ident) => { |
| 320 | impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} | 322 | impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} |
| 321 | impl crate::opamp::sealed::OutputPin<peripherals::$inst> for crate::peripherals::$pin {} | 323 | impl crate::opamp::SealedOutputPin<peripherals::$inst> for crate::peripherals::$pin {} |
| 322 | }; | 324 | }; |
| 323 | } | 325 | } |
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 8a709a89e..3c054e666 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs | |||
| @@ -8,8 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 8 | use enums::*; | 8 | use enums::*; |
| 9 | 9 | ||
| 10 | use crate::dma::Transfer; | 10 | use crate::dma::Transfer; |
| 11 | use crate::gpio::sealed::AFType; | 11 | use crate::gpio::{AFType, AnyPin, Pull}; |
| 12 | use crate::gpio::{AnyPin, Pull}; | ||
| 13 | use crate::pac::quadspi::Quadspi as Regs; | 12 | use crate::pac::quadspi::Quadspi as Regs; |
| 14 | use crate::rcc::RccPeripheral; | 13 | use crate::rcc::RccPeripheral; |
| 15 | use crate::{peripherals, Peripheral}; | 14 | use crate::{peripherals, Peripheral}; |
| @@ -381,16 +380,13 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | |||
| 381 | } | 380 | } |
| 382 | } | 381 | } |
| 383 | 382 | ||
| 384 | pub(crate) mod sealed { | 383 | trait SealedInstance { |
| 385 | use super::*; | 384 | const REGS: Regs; |
| 386 | |||
| 387 | pub trait Instance { | ||
| 388 | const REGS: Regs; | ||
| 389 | } | ||
| 390 | } | 385 | } |
| 391 | 386 | ||
| 392 | /// QSPI instance trait. | 387 | /// QSPI instance trait. |
| 393 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} | 388 | #[allow(private_bounds)] |
| 389 | pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} | ||
| 394 | 390 | ||
| 395 | pin_trait!(SckPin, Instance); | 391 | pin_trait!(SckPin, Instance); |
| 396 | pin_trait!(BK1D0Pin, Instance); | 392 | pin_trait!(BK1D0Pin, Instance); |
| @@ -409,7 +405,7 @@ dma_trait!(QuadDma, Instance); | |||
| 409 | 405 | ||
| 410 | foreach_peripheral!( | 406 | foreach_peripheral!( |
| 411 | (quadspi, $inst:ident) => { | 407 | (quadspi, $inst:ident) => { |
| 412 | impl sealed::Instance for peripherals::$inst { | 408 | impl SealedInstance for peripherals::$inst { |
| 413 | const REGS: Regs = crate::pac::$inst; | 409 | const REGS: Regs = crate::pac::$inst; |
| 414 | } | 410 | } |
| 415 | 411 | ||
diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs index 19a8c8cb9..6f0d7b379 100644 --- a/embassy-stm32/src/rcc/hsi48.rs +++ b/embassy-stm32/src/rcc/hsi48.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | use crate::pac::crs::vals::Syncsrc; | 3 | use crate::pac::crs::vals::Syncsrc; |
| 4 | use crate::pac::{CRS, RCC}; | 4 | use crate::pac::{CRS, RCC}; |
| 5 | use crate::rcc::sealed::RccPeripheral; | 5 | use crate::rcc::SealedRccPeripheral; |
| 6 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| 7 | 7 | ||
| 8 | /// HSI48 speed | 8 | /// HSI48 speed |
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 654943bc1..d8604e07e 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs | |||
| @@ -2,8 +2,7 @@ use core::marker::PhantomData; | |||
| 2 | 2 | ||
| 3 | use embassy_hal_internal::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | 4 | ||
| 5 | use crate::gpio::sealed::AFType; | 5 | use crate::gpio::{AFType, Speed}; |
| 6 | use crate::gpio::Speed; | ||
| 7 | #[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] | 6 | #[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] |
| 8 | pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; | 7 | pub use crate::pac::rcc::vals::Mcopre as McoPrescaler; |
| 9 | #[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))] | 8 | #[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))] |
| @@ -19,23 +18,25 @@ pub enum McoPrescaler { | |||
| 19 | DIV1, | 18 | DIV1, |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | pub(crate) mod sealed { | 21 | pub(crate) trait SealedMcoInstance {} |
| 23 | pub trait McoInstance { | ||
| 24 | type Source; | ||
| 25 | unsafe fn apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | 22 | ||
| 29 | pub trait McoInstance: sealed::McoInstance + 'static {} | 23 | #[allow(private_bounds)] |
| 24 | pub trait McoInstance: SealedMcoInstance + 'static { | ||
| 25 | type Source; | ||
| 26 | |||
| 27 | #[doc(hidden)] | ||
| 28 | unsafe fn _apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler); | ||
| 29 | } | ||
| 30 | 30 | ||
| 31 | pin_trait!(McoPin, McoInstance); | 31 | pin_trait!(McoPin, McoInstance); |
| 32 | 32 | ||
| 33 | macro_rules! impl_peri { | 33 | macro_rules! impl_peri { |
| 34 | ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { | 34 | ($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => { |
| 35 | impl sealed::McoInstance for peripherals::$peri { | 35 | impl SealedMcoInstance for peripherals::$peri {} |
| 36 | impl McoInstance for peripherals::$peri { | ||
| 36 | type Source = $source; | 37 | type Source = $source; |
| 37 | 38 | ||
| 38 | unsafe fn apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) { | 39 | unsafe fn _apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) { |
| 39 | #[cfg(not(any(stm32u5, stm32wba)))] | 40 | #[cfg(not(any(stm32u5, stm32wba)))] |
| 40 | let r = RCC.cfgr(); | 41 | let r = RCC.cfgr(); |
| 41 | #[cfg(any(stm32u5, stm32wba))] | 42 | #[cfg(any(stm32u5, stm32wba))] |
| @@ -48,8 +49,6 @@ macro_rules! impl_peri { | |||
| 48 | }); | 49 | }); |
| 49 | } | 50 | } |
| 50 | } | 51 | } |
| 51 | |||
| 52 | impl McoInstance for peripherals::$peri {} | ||
| 53 | }; | 52 | }; |
| 54 | } | 53 | } |
| 55 | 54 | ||
| @@ -79,7 +78,7 @@ impl<'d, T: McoInstance> Mco<'d, T> { | |||
| 79 | into_ref!(pin); | 78 | into_ref!(pin); |
| 80 | 79 | ||
| 81 | critical_section::with(|_| unsafe { | 80 | critical_section::with(|_| unsafe { |
| 82 | T::apply_clock_settings(source, prescaler); | 81 | T::_apply_clock_settings(source, prescaler); |
| 83 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); | 82 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); |
| 84 | pin.set_speed(Speed::VeryHigh); | 83 | pin.set_speed(Speed::VeryHigh); |
| 85 | }); | 84 | }); |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 910ebe205..d53d02203 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -10,6 +10,7 @@ pub use bd::*; | |||
| 10 | 10 | ||
| 11 | #[cfg(any(mco, mco1, mco2))] | 11 | #[cfg(any(mco, mco1, mco2))] |
| 12 | mod mco; | 12 | mod mco; |
| 13 | use critical_section::CriticalSection; | ||
| 13 | #[cfg(any(mco, mco1, mco2))] | 14 | #[cfg(any(mco, mco1, mco2))] |
| 14 | pub use mco::*; | 15 | pub use mco::*; |
| 15 | 16 | ||
| @@ -32,6 +33,7 @@ mod _version; | |||
| 32 | pub use _version::*; | 33 | pub use _version::*; |
| 33 | 34 | ||
| 34 | pub use crate::_generated::{mux, Clocks}; | 35 | pub use crate::_generated::{mux, Clocks}; |
| 36 | use crate::time::Hertz; | ||
| 35 | 37 | ||
| 36 | #[cfg(feature = "low-power")] | 38 | #[cfg(feature = "low-power")] |
| 37 | /// Must be written within a critical section | 39 | /// Must be written within a critical section |
| @@ -63,29 +65,21 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks { | |||
| 63 | CLOCK_FREQS.assume_init_ref() | 65 | CLOCK_FREQS.assume_init_ref() |
| 64 | } | 66 | } |
| 65 | 67 | ||
| 66 | #[cfg(feature = "unstable-pac")] | 68 | pub(crate) trait SealedRccPeripheral { |
| 67 | pub mod low_level { | 69 | fn frequency() -> crate::time::Hertz; |
| 68 | pub use super::sealed::*; | 70 | fn enable_and_reset_with_cs(cs: CriticalSection); |
| 69 | } | 71 | fn disable_with_cs(cs: CriticalSection); |
| 70 | |||
| 71 | pub(crate) mod sealed { | ||
| 72 | use critical_section::CriticalSection; | ||
| 73 | |||
| 74 | pub trait RccPeripheral { | ||
| 75 | fn frequency() -> crate::time::Hertz; | ||
| 76 | fn enable_and_reset_with_cs(cs: CriticalSection); | ||
| 77 | fn disable_with_cs(cs: CriticalSection); | ||
| 78 | 72 | ||
| 79 | fn enable_and_reset() { | 73 | fn enable_and_reset() { |
| 80 | critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) | 74 | critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) |
| 81 | } | 75 | } |
| 82 | fn disable() { | 76 | fn disable() { |
| 83 | critical_section::with(|cs| Self::disable_with_cs(cs)) | 77 | critical_section::with(|cs| Self::disable_with_cs(cs)) |
| 84 | } | ||
| 85 | } | 78 | } |
| 86 | } | 79 | } |
| 87 | 80 | ||
| 88 | pub trait RccPeripheral: sealed::RccPeripheral + 'static {} | 81 | #[allow(private_bounds)] |
| 82 | pub trait RccPeripheral: SealedRccPeripheral + 'static {} | ||
| 89 | 83 | ||
| 90 | #[allow(unused)] | 84 | #[allow(unused)] |
| 91 | mod util { | 85 | mod util { |
| @@ -116,3 +110,12 @@ mod util { | |||
| 116 | Ok(Some(x)) | 110 | Ok(Some(x)) |
| 117 | } | 111 | } |
| 118 | } | 112 | } |
| 113 | |||
| 114 | /// Get the kernel clocok frequency of the peripheral `T`. | ||
| 115 | /// | ||
| 116 | /// # Panics | ||
| 117 | /// | ||
| 118 | /// Panics if the clock is not active. | ||
| 119 | pub fn frequency<T: RccPeripheral>() -> Hertz { | ||
| 120 | T::frequency() | ||
| 121 | } | ||
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index ca641f352..7a228e4a4 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs | |||
| @@ -222,16 +222,13 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> { | |||
| 222 | 222 | ||
| 223 | impl<'d, T: Instance> CryptoRng for Rng<'d, T> {} | 223 | impl<'d, T: Instance> CryptoRng for Rng<'d, T> {} |
| 224 | 224 | ||
| 225 | pub(crate) mod sealed { | 225 | trait SealedInstance { |
| 226 | use super::*; | 226 | fn regs() -> pac::rng::Rng; |
| 227 | |||
| 228 | pub trait Instance { | ||
| 229 | fn regs() -> pac::rng::Rng; | ||
| 230 | } | ||
| 231 | } | 227 | } |
| 232 | 228 | ||
| 233 | /// RNG instance trait. | 229 | /// RNG instance trait. |
| 234 | pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { | 230 | #[allow(private_bounds)] |
| 231 | pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { | ||
| 235 | /// Interrupt for this RNG instance. | 232 | /// Interrupt for this RNG instance. |
| 236 | type Interrupt: interrupt::typelevel::Interrupt; | 233 | type Interrupt: interrupt::typelevel::Interrupt; |
| 237 | } | 234 | } |
| @@ -242,7 +239,7 @@ foreach_interrupt!( | |||
| 242 | type Interrupt = crate::interrupt::typelevel::$irq; | 239 | type Interrupt = crate::interrupt::typelevel::$irq; |
| 243 | } | 240 | } |
| 244 | 241 | ||
| 245 | impl sealed::Instance for peripherals::$inst { | 242 | impl SealedInstance for peripherals::$inst { |
| 246 | fn regs() -> crate::pac::rng::Rng { | 243 | fn regs() -> crate::pac::rng::Rng { |
| 247 | crate::pac::$inst | 244 | crate::pac::$inst |
| 248 | } | 245 | } |
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index ef92fa4bb..bab8cf4a3 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs | |||
| @@ -1,13 +1,10 @@ | |||
| 1 | #[cfg(feature = "chrono")] | 1 | #[cfg(feature = "chrono")] |
| 2 | use core::convert::From; | 2 | use chrono::{Datelike, NaiveDate, Timelike, Weekday}; |
| 3 | |||
| 4 | #[cfg(feature = "chrono")] | ||
| 5 | use chrono::{self, Datelike, NaiveDate, Timelike, Weekday}; | ||
| 6 | 3 | ||
| 7 | #[cfg(any(feature = "defmt", feature = "time"))] | 4 | #[cfg(any(feature = "defmt", feature = "time"))] |
| 8 | use crate::peripherals::RTC; | 5 | use crate::peripherals::RTC; |
| 9 | #[cfg(any(feature = "defmt", feature = "time"))] | 6 | #[cfg(any(feature = "defmt", feature = "time"))] |
| 10 | use crate::rtc::sealed::Instance; | 7 | use crate::rtc::SealedInstance; |
| 11 | 8 | ||
| 12 | /// 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 |
| 13 | pub struct RtcInstant { | 10 | pub struct RtcInstant { |
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 169505501..00abe9356 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -31,7 +31,6 @@ pub use _version::*; | |||
| 31 | use embassy_hal_internal::Peripheral; | 31 | use embassy_hal_internal::Peripheral; |
| 32 | 32 | ||
| 33 | use crate::peripherals::RTC; | 33 | use crate::peripherals::RTC; |
| 34 | use crate::rtc::sealed::Instance; | ||
| 35 | 34 | ||
| 36 | #[allow(dead_code)] | 35 | #[allow(dead_code)] |
| 37 | #[repr(u8)] | 36 | #[repr(u8)] |
| @@ -212,7 +211,7 @@ impl Rtc { | |||
| 212 | /// Create a new RTC instance. | 211 | /// Create a new RTC instance. |
| 213 | pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { | 212 | pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { |
| 214 | #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] | 213 | #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] |
| 215 | <RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset(); | 214 | <RTC as crate::rcc::SealedRccPeripheral>::enable_and_reset(); |
| 216 | 215 | ||
| 217 | let mut this = Self { | 216 | let mut this = Self { |
| 218 | #[cfg(feature = "low-power")] | 217 | #[cfg(feature = "low-power")] |
| @@ -437,7 +436,7 @@ impl Rtc { | |||
| 437 | .fpr(0) | 436 | .fpr(0) |
| 438 | .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 437 | .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| 439 | 438 | ||
| 440 | <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); | 439 | <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); |
| 441 | }); | 440 | }); |
| 442 | } | 441 | } |
| 443 | 442 | ||
| @@ -449,8 +448,8 @@ impl Rtc { | |||
| 449 | use crate::interrupt::typelevel::Interrupt; | 448 | use crate::interrupt::typelevel::Interrupt; |
| 450 | use crate::pac::EXTI; | 449 | use crate::pac::EXTI; |
| 451 | 450 | ||
| 452 | <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend(); | 451 | <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); |
| 453 | unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() }; | 452 | unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() }; |
| 454 | 453 | ||
| 455 | EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 454 | EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| 456 | EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); | 455 | EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); |
| @@ -477,34 +476,30 @@ pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 { | |||
| 477 | tmp + (value & 0x0F) | 476 | tmp + (value & 0x0F) |
| 478 | } | 477 | } |
| 479 | 478 | ||
| 480 | pub(crate) mod sealed { | 479 | trait SealedInstance { |
| 481 | use crate::pac::rtc::Rtc; | 480 | const BACKUP_REGISTER_COUNT: usize; |
| 482 | 481 | ||
| 483 | pub trait Instance { | 482 | #[cfg(feature = "low-power")] |
| 484 | const BACKUP_REGISTER_COUNT: usize; | 483 | const EXTI_WAKEUP_LINE: usize; |
| 485 | |||
| 486 | #[cfg(feature = "low-power")] | ||
| 487 | const EXTI_WAKEUP_LINE: usize; | ||
| 488 | 484 | ||
| 489 | #[cfg(feature = "low-power")] | 485 | #[cfg(feature = "low-power")] |
| 490 | type WakeupInterrupt: crate::interrupt::typelevel::Interrupt; | 486 | type WakeupInterrupt: crate::interrupt::typelevel::Interrupt; |
| 491 | 487 | ||
| 492 | fn regs() -> Rtc { | 488 | fn regs() -> crate::pac::rtc::Rtc { |
| 493 | crate::pac::RTC | 489 | crate::pac::RTC |
| 494 | } | 490 | } |
| 495 | 491 | ||
| 496 | /// Read content of the backup register. | 492 | /// Read content of the backup register. |
| 497 | /// | 493 | /// |
| 498 | /// The registers retain their values during wakes from standby mode or system resets. They also | 494 | /// The registers retain their values during wakes from standby mode or system resets. They also |
| 499 | /// retain their value when Vdd is switched off as long as V_BAT is powered. | 495 | /// retain their value when Vdd is switched off as long as V_BAT is powered. |
| 500 | fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32>; | 496 | fn read_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize) -> Option<u32>; |
| 501 | 497 | ||
| 502 | /// Set content of the backup register. | 498 | /// Set content of the backup register. |
| 503 | /// | 499 | /// |
| 504 | /// The registers retain their values during wakes from standby mode or system resets. They also | 500 | /// The registers retain their values during wakes from standby mode or system resets. They also |
| 505 | /// retain their value when Vdd is switched off as long as V_BAT is powered. | 501 | /// retain their value when Vdd is switched off as long as V_BAT is powered. |
| 506 | fn write_backup_register(rtc: &Rtc, register: usize, value: u32); | 502 | fn write_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize, value: u32); |
| 507 | 503 | ||
| 508 | // fn apply_config(&mut self, rtc_config: RtcConfig); | 504 | // fn apply_config(&mut self, rtc_config: RtcConfig); |
| 509 | } | ||
| 510 | } | 505 | } |
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 1eda097a7..92f9de846 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -1,9 +1,8 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Osel, Pol}; | 1 | use stm32_metapac::rtc::vals::{Osel, Pol}; |
| 2 | 2 | ||
| 3 | use super::sealed; | 3 | use super::SealedInstance; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | 5 | use crate::peripherals::RTC; |
| 6 | use crate::rtc::sealed::Instance; | ||
| 7 | 6 | ||
| 8 | #[allow(dead_code)] | 7 | #[allow(dead_code)] |
| 9 | impl super::Rtc { | 8 | impl super::Rtc { |
| @@ -126,7 +125,7 @@ impl super::Rtc { | |||
| 126 | } | 125 | } |
| 127 | } | 126 | } |
| 128 | 127 | ||
| 129 | impl sealed::Instance for crate::peripherals::RTC { | 128 | impl SealedInstance for crate::peripherals::RTC { |
| 130 | const BACKUP_REGISTER_COUNT: usize = 20; | 129 | const BACKUP_REGISTER_COUNT: usize = 20; |
| 131 | 130 | ||
| 132 | #[cfg(all(feature = "low-power", stm32f4))] | 131 | #[cfg(all(feature = "low-power", stm32f4))] |
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 3d44a52ff..8a78d16e1 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Key, Osel, Pol, TampalrmType}; | 1 | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Key, Osel, Pol, TampalrmType}; |
| 2 | 2 | ||
| 3 | use super::{sealed, RtcCalibrationCyclePeriod}; | 3 | use super::RtcCalibrationCyclePeriod; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | 5 | use crate::peripherals::RTC; |
| 6 | use crate::rtc::sealed::Instance; | 6 | use crate::rtc::SealedInstance; |
| 7 | 7 | ||
| 8 | impl super::Rtc { | 8 | impl super::Rtc { |
| 9 | /// Applies the RTC config | 9 | /// Applies the RTC config |
| @@ -126,7 +126,7 @@ impl super::Rtc { | |||
| 126 | } | 126 | } |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | impl sealed::Instance for crate::peripherals::RTC { | 129 | impl SealedInstance for crate::peripherals::RTC { |
| 130 | const BACKUP_REGISTER_COUNT: usize = 32; | 130 | const BACKUP_REGISTER_COUNT: usize = 32; |
| 131 | 131 | ||
| 132 | #[cfg(all(feature = "low-power", stm32g4))] | 132 | #[cfg(all(feature = "low-power", stm32g4))] |
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 02f96f8a9..54dd81524 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs | |||
| @@ -6,12 +6,10 @@ use core::marker::PhantomData; | |||
| 6 | 6 | ||
| 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | 8 | ||
| 9 | use self::sealed::WhichSubBlock; | ||
| 10 | pub use crate::dma::word; | 9 | pub use crate::dma::word; |
| 11 | #[cfg(not(gpdma))] | 10 | #[cfg(not(gpdma))] |
| 12 | use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; | 11 | use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; |
| 13 | use crate::gpio::sealed::{AFType, Pin as _}; | 12 | use crate::gpio::{AFType, AnyPin, SealedPin as _}; |
| 14 | use crate::gpio::AnyPin; | ||
| 15 | use crate::pac::sai::{vals, Sai as Regs}; | 13 | use crate::pac::sai::{vals, Sai as Regs}; |
| 16 | use crate::rcc::RccPeripheral; | 14 | use crate::rcc::RccPeripheral; |
| 17 | use crate::{peripherals, Peripheral}; | 15 | use crate::{peripherals, Peripheral}; |
| @@ -386,6 +384,7 @@ impl OutputDrive { | |||
| 386 | /// Master clock divider. | 384 | /// Master clock divider. |
| 387 | #[derive(Copy, Clone, PartialEq)] | 385 | #[derive(Copy, Clone, PartialEq)] |
| 388 | #[allow(missing_docs)] | 386 | #[allow(missing_docs)] |
| 387 | #[cfg(any(sai_v1, sai_v2))] | ||
| 389 | pub enum MasterClockDivider { | 388 | pub enum MasterClockDivider { |
| 390 | MasterClockDisabled, | 389 | MasterClockDisabled, |
| 391 | Div1, | 390 | Div1, |
| @@ -406,8 +405,79 @@ pub enum MasterClockDivider { | |||
| 406 | Div30, | 405 | Div30, |
| 407 | } | 406 | } |
| 408 | 407 | ||
| 408 | /// Master clock divider. | ||
| 409 | #[derive(Copy, Clone, PartialEq)] | ||
| 410 | #[allow(missing_docs)] | ||
| 411 | #[cfg(any(sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 412 | pub enum MasterClockDivider { | ||
| 413 | MasterClockDisabled, | ||
| 414 | Div1, | ||
| 415 | Div2, | ||
| 416 | Div3, | ||
| 417 | Div4, | ||
| 418 | Div5, | ||
| 419 | Div6, | ||
| 420 | Div7, | ||
| 421 | Div8, | ||
| 422 | Div9, | ||
| 423 | Div10, | ||
| 424 | Div11, | ||
| 425 | Div12, | ||
| 426 | Div13, | ||
| 427 | Div14, | ||
| 428 | Div15, | ||
| 429 | Div16, | ||
| 430 | Div17, | ||
| 431 | Div18, | ||
| 432 | Div19, | ||
| 433 | Div20, | ||
| 434 | Div21, | ||
| 435 | Div22, | ||
| 436 | Div23, | ||
| 437 | Div24, | ||
| 438 | Div25, | ||
| 439 | Div26, | ||
| 440 | Div27, | ||
| 441 | Div28, | ||
| 442 | Div29, | ||
| 443 | Div30, | ||
| 444 | Div31, | ||
| 445 | Div32, | ||
| 446 | Div33, | ||
| 447 | Div34, | ||
| 448 | Div35, | ||
| 449 | Div36, | ||
| 450 | Div37, | ||
| 451 | Div38, | ||
| 452 | Div39, | ||
| 453 | Div40, | ||
| 454 | Div41, | ||
| 455 | Div42, | ||
| 456 | Div43, | ||
| 457 | Div44, | ||
| 458 | Div45, | ||
| 459 | Div46, | ||
| 460 | Div47, | ||
| 461 | Div48, | ||
| 462 | Div49, | ||
| 463 | Div50, | ||
| 464 | Div51, | ||
| 465 | Div52, | ||
| 466 | Div53, | ||
| 467 | Div54, | ||
| 468 | Div55, | ||
| 469 | Div56, | ||
| 470 | Div57, | ||
| 471 | Div58, | ||
| 472 | Div59, | ||
| 473 | Div60, | ||
| 474 | Div61, | ||
| 475 | Div62, | ||
| 476 | Div63, | ||
| 477 | } | ||
| 478 | |||
| 409 | impl MasterClockDivider { | 479 | impl MasterClockDivider { |
| 410 | #[cfg(any(sai_v1, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | 480 | #[cfg(any(sai_v1, sai_v2))] |
| 411 | const fn mckdiv(&self) -> u8 { | 481 | const fn mckdiv(&self) -> u8 { |
| 412 | match self { | 482 | match self { |
| 413 | MasterClockDivider::MasterClockDisabled => 0, | 483 | MasterClockDivider::MasterClockDisabled => 0, |
| @@ -429,6 +499,76 @@ impl MasterClockDivider { | |||
| 429 | MasterClockDivider::Div30 => 15, | 499 | MasterClockDivider::Div30 => 15, |
| 430 | } | 500 | } |
| 431 | } | 501 | } |
| 502 | |||
| 503 | #[cfg(any(sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 504 | const fn mckdiv(&self) -> u8 { | ||
| 505 | match self { | ||
| 506 | MasterClockDivider::MasterClockDisabled => 0, | ||
| 507 | MasterClockDivider::Div1 => 1, | ||
| 508 | MasterClockDivider::Div2 => 2, | ||
| 509 | MasterClockDivider::Div3 => 3, | ||
| 510 | MasterClockDivider::Div4 => 4, | ||
| 511 | MasterClockDivider::Div5 => 5, | ||
| 512 | MasterClockDivider::Div6 => 6, | ||
| 513 | MasterClockDivider::Div7 => 7, | ||
| 514 | MasterClockDivider::Div8 => 8, | ||
| 515 | MasterClockDivider::Div9 => 9, | ||
| 516 | MasterClockDivider::Div10 => 10, | ||
| 517 | MasterClockDivider::Div11 => 11, | ||
| 518 | MasterClockDivider::Div12 => 12, | ||
| 519 | MasterClockDivider::Div13 => 13, | ||
| 520 | MasterClockDivider::Div14 => 14, | ||
| 521 | MasterClockDivider::Div15 => 15, | ||
| 522 | MasterClockDivider::Div16 => 16, | ||
| 523 | MasterClockDivider::Div17 => 17, | ||
| 524 | MasterClockDivider::Div18 => 18, | ||
| 525 | MasterClockDivider::Div19 => 19, | ||
| 526 | MasterClockDivider::Div20 => 20, | ||
| 527 | MasterClockDivider::Div21 => 21, | ||
| 528 | MasterClockDivider::Div22 => 22, | ||
| 529 | MasterClockDivider::Div23 => 23, | ||
| 530 | MasterClockDivider::Div24 => 24, | ||
| 531 | MasterClockDivider::Div25 => 25, | ||
| 532 | MasterClockDivider::Div26 => 26, | ||
| 533 | MasterClockDivider::Div27 => 27, | ||
| 534 | MasterClockDivider::Div28 => 28, | ||
| 535 | MasterClockDivider::Div29 => 29, | ||
| 536 | MasterClockDivider::Div30 => 30, | ||
| 537 | MasterClockDivider::Div31 => 31, | ||
| 538 | MasterClockDivider::Div32 => 32, | ||
| 539 | MasterClockDivider::Div33 => 33, | ||
| 540 | MasterClockDivider::Div34 => 34, | ||
| 541 | MasterClockDivider::Div35 => 35, | ||
| 542 | MasterClockDivider::Div36 => 36, | ||
| 543 | MasterClockDivider::Div37 => 37, | ||
| 544 | MasterClockDivider::Div38 => 38, | ||
| 545 | MasterClockDivider::Div39 => 39, | ||
| 546 | MasterClockDivider::Div40 => 40, | ||
| 547 | MasterClockDivider::Div41 => 41, | ||
| 548 | MasterClockDivider::Div42 => 42, | ||
| 549 | MasterClockDivider::Div43 => 43, | ||
| 550 | MasterClockDivider::Div44 => 44, | ||
| 551 | MasterClockDivider::Div45 => 45, | ||
| 552 | MasterClockDivider::Div46 => 46, | ||
| 553 | MasterClockDivider::Div47 => 47, | ||
| 554 | MasterClockDivider::Div48 => 48, | ||
| 555 | MasterClockDivider::Div49 => 49, | ||
| 556 | MasterClockDivider::Div50 => 50, | ||
| 557 | MasterClockDivider::Div51 => 51, | ||
| 558 | MasterClockDivider::Div52 => 52, | ||
| 559 | MasterClockDivider::Div53 => 53, | ||
| 560 | MasterClockDivider::Div54 => 54, | ||
| 561 | MasterClockDivider::Div55 => 55, | ||
| 562 | MasterClockDivider::Div56 => 56, | ||
| 563 | MasterClockDivider::Div57 => 57, | ||
| 564 | MasterClockDivider::Div58 => 58, | ||
| 565 | MasterClockDivider::Div59 => 59, | ||
| 566 | MasterClockDivider::Div60 => 60, | ||
| 567 | MasterClockDivider::Div61 => 61, | ||
| 568 | MasterClockDivider::Div62 => 62, | ||
| 569 | MasterClockDivider::Div63 => 63, | ||
| 570 | } | ||
| 571 | } | ||
| 432 | } | 572 | } |
| 433 | 573 | ||
| 434 | /// [`SAI`] configuration. | 574 | /// [`SAI`] configuration. |
| @@ -899,43 +1039,42 @@ impl<'d, T: Instance, W: word::Word> Drop for Sai<'d, T, W> { | |||
| 899 | } | 1039 | } |
| 900 | } | 1040 | } |
| 901 | 1041 | ||
| 902 | pub(crate) mod sealed { | 1042 | trait SealedInstance { |
| 903 | use super::*; | 1043 | const REGS: Regs; |
| 904 | 1044 | } | |
| 905 | pub trait Instance { | ||
| 906 | const REGS: Regs; | ||
| 907 | } | ||
| 908 | 1045 | ||
| 909 | #[derive(Copy, Clone)] | 1046 | #[derive(Copy, Clone)] |
| 910 | pub enum WhichSubBlock { | 1047 | enum WhichSubBlock { |
| 911 | A = 0, | 1048 | A = 0, |
| 912 | B = 1, | 1049 | B = 1, |
| 913 | } | 1050 | } |
| 914 | 1051 | ||
| 915 | pub trait SubBlock { | 1052 | trait SealedSubBlock { |
| 916 | const WHICH: WhichSubBlock; | 1053 | const WHICH: WhichSubBlock; |
| 917 | } | ||
| 918 | } | 1054 | } |
| 919 | 1055 | ||
| 920 | /// Sub-block instance trait. | 1056 | /// Sub-block instance trait. |
| 921 | pub trait SubBlockInstance: sealed::SubBlock {} | 1057 | #[allow(private_bounds)] |
| 1058 | pub trait SubBlockInstance: SealedSubBlock {} | ||
| 922 | 1059 | ||
| 923 | /// Sub-block A. | 1060 | /// Sub-block A. |
| 924 | pub enum A {} | 1061 | pub enum A {} |
| 925 | impl sealed::SubBlock for A { | 1062 | impl SealedSubBlock for A { |
| 926 | const WHICH: WhichSubBlock = WhichSubBlock::A; | 1063 | const WHICH: WhichSubBlock = WhichSubBlock::A; |
| 927 | } | 1064 | } |
| 928 | impl SubBlockInstance for A {} | 1065 | impl SubBlockInstance for A {} |
| 929 | 1066 | ||
| 930 | /// Sub-block B. | 1067 | /// Sub-block B. |
| 931 | pub enum B {} | 1068 | pub enum B {} |
| 932 | impl sealed::SubBlock for B { | 1069 | impl SealedSubBlock for B { |
| 933 | const WHICH: WhichSubBlock = WhichSubBlock::B; | 1070 | const WHICH: WhichSubBlock = WhichSubBlock::B; |
| 934 | } | 1071 | } |
| 935 | impl SubBlockInstance for B {} | 1072 | impl SubBlockInstance for B {} |
| 936 | 1073 | ||
| 937 | /// SAI instance trait. | 1074 | /// SAI instance trait. |
| 938 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} | 1075 | #[allow(private_bounds)] |
| 1076 | pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} | ||
| 1077 | |||
| 939 | pin_trait!(SckPin, Instance, SubBlockInstance); | 1078 | pin_trait!(SckPin, Instance, SubBlockInstance); |
| 940 | pin_trait!(FsPin, Instance, SubBlockInstance); | 1079 | pin_trait!(FsPin, Instance, SubBlockInstance); |
| 941 | pin_trait!(SdPin, Instance, SubBlockInstance); | 1080 | pin_trait!(SdPin, Instance, SubBlockInstance); |
| @@ -945,7 +1084,7 @@ dma_trait!(Dma, Instance, SubBlockInstance); | |||
| 945 | 1084 | ||
| 946 | foreach_peripheral!( | 1085 | foreach_peripheral!( |
| 947 | (sai, $inst:ident) => { | 1086 | (sai, $inst:ident) => { |
| 948 | impl sealed::Instance for peripherals::$inst { | 1087 | impl SealedInstance for peripherals::$inst { |
| 949 | const REGS: Regs = crate::pac::$inst; | 1088 | const REGS: Regs = crate::pac::$inst; |
| 950 | } | 1089 | } |
| 951 | 1090 | ||
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs index fa1f710d8..f79a11606 100644 --- a/embassy-stm32/src/sdmmc/mod.rs +++ b/embassy-stm32/src/sdmmc/mod.rs | |||
| @@ -13,8 +13,7 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 13 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; | 13 | use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; |
| 14 | 14 | ||
| 15 | use crate::dma::NoDma; | 15 | use crate::dma::NoDma; |
| 16 | use crate::gpio::sealed::{AFType, Pin}; | 16 | use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed}; |
| 17 | use crate::gpio::{AnyPin, Pull, Speed}; | ||
| 18 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 19 | use crate::pac::sdmmc::Sdmmc as RegBlock; | 18 | use crate::pac::sdmmc::Sdmmc as RegBlock; |
| 20 | use crate::rcc::RccPeripheral; | 19 | use crate::rcc::RccPeripheral; |
| @@ -1418,21 +1417,17 @@ impl Cmd { | |||
| 1418 | 1417 | ||
| 1419 | ////////////////////////////////////////////////////// | 1418 | ////////////////////////////////////////////////////// |
| 1420 | 1419 | ||
| 1421 | pub(crate) mod sealed { | 1420 | trait SealedInstance { |
| 1422 | use super::*; | 1421 | fn regs() -> RegBlock; |
| 1423 | 1422 | fn state() -> &'static AtomicWaker; | |
| 1424 | pub trait Instance { | ||
| 1425 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1426 | |||
| 1427 | fn regs() -> RegBlock; | ||
| 1428 | fn state() -> &'static AtomicWaker; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | pub trait Pins<T: Instance> {} | ||
| 1432 | } | 1423 | } |
| 1433 | 1424 | ||
| 1434 | /// SDMMC instance trait. | 1425 | /// SDMMC instance trait. |
| 1435 | pub trait Instance: sealed::Instance + RccPeripheral + 'static {} | 1426 | #[allow(private_bounds)] |
| 1427 | pub trait Instance: SealedInstance + RccPeripheral + 'static { | ||
| 1428 | /// Interrupt for this instance. | ||
| 1429 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1430 | } | ||
| 1436 | 1431 | ||
| 1437 | pin_trait!(CkPin, Instance); | 1432 | pin_trait!(CkPin, Instance); |
| 1438 | pin_trait!(CmdPin, Instance); | 1433 | pin_trait!(CmdPin, Instance); |
| @@ -1459,9 +1454,7 @@ impl<T: Instance> SdmmcDma<T> for NoDma {} | |||
| 1459 | 1454 | ||
| 1460 | foreach_peripheral!( | 1455 | foreach_peripheral!( |
| 1461 | (sdmmc, $inst:ident) => { | 1456 | (sdmmc, $inst:ident) => { |
| 1462 | impl sealed::Instance for peripherals::$inst { | 1457 | impl SealedInstance for peripherals::$inst { |
| 1463 | type Interrupt = crate::interrupt::typelevel::$inst; | ||
| 1464 | |||
| 1465 | fn regs() -> RegBlock { | 1458 | fn regs() -> RegBlock { |
| 1466 | crate::pac::$inst | 1459 | crate::pac::$inst |
| 1467 | } | 1460 | } |
| @@ -1472,6 +1465,8 @@ foreach_peripheral!( | |||
| 1472 | } | 1465 | } |
| 1473 | } | 1466 | } |
| 1474 | 1467 | ||
| 1475 | impl Instance for peripherals::$inst {} | 1468 | impl Instance for peripherals::$inst { |
| 1469 | type Interrupt = crate::interrupt::typelevel::$inst; | ||
| 1470 | } | ||
| 1476 | }; | 1471 | }; |
| 1477 | ); | 1472 | ); |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index b517f640a..0b38c4288 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -9,8 +9,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 9 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 9 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 10 | 10 | ||
| 11 | use crate::dma::{slice_ptr_parts, word, Transfer}; | 11 | use crate::dma::{slice_ptr_parts, word, Transfer}; |
| 12 | use crate::gpio::sealed::{AFType, Pin as _}; | 12 | use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _}; |
| 13 | use crate::gpio::{AnyPin, Pull}; | ||
| 14 | use crate::pac::spi::{regs, vals, Spi as Regs}; | 13 | use crate::pac::spi::{regs, vals, Spi as Regs}; |
| 15 | use crate::rcc::RccPeripheral; | 14 | use crate::rcc::RccPeripheral; |
| 16 | use crate::time::Hertz; | 15 | use crate::time::Hertz; |
| @@ -210,7 +209,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 210 | // see RM0453 rev 1 section 7.2.13 page 291 | 209 | // see RM0453 rev 1 section 7.2.13 page 291 |
| 211 | // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. | 210 | // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. |
| 212 | // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. | 211 | // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. |
| 213 | let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::sealed::RccPeripheral>::frequency().0; | 212 | let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0; |
| 214 | let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); | 213 | let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); |
| 215 | let mut config = Config::default(); | 214 | let mut config = Config::default(); |
| 216 | config.mode = MODE_0; | 215 | config.mode = MODE_0; |
| @@ -271,13 +270,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 271 | if mosi.is_none() { | 270 | if mosi.is_none() { |
| 272 | w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); | 271 | w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); |
| 273 | } | 272 | } |
| 274 | w.set_dff(<u8 as sealed::Word>::CONFIG) | 273 | w.set_dff(<u8 as SealedWord>::CONFIG) |
| 275 | }); | 274 | }); |
| 276 | } | 275 | } |
| 277 | #[cfg(spi_v2)] | 276 | #[cfg(spi_v2)] |
| 278 | { | 277 | { |
| 279 | T::REGS.cr2().modify(|w| { | 278 | T::REGS.cr2().modify(|w| { |
| 280 | let (ds, frxth) = <u8 as sealed::Word>::CONFIG; | 279 | let (ds, frxth) = <u8 as SealedWord>::CONFIG; |
| 281 | w.set_frxth(frxth); | 280 | w.set_frxth(frxth); |
| 282 | w.set_ds(ds); | 281 | w.set_ds(ds); |
| 283 | w.set_ssoe(false); | 282 | w.set_ssoe(false); |
| @@ -317,7 +316,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 317 | T::REGS.cfg1().modify(|w| { | 316 | T::REGS.cfg1().modify(|w| { |
| 318 | w.set_crcen(false); | 317 | w.set_crcen(false); |
| 319 | w.set_mbr(br); | 318 | w.set_mbr(br); |
| 320 | w.set_dsize(<u8 as sealed::Word>::CONFIG); | 319 | w.set_dsize(<u8 as SealedWord>::CONFIG); |
| 321 | w.set_fthlv(vals::Fthlv::ONEFRAME); | 320 | w.set_fthlv(vals::Fthlv::ONEFRAME); |
| 322 | }); | 321 | }); |
| 323 | T::REGS.cr2().modify(|w| { | 322 | T::REGS.cr2().modify(|w| { |
| @@ -336,7 +335,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 336 | miso, | 335 | miso, |
| 337 | txdma, | 336 | txdma, |
| 338 | rxdma, | 337 | rxdma, |
| 339 | current_word_size: <u8 as sealed::Word>::CONFIG, | 338 | current_word_size: <u8 as SealedWord>::CONFIG, |
| 340 | } | 339 | } |
| 341 | } | 340 | } |
| 342 | 341 | ||
| @@ -975,24 +974,21 @@ impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::s | |||
| 975 | } | 974 | } |
| 976 | } | 975 | } |
| 977 | 976 | ||
| 978 | pub(crate) mod sealed { | 977 | pub(crate) trait SealedInstance { |
| 979 | use super::*; | 978 | const REGS: Regs; |
| 980 | 979 | } | |
| 981 | pub trait Instance { | ||
| 982 | const REGS: Regs; | ||
| 983 | } | ||
| 984 | 980 | ||
| 985 | pub trait Word { | 981 | trait SealedWord { |
| 986 | const CONFIG: word_impl::Config; | 982 | const CONFIG: word_impl::Config; |
| 987 | } | ||
| 988 | } | 983 | } |
| 989 | 984 | ||
| 990 | /// Word sizes usable for SPI. | 985 | /// Word sizes usable for SPI. |
| 991 | pub trait Word: word::Word + sealed::Word {} | 986 | #[allow(private_bounds)] |
| 987 | pub trait Word: word::Word + SealedWord {} | ||
| 992 | 988 | ||
| 993 | macro_rules! impl_word { | 989 | macro_rules! impl_word { |
| 994 | ($T:ty, $config:expr) => { | 990 | ($T:ty, $config:expr) => { |
| 995 | impl sealed::Word for $T { | 991 | impl SealedWord for $T { |
| 996 | const CONFIG: Config = $config; | 992 | const CONFIG: Config = $config; |
| 997 | } | 993 | } |
| 998 | impl Word for $T {} | 994 | impl Word for $T {} |
| @@ -1068,7 +1064,8 @@ mod word_impl { | |||
| 1068 | } | 1064 | } |
| 1069 | 1065 | ||
| 1070 | /// SPI instance trait. | 1066 | /// SPI instance trait. |
| 1071 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} | 1067 | #[allow(private_bounds)] |
| 1068 | pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} | ||
| 1072 | 1069 | ||
| 1073 | pin_trait!(SckPin, Instance); | 1070 | pin_trait!(SckPin, Instance); |
| 1074 | pin_trait!(MosiPin, Instance); | 1071 | pin_trait!(MosiPin, Instance); |
| @@ -1082,7 +1079,7 @@ dma_trait!(TxDma, Instance); | |||
| 1082 | 1079 | ||
| 1083 | foreach_peripheral!( | 1080 | foreach_peripheral!( |
| 1084 | (spi, $inst:ident) => { | 1081 | (spi, $inst:ident) => { |
| 1085 | impl sealed::Instance for peripherals::$inst { | 1082 | impl SealedInstance for peripherals::$inst { |
| 1086 | const REGS: Regs = crate::pac::$inst; | 1083 | const REGS: Regs = crate::pac::$inst; |
| 1087 | } | 1084 | } |
| 1088 | 1085 | ||
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 37b2e7526..cc8161276 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | #![allow(non_snake_case)] | 1 | #![allow(non_snake_case)] |
| 2 | 2 | ||
| 3 | use core::cell::Cell; | 3 | use core::cell::Cell; |
| 4 | use core::convert::TryInto; | ||
| 5 | use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; |
| 6 | use core::{mem, ptr}; | 5 | use core::{mem, ptr}; |
| 7 | 6 | ||
| @@ -9,16 +8,16 @@ use critical_section::CriticalSection; | |||
| 9 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 8 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 10 | use embassy_sync::blocking_mutex::Mutex; | 9 | use embassy_sync::blocking_mutex::Mutex; |
| 11 | use embassy_time_driver::{AlarmHandle, Driver, TICK_HZ}; | 10 | use embassy_time_driver::{AlarmHandle, Driver, TICK_HZ}; |
| 12 | use stm32_metapac::timer::regs; | 11 | use stm32_metapac::timer::{regs, TimGp16}; |
| 13 | 12 | ||
| 14 | use crate::interrupt::typelevel::Interrupt; | 13 | use crate::interrupt::typelevel::Interrupt; |
| 15 | use crate::pac::timer::vals; | 14 | use crate::pac::timer::vals; |
| 16 | use crate::rcc::sealed::RccPeripheral; | 15 | use crate::rcc::SealedRccPeripheral; |
| 17 | #[cfg(feature = "low-power")] | 16 | #[cfg(feature = "low-power")] |
| 18 | use crate::rtc::Rtc; | 17 | use crate::rtc::Rtc; |
| 19 | #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] | 18 | #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] |
| 20 | use crate::timer::sealed::AdvancedControlInstance; | 19 | use crate::timer::AdvancedInstance1Channel; |
| 21 | use crate::timer::sealed::{CoreInstance, GeneralPurpose16bitInstance as Instance}; | 20 | use crate::timer::CoreInstance; |
| 22 | use crate::{interrupt, peripherals}; | 21 | use crate::{interrupt, peripherals}; |
| 23 | 22 | ||
| 24 | // NOTE regarding ALARM_COUNT: | 23 | // NOTE regarding ALARM_COUNT: |
| @@ -208,6 +207,10 @@ foreach_interrupt! { | |||
| 208 | }; | 207 | }; |
| 209 | } | 208 | } |
| 210 | 209 | ||
| 210 | fn regs_gp16() -> TimGp16 { | ||
| 211 | unsafe { TimGp16::from_ptr(T::regs()) } | ||
| 212 | } | ||
| 213 | |||
| 211 | // Clock timekeeping works with something we call "periods", which are time intervals | 214 | // Clock timekeeping works with something we call "periods", which are time intervals |
| 212 | // of 2^15 ticks. The Clock counter value is 16 bits, so one "overflow cycle" is 2 periods. | 215 | // of 2^15 ticks. The Clock counter value is 16 bits, so one "overflow cycle" is 2 periods. |
| 213 | // | 216 | // |
| @@ -272,9 +275,9 @@ embassy_time_driver::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver { | |||
| 272 | 275 | ||
| 273 | impl RtcDriver { | 276 | impl RtcDriver { |
| 274 | fn init(&'static self, cs: critical_section::CriticalSection) { | 277 | fn init(&'static self, cs: critical_section::CriticalSection) { |
| 275 | let r = T::regs_gp16(); | 278 | let r = regs_gp16(); |
| 276 | 279 | ||
| 277 | <T as RccPeripheral>::enable_and_reset_with_cs(cs); | 280 | <T as SealedRccPeripheral>::enable_and_reset_with_cs(cs); |
| 278 | 281 | ||
| 279 | let timer_freq = T::frequency(); | 282 | let timer_freq = T::frequency(); |
| 280 | 283 | ||
| @@ -287,7 +290,7 @@ impl RtcDriver { | |||
| 287 | Ok(n) => n, | 290 | Ok(n) => n, |
| 288 | }; | 291 | }; |
| 289 | 292 | ||
| 290 | r.psc().write(|w| w.set_psc(psc)); | 293 | r.psc().write_value(psc); |
| 291 | r.arr().write(|w| w.set_arr(u16::MAX)); | 294 | r.arr().write(|w| w.set_arr(u16::MAX)); |
| 292 | 295 | ||
| 293 | // Set URS, generate update and clear URS | 296 | // Set URS, generate update and clear URS |
| @@ -309,9 +312,9 @@ impl RtcDriver { | |||
| 309 | 312 | ||
| 310 | #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] | 313 | #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] |
| 311 | { | 314 | { |
| 312 | <T as AdvancedControlInstance>::CaptureCompareInterrupt::unpend(); | 315 | <T as AdvancedInstance1Channel>::CaptureCompareInterrupt::unpend(); |
| 313 | unsafe { | 316 | unsafe { |
| 314 | <T as AdvancedControlInstance>::CaptureCompareInterrupt::enable(); | 317 | <T as AdvancedInstance1Channel>::CaptureCompareInterrupt::enable(); |
| 315 | } | 318 | } |
| 316 | } | 319 | } |
| 317 | 320 | ||
| @@ -319,7 +322,7 @@ impl RtcDriver { | |||
| 319 | } | 322 | } |
| 320 | 323 | ||
| 321 | fn on_interrupt(&self) { | 324 | fn on_interrupt(&self) { |
| 322 | let r = T::regs_gp16(); | 325 | let r = regs_gp16(); |
| 323 | 326 | ||
| 324 | // XXX: reduce the size of this critical section ? | 327 | // XXX: reduce the size of this critical section ? |
| 325 | critical_section::with(|cs| { | 328 | critical_section::with(|cs| { |
| @@ -350,7 +353,7 @@ impl RtcDriver { | |||
| 350 | } | 353 | } |
| 351 | 354 | ||
| 352 | fn next_period(&self) { | 355 | fn next_period(&self) { |
| 353 | let r = T::regs_gp16(); | 356 | let r = regs_gp16(); |
| 354 | 357 | ||
| 355 | // We only modify the period from the timer interrupt, so we know this can't race. | 358 | // We only modify the period from the timer interrupt, so we know this can't race. |
| 356 | let period = self.period.load(Ordering::Relaxed) + 1; | 359 | let period = self.period.load(Ordering::Relaxed) + 1; |
| @@ -414,7 +417,7 @@ impl RtcDriver { | |||
| 414 | /// Add the given offset to the current time | 417 | /// Add the given offset to the current time |
| 415 | fn add_time(&self, offset: embassy_time::Duration, cs: CriticalSection) { | 418 | fn add_time(&self, offset: embassy_time::Duration, cs: CriticalSection) { |
| 416 | let offset = offset.as_ticks(); | 419 | let offset = offset.as_ticks(); |
| 417 | let cnt = T::regs_gp16().cnt().read().cnt() as u32; | 420 | let cnt = regs_gp16().cnt().read().cnt() as u32; |
| 418 | let period = self.period.load(Ordering::SeqCst); | 421 | let period = self.period.load(Ordering::SeqCst); |
| 419 | 422 | ||
| 420 | // Correct the race, if it exists | 423 | // Correct the race, if it exists |
| @@ -440,7 +443,7 @@ impl RtcDriver { | |||
| 440 | let period = if cnt > u16::MAX as u32 / 2 { period + 1 } else { period }; | 443 | let period = if cnt > u16::MAX as u32 / 2 { period + 1 } else { period }; |
| 441 | 444 | ||
| 442 | self.period.store(period, Ordering::SeqCst); | 445 | self.period.store(period, Ordering::SeqCst); |
| 443 | T::regs_gp16().cnt().write(|w| w.set_cnt(cnt as u16)); | 446 | regs_gp16().cnt().write(|w| w.set_cnt(cnt as u16)); |
| 444 | 447 | ||
| 445 | // Now, recompute all alarms | 448 | // Now, recompute all alarms |
| 446 | for i in 0..ALARM_COUNT { | 449 | for i in 0..ALARM_COUNT { |
| @@ -497,7 +500,7 @@ impl RtcDriver { | |||
| 497 | .unwrap() | 500 | .unwrap() |
| 498 | .start_wakeup_alarm(time_until_next_alarm, cs); | 501 | .start_wakeup_alarm(time_until_next_alarm, cs); |
| 499 | 502 | ||
| 500 | T::regs_gp16().cr1().modify(|w| w.set_cen(false)); | 503 | regs_gp16().cr1().modify(|w| w.set_cen(false)); |
| 501 | 504 | ||
| 502 | Ok(()) | 505 | Ok(()) |
| 503 | } | 506 | } |
| @@ -507,7 +510,7 @@ impl RtcDriver { | |||
| 507 | #[cfg(feature = "low-power")] | 510 | #[cfg(feature = "low-power")] |
| 508 | /// Resume the timer with the given offset | 511 | /// Resume the timer with the given offset |
| 509 | pub(crate) fn resume_time(&self) { | 512 | pub(crate) fn resume_time(&self) { |
| 510 | if T::regs_gp16().cr1().read().cen() { | 513 | if regs_gp16().cr1().read().cen() { |
| 511 | // Time isn't currently stopped | 514 | // Time isn't currently stopped |
| 512 | 515 | ||
| 513 | return; | 516 | return; |
| @@ -516,14 +519,14 @@ impl RtcDriver { | |||
| 516 | critical_section::with(|cs| { | 519 | critical_section::with(|cs| { |
| 517 | self.stop_wakeup_alarm(cs); | 520 | self.stop_wakeup_alarm(cs); |
| 518 | 521 | ||
| 519 | T::regs_gp16().cr1().modify(|w| w.set_cen(true)); | 522 | regs_gp16().cr1().modify(|w| w.set_cen(true)); |
| 520 | }) | 523 | }) |
| 521 | } | 524 | } |
| 522 | } | 525 | } |
| 523 | 526 | ||
| 524 | impl Driver for RtcDriver { | 527 | impl Driver for RtcDriver { |
| 525 | fn now(&self) -> u64 { | 528 | fn now(&self) -> u64 { |
| 526 | let r = T::regs_gp16(); | 529 | let r = regs_gp16(); |
| 527 | 530 | ||
| 528 | let period = self.period.load(Ordering::Relaxed); | 531 | let period = self.period.load(Ordering::Relaxed); |
| 529 | compiler_fence(Ordering::Acquire); | 532 | compiler_fence(Ordering::Acquire); |
| @@ -554,7 +557,7 @@ impl Driver for RtcDriver { | |||
| 554 | 557 | ||
| 555 | fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool { | 558 | fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool { |
| 556 | critical_section::with(|cs| { | 559 | critical_section::with(|cs| { |
| 557 | let r = T::regs_gp16(); | 560 | let r = regs_gp16(); |
| 558 | 561 | ||
| 559 | let n = alarm.id() as usize; | 562 | let n = alarm.id() as usize; |
| 560 | let alarm = self.get_alarm(cs, alarm); | 563 | let alarm = self.get_alarm(cs, alarm); |
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 72f1ec864..a892646cf 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -5,12 +5,15 @@ use core::marker::PhantomData; | |||
| 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use stm32_metapac::timer::vals::Ckd; | 6 | use stm32_metapac::timer::vals::Ckd; |
| 7 | 7 | ||
| 8 | use super::simple_pwm::*; | 8 | use super::low_level::{CountingMode, OutputPolarity, Timer}; |
| 9 | use super::*; | 9 | use super::simple_pwm::{Ch1, Ch2, Ch3, Ch4, PwmPin}; |
| 10 | #[allow(unused_imports)] | 10 | use super::{ |
| 11 | use crate::gpio::sealed::{AFType, Pin}; | 11 | AdvancedInstance4Channel, Channel, Channel1ComplementaryPin, Channel2ComplementaryPin, Channel3ComplementaryPin, |
| 12 | Channel4ComplementaryPin, | ||
| 13 | }; | ||
| 12 | use crate::gpio::{AnyPin, OutputType}; | 14 | use crate::gpio::{AnyPin, OutputType}; |
| 13 | use crate::time::Hertz; | 15 | use crate::time::Hertz; |
| 16 | use crate::timer::low_level::OutputCompareMode; | ||
| 14 | use crate::Peripheral; | 17 | use crate::Peripheral; |
| 15 | 18 | ||
| 16 | /// Complementary PWM pin wrapper. | 19 | /// Complementary PWM pin wrapper. |
| @@ -23,7 +26,7 @@ pub struct ComplementaryPwmPin<'d, T, C> { | |||
| 23 | 26 | ||
| 24 | macro_rules! complementary_channel_impl { | 27 | macro_rules! complementary_channel_impl { |
| 25 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 28 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 26 | impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwmPin<'d, T, $channel> { | 29 | impl<'d, T: AdvancedInstance4Channel> ComplementaryPwmPin<'d, T, $channel> { |
| 27 | #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] | 30 | #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] |
| 28 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { | 31 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { |
| 29 | into_ref!(pin); | 32 | into_ref!(pin); |
| @@ -48,11 +51,11 @@ complementary_channel_impl!(new_ch3, Ch3, Channel3ComplementaryPin); | |||
| 48 | complementary_channel_impl!(new_ch4, Ch4, Channel4ComplementaryPin); | 51 | complementary_channel_impl!(new_ch4, Ch4, Channel4ComplementaryPin); |
| 49 | 52 | ||
| 50 | /// PWM driver with support for standard and complementary outputs. | 53 | /// PWM driver with support for standard and complementary outputs. |
| 51 | pub struct ComplementaryPwm<'d, T> { | 54 | pub struct ComplementaryPwm<'d, T: AdvancedInstance4Channel> { |
| 52 | inner: PeripheralRef<'d, T>, | 55 | inner: Timer<'d, T>, |
| 53 | } | 56 | } |
| 54 | 57 | ||
| 55 | impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | 58 | impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { |
| 56 | /// Create a new complementary PWM driver. | 59 | /// Create a new complementary PWM driver. |
| 57 | #[allow(clippy::too_many_arguments)] | 60 | #[allow(clippy::too_many_arguments)] |
| 58 | pub fn new( | 61 | pub fn new( |
| @@ -72,11 +75,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | |||
| 72 | } | 75 | } |
| 73 | 76 | ||
| 74 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { | 77 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { |
| 75 | into_ref!(tim); | 78 | let mut this = Self { inner: Timer::new(tim) }; |
| 76 | |||
| 77 | T::enable_and_reset(); | ||
| 78 | |||
| 79 | let mut this = Self { inner: tim }; | ||
| 80 | 79 | ||
| 81 | this.inner.set_counting_mode(counting_mode); | 80 | this.inner.set_counting_mode(counting_mode); |
| 82 | this.set_frequency(freq); | 81 | this.set_frequency(freq); |
| @@ -123,7 +122,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | |||
| 123 | /// | 122 | /// |
| 124 | /// This value depends on the configured frequency and the timer's clock rate from RCC. | 123 | /// This value depends on the configured frequency and the timer's clock rate from RCC. |
| 125 | pub fn get_max_duty(&self) -> u16 { | 124 | pub fn get_max_duty(&self) -> u16 { |
| 126 | self.inner.get_max_compare_value() + 1 | 125 | self.inner.get_max_compare_value() as u16 + 1 |
| 127 | } | 126 | } |
| 128 | 127 | ||
| 129 | /// Set the duty for a given channel. | 128 | /// Set the duty for a given channel. |
| @@ -131,7 +130,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | |||
| 131 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. | 130 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. |
| 132 | pub fn set_duty(&mut self, channel: Channel, duty: u16) { | 131 | pub fn set_duty(&mut self, channel: Channel, duty: u16) { |
| 133 | assert!(duty <= self.get_max_duty()); | 132 | assert!(duty <= self.get_max_duty()); |
| 134 | self.inner.set_compare_value(channel, duty) | 133 | self.inner.set_compare_value(channel, duty as _) |
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | /// Set the output polarity for a given channel. | 136 | /// Set the output polarity for a given channel. |
| @@ -149,7 +148,7 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> ComplementaryPwm<'d, T> { | |||
| 149 | } | 148 | } |
| 150 | } | 149 | } |
| 151 | 150 | ||
| 152 | impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { | 151 | impl<'d, T: AdvancedInstance4Channel> embedded_hal_02::Pwm for ComplementaryPwm<'d, T> { |
| 153 | type Channel = Channel; | 152 | type Channel = Channel; |
| 154 | type Time = Hertz; | 153 | type Time = Hertz; |
| 155 | type Duty = u16; | 154 | type Duty = u16; |
| @@ -169,16 +168,16 @@ impl<'d, T: ComplementaryCaptureCompare16bitInstance> embedded_hal_02::Pwm for C | |||
| 169 | } | 168 | } |
| 170 | 169 | ||
| 171 | fn get_duty(&self, channel: Self::Channel) -> Self::Duty { | 170 | fn get_duty(&self, channel: Self::Channel) -> Self::Duty { |
| 172 | self.inner.get_compare_value(channel) | 171 | self.inner.get_compare_value(channel) as u16 |
| 173 | } | 172 | } |
| 174 | 173 | ||
| 175 | fn get_max_duty(&self) -> Self::Duty { | 174 | fn get_max_duty(&self) -> Self::Duty { |
| 176 | self.inner.get_max_compare_value() + 1 | 175 | self.inner.get_max_compare_value() as u16 + 1 |
| 177 | } | 176 | } |
| 178 | 177 | ||
| 179 | fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { | 178 | fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) { |
| 180 | assert!(duty <= self.get_max_duty()); | 179 | assert!(duty <= self.get_max_duty()); |
| 181 | self.inner.set_compare_value(channel, duty) | 180 | self.inner.set_compare_value(channel, duty as u32) |
| 182 | } | 181 | } |
| 183 | 182 | ||
| 184 | fn set_period<P>(&mut self, period: P) | 183 | fn set_period<P>(&mut self, period: P) |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs new file mode 100644 index 000000000..a5d942314 --- /dev/null +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -0,0 +1,638 @@ | |||
| 1 | //! Low-level timer driver. | ||
| 2 | //! | ||
| 3 | //! This is an unopinionated, very low-level driver for all STM32 timers. It allows direct register | ||
| 4 | //! manipulation with the `regs_*()` methods, and has utility functions that are thin wrappers | ||
| 5 | //! over the registers. | ||
| 6 | //! | ||
| 7 | //! The available functionality depends on the timer type. | ||
| 8 | |||
| 9 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | ||
| 10 | |||
| 11 | use super::*; | ||
| 12 | use crate::pac::timer::vals; | ||
| 13 | use crate::time::Hertz; | ||
| 14 | |||
| 15 | /// Input capture mode. | ||
| 16 | #[derive(Clone, Copy)] | ||
| 17 | pub enum InputCaptureMode { | ||
| 18 | /// Rising edge only. | ||
| 19 | Rising, | ||
| 20 | /// Falling edge only. | ||
| 21 | Falling, | ||
| 22 | /// Both rising or falling edges. | ||
| 23 | BothEdges, | ||
| 24 | } | ||
| 25 | |||
| 26 | /// Input TI selection. | ||
| 27 | #[derive(Clone, Copy)] | ||
| 28 | pub enum InputTISelection { | ||
| 29 | /// Normal | ||
| 30 | Normal, | ||
| 31 | /// Alternate | ||
| 32 | Alternate, | ||
| 33 | /// TRC | ||
| 34 | TRC, | ||
| 35 | } | ||
| 36 | |||
| 37 | impl From<InputTISelection> for stm32_metapac::timer::vals::CcmrInputCcs { | ||
| 38 | fn from(tisel: InputTISelection) -> Self { | ||
| 39 | match tisel { | ||
| 40 | InputTISelection::Normal => stm32_metapac::timer::vals::CcmrInputCcs::TI4, | ||
| 41 | InputTISelection::Alternate => stm32_metapac::timer::vals::CcmrInputCcs::TI3, | ||
| 42 | InputTISelection::TRC => stm32_metapac::timer::vals::CcmrInputCcs::TRC, | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | /// Timer counting mode. | ||
| 48 | #[repr(u8)] | ||
| 49 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] | ||
| 50 | pub enum CountingMode { | ||
| 51 | #[default] | ||
| 52 | /// The timer counts up to the reload value and then resets back to 0. | ||
| 53 | EdgeAlignedUp, | ||
| 54 | /// The timer counts down to 0 and then resets back to the reload value. | ||
| 55 | EdgeAlignedDown, | ||
| 56 | /// The timer counts up to the reload value and then counts back to 0. | ||
| 57 | /// | ||
| 58 | /// The output compare interrupt flags of channels configured in output are | ||
| 59 | /// set when the counter is counting down. | ||
| 60 | CenterAlignedDownInterrupts, | ||
| 61 | /// The timer counts up to the reload value and then counts back to 0. | ||
| 62 | /// | ||
| 63 | /// The output compare interrupt flags of channels configured in output are | ||
| 64 | /// set when the counter is counting up. | ||
| 65 | CenterAlignedUpInterrupts, | ||
| 66 | /// The timer counts up to the reload value and then counts back to 0. | ||
| 67 | /// | ||
| 68 | /// The output compare interrupt flags of channels configured in output are | ||
| 69 | /// set when the counter is counting both up or down. | ||
| 70 | CenterAlignedBothInterrupts, | ||
| 71 | } | ||
| 72 | |||
| 73 | impl CountingMode { | ||
| 74 | /// Return whether this mode is edge-aligned (up or down). | ||
| 75 | pub fn is_edge_aligned(&self) -> bool { | ||
| 76 | matches!(self, CountingMode::EdgeAlignedUp | CountingMode::EdgeAlignedDown) | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Return whether this mode is center-aligned. | ||
| 80 | pub fn is_center_aligned(&self) -> bool { | ||
| 81 | matches!( | ||
| 82 | self, | ||
| 83 | CountingMode::CenterAlignedDownInterrupts | ||
| 84 | | CountingMode::CenterAlignedUpInterrupts | ||
| 85 | | CountingMode::CenterAlignedBothInterrupts | ||
| 86 | ) | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | impl From<CountingMode> for (vals::Cms, vals::Dir) { | ||
| 91 | fn from(value: CountingMode) -> Self { | ||
| 92 | match value { | ||
| 93 | CountingMode::EdgeAlignedUp => (vals::Cms::EDGEALIGNED, vals::Dir::UP), | ||
| 94 | CountingMode::EdgeAlignedDown => (vals::Cms::EDGEALIGNED, vals::Dir::DOWN), | ||
| 95 | CountingMode::CenterAlignedDownInterrupts => (vals::Cms::CENTERALIGNED1, vals::Dir::UP), | ||
| 96 | CountingMode::CenterAlignedUpInterrupts => (vals::Cms::CENTERALIGNED2, vals::Dir::UP), | ||
| 97 | CountingMode::CenterAlignedBothInterrupts => (vals::Cms::CENTERALIGNED3, vals::Dir::UP), | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | impl From<(vals::Cms, vals::Dir)> for CountingMode { | ||
| 103 | fn from(value: (vals::Cms, vals::Dir)) -> Self { | ||
| 104 | match value { | ||
| 105 | (vals::Cms::EDGEALIGNED, vals::Dir::UP) => CountingMode::EdgeAlignedUp, | ||
| 106 | (vals::Cms::EDGEALIGNED, vals::Dir::DOWN) => CountingMode::EdgeAlignedDown, | ||
| 107 | (vals::Cms::CENTERALIGNED1, _) => CountingMode::CenterAlignedDownInterrupts, | ||
| 108 | (vals::Cms::CENTERALIGNED2, _) => CountingMode::CenterAlignedUpInterrupts, | ||
| 109 | (vals::Cms::CENTERALIGNED3, _) => CountingMode::CenterAlignedBothInterrupts, | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | /// Output compare mode. | ||
| 115 | #[derive(Clone, Copy)] | ||
| 116 | pub enum OutputCompareMode { | ||
| 117 | /// The comparison between the output compare register TIMx_CCRx and | ||
| 118 | /// the counter TIMx_CNT has no effect on the outputs. | ||
| 119 | /// (this mode is used to generate a timing base). | ||
| 120 | Frozen, | ||
| 121 | /// Set channel to active level on match. OCxREF signal is forced high when the | ||
| 122 | /// counter TIMx_CNT matches the capture/compare register x (TIMx_CCRx). | ||
| 123 | ActiveOnMatch, | ||
| 124 | /// Set channel to inactive level on match. OCxREF signal is forced low when the | ||
| 125 | /// counter TIMx_CNT matches the capture/compare register x (TIMx_CCRx). | ||
| 126 | InactiveOnMatch, | ||
| 127 | /// Toggle - OCxREF toggles when TIMx_CNT=TIMx_CCRx. | ||
| 128 | Toggle, | ||
| 129 | /// Force inactive level - OCxREF is forced low. | ||
| 130 | ForceInactive, | ||
| 131 | /// Force active level - OCxREF is forced high. | ||
| 132 | ForceActive, | ||
| 133 | /// PWM mode 1 - In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRx | ||
| 134 | /// else inactive. In downcounting, channel is inactive (OCxREF=0) as long as | ||
| 135 | /// TIMx_CNT>TIMx_CCRx else active (OCxREF=1). | ||
| 136 | PwmMode1, | ||
| 137 | /// PWM mode 2 - In upcounting, channel is inactive as long as | ||
| 138 | /// TIMx_CNT<TIMx_CCRx else active. In downcounting, channel is active as long as | ||
| 139 | /// TIMx_CNT>TIMx_CCRx else inactive. | ||
| 140 | PwmMode2, | ||
| 141 | // TODO: there's more modes here depending on the chip family. | ||
| 142 | } | ||
| 143 | |||
| 144 | impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm { | ||
| 145 | fn from(mode: OutputCompareMode) -> Self { | ||
| 146 | match mode { | ||
| 147 | OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN, | ||
| 148 | OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVEONMATCH, | ||
| 149 | OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVEONMATCH, | ||
| 150 | OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE, | ||
| 151 | OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCEINACTIVE, | ||
| 152 | OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCEACTIVE, | ||
| 153 | OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWMMODE1, | ||
| 154 | OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWMMODE2, | ||
| 155 | } | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | /// Timer output pin polarity. | ||
| 160 | #[derive(Clone, Copy)] | ||
| 161 | pub enum OutputPolarity { | ||
| 162 | /// Active high (higher duty value makes the pin spend more time high). | ||
| 163 | ActiveHigh, | ||
| 164 | /// Active low (higher duty value makes the pin spend more time low). | ||
| 165 | ActiveLow, | ||
| 166 | } | ||
| 167 | |||
| 168 | impl From<OutputPolarity> for bool { | ||
| 169 | fn from(mode: OutputPolarity) -> Self { | ||
| 170 | match mode { | ||
| 171 | OutputPolarity::ActiveHigh => false, | ||
| 172 | OutputPolarity::ActiveLow => true, | ||
| 173 | } | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | /// Low-level timer driver. | ||
| 178 | pub struct Timer<'d, T: CoreInstance> { | ||
| 179 | tim: PeripheralRef<'d, T>, | ||
| 180 | } | ||
| 181 | |||
| 182 | impl<'d, T: CoreInstance> Drop for Timer<'d, T> { | ||
| 183 | fn drop(&mut self) { | ||
| 184 | T::disable() | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | impl<'d, T: CoreInstance> Timer<'d, T> { | ||
| 189 | /// Create a new timer driver. | ||
| 190 | pub fn new(tim: impl Peripheral<P = T> + 'd) -> Self { | ||
| 191 | into_ref!(tim); | ||
| 192 | |||
| 193 | T::enable_and_reset(); | ||
| 194 | |||
| 195 | Self { tim } | ||
| 196 | } | ||
| 197 | |||
| 198 | /// Get access to the virutal core 16bit timer registers. | ||
| 199 | /// | ||
| 200 | /// Note: This works even if the timer is more capable, because registers | ||
| 201 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 202 | /// for a given set of capabilities, and having it transparently work with | ||
| 203 | /// more capable timers. | ||
| 204 | pub fn regs_core(&self) -> crate::pac::timer::TimCore { | ||
| 205 | unsafe { crate::pac::timer::TimCore::from_ptr(T::regs()) } | ||
| 206 | } | ||
| 207 | |||
| 208 | #[cfg(not(stm32l0))] | ||
| 209 | fn regs_gp32_unchecked(&self) -> crate::pac::timer::TimGp32 { | ||
| 210 | unsafe { crate::pac::timer::TimGp32::from_ptr(T::regs()) } | ||
| 211 | } | ||
| 212 | |||
| 213 | /// Start the timer. | ||
| 214 | pub fn start(&self) { | ||
| 215 | self.regs_core().cr1().modify(|r| r.set_cen(true)); | ||
| 216 | } | ||
| 217 | |||
| 218 | /// Stop the timer. | ||
| 219 | pub fn stop(&self) { | ||
| 220 | self.regs_core().cr1().modify(|r| r.set_cen(false)); | ||
| 221 | } | ||
| 222 | |||
| 223 | /// Reset the counter value to 0 | ||
| 224 | pub fn reset(&self) { | ||
| 225 | self.regs_core().cnt().write(|r| r.set_cnt(0)); | ||
| 226 | } | ||
| 227 | |||
| 228 | /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. | ||
| 229 | /// | ||
| 230 | /// This means that in the default edge-aligned mode, | ||
| 231 | /// the timer counter will wrap around at the same frequency as is being set. | ||
| 232 | /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved | ||
| 233 | /// because it needs to count up and down. | ||
| 234 | pub fn set_frequency(&self, frequency: Hertz) { | ||
| 235 | let f = frequency.0; | ||
| 236 | assert!(f > 0); | ||
| 237 | let timer_f = T::frequency().0; | ||
| 238 | |||
| 239 | match T::BITS { | ||
| 240 | TimerBits::Bits16 => { | ||
| 241 | let pclk_ticks_per_timer_period = timer_f / f; | ||
| 242 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 16)).try_into()); | ||
| 243 | let divide_by = pclk_ticks_per_timer_period / (u32::from(psc) + 1); | ||
| 244 | |||
| 245 | // the timer counts `0..=arr`, we want it to count `0..divide_by` | ||
| 246 | let arr = unwrap!(u16::try_from(divide_by - 1)); | ||
| 247 | |||
| 248 | let regs = self.regs_core(); | ||
| 249 | regs.psc().write_value(psc); | ||
| 250 | regs.arr().write(|r| r.set_arr(arr)); | ||
| 251 | |||
| 252 | regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY)); | ||
| 253 | regs.egr().write(|r| r.set_ug(true)); | ||
| 254 | regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); | ||
| 255 | } | ||
| 256 | #[cfg(not(stm32l0))] | ||
| 257 | TimerBits::Bits32 => { | ||
| 258 | let pclk_ticks_per_timer_period = (timer_f / f) as u64; | ||
| 259 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into()); | ||
| 260 | let arr: u32 = unwrap!((pclk_ticks_per_timer_period / (psc as u64 + 1)).try_into()); | ||
| 261 | |||
| 262 | let regs = self.regs_gp32_unchecked(); | ||
| 263 | regs.psc().write_value(psc); | ||
| 264 | regs.arr().write_value(arr); | ||
| 265 | |||
| 266 | regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY)); | ||
| 267 | regs.egr().write(|r| r.set_ug(true)); | ||
| 268 | regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | /// Clear update interrupt. | ||
| 274 | /// | ||
| 275 | /// Returns whether the update interrupt flag was set. | ||
| 276 | pub fn clear_update_interrupt(&self) -> bool { | ||
| 277 | let regs = self.regs_core(); | ||
| 278 | let sr = regs.sr().read(); | ||
| 279 | if sr.uif() { | ||
| 280 | regs.sr().modify(|r| { | ||
| 281 | r.set_uif(false); | ||
| 282 | }); | ||
| 283 | true | ||
| 284 | } else { | ||
| 285 | false | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | /// Enable/disable the update interrupt. | ||
| 290 | pub fn enable_update_interrupt(&self, enable: bool) { | ||
| 291 | self.regs_core().dier().modify(|r| r.set_uie(enable)); | ||
| 292 | } | ||
| 293 | |||
| 294 | /// Enable/disable autoreload preload. | ||
| 295 | pub fn set_autoreload_preload(&self, enable: bool) { | ||
| 296 | self.regs_core().cr1().modify(|r| r.set_arpe(enable)); | ||
| 297 | } | ||
| 298 | |||
| 299 | /// Get the timer frequency. | ||
| 300 | pub fn get_frequency(&self) -> Hertz { | ||
| 301 | let timer_f = T::frequency(); | ||
| 302 | |||
| 303 | match T::BITS { | ||
| 304 | TimerBits::Bits16 => { | ||
| 305 | let regs = self.regs_core(); | ||
| 306 | let arr = regs.arr().read().arr(); | ||
| 307 | let psc = regs.psc().read(); | ||
| 308 | |||
| 309 | timer_f / arr / (psc + 1) | ||
| 310 | } | ||
| 311 | #[cfg(not(stm32l0))] | ||
| 312 | TimerBits::Bits32 => { | ||
| 313 | let regs = self.regs_gp32_unchecked(); | ||
| 314 | let arr = regs.arr().read(); | ||
| 315 | let psc = regs.psc().read(); | ||
| 316 | |||
| 317 | timer_f / arr / (psc + 1) | ||
| 318 | } | ||
| 319 | } | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | impl<'d, T: BasicNoCr2Instance> Timer<'d, T> { | ||
| 324 | /// Get access to the Baisc 16bit timer registers. | ||
| 325 | /// | ||
| 326 | /// Note: This works even if the timer is more capable, because registers | ||
| 327 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 328 | /// for a given set of capabilities, and having it transparently work with | ||
| 329 | /// more capable timers. | ||
| 330 | pub fn regs_basic_no_cr2(&self) -> crate::pac::timer::TimBasicNoCr2 { | ||
| 331 | unsafe { crate::pac::timer::TimBasicNoCr2::from_ptr(T::regs()) } | ||
| 332 | } | ||
| 333 | |||
| 334 | /// Enable/disable the update dma. | ||
| 335 | pub fn enable_update_dma(&self, enable: bool) { | ||
| 336 | self.regs_basic_no_cr2().dier().modify(|r| r.set_ude(enable)); | ||
| 337 | } | ||
| 338 | |||
| 339 | /// Get the update dma enable/disable state. | ||
| 340 | pub fn get_update_dma_state(&self) -> bool { | ||
| 341 | self.regs_basic_no_cr2().dier().read().ude() | ||
| 342 | } | ||
| 343 | } | ||
| 344 | |||
| 345 | impl<'d, T: BasicInstance> Timer<'d, T> { | ||
| 346 | /// Get access to the Baisc 16bit timer registers. | ||
| 347 | /// | ||
| 348 | /// Note: This works even if the timer is more capable, because registers | ||
| 349 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 350 | /// for a given set of capabilities, and having it transparently work with | ||
| 351 | /// more capable timers. | ||
| 352 | pub fn regs_basic(&self) -> crate::pac::timer::TimBasic { | ||
| 353 | unsafe { crate::pac::timer::TimBasic::from_ptr(T::regs()) } | ||
| 354 | } | ||
| 355 | } | ||
| 356 | |||
| 357 | impl<'d, T: GeneralInstance1Channel> Timer<'d, T> { | ||
| 358 | /// Get access to the general purpose 1 channel 16bit timer registers. | ||
| 359 | /// | ||
| 360 | /// Note: This works even if the timer is more capable, because registers | ||
| 361 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 362 | /// for a given set of capabilities, and having it transparently work with | ||
| 363 | /// more capable timers. | ||
| 364 | pub fn regs_1ch(&self) -> crate::pac::timer::Tim1ch { | ||
| 365 | unsafe { crate::pac::timer::Tim1ch::from_ptr(T::regs()) } | ||
| 366 | } | ||
| 367 | |||
| 368 | /// Set clock divider. | ||
| 369 | pub fn set_clock_division(&self, ckd: vals::Ckd) { | ||
| 370 | self.regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); | ||
| 371 | } | ||
| 372 | |||
| 373 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. | ||
| 374 | pub fn get_max_compare_value(&self) -> u32 { | ||
| 375 | match T::BITS { | ||
| 376 | TimerBits::Bits16 => self.regs_1ch().arr().read().arr() as u32, | ||
| 377 | #[cfg(not(stm32l0))] | ||
| 378 | TimerBits::Bits32 => self.regs_gp32_unchecked().arr().read(), | ||
| 379 | } | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | impl<'d, T: GeneralInstance2Channel> Timer<'d, T> { | ||
| 384 | /// Get access to the general purpose 2 channel 16bit timer registers. | ||
| 385 | /// | ||
| 386 | /// Note: This works even if the timer is more capable, because registers | ||
| 387 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 388 | /// for a given set of capabilities, and having it transparently work with | ||
| 389 | /// more capable timers. | ||
| 390 | pub fn regs_2ch(&self) -> crate::pac::timer::Tim2ch { | ||
| 391 | unsafe { crate::pac::timer::Tim2ch::from_ptr(T::regs()) } | ||
| 392 | } | ||
| 393 | } | ||
| 394 | |||
| 395 | impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | ||
| 396 | /// Get access to the general purpose 16bit timer registers. | ||
| 397 | /// | ||
| 398 | /// Note: This works even if the timer is more capable, because registers | ||
| 399 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 400 | /// for a given set of capabilities, and having it transparently work with | ||
| 401 | /// more capable timers. | ||
| 402 | pub fn regs_gp16(&self) -> crate::pac::timer::TimGp16 { | ||
| 403 | unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) } | ||
| 404 | } | ||
| 405 | |||
| 406 | /// Enable timer outputs. | ||
| 407 | pub fn enable_outputs(&self) { | ||
| 408 | self.tim.enable_outputs() | ||
| 409 | } | ||
| 410 | |||
| 411 | /// Set counting mode. | ||
| 412 | pub fn set_counting_mode(&self, mode: CountingMode) { | ||
| 413 | let (cms, dir) = mode.into(); | ||
| 414 | |||
| 415 | let timer_enabled = self.regs_core().cr1().read().cen(); | ||
| 416 | // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. | ||
| 417 | // Changing direction is discouraged while the timer is running. | ||
| 418 | assert!(!timer_enabled); | ||
| 419 | |||
| 420 | self.regs_gp16().cr1().modify(|r| r.set_dir(dir)); | ||
| 421 | self.regs_gp16().cr1().modify(|r| r.set_cms(cms)) | ||
| 422 | } | ||
| 423 | |||
| 424 | /// Get counting mode. | ||
| 425 | pub fn get_counting_mode(&self) -> CountingMode { | ||
| 426 | let cr1 = self.regs_gp16().cr1().read(); | ||
| 427 | (cr1.cms(), cr1.dir()).into() | ||
| 428 | } | ||
| 429 | |||
| 430 | /// Set input capture filter. | ||
| 431 | pub fn set_input_capture_filter(&self, channel: Channel, icf: vals::FilterValue) { | ||
| 432 | let raw_channel = channel.index(); | ||
| 433 | self.regs_gp16() | ||
| 434 | .ccmr_input(raw_channel / 2) | ||
| 435 | .modify(|r| r.set_icf(raw_channel % 2, icf)); | ||
| 436 | } | ||
| 437 | |||
| 438 | /// Clear input interrupt. | ||
| 439 | pub fn clear_input_interrupt(&self, channel: Channel) { | ||
| 440 | self.regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); | ||
| 441 | } | ||
| 442 | |||
| 443 | /// Enable input interrupt. | ||
| 444 | pub fn enable_input_interrupt(&self, channel: Channel, enable: bool) { | ||
| 445 | self.regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); | ||
| 446 | } | ||
| 447 | |||
| 448 | /// Set input capture prescaler. | ||
| 449 | pub fn set_input_capture_prescaler(&self, channel: Channel, factor: u8) { | ||
| 450 | let raw_channel = channel.index(); | ||
| 451 | self.regs_gp16() | ||
| 452 | .ccmr_input(raw_channel / 2) | ||
| 453 | .modify(|r| r.set_icpsc(raw_channel % 2, factor)); | ||
| 454 | } | ||
| 455 | |||
| 456 | /// Set input TI selection. | ||
| 457 | pub fn set_input_ti_selection(&self, channel: Channel, tisel: InputTISelection) { | ||
| 458 | let raw_channel = channel.index(); | ||
| 459 | self.regs_gp16() | ||
| 460 | .ccmr_input(raw_channel / 2) | ||
| 461 | .modify(|r| r.set_ccs(raw_channel % 2, tisel.into())); | ||
| 462 | } | ||
| 463 | |||
| 464 | /// Set input capture mode. | ||
| 465 | pub fn set_input_capture_mode(&self, channel: Channel, mode: InputCaptureMode) { | ||
| 466 | self.regs_gp16().ccer().modify(|r| match mode { | ||
| 467 | InputCaptureMode::Rising => { | ||
| 468 | r.set_ccnp(channel.index(), false); | ||
| 469 | r.set_ccp(channel.index(), false); | ||
| 470 | } | ||
| 471 | InputCaptureMode::Falling => { | ||
| 472 | r.set_ccnp(channel.index(), false); | ||
| 473 | r.set_ccp(channel.index(), true); | ||
| 474 | } | ||
| 475 | InputCaptureMode::BothEdges => { | ||
| 476 | r.set_ccnp(channel.index(), true); | ||
| 477 | r.set_ccp(channel.index(), true); | ||
| 478 | } | ||
| 479 | }); | ||
| 480 | } | ||
| 481 | |||
| 482 | /// Set output compare mode. | ||
| 483 | pub fn set_output_compare_mode(&self, channel: Channel, mode: OutputCompareMode) { | ||
| 484 | let raw_channel: usize = channel.index(); | ||
| 485 | self.regs_gp16() | ||
| 486 | .ccmr_output(raw_channel / 2) | ||
| 487 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 488 | } | ||
| 489 | |||
| 490 | /// Set output polarity. | ||
| 491 | pub fn set_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { | ||
| 492 | self.regs_gp16() | ||
| 493 | .ccer() | ||
| 494 | .modify(|w| w.set_ccp(channel.index(), polarity.into())); | ||
| 495 | } | ||
| 496 | |||
| 497 | /// Enable/disable a channel. | ||
| 498 | pub fn enable_channel(&self, channel: Channel, enable: bool) { | ||
| 499 | self.regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); | ||
| 500 | } | ||
| 501 | |||
| 502 | /// Get enable/disable state of a channel | ||
| 503 | pub fn get_channel_enable_state(&self, channel: Channel) -> bool { | ||
| 504 | self.regs_gp16().ccer().read().cce(channel.index()) | ||
| 505 | } | ||
| 506 | |||
| 507 | /// Set compare value for a channel. | ||
| 508 | pub fn set_compare_value(&self, channel: Channel, value: u32) { | ||
| 509 | match T::BITS { | ||
| 510 | TimerBits::Bits16 => { | ||
| 511 | let value = unwrap!(u16::try_from(value)); | ||
| 512 | self.regs_gp16().ccr(channel.index()).modify(|w| w.set_ccr(value)); | ||
| 513 | } | ||
| 514 | #[cfg(not(stm32l0))] | ||
| 515 | TimerBits::Bits32 => { | ||
| 516 | self.regs_gp32_unchecked().ccr(channel.index()).write_value(value); | ||
| 517 | } | ||
| 518 | } | ||
| 519 | } | ||
| 520 | |||
| 521 | /// Get compare value for a channel. | ||
| 522 | pub fn get_compare_value(&self, channel: Channel) -> u32 { | ||
| 523 | match T::BITS { | ||
| 524 | TimerBits::Bits16 => self.regs_gp16().ccr(channel.index()).read().ccr() as u32, | ||
| 525 | #[cfg(not(stm32l0))] | ||
| 526 | TimerBits::Bits32 => self.regs_gp32_unchecked().ccr(channel.index()).read(), | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | /// Get capture value for a channel. | ||
| 531 | pub fn get_capture_value(&self, channel: Channel) -> u32 { | ||
| 532 | self.get_compare_value(channel) | ||
| 533 | } | ||
| 534 | |||
| 535 | /// Set output compare preload. | ||
| 536 | pub fn set_output_compare_preload(&self, channel: Channel, preload: bool) { | ||
| 537 | let channel_index = channel.index(); | ||
| 538 | self.regs_gp16() | ||
| 539 | .ccmr_output(channel_index / 2) | ||
| 540 | .modify(|w| w.set_ocpe(channel_index % 2, preload)); | ||
| 541 | } | ||
| 542 | |||
| 543 | /// Get capture compare DMA selection | ||
| 544 | pub fn get_cc_dma_selection(&self) -> vals::Ccds { | ||
| 545 | self.regs_gp16().cr2().read().ccds() | ||
| 546 | } | ||
| 547 | |||
| 548 | /// Set capture compare DMA selection | ||
| 549 | pub fn set_cc_dma_selection(&self, ccds: vals::Ccds) { | ||
| 550 | self.regs_gp16().cr2().modify(|w| w.set_ccds(ccds)) | ||
| 551 | } | ||
| 552 | |||
| 553 | /// Get capture compare DMA enable state | ||
| 554 | pub fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { | ||
| 555 | self.regs_gp16().dier().read().ccde(channel.index()) | ||
| 556 | } | ||
| 557 | |||
| 558 | /// Set capture compare DMA enable state | ||
| 559 | pub fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { | ||
| 560 | self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) | ||
| 561 | } | ||
| 562 | } | ||
| 563 | |||
| 564 | #[cfg(not(stm32l0))] | ||
| 565 | impl<'d, T: GeneralInstance32bit4Channel> Timer<'d, T> { | ||
| 566 | /// Get access to the general purpose 32bit timer registers. | ||
| 567 | /// | ||
| 568 | /// Note: This works even if the timer is more capable, because registers | ||
| 569 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 570 | /// for a given set of capabilities, and having it transparently work with | ||
| 571 | /// more capable timers. | ||
| 572 | pub fn regs_gp32(&self) -> crate::pac::timer::TimGp32 { | ||
| 573 | unsafe { crate::pac::timer::TimGp32::from_ptr(T::regs()) } | ||
| 574 | } | ||
| 575 | } | ||
| 576 | |||
| 577 | #[cfg(not(stm32l0))] | ||
| 578 | impl<'d, T: AdvancedInstance1Channel> Timer<'d, T> { | ||
| 579 | /// Get access to the general purpose 1 channel with one complementary 16bit timer registers. | ||
| 580 | /// | ||
| 581 | /// Note: This works even if the timer is more capable, because registers | ||
| 582 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 583 | /// for a given set of capabilities, and having it transparently work with | ||
| 584 | /// more capable timers. | ||
| 585 | pub fn regs_1ch_cmp(&self) -> crate::pac::timer::Tim1chCmp { | ||
| 586 | unsafe { crate::pac::timer::Tim1chCmp::from_ptr(T::regs()) } | ||
| 587 | } | ||
| 588 | |||
| 589 | /// Set clock divider for the dead time. | ||
| 590 | pub fn set_dead_time_clock_division(&self, value: vals::Ckd) { | ||
| 591 | self.regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); | ||
| 592 | } | ||
| 593 | |||
| 594 | /// Set dead time, as a fraction of the max duty value. | ||
| 595 | pub fn set_dead_time_value(&self, value: u8) { | ||
| 596 | self.regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); | ||
| 597 | } | ||
| 598 | |||
| 599 | /// Set state of MOE-bit in BDTR register to en-/disable output | ||
| 600 | pub fn set_moe(&self, enable: bool) { | ||
| 601 | self.regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable)); | ||
| 602 | } | ||
| 603 | } | ||
| 604 | |||
| 605 | #[cfg(not(stm32l0))] | ||
| 606 | impl<'d, T: AdvancedInstance2Channel> Timer<'d, T> { | ||
| 607 | /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. | ||
| 608 | /// | ||
| 609 | /// Note: This works even if the timer is more capable, because registers | ||
| 610 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 611 | /// for a given set of capabilities, and having it transparently work with | ||
| 612 | /// more capable timers. | ||
| 613 | pub fn regs_2ch_cmp(&self) -> crate::pac::timer::Tim2chCmp { | ||
| 614 | unsafe { crate::pac::timer::Tim2chCmp::from_ptr(T::regs()) } | ||
| 615 | } | ||
| 616 | } | ||
| 617 | |||
| 618 | #[cfg(not(stm32l0))] | ||
| 619 | impl<'d, T: AdvancedInstance4Channel> Timer<'d, T> { | ||
| 620 | /// Get access to the advanced timer registers. | ||
| 621 | pub fn regs_advanced(&self) -> crate::pac::timer::TimAdv { | ||
| 622 | unsafe { crate::pac::timer::TimAdv::from_ptr(T::regs()) } | ||
| 623 | } | ||
| 624 | |||
| 625 | /// Set complementary output polarity. | ||
| 626 | pub fn set_complementary_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { | ||
| 627 | self.regs_advanced() | ||
| 628 | .ccer() | ||
| 629 | .modify(|w| w.set_ccnp(channel.index(), polarity.into())); | ||
| 630 | } | ||
| 631 | |||
| 632 | /// Enable/disable a complementary channel. | ||
| 633 | pub fn enable_complementary_channel(&self, channel: Channel, enable: bool) { | ||
| 634 | self.regs_advanced() | ||
| 635 | .ccer() | ||
| 636 | .modify(|w| w.set_ccne(channel.index(), enable)); | ||
| 637 | } | ||
| 638 | } | ||
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index ef893c7f5..2ba6b3f11 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -1,490 +1,13 @@ | |||
| 1 | //! Timers, PWM, quadrature decoder. | 1 | //! Timers, PWM, quadrature decoder. |
| 2 | //! | ||
| 3 | |||
| 4 | //! Timer inheritance | ||
| 5 | //! | ||
| 6 | |||
| 7 | // sealed: | ||
| 8 | // | ||
| 9 | // Core -------------------------> 1CH -------------------------> 1CH_CMP | ||
| 10 | // | | ^ | | ||
| 11 | // +--> Basic_NoCr2 --> Basic +--> 2CH --> GP16 --> GP32 | +--> 2CH_CMP --> ADV | ||
| 12 | // | | | ^ | | ^ ^ | ||
| 13 | // | | +------|--|--------------|-----------+ | | ||
| 14 | // | +--------------------+ +--------------|-----------|---------+ | ||
| 15 | // | | | | | ||
| 16 | // | +--------------------------------------|-----------+ | ||
| 17 | // +----------------------------------------------------+ | ||
| 18 | |||
| 19 | //! ```text | ||
| 20 | //! BasicInstance --> CaptureCompare16bitInstance --+--> ComplementaryCaptureCompare16bitInstance | ||
| 21 | //! | | ||
| 22 | //! +--> CaptureCompare32bitInstance | ||
| 23 | //! ``` | ||
| 24 | //! | ||
| 25 | //! Mapping: | ||
| 26 | //! | ||
| 27 | //! | trait | timer | | ||
| 28 | //! | :----------------------------------------: | ------------------------------------------------------------------------------------------------- | | ||
| 29 | //! | [BasicInstance] | Basic Timer | | ||
| 30 | //! | [CaptureCompare16bitInstance] | 1-channel Timer, 2-channel Timer, General Purpose 16-bit Timer | | ||
| 31 | //! | [CaptureCompare32bitInstance] | General Purpose 32-bit Timer | | ||
| 32 | //! | [ComplementaryCaptureCompare16bitInstance] | 1-channel with one complentary Timer, 2-channel with one complentary Timer, Advance Control Timer | | ||
| 33 | 2 | ||
| 34 | #[cfg(not(stm32l0))] | 3 | #[cfg(not(stm32l0))] |
| 35 | pub mod complementary_pwm; | 4 | pub mod complementary_pwm; |
| 5 | pub mod low_level; | ||
| 36 | pub mod qei; | 6 | pub mod qei; |
| 37 | pub mod simple_pwm; | 7 | pub mod simple_pwm; |
| 38 | 8 | ||
| 39 | use stm32_metapac::timer::vals; | ||
| 40 | |||
| 41 | use crate::interrupt; | 9 | use crate::interrupt; |
| 42 | use crate::rcc::RccPeripheral; | 10 | use crate::rcc::RccPeripheral; |
| 43 | use crate::time::Hertz; | ||
| 44 | |||
| 45 | /// Low-level timer access. | ||
| 46 | #[cfg(feature = "unstable-pac")] | ||
| 47 | pub mod low_level { | ||
| 48 | pub use super::sealed::*; | ||
| 49 | } | ||
| 50 | |||
| 51 | pub(crate) mod sealed { | ||
| 52 | use super::*; | ||
| 53 | |||
| 54 | /// Virtual Core 16-bit timer instance. | ||
| 55 | pub trait CoreInstance: RccPeripheral { | ||
| 56 | /// Interrupt for this timer. | ||
| 57 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 58 | |||
| 59 | /// Get access to the virutal core 16bit timer registers. | ||
| 60 | /// | ||
| 61 | /// Note: This works even if the timer is more capable, because registers | ||
| 62 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 63 | /// for a given set of capabilities, and having it transparently work with | ||
| 64 | /// more capable timers. | ||
| 65 | fn regs_core() -> crate::pac::timer::TimCore; | ||
| 66 | |||
| 67 | /// Start the timer. | ||
| 68 | fn start(&self) { | ||
| 69 | Self::regs_core().cr1().modify(|r| r.set_cen(true)); | ||
| 70 | } | ||
| 71 | |||
| 72 | /// Stop the timer. | ||
| 73 | fn stop(&self) { | ||
| 74 | Self::regs_core().cr1().modify(|r| r.set_cen(false)); | ||
| 75 | } | ||
| 76 | |||
| 77 | /// Reset the counter value to 0 | ||
| 78 | fn reset(&self) { | ||
| 79 | Self::regs_core().cnt().write(|r| r.set_cnt(0)); | ||
| 80 | } | ||
| 81 | |||
| 82 | /// Set the frequency of how many times per second the timer counts up to the max value or down to 0. | ||
| 83 | /// | ||
| 84 | /// This means that in the default edge-aligned mode, | ||
| 85 | /// the timer counter will wrap around at the same frequency as is being set. | ||
| 86 | /// In center-aligned mode (which not all timers support), the wrap-around frequency is effectively halved | ||
| 87 | /// because it needs to count up and down. | ||
| 88 | fn set_frequency(&self, frequency: Hertz) { | ||
| 89 | let f = frequency.0; | ||
| 90 | let timer_f = Self::frequency().0; | ||
| 91 | assert!(f > 0); | ||
| 92 | let pclk_ticks_per_timer_period = timer_f / f; | ||
| 93 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 16)).try_into()); | ||
| 94 | let divide_by = pclk_ticks_per_timer_period / (u32::from(psc) + 1); | ||
| 95 | |||
| 96 | // the timer counts `0..=arr`, we want it to count `0..divide_by` | ||
| 97 | let arr = unwrap!(u16::try_from(divide_by - 1)); | ||
| 98 | |||
| 99 | let regs = Self::regs_core(); | ||
| 100 | regs.psc().write(|r| r.set_psc(psc)); | ||
| 101 | regs.arr().write(|r| r.set_arr(arr)); | ||
| 102 | |||
| 103 | regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY)); | ||
| 104 | regs.egr().write(|r| r.set_ug(true)); | ||
| 105 | regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); | ||
| 106 | } | ||
| 107 | |||
| 108 | /// Clear update interrupt. | ||
| 109 | /// | ||
| 110 | /// Returns whether the update interrupt flag was set. | ||
| 111 | fn clear_update_interrupt(&self) -> bool { | ||
| 112 | let regs = Self::regs_core(); | ||
| 113 | let sr = regs.sr().read(); | ||
| 114 | if sr.uif() { | ||
| 115 | regs.sr().modify(|r| { | ||
| 116 | r.set_uif(false); | ||
| 117 | }); | ||
| 118 | true | ||
| 119 | } else { | ||
| 120 | false | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | /// Enable/disable the update interrupt. | ||
| 125 | fn enable_update_interrupt(&self, enable: bool) { | ||
| 126 | Self::regs_core().dier().modify(|r| r.set_uie(enable)); | ||
| 127 | } | ||
| 128 | |||
| 129 | /// Enable/disable autoreload preload. | ||
| 130 | fn set_autoreload_preload(&self, enable: bool) { | ||
| 131 | Self::regs_core().cr1().modify(|r| r.set_arpe(enable)); | ||
| 132 | } | ||
| 133 | |||
| 134 | /// Get the timer frequency. | ||
| 135 | fn get_frequency(&self) -> Hertz { | ||
| 136 | let timer_f = Self::frequency(); | ||
| 137 | |||
| 138 | let regs = Self::regs_core(); | ||
| 139 | let arr = regs.arr().read().arr(); | ||
| 140 | let psc = regs.psc().read().psc(); | ||
| 141 | |||
| 142 | timer_f / arr / (psc + 1) | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | /// Virtual Basic without CR2 16-bit timer instance. | ||
| 147 | pub trait BasicNoCr2Instance: CoreInstance { | ||
| 148 | /// Get access to the Baisc 16bit timer registers. | ||
| 149 | /// | ||
| 150 | /// Note: This works even if the timer is more capable, because registers | ||
| 151 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 152 | /// for a given set of capabilities, and having it transparently work with | ||
| 153 | /// more capable timers. | ||
| 154 | fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2; | ||
| 155 | |||
| 156 | /// Enable/disable the update dma. | ||
| 157 | fn enable_update_dma(&self, enable: bool) { | ||
| 158 | Self::regs_basic_no_cr2().dier().modify(|r| r.set_ude(enable)); | ||
| 159 | } | ||
| 160 | |||
| 161 | /// Get the update dma enable/disable state. | ||
| 162 | fn get_update_dma_state(&self) -> bool { | ||
| 163 | Self::regs_basic_no_cr2().dier().read().ude() | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | /// Basic 16-bit timer instance. | ||
| 168 | pub trait BasicInstance: BasicNoCr2Instance { | ||
| 169 | /// Get access to the Baisc 16bit timer registers. | ||
| 170 | /// | ||
| 171 | /// Note: This works even if the timer is more capable, because registers | ||
| 172 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 173 | /// for a given set of capabilities, and having it transparently work with | ||
| 174 | /// more capable timers. | ||
| 175 | fn regs_basic() -> crate::pac::timer::TimBasic; | ||
| 176 | } | ||
| 177 | |||
| 178 | /// Gneral-purpose 1 channel 16-bit timer instance. | ||
| 179 | pub trait GeneralPurpose1ChannelInstance: CoreInstance { | ||
| 180 | /// Get access to the general purpose 1 channel 16bit timer registers. | ||
| 181 | /// | ||
| 182 | /// Note: This works even if the timer is more capable, because registers | ||
| 183 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 184 | /// for a given set of capabilities, and having it transparently work with | ||
| 185 | /// more capable timers. | ||
| 186 | fn regs_1ch() -> crate::pac::timer::Tim1ch; | ||
| 187 | |||
| 188 | /// Set clock divider. | ||
| 189 | fn set_clock_division(&self, ckd: vals::Ckd) { | ||
| 190 | Self::regs_1ch().cr1().modify(|r| r.set_ckd(ckd)); | ||
| 191 | } | ||
| 192 | |||
| 193 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. | ||
| 194 | fn get_max_compare_value(&self) -> u16 { | ||
| 195 | Self::regs_1ch().arr().read().arr() | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | /// Gneral-purpose 1 channel 16-bit timer instance. | ||
| 200 | pub trait GeneralPurpose2ChannelInstance: GeneralPurpose1ChannelInstance { | ||
| 201 | /// Get access to the general purpose 2 channel 16bit timer registers. | ||
| 202 | /// | ||
| 203 | /// Note: This works even if the timer is more capable, because registers | ||
| 204 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 205 | /// for a given set of capabilities, and having it transparently work with | ||
| 206 | /// more capable timers. | ||
| 207 | fn regs_2ch() -> crate::pac::timer::Tim2ch; | ||
| 208 | } | ||
| 209 | |||
| 210 | /// Gneral-purpose 16-bit timer instance. | ||
| 211 | pub trait GeneralPurpose16bitInstance: BasicInstance + GeneralPurpose2ChannelInstance { | ||
| 212 | /// Get access to the general purpose 16bit timer registers. | ||
| 213 | /// | ||
| 214 | /// Note: This works even if the timer is more capable, because registers | ||
| 215 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 216 | /// for a given set of capabilities, and having it transparently work with | ||
| 217 | /// more capable timers. | ||
| 218 | fn regs_gp16() -> crate::pac::timer::TimGp16; | ||
| 219 | |||
| 220 | /// Set counting mode. | ||
| 221 | fn set_counting_mode(&self, mode: CountingMode) { | ||
| 222 | let (cms, dir) = mode.into(); | ||
| 223 | |||
| 224 | let timer_enabled = Self::regs_core().cr1().read().cen(); | ||
| 225 | // Changing from edge aligned to center aligned (and vice versa) is not allowed while the timer is running. | ||
| 226 | // Changing direction is discouraged while the timer is running. | ||
| 227 | assert!(!timer_enabled); | ||
| 228 | |||
| 229 | Self::regs_gp16().cr1().modify(|r| r.set_dir(dir)); | ||
| 230 | Self::regs_gp16().cr1().modify(|r| r.set_cms(cms)) | ||
| 231 | } | ||
| 232 | |||
| 233 | /// Get counting mode. | ||
| 234 | fn get_counting_mode(&self) -> CountingMode { | ||
| 235 | let cr1 = Self::regs_gp16().cr1().read(); | ||
| 236 | (cr1.cms(), cr1.dir()).into() | ||
| 237 | } | ||
| 238 | |||
| 239 | /// Set input capture filter. | ||
| 240 | fn set_input_capture_filter(&self, channel: Channel, icf: vals::FilterValue) { | ||
| 241 | let raw_channel = channel.index(); | ||
| 242 | Self::regs_gp16() | ||
| 243 | .ccmr_input(raw_channel / 2) | ||
| 244 | .modify(|r| r.set_icf(raw_channel % 2, icf)); | ||
| 245 | } | ||
| 246 | |||
| 247 | /// Clear input interrupt. | ||
| 248 | fn clear_input_interrupt(&self, channel: Channel) { | ||
| 249 | Self::regs_gp16().sr().modify(|r| r.set_ccif(channel.index(), false)); | ||
| 250 | } | ||
| 251 | |||
| 252 | /// Enable input interrupt. | ||
| 253 | fn enable_input_interrupt(&self, channel: Channel, enable: bool) { | ||
| 254 | Self::regs_gp16().dier().modify(|r| r.set_ccie(channel.index(), enable)); | ||
| 255 | } | ||
| 256 | |||
| 257 | /// Set input capture prescaler. | ||
| 258 | fn set_input_capture_prescaler(&self, channel: Channel, factor: u8) { | ||
| 259 | let raw_channel = channel.index(); | ||
| 260 | Self::regs_gp16() | ||
| 261 | .ccmr_input(raw_channel / 2) | ||
| 262 | .modify(|r| r.set_icpsc(raw_channel % 2, factor)); | ||
| 263 | } | ||
| 264 | |||
| 265 | /// Set input TI selection. | ||
| 266 | fn set_input_ti_selection(&self, channel: Channel, tisel: InputTISelection) { | ||
| 267 | let raw_channel = channel.index(); | ||
| 268 | Self::regs_gp16() | ||
| 269 | .ccmr_input(raw_channel / 2) | ||
| 270 | .modify(|r| r.set_ccs(raw_channel % 2, tisel.into())); | ||
| 271 | } | ||
| 272 | |||
| 273 | /// Set input capture mode. | ||
| 274 | fn set_input_capture_mode(&self, channel: Channel, mode: InputCaptureMode) { | ||
| 275 | Self::regs_gp16().ccer().modify(|r| match mode { | ||
| 276 | InputCaptureMode::Rising => { | ||
| 277 | r.set_ccnp(channel.index(), false); | ||
| 278 | r.set_ccp(channel.index(), false); | ||
| 279 | } | ||
| 280 | InputCaptureMode::Falling => { | ||
| 281 | r.set_ccnp(channel.index(), false); | ||
| 282 | r.set_ccp(channel.index(), true); | ||
| 283 | } | ||
| 284 | InputCaptureMode::BothEdges => { | ||
| 285 | r.set_ccnp(channel.index(), true); | ||
| 286 | r.set_ccp(channel.index(), true); | ||
| 287 | } | ||
| 288 | }); | ||
| 289 | } | ||
| 290 | |||
| 291 | /// Set output compare mode. | ||
| 292 | fn set_output_compare_mode(&self, channel: Channel, mode: OutputCompareMode) { | ||
| 293 | let raw_channel: usize = channel.index(); | ||
| 294 | Self::regs_gp16() | ||
| 295 | .ccmr_output(raw_channel / 2) | ||
| 296 | .modify(|w| w.set_ocm(raw_channel % 2, mode.into())); | ||
| 297 | } | ||
| 298 | |||
| 299 | /// Set output polarity. | ||
| 300 | fn set_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { | ||
| 301 | Self::regs_gp16() | ||
| 302 | .ccer() | ||
| 303 | .modify(|w| w.set_ccp(channel.index(), polarity.into())); | ||
| 304 | } | ||
| 305 | |||
| 306 | /// Enable/disable a channel. | ||
| 307 | fn enable_channel(&self, channel: Channel, enable: bool) { | ||
| 308 | Self::regs_gp16().ccer().modify(|w| w.set_cce(channel.index(), enable)); | ||
| 309 | } | ||
| 310 | |||
| 311 | /// Get enable/disable state of a channel | ||
| 312 | fn get_channel_enable_state(&self, channel: Channel) -> bool { | ||
| 313 | Self::regs_gp16().ccer().read().cce(channel.index()) | ||
| 314 | } | ||
| 315 | |||
| 316 | /// Set compare value for a channel. | ||
| 317 | fn set_compare_value(&self, channel: Channel, value: u16) { | ||
| 318 | Self::regs_gp16().ccr(channel.index()).modify(|w| w.set_ccr(value)); | ||
| 319 | } | ||
| 320 | |||
| 321 | /// Get capture value for a channel. | ||
| 322 | fn get_capture_value(&self, channel: Channel) -> u16 { | ||
| 323 | Self::regs_gp16().ccr(channel.index()).read().ccr() | ||
| 324 | } | ||
| 325 | |||
| 326 | /// Get compare value for a channel. | ||
| 327 | fn get_compare_value(&self, channel: Channel) -> u16 { | ||
| 328 | Self::regs_gp16().ccr(channel.index()).read().ccr() | ||
| 329 | } | ||
| 330 | |||
| 331 | /// Set output compare preload. | ||
| 332 | fn set_output_compare_preload(&self, channel: Channel, preload: bool) { | ||
| 333 | let channel_index = channel.index(); | ||
| 334 | Self::regs_gp16() | ||
| 335 | .ccmr_output(channel_index / 2) | ||
| 336 | .modify(|w| w.set_ocpe(channel_index % 2, preload)); | ||
| 337 | } | ||
| 338 | |||
| 339 | /// Get capture compare DMA selection | ||
| 340 | fn get_cc_dma_selection(&self) -> super::vals::Ccds { | ||
| 341 | Self::regs_gp16().cr2().read().ccds() | ||
| 342 | } | ||
| 343 | |||
| 344 | /// Set capture compare DMA selection | ||
| 345 | fn set_cc_dma_selection(&self, ccds: super::vals::Ccds) { | ||
| 346 | Self::regs_gp16().cr2().modify(|w| w.set_ccds(ccds)) | ||
| 347 | } | ||
| 348 | |||
| 349 | /// Get capture compare DMA enable state | ||
| 350 | fn get_cc_dma_enable_state(&self, channel: Channel) -> bool { | ||
| 351 | Self::regs_gp16().dier().read().ccde(channel.index()) | ||
| 352 | } | ||
| 353 | |||
| 354 | /// Set capture compare DMA enable state | ||
| 355 | fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { | ||
| 356 | Self::regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | #[cfg(not(stm32l0))] | ||
| 361 | /// Gneral-purpose 32-bit timer instance. | ||
| 362 | pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { | ||
| 363 | /// Get access to the general purpose 32bit timer registers. | ||
| 364 | /// | ||
| 365 | /// Note: This works even if the timer is more capable, because registers | ||
| 366 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 367 | /// for a given set of capabilities, and having it transparently work with | ||
| 368 | /// more capable timers. | ||
| 369 | fn regs_gp32() -> crate::pac::timer::TimGp32; | ||
| 370 | |||
| 371 | /// Set timer frequency. | ||
| 372 | fn set_frequency(&self, frequency: Hertz) { | ||
| 373 | let f = frequency.0; | ||
| 374 | assert!(f > 0); | ||
| 375 | let timer_f = Self::frequency().0; | ||
| 376 | let pclk_ticks_per_timer_period = (timer_f / f) as u64; | ||
| 377 | let psc: u16 = unwrap!(((pclk_ticks_per_timer_period - 1) / (1 << 32)).try_into()); | ||
| 378 | let arr: u32 = unwrap!((pclk_ticks_per_timer_period / (psc as u64 + 1)).try_into()); | ||
| 379 | |||
| 380 | let regs = Self::regs_gp32(); | ||
| 381 | regs.psc().write(|r| r.set_psc(psc)); | ||
| 382 | regs.arr().write_value(arr); | ||
| 383 | |||
| 384 | regs.cr1().modify(|r| r.set_urs(vals::Urs::COUNTERONLY)); | ||
| 385 | regs.egr().write(|r| r.set_ug(true)); | ||
| 386 | regs.cr1().modify(|r| r.set_urs(vals::Urs::ANYEVENT)); | ||
| 387 | } | ||
| 388 | |||
| 389 | /// Get timer frequency. | ||
| 390 | fn get_frequency(&self) -> Hertz { | ||
| 391 | let timer_f = Self::frequency(); | ||
| 392 | |||
| 393 | let regs = Self::regs_gp32(); | ||
| 394 | let arr = regs.arr().read(); | ||
| 395 | let psc = regs.psc().read().psc(); | ||
| 396 | |||
| 397 | timer_f / arr / (psc + 1) | ||
| 398 | } | ||
| 399 | |||
| 400 | /// Set comapre value for a channel. | ||
| 401 | fn set_compare_value(&self, channel: Channel, value: u32) { | ||
| 402 | Self::regs_gp32().ccr(channel.index()).write_value(value); | ||
| 403 | } | ||
| 404 | |||
| 405 | /// Get capture value for a channel. | ||
| 406 | fn get_capture_value(&self, channel: Channel) -> u32 { | ||
| 407 | Self::regs_gp32().ccr(channel.index()).read() | ||
| 408 | } | ||
| 409 | |||
| 410 | /// Get max compare value. This depends on the timer frequency and the clock frequency from RCC. | ||
| 411 | fn get_max_compare_value(&self) -> u32 { | ||
| 412 | Self::regs_gp32().arr().read() | ||
| 413 | } | ||
| 414 | |||
| 415 | /// Get compare value for a channel. | ||
| 416 | fn get_compare_value(&self, channel: Channel) -> u32 { | ||
| 417 | Self::regs_gp32().ccr(channel.index()).read() | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | #[cfg(not(stm32l0))] | ||
| 422 | /// Gneral-purpose 1 channel with one complementary 16-bit timer instance. | ||
| 423 | pub trait GeneralPurpose1ChannelComplementaryInstance: BasicNoCr2Instance + GeneralPurpose1ChannelInstance { | ||
| 424 | /// Get access to the general purpose 1 channel with one complementary 16bit timer registers. | ||
| 425 | /// | ||
| 426 | /// Note: This works even if the timer is more capable, because registers | ||
| 427 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 428 | /// for a given set of capabilities, and having it transparently work with | ||
| 429 | /// more capable timers. | ||
| 430 | fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp; | ||
| 431 | |||
| 432 | /// Set clock divider for the dead time. | ||
| 433 | fn set_dead_time_clock_division(&self, value: vals::Ckd) { | ||
| 434 | Self::regs_1ch_cmp().cr1().modify(|w| w.set_ckd(value)); | ||
| 435 | } | ||
| 436 | |||
| 437 | /// Set dead time, as a fraction of the max duty value. | ||
| 438 | fn set_dead_time_value(&self, value: u8) { | ||
| 439 | Self::regs_1ch_cmp().bdtr().modify(|w| w.set_dtg(value)); | ||
| 440 | } | ||
| 441 | |||
| 442 | /// Set state of MOE-bit in BDTR register to en-/disable output | ||
| 443 | fn set_moe(&self, enable: bool) { | ||
| 444 | Self::regs_1ch_cmp().bdtr().modify(|w| w.set_moe(enable)); | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | #[cfg(not(stm32l0))] | ||
| 449 | /// Gneral-purpose 2 channel with one complementary 16-bit timer instance. | ||
| 450 | pub trait GeneralPurpose2ChannelComplementaryInstance: | ||
| 451 | BasicInstance + GeneralPurpose2ChannelInstance + GeneralPurpose1ChannelComplementaryInstance | ||
| 452 | { | ||
| 453 | /// Get access to the general purpose 2 channel with one complementary 16bit timer registers. | ||
| 454 | /// | ||
| 455 | /// Note: This works even if the timer is more capable, because registers | ||
| 456 | /// for the less capable timers are a subset. This allows writing a driver | ||
| 457 | /// for a given set of capabilities, and having it transparently work with | ||
| 458 | /// more capable timers. | ||
| 459 | fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp; | ||
| 460 | } | ||
| 461 | |||
| 462 | #[cfg(not(stm32l0))] | ||
| 463 | /// Advanced control timer instance. | ||
| 464 | pub trait AdvancedControlInstance: | ||
| 465 | GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance | ||
| 466 | { | ||
| 467 | /// Capture compare interrupt for this timer. | ||
| 468 | type CaptureCompareInterrupt: interrupt::typelevel::Interrupt; | ||
| 469 | |||
| 470 | /// Get access to the advanced timer registers. | ||
| 471 | fn regs_advanced() -> crate::pac::timer::TimAdv; | ||
| 472 | |||
| 473 | /// Set complementary output polarity. | ||
| 474 | fn set_complementary_output_polarity(&self, channel: Channel, polarity: OutputPolarity) { | ||
| 475 | Self::regs_advanced() | ||
| 476 | .ccer() | ||
| 477 | .modify(|w| w.set_ccnp(channel.index(), polarity.into())); | ||
| 478 | } | ||
| 479 | |||
| 480 | /// Enable/disable a complementary channel. | ||
| 481 | fn enable_complementary_channel(&self, channel: Channel, enable: bool) { | ||
| 482 | Self::regs_advanced() | ||
| 483 | .ccer() | ||
| 484 | .modify(|w| w.set_ccne(channel.index(), enable)); | ||
| 485 | } | ||
| 486 | } | ||
| 487 | } | ||
| 488 | 11 | ||
| 489 | /// Timer channel. | 12 | /// Timer channel. |
| 490 | #[derive(Clone, Copy)] | 13 | #[derive(Clone, Copy)] |
| @@ -511,181 +34,44 @@ impl Channel { | |||
| 511 | } | 34 | } |
| 512 | } | 35 | } |
| 513 | 36 | ||
| 514 | /// Input capture mode. | 37 | /// Amount of bits of a timer. |
| 515 | #[derive(Clone, Copy)] | 38 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 516 | pub enum InputCaptureMode { | 39 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 517 | /// Rising edge only. | 40 | pub enum TimerBits { |
| 518 | Rising, | 41 | /// 16 bits. |
| 519 | /// Falling edge only. | 42 | Bits16, |
| 520 | Falling, | 43 | /// 32 bits. |
| 521 | /// Both rising or falling edges. | 44 | #[cfg(not(stm32l0))] |
| 522 | BothEdges, | 45 | Bits32, |
| 523 | } | 46 | } |
| 524 | 47 | ||
| 525 | /// Input TI selection. | 48 | /// Core timer instance. |
| 526 | #[derive(Clone, Copy)] | 49 | pub trait CoreInstance: RccPeripheral + 'static { |
| 527 | pub enum InputTISelection { | 50 | /// Interrupt for this timer. |
| 528 | /// Normal | 51 | type Interrupt: interrupt::typelevel::Interrupt; |
| 529 | Normal, | ||
| 530 | /// Alternate | ||
| 531 | Alternate, | ||
| 532 | /// TRC | ||
| 533 | TRC, | ||
| 534 | } | ||
| 535 | 52 | ||
| 536 | impl From<InputTISelection> for stm32_metapac::timer::vals::CcmrInputCcs { | 53 | /// Amount of bits this timer has. |
| 537 | fn from(tisel: InputTISelection) -> Self { | 54 | const BITS: TimerBits; |
| 538 | match tisel { | ||
| 539 | InputTISelection::Normal => stm32_metapac::timer::vals::CcmrInputCcs::TI4, | ||
| 540 | InputTISelection::Alternate => stm32_metapac::timer::vals::CcmrInputCcs::TI3, | ||
| 541 | InputTISelection::TRC => stm32_metapac::timer::vals::CcmrInputCcs::TRC, | ||
| 542 | } | ||
| 543 | } | ||
| 544 | } | ||
| 545 | 55 | ||
| 546 | /// Timer counting mode. | 56 | /// Registers for this timer. |
| 547 | #[repr(u8)] | ||
| 548 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] | ||
| 549 | pub enum CountingMode { | ||
| 550 | #[default] | ||
| 551 | /// The timer counts up to the reload value and then resets back to 0. | ||
| 552 | EdgeAlignedUp, | ||
| 553 | /// The timer counts down to 0 and then resets back to the reload value. | ||
| 554 | EdgeAlignedDown, | ||
| 555 | /// The timer counts up to the reload value and then counts back to 0. | ||
| 556 | /// | 57 | /// |
| 557 | /// The output compare interrupt flags of channels configured in output are | 58 | /// This is a raw pointer to the register block. The actual register block layout varies depending on the timer type. |
| 558 | /// set when the counter is counting down. | 59 | fn regs() -> *mut (); |
| 559 | CenterAlignedDownInterrupts, | ||
| 560 | /// The timer counts up to the reload value and then counts back to 0. | ||
| 561 | /// | ||
| 562 | /// The output compare interrupt flags of channels configured in output are | ||
| 563 | /// set when the counter is counting up. | ||
| 564 | CenterAlignedUpInterrupts, | ||
| 565 | /// The timer counts up to the reload value and then counts back to 0. | ||
| 566 | /// | ||
| 567 | /// The output compare interrupt flags of channels configured in output are | ||
| 568 | /// set when the counter is counting both up or down. | ||
| 569 | CenterAlignedBothInterrupts, | ||
| 570 | } | ||
| 571 | |||
| 572 | impl CountingMode { | ||
| 573 | /// Return whether this mode is edge-aligned (up or down). | ||
| 574 | pub fn is_edge_aligned(&self) -> bool { | ||
| 575 | matches!(self, CountingMode::EdgeAlignedUp | CountingMode::EdgeAlignedDown) | ||
| 576 | } | ||
| 577 | |||
| 578 | /// Return whether this mode is center-aligned. | ||
| 579 | pub fn is_center_aligned(&self) -> bool { | ||
| 580 | matches!( | ||
| 581 | self, | ||
| 582 | CountingMode::CenterAlignedDownInterrupts | ||
| 583 | | CountingMode::CenterAlignedUpInterrupts | ||
| 584 | | CountingMode::CenterAlignedBothInterrupts | ||
| 585 | ) | ||
| 586 | } | ||
| 587 | } | ||
| 588 | |||
| 589 | impl From<CountingMode> for (vals::Cms, vals::Dir) { | ||
| 590 | fn from(value: CountingMode) -> Self { | ||
| 591 | match value { | ||
| 592 | CountingMode::EdgeAlignedUp => (vals::Cms::EDGEALIGNED, vals::Dir::UP), | ||
| 593 | CountingMode::EdgeAlignedDown => (vals::Cms::EDGEALIGNED, vals::Dir::DOWN), | ||
| 594 | CountingMode::CenterAlignedDownInterrupts => (vals::Cms::CENTERALIGNED1, vals::Dir::UP), | ||
| 595 | CountingMode::CenterAlignedUpInterrupts => (vals::Cms::CENTERALIGNED2, vals::Dir::UP), | ||
| 596 | CountingMode::CenterAlignedBothInterrupts => (vals::Cms::CENTERALIGNED3, vals::Dir::UP), | ||
| 597 | } | ||
| 598 | } | ||
| 599 | } | ||
| 600 | |||
| 601 | impl From<(vals::Cms, vals::Dir)> for CountingMode { | ||
| 602 | fn from(value: (vals::Cms, vals::Dir)) -> Self { | ||
| 603 | match value { | ||
| 604 | (vals::Cms::EDGEALIGNED, vals::Dir::UP) => CountingMode::EdgeAlignedUp, | ||
| 605 | (vals::Cms::EDGEALIGNED, vals::Dir::DOWN) => CountingMode::EdgeAlignedDown, | ||
| 606 | (vals::Cms::CENTERALIGNED1, _) => CountingMode::CenterAlignedDownInterrupts, | ||
| 607 | (vals::Cms::CENTERALIGNED2, _) => CountingMode::CenterAlignedUpInterrupts, | ||
| 608 | (vals::Cms::CENTERALIGNED3, _) => CountingMode::CenterAlignedBothInterrupts, | ||
| 609 | } | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | /// Output compare mode. | ||
| 614 | #[derive(Clone, Copy)] | ||
| 615 | pub enum OutputCompareMode { | ||
| 616 | /// The comparison between the output compare register TIMx_CCRx and | ||
| 617 | /// the counter TIMx_CNT has no effect on the outputs. | ||
| 618 | /// (this mode is used to generate a timing base). | ||
| 619 | Frozen, | ||
| 620 | /// Set channel to active level on match. OCxREF signal is forced high when the | ||
| 621 | /// counter TIMx_CNT matches the capture/compare register x (TIMx_CCRx). | ||
| 622 | ActiveOnMatch, | ||
| 623 | /// Set channel to inactive level on match. OCxREF signal is forced low when the | ||
| 624 | /// counter TIMx_CNT matches the capture/compare register x (TIMx_CCRx). | ||
| 625 | InactiveOnMatch, | ||
| 626 | /// Toggle - OCxREF toggles when TIMx_CNT=TIMx_CCRx. | ||
| 627 | Toggle, | ||
| 628 | /// Force inactive level - OCxREF is forced low. | ||
| 629 | ForceInactive, | ||
| 630 | /// Force active level - OCxREF is forced high. | ||
| 631 | ForceActive, | ||
| 632 | /// PWM mode 1 - In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRx | ||
| 633 | /// else inactive. In downcounting, channel is inactive (OCxREF=0) as long as | ||
| 634 | /// TIMx_CNT>TIMx_CCRx else active (OCxREF=1). | ||
| 635 | PwmMode1, | ||
| 636 | /// PWM mode 2 - In upcounting, channel is inactive as long as | ||
| 637 | /// TIMx_CNT<TIMx_CCRx else active. In downcounting, channel is active as long as | ||
| 638 | /// TIMx_CNT>TIMx_CCRx else inactive. | ||
| 639 | PwmMode2, | ||
| 640 | // TODO: there's more modes here depending on the chip family. | ||
| 641 | } | ||
| 642 | |||
| 643 | impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm { | ||
| 644 | fn from(mode: OutputCompareMode) -> Self { | ||
| 645 | match mode { | ||
| 646 | OutputCompareMode::Frozen => stm32_metapac::timer::vals::Ocm::FROZEN, | ||
| 647 | OutputCompareMode::ActiveOnMatch => stm32_metapac::timer::vals::Ocm::ACTIVEONMATCH, | ||
| 648 | OutputCompareMode::InactiveOnMatch => stm32_metapac::timer::vals::Ocm::INACTIVEONMATCH, | ||
| 649 | OutputCompareMode::Toggle => stm32_metapac::timer::vals::Ocm::TOGGLE, | ||
| 650 | OutputCompareMode::ForceInactive => stm32_metapac::timer::vals::Ocm::FORCEINACTIVE, | ||
| 651 | OutputCompareMode::ForceActive => stm32_metapac::timer::vals::Ocm::FORCEACTIVE, | ||
| 652 | OutputCompareMode::PwmMode1 => stm32_metapac::timer::vals::Ocm::PWMMODE1, | ||
| 653 | OutputCompareMode::PwmMode2 => stm32_metapac::timer::vals::Ocm::PWMMODE2, | ||
| 654 | } | ||
| 655 | } | ||
| 656 | } | 60 | } |
| 61 | /// Cut-down basic timer instance. | ||
| 62 | pub trait BasicNoCr2Instance: CoreInstance {} | ||
| 63 | /// Basic timer instance. | ||
| 64 | pub trait BasicInstance: BasicNoCr2Instance {} | ||
| 657 | 65 | ||
| 658 | /// Timer output pin polarity. | 66 | /// General-purpose 16-bit timer with 1 channel instance. |
| 659 | #[derive(Clone, Copy)] | 67 | pub trait GeneralInstance1Channel: CoreInstance {} |
| 660 | pub enum OutputPolarity { | ||
| 661 | /// Active high (higher duty value makes the pin spend more time high). | ||
| 662 | ActiveHigh, | ||
| 663 | /// Active low (higher duty value makes the pin spend more time low). | ||
| 664 | ActiveLow, | ||
| 665 | } | ||
| 666 | 68 | ||
| 667 | impl From<OutputPolarity> for bool { | 69 | /// General-purpose 16-bit timer with 2 channels instance. |
| 668 | fn from(mode: OutputPolarity) -> Self { | 70 | pub trait GeneralInstance2Channel: GeneralInstance1Channel {} |
| 669 | match mode { | ||
| 670 | OutputPolarity::ActiveHigh => false, | ||
| 671 | OutputPolarity::ActiveLow => true, | ||
| 672 | } | ||
| 673 | } | ||
| 674 | } | ||
| 675 | 71 | ||
| 676 | /// Basic 16-bit timer instance. | 72 | /// General-purpose 16-bit timer with 4 channels instance. |
| 677 | pub trait BasicInstance: sealed::BasicInstance + sealed::BasicNoCr2Instance + sealed::CoreInstance + 'static {} | 73 | pub trait GeneralInstance4Channel: BasicInstance + GeneralInstance2Channel { |
| 678 | 74 | // SimplePwm<'d, T> is implemented for T: GeneralInstance4Channel | |
| 679 | // It's just a General-purpose 16-bit timer instance. | ||
| 680 | /// Capture Compare timer instance. | ||
| 681 | pub trait CaptureCompare16bitInstance: | ||
| 682 | BasicInstance | ||
| 683 | + sealed::GeneralPurpose2ChannelInstance | ||
| 684 | + sealed::GeneralPurpose1ChannelInstance | ||
| 685 | + sealed::GeneralPurpose16bitInstance | ||
| 686 | + 'static | ||
| 687 | { | ||
| 688 | // SimplePwm<'d, T> is implemented for T: CaptureCompare16bitInstance | ||
| 689 | // Advanced timers implement this trait, but the output needs to be | 75 | // Advanced timers implement this trait, but the output needs to be |
| 690 | // enabled explicitly. | 76 | // enabled explicitly. |
| 691 | // To support general-purpose and advanced timers, this function is added | 77 | // To support general-purpose and advanced timers, this function is added |
| @@ -694,296 +80,149 @@ pub trait CaptureCompare16bitInstance: | |||
| 694 | fn enable_outputs(&self) {} | 80 | fn enable_outputs(&self) {} |
| 695 | } | 81 | } |
| 696 | 82 | ||
| 697 | #[cfg(not(stm32l0))] | 83 | /// General-purpose 32-bit timer with 4 channels instance. |
| 698 | // It's just a General-purpose 32-bit timer instance. | 84 | pub trait GeneralInstance32bit4Channel: GeneralInstance4Channel {} |
| 699 | /// Capture Compare 32-bit timer instance. | ||
| 700 | pub trait CaptureCompare32bitInstance: | ||
| 701 | CaptureCompare16bitInstance + sealed::GeneralPurpose32bitInstance + 'static | ||
| 702 | { | ||
| 703 | } | ||
| 704 | |||
| 705 | #[cfg(not(stm32l0))] | ||
| 706 | // It's just a Advanced Control timer instance. | ||
| 707 | /// Complementary Capture Compare 32-bit timer instance. | ||
| 708 | pub trait ComplementaryCaptureCompare16bitInstance: | ||
| 709 | CaptureCompare16bitInstance | ||
| 710 | + sealed::GeneralPurpose1ChannelComplementaryInstance | ||
| 711 | + sealed::GeneralPurpose2ChannelComplementaryInstance | ||
| 712 | + sealed::AdvancedControlInstance | ||
| 713 | + 'static | ||
| 714 | { | ||
| 715 | } | ||
| 716 | |||
| 717 | pin_trait!(Channel1Pin, CaptureCompare16bitInstance); | ||
| 718 | pin_trait!(Channel2Pin, CaptureCompare16bitInstance); | ||
| 719 | pin_trait!(Channel3Pin, CaptureCompare16bitInstance); | ||
| 720 | pin_trait!(Channel4Pin, CaptureCompare16bitInstance); | ||
| 721 | pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance); | ||
| 722 | |||
| 723 | cfg_if::cfg_if! { | ||
| 724 | if #[cfg(not(stm32l0))] { | ||
| 725 | pin_trait!(Channel1ComplementaryPin, ComplementaryCaptureCompare16bitInstance); | ||
| 726 | pin_trait!(Channel2ComplementaryPin, ComplementaryCaptureCompare16bitInstance); | ||
| 727 | pin_trait!(Channel3ComplementaryPin, ComplementaryCaptureCompare16bitInstance); | ||
| 728 | pin_trait!(Channel4ComplementaryPin, ComplementaryCaptureCompare16bitInstance); | ||
| 729 | |||
| 730 | pin_trait!(BreakInputPin, ComplementaryCaptureCompare16bitInstance); | ||
| 731 | pin_trait!(BreakInput2Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 732 | 85 | ||
| 733 | pin_trait!(BreakInputComparator1Pin, ComplementaryCaptureCompare16bitInstance); | 86 | /// Advanced 16-bit timer with 1 channel instance. |
| 734 | pin_trait!(BreakInputComparator2Pin, ComplementaryCaptureCompare16bitInstance); | 87 | pub trait AdvancedInstance1Channel: BasicNoCr2Instance + GeneralInstance1Channel { |
| 735 | 88 | /// Capture compare interrupt for this timer. | |
| 736 | pin_trait!(BreakInput2Comparator1Pin, ComplementaryCaptureCompare16bitInstance); | 89 | type CaptureCompareInterrupt: interrupt::typelevel::Interrupt; |
| 737 | pin_trait!(BreakInput2Comparator2Pin, ComplementaryCaptureCompare16bitInstance); | ||
| 738 | } | ||
| 739 | } | 90 | } |
| 91 | /// Advanced 16-bit timer with 2 channels instance. | ||
| 740 | 92 | ||
| 741 | #[allow(unused)] | 93 | pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + AdvancedInstance1Channel {} |
| 742 | macro_rules! impl_core_timer { | ||
| 743 | ($inst:ident, $irq:ident) => { | ||
| 744 | impl sealed::CoreInstance for crate::peripherals::$inst { | ||
| 745 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 746 | 94 | ||
| 747 | fn regs_core() -> crate::pac::timer::TimCore { | 95 | /// Advanced 16-bit timer with 4 channels instance. |
| 748 | unsafe { crate::pac::timer::TimCore::from_ptr(crate::pac::$inst.as_ptr()) } | 96 | pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} |
| 749 | } | ||
| 750 | } | ||
| 751 | }; | ||
| 752 | } | ||
| 753 | 97 | ||
| 754 | #[allow(unused)] | 98 | pin_trait!(Channel1Pin, GeneralInstance4Channel); |
| 755 | macro_rules! impl_basic_no_cr2_timer { | 99 | pin_trait!(Channel2Pin, GeneralInstance4Channel); |
| 756 | ($inst:ident) => { | 100 | pin_trait!(Channel3Pin, GeneralInstance4Channel); |
| 757 | impl sealed::BasicNoCr2Instance for crate::peripherals::$inst { | 101 | pin_trait!(Channel4Pin, GeneralInstance4Channel); |
| 758 | fn regs_basic_no_cr2() -> crate::pac::timer::TimBasicNoCr2 { | 102 | pin_trait!(ExternalTriggerPin, GeneralInstance4Channel); |
| 759 | unsafe { crate::pac::timer::TimBasicNoCr2::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 760 | } | ||
| 761 | } | ||
| 762 | }; | ||
| 763 | } | ||
| 764 | 103 | ||
| 765 | #[allow(unused)] | 104 | pin_trait!(Channel1ComplementaryPin, AdvancedInstance4Channel); |
| 766 | macro_rules! impl_basic_timer { | 105 | pin_trait!(Channel2ComplementaryPin, AdvancedInstance4Channel); |
| 767 | ($inst:ident) => { | 106 | pin_trait!(Channel3ComplementaryPin, AdvancedInstance4Channel); |
| 768 | impl sealed::BasicInstance for crate::peripherals::$inst { | 107 | pin_trait!(Channel4ComplementaryPin, AdvancedInstance4Channel); |
| 769 | fn regs_basic() -> crate::pac::timer::TimBasic { | ||
| 770 | unsafe { crate::pac::timer::TimBasic::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 771 | } | ||
| 772 | } | ||
| 773 | }; | ||
| 774 | } | ||
| 775 | 108 | ||
| 776 | #[allow(unused)] | 109 | pin_trait!(BreakInputPin, AdvancedInstance4Channel); |
| 777 | macro_rules! impl_1ch_timer { | 110 | pin_trait!(BreakInput2Pin, AdvancedInstance4Channel); |
| 778 | ($inst:ident) => { | ||
| 779 | impl sealed::GeneralPurpose1ChannelInstance for crate::peripherals::$inst { | ||
| 780 | fn regs_1ch() -> crate::pac::timer::Tim1ch { | ||
| 781 | unsafe { crate::pac::timer::Tim1ch::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 782 | } | ||
| 783 | } | ||
| 784 | }; | ||
| 785 | } | ||
| 786 | 111 | ||
| 787 | #[allow(unused)] | 112 | pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel); |
| 788 | macro_rules! impl_2ch_timer { | 113 | pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel); |
| 789 | ($inst:ident) => { | ||
| 790 | impl sealed::GeneralPurpose2ChannelInstance for crate::peripherals::$inst { | ||
| 791 | fn regs_2ch() -> crate::pac::timer::Tim2ch { | ||
| 792 | unsafe { crate::pac::timer::Tim2ch::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 793 | } | ||
| 794 | } | ||
| 795 | }; | ||
| 796 | } | ||
| 797 | 114 | ||
| 798 | #[allow(unused)] | 115 | pin_trait!(BreakInput2Comparator1Pin, AdvancedInstance4Channel); |
| 799 | macro_rules! impl_gp16_timer { | 116 | pin_trait!(BreakInput2Comparator2Pin, AdvancedInstance4Channel); |
| 800 | ($inst:ident) => { | ||
| 801 | impl sealed::GeneralPurpose16bitInstance for crate::peripherals::$inst { | ||
| 802 | fn regs_gp16() -> crate::pac::timer::TimGp16 { | ||
| 803 | unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 804 | } | ||
| 805 | } | ||
| 806 | }; | ||
| 807 | } | ||
| 808 | 117 | ||
| 809 | #[allow(unused)] | 118 | // Update Event trigger DMA for every timer |
| 810 | macro_rules! impl_gp32_timer { | 119 | dma_trait!(UpDma, BasicInstance); |
| 811 | ($inst:ident) => { | ||
| 812 | impl sealed::GeneralPurpose32bitInstance for crate::peripherals::$inst { | ||
| 813 | fn regs_gp32() -> crate::pac::timer::TimGp32 { | ||
| 814 | crate::pac::$inst | ||
| 815 | } | ||
| 816 | } | ||
| 817 | }; | ||
| 818 | } | ||
| 819 | 120 | ||
| 820 | #[allow(unused)] | 121 | dma_trait!(Ch1Dma, GeneralInstance4Channel); |
| 821 | macro_rules! impl_1ch_cmp_timer { | 122 | dma_trait!(Ch2Dma, GeneralInstance4Channel); |
| 822 | ($inst:ident) => { | 123 | dma_trait!(Ch3Dma, GeneralInstance4Channel); |
| 823 | impl sealed::GeneralPurpose1ChannelComplementaryInstance for crate::peripherals::$inst { | 124 | dma_trait!(Ch4Dma, GeneralInstance4Channel); |
| 824 | fn regs_1ch_cmp() -> crate::pac::timer::Tim1chCmp { | ||
| 825 | unsafe { crate::pac::timer::Tim1chCmp::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 826 | } | ||
| 827 | } | ||
| 828 | }; | ||
| 829 | } | ||
| 830 | 125 | ||
| 831 | #[allow(unused)] | 126 | #[allow(unused)] |
| 832 | macro_rules! impl_2ch_cmp_timer { | 127 | macro_rules! impl_core_timer { |
| 833 | ($inst:ident) => { | 128 | ($inst:ident, $bits:expr) => { |
| 834 | impl sealed::GeneralPurpose2ChannelComplementaryInstance for crate::peripherals::$inst { | 129 | impl CoreInstance for crate::peripherals::$inst { |
| 835 | fn regs_2ch_cmp() -> crate::pac::timer::Tim2chCmp { | 130 | type Interrupt = crate::_generated::peripheral_interrupts::$inst::UP; |
| 836 | unsafe { crate::pac::timer::Tim2chCmp::from_ptr(crate::pac::$inst.as_ptr()) } | ||
| 837 | } | ||
| 838 | } | ||
| 839 | }; | ||
| 840 | } | ||
| 841 | 131 | ||
| 842 | #[allow(unused)] | 132 | const BITS: TimerBits = $bits; |
| 843 | macro_rules! impl_adv_timer { | ||
| 844 | ($inst:ident, $irq:ident) => { | ||
| 845 | impl sealed::AdvancedControlInstance for crate::peripherals::$inst { | ||
| 846 | type CaptureCompareInterrupt = crate::interrupt::typelevel::$irq; | ||
| 847 | 133 | ||
| 848 | fn regs_advanced() -> crate::pac::timer::TimAdv { | 134 | fn regs() -> *mut () { |
| 849 | unsafe { crate::pac::timer::TimAdv::from_ptr(crate::pac::$inst.as_ptr()) } | 135 | crate::pac::$inst.as_ptr() |
| 850 | } | 136 | } |
| 851 | } | 137 | } |
| 852 | }; | 138 | }; |
| 853 | } | 139 | } |
| 854 | 140 | ||
| 855 | foreach_interrupt! { | 141 | foreach_interrupt! { |
| 856 | |||
| 857 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { | 142 | ($inst:ident, timer, TIM_BASIC, UP, $irq:ident) => { |
| 858 | impl_core_timer!($inst, $irq); | 143 | impl_core_timer!($inst, TimerBits::Bits16); |
| 859 | impl_basic_no_cr2_timer!($inst); | 144 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 860 | impl_basic_timer!($inst); | ||
| 861 | impl BasicInstance for crate::peripherals::$inst {} | 145 | impl BasicInstance for crate::peripherals::$inst {} |
| 862 | }; | 146 | }; |
| 863 | 147 | ||
| 864 | ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { | 148 | ($inst:ident, timer, TIM_1CH, UP, $irq:ident) => { |
| 865 | impl_core_timer!($inst, $irq); | 149 | impl_core_timer!($inst, TimerBits::Bits16); |
| 866 | impl_basic_no_cr2_timer!($inst); | 150 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 867 | impl_basic_timer!($inst); | ||
| 868 | impl_1ch_timer!($inst); | ||
| 869 | impl_2ch_timer!($inst); | ||
| 870 | impl_gp16_timer!($inst); | ||
| 871 | impl BasicInstance for crate::peripherals::$inst {} | 151 | impl BasicInstance for crate::peripherals::$inst {} |
| 872 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 152 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 153 | impl GeneralInstance2Channel for crate::peripherals::$inst {} | ||
| 154 | impl GeneralInstance4Channel for crate::peripherals::$inst {} | ||
| 873 | }; | 155 | }; |
| 874 | 156 | ||
| 875 | |||
| 876 | ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { | 157 | ($inst:ident, timer, TIM_2CH, UP, $irq:ident) => { |
| 877 | impl_core_timer!($inst, $irq); | 158 | impl_core_timer!($inst, TimerBits::Bits16); |
| 878 | impl_basic_no_cr2_timer!($inst); | 159 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 879 | impl_basic_timer!($inst); | ||
| 880 | impl_1ch_timer!($inst); | ||
| 881 | impl_2ch_timer!($inst); | ||
| 882 | impl_gp16_timer!($inst); | ||
| 883 | impl BasicInstance for crate::peripherals::$inst {} | 160 | impl BasicInstance for crate::peripherals::$inst {} |
| 884 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 161 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 162 | impl GeneralInstance2Channel for crate::peripherals::$inst {} | ||
| 163 | impl GeneralInstance4Channel for crate::peripherals::$inst {} | ||
| 885 | }; | 164 | }; |
| 886 | 165 | ||
| 887 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { | 166 | ($inst:ident, timer, TIM_GP16, UP, $irq:ident) => { |
| 888 | impl_core_timer!($inst, $irq); | 167 | impl_core_timer!($inst, TimerBits::Bits16); |
| 889 | impl_basic_no_cr2_timer!($inst); | 168 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 890 | impl_basic_timer!($inst); | ||
| 891 | impl_1ch_timer!($inst); | ||
| 892 | impl_2ch_timer!($inst); | ||
| 893 | impl_gp16_timer!($inst); | ||
| 894 | impl BasicInstance for crate::peripherals::$inst {} | 169 | impl BasicInstance for crate::peripherals::$inst {} |
| 895 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 170 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 171 | impl GeneralInstance2Channel for crate::peripherals::$inst {} | ||
| 172 | impl GeneralInstance4Channel for crate::peripherals::$inst {} | ||
| 896 | }; | 173 | }; |
| 897 | 174 | ||
| 898 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { | 175 | ($inst:ident, timer, TIM_GP32, UP, $irq:ident) => { |
| 899 | impl_core_timer!($inst, $irq); | 176 | impl_core_timer!($inst, TimerBits::Bits32); |
| 900 | impl_basic_no_cr2_timer!($inst); | 177 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 901 | impl_basic_timer!($inst); | ||
| 902 | impl_1ch_timer!($inst); | ||
| 903 | impl_2ch_timer!($inst); | ||
| 904 | impl_gp16_timer!($inst); | ||
| 905 | impl_gp32_timer!($inst); | ||
| 906 | impl BasicInstance for crate::peripherals::$inst {} | 178 | impl BasicInstance for crate::peripherals::$inst {} |
| 907 | impl CaptureCompare16bitInstance for crate::peripherals::$inst {} | 179 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 908 | impl CaptureCompare32bitInstance for crate::peripherals::$inst {} | 180 | impl GeneralInstance2Channel for crate::peripherals::$inst {} |
| 181 | impl GeneralInstance4Channel for crate::peripherals::$inst {} | ||
| 182 | impl GeneralInstance32bit4Channel for crate::peripherals::$inst {} | ||
| 909 | }; | 183 | }; |
| 910 | 184 | ||
| 911 | ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { | 185 | ($inst:ident, timer, TIM_1CH_CMP, UP, $irq:ident) => { |
| 912 | impl_core_timer!($inst, $irq); | 186 | impl_core_timer!($inst, TimerBits::Bits16); |
| 913 | impl_basic_no_cr2_timer!($inst); | 187 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 914 | impl_basic_timer!($inst); | ||
| 915 | impl_1ch_timer!($inst); | ||
| 916 | impl_2ch_timer!($inst); | ||
| 917 | impl_gp16_timer!($inst); | ||
| 918 | impl_1ch_cmp_timer!($inst); | ||
| 919 | impl_2ch_cmp_timer!($inst); | ||
| 920 | impl BasicInstance for crate::peripherals::$inst {} | 188 | impl BasicInstance for crate::peripherals::$inst {} |
| 921 | impl CaptureCompare16bitInstance for crate::peripherals::$inst { | 189 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 922 | /// Enable timer outputs. | 190 | impl GeneralInstance2Channel for crate::peripherals::$inst {} |
| 923 | fn enable_outputs(&self) { | 191 | impl GeneralInstance4Channel for crate::peripherals::$inst { fn enable_outputs(&self) { set_moe::<Self>() }} |
| 924 | use crate::timer::sealed::GeneralPurpose1ChannelComplementaryInstance; | 192 | impl AdvancedInstance1Channel for crate::peripherals::$inst { type CaptureCompareInterrupt = crate::_generated::peripheral_interrupts::$inst::CC; } |
| 925 | self.set_moe(true); | 193 | impl AdvancedInstance2Channel for crate::peripherals::$inst {} |
| 926 | } | 194 | impl AdvancedInstance4Channel for crate::peripherals::$inst {} |
| 927 | } | ||
| 928 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 929 | }; | ||
| 930 | ($inst:ident, timer, TIM_1CH_CMP, CC, $irq:ident) => { | ||
| 931 | impl_adv_timer!($inst, $irq); | ||
| 932 | }; | 195 | }; |
| 933 | 196 | ||
| 934 | |||
| 935 | ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => { | 197 | ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => { |
| 936 | impl_core_timer!($inst, $irq); | 198 | impl_core_timer!($inst, TimerBits::Bits16); |
| 937 | impl_basic_no_cr2_timer!($inst); | 199 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 938 | impl_basic_timer!($inst); | ||
| 939 | impl_1ch_timer!($inst); | ||
| 940 | impl_2ch_timer!($inst); | ||
| 941 | impl_gp16_timer!($inst); | ||
| 942 | impl_1ch_cmp_timer!($inst); | ||
| 943 | impl_2ch_cmp_timer!($inst); | ||
| 944 | impl BasicInstance for crate::peripherals::$inst {} | 200 | impl BasicInstance for crate::peripherals::$inst {} |
| 945 | impl CaptureCompare16bitInstance for crate::peripherals::$inst { | 201 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 946 | /// Enable timer outputs. | 202 | impl GeneralInstance2Channel for crate::peripherals::$inst {} |
| 947 | fn enable_outputs(&self) { | 203 | impl GeneralInstance4Channel for crate::peripherals::$inst { fn enable_outputs(&self) { set_moe::<Self>() }} |
| 948 | use crate::timer::sealed::GeneralPurpose1ChannelComplementaryInstance; | 204 | impl AdvancedInstance1Channel for crate::peripherals::$inst { type CaptureCompareInterrupt = crate::_generated::peripheral_interrupts::$inst::CC; } |
| 949 | self.set_moe(true); | 205 | impl AdvancedInstance2Channel for crate::peripherals::$inst {} |
| 950 | } | 206 | impl AdvancedInstance4Channel for crate::peripherals::$inst {} |
| 951 | } | ||
| 952 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 953 | }; | ||
| 954 | ($inst:ident, timer, TIM_2CH_CMP, CC, $irq:ident) => { | ||
| 955 | impl_adv_timer!($inst, $irq); | ||
| 956 | }; | 207 | }; |
| 957 | 208 | ||
| 958 | |||
| 959 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { | 209 | ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { |
| 960 | impl_core_timer!($inst, $irq); | 210 | impl_core_timer!($inst, TimerBits::Bits16); |
| 961 | impl_basic_no_cr2_timer!($inst); | 211 | impl BasicNoCr2Instance for crate::peripherals::$inst {} |
| 962 | impl_basic_timer!($inst); | ||
| 963 | impl_1ch_timer!($inst); | ||
| 964 | impl_2ch_timer!($inst); | ||
| 965 | impl_gp16_timer!($inst); | ||
| 966 | impl_1ch_cmp_timer!($inst); | ||
| 967 | impl_2ch_cmp_timer!($inst); | ||
| 968 | impl BasicInstance for crate::peripherals::$inst {} | 212 | impl BasicInstance for crate::peripherals::$inst {} |
| 969 | impl CaptureCompare16bitInstance for crate::peripherals::$inst { | 213 | impl GeneralInstance1Channel for crate::peripherals::$inst {} |
| 970 | /// Enable timer outputs. | 214 | impl GeneralInstance2Channel for crate::peripherals::$inst {} |
| 971 | fn enable_outputs(&self) { | 215 | impl GeneralInstance4Channel for crate::peripherals::$inst { fn enable_outputs(&self) { set_moe::<Self>() }} |
| 972 | use crate::timer::sealed::GeneralPurpose1ChannelComplementaryInstance; | 216 | impl AdvancedInstance1Channel for crate::peripherals::$inst { type CaptureCompareInterrupt = crate::_generated::peripheral_interrupts::$inst::CC; } |
| 973 | self.set_moe(true); | 217 | impl AdvancedInstance2Channel for crate::peripherals::$inst {} |
| 974 | } | 218 | impl AdvancedInstance4Channel for crate::peripherals::$inst {} |
| 975 | } | ||
| 976 | impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} | ||
| 977 | }; | ||
| 978 | ($inst:ident, timer, TIM_ADV, CC, $irq:ident) => { | ||
| 979 | impl_adv_timer!($inst, $irq); | ||
| 980 | }; | 219 | }; |
| 981 | } | 220 | } |
| 982 | 221 | ||
| 983 | // Update Event trigger DMA for every timer | 222 | #[cfg(not(stm32l0))] |
| 984 | dma_trait!(UpDma, BasicInstance); | 223 | #[allow(unused)] |
| 985 | 224 | fn set_moe<T: GeneralInstance4Channel>() { | |
| 986 | dma_trait!(Ch1Dma, CaptureCompare16bitInstance); | 225 | unsafe { crate::pac::timer::Tim1chCmp::from_ptr(T::regs()) } |
| 987 | dma_trait!(Ch2Dma, CaptureCompare16bitInstance); | 226 | .bdtr() |
| 988 | dma_trait!(Ch3Dma, CaptureCompare16bitInstance); | 227 | .modify(|w| w.set_moe(true)); |
| 989 | dma_trait!(Ch4Dma, CaptureCompare16bitInstance); | 228 | } |
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 59efb72ba..ab9879be6 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs | |||
| @@ -3,10 +3,11 @@ | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | 4 | ||
| 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | use stm32_metapac::timer::vals; | ||
| 6 | 7 | ||
| 7 | use super::*; | 8 | use super::low_level::Timer; |
| 8 | use crate::gpio::sealed::AFType; | 9 | use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; |
| 9 | use crate::gpio::AnyPin; | 10 | use crate::gpio::{AFType, AnyPin}; |
| 10 | use crate::Peripheral; | 11 | use crate::Peripheral; |
| 11 | 12 | ||
| 12 | /// Counting direction | 13 | /// Counting direction |
| @@ -30,7 +31,7 @@ pub struct QeiPin<'d, T, Channel> { | |||
| 30 | 31 | ||
| 31 | macro_rules! channel_impl { | 32 | macro_rules! channel_impl { |
| 32 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 33 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 33 | impl<'d, T: CaptureCompare16bitInstance> QeiPin<'d, T, $channel> { | 34 | impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { |
| 34 | #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] | 35 | #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] |
| 35 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { | 36 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { |
| 36 | into_ref!(pin); | 37 | into_ref!(pin); |
| @@ -53,29 +54,28 @@ channel_impl!(new_ch1, Ch1, Channel1Pin); | |||
| 53 | channel_impl!(new_ch2, Ch2, Channel2Pin); | 54 | channel_impl!(new_ch2, Ch2, Channel2Pin); |
| 54 | 55 | ||
| 55 | /// Quadrature decoder driver. | 56 | /// Quadrature decoder driver. |
| 56 | pub struct Qei<'d, T> { | 57 | pub struct Qei<'d, T: GeneralInstance4Channel> { |
| 57 | _inner: PeripheralRef<'d, T>, | 58 | inner: Timer<'d, T>, |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { | 61 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { |
| 61 | /// Create a new quadrature decoder driver. | 62 | /// Create a new quadrature decoder driver. |
| 62 | pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { | 63 | pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { |
| 63 | Self::new_inner(tim) | 64 | Self::new_inner(tim) |
| 64 | } | 65 | } |
| 65 | 66 | ||
| 66 | fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { | 67 | fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { |
| 67 | into_ref!(tim); | 68 | let inner = Timer::new(tim); |
| 68 | 69 | let r = inner.regs_gp16(); | |
| 69 | T::enable_and_reset(); | ||
| 70 | 70 | ||
| 71 | // Configure TxC1 and TxC2 as captures | 71 | // Configure TxC1 and TxC2 as captures |
| 72 | T::regs_gp16().ccmr_input(0).modify(|w| { | 72 | r.ccmr_input(0).modify(|w| { |
| 73 | w.set_ccs(0, vals::CcmrInputCcs::TI4); | 73 | w.set_ccs(0, vals::CcmrInputCcs::TI4); |
| 74 | w.set_ccs(1, vals::CcmrInputCcs::TI4); | 74 | w.set_ccs(1, vals::CcmrInputCcs::TI4); |
| 75 | }); | 75 | }); |
| 76 | 76 | ||
| 77 | // enable and configure to capture on rising edge | 77 | // enable and configure to capture on rising edge |
| 78 | T::regs_gp16().ccer().modify(|w| { | 78 | r.ccer().modify(|w| { |
| 79 | w.set_cce(0, true); | 79 | w.set_cce(0, true); |
| 80 | w.set_cce(1, true); | 80 | w.set_cce(1, true); |
| 81 | 81 | ||
| @@ -83,19 +83,19 @@ impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { | |||
| 83 | w.set_ccp(1, false); | 83 | w.set_ccp(1, false); |
| 84 | }); | 84 | }); |
| 85 | 85 | ||
| 86 | T::regs_gp16().smcr().modify(|w| { | 86 | r.smcr().modify(|w| { |
| 87 | w.set_sms(vals::Sms::ENCODER_MODE_3); | 87 | w.set_sms(vals::Sms::ENCODER_MODE_3); |
| 88 | }); | 88 | }); |
| 89 | 89 | ||
| 90 | T::regs_gp16().arr().modify(|w| w.set_arr(u16::MAX)); | 90 | r.arr().modify(|w| w.set_arr(u16::MAX)); |
| 91 | T::regs_gp16().cr1().modify(|w| w.set_cen(true)); | 91 | r.cr1().modify(|w| w.set_cen(true)); |
| 92 | 92 | ||
| 93 | Self { _inner: tim } | 93 | Self { inner } |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | /// Get direction. | 96 | /// Get direction. |
| 97 | pub fn read_direction(&self) -> Direction { | 97 | pub fn read_direction(&self) -> Direction { |
| 98 | match T::regs_gp16().cr1().read().dir() { | 98 | match self.inner.regs_gp16().cr1().read().dir() { |
| 99 | vals::Dir::DOWN => Direction::Downcounting, | 99 | vals::Dir::DOWN => Direction::Downcounting, |
| 100 | vals::Dir::UP => Direction::Upcounting, | 100 | vals::Dir::UP => Direction::Upcounting, |
| 101 | } | 101 | } |
| @@ -103,6 +103,6 @@ impl<'d, T: CaptureCompare16bitInstance> Qei<'d, T> { | |||
| 103 | 103 | ||
| 104 | /// Get count. | 104 | /// Get count. |
| 105 | pub fn count(&self) -> u16 { | 105 | pub fn count(&self) -> u16 { |
| 106 | T::regs_gp16().cnt().read().cnt() | 106 | self.inner.regs_gp16().cnt().read().cnt() |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 6df2f66ec..b54e9a0d6 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -4,9 +4,8 @@ use core::marker::PhantomData; | |||
| 4 | 4 | ||
| 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 6 | 6 | ||
| 7 | use super::*; | 7 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; |
| 8 | #[allow(unused_imports)] | 8 | use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel}; |
| 9 | use crate::gpio::sealed::{AFType, Pin}; | ||
| 10 | use crate::gpio::{AnyPin, OutputType}; | 9 | use crate::gpio::{AnyPin, OutputType}; |
| 11 | use crate::time::Hertz; | 10 | use crate::time::Hertz; |
| 12 | use crate::Peripheral; | 11 | use crate::Peripheral; |
| @@ -30,7 +29,7 @@ pub struct PwmPin<'d, T, C> { | |||
| 30 | 29 | ||
| 31 | macro_rules! channel_impl { | 30 | macro_rules! channel_impl { |
| 32 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 31 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 33 | impl<'d, T: CaptureCompare16bitInstance> PwmPin<'d, T, $channel> { | 32 | impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { |
| 34 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] | 33 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] |
| 35 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { | 34 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { |
| 36 | into_ref!(pin); | 35 | into_ref!(pin); |
| @@ -55,11 +54,11 @@ channel_impl!(new_ch3, Ch3, Channel3Pin); | |||
| 55 | channel_impl!(new_ch4, Ch4, Channel4Pin); | 54 | channel_impl!(new_ch4, Ch4, Channel4Pin); |
| 56 | 55 | ||
| 57 | /// Simple PWM driver. | 56 | /// Simple PWM driver. |
| 58 | pub struct SimplePwm<'d, T> { | 57 | pub struct SimplePwm<'d, T: GeneralInstance4Channel> { |
| 59 | inner: PeripheralRef<'d, T>, | 58 | inner: Timer<'d, T>, |
| 60 | } | 59 | } |
| 61 | 60 | ||
| 62 | impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | 61 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { |
| 63 | /// Create a new simple PWM driver. | 62 | /// Create a new simple PWM driver. |
| 64 | pub fn new( | 63 | pub fn new( |
| 65 | tim: impl Peripheral<P = T> + 'd, | 64 | tim: impl Peripheral<P = T> + 'd, |
| @@ -74,15 +73,11 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 74 | } | 73 | } |
| 75 | 74 | ||
| 76 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { | 75 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { |
| 77 | into_ref!(tim); | 76 | let mut this = Self { inner: Timer::new(tim) }; |
| 78 | |||
| 79 | T::enable_and_reset(); | ||
| 80 | |||
| 81 | let mut this = Self { inner: tim }; | ||
| 82 | 77 | ||
| 83 | this.inner.set_counting_mode(counting_mode); | 78 | this.inner.set_counting_mode(counting_mode); |
| 84 | this.set_frequency(freq); | 79 | this.set_frequency(freq); |
| 85 | this.inner.enable_outputs(); // Required for advanced timers, see CaptureCompare16bitInstance for details | 80 | this.inner.enable_outputs(); // Required for advanced timers, see GeneralInstance4Channel for details |
| 86 | this.inner.start(); | 81 | this.inner.start(); |
| 87 | 82 | ||
| 88 | [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] | 83 | [Channel::Ch1, Channel::Ch2, Channel::Ch3, Channel::Ch4] |
| @@ -127,14 +122,14 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 127 | /// Get max duty value. | 122 | /// Get max duty value. |
| 128 | /// | 123 | /// |
| 129 | /// This value depends on the configured frequency and the timer's clock rate from RCC. | 124 | /// This value depends on the configured frequency and the timer's clock rate from RCC. |
| 130 | pub fn get_max_duty(&self) -> u16 { | 125 | pub fn get_max_duty(&self) -> u32 { |
| 131 | self.inner.get_max_compare_value() + 1 | 126 | self.inner.get_max_compare_value() + 1 |
| 132 | } | 127 | } |
| 133 | 128 | ||
| 134 | /// Set the duty for a given channel. | 129 | /// Set the duty for a given channel. |
| 135 | /// | 130 | /// |
| 136 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. | 131 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. |
| 137 | pub fn set_duty(&mut self, channel: Channel, duty: u16) { | 132 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { |
| 138 | assert!(duty <= self.get_max_duty()); | 133 | assert!(duty <= self.get_max_duty()); |
| 139 | self.inner.set_compare_value(channel, duty) | 134 | self.inner.set_compare_value(channel, duty) |
| 140 | } | 135 | } |
| @@ -142,7 +137,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 142 | /// Get the duty for a given channel. | 137 | /// Get the duty for a given channel. |
| 143 | /// | 138 | /// |
| 144 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. | 139 | /// The value ranges from 0 for 0% duty, to [`get_max_duty`](Self::get_max_duty) for 100% duty, both included. |
| 145 | pub fn get_duty(&self, channel: Channel) -> u16 { | 140 | pub fn get_duty(&self, channel: Channel) -> u32 { |
| 146 | self.inner.get_compare_value(channel) | 141 | self.inner.get_compare_value(channel) |
| 147 | } | 142 | } |
| 148 | 143 | ||
| @@ -166,8 +161,6 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 166 | channel: Channel, | 161 | channel: Channel, |
| 167 | duty: &[u16], | 162 | duty: &[u16], |
| 168 | ) { | 163 | ) { |
| 169 | assert!(duty.iter().all(|v| *v <= self.get_max_duty())); | ||
| 170 | |||
| 171 | into_ref!(dma); | 164 | into_ref!(dma); |
| 172 | 165 | ||
| 173 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 166 | #[allow(clippy::let_unit_value)] // eg. stm32f334 |
| @@ -202,7 +195,7 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 202 | &mut dma, | 195 | &mut dma, |
| 203 | req, | 196 | req, |
| 204 | duty, | 197 | duty, |
| 205 | T::regs_1ch().ccr(channel.index()).as_ptr() as *mut _, | 198 | self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut _, |
| 206 | dma_transfer_option, | 199 | dma_transfer_option, |
| 207 | ) | 200 | ) |
| 208 | .await | 201 | .await |
| @@ -228,22 +221,20 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | |||
| 228 | 221 | ||
| 229 | macro_rules! impl_waveform_chx { | 222 | macro_rules! impl_waveform_chx { |
| 230 | ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { | 223 | ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { |
| 231 | impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | 224 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { |
| 232 | /// Generate a sequence of PWM waveform | 225 | /// Generate a sequence of PWM waveform |
| 233 | /// | 226 | /// |
| 234 | /// Note: | 227 | /// Note: |
| 235 | /// you will need to provide corresponding TIMx_CHy DMA channel to use this method. | 228 | /// you will need to provide corresponding TIMx_CHy DMA channel to use this method. |
| 236 | pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u16]) { | 229 | pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u16]) { |
| 237 | use super::vals::Ccds; | 230 | use crate::pac::timer::vals::Ccds; |
| 238 | |||
| 239 | assert!(duty.iter().all(|v| *v <= self.get_max_duty())); | ||
| 240 | 231 | ||
| 241 | into_ref!(dma); | 232 | into_ref!(dma); |
| 242 | 233 | ||
| 243 | #[allow(clippy::let_unit_value)] // eg. stm32f334 | 234 | #[allow(clippy::let_unit_value)] // eg. stm32f334 |
| 244 | let req = dma.request(); | 235 | let req = dma.request(); |
| 245 | 236 | ||
| 246 | let cc_channel = super::Channel::$cc_ch; | 237 | let cc_channel = Channel::$cc_ch; |
| 247 | 238 | ||
| 248 | let original_duty_state = self.get_duty(cc_channel); | 239 | let original_duty_state = self.get_duty(cc_channel); |
| 249 | let original_enable_state = self.is_enabled(cc_channel); | 240 | let original_enable_state = self.is_enabled(cc_channel); |
| @@ -280,7 +271,7 @@ macro_rules! impl_waveform_chx { | |||
| 280 | &mut dma, | 271 | &mut dma, |
| 281 | req, | 272 | req, |
| 282 | duty, | 273 | duty, |
| 283 | T::regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _, | 274 | self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut _, |
| 284 | dma_transfer_option, | 275 | dma_transfer_option, |
| 285 | ) | 276 | ) |
| 286 | .await | 277 | .await |
| @@ -315,10 +306,10 @@ impl_waveform_chx!(waveform_ch2, Ch2Dma, Ch2); | |||
| 315 | impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); | 306 | impl_waveform_chx!(waveform_ch3, Ch3Dma, Ch3); |
| 316 | impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); | 307 | impl_waveform_chx!(waveform_ch4, Ch4Dma, Ch4); |
| 317 | 308 | ||
| 318 | impl<'d, T: CaptureCompare16bitInstance> embedded_hal_02::Pwm for SimplePwm<'d, T> { | 309 | impl<'d, T: GeneralInstance4Channel> embedded_hal_02::Pwm for SimplePwm<'d, T> { |
| 319 | type Channel = Channel; | 310 | type Channel = Channel; |
| 320 | type Time = Hertz; | 311 | type Time = Hertz; |
| 321 | type Duty = u16; | 312 | type Duty = u32; |
| 322 | 313 | ||
| 323 | fn disable(&mut self, channel: Self::Channel) { | 314 | fn disable(&mut self, channel: Self::Channel) { |
| 324 | self.inner.enable_channel(channel, false); | 315 | self.inner.enable_channel(channel, false); |
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index 9c37d2c04..fe614b811 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs | |||
| @@ -16,11 +16,12 @@ | |||
| 16 | 16 | ||
| 17 | use core::future::poll_fn; | 17 | use core::future::poll_fn; |
| 18 | use core::marker::PhantomData; | 18 | use core::marker::PhantomData; |
| 19 | use core::sync::atomic::Ordering; | 19 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 20 | use core::task::Poll; | 20 | use core::task::Poll; |
| 21 | 21 | ||
| 22 | use embassy_hal_internal::drop::OnDrop; | 22 | use embassy_hal_internal::drop::OnDrop; |
| 23 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | 23 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 24 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 24 | 25 | ||
| 25 | use crate::dma::{AnyChannel, Request, Transfer, TransferOptions}; | 26 | use crate::dma::{AnyChannel, Request, Transfer, TransferOptions}; |
| 26 | use crate::interrupt; | 27 | use crate::interrupt; |
| @@ -555,50 +556,47 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 555 | } | 556 | } |
| 556 | } | 557 | } |
| 557 | 558 | ||
| 558 | /// UCPD instance trait. | 559 | struct State { |
| 559 | pub trait Instance: sealed::Instance + RccPeripheral {} | 560 | waker: AtomicWaker, |
| 560 | 561 | // Inverted logic for a default state of 0 so that the data goes into the .bss section. | |
| 561 | mod sealed { | 562 | drop_not_ready: AtomicBool, |
| 562 | use core::sync::atomic::AtomicBool; | 563 | } |
| 563 | |||
| 564 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 565 | |||
| 566 | pub struct State { | ||
| 567 | pub waker: AtomicWaker, | ||
| 568 | // Inverted logic for a default state of 0 so that the data goes into the .bss section. | ||
| 569 | pub drop_not_ready: AtomicBool, | ||
| 570 | } | ||
| 571 | 564 | ||
| 572 | impl State { | 565 | impl State { |
| 573 | pub const fn new() -> Self { | 566 | pub const fn new() -> Self { |
| 574 | Self { | 567 | Self { |
| 575 | waker: AtomicWaker::new(), | 568 | waker: AtomicWaker::new(), |
| 576 | drop_not_ready: AtomicBool::new(false), | 569 | drop_not_ready: AtomicBool::new(false), |
| 577 | } | ||
| 578 | } | 570 | } |
| 579 | } | 571 | } |
| 572 | } | ||
| 580 | 573 | ||
| 581 | pub trait Instance { | 574 | trait SealedInstance { |
| 582 | type Interrupt: crate::interrupt::typelevel::Interrupt; | 575 | const REGS: crate::pac::ucpd::Ucpd; |
| 583 | const REGS: crate::pac::ucpd::Ucpd; | 576 | fn state() -> &'static State; |
| 584 | fn state() -> &'static crate::ucpd::sealed::State; | 577 | } |
| 585 | } | 578 | |
| 579 | /// UCPD instance trait. | ||
| 580 | #[allow(private_bounds)] | ||
| 581 | pub trait Instance: SealedInstance + RccPeripheral { | ||
| 582 | /// Interrupt for this instance. | ||
| 583 | type Interrupt: crate::interrupt::typelevel::Interrupt; | ||
| 586 | } | 584 | } |
| 587 | 585 | ||
| 588 | foreach_interrupt!( | 586 | foreach_interrupt!( |
| 589 | ($inst:ident, ucpd, UCPD, GLOBAL, $irq:ident) => { | 587 | ($inst:ident, ucpd, UCPD, GLOBAL, $irq:ident) => { |
| 590 | impl sealed::Instance for crate::peripherals::$inst { | 588 | impl SealedInstance for crate::peripherals::$inst { |
| 591 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 592 | |||
| 593 | const REGS: crate::pac::ucpd::Ucpd = crate::pac::$inst; | 589 | const REGS: crate::pac::ucpd::Ucpd = crate::pac::$inst; |
| 594 | 590 | ||
| 595 | fn state() -> &'static crate::ucpd::sealed::State { | 591 | fn state() -> &'static State { |
| 596 | static STATE: crate::ucpd::sealed::State = crate::ucpd::sealed::State::new(); | 592 | static STATE: State = State::new(); |
| 597 | &STATE | 593 | &STATE |
| 598 | } | 594 | } |
| 599 | } | 595 | } |
| 600 | 596 | ||
| 601 | impl Instance for crate::peripherals::$inst {} | 597 | impl Instance for crate::peripherals::$inst { |
| 598 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 599 | } | ||
| 602 | }; | 600 | }; |
| 603 | ); | 601 | ); |
| 604 | 602 | ||
diff --git a/embassy-stm32/src/uid.rs b/embassy-stm32/src/uid.rs index aa13586f8..5e38532bd 100644 --- a/embassy-stm32/src/uid.rs +++ b/embassy-stm32/src/uid.rs | |||
| @@ -27,5 +27,5 @@ pub fn uid_hex_bytes() -> &'static [u8; 24] { | |||
| 27 | LOADED = true; | 27 | LOADED = true; |
| 28 | } | 28 | } |
| 29 | }); | 29 | }); |
| 30 | unsafe { &UID_HEX } | 30 | unsafe { &*core::ptr::addr_of!(UID_HEX) } |
| 31 | } | 31 | } |
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index c11e3382f..51862e185 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -1,13 +1,10 @@ | |||
| 1 | use core::future::poll_fn; | ||
| 2 | use core::slice; | 1 | use core::slice; |
| 3 | use core::sync::atomic::{AtomicBool, Ordering}; | 2 | use core::sync::atomic::AtomicBool; |
| 4 | use core::task::Poll; | ||
| 5 | 3 | ||
| 6 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | 4 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 5 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | 6 | ||
| 9 | use super::*; | 7 | use super::*; |
| 10 | use crate::interrupt::typelevel::Interrupt; | ||
| 11 | 8 | ||
| 12 | /// Interrupt handler. | 9 | /// Interrupt handler. |
| 13 | pub struct InterruptHandler<T: BasicInstance> { | 10 | pub struct InterruptHandler<T: BasicInstance> { |
| @@ -55,7 +52,7 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt | |||
| 55 | // FIXME: Should we disable any further RX interrupts when the buffer becomes full. | 52 | // FIXME: Should we disable any further RX interrupts when the buffer becomes full. |
| 56 | } | 53 | } |
| 57 | 54 | ||
| 58 | if state.rx_buf.is_full() { | 55 | if !state.rx_buf.is_empty() { |
| 59 | state.rx_waker.wake(); | 56 | state.rx_waker.wake(); |
| 60 | } | 57 | } |
| 61 | } | 58 | } |
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index ea727b010..7ab33043a 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -10,10 +10,11 @@ use core::task::Poll; | |||
| 10 | use embassy_embedded_hal::SetConfig; | 10 | use embassy_embedded_hal::SetConfig; |
| 11 | use embassy_hal_internal::drop::OnDrop; | 11 | use embassy_hal_internal::drop::OnDrop; |
| 12 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 12 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 13 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 13 | use futures::future::{select, Either}; | 14 | use futures::future::{select, Either}; |
| 14 | 15 | ||
| 15 | use crate::dma::{NoDma, Transfer}; | 16 | use crate::dma::{NoDma, Transfer}; |
| 16 | use crate::gpio::sealed::AFType; | 17 | use crate::gpio::AFType; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 18 | use crate::interrupt::typelevel::Interrupt; |
| 18 | #[allow(unused_imports)] | 19 | #[allow(unused_imports)] |
| 19 | #[cfg(not(any(usart_v1, usart_v2)))] | 20 | #[cfg(not(any(usart_v1, usart_v2)))] |
| @@ -1326,8 +1327,6 @@ mod ringbuffered; | |||
| 1326 | #[cfg(not(gpdma))] | 1327 | #[cfg(not(gpdma))] |
| 1327 | pub use ringbuffered::RingBufferedUartRx; | 1328 | pub use ringbuffered::RingBufferedUartRx; |
| 1328 | 1329 | ||
| 1329 | use self::sealed::Kind; | ||
| 1330 | |||
| 1331 | #[cfg(any(usart_v1, usart_v2))] | 1330 | #[cfg(any(usart_v1, usart_v2))] |
| 1332 | fn tdr(r: crate::pac::usart::Usart) -> *mut u8 { | 1331 | fn tdr(r: crate::pac::usart::Usart) -> *mut u8 { |
| 1333 | r.dr().as_ptr() as _ | 1332 | r.dr().as_ptr() as _ |
| @@ -1370,52 +1369,50 @@ fn clear_interrupt_flags(r: Regs, sr: regs::Isr) { | |||
| 1370 | r.icr().write(|w| *w = regs::Icr(sr.0)); | 1369 | r.icr().write(|w| *w = regs::Icr(sr.0)); |
| 1371 | } | 1370 | } |
| 1372 | 1371 | ||
| 1373 | pub(crate) mod sealed { | 1372 | #[derive(Clone, Copy, PartialEq, Eq)] |
| 1374 | use embassy_sync::waitqueue::AtomicWaker; | 1373 | enum Kind { |
| 1375 | 1374 | Uart, | |
| 1376 | use super::*; | 1375 | #[cfg(any(usart_v3, usart_v4))] |
| 1377 | 1376 | #[allow(unused)] | |
| 1378 | #[derive(Clone, Copy, PartialEq, Eq)] | 1377 | Lpuart, |
| 1379 | pub enum Kind { | 1378 | } |
| 1380 | Uart, | ||
| 1381 | #[cfg(any(usart_v3, usart_v4))] | ||
| 1382 | Lpuart, | ||
| 1383 | } | ||
| 1384 | 1379 | ||
| 1385 | pub struct State { | 1380 | struct State { |
| 1386 | pub rx_waker: AtomicWaker, | 1381 | rx_waker: AtomicWaker, |
| 1387 | pub tx_waker: AtomicWaker, | 1382 | } |
| 1388 | } | ||
| 1389 | 1383 | ||
| 1390 | impl State { | 1384 | impl State { |
| 1391 | pub const fn new() -> Self { | 1385 | const fn new() -> Self { |
| 1392 | Self { | 1386 | Self { |
| 1393 | rx_waker: AtomicWaker::new(), | 1387 | rx_waker: AtomicWaker::new(), |
| 1394 | tx_waker: AtomicWaker::new(), | ||
| 1395 | } | ||
| 1396 | } | 1388 | } |
| 1397 | } | 1389 | } |
| 1390 | } | ||
| 1398 | 1391 | ||
| 1399 | pub trait BasicInstance: crate::rcc::RccPeripheral { | 1392 | trait SealedBasicInstance: crate::rcc::RccPeripheral { |
| 1400 | const KIND: Kind; | 1393 | const KIND: Kind; |
| 1401 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1402 | 1394 | ||
| 1403 | fn regs() -> Regs; | 1395 | fn regs() -> Regs; |
| 1404 | fn state() -> &'static State; | 1396 | fn state() -> &'static State; |
| 1405 | 1397 | ||
| 1406 | fn buffered_state() -> &'static buffered::State; | 1398 | fn buffered_state() -> &'static buffered::State; |
| 1407 | } | 1399 | } |
| 1408 | 1400 | ||
| 1409 | pub trait FullInstance: BasicInstance { | 1401 | trait SealedFullInstance: SealedBasicInstance { |
| 1410 | fn regs_uart() -> crate::pac::usart::Usart; | 1402 | #[allow(unused)] |
| 1411 | } | 1403 | fn regs_uart() -> crate::pac::usart::Usart; |
| 1412 | } | 1404 | } |
| 1413 | 1405 | ||
| 1414 | /// Basic UART driver instance | 1406 | /// Basic UART driver instance |
| 1415 | pub trait BasicInstance: Peripheral<P = Self> + sealed::BasicInstance + 'static + Send {} | 1407 | #[allow(private_bounds)] |
| 1408 | pub trait BasicInstance: Peripheral<P = Self> + SealedBasicInstance + 'static + Send { | ||
| 1409 | /// Interrupt for this instance. | ||
| 1410 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1411 | } | ||
| 1416 | 1412 | ||
| 1417 | /// Full UART driver instance | 1413 | /// Full UART driver instance |
| 1418 | pub trait FullInstance: sealed::FullInstance {} | 1414 | #[allow(private_bounds)] |
| 1415 | pub trait FullInstance: SealedFullInstance {} | ||
| 1419 | 1416 | ||
| 1420 | pin_trait!(RxPin, BasicInstance); | 1417 | pin_trait!(RxPin, BasicInstance); |
| 1421 | pin_trait!(TxPin, BasicInstance); | 1418 | pin_trait!(TxPin, BasicInstance); |
| @@ -1429,16 +1426,15 @@ dma_trait!(RxDma, BasicInstance); | |||
| 1429 | 1426 | ||
| 1430 | macro_rules! impl_usart { | 1427 | macro_rules! impl_usart { |
| 1431 | ($inst:ident, $irq:ident, $kind:expr) => { | 1428 | ($inst:ident, $irq:ident, $kind:expr) => { |
| 1432 | impl sealed::BasicInstance for crate::peripherals::$inst { | 1429 | impl SealedBasicInstance for crate::peripherals::$inst { |
| 1433 | const KIND: Kind = $kind; | 1430 | const KIND: Kind = $kind; |
| 1434 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 1435 | 1431 | ||
| 1436 | fn regs() -> Regs { | 1432 | fn regs() -> Regs { |
| 1437 | unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) } | 1433 | unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) } |
| 1438 | } | 1434 | } |
| 1439 | 1435 | ||
| 1440 | fn state() -> &'static crate::usart::sealed::State { | 1436 | fn state() -> &'static crate::usart::State { |
| 1441 | static STATE: crate::usart::sealed::State = crate::usart::sealed::State::new(); | 1437 | static STATE: crate::usart::State = crate::usart::State::new(); |
| 1442 | &STATE | 1438 | &STATE |
| 1443 | } | 1439 | } |
| 1444 | 1440 | ||
| @@ -1448,7 +1444,9 @@ macro_rules! impl_usart { | |||
| 1448 | } | 1444 | } |
| 1449 | } | 1445 | } |
| 1450 | 1446 | ||
| 1451 | impl BasicInstance for peripherals::$inst {} | 1447 | impl BasicInstance for peripherals::$inst { |
| 1448 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 1449 | } | ||
| 1452 | }; | 1450 | }; |
| 1453 | } | 1451 | } |
| 1454 | 1452 | ||
| @@ -1460,7 +1458,7 @@ foreach_interrupt!( | |||
| 1460 | ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { | 1458 | ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { |
| 1461 | impl_usart!($inst, $irq, Kind::Uart); | 1459 | impl_usart!($inst, $irq, Kind::Uart); |
| 1462 | 1460 | ||
| 1463 | impl sealed::FullInstance for peripherals::$inst { | 1461 | impl SealedFullInstance for peripherals::$inst { |
| 1464 | fn regs_uart() -> crate::pac::usart::Usart { | 1462 | fn regs_uart() -> crate::pac::usart::Usart { |
| 1465 | crate::pac::$inst | 1463 | crate::pac::$inst |
| 1466 | } | 1464 | } |
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs index 4debd4e54..1e3c44167 100644 --- a/embassy-stm32/src/usb/mod.rs +++ b/embassy-stm32/src/usb/mod.rs | |||
| @@ -1,37 +1,69 @@ | |||
| 1 | //! Universal Serial Bus (USB) | 1 | //! Universal Serial Bus (USB) |
| 2 | 2 | ||
| 3 | use crate::interrupt; | 3 | #[cfg_attr(usb, path = "usb.rs")] |
| 4 | use crate::rcc::RccPeripheral; | 4 | #[cfg_attr(otg, path = "otg.rs")] |
| 5 | mod _version; | ||
| 6 | pub use _version::*; | ||
| 5 | 7 | ||
| 6 | mod usb; | 8 | use crate::interrupt::typelevel::Interrupt; |
| 7 | pub use usb::*; | 9 | use crate::rcc::SealedRccPeripheral; |
| 8 | 10 | ||
| 9 | pub(crate) mod sealed { | 11 | /// clock, power initialization stuff that's common for USB and OTG. |
| 10 | pub trait Instance { | 12 | fn common_init<T: Instance>() { |
| 11 | fn regs() -> crate::pac::usb::Usb; | 13 | // Check the USB clock is enabled and running at exactly 48 MHz. |
| 14 | // frequency() will panic if not enabled | ||
| 15 | let freq = T::frequency(); | ||
| 16 | // Check frequency is within the 0.25% tolerance allowed by the spec. | ||
| 17 | // Clock might not be exact 48Mhz due to rounding errors in PLL calculation, or if the user | ||
| 18 | // has tight clock restrictions due to something else (like audio). | ||
| 19 | if freq.0.abs_diff(48_000_000) > 120_000 { | ||
| 20 | panic!( | ||
| 21 | "USB clock should be 48Mhz but is {} Hz. Please double-check your RCC settings.", | ||
| 22 | freq.0 | ||
| 23 | ) | ||
| 12 | } | 24 | } |
| 13 | } | ||
| 14 | 25 | ||
| 15 | /// USB instance trait. | 26 | #[cfg(any(stm32l4, stm32l5, stm32wb))] |
| 16 | pub trait Instance: sealed::Instance + RccPeripheral + 'static { | 27 | critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); |
| 17 | /// Interrupt for this USB instance. | 28 | |
| 18 | type Interrupt: interrupt::typelevel::Interrupt; | 29 | #[cfg(pwr_h5)] |
| 19 | } | 30 | critical_section::with(|_| crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true))); |
| 31 | |||
| 32 | #[cfg(stm32h7)] | ||
| 33 | { | ||
| 34 | // If true, VDD33USB is generated by internal regulator from VDD50USB | ||
| 35 | // If false, VDD33USB and VDD50USB must be suplied directly with 3.3V (default on nucleo) | ||
| 36 | // TODO: unhardcode | ||
| 37 | let internal_regulator = false; | ||
| 38 | |||
| 39 | // Enable USB power | ||
| 40 | critical_section::with(|_| { | ||
| 41 | crate::pac::PWR.cr3().modify(|w| { | ||
| 42 | w.set_usb33den(true); | ||
| 43 | w.set_usbregen(internal_regulator); | ||
| 44 | }) | ||
| 45 | }); | ||
| 46 | |||
| 47 | // Wait for USB power to stabilize | ||
| 48 | while !crate::pac::PWR.cr3().read().usb33rdy() {} | ||
| 49 | } | ||
| 50 | |||
| 51 | #[cfg(stm32u5)] | ||
| 52 | { | ||
| 53 | // Enable USB power | ||
| 54 | critical_section::with(|_| { | ||
| 55 | crate::pac::PWR.svmcr().modify(|w| { | ||
| 56 | w.set_usv(true); | ||
| 57 | w.set_uvmen(true); | ||
| 58 | }) | ||
| 59 | }); | ||
| 60 | |||
| 61 | // Wait for USB power to stabilize | ||
| 62 | while !crate::pac::PWR.svmsr().read().vddusbrdy() {} | ||
| 63 | } | ||
| 64 | |||
| 65 | T::Interrupt::unpend(); | ||
| 66 | unsafe { T::Interrupt::enable() }; | ||
| 20 | 67 | ||
| 21 | // Internal PHY pins | 68 | <T as SealedRccPeripheral>::enable_and_reset(); |
| 22 | pin_trait!(DpPin, Instance); | 69 | } |
| 23 | pin_trait!(DmPin, Instance); | ||
| 24 | |||
| 25 | foreach_interrupt!( | ||
| 26 | ($inst:ident, usb, $block:ident, LP, $irq:ident) => { | ||
| 27 | impl sealed::Instance for crate::peripherals::$inst { | ||
| 28 | fn regs() -> crate::pac::usb::Usb { | ||
| 29 | crate::pac::$inst | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | impl Instance for crate::peripherals::$inst { | ||
| 34 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | ); | ||
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb/otg.rs index 373697ec8..b0e7067bd 100644 --- a/embassy-stm32/src/usb_otg/usb.rs +++ b/embassy-stm32/src/usb/otg.rs | |||
| @@ -6,17 +6,16 @@ use core::task::Poll; | |||
| 6 | use embassy_hal_internal::{into_ref, Peripheral}; | 6 | use embassy_hal_internal::{into_ref, Peripheral}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use embassy_usb_driver::{ | 8 | use embassy_usb_driver::{ |
| 9 | self, Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, | 9 | Bus as _, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointIn, EndpointInfo, EndpointOut, |
| 10 | EndpointOut, EndpointType, Event, Unsupported, | 10 | EndpointType, Event, Unsupported, |
| 11 | }; | 11 | }; |
| 12 | use futures::future::poll_fn; | 12 | use futures::future::poll_fn; |
| 13 | 13 | ||
| 14 | use super::*; | 14 | use crate::gpio::AFType; |
| 15 | use crate::gpio::sealed::AFType; | ||
| 16 | use crate::interrupt; | 15 | use crate::interrupt; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 16 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::otg::{regs, vals}; | 17 | use crate::pac::otg::{regs, vals}; |
| 19 | use crate::rcc::sealed::RccPeripheral; | 18 | use crate::rcc::{RccPeripheral, SealedRccPeripheral}; |
| 20 | use crate::time::Hertz; | 19 | use crate::time::Hertz; |
| 21 | 20 | ||
| 22 | /// Interrupt handler. | 21 | /// Interrupt handler. |
| @@ -561,8 +560,7 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 561 | 560 | ||
| 562 | impl<'d, T: Instance> Bus<'d, T> { | 561 | impl<'d, T: Instance> Bus<'d, T> { |
| 563 | fn init(&mut self) { | 562 | fn init(&mut self) { |
| 564 | #[cfg(stm32l4)] | 563 | super::common_init::<T>(); |
| 565 | critical_section::with(|_| crate::pac::PWR.cr2().modify(|w| w.set_usv(true))); | ||
| 566 | 564 | ||
| 567 | #[cfg(stm32f7)] | 565 | #[cfg(stm32f7)] |
| 568 | { | 566 | { |
| @@ -590,22 +588,6 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 590 | 588 | ||
| 591 | #[cfg(stm32h7)] | 589 | #[cfg(stm32h7)] |
| 592 | { | 590 | { |
| 593 | // If true, VDD33USB is generated by internal regulator from VDD50USB | ||
| 594 | // If false, VDD33USB and VDD50USB must be suplied directly with 3.3V (default on nucleo) | ||
| 595 | // TODO: unhardcode | ||
| 596 | let internal_regulator = false; | ||
| 597 | |||
| 598 | // Enable USB power | ||
| 599 | critical_section::with(|_| { | ||
| 600 | crate::pac::PWR.cr3().modify(|w| { | ||
| 601 | w.set_usb33den(true); | ||
| 602 | w.set_usbregen(internal_regulator); | ||
| 603 | }) | ||
| 604 | }); | ||
| 605 | |||
| 606 | // Wait for USB power to stabilize | ||
| 607 | while !crate::pac::PWR.cr3().read().usb33rdy() {} | ||
| 608 | |||
| 609 | // Enable ULPI clock if external PHY is used | 591 | // Enable ULPI clock if external PHY is used |
| 610 | let ulpien = !self.phy_type.internal(); | 592 | let ulpien = !self.phy_type.internal(); |
| 611 | critical_section::with(|_| { | 593 | critical_section::with(|_| { |
| @@ -626,25 +608,6 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 626 | }); | 608 | }); |
| 627 | } | 609 | } |
| 628 | 610 | ||
| 629 | #[cfg(stm32u5)] | ||
| 630 | { | ||
| 631 | // Enable USB power | ||
| 632 | critical_section::with(|_| { | ||
| 633 | crate::pac::PWR.svmcr().modify(|w| { | ||
| 634 | w.set_usv(true); | ||
| 635 | w.set_uvmen(true); | ||
| 636 | }) | ||
| 637 | }); | ||
| 638 | |||
| 639 | // Wait for USB power to stabilize | ||
| 640 | while !crate::pac::PWR.svmsr().read().vddusbrdy() {} | ||
| 641 | } | ||
| 642 | |||
| 643 | <T as RccPeripheral>::enable_and_reset(); | ||
| 644 | |||
| 645 | T::Interrupt::unpend(); | ||
| 646 | unsafe { T::Interrupt::enable() }; | ||
| 647 | |||
| 648 | let r = T::regs(); | 611 | let r = T::regs(); |
| 649 | let core_id = r.cid().read().0; | 612 | let core_id = r.cid().read().0; |
| 650 | trace!("Core id {:08x}", core_id); | 613 | trace!("Core id {:08x}", core_id); |
| @@ -846,7 +809,7 @@ impl<'d, T: Instance> Bus<'d, T> { | |||
| 846 | fn disable(&mut self) { | 809 | fn disable(&mut self) { |
| 847 | T::Interrupt::disable(); | 810 | T::Interrupt::disable(); |
| 848 | 811 | ||
| 849 | <T as RccPeripheral>::disable(); | 812 | <T as SealedRccPeripheral>::disable(); |
| 850 | 813 | ||
| 851 | #[cfg(stm32l4)] | 814 | #[cfg(stm32l4)] |
| 852 | crate::pac::PWR.cr2().modify(|w| w.set_usv(false)); | 815 | crate::pac::PWR.cr2().modify(|w| w.set_usv(false)); |
| @@ -1469,3 +1432,158 @@ fn calculate_trdt(speed: vals::Dspd, ahb_freq: Hertz) -> u8 { | |||
| 1469 | fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { | 1432 | fn quirk_setup_late_cnak(r: crate::pac::otg::Otg) -> bool { |
| 1470 | r.cid().read().0 & 0xf000 == 0x1000 | 1433 | r.cid().read().0 & 0xf000 == 0x1000 |
| 1471 | } | 1434 | } |
| 1435 | |||
| 1436 | // Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps | ||
| 1437 | const MAX_EP_COUNT: usize = 9; | ||
| 1438 | |||
| 1439 | trait SealedInstance { | ||
| 1440 | const HIGH_SPEED: bool; | ||
| 1441 | const FIFO_DEPTH_WORDS: u16; | ||
| 1442 | const ENDPOINT_COUNT: usize; | ||
| 1443 | |||
| 1444 | fn regs() -> crate::pac::otg::Otg; | ||
| 1445 | fn state() -> &'static super::State<{ MAX_EP_COUNT }>; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | /// USB instance trait. | ||
| 1449 | #[allow(private_bounds)] | ||
| 1450 | pub trait Instance: SealedInstance + RccPeripheral + 'static { | ||
| 1451 | /// Interrupt for this USB instance. | ||
| 1452 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1453 | } | ||
| 1454 | |||
| 1455 | // Internal PHY pins | ||
| 1456 | pin_trait!(DpPin, Instance); | ||
| 1457 | pin_trait!(DmPin, Instance); | ||
| 1458 | |||
| 1459 | // External PHY pins | ||
| 1460 | pin_trait!(UlpiClkPin, Instance); | ||
| 1461 | pin_trait!(UlpiDirPin, Instance); | ||
| 1462 | pin_trait!(UlpiNxtPin, Instance); | ||
| 1463 | pin_trait!(UlpiStpPin, Instance); | ||
| 1464 | pin_trait!(UlpiD0Pin, Instance); | ||
| 1465 | pin_trait!(UlpiD1Pin, Instance); | ||
| 1466 | pin_trait!(UlpiD2Pin, Instance); | ||
| 1467 | pin_trait!(UlpiD3Pin, Instance); | ||
| 1468 | pin_trait!(UlpiD4Pin, Instance); | ||
| 1469 | pin_trait!(UlpiD5Pin, Instance); | ||
| 1470 | pin_trait!(UlpiD6Pin, Instance); | ||
| 1471 | pin_trait!(UlpiD7Pin, Instance); | ||
| 1472 | |||
| 1473 | foreach_interrupt!( | ||
| 1474 | (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => { | ||
| 1475 | impl SealedInstance for crate::peripherals::USB_OTG_FS { | ||
| 1476 | const HIGH_SPEED: bool = false; | ||
| 1477 | |||
| 1478 | cfg_if::cfg_if! { | ||
| 1479 | if #[cfg(stm32f1)] { | ||
| 1480 | const FIFO_DEPTH_WORDS: u16 = 128; | ||
| 1481 | const ENDPOINT_COUNT: usize = 8; | ||
| 1482 | } else if #[cfg(any( | ||
| 1483 | stm32f2, | ||
| 1484 | stm32f401, | ||
| 1485 | stm32f405, | ||
| 1486 | stm32f407, | ||
| 1487 | stm32f411, | ||
| 1488 | stm32f415, | ||
| 1489 | stm32f417, | ||
| 1490 | stm32f427, | ||
| 1491 | stm32f429, | ||
| 1492 | stm32f437, | ||
| 1493 | stm32f439, | ||
| 1494 | ))] { | ||
| 1495 | const FIFO_DEPTH_WORDS: u16 = 320; | ||
| 1496 | const ENDPOINT_COUNT: usize = 4; | ||
| 1497 | } else if #[cfg(any( | ||
| 1498 | stm32f412, | ||
| 1499 | stm32f413, | ||
| 1500 | stm32f423, | ||
| 1501 | stm32f446, | ||
| 1502 | stm32f469, | ||
| 1503 | stm32f479, | ||
| 1504 | stm32f7, | ||
| 1505 | stm32l4, | ||
| 1506 | stm32u5, | ||
| 1507 | ))] { | ||
| 1508 | const FIFO_DEPTH_WORDS: u16 = 320; | ||
| 1509 | const ENDPOINT_COUNT: usize = 6; | ||
| 1510 | } else if #[cfg(stm32g0x1)] { | ||
| 1511 | const FIFO_DEPTH_WORDS: u16 = 512; | ||
| 1512 | const ENDPOINT_COUNT: usize = 8; | ||
| 1513 | } else if #[cfg(stm32h7)] { | ||
| 1514 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 1515 | const ENDPOINT_COUNT: usize = 9; | ||
| 1516 | } else if #[cfg(stm32u5)] { | ||
| 1517 | const FIFO_DEPTH_WORDS: u16 = 320; | ||
| 1518 | const ENDPOINT_COUNT: usize = 6; | ||
| 1519 | } else { | ||
| 1520 | compile_error!("USB_OTG_FS peripheral is not supported by this chip."); | ||
| 1521 | } | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | fn regs() -> crate::pac::otg::Otg { | ||
| 1525 | crate::pac::USB_OTG_FS | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | fn state() -> &'static State<MAX_EP_COUNT> { | ||
| 1529 | static STATE: State<MAX_EP_COUNT> = State::new(); | ||
| 1530 | &STATE | ||
| 1531 | } | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | impl Instance for crate::peripherals::USB_OTG_FS { | ||
| 1535 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 1536 | } | ||
| 1537 | }; | ||
| 1538 | |||
| 1539 | (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => { | ||
| 1540 | impl SealedInstance for crate::peripherals::USB_OTG_HS { | ||
| 1541 | const HIGH_SPEED: bool = true; | ||
| 1542 | |||
| 1543 | cfg_if::cfg_if! { | ||
| 1544 | if #[cfg(any( | ||
| 1545 | stm32f2, | ||
| 1546 | stm32f405, | ||
| 1547 | stm32f407, | ||
| 1548 | stm32f415, | ||
| 1549 | stm32f417, | ||
| 1550 | stm32f427, | ||
| 1551 | stm32f429, | ||
| 1552 | stm32f437, | ||
| 1553 | stm32f439, | ||
| 1554 | ))] { | ||
| 1555 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 1556 | const ENDPOINT_COUNT: usize = 6; | ||
| 1557 | } else if #[cfg(any( | ||
| 1558 | stm32f446, | ||
| 1559 | stm32f469, | ||
| 1560 | stm32f479, | ||
| 1561 | stm32f7, | ||
| 1562 | stm32h7, | ||
| 1563 | ))] { | ||
| 1564 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 1565 | const ENDPOINT_COUNT: usize = 9; | ||
| 1566 | } else if #[cfg(stm32u5)] { | ||
| 1567 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 1568 | const ENDPOINT_COUNT: usize = 9; | ||
| 1569 | } else { | ||
| 1570 | compile_error!("USB_OTG_HS peripheral is not supported by this chip."); | ||
| 1571 | } | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | fn regs() -> crate::pac::otg::Otg { | ||
| 1575 | // OTG HS registers are a superset of FS registers | ||
| 1576 | unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) } | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | fn state() -> &'static State<MAX_EP_COUNT> { | ||
| 1580 | static STATE: State<MAX_EP_COUNT> = State::new(); | ||
| 1581 | &STATE | ||
| 1582 | } | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | impl Instance for crate::peripherals::USB_OTG_HS { | ||
| 1586 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 1587 | } | ||
| 1588 | }; | ||
| 1589 | ); | ||
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index be321a19b..f48808cb3 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs | |||
| @@ -12,12 +12,10 @@ use embassy_usb_driver::{ | |||
| 12 | Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, | 12 | Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, |
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| 15 | use super::{DmPin, DpPin, Instance}; | ||
| 16 | use crate::interrupt::typelevel::Interrupt; | ||
| 17 | use crate::pac::usb::regs; | 15 | use crate::pac::usb::regs; |
| 18 | use crate::pac::usb::vals::{EpType, Stat}; | 16 | use crate::pac::usb::vals::{EpType, Stat}; |
| 19 | use crate::pac::USBRAM; | 17 | use crate::pac::USBRAM; |
| 20 | use crate::rcc::sealed::RccPeripheral; | 18 | use crate::rcc::RccPeripheral; |
| 21 | use crate::{interrupt, Peripheral}; | 19 | use crate::{interrupt, Peripheral}; |
| 22 | 20 | ||
| 23 | /// Interrupt handler. | 21 | /// Interrupt handler. |
| @@ -259,18 +257,10 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 259 | dm: impl Peripheral<P = impl DmPin<T>> + 'd, | 257 | dm: impl Peripheral<P = impl DmPin<T>> + 'd, |
| 260 | ) -> Self { | 258 | ) -> Self { |
| 261 | into_ref!(dp, dm); | 259 | into_ref!(dp, dm); |
| 262 | T::Interrupt::unpend(); | ||
| 263 | unsafe { T::Interrupt::enable() }; | ||
| 264 | 260 | ||
| 265 | let regs = T::regs(); | 261 | super::common_init::<T>(); |
| 266 | |||
| 267 | #[cfg(any(stm32l4, stm32l5, stm32wb))] | ||
| 268 | crate::pac::PWR.cr2().modify(|w| w.set_usv(true)); | ||
| 269 | |||
| 270 | #[cfg(pwr_h5)] | ||
| 271 | crate::pac::PWR.usbscr().modify(|w| w.set_usb33sv(true)); | ||
| 272 | 262 | ||
| 273 | <T as RccPeripheral>::enable_and_reset(); | 263 | let regs = T::regs(); |
| 274 | 264 | ||
| 275 | regs.cntr().write(|w| { | 265 | regs.cntr().write(|w| { |
| 276 | w.set_pdwn(false); | 266 | w.set_pdwn(false); |
| @@ -287,8 +277,8 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 287 | 277 | ||
| 288 | #[cfg(not(stm32l1))] | 278 | #[cfg(not(stm32l1))] |
| 289 | { | 279 | { |
| 290 | dp.set_as_af(dp.af_num(), crate::gpio::sealed::AFType::OutputPushPull); | 280 | dp.set_as_af(dp.af_num(), crate::gpio::AFType::OutputPushPull); |
| 291 | dm.set_as_af(dm.af_num(), crate::gpio::sealed::AFType::OutputPushPull); | 281 | dm.set_as_af(dm.af_num(), crate::gpio::AFType::OutputPushPull); |
| 292 | } | 282 | } |
| 293 | #[cfg(stm32l1)] | 283 | #[cfg(stm32l1)] |
| 294 | let _ = (dp, dm); // suppress "unused" warnings. | 284 | let _ = (dp, dm); // suppress "unused" warnings. |
| @@ -647,7 +637,6 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 647 | 637 | ||
| 648 | trait Dir { | 638 | trait Dir { |
| 649 | fn dir() -> Direction; | 639 | fn dir() -> Direction; |
| 650 | fn waker(i: usize) -> &'static AtomicWaker; | ||
| 651 | } | 640 | } |
| 652 | 641 | ||
| 653 | /// Marker type for the "IN" direction. | 642 | /// Marker type for the "IN" direction. |
| @@ -656,11 +645,6 @@ impl Dir for In { | |||
| 656 | fn dir() -> Direction { | 645 | fn dir() -> Direction { |
| 657 | Direction::In | 646 | Direction::In |
| 658 | } | 647 | } |
| 659 | |||
| 660 | #[inline] | ||
| 661 | fn waker(i: usize) -> &'static AtomicWaker { | ||
| 662 | &EP_IN_WAKERS[i] | ||
| 663 | } | ||
| 664 | } | 648 | } |
| 665 | 649 | ||
| 666 | /// Marker type for the "OUT" direction. | 650 | /// Marker type for the "OUT" direction. |
| @@ -669,11 +653,6 @@ impl Dir for Out { | |||
| 669 | fn dir() -> Direction { | 653 | fn dir() -> Direction { |
| 670 | Direction::Out | 654 | Direction::Out |
| 671 | } | 655 | } |
| 672 | |||
| 673 | #[inline] | ||
| 674 | fn waker(i: usize) -> &'static AtomicWaker { | ||
| 675 | &EP_OUT_WAKERS[i] | ||
| 676 | } | ||
| 677 | } | 656 | } |
| 678 | 657 | ||
| 679 | /// USB endpoint. | 658 | /// USB endpoint. |
| @@ -1057,3 +1036,32 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 1057 | }); | 1036 | }); |
| 1058 | } | 1037 | } |
| 1059 | } | 1038 | } |
| 1039 | |||
| 1040 | trait SealedInstance { | ||
| 1041 | fn regs() -> crate::pac::usb::Usb; | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | /// USB instance trait. | ||
| 1045 | #[allow(private_bounds)] | ||
| 1046 | pub trait Instance: SealedInstance + RccPeripheral + 'static { | ||
| 1047 | /// Interrupt for this USB instance. | ||
| 1048 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | // Internal PHY pins | ||
| 1052 | pin_trait!(DpPin, Instance); | ||
| 1053 | pin_trait!(DmPin, Instance); | ||
| 1054 | |||
| 1055 | foreach_interrupt!( | ||
| 1056 | ($inst:ident, usb, $block:ident, LP, $irq:ident) => { | ||
| 1057 | impl SealedInstance for crate::peripherals::$inst { | ||
| 1058 | fn regs() -> crate::pac::usb::Usb { | ||
| 1059 | crate::pac::$inst | ||
| 1060 | } | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | impl Instance for crate::peripherals::$inst { | ||
| 1064 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 1065 | } | ||
| 1066 | }; | ||
| 1067 | ); | ||
diff --git a/embassy-stm32/src/usb_otg/mod.rs b/embassy-stm32/src/usb_otg/mod.rs deleted file mode 100644 index 0649e684b..000000000 --- a/embassy-stm32/src/usb_otg/mod.rs +++ /dev/null | |||
| @@ -1,163 +0,0 @@ | |||
| 1 | //! USB On The Go (OTG) | ||
| 2 | |||
| 3 | use crate::rcc::RccPeripheral; | ||
| 4 | use crate::{interrupt, peripherals}; | ||
| 5 | |||
| 6 | mod usb; | ||
| 7 | pub use usb::*; | ||
| 8 | |||
| 9 | // Using Instance::ENDPOINT_COUNT requires feature(const_generic_expr) so just define maximum eps | ||
| 10 | const MAX_EP_COUNT: usize = 9; | ||
| 11 | |||
| 12 | pub(crate) mod sealed { | ||
| 13 | pub trait Instance { | ||
| 14 | const HIGH_SPEED: bool; | ||
| 15 | const FIFO_DEPTH_WORDS: u16; | ||
| 16 | const ENDPOINT_COUNT: usize; | ||
| 17 | |||
| 18 | fn regs() -> crate::pac::otg::Otg; | ||
| 19 | fn state() -> &'static super::State<{ super::MAX_EP_COUNT }>; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | /// USB OTG instance. | ||
| 24 | pub trait Instance: sealed::Instance + RccPeripheral { | ||
| 25 | /// Interrupt for this USB OTG instance. | ||
| 26 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 27 | } | ||
| 28 | |||
| 29 | // Internal PHY pins | ||
| 30 | pin_trait!(DpPin, Instance); | ||
| 31 | pin_trait!(DmPin, Instance); | ||
| 32 | |||
| 33 | // External PHY pins | ||
| 34 | pin_trait!(UlpiClkPin, Instance); | ||
| 35 | pin_trait!(UlpiDirPin, Instance); | ||
| 36 | pin_trait!(UlpiNxtPin, Instance); | ||
| 37 | pin_trait!(UlpiStpPin, Instance); | ||
| 38 | pin_trait!(UlpiD0Pin, Instance); | ||
| 39 | pin_trait!(UlpiD1Pin, Instance); | ||
| 40 | pin_trait!(UlpiD2Pin, Instance); | ||
| 41 | pin_trait!(UlpiD3Pin, Instance); | ||
| 42 | pin_trait!(UlpiD4Pin, Instance); | ||
| 43 | pin_trait!(UlpiD5Pin, Instance); | ||
| 44 | pin_trait!(UlpiD6Pin, Instance); | ||
| 45 | pin_trait!(UlpiD7Pin, Instance); | ||
| 46 | |||
| 47 | foreach_interrupt!( | ||
| 48 | (USB_OTG_FS, otg, $block:ident, GLOBAL, $irq:ident) => { | ||
| 49 | impl sealed::Instance for peripherals::USB_OTG_FS { | ||
| 50 | const HIGH_SPEED: bool = false; | ||
| 51 | |||
| 52 | cfg_if::cfg_if! { | ||
| 53 | if #[cfg(stm32f1)] { | ||
| 54 | const FIFO_DEPTH_WORDS: u16 = 128; | ||
| 55 | const ENDPOINT_COUNT: usize = 8; | ||
| 56 | } else if #[cfg(any( | ||
| 57 | stm32f2, | ||
| 58 | stm32f401, | ||
| 59 | stm32f405, | ||
| 60 | stm32f407, | ||
| 61 | stm32f411, | ||
| 62 | stm32f415, | ||
| 63 | stm32f417, | ||
| 64 | stm32f427, | ||
| 65 | stm32f429, | ||
| 66 | stm32f437, | ||
| 67 | stm32f439, | ||
| 68 | ))] { | ||
| 69 | const FIFO_DEPTH_WORDS: u16 = 320; | ||
| 70 | const ENDPOINT_COUNT: usize = 4; | ||
| 71 | } else if #[cfg(any( | ||
| 72 | stm32f412, | ||
| 73 | stm32f413, | ||
| 74 | stm32f423, | ||
| 75 | stm32f446, | ||
| 76 | stm32f469, | ||
| 77 | stm32f479, | ||
| 78 | stm32f7, | ||
| 79 | stm32l4, | ||
| 80 | stm32u5, | ||
| 81 | ))] { | ||
| 82 | const FIFO_DEPTH_WORDS: u16 = 320; | ||
| 83 | const ENDPOINT_COUNT: usize = 6; | ||
| 84 | } else if #[cfg(stm32g0x1)] { | ||
| 85 | const FIFO_DEPTH_WORDS: u16 = 512; | ||
| 86 | const ENDPOINT_COUNT: usize = 8; | ||
| 87 | } else if #[cfg(stm32h7)] { | ||
| 88 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 89 | const ENDPOINT_COUNT: usize = 9; | ||
| 90 | } else if #[cfg(stm32u5)] { | ||
| 91 | const FIFO_DEPTH_WORDS: u16 = 320; | ||
| 92 | const ENDPOINT_COUNT: usize = 6; | ||
| 93 | } else { | ||
| 94 | compile_error!("USB_OTG_FS peripheral is not supported by this chip."); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | fn regs() -> crate::pac::otg::Otg { | ||
| 99 | crate::pac::USB_OTG_FS | ||
| 100 | } | ||
| 101 | |||
| 102 | fn state() -> &'static State<MAX_EP_COUNT> { | ||
| 103 | static STATE: State<MAX_EP_COUNT> = State::new(); | ||
| 104 | &STATE | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | impl Instance for peripherals::USB_OTG_FS { | ||
| 109 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 110 | } | ||
| 111 | }; | ||
| 112 | |||
| 113 | (USB_OTG_HS, otg, $block:ident, GLOBAL, $irq:ident) => { | ||
| 114 | impl sealed::Instance for peripherals::USB_OTG_HS { | ||
| 115 | const HIGH_SPEED: bool = true; | ||
| 116 | |||
| 117 | cfg_if::cfg_if! { | ||
| 118 | if #[cfg(any( | ||
| 119 | stm32f2, | ||
| 120 | stm32f405, | ||
| 121 | stm32f407, | ||
| 122 | stm32f415, | ||
| 123 | stm32f417, | ||
| 124 | stm32f427, | ||
| 125 | stm32f429, | ||
| 126 | stm32f437, | ||
| 127 | stm32f439, | ||
| 128 | ))] { | ||
| 129 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 130 | const ENDPOINT_COUNT: usize = 6; | ||
| 131 | } else if #[cfg(any( | ||
| 132 | stm32f446, | ||
| 133 | stm32f469, | ||
| 134 | stm32f479, | ||
| 135 | stm32f7, | ||
| 136 | stm32h7, | ||
| 137 | ))] { | ||
| 138 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 139 | const ENDPOINT_COUNT: usize = 9; | ||
| 140 | } else if #[cfg(stm32u5)] { | ||
| 141 | const FIFO_DEPTH_WORDS: u16 = 1024; | ||
| 142 | const ENDPOINT_COUNT: usize = 9; | ||
| 143 | } else { | ||
| 144 | compile_error!("USB_OTG_HS peripheral is not supported by this chip."); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | fn regs() -> crate::pac::otg::Otg { | ||
| 149 | // OTG HS registers are a superset of FS registers | ||
| 150 | unsafe { crate::pac::otg::Otg::from_ptr(crate::pac::USB_OTG_HS.as_ptr()) } | ||
| 151 | } | ||
| 152 | |||
| 153 | fn state() -> &'static State<MAX_EP_COUNT> { | ||
| 154 | static STATE: State<MAX_EP_COUNT> = State::new(); | ||
| 155 | &STATE | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | impl Instance for peripherals::USB_OTG_HS { | ||
| 160 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 161 | } | ||
| 162 | }; | ||
| 163 | ); | ||
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs index 2ff0db09e..ab21c4b6b 100644 --- a/embassy-stm32/src/wdg/mod.rs +++ b/embassy-stm32/src/wdg/mod.rs | |||
| @@ -80,18 +80,17 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> { | |||
| 80 | } | 80 | } |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | mod sealed { | 83 | trait SealedInstance { |
| 84 | pub trait Instance { | 84 | fn regs() -> crate::pac::iwdg::Iwdg; |
| 85 | fn regs() -> crate::pac::iwdg::Iwdg; | ||
| 86 | } | ||
| 87 | } | 85 | } |
| 88 | 86 | ||
| 89 | /// IWDG instance trait. | 87 | /// IWDG instance trait. |
| 90 | pub trait Instance: sealed::Instance {} | 88 | #[allow(private_bounds)] |
| 89 | pub trait Instance: SealedInstance {} | ||
| 91 | 90 | ||
| 92 | foreach_peripheral!( | 91 | foreach_peripheral!( |
| 93 | (iwdg, $inst:ident) => { | 92 | (iwdg, $inst:ident) => { |
| 94 | impl sealed::Instance for crate::peripherals::$inst { | 93 | impl SealedInstance for crate::peripherals::$inst { |
| 95 | fn regs() -> crate::pac::iwdg::Iwdg { | 94 | fn regs() -> crate::pac::iwdg::Iwdg { |
| 96 | crate::pac::$inst | 95 | crate::pac::$inst |
| 97 | } | 96 | } |
diff --git a/embassy-sync/Cargo.toml b/embassy-sync/Cargo.toml index 85673026c..aaf6fab1d 100644 --- a/embassy-sync/Cargo.toml +++ b/embassy-sync/Cargo.toml | |||
| @@ -20,7 +20,7 @@ src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-sync/ | |||
| 20 | target = "thumbv7em-none-eabi" | 20 | target = "thumbv7em-none-eabi" |
| 21 | 21 | ||
| 22 | [features] | 22 | [features] |
| 23 | std = [] | 23 | std = ["critical-section/std"] |
| 24 | turbowakers = [] | 24 | turbowakers = [] |
| 25 | 25 | ||
| 26 | [dependencies] | 26 | [dependencies] |
diff --git a/embassy-sync/src/fmt.rs b/embassy-sync/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-sync/src/fmt.rs +++ b/embassy-sync/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs index d88c76db5..61b173e80 100644 --- a/embassy-sync/src/lib.rs +++ b/embassy-sync/src/lib.rs | |||
| @@ -13,6 +13,7 @@ mod ring_buffer; | |||
| 13 | pub mod blocking_mutex; | 13 | pub mod blocking_mutex; |
| 14 | pub mod channel; | 14 | pub mod channel; |
| 15 | pub mod mutex; | 15 | pub mod mutex; |
| 16 | pub mod once_lock; | ||
| 16 | pub mod pipe; | 17 | pub mod pipe; |
| 17 | pub mod priority_channel; | 18 | pub mod priority_channel; |
| 18 | pub mod pubsub; | 19 | pub mod pubsub; |
diff --git a/embassy-sync/src/once_lock.rs b/embassy-sync/src/once_lock.rs new file mode 100644 index 000000000..31cc99711 --- /dev/null +++ b/embassy-sync/src/once_lock.rs | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | //! Syncronization primitive for initializing a value once, allowing others to await a reference to the value. | ||
| 2 | |||
| 3 | use core::cell::Cell; | ||
| 4 | use core::future::poll_fn; | ||
| 5 | use core::mem::MaybeUninit; | ||
| 6 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 7 | use core::task::Poll; | ||
| 8 | |||
| 9 | /// The `OnceLock` is a synchronization primitive that allows for | ||
| 10 | /// initializing a value once, and allowing others to `.await` a | ||
| 11 | /// reference to the value. This is useful for lazy initialization of | ||
| 12 | /// a static value. | ||
| 13 | /// | ||
| 14 | /// **Note**: this implementation uses a busy loop to poll the value, | ||
| 15 | /// which is not as efficient as registering a dedicated `Waker`. | ||
| 16 | /// However, the if the usecase for is to initialize a static variable | ||
| 17 | /// relatively early in the program life cycle, it should be fine. | ||
| 18 | /// | ||
| 19 | /// # Example | ||
| 20 | /// ``` | ||
| 21 | /// use futures_executor::block_on; | ||
| 22 | /// use embassy_sync::once_lock::OnceLock; | ||
| 23 | /// | ||
| 24 | /// // Define a static value that will be lazily initialized | ||
| 25 | /// static VALUE: OnceLock<u32> = OnceLock::new(); | ||
| 26 | /// | ||
| 27 | /// let f = async { | ||
| 28 | /// | ||
| 29 | /// // Initialize the value | ||
| 30 | /// let reference = VALUE.get_or_init(|| 20); | ||
| 31 | /// assert_eq!(reference, &20); | ||
| 32 | /// | ||
| 33 | /// // Wait for the value to be initialized | ||
| 34 | /// // and get a static reference it | ||
| 35 | /// assert_eq!(VALUE.get().await, &20); | ||
| 36 | /// | ||
| 37 | /// }; | ||
| 38 | /// block_on(f) | ||
| 39 | /// ``` | ||
| 40 | pub struct OnceLock<T> { | ||
| 41 | init: AtomicBool, | ||
| 42 | data: Cell<MaybeUninit<T>>, | ||
| 43 | } | ||
| 44 | |||
| 45 | unsafe impl<T> Sync for OnceLock<T> {} | ||
| 46 | |||
| 47 | impl<T> OnceLock<T> { | ||
| 48 | /// Create a new uninitialized `OnceLock`. | ||
| 49 | pub const fn new() -> Self { | ||
| 50 | Self { | ||
| 51 | init: AtomicBool::new(false), | ||
| 52 | data: Cell::new(MaybeUninit::zeroed()), | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | /// Get a reference to the underlying value, waiting for it to be set. | ||
| 57 | /// If the value is already set, this will return immediately. | ||
| 58 | pub async fn get(&self) -> &T { | ||
| 59 | poll_fn(|cx| match self.try_get() { | ||
| 60 | Some(data) => Poll::Ready(data), | ||
| 61 | None => { | ||
| 62 | cx.waker().wake_by_ref(); | ||
| 63 | Poll::Pending | ||
| 64 | } | ||
| 65 | }) | ||
| 66 | .await | ||
| 67 | } | ||
| 68 | |||
| 69 | /// Try to get a reference to the underlying value if it exists. | ||
| 70 | pub fn try_get(&self) -> Option<&T> { | ||
| 71 | if self.init.load(Ordering::Relaxed) { | ||
| 72 | Some(unsafe { self.get_ref_unchecked() }) | ||
| 73 | } else { | ||
| 74 | None | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | /// Set the underlying value. If the value is already set, this will return an error with the given value. | ||
| 79 | pub fn init(&self, value: T) -> Result<(), T> { | ||
| 80 | // Critical section is required to ensure that the value is | ||
| 81 | // not simultaniously initialized elsewhere at the same time. | ||
| 82 | critical_section::with(|_| { | ||
| 83 | // If the value is not set, set it and return Ok. | ||
| 84 | if !self.init.load(Ordering::Relaxed) { | ||
| 85 | self.data.set(MaybeUninit::new(value)); | ||
| 86 | self.init.store(true, Ordering::Relaxed); | ||
| 87 | Ok(()) | ||
| 88 | |||
| 89 | // Otherwise return an error with the given value. | ||
| 90 | } else { | ||
| 91 | Err(value) | ||
| 92 | } | ||
| 93 | }) | ||
| 94 | } | ||
| 95 | |||
| 96 | /// Get a reference to the underlying value, initializing it if it does not exist. | ||
| 97 | pub fn get_or_init<F>(&self, f: F) -> &T | ||
| 98 | where | ||
| 99 | F: FnOnce() -> T, | ||
| 100 | { | ||
| 101 | // Critical section is required to ensure that the value is | ||
| 102 | // not simultaniously initialized elsewhere at the same time. | ||
| 103 | critical_section::with(|_| { | ||
| 104 | // If the value is not set, set it. | ||
| 105 | if !self.init.load(Ordering::Relaxed) { | ||
| 106 | self.data.set(MaybeUninit::new(f())); | ||
| 107 | self.init.store(true, Ordering::Relaxed); | ||
| 108 | } | ||
| 109 | }); | ||
| 110 | |||
| 111 | // Return a reference to the value. | ||
| 112 | unsafe { self.get_ref_unchecked() } | ||
| 113 | } | ||
| 114 | |||
| 115 | /// Consume the `OnceLock`, returning the underlying value if it was initialized. | ||
| 116 | pub fn into_inner(self) -> Option<T> { | ||
| 117 | if self.init.load(Ordering::Relaxed) { | ||
| 118 | Some(unsafe { self.data.into_inner().assume_init() }) | ||
| 119 | } else { | ||
| 120 | None | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | /// Take the underlying value if it was initialized, uninitializing the `OnceLock` in the process. | ||
| 125 | pub fn take(&mut self) -> Option<T> { | ||
| 126 | // If the value is set, uninitialize the lock and return the value. | ||
| 127 | critical_section::with(|_| { | ||
| 128 | if self.init.load(Ordering::Relaxed) { | ||
| 129 | let val = unsafe { self.data.replace(MaybeUninit::zeroed()).assume_init() }; | ||
| 130 | self.init.store(false, Ordering::Relaxed); | ||
| 131 | Some(val) | ||
| 132 | |||
| 133 | // Otherwise return None. | ||
| 134 | } else { | ||
| 135 | None | ||
| 136 | } | ||
| 137 | }) | ||
| 138 | } | ||
| 139 | |||
| 140 | /// Check if the value has been set. | ||
| 141 | pub fn is_set(&self) -> bool { | ||
| 142 | self.init.load(Ordering::Relaxed) | ||
| 143 | } | ||
| 144 | |||
| 145 | /// Get a reference to the underlying value. | ||
| 146 | /// # Safety | ||
| 147 | /// Must only be used if a value has been set. | ||
| 148 | unsafe fn get_ref_unchecked(&self) -> &T { | ||
| 149 | (*self.data.as_ptr()).assume_init_ref() | ||
| 150 | } | ||
| 151 | } | ||
| 152 | |||
| 153 | #[cfg(test)] | ||
| 154 | mod tests { | ||
| 155 | use super::*; | ||
| 156 | |||
| 157 | #[test] | ||
| 158 | fn once_lock() { | ||
| 159 | let lock = OnceLock::new(); | ||
| 160 | assert_eq!(lock.try_get(), None); | ||
| 161 | assert_eq!(lock.is_set(), false); | ||
| 162 | |||
| 163 | let v = 42; | ||
| 164 | assert_eq!(lock.init(v), Ok(())); | ||
| 165 | assert_eq!(lock.is_set(), true); | ||
| 166 | assert_eq!(lock.try_get(), Some(&v)); | ||
| 167 | assert_eq!(lock.try_get(), Some(&v)); | ||
| 168 | |||
| 169 | let v = 43; | ||
| 170 | assert_eq!(lock.init(v), Err(v)); | ||
| 171 | assert_eq!(lock.is_set(), true); | ||
| 172 | assert_eq!(lock.try_get(), Some(&42)); | ||
| 173 | } | ||
| 174 | |||
| 175 | #[test] | ||
| 176 | fn once_lock_get_or_init() { | ||
| 177 | let lock = OnceLock::new(); | ||
| 178 | assert_eq!(lock.try_get(), None); | ||
| 179 | assert_eq!(lock.is_set(), false); | ||
| 180 | |||
| 181 | let v = lock.get_or_init(|| 42); | ||
| 182 | assert_eq!(v, &42); | ||
| 183 | assert_eq!(lock.is_set(), true); | ||
| 184 | assert_eq!(lock.try_get(), Some(&42)); | ||
| 185 | |||
| 186 | let v = lock.get_or_init(|| 43); | ||
| 187 | assert_eq!(v, &42); | ||
| 188 | assert_eq!(lock.is_set(), true); | ||
| 189 | assert_eq!(lock.try_get(), Some(&42)); | ||
| 190 | } | ||
| 191 | |||
| 192 | #[test] | ||
| 193 | fn once_lock_static() { | ||
| 194 | static LOCK: OnceLock<i32> = OnceLock::new(); | ||
| 195 | |||
| 196 | let v: &'static i32 = LOCK.get_or_init(|| 42); | ||
| 197 | assert_eq!(v, &42); | ||
| 198 | |||
| 199 | let v: &'static i32 = LOCK.get_or_init(|| 43); | ||
| 200 | assert_eq!(v, &42); | ||
| 201 | } | ||
| 202 | |||
| 203 | #[futures_test::test] | ||
| 204 | async fn once_lock_async() { | ||
| 205 | static LOCK: OnceLock<i32> = OnceLock::new(); | ||
| 206 | |||
| 207 | assert!(LOCK.init(42).is_ok()); | ||
| 208 | |||
| 209 | let v: &'static i32 = LOCK.get().await; | ||
| 210 | assert_eq!(v, &42); | ||
| 211 | } | ||
| 212 | |||
| 213 | #[test] | ||
| 214 | fn once_lock_into_inner() { | ||
| 215 | let lock: OnceLock<i32> = OnceLock::new(); | ||
| 216 | |||
| 217 | let v = lock.get_or_init(|| 42); | ||
| 218 | assert_eq!(v, &42); | ||
| 219 | |||
| 220 | assert_eq!(lock.into_inner(), Some(42)); | ||
| 221 | } | ||
| 222 | |||
| 223 | #[test] | ||
| 224 | fn once_lock_take_init() { | ||
| 225 | let mut lock: OnceLock<i32> = OnceLock::new(); | ||
| 226 | |||
| 227 | assert_eq!(lock.get_or_init(|| 42), &42); | ||
| 228 | assert_eq!(lock.is_set(), true); | ||
| 229 | |||
| 230 | assert_eq!(lock.take(), Some(42)); | ||
| 231 | assert_eq!(lock.is_set(), false); | ||
| 232 | |||
| 233 | assert_eq!(lock.get_or_init(|| 43), &43); | ||
| 234 | assert_eq!(lock.is_set(), true); | ||
| 235 | } | ||
| 236 | } | ||
diff --git a/embassy-sync/src/signal.rs b/embassy-sync/src/signal.rs index d75750ce7..520f1a896 100644 --- a/embassy-sync/src/signal.rs +++ b/embassy-sync/src/signal.rs | |||
| @@ -125,7 +125,7 @@ where | |||
| 125 | }) | 125 | }) |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | /// non-blocking method to check whether this signal has been signaled. | 128 | /// non-blocking method to check whether this signal has been signaled. This does not clear the signal. |
| 129 | pub fn signaled(&self) -> bool { | 129 | pub fn signaled(&self) -> bool { |
| 130 | self.state.lock(|cell| { | 130 | self.state.lock(|cell| { |
| 131 | let state = cell.replace(State::None); | 131 | let state = cell.replace(State::None); |
diff --git a/embassy-time/src/fmt.rs b/embassy-time/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-time/src/fmt.rs +++ b/embassy-time/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-usb-dfu/src/fmt.rs b/embassy-usb-dfu/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-usb-dfu/src/fmt.rs +++ b/embassy-usb-dfu/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-usb-logger/src/lib.rs b/embassy-usb-logger/src/lib.rs index da5ff0f36..34d1ca663 100644 --- a/embassy-usb-logger/src/lib.rs +++ b/embassy-usb-logger/src/lib.rs | |||
| @@ -16,7 +16,6 @@ type CS = embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | |||
| 16 | /// The logger state containing buffers that must live as long as the USB peripheral. | 16 | /// The logger state containing buffers that must live as long as the USB peripheral. |
| 17 | pub struct LoggerState<'d> { | 17 | pub struct LoggerState<'d> { |
| 18 | state: State<'d>, | 18 | state: State<'d>, |
| 19 | device_descriptor: [u8; 32], | ||
| 20 | config_descriptor: [u8; 128], | 19 | config_descriptor: [u8; 128], |
| 21 | bos_descriptor: [u8; 16], | 20 | bos_descriptor: [u8; 16], |
| 22 | msos_descriptor: [u8; 256], | 21 | msos_descriptor: [u8; 256], |
| @@ -28,7 +27,6 @@ impl<'d> LoggerState<'d> { | |||
| 28 | pub fn new() -> Self { | 27 | pub fn new() -> Self { |
| 29 | Self { | 28 | Self { |
| 30 | state: State::new(), | 29 | state: State::new(), |
| 31 | device_descriptor: [0; 32], | ||
| 32 | config_descriptor: [0; 128], | 30 | config_descriptor: [0; 128], |
| 33 | bos_descriptor: [0; 16], | 31 | bos_descriptor: [0; 16], |
| 34 | msos_descriptor: [0; 256], | 32 | msos_descriptor: [0; 256], |
| @@ -74,7 +72,6 @@ impl<const N: usize> UsbLogger<N> { | |||
| 74 | let mut builder = Builder::new( | 72 | let mut builder = Builder::new( |
| 75 | driver, | 73 | driver, |
| 76 | config, | 74 | config, |
| 77 | &mut state.device_descriptor, | ||
| 78 | &mut state.config_descriptor, | 75 | &mut state.config_descriptor, |
| 79 | &mut state.bos_descriptor, | 76 | &mut state.bos_descriptor, |
| 80 | &mut state.msos_descriptor, | 77 | &mut state.msos_descriptor, |
| @@ -151,7 +148,17 @@ struct Writer<'d, const N: usize>(&'d Pipe<CS, N>); | |||
| 151 | 148 | ||
| 152 | impl<'d, const N: usize> core::fmt::Write for Writer<'d, N> { | 149 | impl<'d, const N: usize> core::fmt::Write for Writer<'d, N> { |
| 153 | fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { | 150 | fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { |
| 154 | let _ = self.0.try_write(s.as_bytes()); | 151 | // The Pipe is implemented in such way that we cannot |
| 152 | // write across the wraparound discontinuity. | ||
| 153 | let b = s.as_bytes(); | ||
| 154 | if let Ok(n) = self.0.try_write(b) { | ||
| 155 | if n < b.len() { | ||
| 156 | // We wrote some data but not all, attempt again | ||
| 157 | // as the reason might be a wraparound in the | ||
| 158 | // ring buffer, which resolves on second attempt. | ||
| 159 | let _ = self.0.try_write(&b[n..]); | ||
| 160 | } | ||
| 161 | } | ||
| 155 | Ok(()) | 162 | Ok(()) |
| 156 | } | 163 | } |
| 157 | } | 164 | } |
diff --git a/embassy-usb/src/builder.rs b/embassy-usb/src/builder.rs index c4705d041..c06107396 100644 --- a/embassy-usb/src/builder.rs +++ b/embassy-usb/src/builder.rs | |||
| @@ -128,7 +128,6 @@ pub struct Builder<'d, D: Driver<'d>> { | |||
| 128 | driver: D, | 128 | driver: D, |
| 129 | next_string_index: u8, | 129 | next_string_index: u8, |
| 130 | 130 | ||
| 131 | device_descriptor: DescriptorWriter<'d>, | ||
| 132 | config_descriptor: DescriptorWriter<'d>, | 131 | config_descriptor: DescriptorWriter<'d>, |
| 133 | bos_descriptor: BosWriter<'d>, | 132 | bos_descriptor: BosWriter<'d>, |
| 134 | 133 | ||
| @@ -144,7 +143,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 144 | pub fn new( | 143 | pub fn new( |
| 145 | driver: D, | 144 | driver: D, |
| 146 | config: Config<'d>, | 145 | config: Config<'d>, |
| 147 | device_descriptor_buf: &'d mut [u8], | ||
| 148 | config_descriptor_buf: &'d mut [u8], | 146 | config_descriptor_buf: &'d mut [u8], |
| 149 | bos_descriptor_buf: &'d mut [u8], | 147 | bos_descriptor_buf: &'d mut [u8], |
| 150 | msos_descriptor_buf: &'d mut [u8], | 148 | msos_descriptor_buf: &'d mut [u8], |
| @@ -167,11 +165,9 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 167 | _ => panic!("invalid max_packet_size_0, the allowed values are 8, 16, 32 or 64"), | 165 | _ => panic!("invalid max_packet_size_0, the allowed values are 8, 16, 32 or 64"), |
| 168 | } | 166 | } |
| 169 | 167 | ||
| 170 | let mut device_descriptor = DescriptorWriter::new(device_descriptor_buf); | ||
| 171 | let mut config_descriptor = DescriptorWriter::new(config_descriptor_buf); | 168 | let mut config_descriptor = DescriptorWriter::new(config_descriptor_buf); |
| 172 | let mut bos_descriptor = BosWriter::new(DescriptorWriter::new(bos_descriptor_buf)); | 169 | let mut bos_descriptor = BosWriter::new(DescriptorWriter::new(bos_descriptor_buf)); |
| 173 | 170 | ||
| 174 | device_descriptor.device(&config); | ||
| 175 | config_descriptor.configuration(&config); | 171 | config_descriptor.configuration(&config); |
| 176 | bos_descriptor.bos(); | 172 | bos_descriptor.bos(); |
| 177 | 173 | ||
| @@ -183,7 +179,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 183 | control_buf, | 179 | control_buf, |
| 184 | next_string_index: STRING_INDEX_CUSTOM_START, | 180 | next_string_index: STRING_INDEX_CUSTOM_START, |
| 185 | 181 | ||
| 186 | device_descriptor, | ||
| 187 | config_descriptor, | 182 | config_descriptor, |
| 188 | bos_descriptor, | 183 | bos_descriptor, |
| 189 | 184 | ||
| @@ -199,7 +194,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 199 | self.bos_descriptor.end_bos(); | 194 | self.bos_descriptor.end_bos(); |
| 200 | 195 | ||
| 201 | // Log the number of allocator bytes actually used in descriptor buffers | 196 | // Log the number of allocator bytes actually used in descriptor buffers |
| 202 | info!("USB: device_descriptor used: {}", self.device_descriptor.position()); | ||
| 203 | info!("USB: config_descriptor used: {}", self.config_descriptor.position()); | 197 | info!("USB: config_descriptor used: {}", self.config_descriptor.position()); |
| 204 | info!("USB: bos_descriptor used: {}", self.bos_descriptor.writer.position()); | 198 | info!("USB: bos_descriptor used: {}", self.bos_descriptor.writer.position()); |
| 205 | info!("USB: msos_descriptor used: {}", msos_descriptor.len()); | 199 | info!("USB: msos_descriptor used: {}", msos_descriptor.len()); |
| @@ -209,7 +203,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> { | |||
| 209 | self.driver, | 203 | self.driver, |
| 210 | self.config, | 204 | self.config, |
| 211 | self.handlers, | 205 | self.handlers, |
| 212 | self.device_descriptor.into_buf(), | ||
| 213 | self.config_descriptor.into_buf(), | 206 | self.config_descriptor.into_buf(), |
| 214 | self.bos_descriptor.writer.into_buf(), | 207 | self.bos_descriptor.writer.into_buf(), |
| 215 | msos_descriptor, | 208 | msos_descriptor, |
diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index fa83ef583..eb3d1f53a 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs | |||
| @@ -82,30 +82,6 @@ impl<'a> DescriptorWriter<'a> { | |||
| 82 | self.position = start + length; | 82 | self.position = start + length; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | pub(crate) fn device(&mut self, config: &Config) { | ||
| 86 | self.write( | ||
| 87 | descriptor_type::DEVICE, | ||
| 88 | &[ | ||
| 89 | 0x10, | ||
| 90 | 0x02, // bcdUSB 2.1 | ||
| 91 | config.device_class, // bDeviceClass | ||
| 92 | config.device_sub_class, // bDeviceSubClass | ||
| 93 | config.device_protocol, // bDeviceProtocol | ||
| 94 | config.max_packet_size_0, // bMaxPacketSize0 | ||
| 95 | config.vendor_id as u8, | ||
| 96 | (config.vendor_id >> 8) as u8, // idVendor | ||
| 97 | config.product_id as u8, | ||
| 98 | (config.product_id >> 8) as u8, // idProduct | ||
| 99 | config.device_release as u8, | ||
| 100 | (config.device_release >> 8) as u8, // bcdDevice | ||
| 101 | config.manufacturer.map_or(0, |_| 1), // iManufacturer | ||
| 102 | config.product.map_or(0, |_| 2), // iProduct | ||
| 103 | config.serial_number.map_or(0, |_| 3), // iSerialNumber | ||
| 104 | 1, // bNumConfigurations | ||
| 105 | ], | ||
| 106 | ); | ||
| 107 | } | ||
| 108 | |||
| 109 | pub(crate) fn configuration(&mut self, config: &Config) { | 85 | pub(crate) fn configuration(&mut self, config: &Config) { |
| 110 | self.num_interfaces_mark = Some(self.position + 4); | 86 | self.num_interfaces_mark = Some(self.position + 4); |
| 111 | 87 | ||
| @@ -269,6 +245,33 @@ impl<'a> DescriptorWriter<'a> { | |||
| 269 | } | 245 | } |
| 270 | } | 246 | } |
| 271 | 247 | ||
| 248 | /// Create a new Device Descriptor array. | ||
| 249 | /// | ||
| 250 | /// All device descriptors are always 18 bytes, so there's no need for | ||
| 251 | /// a variable-length buffer or DescriptorWriter. | ||
| 252 | pub(crate) fn device_descriptor(config: &Config) -> [u8; 18] { | ||
| 253 | [ | ||
| 254 | 18, // bLength | ||
| 255 | 0x01, // bDescriptorType | ||
| 256 | 0x10, | ||
| 257 | 0x02, // bcdUSB 2.1 | ||
| 258 | config.device_class, // bDeviceClass | ||
| 259 | config.device_sub_class, // bDeviceSubClass | ||
| 260 | config.device_protocol, // bDeviceProtocol | ||
| 261 | config.max_packet_size_0, // bMaxPacketSize0 | ||
| 262 | config.vendor_id as u8, | ||
| 263 | (config.vendor_id >> 8) as u8, // idVendor | ||
| 264 | config.product_id as u8, | ||
| 265 | (config.product_id >> 8) as u8, // idProduct | ||
| 266 | config.device_release as u8, | ||
| 267 | (config.device_release >> 8) as u8, // bcdDevice | ||
| 268 | config.manufacturer.map_or(0, |_| 1), // iManufacturer | ||
| 269 | config.product.map_or(0, |_| 2), // iProduct | ||
| 270 | config.serial_number.map_or(0, |_| 3), // iSerialNumber | ||
| 271 | 1, // bNumConfigurations | ||
| 272 | ] | ||
| 273 | } | ||
| 274 | |||
| 272 | /// A writer for Binary Object Store descriptor. | 275 | /// A writer for Binary Object Store descriptor. |
| 273 | pub struct BosWriter<'a> { | 276 | pub struct BosWriter<'a> { |
| 274 | pub(crate) writer: DescriptorWriter<'a>, | 277 | pub(crate) writer: DescriptorWriter<'a>, |
diff --git a/embassy-usb/src/fmt.rs b/embassy-usb/src/fmt.rs index 78e583c1c..2ac42c557 100644 --- a/embassy-usb/src/fmt.rs +++ b/embassy-usb/src/fmt.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | #![allow(unused_macros)] | 2 | #![allow(unused)] |
| 3 | 3 | ||
| 4 | use core::fmt::{Debug, Display, LowerHex}; | 4 | use core::fmt::{Debug, Display, LowerHex}; |
| 5 | 5 | ||
| @@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> { | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | #[allow(unused)] | ||
| 233 | pub(crate) struct Bytes<'a>(pub &'a [u8]); | 232 | pub(crate) struct Bytes<'a>(pub &'a [u8]); |
| 234 | 233 | ||
| 235 | impl<'a> Debug for Bytes<'a> { | 234 | impl<'a> Debug for Bytes<'a> { |
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 241e33a78..d58950838 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs | |||
| @@ -168,8 +168,6 @@ struct Interface { | |||
| 168 | #[derive(PartialEq, Eq, Copy, Clone, Debug)] | 168 | #[derive(PartialEq, Eq, Copy, Clone, Debug)] |
| 169 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 169 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 170 | pub struct UsbBufferReport { | 170 | pub struct UsbBufferReport { |
| 171 | /// Number of device descriptor bytes used | ||
| 172 | pub device_descriptor_used: usize, | ||
| 173 | /// Number of config descriptor bytes used | 171 | /// Number of config descriptor bytes used |
| 174 | pub config_descriptor_used: usize, | 172 | pub config_descriptor_used: usize, |
| 175 | /// Number of bos descriptor bytes used | 173 | /// Number of bos descriptor bytes used |
| @@ -191,7 +189,7 @@ struct Inner<'d, D: Driver<'d>> { | |||
| 191 | bus: D::Bus, | 189 | bus: D::Bus, |
| 192 | 190 | ||
| 193 | config: Config<'d>, | 191 | config: Config<'d>, |
| 194 | device_descriptor: &'d [u8], | 192 | device_descriptor: [u8; 18], |
| 195 | config_descriptor: &'d [u8], | 193 | config_descriptor: &'d [u8], |
| 196 | bos_descriptor: &'d [u8], | 194 | bos_descriptor: &'d [u8], |
| 197 | msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, | 195 | msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, |
| @@ -217,7 +215,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 217 | driver: D, | 215 | driver: D, |
| 218 | config: Config<'d>, | 216 | config: Config<'d>, |
| 219 | handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>, | 217 | handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>, |
| 220 | device_descriptor: &'d [u8], | ||
| 221 | config_descriptor: &'d [u8], | 218 | config_descriptor: &'d [u8], |
| 222 | bos_descriptor: &'d [u8], | 219 | bos_descriptor: &'d [u8], |
| 223 | msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, | 220 | msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, |
| @@ -227,6 +224,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 227 | // Start the USB bus. | 224 | // Start the USB bus. |
| 228 | // This prevent further allocation by consuming the driver. | 225 | // This prevent further allocation by consuming the driver. |
| 229 | let (bus, control) = driver.start(config.max_packet_size_0 as u16); | 226 | let (bus, control) = driver.start(config.max_packet_size_0 as u16); |
| 227 | let device_descriptor = descriptor::device_descriptor(&config); | ||
| 230 | 228 | ||
| 231 | Self { | 229 | Self { |
| 232 | control_buf, | 230 | control_buf, |
| @@ -256,7 +254,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { | |||
| 256 | /// Useful for tuning buffer sizes for actual usage | 254 | /// Useful for tuning buffer sizes for actual usage |
| 257 | pub fn buffer_usage(&self) -> UsbBufferReport { | 255 | pub fn buffer_usage(&self) -> UsbBufferReport { |
| 258 | UsbBufferReport { | 256 | UsbBufferReport { |
| 259 | device_descriptor_used: self.inner.device_descriptor.len(), | ||
| 260 | config_descriptor_used: self.inner.config_descriptor.len(), | 257 | config_descriptor_used: self.inner.config_descriptor.len(), |
| 261 | bos_descriptor_used: self.inner.bos_descriptor.len(), | 258 | bos_descriptor_used: self.inner.bos_descriptor.len(), |
| 262 | msos_descriptor_used: self.inner.msos_descriptor.len(), | 259 | msos_descriptor_used: self.inner.msos_descriptor.len(), |
| @@ -720,7 +717,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { | |||
| 720 | 717 | ||
| 721 | match dtype { | 718 | match dtype { |
| 722 | descriptor_type::BOS => InResponse::Accepted(self.bos_descriptor), | 719 | descriptor_type::BOS => InResponse::Accepted(self.bos_descriptor), |
| 723 | descriptor_type::DEVICE => InResponse::Accepted(self.device_descriptor), | 720 | descriptor_type::DEVICE => InResponse::Accepted(&self.device_descriptor), |
| 724 | descriptor_type::CONFIGURATION => InResponse::Accepted(self.config_descriptor), | 721 | descriptor_type::CONFIGURATION => InResponse::Accepted(self.config_descriptor), |
| 725 | descriptor_type::STRING => { | 722 | descriptor_type::STRING => { |
| 726 | if index == 0 { | 723 | if index == 0 { |
diff --git a/embassy-usb/src/msos.rs b/embassy-usb/src/msos.rs index 3858c0f51..25936d084 100644 --- a/embassy-usb/src/msos.rs +++ b/embassy-usb/src/msos.rs | |||
| @@ -226,27 +226,21 @@ pub mod windows_version { | |||
| 226 | pub const WIN10: u32 = 0x0A000000; | 226 | pub const WIN10: u32 = 0x0A000000; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | mod sealed { | 229 | /// A trait for descriptors |
| 230 | use core::mem::size_of; | 230 | trait Descriptor: Sized { |
| 231 | const TYPE: DescriptorType; | ||
| 231 | 232 | ||
| 232 | /// A trait for descriptors | 233 | /// The size of the descriptor's header. |
| 233 | pub trait Descriptor: Sized { | 234 | fn size(&self) -> usize { |
| 234 | const TYPE: super::DescriptorType; | 235 | size_of::<Self>() |
| 235 | |||
| 236 | /// The size of the descriptor's header. | ||
| 237 | fn size(&self) -> usize { | ||
| 238 | size_of::<Self>() | ||
| 239 | } | ||
| 240 | |||
| 241 | fn write_to(&self, buf: &mut [u8]); | ||
| 242 | } | 236 | } |
| 243 | 237 | ||
| 244 | pub trait DescriptorSet: Descriptor { | 238 | fn write_to(&self, buf: &mut [u8]); |
| 245 | const LENGTH_OFFSET: usize; | ||
| 246 | } | ||
| 247 | } | 239 | } |
| 248 | 240 | ||
| 249 | use sealed::*; | 241 | trait DescriptorSet: Descriptor { |
| 242 | const LENGTH_OFFSET: usize; | ||
| 243 | } | ||
| 250 | 244 | ||
| 251 | /// Copies the data of `t` into `buf`. | 245 | /// Copies the data of `t` into `buf`. |
| 252 | /// | 246 | /// |
| @@ -255,7 +249,7 @@ use sealed::*; | |||
| 255 | unsafe fn transmute_write_to<T: Sized>(t: &T, buf: &mut [u8]) { | 249 | unsafe fn transmute_write_to<T: Sized>(t: &T, buf: &mut [u8]) { |
| 256 | let bytes = core::slice::from_raw_parts((t as *const T) as *const u8, size_of::<T>()); | 250 | let bytes = core::slice::from_raw_parts((t as *const T) as *const u8, size_of::<T>()); |
| 257 | assert!(buf.len() >= bytes.len(), "MS OS descriptor buffer full"); | 251 | assert!(buf.len() >= bytes.len(), "MS OS descriptor buffer full"); |
| 258 | (&mut buf[..bytes.len()]).copy_from_slice(bytes); | 252 | buf[..bytes.len()].copy_from_slice(bytes); |
| 259 | } | 253 | } |
| 260 | 254 | ||
| 261 | /// Table 9. Microsoft OS 2.0 descriptor wDescriptorType values. | 255 | /// Table 9. Microsoft OS 2.0 descriptor wDescriptorType values. |
| @@ -412,9 +406,11 @@ impl DescriptorSet for FunctionSubsetHeader { | |||
| 412 | // Feature Descriptors | 406 | // Feature Descriptors |
| 413 | 407 | ||
| 414 | /// A marker trait for feature descriptors that are valid at the device level. | 408 | /// A marker trait for feature descriptors that are valid at the device level. |
| 409 | #[allow(private_bounds)] | ||
| 415 | pub trait DeviceLevelDescriptor: Descriptor {} | 410 | pub trait DeviceLevelDescriptor: Descriptor {} |
| 416 | 411 | ||
| 417 | /// A marker trait for feature descriptors that are valid at the function level. | 412 | /// A marker trait for feature descriptors that are valid at the function level. |
| 413 | #[allow(private_bounds)] | ||
| 418 | pub trait FunctionLevelDescriptor: Descriptor {} | 414 | pub trait FunctionLevelDescriptor: Descriptor {} |
| 419 | 415 | ||
| 420 | /// Table 13. Microsoft OS 2.0 compatible ID descriptor. | 416 | /// Table 13. Microsoft OS 2.0 compatible ID descriptor. |
| @@ -444,9 +440,9 @@ impl CompatibleIdFeatureDescriptor { | |||
| 444 | pub fn new(compatible_id: &str, sub_compatible_id: &str) -> Self { | 440 | pub fn new(compatible_id: &str, sub_compatible_id: &str) -> Self { |
| 445 | assert!(compatible_id.len() <= 8 && sub_compatible_id.len() <= 8); | 441 | assert!(compatible_id.len() <= 8 && sub_compatible_id.len() <= 8); |
| 446 | let mut cid = [0u8; 8]; | 442 | let mut cid = [0u8; 8]; |
| 447 | (&mut cid[..compatible_id.len()]).copy_from_slice(compatible_id.as_bytes()); | 443 | cid[..compatible_id.len()].copy_from_slice(compatible_id.as_bytes()); |
| 448 | let mut scid = [0u8; 8]; | 444 | let mut scid = [0u8; 8]; |
| 449 | (&mut scid[..sub_compatible_id.len()]).copy_from_slice(sub_compatible_id.as_bytes()); | 445 | scid[..sub_compatible_id.len()].copy_from_slice(sub_compatible_id.as_bytes()); |
| 450 | Self::new_raw(cid, scid) | 446 | Self::new_raw(cid, scid) |
| 451 | } | 447 | } |
| 452 | 448 | ||
diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index 37c3d7d90..929d6802c 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs | |||
| @@ -41,7 +41,6 @@ async fn main(_spawner: Spawner) { | |||
| 41 | config.product = Some("USB-DFU Runtime example"); | 41 | config.product = Some("USB-DFU Runtime example"); |
| 42 | config.serial_number = Some("1235678"); | 42 | config.serial_number = Some("1235678"); |
| 43 | 43 | ||
| 44 | let mut device_descriptor = [0; 256]; | ||
| 45 | let mut config_descriptor = [0; 256]; | 44 | let mut config_descriptor = [0; 256]; |
| 46 | let mut bos_descriptor = [0; 256]; | 45 | let mut bos_descriptor = [0; 256]; |
| 47 | let mut control_buf = [0; 64]; | 46 | let mut control_buf = [0; 64]; |
| @@ -49,7 +48,6 @@ async fn main(_spawner: Spawner) { | |||
| 49 | let mut builder = Builder::new( | 48 | let mut builder = Builder::new( |
| 50 | driver, | 49 | driver, |
| 51 | config, | 50 | config, |
| 52 | &mut device_descriptor, | ||
| 53 | &mut config_descriptor, | 51 | &mut config_descriptor, |
| 54 | &mut bos_descriptor, | 52 | &mut bos_descriptor, |
| 55 | &mut [], | 53 | &mut [], |
diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index d989fbfdf..093b39f9d 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs | |||
| @@ -49,7 +49,6 @@ fn main() -> ! { | |||
| 49 | let mut buffer = AlignedBuffer([0; WRITE_SIZE]); | 49 | let mut buffer = AlignedBuffer([0; WRITE_SIZE]); |
| 50 | let updater = BlockingFirmwareUpdater::new(fw_config, &mut buffer.0[..]); | 50 | let updater = BlockingFirmwareUpdater::new(fw_config, &mut buffer.0[..]); |
| 51 | 51 | ||
| 52 | let mut device_descriptor = [0; 256]; | ||
| 53 | let mut config_descriptor = [0; 256]; | 52 | let mut config_descriptor = [0; 256]; |
| 54 | let mut bos_descriptor = [0; 256]; | 53 | let mut bos_descriptor = [0; 256]; |
| 55 | let mut control_buf = [0; 4096]; | 54 | let mut control_buf = [0; 4096]; |
| @@ -57,7 +56,6 @@ fn main() -> ! { | |||
| 57 | let mut builder = Builder::new( | 56 | let mut builder = Builder::new( |
| 58 | driver, | 57 | driver, |
| 59 | config, | 58 | config, |
| 60 | &mut device_descriptor, | ||
| 61 | &mut config_descriptor, | 59 | &mut config_descriptor, |
| 62 | &mut bos_descriptor, | 60 | &mut bos_descriptor, |
| 63 | &mut [], | 61 | &mut [], |
diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index 3469c6e5f..a7e5c2668 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs | |||
| @@ -70,7 +70,6 @@ async fn main(spawner: Spawner) { | |||
| 70 | config.device_protocol = 0x01; | 70 | config.device_protocol = 0x01; |
| 71 | 71 | ||
| 72 | // Create embassy-usb DeviceBuilder using the driver and config. | 72 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 73 | static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 74 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 73 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 75 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 74 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 76 | static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); | 75 | static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); |
| @@ -78,7 +77,6 @@ async fn main(spawner: Spawner) { | |||
| 78 | let mut builder = Builder::new( | 77 | let mut builder = Builder::new( |
| 79 | driver, | 78 | driver, |
| 80 | config, | 79 | config, |
| 81 | &mut DEVICE_DESC.init([0; 256])[..], | ||
| 82 | &mut CONFIG_DESC.init([0; 256])[..], | 80 | &mut CONFIG_DESC.init([0; 256])[..], |
| 83 | &mut BOS_DESC.init([0; 256])[..], | 81 | &mut BOS_DESC.init([0; 256])[..], |
| 84 | &mut MSOS_DESC.init([0; 128])[..], | 82 | &mut MSOS_DESC.init([0; 128])[..], |
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs index 3e86590c4..52f081487 100644 --- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs | |||
| @@ -50,7 +50,6 @@ async fn main(_spawner: Spawner) { | |||
| 50 | 50 | ||
| 51 | // Create embassy-usb DeviceBuilder using the driver and config. | 51 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 52 | // It needs some buffers for building the descriptors. | 52 | // It needs some buffers for building the descriptors. |
| 53 | let mut device_descriptor = [0; 256]; | ||
| 54 | let mut config_descriptor = [0; 256]; | 53 | let mut config_descriptor = [0; 256]; |
| 55 | let mut bos_descriptor = [0; 256]; | 54 | let mut bos_descriptor = [0; 256]; |
| 56 | let mut msos_descriptor = [0; 256]; | 55 | let mut msos_descriptor = [0; 256]; |
| @@ -63,7 +62,6 @@ async fn main(_spawner: Spawner) { | |||
| 63 | let mut builder = Builder::new( | 62 | let mut builder = Builder::new( |
| 64 | driver, | 63 | driver, |
| 65 | config, | 64 | config, |
| 66 | &mut device_descriptor, | ||
| 67 | &mut config_descriptor, | 65 | &mut config_descriptor, |
| 68 | &mut bos_descriptor, | 66 | &mut bos_descriptor, |
| 69 | &mut msos_descriptor, | 67 | &mut msos_descriptor, |
diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index 04ad841b7..5d2837793 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs | |||
| @@ -43,7 +43,6 @@ async fn main(_spawner: Spawner) { | |||
| 43 | 43 | ||
| 44 | // Create embassy-usb DeviceBuilder using the driver and config. | 44 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 45 | // It needs some buffers for building the descriptors. | 45 | // It needs some buffers for building the descriptors. |
| 46 | let mut device_descriptor = [0; 256]; | ||
| 47 | let mut config_descriptor = [0; 256]; | 46 | let mut config_descriptor = [0; 256]; |
| 48 | let mut bos_descriptor = [0; 256]; | 47 | let mut bos_descriptor = [0; 256]; |
| 49 | let mut msos_descriptor = [0; 256]; | 48 | let mut msos_descriptor = [0; 256]; |
| @@ -55,7 +54,6 @@ async fn main(_spawner: Spawner) { | |||
| 55 | let mut builder = Builder::new( | 54 | let mut builder = Builder::new( |
| 56 | driver, | 55 | driver, |
| 57 | config, | 56 | config, |
| 58 | &mut device_descriptor, | ||
| 59 | &mut config_descriptor, | 57 | &mut config_descriptor, |
| 60 | &mut bos_descriptor, | 58 | &mut bos_descriptor, |
| 61 | &mut msos_descriptor, | 59 | &mut msos_descriptor, |
diff --git a/examples/nrf52840/src/bin/usb_serial.rs b/examples/nrf52840/src/bin/usb_serial.rs index aff539b1b..02048e692 100644 --- a/examples/nrf52840/src/bin/usb_serial.rs +++ b/examples/nrf52840/src/bin/usb_serial.rs | |||
| @@ -48,7 +48,6 @@ async fn main(_spawner: Spawner) { | |||
| 48 | 48 | ||
| 49 | // Create embassy-usb DeviceBuilder using the driver and config. | 49 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 50 | // It needs some buffers for building the descriptors. | 50 | // It needs some buffers for building the descriptors. |
| 51 | let mut device_descriptor = [0; 256]; | ||
| 52 | let mut config_descriptor = [0; 256]; | 51 | let mut config_descriptor = [0; 256]; |
| 53 | let mut bos_descriptor = [0; 256]; | 52 | let mut bos_descriptor = [0; 256]; |
| 54 | let mut msos_descriptor = [0; 256]; | 53 | let mut msos_descriptor = [0; 256]; |
| @@ -59,7 +58,6 @@ async fn main(_spawner: Spawner) { | |||
| 59 | let mut builder = Builder::new( | 58 | let mut builder = Builder::new( |
| 60 | driver, | 59 | driver, |
| 61 | config, | 60 | config, |
| 62 | &mut device_descriptor, | ||
| 63 | &mut config_descriptor, | 61 | &mut config_descriptor, |
| 64 | &mut bos_descriptor, | 62 | &mut bos_descriptor, |
| 65 | &mut msos_descriptor, | 63 | &mut msos_descriptor, |
diff --git a/examples/nrf52840/src/bin/usb_serial_multitask.rs b/examples/nrf52840/src/bin/usb_serial_multitask.rs index 4e8118fb8..895cca8b9 100644 --- a/examples/nrf52840/src/bin/usb_serial_multitask.rs +++ b/examples/nrf52840/src/bin/usb_serial_multitask.rs | |||
| @@ -67,7 +67,6 @@ async fn main(spawner: Spawner) { | |||
| 67 | let state = STATE.init(State::new()); | 67 | let state = STATE.init(State::new()); |
| 68 | 68 | ||
| 69 | // Create embassy-usb DeviceBuilder using the driver and config. | 69 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 70 | static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 71 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 70 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 72 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 71 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 73 | static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); | 72 | static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new(); |
| @@ -75,7 +74,6 @@ async fn main(spawner: Spawner) { | |||
| 75 | let mut builder = Builder::new( | 74 | let mut builder = Builder::new( |
| 76 | driver, | 75 | driver, |
| 77 | config, | 76 | config, |
| 78 | &mut DEVICE_DESC.init([0; 256])[..], | ||
| 79 | &mut CONFIG_DESC.init([0; 256])[..], | 77 | &mut CONFIG_DESC.init([0; 256])[..], |
| 80 | &mut BOS_DESC.init([0; 256])[..], | 78 | &mut BOS_DESC.init([0; 256])[..], |
| 81 | &mut MSOS_DESC.init([0; 128])[..], | 79 | &mut MSOS_DESC.init([0; 128])[..], |
diff --git a/examples/nrf52840/src/bin/usb_serial_winusb.rs b/examples/nrf52840/src/bin/usb_serial_winusb.rs index 060f9ba94..c6675a3d3 100644 --- a/examples/nrf52840/src/bin/usb_serial_winusb.rs +++ b/examples/nrf52840/src/bin/usb_serial_winusb.rs | |||
| @@ -53,7 +53,6 @@ async fn main(_spawner: Spawner) { | |||
| 53 | 53 | ||
| 54 | // Create embassy-usb DeviceBuilder using the driver and config. | 54 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 55 | // It needs some buffers for building the descriptors. | 55 | // It needs some buffers for building the descriptors. |
| 56 | let mut device_descriptor = [0; 256]; | ||
| 57 | let mut config_descriptor = [0; 256]; | 56 | let mut config_descriptor = [0; 256]; |
| 58 | let mut bos_descriptor = [0; 256]; | 57 | let mut bos_descriptor = [0; 256]; |
| 59 | let mut msos_descriptor = [0; 256]; | 58 | let mut msos_descriptor = [0; 256]; |
| @@ -64,7 +63,6 @@ async fn main(_spawner: Spawner) { | |||
| 64 | let mut builder = Builder::new( | 63 | let mut builder = Builder::new( |
| 65 | driver, | 64 | driver, |
| 66 | config, | 65 | config, |
| 67 | &mut device_descriptor, | ||
| 68 | &mut config_descriptor, | 66 | &mut config_descriptor, |
| 69 | &mut bos_descriptor, | 67 | &mut bos_descriptor, |
| 70 | &mut msos_descriptor, | 68 | &mut msos_descriptor, |
diff --git a/examples/rp/src/bin/multicore.rs b/examples/rp/src/bin/multicore.rs index c7b087476..7cb546c91 100644 --- a/examples/rp/src/bin/multicore.rs +++ b/examples/rp/src/bin/multicore.rs | |||
| @@ -30,10 +30,14 @@ fn main() -> ! { | |||
| 30 | let p = embassy_rp::init(Default::default()); | 30 | let p = embassy_rp::init(Default::default()); |
| 31 | let led = Output::new(p.PIN_25, Level::Low); | 31 | let led = Output::new(p.PIN_25, Level::Low); |
| 32 | 32 | ||
| 33 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 33 | spawn_core1( |
| 34 | let executor1 = EXECUTOR1.init(Executor::new()); | 34 | p.CORE1, |
| 35 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led)))); | 35 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 36 | }); | 36 | move || { |
| 37 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 38 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led)))); | ||
| 39 | }, | ||
| 40 | ); | ||
| 37 | 41 | ||
| 38 | let executor0 = EXECUTOR0.init(Executor::new()); | 42 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 39 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); | 43 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); |
diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs index a07f1c180..53b696309 100644 --- a/examples/rp/src/bin/pio_uart.rs +++ b/examples/rp/src/bin/pio_uart.rs | |||
| @@ -60,7 +60,6 @@ async fn main(_spawner: Spawner) { | |||
| 60 | 60 | ||
| 61 | // Create embassy-usb DeviceBuilder using the driver and config. | 61 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 62 | // It needs some buffers for building the descriptors. | 62 | // It needs some buffers for building the descriptors. |
| 63 | let mut device_descriptor = [0; 256]; | ||
| 64 | let mut config_descriptor = [0; 256]; | 63 | let mut config_descriptor = [0; 256]; |
| 65 | let mut bos_descriptor = [0; 256]; | 64 | let mut bos_descriptor = [0; 256]; |
| 66 | let mut control_buf = [0; 64]; | 65 | let mut control_buf = [0; 64]; |
| @@ -70,7 +69,6 @@ async fn main(_spawner: Spawner) { | |||
| 70 | let mut builder = Builder::new( | 69 | let mut builder = Builder::new( |
| 71 | driver, | 70 | driver, |
| 72 | config, | 71 | config, |
| 73 | &mut device_descriptor, | ||
| 74 | &mut config_descriptor, | 72 | &mut config_descriptor, |
| 75 | &mut bos_descriptor, | 73 | &mut bos_descriptor, |
| 76 | &mut [], // no msos descriptors | 74 | &mut [], // no msos descriptors |
diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index 01f0d5967..f1b124efa 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs | |||
| @@ -64,14 +64,12 @@ async fn main(spawner: Spawner) { | |||
| 64 | config.device_protocol = 0x01; | 64 | config.device_protocol = 0x01; |
| 65 | 65 | ||
| 66 | // Create embassy-usb DeviceBuilder using the driver and config. | 66 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 67 | static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 68 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 67 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 69 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 68 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 70 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | 69 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); |
| 71 | let mut builder = Builder::new( | 70 | let mut builder = Builder::new( |
| 72 | driver, | 71 | driver, |
| 73 | config, | 72 | config, |
| 74 | &mut DEVICE_DESC.init([0; 256])[..], | ||
| 75 | &mut CONFIG_DESC.init([0; 256])[..], | 73 | &mut CONFIG_DESC.init([0; 256])[..], |
| 76 | &mut BOS_DESC.init([0; 256])[..], | 74 | &mut BOS_DESC.init([0; 256])[..], |
| 77 | &mut [], // no msos descriptors | 75 | &mut [], // no msos descriptors |
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs index b5ac16245..710be8d13 100644 --- a/examples/rp/src/bin/usb_hid_keyboard.rs +++ b/examples/rp/src/bin/usb_hid_keyboard.rs | |||
| @@ -36,7 +36,6 @@ async fn main(_spawner: Spawner) { | |||
| 36 | 36 | ||
| 37 | // Create embassy-usb DeviceBuilder using the driver and config. | 37 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 38 | // It needs some buffers for building the descriptors. | 38 | // It needs some buffers for building the descriptors. |
| 39 | let mut device_descriptor = [0; 256]; | ||
| 40 | let mut config_descriptor = [0; 256]; | 39 | let mut config_descriptor = [0; 256]; |
| 41 | let mut bos_descriptor = [0; 256]; | 40 | let mut bos_descriptor = [0; 256]; |
| 42 | // You can also add a Microsoft OS descriptor. | 41 | // You can also add a Microsoft OS descriptor. |
| @@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) { | |||
| 50 | let mut builder = Builder::new( | 49 | let mut builder = Builder::new( |
| 51 | driver, | 50 | driver, |
| 52 | config, | 51 | config, |
| 53 | &mut device_descriptor, | ||
| 54 | &mut config_descriptor, | 52 | &mut config_descriptor, |
| 55 | &mut bos_descriptor, | 53 | &mut bos_descriptor, |
| 56 | &mut msos_descriptor, | 54 | &mut msos_descriptor, |
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs index afebd8813..e8b399cb1 100644 --- a/examples/rp/src/bin/usb_hid_mouse.rs +++ b/examples/rp/src/bin/usb_hid_mouse.rs | |||
| @@ -39,7 +39,6 @@ async fn main(_spawner: Spawner) { | |||
| 39 | 39 | ||
| 40 | // Create embassy-usb DeviceBuilder using the driver and config. | 40 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 41 | // It needs some buffers for building the descriptors. | 41 | // It needs some buffers for building the descriptors. |
| 42 | let mut device_descriptor = [0; 256]; | ||
| 43 | let mut config_descriptor = [0; 256]; | 42 | let mut config_descriptor = [0; 256]; |
| 44 | let mut bos_descriptor = [0; 256]; | 43 | let mut bos_descriptor = [0; 256]; |
| 45 | // You can also add a Microsoft OS descriptor. | 44 | // You can also add a Microsoft OS descriptor. |
| @@ -53,7 +52,6 @@ async fn main(_spawner: Spawner) { | |||
| 53 | let mut builder = Builder::new( | 52 | let mut builder = Builder::new( |
| 54 | driver, | 53 | driver, |
| 55 | config, | 54 | config, |
| 56 | &mut device_descriptor, | ||
| 57 | &mut config_descriptor, | 55 | &mut config_descriptor, |
| 58 | &mut bos_descriptor, | 56 | &mut bos_descriptor, |
| 59 | &mut msos_descriptor, | 57 | &mut msos_descriptor, |
diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs index 95306a35c..11db1b2e1 100644 --- a/examples/rp/src/bin/usb_midi.rs +++ b/examples/rp/src/bin/usb_midi.rs | |||
| @@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) { | |||
| 46 | 46 | ||
| 47 | // Create embassy-usb DeviceBuilder using the driver and config. | 47 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 48 | // It needs some buffers for building the descriptors. | 48 | // It needs some buffers for building the descriptors. |
| 49 | let mut device_descriptor = [0; 256]; | ||
| 50 | let mut config_descriptor = [0; 256]; | 49 | let mut config_descriptor = [0; 256]; |
| 51 | let mut bos_descriptor = [0; 256]; | 50 | let mut bos_descriptor = [0; 256]; |
| 52 | let mut control_buf = [0; 64]; | 51 | let mut control_buf = [0; 64]; |
| @@ -54,7 +53,6 @@ async fn main(_spawner: Spawner) { | |||
| 54 | let mut builder = Builder::new( | 53 | let mut builder = Builder::new( |
| 55 | driver, | 54 | driver, |
| 56 | config, | 55 | config, |
| 57 | &mut device_descriptor, | ||
| 58 | &mut config_descriptor, | 56 | &mut config_descriptor, |
| 59 | &mut bos_descriptor, | 57 | &mut bos_descriptor, |
| 60 | &mut [], // no msos descriptors | 58 | &mut [], // no msos descriptors |
diff --git a/examples/rp/src/bin/usb_raw.rs b/examples/rp/src/bin/usb_raw.rs index a6c8a5b2e..97e7e0244 100644 --- a/examples/rp/src/bin/usb_raw.rs +++ b/examples/rp/src/bin/usb_raw.rs | |||
| @@ -93,7 +93,6 @@ async fn main(_spawner: Spawner) { | |||
| 93 | 93 | ||
| 94 | // Create embassy-usb DeviceBuilder using the driver and config. | 94 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 95 | // It needs some buffers for building the descriptors. | 95 | // It needs some buffers for building the descriptors. |
| 96 | let mut device_descriptor = [0; 256]; | ||
| 97 | let mut config_descriptor = [0; 256]; | 96 | let mut config_descriptor = [0; 256]; |
| 98 | let mut bos_descriptor = [0; 256]; | 97 | let mut bos_descriptor = [0; 256]; |
| 99 | let mut msos_descriptor = [0; 256]; | 98 | let mut msos_descriptor = [0; 256]; |
| @@ -106,7 +105,6 @@ async fn main(_spawner: Spawner) { | |||
| 106 | let mut builder = Builder::new( | 105 | let mut builder = Builder::new( |
| 107 | driver, | 106 | driver, |
| 108 | config, | 107 | config, |
| 109 | &mut device_descriptor, | ||
| 110 | &mut config_descriptor, | 108 | &mut config_descriptor, |
| 111 | &mut bos_descriptor, | 109 | &mut bos_descriptor, |
| 112 | &mut msos_descriptor, | 110 | &mut msos_descriptor, |
diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs index 0dc8e9f72..331c3da4c 100644 --- a/examples/rp/src/bin/usb_raw_bulk.rs +++ b/examples/rp/src/bin/usb_raw_bulk.rs | |||
| @@ -71,7 +71,6 @@ async fn main(_spawner: Spawner) { | |||
| 71 | 71 | ||
| 72 | // Create embassy-usb DeviceBuilder using the driver and config. | 72 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 73 | // It needs some buffers for building the descriptors. | 73 | // It needs some buffers for building the descriptors. |
| 74 | let mut device_descriptor = [0; 256]; | ||
| 75 | let mut config_descriptor = [0; 256]; | 74 | let mut config_descriptor = [0; 256]; |
| 76 | let mut bos_descriptor = [0; 256]; | 75 | let mut bos_descriptor = [0; 256]; |
| 77 | let mut msos_descriptor = [0; 256]; | 76 | let mut msos_descriptor = [0; 256]; |
| @@ -80,7 +79,6 @@ async fn main(_spawner: Spawner) { | |||
| 80 | let mut builder = Builder::new( | 79 | let mut builder = Builder::new( |
| 81 | driver, | 80 | driver, |
| 82 | config, | 81 | config, |
| 83 | &mut device_descriptor, | ||
| 84 | &mut config_descriptor, | 82 | &mut config_descriptor, |
| 85 | &mut bos_descriptor, | 83 | &mut bos_descriptor, |
| 86 | &mut msos_descriptor, | 84 | &mut msos_descriptor, |
diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index ab24a994c..3c9bc96dd 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs | |||
| @@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) { | |||
| 46 | 46 | ||
| 47 | // Create embassy-usb DeviceBuilder using the driver and config. | 47 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 48 | // It needs some buffers for building the descriptors. | 48 | // It needs some buffers for building the descriptors. |
| 49 | let mut device_descriptor = [0; 256]; | ||
| 50 | let mut config_descriptor = [0; 256]; | 49 | let mut config_descriptor = [0; 256]; |
| 51 | let mut bos_descriptor = [0; 256]; | 50 | let mut bos_descriptor = [0; 256]; |
| 52 | let mut control_buf = [0; 64]; | 51 | let mut control_buf = [0; 64]; |
| @@ -56,7 +55,6 @@ async fn main(_spawner: Spawner) { | |||
| 56 | let mut builder = Builder::new( | 55 | let mut builder = Builder::new( |
| 57 | driver, | 56 | driver, |
| 58 | config, | 57 | config, |
| 59 | &mut device_descriptor, | ||
| 60 | &mut config_descriptor, | 58 | &mut config_descriptor, |
| 61 | &mut bos_descriptor, | 59 | &mut bos_descriptor, |
| 62 | &mut [], // no msos descriptors | 60 | &mut [], // no msos descriptors |
diff --git a/examples/rp/src/bin/usb_serial_with_logger.rs b/examples/rp/src/bin/usb_serial_with_logger.rs index 4ba4fc25c..f9cfdef94 100644 --- a/examples/rp/src/bin/usb_serial_with_logger.rs +++ b/examples/rp/src/bin/usb_serial_with_logger.rs | |||
| @@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) { | |||
| 46 | 46 | ||
| 47 | // Create embassy-usb DeviceBuilder using the driver and config. | 47 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 48 | // It needs some buffers for building the descriptors. | 48 | // It needs some buffers for building the descriptors. |
| 49 | let mut device_descriptor = [0; 256]; | ||
| 50 | let mut config_descriptor = [0; 256]; | 49 | let mut config_descriptor = [0; 256]; |
| 51 | let mut bos_descriptor = [0; 256]; | 50 | let mut bos_descriptor = [0; 256]; |
| 52 | let mut control_buf = [0; 64]; | 51 | let mut control_buf = [0; 64]; |
| @@ -57,7 +56,6 @@ async fn main(_spawner: Spawner) { | |||
| 57 | let mut builder = Builder::new( | 56 | let mut builder = Builder::new( |
| 58 | driver, | 57 | driver, |
| 59 | config, | 58 | config, |
| 60 | &mut device_descriptor, | ||
| 61 | &mut config_descriptor, | 59 | &mut config_descriptor, |
| 62 | &mut bos_descriptor, | 60 | &mut bos_descriptor, |
| 63 | &mut [], // no msos descriptors | 61 | &mut [], // no msos descriptors |
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index dad93d0a1..59813d8cb 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use std::default::Default; | ||
| 2 | |||
| 3 | use clap::Parser; | 1 | use clap::Parser; |
| 4 | use embassy_executor::{Executor, Spawner}; | 2 | use embassy_executor::{Executor, Spawner}; |
| 5 | use embassy_net::tcp::TcpSocket; | 3 | use embassy_net::tcp::TcpSocket; |
diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index fca1e076e..3b6a3de37 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use std::default::Default; | ||
| 2 | |||
| 3 | use clap::Parser; | 1 | use clap::Parser; |
| 4 | use embassy_executor::{Executor, Spawner}; | 2 | use embassy_executor::{Executor, Spawner}; |
| 5 | use embassy_net::dns::DnsQueryType; | 3 | use embassy_net::dns::DnsQueryType; |
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 00ccd83a7..e8b6eaa6c 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | use core::fmt::Write as _; | 1 | use core::fmt::Write as _; |
| 2 | use std::default::Default; | ||
| 3 | 2 | ||
| 4 | use clap::Parser; | 3 | use clap::Parser; |
| 5 | use embassy_executor::{Executor, Spawner}; | 4 | use embassy_executor::{Executor, Spawner}; |
diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index 1ae6c1dee..ee99acf41 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs | |||
| @@ -60,7 +60,6 @@ async fn main(_spawner: Spawner) { | |||
| 60 | 60 | ||
| 61 | // Create embassy-usb DeviceBuilder using the driver and config. | 61 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 62 | // It needs some buffers for building the descriptors. | 62 | // It needs some buffers for building the descriptors. |
| 63 | let mut device_descriptor = [0; 256]; | ||
| 64 | let mut config_descriptor = [0; 256]; | 63 | let mut config_descriptor = [0; 256]; |
| 65 | let mut bos_descriptor = [0; 256]; | 64 | let mut bos_descriptor = [0; 256]; |
| 66 | let mut control_buf = [0; 7]; | 65 | let mut control_buf = [0; 7]; |
| @@ -70,7 +69,6 @@ async fn main(_spawner: Spawner) { | |||
| 70 | let mut builder = Builder::new( | 69 | let mut builder = Builder::new( |
| 71 | driver, | 70 | driver, |
| 72 | config, | 71 | config, |
| 73 | &mut device_descriptor, | ||
| 74 | &mut config_descriptor, | 72 | &mut config_descriptor, |
| 75 | &mut bos_descriptor, | 73 | &mut bos_descriptor, |
| 76 | &mut [], // no msos descriptors | 74 | &mut [], // no msos descriptors |
diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index e32f283d1..e39e2daec 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::convert::TryFrom; | ||
| 5 | |||
| 6 | use defmt::*; | 4 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs index ee1c43afd..5760f2c1c 100644 --- a/examples/stm32f3/src/bin/usb_serial.rs +++ b/examples/stm32f3/src/bin/usb_serial.rs | |||
| @@ -54,7 +54,6 @@ async fn main(_spawner: Spawner) { | |||
| 54 | 54 | ||
| 55 | // Create embassy-usb DeviceBuilder using the driver and config. | 55 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 56 | // It needs some buffers for building the descriptors. | 56 | // It needs some buffers for building the descriptors. |
| 57 | let mut device_descriptor = [0; 256]; | ||
| 58 | let mut config_descriptor = [0; 256]; | 57 | let mut config_descriptor = [0; 256]; |
| 59 | let mut bos_descriptor = [0; 256]; | 58 | let mut bos_descriptor = [0; 256]; |
| 60 | let mut control_buf = [0; 7]; | 59 | let mut control_buf = [0; 7]; |
| @@ -64,7 +63,6 @@ async fn main(_spawner: Spawner) { | |||
| 64 | let mut builder = Builder::new( | 63 | let mut builder = Builder::new( |
| 65 | driver, | 64 | driver, |
| 66 | config, | 65 | config, |
| 67 | &mut device_descriptor, | ||
| 68 | &mut config_descriptor, | 66 | &mut config_descriptor, |
| 69 | &mut bos_descriptor, | 67 | &mut bos_descriptor, |
| 70 | &mut [], // no msos descriptors | 68 | &mut [], // no msos descriptors |
diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index a196259a8..d2cbeea1b 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs | |||
| @@ -7,8 +7,8 @@ use embassy_net::tcp::TcpSocket; | |||
| 7 | use embassy_net::{Stack, StackResources}; | 7 | use embassy_net::{Stack, StackResources}; |
| 8 | use embassy_stm32::rng::{self, Rng}; | 8 | use embassy_stm32::rng::{self, Rng}; |
| 9 | use embassy_stm32::time::Hertz; | 9 | use embassy_stm32::time::Hertz; |
| 10 | use embassy_stm32::usb_otg::Driver; | 10 | use embassy_stm32::usb::Driver; |
| 11 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 11 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 12 | use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; | 12 | use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; |
| 13 | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | 13 | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; |
| 14 | use embassy_usb::{Builder, UsbDevice}; | 14 | use embassy_usb::{Builder, UsbDevice}; |
| @@ -36,7 +36,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! { | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | bind_interrupts!(struct Irqs { | 38 | bind_interrupts!(struct Irqs { |
| 39 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 39 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 40 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; | 40 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| @@ -63,13 +63,14 @@ async fn main(spawner: Spawner) { | |||
| 63 | config.rcc.apb1_pre = APBPrescaler::DIV4; | 63 | config.rcc.apb1_pre = APBPrescaler::DIV4; |
| 64 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 64 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 65 | config.rcc.sys = Sysclk::PLL1_P; | 65 | config.rcc.sys = Sysclk::PLL1_P; |
| 66 | config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | ||
| 66 | } | 67 | } |
| 67 | let p = embassy_stm32::init(config); | 68 | let p = embassy_stm32::init(config); |
| 68 | 69 | ||
| 69 | // Create the driver, from the HAL. | 70 | // Create the driver, from the HAL. |
| 70 | static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); | 71 | static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new(); |
| 71 | let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; | 72 | let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..]; |
| 72 | let mut config = embassy_stm32::usb_otg::Config::default(); | 73 | let mut config = embassy_stm32::usb::Config::default(); |
| 73 | config.vbus_detection = true; | 74 | config.vbus_detection = true; |
| 74 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); | 75 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); |
| 75 | 76 | ||
| @@ -88,14 +89,12 @@ async fn main(spawner: Spawner) { | |||
| 88 | config.device_protocol = 0x01; | 89 | config.device_protocol = 0x01; |
| 89 | 90 | ||
| 90 | // Create embassy-usb DeviceBuilder using the driver and config. | 91 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 91 | static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 92 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 92 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 93 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 93 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 94 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | 94 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); |
| 95 | let mut builder = Builder::new( | 95 | let mut builder = Builder::new( |
| 96 | driver, | 96 | driver, |
| 97 | config, | 97 | config, |
| 98 | &mut DEVICE_DESC.init([0; 256])[..], | ||
| 99 | &mut CONFIG_DESC.init([0; 256])[..], | 98 | &mut CONFIG_DESC.init([0; 256])[..], |
| 100 | &mut BOS_DESC.init([0; 256])[..], | 99 | &mut BOS_DESC.init([0; 256])[..], |
| 101 | &mut [], // no msos descriptors | 100 | &mut [], // no msos descriptors |
diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs index 19b5971fb..a799b4e72 100644 --- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs +++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs | |||
| @@ -8,8 +8,8 @@ use embassy_executor::Spawner; | |||
| 8 | use embassy_stm32::exti::ExtiInput; | 8 | use embassy_stm32::exti::ExtiInput; |
| 9 | use embassy_stm32::gpio::Pull; | 9 | use embassy_stm32::gpio::Pull; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::usb_otg::Driver; | 11 | use embassy_stm32::usb::Driver; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 12 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 13 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; | 13 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; |
| 14 | use embassy_usb::control::OutResponse; | 14 | use embassy_usb::control::OutResponse; |
| 15 | use embassy_usb::{Builder, Handler}; | 15 | use embassy_usb::{Builder, Handler}; |
| @@ -18,7 +18,7 @@ use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | |||
| 18 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 19 | ||
| 20 | bind_interrupts!(struct Irqs { | 20 | bind_interrupts!(struct Irqs { |
| 21 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 21 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 22 | }); | 22 | }); |
| 23 | 23 | ||
| 24 | #[embassy_executor::main] | 24 | #[embassy_executor::main] |
| @@ -42,12 +42,13 @@ async fn main(_spawner: Spawner) { | |||
| 42 | config.rcc.apb1_pre = APBPrescaler::DIV4; | 42 | config.rcc.apb1_pre = APBPrescaler::DIV4; |
| 43 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 43 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 44 | config.rcc.sys = Sysclk::PLL1_P; | 44 | config.rcc.sys = Sysclk::PLL1_P; |
| 45 | config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | ||
| 45 | } | 46 | } |
| 46 | let p = embassy_stm32::init(config); | 47 | let p = embassy_stm32::init(config); |
| 47 | 48 | ||
| 48 | // Create the driver, from the HAL. | 49 | // Create the driver, from the HAL. |
| 49 | let mut ep_out_buffer = [0u8; 256]; | 50 | let mut ep_out_buffer = [0u8; 256]; |
| 50 | let mut config = embassy_stm32::usb_otg::Config::default(); | 51 | let mut config = embassy_stm32::usb::Config::default(); |
| 51 | config.vbus_detection = true; | 52 | config.vbus_detection = true; |
| 52 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 53 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 53 | 54 | ||
| @@ -68,7 +69,6 @@ async fn main(_spawner: Spawner) { | |||
| 68 | 69 | ||
| 69 | // Create embassy-usb DeviceBuilder using the driver and config. | 70 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 70 | // It needs some buffers for building the descriptors. | 71 | // It needs some buffers for building the descriptors. |
| 71 | let mut device_descriptor = [0; 256]; | ||
| 72 | let mut config_descriptor = [0; 256]; | 72 | let mut config_descriptor = [0; 256]; |
| 73 | let mut bos_descriptor = [0; 256]; | 73 | let mut bos_descriptor = [0; 256]; |
| 74 | // You can also add a Microsoft OS descriptor. | 74 | // You can also add a Microsoft OS descriptor. |
| @@ -83,7 +83,6 @@ async fn main(_spawner: Spawner) { | |||
| 83 | let mut builder = Builder::new( | 83 | let mut builder = Builder::new( |
| 84 | driver, | 84 | driver, |
| 85 | config, | 85 | config, |
| 86 | &mut device_descriptor, | ||
| 87 | &mut config_descriptor, | 86 | &mut config_descriptor, |
| 88 | &mut bos_descriptor, | 87 | &mut bos_descriptor, |
| 89 | &mut msos_descriptor, | 88 | &mut msos_descriptor, |
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs index c98792880..0bc236119 100644 --- a/examples/stm32f4/src/bin/usb_hid_mouse.rs +++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb_otg::Driver; | 7 | use embassy_stm32::usb::Driver; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_time::Timer; | 9 | use embassy_time::Timer; |
| 10 | use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; | 10 | use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; |
| 11 | use embassy_usb::control::OutResponse; | 11 | use embassy_usb::control::OutResponse; |
| @@ -15,7 +15,7 @@ use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; | |||
| 15 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 16 | 16 | ||
| 17 | bind_interrupts!(struct Irqs { | 17 | bind_interrupts!(struct Irqs { |
| 18 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 18 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 19 | }); | 19 | }); |
| 20 | 20 | ||
| 21 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| @@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) { | |||
| 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; | 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; |
| 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 41 | config.rcc.sys = Sysclk::PLL1_P; | 41 | config.rcc.sys = Sysclk::PLL1_P; |
| 42 | config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | ||
| 42 | } | 43 | } |
| 43 | let p = embassy_stm32::init(config); | 44 | let p = embassy_stm32::init(config); |
| 44 | 45 | ||
| 45 | // Create the driver, from the HAL. | 46 | // Create the driver, from the HAL. |
| 46 | let mut ep_out_buffer = [0u8; 256]; | 47 | let mut ep_out_buffer = [0u8; 256]; |
| 47 | let mut config = embassy_stm32::usb_otg::Config::default(); | 48 | let mut config = embassy_stm32::usb::Config::default(); |
| 48 | config.vbus_detection = true; | 49 | config.vbus_detection = true; |
| 49 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 50 | 51 | ||
| @@ -63,7 +64,6 @@ async fn main(_spawner: Spawner) { | |||
| 63 | 64 | ||
| 64 | // Create embassy-usb DeviceBuilder using the driver and config. | 65 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 65 | // It needs some buffers for building the descriptors. | 66 | // It needs some buffers for building the descriptors. |
| 66 | let mut device_descriptor = [0; 256]; | ||
| 67 | let mut config_descriptor = [0; 256]; | 67 | let mut config_descriptor = [0; 256]; |
| 68 | let mut bos_descriptor = [0; 256]; | 68 | let mut bos_descriptor = [0; 256]; |
| 69 | let mut control_buf = [0; 64]; | 69 | let mut control_buf = [0; 64]; |
| @@ -75,7 +75,6 @@ async fn main(_spawner: Spawner) { | |||
| 75 | let mut builder = Builder::new( | 75 | let mut builder = Builder::new( |
| 76 | driver, | 76 | driver, |
| 77 | config, | 77 | config, |
| 78 | &mut device_descriptor, | ||
| 79 | &mut config_descriptor, | 78 | &mut config_descriptor, |
| 80 | &mut bos_descriptor, | 79 | &mut bos_descriptor, |
| 81 | &mut [], // no msos descriptors | 80 | &mut [], // no msos descriptors |
diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs index afff55187..4e583aeb8 100644 --- a/examples/stm32f4/src/bin/usb_raw.rs +++ b/examples/stm32f4/src/bin/usb_raw.rs | |||
| @@ -52,8 +52,8 @@ | |||
| 52 | use defmt::*; | 52 | use defmt::*; |
| 53 | use embassy_executor::Spawner; | 53 | use embassy_executor::Spawner; |
| 54 | use embassy_stm32::time::Hertz; | 54 | use embassy_stm32::time::Hertz; |
| 55 | use embassy_stm32::usb_otg::Driver; | 55 | use embassy_stm32::usb::Driver; |
| 56 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 56 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 57 | use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; | 57 | use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; |
| 58 | use embassy_usb::msos::{self, windows_version}; | 58 | use embassy_usb::msos::{self, windows_version}; |
| 59 | use embassy_usb::types::InterfaceNumber; | 59 | use embassy_usb::types::InterfaceNumber; |
| @@ -66,7 +66,7 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 66 | const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; | 66 | const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; |
| 67 | 67 | ||
| 68 | bind_interrupts!(struct Irqs { | 68 | bind_interrupts!(struct Irqs { |
| 69 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 69 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 70 | }); | 70 | }); |
| 71 | 71 | ||
| 72 | #[embassy_executor::main] | 72 | #[embassy_executor::main] |
| @@ -92,12 +92,13 @@ async fn main(_spawner: Spawner) { | |||
| 92 | config.rcc.apb1_pre = APBPrescaler::DIV4; | 92 | config.rcc.apb1_pre = APBPrescaler::DIV4; |
| 93 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 93 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 94 | config.rcc.sys = Sysclk::PLL1_P; | 94 | config.rcc.sys = Sysclk::PLL1_P; |
| 95 | config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | ||
| 95 | } | 96 | } |
| 96 | let p = embassy_stm32::init(config); | 97 | let p = embassy_stm32::init(config); |
| 97 | 98 | ||
| 98 | // Create the driver, from the HAL. | 99 | // Create the driver, from the HAL. |
| 99 | let mut ep_out_buffer = [0u8; 256]; | 100 | let mut ep_out_buffer = [0u8; 256]; |
| 100 | let mut config = embassy_stm32::usb_otg::Config::default(); | 101 | let mut config = embassy_stm32::usb::Config::default(); |
| 101 | config.vbus_detection = true; | 102 | config.vbus_detection = true; |
| 102 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 103 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 103 | 104 | ||
| @@ -116,7 +117,6 @@ async fn main(_spawner: Spawner) { | |||
| 116 | 117 | ||
| 117 | // Create embassy-usb DeviceBuilder using the driver and config. | 118 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 118 | // It needs some buffers for building the descriptors. | 119 | // It needs some buffers for building the descriptors. |
| 119 | let mut device_descriptor = [0; 256]; | ||
| 120 | let mut config_descriptor = [0; 256]; | 120 | let mut config_descriptor = [0; 256]; |
| 121 | let mut bos_descriptor = [0; 256]; | 121 | let mut bos_descriptor = [0; 256]; |
| 122 | let mut msos_descriptor = [0; 256]; | 122 | let mut msos_descriptor = [0; 256]; |
| @@ -129,7 +129,6 @@ async fn main(_spawner: Spawner) { | |||
| 129 | let mut builder = Builder::new( | 129 | let mut builder = Builder::new( |
| 130 | driver, | 130 | driver, |
| 131 | config, | 131 | config, |
| 132 | &mut device_descriptor, | ||
| 133 | &mut config_descriptor, | 132 | &mut config_descriptor, |
| 134 | &mut bos_descriptor, | 133 | &mut bos_descriptor, |
| 135 | &mut msos_descriptor, | 134 | &mut msos_descriptor, |
diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs index 58d994a61..f3a375d31 100644 --- a/examples/stm32f4/src/bin/usb_serial.rs +++ b/examples/stm32f4/src/bin/usb_serial.rs | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb_otg::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| @@ -13,7 +13,7 @@ use futures::future::join; | |||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 16 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| @@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) { | |||
| 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; | 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; |
| 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 41 | config.rcc.sys = Sysclk::PLL1_P; | 41 | config.rcc.sys = Sysclk::PLL1_P; |
| 42 | config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | ||
| 42 | } | 43 | } |
| 43 | let p = embassy_stm32::init(config); | 44 | let p = embassy_stm32::init(config); |
| 44 | 45 | ||
| 45 | // Create the driver, from the HAL. | 46 | // Create the driver, from the HAL. |
| 46 | let mut ep_out_buffer = [0u8; 256]; | 47 | let mut ep_out_buffer = [0u8; 256]; |
| 47 | let mut config = embassy_stm32::usb_otg::Config::default(); | 48 | let mut config = embassy_stm32::usb::Config::default(); |
| 48 | config.vbus_detection = true; | 49 | config.vbus_detection = true; |
| 49 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 50 | 51 | ||
| @@ -63,7 +64,6 @@ async fn main(_spawner: Spawner) { | |||
| 63 | 64 | ||
| 64 | // Create embassy-usb DeviceBuilder using the driver and config. | 65 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 65 | // It needs some buffers for building the descriptors. | 66 | // It needs some buffers for building the descriptors. |
| 66 | let mut device_descriptor = [0; 256]; | ||
| 67 | let mut config_descriptor = [0; 256]; | 67 | let mut config_descriptor = [0; 256]; |
| 68 | let mut bos_descriptor = [0; 256]; | 68 | let mut bos_descriptor = [0; 256]; |
| 69 | let mut control_buf = [0; 64]; | 69 | let mut control_buf = [0; 64]; |
| @@ -73,7 +73,6 @@ async fn main(_spawner: Spawner) { | |||
| 73 | let mut builder = Builder::new( | 73 | let mut builder = Builder::new( |
| 74 | driver, | 74 | driver, |
| 75 | config, | 75 | config, |
| 76 | &mut device_descriptor, | ||
| 77 | &mut config_descriptor, | 76 | &mut config_descriptor, |
| 78 | &mut bos_descriptor, | 77 | &mut bos_descriptor, |
| 79 | &mut [], // no msos descriptors | 78 | &mut [], // no msos descriptors |
diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs index 6122cea2d..cbaff75fc 100644 --- a/examples/stm32f4/src/bin/ws2812_pwm.rs +++ b/examples/stm32f4/src/bin/ws2812_pwm.rs | |||
| @@ -15,8 +15,9 @@ | |||
| 15 | use embassy_executor::Spawner; | 15 | use embassy_executor::Spawner; |
| 16 | use embassy_stm32::gpio::OutputType; | 16 | use embassy_stm32::gpio::OutputType; |
| 17 | use embassy_stm32::time::khz; | 17 | use embassy_stm32::time::khz; |
| 18 | use embassy_stm32::timer::low_level::CountingMode; | ||
| 18 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; | 19 | use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; |
| 19 | use embassy_stm32::timer::{Channel, CountingMode}; | 20 | use embassy_stm32::timer::Channel; |
| 20 | use embassy_time::{Duration, Ticker, Timer}; | 21 | use embassy_time::{Duration, Ticker, Timer}; |
| 21 | use {defmt_rtt as _, panic_probe as _}; | 22 | use {defmt_rtt as _, panic_probe as _}; |
| 22 | 23 | ||
| @@ -60,7 +61,7 @@ async fn main(_spawner: Spawner) { | |||
| 60 | // construct ws2812 non-return-to-zero (NRZ) code bit by bit | 61 | // construct ws2812 non-return-to-zero (NRZ) code bit by bit |
| 61 | // ws2812 only need 24 bits for each LED, but we add one bit more to keep PWM output low | 62 | // ws2812 only need 24 bits for each LED, but we add one bit more to keep PWM output low |
| 62 | 63 | ||
| 63 | let max_duty = ws2812_pwm.get_max_duty(); | 64 | let max_duty = ws2812_pwm.get_max_duty() as u16; |
| 64 | let n0 = 8 * max_duty / 25; // ws2812 Bit 0 high level timing | 65 | let n0 = 8 * max_duty / 25; // ws2812 Bit 0 high level timing |
| 65 | let n1 = 2 * n0; // ws2812 Bit 1 high level timing | 66 | let n1 = 2 * n0; // ws2812 Bit 1 high level timing |
| 66 | 67 | ||
diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs index 97daf6bd1..39a5512f4 100644 --- a/examples/stm32f7/src/bin/usb_serial.rs +++ b/examples/stm32f7/src/bin/usb_serial.rs | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb_otg::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| @@ -13,7 +13,7 @@ use futures::future::join; | |||
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 16 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| @@ -39,12 +39,13 @@ async fn main(_spawner: Spawner) { | |||
| 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; | 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; |
| 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 41 | config.rcc.sys = Sysclk::PLL1_P; | 41 | config.rcc.sys = Sysclk::PLL1_P; |
| 42 | config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | ||
| 42 | } | 43 | } |
| 43 | let p = embassy_stm32::init(config); | 44 | let p = embassy_stm32::init(config); |
| 44 | 45 | ||
| 45 | // Create the driver, from the HAL. | 46 | // Create the driver, from the HAL. |
| 46 | let mut ep_out_buffer = [0u8; 256]; | 47 | let mut ep_out_buffer = [0u8; 256]; |
| 47 | let mut config = embassy_stm32::usb_otg::Config::default(); | 48 | let mut config = embassy_stm32::usb::Config::default(); |
| 48 | config.vbus_detection = true; | 49 | config.vbus_detection = true; |
| 49 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 50 | 51 | ||
| @@ -63,7 +64,6 @@ async fn main(_spawner: Spawner) { | |||
| 63 | 64 | ||
| 64 | // Create embassy-usb DeviceBuilder using the driver and config. | 65 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 65 | // It needs some buffers for building the descriptors. | 66 | // It needs some buffers for building the descriptors. |
| 66 | let mut device_descriptor = [0; 256]; | ||
| 67 | let mut config_descriptor = [0; 256]; | 67 | let mut config_descriptor = [0; 256]; |
| 68 | let mut bos_descriptor = [0; 256]; | 68 | let mut bos_descriptor = [0; 256]; |
| 69 | let mut control_buf = [0; 64]; | 69 | let mut control_buf = [0; 64]; |
| @@ -73,7 +73,6 @@ async fn main(_spawner: Spawner) { | |||
| 73 | let mut builder = Builder::new( | 73 | let mut builder = Builder::new( |
| 74 | driver, | 74 | driver, |
| 75 | config, | 75 | config, |
| 76 | &mut device_descriptor, | ||
| 77 | &mut config_descriptor, | 76 | &mut config_descriptor, |
| 78 | &mut bos_descriptor, | 77 | &mut bos_descriptor, |
| 79 | &mut [], // no msos descriptors | 78 | &mut [], // no msos descriptors |
diff --git a/examples/stm32g0/src/bin/usb_serial.rs b/examples/stm32g0/src/bin/usb_serial.rs index 8b9915626..162dfd86b 100644 --- a/examples/stm32g0/src/bin/usb_serial.rs +++ b/examples/stm32g0/src/bin/usb_serial.rs | |||
| @@ -36,7 +36,6 @@ async fn main(_spawner: Spawner) { | |||
| 36 | 36 | ||
| 37 | // Create embassy-usb DeviceBuilder using the driver and config. | 37 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 38 | // It needs some buffers for building the descriptors. | 38 | // It needs some buffers for building the descriptors. |
| 39 | let mut device_descriptor = [0; 256]; | ||
| 40 | let mut config_descriptor = [0; 256]; | 39 | let mut config_descriptor = [0; 256]; |
| 41 | let mut bos_descriptor = [0; 256]; | 40 | let mut bos_descriptor = [0; 256]; |
| 42 | let mut control_buf = [0; 7]; | 41 | let mut control_buf = [0; 7]; |
| @@ -46,7 +45,6 @@ async fn main(_spawner: Spawner) { | |||
| 46 | let mut builder = Builder::new( | 45 | let mut builder = Builder::new( |
| 47 | driver, | 46 | driver, |
| 48 | config, | 47 | config, |
| 49 | &mut device_descriptor, | ||
| 50 | &mut config_descriptor, | 48 | &mut config_descriptor, |
| 51 | &mut bos_descriptor, | 49 | &mut bos_descriptor, |
| 52 | &mut [], // no msos descriptors | 50 | &mut [], // no msos descriptors |
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index dc95aa6e5..dbe8f27c1 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs | |||
| @@ -56,7 +56,6 @@ async fn main(_spawner: Spawner) { | |||
| 56 | config.device_protocol = 0x01; | 56 | config.device_protocol = 0x01; |
| 57 | config.composite_with_iads = true; | 57 | config.composite_with_iads = true; |
| 58 | 58 | ||
| 59 | let mut device_descriptor = [0; 256]; | ||
| 60 | let mut config_descriptor = [0; 256]; | 59 | let mut config_descriptor = [0; 256]; |
| 61 | let mut bos_descriptor = [0; 256]; | 60 | let mut bos_descriptor = [0; 256]; |
| 62 | let mut control_buf = [0; 64]; | 61 | let mut control_buf = [0; 64]; |
| @@ -66,7 +65,6 @@ async fn main(_spawner: Spawner) { | |||
| 66 | let mut builder = Builder::new( | 65 | let mut builder = Builder::new( |
| 67 | driver, | 66 | driver, |
| 68 | config, | 67 | config, |
| 69 | &mut device_descriptor, | ||
| 70 | &mut config_descriptor, | 68 | &mut config_descriptor, |
| 71 | &mut bos_descriptor, | 69 | &mut bos_descriptor, |
| 72 | &mut [], // no msos descriptors | 70 | &mut [], // no msos descriptors |
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 83477c8fa..4f86bb342 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs | |||
| @@ -65,7 +65,6 @@ async fn main(_spawner: Spawner) { | |||
| 65 | 65 | ||
| 66 | // Create embassy-usb DeviceBuilder using the driver and config. | 66 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 67 | // It needs some buffers for building the descriptors. | 67 | // It needs some buffers for building the descriptors. |
| 68 | let mut device_descriptor = [0; 256]; | ||
| 69 | let mut config_descriptor = [0; 256]; | 68 | let mut config_descriptor = [0; 256]; |
| 70 | let mut bos_descriptor = [0; 256]; | 69 | let mut bos_descriptor = [0; 256]; |
| 71 | let mut control_buf = [0; 64]; | 70 | let mut control_buf = [0; 64]; |
| @@ -75,7 +74,6 @@ async fn main(_spawner: Spawner) { | |||
| 75 | let mut builder = Builder::new( | 74 | let mut builder = Builder::new( |
| 76 | driver, | 75 | driver, |
| 77 | config, | 76 | config, |
| 78 | &mut device_descriptor, | ||
| 79 | &mut config_descriptor, | 77 | &mut config_descriptor, |
| 80 | &mut bos_descriptor, | 78 | &mut bos_descriptor, |
| 81 | &mut [], // no msos descriptors | 79 | &mut [], // no msos descriptors |
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index e5a104baf..170a5aa28 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs | |||
| @@ -78,9 +78,9 @@ async fn main(_spawner: Spawner) { | |||
| 78 | ); | 78 | ); |
| 79 | 79 | ||
| 80 | defmt::info!("attempting capture"); | 80 | defmt::info!("attempting capture"); |
| 81 | defmt::unwrap!(dcmi.capture(unsafe { &mut FRAME }).await); | 81 | defmt::unwrap!(dcmi.capture(unsafe { &mut *core::ptr::addr_of_mut!(FRAME) }).await); |
| 82 | 82 | ||
| 83 | defmt::info!("captured frame: {:x}", unsafe { &FRAME }); | 83 | defmt::info!("captured frame: {:x}", unsafe { &*core::ptr::addr_of!(FRAME) }); |
| 84 | 84 | ||
| 85 | defmt::info!("main loop running"); | 85 | defmt::info!("main loop running"); |
| 86 | loop { | 86 | loop { |
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index feec28993..3a9887e3c 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs | |||
| @@ -6,9 +6,9 @@ use embassy_executor::Spawner; | |||
| 6 | use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; | 6 | use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; |
| 7 | use embassy_stm32::pac::timer::vals::Mms; | 7 | use embassy_stm32::pac::timer::vals::Mms; |
| 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; | 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; |
| 9 | use embassy_stm32::rcc::low_level::RccPeripheral; | 9 | use embassy_stm32::rcc::frequency; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::timer::low_level::BasicInstance; | 11 | use embassy_stm32::timer::low_level::Timer; |
| 12 | use micromath::F32Ext; | 12 | use micromath::F32Ext; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -51,19 +51,19 @@ async fn main(spawner: Spawner) { | |||
| 51 | // Obtain two independent channels (p.DAC1 can only be consumed once, though!) | 51 | // Obtain two independent channels (p.DAC1 can only be consumed once, though!) |
| 52 | let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); | 52 | let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); |
| 53 | 53 | ||
| 54 | spawner.spawn(dac_task1(dac_ch1)).ok(); | 54 | spawner.spawn(dac_task1(p.TIM6, dac_ch1)).ok(); |
| 55 | spawner.spawn(dac_task2(dac_ch2)).ok(); | 55 | spawner.spawn(dac_task2(p.TIM7, dac_ch2)).ok(); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | #[embassy_executor::task] | 58 | #[embassy_executor::task] |
| 59 | async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | 59 | async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { |
| 60 | let data: &[u8; 256] = &calculate_array::<256>(); | 60 | let data: &[u8; 256] = &calculate_array::<256>(); |
| 61 | 61 | ||
| 62 | info!("TIM6 frequency is {}", TIM6::frequency()); | 62 | info!("TIM6 frequency is {}", frequency::<TIM6>()); |
| 63 | const FREQUENCY: Hertz = Hertz::hz(200); | 63 | const FREQUENCY: Hertz = Hertz::hz(200); |
| 64 | 64 | ||
| 65 | // Compute the reload value such that we obtain the FREQUENCY for the sine | 65 | // Compute the reload value such that we obtain the FREQUENCY for the sine |
| 66 | let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; | 66 | let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32; |
| 67 | 67 | ||
| 68 | // Depends on your clock and on the specific chip used, you may need higher or lower values here | 68 | // Depends on your clock and on the specific chip used, you may need higher or lower values here |
| 69 | if reload < 10 { | 69 | if reload < 10 { |
| @@ -74,17 +74,17 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 74 | dac.set_triggering(true); | 74 | dac.set_triggering(true); |
| 75 | dac.enable(); | 75 | dac.enable(); |
| 76 | 76 | ||
| 77 | TIM6::enable_and_reset(); | 77 | let tim = Timer::new(tim); |
| 78 | TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 78 | tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 79 | TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 79 | tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 80 | TIM6::regs_basic().cr1().modify(|w| { | 80 | tim.regs_basic().cr1().modify(|w| { |
| 81 | w.set_opm(false); | 81 | w.set_opm(false); |
| 82 | w.set_cen(true); | 82 | w.set_cen(true); |
| 83 | }); | 83 | }); |
| 84 | 84 | ||
| 85 | debug!( | 85 | debug!( |
| 86 | "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", | 86 | "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", |
| 87 | TIM6::frequency(), | 87 | frequency::<TIM6>(), |
| 88 | FREQUENCY, | 88 | FREQUENCY, |
| 89 | reload, | 89 | reload, |
| 90 | reload as u16, | 90 | reload as u16, |
| @@ -99,22 +99,22 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | #[embassy_executor::task] | 101 | #[embassy_executor::task] |
| 102 | async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | 102 | async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { |
| 103 | let data: &[u8; 256] = &calculate_array::<256>(); | 103 | let data: &[u8; 256] = &calculate_array::<256>(); |
| 104 | 104 | ||
| 105 | info!("TIM7 frequency is {}", TIM7::frequency()); | 105 | info!("TIM7 frequency is {}", frequency::<TIM6>()); |
| 106 | 106 | ||
| 107 | const FREQUENCY: Hertz = Hertz::hz(600); | 107 | const FREQUENCY: Hertz = Hertz::hz(600); |
| 108 | let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; | 108 | let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32; |
| 109 | 109 | ||
| 110 | if reload < 10 { | 110 | if reload < 10 { |
| 111 | error!("Reload value {} below threshold!", reload); | 111 | error!("Reload value {} below threshold!", reload); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | TIM7::enable_and_reset(); | 114 | let tim = Timer::new(tim); |
| 115 | TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 115 | tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 116 | TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 116 | tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 117 | TIM7::regs_basic().cr1().modify(|w| { | 117 | tim.regs_basic().cr1().modify(|w| { |
| 118 | w.set_opm(false); | 118 | w.set_opm(false); |
| 119 | w.set_cen(true); | 119 | w.set_cen(true); |
| 120 | }); | 120 | }); |
| @@ -125,7 +125,7 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | |||
| 125 | 125 | ||
| 126 | debug!( | 126 | debug!( |
| 127 | "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", | 127 | "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", |
| 128 | TIM7::frequency(), | 128 | frequency::<TIM7>(), |
| 129 | FREQUENCY, | 129 | FREQUENCY, |
| 130 | reload, | 130 | reload, |
| 131 | reload as u16, | 131 | reload as u16, |
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index cd9a27fcd..7c7964ecd 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs | |||
| @@ -64,19 +64,21 @@ async fn main(spawner: Spawner) -> ! { | |||
| 64 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 64 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 65 | 65 | ||
| 66 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); | 66 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); |
| 67 | // warning: Not all STM32H7 devices have the exact same pins here | ||
| 68 | // for STM32H747XIH, replace p.PB13 for PG12 | ||
| 67 | let device = Ethernet::new( | 69 | let device = Ethernet::new( |
| 68 | PACKETS.init(PacketQueue::<4, 4>::new()), | 70 | PACKETS.init(PacketQueue::<4, 4>::new()), |
| 69 | p.ETH, | 71 | p.ETH, |
| 70 | Irqs, | 72 | Irqs, |
| 71 | p.PA1, | 73 | p.PA1, // ref_clk |
| 72 | p.PA2, | 74 | p.PA2, // mdio |
| 73 | p.PC1, | 75 | p.PC1, // eth_mdc |
| 74 | p.PA7, | 76 | p.PA7, // CRS_DV: Carrier Sense |
| 75 | p.PC4, | 77 | p.PC4, // RX_D0: Received Bit 0 |
| 76 | p.PC5, | 78 | p.PC5, // RX_D1: Received Bit 1 |
| 77 | p.PG13, | 79 | p.PG13, // TX_D0: Transmit Bit 0 |
| 78 | p.PB13, | 80 | p.PB13, // TX_D1: Transmit Bit 1 |
| 79 | p.PG11, | 81 | p.PG11, // TX_EN: Transmit Enable |
| 80 | GenericSMI::new(0), | 82 | GenericSMI::new(0), |
| 81 | mac_addr, | 83 | mac_addr, |
| 82 | ); | 84 | ); |
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 049d9967d..a95b44b74 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs | |||
| @@ -3,11 +3,11 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::low_level::AFType; | 6 | use embassy_stm32::gpio::{AFType, Flex, Pull, Speed}; |
| 7 | use embassy_stm32::gpio::Speed; | ||
| 8 | use embassy_stm32::time::{khz, Hertz}; | 7 | use embassy_stm32::time::{khz, Hertz}; |
| 9 | use embassy_stm32::timer::*; | 8 | use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; |
| 10 | use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; | 9 | use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; |
| 10 | use embassy_stm32::{into_ref, Config, Peripheral}; | ||
| 11 | use embassy_time::Timer; | 11 | use embassy_time::Timer; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 13 | ||
| @@ -56,11 +56,15 @@ async fn main(_spawner: Spawner) { | |||
| 56 | Timer::after_millis(300).await; | 56 | Timer::after_millis(300).await; |
| 57 | } | 57 | } |
| 58 | } | 58 | } |
| 59 | pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { | 59 | pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> { |
| 60 | inner: PeripheralRef<'d, T>, | 60 | tim: LLTimer<'d, T>, |
| 61 | _ch1: Flex<'d>, | ||
| 62 | _ch2: Flex<'d>, | ||
| 63 | _ch3: Flex<'d>, | ||
| 64 | _ch4: Flex<'d>, | ||
| 61 | } | 65 | } |
| 62 | 66 | ||
| 63 | impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | 67 | impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { |
| 64 | pub fn new( | 68 | pub fn new( |
| 65 | tim: impl Peripheral<P = T> + 'd, | 69 | tim: impl Peripheral<P = T> + 'd, |
| 66 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, | 70 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, |
| @@ -69,25 +73,33 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 69 | ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, | 73 | ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, |
| 70 | freq: Hertz, | 74 | freq: Hertz, |
| 71 | ) -> Self { | 75 | ) -> Self { |
| 72 | into_ref!(tim, ch1, ch2, ch3, ch4); | 76 | into_ref!(ch1, ch2, ch3, ch4); |
| 73 | 77 | ||
| 74 | T::enable_and_reset(); | 78 | let af1 = ch1.af_num(); |
| 75 | 79 | let af2 = ch2.af_num(); | |
| 76 | ch1.set_speed(Speed::VeryHigh); | 80 | let af3 = ch3.af_num(); |
| 77 | ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 81 | let af4 = ch4.af_num(); |
| 78 | ch2.set_speed(Speed::VeryHigh); | 82 | let mut ch1 = Flex::new(ch1); |
| 79 | ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 83 | let mut ch2 = Flex::new(ch2); |
| 80 | ch3.set_speed(Speed::VeryHigh); | 84 | let mut ch3 = Flex::new(ch3); |
| 81 | ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 85 | let mut ch4 = Flex::new(ch4); |
| 82 | ch4.set_speed(Speed::VeryHigh); | 86 | ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); |
| 83 | ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 87 | ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); |
| 84 | 88 | ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); | |
| 85 | let mut this = Self { inner: tim }; | 89 | ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); |
| 90 | |||
| 91 | let mut this = Self { | ||
| 92 | tim: LLTimer::new(tim), | ||
| 93 | _ch1: ch1, | ||
| 94 | _ch2: ch2, | ||
| 95 | _ch3: ch3, | ||
| 96 | _ch4: ch4, | ||
| 97 | }; | ||
| 86 | 98 | ||
| 87 | this.set_frequency(freq); | 99 | this.set_frequency(freq); |
| 88 | this.inner.start(); | 100 | this.tim.start(); |
| 89 | 101 | ||
| 90 | let r = T::regs_gp32(); | 102 | let r = this.tim.regs_gp32(); |
| 91 | r.ccmr_output(0) | 103 | r.ccmr_output(0) |
| 92 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); | 104 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); |
| 93 | r.ccmr_output(0) | 105 | r.ccmr_output(0) |
| @@ -101,23 +113,26 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 101 | } | 113 | } |
| 102 | 114 | ||
| 103 | pub fn enable(&mut self, channel: Channel) { | 115 | pub fn enable(&mut self, channel: Channel) { |
| 104 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), true)); | 116 | self.tim.regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), true)); |
| 105 | } | 117 | } |
| 106 | 118 | ||
| 107 | pub fn disable(&mut self, channel: Channel) { | 119 | pub fn disable(&mut self, channel: Channel) { |
| 108 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), false)); | 120 | self.tim |
| 121 | .regs_gp32() | ||
| 122 | .ccer() | ||
| 123 | .modify(|w| w.set_cce(channel.index(), false)); | ||
| 109 | } | 124 | } |
| 110 | 125 | ||
| 111 | pub fn set_frequency(&mut self, freq: Hertz) { | 126 | pub fn set_frequency(&mut self, freq: Hertz) { |
| 112 | <T as embassy_stm32::timer::low_level::GeneralPurpose32bitInstance>::set_frequency(&mut self.inner, freq); | 127 | self.tim.set_frequency(freq); |
| 113 | } | 128 | } |
| 114 | 129 | ||
| 115 | pub fn get_max_duty(&self) -> u32 { | 130 | pub fn get_max_duty(&self) -> u32 { |
| 116 | T::regs_gp32().arr().read() | 131 | self.tim.regs_gp32().arr().read() |
| 117 | } | 132 | } |
| 118 | 133 | ||
| 119 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { | 134 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { |
| 120 | defmt::assert!(duty < self.get_max_duty()); | 135 | defmt::assert!(duty < self.get_max_duty()); |
| 121 | T::regs_gp32().ccr(channel.index()).write_value(duty) | 136 | self.tim.regs_gp32().ccr(channel.index()).write_value(duty) |
| 122 | } | 137 | } |
| 123 | } | 138 | } |
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs index d81efb541..576506ad3 100644 --- a/examples/stm32h7/src/bin/usb_serial.rs +++ b/examples/stm32h7/src/bin/usb_serial.rs | |||
| @@ -3,8 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::usb_otg::{Driver, Instance}; | 6 | use embassy_stm32::usb::{Driver, Instance}; |
| 7 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 7 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 8 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 8 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 9 | use embassy_usb::driver::EndpointError; | 9 | use embassy_usb::driver::EndpointError; |
| 10 | use embassy_usb::Builder; | 10 | use embassy_usb::Builder; |
| @@ -12,7 +12,7 @@ use futures::future::join; | |||
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 13 | ||
| 14 | bind_interrupts!(struct Irqs { | 14 | bind_interrupts!(struct Irqs { |
| 15 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 15 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 16 | }); | 16 | }); |
| 17 | 17 | ||
| 18 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| @@ -40,12 +40,13 @@ async fn main(_spawner: Spawner) { | |||
| 40 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | 40 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz |
| 41 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | 41 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz |
| 42 | config.rcc.voltage_scale = VoltageScale::Scale1; | 42 | config.rcc.voltage_scale = VoltageScale::Scale1; |
| 43 | config.rcc.mux.usbsel = mux::Usbsel::HSI48; | ||
| 43 | } | 44 | } |
| 44 | let p = embassy_stm32::init(config); | 45 | let p = embassy_stm32::init(config); |
| 45 | 46 | ||
| 46 | // Create the driver, from the HAL. | 47 | // Create the driver, from the HAL. |
| 47 | let mut ep_out_buffer = [0u8; 256]; | 48 | let mut ep_out_buffer = [0u8; 256]; |
| 48 | let mut config = embassy_stm32::usb_otg::Config::default(); | 49 | let mut config = embassy_stm32::usb::Config::default(); |
| 49 | config.vbus_detection = true; | 50 | config.vbus_detection = true; |
| 50 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 51 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 51 | 52 | ||
| @@ -64,7 +65,6 @@ async fn main(_spawner: Spawner) { | |||
| 64 | 65 | ||
| 65 | // Create embassy-usb DeviceBuilder using the driver and config. | 66 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 66 | // It needs some buffers for building the descriptors. | 67 | // It needs some buffers for building the descriptors. |
| 67 | let mut device_descriptor = [0; 256]; | ||
| 68 | let mut config_descriptor = [0; 256]; | 68 | let mut config_descriptor = [0; 256]; |
| 69 | let mut bos_descriptor = [0; 256]; | 69 | let mut bos_descriptor = [0; 256]; |
| 70 | let mut control_buf = [0; 64]; | 70 | let mut control_buf = [0; 64]; |
| @@ -74,7 +74,6 @@ async fn main(_spawner: Spawner) { | |||
| 74 | let mut builder = Builder::new( | 74 | let mut builder = Builder::new( |
| 75 | driver, | 75 | driver, |
| 76 | config, | 76 | config, |
| 77 | &mut device_descriptor, | ||
| 78 | &mut config_descriptor, | 77 | &mut config_descriptor, |
| 79 | &mut bos_descriptor, | 78 | &mut bos_descriptor, |
| 80 | &mut [], // no msos descriptors | 79 | &mut [], // no msos descriptors |
diff --git a/examples/stm32l1/src/bin/usb_serial.rs b/examples/stm32l1/src/bin/usb_serial.rs index f738ea358..653bbd6d2 100644 --- a/examples/stm32l1/src/bin/usb_serial.rs +++ b/examples/stm32l1/src/bin/usb_serial.rs | |||
| @@ -46,7 +46,6 @@ async fn main(_spawner: Spawner) { | |||
| 46 | config.device_protocol = 0x01; | 46 | config.device_protocol = 0x01; |
| 47 | config.composite_with_iads = true; | 47 | config.composite_with_iads = true; |
| 48 | 48 | ||
| 49 | let mut device_descriptor = [0; 256]; | ||
| 50 | let mut config_descriptor = [0; 256]; | 49 | let mut config_descriptor = [0; 256]; |
| 51 | let mut bos_descriptor = [0; 256]; | 50 | let mut bos_descriptor = [0; 256]; |
| 52 | let mut control_buf = [0; 64]; | 51 | let mut control_buf = [0; 64]; |
| @@ -56,7 +55,6 @@ async fn main(_spawner: Spawner) { | |||
| 56 | let mut builder = Builder::new( | 55 | let mut builder = Builder::new( |
| 57 | driver, | 56 | driver, |
| 58 | config, | 57 | config, |
| 59 | &mut device_descriptor, | ||
| 60 | &mut config_descriptor, | 58 | &mut config_descriptor, |
| 61 | &mut bos_descriptor, | 59 | &mut bos_descriptor, |
| 62 | &mut [], // no msos descriptors | 60 | &mut [], // no msos descriptors |
diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index f227812cd..d01b016c0 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs | |||
| @@ -6,9 +6,9 @@ use embassy_executor::Spawner; | |||
| 6 | use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; | 6 | use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; |
| 7 | use embassy_stm32::pac::timer::vals::Mms; | 7 | use embassy_stm32::pac::timer::vals::Mms; |
| 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; | 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; |
| 9 | use embassy_stm32::rcc::low_level::RccPeripheral; | 9 | use embassy_stm32::rcc::frequency; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::timer::low_level::BasicInstance; | 11 | use embassy_stm32::timer::low_level::Timer; |
| 12 | use micromath::F32Ext; | 12 | use micromath::F32Ext; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -22,19 +22,19 @@ async fn main(spawner: Spawner) { | |||
| 22 | // Obtain two independent channels (p.DAC1 can only be consumed once, though!) | 22 | // Obtain two independent channels (p.DAC1 can only be consumed once, though!) |
| 23 | let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); | 23 | let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); |
| 24 | 24 | ||
| 25 | spawner.spawn(dac_task1(dac_ch1)).ok(); | 25 | spawner.spawn(dac_task1(p.TIM6, dac_ch1)).ok(); |
| 26 | spawner.spawn(dac_task2(dac_ch2)).ok(); | 26 | spawner.spawn(dac_task2(p.TIM7, dac_ch2)).ok(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | #[embassy_executor::task] | 29 | #[embassy_executor::task] |
| 30 | async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | 30 | async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { |
| 31 | let data: &[u8; 256] = &calculate_array::<256>(); | 31 | let data: &[u8; 256] = &calculate_array::<256>(); |
| 32 | 32 | ||
| 33 | info!("TIM6 frequency is {}", TIM6::frequency()); | 33 | info!("TIM6 frequency is {}", frequency::<TIM6>()); |
| 34 | const FREQUENCY: Hertz = Hertz::hz(200); | 34 | const FREQUENCY: Hertz = Hertz::hz(200); |
| 35 | 35 | ||
| 36 | // Compute the reload value such that we obtain the FREQUENCY for the sine | 36 | // Compute the reload value such that we obtain the FREQUENCY for the sine |
| 37 | let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; | 37 | let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32; |
| 38 | 38 | ||
| 39 | // Depends on your clock and on the specific chip used, you may need higher or lower values here | 39 | // Depends on your clock and on the specific chip used, you may need higher or lower values here |
| 40 | if reload < 10 { | 40 | if reload < 10 { |
| @@ -45,17 +45,17 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 45 | dac.set_triggering(true); | 45 | dac.set_triggering(true); |
| 46 | dac.enable(); | 46 | dac.enable(); |
| 47 | 47 | ||
| 48 | TIM6::enable_and_reset(); | 48 | let tim = Timer::new(tim); |
| 49 | TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 49 | tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 50 | TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 50 | tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 51 | TIM6::regs_basic().cr1().modify(|w| { | 51 | tim.regs_basic().cr1().modify(|w| { |
| 52 | w.set_opm(false); | 52 | w.set_opm(false); |
| 53 | w.set_cen(true); | 53 | w.set_cen(true); |
| 54 | }); | 54 | }); |
| 55 | 55 | ||
| 56 | debug!( | 56 | debug!( |
| 57 | "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", | 57 | "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", |
| 58 | TIM6::frequency(), | 58 | frequency::<TIM6>(), |
| 59 | FREQUENCY, | 59 | FREQUENCY, |
| 60 | reload, | 60 | reload, |
| 61 | reload as u16, | 61 | reload as u16, |
| @@ -70,22 +70,22 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | #[embassy_executor::task] | 72 | #[embassy_executor::task] |
| 73 | async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | 73 | async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { |
| 74 | let data: &[u8; 256] = &calculate_array::<256>(); | 74 | let data: &[u8; 256] = &calculate_array::<256>(); |
| 75 | 75 | ||
| 76 | info!("TIM7 frequency is {}", TIM7::frequency()); | 76 | info!("TIM7 frequency is {}", frequency::<TIM7>()); |
| 77 | 77 | ||
| 78 | const FREQUENCY: Hertz = Hertz::hz(600); | 78 | const FREQUENCY: Hertz = Hertz::hz(600); |
| 79 | let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; | 79 | let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32; |
| 80 | 80 | ||
| 81 | if reload < 10 { | 81 | if reload < 10 { |
| 82 | error!("Reload value {} below threshold!", reload); | 82 | error!("Reload value {} below threshold!", reload); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | TIM7::enable_and_reset(); | 85 | let tim = Timer::new(tim); |
| 86 | TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 86 | tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 87 | TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 87 | tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 88 | TIM7::regs_basic().cr1().modify(|w| { | 88 | tim.regs_basic().cr1().modify(|w| { |
| 89 | w.set_opm(false); | 89 | w.set_opm(false); |
| 90 | w.set_cen(true); | 90 | w.set_cen(true); |
| 91 | }); | 91 | }); |
| @@ -96,7 +96,7 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | |||
| 96 | 96 | ||
| 97 | debug!( | 97 | debug!( |
| 98 | "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", | 98 | "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", |
| 99 | TIM7::frequency(), | 99 | frequency::<TIM7>(), |
| 100 | FREQUENCY, | 100 | FREQUENCY, |
| 101 | reload, | 101 | reload, |
| 102 | reload as u16, | 102 | reload as u16, |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 32bfab6eb..343e09e68 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -42,7 +42,7 @@ bind_interrupts!(struct Irqs { | |||
| 42 | RNG => rng::InterruptHandler<peripherals::RNG>; | 42 | RNG => rng::InterruptHandler<peripherals::RNG>; |
| 43 | }); | 43 | }); |
| 44 | 44 | ||
| 45 | use embassy_net_adin1110::{self, Device, Runner, ADIN1110}; | 45 | use embassy_net_adin1110::{Device, Runner, ADIN1110}; |
| 46 | use embedded_hal_bus::spi::ExclusiveDevice; | 46 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 47 | use hal::gpio::Pull; | 47 | use hal::gpio::Pull; |
| 48 | use hal::i2c::Config as I2C_Config; | 48 | use hal::i2c::Config as I2C_Config; |
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 9247e56a1..198504b59 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs | |||
| @@ -4,9 +4,8 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use defmt_rtt as _; // global logger | 5 | use defmt_rtt as _; // global logger |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rcc::*; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::usb_otg::{Driver, Instance}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | ||
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 11 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 12 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| @@ -14,7 +13,7 @@ use futures::future::join; | |||
| 14 | use panic_probe as _; | 13 | use panic_probe as _; |
| 15 | 14 | ||
| 16 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 17 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 18 | }); | 17 | }); |
| 19 | 18 | ||
| 20 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| @@ -22,23 +21,26 @@ async fn main(_spawner: Spawner) { | |||
| 22 | info!("Hello World!"); | 21 | info!("Hello World!"); |
| 23 | 22 | ||
| 24 | let mut config = Config::default(); | 23 | let mut config = Config::default(); |
| 25 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | 24 | { |
| 26 | config.rcc.sys = Sysclk::PLL1_R; | 25 | use embassy_stm32::rcc::*; |
| 27 | config.rcc.hsi = true; | 26 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB |
| 28 | config.rcc.pll = Some(Pll { | 27 | config.rcc.sys = Sysclk::PLL1_R; |
| 29 | source: PllSource::HSI, | 28 | config.rcc.hsi = true; |
| 30 | prediv: PllPreDiv::DIV1, | 29 | config.rcc.pll = Some(Pll { |
| 31 | mul: PllMul::MUL10, | 30 | source: PllSource::HSI, |
| 32 | divp: None, | 31 | prediv: PllPreDiv::DIV1, |
| 33 | divq: None, | 32 | mul: PllMul::MUL10, |
| 34 | divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) | 33 | divp: None, |
| 35 | }); | 34 | divq: None, |
| 36 | 35 | divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) | |
| 36 | }); | ||
| 37 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; | ||
| 38 | } | ||
| 37 | let p = embassy_stm32::init(config); | 39 | let p = embassy_stm32::init(config); |
| 38 | 40 | ||
| 39 | // Create the driver, from the HAL. | 41 | // Create the driver, from the HAL. |
| 40 | let mut ep_out_buffer = [0u8; 256]; | 42 | let mut ep_out_buffer = [0u8; 256]; |
| 41 | let mut config = embassy_stm32::usb_otg::Config::default(); | 43 | let mut config = embassy_stm32::usb::Config::default(); |
| 42 | config.vbus_detection = true; | 44 | config.vbus_detection = true; |
| 43 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 45 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 44 | 46 | ||
| @@ -58,7 +60,6 @@ async fn main(_spawner: Spawner) { | |||
| 58 | 60 | ||
| 59 | // Create embassy-usb DeviceBuilder using the driver and config. | 61 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 60 | // It needs some buffers for building the descriptors. | 62 | // It needs some buffers for building the descriptors. |
| 61 | let mut device_descriptor = [0; 256]; | ||
| 62 | let mut config_descriptor = [0; 256]; | 63 | let mut config_descriptor = [0; 256]; |
| 63 | let mut bos_descriptor = [0; 256]; | 64 | let mut bos_descriptor = [0; 256]; |
| 64 | let mut control_buf = [0; 64]; | 65 | let mut control_buf = [0; 64]; |
| @@ -68,7 +69,6 @@ async fn main(_spawner: Spawner) { | |||
| 68 | let mut builder = Builder::new( | 69 | let mut builder = Builder::new( |
| 69 | driver, | 70 | driver, |
| 70 | config, | 71 | config, |
| 71 | &mut device_descriptor, | ||
| 72 | &mut config_descriptor, | 72 | &mut config_descriptor, |
| 73 | &mut bos_descriptor, | 73 | &mut bos_descriptor, |
| 74 | &mut [], // no msos descriptors | 74 | &mut [], // no msos descriptors |
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index f6d8b16d0..7f73fd677 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs | |||
| @@ -5,7 +5,6 @@ use defmt::*; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_net::tcp::TcpSocket; | 6 | use embassy_net::tcp::TcpSocket; |
| 7 | use embassy_net::{Stack, StackResources}; | 7 | use embassy_net::{Stack, StackResources}; |
| 8 | use embassy_stm32::rcc::*; | ||
| 9 | use embassy_stm32::rng::Rng; | 8 | use embassy_stm32::rng::Rng; |
| 10 | use embassy_stm32::usb::Driver; | 9 | use embassy_stm32::usb::Driver; |
| 11 | use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; | 10 | use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; |
| @@ -44,17 +43,22 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! { | |||
| 44 | #[embassy_executor::main] | 43 | #[embassy_executor::main] |
| 45 | async fn main(spawner: Spawner) { | 44 | async fn main(spawner: Spawner) { |
| 46 | let mut config = Config::default(); | 45 | let mut config = Config::default(); |
| 47 | config.rcc.hsi = true; | 46 | { |
| 48 | config.rcc.sys = Sysclk::PLL1_R; | 47 | use embassy_stm32::rcc::*; |
| 49 | config.rcc.pll = Some(Pll { | 48 | config.rcc.hsi = true; |
| 50 | // 80Mhz clock (16 / 1 * 10 / 2) | 49 | config.rcc.sys = Sysclk::PLL1_R; |
| 51 | source: PllSource::HSI, | 50 | config.rcc.pll = Some(Pll { |
| 52 | prediv: PllPreDiv::DIV1, | 51 | // 80Mhz clock (16 / 1 * 10 / 2) |
| 53 | mul: PllMul::MUL10, | 52 | source: PllSource::HSI, |
| 54 | divp: None, | 53 | prediv: PllPreDiv::DIV1, |
| 55 | divq: None, | 54 | mul: PllMul::MUL10, |
| 56 | divr: Some(PllRDiv::DIV2), | 55 | divp: None, |
| 57 | }); | 56 | divq: None, |
| 57 | divr: Some(PllRDiv::DIV2), | ||
| 58 | }); | ||
| 59 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 60 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; | ||
| 61 | } | ||
| 58 | let p = embassy_stm32::init(config); | 62 | let p = embassy_stm32::init(config); |
| 59 | 63 | ||
| 60 | // Create the driver, from the HAL. | 64 | // Create the driver, from the HAL. |
| @@ -75,14 +79,12 @@ async fn main(spawner: Spawner) { | |||
| 75 | config.device_protocol = 0x01; | 79 | config.device_protocol = 0x01; |
| 76 | 80 | ||
| 77 | // Create embassy-usb DeviceBuilder using the driver and config. | 81 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 78 | static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 79 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 82 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 80 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | 83 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); |
| 81 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | 84 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); |
| 82 | let mut builder = Builder::new( | 85 | let mut builder = Builder::new( |
| 83 | driver, | 86 | driver, |
| 84 | config, | 87 | config, |
| 85 | &mut DEVICE_DESC.init([0; 256])[..], | ||
| 86 | &mut CONFIG_DESC.init([0; 256])[..], | 88 | &mut CONFIG_DESC.init([0; 256])[..], |
| 87 | &mut BOS_DESC.init([0; 256])[..], | 89 | &mut BOS_DESC.init([0; 256])[..], |
| 88 | &mut [], // no msos descriptors | 90 | &mut [], // no msos descriptors |
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index c51ed96e0..9d30205bb 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_stm32::rcc::*; | ||
| 8 | use embassy_stm32::usb::Driver; | 7 | use embassy_stm32::usb::Driver; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 10 | use embassy_time::Timer; | 9 | use embassy_time::Timer; |
| @@ -21,17 +20,22 @@ bind_interrupts!(struct Irqs { | |||
| 21 | #[embassy_executor::main] | 20 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 21 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 22 | let mut config = Config::default(); |
| 24 | config.rcc.hsi = true; | 23 | { |
| 25 | config.rcc.sys = Sysclk::PLL1_R; | 24 | use embassy_stm32::rcc::*; |
| 26 | config.rcc.pll = Some(Pll { | 25 | config.rcc.hsi = true; |
| 27 | // 80Mhz clock (16 / 1 * 10 / 2) | 26 | config.rcc.sys = Sysclk::PLL1_R; |
| 28 | source: PllSource::HSI, | 27 | config.rcc.pll = Some(Pll { |
| 29 | prediv: PllPreDiv::DIV1, | 28 | // 80Mhz clock (16 / 1 * 10 / 2) |
| 30 | mul: PllMul::MUL10, | 29 | source: PllSource::HSI, |
| 31 | divp: None, | 30 | prediv: PllPreDiv::DIV1, |
| 32 | divq: None, | 31 | mul: PllMul::MUL10, |
| 33 | divr: Some(PllRDiv::DIV2), | 32 | divp: None, |
| 34 | }); | 33 | divq: None, |
| 34 | divr: Some(PllRDiv::DIV2), | ||
| 35 | }); | ||
| 36 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 37 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; | ||
| 38 | } | ||
| 35 | let p = embassy_stm32::init(config); | 39 | let p = embassy_stm32::init(config); |
| 36 | 40 | ||
| 37 | // Create the driver, from the HAL. | 41 | // Create the driver, from the HAL. |
| @@ -47,7 +51,6 @@ async fn main(_spawner: Spawner) { | |||
| 47 | 51 | ||
| 48 | // Create embassy-usb DeviceBuilder using the driver and config. | 52 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 49 | // It needs some buffers for building the descriptors. | 53 | // It needs some buffers for building the descriptors. |
| 50 | let mut device_descriptor = [0; 256]; | ||
| 51 | let mut config_descriptor = [0; 256]; | 54 | let mut config_descriptor = [0; 256]; |
| 52 | let mut bos_descriptor = [0; 256]; | 55 | let mut bos_descriptor = [0; 256]; |
| 53 | let mut control_buf = [0; 64]; | 56 | let mut control_buf = [0; 64]; |
| @@ -58,7 +61,6 @@ async fn main(_spawner: Spawner) { | |||
| 58 | let mut builder = Builder::new( | 61 | let mut builder = Builder::new( |
| 59 | driver, | 62 | driver, |
| 60 | config, | 63 | config, |
| 61 | &mut device_descriptor, | ||
| 62 | &mut config_descriptor, | 64 | &mut config_descriptor, |
| 63 | &mut bos_descriptor, | 65 | &mut bos_descriptor, |
| 64 | &mut [], // no msos descriptors | 66 | &mut [], // no msos descriptors |
diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 87987f2ce..a64bda31b 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_stm32::rcc::*; | ||
| 8 | use embassy_stm32::usb::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| @@ -19,17 +18,22 @@ bind_interrupts!(struct Irqs { | |||
| 19 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 21 | let mut config = Config::default(); | 20 | let mut config = Config::default(); |
| 22 | config.rcc.hsi = true; | 21 | { |
| 23 | config.rcc.sys = Sysclk::PLL1_R; | 22 | use embassy_stm32::rcc::*; |
| 24 | config.rcc.pll = Some(Pll { | 23 | config.rcc.hsi = true; |
| 25 | // 80Mhz clock (16 / 1 * 10 / 2) | 24 | config.rcc.sys = Sysclk::PLL1_R; |
| 26 | source: PllSource::HSI, | 25 | config.rcc.pll = Some(Pll { |
| 27 | prediv: PllPreDiv::DIV1, | 26 | // 80Mhz clock (16 / 1 * 10 / 2) |
| 28 | mul: PllMul::MUL10, | 27 | source: PllSource::HSI, |
| 29 | divp: None, | 28 | prediv: PllPreDiv::DIV1, |
| 30 | divq: None, | 29 | mul: PllMul::MUL10, |
| 31 | divr: Some(PllRDiv::DIV2), | 30 | divp: None, |
| 32 | }); | 31 | divq: None, |
| 32 | divr: Some(PllRDiv::DIV2), | ||
| 33 | }); | ||
| 34 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 35 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; | ||
| 36 | } | ||
| 33 | let p = embassy_stm32::init(config); | 37 | let p = embassy_stm32::init(config); |
| 34 | 38 | ||
| 35 | info!("Hello World!"); | 39 | info!("Hello World!"); |
| @@ -43,7 +47,6 @@ async fn main(_spawner: Spawner) { | |||
| 43 | 47 | ||
| 44 | // Create embassy-usb DeviceBuilder using the driver and config. | 48 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 45 | // It needs some buffers for building the descriptors. | 49 | // It needs some buffers for building the descriptors. |
| 46 | let mut device_descriptor = [0; 256]; | ||
| 47 | let mut config_descriptor = [0; 256]; | 50 | let mut config_descriptor = [0; 256]; |
| 48 | let mut bos_descriptor = [0; 256]; | 51 | let mut bos_descriptor = [0; 256]; |
| 49 | let mut control_buf = [0; 7]; | 52 | let mut control_buf = [0; 7]; |
| @@ -53,7 +56,6 @@ async fn main(_spawner: Spawner) { | |||
| 53 | let mut builder = Builder::new( | 56 | let mut builder = Builder::new( |
| 54 | driver, | 57 | driver, |
| 55 | config, | 58 | config, |
| 56 | &mut device_descriptor, | ||
| 57 | &mut config_descriptor, | 59 | &mut config_descriptor, |
| 58 | &mut bos_descriptor, | 60 | &mut bos_descriptor, |
| 59 | &mut [], // no msos descriptors | 61 | &mut [], // no msos descriptors |
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index 61851e5a2..6a313efb0 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use defmt_rtt as _; // global logger | 5 | use defmt_rtt as _; // global logger |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::usb_otg::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| @@ -13,7 +13,7 @@ use futures::future::join; | |||
| 13 | use panic_probe as _; | 13 | use panic_probe as _; |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | 15 | bind_interrupts!(struct Irqs { |
| 16 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | 16 | OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; |
| 17 | }); | 17 | }); |
| 18 | 18 | ||
| 19 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| @@ -35,13 +35,14 @@ async fn main(_spawner: Spawner) { | |||
| 35 | config.rcc.sys = Sysclk::PLL1_R; | 35 | config.rcc.sys = Sysclk::PLL1_R; |
| 36 | config.rcc.voltage_range = VoltageScale::RANGE1; | 36 | config.rcc.voltage_range = VoltageScale::RANGE1; |
| 37 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | 37 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB |
| 38 | config.rcc.mux.iclksel = mux::Iclksel::HSI48; // USB uses ICLK | ||
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | let p = embassy_stm32::init(config); | 41 | let p = embassy_stm32::init(config); |
| 41 | 42 | ||
| 42 | // Create the driver, from the HAL. | 43 | // Create the driver, from the HAL. |
| 43 | let mut ep_out_buffer = [0u8; 256]; | 44 | let mut ep_out_buffer = [0u8; 256]; |
| 44 | let mut config = embassy_stm32::usb_otg::Config::default(); | 45 | let mut config = embassy_stm32::usb::Config::default(); |
| 45 | config.vbus_detection = false; | 46 | config.vbus_detection = false; |
| 46 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 47 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 47 | 48 | ||
| @@ -60,7 +61,6 @@ async fn main(_spawner: Spawner) { | |||
| 60 | 61 | ||
| 61 | // Create embassy-usb DeviceBuilder using the driver and config. | 62 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 62 | // It needs some buffers for building the descriptors. | 63 | // It needs some buffers for building the descriptors. |
| 63 | let mut device_descriptor = [0; 256]; | ||
| 64 | let mut config_descriptor = [0; 256]; | 64 | let mut config_descriptor = [0; 256]; |
| 65 | let mut bos_descriptor = [0; 256]; | 65 | let mut bos_descriptor = [0; 256]; |
| 66 | let mut control_buf = [0; 64]; | 66 | let mut control_buf = [0; 64]; |
| @@ -70,7 +70,6 @@ async fn main(_spawner: Spawner) { | |||
| 70 | let mut builder = Builder::new( | 70 | let mut builder = Builder::new( |
| 71 | driver, | 71 | driver, |
| 72 | config, | 72 | config, |
| 73 | &mut device_descriptor, | ||
| 74 | &mut config_descriptor, | 73 | &mut config_descriptor, |
| 75 | &mut bos_descriptor, | 74 | &mut bos_descriptor, |
| 76 | &mut [], // no msos descriptors | 75 | &mut [], // no msos descriptors |
diff --git a/rust-toolchain-nightly.toml b/rust-toolchain-nightly.toml index b8a7db353..98696fd2b 100644 --- a/rust-toolchain-nightly.toml +++ b/rust-toolchain-nightly.toml | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | [toolchain] | 1 | [toolchain] |
| 2 | channel = "nightly-2023-12-20" | 2 | channel = "nightly-2024-03-20" |
| 3 | components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ] | 3 | components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ] |
| 4 | targets = [ | 4 | targets = [ |
| 5 | "thumbv7em-none-eabi", | 5 | "thumbv7em-none-eabi", |
diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a6fe52ee2..2f5d17069 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | [toolchain] | 1 | [toolchain] |
| 2 | channel = "1.75" | 2 | channel = "1.77" |
| 3 | components = [ "rust-src", "rustfmt", "llvm-tools" ] | 3 | components = [ "rust-src", "rustfmt", "llvm-tools" ] |
| 4 | targets = [ | 4 | targets = [ |
| 5 | "thumbv7em-none-eabi", | 5 | "thumbv7em-none-eabi", |
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs index 8aed9b80c..e9c6f3122 100644 --- a/tests/rp/src/bin/gpio_multicore.rs +++ b/tests/rp/src/bin/gpio_multicore.rs | |||
| @@ -21,10 +21,14 @@ static CHANNEL1: Channel<CriticalSectionRawMutex, (), 1> = Channel::new(); | |||
| 21 | #[cortex_m_rt::entry] | 21 | #[cortex_m_rt::entry] |
| 22 | fn main() -> ! { | 22 | fn main() -> ! { |
| 23 | let p = embassy_rp::init(Default::default()); | 23 | let p = embassy_rp::init(Default::default()); |
| 24 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 24 | spawn_core1( |
| 25 | let executor1 = EXECUTOR1.init(Executor::new()); | 25 | p.CORE1, |
| 26 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); | 26 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 27 | }); | 27 | move || { |
| 28 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 29 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); | ||
| 30 | }, | ||
| 31 | ); | ||
| 28 | let executor0 = EXECUTOR0.init(Executor::new()); | 32 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 29 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); | 33 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); |
| 30 | } | 34 | } |
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs index 153b37999..9615007bd 100644 --- a/tests/rp/src/bin/i2c.rs +++ b/tests/rp/src/bin/i2c.rs | |||
| @@ -210,10 +210,14 @@ async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { | |||
| 210 | config.addr = DEV_ADDR as u16; | 210 | config.addr = DEV_ADDR as u16; |
| 211 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | 211 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); |
| 212 | 212 | ||
| 213 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 213 | spawn_core1( |
| 214 | let executor1 = EXECUTOR1.init(Executor::new()); | 214 | p.CORE1, |
| 215 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | 215 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 216 | }); | 216 | move || { |
| 217 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 218 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | ||
| 219 | }, | ||
| 220 | ); | ||
| 217 | 221 | ||
| 218 | let c_sda = p.PIN_21; | 222 | let c_sda = p.PIN_21; |
| 219 | let c_scl = p.PIN_20; | 223 | let c_scl = p.PIN_20; |
diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs index 60d9f85ec..783ea0f27 100644 --- a/tests/rp/src/bin/multicore.rs +++ b/tests/rp/src/bin/multicore.rs | |||
| @@ -19,10 +19,14 @@ static CHANNEL1: Channel<CriticalSectionRawMutex, bool, 1> = Channel::new(); | |||
| 19 | #[cortex_m_rt::entry] | 19 | #[cortex_m_rt::entry] |
| 20 | fn main() -> ! { | 20 | fn main() -> ! { |
| 21 | let p = embassy_rp::init(Default::default()); | 21 | let p = embassy_rp::init(Default::default()); |
| 22 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 22 | spawn_core1( |
| 23 | let executor1 = EXECUTOR1.init(Executor::new()); | 23 | p.CORE1, |
| 24 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); | 24 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 25 | }); | 25 | move || { |
| 26 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 27 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); | ||
| 28 | }, | ||
| 29 | ); | ||
| 26 | let executor0 = EXECUTOR0.init(Executor::new()); | 30 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 27 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); | 31 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); |
| 28 | } | 32 | } |
