libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::MSPM0I2C Class Reference
Inheritance diagram for LibXR::MSPM0I2C:
[legend]
Collaboration diagram for LibXR::MSPM0I2C:
[legend]

Data Structures

struct  Resources
 

Public Member Functions

 MSPM0I2C (Resources res, RawData stage_buffer, uint32_t dma_enable_min_size=8, I2C::Configuration config={100000})
 
ErrorCode Read (uint16_t slave_addr, RawData read_data, ReadOperation &op, bool in_isr=false) override
 读取 I2C 设备的数据。 Reads data from an I2C device.
 
ErrorCode Write (uint16_t slave_addr, ConstRawData write_data, WriteOperation &op, bool in_isr=false) override
 I2C 设备写入数据。 Writes data to an I2C device.
 
ErrorCode MemRead (uint16_t slave_addr, uint16_t mem_addr, RawData read_data, ReadOperation &op, MemAddrLength mem_addr_size=MemAddrLength::BYTE_8, bool in_isr=false) override
 I2C 设备指定寄存器读取数据。 Reads data from a specific register of an I2C device.
 
ErrorCode MemWrite (uint16_t slave_addr, uint16_t mem_addr, ConstRawData write_data, WriteOperation &op, MemAddrLength mem_addr_size=MemAddrLength::BYTE_8, bool in_isr=false) override
 I2C 设备指定寄存器写入数据。 Writes data to a specific register of an I2C device.
 
ErrorCode SetConfig (Configuration config) override
 配置 I2C 设备参数。 Configures the I2C device settings.
 
- Public Member Functions inherited from LibXR::I2C
 I2C ()
 默认构造函数。 Default constructor.
 

Static Public Member Functions

static constexpr uint8_t ResolveIndex (IRQn_Type irqn)
 

Private Member Functions

ErrorCode WaitControllerIdle () const
 
ErrorCode WaitTransactionDone () const
 
ErrorCode WaitBusIdle () const
 
ErrorCode CheckControllerError () const
 
ErrorCode PollingWrite7 (uint16_t addr7, const uint8_t *data, size_t size)
 
ErrorCode PollingRead7 (uint16_t addr7, uint8_t *data, size_t size)
 
ErrorCode DmaWrite7 (uint16_t addr7, ConstRawData write_data)
 
ErrorCode DmaRead7 (uint16_t addr7, RawData read_data)
 
ErrorCode WaitDmaTransferDone (uint8_t channel_id) const
 

Private Attributes

Resources res_
 
RawData stage_buffer_
 
uint32_t dma_enable_min_size_
 
bool dma_enabled_ = false
 

Static Private Attributes

static constexpr uint8_t MAX_I2C_INSTANCES = 4
 
static constexpr uint8_t INVALID_INSTANCE_INDEX = 0xFF
 

Additional Inherited Members

- Public Types inherited from LibXR::I2C
enum class  MemAddrLength : uint8_t { BYTE_8 , BYTE_16 }
 

Detailed Description

Definition at line 10 of file mspm0_i2c.hpp.

Constructor & Destructor Documentation

◆ MSPM0I2C()

MSPM0I2C::MSPM0I2C ( Resources res,
RawData stage_buffer,
uint32_t dma_enable_min_size = 8,
I2C::Configuration config = {100000} )

Definition at line 107 of file mspm0_i2c.cpp.

109 : I2C(),
110 res_(res),
111 stage_buffer_(stage_buffer),
112 dma_enable_min_size_(dma_enable_min_size)
113{
114 ASSERT(res_.instance != nullptr);
115 ASSERT(res_.clock_freq > 0);
116 ASSERT(res_.index < MAX_I2C_INSTANCES);
117 ASSERT(stage_buffer_.addr_ != nullptr);
118 ASSERT(stage_buffer_.size_ > 0);
119
120 if (config.clock_speed == 0)
121 {
122 config.clock_speed = res_.default_bus_speed_hz;
123 }
124 const ErrorCode SET_CFG_ANS = SetConfig(config);
125 ASSERT(SET_CFG_ANS == ErrorCode::OK);
126}
I2C()
默认构造函数。 Default constructor.
Definition i2c.hpp:39
ErrorCode SetConfig(Configuration config) override
配置 I2C 设备参数。 Configures the I2C device settings.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
ErrorCode
定义错误码枚举
Definition libxr_def.hpp:64
@ OK
操作成功 | Operation successful
uint32_t clock_speed
I2C 通信时钟速率(单位:Hz)。 The I2C clock speed (in Hz).
Definition i2c.hpp:26

Member Function Documentation

◆ CheckControllerError()

ErrorCode MSPM0I2C::CheckControllerError ( ) const
private

Definition at line 128 of file mspm0_i2c.cpp.

