/**
|
******************************************************************************
|
* File Name : USART.c
|
* Description : This file provides code for the configuration
|
* of the USART instances.
|
******************************************************************************
|
* @attention
|
*
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
* All rights reserved.</center></h2>
|
*
|
* 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 <string.h>
|
#include <stdio.h>
|
|
#include <math.h>
|
#include <stdbool.h>
|
#include <stdint.h>
|
#include <stdarg.h>
|
#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<UART_RINGBUF_SIZE)
|
{
|
memcpy( &TxBuffer[iw], &tempBuff[0], len);
|
iw+=len;
|
}
|
else
|
{
|
lenTop=UART_RINGBUF_SIZE-iw;
|
memcpy( &TxBuffer[iw], &tempBuff[0], lenTop);
|
len-=lenTop;
|
memcpy( &TxBuffer[0], &tempBuff[lenTop], len);
|
iw = len;
|
}
|
RESTORE_PRIMASK();
|
|
HAL_NVIC_SetPendingIRQ(USART1_IRQn);
|
|
va_end(args);
|
VcomPrint();
|
}
|
|
int8_t Board_USART2Recv(uint8_t *pFmt, uint16_t u16TimeOut)
|
{
|
while(u16TimeOut)
|
{
|
if(UartRev.pFront != UartRev.pRear)
|
{
|
/* 如果队首指针和队尾指针不同表明缓冲区中有数据还未收取*/
|
*pFmt = *UartRev.pFront;
|
UartRev.pFront++;
|
|
if (UartRev.pFront >= (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****/
|
|