BLE_TYQ_BJQ_CH32V303/bsp/src/bsp_flash.c

1089 lines
33 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_hr.h"
#include "at_device_ml307.h"
#include <rtthread.h>
#include <rthw.h>
#include "rtdef.h"
#define LOG_TAG "bsp_flash"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
#include <stdlib.h>
// 在此修改默认的服务器地址
flash_sever_info sever_info =
{
.server_url = "8.130.122.162",
.server_port = "7153",
};
/*默认的系统配置*/
rt_uint8_t sys_hw_ver = 0x10;
rt_uint8_t sys_sw_ver = 0x11;
rt_uint8_t sys_iot_retry = 0x03; // 重试次数3次
rt_uint16_t sys_iot_upload_cycle = 0x003C; // 120分钟一次
rt_uint16_t sys_alarm_h_value = 0x09C4; // 2500
rt_uint16_t sys_alarm_l_value = 0x0640; // 1600
rt_uint8_t sys_temp_alarm_threshold = 0x32;
rt_uint8_t sys_emagnetic_switch = 0x04; // 具备阀门功能
rt_uint8_t sys_relay_switch = 0x04; // 具备继电器功能
extern int Convert_To_Hex(const flash_sever_info *sever_info, uint8_t *hex_array);
#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;
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_Iot_Imei(char *buf, rt_size_t len)
{
if ((*(rt_uint8_t *)FLASH_IOT_IMEI_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_IMEI_ADDR != 0x39))
{
rt_memcpy(buf, (char *)FLASH_IOT_IMEI_ADDR, len);
LOG_D("NB IMEI: %s", buf);
return 0;
}
else
{
/*如果没有写进去则全部是0*/
for (rt_uint8_t i = 0; i < len; i++)
{
buf[i] = '0';
}
LOG_D("NB IMSI: %s", buf);
return -1;
}
}
int Get_Iot_Imsi(char *buf, rt_size_t len)
{
if ((*(rt_uint8_t *)FLASH_IOT_IMSI_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_IMSI_ADDR != 0x39))
{
rt_memcpy(buf, (char *)FLASH_IOT_IMSI_ADDR, len);
LOG_D("NB IMSI: %s", buf);
return 0;
}
else
{
/*如果没有写进去则全部是0*/
for (rt_uint8_t i = 0; i < len; i++)
{
buf[i] = '0';
}
LOG_D("NB IMSI: %s", buf);
return -1;
}
}
int Get_Iot_Iccid(char *buf, rt_size_t len)
{
if ((*(rt_uint8_t *)FLASH_IOT_ICCID_ADDR != 0xE3) && (*(rt_uint8_t *)FLASH_IOT_ICCID_ADDR != 0x39))
{
rt_memcpy(buf, (char *)FLASH_IOT_ICCID_ADDR, len);
LOG_D("NB ICCID: %s", buf);
return 0;
}
else
{
/*如果没有写进去则全部是0*/
for (rt_uint8_t i = 0; i < len; i++)
{
buf[i] = '0';
}
LOG_D("NB 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_uint16_t *)(page_buf + in_page_offset) = value;
return Flash_Write_ConfigInfo(page_buf);
}
int Flash_Get_Sever_Addr_Info(flash_sever_info *sever_info)
{
rt_uint8_t data[FLASH_SERVER_LEN];
rt_memcpy(data, (rt_uint8_t *)FLASH_SERVER_ADDR_ADDR, FLASH_SERVER_LEN);
if (data == RT_NULL)
{
LOG_E("Flash_Get_Sever_Addr_Info failed");
return -RT_ERROR;
}
LOG_D("FLASH_SERVER_ADDR_ADDR = %X", FLASH_SERVER_ADDR_ADDR);
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_Addr_Info(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;
}
LOG_D("Flash_Set_Sever_Addr_Info in_page_offset = %d", in_page_offset);
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);
}
TeCalibrationStatus Flash_Get_Calibration_State(void)
{
return *(rt_uint8_t *)FLASH_CALIBRATION_STATUS_ADDR;
}
int Flash_Set_Calibration_State(TeCalibrationStatus status)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
rt_uint8_t in_page_offset = (FLASH_CALIBRATION_STATUS_ADDR - FLASH_CONFIG_INFO_START_ADDR);
LOG_D("FLASH_CALIBRATION_STATUS_ADDR = %X", FLASH_CALIBRATION_STATUS_ADDR);
Flash_ErasePage_ReadConfigInfo(page_buf);
//*将传入的数据写到flash地址中
page_buf[in_page_offset] = status;
return Flash_Write_ConfigInfo(page_buf);
}
/*写入MAC地址 number :1-8
*/
int Flash_Set_Mac_Addr(rt_uint8_t *mac_addr, rt_uint8_t number)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
rt_uint8_t in_page_offset = ((FLASH_VALVE_1_MAC_ADDR_ADDR + (number - 1) * FLASH_VALVE_MAC_ADDR_LEN) - FLASH_CONFIG_INFO_START_ADDR);
LOG_D("FLASH_VALVE_1_MAC_ADDR_ADDR = %X", FLASH_VALVE_1_MAC_ADDR_ADDR);
LOG_D("FLASH_VALVE_MAC_ADDR_LEN = %d", in_page_offset);
if (mac_addr == RT_NULL)
{
return -RT_ERROR;
}
Flash_ErasePage_ReadConfigInfo(page_buf);
for (size_t i = 0; i < FLASH_VALVE_MAC_ADDR_LEN; i++)
{
page_buf[in_page_offset++] = mac_addr[i];
}
return Flash_Write_ConfigInfo(page_buf);
}
/*读取MAC地址 number :1-8*/
int Flash_Get_Mac_Addr(rt_uint8_t *mac_addr, rt_uint8_t number)
{
if (*(rt_uint16_t *)(FLASH_VALVE_1_MAC_ADDR_ADDR + (number - 1) * FLASH_VALVE_MAC_ADDR_LEN) == 0xe339)
{
LOG_D("无阀门数据");
return -1;
}
rt_uint8_t data[FLASH_VALVE_MAC_ADDR_LEN];
char mac[16] = {20};
rt_memcpy(data, (rt_uint8_t *)(FLASH_VALVE_1_MAC_ADDR_ADDR + (number - 1) * FLASH_VALVE_MAC_ADDR_LEN), FLASH_VALVE_MAC_ADDR_LEN);
rt_snprintf(mac, 20, "%02x:%02x:%02x:%02x:%02x:%02x",
data[5], data[4], data[3], data[2], data[1], data[0]);
LOG_I("mac_addr:%s", mac);
rt_memcpy(mac_addr, data, FLASH_VALVE_MAC_ADDR_LEN);
return RT_EOK;
}
/*设置无线调压器数量*/
int Flash_Set_Valve_Num(rt_uint8_t valve_num)
{
rt_uint8_t page_buf[FLASH_PAGE_SIZE] = {0};
rt_uint8_t in_page_offset = (FLASH_VALVE_NUM_ADDR - FLASH_CONFIG_INFO_START_ADDR);
Flash_ErasePage_ReadConfigInfo(page_buf);
page_buf[in_page_offset] = valve_num;
return Flash_Write_ConfigInfo(page_buf);
}
/*获取无线调压器数量*/
rt_uint8_t Flash_Get_Valve_Num(void)
{
return *(rt_uint8_t *)FLASH_VALVE_NUM_ADDR;
}
/**
* @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);
Flash_ErasePage_ConfigInfo();
}
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);
TuFlashProductTimeLimitFrame ReadLimitTime;
Flash_GetProductTimeLimit(&ReadLimitTime, id);
}
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);
LOG_D("FactoryTime:%04d-%02d-%02d,%02d:%02d", 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;
// LOG_D("factory_seconds = %d, expiration_seconds = %d", factory_seconds, expiration_seconds);
TsRtcDateTime DateTime;
Seconds2DateTime(expiration_seconds, &DateTime);
Flash_SetProductTimeLimit(DateTime.year, DateTime.month, DateTime.day,
DateTime.hour, DateTime.minute, DateTime.second,
kExpirationTimeId);
if (Flash_GetProductTimeLimit(&LimitTime, kExpirationTimeId) == READY)
{
LOG_D("Flash_GetProductTimeLimit:%04d-%02d-%02d,%02d:%02d:%02d",
LimitTime.Struct.year, LimitTime.Struct.month,
LimitTime.Struct.day, LimitTime.Struct.hour,
LimitTime.Struct.minute, LimitTime.Struct.second);
}
}
}
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)
{
size_t value = 0;
if (hr_sys_cfg_info_len[id] == 1)
{
return *(rt_uint8_t *)hr_sys_cfg_info_addr[id];
}
else if (hr_sys_cfg_info_len[id] == 2)
{
rt_uint8_t buf[2] = {0};
rt_memcpy(&buf, (rt_uint8_t *)hr_sys_cfg_info_addr[id], hr_sys_cfg_info_len[id]);
value = buf[0] | (buf[1] << 8);
// LOG_D("buf[0]= %u, buf[1]: %u", buf[0], buf[1]);
}
LOG_D("value: %u", value);
return value;
}
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);
}
// LOG_D("/**BSP_Flash_First_Init (%d)**/", record);
}
Flash_ErasePage_ConfigInfo();
}
int BSP_Flash_Init(void)
{
if (*(rt_uint16_t *)FLASH_INIT_FLAG_ADDR != 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_SetProductTimeLimit(2025, 1, 6, 11, 20, 50, kFactoryTimeId);
Set_ExpirationTime(MAX_EXPIRATION_DAYS);
sci.hw_ver = sys_hw_ver;
sci.sw_ver = sys_sw_ver;
sci.alarm_l_value = sys_alarm_l_value;
sci.alarm_h_value = sys_alarm_h_value;
sci.iot_upload_cycle = sys_iot_upload_cycle;
sci.iot_retry = sys_iot_retry;
sci.temp_alarm_threshold = sys_temp_alarm_threshold;
sci.emagnetic_switch = sys_emagnetic_switch;
sci.relay_switch = sys_relay_switch;
Flash_Set_WorkDuration(work_duration);
LOG_D("work_duration:%d", Flash_Get_WorkDuration());
Convert_To_Hex(&sever_info, sever_data);
for (size_t i = 0; i < sizeof(sever_data); i++)
{
LOG_D("%02x", sever_data[i]);
}
if (Flash_Set_Sever_Addr_Info(sever_data) <= 0)
{
LOG_D("Flash_Set_Sever_Addr_Info error!");
}
Flash_Set_Calibration_State(kSysGasCalibStatus); // 未标定状态
Flash_Set_Valve_Num(0);
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
static 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