129{
130 const uint32_t STATUS = DL_I2C_getControllerStatus(res_.instance);
131 if ((STATUS & DL_I2C_CONTROLLER_STATUS_ERROR) != 0 ||
132 (STATUS & DL_I2C_CONTROLLER_STATUS_ARBITRATION_LOST) != 0)
133 {
134 return ErrorCode::FAILED;
135 }
136 return ErrorCode::OK;
137}
@ FAILED
操作失败 | Operation failed

◆ DmaRead7()

ErrorCode MSPM0I2C::DmaRead7 ( uint16_t addr7,
RawData read_data )
private

Definition at line 504 of file mspm0_i2c.cpp.

505{
506 if (read_data.size_ == 0)
507 {
508 return ErrorCode::OK;
509 }
510 if (read_data.size_ > MSPM0_I2C_MAX_TRANSFER_SIZE)
511 {
512 return ErrorCode::ARG_ERR;
513 }
514
515 auto stop_dma = [&]()
516 {
517 const uint32_t DMA_RX_MASK = mspm0_i2c_dma_channel_mask(DMA_CH_RX_CHAN_ID);
518 DL_DMA_disableChannel(DMA, DMA_CH_RX_CHAN_ID);
519 DL_DMA_clearInterruptStatus(DMA, DMA_RX_MASK);
520 };
521
522 auto attempt_once = [&]() -> ErrorCode
523 {
524 ErrorCode ans = WaitControllerIdle();
525 if (ans != ErrorCode::OK)
526 {
527 return ans;
528 }
529
530 DL_I2C_disableInterrupt(res_.instance, 0xFFFFFFFFU);
531 DL_I2C_clearInterruptStatus(res_.instance, 0xFFFFFFFFU);
532
533 const uint32_t DMA_RX_MASK = mspm0_i2c_dma_channel_mask(DMA_CH_RX_CHAN_ID);
534 DL_DMA_disableChannel(DMA, DMA_CH_RX_CHAN_ID);
535 DL_DMA_clearInterruptStatus(DMA, DMA_RX_MASK);
536 DL_DMA_setSrcAddr(DMA, DMA_CH_RX_CHAN_ID,
537 static_cast<uint32_t>(
538 reinterpret_cast<uintptr_t>(&res_.instance->MASTER.MRXDATA)));
539 DL_DMA_setDestAddr(
540 DMA, DMA_CH_RX_CHAN_ID,
541 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(read_data.addr_)));
542 DL_DMA_setTransferSize(DMA, DMA_CH_RX_CHAN_ID,
543 static_cast<uint16_t>(read_data.size_));
544 DL_DMA_enableChannel(DMA, DMA_CH_RX_CHAN_ID);
545
546 DL_I2C_startControllerTransfer(res_.instance, addr7, DL_I2C_CONTROLLER_DIRECTION_RX,
547 static_cast<uint16_t>(read_data.size_));
548
549 ans = WaitDmaTransferDone(DMA_CH_RX_CHAN_ID);
550 if (ans != ErrorCode::OK)
551 {
552 stop_dma();
553 return ans;
554 }
555
556 ans = WaitTransactionDone();
557 if (ans != ErrorCode::OK)
558 {
559 stop_dma();
560 return ans;
561 }
562
563 ans = WaitBusIdle();
564 if (ans != ErrorCode::OK)
565 {
566 stop_dma();
567 return ans;
568 }
569
570 stop_dma();
571 return CheckControllerError();
572 };
573
574 ErrorCode last_error = ErrorCode::FAILED;
575 for (uint32_t attempt = 0; attempt < MSPM0_I2C_POLLING_ATTEMPTS; ++attempt)
576 {
577 last_error = attempt_once();
578 if (last_error == ErrorCode::OK)
579 {
580 return ErrorCode::OK;
581 }
582 mspm0_i2c_recover_controller(res_.instance);
583 }
584
585 return last_error;
586}
@ ARG_ERR
参数错误 | Argument error

◆ DmaWrite7()

ErrorCode MSPM0I2C::DmaWrite7 ( uint16_t addr7,
ConstRawData write_data )
private

Definition at line 420 of file mspm0_i2c.cpp.

