1
use core::task::Poll;
2

            
3
use enumset::{EnumSet, EnumSetType};
4
use portable_atomic::AtomicBool;
5

            
6
#[cfg(feature = "unstable")]
7
use super::BaudrateTolerance;
8
use super::{
9
    AnyUart,
10
    Config,
11
    ConfigError,
12
    DataBits,
13
    HwFlowControl,
14
    Parity,
15
    RxError,
16
    RxErrorKind,
17
    StopBits,
18
    SwFlowControl,
19
    TxError,
20
    UartInterrupt,
21
    any,
22
};
23
#[cfg(sleep_driver_supported)]
24
use super::{WakeConfigError, WakeupConfig};
25
use crate::{
26
    asynch::AtomicWaker,
27
    gpio::{InputSignal, OutputSignal},
28
    handler,
29
    interrupt::InterruptHandler,
30
    pac::uart0::RegisterBlock,
31
    ram,
32
    soc::clocks::{
33
        self,
34
        ClockTree,
35
        UartBaudRateGeneratorConfig as BaudRateConfig,
36
        UartFunctionClockConfig as ClockConfig,
37
    },
38
};
39

            
40
#[cfg_attr(uart_version = "1", path = "v1.rs")]
41
#[cfg_attr(uart_version = "2", path = "v2.rs")]
42
mod version;
43

            
44
pub(super) use version::{enable_register_sync, sync_regs};
45

            
46
#[derive(Debug, EnumSetType)]
47
pub(super) enum TxEvent {
48
    Done,
49
    FiFoEmpty,
50
}
51

            
52
#[derive(Debug, EnumSetType)]
53
pub(super) enum RxEvent {
54
    FifoFull,
55
    CmdCharDetected,
56
    FifoOvf,
57
    FifoTout,
58
    GlitchDetected,
59
    FrameError,
60
    ParityError,
61
    BreakDetected,
62
}
63

            
64
pub(super) fn rx_event_check_for_error(
65
    events: EnumSet<RxEvent>,
66
    reported_errors: EnumSet<RxErrorKind>,
67
) -> Result<(), RxError> {
68
    for event in events {
69
        if let Some(error) = rx_error_kind(event)
70
            && reported_errors.contains(error)
71
        {
72
            return Err(error.into());
73
        }
74
    }
75

            
76
    Ok(())
77
}
78

            
79
fn rx_error_kind(event: RxEvent) -> Option<RxErrorKind> {
80
    match event {
81
        RxEvent::FifoOvf => Some(RxErrorKind::FifoOverflowed),
82
        RxEvent::GlitchDetected => Some(RxErrorKind::GlitchOccurred),
83
        RxEvent::FrameError => Some(RxErrorKind::FrameFormatViolated),
84
        RxEvent::ParityError => Some(RxErrorKind::ParityMismatch),
85
        RxEvent::FifoFull
86
        | RxEvent::CmdCharDetected
87
        | RxEvent::FifoTout
88
        | RxEvent::BreakDetected => None,
89
    }
90
}
91

            
92
/// A future that resolves when the passed interrupt is triggered,
93
/// or has been triggered in the meantime (flag set in INT_RAW).
94
/// Upon construction the future enables the passed interrupt and when it
95
/// is dropped it disables the interrupt again. The future returns the event
96
/// that was initially passed, when it resolves.
97
#[must_use = "futures do nothing unless you `.await` or poll them"]
98
pub(super) struct UartRxFuture {
99
    events: EnumSet<RxEvent>,
100
    uart: &'static Info,
101
    state: &'static State,
102
    registered: bool,
103
}
104

            
105
impl UartRxFuture {
106
    pub(super) fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
107
        Self {
108
            events: events.into(),
109
            uart: uart.info(),
110
            state: uart.state(),
111
            registered: false,
112
        }
113
    }
