| /** |
| ****************************************************************************** |
| * @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; |
| } |