421{
422 if (write_data.size_ == 0)
423 {
424 return ErrorCode::OK;
425 }
426 if (write_data.size_ > MSPM0_I2C_MAX_TRANSFER_SIZE)
427 {
428 return ErrorCode::ARG_ERR;
429 }
430
431 auto stop_dma = [&]()
432 {
433 const uint32_t DMA_TX_MASK = mspm0_i2c_dma_channel_mask(DMA_CH_TX_CHAN_ID);
434 DL_DMA_disableChannel(DMA, DMA_CH_TX_CHAN_ID);
435 DL_DMA_clearInterruptStatus(DMA, DMA_TX_MASK);
436 };
437
438 auto attempt_once = [&]() -> ErrorCode
439 {
440 ErrorCode ans = WaitControllerIdle();
441 if (ans != ErrorCode::OK)
442 {
443 return ans;
444 }
445
446 DL_I2C_disableInterrupt(res_.instance, 0xFFFFFFFFU);
447 DL_I2C_clearInterruptStatus(res_.instance, 0xFFFFFFFFU);
448
449 const uint32_t DMA_TX_MASK = mspm0_i2c_dma_channel_mask(DMA_CH_TX_CHAN_ID);
450 DL_DMA_disableChannel(DMA, DMA_CH_TX_CHAN_ID);
451 DL_DMA_clearInterruptStatus(DMA, DMA_TX_MASK);
452 DL_DMA_setSrcAddr(
453 DMA, DMA_CH_TX_CHAN_ID,
454 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(write_data.addr_)));
455 DL_DMA_setDestAddr(DMA, DMA_CH_TX_CHAN_ID,
456 static_cast<uint32_t>(
457 reinterpret_cast<uintptr_t>(&res_.instance->MASTER.MTXDATA)));
458 DL_DMA_setTransferSize(DMA, DMA_CH_TX_CHAN_ID,
459 static_cast<uint16_t>(write_data.size_));
460 DL_DMA_enableChannel(DMA, DMA_CH_TX_CHAN_ID);
461
462 DL_I2C_startControllerTransfer(res_.instance, addr7, DL_I2C_CONTROLLER_DIRECTION_TX,
463 static_cast<uint16_t>(write_data.size_));
464
465 ans = WaitDmaTransferDone(DMA_CH_TX_CHAN_ID);
466 if (ans != ErrorCode::OK)
467 {
468 stop_dma();
469 return ans;
470 }
471
472 ans = WaitTransactionDone();
473 if (ans != ErrorCode::OK)
474 {
475 stop_dma();
476 return ans;
477 }
478
479 ans = WaitBusIdle();
480 if (ans != ErrorCode::OK)
481 {
482 stop_dma();
483 return ans;
484 }
485
486 stop_dma();
487 return CheckControllerError();
488 };
489
490 ErrorCode last_error = ErrorCode::FAILED;
491 for (uint32_t attempt = 0; attempt < MSPM0_I2C_POLLING_ATTEMPTS; ++attempt)
492 {
493 last_error = attempt_once();
494 if (last_error == ErrorCode::OK)
495 {
496 return ErrorCode::OK;
497 }
498 mspm0_i2c_recover_controller(res_.instance);
499 }
500
501 return last_error;
502}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).

◆ MemRead()

ErrorCode MSPM0I2C::MemRead ( uint16_t slave_addr,
uint16_t mem_addr,
RawData read_data,
ReadOperation & op,
MemAddrLength mem_addr_size = MemAddrLength::BYTE_8,
bool in_isr = false )
overridevirtual

I2C 设备指定寄存器读取数据。 Reads data from a specific register of an I2C device.

该函数从指定 I2C 从设备的寄存器地址读取数据,并存储到 read_data 中。 This function reads data from the specified register of the I2C slave and stores it in read_data.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
mem_addr寄存器地址(通常为 8 位或 16 位)。 Register address (typically 8-bit or 16-bit).
read_data用于存储读取数据的 RawData 对象。 RawData object to store read data.
op异步或同步的读取操作对象。 Read operation object (sync or async).
mem_addr_size寄存器地址长度。 Size of register address in bytes.
in_isr是否在中断中进行操作。Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,表示是否读取成功。 Returns ErrorCode indicating success or failure.

Implements LibXR::I2C.

Definition at line 682 of file mspm0_i2c.cpp.

