Добавлены библиотеки adc, modbus (его надо проверить)

В библиотеке adc пока только сделана заготовка для считывания выброса, надо доделать:
Пока в main крутиться тест: формирование импульса ножкой светодиодом и считыание АЦП. Считывается этот импульс и определяется его пик (максимальное значение) и в районе этого пика беруться значения для расчета его амплитуды

Modbus добавлен но не проверен
This commit is contained in:
2024-12-17 18:24:41 +03:00
parent 580bac9f52
commit a2043006cc
35 changed files with 12115 additions and 85 deletions

File diff suppressed because one or more lines are too long

View File

@@ -65,7 +65,7 @@
/*#define HAL_SPI_MODULE_ENABLED */
/*#define HAL_SRAM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_UART_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */

View File

@@ -56,7 +56,9 @@ void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA1_Channel1_IRQHandler(void);
void TIM2_IRQHandler(void);
void TIM3_IRQHandler(void);
void USART1_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

View File

@@ -32,12 +32,15 @@ extern "C" {
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM2_Init(void);
void MX_TIM3_Init(void);
/* USER CODE BEGIN Prototypes */

View File

@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.h
* @brief This file contains all the function prototypes for
* the usart.c file
******************************************************************************
* @attention
*
* Copyright (c) 2024 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_USART1_UART_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */

View File

@@ -0,0 +1,116 @@
#include "crc_algs.h"
uint32_t CRC_calc;
uint32_t CRC_ref;
//uint16_t CRC_calc;
//uint16_t CRC_ref;
// left this global for debug
uint8_t uchCRCHi = 0xFF;
uint8_t uchCRCLo = 0xFF;
unsigned uIndex;
uint32_t crc32(uint8_t *data, uint32_t data_size)
{
static const unsigned int crc32_table[] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
unsigned int crc = 0xFFFFFFFF;
while (data_size--)
{
crc = (crc >> 8) ^ crc32_table[(crc ^ *data) & 255];
data++;
}
return crc^0xFFFFFFFF;
}
uint16_t crc16(uint8_t *data, uint32_t data_size)
{
/*Table of CRC values for high order byte*/
static unsigned char auchCRCHi[]=
{
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
};
/*Table of CRC values for low order byte*/
static char auchCRCLo[] =
{
0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40,
};
uchCRCHi = 0xFF;
uchCRCLo = 0xFF;
/* CRC Generation Function */
while( data_size--) /* pass through message buffer */
{
uIndex = uchCRCHi ^ *data++; /* calculate the CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
uchCRCLo = auchCRCLo[uIndex];
}
return uchCRCHi | uchCRCLo<<8;
}

View File

@@ -0,0 +1,9 @@
#include "mylibs_include.h"
// extern here to use in bootloader.c
extern uint32_t CRC_calc;
extern uint32_t CRC_ref;
uint16_t crc16(uint8_t *data, uint32_t data_size);
uint32_t crc32(uint8_t *data, uint32_t data_size);

View File

@@ -0,0 +1,125 @@
/**
**************************************************************************
* @file interface_config.h
* @brief Конфигурации для интерфейсов
**************************************************************************
* @defgroup INTERFACE_CONFIGS Configs for interfaces
* @brief Конфигурации для интерфейсов
* @details
@{
*************************************************************************/
#ifndef _INTERFACE_CONFIG_H_
#define _INTERFACE_CONFIG_H_
/**
* @addtogroup MODBUS_CONFIG Конфигурации для модбас
* @ingroup INTERFACE_CONFIGS
* @ingroup MODBUS
@{
*/
#define MODBUS_UART_NUMB 3 ///< Номер используемого UART, по нему выставляется дефайн USED_MB_UART = USARTx
#define MODBUS_SPEED 115200 ///< Скорость UART для модбас
#define MODBUS_GPIOX GPIOB ///< Порт для UART RX/TX
#define MODBUS_GPIO_PIN_RX GPIO_PIN_11 ///< Пин для UART RX
#define MODBUS_GPIO_PIN_TX GPIO_PIN_10 ///< Пин для UART TX
#define MODBUS_TIM_NUMB 7 ///< number of used tim, accord to this define sets define USED_MB_TIM = TIMx
#define MODBUS_TIM_AHB_FREQ 72 ///< TIM AHB Bus Freq
// defines for modbus behaviour
#define MODBUS_DEVICE_ID 1 ///< девайс текущего устройства
#define MODBUS_MAX_TIMEOUT 5000 ///< максимальнйы тайтаут MB is ms
#define RS_UART_Init MX_USART1_UART_Init
#define RS_UART_DeInit HAL_UART_MspDeInit
#define RS_TIM_Init MX_TIM2_Init
#define RS_TIM_DeInit HAL_TIM_Base_MspDeInit
#define rs_huart huart1
#define rs_htim htim2
/////////////////////////////////////////////////////////////////////
/////////////////////////---CALC DEFINES---//////////////////////////
/* set USART_TypeDef for choosen numb of usart */
#if (MODBUS_UART_NUMB == 1)
#define USED_MODBUS_UART USART1
#define USE_USART1
#elif (MODBUS_UART_NUMB == 2)
#define USED_MODBUS_UART USART2
#define USE_USART2
#elif (MODBUS_UART_NUMB == 3)
#define USED_MODBUS_UART USART3
#define USE_USART3
#elif (MODBUS_UART_NUMB == 4)
#define USED_MODBUS_UART UART4
#define USE_UART4
#elif (MODBUS_UART_NUMB == 5)
#define USED_MODBUS_UART UART5
#define USE_UART6
#elif (MODBUS_UART_NUMB == 6)
#define USED_MODBUS_UART USART6
#define USE_USART6
#endif
#if (MODBUS_TIM_NUMB == 1)
#define USED_MODBUS_TIM TIM1
#define USE_TIM1
#elif (MODBUS_TIM_NUMB == 2)
#define USED_MODBUS_TIM TIM2
#define USE_TIM2
#elif (MODBUS_TIM_NUMB == 3)
#define USED_MODBUS_TIM TIM3
#define USE_TIM3
#elif (MODBUS_TIM_NUMB == 4)
#define USED_MODBUS_TIM TIM4
#define USE_TIM4
#elif (MODBUS_TIM_NUMB == 5)
#define USED_MODBUS_TIM TIM5
#define USE_TIM5
#elif (MODBUS_TIM_NUMB == 6)
#define USED_MODBUS_TIM TIM6
#define USE_TIM6
#elif (MODBUS_TIM_NUMB == 7)
#define USED_MODBUS_TIM TIM7
#define USE_TIM7
#elif (MODBUS_TIM_NUMB == 8)
#define USED_MODBUS_TIM TIM8
#define USE_TIM8
#elif (MODBUS_TIM_NUMB == 9)
#define USED_MODBUS_TIM TIM9
#define USE_TIM9
#elif (MODBUS_TIM_NUMB == 10)
#define USED_MODBUS_TIM TIM10
#define USE_TIM10
#elif (MODBUS_TIM_NUMB == 11)
#define USED_MODBUS_TIM TIM11
#define USE_TIM11
#elif (MODBUS_TIM_NUMB == 12)
#define USED_MODBUS_TIM TIM12
#define USE_TIM12
#elif (MODBUS_TIM_NUMB == 13)
#define USED_MODBUS_TIM TIM13
#define USE_TIM13
#elif (MODBUS_TIM_NUMB == 14)
#define USED_MODBUS_TIM TIM14
#define USE_TIM14
#endif
/** MODBUS_CONFIG
* @}
*/
/** INTERFACE_CONFIGS
* @}
*/
#endif //_INTERFACE_CONFIG_H_

View File

@@ -0,0 +1,938 @@
/**
**************************************************************************
* @file modbus.c
* @brief Модуль для реализации MODBUS.
**************************************************************************
* @par Функции и дефайны
*
* Defines: data access
* - MB_Set_Coil_Local() - Выставление коила по локальному адресу относительно начала массива
* - MB_Reset_Coil_Local() - Сброс коила по локальному адресу относительно начала массива
* - MB_Toogle_Coil_Local() - Переключение коила по локальному адресу относительно начала массива
* - MB_Read_Coil_Local() - Чтение коила по локальному адресу относительно начала массива
*
* Functions: data access
* - MB_Write_Coil_Global() - Запись 0/1 в один коил по глобальному адресу
* - MB_Read_Coil_Global() - Чтение одного коила по глобальному адресу
*
* Functions: process message
* - MB_DefineRegistersAddress() - Определение "начального" адреса регистров
* - MB_DefineCoilsAddress() - Определение "начального" адреса коилов
* - MB_Check_Address_For_Arr() - Определение принадлежит ли адресс Addr конкретному массиву
* - Обработка команд модбас
* - MB_Read_Coils(),
* - MB_Read_Hold_Regs(),
* - MB_Write_Single_Coil()
* - MB_Write_Miltuple_Coils()
* - MB_Write_Miltuple_Regs()
*
* Functions: RS functions
* - RS_Parse_Message() / RS_Collect_Message() - Заполнение структуры сообщения и буфера
* - RS_Response() - Ответ на комманду
* - RS_Define_Size_of_RX_Message() - Определение размера принимаемых данных
* - RS_Init() - Инициализация периферии и modbus handler
*
* Functions: initialization
* - MODBUS_FirstInit() - Инициализация modbus
*
**************************************************************************
* @par Данные для модбас
*
* Holding/Input Registers
* - Регистры представляют собой 16-битные числа (слова). В обработке комманд
* находится адресс "начального" регистра и записывается в указатель. Доступ к
* остальным регистрам осуществляется через указатель. Таким образом, сами
* регистры могут представлять собой как массив так и структуру.
*
* Coils
* - Коилы представляют собой биты, упакованные в 16-битные регистры. В обработке
* комманд находится адресс "начального" регистра запрашиваемого коила. Доступ к
* остальным коилам осуществляется через маску и указатель. Таким образом, сами
* коилы могут представлять собой как массив так и структуру.
*
@verbatim
EXAMPLE: INIT SLAVE RECEIVE
//--------------Настройка модбас--------------//
// set up UART for modbus
modbus1_suart.huart.Instance = USED_MODBUS_UART;
modbus1_suart.huart.Init.BaudRate = PROJSET.MB_SPEED;
modbus1_suart.GPIOx = GPIOB;
modbus1_suart.GPIO_PIN_RX = GPIO_PIN_11;
modbus1_suart.GPIO_PIN_TX = GPIO_PIN_10;
// set up timeout TIM for modbus
modbus1_stim.htim.Instance = TIM7;
modbus1_stim.sTimAHBFreqMHz = 84;
modbus1_stim.sTimMode = TIM_IT_CONF;
// set up modbus: MB_RX_Size_NotConst and Timeout enable
hmodbus1.ID = 1;
hmodbus1.sRS_Timeout = 5000;
hmodbus1.sRS_Mode = SLAVE_ALWAYS_WAIT;
hmodbus1.sRS_RX_Size_Mode = RS_RX_Size_NotConst;
// INIT
hmodbus1.RS_STATUS = RS_Init(&hmodbus1, &modbus1_suart, &modbus1_stim, 0);
//----------------Прием модбас----------------//
RS_MsgTypeDef MODBUS_MSG;
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
@endverbatim
*************************************************************************/
#include "rs_message.h"
uint32_t dbg_temp, dbg_temp2, dbg_temp3; // for debug
/* MODBUS HANDLES */
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
UART_SettingsTypeDef modbus1_suart;
TIM_SettingsTypeDef modbus1_stim;
#else
extern UART_HandleTypeDef rs_huart;
extern TIM_HandleTypeDef rs_htim;
#endif
RS_HandleTypeDef hmodbus1;
/* DEFINE REGISTERS/COILS */
MB_DataStructureTypeDef MB_DATA;
RS_MsgTypeDef MODBUS_MSG;
uint32_t delay_scide = 1;
uint32_t numb_scide = 10;
//-------------------------------------------------------------------
//-----------------------------FOR USER------------------------------
/**
* @brief First set up of MODBUS.
* @details Первый инит модбас. Заполняет структуры и инициализирует таймер и юарт для общения по модбас.
* Скважность ШИМ меняется по закону синусоиды, каждый канал генерирует свой полупериод синуса (от -1 до 0 И от 0 до 1)
* ШИМ генерируется на одном канале.
* @note This called from main
*/
void MODBUS_FirstInit(void)
{
//-----------SETUP MODBUS-------------
// set up UART for modbus
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
modbus1_suart.huart.Instance = USED_MODBUS_UART;
modbus1_suart.huart.Init.BaudRate = MODBUS_SPEED;
modbus1_suart.GPIOx = MODBUS_GPIOX;
modbus1_suart.GPIO_PIN_RX = MODBUS_GPIO_PIN_RX;
modbus1_suart.GPIO_PIN_TX = MODBUS_GPIO_PIN_TX;
// set up timeout TIM for modbus
modbus1_stim.htim.Instance = USED_MODBUS_TIM;
modbus1_stim.sTimAHBFreqMHz = MODBUS_TIM_AHB_FREQ;
modbus1_stim.sTimMode = TIM_IT_CONF;
#endif
// set up modbus: MB_RX_Size_NotConst and Timeout enable
hmodbus1.ID = MODBUS_DEVICE_ID;
hmodbus1.sRS_Timeout = MODBUS_MAX_TIMEOUT;
hmodbus1.sRS_Mode = SLAVE_ALWAYS_WAIT;
hmodbus1.sRS_RX_Size_Mode = RS_RX_Size_NotConst;
// INIT
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
hmodbus1.RS_STATUS = RS_Init(&hmodbus1, &modbus1_suart, &modbus1_stim, 0);
#else
hmodbus1.RS_STATUS = RS_Init(&hmodbus1, &rs_huart, &rs_htim, 0);
#endif
RS_EnableReceive();
}
/**
* @brief Set or Reset Coil at its global address.
* @param Addr - адрес коила.
* @param WriteVal - Что записать в коил: 0 или 1.
* @return ExceptionCode - Код исключения если коила по адресу не существует, и NO_ERRORS если все ок.
*
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти.
*/
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception = NO_ERRORS;
uint16_t *coils;
uint16_t start_shift = 0; // shift in coils register
//------------WRITE COIL-------------
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
if(Exception == NO_ERRORS)
{
switch(WriteVal)
{
case SET_COIL:
*coils |= (1<<start_shift);
break;
case RESET_COIL:
*coils &= ~(1<<start_shift);
break;
case TOOGLE_COIL:
*coils ^= (1<<start_shift);
break;
}
}
return Exception;
}
/**
* @brief Read Coil at its global address.
* @param Addr - адрес коила.
* @param Exception - Указатель на переменную для кода исключения, в случа неудачи при чтении.
* @return uint16_t - Возвращает весь регистр с маской на запрошенном коиле.
*
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти.
*/
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception_tmp;
if(Exception == NULL) // if exception is not given to func fill it
Exception = &Exception_tmp;
uint16_t *coils;
uint16_t start_shift = 0; // shift in coils register
//------------READ COIL--------------
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
if(*Exception == NO_ERRORS)
{
return ((*coils)&(1<<start_shift));
}
else
{
return 0;
}
}
//-------------------------------------------------------------------
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
/**
* @brief Check is address valid for certain array.
* @param Addr - начальный адресс.
* @param Qnt - количество запрашиваемых элементов.
* @param R_ARR_ADDR - начальный адресс массива R_ARR.
* @param R_ARR_NUMB - количество элементов в массиве R_ARR.
* @return ExceptionCode - ILLEGAL DATA ADRESS если адресс недействителен, и NO_ERRORS если все ок.
*
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
* Если адресс Addr находится за пределами адрессов массива R_ARR - ILLEGAL_DATA_ADDRESSю.
*/
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
{
// if address from this array
if(Addr >= R_ARR_ADDR)
{
// if quantity too big return error
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
{
return ILLEGAL_DATA_ADDRESS; // return exception code
}
// if all ok - return no errors
return NO_ERRORS;
}
// if address isnt from this array return error
else
return ILLEGAL_DATA_ADDRESS; // return exception code
}
/**
* @brief Define Address Origin for Input/Holding Registers
* @param pRegs - указатель на указатель регистров.
* @param Addr - адрес начального регистра.
* @param Qnt - количество запрашиваемых регистров.
* @param WriteFlag - флаг регистр нужны для чтения или записи.
* @return ExceptionCode - Код исключения если есть, и NO_ERRORS если нет.
*
* @details Определение адреса начального регистра.
* @note WriteFlag пока не используется.
*/
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
{
/* check quantity error */
if (Qnt > 125)
{
return ILLEGAL_DATA_VALUE; // return exception code
}
if(RegisterType == RegisterType_Holding)
{
// Устаки для напряжений ТЭ: предупреждения аварии
if(MB_Check_Address_For_Arr(Addr, Qnt, R_SETPOINTS_ADDR, R_SETPOINTS_QNT) == NO_ERRORS)
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr); // начало регистров хранения/входных
}
// Устаки для настройки МЗКТЭ: запрет опроса и настройки общения (MODBUS/UART)
else if(MB_Check_Address_For_Arr(Addr, Qnt, R_SETTINGS_ADDR, R_SETTINGS_QNT) == NO_ERRORS)
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr); // начало регистров хранения/входных
}
// if address doesnt match any array - return illegal data address response
else
{
return ILLEGAL_DATA_ADDRESS;
}
}
else if(RegisterType == RegisterType_Input)
{
// Напряжения на ТЭ
if(MB_Check_Address_For_Arr(Addr, Qnt, R_TE_VOLTAGE_ADDR, R_TE_VOLTAGE_QNT) == NO_ERRORS)
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr); // начало регистров хранения/входных
}
// Статус регистр МЗКТЭ
else if(MB_Check_Address_For_Arr(Addr, Qnt, R_STATUS_REG_ADDR, R_STATUS_REG_QNT) == NO_ERRORS)
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr); // начало регистров хранения/входных
}
// if address doesnt match any array - return illegal data address response
else
{
return ILLEGAL_DATA_ADDRESS;
}
}
else
{
return ILLEGAL_FUNCTION;
}
// if found requeried array return no err
return NO_ERRORS; // return no errors
}
/**
* @brief Define Address Origin for coils
* @param pCoils - указатель на указатель коилов.
* @param Addr - адресс начального коила.
* @param Qnt - количество запрашиваемых коилов.
* @param start_shift - указатель на переменную содержащую сдвиг внутри регистра для начального коила.
* @param WriteFlag - флаг коилы нужны для чтения или записи.
* @return ExceptionCode - Код исключения если есть, и NO_ERRORS если нет.
*
* @details Определение адреса начального регистра запрашиваемых коилов.
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
*/
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag)
{
/* check quantity error */
if (Qnt > 2000)
{
return ILLEGAL_DATA_VALUE; // return exception code
}
// peripheral control coils
if(MB_Check_Address_For_Arr(Addr, Qnt, C_TE_EXCLUDE_ADDR, C_TE_EXCLUDE_QNT) == NO_ERRORS)
{
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr-C_TE_EXCLUDE_ADDR);
}
// if address doesnt match any array - return illegal data address response
else
{
return ILLEGAL_DATA_ADDRESS;
}
*start_shift = Addr % 16; // set shift to requested coil
// if found requeried array return no err
return NO_ERRORS; // return no errors
}
/**
* @brief Proccess command Read Coils (01 - 0x01).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Read Coils.
*/
uint8_t MB_Read_Coils(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
uint16_t *coils;
uint16_t start_shift = 0; // shift in coils register
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 0);
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//-----------READING COIL------------
// setup output message data size
modbus_msg->ByteCnt = Divide_Up(modbus_msg->Qnt, 8);
// create mask for coils
uint16_t mask_for_coils = 0; // mask for coils that've been chosen
uint16_t setted_coils = 0; // value of setted coils
uint16_t temp_reg = 0; // temp register for saving coils that hasnt been chosen
uint16_t coil_cnt = 0; // counter for processed coils
// cycle until all registers with requered coils would be processed
int shift = start_shift; // set shift to first coil in first register
int ind = 0; // index for coils registers and data
for(; ind <= Divide_Up(start_shift + modbus_msg->Qnt, 16); ind++)
{
//----SET MASK FOR COILS REGISTER----
mask_for_coils = 0;
for(; shift < 0x10; shift++)
{
mask_for_coils |= 1<<(shift); // choose certain coil
if(++coil_cnt >= modbus_msg->Qnt)
break;
}
shift = 0; // set shift to zero for the next step
//-----------READ COILS--------------
modbus_msg->DATA[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
if(ind > 0)
modbus_msg->DATA[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
}
// т.к. DATA 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
for(; ind >= 0; --ind)
modbus_msg->DATA[ind] = ByteSwap16(modbus_msg->DATA[ind]);
return 1;
}
/**
* @brief Proccess command Read Holding Registers (03 - 0x03).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Read Holding Registers.
*/
uint8_t MB_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
// get origin address for data
uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//-----------READING REGS------------
// setup output message data size
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
// read data
int i;
for (i = 0; i<modbus_msg->Qnt; i++)
{
modbus_msg->DATA[i] = *(pHoldRegs++);
}
return 1;
}
/**
* @brief Proccess command Read Input Registers (04 - 0x04).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Read Input Registers.
*/
uint8_t MB_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
// get origin address for data
uint16_t *pInRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input); // определение адреса регистров
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//-----------READING REGS------------
// setup output message data size
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
// read data
int i;
for (i = 0; i<modbus_msg->Qnt; i++)
{
if(*((int16_t *)pInRegs) > 0)
modbus_msg->DATA[i] = (*pInRegs++);
else
modbus_msg->DATA[i] = (*pInRegs++);
}
return 1;
}
/**
* @brief Proccess command Write Single Coils (05 - 0x05).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Write Single Coils.
*/
uint8_t MB_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00))
{
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
return 0;
}
// define position of coil
uint16_t *coils;
uint16_t start_shift = 0; // shift in coils register
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1);
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//----------WRITTING COIL------------
if(modbus_msg->Qnt == 0xFF00)
*(coils) |= 1<<start_shift; // write flags corresponding to received data
else
*(coils) &= ~(1<<start_shift); // write flags corresponding to received data
return 1;
}
/**
* @brief Proccess command Write Single Register (06 - 0x06).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Write Single Register.
*/
uint8_t MB_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
{
// get origin address for data
uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//-----------WRITTING REG------------
*(pHoldRegs) = modbus_msg->Qnt;
return 1;
}
/**
* @brief Proccess command Write Multiple Coils (15 - 0x0F).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Write Multiple Coils.
*/
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
{ // if quantity too large OR if quantity and bytes count arent match
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
return 0;
}
// define position of coil
uint16_t *coils; // pointer to coils
uint16_t start_shift = 0; // shift in coils register
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 1);
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//----------WRITTING COILS-----------
// create mask for coils
uint16_t mask_for_coils = 0; // mask for coils that've been chosen
uint32_t setted_coils = 0; // value of setted coils
uint16_t temp_reg = 0; // temp register for saving coils that hasnt been chosen
uint16_t coil_cnt = 0; // counter for processed coils
// cycle until all registers with requered coils would be processed
int shift = start_shift; // set shift to first coil in first register
for(int ind = 0; ind <= Divide_Up(start_shift + modbus_msg->Qnt, 16); ind++)
{
//----SET MASK FOR COILS REGISTER----
mask_for_coils = 0;
for(; shift < 0x10; shift++)
{
mask_for_coils |= 1<<(shift); // choose certain coil
if(++coil_cnt >= modbus_msg->Qnt)
break;
}
shift = 0; // set shift to zero for the next step
//-----------WRITE COILS-------------
// get current coils
temp_reg = *(coils+ind);
// set coils
setted_coils = ByteSwap16(modbus_msg->DATA[ind]) << start_shift;
if(ind > 0)
{
setted_coils |= ((ByteSwap16(modbus_msg->DATA[ind-1]) << start_shift) >> 16);
}
// write coils
*(coils+ind) = setted_coils & mask_for_coils;
// restore untouched coils
*(coils+ind) |= temp_reg&(~mask_for_coils);
if(coil_cnt >= modbus_msg->Qnt) // if all coils written - break cycle
break; // *kind of unnecessary
}
return 1;
}
/**
* @brief Proccess command Write Multiple Registers (16 - 0x10).
* @param modbus_msg - указатель на структуру собщения modbus.
* @return fMessageHandled - статус о результате обработки комманды.
* @details Обработка команды Write Multiple Registers.
*/
uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
if (modbus_msg->Qnt*2 != modbus_msg->ByteCnt)
{ // if quantity and bytes count arent match
modbus_msg->Except_Code = 3;
return 0;
}
// get origin address for data
uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
if(modbus_msg->Except_Code != NO_ERRORS)
return 0;
//-----------WRITTING REGS-----------
for (int i = 0; i<modbus_msg->Qnt; i++)
{
*(pHoldRegs++) = modbus_msg->DATA[i];
}
return 1;
}
/**
* @brief Respond accord to received message.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @return RS_RES - статус о результате ответа на комманду.
* @details Обработка принятой комманды и ответ на неё.
*/
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
{
RS_StatusTypeDef MB_RES = 0;
hmodbus->f.MessageHandled = 0;
hmodbus->f.EchoResponse = 0;
RS_Reset_TX_Flags(hmodbus); // reset flag for correct transmit
if(modbus_msg->Func_Code < ERR_VALUES_START)// if no errors after parsing
{
switch (modbus_msg->Func_Code)
{
// Read Coils
case MB_R_COILS:
hmodbus->f.MessageHandled = MB_Read_Coils(hmodbus->pMessagePtr);
break;
// Read Hodling Registers
case MB_R_HOLD_REGS:
hmodbus->f.MessageHandled = MB_Read_Hold_Regs(hmodbus->pMessagePtr);
break;
case MB_R_IN_REGS:
hmodbus->f.MessageHandled = MB_Read_Input_Regs(hmodbus->pMessagePtr);
break;
// Write Single Coils
case MB_W_COIL:
hmodbus->f.MessageHandled = MB_Write_Single_Coil(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
hmodbus->f.EchoResponse = 1;
hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
}
break;
case MB_W_HOLD_REG:
hmodbus->f.MessageHandled = MB_Write_Single_Reg(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
hmodbus->f.EchoResponse = 1;
hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
}
break;
// Write Multiple Coils
case MB_W_COILS:
hmodbus->f.MessageHandled = MB_Write_Miltuple_Coils(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
hmodbus->f.EchoResponse = 1;
hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
}
break;
// Write Multiple Registers
case MB_W_HOLD_REGS:
hmodbus->f.MessageHandled = MB_Write_Miltuple_Regs(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
hmodbus->f.EchoResponse = 1;
hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
}
break;
/* unknown func code */
default: modbus_msg->Except_Code = 0x01; /* set exception code: illegal function */
}
if(hmodbus->f.MessageHandled == 0)
{
TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code += ERR_VALUES_START;
}
else
{
TrackerCnt_Ok(hmodbus->rs_err);
}
}
// if we need response - check that transmit isnt busy
if( RS_Is_TX_Busy(hmodbus) )
RS_Abort(hmodbus, ABORT_TX); // if tx busy - set it free
// Transmit right there, or sets (fDeferredResponse) to transmit response in main code
MB_RES = RS_Handle_Transmit_Start(hmodbus, modbus_msg);
hmodbus->RS_STATUS = MB_RES;
return MB_RES;
}
/**
* @brief Collect message in buffer to transmit it.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @param msg_uart_buff - указатель на буффер UART.
* @return RS_RES - статус о результате заполнения буфера.
* @details Заполнение буффера UART из структуры сообщения.
*/
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
{
int ind = 0; // ind for modbus-uart buffer
if(hmodbus->f.EchoResponse && hmodbus->f.MessageHandled) // if echo response need
ind = hmodbus->RS_Message_Size;
else
{
//------INFO ABOUT DATA/MESSAGE------
//-----------[first bytes]-----------
// set ID of message/user
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
// set dat or err response
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
{
// set size of received data
if (modbus_msg->ByteCnt <= DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
else // otherwise return data_size err
{
TrackerCnt_Err(hmodbus->rs_err);
return RS_COLLECT_MSG_ERR;
}
//---------------DATA----------------
//-----------[data bytes]------------
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
{ // set data
if (i%2 == 0) // HI byte
modbus_uart_buff[ind++] = (*tmp_data_addr)>>8;
else // LO byte
{
modbus_uart_buff[ind++] = *tmp_data_addr;
tmp_data_addr++;
}
}
}
else // if some error occur
{ // send expection code
modbus_uart_buff[ind++] = modbus_msg->Except_Code;
}
}
//---------------CRC----------------
//---------[last 16 bytes]----------
// calc crc of received data
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
// write crc to message structure and modbus-uart buffer
modbus_msg->MB_CRC = CRC_VALUE;
modbus_uart_buff[ind++] = CRC_VALUE;
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
hmodbus->RS_Message_Size = ind;
return RS_OK; // returns ok
}
/**
* @brief Parse message from buffer to process it.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @param msg_uart_buff - указатель на буффер UART.
* @return RS_RES - статус о результате заполнения структуры.
* @details Заполнение структуры сообщения из буффера UART.
*/
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
{
uint32_t check_empty_buff;
int ind = 0; // ind for modbus-uart buffer
//-----INFO ABOUT DATA/MESSAGE-------
//-----------[first bits]------------
// get ID of message/user
modbus_msg->MbAddr = modbus_uart_buff[ind++];
if(modbus_msg->MbAddr != hmodbus->ID)
return RS_SKIP;
// get dat or err response
modbus_msg->Func_Code = modbus_uart_buff[ind++];
// get address from CMD
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
modbus_msg->Addr |= modbus_uart_buff[ind++];
// get address from CMD
modbus_msg->Qnt = modbus_uart_buff[ind++] << 8;
modbus_msg->Qnt |= modbus_uart_buff[ind++];
if(hmodbus->f.RX_Half == 0) // if all message received
{
//---------------DATA----------------
// (optional)
if (modbus_msg->ByteCnt != 0)
{
ind++; // increment ind for data_size byte
//check that data size is correct
if (modbus_msg->ByteCnt > DATA_SIZE*2)
{
TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code += ERR_VALUES_START;
return RS_PARSE_MSG_ERR;
}
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
for(int i = 0; i < modbus_msg->ByteCnt; i++) // /2 because we transmit 8 bits, not 16 bits
{ // set data
if (i%2 == 0)
*tmp_data_addr = ((uint16_t)modbus_uart_buff[ind++] << 8);
else
{
*tmp_data_addr |= modbus_uart_buff[ind++];
tmp_data_addr++;
}
}
}
//---------------CRC----------------
//----------[last 16 bits]----------
// calc crc of received data
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
// get crc of received data
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
// compare crc
if (modbus_msg->MB_CRC != CRC_VALUE)
{
TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code += ERR_VALUES_START;
}
// hmodbus->MB_RESPONSE = MB_CRC_ERR; // set func code - error about wrong crc
// check is buffer empty
check_empty_buff = 0;
for(int i=0; i<ind;i++)
check_empty_buff += modbus_uart_buff[i];
// if(check_empty_buff == 0)
// hmodbus->MB_RESPONSE = MB_EMPTY_MSG; //
}
return RS_OK;
}
/**
* @brief Define size of RX Message that need to be received.
* @param hRS - указатель на хендлер RS.
* @param rx_data_size - указатель на переменную для записи кол-ва байт для принятия.
* @return RS_RES - статус о корректности рассчета кол-ва байт для принятия.
* @details Определение сколько байтов надо принять по протоколу.
*/
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hmodbus, uint32_t *rx_data_size)
{
RS_StatusTypeDef MB_RES = 0;
MB_RES = RS_Parse_Message(hmodbus, hmodbus->pMessagePtr, hmodbus->pBufferPtr);
if(MB_RES == RS_SKIP) // if message not for us
return MB_RES; // return
if ((hmodbus->pMessagePtr->Func_Code & ~ERR_VALUES_START) < 0x0F)
{
hmodbus->pMessagePtr->ByteCnt = 0;
*rx_data_size = 1;
}
else
{
hmodbus->pMessagePtr->ByteCnt = hmodbus->pBufferPtr[RX_FIRST_PART_SIZE-1]; // get numb of data in command
// +1 because that defines is size, not ind.
*rx_data_size = hmodbus->pMessagePtr->ByteCnt + 2;
}
hmodbus->RS_Message_Size = RX_FIRST_PART_SIZE + *rx_data_size; // size of whole message
return RS_OK;
}
//-----------------------------FOR USER------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------HANDLERS FUNCTION-------------------------
#if (MODBUS_UART_NUMB == 1) // choose handler for UART
void USART1_IRQHandler(void)
#elif (MODBUS_UART_NUMB == 2)
void USART2_IRQHandler(void)
#elif (MODBUS_UART_NUMB == 3)
void USART3_IRQHandler(void)
#elif (MODBUS_UART_NUMB == 4)
void USART4_IRQHandler(void)
#elif (MODBUS_UART_NUMB == 5)
void USART5_IRQHandler(void)
#elif (MODBUS_UART_NUMB == 6)
void USART6_IRQHandler(void)
#endif
{
Trace_MB_UART_Enter();
RS_UART_Handler(&hmodbus1);
Trace_MB_UART_Exit();
}
#if (MODBUS_TIM_NUMB == 1) || (MODBUS_TIM_NUMB == 10) // choose handler for TIM
void TIM1_UP_TIM10_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 2)
void TIM2_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 3)
void TIM3_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 4)
void TIM4_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 5)
void TIM5_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 6)
void TIM6_DAC_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 7)
void TIM7_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 8) || (MODBUS_TIM_NUMB == 13)
void TIM8_UP_TIM13_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 1) || (MODBUS_TIM_NUMB == 9)
void TIM1_BRK_TIM9_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 1) || (MODBUS_TIM_NUMB == 11)
void TIM1_TRG_COM_TIM11_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 8) || (MODBUS_TIM_NUMB == 12)
void TIM8_BRK_TIM12_IRQHandler(void)
#elif (MODBUS_TIM_NUMB == 8) || (MODBUS_TIM_NUMB == 14)
void TIM8_TRG_COM_TIM14_IRQHandler(void)
#endif
{
Trace_MB_TIM_Enter();
RS_TIM_Handler(&hmodbus1);
Trace_MB_TIM_Exit();
}
//-------------------------HANDLERS FUNCTION-------------------------
//-------------------------------------------------------------------

