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

753 lines
23 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 "include.h"
#include "bsp_i2c.h"
#include "axs5106.h"
#include "app_variable.h"
#if (CTP_SELECT | CTP_AXS5106)
#define AXS_UPGRADE_ENABLE
#ifdef AXS_UPGRADE_ENABLE
#define AXS_UPGRADE_CHECK_VERSION 1
#define AXS_UPGRADE_FAILED_RETRY_TIMES 1
#define AXS_UPGRADE_FAST_MODE 1
#define AXS_UPGRADE_SYNC_VERSION 0
static const uint8_t fw_buf[] = {
#if AXS_UPGRADE_SYNC_VERSION
#include "GD9853_G2538B_AXS5106_V01_03_20231116_App_async.h"
#elif (CTP_SELECT == CTP_AXS5106L)
#include "ZX_S2403062_TZ1_TB36_AXS5106L_TJD_V01_00_20240315_App.h"
#elif (CTP_SELECT == CTP_TZ1_T168_AXS5106L_TJD_V01)
#include "ZX_S2404094_TZ1_T168_AXS5106L_TJD_V01_00_20240402_App.h"
#elif (CTP_SELECT == CTP_TZ64_T168_AXS5106L_TJD_V01)
#include "ZX_S2406017_T14833_TZ64A_G3270B_01_AXS5106L_TJD_V01_00_20240611_App.h"
#elif (CTP_SELECT == CTP_TZ1_T83_AXS5106L_TJD_V01)
#include "ZX_S2406077_TZ1_T83_AXS5106L_TJD_V01_00_20240628_App.h"
#elif (CTP_SELECT == CTP_T14833_TZ64A_KP871_AXS5106L_TJD_V01)
#include "ZX_S2407020_T14833-TZ64A_KP871-S107_AXS5106L_TJD_V01_00_20240709_App.h"
#elif (CTP_SELECT == CTP_T14833_TZ64A_KP871_AXS5106L_TJD_V02)
#include "ZX_S2407020_T14833-TZ64A_KP871-S107_AXS5106L_TJD_V01_02_20240814_App.h"
#elif (CTP_SELECT == CTP_TZ2_TB71_A_AXS5106L_TJD_V01)
#include "ZX_S2407031_TZ2_TB71-A_AXS5106L_TJD_V01_00_20240715_App.h"
#elif (CTP_SELECT == CTP_TZ19A_KYA002_AXS5106L_TJD_V01)
#include "ZX_S2409003_TZ19C_KYA002_AXS5106L_TJD_V01_01_20240920_App.h"
#elif (CTP_SELECT == CTP_TZ19A_FWT038_AXS5106L_TJD_V01)
#include "ZX_S2409038_TZ19A_FWT038_AXS5106L_TJD_V01_00_20240912_App.h"
#elif (CTP_SELECT == CTP_TZ19A_FWT038_KYA012_AXS5106L_TJD_V01)
#include "ZX_S2411026_TZ19A_FWT030_KYA012_AXS5106L_TJD_V01_00_20241114_App.h"
#elif (CTP_SELECT == CTP_TZ19A_MWD_1219_V1_AXS5106L_TJD_V01)
#include "ZX_S2410064_TZ19A_MWD-1219-V1_AXS5106L_TJD_V01_00_20241029_App.h"
#elif (CTP_SELECT == CTP_TZ19A_KYA029_AXS5106L_TJD_V01)
#include "ZX_S2410079_TZ19A_KYA029_AXS5106L_TJD_V01_00_20241031_App.h"
#else
#include "GD9853_G2538B_AXS5106_V01_03_20231106_App.h"
#endif // AXS_UPGRADE_SYNC_VERSION
};
#endif
#define TRACE_EN 0
#if TRACE_EN
#define TRACE(...) printf(__VA_ARGS__)
#else
#define TRACE(...)
#endif
#define I2C_ADDR_AXS5106 (0x63)
// RST PE3
#if (FLASH_SIZE == FSIZE_8M)
#define AXS5106_RESET_FEN GPIOBFEN
#define AXS5106_RESET_PDIR GPIOBDIR
#define AXS5106_RESET_PORTSET GPIOBSET
#define AXS5106_RESET_PORTCLR GPIOBCLR
#define AXS5106_RESET_FEN GPIOBFEN
#define AXS5106_RESET_DE GPIOBDE
#define AXS5106_RESET 7
#elif (CHIP_PACKAGE_SELECT == CHIP_5682C)
// RST PE3
#define AXS5106_RESET_FEN GPIOEFEN
#define AXS5106_RESET_PDIR GPIOEDIR
#define AXS5106_RESET_PORTSET GPIOESET
#define AXS5106_RESET_PORTCLR GPIOECLR
#define AXS5106_RESET_FEN GPIOEFEN
#define AXS5106_RESET_DE GPIOEDE
#define AXS5106_RESET 3
#else
// RST PE7
#define AXS5106_RESET_FEN GPIOEFEN
#define AXS5106_RESET_PDIR GPIOEDIR
#define AXS5106_RESET_PORTSET GPIOESET
#define AXS5106_RESET_PORTCLR GPIOECLR
#define AXS5106_RESET_FEN GPIOEFEN
#define AXS5106_RESET_DE GPIOEDE
#define AXS5106_RESET 7
#endif
//// INT PF3
//
//#define AXS5106_INT_PDIR GPIOFDIR
//#define AXS5106_INT_PORTSET GPIOFSET
//#define AXS5106_INT_PORTCLR GPIOFCLR
//#define AXS5106_INT_FEN GPIOFFEN
//#define AXS5106_INT_DE GPIOFDE
//#define AXS5106_INT 3
#define AXS5106_WRITE_ADDR(ADDR) ((ADDR) << 1)
#define AXS5106_READ_ADDR(ADDR) ((ADDR) << 1 | 1)
#define AXS5106_FINGER_MAX 1
#define TOUCH_DATA_GROUP_LEN 4
#define TOUCH_DATA_LEN (2 + TOUCH_DATA_GROUP_LEN * AXS5106_FINGER_MAX)
#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 __AX5106_IIC1 = {
.sfr = (i2c_sfr_t *) &IIC1CON0,
.map = (i2c_map_t *) &FUNCMCON2,
};
i2c_t *AX5106_IICx = &__AX5106_IIC1;
#else
#if (CHIP_PACKAGE_SELECT == CHIP_5682C)
static i2c_t __AX5106_IIC1 = {
.sfr = (i2c_sfr_t *) &IIC1CON0,
.map = (i2c_map_t *) &FUNCMCON2,
};
i2c_t *AX5106_IICx = &__AX5106_IIC1;
#else
static i2c_t __AX5106_IIC0 = {
.sfr = (i2c_sfr_t *) &IIC0CON0,
.map = (i2c_map_t *) &FUNCMCON2,
};
i2c_t *AX5106_IICx = &__AX5106_IIC0;
#endif
#endif
#ifdef AXS_UPGRADE_ENABLE
static bool axs_fwupg_get_ver_in_bin(uint16_t *ver);
//static bool axs_fwupg_get_ver_in_tp(uint16_t *ver);
static bool axs_fwupg_get_pj_id_in_bin(uint16_t *ver);
//static bool axs_fwupg_get_pj_id_in_tp(uint16_t *ver);
static void axs_fwupg_enter_debug_mode(void);
static void axs_fwupg_exit_debug_mode(void);
static bool axs_fwupg_unlock_mtpc_wp(void);
static bool axs_fwupg_flash_erase(void);
static bool axs_fwupg_flash_write(const uint8_t *fw_buf, uint16_t fw_len);
static bool axs_fwupg_write_flash(void);
bool axs_upgrade_process(void);
#ifdef AXS_UPGRADE_CHECK_VERSION
static bool axs_fwupg_need_upgrade(void);
#endif
#define MAX_TP_UPDATE_LEN_ONCE (0x4000) // 加大buffer 一次传完测试Ok
u8 tp_ota_buf[ MAX_TP_UPDATE_LEN_ONCE] AT(.ctp_ota);
#endif
#if TRACE_EN
AT(.com_rodata.tp)
const char tp_read[] = "AX5106_IICx->sfr->IICxCMDA: %x len: %d \n";
//AT(.com_rodata.tp)
//const char AX5106_IICx->sfr->IICx_DATA[] = " read AX5106_IICx->sfr->IICxCON0: %x AX5106_IICx->sfr->IICxCON1:%x AX5106_IICx->sfr->IICxCMDA: %x AX5106_IICx->sfr->IICxDMAADR: %x AX5106_IICx->sfr->IICxDMACNT: %x \n";
//
//AT(.com_rodata.tp)
//const char AX5106_IICx->sfr->IICx_DATA2[] = "read2 AX5106_IICx->sfr->IICxCON0: %x AX5106_IICx->sfr->IICxCON1:%x AX5106_IICx->sfr->IICxCMDA: %x AX5106_IICx->sfr->IICxDMAADR: %x AX5106_IICx->sfr->IICxDMACNT: %x \n";
//
//AT(.com_rodata.tp)
//const char AX5106_IICx->sfr->IICx_wDATA[] = "writ AX5106_IICx->sfr->IICxCON0: %x AX5106_IICx->sfr->IICxCON1:%x AX5106_IICx->sfr->IICxCMDA: %x AX5106_IICx->sfr->IICxDMAADR: %x AX5106_IICx->sfr->IICxDMACNT: %x \n";
//
//AT(.com_rodata.tp)
//const char AX5106_IICx->sfr->IICx_wDATA2[] = "writ2 AX5106_IICx->sfr->IICxCON0: %x AX5106_IICx->sfr->IICxCON1:%x AX5106_IICx->sfr->IICxCMDA: %x AX5106_IICx->sfr->IICxDMAADR: %x AX5106_IICx->sfr->IICxDMACNT: %x \n";
AT(.com_rodata.tp)
const char tp_str[] = "%x %x \n";
AT(.com_rodata.tp)
const char tp_x_y[] = "x: %d y: %d \n";
AT(.com_rodata.tp)
const char h_str[] = "\n";
AT(.com_rodata.tp)
const char d_str[] = "down:%d,%d\n";
AT(.com_rodata.tp)
const char u_str[] = "up\n";
#endif
uint8_t tp_data[TOUCH_DATA_LEN];
AT(.com_text.ctp)
static void tp_i2c_read_kick(uint8_t subAddr, uint8_t *read_data, u16 len)
{
AX5106_IICx->sfr->IICxCMDA = (I2C_READ_ADDR(I2C_ADDR_AXS5106) << 24) | (subAddr << 8) | I2C_WRITE_ADDR(I2C_ADDR_AXS5106); //0x2A
AX5106_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | BIT(5) | BIT(4) | BIT(3) | len;
AX5106_IICx->sfr->IICxDMAADR = DMA_ADR(read_data);
AX5106_IICx->sfr->IICxDMACNT = ((len - 1) << 16) | BIT(0);
AX5106_IICx->sfr->IICxCON0 |= BIT(28); //KICK
}
AT(.text.sensor.AXS5106) __attribute__((unused))
static void tp_i2c_write(uint16_t subAddr, const uint8_t *write_data, u16 len)
{
//tp_i2c_write_do(false, I2C_ADDR_AXS5106, subAddr, false, write_data, len);
u32 ticks;
AX5106_IICx->sfr->IICxCMDA = (subAddr << 8) | I2C_WRITE_ADDR(I2C_ADDR_AXS5106); //0x2A
AX5106_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(10) | BIT(5) | BIT(4) | BIT(3) ;
AX5106_IICx->sfr->IICxDMAADR = DMA_ADR(write_data);
AX5106_IICx->sfr->IICxDMACNT = ((len - 1) << 16) | BIT(1) |BIT(0);
AX5106_IICx->sfr->IICxCON0 |= BIT(28); //KICK
delay_ms(2);
ticks = tick_get();
while (!(AX5106_IICx->sfr->IICxCON0 & BIT(31))) {
if (tick_check_expire(ticks, 20)) {
TRACE("tp_i2c_write time out ERROR\n");
return;
}
}
AX5106_IICx->sfr->IICxCON0 |= BIT(29); //Clear Pending
}
AT(.text.sensor.AXS5106) __attribute__((unused))
static void tp_i2c_read(uint8_t subAddr, uint8_t *read_data, u16 len)
{
// tp_i2c_read_do(false, I2C_ADDR_AXS5106, subAddr, false, read_data, len);
u32 ticks;
AX5106_IICx->sfr->IICxCMDA = (I2C_READ_ADDR(I2C_ADDR_AXS5106) << 24) | (subAddr << 8) | I2C_WRITE_ADDR(I2C_ADDR_AXS5106); //0x2A
AX5106_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(9) | BIT(8) | BIT(7) | BIT(5) | BIT(4) | BIT(3) | len;
AX5106_IICx->sfr->IICxDMAADR = DMA_ADR(read_data);
AX5106_IICx->sfr->IICxDMACNT = ((len - 1) << 16) | BIT(0);
AX5106_IICx->sfr->IICxCON0 |= BIT(28); //KICK
ticks = tick_get();
while (!(AX5106_IICx->sfr->IICxCON0 & BIT(31))) {
if (tick_check_expire(ticks, 20)) {
TRACE("tp_i2c_read time out ERROR\n");
return;
}
}
AX5106_IICx->sfr->IICxCON0 |= BIT(29); //Clear Pending
}
AT(.text.sensor.AXS5106)
void AXS5106_io_init(void)
{
// Reset
AXS5106_RESET_FEN &= ~BIT(AXS5106_RESET);
AXS5106_RESET_PORTSET = BIT(AXS5106_RESET);
AXS5106_RESET_PDIR &= ~BIT(AXS5106_RESET);
AXS5106_RESET_DE |= BIT(AXS5106_RESET);
}
AT(.text.sensor.AXS5106)
void AXS5106_reset(void)
{
u8 cmd = 0xff;
TRACE("AXS5106_reset data:\n");
AXS5106_RESET_PORTCLR |= BIT(AXS5106_RESET);
delay_us(50);
tp_i2c_write(0xff, &cmd, 1);
delay_ms(25);
AXS5106_RESET_PORTSET |= BIT(AXS5106_RESET);
}
void tp_sleep_en(void)
{
u8 cmd = 0x03;
tp_i2c_write(0x19, &cmd, 1);
}
#ifdef AXS_UPGRADE_ENABLE
AT(.text.sensor.AXS5106)
static uint8_t axs_upgrade_enter(void)
{
u8 i=0;
#if AXS_UPGRADE_CHECK_VERSION
AXS5106_reset();
//delay > 5ms
delay_ms(10);
if (!axs_fwupg_need_upgrade())
{
TRACE("o not need upgrade:\n");
return -1; /*do not need upgrade*/
}
#endif
for (i=0; i<(AXS_UPGRADE_FAILED_RETRY_TIMES+1); i++)
{
TRACE("axs_upgrade_enter:\n");
if (axs_upgrade_process())
{
break; // success
}
}
if (i==(AXS_UPGRADE_FAILED_RETRY_TIMES+1))
{
return -2;/*upgrade failed*/
}
return 0;/*upgrade success*/
}
#endif
AT(.text.sensor.AXS5106)
int axs_read_fw_version(uint16_t *ver)
{
uint8_t firmware_ver[2];
delay_ms(50);
tp_i2c_read(0x05, firmware_ver, 2);
*ver = ((firmware_ver[0]<<8)|firmware_ver[1]);
TRACE("axs_read_fw_version: %x %x \n", firmware_ver[0], firmware_ver[1]);
return true;
}
AT(.text.sensor.AXS5106)
int axs_read_fw_chipid(uint16_t *chipid)
{
uint8_t firmware_chipid[3];
tp_i2c_read(0x08, firmware_chipid, 3);
*chipid = ((firmware_chipid[1]<<8)|firmware_chipid[2]);
return true;
}
AT(.text.sensor.AXS5106)
int axs_read_fw_pj_id(uint16_t *pj_id)
{
uint8_t firmware_pj_id[2];
tp_i2c_read(0x0A, firmware_pj_id, 2);
*pj_id = ((firmware_pj_id[0]<<8)|firmware_pj_id[1]);
return true;
}
AT(.text.sensor.AXS5106)
bool AXS5106_init(void)
{
uint16_t TP_verison = 0;
uint16_t chip_ID = 0;
AXS5106_io_init();
//axs_read_fw_version(&TP_verison);
delay_5ms(2);
AXS5106_reset();
delay_5ms(10);
axs_read_fw_chipid(&chip_ID);
if (chip_ID != CTP_AXS5106_CHIP_ID && chip_ID != CTP_AXS5106_CHIP_NONE_ID) {
return false;
}
// uint8_t cmd[1];
// cmd[0] = 0x60;
// tp_i2c_write(0xFA, cmd,1); //报点模式
// cmd[0] = 0x00;
// tp_i2c_write(0xFC, cmd,1); //关闭手势自动复位
// tp_i2c_write(0xFD, cmd,1); //关闭长按自动复位
//tp_i2c_read(0xFA, &tmp,1);
//TRACE("read 0xFA :%x\n",tmp);
// u8 info[4];
// delay_ms(200);
// ctp_iic_read(info, 0x08, 1);
// TRACE("info: %x :%02x %02x %02x \n", info[0], info[1], info[2], info[3]);
#ifdef AXS_UPGRADE_ENABLE
axs_upgrade_enter();
#endif
if (chip_ID == CTP_AXS5106_CHIP_NONE_ID) {
axs_read_fw_chipid(&chip_ID);
if (chip_ID != CTP_AXS5106_CHIP_ID) {
return false;
}
}
set_ctp_chip_ID(chip_ID);
// axs_read_fw_version(&TP_verison);
// axs_read_fw_chipid(&chip_ID);
// TRACE("TP_verison:%x ,chip_ID:%x \n", TP_verison, chip_ID);
return true;
// if (TP_verison == 0 || chip_ID != 0x0601) {
// TRACE("Touch error! TP_verison = %x, true is 1, chip_ID = %x, true is b6\r\n", TP_verison, chip_ID);
// return true;
// } else {
// return true;
// }
}
AT(.com_text.ctp)
//void AXS5106_get_touch_point(void)
void AXS5106_read_readkick(void)
{
tp_i2c_read_kick(0x01, tp_data, TOUCH_DATA_LEN);
}
// AT(.com_rodata.tp)
// const char err_str[] = "----> return:%x, %x\n";
AT(.com_rodata.tp)
const char test_str[] = "----> AXS5106d:%x, %x\n";
AT(.com_text.ctp)
bool AXS5106_get_touch_point(s32 *x, s32 *y)
{
uint8_t touch_num = tp_data[1];
u8 touch_type = tp_data[2] >> 4;
*x = ((u16)(tp_data[2] & 0x0f) << 8) + (u16)tp_data[3];
*y = ((u16)(tp_data[4] & 0x0f) << 8) + (u16)tp_data[5];
// printf(test_str, *x,*y);
#if CTP_SUPPORT_COVER
if(tp_data[0] == 0x80)//一处控制就好
{
*x = -1;
*y = -1;
return false;
}
#endif
if (touch_type == 0x00 && touch_num) { //第一次按下
return true;
} else if (touch_type == 0x04 && !touch_num) { //抬起
return false;
} else if (touch_type == 0x08 && touch_num) { //按住
return true;
}
return true;
}
#ifdef AXS_UPGRADE_ENABLE
AT(.text.sensor.AXS5106)
static void tp_i2c_write_regs(const uint8_t *subAddr_data, u16 reg_len, const uint8_t *write_data, u16 len)
{
TRACE("%s \n", __func__);
u32 ticks;
u16 transfer_len = 0;
u32 regen_addr1 = 0;
u32 regen_addr2 = 0;
u32 iicxcon0 = AX5106_IICx->sfr->IICxCON0;
u32 iicxcon1 = AX5106_IICx->sfr->IICxCON1;
//50KHZ 低速配置IIC模块
AX5106_IICx->sfr->IICxCON0 = BIT(10) | (63 << 4) | BIT(0) | (0 << 2); //WSCL_OPT, POSDIV, IIC EN
regen_addr1 = I2C_WRITE_ADDR(I2C_ADDR_AXS5106);
regen_addr2 = subAddr_data[0];
memcpy(tp_ota_buf, &subAddr_data[1], reg_len -1);
memcpy(&tp_ota_buf[reg_len -1], write_data, len);
transfer_len = len + reg_len -1 ;
TRACE("transfer_len: %d \n", transfer_len);
AX5106_IICx->sfr->IICxCMDA = (regen_addr2 << 8) | regen_addr1; //0x2A
AX5106_IICx->sfr->IICxCON1 = BIT(12) | BIT(11) | BIT(10) | BIT(5) | BIT(4) | BIT(3) ;
AX5106_IICx->sfr->IICxDMAADR = DMA_ADR(tp_ota_buf);
AX5106_IICx->sfr->IICxDMACNT = ((transfer_len-1) << 16) | BIT(1) |BIT(0);
AX5106_IICx->sfr->IICxCON0 |= BIT(28); //KICK
delay_ms(2);
ticks = tick_get();
while (!(AX5106_IICx->sfr->IICxCON0 & BIT(31))) {
WDT_CLR();
if (tick_check_expire(ticks, 10000)) {
TRACE("tp_i2c_write_regs ERROR timerout \n");
return ;
}
}
AX5106_IICx->sfr->IICxCON0 |= BIT(29); //Clear Pending
AX5106_IICx->sfr->IICxCON0 = iicxcon0;
AX5106_IICx->sfr->IICxCON1 = iicxcon1;
}
AT(.text.sensor.AXS5106)
static bool axs_fwupg_get_ver_in_bin(uint16_t *ver)
{
uint16_t ver_offset = 0x400;
if (!ver)
{
TRACE("axs_data/upgrade/func/fw/ver is NULL");
return FALSE;
}
if (sizeof(fw_buf) < ver_offset)
{
TRACE("fw len(0x%0x) < fw ver offset(0x%x)",
sizeof(fw_buf), ver_offset);
return FALSE;
}
*ver = ((fw_buf[ver_offset]<<8)|(fw_buf[ver_offset+1]));
TRACE("current version :%x \n", *ver);
return TRUE;
}
AT(.text.sensor.AXS5106)
static bool axs_fwupg_get_pj_id_in_bin(uint16_t *ver)
{
uint16_t ver_offset = 0x402;
if (!ver)
{
TRACE("axs_data/upgrade/func/fw/ver is NULL");
return FALSE;
}
if (sizeof(fw_buf) < ver_offset)
{
TRACE("fw len(0x%0x) < fw ver offset(0x%x)",
sizeof(fw_buf), ver_offset);
return FALSE;
}
*ver = ((fw_buf[ver_offset]<<8)|(fw_buf[ver_offset+1]));
return TRUE;
}
/******************************************************************************
*@Description : ɽ¼¶׼±¸£¬½øȫdebugģʽ
*@Function : axs_fwupg_enter_debug_mode
*@Note :
*******************************************************************************/
AT(.text.sensor.AXS5106)
static void axs_fwupg_enter_debug_mode(void)
{
uint8_t debug_mode_cmd[1] = {0x55};
AXS5106_reset();
//make sure: 500us < delay time < 4ms
delay_ms(1);
tp_i2c_write(0xaa,debug_mode_cmd,1);
//delay time >= 50us
delay_us(100);
}
AT(.text.sensor.AXS5106)
static void axs_fwupg_exit_debug_mode(void)
{
uint8_t debug_mode_cmd[1] = {0x5f};
tp_i2c_write(0xa0,debug_mode_cmd,1);
}
/******************************************************************************
*@Description : ɽ¼¶׼±¸£¬½⋸±£»¤
*@Function : axs_fwupg_unlock_mtpc_wp
*@Note :
*******************************************************************************/
AT(.text.sensor.AXS5106)
static bool axs_fwupg_unlock_mtpc_wp(void)
{
uint8_t unlock_mtpc_cmd[3] = {0x6f,0xff,0xff};
tp_i2c_write(0x90,unlock_mtpc_cmd,3);
unlock_mtpc_cmd[1]=0xda;
unlock_mtpc_cmd[2]=0x18;
tp_i2c_write(0x90,unlock_mtpc_cmd,3);
return TRUE;
}
/******************************************************************************
*@Description : ɽ¼¶׼±¸£¬ǥ³ýflashĚȝ
*@Function : axs_fwupg_flash_erase
*@Note :
*******************************************************************************/
AT(.text.sensor.AXS5106)
static bool axs_fwupg_flash_erase(void)
{
uint8_t erase_cmd[3] = {0x6f,0xd6,0x77};
tp_i2c_write(0x90,erase_cmd,3);
//delay time >= 240ms
delay_ms(260);
erase_cmd[2]=0x00;
tp_i2c_write(0x90,erase_cmd,3);
return TRUE;
}
/******************************************************************************
*@Description : ɽ¼¶¶¯׷£¬½«¹̼þдȫflash
*@Function : axs_fwupg_flash_write
*@Note :
*******************************************************************************/
AT(.text.sensor.AXS5106)
static bool axs_fwupg_flash_write(const uint8_t *fw_buf, uint16_t fw_len)
{
uint8_t write_flash_cmd[3] = {0x6f,0xd4,0x00};
#if AXS_UPGRADE_FAST_MODE
uint8_t write_flash_long_reg[6] = {0x70,0x8f,0xd7,0x00,0x00,0x00};
#else
uint16_t i;
#endif
tp_i2c_write(0x90,write_flash_cmd,3);
write_flash_cmd[1]=0xd5;
tp_i2c_write(0x90,write_flash_cmd,3);
write_flash_cmd[1]=0xd2;
write_flash_cmd[2]=((fw_len-1)&0xff);
tp_i2c_write(0x90,write_flash_cmd,3);
write_flash_cmd[1]=0xd3;
write_flash_cmd[2]=(((fw_len-1)>>8)&0xff);
tp_i2c_write(0x90,write_flash_cmd,3);
write_flash_cmd[1]=0xd6;
write_flash_cmd[2]=0xf4;
tp_i2c_write(0x90,write_flash_cmd,3);
#if AXS_UPGRADE_FAST_MODE
write_flash_long_reg[4]=((fw_len-1)>>8)&0xff;
write_flash_long_reg[5]=(fw_len-1)&0xff;
// 第一次写的有c6 这个命令,后续的 fw_buf 没有c6 这个命令
TRACE("%s AXS_UPGRADE_FAST_MODE \n");
tp_i2c_write_regs(write_flash_long_reg,6,fw_buf,fw_len);
#else
write_flash_cmd[1]=0xd7;
for (i = 0; i < (fw_len); i++)
{
write_flash_cmd[2]=fw_buf[i];
tp_i2c_write(0x90,write_flash_cmd,3);
}
#endif
write_flash_cmd[1]=0xd6;
write_flash_cmd[2]=0x00;
tp_i2c_write(0x90,write_flash_cmd,3);
return TRUE;
}
/******************************************************************************
*@Description : ɽ¼¶º¯ʽ
*@Function : axs_fwupg_write_flash
*@Note :
*******************************************************************************/
AT(.text.sensor.AXS5106)
static bool axs_fwupg_write_flash(void)
{
axs_fwupg_enter_debug_mode();
// sfr
if (!axs_fwupg_unlock_mtpc_wp())
{
TRACE("axs_fwupg_flash_init failed");
return FALSE;
}
if (!axs_fwupg_flash_erase())
{
TRACE("axs_fwupg_flash_erase failed");
return FALSE;
}
// write firmware
if (!axs_fwupg_flash_write(fw_buf, sizeof(fw_buf)))
{
TRACE("axs_fwupg_flash_write failed");
return FALSE;
}
axs_fwupg_exit_debug_mode();
delay_ms(1);
return TRUE;
}
/******************************************************************************
*@Description : ɽ¼¶¼첩
*@Function : axs_fwupg_need_upgrade
*@Note :
*******************************************************************************/
#ifdef AXS_UPGRADE_CHECK_VERSION
AT(.text.sensor.AXS5106)
static bool axs_fwupg_need_upgrade(void)
{
uint16_t fw_ver_in_bin = 0;
uint16_t fw_ver_in_tp = 0;
uint16_t fw_pj_id_in_bin = 0;
uint16_t fw_pj_id_in_tp = 0;
if (!axs_fwupg_get_ver_in_bin(&fw_ver_in_bin))
{
return FALSE;
}
if (!axs_read_fw_version(&fw_ver_in_tp))
{
return FALSE; /*get firmware ver failed, do not upgrade;*/
}
if (!axs_fwupg_get_pj_id_in_bin(&fw_pj_id_in_bin))
{
return FALSE;
}
if (!axs_read_fw_pj_id(&fw_pj_id_in_tp))
{
return FALSE; /*get firmware ver failed, do not upgrade;*/
}
TRACE("fw version in tp:%x, host:%x \n", fw_ver_in_tp, fw_ver_in_bin);
TRACE("fw project id in tp:%x, host:%x \n", fw_pj_id_in_tp, fw_pj_id_in_bin);
if ((fw_ver_in_tp != fw_ver_in_bin) || (fw_pj_id_in_tp != fw_pj_id_in_bin))
{
return TRUE;
//return false;
}
else
{
TRACE("fw version is latest! \n");
}
return FALSE;
}
#endif
/******************************************************************************
*@Description : ͪջɽ¼¶Á÷³̍
*@Function : axs_upgrade_process
*@Note :
*******************************************************************************/
AT(.text.sensor.AXS5106)
bool axs_upgrade_process(void)
{
if (!axs_fwupg_write_flash())
{
TRACE("writing firmware Failed\r\n");
return FALSE;
}
return TRUE;
}
#endif
#endif //TP_AXS5106