#include "include.h" #if (CTP_SELECT == CTP_CST8X) #define TRACE_EN 0 #if TRACE_EN #define TRACE(...) printf(__VA_ARGS__) #else #define TRACE(...) #endif //CTP升级相关 #define CST8X_UPDATE_EN 0 //打开TP升级功能 #define PER_LEN 512 #define TANS_LIMT (8L) //To be divisible by 512 eg:4 8 16 32 64 .... #define MAX_ADDR (0x3C00L) //CST816只支持一个TOUCH NUM #define CTP_READ_ADDR 0x03 //P1_XH, P1_XL, P1_YH, P1_YL #define CTP_READ_SIZE 4 static u8 ctp_cst8x_buf[CTP_READ_SIZE]; #if CST8X_UPDATE_EN bool ctp_iic_update_read(u8 dev_addr, void *rbuf, int rlen, u16 w_addr, u8 *w_cmd, int wlen); bool ctp_iic_update_write(u8 dev_addr, u16 addr, u8 *cmd, int len); void ctp_reset(void); bool cst8x_enter_bootmode(void) { // printf("%s\n", __func__); uint8_t retry_cnt = 50; //进入Boot要拉复位,拉低拉高后延时10ms,否则无法进入Boot delay_5ms(2); PORT_CTP_RST_L(); delay_5ms(2); PORT_CTP_RST_H(); delay_5ms(2); while (retry_cnt--) { u8 cmd[1]; u8 res = 0; cmd[0] = 0xAB; ctp_iic_update_write(TP_IIC_UPDATE_ADDR, 0xA001, cmd, 2); cmd[0] = 0; ctp_iic_update_read(TP_IIC_UPDATE_ADDR, &res, 1, 0xA003, cmd, 1); // if (cmd[0] != 0x55) { // CST716, CST816S, CST826, CST830, CST836U if (res != 0xC1) { // CST816D, CST816T delay_ms(2); continue; } else { return true; } delay_ms(2); } printf("%s fail!\n", __func__); return false; } static uint16_t cst8x_read_checksum(void) { union { uint32_t sum; uint8_t buf[4]; } checksum; uint8_t cmd[3] = {0}; // uint8_t readback[4] = {0}; if (cst8x_enter_bootmode() == false) { return false; } cmd[0] = 0; ctp_iic_update_write(TP_IIC_UPDATE_ADDR, 0xA003, cmd, 2); delay_ms(500); checksum.sum = 0; ctp_iic_update_read(TP_IIC_UPDATE_ADDR, &checksum.buf, 4, 0xA008, 0, 1); return (uint16_t)checksum.sum; } static int ctp_cst8x_update_do(uint16_t start_addr, uint16_t len, u8 *src) { uint16_t temp_addr; uint16_t total_len = len; uint8_t cmd[2 + TANS_LIMT]; // uint8_t index; int ret = 0; if (cst8x_enter_bootmode() == false) { ret = -1; goto update_fail; } printf("start updata !!\n"); do { if (start_addr > (MAX_ADDR - PER_LEN)) { //protect bootloade ret = -2; goto update_fail; } // send address cmd[0] = start_addr & 0xFF; cmd[1] = start_addr >> 8; // printf("---> start_addr:%lx\n", start_addr); ctp_iic_update_write(TP_IIC_UPDATE_ADDR, 0xA014, cmd, 3); delay_ms(2); //////////////////write 512 byte to ram temp_addr = 0xA018; do { ctp_iic_update_write(TP_IIC_UPDATE_ADDR, temp_addr, src, TANS_LIMT + 1); temp_addr += TANS_LIMT; src += TANS_LIMT; delay_ms(2); } while (temp_addr < 0xA214); /////////////////// cmd[0] = 0xEE; ctp_iic_update_write(TP_IIC_UPDATE_ADDR, 0xA004, cmd, 2); delay_5ms(40); { uint8_t retrycnt = 50; while (--retrycnt) { cmd[0] = 0; ctp_iic_update_read(TP_IIC_UPDATE_ADDR, &cmd, 1, 0xA005, 0, 1); if (cmd[0] == 0x55) { // success break; } delay_ms(10); } } start_addr += PER_LEN; len = len > PER_LEN ? (len - PER_LEN) : 0; //预留升级百分比方便UI做显示 printf("%d%%\n", (total_len - len) *100 / total_len); } while (len); ret = 0; update_fail: cmd[0] = 0x00; ctp_iic_update_write(TP_IIC_UPDATE_ADDR, 0xA003, cmd, 2); // exit program mode // printf("exit boot mode !!\n"); return ret; } bool ctp_cst8x_update(void) { u8 *update_ptr = (u8 *)(RES_BUF_CTP_CTP_UPDATE_BIN); u32 update_len = RES_LEN_CTP_CTP_UPDATE_BIN; // printf("update_len:%x\n", update_len); if (cst8x_enter_bootmode() == true) { if (update_len > 10) { uint16_t start_addr = (update_ptr[1] << 8) | update_ptr[0]; uint16_t length = (update_ptr[3] << 8) | update_ptr[2]; uint16_t checksum = (update_ptr[5] << 8) | update_ptr[4]; uint16_t checksum_old = cst8x_read_checksum(); //enter bootmode fail while checking sum if (checksum_old == 0) { printf("update cecksum enter bootmode err:0\n"); } if (checksum_old == checksum) { printf("CTP fw check sum:0x%04x, it's already the latest version!\n"); } else{ printf("CTP check sum old:0x%x new:checksum=0x%x\n",checksum_old, checksum); ctp_cst8x_update_do(start_addr, length, &update_ptr[6]); checksum_old = cst8x_read_checksum(); if (checksum_old == checksum) { printf("update cecksum sucess!\n"); } else { printf("update cecksum error:0x%04x, correct:0x%04x\n", checksum_old, checksum); } } } return true; } return false; } void ctp_cst8x_update_check(void) { u32 iic1con0 = IIC1CON0; u32 iic1con1 = IIC1CON1; //50KHZ 低速配置IIC模块 IIC1CON0 = BIT(10) | (63 << 4) | BIT(0) | (0 << 2); //WSCL_OPT, POSDIV, IIC EN bool ret = ctp_cst8x_update(); if (ret == false) { printf("CTP update failed!\n"); } IIC1CON0 = iic1con0; IIC1CON1 = iic1con1; ctp_reset(); } #endif bool ctp_cst8x_init(void) { #if CST8X_UPDATE_EN //Only check once after power on static bool check_flag = false; if (!check_flag) { ctp_cst8x_update_check(); check_flag = true; } #endif u8 info[4]; if (!ctp_iic_read(info, 0xA7, 4)) { return false; } TRACE("CTP ID: %02x, VER: %02x\n", info[0], info[2]); if ((info[0] != 0xB6 && info[0] != 0xB7) || info[2] == 0) { //0xB6:cst816, 0xB7:cst820 return false; } return true; } AT(.com_text.ctp) void ctp_cst8x_readkick(void) { ctp_iic_readkick(ctp_cst8x_buf, CTP_READ_ADDR, CTP_READ_SIZE); } AT(.com_text.ctp) bool ctp_cst8x_get_point(s32 *x, s32 *y) { *x = ((ctp_cst8x_buf[0] & 0xf) << 8) + ctp_cst8x_buf[1]; *y = ((ctp_cst8x_buf[2] & 0xf) << 8) + ctp_cst8x_buf[3]; return ((ctp_cst8x_buf[0] & 0xC0) == 0x80); } #endif