View File

@@ -0,0 +1,325 @@
/**
**************************************************************************
* @file modbus.h
* @brief Заголовочный файл модуля MODBUS.
* @details Данный файл необходимо подключить в rs_message.h. После подключать
* rs_message.h к основному проекту.
*
* @defgroup MODBUS
* @brief Modbus stuff
*
*************************************************************************/
#ifndef __MODBUS_H_
#define __MODBUS_H_
#include "mylibs_include.h"
#include "modbus_data.h"
//#include "settings.h" // for modbus settings
/**
* @addtogroup MODBUS_SETTINGS
* @ingroup MODBUS
* @brief Some defines for modbus
@{
*/
/////////////////////////////////////////////////////////////////////
//////////////////////////---SETTINGS---/////////////////////////////
// USER SETTINGS FOR MODBUS IN interface_config.h
//////////////////////////---SETTINGS---/////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////---USER MESSAGE DEFINES---//////////////////////
//-------------DEFINES FOR STRUCTURE----------------
/* defines for structure of modbus message */
#define MbAddr_SIZE 1 ///< size of (MbAddr)
#define Func_Code_SIZE 1 ///< size of (Func_Code)
#define Addr_SIZE 2 ///< size of (Addr)
#define Qnt_SIZE 2 ///< size of (Qnt)
#define ByteCnt_SIZE 1 ///< size of (ByteCnt)
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
#define CRC_SIZE 2 ///< size of (MB_CRC) in bytes
/** @brief Size of whole message */
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
/** @brief Size of first part of message that will be received
first receive info part of message, than defines size of rest message*/
#define RX_FIRST_PART_SIZE INFO_SIZE_MAX
/** @brief Size of buffer: max size of whole message */
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
/** @brief Structure for modbus exception codes */
typedef enum //MB_ExceptionTypeDef
{
// reading
NO_ERRORS = 0x00, ///< no errors
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
// ACKNOWLEDGE = 0x05, ///< idk
// SLAVE_DEVICE_BUSY = 0x06, ///< idk
// MEMORY_PARITY_ERROR = 0x08, ///< idk
}MB_ExceptionTypeDef;
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes
/** @brief Structure for modbus func codes */
typedef enum //MB_FunctonTypeDef
{
/* COMMANDS */
// reading
MB_R_COILS = 0x01, ///< Чтение битовых ячеек
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов
#ifndef TESTER_MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения
#else
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения
#endif
// writting
MB_W_COIL = 0x05, ///< Запись битовой ячейки
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
/* ERRORS */
// error reading
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров
// error writting
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров
}MB_FunctonTypeDef;
/** @brief Structure for modbus messsage */
typedef struct // RS_MsgTypeDef
{
uint8_t MbAddr; ///< Modbus Slave Address
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
uint16_t Addr; ///< Modbus Address of data
uint16_t Qnt; ///< Quantity of modbus data
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
uint16_t DATA[DATA_SIZE]; ///< Modbus Data
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
uint16_t MB_CRC; ///< Modbus CRC
}RS_MsgTypeDef;
//--------------------------------------------------
extern RS_MsgTypeDef MODBUS_MSG;
/////////////////////---MODBUS USER SETTINGS---//////////////////////
/** MODBUS_SETTINGS
* @}
*/
/////////////////////////////////////////////////////////////////////
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
/**
* @addtogroup MODBUS_MESSAGE_DEFINES
* @ingroup MODBUS
* @brief Some defines for modbus
@{
*/
/** @brief Structure for coils operation */
typedef enum
{
SET_COIL,
RESET_COIL,
TOOGLE_COIL,
}MB_CoilsOpTypeDef;
//--------------------------------------------------
/**
* @brief Macros to set pointer to 16-bit array
* @param _arr_ - массив регистров (16-бит).
*/
#define MB_Set_Arr16_Ptr(_arr_) ((uint16_t*)(&(_arr_)))
/**
* @brief Macros to set pointer to register
* @param _parr_ - массив регистров.
* @param _addr_ - Номер регистра (его индекс) от начала массива _arr_.
*/
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
/**
* @brief Macros to set pointer to a certain register that contains certain coil
* @param _parr_ - массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Mask
@verbatim Пояснение выражений
(_coil_/16) - get index (address shift) of register that contain certain coil
Visual explanation: 30th coil in coils registers array
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endverbatim
*/
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
/**
* @brief Macros to set mask to a certain bit in coils register
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
@verbatim Пояснение выражений
(16*(_coil_/16) - how many coils we need to skip. e.g. (16*30/16) - skip 16 coils from first register
_coil_-(16*(_coil_/16)) - shift to certain coil in certain register
e.g. Coil(30) gets in register[1] (30/16 = 1) coil №14 (30 - (16*30/16) = 30 - 16 = 14)
Visual explanation: 30th coil in coils registers array
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endverbatim
*/
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
/**
* @brief Read Coil at its local address.
* @param _parr_ - массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
* @return uint16_t - Возвращает запрошенный коил на 0м бите.
*
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/
#define MB_Read_Coil_Local(_parr_, _coil_) (( *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) & MB_Set_Coil_Mask(_coil_) ) >> (_coil_))
/**
* @brief Set Coil at its local address.
* @param _parr_ - указатель на массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
*
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/
#define MB_Set_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) |= MB_Set_Coil_Mask(_coil_)
/**
* @brief Reset Coil at its local address.
* @param _parr_ - указатель на массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
*
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/
#define MB_Reset_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) &= ~(MB_Set_Coil_Mask(_coil_))
/**
* @brief Set Coil at its local address.
* @param _parr_ - указатель на массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
*
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/
#define MB_Toogle_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ^= MB_Set_Coil_Mask(_coil_)
//--------------------------------------------------
//------------------OTHER DEFINES-------------------
#define RegisterType_Holding 0
#define RegisterType_Input 1
#define RegisterType_Discrete 2
// create hadnles and settings for uart, tim, rs with _modbus_ name
#define CONCAT(a,b) a##b
#define Create_MODBUS_Handles(_modbus_) \
UART_SettingsTypeDef CONCAT(_modbus_, _suart); \
UART_HandleTypeDef CONCAT(_modbus_, _huart); \
TIM_SettingsTypeDef CONCAT(_modbus_, _stim); \
TIM_HandleTypeDef CONCAT(_modbus_, _htim); \
RS_HandleTypeDef CONCAT(h, _modbus_)
//--------------------------------------------------
/** GENERAL_MODBUS_STUFF
* @}
*/
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_FUNCTIONS
* @ingroup MODBUS
* @brief Function for controling modbus communication
*/
//----------------FUNCTIONS FOR USER----------------
/**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
* @ingroup MODBUS_FUNCTIONS
* @brief Function for user use
@{
*/
/* First set up of MODBUS */
void MODBUS_FirstInit(void);
/* Set or Reset Coil at its global address */
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal);
/* Read Coil at its global address */
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
/** MODBUS_DATA_ACCESS_FUNCTIONS
* @}
*/
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
* @ingroup MODBUS_FUNCTIONS
* @brief Function process commands
@{
*/
/* Check is address valid for certain array */
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB);
/* Define Address Origin for Input/Holding Registers */
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType);
/* Define Address Origin for coils */
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag);
/* Proccess command Read Coils (01 - 0x01) */
uint8_t MB_Read_Coils(RS_MsgTypeDef *modbus_msg);
/* Proccess command Read Holding Registers (03 - 0x03) */
uint8_t MB_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
/* Proccess command Read Input Registers (04 - 0x04) */
uint8_t MB_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
/* Proccess command Write Single Coils (05 - 0x05) */
uint8_t MB_Write_Single_Coil(RS_MsgTypeDef *modbus_msg);
/* Proccess command Write Multiple Coils (15 - 0x0F) */
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
/* Proccess command Write Multiple Register (16 - 0x10) */
uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg);
/** MODBUS_DATA_ACCESS_FUNCTIONS
* @}
*/
/////////////////////////---FUNCTIONS---/////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////---CALC DEFINES---//////////////////////////
// TRACES DEFINES
#ifndef Trace_MB_UART_Enter
#define Trace_MB_UART_Enter()
#endif //Trace_MB_UART_Enter
#ifndef Trace_MB_UART_Exit
#define Trace_MB_UART_Exit()
#endif //Trace_MB_UART_Exit
#ifndef Trace_MB_TIM_Enter
#define Trace_MB_TIM_Enter()
#endif //Trace_MB_TIM_Enter
#ifndef Trace_MB_TIM_Exit
#define Trace_MB_TIM_Exit()
#endif //Trace_MB_TIM_Exit
#endif //__MODBUS_H_

View File

@@ -0,0 +1,163 @@
/**
**************************************************************************
* @file modbus_data.h
* @brief Заголовочный файл с описанием даты MODBUS.
* @details Данный файл необходимо подключается в rs_message.h. После rs_message.h
* подключается к основному проекту.
*
* @defgroup MODBUS_DATA
* @ingroup MODBUS
* @brief Modbus data description
*
*************************************************************************/
#ifndef _MODBUS_DATA_H_
#define _MODBUS_DATA_H_
#include "stdint.h"
//--------------DEFINES FOR REGISTERS---------------
// DEFINES FOR ARRAYS
/**
* @addtogroup MODBUS_DATA_RERISTERS_DEFINES
* @ingroup MODBUS_DATA
* @brief Defines for registers
Структура дефайна адресов
@verbatim
Для массивов регистров:
R_<NAME_ARRAY>_ADDR - модбас адресс первого регистра в массиве
R_<NAME_ARRAY>_QNT - количество регистров в массиве
@endverbatim
* @{
*/
/**
* @brief Регистры хранения
*/
typedef struct //MB_DataInRegsTypeDef
{
unsigned DUMMY;
}MB_DataInRegsTypeDef;
/**
* @brief Входные регистры
*/
typedef struct //MB_DataInRegsTypeDef
{
unsigned DUMMY;
}MB_DataHoldRegsTypeDef;
// DEFINES FOR INPUT REGISTERS ARRAYS
#define R_TE_VOLTAGE_ADDR 0
#define R_TE_VOLTAGE_QNT 85
#define R_STATUS_REG_ADDR 85
#define R_STATUS_REG_QNT 1
// DEFINES FOR HOLDING REGISTERS ARRAYS
#define R_SETPOINTS_ADDR 0
#define R_SETPOINTS_QNT 170
#define R_SETTINGS_ADDR 170
#define R_SETTINGS_QNT 5
// DEFINES FOR REGISTERS LOCAL ADDRESSES
//#define R_SET_ERROR(_te_num_) 0
/** MODBUS_DATA_RERISTERS_DEFINES
* @}
*/
//----------------DEFINES FOR COILS-----------------
/**
* @addtogroup MODBUS_DATA_COILS_DEFINES
* @ingroup MODBUS_DATA
* @brief Defines for coils
@verbatim
Структура дефайна
Для массивов коилов:
C_<NAME_ARRAY>_ADDR - модбас адресс первого коила в массиве
C_<NAME_ARRAY>_QNT - количество коилов в массиве (минимум 16)
@endverbatim
* @{
*/
/**
* @brief Коилы
*/
typedef struct //MB_DataCoilsTypeDef
{
unsigned DUMMY;
}MB_DataCoilsTypeDef;
// DEFINES FOR COIL ARRAYS
#define C_TE_EXCLUDE_ADDR 0
#define C_TE_EXCLUDE_QNT 85
/** MODBUS_DATA_COILS_DEFINES
* @}
*/
//-----------MODBUS DEVICE DATA SETTING-------------
// MODBUS DATA STRUCTTURE
/**
* @brief Структура со всеми регистрами и коилами модбас
* @ingroup MODBUS_DATA
*/
typedef struct // tester modbus data
{
MB_DataInRegsTypeDef InRegs; ///< Modbus input registers @ref MB_DataInRegsTypeDef
MB_DataCoilsTypeDef Coils; ///< Modbus coils @ref MB_DataCoilsTypeDef
MB_DataHoldRegsTypeDef HoldRegs; ///< Modbus holding registers @ref MB_DataHoldRegsTypeDef
}MB_DataStructureTypeDef;
extern MB_DataStructureTypeDef MB_DATA;
#endif //_MODBUS_DATA_H_
/////////////////////////////////////////////////////////////
///////////////////////TEMP/OUTDATE/OTHER////////////////////
//typedef enum //MB_TESTERCommandsTypeDef
//{
// StandartMode = 0x00, ///< Стандартная работа
// Opros_TE_Disable = 0x01, ///< Запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются)
//}MB_TESTERCommandsTypeDef;
///**
// * @brief Состояние МЗКТЭ
// */
//typedef enum //MB_TESTERErrStatusTypeDef
//{
// TESTER_OK = 0x0, ///< МЗКТЭ функционирует нормально. Идет опрос ТЭ.
// NonCritical_Err = 0x1, ///< Неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции (некоторые программные ошибки из @ref MB_TESTERTrackerTypeDef).
// Critical_Err = 0x2, ///< Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным (ошибки 1-3 и некоторые программные ошибки из @ref MB_TESTERTrackerTypeDef)
//
//}MB_TESTERErrStatusTypeDef;
//typedef enum
//{
// TE_No_Err = 0x0, ///< Напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария»
// TE_Err = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария»
//}MB_TEErrActiveTypeDef;
//typedef enum
//{
// TE_No_Warn = 0x0, ///< Напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение»
// TE_Warn = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение»
//}MB_TEWarnActiveTypeDef;
//typedef enum
//{
// OprosTE_Enable = 0x0, ///< Опрос ТЭ разрешен
// OprosTE_Disable = 0x1, ///< Опрос ТЭ запрещен (см. регистр хранения 170)
//}MB_OprosTETypeDef;

View File

@@ -0,0 +1,580 @@
/**
**************************************************************************
* @file rs_message.c
* @brief Модуль для реализации протоколов по RS/UART.
**************************************************************************
@verbatim
//-------------------Функции-------------------//
Functions: users
- RS_Parse_Message/RS_Collect_Message Заполнение структуры сообщения и буфера
- RS_Response Ответ на сообщение
- RS_Define_Size_of_RX_Message Определение размера принимаемых данных
Functions: general
- RS_Receive_IT Ожидание комманды и ответ на неё
- RS_Transmit_IT Отправление комманды и ожидание ответа
- RS_Init Инициализация переферии и структуры для RS
- RS_ReInit_UART Реинициализация UART для RS
- RS_Abort Отмена приема/передачи по ЮАРТ
- RS_Init Инициализация периферии и modbus handler
Functions: callback/handler
- RS_Handle_Receive_Start Функция для запуска приема или остановки RS
- RS_Handle_Transmit_Start Функция для запуска передачи или остановки RS
- RS_UART_RxCpltCallback Коллбек при окончании приема или передачи
RS_UART_TxCpltCallback
- RS_UART_Handler Обработчик прерывания для UART
- RS_TIM_Handler Обработчик прерывания для TIM
Functions: uart initialize (это было в отдельных файлах, мб надо обратно разнести)
- UART_Base_Init Инициализация UART для RS
- RS_UART_GPIO_Init Инициализация GPIO для RS
- UART_DMA_Init Инициализация DMA для RS
- UART_MspInit Аналог HAL_MspInit для RS
- UART_MspDeInit Аналог HAL_MspDeInit для RS
@endverbatim
*************************************************************************/
#include "rs_message.h"
uint8_t RS_Buffer[MSG_SIZE_MAX]; // uart buffer
#ifndef INCLUDE_GENERAL_PERIPH_LIBS
extern void RS_UART_Init(void);
extern void RS_UART_DeInit(UART_HandleTypeDef *huart);
extern void RS_TIM_Init(void);
extern void RS_TIM_DeInit(TIM_HandleTypeDef *htim);
#endif
//-------------------------------------------------------------------
//-------------------------GENERAL FUNCTIONS-------------------------
/**
* @brief Start receive IT.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @return RS_RES - статус о состоянии RS после инициализации приема.
*/
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
{
RS_StatusTypeDef RS_RES = 0;
HAL_StatusTypeDef uart_res = 0;
//-------------CHECK RS LINE----------------
// check that receive isnt busy
if( RS_Is_RX_Busy(hRS) ) // if tx busy - return busy status
return RS_BUSY;
//-----------INITIALIZE RECEIVE-------------
// if all OK: start receiving
RS_EnableReceive();
RS_Set_Busy(hRS); // set RS busy
RS_Set_RX_Flags(hRS); // initialize flags for receive
hRS->pMessagePtr = RS_msg; // set pointer to message structire for filling it from UARTHandler fucntions
// start receiving
uart_res = HAL_UART_Receive_IT(hRS->huart, hRS->pBufferPtr, RX_FIRST_PART_SIZE); // receive until ByteCnt+1 byte,
// then in Callback restart receive for rest bytes
// if receive isnt started - abort RS
if(uart_res != HAL_OK)
{
RS_RES = RS_Abort(hRS, ABORT_RS);
printf_rs_err("\n%d: Error RS: Failed to start RS receiving...", uwTick);
TrackerCnt_Err(hRS->rs_err);
}
else
{
RS_RES = RS_OK;
printf_rs("\n%d: RS: Start Receiving...", uwTick);
TrackerCnt_Ok(hRS->rs_err);
}
hRS->RS_STATUS = RS_RES;
return RS_RES; // returns result of receive init
}
/**
* @brief Start transmit IT.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @return RS_RES - статус о состоянии RS после инициализации передачи.
*/
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
{
RS_StatusTypeDef RS_RES = 0;
HAL_StatusTypeDef uart_res = 0;
//-------------CHECK RS LINE----------------
// check that transmit isnt busy
if( RS_Is_TX_Busy(hRS) ) // if tx busy - return busy status
return RS_BUSY;
// check receive line
//------------COLLECT MESSAGE---------------
RS_RES = RS_Collect_Message(hRS, RS_msg, hRS->pBufferPtr);
if (RS_RES != RS_OK) // if message isnt collect - stop RS and return error in RS_RES
{// need collect message status, so doesnt write abort to RS_RES
RS_Abort(hRS, ABORT_RS);
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr); // restart receive
}
else // if collect successful
{
//----------INITIALIZE TRANSMIT-------------
RS_EnableTransmit();
// for(int i = 0; i < hRS->sRS_Timeout; i++);
RS_Set_Busy(hRS); // set RS busy
RS_Set_TX_Flags(hRS); // initialize flags for transmit IT
hRS->pMessagePtr = RS_msg; // set pointer for filling given structure from UARTHandler fucntion
// if all OK: start transmitting
uart_res = HAL_UART_Transmit_IT(hRS->huart, hRS->pBufferPtr, hRS->RS_Message_Size);
// if transmit isnt started - abort RS
if(uart_res != HAL_OK)
{
RS_RES = RS_Abort(hRS, ABORT_RS);
printf_rs_err("\n%d: Error RS: Failed to start RS transmitting...", uwTick);
TrackerCnt_Err(hRS->rs_err);
}
else
{
RS_RES = RS_OK;
printf_rs("\n%d: RS: Start Transmitting...", uwTick);
TrackerCnt_Ok(hRS->rs_err);
}
}
hRS->RS_STATUS = RS_RES;
return RS_RES; // returns result of transmit init
}
/**
* @brief Initialize UART and handle RS stucture.
* @param hRS - указатель на хендлер RS.
* @param suart - указатель на структуру с настройками UART.
* @param stim - указатель на структуру с настройками таймера.
* @param pRS_BufferPtr - указатель на буффер для приема-передачи по UART. Если он NULL, то поставиться библиотечный буфер.
* @return RS_RES - статус о состоянии RS после инициализации.
* @note Инициализация перефирии и структуры для приема-передачи по RS.
*/
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_SettingsTypeDef *suart, TIM_SettingsTypeDef *stim, uint8_t *pRS_BufferPtr)
#else
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr)
#endif
{
// check that hRS is defined
if (hRS == NULL)
return RS_ERR;
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
// check that huart is defined
if ((suart->huart.Instance == NULL) || (suart->huart.Init.BaudRate == NULL))
return RS_ERR;
#else
// check that huart is defined
if (huart == NULL)
return RS_ERR;
#endif
// init uart
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
UART_Base_Init(suart);
hRS->huart = &suart->huart;
#else
RS_UART_Init();
hRS->huart = huart;
#endif
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
// check that timeout in interrupt needed
if (hRS->sRS_Timeout)
{
if (stim->htim.Instance == NULL) // check is timer defined
return RS_ERR;
// calc frequency corresponding to timeout and tims 1ms tickbase
stim->sTickBaseUS = TIM_TickBase_1MS;
stim->htim.Init.Period = hRS->sRS_Timeout;
TIM_Base_Init(stim);
hRS->htim = &stim->htim;
}
#else
RS_TIM_Init();
hRS->htim = htim;
#endif
if (hRS->sRS_RX_Size_Mode == NULL)
return RS_ERR;
// check that buffer is defined
if (hRS->pBufferPtr == NULL)
{
hRS->pBufferPtr = RS_Buffer; // if no - set default
}
else
hRS->pBufferPtr = pRS_BufferPtr; // if yes - set by user
return RS_OK;
}
/**
* @brief ReInitialize UART and RS receive.
* @param hRS - указатель на хендлер RS.
* @param suart - указатель на структуру с настройками UART.
* @return RS_RES - статус о состоянии RS после инициализации.
* @note Реинициализация UART и приема по RS.
*/
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_SettingsTypeDef *suart)
#else
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart)
#endif
{
HAL_StatusTypeDef RS_RES;
hRS->f.ReInit_UART = 0;
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
// check is settings are valid
if(Check_UART_Init_Struct(suart) != HAL_OK)
return HAL_ERROR;
RS_Abort(hRS, ABORT_RS);
UART_MspDeInit(&suart->huart);
RS_RES = UART_Base_Init(suart);
RS_RES = RS_UART_Init()
#else
// // check is settings are valid
// if(Check_UART_Init_Struct(suart) != HAL_OK)
// return HAL_ERROR;
RS_Abort(hRS, ABORT_RS);
RS_UART_DeInit(huart);
RS_UART_Init();
#endif
RS_Receive_IT(hRS, hRS->pMessagePtr);
return RS_RES;
}
/**
* @brief Abort RS/UART.
* @param hRS - указатель на хендлер RS.
* @param AbortMode - выбор, что надо отменить.
- ABORT_TX: Отмена передачи по ЮАРТ, с очищением флагов TX,
- ABORT_RX: Отмена приема по ЮАРТ, с очищением флагов RX,
- ABORT_RX_TX: Отмена приема и передачи по ЮАРТ,
- ABORT_RS: Отмена приема-передачи RS, с очищением всей структуры.
* @return RS_RES - статус о состоянии RS после аборта.
* @note Отмена работы UART в целом или отмена приема/передачи RS.
Также очищается хендл hRS.
*/
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode)
{
HAL_StatusTypeDef uart_res = 0;
hRS->htim->Instance->CNT = 0;
__HAL_TIM_CLEAR_IT(hRS->htim, TIM_IT_UPDATE);
if(hRS->sRS_Timeout) // if timeout setted
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
if((AbortMode&ABORT_RS) == 0x00)
{
if((AbortMode&ABORT_RX) == ABORT_RX)
{
uart_res = HAL_UART_AbortReceive(hRS->huart); // abort receive
RS_Reset_RX_Flags(hRS);
}
if((AbortMode&ABORT_TX) == ABORT_TX)
{
uart_res = HAL_UART_AbortTransmit(hRS->huart); // abort transmit
RS_Reset_TX_Flags(hRS);
}
}
else
{
uart_res = HAL_UART_Abort(hRS->huart);
RS_Clear_All(hRS);
}
hRS->RS_STATUS = RS_ABORTED;
return RS_ABORTED;
}
//-------------------------GENERAL FUNCTIONS-------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
/**
* @brief Handle for starting receive.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @return RS_RES - статус о состоянии RS после инициализации приема или окончания общения.
* @note Определяет начинать прием команды/ответа или нет.
*/
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
{
RS_StatusTypeDef RS_RES = 0;
switch(hRS->sRS_Mode)
{
case SLAVE_ALWAYS_WAIT: // in slave mode with permanent waiting
RS_RES = RS_Receive_IT(hRS, RS_msg); break; // start receiving again
case SLAVE_TIMEOUT_WAIT: // in slave mode with timeout waiting (start receiving cmd by request)
RS_Set_Free(hRS); RS_RES = RS_OK; break; // end RS communication (set RS unbusy)
}
if(RS_RES != RS_OK)
{
TrackerCnt_Err(hRS->rs_err);
}
return RS_RES;
}
/**
* @brief Handle for starting transmit.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @return RS_RES - статус о состоянии RS после инициализации передачи.
* @note Определяет отвечать ли на команду или нет.
*/
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
{
RS_StatusTypeDef RS_RES = 0;
switch(hRS->sRS_Mode)
{
case SLAVE_ALWAYS_WAIT: // in slave mode always response
case SLAVE_TIMEOUT_WAIT: // transmit response
RS_RES = RS_Transmit_IT(hRS, RS_msg); break;
}
if(RS_RES != RS_OK)
{
TrackerCnt_Err(hRS->rs_err);
}
return RS_RES;
}
/**
* @brief UART RX Callback: define behaviour after receiving parts of message.
* @param hRS - указатель на хендлер RS.
* @return RS_RES - статус о состоянии RS после обработки приема.
* @note Контролирует прием сообщения: определяет размер принимаемой посылки и обрабатывает его.
*/
RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS)
{
RS_StatusTypeDef RS_RES = 0;
HAL_StatusTypeDef uart_res = 0;
// if we had received bytes before ByteCnt
if((hRS->sRS_RX_Size_Mode == RS_RX_Size_NotConst) && (hRS->f.RX_Half == 0)) // if data size isnt constant and its first half, and
{ // First receive part of message, then define size of rest of message, and start receive it
hRS->f.RX_Half = 1;
//---------------FIND DATA SIZE-----------------
uint32_t NuRS_of_Rest_Bytes = 0;
RS_RES = RS_Define_Size_of_RX_Message(hRS, &NuRS_of_Rest_Bytes);
// if there is no bytes to receive OR we need to skip this message - restart receive
if ((NuRS_of_Rest_Bytes == 0) || (RS_RES == RS_SKIP))
{
TrackerCnt_Err(hRS->rs_err);
RS_Abort(hRS, ABORT_RX);
RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
return RS_RES;
}
//-------------START UART RECEIVE---------------
uart_res = HAL_UART_Receive_IT(hRS->huart, (hRS->pBufferPtr + RX_FIRST_PART_SIZE), NuRS_of_Rest_Bytes);
if(uart_res != HAL_OK)
{// need uart status, so doesnt write abort to RS_RES
TrackerCnt_Err(hRS->rs_err);
RS_RES = RS_Abort(hRS, ABORT_RS);
}
else
RS_RES = RS_OK;
}
else // if we had received whole message
{
hRS->f.RX_Half = 0;
//---------PROCESS DATA & ENDING RECEIVING--------
RS_Set_RX_End(hRS);
if(hRS->sRS_Timeout) // if timeout setted
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
// parse received data
RS_RES = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); // parse message
// RESPONSE
RS_RES = RS_Response(hRS, hRS->pMessagePtr);
}
return RS_RES;
}
/**
* @brief UART TX Callback: define behaviour after transmiting message.
* @param hRS - указатель на хендлер RS.
* @return RS_RES - статус о состоянии RS после обработки приема.
* @note Определяет поведение RS после передачи сообщения.
*/
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS)
{
RS_StatusTypeDef RS_RES = RS_OK;
HAL_StatusTypeDef uart_res = 0;
//--------------ENDING TRANSMITTING-------------
RS_Set_TX_End(hRS);
RS_EnableReceive();
// for(int i = 0; i < hRS->sRS_Timeout; i++);
//-----------START RECEIVING or END RS----------
RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
return RS_RES;
}
/**
* @brief Handler for UART.
* @param hRS - указатель на хендлер RS.
* @note Обрабатывает ошибки если есть и вызывает RS Коллбеки.
* Добавить вызов этой функции в UARTx_IRQHandler().
*/
void RS_UART_Handler(RS_HandleTypeDef *hRS)
{
HAL_UART_IRQHandler(hRS->huart);
//-------------CALL RS CALLBACKS------------
/* IF NO ERROR OCCURS */
if(hRS->huart->ErrorCode == 0)
{
hRS->htim->Instance->CNT = 0; // reset cnt;
/* Start timeout */
if(hRS->sRS_Timeout) // if timeout setted
if((hRS->huart->RxXferCount+1 == hRS->huart->RxXferSize) && RS_Is_RX_Busy(hRS)) // if first byte is received and receive is active
{
HAL_TIM_Base_Start_IT(hRS->htim);
RS_Set_RX_Active_Flags(hRS);
}
/* RX Callback */
if (( hRS->huart->RxXferCount == 0U) && RS_Is_RX_Busy(hRS) && // if all bytes are received and receive is active
hRS->huart->RxState != HAL_UART_STATE_BUSY_RX) // also check that receive "REALLY" isnt busy
RS_UART_RxCpltCallback(hRS);
/* TX Callback */
if (( hRS->huart->TxXferCount == 0U) && RS_Is_TX_Busy(hRS) && // if all bytes are transmited and transmit is active
hRS->huart->gState != HAL_UART_STATE_BUSY_TX) // also check that receive "REALLY" isnt busy
RS_UART_TxCpltCallback(hRS);
}
//----------------ERRORS HANDLER----------------
else
{
TrackerCnt_Err(hRS->rs_err);
/* de-init uart transfer */
RS_Abort(hRS, ABORT_RS);
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
// later, maybe, will be added specific handlers for err
}
}
/**
* @brief Handler for TIM.
* @param hRS - указатель на хендлер RS.
* @note Попадание сюда = таймаут и перезапуск RS приема
* Добавить вызов этой функции в TIMx_IRQHandler().
*/
void RS_TIM_Handler(RS_HandleTypeDef *hRS)
{
HAL_TIM_IRQHandler(hRS->htim);
HAL_TIM_Base_Stop_IT(hRS->htim);
RS_Abort(hRS, ABORT_RS);
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
}
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//--------------WEAK PROTOTYPES FOR PROCESSING MESSAGE---------------
/**
* @brief Respond accord to received message.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @return RS_RES - статус о результате ответа на комманду.
* @note Обработка принятой комманды и ответ на неё.
*/
__weak RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
{
/* Redefine function for user purposes */
return RS_ERR;
}
/**
* @brief Collect message in buffer to transmit it.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @param msg_uart_buff - указатель на буффер UART.
* @return RS_RES - статус о результате заполнения буфера.
* @note Заполнение буффера UART из структуры сообщения.
*/
__weak RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
{
/* Redefine function for user purposes */
return RS_ERR;
}
/**
* @brief Parse message from buffer to process it.
* @param hRS - указатель на хендлер RS.
* @param RS_msg - указатель на структуру сообщения.
* @param msg_uart_buff - указатель на буффер UART.
* @return RS_RES - статус о результате заполнения структуры.
* @note Заполнение структуры сообщения из буффера UART.
*/
__weak RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
{
/* Redefine function for user purposes */
return RS_ERR;
}
/**
* @brief Define size of RX Message that need to be received.
* @param hRS - указатель на хендлер RS.
* @param rx_data_size - указатель на переменную для записи кол-ва байт для принятия.
* @return RS_RES - статус о корректности рассчета кол-ва байт для принятия.
* @note Определение сколько байтов надо принять по протоколу.
*/
__weak RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size)
{
/* Redefine function for user purposes */
return RS_ERR;
}
//--------------WEAK PROTOTYPES FOR PROCESSING MESSAGE---------------
//-------------------------------------------------------------------

View File

