Files
kunlun/driver/src/hw3/efuse.c
2024-09-28 14:24:04 +08:00

922 lines
24 KiB
C
Raw 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.

/****************************************************************************
*
* 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;
}