blob: f647dc4f87993fa5a763d125bb791b6ae04acf04 [file] [log] [blame]
/**
******************************************************************************
* @file hw_uart.c
* @author MCD Application Team
* @brief hardware access
******************************************************************************
* @attention
*
* Copyright (c) 2018(-2021) STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "hw_conf.h"
/* Macros --------------------------------------------------------------------*/
#define HW_UART_INIT(__HANDLE__, __USART_BASE__) \
do \
{ \
(__HANDLE__).Instance = (__USART_BASE__); \
(__HANDLE__).Init.BaudRate = CFG_HW_##__USART_BASE__##_BAUDRATE; \
(__HANDLE__).Init.WordLength = CFG_HW_##__USART_BASE__##_WORDLENGTH; \
(__HANDLE__).Init.StopBits = CFG_HW_##__USART_BASE__##_STOPBITS; \
(__HANDLE__).Init.Parity = CFG_HW_##__USART_BASE__##_PARITY; \
(__HANDLE__).Init.HwFlowCtl = CFG_HW_##__USART_BASE__##_HWFLOWCTL; \
(__HANDLE__).Init.Mode = CFG_HW_##__USART_BASE__##_MODE; \
(__HANDLE__).Init.OverSampling = CFG_HW_##__USART_BASE__##_OVERSAMPLING; \
(__HANDLE__).AdvancedInit.AdvFeatureInit = CFG_HW_##__USART_BASE__##_ADVFEATUREINIT; \
HAL_UART_Init(&(__HANDLE__)); \
} while (0)
#define HW_UART_RX_IT(__HANDLE__, __USART_BASE__) \
do \
{ \
HW_##__HANDLE__##RxCb = cb; \
(__HANDLE__).Instance = (__USART_BASE__); \
HAL_UART_Receive_IT(&(__HANDLE__), p_data, size); \
} while (0)
#define HW_UART_TX_IT(__HANDLE__, __USART_BASE__) \
do \
{ \
HW_##__HANDLE__##TxCb = cb; \
(__HANDLE__).Instance = (__USART_BASE__); \
HAL_UART_Transmit_IT(&(__HANDLE__), p_data, size); \
} while (0)
#define HW_UART_TX(__HANDLE__, __USART_BASE__) \
do \
{ \
(__HANDLE__).Instance = (__USART_BASE__); \
hal_status = HAL_UART_Transmit(&(__HANDLE__), p_data, size, timeout); \
} while (0)
#define HW_UART_MSP_UART_INIT(__HANDLE__, __USART_BASE__) \
do \
{ \
/* Enable GPIO clock */ \
CFG_HW_##__USART_BASE__##_TX_PORT_CLK_ENABLE(); \
\
/* Enable USART clock */ \
__HAL_RCC_##__USART_BASE__##_CLK_ENABLE(); \
\
GPIO_InitStruct.Pin = CFG_HW_##__USART_BASE__##_TX_PIN; \
GPIO_InitStruct.Mode = CFG_HW_##__USART_BASE__##_TX_MODE; \
GPIO_InitStruct.Pull = CFG_HW_##__USART_BASE__##_TX_PULL; \
GPIO_InitStruct.Speed = CFG_HW_##__USART_BASE__##_TX_SPEED; \
GPIO_InitStruct.Alternate = CFG_HW_##__USART_BASE__##_TX_ALTERNATE; \
\
HAL_GPIO_Init(CFG_HW_##__USART_BASE__##_TX_PORT, &GPIO_InitStruct); \
\
CFG_HW_##__USART_BASE__##_RX_PORT_CLK_ENABLE(); \
\
GPIO_InitStruct.Pin = CFG_HW_##__USART_BASE__##_RX_PIN; \
GPIO_InitStruct.Mode = CFG_HW_##__USART_BASE__##_RX_MODE; \
GPIO_InitStruct.Pull = CFG_HW_##__USART_BASE__##_RX_PULL; \
GPIO_InitStruct.Speed = CFG_HW_##__USART_BASE__##_RX_SPEED; \
GPIO_InitStruct.Alternate = CFG_HW_##__USART_BASE__##_RX_ALTERNATE; \
\
HAL_GPIO_Init(CFG_HW_##__USART_BASE__##_RX_PORT, &GPIO_InitStruct); \
\
CFG_HW_##__USART_BASE__##_CTS_PORT_CLK_ENABLE(); \
\
GPIO_InitStruct.Pin = CFG_HW_##__USART_BASE__##_CTS_PIN; \
GPIO_InitStruct.Mode = CFG_HW_##__USART_BASE__##_CTS_MODE; \
GPIO_InitStruct.Pull = CFG_HW_##__USART_BASE__##_CTS_PULL; \
GPIO_InitStruct.Speed = CFG_HW_##__USART_BASE__##_CTS_SPEED; \
GPIO_InitStruct.Alternate = CFG_HW_##__USART_BASE__##_CTS_ALTERNATE; \
\
HAL_GPIO_Init(CFG_HW_##__USART_BASE__##_CTS_PORT, &GPIO_InitStruct); \
\
HAL_NVIC_SetPriority(__USART_BASE__##_IRQn, CFG_HW_##__USART_BASE__##_PREEMPTPRIORITY, \
CFG_HW_##__USART_BASE__##_SUBPRIORITY); \
HAL_NVIC_EnableIRQ(__USART_BASE__##_IRQn); \
} while (0)
#define HW_UART_MSP_TX_DMA_INIT(__HANDLE__, __USART_BASE__) \
do \
{ \
/* Configure the DMA handler for Transmission process */ \
/* Enable DMA clock */ \
CFG_HW_##__USART_BASE__##_DMA_CLK_ENABLE(); \
/* Enable DMA MUX clock */ \
CFG_HW_##__USART_BASE__##_DMAMUX_CLK_ENABLE(); \
\
HW_hdma_##__HANDLE__##_tx.Instance = CFG_HW_##__USART_BASE__##_TX_DMA_CHANNEL; \
HW_hdma_##__HANDLE__##_tx.Init.Request = CFG_HW_##__USART_BASE__##_TX_DMA_REQ; \
HW_hdma_##__HANDLE__##_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; \
HW_hdma_##__HANDLE__##_tx.Init.PeriphInc = DMA_PINC_DISABLE; \
HW_hdma_##__HANDLE__##_tx.Init.MemInc = DMA_MINC_ENABLE; \
HW_hdma_##__HANDLE__##_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; \
HW_hdma_##__HANDLE__##_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; \
HW_hdma_##__HANDLE__##_tx.Init.Mode = DMA_NORMAL; \
HW_hdma_##__HANDLE__##_tx.Init.Priority = DMA_PRIORITY_LOW; \
\
HAL_DMA_Init(&HW_hdma_##__HANDLE__##_tx); \
\
/* Associate the initialized DMA handle to the UART handle */ \
__HAL_LINKDMA(huart, hdmatx, HW_hdma_##__HANDLE__##_tx); \
\
/* NVIC configuration for DMA transfer complete interrupt */ \
HAL_NVIC_SetPriority(CFG_HW_##__USART_BASE__##_TX_DMA_IRQn, CFG_HW_##__USART_BASE__##_DMA_TX_PREEMPTPRIORITY, \
CFG_HW_##__USART_BASE__##_DMA_TX_SUBPRIORITY); \
HAL_NVIC_EnableIRQ(CFG_HW_##__USART_BASE__##_TX_DMA_IRQn); \
} while (0)
/* Variables ------------------------------------------------------------------*/
#if (CFG_HW_USART1_ENABLED == 1)
UART_HandleTypeDef huart1 = { 0 };
#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
DMA_HandleTypeDef HW_hdma_huart1_tx = { 0 };
#endif
void (*HW_huart1RxCb)(void);
void (*HW_huart1TxCb)(void);
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
UART_HandleTypeDef lpuart1 = { 0 };
#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
DMA_HandleTypeDef HW_hdma_lpuart1_tx = { 0 };
#endif
void (*HW_lpuart1RxCb)(void);
void (*HW_lpuart1TxCb)(void);
#endif
void HW_UART_Init(hw_uart_id_t hw_uart_id)
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_INIT(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_INIT(lpuart1, LPUART1);
break;
#endif
default:
break;
}
return;
}
void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*cb)(void))
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_RX_IT(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_RX_IT(lpuart1, LPUART1);
break;
#endif
default:
break;
}
return;
}
void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*cb)(void))
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_TX_IT(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_TX_IT(lpuart1, LPUART1);
break;
#endif
default:
break;
}
return;
}
hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, uint32_t timeout)
{
HAL_StatusTypeDef hal_status = HAL_OK;
hw_status_t hw_status = hw_uart_ok;
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_TX(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_TX(lpuart1, LPUART1);
break;
#endif
default:
break;
}
switch (hal_status)
{
case HAL_OK:
hw_status = hw_uart_ok;
break;
case HAL_ERROR:
hw_status = hw_uart_error;
break;
case HAL_BUSY:
hw_status = hw_uart_busy;
break;
case HAL_TIMEOUT:
hw_status = hw_uart_to;
break;
default:
break;
}
return hw_status;
}
hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*cb)(void))
{
HAL_StatusTypeDef hal_status = HAL_OK;
hw_status_t hw_status = hw_uart_ok;
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_huart1TxCb = cb;
huart1.Instance = USART1;
hal_status = HAL_UART_Transmit_DMA(&huart1, p_data, size);
break;
#endif
#if (CFG_HW_USART2_ENABLED == 1)
case hw_uart2:
HW_huart2TxCb = cb;
huart2.Instance = USART2;
hal_status = HAL_UART_Transmit_DMA(&huart2, p_data, size);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_lpuart1TxCb = cb;
lpuart1.Instance = LPUART1;
hal_status = HAL_UART_Transmit_DMA(&lpuart1, p_data, size);
break;
#endif
default:
break;
}
switch (hal_status)
{
case HAL_OK:
hw_status = hw_uart_ok;
break;
case HAL_ERROR:
hw_status = hw_uart_error;
break;
case HAL_BUSY:
hw_status = hw_uart_busy;
break;
case HAL_TIMEOUT:
hw_status = hw_uart_to;
break;
default:
break;
}
return hw_status;
}
void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id)
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HAL_UART_IRQHandler(&huart1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HAL_UART_IRQHandler(&lpuart1);
break;
#endif
default:
break;
}
return;
}
void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id)
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
case hw_uart1:
HAL_DMA_IRQHandler(huart1.hdmatx);
break;
#endif
#if (CFG_HW_USART2_DMA_TX_SUPPORTED == 1)
case hw_uart2:
HAL_DMA_IRQHandler(huart2.hdmatx);
break;
#endif
#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
case hw_lpuart1:
HAL_DMA_IRQHandler(lpuart1.hdmatx);
break;
#endif
default:
break;
}
return;
}
void HAL_UART_MspInit(UART_HandleTypeDef * huart)
{
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
switch ((uint32_t) huart->Instance)
{
#if (CFG_HW_USART1_ENABLED == 1)
case (uint32_t) USART1:
HW_UART_MSP_UART_INIT(huart1, USART1);
#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
HW_UART_MSP_TX_DMA_INIT(huart1, USART1);
#endif
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case (uint32_t) LPUART1:
HW_UART_MSP_UART_INIT(lpuart1, LPUART1);
#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
HW_UART_MSP_TX_DMA_INIT(lpuart1, LPUART1);
#endif
break;
#endif
default:
break;
}
return;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
{
switch ((uint32_t) huart->Instance)
{
#if (CFG_HW_USART1_ENABLED == 1)
case (uint32_t) USART1:
if (HW_huart1RxCb)
{
HW_huart1RxCb();
}
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case (uint32_t) LPUART1:
if (HW_lpuart1RxCb)
{
HW_lpuart1RxCb();
}
break;
#endif
default:
break;
}
return;
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)
{
switch ((uint32_t) huart->Instance)
{
#if (CFG_HW_USART1_ENABLED == 1)
case (uint32_t) USART1:
if (HW_huart1TxCb)
{
HW_huart1TxCb();
}
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case (uint32_t) LPUART1:
if (HW_lpuart1TxCb)
{
HW_lpuart1TxCb();
}
break;
#endif
default:
break;
}
return;
}