/**
******************************************************************************
* 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;
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 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=13,0,7,<%04x%04x%04x%02x\r\n",
PCR_parameter.Start,PCR_parameter.End,PCR_parameter.Threshold,PCR_parameter.Gain);
//change to port 13 to align with other config
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);
Node_Send_Data(senddataport,UnConfirmed, Red, Work_Mode, Door_Status, Occupancy_Status);
*color = Red;
}
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);
Node_Send_Data(senddataport,UnConfirmed, Green, Work_Mode, Door_Status, Occupancy_Status);
*color = Green;
}
}
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