438 lines
14 KiB
C
438 lines
14 KiB
C
/*
|
|
******************************************************************************
|
|
* @file HAL_LPUART.c
|
|
* @version V1.0.0
|
|
* @date 2020
|
|
* @brief LPUART HAL module driver.
|
|
* This file provides firmware functions to manage the following
|
|
* functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (LPUART).
|
|
* @ Initialization and de-initialization functions
|
|
* @ IO operation functions
|
|
* @ Peripheral Control functions
|
|
******************************************************************************
|
|
*/
|
|
#include "ACM32Fxx_HAL.h"
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_LPUART_IRQHander
|
|
* Description : LPUART IRQHander
|
|
* Input :
|
|
* Outpu :
|
|
* Author : CWT Data : 2020年
|
|
**********************************************************************************/
|
|
void HAL_LPUART_IRQHander(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
while ( (hlpuart->Instance->SR) & (1U << LPUART_SR_RX_INDEX))
|
|
{
|
|
if(hlpuart->rx_read_index != (((hlpuart->rx_write_index) + 1)% (hlpuart->rx_buffer_size) ) )
|
|
{
|
|
hlpuart->rx_buffer[hlpuart->rx_write_index] = hlpuart->Instance->RXDR;
|
|
hlpuart->rx_write_index = ((hlpuart->rx_write_index + 1)%(hlpuart->rx_buffer_size) );
|
|
}
|
|
else
|
|
{
|
|
hlpuart->Instance->SR = (1U << LPUART_SR_RX_INDEX); // buffer overflow
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
/************************************************************************
|
|
* function : HAL_UART_Buffer_Init
|
|
* Description: uart buffer initiation.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* return: 0: FAIL; 1: SUCCESS
|
|
************************************************************************/
|
|
HAL_StatusTypeDef HAL_LPUART_Buffer_Init(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
hlpuart->rx_read_index = 0;
|
|
hlpuart->rx_write_index = 0;
|
|
hlpuart->tx_busy = 0;
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**********************************************************************************
|
|
* function : HAL_LPUART_MSPInit
|
|
* Description: UART MCU specific initiation, such as IO share, module clock, ...
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* return: 0: FAIL; 1: SUCCESS
|
|
***************************************************************************************/
|
|
|
|
__weak void HAL_LPUART_MSPInit(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
GPIO_InitTypeDef gpio_init;
|
|
|
|
System_Module_Reset(RST_LPUART);
|
|
gpio_init.Pin = GPIO_PIN_2|GPIO_PIN_3; // TX PA2 RX PA3
|
|
gpio_init.Mode = GPIO_MODE_AF_PP;
|
|
gpio_init.Pull = GPIO_PULLUP;
|
|
gpio_init.Alternate = GPIO_FUNCTION_6;
|
|
HAL_GPIO_Init(GPIOA,&gpio_init);
|
|
System_Module_Enable(EN_LPUART);
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : HAL_LPUART_MspDeInit
|
|
* Description : LPUART MSP De-Initialization
|
|
* This function frees the hardware resources used in this example:
|
|
* - Disable the Peripheral's clock
|
|
* - Revert GPIO configuration to their default state
|
|
* Input : hcan : pointer to a CAN_HandleTypeDef structure that contains
|
|
* the configuration information for CAN module
|
|
* Output :
|
|
* Author : CWT Data : 2020年
|
|
**********************************************************************************/
|
|
void HAL_LPUART_MspDeInit(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
/* Initialization GPIO */
|
|
/* // TX PA2 RX PA3 */
|
|
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2);
|
|
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3);
|
|
}
|
|
/**********************************************************************************
|
|
* function : HAL_LPUART_Set_Baud_Rate
|
|
* Description: set uart module's baud rate. It should be set when UART is disabled.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* return: 0: FAIL; 1: SUCCESS
|
|
***************************************************************************************/
|
|
uint8_t HAL_LPUART_Set_Baud_Rate(LPUART_HandleTypeDef *hlpuart, uint32_t lpuart_clk, uint32_t baud_rate)
|
|
{
|
|
uint32_t ibaud, fbaud, rxsamp;
|
|
|
|
if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
|
|
{
|
|
return 0;
|
|
}
|
|
ibaud = 2;
|
|
fbaud = 0x952;
|
|
rxsamp = 1;
|
|
switch(lpuart_clk)
|
|
{
|
|
case 32000:
|
|
case 32768:
|
|
switch(baud_rate)
|
|
{
|
|
case 9600:
|
|
ibaud = 2;
|
|
fbaud = 0x952;
|
|
// ibaud = 2;
|
|
// fbaud = 0xA44;
|
|
break;
|
|
|
|
case 4800:
|
|
ibaud = 5;
|
|
fbaud = 0xefb;
|
|
break;
|
|
|
|
case 2400:
|
|
ibaud = 12;
|
|
fbaud = 0x6db;
|
|
break;
|
|
|
|
case 1200:
|
|
ibaud = 26;
|
|
fbaud = 0x492;
|
|
break;
|
|
default:
|
|
ibaud = 2;
|
|
fbaud = 0x952;
|
|
break;
|
|
}
|
|
rxsamp = ibaud >> 1;
|
|
break;
|
|
|
|
default:
|
|
switch(baud_rate)
|
|
{
|
|
case 115200:
|
|
ibaud = 16;
|
|
fbaud = 0x924;
|
|
break;
|
|
|
|
case 9600:
|
|
ibaud = 203;
|
|
fbaud = 0x888;
|
|
break;
|
|
}
|
|
rxsamp = ibaud >> 1;
|
|
break;
|
|
}
|
|
hlpuart->Instance->IBAUD = ibaud | (rxsamp << 8);
|
|
hlpuart->Instance->FBAUD = fbaud;
|
|
return 1;
|
|
}
|
|
|
|
/************************************************************************
|
|
* function : HAL_LPUART_Config
|
|
* Description: Configure UART module parameters, such as baudrate, parity,
|
|
* stop bits, dataword.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* return: 0: FAIL; 1: SUCCESS
|
|
************************************************************************/
|
|
uint8_t HAL_LPUART_Config(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
volatile uint32_t temp_reg;
|
|
if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
|
|
{
|
|
return 0;
|
|
}
|
|
temp_reg = 1U << 7; // default value
|
|
temp_reg |= ((hlpuart->ConfigParam.WordLength << 4) | (hlpuart->ConfigParam.StopBits << 3));
|
|
switch(hlpuart->ConfigParam.Parity)
|
|
{
|
|
case LPUART_PARITY_NONE:
|
|
break; // do nothing
|
|
|
|
case LPUART_PARITY_SELECT_ODD:
|
|
case LPUART_PARITY_SELECT_EVEN:
|
|
temp_reg |= (((hlpuart->ConfigParam.Parity - LPUART_PARITY_SELECT_ODD) << LPUART_EPS_INDEX) | (1 << LPUART_PEN_INDEX));
|
|
break;
|
|
|
|
case LPUART_PARITY_SELECT_ONE:
|
|
case LPUART_PARITY_SELECT_ZERO:
|
|
temp_reg |= (((hlpuart->ConfigParam.Parity - LPUART_PARITY_SELECT_ONE) << LPUART_EPS_INDEX) | (1 << LPUART_SPS_INDEX) | (1 << LPUART_PEN_INDEX) );
|
|
break;
|
|
}
|
|
hlpuart->Instance->LCR = temp_reg;
|
|
return 1;
|
|
}
|
|
|
|
/*********************************************************************************
|
|
* Function : LPUART_Clock_Select
|
|
* Description : Select the LPUART clock.
|
|
* Input : lpuart_clk_src:Could be LPUART_CLOCK_SOURCE_RC32K LPUART_CLOCK_SOURCE_XTAL LPUART_CLOCK_SOURCE_PLL_DIV
|
|
* Outpu :
|
|
* Author : CWT Data : 2020年
|
|
**********************************************************************************/
|
|
void LPUART_Clock_Select(uint8_t lpuart_clk_src)
|
|
{
|
|
if (0 == lpuart_clk_src)
|
|
{
|
|
SCU->CCR2 &= (~(BIT13 | BIT14) ); // RC32K
|
|
}
|
|
else if (1 == lpuart_clk_src)
|
|
{
|
|
SCU->CCR2 = (SCU->CCR2 & (~(BIT13 | BIT14) )) | (BIT13); // XTAL
|
|
}
|
|
else
|
|
{
|
|
SCU->CCR2 = (SCU->CCR2 & (~(BIT11 | BIT12| BIT13 | BIT14) )) | (BIT11 | BIT12 | BIT14); // pclk/32
|
|
}
|
|
}
|
|
/************************************************************************
|
|
* function : HAL_LPUART_Init
|
|
* Description: uart initial with parameters.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* return: 0: FAIL; 1: SUCCESS
|
|
************************************************************************/
|
|
HAL_StatusTypeDef HAL_LPUART_Init(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
uint32_t lpuart_clock;
|
|
if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
|
|
{
|
|
return HAL_ERROR;;
|
|
}
|
|
|
|
HAL_LPUART_Buffer_Init(hlpuart);
|
|
/*reset module, configure tx and rx, enable module clock*/
|
|
HAL_LPUART_MSPInit(hlpuart);
|
|
|
|
if (LPUART_CLOCK_SOURCE_RC32K == hlpuart->ConfigParam.ClockSrc)
|
|
{
|
|
lpuart_clock = 32000;
|
|
System_Module_Enable(EN_RTC);
|
|
System_Enable_Disable_RTC_Domain_Access(FUNC_ENABLE);
|
|
System_Enable_RC32K();
|
|
LPUART_Clock_Select(0);
|
|
}
|
|
else if (LPUART_CLOCK_SOURCE_XTAL == hlpuart->ConfigParam.ClockSrc)
|
|
{
|
|
lpuart_clock = 32768;
|
|
System_Module_Enable(EN_RTC);
|
|
System_Enable_Disable_RTC_Domain_Access(FUNC_ENABLE);
|
|
System_Enable_XTAL();
|
|
LPUART_Clock_Select(1);
|
|
}
|
|
else
|
|
{
|
|
lpuart_clock = System_Get_APBClock()/32;
|
|
LPUART_Clock_Select(2);
|
|
}
|
|
HAL_LPUART_Set_Baud_Rate(hlpuart, lpuart_clock, hlpuart->ConfigParam.BaudRate);
|
|
|
|
HAL_LPUART_Config(hlpuart);
|
|
|
|
hlpuart->Instance->SR = LPUART_SR_BITS_ALL;
|
|
hlpuart->Instance->IE = (1U << LPUART_IE_RX_INDEX);
|
|
hlpuart->Instance->CR = (1U << LPUART_CR_RXE_INDEX) | (1 << LPUART_CR_TXE_INDEX);
|
|
hlpuart->Instance->LCR=((hlpuart->StopWakeup.Wakeup_Source<<5)|(hlpuart->StopWakeup.Wakeup_Check<<7));
|
|
hlpuart->Instance->ADDR=(hlpuart->StopWakeup.Wakeup_Addr);
|
|
NVIC_ClearPendingIRQ(LPUART_IRQn);
|
|
NVIC_EnableIRQ(LPUART_IRQn);
|
|
return HAL_OK;;
|
|
}
|
|
HAL_StatusTypeDef HAL_LPUART_DeInit(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
/* Check handle */
|
|
if(!IS_LPUART_INSTANCE(hlpuart->Instance)) return HAL_ERROR;
|
|
HAL_LPUART_MspDeInit(hlpuart);
|
|
/* Disable LPUART clock */
|
|
System_Module_Disable(EN_LPUART);
|
|
/* Return function status */
|
|
return HAL_OK;
|
|
}
|
|
/************************************************************************
|
|
* function : HAL_LPUART_Wait_TX_Done
|
|
* Description: wait uart not busy
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* return: 0: FAIL; 1: SUCCESS
|
|
************************************************************************/
|
|
HAL_StatusTypeDef HAL_LPUART_Wait_TX_Done(LPUART_HandleTypeDef *hlpuart)
|
|
{
|
|
while (0 == (hlpuart->Instance->SR & (1 << LPUART_SR_TX_FINISH_INDEX) ) ) {};
|
|
hlpuart->Instance->SR = (1 << LPUART_SR_TX_FINISH_INDEX);
|
|
return HAL_OK;
|
|
}
|
|
|
|
void HAL_LPUART_Output(LPUART_HandleTypeDef *hlpuart, unsigned char c)
|
|
{
|
|
if ((hlpuart->Instance->SR) & (1U << LPUART_SR_TX_EMPTY_INDEX) )
|
|
{
|
|
hlpuart->Instance->TXDR = c;
|
|
}
|
|
|
|
HAL_LPUART_Wait_TX_Done(hlpuart);
|
|
}
|
|
|
|
/************************************************************************
|
|
* function : uart_send_bytes
|
|
* Description: uart send bytes
|
|
* input :
|
|
* UINT32 uart_index: Serial port number
|
|
* UINT8* buff: out buffer
|
|
* UINT32 length: buffer length
|
|
* return: none
|
|
************************************************************************/
|
|
void HAL_LPUART_Send_Bytes(LPUART_HandleTypeDef *hlpuart, uint8_t *buff, uint32_t length)
|
|
{
|
|
uint32_t i;
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
HAL_LPUART_Output(hlpuart, *buff++);
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* function : HAL_LPUART_Receive_Bytes_Timeout
|
|
* Description: uart receive bytes
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* UINT8* buff: out buffer
|
|
* UINT32 length: buffer length
|
|
* UINT32 ms: number of ms to delay one byte
|
|
* return: received bytes
|
|
************************************************************************/
|
|
uint32_t HAL_LPUART_Receive_Bytes_Timeout(LPUART_HandleTypeDef *hlpuart, uint8_t * rxbuff, uint32_t length, uint32_t ms)
|
|
{
|
|
volatile uint32_t i, timeout, count;;
|
|
if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
|
|
{
|
|
return 0;
|
|
}
|
|
timeout = (System_Get_APBClock() >> 13) * ms;
|
|
count = timeout;
|
|
i = 0;
|
|
while(i < length)
|
|
{
|
|
if((hlpuart->rx_read_index) != (hlpuart->rx_write_index))
|
|
{
|
|
rxbuff[i] = hlpuart->rx_buffer[hlpuart->rx_read_index];
|
|
hlpuart->rx_read_index = (((hlpuart->rx_read_index) + 1)%(hlpuart->rx_buffer_size) );
|
|
count = timeout;
|
|
i++;
|
|
}
|
|
else
|
|
{
|
|
if (0 == count)//timeout
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
count--;
|
|
}
|
|
}
|
|
}
|
|
return i;
|
|
}
|
|
/************************************************************************
|
|
* function : HAL_LPUART_Receive_Bytes
|
|
* Description: LPUART receive bytes.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* buff:receive data buff
|
|
* length:length of buff
|
|
* return:length
|
|
************************************************************************/
|
|
uint32_t HAL_LPUART_Receive_Bytes(LPUART_HandleTypeDef *hlpuart, uint8_t * rxbuff, uint32_t length)
|
|
{
|
|
volatile uint32_t i, ie_backup;
|
|
if(0x00 == IS_LPUART_INSTANCE(hlpuart->Instance))
|
|
{
|
|
return 0;
|
|
}
|
|
ie_backup = hlpuart->Instance->IE;
|
|
hlpuart->Instance->IE = 0;
|
|
i = 0;
|
|
while(i < length)
|
|
{
|
|
if( (hlpuart->Instance->SR) & (1U << LPUART_SR_RX_INDEX) )
|
|
{
|
|
rxbuff[i] = hlpuart->Instance->RXDR;
|
|
i++;
|
|
}
|
|
}
|
|
hlpuart->Instance->IE = ie_backup;
|
|
return length;
|
|
}
|
|
/************************************************************************
|
|
* function : HAL_LPUART_DMA_Send_Bytes
|
|
* Description: LPUART send bytes by DMA.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* buff:send data buff
|
|
* length:length of buff
|
|
* return:none
|
|
************************************************************************/
|
|
void HAL_LPUART_DMA_Send_Bytes(LPUART_HandleTypeDef *hlpuart, uint8_t *buff, uint32_t length)
|
|
{
|
|
hlpuart->Instance->CR |= (1U << LPUART_CR_DMA_EN_INDEX);
|
|
hlpuart->tx_busy = 1;
|
|
HAL_DMA_Start_IT(hlpuart->dma_tx_handler, (uint32_t)buff, (uint32_t)&hlpuart->Instance->TXDR, length);
|
|
}
|
|
|
|
/************************************************************************
|
|
* function : HAL_LPUART_Clear_Wakeup_Flags
|
|
* Description: Clear the LPUART STOP wake up flag.
|
|
* input :
|
|
* UART_HandleTypeDef *huart: pointer to uart handle structure
|
|
* Wakeup_Bits:LPUART wakeup flag,could be: LPUART_WAKEUP_RX_BIT LPUART_WAKEUP_MATCH_BIT LPUART_WAKEUP_START_BIT
|
|
* return:none
|
|
************************************************************************/
|
|
|
|
void HAL_LPUART_Clear_Wakeup_Flags(LPUART_HandleTypeDef *hlpuart, uint32_t Wakeup_Bits)
|
|
{
|
|
hlpuart->Instance->SR = Wakeup_Bits;
|
|
}
|
|
|
|
|