344 lines
9.5 KiB
C
344 lines
9.5 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.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
/* 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)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|