114
}
115

            
116
impl core::future::Future for UartRxFuture {
117
    type Output = EnumSet<RxEvent>;
118

            
119
    fn poll(
120
        mut self: core::pin::Pin<&mut Self>,
121
        cx: &mut core::task::Context<'_>,
122
    ) -> core::task::Poll<Self::Output> {
123
        let events = self.uart.rx_events().intersection(self.events);
124
        if !events.is_empty() {
125
            self.uart.clear_rx_events(events);
126
            Poll::Ready(events)
127
        } else {
128
            self.state.rx_waker.register(cx.waker());
129
            if !self.registered {
130
                self.uart.enable_listen_rx(self.events, true);
131
                self.registered = true;
132
            }
133
            Poll::Pending
134
        }
135
    }
136
}
137

            
138
impl Drop for UartRxFuture {
139
    fn drop(&mut self) {
140
        // Although the isr disables the interrupt that occurred directly, we need to
141
        // disable the other interrupts (= the ones that did not occur), as
142
        // soon as this future goes out of scope.
143
        self.uart.enable_listen_rx(self.events, false);
144
    }
145
}
146

            
147
#[must_use = "futures do nothing unless you `.await` or poll them"]
148
pub(super) struct UartTxFuture {
149
    events: EnumSet<TxEvent>,
150
    uart: &'static Info,
151
    state: &'static State,
152
    registered: bool,
153
}
154

            
155
impl UartTxFuture {
156
    pub(super) fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
157
        Self {
158
            events: events.into(),
159
            uart: uart.info(),
160
            state: uart.state(),
161
            registered: false,
162
        }
163
    }
164
}
165

            
166
impl core::future::Future for UartTxFuture {
167
    type Output = ();
168

            
169
    fn poll(
170
        mut self: core::pin::Pin<&mut Self>,
171
        cx: &mut core::task::Context<'_>,
172
    ) -> core::task::Poll<Self::Output> {
173
        let events = self.uart.tx_events().intersection(self.events);
174
        if !events.is_empty() {
175
            self.uart.clear_tx_events(events);
176
            Poll::Ready(())
177
        } else {
178
            self.state.tx_waker.register(cx.waker());
179
            if !self.registered {
180
                self.uart.enable_listen_tx(self.events, true);
181
                self.registered = true;
182
            }
183
            Poll::Pending
184
        }
185
    }
186
}
187

            
188
impl Drop for UartTxFuture {
189
    fn drop(&mut self) {
190
        // Although the isr disables the interrupt that occurred directly, we need to
191
        // disable the other interrupts (= the ones that did not occur), as
192
        // soon as this future goes out of scope.
193
        self.uart.enable_listen_tx(self.events, false);
194
    }
195
}
196

            
197
/// Interrupt handler for all UART instances
198
/// Clears and disables interrupts that have occurred and have their enable
199
/// bit set. The fact that an interrupt has been disabled is used by the
200
/// futures to detect that they should indeed resolve after being woken up
201
#[ram]
202
pub(super) fn intr_handler(uart: &Info, state: &State) {
203
    let interrupts = uart.regs().int_st().read();
204
    let interrupt_bits = interrupts.bits(); // = int_raw & int_ena
205
    let rx_wake = interrupts.rxfifo_full().bit_is_set()
206
        | interrupts.rxfifo_ovf().bit_is_set()
207
        | interrupts.rxfifo_tout().bit_is_set()
208
        | interrupts.at_cmd_char_det().bit_is_set()
209
        | interrupts.glitch_det().bit_is_set()
210
        | interrupts.frm_err().bit_is_set()
211
        | interrupts.parity_err().bit_is_set()
212
        | interrupts.brk_det().bit_is_set();
213
    let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
214

            
215
    uart.regs()
216
        .int_ena()
217
        .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
218

            
219
    if tx_wake {
220
        state.tx_waker.wake();
221
    }
222
    if rx_wake {
223
        state.rx_waker.wake();
224
    }
225
}
226

            
227
/// A peripheral singleton compatible with the UART driver.
228
pub trait Instance: crate::private::Sealed + any::Degrade {
229
    #[doc(hidden)]
230
    /// Returns the peripheral data and state describing this UART instance.
231
    fn parts(&self) -> (&'static Info, &'static State);
232

            
233
    /// Returns the peripheral data describing this UART instance.
234
    #[inline(always)]
235
    #[doc(hidden)]
236
    fn info(&self) -> &'static Info {
237
        self.parts().0
238
    }
239

            
240
    /// Returns the peripheral state for this UART instance.
241
    #[inline(always)]
242
    #[doc(hidden)]
243
    fn state(&self) -> &'static State {
244
        self.parts().1
245
    }
