8#include "ch32_gpio.hpp"
12CH32I2C* CH32I2C::map_[CH32_I2C_NUMBER] = {
nullptr};
17constexpr uint32_t CH32_I2C_ERROR_FLAGS =
18 ((I2C_FLAG_BERR & 0xFFFFu) | (I2C_FLAG_ARLO & 0xFFFFu) | (I2C_FLAG_AF & 0xFFFFu) |
19 (I2C_FLAG_OVR & 0xFFFFu) | (I2C_FLAG_PECERR & 0xFFFFu) |
20 (I2C_FLAG_TIMEOUT & 0xFFFFu) | (I2C_FLAG_SMBALERT & 0xFFFFu));
24static inline void ch32_i2c_enable_clocks(ch32_i2c_id_t
id)
26 RCC_APB1PeriphClockCmd(CH32_I2C_RCC_PERIPH_MAP[
id], ENABLE);
27 RCC_AHBPeriphClockCmd(CH32_I2C_RCC_PERIPH_MAP_DMA[
id], ENABLE);
31 uint16_t scl_pin, GPIO_TypeDef* sda_port, uint16_t sda_pin,
32 uint32_t pin_remap, uint32_t dma_enable_min_size,
33 uint32_t default_clock_hz,
bool ten_bit_addr)
35 instance_(ch32_i2c_get_instance_id(id)),
36 dma_rx_channel_(CH32_I2C_RX_DMA_CHANNEL_MAP[id]),
37 dma_tx_channel_(CH32_I2C_TX_DMA_CHANNEL_MAP[id]),
39 dma_enable_min_size_(dma_enable_min_size),
45 ten_bit_addr_(ten_bit_addr)
47 ASSERT(instance_ !=
nullptr);
48 ASSERT(dma_buff_.
addr_ !=
nullptr && dma_buff_.
size_ > 0);
53 ch32_i2c_enable_clocks(id_);
57 GPIO_InitTypeDef gpio = {};
58 gpio.GPIO_Speed = GPIO_Speed_50MHz;
59 gpio.GPIO_Mode = GPIO_Mode_AF_OD;
61 RCC_APB2PeriphClockCmd(ch32_get_gpio_periph(scl_port_), ENABLE);
62 RCC_APB2PeriphClockCmd(ch32_get_gpio_periph(sda_port_), ENABLE);
64 GPIO_SetBits(scl_port_, scl_pin_);
65 GPIO_SetBits(sda_port_, sda_pin_);
67 gpio.GPIO_Pin = scl_pin_;
68 GPIO_Init(scl_port_, &gpio);
70 gpio.GPIO_Pin = sda_pin_;
71 GPIO_Init(sda_port_, &gpio);
75 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
76 GPIO_PinRemapConfig(pin_remap, ENABLE);
84 ch32_dma_callback_t cb = [](
void* arg)
86 ch32_dma_register_callback(ch32_dma_get_id(dma_rx_channel_), cb,
this);
88 DMA_InitTypeDef di = {};
89 DMA_DeInit(dma_rx_channel_);
90 di.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
91 di.DMA_MemoryBaseAddr = (uint32_t)dma_buff_.
addr_;
92 di.DMA_DIR = DMA_DIR_PeripheralSRC;
93 di.DMA_BufferSize = 0;
94 di.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
95 di.DMA_MemoryInc = DMA_MemoryInc_Enable;
96 di.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
97 di.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
98 di.DMA_Mode = DMA_Mode_Normal;
99 di.DMA_Priority = DMA_Priority_High;
100 di.DMA_M2M = DMA_M2M_Disable;
101 DMA_Init(dma_rx_channel_, &di);
102 DMA_ITConfig(dma_rx_channel_, DMA_IT_TC, ENABLE);
103 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[ch32_dma_get_id(dma_rx_channel_)]);
108 ch32_dma_callback_t cb = [](
void* arg)
109 {
reinterpret_cast<CH32I2C*
>(arg)->TxDmaIRQHandler(); };
110 ch32_dma_register_callback(ch32_dma_get_id(dma_tx_channel_), cb,
this);
112 DMA_InitTypeDef di = {};
113 DMA_DeInit(dma_tx_channel_);
114 di.DMA_PeripheralBaseAddr = (uint32_t)&instance_->DATAR;
115 di.DMA_MemoryBaseAddr = (uint32_t)dma_buff_.
addr_;
116 di.DMA_DIR = DMA_DIR_PeripheralDST;
117 di.DMA_BufferSize = 0;
118 di.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
119 di.DMA_MemoryInc = DMA_MemoryInc_Enable;
120 di.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
121 di.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
122 di.DMA_Mode = DMA_Mode_Normal;
123 di.DMA_Priority = DMA_Priority_VeryHigh;
124 di.DMA_M2M = DMA_M2M_Disable;
125 DMA_Init(dma_tx_channel_, &di);
126 DMA_ITConfig(dma_tx_channel_, DMA_IT_TC, ENABLE);
127 NVIC_EnableIRQ(CH32_DMA_IRQ_MAP[ch32_dma_get_id(dma_tx_channel_)]);
132 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
133 NVIC_EnableIRQ(CH32_I2C_ER_IRQ_MAP[id_]);
142 if (instance_ ==
nullptr || config.
clock_speed == 0U)
150 if (recovering_ || DmaBusy() || I2C_GetFlagStatus(instance_, I2C_FLAG_BUSY) != RESET)
155 RCC_ClocksTypeDef clocks{};
156 RCC_GetClocksFreq(&clocks);
157 const uint64_t denominator =
160 if (clocks.PCLK1_Frequency == 0U ||
161 (uint64_t(clocks.PCLK1_Frequency) + denominator - 1U) / denominator > 0x0FFFU)
171void CH32I2C::ApplyConfig(Configuration config)
173 I2C_Cmd(instance_, DISABLE);
174 I2C_DeInit(instance_);
176 I2C_InitTypeDef init = {};
177 init.I2C_ClockSpeed = config.clock_speed;
178 init.I2C_Mode = I2C_Mode_I2C;
179 init.I2C_DutyCycle = I2C_DutyCycle_2;
180 init.I2C_OwnAddress1 = 0;
181 init.I2C_Ack = I2C_Ack_Enable;
182 init.I2C_AcknowledgedAddress =
183 ten_bit_addr_ ? I2C_AcknowledgedAddress_10bit : I2C_AcknowledgedAddress_7bit;
185 I2C_Init(instance_, &init);
186 I2C_Cmd(instance_, ENABLE);
189 I2C_AcknowledgeConfig(instance_, ENABLE);
190 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
192 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
195bool CH32I2C::WaitEvent(uint32_t evt, uint32_t timeout_us)
200 if ((instance_->STAR1 & CH32_I2C_ERROR_FLAGS) != 0u)
204 if (I2C_CheckEvent(instance_, evt) == READY)
212bool CH32I2C::WaitFlag(uint32_t flag, FlagStatus st, uint32_t timeout_us)
217 if ((flag != I2C_FLAG_BUSY) && ((instance_->STAR1 & CH32_I2C_ERROR_FLAGS) != 0u))
221 if (I2C_GetFlagStatus(instance_, flag) == st)
229ErrorCode CH32I2C::WaitEventOrRecover(uint32_t evt, uint32_t timeout_us)
231 if (WaitEvent(evt, timeout_us))
235 RecoverAfterImmediateFailure();
239ErrorCode CH32I2C::WaitFlagOrRecover(uint32_t flag, FlagStatus st, uint32_t timeout_us)
241 if (WaitFlag(flag, st, timeout_us))
245 RecoverAfterImmediateFailure();
249void CH32I2C::ClearAddrFlag()
251 volatile uint16_t tmp1 = instance_->STAR1;
252 volatile uint16_t tmp2 = instance_->STAR2;
257ErrorCode CH32I2C::MasterStartAndAddress10Bit(uint16_t addr10, uint8_t final_dir)
259 addr10 = Addr10Clamp(addr10);
262 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_BUSY, RESET); ec !=
ErrorCode::OK)
268 I2C_GenerateSTART(instance_, ENABLE);
269 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_MODE_SELECT); ec !=
ErrorCode::OK)
276 const uint8_t HEADER =
static_cast<uint8_t
>(0xF0 | ((addr10 >> 7) & 0x06));
277 I2C_Send7bitAddress(instance_, HEADER, I2C_Direction_Transmitter);
280 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_MODE_ADDRESS10); ec !=
ErrorCode::OK)
286 I2C_SendData(instance_,
static_cast<uint8_t
>(addr10 & 0xFF));
289 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
296 if (final_dir == I2C_Direction_Transmitter)
302 I2C_GenerateSTART(instance_, ENABLE);
303 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_MODE_SELECT); ec !=
ErrorCode::OK)
308 I2C_Send7bitAddress(instance_, HEADER, I2C_Direction_Receiver);
309 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
319ErrorCode CH32I2C::MasterStartAndAddress(uint16_t slave_addr, uint8_t dir)
324 const uint8_t ADDR8 = Addr7ToAddr8(slave_addr);
326 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_BUSY, RESET); ec !=
ErrorCode::OK)
331 I2C_GenerateSTART(instance_, ENABLE);
332 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_MODE_SELECT); ec !=
ErrorCode::OK)
337 I2C_Send7bitAddress(instance_, ADDR8, dir);
339 if (dir == I2C_Direction_Transmitter)
341 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
349 if (
auto ec = WaitEventOrRecover(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
361 return MasterStartAndAddress10Bit(slave_addr, dir);
364ErrorCode CH32I2C::SendMemAddr(uint16_t mem_addr, MemAddrLength len)
366 if (len == MemAddrLength::BYTE_16)
368 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_TXE, SET); ec !=
ErrorCode::OK)
372 I2C_SendData(instance_,
static_cast<uint8_t
>((mem_addr >> 8) & 0xFF));
373 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_TXE, SET); ec !=
ErrorCode::OK)
377 I2C_SendData(instance_,
static_cast<uint8_t
>(mem_addr & 0xFF));
381 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_TXE, SET); ec !=
ErrorCode::OK)
385 I2C_SendData(instance_,
static_cast<uint8_t
>(mem_addr & 0xFF));
388 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_BTF, SET); ec !=
ErrorCode::OK)
395ErrorCode CH32I2C::PollingWriteBytes(
const uint8_t* data, uint32_t len)
397 for (uint32_t i = 0; i < len; ++i)
399 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_TXE, SET); ec !=
ErrorCode::OK)
403 I2C_SendData(instance_, data[i]);
405 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_BTF, SET); ec !=
ErrorCode::OK)
412ErrorCode CH32I2C::PollingReadBytes(uint8_t* data, uint32_t len)
422 I2C_AcknowledgeConfig(instance_, DISABLE);
423 I2C_GenerateSTOP(instance_, ENABLE);
424 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_RXNE, SET); ec !=
ErrorCode::OK)
428 data[0] = I2C_ReceiveData(instance_);
429 I2C_AcknowledgeConfig(instance_, ENABLE);
436 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Next);
437 I2C_AcknowledgeConfig(instance_, DISABLE);
439 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_BTF, SET); ec !=
ErrorCode::OK)
443 I2C_GenerateSTOP(instance_, ENABLE);
445 data[0] = I2C_ReceiveData(instance_);
446 data[1] = I2C_ReceiveData(instance_);
448 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
449 I2C_AcknowledgeConfig(instance_, ENABLE);
454 I2C_AcknowledgeConfig(instance_, ENABLE);
455 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
460 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_RXNE, SET); ec !=
ErrorCode::OK)
464 data[idx++] = I2C_ReceiveData(instance_);
469 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_BTF, SET); ec !=
ErrorCode::OK)
473 I2C_AcknowledgeConfig(instance_, DISABLE);
474 data[idx++] = I2C_ReceiveData(instance_);
475 I2C_GenerateSTOP(instance_, ENABLE);
476 data[idx++] = I2C_ReceiveData(instance_);
478 if (
auto ec = WaitFlagOrRecover(I2C_FLAG_RXNE, SET); ec !=
ErrorCode::OK)
482 data[idx++] = I2C_ReceiveData(instance_);
484 I2C_AcknowledgeConfig(instance_, ENABLE);
488void CH32I2C::StartTxDma(uint32_t len)
490 dma_tx_channel_->MADDR =
reinterpret_cast<uint32_t
>(dma_buff_.
addr_);
491 dma_tx_channel_->CNTR = len;
493 I2C_DMACmd(instance_, ENABLE);
494 DMA_Cmd(dma_tx_channel_, ENABLE);
497void CH32I2C::StartRxDma(uint32_t len)
500 I2C_AcknowledgeConfig(instance_, ENABLE);
501 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
503 dma_rx_channel_->MADDR =
reinterpret_cast<uint32_t
>(dma_buff_.
addr_);
504 dma_rx_channel_->CNTR = len;
506 I2C_DMALastTransferCmd(instance_, ENABLE);
507 I2C_DMACmd(instance_, ENABLE);
508 DMA_Cmd(dma_rx_channel_, ENABLE);
513 I2C_DMACmd(instance_, DISABLE);
514 I2C_DMALastTransferCmd(instance_, DISABLE);
515 DMA_Cmd(dma_tx_channel_, DISABLE);
516 DMA_Cmd(dma_rx_channel_, DISABLE);
519 I2C_AcknowledgeConfig(instance_, ENABLE);
520 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
522 I2C_GenerateSTOP(instance_, ENABLE);
528 if (read_op_.
type == ReadOperation::OperationType::BLOCK)
530 (void)block_wait_.
TryPost(
true, ec);
539 if (write_op_.
type == WriteOperation::OperationType::BLOCK)
541 (void)block_wait_.
TryPost(
true, ec);
550void CH32I2C::RecoverAfterImmediateFailure()
553 I2C_ITConfig(instance_, I2C_IT_ERR, DISABLE);
554 I2C_DMACmd(instance_, DISABLE);
555 I2C_DMALastTransferCmd(instance_, DISABLE);
556 DMA_Cmd(dma_tx_channel_, DISABLE);
557 DMA_Cmd(dma_rx_channel_, DISABLE);
558 dma_tx_channel_->CNTR = 0;
559 dma_rx_channel_->CNTR = 0;
561 DMA_ClearITPendingBit(CH32_I2C_TX_DMA_IT_MAP[id_]);
562 DMA_ClearITPendingBit(CH32_I2C_RX_DMA_IT_MAP[id_]);
564 const uint32_t err_its[] = {I2C_IT_BERR, I2C_IT_ARLO, I2C_IT_AF, I2C_IT_OVR,
565 I2C_IT_PECERR, I2C_IT_TIMEOUT, I2C_IT_SMBALERT};
566 for (uint32_t it : err_its)
568 I2C_ClearITPendingBit(instance_, it);
571 I2C_GenerateSTOP(instance_, ENABLE);
572 if (!WaitFlag(I2C_FLAG_BUSY, RESET, K_DEFAULT_TIMEOUT_US))
579 I2C_AcknowledgeConfig(instance_, ENABLE);
580 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
587 read_buff_ = {
nullptr, 0};
588 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
595 if (write_data.
size_ == 0)
597 if (op.
type != WriteOperation::OperationType::BLOCK)
611 I2C_ITConfig(instance_, I2C_IT_ERR, DISABLE);
613 ErrorCode ec = MasterStartAndAddress(slave_addr, I2C_Direction_Transmitter);
620 if (write_data.
size_ <= dma_enable_min_size_)
622 ec = PollingWriteBytes(
reinterpret_cast<const uint8_t*
>(write_data.
addr_),
624 I2C_GenerateSTOP(instance_, ENABLE);
625 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
627 if (op.
type != WriteOperation::OperationType::BLOCK)
640 if (op.
type == WriteOperation::OperationType::BLOCK)
645 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
646 StartTxDma(write_data.
size_);
648 if (op.
type == WriteOperation::OperationType::BLOCK)
658 if (read_data.
size_ == 0)
660 if (op.
type != ReadOperation::OperationType::BLOCK)
674 I2C_ITConfig(instance_, I2C_IT_ERR, DISABLE);
676 ErrorCode ec = MasterStartAndAddress(slave_addr, I2C_Direction_Receiver);
683 if (read_data.
size_ <= dma_enable_min_size_)
685 ec = PollingReadBytes(
reinterpret_cast<uint8_t*
>(read_data.
addr_), read_data.
size_);
686 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
687 if (op.
type != ReadOperation::OperationType::BLOCK)
696 read_buff_ = read_data;
699 if (op.
type == ReadOperation::OperationType::BLOCK)
704 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
705 StartRxDma(read_data.
size_);
707 if (op.
type == ReadOperation::OperationType::BLOCK)
716 MemAddrLength mem_addr_size,
bool in_isr)
718 if (write_data.
size_ == 0)
720 if (op.
type != WriteOperation::OperationType::BLOCK)
734 I2C_ITConfig(instance_, I2C_IT_ERR, DISABLE);
736 ErrorCode ec = MasterStartAndAddress(slave_addr, I2C_Direction_Transmitter);
742 ec = SendMemAddr(mem_addr, mem_addr_size);
745 I2C_GenerateSTOP(instance_, ENABLE);
746 if (op.
type != WriteOperation::OperationType::BLOCK)
753 if (write_data.
size_ <= dma_enable_min_size_)
755 ec = PollingWriteBytes(
reinterpret_cast<const uint8_t*
>(write_data.
addr_),
757 I2C_GenerateSTOP(instance_, ENABLE);
758 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
760 if (op.
type != WriteOperation::OperationType::BLOCK)
772 if (op.
type == WriteOperation::OperationType::BLOCK)
777 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
778 StartTxDma(write_data.
size_);
780 if (op.
type == WriteOperation::OperationType::BLOCK)
790 if (read_data.
size_ == 0)
792 if (op.
type != ReadOperation::OperationType::BLOCK)
806 I2C_ITConfig(instance_, I2C_IT_ERR, DISABLE);
809 ErrorCode ec = MasterStartAndAddress(slave_addr, I2C_Direction_Transmitter);
815 ec = SendMemAddr(mem_addr, mem_addr_size);
818 I2C_GenerateSTOP(instance_, ENABLE);
819 if (op.
type != ReadOperation::OperationType::BLOCK)
829 const uint8_t ADDR8 = Addr7ToAddr8(slave_addr);
831 I2C_GenerateSTART(instance_, ENABLE);
832 if (!WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
834 I2C_GenerateSTOP(instance_, ENABLE);
836 if (op.
type != ReadOperation::OperationType::BLOCK)
843 I2C_Send7bitAddress(instance_, ADDR8, I2C_Direction_Receiver);
844 if (!WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
846 I2C_GenerateSTOP(instance_, ENABLE);
848 if (op.
type != ReadOperation::OperationType::BLOCK)
858 const uint16_t ADDR10 = Addr10Clamp(slave_addr);
859 const uint8_t HEADER =
static_cast<uint8_t
>(0xF0 | ((ADDR10 >> 7) & 0x06));
861 I2C_GenerateSTART(instance_, ENABLE);
862 if (!WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
864 I2C_GenerateSTOP(instance_, ENABLE);
866 if (op.
type != ReadOperation::OperationType::BLOCK)
873 I2C_Send7bitAddress(instance_, HEADER, I2C_Direction_Receiver);
874 if (!WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
876 I2C_GenerateSTOP(instance_, ENABLE);
878 if (op.
type != ReadOperation::OperationType::BLOCK)
888 if (read_data.
size_ <= dma_enable_min_size_)
890 ec = PollingReadBytes(
reinterpret_cast<uint8_t*
>(read_data.
addr_), read_data.
size_);
891 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
892 if (op.
type != ReadOperation::OperationType::BLOCK)
901 read_buff_ = read_data;
904 if (op.
type == ReadOperation::OperationType::BLOCK)
909 I2C_ITConfig(instance_, I2C_IT_ERR, ENABLE);
910 StartRxDma(read_data.
size_);
912 if (op.
type == ReadOperation::OperationType::BLOCK)
919void CH32I2C::TxDmaIRQHandler()
921 if (DMA_GetITStatus(CH32_I2C_TX_DMA_IT_MAP[id_]) == RESET)
925 DMA_ClearITPendingBit(CH32_I2C_TX_DMA_IT_MAP[id_]);
927 DMA_Cmd(dma_tx_channel_, DISABLE);
928 I2C_DMACmd(instance_, DISABLE);
930 if (recovering_ || !busy_)
935 (void)WaitFlag(I2C_FLAG_BTF, SET, 20000);
936 I2C_GenerateSTOP(instance_, ENABLE);
939 if (write_op_.
type == WriteOperation::OperationType::BLOCK)
951 if (DMA_GetITStatus(CH32_I2C_RX_DMA_IT_MAP[id_]) == RESET)
955 DMA_ClearITPendingBit(CH32_I2C_RX_DMA_IT_MAP[id_]);
957 DMA_Cmd(dma_rx_channel_, DISABLE);
958 I2C_DMACmd(instance_, DISABLE);
959 I2C_DMALastTransferCmd(instance_, DISABLE);
961 if (recovering_ || !busy_)
966 I2C_GenerateSTOP(instance_, ENABLE);
968 if (read_buff_.
size_ > 0)
971 read_buff_.
size_ = 0;
975 I2C_AcknowledgeConfig(instance_, ENABLE);
976 I2C_NACKPositionConfig(instance_, I2C_NACKPosition_Current);
979 if (read_op_.
type == ReadOperation::OperationType::BLOCK)
991 bool has_err =
false;
993 const uint32_t ITS[] = {I2C_IT_BERR, I2C_IT_ARLO, I2C_IT_AF, I2C_IT_OVR,
994 I2C_IT_TIMEOUT, I2C_IT_PECERR, I2C_IT_SMBALERT};
996 for (uint32_t it : ITS)
998 if (I2C_GetITStatus(instance_, it) == SET)
1000 I2C_ClearITPendingBit(instance_, it);
1005 if (has_err && busy_ && !recovering_)
1015 void i2_c1_er_irq_handler(
void) __attribute__((interrupt(
"WCH-Interrupt-fast")));
1016 void i2_c1_er_irq_handler(
void)
1018 auto* p = LibXR::CH32I2C::map_[ch32_i2c_get_id(I2C1)];
1021 p->ErrorIRQHandler();
1027 void i2_c2_er_irq_handler(
void) __attribute__((interrupt(
"WCH-Interrupt-fast")));
1028 void i2_c2_er_irq_handler(
void)
1030 auto* p = LibXR::CH32I2C::map_[ch32_i2c_get_id(I2C2)];
1033 p->ErrorIRQHandler();
bool TryPost(bool in_isr, ErrorCode ec)
尝试认领完成并唤醒调用者 / Try to claim completion and wake the caller.
void Start(Semaphore &sem)
绑定信号量并开始等待 / Bind a semaphore and start waiting.
ErrorCode Wait(uint32_t timeout)
等待完成或超时交接 / Wait for completion or a timeout handoff.
ErrorCode MemWrite(uint16_t slave_addr, uint16_t mem_addr, ConstRawData write_data, WriteOperation &op, MemAddrLength mem_addr_size, bool in_isr) override
向 I2C 设备指定寄存器写入数据。 Writes data to a specific register of an I2C device.
ErrorCode MemRead(uint16_t slave_addr, uint16_t mem_addr, RawData read_data, ReadOperation &op, MemAddrLength mem_addr_size, bool in_isr) override
从 I2C 设备指定寄存器读取数据。 Reads data from a specific register of an I2C device.
void RxDmaIRQHandler()
DMA 回调入口 / DMA callbacks from CH32 DMA driver.
void ErrorIRQHandler()
错误中断回调 / I2C error IRQ callback
ErrorCode Write(uint16_t slave_addr, ConstRawData write_data, WriteOperation &op, bool in_isr) override
向 I2C 设备写入数据。 Writes data to an I2C device.
ErrorCode Read(uint16_t slave_addr, RawData read_data, ReadOperation &op, bool in_isr) override
读取 I2C 设备的数据。 Reads data from an I2C device.
CH32I2C(ch32_i2c_id_t id, RawData dma_buff, GPIO_TypeDef *scl_port, uint16_t scl_pin, GPIO_TypeDef *sda_port, uint16_t sda_pin, uint32_t pin_remap=0, uint32_t dma_enable_min_size=3, uint32_t default_clock_hz=400000, bool ten_bit_addr=false)
构造 I2C 驱动对象 / Construct I2C driver object
ErrorCode SetConfig(Configuration config) override
配置 I2C 设备参数。 Configures the I2C device settings.
只读原始数据视图 / Immutable raw data view
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
I2C(Inter-Integrated Circuit)接口类。 I2C (Inter-Integrated Circuit) interface class.
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
uint32_t timeout
等待超时值 / Wait timeout.
void UpdateStatus(bool in_isr, Status &&status)
按通知方式报告完成结果 / Report completion using the selected mode.
union LibXR::Operation::@6 data
完成通知对象,由 type 选择有效成员 / Notification target selected by type.
void MarkAsRunning()
标记轮询操作正在执行 / Mark a polling operation as running.
Semaphore * sem
借用的信号量 / Borrowed semaphore.
OperationType type
当前通知方式 / Current notification mode.
可写原始数据视图 / Mutable raw data view
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
static MicrosecondTimestamp GetMicroseconds()
获取当前时间的微秒级时间戳。 Gets the current timestamp in microseconds.
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ NOT_SUPPORT
不支持 / Not supported
@ FAILED
操作失败 / Operation failed
@ OK
操作成功 / Operation successful
@ ARG_ERR
参数错误 / Argument error
I2C 设备的配置信息结构体。 Configuration structure for an I2C device.
uint32_t clock_speed
I2C 通信时钟速率(单位:Hz) / The I2C clock speed (in Hz).