@@ -0,0 +1,265 @@
/**
**************************************************************************
* @file rs_message.h
* @brief Заголовочный файл для модуля реализации протоколов по RS/UART.
**************************************************************************
* @defgroup RS_TOOLS
* @brief Всякое для работы по UART/RS
**************************************************************************
@details
**************************************************************************
Для настройки RS/UART под нужный протокол, необходимо:
- Определить структуру сообщения RS_MsgTypeDef и
дефайны RX_FIRST_PART_SIZE и MSG_SIZE_MAX.
- Подключить этот файл в раздел rs_message.h.
- Определить функции для обработки сообщения: RS_Parse_Message(),
RS_Collect_Message(), RS_Response(), RS_Define_Size_of_RX_Message()
- Добавить UART/TIM Handler в Хендлер используемых UART/TIM.
Так же данный модуль использует счетчики
**************************************************************************
@verbatim
Визуальное описание. Форматирование сохраняется как в коде.
@endverbatim
*************************************************************************/
#ifndef __RS_LIB_H_
#define __RS_LIB_H_
#include "modbus.h"
#include "mylibs_include.h"
#include "crc_algs.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
/* Check that all defines required by RS are defined */
#ifndef MSG_SIZE_MAX
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
#endif
#ifndef RX_FIRST_PART_SIZE
#error Define RX_FIRST_PART_SIZE (Size of first part of message). This is necessary to receive the first part of the message, from which determine the size of the remaining part of the message.
#endif
/* Clear message-uart buffer */
#define RS_Clear_Buff(_buff_) for(int i=0; i<MSG_SIZE_MAX;i++) _buff_[i] = NULL
/* Set/Reset flags */
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
#define RS_Set_Busy(_hRS_) _hRS_->f.RS_Busy = 1
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
#define RS_Set_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 1
#define RS_Set_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 1; _hRS_->f.TX_Done = 0
#define RS_Reset_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 0
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
#define RS_Reset_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 0; _hRS_->f.TX_Done = 0
#define RS_Set_RX_End_Flag(_hRS_) _hRS_->f.RX_Done = 1;
#define RS_Set_TX_End_Flag(_hRS_) _hRS_->f.TX_Done = 1
#define RS_Set_RX_End(_hRS_) RS_Reset_RX_Flags(_hRS_); RS_Set_RX_End_Flag(_hRS_)
#define RS_Set_TX_End(_hRS_) RS_Reset_TX_Flags(_hRS_); RS_Set_TX_End_Flag(_hRS_)
/* Clear all RS stuff */
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
//#define MB_Is_RX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_RX)
//#define MB_Is_TX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_TX)
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy == 1)
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
#ifndef RS_EnableReceive
#define RS_EnableReceive()
#endif
#ifndef RS_EnableTransmit
#define RS_EnableTransmit()
#endif
////////////////////////////---DEFINES---////////////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////---STRUCTURES & ENUMS---//////////////////////
//------------------ENUMERATIONS--------------------
/** @brief Enums for respond CMD about RS status */
typedef enum // RS_StatusTypeDef
{
/* IN-CODE STATUS (start from 0x01, and goes up)*/
/*0x01*/ RS_OK = 0x01,
/*0x02*/ RS_ERR,
/*0x03*/ RS_ABORTED,
/*0x04*/ RS_BUSY,
/*0x05*/ RS_SKIP,
/*0x06*/ RS_COLLECT_MSG_ERR,
/*0x07*/ RS_PARSE_MSG_ERR,
// reserved values
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
}RS_StatusTypeDef;
/** @brief Enums for RS Modes */
typedef enum // RS_ModeTypeDef
{
SLAVE_ALWAYS_WAIT = 0x01, ///< Slave mode with infinity waiting
SLAVE_TIMEOUT_WAIT = 0x02, ///< Slave mode with waiting with timeout
// MASTER = 0x03, ///< Master mode
}RS_ModeTypeDef;
/** @brief Enums for RS UART Modes */
typedef enum // RS_ITModeTypeDef
{
BLCK_MODE = 0x00, ///< Blocking mode
IT_MODE = 0x01, ///< Interrupt mode
}RS_ITModeTypeDef;
/** @brief Enums for Abort modes */
typedef enum // RS_AbortTypeDef
{
ABORT_TX = 0x01, ///< Abort transmit
ABORT_RX = 0x02, ///< Abort receive
ABORT_RX_TX = 0x03, ///< Abort receive and transmit
ABORT_RS = 0x04, ///< Abort uart and reset RS structure
}RS_AbortTypeDef;
/** @brief Enums for RX Size modes */
typedef enum // RS_RXSizeTypeDef
{
RS_RX_Size_Const = 0x01, ///< size of receiving message is constant
RS_RX_Size_NotConst = 0x02, ///< size of receiving message isnt constant
}RS_RXSizeTypeDef;
//-----------STRUCTURE FOR HANDLE RS------------
/** @brief Struct for flags RS */
typedef struct
{
unsigned RX_Half:1; ///< flag: 0 - receiving msg before ByteCnt, 0 - receiving msg after ByteCnt
unsigned RS_Busy:1; ///< flag: 1 - RS is busy, 0 - RS isnt busy
unsigned RX_Ongoing:1; ///< flag: 1 - receiving data right now, 0 - waiting for receiving data
unsigned RX_Busy:1; ///< flag: 1 - receiving is active, 0 - receiving isnt active
unsigned TX_Busy:1; ///< flag: 1 - transmiting is active, 0 - transmiting isnt active
unsigned RX_Done:1; ///< flag: 1 - receiving is done, 0 - receiving isnt done
unsigned TX_Done:1; ///< flag: 1 - transmiting is done, 0 - transmiting isnt done
// setted by user
unsigned MessageHandled:1; ///< flag: 1 - RS command is handled, 0 - RS command isnt handled yet
unsigned EchoResponse:1; ///< flag: 1 - response with received msg, 0 - response with own msg
unsigned DeferredResponse:1; ///< flag: 1 - response not in interrupt, 0 - response in interrupt
unsigned ReInit_UART:1; ///< flag: 1 - need to reinitialize uart, 0 - nothing
}RS_FlagsTypeDef;
/**
* @brief Handle for RS communication.
* @note Prefixes: h - handle, s - settings, f - flag
*/
typedef struct // RS_HandleTypeDef
{
/* MESSAGE */
uint8_t ID; ///< ID of RS "channel"
RS_MsgTypeDef *pMessagePtr; ///< pointer to message struct
uint8_t *pBufferPtr; ///< pointer to message buffer
uint32_t RS_Message_Size; ///< size of whole message, not only data
/* HANDLERS and SETTINGS */
UART_HandleTypeDef *huart; ///< handler for used uart
TIM_HandleTypeDef *htim; ///< handler for used tim
RS_ModeTypeDef sRS_Mode; ///< setting: slave or master @ref RS_ModeTypeDef
RS_ITModeTypeDef sRS_IT_Mode; ///< setting: 1 - IT mode, 0 - Blocking mode
uint16_t sRS_Timeout; ///< setting: timeout in ms
RS_RXSizeTypeDef sRS_RX_Size_Mode; ///< setting: 1 - not const, 0 - const
/* FLAGS */
RS_FlagsTypeDef f; ///< These flags for controling receive/transmit
/* RS STATUS */
RS_StatusTypeDef RS_STATUS; ///< RS status
RS_TrackerTypeDef rs_err;
}RS_HandleTypeDef;
extern RS_HandleTypeDef hmodbus1;
///////////////////////---STRUCTURES & ENUMS---//////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////////---FUNCTIONS---///////////////////////////
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
/*--------------------Defined by users purposes--------------------*/
/* Respond accord to received message */
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Collect message in buffer to transmit it */
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
/* Parse message from buffer to process it */
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
/* Define size of RX Message that need to be received */
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size);
//-------------------------GENERAL FUNCTIONS-------------------------
/*-----------------Should be called from main code-----------------*/
/* Start receive IT */
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Start transmit IT */
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Initialize UART and handle RS stucture */
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_SettingsTypeDef *suart, TIM_SettingsTypeDef *stim, uint8_t *pRS_BufferPtr);
#else
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
#endif
/* ReInitialize UART and RS receive */
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_SettingsTypeDef *suart);
#else
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *suart);
#endif
/* Abort RS/UART */
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
//-------------------------GENERAL FUNCTIONS-------------------------
//-------------------------------------------------------------------
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
/* Handle for starting receive */
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Handle for starting transmit */
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* UART RX Callback: define behaviour after receiving parts of message */
RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS);
/* UART TX Callback: define behaviour after transmiting message */
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS);
/* Handler for UART */
void RS_UART_Handler(RS_HandleTypeDef *hRS);
/* Handler for TIM */
void RS_TIM_Handler(RS_HandleTypeDef *hRS);
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
///////////////////////////---FUNCTIONS---///////////////////////////
#ifndef printf_rs_err
#define printf_rs_err(...)
#endif
#ifndef printf_rs
#define printf_rs(...)
#endif
#endif // __RS_LIB_H_

View File

@@ -0,0 +1,249 @@
/**
**************************************************************************
* @file mylibs_defs.h
* @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral.
**************************************************************************
* @defgroup BIT_ACCESS_DEFINES Bit access defines
* @ingroup MYLIBS_DEFINES
* @brief Всякое для доступа к битам в unsigned
*************************************************************************/
#ifndef __BIT_ACCESS_H_
#define __BIT_ACCESS_H_
#include "mylibs_defs.h"
/**
* @addtogroup BIT_ACCESS_TYPEDEF Byte access typedefs
* @ingroup BIT_ACCESS_DEFINES
* @brief Дефайны юнионов для обращения к битам.
@{
*/
typedef union
{
uint8_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned reserved:4;
}bit;
}uint4_BitTypeDef;
typedef union
{
uint8_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned reserved:3;
}bit;
}uint5_BitTypeDef;
typedef union
{
uint8_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned reserved:2;
}bit;
}uint6_BitTypeDef;
typedef union
{
uint8_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned reserved:1;
}bit;
}uint7_BitTypeDef;
typedef union
{
uint8_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
}bit;
}uint8_BitTypeDef;
typedef union
{
uint16_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
unsigned bit8:1;
unsigned bit9:1;
unsigned bit10:1;
unsigned bit11:1;
unsigned bit12:1;
unsigned bit13:1;
unsigned bit14:1;
unsigned bit15:1;
}bit;
}uint16_BitTypeDef;
typedef union
{
uint32_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
unsigned bit8:1;
unsigned bit9:1;
unsigned bit10:1;
unsigned bit11:1;
unsigned bit12:1;
unsigned bit13:1;
unsigned bit14:1;
unsigned bit15:1;
unsigned bit16:1;
unsigned bit17:1;
unsigned bit18:1;
unsigned bit19:1;
unsigned bit20:1;
unsigned bit21:1;
unsigned bit22:1;
unsigned bit23:1;
unsigned bit24:1;
unsigned bit25:1;
unsigned bit26:1;
unsigned bit27:1;
unsigned bit28:1;
unsigned bit29:1;
unsigned bit30:1;
unsigned bit31:1;
}bit;
}uint32_BitTypeDef;
typedef union
{
uint64_t all;
struct
{
unsigned bit0:1;
unsigned bit1:1;
unsigned bit2:1;
unsigned bit3:1;
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
unsigned bit8:1;
unsigned bit9:1;
unsigned bit10:1;
unsigned bit11:1;
unsigned bit12:1;
unsigned bit13:1;
unsigned bit14:1;
unsigned bit15:1;
unsigned bit16:1;
unsigned bit17:1;
unsigned bit18:1;
unsigned bit19:1;
unsigned bit20:1;
unsigned bit21:1;
unsigned bit22:1;
unsigned bit23:1;
unsigned bit24:1;
unsigned bit25:1;
unsigned bit26:1;
unsigned bit27:1;
unsigned bit28:1;
unsigned bit29:1;
unsigned bit30:1;
unsigned bit31:1;
unsigned bit32:1;
unsigned bit33:1;
unsigned bit34:1;
unsigned bit35:1;
unsigned bit36:1;
unsigned bit37:1;
unsigned bit38:1;
unsigned bit39:1;
unsigned bit40:1;
unsigned bit41:1;
unsigned bit42:1;
unsigned bit43:1;
unsigned bit44:1;
unsigned bit45:1;
unsigned bit46:1;
unsigned bit47:1;
unsigned bit48:1;
unsigned bit49:1;
unsigned bit50:1;
unsigned bit51:1;
unsigned bit52:1;
unsigned bit53:1;
unsigned bit54:1;
unsigned bit55:1;
unsigned bit56:1;
unsigned bit57:1;
unsigned bit58:1;
unsigned bit59:1;
unsigned bit60:1;
unsigned bit61:1;
unsigned bit62:1;
unsigned bit63:1;
}bit;
}uint64_BitTypeDef;
/** BIT_ACCESS_TYPEDEF
* @}
*/
/**
* @addtogroup BIT_ACCESS_FUNCTIONS Byte access functions
* @ingroup BIT_ACCESS_DEFINES
* @brief Дефайны для обращения к битам в unsigned.
@{
*/
#define uint8_bit(_uint8_, _bit_) (*(uint8_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
#define uint16_bit(_uint8_, _bit_) (*(uint16_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
#define uint32_bit(_uint8_, _bit_) (*(uint32_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
#define uint64_bit(_uint8_, _bit_) (*(uint64_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
/** BIT_ACCESS_FUNCTIONS
* @}
*/
#endif //__BIT_ACCESS_H_

View File

@@ -0,0 +1,36 @@
/**
**************************************************************************
* @file mylibs_config.h
* @brief Конфигурации для библиотек MyLibs
**************************************************************************
* @defgroup MYLIBS_CONFIG Configs My Libs
* @ingroup MYLIBS_ALL
* @brief Конфигурации для библиотек MyLibs
@{
*************************************************************************/
#ifndef __MYLIBS_CONFIG_H_
#define __MYLIBS_CONFIG_H_
#include "stm32f1xx_hal.h"
// user includes
#include "interface_config.h"
#include "tester_config.h"
#define RS_USER_VARS_NUMB 0
#define ADC_USER_VARS_NUMB 0
#define ADC_CH_USER_VARS_NUMB 0
#define INCLUDE_BIT_ACCESS_LIB
#define INCLUDE_TRACKERS_LIB
#define INCLUDE_TRACE_LIB
//#define INCLUDE_GENERAL_PERIPH_LIBS
//#define FREERTOS_DELAY
/** MYLIBS_CONFIG
* @}
*/
#endif //__MYLIBS_CONFIG_H_

View File

@@ -0,0 +1,106 @@
/**
**************************************************************************
* @file mylibs_defs.h
* @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral.
**************************************************************************
* @defgroup MYLIBS_DEFINES My Libs defines
* @brief Базовые дефайны для всего проекта
*
*************************************************************************/
#ifndef __MYLIBS_DEFINES_H_
#define __MYLIBS_DEFINES_H_
#include "stm32f1xx_hal.h"
#include "mylibs_config.h"
/***************************************************************************
******************************ERROR_HANDLER********************************/
/**
* @addtogroup ERROR_HANDLER_DEFINES Error Handler defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для определения функции обработки ошибок
@{
*/
/* extern Error_Handler from main.h */
extern void Error_Handler(void);
/* Define error handler for MyLibs */
#define MyLibs_Error_Handler(_params_) Error_Handler(_params_)
/* If error handler not defined - set void */
#ifndef MyLibs_Error_Handler
#define ((void)0U)
#endif // MyLibs_Error_Handler
/** ERROR_HANDLER_DEFINES
* @}
*/
/***************************************************************************
********************************ACCESS_DEFINES*****************************/
#define ClearStruct(_struct_) memset(&(_struct_), 0, sizeof(_struct_))
/***************************************************************************
******************************DELAYS_DEFINES*******************************/
/**
* @addtogroup DELAYS_DEFINES Delays defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для реализации задержек
@{
*/
#ifdef FREERTOS_DELAY
#define msDelay(_ms_) osDelay(_ms_)
#else
#define msDelay(_ms_) HAL_Delay(_ms_)
#endif
/** DELAYS_DEFINES
* @}
*/
/***************************************************************************
*******************************MATH_DEFINES********************************/
/**
* @addtogroup MATH_DEFINES Math defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для различных математических функций
@{
*/
/**
* @brief Calc dividing including remainder
* @param _val_ - делимое.
* @param _div_ - делитель.
* @details Если результат деления без остатка: он возвращается как есть
Если с остатком - округляется вверх
*/
//#define Divide_Up(_val_, _div_) (((_val_)%(_div_))? (_val_)/(_div_)+1 : (_val_)/_div_) /* через тернарный оператор */
#define Divide_Up(_val_, _div_) ((_val_ - 1) / _div_) + 1 /* через мат выражение */
/**
* @brief Swap between Little Endian and Big Endian
* @param v - Переменная для свапа.
* @return v (new) - Свапнутая переменная.
* @details Переключения между двумя типами хранения слова: HI-LO байты и LO-HI байты.
*/
#define ByteSwap16(v) (((v&0xFF00) >> (8)) | ((v&0x00FF) << (8)))
/**
* @brief Absolute
* @param x - Переменная для модудя.
* @return x (new) - Число по модулю.
* @details Берет число по модулю. Хз как работает библиотечный abs в stdlib.h, мб это быстрее, но вряд ли конечно.
*/
#define ABS(x) ( ((x) > 0)? (x) : -(x))?
/** MATH_DEFINES
* @}
*/
#endif //__MYLIBS_DEFINES_H_

View File

@@ -0,0 +1,79 @@
/**
**************************************************************************
* @file mylibs_include.h
* @brief Заголочный файл для всех библиотек
**************************************************************************
@details
Здесь нужно собрать библиотеки и дефайны, которые должны быть видны во всем проекте,
чтобы не подключать 100 инклюдов в каждом ".c" файле
**************************************************************************
* @defgroup MYLIBS_ALL My Libs
* @brief Все используемые MyLibs библиотеки
*
*************************************************************************/
#ifndef __MYLIBS_INCLUDE_H_
#define __MYLIBS_INCLUDE_H_
#include "mylibs_defs.h"
#ifdef ARM_MATH_CM4
#include "arm_math.h"
#endif
#ifdef INCLUDE_BIT_ACCESS_LIB
#include "bit_access.h"
#endif
#ifdef INCLUDE_TRACKERS_LIB
#include "trackers.h"
#endif
#ifdef INCLUDE_TRACE_LIB
#include "trace.h"
#endif
#ifdef INCLUDE_GENERAL_PERIPH_LIBS
#include "general_flash.h"
#include "general_gpio.h"
#ifdef HAL_SPI_MODULE_ENABLED
#include "general_spi.h"
#endif
#ifdef HAL_UART_MODULE_ENABLED
#include "general_uart.h"
#endif
#ifdef HAL_TIM_MODULE_ENABLED
#include "general_tim.h"
#endif
#endif //INCLUDE_GENERAL_PERIPH_LIBS
/////////////////////////---USER SETTINGS---/////////////////////////
// user includes
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "math.h"
#include "main.h"
#include "modbus_data.h"
/** @brief Struct for trackers for Measure */
/** @brief Struct for trackers for RS */
typedef TrackerTypeDef(RS_USER_VARS_NUMB) RS_TrackerTypeDef;
/** @brief Struct for trackers for ADC */
typedef TrackerTypeDef(ADC_USER_VARS_NUMB) ADC_TrackerTypeDef;
/** @brief Struct for trackers for ADC Channel */
typedef TrackerTypeDef(ADC_CH_USER_VARS_NUMB) ADCChannel_TrackerTypeDef;
/////////////////////////---USER SETTINGS---/////////////////////////
#endif // __MYLIBS_INCLUDE_H_

View File

@@ -0,0 +1,80 @@
/**
**************************************************************************
* @file trace.h
* @brief Заголочный файл для работы с трассировкой.
**************************************************************************
* @addtogroup TRACE Trace defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для работы с трассировкой
*************************************************************************/
#ifndef __TRACE_H_
#define __TRACE_H_
#include "mylibs_defs.h"
/**
* @addtogroup TRACE_SERIAL Serial trace defines
* @ingroup TRACE
* @brief Дефайны для работы с serial трассировкой
* @details Определяется дефайн my_printf() для работы с serial трассировкой:
- для RTT это будет вызов функции SEGGER_RTT_printf(), с подключением библиотеки SEGGER_RTT.h
- для SWO это будет просто printf(), но библиотеку STDOUT надо подключить самостоятельно:
@verbatim
Manage Run-Time Environment -> Compiler -> I/O -> STDOUT
@endverbatim
- Если трассировка отключена, то все дефайны определяются как 'ничего' и на производительность кода не влияют
@{
*/
/* Выбор какой serial trace использовать */
#ifdef SERIAL_TRACE_ENABLE
#if defined(RTT_TRACE_ENABLE)
#undef SWO_TRACE_ENABLE
#include "SEGGER_RTT.h"
#define my_printf(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#elif defined(SWO_TRACE_ENABLE)
#undef RTT_TRACE_ENABLE
#define my_printf(...) printf(__VA_ARGS__)
#else // NO_TRACE
#define my_printf(...)
#warning No trace is selected. Serial debug wont work.
#endif // RTT_TRACE_ENABLE/SWO_TRACE_ENABLE/NO_TRACE
#else //SERIAL_TRACE_ENABLE
#define my_printf(...)
#undef RTT_TRACE_ENABLE
#undef SWO_TRACE_ENABLE
#endif //SERIAL_TRACE_ENABLE
/** TRACE_SERIAL
* @}
*/
/**
* @addtogroup TRACE_GPIO GPIO trace defines
* @ingroup TRACE
* @brief Дефайны для работы с GPIO трассировкой
* @details Определяется дефайны для работы с GPIO трассировкой:
- TRACE_GPIO_RESET() - для сброса ножки GPIO (через BSRR)
- TRACE_GPIO_SET() - для выставления ножки GPIO (через BSRR)
- Если трассировка отключена, то все дефайны определяются как 'ничего' и на производительность кода не влияют
@{
*/
#ifndef GPIO_TRACE_ENABLE
#define TRACE_GPIO_RESET(_gpio_,_pin_)
#define TRACE_GPIO_SET(_gpio_,_pin_)
#else
#define TRACE_GPIO_RESET(_gpio_,_pin_) (_gpio_)->BSRR = ((_pin_)<<16)
#define TRACE_GPIO_SET(_gpio_,_pin_) (_gpio_)->BSRR = (((_pin_)))
#endif //GPIO_TRACE_ENABLE
/** TRACE_GPIO
* @}
*/
#endif //__TRACE_H_

View File

@@ -0,0 +1,141 @@
/**
**************************************************************************
* @file mylibs_defs.h
* @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral.
**************************************************************************
* @defgroup MYLIBS_DEFINES My Libs defines
* @brief Базовые дефайны для всего проекта
*
*************************************************************************/
#ifndef __TRACKERS_H_
#define __TRACKERS_H_
#include "mylibs_defs.h"
/**
* @addtogroup TRACKERS Trackers defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для работы с трекерами
* @details Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars).
Структура состоит из следующих элементов:
- cnt_ok
- cnt_err
- cnt_warn
- user[num_user_vars]
Также есть ряд функций (дефайнов) для обращения к элементам этой структуры.
Если трассировка отключена, то все дефайны определяются как ничего и на производительность кода не влияют
@par Пример:
Определяем typedef трекера измерений @ref Measure_TrackerTypeDef
@verbatim
typedef TrackerTypeDef(MEASURE_USER_VARS_NUMB) Measure_TrackerTypeDef;
@endverbatim
И через @ref Measure_TrackerTypeDef структура подключается в @ref TESTER_MeasureHandleTypeDef, а также
если необхожимо в другие структуру, например в структуру всех ошибок через указатель @ref TESTER_TrackerTypeDef
@{
*/
#ifdef TRACKERS_ENABLE
/**
* @brief Структура для счетчиков отладки
* @param num_user_vars - количество пользовательских счетчиков
* @details Содержит счетчик для успешных событый (cnt_ok),
* счетчик для ошибок (cnt_err), счетчик для предупреждений (cnt_warn).
*
* Также есть возможность объявить пользовательские счетчики в
* количестве <num_user_vars> штук.
*
* Для работы с структурой можно использовать функции:
* - TrackerCnt_Ok()
* - TrackerCnt_Err()
* - TrackerCnt_Warn()
* - TrackerCnt_User()
* - TrackerWrite_User()
* - TrackerClear_All()
* - TrackerClear_Ok()
* - TrackerClear_Err()
* - TrackerClear_Warn()
* - TrackerClear_User()
* - TrackerClear_UserAll()
*/
#define TrackerTypeDef(num_user_vars) \
struct \
{ \
uint32_t cnt_ok; \
uint32_t cnt_err; \
uint32_t cnt_warn; \
uint32_t user[num_user_vars]; \
}
/** @brief Получить количетство пользовательских переменных */
#define num_of_usercnts(_user_) (sizeof(_user_) / sizeof(_user_[0]))
/** @brief Проверка существует ли указанная пользовательская переменная */
#define assert_usertracker(_cntstruct_, _uservarnumb_) ((_uservarnumb_) < num_of_usercnts((_cntstruct_).user))
/** @brief Условие для проверки существует ли указанная пользовательская переменная */
#define if_assert_usertracker(_cntstruct_, _uservarnumb_) if(assert_usertracker(_cntstruct_, _uservarnumb_))
/** @brief Тернарный оператор для проверки существует ли указанная пользовательская переменная */
#define tern_assert_usertracker(_cntstruct_, _uservarnumb_) (assert_usertracker(_cntstruct_, _uservarnumb_)) ? _uservarnumb_ : 0
/**
* @brief Запись числа в пользовательскую переменную
* @note Здесь нет проверки - существует ли пользовательская переменная!
* Есть возможность выйти за границы структуры!!!
* Чтобы этого избежать используете дефайн #ref assert_usertracker()
*/
#define TrackerGet_User(_cntstruct_, _uservarnumb_) (_cntstruct_).user[tern_assert_usertracker(_cntstruct_, _uservarnumb_)]
/** @brief Инкрементирование счетчика успешных событий */
#define TrackerCnt_Ok(_cntstruct_) (_cntstruct_).cnt_ok++
/** @brief Инкрементирование счетчика ошибок */
#define TrackerCnt_Err(_cntstruct_) (_cntstruct_).cnt_err++
/** @brief Инкрементирование счетчика предупреждений */
#define TrackerCnt_Warn(_cntstruct_) (_cntstruct_).cnt_warn++
/** @brief Инкрементирование пользовательской переменной */
#define TrackerCnt_User(_cntstruct_, _uservarnumb_) if_assert_usertracker(_cntstruct_, _uservarnumb_) (_cntstruct_).user[_uservarnumb_]++;
/** @brief Запись числа в пользовательскую переменную */
#define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_) if_assert_usertracker(_cntstruct_, _uservarnumb_) (_cntstruct_).user[_uservarnumb_] = (_val_)
/** @brief Очистка всей структуры */
#define TrackerClear_All(_cntstruct_) memset(&(_cntstruct_), 0, sizeof(_cntstruct_))
/** @brief Очистка счетчика успешных событий */
#define TrackerClear_Ok(_cntstruct_) (_cntstruct_).cnt_ok = 0
/** @brief Очистка счетчика ошибок */
#define TrackerClear_Err(_cntstruct_) (_cntstruct_).cnt_err = 0
/** @brief Очистка счетчика предупреждений */
#define TrackerClear_Warn(_cntstruct_) (_cntstruct_).cnt_warn = 0
/** @brief Очистка пользовательской переменной */
#define TrackerClear_User(_cntstruct_, _uservarnumb_) if_assert_usertracker(_cntstruct_, _uservarnumb_) (_cntstruct_).user[_uservarnumb_] = 0;
/** @brief Очистка всех пользовательских переменных */
#define TrackerClear_UserAll(_cntstruct_) memset(&(_cntstruct_).user, 0, sizeof((_cntstruct_).user))
#else //TRACKERS_ENABLE
#define TrackerTypeDef(num_user_vars) void *
#define num_of_usercnts(_user_)
#define assert_tracecnt(_cntstruct_, _uservarnumb_)
#define TrackerCnt_Ok(_cntstruct_)
#define TrackerCnt_Err(_cntstruct_)
#define TrackerCnt_Warn(_cntstruct_)
#define TrackerCnt_User(_cntstruct_, _uservarnumb_)
#define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
/** @brief Очистка всей структуры */
#define TrackerClear_All(_cntstruct_)
#define TrackerClear_Ok(_cntstruct_)
#define TrackerClear_Err(_cntstruct_)
#define TrackerClear_Warn(_cntstruct_)
#define TrackerClear_User(_cntstruct_)
#define TrackerClear_UserAll(_cntstruct_)
#endif //TRACKERS_ENABLE
#endif //__TRACKERS_H_

View File

@@ -45,9 +45,9 @@ void MX_ADC1_Init(void)
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
@@ -98,7 +98,7 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_NORMAL;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{

View File

@@ -42,10 +42,23 @@
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */

View File

@@ -21,11 +21,13 @@
#include "adc.h"
#include "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "rs_message.h"
#include "tester_adc_func.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -58,6 +60,10 @@ void SystemClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int delay = 250;
int delay_en = 1;
int before_pulse_delay = 50;
int pulse_delay = 10;
/* USER CODE END 0 */
/**
@@ -92,14 +98,28 @@ int main(void)
MX_DMA_Init();
MX_ADC1_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
// HAL_ADC_Start_DMA(&hadc1, (uint32_t *)buff, ADC_BUFF_SIZE);
// HAL_TIM_Base_Start_IT(&htim3);
TESTER_ADC_StructInit(&tester_adc);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(delay_en)
msDelay(delay);
// HAL_UART_Transmit(&huart1, (uint8_t *)"axaxa", 5, 100);
ADC_DMA_StartRead(&tester_adc);
for(int i = 0; i < before_pulse_delay; i++);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
for(int i = 0; i < pulse_delay; i++);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
ADC_DMA_ReadWhileDMA(&tester_adc, 1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */

View File

@@ -22,6 +22,7 @@
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "tester_adc_func.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -56,9 +57,12 @@
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
@@ -205,7 +209,7 @@ void SysTick_Handler(void)
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
ADC_DMA_Handler(&tester_adc);
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
@@ -213,13 +217,27 @@ void DMA1_Channel1_IRQHandler(void)
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles TIM2 global interrupt.
*/
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
/* USER CODE END TIM2_IRQn 0 */
HAL_TIM_IRQHandler(&htim2);
/* USER CODE BEGIN TIM2_IRQn 1 */
/* USER CODE END TIM2_IRQn 1 */
}
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
HAL_NVIC_ClearPendingIRQ(TIM3_IRQn);
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
@@ -227,6 +245,20 @@ void TIM3_IRQHandler(void)
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -24,8 +24,49 @@
/* USER CODE END 0 */
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
/* TIM2 init function */
void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
/* TIM3 init function */
void MX_TIM3_Init(void)
{
@@ -70,7 +111,22 @@ void MX_TIM3_Init(void)
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM3)
if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */
/* USER CODE END TIM2_MspInit 0 */
/* TIM2 clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
/* TIM2 interrupt Init */
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspInit 1 */
/* USER CODE END TIM2_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */
@@ -90,7 +146,21 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM3)
if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspDeInit 0 */
/* USER CODE END TIM2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM2_CLK_DISABLE();
/* TIM2 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspDeInit 1 */
/* USER CODE END TIM2_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspDeInit 0 */

View File

