Loading...
Searching...
No Matches
general_uart.c
Go to the documentation of this file.
/**
**************************************************************************
* @file general_uart.c
* @brief Модуль для инициализации UART.
**************************************************************************
Реализация функций для работы с UART:
- Инициализация UART и его линий RX/TX
- Настройка DMA для UART
- Настройка GPIO для UART
- Настройка NVIC и тактирования UART
**************************************************************************/
#include "general_uart.h"
#include "general_gpio.h"
//-------------------------------------------------------------------
//------------------------UART INIT FUNCTIONS------------------------
/**
* @brief Инициализация UART с помощью структуры UART_SettingsTypeDef.
* @param suart Указатель на структуру с настройками UART.
* @return HAL status.
* @details
* Инициализирует UART и его GPIO и при необходимости DMA.
* Настройка аналогична HAL_UART_Init
* @code
* suart.huart.Init...
* @endcode
* но дополнительно надо прописать пины RX/TX @ref UART_SettingsTypeDef
* @code
* suart->GPIOx, suart->GPIO_PIN_RX, suart->GPIO_PIN_TX
* @endcode
*/
HAL_StatusTypeDef UART_Base_Init(UART_SettingsTypeDef *suart)
{ // function takes setting structure for init
// check is settings are valid
if(UART_Check_Init_Struct(suart) != HAL_OK)
return HAL_ERROR;
suart->huart.Init.Mode = UART_MODE_TX_RX;
UART_MspInit(&suart->huart);
if (HAL_UART_Init(&suart->huart) != HAL_OK)
{
MyLibs_Error_Handler();
return HAL_ERROR;
}
// init gpio from UARTSettings structure
UART_GPIO_Init(suart->GPIOx, suart->GPIO_PIN_RX, suart->GPIO_PIN_TX);
__HAL_UART_ENABLE_IT(&suart->huart, UART_IT_IDLE);
// init dma from UARTSettings structure if need
if (suart->DMAChannel != 0)
UART_DMA_Init(&suart->huart, suart->huart.hdmarx, suart->DMAChannel, suart->DMA_CHANNEL_X);
return HAL_OK;
}
/**
* @brief Инициализация GPIO для UART.
* @param GPIOx Порт для настройки.
* @param GPIO_PIN_RX Пин для приема.
* @param GPIO_PIN_TX Пин для передачи.
*/
void UART_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN_RX, uint16_t GPIO_PIN_TX)
{ // function takes port and pins (for rx and tx)
GPIO_InitTypeDef GPIO_InitStruct = {0};
// choose port for enable clock
GPIO_Clock_Enable(GPIOx);
//USART3 GPIO Configuration
//GPIO_PIN_TX ------> USART_TX
//GPIO_PIN_RX ------> USART_RX
#if defined(STM32F4xx) // gpio init for 407
GPIO_InitStruct.Pin = GPIO_PIN_TX|GPIO_PIN_RX;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
#elif defined(STM32F1xx) // gpio init for atm403/stm103
//GPIO_PIN_TX ------> USART_TX
GPIO_InitStruct.Pin = GPIO_PIN_TX;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
// GPIO_PIN_RX ------> USART_RX
GPIO_InitStruct.Pin = GPIO_PIN_RX;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
#endif
}
/**
* @brief Инициализация DMA для UART.
* @param huart Указатель на хендл UART.
* @param hdma_rx Указатель на хендл DMA для линии приема UART.
* @param DMAChannel Указатель на канал DMA/поток DMA в STM32F407.
* @param DMA_CHANNEL_X Канал DMA.
*/
void UART_DMA_Init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X)
{ // function takes uart and dma handlers and dmachannel for uart
// for now only dma rx is supported, tx maybe later if needed
// calc defines on boot_project_setup.h
/* USART3 DMA Init */
/* USART3_RX Init */
hdma_rx->Instance = DMAChannel;
#if defined(STM32F4xx) // dma channel choose for 407
hdma_rx->Init.Channel = DMA_CHANNEL_X;
#endif
hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx->Init.Mode = DMA_CIRCULAR;
hdma_rx->Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(hdma_rx) != HAL_OK)
{
MyLibs_Error_Handler();
}
__USER_LINKDMA(huart,hdmarx,hdma_rx);
// __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx
// so you get error because hal uses . insted of ->
}
/**
* @brief Настройка тактирования и прерываний UART.
* @param huart Указатель на хендл UART.
* @note Чтобы не генерировать функцию с иницилизацией неиспользуемых UART,
дефайнами @ref UART_INIT в @ref general_uart.h определяются используемые UART.
*/
void UART_MspInit(UART_HandleTypeDef *huart) // analog for hal function
{
// __RCC_DMA_UART_CLK_ENABLE();
// /* DMA interrupt init */
// /* DMA1_Stream1_IRQn interrupt configuration */
// HAL_NVIC_SetPriority(DMA_UART_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA_UART_IRQn);
// rcc, dma and interrupt init for USARTs
// GPIO init was moved to own functions UART_GPIO_Init
if(0);
#ifdef USE_USART1
else if(huart->Instance==USART1)
{
/* DMA2 clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
#endif // USE_USART1
#ifdef USE_USART2
else if(huart->Instance==USART2)
{
/* DMA1 clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
#endif // USE_USART2
#ifdef USE_USART3
else if(huart->Instance==USART3)
{
/* DMA1 clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/* USART3 clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
}
#endif // USE_USART3
#ifdef USE_UART4
else if(huart->Instance==UART4)
{
/* DMA1 clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
/* UART4 clock enable */
__HAL_RCC_UART4_CLK_ENABLE();
/* UART4 interrupt Init */
HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UART4_IRQn);
}
#endif // USE_UART4
#ifdef USE_UART5
else if(huart->Instance==UART5)
{
/* DMA1 clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
/* UART5 clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* UART5 interrupt Init */
HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UART5_IRQn);
}
#endif // USE_UART5
#ifdef USE_USART6
else if(huart->Instance==USART6)
{
/* DMA2 clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
/* USART6 clock enable */
__HAL_RCC_USART6_CLK_ENABLE();
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
}
#endif // USE_USART6
}
/**
* @brief Деинициализация тактирования и прерываний UART.
* @param huart Указатель на хендл UART.
* @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых UART,
дефайнами @ref UART_INIT в @ref general_uart.h определяются используемые UART.
*/
void UART_MspDeInit(UART_HandleTypeDef *huart) // analog for hal function
{
// rcc, dma and interrupt init for USARTs
// GPIO init was moved to own functions UART_GPIO_Init
if(0);
#ifdef USE_USART1
else if(huart->Instance==USART1)
{
// /* DMA2 clock enable */
// __HAL_RCC_DMA2_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* USART1 clock reset */
__HAL_RCC_USART1_FORCE_RESET();
__HAL_RCC_USART1_RELEASE_RESET();
}
#endif // USE_USART1
#ifdef USE_USART2
else if(huart->Instance==USART2)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* USART2 clock reset */
__HAL_RCC_USART2_FORCE_RESET();
__HAL_RCC_USART2_RELEASE_RESET();
}
#endif // USE_USART2
#ifdef USE_USART3
else if(huart->Instance==USART3)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/* USART3 clock reset */
__HAL_RCC_USART3_FORCE_RESET();
__HAL_RCC_USART3_RELEASE_RESET();
}
#endif // USE_USART3
#ifdef USE_UART4
else if(huart->Instance==UART4)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
/* UART4 clock reset */
__HAL_RCC_UART4_FORCE_RESET();
__HAL_RCC_UART4_RELEASE_RESET();
}
#endif // USE_UART4
#ifdef USE_UART5
else if(huart->Instance==UART5)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
/* UART5 clock reset */
__HAL_RCC_UART5_FORCE_RESET();
__HAL_RCC_UART5_RELEASE_RESET();
}
#endif // USE_UART5
#ifdef USE_USART6
else if(huart->Instance==USART6)
{
// /* DMA2 clock enable */
// __HAL_RCC_DMA2_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
/* USART6 clock reset */
__HAL_RCC_USART6_FORCE_RESET();
__HAL_RCC_USART6_RELEASE_RESET();
}
#endif // USE_USART6
}
/**
* @brief Проверка корректности структуры инициализации UART.
* @param suart Указатель на структуру с настройками UART.
* @return HAL status.
*/
HAL_StatusTypeDef UART_Check_Init_Struct(UART_SettingsTypeDef *suart)
{
// check is settings are valid
if (!IS_UART_INSTANCE(suart->huart.Instance))
return HAL_ERROR;
if (!IS_UART_BAUDRATE(suart->huart.Init.BaudRate) || (suart->huart.Init.BaudRate == NULL))
return HAL_ERROR;
if (!IS_GPIO_ALL_INSTANCE(suart->GPIOx))
return HAL_ERROR;
if (!IS_GPIO_PIN(suart->GPIO_PIN_RX) && !IS_GPIO_PIN(suart->GPIO_PIN_TX)) // if both pins arent set up
return HAL_ERROR;
return HAL_OK;
}
//------------------------UART INIT FUNCTIONS------------------------
//-------------------------------------------------------------------
general_gpio.h
Заголовочный файл для модуля инициализации портов и работы с ними.
UART_GPIO_Init
void UART_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN_RX, uint16_t GPIO_PIN_TX)
Инициализация GPIO для UART.
Definition general_uart.c:69
UART_DMA_Init
void UART_DMA_Init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X)
Инициализация DMA для UART.
Definition general_uart.c:109
general_uart.h
Заголовочный файл для модуля инициализации UART.
MyLibs_Error_Handler
#define MyLibs_Error_Handler(params)
Error_Handler который будет вызыватся в библиотеке
Definition mylibs_defs.h:31
UART_Check_Init_Struct
HAL_StatusTypeDef UART_Check_Init_Struct(UART_SettingsTypeDef *suart)
Проверка корректности структуры инициализации UART.
Definition general_uart.c:364
UART_MspDeInit
void UART_MspDeInit(UART_HandleTypeDef *huart)
Деинициализация тактирования и прерываний UART.
Definition general_uart.c:267
UART_MspInit
void UART_MspInit(UART_HandleTypeDef *huart)
Настройка тактирования и прерываний UART.
Definition general_uart.c:146
UART_Base_Init
HAL_StatusTypeDef UART_Base_Init(UART_SettingsTypeDef *suart)
Инициализация UART с помощью структуры UART_SettingsTypeDef.
Definition general_uart.c:32
GPIO_Clock_Enable
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
Включить тактирование порта GPIO.
Definition general_gpio.c:22
UART_SettingsTypeDef
Структура настроек UART.
Definition general_uart.h:97
UART_SettingsTypeDef::DMA_CHANNEL_X
uint32_t DMA_CHANNEL_X
Номер канала DMA (0 если не нужен)
Definition general_uart.h:105
UART_SettingsTypeDef::DMAChannel
DMA_Stream_TypeDef * DMAChannel
Канал DMA (NULL если не нужен)
Definition general_uart.h:104
UART_SettingsTypeDef::GPIO_PIN_RX
uint16_t GPIO_PIN_RX
Пин приема
Definition general_uart.h:101
UART_SettingsTypeDef::GPIO_PIN_TX
uint16_t GPIO_PIN_TX
Пин передачи
Definition general_uart.h:102
UART_SettingsTypeDef::huart
UART_HandleTypeDef huart
HAL handle UART.
Definition general_uart.h:98
UART_SettingsTypeDef::GPIOx
GPIO_TypeDef * GPIOx
Порт для UART.
Definition general_uart.h:100