828eco基于GD32H7mcu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

630 lines
22 KiB

/*!
\file gd32h75e_efuse.c
\brief EFUSE driver
\version 2025-08-07, V1.2.0, firmware for GD32H75E
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#include "gd32h75e_efuse.h"
/* FMC register bit offset */
#define EFUSE_CTL_AES_KEY_CRC_OFFSET ((uint32_t)0x00000018U) /*!< bit offset of AES_KEY_CRC in EFUSE_CTL register*/
#define EFUSE_CTL_MPVEN_OFFSET ((uint32_t)0x0000000FU) /*!< bit offset of MPVEN in EFUSE_CTL register*/
#define EFUSE_STAT_LDO_RDY_OFFSET ((uint32_t)0x00000004U) /*!< bit offset of LDO_RDY in EFUSE_STAT register*/
#define EFUSE_ADDR_EFSIZE_OFFSET ((uint32_t)0x0000000AU) /*!< EFSIZE OFFSET in register EFUSE_ADDR */
#define EFUSE_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< EFUSE operation timeout value */
#define USER_CTL_NDBG0 BIT(8) /*!< debug mode setting bit0 in register EFUSE_USER_CTL */
static uint32_t para_start_efaddr[EFUSE_PARA_CNT] = {USER_CTL_EFADDR, MCU_RESERVED_EFADDR, DP_EFADDR, AES_KEY_EFADDR, USER_DATA_EFADDR};
static uint32_t para_reg_start_addr[EFUSE_PARA_CNT] = {EFUSE_USER_CTL_REG_ADDR, EFUSE_MCU_RSV_REG_ADDR, EFUSE_DP_REG_ADDR, EFUSE_AES_KEY_REG_ADDR, EFUSE_USER_DATA_REG_ADDR};
static efuse_state_enum efuse_ready_wait(uint32_t efuse_flag, uint32_t timeout);
/*!
\brief read system parameters from EFUSE macro to registers (API_ID(0x0001U))
\param[in] ef_addr: start address of the system parameters to be read
only one parameter can be selected which is shown as below:
\arg USER_CTL_EFADDR: user control parameter start address
\arg MCU_RESERVED_EFADDR: MCU reserved parameter start address
\arg DP_EFADDR: debug password parameter start address
\arg USER_DATA_EFADDR: user data parameter start address
\param[in] size: size of the system parameters to be read
only one parameter can be selected which is shown as below:
\arg USER_CTL_MCU_RESERVED_SIZE: user control parameter size,MCU reserved parameter size
\arg DP_SIZE: debug password parameter size
\arg USER_DATA_SIZE: user data parameter size
\param[out] buf: the buffer for data read from EFUSE macro
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_read(uint32_t ef_addr, uint32_t size, uint32_t buf[])
{
ErrStatus status = SUCCESS;
uint32_t timeout = EFUSE_TIMEOUT;
efuse_state_enum efuse_state;
uint32_t reg_addr = 0U;
uint32_t i = 0U;
uint32_t number = 0U;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_ADDR(ef_addr)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0001U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_SIZE(size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0001U), ERR_PARAM_INVALID);
} else
#endif /* FW_DEBUG_ERR_REPORT */
{
switch(ef_addr) {
case USER_CTL_EFADDR:
status = ERROR;
break;
case MCU_RESERVED_EFADDR:
/* read MCU reserved data */
reg_addr = EFUSE_MCU_RSV_REG_ADDR;
number = 1U;
break;
case DP_EFADDR:
/* read debug password */
if(RESET != (EFUSE_USER_CTL & EFUSE_USER_CTL_DPLK)) {
if(RESET != (EFUSE_USER_CTL & EFUSE_USER_CTL_JTAGNSW)) {
if((RESET != (EFUSE_USER_CTL & USER_CTL_NDBG0))) {
status = ERROR;
}
}
}
if(SUCCESS == status) {
reg_addr = EFUSE_DP_REG_ADDR;
number = 2U;
}
break;
case USER_DATA_EFADDR:
/* read user data */
reg_addr = EFUSE_USER_DATA_REG_ADDR;
number = 4U;
break;
default:
status = ERROR;
break;
}
if(ERROR == status) {
return status;
}
/* clear the RDIF bit if it is SET */
efuse_flag_clear(EFUSE_FLAG_READ_COMPLETE_CLR);
/* reset the EFRW bit in EFUSE_CTL */
EFUSE_CTL &= ~EFUSE_CTL_EFRW;
/* write the desired efuse address and size to the EFUSE_ADDR register */
EFUSE_ADDR = (uint32_t)((size << EFUSE_ADDR_EFSIZE_OFFSET) | ef_addr);
/* start array read EFUSE operation */
EFUSE_CTL |= EFUSE_CTL_EFSTR;
/* wait for the operation to complete */
efuse_state = efuse_ready_wait(EFUSE_FLAG_READ_COMPLETE, timeout);
if(EFUSE_READY != efuse_state) {
status = ERROR;
}
/* read EFUSE register */
for(i = 0U; i < number; i++) {
buf[i] = REG32(reg_addr + (4U * i));
}
}
return status;
}
/*!
\brief program register values to EFUSE macro system parameters (API_ID(0x0002U))
\param[in] ef_addr: the EFUSE address to be programmed, pgm_addr cannot exceed 384, and must be an integral multiple of 8
\param[in] size: byte count to program, (1~16)
\param[in] buf: the buffer for data written to EFUSE macro
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_write(uint32_t ef_addr, uint32_t size, uint8_t *buf)
{
uint32_t i;
uint32_t reg_addr;
uint32_t byte_offset_in_reg;
uint32_t cnt;
ErrStatus status = SUCCESS;
uint32_t para_index;
uint32_t tmp_buf_8;
uint32_t buf_addr;
uint32_t timeout = EFUSE_TIMEOUT;
efuse_state_enum efuse_state;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_VALID_SIZE(size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR(ef_addr)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR_CONFIG5(ef_addr, size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR_CONFIG4(ef_addr, size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR_CONFIG3(ef_addr, size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR_CONFIG2(ef_addr, size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR_CONFIG1(ef_addr, size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_EFUSE_VALID_ADDR_CONFIG0(ef_addr, size)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_INVALID);
} else if(NOT_VALID_POINTER(buf)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0002U), ERR_PARAM_POINTER);
} else
#endif
{
for(i = EFUSE_PARA_CNT; i > 0U; i--) {
if(ef_addr >= para_start_efaddr[i - 1U]) {
break;
}
}
/* get the index of parameter to be programmed */
para_index = i - 1U;
reg_addr = (unsigned int)para_reg_start_addr[para_index] + (ef_addr - para_start_efaddr[para_index]) / 32U * 4U;
byte_offset_in_reg = ((ef_addr - para_start_efaddr[para_index]) / 8U) % 4U;
/* clear the PGIF bit if it is SET */
efuse_flag_clear(EFUSE_FLAG_PROGRAM_COMPLETE_CLR);
/* set the EFRW bit in EFUSE_CTL */
EFUSE_CTL |= EFUSE_CTL_EFRW;
/* write the desired efuse address and size to the EFUSE_ADDR register */
EFUSE_ADDR = (uint32_t)((size << EFUSE_ADDR_EFSIZE_OFFSET) | ef_addr);
buf_addr = (uint32_t)buf;
while(size) {
if((0U != byte_offset_in_reg) || ((0U == byte_offset_in_reg) && (size < 4U))) {
cnt = size < (4U - byte_offset_in_reg) ? size : 4U - byte_offset_in_reg;
for(i = 0U; i < cnt; i++) {
tmp_buf_8 = buf_addr;
/* write the data to the corresponding register */
tmp_buf_8 += i;
REG32(reg_addr) |= (((uint32_t)(*(uint8_t *)(tmp_buf_8))) << ((byte_offset_in_reg + i) * 8U));
}
size -= cnt;
reg_addr += 4U;
byte_offset_in_reg = 0U;
buf_addr += cnt;
} else {
cnt = size / 4U;
for(i = 0U; i < cnt; i++) {
tmp_buf_8 = buf_addr;
/* write the data to the corresponding register */
tmp_buf_8 += (i * 4U);
REG32(reg_addr) = (uint32_t)(*(uint32_t *)(tmp_buf_8));
reg_addr += 4U;
}
size -= cnt * 4U;
buf_addr += cnt * 4U;
}
}
/* start EFUSE program operation */
EFUSE_CTL |= EFUSE_CTL_EFSTR;
/* wait for the operation to complete */
efuse_state = efuse_ready_wait(EFUSE_FLAG_PROGRAM_COMPLETE, timeout);
if(EFUSE_READY != efuse_state) {
status = ERROR;
}
}
return status;
}
/*!
\brief program all user control parameters (API_ID(0x0003U))
\param[in] buf: the buffer of data written to efuse
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_user_control_write(uint8_t *buf)
{
ErrStatus status = SUCCESS;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_VALID_POINTER(buf)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0003U), ERR_PARAM_POINTER);
} else
#endif
{
status = efuse_write(USER_CTL_EFADDR, USER_CTL_MCU_RESERVED_SIZE, buf);
}
return status;
}
/*!
\brief program all MCU reserved parameters (API_ID(0x0004U))
\param[in] buf: the buffer of data written to efuse
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_mcu_reserved_write(uint8_t *buf)
{
ErrStatus status = SUCCESS;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_VALID_POINTER(buf)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0004U), ERR_PARAM_POINTER);
} else
#endif
{
status = efuse_write(MCU_RESERVED_EFADDR, USER_CTL_MCU_RESERVED_SIZE, buf);
}
return status;
}
/*!
\brief program all debug password parameters (API_ID(0x0005U))
\param[in] buf: the buffer of data written to efuse
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_dp_write(uint8_t *buf)
{
ErrStatus status = SUCCESS;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_VALID_POINTER(buf)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0005U), ERR_PARAM_POINTER);
} else
#endif
{
status = efuse_write(DP_EFADDR, DP_SIZE, buf);
}
return status;
}
/*!
\brief program all AES key parameters (API_ID(0x0006U))
\param[in] buf: the buffer of data written to efuse
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_aes_key_write(uint8_t *buf)
{
ErrStatus status = SUCCESS;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_VALID_POINTER(buf)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0006U), ERR_PARAM_POINTER);
} else
#endif
{
status = efuse_write(AES_KEY_EFADDR, AES_KEY_SIZE, buf);
}
return status;
}
/*!
\brief program all user data parameters (API_ID(0x0007U))
\param[in] buf: the buffer of data written to efuse
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus efuse_user_data_write(uint8_t *buf)
{
ErrStatus status = SUCCESS;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_VALID_POINTER(buf)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0007U), ERR_PARAM_POINTER);
} else
#endif
{
status = efuse_write(USER_DATA_EFADDR, USER_DATA_SIZE, buf);
}
return status;
}
/*!
\brief get 8-bits CRC calculation result value of AES key (API_ID(0x0008U))
\param[in] none
\param[out] none
\retval 8-bits CRC calculation result value of AES key
*/
uint8_t efuse_aes_key_crc_get(void)
{
return (uint8_t)((EFUSE_CTL & EFUSE_CTL_AES_KEY_CRC) >> EFUSE_CTL_AES_KEY_CRC_OFFSET);
}
/*!
\brief enable monitor program voltage function (API_ID(0x0009U))
\param[in] none
\param[out] none
\retval none
*/
void efuse_monitor_program_voltage_enable(void)
{
uint32_t ctl_reg;
ctl_reg = EFUSE_CTL;
/* enable monitor program voltage function */
ctl_reg |= EFUSE_CTL_MPVEN;
EFUSE_CTL = ctl_reg;
}
/*!
\brief disable monitor program voltage function (API_ID(0x000AU))
\param[in] none
\param[out] none
\retval none
*/
void efuse_monitor_program_voltage_disable(void)
{
uint32_t ctl_reg;
ctl_reg = EFUSE_CTL;
/* disable monitor program voltage function */
ctl_reg &= ~EFUSE_CTL_MPVEN;
EFUSE_CTL = ctl_reg;
}
/*!
\brief get monitor program voltage function (API_ID(0x000BU))
\param[in] none
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus efuse_monitor_program_voltage_get(void)
{
FlagStatus mpven_state = RESET;
if(EFUSE_CTL_MPVEN == (uint32_t)(EFUSE_CTL & EFUSE_CTL_MPVEN)) {
mpven_state = SET;
} else {
mpven_state = RESET;
}
return mpven_state;
}
/*!
\brief get ldo ready signal (API_ID(0x000CU))
\param[in] none
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus efuse_ldo_ready_get(void)
{
FlagStatus ldo_ready_state = RESET;
if(EFUSE_STAT_LDO_RDY == (uint32_t)(EFUSE_STAT & EFUSE_STAT_LDO_RDY)) {
ldo_ready_state = SET;
} else {
ldo_ready_state = RESET;
}
return ldo_ready_state;
}
/*!
\brief check EFUSE flag is set or not (API_ID(0x000DU))
\param[in] flag: specifies to get a flag
only one parameter can be selected which is shown as below:
\arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR: illegal access error flag
\arg EFUSE_FLAG_PROGRAM_COMPLETE: programming operation completion flag
\arg EFUSE_FLAG_READ_COMPLETE: read operation completion flag
\arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error flag
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus efuse_flag_get(uint32_t flag)
{
FlagStatus flag_temp = RESET;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_FLAG(flag)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x000DU), ERR_PARAM_INVALID);
} else
#endif
{
if(EFUSE_STAT & (uint32_t)flag) {
flag_temp = SET;
} else {
flag_temp = RESET;
}
}
return flag_temp;
}
/*!
\brief clear EFUSE pending flag (API_ID(0x000EU))
\param[in] flag: specifies to clear a flag
only one parameter can be selected which is shown as below:
\arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR_CLR: clear illegal access error flag
\arg EFUSE_FLAG_PROGRAM_COMPLETE_CLR: clear programming operation completion flag
\arg EFUSE_FLAG_READ_COMPLETE_CLR: clear read operation completion flag
\arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR_CLR: clear program voltage setting error interrupt flag
\param[out] none
\retval none
*/
void efuse_flag_clear(uint32_t flag)
{
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_FLAG_CLR(flag)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x000EU), ERR_PARAM_INVALID);
} else
#endif
{
EFUSE_STATC |= (uint32_t)flag;
}
}
/*!
\brief enable EFUSE interrupt (API_ID(0x000FU))
\param[in] interrupt: specifies an interrupt to enbale
only one parameter can be selected which is shown as below:
\arg EFUSE_INT_ILLEGAL_ACCESS_ERR: illegal access error interrupt
\arg EFUSE_INT_PROGRAM_COMPLETE: programming operation completion interrupt
\arg EFUSE_INT_READ_COMPLETE: read operation completion interrupt
\arg EFUSE_INT_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt
\param[out] none
\retval none
*/
void efuse_interrupt_enable(uint32_t interrupt)
{
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_INT(interrupt)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x000FU), ERR_PARAM_INVALID);
} else
#endif
{
EFUSE_CTL = (uint32_t)interrupt;
}
}
/*!
\brief disable EFUSE interrupt (API_ID(0x0010U))
\param[in] interrupt: specifies an interrupt to disbale
only one parameter can be selected which is shown as below:
\arg EFUSE_INT_ILLEGAL_ACCESS_ERR: illegal access error interrupt
\arg EFUSE_INT_PROGRAM_COMPLETE: programming operation completion interrupt
\arg EFUSE_INT_READ_COMPLETE: read operation completion interrupt
\arg EFUSE_INT_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt
\param[out] none
\retval none
*/
void efuse_interrupt_disable(uint32_t interrupt)
{
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_INT(interrupt)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0010U), ERR_PARAM_INVALID);
} else
#endif
{
EFUSE_CTL &= ~(uint32_t)interrupt;
}
}
/*!
\brief check EFUSE interrupt flag is set or not (API_ID(0x0011U))
\param[in] int_flag: specifies to get a flag
only one parameter can be selected which is shown as below:
\arg EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR: illegal access error interrupt
\arg EFUSE_INT_FLAG_PROGRAM_COMPLETE: programming operation completion interrupt
\arg EFUSE_INT_FLAG_READ_COMPLETE: read operation completion interrupt
\arg EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus efuse_interrupt_flag_get(efuse_interrupt_flag_enum int_flag)
{
uint32_t intenable = 0U, flagstatus = 0U;
/* get the interrupt enable bit status */
intenable = (EFUSE_REG_VAL(int_flag) & BIT(EFUSE_BIT_POS(int_flag)));
/* get the corresponding flag bit status */
flagstatus = (EFUSE_REG_VAL2(int_flag) & BIT(EFUSE_BIT_POS2(int_flag)));
if(flagstatus && intenable) {
return SET;
} else {
return RESET;
}
}
/*!
\brief clear EFUSE pending interrupt flag (API_ID(0x0012U))
\param[in] int_flag: specifies to clear a flag
only one parameter can be selected which is shown as below:
\arg EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR_CLR: clear illegal access error interrupt flag
\arg EFUSE_INT_FLAG_PROGRAM_COMPLETE_CLR: clear programming operation completion interrupt flag
\arg EFUSE_INT_FLAG_READ_COMPLETE_CLR: clear operation completion interrupt flag
\arg EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR_CLR: clear program voltage setting error interrupt flag
\param[out] none
\retval none
*/
void efuse_interrupt_flag_clear(uint32_t int_flag)
{
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_INT_FLAG_CLR(int_flag)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0012U), ERR_PARAM_INVALID);
} else
#endif /* FW_DEBUG_ERR_REPORT */
{
EFUSE_STATC |= (uint32_t)int_flag;
}
}
/*!
\brief check whether EFUSE is ready or not (API_ID(0x0013U))
\param[in] flag:
only one parameter can be selected which is shown as below:
\arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR: illegal access error flag
\arg EFUSE_FLAG_PROGRAM_COMPLETE: programming operation completion flag
\arg EFUSE_FLAG_READ_COMPLETE: read operation completion flag
\arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error flag
\param[out] none
\retval state of EFUSE
\arg EFUSE_READY: EFUSE operation has been completed
\arg EFUSE_BUSY: EFUSE operation is in progress
\arg EFUSE_IAERR: illegal access error
\arg EFUSE_PVERR: program voltage setting error
\arg EFUSE_TOERR: EFUSE timeout error
*/
static efuse_state_enum efuse_ready_wait(uint32_t efuse_flag, uint32_t timeout)
{
efuse_state_enum efuse_state = EFUSE_BUSY;
#ifdef FW_DEBUG_ERR_REPORT
/* check parameter */
if(NOT_EFUSE_FLAG(efuse_flag)) {
fw_debug_report_err(EFUSE_MODULE_ID, API_ID(0x0013U), ERR_PARAM_INVALID);
} else
#endif /* FW_DEBUG_ERR_REPORT */
{
/* wait for EFUSE ready */
do {
/* get EFUSE flag set or not */
if(EFUSE_STAT & (uint32_t)efuse_flag) {
efuse_state = EFUSE_READY;
} else if(EFUSE_STAT & EFUSE_STAT_IAERRIF) {
efuse_state = EFUSE_IAERR;
} else if(EFUSE_STAT & EFUSE_STAT_PVIF) {
efuse_state = EFUSE_PVERR;
} else {
/* illegal parameters */
}
timeout--;
} while((EFUSE_BUSY == efuse_state) && (0U != timeout));
if(EFUSE_BUSY == efuse_state) {
efuse_state = EFUSE_TOERR;
}
}
/* return the EFUSE state */
return efuse_state;
}