初始提交

This commit is contained in:
2024-09-28 14:24:04 +08:00
commit c756587541
5564 changed files with 2413077 additions and 0 deletions

921
driver/src/hw3/efuse.c Normal file
View File

@@ -0,0 +1,921 @@
/****************************************************************************
*
* 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 "os_types.h"
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "efuse_dig_reg.h"
#include "efuse_dig_reg_s.h"
#include "apb.h"
#include "efuse.h"
#include "efuse_mapping.h"
#include "iot_errno.h"
#include "iot_system.h"
#include "iot_utils_api.h"
#define EFUSE_WAIT_IDLE_TIMEOUT_CNT 10000000
/**
* efuse cmd
**/
typedef enum {
EFUSE_CMD_PHY_BIT_PROG = 0x00,
EFUSE_CMD_PHY_BYTE_READ,
EFUSE_CMD_PHY_MUL_BYTE_LOAD,
EFUSE_CMD_REG_BYTE_READ,
EFUSE_CMD_REG_BYTE_WRITE,
EFUSE_CMD_MAX
} EFUSE_CMD;
static volatile efuse_ctrl_reg_t *efuse_base = (volatile efuse_ctrl_reg_t *)EFUSE_BASEADDR;
void efuse_init(void)
{
/* enable apb clock */
apb_enable(APB_EFUSE);
/* kl3 after power on, eFuse data will be automatically loaded into the
* internal register, so manual loading is not required.
*/
}
void efuse_deinit(void)
{
/* disable apb clock */
apb_disable(APB_EFUSE);
}
uint8_t efuse_get_idle_statue(void)
{
/* idle is 1 */
return RE_REG_FIELD(efuse_base->efuse_idle, efuse_idle);
}
void efuse_wait_ilde_vaild(void)
{
uint32_t timer_cnt = 0;
while (!efuse_get_idle_statue()) {
__asm volatile("nop\n");
if (timer_cnt++ > EFUSE_WAIT_IDLE_TIMEOUT_CNT) {
IOT_ASSERT(0);
}
}
}
void efuse_set_bit_addr(uint8_t efuse_byte_num, uint8_t bit_index)
{
/* efuse addr: byte for number: [15:0], bit for byte: [31:16] */
WR_REG_FIELD(efuse_base->efuse_bit_addr, efuse_bit_addr_x, efuse_byte_num);
WR_REG_FIELD(efuse_base->efuse_bit_addr, efuse_bit_addr_y, bit_index);
}
void efuse_set_read_len(uint16_t len)
{
efuse_base->efuse_len_read.w = (uint32_t)len;
}
void efuse_enable_cmd_set_mode(uint8_t mode)
{
IOT_ASSERT(mode < EFUSE_CMD_MAX);
WR_REG_FIELD(efuse_base->efuse_cmd, efuse_cmd, mode);
/* enable command vaild */
WR_REG_FIELD(efuse_base->efuse_cmd, efuse_cmd_valid, 1);
}
uint16_t efuse_read_bit_ecnt(void)
{
return (uint16_t)efuse_base->efuse_status.w;
}
uint32_t efuse_read_reg(void)
{
return efuse_base->efuse_reg_read.w;
}
void efuse_write_reg(uint8_t data)
{
efuse_base->efuse_reg_write.w = (uint32_t)data;
}
uint32_t efuse_read_phy(void)
{
return efuse_base->efuse_phy_read.w;
}
uint32_t efuse_get_tpg()
{
return (uint32_t)RE_REG_FIELD(efuse_base->efuse_tpg, efuse_tpg);
}
void efuse_phy_bit_prog(uint8_t efuse_byte_num, uint8_t bit_index)
{
/* only opeation when efuse is in idle status */
efuse_wait_ilde_vaild();
efuse_set_bit_addr(efuse_byte_num, bit_index);
efuse_enable_cmd_set_mode(EFUSE_CMD_PHY_BIT_PROG);
efuse_wait_ilde_vaild();
}
uint8_t efuse_phy_byte_read(uint8_t efuse_byte_num)
{
/* only opeation when efuse is in idle status */
efuse_wait_ilde_vaild();
/* bit_index set to 0 when read the entire Byte */
efuse_set_bit_addr(efuse_byte_num, 0);
efuse_enable_cmd_set_mode(EFUSE_CMD_PHY_BYTE_READ);
efuse_wait_ilde_vaild();
return (uint8_t)efuse_read_phy();
}
void efuse_phy_load_to_reg(uint32_t offset, uint32_t len)
{
/* only opeation when efuse is in idle status */
efuse_wait_ilde_vaild();
/* bit_index set to 0 when read the entire Byte */
efuse_set_bit_addr(offset, 0);
efuse_set_read_len(len);
efuse_enable_cmd_set_mode(EFUSE_CMD_PHY_MUL_BYTE_LOAD);
efuse_wait_ilde_vaild();
}
void efuse_reg_byte_prog(uint8_t efuse_byte_num, uint8_t data)
{
/* only opeation when efuse is in idle status */
efuse_wait_ilde_vaild();
efuse_set_bit_addr(efuse_byte_num, 0);
efuse_write_reg(data);
efuse_enable_cmd_set_mode(EFUSE_CMD_REG_BYTE_WRITE);
efuse_wait_ilde_vaild();
}
uint8_t efuse_reg_byte_read(uint8_t efuse_byte_num)
{
/* only opeation when efuse is in idle status */
efuse_wait_ilde_vaild();
/* bit_index set to 0 when read the entire Byte */
efuse_set_bit_addr(efuse_byte_num, 0);
efuse_enable_cmd_set_mode(EFUSE_CMD_REG_BYTE_READ);
efuse_wait_ilde_vaild();
return (uint8_t)efuse_read_reg();
}
static uint32_t efuse_read_bytes(uint32_t offset, uint8_t len, uint8_t *p)
{
for (uint8_t i = 0; i < len; i++) {
p[i] = efuse_reg_byte_read(offset + i);
}
return 0;
}
uint32_t efuse_read(uint32_t offset)
{
/* compatible with bootram and ram program, read out 4 bytes */
uint32_t value = 0;
for (int i = 3; i >= 0; i--) {
value = (value << 8) + efuse_reg_byte_read(i + offset);
}
return value;
}
uint32_t efuse_write_bytes(uint32_t offset, uint8_t len, uint8_t *val_ptr)
{
for (uint8_t i = 0; i < len; i++) {
/* write in 1 bytes */
uint8_t val = *(val_ptr + i);
for (uint8_t j = 0; j < 8; j++) {
if (val & (1 << j)) {
efuse_phy_bit_prog(offset + i, j);
}
}
}
/* reload phy value to reg */
efuse_phy_load_to_reg(offset, len);
return 0;
}
uint32_t efuse_write(uint32_t offset, uint32_t val)
{
/* compatible with bootram and ram program, write in 4 bytes */
uint8_t temp = 0;
for (uint8_t i = 0; i < 4; i++) {
temp = (uint8_t)(val >> (i * 8));
for (uint8_t j = 0; j < 8; j++) {
if (temp & (1 << j)) {
efuse_phy_bit_prog(offset + i, j);
}
}
}
/* reload phy value to reg */
efuse_phy_load_to_reg(offset, sizeof(uint32_t));
return 0;
}
/* efuse data read and write function, kl3 private */
/* only part of the API is provided for use by ATE programs */
uint32_t efuse_get_lot_id(uint8_t *buf)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W0_ADDR;
if (buf == NULL) {
return ERR_FAIL;
}
for (uint8_t i = 0; i < 6; i++) {
buf[i] = efuse_reg_byte_read(index + i);
}
return ERR_OK;
}
uint32_t efuse_get_wafer_id()
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W1_ADDR +
(EFUSE_FUNC_ATE_WAFER_ID_OFFSET >> 3);
return efuse_reg_byte_read(index);
}
uint32_t efuse_get_die_x_coordinate()
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W1_ADDR +
(EFUSE_FUNC_ATE_DIE_X_COORDINATE_OFFSET >> 3);
return efuse_reg_byte_read(index);
}
uint32_t efuse_get_die_y_coordinate()
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_DIE_Y_COORDINATE_OFFSET >> 3);
return efuse_reg_byte_read(index);
}
uint32_t efuse_get_wafer_rev_record()
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_WAFER_REV_RECORD_OFFSET >> 3);
return efuse_reg_byte_read(index);
}
uint32_t efuse_get_ft_pass_flag(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_FT_PASS_FLAG_OFFSET >> 3);
return (efuse_reg_byte_read(index) & 0xf);
}
uint32_t efuse_get_analog_bin_ver(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_ANALOG_BIN_VER_OFFSET >> 3);
return (efuse_reg_byte_read(index) >> 4);
}
uint8_t efuse_get_dcdc_trim(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_D_VREF_TUNE_DCDC_OFFSET >> 3);
return (efuse_reg_byte_read(index) & 0xf);
}
uint32_t efuse_get_flash_ldo_out_trim(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_FLASH_LDO_OUT_TRIM_18_OFFSET >> 3);
return (efuse_reg_byte_read(index) >> 4);
}
uint32_t efuse_set_flash_ldo_out_trim(ate_ldo_value_e ldo_value)
{
uint8_t ldo_value_temp;
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W2_ADDR +
(EFUSE_FUNC_ATE_FLASH_LDO_OUT_TRIM_18_OFFSET >> 3);
if (ldo_value >= ATE_LDO_MAX || ldo_value < 0) {
return ERR_FAIL;
}
ldo_value_temp = efuse_reg_byte_read(index) | (ldo_value << 4);
efuse_write_bytes(index, 1, &ldo_value_temp);
return ERR_OK;
}
uint32_t efuse_get_d_mdll_ldo_vref_trim(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_ATE_D_MDLL_LDOVREF_TRIM_OFFSET >> 3);
return (efuse_reg_byte_read(index) & 0xf);
}
uint32_t efuse_get_d_bg_vbg_cntl(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_ATE_D_BG_VBG_CNTL_OFFSET >> 3);
return ((efuse_reg_byte_read(index) >> 4) & 0x7);
}
uint32_t efuse_get_d_bg_iccal(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_ATE_D_BG_ICCAL_OFFSET >> 3);
return (efuse_reg_byte_read(index) & 0x1f);
}
uint32_t efuse_get_rx_adc_vcm_ctrl(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_ATE_RX_ADC_VCM_CTRL_OFFSET >> 3);
return ((efuse_reg_byte_read(index) >> 5) & 0x7);
}
uint32_t efuse_get_flash_ldo_out_trim_2v5(void)
{
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_ATE_FLASH_LDO_OUT_TRIM_25_OFFSET >> 3);
return (efuse_reg_byte_read(index) & 0xf);
}
uint16_t efuse_get_sadc_meter_dc_offset_code(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_SECTION_W30_ADDR +
(EFUSE_FUNC_SADC_METER_DC_OFFSET_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_meter_dc_offset_code_n12db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W26_ADDR +
(EFUSE_FUNC_SADC_2_METER_DC_OFFSET_N12DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_meter_dc_offset_code_n6db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W26_ADDR +
(EFUSE_FUNC_SADC_2_METER_DC_OFFSET_N6DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_meter_dc_offset_code_12db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W27_ADDR +
(EFUSE_FUNC_SADC_2_METER_DC_OFFSET_12DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_meter_dc_offset_code_24db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W27_ADDR +
(EFUSE_FUNC_SADC_2_METER_DC_OFFSET_24DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_meter_vref_code(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_SECTION_W31_ADDR +
(EFUSE_FUNC_SADC_METER_VREF_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_meter_vcm_code(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_SECTION_W31_ADDR +
(EFUSE_FUNC_SADC_METER_VCM_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_dc_offset_code(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_SECTION_W29_ADDR +
(EFUSE_FUNC_SADC_TPID_DC_OFFSET_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_dc_offset_code_n12db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W24_ADDR +
(EFUSE_FUNC_SADC_2_TPID_DC_OFFSET_N12DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_dc_offset_code_n6db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W24_ADDR +
(EFUSE_FUNC_SADC_2_TPID_DC_OFFSET_N6DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_dc_offset_code_12db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W25_ADDR +
(EFUSE_FUNC_SADC_2_TPID_DC_OFFSET_12DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_dc_offset_code_24db(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_2_SECTION_W25_ADDR +
(EFUSE_FUNC_SADC_2_TPID_DC_OFFSET_24DB_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_vref_code(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_SECTION_W29_ADDR +
(EFUSE_FUNC_SADC_TPID_VREF_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
uint16_t efuse_get_sadc_tpid_vcm_code(void)
{
uint8_t byte_index;
uint16_t value = 0;
byte_index = CFG_EFUSE_MAPPING_SADC_SECTION_W30_ADDR +
(EFUSE_FUNC_SADC_TPID_VCM_OFFSET >> 3);
efuse_read_bytes(byte_index, sizeof(value), (uint8_t*)&value);
return value;
}
void efuse_get_mac_addr(uint8_t *mac)
{
if (mac == NULL) {
return;
}
#if HW_PLATFORM > HW_PLATFORM_FPGA
uint8_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W4_ADDR +
(EFUSE_FUNC_ATE_MAC_ADDR0_OFFSET >> 3);
/* mac addr len=6 */
for (uint8_t i = 0; i < 6; i++) {
mac[i] = efuse_reg_byte_read(index + i);
}
#endif
}
void efuse_set_mac_addr(uint8_t *mac)
{
uint32_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W4_ADDR +
(EFUSE_FUNC_ATE_MAC_ADDR0_OFFSET >> 3);
/* mac addr len=6 */
efuse_write_bytes(index, 6, mac);
}
void efuse_set_chip_id(uint32_t chipid)
{
/* | chid_id[15:12] | chip_id[11:8] | chip_id[7:4] | chip_id[3:0] |
* | project[3:0] | wafer[3:0] | mark[3:0] | sip[3:0] |
*/
uint32_t chipid_w = (((chipid >> 4) & 0xFF) | ((chipid & 0xF) << 8) |
((chipid & 0xF000))) & 0xFFFF;
uint32_t index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_MARK_OFFSET >> 3);
/* chip id: [15:12] wafer_version [11:8] mark [7:0] sip */
efuse_write_bytes(index, 2, (uint8_t *)&chipid_w);
}
uint32_t efuse_get_chip_id(void)
{
#if HW_PLATFORM > HW_PLATFORM_FPGA
uint32_t chipid = 0;
uint8_t byte_index;
uint8_t mark_and_wafer, sip_and_project;
/* | chid_id[15:12] | chip_id[11:8] | chip_id[7:4] | chip_id[3:0] |
* | project[3:0] | wafer[3:0] | mark[3:0] | sip[3:0] |
*/
byte_index = CFG_EFUSE_MAPPING_ATE_SECTION_W3_ADDR +
(EFUSE_FUNC_MARK_OFFSET >> 3);
mark_and_wafer = efuse_reg_byte_read(byte_index);
byte_index = CFG_EFUSE_MAPPING_ATE_SECTION_W4_ADDR +
(EFUSE_FUNC_SIP_OFFSET >> 3);
sip_and_project = efuse_reg_byte_read(byte_index);
chipid = ((sip_and_project & 0xF0) << 8) | (mark_and_wafer << 4) |
(sip_and_project & 0xF);
return chipid & 0xFFFF;
#else
return CHIP_ID_HZ3211_V1A;
#endif
}
/* about efuse_set_sub_id:
* 1.这个函数只应该被 ram.bin 调用;
* 2.ate efuse内容检查是不检查sub id的值;
* 3.上层应用sub id和chip id会被使用.
* 底层应用sub id不牵扯任何芯片资源;
*/
void efuse_set_sub_id(uint32_t subid)
{
/* | sub_id[15:12] | sub_id[11:8] | sub_id[7:4] | sub_id[3:0] |
* | project[3:0] | wafer[3:0] | mark[3:0] | sip[3:0] |
*/
uint32_t subid_w = (((subid >> 4) & 0xFF) | ((subid & 0xF) << 8) |
((subid & 0xF000))) & 0xFFFF;
uint32_t index = CFG_EFUSE_MAPPING_PATCH_SECTION_W28_ADDR +
(EFUSE_FUNC_PATCH_SUB_MARK_OFFSET >> 3);
/* sub id: [15:12] wafer_version [11:8] mark [7:0] sip */
efuse_write_bytes(index, 2, (uint8_t *)&subid_w);
}
uint32_t efuse_get_sub_id(void)
{
#if HW_PLATFORM > HW_PLATFORM_FPGA
uint32_t subid = 0;
uint8_t byte_index;
uint8_t mark_and_wafer, sip_and_project;
/* | sub_id[15:12] | sub_id[11:8] | sub_id[7:4] | sub_id[3:0] |
* | project[3:0] | wafer[3:0] | mark[3:0] | sip[3:0] |
*/
byte_index = CFG_EFUSE_MAPPING_PATCH_SECTION_W28_ADDR +
(EFUSE_FUNC_PATCH_SUB_MARK_OFFSET >> 3);
mark_and_wafer = efuse_reg_byte_read(byte_index);
byte_index = CFG_EFUSE_MAPPING_PATCH_SECTION_W28_ADDR +
(EFUSE_FUNC_PATCH_SUB_SIP_OFFSET >> 3);
sip_and_project = efuse_reg_byte_read(byte_index);
subid = ((sip_and_project & 0xF0) << 8) | (mark_and_wafer << 4) |
(sip_and_project & 0xF);
return subid & 0xFFFF;
#else
return CHIP_ID_HZ3211_V1A;
#endif
}
void efuse_get_sadc_calib_code(uint8_t id, float *vref,
float *vcm, float *dc_offset, uint8_t dc_offset_array_len)
{
if (dc_offset_array_len < 5) {
return;
}
if (id == 0) { //meter
if (dc_offset) {
/* the order is the same as sadc_hw_calib_gain_t */
dc_offset[0] = (float)efuse_get_sadc_meter_dc_offset_code_n12db();
dc_offset[1] = (float)efuse_get_sadc_meter_dc_offset_code_n6db();
dc_offset[2] = (float)efuse_get_sadc_meter_dc_offset_code();
dc_offset[3] = (float)efuse_get_sadc_meter_dc_offset_code_12db();
dc_offset[4] = (float)efuse_get_sadc_meter_dc_offset_code_24db();
}
if (vref) {
*vref = (float)efuse_get_sadc_meter_vref_code();
}
if (vcm) {
*vcm = (float)efuse_get_sadc_meter_vcm_code();
}
} else if (id == 1) { //tpid
if (dc_offset) {
/* the order is the same as sadc_hw_calib_gain_t */
dc_offset[0] = (float)efuse_get_sadc_tpid_dc_offset_code_n12db();
dc_offset[1] = (float)efuse_get_sadc_tpid_dc_offset_code_n6db();
dc_offset[2] = (float)efuse_get_sadc_tpid_dc_offset_code();
dc_offset[3] = (float)efuse_get_sadc_tpid_dc_offset_code_12db();
dc_offset[4] = (float)efuse_get_sadc_tpid_dc_offset_code_24db();
}
if (vref) {
*vref = (float)efuse_get_sadc_tpid_vref_code();
}
if (vcm) {
*vcm = (float)efuse_get_sadc_tpid_vcm_code();
}
} else {
/* do nothing */
}
/* efuse saves the sampling values that retain 2 decimal place */
*vref /= EFUSE_SADC_SAMPLING_CODE_MULTIPLE;
*vcm /= EFUSE_SADC_SAMPLING_CODE_MULTIPLE;
for (uint8_t i = 0; i < 5; i++) {
dc_offset[i] /= EFUSE_SADC_SAMPLING_CODE_MULTIPLE;
}
}
uint32_t efuse_get_rf_tx_iqm_dc_calib_info(uint8_t *i_mag, uint8_t *q_mag,
uint8_t *i_phase, uint8_t *q_phase, int8_t *i_dc, int8_t *q_dc)
{
efuse_section_ana_t ana = {0};
uint32_t index = CFG_EFUSE_MAPPING_SYS_ANA_SECTION_W10_ADDR +
(EFUSE_FUNC_ANA_DATA0_OFFSET >> 3);
efuse_read_bytes(index, sizeof(ana), (uint8_t *)&ana);
if (ana.valid_mark & EFULSE_SEC_ANA_VALID_MARK_RF_TX_IQM_DC_CALIB) {
*i_mag = ana.tx_iqm_dc.i_mag;
*q_mag = ana.tx_iqm_dc.q_mag;
*i_phase = ana.tx_iqm_dc.i_phase;
*q_phase = ana.tx_iqm_dc.q_phase;
*i_dc = ana.tx_iqm_dc.i_dc;
*q_dc = ana.tx_iqm_dc.i_dc;
return ERR_OK;
}
return ERR_NOT_EXIST;
}
/*******BOND FUNCTION BEGIN********/
uint32_t efuse_set_bond_data(uint32_t bond_data)
{
uint32_t byte_index;
uint32_t bond_data_tmp;
bond_data_tmp = (efuse_read(CFG_EFUSE_MAPPING_BOND_SECTION_W6_ADDR) &
efuse_read(CFG_EFUSE_MAPPING_BOND_SECTION_W7_ADDR)) |
bond_data;
byte_index = CFG_EFUSE_MAPPING_BOND_SECTION_W6_ADDR;
efuse_write(byte_index, bond_data_tmp);
byte_index = CFG_EFUSE_MAPPING_BOND_SECTION_W7_ADDR;
efuse_write(byte_index, bond_data_tmp);
return 0;
}
uint32_t efuse_get_bond_data(bond_type type)
{
uint32_t ret_data;
uint32_t bond_data, bond_data_backup;
switch (type) {
case BOND_CONFIG:
bond_data = efuse_read(CFG_EFUSE_MAPPING_BOND_SECTION_W6_ADDR);
ret_data = bond_data;
break;
case BOND_BACKUP:
bond_data_backup = efuse_read(CFG_EFUSE_MAPPING_BOND_SECTION_W7_ADDR);
ret_data = bond_data_backup;
break;
case BOND_DATA:
default:
bond_data = efuse_read(CFG_EFUSE_MAPPING_BOND_SECTION_W6_ADDR);
bond_data_backup = efuse_read(CFG_EFUSE_MAPPING_BOND_SECTION_W7_ADDR);
ret_data = bond_data & bond_data_backup;
break;
}
return ret_data;
}
/*******BOND FUNCTION END********/
/* efuse data read and write function, kl public */
uint8_t efuse_check_data()
{
/* 0x00: check succeed; other: the corresponding item fails to be verified.
* bit 0: chip id check result;
* bit 1: mac address check result;
* bit 2: ate calibration check result;
* bit 3: sadc meter check result.
* bit 4: sadc tpid check result.
*/
uint8_t ret_st = 0x00;
#if HW_PLATFORM > HW_PLATFORM_FPGA
uint32_t ate_info, chipid, ate_ver;
uint8_t mac_info[IOT_MAC_ADDR_LEN] = {0};
uint8_t i = 0;
/* check chip id */
chipid = efuse_get_chip_id();
if (chipid == 0) {
ret_st |= 1 << 0;
}
/* check mac */
efuse_get_mac_addr(mac_info);
for (i = 0; i < IOT_MAC_ADDR_LEN; i++) {
if (mac_info[i] != 0) {
break;
}
}
if (i >= IOT_MAC_ADDR_LEN) {
ret_st |= 1 << 1;
}
ate_ver = efuse_get_analog_bin_ver();
/* check ate */
ate_info = ate_ver;
ate_info |= efuse_get_ft_pass_flag();
ate_info |= efuse_get_dcdc_trim();
ate_info |= efuse_get_flash_ldo_out_trim();
ate_info |= efuse_get_d_mdll_ldo_vref_trim();
ate_info |= efuse_get_d_bg_vbg_cntl();
ate_info |= efuse_get_d_bg_iccal();
ate_info |= efuse_get_rx_adc_vcm_ctrl();
ate_info |= efuse_get_flash_ldo_out_trim_2v5();
if (ate_info == 0) {
ret_st |= 1 << 2;
}
/* check sadc meter */
ate_info = efuse_get_sadc_meter_dc_offset_code();
ate_info |= efuse_get_sadc_meter_vref_code();
ate_info |= efuse_get_sadc_meter_vcm_code();
if (ate_ver >= EFUSE_ATE_BIN_VERSION_V2) {
ate_info |= efuse_get_sadc_meter_dc_offset_code_n12db();
ate_info |= efuse_get_sadc_meter_dc_offset_code_n6db();
ate_info |= efuse_get_sadc_meter_dc_offset_code_12db();
ate_info |= efuse_get_sadc_meter_dc_offset_code_24db();
}
if (ate_info == 0) {
ret_st |= 1 << 3;
}
/* check sadc tpid */
if (ate_ver >= EFUSE_ATE_BIN_VERSION_V2) {
ate_info = efuse_get_sadc_tpid_dc_offset_code();
ate_info |= efuse_get_sadc_tpid_vref_code();
ate_info |= efuse_get_sadc_tpid_vcm_code();
ate_info |= efuse_get_sadc_tpid_dc_offset_code_n12db();
ate_info |= efuse_get_sadc_tpid_dc_offset_code_n6db();
ate_info |= efuse_get_sadc_tpid_dc_offset_code_12db();
ate_info |= efuse_get_sadc_tpid_dc_offset_code_24db();
if (ate_info == 0) {
ret_st |= (1 << 4);
}
}
#endif
return ret_st;
}
bool_t efuse_prog_done_check()
{
if (efuse_get_idle_statue()) {
return true;
}
return false;
}
void efuse_write_prog_done()
{
efuse_wait_ilde_vaild();
}
uint32_t efuse_protect()
{
/* not support */
return 0;
}
uint32_t efuse_protect_off()
{
/* not support */
return 0;
}
uint32_t efuse_get_wafer_version()
{
/* not support */
return 0;
}
uint32_t efuse_get_reserve_version()
{
/* not support */
return 0;
}
uint32_t efuse_get_package_version()
{
/* not support */
return 0;
}
uint8_t efuse_get_pmu_ldo_trim()
{
/* not support */
return 0;
}