BLE_TYQ_BJQ_CH32V303/bsp/src/bsp_flash.c

1048 lines
31 KiB
C
Raw Normal View History

2024-12-01 13:49:43 +08:00
#include "bsp_flash.h"
#include "lwutil.h"
#include "bsp_rtc.h"
#include "bsp_hr.h"
2024-12-03 10:24:55 +08:00
#include "at_device_ml307.h"
2024-12-01 13:49:43 +08:00
#include <rtthread.h>
#include <rthw.h>
#define LOG_TAG "bsp_flash"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
#include <stdlib.h>
2024-12-01 15:31:07 +08:00
extern int Convert_To_Hex(const struct flash_sever_info *sever_info, uint8_t *hex_array);
2024-12-01 13:49:43 +08:00
#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) \
2024-12-03 10:24:55 +08:00
: (id) == kIotUploadCycleId ? (&(info)->nb_upload_cycle) \
: (id) == kIotRetryId ? (&(info)->nb_retry) \
2024-12-01 13:49:43 +08:00
: (id) == kEmagneticSwitchId ? (&(info)->emagnetic_switch) \
: (id) == kRelaySwitchId ? (&(info)->relay_switch) \
2024-12-03 10:24:55 +08:00
: (id) == kIotImeiId ? ((info)->nb_imei) \
: (id) == kIotImsiId ? ((info)->nb_imsi) \
: (id) == kIotIccidId ? ((info)->nb_iccid) \
2024-12-01 13:49:43 +08:00
: 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_NB_UPLOAD_CYCLE_ADDR,
FLASH_NB_RETRY_ADDR,
FLASH_TEMP_ALARM_THRESHOLD_ADDR,
FLASH_EMAGNETIC_SWITCH_ADDR,
FLASH_RELAY_SWITCH_ADDR,
FLASH_NB_IMEI_ADDR,
FLASH_NB_IMSI_ADDR,
FLASH_NB_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_NB_UPLOAD_CYCLE_LEN,
FLASH_NB_RETRY_LEN,
FLASH_TEMP_ALARM_THRESHOLD_LEN,
FLASH_EMAGNETIC_SWITCH_LEN,
FLASH_RELAY_SWITCH_LEN,
FLASH_NB_IMEI_LEN,
FLASH_NB_IMSI_LEN,
FLASH_NB_ICCID_LEN,
};
static rt_base_t interrupt_value;
/*默认的系统配置*/
rt_uint8_t sys_hw_ver = 0x10;
rt_uint8_t sys_sw_ver = 0x11;
rt_uint8_t sys_nb_retry = 0x03; // 重试次数3次
2024-12-03 10:24:55 +08:00
rt_uint16_t sys_nb_upload_cycle = 0x0078; // 120分钟一次
2024-12-01 13:49:43 +08:00
rt_uint16_t sys_alarm_h_value = 0x0032; // 50
2024-12-01 15:31:07 +08:00
rt_uint16_t sys_alarm_l_value = 0x09C4; // 10
2024-12-01 13:49:43 +08:00
rt_uint8_t sys_temp_alarm_threshold = 0x32;
rt_uint8_t sys_emagnetic_switch = 0x04; // 具备阀门功能
rt_uint8_t sys_relay_switch = 0x04; // 具备继电器功能
2024-12-01 15:31:07 +08:00
struct flash_sever_info sever_info =
2024-12-01 13:49:43 +08:00
{
2024-12-03 10:24:55 +08:00
// .server_url = "47.94.169.135",
// .server_port = "7150",
.server_port = "34215",
.server_url = "8.135.10.183",
2024-12-01 13:49:43 +08:00
};
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;
}
2024-12-03 10:24:55 +08:00
int Get_Iot_Imei(char *buf, rt_size_t len)
2024-12-01 13:49:43 +08:00
{
if ((*(rt_uint8_t *)FLASH_NB_IMEI_ADDR != 0xE3)&&(*(rt_uint8_t *)FLASH_NB_IMEI_ADDR != 0x39))
{
rt_memcpy(buf, (char *)FLASH_NB_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;
}
}
2024-12-03 10:24:55 +08:00
int Get_Iot_Imsi(char *buf, rt_size_t len)
2024-12-01 13:49:43 +08:00
{
if ((*(rt_uint8_t *)FLASH_NB_IMSI_ADDR != 0xE3)&&(*(rt_uint8_t *)FLASH_NB_IMSI_ADDR != 0x39))
{
rt_memcpy(buf, (char *)FLASH_NB_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;
}
}
2024-12-03 10:24:55 +08:00
int Get_Iot_Iccid(char *buf, rt_size_t len)
2024-12-01 13:49:43 +08:00
{
if ((*(rt_uint8_t *)FLASH_NB_ICCID_ADDR != 0xE3)&&(*(rt_uint8_t *)FLASH_NB_ICCID_ADDR != 0x39))
{
rt_memcpy(buf, (char *)FLASH_NB_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);
}
2024-12-03 10:24:55 +08:00
int Flash_Get_Sever_Addr_Info(struct flash_sever_info *sever_info)
2024-12-01 13:49:43 +08:00
{
rt_uint8_t data[FLASH_SERVER_LEN];
rt_memcpy(data, (rt_uint8_t *)FLASH_SERVER_ADDR_ADDR, FLASH_SERVER_LEN);
if (data == RT_NULL)
{
2024-12-03 10:24:55 +08:00
LOG_E("Flash_Get_Sever_Addr_Info failed");
2024-12-01 13:49:43 +08:00
return -RT_ERROR;
}
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);
2024-12-03 10:24:55 +08:00
// LOG_D("server_url:%s, server_port:%s", sever_info->server_url, sever_info->server_port);
2024-12-01 13:49:43 +08:00
return 0;
}
2024-12-03 10:24:55 +08:00
int Flash_Set_Sever_Addr_Info(rt_uint8_t *data)
2024-12-01 13:49:43 +08:00
{
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);
}
2024-12-01 15:31:07 +08:00
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);
Flash_ErasePage_ReadConfigInfo(page_buf);
//*将传入的数据写到flash地址中
page_buf[in_page_offset] = status;
return Flash_Write_ConfigInfo(page_buf);
}
2024-12-01 13:49:43 +08:00
/**
* @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;
2024-12-01 15:31:07 +08:00
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]);
}
2024-12-01 13:49:43 +08:00
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(2024, 9, 8, 13, 58, 20, kFactoryTimeId);
Flash_SetProductTimeLimit(2024 + 8, 9, 8, 13, 58, 20, kExpirationTimeId);
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.nb_upload_cycle = sys_nb_upload_cycle;
sci.nb_retry = sys_nb_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]);
}
2024-12-03 10:24:55 +08:00
if(Flash_Set_Sever_Addr_Info(sever_data) <= 0)
2024-12-01 13:49:43 +08:00
{
2024-12-03 10:24:55 +08:00
LOG_D("Flash_Set_Sever_Addr_Info error!");
2024-12-01 13:49:43 +08:00
}
2024-12-01 15:31:07 +08:00
Flash_Set_Calibration_State(kNotCalibrated);//未标定状态
2024-12-01 13:49:43 +08:00
Flash_Write(FLASH_HW_VER_ADDR, (rt_uint8_t *)&sci,
(sizeof(sys_config_info) - 50));
}
return 0;
}
#ifdef RT_USING_COMPONENTS_INIT
INIT_BOARD_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