JT-DT-YD4N02B_4G_RTT_MRS/bsp/src/bsp_flash.c

986 lines
29 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_flash.h"
#include "lwutil.h"
#include "bsp_rtc.h"
// #include "bsp_wdg.h"
#include "bsp_hr.h"
#include "at_device_nt26k.h"
#include <rtthread.h>
#include <rthw.h>
#include "user_sys.h"
#define LOG_TAG "bsp_flash"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
#include <stdlib.h>
#define GETATTR(info, id) ((id) == kHwVerId ? (&(info)->hw_ver) \
: (id) == kSwVerId ? (&(info)->sw_ver) \
: (id) == kAlarmLValueId ? (&(info)->alarm_l_value) \
: (id) == kAlarmHValueId ? (&(info)->alarm_h_value) \
: (id) == kTempAlarmThresholdId ? (&(info)->temp_alarm_threshold) \
: (id) == kIotUploadCycleId ? (&(info)->iot_upload_cycle) \
: (id) == kIotRetryId ? (&(info)->iot_retry) \
: (id) == kEmagneticSwitchId ? (&(info)->emagnetic_switch) \
: (id) == kRelaySwitchId ? (&(info)->relay_switch) \
: (id) == kIotImeiId ? ((info)->iot_imei) \
: (id) == kIotImsiId ? ((info)->iot_imsi) \
: (id) == kIotIccidId ? ((info)->iot_iccid) \
: NULL)
TsTotalRecords TotalRecords;
const rt_uint32_t hr_start_addr[7] = {FLASH_HR_ALARM_START_ADDR,
FLASH_HR_ALARM_RCY_START_ADDR,
FLASH_HR_FAULT_START_ADDR, FLASH_HR_FAULT_RCY_START_ADDR,
FLASH_HR_POWER_FAILURE_START_ADDR, FLASH_HR_POWER_ON_START_ADDR,
FLASH_HR_SENSOR_FAILURE_START_ADDR};
const rt_uint8_t hr_record_max_num[7] = {HR_ALARM_MAX_NUM,
HR_ALARM_RCY_MAX_NUM,
HR_FAULT_MAX_NUM, HR_FAULT_RCY_MAX_NUM,
HR_POWER_FAILURE_MAX_NUM, HR_POWER_ON_MAX_NUM,
HR_SENSOR_FAILURE_MAX_NUM};
const rt_uint8_t hr_record_pages[7] = {HR_ALARM_PAGES, HR_ALARM_RCY_PAGES,
HR_FAULT_PAGES, HR_FAULT_RCY_PAGES,
HR_POWER_FAILURE_PAGES, HR_POWER_ON_PAGES,
HR_SENSOR_FAILURE_PAGES};
const rt_uint32_t hr_sys_cfg_info_addr[kCnt] = {
FLASH_HW_VER_ADDR,
FLASH_SW_VER_ADDR,
FLASH_ALARM_L_VALUE_ADDR,
FLASH_ALARM_H_VALUE_ADDR,
FLASH_IOT_UPLOAD_CYCLE_ADDR,
FLASH_IOT_RETRY_ADDR,
FLASH_TEMP_ALARM_THRESHOLD_ADDR,
FLASH_EMAGNETIC_SWITCH_ADDR,
FLASH_RELAY_SWITCH_ADDR,
FLASH_IOT_IMEI_ADDR,
FLASH_IOT_IMSI_ADDR,
FLASH_IOT_ICCID_ADDR,
};
const rt_uint32_t hr_sys_cfg_info_len[kCnt] = {
FLASH_HW_VER_LEN,
FLASH_SW_VER_LEN,
FLASH_ALARM_L_VALUE_LEN,
FLASH_ALARM_H_VALUE_LEN,
FLASH_IOT_UPLOAD_CYCLE_LEN,
FLASH_IOT_RETRY_LEN,
FLASH_TEMP_ALARM_THRESHOLD_LEN,
FLASH_EMAGNETIC_SWITCH_LEN,
FLASH_RELAY_SWITCH_LEN,
FLASH_IOT_IMEI_LEN,
FLASH_IOT_IMSI_LEN,
FLASH_IOT_ICCID_LEN,
};
static rt_base_t interrupt_value;
/*默认的系统配置*/
flash_sever_info sever_info =
{
.server_url = SYS_IOT_URL,
.server_port = SYS_IOT_PORT,
};
static void BSP_Flash_UnLock (void)
{
#if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE)
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
#endif
interrupt_value = rt_hw_interrupt_disable();
FLASH_Unlock();
}
static void BSP_Flash_Lock (void)
{
FLASH_Lock();
#if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE)
RCC->CFGR0 &= ~(uint32_t)RCC_HPRE_DIV2;
#endif
rt_hw_interrupt_enable (interrupt_value);
}
static void BSP_Flash_FastUnLock (void)
{
#if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE)
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
#endif
interrupt_value = rt_hw_interrupt_disable();
FLASH_Unlock_Fast();
}
static void BSP_Flash_FastLock (void)
{
FLASH_Lock_Fast();
#if (SystemCoreClock > SYSCLK_FREQ_96MHz_HSE)
RCC->CFGR0 &= ~(uint32_t)RCC_HPRE_DIV2;
#endif
rt_hw_interrupt_enable (interrupt_value);
}
static rt_size_t Flash_Read (rt_uint32_t addr, rt_uint8_t *buf, rt_size_t len)
{
rt_size_t read_len = 0;
for (rt_size_t i = 0; i < len; i++, buf++, addr++, read_len++)
{
*buf = *(rt_uint8_t *)addr;
}
return read_len;
}
int Get_IotImei (char *buf, rt_size_t len)
{
if ((*(rt_uint8_t *)FLASH_IOT_IMEI_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_IMEI_ADDR != 0x39))
{
char imei_buf[FLASH_IOT_IMEI_LEN]={0};
Flash_Read(FLASH_IOT_IMEI_ADDR, (rt_uint8_t *)&imei_buf[0], len);
LOG_D ("read imei: %s", imei_buf);
rt_memcpy(buf, imei_buf, len);
return 0;
}
else
{
/*如果没有写进去则全部是0*/
for (rt_uint8_t i = 0; i < len; i++)
{
buf[i] = '0';
}
LOG_D ("IOT IMSI: %s", buf);
return -1;
}
}
int Get_IotImsi (char *buf, rt_size_t len)
{
if ((*(rt_uint8_t *)FLASH_IOT_IMSI_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_IMSI_ADDR != 0x39))
{
char imsi_buf[FLASH_IOT_IMSI_LEN]={0};
Flash_Read(FLASH_IOT_IMSI_ADDR, (rt_uint8_t *)imsi_buf, len);
LOG_D ("read imsi: %s", imsi_buf);
rt_memcpy(buf, imsi_buf, len);
return 0;
}
else
{
/*如果没有写进去则全部是0*/
for (rt_uint8_t i = 0; i < len; i++)
{
buf[i] = '0';
}
LOG_D ("IOT IMSI: %s", buf);
return -1;
}
}
int Get_IotIccid (char *buf, rt_size_t len)
{
if ((*(rt_uint8_t *)FLASH_IOT_ICCID_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_ICCID_ADDR != 0x39))
{
char iccid_buf[FLASH_IOT_ICCID_LEN]={0};
Flash_Read(FLASH_IOT_ICCID_ADDR, (rt_uint8_t *)iccid_buf, len);
LOG_D ("read iccid: %s", iccid_buf);
rt_memcpy(buf, iccid_buf, len);
return 0;
}
else
{
/*如果没有写进去则全部是0*/
for (rt_uint8_t i = 0; i < len; i++)
{
buf[i] = '0';
}
LOG_D ("IOT ICCID: %s", buf);
return -1;
}
}
/**
* @description:
* @param {uint32_t} addr
* @param {uint8_t} *buf
* @param {size_t} len
* @return {*}
*/
static rt_size_t Flash_Write (rt_uint32_t addr, rt_uint8_t *buf, rt_size_t len)
{
rt_size_t i = 0;
__attribute__ ((aligned (2))) rt_uint16_t write_data;
if (addr % 2 != 0)
return 0;
FLASH_ClearFlag (FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
BSP_Flash_UnLock();
for (i = 0; i < len; i += 2, buf += 2, addr += 2)
{
rt_memcpy (&write_data, buf, 2);
FLASH_ProgramHalfWord (addr, write_data);
/* You can add your code under here. */
if (*(rt_uint16_t *)addr != write_data)
{
BSP_Flash_Lock();
LOG_E ("Flash_Write Error");
return 0;
}
}
BSP_Flash_Lock();
return i;
}
int BSP_Flash_Write_Info (rt_uint8_t *buf, rt_size_t len)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
rt_uint8_t in_page_offset = (FLASH_HW_VER_ADDR - FLASH_CONFIG_INFO_START_ADDR);
Flash_ErasePage_ReadConfigInfo (page_buf);
for (rt_uint8_t i = 0; i < len; i++)
{
page_buf[in_page_offset + i] = buf[i];
}
return Flash_Write_ConfigInfo (page_buf);
}
rt_uint16_t Flash_Get_WorkDuration (void)
{
return *(rt_uint16_t *)(FLASH_WORK_TIME_ADDR);
}
int Flash_Set_WorkDuration (rt_uint16_t value)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
rt_uint8_t in_page_offset = (FLASH_WORK_TIME_ADDR - FLASH_CONFIG_INFO_START_ADDR);
Flash_ErasePage_ReadConfigInfo (page_buf);
rt_memcpy (page_buf + in_page_offset, &value, FLASH_WORK_TIME_LEN);
return Flash_Write_ConfigInfo (page_buf);
}
int Flash_Get_Sever_Data (flash_sever_info *sever_info)
{
rt_uint8_t data[FLASH_SERVER_LEN] = {0};
rt_memcpy (data, (rt_uint8_t *)FLASH_SERVER_ADDR_ADDR, FLASH_SERVER_LEN);
LOG_D ("data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x data[%d] = %x", 0, data[0], 1, data[1], 2, data[2], 3, data[3], 4, data[4], 5, data[5]);
rt_snprintf (sever_info->server_url, sizeof (sever_info->server_url), "%d.%d.%d.%d",
data[3], data[2], data[1], data[0]);
rt_uint16_t port_num = ((data[5] << 8) | data[4]);
LOG_D ("port_num = %d", port_num);
rt_snprintf (sever_info->server_port, sizeof (sever_info->server_port), "%d", port_num);
LOG_D ("server_url:%s, server_port:%s", sever_info->server_url, sever_info->server_port);
return 0;
}
int Flash_Set_Sever_Data (rt_uint8_t *data)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
rt_uint8_t in_page_offset = (FLASH_SERVER_ADDR_ADDR - FLASH_CONFIG_INFO_START_ADDR);
if (data == RT_NULL)
{
return -RT_ERROR;
}
Flash_ErasePage_ReadConfigInfo (page_buf);
//*将传入的数据写到flash地址中
for (size_t i = 0; i < FLASH_SERVER_LEN; i++)
{
page_buf[in_page_offset++] = data[i];
}
return Flash_Write_ConfigInfo (page_buf);
}
/**
* @description: Flash Erase Page
* @param {TeRecord} record
* @param {uint8_t} page
* @return {*}
*/
static ErrorStatus Flash_ErasePage_Records (TeRecord record,
rt_uint8_t page_offset)
{
ErrorStatus flag = READY;
rt_uint8_t erase_page = 0;
if (page_offset <= hr_record_pages[record] - 1)
{
erase_page = page_offset;
}
else
{
erase_page = hr_record_pages[record] - 1;
}
BSP_Flash_FastUnLock();
FLASH_ErasePage_Fast (hr_start_addr[record] + FLASH_PAGE_SIZE * erase_page);
BSP_Flash_FastLock();
for (rt_uint8_t i = 0; i < (FLASH_PAGE_SIZE / 2); i++)
{
if (*(rt_uint16_t *)((hr_start_addr[record] + FLASH_PAGE_SIZE * erase_page) + 2 * i) != 0xE339)
{
flag = NoREADY;
}
}
LOG_D ("/**Flash_Erase(%d)Page(%d)=%d**/", record, erase_page, flag);
return flag;
}
void Flash_Erase_Records (TeRecord record)
{
for (rt_uint8_t erase_page = 0; erase_page < hr_record_pages[record];
erase_page++)
{
Flash_ErasePage_Records (record, erase_page);
}
LOG_D ("Flash_Erase_Records(%d)", record);
}
/*
* @description:
* @param {TeRecord} record
* @return {*}
*/
static rt_uint16_t Flash_GetMaxIndex_Records (TeRecord record)
{
rt_uint16_t index_max = 0;
for (rt_uint8_t page = 0; page < hr_record_pages[record]; page++)
{
for (rt_uint8_t i = 0; i < FLASH_PAGE_HR_RECORD_NUM; i++)
{
if (*(rt_uint16_t *)(hr_start_addr[record] + FLASH_PAGE_SIZE * page + FLASH_HR_ONE_RECORD_SIZE * i) == HR_RECORD_FRAME_HEADER)
{
index_max =
LWUTIL_MAX (index_max,
*(rt_uint16_t *)(hr_start_addr[record] + FLASH_PAGE_SIZE * page + FLASH_HR_ONE_RECORD_SIZE * i + 2));
}
}
}
LOG_D ("Flash_Get_Records(%d)MaxNum = %d", record, index_max);
return index_max;
}
/**
* @description:
* @param {TeRecord} record
* @return {*}
*/
rt_uint8_t Flash_GetNum_Records (TeRecord record)
{
rt_uint8_t num = 0;
rt_uint16_t num_max = Flash_GetMaxIndex_Records (record);
if (num_max <= hr_record_max_num[record])
{
num = num_max;
}
else
{
num = hr_record_max_num[record];
}
LOG_D ("Flash_GetNum_(%d)Records = %d", record, num);
return num;
}
/**
* @description:
* @param {TuFlashHrRecordFrame*} pHrRecord
* @param {TeRecord} record
* @param {uint8_t} index
* @return {*}
*/
void Flash_Read_Record (TuFlashHrRecordFrame *pHrRecord, TeRecord record,
rt_uint8_t index)
{
LOG_D ("/*********Flash_Read_(%d)Record(%d)***************/", record, index);
uint16_t index_max = Flash_GetMaxIndex_Records (record);
rt_uint8_t page_offset = 0;
rt_uint8_t in_page_offset = 0;
if (index <= index_max)
{
if (index_max > hr_record_max_num[record])
{
if (record < kRecordSensoEndOfLife)
{
// index_redirect = index_max - (hr_record_max_num[record] - index);
uint16_t index_redirect = index_max - (50 - index);
LOG_D ("index_redirect = %d", index_redirect);
page_offset = ((index_redirect - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record];
in_page_offset = ((index_redirect - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE;
}
else
{
page_offset = 0;
in_page_offset = ((index_max - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE;
}
}
else
{
page_offset = ((index - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record];
in_page_offset = ((index - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE;
}
LOG_D ("page_offset = %d", page_offset);
LOG_D ("in_page_offset = %d", in_page_offset);
uint32_t addr = (hr_start_addr[record] + FLASH_PAGE_SIZE * page_offset + in_page_offset);
LOG_D ("addr = %04X", addr);
Flash_Read (addr, pHrRecord->buf, HR_RECORD_FRAME_LEN);
LOG_D ("Flash_Read_(%d)Record(%d):%04d-%02d-%02d,%02d:%02d", record,
index, pHrRecord->Struct.year, pHrRecord->Struct.month,
pHrRecord->Struct.day, pHrRecord->Struct.hour,
pHrRecord->Struct.minute);
}
else
{
rt_memset (pHrRecord->buf, 0, HR_RECORD_FRAME_LEN);
LOG_E ("Flash_GetMaxNum_(%d)Records Error!: (index_max)%d < %d", record,
index_max, index);
}
}
/**
* @description:
* @param {TuFlashHrRecordFrame*} pHrRecord
* @param {uint16_t} index
* @return {*}
*/
void Flash_Write_RecordIndex (TuFlashHrRecordFrame *pHrRecord, TeRecord record,
rt_uint16_t index)
{
LOG_D ("/*********Flash_Write_RecordIndex***************/");
rt_uint8_t page_offset = ((index - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record];
LOG_D ("page_offset = %d", page_offset);
rt_uint8_t in_page_offset = ((index - 1) % FLASH_PAGE_HR_RECORD_NUM) * FLASH_HR_ONE_RECORD_SIZE;
LOG_D ("in_page_offset = %d", in_page_offset);
rt_uint32_t addr = (hr_start_addr[record] + FLASH_PAGE_SIZE * page_offset + in_page_offset);
LOG_D ("addr = %04X", addr);
Flash_Write (addr, pHrRecord->buf, HR_RECORD_FRAME_LEN);
TuFlashHrRecordFrame pReadRecord;
Flash_Read (addr, pReadRecord.buf, HR_RECORD_FRAME_LEN);
LOG_D ("(%04X)Flash_Write_(%d)RecordIndex(%d):%04d-%02d-%02d,%02d:%02d",
pReadRecord.Struct.header, record, pReadRecord.Struct.index,
pReadRecord.Struct.year, pReadRecord.Struct.month,
pReadRecord.Struct.day, pReadRecord.Struct.hour,
pReadRecord.Struct.minute);
}
void Flash_Write_Record (TeRecord record)
{
LOG_D ("/*********Flash_Write_Record***************/");
rt_uint16_t index_max = Flash_GetMaxIndex_Records (record);
rt_uint16_t index_new = index_max + 1;
LOG_D ("index_new = %d", index_new);
rt_uint16_t index_start;
rt_uint8_t index_start_page_offset;
rt_uint8_t index_max_page_offset;
rt_uint8_t index_max_in_page_offset;
if (index_max <= hr_record_max_num[record])
{
index_start = 0;
index_start_page_offset = 0;
index_max_page_offset = ((index_max - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record];
LOG_D ("index_max_page_offset = %d", index_max_page_offset);
}
else
{
index_start = index_max - (hr_record_max_num[record] - 1);
LOG_D ("index_start = %d", index_start);
index_start_page_offset = ((index_start - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record];
LOG_D ("index_start_page_offset = %d", index_start_page_offset);
index_max_page_offset = ((index_max - 1) / FLASH_PAGE_HR_RECORD_NUM) % hr_record_pages[record];
}
index_max_in_page_offset = (index_max - 1) % FLASH_PAGE_HR_RECORD_NUM;
LOG_D ("index_max_in_page_offset = %d", index_max_in_page_offset);
if ((index_max_in_page_offset + 1) == (FLASH_PAGE_HR_RECORD_NUM - 1) && index_max_page_offset == (hr_record_pages[record] - 1))
{
Flash_ErasePage_Records (record, 0);
}
else if ((index_max_in_page_offset + 1) == (FLASH_PAGE_HR_RECORD_NUM - 1) && index_max_page_offset == index_start_page_offset - 1)
{
Flash_ErasePage_Records (record, index_max_page_offset + 1);
}
RTC_GetTime();
TuFlashHrRecordFrame HrRecord;
HrRecord.Struct.header = HR_RECORD_FRAME_HEADER;
HrRecord.Struct.index = index_new;
HrRecord.Struct.year = RtcDateTime.year;
HrRecord.Struct.month = RtcDateTime.month;
HrRecord.Struct.day = RtcDateTime.day;
HrRecord.Struct.hour = RtcDateTime.hour;
HrRecord.Struct.minute = RtcDateTime.minute;
Flash_Write_RecordIndex (&HrRecord, record, index_new);
}
void Flash_ErasePage_ConfigInfo (void)
{
BSP_Flash_FastUnLock();
FLASH_ErasePage_Fast (FLASH_CONFIG_INFO_START_ADDR);
BSP_Flash_FastLock();
}
void Flash_ErasePage_ReadConfigInfo (rt_uint8_t *page_buf)
{
Flash_Read (FLASH_CONFIG_INFO_START_ADDR, page_buf, FLASH_PAGE_SIZE);
rt_thread_mdelay (10);
Flash_ErasePage_ConfigInfo();
rt_thread_mdelay (10);
}
int Flash_Write_ConfigInfo (rt_uint8_t *page_buf)
{
return Flash_Write (FLASH_CONFIG_INFO_START_ADDR, page_buf, FLASH_PAGE_SIZE);
}
ErrorStatus Flash_GetProductTimeLimit (TuFlashProductTimeLimitFrame *pLimitTime,
TeFlashProductTimeLimitId id)
{
ErrorStatus flag = NoREADY;
rt_uint32_t addr = 0;
if (id == kFactoryTimeId)
{
addr = FLASH_FACTORY_TIME_START_ADDR;
}
else if (id == kExpirationTimeId)
{
addr = FLASH_EXPIRATION_TIME_START_ADDR;
}
if (addr != 0)
{
Flash_Read (addr, pLimitTime->buf, sizeof (TuFlashProductTimeLimitFrame));
if (pLimitTime->Struct.header == FLASH_PRODUCT_TIME_FRAME_HEADER)
{
flag = READY;
LOG_D ("Flash_GetProductTimeLimit(%d):%04d-%02d-%02d,%02d:%02d:%02d",
id, pLimitTime->Struct.year, pLimitTime->Struct.month,
pLimitTime->Struct.day, pLimitTime->Struct.hour,
pLimitTime->Struct.minute, pLimitTime->Struct.second);
}
else
{
LOG_E ("Flash_GetProductTimeLimit Error!");
}
}
return flag;
}
void Flash_SetProductTimeLimit (rt_uint16_t year, rt_uint8_t mon, rt_uint8_t day,
rt_uint8_t hour, rt_uint8_t min, rt_uint8_t second,
TeFlashProductTimeLimitId id)
{
TuFlashProductTimeLimitFrame LimitTime;
rt_uint8_t page_buf[FLASH_PAGE_SIZE];
Flash_ErasePage_ReadConfigInfo (page_buf);
LimitTime.Struct.header = FLASH_PRODUCT_TIME_FRAME_HEADER;
LimitTime.Struct.year = year;
LimitTime.Struct.month = mon;
LimitTime.Struct.day = day;
LimitTime.Struct.hour = hour;
LimitTime.Struct.minute = min;
LimitTime.Struct.second = second;
rt_uint8_t in_page_offset = 0;
if (id == kFactoryTimeId)
{
in_page_offset = (FLASH_FACTORY_TIME_START_ADDR - FLASH_CONFIG_INFO_START_ADDR);
}
else if (id == kExpirationTimeId)
{
in_page_offset = (FLASH_EXPIRATION_TIME_START_ADDR - FLASH_CONFIG_INFO_START_ADDR);
}
for (rt_uint8_t i = 0; i < sizeof (TuFlashProductTimeLimitFrame); i++)
{
page_buf[in_page_offset + i] = LimitTime.buf[i];
}
Flash_Write_ConfigInfo (page_buf);
}
void Set_ExpirationTime (rt_uint16_t days)
{
uint32_t factory_seconds, expiration_seconds;
TuFlashProductTimeLimitFrame LimitTime;
if (Flash_GetProductTimeLimit (&LimitTime, kFactoryTimeId) == READY)
{
factory_seconds = DateTime2Seconds (LimitTime.Struct.year,
LimitTime.Struct.month, LimitTime.Struct.day,
LimitTime.Struct.hour, LimitTime.Struct.minute,
LimitTime.Struct.second);
expiration_seconds = factory_seconds + days * 24 * 3600;
TsRtcDateTime DateTime;
Seconds2DateTime (expiration_seconds, &DateTime);
Flash_SetProductTimeLimit (DateTime.year, DateTime.month, DateTime.day,
DateTime.hour, DateTime.minute, DateTime.second,
kExpirationTimeId);
}
}
rt_uint8_t Flash_Sys_Cfg (TeFlashCfgInfoId id, rt_uint8_t *buf, rt_size_t len)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
Flash_ErasePage_ReadConfigInfo (page_buf);
rt_uint8_t in_page_offset = (hr_sys_cfg_info_addr[id] - FLASH_CONFIG_INFO_START_ADDR);
if (len > hr_sys_cfg_info_len[id])
{
LOG_E ("Flash_Sys_Cfg: id value too long ->%d", id);
LOG_D ("buf len %d > id len[%d]", len, hr_sys_cfg_info_len[id]);
return -RT_ERROR;
}
for (rt_uint8_t i = 0; i < hr_sys_cfg_info_len[id]; i++)
{
page_buf[in_page_offset + i] = buf[i];
}
return Flash_Write_ConfigInfo (page_buf);
}
/*这个返回一两个字节的数,方便提取*/
size_t Flash_Get_SysCfg (TeFlashCfgInfoId id)
{
rt_uint8_t iot_upload_cycle[2] = {0};
rt_uint16_t iot_upload;
if (id != kIotUploadCycleId)
{
return *(rt_uint8_t *)hr_sys_cfg_info_addr[id];
}
else
{
rt_memcpy (&iot_upload_cycle[0], (rt_uint8_t *)hr_sys_cfg_info_addr[id], 2);
iot_upload = ((iot_upload_cycle[0] << 8) + iot_upload_cycle[1]);
LOG_D ("iot_upload: %d", iot_upload);
return iot_upload;
}
}
ErrorStatus Flash_GetTotalRecord (TsTotalRecords *pTotalRecords)
{
ErrorStatus flag = NoREADY;
pTotalRecords->alarm = Flash_GetNum_Records (kRecordAlarm);
pTotalRecords->alarm_rcy = Flash_GetNum_Records (kRecordAlarmRcy);
pTotalRecords->fault = Flash_GetNum_Records (kRecordFault);
pTotalRecords->fault_rcy = Flash_GetNum_Records (kRecordFaultRcy);
pTotalRecords->power_failure = Flash_GetNum_Records (kRecordPowerDown);
pTotalRecords->power_on = Flash_GetNum_Records (kRecordPowerOn);
pTotalRecords->sensor_failure = Flash_GetNum_Records (kRecordSensoEndOfLife);
flag = READY;
return flag;
}
ErrorStatus Flash_GetRecord (TeFrameC2 record_type, rt_uint8_t index,
TsRecordsTime *pRecordsTime)
{
ErrorStatus flag = NoREADY;
if (kNumOfRecords < record_type && record_type < kGetCurrentTime)
{
TuFlashHrRecordFrame pHrReadRecord;
Flash_Read_Record (&pHrReadRecord, record_type - 1, index);
LOG_D ("(%d)Flash_GetRecord(%d):%04d-%02d-%02d,%02d:%02d",
record_type - 1, pHrReadRecord.Struct.index,
pHrReadRecord.Struct.year, pHrReadRecord.Struct.month,
pHrReadRecord.Struct.day, pHrReadRecord.Struct.hour,
pHrReadRecord.Struct.minute);
pRecordsTime->year_h = pHrReadRecord.Struct.year / 256;
pRecordsTime->year_l = pHrReadRecord.Struct.year % 256;
pRecordsTime->month = pHrReadRecord.Struct.month;
pRecordsTime->day = pHrReadRecord.Struct.day;
pRecordsTime->hour = pHrReadRecord.Struct.hour;
pRecordsTime->minute = pHrReadRecord.Struct.minute;
flag = READY;
}
return flag;
}
/**
* @description:
* @return {*}
*/
void BSP_Flash_EraseRecodrs (void)
{
for (rt_uint8_t record = 0; record <= kRecordSensoEndOfLife; record++)
{
for (rt_uint8_t i = 0; i < hr_record_pages[record]; i++)
{
Flash_ErasePage_Records (record, i);
}
}
Flash_ErasePage_ConfigInfo();
}
int BSP_Flash_Init (void)
{
rt_uint16_t flag_value = *(rt_uint16_t *)FLASH_INIT_FLAG_ADDR;
rt_thread_mdelay(10);
if (flag_value != FLASH_FIRST_INIT_VALUE)
{
LOG_D ("BSP_Flash_EraseRecodrs!");
rt_uint8_t flash_init_flag[2];
sys_config_info sci;
rt_uint8_t sever_data[6] = {0};
flash_init_flag[0] = FLASH_FIRST_INIT_VALUE % 256;
flash_init_flag[1] = FLASH_FIRST_INIT_VALUE / 256;
BSP_Flash_EraseRecodrs();
Flash_Write (FLASH_INIT_FLAG_ADDR, flash_init_flag,
sizeof (flash_init_flag));
Flash_Set_WorkDuration (work_duration);
LOG_D ("work_duration:%d", Flash_Get_WorkDuration());
Convert_To_Hex (&sever_info, sever_data);
if (Flash_Set_Sever_Data (sever_data) <= 0)
{
LOG_D ("Flash_Set_Sever_Data error!");
}
Flash_SetProductTimeLimit (2025, 1, 19, 13, 50, 20, kFactoryTimeId);
Set_ExpirationTime (MAX_EXPIRATION_DAYS);
sci.hw_ver = SYS_HW_VERSION;
sci.sw_ver = SYS_SW_VERSION;
sci.alarm_l_value = SYS_ALARM_VALVE;
sci.alarm_h_value = SYS_ALARM_VALVE_MAX;
sci.iot_upload_cycle = SYS_IOT_UPLOAD_CYCLE_MIN;
sci.iot_retry = SYS_IOT_RETRY;
sci.temp_alarm_threshold = SYS_TEMP_ALARM_THRESHOLD;
sci.emagnetic_switch = SYS_EMV_SWITCH;
sci.relay_switch = SYS_RELAY_SWITCH;
Flash_Write (FLASH_HW_VER_ADDR, (rt_uint8_t *)&sci,
(sizeof (sys_config_info) - 50));
}
return 0;
}
#ifdef RT_USING_COMPONENTS_INIT
INIT_PREV_EXPORT (BSP_Flash_Init);
#endif
#ifdef TEST_ENABLE
void TEST_Flash_GetMaxIndex_Records (int argc, char **argv)
{
if (argc == 2)
{
rt_uint8_t record = atoi (argv[1]);
LOG_D ("Flash_GetMaxIndex_Records(%d) = %d", record,
Flash_GetMaxIndex_Records (record));
}
else
{
LOG_E ("TEST_Flash_GetMaxIndex_Records --use _cmd_ [record](0~6)");
}
}
MSH_CMD_EXPORT (TEST_Flash_GetMaxIndex_Records,
"TEST_Flash_GetMaxIndex_Records");
static void TEST_Flash_Erase_Records (int argc, char **argv)
{
if (argc == 2)
{
int record = atoi (argv[1]);
Flash_Erase_Records (record);
}
else
{
LOG_E ("TEST_Flash_Erase_Records --use _cmd_ [record](0~6)");
}
}
MSH_CMD_EXPORT (TEST_Flash_Erase_Records, "TEST_Flash_Erase_Records");
static void TEST_Flash_Write_Record (int argc, char **argv)
{
if (argc == 3)
{
int record = atoi (argv[1]);
int num = atoi (argv[2]);
for (rt_uint8_t i = 0; i < num; i++)
{
Flash_Write_Record (record);
rt_thread_mdelay (2);
// BSP_WDG_Loop();
}
}
else
{
LOG_E ("TEST_Flash_Write_Record --use _cmd_ [record(0~6)] [num]");
}
}
MSH_CMD_EXPORT (TEST_Flash_Write_Record, "TEST_Flash_Write_Record");
static void TEST_Flash_GetNum_Records (int argc, char **argv)
{
if (argc == 2)
{
int record = atoi (argv[1]);
if (0 <= record && record <= 6)
{
LOG_D ("TEST_Flash_GetNum_Records(%d) = %d", record,
Flash_GetNum_Records (record));
}
else
{
LOG_E ("TEST_Flash_GetNum_Records --use _cmd_ [record](0~6)");
}
}
else
{
LOG_E ("TEST_Flash_GetNum_Records --use _cmd_ [record](0~6)");
}
}
MSH_CMD_EXPORT (TEST_Flash_GetNum_Records, "TEST_Flash_GetNum_Records");
static void TEST_Flash_GetProductTimeLimit (int argc, char **argv)
{
if (argc == 2)
{
int id = atoi (argv[1]);
TuFlashProductTimeLimitFrame LimitTime;
Flash_GetProductTimeLimit (&LimitTime, id);
}
else
{
LOG_E (
"TEST_Flash_GetProductTimeLimit --use _cmd_ [id(0:FACTORY; 1:EXPIRATION)]");
}
}
MSH_CMD_EXPORT (TEST_Flash_GetProductTimeLimit,
"TEST_Flash_GetProductTimeLimit");
static void TEST_Flash_SetProductTimeLimit (int argc, char **argv)
{
if (argc == 8)
{
int year = atoi (argv[1]);
int mon = atoi (argv[2]);
int day = atoi (argv[3]);
int hour = atoi (argv[4]);
int min = atoi (argv[5]);
int second = atoi (argv[6]);
int id = atoi (argv[7]);
Flash_SetProductTimeLimit (year, mon, day, hour, min, second, id);
}
else
{
LOG_E (
"TEST_Flash_SetProductTimeLimit --use _cmd_ [y] [m] [d] [h] [m] [s] [id(0:FACTORY; 1:EXPIRATION)]");
}
}
MSH_CMD_EXPORT (TEST_Flash_SetProductTimeLimit,
"TEST_Flash_SetProductTimeLimit");
void Set_FactoryRtcTime (void)
{
RTC_GetTime();
LOG_D ("%4d-%02d-%02d, %02d:%02d:%02d", RtcDateTime.year, RtcDateTime.month,
RtcDateTime.day, RtcDateTime.hour, RtcDateTime.minute,
RtcDateTime.second);
Flash_SetProductTimeLimit (RtcDateTime.year, RtcDateTime.month,
RtcDateTime.day, RtcDateTime.hour, RtcDateTime.minute,
RtcDateTime.second, kFactoryTimeId);
}
MSH_CMD_EXPORT (Set_FactoryRtcTime, "Use RTC time Set_FactoryRtcTime");
static void TEST_Flash_Set_ExpirationTime (int argc, char **argv)
{
if (argc == 2)
{
int days = atoi (argv[1]);
Set_ExpirationTime (days);
}
else
{
LOG_E ("TEST_Flash_Set_ExpirationTime --use _cmd_ [days]");
}
}
MSH_CMD_EXPORT (TEST_Flash_Set_ExpirationTime, "TEST_Flash_Set_ExpirationTime");
static void TEST_Flash_Get_Sys_Info (int argc, char **argv)
{
if (argc == 2)
{
int id = atoi (argv[1]);
Flash_Get_SysCfg (id);
}
else
{
LOG_E ("TEST_Flash_Get_Sys_Info ");
}
}
MSH_CMD_EXPORT (TEST_Flash_Get_Sys_Info, "TEST_Flash_Get_Sys_Info");
#endif