| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624 |
- #include <string.h>
- #include "eeprom.h"
- #include "prj_com.h"
- #include "bill.h"
- #include "tdc_tof.h"
- #include "param.h"
- #include "app_nb.h"
- #include "alarm.h"
- Param_t Paramx;
- uint8_t rewrite_para_flag = 0;
- // DIAMETER_AND_TEMP_COMPENSATION_DEF Temp_compensation;//其中的diameter保存的校验值
- const char SOFT_VER[5] = {
- 'V', VER_TYPE, VER_OPERATOR, VER_MODULE, VER_FIRMWARE};
- // EEPROM_MAX_WRITE_SIZE 125
- // EEPROM_PAGE_SIZE 256
- /****************************************************************/
- ////由于_read_eeprom write_eeprom是针对存bill记录的,最后一个字节
- /// 自动校验,写参数不能用,这里需另外增加/////////
- /*********************批量写入数据********************************/
- // 参数1:dat 指向要写入的数据指针
- // 参数2:addr写入到M24M01存储器的地址
- // 参数3:len写入数据的长度(字节单位)
- // 返回:1:成功
- ////////////////////////////////////////////////////////////////
- uint8_t eeprom_MassWrite(uint8_t *dat, uint32_t addr, uint16_t len) //
- {
- if (addr > EEPROM_MAX_SIZE - 1 || addr + len > EEPROM_MAX_SIZE)
- return 1;
- // 已经跨页
- // uint8_t num=(uint8_t)(EEPROM_PAGE_SIZE/EEPROM_MAX_WRITE_SIZE+1);//每页需写入的次数
- // LOG("len= %d",len);
- uint32_t add_end = addr + len; // 地址末尾
- uint16_t w_size; // 写入数据大小
- uint8_t ret = 0;
- while (addr < add_end)
- {
- if (addr / EEPROM_PAGE_SIZE == (addr + EEPROM_MAX_WRITE_SIZE - 1) / EEPROM_PAGE_SIZE)
- { // 还在本页内
- w_size = EEPROM_MAX_WRITE_SIZE; // 取写入长度为最大长度
- }
- else
- { // 最大写入长度已经超过本页
- w_size = EEPROM_PAGE_SIZE - (addr % EEPROM_PAGE_SIZE); // 取写入长度刚好到页边界
- }
- if (addr + w_size > add_end)
- { // 写入长度已超出实际写入边界
- w_size = add_end - addr; // 取实际写入长度
- }
- ret |= write_eeprom_para(addr, dat, w_size); // 这里要改,write_eeprom是专门为写记录准备的,最后一个字节是校验位
- addr += w_size; // 地址增加
- dat += w_size; // 写数据指针增加
- // LOG("addr= %d,size= %d\r\n",addr,w_size);
- }
- //}
- return ret;
- }
- /*******************批量读取数据********************************/
- // 参数1 dat:读取数据保存指针
- // 参数2 addr 读取数据eeprom起始地址
- // 参数3 len:读取长度
- // 返回:1:成功
- /***************************************************************/
- uint8_t eeprom_MassRead(uint8_t *dat, uint32_t addr, uint16_t len)
- {
- memset(dat, 0, len);
- uint16_t i;
- uint8_t ret = 0;
- if (addr > EEPROM_MAX_SIZE - 1 || addr + len > EEPROM_MAX_SIZE)
- { // 写入空间超过了最大地址范围
- return 1;
- }
- if (len > EEPROM_MAX_READ_SIZE)
- { // 超过最大写读取长度
- for (i = 0; i < len / EEPROM_MAX_READ_SIZE; i++)
- { // 每次读取最大长度
- ret |= read_eeprom_para(addr + i * EEPROM_MAX_READ_SIZE, dat + i * EEPROM_MAX_READ_SIZE, EEPROM_MAX_READ_SIZE); // 要改
- }
- if ((len % EEPROM_MAX_READ_SIZE) != 0)
- { // 整长度读完后,读取可能剩余的部分
- ret |= read_eeprom_para(addr + i * EEPROM_MAX_READ_SIZE, dat + i * EEPROM_MAX_READ_SIZE, len % EEPROM_MAX_READ_SIZE);
- }
- }
- else
- { // 未超过最大长度
- ret |= read_eeprom_para(addr, dat, len);
- }
- return ret;
- }
- #define DEFAULT_PATH_SKEW 0 // 超声波通道偏差修正系数
- #define DEFAULT_PIPE_COE 0.1168745 // COE系数
- #define DEFAULT_IMEI "000000000000000" // 默认IMEI
- #define DEFAULT_CCID "00000000000000000000" // 默认IMEI
- // 01234567890123456789
- #define DEFAULT_MUX_CH_NO1 0
- #define DEFAULT_MUX_CH_NO2 1
- #define DEFAULT_MUX_CH_NO3 2
- #define DEFAULT_MUX_CH_NO4 3
- void LoadDefaultParam(void) // 加载默认参数值
- {
- memset((uint8_t *)&Paramx, 0, sizeof(Param_t));
- Paramx.path_skew[0] = DEFAULT_PATH_SKEW;
- Paramx.path_skew[1] = DEFAULT_PATH_SKEW;
- Paramx.path_skew[2] = DEFAULT_PATH_SKEW;
- Paramx.path_skew[3] = DEFAULT_PATH_SKEW; // 通道修正系数
- Paramx.pipe_coe = DEFAULT_PIPE_COE; // coe系数
- // strcpy(Paramx.imei, DEFAULT_IMEI); // imei号
- // Paramx.imei[sizeof(DEFAULT_IMEI) - 1] = 0;
- // strcpy(Paramx.ccid, DEFAULT_CCID); // CCID号
- // Paramx.ccid[sizeof(DEFAULT_CCID) - 1] = 0;
- Paramx.mux_ch_no[0] = DEFAULT_MUX_CH_NO1;
- Paramx.mux_ch_no[1] = DEFAULT_MUX_CH_NO2;
- Paramx.mux_ch_no[2] = DEFAULT_MUX_CH_NO3;
- Paramx.mux_ch_no[3] = DEFAULT_MUX_CH_NO4; // 多路开关地址
- // Paramx.dev_id[0] = 0x00; //a6
- Paramx.dev_id[0] = 0x80; // bcd //a5
- Paramx.dev_id[1] = 0x55; // bcd
- Paramx.dev_id[2] = 0x60; // bcd
- Paramx.dev_id[3] = 0x10; // bcd
- Paramx.dev_id[4] = 0x00; // bcd
- Paramx.dev_id[5] = 0x03; // bcd//设备地址 A0
- Paramx.chan_num = 1; // 超声波通道数量
- Paramx.diameter = 25; // 直径
- Paramx.pressure_sensor = 2; // without pressure sensor 是否带压力传感器,默认不带
- Paramx.settlement_day = 0; // 结算日,默认 每月最后一天
- Paramx.report_base_hour = 0;
- Paramx.report_base_min = 0;
- Paramx.report_base_sec = 0; // 上报时间点
- Paramx.report_interval = 24 * 60; // 上报间隔 1天
- Paramx.high_temp_alarm_thres = 32767; // 高温报警阈值
- Paramx.low_temp_alarm_thres = -32768; // 低温报警阈值
- Paramx.large_flow_alarm_thres = 0; // 大流量报警阈值
- Paramx.large_flow_cnti_moni_time = 0; // 大流量持续时间
- Paramx.cnti_flow_cnti_moni_time = 0; // 持续流量报警时间
- Paramx.leak_flow_alarm_thres = 0; // 渗漏报警阈值
- Paramx.leak_flow_cnti_moni_time = 0; // 渗漏报警持续时间
- Paramx.high_press_alarm_thres = 0; // 高压力报警阈值
- Paramx.low_press_alarm_thres = 0; // 低压力报警阈值
- Paramx.main_server_ip[0] = 221;
- Paramx.main_server_ip[1] = 229;
- Paramx.main_server_ip[2] = 214;
- Paramx.main_server_ip[3] = 202; // 主服务器ip地址
- Paramx.main_server_port = 5683; // 主服务器端口号
- Paramx.sub_server_ip[0] = 221; // 备用服务器ip地址
- Paramx.sub_server_ip[1] = 229;
- Paramx.sub_server_ip[2] = 214;
- Paramx.sub_server_ip[3] = 202;
- Paramx.sub_server_port = 5683; // 备用服务器端口号
- Paramx.dma_report_start[0] = 0;
- Paramx.dma_report_start[1] = 0;
- Paramx.dma_report_start[2] = 0; // dma上报起始时间 时分秒
- Paramx.dma_report_end[0] = 0;
- Paramx.dma_report_end[1] = 0;
- Paramx.dma_report_end[2] = 0; // dma上报结束时间 时分秒
- Paramx.dma_interval = 0; // dma上报间隔 分钟单位
- Paramx.total_positive_water[0] = 0;
- Paramx.total_positive_water[1] = 0;
- Paramx.total_positive_water[2] = 0;
- Paramx.total_positive_water[3] = 0; // 表底读数
- uint16_t i, j;
- for (i = 0; i < CHECK_TEMP_POINT; i++)
- { // 8个流量等级 ,3个温度等级下的修正流速,用于查找当前流速落入哪个区间
- Paramx.check_spdLvl_c[i].spd_lvl[0] = GetSpdLvl(Q1);
- Paramx.check_spdLvl_c[i].spd_lvl[1] = GetSpdLvl(1.6 * Q1);
- Paramx.check_spdLvl_c[i].spd_lvl[2] = GetSpdLvl(3.2 * Q1);
- Paramx.check_spdLvl_c[i].spd_lvl[3] = GetSpdLvl(8 * Q1);
- Paramx.check_spdLvl_c[i].spd_lvl[4] = GetSpdLvl(0.1 * Q3);
- Paramx.check_spdLvl_c[i].spd_lvl[5] = GetSpdLvl(0.2 * Q3);
- Paramx.check_spdLvl_c[i].spd_lvl[6] = GetSpdLvl(0.35 * (1.6 * Q1 + Q3));
- Paramx.check_spdLvl_c[i].spd_lvl[7] = GetSpdLvl(Q3);
- // init c value is 1340
- for (j = 0; j < CHECK_POINT_NUM; j++)
- { // 8个流量等级 ,3个温度等级下的基础声速,修正声速
- Paramx.check_spdLvl_c[i].base_c[j] = CHECK_C_VALUE;
- Paramx.check_spdLvl_c[i].cur_c[j] = CHECK_C_VALUE;
- }
- }
- // float *fp = (float *)Quad_Cell_Ary;
- // for (i = 0; i < Quad_Cell_NUM * 5; i++)
- // {
- // *fp = 1;
- // fp++;
- // }
- Paramx.q_value = CHECK_Q_VALUE; // 默认Q值,影响check脉冲计算
- Paramx.para_len = sizeof(Paramx) - 8;
- Paramx.para_crc32 = com_crc32L_next(0xFFFFFFFFu, (uint8_t *)(&Paramx) + 8, sizeof(Param_t) - 8, 0xEDB88320); // 计算crc校验值
- // eeprom_MassWrite((uint8_t *)&Paramx,PARAMX_START_ADDR,sizeof(Param_t));
- // eeprom_MassRead((uint8_t *)&Paramx,PARAMX_START_ADDR,sizeof(Param_t));
- Paramx.b = 63;
- Paramx.n = 45;
- Paramx.q = 32;
- Paramx.r = 500;
- rewrite_para_flag |= 0x1;
- }
- void get_para_to_tdcitf(void) // 获取参数给tdcItf
- {
- uint8_t i;
- for (i = 0; i < MUX_CH_NUM; i++)
- TdcItf.path_skew[i] = Paramx.path_skew[i];
- TdcItf.pipe_coe = Paramx.pipe_coe;
- TdcItf.ch_num = Paramx.chan_num;
- if (TdcItf.ch_num == 1)
- {
- TdcItf.ch_bit_map = 1;
- }
- else if (TdcItf.ch_num == 2)
- {
- TdcItf.ch_bit_map = 3;
- }
- else if (TdcItf.ch_num == 4)
- {
- TdcItf.ch_bit_map = 0x0F;
- }
- for (i = 0; i < MUX_CH_NUM; i++)
- TdcItf.mux_ch_no[i] = Paramx.mux_ch_no[i];
- }
- // #define DEBUG_PARAM
- // #ifdef DEBUG_PARAM
- // uint8_t p1data[sizeof(Param_t)];
- // uint8_t p2data[sizeof(Param_t)];
- // uint8_t err_pos=0;
- // #endif
- void ParamInit(void) // 上电初始化
- {
- uint8_t i;
- if (init_eeprom_mutx_flag == 0)
- {
- eeprom_mutx_init(); // 创建eeprom操作的互斥信号量,未进入调度前,不能用
- }
- eeprom_MassRead((unsigned char *)&Paramx, PARAMX_START_ADDR, sizeof(Param_t)); // 读取参数
- // memcpy(p1data,&Paramx,sizeof(Param_t));
- uint32_t crc = com_crc32L_next(0xFFFFFFFFu, (uint8_t *)(&Paramx) + 8, sizeof(Param_t) - 8, 0xEDB88320);
- if (crc != Paramx.para_crc32) // wxl2026-5-8 校验错误时记录日志
- rewrite_para_flag |= 4;
- if (Paramx.para_len != sizeof(Paramx) - 8)
- {
- LoadDefaultParam(); // 加载默认参数
- }
- // Nb_Run_t *nb_run;
- // GetNbRun(&nb_run);
- // Paramx.imei[15] = 0; // 限制长度,防止溢出
- // strcpy(nb_run->imei, Paramx.imei);
- // Paramx.ccid[31] = 0; // 限制长度,防止溢出
- // strcpy(nb_run->ccid, Paramx.ccid);
- // Paramx.ver_type = VER_TYPE; // type, 1: ultrasound flow meter;
- // Paramx.ver_operator = VER_OPERATOR; // operator, 1: China Telecom;
- // Paramx.ver_module = VER_MODULE; // module, 1: HC32_BC28;
- // Paramx.ver_firmware = VER_FIRMWARE; // firmware version;//设备版本信息
- if (Paramx.chan_num != 1)
- {
- Paramx.chan_num = 1;
- rewrite_para_flag |= 1;
- }
- get_para_to_tdcitf(); // 获取参数到tdcitf结构体
- memset((uint8_t *)&PatchInfo, 0, sizeof(PATCH_INFO_DEF));
- if (Check_quad_cell_data_valid(QUAD_CELL_START_ADDR) == 0)
- { // wxl2026-4-16
- get_quad_cell_data(Quad_Cell_Ary); // wxl2026-4-14
- }
- else
- {
- rewrite_para_flag |= 0x2;
- }
- alarm_init();
- bill_init();
- init_eeprom_mutx_flag = 1;
- }
- ////////////检查参数时,发现参数不合法,加载默认参数后重新eeprom/////////////////
- void check_rewrite_para(void)
- {
- if (StartUp != 2) // 在第二秒开始判断参数正确性
- return;
- if (rewrite_para_flag & 0x1)
- {
- // 保存主参数
- eeprom_MassWrite((uint8_t *)&Paramx, PARAMX_START_ADDR, sizeof(Param_t));
- rewrite_para_flag |= 0x4;
- }
- if (rewrite_para_flag & 0x2)
- {
- // 保存主参数
- set_diameter_and_quad_cell_data(0, &Quad_Cell_Ary);
- }
- // crc校验错误写日志
- if (rewrite_para_flag & 0x4) // wxl2026-5-8
- {
- write_alarm(LOG_PARA_CRC_ERROR, 1, 5555);
- // memcpy(p2data,&Paramx,sizeof(Param_t));
- set_crc_check_para();
- // int i;
- /// for(i=0;i<sizeof(Param_t);i++)if(p1data[i]!=p2data[i])err_pos= i;
- }
- rewrite_para_flag = 0;
- }
- uint16_t GetSpdLvl(double flow_rate)
- { // 获取当前流速,用于查表
- return (uint16_t)(flow_rate * 1000000 / 3600 / TdcItf.pipe_coe);
- }
- // modified by yuewei 20260316 only use check_spdLvl_c[0] start
- // check temperature interval: 0~10/10~40/40 and above
- /*
- uint16_t CheckTempRangeIndex(float temp) {//获取温度等级索引号
- if (temp >= 40.0) {
- return 2;
- } if (temp >= 10.0) {
- return 1;
- }
- return 0;
- }
- */
- // 获取温度等级索引号,only use 0
- uint16_t CheckTempRangeIndex(float temp)
- {
- return 0;
- }
- // modified by yuewei 20260316 only use check_spdLvl_c[0] end
- /**************************************************/
- // 获取流速等级索引号,用于获取校正系数
- /***************************************************/
- #if 0
- uint8_t CheckCValueIndex(uint16_t temp_idx, uint16_t spdLvl) {
- uint8_t i;
- uint16_t mid;
- CheckSpdLvlC_t *p = &Paramx.check_spdLvl_c[temp_idx];
- if (spdLvl <= p->spd_lvl[0]) {
- return 0;
- }
- for (i = 0; i < CHECK_POINT_NUM - 1; i++) {
- mid = (p->spd_lvl[i + 1] + p->spd_lvl[i]) / 2;
- if (spdLvl >= p->spd_lvl[i] && spdLvl < mid) {
- return i;
- } else if (spdLvl >= mid && spdLvl < p->spd_lvl[i + 1]) {
- return i + 1;
- }
- }
- return CHECK_POINT_NUM - 1;
- }
- #endif
- #if 0
- uint8_t CheckCValueIndex(uint16_t temp_idx, uint16_t spdLvl)
- {
- // 1. Boundary safety limit, only 3 temperature intervals, actually use index 0 only
- if (temp_idx >= 3)
- {
- return 0;
- }
- CheckSpdLvlC_t *p = &Paramx.check_spdLvl_c[temp_idx];
- uint8_t i;
- // 2. Less than minimum speed level -> fixed return 0
- if (spdLvl <= p->spd_lvl[0])
- {
- return 0;
- }
- // 3. Direct interval judgment (hysteresis canceled)
- for (i = 0; i < CHECK_POINT_NUM - 1; i++)
- {
- // Directly match speed level interval
- if (spdLvl <= p->spd_lvl[i + 1])
- {
- return i;
- }
- }
- // 4. Greater than maximum speed level -> return last index
- return CHECK_POINT_NUM - 1;
- }
- #endif
- uint8_t CheckCValueIndex(uint16_t temp_idx, uint16_t spdLvl)
- {
- // 1. 温度区间安全限界,仅0/1/2有效
- if (temp_idx >= 3)
- {
- return 0;
- }
- CheckSpdLvlC_t *p = &Paramx.check_spdLvl_c[temp_idx];
- uint8_t i;
- uint8_t best_idx = 0;
- uint16_t min_diff;
- uint16_t curr_diff;
- spdLvl = spdLvl - 5;//add by yuewei 20260629
-
- // 初始化最小差值为第一个点差值
- if (spdLvl >= p->spd_lvl[0])
- min_diff = spdLvl - p->spd_lvl[0];
- else
- min_diff = p->spd_lvl[0] - spdLvl;
- // 遍历所有速度点,寻找差值最小的下标
- for (i = 1; i < CHECK_POINT_NUM; i++)
- {
- if (spdLvl >= p->spd_lvl[i])
- curr_diff = spdLvl - p->spd_lvl[i];
- else
- curr_diff = p->spd_lvl[i] - spdLvl;
- // 更新最小差值与最优索引
- if (curr_diff < min_diff)
- {
- min_diff = curr_diff;
- best_idx = i;
- }
- }
- return best_idx;
- }
- // 获取在不同温度和流速等级下的,声速修正系数
- float CheckFlowCorrectFactor(float temp, uint16_t spdLvl)
- {
- uint16_t temp_idx = CheckTempRangeIndex(temp);
- uint8_t c_idx = CheckCValueIndex(temp_idx, spdLvl);
- CheckSpdLvlC_t *p = &Paramx.check_spdLvl_c[temp_idx];
- uint16_t curr_c = p->cur_c[c_idx];
- uint16_t base_c = p->base_c[c_idx];
- LOG("spdLvl=%d,curr_c = %d,c_idx=%d\n", spdLvl, curr_c, c_idx);
- return ((float)curr_c * 1.0f) / (float)base_c;
- }
- uint32_t BillTime(uint8_t year, uint8_t month) // 确定结算日的上报时间(取)
- {
- uint8_t last_day = last_day_of_month(year, month);
- uint8_t day;
- if (Paramx.settlement_day == 0)
- {
- return 0;
- }
- if (Paramx.settlement_day > 0 && Paramx.settlement_day <= last_day)
- {
- day = Paramx.settlement_day;
- }
- else
- {
- day = last_day;
- }
- return ((day << 24) | (Paramx.report_base_hour << 16) |
- (Paramx.report_base_min << 8) | Paramx.report_base_sec); // 上报时分秒
- }
- /////////////////获取参数结构体指针//////////////////////
- // 输入参数:指向结构体指针的指针
- // 返回参数:无
- //////////////////////////////////////
- void GetParam(Param_t **para)
- {
- *para = &Paramx;
- }
- ///////////////////////保存所有参数//////////////////
- // 输入参数:无
- // 返回参数:无
- //////将内存中的param参数全部写入到eeprom中//////////
- void SaveParam(void)
- {
- uint32_t param_len = 0;
- uint32_t param_crc;
- uint8_t *data;
- uint8_t i;
- Nb_Run_t *nb_run;
- GetNbRun(&nb_run);
- Paramx.path_skew[0] = TdcItf.path_skew[0];
- Paramx.path_skew[1] = TdcItf.path_skew[1];
- Paramx.path_skew[2] = TdcItf.path_skew[2];
- Paramx.path_skew[3] = TdcItf.path_skew[3];
- Paramx.pipe_coe = TdcItf.pipe_coe;
- // memcpy(Paramx.imei, nb_run->imei, 16); // imei号保存
- // memcpy(Paramx.ccid, nb_run->ccid, 32); // ccid号保存
- memcpy(Paramx.mux_ch_no, TdcItf.mux_ch_no, sizeof(TdcItf.mux_ch_no)); // 多路开关地址
- Paramx.para_crc32 = com_crc32L_next(0xFFFFFFFFu, (uint8_t *)(&Paramx) + 8, sizeof(Param_t) - 8, 0xEDB88320);
- Paramx.para_len = sizeof(Paramx) - 8;
- eeprom_MassWrite((uint8_t *)&Paramx, PARAMX_START_ADDR, sizeof(Paramx));
- }
- /////////////////设置版本号 保存到eeprom中///////////////////////
- // 参数:版本号uchar
- // 返回:无
- ///////////////////////////////
- // void set_param_firmware_ver(uint8_t ver)
- //{ // 设置版本号
- // Paramx.ver_firmware = ver;
- // uint32_t addr = offsetof(Param_t, ver_firmware) + PARAMX_START_ADDR;
- // write_eeprom_para(addr, (uint8_t *)&ver, sizeof(ver));
- // set_crc_check_para();
- // }
- ////////////获取版本号//////////////
- // 参数:无
- // 返回:版本号数值uchar
- ////////////////////////
- uint8_t get_param_firmware_ver(void)
- { // 读取版本号
- return VER_FIRMWARE;
- }
- /////////////////获取超声波通道数/////////////////////
- /// 参数:无
- // 返回:超声波通道数
- /////////////////////////////////////
- uint8_t GetChNum(void)
- {
- uint8_t numb;
- get_channel_numb(&numb);
- return numb;
- }
- int8_t get_channel_numb(uint8_t *numb)
- { // 获取通道数
- *numb = Paramx.chan_num;
- return 0;
- }
- /////////////////////////////与红外通讯相关的设置和读取///////////////////////////////////////////
- //////////////////////////////////对paramx参数进行crc校验,并保存crc校验值////////////////////////////////////////////////////////////////
- // 参数:无
- // 返回0:正常 1:异常
- uint8_t set_crc_check_para(void)
- {
- Paramx.para_crc32 = com_crc32L_next(0xFFFFFFFFu, (uint8_t *)(&Paramx) + 8, sizeof(Param_t) - 8, 0xEDB88320);
- return write_eeprom_para(PARAMX_START_ADDR + offsetof(Param_t, para_crc32), (uint8_t *)&Paramx.para_crc32, sizeof(Paramx.para_crc32)); // 校验值长度
- return 0;
- }
- /////////////////////////检查新参数是否改变,如果改变则保存/////////////////////////////////////////////////
- // 参数1: new_para新参数值
- // 参数2: old_para原参数值
- // 参数3: len参数长度
- // 参数5:flag保存是否修改的标志1:修改了,0,未修改
- // 返回:0:保存成功 1:失败
- /////////////////////////////////////////////////////////////////////////////
- uint8_t set_para_if_nessary(void *new_para, void *old_para, uint8_t len, uint8_t *flag)
- {
- uint8_t *dat1 = new_para; // 转换为char型指针
- uint8_t *dat2 = old_para; // 转换为char型指针
- // if(memcmp(dat1,dat2,len)==0){//检查新数据和老数据是否一致
- // return 0;
- // }
- memcpy(dat2, dat1, len); // 更新参数值,在paramx中
- *flag = 1; // 参数更改标志,用于crc校验参考
- uint32_t addr = PARAMX_START_ADDR + (uint32_t)old_para - (uint32_t)&Paramx; // 取改参数在eeprom中的地址
- uint8_t ret;
- ret = write_eeprom_para(addr, dat1, len); // 返回写入是否成功标志 0:成功,1失败
- ret |= read_eeprom_para(addr, old_para, len); // 写入后读回来
- get_para_to_tdcitf();
- return 0;
- }
- //////////////////设置硬件参数参数////////////////////////////
- /// 参数:HardWarePara 包含 是否带压力传感器指示 pressure_sensor //
- // 关断参数:pipe_coe
- // 返回: 成功返回1, 失败返回2
- ///////////////////////////////////
- int8_t set_hardware_para(HardWareParaDef *HardWarePara)
- {
- uint8_t flag = 0, ret = 0;
- if (HardWarePara->pipe_coe <= 0)
- return 2; // 数据不合法
- if (HardWarePara->pressure_sensor != 1 && HardWarePara->pressure_sensor != 2)
- return 2;
- ret |= set_para_if_nessary(&HardWarePara->pipe_coe, &Paramx.pipe_coe, sizeof(Paramx.pipe_coe), &flag);
- ret |= set_para_if_nessary(&HardWarePara->pressure_sensor, &Paramx.pressure_sensor, sizeof(Paramx.pressure_sensor), &flag);
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1); // write_eeprom_para在成功写入后返回0,否则返回非零值
- }
- ////////////////////////读取硬件参数///////////////////////////////////
- // 参数:硬件参数指针HardWareParaDef
- // 返回:0:读取不成功, 1:读取成功
- ///////////////////////////////////////////////////////////////////////
- int8_t get_hardware_para(HardWareParaDef *HardWarePara)
- {
- HardWarePara->pipe_coe = Paramx.pipe_coe;
- HardWarePara->pressure_sensor = Paramx.pressure_sensor;
- return 0;
- }
- PATCH_INFO_DEF PatchInfo;
- ///////////////////设置表端开始升级信息//////////////////////////////////////////
- // 参数patch_info:表端升级相关信息指针
- // 返回:1:设置成功 2:版本号不匹配 3:升级包长度值超过允许长度
- /////////////////////////////////////////////////////////
- int8_t set_patch_info(PATCH_INFO_DEF *patch_info)
- {
- memset((uint8_t *)&PatchInfo, 0, sizeof(PATCH_INFO_DEF));
- if (patch_info->new_ver[4] <= patch_info->cur_ver[4] || patch_info->new_ver[0] != patch_info->cur_ver[0] || patch_info->new_ver[1] != patch_info->cur_ver[1] || patch_info->new_ver[2] != patch_info->cur_ver[2] || patch_info->new_ver[3] != patch_info->cur_ver[3])
- { // 新版本信息不合法
- return 2;
- }
- if (patch_info->cur_ver[0] != 'V')
- return 2;
- if (patch_info->cur_ver[1] != VER_TYPE)
- return 2;
- if (patch_info->cur_ver[2] != VER_OPERATOR)
- return 2;
- if (patch_info->cur_ver[3] != VER_MODULE)
- return 2;
- if (patch_info->cur_ver[4] != VER_FIRMWARE)
- return 2; // 差分包当前版本和正在运行的版本不一致
- if (patch_info->patch_len > DIFF_PATCH_PACKET_SIZE)
- return 3; // 长度超过写入最大长度
- memcpy(PatchInfo.cur_ver, patch_info->cur_ver, sizeof(patch_info->cur_ver)); // 保存当前版本号
- memcpy(PatchInfo.new_ver, patch_info->new_ver, sizeof(patch_info->new_ver)); // 保存新版本号
- PatchInfo.packet_crc = patch_info->packet_crc; // 数据的总校验值
- PatchInfo.patch_len = patch_info->patch_len; // 数据总长度
- PatchInfo.per_packet_len = patch_info->per_packet_len; // 固定512字节
- // PatchInfo.per_packet_len=patch_info->per_packet_len;//每包数据长度
- PatchInfo.update_status = 0x1; // 开始升级标志
- PatchInfo.cur_num = 1; // 当前升级包序号,初始0,第一包值=1
- PatchInfo.res_crc16 = 0; // 累计crc,没来一包数据校验一次,最后检查和中校验值是否相等
- PatchInfo.flash_addr_ptr = 0; // 当前flash写入地址
- LOG("packet num =%d,total size = %d\r\n",
- (patch_info->patch_len + PatchInfo.per_packet_len - 1) / PatchInfo.per_packet_len,
- patch_info->patch_len);
- return 1;
- }
- ////////////////////////////向flash写入差分包/////////////////////////////////////////
- ////DIFF_PACKET_DEF参数1 numb:包序号,从1开始
- // DIFF_PACKET_DEF参数2: len:差分包长度,目前默认是512byte
- // DIFF_PACKET_DEF参数3:data指针 指向要写入的差分包数据
- // 返回:1:成功写入 2:crc失败 6:未收到开始包 7:数据包序号不对
- //////////////////////////////////////////////////////////////////////////////
- // const uint8_t app_addr=0;
- uint8_t write_diff_patch_to_flash(DIFF_PACKET_DEF *Packet)
- {
- McuFlash_WP_t WP;
- uint8_t last_dat = 0;
- uint16_t write_len;
- if (PatchInfo.update_status != 1)
- return 0x6;
- if (Packet->packet_numb != PatchInfo.cur_num)
- return 6; // 不是下一个包
- //////////////////确定最后一帧及写入长度///////////////////
- Packet->packet_size = Packet->packet_size; // DIFF_PER_PACKET_SIZE;//固定
- if (Packet->packet_numb * PatchInfo.per_packet_len >= PatchInfo.patch_len)
- {
- last_dat = 1;
- write_len = (uint16_t)(PatchInfo.patch_len % PatchInfo.per_packet_len);
- }
- else
- {
- last_dat = 0; // 中间帧数据
- write_len = Packet->packet_size;
- }
- // write_len = Packet->packet_size;
- PatchInfo.res_crc16 = pack_crc_check(PatchInfo.res_crc16, Packet->data, write_len);
- if (Packet->packet_numb == 1)
- { // 第一包数据,先擦除
- #ifndef DEBUG_PATCH
- rt_enter_critical();
- // McuFlash_Unlock();
- McuFlash_EraseSegment(DIFF_PATCH_PACKET_START, DIFF_PATCH_PACKET_SIZE);
- // McuFlash_Lock();
- rt_exit_critical();
- #endif
- // erase_flash_memory(DIFF_PATCH_PACKET_START, DIFF_PATCH_PACKET_SIZE);
- }
- #ifndef DEBUG_PATCH
- write_flash_memory(Packet->data, DIFF_PATCH_PACKET_START + PatchInfo.flash_addr_ptr, write_len);
- #endif
- #ifdef APP_DEBUG_PRINT
- LOG("write patch num= %d\r\n", PatchInfo.cur_num);
- #endif
- PatchInfo.cur_num++;
- PatchInfo.flash_addr_ptr += write_len;
- if (last_dat == 1)
- { // 最后一包
- if (PatchInfo.res_crc16 != PatchInfo.packet_crc)
- {
- LOG("update data crc err pack:%d\r\n", Packet->packet_numb);
- return 2;
- }
- else
- {
- PatchInfo.update_status = 2; // 升级包写入结束,bootloader用该位判断是否需要升级,升级完成后将该位清零
- // 未升级的情况下,bootloader根据代码的完整程度和版本的新旧情况运行app
- // 写差分升级包升级的信息,供bootloader使用
- PatchInfo.run_app_ver_addr = (uint32_t)SOFT_VER;
- #ifndef DEBUG_PATCH
- erase_flash_memory(DIFF_UPDATE_INFO_START, DIFF_UPDATE_INFO_SIZE); // 写flash
- write_flash_memory((uint8_t *)&PatchInfo, DIFF_UPDATE_INFO_START, sizeof(PATCH_INFO_DEF));
- #endif
- LOG("last packet ok\r\n");
- NbRun.reset_mcu_cnt = 5;
- return 1; // 最后一包
- }
- }
- return 1; // 0x10;//中间包
- }
- //************设置主服务器和从服务器的ip地址和端口号******************************/
- // 参数dat:指向SERVER_IP_PORT_DEF结构体
- // 返回:成功返回1,失败返回2
- /////////////////////////////////////////////////////////////////////////////////
- int8_t set_server_ip_port_para(SERVER_IP_PORT_DEF *server_ip_para)
- {
- uint8_t flag = 0, ret = 0;
- // uint32_t addr;
- ret |= set_para_if_nessary(server_ip_para->main_server_ip, Paramx.main_server_ip, sizeof(Paramx.main_server_ip), &flag);
- ret |= set_para_if_nessary(&server_ip_para->main_server_port, &Paramx.main_server_port, sizeof(Paramx.main_server_port), &flag);
- ret |= set_para_if_nessary(server_ip_para->sub_server_ip, Paramx.sub_server_ip, sizeof(Paramx.sub_server_ip), &flag);
- ret |= set_para_if_nessary(&server_ip_para->sub_server_port, &Paramx.sub_server_port, sizeof(Paramx.sub_server_port), &flag);
- if (flag == 1)
- { // 保存crc校验
- // Paramx.para_crc32 = com_crc32L_next(0xFFFFFFFFu, (uint8_t *)(&Paramx+8), sizeof(Param_t)-8, 0xEDB88320);
- // ret|=write_eeprom_para(PARAMX_START_ADDR+offsetof(Param_t,para_crc32),(uint8_t *)&Paramx.para_crc32,sizeof(Paramx.para_crc32));//校验值长度
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1); // write_eeprom_para在成功写入后返回0,否则返回非零值
- }
- ////////////////////////////读取主服务器和备用服务器ip地址和端口号/////////////////////////////
- // 参数server_ip_dat :SERVER_IP_PORT_DEF类型指针,用于保存主服务器和备用服务器的端口和ip地址信息
- //////////////////////////////////////////////////////////
- int8_t get_server_ip_port_para(SERVER_IP_PORT_DEF *server_ip_para)
- {
- memcpy(server_ip_para->main_server_ip, Paramx.main_server_ip, sizeof(Paramx.main_server_ip));
- server_ip_para->main_server_port = Paramx.main_server_port;
- memcpy(server_ip_para->sub_server_ip, Paramx.sub_server_ip, sizeof(Paramx.sub_server_ip));
- server_ip_para->sub_server_port = Paramx.sub_server_port;
- return 0;
- }
- ////////////////////////////设置定时上报周期和时间间隔/////////////////////////////////////////////////////
- // 参数:regular_report_para定时上报数据结构体,包含起始基准时间,间隔时间u\
- //返回:1:成功2:失败
- /////////////////////////////////////////////////////////////////////////////////////////////////////////
- int8_t set_regular_report_para(REGULAR_REPORT_DEF *regular_report_para)
- {
- uint8_t flag = 0, ret = 0;
- if (regular_report_para->report_base_hour > 23 || regular_report_para->report_base_min > 59 || regular_report_para->report_base_sec > 59)
- return 2;
- ret |= set_para_if_nessary(®ular_report_para->report_base_hour, &Paramx.report_base_hour, 3, &flag); // 年月日参数
- ret |= set_para_if_nessary(®ular_report_para->report_interval, &Paramx.report_interval, sizeof(Paramx.report_interval), &flag); // 时间间隔
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- /////////////////////////////读取定时上报周期和时间间隔信息//////////////////////////////////////////////
- // 参数regular_report_para保存定时上报数据结构体
- // 返回:1成功读取
- ////////////////////////////////////////////
- int8_t get_regular_report_para(REGULAR_REPORT_DEF *regular_report_para)
- {
- regular_report_para->report_base_hour = Paramx.report_base_hour;
- regular_report_para->report_base_min = Paramx.report_base_min;
- regular_report_para->report_base_sec = Paramx.report_base_sec;
- regular_report_para->report_interval = Paramx.report_interval;
- return 0;
- }
- ///////////////////////////////////设置DMA定时上报周期参数////////////////////////////////////////////////
- // 参数:dma_report_para dma参数结构体,包含dma起始时间结束时间和时间间隔参数
- // 返回:1:成功 2:失败
- ////////////////////////////////////////////////////////////////////////////////////
- int8_t set_dma_regular_report_para(DMA_REGULAR_REPORT_DEF *dma_report_para)
- {
- uint8_t flag = 0, ret = 0;
- // 判断数据是否在正常范围内
- if (dma_report_para->dma_report_start_hour > 23 || dma_report_para->dma_report_start_min > 59 || dma_report_para->dma_report_start_sec > 59)
- return 2;
- if (dma_report_para->dma_report_end_hour > 23 || dma_report_para->dma_report_end_min > 59 || dma_report_para->dma_report_end_sec > 59)
- return 2;
- ret |= set_para_if_nessary(dma_report_para, Paramx.dma_report_start, 8, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- //////////////////////////////读取DMA定时上报参数///////////////////////////////////////////////////////
- // 参数: dma_report_para 参数保存结构体
- // 返回1:获取成功2:失败
- ////////////////////////////////////////////////////////////////////////////////////////
- int8_t get_dma_regular_report_para(DMA_REGULAR_REPORT_DEF *dma_report_para)
- {
- dma_report_para->dma_report_start_hour = Paramx.dma_report_start[0];
- dma_report_para->dma_report_start_min = Paramx.dma_report_start[1];
- dma_report_para->dma_report_start_sec = Paramx.dma_report_start[2];
- dma_report_para->dma_report_end_hour = Paramx.dma_report_end[0];
- dma_report_para->dma_report_end_min = Paramx.dma_report_end[1];
- dma_report_para->dma_report_end_sec = Paramx.dma_report_end[2];
- dma_report_para->dma_interval = Paramx.dma_interval;
- return 0;
- }
- ////////////////////////设置流量告警参数//////////////////////////////////////
- // 参数:flow_alarm_para流量告警参数结构体
- // 返回:1:设置成功 2:失败
- int8_t set_flow_alarm_para(FLOW_ALARM_PARA_DEF *flow_alarm_para)
- {
- uint8_t flag = 0, ret = 0;
- // 判断数据是否在正常范围内
- ret = set_para_if_nessary(flow_alarm_para, &Paramx.large_flow_alarm_thres, 14, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ?: -1);
- }
- ////////////////////////获取流量告警参数值/////////////////////////////////////////
- // 参数flow_alarm_para 保存流量参数
- // 返回:1:成功 2:失败
- //////////////////////////////////////////////////////
- int8_t get_flow_alarm_para(FLOW_ALARM_PARA_DEF *flow_alarm_para)
- {
- flow_alarm_para->large_flow_alarm_thres = Paramx.large_flow_alarm_thres;
- flow_alarm_para->large_flow_cnti_moni_time = Paramx.large_flow_cnti_moni_time;
- flow_alarm_para->cnti_flow_cnti_moni_time = Paramx.cnti_flow_cnti_moni_time;
- flow_alarm_para->leak_flow_alarm_thres = Paramx.leak_flow_alarm_thres;
- flow_alarm_para->leak_flow_cnti_moni_time = Paramx.leak_flow_cnti_moni_time;
- return 0;
- }
- /////////////////////设置压力表告警参数///////////////////////////////////////////////////
- // 参数:press_alarm_para 要设置的压力表报警参数数据指针
- // 返回:1:成功,2:失败
- ///////////////////////////////////////////////////////////////////////////////
- int8_t set_press_alarm_para(PRESS_ALARM_PARA_DEF *press_alarm_para)
- {
- uint8_t flag = 0, ret = 0;
- uint8_t dat[4];
- memset(dat, 0, 4);
- dat[0] = press_alarm_para->high_press_alarm_thres;
- dat[2] = press_alarm_para->low_press_alarm_thres;
- if (dat[0] < dat[2])
- return 3;
- // 判断数据是否在正常范围内
- ret = set_para_if_nessary(dat, &Paramx.high_press_alarm_thres, 4, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- ////////////////////////获取压力报警参数//////////////////////////////////////////////////
- ////参数 press_alarm_para 存储压力报警参数值,包括高压力和低压力报警阈值
- // 返回 1:读取成功
- ////////////////////////////////////////////////////////////////////////////////////////////
- int8_t get_press_alarm_para(PRESS_ALARM_PARA_DEF *press_alarm_para)
- {
- press_alarm_para->high_press_alarm_thres = Paramx.high_press_alarm_thres;
- press_alarm_para->low_press_alarm_thres = Paramx.low_press_alarm_thres;
- return 0;
- }
- /////////////////////////设置温度告警参数//////////////////////////////////////
- /////参数: temp_alarm_para 指针包含要存储的温度报警参数 包括高温和低温报警阈值
- // 返回 1:成功 2:失败
- ////////////////////////////////////////////////////////////////////////////
- int8_t set_temp_alarm_para(TEMP_ALARM_PARA_DEF *temp_alarm_para)
- {
- uint8_t flag = 0, ret = 0;
- if (temp_alarm_para->high_temp_alarm_thres < temp_alarm_para->low_temp_alarm_thres)
- return 2;
- ret = set_para_if_nessary(temp_alarm_para, &Paramx.high_temp_alarm_thres, 4, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- /////////////////////////获取温度告警参数//////////////////////////////////////
- /////参数: temp_alarm_para 指针,保存读出的参数
- // 返回 1:成功 2:失败
- ////////////////////////////////////////////////////////////////////////////
- int8_t get_temp_alarm_para(TEMP_ALARM_PARA_DEF *temp_alarm_para)
- {
- temp_alarm_para->high_temp_alarm_thres = Paramx.high_temp_alarm_thres;
- temp_alarm_para->low_temp_alarm_thres = Paramx.low_temp_alarm_thres;
- return 0;
- }
- ////////////////////////////设置表端结算日参数/////////////////////////////////////
- // 参数:要写入的表端结算日数据
- // 返回 1:成功 2:失败
- ////////////////////////////////////////////////////////////////////////////////////
- int8_t set_settlement_day_para(SETTLEMENT_DAY_DEF *settlement_day_para)
- {
- uint8_t flag = 0, ret = 0;
- if (settlement_day_para->settlement_day > 31)
- return 2;
- ret = set_para_if_nessary(settlement_day_para, &Paramx.settlement_day, 1, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- ////////////////////////////读取表端结算日参数/////////////////////////////////////
- // 参数:要写入的表端结算日数据
- // 返回 1:成功 2:失败
- ////////////////////////////////////////////////////////////////////////////////////
- int8_t get_settlement_day_para(SETTLEMENT_DAY_DEF *settlement_day_para)
- {
- settlement_day_para->settlement_day = Paramx.settlement_day;
- return 0;
- }
- ///////////////////////////////设置表端底读///////////////////////////////////////////////////
- // 参数:指向表端底读数据指针
- // 返回:1:成功 2:失败
- //////////////////////////////////////////////////////////////////////////////////////////////
- int8_t set_meter_bottom_data(METER_BOTTOM_DEF *bottom_data)
- {
- uint8_t flag = 0, ret = 0;
- double base_read = (double)(uint32_t)((bottom_data->fw[3] << 24) |
- (bottom_data->fw[2] << 16) |
- (bottom_data->fw[1] << 8) |
- bottom_data->fw[0]);
- base_read *= 10000; // 0.01->0.000001//转换为0.000001单位
- FwCumFlow = base_read; // 更新当前流量和正向流量
- base_read = (double)(uint32_t)((bottom_data->bw[3] << 24) |
- (bottom_data->bw[2] << 16) |
- (bottom_data->bw[1] << 8) |
- bottom_data->bw[0]);
- base_read *= 10000; // 0.01->0.000001//转换为0.000001单位
- BwCumFlow = base_read;
- CumFlow = FwCumFlow - BwCumFlow;
- SetBillCumFlow(CumFlow, FwCumFlow, BwCumFlow); // 设置当前流量数据
- save_cur_flow_flag = 1; // 保存到当前值,循环存储
- return 0;
- }
- ////////////////////////读取前18个月月结数据//////////////////////////////////////////
- // 参数:月结数据指针,空间大小18*11
- // 成功返回1,失败返回2
- /////////////////////////////////////////////////////////////////////////////////////
- int8_t get_18month_record_data(uint8_t *data)
- {
- uint8_t i, ret = 0;
- bill_t bill;
- rtc_run_t *rr;
- get_rtc_run(&rr); // 当前时间
- uint8_t flag, j;
- uint32_t date = ((rr->year << 16) | (rr->month << 8));
- for (i = 0; i < 18; i++)
- {
- date = prev_month(date);
- flag = get_month_used_bill((uint8_t)(date >> 16), (uint8_t)(date >> 8), &bill);
- ret |= flag;
- if (flag != 0)
- {
- for (j = 0; j < 11; j++)
- data[i * 11 + j] = 0;
- continue;
- }
- data[i * 11] = 0x14;
- data[i * 11 + 1] = bill.date[0];
- data[i * 11 + 2] = bill.date[1]; //
- data[i * 11 + 3] = (unsigned char)(bill.fw_used);
- data[i * 11 + 4] = (unsigned char)(bill.fw_used >> 8);
- data[i * 11 + 5] = (unsigned char)(bill.fw_used >> 16);
- data[i * 11 + 6] = (unsigned char)(bill.fw_used >> 24); // 正向流量
- data[i * 11 + 7] = (unsigned char)(bill.bw_used);
- data[i * 11 + 8] = (unsigned char)(bill.bw_used >> 8);
- data[i * 11 + 9] = (unsigned char)(bill.bw_used >> 16);
- data[i * 11 + 10] = (unsigned char)(bill.bw_used >> 24); // 反向流量
- }
- if (ret != 0)
- return -1;
- else
- return 0;
- }
- ////////////////////////读取前30日日结数据//////////////////////////////////////////
- // 参数:日结数据指针,空间大小30*12
- // 成功返回1,失败返回2
- /////////////////////////////////////////////////////////////////////////////////////
- int8_t get_30day_record_data(uint8_t *data)
- {
- uint8_t i, ret = 0;
- bill_t bill;
- rtc_run_t *rr;
- get_rtc_run(&rr); // 当前时间
- uint32_t date = ((rr->year << 16) | (rr->month << 8) | rr->day);
- uint8_t flag, j;
- for (i = 0; i < 30; i++)
- {
- date = prev_day(date);
- flag = get_day_used_bill((uint8_t)(date >> 8), (uint8_t)date, &bill);
- ret |= flag;
- if ((uint8_t)(date >> 16) != bill.date[0] || (uint8_t)(date >> 8) != bill.date[1] || (uint8_t)(date & 0xff) != bill.date[2] // rec time is not intend to read
- || flag != 0)
- {
- ret |= 1;
- for (j = 0; j < 12; j++)
- data[i * 12 + j] = 0;
- continue;
- }
- data[i * 12] = 0x14; // 20
- data[i * 12 + 1] = bill.date[0]; // 年
- data[i * 12 + 2] = bill.date[1]; // 月
- data[i * 12 + 3] = bill.date[2]; // 日
- data[i * 12 + 4] = (unsigned char)(bill.fw_used);
- data[i * 12 + 5] = (unsigned char)(bill.fw_used >> 8);
- data[i * 12 + 6] = (unsigned char)(bill.fw_used >> 16);
- data[i * 12 + 7] = (unsigned char)(bill.fw_used >> 24);
- data[i * 12 + 8] = (unsigned char)(bill.bw_used);
- data[i * 12 + 9] = (unsigned char)(bill.bw_used >> 8);
- data[i * 12 + 10] = (unsigned char)(bill.bw_used >> 16);
- data[i * 12 + 11] = (unsigned char)(bill.bw_used >> 24);
- }
- if (ret != 0)
- return -1;
- else
- return 0;
- }
- ////////////////////////读取结数据//////////////////////////////////////////
- // 参数1:读取的年月日
- /////////////////////////////////////////////////////////////////////////////////////
- int8_t get_hour_record_data(uint8_t year, uint8_t month, uint8_t day, uint8_t *data)
- {
- uint8_t i;
- hour_bill_t bill;
- int32_t days;
- // 1. 默认填零
- memset(data, 0, 244);
- // 2. 检查时间有效性
- days = get_days_between_now(year, month, day);
- // 假设:有效范围为过去30天内(含今天,即0~30天)
- // 如果 get_days_between_now 返回负数表示未来,正数表示过去
- if (days < 0 || days > 30)
- {
- return 0; // 不在30天内,返回全零(已memset)
- }
- // 3. 读取数据
- // 注意:请确认 get_hour_used_bill 的正确用法。
- // 如果原代码 (uint8_t)date 是bug,这里应该传入正确的参数。
- // 假设 get_hour_used_bill 需要 year, month, day, hour
- // 由于我不知道 get_hour_used_bill 的确切签名,以下代码假设它需要修正以支持年月日
- // 如果原系统确实只传 day 就能工作(例如底层驱动自动处理环形缓冲或当前月),则保留原调用方式但需注意局限性。
- for (i = 0; i < 24; i++)
- {
- // 【重要】原代码这里强转 uint8_t 丢失了年月信息,极大概率是Bug。
- // 如果 get_hour_used_bill 只能接受 uint8_t day,请确认它是否能正确读取指定年月的数据。
- // 如果不能,你需要修改 get_hour_used_bill 或在此处提供完整日期上下文。
- // 暂时沿用原调用方式,但加上注释警示
- if (get_hour_used_bill(day, i, &bill) == 0)
- {
- if (bill.date[0] != year || bill.date[1] != month || bill.date[2] != day || bill.date[3] != i) // if rec time is not valid drop it
- continue;
- data[0] = 0x14; // 标记有效? 原代码在循环外设置 data[0]=0x14, 这里如果部分失败怎么处理?
- // 原代码逻辑:只要进入else,data[0]就被设为0x14。
- // 如果某个小时失败,bill是全零,拷贝进去也是零。
- memcpy(&data[4 + i * 3], bill.fw_used, 3);
- memcpy(&data[4 + 72 + i * 3], bill.bw_used, 3);
- data[4 + 144 + i] = bill.pressure;
- memcpy(&data[4 + 168 + i * 3], bill.flow_rate, 3);
- }
- // 如果读取失败,data对应位置保持为0(因为开头memset了)
- }
- // 设置头部信息,表示这是一条有效的记录结构(即使内容为0)
- data[0] = 0x14;
- data[1] = year;
- data[2] = month;
- data[3] = day;
- return 0;
- }
- ////////////////////////////////比较两个时间的大小///////////////////////////////////////////
- // 参数1,2,用于比较的两个时间结构体
- // 返回:date1>date2时返回1,相等时返回0,date1<date2时返回-1
- ///////////////////////////////////////////////////////////////////////////////////////////
- int8_t datecmp(tm_t date1, tm_t date2)
- {
- if (date1.year > date2.year)
- return 1;
- else if (date1.year < date2.year)
- return -1;
- if (date1.month > date2.month)
- return 1;
- else if (date1.month < date2.month)
- return -1;
- if (date1.day > date2.day)
- return 1;
- else if (date1.day < date2.day)
- return -1;
- if (date1.hour > date2.hour)
- return 1;
- else if (date1.hour < date2.hour)
- return -1;
- if (date1.min > date2.min)
- return 1;
- else if (date1.min < date2.min)
- return -1;
- if (date1.sec > date2.sec)
- return 1;
- else if (date1.sec < date2.sec)
- return -1;
- return 0;
- }
- //////////////////////////////////获取5分钟密集数据///////////////////////////////////////////////////////////
- // 参数get_5min_record_data:保存读取的起始时间和终止时间,
- // 参数numb:读取的序号,0表示读取第一组数据,
- // 返回1:表示读取成功 2:表示读取失败,3:读取成功,最后一帧数据
- int8_t get_5min_record_data(GET_5MIN_REOCORD_DEF *get_5min_record_info, uint16_t numb, uint8_t *data)
- {
- uint8_t ret = 0;
- uint8_t i;
- hour_bill_t bill;
- tm_t query_time; // 用户逻辑上的查询时间点(例如 10:00)
- tm_t index_time; // 底层存储使用的索引时间点(例如 10:05)
- tm_t start_time;
- // 1. 初始化输出缓冲区
- memset(data, 0, 24 * 16);
- // 2. 解析起始时间 (用户传入的 start_time)
- start_time.year = get_5min_record_info->start_time[0];
- start_time.month = get_5min_record_info->start_time[1];
- start_time.day = get_5min_record_info->start_time[2];
- start_time.hour = get_5min_record_info->start_time[3];
- start_time.min = get_5min_record_info->start_time[4];
- start_time.sec = 0;
- // 3. 计算当前页的起始查询时间
- // 每页 24 个点 * 5 分钟 = 120 分钟 = 7200 秒
- uint32_t offset_seconds = (uint32_t)numb * 24 * 5 * 60;
- memcpy(&query_time, &start_time, sizeof(tm_t));
- if (offset_seconds > 0)
- {
- time_add_secs(&query_time, &query_time, offset_seconds);
- }
- // 4. 循环读取 24 个点
- for (i = 0; i < 24; i++)
- {
- // 【关键修正】:因为底层存储使用“区间末尾时间”作为标记
- // 所以查询 10:00 的数据,实际要用 10:05 去查
- memcpy(&index_time, &query_time, sizeof(tm_t));
- time_add_secs(&index_time, &index_time, 5 * 60);
- // 5. 调用底层读取函数
- // 使用 index_time (末尾时间) 进行查询
- // 【严重警告】:请确认 get_5min_used_bill 能正确处理 index_time 的年月!
- // 如果它只能处理当前月,查询历史数据必错。
- uint8_t flag = get_5min_used_bill(index_time.day, index_time.hour, index_time.min, &bill);
- if (flag != 0)
- {
- // 读取失败,该点数据保持为 0
- ret |= 1;
- }
- else if (bill.date[0] != index_time.year || bill.date[1] != index_time.month || bill.date[2] != index_time.day || bill.date[3] != index_time.hour)
- {
- ret |= 1;
- }
- else
- {
- // 填充数据
- data[i * 16] = 0x14; // 标记有效
- data[1 + i * 16] = bill.date[0];
- data[2 + i * 16] = bill.date[1];
- data[3 + i * 16] = bill.date[2];
- data[4 + i * 16] = bill.date[3];
- // 注意:这里返回给上层的分钟数,应该填 query_time.min (用户请求的逻辑时间)
- // 还是 index_time.min (底层存储的物理时间)?
- // 通常协议要求返回“数据所属的时间点”。如果用户查 10:00,期望看到 10:00 或 10:05?
- // 根据原代码 logic: data[5 + i * 16] = (uint8_t)dest.min; (原代码用的是查询时间)
- // 建议保持一致性,如果上层知道这是5分钟数据,通常展示开始时间或结束时间需统一。
- // 这里暂且填入 index_time.min (10:05),因为这是数据的真实标记。
- data[5 + i * 16] = index_time.min;
- memcpy(&data[6 + i * 16], bill.fw_used, 10);
- }
- // 6. 移动到下一个查询点 (逻辑时间 + 5分钟)
- time_add_secs(&query_time, &query_time, 5 * 60);
- }
- return ret ? -2 : 0;
- }
- //////////////////////////////读取日志信息///////////////////////////////////////////
- // 参数:日志信息存储指针data, 一个30*13个字节
- // 返回1:成功, 0:失败
- /////////////////////////////////////////////////////////////////////////
- int8_t get_log_record(uint8_t start, uint8_t num, uint8_t *data)
- {
- alarm_t alarm;
- uint8_t i;
- if (num > 30)
- num = 30;
- memset(data, 0, 30 * 13); // 先清零存储器
- for (i = 0; i < num; i++)
- {
- if (read_alarm(start + i, &alarm) == 1)
- { // 读取成功
- memcpy(data, alarm.time, 7);
- data[7] = alarm.err_no;
- data[8] = alarm.type;
- memcpy(&data[9], alarm.arg, 4);
- }
- data += 13;
- }
- return 0;
- }
- /////////////////////////////设置声道数/////////////////////////////////////////////
- int8_t set_channel_numb(uint8_t *numb)
- {
- /*
- if (*numb == 0 || *numb > 4)
- return -2;
- uint8_t flag = 0, ret = 0;
- // 判断数据是否在正常范围内
- ret = set_para_if_nessary(numb, &Paramx.chan_num, 1, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- */
- return 0;
- }
- ////////////////////////////////读表地址/////////////////////////////////////////////////
- int8_t get_device_addr(uint8_t *data)
- {
- memcpy(data, Paramx.dev_id, sizeof(Paramx.dev_id));
- return 0;
- }
- ////////////////////////////////设置表地址////////////////////////////////////////////////
- int8_t set_device_addr(uint8_t *data)
- {
- uint8_t flag = 0, ret = 0;
- // 判断数据是否在正常范围内
- ret = set_para_if_nessary(data, &Paramx.dev_id, 6, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- ////////////////////////////////设置流量参数////////////////////////////////////////////
- // 参数flow_para指针保存8个流量数据,其中index成员是温度等级范围0~2
- ////////////////////////////////////////////////////////////////////////////////////////
- int8_t set_flow_para(FLOW_PARA_DEF *flow_para)
- {
- uint8_t flag = 0, ret = 0;
- // 判断数据是否在正常范围内
- uint8_t ser = CheckTempRangeIndex((float)flow_para->temp);
- if (ser > 2)
- return 2; // 温度等级确定的序号,一共3个温度等级
- ret = set_para_if_nessary(flow_para->cur_c, Paramx.check_spdLvl_c[ser].cur_c, 16, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- /////////////////////////////读取流量参数///////////////////////////////////////////
- // 参数flow_para指针保存流量信息,读取前应设置成员index值,范围0~2表示温度等级
- ////////////////////////////////////////////////////////////////////////////////////
- int8_t get_flow_para(FLOW_PARA_DEF *flow_para)
- {
- uint8_t i;
- uint8_t ser = CheckTempRangeIndex((float)flow_para->temp);
- for (i = 0; i < 8; i++)
- {
- flow_para->cur_c[i] = Paramx.check_spdLvl_c[ser].cur_c[i];
- }
- return 0;
- }
- /////////////////////////////////设置deltaTC流量参数/////////////////////////////////////////////////////////////
- // 参数deltaTC_para保存相关参数,temp是温度值,整型
- /////////////////////////////////////////////////////////////////////////////////
- int8_t set_deltaTC_flow_para(DELTA_TC_FLOW_PARA_DEF *deltaTC_para)
- {
- uint8_t flag = 0, ret = 0;
- const uint16_t base_data[8] = {1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340};
- // 判断数据是否在正常范围内
- uint8_t ser = CheckTempRangeIndex((float)deltaTC_para->temp);
- if (ser > 2)
- return 2; // 温度等级确定的序号,一共3个温度等级
- ret = set_para_if_nessary(deltaTC_para->cur_c, Paramx.check_spdLvl_c[ser].cur_c, 16, &flag); // 参数整体保存
- ret |= set_para_if_nessary(deltaTC_para->spd_lvl, Paramx.check_spdLvl_c[ser].spd_lvl, 16, &flag); // 参数整体保存
- ret |= set_para_if_nessary((uint16_t *)base_data, Paramx.check_spdLvl_c[ser].base_c, 16, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- /////////////////////读取参数deltaTC_para参数///////////////////////////////////
- ///////////////参数中temp是温度值,
- // 返回1:成功 2:失败
- //////////////////////////////////////////////////////////////////////////
- int8_t get_deltaTC_flow_para(DELTA_TC_FLOW_PARA_DEF *deltaTC_para)
- {
- uint8_t ser = CheckTempRangeIndex((float)deltaTC_para->temp);
- if (ser > 2)
- return 2; // 超出范围
- uint8_t i;
- for (i = 0; i < 8; i++)
- {
- deltaTC_para->cur_c[i] = Paramx.check_spdLvl_c[ser].cur_c[i];
- deltaTC_para->spd_lvl[i] = Paramx.check_spdLvl_c[ser].spd_lvl[i];
- }
- return 0;
- }
- ////////////////////////设置口径和温度补偿值////////////////////////////////////////////////////////
- // 返回1:成功,2失败
- /////////////////////////////////////////////////////////////////////////////////////////////////////
- int8_t set_diameter_and_quad_cell_data(uint16_t diameter, void *quad_cell_data)
- {
- uint8_t flag = 0, ret = 0;
- if (diameter != 0)
- { // 添加不为零判断
- ret = set_para_if_nessary(&diameter, &Paramx.diameter, sizeof(Paramx.diameter), &flag); // 保存直径数据
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- }
- ret |= eeprom_MassWrite(quad_cell_data, QUAD_CELL_START_ADDR, sizeof(Quad_Cell_t) * Quad_Cell_NUM);
- get_quad_cell_data(Quad_Cell_Ary);
- return (ret == 0 ? 0 : -1);
- }
- ////////////////////////读取温度补偿值 在初始化时调用////////////////////////////////////////////////////////
- // 参数data指向要存储的参数 其中包括125个温度补偿数据和一个直径数据
- // 返回1:成功,2失败
- /////////////////////////////////////////////////////////////////////////////////////////////////////
- int8_t get_quad_cell_data(void *quad_cell_data)
- {
- uint8_t ret = 0;
- ret = eeprom_MassRead(quad_cell_data, QUAD_CELL_START_ADDR, sizeof(Quad_Cell_t) * Quad_Cell_NUM);
- return ret;
- }
- ////////////////////// 判断温度补偿数据是否合法////////////////////////////////
- // 合法返回 0, 不合法返回-1
- //////////////////////////////////////////////////////
- int8_t Check_quad_cell_data_valid(uint32_t quad_cell_addr)
- {
- float temp[4];
- uint8_t i;
- for (i = 0; i < (Quad_Cell_NUM * 5) / 4; i++)
- {
- eeprom_MassRead((uint8_t *)temp, (uint32_t)quad_cell_addr + i * sizeof(float) * 4, sizeof(float) * 4);
- if (temp[0] < -100 || temp[0] > 50000 ||
- temp[1] < -100 || temp[1] > 50000 ||
- temp[2] < -100 || temp[2] > 50000 ||
- temp[3] < -100 || temp[3] > 50000)
- return -1;
- }
- return 0;
- }
- ///////////////////////设置自动匹配电平参数///////////////////////////////////////////////
- // 参数指针data 包含比较器和比较器门槛和门槛宽度
- /////////////////////////////////////////////////////////////////////////////////////
- int8_t set_auto_match_level_para(AUTO_MATCH_LEVEL_PARA_DEF *data)
- {
- uint8_t flag = 0, ret = 0;
- ret = set_para_if_nessary(data, &Paramx.cmp_thers, 30, &flag); // 保存直径数据
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- /////////////保存skew参数/////////////////////
- /////////////////////////////////
- int8_t set_skew_para(SKEW_PARA_DEF *skew_para)
- {
- uint8_t flag = 0, ret = 0;
- ret = set_para_if_nessary(skew_para, &Paramx.path_skew, 16, &flag); // 保存直径数据
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- ////////////////////////////设置nb已选择频段标志/////////////////////////////////
- int8_t set_nb_band(void)
- {
- uint8_t flag = 0, ret = 0;
- uint8_t dat=0;
- // 判断数据是否在正常范围内
- ret = set_para_if_nessary(&dat, &Paramx.nb_band_flag, 1, &flag); // 参数整体保存
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ?: -1);
- }
- ////////////////////////////读取自动匹配电平参数/////////////////////////////////////////////
- // 参数指针保存比较器和比较器门槛宽度数据
- // 返回1读取成功
- ////////////////////////////////////////////////////////////////////
- int8_t get_auto_match_level_para(AUTO_MATCH_LEVEL_PARA_DEF *data)
- {
- memcpy((uint8_t *)data, Paramx.cmp_thers, sizeof(AUTO_MATCH_LEVEL_PARA_DEF));
- return 0;
- }
- int8_t set_nbqr_para(NBQR_PARA_DEF *nbqr_para)
- {
- uint8_t flag = 0, ret = 0;
- ret = set_para_if_nessary(nbqr_para, &Paramx.n, sizeof(NBQR_PARA_DEF), &flag); // 保存直径数据
- if (flag == 1)
- { // 保存crc校验
- ret |= set_crc_check_para();
- }
- return (ret == 0 ? 0 : -1);
- }
- int8_t get_bnqr_para(NBQR_PARA_DEF *nbqr_para)
- {
- nbqr_para->n = Paramx.n;
- nbqr_para->b = Paramx.b;
- nbqr_para->q = Paramx.q;
- nbqr_para->r = Paramx.r;
- return 0;
- }
- uint16_t pack_crc_check(uint16_t prev_data, uint8_t *data, uint16_t len)
- {
- uint16_t i, crc;
- uint8_t index;
- for (i = 0; i < len; i++)
- {
- index = (uint8_t)(data[i] ^ (prev_data >> 8));
- crc = (uint16_t)(ccitt_table[index] ^ (prev_data << 8));
- prev_data = crc;
- }
- return crc;
- }
- ///////////////////1秒一次运行的一些零星任务//////////////////////
- uint8_t rtc_1s_flag;
- void run_clk_task_handler(void)
- {
- check_rewrite_para(); // 相关参数判断,不合法的重写eeprom
- rtc_1s_flag=1;
- }
- //////////////////////////////////////
- ///////////检查是否是新app第一次运行,如果是,则更新flash中的运行信息//////////////////
- // 参数:无
- // 返回:无
- ////////////////////////////////////////////////////////////////////////////////////
- void update_run_app_info(void)
- {
- if (StartUp != 5)
- return;
- PatchInfo = *(PATCH_INFO_DEF *)DIFF_UPDATE_INFO_START; // 整个结构体一起拷贝
- #ifdef APP_DEBUG_PRINT
- if (PatchInfo.update_status == 3)
- {
- LOG("new app first run\r\n");
- }
- else
- {
- LOG("old app run run\r\n");
- }
- LOG("cur ver = V%d.%d.%d.%d\r\n", VER_TYPE, VER_OPERATOR, VER_MODULE, VER_FIRMWARE);
- #endif
- if (PatchInfo.update_status != 0)
- {
- memset(&PatchInfo, 0, sizeof(PATCH_INFO_DEF));
- write_flash_memory((uint8_t *)&PatchInfo, DIFF_UPDATE_INFO_START, sizeof(PATCH_INFO_DEF));
- }
- #ifndef DEBUG_RESET_LOG_NOT_SEND
- write_alarm(LOG_MCU_RESET, 1, 5555); // wxl2026-5-8 非调试状态写入单片机复位事件日志
- #endif
- }
- void write_flash_memory(uint8_t *data, uint32_t addr, uint32_t len)
- {
- McuFlash_WP_t WP;
- feed_dog();
- rt_enter_critical();
- McuFlash_Unlock();
- McuFlash_OpenWP(addr, &WP);
- McuFlash_Buf2WP(data, len, &WP);
- McuFlash_CloseWP(&WP);
- McuFlash_Lock();
- rt_exit_critical();
- }
- void erase_flash_memory(uint32_t addr, uint32_t size)
- {
- feed_dog();
- rt_enter_critical();
- McuFlash_Unlock();
- McuFlash_EraseSegment(addr, size);
- McuFlash_Lock();
- rt_exit_critical();
- }
- const uint16_t ccitt_table[256] = {
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
- 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
- 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
- 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
- 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
- 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
- 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
- 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
- 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
- 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
- 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
- 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
- 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
- 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
- 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
- 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
- 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
- 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
- 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
- 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
- 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
- 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
- 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
|