@@ -0,0 +1,122 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,457 @@
#include "tester_adc_func.h"
#include "adc.h"
TESTER_ADCTypeDef tester_adc = {0};
uint16_t ADC_DMA_Buff[ADC_DMA_BUFF_SIZE];
uint16_t ADC_DMA_HalfBuff[ADC_DMA_BUFF_SIZE/2];
void ADC_DMA_Handler(TESTER_ADCTypeDef *adc)
{
int flag_parse_dma = 0;
int buff_start_ind = 0;
int buff_end_ind = 0;
if(adc->f.dmaHandlerbusy)
return;
adc->f.dmaHandlerbusy = 1;
__disable_irq();
if(DMA1->ISR & DMA_FLAG_HT1)
{
memcpy(ADC_DMA_HalfBuff, ADC_DMA_Buff, sizeof(ADC_DMA_HalfBuff));
adc->f.dmaBufferHalfDone = 1;
buff_start_ind = 0;
buff_end_ind = ADC_BUFF_SIZE/2;
flag_parse_dma = 1;
}
else if (DMA1->ISR & DMA_FLAG_TC1)
{
memcpy(ADC_DMA_HalfBuff, (ADC_DMA_Buff+ADC_DMA_BUFF_SIZE/2), sizeof(ADC_DMA_HalfBuff));
adc->f.dmaBufferHalfDone = 2;
buff_start_ind = ADC_BUFF_SIZE/2;
buff_end_ind = ADC_BUFF_SIZE;
flag_parse_dma = 1;
}
else
{
flag_parse_dma = 0;
TrackerCnt_Warn(adc->adc_err);
}
__enable_irq();
if(adc->f.enable_dmaBuffTransfer && flag_parse_dma)
{
int dma_ind = 0;
for(int buff_ind = buff_start_ind;
buff_ind < buff_end_ind;
buff_ind++)
{
adc->chAdc.ADC_Buff[buff_ind] = ADC_DMA_HalfBuff[dma_ind];
dma_ind += 1;
}
printf_adc_it("\n%d: ADC DMA IT Done %d-half", uwTick, adc->f.dmaBufferHalfDone);
adc->f.dmaHandlerbusy = 0;
TrackerCnt_Ok(adc->adc_err);
}
else
{
TrackerCnt_Warn(adc->adc_err);
}
}
void TESTER_ADC_StructInit(TESTER_ADCTypeDef *adc)
{
ClearStruct(*adc);
adc->hadc = &hadc1;
adc->chAdc.pulse_width = 4;
adc->filter.array_size = FOSTER_STUDENT_N;
adc->chAdc.ChMask = ADC_MEASURE_CHANNEL_0;
#ifdef FOSTER_STUDENT_USER_T_CRITICAL
adc->filter.t_critical = FOSTER_STUDENT_USER_T_CRITICAL;
#else
adc->filter.precise_table_ind = 2;
#endif
// adc->DMA_HalfBuff = ADC_DMA_HalfBuff;
// adc->DMA_Buff = ADC_DMA_Buff;
}
HAL_StatusTypeDef ADC_DMA_StartRead(TESTER_ADCTypeDef *adc)
{
HAL_StatusTypeDef res;
/* Очистка буферов каналов */
ClearStruct(adc->chAdc.ADC_Buff);
/* Очистка флага какая половина DMA уже готова */
adc->f.dmaBufferHalfDone = 0; // никакая, данные DMA пока не готовы в принципе
/* Разрешение заполнения буферов каналов */
adc->f.enable_dmaBuffTransfer = 1;
/* Выставления флага, что АЦП работает */
adc->f.adc_running = 1;
printf_adc("\n%d: ADC DMA Start", uwTick);
/* Старт АЦП с DMA */
res = HAL_ADC_Start_DMA(adc->hadc, (uint32_t *)ADC_DMA_Buff, ADC_DMA_BUFF_SIZE);
/* Если старт неудачен - запрет заполнения буферов каналов */
if(res != HAL_OK)
{
adc->f.enable_dmaBuffTransfer = 0;
adc->f.adc_running = 0;
}
return res;
}
HAL_StatusTypeDef ADC_DMA_StopRead(TESTER_ADCTypeDef *adc)
{
HAL_StatusTypeDef res;
if(adc->f.adc_running)
{
/* Остановка АЦП */
res = HAL_ADC_Stop_DMA(adc->hadc);
/* Очищение флагов АЦП */
adc->f.adc_running = 0;
adc->f.enable_dmaBuffTransfer = 0;
adc->f.dmaHandlerbusy = 0;
printf_adc("\n%d: ADC DMA Stop", uwTick);
}
return res;
}
void ADC_DMA_Fuel_Cell_Reset(TESTER_ADCChannelTypeDef *adc_fc)
{
adc_fc->ADC_Filtered = 0;
adc_fc->ADC_Max = 0;
adc_fc->ADC_Min = 0;
adc_fc->max_value_ind = 0;
adc_fc->state = 0;
}
void ADC_DMA_Channels_Prepare(TESTER_ADCChannelTypeDef *adc_fuel_cells, uint8_t MaskForChannels, uint8_t state)
{
for(int i = 0; i < 4; i++)
{
if(MaskForChannels&(1<<i))
{
ADC_DMA_Fuel_Cell_Reset(&adc_fuel_cells[i]);
adc_fuel_cells[i].state = state;
}
}
}
//uint8_t FosterStudent(TESTER_ADCChannelTypeDef *adc_fc, TESTER_ADCFilterTypeDef *Filter, uint32_t ind)
//{
//#ifndef FOSTER_STUDENT_USER_T_CRITICAL
// uint32_t t_critical[] = FOSTER_STUDENT_T_CRITICALS;
//#endif //FOSTER_STUDENT_USER_T_CRITICAL
// uint8_t res = 0;
//
// uint8_t m = 0;
// uint8_t l = 0;
//
// uint16_t max = adc_fc->ADC_Buff[ind];
// uint16_t min = adc_fc->ADC_Buff[ind];
//
// int16_t d_sum = 0;
// uint32_t t;
//
// uint16_t arr_size;
// if(ind < Filter->array_size)
// return 0xFF;
//
// for(int i = ind; i > ind - Filter->array_size; i--)
// {
//
// if(adc_fc->ADC_Buff[i] > max)
// {
// max = adc_fc->ADC_Buff[i];
// m = 1;
// }
// else
// m = 0;
// if(adc_fc->ADC_Buff[i] < min)
// {
// min = adc_fc->ADC_Buff[i];
// l = 1;
// }
// else
// l = 0;
// d_sum += (m-l);
// }
//
//#define fixed_base 1000
// if(d_sum < 0)
// d_sum = -d_sum;
// t = d_sum*fixed_base*fixed_base/FOSTER_STUDENT_MSE;
//
// Filter->t_current = t;
//#ifndef FOSTER_STUDENT_USER_T_CRITICAL
// Filter->t_critical = t_critical[Filter->precise_table_ind];
//#endif //FOSTER_STUDENT_USER_T_CRITICAL
//
//
// if(Filter->t_current > Filter->t_critical)
// {
// res = 1;
// }
// else
// {
// res = 0;
// }
//
//
//
// return res;
//}
void ADC_DMA_WaitForStableVoltage(TESTER_ADCChannelTypeDef *adc_fc, TESTER_ADCFilterTypeDef *Filter, uint32_t ind)
{
// if(FosterStudent(adc_fc, Filter, ind) == 0)
// {
// /* Сохраняем индекс еще стабильного напряжения */
// adc_fc->stable_start_ind = ind - Filter->array_size/2;
// /* Переключение на стабильное напряжение найдено */
// adc_fc->state = WAIT_FOR_DROP;
// }
}
void ADC_DMA_WaitForDropVoltage(TESTER_ADCChannelTypeDef *adc_fc, TESTER_ADCFilterTypeDef *Filter, uint32_t ind)
{
// if(FosterStudent(adc_fc, Filter, ind) == 1)
// {
// /* Сохраняем индекс еще стабильного напряжения */
// adc_fc->stable_end_ind = ind-Filter->array_size/2;
// /* Переключение на стабильное напряжение найдено */
// adc_fc->state = STABLE_FOUND;
// }
}
void ADC_DMA_CalcStabilized(TESTER_ADCChannelTypeDef *adc_fc)
{
uint16_t tmp_val = 0;
uint32_t val_sum = 0;
adc_fc->ADC_Max = 0;
adc_fc->ADC_Min = 0xFFFF;
/* Просмотр стабильных значений в буфере */
for(int i = 0; i < ADC_BUFF_SIZE; i++)
{
tmp_val = adc_fc->ADC_Buff[i];
/* Обновление максимального значения */
if(tmp_val > adc_fc->ADC_Max)
{
adc_fc->ADC_Max = tmp_val;
adc_fc->max_value_ind = i;
}
/* Обновление минимального значения */
if(tmp_val < adc_fc->ADC_Min)
{
adc_fc->ADC_Min = tmp_val;
}
}
/* Расчет среднего значения в пике */
for(int i = (adc_fc->max_value_ind - adc_fc->pulse_width)/2; i < (adc_fc->max_value_ind + adc_fc->pulse_width/2); i++)
{
tmp_val = adc_fc->ADC_Buff[i];
/* Накопление значений для расчета среднего */
val_sum += tmp_val;
}
adc_fc->ADC_Filtered = val_sum/(adc_fc->pulse_width);
}
void ADC_DMA_ProcessSingleBuffer(TESTER_ADCChannelTypeDef *adc_fc)
{
}
void ADC_DMA_ProcessBuffer(TESTER_ADCTypeDef *adc)
{
ADC_DMA_ProcessSingleBuffer(&adc->chAdc);
}
void ADC_DMA_BufferHandler(TESTER_ADCChannelTypeDef *adc_fc, TESTER_ADCFilterTypeDef *Filter, uint32_t ind)
{
// switch(adc_fc->state)
// {
// /* Канал не проверяется */
// case NOT_CHECKING:
// break;
//
// /* Пока на каналах не зарядится кондер */
// case WAIT_FOR_STABLE:
//// ADC_DMA_WaitForStableVoltage(adc_fc, Filter, ind);
// break;
//
// /* Проверка пока на первом канале не начнет разряжаться кондер */
// case WAIT_FOR_DROP:
//// ADC_DMA_WaitForDropVoltage(adc_fc, Filter, ind);
// break;
//
// /* Стабильное напряжение найдено */
// case STABLE_FOUND:
// /* Стабильное напряжение НЕ найдено */
// case STABLE_NOT_FOUND:
// /* Конец стабильного напряжения НЕ найден */
// case DROP_NOT_FOUND:
// break;
//
//
// /* Если состояние неопределенное */
// default:
// adc_fc->state = NOT_CHECKING;
// break;
//
// }
}
/**
* @brief Считывать АЦП до тех пор, пока буфер DMA не заполнится и не будет обработан
*/
HAL_StatusTypeDef ADC_DMA_ReadWhileDMA(TESTER_ADCTypeDef *adc, uint32_t Timeout)
{
uint32_t tickstart = HAL_GetTick();
/* Проверка принятых параметров функции */
if(adc == 0)
{
ADC_DMA_StopRead(adc);
printf_adc_err("\n%d: Error ADC: Handle is NULL)", uwTick);
return HAL_ERROR;
}
if(Timeout == 0)
{
ADC_DMA_StopRead(adc);
printf_adc_err("\n%d: Error ADC: Read timeout is NULL)", uwTick);
return HAL_ERROR;
}
int adc_buff_ind = 1;
uint16_t filter_halfend = ADC_BUFF_SIZE/2;
uint16_t filter_end = ADC_BUFF_SIZE;
uint8_t run_adc_check = 0;
uint8_t expected_dmaBufferHalf = 1;
/* Обработка АЦП */
while(1)
{
/* Проверка на таймаут */
if(HAL_GetTick() - tickstart > Timeout)
{
ADC_DMA_StopRead(adc);
printf_adc_err("\n%d: Error ADC: Stable Not Found (Timeout)", uwTick);
return HAL_TIMEOUT;
}
/* Запуск обработки данных из DMA буфера, когда они готовы */
if( (expected_dmaBufferHalf == adc->f.dmaBufferHalfDone) && // Ожидаемая половина DMA буфера готова
(run_adc_check == 0)) // Обработка предыдущей половины не активна
{
run_adc_check = 1;
if(adc->f.dmaBufferHalfDone == 1)
printf_adc_processing("\n%d: ADC Processing DMA start...", uwTick);
else if(adc->f.dmaBufferHalfDone == 2)
printf_adc_processing("\n%d: ADC Processing DMA 2-half start...", uwTick);
}
/* Обработка буфера DMA */
if(run_adc_check)
{
/* Вызов обработчиков буфера DMA для каждого канала, если он выбран */
ADC_DMA_BufferHandler(&adc->chAdc, &adc->filter, adc_buff_ind);
/* Переход на следующие во времени значения каналов АЦП */
adc_buff_ind++;
/* если это первая половина DMA буфера */
if(expected_dmaBufferHalf == 1)
{
if(adc_buff_ind > filter_halfend) // Проверка первой половины закончена
{
adc_buff_ind = filter_halfend; // Выставляем индекс на вторую половину
run_adc_check = 0; // Сбрасываем флаг проверки каналов
expected_dmaBufferHalf = 2; // Устанавливаем ожидание готовности второй половины данных DMA буфера
printf_adc_processing("\n%d: ADC Processing 1-half DMA complete, wait for 2-half...", uwTick);
}
}
/* если это вторая половина DMA буфера */
else if(expected_dmaBufferHalf == 2)
{
/* Если АЦП работает - останавливаем его */
// note: пока без кольцевого режима, если за один цикл буфера ничего не удалось словить, вряд ли далее что-то появиться??
if(adc->f.adc_running)
{
ADC_DMA_StopRead(adc);
printf_adc_processing(": wait for processing complete...");
}
if(adc_buff_ind > filter_end) // Проверка первой половины закончена
{
adc_buff_ind = 0; // Выставляем индекс на первую половину
run_adc_check = 0; // Сбрасываем флаг проверки каналов
expected_dmaBufferHalf = 1; // Устанавливаем ожидание готовности первой половины данных DMA буфера
printf_adc_processing("\n%d: ADC Processing DMA complete", uwTick);
break;
}
}
/* если это "никакая" половина DMA буфера */
else
{ /* Сброс всего */
printf_adc_err("\n%d: ADC Processing DMA unexcpected half", uwTick);
adc_buff_ind = 0;
run_adc_check = 0;
expected_dmaBufferHalf = 1;
}
}
}
ADC_DMA_CalcStabilized(&adc->chAdc);
return HAL_OK;
}

View File

@@ -0,0 +1,156 @@
/**
**************************************************************************
* @file tester_func.h
* @brief Заголовочный файл для функций МЗКТ.
**************************************************************************
@details
*************************************************************************/
#ifndef _TESTER_ADC_FUNC_H_
#define _TESTER_ADC_FUNC_H_
#include "mylibs_include.h"
#define ADC_MEASURE_CHANNEL_0_Pos 0x00
#define ADC_MEASURE_CHANNEL_1_Pos 0x01
#define ADC_MEASURE_CHANNEL_2_Pos 0x02
#define ADC_MEASURE_CHANNEL_3_Pos 0x03
#define ADC_MEASURE_CHANNEL_0 (0x01 << ADC_MEASURE_CHANNEL_0_Pos)
#define ADC_MEASURE_CHANNEL_1 (0x01 << ADC_MEASURE_CHANNEL_1_Pos)
#define ADC_MEASURE_CHANNEL_2 (0x01 << ADC_MEASURE_CHANNEL_2_Pos)
#define ADC_MEASURE_CHANNEL_3 (0x01 << ADC_MEASURE_CHANNEL_3_Pos)
#define ADC_CH_IGNORE NULL // должно быть NULL!!!
#define Measure_Get_Channel(_chPtr_) (_chPtr_)->Tadc->chAdc
#define Measure_Get_Voltage(_chPtr_) ((_chPtr_)->Tadc->chAdc->U_Current)
#define Measure_Get_Zero(_chPtr_) ((_chPtr_)->Tadc->chAdc->refADC_zero)
#define Measure_Get_Calibr(_chPtr_) ((_chPtr_)->Tadc->chAdc->refADC_calibr)
#define Measure_Get_VoltStep(_chPtr_) ((_chPtr_)->Tadc->chAdc->refU_step)
#define Measure_Get_Filtered(_chPtr_) ((_chPtr_)->Tadc->chAdc->ADC_Filtered)
#define Measure_Calc_CalibrDiff(_chPtr_) abs((int)Measure_Get_Calibr(_chPtr_) - Measure_Get_Zero(_chPtr_))
#define Measure_Calc_FilterDiff(_chPtr_) abs((int)Measure_Get_Filtered(_chPtr_) - Measure_Get_Zero(_chPtr_))
#define Measure_Calc_Voltage(_chPtr_) ((float)Measure_Calc_FilterDiff(_chPtr_)*Measure_Get_VoltStep(_chPtr_))
//#define ADC_GetChannel(_AdcChPtr_) (_AdcChPtr_)->Tadc->chAdc
////#define Measure_Get_Voltage(_AdcChPtr_) ((_AdcChPtr_)->Tadc->chAdc->U_Current)
////#define Measure_Get_Zero(_AdcChPtr_) ((_AdcChPtr_)->Tadc->chAdc->refADC_zero)
////#define Measure_Get_Calibr(_AdcChPtr_) ((_AdcChPtr_)->Tadc->chAdc->refADC_calibr)
////#define Measure_Get_VoltStep(_AdcChPtr_) ((_AdcChPtr_)->Tadc->chAdc->refU_step)
////#define Measure_Get_Filtered(_AdcChPtr_) ((_AdcChPtr_)->Tadc->chAdc->ADC_Filtered)
//#define Channel_Calc_Diff(_AdcChPtr_, _value_) ((int)(_value_) - (_AdcChPtr_)->refADC_zero)
//#define Channel_Calc_CalibrValue(_AdcChPtr_) (abs(Channel_Calc_Diff((_AdcChPtr_), (_AdcChPtr_)->refADC_calibr)) )
//#define Channel_Calc_AdcValue(_AdcChPtr_) (abs(Channel_Calc_Diff((_AdcChPtr_), (_AdcChPtr_)->ADC_Filtered)) )
//#define Channel_Calc_Voltage(_AdcChPtr_) ((float)Channel_Calc_AdcValue(_AdcChPtr_)*(_AdcChPtr_)->refU_step)
typedef uint16_t ADC_BuffTypeDef[ADC_BUFF_SIZE];
typedef enum
{
ADC_DISABLED = 0,
WAIT_FOR_FIRST_HALF = 1,
PROCESSING_FIRST_HALF = 2,
WAIT_FOR_SECOND_HALF = 3,
PROCESSING_SECOND_HALF = 4,
ADC_DONE = 5,
}ADC_ChannelState;
typedef struct
{
ADC_BuffTypeDef ADC_Buff;
uint16_t ADC_Filtered;
float U_Current;
/* Parameter for calc voltage */
uint16_t refADC_zero;
uint16_t refADC_calibr;
float refU_step;
uint16_t ADC_Max;
uint16_t ADC_Min;
unsigned pulse_width;
unsigned max_value_ind;
uint8_t ChMask;
ADC_ChannelState state;
ADCChannel_TrackerTypeDef adc_ch_err;
}TESTER_ADCChannelTypeDef;
typedef struct
{
int32_t t_current;
int32_t t_critical;
#ifdef FOSTER_STUDENT_USER_T_CRITICAL
#else
uint8_t precise_table_ind;
#endif
uint16_t array_size;
}TESTER_ADCFilterTypeDef;
typedef struct
{
TESTER_ADCChannelTypeDef chAdc;
ADC_HandleTypeDef *hadc;
TESTER_ADCFilterTypeDef filter;
struct
{
unsigned adc_running:1;
unsigned enable_dmaBuffTransfer:1;
unsigned dmaBufferHalfDone:2;
unsigned dmaHandlerbusy:1;
}f;
ADC_TrackerTypeDef adc_err;
}TESTER_ADCTypeDef;
extern TESTER_ADCTypeDef tester_adc;
extern uint16_t ADC_DMA_Buff[ADC_DMA_BUFF_SIZE];
extern uint16_t ADC_DMA_HalfBuff[ADC_DMA_BUFF_SIZE/2];
void TESTER_ADC_StructInit(TESTER_ADCTypeDef *adc);
void ADC_DMA_Handler(TESTER_ADCTypeDef *adc);
void ADC_DMA_ProcessBuffer(TESTER_ADCTypeDef *adc);
void ADC_DMA_Channels_Prepare(TESTER_ADCChannelTypeDef *adc_fuel_cells, uint8_t MaskForChannels, uint8_t state);
HAL_StatusTypeDef ADC_DMA_StartRead(TESTER_ADCTypeDef *adc);
HAL_StatusTypeDef ADC_DMA_ReadWhileDMA(TESTER_ADCTypeDef *adc, uint32_t Timeout);
#ifndef printf_adc_result
#define printf_adc_result(...)
#endif
#ifndef printf_adc_processing
#define printf_adc_processing(...)
#endif
#ifndef printf_adc_err
#define printf_adc_err(...)
#endif
#ifndef printf_adc_it
#define printf_adc_it(...)
#endif
#ifndef printf_adc
#define printf_adc(...)
#endif
#endif //_TESTER_ADC_FUNC_H_

View File

@@ -0,0 +1,67 @@
/**
**************************************************************************
* @file tester_config.h
* @brief Конфигурации для тестера диодов
**************************************************************************
* @defgroup TESTER_CONFIGS Configs for project
* @brief Конфигурации для тестера диодов
* @details
@{
*************************************************************************/
#ifndef _TESTER_CONFIG_H_
#define _TESTER_CONFIG_H_
/**
* @addtogroup TESTER_ADC_CONFIG Configs for ADC
* @ingroup TESTER_CONFIGS
* @brief Конфигурации для АЦП
@{
*/
#define ADC_BUFF_SIZE (500) ///< Размер буфера АЦП
#define ADC_DMA_BUFF_SIZE (ADC_BUFF_SIZE*4) ///< Размер буфера ДМА (4 канала)
#define ADC_U_CALIBR ((float)1.1) ///< Напряжение, которое подается при калибровке
#define ADC_READ_TIMEOUT_MS 20 ///< Таймаут на ожидание разрядки конденсатора
#define ADC_ZERO_WAIT_TIMEOUS_MS 100 ///< Таймаут на ожидание нуля (при калибровке)
#define FOSTER_STUDENT_N 40 ///< Выборка для определения начала разрядки конденсатора
#define FOSTER_STUDENT_MSE 2561 /*!< @brief Среднеквадратическая ошибка для выборки размером FOSTER_STUDENT_N, умноженная на 1000
@details Выражение для СКО: sqrt(2*ln(N) - 0,8456)
URL: https://old.stgau.ru/company/personal/user/7750/files/lib/%D0%A1%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5%20%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D1%8B%20%D0%BF%D1%80%D0%BE%D0%B3%D0%BD%D0%BE%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F/%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D1%83%D0%BC_%D1%82%D0%B5%D0%BC%D0%B0%201.pdf
*/
/**
* @brief Критическое значение Стьюдента
* @details Используется для определения разрядки конденсатора.
* Записывается в единицах*1000
* @note Если закомментировать, то будет использоваться таблица указанная в @ref FOSTER_STUDENT_T_CRITICALS
с индексом, указанным в @ref precise_table_ind
*/
#define FOSTER_STUDENT_USER_T_CRITICAL 1600//2650//2500
/**
* @brief Критическое значение Стьюдента для калибровки
* @details Используется для определения разрядки конденсатора при калибровке.
* Записывается в единицах*1000
* @note Если закомментировать, то будет использоваться значение указанное в @ref FOSTER_STUDENT_USER_T_CRITICAL
*/
//#define FOSTER_STUDENT_USER_T_CRITICAL_CALIBR 2600//2650//2500
/**
* @brief Таблица критических значений Стьюдента с разной погрешностью
* @details Используется для определения разрядки конденсатора при закомментированном
* @ref FOSTER_STUDENT_USER_T_CRITICAL
*/
#define FOSTER_STUDENT_T_CRITICALS {257, 688, 1328, 1729, 2093, 2539}
/** TESTER_ADC_CONFIG
* @}
*/
/** TESTER_CONFIGS
* @}
*/
#endif //_TESTER_CONFIG_H_

View File

@@ -0,0 +1,915 @@
/**
******************************************************************************
* @file stm32f1xx_hal_uart.h
* @author MCD Application Team
* @brief Header file of UART HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2016 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_UART_H
#define __STM32F1xx_HAL_UART_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal_def.h"
/** @addtogroup STM32F1xx_HAL_Driver
* @{
*/
/** @addtogroup UART
* @{
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup UART_Exported_Types UART Exported Types
* @{
*/
/**
* @brief UART Init Structure definition
*/
typedef struct
{
uint32_t BaudRate; /*!< This member configures the UART communication baud rate.
The baud rate is computed using the following formula:
- IntegerDivider = ((PCLKx) / (16 * (huart->Init.BaudRate)))
- FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
This parameter can be a value of @ref UART_Word_Length */
uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
This parameter can be a value of @ref UART_Stop_Bits */
uint32_t Parity; /*!< Specifies the parity mode.
This parameter can be a value of @ref UART_Parity
@note When parity is enabled, the computed parity is inserted
at the MSB position of the transmitted data (9th bit when
the word length is set to 9 data bits; 8th bit when the
word length is set to 8 data bits). */
uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
This parameter can be a value of @ref UART_Mode */
uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
This parameter can be a value of @ref UART_Hardware_Flow_Control */
uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
This parameter can be a value of @ref UART_Over_Sampling. This feature is only available
on STM32F100xx family, so OverSampling parameter should always be set to 16. */
} UART_InitTypeDef;
/**
* @brief HAL UART State structures definition
* @note HAL UART State value is a combination of 2 different substates: gState and RxState.
* - gState contains UART state information related to global Handle management
* and also information related to Tx operations.
* gState value coding follow below described bitmap :
* b7-b6 Error information
* 00 : No Error
* 01 : (Not Used)
* 10 : Timeout
* 11 : Error
* b5 Peripheral initialization status
* 0 : Reset (Peripheral not initialized)
* 1 : Init done (Peripheral initialized. HAL UART Init function already called)
* b4-b3 (not used)
* xx : Should be set to 00
* b2 Intrinsic process state
* 0 : Ready
* 1 : Busy (Peripheral busy with some configuration or internal operations)
* b1 (not used)
* x : Should be set to 0
* b0 Tx state
* 0 : Ready (no Tx operation ongoing)
* 1 : Busy (Tx operation ongoing)
* - RxState contains information related to Rx operations.
* RxState value coding follow below described bitmap :
* b7-b6 (not used)
* xx : Should be set to 00
* b5 Peripheral initialization status
* 0 : Reset (Peripheral not initialized)
* 1 : Init done (Peripheral initialized)
* b4-b2 (not used)
* xxx : Should be set to 000
* b1 Rx state
* 0 : Ready (no Rx operation ongoing)
* 1 : Busy (Rx operation ongoing)
* b0 (not used)
* x : Should be set to 0.
*/
typedef enum
{
HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
Value is allowed for gState and RxState */
HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
Value is allowed for gState and RxState */
HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
Value is allowed for gState only */
HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
Value is allowed for gState only */
HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
Value is allowed for RxState only */
HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
Not to be used for neither gState nor RxState.
Value is result of combination (Or) between gState and RxState values */
HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
Value is allowed for gState only */
HAL_UART_STATE_ERROR = 0xE0U /*!< Error
Value is allowed for gState only */
} HAL_UART_StateTypeDef;
/**
* @brief HAL UART Reception type definition
* @note HAL UART Reception type value aims to identify which type of Reception is ongoing.
* This parameter can be a value of @ref UART_Reception_Type_Values :
* HAL_UART_RECEPTION_STANDARD = 0x00U,
* HAL_UART_RECEPTION_TOIDLE = 0x01U,
*/
typedef uint32_t HAL_UART_RxTypeTypeDef;
/**
* @brief HAL UART Rx Event type definition
* @note HAL UART Rx Event type value aims to identify which type of Event has occurred
* leading to call of the RxEvent callback.
* This parameter can be a value of @ref UART_RxEvent_Type_Values :
* HAL_UART_RXEVENT_TC = 0x00U,
* HAL_UART_RXEVENT_HT = 0x01U,
* HAL_UART_RXEVENT_IDLE = 0x02U,
*/
typedef uint32_t HAL_UART_RxEventTypeTypeDef;
/**
* @brief UART handle Structure definition
*/
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance; /*!< UART registers base address */
UART_InitTypeDef Init; /*!< UART communication parameters */
const uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
uint16_t TxXferSize; /*!< UART Tx Transfer size */
__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
uint16_t RxXferSize; /*!< UART Rx Transfer size */
__IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
__IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */
__IO HAL_UART_RxEventTypeTypeDef RxEventType; /*!< Type of Rx Event */
DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
HAL_LockTypeDef Lock; /*!< Locking object */
__IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
and also related to Tx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO uint32_t ErrorCode; /*!< UART Error code */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Half Complete Callback */
void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Complete Callback */
void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Half Complete Callback */
void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Complete Callback */
void (* ErrorCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Error Callback */
void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Complete Callback */
void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */
void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Receive Complete Callback */
void (* WakeupCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Wakeup Callback */
void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback */
void (* MspInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp Init callback */
void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp DeInit callback */
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
} UART_HandleTypeDef;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/**
* @brief HAL UART Callback ID enumeration definition
*/
typedef enum
{
HAL_UART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< UART Tx Half Complete Callback ID */
HAL_UART_TX_COMPLETE_CB_ID = 0x01U, /*!< UART Tx Complete Callback ID */
HAL_UART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< UART Rx Half Complete Callback ID */
HAL_UART_RX_COMPLETE_CB_ID = 0x03U, /*!< UART Rx Complete Callback ID */
HAL_UART_ERROR_CB_ID = 0x04U, /*!< UART Error Callback ID */
HAL_UART_ABORT_COMPLETE_CB_ID = 0x05U, /*!< UART Abort Complete Callback ID */
HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< UART Abort Transmit Complete Callback ID */
HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< UART Abort Receive Complete Callback ID */
HAL_UART_WAKEUP_CB_ID = 0x08U, /*!< UART Wakeup Callback ID */
HAL_UART_MSPINIT_CB_ID = 0x0BU, /*!< UART MspInit callback ID */
HAL_UART_MSPDEINIT_CB_ID = 0x0CU /*!< UART MspDeInit callback ID */
} HAL_UART_CallbackIDTypeDef;
/**
* @brief HAL UART Callback pointer definition
*/
typedef void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */
typedef void (*pUART_RxEventCallbackTypeDef)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< pointer to a UART Rx Event specific callback function */
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup UART_Exported_Constants UART Exported Constants
* @{
*/
/** @defgroup UART_Error_Code UART Error Code
* @{
*/
#define HAL_UART_ERROR_NONE 0x00000000U /*!< No error */
#define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error */
#define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error */
#define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error */
#define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error */
#define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
#define HAL_UART_ERROR_INVALID_CALLBACK 0x00000020U /*!< Invalid Callback error */
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
/**
* @}
*/
/** @defgroup UART_Word_Length UART Word Length
* @{
*/
#define UART_WORDLENGTH_8B 0x00000000U
#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
/**
* @}
*/
/** @defgroup UART_Stop_Bits UART Number of Stop Bits
* @{
*/
#define UART_STOPBITS_1 0x00000000U
#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
/**
* @}
*/
/** @defgroup UART_Parity UART Parity
* @{
*/
#define UART_PARITY_NONE 0x00000000U
#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
/**
* @}
*/
/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
* @{
*/
#define UART_HWCONTROL_NONE 0x00000000U
#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE)
#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE)
#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
/**
* @}
*/
/** @defgroup UART_Mode UART Transfer Mode
* @{
*/
#define UART_MODE_RX ((uint32_t)USART_CR1_RE)
#define UART_MODE_TX ((uint32_t)USART_CR1_TE)
#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE | USART_CR1_RE))
/**
* @}
*/
/** @defgroup UART_State UART State
* @{
*/
#define UART_STATE_DISABLE 0x00000000U
#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE)
/**
* @}
*/
/** @defgroup UART_Over_Sampling UART Over Sampling
* @{
*/
#define UART_OVERSAMPLING_16 0x00000000U
#if defined(USART_CR1_OVER8)
#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8)
#endif /* USART_CR1_OVER8 */
/**
* @}
*/
/** @defgroup UART_LIN_Break_Detection_Length UART LIN Break Detection Length
* @{
*/
#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U
#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL)
/**
* @}
*/
/** @defgroup UART_WakeUp_functions UART Wakeup Functions
* @{
*/
#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U
#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE)
/**
* @}
*/
/** @defgroup UART_Flags UART FLags
* Elements values convention: 0xXXXX
* - 0xXXXX : Flag mask in the SR register
* @{
*/
#define UART_FLAG_CTS ((uint32_t)USART_SR_CTS)
#define UART_FLAG_LBD ((uint32_t)USART_SR_LBD)
#define UART_FLAG_TXE ((uint32_t)USART_SR_TXE)
#define UART_FLAG_TC ((uint32_t)USART_SR_TC)
#define UART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
#define UART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
#define UART_FLAG_ORE ((uint32_t)USART_SR_ORE)
#define UART_FLAG_NE ((uint32_t)USART_SR_NE)
#define UART_FLAG_FE ((uint32_t)USART_SR_FE)
#define UART_FLAG_PE ((uint32_t)USART_SR_PE)
/**
* @}
*/
/** @defgroup UART_Interrupt_definition UART Interrupt Definitions
* Elements values convention: 0xY000XXXX
* - XXXX : Interrupt mask (16 bits) in the Y register
* - Y : Interrupt source register (2bits)
* - 0001: CR1 register
* - 0010: CR2 register
* - 0011: CR3 register
* @{
*/
#define UART_IT_PE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
#define UART_IT_TXE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
#define UART_IT_TC ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
#define UART_IT_RXNE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
#define UART_IT_IDLE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
#define UART_IT_LBD ((uint32_t)(UART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
#define UART_IT_CTS ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
#define UART_IT_ERR ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
/**
* @}
*/
/** @defgroup UART_Reception_Type_Values UART Reception type values
* @{
*/
#define HAL_UART_RECEPTION_STANDARD (0x00000000U) /*!< Standard reception */
#define HAL_UART_RECEPTION_TOIDLE (0x00000001U) /*!< Reception till completion or IDLE event */
/**
* @}
*/
/** @defgroup UART_RxEvent_Type_Values UART RxEvent type values
* @{
*/
#define HAL_UART_RXEVENT_TC (0x00000000U) /*!< RxEvent linked to Transfer Complete event */
#define HAL_UART_RXEVENT_HT (0x00000001U) /*!< RxEvent linked to Half Transfer event */
#define HAL_UART_RXEVENT_IDLE (0x00000002U)
/**
* @}
*/
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/** @defgroup UART_Exported_Macros UART Exported Macros
* @{
*/
/** @brief Reset UART handle gstate & RxState
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @retval None
*/
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
(__HANDLE__)->gState = HAL_UART_STATE_RESET; \
(__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
(__HANDLE__)->MspInitCallback = NULL; \
(__HANDLE__)->MspDeInitCallback = NULL; \
} while(0U)
#else
#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
(__HANDLE__)->gState = HAL_UART_STATE_RESET; \
(__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
} while(0U)
#endif /*USE_HAL_UART_REGISTER_CALLBACKS */
/** @brief Flushes the UART DR register
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
*/
#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
/** @brief Checks whether the specified UART flag is set or not.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @param __FLAG__ specifies the flag to check.
* This parameter can be one of the following values:
* @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
* @arg UART_FLAG_LBD: LIN Break detection flag
* @arg UART_FLAG_TXE: Transmit data register empty flag
* @arg UART_FLAG_TC: Transmission Complete flag
* @arg UART_FLAG_RXNE: Receive data register not empty flag
* @arg UART_FLAG_IDLE: Idle Line detection flag
* @arg UART_FLAG_ORE: Overrun Error flag
* @arg UART_FLAG_NE: Noise Error flag
* @arg UART_FLAG_FE: Framing Error flag
* @arg UART_FLAG_PE: Parity Error flag
* @retval The new state of __FLAG__ (TRUE or FALSE).
*/
#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
/** @brief Clears the specified UART pending flag.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @param __FLAG__ specifies the flag to check.
* This parameter can be any combination of the following values:
* @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
* @arg UART_FLAG_LBD: LIN Break detection flag.
* @arg UART_FLAG_TC: Transmission Complete flag.
* @arg UART_FLAG_RXNE: Receive data register not empty flag.
*
* @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun
* error) and IDLE (Idle line detected) flags are cleared by software
* sequence: a read operation to USART_SR register followed by a read
* operation to USART_DR register.
* @note RXNE flag can be also cleared by a read to the USART_DR register.
* @note TC flag can be also cleared by software sequence: a read operation to
* USART_SR register followed by a write operation to USART_DR register.
* @note TXE flag is cleared only by a write to the USART_DR register.
*
* @retval None
*/
#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
/** @brief Clears the UART PE pending flag.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @retval None
*/
#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \
do{ \
__IO uint32_t tmpreg = 0x00U; \
tmpreg = (__HANDLE__)->Instance->SR; \
tmpreg = (__HANDLE__)->Instance->DR; \
UNUSED(tmpreg); \
} while(0U)
/** @brief Clears the UART FE pending flag.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @retval None
*/
#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
/** @brief Clears the UART NE pending flag.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @retval None
*/
#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
/** @brief Clears the UART ORE pending flag.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @retval None
*/
#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
/** @brief Clears the UART IDLE pending flag.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @retval None
*/
#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
/** @brief Enable the specified UART interrupt.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @param __INTERRUPT__ specifies the UART interrupt source to enable.
* This parameter can be one of the following values:
* @arg UART_IT_CTS: CTS change interrupt
* @arg UART_IT_LBD: LIN Break detection interrupt
* @arg UART_IT_TXE: Transmit Data Register empty interrupt
* @arg UART_IT_TC: Transmission complete interrupt
* @arg UART_IT_RXNE: Receive Data register not empty interrupt
* @arg UART_IT_IDLE: Idle line detection interrupt
* @arg UART_IT_PE: Parity Error interrupt
* @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
* @retval None
*/
#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
/** @brief Disable the specified UART interrupt.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @param __INTERRUPT__ specifies the UART interrupt source to disable.
* This parameter can be one of the following values:
* @arg UART_IT_CTS: CTS change interrupt
* @arg UART_IT_LBD: LIN Break detection interrupt
* @arg UART_IT_TXE: Transmit Data Register empty interrupt
* @arg UART_IT_TC: Transmission complete interrupt
* @arg UART_IT_RXNE: Receive Data register not empty interrupt
* @arg UART_IT_IDLE: Idle line detection interrupt
* @arg UART_IT_PE: Parity Error interrupt
* @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
* @retval None
*/
#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
/** @brief Checks whether the specified UART interrupt source is enabled or not.
* @param __HANDLE__ specifies the UART Handle.
* UART Handle selects the USARTx or UARTy peripheral
* (USART,UART availability and x,y values depending on device).
* @param __IT__ specifies the UART interrupt source to check.
* This parameter can be one of the following values:
* @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
* @arg UART_IT_LBD: LIN Break detection interrupt
* @arg UART_IT_TXE: Transmit Data Register empty interrupt
* @arg UART_IT_TC: Transmission complete interrupt
* @arg UART_IT_RXNE: Receive Data register not empty interrupt
* @arg UART_IT_IDLE: Idle line detection interrupt
* @arg UART_IT_ERR: Error interrupt
* @retval The new state of __IT__ (TRUE or FALSE).
*/
#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == UART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == UART_CR2_REG_INDEX)? \
(__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK))
/** @brief Enable CTS flow control
* @note This macro allows to enable CTS hardware flow control for a given UART instance,
* without need to call HAL_UART_Init() function.
* As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
* @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
* for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
* - UART instance should have already been initialised (through call of HAL_UART_Init() )
* - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
* and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
* @param __HANDLE__ specifies the UART Handle.
* The Handle Instance can be any USARTx (supporting the HW Flow control feature).
* It is used to select the USART peripheral (USART availability and x value depending on device).
* @retval None
*/
#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \
do{ \
ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
(__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \
} while(0U)
/** @brief Disable CTS flow control
* @note This macro allows to disable CTS hardware flow control for a given UART instance,
* without need to call HAL_UART_Init() function.
* As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
* @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
* for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
* - UART instance should have already been initialised (through call of HAL_UART_Init() )
* - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
* and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
* @param __HANDLE__ specifies the UART Handle.
* The Handle Instance can be any USARTx (supporting the HW Flow control feature).
* It is used to select the USART peripheral (USART availability and x value depending on device).
* @retval None
*/
#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \
do{ \
ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
(__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \
} while(0U)
/** @brief Enable RTS flow control
* This macro allows to enable RTS hardware flow control for a given UART instance,
* without need to call HAL_UART_Init() function.
* As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
* @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
* for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
* - UART instance should have already been initialised (through call of HAL_UART_Init() )
* - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
* and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
* @param __HANDLE__ specifies the UART Handle.
* The Handle Instance can be any USARTx (supporting the HW Flow control feature).
* It is used to select the USART peripheral (USART availability and x value depending on device).
* @retval None
*/
#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \
do{ \
ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \
(__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \
} while(0U)
/** @brief Disable RTS flow control
* This macro allows to disable RTS hardware flow control for a given UART instance,
* without need to call HAL_UART_Init() function.
* As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
* @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
* for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
* - UART instance should have already been initialised (through call of HAL_UART_Init() )
* - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
* and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
* @param __HANDLE__ specifies the UART Handle.
* The Handle Instance can be any USARTx (supporting the HW Flow control feature).
* It is used to select the USART peripheral (USART availability and x value depending on device).
* @retval None
*/
#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \
do{ \
ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\
(__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \
} while(0U)
#if defined(USART_CR3_ONEBIT)
/** @brief Macro to enable the UART's one bit sample method
* @param __HANDLE__ specifies the UART Handle.
* @retval None
*/
#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
/** @brief Macro to disable the UART's one bit sample method
* @param __HANDLE__ specifies the UART Handle.
* @retval None
*/
#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3\
&= (uint16_t)~((uint16_t)USART_CR3_ONEBIT))
#endif /* UART_ONE_BIT_SAMPLE_Feature */
/** @brief Enable UART
* @param __HANDLE__ specifies the UART Handle.
* @retval None
*/
#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
/** @brief Disable UART
* @param __HANDLE__ specifies the UART Handle.
* @retval None
*/
#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup UART_Exported_Functions
* @{
*/
/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
* @{
*/
/* Initialization/de-initialization functions **********************************/
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);
void HAL_UART_MspInit(UART_HandleTypeDef *huart);
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
/* Callbacks Register/UnRegister functions ***********************************/
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
pUART_CallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID);
HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
/**
* @}
*/
/** @addtogroup UART_Exported_Functions_Group2 IO operation functions
* @{
*/
/* IO operation functions *******************************************************/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
uint32_t Timeout);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart);
/* Transfer Abort functions */
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart);
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);
/**
* @}
*/
/** @addtogroup UART_Exported_Functions_Group3
* @{
*/
/* Peripheral Control functions ************************************************/
HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart);
/**
* @}
*/
/** @addtogroup UART_Exported_Functions_Group4
* @{
*/
/* Peripheral State functions **************************************************/
HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart);
uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart);
/**
* @}
*/
/**
* @}
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/** @defgroup UART_Private_Constants UART Private Constants
* @{
*/
/** @brief UART interruptions flag mask
*
*/
#define UART_IT_MASK 0x0000FFFFU
#define UART_CR1_REG_INDEX 1U
#define UART_CR2_REG_INDEX 2U
#define UART_CR3_REG_INDEX 3U
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup UART_Private_Macros UART Private Macros
* @{
*/
#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \
((LENGTH) == UART_WORDLENGTH_9B))
#define IS_UART_LIN_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B))
#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \
((STOPBITS) == UART_STOPBITS_2))
#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \
((PARITY) == UART_PARITY_EVEN) || \
((PARITY) == UART_PARITY_ODD))
#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
(((CONTROL) == UART_HWCONTROL_NONE) || \
((CONTROL) == UART_HWCONTROL_RTS) || \
((CONTROL) == UART_HWCONTROL_CTS) || \
((CONTROL) == UART_HWCONTROL_RTS_CTS))
#define IS_UART_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00U))
#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \
((STATE) == UART_STATE_ENABLE))
#if defined(USART_CR1_OVER8)
#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \
((SAMPLING) == UART_OVERSAMPLING_8))
#endif /* USART_CR1_OVER8 */
#define IS_UART_LIN_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16))
#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \
((LENGTH) == UART_LINBREAKDETECTLENGTH_11B))
#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \
((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK))
#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) <= 4500000U)
#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0x0FU)
#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
#define UART_DIVMANT_SAMPLING16(_PCLK_, _BAUD_) (UART_DIV_SAMPLING16((_PCLK_), (_BAUD_))/100U)
#define UART_DIVFRAQ_SAMPLING16(_PCLK_, _BAUD_) ((((UART_DIV_SAMPLING16((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) * 100U)) * 16U)\
+ 50U) / 100U)
/* UART BRR = mantissa + overflow + fraction
= (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) << 4U) + \
(UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0xF0U)) + \
(UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0x0FU))
#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(2U*(_BAUD_)))
#define UART_DIVMANT_SAMPLING8(_PCLK_, _BAUD_) (UART_DIV_SAMPLING8((_PCLK_), (_BAUD_))/100U)
#define UART_DIVFRAQ_SAMPLING8(_PCLK_, _BAUD_) ((((UART_DIV_SAMPLING8((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) * 100U)) * 8U)\
+ 50U) / 100U)
/* UART BRR = mantissa + overflow + fraction
= (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07U) */
#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4U) + \
((UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0xF8U) << 1U)) + \
(UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x07U))
/**
* @}
*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup UART_Private_Functions UART Private Functions
* @{
*/
HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32F1xx_HAL_UART_H */

