1
#![cfg_attr(docsrs, procmacros::doc_replace)]
2
//! # Two-wire Automotive Interface (TWAI)
3
//!
4
//! ## Overview
5
//!
6
//! The TWAI is a multi-master, multi-cast communication protocol with error
7
//! detection and signaling and inbuilt message priorities and arbitration. The
8
//! TWAI protocol is suited for automotive and industrial applications.
9
//!
10
//! See ESP-IDF's
11
#![doc = concat!("[TWAI documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", chip!(), "/api-reference/peripherals/twai.html#twai-protocol-summary)")]
12
//! for a summary on the protocol.
13
//!
14
//! ## Configuration
15
//! The driver  offers functions for initializing the TWAI peripheral, setting
16
//! up the timing parameters, configuring acceptance filters, handling
17
//! interrupts, and transmitting/receiving messages on the TWAI bus.
18
//!
19
//! This driver manages the ISO 11898-1 compatible TWAI
20
//! controllers. It supports Standard Frame Format (11-bit) and Extended Frame
21
//! Format (29-bit) frame identifiers.
22
//!
23
//! ## Examples
24
//!
25
//! ### Transmitting and Receiving Messages
26
//!
27
//! ```rust, no_run
28
//! # {before_snippet}
29
//! # use esp_hal::twai;
30
//! # use esp_hal::twai::filter;
31
//! # use esp_hal::twai::filter::SingleStandardFilter;
32
//! # use esp_hal::twai::TwaiConfiguration;
33
//! # use esp_hal::twai::BaudRate;
34
//! # use esp_hal::twai::TwaiMode;
35
//! # use nb::block;
36
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI
37
//! // transceiver.
38
//! let twai_rx_pin = peripherals.GPIO3;
39
//! let twai_tx_pin = peripherals.GPIO2;
40
//!
41
//! // The speed of the TWAI bus.
42
//! const TWAI_BAUDRATE: twai::BaudRate = BaudRate::B1000K;
43
//!
44
//! // Begin configuring the TWAI peripheral. The peripheral is in a reset like
45
//! // state that prevents transmission but allows configuration.
46
//! let mut twai_config = twai::TwaiConfiguration::new(
47
//!     peripherals.TWAI0,
48
//!     twai_rx_pin,
49
//!     twai_tx_pin,
50
//!     TWAI_BAUDRATE,
51
//!     TwaiMode::Normal,
52
//! );
53
//!
54
//! // Partially filter the incoming messages to reduce overhead of receiving
55
//! // undesired messages
56
//! twai_config.set_filter(
57
//!     const { SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx", b"xxxxxxxx"]) },
58
//! );
59
//!
60
//! // Start the peripheral. This locks the configuration settings of the
61
//! // peripheral and puts it into operation mode, allowing packets to be sent
62
//! // and received.
63
//! let mut twai = twai_config.start();
64
//!
65
//! loop {
66
//!     // Wait for a frame to be received.
67
//!     let frame = block!(twai.receive())?;
68
//!
69
//!     // Transmit the frame back.
70
//!     let _result = block!(twai.transmit(&frame))?;
71
//! }
72
//! # }
73
//! ```
74
//!
75
//! ### Self-testing (self reception of transmitted messages)
76
//! ```rust, no_run
77
//! # {before_snippet}
78
//! # use esp_hal::twai;
79
//! # use esp_hal::twai::filter;
80
//! # use esp_hal::twai::filter::SingleStandardFilter;
81
//! # use esp_hal::twai::TwaiConfiguration;
82
//! # use esp_hal::twai::BaudRate;
83
//! # use esp_hal::twai::EspTwaiFrame;
84
//! # use esp_hal::twai::StandardId;
85
//! # use esp_hal::twai::TwaiMode;
86
//! # use nb::block;
87
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI
88
//! // transceiver.
89
//! let can_rx_pin = peripherals.GPIO3;
90
//! let can_tx_pin = peripherals.GPIO2;
91
//!
92
//! // The speed of the TWAI bus.
93
//! const TWAI_BAUDRATE: twai::BaudRate = BaudRate::B1000K;
94
//!
95
//! // Begin configuring the TWAI peripheral.
96
//! let mut can_config = twai::TwaiConfiguration::new(
97
//!     peripherals.TWAI0,
98
//!     can_rx_pin,
99
//!     can_tx_pin,
100
//!     TWAI_BAUDRATE,
101
//!     TwaiMode::SelfTest
102
//! );
103
//!
104
//! // Partially filter the incoming messages to reduce overhead of receiving
105
//! // undesired messages
106
//! can_config.set_filter(const { SingleStandardFilter::new(b"xxxxxxxxxx0",
107
//! b"x", [b"xxxxxxxx", b"xxxxxxxx"]) });
108
//!
109
//! // Start the peripheral. This locks the configuration settings of the
110
//! // peripheral and puts it into operation mode, allowing packets to be sent
111
//! // and received.
112
//! let mut can = can_config.start();
113
//!
114
//! # // TODO: `new_*` should return Result not Option
115
//! let frame = EspTwaiFrame::new_self_reception(StandardId::ZERO,
116
//!     &[1, 2, 3]).unwrap(); // Wait for a frame to be received.
117
//! let frame = block!(can.receive())?;
118
//!
119
//! # loop {}
120
//! # }
121
//! ```
122

            
123
use core::marker::PhantomData;
124

            
125
use enumset::{EnumSet, EnumSetType};
126
use procmacros::handler;
127

            
128
use self::filter::{Filter, FilterType};
129
use crate::{
130
    Async,
131
    Blocking,
132
    DriverMode,
133
    gpio::{
134
        DriveMode,
135
        InputConfig,
136
        InputSignal,
137
        OutputConfig,
138
        OutputSignal,
139
        Pull,
140
        interconnect::{PeripheralInput, PeripheralOutput},
141
    },
142
    interrupt::InterruptHandler,
143
    pac::twai0::RegisterBlock,
144
    system::{Cpu, PeripheralGuard},
145
    twai::filter::SingleStandardFilter,
146
};
147
pub mod filter;
148

            
149
/// TWAI error kind
150
///
151
/// This represents a common set of TWAI operation errors. HAL implementations
152
/// are free to define more specific or additional error types. However, by
153
/// providing a mapping to these common TWAI errors, generic code can still
154
/// react to them.
155
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
156
#[non_exhaustive]
157
pub enum ErrorKind {
158
    /// The peripheral receive buffer was overrun.
159
    Overrun,
160
    // MAC sublayer errors
161
    /// A bit error is detected at that bit time when the bit value that is
162
    /// monitored differs from the bit value sent.
163
    Bit,
164
    /// A stuff error is detected at the bit time of the sixth consecutive
165
    /// equal bit level in a frame field that shall be coded by the method
166
    /// of bit stuffing.
167
    Stuff,
168
    /// Calculated CRC sequence does not equal the received one.
169
    Crc,
170
    /// A form error shall be detected when a fixed-form bit field contains
171
    /// one or more illegal bits.
172
    Form,
173
    /// An ACK  error shall be detected by a transmitter whenever it does not
174
    /// monitor a dominant bit during the ACK slot.
175
    Acknowledge,
176
    /// A different error occurred. The original error may contain more
177
    /// information.
178
    Other,
179
}
180

            
181
macro_rules! impl_display {
182
    ($($kind:ident => $msg:expr),* $(,)?) => {
183
        impl core::fmt::Display for ErrorKind {
184
            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
185
                match self {
186
                    $(Self::$kind => write!(f, $msg)),*
187
                }
188
            }
189
        }
190

            
191
        #[cfg(feature = "defmt")]
192
        impl defmt::Format for ErrorKind {
193
            fn format(&self, f: defmt::Formatter<'_>) {
194
                match self {
195
                    $(Self::$kind => defmt::write!(f, $msg)),*
196
                }
197
            }
198
        }
199
    };
