713 lines
22 KiB
C
713 lines
22 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.
|
|
|
|
****************************************************************************/
|
|
#include "chip_reg_base.h"
|
|
#include "hw_reg_api.h"
|
|
#include "ana_dig_wrap_rf.h"
|
|
#include "efuse_mapping.h"
|
|
|
|
#include "efuse.h"
|
|
|
|
#include "dbg_io.h"
|
|
|
|
#include "iot_errno_api.h"
|
|
|
|
#include "dtest_printf.h"
|
|
#include "iot_system.h"
|
|
#include "uart.h"
|
|
#include "gp_timer.h"
|
|
#include "iot_system.h"
|
|
|
|
/* the new function is not suitable for writing to the header file
|
|
* until the compatibility problem is determined
|
|
*/
|
|
void efuse_init(void);
|
|
void efuse_deinit(void);
|
|
uint8_t efuse_get_idle_statue(void);
|
|
void efuse_wait_ilde_vaild(void);
|
|
void efuse_set_bit_addr(uint8_t efuse_byte_num, uint8_t bit_index);
|
|
void efuse_set_read_len(uint16_t len);
|
|
void efuse_enable_cmd_set_mode(uint8_t mode);
|
|
uint16_t efuse_read_bit_ecnt(void);
|
|
uint32_t efuse_read_reg(void);
|
|
uint32_t efuse_read_phy(void);
|
|
void efuse_phy_bit_prog(uint8_t efuse_byte_num, uint8_t bit_index);
|
|
uint8_t efuse_phy_byte_read(uint8_t efuse_byte_num);
|
|
void efuse_reg_byte_prog(uint8_t efuse_byte_num, uint8_t data);
|
|
uint8_t efuse_reg_byte_read(uint8_t efuse_byte_num);
|
|
void efuse_phy_load_to_reg();
|
|
|
|
/* KL3 eFuse controller has 1K bit register inside, which is used to
|
|
* back up eFuse data and reduce the times of reading and writing eFuse.
|
|
* the hardware automatically read eFuse data into the register after power on
|
|
*/
|
|
#define DTEST_EFUSE_SOFT_BACKUP_ENABLE 0
|
|
|
|
#define DTEST_EFUSE_FPGA_BOARD_ENABLE 0
|
|
|
|
/* In the screening process, need to write the mac address and chip id in advance */
|
|
#define DTEST_EFUSE_BURN_CHIPID_MAC_ADDR 0
|
|
|
|
#define DTEST_EFUSE_SPACE_SIZE 128 //byte
|
|
|
|
#define DTEST_EFUSE_CASE_DUMP_DATA (1 << 0)
|
|
#define DTEST_EFUSE_CASE_WRITE (1 << 1)
|
|
|
|
#if DTEST_EFUSE_FPGA_BOARD_ENABLE
|
|
#if DTEST_EFUSE_SOFT_BACKUP_ENABLE
|
|
|
|
typedef struct _dtest_efuse_layout_t {
|
|
uint8_t data[DTEST_EFUSE_SPACE_SIZE];
|
|
} dtest_efuse_layout_t;
|
|
|
|
dtest_efuse_layout_t dtest_efuse_layout;
|
|
|
|
static uint32_t dtest_efuse_load_to_ram(void)
|
|
{
|
|
uint8_t i;
|
|
uint8_t *ptr = (uint8_t *)&dtest_efuse_layout;
|
|
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
ptr[i] = efuse_phy_byte_read(i);
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_data_dump(void)
|
|
{
|
|
uint8_t i;
|
|
uint8_t *ptr = (uint8_t *)&dtest_efuse_layout;
|
|
|
|
dprintf("efuse dump:\n\t");
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
if ((i != 0) && (i % 16 == 0)) {
|
|
iot_printf("\n\t");
|
|
}
|
|
iot_printf("0x%02x ", ptr[i]);
|
|
}
|
|
iot_printf("\n");
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_read_byte(uint8_t offset, uint8_t *data)
|
|
{
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal address:%d\n", offset);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
*data = dtest_efuse_layout.data[offset];
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_write_bit(uint8_t offset, uint8_t bit_idx)
|
|
{
|
|
uint8_t data_temp;
|
|
uint8_t retry_cnt = 3;
|
|
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal address:%d\n", offset);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal bit index:%d\n", bit_idx);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if ((dtest_efuse_layout.data[offset] >> bit_idx) & 0x1) {
|
|
dprintf("byte(%d) bit(%d) has been set\n", offset, bit_idx);
|
|
return ERR_OK;
|
|
}
|
|
|
|
do {
|
|
efuse_phy_bit_prog(offset, bit_idx);
|
|
data_temp = efuse_phy_byte_read(offset);
|
|
if ((data_temp >>bit_idx) &0x1) {
|
|
break;
|
|
}
|
|
} while (--retry_cnt);
|
|
|
|
if (retry_cnt == 0) {
|
|
dprintf("efuse bit program failed, offset:%d, bit index:%d\n", offset, bit_idx);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
dprintf("efuse bit program succeed, offset:%d, bit index:%d\n", offset, bit_idx);
|
|
/* update ram data */
|
|
dtest_efuse_layout.data[offset] |= (1 << bit_idx);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_write_byte(uint32_t offset, uint8_t data)
|
|
{
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal address:%d\n", offset);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
if (!((data >> i) & 0x1) && ((dtest_efuse_layout.data[offset] >> i) & 0x1)) {
|
|
dprintf("efuse can't be changed from 1 to 0, efuse data:0x%02x, "
|
|
"write data:0x%02x\n", dtest_efuse_layout.data[offset], data);
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
|
|
dprintf("efuse byte program, offset:%d, data:0x%02x\n", offset, data);
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
if ((data >> i) & 0x1) {
|
|
if (dtest_efuse_write_bit(offset, i) != ERR_OK) {
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
#else
|
|
|
|
static const uint8_t dtest_efuse_data_default[DTEST_EFUSE_SPACE_SIZE] = {
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
|
|
};
|
|
|
|
void dtest_efuse_phy_load_to_reg()
|
|
{
|
|
/* 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(0, 0);
|
|
|
|
efuse_set_read_len(DTEST_EFUSE_SPACE_SIZE);
|
|
|
|
efuse_enable_cmd_set_mode(2);
|
|
|
|
efuse_wait_ilde_vaild();
|
|
}
|
|
|
|
static uint32_t dtest_efuse_load_to_ram(void)
|
|
{
|
|
// dtest_efuse_phy_load_to_reg();
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_data_dump(void)
|
|
{
|
|
uint8_t i, data, err_cnt = 0;
|
|
|
|
dprintf("efuse dump:\n\t");
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
data = efuse_reg_byte_read(i);
|
|
if ((i != 0) && (i % 16 == 0)) {
|
|
iot_printf("\n\t");
|
|
}
|
|
iot_printf("0x%02x ", data);
|
|
if (data != dtest_efuse_data_default[i]) {
|
|
err_cnt++;
|
|
}
|
|
}
|
|
iot_printf("\n");
|
|
|
|
dprintf("efuse data error cnt:%d\n", err_cnt);
|
|
|
|
if (err_cnt) {
|
|
return ERR_FAIL;
|
|
} else {
|
|
return ERR_OK;
|
|
}
|
|
}
|
|
|
|
static uint32_t dtest_efuse_read_byte(uint8_t offset, uint8_t *data)
|
|
{
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal address:%d\n", offset);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
*data = efuse_reg_byte_read(offset);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_write_bit(uint8_t offset, uint8_t bit_idx)
|
|
{
|
|
uint8_t data_temp, data_reg;
|
|
uint8_t retry_cnt = 3;
|
|
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal address:%d\n", offset);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal bit index:%d\n", bit_idx);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
data_reg = efuse_reg_byte_read(offset);
|
|
if ((data_reg >> bit_idx) & 0x1) {
|
|
dprintf("byte(%d) bit(%d) has been set\n", offset, bit_idx);
|
|
return ERR_OK;
|
|
}
|
|
|
|
do {
|
|
efuse_phy_bit_prog(offset, bit_idx);
|
|
data_temp = efuse_phy_byte_read(offset);
|
|
if ((data_temp >>bit_idx) &0x1) {
|
|
break;
|
|
}
|
|
} while (--retry_cnt);
|
|
|
|
if (retry_cnt == 0) {
|
|
dprintf("efuse bit program failed, offset:%d, bit index:%d\n", offset, bit_idx);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
dprintf("efuse bit program succeed, offset:%d, bit index:%d\n", offset, bit_idx);
|
|
/* update register data */
|
|
data_reg |= (1 << bit_idx);
|
|
retry_cnt = 3;
|
|
do {
|
|
efuse_reg_byte_prog(offset, data_reg);
|
|
data_temp = efuse_reg_byte_read(offset);
|
|
if (data_temp == data_reg) {
|
|
break;
|
|
}
|
|
} while (--retry_cnt);
|
|
|
|
if (retry_cnt == 0) {
|
|
dprintf("efuse reg program failed, offset:%d, data:0x%x\n", offset, data_reg);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_write_byte(uint32_t offset, uint8_t data)
|
|
{
|
|
uint8_t data_reg;
|
|
|
|
if (offset >= DTEST_EFUSE_SPACE_SIZE) {
|
|
dprintf("illegal address:%d\n", offset);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
data_reg = efuse_reg_byte_read(offset);
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
if (!((data >> i) & 0x1) && ((data_reg >> i) & 0x1)) {
|
|
dprintf("efuse can't be changed from 1 to 0, efuse data:0x%02x, "
|
|
"write data:0x%02x\n", data_reg, data);
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
|
|
dprintf("efuse byte program, offset:%d, data:0x%02x\n", offset, data);
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
if ((data >> i) & 0x1) {
|
|
if (dtest_efuse_write_bit(offset, i) != ERR_OK) {
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
static uint32_t dtest_efuse_data_dump_test()
|
|
{
|
|
dcase_start("efuse data dump\n");
|
|
|
|
dtest_efuse_load_to_ram();
|
|
if (dtest_efuse_data_dump() == ERR_OK) {
|
|
dcase_success();
|
|
return ERR_OK;
|
|
} else {
|
|
dcase_failed();
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
|
|
/* Since ram is used as eFuse in FPGA, it needs to be executed after each restart */
|
|
static uint32_t dtest_efuse_data_rw_test()
|
|
{
|
|
uint8_t i;
|
|
uint8_t data_backup, data_efuse, data_test = 0x11;
|
|
|
|
dcase_start("efuse data read/write test\n");
|
|
/* 0 -> 1 */
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
if (dtest_efuse_write_byte(i, data_test) != ERR_OK) {
|
|
dprintf("efuse program failed\n");
|
|
goto fail;
|
|
}
|
|
|
|
if (dtest_efuse_read_byte(i, &data_backup) != ERR_OK) {
|
|
dprintf("efuse read failed\n");
|
|
goto fail;
|
|
}
|
|
|
|
data_efuse = efuse_phy_byte_read(i);
|
|
dprintf("efuse rw test, write data:0x%02x, read data:0x%02x, efuse data:0x%02x\n",
|
|
data_test, data_backup, data_efuse);
|
|
if ((data_backup != data_test) || (data_efuse != data_test)) {
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
/* 1 - > 1 */
|
|
data_test = 0x11;
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
if (dtest_efuse_write_byte(i, data_test) != ERR_OK) {
|
|
dprintf("efuse program failed\n");
|
|
goto fail;
|
|
}
|
|
|
|
if (dtest_efuse_read_byte(i, &data_backup) != ERR_OK) {
|
|
dprintf("efuse read failed\n");
|
|
goto fail;
|
|
}
|
|
|
|
data_efuse = efuse_phy_byte_read(i);
|
|
dprintf("efuse rw test, write data:0x%02x, read data:0x%02x, efuse data:0x%02x\n",
|
|
data_test, data_backup, data_efuse);
|
|
if ((data_backup != data_test) || (data_efuse != data_test)) {
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
/* 1 -> 0 */
|
|
data_test = 0x00;
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
if (dtest_efuse_write_byte(i, data_test) == ERR_OK) {
|
|
dprintf("efuse program logic error\n");
|
|
goto fail;
|
|
}
|
|
|
|
if (dtest_efuse_read_byte(i, &data_backup) != ERR_OK) {
|
|
dprintf("efuse read failed\n");
|
|
goto fail;
|
|
}
|
|
|
|
data_efuse = efuse_phy_byte_read(i);
|
|
dprintf("efuse rw test, write data:0x%02x, read data:0x%02x, efuse data:0x%02x\n",
|
|
data_test, data_backup, data_efuse);
|
|
if ((data_backup == data_test) || (data_efuse == data_test)) {
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
dcase_success();
|
|
return ERR_OK;
|
|
fail:
|
|
dcase_failed();
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
#else
|
|
|
|
uint8_t g_dtest_efuse_data_buf[DTEST_EFUSE_SPACE_SIZE] = {0};
|
|
|
|
static uint32_t dtest_efuse_data_dump_test()
|
|
{
|
|
uint8_t i = 0;
|
|
efuse_section_t *efuse = (efuse_section_t *)g_dtest_efuse_data_buf;
|
|
|
|
for (i = 0; i < DTEST_EFUSE_SPACE_SIZE; i++) {
|
|
g_dtest_efuse_data_buf[i] = efuse_reg_byte_read(i);
|
|
}
|
|
|
|
dprintf("efuse data dump\n");
|
|
/* ate section */
|
|
dprintf("ate section data:\n");
|
|
dprintf("\tlot_id:%x-%x-%x-%x-%x-%x\n",
|
|
efuse->ate.lot_id[0], efuse->ate.lot_id[1], efuse->ate.lot_id[2],
|
|
efuse->ate.lot_id[3], efuse->ate.lot_id[4], efuse->ate.lot_id[5]);
|
|
dprintf("\twafer_id:%d\n", efuse->ate.wafer_id);
|
|
dprintf("\tx_coor:%d\n", efuse->ate.x_coor);
|
|
dprintf("\ty_coor:%d\n", efuse->ate.y_coor);
|
|
dprintf("\twafer_recv:%d\n", efuse->ate.wafer_rev);
|
|
dprintf("\tft_pass_flag:%d\n", efuse->ate.ft_pass_flag);
|
|
dprintf("\tanalog_bin_ver:%d\n", efuse->ate.analog_bin_ver);
|
|
dprintf("\tdcdc_1p1 code:%d\n", efuse->ate.dcdc_1p1);
|
|
dprintf("\tldo_1p8 code:%d\n", efuse->ate.ldo_1p8);
|
|
dprintf("\tmdll_ldo_1p1 code:%d\n", efuse->ate.mdll_ldo_1p1);
|
|
dprintf("\tvbg_cntl code:%d\n", efuse->ate.vbg_cntl);
|
|
dprintf("\tic_cal code:%d\n", efuse->ate.ic_cal);
|
|
dprintf("\trx_adc_vcm_ctrl code:%d\n", efuse->ate.rx_adc_vcm_ctrl);
|
|
dprintf("\tldo_2p5 code:%d\n", efuse->ate.ldo_2p5);
|
|
dprintf("\tmark:%d\n", efuse->ate.mark);
|
|
dprintf("\twafer_ver:%d\n", efuse->ate.wafer_ver);
|
|
dprintf("\tsip:%d\n", efuse->ate.sip);
|
|
dprintf("\tproject:%d\n", efuse->ate.project);
|
|
dprintf("\tmac:%x-%x-%x-%x-%x-%x\n",
|
|
efuse->ate.mac[0], efuse->ate.mac[1], efuse->ate.mac[2],
|
|
efuse->ate.mac[3], efuse->ate.mac[4], efuse->ate.mac[5]);
|
|
/* bond section */
|
|
dprintf("bond section data:");
|
|
for (i = 0; i < sizeof(efuse_section_bond_t); i++) {
|
|
iot_printf("%02x ", *(((uint8_t *)&(efuse->bond)) + i));
|
|
}
|
|
iot_printf("\n");
|
|
/* iomap section */
|
|
dprintf("iomap section data:0x%08x, 0x%08x\n",
|
|
efuse->iomap.iomap, efuse->iomap.iomap_bak);
|
|
/* system section */
|
|
dprintf("system section data:\n");
|
|
dprintf("\tsbl_crc_power_on:%d\n", efuse->system.sbl_crc_power_on);
|
|
dprintf("\tsbl_crc_wdg_rst:%d\n", efuse->system.sbl_crc_wdg_rst);
|
|
dprintf("\trom_err_msg_en:%d\n", efuse->system.rom_err_msg_en);
|
|
dprintf("\tsbl_crc_power_on_bak:%d\n", efuse->system.sbl_crc_power_on_bak);
|
|
dprintf("\tsbl_crc_wdg_rst_bak:%d\n", efuse->system.sbl_crc_wdg_rst_bak);
|
|
dprintf("\trom_err_msg_en_bak:%d\n", efuse->system.rom_err_msg_en_bak);
|
|
/* ana section */
|
|
dprintf("ana section data:");
|
|
for (i = 0; i < sizeof(efuse_section_ana_t); i++) {
|
|
iot_printf("%02x ", *(((uint8_t *)&(efuse->ana)) + i));
|
|
}
|
|
iot_printf("\n");
|
|
/* rom patch section */
|
|
dprintf("rom patch section data:\n");
|
|
dprintf("\tvalid_flag:%02x\n", efuse->rom_patch.valid_flag);
|
|
dprintf("\tvalid_flag_bak:%02x\n", efuse->rom_patch.valid_flag_bak);
|
|
dprintf("\tpatch_0_pos:%02x\n", efuse->rom_patch.patch_0_pos);
|
|
dprintf("\tpatch_1_pos:%02x\n", efuse->rom_patch.patch_1_pos);
|
|
dprintf("\tpatch_0_addr:0x%08x\n", efuse->rom_patch.patch_0_addr);
|
|
dprintf("\tpatch_0_data:0x%08x\n", efuse->rom_patch.patch_0_data);
|
|
dprintf("\tpatch_1_addr:0x%08x\n", efuse->rom_patch.patch_1_addr);
|
|
dprintf("\tpatch_1_data:0x%08x\n", efuse->rom_patch.patch_1_data);
|
|
dprintf("\tpatch_2_addr:0x%08x\n", efuse->rom_patch.patch_2_addr);
|
|
dprintf("\tpatch_2_data:0x%08x\n", efuse->rom_patch.patch_2_data);
|
|
dprintf("\tpatch_3_addr:0x%08x\n", efuse->rom_patch.patch_3_addr);
|
|
dprintf("\tpatch_3_data:0x%08x\n", efuse->rom_patch.patch_3_data);
|
|
/* sadc_2 section */
|
|
dprintf("sadc_2 section data:\n");
|
|
dprintf("\ttpid_dc_offset_n12db:%d\n", efuse->sadc_2.tpid_dc_offset_n12db);
|
|
dprintf("\ttpid_dc_offset_n6db:%d\n", efuse->sadc_2.tpid_dc_offset_n6db);
|
|
dprintf("\ttpid_dc_offset_12db:%d\n", efuse->sadc_2.tpid_dc_offset_12db);
|
|
dprintf("\ttpid_dc_offset_24db:%d\n", efuse->sadc_2.tpid_dc_offset_24db);
|
|
dprintf("\tmeter_dc_offset_n12db:%d\n", efuse->sadc_2.meter_dc_offset_n12db);
|
|
dprintf("\tmeter_dc_offset_n6db:%d\n", efuse->sadc_2.meter_dc_offset_n6db);
|
|
dprintf("\tmeter_dc_offset_12db:%d\n", efuse->sadc_2.meter_dc_offset_12db);
|
|
dprintf("\tmeter_dc_offset_24db:%d\n", efuse->sadc_2.meter_dc_offset_24db);
|
|
/* sub id section */
|
|
dprintf("subid section data:\n");
|
|
dprintf("\tsub_mark:%x\n", efuse->subid.sub_mark);
|
|
dprintf("\tsub_wafer_ver:%x\n", efuse->subid.sub_wafer_ver);
|
|
dprintf("\tsub_sip:%x\n", efuse->subid.sub_sip);
|
|
dprintf("\tsub_project:%x\n", efuse->subid.sub_project);
|
|
/* sadc section */
|
|
dprintf("sadc section data:\n");
|
|
dprintf("\ttpid_dc_offset_code:%d\n", efuse->sadc.tpid_dc_offset_code);
|
|
dprintf("\ttpid_vref_code:%d\n", efuse->sadc.tpid_vref_code);
|
|
dprintf("\ttpid_vcm_code:%d\n", efuse->sadc.tpid_vcm_code);
|
|
dprintf("\tmeter_dc_offset_code:%d\n", efuse->sadc.meter_dc_offset_code);
|
|
dprintf("\tmeter_vref_code:%d\n", efuse->sadc.meter_vref_code);
|
|
dprintf("\tmeter_vcm_code:%d\n", efuse->sadc.meter_vcm_code);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t dtest_efuse_data_rw_test()
|
|
{
|
|
/* [todo] */
|
|
return ERR_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
void dtest_efuse_main()
|
|
{
|
|
uint32_t case_group = 0, error_cnt = 0;
|
|
|
|
if (dtest_get_case_group(&case_group) < 0) {
|
|
case_group = 0xffffffff;
|
|
}
|
|
dprintf("get case group:0x%08X\n", case_group);
|
|
|
|
efuse_init();
|
|
|
|
if (case_group & DTEST_EFUSE_CASE_DUMP_DATA) {
|
|
if (dtest_efuse_data_dump_test() != ERR_OK) {
|
|
error_cnt++;
|
|
}
|
|
}
|
|
|
|
if (case_group & DTEST_EFUSE_CASE_WRITE) {
|
|
if (dtest_efuse_data_rw_test() != ERR_OK) {
|
|
error_cnt++;
|
|
}
|
|
}
|
|
|
|
if (error_cnt) {
|
|
dprintf("efuse test failed\n");
|
|
} else {
|
|
dprintf("efuse test succeed\n");
|
|
}
|
|
|
|
dend();
|
|
|
|
return;
|
|
}
|
|
|
|
/* eFuse uses the flash LDO power supply, but the flash works at 1.8V,
|
|
* and the eFuse burning voltage needs 2.5V, so it needs a short boost.
|
|
* the shorter the boost duration, the better.
|
|
* do not operate the flash chip during the boost period.
|
|
*/
|
|
void efuse_power_config(uint8_t en)
|
|
{
|
|
uint32_t temp;
|
|
|
|
if (en) {
|
|
temp = DTOP_ANA_INF_READ_REG(CFG_ANA_DIG_REG_CFG21_ADDR);
|
|
REG_FIELD_SET(FLASH_LDO_OUT_TRIM, temp, 0b1000); //2.5v
|
|
DTOP_ANA_INF_WRITE_REG(CFG_ANA_DIG_REG_CFG21_ADDR, temp);
|
|
|
|
temp = DTOP_ANA_INF_READ_REG(CFG_ANA_DIG_REG_CFG22_ADDR);
|
|
REG_FIELD_SET(FLASH_LDO_EN_VOUT_EFUSE, temp, 1);
|
|
DTOP_ANA_INF_WRITE_REG(CFG_ANA_DIG_REG_CFG22_ADDR, temp);
|
|
} else {
|
|
temp = DTOP_ANA_INF_READ_REG(CFG_ANA_DIG_REG_CFG22_ADDR);
|
|
REG_FIELD_SET(FLASH_LDO_EN_VOUT_EFUSE, temp, 0);
|
|
DTOP_ANA_INF_WRITE_REG(CFG_ANA_DIG_REG_CFG22_ADDR, temp);
|
|
|
|
temp = DTOP_ANA_INF_READ_REG(CFG_ANA_DIG_REG_CFG21_ADDR);
|
|
REG_FIELD_SET(FLASH_LDO_OUT_TRIM, temp, 0b0011); //1.8v
|
|
DTOP_ANA_INF_WRITE_REG(CFG_ANA_DIG_REG_CFG21_ADDR, temp);
|
|
}
|
|
}
|
|
|
|
int dtest_efuse_mac_chipid_burn()
|
|
{
|
|
uint32_t chipid_write = CHIP_ID_HZ5202_V1A;
|
|
uint32_t chipid_read = 0;
|
|
uint8_t mac_buf_write[8] = {0x0};
|
|
uint8_t mac_buf_read[6] = {0x0};
|
|
|
|
/* dump mac addr && chip id */
|
|
efuse_get_mac_addr(mac_buf_read);
|
|
chipid_read = efuse_get_chip_id();
|
|
dprintf("$$ read chipid:0x%04x, mac addr:%02x %02x %02x %02x %02x %02x\n",
|
|
chipid_read, mac_buf_read[0], mac_buf_read[1], mac_buf_read[2],
|
|
mac_buf_read[3], mac_buf_read[4], mac_buf_read[5]);
|
|
if ((0 != chipid_read) && (chipid_write != chipid_read)) {
|
|
dprintf("set chipid result:fail, old chipid: 0x%x chipid_write:0x%x\n",
|
|
chipid_read, chipid_write);
|
|
return 0;
|
|
}
|
|
|
|
efuse_power_config(1);
|
|
efuse_set_chip_id(chipid_write);
|
|
efuse_power_config(0);
|
|
chipid_read = efuse_get_chip_id();
|
|
|
|
if (chipid_read == chipid_write) {
|
|
dprintf("set chipid:0x%08x read chipid:0x%08x, set chipid result:success\n",
|
|
chipid_write, chipid_read);
|
|
} else {
|
|
dprintf("set chipid:0x%08x read chipid:0x%08x, set chipid result:fail\n",
|
|
chipid_write, chipid_read);
|
|
}
|
|
|
|
/* set mac addr by uart */
|
|
iot_printf("waiting for mac address\n");
|
|
|
|
uint32_t i;
|
|
gp_timer_start(0);
|
|
while (gp_timer_get_current_val(0) < 30 * 1000000) {
|
|
if (uart_e_ctrl.rx_fifo_cnt(0) >= 8) {
|
|
mac_buf_write[0] = uart_e_ctrl.getc(0);
|
|
if (0xaa == mac_buf_write[0]) {
|
|
for (uint32_t x = 0; x < 7; x++) {
|
|
mac_buf_write[x + 1] = uart_e_ctrl.try_getc(0);
|
|
}
|
|
if (0x55 == mac_buf_write[7]) {
|
|
efuse_power_config(1);
|
|
efuse_set_mac_addr(mac_buf_write + 1);
|
|
efuse_power_config(0);
|
|
efuse_get_mac_addr(mac_buf_read);
|
|
for (i = 0; i < 6; i++) {
|
|
if (mac_buf_write[i + 1] != mac_buf_read[i]) {
|
|
break;
|
|
}
|
|
}
|
|
dprintf("set mac:%02x %02x %02x %02x %02x %02x "
|
|
"read mac:%02x %02x %02x %02x %02x %02x, "
|
|
"set mac result:%s\n",
|
|
mac_buf_write[1], mac_buf_write[2], mac_buf_write[3],
|
|
mac_buf_write[4], mac_buf_write[5], mac_buf_write[6],
|
|
mac_buf_read[0], mac_buf_read[1], mac_buf_read[2],
|
|
mac_buf_read[3], mac_buf_read[4], mac_buf_read[5],
|
|
6 == i ? "success" : "fail");
|
|
return 0;
|
|
} else {
|
|
dprintf("set mac result:fail\n");
|
|
return 0;
|
|
}
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
dprintf("set mac result:fail\n");
|
|
return -1;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
gp_timer_init();
|
|
gp_timer_set(0, 0xffffffff, 0);
|
|
gp_timer_start(0);
|
|
while (gp_timer_get_current_val(0) < 1000000);
|
|
gp_timer_stop(0);
|
|
|
|
dbg_uart_init();
|
|
dconfig();
|
|
dstart();
|
|
dversion();
|
|
efuse_init();
|
|
|
|
|
|
#if DTEST_EFUSE_BURN_CHIPID_MAC_ADDR
|
|
dtest_efuse_mac_chipid_burn();
|
|
#else
|
|
|
|
#if 1
|
|
dtest_efuse_main();
|
|
#else
|
|
extern void efuse_data_burning(void);
|
|
efuse_data_burning();
|
|
#endif
|
|
|
|
#endif
|
|
return 0;
|
|
}
|
|
|