/**
******************************************************************************
* File Name : USART.c
* Description : This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
*
© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include "usart.h"
#include "utilities.h"
#include "tim.h"
#include "board_common.h"
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
static uint8_t aRxBuffer[UART_RINGBUF_SIZE] = {0};
static uint8_t aTxBuffer[UART_RINGBUF_SIZE] = {0};
static UartBuffer_t UartRev;
static UartBuffer_t UartSnd;
static uint8_t RxBuffer = 0;
static char TxBuffer[UART_RINGBUF_SIZE];
/* buffer write index*/
static __IO uint16_t iw=0;
/* buffer read index*/
Uart_Rxbuffer_t Debug_Rxbuffer;
void Board_USART2RX_Enable(void);
/* USART1 init function */
void Board_USART1Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void Board_USART1DeInit(void)
{
HAL_UART_DeInit(&huart1);
}
void Board_USART1RX_Enable(void)
{
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); //再开启接收中断
}
void Board_USART1RX_Disable(void)
{
CLEAR_BIT(USART1->CR1, USART_CR1_RXNEIE);
}
static void Board_USART2BufferInit(void)
{
/*
* 初始化缓存
* 两个指针指向相同的地址空间
*/
memset(aRxBuffer, 0, sizeof(aRxBuffer));
memset(aTxBuffer, 0, sizeof(aTxBuffer));
UartRev.pFront = aRxBuffer;
UartRev.pRear = aRxBuffer;
UartSnd.pFront = aTxBuffer;
UartSnd.pRear = aTxBuffer; //两个指针指向相同的地址空间
}
/* USART3 init function */
void Board_USART2Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
Board_USART2BufferInit();
Board_USART2RX_Enable();
}
void Board_USART2DeInit(void)
{
HAL_UART_DeInit(&huart2);
}
void Board_USART2RX_Enable(void)
{
HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer, 1); //再开启接收中断
}
void Board_USART2RX_Disable(void)
{
CLEAR_BIT(USART2->CR1, USART_CR1_RXNEIE);
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if (uartHandle->Instance==USART2)
{
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
else if (uartHandle->Instance==USART2)
{
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_2 ;
HW_GPIO_Init( GPIOA, GPIO_PIN_2, &GPIO_InitStruct );
HW_GPIO_Write( GPIOA, GPIO_PIN_2, 1);
//GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pin = GPIO_PIN_3 ;
HW_GPIO_Init(GPIOA, GPIO_PIN_3, &GPIO_InitStruct );
HW_GPIO_Write(GPIOA, GPIO_PIN_3, 1);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
}
}
/* modifes only ir*/
void VcomPrint( void)
{
static uint16_t ir=0;
char* CurChar;
while(((iw+UART_RINGBUF_SIZE-ir)%UART_RINGBUF_SIZE) > 0)
{
BACKUP_PRIMASK();
DISABLE_IRQ();
CurChar = &TxBuffer[ir];
ir= (ir+1) %UART_RINGBUF_SIZE;
RESTORE_PRIMASK();
HAL_UART_Transmit(&huart1, (uint8_t *) CurChar, 1, 300);
}
HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
}
void VcomSend( char *format, ... )
{
va_list args;
va_start(args, format);
uint8_t len;
uint8_t lenTop;
char tempBuff[255];
BACKUP_PRIMASK();
DISABLE_IRQ();
/*convert into string at buff[0] of length iw*/
len = vsprintf(&tempBuff[0], format, args);
if (iw+len= (aRxBuffer+UART_RINGBUF_SIZE))
UartRev.pFront = aRxBuffer;
return 0;
}
u16TimeOut--;
}
return -1;
}
/**********************************************************************
函数:Uart2SendChar()
函数作用:发送一个字节数据
参数:
uint8_t *pFmt--------------------------------需要发送的数据
返回值:
上一版本:无
当前版本:1.0
作者:
最后修改时间:2015-04-08
说明:
**********************************************************************/
static void Uart2SendChar(uint8_t u8Fmt)
{
uint8_t u8Ret = HAL_OK;
if(UartSnd.pRear == UartSnd.pFront)
{
//队首指针和队尾指针相等表明当前没有数据需要发送,这里需要手动开启发送请求
*UartSnd.pRear = u8Fmt;
UartSnd.pRear++;
if(UartSnd.pRear >= aTxBuffer + UART_RINGBUF_SIZE)
UartSnd.pRear = aTxBuffer;
do
{
u8Ret = HAL_UART_Transmit_IT(&huart2, UartSnd.pFront, 1);//请求发送下一个数据
}while(u8Ret != HAL_OK);
}
else
{
*UartSnd.pRear = u8Fmt;
UartSnd.pRear++;
if(UartSnd.pRear >= aTxBuffer + UART_RINGBUF_SIZE)
UartSnd.pRear = aTxBuffer;
}
}
int8_t Board_USART2Send(const uint8_t *pFmt, uint8_t u8Len)
{
while(u8Len)
{
Uart2SendChar(*pFmt);
pFmt++;
u8Len--;
}
//HAL_Delay(10);
return 0;
}
//#define DATA_OVERFLOW "Buffer locked or data overflow.\r\n"
#define DATA_OVERFLOW "122.\r\n"
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
/*
* 溢出判断
*/
if (Debug_Rxbuffer.Locked || (Debug_Rxbuffer.RxSize >= sizeof(Debug_Rxbuffer.RxBuffer)))
{
//HAL_UART_Transmit(&huart1, (uint8_t *)DATA_OVERFLOW, strlen(DATA_OVERFLOW), 0xFFFF); //将收到的信息发送出去
//while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
FreeUart1Buffer(); // 清除buffer
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); //再开启接收中断
return ;
}
/*
* 取数据
*/
Debug_Rxbuffer.RxBuffer[Debug_Rxbuffer.RxSize++] = RxBuffer;
Debug_Rxbuffer.Time = jiffies;
/*
* 判断结束
*/
if ((Debug_Rxbuffer.RxBuffer[Debug_Rxbuffer.RxSize-1] == 0x0A) && (Debug_Rxbuffer.RxBuffer[Debug_Rxbuffer.RxSize-2] == 0x0D))
{
//HAL_UART_Transmit(&huart1, (uint8_t *)Uart1_Rxbuffer.RxBuffer, Uart1_Rxbuffer.RxSize, 0xFFFF); //将收到的信息发送出去
// while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
Debug_Rxbuffer.Locked = 1;
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); //再开启接收中断
}
else if(huart->Instance == USART2)
{
uint8_t u8Ret = HAL_OK;
//PRINTF("--%d-\r\n", __LINE__);
UartRev.pRear++;
if(UartRev.pRear >= (aRxBuffer + UART_RINGBUF_SIZE)) /* 判断队列是否满*/
UartRev.pRear = aRxBuffer; /* 从头开始存储*/
do
{
u8Ret= HAL_UART_Receive_IT(huart, UartRev.pRear, 1);
}while(u8Ret != HAL_OK);
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *pHuart)
{
uint8_t u8Ret = HAL_OK;
UartSnd.pFront++; /* 更新rear指针*/
if(UartSnd.pFront >= (aTxBuffer + UART_RINGBUF_SIZE))
UartSnd.pFront = aTxBuffer;
if(UartSnd.pFront != UartSnd.pRear)
{
/* 如果队首指针和队尾指针不同表明缓冲区中有数据还未发送*/
do
{
u8Ret = HAL_UART_Transmit_IT(pHuart, UartSnd.pFront, 1);/* 请求发送下一个数据*/
}while(u8Ret != HAL_OK);
}
}
#if 0
int8_t Board_USART2Test(void)
{
uint8_t u8Rx = 0;
uint32_t u32TestTimeOut = jiffies + 5000;
uint32_t u32RecvTimeOut = jiffies + 200;
const uint8_t u8SendBuffer[32] = "Recv OK\r\n";
uint8_t u8RecvBuffer[32] = {0};
uint8_t u8Index = 0;
//RS485_RX_ENABLE();
//Board_RS485RecvEnable();
while(1)
{
while( !Timeout_Happened(u32RecvTimeOut))
{
if (!Board_USART2Recv(&u8Rx, 200))
{
PRINTF("--%d-\r\n", __LINE__);
u8RecvBuffer[u8Index] = u8Rx;
if (u8Index <= (sizeof(u8RecvBuffer)-1))
u8Index++;
else
break;
}
}
//if(strstr((char *)u8RecvBuffer, (const char *)u8SendBuffer))
if(u8Index > 0)
{
PRINTF("--%d-\r\n", __LINE__);
Board_USART2Send(u8SendBuffer, strlen((const char *)u8SendBuffer));
//return 0;
}
u8Index = 0;
memset(u8RecvBuffer, 0, sizeof(u8RecvBuffer));
u32RecvTimeOut = jiffies + 200;
}
return -1;
}
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/