246
}
247

            
248
/// Peripheral data describing a particular UART instance.
249
#[doc(hidden)]
250
#[non_exhaustive]
251
#[allow(private_interfaces, reason = "Unstable details")]
252
pub struct Info {
253
    /// Pointer to the register block for this UART instance.
254
    ///
255
    /// Used with [`Self::register_block`] to access the register block.
256
    pub register_block: *const RegisterBlock,
257

            
258
    /// The system peripheral marker.
259
    pub peripheral: crate::system::Peripheral,
260

            
261
    /// UART clock group instance.
262
    pub clock_instance: clocks::UartInstance,
263

            
264
    /// Interrupt handler for the asynchronous operations of this UART instance.
265
    pub async_handler: InterruptHandler,
266

            
267
    /// TX pin
268
    pub tx_signal: OutputSignal,
269

            
270
    /// RX pin
271
    pub rx_signal: InputSignal,
272

            
273
    /// CTS (Clear to Send) pin
274
    pub cts_signal: InputSignal,
275

            
276
    /// RTS (Request to Send) pin
277
    pub rts_signal: OutputSignal,
278

            
279
    /// The wakeup source of this instance, or `None` if the instance cannot wake the chip.
280
    #[cfg(sleep_driver_supported)]
281
    pub wakeup_source: Option<crate::rtc_cntl::WakeupSource>,
282
}
283

            
284
/// Peripheral state for a UART instance.
285
#[doc(hidden)]
286
#[non_exhaustive]
287
pub struct State {
288
    /// Waker for the asynchronous RX operations.
289
    pub rx_waker: AtomicWaker,
290

            
291
    /// Waker for the asynchronous TX operations.
292
    pub tx_waker: AtomicWaker,
293

            
294
    /// Stores whether the RX half is configured for async operation.
295
    pub is_rx_async: AtomicBool,
296

            
297
    /// Stores whether the TX half is configured for async operation.
298
    pub is_tx_async: AtomicBool,
299
}
300

            
301
impl Info {
302
    // Currently we don't support merging adjacent FIFO memory, so the max size is
303
    // 128 bytes, the max threshold is 127 bytes.
304
    pub(super) const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
305
    pub(super) const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
306
    pub(super) const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
307

            
308
    /// Returns the register block for this UART instance.
309
    pub fn regs(&self) -> &RegisterBlock {
310
        unsafe { &*self.register_block }
311
    }
312

            
313
    /// Listens for the given interrupts.
314
    pub(super) fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
315
        let reg_block = self.regs();
316

            
317
        reg_block.int_ena().modify(|_, w| {
318
            for interrupt in interrupts {
319
                match interrupt {
320
                    UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
321
                    UartInterrupt::TxDone => w.tx_done().bit(enable),
322
                    UartInterrupt::RxBreakDetected => w.brk_det().bit(enable),
323
                    UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
324
                    UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
325
                };
326
            }
327
            w
328
        });
329
    }
330

            
331
    pub(super) fn interrupts(&self) -> EnumSet<UartInterrupt> {
332
        let mut res = EnumSet::new();
333
        let reg_block = self.regs();
334

            
335
        let ints = reg_block.int_raw().read();
336

            
337
        if ints.at_cmd_char_det().bit_is_set() {
338
            res.insert(UartInterrupt::AtCmd);
339
        }
340
        if ints.tx_done().bit_is_set() {
341
            res.insert(UartInterrupt::TxDone);
342
        }
343
        if ints.brk_det().bit_is_set() {
344
            res.insert(UartInterrupt::RxBreakDetected);
345
        }
346
        if ints.rxfifo_full().bit_is_set() {
347
            res.insert(UartInterrupt::RxFifoFull);
348
        }
349
        if ints.rxfifo_tout().bit_is_set() {
350
            res.insert(UartInterrupt::RxTimeout);
351
        }
352

            
353
        res
354
    }
355

            
356
    pub(super) fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
357
        let reg_block = self.regs();
358

            
359
        reg_block.int_clr().write(|w| {
360
            for interrupt in interrupts {
361
                match interrupt {
362
                    UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
363
                    UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
364
                    UartInterrupt::RxBreakDetected => w.brk_det().clear_bit_by_one(),
365
                    UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
366
                    UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
367
                };
368
            }
369
            w
370
        });
371
    }
372

            
373
    pub(super) fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
374
        config.validate()?;
375
        self.change_baud(config)?;
376
        self.change_data_bits(config.data_bits);
377
        self.change_parity(config.parity);
378
        self.change_stop_bits(config.stop_bits);
379
        self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
380

            
381
        // Avoid glitch interrupts.
382
        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
383

            
384
        Ok(())
385
    }
386

            
387
    pub(super) fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
