/* ********************************************************************************************************* * IAR Development Kits * on the * * M451 * * Filename : flash_config.h * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #include "includes.h" // Flash存储规划如下: // 0~7K: boot-loader,解压程序,由LDROM调入内存执行 // 8~11K: 配置数据(2K+2K,双份存储) // 12~15K:保留 // 16~255K: 保留(以后可能用于存放16点阵的字库,现为了烧录方便,是放在程序里面) // 256~511K:升级包 // 512K~8M: 保留(以后可能用于存放GPRS采集数据,现放在铁电里面) // 每个配置块划分为4组配置 #define CONFIG_DC_SIZE (DATA_BUFF_SIZE) // 配置分块大小(每个分区划为4个块,循环覆盖写入) #define CONFIG_BLOCK_SIZE (CONFIG_DC_SIZE * 4) // 配置分区大小:主分区=镜像分区=可擦除页大小 #define CONFIG_PARTITION_SIZE (CONFIG_BLOCK_SIZE * 4) // 分区号: 0~1, 分块号: 0~3,分组号: 0~3 #define CONFIG_PARTITION(partition) (partition) #define CONFIG_BLOCK(block) (block) #define CONFIG_DC(DC) ((DC) - 1) // 读写Flash的临时缓冲 static rd_buff_t rdBuff; // 读写Flash的缓冲 uint8_t Config_rwBuf[CONFIG_BLOCK_SIZE] = {0}; // 扩展内存 static uint32_t Flash_ErasePartition(uint8_t partition) { uint8_t i, loop = CONFIG_PARTITION_SIZE / SFLASH_ERASE_SIZE; uint32_t u32StartAddr = SFLASH_CONFIG_BASE + CONFIG_PARTITION(partition) * CONFIG_PARTITION_SIZE; for(i = 0; i < loop; i++) { SFlash_WriteEN(); SFlash_PageErase(u32StartAddr + i * SFLASH_ERASE_SIZE); } return TRUE; } static uint32_t Flash_ReadDC(uint8_t partition, uint8_t block, uint8_t DC, rd_buff_t *dataBuff) { uint32_t u32StartAddr = SFLASH_CONFIG_BASE + CONFIG_PARTITION(partition) * CONFIG_PARTITION_SIZE + CONFIG_BLOCK(block) * CONFIG_BLOCK_SIZE + CONFIG_DC(DC) * CONFIG_DC_SIZE; SFlash_BufferRead(u32StartAddr, dataBuff->buff, CONFIG_DATA_LEN(DC)); return TRUE; } static uint32_t Flash_ReadBlock(uint8_t partition, uint8_t block, uint32_t forTest) { // 采集板存储配置区1、2、3的数据 if(CONFIG_BOARD_SELF == CONFIG_BOARD_SAMPLE || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) { if(!Flash_ReadDC(partition, block, CAN_DC_BOTTLE_CONFIG, &rdBuff) || !Config_CheckValid(&rdBuff, CAN_DC_BOTTLE_CONFIG)) return FALSE; if(forTest) return TRUE; dcBuff.configBottle = rdBuff.configBottle; if(!Flash_ReadDC(partition, block, CAN_DC_SENSOR_CONFIG, &rdBuff) || !Config_CheckValid(&rdBuff, CAN_DC_SENSOR_CONFIG)) return FALSE; dcBuff.configSensor = rdBuff.configSensor; if(!Flash_ReadDC(partition, block, CAN_DC_DATA_CONFIG, &rdBuff) || !Config_CheckValid(&rdBuff, CAN_DC_DATA_CONFIG)) return FALSE; dcBuff.configData = rdBuff.configData; } // 电源板存储配置区4的数据 if(CONFIG_BOARD_SELF == CONFIG_BOARD_POWER || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) { if(!Flash_ReadDC(partition, block, CAN_DC_DISPLAY_CONFIG, &rdBuff) || !Config_CheckValid(&rdBuff, CAN_DC_DISPLAY_CONFIG)) return FALSE; if(CONFIG_BOARD_SELF == CONFIG_BOARD_POWER) { if(forTest) return TRUE; } dcBuff.configDisplay = rdBuff.configDisplay; } return TRUE; } static uint32_t Flash_ReadConfig(uint8_t partition, uint32_t forTest, uint8_t *blockNo) { uint8_t block; for(block = 0; block < 4; block++) { if(Flash_ReadBlock(partition, block, forTest)) { *blockNo = block; return TRUE; } } return FALSE; } static uint32_t Flash_WriteConfig(uint8_t partition) { uint8_t block = 0; uint8_t i; uint32_t u32StartAddr; // 读取现有配置数据的块号 if(!Flash_ReadConfig(partition, TRUE, &block)) block = 3; for(i = 0; i < 4; i++) { // 确定循环写入的块号 block = (block + 1) % 4; if(!Flash_ErasePartition(partition)) return FALSE; memset(Config_rwBuf, 0xFF, CONFIG_BLOCK_SIZE); // 采集板存储配置区1、2、3的数据 if(CONFIG_BOARD_SELF == CONFIG_BOARD_SAMPLE || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) { rdBuff.configBottle = dcBuff.configBottle; memmove(Config_rwBuf + CONFIG_DC(CAN_DC_BOTTLE_CONFIG) * CONFIG_DC_SIZE, rdBuff.buff, CONFIG_DATA_LEN(CAN_DC_BOTTLE_CONFIG)); rdBuff.configSensor = dcBuff.configSensor; memmove(Config_rwBuf + CONFIG_DC(CAN_DC_SENSOR_CONFIG) * CONFIG_DC_SIZE, rdBuff.buff, CONFIG_DATA_LEN(CAN_DC_SENSOR_CONFIG)); rdBuff.configData = dcBuff.configData; memmove(Config_rwBuf + CONFIG_DC(CAN_DC_DATA_CONFIG) * CONFIG_DC_SIZE, rdBuff.buff, CONFIG_DATA_LEN(CAN_DC_DATA_CONFIG)); } // 电源板存储配置区4的数据 if(CONFIG_BOARD_SELF == CONFIG_BOARD_POWER || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) { rdBuff.configDisplay = dcBuff.configDisplay; memmove(Config_rwBuf + CONFIG_DC(CAN_DC_DISPLAY_CONFIG) * CONFIG_DC_SIZE, rdBuff.buff, CONFIG_DATA_LEN(CAN_DC_DISPLAY_CONFIG)); } u32StartAddr = SFLASH_CONFIG_BASE + CONFIG_PARTITION(partition) * CONFIG_PARTITION_SIZE + CONFIG_BLOCK(block) * CONFIG_BLOCK_SIZE; if(SFlash_BufferWrite(u32StartAddr, Config_rwBuf, CONFIG_BLOCK_SIZE)) return TRUE; } return FALSE; } uint32_t Config_LoadConfig() { uint8_t block; if(Flash_ReadConfig(0, FALSE, &block)) return TRUE; return Flash_ReadConfig(1, FALSE, &block); } uint32_t Config_SaveConfig() { uint32_t ret = 1, ret1 = 1; Config_ForceValid((rd_buff_t *) &dcBuff.configBottle, CAN_DC_BOTTLE_CONFIG); Config_ForceValid((rd_buff_t *) &dcBuff.configSensor, CAN_DC_SENSOR_CONFIG); Config_ForceValid((rd_buff_t *) &dcBuff.configData, CAN_DC_DATA_CONFIG); Config_ForceValid((rd_buff_t *) &dcBuff.configDisplay, CAN_DC_DISPLAY_CONFIG); // 贴片厂测试软件关闭 ret = Flash_WriteConfig(0); ret1= Flash_WriteConfig(1); return ret || ret1; } void Config_Init() { } void Config_Open() { uint16_t i; extern const uint16_t LSrc_DensityExt[]; uint32_t ret =0; // 分配扩展内存 // Config_rwBuf = SRAM_Alloc(CONFIG_BLOCK_SIZE); delay_ms(20); SFlash_UnlockBPR(); // 设置默认参数(默认参数由另一个程序写入,本程序只读出来用) // 贴片厂测试软件打开 // Config_setBottleDefParam(&dcBuff); // Config_setSensorDefParam(&dcBuff); // Config_setDataDefParam(&dcBuff); // Config_setDisplayDefParam(&dcBuff); // dcBuff.configDisplay.op_LOCAL_DISP = 1; // 读取保存的配置 // 贴片厂测试软件关闭 ret=Config_LoadConfig(); printf("\n\t***load data %d ***\n",ret); if(ret==0) { Config_setBottleDefParam(&dcBuff); Config_setSensorDefParam(&dcBuff); Config_setDataDefParam(&dcBuff); Config_setDisplayDefParam(&dcBuff); Config_SaveConfig(); } // 测试代码 //// dcBuff.configBottle.PSN[0] = 19; // PSN: 2019041580002 //// dcBuff.configBottle.PSN[1] = 4; //// dcBuff.configBottle.PSN[2] = 18; //// dcBuff.configBottle.PSN[3] = 80; //// dcBuff.configBottle.PSN[4] = 0; //// dcBuff.configBottle.PSN[5] = 3; //// Config_SaveConfig(); //// dcBuff.configData.intervalTrans = 120; // 修改普莱克斯和林德的维护平台地址 if(dcBuff.configBottle.serverVer == 3 || dcBuff.configBottle.serverVer == 4) { strcpy(dcBuff.configData.upgServer, dcBuff.configData.server); } // 液位计:修正默认参数 if(dcBuff.configDisplay.op_PRODUCT_CLASS != PRODUCT_CLASS_LEVEL) { dcBuff.configDisplay.op_PRODUCT_CLASS = PRODUCT_CLASS_LEVEL; if(!dcBuff.configDisplay.op_DOL_VER) { dcBuff.configSensor.sensorPress.lowRange = 0; // 0MPa dcBuff.configSensor.sensorPress.highRange = 4000; // 4MPa dcBuff.configSensor.sensorPress.zeroValue = 683; // 理论值:0.5v / 3.0v dcBuff.configSensor.sensorPress.fullValue = 3823; // 理论值:2.8v / 3.0v } else { dcBuff.configSensor.sensorPress.lowRange = 0; // 0MPa dcBuff.configSensor.sensorPress.highRange = 5000; // 5MPa dcBuff.configSensor.sensorPress.zeroValue = 710; // 理论值:4mA * 130Ω / 3.0v dcBuff.configSensor.sensorPress.fullValue = 3550; // 理论值:20mA * 130Ω / 3.0v } dcBuff.configBottle.warnPress = 300; // 压力报警点 dcBuff.configDisplay.L_Unit = UNIT_PCT; // 显示单位 // 保存 Config_SaveConfig(); } // 新增介质密度 for(i = 0; i < sizeof(dcBuff.configBottle.densityExt) / sizeof(uint16_t); i++) { if(dcBuff.configBottle.densityExt[i] == 0) dcBuff.configBottle.densityExt[i] = LSrc_DensityExt[i]; } // 新增温度报警参数 if(dcBuff.configBottle.serverVer != 3 && dcBuff.configBottle.warnTemprH == 0 && dcBuff.configBottle.warnTempr == 0) { dcBuff.configBottle.warnTemprH = -300; dcBuff.configBottle.warnTempr = -300; } //// // 特定设备的参数修改 //// if(dcBuff.configBottle.PSN[0] == 21 && dcBuff.configBottle.PSN[1] == 6 && dcBuff.configBottle.PSN[2] == 25 //// && dcBuff.configBottle.PSN[3] == 10 && dcBuff.configBottle.PSN[4] == 1 //// && dcBuff.configBottle.PSN[5] == 3 //// && dcBuff.configDisplay.op_HARDWARE_VER_MAJOR != 233) //// { //// dcBuff.configDisplay.op_HARDWARE_VER_MAJOR = 233; //// dcBuff.configDisplay.op_ALARM_OUTPUT = 1; //// dcBuff.configDisplay.op_LOW_ALARM_OUTPUT = 1; //// dcBuff.configDisplay.op_PRESS_ALARM_OUTPUT = 1; //// dcBuff.configDisplay.op_LOW_PRESS_ALARM_OUTPUT = 1; //// dcBuff.configBottle.fullPct = 9300; //// dcBuff.configBottle.emptyPct = 1000; //// dcBuff.configBottle.warnPress = 0; //// dcBuff.configBottle.warnPressH = 800; //// Config_SaveConfig(); //// } // 填充采集板系统信息 if(CONFIG_BOARD_SELF == CONFIG_BOARD_SAMPLE || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) Config_fillSampleInfo(&dcBuff); // 填充电源板系统信息 if(CONFIG_BOARD_SELF == CONFIG_BOARD_POWER || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) Config_fillPowerInfo(&dcBuff); // 填充显示板系统信息 if(CONFIG_BOARD_SELF == CONFIG_BOARD_DISPLAY || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) Config_fillDisplayInfo(&dcBuff); // 填充蓝牙板系统信息 if(CONFIG_BOARD_SELF == CONFIG_BOARD_BLUETOOTH || CONFIG_BOARD_SELF == CONFIG_BOARD_SINGLE) Config_fillBluetoothInfo(&dcBuff); // 显示版本及配置信息 printf("\n****\tPSN: 20%02d%02d%02d%02d%03d ****\n", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); //apex dcBuff.powerInfo.hardVer.major = 232; dcBuff.configDisplay.op_LOW_ALARM_OUTPUT=1; dcBuff.configDisplay.op_ALARM_OUTPUT=1; dcBuff.configDisplay.op_PRESS_ALARM_OUTPUT = 1; dcBuff.configDisplay.op_LOW_PRESS_ALARM_OUTPUT=1; printf("\n****\tProductVer: %d ***\n", dcBuff.powerInfo.hardVer.minor); printf("\n****\tHardVer: %d, SoftVer: %d, protcolVer: %d, SoftDate: 20%02d-%02d-%02d ***\n", dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.softVer.minor, dcBuff.powerInfo.protocolVer.minor, dcBuff.powerInfo.softDate.year, dcBuff.powerInfo.softDate.month, dcBuff.powerInfo.softDate.day); if(dcBuff.configDisplay.op_DISP_MMWC_ONLY) printf("\n\t*** op_DISP_MMWC_ONLY = 1 ***\n"); if(dcBuff.configDisplay.op_DOL_VER) printf("\n\t*** op_DOL_VER = 1 ***\n"); if(dcBuff.configDisplay.op_BOX_VER) printf("\n\t*** op_BOX_VER = 1 ***\n"); if(dcBuff.configDisplay.op_CELL_LOCATION) printf("\n\t*** op_CELL_LOCATION = 1 ***\n"); if(dcBuff.configDisplay.op_NO_LOCATION) printf("\n\t*** op_NO_LOCATION = 1 ***\n"); if(dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY) printf("\n\t*** op_LEVEL_SENSOR_ONLY = 1 ***\n"); if(!dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY) { if(!dcBuff.configDisplay.op_USE_PT100_SENSOR) printf("\n\t*** op_USE_PT100_SENSOR = 0 ***\n"); if(dcBuff.configDisplay.op_USE_PT100_SENSOR && dcBuff.configDisplay.op_PT100_MULTI != 10) printf("\n\t*** op_PT100_MULTI = %d ***\n", dcBuff.configDisplay.op_PT100_MULTI); if(!dcBuff.configDisplay.op_PT100_3LINE) printf("\n\t*** op_PT100_3LINE = 0 ***\n"); if(!dcBuff.configDisplay.op_DIFF_RESIST) printf("\n\t*** op_DIFF_RESIST = 0 ***\n"); } if(dcBuff.configDisplay.op_SEND_GPS_DATA) printf("\n\t*** op_SEND_GPS_DATA = 1 ***\n"); if(dcBuff.configDisplay.op_USE_CAPACITY_SENSOR) printf("\n\t*** op_USE_CAPACITY_SENSOR = 1 ***\n"); if(dcBuff.configDisplay.op_LOCAL_DISP) printf("\n\t*** op_LOCAL_DISP = 1 ***\n"); if(dcBuff.configDisplay.op_LOCAL_DISP_1S) printf("\n\t*** op_LOCAL_DISP_1S = 1 ***\n"); if(dcBuff.configDisplay.op_ANTI_OVERFILL) printf("\n\t*** op_ANTI_OVERFILL = 1 ***\n"); if(dcBuff.configDisplay.op_ANTI_SINGLE_CTRL) printf("\n\t*** op_ANTI_SINGLE_CTRL = 1 ***\n"); if(dcBuff.configDisplay.op_ANTI_NORM_OPEN) printf("\n\t*** op_ANTI_NORM_OPEN = 1 ***\n"); if(dcBuff.configDisplay.op_ALARM_OUTPUT) printf("\n\t*** op_ALARM_OUTPUT = 1 ***\n"); if(dcBuff.configDisplay.op_LOW_ALARM_OUTPUT) printf("\n\t*** op_LOW_ALARM_OUTPUT = 1 ***\n"); if(dcBuff.configDisplay.op_PRESS_ALARM_OUTPUT) printf("\n\t*** op_PRESS_ALARM_OUTPUT = 1 ***\n"); if(dcBuff.configDisplay.op_LOW_PRESS_ALARM_OUTPUT) printf("\n\t*** op_LOW_PRESS_ALARM_OUTPUT = 1 ***\n"); if(dcBuff.configDisplay.op_DIFF_420MA) printf("\n\t*** op_DIFF_420MA = 1 ***\n"); if(dcBuff.configDisplay.op_PRESS_420MA) printf("\n\t*** op_PRESS_420MA = 1 ***\n"); if(dcBuff.configDisplay.op_2ND_420MA_OUT_LEVEL) printf("\n\t*** op_2ND_420MA_OUT_LEVEL = 1 ***\n"); if(dcBuff.configDisplay.op_USE_R0SEMOUNT) printf("\n\t*** op_USE_R0SEMOUNT = 1 ***\n"); if(dcBuff.configDisplay.op_USE_SOLAR) printf("\n\t*** op_USE_SOLAR = 1 ***\n"); if(dcBuff.configDisplay.op_USE_O2_LEAK) printf("\n\t*** op_USE_O2_LEAK = 1 ***\n"); if(dcBuff.configDisplay.op_LEAK_ALARM_OUTPUT) printf("\n\t*** op_LEAK_ALARM_OUTPUT = 1 ***\n"); if(dcBuff.configDisplay.op_USE_DOL_TTL) printf("\n\t*** op_USE_DOL_TTL = 1 ***\n"); if(dcBuff.configDisplay.op_USE_HEIGHT_LEVEL) printf("\n\t*** op_USE_HEIGHT_LEVEL = 1 ***\n"); if(dcBuff.configDisplay.op_USE_PCT_LEVEL) printf("\n\t*** op_USE_PCT_LEVEL = 1 ***\n"); if(dcBuff.configDisplay.op_LNG_LORA) printf("\n\t*** op_LNG_LORA = 1 ***\n"); if(dcBuff.configBottle.dispMode != DISP_MODE_ALL) printf("\n\t*** dispMode = %d ***\n", dcBuff.configBottle.dispMode); if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_MQTT) printf("\n*** op_SERVER_PROTOCOL:\tMQTT ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HTTPS) printf("\n*** op_SERVER_PROTOCOL:\tHTTPS ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HTTP) printf("\n*** op_SERVER_PROTOCOL:\tHTTP ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_TRAIN) printf("\n*** op_SERVER_PROTOCOL:\tTRAIN ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_AOYANG) printf("\n*** op_SERVER_PROTOCOL:\tAOYANG ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_BRASIL) printf("\n*** op_SERVER_PROTOCOL:\tBRASIL ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_FURUI) printf("\n*** op_SERVER_PROTOCOL:\tFURUI ***\n"); else if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_HUIDA) printf("\n*** op_SERVER_PROTOCOL:\tHUIDA ***\n"); else printf("\n*** op_SERVER_PROTOCOL:\tTCP ***\n"); printf("\n*** Server:\t%s:%d ***\n", dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_MQTT ? SERVER_URLs[dcBuff.configDisplay.op_SERVER_INDEX] : dcBuff.configData.server, dcBuff.configData.port); if(dcBuff.configDisplay.op_SERVER_PROTOCOL == SERVER_PROTOCOL_TCP && dcBuff.configDisplay.op_UNIDIR_COMM) printf("\n\t*** op_UNIDIR_COMM = 1 ***\n"); printf("\n*** Sample:\t%ds ***\n", dcBuff.configData.intervalSample); printf("\n*** Send:\t%ds ***\n", dcBuff.configData.intervalTrans); }