200
}
201

            
202
impl_display! {
203
    Overrun => "The peripheral receive buffer was overrun",
204
    Bit => "Bit value that is monitored differs from the bit value sent",
205
    Stuff => "Sixth consecutive equal bits detected",
206
    Crc => "Calculated CRC sequence does not equal the received one",
207
    Form => "A fixed-form bit field contains one or more illegal bits",
208
    Acknowledge => "Transmitted frame was not acknowledged",
209
    Other => "A different error occurred. The original error may contain more information",
210
}
211

            
212
#[instability::unstable]
213
impl From<ErrorKind> for embedded_can::ErrorKind {
214
    fn from(value: ErrorKind) -> Self {
215
        match value {
216
            ErrorKind::Overrun => embedded_can::ErrorKind::Overrun,
217
            ErrorKind::Bit => embedded_can::ErrorKind::Bit,
218
            ErrorKind::Stuff => embedded_can::ErrorKind::Stuff,
219
            ErrorKind::Crc => embedded_can::ErrorKind::Crc,
220
            ErrorKind::Form => embedded_can::ErrorKind::Form,
221
            ErrorKind::Acknowledge => embedded_can::ErrorKind::Acknowledge,
222
            ErrorKind::Other => embedded_can::ErrorKind::Other,
223
        }
224
    }
225
}
226

            
227
#[instability::unstable]
228
impl embedded_can::Error for ErrorKind {
229
    fn kind(&self) -> embedded_can::ErrorKind {
230
        (*self).into()
231
    }
232
}
233

            
234
/// Specifies in which mode the TWAI controller will operate.
235
9
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
236
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
237
pub enum TwaiMode {
238
    /// Normal operating mode.
239
    Normal,
240
    /// Self-test mode (no acknowledgement required for a successful message
241
    /// transmission).
242
    SelfTest,
243
    /// Listens only operating mode.
244
    ListenOnly,
245
}
246

            
247
/// Standard 11-bit TWAI Identifier (`0..=0x7FF`).
248
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
249
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
250
pub struct StandardId(u16);
251

            
252
impl StandardId {
253
    /// TWAI ID `0`, the highest priority.
254
    pub const ZERO: Self = StandardId(0);
255

            
256
    /// TWAI ID `0x7FF`, the lowest priority.
257
    pub const MAX: Self = StandardId(0x7FF);
258

            
259
    /// Tries to create a `StandardId` from a raw 16-bit integer.
260
    ///
261
    /// Returns `None` if `raw` is out of range of an 11-bit integer.
262
    /// (`> 0x7FF`).
263
    #[inline]
264
    pub fn new(raw: u16) -> Option<Self> {
265
        if raw <= 0x7FF {
266
            Some(StandardId(raw))
267
        } else {
268
            None
269
        }
270
    }
271

            
272
    /// Creates a new `StandardId` without checking if it is inside the valid
273
    /// range.
274
    ///
275
    /// # Safety
276
    /// Using this method can create an invalid ID and is thus marked as unsafe.
277
    #[inline]
278
    pub const unsafe fn new_unchecked(raw: u16) -> Self {
279
        StandardId(raw)
280
    }
281

            
282
    /// Returns TWAI Identifier as a raw 16-bit integer.
283
    #[inline]
284
    pub fn as_raw(&self) -> u16 {
285
        self.0
286
    }
287
}
288

            
289
#[instability::unstable]
290
impl From<StandardId> for embedded_can::StandardId {
291
    fn from(value: StandardId) -> Self {
292
        embedded_can::StandardId::new(value.as_raw()).unwrap()
293
    }
294
}
295

            
296
#[instability::unstable]
297
impl From<embedded_can::StandardId> for StandardId {
298
    fn from(value: embedded_can::StandardId) -> Self {
299
        StandardId::new(value.as_raw()).unwrap()
300
    }
301
}
302

            
303
/// Extended 29-bit TWAI Identifier (`0..=1FFF_FFFF`).
304
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
305
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
306
pub struct ExtendedId(u32);
307

            
308
impl ExtendedId {
309
    /// TWAI ID `0`, the highest priority.
310
    pub const ZERO: Self = ExtendedId(0);
311

            
312
    /// TWAI ID `0x1FFFFFFF`, the lowest priority.
313
    pub const MAX: Self = ExtendedId(0x1FFF_FFFF);
314

            
315
    /// Tries to create a `ExtendedId` from a raw 32-bit integer.
316
    ///
317
    /// Returns `None` if `raw` is out of range of an 29-bit integer.
318
    /// (`> 0x1FFF_FFFF`).
319
    #[inline]
320
    pub fn new(raw: u32) -> Option<Self> {
321
        if raw <= 0x1FFF_FFFF {
322
            Some(ExtendedId(raw))
323
        } else {
324
            None
325
        }
326
    }
327

            
328
    /// Creates a new `ExtendedId` without checking if it is inside the valid
329
    /// range.
330
    ///
331
    /// # Safety
332
    /// Using this method can create an invalid ID and is thus marked as unsafe.
333
    #[inline]
334
    pub const unsafe fn new_unchecked(raw: u32) -> Self {
335
        ExtendedId(raw)
336
    }
337

            
338
    /// Returns TWAI Identifier as a raw 32-bit integer.
339
    #[inline]
340
    pub fn as_raw(&self) -> u32 {
341
        self.0
342
    }
343

            
344
    /// Returns the Base ID part of this extended identifier.
345
    pub fn standard_id(&self) -> StandardId {
346
        // ID-28 to ID-18
347
        StandardId((self.0 >> 18) as u16)
348
    }
349
}
350

            
351
#[instability::unstable]
352
impl From<ExtendedId> for embedded_can::ExtendedId {
353
    fn from(value: ExtendedId) -> Self {
354
        embedded_can::ExtendedId::new(value.0).unwrap()
355
    }
356
}
357

            
358
#[instability::unstable]
359
impl From<embedded_can::ExtendedId> for ExtendedId {
360
    fn from(value: embedded_can::ExtendedId) -> Self {
361
        ExtendedId::new(value.as_raw()).unwrap()
362
    }
363
}
364

            
365
/// A TWAI Identifier (standard or extended).
366
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
367
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
368
pub enum Id {
369
    /// Standard 11-bit Identifier (`0..=0x7FF`).
370
    Standard(StandardId),
371
    /// Extended 29-bit Identifier (`0..=0x1FFF_FFFF`).
372
    Extended(ExtendedId),
373
}
374

            
375
impl From<StandardId> for Id {
376
    #[inline]
377
    fn from(id: StandardId) -> Self {
378
        Id::Standard(id)
379
    }
380
}
381

            
382
impl From<ExtendedId> for Id {
383
    #[inline]
384
    fn from(id: ExtendedId) -> Self {
385
        Id::Extended(id)
386
    }
387
}
388

            
389
#[instability::unstable]
390
impl From<Id> for embedded_can::Id {
391
    fn from(value: Id) -> Self {
392
        match value {
393
            Id::Standard(id) => embedded_can::Id::Standard(id.into()),
394
            Id::Extended(id) => embedded_can::Id::Extended(id.into()),
395
        }
396
    }
397
}
398

            
399
#[instability::unstable]
400
impl From<embedded_can::Id> for Id {
401
    fn from(value: embedded_can::Id) -> Self {
402
        match value {
403
            embedded_can::Id::Standard(id) => Id::Standard(id.into()),
404
            embedded_can::Id::Extended(id) => Id::Extended(id.into()),
405
        }
406
    }
407
}
408

            
409
#[instability::unstable]
410
impl embedded_can::Frame for EspTwaiFrame {
411
    fn new(id: impl Into<embedded_can::Id>, data: &[u8]) -> Option<Self> {
412
        Self::new(id.into(), data)
413
    }
414

            
415
    fn new_remote(id: impl Into<embedded_can::Id>, dlc: usize) -> Option<Self> {
416
        Self::new_remote(id.into(), dlc)
417
    }
418

            
419
    fn is_extended(&self) -> bool {
420
        self.is_extended_format()
421
    }
422

            
423
    fn is_remote_frame(&self) -> bool {
424
        self.is_remote_request()
425
    }
426

            
427
    fn id(&self) -> embedded_can::Id {
428
        self.identifier().into()
429
    }
430

            
431
    fn dlc(&self) -> usize {
432
        self.data_length_code()
433
    }
434

            
435
    fn data(&self) -> &[u8] {
436
        self.data()
437
    }
438
}
439

            
440
/// A RAM buffer for a TWAI frame.
441
///
442
/// Mirror image of the 13 TWAI_DATA_x_REG registers.
443
#[derive(Clone, Copy)]
444
pub struct EspTwaiFrame {
445
    bytes: [u8; 13],
446
}
447

            
448
impl EspTwaiFrame {
449
    /// Frame Information: specifies a frame's type, format, data length, etc.
450
    ///
451
    /// | Offset | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
452
    /// |--------|-------|-------|-------|-------|-------|-------|-------|-------|
453
    /// |  0x0   |  FF   |  RTR  |  ---  |  SR   | DLC.3 | DLC.2 | DLC.1 | DLC.0 |
454
    #[inline(always)]
455
    fn info(&self) -> u8 {
456
        self.bytes[0]
457
    }
458

            
459
    /// Frame Format (FF): specifies whether content is Extended Frame Format (EFF) or Standard
460
    /// Frame Format (SFF).
461
    ///
462
    /// Private: interested clients should deduce the frame format from
463
    /// [`Self::id()`].
464
    #[inline(always)]
465
    fn is_extended_format(&self) -> bool {
466
        self.info() & (0b1 << 7) != 0
467
    }
468

            
469
    /// Remote Transmission Request (RTR): specifies whether content is a data frame or a remote
470
    /// request frame (on-demand polling).
471
    ///
472
    /// Remote request frames do not have a data payload, no matter their DLC.
473
    pub fn is_remote_request(&self) -> bool {
474
        self.info() & (0b1 << 6) != 0
475
    }
476

            
477
    /// Self Reception (SR): indicates whether content was sent by us (using the TWAI_SELF_RX_SEQ
478
    /// command) or received from the bus.
479
    pub fn is_self_reception(&self) -> bool {
480
        self.info() & (0b1 << 4) != 0
481
    }
482

            
483
    /// Data Length Code (DLC): specifies the number of data bytes for a data frame, or the number
484
    /// of data bytes requested by a remote frame.
485
    ///
486
    /// Although no frame can have a payload longer than 8, the DLC can be greater than 8 in
487
    /// rare cases (payload length then is still 8).
488
    pub fn data_length_code(&self) -> usize {
489
        (self.info() & 0b1111) as usize
490
    }
491

            
492
    /// Length of the data payload: 0 for a RTR frame, 8 if DLC > 8.
493
    pub fn data_length(&self) -> usize {
494
        match self.is_remote_request() {
495
            true => 0,
496
            false => core::cmp::min(self.data_length_code(), 8),
497
        }
498
    }
499

            
500
    /// Frame Identifier: 11-bit long for a SFF frame, 29-bit long for an EFF frame.
501
    #[inline]
502
    pub fn identifier(&self) -> Id {
503
        let bytes = self.bytes;
504
        match self.is_extended_format() {
505
            false => {
506
                // Standard Format: 11-bit Identifier, 2 bytes long
507
                //
508
                // | Offset | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
509
                // |--------|-------|-------|-------|-------|-------|-------|-------|-------|
510
                // |  0x1   | ID.10 | ID.9  | ID.8  | ID.7  | ID.6  | ID.5  | ID.4  | ID.3  |
511
                // |  0x2   | ID.2  | ID.1  | ID.0  |  ---  |  ---  |  ---  |  ---  |  ---  |
512
                let raw_id: u16 = ((bytes[1] as u16) << 3) | ((bytes[2] as u16) >> 5);
513
                // SAFETY: safe because raw_id is 11 bits long (it cannot exceed StandardId::MAX).
514
                unsafe { StandardId::new_unchecked(raw_id).into() }
515
            }
516
            true => {
517
                // Extended Format: 29-bit Identifier, 4 bytes long
518
                //
519
                // | Offset | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
520
                // |--------|-------|-------|-------|-------|-------|-------|-------|-------|
521
                // |  0x1   | ID.28 | ID.27 | ID.26 | ID.25 | ID.24 | ID.23 | ID.22 | ID.21 |
522
                // |  0x2   | ID.20 | ID.19 | ID.18 | ID.17 | ID.16 | ID.15 | ID.14 | ID.13 |
523
                // |  0x3   | ID.12 | ID.11 | ID.10 | ID.9  | ID.8  | ID.7  | ID.6  | ID.5  |
524
                // |  0x4   | ID.4  | ID.3  | ID.2  | ID.1  | ID.0  |  ---  |  ---  |  ---  |
525
                let raw_id: u32 = ((bytes[1] as u32) << 21)
526
                    | ((bytes[2] as u32) << 13)
527
                    | ((bytes[3] as u32) << 5)
528
                    | ((bytes[4] as u32) >> 3);
529
                // SAFETY: safe because raw_id is 29 bits long (it cannot exceed ExtendedId::MAX)
530
                unsafe { ExtendedId::new_unchecked(raw_id).into() }
531
            }
532
        }
533
    }
534

            
535
    /// Offset at which frame data starts: 0x3 for a SFF, 0x5 for an EFF.
536
    #[inline(always)]
537
    fn data_offset(&self) -> usize {
538
        match self.is_extended_format() {
539
            false => 0x3,
540
            true => 0x5,
541
        }
542
    }
543

            
544
    /// Frame Data: data payload, 0 to 8 bytes long.
545
    ///
546
    /// Returns a reference to a slice:
547
    /// * empty in case of a Remote Transmission Request
548
    /// * 8 bytes long in case DLC > 8
549
    #[inline]
550
    pub fn data(&self) -> &[u8] {
551
        let data_start = self.data_offset();
552
        let data_end = data_start + self.data_length();
553
        &self.bytes[data_start..data_end]
554
    }
555

            
556
    /// Returns a slice reference to the relevant frame bytes.
557
    fn as_slice(&self) -> &[u8] {
558
        let len = self.data_offset() + self.data_length();
559
        &self.bytes[0..len]
560
    }
561

            
562
    /// Creates a new [`EspTwaiFrame`] from TWAI_DATA_x_REG registers.
563
    pub(super) fn new_from_registers(register_block: &RegisterBlock) -> Self {
564
        let mut bytes: [u8; 13] = [0; 13];
565
        // SAFETY: Safe because it is a constant-size, read-only access to the 13 data registers
566
        unsafe {
567
            copy_from_data_register(&mut bytes, register_block.data(0).as_ptr());
568
        }
569
        Self { bytes }
570
    }
571

            
572
    /// Creates a new [`EspTwaiFrame`] from parameters.
573
    fn new_from_parameters(
574
        id: impl Into<Id>,
575
        remote_request: bool,
576
        self_reception: bool,
577
        dlc: usize,
578
        data: &[u8],
579
    ) -> Result<Self, EspTwaiError> {
580
        let data_len = data.len();
581

            
582
        // Assert that:
583
        // - Max data length is 8
584
        // - remote request frames have no data payload
585
1
        if data_len > 8 || (remote_request & (data_len > 0)) {
586
            return Err(EspTwaiError::InvalidDataLength(data_len as u8));
587
        }
588
        // Assert that:
589
        // - Max DLC is 15
590
        // - Data length smaller than 8 must have equal DLC
591
        // - Data length equal to 8 hmust ave DLC >= 8
592
        if dlc > 15 || ((data_len < 8) & (dlc != data_len)) || ((data_len == 8) & (dlc < 8)) {
593
            return Err(EspTwaiError::NonCompliantDlc(dlc as u8));
594
        }
595

            
596
1
        let mut bytes = [0u8; 13];
597

            
598
        // Id
599
        let (extended_format, data_start): (u8, usize) = match id.into() {
600
            Id::Standard(id) => {
601
                let raw = id.as_raw();
602
                bytes[1] = (raw >> 3) as u8;
603
                bytes[2] = (raw << 5) as u8;
604
                (0, 3)
605
            }
606
            Id::Extended(id) => {
607
                let raw = id.as_raw();
608
                bytes[1] = (raw >> 21) as u8;
609
                bytes[2] = (raw >> 13) as u8;
610
                bytes[3] = (raw >> 5) as u8;
611
                bytes[4] = (raw << 3) as u8;
612
                (1, 5)
613
            }
614
        };
615
        // Frame Info
616
        let ff = extended_format << 7;
617
        let rtr = (remote_request as u8) << 6;
618
        let sr = (self_reception as u8) << 4;
619
        let dlc = (dlc as u8) & 0b1111;
620
1
        bytes[0] = ff | rtr | sr | dlc;
621
        // Data
622
        let data_end = data_start + data_len;
623
        bytes[data_start..data_end].copy_from_slice(data);
624

            
625
1
        Ok(Self { bytes })
626
    }
627

            
628
    /// Creates a new `EspTwaiFrame` with the specified ID and data payload.
629
    pub fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
630
        Self::new_from_parameters(id.into(), false, false, data.len(), data).ok()
631
    }