388
        self.regs().int_ena().modify(|_, w| {
389
            for event in events {
390
                match event {
391
                    TxEvent::Done => w.tx_done().bit(enable),
392
                    TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
393
                };
394
            }
395
            w
396
        });
397
    }
398

            
399
    fn tx_events(&self) -> EnumSet<TxEvent> {
400
        let pending_interrupts = self.regs().int_raw().read();
401
        let mut active_events = EnumSet::new();
402

            
403
        if pending_interrupts.tx_done().bit_is_set() {
404
            active_events |= TxEvent::Done;
405
        }
406
        if pending_interrupts.txfifo_empty().bit_is_set() {
407
            active_events |= TxEvent::FiFoEmpty;
408
        }
409

            
410
        active_events
411
    }
412

            
413
    fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
414
        let events = events.into();
415
        self.regs().int_clr().write(|w| {
416
            for event in events {
417
                match event {
418
                    TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
419
                    TxEvent::Done => w.tx_done().clear_bit_by_one(),
420
                };
421
            }
422
            w
423
        });
424
    }
425

            
426
    pub(super) fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
427
        self.regs().int_ena().modify(|_, w| {
428
            for event in events {
429
                match event {
430
                    RxEvent::FifoFull => w.rxfifo_full().bit(enable),
431
                    RxEvent::BreakDetected => w.brk_det().bit(enable),
432
                    RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
433

            
434
                    RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
435
                    RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
436
                    RxEvent::GlitchDetected => w.glitch_det().bit(enable),
437
                    RxEvent::FrameError => w.frm_err().bit(enable),
438
                    RxEvent::ParityError => w.parity_err().bit(enable),
439
                };
440
            }
441
            w
442
        });
443
    }
444

            
445
    fn rx_events(&self) -> EnumSet<RxEvent> {
446
        let pending_interrupts = self.regs().int_raw().read();
447
        let mut active_events = EnumSet::new();
448

            
449
        if pending_interrupts.rxfifo_full().bit_is_set() {
450
            active_events |= RxEvent::FifoFull;
451
        }
452
        if pending_interrupts.brk_det().bit_is_set() {
453
            active_events |= RxEvent::BreakDetected;
454
        }
455
        if pending_interrupts.at_cmd_char_det().bit_is_set() {
456
            active_events |= RxEvent::CmdCharDetected;
457
        }
458
        if pending_interrupts.rxfifo_ovf().bit_is_set() {
459
            active_events |= RxEvent::FifoOvf;
460
        }
461
        if pending_interrupts.rxfifo_tout().bit_is_set() {
462
            active_events |= RxEvent::FifoTout;
463
        }
464
        if pending_interrupts.glitch_det().bit_is_set() {
465
            active_events |= RxEvent::GlitchDetected;
466
        }
467
        if pending_interrupts.frm_err().bit_is_set() {
468
            active_events |= RxEvent::FrameError;
469
        }
470
        if pending_interrupts.parity_err().bit_is_set() {
471
            active_events |= RxEvent::ParityError;
472
        }
473

            
474
        active_events
475
    }
476

            
477
    fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
478
        let events = events.into();
479
        self.regs().int_clr().write(|w| {
480
            for event in events {
481
                match event {
482
                    RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
483
                    RxEvent::BreakDetected => w.brk_det().clear_bit_by_one(),
484
                    RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
485

            
486
                    RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
487
                    RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
488
                    RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
489
                    RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
490
                    RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
491
                };
492
            }
493
            w
494
        });
495
    }
496

            
497
    /// Configures the RX-FIFO threshold.
498
    ///
499
    /// # Errors
500
    ///
501
    /// [`ConfigError::RxFifoThresholdNotSupported`] if the provided value is zero
502
    /// or exceeds [`Info::RX_FIFO_MAX_THRHD`].
503
    pub(super) fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
504
        if threshold == 0 || threshold > Self::RX_FIFO_MAX_THRHD {
505
            return Err(ConfigError::RxFifoThresholdNotSupported);
506
        }
507

            
508
        self.regs()
509
            .conf1()
510
            .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
511

            
512
        Ok(())
513
    }
514

            
515
    /// Reads the RX-FIFO threshold.
516
    #[allow(clippy::useless_conversion)]
517
    pub(super) fn rx_fifo_full_threshold(&self) -> u16 {
518
        self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
519
    }
520

            
521
    /// Configures the TX-FIFO threshold.
522
    ///
523
    /// # Errors
524
    ///
525
    /// [`ConfigError::TxFifoThresholdNotSupported`] if the provided value exceeds
