#include "spt5113c.h" #include "bsp_i2c.h" #if ((CTP_SELECT | CTP_SPT5113C) || GUI_CTP_COMPATIBLE_DRIVER) #if AXS_UPGRADE_SYNC_VERSION #include "spt5113c_firmware.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C) #include "spt5113c_firmware.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_KYA012V1_FWT_064_V1) #include "spt5113c_firmware_KYA012V1_FWT-064-V1_241129_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_B796A01_FWT030V0) #include "spt5113c_firmware_B796A01_FWT030V0_241129_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ1_MWD1303_01) #include "spt5113c_firmware_TZ1_MWD1303_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ1_TB36V2) #include "spt5113c_firmware_TZ1_TB36V2_2411271634.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ19A_S693_FWT038) #include "spt5113c_firmware_TZ19A_2TP_S693+FWT038_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ32A_Q1328) #include "spt5113c_firmware_tz32a_q1328_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ64A_KB871_V01) #include "spt5113c_firmware_TZ64A_KB871_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ2_TB71A_01) #include "spt5113c_firmware_TZ2_TB71A_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ19A_2TP_S693_FWT038_01) #include "spt5113c_firmware_TZ19A_2TP_S693+FWT038_01.h" #elif (CTP_SELECT_SPT5113C == CTP_SPT5113C_TZ19A_2TP_MWD1219_S782_01) #include "spt5113c_firmware_TZ19A_2TP_MWD1219+S782_01.h" #else #include "spt5113c_firmware.h" #endif static bool spt5113c_firmware_update(void); static bool spt5113c_is_init = false; typedef enum { EXEC_OK = 0, CTP_STP5113_CHIP_ID_ERR, UPGRADE_HOLD_ERR, WRITE_CODE_ERR, CRC_CHECK_ERR, }FIRMWARE_UPDATE_STATUS; #define MAX_CTP_UPDATE_LEN (0x400) static uint8_t ctp_fw_temp_buffer[MAX_CTP_UPDATE_LEN] = {0}; static uint16_t spt5113c_save_freq = 0; #define UPDATE_INFO_EN 1 #if (UPDATE_INFO_EN) #define UPDATE_INFO(fmt, ...) printf(fmt, ##__VA_ARGS__) #else #define UPDATE_INFO(fmt, ...) #endif #define ASU_DEV_ADDR 0x60 #define APP_DEV_ADDR 0x13 // #define CTP_STP5113_CHIP_ID 0x53 #define I2C_WRITE_ADDR(ADDR) ((ADDR) << 1) //CTP IICд��ַ #define I2C_READ_ADDR(ADDR) ((ADDR) << 1 | 1) //CTP IIC����ַ #if CHIP_PACKAGE_QFN40 static i2c_t __SPT5113C_IIC1 = { .sfr = (i2c_sfr_t *)&IIC1CON0, .map = (i2c_map_t *)&FUNCMCON2, }; i2c_t *SPT5113C_IICx = &__SPT5113C_IIC1; #else #if (CHIP_PACKAGE_SELECT == CHIP_5682C) static i2c_t __SPT5113C_IIC1 = { .sfr = (i2c_sfr_t *)&IIC1CON0, .map = (i2c_map_t *)&FUNCMCON2, }; i2c_t *SPT5113C_IICx = &__SPT5113C_IIC1; #else static i2c_t __SPT5113C_IIC0 = { .sfr = (i2c_sfr_t *)&IIC0CON0, .map = (i2c_map_t *)&FUNCMCON2, }; i2c_t *SPT5113C_IICx = &__SPT5113C_IIC0; #endif #endif AT(.com_rodata.tp) static uint8_t spt5113c_buff[7] = {0}; AT(.text.sensor.spt5113c) __attribute__((unused)) static void spt5113c_i2c_read_16bit(uint8_t dev_addr, uint16_t reg_addr, uint8_t *read_data, uint16_t read_len) { u32 ticks; SPT5113C_IICx->sfr->IICxCMDA = (I2C_READ_ADDR(dev_addr) << 24) | (reg_addr << 8) | I2C_WRITE_ADDR(dev_addr); //0x2A SPT5113C_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | read_len; SPT5113C_IICx->sfr->IICxDMAADR = DMA_ADR(read_data); SPT5113C_IICx->sfr->IICxDMACNT = ((read_len - 1) << 16) | BIT(0); SPT5113C_IICx->sfr->IICxCON0 |= BIT(28); //KICK ticks = tick_get(); while (!(SPT5113C_IICx->sfr->IICxCON0 & BIT(31))) { if (tick_check_expire(ticks, 200)) { UPDATE_INFO("spt5113c_i2c_read 16bit time out ERROR\n"); return; } } SPT5113C_IICx->sfr->IICxCON0 |= BIT(29); //Clear Pending } AT(.text.sensor.spt5113c) __attribute__((unused)) static void spt5113c_i2c_write_16bit(uint8_t dev_addr, uint16_t reg_addr, uint8_t *write_data, uint16_t write_len) { u32 ticks; SPT5113C_IICx->sfr->IICxCMDA = (reg_addr << 8) | I2C_WRITE_ADDR(dev_addr); //0x2A SPT5113C_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(10) | BIT(6) | BIT(5) | BIT(4) | BIT(3); SPT5113C_IICx->sfr->IICxDMAADR = DMA_ADR(write_data); SPT5113C_IICx->sfr->IICxDMACNT = ((write_len - 1) << 16) | BIT(1) |BIT(0); SPT5113C_IICx->sfr->IICxCON0 |= BIT(28); //KICK ticks = tick_get(); while (!(SPT5113C_IICx->sfr->IICxCON0 & BIT(31))) { if (tick_check_expire(ticks, 2000)) { UPDATE_INFO("spt5113c_i2c_write 16bit time out ERROR\n"); return; } } SPT5113C_IICx->sfr->IICxCON0 |= BIT(29); //Clear Pending } AT(.com_text.ctp) static void spt5113c_i2c_read_8bit_kick(uint8_t dev_addr, uint8_t reg_addr, uint8_t *read_data, int read_len) { SPT5113C_IICx->sfr->IICxCMDA = (I2C_READ_ADDR(dev_addr) << 24) | (reg_addr << 8) | I2C_WRITE_ADDR(dev_addr); //0x2A SPT5113C_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | BIT(5) | BIT(4) | BIT(3) | read_len; SPT5113C_IICx->sfr->IICxDMAADR = DMA_ADR(read_data); SPT5113C_IICx->sfr->IICxDMACNT = ((read_len - 1) << 16) | BIT(0); SPT5113C_IICx->sfr->IICxCON0 |= BIT(28); //KICK } AT(.com_text.ctp) static void spt5113c_i2c_write_8bit(uint8_t dev_addr, uint8_t reg_addr, uint8_t *write_data, int write_len) { u32 ticks; SPT5113C_IICx->sfr->IICxCMDA = (reg_addr << 8) | I2C_WRITE_ADDR(dev_addr); //0x2A SPT5113C_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(10) | BIT(5) | BIT(4) | BIT(3); SPT5113C_IICx->sfr->IICxDMAADR = DMA_ADR(write_data); SPT5113C_IICx->sfr->IICxDMACNT = ((write_len - 1) << 16) | BIT(1) | BIT(0); SPT5113C_IICx->sfr->IICxCON0 |= BIT(28); //KICK ticks = tick_get(); while (!(SPT5113C_IICx->sfr->IICxCON0 & BIT(31))) { if (tick_check_expire(ticks, 1)) { //UPDATE_INFO("spt5113c_i2c_write 8bit time out ERROR\n"); return; } } SPT5113C_IICx->sfr->IICxCON0 |= BIT(29); //Clear Pending } /******************************** SPT5113C ���� ****************************************/ AT(.com_text.ctp) bool spt5113c_init(void) { uint8_t reg_temp; SPT5113C_IICx->sfr->IICxCON0 = BIT(10) | (8 << 4) | BIT(0); //临时提高I2C速率:400K spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC000, ®_temp, 1); printf("spt5113c_i2c_read_16bit %d\n" , reg_temp); if (reg_temp != CTP_STP5113_CHIP_ID) { SPT5113C_IICx->sfr->IICxCON0 = BIT(10) | (16 << 4) | BIT(0); //恢复I2C速率:200K return false; } set_ctp_chip_ID(reg_temp); return spt5113c_firmware_update(); } AT(.com_text.ctp) static void spt5113c_reset(void) { PORT_CTP_RST_H(); delay_ms(10); PORT_CTP_RST_L(); delay_ms(12); PORT_CTP_RST_H(); delay_ms(12); } AT(.com_text.ctp) static FIRMWARE_UPDATE_STATUS spt5113c_asu_connect(void) { uint8_t reg_temp; //CHIP CODE verify spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC000, ®_temp, 1); if(reg_temp != CTP_STP5113_CHIP_ID) { return CTP_STP5113_CHIP_ID_ERR; } //Enter upgrade spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); reg_temp &= 0xf0;// low 4 bits clear hold upgrade spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1);//re-write return EXEC_OK; } AT(.com_text.ctp) static void spt5113c_write_code_length(void) { uint8_t length_lo = (FIRMWARE_SIZE - 1) & 0xFF; uint8_t length_hi = ((FIRMWARE_SIZE - 1) >> 8) & 0xFF; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC130, &length_hi, 1); spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC131, &length_lo, 1); } AT(.com_text.ctp) static void spt5113c_write_code_crc(void) { uint8_t crc_lo = CRC16_CHECK_CODE & 0xFF; uint8_t crc_hi = (CRC16_CHECK_CODE >> 8) & 0xFF; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC132, &crc_hi, 1); spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC133, &crc_lo, 1); } AT(.com_text.ctp) static FIRMWARE_UPDATE_STATUS spt5113c_write_code(uint16_t write_addr, uint8_t *write_buffer, uint16_t write_length) { if((write_buffer == NULL) || (write_length == 0) || ((write_addr + write_length) > 0x2800)) { return WRITE_CODE_ERR; } while(write_length) { uint16_t copy_length = MAX_CTP_UPDATE_LEN; if(write_length < MAX_CTP_UPDATE_LEN) { copy_length = write_length; } memset(ctp_fw_temp_buffer, 0 ,sizeof(ctp_fw_temp_buffer)); memcpy(ctp_fw_temp_buffer, write_buffer + write_addr, copy_length); spt5113c_i2c_write_16bit(ASU_DEV_ADDR, write_addr, ctp_fw_temp_buffer, copy_length); write_length -= copy_length; write_addr += copy_length; } return EXEC_OK; } AT(.com_text.ctp) static FIRMWARE_UPDATE_STATUS spt5113c_crc_check(void) { uint8_t inc, byte_lo, byte_hi; uint8_t crc_check_cnt = 0; uint16_t crc_code; spt5113c_write_code_length(); spt5113c_write_code_crc(); inc = 0x01; //soft start crc check spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC136, &inc, 1); //send inc //delay_ms(10); //wait for check complete while(crc_check_cnt < 100) { inc = 0; spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC136, &inc, 1); if((inc & 0x01) == 0) { //CRC������� break; } crc_check_cnt++; delay_us(100); } spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC134, &byte_hi, 1); //read crc hi byte spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC135, &byte_lo, 1); //read crc lo byte UPDATE_INFO("# byte_hi :%d %d\r\n", byte_hi , byte_lo); crc_code = ((uint16_t)byte_hi << 8) + byte_lo; if(crc_code == CRC16_CHECK_CODE) { return EXEC_OK; } else { return CRC_CHECK_ERR; } } //SPT5113C按照默认频率运行 AT(.com_text.ctp) void spt5113c_start_work(void) { uint8_t reg_temp; uint8_t hopping_ctrl[3] = {0x00, 0x00, 0x00}; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB0, hopping_ctrl, 3); spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); reg_temp &= 0xDF; reg_temp |= 0x03; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); UPDATE_INFO("#### spt5113c start work with normal freq.\r\n"); } //SPT5113C运行并开始扫描跳频 AT(.com_text.ctp) void spt5113c_start_work_with_scan(void) { uint8_t reg_temp; uint8_t hopping_ctrl[3] = {0x01, 0x00, 0x00}; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB0, hopping_ctrl, 3); spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); reg_temp &= 0xDF; reg_temp |= 0x03; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); UPDATE_INFO("#### spt5113c start work with scan.\r\n"); } //SPT5113C按照给定的频率运行 AT(.com_text.ctp) void spt5113c_start_work_with_freqset(uint16_t freqset) { uint8_t reg_temp = 0; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB0, ®_temp, 1); reg_temp = (uint8_t)(freqset & 0xFF); spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB1, ®_temp, 1); reg_temp = (uint8_t)((freqset >> 8) & 0xFF); spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB2, ®_temp, 1); spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); reg_temp &= 0xDF; reg_temp |= 0x03; spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, ®_temp, 1); UPDATE_INFO("#### spt5113c start work with freq set: %d.\r\n", freqset); } //SPT5113C查询扫描跳频状态 AT(.com_text.ctp) bool spt5113c_freq_check_cmd_finish_get(void) { uint8_t check_cmd_finish = 0x01; spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0x2FB0, &check_cmd_finish, 1); return (check_cmd_finish == 0x00 ? true : false); } //SPT5113C获取扫描跳频完成得到的频率 AT(.com_text.ctp) uint16_t spt5113c_freq_result_get(void) { uint16_t tp_freq = 0; spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0x2FB1, (uint8_t *)&tp_freq, 2); //0x2FB1: LowByte, 0x2FB2: HighByte return tp_freq; } //SPT5113C读取临时保存的跳频结果 AT(.com_text.ctp) uint16_t spt5113c_freq_save_get(void) { return spt5113c_save_freq; } //SPT5113C临时保存跳频结果 AT(.com_text.ctp) void spt5113c_freq_save_set(uint16_t freqset) { spt5113c_save_freq = freqset; } AT(.com_text.ctp) static bool spt5113c_firmware_update(void) { FIRMWARE_UPDATE_STATUS status = EXEC_OK; UPDATE_INFO("\r\n#######################plxc spt5113c firmware update#######################\r\n"); //reset spt5113c_reset(); UPDATE_INFO("# spt5113c reset.\r\n"); spt5113c_is_init = true; //connect status = spt5113c_asu_connect(); if(status == EXEC_OK) { UPDATE_INFO("# spt5113c connect success!\r\n"); } else { UPDATE_INFO("# spt5113c connect fail. fail code:%d\r\n", status); goto exit; } //write code to rom status = spt5113c_write_code(0, (uint8_t *)spt5113c_firmware, FIRMWARE_SIZE);//run code 79ms. //check code status = spt5113c_crc_check(); if(status == EXEC_OK) { UPDATE_INFO("### spt5113c update success!\r\n"); } else { UPDATE_INFO("### spt5113c update fail!\r\n"); goto exit; } // spt5113c_start_work(); //exit must reboot return true; exit: // spt5113c_start_work(); //exit must reboot return false; } AT(.com_text.ctp) void spt5113c_enter_sleep(void) { uint8_t temp_data; temp_data = 0xFF; spt5113c_i2c_write_8bit(APP_DEV_ADDR, 0xFF, &temp_data, 1); temp_data = 0x03; spt5113c_i2c_write_8bit(APP_DEV_ADDR, 0xE5, &temp_data, 1); // temp_data = 0x01; // spt5113c_i2c_write_8bit(APP_DEV_ADDR, 0xFE, &temp_data, 1); } AT(.com_text.ctp) void spt5113c_readkick(void) { spt5113c_i2c_read_8bit_kick(APP_DEV_ADDR, 0x00, spt5113c_buff, sizeof(spt5113c_buff)); } AT(.com_text.ctp) bool spt5113c_get_point(int32_t *x, int32_t *y) { uint8_t temp_data = 0x01; bool press = false; #if CTP_SUPPORT_COVER if (spt5113c_buff[0] == 0x80) { memset(spt5113c_buff, 0, sizeof(spt5113c_buff)); *x = -1; *y = -1; return false; } #endif *x = ((spt5113c_buff[3] & 0x0F) << 8) + spt5113c_buff[4]; *y = ((spt5113c_buff[5] & 0x0F) << 8) + spt5113c_buff[6]; press = ((spt5113c_buff[3] & 0xC0) == 0x80) ? true : false; return press; } AT(.com_text.ctp) void spt5113c_wake_up(void) { spt5113c_firmware_update(); } #endif