441 lines
9.7 KiB
C
Raw Normal View History

2022-02-18 11:27:58 +08:00
#include "wm_uart.h"
__attribute__((weak)) void HAL_UART_MspInit(UART_HandleTypeDef *huart);
__attribute__((weak)) void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, uint8_t Status, uint32_t Tickstart, uint32_t Timeout);
static void UART_SetConfig(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
if (huart == NULL)
{
return HAL_ERROR;
}
assert_param(IS_UART_INSTANCE(huart->Instance));
if (huart->gState == HAL_UART_STATE_RESET)
{
huart->Lock = HAL_UNLOCKED;
HAL_UART_MspInit(huart);
}
huart->gState = HAL_UART_STATE_BUSY;
__HAL_UART_DISABLE(huart);
UART_SetConfig(huart);
__HAL_UART_ENABLE(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
return HAL_OK;
}
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
{
if (huart == NULL)
{
return HAL_ERROR;
}
assert_param(IS_UART_INSTANCE(huart->Instance));
huart->gState = HAL_UART_STATE_BUSY;
__HAL_UART_DISABLE(huart);
HAL_UART_MspDeInit(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_RESET;
huart->RxState = HAL_UART_STATE_RESET;
__HAL_UNLOCK(huart);
return HAL_OK;
}
__attribute__((weak)) void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
__attribute__((weak)) void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint8_t *pdata8bits;
uint32_t tickstart = 0U;
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
__HAL_LOCK(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
tickstart = HAL_GetTick();
huart->TxXferSize = Size;
huart->TxXferCount = Size;
pdata8bits = pData;
__HAL_UNLOCK(huart);
while (huart->TxXferCount > 0)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FIFOS_TFC, UART_FIFO_TX_NOT_FULL, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
huart->Instance->TDW = *pdata8bits;
pdata8bits++;
huart->TxXferCount--;
}
if (UART_WaitOnFlagUntilTimeout(huart, UART_FIFOS_TFC, UART_FIFO_TX_EMPTY, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
huart->gState = HAL_UART_STATE_READY;
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint8_t *pdata8bits;
uint32_t tickstart = 0U;
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
__HAL_LOCK(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
tickstart = HAL_GetTick();
huart->RxXferSize = Size;
huart->RxXferCount = Size;
pdata8bits = pData;
__HAL_UNLOCK(huart);
while (huart->RxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FIFOS_RFC, UART_FIFO_RX_NOT_EMPTY, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
*pdata8bits = huart->Instance->RDW;
pdata8bits++;
huart->RxXferCount--;
}
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
__HAL_UNLOCK(huart);
__HAL_UART_ENABLE_IT(huart, UART_TX_INT_FLAG);
do {
if ((huart->Instance->FIFOS & UART_FIFOS_TFC) == UART_FIFO_FULL)
{
break;
}
huart->Instance->TDW = *(huart->pTxBuffPtr);
huart->pTxBuffPtr++;
huart->TxXferCount--;
} while(0);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
if (huart->RxState == HAL_UART_STATE_READY)
{
if (pData == NULL)
{
return HAL_ERROR;
}
__HAL_LOCK(huart);
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = 0;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
__HAL_UNLOCK(huart);
__HAL_UART_CLEAR_FLAG(huart, UART_RX_INT_FLAG);
__HAL_UART_ENABLE_IT(huart, UART_RX_INT_FLAG);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t isrflags = READ_REG(huart->Instance->INTS);
uint32_t isrmasks = READ_REG(huart->Instance->INTM);
__HAL_UART_CLEAR_FLAG(huart, isrflags);
if (((isrflags & UART_RX_INT_FLAG) != RESET) && ((isrmasks & UART_RX_INT_FLAG) == RESET))
{
if ((isrflags & UART_RX_ERR_INT_FLAG) != RESET)
{
huart->ErrorCode = isrflags & UART_RX_ERR_INT_FLAG;
}
else
{
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
if(isrflags&UART_INTS_RTO)
{
huart->RxFlag=1;
}
UART_Receive_IT(huart);
}
if (((isrflags & UART_INTS_TL) != RESET) && ((isrmasks & UART_INTM_RL) == RESET))
{
UART_Transmit_IT(huart);
}
if (((isrflags & UART_INTS_TEMPT) != RESET) && ((isrmasks & UART_INTM_TEMPT) == RESET))
{
UART_EndTransmit_IT(huart);
}
}
__attribute__((weak)) void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
__attribute__((weak)) void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, uint8_t Status, uint32_t Tickstart, uint32_t Timeout)
{
while (1)
{
if (Status == UART_FIFO_TX_NOT_FULL)
{
if ((huart->Instance->FIFOS & Flag) < UART_FIFO_FULL)
break;
}
else if (Status == UART_FIFO_TX_EMPTY)
{
if ((huart->Instance->FIFOS & Flag) == 0)
break;
}
else if (Status == UART_FIFO_RX_NOT_EMPTY)
{
if ((huart->Instance->FIFOS & Flag) > 0)
break;
}
if (Timeout != HAL_MAX_DELAY)
{
if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
{
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
__HAL_UNLOCK(huart);
return HAL_TIMEOUT;
}
}
}
return HAL_OK;
}
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
if (huart->gState == HAL_UART_STATE_BUSY_TX)
{
while (huart->TxXferCount > 0)
{
if ((huart->Instance->FIFOS & UART_FIFOS_TFC) == UART_FIFO_FULL)
{
break;
}
huart->Instance->TDW = *(huart->pTxBuffPtr);
huart->pTxBuffPtr++;
huart->TxXferCount--;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
{
if (huart->TxXferCount == 0)
{
__HAL_UART_DISABLE_IT(huart, UART_INTM_TL | UART_INTM_TEMPT);
huart->gState = HAL_UART_STATE_READY;
HAL_UART_TxCpltCallback(huart);
}
return HAL_OK;
}
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint8_t ch, count;
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
count = ((READ_REG(huart->Instance->FIFOS) & UART_FIFOS_RFC) >> UART_FIFOS_RFC_Pos);
while (count-- > 0)
{
ch = (uint8_t)(huart->Instance->RDW);
if ((huart->ErrorCode & UART_RX_ERR_INT_FLAG) != RESET)
{
continue;
}
*(huart->pRxBuffPtr) = ch;
huart->pRxBuffPtr++;
huart->RxXferCount++;
if (huart->RxXferSize > 0)
{
if (huart->RxXferCount == huart->RxXferSize)
{
huart->pRxBuffPtr -= huart->RxXferSize;
HAL_UART_RxCpltCallback(huart);
huart->RxXferCount = 0;
}
}
else
{
if (count == 0)
{
huart->pRxBuffPtr -= huart->RxXferCount;
HAL_UART_RxCpltCallback(huart);
huart->RxXferCount = 0;
}
}
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
static void UART_SetConfig(UART_HandleTypeDef *huart)
{
uint32_t value;
uint32_t apbclk;
wm_sys_clk sysclk;
assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
assert_param(IS_UART_PARITY(huart->Init.Parity));
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
assert_param(IS_UART_MODE(huart->Init.Mode));
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
MODIFY_REG(huart->Instance->LC,
(uint32_t)(UART_LC_RE | UART_LC_TE | UART_LC_PS | UART_LC_PCE | UART_LC_STOP | UART_LC_DATAL),
(uint32_t)(huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.StopBits));
if (huart->Instance == UART2)
{
CLEAR_BIT(huart->Instance->LC, (1 << 24));
}
MODIFY_REG(huart->Instance->FC, (uint32_t)(UART_FC_RTSL | UART_FC_AFCE), (uint32_t)(UART_FC_RTSL_24 | huart->Init.HwFlowCtl));
MODIFY_REG(huart->Instance->DMAC, (uint32_t)(UART_DMAC_RTO | UART_DMAC_RTOE), (uint32_t)((4 << 3) | UART_DMAC_RTOE));
MODIFY_REG(huart->Instance->FIFOC,
(uint32_t)(UART_FIFOC_RFL | UART_FIFOC_TFL | UART_FIFOC_RFRST | UART_FIFOC_TFRST),
(uint32_t)(UART_FIFOC_RFL_16 | UART_FIFOC_TFL_16 | UART_FIFOC_RFRST | UART_FIFOC_TFRST));
SystemClock_Get(&sysclk);
apbclk = sysclk.apbclk * 1000000;
value = (apbclk / (16 * (huart->Init.BaudRate)) - 1) |
(((apbclk % ((huart->Init.BaudRate) * 16)) * 16 / ((huart->Init.BaudRate) * 16)) << 16);
huart->Instance->BAUDR = value;
}