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