diff options
| author | Christian Perez Llamas <[email protected]> | 2022-11-12 18:48:57 +0100 |
|---|---|---|
| committer | Christian Perez Llamas <[email protected]> | 2022-11-12 18:48:57 +0100 |
| commit | 122a31d20877005c7201d4e7c98da5544666dd1d (patch) | |
| tree | c97037ba880f63a4e03e642c6630efb1042a3cde /embassy-nrf/src/i2s.rs | |
| parent | 10e3c3f2ec358da6d81f2bb9c05936c2ab6da567 (diff) | |
Interrupts, async, sine oscillator
Diffstat (limited to 'embassy-nrf/src/i2s.rs')
| -rw-r--r-- | embassy-nrf/src/i2s.rs | 296 |
1 files changed, 217 insertions, 79 deletions
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index fb6fa4bdf..f5e36f0dd 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs | |||
| @@ -2,17 +2,18 @@ | |||
| 2 | 2 | ||
| 3 | //! I2S | 3 | //! I2S |
| 4 | 4 | ||
| 5 | //use core::future::poll_fn; | 5 | use core::future::poll_fn; |
| 6 | //use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 7 | //use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | //use embassy_hal_common::drop::OnDrop; | 9 | use embassy_cortex_m::interrupt::{InterruptExt, Priority}; |
| 10 | use embassy_hal_common::drop::OnDrop; | ||
| 10 | use embassy_hal_common::{into_ref, PeripheralRef}; | 11 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 11 | 12 | ||
| 12 | //use crate::gpio::sealed::Pin as _; | 13 | //use crate::gpio::sealed::Pin as _; |
| 13 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 14 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 14 | use crate::interrupt::Interrupt; | 15 | use crate::interrupt::Interrupt; |
| 15 | use crate::pac::i2s::CONFIG; | 16 | use crate::pac::i2s::{RegisterBlock, CONFIG, PSEL}; |
| 16 | use crate::Peripheral; | 17 | use crate::Peripheral; |
| 17 | 18 | ||
| 18 | // TODO: Define those in lib.rs somewhere else | 19 | // TODO: Define those in lib.rs somewhere else |
| @@ -35,10 +36,39 @@ pub enum Error { | |||
| 35 | // TODO: add other error variants. | 36 | // TODO: add other error variants. |
| 36 | } | 37 | } |
| 37 | 38 | ||
| 39 | pub const MODE_MASTER_8000: Mode = Mode::Master { | ||
| 40 | freq: MckFreq::_32MDiv125, | ||
| 41 | ratio: Ratio::_32x, | ||
| 42 | }; // error = 0 | ||
| 43 | pub const MODE_MASTER_11025: Mode = Mode::Master { | ||
| 44 | freq: MckFreq::_32MDiv15, | ||
| 45 | ratio: Ratio::_192x, | ||
| 46 | }; // error = 86 | ||
| 47 | pub const MODE_MASTER_16000: Mode = Mode::Master { | ||
| 48 | freq: MckFreq::_32MDiv21, | ||
| 49 | ratio: Ratio::_96x, | ||
| 50 | }; // error = 127 | ||
| 51 | pub const MODE_MASTER_22050: Mode = Mode::Master { | ||
| 52 | freq: MckFreq::_32MDiv15, | ||
| 53 | ratio: Ratio::_96x, | ||
| 54 | }; // error = 172 | ||
| 55 | pub const MODE_MASTER_32000: Mode = Mode::Master { | ||
| 56 | freq: MckFreq::_32MDiv21, | ||
| 57 | ratio: Ratio::_48x, | ||
| 58 | }; // error = 254 | ||
| 59 | pub const MODE_MASTER_44100: Mode = Mode::Master { | ||
| 60 | freq: MckFreq::_32MDiv15, | ||
| 61 | ratio: Ratio::_48x, | ||
| 62 | }; // error = 344 | ||
| 63 | pub const MODE_MASTER_48000: Mode = Mode::Master { | ||
| 64 | freq: MckFreq::_32MDiv21, | ||
| 65 | ratio: Ratio::_32x, | ||
| 66 | }; // error = 381 | ||
| 67 | |||
| 38 | #[derive(Clone)] | 68 | #[derive(Clone)] |
| 39 | #[non_exhaustive] | 69 | #[non_exhaustive] |
| 40 | pub struct Config { | 70 | pub struct Config { |
| 41 | pub ratio: Ratio, | 71 | pub mode: Mode, |
| 42 | pub swidth: SampleWidth, | 72 | pub swidth: SampleWidth, |
| 43 | pub align: Align, | 73 | pub align: Align, |
| 44 | pub format: Format, | 74 | pub format: Format, |
| @@ -48,7 +78,7 @@ pub struct Config { | |||
| 48 | impl Default for Config { | 78 | impl Default for Config { |
| 49 | fn default() -> Self { | 79 | fn default() -> Self { |
| 50 | Self { | 80 | Self { |
| 51 | ratio: Ratio::_32x, | 81 | mode: MODE_MASTER_32000, |
| 52 | swidth: SampleWidth::_16bit, | 82 | swidth: SampleWidth::_16bit, |
| 53 | align: Align::Left, | 83 | align: Align::Left, |
| 54 | format: Format::I2S, | 84 | format: Format::I2S, |
| @@ -57,6 +87,66 @@ impl Default for Config { | |||
| 57 | } | 87 | } |
| 58 | } | 88 | } |
| 59 | 89 | ||
| 90 | /// I2S Mode | ||
| 91 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 92 | pub enum Mode { | ||
| 93 | Master { freq: MckFreq, ratio: Ratio }, | ||
| 94 | Slave, | ||
| 95 | } | ||
| 96 | |||
| 97 | impl Mode { | ||
| 98 | pub fn sample_rate(&self) -> Option<u32> { | ||
| 99 | match self { | ||
| 100 | Mode::Master { freq, ratio } => Some(freq.to_frequency() / ratio.to_divisor()), | ||
| 101 | Mode::Slave => None, | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | /// Master clock generator frequency. | ||
| 107 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 108 | pub enum MckFreq { | ||
| 109 | _32MDiv8, | ||
| 110 | _32MDiv10, | ||
| 111 | _32MDiv11, | ||
| 112 | _32MDiv15, | ||
| 113 | _32MDiv16, | ||
| 114 | _32MDiv21, | ||
| 115 | _32MDiv23, | ||
| 116 | _32MDiv30, | ||
| 117 | _32MDiv31, | ||
| 118 | _32MDiv32, | ||
| 119 | _32MDiv42, | ||
| 120 | _32MDiv63, | ||
| 121 | _32MDiv125, | ||
| 122 | } | ||
| 123 | |||
| 124 | impl MckFreq { | ||
| 125 | const REGISTER_VALUES: &[u32] = &[ | ||
| 126 | 0x20000000, 0x18000000, 0x16000000, 0x11000000, 0x10000000, 0x0C000000, 0x0B000000, 0x08800000, 0x08400000, | ||
| 127 | 0x08000000, 0x06000000, 0x04100000, 0x020C0000, | ||
| 128 | ]; | ||
| 129 | |||
| 130 | const FREQUENCIES: &[u32] = &[ | ||
| 131 | 4000000, 3200000, 2909090, 2133333, 2000000, 1523809, 1391304, 1066666, 1032258, 1000000, 761904, 507936, | ||
| 132 | 256000, | ||
| 133 | ]; | ||
| 134 | |||
| 135 | pub fn to_register_value(&self) -> u32 { | ||
| 136 | Self::REGISTER_VALUES[usize::from(*self)] | ||
| 137 | } | ||
| 138 | |||
| 139 | pub fn to_frequency(&self) -> u32 { | ||
| 140 | Self::FREQUENCIES[usize::from(*self)] | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | impl From<MckFreq> for usize { | ||
| 145 | fn from(variant: MckFreq) -> Self { | ||
| 146 | variant as _ | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 60 | /// MCK / LRCK ratio. | 150 | /// MCK / LRCK ratio. |
| 61 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 151 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 62 | pub enum Ratio { | 152 | pub enum Ratio { |
| @@ -71,6 +161,14 @@ pub enum Ratio { | |||
| 71 | _512x, | 161 | _512x, |
| 72 | } | 162 | } |
| 73 | 163 | ||
| 164 | impl Ratio { | ||
| 165 | const RATIOS: &[u32] = &[32, 48, 64, 96, 128, 192, 256, 384, 512]; | ||
| 166 | |||
| 167 | pub fn to_divisor(&self) -> u32 { | ||
| 168 | Self::RATIOS[u8::from(*self) as usize] | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 74 | impl From<Ratio> for u8 { | 172 | impl From<Ratio> for u8 { |
| 75 | fn from(variant: Ratio) -> Self { | 173 | fn from(variant: Ratio) -> Self { |
| 76 | variant as _ | 174 | variant as _ |
| @@ -136,31 +234,6 @@ impl From<Channels> for u8 { | |||
| 136 | } | 234 | } |
| 137 | } | 235 | } |
| 138 | 236 | ||
| 139 | /// I2S Mode | ||
| 140 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 141 | pub enum Mode { | ||
| 142 | Controller, | ||
| 143 | Peripheral, | ||
| 144 | } | ||
| 145 | |||
| 146 | // /// Master clock generator frequency. | ||
| 147 | // #[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
| 148 | // pub enum MckFreq { | ||
| 149 | // _32MDiv8 = 0x20000000, | ||
| 150 | // _32MDiv10 = 0x18000000, | ||
| 151 | // _32MDiv11 = 0x16000000, | ||
| 152 | // _32MDiv15 = 0x11000000, | ||
| 153 | // _32MDiv16 = 0x10000000, | ||
| 154 | // _32MDiv21 = 0x0C000000, | ||
| 155 | // _32MDiv23 = 0x0B000000, | ||
| 156 | // _32MDiv30 = 0x08800000, | ||
| 157 | // _32MDiv31 = 0x08400000, | ||
| 158 | // _32MDiv32 = 0x08000000, | ||
| 159 | // _32MDiv42 = 0x06000000, | ||
| 160 | // _32MDiv63 = 0x04100000, | ||
| 161 | // _32MDiv125 = 0x020C0000, | ||
| 162 | // } | ||
| 163 | |||
| 164 | /// Interface to the UARTE peripheral using EasyDMA to offload the transmission and reception workload. | 237 | /// Interface to the UARTE peripheral using EasyDMA to offload the transmission and reception workload. |
| 165 | /// | 238 | /// |
| 166 | /// For more details about EasyDMA, consult the module documentation. | 239 | /// For more details about EasyDMA, consult the module documentation. |
| @@ -185,7 +258,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 185 | /// Create a new I2S | 258 | /// Create a new I2S |
| 186 | pub fn new( | 259 | pub fn new( |
| 187 | i2s: impl Peripheral<P = T> + 'd, | 260 | i2s: impl Peripheral<P = T> + 'd, |
| 188 | // irq: impl Peripheral<P = T::Interrupt> + 'd, | 261 | irq: impl Peripheral<P = T::Interrupt> + 'd, |
| 189 | mck: impl Peripheral<P = impl GpioPin> + 'd, | 262 | mck: impl Peripheral<P = impl GpioPin> + 'd, |
| 190 | sck: impl Peripheral<P = impl GpioPin> + 'd, | 263 | sck: impl Peripheral<P = impl GpioPin> + 'd, |
| 191 | lrck: impl Peripheral<P = impl GpioPin> + 'd, | 264 | lrck: impl Peripheral<P = impl GpioPin> + 'd, |
| @@ -196,7 +269,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 196 | into_ref!(mck, sck, lrck, sdin, sdout); | 269 | into_ref!(mck, sck, lrck, sdin, sdout); |
| 197 | Self::new_inner( | 270 | Self::new_inner( |
| 198 | i2s, | 271 | i2s, |
| 199 | // irq, | 272 | irq, |
| 200 | mck.map_into(), | 273 | mck.map_into(), |
| 201 | sck.map_into(), | 274 | sck.map_into(), |
| 202 | lrck.map_into(), | 275 | lrck.map_into(), |
| @@ -208,7 +281,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 208 | 281 | ||
| 209 | fn new_inner( | 282 | fn new_inner( |
| 210 | i2s: impl Peripheral<P = T> + 'd, | 283 | i2s: impl Peripheral<P = T> + 'd, |
| 211 | // irq: impl Peripheral<P = T::Interrupt> + 'd, | 284 | irq: impl Peripheral<P = T::Interrupt> + 'd, |
| 212 | mck: PeripheralRef<'d, AnyPin>, | 285 | mck: PeripheralRef<'d, AnyPin>, |
| 213 | sck: PeripheralRef<'d, AnyPin>, | 286 | sck: PeripheralRef<'d, AnyPin>, |
| 214 | lrck: PeripheralRef<'d, AnyPin>, | 287 | lrck: PeripheralRef<'d, AnyPin>, |
| @@ -216,36 +289,12 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 216 | sdout: PeripheralRef<'d, AnyPin>, | 289 | sdout: PeripheralRef<'d, AnyPin>, |
| 217 | config: Config, | 290 | config: Config, |
| 218 | ) -> Self { | 291 | ) -> Self { |
| 219 | into_ref!(i2s, /* irq, */ mck, sck, lrck, sdin, sdout); | 292 | into_ref!(i2s, irq, mck, sck, lrck, sdin, sdout); |
| 220 | 293 | ||
| 221 | let r = T::regs(); | 294 | let r = T::regs(); |
| 222 | |||
| 223 | Self::apply_config(&r.config, &config); | 295 | Self::apply_config(&r.config, &config); |
| 224 | 296 | Self::select_pins(&r.psel, mck, sck, lrck, sdin, sdout); | |
| 225 | r.psel.mck.write(|w| { | 297 | Self::setup_interrupt(irq, r); |
| 226 | unsafe { w.bits(mck.psel_bits()) }; | ||
| 227 | w.connect().connected() | ||
| 228 | }); | ||
| 229 | |||
| 230 | r.psel.sck.write(|w| { | ||
| 231 | unsafe { w.bits(sck.psel_bits()) }; | ||
| 232 | w.connect().connected() | ||
| 233 | }); | ||
| 234 | |||
| 235 | r.psel.lrck.write(|w| { | ||
| 236 | unsafe { w.bits(lrck.psel_bits()) }; | ||
| 237 | w.connect().connected() | ||
| 238 | }); | ||
| 239 | |||
| 240 | r.psel.sdin.write(|w| { | ||
| 241 | unsafe { w.bits(sdin.psel_bits()) }; | ||
| 242 | w.connect().connected() | ||
| 243 | }); | ||
| 244 | |||
| 245 | r.psel.sdout.write(|w| { | ||
| 246 | unsafe { w.bits(sdout.psel_bits()) }; | ||
| 247 | w.connect().connected() | ||
| 248 | }); | ||
| 249 | 298 | ||
| 250 | r.enable.write(|w| w.enable().enabled()); | 299 | r.enable.write(|w| w.enable().enabled()); |
| 251 | 300 | ||
| @@ -322,19 +371,87 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 322 | self.input.rx(buffer).await | 371 | self.input.rx(buffer).await |
| 323 | } | 372 | } |
| 324 | 373 | ||
| 374 | fn on_interrupt(_: *mut ()) { | ||
| 375 | let r = T::regs(); | ||
| 376 | let s = T::state(); | ||
| 377 | |||
| 378 | if r.events_txptrupd.read().bits() != 0 { | ||
| 379 | s.tx_waker.wake(); | ||
| 380 | r.intenclr.write(|w| w.txptrupd().clear()); | ||
| 381 | } | ||
| 382 | |||
| 383 | if r.events_rxptrupd.read().bits() != 0 { | ||
| 384 | s.rx_waker.wake(); | ||
| 385 | r.intenclr.write(|w| w.rxptrupd().clear()); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 325 | fn apply_config(c: &CONFIG, config: &Config) { | 389 | fn apply_config(c: &CONFIG, config: &Config) { |
| 326 | // TODO support slave too | 390 | match config.mode { |
| 327 | c.mcken.write(|w| w.mcken().enabled()); | 391 | Mode::Master { freq, ratio } => { |
| 328 | c.mckfreq.write(|w| w.mckfreq()._32mdiv16()); | 392 | c.mode.write(|w| w.mode().master()); |
| 329 | c.mode.write(|w| w.mode().master()); | 393 | c.mcken.write(|w| w.mcken().enabled()); |
| 394 | c.mckfreq | ||
| 395 | .write(|w| unsafe { w.mckfreq().bits(freq.to_register_value()) }); | ||
| 396 | c.ratio.write(|w| unsafe { w.ratio().bits(ratio.into()) }); | ||
| 397 | } | ||
| 398 | Mode::Slave => { | ||
| 399 | c.mode.write(|w| w.mode().slave()); | ||
| 400 | } | ||
| 401 | }; | ||
| 330 | 402 | ||
| 331 | c.ratio.write(|w| unsafe { w.ratio().bits(config.ratio.into()) }); | ||
| 332 | c.swidth.write(|w| unsafe { w.swidth().bits(config.swidth.into()) }); | 403 | c.swidth.write(|w| unsafe { w.swidth().bits(config.swidth.into()) }); |
| 333 | c.align.write(|w| w.align().bit(config.align.into())); | 404 | c.align.write(|w| w.align().bit(config.align.into())); |
| 334 | c.format.write(|w| w.format().bit(config.format.into())); | 405 | c.format.write(|w| w.format().bit(config.format.into())); |
| 335 | c.channels | 406 | c.channels |
| 336 | .write(|w| unsafe { w.channels().bits(config.channels.into()) }); | 407 | .write(|w| unsafe { w.channels().bits(config.channels.into()) }); |
| 337 | } | 408 | } |
| 409 | |||
| 410 | fn select_pins( | ||
| 411 | psel: &PSEL, | ||
| 412 | mck: PeripheralRef<'d, AnyPin>, | ||
| 413 | sck: PeripheralRef<'d, AnyPin>, | ||
| 414 | lrck: PeripheralRef<'d, AnyPin>, | ||
| 415 | sdin: PeripheralRef<'d, AnyPin>, | ||
| 416 | sdout: PeripheralRef<'d, AnyPin>, | ||
| 417 | ) { | ||
| 418 | psel.mck.write(|w| { | ||
| 419 | unsafe { w.bits(mck.psel_bits()) }; | ||
| 420 | w.connect().connected() | ||
| 421 | }); | ||
| 422 | |||
| 423 | psel.sck.write(|w| { | ||
| 424 | unsafe { w.bits(sck.psel_bits()) }; | ||
| 425 | w.connect().connected() | ||
| 426 | }); | ||
| 427 | |||
| 428 | psel.lrck.write(|w| { | ||
| 429 | unsafe { w.bits(lrck.psel_bits()) }; | ||
| 430 | w.connect().connected() | ||
| 431 | }); | ||
| 432 | |||
| 433 | psel.sdin.write(|w| { | ||
| 434 | unsafe { w.bits(sdin.psel_bits()) }; | ||
| 435 | w.connect().connected() | ||
| 436 | }); | ||
| 437 | |||
| 438 | psel.sdout.write(|w| { | ||
| 439 | unsafe { w.bits(sdout.psel_bits()) }; | ||
| 440 | w.connect().connected() | ||
| 441 | }); | ||
| 442 | } | ||
| 443 | |||
| 444 | fn setup_interrupt(irq: PeripheralRef<'d, T::Interrupt>, r: &RegisterBlock) { | ||
| 445 | irq.set_handler(Self::on_interrupt); | ||
| 446 | irq.set_priority(Priority::P1); // TODO review priorities | ||
| 447 | irq.unpend(); | ||
| 448 | irq.enable(); | ||
| 449 | |||
| 450 | r.intenclr.write(|w| w.rxptrupd().clear()); | ||
| 451 | r.intenclr.write(|w| w.txptrupd().clear()); | ||
| 452 | r.events_rxptrupd.reset(); | ||
| 453 | r.events_txptrupd.reset(); | ||
| 454 | } | ||
| 338 | } | 455 | } |
| 339 | 456 | ||
| 340 | impl<'d, T: Instance> I2sOutput<'d, T> { | 457 | impl<'d, T: Instance> I2sOutput<'d, T> { |
| @@ -360,15 +477,40 @@ impl<'d, T: Instance> I2sOutput<'d, T> { | |||
| 360 | } | 477 | } |
| 361 | 478 | ||
| 362 | let r = T::regs(); | 479 | let r = T::regs(); |
| 363 | let _s = T::state(); | 480 | let s = T::state(); |
| 364 | 481 | ||
| 365 | // TODO we can not progress until the last buffer written in TXD.PTR | 482 | let drop = OnDrop::new(move || { |
| 366 | // has started the transmission. | 483 | trace!("write drop: stopping"); |
| 367 | // We can use some sync primitive from `embassy-sync`. | 484 | |
| 485 | r.intenclr.write(|w| w.txptrupd().clear()); | ||
| 486 | r.events_txptrupd.reset(); | ||
| 487 | r.config.txen.write(|w| w.txen().disabled()); | ||
| 488 | |||
| 489 | // TX is stopped almost instantly, spinning is fine. | ||
| 490 | while r.events_txptrupd.read().bits() == 0 {} | ||
| 491 | trace!("write drop: stopped"); | ||
| 492 | }); | ||
| 368 | 493 | ||
| 369 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 494 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); |
| 370 | r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) }); | 495 | r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) }); |
| 371 | 496 | ||
| 497 | r.intenset.write(|w| w.txptrupd().set()); | ||
| 498 | |||
| 499 | compiler_fence(Ordering::SeqCst); | ||
| 500 | |||
| 501 | poll_fn(|cx| { | ||
| 502 | s.tx_waker.register(cx.waker()); | ||
| 503 | if r.events_txptrupd.read().bits() != 0 { | ||
| 504 | Poll::Ready(()) | ||
| 505 | } else { | ||
| 506 | Poll::Pending | ||
| 507 | } | ||
| 508 | }) | ||
| 509 | .await; | ||
| 510 | |||
| 511 | compiler_fence(Ordering::SeqCst); | ||
| 512 | drop.defuse(); | ||
| 513 | |||
| 372 | Ok(()) | 514 | Ok(()) |
| 373 | } | 515 | } |
| 374 | } | 516 | } |
| @@ -451,23 +593,19 @@ impl Buffer for &[i32] { | |||
| 451 | } | 593 | } |
| 452 | 594 | ||
| 453 | pub(crate) mod sealed { | 595 | pub(crate) mod sealed { |
| 454 | use core::sync::atomic::AtomicU8; | ||
| 455 | |||
| 456 | use embassy_sync::waitqueue::AtomicWaker; | 596 | use embassy_sync::waitqueue::AtomicWaker; |
| 457 | 597 | ||
| 458 | //use super::*; | 598 | //use super::*; |
| 459 | 599 | ||
| 460 | pub struct State { | 600 | pub struct State { |
| 461 | pub input_waker: AtomicWaker, | 601 | pub rx_waker: AtomicWaker, |
| 462 | pub output_waker: AtomicWaker, | 602 | pub tx_waker: AtomicWaker, |
| 463 | pub buffers_refcount: AtomicU8, | ||
| 464 | } | 603 | } |
| 465 | impl State { | 604 | impl State { |
| 466 | pub const fn new() -> Self { | 605 | pub const fn new() -> Self { |
| 467 | Self { | 606 | Self { |
| 468 | input_waker: AtomicWaker::new(), | 607 | rx_waker: AtomicWaker::new(), |
| 469 | output_waker: AtomicWaker::new(), | 608 | tx_waker: AtomicWaker::new(), |
| 470 | buffers_refcount: AtomicU8::new(0), | ||
| 471 | } | 609 | } |
| 472 | } | 610 | } |
| 473 | } | 611 | } |
