Files
ninlight-w600/sdk/Platform/Drivers/efuse/wm_efuse.c
T
Michael Sauer 1b0501179d build: W600-SDK importiert, Firmware-Build und Hello am EVK
Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet,
Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont
gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs
(EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
2026-09-11 12:52:26 +02:00

645 lines
17 KiB
C

/**************************************************************************
* File Name : tls_efuse.c
* Author :
* Version :
* Date :
* Description : Use Flash Addr as virtual efuse
*
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
* All rights reserved.
*
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wm_debug.h"
#include "wm_regs.h"
#include "wm_efuse.h"
#include "wm_config.h"
#include "list.h"
#include "wm_internal_flash.h"
#include "wm_crypto_hard.h"
#include "wm_timer.h"
#include "wm_cpu.h"
#include "wm_irq.h"
#include "wm_flash_map.h"
#include "wm_mem.h"
extern void flashSRRW(unsigned long offset,unsigned char *buf,unsigned long sz, unsigned char *backbuf, unsigned int backlen, unsigned int rd);
#define FT_MAGICNUM_ADDR (FLASH_BASE_ADDR)
#define MAGICNUM_LEN (4)
#define FT_CHECKSUM_ADDR (FT_MAGICNUM_ADDR + MAGICNUM_LEN)
#define CHECKSUM_LEN (4)
#define FT_DATALEN_ADDR (FT_CHECKSUM_ADDR + CHECKSUM_LEN)
#define FT_DATALEN_LEN (4)
#define FT_MAC_ADDR (FT_DATALEN_ADDR + FT_DATALEN_LEN)
#define MAC_ADDR_LEN (8)
#define FT_TX_DC_OFFSET_ADDR (FT_MAC_ADDR + MAC_ADDR_LEN)
#define TX_DC_OFFSET_LEN (4)
#define FT_RX_DC_OFFSET_ADDR (FT_TX_DC_OFFSET_ADDR + TX_DC_OFFSET_LEN)
#define RX_DC_OFFSET_LEN (4)
#define FT_TX_IQ_GAIN_ADDR (FT_RX_DC_OFFSET_ADDR + RX_DC_OFFSET_LEN)
#define TX_IQ_GAIN_LEN (4)
#define FT_RX_IQ_GAIN_ADDR (FT_TX_IQ_GAIN_ADDR + TX_IQ_GAIN_LEN)
#define RX_IQ_GAIN_LEN (4)
#define FT_TX_IQ_PHASE_ADDR (FT_RX_IQ_GAIN_ADDR + RX_IQ_GAIN_LEN)
#define TX_IQ_PHASE_LEN (4)
#define FT_RX_IQ_PHASE_ADDR (FT_TX_IQ_PHASE_ADDR + TX_IQ_PHASE_LEN)
#define RX_IQ_PHASE_LEN (4)
#define FT_GAIN_ADDR (FT_RX_IQ_PHASE_ADDR + RX_IQ_PHASE_LEN)
#define FT_GAIN_LEN (84)
#define FT_FIX_DATA_LEN (MAC_ADDR_LEN + TX_DC_OFFSET_LEN + RX_DC_OFFSET_LEN + TX_IQ_GAIN_LEN + RX_IQ_GAIN_LEN \
+ TX_IQ_PHASE_LEN \
+ RX_IQ_PHASE_LEN)
/* key paramater area -- begin -- */
/** PHY parameter area **/
#define PHY_BASE_ADDR (FLASH_BASE_ADDR)
#define PHY_AREA_LEN (0x1000)
/** QFlash parameter area **/
#define QFLASH_BASE_ADDR (PHY_BASE_ADDR + PHY_AREA_LEN)
#define QFLASH_AREA_LEN (0x1000)
#define QFLASH_HDR_BASE_ADDR (QFLASH_BASE_ADDR)
#define QFLASH_HDR_LEN (12)
#define QFLASH_Sec_Level_BASE_ADDR (QFLASH_HDR_BASE_ADDR + QFLASH_HDR_LEN)
#define QFLASH_Sec_Level_LEN (4)
#define QFLASH_CHIP_ID_BASE_ADDR (QFLASH_Sec_Level_BASE_ADDR + QFLASH_Sec_Level_LEN)
#define QFLASH_CHIP_ID_LEN (16)
/* key parameter area -- end -- */
typedef struct FT_PARAM
{
unsigned int magic_no;
unsigned int checksum;
unsigned int data_len;
unsigned char mac_addr[MAC_ADDR_LEN];
unsigned int tx_dcoffset;
unsigned int rx_dcoffset;
unsigned int tx_iq_gain;
unsigned int rx_iq_gain;
unsigned int tx_iq_phase;
unsigned int rx_iq_phase;
unsigned char tx_gain[FT_GAIN_LEN];
}FT_PARAM_ST;
static u8 default_mac[6] = {0x00,0x25,0x08,0x09,0x01,0x0F};
FT_PARAM_ST gftParam;
int tls_ft_param_init(void)
{
int i = 0;
int usedcnt[2] = {0, 0};
u32 crcvalue = 0;
psCrcContext_t ctx;
u8 *pmem = NULL;
FT_PARAM_ST *pft = NULL;
if (gftParam.magic_no == SIGNATURE_WORD)
{
return TRUE;
}
pmem = tls_mem_alloc(512);
if (pmem == NULL)
{
return FALSE;
}
pft = tls_mem_alloc(sizeof(FT_PARAM_ST));
if (pft == NULL)
{
return FALSE;
}
for (i = 0; i < 2; i++)
{
if (i == 0)
{
tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)pft, sizeof(FT_PARAM_ST));
}else{
flashSRRW(0, (unsigned char *)pft, sizeof(FT_PARAM_ST), pmem, 256, 1);
}
if (pft->magic_no == SIGNATURE_WORD)
{
tls_crypto_init();
tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
tls_crypto_crc_update(&ctx, (unsigned char *)pft + 12, sizeof(FT_PARAM_ST) - 12);
tls_crypto_crc_final(&ctx, &crcvalue);
if ((pft->checksum != crcvalue))
{
usedcnt[i] = -1;
continue;
}
if (gftParam.magic_no != SIGNATURE_WORD)
{
memcpy(&gftParam, pft, sizeof(FT_PARAM_ST));
}
}else{
usedcnt[i] = -1;
}
}
if ((usedcnt[0] + usedcnt[1]) == -2)
{
/*Use default ft param*/
}
else if (usedcnt[0] < 0) /*flash param destroyed*/
{
tls_flash_unlock();
tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
tls_flash_lock();
}
else if (usedcnt[1] < 0) /*SR param destroyed*/
{
flashSRRW(0, (unsigned char *)&gftParam, sizeof(FT_PARAM_ST), pmem, 256, 0);
}
else
{
if (gftParam.checksum != pft->checksum)
{
flashSRRW(0, (unsigned char *)&gftParam, sizeof(FT_PARAM_ST), pmem, 256, 0);
}
}
tls_mem_free(pmem);
tls_mem_free(pft);
return TRUE;
}
int tls_ft_param_get(unsigned int opnum, void *data, unsigned int rdlen)
{
//FT_PARAM_ST ft;
//tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)&ft, sizeof(ft));
switch (opnum)
{
case CMD_MAC: /*MAC*/
if ((gftParam.mac_addr[0]&0x1)
||(0 == (gftParam.mac_addr[0]|gftParam.mac_addr[1]|gftParam.mac_addr[2]|gftParam.mac_addr[3]|gftParam.mac_addr[4]|gftParam.mac_addr[5])))
{
memcpy(data, default_mac, rdlen);
}
else
{
memcpy(data, gftParam.mac_addr, rdlen);
}
break;
case CMD_TX_DC: /*tx_dcoffset*/
*(unsigned int *)data = gftParam.tx_dcoffset;
break;
case CMD_RX_DC: /*rx_dcoffset*/
*(unsigned int *)data = gftParam.rx_dcoffset;
break;
case CMD_TX_IQ_GAIN:
*(unsigned int *)data = gftParam.tx_iq_gain;
break;
case CMD_RX_IQ_GAIN:
*(unsigned int *)data = gftParam.rx_iq_gain;
break;
case CMD_TX_IQ_PHASE:
*(unsigned int *)data = gftParam.tx_iq_phase;
break;
case CMD_RX_IQ_PHASE:
*(unsigned int *)data = gftParam.rx_iq_phase;
break;
case CMD_TX_GAIN: /*gain*/
if (rdlen < FT_GAIN_LEN)
{
memcpy(data, gftParam.tx_gain, rdlen);
}
else
{
memcpy(data, gftParam.tx_gain, FT_GAIN_LEN);
}
break;
default:
return -1;
}
return 0;
}
int tls_ft_param_set(unsigned int opnum, void *data, unsigned int len)
{
psCrcContext_t ctx;
unsigned int writelen = 0;
u8 *pmem = NULL;
if (!data || !len)
{
return -1;
}
//tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
switch (opnum)
{
case CMD_MAC: /*MAC*/
memcpy(gftParam.mac_addr, (unsigned char *)data, len);
break;
case CMD_TX_DC: /*tx_dcoffset*/
gftParam.tx_dcoffset = *(unsigned int *)data;
break;
case CMD_RX_DC: /*rx_dcoffset*/
gftParam.rx_dcoffset = *(unsigned int *)data;
break;
case CMD_TX_IQ_GAIN:
gftParam.tx_iq_gain = *(unsigned int *)data;
break;
case CMD_RX_IQ_GAIN:
gftParam.rx_iq_gain = *(unsigned int *) data;
break;
case CMD_TX_IQ_PHASE:
gftParam.tx_iq_phase = *(unsigned int *)data;
break;
case CMD_RX_IQ_PHASE:
gftParam.rx_iq_phase = *(unsigned int *) data;
break;
case CMD_TX_GAIN: /*gain*/
if (len >= FT_GAIN_LEN)
{
writelen = FT_GAIN_LEN;
}
else
{
writelen = len;
}
memcpy(gftParam.tx_gain, data, writelen);
break;
default:
return -1;
}
tls_crypto_init();
tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
gftParam.magic_no = SIGNATURE_WORD;
tls_crypto_crc_update(&ctx, (unsigned char *)&gftParam + 12, sizeof(gftParam) -12);
tls_crypto_crc_final(&ctx, &gftParam.checksum);
tls_flash_unlock();
tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
tls_flash_lock();
pmem = tls_mem_alloc(512);
if (pmem)
{
flashSRRW(0, (unsigned char *)&gftParam, sizeof(gftParam), pmem, 512, 0);
tls_mem_free(pmem);
}
return 0;
}
/**********************************************************************************************************
* Description: This function is used to get mac addr.
*
* Arguments : mac mac addr,6 byte
*
* Returns : TLS_EFUSE_STATUS_OK get success
* TLS_EFUSE_STATUS_EIO get failed
**********************************************************************************************************/
int tls_get_mac_addr(u8 *mac)
{
return tls_ft_param_get(CMD_MAC, mac, 6);
}
/**********************************************************************************************************
* Description: This function is used to set mac addr.
*
* Arguments : mac mac addr,6 byte
*
* Returns : TLS_EFUSE_STATUS_OK get success
* TLS_EFUSE_STATUS_EIO get failed
**********************************************************************************************************/
int tls_set_mac_addr(u8 *mac)
{
return tls_ft_param_set(CMD_MAC, mac, 6);
}
/**********************************************************************************************************
* Description: This function is used to get tx lod.
*
* Arguments : *txlo
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_get_tx_lo(u8 *txlo)
{
return tls_ft_param_get(CMD_TX_DC, txlo, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx lo.
*
* Arguments : txlo
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_lo(u8 *txlo)
{
return tls_ft_param_set(CMD_TX_DC, txlo, 4);
}
/**********************************************************************************************************
* Description: This function is used to get tx iq gain.
*
* Arguments : txGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_tx_iq_gain(u8 *txGain)
{
return tls_ft_param_get(CMD_TX_IQ_GAIN, txGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx iq gain.
*
* Arguments : txGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_iq_gain(u8 *txGain)
{
return tls_ft_param_set(CMD_TX_IQ_GAIN, txGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to get rx iq gain.
*
* Arguments : rxGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_rx_iq_gain(u8 *rxGain)
{
return tls_ft_param_get(CMD_RX_IQ_GAIN, rxGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to set rx iq gain.
*
* Arguments : rxGain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_rx_iq_gain(u8 *rxGain)
{
return tls_ft_param_set(CMD_RX_IQ_GAIN, rxGain, 4);
}
/**********************************************************************************************************
* Description: This function is used to get tx iq phase.
*
* Arguments : txPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_tx_iq_phase(u8 *txPhase)
{
return tls_ft_param_get(CMD_TX_IQ_PHASE, txPhase, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx iq phase.
*
* Arguments : txPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_iq_phase(u8 *txPhase)
{
return tls_ft_param_set(CMD_TX_IQ_PHASE, txPhase, 4);
}
/**********************************************************************************************************
* Description: This function is used to get rx iq phase.
*
* Arguments : rxPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_get_rx_iq_phase(u8 *rxPhase)
{
return tls_ft_param_get(CMD_RX_IQ_PHASE, rxPhase, 4);
}
/**********************************************************************************************************
* Description: This function is used to set tx iq phase.
*
* Arguments : rxPhase
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_rx_iq_phase(u8 *rxPhase)
{
return tls_ft_param_set(CMD_RX_IQ_PHASE, rxPhase, 4);
}
int tls_freq_err_op(u8 *freqerr, u8 flag)
{
tls_flash_unlock();
if (flag){
tls_fls_write(FT_MAGICNUM_ADDR + sizeof(FT_PARAM_ST), freqerr, 4);
}
else
{
tls_fls_read(FT_MAGICNUM_ADDR + sizeof(FT_PARAM_ST), freqerr, 4);
}
tls_flash_lock();
return TLS_EFUSE_STATUS_OK;
}
int tls_rf_vcg_ctrl_op(u8 *vcg, u8 flag)
{
tls_flash_unlock();
if (flag){
tls_fls_write(VCG_ADDR, vcg, VCG_LEN);
}
else
{
tls_fls_read(VCG_ADDR, vcg, VCG_LEN);
}
tls_flash_lock();
return TLS_EFUSE_STATUS_OK;
}
/**********************************************************************************************************
* Description: This function is used to get tx gain.
*
* Arguments : txgain tx gain
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_get_tx_gain(u8 *txgain)
{
return tls_ft_param_get(CMD_TX_GAIN, txgain, TX_GAIN_LEN);
}
/**********************************************************************************************************
* Description: This function is used to set tx gain.
*
* Arguments : txgain tx gain
*
* Returns : 0 set success
* -1 set failed
**********************************************************************************************************/
int tls_set_tx_gain(u8 *txgain)
{
return tls_ft_param_set(CMD_TX_GAIN, txgain, TX_GAIN_LEN);
}
/**********************************************************************************************************
* Description: This function is used to get uuid
*
* Arguments : *uuid
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_get_uuid(u8 *uuid, u8 len)
{
u8 *pmem = NULL;
if (uuid)
{
pmem = tls_mem_alloc(512);
if (pmem == NULL)
{
return TLS_EFUSE_STATUS_ERR;
}
flashSRRW(256, (unsigned char *)pmem, len, pmem, 512, 1);
memcpy(uuid, &pmem[0], len);
tls_mem_free(pmem);
pmem = NULL;
return TLS_EFUSE_STATUS_OK;
}
return TLS_EFUSE_STATUS_ERR;
}
/**********************************************************************************************************
* Description: This function is used to get uuid
*
* Arguments : *uuid :data to be written to otp area
* len : data len to be written
* iflock : if lock the otp area,1-lock, once lock,can not unlock!!!
*
* Returns : 0 get success
* -1 get failed
**********************************************************************************************************/
int tls_set_uuid(u8 *uuid, u8 len, u8 iflock)
{
u8 *pmem = NULL;
if (uuid)
{
pmem = tls_mem_alloc(512);
if (pmem == NULL)
{
return TLS_EFUSE_STATUS_ERR;
}
flashSRRW(256, (unsigned char *)uuid, len, pmem, 512, 0);
if (iflock)
{
writeSRLockBit(2);
}
tls_mem_free(pmem);
pmem = NULL;
return TLS_EFUSE_STATUS_OK;
}
return TLS_EFUSE_STATUS_ERR;
}
#define FF_n16 0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff
int tls_get_chipid(u8 chip_id[QFLASH_CHIP_ID_LEN])
{
int ret = 0;
static u8 _chip_id[QFLASH_CHIP_ID_LEN] = { FF_n16 };
u8 zero[QFLASH_CHIP_ID_LEN] = { FF_n16 };
if (!memcmp(_chip_id, zero, QFLASH_CHIP_ID_LEN))
{
ret = tls_fls_read(QFLASH_CHIP_ID_BASE_ADDR, _chip_id, QFLASH_CHIP_ID_LEN);
}
if (0 == ret)
{
memcpy(chip_id, _chip_id, QFLASH_CHIP_ID_LEN);
}
return ret;
}
#undef FF_n16
unsigned int tls_sleep(unsigned int seconds)
{
int ret = 0;
ret = tls_msleep(seconds * 1000);
return ret;
}
int tls_msleep(unsigned int msec)
{
int ret = 0;
ret = tls_delay_via_timer(msec, TIMER_MS_UNIT_FLAG);
return ret;
}
int tls_usleep(unsigned int /*useconds_t*/ usec)
{
int ret = 0;
ret = tls_delay_via_timer(usec, TIMER_US_UNIT_FLAG);
return ret;
}