#include "main.h" #define BootloaderAddress 0X08000000 // 初始位置 #define FLASH_INIT_ADDR 0X08004000 // 呼吸心率上下限存储 #define FLASH_DATA_FLAG_ADDR 0x08008000 // FLASH_Sector_2 #define FLASH_VERSION_ADDR 0x0800C000 // FLASH_Sector_3 #define FLASH_OLDAPP_ADDR 0x08010000 // FLASH_Sector_4 #define FLASH_APP_ADDR 0x08080000 // FLASH_Sector_8 128Kb #define FLASH_DATA_FLAG 0x1010 // 准备升级 #define FLASH_START_FLAG 0x1111 // 升级完成 #define FLASH_OLD_FLAG 0x0101 // 启动老程序 /*************** FLASH_Sector_0 0x0800 0000 ~ 0x0800 3FFF (16KB)--bootloader FLASH_Sector_1 0x0800 4000 ~ 0x0800 7FFF (16KB)--呼吸心率上下限存储 FLASH_Sector_2 0x0800 8000 ~ 0x0800 BFFF (16KB)--标志位位置(FLASH_DATA_FLAG_ADDR) FLASH_Sector_3 0x0800 C000 ~ 0x0800 FFFF (16KB)--版本号位置(FLASH_VERSION_ADDR) FLASH_Sector_4 0x0801 0000 ~ 0x0801 FFFF (64KB)--固定程序位置(FLASH_OLDAPP_ADDR) FLASH_Sector_5 0x0802 0000 ~ 0x0803 FFFF (128KB) FLASH_Sector_6 0x0804 0000 ~ 0x0805 FFFF (128KB) FLASH_Sector_7 0x0806 0000 ~ 0x0807 FFFF (128KB) FLASH_Sector_8 0x0808 0000 ~ 0x0809 FFFF (128KB)--升级程序位置(FLASH_APP_ADDR) FLASH_Sector_9 0x080A 0000 ~ 0x080B FFFF (128KB) FLASH_Sector_10 0x080C 0000 ~ 0x080D FFFF (128KB) FLASH_Sector_11 0x080E 0000 ~ 0x080F FFFF (128KB) **************/ pFunction Jump_To_Application; uint32_t JumpAddress; uint32_t BlockNbr = 0, UserMemoryMask = 0; __IO uint32_t FlashProtection = 0; uint8_t wifi_frame_flg = 0; uint32_t wifi_len = 0; uint32_t wifi_len_500 = 0; uint32_t wifi_len_500_flg = 0; uint16_t wifi_signs_len = 13; // uint8_t wifi_opm_buf[500 * 4 + 100]; // 全部数据 // uint8_t wifi_opm_send_buf[500 * 4 + 100]; // 全部数据 uint8_t wifi_opm_send_buf[17]; // 全部数据 uint64_t timeClockCount = 0; uint64_t timeClockCount_Send = 0; uint8_t TimeClock_Flag = 0; uint8_t get_time_buf[13] = {0xA5, 0x5A, 0x0D, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t get_config_buf[13] = {0xA5, 0x5A, 0x0D, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 呼吸黄色警报 8(0x08)-25(0x19) // 呼吸红色警报 6-30 // 心率黄色警报 55(0x37)-100(0x64) // 心率红色警报 50-110 uint8_t get_breathe_buf[6] = {0x11, 0x11, 0x19, 0x08, 0x64, 0x37}; warning_config_t warning_config; extern float ON_BED_Threshold; extern float OFF_BED_Threshold; extern char Calibration_Off_Bed_Done_Flag; extern char Calibration_In_Bed_Done_Flag; typedef union UnionFloat2uint32 { float fValue; uint32_t uintValue; } UnionFloat2uint32_t; UnionFloat2uint32_t Float2uint32; /** * @brief 跳转到用户程序执行 * @param void * @retval none */ uint8_t Execute_user_Program(void) { __disable_irq(); if (((*(__IO uint32_t *)BootloaderAddress) & 0x2FFE0000) == 0x20000000) // 判断用户是否已经下载程序,防止跑飞 { // 跳转至用户代码 JumpAddress = *(__IO uint32_t *)(BootloaderAddress + 4); Jump_To_Application = (pFunction)JumpAddress; // 初始化用户程序的堆栈指针 __set_MSP(*(__IO uint32_t *)BootloaderAddress); Jump_To_Application(); } else { return 1; } return 0; } void upgradeVersion(void) { __disable_irq(); drv_flash_Init(); FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3); FLASH_ProgramWord(FLASH_DATA_FLAG_ADDR, FLASH_DATA_FLAG); FLASH_Lock(); NVIC_SystemReset(); } void version_upload(void) { wifi_crc_send(version, 8); delay_ms(100); } /** * @brief 处理系统命令 * @param void * @retval void */ char ResetCountTime = 0; char WarnConfigDoneFlag = 0; extern char PowerOn_StartConfigFlg; extern char PowerOn_OneMinuteCount_Start; char ConfirmUpgradeCountTime = 0; uint64_t OverTime = 0; void wifi_cmd_exe(void) { uint64_t *p; unsigned char pMem[8]; switch (USART1_RX_BUF[4]) { // 升级请求 case 0x10: // 防止进入升级界面 (红灯情况) if (USART1_RX_BUF[0] == 0xA5 && USART1_RX_BUF[1] == 0x5A && USART1_RX_BUF[2] == 0x01 && USART1_RX_BUF[3] == 0x00) ConfirmUpgradeCountTime++; if (ConfirmUpgradeCountTime >= 10) upgradeVersion(); break; case 0x12: // 下发心率呼吸值(上下限) get_breathe_buf[2] = USART1_RX_BUF[7]; get_breathe_buf[3] = USART1_RX_BUF[8]; get_breathe_buf[4] = USART1_RX_BUF[11]; get_breathe_buf[5] = USART1_RX_BUF[12]; Breathe_H = USART1_RX_BUF[7]; Breathe_L = USART1_RX_BUF[8]; HeartRate_H = USART1_RX_BUF[11]; HeartRate_L = USART1_RX_BUF[12]; drv_flash_Init(); FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3); flashWrite(get_breathe_buf, 6); // 写入flash,固定一包写6个字节 FLASH_Lock(); break; case 0x13: // 版本号请求 version_upload(); break; case 0x20: TIM_Cmd(TIM3, ENABLE); // 使能定时器3 pMem[0] = USART1_RX_BUF[5]; pMem[1] = USART1_RX_BUF[6]; pMem[2] = USART1_RX_BUF[7]; pMem[3] = USART1_RX_BUF[8]; pMem[4] = USART1_RX_BUF[9]; pMem[5] = USART1_RX_BUF[10]; pMem[6] = USART1_RX_BUF[11]; pMem[7] = USART1_RX_BUF[12]; p = (uint64_t *)pMem; timeClockCount = *p; // 配置完成 0 -> 1 TimeClock_Flag = 1; USART1_RX_BUF[0] = 0x00; // 清除头 timeClockCount_Send = timeClockCount; // 用于发送的时间戳赋值 LED_R = 1; LED_G = 1; LED_B = 1; break; case 0x0C: // 配网 if (Key_Cal_Flag == 1) // 配网中才进 { if (USART1_RX_BUF[5] == 01) // 开始配网 { LED_G = 1; LED_B = 0; PowerOn_StartConfigFlg = 1; delay_ms(200); } else if (USART1_RX_BUF[5] == 02) // 配网成功 { LED_R = 1; LED_B = 1; LED_G = 1; delay_ms(200); Key_Cal_Flag = 0; // 配网成功 TIM_Cmd(TIM3, ENABLE); // 使能定时器3 /* NVIC_SystemReset(); */ // 复位 } else if (USART1_RX_BUF[5] == 03) // 制造商成功 { Key_Cal_Flag = 0; LED_B = 1; LED_G = 0; delay_ms(1000); } } else if (Key_Cal_Flag == 0) // 刚启动检测 { if (USART1_RX_BUF[5] == 01 && PowerOn_OneMinuteCount_Start != 1) // 开始配网 { Key_Cal_Flag = 1; // NOTE: 此处 = 1导致重新配ID出现黑掉的情况 delay_ms(200); } else if (USART1_RX_BUF[5] == 02) // 配网成功 { delay_ms(200); } } break; case 0x0D: { sendFirmwareInfo(); } break; case 0x1A: // 预警信息下发解析 { uint32_t Buffer_CRC = 0; uint32_t CRC_Value = 0; uint8_t ack_buf[6]; for (char i = 0; i < 28; i++) { printf("%x ", USART1_RX_BUF[i]); } // CRC 校验 CRC_Value = OPENBL_CRC32_MPEG_2(USART1_RX_BUF + 5, 20); // 计算 memcpy(&Buffer_CRC, USART1_RX_BUF + 25, sizeof(CRC_Value)); printf("CRC_Value : %x ,Buffer_CRC :%x \n", CRC_Value, Buffer_CRC); if (Buffer_CRC != CRC_Value) break; warning_config.sex = USART1_RX_BUF[5]; // 性别 warning_config.age = USART1_RX_BUF[10]; // 年龄 warning_config.timeZone = USART1_RX_BUF[11]; // 时区 warning_config.height = (USART1_RX_BUF[6] << 8) + USART1_RX_BUF[7]; // 身高 warning_config.weight = (USART1_RX_BUF[8] << 8) + USART1_RX_BUF[9]; // 体重 warning_config.heart_min_th = USART1_RX_BUF[13]; // 心率最小值阈值 warning_config.heart_max_th = USART1_RX_BUF[14]; // 心率最大值阈值 warning_config.heart_keep_th = (USART1_RX_BUF[15] << 8) + USART1_RX_BUF[16]; // 心率告警持续时间 warning_config.breath_min_th = USART1_RX_BUF[18]; // 呼吸最小值阈值 warning_config.breath_max_th = USART1_RX_BUF[19]; // 呼吸最大值阈值 warning_config.breath_keep_th = (USART1_RX_BUF[20] << 8) + USART1_RX_BUF[21]; // 呼吸告警持续时间 warning_config.Move_keep_th = (USART1_RX_BUF[23] << 8) + USART1_RX_BUF[24]; // 体动告警持续时间 printf("warning_config.sex : %d \n", warning_config.sex); printf("warning_config.age : %d \n", warning_config.age); printf("warning_config.height : %d \n", warning_config.height); printf("warning_config.weight : %d \n", warning_config.weight); printf("warning_config.timeZone : %d \n", (signed char)warning_config.timeZone); printf("warning_config.heart_min_th : %d \n", warning_config.heart_min_th); printf("warning_config.heart_max_th : %d \n", warning_config.heart_max_th); printf("warning_config.breath_min_th : %d \n", warning_config.breath_min_th); printf("warning_config.breath_max_th : %d \n", warning_config.breath_max_th); printf("warning_config.Move_keep_th : %d \n", warning_config.Move_keep_th); printf("warning_config.heart_keep_th : %d \n", warning_config.heart_keep_th); printf("warning_config.breath_keep_th : %d \n", warning_config.breath_keep_th); // 接收到数据发送应答 ack_buf[0] = 0xA5; ack_buf[1] = 0x5A; ack_buf[2] = 0x06; ack_buf[3] = 0x00; ack_buf[4] = 0x1A; ack_buf[5] = 0x01; WarnConfigDoneFlag = 1; printf("Ack Send\r\n"); // TIM_Cmd(TIM3, ENABLE); // 使能定时器3 ,启动LED状态 // wifiSendMsgOneMoreTimes(wifi_opm_send_buf, 17, 3); for (char i = 0; i < 3; i++) { wifi_crc_send(ack_buf, sizeof(ack_buf)); delay_ms(100); } } break; case 0x0E: // 校准 参数上报 { CalValue_Upload(); break; } case 0x0F: // 校准 if (USART1_RX_BUF[2] == 02 && USART1_RX_BUF[3] == 00) { Key_Cal_Flag = 1; // 暂时不进行opm opm_cal_flag = 1; opm_cal_ready(); if (USART1_RX_BUF[5] == 01) // 第一次校准 { Calibration_In_Bed_Done_Flag = 1; Calibration_Off_Bed_Done_Flag = 0; sendOPMCalStatus(1, 1); } else if (USART1_RX_BUF[5] == 02) { Calibration_Off_Bed_Done_Flag = 1; sendOPMCalStatus(2, 1); } } break; case 0xFF: // 复位 if (USART1_RX_BUF[2] == 0x01 && USART1_RX_BUF[3] == 0x00) { printf("Count Time %d \r\n", ResetCountTime); ResetCountTime++; } if (ResetCountTime >= 10) { printf("Count Time Done !!!! \r\n"); NVIC_SystemReset(); } break; case 0xE5: if (USART1_RX_BUF[5] == 00) // MQTT断开 { TimeClock_Flag = 0; TIM_Cmd(TIM2, DISABLE); printf("MQTT Disconnected\n"); } else if (USART1_RX_BUF[5] == 01) // MQTT连上 { USART1_SendData(version, 8); printf("MQTT Connected\n"); for (char i = 0; i < 6; i++) { LED_B = 0; LED_G = 0; delay_ms(20); LED_R = 1; LED_G = 1; LED_B = 1; delay_ms(20); } } USART1_RX_BUF[0] = 0x00; // 清除头 break; default: break; } uart_flg = 0; uart_time = 0; USART_RX_Length = 0; // 状态寄存器清空 memset(USART1_RX_BUF, 0, sizeof(USART1_RX_BUF)); } uint32_t OPENBL_CRC32_MPEG_2(uint8_t *data, uint32_t length) { uint32_t i; uint32_t crc = 0xffffffff, j = 0; while ((length--) != 0) { crc ^= (uint32_t)data[j] << 24; j++; for (i = 0; i < 8; ++i) { if ((crc & 0x80000000) != 0) { crc = (crc << 1) ^ 0x04C11DB7; } else { crc <<= 1; } } } return crc; } void wifi_crc_send(uint8_t *data, uint32_t length) { uint32_t crc_temp, i; uint8_t crc[4]; crc_temp = OPENBL_CRC32_MPEG_2(data, length); crc[0] = (uint8_t)crc_temp; crc[1] = (uint8_t)(crc_temp >> 8); crc[2] = (uint8_t)(crc_temp >> 16); crc[3] = (uint8_t)(crc_temp >> 24); for (i = 0; i < length; i++) { UART_SendByte(USART1, (uint8_t)data[i]); } for (i = 0; i < 4; i++) { UART_SendByte(USART1, (uint8_t)crc[i]); } while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) ; } void sendFirmwareInfo(void) { uint8_t version_buf[10]; uint32_t value; value = *(__IO uint32_t *)FLASH_VERSION_ADDR; version_buf[0] = 0xA5; version_buf[1] = 0x5A; version_buf[2] = 0x0A; version_buf[3] = 0x00; version_buf[4] = 0x30; version_buf[5] = 0x01; version_buf[6] = (uint8_t)value; version_buf[7] = (uint8_t)(value >> 8); version_buf[8] = (uint8_t)(value >> 16); version_buf[9] = (uint8_t)(value >> 24); wifi_crc_send(version_buf, 10); } void sendOPMCalStatus(char Times, char Status) { uint8_t Send_buf[7]; Send_buf[0] = 0xA5; Send_buf[1] = 0x5A; Send_buf[2] = 0x07; Send_buf[3] = 0x00; Send_buf[4] = 0x0f; Send_buf[5] = Times; Send_buf[6] = Status; wifi_crc_send(Send_buf, 7); } void sendOPMCalValue(uint32_t OFF_Value, uint32_t ON_Value) { uint8_t Send_buf[13]; Send_buf[0] = 0xA5; Send_buf[1] = 0x5A; Send_buf[2] = 0x0d; Send_buf[3] = 0x00; Send_buf[4] = 0x0E; Send_buf[5] = ON_Value >> 24; Send_buf[6] = ON_Value >> 16; Send_buf[7] = ON_Value >> 8; Send_buf[8] = ON_Value & 0xff; Send_buf[9] = OFF_Value >> 24; Send_buf[10] = OFF_Value >> 16; Send_buf[11] = OFF_Value >> 8; Send_buf[12] = OFF_Value & 0xff; wifi_crc_send(Send_buf, 13); } /** * @function: CalValue_Upload * @brief: 只上报OPM_Original * @return {*} * @author: lzc */ extern float OPM_Original; void CalValue_Upload(void) { uint32_t ON_BED_Threshold_Value = 0; uint32_t OFF_BED_Threshold_Value = 0; // TODO: 增加联合体转换之后的校准数据上报 Float2uint32.fValue = OPM_Original; OFF_BED_Threshold_Value = Float2uint32.uintValue; Float2uint32.fValue = OPM_Original; ON_BED_Threshold_Value = Float2uint32.uintValue; sendOPMCalValue(ON_BED_Threshold_Value, OFF_BED_Threshold_Value); delay_ms(100); sendOPMCalValue(ON_BED_Threshold_Value, OFF_BED_Threshold_Value); delay_ms(100); } void CheckOverTimeValueClear(void) { if (ConfirmUpgradeCountTime != 0) { OverTime++; if (OverTime >= 300) { OverTime = 0; ConfirmUpgradeCountTime = 0; printf("ConfirmUpgradeCountTime Clear Done!!!!!!!\r\n"); } } if (ResetCountTime != 0) { OverTime++; if (OverTime >= 300) { OverTime = 0; ResetCountTime = 0; printf("ResetCountTime Clear Done!!!!!!!\r\n"); } } }