#include "FreeRTOS.h" #include "task.h" #include "diag.h" #include "hal_efuse.h" #include "efuse_api.h" #include "osdep_service.h" #include "device_lock.h" _LONG_CALL_ROM_ extern u32 HALEFUSEOneByteReadROM(IN u32 CtrlSetting, IN u16 Addr, OUT u8 *Data, IN u8 L25OutVoltage); _LONG_CALL_ROM_ extern u32 HALEFUSEOneByteWriteROM(IN u32 CtrlSetting, IN u16 Addr, IN u8 Data, IN u8 L25OutVoltage); //====================================================== Start libs //----- int _HalEFUSEPowerSwitch8195AROM(uint8_t bWrite, uint8_t PwrState, uint8_t L25OutVoltage) { if (PwrState == 1) { HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF) | 0x69000000); // EFUSE_UNLOCK if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & BIT_SYS_FEN_EELDR)) // REG_SYS_FUNC_EN BIT_SYS_FEN_EELDR ? HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) | BIT_SYS_FEN_EELDR); if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) & BIT_SYSON_CK_EELDR_EN)) // REG_SYS_CLK_CTRL0 BIT_SYSON_CK_EELDR_EN ? HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) | BIT_SYSON_CK_EELDR_EN); if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & BIT_PESOC_EELDR_CK_SEL)) // REG_SYS_CLK_CTRL1 BIT_PESOC_EELDR_CK_SEL ? HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) | BIT_PESOC_EELDR_CK_SEL); if (bWrite == 1) HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & 0xFFFFF0FF) | BIT_SYS_REGU_LDO25E_EN | BIT_SYS_REGU_LDO25E_ADJ(L25OutVoltage)); } else { HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF); // EFUSE_UNLOCK if ( bWrite == 1 ) HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & (~BIT_SYS_REGU_LDO25E_EN))); } return bWrite; } //----- int _HALEFUSEOneByteReadROM(uint32_t CtrlSetting, uint16_t Addr, uint8_t *Data, uint8_t L25OutVoltage) { int i = 0, ret = 0; if ( (Addr <= 0xFF) || ((CtrlSetting & 0xFFFF) == 0x26AE) ) { _HalEFUSEPowerSwitch8195AROM(1, 1, L25OutVoltage); HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST) & (~BIT_SYS_EF_FORCE_PGMEN)); HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL, (CtrlSetting & (~(BIT_SYS_EF_RWFLAG | (BIT_MASK_SYS_EF_ADDR << BIT_SHIFT_SYS_EF_ADDR) | (BIT_MASK_SYS_EF_DATA << BIT_SHIFT_SYS_EF_DATA)))) | BIT_SYS_EF_ADDR(Addr)); if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) { *Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL); ret = 1; } else while(1) { HalDelayUs(1000); if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) { *Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL); ret = 1; break; } if (i++ >= 100) { *Data = -1; ret = 1; break; }; }; _HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage); } else *Data = -1; return ret; } //----- int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) { int result; if ( (unsigned int)(Addr - 128) > 0x1F ) result = 1; else result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); return result; } //----- int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) { int result; if ( (unsigned int)(Addr - 160) > 0x33 ) { result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); } else { *Data = -1; result = 1; } return result; } //----- void _ReadEOTPContant(uint8_t *pContant) { int i; for(i = 0; i < 32; i++ ) _HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE); } //----- void _ReadEfuseContant(int UserCode, uint8_t *pContant) { #define EFUSE_SECTION 11 uint8_t *pbuf; int eFuse_Addr; int offset; int bcnt; int i, j; uint8_t DataTemp0; uint8_t DataTemp1; pbuf = pContant; eFuse_Addr = 0; do { _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); if ( DataTemp0 == 0x0FF ) break; if ( (DataTemp0 & 0x0F) == 0x0F ) { _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE); offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1; bcnt = (~DataTemp1) & 0x0F; if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) { while (bcnt) { if (bcnt & 1) eFuse_Addr += 2; bcnt >>= 1; } } else { int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3; j = 0; while ( bcnt ) { if ( bcnt & 1 ) { _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE); _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE); } bcnt >>= 1; j += 2; } } } else { for (i = (~DataTemp0) & 0x0F; i; i >>= 1 ) { if (i & 1) eFuse_Addr += 2; } } eFuse_Addr++; } while (eFuse_Addr <= 0x7E); } //----- void _ReadEfuseContant1(uint8_t *pContant) { _ReadEfuseContant(0, pContant); } //----- void _ReadEfuseContant2(uint8_t *pContant) { _ReadEfuseContant(1, pContant); } //----- void _ReadEfuseContant3(uint8_t *pContant) { _ReadEfuseContant(2, pContant); } int _efuse_otp_read(u8 address, u8 len, u8 *buf) { u8 content[32]; // the OTP max length is 32 if((address + len) > 32) return -1; _ReadEOTPContant(content); _memcpy(buf, content + address, len); return 0; } //====================================================== end libs //====================================================== // OTP : one time programming //====================================================== uint8_t buf[128]; #define OTP_MAX_LEN 32 // The OTP max length is 32 bytes static void efuse_otp_task(void *param) { int ret; u8 i; DBG_8195A("\nefuse OTP block: Test Start\n"); // read OTP content device_mutex_lock(RT_DEV_LOCK_EFUSE); ret = efuse_otp_read(0, OTP_MAX_LEN, buf); device_mutex_unlock(RT_DEV_LOCK_EFUSE); if(ret < 0){ DBG_8195A("efuse OTP block: read address and length error\n"); goto exit; } for(i=0; i