526
    /// [`Info::TX_FIFO_MAX_THRHD`].
527
    pub(super) fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
528
        if threshold > Self::TX_FIFO_MAX_THRHD {
529
            return Err(ConfigError::TxFifoThresholdNotSupported);
530
        }
531

            
532
        self.regs()
533
            .conf1()
534
            .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
535

            
536
        Ok(())
537
    }
538

            
539
    #[cfg(uart_has_sclk_enable)]
540
    pub(super) fn set_at_cmd_clock_enabled(&self, enabled: bool) {
541
        self.regs()
542
            .clk_conf()
543
            .modify(|_, w| w.sclk_en().bit(enabled));
544
    }
545

            
546
    #[procmacros::doc_replace(
547
        "rx_timeout_limit" => {
548
            cfg(esp32) => "- Symbol size is fixed to 8, do not pass a value > **0x7F**.",
549
            _ => "- The value you pass times the symbol size must be <= **0x3FF**.",
550
        }
551
    )]
552
    /// Configures the Receive Timeout detection setting.
553
    ///
554
    /// ## Arguments
555
    ///
556
    /// `timeout` - the number of symbols ("bytes") to wait for before
557
    /// triggering a timeout. Pass None to disable the timeout.
558
    ///
559
    /// # Errors
560
    ///
561
    /// [`ConfigError::TimeoutTooLong`] if the provided value exceeds
562
    /// the maximum value for SOC:
563
    /// {rx_timeout_limit}
564
    pub(super) fn set_rx_timeout(
565
        &self,
566
        timeout: Option<u8>,
567
        symbol_len: u8,
568
    ) -> Result<(), ConfigError> {
569
        version::set_rx_timeout(self, timeout, symbol_len)
570
    }
571

            
572
    pub(super) fn rx_timeout_enabled(&self) -> bool {
573
        version::rx_timeout_enabled(self)
574
    }
575

            
576
    pub(super) fn set_discard_erroneous_bytes(&self, discard: bool) {
577
        // ERR_WR_MASK causes the hardware to discard bytes with UART errors
578
        // instead of storing them in the RX FIFO.
579
        self.regs()
580
            .conf0()
581
            .modify(|_, w| w.err_wr_mask().bit(discard));
582
        self.sync_regs();
583
    }
584

            
585
    pub(super) fn is_tx_idle(&self) -> bool {
586
        version::is_tx_idle(self)
587
    }
588

            
589
    fn sync_regs(&self) {
590
        sync_regs(self.regs());
591
    }
592

            
593
    fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
594
        ClockTree::with(|clocks| {
595
            let clock = self.clock_instance;
596

            
597
            let clk = clocks::UartInstance::function_clock_source_frequency(config.clock_source);
598

            
599
            // The UART baud rate clock divider is, depending on the device, either a
600
            // 20.4 bit, or a 12.4 bit divider.
601
            const FRAC_BITS: u32 = const {
602
                let largest_divider: u32 =
603
                    property!("clock_tree.uart.baud_rate_generator.fractional").1;
604
                ::core::assert!((largest_divider + 1).is_power_of_two());
605
                largest_divider.count_ones()
606
            };
607
            const FRAC_MASK: u32 = (1 << FRAC_BITS) - 1;
608

            
609
            // TODO: this block should only prepare the new clock config, and it should
610
            // be applied only after validating the resulting baud rate.
611
            cfg_select! {
612
                any(uart_has_sclk_divider, soc_has_pcr, esp32p4, esp32s31) => {
613
                    const MAX_DIV: u32 =
614
                        property!("clock_tree.uart.baud_rate_generator.integral").1;
615
                    let clk_div = clk.div_ceil(MAX_DIV).div_ceil(config.baudrate);
616
                    debug!("SCLK: {} divider: {}", clk, clk_div);
617

            
618
                    let conf = ClockConfig::new(config.clock_source, clk_div - 1);
619
                    let divider = (clk << FRAC_BITS) / (config.baudrate * clk_div);
620
                }
621
                _ => {
622
                    debug!("SCLK: {}", clk);
623
                    let conf = ClockConfig::new(config.clock_source);
624
                    let divider = (clk << FRAC_BITS) / config.baudrate;
625
                }
626
            }
627

            
628
            let divider_integer = divider >> FRAC_BITS;
629
            let divider_frag = divider & FRAC_MASK;
630
            debug!(
631
                "UART CLK divider: {} + {}/16",
632
                divider_integer, divider_frag
633
            );
634

            
635
            clock.configure_function_clock(clocks, conf);
636
            clock.configure_baud_rate_generator(
637
                clocks,
638
                BaudRateConfig::new(divider_frag, divider_integer),
639
            );
640

            
641
            self.sync_regs();
642

            
643
            #[cfg(feature = "unstable")]
644
            {
645
                let deviation_limit = match config.baudrate_tolerance {
646
                    BaudrateTolerance::Exact => 1, // Still allow a tiny deviation
647
                    BaudrateTolerance::ErrorPercent(percent) => percent as u32,
648
                    _ => return Ok(()),
649
                };
650

            
651
                let actual_baud = clock.baud_rate_generator_frequency();
652
                if actual_baud == 0 {
653
                    return Err(ConfigError::BaudrateNotAchievable);
654
                }
655

            
656
                let deviation = (config.baudrate.abs_diff(actual_baud) * 100) / actual_baud;
657
                debug!(
658
                    "Nominal baud: {}, actual: {}, deviation: {}%",
659
                    config.baudrate, actual_baud, deviation
660
                );
661

            
662
                if deviation > deviation_limit {
663
                    return Err(ConfigError::BaudrateNotAchievable);
664
                }
665
            }
666

            
667
            Ok(())
668
        })
