Job_SignsPads/STM32/Code/STM32F405/Application/wificom.c
2025-04-22 10:29:37 +08:00

482 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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");
}
}
}