632

            
633
    /// Creates a new `EspTwaiFrame` for a transmission request with the
634
    /// specified ID and data length (DLC).
635
    pub fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
636
        Self::new_from_parameters(id.into(), true, false, dlc, &[]).ok()
637
    }
638

            
639
    /// Creates a new `EspTwaiFrame` ready for self-reception with the specified
640
    /// ID and data payload.
641
    pub fn new_self_reception(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
642
        Self::new_from_parameters(id.into(), false, true, data.len(), data).ok()
643
    }
644
}
645

            
646
#[cfg(feature = "defmt")]
647
impl defmt::Format for EspTwaiFrame {
648
    fn format(&self, f: defmt::Formatter<'_>) {
649
        defmt::write!(
650
            f,
651
            "EspTwaiFrame {{ id: {1=u32}, EFF: {0=7..8}, RTR: {0=6..7}, SR: {0=4..5}, DLC: {0=0..4}, data: {2=[u8]:#x}, raw: {3=[u8]:#x} }}",
652
            self.info(),
653
            match self.identifier() {
654
                Id::Standard(id) => id.as_raw() as u32,
655
                Id::Extended(id) => id.as_raw(),
656
            },
657
            self.data(),
658
            self.as_slice(),
659
        );
660
    }
661
}
662

            
663
impl core::fmt::Debug for EspTwaiFrame {
664
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
665
        f.debug_struct("EspTwaiFrame")
666
            .field(
667
                "id",
668
                &match self.identifier() {
669
                    Id::Standard(id) => id.as_raw() as u32,
670
                    Id::Extended(id) => id.as_raw(),
671
                },
672
            )
673
            .field("EFF", &(self.is_extended_format() as u8))
674
            .field("RTR", &(self.is_remote_request() as u8))
675
            .field("SR", &(self.is_self_reception() as u8))
676
            .field("DLC", &self.data_length_code())
677
            .field("data", &format_args!("{:02x?}", self.data()))
678
            .field("raw", &format_args!("{:02x?}", self.as_slice()))
679
            .finish()
680
    }
681
}
682

            
683
/// The underlying timings for the TWAI peripheral.
684
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
685
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
686
pub struct TimingConfig {
687
    /// The baudrate prescaler is used to determine the period of each time
688
    /// quantum by dividing the TWAI controller's source clock.
689
    pub baud_rate_prescaler: u16,
690

            
691
    /// The synchronization jump width is used to determine the maximum number
692
    /// of time quanta a single bit time can be lengthened/shortened for
693
    /// synchronization purposes.
694
    pub sync_jump_width: u8,
695

            
696
    /// Timing segment 1 consists of 1 to 16 time quanta before sample point.
697
    pub tseg_1: u8,
698

            
699
    /// Timing Segment 2 consists of 1 to 8 time quanta after sample point.
700
    pub tseg_2: u8,
701

            
702
    /// Enabling triple sampling causes 3 time quanta to be sampled per bit
703
    /// instead of 1.
704
    pub triple_sample: bool,
705
}
706

            
707
/// A selection of pre-determined baudrates for the TWAI driver.
708
/// Currently these timings are sourced from the ESP IDF C driver which assumes
709
/// an APB clock of 80 MHz.
710
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
711
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
712
pub enum BaudRate {
713
    /// A baud rate of 125 Kbps.
714
    B125K,
715
    /// A baud rate of 250 Kbps.
716
    B250K,
717
    /// A baud rate of 500 Kbps.
718
    B500K,
719
    /// A baud rate of 1 Mbps.
720
    B1000K,
721
    /// A custom baud rate.
722
    ///
723
    /// Specifies a custom timing configuration using a `TimingConfig` struct.
724
    Custom(TimingConfig),
725
}
726

            
727
impl BaudRate {
728
    /// Converts the BaudRate into the timings that the peripheral needs.
729
    // See: https://github.com/espressif/esp-idf/tree/ab4200e/components/esp_hal_twai/include/hal/twai_types.h
730
    const fn timing(self) -> TimingConfig {
731
        #[cfg(not(esp32h2))]
732
9
        let timing = match self {
733
            Self::B125K => TimingConfig {
734
                baud_rate_prescaler: 32,
735
                sync_jump_width: 3,
736
                tseg_1: 15,
737
                tseg_2: 4,
738
                triple_sample: false,
739
            },
740
            Self::B250K => TimingConfig {
741
                baud_rate_prescaler: 16,
742
                sync_jump_width: 3,
743
                tseg_1: 15,
744
                tseg_2: 4,
745
                triple_sample: false,
746
            },
747
1
            Self::B500K => TimingConfig {
748
                baud_rate_prescaler: 8,
749
                sync_jump_width: 3,
750
                tseg_1: 15,
751
                tseg_2: 4,
752
                triple_sample: false,
753
            },
754
            Self::B1000K => TimingConfig {
755
                baud_rate_prescaler: 4,
756
                sync_jump_width: 3,
757
                tseg_1: 15,
758
                tseg_2: 4,
759
                triple_sample: false,
760
            },
761
            Self::Custom(timing_config) => timing_config,
762
        };
763

            
764
        #[cfg(esp32h2)]
765
        let timing = match self {
766
            Self::B125K => TimingConfig {
767
                baud_rate_prescaler: 16,
768
                sync_jump_width: 3,
769
                tseg_1: 11,
770
                tseg_2: 4,
771
                triple_sample: false,
772
            },
773
            Self::B250K => TimingConfig {
774
                baud_rate_prescaler: 8,
775
                sync_jump_width: 3,
776
                tseg_1: 11,
777
                tseg_2: 4,
778
                triple_sample: false,
779
            },
780
            Self::B500K => TimingConfig {
781
                baud_rate_prescaler: 4,
782
                sync_jump_width: 3,
783
                tseg_1: 11,
784
                tseg_2: 4,
785
                triple_sample: false,
786
            },
787
            Self::B1000K => TimingConfig {
788
                baud_rate_prescaler: 2,
789
                sync_jump_width: 3,
790
                tseg_1: 11,
791
                tseg_2: 4,
792
                triple_sample: false,
793
            },
794
            Self::Custom(timing_config) => timing_config,
795
        };
796

            
797
        // clock source on ESP32-C6 is xtal (40MHz)
798
        #[cfg(esp32c6)]
799
        let timing = TimingConfig {
800
            baud_rate_prescaler: timing.baud_rate_prescaler / 2,
801
            ..timing
802
        };
803

            
804
        timing
805
    }
806
}
807

            
808
/// An inactive TWAI peripheral in the "Reset"/configuration state.
809
pub struct TwaiConfiguration<'d, Dm: DriverMode> {
810
    twai: AnyTwai<'d>,
