sync(template): 回合 capsule_mb 通用驱动修复
- uart_ring_buffer: PRIMASK 位检查从 ==0 改为 &0x1 修正 - i2c: 新增 i2c_read_raw() 无子地址读函数 - 全局: volatile 统一替换为 __IO (CMSIS 风格)
This commit is contained in:
@@ -129,6 +129,16 @@ i2c_result_t i2c_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint
|
|||||||
*/
|
*/
|
||||||
i2c_result_t i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
|
i2c_result_t i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
|
/* Pure read response without sub-address phase (for commands that already sent read request parameters) */
|
||||||
|
/*!
|
||||||
|
\brief read data from I2C device without register/sub-address phase
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\param[out] data: pointer to data buffer
|
||||||
|
\param[in] length: number of bytes to read (1-255)
|
||||||
|
\retval i2c_result_t: operation result
|
||||||
|
*/
|
||||||
|
i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
/*!
|
/*!
|
||||||
\brief get status string for debugging
|
\brief get status string for debugging
|
||||||
|
|||||||
@@ -1110,6 +1110,163 @@ i2c_result_t i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8
|
|||||||
return I2C_RESULT_TIMEOUT;
|
return I2C_RESULT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief read data from I2C device without register/sub-address phase
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\param[out] data: pointer to data buffer
|
||||||
|
\param[in] length: number of bytes to read (1-255)
|
||||||
|
\retval i2c_result_t: operation result
|
||||||
|
*/
|
||||||
|
i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length)
|
||||||
|
{
|
||||||
|
i2c_state_t state = I2C_STATE_START;
|
||||||
|
uint16_t timeout = 0;
|
||||||
|
uint8_t retry_count = 0;
|
||||||
|
uint8_t data_index = 0;
|
||||||
|
|
||||||
|
if (data == NULL || slave_addr > 0x7F || length == 0) {
|
||||||
|
return I2C_RESULT_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
|
||||||
|
while (retry_count < (uint8_t)I2C_MAX_RETRY) {
|
||||||
|
switch (state) {
|
||||||
|
case I2C_STATE_START:
|
||||||
|
timeout = 0;
|
||||||
|
data_index = 0;
|
||||||
|
|
||||||
|
if (_i2c_wait_flag_clear_timeout(I2C_FLAG_I2CBSY) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_start_on_bus(I2C0);
|
||||||
|
state = I2C_STATE_SEND_ADDRESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case I2C_STATE_SEND_ADDRESS:
|
||||||
|
if (_i2c_wait_flag_timeout(I2C_FLAG_SBSEND) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_master_addressing(I2C0, (slave_addr << 1), I2C_RECEIVER);
|
||||||
|
state = I2C_STATE_CLEAR_ADDRESS;
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case I2C_STATE_CLEAR_ADDRESS:
|
||||||
|
while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (!i2c_flag_get(I2C0, I2C_FLAG_AERR)) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout >= I2C_TIME_OUT) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) {
|
||||||
|
i2c_flag_clear(I2C0, I2C_FLAG_AERR);
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
return I2C_RESULT_NACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 1) {
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||||
|
} else if (length == 2) {
|
||||||
|
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||||
|
} else {
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||||
|
state = I2C_STATE_RECEIVE_DATA;
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case I2C_STATE_RECEIVE_DATA:
|
||||||
|
if (length == 1) {
|
||||||
|
if (_i2c_wait_flag_timeout(I2C_FLAG_RBNE) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data[0] = i2c_data_receive(I2C0);
|
||||||
|
state = I2C_STATE_STOP;
|
||||||
|
} else if (length == 2) {
|
||||||
|
if (_i2c_wait_flag_timeout(I2C_FLAG_BTC) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
data[0] = i2c_data_receive(I2C0);
|
||||||
|
data[1] = i2c_data_receive(I2C0);
|
||||||
|
state = I2C_STATE_STOP;
|
||||||
|
} else {
|
||||||
|
while (data_index < length) {
|
||||||
|
if (data_index < length - 2) {
|
||||||
|
if (_i2c_wait_flag_timeout(I2C_FLAG_RBNE) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data[data_index++] = i2c_data_receive(I2C0);
|
||||||
|
} else if (data_index == length - 2) {
|
||||||
|
if (_i2c_wait_flag_timeout(I2C_FLAG_BTC) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
data[data_index++] = i2c_data_receive(I2C0);
|
||||||
|
} else {
|
||||||
|
if (_i2c_wait_flag_timeout(I2C_FLAG_RBNE) != I2C_RESULT_SUCCESS) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data[data_index++] = i2c_data_receive(I2C0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state == I2C_STATE_ERROR) break;
|
||||||
|
state = I2C_STATE_STOP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case I2C_STATE_STOP:
|
||||||
|
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
if (timeout >= I2C_TIME_OUT) {
|
||||||
|
state = I2C_STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
|
||||||
|
return I2C_RESULT_SUCCESS;
|
||||||
|
|
||||||
|
case I2C_STATE_ERROR:
|
||||||
|
i2c_bus_reset();
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
|
||||||
|
|
||||||
|
retry_count++;
|
||||||
|
if (retry_count >= I2C_MAX_RETRY) {
|
||||||
|
return I2C_RESULT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = I2C_STATE_START;
|
||||||
|
timeout = 0;
|
||||||
|
delay_10us(10);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
state = I2C_STATE_START;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return I2C_RESULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
/*!
|
/*!
|
||||||
\brief get status string for debugging
|
\brief get status string for debugging
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
It is strongly recommended to include it to avoid issues caused by self-removal.
|
It is strongly recommended to include it to avoid issues caused by self-removal.
|
||||||
*/
|
*/
|
||||||
#define RCU_MODIFY(__delay) do{ \
|
#define RCU_MODIFY(__delay) do{ \
|
||||||
volatile uint32_t i,reg; \
|
__IO uint32_t i,reg; \
|
||||||
if(0 != __delay){ \
|
if(0 != __delay){ \
|
||||||
reg = RCU_CFG0; \
|
reg = RCU_CFG0; \
|
||||||
reg &= ~(RCU_CFG0_AHBPSC); \
|
reg &= ~(RCU_CFG0_AHBPSC); \
|
||||||
|
|||||||
+4
-4
@@ -12,7 +12,7 @@
|
|||||||
#include "gd32e23x.h"
|
#include "gd32e23x.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
|
||||||
volatile static uint32_t delay_count = 0;
|
static __IO uint32_t delay_count = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ************************************************************************
|
* ************************************************************************
|
||||||
@@ -47,7 +47,7 @@ void delay_10us(uint32_t count)
|
|||||||
uint32_t loops_per_10us = SystemCoreClock / 1700000; // 粗略估计,每10微秒的循环次数
|
uint32_t loops_per_10us = SystemCoreClock / 1700000; // 粗略估计,每10微秒的循环次数
|
||||||
|
|
||||||
for(uint32_t i = 0; i < count; i++) {
|
for(uint32_t i = 0; i < count; i++) {
|
||||||
for(volatile uint32_t j = 0; j < loops_per_10us; j++);
|
for(__IO uint32_t j = 0; j < loops_per_10us; j++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ void delay_decrement(void)
|
|||||||
// uint32_t loops_per_ms = SystemCoreClock / 14000; // 粗略估计
|
// uint32_t loops_per_ms = SystemCoreClock / 14000; // 粗略估计
|
||||||
|
|
||||||
// for(uint32_t i = 0; i < count; i++) {
|
// for(uint32_t i = 0; i < count; i++) {
|
||||||
// for(volatile uint32_t j = 0; j < loops_per_ms; j++);
|
// for(__IO uint32_t j = 0; j < loops_per_ms; j++);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -113,6 +113,6 @@ void delay_decrement(void)
|
|||||||
// uint32_t loops_per_us = SystemCoreClock / 22000000; // 粗略估计,每微秒的循环次数
|
// uint32_t loops_per_us = SystemCoreClock / 22000000; // 粗略估计,每微秒的循环次数
|
||||||
|
|
||||||
// for(uint32_t i = 0; i < count; i++) {
|
// for(uint32_t i = 0; i < count; i++) {
|
||||||
// for(volatile uint32_t j = 0; j < loops_per_us; j++);
|
// for(__IO uint32_t j = 0; j < loops_per_us; j++);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
#include "uart_ring_buffer.h"
|
#include "uart_ring_buffer.h"
|
||||||
#include "gd32e23x.h"
|
#include "gd32e23x.h"
|
||||||
|
|
||||||
static volatile uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];
|
static __IO uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];
|
||||||
static volatile uint8_t write_index = 0;
|
static __IO uint8_t write_index = 0;
|
||||||
static volatile uint8_t read_index = 0;
|
static __IO uint8_t read_index = 0;
|
||||||
static volatile uint32_t dropped_bytes = 0;
|
static __IO uint32_t dropped_bytes = 0;
|
||||||
|
|
||||||
static inline uint32_t irq_save(void) {
|
static inline uint32_t irq_save(void) {
|
||||||
uint32_t primask = __get_PRIMASK();
|
uint32_t primask = __get_PRIMASK();
|
||||||
@@ -20,7 +20,7 @@ static inline uint32_t irq_save(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void irq_restore(uint32_t primask) {
|
static inline void irq_restore(uint32_t primask) {
|
||||||
if (primask == 0U) {
|
if ((primask & 0x1) == 0) {
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,9 +44,9 @@ static void uart_ring_buffer_reset_state(void) {
|
|||||||
* @ingroup RingBuffer
|
* @ingroup RingBuffer
|
||||||
*/
|
*/
|
||||||
void uart_ring_buffer_init(void) {
|
void uart_ring_buffer_init(void) {
|
||||||
uint32_t irq_key = irq_save();
|
uint32_t primask = irq_save();
|
||||||
uart_ring_buffer_reset_state();
|
uart_ring_buffer_reset_state();
|
||||||
irq_restore(irq_key);
|
irq_restore(primask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,9 +105,9 @@ bool uart_ring_buffer_put(uint8_t data) {
|
|||||||
* @ingroup RingBuffer
|
* @ingroup RingBuffer
|
||||||
*/
|
*/
|
||||||
void uart_ring_buffer_clear(void) {
|
void uart_ring_buffer_clear(void) {
|
||||||
uint32_t irq_key = irq_save();
|
uint32_t primask = irq_save();
|
||||||
uart_ring_buffer_reset_state();
|
uart_ring_buffer_reset_state();
|
||||||
irq_restore(irq_key);
|
irq_restore(primask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user