diff options
| author | Timo Kröger <[email protected]> | 2023-01-01 21:34:20 +0100 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2023-01-04 15:58:26 +0100 |
| commit | 68c186309f5da13266118a5c6b90c9082f73cbfb (patch) | |
| tree | 3f6c7b3ffdc0715ceaea463415e3aadb47f1efac | |
| parent | 0aa2a9ac2705ead5186d4c1d53bba55064c33db7 (diff) | |
rp: Common init function for BufferedUart
BufferedUart, BufferedUartRx and BufferedUartTX can all use the same init code.
| -rw-r--r-- | embassy-rp/src/uart/buffered.rs | 186 |
1 files changed, 64 insertions, 122 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index 1d1fe37c2..d853618a0 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs | |||
| @@ -38,6 +38,38 @@ pub struct BufferedUartTx<'d, T: Instance> { | |||
| 38 | phantom: PhantomData<&'d mut T>, | 38 | phantom: PhantomData<&'d mut T>, |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | fn init<'d, T: Instance + 'd>( | ||
| 42 | irq: PeripheralRef<'d, T::Interrupt>, | ||
| 43 | tx: Option<PeripheralRef<'d, AnyPin>>, | ||
| 44 | rx: Option<PeripheralRef<'d, AnyPin>>, | ||
| 45 | rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 46 | cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 47 | tx_buffer: &'d mut [u8], | ||
| 48 | rx_buffer: &'d mut [u8], | ||
| 49 | config: Config, | ||
| 50 | ) { | ||
| 51 | let regs = T::regs(); | ||
| 52 | unsafe { | ||
| 53 | regs.uartimsc().modify(|w| { | ||
| 54 | w.set_rxim(true); | ||
| 55 | w.set_rtim(true); | ||
| 56 | w.set_txim(true); | ||
| 57 | }); | ||
| 58 | } | ||
| 59 | |||
| 60 | super::Uart::<'d, T, Async>::init(tx, rx, rts, cts, config); | ||
| 61 | |||
| 62 | let state = T::state(); | ||
| 63 | let len = tx_buffer.len(); | ||
| 64 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 65 | let len = rx_buffer.len(); | ||
| 66 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||
| 67 | |||
| 68 | irq.set_handler(on_interrupt::<T>); | ||
| 69 | irq.unpend(); | ||
| 70 | irq.enable(); | ||
| 71 | } | ||
| 72 | |||
| 41 | impl<'d, T: Instance> BufferedUart<'d, T> { | 73 | impl<'d, T: Instance> BufferedUart<'d, T> { |
| 42 | pub fn new( | 74 | pub fn new( |
| 43 | _uart: impl Peripheral<P = T> + 'd, | 75 | _uart: impl Peripheral<P = T> + 'd, |
| @@ -48,17 +80,18 @@ impl<'d, T: Instance> BufferedUart<'d, T> { | |||
| 48 | rx_buffer: &'d mut [u8], | 80 | rx_buffer: &'d mut [u8], |
| 49 | config: Config, | 81 | config: Config, |
| 50 | ) -> Self { | 82 | ) -> Self { |
| 51 | into_ref!(tx, rx); | 83 | into_ref!(irq, tx, rx); |
| 52 | Self::new_inner( | 84 | init::<T>( |
| 53 | irq, | 85 | irq, |
| 54 | tx.map_into(), | 86 | Some(tx.map_into()), |
| 55 | rx.map_into(), | 87 | Some(rx.map_into()), |
| 56 | None, | 88 | None, |
| 57 | None, | 89 | None, |
| 58 | tx_buffer, | 90 | tx_buffer, |
| 59 | rx_buffer, | 91 | rx_buffer, |
| 60 | config, | 92 | config, |
| 61 | ) | 93 | ); |
| 94 | Self { phantom: PhantomData } | ||
| 62 | } | 95 | } |
| 63 | 96 | ||
| 64 | pub fn new_with_rtscts( | 97 | pub fn new_with_rtscts( |
| @@ -72,58 +105,17 @@ impl<'d, T: Instance> BufferedUart<'d, T> { | |||
| 72 | rx_buffer: &'d mut [u8], | 105 | rx_buffer: &'d mut [u8], |
| 73 | config: Config, | 106 | config: Config, |
| 74 | ) -> Self { | 107 | ) -> Self { |
| 75 | into_ref!(tx, rx, cts, rts); | 108 | into_ref!(irq, tx, rx, cts, rts); |
| 76 | Self::new_inner( | 109 | init::<T>( |
| 77 | irq, | 110 | irq, |
| 78 | tx.map_into(), | 111 | Some(tx.map_into()), |
| 79 | rx.map_into(), | 112 | Some(rx.map_into()), |
| 80 | Some(rts.map_into()), | 113 | Some(rts.map_into()), |
| 81 | Some(cts.map_into()), | 114 | Some(cts.map_into()), |
| 82 | tx_buffer, | 115 | tx_buffer, |
| 83 | rx_buffer, | 116 | rx_buffer, |
| 84 | config, | 117 | config, |
| 85 | ) | ||
| 86 | } | ||
| 87 | |||
| 88 | fn new_inner( | ||
| 89 | irq: impl Peripheral<P = T::Interrupt> + 'd, | ||
| 90 | mut tx: PeripheralRef<'d, AnyPin>, | ||
| 91 | mut rx: PeripheralRef<'d, AnyPin>, | ||
| 92 | mut rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 93 | mut cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 94 | tx_buffer: &'d mut [u8], | ||
| 95 | rx_buffer: &'d mut [u8], | ||
| 96 | config: Config, | ||
| 97 | ) -> Self { | ||
| 98 | into_ref!(irq); | ||
| 99 | super::Uart::<'d, T, Async>::init( | ||
| 100 | Some(tx.reborrow()), | ||
| 101 | Some(rx.reborrow()), | ||
| 102 | rts.as_mut().map(|x| x.reborrow()), | ||
| 103 | cts.as_mut().map(|x| x.reborrow()), | ||
| 104 | config, | ||
| 105 | ); | 118 | ); |
| 106 | |||
| 107 | let state = T::state(); | ||
| 108 | let regs = T::regs(); | ||
| 109 | |||
| 110 | let len = tx_buffer.len(); | ||
| 111 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 112 | let len = rx_buffer.len(); | ||
| 113 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||
| 114 | |||
| 115 | unsafe { | ||
| 116 | regs.uartimsc().modify(|w| { | ||
| 117 | w.set_rxim(true); | ||
| 118 | w.set_rtim(true); | ||
| 119 | w.set_txim(true); | ||
| 120 | }); | ||
| 121 | } | ||
| 122 | |||
| 123 | irq.set_handler(on_interrupt::<T>); | ||
| 124 | irq.unpend(); | ||
| 125 | irq.enable(); | ||
| 126 | |||
| 127 | Self { phantom: PhantomData } | 119 | Self { phantom: PhantomData } |
| 128 | } | 120 | } |
| 129 | 121 | ||
| @@ -143,8 +135,9 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 143 | rx_buffer: &'d mut [u8], | 135 | rx_buffer: &'d mut [u8], |
| 144 | config: Config, | 136 | config: Config, |
| 145 | ) -> Self { | 137 | ) -> Self { |
| 146 | into_ref!(rx); | 138 | into_ref!(irq, rx); |
| 147 | Self::new_inner(irq, rx.map_into(), None, rx_buffer, config) | 139 | init::<T>(irq, None, Some(rx.map_into()), None, None, &mut [], rx_buffer, config); |
| 140 | Self { phantom: PhantomData } | ||
| 148 | } | 141 | } |
| 149 | 142 | ||
| 150 | pub fn new_with_rts( | 143 | pub fn new_with_rts( |
| @@ -155,43 +148,17 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 155 | rx_buffer: &'d mut [u8], | 148 | rx_buffer: &'d mut [u8], |
| 156 | config: Config, | 149 | config: Config, |
| 157 | ) -> Self { | 150 | ) -> Self { |
| 158 | into_ref!(rx, rts); | 151 | into_ref!(irq, rx, rts); |
| 159 | Self::new_inner(irq, rx.map_into(), Some(rts.map_into()), rx_buffer, config) | 152 | init::<T>( |
| 160 | } | 153 | irq, |
| 161 | |||
| 162 | fn new_inner( | ||
| 163 | irq: impl Peripheral<P = T::Interrupt> + 'd, | ||
| 164 | mut rx: PeripheralRef<'d, AnyPin>, | ||
| 165 | mut rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 166 | rx_buffer: &'d mut [u8], | ||
| 167 | config: Config, | ||
| 168 | ) -> Self { | ||
| 169 | into_ref!(irq); | ||
| 170 | super::Uart::<'d, T, Async>::init( | ||
| 171 | None, | 154 | None, |
| 172 | Some(rx.reborrow()), | 155 | Some(rx.map_into()), |
| 173 | rts.as_mut().map(|x| x.reborrow()), | 156 | Some(rts.map_into()), |
| 174 | None, | 157 | None, |
| 158 | &mut [], | ||
| 159 | rx_buffer, | ||
| 175 | config, | 160 | config, |
| 176 | ); | 161 | ); |
| 177 | |||
| 178 | let state = T::state(); | ||
| 179 | let regs = T::regs(); | ||
| 180 | |||
| 181 | let len = rx_buffer.len(); | ||
| 182 | unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||
| 183 | |||
| 184 | unsafe { | ||
| 185 | regs.uartimsc().modify(|w| { | ||
| 186 | w.set_rxim(true); | ||
| 187 | w.set_rtim(true); | ||
| 188 | }); | ||
| 189 | } | ||
| 190 | |||
| 191 | irq.set_handler(on_interrupt::<T>); | ||
| 192 | irq.unpend(); | ||
| 193 | irq.enable(); | ||
| 194 | |||
| 195 | Self { phantom: PhantomData } | 162 | Self { phantom: PhantomData } |
| 196 | } | 163 | } |
| 197 | 164 | ||
| @@ -231,7 +198,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 231 | fn consume(amt: usize) { | 198 | fn consume(amt: usize) { |
| 232 | let state = T::state(); | 199 | let state = T::state(); |
| 233 | let mut rx_reader = unsafe { state.rx_buf.reader() }; | 200 | let mut rx_reader = unsafe { state.rx_buf.reader() }; |
| 234 | rx_reader.pop_done(amt) | 201 | rx_reader.pop_done(amt); |
| 235 | } | 202 | } |
| 236 | } | 203 | } |
| 237 | 204 | ||
| @@ -243,8 +210,9 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 243 | tx_buffer: &'d mut [u8], | 210 | tx_buffer: &'d mut [u8], |
| 244 | config: Config, | 211 | config: Config, |
| 245 | ) -> Self { | 212 | ) -> Self { |
| 246 | into_ref!(tx); | 213 | into_ref!(irq, tx); |
| 247 | Self::new_inner(irq, tx.map_into(), None, tx_buffer, config) | 214 | init::<T>(irq, Some(tx.map_into()), None, None, None, tx_buffer, &mut [], config); |
| 215 | Self { phantom: PhantomData } | ||
| 248 | } | 216 | } |
| 249 | 217 | ||
| 250 | pub fn new_with_cts( | 218 | pub fn new_with_cts( |
| @@ -255,42 +223,17 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 255 | tx_buffer: &'d mut [u8], | 223 | tx_buffer: &'d mut [u8], |
| 256 | config: Config, | 224 | config: Config, |
| 257 | ) -> Self { | 225 | ) -> Self { |
| 258 | into_ref!(tx, cts); | 226 | into_ref!(irq, tx, cts); |
| 259 | Self::new_inner(irq, tx.map_into(), Some(cts.map_into()), tx_buffer, config) | 227 | init::<T>( |
| 260 | } | 228 | irq, |
| 261 | 229 | Some(tx.map_into()), | |
| 262 | fn new_inner( | ||
| 263 | irq: impl Peripheral<P = T::Interrupt> + 'd, | ||
| 264 | mut tx: PeripheralRef<'d, AnyPin>, | ||
| 265 | mut cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 266 | tx_buffer: &'d mut [u8], | ||
| 267 | config: Config, | ||
| 268 | ) -> Self { | ||
| 269 | into_ref!(irq); | ||
| 270 | super::Uart::<'d, T, Async>::init( | ||
| 271 | Some(tx.reborrow()), | ||
| 272 | None, | 230 | None, |
| 273 | None, | 231 | None, |
| 274 | cts.as_mut().map(|x| x.reborrow()), | 232 | Some(cts.map_into()), |
| 233 | tx_buffer, | ||
| 234 | &mut [], | ||
| 275 | config, | 235 | config, |
| 276 | ); | 236 | ); |
| 277 | |||
| 278 | let state = T::state(); | ||
| 279 | let regs = T::regs(); | ||
| 280 | |||
| 281 | let len = tx_buffer.len(); | ||
| 282 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 283 | |||
| 284 | unsafe { | ||
| 285 | regs.uartimsc().modify(|w| { | ||
| 286 | w.set_txim(true); | ||
| 287 | }); | ||
| 288 | } | ||
| 289 | |||
| 290 | irq.set_handler(on_interrupt::<T>); | ||
| 291 | irq.unpend(); | ||
| 292 | irq.enable(); | ||
| 293 | |||
| 294 | Self { phantom: PhantomData } | 237 | Self { phantom: PhantomData } |
| 295 | } | 238 | } |
| 296 | 239 | ||
| @@ -306,10 +249,9 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 306 | if n == 0 { | 249 | if n == 0 { |
| 307 | state.tx_waker.register(cx.waker()); | 250 | state.tx_waker.register(cx.waker()); |
| 308 | return Poll::Pending; | 251 | return Poll::Pending; |
| 309 | } else { | ||
| 310 | unsafe { T::Interrupt::steal() }.pend(); | ||
| 311 | } | 252 | } |
| 312 | 253 | ||
| 254 | unsafe { T::Interrupt::steal() }.pend(); | ||
| 313 | Poll::Ready(Ok(n)) | 255 | Poll::Ready(Ok(n)) |
| 314 | }) | 256 | }) |
| 315 | } | 257 | } |
