refactor(touch): 集成硬件 I2C 驱动并添加 EXTI 中断支持

- 将 touch 底层从软件 I2C 位冲切换为硬件 I2C0 (PB6/PB7)
- 修复 i2c_driver I2C0 引脚映射 (PB8/PB9 -> PB6/PB7)
- 重写 master_write_read() 实现正确的重复起始条件
- 添加 i2c_driver.h C API 声明供 C 代码调用
- 添加 GT1151 EXTI 中断 (PD11, EXTI11 下降沿触发)
- 删除 touch.h 中废弃的软件 I2C 函数声明
- test_touch() 改为中断驱动,无触摸时 I2C 总线空闲
This commit is contained in:
2026-04-26 20:36:54 +08:00
parent 851c3db56e
commit cbad06d616
6 changed files with 560 additions and 464 deletions
+180 -71
View File
@@ -4,7 +4,8 @@
#define I2C_TIMEOUT 50000
struct i2c_hw_config_t {
struct i2c_hw_config_t
{
uint32_t i2c_periph;
rcu_periph_enum rcu_clock;
uint32_t gpio_port;
@@ -15,60 +16,67 @@ struct i2c_hw_config_t {
};
static constexpr i2c_hw_config_t i2c_hw_map[] = {
{I2C0, RCU_I2C0, GPIOB, GPIO_PIN_8, GPIO_PIN_9, GPIO_AF_4, RCU_GPIOB},
{I2C0, RCU_I2C0, GPIOB, GPIO_PIN_6, GPIO_PIN_7, GPIO_AF_4, RCU_GPIOB},
{I2C1, RCU_I2C1, GPIOB, GPIO_PIN_10, GPIO_PIN_11, GPIO_AF_4, RCU_GPIOB},
{I2C2, RCU_I2C2, GPIOC, GPIO_PIN_4, GPIO_PIN_5, GPIO_AF_4, RCU_GPIOC},
{I2C2, RCU_I2C2, GPIOC, GPIO_PIN_4, GPIO_PIN_5, GPIO_AF_4, RCU_GPIOC},
};
static RetCode wait_flag(uint32_t i2c_periph, i2c_flag_enum flag)
{
uint32_t timeout = I2C_TIMEOUT;
while (RESET == i2c_flag_get(i2c_periph, flag)) {
if (--timeout == 0) {
while (RESET == i2c_flag_get(i2c_periph, flag))
{
if (--timeout == 0)
{
return RET_ERROR;
}
}
return RET_OK;
}
extern "C" {
static I2cBus i2c_0(I2cPort::_0);
static I2cBus i2c_1(I2cPort::_1);
static I2cBus i2c_2(I2cPort::_2);
static I2cBus *i2c_instances[] = { &i2c_0, &i2c_1, &i2c_2 };
static uint8_t i2c_inited[3] = {0};
int i2c_init(uint8_t port, uint32_t speed_hz)
extern "C"
{
if (port >= 3) return -1;
I2cConfig cfg;
cfg.speed_hz = speed_hz;
RetCode ret = i2c_instances[port]->init(cfg);
i2c_inited[port] = (ret == RET_OK) ? 1 : 0;
return i2c_inited[port] ? 0 : -1;
}
int i2c_master_write(uint8_t port, uint16_t dev_addr, const uint8_t *data, uint32_t len)
{
if (port >= 3 || !i2c_inited[port]) return -1;
I2cDevice dev(dev_addr);
return i2c_instances[port]->master_write(dev, data, len) == RET_OK ? 0 : -1;
}
static I2cBus i2c_0(I2cPort::_0);
static I2cBus i2c_1(I2cPort::_1);
static I2cBus i2c_2(I2cPort::_2);
static I2cBus *i2c_instances[] = {&i2c_0, &i2c_1, &i2c_2};
static uint8_t i2c_inited[3] = {0};
int i2c_master_read(uint8_t port, uint16_t dev_addr, uint8_t *data, uint32_t len)
{
if (port >= 3 || !i2c_inited[port]) return -1;
I2cDevice dev(dev_addr);
return i2c_instances[port]->master_read(dev, data, len) == RET_OK ? 0 : -1;
}
int i2c_init(uint8_t port, uint32_t speed_hz)
{
if (port >= 3)
return -1;
I2cConfig cfg;
cfg.speed_hz = speed_hz;
RetCode ret = i2c_instances[port]->init(cfg);
i2c_inited[port] = (ret == RET_OK) ? 1 : 0;
return i2c_inited[port] ? 0 : -1;
}
int i2c_master_write_read(uint8_t port, uint16_t dev_addr, const uint8_t *wdata, uint32_t wlen, uint8_t *rdata, uint32_t rlen)
{
if (port >= 3 || !i2c_inited[port]) return -1;
I2cDevice dev(dev_addr);
return i2c_instances[port]->master_write_read(dev, wdata, wlen, rdata, rlen) == RET_OK ? 0 : -1;
}
int i2c_master_write(uint8_t port, uint16_t dev_addr, const uint8_t *data, uint32_t len)
{
if (port >= 3 || !i2c_inited[port])
return -1;
I2cDevice dev(dev_addr);
return i2c_instances[port]->master_write(dev, data, len) == RET_OK ? 0 : -1;
}
int i2c_master_read(uint8_t port, uint16_t dev_addr, uint8_t *data, uint32_t len)
{
if (port >= 3 || !i2c_inited[port])
return -1;
I2cDevice dev(dev_addr);
return i2c_instances[port]->master_read(dev, data, len) == RET_OK ? 0 : -1;
}
int i2c_master_write_read(uint8_t port, uint16_t dev_addr, const uint8_t *wdata, uint32_t wlen, uint8_t *rdata, uint32_t rlen)
{
if (port >= 3 || !i2c_inited[port])
return -1;
I2cDevice dev(dev_addr);
return i2c_instances[port]->master_write_read(dev, wdata, wlen, rdata, rlen) == RET_OK ? 0 : -1;
}
} /* extern "C" */
@@ -89,7 +97,8 @@ I2cBus::I2cBus(I2cPort port)
I2cBus::~I2cBus()
{
if (initialized_) {
if (initialized_)
{
deinit();
}
}
@@ -97,12 +106,14 @@ I2cBus::~I2cBus()
RetCode I2cBus::init(const I2cConfig &config)
{
uint8_t port_idx = static_cast<uint8_t>(port_);
if (port_idx >= sizeof(i2c_hw_map) / sizeof(i2c_hw_map[0])) {
if (port_idx >= sizeof(i2c_hw_map) / sizeof(i2c_hw_map[0]))
{
return RET_INVALID_PARAM;
}
const i2c_hw_config_t &hw = i2c_hw_map[port_idx];
if (hw.i2c_periph == 0) {
if (hw.i2c_periph == 0)
{
return RET_NOT_SUPPORTED;
}
@@ -118,7 +129,8 @@ RetCode I2cBus::init(const I2cConfig &config)
i2c_deinit(hw.i2c_periph);
uint32_t speed = config.speed_hz;
if (speed == 0) {
if (speed == 0)
{
speed = 100000;
}
i2c_clock_config(hw.i2c_periph, speed, I2C_DTCY_2);
@@ -133,7 +145,8 @@ RetCode I2cBus::init(const I2cConfig &config)
RetCode I2cBus::deinit()
{
uint8_t port_idx = static_cast<uint8_t>(port_);
if (port_idx >= sizeof(i2c_hw_map) / sizeof(i2c_hw_map[0])) {
if (port_idx >= sizeof(i2c_hw_map) / sizeof(i2c_hw_map[0]))
{
return RET_INVALID_PARAM;
}
@@ -149,19 +162,23 @@ RetCode I2cBus::deinit()
static RetCode i2c_master_start(uint32_t i2c_periph, uint16_t addr, uint32_t direction)
{
uint32_t timeout = I2C_TIMEOUT;
while (i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)) {
if (--timeout == 0) {
while (i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY))
{
if (--timeout == 0)
{
return RET_TIMEOUT;
}
}
i2c_start_on_bus(i2c_periph);
if (wait_flag(i2c_periph, I2C_FLAG_SBSEND) != RET_OK) {
if (wait_flag(i2c_periph, I2C_FLAG_SBSEND) != RET_OK)
{
return RET_TIMEOUT;
}
i2c_master_addressing(i2c_periph, addr, direction);
if (wait_flag(i2c_periph, I2C_FLAG_ADDSEND) != RET_OK) {
if (wait_flag(i2c_periph, I2C_FLAG_ADDSEND) != RET_OK)
{
return RET_TIMEOUT;
}
@@ -172,30 +189,36 @@ static RetCode i2c_master_start(uint32_t i2c_periph, uint16_t addr, uint32_t dir
RetCode I2cBus::master_write(I2cDevice &dev, const uint8_t *data, uint32_t len)
{
if (data == nullptr || len == 0) {
if (data == nullptr || len == 0)
{
return RET_INVALID_PARAM;
}
if (!initialized_) return RET_NOT_INITIALIZED;
if (!initialized_)
return RET_NOT_INITIALIZED;
uint8_t port_idx = static_cast<uint8_t>(port_);
const i2c_hw_config_t &hw = i2c_hw_map[port_idx];
uint32_t i2c = hw.i2c_periph;
RetCode ret = i2c_master_start(i2c, dev.dev_addr_, I2C_TRANSMITTER);
if (ret != RET_OK) {
if (ret != RET_OK)
{
i2c_stop_on_bus(i2c);
return ret;
}
for (uint32_t i = 0; i < len; i++) {
if (wait_flag(i2c, I2C_FLAG_TBE) != RET_OK) {
for (uint32_t i = 0; i < len; i++)
{
if (wait_flag(i2c, I2C_FLAG_TBE) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
i2c_data_transmit(i2c, data[i]);
}
if (wait_flag(i2c, I2C_FLAG_TBE) != RET_OK) {
if (wait_flag(i2c, I2C_FLAG_TBE) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
@@ -206,34 +229,43 @@ RetCode I2cBus::master_write(I2cDevice &dev, const uint8_t *data, uint32_t len)
RetCode I2cBus::master_read(I2cDevice &dev, uint8_t *data, uint32_t len)
{
if (data == nullptr || len == 0) {
if (data == nullptr || len == 0)
{
return RET_INVALID_PARAM;
}
if (!initialized_) return RET_NOT_INITIALIZED;
if (!initialized_)
return RET_NOT_INITIALIZED;
uint8_t port_idx = static_cast<uint8_t>(port_);
const i2c_hw_config_t &hw = i2c_hw_map[port_idx];
uint32_t i2c = hw.i2c_periph;
if (len == 1) {
if (len == 1)
{
i2c_ack_config(i2c, I2C_ACK_DISABLE);
} else {
}
else
{
i2c_ack_config(i2c, I2C_ACK_ENABLE);
}
RetCode ret = i2c_master_start(i2c, dev.dev_addr_, I2C_RECEIVER);
if (ret != RET_OK) {
if (ret != RET_OK)
{
i2c_stop_on_bus(i2c);
return ret;
}
for (uint32_t i = 0; i < len; i++) {
if (i == len - 1) {
for (uint32_t i = 0; i < len; i++)
{
if (i == len - 1)
{
i2c_ack_config(i2c, I2C_ACK_DISABLE);
i2c_stop_on_bus(i2c);
}
if (wait_flag(i2c, I2C_FLAG_RBNE) != RET_OK) {
if (wait_flag(i2c, I2C_FLAG_RBNE) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
@@ -245,18 +277,95 @@ RetCode I2cBus::master_read(I2cDevice &dev, uint8_t *data, uint32_t len)
RetCode I2cBus::master_write_read(I2cDevice &dev, const uint8_t *wdata, uint32_t wlen, uint8_t *rdata, uint32_t rlen)
{
if (wlen > 0) {
RetCode ret = master_write(dev, wdata, wlen);
if (ret != RET_OK) {
return ret;
}
if (wdata == nullptr || wlen == 0 || rdata == nullptr || rlen == 0)
{
return RET_INVALID_PARAM;
}
if (!initialized_)
return RET_NOT_INITIALIZED;
uint8_t port_idx = static_cast<uint8_t>(port_);
const i2c_hw_config_t &hw = i2c_hw_map[port_idx];
uint32_t i2c = hw.i2c_periph;
// === 写阶段:发送寄存器地址(不发 STOP) ===
uint32_t timeout = I2C_TIMEOUT;
while (i2c_flag_get(i2c, I2C_FLAG_I2CBSY))
{
if (--timeout == 0)
return RET_TIMEOUT;
}
if (rlen > 0) {
RetCode ret = master_read(dev, rdata, rlen);
if (ret != RET_OK) {
return ret;
i2c_start_on_bus(i2c);
if (wait_flag(i2c, I2C_FLAG_SBSEND) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
i2c_master_addressing(i2c, dev.dev_addr_, I2C_TRANSMITTER);
if (wait_flag(i2c, I2C_FLAG_ADDSEND) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
i2c_flag_clear(i2c, I2C_FLAG_ADDSEND);
for (uint32_t i = 0; i < wlen; i++)
{
if (wait_flag(i2c, I2C_FLAG_TBE) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
i2c_data_transmit(i2c, wdata[i]);
}
if (wait_flag(i2c, I2C_FLAG_TBE) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
// === 读阶段:以重复起始条件开始(无 STOP 间隔) ===
if (rlen == 1)
{
i2c_ack_config(i2c, I2C_ACK_DISABLE);
}
else
{
i2c_ack_config(i2c, I2C_ACK_ENABLE);
}
i2c_start_on_bus(i2c);
if (wait_flag(i2c, I2C_FLAG_SBSEND) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
i2c_master_addressing(i2c, dev.dev_addr_, I2C_RECEIVER);
if (wait_flag(i2c, I2C_FLAG_ADDSEND) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
i2c_flag_clear(i2c, I2C_FLAG_ADDSEND);
for (uint32_t i = 0; i < rlen; i++)
{
if (i == rlen - 1)
{
i2c_ack_config(i2c, I2C_ACK_DISABLE);
i2c_stop_on_bus(i2c);
}
if (wait_flag(i2c, I2C_FLAG_RBNE) != RET_OK)
{
i2c_stop_on_bus(i2c);
return RET_TIMEOUT;
}
rdata[i] = i2c_data_receive(i2c);
}
return RET_OK;
+13
View File
@@ -46,4 +46,17 @@ private:
bool initialized_ = false;
};
#ifdef __cplusplus
extern "C" {
#endif
int i2c_init(uint8_t port, uint32_t speed_hz);
int i2c_master_write(uint8_t port, uint16_t dev_addr, const uint8_t *data, uint32_t len);
int i2c_master_read(uint8_t port, uint16_t dev_addr, uint8_t *data, uint32_t len);
int i2c_master_write_read(uint8_t port, uint16_t dev_addr, const uint8_t *wdata, uint32_t wlen, uint8_t *rdata, uint32_t rlen);
#ifdef __cplusplus
}
#endif
#endif
+2
View File
@@ -63,6 +63,8 @@ void DebugMon_Handler(void);
void PendSV_Handler(void);
/* this function handles SysTick exception */
void SysTick_Handler(void);
/* this function handles EXTI10-15 exception */
void EXTI10_15_IRQHandler(void);
#ifdef __cplusplus
}