Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libraries/FlashStorage/src/FlashStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class FlashStorage
for (uint32_t i = 0; i < _storage_size; i++) {
buffer_[i] = src[i];
}
fmc_lock();
}

uint32_t length()
Expand Down Expand Up @@ -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;
Expand All @@ -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();
}
};
5 changes: 1 addition & 4 deletions libraries/Wire/src/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
168 changes: 136 additions & 32 deletions libraries/Wire/src/utility/twi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -613,7 +614,10 @@ 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;

/** This function handles I2C interrupt handler
*
Expand All @@ -629,34 +633,133 @@ 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 (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))
{
/* Send a data byte */
// 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++);
}

if (i2c_interrupt_flag_get(i2c, I2C_INT_FLAG_TBE))
{
i2c_data_transmit(i2c, 0xaa + snd_count++);
}
} 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)) {
/* 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);

if (!is_transmitter) {
obj_s->slave_receive_callback(obj_s->pWireObj, (uint8_t*)obj_s->rx_buffer_ptr, rx_count); // onReceiveService
}
is_transmitter = false;

}
}

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;
}
}

Expand All @@ -666,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
Expand Down
8 changes: 4 additions & 4 deletions libraries/Wire/src/utility/twi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down