684{
685 if (read_data.size_ > MSPM0_I2C_MAX_TRANSFER_SIZE)
686 {
687 return ErrorCode::ARG_ERR;
688 }
689 if (read_data.size_ == 0)
690 {
691 if (op.type != ReadOperation::OperationType::BLOCK)
692 {
693 op.UpdateStatus(in_isr, ErrorCode::OK);
694 }
695 return ErrorCode::OK;
696 }
697
698 const uint16_t ADDR7 = mspm0_i2c_to_addr7(slave_addr);
699 const size_t ADDR_SIZE = (mem_addr_size == MemAddrLength::BYTE_8) ? 1 : 2;
700 auto* addr_bytes = static_cast<uint8_t*>(stage_buffer_.addr_);
701 if (stage_buffer_.size_ < ADDR_SIZE)
702 {
703 return ErrorCode::ARG_ERR;
704 }
705
706 if (ADDR_SIZE == 1)
707 {
708 addr_bytes[0] = static_cast<uint8_t>(mem_addr & 0xFF);
709 }
710 else
711 {
712 addr_bytes[0] = static_cast<uint8_t>((mem_addr >> 8) & 0xFF);
713 addr_bytes[1] = static_cast<uint8_t>(mem_addr & 0xFF);
714 }
715
716 auto finalize = [&](ErrorCode code)
717 {
718 if (op.type != ReadOperation::OperationType::BLOCK)
719 {
720 op.UpdateStatus(in_isr, code);
721 }
722 return code;
723 };
724
725 auto try_repeated_start = [&]() -> ErrorCode
726 {
727 ErrorCode ans = WaitControllerIdle();
728 if (ans != ErrorCode::OK)
729 {
730 return ans;
731 }
732
733 DL_I2C_clearInterruptStatus(res_.instance, 0xFFFFFFFFU);
734
735 const uint16_t ADDR_SENT = DL_I2C_fillControllerTXFIFO(
736 res_.instance, addr_bytes, static_cast<uint16_t>(ADDR_SIZE));
737 if (ADDR_SENT != ADDR_SIZE)
738 {
739 return ErrorCode::FAILED;
740 }
741
742 DL_I2C_startControllerTransferAdvanced(
743 res_.instance, ADDR7, DL_I2C_CONTROLLER_DIRECTION_TX,
744 static_cast<uint16_t>(ADDR_SIZE), DL_I2C_CONTROLLER_START_ENABLE,
745 DL_I2C_CONTROLLER_STOP_DISABLE, DL_I2C_CONTROLLER_ACK_ENABLE);
746
747 uint32_t tx_done_timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
748 while (DL_I2C_getRawInterruptStatus(res_.instance,
749 DL_I2C_INTERRUPT_CONTROLLER_TX_DONE) == 0U)
750 {
751 if (CheckControllerError() != ErrorCode::OK)
752 {
753 return ErrorCode::FAILED;
754 }
755 if (tx_done_timeout-- == 0U)
756 {
757 return ErrorCode::BUSY;
758 }
759 }
760 DL_I2C_clearInterruptStatus(res_.instance, DL_I2C_INTERRUPT_CONTROLLER_TX_DONE);
761
762 if (CheckControllerError() != ErrorCode::OK)
763 {
764 return ErrorCode::FAILED;
765 }
766
767 DL_I2C_startControllerTransferAdvanced(
768 res_.instance, ADDR7, DL_I2C_CONTROLLER_DIRECTION_RX,
769 static_cast<uint16_t>(read_data.size_), DL_I2C_CONTROLLER_START_ENABLE,
770 DL_I2C_CONTROLLER_STOP_ENABLE, DL_I2C_CONTROLLER_ACK_DISABLE);
771
772 size_t received = 0;
773 auto* read_ptr = static_cast<uint8_t*>(read_data.addr_);
774 while (received < read_data.size_)
775 {
776 uint32_t timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
777 while (DL_I2C_isControllerRXFIFOEmpty(res_.instance))
778 {
779 if (CheckControllerError() != ErrorCode::OK)
780 {
781 return ErrorCode::FAILED;
782 }
783 if (timeout-- == 0)
784 {
785 return ErrorCode::BUSY;
786 }
787 }
788
789 while (!DL_I2C_isControllerRXFIFOEmpty(res_.instance) && received < read_data.size_)
790 {
791 read_ptr[received++] = DL_I2C_receiveControllerData(res_.instance);
792 }
793 }
794
795 uint32_t rx_done_timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
796 while (DL_I2C_getRawInterruptStatus(res_.instance,
797 DL_I2C_INTERRUPT_CONTROLLER_RX_DONE) == 0U)
798 {
799 if (CheckControllerError() != ErrorCode::OK)
800 {
801 return ErrorCode::FAILED;
802 }
803 if (rx_done_timeout-- == 0U)
804 {
805 return ErrorCode::BUSY;
806 }
807 }
808 DL_I2C_clearInterruptStatus(res_.instance, DL_I2C_INTERRUPT_CONTROLLER_RX_DONE);
809
810 ans = WaitBusIdle();
811 if (ans != ErrorCode::OK)
812 {
813 return ans;
814 }
815
816 return CheckControllerError();
817 };
818
819 ErrorCode last_error = ErrorCode::FAILED;
820 for (uint32_t attempt = 0; attempt < MSPM0_I2C_MEMREAD_RS_ATTEMPTS; ++attempt)
821 {
822 last_error = try_repeated_start();
823 if (last_error == ErrorCode::OK)
824 {
825 return finalize(ErrorCode::OK);
826 }
827 mspm0_i2c_recover_controller(res_.instance);
828 }
829
830 for (uint32_t attempt = 0; attempt < MSPM0_I2C_MEMREAD_FALLBACK_ATTEMPTS; ++attempt)
831 {
832 last_error = PollingWrite7(ADDR7, addr_bytes, ADDR_SIZE);
833 if (last_error == ErrorCode::OK)
834 {
835 last_error =
836 PollingRead7(ADDR7, static_cast<uint8_t*>(read_data.addr_), read_data.size_);
837 if (last_error == ErrorCode::OK)
838 {
839 return finalize(ErrorCode::OK);
840 }
841 }
842 mspm0_i2c_recover_controller(res_.instance);
843 }
844
845 return finalize(last_error);
846}
void UpdateStatus(bool in_isr, Status &&status)
Updates operation status based on type.
Definition libxr_rw.hpp:178
OperationType type
Definition libxr_rw.hpp:237
@ BUSY
忙碌 | Busy

