571 lines
17 KiB
C
571 lines
17 KiB
C
#include "include.h"
|
|
#include "app_variable.h"
|
|
|
|
|
|
#define TRACE_EN 0
|
|
|
|
#if TRACE_EN
|
|
#define TRACE(...) printf(__VA_ARGS__)
|
|
#define TRACE_K(...) printk(__VA_ARGS__)
|
|
AT(.com_rodata)
|
|
const char str_xy[] = "%d: %d, %d\n";
|
|
#else
|
|
#define TRACE(...)
|
|
#define TRACE_K(...)
|
|
#endif
|
|
|
|
//TP相关配置
|
|
#define CTP_CNT_SHORT_MOV (GUI_SCREEN_WIDTH / 30) //CTP短划阈值(屏幕距离)
|
|
#define CTP_CNT_LONG_MOV (GUI_SCREEN_WIDTH / 3) //CTP长划阈值(屏幕距离)
|
|
#define CTP_CNT_LONG 40 //CTP长按时间阈值(CTP INT时钟个数)
|
|
#define I2C_WRITE_ADDR(ADDR) ((ADDR) << 1) //CTP IIC写地址
|
|
#define I2C_READ_ADDR(ADDR) ((ADDR) << 1 | 1) //CTP IIC读地址
|
|
|
|
#if SECURITY_PAY_EN
|
|
AT(.com_text.ctp_var)
|
|
bool ctp_kick_status;
|
|
#endif // SECURITY_PAY_EN
|
|
|
|
enum {
|
|
CTP_STA_IDLE,
|
|
CTP_STA_PRESS,
|
|
CTP_STA_PRESS_LONG,
|
|
CTP_STA_MOV_SHORT,
|
|
CTP_STA_MOV_LONG,
|
|
};
|
|
|
|
|
|
static struct ctp_cb_t {
|
|
s32 x; //当前坐标
|
|
s32 y;
|
|
s32 sx; //起始坐标
|
|
s32 sy;
|
|
s32 last_dx; //最后一次相对偏移
|
|
s32 last_dy;
|
|
u8 cnt;
|
|
u8 sta;
|
|
bool flag_last;
|
|
} ctp_cb;
|
|
|
|
#if CHIP_PACKAGE_QFN40
|
|
static i2c_t __CTP_IIC1 = {
|
|
.sfr = (i2c_sfr_t *) &IIC1CON0,
|
|
.map = (i2c_map_t *) &FUNCMCON2,
|
|
};
|
|
|
|
i2c_t *CTP_IIC = &__CTP_IIC1;
|
|
#else
|
|
|
|
#if (CHIP_PACKAGE_SELECT == CHIP_5682C)
|
|
static i2c_t __CTP_IIC1 = {
|
|
.sfr = (i2c_sfr_t *) &IIC1CON0,
|
|
.map = (i2c_map_t *) &FUNCMCON2,
|
|
};
|
|
|
|
i2c_t *CTP_IIC = &__CTP_IIC1;
|
|
#else
|
|
static i2c_t __CTP_IIC0 = {
|
|
.sfr = (i2c_sfr_t *) &IIC0CON0,
|
|
.map = (i2c_map_t *) &FUNCMCON2,
|
|
};
|
|
i2c_t *CTP_IIC = &__CTP_IIC0;
|
|
#endif
|
|
|
|
#endif
|
|
|
|
static int ctp_chip_id = 0;
|
|
int get_ctp_chip_ID(void)
|
|
{
|
|
return ctp_chip_id;
|
|
}
|
|
|
|
void set_ctp_chip_ID(int id)
|
|
{
|
|
ctp_chip_id = id;
|
|
}
|
|
|
|
|
|
AT(.com_text.ctp)
|
|
void ctp_int_isr(void)
|
|
{
|
|
if (WKUPEDG & BIT(16 + PORT_CTP_INT_VECTOR))
|
|
{
|
|
uart_putchar('#');
|
|
WKUPCPND = BIT(16 + PORT_CTP_INT_VECTOR);
|
|
#if GUI_CTP_COMPATIBLE_DRIVER
|
|
|
|
if (get_ctp_chip_ID() == CTP_AXS5106_CHIP_ID)
|
|
{
|
|
AXS5106_read_readkick();
|
|
}
|
|
else
|
|
{
|
|
spt5113c_readkick();
|
|
}
|
|
#else
|
|
#if (CTP_SELECT == CTP_CST8X)
|
|
ctp_cst8x_readkick();
|
|
#elif (CTP_SELECT == CTP_CHSC6X)
|
|
ctp_chsc6x_readkick();
|
|
#elif (CTP_SELECT == CTP_AXS5106)
|
|
AXS5106_read_readkick();
|
|
#elif (CTP_SELECT | CTP_SPT5113C)
|
|
spt5113c_readkick();
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//处理TP的消息
|
|
AT(.com_text.ctp)
|
|
void ctp_msg_deal(bool press)
|
|
{
|
|
if (press) {
|
|
reset_sleep_delay_all();
|
|
|
|
int mx, my;
|
|
mx = abs_s(ctp_cb.x - ctp_cb.sx);
|
|
my = abs_s(ctp_cb.y - ctp_cb.sy);
|
|
|
|
switch (ctp_cb.sta) {
|
|
case CTP_STA_IDLE:
|
|
ctp_cb.sta = CTP_STA_PRESS; //按下
|
|
ctp_cb.sx = ctp_cb.x;
|
|
ctp_cb.sy = ctp_cb.y;
|
|
my_msg_enqueue(MSG_CTP_TOUCH); //触摸事件
|
|
ctp_cb.cnt++;
|
|
break;
|
|
|
|
case CTP_STA_PRESS:
|
|
case CTP_STA_PRESS_LONG:
|
|
case CTP_STA_MOV_SHORT:
|
|
if (ctp_cb.sta == CTP_STA_PRESS) {
|
|
ctp_cb.cnt++;
|
|
if (ctp_cb.cnt >= CTP_CNT_LONG) {
|
|
my_msg_enqueue(MSG_CTP_LONG); //长按
|
|
ctp_cb.sta = CTP_STA_PRESS_LONG;
|
|
return;
|
|
}
|
|
}
|
|
if (mx >= my) {
|
|
if (mx >= CTP_CNT_LONG_MOV) {
|
|
if (ctp_cb.x < ctp_cb.sx) {
|
|
if (ctp_cb.sta != CTP_STA_MOV_SHORT) {
|
|
my_msg_enqueue(MSG_CTP_SHORT_LEFT); //补发左短划
|
|
}
|
|
my_msg_enqueue(MSG_CTP_LONG_LEFT); //左长划
|
|
ctp_cb.sta = CTP_STA_MOV_LONG;
|
|
} else {
|
|
if (ctp_cb.sta != CTP_STA_MOV_SHORT) {
|
|
my_msg_enqueue(MSG_CTP_SHORT_RIGHT); //补发右短划
|
|
}
|
|
my_msg_enqueue(MSG_CTP_LONG_RIGHT); //右长划
|
|
ctp_cb.sta = CTP_STA_MOV_LONG;
|
|
}
|
|
return;
|
|
}
|
|
if (ctp_cb.sta != CTP_STA_MOV_SHORT && mx >= CTP_CNT_SHORT_MOV) {
|
|
if (ctp_cb.x < ctp_cb.sx) {
|
|
my_msg_enqueue(MSG_CTP_SHORT_LEFT); //左短划
|
|
ctp_cb.sta = CTP_STA_MOV_SHORT;
|
|
} else {
|
|
my_msg_enqueue(MSG_CTP_SHORT_RIGHT); //右短划
|
|
ctp_cb.sta = CTP_STA_MOV_SHORT;
|
|
}
|
|
return;
|
|
}
|
|
} else {
|
|
if (my >= CTP_CNT_LONG_MOV) {
|
|
if (ctp_cb.y < ctp_cb.sy) {
|
|
if (ctp_cb.sta != CTP_STA_MOV_SHORT) {
|
|
my_msg_enqueue(MSG_CTP_SHORT_UP); //补发上短划
|
|
}
|
|
my_msg_enqueue(MSG_CTP_LONG_UP); //上长划
|
|
ctp_cb.sta = CTP_STA_MOV_LONG;
|
|
} else {
|
|
if (ctp_cb.sta != CTP_STA_MOV_SHORT) {
|
|
my_msg_enqueue(MSG_CTP_SHORT_DOWN); //补发下短划
|
|
}
|
|
my_msg_enqueue(MSG_CTP_LONG_DOWN); //下长划
|
|
ctp_cb.sta = CTP_STA_MOV_LONG;
|
|
}
|
|
return;
|
|
}
|
|
if (ctp_cb.sta != CTP_STA_MOV_SHORT && my >= CTP_CNT_SHORT_MOV) {
|
|
if (ctp_cb.y < ctp_cb.sy) {
|
|
my_msg_enqueue(MSG_CTP_SHORT_UP); //上短划
|
|
ctp_cb.sta = CTP_STA_MOV_SHORT;
|
|
} else {
|
|
my_msg_enqueue(MSG_CTP_SHORT_DOWN); //下短划
|
|
ctp_cb.sta = CTP_STA_MOV_SHORT;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CTP_STA_MOV_LONG:
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
if (ctp_cb.sta == CTP_STA_PRESS) {
|
|
my_msg_enqueue(MSG_CTP_CLICK); //单击
|
|
} else if (ctp_cb.sta == CTP_STA_PRESS_LONG) {
|
|
my_msg_enqueue(MSG_CTP_LONG_LIFT); //长按抬起
|
|
}
|
|
|
|
ctp_cb.cnt = 0;
|
|
ctp_cb.sta = CTP_STA_IDLE;
|
|
}
|
|
}
|
|
|
|
#if SECURITY_PAY_EN
|
|
AT(.com_text.ctp)
|
|
bool ctp_get_kick_status(void)
|
|
{
|
|
return ctp_kick_status;
|
|
}
|
|
#endif // SECURITY_PAY_EN
|
|
|
|
AT(.com_text.ctp)
|
|
void ctp_isr(void)
|
|
{
|
|
bool press;
|
|
if (CTP_IIC->sfr->IICxCON0 & BIT(31))
|
|
{
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(29);
|
|
|
|
s32 last_x = ctp_cb.x;
|
|
s32 last_y = ctp_cb.y;
|
|
|
|
#if GUI_CTP_COMPATIBLE_DRIVER
|
|
|
|
if (get_ctp_chip_ID() == CTP_AXS5106_CHIP_ID) {
|
|
press = AXS5106_get_touch_point(&ctp_cb.x, &ctp_cb.y);
|
|
} else {
|
|
press = spt5113c_get_point(&ctp_cb.x, &ctp_cb.y);
|
|
}
|
|
|
|
#else
|
|
#if (CTP_SELECT == CTP_CST8X)
|
|
press = ctp_cst8x_get_point(&ctp_cb.x, &ctp_cb.y);
|
|
#elif (CTP_SELECT == CTP_CHSC6X)
|
|
press = ctp_chsc6x_get_point(&ctp_cb.x, &ctp_cb.y);
|
|
#elif (CTP_SELECT == CTP_AXS5106)
|
|
press = AXS5106_get_touch_point(&ctp_cb.x, &ctp_cb.y);
|
|
#elif (CTP_SELECT | CTP_SPT5113C)
|
|
press = spt5113c_get_point(&ctp_cb.x, &ctp_cb.y);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
if (press) {
|
|
if (ctp_cb.flag_last) {
|
|
ctp_cb.last_dx = ctp_cb.x - last_x;
|
|
ctp_cb.last_dy = ctp_cb.y - last_y;
|
|
} else {
|
|
ctp_cb.flag_last = true;
|
|
ctp_cb.last_dx = 0;
|
|
ctp_cb.last_dy = 0;
|
|
}
|
|
} else {
|
|
ctp_cb.flag_last = false;
|
|
}
|
|
#if CTP_SUPPORT_COVER
|
|
if ((ctp_cb.x == -1)&&(SysVariable.capping_hand_offscreen_flag))
|
|
{
|
|
my_msg_enqueue(MSG_CTP_COVER); //盖手
|
|
}
|
|
#endif
|
|
TRACE_K(str_xy, press, ctp_cb.x, ctp_cb.y);
|
|
ctp_msg_deal(press);
|
|
#if SECURITY_PAY_EN
|
|
ctp_kick_status = false;
|
|
#endif // SECURITY_PAY_EN
|
|
}
|
|
}
|
|
|
|
//获取坐标,返回触屏点击状态
|
|
AT(.com_text.ctp)
|
|
bool ctp_get_cur_point(s32 *sx, s32 *sy, s32 *x, s32 *y)
|
|
{
|
|
bool press;
|
|
GLOBAL_INT_DISABLE();
|
|
*sx = ctp_cb.sx;
|
|
*sy = ctp_cb.sy;
|
|
*x = ctp_cb.x;
|
|
*y = ctp_cb.y;
|
|
press = (ctp_cb.sta != CTP_STA_IDLE);
|
|
GLOBAL_INT_RESTORE();
|
|
return press;
|
|
}
|
|
|
|
//获取坐标差量,返回触屏点击状态
|
|
AT(.com_text.ctp)
|
|
bool ctp_get_dxy(s32 *dx, s32 *dy)
|
|
{
|
|
bool press;
|
|
GLOBAL_INT_DISABLE();
|
|
press = (ctp_cb.sta != CTP_STA_IDLE);
|
|
if (press) {
|
|
*dx = ctp_cb.x - ctp_cb.sx;
|
|
*dy = ctp_cb.y - ctp_cb.sy;
|
|
}
|
|
GLOBAL_INT_RESTORE();
|
|
return press;
|
|
}
|
|
|
|
//获取起始X,Y坐标
|
|
AT(.com_text.ctp)
|
|
point_t ctp_get_sxy(void)
|
|
{
|
|
point_t pt;
|
|
GLOBAL_INT_DISABLE();
|
|
pt.x = ctp_cb.sx;
|
|
pt.y = ctp_cb.sy;
|
|
GLOBAL_INT_RESTORE();
|
|
return pt;
|
|
}
|
|
|
|
//获取最后一次偏移
|
|
AT(.com_text.ctp)
|
|
point_t ctp_get_last_dxy(void)
|
|
{
|
|
point_t pt;
|
|
GLOBAL_INT_DISABLE();
|
|
pt.x = ctp_cb.last_dx;
|
|
pt.y = ctp_cb.last_dy;
|
|
GLOBAL_INT_RESTORE();
|
|
return pt;
|
|
}
|
|
|
|
//获取点击XY的相对于控件的坐标
|
|
AT(.com_text.ctp)
|
|
point_t ctp_get_rxy(widget_t *widget)
|
|
{
|
|
point_t pt;
|
|
rect_t rect = widget_get_absolute(widget);
|
|
GLOBAL_INT_DISABLE();
|
|
pt.x = (ctp_cb.sx - (rect.x - (rect.wid >> 1)) + (rect.wid >> 1)) >> 1;
|
|
pt.y = (ctp_cb.sy - (rect.y - (rect.hei >> 1)) + (rect.hei >> 1)) >> 1;
|
|
GLOBAL_INT_RESTORE();
|
|
return pt;
|
|
}
|
|
|
|
//读数据KICK
|
|
AT(.com_text.ctp)
|
|
void ctp_iic_readkick(void *buf, u8 addr, int len)
|
|
{
|
|
CTP_IIC->sfr->IICxCMDA = (I2C_READ_ADDR(TP_IIC_ADDR) << 24) | (addr << 8) | I2C_WRITE_ADDR(TP_IIC_ADDR); //0x2A
|
|
CTP_IIC->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | BIT(5) | BIT(4) | BIT(3);
|
|
CTP_IIC->sfr->IICxDMAADR = DMA_ADR(buf);
|
|
CTP_IIC->sfr->IICxDMACNT = ((len - 1) << 16) | BIT(0);
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(28); //KICK
|
|
#if SECURITY_PAY_EN
|
|
ctp_kick_status = true;
|
|
#endif // SECURITY_PAY_EN
|
|
}
|
|
|
|
//读数据接口(开中断前)
|
|
bool ctp_iic_read(void *buf, u8 addr, int len)
|
|
{
|
|
u32 ticks;
|
|
ctp_iic_readkick(buf, addr, len);
|
|
ticks = tick_get();
|
|
while (!(CTP_IIC->sfr->IICxCON0 & BIT(31))) {
|
|
if (tick_check_expire(ticks, 20)) {
|
|
return false;
|
|
}
|
|
}
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(29); //Clear Pending
|
|
return true;
|
|
}
|
|
|
|
|
|
//复位
|
|
void ctp_reset(void)
|
|
{
|
|
PORT_CTP_RST_L();
|
|
delay_5ms(2);
|
|
PORT_CTP_RST_H();
|
|
delay_5ms(21);
|
|
}
|
|
|
|
//初始化
|
|
void ctp_init(void)
|
|
{
|
|
bool res;
|
|
memset(&ctp_cb, 0, sizeof(ctp_cb));
|
|
|
|
//配置时钟
|
|
#if CHIP_PACKAGE_QFN40
|
|
CLKGAT2 |= BIT(1); //IIC1
|
|
CLKCON1 |= BIT(8); //x26m_clkdiv8
|
|
RSTCON0 |= BIT(7); //Release CTP_IIC->sfr->IICx
|
|
#else
|
|
#if (CHIP_PACKAGE_SELECT == CHIP_5682C)
|
|
CLKGAT2 |= BIT(1); //IIC1
|
|
CLKCON1 |= BIT(8); //x26m_clkdiv8
|
|
RSTCON0 |= BIT(7); //Release CTP_IIC->sfr->IICx
|
|
#else
|
|
CLKGAT2 |= BIT(0); //IIC0
|
|
CLKCON1 |= BIT(7); //x26m_clkdiv8
|
|
RSTCON0 |= BIT(3); //Release CTP_IIC->sfr->IICx
|
|
#endif
|
|
#endif
|
|
|
|
port_ctp_init();
|
|
|
|
//配置IIC模块
|
|
#if (CTP_SELECT | CTP_AXS5106)||(CTP_SELECT | CTP_SPT5113C)
|
|
CTP_IIC->sfr->IICxCON0 = BIT(10) | (16 << 4) | BIT(0); //WSCL_OPT, POSDIV, IIC EN 5106 200K 以下能够读到正确的ID
|
|
#else
|
|
CTP_IIC->sfr->IICxCON0 = BIT(10) | (8 << 4) | BIT(0); //WSCL_OPT, POSDIV, IIC EN
|
|
#endif
|
|
CTP_IIC->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | BIT(5) | BIT(4) | BIT(3) | 1;
|
|
|
|
//复位TP/等待模块使能
|
|
ctp_reset();
|
|
|
|
#if GUI_CTP_COMPATIBLE_DRIVER
|
|
res = AXS5106_init();
|
|
if (!res) {
|
|
res = spt5113c_init();
|
|
}
|
|
#else
|
|
#if (CTP_SELECT == CTP_CST8X)
|
|
res = ctp_cst8x_init();
|
|
#elif (CTP_SELECT == CTP_CHSC6X)
|
|
res = ctp_chsc6x_init();
|
|
#elif (CTP_SELECT == CTP_AXS5106)
|
|
res = AXS5106_init();
|
|
#elif (CTP_SELECT | CTP_SPT5113C)
|
|
res = spt5113c_init();
|
|
#endif
|
|
#endif
|
|
|
|
#if SECURITY_PAY_EN
|
|
CTP_IIC->sfr->IICxCON0 = BIT(10) | (26 << 4) | BIT(0); //alipay不支持那么高速率
|
|
#endif // SECURITY_PAY_EN
|
|
|
|
if (!res) {
|
|
TRACE("CTP ERROR!\n");
|
|
return;
|
|
}
|
|
|
|
//SPT5113C需要延后初始化IRQ信号引脚
|
|
if(get_ctp_chip_ID() != CTP_STP5113_CHIP_ID)
|
|
{
|
|
sys_irq_init(IRQ_CTP_VECTOR, 0, ctp_isr);
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(1); //IIC INT EN
|
|
|
|
//INT信号中断
|
|
port_irq_register(PORT_CTP_INT_VECTOR, ctp_int_isr);
|
|
port_wakeup_init(PORT_CTP_INT, 1, 1); //开内部上拉, 下降沿唤醒
|
|
}
|
|
}
|
|
|
|
//初始化IRQ信号引脚
|
|
void ctp_irq_init(void)
|
|
{
|
|
sys_irq_init(IRQ_CTP_VECTOR, 0, ctp_isr);
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(1); //IIC INT EN
|
|
|
|
//INT信号中断
|
|
port_irq_register(PORT_CTP_INT_VECTOR, ctp_int_isr);
|
|
port_wakeup_init(PORT_CTP_INT, 1, 1); //开内部上拉, 下降沿唤醒
|
|
}
|
|
|
|
void ctp_exit(void)
|
|
{
|
|
#if CHIP_PACKAGE_QFN40
|
|
CTP_IIC->sfr->IICxCON0 = 0;
|
|
RSTCON0 &= ~BIT(7); //reset CTP_IIC->sfr->IICx
|
|
CLKGAT2 &= ~BIT(1);
|
|
#else
|
|
#if (CHIP_PACKAGE_SELECT == CHIP_5682C)
|
|
CTP_IIC->sfr->IICxCON0 = 0;
|
|
RSTCON0 &= ~BIT(7); //reset CTP_IIC->sfr->IICx
|
|
CLKGAT2 &= ~BIT(1);
|
|
#else
|
|
CTP_IIC->sfr->IICxCON0 = 0;
|
|
RSTCON0 &= ~BIT(3); //reset CTP_IIC->sfr->IICx
|
|
CLKGAT2 &= ~BIT(0);
|
|
#endif
|
|
#endif
|
|
port_ctp_exit();
|
|
port_irq_free(PORT_CTP_INT_VECTOR);
|
|
port_wakeup_exit(PORT_CTP_INT);
|
|
}
|
|
|
|
//升级写KICK
|
|
void ctp_iic_write_update_kick(u8 dev_addr, u16 addr, u8 *cmd, int len)
|
|
{
|
|
CTP_IIC->sfr->IICxCMDA = ((addr >> 8) << 8) | I2C_WRITE_ADDR(dev_addr); //2Bytes的reg addr放高位到addr0
|
|
|
|
u8 buf[8];
|
|
buf[0] = addr & 0xff; //2Bytes的reg addr低位放到数据第一字节
|
|
if(len > 1) {
|
|
memcpy(&buf[1], cmd, len - 1);
|
|
}
|
|
|
|
CTP_IIC->sfr->IICxDMAADR = DMA_ADR(buf);
|
|
CTP_IIC->sfr->IICxDMACNT = ((len - 1) << 16) | BIT(1) | BIT(0);
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(28); //KICK
|
|
delay_ms(2);
|
|
|
|
}
|
|
|
|
//升级写
|
|
bool ctp_iic_update_write(u8 dev_addr, u16 addr, u8 *cmd, int len)
|
|
{
|
|
CTP_IIC->sfr->IICxCON1 = BIT(11) | BIT(10) | BIT(5) | BIT(4) | BIT(3) | len;
|
|
u32 ticks;
|
|
ctp_iic_write_update_kick(dev_addr, addr, cmd, len);
|
|
ticks = tick_get();
|
|
while (!(CTP_IIC->sfr->IICxCON0 & BIT(31))) {
|
|
if (tick_check_expire(ticks, 20)) {
|
|
// printf("WRITE UPDATE IIC TOUT\n");
|
|
return false;
|
|
}
|
|
WDT_CLR();
|
|
}
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(29); //Clear Pending
|
|
|
|
// delay_5ms(2);
|
|
return true;
|
|
}
|
|
|
|
//升级读KICK
|
|
void ctp_iic_update_readkick(u8 dev_addr, void *buf, int len)
|
|
{
|
|
CTP_IIC->sfr->IICxCMDA = (I2C_READ_ADDR(dev_addr)) << 24;
|
|
|
|
CTP_IIC->sfr->IICxDMAADR = DMA_ADR(buf);
|
|
CTP_IIC->sfr->IICxDMACNT = ((len - 1) << 16) | BIT(0);
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(28); //KICK
|
|
}
|
|
|
|
//升级读
|
|
bool ctp_iic_update_read(u8 dev_addr, void *rbuf, int rlen, u16 w_addr, u8 *w_cmd, int wlen)
|
|
{
|
|
ctp_iic_update_write(dev_addr, w_addr, w_cmd, wlen);
|
|
|
|
CTP_IIC->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | rlen;
|
|
u32 ticks;
|
|
ctp_iic_update_readkick(dev_addr, rbuf, rlen);
|
|
ticks = tick_get();
|
|
while (!(CTP_IIC->sfr->IICxCON0 & BIT(31))) {
|
|
if (tick_check_expire(ticks, 20)) {
|
|
// printf("READ UPDATE IIC TOUT\n");
|
|
return false;
|
|
}
|
|
}
|
|
CTP_IIC->sfr->IICxCON0 |= BIT(29); //Clear Pending
|
|
|
|
delay_ms(2);
|
|
return true;
|
|
}
|
|
|