/**
  ******************************************************************************
  * File Name          : USART.c
  * Description        : This file provides code for the configuration
  *                      of the USART instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * 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;
	
	Node_Config_LoRa_ADR(1);		//enable LORA-WAN ADR
	
	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<Buffer_INDEX;index1++)
			{
				if(USART1_RX_Buffer[index1] == '<'){
					break;
				}
			}
			//datalen
			index2 = index1-1;
			while(index2--)
			{
				if(USART1_RX_Buffer[index2] == ','){
					break;
        }
			}
			switch (index1-index2)
			{
				case 3: data_len = USART1_RX_Buffer[index2+1]-'0';break;
				case 4: data_len = (USART1_RX_Buffer[index2+1]-'0')*10+USART1_RX_Buffer[index2+2]-'0';break;
			}
			
			strncpy(hex_str,(char *)&USART1_RX_Buffer[index1+1],data_len*2);
			
			hex2str(hex_str , char_str);
			
			/*  ����ģʽ  								*/
			//�������  									0
			//���߿���  									1
			//��������  									2
			//�״����  									3
			//Dual Mode ˫ģʽ����  			4
			/*  ����ģʽ  								*/
			
			if(char_str[0] == '0')  // Config work Mode="0,1,2,3,4" or Config Radar Parameter="P"
			{
				Work_Mode = char_str[0] - '0';			// Config work Mode = {0} Network_Mode
				*Color = char_str[1] - '0';					// Config LED color = {0,1,2,3,4,5,6,8,8} Color code
			}
			switch (char_str[0])
			{
				case '0' : {												// Network_Mode
					Work_Mode = char_str[0] - '0';
					*Color = char_str[1] - '0';				// Config LED color = {0,1,2,3,4,5,6,8,8} Color code
					break;
				}
				
				case '2' : {												// Reed_Mode
					Work_Mode = char_str[0] - '0';
					Reed_Working();
					break;
				}
				
				case '3' : {												// Radar_Mode
					Work_Mode = char_str[0] - '0';
					memset(USART3_RX_Buffer,0,sizeof(USART3_RX_Buffer));		// Get Radar config Parameters
					Radar_Data_Flag = 0;							//
					break;
				}
				
				case '4' : {												// Reed_Radar_Dual_Mode
//					Work_Mode = char_str[0] - '0';
					Work_Mode = Reed_Radar_Dual_Mode;
					memset(USART3_RX_Buffer,0,sizeof(USART3_RX_Buffer));		// Get Radar config Parameters
					Radar_Data_Flag = 0;							//
					break;
				}

				case 'P' : {												// Config Radar parameters in following code
					Set_PCR_Parameter(char_str , data_len);
				}
				case 'V' : {			
					Reply_Version_Info();
				}
			}
//			if(USART1_RX_Buffer[index1+1] != '5')
//			{
//				Work_Mode = USART1_RX_Buffer[index+2]-'0';
//				if(Work_Mode == 0)
//				{
//					*Color = USART1_RX_Buffer[index+4]-'0';				
//				}
//				else if(Work_Mode == 2)
//				{
//					Reed_Working();
//				}
//				else if(Work_Mode == 3)
//				{
//					memset(USART3_RX_Buffer,0,sizeof(USART3_RX_Buffer));
//					Radar_Data_Flag = 0;
//				}
//			}
//			else if(USART1_RX_Buffer[index+2] == 'P')
//			{
//				Set_PCR_Parameter((char *)&USART1_RX_Buffer[index+3]);
//			}

			memset(USART1_RX_Buffer,0,sizeof(USART1_RX_Buffer));
			
		}
		
	}
}

static int hex2int(char c)
{
    if(c >= '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 , 0x56, MajorVer, MinorVer, SubMinorVer); 
	printf("AT+LRSEND=%d,0,4,<%02x%02x%02x%02x\r\n",userappctrlport,	0x56, MajorVer, MinorVer, SubMinorVer);		//2023-06-01 
		
	
	/* V 2.1.2   {56 23 06 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,16,<%02x%04x%04x%04x%02x\r\n",cmdreplyport,0x50,														/* change to port 13= cmdreplyport to align with other config�� 2023-06-1 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 Node_Config_LoRa_ADR(uint8_t adr_en)
{
	if (adr_en==1)
		printf("AT+ADREN=1\r\n");
	else printf("AT+ADREN=0\r\n");
	
}


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<num; i++)
  {
	    /* ����һ���ֽ����ݵ�USART */
	    Usart_SendByte(pUSARTx,array[i]);	
  
  }
	/* �ȴ�������� */
	while(LL_USART_IsActiveFlag_TC(pUSARTx)==RESET);
}



/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/