Job_SignsPads/STM32/Code/STM32F405/Application/wificom.c

482 lines
13 KiB
C
Raw Normal View History

2025-04-22 02:29:37 +00:00
#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");
}
}
}