diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-09-17 21:33:18 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-17 21:33:18 +0000 |
| commit | daeb497045d47db3afa926b4e0e9e17973a544d5 (patch) | |
| tree | 7a3adc03ecc265b7eeea7a2e7567a02087b289df | |
| parent | cd128c20faaecc685771997cb4a31f2da4722b17 (diff) | |
| parent | 88eb5cca71a470cca93001943e962b63e15168af (diff) | |
Merge pull request #1917 from MabezDev/set-config-uart
stm32: Implement `set_config` for Uart structs
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 36 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 49 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 16 |
4 files changed, 102 insertions, 3 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 853de98f9..f40bce784 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -323,7 +323,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | /// Reconfigures it with the supplied config. | 325 | /// Reconfigures it with the supplied config. |
| 326 | pub fn reconfigure(&mut self, config: Config) { | 326 | pub fn set_config(&mut self, config: Config) { |
| 327 | let cpha = config.raw_phase(); | 327 | let cpha = config.raw_phase(); |
| 328 | let cpol = config.raw_polarity(); | 328 | let cpol = config.raw_polarity(); |
| 329 | 329 | ||
| @@ -1062,6 +1062,6 @@ foreach_peripheral!( | |||
| 1062 | impl<'d, T: Instance, Tx, Rx> SetConfig for Spi<'d, T, Tx, Rx> { | 1062 | impl<'d, T: Instance, Tx, Rx> SetConfig for Spi<'d, T, Tx, Rx> { |
| 1063 | type Config = Config; | 1063 | type Config = Config; |
| 1064 | fn set_config(&mut self, config: &Self::Config) { | 1064 | fn set_config(&mut self, config: &Self::Config) { |
| 1065 | self.reconfigure(*config); | 1065 | self.set_config(*config); |
| 1066 | } | 1066 | } |
| 1067 | } | 1067 | } |
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index b88eebc79..323d83818 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -114,6 +114,30 @@ pub struct BufferedUartRx<'d, T: BasicInstance> { | |||
| 114 | phantom: PhantomData<&'d mut T>, | 114 | phantom: PhantomData<&'d mut T>, |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { | ||
| 118 | type Config = Config; | ||
| 119 | |||
| 120 | fn set_config(&mut self, config: &Self::Config) { | ||
| 121 | self.set_config(config) | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { | ||
| 126 | type Config = Config; | ||
| 127 | |||
| 128 | fn set_config(&mut self, config: &Self::Config) { | ||
| 129 | self.set_config(config) | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { | ||
| 134 | type Config = Config; | ||
| 135 | |||
| 136 | fn set_config(&mut self, config: &Self::Config) { | ||
| 137 | self.set_config(config) | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 117 | impl<'d, T: BasicInstance> BufferedUart<'d, T> { | 141 | impl<'d, T: BasicInstance> BufferedUart<'d, T> { |
| 118 | pub fn new( | 142 | pub fn new( |
| 119 | peri: impl Peripheral<P = T> + 'd, | 143 | peri: impl Peripheral<P = T> + 'd, |
| @@ -228,6 +252,10 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | |||
| 228 | pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) { | 252 | pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) { |
| 229 | (self.tx, self.rx) | 253 | (self.tx, self.rx) |
| 230 | } | 254 | } |
| 255 | |||
| 256 | pub fn set_config(&mut self, config: &Config) { | ||
| 257 | reconfigure::<T>(config) | ||
| 258 | } | ||
| 231 | } | 259 | } |
| 232 | 260 | ||
| 233 | impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { | 261 | impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { |
| @@ -304,6 +332,10 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { | |||
| 304 | T::Interrupt::pend(); | 332 | T::Interrupt::pend(); |
| 305 | } | 333 | } |
| 306 | } | 334 | } |
| 335 | |||
| 336 | pub fn set_config(&mut self, config: &Config) { | ||
| 337 | reconfigure::<T>(config) | ||
| 338 | } | ||
| 307 | } | 339 | } |
| 308 | 340 | ||
| 309 | impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { | 341 | impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { |
| @@ -374,6 +406,10 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { | |||
| 374 | } | 406 | } |
| 375 | } | 407 | } |
| 376 | } | 408 | } |
| 409 | |||
| 410 | pub fn set_config(&mut self, config: &Config) { | ||
| 411 | reconfigure::<T>(config) | ||
| 412 | } | ||
| 377 | } | 413 | } |
| 378 | 414 | ||
| 379 | impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> { | 415 | impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> { |
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index c6d6cc59c..ff02d0a63 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -5,6 +5,7 @@ use core::marker::PhantomData; | |||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_embedded_hal::SetConfig; | ||
| 8 | use embassy_hal_internal::drop::OnDrop; | 9 | use embassy_hal_internal::drop::OnDrop; |
| 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | use futures::future::{select, Either}; | 11 | use futures::future::{select, Either}; |
| @@ -168,11 +169,28 @@ pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { | |||
| 168 | rx: UartRx<'d, T, RxDma>, | 169 | rx: UartRx<'d, T, RxDma>, |
| 169 | } | 170 | } |
| 170 | 171 | ||
| 172 | impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> { | ||
| 173 | type Config = Config; | ||
| 174 | |||
| 175 | fn set_config(&mut self, config: &Self::Config) { | ||
| 176 | self.tx.set_config(config); | ||
| 177 | self.rx.set_config(config); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 171 | pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { | 181 | pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { |
| 172 | phantom: PhantomData<&'d mut T>, | 182 | phantom: PhantomData<&'d mut T>, |
| 173 | tx_dma: PeripheralRef<'d, TxDma>, | 183 | tx_dma: PeripheralRef<'d, TxDma>, |
| 174 | } | 184 | } |
| 175 | 185 | ||
| 186 | impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { | ||
| 187 | type Config = Config; | ||
| 188 | |||
| 189 | fn set_config(&mut self, config: &Self::Config) { | ||
| 190 | self.set_config(config); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 176 | pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { | 194 | pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { |
| 177 | _peri: PeripheralRef<'d, T>, | 195 | _peri: PeripheralRef<'d, T>, |
| 178 | rx_dma: PeripheralRef<'d, RxDma>, | 196 | rx_dma: PeripheralRef<'d, RxDma>, |
| @@ -181,6 +199,14 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { | |||
| 181 | buffered_sr: stm32_metapac::usart::regs::Sr, | 199 | buffered_sr: stm32_metapac::usart::regs::Sr, |
| 182 | } | 200 | } |
| 183 | 201 | ||
| 202 | impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { | ||
| 203 | type Config = Config; | ||
| 204 | |||
| 205 | fn set_config(&mut self, config: &Self::Config) { | ||
| 206 | self.set_config(config); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 184 | impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { | 210 | impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { |
| 185 | /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. | 211 | /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. |
| 186 | pub fn new( | 212 | pub fn new( |
| @@ -237,6 +263,10 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { | |||
| 237 | } | 263 | } |
| 238 | } | 264 | } |
| 239 | 265 | ||
| 266 | pub fn set_config(&mut self, config: &Config) { | ||
| 267 | reconfigure::<T>(config) | ||
| 268 | } | ||
| 269 | |||
| 240 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> | 270 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> |
| 241 | where | 271 | where |
| 242 | TxDma: crate::usart::TxDma<T>, | 272 | TxDma: crate::usart::TxDma<T>, |
| @@ -334,6 +364,10 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { | |||
| 334 | } | 364 | } |
| 335 | } | 365 | } |
| 336 | 366 | ||
| 367 | pub fn set_config(&mut self, config: &Config) { | ||
| 368 | reconfigure::<T>(config) | ||
| 369 | } | ||
| 370 | |||
| 337 | #[cfg(any(usart_v1, usart_v2))] | 371 | #[cfg(any(usart_v1, usart_v2))] |
| 338 | fn check_rx_flags(&mut self) -> Result<bool, Error> { | 372 | fn check_rx_flags(&mut self) -> Result<bool, Error> { |
| 339 | let r = T::regs(); | 373 | let r = T::regs(); |
| @@ -759,6 +793,10 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | |||
| 759 | } | 793 | } |
| 760 | } | 794 | } |
| 761 | 795 | ||
| 796 | pub fn set_config(&mut self, config: &Config) { | ||
| 797 | reconfigure::<T>(config) | ||
| 798 | } | ||
| 799 | |||
| 762 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> | 800 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> |
| 763 | where | 801 | where |
| 764 | TxDma: crate::usart::TxDma<T>, | 802 | TxDma: crate::usart::TxDma<T>, |
| @@ -804,6 +842,17 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | |||
| 804 | } | 842 | } |
| 805 | } | 843 | } |
| 806 | 844 | ||
| 845 | fn reconfigure<T: BasicInstance>(config: &Config) { | ||
| 846 | T::Interrupt::disable(); | ||
| 847 | let r = T::regs(); | ||
| 848 | |||
| 849 | let cr = r.cr1().read(); | ||
| 850 | configure(r, config, T::frequency(), T::KIND, cr.re(), cr.te()); | ||
| 851 | |||
| 852 | T::Interrupt::unpend(); | ||
| 853 | unsafe { T::Interrupt::enable() }; | ||
| 854 | } | ||
| 855 | |||
| 807 | fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: bool, enable_tx: bool) { | 856 | fn configure(r: Regs, config: &Config, pclk_freq: Hertz, kind: Kind, enable_rx: bool, enable_tx: bool) { |
| 808 | if !enable_rx && !enable_tx { | 857 | if !enable_rx && !enable_tx { |
| 809 | panic!("USART: At least one of RX or TX should be enabled"); | 858 | panic!("USART: At least one of RX or TX should be enabled"); |
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index e990eaca8..eed5ef5d6 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -3,10 +3,11 @@ use core::mem; | |||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_embedded_hal::SetConfig; | ||
| 6 | use embassy_hal_internal::PeripheralRef; | 7 | use embassy_hal_internal::PeripheralRef; |
| 7 | use futures::future::{select, Either}; | 8 | use futures::future::{select, Either}; |
| 8 | 9 | ||
| 9 | use super::{clear_interrupt_flags, rdr, sr, BasicInstance, Error, UartRx}; | 10 | use super::{clear_interrupt_flags, rdr, reconfigure, sr, BasicInstance, Config, Error, UartRx}; |
| 10 | use crate::dma::ReadableRingBuffer; | 11 | use crate::dma::ReadableRingBuffer; |
| 11 | use crate::usart::{Regs, Sr}; | 12 | use crate::usart::{Regs, Sr}; |
| 12 | 13 | ||
| @@ -15,6 +16,14 @@ pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma<T>> { | |||
| 15 | ring_buf: ReadableRingBuffer<'d, RxDma, u8>, | 16 | ring_buf: ReadableRingBuffer<'d, RxDma, u8>, |
| 16 | } | 17 | } |
| 17 | 18 | ||
| 19 | impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> SetConfig for RingBufferedUartRx<'d, T, RxDma> { | ||
| 20 | type Config = Config; | ||
| 21 | |||
| 22 | fn set_config(&mut self, config: &Self::Config) { | ||
| 23 | self.set_config(config); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 18 | impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> { | 27 | impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> { |
| 19 | /// Turn the `UartRx` into a buffered uart which can continously receive in the background | 28 | /// Turn the `UartRx` into a buffered uart which can continously receive in the background |
| 20 | /// without the possibility of loosing bytes. The `dma_buf` is a buffer registered to the | 29 | /// without the possibility of loosing bytes. The `dma_buf` is a buffer registered to the |
| @@ -54,6 +63,11 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> RingBufferedUartRx<'d, T, RxD | |||
| 54 | Err(err) | 63 | Err(err) |
| 55 | } | 64 | } |
| 56 | 65 | ||
| 66 | pub fn set_config(&mut self, config: &Config) { | ||
| 67 | self.teardown_uart(); | ||
| 68 | reconfigure::<T>(config) | ||
| 69 | } | ||
| 70 | |||
| 57 | /// Start uart background receive | 71 | /// Start uart background receive |
| 58 | fn setup_uart(&mut self) { | 72 | fn setup_uart(&mut self) { |
| 59 | // fence before starting DMA. | 73 | // fence before starting DMA. |