◆ MemWrite()

ErrorCode MSPM0I2C::MemWrite ( uint16_t slave_addr,
uint16_t mem_addr,
ConstRawData write_data,
WriteOperation & op,
MemAddrLength mem_addr_size = MemAddrLength::BYTE_8,
bool in_isr = false )
overridevirtual

I2C 设备指定寄存器写入数据。 Writes data to a specific register of an I2C device.

该函数将 write_data 写入指定 I2C 从设备的寄存器地址。 This function writes write_data to the specified register of the I2C slave.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
mem_addr寄存器地址(通常为 8 位或 16 位)。 Register address (typically 8-bit or 16-bit).
write_data要写入的数据,ConstRawData 类型。 Data to be written, of type ConstRawData.
op异步或同步的写入操作对象。 Write operation object (sync or async).
mem_addr_size寄存器地址长度。 Size of register address in bytes.
in_isr是否在中断中进行操作。Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,表示是否写入成功。 Returns ErrorCode indicating success or failure.

Implements LibXR::I2C.

Definition at line 649 of file mspm0_i2c.cpp.

652{
653 const size_t ADDR_SIZE = (mem_addr_size == MemAddrLength::BYTE_8) ? 1 : 2;
654 const size_t TOTAL_SIZE = ADDR_SIZE + write_data.size_;
655 if (TOTAL_SIZE > MSPM0_I2C_MAX_TRANSFER_SIZE)
656 {
657 return ErrorCode::ARG_ERR;
658 }
659 if (TOTAL_SIZE > stage_buffer_.size_)
660 {
661 return ErrorCode::ARG_ERR;
662 }
663
664 auto* tx = static_cast<uint8_t*>(stage_buffer_.addr_);
665 if (ADDR_SIZE == 1)
666 {
667 tx[0] = static_cast<uint8_t>(mem_addr & 0xFF);
668 }
669 else
670 {
671 tx[0] = static_cast<uint8_t>((mem_addr >> 8) & 0xFF);
672 tx[1] = static_cast<uint8_t>(mem_addr & 0xFF);
673 }
674 if (write_data.size_ > 0)
675 {
676 memcpy(tx + ADDR_SIZE, write_data.addr_, write_data.size_);
677 }
678
679 return Write(slave_addr, ConstRawData(tx, TOTAL_SIZE), op, in_isr);
680}
常量原始数据封装类。 A class for encapsulating constant raw data.
ErrorCode Write(uint16_t slave_addr, ConstRawData write_data, WriteOperation &op, bool in_isr=false) override
向 I2C 设备写入数据。 Writes data to an I2C device.

◆ PollingRead7()

ErrorCode MSPM0I2C::PollingRead7 ( uint16_t addr7,
uint8_t * data,
size_t size )
private

Definition at line 335 of file mspm0_i2c.cpp.

336{
337 if (size == 0)
338 {
339 return ErrorCode::OK;
340 }
341 if (size > MSPM0_I2C_MAX_TRANSFER_SIZE)
342 {
343 return ErrorCode::ARG_ERR;
344 }
345
346 auto attempt_once = [&]() -> ErrorCode
347 {
348 ErrorCode ans = WaitControllerIdle();
349 if (ans != ErrorCode::OK)
350 {
351 return ans;
352 }
353
354 DL_I2C_clearInterruptStatus(res_.instance, 0xFFFFFFFFU);
355 DL_I2C_startControllerTransfer(res_.instance, addr7, DL_I2C_CONTROLLER_DIRECTION_RX,
356 static_cast<uint16_t>(size));
357
358 size_t received = 0;
359 while (received < size)
360 {
361 uint32_t timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
362 while (DL_I2C_isControllerRXFIFOEmpty(res_.instance))
363 {
364 if (CheckControllerError() != ErrorCode::OK)
365 {
366 return ErrorCode::FAILED;
367 }
368 if (timeout-- == 0)
369 {
370 return ErrorCode::BUSY;
371 }
372 }
373
374 while (!DL_I2C_isControllerRXFIFOEmpty(res_.instance) && received < size)
375 {
376 data[received++] = DL_I2C_receiveControllerData(res_.instance);
377 }
378 }
379
380 ans = WaitBusIdle();
381 if (ans != ErrorCode::OK)
382 {
383 return ans;
384 }
385
386 return CheckControllerError();
387 };
388
389 ErrorCode last_error = ErrorCode::FAILED;
390 for (uint32_t attempt = 0; attempt < MSPM0_I2C_POLLING_ATTEMPTS; ++attempt)
391 {
392 last_error = attempt_once();
393 if (last_error == ErrorCode::OK)
394 {
395 return ErrorCode::OK;
396 }
397 mspm0_i2c_recover_controller(res_.instance);
398 }
399
400 return last_error;
401}