811
    filter: Option<(FilterType, [u8; 8])>,
812
    phantom: PhantomData<Dm>,
813
    mode: TwaiMode,
814
    _guard: PeripheralGuard,
815
}
816

            
817
impl<'d, Dm> TwaiConfiguration<'d, Dm>
818
where
819
    Dm: DriverMode,
820
{
821
6
    fn new_internal(
822
        twai: AnyTwai<'d>,
823
        rx_pin: impl PeripheralInput<'d>,
824
        tx_pin: impl PeripheralOutput<'d>,
825
        baud_rate: BaudRate,
826
        no_transceiver: bool,
827
        mode: TwaiMode,
828
    ) -> Self {
829
6
        let rx_pin = rx_pin.into();
830
6
        let tx_pin = tx_pin.into();
831

            
832
6
        let guard = PeripheralGuard::new(twai.peripheral());
833

            
834
        let mut this = TwaiConfiguration {
835
            twai,
836
            filter: None, // We'll immediately call `set_filter`
837
            phantom: PhantomData,
838
            mode,
839
            _guard: guard,
840
        };
841

            
842
        // Accept all messages by default.
843
        this.set_filter(
844
            const { SingleStandardFilter::new(b"xxxxxxxxxxx", b"x", [b"xxxxxxxx", b"xxxxxxxx"]) },
845
        );
846

            
847
        // Set RESET bit to 1
848
        this.regs().mode().write(|w| w.reset_mode().set_bit());
849

            
850
        // Enable extended register layout
851
        #[cfg(esp32)]
852
        this.regs()
853
            .clock_divider()
854
            .modify(|_, w| w.ext_mode().set_bit());
855

            
856
        // Set up the GPIO pins.
857
        let tx_config = if no_transceiver {
858
            OutputConfig::default()
859
                .with_drive_mode(DriveMode::OpenDrain)
860
                .with_pull(Pull::Up)
861
        } else {
862
            OutputConfig::default()
863
        };
864

            
865
        tx_pin.apply_output_config(&tx_config);
866
        rx_pin.apply_input_config(&InputConfig::default().with_pull(if no_transceiver {
867
            Pull::Up
868
        } else {
869
            Pull::None
870
        }));
871

            
872
        tx_pin.set_output_enable(true);
873
        rx_pin.set_input_enable(true);
874

            
875
        this.twai.output_signal().connect_to(&tx_pin);
876
        this.twai.input_signal().connect_to(&rx_pin);
877

            
878
        // Freeze REC by changing to LOM mode
879
        this.set_mode(TwaiMode::ListenOnly);
880

            
881
        // Set TEC to 0
882
        this.regs()
883
            .tx_err_cnt()
884
            .write(|w| unsafe { w.tx_err_cnt().bits(0) });
885

            
886
        // Set REC to 0
887
        this.regs()
888
            .rx_err_cnt()
889
            .write(|w| unsafe { w.rx_err_cnt().bits(0) });
890

            
891
        // Set EWL to 96
892
        this.regs()
893
            .err_warning_limit()
894
            .write(|w| unsafe { w.err_warning_limit().bits(96) });
895

            
896
6
        this.set_baud_rate(baud_rate);
897
6
        this
898
6
    }
899

            
900
    fn regs(&self) -> &RegisterBlock {
901
        self.twai.register_block()
902
    }
903

            
904
    fn internal_set_interrupt_handler(&mut self, handler: InterruptHandler) {
905
        for core in Cpu::other() {
906
            crate::interrupt::disable(core, self.twai.interrupt());
907
        }
908
        crate::interrupt::bind_handler(self.twai.interrupt(), handler);
909
    }
910

            
911
    /// Sets the bitrate of the bus. Also usable on the configuration
912
    /// [`Twai::stop`] returns, to change the bitrate of a driver that has
913
    /// been running.
914
    ///
915
    /// The timings currently assume an APB_CLK of 80 MHz.
916
    #[instability::unstable]
917
9
    pub fn set_baud_rate(&mut self, baud_rate: BaudRate) {
918
        // TWAI is clocked from the APB_CLK according to Table 6-4 [ESP32C3 Reference Manual](https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf)
919
        // Included timings are all for 80MHz so assert that we are running at 80MHz.
920
        #[cfg(not(any(esp32h2, esp32c6)))]
921
        {
922
9
            assert!(crate::soc::clocks::apb_clk_frequency() == 80_000_000);
923
        }
924

            
925
        // Unpack the baud rate timings and convert them to the values needed for the
926
        // register. Many of the registers have a minimum value of 1 which is
927
        // represented by having zero bits set, therefore many values need to
928
        // have 1 subtracted from them before being stored into the register.
929
        let timing = baud_rate.timing();
930

            
931
        #[cfg_attr(not(esp32), allow(unused_mut))]
932
        let mut prescaler = timing.baud_rate_prescaler;
933

            
934
        #[cfg(esp32)]
935
        {
936
            // From <https://github.com/espressif/esp-idf/blob/6e5a178b3120dced7fa5c29c655cc22ea182df3d/components/soc/esp32/register/soc/twai_struct.h#L79>
937
            // and <https://github.com/espressif/esp-idf/blob/6e5a178b3120dced7fa5c29c655cc22ea182df3d/components/hal/esp32/include/hal/twai_ll.h#L528-L534>:
938
            if timing.baud_rate_prescaler > 128 {
939
                // Enable /2 baudrate divider by setting `brp_div`.
940
                // `brp_div` is not an interrupt, it will prescale BRP by 2. Only available on
941
                // ESP32 Revision 2 or later. Reserved otherwise.
942
                self.regs().int_ena().modify(|_, w| w.brp_div().set_bit());
943
                prescaler = timing.baud_rate_prescaler / 2;
944
            } else {
945
                // Disable /2 baudrate divider by clearing brp_div.
946
                self.regs().int_ena().modify(|_, w| w.brp_div().clear_bit());
947
            }
948
        }
949

            
950
        let prescale = (prescaler / 2) - 1;
951
        let sjw = timing.sync_jump_width - 1;
952
        let tseg_1 = timing.tseg_1 - 1;
953
        let tseg_2 = timing.tseg_2 - 1;
954
        let triple_sample = timing.triple_sample;
955

            
956
        // Set up the prescaler and sync jump width.
957
        self.regs().bus_timing_0().modify(|_, w| unsafe {
958
            w.baud_presc().bits(prescale as _);
959
            w.sync_jump_width().bits(sjw)
960
        });
961

            
962
        // Set up the time segment 1, time segment 2, and triple sample.
963
        self.regs().bus_timing_1().modify(|_, w| unsafe {
964
            w.time_seg1().bits(tseg_1);
965
            w.time_seg2().bits(tseg_2);
966
            w.time_samp().bit(triple_sample)
967
        });
968

            
969
        // disable CLKOUT
970
        self.regs()
971
            .clock_divider()
972
            .modify(|_, w| w.clock_off().set_bit());
973
9
    }
974

            
975
    /// Sets up the acceptance filter on the device.
976
    ///
977
    /// NOTE: On a bus with mixed 11-bit and 29-bit packet id's, an 11-bit filter
978
    /// match against a 29-bit frame and vice versa may occur. Applications should
979
    /// verify the id again once a frame has been received to make sure it is the
980
    /// expected value.
981
    ///
982
    /// A `const {}` block can ensure that the filter is parsed during program
983
    /// compilation.
984
    ///
985
    /// The filter is not applied to the peripheral until [`Self::start`] is
986
    /// called.
987
    ///
988
    /// [ESP32C3 Reference Manual](https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#subsubsection.29.4.6)
989
    pub fn set_filter(&mut self, filter: impl Filter) {
990
        // Convert the filter into values for the registers and store them for later
991
        // use.
992
3
        self.filter = Some((filter.filter_type(), filter.to_registers()));
993
    }
994

            
995
    fn apply_filter(&self) {
996
        let Some((filter_type, registers)) = self.filter.as_ref() else {
997
            return;
998
        };
999

            
        // Set or clear the rx filter mode bit depending on the filter type.
        self.regs()
            .mode()
            .modify(|_, w| w.rx_filter_mode().bit(*filter_type == FilterType::Single));
        // Copy the filter to the peripheral.
        unsafe {
            copy_to_data_register(self.regs().data(0).as_ptr(), registers);
        }
    }
    /// Sets the error warning threshold.
    ///
    /// In the case when any of an error counter value exceeds the threshold, or
    /// all the error counter values are below the threshold, an error
    /// warning interrupt will be triggered (given the enable signal is
    /// valid).
    pub fn set_error_warning_limit(&mut self, limit: u8) {
        self.regs()
            .err_warning_limit()
            .write(|w| unsafe { w.err_warning_limit().bits(limit) });
    }
    /// Sets the operating mode the driver starts in ([`Self::start`]). Also
    /// usable on the configuration [`Twai::stop`] returns.
    #[instability::unstable]
    pub fn set_operating_mode(&mut self, mode: TwaiMode) {
        self.mode = mode;
    }
    /// Sets the operating mode based on provided option.
    fn set_mode(&self, mode: TwaiMode) {
        self.regs().mode().modify(|_, w| {
            // self-test mode turns off acknowledgement requirement
            w.self_test_mode().bit(mode == TwaiMode::SelfTest);
            w.listen_only_mode().bit(mode == TwaiMode::ListenOnly)
        });
    }
    /// Puts the peripheral into Operation Mode, allowing the transmission and
    /// reception of packets using the new object.
9
    pub fn start(self) -> Twai<'d, Dm> {
        self.apply_filter();
9
        self.set_mode(self.mode);
        // Clear the TEC and REC
        self.regs()
            .tx_err_cnt()
            .write(|w| unsafe { w.tx_err_cnt().bits(0) });
        let rec =
9
            if cfg!(any(esp32, esp32s2, esp32s3, esp32c3)) && self.mode == TwaiMode::ListenOnly {
                // Errata workaround: Prevent transmission of dominant error frame while in
                // listen only mode by setting REC to 128 before exiting reset mode.
                // This forces the controller to be error passive (thus only transmits recessive
                // bits). The TEC/REC remain frozen in listen only mode thus
                // ensuring we remain error passive.
                128
            } else {
                0
            };
        self.regs()
            .rx_err_cnt()
            .write(|w| unsafe { w.rx_err_cnt().bits(rec) });
        // Clear any interrupts by reading the status register
        let _ = self.regs().int_raw().read();
9
        self.twai.async_state().counts.reset();
        // Put the peripheral into operation mode by clearing the reset mode bit.
        self.regs().mode().modify(|_, w| w.reset_mode().clear_bit());
        Twai {
            rx: TwaiRx {
                twai: unsafe { self.twai.clone_unchecked() },
                phantom: PhantomData,
9
                _guard: PeripheralGuard::new(self.twai.peripheral()),
            },
            tx: TwaiTx {
                twai: unsafe { self.twai.clone_unchecked() },
                phantom: PhantomData,
9
                _guard: PeripheralGuard::new(self.twai.peripheral()),
            },
            twai: unsafe { self.twai.clone_unchecked() },
            phantom: PhantomData,
        }
9
    }
}
impl<'d> TwaiConfiguration<'d, Blocking> {
    /// Creates a new instance of [TwaiConfiguration].
    ///
    /// A transceiver is required to connect to the TWAI bus.
    pub fn new(
        peripheral: impl Instance + 'd,
        rx_pin: impl PeripheralInput<'d>,
        tx_pin: impl PeripheralOutput<'d>,
        baud_rate: BaudRate,
        mode: TwaiMode,
    ) -> Self {
3
        Self::new_internal(peripheral.degrade(), rx_pin, tx_pin, baud_rate, false, mode)
    }
    /// Creates a new instance of [`TwaiConfiguration`] meant to connect two ESP32s
    /// directly.
    ///
    /// A transceiver is not required when following the description in the
    /// `twai.rs` example.
    pub fn new_no_transceiver(
        peripheral: impl Instance + 'd,
        rx_pin: impl PeripheralInput<'d>,
        tx_pin: impl PeripheralOutput<'d>,
        baud_rate: BaudRate,
        mode: TwaiMode,
    ) -> Self {
        Self::new_internal(peripheral.degrade(), rx_pin, tx_pin, baud_rate, true, mode)
    }
    /// Converts the configuration into an async configuration.
4
    pub fn into_async(mut self) -> TwaiConfiguration<'d, Async> {
        self.set_interrupt_handler(self.twai.async_handler());
4
        TwaiConfiguration {
            twai: self.twai,
            filter: self.filter,
            phantom: PhantomData,
4
            mode: self.mode,
4
            _guard: self._guard,
        }
4
    }
    /// Registers an interrupt handler for the TWAI peripheral.
    ///
    /// Replaces any previously registered interrupt handlers.
    #[instability::unstable]
    pub fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
        self.internal_set_interrupt_handler(handler);
    }
}
impl<'d> TwaiConfiguration<'d, Async> {
    /// Converts the configuration into a blocking configuration.
    pub fn into_blocking(self) -> TwaiConfiguration<'d, Blocking> {
        use crate::{interrupt, system::Cpu};
        interrupt::disable(Cpu::current(), self.twai.interrupt());
        // Re-create in  blocking mode
        TwaiConfiguration {
            twai: self.twai,
            filter: self.filter,
            phantom: PhantomData,
            mode: self.mode,
            _guard: self._guard,
        }
    }
}
impl crate::private::Sealed for TwaiConfiguration<'_, Blocking> {}
#[instability::unstable]
impl crate::interrupt::InterruptConfigurable for TwaiConfiguration<'_, Blocking> {
    fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
        self.internal_set_interrupt_handler(handler);
    }
}
/// An active TWAI peripheral in Normal Mode.
///
/// In this mode, the TWAI controller can transmit and receive messages
/// including error signals (such as error and overload frames).
pub struct Twai<'d, Dm: DriverMode> {
    twai: AnyTwai<'d>,
    tx: TwaiTx<'d, Dm>,
    rx: TwaiRx<'d, Dm>,
    phantom: PhantomData<Dm>,
}
impl<'d, Dm> Twai<'d, Dm>
where
    Dm: DriverMode,
{
    fn regs(&self) -> &RegisterBlock {
        self.twai.register_block()
    }
    fn mode(&self) -> TwaiMode {
        let mode = self.regs().mode().read();
        if mode.self_test_mode().bit_is_set() {
            TwaiMode::SelfTest
        } else if mode.listen_only_mode().bit_is_set() {
            TwaiMode::ListenOnly
        } else {
            TwaiMode::Normal
        }
    }
    /// Stops the peripheral, putting it into reset mode and enabling
    /// reconfiguration.
    pub fn stop(self) -> TwaiConfiguration<'d, Dm> {
        // Put the peripheral into reset/configuration mode by setting the reset mode
        // bit.
        self.regs().mode().modify(|_, w| w.reset_mode().set_bit());
        let mode = self.mode();
1
        let guard = PeripheralGuard::new(self.twai.peripheral());
        TwaiConfiguration {
            twai: self.twai,
            filter: None, // filter already applied, no need to restore it
            phantom: PhantomData,
            mode,
            _guard: guard,
        }
    }
    /// Returns the value of the receive error counter.
    pub fn receive_error_count(&self) -> u8 {
        self.regs().rx_err_cnt().read().rx_err_cnt().bits()
    }
    /// Returns the value of the transmit error counter.
    pub fn transmit_error_count(&self) -> u8 {
        self.regs().tx_err_cnt().read().tx_err_cnt().bits()
    }
    /// What the controller has reported since the driver was started (see
    /// [`ErrorCounts`])
    #[instability::unstable]
    pub fn error_counts(&self) -> ErrorCounts {
        self.twai.async_state().counts.snapshot()
    }
    /// Returns whether the controller is in a bus off state.
    pub fn is_bus_off(&self) -> bool {
        self.regs().status().read().bus_off_st().bit_is_set()
    }
    /// Initiates recovery from the bus-off state.
    ///
    /// The peripheral recovers once it has observed 128 occurrences of 11
    /// consecutive recessive (idle) bits on the bus. Use [`Self::is_bus_off`]
    /// to poll whether recovery has completed.
    ///
    /// Does nothing if the peripheral is not in the bus-off state.
    #[instability::unstable]
    pub fn initiate_recovery(&mut self) {
        if self.is_bus_off() {
            // Entering the bus-off state parks the peripheral in reset mode;
            // the 1-to-0 transition of the reset mode bit starts the recovery
            // sequence.
            self.regs().mode().modify(|_, w| w.reset_mode().set_bit());
            self.regs().mode().modify(|_, w| w.reset_mode().clear_bit());
        }
    }
    /// Returns the number of messages that the peripheral has available in the
    /// receive FIFO.
    ///
    /// May not be the number of valid messages in the receive FIFO due to fifo
    /// overflow or overrun.
    pub fn num_available_messages(&self) -> u8 {
        self.regs()
            .rx_message_cnt()
            .read()
            .rx_message_counter()
            .bits()
    }
    /// Clears the receive FIFO, discarding any valid, partial, or invalid
    /// packets.
    ///
    /// This is typically used to clear an overrun receive FIFO.
    ///
    /// TODO: Not sure if this needs to be guarded against Bus Off or other
    /// error states.
    pub fn clear_receive_fifo(&self) {
        while self.num_available_messages() > 0 {
            release_receive_fifo(self.regs());
        }
    }
    /// Sends the specified `EspTwaiFrame` over the TWAI bus.
    pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> {
        self.tx.transmit(frame)
    }
    /// Receives a TWAI frame from the TWAI bus.
    pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
        self.rx.receive()
    }
    /// Borrows the receiving and transmitting halves. Unlike [`Self::split`]
    /// the driver stays whole, so it can still be stopped and reconfigured
    /// ([`Self::stop`]) once they are no longer in use.
    #[instability::unstable]
    pub fn split_mut(&mut self) -> (&mut TwaiRx<'d, Dm>, &mut TwaiTx<'d, Dm>) {
        (&mut self.rx, &mut self.tx)
    }
    /// Consumes this `Twai` instance and splits it into transmitting and
    /// receiving halves.
    pub fn split(self) -> (TwaiRx<'d, Dm>, TwaiTx<'d, Dm>) {
        (self.rx, self.tx)
    }
}
/// Interface to the TWAI transmitter part.
pub struct TwaiTx<'d, Dm: DriverMode> {
    twai: AnyTwai<'d>,
    phantom: PhantomData<Dm>,
    _guard: PeripheralGuard,
}
impl<Dm> TwaiTx<'_, Dm>
where
    Dm: DriverMode,
{
    fn regs(&self) -> &RegisterBlock {
        self.twai.register_block()
    }
    /// Transmits a frame.
    ///
    /// Because of how the TWAI registers are set up, bytes must be assembled
    /// manually. These registers serve a filter configuration role when the
    /// device is in configuration mode, so patching the SVD files to improve
    /// this may be non-trivial.
    ///
    /// [ESP32C3 Reference Manual](https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#subsubsection.29.4.4.2)
    ///
    /// NOTE: TODO: This may not work if using the self reception/self test
    /// functionality. See notes 1 and 2 in the "Frame Identifier" section
    /// of the reference manual.
    ///
    /// If a previous frame is still pending and the peripheral has entered the
    /// error-passive state because of it (the bus cannot carry the frame, e.g.
    /// no other node acknowledges it), the pending transmission is aborted and
    /// [`EspTwaiError::TransmissionAborted`] is returned. An unacknowledged
    /// transmitter's error counter does not increase past the error-passive
    /// threshold, so without giving up the transmission would be retried
    /// forever.
    pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> {
        let status = self.regs().status().read();
        // Check that the peripheral is not in a bus off state.
2027752
        if status.bus_off_st().bit_is_set() {
            return nb::Result::Err(nb::Error::Other(EspTwaiError::BusOff));
        }
        // Check that the peripheral is not already transmitting a packet.
2027752
        if status.tx_buf_st().bit_is_clear() {
2027752
            if is_error_passive(self.regs()) {
                // Give up on the pending frame: the bus is apparently unable to
                // carry it.
                self.regs().cmd().write(|w| w.abort_tx().set_bit());
                return nb::Result::Err(nb::Error::Other(EspTwaiError::TransmissionAborted));
            }
            return nb::Result::Err(nb::Error::WouldBlock);
        }
        write_frame(self.regs(), frame);
        Ok(())
    }
}
/// Interface to the TWAI receiver part.
pub struct TwaiRx<'d, Dm: DriverMode> {
    twai: AnyTwai<'d>,
    phantom: PhantomData<Dm>,
    _guard: PeripheralGuard,
}
impl<Dm> TwaiRx<'_, Dm>
where
    Dm: DriverMode,
{
    fn regs(&self) -> &RegisterBlock {
        self.twai.register_block()
    }
    /// What the controller has reported since the driver was started (see
    /// [`ErrorCounts`])
    #[instability::unstable]
    pub fn error_counts(&self) -> ErrorCounts {
        self.twai.async_state().counts.snapshot()
    }
    /// Receives a frame.
    pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
        let status = self.regs().status().read();
        // Check that the peripheral is not in a bus off state.
        if status.bus_off_st().bit_is_set() {
            return nb::Result::Err(nb::Error::Other(EspTwaiError::BusOff));
        }
        // Check that we actually have packets to receive.
        if status.rx_buf_st().bit_is_clear() {
            return nb::Result::Err(nb::Error::WouldBlock);
        }
        // Check if the packet in the receive buffer is valid or overrun.
        if status.miss_st().bit_is_set() {
            // The FIFO entry is what is left of an overrun, not a frame:
            // release it, or every later call would report it again. The
            // async interrupt handler does the same.
            release_receive_fifo(self.regs());
            return nb::Result::Err(nb::Error::Other(EspTwaiError::EmbeddedHAL(
                ErrorKind::Overrun,
            )));
        }
        let frame = EspTwaiFrame::new_from_registers(self.regs());
        release_receive_fifo(self.regs());
        Ok(frame)
    }
}
/// List of TWAI events.
#[derive(Debug, EnumSetType)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
#[instability::unstable]
pub enum TwaiInterrupt {
    /// A frame has been received.
    Receive,
    /// A frame has been transmitted.
    Transmit,
    /// An error has occurred on the bus.
    BusError,
    /// An arbitration lost event has occurred.
    ArbitrationLost,
    /// The controller has entered an error passive state.
    ErrorPassive,
    /// The error or bus status has changed: an error counter crossed the
    /// error warning limit in either direction, or the controller entered or
    /// left the bus-off state.
    ErrorWarning,
}
/// What the controller has reported since the driver was last started
/// ([`TwaiConfiguration::start`]), as counted by the async driver's interrupt
/// handler (a blocking driver counts nothing).
///
/// Bus errors are classified from the error code capture register as
/// ESP-IDF does: bit, form and stuff errors by type, an acknowledgement
/// error by the ACK slot segment, anything else as `other`.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
#[instability::unstable]
pub struct ErrorCounts {
    /// Bit errors
    pub bit: u32,
    /// Form errors
    pub form: u32,
    /// Stuff errors
    pub stuff: u32,
    /// Acknowledgement errors: nobody acknowledged a transmitted frame
    pub acknowledge: u32,
    /// Other bus errors
    pub other: u32,
    /// Arbitration lost while transmitting (the controller retries)
    pub arbitration_lost: u32,
    /// Frames lost in the controller: its receive FIFO overran
    pub overrun: u32,
    /// Frames lost because the driver's receive queue was full
    pub queue_full: u32,
}
/// Errors that can occur when interacting with the TWAI peripheral.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum EspTwaiError {
    /// TWAI peripheral has entered a bus-off state.
    BusOff,
    /// The transmission was aborted because the peripheral repeatedly failed
    /// to transmit the frame and entered the error-passive state (e.g. no
    /// other node on the bus acknowledged the frame).
    TransmissionAborted,
    /// The received frame contains an invalid DLC.
    NonCompliantDlc(u8),
    /// Invalid data length.
    InvalidDataLength(u8),
    /// Encapsulates errors defined by the embedded-hal crate.
    EmbeddedHAL(ErrorKind),
}
#[instability::unstable]
impl embedded_can::Error for EspTwaiError {
    fn kind(&self) -> embedded_can::ErrorKind {
        if let Self::EmbeddedHAL(kind) = self {
            (*kind).into()
        } else {
            embedded_can::ErrorKind::Other
        }
    }
}
/// Copies data from multiple TWAI_DATA_x_REG registers, packing the source into
/// the destination.
///
/// # Safety
///
/// Reads arbitrarily from memory-mapped registers. Specifically, this function
/// is used with the TWAI_DATA_x_REG registers, which have different results
/// based on the mode of the peripheral.
#[inline(always)]
unsafe fn copy_from_data_register(dest: &mut [u8], src: *const u32) {
    for (i, dest) in dest.iter_mut().enumerate() {
        // Perform a volatile read to avoid compiler optimizations.
        unsafe {
            *dest = src.add(i).read_volatile() as u8;
        }
    }
}
/// Copies data to multiple TWAI_DATA_x_REG registers, unpacking the source into
/// the destination.
///
/// # Safety
///
/// Writes arbitrarily to memory-mapped registers. Specifically, this function
/// is used with the TWAI_DATA_x_REG registers, which have different results
/// based on the mode of the peripheral.
#[inline(always)]
unsafe fn copy_to_data_register(dest: *mut u32, src: &[u8]) {
    for (i, src) in src.iter().enumerate() {
        // Perform a volatile write to avoid compiler optimizations.
        unsafe {
8
            dest.add(i).write_volatile(*src as u32);
        }
    }
}
#[instability::unstable]
impl<Dm> embedded_can::nb::Can for Twai<'_, Dm>
where
    Dm: DriverMode,
{
    type Frame = EspTwaiFrame;
    type Error = EspTwaiError;
    /// Transmits a frame.
    fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
        self.tx.transmit(frame)?;
        // Success in readying packet for transmit. No packets can be replaced in the
        // transmit buffer so return None in accordance with the
        // embedded-can/embedded-hal trait.
        nb::Result::Ok(None)
    }
    /// Returns the next received frame, or a would-block error when none is available.
    fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
        self.rx.receive()
    }
}
/// TWAI peripheral instance.
#[doc(hidden)]
pub trait PrivateInstance: crate::private::Sealed {
    /// Returns the system peripheral marker for this instance.
    fn peripheral(&self) -> crate::system::Peripheral;
    /// Input signal.
    fn input_signal(&self) -> InputSignal;
    /// Output signal.
    fn output_signal(&self) -> OutputSignal;
    /// The interrupt associated with this TWAI instance.
    fn interrupt(&self) -> crate::peripherals::Interrupt;
    /// Provides an asynchronous interrupt handler for TWAI instance.
    fn async_handler(&self) -> InterruptHandler;
    /// Returns a reference to the register block for TWAI instance.
    fn register_block(&self) -> &RegisterBlock;
    /// Enables or disables interrupts for the TWAI peripheral based on the `enable` flag.
    fn enable_interrupts(&self, interrupts: EnumSet<TwaiInterrupt>, enable: bool) {
        self.register_block().int_ena().modify(|_, w| {
            for interrupt in interrupts {
                match interrupt {
                    TwaiInterrupt::Receive => w.rx_int_ena().bit(enable),
                    TwaiInterrupt::Transmit => w.tx_int_ena().bit(enable),
                    TwaiInterrupt::BusError => w.bus_err_int_ena().bit(enable),
                    TwaiInterrupt::ArbitrationLost => w.arb_lost_int_ena().bit(enable),
                    TwaiInterrupt::ErrorPassive => w.err_passive_int_ena().bit(enable),
                    TwaiInterrupt::ErrorWarning => w.err_warn_int_ena().bit(enable),
                };
            }
            w
        });
    }
    /// Listens for given interrupts.
    fn listen(&mut self, interrupts: impl Into<EnumSet<TwaiInterrupt>>) {
        self.enable_interrupts(interrupts.into(), true);
    }
    /// Unlistens from the given interrupts.
    fn unlisten(&mut self, interrupts: impl Into<EnumSet<TwaiInterrupt>>) {
        self.enable_interrupts(interrupts.into(), false);
    }
    /// Returns a reference to the asynchronous state for this TWAI instance.
    fn async_state(&self) -> &asynch::TwaiAsyncState;
}
/// Releases the message in the buffer. This will decrement the received
/// message counter and prepare the next message in the FIFO for
/// reading.
fn release_receive_fifo(register_block: &RegisterBlock) {
    register_block.cmd().write(|w| w.release_buf().set_bit());
}
/// Returns whether the peripheral is in the error-passive state, i.e. one of the
/// error counters has reached 128.
12103098
fn is_error_passive(register_block: &RegisterBlock) -> bool {
12103095
    register_block.tx_err_cnt().read().tx_err_cnt().bits() >= 128
12103094
        || register_block.rx_err_cnt().read().rx_err_cnt().bits() >= 128
12103094
}
/// Writes a frame to the peripheral.
fn write_frame(register_block: &RegisterBlock, frame: &EspTwaiFrame) {
    // SAFETY: safe because there are 13 data registers and the slice is 13 bytes long max
    unsafe {
        copy_to_data_register(register_block.data(0).as_ptr(), frame.as_slice());
    }
    // Trigger the appropriate transmission request based on self_reception flag
    match frame.is_self_reception() {
        // Set the transmit request command, this will lock the transmit buffer until
        // the transmission is complete or aborted.
        false => register_block.cmd().write(|w| w.tx_req().set_bit()),
        true => register_block.cmd().write(|w| w.self_rx_req().set_bit()),
    };
}
impl PrivateInstance for crate::peripherals::TWAI0<'_> {
    fn peripheral(&self) -> crate::system::Peripheral {
        crate::system::Peripheral::Twai0
    }
    fn input_signal(&self) -> InputSignal {
        cfg_select! {
            any(esp32, esp32c3, esp32s2, esp32s3) => InputSignal::TWAI_RX,
            _ => InputSignal::TWAI0_RX,
        }
    }
    fn output_signal(&self) -> OutputSignal {
        cfg_select! {
            any(esp32, esp32c3, esp32s2, esp32s3) => OutputSignal::TWAI_TX,
            _ => OutputSignal::TWAI0_TX,
        }
    }
    fn interrupt(&self) -> crate::peripherals::Interrupt {
        crate::peripherals::Interrupt::TWAI0
    }
    fn async_handler(&self) -> InterruptHandler {
        #[handler]
        fn twai0() {
            let twai = unsafe { crate::peripherals::TWAI0::steal() };
            asynch::handle_interrupt(twai.register_block(), twai.async_state());
        }
        twai0
    }
    #[inline(always)]
    fn register_block(&self) -> &RegisterBlock {
        crate::peripherals::TWAI0::regs()
    }
    fn async_state(&self) -> &asynch::TwaiAsyncState {
        static STATE: asynch::TwaiAsyncState = asynch::TwaiAsyncState::new();
        &STATE
    }
}
#[cfg(soc_has_twai1)]
impl PrivateInstance for crate::peripherals::TWAI1<'_> {
    fn peripheral(&self) -> crate::system::Peripheral {
        crate::system::Peripheral::Twai1
    }
    fn input_signal(&self) -> InputSignal {
        InputSignal::TWAI1_RX
    }
    fn output_signal(&self) -> OutputSignal {
        OutputSignal::TWAI1_TX
    }
    fn interrupt(&self) -> crate::peripherals::Interrupt {
        crate::peripherals::Interrupt::TWAI1
    }
    fn async_handler(&self) -> InterruptHandler {
        #[handler]
        fn twai1() {
            let twai = unsafe { crate::peripherals::TWAI1::steal() };
            asynch::handle_interrupt(twai.register_block(), twai.async_state());
        }
        twai1
    }
    #[inline(always)]
    fn register_block(&self) -> &RegisterBlock {
        crate::peripherals::TWAI1::regs()
    }
    fn async_state(&self) -> &asynch::TwaiAsyncState {
        static STATE: asynch::TwaiAsyncState = asynch::TwaiAsyncState::new();
        &STATE
    }
}
crate::any_peripheral! {
    /// Any TWAI peripheral.
    pub peripheral AnyTwai<'d> {
        #[cfg(soc_has_twai0)]
        Twai0(crate::peripherals::TWAI0<'d>),
        #[cfg(soc_has_twai1)]
        Twai1(crate::peripherals::TWAI1<'d>),
    }
}
impl PrivateInstance for AnyTwai<'_> {
    delegate::delegate! {
        to match &self.0 {
            #[cfg(soc_has_twai0)]
            any::Inner::Twai0(twai) => twai,
            #[cfg(soc_has_twai1)]
            any::Inner::Twai1(twai) => twai,
        } {
            fn peripheral(&self) -> crate::system::Peripheral;
            fn input_signal(&self) -> InputSignal;
            fn output_signal(&self) -> OutputSignal;
            fn interrupt(&self) -> crate::peripherals::Interrupt;
            fn async_handler(&self) -> InterruptHandler;
            fn register_block(&self) -> &RegisterBlock;
            fn async_state(&self) -> &asynch::TwaiAsyncState;
        }
    }
}
/// A peripheral singleton compatible with the TWAI driver.
pub trait Instance: PrivateInstance + any::Degrade {}
#[cfg(soc_has_twai0)]
impl Instance for crate::peripherals::TWAI0<'_> {}
#[cfg(soc_has_twai1)]
impl Instance for crate::peripherals::TWAI1<'_> {}
impl Instance for AnyTwai<'_> {}
mod asynch {
    use core::{future::poll_fn, task::Poll};
    use embassy_sync::{channel::Channel, waitqueue::AtomicWaker};
    use esp_sync::RawMutex;
    // `portable_atomic`: the ESP32-C3 has no atomic read-modify-write
    use portable_atomic::{AtomicU32, Ordering};
    use super::*;
    use crate::rtc_cntl::WakeLock;
    pub struct TwaiAsyncState {
        pub tx_waker: AtomicWaker,
        pub err_waker: AtomicWaker,
        pub rx_queue: Channel<RawMutex, Result<EspTwaiFrame, EspTwaiError>, 32>,
        pub counts: Counts,
    }
    /// [`ErrorCounts`], kept by the interrupt handler
    pub struct Counts {
        bit: AtomicU32,
        form: AtomicU32,
        stuff: AtomicU32,
        acknowledge: AtomicU32,
        other: AtomicU32,
        arbitration_lost: AtomicU32,
        overrun: AtomicU32,
        queue_full: AtomicU32,
    }
    /// ECC: the error type in bits 7-6, the segment in bits 4-0
    const ECC_TYPE_OTHER: u8 = 3;
    const ECC_SEGMENT_ACK_SLOT: u8 = 25;
    impl Counts {
        const fn new() -> Self {
            Self {
                bit: AtomicU32::new(0),
                form: AtomicU32::new(0),
                stuff: AtomicU32::new(0),
                acknowledge: AtomicU32::new(0),
                other: AtomicU32::new(0),
                arbitration_lost: AtomicU32::new(0),
                overrun: AtomicU32::new(0),
                queue_full: AtomicU32::new(0),
            }
        }
        fn count(counter: &AtomicU32) {
            counter.fetch_add(1, Ordering::Relaxed);
        }
        /// A bus error, from the error code capture register
        fn bus_error(&self, ecc: u8) {
            let counter = match ecc >> 6 {
                0 => &self.bit,
                1 => &self.form,
                2 => &self.stuff,
                ECC_TYPE_OTHER if ecc & 0x1F == ECC_SEGMENT_ACK_SLOT => &self.acknowledge,
                _ => &self.other,
            };
            Self::count(counter);
        }
9
        pub fn reset(&self) {
            for counter in [
                &self.bit,
9
                &self.form,
9
                &self.stuff,
9
                &self.acknowledge,
9
                &self.other,
9
                &self.arbitration_lost,
9
                &self.overrun,
9
                &self.queue_full,
            ] {
                counter.store(0, Ordering::Relaxed);
            }
9
        }
        pub fn snapshot(&self) -> ErrorCounts {
            let get = |c: &AtomicU32| c.load(Ordering::Relaxed);
            ErrorCounts {
                bit: get(&self.bit),
                form: get(&self.form),
                stuff: get(&self.stuff),
                acknowledge: get(&self.acknowledge),
                other: get(&self.other),
                arbitration_lost: get(&self.arbitration_lost),
                overrun: get(&self.overrun),
                queue_full: get(&self.queue_full),
            }
        }
    }
    impl Default for TwaiAsyncState {
        fn default() -> Self {
            Self::new()
        }
    }
    impl TwaiAsyncState {
        pub const fn new() -> Self {
            Self {
                tx_waker: AtomicWaker::new(),
                err_waker: AtomicWaker::new(),
                rx_queue: Channel::new(),
                counts: Counts::new(),
            }
        }
    }
    impl Twai<'_, Async> {
        /// Transmits an `EspTwaiFrame` asynchronously over the TWAI bus.
        ///
        /// The transmission is aborted if the future is dropped. The technical
        /// reference manual does not specifiy if aborting the transmission also
        /// stops it, in case it is activly transmitting. Therefor it could be
        /// the case that even though the future is dropped, the frame was sent
        /// anyways.
        ///
        /// If the bus cannot carry the frame (e.g. no other node acknowledges
        /// it), the transmission is aborted once the peripheral enters the
        /// error-passive or bus-off state and the future resolves to
        /// [`EspTwaiError::TransmissionAborted`] or [`EspTwaiError::BusOff`],
        /// respectively.
1
        pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
1
            self.tx.transmit_async(frame).await
        }
        /// Receives an `EspTwaiFrame` asynchronously over the TWAI bus.
        pub async fn receive_async(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
            self.rx.receive_async().await
        }
    }
    #[must_use = "futures do nothing unless you `.await` or poll them"]
    pub struct TransmitFuture<'d, 'f> {
        twai: AnyTwai<'d>,
        frame: &'f EspTwaiFrame,
        in_flight: bool,
        _wake_lock: WakeLock,
    }
    impl<'d, 'f> TransmitFuture<'d, 'f> {
2
        pub fn new(twai: AnyTwai<'d>, frame: &'f EspTwaiFrame) -> Self {
            Self {
                twai,
                frame,
                in_flight: false,
                _wake_lock: WakeLock::new(),
            }
2
        }
    }
    impl core::future::Future for TransmitFuture<'_, '_> {
        type Output = Result<(), EspTwaiError>;
2
        fn poll(
            mut self: core::pin::Pin<&mut Self>,
            cx: &mut core::task::Context<'_>,
        ) -> Poll<Self::Output> {
2
            self.twai.async_state().tx_waker.register(cx.waker());
            self.twai.listen(EnumSet::all());
            let regs = self.twai.register_block();
            let status = regs.status().read();
            // Check that the peripheral is not in a bus off state.
2
            if status.bus_off_st().bit_is_set() {
                return Poll::Ready(Err(EspTwaiError::BusOff));
            }
            // Check that the peripheral is not currently transmitting a packet.
            // This must come before the error-passive check: a frame whose
            // buffer has been released was transmitted successfully, no matter
            // what state the error counters are in.
2
            if status.tx_buf_st().bit_is_clear() {
2
                if is_error_passive(regs) {
                    // Give up on the pending frame: the bus is apparently
                    // unable to carry it (e.g. no other node acknowledges it),
                    // and an unacknowledged transmitter's error counter does
                    // not increase past the error-passive threshold, so the
                    // frame would otherwise be retried forever. The pending
                    // frame is not necessarily this future's own; a blocking
                    // `transmit` may have left it behind.
                    regs.cmd().write(|w| w.abort_tx().set_bit());
                    return Poll::Ready(Err(EspTwaiError::TransmissionAborted));
                }
                return Poll::Pending;
            }
            if !self.in_flight {
                write_frame(regs, self.frame);
                self.in_flight = true;
                return Poll::Pending;
            }
            Poll::Ready(Ok(()))
2
        }
    }
    impl Drop for TransmitFuture<'_, '_> {
        fn drop(&mut self) {
            self.twai
                .register_block()
                .cmd()
                .write(|w| w.abort_tx().set_bit());
        }
    }
    impl TwaiTx<'_, Async> {
        /// Transmits an `EspTwaiFrame` asynchronously over the TWAI bus.
        ///
        /// The transmission is aborted if the future is dropped. The technical
        /// reference manual does not specifiy if aborting the transmission also
        /// stops it, in case it is actively transmitting. Therefor it could be
        /// the case that even though the future is dropped, the frame was sent
        /// anyways.
        ///
        /// If the bus cannot carry the frame (e.g. no other node acknowledges
        /// it), the transmission is aborted once the peripheral enters the
        /// error-passive or bus-off state and the future resolves to
        /// [`EspTwaiError::TransmissionAborted`] or [`EspTwaiError::BusOff`],
        /// respectively.
