mcu_ab568x/app/platform/gui/ctp/spt5113/spt5113c.c
2025-05-30 18:03:10 +08:00

493 lines
15 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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д<43><D0B4>ַ
#define I2C_READ_ADDR(ADDR) ((ADDR) << 1 | 1) //CTP IIC<49><43><EFBFBD><EFBFBD>ַ
#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 <20><><EFBFBD><EFBFBD> ****************************************/
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, &reg_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, &reg_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, &reg_temp, 1);
reg_temp &= 0xf0;// low 4 bits clear hold upgrade
spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, &reg_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<52><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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, &reg_temp, 1);
reg_temp &= 0xDF;
reg_temp |= 0x03;
spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, &reg_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, &reg_temp, 1);
reg_temp &= 0xDF;
reg_temp |= 0x03;
spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, &reg_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, &reg_temp, 1);
reg_temp = (uint8_t)(freqset & 0xFF);
spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB1, &reg_temp, 1);
reg_temp = (uint8_t)((freqset >> 8) & 0xFF);
spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0x2FB2, &reg_temp, 1);
spt5113c_i2c_read_16bit(ASU_DEV_ADDR, 0xC103, &reg_temp, 1);
reg_temp &= 0xDF;
reg_temp |= 0x03;
spt5113c_i2c_write_16bit(ASU_DEV_ADDR, 0xC103, &reg_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