◆ PollingWrite7()

ErrorCode MSPM0I2C::PollingWrite7 ( uint16_t addr7,
const uint8_t * data,
size_t size )
private

Definition at line 266 of file mspm0_i2c.cpp.

267{
268 if (size == 0)
269 {
270 return ErrorCode::OK;
271 }
272 if (size > MSPM0_I2C_MAX_TRANSFER_SIZE)
273 {
274 return ErrorCode::ARG_ERR;
275 }
276
277 auto attempt_once = [&]() -> ErrorCode
278 {
279 ErrorCode ans = WaitControllerIdle();
280 if (ans != ErrorCode::OK)
281 {
282 return ans;
283 }
284
285 DL_I2C_clearInterruptStatus(res_.instance, 0xFFFFFFFFU);
286
287 size_t sent =
288 DL_I2C_fillControllerTXFIFO(res_.instance, data, static_cast<uint16_t>(size));
289 DL_I2C_startControllerTransfer(res_.instance, addr7, DL_I2C_CONTROLLER_DIRECTION_TX,
290 static_cast<uint16_t>(size));
291
292 while (sent < size)
293 {
294 uint32_t timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
295 while (DL_I2C_getRawInterruptStatus(
296 res_.instance, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER) == 0U)
297 {
298 if (CheckControllerError() != ErrorCode::OK)
299 {
300 return ErrorCode::FAILED;
301 }
302 if (timeout-- == 0)
303 {
304 return ErrorCode::BUSY;
305 }
306 }
307
308 sent += DL_I2C_fillControllerTXFIFO(res_.instance, data + sent,
309 static_cast<uint16_t>(size - sent));
310 }
311
312 ans = WaitBusIdle();
313 if (ans != ErrorCode::OK)
314 {
315 return ans;
316 }
317
318 return CheckControllerError();
319 };
320
321 ErrorCode last_error = ErrorCode::FAILED;
322 for (uint32_t attempt = 0; attempt < MSPM0_I2C_POLLING_ATTEMPTS; ++attempt)
323 {
324 last_error = attempt_once();
325 if (last_error == ErrorCode::OK)
326 {
327 return ErrorCode::OK;
328 }
329 mspm0_i2c_recover_controller(res_.instance);
330 }
331
332 return last_error;
333}

◆ Read()

ErrorCode MSPM0I2C::Read ( uint16_t slave_addr,
RawData read_data,
ReadOperation & op,
bool in_isr = false )
overridevirtual

读取 I2C 设备的数据。 Reads data from an I2C device.

该函数从指定的 I2C 从设备地址读取数据,并存储到 read_data 中。 This function reads data from the specified I2C slave address and stores it in read_data.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
read_data存储读取数据的 RawData 对象。 A RawData object to store the read data.
op读取操作对象,包含同步或异步操作模式。 Read operation object containing synchronous or asynchronous operation mode.
in_isr是否在中断中进行操作。Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,指示操作是否成功。 Returns an ErrorCode indicating whether the operation was successful.

Implements LibXR::I2C.

Definition at line 588 of file mspm0_i2c.cpp.

590{
591 if (read_data.size_ == 0)
592 {
593 if (op.type != ReadOperation::OperationType::BLOCK)
594 {
595 op.UpdateStatus(in_isr, ErrorCode::OK);
596 }
597 return ErrorCode::OK;
598 }
599
600 const uint16_t ADDR7 = mspm0_i2c_to_addr7(slave_addr);
602 if (dma_enabled_ && read_data.size_ > dma_enable_min_size_)
603 {
604 ans = DmaRead7(ADDR7, read_data);
605 }
606 else
607 {
608 ans = PollingRead7(ADDR7, static_cast<uint8_t*>(read_data.addr_), read_data.size_);
609 }
610
611 if (op.type != ReadOperation::OperationType::BLOCK)
612 {
613 op.UpdateStatus(in_isr, ans);
614 }
615 return ans;
616}
@ NOT_SUPPORT
不支持 | Not supported

◆ ResolveIndex()

static constexpr uint8_t LibXR::MSPM0I2C::ResolveIndex ( IRQn_Type irqn)
inlinestaticconstexpr

Definition at line 43 of file mspm0_i2c.hpp.

44 {
45 switch (irqn)
46 {
47#if defined(I2C0_BASE)
48 case I2C0_INT_IRQn:
49 return 0;
50#endif
51#if defined(I2C1_BASE)
52 case I2C1_INT_IRQn:
53 return 1;
54#endif
55#if defined(I2C2_BASE)
56 case I2C2_INT_IRQn:
57 return 2;
58#endif
59#if defined(I2C3_BASE)
60 case I2C3_INT_IRQn:
61 return 3;
62#endif
63 default:
64 return INVALID_INSTANCE_INDEX;
65 }
66 }

◆ SetConfig()

ErrorCode MSPM0I2C::SetConfig ( Configuration config)
overridevirtual

