pinebuds/services/nv_section/factory_section/factory_section.c

274 lines
7.4 KiB
C

/***************************************************************************
*
* Copyright 2015-2019 BES.
* All rights reserved. All unpublished rights reserved.
*
* No part of this work may be used or reproduced in any form or by any
* means, or stored in a database or retrieval system, without prior written
* permission of BES.
*
* Use of this work is governed by a license granted by BES.
* This work contains confidential and proprietary information of
* BES. which is protected by copyright, trade secret,
* trademark and other intellectual property rights.
*
****************************************************************************/
#include "cmsis.h"
#include "plat_types.h"
#include "tgt_hardware.h"
#include "string.h"
#include "crc32.h"
#include "factory_section.h"
#include "pmu.h"
#include "hal_trace.h"
#include "hal_norflash.h"
#include "norflash_api.h"
#include "heap_api.h"
extern uint32_t __factory_start[];
extern uint32_t __factory_end[];
static factory_section_t *factory_section_p = NULL;
static uint8_t nv_record_dev_rev = nvrec_current_version;
#ifndef BTIF_BD_ADDR_SIZE
#define BTIF_BD_ADDR_SIZE 6
#endif
static void factory_callback(void* param)
{
NORFLASH_API_OPERA_RESULT *opera_result;
opera_result = (NORFLASH_API_OPERA_RESULT*)param;
TRACE(5,"%s:type = %d, addr = 0x%x,len = 0x%x,result = %d.",
__func__,
opera_result->type,
opera_result->addr,
opera_result->len,
opera_result->result);
}
void factory_section_init(void)
{
enum NORFLASH_API_RET_T result;
uint32_t sector_size = 0;
uint32_t block_size = 0;
uint32_t page_size = 0;
hal_norflash_get_size(HAL_NORFLASH_ID_0,
NULL,
&block_size,
&sector_size,
&page_size);
result = norflash_api_register(NORFLASH_API_MODULE_ID_FACTORY,
HAL_NORFLASH_ID_0,
((uint32_t)__factory_start)&0x00FFFFFF,
(uint32_t)__factory_end - (uint32_t)__factory_start,
block_size,
sector_size,
page_size,
FACTORY_SECTOR_SIZE,
factory_callback
);
ASSERT(result == NORFLASH_API_OK,"nv_record_init: module register failed! result = %d.",result);
}
int factory_section_open(void)
{
factory_section_p = (factory_section_t *)__factory_start;
if (factory_section_p->head.magic != nvrec_dev_magic){
factory_section_p = NULL;
return -1;
}
if ((factory_section_p->head.version < nvrec_mini_version) ||
(factory_section_p->head.version > nvrec_current_version))
{
factory_section_p = NULL;
return -1;
}
nv_record_dev_rev = factory_section_p->head.version;
if (1 == nv_record_dev_rev)
{
if (factory_section_p->head.crc !=
crc32(0,(unsigned char *)(&(factory_section_p->head.reserved0)),
sizeof(factory_section_t)-2-2-4-(5+63+2+2+2+1+8)*sizeof(int))){
factory_section_p = NULL;
return -1;
}
memcpy(bt_addr, factory_section_p->data.bt_address, BTIF_BD_ADDR_SIZE);
memcpy(ble_addr, factory_section_p->data.ble_address, BTIF_BD_ADDR_SIZE);
TRACE(2,"%s sucess btname:%s", __func__, factory_section_p->data.device_name);
}
else
{
// check the data length
if (((uint32_t)(&((factory_section_t *)0)->data.rev2_reserved0)+
factory_section_p->data.rev2_data_len) > 4096)
{
TRACE(1,"nv rec dev data len %d has exceeds the facory sector size!.",
factory_section_p->data.rev2_data_len);
return -1;
}
if (factory_section_p->data.rev2_crc !=
crc32(0,(unsigned char *)(&(factory_section_p->data.rev2_reserved0)),
factory_section_p->data.rev2_data_len)){
factory_section_p = NULL;
return -1;
}
memcpy(bt_addr, factory_section_p->data.rev2_bt_addr, BTIF_BD_ADDR_SIZE);
memcpy(ble_addr, factory_section_p->data.rev2_ble_addr, BTIF_BD_ADDR_SIZE);
TRACE(2,"%s sucess btname:%s", __func__, (char *)factory_section_p->data.rev2_bt_name);
}
DUMP8("%02x ", bt_addr, 6);
DUMP8("%02x ", ble_addr, 6);
return 0;
}
uint8_t* factory_section_get_bt_address(void)
{
if (factory_section_p)
{
if (1 == nv_record_dev_rev)
{
return (uint8_t *)&(factory_section_p->data.bt_address);
}
else
{
return (uint8_t *)&(factory_section_p->data.rev2_bt_addr);
}
}
else
{
return NULL;
}
}
uint8_t* factory_section_get_bt_name(void)
{
if (factory_section_p)
{
if (1 == nv_record_dev_rev)
{
return (uint8_t *)&(factory_section_p->data.device_name);
}
else
{
return (uint8_t *)&(factory_section_p->data.rev2_bt_name);
}
}
else
{
return (uint8_t *)BT_LOCAL_NAME;
}
}
uint8_t* factory_section_get_ble_name(void)
{
if (factory_section_p)
{
if (1 == nv_record_dev_rev)
{
return (uint8_t *)BLE_DEFAULT_NAME;
}
else
{
return (uint8_t *)&(factory_section_p->data.rev2_ble_name);
}
}
else
{
return (uint8_t *)BLE_DEFAULT_NAME;
}
}
uint32_t factory_section_get_version(void)
{
if (factory_section_p)
{
return nv_record_dev_rev;
}
return 0;
}
int factory_section_xtal_fcap_get(unsigned int *xtal_fcap)
{
if (factory_section_p){
if (1 == nv_record_dev_rev)
{
*xtal_fcap = factory_section_p->data.xtal_fcap;
}
else
{
*xtal_fcap = factory_section_p->data.rev2_xtal_fcap;
}
return 0;
}else{
return -1;
}
}
int factory_section_xtal_fcap_set(unsigned int xtal_fcap)
{
uint8_t *mempool = NULL;
uint32_t lock;
enum NORFLASH_API_RET_T ret;
if (factory_section_p){
TRACE(1,"factory_section_xtal_fcap_set:%d", xtal_fcap);
syspool_init();
syspool_get_buff((uint8_t **)&mempool, 0x1000);
memcpy(mempool, factory_section_p, 0x1000);
if (1 == nv_record_dev_rev)
{
((factory_section_t *)mempool)->data.xtal_fcap = xtal_fcap;
((factory_section_t *)mempool)->head.crc = crc32(0,(unsigned char *)(&(((factory_section_t *)mempool)->head.reserved0)),sizeof(factory_section_t)-2-2-4);
}
else
{
((factory_section_t *)mempool)->data.rev2_xtal_fcap = xtal_fcap;
((factory_section_t *)mempool)->data.rev2_crc =
crc32(0,(unsigned char *)(&(factory_section_p->data.rev2_reserved0)),
factory_section_p->data.rev2_data_len);
}
lock = int_lock_global();
ret = norflash_api_erase(NORFLASH_API_MODULE_ID_FACTORY,(uint32_t)(__factory_start)&0x00FFFFFF,0x1000,false);
ASSERT(ret == NORFLASH_API_OK,"factory_section_xtal_fcap_set: erase failed! ret = %d.",ret);
ret = norflash_api_write(NORFLASH_API_MODULE_ID_FACTORY,(uint32_t)(__factory_start)&0x00FFFFFF,(uint8_t *)mempool,0x1000,false);
ASSERT(ret == NORFLASH_API_OK,"factory_section_xtal_fcap_set: write failed! ret = %d.",ret);
int_unlock_global(lock);
return 0;
}else{
return -1;
}
}
void factory_section_original_btaddr_get(uint8_t *btAddr)
{
if(factory_section_p){
TRACE(0,"get factory_section_p");
if (1 == nv_record_dev_rev)
{
memcpy(btAddr, factory_section_p->data.bt_address, BTIF_BD_ADDR_SIZE);
}
else
{
memcpy(btAddr, factory_section_p->data.rev2_bt_addr, BTIF_BD_ADDR_SIZE);
}
}else{
TRACE(0,"get bt_addr");
memcpy(btAddr, bt_addr, BTIF_BD_ADDR_SIZE);
}
}