669
    }
670

            
671
    fn change_data_bits(&self, data_bits: DataBits) {
672
        self.regs()
673
            .conf0()
674
            .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
675
    }
676

            
677
    fn change_parity(&self, parity: Parity) {
678
        self.regs().conf0().modify(|_, w| match parity {
679
            Parity::None => w.parity_en().clear_bit(),
680
            Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
681
            Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
682
        });
683
    }
684

            
685
    fn change_stop_bits(&self, stop_bits: StopBits) {
686
        version::change_stop_bits(self, stop_bits);
687
    }
688

            
689
    fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
690
        version::change_flow_control(self, sw_flow_ctrl, hw_flow_ctrl);
691
    }
692

            
693
    pub(super) fn rxfifo_reset(&self) {
694
        fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
695
            reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
696
            sync_regs(reg_block);
697
        }
698

            
699
        rxfifo_rst(self.regs(), true);
700
        rxfifo_rst(self.regs(), false);
701
    }
702

            
703
    pub(super) fn txfifo_reset(&self) {
704
        fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
705
            reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
706
            sync_regs(reg_block);
707
        }
708

            
709
        txfifo_rst(self.regs(), true);
710
        txfifo_rst(self.regs(), false);
711

            
712
        // The reset can drive the state machine. Wait for it to settle.
713
        while !self.is_tx_idle() {}
714
    }
715

            
716
    pub(super) fn current_symbol_length(&self) -> u8 {
717
        version::current_symbol_length(self)
718
    }
719

            
720
    /// Reads one byte from the RX FIFO.
721
    ///
722
    /// If the FIFO is empty, the value of the returned byte is not specified.
723
    pub(super) fn read_next_from_fifo(&self) -> u8 {
724
        version::read_next_from_fifo(self)
725
    }
726

            
727
    #[allow(clippy::useless_conversion)]
728
    pub(super) fn tx_fifo_count(&self) -> u16 {
729
        u16::from(self.regs().status().read().txfifo_cnt().bits())
730
    }
731

            
732
    pub(super) fn write_byte(&self, byte: u8) {
733
        self.regs()
734
            .fifo()
735
            .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
736
    }
737

            
738
    fn check_for_errors_and_reset_fifo(
739
        &self,
740
        reported_errors: EnumSet<RxErrorKind>,
741
    ) -> Result<bool, RxError> {
742
        let errors =
743
            RxEvent::FifoOvf | RxEvent::GlitchDetected | RxEvent::FrameError | RxEvent::ParityError;
744
        let events = self.rx_events().intersection(errors);
745
        let result = rx_event_check_for_error(events, reported_errors);
746
        let fifo_overflowed = events.contains(RxEvent::FifoOvf);
747
        if !events.is_empty() {
748
            self.clear_rx_events(events);
749
            if fifo_overflowed {
750
                self.rxfifo_reset();
751
            }
752
        }
753
        result.map(|()| fifo_overflowed)
754
    }
755

            
756
    pub(super) fn check_for_errors(
757
        &self,
758
        reported_errors: EnumSet<RxErrorKind>,
759
    ) -> Result<(), RxError> {
760
        self.check_for_errors_and_reset_fifo(reported_errors)
761
            .map(|_| ())
762
    }
