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:
+104
-1
@@ -6,6 +6,7 @@
|
||||
#include "sdram_manager.h"
|
||||
#include "flash_manager.h"
|
||||
#include "lcd.h"
|
||||
#include "touch.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
@@ -346,7 +347,106 @@ static void concurrent_loop(void)
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
// 主函数
|
||||
// Touch 测试
|
||||
// =============================================================
|
||||
|
||||
static void test_touch(void)
|
||||
{
|
||||
printf("\r\n===== Touch 测试 (中断驱动) =====\r\n");
|
||||
|
||||
uint8_t ret = GT1151_Init();
|
||||
if (ret != 0)
|
||||
{
|
||||
printf(" Touch 初始化失败 (ret=%d)\r\n", ret);
|
||||
return;
|
||||
}
|
||||
printf(" Touch 初始化成功,等待触摸中断...\r\n");
|
||||
|
||||
LCD_Clear(0x0841);
|
||||
POINT_COLOR = CYAN;
|
||||
LCD_ShowString(10, 10, 460, 24, 16, 0, (uint8_t *)"=== Touch Test (IRQ) ===");
|
||||
POINT_COLOR = WHITE;
|
||||
LCD_ShowString(10, 35, 460, 24, 16, 0, (uint8_t *)"Touch screen now");
|
||||
LCD_ShowString(10, 55, 300, 24, 16, 0, (uint8_t *)"IRQ driven, watch UART");
|
||||
LCD_ShowString(10, 75, 200, 24, 16, 0, (uint8_t *)"X:0 Y:0");
|
||||
|
||||
uint16_t last_x = 0xFFFF;
|
||||
uint16_t last_y = 0xFFFF;
|
||||
uint32_t idle_counter = 0;
|
||||
bool was_touching = false;
|
||||
uint32_t iter = 0;
|
||||
|
||||
g_touch_irq_flag = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (g_touch_irq_flag)
|
||||
{
|
||||
g_touch_irq_flag = 0;
|
||||
delay_1ms(5);
|
||||
|
||||
GT1151_Scan(0);
|
||||
|
||||
if (tp_dev.sta & TP_PRES_DOWN)
|
||||
{
|
||||
idle_counter = 0;
|
||||
uint16_t x = tp_dev.x[0];
|
||||
uint16_t y = tp_dev.y[0];
|
||||
|
||||
printf("[TOUCH] iter=%lu sta=0x%02X x=%u y=%u\r\n",
|
||||
(unsigned long)iter, tp_dev.sta, x, y);
|
||||
|
||||
if (x < lcddev.width && y < lcddev.height)
|
||||
{
|
||||
POINT_COLOR = BLACK;
|
||||
LCD_FillRectangle(10, 75, 200, 95);
|
||||
POINT_COLOR = GREEN;
|
||||
char buf[24];
|
||||
sprintf(buf, "X:%-3d Y:%-3d", x, y);
|
||||
LCD_ShowString(10, 75, 200, 24, 16, 0, (uint8_t *)buf);
|
||||
|
||||
if (was_touching && last_x != 0xFFFF)
|
||||
{
|
||||
POINT_COLOR = MAGENTA;
|
||||
LCD_DrawLine(last_x, last_y, x, y);
|
||||
}
|
||||
|
||||
POINT_COLOR = YELLOW;
|
||||
LCD_FillCircle(x, y, 4);
|
||||
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
was_touching = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
was_touching = false;
|
||||
last_x = 0xFFFF;
|
||||
last_y = 0xFFFF;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
idle_counter++;
|
||||
delay_1ms(10);
|
||||
if (idle_counter > 500)
|
||||
{
|
||||
printf(" 无触摸超过 5 秒,退出 Touch 测试\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LCD_Clear(BLUE);
|
||||
printf(" Touch 测试完成\r\n");
|
||||
delay_1ms(500);
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
// 主函数
|
||||
// =============================================================
|
||||
int main(void)
|
||||
{
|
||||
@@ -438,6 +538,9 @@ int main(void)
|
||||
concurrent_loop();
|
||||
delay_1ms(500);
|
||||
|
||||
test_touch();
|
||||
delay_1ms(500);
|
||||
|
||||
// ---- 主循环 ----
|
||||
led_pattern(0x0F);
|
||||
printf("\r\n===== 所有外设测试完成 =====\r\n");
|
||||
|
||||
+218
-336
@@ -1,383 +1,265 @@
|
||||
#include "touch.h"
|
||||
#include "i2c_driver.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
|
||||
|
||||
_m_tp_dev tp_dev;
|
||||
|
||||
volatile uint8_t g_touch_irq_flag = 0;
|
||||
|
||||
void delay_1us(uint16_t us)
|
||||
#define TOUCH_I2C_PORT 0
|
||||
#define TOUCH_DEV_ADDR 0x28
|
||||
|
||||
uint8_t GT1151_WR_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
while(us--)
|
||||
uint8_t tmp[2 + 256];
|
||||
tmp[0] = (uint8_t)(reg >> 8);
|
||||
tmp[1] = (uint8_t)(reg & 0xFF);
|
||||
for (uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
tmp[2 + i] = buf[i];
|
||||
}
|
||||
int ret = i2c_master_write(TOUCH_I2C_PORT, TOUCH_DEV_ADDR, tmp, 2 + len);
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
void CT_Delay(void)
|
||||
void GT1151_RD_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
delay_1us(2);
|
||||
uint8_t reg_bytes[2];
|
||||
reg_bytes[0] = (uint8_t)(reg >> 8);
|
||||
reg_bytes[1] = (uint8_t)(reg & 0xFF);
|
||||
i2c_master_write_read(TOUCH_I2C_PORT, TOUCH_DEV_ADDR, reg_bytes, 2, buf, len);
|
||||
}
|
||||
|
||||
void CT_IIC_Init(void)
|
||||
{
|
||||
rcu_periph_clock_enable(SCL_RCU);
|
||||
gpio_mode_set(SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,SCL_PIN);
|
||||
gpio_output_options_set(SCL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SCL_PIN);
|
||||
|
||||
rcu_periph_clock_enable(SDA_RCU);
|
||||
gpio_mode_set(SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,SDA_PIN);
|
||||
gpio_output_options_set(SDA_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SDA_PIN);
|
||||
|
||||
}
|
||||
|
||||
void CT_IIC_Start(void)
|
||||
{
|
||||
CT_SDA_OUT();
|
||||
SDA_ON;
|
||||
SCL_ON;
|
||||
delay_1us(30);
|
||||
SDA_OFF;
|
||||
CT_Delay();
|
||||
SCL_OFF;
|
||||
}
|
||||
|
||||
void CT_IIC_Stop(void)
|
||||
{
|
||||
CT_SDA_OUT();
|
||||
SCL_ON;
|
||||
delay_1us(30);
|
||||
SDA_OFF;
|
||||
CT_Delay();
|
||||
SDA_ON;
|
||||
}
|
||||
|
||||
uint8_t CT_IIC_Wait_Ack(void)
|
||||
{
|
||||
uint8_t ucErrTime=0;
|
||||
CT_SDA_IN();
|
||||
SDA_ON;
|
||||
SCL_ON;
|
||||
CT_Delay();
|
||||
while(CT_READ_SDA)
|
||||
{
|
||||
ucErrTime++;
|
||||
if(ucErrTime>250)
|
||||
{
|
||||
CT_IIC_Stop();
|
||||
return 1;
|
||||
}
|
||||
CT_Delay();
|
||||
}
|
||||
SCL_OFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CT_IIC_Ack(void)
|
||||
{
|
||||
SCL_OFF;
|
||||
CT_SDA_OUT();
|
||||
CT_Delay();
|
||||
SDA_OFF;
|
||||
CT_Delay();
|
||||
SCL_ON;
|
||||
CT_Delay();
|
||||
SCL_OFF;
|
||||
}
|
||||
|
||||
void CT_IIC_NAck(void)
|
||||
{
|
||||
SCL_OFF;
|
||||
CT_SDA_OUT();
|
||||
CT_Delay();
|
||||
SDA_ON;
|
||||
CT_Delay();
|
||||
SCL_ON;
|
||||
CT_Delay();
|
||||
SCL_OFF;
|
||||
}
|
||||
|
||||
void CT_IIC_Send_Byte(uint8_t txd)
|
||||
{
|
||||
uint8_t t;
|
||||
CT_SDA_OUT();
|
||||
SCL_OFF;
|
||||
CT_Delay();
|
||||
for(t=0;t<8;t++)
|
||||
const uint8_t GT1151_CFG_TBL[] =
|
||||
{
|
||||
if((txd&0x80)>>7)
|
||||
{
|
||||
gpio_bit_set(SDA_PORT,SDA_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_bit_reset(SDA_PORT,SDA_PIN);
|
||||
}
|
||||
0x63, 0xE0, 0x01, 0x20, 0x03, 0x05, 0x3D, 0x04, 0x00, 0x08,
|
||||
0x09, 0x0F, 0x55, 0x37, 0x33, 0x11, 0x00, 0x03, 0x08, 0x56,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00,
|
||||
0x3C, 0x08, 0x0A, 0x28, 0x1E, 0x50, 0x00, 0x00, 0x82, 0xB4,
|
||||
0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x85, 0x25, 0x10, 0x41, 0x43, 0x31,
|
||||
0x0D, 0x00, 0xAD, 0x22, 0x24, 0x7D, 0x1D, 0x1D, 0x32, 0xDF,
|
||||
0x4F, 0x44, 0x0F, 0x80, 0x2C, 0x50, 0x50, 0x00, 0x00, 0x00,
|
||||
0x00, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x28, 0x1E, 0xFF,
|
||||
0xF0, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x50, 0xB4, 0xC0, 0x94, 0x53, 0x2D,
|
||||
0x0A, 0x02, 0xBE, 0x60, 0xA2, 0x71, 0x8F, 0x82, 0x80, 0x92,
|
||||
0x74, 0xA3, 0x6B, 0x01, 0x0F, 0x14, 0x03, 0x1E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0E, 0x0F, 0x10, 0x12,
|
||||
0x13, 0x14, 0x15, 0x1F, 0x1D, 0x1B, 0x1A, 0x19, 0x18, 0x17,
|
||||
0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x08, 0x0C,
|
||||
0x12, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
0xC4, 0x09, 0x23, 0x23, 0x50, 0x5D, 0x54, 0x4B, 0x3C, 0x0F,
|
||||
0x32, 0xFF, 0xE4, 0x04, 0x40, 0x00, 0x8A, 0x05, 0x40, 0x00,
|
||||
0xAA, 0x00, 0x22, 0x22, 0x00, 0x00, 0x73, 0x22, 0x01};
|
||||
|
||||
txd<<=1;
|
||||
SCL_ON;
|
||||
CT_Delay();
|
||||
SCL_OFF;
|
||||
CT_Delay();
|
||||
uint16_t CRC16(uint8_t *srcdata, uint16_t length)
|
||||
{
|
||||
uint16_t crc = 0xffff;
|
||||
uint16_t i, j;
|
||||
uint8_t value;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
value = ((srcdata[i] << j) & 0x80) ^ ((crc & 0x8000) >> 8);
|
||||
crc <<= 1;
|
||||
if (value != 0)
|
||||
{
|
||||
crc ^= 0x8005;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t CT_IIC_Read_Byte(unsigned char ack)
|
||||
{
|
||||
uint8_t i,receive=0;
|
||||
CT_SDA_IN();
|
||||
delay_1us(30);
|
||||
for(i=0;i<8;i++ )
|
||||
{
|
||||
SCL_OFF;
|
||||
CT_Delay();
|
||||
SCL_ON;
|
||||
receive<<=1;
|
||||
|
||||
if(CT_READ_SDA)receive++;
|
||||
}
|
||||
|
||||
if (!ack)CT_IIC_NAck();
|
||||
else CT_IIC_Ack();
|
||||
return receive;
|
||||
}
|
||||
|
||||
const uint8_t GT1151_CFG_TBL[]=
|
||||
{
|
||||
0x63,0xE0,0x01,0x20,0x03,0x05,0x3D,0x04,0x00,0x08,
|
||||
0x09,0x0F,0x55,0x37,0x33,0x11,0x00,0x03,0x08,0x56,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,
|
||||
0x3C,0x08,0x0A,0x28,0x1E,0x50,0x00,0x00,0x82,0xB4,
|
||||
0xD2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x85,0x25,0x10,0x41,0x43,0x31,
|
||||
0x0D,0x00,0xAD,0x22,0x24,0x7D,0x1D,0x1D,0x32,0xDF,
|
||||
0x4F,0x44,0x0F,0x80,0x2C,0x50,0x50,0x00,0x00,0x00,
|
||||
0x00,0xD3,0x00,0x00,0x00,0x00,0x0F,0x28,0x1E,0xFF,
|
||||
0xF0,0x37,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x50,0xB4,0xC0,0x94,0x53,0x2D,
|
||||
0x0A,0x02,0xBE,0x60,0xA2,0x71,0x8F,0x82,0x80,0x92,
|
||||
0x74,0xA3,0x6B,0x01,0x0F,0x14,0x03,0x1E,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x0D,0x0E,0x0F,0x10,0x12,
|
||||
0x13,0x14,0x15,0x1F,0x1D,0x1B,0x1A,0x19,0x18,0x17,
|
||||
0x16,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x06,0x08,0x0C,
|
||||
0x12,0x13,0x14,0x15,0x17,0x18,0x19,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
|
||||
0xC4,0x09,0x23,0x23,0x50,0x5D,0x54,0x4B,0x3C,0x0F,
|
||||
0x32,0xFF,0xE4,0x04,0x40,0x00,0x8A,0x05,0x40,0x00,
|
||||
0xAA,0x00,0x22,0x22,0x00,0x00,0x73,0x22,0x01
|
||||
};
|
||||
|
||||
uint16_t CRC16(uint8_t *srcdata,uint16_t length)
|
||||
{
|
||||
uint16_t crc=0xffff;
|
||||
uint16_t i,j;
|
||||
uint8_t value;
|
||||
for(i=0;i<length;i++)
|
||||
{
|
||||
for(j=0;j<8;j++)
|
||||
{
|
||||
value=((srcdata[i]<<j)&0x80)^((crc&0x8000)>>8);
|
||||
crc<<=1;
|
||||
if(value!=0)
|
||||
{
|
||||
crc^=0x8005;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
return crc;
|
||||
}
|
||||
|
||||
void check_sum(void)
|
||||
{
|
||||
uint16_t checksum=0;
|
||||
uint8_t checksumH,checksumL;
|
||||
uint8_t i=0;
|
||||
for(i=0;i<(sizeof(GT1151_CFG_TBL)-3);i+=2)
|
||||
checksum +=((GT1151_CFG_TBL[i]<<8)|GT1151_CFG_TBL[i+1]);
|
||||
checksum =(~checksum)+1;
|
||||
checksumH=checksum>>8;
|
||||
checksumL=checksum;
|
||||
printf("chksum:0x%X,\r\n",checksum);
|
||||
printf("chksumH:0x%X,\r\n",checksumH);
|
||||
printf("chksumL:0x%X,\r\n",checksumL);
|
||||
uint16_t checksum = 0;
|
||||
uint8_t checksumH, checksumL;
|
||||
uint8_t i = 0;
|
||||
for (i = 0; i < (sizeof(GT1151_CFG_TBL) - 3); i += 2)
|
||||
checksum += ((GT1151_CFG_TBL[i] << 8) | GT1151_CFG_TBL[i + 1]);
|
||||
checksum = (~checksum) + 1;
|
||||
checksumH = checksum >> 8;
|
||||
checksumL = checksum;
|
||||
printf("chksum:0x%X,\r\n", checksum);
|
||||
printf("chksumH:0x%X,\r\n", checksumH);
|
||||
printf("chksumL:0x%X,\r\n", checksumL);
|
||||
}
|
||||
|
||||
uint8_t GT1151_Send_Cfg(uint8_t mode)
|
||||
{
|
||||
uint16_t checksum=0;
|
||||
uint8_t i=0;
|
||||
for(i=0;i<(sizeof(GT1151_CFG_TBL)-3);i+=2)
|
||||
checksum +=((GT1151_CFG_TBL[i]<<8)|GT1151_CFG_TBL[i+1]);
|
||||
checksum =(~checksum)+1;
|
||||
printf("chksum:0x%x,\r\n",checksum);
|
||||
GT1151_WR_Reg(GT_CFGS_REG,(uint8_t*)GT1151_CFG_TBL,sizeof(GT1151_CFG_TBL));
|
||||
return 0;
|
||||
uint16_t checksum = 0;
|
||||
uint8_t i = 0;
|
||||
for (i = 0; i < (sizeof(GT1151_CFG_TBL) - 3); i += 2)
|
||||
checksum += ((GT1151_CFG_TBL[i] << 8) | GT1151_CFG_TBL[i + 1]);
|
||||
checksum = (~checksum) + 1;
|
||||
printf("chksum:0x%x,\r\n", checksum);
|
||||
GT1151_WR_Reg(GT_CFGS_REG, (uint8_t *)GT1151_CFG_TBL, sizeof(GT1151_CFG_TBL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t GT1151_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
|
||||
static void GT1151_EXTI_Init(void)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t ret=0;
|
||||
CT_IIC_Start();
|
||||
CT_IIC_Send_Byte(GT_CMD_WR);
|
||||
CT_IIC_Wait_Ack();
|
||||
CT_IIC_Send_Byte(reg>>8);
|
||||
CT_IIC_Wait_Ack();
|
||||
CT_IIC_Send_Byte(reg&0XFF);
|
||||
CT_IIC_Wait_Ack();
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
CT_IIC_Send_Byte(buf[i]);
|
||||
ret=CT_IIC_Wait_Ack();
|
||||
if(ret)break;
|
||||
}
|
||||
CT_IIC_Stop();
|
||||
return ret;
|
||||
rcu_periph_clock_enable(RCU_SYSCFG);
|
||||
|
||||
syscfg_exti_line_config(EXTI_SOURCE_GPIOD, EXTI_SOURCE_PIN11);
|
||||
|
||||
exti_init(TOUCH_EXTI_LINE, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
|
||||
|
||||
exti_interrupt_enable(TOUCH_EXTI_LINE);
|
||||
|
||||
nvic_irq_enable(TOUCH_EXTI_IRQn, 2, 0);
|
||||
}
|
||||
|
||||
void GT1151_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
CT_IIC_Start();
|
||||
CT_IIC_Send_Byte(GT_CMD_WR);
|
||||
CT_IIC_Wait_Ack();
|
||||
CT_IIC_Send_Byte(reg>>8);
|
||||
CT_IIC_Wait_Ack();
|
||||
CT_IIC_Send_Byte(reg&0XFF);
|
||||
CT_IIC_Wait_Ack();
|
||||
CT_IIC_Start();
|
||||
CT_IIC_Send_Byte(GT_CMD_RD);
|
||||
CT_IIC_Wait_Ack();
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1);
|
||||
}
|
||||
CT_IIC_Stop();
|
||||
}
|
||||
|
||||
uint8_t Cfg_Info1[239] = {0};
|
||||
uint8_t GT1151_Init(void)
|
||||
{
|
||||
uint8_t temp[6]={0};
|
||||
uint8_t i=0;
|
||||
uint8_t temp[6] = {0};
|
||||
uint8_t retry = 3;
|
||||
|
||||
// RST_PIN (PD12) 与 LCD 共享,LCD_Init 已完成硬件复位
|
||||
// 通过 INT 引脚对 GT1151 做 I2C 复位握手
|
||||
|
||||
rcu_periph_clock_enable(INT_RCU);
|
||||
gpio_mode_set(INT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,INT_PIN);
|
||||
gpio_output_options_set(INT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,INT_PIN);
|
||||
gpio_mode_set(INT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, INT_PIN);
|
||||
gpio_output_options_set(INT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, INT_PIN);
|
||||
gpio_bit_reset(INT_PORT, INT_PIN);
|
||||
delay_1ms(20);
|
||||
|
||||
CT_IIC_Init();
|
||||
gpio_mode_set(INT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE,INT_PIN);
|
||||
// 初始化硬件 I2C0 (PB6=SCL, PB7=SDA)
|
||||
i2c_init(TOUCH_I2C_PORT, 100000);
|
||||
|
||||
delay_1ms(100);
|
||||
// 释放 INT(设为浮空输入),等待 GT1151 就绪
|
||||
gpio_mode_set(INT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, INT_PIN);
|
||||
delay_1ms(150);
|
||||
|
||||
GT1151_RD_Reg(GT_PID_REG,temp,4);
|
||||
// 读取产品 ID,带重试
|
||||
do
|
||||
{
|
||||
GT1151_RD_Reg(GT_PID_REG, temp, 4);
|
||||
if (temp[0] != 0 && temp[0] != 0xFF)
|
||||
break;
|
||||
delay_1ms(50);
|
||||
} while (--retry > 0);
|
||||
|
||||
printf("CTP ID:GT%s\r\n",temp);
|
||||
printf("CTP ID: GT%s\r\n", temp);
|
||||
|
||||
check_sum();
|
||||
if (strcmp((char *)temp, "1158") == 0 || strcmp((char *)temp, "1151") == 0)
|
||||
{
|
||||
GT1151_RD_Reg(GT_CFGS_REG, temp, 1);
|
||||
printf("GT Config Version: 0x%02X\r\n", temp[0]);
|
||||
|
||||
if(strcmp((char*)temp,"1158")==0)
|
||||
{
|
||||
GT1151_RD_Reg(GT_CFGS_REG,temp,1);
|
||||
printf("Default Ver:0x%x\r\n",temp[0]);
|
||||
GT1151_Send_Cfg(0);
|
||||
delay_1ms(50);
|
||||
|
||||
#if 1
|
||||
GT1151_RD_Reg(0x8050,Cfg_Info1,239);
|
||||
printf("Config Info:\r\n");
|
||||
for( i = 0; i < 239; i++ )
|
||||
{
|
||||
printf("0x%02X,",Cfg_Info1[i]);
|
||||
if((i+1)%10==0)
|
||||
printf("\r\n");
|
||||
}
|
||||
printf("\r\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
GT1151_EXTI_Init();
|
||||
printf("GT EXTI initialized\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("GT Init: unknown ID, will still attempt to use touch\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const uint16_t GT1151_TPX_TBL[5]={GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};
|
||||
const uint16_t GT1151_TPX_TBL[5] = {GT_TP1_REG, GT_TP2_REG, GT_TP3_REG, GT_TP4_REG, GT_TP5_REG};
|
||||
|
||||
uint8_t GT1151_Scan(uint8_t mode)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
uint8_t i=0;
|
||||
uint8_t res=0;
|
||||
uint8_t temp;
|
||||
uint8_t tempsta;
|
||||
static uint8_t t=0;
|
||||
t++;
|
||||
if((t%10)==0||t<10)
|
||||
{
|
||||
GT1151_RD_Reg(GT_GSTID_REG,&mode,1);
|
||||
if(mode&0X80&&((mode&0XF)<6))
|
||||
{
|
||||
temp=0;
|
||||
GT1151_WR_Reg(GT_GSTID_REG,&temp,1);
|
||||
}
|
||||
if((mode&0XF)&&((mode&0XF)<6))
|
||||
{
|
||||
temp=0XFF<<(mode&0XF);
|
||||
tempsta=tp_dev.sta;
|
||||
tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES;
|
||||
tp_dev.x[4]=tp_dev.x[0];
|
||||
tp_dev.y[4]=tp_dev.y[0];
|
||||
for(i=0;i<5;i++)
|
||||
{
|
||||
if(tp_dev.sta&(1<<i))
|
||||
{
|
||||
GT1151_RD_Reg(GT1151_TPX_TBL[i],buf,4);
|
||||
if(tp_dev.touchtype&0X01)
|
||||
{
|
||||
tp_dev.x[i]=((uint16_t)buf[1]<<8)+buf[0];
|
||||
tp_dev.y[i]=((uint16_t)buf[3]<<8)+buf[2];
|
||||
}else
|
||||
{
|
||||
tp_dev.x[i]=((uint16_t)buf[1]<<8)+buf[0];
|
||||
tp_dev.y[i]=((uint16_t)buf[3]<<8)+buf[2];
|
||||
}
|
||||
if(tp_dev.x[i]>0&&tp_dev.x[i]<480&&tp_dev.y[i]>0&&tp_dev.y[i]<800)
|
||||
printf("x[%d]:%d,y[%d]:%d\r\n",i,tp_dev.x[i],i,tp_dev.y[i]);
|
||||
}
|
||||
}
|
||||
res=1;
|
||||
if(tp_dev.x[0]>1024||tp_dev.y[0]>1024)
|
||||
{
|
||||
if((mode&0XF)>1)
|
||||
{
|
||||
tp_dev.x[0]=tp_dev.x[1];
|
||||
tp_dev.y[0]=tp_dev.y[1];
|
||||
t=0;
|
||||
}else
|
||||
{
|
||||
tp_dev.x[0]=tp_dev.x[4];
|
||||
tp_dev.y[0]=tp_dev.y[4];
|
||||
mode=0X80;
|
||||
tp_dev.sta=tempsta;
|
||||
}
|
||||
}else t=0;
|
||||
}
|
||||
}
|
||||
if((mode&0X8F)==0X80)
|
||||
{
|
||||
if(tp_dev.sta&TP_PRES_DOWN)
|
||||
{
|
||||
tp_dev.sta&=~(1<<7);
|
||||
}else
|
||||
{
|
||||
tp_dev.x[0]=0xffff;
|
||||
tp_dev.y[0]=0xffff;
|
||||
tp_dev.sta&=0XE0;
|
||||
}
|
||||
}
|
||||
if(t>240)t=10;
|
||||
return res;
|
||||
uint8_t buf[4];
|
||||
uint8_t i = 0;
|
||||
uint8_t res = 0;
|
||||
uint8_t temp;
|
||||
uint8_t tempsta;
|
||||
static uint8_t t = 0;
|
||||
t++;
|
||||
if ((t % 10) == 0 || t < 10)
|
||||
{
|
||||
GT1151_RD_Reg(GT_GSTID_REG, &mode, 1);
|
||||
if (mode & 0X80 && ((mode & 0XF) < 6))
|
||||
{
|
||||
temp = 0;
|
||||
GT1151_WR_Reg(GT_GSTID_REG, &temp, 1);
|
||||
}
|
||||
if ((mode & 0XF) && ((mode & 0XF) < 6))
|
||||
{
|
||||
temp = 0XFF << (mode & 0XF);
|
||||
tempsta = tp_dev.sta;
|
||||
tp_dev.sta = (~temp) | TP_PRES_DOWN | TP_CATH_PRES;
|
||||
tp_dev.x[4] = tp_dev.x[0];
|
||||
tp_dev.y[4] = tp_dev.y[0];
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (tp_dev.sta & (1 << i))
|
||||
{
|
||||
GT1151_RD_Reg(GT1151_TPX_TBL[i], buf, 4);
|
||||
if (tp_dev.touchtype & 0X01)
|
||||
{
|
||||
tp_dev.x[i] = ((uint16_t)buf[1] << 8) + buf[0];
|
||||
tp_dev.y[i] = ((uint16_t)buf[3] << 8) + buf[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
tp_dev.x[i] = ((uint16_t)buf[1] << 8) + buf[0];
|
||||
tp_dev.y[i] = ((uint16_t)buf[3] << 8) + buf[2];
|
||||
}
|
||||
if (tp_dev.x[i] > 0 && tp_dev.x[i] < 480 && tp_dev.y[i] > 0 && tp_dev.y[i] < 800)
|
||||
printf("x[%d]:%d,y[%d]:%d\r\n", i, tp_dev.x[i], i, tp_dev.y[i]);
|
||||
}
|
||||
}
|
||||
res = 1;
|
||||
if (tp_dev.x[0] > 1024 || tp_dev.y[0] > 1024)
|
||||
{
|
||||
if ((mode & 0XF) > 1)
|
||||
{
|
||||
tp_dev.x[0] = tp_dev.x[1];
|
||||
tp_dev.y[0] = tp_dev.y[1];
|
||||
t = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp_dev.x[0] = tp_dev.x[4];
|
||||
tp_dev.y[0] = tp_dev.y[4];
|
||||
mode = 0X80;
|
||||
tp_dev.sta = tempsta;
|
||||
}
|
||||
}
|
||||
else
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
if ((mode & 0X8F) == 0X80)
|
||||
{
|
||||
if (tp_dev.sta & TP_PRES_DOWN)
|
||||
{
|
||||
tp_dev.sta &= ~(1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp_dev.x[0] = 0xffff;
|
||||
tp_dev.y[0] = 0xffff;
|
||||
tp_dev.sta &= 0XE0;
|
||||
}
|
||||
}
|
||||
if (t > 240)
|
||||
t = 10;
|
||||
return res;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void EXTI10_15_IRQHandler(void)
|
||||
{
|
||||
if (exti_flag_get(TOUCH_EXTI_LINE) == SET)
|
||||
{
|
||||
g_touch_irq_flag = 1;
|
||||
exti_flag_clear(TOUCH_EXTI_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+43
-56
@@ -21,87 +21,74 @@
|
||||
#define SDA_OFF gpio_bit_reset(SDA_PORT,SDA_PIN)
|
||||
#define SDA_TOGGLE gpio_bit_toggle(SDA_PORT,SDA_PIN)
|
||||
|
||||
//IO方向设置
|
||||
#define CT_SDA_IN() gpio_mode_set(SCL_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP,SDA_PIN);//{GPIOF->MODER&=~(3<<(2*11));GPIOF->MODER|=0<<2*11;} //PF11输入模式
|
||||
#define CT_SDA_OUT() gpio_mode_set(SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,SDA_PIN);//{GPIOF->MODER&=~(3<<(2*11));GPIOF->MODER|=1<<2*11;} //PF11输出模式
|
||||
//IO操作函数
|
||||
//IO方向设置
|
||||
#define CT_SDA_IN() gpio_mode_set(SDA_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, SDA_PIN)
|
||||
#define CT_SDA_OUT() gpio_mode_set(SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, SDA_PIN)
|
||||
//IO操作函数
|
||||
#define CT_IIC_SCL //PBout(0) //SCL
|
||||
#define CT_IIC_SDA(val) ((val)==1?SDA_ON:SDA_OFF)//PFout(11) //SDA
|
||||
#define CT_READ_SDA gpio_input_bit_get(SDA_PORT,SDA_PIN) //PFin(11) //输入SDA
|
||||
#define CT_READ_SDA gpio_input_bit_get(SDA_PORT,SDA_PIN) //PFin(11) //输入SDA
|
||||
|
||||
#define RST_RCU RCU_GPIOD
|
||||
#define RST_PORT GPIOD
|
||||
#define RST_PIN GPIO_PIN_12
|
||||
#define RST_ON gpio_bit_set(RST_PORT,RST_PIN);
|
||||
#define RST_OFF gpio_bit_reset(RST_PORT,RST_PIN);
|
||||
#define RST_TOGGLE gpio_bit_toggle(RST_PORT,RST_PIN);
|
||||
#define RST_ON gpio_bit_set(RST_PORT,RST_PIN)
|
||||
#define RST_OFF gpio_bit_reset(RST_PORT,RST_PIN)
|
||||
#define RST_TOGGLE gpio_bit_toggle(RST_PORT,RST_PIN)
|
||||
|
||||
#define INT_RCU RCU_GPIOD
|
||||
#define INT_PORT GPIOD
|
||||
#define INT_PIN GPIO_PIN_11
|
||||
#define INT_ON gpio_bit_set(INT_PORT,INT_PIN);
|
||||
#define INT_OFF gpio_bit_reset(INT_PORT,INT_PIN);
|
||||
#define INT_TOGGLE gpio_bit_toggle(INT_PORT,INT_PIN);
|
||||
|
||||
//I2C读写命令
|
||||
#define GT_CMD_WR 0X28 //写命令
|
||||
#define GT_CMD_RD 0X29 //读命令
|
||||
|
||||
//GT1151 部分寄存器定义
|
||||
#define GT_CTRL_REG 0X8040 //GT1151控制寄存器
|
||||
#define GT_CFGS_REG 0X8050 //GT1151地址寄存器
|
||||
#define GT_CHECK_REG 0X813C //GT1151验和寄存器
|
||||
#define GT_PID_REG 0X8140 //GT1151产品ID寄存器
|
||||
#define INT_ON gpio_bit_set(INT_PORT,INT_PIN)
|
||||
#define INT_OFF gpio_bit_reset(INT_PORT,INT_PIN)
|
||||
#define INT_TOGGLE gpio_bit_toggle(INT_PORT,INT_PIN)
|
||||
|
||||
#define GT_GSTID_REG 0X814E //GT1151前检测到的触摸情况
|
||||
#define GT_TP1_REG 0X8150 //第一个触摸点数据地址
|
||||
#define GT_TP2_REG 0X8158 //第二个触摸点数据地址
|
||||
#define GT_TP3_REG 0X8160 //第三个触摸点数据地址
|
||||
#define GT_TP4_REG 0X8168 //第四个触摸点数据地址
|
||||
#define GT_TP5_REG 0X8170 //第五个触摸点数据地址
|
||||
// EXTI 中断配置
|
||||
#define TOUCH_EXTI_LINE EXTI_11
|
||||
#define TOUCH_EXTI_IRQn EXTI10_15_IRQn
|
||||
extern volatile uint8_t g_touch_irq_flag;
|
||||
|
||||
//I2C读写命令
|
||||
#define GT_CMD_WR 0X28 //写命令
|
||||
#define GT_CMD_RD 0X29 //读命令
|
||||
|
||||
//GT1151 部分寄存器定义
|
||||
#define GT_CTRL_REG 0X8040 //GT1151控制寄存器
|
||||
#define GT_CFGS_REG 0X8050 //GT1151地址寄存器
|
||||
#define GT_CHECK_REG 0X813C //GT1151验和寄存器
|
||||
#define GT_PID_REG 0X8140 //GT1151产品ID寄存器
|
||||
|
||||
#define GT_GSTID_REG 0X814E //GT1151前检测到的触摸情况
|
||||
#define GT_TP1_REG 0X8150 //第一个触摸点数据地址
|
||||
#define GT_TP2_REG 0X8158 //第二个触摸点数据地址
|
||||
#define GT_TP3_REG 0X8160 //第三个触摸点数据地址
|
||||
#define GT_TP4_REG 0X8168 //第四个触摸点数据地址
|
||||
#define GT_TP5_REG 0X8170 //第五个触摸点数据地址
|
||||
|
||||
#define TP_PRES_DOWN 0x80 //触屏被按下
|
||||
#define TP_CATH_PRES 0x40 //有按键按下了
|
||||
#define CT_MAX_TOUCH 5 //电容屏支持的点数,固定为5点
|
||||
//触摸屏控制器
|
||||
#define TP_PRES_DOWN 0x80 //触屏被按下
|
||||
#define TP_CATH_PRES 0x40 //有按键按下了
|
||||
#define CT_MAX_TOUCH 5 //电容屏支持的点数,固定为5点
|
||||
//触摸屏控制器
|
||||
typedef struct
|
||||
{
|
||||
// uint8_t (*init)(void); //初始化触摸屏控制器
|
||||
// uint8_t (*scan)(uint8_t); //扫描触摸屏.0,屏幕扫描;1,物理坐标;
|
||||
// void (*adjust)(void); //触摸屏校准
|
||||
uint16_t x[CT_MAX_TOUCH]; //当前坐标
|
||||
uint16_t y[CT_MAX_TOUCH]; //电容屏有最多5组坐标,电阻屏则用x[0],y[0]代表:此次扫描时,触屏的坐标,用
|
||||
uint8_t sta; //笔的状态
|
||||
// uint8_t (*init)(void); //初始化触摸屏控制器
|
||||
// uint8_t (*scan)(uint8_t); //扫描触摸屏.0,屏幕扫描;1,物理坐标;
|
||||
// void (*adjust)(void); //触摸屏校准
|
||||
uint16_t x[CT_MAX_TOUCH]; //当前坐标
|
||||
uint16_t y[CT_MAX_TOUCH]; //电容屏有最多5组坐标,电阻屏则用x[0],y[0]代表:此次扫描时,触屏的坐标,用
|
||||
uint8_t sta; //笔的状态
|
||||
float xfac;
|
||||
float yfac;
|
||||
short xoff;
|
||||
short yoff;
|
||||
uint8_t touchtype;
|
||||
}_m_tp_dev;
|
||||
extern _m_tp_dev tp_dev; //触屏控制器在touch.c里面定义
|
||||
extern _m_tp_dev tp_dev; //触屏控制器在touch.c里面定义
|
||||
|
||||
|
||||
//IIC所有操作函数
|
||||
void CT_IIC_Init(void); //初始化IIC的IO口
|
||||
void CT_IIC_Start(void); //发送IIC开始信号
|
||||
void CT_IIC_Stop(void); //发送IIC停止信号
|
||||
void CT_IIC_Send_Byte(uint8_t txd); //IIC发送一个字节
|
||||
uint8_t CT_IIC_Read_Byte(unsigned char ack); //IIC读取一个字节
|
||||
uint8_t CT_IIC_Wait_Ack(void); //IIC等待ACK信号
|
||||
void CT_IIC_Ack(void); //IIC发送ACK信号
|
||||
void CT_IIC_NAck(void); //IIC不发送ACK信号
|
||||
|
||||
|
||||
|
||||
uint8_t GT1151_Send_Cfg(uint8_t mode);
|
||||
uint8_t GT1151_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len);
|
||||
void GT1151_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len);
|
||||
uint8_t GT1151_Init(void);
|
||||
uint8_t GT1151_Scan(uint8_t mode);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+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