#include "main.h"

static void USART1_Init(uint32_t baudRate);
static void USART2_Init(uint32_t baudRate);
static void USART3_Init(uint32_t baudRate);
static void USART_SendString1(USART_TypeDef *USARTx, uint8_t *str, uint16_t len);
static void USART_SendString2(USART_TypeDef *USARTx, uint8_t *str);

USARTClassStruct USARTClass = {
	.USART1_Init = USART1_Init,
	.USART2_Init = USART2_Init,
	.USART3_Init = USART3_Init,
	.USART_SendString1 = USART_SendString1,
	.USART_SendString2 = USART_SendString2};

#define use_USART1
#define use_USART2
#define use_USART3
#define DEBUG_USART USART1

/* 在别的地方复现此函数  串口1中断函数
void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}
*/
/* 在别的地方复现此函数  串口2中断函数
void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
	}
}
*/
/* 在别的地方复现此函数  串口3中断函数
void USART3_IRQHandler(void)
{
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
	}
}
*/
#define DEBUG_REVDATA_SIZE 500
uint8_t g_debugRxFlag = 0;
uint8_t g_debugRxBuf[DEBUG_REVDATA_SIZE];
uint16_t g_debugRxLen = 0;
uint8_t Lora_sendbuf[DEBUG_REVDATA_SIZE];
void USART1_IRQHandler(void)
{
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		g_debugRxBuf[g_debugRxLen] = USART_ReceiveData(USART1);
		g_debugRxLen++;
	}
	else if (USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)
	{
		USART1->SR;
		USART1->DR;
		//	memcpy(Lora_sendbuf,g_debugRxBuf,g_debugRxLen);

		//	printf("send data:%s\r\n",g_debugRxBuf);
		//	USARTClass.USART_SendString1(USART3,g_debugRxBuf,g_debugRxLen);
		//	memset(g_debugRxBuf,0x00,DEBUG_REVDATA_SIZE);
		// g_debugRxLen = 0;
		g_debugRxFlag = 1;
	}
}

/**
 * @brief  USART1初始化
 * @param  baudRate: 波特率
 * @retval None
 */
static void USART1_Init(uint32_t baudRate)
{
#ifdef use_USART1
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	// 打开串口GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	// 打开串口外设的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	// 配置波特率
	USART_InitStructure.USART_BaudRate = baudRate;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式，收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(USART1, &USART_InitStructure);
	// 使能串口
	USART_Cmd(USART1, ENABLE);
	// 使能接收中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 使能串口空闲中断

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 中断控制器分组设置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
#endif
}

#define ASR_REVDATA_SIZE 20
uint8_t g_asrRxFlag = 0;
uint8_t Asr_recbuff[ASR_REVDATA_SIZE];
uint16_t g_asrRxLen = 0;

void USART2_IRQHandler(void)
{
	if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
	{
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
		Asr_recbuff[g_asrRxLen] = USART_ReceiveData(USART2);
		g_asrRxLen++;
	}
	else if (USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET)
	{
		USART2->SR;
		USART2->DR;
		g_asrRxLen = 0;
		// printf("asr data:");
		// for(int i = 0;i<=2;i++)
		// {
		// 	printf("%02X",Asr_recbuff[i]);

		// }
		// printf("\r\n");
		g_asrRxFlag = 1;
	}
}
/**
 * @brief  USART2初始化
 * @param  baudRate: 波特率
 * @retval None
 */
static void USART2_Init(uint32_t baudRate)
{
#ifdef use_USART2
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	// 打开串口GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	// 打开串口外设的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	// 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	// 配置波特率
	USART_InitStructure.USART_BaudRate = baudRate;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式，收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(USART2, &USART_InitStructure);
	// 使能串口
	USART_Cmd(USART2, ENABLE);
	// 使能接收中断
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

	USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // 使能串口空闲中断

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 中断控制器分组设置
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
#endif
}

#define LORA_REVDATA_SIZE 400
uint8_t g_loraRxFlag = 0;
uint8_t Lora_recbuff[LORA_REVDATA_SIZE];
uint16_t g_loraRxLen = 0;

void USART3_IRQHandler(void)
{
	if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
		Lora_recbuff[g_loraRxLen] = USART_ReceiveData(USART3);
		g_loraRxLen++;
	}
	else if (USART_GetFlagStatus(USART3, USART_FLAG_IDLE) != RESET)
	{
		USART3->SR;
		USART3->DR;
		g_loraRxLen = 0;
		printf("%s", Lora_recbuff);
		memset(Lora_recbuff, 0x00, LORA_REVDATA_SIZE);
		g_loraRxFlag = 1;
	}
}

/**
 * @brief  USART3初始化
 * @param  baudRate: 波特率
 * @retval None
 */
static void USART3_Init(uint32_t baudRate)
{
#ifdef use_USART3
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	// 打开串口GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	// 打开串口外设的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	// 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	// 配置波特率
	USART_InitStructure.USART_BaudRate = baudRate;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式，收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(USART3, &USART_InitStructure);
	// 使能串口
	USART_Cmd(USART3, ENABLE);
	// 使能接收中断
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
	USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); // 使能串口空闲中断

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 中断控制器分组设置
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
#endif
}
/**
 * @brief  USART发送定长字符串
 * @param  USARTx: 串口几发送
 * @param  str: 发送的内容
 * @param 	len: 长度
 * @retval None
 */
static void USART_SendString1(USART_TypeDef *USARTx, uint8_t *str, uint16_t len)
{

	unsigned short count = 0;

	for (; count < len; count++)
	{
		USART_SendData(USARTx, *str++); // 发送数据
		while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
			; // 等待发送完成
	}
}
/**
 * @brief  USART发送不定长字符串
 * @param  USARTx: 串口几发送
 * @param  str: 发送的内容
 * @retval None
 */
static void USART_SendString2(USART_TypeDef *USARTx, uint8_t *str)
{
	unsigned int k = 0;
	do
	{
		USART_SendData(USARTx, *(str + k));
		/* 等待发送数据寄存器为空 */
		while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
		{
		}
		k++;
	} while (*(str + k) != '\0');
	/* 等待发送完成 */
	while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
	{
	}
}

/// 重定向c库函数printf到串口，重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
	/* 发送一个字节数据到串口 */
	USART_SendData(DEBUG_USART, (uint8_t)ch);
	/* 等待发送完毕 */
	while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET)
		;
	return (ch);
}

void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t ch)
{
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx, ch);

	/* 等待发送数据寄存器为空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == 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 (USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET)
	{
	}
}
