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:
+180
-71
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user