配置 I2C 设备参数。 Configures the I2C device settings.

该函数用于设置 I2C 设备的参数,例如通信速率等。 This function sets the parameters of the I2C device, such as the communication speed.

Parameters
config包含 I2C 设置信息的 Configuration 结构体。 A Configuration structure containing I2C settings.
Returns
返回 ErrorCode,指示配置是否成功。 Returns an ErrorCode indicating whether the configuration was successful.

Implements LibXR::I2C.

Definition at line 191 of file mspm0_i2c.cpp.

192{
193 if (config.clock_speed == 0)
194 {
195 return ErrorCode::ARG_ERR;
196 }
197
198 const uint32_t PERIOD_DEN = config.clock_speed * 10U;
199 if (PERIOD_DEN == 0)
200 {
201 return ErrorCode::ARG_ERR;
202 }
203
204 uint32_t period_factor = res_.clock_freq / PERIOD_DEN;
205 if (period_factor == 0)
206 {
208 }
209 if (period_factor > 128U)
210 {
212 }
213
214 const uint8_t TIMER_PERIOD = static_cast<uint8_t>(period_factor - 1U);
215 const DL_I2C_ClockConfig CLOCK_CONFIG = {
216 .clockSel = DL_I2C_CLOCK_BUSCLK,
217 .divideRatio = DL_I2C_CLOCK_DIVIDE_1,
218 };
219
220 uint8_t dma_tx_trigger = 0U;
221 uint8_t dma_rx_trigger = 0U;
222 const bool USE_DMA =
223 mspm0_i2c_resolve_dma_triggers(res_.instance, dma_tx_trigger, dma_rx_trigger);
224 dma_enabled_ = USE_DMA;
225
226 DL_I2C_disableController(res_.instance);
227 DL_I2C_setClockConfig(res_.instance, &CLOCK_CONFIG);
228 DL_I2C_resetControllerTransfer(res_.instance);
229 DL_I2C_setTimerPeriod(res_.instance, TIMER_PERIOD);
230 DL_I2C_setControllerTXFIFOThreshold(
231 res_.instance, USE_DMA ? DL_I2C_TX_FIFO_LEVEL_EMPTY : DL_I2C_TX_FIFO_LEVEL_BYTES_1);
232 DL_I2C_setControllerRXFIFOThreshold(res_.instance, DL_I2C_RX_FIFO_LEVEL_BYTES_1);
233 DL_I2C_enableControllerClockStretching(res_.instance);
234 DL_I2C_disableInterrupt(res_.instance, 0xFFFFFFFFU);
235 DL_I2C_clearInterruptStatus(res_.instance, 0xFFFFFFFFU);
236
237 DL_I2C_disableDMAEvent(res_.instance, DL_I2C_EVENT_ROUTE_1,
238 DL_I2C_DMA_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
239 DL_I2C_disableDMAEvent(res_.instance, DL_I2C_EVENT_ROUTE_2,
240 DL_I2C_DMA_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
241 DL_DMA_disableChannel(DMA, DMA_CH_TX_CHAN_ID);
242 DL_DMA_disableChannel(DMA, DMA_CH_RX_CHAN_ID);
243 DL_DMA_clearInterruptStatus(DMA, mspm0_i2c_dma_channel_mask(DMA_CH_TX_CHAN_ID) |
244 mspm0_i2c_dma_channel_mask(DMA_CH_RX_CHAN_ID));
245
246 if (USE_DMA)
247 {
248 DL_DMA_Config dma_tx_config = MSPM0_I2C_DMA_TX_CONFIG_BASE;
249 DL_DMA_Config dma_rx_config = MSPM0_I2C_DMA_RX_CONFIG_BASE;
250 dma_tx_config.trigger = dma_tx_trigger;
251 dma_rx_config.trigger = dma_rx_trigger;
252
253 DL_I2C_enableDMAEvent(res_.instance, DL_I2C_EVENT_ROUTE_1,
254 DL_I2C_DMA_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
255 DL_I2C_enableDMAEvent(res_.instance, DL_I2C_EVENT_ROUTE_2,
256 DL_I2C_DMA_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
257 DL_DMA_initChannel(DMA, DMA_CH_TX_CHAN_ID, &dma_tx_config);
258 DL_DMA_initChannel(DMA, DMA_CH_RX_CHAN_ID, &dma_rx_config);
259 }
260
261 DL_I2C_enableController(res_.instance);
262
263 return ErrorCode::OK;
264}

◆ WaitBusIdle()

ErrorCode MSPM0I2C::WaitBusIdle ( ) const
private

Definition at line 173 of file mspm0_i2c.cpp.

174{
175 uint32_t timeout = MSPM0_I2C_WAIT_BUS_TIMEOUT;
176 while (timeout-- > 0)
177 {
178 if ((DL_I2C_getControllerStatus(res_.instance) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) ==
179 0)
180 {
181 return ErrorCode::OK;
182 }
183 if (CheckControllerError() != ErrorCode::OK)
184 {
185 return ErrorCode::FAILED;
186 }
187 }
188 return ErrorCode::BUSY;
189}

◆ WaitControllerIdle()

ErrorCode MSPM0I2C::WaitControllerIdle ( ) const
private

Definition at line 139 of file mspm0_i2c.cpp.

140{
141 uint32_t timeout = MSPM0_I2C_WAIT_IDLE_TIMEOUT;
142 while (timeout-- > 0)
143 {
144 if ((DL_I2C_getControllerStatus(res_.instance) & DL_I2C_CONTROLLER_STATUS_IDLE) != 0)
145 {
146 return ErrorCode::OK;
147 }
148 if (CheckControllerError() != ErrorCode::OK)
149 {
150 return ErrorCode::FAILED;
151 }
152 }
153 return ErrorCode::BUSY;
154}

◆ WaitDmaTransferDone()

ErrorCode MSPM0I2C::WaitDmaTransferDone ( uint8_t channel_id) const
private

Definition at line 403 of file mspm0_i2c.cpp.

404{
405 uint32_t timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
406 while (DL_DMA_getTransferSize(DMA, channel_id) != 0U)
407 {
408 if (CheckControllerError() != ErrorCode::OK)
409 {
410 return ErrorCode::FAILED;
411 }
412 if (timeout-- == 0U)
413 {
414 return ErrorCode::BUSY;
415 }
416 }
417 return ErrorCode::OK;
418}

◆ WaitTransactionDone()

ErrorCode MSPM0I2C::WaitTransactionDone ( ) const
private

Definition at line 156 of file mspm0_i2c.cpp.

157{
158 uint32_t timeout = MSPM0_I2C_WAIT_FIFO_TIMEOUT;
159 while (timeout-- > 0)
160 {
161 if (DL_I2C_getTransactionCount(res_.instance) == 0)
162 {
163 return ErrorCode::OK;
164 }
165 if (CheckControllerError() != ErrorCode::OK)
166 {
167 return ErrorCode::FAILED;
168 }
169 }
170 return ErrorCode::BUSY;
171}

◆ Write()

ErrorCode MSPM0I2C::Write ( uint16_t slave_addr,
ConstRawData write_data,
WriteOperation & op,
bool in_isr = false )
overridevirtual

I2C 设备写入数据。 Writes data to an I2C device.

该函数将 write_data 写入指定的 I2C 从设备地址。 This function writes write_data to the specified I2C slave address.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
write_data需要写入的数据,ConstRawData 类型。 The data to be written, of type ConstRawData.
op写入操作对象,包含同步或异步操作模式。 Write operation object containing synchronous or asynchronous operation mode.
in_isr是否在中断中进行操作。Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,指示操作是否成功。 Returns an ErrorCode indicating whether the operation was successful.

Implements LibXR::I2C.

Definition at line 618 of file mspm0_i2c.cpp.

620{
621 if (write_data.size_ == 0)
622 {
623 if (op.type != WriteOperation::OperationType::BLOCK)
624 {
625 op.UpdateStatus(in_isr, ErrorCode::OK);
626 }
627 return ErrorCode::OK;
628 }
629
630 const uint16_t ADDR7 = mspm0_i2c_to_addr7(slave_addr);
632 if (dma_enabled_ && write_data.size_ > dma_enable_min_size_)
633 {
634 ans = DmaWrite7(ADDR7, write_data);
635 }
636 else
637 {
638 ans = PollingWrite7(ADDR7, static_cast<const uint8_t*>(write_data.addr_),
639 write_data.size_);
640 }
641
642 if (op.type != WriteOperation::OperationType::BLOCK)
643 {
644 op.UpdateStatus(in_isr, ans);
645 }
646 return ans;
647}

Field Documentation

◆ dma_enable_min_size_

uint32_t LibXR::MSPM0I2C::dma_enable_min_size_
private

Definition at line 92 of file mspm0_i2c.hpp.

◆ dma_enabled_

bool LibXR::MSPM0I2C::dma_enabled_ = false
private

Definition at line 93 of file mspm0_i2c.hpp.

◆ INVALID_INSTANCE_INDEX

uint8_t LibXR::MSPM0I2C::INVALID_INSTANCE_INDEX = 0xFF
staticconstexprprivate

Definition at line 70 of file mspm0_i2c.hpp.

◆ MAX_I2C_INSTANCES

uint8_t LibXR::MSPM0I2C::MAX_I2C_INSTANCES = 4
staticconstexprprivate

Definition at line 69 of file mspm0_i2c.hpp.

◆ res_

Resources LibXR::MSPM0I2C::res_
private

Definition at line 90 of file mspm0_i2c.hpp.

◆ stage_buffer_

RawData LibXR::MSPM0I2C::stage_buffer_
private

Definition at line 91 of file mspm0_i2c.hpp.


The documentation for this class was generated from the following files: