Files
kunlun/pib/src/iot_cal_data.c

344 lines
9.5 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_mem.h"
#include "iot_errno.h"
#include "iot_mtd.h"
#include "iot_cal_data.h"
#include "iot_io.h"
#include "iot_crc.h"
#include "os_utils_api.h"
typedef struct _iot_cal_data_obj_t {
uint8_t ready;
uint8_t mtd_err;
iot_cal_data_cfg_t cal_data_cfg;
} iot_cal_data_obj_t;
uint32_t iot_cal_data_check_mask(iot_cal_data_cfg_t *calcfg, uint8_t type)
{
uint32_t ret = 0;
if (calcfg->halphy_cfg.magic != IOT_OEM_PHY_MAGIC_NUM) {
return ret;
}
/* new id need to check mask FFFFFFFF issue */
switch (type) {
case IOT_PHY_CFG_MASK_CHIPID:
case IOT_PHY_CFG_MASK_PPM:
case IOT_PHY_CFG_MASK_TX_DC:
case IOT_PHY_CFG_MASK_RX_DC:
case IOT_PHY_CFG_MASK_PT_VER:
{
ret = (calcfg->halphy_cfg.mask >> type) & 0x1;
break;
}
case IOT_PHY_CFG_MASK_CALI_TEMP:
case IOT_PHY_CFG_MASK_CALI_ADC:
case IOT_PHY_CFG_MASK_CALI_RF_TXIQM:
case IOT_PHY_CFG_MASK_CALI_RF_TXF:
case IOT_PHY_CFG_MASK_CALI_PT_INFO:
case IOT_PHY_CFG_MASK_CALI_RF_RXIQM:
{
ret = (calcfg->halphy_cfg.mask != 0xFFFFFFFF) &&
((calcfg->halphy_cfg.mask >> type) & 0x1);
break;
}
default:
break;
}
return ret;
}
void iot_cal_data_set_mask(iot_cal_data_cfg_t *calcfg, uint8_t type)
{
if (calcfg->halphy_cfg.magic != IOT_OEM_PHY_MAGIC_NUM) {
IOT_ASSERT(0);
}
switch (type) {
case IOT_PHY_CFG_MASK_CHIPID:
case IOT_PHY_CFG_MASK_PPM:
case IOT_PHY_CFG_MASK_TX_DC:
case IOT_PHY_CFG_MASK_RX_DC:
case IOT_PHY_CFG_MASK_PT_VER:
case IOT_PHY_CFG_MASK_CALI_TEMP:
case IOT_PHY_CFG_MASK_CALI_ADC:
case IOT_PHY_CFG_MASK_CALI_RF_TXIQM:
case IOT_PHY_CFG_MASK_CALI_RF_TXF:
case IOT_PHY_CFG_MASK_CALI_PT_INFO:
case IOT_PHY_CFG_MASK_CALI_RF_RXIQM:
{
calcfg->halphy_cfg.mask |= (1 << type);
break;
}
default:
IOT_ASSERT(0);
}
}
static uint32_t iot_cal_data_read_mtd(uint8_t *buf, uint32_t size, uint32_t offset)
{
uint32_t ret = ERR_FAIL;
int fd = 0;
int status = 0;
uint8_t cal_data_prtition = 0;
do {
status = dev_get_cal_data_part_num(&cal_data_prtition);
if (status) {
break;
}
iot_printf("%s caldata partition id:%d\n", __FUNCTION__, cal_data_prtition);
fd = dev_open(cal_data_prtition, 0);
if (fd < 0) {
fd = 0;
break;
}
status = dev_seek(fd, offset, DEV_SEEK_SET);
if (status < 0) {
break;
}
status = dev_read(fd, buf, size);
if (status < 0) {
break;
}
ret = ERR_OK;
} while (0);
if (fd) {
dev_close(fd);
}
return ret;
}
static uint32_t iot_cal_data_write_mtd(uint8_t *buf, uint32_t size, uint32_t offset)
{
uint32_t ret = ERR_FAIL;
int fd = 0;
int status = 0;
uint8_t cal_data_prtition = 0;
do {
status = dev_get_cal_data_part_num(&cal_data_prtition);
if (status) {
break;
}
iot_printf("%s cal partition id:%d\n", __FUNCTION__, cal_data_prtition);
fd = dev_open(cal_data_prtition, 0);
if (fd < 0) {
fd = 0;
break;
}
status = dev_seek(fd, offset, DEV_SEEK_SET);
if (status < 0) {
break;
}
status = dev_write(fd, buf, size);
if (status < 0) {
break;
}
ret = ERR_OK;
} while (0);
if (fd) {
dev_close(fd);
}
return ret;
}
static iot_cal_data_obj_t gbl_cal_data_cfg = { 0 };
uint32_t iot_cal_data_set_cfg(iot_cal_data_cfg_t* cal_data_cfg)
{
uint32_t ret = ERR_FAIL;
uint8_t crc8 = 0;
uint8_t* pbuf;
uint32_t size;
iot_cal_data_cfg_t *tmp_cal_data_cfg;
if(cal_data_cfg == NULL) {
return ret;
}
os_mem_cpy(&gbl_cal_data_cfg.cal_data_cfg, cal_data_cfg,
sizeof(iot_cal_data_cfg_t));
pbuf = (uint8_t*)&gbl_cal_data_cfg.cal_data_cfg.halphy_cfg;
size = sizeof(iot_halphy_real_cfg_t);
/* validate crc8 */
crc8 = (uint8_t)iot_getcrc8(pbuf, size);
gbl_cal_data_cfg.cal_data_cfg.crc = crc8;
ret = iot_cal_data_write_mtd((uint8_t*)&gbl_cal_data_cfg.cal_data_cfg,
sizeof(iot_cal_data_cfg_t), 0);
if(ret != ERR_OK)
{
gbl_cal_data_cfg.ready = 0;
gbl_cal_data_cfg.mtd_err = 1;
} else {
gbl_cal_data_cfg.ready = 0;
gbl_cal_data_cfg.mtd_err = 0;
ret = iot_cal_data_get_cfg(&tmp_cal_data_cfg);
}
return ret;
}
uint32_t iot_cal_data_get_cfg(iot_cal_data_cfg_t** cal_data_cfg)
{
uint32_t ret = ERR_FAIL;
uint8_t crc8 = 0;
uint8_t* pbuf;
uint32_t size;
uint32_t ver;
if (gbl_cal_data_cfg.ready != 1) {
ret = iot_cal_data_read_mtd((uint8_t*)&gbl_cal_data_cfg.cal_data_cfg, \
sizeof(iot_cal_data_cfg_t), 0);
if (ret == ERR_OK) {
pbuf = (uint8_t*)&gbl_cal_data_cfg.cal_data_cfg.halphy_cfg;
size = sizeof(iot_halphy_real_cfg_t);
/* validate crc8 */
crc8 = (uint8_t)iot_getcrc8(pbuf, size);
iot_printf("cal_crc: %x, cfg_crc: %x, cfg_pt_ver: %x, "\
"hw_ver: %d.%d.%d.%d, cfg_magic: %x.\n", \
crc8, gbl_cal_data_cfg.cal_data_cfg.crc, \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.pt_fw_ver, \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.hw_ver_major >> 8, \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.hw_ver_major & 0xFF, \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.hw_ver_minor >> 8, \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.hw_ver_minor & 0xFF, \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.magic);
ver = gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.pt_fw_ver;
if (crc8 == gbl_cal_data_cfg.cal_data_cfg.crc) {
/* new version */
if (ver && 0xFFFFFFFF != ver && \
IOT_OEM_PHY_MAGIC_NUM == \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.magic) {
gbl_cal_data_cfg.ready = 1;
ret = ERR_OK;
} else {
ret = ERR_CRC_FAIL;
}
} else {
if (0xFFFFFFFF == ver) {
if (IOT_OEM_PHY_MAGIC_NUM == \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.magic) {
gbl_cal_data_cfg.ready = 1;
/* old version */
ret = ERR_NOSUPP;
} else if (0xFFFFFFFF == \
gbl_cal_data_cfg.cal_data_cfg.halphy_cfg.magic) {
/* initial state, ready 4 1st pt */
ret = ERR_NOT_EXIST;
} else {
ret = ERR_FAIL;
}
} else {
ret = ERR_FAIL;
}
}
} else {
iot_printf("failed to read cal data mtd.\n");
}
} else {
ret = ERR_OK;
}
if (ret && ret != ERR_NOSUPP) {
gbl_cal_data_cfg.mtd_err = 1;
} else {
gbl_cal_data_cfg.mtd_err = 0;
}
*cal_data_cfg = &gbl_cal_data_cfg.cal_data_cfg;
return ret;
}
uint32_t iot_cal_data_get_adc_m_cali(iot_adc_m_cal_data_t **adc_m_cali_data)
{
uint32_t ret = ERR_FAIL;
iot_cal_data_cfg_t *calcfg = NULL;
ret = iot_cal_data_get_cfg(&calcfg);
if (ERR_OK == ret) {
if (iot_cal_data_check_mask(calcfg, IOT_PHY_CFG_MASK_CALI_ADC)) {
*adc_m_cali_data = &calcfg->halphy_cfg.cali_adc_m;
} else {
ret = ERR_FAIL;
}
}
return ret;
}
uint32_t iot_cal_data_get_rf_phy_txiqm_cali(
iot_cal_data_rf_ver_phy_txiqm_t **cali)
{
uint32_t ret = ERR_FAIL;
iot_cal_data_cfg_t *calcfg = NULL;
ret = iot_cal_data_get_cfg(&calcfg);
if (ERR_OK == ret) {
if (iot_cal_data_check_mask(calcfg, IOT_PHY_CFG_MASK_CALI_RF_TXIQM)) {
*cali = &calcfg->halphy_cfg.rf_txiqm;
} else {
ret = ERR_FAIL;
}
}
return ret;
}
uint32_t iot_cal_data_get_rf_phy_txf_cali(iot_cal_data_rf_phy_txf_t **cali)
{
uint32_t ret = ERR_FAIL;
iot_cal_data_cfg_t *calcfg = NULL;
ret = iot_cal_data_get_cfg(&calcfg);
if (ERR_OK == ret) {
if (iot_cal_data_check_mask(calcfg, IOT_PHY_CFG_MASK_CALI_RF_TXF)) {
*cali = &calcfg->halphy_cfg.rf_txf;
} else {
ret = ERR_FAIL;
}
}
return ret;
}
uint32_t iot_cal_data_get_mtd_sts(void)
{
if(gbl_cal_data_cfg.mtd_err){
return ERR_FAIL;
} else{
return ERR_OK;
}
}
void iot_cal_data_init(void)
{
}