View File

@@ -0,0 +1,2569 @@
/**
******************************************************************************
* @file stm32f1xx_ll_usart.h
* @author MCD Application Team
* @brief Header file of USART LL module.
******************************************************************************
* @attention
*
* Copyright (c) 2016 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_LL_USART_H
#define __STM32F1xx_LL_USART_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx.h"
/** @addtogroup STM32F1xx_LL_Driver
* @{
*/
#if defined (USART1) || defined (USART2) || defined (USART3) || defined (UART4) || defined (UART5)
/** @defgroup USART_LL USART
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/** @defgroup USART_LL_Private_Constants USART Private Constants
* @{
*/
/* Defines used for the bit position in the register and perform offsets*/
#define USART_POSITION_GTPR_GT USART_GTPR_GT_Pos
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
#if defined(USE_FULL_LL_DRIVER)
/** @defgroup USART_LL_Private_Macros USART Private Macros
* @{
*/
/**
* @}
*/
#endif /*USE_FULL_LL_DRIVER*/
/* Exported types ------------------------------------------------------------*/
#if defined(USE_FULL_LL_DRIVER)
/** @defgroup USART_LL_ES_INIT USART Exported Init structures
* @{
*/
/**
* @brief LL USART Init Structure definition
*/
typedef struct
{
uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate.
This feature can be modified afterwards using unitary function @ref LL_USART_SetBaudRate().*/
uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame.
This parameter can be a value of @ref USART_LL_EC_DATAWIDTH.
This feature can be modified afterwards using unitary function @ref LL_USART_SetDataWidth().*/
uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
This parameter can be a value of @ref USART_LL_EC_STOPBITS.
This feature can be modified afterwards using unitary function @ref LL_USART_SetStopBitsLength().*/
uint32_t Parity; /*!< Specifies the parity mode.
This parameter can be a value of @ref USART_LL_EC_PARITY.
This feature can be modified afterwards using unitary function @ref LL_USART_SetParity().*/
uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled.
This parameter can be a value of @ref USART_LL_EC_DIRECTION.
This feature can be modified afterwards using unitary function @ref LL_USART_SetTransferDirection().*/
uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
This parameter can be a value of @ref USART_LL_EC_HWCONTROL.
This feature can be modified afterwards using unitary function @ref LL_USART_SetHWFlowCtrl().*/
uint32_t OverSampling; /*!< Specifies whether USART oversampling mode is 16 or 8.
This parameter can be a value of @ref USART_LL_EC_OVERSAMPLING.
This feature can be modified afterwards using unitary function @ref LL_USART_SetOverSampling().*/
} LL_USART_InitTypeDef;
/**
* @brief LL USART Clock Init Structure definition
*/
typedef struct
{
uint32_t ClockOutput; /*!< Specifies whether the USART clock is enabled or disabled.
This parameter can be a value of @ref USART_LL_EC_CLOCK.
USART HW configuration can be modified afterwards using unitary functions
@ref LL_USART_EnableSCLKOutput() or @ref LL_USART_DisableSCLKOutput().
For more details, refer to description of this function. */
uint32_t ClockPolarity; /*!< Specifies the steady state of the serial clock.
This parameter can be a value of @ref USART_LL_EC_POLARITY.
USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetClockPolarity().
For more details, refer to description of this function. */
uint32_t ClockPhase; /*!< Specifies the clock transition on which the bit capture is made.
This parameter can be a value of @ref USART_LL_EC_PHASE.
USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetClockPhase().
For more details, refer to description of this function. */
uint32_t LastBitClockPulse; /*!< Specifies whether the clock pulse corresponding to the last transmitted
data bit (MSB) has to be output on the SCLK pin in synchronous mode.
This parameter can be a value of @ref USART_LL_EC_LASTCLKPULSE.
USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetLastClkPulseOutput().
For more details, refer to description of this function. */
} LL_USART_ClockInitTypeDef;
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/* Exported constants --------------------------------------------------------*/
/** @defgroup USART_LL_Exported_Constants USART Exported Constants
* @{
*/
/** @defgroup USART_LL_EC_GET_FLAG Get Flags Defines
* @brief Flags defines which can be used with LL_USART_ReadReg function
* @{
*/
#define LL_USART_SR_PE USART_SR_PE /*!< Parity error flag */
#define LL_USART_SR_FE USART_SR_FE /*!< Framing error flag */
#define LL_USART_SR_NE USART_SR_NE /*!< Noise detected flag */
#define LL_USART_SR_ORE USART_SR_ORE /*!< Overrun error flag */
#define LL_USART_SR_IDLE USART_SR_IDLE /*!< Idle line detected flag */
#define LL_USART_SR_RXNE USART_SR_RXNE /*!< Read data register not empty flag */
#define LL_USART_SR_TC USART_SR_TC /*!< Transmission complete flag */
#define LL_USART_SR_TXE USART_SR_TXE /*!< Transmit data register empty flag */
#define LL_USART_SR_LBD USART_SR_LBD /*!< LIN break detection flag */
#define LL_USART_SR_CTS USART_SR_CTS /*!< CTS flag */
/**
* @}
*/
/** @defgroup USART_LL_EC_IT IT Defines
* @brief IT defines which can be used with LL_USART_ReadReg and LL_USART_WriteReg functions
* @{
*/
#define LL_USART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */
#define LL_USART_CR1_RXNEIE USART_CR1_RXNEIE /*!< Read data register not empty interrupt enable */
#define LL_USART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */
#define LL_USART_CR1_TXEIE USART_CR1_TXEIE /*!< Transmit data register empty interrupt enable */
#define LL_USART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */
#define LL_USART_CR2_LBDIE USART_CR2_LBDIE /*!< LIN break detection interrupt enable */
#define LL_USART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */
#define LL_USART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */
/**
* @}
*/
/** @defgroup USART_LL_EC_DIRECTION Communication Direction
* @{
*/
#define LL_USART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */
#define LL_USART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */
#define LL_USART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */
#define LL_USART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */
/**
* @}
*/
/** @defgroup USART_LL_EC_PARITY Parity Control
* @{
*/
#define LL_USART_PARITY_NONE 0x00000000U /*!< Parity control disabled */
#define LL_USART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */
#define LL_USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */
/**
* @}
*/
/** @defgroup USART_LL_EC_WAKEUP Wakeup
* @{
*/
#define LL_USART_WAKEUP_IDLELINE 0x00000000U /*!< USART wake up from Mute mode on Idle Line */
#define LL_USART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< USART wake up from Mute mode on Address Mark */
/**
* @}
*/
/** @defgroup USART_LL_EC_DATAWIDTH Datawidth
* @{
*/
#define LL_USART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */
#define LL_USART_DATAWIDTH_9B USART_CR1_M /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */
/**
* @}
*/
/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling
* @{
*/
#define LL_USART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */
#if defined(USART_CR1_OVER8)
#define LL_USART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */
#endif /* USART_OverSampling_Feature */
/**
* @}
*/
#if defined(USE_FULL_LL_DRIVER)
/** @defgroup USART_LL_EC_CLOCK Clock Signal
* @{
*/
#define LL_USART_CLOCK_DISABLE 0x00000000U /*!< Clock signal not provided */
#define LL_USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< Clock signal provided */
/**
* @}
*/
#endif /*USE_FULL_LL_DRIVER*/
/** @defgroup USART_LL_EC_LASTCLKPULSE Last Clock Pulse
* @{
*/
#define LL_USART_LASTCLKPULSE_NO_OUTPUT 0x00000000U /*!< The clock pulse of the last data bit is not output to the SCLK pin */
#define LL_USART_LASTCLKPULSE_OUTPUT USART_CR2_LBCL /*!< The clock pulse of the last data bit is output to the SCLK pin */
/**
* @}
*/
/** @defgroup USART_LL_EC_PHASE Clock Phase
* @{
*/
#define LL_USART_PHASE_1EDGE 0x00000000U /*!< The first clock transition is the first data capture edge */
#define LL_USART_PHASE_2EDGE USART_CR2_CPHA /*!< The second clock transition is the first data capture edge */
/**
* @}
*/
/** @defgroup USART_LL_EC_POLARITY Clock Polarity
* @{
*/
#define LL_USART_POLARITY_LOW 0x00000000U /*!< Steady low value on SCLK pin outside transmission window*/
#define LL_USART_POLARITY_HIGH USART_CR2_CPOL /*!< Steady high value on SCLK pin outside transmission window */
/**
* @}
*/
/** @defgroup USART_LL_EC_STOPBITS Stop Bits
* @{
*/
#define LL_USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< 0.5 stop bit */
#define LL_USART_STOPBITS_1 0x00000000U /*!< 1 stop bit */
#define LL_USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< 1.5 stop bits */
#define LL_USART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */
/**
* @}
*/
/** @defgroup USART_LL_EC_HWCONTROL Hardware Control
* @{
*/
#define LL_USART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */
#define LL_USART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested when there is space in the receive buffer */
#define LL_USART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted when the nCTS input is asserted (tied to 0) */
#define LL_USART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */
/**
* @}
*/
/** @defgroup USART_LL_EC_IRDA_POWER IrDA Power
* @{
*/
#define LL_USART_IRDA_POWER_NORMAL 0x00000000U /*!< IrDA normal power mode */
#define LL_USART_IRDA_POWER_LOW USART_CR3_IRLP /*!< IrDA low power mode */
/**
* @}
*/
/** @defgroup USART_LL_EC_LINBREAK_DETECT LIN Break Detection Length
* @{
*/
#define LL_USART_LINBREAK_DETECT_10B 0x00000000U /*!< 10-bit break detection method selected */
#define LL_USART_LINBREAK_DETECT_11B USART_CR2_LBDL /*!< 11-bit break detection method selected */
/**
* @}
*/
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/** @defgroup USART_LL_Exported_Macros USART Exported Macros
* @{
*/
/** @defgroup USART_LL_EM_WRITE_READ Common Write and read registers Macros
* @{
*/
/**
* @brief Write a value in USART register
* @param __INSTANCE__ USART Instance
* @param __REG__ Register to be written
* @param __VALUE__ Value to be written in the register
* @retval None
*/
#define LL_USART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
/**
* @brief Read a value in USART register
* @param __INSTANCE__ USART Instance
* @param __REG__ Register to be read
* @retval Register value
*/
#define LL_USART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
/**
* @}
*/
/** @defgroup USART_LL_EM_Exported_Macros_Helper Exported Macros Helper
* @{
*/
/**
* @brief Compute USARTDIV value according to Peripheral Clock and
* expected Baud Rate in 8 bits sampling mode (32 bits value of USARTDIV is returned)
* @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance
* @param __BAUDRATE__ Baud rate value to achieve
* @retval USARTDIV value to be used for BRR register filling in OverSampling_8 case
*/
#define __LL_USART_DIV_SAMPLING8_100(__PERIPHCLK__, __BAUDRATE__) (((__PERIPHCLK__)*25)/(2*(__BAUDRATE__)))
#define __LL_USART_DIVMANT_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (__LL_USART_DIV_SAMPLING8_100((__PERIPHCLK__), (__BAUDRATE__))/100)
#define __LL_USART_DIVFRAQ_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIV_SAMPLING8_100((__PERIPHCLK__), (__BAUDRATE__)) - (__LL_USART_DIVMANT_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) * 100)) * 8\
+ 50) / 100)
/* UART BRR = mantissa + overflow + fraction
= (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07) */
#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIVMANT_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) << 4) + \
((__LL_USART_DIVFRAQ_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) & 0xF8) << 1)) + \
(__LL_USART_DIVFRAQ_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) & 0x07))
/**
* @brief Compute USARTDIV value according to Peripheral Clock and
* expected Baud Rate in 16 bits sampling mode (32 bits value of USARTDIV is returned)
* @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance
* @param __BAUDRATE__ Baud rate value to achieve
* @retval USARTDIV value to be used for BRR register filling in OverSampling_16 case
*/
#define __LL_USART_DIV_SAMPLING16_100(__PERIPHCLK__, __BAUDRATE__) (((__PERIPHCLK__)*25)/(4*(__BAUDRATE__)))
#define __LL_USART_DIVMANT_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (__LL_USART_DIV_SAMPLING16_100((__PERIPHCLK__), (__BAUDRATE__))/100)
#define __LL_USART_DIVFRAQ_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) ((((__LL_USART_DIV_SAMPLING16_100((__PERIPHCLK__), (__BAUDRATE__)) - (__LL_USART_DIVMANT_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) * 100)) * 16)\
+ 50) / 100)
/* USART BRR = mantissa + overflow + fraction
= (USART DIVMANT << 4) + (USART DIVFRAQ & 0xF0) + (USART DIVFRAQ & 0x0F) */
#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIVMANT_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) << 4) + \
(__LL_USART_DIVFRAQ_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) & 0xF0)) + \
(__LL_USART_DIVFRAQ_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) & 0x0F))
/**
* @}
*/
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup USART_LL_Exported_Functions USART Exported Functions
* @{
*/
/** @defgroup USART_LL_EF_Configuration Configuration functions
* @{
*/
/**
* @brief USART Enable
* @rmtoll CR1 UE LL_USART_Enable
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR1, USART_CR1_UE);
}
/**
* @brief USART Disable (all USART prescalers and outputs are disabled)
* @note When USART is disabled, USART prescalers and outputs are stopped immediately,
* and current operations are discarded. The configuration of the USART is kept, but all the status
* flags, in the USARTx_SR are set to their default values.
* @rmtoll CR1 UE LL_USART_Disable
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR1, USART_CR1_UE);
}
/**
* @brief Indicate if USART is enabled
* @rmtoll CR1 UE LL_USART_IsEnabled
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabled(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_UE) == (USART_CR1_UE));
}
/**
* @brief Receiver Enable (Receiver is enabled and begins searching for a start bit)
* @rmtoll CR1 RE LL_USART_EnableDirectionRx
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableDirectionRx(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RE);
}
/**
* @brief Receiver Disable
* @rmtoll CR1 RE LL_USART_DisableDirectionRx
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableDirectionRx(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RE);
}
/**
* @brief Transmitter Enable
* @rmtoll CR1 TE LL_USART_EnableDirectionTx
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TE);
}
/**
* @brief Transmitter Disable
* @rmtoll CR1 TE LL_USART_DisableDirectionTx
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TE);
}
/**
* @brief Configure simultaneously enabled/disabled states
* of Transmitter and Receiver
* @rmtoll CR1 RE LL_USART_SetTransferDirection\n
* CR1 TE LL_USART_SetTransferDirection
* @param USARTx USART Instance
* @param TransferDirection This parameter can be one of the following values:
* @arg @ref LL_USART_DIRECTION_NONE
* @arg @ref LL_USART_DIRECTION_RX
* @arg @ref LL_USART_DIRECTION_TX
* @arg @ref LL_USART_DIRECTION_TX_RX
* @retval None
*/
__STATIC_INLINE void LL_USART_SetTransferDirection(USART_TypeDef *USARTx, uint32_t TransferDirection)
{
ATOMIC_MODIFY_REG(USARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection);
}
/**
* @brief Return enabled/disabled states of Transmitter and Receiver
* @rmtoll CR1 RE LL_USART_GetTransferDirection\n
* CR1 TE LL_USART_GetTransferDirection
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_DIRECTION_NONE
* @arg @ref LL_USART_DIRECTION_RX
* @arg @ref LL_USART_DIRECTION_TX
* @arg @ref LL_USART_DIRECTION_TX_RX
*/
__STATIC_INLINE uint32_t LL_USART_GetTransferDirection(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_RE | USART_CR1_TE));
}
/**
* @brief Configure Parity (enabled/disabled and parity mode if enabled).
* @note This function selects if hardware parity control (generation and detection) is enabled or disabled.
* When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position
* (9th or 8th bit depending on data width) and parity is checked on the received data.
* @rmtoll CR1 PS LL_USART_SetParity\n
* CR1 PCE LL_USART_SetParity
* @param USARTx USART Instance
* @param Parity This parameter can be one of the following values:
* @arg @ref LL_USART_PARITY_NONE
* @arg @ref LL_USART_PARITY_EVEN
* @arg @ref LL_USART_PARITY_ODD
* @retval None
*/
__STATIC_INLINE void LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity)
{
MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity);
}
/**
* @brief Return Parity configuration (enabled/disabled and parity mode if enabled)
* @rmtoll CR1 PS LL_USART_GetParity\n
* CR1 PCE LL_USART_GetParity
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_PARITY_NONE
* @arg @ref LL_USART_PARITY_EVEN
* @arg @ref LL_USART_PARITY_ODD
*/
__STATIC_INLINE uint32_t LL_USART_GetParity(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE));
}
/**
* @brief Set Receiver Wake Up method from Mute mode.
* @rmtoll CR1 WAKE LL_USART_SetWakeUpMethod
* @param USARTx USART Instance
* @param Method This parameter can be one of the following values:
* @arg @ref LL_USART_WAKEUP_IDLELINE
* @arg @ref LL_USART_WAKEUP_ADDRESSMARK
* @retval None
*/
__STATIC_INLINE void LL_USART_SetWakeUpMethod(USART_TypeDef *USARTx, uint32_t Method)
{
MODIFY_REG(USARTx->CR1, USART_CR1_WAKE, Method);
}
/**
* @brief Return Receiver Wake Up method from Mute mode
* @rmtoll CR1 WAKE LL_USART_GetWakeUpMethod
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_WAKEUP_IDLELINE
* @arg @ref LL_USART_WAKEUP_ADDRESSMARK
*/
__STATIC_INLINE uint32_t LL_USART_GetWakeUpMethod(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_WAKE));
}
/**
* @brief Set Word length (i.e. nb of data bits, excluding start and stop bits)
* @rmtoll CR1 M LL_USART_SetDataWidth
* @param USARTx USART Instance
* @param DataWidth This parameter can be one of the following values:
* @arg @ref LL_USART_DATAWIDTH_8B
* @arg @ref LL_USART_DATAWIDTH_9B
* @retval None
*/
__STATIC_INLINE void LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth)
{
MODIFY_REG(USARTx->CR1, USART_CR1_M, DataWidth);
}
/**
* @brief Return Word length (i.e. nb of data bits, excluding start and stop bits)
* @rmtoll CR1 M LL_USART_GetDataWidth
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_DATAWIDTH_8B
* @arg @ref LL_USART_DATAWIDTH_9B
*/
__STATIC_INLINE uint32_t LL_USART_GetDataWidth(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_M));
}
#if defined(USART_CR1_OVER8)
/**
* @brief Set Oversampling to 8-bit or 16-bit mode
* @rmtoll CR1 OVER8 LL_USART_SetOverSampling
* @param USARTx USART Instance
* @param OverSampling This parameter can be one of the following values:
* @arg @ref LL_USART_OVERSAMPLING_16
* @arg @ref LL_USART_OVERSAMPLING_8
* @retval None
*/
__STATIC_INLINE void LL_USART_SetOverSampling(USART_TypeDef *USARTx, uint32_t OverSampling)
{
MODIFY_REG(USARTx->CR1, USART_CR1_OVER8, OverSampling);
}
/**
* @brief Return Oversampling mode
* @rmtoll CR1 OVER8 LL_USART_GetOverSampling
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_OVERSAMPLING_16
* @arg @ref LL_USART_OVERSAMPLING_8
*/
__STATIC_INLINE uint32_t LL_USART_GetOverSampling(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_OVER8));
}
#endif /* USART_OverSampling_Feature */
/**
* @brief Configure if Clock pulse of the last data bit is output to the SCLK pin or not
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 LBCL LL_USART_SetLastClkPulseOutput
* @param USARTx USART Instance
* @param LastBitClockPulse This parameter can be one of the following values:
* @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
* @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
* @retval None
*/
__STATIC_INLINE void LL_USART_SetLastClkPulseOutput(USART_TypeDef *USARTx, uint32_t LastBitClockPulse)
{
MODIFY_REG(USARTx->CR2, USART_CR2_LBCL, LastBitClockPulse);
}
/**
* @brief Retrieve Clock pulse of the last data bit output configuration
* (Last bit Clock pulse output to the SCLK pin or not)
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 LBCL LL_USART_GetLastClkPulseOutput
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
* @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
*/
__STATIC_INLINE uint32_t LL_USART_GetLastClkPulseOutput(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBCL));
}
/**
* @brief Select the phase of the clock output on the SCLK pin in synchronous mode
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CPHA LL_USART_SetClockPhase
* @param USARTx USART Instance
* @param ClockPhase This parameter can be one of the following values:
* @arg @ref LL_USART_PHASE_1EDGE
* @arg @ref LL_USART_PHASE_2EDGE
* @retval None
*/
__STATIC_INLINE void LL_USART_SetClockPhase(USART_TypeDef *USARTx, uint32_t ClockPhase)
{
MODIFY_REG(USARTx->CR2, USART_CR2_CPHA, ClockPhase);
}
/**
* @brief Return phase of the clock output on the SCLK pin in synchronous mode
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CPHA LL_USART_GetClockPhase
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_PHASE_1EDGE
* @arg @ref LL_USART_PHASE_2EDGE
*/
__STATIC_INLINE uint32_t LL_USART_GetClockPhase(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPHA));
}
/**
* @brief Select the polarity of the clock output on the SCLK pin in synchronous mode
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CPOL LL_USART_SetClockPolarity
* @param USARTx USART Instance
* @param ClockPolarity This parameter can be one of the following values:
* @arg @ref LL_USART_POLARITY_LOW
* @arg @ref LL_USART_POLARITY_HIGH
* @retval None
*/
__STATIC_INLINE void LL_USART_SetClockPolarity(USART_TypeDef *USARTx, uint32_t ClockPolarity)
{
MODIFY_REG(USARTx->CR2, USART_CR2_CPOL, ClockPolarity);
}
/**
* @brief Return polarity of the clock output on the SCLK pin in synchronous mode
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CPOL LL_USART_GetClockPolarity
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_POLARITY_LOW
* @arg @ref LL_USART_POLARITY_HIGH
*/
__STATIC_INLINE uint32_t LL_USART_GetClockPolarity(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPOL));
}
/**
* @brief Configure Clock signal format (Phase Polarity and choice about output of last bit clock pulse)
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @note Call of this function is equivalent to following function call sequence :
* - Clock Phase configuration using @ref LL_USART_SetClockPhase() function
* - Clock Polarity configuration using @ref LL_USART_SetClockPolarity() function
* - Output of Last bit Clock pulse configuration using @ref LL_USART_SetLastClkPulseOutput() function
* @rmtoll CR2 CPHA LL_USART_ConfigClock\n
* CR2 CPOL LL_USART_ConfigClock\n
* CR2 LBCL LL_USART_ConfigClock
* @param USARTx USART Instance
* @param Phase This parameter can be one of the following values:
* @arg @ref LL_USART_PHASE_1EDGE
* @arg @ref LL_USART_PHASE_2EDGE
* @param Polarity This parameter can be one of the following values:
* @arg @ref LL_USART_POLARITY_LOW
* @arg @ref LL_USART_POLARITY_HIGH
* @param LBCPOutput This parameter can be one of the following values:
* @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
* @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigClock(USART_TypeDef *USARTx, uint32_t Phase, uint32_t Polarity, uint32_t LBCPOutput)
{
MODIFY_REG(USARTx->CR2, USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, Phase | Polarity | LBCPOutput);
}
/**
* @brief Enable Clock output on SCLK pin
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CLKEN LL_USART_EnableSCLKOutput
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableSCLKOutput(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR2, USART_CR2_CLKEN);
}
/**
* @brief Disable Clock output on SCLK pin
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CLKEN LL_USART_DisableSCLKOutput
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableSCLKOutput(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN);
}
/**
* @brief Indicate if Clock output on SCLK pin is enabled
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @rmtoll CR2 CLKEN LL_USART_IsEnabledSCLKOutput
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledSCLKOutput(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR2, USART_CR2_CLKEN) == (USART_CR2_CLKEN));
}
/**
* @brief Set the length of the stop bits
* @rmtoll CR2 STOP LL_USART_SetStopBitsLength
* @param USARTx USART Instance
* @param StopBits This parameter can be one of the following values:
* @arg @ref LL_USART_STOPBITS_0_5
* @arg @ref LL_USART_STOPBITS_1
* @arg @ref LL_USART_STOPBITS_1_5
* @arg @ref LL_USART_STOPBITS_2
* @retval None
*/
__STATIC_INLINE void LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, uint32_t StopBits)
{
MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits);
}
/**
* @brief Retrieve the length of the stop bits
* @rmtoll CR2 STOP LL_USART_GetStopBitsLength
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_STOPBITS_0_5
* @arg @ref LL_USART_STOPBITS_1
* @arg @ref LL_USART_STOPBITS_1_5
* @arg @ref LL_USART_STOPBITS_2
*/
__STATIC_INLINE uint32_t LL_USART_GetStopBitsLength(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_STOP));
}
/**
* @brief Configure Character frame format (Datawidth, Parity control, Stop Bits)
* @note Call of this function is equivalent to following function call sequence :
* - Data Width configuration using @ref LL_USART_SetDataWidth() function
* - Parity Control and mode configuration using @ref LL_USART_SetParity() function
* - Stop bits configuration using @ref LL_USART_SetStopBitsLength() function
* @rmtoll CR1 PS LL_USART_ConfigCharacter\n
* CR1 PCE LL_USART_ConfigCharacter\n
* CR1 M LL_USART_ConfigCharacter\n
* CR2 STOP LL_USART_ConfigCharacter
* @param USARTx USART Instance
* @param DataWidth This parameter can be one of the following values:
* @arg @ref LL_USART_DATAWIDTH_8B
* @arg @ref LL_USART_DATAWIDTH_9B
* @param Parity This parameter can be one of the following values:
* @arg @ref LL_USART_PARITY_NONE
* @arg @ref LL_USART_PARITY_EVEN
* @arg @ref LL_USART_PARITY_ODD
* @param StopBits This parameter can be one of the following values:
* @arg @ref LL_USART_STOPBITS_0_5
* @arg @ref LL_USART_STOPBITS_1
* @arg @ref LL_USART_STOPBITS_1_5
* @arg @ref LL_USART_STOPBITS_2
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigCharacter(USART_TypeDef *USARTx, uint32_t DataWidth, uint32_t Parity,
uint32_t StopBits)
{
MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth);
MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits);
}
/**
* @brief Set Address of the USART node.
* @note This is used in multiprocessor communication during Mute mode or Stop mode,
* for wake up with address mark detection.
* @rmtoll CR2 ADD LL_USART_SetNodeAddress
* @param USARTx USART Instance
* @param NodeAddress 4 bit Address of the USART node.
* @retval None
*/
__STATIC_INLINE void LL_USART_SetNodeAddress(USART_TypeDef *USARTx, uint32_t NodeAddress)
{
MODIFY_REG(USARTx->CR2, USART_CR2_ADD, (NodeAddress & USART_CR2_ADD));
}
/**
* @brief Return 4 bit Address of the USART node as set in ADD field of CR2.
* @note only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant)
* @rmtoll CR2 ADD LL_USART_GetNodeAddress
* @param USARTx USART Instance
* @retval Address of the USART node (Value between Min_Data=0 and Max_Data=255)
*/
__STATIC_INLINE uint32_t LL_USART_GetNodeAddress(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADD));
}
/**
* @brief Enable RTS HW Flow Control
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 RTSE LL_USART_EnableRTSHWFlowCtrl
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableRTSHWFlowCtrl(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_RTSE);
}
/**
* @brief Disable RTS HW Flow Control
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 RTSE LL_USART_DisableRTSHWFlowCtrl
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableRTSHWFlowCtrl(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_RTSE);
}
/**
* @brief Enable CTS HW Flow Control
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 CTSE LL_USART_EnableCTSHWFlowCtrl
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableCTSHWFlowCtrl(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_CTSE);
}
/**
* @brief Disable CTS HW Flow Control
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 CTSE LL_USART_DisableCTSHWFlowCtrl
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableCTSHWFlowCtrl(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_CTSE);
}
/**
* @brief Configure HW Flow Control mode (both CTS and RTS)
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 RTSE LL_USART_SetHWFlowCtrl\n
* CR3 CTSE LL_USART_SetHWFlowCtrl
* @param USARTx USART Instance
* @param HardwareFlowControl This parameter can be one of the following values:
* @arg @ref LL_USART_HWCONTROL_NONE
* @arg @ref LL_USART_HWCONTROL_RTS
* @arg @ref LL_USART_HWCONTROL_CTS
* @arg @ref LL_USART_HWCONTROL_RTS_CTS
* @retval None
*/
__STATIC_INLINE void LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, uint32_t HardwareFlowControl)
{
MODIFY_REG(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl);
}
/**
* @brief Return HW Flow Control configuration (both CTS and RTS)
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 RTSE LL_USART_GetHWFlowCtrl\n
* CR3 CTSE LL_USART_GetHWFlowCtrl
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_HWCONTROL_NONE
* @arg @ref LL_USART_HWCONTROL_RTS
* @arg @ref LL_USART_HWCONTROL_CTS
* @arg @ref LL_USART_HWCONTROL_RTS_CTS
*/
__STATIC_INLINE uint32_t LL_USART_GetHWFlowCtrl(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE));
}
#if defined(USART_CR3_ONEBIT)
/**
* @brief Enable One bit sampling method
* @rmtoll CR3 ONEBIT LL_USART_EnableOneBitSamp
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableOneBitSamp(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_ONEBIT);
}
/**
* @brief Disable One bit sampling method
* @rmtoll CR3 ONEBIT LL_USART_DisableOneBitSamp
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableOneBitSamp(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_ONEBIT);
}
/**
* @brief Indicate if One bit sampling method is enabled
* @rmtoll CR3 ONEBIT LL_USART_IsEnabledOneBitSamp
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledOneBitSamp(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_ONEBIT) == (USART_CR3_ONEBIT));
}
#endif /* USART_OneBitSampling_Feature */
#if defined(USART_CR1_OVER8)
/**
* @brief Configure USART BRR register for achieving expected Baud Rate value.
* @note Compute and set USARTDIV value in BRR Register (full BRR content)
* according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values
* @note Peripheral clock and Baud rate values provided as function parameters should be valid
* (Baud rate value != 0)
* @rmtoll BRR BRR LL_USART_SetBaudRate
* @param USARTx USART Instance
* @param PeriphClk Peripheral Clock
* @param OverSampling This parameter can be one of the following values:
* @arg @ref LL_USART_OVERSAMPLING_16
* @arg @ref LL_USART_OVERSAMPLING_8
* @param BaudRate Baud Rate
* @retval None
*/
__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling,
uint32_t BaudRate)
{
if (OverSampling == LL_USART_OVERSAMPLING_8)
{
USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, BaudRate));
}
else
{
USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate));
}
}
/**
* @brief Return current Baud Rate value, according to USARTDIV present in BRR register
* (full BRR content), and to used Peripheral Clock and Oversampling mode values
* @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned.
* @rmtoll BRR BRR LL_USART_GetBaudRate
* @param USARTx USART Instance
* @param PeriphClk Peripheral Clock
* @param OverSampling This parameter can be one of the following values:
* @arg @ref LL_USART_OVERSAMPLING_16
* @arg @ref LL_USART_OVERSAMPLING_8
* @retval Baud Rate
*/
__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling)
{
uint32_t usartdiv = 0x0U;
uint32_t brrresult = 0x0U;
usartdiv = USARTx->BRR;
if (OverSampling == LL_USART_OVERSAMPLING_8)
{
if ((usartdiv & 0xFFF7U) != 0U)
{
usartdiv = (uint16_t)((usartdiv & 0xFFF0U) | ((usartdiv & 0x0007U) << 1U)) ;
brrresult = (PeriphClk * 2U) / usartdiv;
}
}
else
{
if ((usartdiv & 0xFFFFU) != 0U)
{
brrresult = PeriphClk / usartdiv;
}
}
return (brrresult);
}
#else
/**
* @brief Configure USART BRR register for achieving expected Baud Rate value.
* @note Compute and set USARTDIV value in BRR Register (full BRR content)
* according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values
* @note Peripheral clock and Baud rate values provided as function parameters should be valid
* (Baud rate value != 0)
* @rmtoll BRR BRR LL_USART_SetBaudRate
* @param USARTx USART Instance
* @param PeriphClk Peripheral Clock
* @param BaudRate Baud Rate
* @retval None
*/
__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t BaudRate)
{
USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate));
}
/**
* @brief Return current Baud Rate value, according to USARTDIV present in BRR register
* (full BRR content), and to used Peripheral Clock and Oversampling mode values
* @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned.
* @rmtoll BRR BRR LL_USART_GetBaudRate
* @param USARTx USART Instance
* @param PeriphClk Peripheral Clock
* @retval Baud Rate
*/
__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk)
{
uint32_t usartdiv = 0x0U;
uint32_t brrresult = 0x0U;
usartdiv = USARTx->BRR;
if ((usartdiv & 0xFFFFU) != 0U)
{
brrresult = PeriphClk / usartdiv;
}
return (brrresult);
}
#endif /* USART_OverSampling_Feature */
/**
* @}
*/
/** @defgroup USART_LL_EF_Configuration_IRDA Configuration functions related to Irda feature
* @{
*/
/**
* @brief Enable IrDA mode
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll CR3 IREN LL_USART_EnableIrda
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIrda(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_IREN);
}
/**
* @brief Disable IrDA mode
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll CR3 IREN LL_USART_DisableIrda
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIrda(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_IREN);
}
/**
* @brief Indicate if IrDA mode is enabled
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll CR3 IREN LL_USART_IsEnabledIrda
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIrda(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_IREN) == (USART_CR3_IREN));
}
/**
* @brief Configure IrDA Power Mode (Normal or Low Power)
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll CR3 IRLP LL_USART_SetIrdaPowerMode
* @param USARTx USART Instance
* @param PowerMode This parameter can be one of the following values:
* @arg @ref LL_USART_IRDA_POWER_NORMAL
* @arg @ref LL_USART_IRDA_POWER_LOW
* @retval None
*/
__STATIC_INLINE void LL_USART_SetIrdaPowerMode(USART_TypeDef *USARTx, uint32_t PowerMode)
{
MODIFY_REG(USARTx->CR3, USART_CR3_IRLP, PowerMode);
}
/**
* @brief Retrieve IrDA Power Mode configuration (Normal or Low Power)
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll CR3 IRLP LL_USART_GetIrdaPowerMode
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_IRDA_POWER_NORMAL
* @arg @ref LL_USART_PHASE_2EDGE
*/
__STATIC_INLINE uint32_t LL_USART_GetIrdaPowerMode(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_IRLP));
}
/**
* @brief Set Irda prescaler value, used for dividing the USART clock source
* to achieve the Irda Low Power frequency (8 bits value)
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll GTPR PSC LL_USART_SetIrdaPrescaler
* @param USARTx USART Instance
* @param PrescalerValue Value between Min_Data=0x00 and Max_Data=0xFF
* @retval None
*/
__STATIC_INLINE void LL_USART_SetIrdaPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue)
{
MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, PrescalerValue);
}
/**
* @brief Return Irda prescaler value, used for dividing the USART clock source
* to achieve the Irda Low Power frequency (8 bits value)
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @rmtoll GTPR PSC LL_USART_GetIrdaPrescaler
* @param USARTx USART Instance
* @retval Irda prescaler value (Value between Min_Data=0x00 and Max_Data=0xFF)
*/
__STATIC_INLINE uint32_t LL_USART_GetIrdaPrescaler(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_Configuration_Smartcard Configuration functions related to Smartcard feature
* @{
*/
/**
* @brief Enable Smartcard NACK transmission
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll CR3 NACK LL_USART_EnableSmartcardNACK
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableSmartcardNACK(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_NACK);
}
/**
* @brief Disable Smartcard NACK transmission
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll CR3 NACK LL_USART_DisableSmartcardNACK
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableSmartcardNACK(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_NACK);
}
/**
* @brief Indicate if Smartcard NACK transmission is enabled
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll CR3 NACK LL_USART_IsEnabledSmartcardNACK
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcardNACK(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_NACK) == (USART_CR3_NACK));
}
/**
* @brief Enable Smartcard mode
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll CR3 SCEN LL_USART_EnableSmartcard
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableSmartcard(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_SCEN);
}
/**
* @brief Disable Smartcard mode
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll CR3 SCEN LL_USART_DisableSmartcard
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableSmartcard(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_SCEN);
}
/**
* @brief Indicate if Smartcard mode is enabled
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll CR3 SCEN LL_USART_IsEnabledSmartcard
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcard(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_SCEN) == (USART_CR3_SCEN));
}
/**
* @brief Set Smartcard prescaler value, used for dividing the USART clock
* source to provide the SMARTCARD Clock (5 bits value)
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll GTPR PSC LL_USART_SetSmartcardPrescaler
* @param USARTx USART Instance
* @param PrescalerValue Value between Min_Data=0 and Max_Data=31
* @retval None
*/
__STATIC_INLINE void LL_USART_SetSmartcardPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue)
{
MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, PrescalerValue);
}
/**
* @brief Return Smartcard prescaler value, used for dividing the USART clock
* source to provide the SMARTCARD Clock (5 bits value)
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll GTPR PSC LL_USART_GetSmartcardPrescaler
* @param USARTx USART Instance
* @retval Smartcard prescaler value (Value between Min_Data=0 and Max_Data=31)
*/
__STATIC_INLINE uint32_t LL_USART_GetSmartcardPrescaler(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC));
}
/**
* @brief Set Smartcard Guard time value, expressed in nb of baud clocks periods
* (GT[7:0] bits : Guard time value)
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll GTPR GT LL_USART_SetSmartcardGuardTime
* @param USARTx USART Instance
* @param GuardTime Value between Min_Data=0x00 and Max_Data=0xFF
* @retval None
*/
__STATIC_INLINE void LL_USART_SetSmartcardGuardTime(USART_TypeDef *USARTx, uint32_t GuardTime)
{
MODIFY_REG(USARTx->GTPR, USART_GTPR_GT, GuardTime << USART_POSITION_GTPR_GT);
}
/**
* @brief Return Smartcard Guard time value, expressed in nb of baud clocks periods
* (GT[7:0] bits : Guard time value)
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @rmtoll GTPR GT LL_USART_GetSmartcardGuardTime
* @param USARTx USART Instance
* @retval Smartcard Guard time value (Value between Min_Data=0x00 and Max_Data=0xFF)
*/
__STATIC_INLINE uint32_t LL_USART_GetSmartcardGuardTime(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_GT) >> USART_POSITION_GTPR_GT);
}
/**
* @}
*/
/** @defgroup USART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature
* @{
*/
/**
* @brief Enable Single Wire Half-Duplex mode
* @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
* Half-Duplex mode is supported by the USARTx instance.
* @rmtoll CR3 HDSEL LL_USART_EnableHalfDuplex
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableHalfDuplex(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR3, USART_CR3_HDSEL);
}
/**
* @brief Disable Single Wire Half-Duplex mode
* @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
* Half-Duplex mode is supported by the USARTx instance.
* @rmtoll CR3 HDSEL LL_USART_DisableHalfDuplex
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableHalfDuplex(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL);
}
/**
* @brief Indicate if Single Wire Half-Duplex mode is enabled
* @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
* Half-Duplex mode is supported by the USARTx instance.
* @rmtoll CR3 HDSEL LL_USART_IsEnabledHalfDuplex
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledHalfDuplex(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_Configuration_LIN Configuration functions related to LIN feature
* @{
*/
/**
* @brief Set LIN Break Detection Length
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LBDL LL_USART_SetLINBrkDetectionLen
* @param USARTx USART Instance
* @param LINBDLength This parameter can be one of the following values:
* @arg @ref LL_USART_LINBREAK_DETECT_10B
* @arg @ref LL_USART_LINBREAK_DETECT_11B
* @retval None
*/
__STATIC_INLINE void LL_USART_SetLINBrkDetectionLen(USART_TypeDef *USARTx, uint32_t LINBDLength)
{
MODIFY_REG(USARTx->CR2, USART_CR2_LBDL, LINBDLength);
}
/**
* @brief Return LIN Break Detection Length
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LBDL LL_USART_GetLINBrkDetectionLen
* @param USARTx USART Instance
* @retval Returned value can be one of the following values:
* @arg @ref LL_USART_LINBREAK_DETECT_10B
* @arg @ref LL_USART_LINBREAK_DETECT_11B
*/
__STATIC_INLINE uint32_t LL_USART_GetLINBrkDetectionLen(const USART_TypeDef *USARTx)
{
return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBDL));
}
/**
* @brief Enable LIN mode
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LINEN LL_USART_EnableLIN
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableLIN(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR2, USART_CR2_LINEN);
}
/**
* @brief Disable LIN mode
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LINEN LL_USART_DisableLIN
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableLIN(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR2, USART_CR2_LINEN);
}
/**
* @brief Indicate if LIN mode is enabled
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LINEN LL_USART_IsEnabledLIN
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledLIN(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR2, USART_CR2_LINEN) == (USART_CR2_LINEN));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_AdvancedConfiguration Advanced Configurations services
* @{
*/
/**
* @brief Perform basic configuration of USART for enabling use in Asynchronous Mode (UART)
* @note In UART mode, the following bits must be kept cleared:
* - LINEN bit in the USART_CR2 register,
* - CLKEN bit in the USART_CR2 register,
* - SCEN bit in the USART_CR3 register,
* - IREN bit in the USART_CR3 register,
* - HDSEL bit in the USART_CR3 register.
* @note Call of this function is equivalent to following function call sequence :
* - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
* - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
* - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
* - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
* - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
* @note Other remaining configurations items related to Asynchronous Mode
* (as Baud Rate, Word length, Parity, ...) should be set using
* dedicated functions
* @rmtoll CR2 LINEN LL_USART_ConfigAsyncMode\n
* CR2 CLKEN LL_USART_ConfigAsyncMode\n
* CR3 SCEN LL_USART_ConfigAsyncMode\n
* CR3 IREN LL_USART_ConfigAsyncMode\n
* CR3 HDSEL LL_USART_ConfigAsyncMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigAsyncMode(USART_TypeDef *USARTx)
{
/* In Asynchronous mode, the following bits must be kept cleared:
- LINEN, CLKEN bits in the USART_CR2 register,
- SCEN, IREN and HDSEL bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL));
}
/**
* @brief Perform basic configuration of USART for enabling use in Synchronous Mode
* @note In Synchronous mode, the following bits must be kept cleared:
* - LINEN bit in the USART_CR2 register,
* - SCEN bit in the USART_CR3 register,
* - IREN bit in the USART_CR3 register,
* - HDSEL bit in the USART_CR3 register.
* This function also sets the USART in Synchronous mode.
* @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not
* Synchronous mode is supported by the USARTx instance.
* @note Call of this function is equivalent to following function call sequence :
* - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
* - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
* - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
* - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
* - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function
* @note Other remaining configurations items related to Synchronous Mode
* (as Baud Rate, Word length, Parity, Clock Polarity, ...) should be set using
* dedicated functions
* @rmtoll CR2 LINEN LL_USART_ConfigSyncMode\n
* CR2 CLKEN LL_USART_ConfigSyncMode\n
* CR3 SCEN LL_USART_ConfigSyncMode\n
* CR3 IREN LL_USART_ConfigSyncMode\n
* CR3 HDSEL LL_USART_ConfigSyncMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigSyncMode(USART_TypeDef *USARTx)
{
/* In Synchronous mode, the following bits must be kept cleared:
- LINEN bit in the USART_CR2 register,
- SCEN, IREN and HDSEL bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN));
CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL));
/* set the UART/USART in Synchronous mode */
SET_BIT(USARTx->CR2, USART_CR2_CLKEN);
}
/**
* @brief Perform basic configuration of USART for enabling use in LIN Mode
* @note In LIN mode, the following bits must be kept cleared:
* - STOP and CLKEN bits in the USART_CR2 register,
* - SCEN bit in the USART_CR3 register,
* - IREN bit in the USART_CR3 register,
* - HDSEL bit in the USART_CR3 register.
* This function also set the UART/USART in LIN mode.
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @note Call of this function is equivalent to following function call sequence :
* - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
* - Clear STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
* - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
* - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
* - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
* - Set LINEN in CR2 using @ref LL_USART_EnableLIN() function
* @note Other remaining configurations items related to LIN Mode
* (as Baud Rate, Word length, LIN Break Detection Length, ...) should be set using
* dedicated functions
* @rmtoll CR2 CLKEN LL_USART_ConfigLINMode\n
* CR2 STOP LL_USART_ConfigLINMode\n
* CR2 LINEN LL_USART_ConfigLINMode\n
* CR3 IREN LL_USART_ConfigLINMode\n
* CR3 SCEN LL_USART_ConfigLINMode\n
* CR3 HDSEL LL_USART_ConfigLINMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigLINMode(USART_TypeDef *USARTx)
{
/* In LIN mode, the following bits must be kept cleared:
- STOP and CLKEN bits in the USART_CR2 register,
- IREN, SCEN and HDSEL bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP));
CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL));
/* Set the UART/USART in LIN mode */
SET_BIT(USARTx->CR2, USART_CR2_LINEN);
}
/**
* @brief Perform basic configuration of USART for enabling use in Half Duplex Mode
* @note In Half Duplex mode, the following bits must be kept cleared:
* - LINEN bit in the USART_CR2 register,
* - CLKEN bit in the USART_CR2 register,
* - SCEN bit in the USART_CR3 register,
* - IREN bit in the USART_CR3 register,
* This function also sets the UART/USART in Half Duplex mode.
* @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
* Half-Duplex mode is supported by the USARTx instance.
* @note Call of this function is equivalent to following function call sequence :
* - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
* - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
* - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
* - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
* - Set HDSEL in CR3 using @ref LL_USART_EnableHalfDuplex() function
* @note Other remaining configurations items related to Half Duplex Mode
* (as Baud Rate, Word length, Parity, ...) should be set using
* dedicated functions
* @rmtoll CR2 LINEN LL_USART_ConfigHalfDuplexMode\n
* CR2 CLKEN LL_USART_ConfigHalfDuplexMode\n
* CR3 HDSEL LL_USART_ConfigHalfDuplexMode\n
* CR3 SCEN LL_USART_ConfigHalfDuplexMode\n
* CR3 IREN LL_USART_ConfigHalfDuplexMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigHalfDuplexMode(USART_TypeDef *USARTx)
{
/* In Half Duplex mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN and IREN bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN));
/* set the UART/USART in Half Duplex mode */
SET_BIT(USARTx->CR3, USART_CR3_HDSEL);
}
/**
* @brief Perform basic configuration of USART for enabling use in Smartcard Mode
* @note In Smartcard mode, the following bits must be kept cleared:
* - LINEN bit in the USART_CR2 register,
* - IREN bit in the USART_CR3 register,
* - HDSEL bit in the USART_CR3 register.
* This function also configures Stop bits to 1.5 bits and
* sets the USART in Smartcard mode (SCEN bit).
* Clock Output is also enabled (CLKEN).
* @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
* Smartcard feature is supported by the USARTx instance.
* @note Call of this function is equivalent to following function call sequence :
* - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
* - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
* - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
* - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
* - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function
* - Set SCEN in CR3 using @ref LL_USART_EnableSmartcard() function
* @note Other remaining configurations items related to Smartcard Mode
* (as Baud Rate, Word length, Parity, ...) should be set using
* dedicated functions
* @rmtoll CR2 LINEN LL_USART_ConfigSmartcardMode\n
* CR2 STOP LL_USART_ConfigSmartcardMode\n
* CR2 CLKEN LL_USART_ConfigSmartcardMode\n
* CR3 HDSEL LL_USART_ConfigSmartcardMode\n
* CR3 SCEN LL_USART_ConfigSmartcardMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigSmartcardMode(USART_TypeDef *USARTx)
{
/* In Smartcard mode, the following bits must be kept cleared:
- LINEN bit in the USART_CR2 register,
- IREN and HDSEL bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN));
CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
/* Configure Stop bits to 1.5 bits */
/* Synchronous mode is activated by default */
SET_BIT(USARTx->CR2, (USART_CR2_STOP_0 | USART_CR2_STOP_1 | USART_CR2_CLKEN));
/* set the UART/USART in Smartcard mode */
SET_BIT(USARTx->CR3, USART_CR3_SCEN);
}
/**
* @brief Perform basic configuration of USART for enabling use in Irda Mode
* @note In IRDA mode, the following bits must be kept cleared:
* - LINEN bit in the USART_CR2 register,
* - STOP and CLKEN bits in the USART_CR2 register,
* - SCEN bit in the USART_CR3 register,
* - HDSEL bit in the USART_CR3 register.
* This function also sets the UART/USART in IRDA mode (IREN bit).
* @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
* IrDA feature is supported by the USARTx instance.
* @note Call of this function is equivalent to following function call sequence :
* - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
* - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
* - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
* - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
* - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
* - Set IREN in CR3 using @ref LL_USART_EnableIrda() function
* @note Other remaining configurations items related to Irda Mode
* (as Baud Rate, Word length, Power mode, ...) should be set using
* dedicated functions
* @rmtoll CR2 LINEN LL_USART_ConfigIrdaMode\n
* CR2 CLKEN LL_USART_ConfigIrdaMode\n
* CR2 STOP LL_USART_ConfigIrdaMode\n
* CR3 SCEN LL_USART_ConfigIrdaMode\n
* CR3 HDSEL LL_USART_ConfigIrdaMode\n
* CR3 IREN LL_USART_ConfigIrdaMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigIrdaMode(USART_TypeDef *USARTx)
{
/* In IRDA mode, the following bits must be kept cleared:
- LINEN, STOP and CLKEN bits in the USART_CR2 register,
- SCEN and HDSEL bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP));
CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
/* set the UART/USART in IRDA mode */
SET_BIT(USARTx->CR3, USART_CR3_IREN);
}
/**
* @brief Perform basic configuration of USART for enabling use in Multi processor Mode
* (several USARTs connected in a network, one of the USARTs can be the master,
* its TX output connected to the RX inputs of the other slaves USARTs).
* @note In MultiProcessor mode, the following bits must be kept cleared:
* - LINEN bit in the USART_CR2 register,
* - CLKEN bit in the USART_CR2 register,
* - SCEN bit in the USART_CR3 register,
* - IREN bit in the USART_CR3 register,
* - HDSEL bit in the USART_CR3 register.
* @note Call of this function is equivalent to following function call sequence :
* - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
* - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
* - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
* - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
* - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
* @note Other remaining configurations items related to Multi processor Mode
* (as Baud Rate, Wake Up Method, Node address, ...) should be set using
* dedicated functions
* @rmtoll CR2 LINEN LL_USART_ConfigMultiProcessMode\n
* CR2 CLKEN LL_USART_ConfigMultiProcessMode\n
* CR3 SCEN LL_USART_ConfigMultiProcessMode\n
* CR3 HDSEL LL_USART_ConfigMultiProcessMode\n
* CR3 IREN LL_USART_ConfigMultiProcessMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ConfigMultiProcessMode(USART_TypeDef *USARTx)
{
/* In Multi Processor mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- IREN, SCEN and HDSEL bits in the USART_CR3 register.*/
CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_FLAG_Management FLAG_Management
* @{
*/
/**
* @brief Check if the USART Parity Error Flag is set or not
* @rmtoll SR PE LL_USART_IsActiveFlag_PE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_PE) == (USART_SR_PE));
}
/**
* @brief Check if the USART Framing Error Flag is set or not
* @rmtoll SR FE LL_USART_IsActiveFlag_FE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_FE) == (USART_SR_FE));
}
/**
* @brief Check if the USART Noise error detected Flag is set or not
* @rmtoll SR NF LL_USART_IsActiveFlag_NE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_NE) == (USART_SR_NE));
}
/**
* @brief Check if the USART OverRun Error Flag is set or not
* @rmtoll SR ORE LL_USART_IsActiveFlag_ORE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_ORE) == (USART_SR_ORE));
}
/**
* @brief Check if the USART IDLE line detected Flag is set or not
* @rmtoll SR IDLE LL_USART_IsActiveFlag_IDLE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_IDLE) == (USART_SR_IDLE));
}
/**
* @brief Check if the USART Read Data Register Not Empty Flag is set or not
* @rmtoll SR RXNE LL_USART_IsActiveFlag_RXNE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_RXNE) == (USART_SR_RXNE));
}
/**
* @brief Check if the USART Transmission Complete Flag is set or not
* @rmtoll SR TC LL_USART_IsActiveFlag_TC
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_TC) == (USART_SR_TC));
}
/**
* @brief Check if the USART Transmit Data Register Empty Flag is set or not
* @rmtoll SR TXE LL_USART_IsActiveFlag_TXE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_TXE) == (USART_SR_TXE));
}
/**
* @brief Check if the USART LIN Break Detection Flag is set or not
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll SR LBD LL_USART_IsActiveFlag_LBD
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_LBD(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_LBD) == (USART_SR_LBD));
}
/**
* @brief Check if the USART CTS Flag is set or not
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll SR CTS LL_USART_IsActiveFlag_nCTS
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_nCTS(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->SR, USART_SR_CTS) == (USART_SR_CTS));
}
/**
* @brief Check if the USART Send Break Flag is set or not
* @rmtoll CR1 SBK LL_USART_IsActiveFlag_SBK
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_SBK(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_SBK) == (USART_CR1_SBK));
}
/**
* @brief Check if the USART Receive Wake Up from mute mode Flag is set or not
* @rmtoll CR1 RWU LL_USART_IsActiveFlag_RWU
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RWU(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_RWU) == (USART_CR1_RWU));
}
/**
* @brief Clear Parity Error Flag
* @note Clearing this flag is done by a read access to the USARTx_SR
* register followed by a read access to the USARTx_DR register.
* @note Please also consider that when clearing this flag, other flags as
* NE, FE, ORE, IDLE would also be cleared.
* @rmtoll SR PE LL_USART_ClearFlag_PE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx)
{
__IO uint32_t tmpreg;
tmpreg = USARTx->SR;
(void) tmpreg;
tmpreg = USARTx->DR;
(void) tmpreg;
}
/**
* @brief Clear Framing Error Flag
* @note Clearing this flag is done by a read access to the USARTx_SR
* register followed by a read access to the USARTx_DR register.
* @note Please also consider that when clearing this flag, other flags as
* PE, NE, ORE, IDLE would also be cleared.
* @rmtoll SR FE LL_USART_ClearFlag_FE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx)
{
__IO uint32_t tmpreg;
tmpreg = USARTx->SR;
(void) tmpreg;
tmpreg = USARTx->DR;
(void) tmpreg;
}
/**
* @brief Clear Noise detected Flag
* @note Clearing this flag is done by a read access to the USARTx_SR
* register followed by a read access to the USARTx_DR register.
* @note Please also consider that when clearing this flag, other flags as
* PE, FE, ORE, IDLE would also be cleared.
* @rmtoll SR NF LL_USART_ClearFlag_NE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx)
{
__IO uint32_t tmpreg;
tmpreg = USARTx->SR;
(void) tmpreg;
tmpreg = USARTx->DR;
(void) tmpreg;
}
/**
* @brief Clear OverRun Error Flag
* @note Clearing this flag is done by a read access to the USARTx_SR
* register followed by a read access to the USARTx_DR register.
* @note Please also consider that when clearing this flag, other flags as
* PE, NE, FE, IDLE would also be cleared.
* @rmtoll SR ORE LL_USART_ClearFlag_ORE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx)
{
__IO uint32_t tmpreg;
tmpreg = USARTx->SR;
(void) tmpreg;
tmpreg = USARTx->DR;
(void) tmpreg;
}
/**
* @brief Clear IDLE line detected Flag
* @note Clearing this flag is done by a read access to the USARTx_SR
* register followed by a read access to the USARTx_DR register.
* @note Please also consider that when clearing this flag, other flags as
* PE, NE, FE, ORE would also be cleared.
* @rmtoll SR IDLE LL_USART_ClearFlag_IDLE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx)
{
__IO uint32_t tmpreg;
tmpreg = USARTx->SR;
(void) tmpreg;
tmpreg = USARTx->DR;
(void) tmpreg;
}
/**
* @brief Clear Transmission Complete Flag
* @rmtoll SR TC LL_USART_ClearFlag_TC
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx)
{
WRITE_REG(USARTx->SR, ~(USART_SR_TC));
}
/**
* @brief Clear RX Not Empty Flag
* @rmtoll SR RXNE LL_USART_ClearFlag_RXNE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_RXNE(USART_TypeDef *USARTx)
{
WRITE_REG(USARTx->SR, ~(USART_SR_RXNE));
}
/**
* @brief Clear LIN Break Detection Flag
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll SR LBD LL_USART_ClearFlag_LBD
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_LBD(USART_TypeDef *USARTx)
{
WRITE_REG(USARTx->SR, ~(USART_SR_LBD));
}
/**
* @brief Clear CTS Interrupt Flag
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll SR CTS LL_USART_ClearFlag_nCTS
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_ClearFlag_nCTS(USART_TypeDef *USARTx)
{
WRITE_REG(USARTx->SR, ~(USART_SR_CTS));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_IT_Management IT_Management
* @{
*/
/**
* @brief Enable IDLE Interrupt
* @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_IDLEIE);
}
/**
* @brief Enable RX Not Empty Interrupt
* @rmtoll CR1 RXNEIE LL_USART_EnableIT_RXNE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE);
}
/**
* @brief Enable Transmission Complete Interrupt
* @rmtoll CR1 TCIE LL_USART_EnableIT_TC
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TCIE);
}
/**
* @brief Enable TX Empty Interrupt
* @rmtoll CR1 TXEIE LL_USART_EnableIT_TXE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE);
}
/**
* @brief Enable Parity Error Interrupt
* @rmtoll CR1 PEIE LL_USART_EnableIT_PE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_PEIE);
}
/**
* @brief Enable LIN Break Detection Interrupt
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LBDIE LL_USART_EnableIT_LBD
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_LBD(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR2, USART_CR2_LBDIE);
}
/**
* @brief Enable Error Interrupt
* @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing
* error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_SR register).
* 0: Interrupt is inhibited
* 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_SR register.
* @rmtoll CR3 EIE LL_USART_EnableIT_ERROR
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_ERROR(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_EIE);
}
/**
* @brief Enable CTS Interrupt
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 CTSIE LL_USART_EnableIT_CTS
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableIT_CTS(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_CTSIE);
}
/**
* @brief Disable IDLE Interrupt
* @rmtoll CR1 IDLEIE LL_USART_DisableIT_IDLE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_IDLE(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_IDLEIE);
}
/**
* @brief Disable RX Not Empty Interrupt
* @rmtoll CR1 RXNEIE LL_USART_DisableIT_RXNE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_RXNE(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE);
}
/**
* @brief Disable Transmission Complete Interrupt
* @rmtoll CR1 TCIE LL_USART_DisableIT_TC
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_TC(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TCIE);
}
/**
* @brief Disable TX Empty Interrupt
* @rmtoll CR1 TXEIE LL_USART_DisableIT_TXE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_TXE(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE);
}
/**
* @brief Disable Parity Error Interrupt
* @rmtoll CR1 PEIE LL_USART_DisableIT_PE
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_PE(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_PEIE);
}
/**
* @brief Disable LIN Break Detection Interrupt
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LBDIE LL_USART_DisableIT_LBD
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_LBD(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR2, USART_CR2_LBDIE);
}
/**
* @brief Disable Error Interrupt
* @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing
* error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_SR register).
* 0: Interrupt is inhibited
* 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_SR register.
* @rmtoll CR3 EIE LL_USART_DisableIT_ERROR
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_ERROR(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_EIE);
}
/**
* @brief Disable CTS Interrupt
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 CTSIE LL_USART_DisableIT_CTS
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableIT_CTS(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_CTSIE);
}
/**
* @brief Check if the USART IDLE Interrupt source is enabled or disabled.
* @rmtoll CR1 IDLEIE LL_USART_IsEnabledIT_IDLE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_IDLE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE));
}
/**
* @brief Check if the USART RX Not Empty Interrupt is enabled or disabled.
* @rmtoll CR1 RXNEIE LL_USART_IsEnabledIT_RXNE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_RXNEIE) == (USART_CR1_RXNEIE));
}
/**
* @brief Check if the USART Transmission Complete Interrupt is enabled or disabled.
* @rmtoll CR1 TCIE LL_USART_IsEnabledIT_TC
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TC(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE));
}
/**
* @brief Check if the USART TX Empty Interrupt is enabled or disabled.
* @rmtoll CR1 TXEIE LL_USART_IsEnabledIT_TXE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_TXEIE) == (USART_CR1_TXEIE));
}
/**
* @brief Check if the USART Parity Error Interrupt is enabled or disabled.
* @rmtoll CR1 PEIE LL_USART_IsEnabledIT_PE
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_PE(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE));
}
/**
* @brief Check if the USART LIN Break Detection Interrupt is enabled or disabled.
* @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
* LIN feature is supported by the USARTx instance.
* @rmtoll CR2 LBDIE LL_USART_IsEnabledIT_LBD
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_LBD(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR2, USART_CR2_LBDIE) == (USART_CR2_LBDIE));
}
/**
* @brief Check if the USART Error Interrupt is enabled or disabled.
* @rmtoll CR3 EIE LL_USART_IsEnabledIT_ERROR
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_ERROR(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE));
}
/**
* @brief Check if the USART CTS Interrupt is enabled or disabled.
* @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
* Hardware Flow control feature is supported by the USARTx instance.
* @rmtoll CR3 CTSIE LL_USART_IsEnabledIT_CTS
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CTS(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_DMA_Management DMA_Management
* @{
*/
/**
* @brief Enable DMA Mode for reception
* @rmtoll CR3 DMAR LL_USART_EnableDMAReq_RX
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAR);
}
/**
* @brief Disable DMA Mode for reception
* @rmtoll CR3 DMAR LL_USART_DisableDMAReq_RX
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableDMAReq_RX(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAR);
}
/**
* @brief Check if DMA Mode is enabled for reception
* @rmtoll CR3 DMAR LL_USART_IsEnabledDMAReq_RX
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_RX(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR));
}
/**
* @brief Enable DMA Mode for transmission
* @rmtoll CR3 DMAT LL_USART_EnableDMAReq_TX
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx)
{
ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAT);
}
/**
* @brief Disable DMA Mode for transmission
* @rmtoll CR3 DMAT LL_USART_DisableDMAReq_TX
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_DisableDMAReq_TX(USART_TypeDef *USARTx)
{
ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAT);
}
/**
* @brief Check if DMA Mode is enabled for transmission
* @rmtoll CR3 DMAT LL_USART_IsEnabledDMAReq_TX
* @param USARTx USART Instance
* @retval State of bit (1 or 0).
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_TX(const USART_TypeDef *USARTx)
{
return (READ_BIT(USARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT));
}
/**
* @brief Get the data register address used for DMA transfer
* @rmtoll DR DR LL_USART_DMA_GetRegAddr
* @note Address of Data Register is valid for both Transmit and Receive transfers.
* @param USARTx USART Instance
* @retval Address of data register
*/
__STATIC_INLINE uint32_t LL_USART_DMA_GetRegAddr(const USART_TypeDef *USARTx)
{
/* return address of DR register */
return ((uint32_t) &(USARTx->DR));
}
/**
* @}
*/
/** @defgroup USART_LL_EF_Data_Management Data_Management
* @{
*/
/**
* @brief Read Receiver Data register (Receive Data value, 8 bits)
* @rmtoll DR DR LL_USART_ReceiveData8
* @param USARTx USART Instance
* @retval Value between Min_Data=0x00 and Max_Data=0xFF
*/
__STATIC_INLINE uint8_t LL_USART_ReceiveData8(const USART_TypeDef *USARTx)
{
return (uint8_t)(READ_BIT(USARTx->DR, USART_DR_DR));
}
/**
* @brief Read Receiver Data register (Receive Data value, 9 bits)
* @rmtoll DR DR LL_USART_ReceiveData9
* @param USARTx USART Instance
* @retval Value between Min_Data=0x00 and Max_Data=0x1FF
*/
__STATIC_INLINE uint16_t LL_USART_ReceiveData9(const USART_TypeDef *USARTx)
{
return (uint16_t)(READ_BIT(USARTx->DR, USART_DR_DR));
}
/**
* @brief Write in Transmitter Data Register (Transmit Data value, 8 bits)
* @rmtoll DR DR LL_USART_TransmitData8
* @param USARTx USART Instance
* @param Value between Min_Data=0x00 and Max_Data=0xFF
* @retval None
*/
__STATIC_INLINE void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value)
{
USARTx->DR = Value;
}
/**
* @brief Write in Transmitter Data Register (Transmit Data value, 9 bits)
* @rmtoll DR DR LL_USART_TransmitData9
* @param USARTx USART Instance
* @param Value between Min_Data=0x00 and Max_Data=0x1FF
* @retval None
*/
__STATIC_INLINE void LL_USART_TransmitData9(USART_TypeDef *USARTx, uint16_t Value)
{
USARTx->DR = Value & 0x1FFU;
}
/**
* @}
*/
/** @defgroup USART_LL_EF_Execution Execution
* @{
*/
/**
* @brief Request Break sending
* @rmtoll CR1 SBK LL_USART_RequestBreakSending
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_RequestBreakSending(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR1, USART_CR1_SBK);
}
/**
* @brief Put USART in Mute mode
* @rmtoll CR1 RWU LL_USART_RequestEnterMuteMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_RequestEnterMuteMode(USART_TypeDef *USARTx)
{
SET_BIT(USARTx->CR1, USART_CR1_RWU);
}
/**
* @brief Put USART in Active mode
* @rmtoll CR1 RWU LL_USART_RequestExitMuteMode
* @param USARTx USART Instance
* @retval None
*/
__STATIC_INLINE void LL_USART_RequestExitMuteMode(USART_TypeDef *USARTx)
{
CLEAR_BIT(USARTx->CR1, USART_CR1_RWU);
}
/**
* @}
*/
#if defined(USE_FULL_LL_DRIVER)
/** @defgroup USART_LL_EF_Init Initialization and de-initialization functions
* @{
*/
ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx);
ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct);
void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct);
ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct);
void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct);
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/**
* @}
*/
/**
* @}
*/
#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32F1xx_LL_USART_H */

