libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
mspm0_uart.cpp
1#include "mspm0_uart.hpp"
2
3#include <atomic>
4
5using namespace LibXR;
6
7MSPM0UART* MSPM0UART::instance_map_[MAX_UART_INSTANCES] = {nullptr};
8
9static constexpr uint32_t MSPM0_UART_RX_ERROR_INTERRUPT_MASK =
10 DL_UART_INTERRUPT_OVERRUN_ERROR | DL_UART_INTERRUPT_BREAK_ERROR |
11 DL_UART_INTERRUPT_PARITY_ERROR | DL_UART_INTERRUPT_FRAMING_ERROR |
12 DL_UART_INTERRUPT_NOISE_ERROR;
13
14static constexpr uint32_t MSPM0_UART_BASE_INTERRUPT_MASK =
15 // RX/TX + 地址匹配 + 错误中断;超时中断按需在 Read() 时动态开关 / RX, TX,
16 // address-match and error IRQs; timeout IRQ is enabled on demand in Read().
17 DL_UART_INTERRUPT_RX | DL_UART_INTERRUPT_TX | DL_UART_INTERRUPT_ADDRESS_MATCH |
18 MSPM0_UART_RX_ERROR_INTERRUPT_MASK;
19
20MSPM0UART::MSPM0UART(Resources res, RawData rx_stage_buffer, uint32_t tx_queue_size,
21 uint32_t tx_buffer_size, UART::Configuration config)
22 : UART(&_read_port, &_write_port),
23 _read_port(rx_stage_buffer.size_),
24 _write_port(tx_queue_size, tx_buffer_size),
25 res_(res)
26{
27 ASSERT(res_.instance != nullptr);
28 ASSERT(res_.clock_freq > 0);
29 ASSERT(rx_stage_buffer.addr_ != nullptr);
30 ASSERT(rx_stage_buffer.size_ > 0);
31 ASSERT(tx_queue_size > 0);
32 ASSERT(tx_buffer_size > 0);
33
34 _read_port = ReadFun;
35 _write_port = WriteFun;
36
37 ASSERT(res_.index < MAX_UART_INSTANCES);
38 ASSERT(instance_map_[res_.index] == nullptr);
39 instance_map_[res_.index] = this;
40
41 NVIC_ClearPendingIRQ(res_.irqn);
42 NVIC_EnableIRQ(res_.irqn);
43
44 const ErrorCode SET_CFG_ANS = SetConfig(config);
45 ASSERT(SET_CFG_ANS == ErrorCode::OK);
46}
47
48UART::Configuration MSPM0UART::BuildConfigFromSysCfg(UART_Regs* instance,
49 uint32_t baudrate)
50{
51 ASSERT(instance != nullptr);
52 ASSERT(baudrate > 0U);
53
54 UART::Configuration config = {baudrate, UART::Parity::NO_PARITY, 8U, 1U};
55
56 switch (DL_UART_getWordLength(instance))
57 {
58 case DL_UART_WORD_LENGTH_5_BITS:
59 config.data_bits = 5U;
60 break;
61 case DL_UART_WORD_LENGTH_6_BITS:
62 config.data_bits = 6U;
63 break;
64 case DL_UART_WORD_LENGTH_7_BITS:
65 config.data_bits = 7U;
66 break;
67 case DL_UART_WORD_LENGTH_8_BITS:
68 default:
69 config.data_bits = 8U;
70 break;
71 }
72
73 switch (DL_UART_getParityMode(instance))
74 {
75 case DL_UART_PARITY_NONE:
77 break;
78 case DL_UART_PARITY_EVEN:
80 break;
81 case DL_UART_PARITY_ODD:
83 break;
84 default:
85 // LibXR UART config only supports none/even/odd parity.
86 ASSERT(false);
88 break;
89 }
90
91 config.stop_bits = (DL_UART_getStopBits(instance) == DL_UART_STOP_BITS_TWO) ? 2U : 1U;
92 return config;
93}
94
96{
97 if (config.baudrate == 0)
98 {
99 return ErrorCode::ARG_ERR;
100 }
101
102 if (config.data_bits < 5 || config.data_bits > 8)
103 {
104 return ErrorCode::ARG_ERR;
105 }
106
107 if (config.stop_bits != 1 && config.stop_bits != 2)
108 {
109 return ErrorCode::ARG_ERR;
110 }
111
112 DL_UART_WORD_LENGTH word_length = DL_UART_WORD_LENGTH_8_BITS;
113 switch (config.data_bits)
114 {
115 case 5:
116 word_length = DL_UART_WORD_LENGTH_5_BITS;
117 break;
118 case 6:
119 word_length = DL_UART_WORD_LENGTH_6_BITS;
120 break;
121 case 7:
122 word_length = DL_UART_WORD_LENGTH_7_BITS;
123 break;
124 case 8:
125 word_length = DL_UART_WORD_LENGTH_8_BITS;
126 break;
127 default:
128 return ErrorCode::ARG_ERR;
129 }
130
131 DL_UART_PARITY parity = DL_UART_PARITY_NONE;
132 switch (config.parity)
133 {
135 parity = DL_UART_PARITY_NONE;
136 break;
138 parity = DL_UART_PARITY_EVEN;
139 break;
141 parity = DL_UART_PARITY_ODD;
142 break;
143 default:
144 return ErrorCode::ARG_ERR;
145 }
146
147 const DL_UART_STOP_BITS STOP_BITS =
148 (config.stop_bits == 2) ? DL_UART_STOP_BITS_TWO : DL_UART_STOP_BITS_ONE;
149
150 DL_UART_changeConfig(res_.instance);
151
152 DL_UART_setWordLength(res_.instance, word_length);
153 DL_UART_setParityMode(res_.instance, parity);
154 DL_UART_setStopBits(res_.instance, STOP_BITS);
155
156 DL_UART_enableFIFOs(res_.instance);
157 DL_UART_setTXFIFOThreshold(res_.instance, DL_UART_TX_FIFO_LEVEL_ONE_ENTRY);
158
159 DL_UART_configBaudRate(res_.instance, res_.clock_freq, config.baudrate);
160
161 ApplyRxTimeoutMode();
162
163 DL_UART_clearInterruptStatus(res_.instance, 0xFFFFFFFF);
164 DL_UART_enableInterrupt(res_.instance, MSPM0_UART_BASE_INTERRUPT_MASK);
165 DL_UART_disableInterrupt(res_.instance,
166 DL_UART_INTERRUPT_TX | GetTimeoutInterruptMask());
167
168 tx_active_valid_ = false;
169 tx_active_remaining_ = 0;
170 tx_active_total_ = 0;
171
172 DL_UART_enable(res_.instance);
173
174 return ErrorCode::OK;
175}
176
177ErrorCode MSPM0UART::WriteFun(WritePort& port)
178{
179 auto* uart = CONTAINER_OF(&port, MSPM0UART, _write_port);
180 if (port.queue_info_->Size() == 0)
181 {
182 return ErrorCode::OK;
183 }
184
185 DL_UART_enableInterrupt(uart->res_.instance, DL_UART_INTERRUPT_TX);
186 uart->res_.instance->CPU_INT.ISET = DL_UART_INTERRUPT_TX;
187 return ErrorCode::OK;
188}
189
190ErrorCode MSPM0UART::ReadFun(ReadPort& port)
191{
192 auto* uart = CONTAINER_OF(&port, MSPM0UART, _read_port);
193 const uint32_t TIMEOUT_MASK = uart->GetTimeoutInterruptMask();
194 if (TIMEOUT_MASK != 0U)
195 {
196 // 仅在有挂起读请求时启用超时中断,避免空闲无效触发 / Enable timeout IRQ
197 // only when a read request is pending to avoid idle false triggers.
198 if (uart->rx_timeout_mode_ == RxTimeoutMode::LIN_COMPARE)
199 {
200 // 以本次 Read 请求开始作为超时计时起点 / Start timeout timing from this
201 // Read request boundary.
202 uart->ResetLinCounter();
203 }
204
205 DL_UART_clearInterruptStatus(uart->res_.instance, TIMEOUT_MASK);
206 DL_UART_enableInterrupt(uart->res_.instance, TIMEOUT_MASK);
207 }
208
209 return ErrorCode::EMPTY;
210}
211
212MSPM0UART::RxTimeoutMode MSPM0UART::ResolveRxTimeoutMode() const
213{
214 // 分发规则 / Dispatch rule:
215 // 1) [LIN路径 / LIN path] UART0 且存在 LIN compare 宏配置 -> LIN_COMPARE
216 // 2) [LIN路径 / LIN path] 运行时探测到 LIN counter+compare 已启用 -> LIN_COMPARE
217 // 3) [BYTE路径 / BYTE path] 其他情况 -> BYTE_INTERRUPT
218#if defined(UART_0_INST) && defined(UART_0_COUNTER_COMPARE_VALUE)
219 if (res_.instance == UART_0_INST)
220 {
221 // 本项目 UART0 在 SysConfig 中配置为 LIN 扩展实例 / UART0 is configured as a
222 // LIN extend instance by SysConfig in this project.
223 // [LIN路径 / LIN path] 固定走 LIN compare / Force LIN compare path.
224 return RxTimeoutMode::LIN_COMPARE;
225 }
226#endif
227
228 if (DL_UART_isLINCounterEnabled(res_.instance) &&
229 DL_UART_isLINCounterCompareMatchEnabled(res_.instance))
230 {
231 // [LIN路径 / LIN path] 非 UART0 按寄存器能力探测:若 LIN counter+compare
232 // 已启用则走 LIN /
233 // For non-UART0, use LIN path when LIN counter+compare are already enabled.
234 return RxTimeoutMode::LIN_COMPARE;
235 }
236
237 // [BYTE路径 / BYTE path] 不满足 LIN 条件时回落到按字节中断路径 /
238 // Fall back to byte-interrupt path when LIN conditions are not met.
239 return RxTimeoutMode::BYTE_INTERRUPT;
240}
241
242uint32_t MSPM0UART::GetTimeoutInterruptMask() const
243{
244 switch (rx_timeout_mode_)
245 {
246 // [LIN路径 / LIN path] 使用 LINC0 compare match 作为帧间超时事件 /
247 // Use LINC0 compare match as frame-gap timeout event.
248 case RxTimeoutMode::LIN_COMPARE:
249 return DL_UART_INTERRUPT_LINC0_MATCH;
250 // [BYTE路径 / BYTE path] 不使用硬件超时中断 /
251 // No hardware timeout interrupt in byte-interrupt mode.
252 case RxTimeoutMode::BYTE_INTERRUPT:
253 default:
254 return 0;
255 }
256}
257
258uint32_t MSPM0UART::GetTimeoutInterruptEnabledMask() const
259{
260 const uint32_t TIMEOUT_MASK = GetTimeoutInterruptMask();
261 if (TIMEOUT_MASK == 0U)
262 {
263 return 0U;
264 }
265 return DL_UART_getEnabledInterrupts(res_.instance, TIMEOUT_MASK);
266}
267
268uint32_t MSPM0UART::GetTimeoutInterruptMaskedStatus() const
269{
270 const uint32_t TIMEOUT_MASK = GetTimeoutInterruptMask();
271 if (TIMEOUT_MASK == 0U)
272 {
273 return 0U;
274 }
275 return DL_UART_getEnabledInterruptStatus(res_.instance, TIMEOUT_MASK);
276}
277
278uint32_t MSPM0UART::GetTimeoutInterruptRawStatus() const
279{
280 const uint32_t TIMEOUT_MASK = GetTimeoutInterruptMask();
281 if (TIMEOUT_MASK == 0U)
282 {
283 return 0U;
284 }
285 return DL_UART_getRawInterruptStatus(res_.instance, TIMEOUT_MASK);
286}
287
288uint32_t MSPM0UART::GetRxInterruptTimeoutValue() const
289{
290 return DL_UART_getRXInterruptTimeout(res_.instance);
291}
292
293uint32_t MSPM0UART::GetRxFifoThresholdValue() const
294{
295 return static_cast<uint32_t>(DL_UART_getRXFIFOThreshold(res_.instance));
296}
297
298void MSPM0UART::ResetLinCounter()
299{
300 if (rx_timeout_mode_ == RxTimeoutMode::LIN_COMPARE)
301 {
302 DL_UART_setLINCounterValue(res_.instance, 0);
303 }
304}
305
306void MSPM0UART::ApplyRxTimeoutMode()
307{
308 rx_timeout_mode_ = ResolveRxTimeoutMode();
309
310 // 基础 UART 配置对 LIN/BYTE 两条路径一致,先统一配置后再处理模式差异 /
311 // Apply shared UART settings first, then patch mode-specific differences.
312 DL_UART_setCommunicationMode(res_.instance, DL_UART_MODE_NORMAL);
313 DL_UART_setAddressMask(res_.instance, 0U);
314 DL_UART_setAddress(res_.instance, 0U);
315 DL_UART_setRXFIFOThreshold(res_.instance, DL_UART_RX_FIFO_LEVEL_ONE_ENTRY);
316 DL_UART_setRXInterruptTimeout(res_.instance, 0U);
317
318 switch (rx_timeout_mode_)
319 {
320 // [LIN路径 / LIN path] 使能 LIN counter/compare,超时事件来自 LINC0_MATCH。
321 // [LIN路径 / LIN path] Enable LIN counter/compare; timeout event is LINC0_MATCH.
322 case RxTimeoutMode::LIN_COMPARE:
323 if (!DL_UART_isLINCounterEnabled(res_.instance))
324 {
325 DL_UART_enableLINCounter(res_.instance);
326 }
327 if (!DL_UART_isLINCounterCompareMatchEnabled(res_.instance))
328 {
329 DL_UART_enableLINCounterCompareMatch(res_.instance);
330 }
331#if defined(UART_0_COUNTER_COMPARE_VALUE)
332 DL_UART_setLINCounterCompareValue(res_.instance, UART_0_COUNTER_COMPARE_VALUE);
333#endif
334 DL_UART_disableLINCountWhileLow(res_.instance);
335 ResetLinCounter();
336 break;
337
338 // [BYTE路径 / BYTE path] 仅保留按字节 RX 中断,不依赖超时中断。
339 // [BYTE路径 / BYTE path] Keep plain per-byte RX interrupt; no timeout IRQ.
340 case RxTimeoutMode::BYTE_INTERRUPT:
341 default:
342 break;
343 }
344}
345
346void MSPM0UART::OnInterrupt(uint8_t index)
347{
348 if (index >= MAX_UART_INSTANCES)
349 {
350 return;
351 }
352
353 auto* uart = instance_map_[index];
354 if (uart == nullptr)
355 {
356 return;
357 }
358
359 uart->HandleInterrupt();
360}
361
362void MSPM0UART::HandleInterrupt()
363{
364 const uint32_t TIMEOUT_MASK = GetTimeoutInterruptMask();
365 const uint32_t IRQ_MASK = MSPM0_UART_BASE_INTERRUPT_MASK | TIMEOUT_MASK;
366
367 uint32_t pending = DL_UART_getEnabledInterruptStatus(res_.instance, IRQ_MASK);
368 if (TIMEOUT_MASK != 0U)
369 {
370 // LIN compare 在部分路径需读取 RAW 位,避免漏掉超时事件 / For LIN
371 // compare, raw status is required on some paths to avoid missing timeout events.
372 pending |= DL_UART_getRawInterruptStatus(res_.instance, TIMEOUT_MASK);
373 }
374
375 const uint32_t PENDING = pending;
376 if (PENDING == 0U)
377 {
378 return;
379 }
380
381 constexpr uint32_t RX_PENDING_MASK =
382 DL_UART_INTERRUPT_RX | DL_UART_INTERRUPT_ADDRESS_MATCH;
383 if ((PENDING & RX_PENDING_MASK) != 0U)
384 {
385 HandleRxInterrupt(TIMEOUT_MASK);
386 if ((PENDING & DL_UART_INTERRUPT_ADDRESS_MATCH) != 0U)
387 {
388 DL_UART_clearInterruptStatus(res_.instance, DL_UART_INTERRUPT_ADDRESS_MATCH);
389 }
390 }
391
392 if (TIMEOUT_MASK != 0U)
393 {
394 HandleRxTimeoutInterrupt(PENDING, TIMEOUT_MASK);
395 }
396
397 if ((PENDING & DL_UART_INTERRUPT_OVERRUN_ERROR) != 0U)
398 {
399 HandleErrorInterrupt(DL_UART_IIDX_OVERRUN_ERROR);
400 }
401 if ((PENDING & DL_UART_INTERRUPT_BREAK_ERROR) != 0U)
402 {
403 HandleErrorInterrupt(DL_UART_IIDX_BREAK_ERROR);
404 }
405 if ((PENDING & DL_UART_INTERRUPT_PARITY_ERROR) != 0U)
406 {
407 HandleErrorInterrupt(DL_UART_IIDX_PARITY_ERROR);
408 }
409 if ((PENDING & DL_UART_INTERRUPT_FRAMING_ERROR) != 0U)
410 {
411 HandleErrorInterrupt(DL_UART_IIDX_FRAMING_ERROR);
412 }
413 if ((PENDING & DL_UART_INTERRUPT_NOISE_ERROR) != 0U)
414 {
415 HandleErrorInterrupt(DL_UART_IIDX_NOISE_ERROR);
416 }
417
418 if ((PENDING & DL_UART_INTERRUPT_TX) != 0U)
419 {
420 HandleTxInterrupt(true);
421 }
422}
423
424void MSPM0UART::HandleRxInterrupt(uint32_t timeout_mask)
425{
426 bool pushed = false;
427 bool received = false;
428
429 DrainRxFIFO(received, pushed);
430
431 if (received && rx_timeout_mode_ == RxTimeoutMode::LIN_COMPARE)
432 {
433 // [LIN路径 / LIN path] 连续接收时重置 LIN 计数器,避免帧内误超时 /
434 // Reset LIN counter on data reception to avoid in-frame timeout.
435 ResetLinCounter();
436 }
437
438 if (pushed)
439 {
441 }
442
443 if (timeout_mask != 0U &&
444 read_port_->busy_.load(std::memory_order_relaxed) != ReadPort::BusyState::PENDING)
445 {
446 // 无挂起读请求时关闭超时中断,减少无意义 IRQ / Disable timeout IRQ when no
447 // pending read remains.
448 DL_UART_disableInterrupt(res_.instance, timeout_mask);
449 DL_UART_clearInterruptStatus(res_.instance, timeout_mask);
450 }
451
452 DL_UART_clearInterruptStatus(res_.instance, DL_UART_INTERRUPT_RX);
453}
454
455void MSPM0UART::DrainRxFIFO(bool& received, bool& pushed)
456{
457 while (!DL_UART_isRXFIFOEmpty(res_.instance))
458 {
459 const uint8_t RX_BYTE = DL_UART_receiveData(res_.instance);
460 received = true;
461
462 if (read_port_->queue_data_->Push(RX_BYTE) == ErrorCode::OK)
463 {
464 pushed = true;
465 }
466 else
467 {
468 rx_drop_count_++;
469 }
470 }
471}
472
473void MSPM0UART::HandleRxTimeoutInterrupt(uint32_t pending, uint32_t timeout_mask)
474{
475 // [BYTE路径 / BYTE path] timeout_mask=0,直接返回;本函数实际只在 LIN 路径生效。
476 // In BYTE path timeout_mask is 0, so this function is effectively LIN-only.
477 if ((timeout_mask == 0U) || ((pending & timeout_mask) == 0U))
478 {
479 return;
480 }
481
482 rx_timeout_count_++;
483 DL_UART_clearInterruptStatus(res_.instance, pending & timeout_mask);
484
485 // FULL 阈值模式下短帧可能滞留在 HW FIFO,直到超时中断到来 / In
486 // FULL-threshold modes, short frames may remain in HW FIFO until timeout IRQ.
487 // 先拉取 FIFO,再按超时语义完成挂起读请求 / Drain FIFO first so timeout can
488 // complete pending reads with actual data.
489 bool pushed = false;
490 bool received = false;
491
492 DrainRxFIFO(received, pushed);
493
494 if (pushed)
495 {
497 }
498
499 const bool PENDING_READ =
500 (read_port_->busy_.load(std::memory_order_relaxed) == ReadPort::BusyState::PENDING);
501 if (!PENDING_READ)
502 {
503 // 超时到来时若无挂起读请求,仅清理硬件状态并退出 / If timeout arrives
504 // with no pending read, only clear HW state and exit.
505 DL_UART_disableInterrupt(res_.instance, timeout_mask);
506 return;
507 }
508
509 if (rx_timeout_mode_ == RxTimeoutMode::LIN_COMPARE)
510 {
511 ResetLinCounter();
512 }
513
514 CompletePendingReadOnTimeout(true);
515
516 if (read_port_->busy_.load(std::memory_order_relaxed) != ReadPort::BusyState::PENDING)
517 {
518 DL_UART_disableInterrupt(res_.instance, timeout_mask);
519 }
520}
521
522void MSPM0UART::CompletePendingReadOnTimeout(bool in_isr)
523{
524 if (read_port_->busy_.load(std::memory_order_relaxed) != ReadPort::BusyState::PENDING)
525 {
526 return;
527 }
528
529 const size_t AVAILABLE = read_port_->queue_data_->Size();
530 if (AVAILABLE == 0U)
531 {
532 return;
533 }
534
535 const size_t REQUESTED = read_port_->info_.data.size_;
536 const size_t POP_SIZE = (AVAILABLE < REQUESTED) ? AVAILABLE : REQUESTED;
537 if (POP_SIZE == 0U)
538 {
539 return;
540 }
541
542 const ErrorCode POP_ANS = read_port_->queue_data_->PopBatch(
543 reinterpret_cast<uint8_t*>(read_port_->info_.data.addr_), POP_SIZE);
544 if (POP_ANS != ErrorCode::OK)
545 {
546 return;
547 }
548
549 const ErrorCode STATUS =
550 // 超时允许短包完成:不足请求长度时返回 EMPTY 并带回已收字节数 / Timeout
551 // allows short-frame completion: return EMPTY with the received byte count.
552 (POP_SIZE == REQUESTED) ? ErrorCode::OK : ErrorCode::EMPTY;
553 read_port_->Finish(in_isr, STATUS, read_port_->info_, static_cast<uint32_t>(POP_SIZE));
554}
555
556void MSPM0UART::HandleTxInterrupt(bool in_isr)
557{
558 // 发送状态机:取写请求并尽量填满 TX FIFO,直到该请求完成 / TX state machine:
559 // fetch one write request and keep filling TX FIFO until it completes.
560 while (true)
561 {
562 if (!tx_active_valid_)
563 {
564 if (write_port_->queue_info_->Pop(tx_active_info_) != ErrorCode::OK)
565 {
566 DisableTxInterrupt();
567
568 if (write_port_->queue_info_->Size() > 0)
569 {
570 DL_UART_enableInterrupt(res_.instance, DL_UART_INTERRUPT_TX);
571 res_.instance->CPU_INT.ISET = DL_UART_INTERRUPT_TX;
572 }
573
574 return;
575 }
576
577 tx_active_total_ = tx_active_info_.data.size_;
578 tx_active_remaining_ = tx_active_total_;
579 tx_active_valid_ = true;
580 }
581
582 while (tx_active_remaining_ > 0 && !DL_UART_isTXFIFOFull(res_.instance))
583 {
584 uint8_t tx_byte = 0;
585 if (write_port_->queue_data_->Pop(tx_byte) != ErrorCode::OK)
586 {
587 write_port_->Finish(in_isr, ErrorCode::FAILED, tx_active_info_,
588 tx_active_total_ - tx_active_remaining_);
589 tx_active_valid_ = false;
590 tx_active_remaining_ = 0;
591 tx_active_total_ = 0;
592 DisableTxInterrupt();
593 return;
594 }
595
596 DL_UART_transmitData(res_.instance, tx_byte);
597 tx_active_remaining_--;
598 }
599
600 if (tx_active_remaining_ > 0)
601 {
602 return;
603 }
604
605 write_port_->Finish(in_isr, ErrorCode::OK, tx_active_info_, tx_active_total_);
606 tx_active_valid_ = false;
607 tx_active_remaining_ = 0;
608 tx_active_total_ = 0;
609 }
610}
611
612void MSPM0UART::HandleErrorInterrupt(DL_UART_IIDX iidx)
613{
614 uint32_t clear_mask = 0;
615
616 switch (iidx)
617 {
618 case DL_UART_IIDX_OVERRUN_ERROR:
619 clear_mask = DL_UART_INTERRUPT_OVERRUN_ERROR;
620 break;
621
622 case DL_UART_IIDX_BREAK_ERROR:
623 clear_mask = DL_UART_INTERRUPT_BREAK_ERROR;
624 break;
625
626 case DL_UART_IIDX_PARITY_ERROR:
627 clear_mask = DL_UART_INTERRUPT_PARITY_ERROR;
628 break;
629
630 case DL_UART_IIDX_FRAMING_ERROR:
631 clear_mask = DL_UART_INTERRUPT_FRAMING_ERROR;
632 break;
633
634 case DL_UART_IIDX_NOISE_ERROR:
635 clear_mask = DL_UART_INTERRUPT_NOISE_ERROR;
636 break;
637
638 default:
639 break;
640 }
641
642 if (clear_mask != 0)
643 {
644 DL_UART_clearInterruptStatus(res_.instance, clear_mask);
645 }
646}
647
648void MSPM0UART::DisableTxInterrupt()
649{
650 DL_UART_disableInterrupt(res_.instance, DL_UART_INTERRUPT_TX);
651 DL_UART_clearInterruptStatus(res_.instance, DL_UART_INTERRUPT_TX);
652 NVIC_ClearPendingIRQ(res_.irqn);
653}
654
655#if defined(UART0_BASE)
656extern "C" void UART0_IRQHandler(void) // NOLINT
657{
658 LibXR::MSPM0UART::OnInterrupt(0);
659}
660#endif
661
662#if defined(UART1_BASE)
663extern "C" void UART1_IRQHandler(void) // NOLINT
664{
665 LibXR::MSPM0UART::OnInterrupt(1);
666}
667#endif
668
669#if defined(UART2_BASE)
670extern "C" void UART2_IRQHandler(void) // NOLINT
671{
672 LibXR::MSPM0UART::OnInterrupt(2);
673}
674#endif
675
676#if defined(UART3_BASE)
677extern "C" void UART3_IRQHandler(void) // NOLINT
678{
679 LibXR::MSPM0UART::OnInterrupt(3);
680}
681#endif
682
683#if defined(UART4_BASE)
684extern "C" void UART4_IRQHandler(void) { LibXR::MSPM0UART::OnInterrupt(4); }
685#endif
686
687#if defined(UART5_BASE)
688extern "C" void UART5_IRQHandler(void) { LibXR::MSPM0UART::OnInterrupt(5); }
689#endif
690
691#if defined(UART6_BASE)
692extern "C" void UART6_IRQHandler(void) { LibXR::MSPM0UART::OnInterrupt(6); }
693#endif
694
695#if defined(UART7_BASE)
696extern "C" void UART7_IRQHandler(void) { LibXR::MSPM0UART::OnInterrupt(7); }
697#endif
size_t size_
数据大小(字节)。 The size of the data (in bytes).
ErrorCode Pop(ElementData &item)
从队列中弹出数据 / Pops data from the queue
ErrorCode Push(ElementData &&item)
向队列中推入数据 / Pushes data into the queue
size_t Size() const
获取当前队列中的元素数量 / Returns the number of elements currently in the queue
ErrorCode PopBatch(Data *data, size_t size)
批量弹出数据 / Pops multiple elements from the queue
ErrorCode SetConfig(UART::Configuration config) override
设置 UART 配置 / Sets the UART configuration
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
ReadPort class for handling read operations.
Definition libxr_rw.hpp:279
void Finish(bool in_isr, ErrorCode ans, ReadInfoBlock &info)
更新读取操作的状态。 Updates the status of the read operation.
Definition libxr_rw.cpp:38
void ProcessPendingReads(bool in_isr)
Processes pending reads.
Definition libxr_rw.cpp:193
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
Definition uart.hpp:19
ReadPort * read_port_
读取端口 / Read port
Definition uart.hpp:53
@ NO_PARITY
无校验 / No parity
@ ODD
奇校验 / Odd parity
@ EVEN
偶校验 / Even parity
WritePort * write_port_
写入端口 / Write port
Definition uart.hpp:54
WritePort class for handling write operations.
Definition libxr_rw.hpp:438
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
Definition libxr_rw.cpp:294
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read operations.
Definition libxr_rw.hpp:256
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
Definition libxr_rw.hpp:252
RawData data
Data buffer. 数据缓冲区。
Definition libxr_rw.hpp:264
UART 配置结构体 / UART configuration structure.
Definition uart.hpp:44
uint8_t stop_bits
停止位长度 / Number of stop bits
Definition uart.hpp:50
Parity parity
校验模式 / Parity mode
Definition uart.hpp:47
uint8_t data_bits
数据位长度 / Number of data bits
Definition uart.hpp:48
uint32_t baudrate
波特率 / Baud rate
Definition uart.hpp:45
ConstRawData data
Data buffer. 数据缓冲区。
Definition libxr_rw.hpp:270