初始提交
This commit is contained in:
921
driver/src/hw3/efuse.c
Normal file
921
driver/src/hw3/efuse.c
Normal 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user