763

            
764
    pub(super) fn check_rx_break_detected(&self) -> bool {
765
        self.rx_events().contains(RxEvent::BreakDetected)
766
    }
767

            
768
    pub(super) fn clear_rx_break_detected(&self) {
769
        self.clear_rx_events(RxEvent::BreakDetected);
770
    }
771

            
772
    pub(super) fn rx_fifo_count(&self) -> u16 {
773
        version::rx_fifo_count(self)
774
    }
775

            
776
    pub(super) fn write(&self, data: &[u8]) -> Result<usize, TxError> {
777
        if data.is_empty() {
778
            return Ok(0);
779
        }
780

            
781
        while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
782

            
783
        let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
784
        let to_write = space.min(data.len());
785
        for &byte in &data[..to_write] {
786
            self.write_byte(byte);
787
        }
788

            
789
        Ok(to_write)
790
    }
791

            
792
    pub(super) fn read(
793
        &self,
794
        buf: &mut [u8],
795
        reported_errors: EnumSet<RxErrorKind>,
796
    ) -> Result<usize, RxError> {
797
        if buf.is_empty() {
798
            return Ok(0);
799
        }
800

            
801
        loop {
802
            while self.rx_fifo_count() == 0 {
803
                // Block until we received at least one byte
804
                self.check_for_errors(reported_errors)?;
805
            }
806

            
807
            let read = self.read_buffered(buf, reported_errors)?;
808
            if read > 0 {
809
                break Ok(read);
810
            }
811
        }
812
    }
813

            
814
    pub(super) fn read_buffered(
815
        &self,
816
        buf: &mut [u8],
817
        reported_errors: EnumSet<RxErrorKind>,
818
    ) -> Result<usize, RxError> {
819
        // Get the count first, to avoid accidentally reading a corrupted byte received
820
        // after the error check.
821
        let to_read = (self.rx_fifo_count() as usize).min(buf.len());
822
        if self.check_for_errors_and_reset_fifo(reported_errors)? {
823
            return Ok(0);
824
        }
825

            
826
        for byte_into in buf[..to_read].iter_mut() {
827
            *byte_into = self.read_next_from_fifo();
828
        }
829

            
830
        // This bit is not cleared until the FIFO actually drops below the threshold.
831
        self.clear_rx_events(RxEvent::FifoFull);
832

            
833
        Ok(to_read)
834
    }
835

            
836
    #[cfg(sleep_driver_supported)]
837
    pub(crate) fn suspend_for_sleep(&self) {
838
        version::suspend(self, true);
839
        version::wait_for_suspended(self);
840
    }
841

            
842
    #[cfg(sleep_driver_supported)]
843
    pub(crate) fn resume_from_sleep(&self) {
844
        version::suspend(self, false);
845
    }
846

            
847
    /// Lets this instance wake the chip from light sleep.
848
    #[cfg(sleep_driver_supported)]
849
    pub(crate) fn enable_wakeup(&self, config: &WakeupConfig) -> Result<(), WakeConfigError> {
850
        let source = self
851
            .wakeup_source
852
            .ok_or(WakeConfigError::NotAWakeupSource)?;
853

            
854
        let edges = config.rising_edges();
855
        if !(super::MIN_WAKEUP_EDGES..=super::MAX_WAKEUP_EDGES).contains(&edges) {
856
            return Err(WakeConfigError::EdgeCountUnsupported);
857
        }
858

            
859
        // The register holds the number of edges above a fixed offset.
860
        version::set_wakeup_edge_threshold(self, edges - super::WAKEUP_EDGE_OFFSET);
861

            
862
        source.enable_with_hooks(Some(keep_peripherals_powered), None);
863

            
864
        Ok(())
865
    }
866

            
867
    /// Stops this instance from waking the chip.
868
    #[cfg(sleep_driver_supported)]
869
    pub(crate) fn disable_wakeup(&self) {
870
        if let Some(source) = self.wakeup_source {
871
            source.disable();
872
        }
873
    }
