mirror of
https://github.com/drasko/open-ameba.git
synced 2024-12-26 16:15:19 +00:00
361 lines
11 KiB
C
361 lines
11 KiB
C
#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<OTP_MAX_LEN; i+=8){
|
|
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
|
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
|
}
|
|
int x = 0;
|
|
while(x < 1024) {
|
|
DBG_8195A("efuse OTP block at %d:\n", x);
|
|
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
|
for(i = 0; i < sizeof(buf); i++ )
|
|
// _HALEFUSEOneByteReadROM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+x, &buf[i], L25EOUTVOLTAGE);
|
|
_HALEFUSEOneByteReadROM(0x26AF, i+x, &buf[i], L25EOUTVOLTAGE);
|
|
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
|
for(i = 0; i < sizeof(buf); i+=8){
|
|
DBG_8195A("[%04x]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
|
i+x, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
|
}
|
|
x+=sizeof(buf);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
// write OTP content
|
|
_memset(buf, 0xFF, OTP_MAX_LEN);
|
|
if(0){ // fill your data
|
|
for(i=0; i<OTP_MAX_LEN; i++)
|
|
buf[i] = i;
|
|
}
|
|
if(0){ // write
|
|
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
|
ret = efuse_otp_write(0, OTP_MAX_LEN, buf);
|
|
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
|
if(ret < 0){
|
|
DBG_8195A("efuse OTP block: write address and length error\n");
|
|
goto exit;
|
|
}
|
|
DBG_8195A("\nWrite Done.\n");
|
|
}
|
|
DBG_8195A("\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<OTP_MAX_LEN; i+=8){
|
|
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
|
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
|
}
|
|
*/
|
|
DBG_8195A("efuse OTP block: Test Done\n");
|
|
vTaskDelete(NULL);
|
|
|
|
exit:
|
|
DBG_8195A("efuse OTP block: Test Fail!\n");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
//======================================================
|
|
// MTP : M? time programming
|
|
//======================================================
|
|
|
|
#define MTP_MAX_LEN 32 // The MTP max length is 32 bytes
|
|
static void efuse_mtp_task(void *param)
|
|
{
|
|
int ret;
|
|
u8 i;
|
|
|
|
DBG_8195A("\nefuse MTP block: Test Start\n");
|
|
// read MTP content
|
|
_memset(buf, 0xFF, MTP_MAX_LEN);
|
|
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
|
efuse_mtp_read(buf);
|
|
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
|
for(i=0; i<MTP_MAX_LEN; i+=8){
|
|
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
|
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
|
}
|
|
DBG_8195A("\nefuse MTP block: Test Start\n");
|
|
// read MTP content
|
|
_memset(buf, 0xFF, MTP_MAX_LEN);
|
|
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
|
_ReadEfuseContant1(buf);
|
|
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
|
for(i=0; i<MTP_MAX_LEN; i+=8){
|
|
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
|
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
|
}
|
|
/*
|
|
// write MTP content
|
|
_memset(buf, 0xFF, MTP_MAX_LEN);
|
|
if(0){ // fill your data
|
|
for(i=0; i<MTP_MAX_LEN; i++)
|
|
buf[i] = i;
|
|
}
|
|
if(0){ // write
|
|
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
|
ret = efuse_mtp_write(buf, MTP_MAX_LEN);
|
|
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
|
if(ret < 0){
|
|
DBG_8195A("efuse MTP block: write length error\n");
|
|
goto exit;
|
|
}
|
|
DBG_8195A("\nWrite Done\n");
|
|
DBG_8195A("Remain %d\n", efuse_get_remaining_length());
|
|
}
|
|
DBG_8195A("\n");
|
|
|
|
// read MTP content
|
|
_memset(buf, 0xFF, MTP_MAX_LEN);
|
|
device_mutex_lock(RT_DEV_LOCK_EFUSE);
|
|
efuse_mtp_read(buf);
|
|
device_mutex_unlock(RT_DEV_LOCK_EFUSE);
|
|
for(i=0; i<MTP_MAX_LEN; i+=8){
|
|
DBG_8195A("[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n",
|
|
i, buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
|
|
}
|
|
|
|
*/
|
|
DBG_8195A("efuse MTP block: Test Done\n");
|
|
vTaskDelete(NULL);
|
|
exit:
|
|
DBG_8195A("efuse MTP block: Test Fail!\n");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void main(void)
|
|
{
|
|
ConfigDebugErr = -1; // ~_DBG_GDMA_;
|
|
ConfigDebugInfo = -1; // ~_DBG_GDMA_;
|
|
ConfigDebugWarn = -1; // ~_DBG_GDMA_;
|
|
|
|
DBG_8195A("EFUSE_CTRL=%08x\n", HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL));
|
|
|
|
if(xTaskCreate(efuse_mtp_task, ((const char*)"efuse_mtp_task"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
|
printf("\n\r%s xTaskCreate(efuse_mtp_task) failed", __FUNCTION__);
|
|
|
|
if(xTaskCreate(efuse_otp_task, ((const char*)"efuse_otp_task"), 512, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS)
|
|
printf("\n\r%s xTaskCreate(efuse_otp_task) failed", __FUNCTION__);
|
|
|
|
/*Enable Schedule, Start Kernel*/
|
|
if(rtw_get_scheduler_state() == OS_SCHEDULER_NOT_STARTED)
|
|
vTaskStartScheduler();
|
|
else
|
|
vTaskDelete(NULL);
|
|
}
|