Files
kunlun/dtest/kl1_ppm_tool/ppm_tool.c
2024-09-28 14:24:04 +08:00

407 lines
10 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "iot_bitops.h"
#include "flash.h"
#include "os_lock.h"
#include "iot_config.h"
#include "ahb_rf.h"
#include "ahb.h"
#include "clk.h"
#include "sfc.h"
#include "sec_glb.h"
#include "dbg_io.h"
#include "iot_io.h"
#include "iot_errno_api.h"
#include "gp_timer.h"
#include "flash.h"
#include "os_mem_api.h"
#include "iot_crc.h"
#include "iot_cal_data.h"
#include "uart.h"
#include "iot_string.h"
#define PPM_VERSION "V1.0"
extern struct uart_ctrl uart_e_ctrl;
iot_cal_data_cfg_t g_calc_data;
uint8_t gbuf[256];
int ppm_tool_atoi(uint8_t * str)
{
int value = 0;
int sign = 1;
int radix;
if(*str == '-')
{
sign = -1;
str++;
}
if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
{
radix = 16;
str += 2;
} else {
radix = 10;
}
while(*str)
{
if(radix == 16)
{
if(*str >= '0' && *str <= '9')
{
value = value * radix + *str - '0';
}
else if(*str >= 'A' && *str <= 'F')
{
value = value * radix + *str - 'A' + 10;
}
else if(*str >= 'a' && *str <= 'f')
{
value = value * radix + *str - 'a' + 10;
}
else
{
break;
}
}
else if(radix == 8)
{
if(*str >= '0' && *str <= '7')
{
value = value * radix + *str - '0';
}
else
{
break;
}
}
else
{
if(*str >= '0' && *str <= '9')
{
value = value * radix + *str - '0';
}
else
{
break;
}
}
str ++;
}
return sign*value;
}
/*
* String = "#PPM=-120,ptver=0x00880000,crc8=0x65#"
* crc8 protect "#PPM=-120,ptver=0x88880000,"
*/
const char input_str[] = "#PPM=+128,ptver=0x56789012,crc8=0xc0#";
uint32_t ppm_tool_uart_param_get(uint32_t *p_out_ptver, int8_t *p_out_ppm, uint32_t tm_ms)
{
uint8_t *p_w_pos = gbuf, *p_ppm, *p_ptver, *p_crc, buf[12], crc;
int8_t ppm;
uint32_t tm_start, tm_delta, ch, ptver;
tm_start = gp_timer_get_current_val(0);
tm_delta = tm_ms * 1000;
os_mem_set(gbuf, 0, sizeof(gbuf));
do {
while (uart_e_ctrl.rx_fifo_cnt(0) > 0) {
ch = uart_e_ctrl.getc(0);
*p_w_pos++ = ch & 0xFF;
}
if (sizeof(input_str) - 1 <= (p_w_pos - gbuf)) {
break;
}
} while (tm_delta > gp_timer_get_current_val(0) - tm_start);
p_w_pos = '\0';
/* Find PPM */
if (NULL == (p_ppm = (uint8_t *)iot_strstr ((char *)gbuf, "#PPM"))
|| ',' != p_ppm[9]) {
return ERR_FAIL;
}
os_mem_set(buf, 0x0, sizeof(buf));
os_mem_cpy(buf, &p_ppm[6], 3);
ppm = ppm_tool_atoi(buf);
ppm = ('-' == p_ppm[5]) ? (0 - ppm) : ppm;
/* Find ptver */
if (NULL == (p_ptver = (uint8_t *)iot_strstr ((char *)gbuf, "ptver"))
|| ',' != p_ptver[16]) {
return ERR_FAIL;
}
os_mem_set(buf, 0x0, sizeof(buf));
os_mem_cpy(buf, &p_ptver[6], 10);
ptver = (uint32_t)ppm_tool_atoi(buf);
/* Find crc8 */
if (NULL == (p_crc = (uint8_t *)iot_strstr ((char *)gbuf, "crc8"))
|| '#' != p_crc[9]) {
return ERR_FAIL;
}
os_mem_set(buf, 0x0, sizeof(buf));
os_mem_cpy(buf, &p_crc[5], 4);
crc = (uint8_t)ppm_tool_atoi(buf);
if (crc != iot_getcrc8(p_ppm, p_crc - p_ppm)) {
iot_printf("crc 0x%x != 0x%x\n", crc, iot_getcrc8(p_ppm, p_crc - p_ppm));
return ERR_FAIL;
}
*p_out_ptver = ptver;
*p_out_ppm = 0 - ppm;
return ERR_OK;
}
void ppm_tool_uart_rx_clear(void)
{
uint32_t cnt = 256;
do {
(void)uart_e_ctrl.getc(0);
} while (uart_e_ctrl.rx_fifo_cnt(0) > 0 && cnt-- > 0);
return;
}
uint32_t ppm_tool_uart_param_put(uint32_t ptver, int8_t ppm)
{
uint32_t s_len, fin_ppm;
uint8_t crc;
/* Not need to check ppm && version. */
if (0 >= ppm) {
fin_ppm = 0 - ppm;
/* Change the SIGN of ppm to uart. */
s_len = iot_sprintf((char *)gbuf, "#PPM=+%03d,ptver=0x%08x,", fin_ppm, ptver);
} else {
fin_ppm = ppm;
/* Change the SIGN of ppm to uart. */
s_len = iot_sprintf((char *)gbuf, "#PPM=-%03d,ptver=0x%08x,", fin_ppm, ptver);
}
crc = iot_getcrc8(gbuf, s_len);
iot_sprintf((char *)(gbuf + s_len), "crc8=0x%02x#", crc);
iot_printf("%s", gbuf);
return ERR_OK;
}
uint32_t ppm_tool_uart_errcode_put(uint32_t err_code)
{
iot_printf("#DONE=0x%08x#", err_code);
return ERR_OK;
}
uint32_t ppm_tool_flash_part_offset_get (void)
{
uint32_t f_size, p_offset;
f_size = flash_get_dev_size();
switch (f_size) {
case FLASH_SIZE_2MB:
/* 2m cal part start addr 0x001FF000 */
p_offset = 0x001FF000;
break;
default:
p_offset = 0x001FF000;
break;
}
return p_offset;
}
uint32_t ppm_tool_flash_data_read (iot_cal_data_cfg_t *p_cal)
{
uint32_t offset = ppm_tool_flash_part_offset_get();
if (HAL_OK != flash_read(p_cal, offset, sizeof(*p_cal), MOD_SFC_READ_QUAD_IO_FAST)) {
return ERR_FAIL;
}
return ERR_OK;
}
uint32_t ppm_tool_flash_data_write (iot_cal_data_cfg_t *p_cal)
{
uint32_t offset = ppm_tool_flash_part_offset_get();
flash_write_param_t w_param = {
.read_mode = MOD_SFC_READ_QUAD_IO_FAST,
.write_mode = MOD_SFC_PROG_QUAD,
.is_erase = 1,
.sw_mode = MOD_SW_MODE_DIS,
.erase_mode = MODE_ERASE_SECTOR
};
if (HAL_OK != flash_write(p_cal, offset, sizeof(*p_cal), &w_param)) {
return ERR_FAIL;
}
return ERR_OK;
}
void gp_timer_delay()
{
uint32_t timer_val = 0;
gp_timer_init();
gp_timer_set(0, -1, 0);
gp_timer_start(0);
while(1) {
timer_val = gp_timer_get_current_val(0);
if (timer_val > 100000) break;
}
}
void ppm_tool_hw_init (void)
{
gp_timer_delay();
dbg_uart_init();
flash_init(1);
clk_core_freq_set(CPU_FREQ_150M);
/* The basic frequency of SFC is 75m, 0 represents no frequency division */
sfc_clk_div_set(1);
return;
}
void ppm_tool_dump_version(void)
{
iot_printf("\r\n#PPM tool ver:%s %s %s#\n", PPM_VERSION, __DATE__, __TIME__);
}
void ppm_tool (void)
{
uint8_t crc8;
int8_t param_ppm = 0;
uint32_t pt_ver = 0, param_pt_ver = 0, err_code = 0;
/* Read calibration data from flash. */
if (ERR_OK != ppm_tool_flash_data_read(&g_calc_data)) {
/* Read flash failed. */
err_code = 1;
goto error_out;
}
ppm_tool_uart_rx_clear();
/* Write org ppm & pt_ver to uart. */
ppm_tool_uart_param_put(g_calc_data.halphy_cfg.pt_fw_ver, g_calc_data.halphy_cfg.ppm);
/* Read new ppm & pt_ver from uart */
if (ERR_OK != ppm_tool_uart_param_get(&param_pt_ver, &param_ppm, 10000)) {
err_code = 2;
goto error_out;
}
/* -15 ≤ ppm ≤ 15*/
if (param_ppm > 15 || param_ppm < -15) {
err_code = 3;
goto error_out;
}
pt_ver = g_calc_data.halphy_cfg.pt_fw_ver;
/* Check the top structure by crc8, only 'halphy_cfg' section. */
crc8 = iot_getcrc8((uint8_t *)&g_calc_data.halphy_cfg, sizeof(g_calc_data.halphy_cfg));
if (g_calc_data.crc == crc8) {
if (IOT_OEM_PHY_MAGIC_NUM == g_calc_data.halphy_cfg.magic) {
if (pt_ver && 0xFFFFFFFF != pt_ver) {
//iot_printf("Exist ptver:0x%08x\n", pt_ver);
if (pt_ver != param_pt_ver) {
err_code = 4;
goto error_out;
}
} else {
g_calc_data.halphy_cfg.pt_fw_ver = param_pt_ver;
g_calc_data.halphy_cfg.mask |= (1 << IOT_PHY_CFG_MASK_PT_VER);
}
/* pt_ver && halphy_cfg are OK. Just change ppm. */
g_calc_data.halphy_cfg.ppm = param_ppm;
g_calc_data.halphy_cfg.mask |= (1 << IOT_PHY_CFG_MASK_PPM);
} else {
/* Structure broken, do nothing, return ERROR. */
err_code = 5;
goto error_out;
}
} else if (0xFF == g_calc_data.crc && 0xFFFFFFFF == g_calc_data.halphy_cfg.magic) {
/* Top structure is NULL, update the data. */
g_calc_data.halphy_cfg.magic = IOT_OEM_PHY_MAGIC_NUM;
g_calc_data.halphy_cfg.pt_fw_ver = param_pt_ver;
g_calc_data.halphy_cfg.ppm = param_ppm;
g_calc_data.halphy_cfg.mask = (1 << IOT_PHY_CFG_MASK_PPM) | (1 << IOT_PHY_CFG_MASK_PT_VER);
/* Init hw version as 0. */
g_calc_data.halphy_cfg.hw_ver_major = 0;
g_calc_data.halphy_cfg.hw_ver_minor = 0;
} else {
/* Top structuer is broken, return error. */
err_code = 6;
goto error_out;
}
/* Write the whole new structure. */
g_calc_data.crc = iot_getcrc8((uint8_t *)&g_calc_data.halphy_cfg, sizeof(g_calc_data.halphy_cfg));
if (ERR_OK != ppm_tool_flash_data_write(&g_calc_data)) {
/* Read flash failed. */
err_code = 7;
goto error_out;
}
/* Read back the structure. */
if (ERR_OK != ppm_tool_flash_data_read(&g_calc_data)) {
/* Read flash failed. */
err_code = 8;
goto error_out;
}
/* Write new ppm & pt_ver to uart. */
ppm_tool_uart_param_put(g_calc_data.halphy_cfg.pt_fw_ver, g_calc_data.halphy_cfg.ppm);
error_out:
/* Handle error condition : 1. print error code to uart. */
ppm_tool_uart_errcode_put(err_code);
return;
}
int main(void) {
ppm_tool_hw_init();
ppm_tool();
ppm_tool_dump_version();
while(1);
return 0;
}