View File

@@ -0,0 +1,3771 @@
/**
******************************************************************************
* @file stm32f1xx_hal_uart.c
* @author MCD Application Team
* @brief UART HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
* + Initialization and de-initialization functions
* + IO operation functions
* + Peripheral Control functions
* + Peripheral State and Errors functions
*
******************************************************************************
* @attention
*
* Copyright (c) 2016 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.
*
******************************************************************************
@verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..]
The UART HAL driver can be used as follows:
(#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
(#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
(##) Enable the USARTx interface clock.
(##) UART pins configuration:
(+++) Enable the clock for the UART GPIOs.
(+++) Configure the UART TX/RX pins as alternate function pull-up.
(##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
and HAL_UART_Receive_IT() APIs):
(+++) Configure the USARTx interrupt priority.
(+++) Enable the NVIC USART IRQ handle.
(##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
and HAL_UART_Receive_DMA() APIs):
(+++) Declare a DMA handle structure for the Tx/Rx channel.
(+++) Enable the DMAx interface clock.
(+++) Configure the declared DMA handle structure with the required
Tx/Rx parameters.
(+++) Configure the DMA Tx/Rx channel.
(+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
(+++) Configure the priority and enable the NVIC for the transfer complete
interrupt on the DMA Tx/Rx channel.
(+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
(used for last byte sending completion detection in DMA non circular mode)
(#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
flow control and Mode(Receiver/Transmitter) in the huart Init structure.
(#) For the UART asynchronous mode, initialize the UART registers by calling
the HAL_UART_Init() API.
(#) For the UART Half duplex mode, initialize the UART registers by calling
the HAL_HalfDuplex_Init() API.
(#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
(#) For the Multi-Processor mode, initialize the UART registers by calling
the HAL_MultiProcessor_Init() API.
[..]
(@) The specific UART interrupts (Transmission complete interrupt,
RXNE interrupt and Error Interrupts) will be managed using the macros
__HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
and receive process.
[..]
(@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
HAL_UART_MspInit() API.
##### Callback registration #####
==================================
[..]
The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
allows the user to configure dynamically the driver callbacks.
[..]
Use Function HAL_UART_RegisterCallback() to register a user callback.
Function HAL_UART_RegisterCallback() allows to register following callbacks:
(+) TxHalfCpltCallback : Tx Half Complete Callback.
(+) TxCpltCallback : Tx Complete Callback.
(+) RxHalfCpltCallback : Rx Half Complete Callback.
(+) RxCpltCallback : Rx Complete Callback.
(+) ErrorCallback : Error Callback.
(+) AbortCpltCallback : Abort Complete Callback.
(+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
(+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
(+) MspInitCallback : UART MspInit.
(+) MspDeInitCallback : UART MspDeInit.
This function takes as parameters the HAL peripheral handle, the Callback ID
and a pointer to the user callback function.
[..]
Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
weak (surcharged) function.
HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
and the Callback ID.
This function allows to reset following callbacks:
(+) TxHalfCpltCallback : Tx Half Complete Callback.
(+) TxCpltCallback : Tx Complete Callback.
(+) RxHalfCpltCallback : Rx Half Complete Callback.
(+) RxCpltCallback : Rx Complete Callback.
(+) ErrorCallback : Error Callback.
(+) AbortCpltCallback : Abort Complete Callback.
(+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
(+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
(+) MspInitCallback : UART MspInit.
(+) MspDeInitCallback : UART MspDeInit.
[..]
For specific callback RxEventCallback, use dedicated registration/reset functions:
respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
[..]
By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
all callbacks are set to the corresponding weak (surcharged) functions:
examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
Exception done for MspInit and MspDeInit functions that are respectively
reset to the legacy weak (surcharged) functions in the HAL_UART_Init()
and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
[..]
Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
Exception done MspInit/MspDeInit that can be registered/unregistered
in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
MspInit/DeInit callbacks can be used during the Init/DeInit.
In that case first register the MspInit/MspDeInit user callbacks
using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
or HAL_UART_Init() function.
[..]
When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
not defined, the callback registration feature is not available
and weak (surcharged) callbacks are used.
[..]
Three operation modes are available within this driver :
*** Polling mode IO operation ***
=================================
[..]
(+) Send an amount of data in blocking mode using HAL_UART_Transmit()
(+) Receive an amount of data in blocking mode using HAL_UART_Receive()
*** Interrupt mode IO operation ***
===================================
[..]
(+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
(+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
add his own code by customization of function pointer HAL_UART_TxCpltCallback
(+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
(+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
add his own code by customization of function pointer HAL_UART_RxCpltCallback
(+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
add his own code by customization of function pointer HAL_UART_ErrorCallback
*** DMA mode IO operation ***
==============================
[..]
(+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
(+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
(+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
add his own code by customization of function pointer HAL_UART_TxCpltCallback
(+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
(+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
(+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
add his own code by customization of function pointer HAL_UART_RxCpltCallback
(+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
add his own code by customization of function pointer HAL_UART_ErrorCallback
(+) Pause the DMA Transfer using HAL_UART_DMAPause()
(+) Resume the DMA Transfer using HAL_UART_DMAResume()
(+) Stop the DMA Transfer using HAL_UART_DMAStop()
[..] This subsection also provides a set of additional functions providing enhanced reception
services to user. (For example, these functions allow application to handle use cases
where number of data to be received is unknown).
(#) Compared to standard reception services which only consider number of received
data elements as reception completion criteria, these functions also consider additional events
as triggers for updating reception status to caller :
(+) Detection of inactivity period (RX line has not been active for a given period).
(++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
for 1 frame time, after last received byte.
(#) There are two mode of transfer:
(+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
or till IDLE event occurs. Reception is handled only during function execution.
When function exits, no data reception could occur. HAL status and number of actually received data elements,
are returned by function after finishing transfer.
(+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
These API's return the HAL status.
The end of the data processing will be indicated through the
dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
(#) Blocking mode API:
(+) HAL_UARTEx_ReceiveToIdle()
(#) Non-Blocking mode API with Interrupt:
(+) HAL_UARTEx_ReceiveToIdle_IT()
(#) Non-Blocking mode API with DMA:
(+) HAL_UARTEx_ReceiveToIdle_DMA()
*** UART HAL driver macros list ***
=============================================
[..]
Below the list of most used macros in UART HAL driver.
(+) __HAL_UART_ENABLE: Enable the UART peripheral
(+) __HAL_UART_DISABLE: Disable the UART peripheral
(+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
(+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
(+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
(+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
(+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
[..]
(@) You can refer to the UART HAL driver header file for more useful macros
@endverbatim
[..]
(@) Additional remark: If the parity is enabled, then the MSB bit of the data written
in the data register is transmitted but is changed by the parity bit.
Depending on the frame length defined by the M bit (8-bits or 9-bits),
the possible UART frame formats are as listed in the following table:
+-------------------------------------------------------------+
| M bit | PCE bit | UART frame |
|---------------------|---------------------------------------|
| 0 | 0 | | SB | 8 bit data | STB | |
|---------|-----------|---------------------------------------|
| 0 | 1 | | SB | 7 bit data | PB | STB | |
|---------|-----------|---------------------------------------|
| 1 | 0 | | SB | 9 bit data | STB | |
|---------|-----------|---------------------------------------|
| 1 | 1 | | SB | 8 bit data | PB | STB | |
+-------------------------------------------------------------+
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
/** @addtogroup STM32F1xx_HAL_Driver
* @{
*/
/** @defgroup UART UART
* @brief HAL UART module driver
* @{
*/
#ifdef HAL_UART_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @addtogroup UART_Private_Constants
* @{
*/
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @addtogroup UART_Private_Functions UART Private Functions
* @{
*/
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
static void UART_DMAError(DMA_HandleTypeDef *hdma);
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
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, FlagStatus Status,
uint32_t Tickstart, uint32_t Timeout);
static void UART_SetConfig(UART_HandleTypeDef *huart);
/**
* @}
*/
/* Exported functions ---------------------------------------------------------*/
/** @defgroup UART_Exported_Functions UART Exported Functions
* @{
*/
/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
* @brief Initialization and Configuration functions
*
@verbatim
===============================================================================
##### Initialization and Configuration functions #####
===============================================================================
[..]
This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
in asynchronous mode.
(+) For the asynchronous mode only these parameters can be configured:
(++) Baud Rate
(++) Word Length
(++) Stop Bit
(++) Parity: If the parity is enabled, then the MSB bit of the data written
in the data register is transmitted but is changed by the parity bit.
Depending on the frame length defined by the M bit (8-bits or 9-bits),
please refer to Reference manual for possible UART frame formats.
(++) Hardware flow control
(++) Receiver/transmitter modes
(++) Over Sampling Method
[..]
The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor configuration
procedures (details for the procedures are available in reference manuals
(RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
@endverbatim
* @{
*/
/**
* @brief Initializes the UART mode according to the specified parameters in
* the UART_InitTypeDef and create the associated handle.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
{
/* The hardware flow control is available only for USART1, USART2 and USART3 */
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
}
else
{
assert_param(IS_UART_INSTANCE(huart->Instance));
}
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
#if defined(USART_CR1_OVER8)
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
#endif /* USART_CR1_OVER8 */
if (huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(huart);
if (huart->MspInitCallback == NULL)
{
huart->MspInitCallback = HAL_UART_MspInit;
}
/* Init the low level hardware */
huart->MspInitCallback(huart);
#else
/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the peripheral */
__HAL_UART_DISABLE(huart);
/* Set the UART Communication parameters */
UART_SetConfig(huart);
/* In asynchronous mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
/* Enable the peripheral */
__HAL_UART_ENABLE(huart);
/* Initialize the UART state */
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->RxEventType = HAL_UART_RXEVENT_TC;
return HAL_OK;
}
/**
* @brief Initializes the half-duplex mode according to the specified
* parameters in the UART_InitTypeDef and create the associated handle.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
#if defined(USART_CR1_OVER8)
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
#endif /* USART_CR1_OVER8 */
if (huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(huart);
if (huart->MspInitCallback == NULL)
{
huart->MspInitCallback = HAL_UART_MspInit;
}
/* Init the low level hardware */
huart->MspInitCallback(huart);
#else
/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the peripheral */
__HAL_UART_DISABLE(huart);
/* Set the UART Communication parameters */
UART_SetConfig(huart);
/* In half-duplex mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN and IREN bits in the USART_CR3 register.*/
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
/* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
/* Enable the peripheral */
__HAL_UART_ENABLE(huart);
/* Initialize the UART state*/
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->RxEventType = HAL_UART_RXEVENT_TC;
return HAL_OK;
}
/**
* @brief Initializes the LIN mode according to the specified
* parameters in the UART_InitTypeDef and create the associated handle.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param BreakDetectLength Specifies the LIN break detection length.
* This parameter can be one of the following values:
* @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
* @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
* @retval HAL status
*/
HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the LIN UART instance */
assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
/* Check the Break detection length parameter */
assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
#if defined(USART_CR1_OVER8)
assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
#endif /* USART_CR1_OVER8 */
if (huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(huart);
if (huart->MspInitCallback == NULL)
{
huart->MspInitCallback = HAL_UART_MspInit;
}
/* Init the low level hardware */
huart->MspInitCallback(huart);
#else
/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the peripheral */
__HAL_UART_DISABLE(huart);
/* Set the UART Communication parameters */
UART_SetConfig(huart);
/* In LIN mode, the following bits must be kept cleared:
- CLKEN bits in the USART_CR2 register,
- SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
/* Enable the LIN mode by setting the LINEN bit in the CR2 register */
SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
/* Set the USART LIN Break detection length. */
CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL);
SET_BIT(huart->Instance->CR2, BreakDetectLength);
/* Enable the peripheral */
__HAL_UART_ENABLE(huart);
/* Initialize the UART state*/
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->RxEventType = HAL_UART_RXEVENT_TC;
return HAL_OK;
}
/**
* @brief Initializes the Multi-Processor mode according to the specified
* parameters in the UART_InitTypeDef and create the associated handle.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param Address USART address
* @param WakeUpMethod specifies the USART wake-up method.
* This parameter can be one of the following values:
* @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
* @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_UART_INSTANCE(huart->Instance));
/* Check the Address & wake up method parameters */
assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
assert_param(IS_UART_ADDRESS(Address));
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
#if defined(USART_CR1_OVER8)
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
#endif /* USART_CR1_OVER8 */
if (huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(huart);
if (huart->MspInitCallback == NULL)
{
huart->MspInitCallback = HAL_UART_MspInit;
}
/* Init the low level hardware */
huart->MspInitCallback(huart);
#else
/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the peripheral */
__HAL_UART_DISABLE(huart);
/* Set the UART Communication parameters */
UART_SetConfig(huart);
/* In Multi-Processor mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN, HDSEL and IREN bits in the USART_CR3 register */
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
/* Set the USART address node */
CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD);
SET_BIT(huart->Instance->CR2, Address);
/* Set the wake up method by setting the WAKE bit in the CR1 register */
CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE);
SET_BIT(huart->Instance->CR1, WakeUpMethod);
/* Enable the peripheral */
__HAL_UART_ENABLE(huart);
/* Initialize the UART state */
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->RxEventType = HAL_UART_RXEVENT_TC;
return HAL_OK;
}
/**
* @brief DeInitializes the UART peripheral.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_UART_INSTANCE(huart->Instance));
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the Peripheral */
__HAL_UART_DISABLE(huart);
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
if (huart->MspDeInitCallback == NULL)
{
huart->MspDeInitCallback = HAL_UART_MspDeInit;
}
/* DeInit the low level hardware */
huart->MspDeInitCallback(huart);
#else
/* DeInit the low level hardware */
HAL_UART_MspDeInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_RESET;
huart->RxState = HAL_UART_STATE_RESET;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
huart->RxEventType = HAL_UART_RXEVENT_TC;
/* Process Unlock */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @brief UART MSP Init.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_MspInit could be implemented in the user file
*/
}
/**
* @brief UART MSP DeInit.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_MspDeInit could be implemented in the user file
*/
}
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/**
* @brief Register a User UART Callback
* To be used instead of the weak predefined callback
* @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(),
* HAL_MultiProcessor_Init() to register callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
* @param huart uart handle
* @param CallbackID ID of the callback to be registered
* This parameter can be one of the following values:
* @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
* @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
* @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
* @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
* @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
* @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
* @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
* @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
* @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
* @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
* @param pCallback pointer to the Callback function
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
pUART_CallbackTypeDef pCallback)
{
HAL_StatusTypeDef status = HAL_OK;
if (pCallback == NULL)
{
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
return HAL_ERROR;
}
if (huart->gState == HAL_UART_STATE_READY)
{
switch (CallbackID)
{
case HAL_UART_TX_HALFCOMPLETE_CB_ID :
huart->TxHalfCpltCallback = pCallback;
break;
case HAL_UART_TX_COMPLETE_CB_ID :
huart->TxCpltCallback = pCallback;
break;
case HAL_UART_RX_HALFCOMPLETE_CB_ID :
huart->RxHalfCpltCallback = pCallback;
break;
case HAL_UART_RX_COMPLETE_CB_ID :
huart->RxCpltCallback = pCallback;
break;
case HAL_UART_ERROR_CB_ID :
huart->ErrorCallback = pCallback;
break;
case HAL_UART_ABORT_COMPLETE_CB_ID :
huart->AbortCpltCallback = pCallback;
break;
case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
huart->AbortTransmitCpltCallback = pCallback;
break;
case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
huart->AbortReceiveCpltCallback = pCallback;
break;
case HAL_UART_MSPINIT_CB_ID :
huart->MspInitCallback = pCallback;
break;
case HAL_UART_MSPDEINIT_CB_ID :
huart->MspDeInitCallback = pCallback;
break;
default :
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else if (huart->gState == HAL_UART_STATE_RESET)
{
switch (CallbackID)
{
case HAL_UART_MSPINIT_CB_ID :
huart->MspInitCallback = pCallback;
break;
case HAL_UART_MSPDEINIT_CB_ID :
huart->MspDeInitCallback = pCallback;
break;
default :
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else
{
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
}
return status;
}
/**
* @brief Unregister an UART Callback
* UART callaback is redirected to the weak predefined callback
* @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
* HAL_LIN_Init(), HAL_MultiProcessor_Init() to un-register callbacks for HAL_UART_MSPINIT_CB_ID
* and HAL_UART_MSPDEINIT_CB_ID
* @param huart uart handle
* @param CallbackID ID of the callback to be unregistered
* This parameter can be one of the following values:
* @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
* @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
* @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
* @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
* @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
* @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
* @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
* @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
* @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
* @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
{
HAL_StatusTypeDef status = HAL_OK;
if (HAL_UART_STATE_READY == huart->gState)
{
switch (CallbackID)
{
case HAL_UART_TX_HALFCOMPLETE_CB_ID :
huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
break;
case HAL_UART_TX_COMPLETE_CB_ID :
huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
break;
case HAL_UART_RX_HALFCOMPLETE_CB_ID :
huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
break;
case HAL_UART_RX_COMPLETE_CB_ID :
huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
break;
case HAL_UART_ERROR_CB_ID :
huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
break;
case HAL_UART_ABORT_COMPLETE_CB_ID :
huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
break;
case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
break;
case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
break;
case HAL_UART_MSPINIT_CB_ID :
huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
break;
case HAL_UART_MSPDEINIT_CB_ID :
huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
break;
default :
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else if (HAL_UART_STATE_RESET == huart->gState)
{
switch (CallbackID)
{
case HAL_UART_MSPINIT_CB_ID :
huart->MspInitCallback = HAL_UART_MspInit;
break;
case HAL_UART_MSPDEINIT_CB_ID :
huart->MspDeInitCallback = HAL_UART_MspDeInit;
break;
default :
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
break;
}
}
else
{
/* Update the error code */
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
/* Return error status */
status = HAL_ERROR;
}
return status;
}
/**
* @brief Register a User UART Rx Event Callback
* To be used instead of the weak predefined callback
* @param huart Uart handle
* @param pCallback Pointer to the Rx Event Callback function
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
{
HAL_StatusTypeDef status = HAL_OK;
if (pCallback == NULL)
{
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
return HAL_ERROR;
}
/* Process locked */
__HAL_LOCK(huart);
if (huart->gState == HAL_UART_STATE_READY)
{
huart->RxEventCallback = pCallback;
}
else
{
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
status = HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(huart);
return status;
}
/**
* @brief UnRegister the UART Rx Event Callback
* UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
* @param huart Uart handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
{
HAL_StatusTypeDef status = HAL_OK;
/* Process locked */
__HAL_LOCK(huart);
if (huart->gState == HAL_UART_STATE_READY)
{
huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
}
else
{
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
status = HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(huart);
return status;
}
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
/**
* @}
*/
/** @defgroup UART_Exported_Functions_Group2 IO operation functions
* @brief UART Transmit and Receive functions
*
@verbatim
===============================================================================
##### IO operation functions #####
===============================================================================
This subsection provides a set of functions allowing to manage the UART asynchronous
and Half duplex data transfers.
(#) There are two modes of transfer:
(+) Blocking mode: The communication is performed in polling mode.
The HAL status of all data processing is returned by the same function
after finishing transfer.
(+) Non-Blocking mode: The communication is performed using Interrupts
or DMA, these API's return the HAL status.
The end of the data processing will be indicated through the
dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
using DMA mode.
The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
will be executed respectively at the end of the transmit or receive process
The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected.
(#) Blocking mode API's are :
(+) HAL_UART_Transmit()
(+) HAL_UART_Receive()
(#) Non-Blocking mode API's with Interrupt are :
(+) HAL_UART_Transmit_IT()
(+) HAL_UART_Receive_IT()
(+) HAL_UART_IRQHandler()
(#) Non-Blocking mode API's with DMA are :
(+) HAL_UART_Transmit_DMA()
(+) HAL_UART_Receive_DMA()
(+) HAL_UART_DMAPause()
(+) HAL_UART_DMAResume()
(+) HAL_UART_DMAStop()
(#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
(+) HAL_UART_TxHalfCpltCallback()
(+) HAL_UART_TxCpltCallback()
(+) HAL_UART_RxHalfCpltCallback()
(+) HAL_UART_RxCpltCallback()
(+) HAL_UART_ErrorCallback()
(#) Non-Blocking mode transfers could be aborted using Abort API's :
(+) HAL_UART_Abort()
(+) HAL_UART_AbortTransmit()
(+) HAL_UART_AbortReceive()
(+) HAL_UART_Abort_IT()
(+) HAL_UART_AbortTransmit_IT()
(+) HAL_UART_AbortReceive_IT()
(#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
(+) HAL_UART_AbortCpltCallback()
(+) HAL_UART_AbortTransmitCpltCallback()
(+) HAL_UART_AbortReceiveCpltCallback()
(#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced reception services:
(+) HAL_UARTEx_RxEventCallback()
(#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
Errors are handled as follows :
(+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
If user wants to abort it, Abort services should be called by user.
(+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
-@- In the Half duplex communication, it is forbidden to run the transmit
and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
@endverbatim
* @{
*/
/**
* @brief Sends an amount of data in blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the sent data is handled as a set of u16. In this case, Size must indicate the number
* of u16 provided through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be sent
* @param Timeout Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
const uint8_t *pdata8bits;
const uint16_t *pdata16bits;
uint32_t tickstart = 0U;
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Init tickstart for timeout management */
tickstart = HAL_GetTick();
huart->TxXferSize = Size;
huart->TxXferCount = Size;
/* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (const uint16_t *) pData;
}
else
{
pdata8bits = pData;
pdata16bits = NULL;
}
while (huart->TxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
huart->gState = HAL_UART_STATE_READY;
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
{
huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
pdata16bits++;
}
else
{
huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
pdata8bits++;
}
huart->TxXferCount--;
}
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
{
huart->gState = HAL_UART_STATE_READY;
return HAL_TIMEOUT;
}
/* At end of Tx process, restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Receives an amount of data in blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @param Timeout Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint8_t *pdata8bits;
uint16_t *pdata16bits;
uint32_t tickstart = 0U;
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Init tickstart for timeout management */
tickstart = HAL_GetTick();
huart->RxXferSize = Size;
huart->RxXferCount = Size;
/* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (uint16_t *) pData;
}
else
{
pdata8bits = pData;
pdata16bits = NULL;
}
/* Check the remain data to be received */
while (huart->RxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
{
huart->RxState = HAL_UART_STATE_READY;
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
{
*pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
pdata16bits++;
}
else
{
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
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;
}
}
/**
* @brief Sends an amount of data in non blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the sent data is handled as a set of u16. In this case, Size must indicate the number
* of u16 provided through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
{
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Enable the UART Transmit data register empty Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Receives an amount of data in non blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* Set Reception type to Standard reception */
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
return (UART_Start_Receive_IT(huart, pData, Size));
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Sends an amount of data in DMA mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the sent data is handled as a set of u16. In this case, Size must indicate the number
* of u16 provided through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
{
const uint32_t *tmp;
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Set the UART DMA transfer complete callback */
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
/* Set the DMA error callback */
huart->hdmatx->XferErrorCallback = UART_DMAError;
/* Set the DMA abort callback */
huart->hdmatx->XferAbortCallback = NULL;
/* Enable the UART transmit DMA channel */
tmp = (const uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
/* Clear the TC flag in the SR register by writing 0 to it */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
/* Enable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Receives an amount of data in DMA mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* Set Reception type to Standard reception */
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
return (UART_Start_Receive_DMA(huart, pData, Size));
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Pauses the DMA Transfer.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
{
uint32_t dmarequest = 0x00U;
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
{
/* Disable the UART DMA Tx request */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
}
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Disable the UART DMA Rx request */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
}
return HAL_OK;
}
/**
* @brief Resumes the DMA Transfer.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
{
if (huart->gState == HAL_UART_STATE_BUSY_TX)
{
/* Enable the UART DMA Tx request */
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
}
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
/* Clear the Overrun flag before resuming the Rx transfer*/
__HAL_UART_CLEAR_OREFLAG(huart);
/* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
if (huart->Init.Parity != UART_PARITY_NONE)
{
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
}
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Enable the UART DMA Rx request */
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
}
return HAL_OK;
}
/**
* @brief Stops the DMA Transfer.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
{
uint32_t dmarequest = 0x00U;
/* The Lock is not implemented on this API to allow the user application
to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
*/
/* Stop UART DMA Tx request if ongoing */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Abort the UART DMA Tx channel */
if (huart->hdmatx != NULL)
{
HAL_DMA_Abort(huart->hdmatx);
}
UART_EndTxTransfer(huart);
}
/* Stop UART DMA Rx request if ongoing */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel */
if (huart->hdmarx != NULL)
{
HAL_DMA_Abort(huart->hdmarx);
}
UART_EndRxTransfer(huart);
}
return HAL_OK;
}
/**
* @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs.
* @note HAL_OK is returned if reception is completed (expected number of data has been received)
* or if reception is stopped after IDLE event (less than the expected number of data has been received)
* In this case, RxLen output parameter indicates number of data available in reception buffer.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
* the received data is handled as a set of uint16_t. In this case, Size must indicate the number
* of uint16_t available through pData.
* @param huart UART handle.
* @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
* @param Size Amount of data elements (uint8_t or uint16_t) to be received.
* @param RxLen Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event)
* @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
uint32_t Timeout)
{
uint8_t *pdata8bits;
uint16_t *pdata16bits;
uint32_t tickstart;
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
huart->RxEventType = HAL_UART_RXEVENT_TC;
/* Init tickstart for timeout management */
tickstart = HAL_GetTick();
huart->RxXferSize = Size;
huart->RxXferCount = Size;
/* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (uint16_t *) pData;
}
else
{
pdata8bits = pData;
pdata16bits = NULL;
}
/* Initialize output number of received elements */
*RxLen = 0U;
/* as long as data have to be received */
while (huart->RxXferCount > 0U)
{
/* Check if IDLE flag is set */
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
{
/* Clear IDLE flag in ISR */
__HAL_UART_CLEAR_IDLEFLAG(huart);
/* If Set, but no data ever received, clear flag without exiting loop */
/* If Set, and data has already been received, this means Idle Event is valid : End reception */
if (*RxLen > 0U)
{
huart->RxEventType = HAL_UART_RXEVENT_IDLE;
huart->RxState = HAL_UART_STATE_READY;
return HAL_OK;
}
}
/* Check if RXNE flag is set */
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
{
if (pdata8bits == NULL)
{
*pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
pdata16bits++;
}
else
{
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
pdata8bits++;
}
/* Increment number of received elements */
*RxLen += 1U;
huart->RxXferCount--;
}
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
{
huart->RxState = HAL_UART_STATE_READY;
return HAL_TIMEOUT;
}
}
}
/* Set number of received elements in output parameter : RxLen */
*RxLen = huart->RxXferSize - 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;
}
}
/**
* @brief Receive an amount of data in interrupt mode till either the expected number of data is received or an IDLE event occurs.
* @note Reception is initiated by this function call. Further progress of reception is achieved thanks
* to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
* number of received data elements.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
* the received data is handled as a set of uint16_t. In this case, Size must indicate the number
* of uint16_t available through pData.
* @param huart UART handle.
* @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
* @param Size Amount of data elements (uint8_t or uint16_t) to be received.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
HAL_StatusTypeDef status;
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* Set Reception type to reception till IDLE Event*/
huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
huart->RxEventType = HAL_UART_RXEVENT_TC;
status = UART_Start_Receive_IT(huart, pData, Size);
/* Check Rx process has been successfully started */
if (status == HAL_OK)
{
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
}
else
{
/* In case of errors already pending when reception is started,
Interrupts may have already been raised and lead to reception abortion.
(Overrun error for instance).
In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
status = HAL_ERROR;
}
}
return status;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs.
* @note Reception is initiated by this function call. Further progress of reception is achieved thanks
* to DMA services, transferring automatically received data elements in user reception buffer and
* calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
* reception phase as ended. In all cases, callback execution will indicate number of received data elements.
* @note When the UART parity is enabled (PCE = 1), the received data contain
* the parity bit (MSB position).
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
* the received data is handled as a set of uint16_t. In this case, Size must indicate the number
* of uint16_t available through pData.
* @param huart UART handle.
* @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
* @param Size Amount of data elements (uint8_t or uint16_t) to be received.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
HAL_StatusTypeDef status;
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* Set Reception type to reception till IDLE Event*/
huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
huart->RxEventType = HAL_UART_RXEVENT_TC;
status = UART_Start_Receive_DMA(huart, pData, Size);
/* Check Rx process has been successfully started */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
}
else
{
/* In case of errors already pending when reception is started,
Interrupts may have already been raised and lead to reception abortion.
(Overrun error for instance).
In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
status = HAL_ERROR;
}
return status;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Provide Rx Event type that has lead to RxEvent callback execution.
* @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
* of reception process is provided to application through calls of Rx Event callback (either default one
* HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
* Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
* to Rx Event callback execution.
* @note This function is expected to be called within the user implementation of Rx Event Callback,
* in order to provide the accurate value :
* In Interrupt Mode :
* - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
* - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
* received data is lower than expected one)
* In DMA Mode :
* - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
* - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
* - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
* received data is lower than expected one).
* In DMA mode, RxEvent callback could be called several times;
* When DMA is configured in Normal Mode, HT event does not stop Reception process;
* When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
* @param huart UART handle.
* @retval Rx Event Type (returned value will be a value of @ref UART_RxEvent_Type_Values)
*/
HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart)
{
/* Return Rx Event type value, as stored in UART handle */
return(huart->RxEventType);
}
/**
* @brief Abort ongoing transfers (blocking mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx and Rx)
* - Disable the DMA transfer in the peripheral register (if enabled)
* - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
* - Set handle State to READY
* @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
{
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
}
/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */
if (huart->hdmatx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmatx->XferAbortCallback = NULL;
if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;
return HAL_TIMEOUT;
}
}
}
}
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = NULL;
if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;
return HAL_TIMEOUT;
}
}
}
}
/* Reset Tx and Rx transfer counters */
huart->TxXferCount = 0x00U;
huart->RxXferCount = 0x00U;
/* Reset ErrorCode */
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Restore huart->RxState and huart->gState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->gState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
return HAL_OK;
}
/**
* @brief Abort ongoing Transmit transfer (blocking mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx)
* - Disable the DMA transfer in the peripheral register (if enabled)
* - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
* - Set handle State to READY
* @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
if (huart->hdmatx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmatx->XferAbortCallback = NULL;
if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;
return HAL_TIMEOUT;
}
}
}
}
/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;
/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
return HAL_OK;
}
/**
* @brief Abort ongoing Receive transfer (blocking mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Rx)
* - Disable the DMA transfer in the peripheral register (if enabled)
* - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
* - Set handle State to READY
* @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
}
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = NULL;
if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;
return HAL_TIMEOUT;
}
}
}
}
/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;
/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
return HAL_OK;
}
/**
* @brief Abort ongoing transfers (Interrupt mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx and Rx)
* - Disable the DMA transfer in the peripheral register (if enabled)
* - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
* - Set handle State to READY
* - At abort completion, call user abort complete callback
* @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
* considered as completed only when user abort complete callback is executed (not when exiting function).
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
{
uint32_t AbortCplt = 0x01U;
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
}
/* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
before any call to DMA Abort functions */
/* DMA Tx Handle is valid */
if (huart->hdmatx != NULL)
{
/* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
Otherwise, set it to NULL */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
}
else
{
huart->hdmatx->XferAbortCallback = NULL;
}
}
/* DMA Rx Handle is valid */
if (huart->hdmarx != NULL)
{
/* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
Otherwise, set it to NULL */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
}
else
{
huart->hdmarx->XferAbortCallback = NULL;
}
}
/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
/* Disable DMA Tx at UART level */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
if (huart->hdmatx != NULL)
{
/* UART Tx DMA Abort callback has already been initialised :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
/* Abort DMA TX */
if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
{
huart->hdmatx->XferAbortCallback = NULL;
}
else
{
AbortCplt = 0x00U;
}
}
}
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
if (huart->hdmarx != NULL)
{
/* UART Rx DMA Abort callback has already been initialised :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
/* Abort DMA RX */
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
huart->hdmarx->XferAbortCallback = NULL;
AbortCplt = 0x01U;
}
else
{
AbortCplt = 0x00U;
}
}
}
/* if no DMA abort complete callback execution is required => call user Abort Complete callback */
if (AbortCplt == 0x01U)
{
/* Reset Tx and Rx transfer counters */
huart->TxXferCount = 0x00U;
huart->RxXferCount = 0x00U;
/* Reset ErrorCode */
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Restore huart->gState and huart->RxState to Ready */
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort complete callback */
huart->AbortCpltCallback(huart);
#else
/* Call legacy weak Abort complete callback */
HAL_UART_AbortCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
return HAL_OK;
}
/**
* @brief Abort ongoing Transmit transfer (Interrupt mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx)
* - Disable the DMA transfer in the peripheral register (if enabled)
* - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
* - Set handle State to READY
* - At abort completion, call user abort complete callback
* @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
* considered as completed only when user abort complete callback is executed (not when exiting function).
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
if (huart->hdmatx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
/* Abort DMA TX */
if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
{
/* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
huart->hdmatx->XferAbortCallback(huart->hdmatx);
}
}
else
{
/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;
/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Transmit Complete Callback */
huart->AbortTransmitCpltCallback(huart);
#else
/* Call legacy weak Abort Transmit Complete Callback */
HAL_UART_AbortTransmitCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;
/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Transmit Complete Callback */
huart->AbortTransmitCpltCallback(huart);
#else
/* Call legacy weak Abort Transmit Complete Callback */
HAL_UART_AbortTransmitCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
return HAL_OK;
}
/**
* @brief Abort ongoing Receive transfer (Interrupt mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Rx)
* - Disable the DMA transfer in the peripheral register (if enabled)
* - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
* - Set handle State to READY
* - At abort completion, call user abort complete callback
* @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
* considered as completed only when user abort complete callback is executed (not when exiting function).
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
}
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
/* Abort DMA RX */
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
/* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
else
{
/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;
/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Receive Complete Callback */
huart->AbortReceiveCpltCallback(huart);
#else
/* Call legacy weak Abort Receive Complete Callback */
HAL_UART_AbortReceiveCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;
/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Receive Complete Callback */
huart->AbortReceiveCpltCallback(huart);
#else
/* Call legacy weak Abort Receive Complete Callback */
HAL_UART_AbortReceiveCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
return HAL_OK;
}
/**
* @brief This function handles UART interrupt request.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t isrflags = READ_REG(huart->Instance->SR);
uint32_t cr1its = READ_REG(huart->Instance->CR1);
uint32_t cr3its = READ_REG(huart->Instance->CR3);
uint32_t errorflags = 0x00U;
uint32_t dmarequest = 0x00U;
/* If no error occurs */
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
if (errorflags == RESET)
{
/* UART in mode Receiver -------------------------------------------------*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);
return;
}
}
/* If some errors occur */
if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET)
|| ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
{
/* UART parity error interrupt occurred ----------------------------------*/
if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
/* UART noise error interrupt occurred -----------------------------------*/
if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
/* UART frame error interrupt occurred -----------------------------------*/
if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
/* UART Over-Run interrupt occurred --------------------------------------*/
if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET)
|| ((cr3its & USART_CR3_EIE) != RESET)))
{
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
/* Call UART Error Call back function if need be --------------------------*/
if (huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* UART in mode Receiver -----------------------------------------------*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);
}
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
consider error as blocking */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
{
/* Blocking error : transfer is aborted
Set the UART state ready to be able to start again the process,
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
UART_EndRxTransfer(huart);
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
/* Call Directly XferAbortCallback function in case of error */
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
else
{
/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Non Blocking error : transfer could go on.
Error is notified to user through user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
}
return;
} /* End if some error occurs */
/* Check current reception Mode :
If Reception till IDLE event has been selected : */
if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
&& ((isrflags & USART_SR_IDLE) != 0U)
&& ((cr1its & USART_SR_IDLE) != 0U))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
/* Check if DMA mode is enabled in UART */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
/* DMA mode enabled */
/* Check received length : If all expected data are received, do nothing,
(DMA cplt callback will be called).
Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
if ((nb_remaining_rx_data > 0U)
&& (nb_remaining_rx_data < huart->RxXferSize))
{
/* Reception is not complete */
huart->RxXferCount = nb_remaining_rx_data;
/* In Normal mode, end DMA xfer and HAL UART Rx process*/
if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
{
/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Disable the DMA transfer for the receiver request by resetting the DMAR bit
in the UART CR3 register */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
/* Last bytes received, so no need as the abort is immediate */
(void)HAL_DMA_Abort(huart->hdmarx);
}
/* Initialize type of RxEvent that correspond to RxEvent callback execution;
In this case, Rx Event type is Idle Event */
huart->RxEventType = HAL_UART_RXEVENT_IDLE;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
return;
}
else
{
/* DMA mode not enabled */
/* Check received length : If all expected data are received, do nothing.
Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
if ((huart->RxXferCount > 0U)
&& (nb_rx_data > 0U))
{
/* Disable the UART Parity Error Interrupt and RXNE interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
/* Initialize type of RxEvent that correspond to RxEvent callback execution;
In this case, Rx Event type is Idle Event */
huart->RxEventType = HAL_UART_RXEVENT_IDLE;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxEventCallback(huart, nb_rx_data);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
return;
}
}
/* UART in mode Transmitter ------------------------------------------------*/
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
{
UART_Transmit_IT(huart);
return;
}
/* UART in mode Transmitter end --------------------------------------------*/
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
{
UART_EndTransmit_IT(huart);
return;
}
}
/**
* @brief Tx Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
}
/**
* @brief Tx Half Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_TxHalfCpltCallback could be implemented in the user file
*/
}
/**
* @brief Rx Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
}
/**
* @brief Rx Half Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_RxHalfCpltCallback could be implemented in the user file
*/
}
/**
* @brief UART error callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_ErrorCallback could be implemented in the user file
*/
}
/**
* @brief UART Abort Complete callback.
* @param huart UART handle.
* @retval None
*/
__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_AbortCpltCallback can be implemented in the user file.
*/
}
/**
* @brief UART Abort Complete callback.
* @param huart UART handle.
* @retval None
*/
__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
*/
}
/**
* @brief UART Abort Receive Complete callback.
* @param huart UART handle.
* @retval None
*/
__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
*/
}
/**
* @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
* @param huart UART handle
* @param Size Number of data available in application reception buffer (indicates a position in
* reception buffer until which, data are available)
* @retval None
*/
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
UNUSED(Size);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UARTEx_RxEventCallback can be implemented in the user file.
*/
}
/**
* @}
*/
/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
* @brief UART control functions
*
@verbatim
==============================================================================
##### Peripheral Control functions #####
==============================================================================
[..]
This subsection provides a set of functions allowing to control the UART:
(+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
(+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
(+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
(+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
(+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
@endverbatim
* @{
*/
/**
* @brief Transmits break characters.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
{
/* Check the parameters */
assert_param(IS_UART_INSTANCE(huart->Instance));
/* Process Locked */
__HAL_LOCK(huart);
huart->gState = HAL_UART_STATE_BUSY;
/* Send break characters */
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
huart->gState = HAL_UART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @brief Enters the UART in mute mode.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
{
/* Check the parameters */
assert_param(IS_UART_INSTANCE(huart->Instance));
/* Process Locked */
__HAL_LOCK(huart);
huart->gState = HAL_UART_STATE_BUSY;
/* Enable the USART mute mode by setting the RWU bit in the CR1 register */
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
huart->gState = HAL_UART_STATE_READY;
huart->RxEventType = HAL_UART_RXEVENT_TC;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @brief Exits the UART mute mode: wake up software.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
{
/* Check the parameters */
assert_param(IS_UART_INSTANCE(huart->Instance));
/* Process Locked */
__HAL_LOCK(huart);
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
huart->gState = HAL_UART_STATE_READY;
huart->RxEventType = HAL_UART_RXEVENT_TC;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @brief Enables the UART transmitter and disables the UART receiver.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
{
uint32_t tmpreg = 0x00U;
/* Process Locked */
__HAL_LOCK(huart);
huart->gState = HAL_UART_STATE_BUSY;
/*-------------------------- USART CR1 Configuration -----------------------*/
tmpreg = huart->Instance->CR1;
/* Clear TE and RE bits */
tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
/* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
tmpreg |= (uint32_t)USART_CR1_TE;
/* Write to USART CR1 */
WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
huart->gState = HAL_UART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @brief Enables the UART receiver and disables the UART transmitter.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
{
uint32_t tmpreg = 0x00U;
/* Process Locked */
__HAL_LOCK(huart);
huart->gState = HAL_UART_STATE_BUSY;
/*-------------------------- USART CR1 Configuration -----------------------*/
tmpreg = huart->Instance->CR1;
/* Clear TE and RE bits */
tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
/* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
tmpreg |= (uint32_t)USART_CR1_RE;
/* Write to USART CR1 */
WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
huart->gState = HAL_UART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
/**
* @}
*/
/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
* @brief UART State and Errors functions
*
@verbatim
==============================================================================
##### Peripheral State and Errors functions #####
==============================================================================
[..]
This subsection provides a set of functions allowing to return the State of
UART communication process, return Peripheral Errors occurred during communication
process
(+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
(+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
@endverbatim
* @{
*/
/**
* @brief Returns the UART state.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL state
*/
HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
{
uint32_t temp1 = 0x00U, temp2 = 0x00U;
temp1 = huart->gState;
temp2 = huart->RxState;
return (HAL_UART_StateTypeDef)(temp1 | temp2);
}
/**
* @brief Return the UART error code
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART.
* @retval UART Error Code
*/
uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
{
return huart->ErrorCode;
}
/**
* @}
*/
/**
* @}
*/
/** @defgroup UART_Private_Functions UART Private Functions
* @{
*/
/**
* @brief Initialize the callbacks to their default values.
* @param huart UART handle.
* @retval none
*/
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
{
/* Init the UART Callback settings */
huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
}
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
/**
* @brief DMA UART transmit process complete callback.
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
/* DMA Normal mode*/
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
{
huart->TxXferCount = 0x00U;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
}
/* DMA Circular mode */
else
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Tx complete callback*/
huart->TxCpltCallback(huart);
#else
/*Call legacy weak Tx complete callback*/
HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
/**
* @brief DMA UART transmit process half complete callback
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Tx complete callback*/
huart->TxHalfCpltCallback(huart);
#else
/*Call legacy weak Tx complete callback*/
HAL_UART_TxHalfCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief DMA UART receive process complete callback.
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
/* DMA Normal mode*/
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
{
huart->RxXferCount = 0U;
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Disable the DMA transfer for the receiver request by setting the DMAR bit
in the UART CR3 register */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
/* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
}
}
/* Initialize type of RxEvent that correspond to RxEvent callback execution;
In this case, Rx Event type is Transfer Complete */
huart->RxEventType = HAL_UART_RXEVENT_TC;
/* Check current reception Mode :
If Reception till IDLE event has been selected : use Rx Event callback */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
else
{
/* In other cases : use Rx Complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
/**
* @brief DMA UART receive process half complete callback
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
/* Initialize type of RxEvent that correspond to RxEvent callback execution;
In this case, Rx Event type is Half Transfer */
huart->RxEventType = HAL_UART_RXEVENT_HT;
/* Check current reception Mode :
If Reception till IDLE event has been selected : use Rx Event callback */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize / 2U);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
else
{
/* In other cases : use Rx Half Complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Half complete callback*/
huart->RxHalfCpltCallback(huart);
#else
/*Call legacy weak Rx Half complete callback*/
HAL_UART_RxHalfCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
/**
* @brief DMA UART communication error callback.
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMAError(DMA_HandleTypeDef *hdma)
{
uint32_t dmarequest = 0x00U;
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
/* Stop UART DMA Tx request if ongoing */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
{
huart->TxXferCount = 0x00U;
UART_EndTxTransfer(huart);
}
/* Stop UART DMA Rx request if ongoing */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
{
huart->RxXferCount = 0x00U;
UART_EndRxTransfer(huart);
}
huart->ErrorCode |= HAL_UART_ERROR_DMA;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief This function handles UART Communication Timeout. It waits
* until a flag is no longer in the specified status.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param Flag specifies the UART flag to check.
* @param Status The actual Flag status (SET or RESET).
* @param Tickstart Tick start value
* @param Timeout Timeout duration
* @retval HAL status
*/
static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
uint32_t Tickstart, uint32_t Timeout)
{
/* Wait until flag is set */
while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
{
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
return HAL_TIMEOUT;
}
if ((READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC))
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
{
/* Clear Overrun Error flag*/
__HAL_UART_CLEAR_OREFLAG(huart);
/* Blocking error : transfer is aborted
Set the UART state ready to be able to start again the process,
Disable Rx Interrupts if ongoing */
UART_EndRxTransfer(huart);
huart->ErrorCode = HAL_UART_ERROR_ORE;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_ERROR;
}
}
}
}
return HAL_OK;
}
/**
* @brief Start Receive operation in interrupt mode.
* @note This function could be called by all HAL UART API providing reception in Interrupt mode.
* @note When calling this function, parameters validity is considered as already checked,
* i.e. Rx State, buffer address, ...
* UART Handle is assumed as Locked.
* @param huart UART handle.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @retval HAL status
*/
HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
if (huart->Init.Parity != UART_PARITY_NONE)
{
/* Enable the UART Parity Error Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_PE);
}
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
/* Enable the UART Data Register not empty Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
return HAL_OK;
}
/**
* @brief Start Receive operation in DMA mode.
* @note This function could be called by all HAL UART API providing reception in DMA mode.
* @note When calling this function, parameters validity is considered as already checked,
* i.e. Rx State, buffer address, ...
* UART Handle is assumed as Locked.
* @param huart UART handle.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @retval HAL status
*/
HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
/* Set the UART DMA transfer complete callback */
huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
/* Set the DMA error callback */
huart->hdmarx->XferErrorCallback = UART_DMAError;
/* Set the DMA abort callback */
huart->hdmarx->XferAbortCallback = NULL;
/* Enable the DMA stream */
tmp = (uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t *)tmp, Size);
/* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
__HAL_UART_CLEAR_OREFLAG(huart);
if (huart->Init.Parity != UART_PARITY_NONE)
{
/* Enable the UART Parity Error Interrupt */
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
}
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
in the UART CR3 register */
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
return HAL_OK;
}
/**
* @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
* @param huart UART handle.
* @retval None
*/
static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
/* At end of Tx process, restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
}
/**
* @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
* @param huart UART handle.
* @retval None
*/
static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
}
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
}
/**
* @brief DMA UART communication abort callback, when initiated by HAL services on Error
* (To be called at end of DMA Abort procedure following error occurrence).
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
huart->RxXferCount = 0x00U;
huart->TxXferCount = 0x00U;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief DMA UART Tx communication abort callback, when initiated by user
* (To be called at end of DMA Tx Abort procedure following user abort request).
* @note When this callback is executed, User Abort complete call back is called only if no
* Abort still ongoing for Rx DMA Handle.
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
huart->hdmatx->XferAbortCallback = NULL;
/* Check if an Abort process is still ongoing */
if (huart->hdmarx != NULL)
{
if (huart->hdmarx->XferAbortCallback != NULL)
{
return;
}
}
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
huart->TxXferCount = 0x00U;
huart->RxXferCount = 0x00U;
/* Reset ErrorCode */
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Restore huart->gState and huart->RxState to Ready */
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Call user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort complete callback */
huart->AbortCpltCallback(huart);
#else
/* Call legacy weak Abort complete callback */
HAL_UART_AbortCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief DMA UART Rx communication abort callback, when initiated by user
* (To be called at end of DMA Rx Abort procedure following user abort request).
* @note When this callback is executed, User Abort complete call back is called only if no
* Abort still ongoing for Tx DMA Handle.
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
huart->hdmarx->XferAbortCallback = NULL;
/* Check if an Abort process is still ongoing */
if (huart->hdmatx != NULL)
{
if (huart->hdmatx->XferAbortCallback != NULL)
{
return;
}
}
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
huart->TxXferCount = 0x00U;
huart->RxXferCount = 0x00U;
/* Reset ErrorCode */
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Restore huart->gState and huart->RxState to Ready */
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Call user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort complete callback */
huart->AbortCpltCallback(huart);
#else
/* Call legacy weak Abort complete callback */
HAL_UART_AbortCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief DMA UART Tx communication abort callback, when initiated by user by a call to
* HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
* (This callback is executed at end of DMA Tx Abort procedure following user abort request,
* and leads to user Tx Abort Complete callback execution).
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
huart->TxXferCount = 0x00U;
/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
/* Call user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Transmit Complete Callback */
huart->AbortTransmitCpltCallback(huart);
#else
/* Call legacy weak Abort Transmit Complete Callback */
HAL_UART_AbortTransmitCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief DMA UART Rx communication abort callback, when initiated by user by a call to
* HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
* (This callback is executed at end of DMA Rx Abort procedure following user abort request,
* and leads to user Rx Abort Complete callback execution).
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
huart->RxXferCount = 0x00U;
/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Call user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Receive Complete Callback */
huart->AbortReceiveCpltCallback(huart);
#else
/* Call legacy weak Abort Receive Complete Callback */
HAL_UART_AbortReceiveCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
/**
* @brief Sends an amount of data in non blocking mode.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
{
const uint16_t *tmp;
/* Check that a Tx process is ongoing */
if (huart->gState == HAL_UART_STATE_BUSY_TX)
{
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
tmp = (const uint16_t *) huart->pTxBuffPtr;
huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
huart->pTxBuffPtr += 2U;
}
else
{
huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
}
if (--huart->TxXferCount == 0U)
{
/* Disable the UART Transmit Data Register Empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
/* Enable the UART Transmit Complete Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Wraps up transmission in non blocking mode.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
{
/* Disable the UART Transmit Complete Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_TC);
/* Tx process is ended, restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Tx complete callback*/
huart->TxCpltCallback(huart);
#else
/*Call legacy weak Tx complete callback*/
HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
/**
* @brief Receives an amount of data in non blocking mode
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint8_t *pdata8bits;
uint16_t *pdata16bits;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (uint16_t *) huart->pRxBuffPtr;
*pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2U;
}
else
{
pdata8bits = (uint8_t *) huart->pRxBuffPtr;
pdata16bits = NULL;
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
huart->pRxBuffPtr += 1U;
}
if (--huart->RxXferCount == 0U)
{
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
/* Initialize type of RxEvent to Transfer Complete */
huart->RxEventType = HAL_UART_RXEVENT_TC;
/* Check current reception Mode :
If Reception till IDLE event has been selected : */
if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
{
/* Set reception type to Standard */
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Disable IDLE interrupt */
ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
/* Check if IDLE flag is set */
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
{
/* Clear IDLE flag in ISR */
__HAL_UART_CLEAR_IDLEFLAG(huart);
}
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx Event callback*/
huart->RxEventCallback(huart, huart->RxXferSize);
#else
/*Call legacy weak Rx Event callback*/
HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
else
{
/* Standard reception API called */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief Configures the UART peripheral.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
static void UART_SetConfig(UART_HandleTypeDef *huart)
{
uint32_t tmpreg;
uint32_t pclk;
/* Check the parameters */
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_MODE(huart->Init.Mode));
/*-------------------------- USART CR2 Configuration -----------------------*/
/* Configure the UART Stop Bits: Set STOP[13:12] bits
according to huart->Init.StopBits value */
MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
/*-------------------------- USART CR1 Configuration -----------------------*/
/* Configure the UART Word Length, Parity and mode:
Set the M bits according to huart->Init.WordLength value
Set PCE and PS bits according to huart->Init.Parity value
Set TE and RE bits according to huart->Init.Mode value
Set OVER8 bit according to huart->Init.OverSampling value */
#if defined(USART_CR1_OVER8)
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
MODIFY_REG(huart->Instance->CR1,
(uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
tmpreg);
#else
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
MODIFY_REG(huart->Instance->CR1,
(uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
tmpreg);
#endif /* USART_CR1_OVER8 */
/*-------------------------- USART CR3 Configuration -----------------------*/
/* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
if(huart->Instance == USART1)
{
pclk = HAL_RCC_GetPCLK2Freq();
}
else
{
pclk = HAL_RCC_GetPCLK1Freq();
}
/*-------------------------- USART BRR Configuration ---------------------*/
#if defined(USART_CR1_OVER8)
if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
{
huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
}
else
{
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
}
#else
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
#endif /* USART_CR1_OVER8 */
}
/**
* @}
*/
#endif /* HAL_UART_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component-->
<events>
</events>
</component_viewer>

View File

@@ -117,6 +117,26 @@
<pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name>(105=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
@@ -125,10 +145,34 @@
<SetRegEntry>
<Number>0</Number>
<Key>ST-LINKIII-KEIL_SWO</Key>
<Name>-U-O142 -O2254 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128 -FS08000000 -FL08000 -FP0($$Device:STM32F103C6$Flash\STM32F10x_128.FLM)</Name>
<Name>-U53FF72064980555724221187 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(1BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL08000 -FP0($$Device:STM32F103C6$Flash\STM32F10x_128.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>tester_adc,0x10</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>ADC_DMA_HalfBuff,0x0A</ItemText>
</Ww>
</WatchWindow1>
<WatchWindow2>
<Ww>
<count>0</count>
<WinNumber>2</WinNumber>
<ItemText>before_pulse_delay</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>2</WinNumber>
<ItemText>pulse_delay</ItemText>
</Ww>
</WatchWindow2>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
@@ -171,6 +215,24 @@
<pszMrulep></pszMrulep>
<pSingCmdsp></pSingCmdsp>
<pMultCmdsp></pMultCmdsp>
<SystemViewers>
<Entry>
<Name>System Viewer\ADC1</Name>
<WinId>35903</WinId>
</Entry>
<Entry>
<Name>System Viewer\DMA1</Name>
<WinId>35902</WinId>
</Entry>
<Entry>
<Name>System Viewer\GPIOA</Name>
<WinId>35904</WinId>
</Entry>
<Entry>
<Name>System Viewer\GPIOC</Name>
<WinId>35905</WinId>
</Entry>
</SystemViewers>
<DebugDescription>
<Enable>1</Enable>
<EnableFlashSeq>0</EnableFlashSeq>
@@ -182,14 +244,250 @@
</Target>
<Group>
<GroupName>Application/MDK-ARM</GroupName>
<tvExp>0</tvExp>
<GroupName>Configs</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>1</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\MyLibs\mylibs_config.h</PathWithFileName>
<FilenameWithoutPath>mylibs_config.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>2</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\interface_config.h</PathWithFileName>
<FilenameWithoutPath>interface_config.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>3</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\MyLibs\mylibs_include.h</PathWithFileName>
<FilenameWithoutPath>mylibs_include.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>4</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Tester_main\tester_config.h</PathWithFileName>
<FilenameWithoutPath>tester_config.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>Tester Main</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Tester_main\tester_adc_func.c</PathWithFileName>
<FilenameWithoutPath>tester_adc_func.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>6</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Tester_main\tester_adc_func.h</PathWithFileName>
<FilenameWithoutPath>tester_adc_func.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>Interfaces</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>7</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\crc_algs.c</PathWithFileName>
<FilenameWithoutPath>crc_algs.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>8</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\crc_algs.h</PathWithFileName>
<FilenameWithoutPath>crc_algs.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>9</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\modbus.c</PathWithFileName>
<FilenameWithoutPath>modbus.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>10</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\modbus.h</PathWithFileName>
<FilenameWithoutPath>modbus.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>11</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\modbus_data.h</PathWithFileName>
<FilenameWithoutPath>modbus_data.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>12</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\rs_message.c</PathWithFileName>
<FilenameWithoutPath>rs_message.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>13</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\Interfaces\rs_message.h</PathWithFileName>
<FilenameWithoutPath>rs_message.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>MyLibs</GroupName>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>14</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\MyLibs\bit_access.h</PathWithFileName>
<FilenameWithoutPath>bit_access.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>15</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\MyLibs\mylibs_defs.h</PathWithFileName>
<FilenameWithoutPath>mylibs_defs.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>16</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\MyLibs\trace.h</PathWithFileName>
<FilenameWithoutPath>trace.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>17</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Core\MyLibs\trackers.h</PathWithFileName>
<FilenameWithoutPath>trackers.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>Application/MDK-ARM</GroupName>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>18</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -208,8 +506,8 @@
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>2</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -220,8 +518,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>3</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -232,8 +530,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>4</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -244,8 +542,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>5</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -256,8 +554,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>6</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -268,8 +566,20 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>7</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Core/Src/usart.c</PathWithFileName>
<FilenameWithoutPath>usart.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -280,8 +590,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>8</FileNumber>
<GroupNumber>6</GroupNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -300,8 +610,8 @@
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>9</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -312,8 +622,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>10</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -324,8 +634,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>11</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>29</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -336,8 +646,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>12</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -348,8 +658,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>13</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -360,8 +670,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>14</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -372,8 +682,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>15</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -384,8 +694,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>16</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>34</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -396,8 +706,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>17</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>35</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -408,8 +718,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>36</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -420,8 +730,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>19</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>37</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -432,8 +742,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>38</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -444,8 +754,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -456,8 +766,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>40</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -468,8 +778,8 @@
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber>
<GroupNumber>7</GroupNumber>
<FileNumber>41</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -479,6 +789,18 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>42</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c</PathWithFileName>
<FilenameWithoutPath>stm32f1xx_hal_uart.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
@@ -488,8 +810,8 @@
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>24</FileNumber>
<GroupNumber>8</GroupNumber>
<FileNumber>43</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>

View File

@@ -82,7 +82,7 @@
</BeforeMake>
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<RunUserProg2>1</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
@@ -341,7 +341,7 @@
<MiscControls></MiscControls>
<Define>USE_HAL_DRIVER,STM32F103x6</Define>
<Undefine></Undefine>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include</IncludePath>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Core/MyLibs;../Core/Interfaces;../Core/Tester_main</IncludePath>
</VariousControls>
</Cads>
<Aads>
@@ -382,6 +382,111 @@
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>Configs</GroupName>
<Files>
<File>
<FileName>mylibs_config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\MyLibs\mylibs_config.h</FilePath>
</File>
<File>
<FileName>interface_config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Interfaces\interface_config.h</FilePath>
</File>
<File>
<FileName>mylibs_include.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\MyLibs\mylibs_include.h</FilePath>
</File>
<File>
<FileName>tester_config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Tester_main\tester_config.h</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Tester Main</GroupName>
<Files>
<File>
<FileName>tester_adc_func.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Tester_main\tester_adc_func.c</FilePath>
</File>
<File>
<FileName>tester_adc_func.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Tester_main\tester_adc_func.h</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Interfaces</GroupName>
<Files>
<File>
<FileName>crc_algs.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Interfaces\crc_algs.c</FilePath>
</File>
<File>
<FileName>crc_algs.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Interfaces\crc_algs.h</FilePath>
</File>
<File>
<FileName>modbus.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Interfaces\modbus.c</FilePath>
</File>
<File>
<FileName>modbus.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Interfaces\modbus.h</FilePath>
</File>
<File>
<FileName>modbus_data.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Interfaces\modbus_data.h</FilePath>
</File>
<File>
<FileName>rs_message.c</FileName>
<FileType>1</FileType>
<FilePath>..\Core\Interfaces\rs_message.c</FilePath>
</File>
<File>
<FileName>rs_message.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\Interfaces\rs_message.h</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>MyLibs</GroupName>
<Files>
<File>
<FileName>bit_access.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\MyLibs\bit_access.h</FilePath>
</File>
<File>
<FileName>mylibs_defs.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\MyLibs\mylibs_defs.h</FilePath>
</File>
<File>
<FileName>trace.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\MyLibs\trace.h</FilePath>
</File>
<File>
<FileName>trackers.h</FileName>
<FileType>5</FileType>
<FilePath>..\Core\MyLibs\trackers.h</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Application/MDK-ARM</GroupName>
<Files>
@@ -522,6 +627,62 @@
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>usart.c</FileName>
<FileType>1</FileType>
<FilePath>../Core/Src/usart.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>stm32f1xx_it.c</FileName>
<FileType>1</FileType>
@@ -612,6 +773,62 @@
<FileType>1</FileType>
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c</FilePath>
</File>
<File>
<FileName>stm32f1xx_hal_uart.c</FileName>
<FileType>1</FileType>
<FilePath>../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
</Files>
</Group>
<Group>

View File

@@ -1,7 +1,8 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_0
ADC1.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO
ADC1.IPParameters=Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,NbrOfConversionFlag,master,ExternalTrigConv
ADC1.ContinuousConvMode=ENABLE
ADC1.ExternalTrigConv=ADC_SOFTWARE_START
ADC1.IPParameters=Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,NbrOfConversionFlag,master,ExternalTrigConv,ContinuousConvMode
ADC1.NbrOfConversionFlag=1
ADC1.Rank-3\#ChannelRegularConversion=1
ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_1CYCLE_5
@@ -13,7 +14,7 @@ Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.Instance=DMA1_Channel1
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
Dma.ADC1.0.Mode=DMA_NORMAL
Dma.ADC1.0.Mode=DMA_CIRCULAR
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
@@ -30,18 +31,24 @@ Mcu.IP1=DMA
Mcu.IP2=NVIC
Mcu.IP3=RCC
Mcu.IP4=SYS
Mcu.IP5=TIM3
Mcu.IPNb=6
Mcu.IP5=TIM2
Mcu.IP6=TIM3
Mcu.IP7=USART1
Mcu.IPNb=8
Mcu.Name=STM32F103C(4-6)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PD0-OSC_IN
Mcu.Pin1=PD1-OSC_OUT
Mcu.Pin2=PA0-WKUP
Mcu.Pin3=PA13
Mcu.Pin4=PA14
Mcu.Pin5=VP_SYS_VS_Systick
Mcu.Pin6=VP_TIM3_VS_ClockSourceINT
Mcu.PinsNb=7
Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PD0-OSC_IN
Mcu.Pin10=VP_TIM3_VS_ClockSourceINT
Mcu.Pin2=PD1-OSC_OUT
Mcu.Pin3=PA0-WKUP
Mcu.Pin4=PA9
Mcu.Pin5=PA10
Mcu.Pin6=PA13
Mcu.Pin7=PA14
Mcu.Pin8=VP_SYS_VS_Systick
Mcu.Pin9=VP_TIM2_VS_ClockSourceINT
Mcu.PinsNb=11
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103C6Tx
@@ -58,13 +65,21 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.TIM3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA0-WKUP.Signal=ADCx_IN0
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PC13-TAMPER-RTC.Locked=true
PC13-TAMPER-RTC.Signal=GPIO_Output
PD0-OSC_IN.Mode=HSE-External-Oscillator
PD0-OSC_IN.Signal=RCC_OSC_IN
PD1-OSC_OUT.Mode=HSE-External-Oscillator
@@ -100,7 +115,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_TIM2_Init-TIM2-false-HAL-true
RCC.ADCFreqValue=12000000
RCC.ADCPresc=RCC_ADCPCLK2_DIV6
RCC.AHBFreq_Value=72000000
@@ -129,8 +144,12 @@ TIM3.IPParameters=Period,Prescaler,TIM_MasterOutputTrigger
TIM3.Period=8999
TIM3.Prescaler=0
TIM3.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM2_VS_ClockSourceINT.Mode=Internal
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
board=custom