From 5d380ec099f2fb2219206569b3916aeb3e7ca0d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=9E=E8=8B=B9=E6=9E=9C?= Date: Thu, 27 Mar 2025 20:45:54 +0800 Subject: [PATCH 1/3] Fix eeprom commit error. --- libraries/FlashStorage/src/FlashStorage.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libraries/FlashStorage/src/FlashStorage.h b/libraries/FlashStorage/src/FlashStorage.h index a2787c3a..d563edf7 100644 --- a/libraries/FlashStorage/src/FlashStorage.h +++ b/libraries/FlashStorage/src/FlashStorage.h @@ -63,6 +63,7 @@ class FlashStorage for (uint32_t i = 0; i < _storage_size; i++) { buffer_[i] = src[i]; } + fmc_lock(); } uint32_t length() @@ -98,12 +99,16 @@ class FlashStorage void commit() { + fmc_unlock(); uint32_t address = data_area_start; uint32_t *ptrs = (uint32_t *)buffer_; do { uint16_t page_size = pageSizeForAddress(address); + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); fmc_page_erase(address); + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); uint32_t word_count = page_size / 4; uint32_t i = 0; @@ -113,5 +118,7 @@ class FlashStorage address += 4U; } while (++i < word_count); } while (address < fmc_end_address); + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + fmc_lock(); } }; From c477fbfe132f2ac5a921fe92edaf190ffc98a49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=9E=E8=8B=B9=E6=9E=9C?= Date: Thu, 27 Mar 2025 20:52:58 +0800 Subject: [PATCH 2/3] Fixed I2C slave interrupt handling anomalies. Fixed incorrect cache memory usage, and revised the interrupt handling logic. --- libraries/Wire/src/Wire.cpp | 5 +- libraries/Wire/src/utility/twi.cpp | 74 +++++++++++++++++++----------- libraries/Wire/src/utility/twi.h | 8 ++-- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 7114b4b9..70887bf4 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -305,14 +305,11 @@ void TwoWire::onRequestService(void* pWireObj) pWire->_tx_buffer.tail = 0; // reset slave tx buffer iterator vars - pWire->_i2c.tx_buffer_ptr = pWire->_tx_buffer.buffer; + // pWire->_i2c.tx_buffer_ptr = pWire->_tx_buffer.buffer; pWire->_i2c.tx_count = 0; // alert user program pWire->user_onRequest(); - - // reset slave tx buffer iterator to let interrupt transmit the buffer - pWire->_i2c.tx_buffer_ptr = pWire->_tx_buffer.buffer; } } diff --git a/libraries/Wire/src/utility/twi.cpp b/libraries/Wire/src/utility/twi.cpp index 6728fe50..8f33e082 100644 --- a/libraries/Wire/src/utility/twi.cpp +++ b/libraries/Wire/src/utility/twi.cpp @@ -543,12 +543,13 @@ void i2c_attach_slave_tx_callback(i2c_t *obj, void (*function)(void*), void* pWi */ i2c_status_enum i2c_slave_write_buffer(i2c_t *obj, uint8_t *data, uint16_t length){ struct i2c_s *obj_s = I2C_S(obj); - if ( (obj_s->tx_count + length) > obj->tx_rx_buffer_size) + if ((obj_s->tx_count + length) > obj->tx_rx_buffer_size){ return I2C_DATA_TOO_LONG; + } - for (uint8_t i = 0; i < length; i++) - *obj_s->tx_buffer_ptr++ = *(data + i); - obj_s->tx_count += length; + for (uint8_t i = 0; i < length; i++){ + *(obj_s->tx_buffer_ptr + obj_s->tx_count++) = *(data + i); + } return I2C_OK; } @@ -614,6 +615,9 @@ void i2c_err_handler(uint32_t i2c) } } +volatile uint8_t snd_count; +volatile uint8_t rx_count; +volatile bool is_transmitter = false; /** This function handles I2C interrupt handler * @@ -629,34 +633,52 @@ static void i2c_irq(struct i2c_s *obj_s) if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_ADDSEND)) { /* clear the ADDSEND bit */ i2c_interrupt_flag_clear(i2c, I2C_INT_FLAG_ADDSEND); - //memset(_rx_Buffer, _rx_count, 0); - obj_s->rx_count = 0; + if (i2c_flag_get(i2c, GD32_I2C_FLAG_IS_TRANSMTR_OR_RECVR)) { - obj_s->slave_transmit_callback(obj_s->pWireObj); + is_transmitter = true; + obj_s->slave_transmit_callback(obj_s->pWireObj); // onRequestService + snd_count = 0; } - } else if ((i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_TBE)) && - (!i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_AERR))) { - /* Send a data byte */ - if (obj_s->tx_count > 0) { - i2c_data_transmit(i2c, *obj_s->tx_buffer_ptr++); - obj_s->tx_count--; + else { + is_transmitter = false; + rx_count = 0; } - } else if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_RBNE)) { - /* if reception data register is not empty, I2C1 will read a data from I2C_DATA */ - /* also check that our RX buffer has enough space for it */ - if(obj_s->rx_count < obj_s->tx_rx_buffer_size) { - *obj_s->rx_buffer_ptr++ = i2c_data_receive(i2c); - obj_s->rx_count++; - } else { - /* indicate RX buffer too small */ + } + + if (is_transmitter) + { + if ((i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_TBE)) && + (!i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_AERR))) + { + /* Send a data byte */ + if (snd_count < obj_s->tx_count) + { + i2c_data_transmit(i2c, *(obj_s->tx_buffer_ptr + snd_count++)); + } + } + else { + i2c_interrupt_flag_clear(i2c, I2C_INT_FLAG_AERR); } - } else if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_STPDET)) { + } + else { + if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_RBNE)) { + /* if reception data register is not empty, I2C1 will read a data from I2C_DATA */ + /* also check that our RX buffer has enough space for it */ + if(rx_count < obj_s->tx_rx_buffer_size) { + *(obj_s->rx_buffer_ptr + rx_count++) = i2c_data_receive(i2c); + } else { + /* indicate RX buffer too small */ + } + } + } + + if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_STPDET)) { + if (!is_transmitter) { + obj_s->slave_receive_callback(obj_s->pWireObj, (uint8_t*)obj_s->rx_buffer_ptr, rx_count); // onReceiveService + } + /* clear the STPDET bit */ i2c_enable(i2c); - if (!i2c_flag_get(i2c, GD32_I2C_FLAG_IS_TRANSMTR_OR_RECVR)) { - obj_s->rx_buffer_ptr = obj_s->rx_buffer_ptr - obj_s->rx_count ; - obj_s->slave_receive_callback(obj_s->pWireObj, obj_s->rx_buffer_ptr, obj_s->rx_count); - } } } diff --git a/libraries/Wire/src/utility/twi.h b/libraries/Wire/src/utility/twi.h index f00763f3..89a70052 100644 --- a/libraries/Wire/src/utility/twi.h +++ b/libraries/Wire/src/utility/twi.h @@ -47,10 +47,10 @@ struct i2c_s { PinName sda; PinName scl; /* operating parameters */ - uint8_t *tx_buffer_ptr; - uint8_t *rx_buffer_ptr; - uint16_t tx_count; - uint16_t rx_count; + volatile uint8_t *tx_buffer_ptr; + volatile uint8_t *rx_buffer_ptr; + volatile uint16_t tx_count; + volatile uint16_t rx_count; /* TX and RX buffer are expected to be of this size */ uint16_t tx_rx_buffer_size; From e774be9ad0359a7c2bb638a3896b6d191f59ae41 Mon Sep 17 00:00:00 2001 From: Lanceliu Date: Sat, 3 Jan 2026 10:51:34 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E8=A7=A3=E5=86=B3AT32=20?= =?UTF-8?q?inav=E9=80=82=E9=85=8D=E9=97=AE=E9=A2=98=20at32=20=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=E7=A9=BA=E9=80=9F=E8=AE=A1=E8=AF=BB=E5=8F=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E5=BA=94=E7=AD=94=E6=97=B6=E9=97=B4=E8=A6=81?= =?UTF-8?q?=E6=B1=82=E6=AF=94stm32=E7=9A=84=E8=A6=81=E6=B1=82=E9=AB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/Wire/src/utility/twi.cpp | 116 +++++++++++++++--- .../GD/GD32E23x/Source/system_gd32e23x.c | 4 +- 2 files changed, 101 insertions(+), 19 deletions(-) diff --git a/libraries/Wire/src/utility/twi.cpp b/libraries/Wire/src/utility/twi.cpp index 8f33e082..622a7be7 100644 --- a/libraries/Wire/src/utility/twi.cpp +++ b/libraries/Wire/src/utility/twi.cpp @@ -44,7 +44,7 @@ typedef enum { I2C_NUM } internal_i2c_index_t; -static struct i2c_s *obj_s_buf[I2C_NUM] = {NULL}; +static i2c_t* obj_s_buf[I2C_NUM] = {NULL}; #ifndef WIRE_I2C_FLAG_TIMEOUT #define WIRE_I2C_FLAG_TIMEOUT (0xF0000U) @@ -161,8 +161,8 @@ void i2c_slaves_interrupt_enable(i2c_t *obj) nvic_irq_enable(I2C0_EV_IRQn, 1, 3); nvic_irq_enable(I2C0_ER_IRQn, 1, 2); #else - nvic_irq_enable(I2C0_EV_IRQn, 1); - nvic_irq_enable(I2C0_ER_IRQn, 1); + nvic_irq_enable(I2C0_EV_IRQn, 0); + nvic_irq_enable(I2C0_ER_IRQn, 0); #endif break; case I2C1: @@ -171,8 +171,8 @@ void i2c_slaves_interrupt_enable(i2c_t *obj) nvic_irq_enable(I2C1_EV_IRQn, 1, 3); nvic_irq_enable(I2C1_ER_IRQn, 1, 2); #else - nvic_irq_enable(I2C1_EV_IRQn, 1); - nvic_irq_enable(I2C1_ER_IRQn, 1); + nvic_irq_enable(I2C1_EV_IRQn, 0); + nvic_irq_enable(I2C1_ER_IRQn, 0); #endif break; #ifdef I2C2 @@ -614,7 +614,7 @@ void i2c_err_handler(uint32_t i2c) i2c_interrupt_flag_clear(i2c, I2C_INT_FLAG_PECERR); } } - +// extern volatile uint8_t data[4]; volatile uint8_t snd_count; volatile uint8_t rx_count; volatile bool is_transmitter = false; @@ -645,19 +645,32 @@ static void i2c_irq(struct i2c_s *obj_s) } } + // if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_RBNE)) { + // /* if reception data register is not empty, I2C1 will read a data from I2C_DATA */ + // /* also check that our RX buffer has enough space for it */ + // if (rx_count < obj_s->tx_rx_buffer_size) + // { + // *(obj_s->rx_buffer_ptr + rx_count++) = i2c_data_receive(i2c); + // } + // } + if (is_transmitter) { - if ((i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_TBE)) && - (!i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_AERR))) + if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_TBE)) { /* Send a data byte */ - if (snd_count < obj_s->tx_count) - { - i2c_data_transmit(i2c, *(obj_s->tx_buffer_ptr + snd_count++)); - } + // if (snd_count < obj_s->tx_count) + // { + // i2c_data_transmit(i2c, *(obj_s->tx_buffer_ptr + snd_count++)); + // } + // i2c_data_transmit(i2c, *(data + snd_count++)); + // i2c_data_transmit(i2c, 0xaa + snd_count++); + i2c_data_transmit(i2c, 0xaa + snd_count++); } - else { - i2c_interrupt_flag_clear(i2c, I2C_INT_FLAG_AERR); + + if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_TBE)) + { + i2c_data_transmit(i2c, 0xaa + snd_count++); } } else { @@ -673,12 +686,80 @@ static void i2c_irq(struct i2c_s *obj_s) } if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_STPDET)) { + /* clear the STPDET bit */ + i2c_enable(i2c); + if (!is_transmitter) { obj_s->slave_receive_callback(obj_s->pWireObj, (uint8_t*)obj_s->rx_buffer_ptr, rx_count); // onReceiveService } + is_transmitter = false; - /* clear the STPDET bit */ - i2c_enable(i2c); + } +} + +volatile uint8_t tx_idx = 0; +volatile bool bUseCmd = false; +volatile uint8_t data[4]; +extern volatile uint8_t reg_status; +extern volatile uint8_t* read_ptr; +extern volatile uint8_t new_data_ready; + +void I2C0_IRQHandler(void) { + /* 1. 地址匹配中断 (Address Matched) */ + if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) { + /* 清除 ADDSEND 位 (通过读 STAT0 和 STAT1) */ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND); + + /* 检查当前是从机接收(主机写)还是从机发送(主机读) */ + if (i2c_flag_get(I2C0, GD32_I2C_FLAG_IS_TRANSMTR_OR_RECVR)) { + // 从机发送模式 (主机要读数据) + tx_idx = 0; // 重置发送索引 + // 可以在这里根据 current_cmd 决定准备什么数据到 i2c_tx_buffer + if(new_data_ready) { + memcpy((uint8_t*)data, (uint8_t*)read_ptr, 4); + new_data_ready = 0; + } + } + } + + /* 2. 接收中断 (Receive Buffer Not Empty) - 主机写数据给从机 */ + if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)) { + bUseCmd = true; + uint8_t cmd = i2c_data_receive(I2C0); + if (cmd == 0x00) { + // 接收到度量指令后,重新标识为新鲜 + reg_status = 0b00; + data[0] = (data[0] & 0x3F); // status = OK + } + } + + /* 3. 发送中断 (Transmit Buffer Empty) - 主机读从机数据 */ + if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) { + do { + if(tx_idx < 4) { + i2c_data_transmit(I2C0, data[tx_idx++]); + } + else { + // 无数据可发送时,发送0xff,适配PX4 + i2c_data_transmit(I2C0, 0xFF); + } + } while (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)); + + // if (bUseCmd && tx_idx == 4) { // 读取一次后数据标识为不新鲜 + // // status = STALE = 0b10 + // // 0x80 = 0b10xx xxxx + // data[0] = 0x80 | (data[0] & 0x3F); + // } + data[0] = 0x80 | (data[0] & 0x3F); + } + + /* 4. 停止位检测 (Stop Condition Detected) */ + if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_STPDET)) { + /* 清除 STPDET (写 STAT0 后读 CTL0) */ + i2c_enable(I2C0); // 简单处理:重新使能以清除标志位并释放总线 + + // 此处可以设置一个全局标志,通知 main 函数:一个完整的包收到了/发完了 + tx_idx = 0; } } @@ -688,7 +769,8 @@ static void i2c_irq(struct i2c_s *obj_s) */ extern "C" void I2C0_EV_IRQHandler(void) { - i2c_irq(obj_s_buf[I2C0_INDEX]); + // i2c_irq(obj_s_buf[I2C0_INDEX]); + I2C0_IRQHandler(); } /** handle I2C0 error interrupt request diff --git a/system/GD32E23x_firmware/CMSIS/GD/GD32E23x/Source/system_gd32e23x.c b/system/GD32E23x_firmware/CMSIS/GD/GD32E23x/Source/system_gd32e23x.c index a3296eaf..3b41a0ac 100644 --- a/system/GD32E23x_firmware/CMSIS/GD/GD32E23x/Source/system_gd32e23x.c +++ b/system/GD32E23x_firmware/CMSIS/GD/GD32E23x/Source/system_gd32e23x.c @@ -44,8 +44,8 @@ /* select a system clock by uncommenting the following line */ //#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL) -//#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) -#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) +//#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) //#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000) #define SEL_IRC8M 0x00