pinebuds/services/nv_section/factory_section/factory_section.c

232 lines
7.2 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 "factory_section.h"
#include "cmsis.h"
#include "crc32.h"
#include "hal_norflash.h"
#include "hal_trace.h"
#include "heap_api.h"
#include "norflash_api.h"
#include "plat_types.h"
#include "pmu.h"
#include "string.h"
#include "tgt_hardware.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);
}
}