/** ****************************************************************************** * File Name : USART.c * Description : This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * *

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "usart.h" #include "main.h" #include "gpio.h" /* USER CODE BEGIN 0 */ extern volatile uint8_t Work_Mode; extern volatile uint8_t Radar_Data_Flag; // STS_O1 For Radar extern volatile uint8_t Occupancy_Status; extern volatile uint8_t netColor; //Cloud instructed color change 2022-09-21 sundp volatile uint8_t Accept_Finished_Flag = 0 ; uint8_t USART1_RX_Buffer[max_size] = {0} ; // LoRaWAN USART1 uint8_t USART3_RX_Buffer[Radar_frame_len] = {0} ; // STS_O1 For Radar for Radar frame volatile uint16_t Buffer_INDEX = 0; volatile uint16_t Previous_INDEX = 0; _Bool Motion_Flag; // STS_O1 For Radar motion detection /* USER CODE END 0 */ /* USART1 init function */ void MX_USART1_UART_Init(void) { LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_10; GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 DMA Init */ /* USART1_RX Init */ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_5, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PRIORITY_VERYHIGH); LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MDATAALIGN_BYTE); /* USART1 interrupt Init */ NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0)); NVIC_EnableIRQ(USART1_IRQn); USART_InitStruct.BaudRate = 9600; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART1, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART1); LL_USART_Enable(USART1); } /* USART2 init function */ void MX_USART2_UART_Init(void) { LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_2; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_3; GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART2, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART2); LL_USART_Enable(USART2); } /* USART3 init function */ void MX_USART3_UART_Init(void) // STS_O1 For Radar USART_RADAR { LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB); /**USART3 GPIO Configuration PB10 ------> USART3_TX PB11 ------> USART3_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_10; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_11; GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USART3 DMA Init */ /* USART3_RX Init */ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE); /* USART3 interrupt Init */ NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0)); NVIC_EnableIRQ(USART3_IRQn); USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART3, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART3); LL_USART_Enable(USART3); } /* USER CODE BEGIN 1 */ uint8_t Check_Status(void) { uint8_t value = 0; const char* buffer="\r\n+STATUS:3" ; LL_USART_ClearFlag_IDLE(USART1); printf("AT+STATUS=?\r\n"); while(Accept_Finished_Flag == 0) { } Accept_Finished_Flag = 0; if(strncmp(buffer, (char*)(USART1_RX_Buffer),11) == 0){ value = 1; LL_TIM_EnableIT_UPDATE(TIM3); LL_TIM_EnableCounter(TIM3); } return value; } /* 颜色说明 灭:0 绿:1 红:2 蓝:3 黄:4 紫:5 青:6 白:7 红蓝闪烁:8 */ void Online_Data_Analysis(volatile uint8_t *Color) // Cloud command parsing from LoRa receive buffer { const char* buffer = "\r\n^LRRECV:"; uint8_t index1 = 0; uint8_t index2 = 0; uint8_t data_len = 0; char hex_str[255]; char char_str[128]; if(Accept_Finished_Flag == 1) // LoRa receive finished or not { Accept_Finished_Flag = 0; if(strncmp((char*)USART1_RX_Buffer,buffer,strlen(buffer)) == 0) { //Usart_SendArray(USART2,USART1_RX_Buffer,strlen((char *)USART1_RX_Buffer)); //找到'<'的位置 for(index1 = 0;index1= '0' && c <= '9'){ return (c-'0'); } else if (c >= 'A' && c<= 'Z'){ return (c-'A'); } else if (c >= 'a' && c <= 'z'){ return (c-'a'); } else { return 0; } } void hex2str(char* hex , char* str ) { uint8_t i = 0; size_t j = 0; uint8_t a,b; for (j = 0; j < strlen(hex); j++) { a = hex2int(hex[i++]); b = hex2int(hex[i++]); str[j] = a*16+b; } str[j] = '\0'; } void Reply_Version_Info() { Node_Send_Data(userappctrlport, UnConfirmed , Red_Blue, 0x56, MajorVer, MinorVer); /* Red_Blue, V, 2 1 {08, 56 02 01} */ } void Set_PCR_Parameter(char *str,uint8_t len) { PCR PCR_parameter; char buffer[128]; if(len == 15) { PCR_parameter.Start = hex2int(str[1])*1000+hex2int(str[2])*100+hex2int(str[3])*10+hex2int(str[4]); PCR_parameter.End = hex2int(str[5])*1000+hex2int(str[6])*100+hex2int(str[7])*10+hex2int(str[8]); PCR_parameter.Threshold = hex2int(str[9])*1000+hex2int(str[10])*100+hex2int(str[11])*10+hex2int(str[12]); PCR_parameter.Gain = hex2int(str[13])*10+hex2int(str[14]); // PCR_parameter.Start = str[1]*1000+str[2]*100+str[3]*10+str[4]; // PCR_parameter.End = str[5]*1000+str[6]*100+str[7]*10+str[8]; // PCR_parameter.Threshold = str[9]*1000+str[10]*100+str[11]*10+str[12]; // PCR_parameter.Gain = str[13]*10+str[14]; sprintf(buffer , "Sparse Stop\r\n"); Usart_SendString(USART3 , buffer); LL_mDelay(500); sprintf(buffer , "Set Start=%dmm\r\n",PCR_parameter.Start); Usart_SendString(USART3 , buffer); LL_mDelay(500); sprintf(buffer , "Set end=%dmm\r\n",PCR_parameter.End); Usart_SendString(USART3 , buffer); LL_mDelay(500); sprintf(buffer , "Set Threshold=%d\r\n",PCR_parameter.Threshold); Usart_SendString(USART3 , buffer); LL_mDelay(500); sprintf(buffer , "Set Gain=%d%%\r\n",PCR_parameter.Gain); Usart_SendString(USART3 , buffer); LL_mDelay(500); sprintf(buffer , "Sparse Start\r\n"); Usart_SendString(USART3 , buffer); LL_mDelay(500); // printf("AT+LRSEND=10,0,2,<4F4B\r\n"); "OK" printf("AT+LRSEND=%d,%d,%d,<00\r\n",port,confirm,1); break; } printf("AT+LRSEND=%d,0,7,<%04x%04x%04x%02x\r\n",cmdreplyport, /* change to port 13= cmdreplyport to align with other config, 2022-09-21 sundp */ PCR_parameter.Start,PCR_parameter.End,PCR_parameter.Threshold,PCR_parameter.Gain); //change to port 13= cmdreplyport to align with other config /* 2022-09-21 sundp */ PCR PCR_parameter; printf("Set Start=%dmm\r\n",PCR_parameter.Start); printf("Set end=%dmm\r\n",PCR_parameter.End); printf("Set Threshold=%d\r\n",PCR_parameter.Threshold); printf("Set Gain=%d%%\r\n",PCR_parameter.Gain); } } uint8_t Radar_Data_Analysis(void) { uint8_t xReturn = 0; const char* person = "Motion "; const char* noperson = "No motion"; if(Radar_Data_Flag == 1) { if(strncmp((char *)USART3_RX_Buffer,person,strlen(person)) == 0){ xReturn = 1; } else if( strncmp((char *)USART3_RX_Buffer,noperson,strlen(noperson)) == 0){ xReturn = 0; } LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3); LL_USART_DisableDMAReq_RX(USART3); LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3,Radar_frame_len); //LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_3,(uint32_t)USART3_RX_Buffer); LL_USART_ReceiveData8(USART3); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3); LL_USART_EnableDMAReq_RX(USART3); } return xReturn; } void Radar_Filtering_clutter(volatile uint8_t *color) { _Bool pNew_Motion_Flag = 0; static uint8_t Motion_Changed_Flag = 1; static uint8_t numerator = Preset_numerator; static uint8_t denominator = Preset_denominator; pNew_Motion_Flag = Radar_Data_Analysis(); if(pNew_Motion_Flag != Motion_Flag){ Motion_Changed_Flag = 1; } if(Motion_Changed_Flag == 1) { denominator++; // num /denom++ if(pNew_Motion_Flag != Motion_Flag){ numerator++; // num ++ /denom } if(denominator >= Preset_denominator) { if(numerator >= Preset_numerator) //的确改变 { Motion_Flag = !Motion_Flag; Occupancy_Status = Motion_Flag; // for heart-heat signal upload if(Motion_Flag) { // if (Work_Mode == Radar_Mode) // M100C_Send_Data(10,0,ZhanYong); // else if (Work_Mode == Reed_Radar_Dual_Mode) // Node_Send_Data(senddataport,UnConfirmed, Red, Work_Mode, Door_Status, Occupancy); if (Work_Mode != Network_Mode) { Node_Send_Data(senddataport,UnConfirmed, Red, Work_Mode, Door_Status, Occupancy_Status); *color = Red; } else { Node_Send_Data(senddataport,UnConfirmed, netColor, Work_Mode, Door_Status, Occupancy_Status); *color = netColor; } } else { // if (Work_Mode == Radar_Mode) // M100C_Send_Data(10,0,KeYong); // else // Not_Presence_status Only // if (Work_Mode == Reed_Radar_Dual_Mode) // Node_Send_Data(senddataport,UnConfirmed, Green, Work_Mode, Door_Status, No_Occupancy); if (Work_Mode != Network_Mode) { Node_Send_Data(senddataport,UnConfirmed, Green, Work_Mode, Door_Status, Occupancy_Status); *color = Green; } else { Node_Send_Data(senddataport,UnConfirmed, netColor, Work_Mode, Door_Status, Occupancy_Status); *color = netColor; } } } denominator = 0; numerator = 0; Motion_Changed_Flag = 0; } } } void M100C_Send_Data(uint8_t port,uint8_t confirm,uint8_t type) { switch (type) { case KeYong: { printf("AT+LRSEND=%d,%d,%d,<00\r\n",port,confirm,1); break; } case ZhanYong: { printf("AT+LRSEND=%d,%d,%d,<01\r\n",port,confirm,1); break; } } } void M100C_Send_HeartBeat(uint8_t color,uint8_t Mode) { printf("AT+LRSEND=5,0,2,<%02x%02x\r\n",color,Mode); PCR PCR_parameter; printf("Start=%dmm\r\n",PCR_parameter.Start); printf("end=%dmm\r\n",PCR_parameter.End); printf("Threshold=%d\r\n",PCR_parameter.Threshold); printf("Gain=%d%%\r\n",PCR_parameter.Gain); } void Node_Send_Data(uint8_t dataport, uint8_t confirm, uint8_t color, uint8_t workmode,uint8_t doorstatus, uint8_t presence_sensor_status) { // printf("AT+LRSEND=%d,%d,%d,<%02x%02x%02x\r\n",dataport,confirm,3,(uint8_t) color, (uint8_t) workmode, (uint8_t)(doorstatus + presence_sensor_status)); printf("AT+LRSEND=%d,%d,%d,<%02x%02x%02x%02x\r\n", dataport,confirm,4, (uint8_t) color, (uint8_t) workmode, (uint8_t) !doorstatus, (uint8_t) presence_sensor_status); } void DMA_USART1_RX_Config(void) { /* 复制USART初始化中DMA的代码,避免CUBE的BUG */ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_5, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PRIORITY_VERYHIGH); LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MDATAALIGN_BYTE); /* 复制USART初始化中DMA的代码,避免CUBE的BUG */ /* 手动配置DMA的外设地址、内存地址并使能DMA */ LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_5,(uint32_t)&(USART1->DR)); LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_5,(uint32_t)USART1_RX_Buffer); LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_5,max_size); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_5); LL_USART_EnableDMAReq_RX(USART1); /* 开启串口空闲中断 */ LL_USART_ClearFlag_IDLE(USART1); LL_USART_EnableIT_IDLE(USART1); } void DMA_USART3_RX_Config(void) { LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_3,(uint32_t)&(USART3->DR)); LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_3,(uint32_t)USART3_RX_Buffer); LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3,Radar_frame_len); LL_USART_ReceiveData8(USART3); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3); LL_USART_EnableDMAReq_RX(USART3); LL_USART_EnableIT_IDLE(USART3); } ///重定向c库函数printf到串口,重定向后可使用printf函数 int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ LL_USART_TransmitData8(USART1, (uint8_t) ch); //USART1 LoRaWAN USART1 /* 等待发送完毕 */ while (LL_USART_IsActiveFlag_TXE(USART1) == RESET); //USART1 LoRaWAN USART1 return (ch); } /***************** 发送一个字节 **********************/ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* 发送一个字节数据到USART */ LL_USART_TransmitData8(pUSARTx,ch); /* 等待发送数据寄存器为空 */ while (LL_USART_IsActiveFlag_TXE(pUSARTx) == RESET); } /***************** 发送字符串 **********************/ void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { unsigned int k=0; do { Usart_SendByte( pUSARTx, *(str + k) ); k++; } while(*(str + k)!='\0'); /* 等待发送完成 */ while(LL_USART_IsActiveFlag_TC(pUSARTx)==RESET) {} } void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num) { uint8_t i; for(i=0; i