482 lines
13 KiB
C
482 lines
13 KiB
C
#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");
|
||
}
|
||
}
|
||
}
|