1
        pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
1
            TransmitFuture::new(self.twai.reborrow(), frame).await
        }
    }
    impl TwaiRx<'_, Async> {
        /// Receives an `EspTwaiFrame` asynchronously over the TWAI bus.
        pub async fn receive_async(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
            poll_fn(|cx| {
                self.twai.async_state().err_waker.register(cx.waker());
                self.twai.listen(EnumSet::all());
                if let Poll::Ready(result) = self.twai.async_state().rx_queue.poll_receive(cx) {
                    return Poll::Ready(result);
                }
                let status = self.regs().status().read();
                // Check that the peripheral is not in a bus off state.
                if status.bus_off_st().bit_is_set() {
                    return Poll::Ready(Err(EspTwaiError::BusOff));
                }
                Poll::Pending
            })
            .await
        }
    }
    pub(super) fn handle_interrupt(register_block: &RegisterBlock, async_state: &TwaiAsyncState) {
        let int_raw = register_block.int_raw().read();
        // Disable the interrupts that fired (except the receive interrupt)
        // before waking anyone: a woken task on a higher priority executor
        // runs as soon as it is woken, before this handler returns. A
        // transmit future polled then enables the transmit interrupt for its
        // next frame, and clearing the bits afterwards from a copy read
        // before the wake would disable it again - the next frame's
        // completion would wake nobody.
        let int_ena = register_block.int_ena().read();
        unsafe {
            register_block
                .int_ena()
                .modify(|r, w| w.bits(r.bits() & (!int_raw.bits() | 1)));
        }
        // ... except the bus error and arbitration lost interrupts: they only
        // feed `ErrorCounts`, and reading their capture registers below
        // re-arms them. Masking them until the next future poll calls
        // `listen` would drop every error in between. ESP-IDF keeps them
        // enabled as well.
        register_block.int_ena().modify(|_, w| {
            w.bus_err_int_ena()
                .bit(int_ena.bus_err_int_ena().bit())
                .arb_lost_int_ena()
                .bit(int_ena.arb_lost_int_ena().bit())
        });
        // The error warning interrupt fires on every change of the error or
        // bus status. Entering bus-off sets both the bus-off and the error
        // warning status; during bus-off recovery the transmit error counter
        // counts down and the error warning status clears while the bus-off
        // status is still set. Gating on both ensures the bus-off state is
        // signalled only once per entry, instead of on every error warning
        // interrupt while the state persists.
        if int_raw.err_warn_int_st().bit_is_set() {
            let status = register_block.status().read();
            if status.bus_off_st().bit_is_set() && status.err_st().bit_is_set() {
                // Any pending transmission is halted by entering the bus-off
                // state; abort it to release the transmit buffer.
                register_block.cmd().write(|w| w.abort_tx().set_bit());
                let _ = async_state.rx_queue.try_send(Err(EspTwaiError::BusOff));
                async_state.tx_waker.wake();
                async_state.err_waker.wake();
            }
        }
        if int_raw.rx_int_st().bit_is_set() {
            let status_reg = register_block.status();
            let rx_queue = &async_state.rx_queue;
            // Consumme all pending frames in the Rx FIFO
            while register_block
                .rx_message_cnt()
                .read()
                .rx_message_counter()
                .bits()
                > 0
            {
                let msg = if status_reg.read().miss_st().bit_is_set() {
                    // Current frame is incomplete (Rx FIFO has overrun)
                    release_receive_fifo(register_block);
                    Counts::count(&async_state.counts.overrun);
                    Err(EspTwaiError::EmbeddedHAL(ErrorKind::Overrun))
                } else {
                    // Current frame is complete
                    let frame = EspTwaiFrame::new_from_registers(register_block);
                    release_receive_fifo(register_block);
                    Ok(frame)
                };
                // Rx queue is full? Stop consuming Rx frames. The one just
                // taken was released already: it is lost, and counted.
                if rx_queue.try_send(msg).is_err() {
                    Counts::count(&async_state.counts.queue_full);
                    break;
                }
            }
        }
        if int_raw.tx_int_st().bit_is_set() {
            async_state.tx_waker.wake();
        }
        if int_raw.arb_lost_int_st().bit_is_set() {
            // Reading the capture register re-arms the interrupt; nothing
            // else did, so it fired once per driver lifetime
            let _ = register_block.arb_lost_cap().read();
            Counts::count(&async_state.counts.arbitration_lost);
        }
        if int_raw.err_warn_int_st().bit_is_set()
            || int_raw.err_passive_int_st().bit_is_set()
            || int_raw.bus_err_int_st().bit_is_set()
        {
            // Reading the capture register also re-arms the bus error
            // interrupt. The error that takes the controller bus-off raises
            // no bus error interrupt of its own (ESP-IDF counts it from the
            // error warning interrupt), so it is counted here too.
            let ecc = register_block.err_code_cap().read().bits() as u8;
            let status = register_block.status().read();
            let entered_bus_off = int_raw.err_warn_int_st().bit_is_set()
                && status.bus_off_st().bit_is_set()
                && status.err_st().bit_is_set();
            if int_raw.bus_err_int_st().bit_is_set() || entered_bus_off {
                async_state.counts.bus_error(ecc);
            }
            async_state.err_waker.wake();
            // A frame that cannot be transmitted never raises the transmit
            // interrupt, so wake transmitters on errors to let them
            // re-evaluate their pending frame and give up once the peripheral
            // reaches the error-passive or bus-off state.
            async_state.tx_waker.wake();
        }
    }
}