874
}
875

            
876
/// The UART peripheral monitors the RX line itself, so the peripheral must stay powered.
877
#[cfg(sleep_driver_supported)]
878
#[crate::ram]
879
fn keep_peripherals_powered(config: &mut crate::rtc_cntl::sleep::WrappedSleepConfig<'_>) {
880
    // A deep sleep powers the peripheral down in all cases, so this request gives no wake there. It
881
    // only increases the current.
882
    if !config.is_deep_sleep() {
883
        config.keep_alive(crate::rtc_cntl::sleep::SleepResource::HpPeripherals);
884
    }
885
}
886

            
887
impl PartialEq for Info {
888
    fn eq(&self, other: &Self) -> bool {
889
        core::ptr::eq(self.register_block, other.register_block)
890
    }
891
}
892

            
893
unsafe impl Sync for Info {}
894

            
895
// Each instance names its wakeup source, and no code calculates the source from the metadata flag.
896
// An instance that cannot wake the chip has no `WakeupSource` variant to name.
897
macro_rules! impl_instance {
898
    ($inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident, $wakeup_source:expr) => {
899
        impl Instance for crate::peripherals::$inst<'_> {
900
            fn parts(&self) -> (&'static Info, &'static State) {
901
                #[handler]
902
                #[ram]
903
                pub(super) fn irq_handler() {
904
                    intr_handler(&PERIPHERAL, &STATE);
905
                }
906

            
907
                static STATE: State = State {
908
                    tx_waker: AtomicWaker::new(),
909
                    rx_waker: AtomicWaker::new(),
910
                    is_rx_async: AtomicBool::new(false),
911
                    is_tx_async: AtomicBool::new(false),
912
                };
913

            
914
                static PERIPHERAL: Info = Info {
915
                    register_block: crate::peripherals::$inst::ptr(),
916
                    peripheral: crate::system::Peripheral::$peri,
917
                    clock_instance: clocks::UartInstance::$peri,
918
                    async_handler: irq_handler,
919
                    tx_signal: OutputSignal::$txd,
920
                    rx_signal: InputSignal::$rxd,
921
                    cts_signal: InputSignal::$cts,
922
                    rts_signal: OutputSignal::$rts,
923
                    #[cfg(sleep_driver_supported)]
924
                    wakeup_source: $wakeup_source,
925
                };
926
                (&PERIPHERAL, &STATE)
927
            }
928
        }
929
    };
930
}
931

            
932
for_each_uart! {
933
    ($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident, wakeup_source = true) => {
934
        impl_instance!($inst, $peri, $rxd, $txd, $cts, $rts, Some(crate::rtc_cntl::WakeupSource::$peri));
935
    };
936
    ($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident, wakeup_source = false) => {
937
        impl_instance!($inst, $peri, $rxd, $txd, $cts, $rts, None);
938
    };
939
}
940

            
941
pub(super) struct UartClockGuard<'t> {
942
    uart: AnyUart<'t>,
943
}
944

            
945
impl<'t> UartClockGuard<'t> {
946
    pub(super) fn new(uart: AnyUart<'t>) -> Self {
947
        let this = Self::new_inner(uart, false);
948
        crate::rom::ets_delay_us(100);
949
        this
950
    }
951

            
952
    pub(super) fn new_inner(uart: AnyUart<'t>, clone: bool) -> Self {
953
        ClockTree::with(|clocks| {
954
            let clock = uart.info().clock_instance;
955

            
956
            // Apply default SCLK configuration when first instance is created.
957
            if !clone {
958
                let sclk_config = ClockConfig::new(
959
                    Default::default(),
960
                    #[cfg(any(uart_has_sclk_divider, soc_has_pcr, esp32p4, esp32s31))]
961
                    0,
962
                );
963
                clock.configure_function_clock(clocks, sclk_config);
964
            }
965
            clock.request_function_clock(clocks);
966
            clock.request_baud_rate_generator(clocks);
967
            #[cfg(soc_has_clock_node_uart_mem_clock)]
968
            clock.request_mem_clock(clocks);
969
        });
970

            
971
        Self { uart }
972
    }
973
}
974

            
975
impl Clone for UartClockGuard<'_> {
976
    fn clone(&self) -> Self {
977
        Self::new_inner(unsafe { self.uart.clone_unchecked() }, true)
978
    }
979
}
980

            
981
impl Drop for UartClockGuard<'_> {
982
    fn drop(&mut self) {
983
        ClockTree::with(|clocks| {
984
            let clock = self.uart.info().clock_instance;
985

            
986
            #[cfg(soc_has_clock_node_uart_mem_clock)]
987
            clock.release_mem_clock(clocks);
988
            clock.release_baud_rate_generator(clocks);
989
            clock.release_function_clock(clocks);
990
        });
991
    }
992
}