документация выделена в отдельную ветку
This commit is contained in:
		
							parent
							
								
									03a203fe2a
								
							
						
					
					
						commit
						81a0b1c010
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +0,0 @@
 | 
			
		||||
/MyLibsGeneral/.vscode/
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
/**************************************************************************
 | 
			
		||||
* @file general_flash.h
 | 
			
		||||
* @brief Заголовочны файл модуля работы с FLASH.
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __FLASH_GENERAL_H_
 | 
			
		||||
#define __FLASH_GENERAL_H_
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
                      
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
 | 
			
		||||
HAL_StatusTypeDef FLASH_Enable_DualBankMode(void);
 | 
			
		||||
HAL_StatusTypeDef FLASH_WriteProtection(uint32_t BankN, uint32_t WriteProtection);
 | 
			
		||||
/* functions for reading bytes/halswords/words */
 | 
			
		||||
uint8_t FLASH_Read_Byte(uint32_t add);
 | 
			
		||||
uint16_t FLASH_Read_HalfWord(uint32_t add);
 | 
			
		||||
uint32_t FLASH_Read_Word(uint32_t add);
 | 
			
		||||
/* functions for writing bytes/halswords/words */
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_Byte(uint32_t Address, uint8_t Data);
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_HalfWord(uint32_t Address, uint16_t Data);
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_Word(uint32_t Address, uint32_t Data);
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
 | 
			
		||||
#endif // __FLASH_GENERAL_H_
 | 
			
		||||
@ -1,100 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_spi.h
 | 
			
		||||
* @brief Заголовочны файл модуля инициализации SPI.
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __SPI_GENERAL_H_
 | 
			
		||||
#define __SPI_GENERAL_H_
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
#define HAL_SPI_MODULE_ENABLED  // need to uncomment these defines in stm32f4xx_hal_conf.h
 | 
			
		||||
                                // also need to add hal_spi.c (source code)
 | 
			
		||||
 | 
			
		||||
#define USE_SPI1
 | 
			
		||||
#define USE_SPI2
 | 
			
		||||
#define USE_SPI3
 | 
			
		||||
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                              
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
typedef struct // struct with settings for custom function
 | 
			
		||||
{
 | 
			
		||||
  SPI_HandleTypeDef hspi;
 | 
			
		||||
  
 | 
			
		||||
  GPIO_TypeDef  *CLK_GPIOx;
 | 
			
		||||
  uint32_t      CLK_PIN;
 | 
			
		||||
  uint32_t      CLK_GPIO_AlternageFunc;
 | 
			
		||||
  
 | 
			
		||||
  GPIO_TypeDef  *MISO_GPIOx;
 | 
			
		||||
  uint32_t      MISO_PIN;
 | 
			
		||||
  uint32_t      MISO_GPIO_AlternageFunc;
 | 
			
		||||
  
 | 
			
		||||
  GPIO_TypeDef  *MOSI_GPIOx;
 | 
			
		||||
  uint32_t      MOSI_PIN; 
 | 
			
		||||
  uint32_t      MOSI_GPIO_AlternageFunc;
 | 
			
		||||
  
 | 
			
		||||
}SPI_SettingsTypeDef;
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize SPI with SPI_SettingsTypeDef structure.
 | 
			
		||||
  * @param  sspi - указатель на структуру с настройками SPI.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   Данная структура содержит хендл ЮАРТ и настройки перефирии (GPIO)
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef SPI_Base_Init(SPI_SettingsTypeDef *sspi);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize GPIO for SPI.
 | 
			
		||||
  * @param  GPIOx       - порт для настройки.
 | 
			
		||||
  * @param  GPIO_PIN_RX - пин для настройки на прием.
 | 
			
		||||
  * @param  GPIO_PIN_TX - пин для настройки на передачу.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_GPIO_Init(SPI_SettingsTypeDef *sspi);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize DMA for SPI.
 | 
			
		||||
  * @param  hspi        - указатель на хендл SPI для настройки DMA.
 | 
			
		||||
  * @param  hdma_rx       - указатель на хендл DMA для линии приема SPI.
 | 
			
		||||
  * @param  DMAChannel    - указатель на канал DMA/поток DMA в STM32F407.
 | 
			
		||||
  * @param  DMA_CHANNEL_X - канал DMA.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_DMA_Init(SPI_HandleTypeDef *hspi, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize SPI & DMA clock and interrupt.
 | 
			
		||||
  * @param  hspi - указатель на хендл SPI для инициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с иницилизацией неиспользуемых SPI,
 | 
			
		||||
            дефайнами определяются используемые SPI.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_MspInit(SPI_HandleTypeDef *hspi);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Deinitialize SPI & DMA clock and interrupt.
 | 
			
		||||
  * @param  hspi - указатель на хендл SPI для деинициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с деиницилизацией неиспользуемых SPI,
 | 
			
		||||
            дефайнами в rs_message.h определяются используемые SPI.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_MspDeInit(SPI_HandleTypeDef *hspi);
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Check that spi init structure have correct values.
 | 
			
		||||
  * @param  sspi - указатель на структуру с настройками SPI.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef Check_SPI_Init_Struct(SPI_SettingsTypeDef *sspi);
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
 | 
			
		||||
#endif // __SPI_GENERAL_H_
 | 
			
		||||
@ -1,108 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_uart.h
 | 
			
		||||
* @brief Заголовочный файл для модуля инициализации UART.
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __UART_GENERAL_H_
 | 
			
		||||
#define __UART_GENERAL_H_
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
#define HAL_UART_MODULE_ENABLED   // need to uncomment these defines in stm32f4xx_hal_conf.h
 | 
			
		||||
//#define HAL_USART_MODULE_ENABLED  // maybe also need to add hal_uart.h/.c (source code)
 | 
			
		||||
 | 
			
		||||
//#define USE_USART1
 | 
			
		||||
//#define USE_USART2
 | 
			
		||||
//#define USE_USART3
 | 
			
		||||
//#define USE_UART4
 | 
			
		||||
//#define USE_UART5
 | 
			
		||||
//#define USE_USART6
 | 
			
		||||
/* note: used uart defines in modbus.h */
 | 
			
		||||
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
#include "interface_config.h" /* used uart defines in modbus.h */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Analog for HAL define. Remade with pointer to structure.
 | 
			
		||||
  * @note   @ref __HAL_LINKDMA.
 | 
			
		||||
  */
 | 
			
		||||
#define __USER_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__)   \
 | 
			
		||||
do{                                                                     \
 | 
			
		||||
(__HANDLE__)->__PPP_DMA_FIELD__ = (__DMA_HANDLE__);                     \
 | 
			
		||||
(__DMA_HANDLE__)->Parent = (__HANDLE__);} while(0U)
 | 
			
		||||
 | 
			
		||||
                              
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
typedef struct // struct with settings for custom function
 | 
			
		||||
{
 | 
			
		||||
  UART_HandleTypeDef huart;
 | 
			
		||||
  
 | 
			
		||||
  GPIO_TypeDef *GPIOx;
 | 
			
		||||
  uint16_t GPIO_PIN_RX;
 | 
			
		||||
  uint16_t GPIO_PIN_TX;
 | 
			
		||||
  
 | 
			
		||||
  DMA_Stream_TypeDef *DMAChannel; // DMAChannel = 0 if doesnt need
 | 
			
		||||
  uint32_t DMA_CHANNEL_X; // DMAChannel = 0 if doesnt need
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
}UART_SettingsTypeDef;
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize UART with UART_SettingsTypeDef structure.
 | 
			
		||||
  * @param  suart - указатель на структуру с настройками UART.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   Данная структура содержит хендл ЮАРТ и настройки перефирии (GPIO)
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef UART_Base_Init(UART_SettingsTypeDef *suart);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize GPIO for UART.
 | 
			
		||||
  * @param  GPIOx       - порт для настройки.
 | 
			
		||||
  * @param  GPIO_PIN_RX - пин для настройки на прием.
 | 
			
		||||
  * @param  GPIO_PIN_TX - пин для настройки на передачу.
 | 
			
		||||
  */
 | 
			
		||||
void UART_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN_RX, uint16_t GPIO_PIN_TX);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize DMA for UART.
 | 
			
		||||
  * @param  huart         - указатель на хендл UART для настройки DMA.
 | 
			
		||||
  * @param  hdma_rx       - указатель на хендл DMA для линии приема UART.
 | 
			
		||||
  * @param  DMAChannel    - указатель на канал DMA/поток DMA в STM32F407.
 | 
			
		||||
  * @param  DMA_CHANNEL_X - канал DMA.
 | 
			
		||||
  */
 | 
			
		||||
void UART_DMA_Init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize UART & DMA clock and interrupt.
 | 
			
		||||
  * @param  huart - указатель на хендл UART для инициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с иницилизацией неиспользуемых UART,
 | 
			
		||||
            дефайнами определяются используемые UART.
 | 
			
		||||
  */
 | 
			
		||||
void UART_MspInit(UART_HandleTypeDef *huart);
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Deinitialize UART & DMA clock and interrupt.
 | 
			
		||||
  * @param  huart - указатель на хендл UART для деинициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с деиницилизацией неиспользуемых UART,
 | 
			
		||||
            дефайнами в rs_message.h определяются используемые UART.
 | 
			
		||||
  */
 | 
			
		||||
void UART_MspDeInit(UART_HandleTypeDef *huart);
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Check that uart init structure have correct values.
 | 
			
		||||
  * @param  suart - указатель на структуру с настройками UART.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  */ 
 | 
			
		||||
HAL_StatusTypeDef Check_UART_Init_Struct(UART_SettingsTypeDef *suart);
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
 | 
			
		||||
#endif // __UART_GENERAL_H_
 | 
			
		||||
@ -1,159 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file bit_access.h
 | 
			
		||||
* @brief Заголочный файл для дефайнов битового доступа.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @defgroup BIT_ACCESS_DEFINES    Bit access defines
 | 
			
		||||
* @ingroup  MYLIBS_DEFINES
 | 
			
		||||
* @brief     Макросы и typedef'ы для работы с битами в unsigned типах.
 | 
			
		||||
* @details
 | 
			
		||||
В этом файле определены макросы для получения значения конкретного бита^
 | 
			
		||||
- @ref uint8_bit
 | 
			
		||||
- @ref uint16_bit
 | 
			
		||||
- @ref uint32_bit
 | 
			
		||||
- @ref uint64_bit
 | 
			
		||||
 | 
			
		||||
Особенности использования:
 | 
			
		||||
- Индекс бита должен быть **константой на этапе компиляции**.
 | 
			
		||||
  Пример верного использования:
 | 
			
		||||
    @code
 | 
			
		||||
      uint8_t val = 0x05;
 | 
			
		||||
      uint8_t b2 = uint8_bit(val, 2); // Получить бит 2
 | 
			
		||||
      uint8_bit(val, 6) = 1; // Записать бит 6
 | 
			
		||||
    @endcode
 | 
			
		||||
- Нельзя использовать переменные в качестве индекса:
 | 
			
		||||
    @code
 | 
			
		||||
      uint8_t i = 2;
 | 
			
		||||
      uint8_bit(val, i); // Не сработает!
 | 
			
		||||
    @endcode
 | 
			
		||||
- Макросы возвращают 0 или 1.
 | 
			
		||||
- Доступ реализован через приведение к `union` с битовыми полями, поэтому это
 | 
			
		||||
  безопасный способ работы с отдельными битами без ручного сдвига и маскирования.
 | 
			
		||||
* @{
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __BIT_ACCESS_H_
 | 
			
		||||
#define __BIT_ACCESS_H_
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Получить n-й бит из uint8_t
 | 
			
		||||
  * @param _uint8_ Переменная типа uint8_t
 | 
			
		||||
  * @param _bit_   Константный номер бита (0..7)
 | 
			
		||||
  * @return Значение выбранного бита (0 или 1)
 | 
			
		||||
  * @note    Индекс бита должен быть известен на этапе компиляции!
 | 
			
		||||
  */
 | 
			
		||||
#define uint8_bit(_uint8_, _bit_)       (*(uint8_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Получить n-й бит из uint16_t
 | 
			
		||||
  * @param _uint16_ Переменная типа uint16_t
 | 
			
		||||
  * @param _bit_    Константный номер бита (0..15)
 | 
			
		||||
  * @return Значение выбранного бита (0 или 1)
 | 
			
		||||
  * @note    Индекс бита должен быть известен на этапе компиляции!
 | 
			
		||||
  */
 | 
			
		||||
#define uint16_bit(_uint8_, _bit_)      (*(uint16_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Получить n-й бит из uint32_t
 | 
			
		||||
  * @param _uint32_ Переменная типа uint32_t
 | 
			
		||||
  * @param _bit_    Константный номер бита (0..31)
 | 
			
		||||
  * @return Значение выбранного бита (0 или 1)
 | 
			
		||||
  * @note    Индекс бита должен быть известен на этапе компиляции!
 | 
			
		||||
  */
 | 
			
		||||
#define uint32_bit(_uint8_, _bit_)      (*(uint32_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Получить n-й бит из uint64_t
 | 
			
		||||
  * @param _uint64_ Переменная типа uint64_t
 | 
			
		||||
  * @param _bit_    Константный номер бита (0..63)
 | 
			
		||||
  * @return Значение выбранного бита (0 или 1)
 | 
			
		||||
  * @note    Индекс бита должен быть известен на этапе компиляции!
 | 
			
		||||
  */
 | 
			
		||||
#define uint64_bit(_uint8_, _bit_)      (*(uint64_BitTypeDef *)(&(_uint8_))).bit.bit##_bit_
 | 
			
		||||
 | 
			
		||||
#endif //__BIT_ACCESS_H_ 
 | 
			
		||||
 | 
			
		||||
/** BIT_ACCESS_DEFINES
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
@ -1,338 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
******************************************************************************
 | 
			
		||||
* @file evolve_optimizer.h
 | 
			
		||||
* @brief Заголовочный файл для адаптивного подбора параметров
 | 
			
		||||
******************************************************************************
 | 
			
		||||
* @addtogroup EVOLVE_OPTIMIZER    Evolve optimizer
 | 
			
		||||
* @ingroup    MYLIBS_DEFINES
 | 
			
		||||
* @brief      Библиотека для эволюционного подбора параметров
 | 
			
		||||
* @details
 | 
			
		||||
Поддерживает:
 | 
			
		||||
- Любое количество параметров
 | 
			
		||||
- Генерацию новых параметров на основе лучших кандидатов
 | 
			
		||||
- Мутацию для поиска оптимальных параметров
 | 
			
		||||
- Несколько независимых оптимизаторов в одной программе
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Параметры для конфигурации:
 | 
			
		||||
- @ref ENABLE_EVOLVE_OPTIMIZATION - Включить оптимизацию параметров
 | 
			
		||||
  Если библиотека отключена @ref ENABLE_EVOLVE_OPTIMIZATION, то вставляются 
 | 
			
		||||
  заглушки, никак не влияющие на параметры и остальную программу
 | 
			
		||||
- @ref EVOLVE_MAX_PARAMS          - Максимальное количество параметров
 | 
			
		||||
- @ref EVOLVE_MAX_CANDIDATES      - Максимальное количество кандидатов для обучения
 | 
			
		||||
- (опционально) @ref EVOLVE_MUTATION_MIN_PCT    - Минимальная мутация в процентах от Loss (по умолчанию 10%)
 | 
			
		||||
- (опционально) @ref EVOLVE_MUTATION_MAX_PCT    - Максимальная мутация в процентах от Loss (по умолчанию 100%)
 | 
			
		||||
- (опционально) @ref ELOVLE_N_ELITE_CANDIDATE   - Количество кандидатов, которые проходят в поколение без изменений
 | 
			
		||||
 | 
			
		||||
@par Пример использования:
 | 
			
		||||
@code
 | 
			
		||||
#include "evolve_optimizer.h"
 | 
			
		||||
#define N_PARAMS        4
 | 
			
		||||
#define N_CANDIDATES    100
 | 
			
		||||
#define N_BEST          10
 | 
			
		||||
#define MUTATION        0.1f
 | 
			
		||||
float params[N_PARAMS];
 | 
			
		||||
EvolveOptimizer_t optimizer;
 | 
			
		||||
 | 
			
		||||
// Формирование параметров
 | 
			
		||||
uint16_t  param_u16 = 800;
 | 
			
		||||
float     param_f   = 0.01f;
 | 
			
		||||
uint8_t   param_u8  = 40;
 | 
			
		||||
int16_t   param_i16 = 1600;
 | 
			
		||||
params[0] = PARAM_SCALE(param_u16,  0.0f,   1000.0f);
 | 
			
		||||
params[1] = PARAM_SCALE(param_f,    0.001f, 0.1f);
 | 
			
		||||
params[2] = PARAM_SCALE(param_u8,   10.0f,  100.0f);
 | 
			
		||||
params[3] = PARAM_SCALE(param_i16,  500.0f, 5000.0f);
 | 
			
		||||
 | 
			
		||||
// Инициалиазция
 | 
			
		||||
EvolveOptimizer_Init(&optimizer, N_PARAMS, N_CANDIDATES, N_BEST, MUTATION, params);
 | 
			
		||||
 | 
			
		||||
// Шаг эволюции
 | 
			
		||||
float loss = calc_loss(); // расчет эффективности параметров (от 0 до 1)
 | 
			
		||||
EvolveOptimizer_Step(&optimizer, params, loss);
 | 
			
		||||
 | 
			
		||||
// Взятие следующих для эволюции параметров
 | 
			
		||||
param_u16 = PARAM_UNSCALE(params[0],  0.0f,   1000.0f);
 | 
			
		||||
param_f   = PARAM_UNSCALE(params[1],  0.001f, 0.1f);
 | 
			
		||||
param_u8  = PARAM_UNSCALE(params[2],  10.0f,  100.0f);
 | 
			
		||||
param_i16 = PARAM_UNSCALE(params[3],  500.0f, 5000.0f);
 | 
			
		||||
@endcode
 | 
			
		||||
* @{  
 | 
			
		||||
*****************************************************************************/
 | 
			
		||||
#ifndef __EVOLVE_OPTIMIZER_H_
 | 
			
		||||
#define __EVOLVE_OPTIMIZER_H_
 | 
			
		||||
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_EVOLVE_OPTIMIZATION
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Линейное масштабирование x из диапазона [min_val, max_val] в диапазон [0, 1)
 | 
			
		||||
  */
 | 
			
		||||
#define PARAM_SCALE(x, min_val, max_val) \
 | 
			
		||||
(((float)(x) - (float)(min_val)) / ((float)(max_val) - (float)(min_val)))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Обратное линейное масштабирование значения из [0, 1) в диапазон [min_val, max_val]
 | 
			
		||||
  */
 | 
			
		||||
#define PARAM_UNSCALE(val, min_val, max_val) \
 | 
			
		||||
(((float)(val)) * ((float)(max_val) - (float)(min_val)) + (float)(min_val))
 | 
			
		||||
 | 
			
		||||
#ifndef local_time
 | 
			
		||||
#define local_time()  HAL_GetTick() ///< Локальное время
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef EVOLVE_MUTATION_MIN_PCT
 | 
			
		||||
#define EVOLVE_MUTATION_MIN_PCT   10    ///< Минимальная мутация (в процентах от Loss)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EVOLVE_MUTATION_MAX_PCT
 | 
			
		||||
#define EVOLVE_MUTATION_MAX_PCT   100   ///< Максимальная мутация (в процентах от Loss)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ELOVLE_N_ELITE_CANDIDATE
 | 
			
		||||
#define ELOVLE_N_ELITE_CANDIDATE  2     ///< Количество кандидатов, которые проходят в поколение без изменений (по умолчанию 2)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Структура эволюционного оптимизатора
 | 
			
		||||
  */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  float     stability;                      ///< Коэффициент насколько стабильная популяция (0..1)(@ref n_cand)
 | 
			
		||||
 | 
			
		||||
  uint16_t  n_params;                       ///< Количество параметров
 | 
			
		||||
  uint16_t  n_cand;                         ///< Количество кандидатов в популяции
 | 
			
		||||
  uint16_t  n_best;                         ///< Количество лучших, усредняемых
 | 
			
		||||
  float     mutation_amp;                   ///< Амплитуда мутации (0..1)
 | 
			
		||||
  
 | 
			
		||||
  uint16_t  cand_index;                     ///< Индекс кандидата для обработки
 | 
			
		||||
  uint16_t  gen_index;                      ///< Индекс популяции  
 | 
			
		||||
  
 | 
			
		||||
  //INTERNAL
 | 
			
		||||
  float     gen_mut;                        ///< Амплитуда мутации у текущей популяции  
 | 
			
		||||
  
 | 
			
		||||
  float     loss[EVOLVE_MAX_CANDIDATES];    ///< Loss для каждого кандидата
 | 
			
		||||
  float     candidates[EVOLVE_MAX_CANDIDATES][EVOLVE_MAX_PARAMS]; ///< Параметры кандидатов
 | 
			
		||||
  uint16_t  sorted_idx[EVOLVE_MAX_CANDIDATES]; ///< Индексы отсортированных кандидатов
 | 
			
		||||
} EvolveOptimizer_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * @cond EVOLVE_INTERNAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Вспомогательный указатель для сортировки
 | 
			
		||||
static EvolveOptimizer_t *g_sort_opt; // глобальный указатель на текущий оптимизатор
 | 
			
		||||
 | 
			
		||||
// функция условия сортировки
 | 
			
		||||
static int cmp_idx(const void *a, const void *b) {
 | 
			
		||||
  if (g_sort_opt->loss[*(const uint16_t*)a] < g_sort_opt->loss[*(const uint16_t*)b]) 
 | 
			
		||||
    return -1;
 | 
			
		||||
  if (g_sort_opt->loss[*(const uint16_t*)a] > g_sort_opt->loss[*(const uint16_t*)b]) 
 | 
			
		||||
    return 1;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
/** @endcond */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Инициализация эволюционного оптимизатора.
 | 
			
		||||
  * @param opt          Указатель на структуру оптимизатора
 | 
			
		||||
  * @param n_params     Количество параметров в одном кандидате
 | 
			
		||||
  * @param n_cand       Количество кандидатов
 | 
			
		||||
  * @param n_best       Количество лучших, усредняемых
 | 
			
		||||
  * @param mutation_amp Амплитуда мутации (в диапазоне 0.0–1.0)
 | 
			
		||||
  * @param start_params Начальные параметры (в диапазоне 0.0–1.0)
 | 
			
		||||
  * @return 0   — если окей, 
 | 
			
		||||
  *         -1  — если ошибка
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt,
 | 
			
		||||
                                        uint16_t n_params,
 | 
			
		||||
                                        uint16_t n_cand,
 | 
			
		||||
                                        uint16_t n_best,
 | 
			
		||||
                                        float mutation_amp,
 | 
			
		||||
                                        float* start_params)
 | 
			
		||||
{
 | 
			
		||||
  if((opt == NULL) || (start_params == NULL))
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  if(n_params > EVOLVE_MAX_PARAMS)
 | 
			
		||||
    return -1;  
 | 
			
		||||
  opt->n_params     = n_params;
 | 
			
		||||
  
 | 
			
		||||
  if(n_cand > EVOLVE_MAX_CANDIDATES)
 | 
			
		||||
    return -1;  
 | 
			
		||||
  opt->n_cand       = n_cand;
 | 
			
		||||
  
 | 
			
		||||
  if(n_best > EVOLVE_MAX_CANDIDATES/2)
 | 
			
		||||
    return -1;  
 | 
			
		||||
  opt->n_best       = n_best;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  if((mutation_amp > 1) || (mutation_amp < 0))
 | 
			
		||||
    return -1;    
 | 
			
		||||
  if(mutation_amp <= 0.001f)
 | 
			
		||||
    mutation_amp = 0.001f;  
 | 
			
		||||
  opt->mutation_amp  = mutation_amp;
 | 
			
		||||
 | 
			
		||||
  uint32_t seed = local_time();
 | 
			
		||||
#ifdef ADC1
 | 
			
		||||
  seed += (ADC1->DR & 0xFF);
 | 
			
		||||
#endif
 | 
			
		||||
  srand(seed);
 | 
			
		||||
  
 | 
			
		||||
  for (uint16_t i = 0; i < n_cand; i++) {
 | 
			
		||||
    for (uint16_t j = 0; j < n_params; j++) {
 | 
			
		||||
      // Добавляем случайную мутацию вокруг стартового параметра
 | 
			
		||||
      float base = start_params[j];
 | 
			
		||||
      float inv_randmax = 1.0f / (float)RAND_MAX;
 | 
			
		||||
      float noise = ((float)rand() * inv_randmax * 2.0f - 1.0f) * mutation_amp;
 | 
			
		||||
      opt->candidates[i][j] = base + noise;
 | 
			
		||||
      if (opt->candidates[i][j] < 0.0f) opt->candidates[i][j] = 0.0f;
 | 
			
		||||
      if (opt->candidates[i][j] > 1.0f) opt->candidates[i][j] = 1.0f;
 | 
			
		||||
    }
 | 
			
		||||
    opt->loss[i] = 0.0f;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  opt->cand_index = 0;
 | 
			
		||||
  opt->gen_index = 0;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Один шаг эволюционного оптимизатора.
 | 
			
		||||
  * @param opt    Указатель на структуру оптимизатора
 | 
			
		||||
  * @param params Массив параметров, которые будут обновлены (на выходе — новые параметры)
 | 
			
		||||
  * @param loss   Loss текущего кандидата
 | 
			
		||||
  * @return 0   — если окей, 
 | 
			
		||||
  *         -1  — если ошибка
 | 
			
		||||
  * @details
 | 
			
		||||
  * Сохраняет loss текущего кандидата и формирует параметры следующего кандидата.
 | 
			
		||||
  * Если накоплено n_cand кандидатов, генерируется новое поколение.
 | 
			
		||||
  * Новое поколение формируется случайным выбором из n_best лучших с добавлением мутации.
 | 
			
		||||
  *
 | 
			
		||||
  * На выходе params содержит параметры следующего кандидата для измерений.
 | 
			
		||||
  * @note Функция использует глобальную внутреннюю переменную для сортировки.
 | 
			
		||||
  * Надо убедится что только один экземпляр функции запущен в момент времени
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt,
 | 
			
		||||
                                        float* params,
 | 
			
		||||
                                        float loss)
 | 
			
		||||
{
 | 
			
		||||
  if((opt == NULL) || (params == NULL))
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  uint16_t n_params = opt->n_params; 
 | 
			
		||||
  if(n_params > EVOLVE_MAX_PARAMS)
 | 
			
		||||
    return -1;  
 | 
			
		||||
  
 | 
			
		||||
  uint16_t n_cand = opt->n_cand; 
 | 
			
		||||
  if(n_cand > EVOLVE_MAX_CANDIDATES)
 | 
			
		||||
    return -1;  
 | 
			
		||||
  
 | 
			
		||||
  uint16_t n_best = opt->n_best; 
 | 
			
		||||
  if(n_best > EVOLVE_MAX_CANDIDATES/2)
 | 
			
		||||
    return -1;
 | 
			
		||||
  
 | 
			
		||||
  float    mut      = opt->mutation_amp;
 | 
			
		||||
  if((mut > 1) ||(mut < 0))
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  // 1. Сохраняем loss текущего кандидата
 | 
			
		||||
  opt->loss[opt->cand_index] = loss;
 | 
			
		||||
  opt->cand_index++;
 | 
			
		||||
 | 
			
		||||
  if (opt->cand_index >= n_cand) {
 | 
			
		||||
    // 2. Сортируем текущее поколение по loss
 | 
			
		||||
    for(uint16_t i = 0; i < opt->n_cand; i++)
 | 
			
		||||
      opt->sorted_idx[i] = i;
 | 
			
		||||
    
 | 
			
		||||
    g_sort_opt = opt;
 | 
			
		||||
    qsort(opt->sorted_idx, opt->n_cand, sizeof(uint16_t), cmp_idx);
 | 
			
		||||
    g_sort_opt = NULL;
 | 
			
		||||
 | 
			
		||||
    // --- Адаптивная мутация в зависимости от Loss ---
 | 
			
		||||
    float best_loss = opt->loss[opt->sorted_idx[0]];
 | 
			
		||||
    float worst_loss = opt->loss[opt->sorted_idx[opt->n_cand - 1]];
 | 
			
		||||
    float diff = worst_loss - best_loss;
 | 
			
		||||
 | 
			
		||||
    float sum_loss = 0.0f;
 | 
			
		||||
    for (uint16_t i = 0; i < n_cand; i++)
 | 
			
		||||
      sum_loss += opt->loss[i];
 | 
			
		||||
    float avg_loss = sum_loss / (float)n_cand;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    float loss_ratio = (diff > 0.0f) ? ((avg_loss - best_loss) / diff) : 0.5f;
 | 
			
		||||
    if (loss_ratio < 0.0f) loss_ratio = 0.0f;
 | 
			
		||||
    if (loss_ratio > 1.0f) loss_ratio = 1.0f;
 | 
			
		||||
    
 | 
			
		||||
    // Записываем стабильность популяции в структуру
 | 
			
		||||
    if(diff < 0.0f) diff = 0.0f;
 | 
			
		||||
    if(diff > 1.0f) diff = 1.0f;
 | 
			
		||||
    opt->stability = (1.0f - worst_loss) * (1.0f - (worst_loss - best_loss));
 | 
			
		||||
    if(opt->stability < 0.0f) opt->stability = 0.0f;
 | 
			
		||||
    if(opt->stability > 1.0f) opt->stability = 1.0f;
 | 
			
		||||
 | 
			
		||||
    float mut_pct = EVOLVE_MUTATION_MIN_PCT +
 | 
			
		||||
                    (EVOLVE_MUTATION_MAX_PCT - EVOLVE_MUTATION_MIN_PCT) * loss_ratio;
 | 
			
		||||
    float adaptive_mut = mut * (mut_pct / 100.0f);
 | 
			
		||||
    if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f;
 | 
			
		||||
    opt->gen_mut = adaptive_mut;
 | 
			
		||||
 | 
			
		||||
    // 3. Генерируем новое поколение
 | 
			
		||||
    uint16_t n_elite = ELOVLE_N_ELITE_CANDIDATE;
 | 
			
		||||
    for (uint16_t c = 0; c < n_cand; c++) {
 | 
			
		||||
      if (c < n_elite) {
 | 
			
		||||
        for (uint16_t i = 0; i < n_params; i++)
 | 
			
		||||
          opt->candidates[c][i] = opt->candidates[opt->sorted_idx[c]][i];
 | 
			
		||||
        opt->loss[c] = 0.0f;
 | 
			
		||||
      } else {
 | 
			
		||||
        for (uint16_t i = 0; i < n_params; i++) {
 | 
			
		||||
          float inv_randmax = 1.0f / (float)RAND_MAX;
 | 
			
		||||
          float noise = ((float)rand() * inv_randmax * 2.0f - 1.0f) * adaptive_mut;
 | 
			
		||||
          uint16_t parent = opt->sorted_idx[rand() % opt->n_best];
 | 
			
		||||
          opt->candidates[c][i] = opt->candidates[parent][i] + noise;
 | 
			
		||||
          if (opt->candidates[c][i] < 0.0f) opt->candidates[c][i] = 0.0f;
 | 
			
		||||
          if (opt->candidates[c][i] > 1.0f) opt->candidates[c][i] = 1.0f;
 | 
			
		||||
        }
 | 
			
		||||
        opt->loss[c] = 0.0f;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    opt->cand_index = 0;
 | 
			
		||||
    opt->gen_index++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 4. Возвращаем параметры следующего кандидата
 | 
			
		||||
  for (uint16_t i = 0; i < opt->n_params; i++)
 | 
			
		||||
    params[i] = opt->candidates[opt->cand_index][i];
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
#else // ENABLE_EVOLVE_OPTIMIZATION
 | 
			
		||||
//заглушки
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint16_t n_params; 
 | 
			
		||||
  uint16_t n_cand; 
 | 
			
		||||
  uint16_t n_best; 
 | 
			
		||||
  float mutation_amp; 
 | 
			
		||||
  float loss[0]; 
 | 
			
		||||
  float candidates[0][0]; 
 | 
			
		||||
} EvolveOptimizer_t;
 | 
			
		||||
#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params)
 | 
			
		||||
#define EvolveOptimizer_Step(opt, params, LossFunc)
 | 
			
		||||
#define PARAM_SCALE(x, min_val, max_val)         (x)
 | 
			
		||||
#define PARAM_UNSCALE(val, min_val, max_val)     (val)
 | 
			
		||||
#endif // ENABLE_EVOLVE_OPTIMIZATION
 | 
			
		||||
 | 
			
		||||
#endif // __EVOLVE_OPTIMIZER_H_
 | 
			
		||||
 | 
			
		||||
/** EVOLVE_OPTIMIZER
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
@ -1,183 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_gpio.h
 | 
			
		||||
* @brief Заголовочный файл для модуля инициализации портов и работы с ними.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @defgroup MY_LIBS_GPIO      GPIO Tools
 | 
			
		||||
* @ingroup  MYLIBS_PERIPHERAL
 | 
			
		||||
* @brief    Функции и макросы для удобной работы с GPIO.
 | 
			
		||||
* @details
 | 
			
		||||
Модуль предоставляет универсальные инструменты для работы с GPIO):
 | 
			
		||||
  - @ref  MYLIBS_GPIO_GENERAL — инициализация и общие функции работы с портами.
 | 
			
		||||
  - @ref  MYLIBS_GPIO_SWITCH — работа с GPIO как с кнопкой: чтение состояния, 
 | 
			
		||||
          фильтрация дребезга, настройка активного уровня.
 | 
			
		||||
  - @ref  MYLIBS_GPIO_LEDS — работа с GPIO как со светодиодом: включение, 
 | 
			
		||||
          выключение, моргание и плавное затухание.
 | 
			
		||||
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __GPIO_GENERAL_H_
 | 
			
		||||
#define __GPIO_GENERAL_H_
 | 
			
		||||
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup GPIO_INIT Init defines
 | 
			
		||||
  * @ingroup    MYLIBS_GPIO_GENERAL
 | 
			
		||||
  * @brief      Настройка состояний кнопок и количества тиков в периоде ШИМ
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
#ifndef LED_PWM_TICKS
 | 
			
		||||
#define LED_PWM_TICKS 15 ///< Количество тиков в периоде ШИМ
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
#ifndef LED_ON
 | 
			
		||||
#define LED_ON 1  ///< Состояние пина для включения светодиода
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef LED_OFF
 | 
			
		||||
#define LED_OFF 0 ///< Состояние пина для выключения светодиода
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef SW_ON
 | 
			
		||||
#define SW_ON 1   ///< Состояние пина при нажатой кнопке
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef SW_OFF
 | 
			
		||||
#define SW_OFF 0  ///< Состояние пина при отжатой кнопке
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** GPIO_INIT
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// /**
 | 
			
		||||
//   * @brief Маппинг альтернативной функции SPI между GPIO
 | 
			
		||||
//   * @ingroup  MYLIBS_GPIO_GENERAL
 | 
			
		||||
//   */
 | 
			
		||||
// #define SPI_Alternate_Mapping(INSTANCE) \
 | 
			
		||||
// ((((INSTANCE) == TIM1)  || ((INSTANCE) == TIM2))?     GPIO_AF1_TIM1:                                                   \
 | 
			
		||||
// (((INSTANCE) == TIM3)   || ((INSTANCE) == TIM4)   || ((INSTANCE) == TIM5))? GPIO_AF2_TIM3:                            \
 | 
			
		||||
// (((INSTANCE) == TIM8)   || ((INSTANCE) == TIM9)   || ((INSTANCE) == TIM10) || ((INSTANCE) == TIM11))? GPIO_AF3_TIM8:  \
 | 
			
		||||
// (((INSTANCE) == TIM12)  || ((INSTANCE) == TIM13)  || ((INSTANCE) == TIM14))? GPIO_AF9_TIM12:                        \
 | 
			
		||||
// (0))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Маппинг альтернативной функции TIM между GPIO
 | 
			
		||||
  * @ingroup  MYLIBS_GPIO_GENERAL
 | 
			
		||||
  */
 | 
			
		||||
#define GPIO_TIM_Alternate_Mapping(INSTANCE) \
 | 
			
		||||
((((INSTANCE) == TIM1)  || ((INSTANCE) == TIM2))? GPIO_AF1_TIM1:                                                      \
 | 
			
		||||
(((INSTANCE) == TIM3)   || ((INSTANCE) == TIM4)   || ((INSTANCE) == TIM5))? GPIO_AF2_TIM3:                            \
 | 
			
		||||
(((INSTANCE) == TIM8)   || ((INSTANCE) == TIM9)   || ((INSTANCE) == TIM10) || ((INSTANCE) == TIM11))? GPIO_AF3_TIM8:  \
 | 
			
		||||
(((INSTANCE) == TIM12)  || ((INSTANCE) == TIM13)  || ((INSTANCE) == TIM14))? GPIO_AF9_TIM12:                          \
 | 
			
		||||
(0))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Режимы работы светодиода
 | 
			
		||||
  * @ingroup  MYLIBS_GPIO_LEDS
 | 
			
		||||
  */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  LED_IS_OFF = 0,       ///< Светодиод выключен
 | 
			
		||||
  LED_IS_ON = 1,        ///< Светодиод включен
 | 
			
		||||
  LED_IS_BLINKING = 2,  ///< Моргание светодиодом
 | 
			
		||||
  LED_IS_FADING = 3,    ///< Плавное моргание светодиодом
 | 
			
		||||
}GPIO_LEDStateTypeDef;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Структура светодиода
 | 
			
		||||
  * @ingroup  MYLIBS_GPIO_LEDS
 | 
			
		||||
  */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GPIO_LEDStateTypeDef state;     ///< Текущий режим работы светодиода
 | 
			
		||||
  
 | 
			
		||||
  GPIO_TypeDef  *LED_Port;        ///< GPIO порт ножки светодиода
 | 
			
		||||
  uint32_t      LED_Pin;          ///< GPIO пин ножки светодиода
 | 
			
		||||
  
 | 
			
		||||
  uint8_t       LED_ActiveLvl;    ///< Активный уровень ножки (при котором светодиод горит)
 | 
			
		||||
  uint32_t      LED_Period;       ///< Период моргания светодиода
 | 
			
		||||
 | 
			
		||||
  uint32_t      tickprev;
 | 
			
		||||
}GPIO_LEDTypeDef;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Структура кнопки
 | 
			
		||||
  * @ingroup  MYLIBS_GPIO_SWITCH
 | 
			
		||||
  */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GPIO_TypeDef  *Sw_Port;         ///< GPIO порт ножки кнопки
 | 
			
		||||
  uint32_t      Sw_Pin;           ///< GPIO пин ножки кнопки
 | 
			
		||||
  
 | 
			
		||||
  uint8_t       Sw_ActiveLvl;     ///< Активный уровень ножки (при котором кнопка нажата)
 | 
			
		||||
  uint32_t      Sw_PrevState;     ///< Предыдущее состояние кнопки
 | 
			
		||||
  uint32_t      Sw_FilterDelay;   ///< Фильтр от дребезга (в мс)
 | 
			
		||||
 | 
			
		||||
  uint32_t      tickprev; 
 | 
			
		||||
}GPIO_SwitchTypeDef;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup MYLIBS_GPIO_GENERAL  General tools
 | 
			
		||||
  * @ingroup    MY_LIBS_GPIO
 | 
			
		||||
  * @brief      Общие функции/макросы для работы с GPIO
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx);
 | 
			
		||||
 | 
			
		||||
/** MYLIBS_GPIO_GENERAL
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
* @addtogroup MYLIBS_GPIO_SWITCH  Switch tools
 | 
			
		||||
* @ingroup    MY_LIBS_GPIO
 | 
			
		||||
* @brief      Функции для работы с GPIO, как с кнопкой
 | 
			
		||||
* @{
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Инициализировать кнопку (структуру кнопки) */
 | 
			
		||||
HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_On_State);
 | 
			
		||||
/* Считать состоянии кнопки запуска */
 | 
			
		||||
int GPIO_Read_Switch(GPIO_SwitchTypeDef *swstart);
 | 
			
		||||
 | 
			
		||||
/** MYLIBS_GPIO_SWITCH
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup MYLIBS_GPIO_LEDS  LED tools
 | 
			
		||||
  * @ingroup    MY_LIBS_GPIO
 | 
			
		||||
  * @brief      Функции для работы с GPIO, для управления светодиодом
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/* Инициализировать светодиод (структуру светодиода) */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_On_State);
 | 
			
		||||
/* Включить светодиод */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_On (GPIO_LEDTypeDef *led);
 | 
			
		||||
/* Выключить светодиод */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Off (GPIO_LEDTypeDef *led);
 | 
			
		||||
/* Выставить светодиод по переменной */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Set (GPIO_LEDTypeDef *led, uint8_t led_state);
 | 
			
		||||
/* Активировать моргание светодиодом */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Blink_Start (GPIO_LEDTypeDef *led, uint32_t period);
 | 
			
		||||
/* Активировать моргание светодиодом */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period);
 | 
			
		||||
/* Управление динамическими режимами свечения светодиода */
 | 
			
		||||
void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led);
 | 
			
		||||
 | 
			
		||||
/** MYLIBS_GPIO_LEDS
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // __GPIO_GENERAL_H_
 | 
			
		||||
@ -1,224 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_tim.h
 | 
			
		||||
* @brief Заголовочный файл для модуля инициализации таймеров и работы с ними.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @defgroup MY_LIBS_TIM      TIM Tools
 | 
			
		||||
* @ingroup  MYLIBS_PERIPHERAL
 | 
			
		||||
* @brief    Функции и макросы для удобной работы с TIM.
 | 
			
		||||
* @details
 | 
			
		||||
Модуль предоставляет универсальные инструменты для работы с TIM:
 | 
			
		||||
  - @ref  MYLIBS_TIM_GENERAL  — базовая инициализация таймеров и прерываний.
 | 
			
		||||
  - @ref  MYLIBS_TIM_DELAY    — функции задержки через таймеры (blocking и non-blocking).
 | 
			
		||||
  - @ref  MYLIBS_TIM_OC       — настройка каналов Output Compare и PWM.
 | 
			
		||||
  - @ref  MYLIBS_TIM_ENCODER  — работа с энкодерами, чтение положения и кнопки.
 | 
			
		||||
*  @note Требуется подключение модуля TIM в библиотеке HAL 
 | 
			
		||||
@code 
 | 
			
		||||
#define HAL_TIM_MODULE_ENABLED
 | 
			
		||||
@endcode
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __TIM_GENERAL_H_
 | 
			
		||||
#define __TIM_GENERAL_H_
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup TIM_INIT Init defines
 | 
			
		||||
  * @ingroup    MYLIBS_TIM_GENERAL
 | 
			
		||||
  * @brief      Настройка таймеров
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
#define HAL_TIM_MODULE_ENABLED
 | 
			
		||||
 | 
			
		||||
#define USE_TIM1    ///< Включить TIM1 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM2    ///< Включить TIM2 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM3    ///< Включить TIM3 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM4    ///< Включить TIM4 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM5    ///< Включить TIM5 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM6    ///< Включить TIM6 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM7    ///< Включить TIM7 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM8    ///< Включить TIM8 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM9    ///< Включить TIM9 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM10   ///< Включить TIM10 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM11   ///< Включить TIM11 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM12   ///< Включить TIM12 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM13   ///< Включить TIM13 в @ref TIM_Base_MspInit
 | 
			
		||||
#define USE_TIM14   ///< Включить TIM14 в @ref TIM_Base_MspInit
 | 
			
		||||
/** TIM_INIT
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
#include "general_gpio.h"
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////
 | 
			
		||||
#define TIM_IT_CONF_Pos           0
 | 
			
		||||
//#define TIM_PWM_CONF_Pos          1
 | 
			
		||||
//#define TIM_CLCK_SRC_CONF_Pos     2
 | 
			
		||||
//#define TIM_SLAVE_CONF_Pos        3
 | 
			
		||||
//#define TIM_MASTER_CONF_Pos       4
 | 
			
		||||
//#define TIM_BDTR_CONF_Pos         5
 | 
			
		||||
 | 
			
		||||
#define TIM_IT_CONF   (1<<(TIM_IT_CONF_Pos))
 | 
			
		||||
//#define TIM_PWM_CONF      (1<<(TIM_PWM_Pos))
 | 
			
		||||
 | 
			
		||||
////////////////////////////---DEFINES---////////////////////////////]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Режим прерываний таймера
 | 
			
		||||
  * @ingroup  MYLIBS_TIM_GENERAL
 | 
			
		||||
  */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  TIM_DEFAULT =         0,            ///< Прерываний отключены
 | 
			
		||||
  TIM_IT_MODE =         TIM_IT_CONF,  ///< Прерываний включены
 | 
			
		||||
//  TIM_PWM_MODE =        TIM_PWM_ENABLE,
 | 
			
		||||
//  TIM_PWM_IT_MODE =     TIM_PWM_ENABLE | TIM_IT_CONF,
 | 
			
		||||
}TIM_ITModeTypeDef;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Длительность тика таймера (частота тактирования таймера)
 | 
			
		||||
  * @ingroup  MYLIBS_TIM_GENERAL
 | 
			
		||||
  * @details  enum дает базовые длительности, но можно выставить другие
 | 
			
		||||
  *           (напр 500 - 0.5 мс)
 | 
			
		||||
  */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  TIM_Base_Disable =      0,      ///< Таймер отключен
 | 
			
		||||
  TIM_TickBase_1US =      1,      ///< Таймер тактируется с частотой 1    МГц
 | 
			
		||||
  TIM_TickBase_10US =     10,     ///< Таймер тактируется с частотой 100  кГц
 | 
			
		||||
  TIM_TickBase_100US =    100,    ///< Таймер тактируется с частотой 10   кГц
 | 
			
		||||
  TIM_TickBase_1MS =      1000,   ///< Таймер тактируется с частотой 1    кГц
 | 
			
		||||
  TIM_TickBase_10MS =     10000,  ///< Таймер тактируется с частотой 100  Гц
 | 
			
		||||
  TIM_TickBase_100MS =    100000, ///< Таймер тактируется с частотой 10   Гц
 | 
			
		||||
}TIM_MHzTickBaseTypeDef;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Структура инициализации таймера
 | 
			
		||||
  * @ingroup  MYLIBS_TIM_GENERAL
 | 
			
		||||
  * @details  
 | 
			
		||||
  * Содержит все базовые структуры, которые нужны для инициализации таймера.
 | 
			
		||||
  * Если структуры настроек не заданы, то они заполнятся сами дефолтными параметрами  
 | 
			
		||||
  * 
 | 
			
		||||
  * Также высокоуровневые настройки частоты работы таймера. 
 | 
			
		||||
  * Если какая-либо высокоуровневая настройка не задана, то 
 | 
			
		||||
  * по возможности берется низкоуровневая настройка из структур
 | 
			
		||||
  */
 | 
			
		||||
typedef struct // struct with settings for custom function
 | 
			
		||||
{
 | 
			
		||||
  TIM_HandleTypeDef       htim;                         ///< HAL handle таймера
 | 
			
		||||
  TIM_ClockConfigTypeDef  sClockSourceConfig;           ///< Настройки тактирования таймера
 | 
			
		||||
  TIM_SlaveConfigTypeDef  sSlaveConfig;                 ///< Настройки слейв режима таймера
 | 
			
		||||
  TIM_MasterConfigTypeDef sMasterConfig;                ///< Настройки мастер режима таймера
 | 
			
		||||
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;  ///< Настройки дедтаймов таймера
 | 
			
		||||
 | 
			
		||||
  TIM_ITModeTypeDef       sTimMode;                     ///< Настройки прерывания таймера  
 | 
			
		||||
  TIM_MHzTickBaseTypeDef  sTickBaseUS;                  ///< Длительность одного тика  
 | 
			
		||||
  uint8_t                 sTickBasePrescaler;           ///< Дополнительный делитель, для удобного деления @ref sTickBaseUS
 | 
			
		||||
  float                   sTimAHBFreqMHz;               ///< Частота шины тактирования таймера
 | 
			
		||||
  float                   sTimFreqHz;                   ///< Желаемая частота таймера
 | 
			
		||||
  
 | 
			
		||||
}TIM_SettingsTypeDef;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Структура инициализации енкодера
 | 
			
		||||
  * @ingroup  MYLIBS_TIM_ENCODER
 | 
			
		||||
  * @details  
 | 
			
		||||
  * Содержит все базовые структуры, которые нужны для инициализации таймера.
 | 
			
		||||
  * Если структуры настроек не заданы, то они заполнятся сами дефолтными параметрами  
 | 
			
		||||
  * 
 | 
			
		||||
  * Также высокоуровневые настройки частоты работы таймера. 
 | 
			
		||||
  * Если какая-либо высокоуровневая настройка не задана, то 
 | 
			
		||||
  * по возможности берется низкоуровневая настройка из структур
 | 
			
		||||
  */
 | 
			
		||||
typedef struct // struct with variables for encoder
 | 
			
		||||
{
 | 
			
		||||
  int16_t                 Encoder_Diff;   ///< Считанная разница
 | 
			
		||||
  uint16_t                Encoder_Shdw;   ///< Последние считанные тики
 | 
			
		||||
  
 | 
			
		||||
  TIM_HandleTypeDef       *htim;          ///< Указатель на HAL handle таймера
 | 
			
		||||
  TIM_Encoder_InitTypeDef sConfig;        ///< Указатель на структуру настройки энкодера
 | 
			
		||||
  
 | 
			
		||||
  GPIO_TypeDef            *GPIOx;         ///< Порт, куда подключается энкодер
 | 
			
		||||
  uint32_t                GPIO_PIN_TI1;   ///< Пин, куда подключается канал TI1
 | 
			
		||||
  uint32_t                GPIO_PIN_TI2;   ///< Пин, куда подключается канал TI2
 | 
			
		||||
  uint32_t                GPIO_PIN_SW;    ///< Пин, куда кнопка энкодера (если есть)
 | 
			
		||||
 | 
			
		||||
  GPIO_SwitchTypeDef      Sw;             ///< Структура кнопки
 | 
			
		||||
  
 | 
			
		||||
}TIM_EncoderTypeDef;
 | 
			
		||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup MYLIBS_TIM_OC PWM/OC Channels tools
 | 
			
		||||
  * @ingroup    MY_LIBS_TIM
 | 
			
		||||
  * @brief      Функции для инициализации базовых функций каналов таймера
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
/* Initialize PWM Channel and GPIO for output */
 | 
			
		||||
HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t PWM_PIN);
 | 
			
		||||
/* Initialize OC Comparator */
 | 
			
		||||
HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL);
 | 
			
		||||
/** MYLIBS_TIM_ENCODER
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup MYLIBS_TIM_ENCODER Encoder tools
 | 
			
		||||
  * @ingroup    MY_LIBS_TIM
 | 
			
		||||
  * @brief      Функции для считывания энкодера
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
/* Initialize TIM Encoder functional */
 | 
			
		||||
HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc1, TIM_HandleTypeDef *htim);
 | 
			
		||||
/* Считать энкодер */
 | 
			
		||||
HAL_StatusTypeDef TIM_Encoder_Read(TIM_EncoderTypeDef *henc);
 | 
			
		||||
/* Считать кнопку энкодера */
 | 
			
		||||
int TIM_Encoder_ReadSwitch(TIM_EncoderTypeDef *henc);
 | 
			
		||||
/** MYLIBS_TIM_ENCODER
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup MYLIBS_TIM_DELAY  Delay tools
 | 
			
		||||
  * @ingroup    MY_LIBS_TIM
 | 
			
		||||
  * @brief      Функции для формирования задержек с помощью таймеров
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
/* Start delay via TIM */
 | 
			
		||||
HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim);
 | 
			
		||||
/* Delay via TIM */
 | 
			
		||||
HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay);
 | 
			
		||||
/* Wait Delay via TIM without blocking app */
 | 
			
		||||
HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay);
 | 
			
		||||
/** MYLIBS_TIM_DELAY
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup MYLIBS_TIM_GENERAL  General tools
 | 
			
		||||
  * @ingroup    MY_LIBS_TIM
 | 
			
		||||
  * @brief      Функции для базовой инициализации таймеров
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
/* Initialize TIM with TIM_SettingsTypeDef structure */
 | 
			
		||||
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef* stim);
 | 
			
		||||
/* Initialize TIMs clock and interrupt */
 | 
			
		||||
void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode);
 | 
			
		||||
/* DeInitialize TIMs clock and interrupt */
 | 
			
		||||
void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim);
 | 
			
		||||
/** MYLIBS_TIM_GENERAL
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
///////////////////////////---FUNCTIONS---///////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // __TIM_GENERAL_H_
 | 
			
		||||
@ -1,94 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file mylibs_config.h
 | 
			
		||||
* @brief Конфигурации для библиотек MyLibs
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @defgroup MYLIBS_CONFIG   Configs
 | 
			
		||||
* @ingroup  MYLIBS_ALL
 | 
			
		||||
* @brief    Конфигурации для библиотек MyLibs
 | 
			
		||||
* @{
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __MYLIBS_CONFIG_H_
 | 
			
		||||
#define __MYLIBS_CONFIG_H_
 | 
			
		||||
 | 
			
		||||
#include "stm32f4xx_hal.h"
 | 
			
		||||
 | 
			
		||||
// user includes
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup TRACE_CONFIG   Trace configs
 | 
			
		||||
  * @ingroup    MYLIBS_CONFIG
 | 
			
		||||
  * @brief      Конфигурация трекеров и трассировки
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
#define TRACKERS_ENABLE           ///< Включить трекеры
 | 
			
		||||
#define SERIAL_TRACE_ENABLE       ///< Включить serial трассировку
 | 
			
		||||
#define RTT_TRACE_ENABLE          ///< Включить serial трассировку через RTT
 | 
			
		||||
#define SWO_TRACE_ENABLE          ///< Включить serial трассировку через SWO
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Уровень log serial трассировки @ref log_printf
 | 
			
		||||
  *  - LOG_LEVEL == 0 - логирование отключено (макрос пустой)
 | 
			
		||||
  *  - LOG_LEVEL == 1 - выводится время и TAG
 | 
			
		||||
  *  - LOG_LEVEL >= 2 - выводится время, TAG, имя файла и номер строки
 | 
			
		||||
  */
 | 
			
		||||
#define LOG_LEVEL 1
 | 
			
		||||
 | 
			
		||||
#define RTT_FLASH_BUFFER_SIZE   1024                    ///< Размер буфера RTT в Flash
 | 
			
		||||
#define RTT_FLASH_SECTOR        FLASH_SECTOR_11         ///< Сектор FLASH куда положится RTT буфер
 | 
			
		||||
#define RTT_FLASH_SECTOR_START  0x080E0000              ///< Начало сектора RTT_FLASH_SECTOR
 | 
			
		||||
#define RTT_FLASH_SECTOR_END    0x080FFFFF              ///< Конец сектора RTT_FLASH_SECTOR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define HARDFAULT_SERIAL_TRACE  ///< Включить обработку и serial трассировку Hardfault
 | 
			
		||||
#define HF_RTT_TAG_BASE         0xDEAD0000              ///< базовый тег для HardFault
 | 
			
		||||
#define HF_RTT_TAIL_SIZE        RTT_FLASH_BUFFER_SIZE   ///< Размер буфера RTT, который сохранится при Hardfault
 | 
			
		||||
#define HF_STACK_DUMP_WORDS     32                      ///< Сколько слов стека будет проанализировано во время Hardfault
 | 
			
		||||
#define HF_FLASH_ADDR           ((uint32_t)0x080FF000)  ///< Адрес FLASH куда положится RTT буфер
 | 
			
		||||
#define HF_RAM_END              0x20030000              ///< Конец RAM памяти (чтобы во время анализа стека не выйти за пределы)
 | 
			
		||||
 | 
			
		||||
#define GPIO_TRACE_ENABLE         ///< Включить GPIO трассировку
 | 
			
		||||
 | 
			
		||||
/** TRACE_CONFIG
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup EVOLVE_CONFIG   Evolve configs
 | 
			
		||||
  * @ingroup    MYLIBS_CONFIG
 | 
			
		||||
  * @brief      Конфигурация однослойного персептрона и алгоритма обучения
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
#define ENABLE_EVOLVE_OPTIMIZATION        ///< Включить оптимизацию параметров
 | 
			
		||||
#define EVOLVE_MAX_PARAMS       20        ///< Максимальное количество параметров
 | 
			
		||||
#define EVOLVE_MAX_CANDIDATES   100       ///< Максимальное количество кандидатов для обучения
 | 
			
		||||
 | 
			
		||||
/** EVOLVE_CONFIG
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup LIBS_CONFIG   Libraries configs
 | 
			
		||||
  * @ingroup    MYLIBS_CONFIG
 | 
			
		||||
  * @brief      Подключение различных модулей библиотеки
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
#define INCLUDE_EVOLVE_OPTIMIZER      ///< Подключить библиотеку для оптимизации параметров
 | 
			
		||||
#define INCLUDE_BIT_ACCESS_LIB        ///< Подключить библиотеку с typedef с битовыми полями
 | 
			
		||||
#define INCLUDE_TRACKERS_LIB          ///< Подключить библиотеку с трекерами
 | 
			
		||||
#define INCLUDE_TRACE_LIB             ///< Подключить библиотеку с трейсами
 | 
			
		||||
#define INCLUDE_GENERAL_PERIPH_LIBS   ///< Подключить библиотеку с периферией
 | 
			
		||||
//#define FREERTOS_DELAY                ///< Использовать FreeRTOS задержку, вместо HAL
 | 
			
		||||
 | 
			
		||||
/** LIBS_CONFIG
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** MYLIBS_CONFIG
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
#endif //__MYLIBS_CONFIG_H_
 | 
			
		||||
@ -1,184 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file mylibs_defs.h
 | 
			
		||||
* @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @defgroup MYLIBS_DEFINES  General Tools
 | 
			
		||||
* @ingroup  MYLIBS_ALL
 | 
			
		||||
* @brief    Общие макросы и typedef'ы, используемые по всему проекту
 | 
			
		||||
*
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __MYLIBS_DEFINES_H_
 | 
			
		||||
#define __MYLIBS_DEFINES_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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Error_Handler который будет вызыватся в библиотеке
 | 
			
		||||
  */
 | 
			
		||||
#define MyLibs_Error_Handler(params)  Error_Handler(params)
 | 
			
		||||
/* If error handler not defined - set void */
 | 
			
		||||
#ifndef MyLibs_Error_Handler
 | 
			
		||||
#define MyLibs_Error_Handler(...)
 | 
			
		||||
#endif // MyLibs_Error_Handler
 | 
			
		||||
 | 
			
		||||
/** @brief Проверить один указатель на NULL */
 | 
			
		||||
#define check_null_ptr_1(p1)                  (p1 == NULL)
 | 
			
		||||
 | 
			
		||||
/** @brief Проверить два указателя на NULL */
 | 
			
		||||
#define check_null_ptr_2(p1, p2)              ((p1 == NULL) || (p1 != NULL && p2 == NULL))
 | 
			
		||||
 | 
			
		||||
/** @brief Проверить три указателя на NULL */
 | 
			
		||||
#define check_null_ptr_3(p1, p2, p3)          ((p1 == NULL) || (p1 != NULL && ((p2 == NULL) || (p2 != NULL && p3 == NULL))))
 | 
			
		||||
 | 
			
		||||
/** @brief Проверить четыре указателя на NULL */
 | 
			
		||||
#define check_null_ptr_4(p1, p2, p3, p4)      ((p1 == NULL) || (p1 != NULL && ((p2 == NULL) || (p2 != NULL && ((p3 == NULL) || (p3 != NULL && p4 == NULL))))))
 | 
			
		||||
 | 
			
		||||
/** @brief Проверить пять указателей на NULL */
 | 
			
		||||
#define check_null_ptr_5(p1, p2, p3, p4, p5)  ((p1 == NULL) || (p1 != NULL && ((p2 == NULL) || (p2 != NULL && ((p3 == NULL) || (p3 != NULL && ((p4 == NULL) || (p4 != NULL && p5 == NULL))))))))
 | 
			
		||||
 | 
			
		||||
/** ERROR_HANDLER_DEFINES
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
******************************DELAYS_DEFINES*******************************/
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup DELAYS_DEFINES    Delays defines
 | 
			
		||||
  * @ingroup    MYLIBS_DEFINES
 | 
			
		||||
  * @brief       Макросы и определения для работы с задержками в миллисекундах.
 | 
			
		||||
  * @details
 | 
			
		||||
  * Этот блок содержит макросы для реализации задержек с использованием HAL или FreeRTOS:
 | 
			
		||||
  * - @ref msDelay             — простая задержка заданной длительности;
 | 
			
		||||
  * - @ref msDelayStart        — сохранение текущего времени начала задержки;
 | 
			
		||||
  * - @ref msDelayWhileActive  — проверка, активна ли задержка;
 | 
			
		||||
  * - @ref msDelayWaitDone     — проверка, завершена ли задержка.
 | 
			
		||||
  * Эти макросы удобны для реализации неблокирующих задержек.
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @def msDelay(_ms_)
 | 
			
		||||
  * @brief Задержка на указанное количество миллисекунд.
 | 
			
		||||
  * @param _ms_ Время задержки в миллисекундах.
 | 
			
		||||
  * @note Использует HAL_Delay или osDelay в зависимости от @ref FREERTOS_DELAY.
 | 
			
		||||
  */
 | 
			
		||||
#ifdef FREERTOS_DELAY
 | 
			
		||||
  #define msDelay(_ms_)       osDelay(_ms_)
 | 
			
		||||
#else
 | 
			
		||||
  #define msDelay(_ms_)       HAL_Delay(_ms_)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Начать отсчет задержки.
 | 
			
		||||
  * @param _pvar_ Указатель на переменную типа uint32_t для хранения времени старта.
 | 
			
		||||
  * @details После вызова этого макроса переменная _pvar_ содержит текущее количество миллисекунд
 | 
			
		||||
  * с момента запуска системы (HAL_GetTick). 
 | 
			
		||||
  * 
 | 
			
		||||
  * Используется для реализации неблокирующих задержек.
 | 
			
		||||
  */
 | 
			
		||||
#define msDelayStart(_pvar_)            *(_pvar_) = HAL_GetTick()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Проверяет, активна ли задержка.
 | 
			
		||||
 * @param _ms_ Длительность задержки в миллисекундах.
 | 
			
		||||
 * @param _pvar_ Указатель на переменную, в которой сохранено время начала (@ref msDelayStart).
 | 
			
		||||
 * @retval 1 Задержка еще активна.
 | 
			
		||||
 * @retval 0 Задержка завершена.
 | 
			
		||||
 * @details
 | 
			
		||||
 * Возвращает true, пока время задержки не истекло. Используется в проверках,
 | 
			
		||||
 * когда нужно **действовать, пока задержка выполняется**. Пример:
 | 
			
		||||
 * @code
 | 
			
		||||
 * while(msDelayWhileActive(1000, &tick)) {
 | 
			
		||||
 *     // выполняем другие задачи, задержка не блокирует поток
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 */
 | 
			
		||||
#define msDelayWhileActive(_ms_, _pvar_)    (HAL_GetTick() - *(_pvar_) < _ms_)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Проверяет, завершилась ли задержка.
 | 
			
		||||
 * @param _ms_ Длительность задержки в миллисекундах.
 | 
			
		||||
 * @param _pvar_ Указатель на переменную, в которой сохранено время начала (msDelayStart).
 | 
			
		||||
 * @retval 1 Задержка завершена.
 | 
			
		||||
 * @retval 0 Задержка еще активна.
 | 
			
		||||
 * @details
 | 
			
		||||
 * Возвращает true, когда задержка уже завершена. Используется в проверках,
 | 
			
		||||
 * когда нужно **выполнить действие только после окончания задержки**. Пример:
 | 
			
		||||
 * @code
 | 
			
		||||
 * if(msDelayWaitDone(1000, &tick)) {
 | 
			
		||||
 *     // выполняем действие после завершения задержки
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 */
 | 
			
		||||
#define msDelayWaitDone(_ms_, _pvar_)    (HAL_GetTick() - *(_pvar_) >= _ms_)
 | 
			
		||||
 | 
			
		||||
/** DELAYS_DEFINES
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
*******************************UTIL_DEFINES********************************/
 | 
			
		||||
static int dummy;
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup UTILS_DEFINES      Utils defines
 | 
			
		||||
  * @ingroup    MYLIBS_DEFINES
 | 
			
		||||
  * @brief      Общие вспомогательные макросы
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Обнуление структуры.
 | 
			
		||||
 * @param _struct_ Структура, которую нужно обнулить.
 | 
			
		||||
 * @details Макрос использует memset для обнуления всей памяти структуры.
 | 
			
		||||
 * Используется для быстрой и безопасной инициализации переменных структур до нуля.
 | 
			
		||||
 */
 | 
			
		||||
#define ClearStruct(_struct_)     memset(&(_struct_), 0, sizeof(_struct_))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Деление с округлением вверх
 | 
			
		||||
  * @param _val_ Делимое.
 | 
			
		||||
  * @param _div_ Делитель.
 | 
			
		||||
  * @return Результат деления, округленный вверх.
 | 
			
		||||
  * @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 Исходное 16-битное значение.
 | 
			
		||||
  * @return Результат с поменяными местами старшим и младшим байтом.
 | 
			
		||||
  * @details  Переключения между двумя типами хранения слова: HI-LO байты и LO-HI байты.
 | 
			
		||||
  */
 | 
			
		||||
#define ByteSwap16(v)                                 (((v&0xFF00) >> (8)) | ((v&0x00FF) << (8)))
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @brief  Абсолютное значение числа
 | 
			
		||||
  * @param x Число.
 | 
			
		||||
  * @return Абсолютное значение числа x.
 | 
			
		||||
  * @details  Берет число по модулю. Хз как работает библиотечный abs в stdlib.h, мб это быстрее, но вряд ли конечно.
 | 
			
		||||
  */
 | 
			
		||||
#define ABS(x) ( ((x) > 0)? (x) : -(x))
 | 
			
		||||
 | 
			
		||||
/** UTILS_DEFINES
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
  
 | 
			
		||||
#endif //__MYLIBS_DEFINES_H_
 | 
			
		||||
@ -1,125 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file mylibs_include.h
 | 
			
		||||
* @brief Заголочный файл для всех библиотек
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @details
 | 
			
		||||
Здесь нужно собрать библиотеки и дефайны, которые должны быть видны во всем проекте,
 | 
			
		||||
чтобы не подключать 100 инклюдов в каждом ".c" файле
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @defgroup MYLIBS_ALL      My Libs
 | 
			
		||||
* @brief    Все используемые MyLibs библиотеки
 | 
			
		||||
* @details
 | 
			
		||||
Для подключения библиотеки необходимо:
 | 
			
		||||
- Сконфигурировать mylibs_config.h:
 | 
			
		||||
  - Подключить заголовочный файл HAL библиотеки конкретного МК (напр. stm32f4xx_hal.h)
 | 
			
		||||
  - Подключить другие заголовочные файлы которые общие для всего проекта и должны быть видны
 | 
			
		||||
  - 
 | 
			
		||||
- Подключить mylibs_include.h туда, где необходим доступ к библиотекам.
 | 
			
		||||
 | 
			
		||||
* @defgroup MYLIBS_PERIPHERAL Peripheral
 | 
			
		||||
* @ingroup  MYLIBS_ALL
 | 
			
		||||
* @brief    Модули для управления периферией
 | 
			
		||||
*
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __MYLIBS_INCLUDE_H_
 | 
			
		||||
#define __MYLIBS_INCLUDE_H_
 | 
			
		||||
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef ARM_MATH_CM4
 | 
			
		||||
  #include "arm_math.h"
 | 
			
		||||
#else
 | 
			
		||||
  #include "math.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_BIT_ACCESS_LIB
 | 
			
		||||
#include "bit_access.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_TRACKERS_LIB
 | 
			
		||||
#include "trackers.h"
 | 
			
		||||
#else
 | 
			
		||||
  #define TrackerTypeDef(num_user_vars) void *
 | 
			
		||||
  #define num_of_usercnts(_user_)                               0
 | 
			
		||||
  #define assert_tracecnt(_cntstruct_, _uservarnumb_)           0
 | 
			
		||||
  #define if_assert_usertracker(_cntstruct_, _uservarnumb_)     if(0)
 | 
			
		||||
  #define tern_assert_usertracker(_cntstruct_, _uservarnumb_)   0
 | 
			
		||||
  #define TrackerGet_Ok(_cntstruct_)                            dummy
 | 
			
		||||
  #define TrackerGet_Err(_cntstruct_)                           dummy
 | 
			
		||||
  #define TrackerGet_Warn(_cntstruct_)                          dummy 
 | 
			
		||||
  #define TrackerGet_User(_cntstruct_, _uservarnumb_)           dummy
 | 
			
		||||
  #define TrackerCnt_Ok(_cntstruct_)                              
 | 
			
		||||
  #define TrackerCnt_Err(_cntstruct_)                             
 | 
			
		||||
  #define TrackerCnt_Warn(_cntstruct_)                            
 | 
			
		||||
  #define TrackerCnt_User(_cntstruct_, _uservarnumb_)                 
 | 
			
		||||
  #define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
 | 
			
		||||
  #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
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_TRACE_LIB
 | 
			
		||||
#include "trace.h"
 | 
			
		||||
#else
 | 
			
		||||
#define my_printf(...)
 | 
			
		||||
#define log_printf(TAG, fmt, ...)  
 | 
			
		||||
#define TRACE_GPIO_SET(_gpio_,_pin_)
 | 
			
		||||
#define TRACE_GPIO_RESET(_gpio_,_pin_)
 | 
			
		||||
#define RTT_FlashPrepare(...)
 | 
			
		||||
#define RTT_EraseFlash(...)    0
 | 
			
		||||
#define RTT_SaveToFlash(...)   0
 | 
			
		||||
#define RTT_ReadFromFlash(...) 0
 | 
			
		||||
#define HF_CheckRecovered(...) 0
 | 
			
		||||
#define HF_HandleFault(...)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef INCLUDE_EVOLVE_OPTIMIZER
 | 
			
		||||
#include "evolve_optimizer.h"
 | 
			
		||||
#else
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint16_t n_params; 
 | 
			
		||||
  uint16_t n_cand; 
 | 
			
		||||
  uint16_t n_best; 
 | 
			
		||||
  uint16_t iq_mutation; 
 | 
			
		||||
  int32_t loss[0]; 
 | 
			
		||||
  int32_t candidates[0][0]; 
 | 
			
		||||
} EvolveOptimizer_t;
 | 
			
		||||
#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, iq_mutation, start_params)
 | 
			
		||||
#define EvolveOptimizer_Step(opt, params, LossFunc)
 | 
			
		||||
#define PARAM_SCALE_Q16(x, min_val, max_val)            (x)
 | 
			
		||||
#define PARAM_UNSCALE_Q16(q16_val, min_val, max_val)    (q16_val)
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
// user settings
 | 
			
		||||
/////////////////////////---USER SETTINGS---/////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // __MYLIBS_INCLUDE_H_
 | 
			
		||||
@ -1,578 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file trace.h
 | 
			
		||||
* @brief Заголочный файл для работы с трассировкой.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @addtogroup   TRACE           Trace defines
 | 
			
		||||
* @ingroup      MYLIBS_DEFINES
 | 
			
		||||
* @brief        Дефайны для работы с трассировкой
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __TRACE_H_
 | 
			
		||||
#define __TRACE_H_
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup TRACE_SERIAL    Serial trace defines
 | 
			
		||||
  * @ingroup    TRACE
 | 
			
		||||
  * @brief      Дефайны для работы с serial трассировкой (SWO, RTT)
 | 
			
		||||
  * @details    В зависимости от настроек определяется дефайн @ref my_printf() и @ref log_printf() для работы с трассировкой:
 | 
			
		||||
    - @ref SERIAL_TRACE_ENABLE - Если трассировка  отключена, то все дефайны определяются как 'ничего' 
 | 
			
		||||
      и на производительность кода не влияют
 | 
			
		||||
 | 
			
		||||
    - @ref RTT_TRACE_ENABLE - для RTT это будет вызов функции SEGGER_RTT_printf(), с подключением библиотеки SEGGER_RTT.h
 | 
			
		||||
      Предварительно надо подключить библиотеку SEGGER RTT и вызвать функцию SEGGER_RTT_Init()
 | 
			
		||||
 | 
			
		||||
    - @ref SWO_TRACE_ENABLE для SWO это будет просто printf()
 | 
			
		||||
    
 | 
			
		||||
      Но библиотеку STDOUT надо подключить самостоятельно:
 | 
			
		||||
      
 | 
			
		||||
      @verbatim
 | 
			
		||||
        Manage Run-Time Environment -> Compiler -> I/O -> STDOUT 
 | 
			
		||||
      @endverbatim
 | 
			
		||||
      
 | 
			
		||||
      Для SWO также надо включить трассировку:    
 | 
			
		||||
      
 | 
			
		||||
      @verbatim
 | 
			
		||||
        Options For Target -> Debug -> Debugger Settings
 | 
			
		||||
      @endverbatim
 | 
			
		||||
      
 | 
			
		||||
      В вкладке Debug: 
 | 
			
		||||
        - Port = SW
 | 
			
		||||
      В вкладке Trace: 
 | 
			
		||||
        - Указать Core Clock
 | 
			
		||||
        - Выставить Trace Port = SWO
 | 
			
		||||
        - ITM - выбрать нужный порт (для Keil нулевой порт)   
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
  * @{
 | 
			
		||||
  *
 | 
			
		||||
  * @def my_printf(...)
 | 
			
		||||
  * @brief Универсальный макрос для вывода трассировки
 | 
			
		||||
  * @details Варианты реализации:
 | 
			
		||||
  *  - RTT_TRACE_ENABLE    `SEGGER_RTT_printf(0, ...)`
 | 
			
		||||
  *  - SWO_TRACE_ENABLE - `printf(...)`
 | 
			
		||||
  *  - NO_TRACE - пустой макрос
 | 
			
		||||
  *
 | 
			
		||||
  * @def log_printf(TAG, fmt, ...)
 | 
			
		||||
  * @brief Макрос логирования с поддержкой уровней LOG_LEVEL
 | 
			
		||||
  * @param TAG  Тэг лога
 | 
			
		||||
  * @param fmt, ...  Форматируемая строка
 | 
			
		||||
  * @details Варианты реализации:
 | 
			
		||||
  *  - LOG_LEVEL == 0 - логирование отключено (макрос пустой)
 | 
			
		||||
  *  - LOG_LEVEL == 1 - выводится время и TAG
 | 
			
		||||
  *  - LOG_LEVEL >= 2 - выводится время, TAG, имя файла и номер строки
 | 
			
		||||
  */
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef LOG_LEVEL
 | 
			
		||||
#define LOG_LEVEL 1  ///< @brief Уровень логирования (по умолчанию == 1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if LOG_LEVEL == 0 // лог отключен
 | 
			
		||||
    #define \
 | 
			
		||||
log_printf(TAG, fmt, ...)  
 | 
			
		||||
#elif LOG_LEVEL == 1 // только тэг
 | 
			
		||||
    #define log_printf(TAG, fmt, ...)  \
 | 
			
		||||
my_printf("\n[%lu] [%s] " fmt, \
 | 
			
		||||
(unsigned long)uwTick, TAG, ##__VA_ARGS__)
 | 
			
		||||
#elif LOG_LEVEL >= 2 // всё
 | 
			
		||||
    #define log_printf(TAG, fmt, ...)  \
 | 
			
		||||
my_printf("\n[%lu] [%s] (%s:%d) " fmt, \
 | 
			
		||||
(unsigned long)uwTick, TAG, __FILE__, __LINE__, ##__VA_ARGS__)
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
/** TRACE_SERIAL
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup TRACE_GPIO    GPIO trace defines
 | 
			
		||||
  * @ingroup    TRACE
 | 
			
		||||
  * @brief      Дефайны для работы с GPIO трассировкой
 | 
			
		||||
  * @details    Определяется дефайны для работы с GPIO трассировкой:
 | 
			
		||||
    - TRACE_GPIO_RESET() - для сброса ножки GPIO (через BSRR)
 | 
			
		||||
    - TRACE_GPIO_SET() - для выставления ножки GPIO (через BSRR)
 | 
			
		||||
    
 | 
			
		||||
    - Если трассировка @ref GPIO_TRACE_ENABLE отключена, то все дефайны определяются как 'ничего' 
 | 
			
		||||
      и на производительность кода не влияют
 | 
			
		||||
  * @{  
 | 
			
		||||
  *
 | 
			
		||||
  * @def TRACE_GPIO_RESET(_gpio_, _pin_)
 | 
			
		||||
  * @brief Сбросить указанную ножку GPIO
 | 
			
		||||
  * @param _gpio_  Указатель на структуру GPIO (напр.  GPIOA)
 | 
			
		||||
  * @param _pin_   Номер ножки (напр. GPIO_PIN_0)
 | 
			
		||||
  * @details Варианты реализации:
 | 
			
		||||
  *  - GPIO_TRACE_ENABLE не определён - макрос пустой
 | 
			
		||||
  *  - GPIO_TRACE_ENABLE определён - устанавливает бит сброса через BSRR ((_pin_)<<16)
 | 
			
		||||
  *
 | 
			
		||||
  * @def TRACE_GPIO_SET(_gpio_, _pin_)
 | 
			
		||||
  * @brief Установить указанную ножку GPIO
 | 
			
		||||
  * @param _gpio_  Указатель на структуру GPIO (например GPIOA)
 | 
			
		||||
  * @param _pin_   Номер ножки (напр. GPIO_PIN_0)
 | 
			
		||||
  * @details Варианты реализации:
 | 
			
		||||
  *  - GPIO_TRACE_ENABLE не определён - макрос пустой
 | 
			
		||||
  *  - GPIO_TRACE_ENABLE определён - устанавливает бит установки через BSRR (_pin_)
 | 
			
		||||
  */
 | 
			
		||||
#ifndef GPIO_TRACE_ENABLE
 | 
			
		||||
  #define TRACE_GPIO_SET(_gpio_,_pin_)
 | 
			
		||||
  #define TRACE_GPIO_RESET(_gpio_,_pin_)
 | 
			
		||||
#else
 | 
			
		||||
  #define TRACE_GPIO_SET(_gpio_,_pin_)          (_gpio_)->BSRR = (((_pin_)))
 | 
			
		||||
  #define TRACE_GPIO_RESET(_gpio_,_pin_)        (_gpio_)->BSRR = ((_pin_)<<16)
 | 
			
		||||
#endif //GPIO_TRACE_ENABLE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** TRACE_GPIO
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(HAL_MODULE_ENABLED) && defined(RTT_TRACE_ENABLE)
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup TRACE_RTT_FLASH    Flash RTT Buffer
 | 
			
		||||
  * @ingroup    TRACE
 | 
			
		||||
  * @brief      Макросы и функции для сохранения/чтения RTT буфера в Flash
 | 
			
		||||
  * @details    Модуль позволяет сохранять данные RTT буфера во Flash и читать их обратно по тегам.  
 | 
			
		||||
  * Теги работают следующим образом:  
 | 
			
		||||
  *  - Базовый тег (младший байт = 0): модуль сам выбирает первый свободный слот во Flash;  
 | 
			
		||||
  *    новые записи получают автоинкрементированный младший байт тега (от 0x00 до 0xFF).  
 | 
			
		||||
  *  - Конкретный тег (младший байт != 0): запись или чтение происходит строго с указанным тегом;  
 | 
			
		||||
  *    если слот с таким тегом уже занят, запись не выполняется.  
 | 
			
		||||
  *  - Автоинкремент позволяет хранить несколько последовательных записей в пределах одного базового тега,  
 | 
			
		||||
  *    без необходимости вручную отслеживать адреса Flash или позиции буферов.  
 | 
			
		||||
  * 
 | 
			
		||||
  * Параметры:
 | 
			
		||||
  * - @ref RTT_FLASH_BUFFER_SIZE    - Размер буфера RTT в Flash
 | 
			
		||||
  * - @ref RTT_FLASH_SECTOR         - Сектор FLASH куда положится RTT буфер
 | 
			
		||||
  * - @ref RTT_FLASH_SECTOR_START   - Начало сектора RTT_FLASH_SECTOR
 | 
			
		||||
  * - @ref RTT_FLASH_SECTOR_END     - Конец сектора RTT_FLASH_SECTOR
 | 
			
		||||
  * 
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Структура RTT, которая будет положена в Flash
 | 
			
		||||
  */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t tag;                   ///< Уникальный идентификатор буфера
 | 
			
		||||
  uint32_t size;                  ///< Размер данных
 | 
			
		||||
  char     data[RTT_FLASH_BUFFER_SIZE];  ///< Буфер RTT
 | 
			
		||||
} RTT_FlashHeader_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Подготовка Flash к записи
 | 
			
		||||
  * @details Сбрасывает ошибки Flash и ожидает готовности перед записью
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_FORCEINLINE void RTT_FlashPrepare(void)
 | 
			
		||||
{
 | 
			
		||||
  HAL_FLASH_Unlock();
 | 
			
		||||
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR | FLASH_FLAG_WRPERR | FLASH_FLAG_OPERR);
 | 
			
		||||
  while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { 
 | 
			
		||||
  __NOP(); 
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Сохраняет последние символы RTT-буфера в Flash по тегу
 | 
			
		||||
  * @param tag        Базовый или конкретный идентификатор буфера.
 | 
			
		||||
  * @param tail_size  Количество последних символов RTT для копирования
 | 
			
		||||
  * @param buf_num    Указатель на переменную в которую запишется номер буфера для конкретного тега
 | 
			
		||||
  * @return >=0 — номер буфера (тег) для записи, <0 — ошибка (нет места, тег уже занят, ошибка записи в флеш)
 | 
			
		||||
  *
 | 
			
		||||
  * @details  Автоматически копирует последние tail_size символов из RTT-буфера
 | 
			
		||||
  *           и записывает их во Flash.
 | 
			
		||||
  *           Тег может быть базовым или конкретным:
 | 
			
		||||
  *             - Если базовый (младший байт == 0) — будет выбран первый свободный слот с автоинкрементом.
 | 
			
		||||
  *               Автоинкремент формируется в пределах от 0x1 до 0xFF
 | 
			
		||||
  *             - Если конкретный (младший байт != 0) — запись выполняется только с этим тегом, иначе ошибка.
 | 
			
		||||
  * 
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_FORCEINLINE int RTT_SaveToFlash(uint32_t tag, uint32_t tail_size)
 | 
			
		||||
{
 | 
			
		||||
  if (tag == 0xFFFFFFFF)
 | 
			
		||||
    return -1;  // Неверный тег
 | 
			
		||||
 | 
			
		||||
  SEGGER_RTT_BUFFER_UP *up = &_SEGGER_RTT.aUp[0];
 | 
			
		||||
  unsigned buf_size = up->SizeOfBuffer;
 | 
			
		||||
  unsigned wr = up->WrOff;
 | 
			
		||||
 | 
			
		||||
  // Ограничиваем по размеру буфера RTT и RTT_FLASH_BUFFER_SIZE
 | 
			
		||||
  unsigned n = (tail_size > buf_size) ? buf_size : tail_size;
 | 
			
		||||
  if (n > RTT_FLASH_BUFFER_SIZE)
 | 
			
		||||
    n = RTT_FLASH_BUFFER_SIZE;
 | 
			
		||||
 | 
			
		||||
  uint32_t addr = RTT_FLASH_SECTOR_START;
 | 
			
		||||
  RTT_FlashHeader_t *flash_hdr = NULL;
 | 
			
		||||
  uint32_t base_tag = tag & 0xFFFFFF00;
 | 
			
		||||
  uint32_t next_tag = (tag & 0xFF) == 0 ? tag + 1 : tag;
 | 
			
		||||
 | 
			
		||||
  // Ищем первый свободный слот, параллельно автоинкрементируем тег
 | 
			
		||||
  while ((addr + sizeof(RTT_FlashHeader_t)) <= RTT_FLASH_SECTOR_END)
 | 
			
		||||
  {
 | 
			
		||||
    flash_hdr = (RTT_FlashHeader_t *)addr;
 | 
			
		||||
 | 
			
		||||
    if (flash_hdr->tag == 0xFFFFFFFF)
 | 
			
		||||
      break;  // Нашли свободное место
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    if((flash_hdr->tag & 0xFFFFFF00) == base_tag) // выбраный тег
 | 
			
		||||
    {
 | 
			
		||||
      if ((tag & 0xFF) == 0) // если он базовый - ищем последний
 | 
			
		||||
        next_tag = flash_hdr->tag + 1;  // автоинкремент
 | 
			
		||||
      else
 | 
			
		||||
        if(flash_hdr->tag == tag) // если он конкретный и уже существует - то ошибка
 | 
			
		||||
          return -1;  // конкретный тег уже занят
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    if(next_tag - tag > 0xFF)
 | 
			
		||||
      return -1; // автоинкремент слишком большой
 | 
			
		||||
    
 | 
			
		||||
    addr += sizeof(RTT_FlashHeader_t);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ((addr + sizeof(RTT_FlashHeader_t)) > RTT_FLASH_SECTOR_END)
 | 
			
		||||
    return -1;  // Нет свободного места
 | 
			
		||||
 | 
			
		||||
  // Копируем последние n символов из RTT
 | 
			
		||||
  char temp[RTT_FLASH_BUFFER_SIZE];
 | 
			
		||||
  unsigned valid_count = 0;
 | 
			
		||||
 | 
			
		||||
  for (unsigned i = 0; i < n; i++)
 | 
			
		||||
  {
 | 
			
		||||
    unsigned idx = (wr + buf_size - n + i) % buf_size;
 | 
			
		||||
    char c = up->pBuffer[idx];
 | 
			
		||||
    if (c != 0)
 | 
			
		||||
      temp[valid_count++] = c;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  RTT_FlashPrepare();
 | 
			
		||||
 | 
			
		||||
  // Формируем структуру в RAM
 | 
			
		||||
  RTT_FlashHeader_t flash_data;
 | 
			
		||||
  flash_data.tag  = next_tag;
 | 
			
		||||
  flash_data.size = valid_count;
 | 
			
		||||
  memcpy(flash_data.data, temp, valid_count);
 | 
			
		||||
 | 
			
		||||
  // Записываем структуру во Flash (по 4 байта)
 | 
			
		||||
  const uint32_t *p = (const uint32_t *)&flash_data;
 | 
			
		||||
  for (unsigned i = 0; i < sizeof(RTT_FlashHeader_t) / 4; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + i * 4, p[i]) != HAL_OK)
 | 
			
		||||
      return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  HAL_FLASH_Lock();
 | 
			
		||||
  __DSB();
 | 
			
		||||
  __ISB();
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  return (int)(next_tag&0xFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Читает последние символы RTT-буфера из Flash по тегу
 | 
			
		||||
  * @param tag        Базовый или конкретный идентификатор буфера.
 | 
			
		||||
  * @param Buffer     Буфер назначения для копирования данных
 | 
			
		||||
  * @param tail_size  Количество последних символов, которые нужно прочитать
 | 
			
		||||
  * @param read_size  Количество считанных символов
 | 
			
		||||
  * @return >=0 — номер буфера (тег) для записи, <0 — ошибка (тег не найден или структура повреждена)
 | 
			
		||||
  *
 | 
			
		||||
  * @details  Копирует последние tail_size символов из найденной записи Flash в Buffer.
 | 
			
		||||
  *           Тег может быть базовым или конкретным:
 | 
			
		||||
  *             - Если базовый (младший байт == 0) — будет прочитана последняя запись из группы.
 | 
			
		||||
  *             - Если конкретный (младший байт != 0) — прочитывается именно эта запись.
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_FORCEINLINE int RTT_ReadFromFlash(uint32_t tag, char *Buffer, uint32_t tail_size, uint32_t *read_size)
 | 
			
		||||
{
 | 
			
		||||
  if (!Buffer || tail_size == 0)
 | 
			
		||||
    return -1;  // Неверные параметры
 | 
			
		||||
 | 
			
		||||
  if (tag == 0xFFFFFFFF)
 | 
			
		||||
    return -1;  // Недопустимый тег
 | 
			
		||||
 | 
			
		||||
  uint32_t addr = RTT_FLASH_SECTOR_START;
 | 
			
		||||
  RTT_FlashHeader_t *flash_hdr = NULL;
 | 
			
		||||
  RTT_FlashHeader_t *target_hdr = NULL;
 | 
			
		||||
  uint32_t base_tag = tag & 0xFFFFFF00;
 | 
			
		||||
 | 
			
		||||
  // Поиск записи по тегу
 | 
			
		||||
  while ((addr + sizeof(RTT_FlashHeader_t)) <= RTT_FLASH_SECTOR_END)
 | 
			
		||||
  {
 | 
			
		||||
    flash_hdr = (RTT_FlashHeader_t *)addr;
 | 
			
		||||
 | 
			
		||||
    if (flash_hdr->tag == 0xFFFFFFFF)
 | 
			
		||||
      break;  // Достигнут конец записанных структур
 | 
			
		||||
 | 
			
		||||
    // выбраный тег
 | 
			
		||||
    if((flash_hdr->tag & 0xFFFFFF00) == base_tag) 
 | 
			
		||||
    {
 | 
			
		||||
      if ((tag & 0xFF) == 0) // если он базовый - ищем последний          
 | 
			
		||||
        target_hdr = flash_hdr;  // сохраняем последний в группе
 | 
			
		||||
      else
 | 
			
		||||
        if(flash_hdr->tag == tag) // если он конкретный и найден - берем его
 | 
			
		||||
        {
 | 
			
		||||
          target_hdr = flash_hdr;
 | 
			
		||||
          break;  // конкретный тег найден
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    addr += sizeof(RTT_FlashHeader_t);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!target_hdr) return -1; // Тег не найден
 | 
			
		||||
  
 | 
			
		||||
  // Проверка корректности размера
 | 
			
		||||
  if (target_hdr->size > RTT_FLASH_BUFFER_SIZE)
 | 
			
		||||
    return -1;  // Повреждённая запись  
 | 
			
		||||
 | 
			
		||||
  // Определяем количество читаемых символов
 | 
			
		||||
  uint32_t n = (tail_size > target_hdr->size) ? target_hdr->size : tail_size;
 | 
			
		||||
  // Начальная позиция для чтения последних tail_size символов
 | 
			
		||||
  uint32_t start = target_hdr->size - n;
 | 
			
		||||
  // Копируем данные из Flash в RAM
 | 
			
		||||
  memcpy(Buffer, &target_hdr->data[start], n);
 | 
			
		||||
  
 | 
			
		||||
  if(read_size != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    *read_size = n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  __DSB();
 | 
			
		||||
  __ISB();
 | 
			
		||||
 | 
			
		||||
  return (int)(target_hdr->tag & 0xFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Стирание сектора Flash с RTT-буфером
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_FORCEINLINE int RTT_EraseFlash(void)
 | 
			
		||||
{
 | 
			
		||||
  FLASH_EraseInitTypeDef eraseInit;
 | 
			
		||||
  uint32_t pageError = 0;
 | 
			
		||||
 | 
			
		||||
  RTT_FlashPrepare();
 | 
			
		||||
 | 
			
		||||
  eraseInit.TypeErase   = FLASH_TYPEERASE_SECTORS;
 | 
			
		||||
  eraseInit.Sector      = RTT_FLASH_SECTOR;
 | 
			
		||||
  eraseInit.NbSectors   = 1;
 | 
			
		||||
 | 
			
		||||
  if (HAL_FLASHEx_Erase(&eraseInit, &pageError) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
  HAL_FLASH_Lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** TRACE_RTT_FLASH
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
#else // HAL_MODULE_ENABLED && RTT_TRACE_ENABLE
 | 
			
		||||
#define RTT_FlashPrepare(...)
 | 
			
		||||
#define RTT_EraseFlash(...)    0
 | 
			
		||||
#define RTT_SaveToFlash(...)   0
 | 
			
		||||
#define RTT_ReadFromFlash(...) 0
 | 
			
		||||
#endif // HAL_MODULE_ENABLED && RTT_TRACE_ENABLE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
  * @addtogroup  TRACE_HARDFAULT    Hardfault trace defines
 | 
			
		||||
  * @ingroup     TRACE
 | 
			
		||||
  * @brief       Модуль трассировки HardFault с возможностью сохранения RTT буфера во Flash
 | 
			
		||||
  * @details
 | 
			
		||||
  * Этот модуль позволяет сохранять контекст процессора и последние символы RTT буфера при возникновении HardFault.
 | 
			
		||||
  *
 | 
			
		||||
  * Механизм работы:
 | 
			
		||||
  *   - При срабатывании HardFault вызывается HF_HandleFault(), который:
 | 
			
		||||
  *       1. Получает указатель на стек, где произошёл HardFault (MSP или PSP).
 | 
			
		||||
  *       2. Выводит значения регистров R0-R3, R12, LR, PC, PSR и системных регистров SCB.
 | 
			
		||||
  *       3. Формирует строку с регистрами и копирует последние символы RTT буфера.
 | 
			
		||||
  *       4. Сохраняет данные во Flash с базовым тегом HF_RTT_TAG_BASE.
 | 
			
		||||
  *   - Для восстановления последнего HardFault используется HF_CheckRecovered(), который:
 | 
			
		||||
  *       1. Читает запись во Flash по базовому тегу.
 | 
			
		||||
  *       2. Выводит сохранённый RTT буфер и контекст регистров.
 | 
			
		||||
  *       3. Опционально стирает Flash после восстановления.
 | 
			
		||||
  * 
 | 
			
		||||
  * Параметры:
 | 
			
		||||
  * - @ref HARDFAULT_SERIAL_TRACE   - Включить обработку и serial трассировку Hardfault
 | 
			
		||||
  *   Если отключена то вставляются заглушки, никак не влияющие на параметры и остальную программу
 | 
			
		||||
  * - @ref HF_RTT_TAG_BASE          - Базовый тег RTT Flash для HardFault 
 | 
			
		||||
  * - @ref HF_RTT_TAIL_SIZE         - Размер буфера RTT, который сохранится при Hardfault
 | 
			
		||||
  * - @ref HF_STACK_DUMP_WORDS      - Сколько слов стека будет проанализировано во время Hardfault
 | 
			
		||||
  * - @ref HF_FLASH_ADDR            - Адрес FLASH куда положится RTT буфер
 | 
			
		||||
  * - @ref HF_RAM_END               - Конец RAM памяти (чтобы во время анализа стека не выйти за пределы)
 | 
			
		||||
  * 
 | 
			
		||||
  @code
 | 
			
		||||
  void Hardfault()
 | 
			
		||||
  {
 | 
			
		||||
    HF_HandleFault();
 | 
			
		||||
    NVIC_SystemReset();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int main()
 | 
			
		||||
  {
 | 
			
		||||
    if(HF_CheckRecovered(0))
 | 
			
		||||
    {
 | 
			
		||||
      //set hardfault error
 | 
			
		||||
      RTT_EraseFlash(); // erase rtt flash after message readed
 | 
			
		||||
    }
 | 
			
		||||
  }  
 | 
			
		||||
  @endcode
 | 
			
		||||
  * @{
 | 
			
		||||
  */
 | 
			
		||||
#if defined(HAL_MODULE_ENABLED) && defined(HARDFAULT_SERIAL_TRACE)
 | 
			
		||||
 | 
			
		||||
#ifndef HF_RTT_TAIL_SIZE
 | 
			
		||||
#define HF_RTT_TAIL_SIZE  RTT_FLASH_BUFFER_SIZE ///< Размер буфера RTT, который сохранится при Hardfault
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Контекст стек-фрейма процессора при HardFault
 | 
			
		||||
  * @details Сохраняет регистры R0-R3, R12, LR, PC, PSR для последующего анализа.
 | 
			
		||||
  */
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint32_t r0;   ///< Регистр R0
 | 
			
		||||
  uint32_t r1;   ///< Регистр R1
 | 
			
		||||
  uint32_t r2;   ///< Регистр R2
 | 
			
		||||
  uint32_t r3;   ///< Регистр R3
 | 
			
		||||
  uint32_t r12;  ///< Регистр R12
 | 
			
		||||
  uint32_t lr;   ///< Link Register
 | 
			
		||||
  uint32_t pc;   ///< Program Counter
 | 
			
		||||
  uint32_t psr;  ///< Program Status Register
 | 
			
		||||
} HF_StackFrame_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Проверка и вывод последнего HardFault-трейса из Flash
 | 
			
		||||
  * @details
 | 
			
		||||
  * Функция ищет последнюю запись HardFault по базовому тегу HF_RTT_TAG_BASE
 | 
			
		||||
  * и выводит её содержимое в консоль. После успешного вывода Flash можно опционально очистить.
 | 
			
		||||
  *
 | 
			
		||||
  * @return int
 | 
			
		||||
  *   - 1 — данные HardFault найдены и выведены
 | 
			
		||||
  *   - 0 — данные отсутствуют или тег не найден
 | 
			
		||||
  * 
 | 
			
		||||
  * @note Вызов рекомендуется при инициализации приложения для анализа предыдущего сбоя.
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_FORCEINLINE int HF_CheckRecovered(int erase)
 | 
			
		||||
{
 | 
			
		||||
  char buffer[RTT_FLASH_BUFFER_SIZE];
 | 
			
		||||
  uint32_t read_size = 0;
 | 
			
		||||
  int n_hardfault = RTT_ReadFromFlash(HF_RTT_TAG_BASE, buffer, HF_RTT_TAIL_SIZE, &read_size);
 | 
			
		||||
  if (n_hardfault > 0)
 | 
			
		||||
  {
 | 
			
		||||
    my_printf("\n--- Recovered HardFault RTT buffer #%u ---\n", n_hardfault);
 | 
			
		||||
    for (int i = 0; i < read_size; i++)
 | 
			
		||||
    {
 | 
			
		||||
      char c = buffer[i];
 | 
			
		||||
      if (c == 0 || c == (char)0xFF) break;
 | 
			
		||||
      my_printf("%c", c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(erase)
 | 
			
		||||
      RTT_EraseFlash();
 | 
			
		||||
    my_printf("\n--------- HardFault Dump End ---------\n");
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static HF_StackFrame_t *stack_frame;
 | 
			
		||||
static uint32_t stack_dump[HF_STACK_DUMP_WORDS];
 | 
			
		||||
static void *ret_adr[10] = {0};
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Обработчик HardFault
 | 
			
		||||
  * @details
 | 
			
		||||
  * Вызывается из прерывания HardFault или в любом месте где понятно что ошибка критическая.
 | 
			
		||||
  * Последовательно выполняет:
 | 
			
		||||
  *   1. Определяет активный стек (MSP или PSP) на момент сбоя.
 | 
			
		||||
  *   2. Сохраняет значения регистров R0-R3, R12, LR, PC, PSR.
 | 
			
		||||
  *   3. Выводит системные регистры CFSR, HFSR, DFSR, AFSR, MMFAR, BFAR.
 | 
			
		||||
  *   4. Формирует stack trace с 3 уровнями возврата.
 | 
			
		||||
  *   5. Копирует последние символы RTT буфера.
 | 
			
		||||
  *   6. Сохраняет все данные во Flash через RTT_SaveToFlash с базовым тегом HF_RTT_TAG_BASE.
 | 
			
		||||
  *
 | 
			
		||||
  * @note Функция защищена, так как вызывается в контексте сбоя — минимизирует использование вызовов HAL.
 | 
			
		||||
  */
 | 
			
		||||
__STATIC_FORCEINLINE void HF_HandleFault(void)
 | 
			
		||||
{
 | 
			
		||||
    // Получаем указатель на стек, где произошёл HardFault
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "TST lr, #4       \n"
 | 
			
		||||
        "ITE EQ           \n"
 | 
			
		||||
        "MRSEQ %[ptr], MSP\n"
 | 
			
		||||
        "MRSNE %[ptr], PSP\n"
 | 
			
		||||
        : [ptr] "=r"(stack_frame)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    my_printf("\n===== HardFault occurred! =====\n");
 | 
			
		||||
    my_printf("R0  = 0x%08X\n", stack_frame->r0);
 | 
			
		||||
    my_printf("R1  = 0x%08X\n", stack_frame->r1);
 | 
			
		||||
    my_printf("R2  = 0x%08X\n", stack_frame->r2);
 | 
			
		||||
    my_printf("R3  = 0x%08X\n", stack_frame->r3);
 | 
			
		||||
    my_printf("R12 = 0x%08X\n", stack_frame->r12);
 | 
			
		||||
    my_printf("LR  = 0x%08X\n", stack_frame->lr);
 | 
			
		||||
    my_printf("PC  = 0x%08X\n", stack_frame->pc);
 | 
			
		||||
    my_printf("PSR = 0x%08X\n", stack_frame->psr);
 | 
			
		||||
 | 
			
		||||
    my_printf("CFSR  = 0x%08X\n", SCB->CFSR);
 | 
			
		||||
    my_printf("HFSR  = 0x%08X\n", SCB->HFSR);
 | 
			
		||||
    my_printf("DFSR  = 0x%08X\n", SCB->DFSR);
 | 
			
		||||
    my_printf("AFSR  = 0x%08X\n", SCB->AFSR);
 | 
			
		||||
    my_printf("MMFAR = 0x%08X\n", SCB->MMFAR);
 | 
			
		||||
    my_printf("BFAR  = 0x%08X\n", SCB->BFAR);
 | 
			
		||||
    
 | 
			
		||||
    // --- Stack trace ---
 | 
			
		||||
    my_printf("--- Stack trace ---\n");
 | 
			
		||||
    ret_adr[0] = __builtin_return_address(0);
 | 
			
		||||
    ret_adr[1] = __builtin_return_address(1);
 | 
			
		||||
    ret_adr[2] = __builtin_return_address(2);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < 3; i++)  // развернуть n уровней
 | 
			
		||||
    {
 | 
			
		||||
      if(ret_adr[i])
 | 
			
		||||
        my_printf("  #%d: 0x%08lX\r\n", i, ret_adr[i]); // -1 для Thumb
 | 
			
		||||
    }
 | 
			
		||||
    RTT_SaveToFlash(HF_RTT_TAG_BASE, HF_RTT_TAIL_SIZE);
 | 
			
		||||
}
 | 
			
		||||
#else // HAL_MODULE_ENABLED && HARDFAULT_SERIAL_TRACE
 | 
			
		||||
#define HF_CheckRecovered(...) 0
 | 
			
		||||
#define HF_HandleFault(...)
 | 
			
		||||
#endif // HAL_MODULE_ENABLED && HARDFAULT_SERIAL_TRACE
 | 
			
		||||
/** TRACE_HARDFAULT
 | 
			
		||||
  * @}
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //__TRACE_H_
 | 
			
		||||
@ -1,163 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file trackers.h
 | 
			
		||||
* @brief Заголочный файл для работы с трекерами @ref TRACKERS.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @addtogroup TRACKERS        Trackers defines
 | 
			
		||||
* @ingroup    MYLIBS_DEFINES
 | 
			
		||||
* @brief      Дефайны для работы с трекерами
 | 
			
		||||
* @details    
 | 
			
		||||
Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars). 
 | 
			
		||||
Структура состоит из следующих элементов: 
 | 
			
		||||
- cnt_ok
 | 
			
		||||
- cnt_err
 | 
			
		||||
- cnt_warn
 | 
			
		||||
- user[num_user_vars]    
 | 
			
		||||
Также есть ряд функций (дефайнов) для обращения к элементам этой структуры.
 | 
			
		||||
 | 
			
		||||
Параметры для конфигурации:
 | 
			
		||||
- @ref TRACKERS_ENABLE - Включить трекеры
 | 
			
		||||
  Если трекеры @ref TRACKERS_ENABLE отключены, то все дефайны определяются как ничего 
 | 
			
		||||
  и на производительность кода не влияют  
 | 
			
		||||
 | 
			
		||||
@par Пример:
 | 
			
		||||
 | 
			
		||||
Определяем typedef трекера измерений Measure_TrackerTypeDef
 | 
			
		||||
 | 
			
		||||
@verbatim
 | 
			
		||||
  typedef TrackerTypeDef(MEASURE_USER_VARS_NUMB) Measure_TrackerTypeDef;
 | 
			
		||||
@endverbatim
 | 
			
		||||
 | 
			
		||||
И через @ref Measure_TrackerTypeDef структура подключается в другие структуры
 | 
			
		||||
 | 
			
		||||
Для работы с структурой можно использовать функции:
 | 
			
		||||
- Для получения значения:
 | 
			
		||||
  - TrackerGet_Ok()
 | 
			
		||||
  - TrackerGet_Err()
 | 
			
		||||
  - TrackerGet_Warn()
 | 
			
		||||
  - TrackerGet_User(n)
 | 
			
		||||
  
 | 
			
		||||
- Для записи значения:
 | 
			
		||||
  - TrackerCnt_Ok()
 | 
			
		||||
  - TrackerCnt_Err()
 | 
			
		||||
  - TrackerCnt_Warn()
 | 
			
		||||
  - TrackerCnt_User()
 | 
			
		||||
  - TrackerWrite_User(n)
 | 
			
		||||
  
 | 
			
		||||
- Для очищения значения:
 | 
			
		||||
  - TrackerClear_All()
 | 
			
		||||
  - TrackerClear_Ok()
 | 
			
		||||
  - TrackerClear_Err()
 | 
			
		||||
  - TrackerClear_Warn()
 | 
			
		||||
  - TrackerClear_User(n)
 | 
			
		||||
  - TrackerClear_UserAll()
 | 
			
		||||
* @{  
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#ifndef __TRACKERS_H_
 | 
			
		||||
#define __TRACKERS_H_
 | 
			
		||||
#include "mylibs_defs.h"
 | 
			
		||||
 | 
			
		||||
#ifdef TRACKERS_ENABLE
 | 
			
		||||
  /** 
 | 
			
		||||
    * @brief Структура для счетчиков отладки
 | 
			
		||||
    * @param num_user_vars - количество пользовательских переменных
 | 
			
		||||
    * @details Содержит счетчик для успешных событый (cnt_ok),
 | 
			
		||||
    * счетчик для ошибок (cnt_err), счетчик для предупреждений (cnt_warn).
 | 
			
		||||
    *
 | 
			
		||||
    * Также есть возможность объявить пользовательские переменные в 
 | 
			
		||||
    * количестве <num_user_vars> штук.
 | 
			
		||||
    */
 | 
			
		||||
  #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(uint32_t))
 | 
			
		||||
  /** @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 Считать счетчик успешных событий */
 | 
			
		||||
  #define TrackerGet_Ok(_cntstruct_)                              (_cntstruct_).cnt_ok
 | 
			
		||||
  /** @brief Считать счетчик ошибок */
 | 
			
		||||
  #define TrackerGet_Err(_cntstruct_)                             (_cntstruct_).cnt_err
 | 
			
		||||
  /** @brief Считать счетчик предупреждений */
 | 
			
		||||
  #define TrackerGet_Warn(_cntstruct_)                            (_cntstruct_).cnt_warn
 | 
			
		||||
  /** 
 | 
			
		||||
    * @brief Считать пользовательскую переменную 
 | 
			
		||||
    * @note   Здесь нет проверки - существует ли пользовательская переменная! 
 | 
			
		||||
    *         Есть возможность выйти за границы структуры!!! 
 | 
			
		||||
    *         Чтобы этого избежать можно использовать дефайн #ref assert_usertracker()
 | 
			
		||||
    @verbatim   
 | 
			
		||||
      if(assert_usertracker(struct, 0)) {
 | 
			
		||||
          TrackerGet_User(struct, 0)
 | 
			
		||||
      }
 | 
			
		||||
    @endverbatim
 | 
			
		||||
    */
 | 
			
		||||
  #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_)                               0
 | 
			
		||||
  #define assert_tracecnt(_cntstruct_, _uservarnumb_)           0
 | 
			
		||||
  #define if_assert_usertracker(_cntstruct_, _uservarnumb_)     if(0)
 | 
			
		||||
  #define tern_assert_usertracker(_cntstruct_, _uservarnumb_)   0
 | 
			
		||||
 | 
			
		||||
  #define TrackerGet_Ok(_cntstruct_)                            dummy
 | 
			
		||||
  #define TrackerGet_Err(_cntstruct_)                           dummy
 | 
			
		||||
  #define TrackerGet_Warn(_cntstruct_)                          dummy 
 | 
			
		||||
  #define TrackerGet_User(_cntstruct_, _uservarnumb_)           dummy
 | 
			
		||||
  
 | 
			
		||||
  #define TrackerCnt_Ok(_cntstruct_)                              
 | 
			
		||||
  #define TrackerCnt_Err(_cntstruct_)                             
 | 
			
		||||
  #define TrackerCnt_Warn(_cntstruct_)                            
 | 
			
		||||
  #define TrackerCnt_User(_cntstruct_, _uservarnumb_)                 
 | 
			
		||||
  #define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
 | 
			
		||||
 | 
			
		||||
  #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_
 | 
			
		||||
@ -1,192 +0,0 @@
 | 
			
		||||
#include "general_flash.h"
 | 
			
		||||
FLASH_EraseInitTypeDef EraseInitStruct;
 | 
			
		||||
extern HAL_StatusTypeDef res_hal;
 | 
			
		||||
unsigned CRC_Update;
 | 
			
		||||
//uint32_t PAGE_OFFSET = ((uint32_t)((4-1) * 0x0400));
 | 
			
		||||
uint32_t PAGE_NUMB = 127;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Записать в память данные, произвольного размера */
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_Data(uint32_t* Address, uint8_t* Data, int Data_size)
 | 
			
		||||
{
 | 
			
		||||
  HAL_StatusTypeDef res_hal;
 | 
			
		||||
  
 | 
			
		||||
  int data_cnt = 0;
 | 
			
		||||
  uint32_t adr;
 | 
			
		||||
  uint32_t word_data;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  res_hal = HAL_FLASH_Unlock();
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
 | 
			
		||||
  for (adr = *Address; adr < *Address + Data_size; adr = adr + 4)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    word_data = (
 | 
			
		||||
      Data[data_cnt] |
 | 
			
		||||
      Data[data_cnt + 1] << 8 |
 | 
			
		||||
      Data[data_cnt + 2] << 16 |
 | 
			
		||||
      Data[data_cnt + 3] << 24);
 | 
			
		||||
    
 | 
			
		||||
    res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, adr, word_data);
 | 
			
		||||
 | 
			
		||||
    if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
 | 
			
		||||
    data_cnt += 4;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *Address += Data_size;
 | 
			
		||||
  res_hal = HAL_FLASH_Lock();
 | 
			
		||||
 | 
			
		||||
  return res_hal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
HAL_StatusTypeDef FLASH_Enable_DualBankMode(void)
 | 
			
		||||
{
 | 
			
		||||
  HAL_StatusTypeDef res_hal;
 | 
			
		||||
  FLASH_AdvOBProgramInitTypeDef OB_DualBank;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Unlock();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_OB_Unlock();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  FLASH->OPTCR |= FLASH_OPTCR_DB1M;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_OB_Launch();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_OB_Lock();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Lock();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
    
 | 
			
		||||
  
 | 
			
		||||
  return res_hal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Убрать защиту */
 | 
			
		||||
HAL_StatusTypeDef FLASH_WriteProtection(uint32_t BankN, uint32_t WriteProtection)
 | 
			
		||||
{
 | 
			
		||||
  HAL_StatusTypeDef res_hal;
 | 
			
		||||
  FLASH_OBProgramInitTypeDef OBInit;
 | 
			
		||||
  
 | 
			
		||||
    // Очистка всех возможных ошибок
 | 
			
		||||
  FLASH->SR |= FLASH_FLAG_WRPERR  // Write Protection Error
 | 
			
		||||
             | FLASH_FLAG_PGSERR  // Programming Sequence Error
 | 
			
		||||
             | FLASH_FLAG_PGAERR  // Programming Alignment Error
 | 
			
		||||
             | FLASH_FLAG_OPERR;  // Operation Error
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Unlock();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_OB_Unlock(); // Разблокировка Option Bytes
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
 | 
			
		||||
  // Считываем текущую конфигурацию Option Bytes
 | 
			
		||||
  HAL_FLASHEx_OBGetConfig(&OBInit);
 | 
			
		||||
 | 
			
		||||
  // Отключаем защиту на всех секторах второго банка
 | 
			
		||||
  OBInit.OptionType = OPTIONBYTE_WRP;
 | 
			
		||||
  OBInit.WRPState = WriteProtection; // Снять защиту
 | 
			
		||||
  OBInit.WRPSector = OB_WRP_SECTOR_12; // Снять защиту
 | 
			
		||||
  OBInit.Banks = BankN; // Указываем второй банк
 | 
			
		||||
  res_hal = HAL_FLASHEx_OBProgram(&OBInit);
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
 | 
			
		||||
  // Записываем изменения и перезагружаем чип
 | 
			
		||||
  res_hal = HAL_FLASH_OB_Launch();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  // Считываем текущую конфигурацию Option Bytes
 | 
			
		||||
  HAL_FLASHEx_OBGetConfig(&OBInit);
 | 
			
		||||
  
 | 
			
		||||
// Блокировка Option Bytes
 | 
			
		||||
  res_hal = HAL_FLASH_OB_Lock(); 
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Lock();
 | 
			
		||||
  if (res_hal != HAL_OK) 
 | 
			
		||||
    return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  return res_hal;
 | 
			
		||||
}
 | 
			
		||||
//-----------------ELEMENTARY FUNCTIONS---------------------
 | 
			
		||||
/* functions for reading bytes/halswords/words */
 | 
			
		||||
uint8_t FLASH_Read_Byte(uint32_t add)
 | 
			
		||||
{
 | 
			
		||||
  return (*(__IO uint8_t*)(add));
 | 
			
		||||
}
 | 
			
		||||
uint16_t FLASH_Read_HalfWord(uint32_t add)
 | 
			
		||||
{
 | 
			
		||||
  return (*(__IO uint16_t*)(add));
 | 
			
		||||
}
 | 
			
		||||
uint32_t FLASH_Read_Word(uint32_t add)
 | 
			
		||||
{
 | 
			
		||||
  return (*(__IO uint32_t*)(add));
 | 
			
		||||
}
 | 
			
		||||
/* functions for writing bytes/halswords/words */
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_Byte(uint32_t Address, uint8_t Data)
 | 
			
		||||
{ 
 | 
			
		||||
  HAL_StatusTypeDef res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Unlock();
 | 
			
		||||
  
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, (uint8_t)(Data));
 | 
			
		||||
  
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
 | 
			
		||||
  res_hal = HAL_FLASH_Lock(); 
 | 
			
		||||
  return res_hal;
 | 
			
		||||
}
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_HalfWord(uint32_t Address, uint16_t Data)
 | 
			
		||||
{
 | 
			
		||||
  HAL_StatusTypeDef res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Unlock();
 | 
			
		||||
  
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, (uint16_t)(Data));
 | 
			
		||||
  
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
 | 
			
		||||
  res_hal = HAL_FLASH_Lock(); 
 | 
			
		||||
  return res_hal;
 | 
			
		||||
}
 | 
			
		||||
HAL_StatusTypeDef FLASH_Write_Word(uint32_t Address, uint32_t Data)
 | 
			
		||||
{
 | 
			
		||||
  HAL_StatusTypeDef res_hal;
 | 
			
		||||
  
 | 
			
		||||
  res_hal = HAL_FLASH_Unlock();
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
 | 
			
		||||
  res_hal = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, (uint32_t)(Data)); 
 | 
			
		||||
  if (res_hal != HAL_OK) return res_hal;
 | 
			
		||||
 | 
			
		||||
  res_hal = HAL_FLASH_Lock(); 
 | 
			
		||||
  return res_hal;
 | 
			
		||||
}
 | 
			
		||||
//----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@ -1,292 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_spi.c
 | 
			
		||||
* @brief Модуль для инициализации SPI.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @details
 | 
			
		||||
*
 | 
			
		||||
* Функции:
 | 
			
		||||
*   - SPI_Base_Init             Инициализация SPI 
 | 
			
		||||
* 
 | 
			
		||||
* Functions: spi initialize
 | 
			
		||||
*   - SPI_GPIO_Init             Инициализация GPIO для SPI
 | 
			
		||||
*   - SPI_DMA_Init              Инициализация DMA для SPI
 | 
			
		||||
*   - SPI_MspInit               Аналог HAL_MspInit для SPI
 | 
			
		||||
*   - SPI_MspDeInit             Аналог HAL_MspDeInit для SPI
 | 
			
		||||
*
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#include "general_spi.h"
 | 
			
		||||
#include "general_gpio.h"
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//------------------------SPI INIT FUNCTIONS------------------------
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize SPI with SPI_SettingsTypeDef structure.
 | 
			
		||||
  * @param  sspi - указатель на структуру с настройками SPI.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   SPI_SettingsTypeDef структура содержит хендл SPI и настройки перефирии (GPIO)
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef SPI_Base_Init(SPI_SettingsTypeDef *sspi)
 | 
			
		||||
{ // function takes setting structure for init
 | 
			
		||||
  
 | 
			
		||||
  // check is settings are valid
 | 
			
		||||
  if(Check_SPI_Init_Struct(sspi) != HAL_OK)
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  SPI_MspInit(&sspi->hspi); 
 | 
			
		||||
  
 | 
			
		||||
  if (HAL_SPI_Init(&sspi->hspi) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // init gpio from SPISettings structure
 | 
			
		||||
  SPI_GPIO_Init(sspi);
 | 
			
		||||
  
 | 
			
		||||
//  // init dma from SPISettings structure if need
 | 
			
		||||
//  if (sspi->DMAChannel != 0)
 | 
			
		||||
//    SPI_DMA_Init(&sspi->hspi, sspi->hspi.hdmarx, sspi->DMAChannel, sspi->DMA_CHANNEL_X);
 | 
			
		||||
    
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize GPIO for SPI.
 | 
			
		||||
  * @param  GPIOx       - порт для настройки.
 | 
			
		||||
  * @param  GPIO_PIN_RX - пин для настройки на прием.
 | 
			
		||||
  * @param  GPIO_PIN_TX - пин для настройки на передачу.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_GPIO_Init(SPI_SettingsTypeDef *sspi)
 | 
			
		||||
{   
 | 
			
		||||
  GPIO_InitTypeDef GPIO_InitStruct = {0}; 
 | 
			
		||||
  // GPIO INIT  
 | 
			
		||||
  GPIO_Clock_Enable(sspi->CLK_GPIOx);
 | 
			
		||||
  GPIO_Clock_Enable(sspi->MISO_GPIOx);
 | 
			
		||||
  GPIO_Clock_Enable(sspi->MOSI_GPIOx);  
 | 
			
		||||
    // CLK PIN INIT
 | 
			
		||||
  GPIO_InitStruct.Pin = sspi->CLK_PIN;
 | 
			
		||||
  GPIO_InitStruct.Alternate = sspi->CLK_GPIO_AlternageFunc;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 | 
			
		||||
  HAL_GPIO_Init(sspi->CLK_GPIOx, &GPIO_InitStruct);
 | 
			
		||||
  // MISO PIN INIT
 | 
			
		||||
  GPIO_InitStruct.Pin = sspi->MISO_PIN;
 | 
			
		||||
  GPIO_InitStruct.Alternate = sspi->MISO_GPIO_AlternageFunc;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 | 
			
		||||
  HAL_GPIO_Init(sspi->MISO_GPIOx, &GPIO_InitStruct);
 | 
			
		||||
  // MOSI PIN INIT
 | 
			
		||||
  GPIO_InitStruct.Pin = sspi->MOSI_PIN;
 | 
			
		||||
  GPIO_InitStruct.Alternate = sspi->MOSI_GPIO_AlternageFunc;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 | 
			
		||||
  HAL_GPIO_Init(sspi->MOSI_GPIOx, &GPIO_InitStruct);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize DMA for SPI.
 | 
			
		||||
  * @param  hspi        - указатель на хендл SPI для настройки DMA.
 | 
			
		||||
  * @param  hdma_rx       - указатель на хендл DMA для линии приема SPI.
 | 
			
		||||
  * @param  DMAChannel    - указатель на канал DMA/поток DMA в STM32F407.
 | 
			
		||||
  * @param  DMA_CHANNEL_X - канал DMA.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_DMA_Init(SPI_HandleTypeDef *hspi, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X)
 | 
			
		||||
{ // function takes spi and dma handlers and dmachannel for spi
 | 
			
		||||
//  // for now only dma rx is supported, tx maybe later if needed
 | 
			
		||||
//    // calc defines on boot_project_setup.h
 | 
			
		||||
 | 
			
		||||
//  /* SPI3 DMA Init */
 | 
			
		||||
//  /* SPI3_RX Init */
 | 
			
		||||
//  
 | 
			
		||||
//  hdma_rx->Instance = DMAChannel;
 | 
			
		||||
//#if defined(STM32F407xx) // dma channel choose for 407
 | 
			
		||||
//  hdma_rx->Init.Channel = DMA_CHANNEL_X;
 | 
			
		||||
//#endif
 | 
			
		||||
//  hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
 | 
			
		||||
//  hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
 | 
			
		||||
//  hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
 | 
			
		||||
//  hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 | 
			
		||||
//  hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 | 
			
		||||
//  hdma_rx->Init.Mode = DMA_CIRCULAR;
 | 
			
		||||
//  hdma_rx->Init.Priority = DMA_PRIORITY_LOW;
 | 
			
		||||
//  if (HAL_DMA_Init(hdma_rx) != HAL_OK)
 | 
			
		||||
//  {
 | 
			
		||||
//    MyLibs_Error_Handler();
 | 
			
		||||
//  }
 | 
			
		||||
 | 
			
		||||
//  __USER_LINKDMA(hspi,hdmarx,hdma_rx);  
 | 
			
		||||
//  
 | 
			
		||||
 | 
			
		||||
//  // __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx
 | 
			
		||||
//  // so you get error because hal uses . insted of ->
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize SPI & DMA clock and interrupt.
 | 
			
		||||
  * @param  hspi - указатель на хендл SPI для инициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с иницилизацией неиспользуемых SPI,
 | 
			
		||||
            дефайнами в general_spi.h определяются используемые SPI.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_MspInit(SPI_HandleTypeDef *hspi) // analog for hal function
 | 
			
		||||
{   
 | 
			
		||||
  // rcc, dma and interrupt init for SPIs
 | 
			
		||||
  // GPIO init was moved to own functions SPI_GPIO_Init  
 | 
			
		||||
  if(0);
 | 
			
		||||
#ifdef USE_SPI1
 | 
			
		||||
  else if(hspi->Instance==SPI1)
 | 
			
		||||
  {
 | 
			
		||||
  
 | 
			
		||||
//  /* DMA2 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA2_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* SPI1 clock enable */
 | 
			
		||||
  __HAL_RCC_SPI1_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* SPI1 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(SPI1_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_SPI1
 | 
			
		||||
#ifdef USE_SPI2
 | 
			
		||||
  else if(hspi->Instance==SPI2)
 | 
			
		||||
  {
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* SPI2 clock enable */
 | 
			
		||||
  __HAL_RCC_SPI2_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* SPI2 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(SPI2_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_SPI2
 | 
			
		||||
#ifdef USE_SPI3
 | 
			
		||||
  else if(hspi->Instance==SPI3)
 | 
			
		||||
  {     
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* SPI3 clock enable */
 | 
			
		||||
  __HAL_RCC_SPI3_CLK_ENABLE();  
 | 
			
		||||
  /* SPI3 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(SPI3_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_SPI3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Deinitialize SPI & DMA clock and interrupt.
 | 
			
		||||
  * @param  hspi - указатель на хендл SPI для деинициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с деиницилизацией неиспользуемых SPI,
 | 
			
		||||
            дефайнами определяются используемые SPI.
 | 
			
		||||
  */
 | 
			
		||||
void SPI_MspDeInit(SPI_HandleTypeDef *hspi) // analog for hal function
 | 
			
		||||
{   
 | 
			
		||||
  // rcc, dma and interrupt init for SPIs
 | 
			
		||||
  // GPIO init was moved to own functions SPI_GPIO_Init  
 | 
			
		||||
  if(0);
 | 
			
		||||
#ifdef USE_SPI1
 | 
			
		||||
  else if(hspi->Instance==SPI1)
 | 
			
		||||
  {
 | 
			
		||||
  
 | 
			
		||||
//  /* DMA2 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA2_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* SPI1 clock reset */
 | 
			
		||||
  __HAL_RCC_SPI1_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_SPI1_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_SPI1
 | 
			
		||||
#ifdef USE_SPI2
 | 
			
		||||
  else if(hspi->Instance==SPI2)
 | 
			
		||||
  {
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* SPI2 clock reset */
 | 
			
		||||
  __HAL_RCC_SPI2_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_SPI2_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_SPI2
 | 
			
		||||
#ifdef USE_SPI3
 | 
			
		||||
  else if(hspi->Instance==SPI3)
 | 
			
		||||
  {     
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* SPI3 clock reset */
 | 
			
		||||
  __HAL_RCC_SPI3_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_SPI3_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_SPI3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Check that spi init structure have correct values.
 | 
			
		||||
  * @param  sspi - указатель на структуру с настройками SPI.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef Check_SPI_Init_Struct(SPI_SettingsTypeDef *sspi)
 | 
			
		||||
{
 | 
			
		||||
  // check is settings are valid
 | 
			
		||||
  if (!IS_SPI_ALL_INSTANCE(sspi->hspi.Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  // check init settings
 | 
			
		||||
  if (!IS_SPI_MODE(sspi->hspi.Init.Mode))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_DIRECTION(sspi->hspi.Init.Direction))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_DATASIZE(sspi->hspi.Init.DataSize))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_BAUDRATE_PRESCALER(sspi->hspi.Init.BaudRatePrescaler))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_CPOL(sspi->hspi.Init.CLKPolarity))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_CPHA(sspi->hspi.Init.CLKPhase))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_NSS(sspi->hspi.Init.NSS))
 | 
			
		||||
    return HAL_ERROR;   
 | 
			
		||||
  if (!IS_SPI_FIRST_BIT(sspi->hspi.Init.FirstBit))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_CRC_CALCULATION(sspi->hspi.Init.CRCCalculation))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_CRC_POLYNOMIAL(sspi->hspi.Init.NSS) && 
 | 
			
		||||
    (sspi->hspi.Init.CRCCalculation != SPI_CRCCALCULATION_DISABLE))
 | 
			
		||||
      return HAL_ERROR; 
 | 
			
		||||
  if (!IS_SPI_TIMODE(sspi->hspi.Init.TIMode))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  // check gpio
 | 
			
		||||
  if (!IS_GPIO_ALL_INSTANCE(sspi->CLK_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MISO_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MOSI_GPIOx))
 | 
			
		||||
    return HAL_ERROR; 
 | 
			
		||||
  if (!IS_GPIO_PIN(sspi->CLK_PIN) && !IS_GPIO_PIN(sspi->MISO_PIN) && !IS_GPIO_PIN(sspi->MOSI_PIN)) // if both pins arent set up
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
@ -1,380 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
  **************************************************************************
 | 
			
		||||
  * @file general_uart.c
 | 
			
		||||
  * @brief Модуль для инициализации UART.
 | 
			
		||||
  **************************************************************************
 | 
			
		||||
  * //-------------------Функции-------------------//
 | 
			
		||||
  * @verbatim
 | 
			
		||||
  * Functions: users
 | 
			
		||||
  *   - UART_Base_Init              Инициализация UART 
 | 
			
		||||
  * 
 | 
			
		||||
  * Functions: uart initialize
 | 
			
		||||
  *   - UART_GPIO_Init              Инициализация GPIO для UART
 | 
			
		||||
  *   - UART_DMA_Init               Инициализация DMA для UART
 | 
			
		||||
  *   - UART_MspInit                Аналог HAL_MspInit для UART
 | 
			
		||||
  *   - UART_MspDeInit              Аналог HAL_MspDeInit для UART
 | 
			
		||||
  * @endverbatim
 | 
			
		||||
***************************************************************************/
 | 
			
		||||
#include "general_uart.h"
 | 
			
		||||
#include "general_gpio.h"
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//------------------------UART INIT FUNCTIONS------------------------
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize UART with UART_SettingsTypeDef structure.
 | 
			
		||||
  * @param  suart - указатель на структуру с настройками UART.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   Данная структура содержит хендл ЮАРТ и настройки перефирии (GPIO)
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef UART_Base_Init(UART_SettingsTypeDef *suart)
 | 
			
		||||
{ // function takes setting structure for init
 | 
			
		||||
  
 | 
			
		||||
  // check is settings are valid
 | 
			
		||||
  if(Check_UART_Init_Struct(suart) != HAL_OK)
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
    
 | 
			
		||||
  suart->huart.Init.Mode = UART_MODE_TX_RX;
 | 
			
		||||
  
 | 
			
		||||
  UART_MspInit(&suart->huart);
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  if (HAL_UART_Init(&suart->huart) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // init gpio from UARTSettings structure
 | 
			
		||||
  UART_GPIO_Init(suart->GPIOx, suart->GPIO_PIN_RX, suart->GPIO_PIN_TX);
 | 
			
		||||
  
 | 
			
		||||
  __HAL_UART_ENABLE_IT(&suart->huart, UART_IT_IDLE);
 | 
			
		||||
  // init dma from UARTSettings structure if need
 | 
			
		||||
  if (suart->DMAChannel != 0)
 | 
			
		||||
    UART_DMA_Init(&suart->huart, suart->huart.hdmarx, suart->DMAChannel, suart->DMA_CHANNEL_X);
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize GPIO for UART.
 | 
			
		||||
  * @param  GPIOx       - порт для настройки.
 | 
			
		||||
  * @param  GPIO_PIN_RX - пин для настройки на прием.
 | 
			
		||||
  * @param  GPIO_PIN_TX - пин для настройки на передачу.
 | 
			
		||||
  */
 | 
			
		||||
void UART_GPIO_Init(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN_RX, uint16_t GPIO_PIN_TX)
 | 
			
		||||
{ // function takes port and pins (for rx and tx)
 | 
			
		||||
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 | 
			
		||||
  
 | 
			
		||||
  // choose port for enable clock
 | 
			
		||||
  GPIO_Clock_Enable(GPIOx);
 | 
			
		||||
  
 | 
			
		||||
  //USART3 GPIO Configuration
 | 
			
		||||
  //GPIO_PIN_TX ------> USART_TX
 | 
			
		||||
  //GPIO_PIN_RX ------> USART_RX    
 | 
			
		||||
  
 | 
			
		||||
#if defined(STM32F407xx) // gpio init for 407
 | 
			
		||||
  GPIO_InitStruct.Pin = GPIO_PIN_TX|GPIO_PIN_RX;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 | 
			
		||||
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
 | 
			
		||||
  HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
 | 
			
		||||
#elif defined(STM32F103xG)  // gpio init for atm403/stm103
 | 
			
		||||
  //GPIO_PIN_TX ------> USART_TX
 | 
			
		||||
  GPIO_InitStruct.Pin = GPIO_PIN_TX;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 | 
			
		||||
  HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
 | 
			
		||||
 | 
			
		||||
//  GPIO_PIN_RX ------> USART_RX  
 | 
			
		||||
  GPIO_InitStruct.Pin = GPIO_PIN_RX;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 | 
			
		||||
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 | 
			
		||||
  HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize DMA for UART.
 | 
			
		||||
  * @param  huart         - указатель на хендл UART для настройки DMA.
 | 
			
		||||
  * @param  hdma_rx       - указатель на хендл DMA для линии приема UART.
 | 
			
		||||
  * @param  DMAChannel    - указатель на канал DMA/поток DMA в STM32F407.
 | 
			
		||||
  * @param  DMA_CHANNEL_X - канал DMA.
 | 
			
		||||
  */
 | 
			
		||||
void UART_DMA_Init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X)
 | 
			
		||||
{ // function takes uart and dma handlers and dmachannel for uart
 | 
			
		||||
  // for now only dma rx is supported, tx maybe later if needed
 | 
			
		||||
    // calc defines on boot_project_setup.h
 | 
			
		||||
 | 
			
		||||
  /* USART3 DMA Init */
 | 
			
		||||
  /* USART3_RX Init */
 | 
			
		||||
  
 | 
			
		||||
  hdma_rx->Instance = DMAChannel;
 | 
			
		||||
#if defined(STM32F407xx) // dma channel choose for 407
 | 
			
		||||
  hdma_rx->Init.Channel = DMA_CHANNEL_X;
 | 
			
		||||
#endif
 | 
			
		||||
  hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
 | 
			
		||||
  hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
 | 
			
		||||
  hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
 | 
			
		||||
  hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 | 
			
		||||
  hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 | 
			
		||||
  hdma_rx->Init.Mode = DMA_CIRCULAR;
 | 
			
		||||
  hdma_rx->Init.Priority = DMA_PRIORITY_LOW;
 | 
			
		||||
  if (HAL_DMA_Init(hdma_rx) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  __USER_LINKDMA(huart,hdmarx,hdma_rx);   
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx
 | 
			
		||||
  // so you get error because hal uses . insted of ->
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Initialize UART & DMA clock and interrupt.
 | 
			
		||||
  * @param  huart - указатель на хендл UART для инициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с иницилизацией неиспользуемых UART,
 | 
			
		||||
            дефайнами в rs_message.h определяются используемые UART.
 | 
			
		||||
  */
 | 
			
		||||
void UART_MspInit(UART_HandleTypeDef *huart) // analog for hal function
 | 
			
		||||
{   
 | 
			
		||||
//  __RCC_DMA_UART_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  /* DMA1_Stream1_IRQn interrupt configuration */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA_UART_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA_UART_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  // rcc, dma and interrupt init for USARTs
 | 
			
		||||
  // GPIO init was moved to own functions UART_GPIO_Init  
 | 
			
		||||
  if(0);
 | 
			
		||||
#ifdef USE_USART1
 | 
			
		||||
  else if(huart->Instance==USART1)
 | 
			
		||||
  {
 | 
			
		||||
  
 | 
			
		||||
  /* DMA2 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA2_CLK_ENABLE();
 | 
			
		||||
  /* DMA interrupt init */
 | 
			
		||||
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART1 clock enable */
 | 
			
		||||
  __HAL_RCC_USART1_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* USART1 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(USART1_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART1
 | 
			
		||||
#ifdef USE_USART2
 | 
			
		||||
  else if(huart->Instance==USART2)
 | 
			
		||||
  {
 | 
			
		||||
  /* DMA1 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
  /* DMA interrupt init */
 | 
			
		||||
  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART2 clock enable */
 | 
			
		||||
  __HAL_RCC_USART2_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* USART2 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(USART2_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART2
 | 
			
		||||
#ifdef USE_USART3
 | 
			
		||||
  else if(huart->Instance==USART3)
 | 
			
		||||
  {     
 | 
			
		||||
  /* DMA1 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
  /* DMA interrupt init */
 | 
			
		||||
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART3 clock enable */
 | 
			
		||||
  __HAL_RCC_USART3_CLK_ENABLE();  
 | 
			
		||||
  /* USART3 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(USART3_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART3
 | 
			
		||||
#ifdef USE_UART4
 | 
			
		||||
  else if(huart->Instance==UART4)
 | 
			
		||||
  {
 | 
			
		||||
  /* DMA1 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
  /* DMA interrupt init */
 | 
			
		||||
  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* UART4 clock enable */
 | 
			
		||||
  __HAL_RCC_UART4_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* UART4 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(UART4_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_UART4
 | 
			
		||||
#ifdef USE_UART5
 | 
			
		||||
  else if(huart->Instance==UART5)
 | 
			
		||||
  {
 | 
			
		||||
  /* DMA1 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
  /* DMA interrupt init */
 | 
			
		||||
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* UART5 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* UART5 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(UART5_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_UART5
 | 
			
		||||
#ifdef USE_USART6
 | 
			
		||||
  else if(huart->Instance==USART6)
 | 
			
		||||
  {
 | 
			
		||||
  /* DMA2 clock enable */
 | 
			
		||||
  __HAL_RCC_DMA2_CLK_ENABLE();
 | 
			
		||||
  /* DMA interrupt init */
 | 
			
		||||
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART6 clock enable */
 | 
			
		||||
  __HAL_RCC_USART6_CLK_ENABLE();
 | 
			
		||||
  
 | 
			
		||||
  /* USART6 interrupt Init */
 | 
			
		||||
  HAL_NVIC_SetPriority(USART6_IRQn, 0, 0);
 | 
			
		||||
  HAL_NVIC_EnableIRQ(USART6_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART6
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Deinitialize UART & DMA clock and interrupt.
 | 
			
		||||
  * @param  huart - указатель на хендл UART для деинициализации.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с деиницилизацией неиспользуемых UART,
 | 
			
		||||
            дефайнами определяются используемые UART.
 | 
			
		||||
  */
 | 
			
		||||
void UART_MspDeInit(UART_HandleTypeDef *huart) // analog for hal function
 | 
			
		||||
{   
 | 
			
		||||
  // rcc, dma and interrupt init for USARTs
 | 
			
		||||
  // GPIO init was moved to own functions UART_GPIO_Init  
 | 
			
		||||
  if(0);
 | 
			
		||||
#ifdef USE_USART1
 | 
			
		||||
  else if(huart->Instance==USART1)
 | 
			
		||||
  {
 | 
			
		||||
  
 | 
			
		||||
//  /* DMA2 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA2_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART1 clock reset */
 | 
			
		||||
  __HAL_RCC_USART1_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_USART1_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART1
 | 
			
		||||
#ifdef USE_USART2
 | 
			
		||||
  else if(huart->Instance==USART2)
 | 
			
		||||
  {
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART2 clock reset */
 | 
			
		||||
  __HAL_RCC_USART2_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_USART2_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART2
 | 
			
		||||
#ifdef USE_USART3
 | 
			
		||||
  else if(huart->Instance==USART3)
 | 
			
		||||
  {     
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART3 clock reset */
 | 
			
		||||
  __HAL_RCC_USART3_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_USART3_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART3
 | 
			
		||||
#ifdef USE_UART4
 | 
			
		||||
  else if(huart->Instance==UART4)
 | 
			
		||||
  {
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* UART4 clock reset */
 | 
			
		||||
  __HAL_RCC_UART4_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_UART4_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_UART4
 | 
			
		||||
#ifdef USE_UART5
 | 
			
		||||
  else if(huart->Instance==UART5)
 | 
			
		||||
  {
 | 
			
		||||
//  /* DMA1 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA1_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* UART5 clock reset */
 | 
			
		||||
  __HAL_RCC_UART5_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_UART5_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_UART5
 | 
			
		||||
#ifdef USE_USART6
 | 
			
		||||
  else if(huart->Instance==USART6)
 | 
			
		||||
  {
 | 
			
		||||
//  /* DMA2 clock enable */
 | 
			
		||||
//  __HAL_RCC_DMA2_CLK_ENABLE();
 | 
			
		||||
//  /* DMA interrupt init */
 | 
			
		||||
//  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
 | 
			
		||||
//  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
 | 
			
		||||
  
 | 
			
		||||
  /* USART6 clock reset */
 | 
			
		||||
  __HAL_RCC_USART6_FORCE_RESET();
 | 
			
		||||
  __HAL_RCC_USART6_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif // USE_USART6
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Check that uart init structure have correct values.
 | 
			
		||||
  * @param  suart - указатель на структуру с настройками UART.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef Check_UART_Init_Struct(UART_SettingsTypeDef *suart)
 | 
			
		||||
{
 | 
			
		||||
  // check is settings are valid
 | 
			
		||||
  if (!IS_UART_INSTANCE(suart->huart.Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  if (!IS_UART_BAUDRATE(suart->huart.Init.BaudRate) || (suart->huart.Init.BaudRate == NULL))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  if (!IS_GPIO_ALL_INSTANCE(suart->GPIOx))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  if (!IS_GPIO_PIN(suart->GPIO_PIN_RX) && !IS_GPIO_PIN(suart->GPIO_PIN_TX)) // if both pins arent set up
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------UART INIT FUNCTIONS------------------------
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
@ -1,326 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_gpio.c
 | 
			
		||||
* @brief Модуль для инициализации портов и работы с ними.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @details 
 | 
			
		||||
Реализация функций для работы с GPIO:
 | 
			
		||||
 - Включение тактирования портов
 | 
			
		||||
 - Инициализация светодиодов и кнопок
 | 
			
		||||
 - Управление светодиодами: включение, выключение, моргание, плавное затухание
 | 
			
		||||
 - Чтение состояния кнопок с фильтром от дребезга
 | 
			
		||||
***************************************************************************/
 | 
			
		||||
#include "general_gpio.h"
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//------------------------GPIO INIT FUNCTIONS------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief Включить тактирование порта GPIO
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
 | 
			
		||||
{ 
 | 
			
		||||
  if(check_null_ptr_1(GPIOx))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  HAL_StatusTypeDef status = HAL_OK;
 | 
			
		||||
  // choose port for enable clock
 | 
			
		||||
  if (GPIOx==GPIOA)
 | 
			
		||||
    __HAL_RCC_GPIOA_CLK_ENABLE();
 | 
			
		||||
  else if (GPIOx==GPIOB)
 | 
			
		||||
    __HAL_RCC_GPIOB_CLK_ENABLE();
 | 
			
		||||
#ifdef GPIOC
 | 
			
		||||
  else if (GPIOx==GPIOC)
 | 
			
		||||
    __HAL_RCC_GPIOC_CLK_ENABLE();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef GPIOD
 | 
			
		||||
  else if (GPIOx==GPIOD)
 | 
			
		||||
    __HAL_RCC_GPIOD_CLK_ENABLE();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef GPIOE
 | 
			
		||||
  else if (GPIOx==GPIOE)
 | 
			
		||||
    __HAL_RCC_GPIOE_CLK_ENABLE();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef GPIOF
 | 
			
		||||
  else if (GPIOx==GPIOF)
 | 
			
		||||
    __HAL_RCC_GPIOF_CLK_ENABLE();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef GPIOH
 | 
			
		||||
  else if (GPIOx==GPIOF)
 | 
			
		||||
    __HAL_RCC_GPIOH_CLK_ENABLE();
 | 
			
		||||
#endif
 | 
			
		||||
  else
 | 
			
		||||
    status = HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------GPIO INIT FUNCTIONS------------------------
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//------------------------GPIO LED FUNCTIONS-------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Инициализировать светодиод (структуру светодиода)
 | 
			
		||||
  * @param led              Указатель на структуру светодиода
 | 
			
		||||
  * @param GPIOx            Указатель на структуру порта для светодиода
 | 
			
		||||
  * @param GPIO_PIN_X       Пин для светодиода
 | 
			
		||||
  * @param LED_ActiveLevel  Состояния пина, при котором светодиод будет включен
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_ActiveLevel)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, GPIOx, GPIO_PIN_X))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  led->LED_Port       = GPIOx;
 | 
			
		||||
  led->LED_Pin        = GPIO_PIN_X;
 | 
			
		||||
  led->LED_ActiveLvl  = LED_ActiveLevel;
 | 
			
		||||
  
 | 
			
		||||
  GPIO_LED_Off(led);
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Включить светодиод 
 | 
			
		||||
  * @param  led Указатель на структуру светодиода
 | 
			
		||||
  * @return HAL Status
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
 | 
			
		||||
    return HAL_ERROR;  
 | 
			
		||||
  
 | 
			
		||||
  led->state = LED_IS_ON;
 | 
			
		||||
  HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Выключить светодиод 
 | 
			
		||||
  * @param  led Указатель на структуру светодиода
 | 
			
		||||
  * @return HAL Status
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Off(GPIO_LEDTypeDef *led)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
 | 
			
		||||
    return HAL_ERROR;  
 | 
			
		||||
  
 | 
			
		||||
  led->state = LED_IS_OFF;
 | 
			
		||||
  HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Выставить светодиод по переменной
 | 
			
		||||
  * @param  led        Указатель на структуру светодиода
 | 
			
		||||
  * @param  led_state  Состояние светодиода
 | 
			
		||||
  * @return HAL Status
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
 | 
			
		||||
    return HAL_ERROR;  
 | 
			
		||||
  
 | 
			
		||||
  if(led_state)
 | 
			
		||||
  {
 | 
			
		||||
    return GPIO_LED_On(led);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    return GPIO_LED_Off(led);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Активировать моргание светодиодом
 | 
			
		||||
  * @param  led Указатель на структуру светодиода
 | 
			
		||||
  * @param  period Период плавного моргания светодиода
 | 
			
		||||
  * @return HAL Status
 | 
			
		||||
  * @details  Функция ставит режим моргания, который после управляется в @ref GPIO_LED_Dynamic_Handle
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
 | 
			
		||||
    return HAL_ERROR;  
 | 
			
		||||
  
 | 
			
		||||
  led->state = LED_IS_BLINKING;
 | 
			
		||||
  led->LED_Period = period;
 | 
			
		||||
    
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Активировать моргание светодиодом
 | 
			
		||||
  * @param  led  Указатель на структуру светодиода
 | 
			
		||||
  * @param  period Период плавного моргания светодиода
 | 
			
		||||
  * @return HAL Status
 | 
			
		||||
  * @details  Функция ставит режим моргания, который после управляется в @ref GPIO_LED_Dynamic_Handle
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
 | 
			
		||||
    return HAL_ERROR;  
 | 
			
		||||
  
 | 
			
		||||
  led->state = LED_IS_FADING;
 | 
			
		||||
  led->LED_Period = period;
 | 
			
		||||
  
 | 
			
		||||
    
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//uint8_t LED_PWM_FADING_DUTYS[LED_PWM_TICKS] = {0 1 2 3 4 5 6 7 8 9 10 11 12 }
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Управление динамическими режимами свечения светодиода
 | 
			
		||||
  * @param  Указатель на структуру светодиода
 | 
			
		||||
  * @details  Функция моргает/плавно моргает светодиодом в неблокирующем режиме
 | 
			
		||||
  * Т.е. функцию надо вызывать постоянно, чтобы она мониторила тики 
 | 
			
		||||
  * и в нужный момент переключала светодиод
 | 
			
		||||
  */
 | 
			
		||||
void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  /* Режим моргания светодиода */
 | 
			
		||||
  if(led->state == LED_IS_BLINKING)
 | 
			
		||||
  {
 | 
			
		||||
    uint32_t tickcurrent = HAL_GetTick();
 | 
			
		||||
    /* Ожидание истечения периода моргания */
 | 
			
		||||
    if((tickcurrent - led->tickprev) > led->LED_Period)
 | 
			
		||||
    {
 | 
			
		||||
      /* Моргание */
 | 
			
		||||
      HAL_GPIO_TogglePin(led->LED_Port, led->LED_Pin);
 | 
			
		||||
      
 | 
			
		||||
      led->tickprev = tickcurrent;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /* Режим плавного моргания светодиода */
 | 
			
		||||
  else if(led->state == LED_IS_FADING)
 | 
			
		||||
  {
 | 
			
		||||
    static unsigned direction = 0;
 | 
			
		||||
    static int duty = 0;
 | 
			
		||||
    uint32_t tickcurrent = HAL_GetTick();
 | 
			
		||||
    /* Ожидание момента изменения яркости */
 | 
			
		||||
    /* Период ШИМ 20 мс, поэтому менять яроксть надо 40 раз за период (туда обратно) */
 | 
			
		||||
    if((tickcurrent - led->tickprev) > led->LED_Period/(LED_PWM_TICKS*2))
 | 
			
		||||
    {
 | 
			
		||||
      /* Формирование разтухания */
 | 
			
		||||
      if(direction == 0)
 | 
			
		||||
      {
 | 
			
		||||
        if(++duty >= LED_PWM_TICKS)
 | 
			
		||||
        {
 | 
			
		||||
          direction = 1;
 | 
			
		||||
          duty = LED_PWM_TICKS;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      /* Формирование затухания */
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        if(--duty  <= 0)
 | 
			
		||||
        {
 | 
			
		||||
          direction = 0;
 | 
			
		||||
          duty = 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      led->tickprev = tickcurrent;
 | 
			
		||||
    }
 | 
			
		||||
    /* Формирование ШИМ для изменения яркости */
 | 
			
		||||
    int duty_crt = (duty*duty/LED_PWM_TICKS);
 | 
			
		||||
    if(tickcurrent%LED_PWM_TICKS < duty_crt)
 | 
			
		||||
    {
 | 
			
		||||
      HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
//------------------------GPIO LED FUNCTIONS-------------------------
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//------------------------GPIO SW FUNCTIONS-------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @brief  Инициализировать кнопку (структуру кнопки)
 | 
			
		||||
  * @param  sw             Указатель на структуру кнопки
 | 
			
		||||
  * @param  GPIOx          Указатель на структуру порта для кнопки
 | 
			
		||||
  * @param  GPIO_PIN_X     Пин для кнопки
 | 
			
		||||
  * @param  SW_ActiveLevel Состояния пина, когда кнопка нажата
 | 
			
		||||
  * @return HAL Status
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_ActiveLevel)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(sw, GPIOx, GPIO_PIN_X))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  sw->Sw_Port       = GPIOx;
 | 
			
		||||
  sw->Sw_Pin        = GPIO_PIN_X;
 | 
			
		||||
  sw->Sw_ActiveLvl  = SW_ActiveLevel;
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  * @brief  Считать состоянии кнопки 
 | 
			
		||||
  * @param  sw  Указатель на структуру кнопки
 | 
			
		||||
  * @return 1 - если кнопка нажата, 
 | 
			
		||||
  *         0 - если отжата, 
 | 
			
		||||
  *         -1 - если ошибка
 | 
			
		||||
  * @details  Функция включает в себя неблокирующую проверку на дребезг
 | 
			
		||||
  * Т.е. функцию надо вызывать постоянно, чтобы она мониторила состояние кнопки
 | 
			
		||||
  */
 | 
			
		||||
int GPIO_Read_Switch(GPIO_SwitchTypeDef *sw)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(sw, sw->Sw_Port, sw->Sw_Pin))
 | 
			
		||||
    return -1;
 | 
			
		||||
  
 | 
			
		||||
  if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
 | 
			
		||||
  {
 | 
			
		||||
    sw->Sw_PrevState = 1;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    if(sw->Sw_FilterDelay) // если включена защита от дребезга
 | 
			
		||||
    {
 | 
			
		||||
      if(sw->tickprev == 0)
 | 
			
		||||
        sw->tickprev = HAL_GetTick();
 | 
			
		||||
    
 | 
			
		||||
      if((HAL_GetTick() - sw->tickprev) >= sw->Sw_FilterDelay)
 | 
			
		||||
      {
 | 
			
		||||
        if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
 | 
			
		||||
        {
 | 
			
		||||
          return 1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          sw->tickprev = 0;
 | 
			
		||||
          return 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else // если нет защиты от дребезга
 | 
			
		||||
    {
 | 
			
		||||
      if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
 | 
			
		||||
      {
 | 
			
		||||
        return 1;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        sw->tickprev = 0;
 | 
			
		||||
        return 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    sw->Sw_PrevState = 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
//------------------------GPIO SW FUNCTIONS-------------------------
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
@ -1,722 +0,0 @@
 | 
			
		||||
/** 
 | 
			
		||||
**************************************************************************
 | 
			
		||||
* @file general_tim.c
 | 
			
		||||
* @brief Модуль для инициализации таймеров и работы с ними.
 | 
			
		||||
**************************************************************************
 | 
			
		||||
Реализация функций для работы с TIM:
 | 
			
		||||
 - Инициализация таймера и его каналов
 | 
			
		||||
 - Формирование задержек через таймеры
 | 
			
		||||
 - Считывание энкодера
 | 
			
		||||
*************************************************************************/
 | 
			
		||||
#include "general_tim.h"
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//-------------------------TIM INIT FUNCTIONS------------------------ 
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Инициализация таймера.
 | 
			
		||||
  * @param  stim Указатель на структуру с настройками таймера.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @details  
 | 
			
		||||
  * Инициализирует таймер исходя из настроек верхнего уровня:
 | 
			
		||||
  * - Длительность одного тика @ref TIM_MHzTickBaseTypeDef
 | 
			
		||||
  * - Частота таймера (в Гц, float)
 | 
			
		||||
  * - Частота тактирования таймера от шины (в Гц, float)
 | 
			
		||||
  * 
 | 
			
		||||
  * При невозможности выставления частоты при заданой длительности тика
 | 
			
		||||
  * длительность тика увеличивается до тех пор, пока частота не будет достигнута.
 | 
			
		||||
  * 
 | 
			
		||||
  * При выставлении дефайна @ref UPDATE_TIM_PARAMS_AFTER_INITIALIZATION
 | 
			
		||||
  * новая длительность тика записывается в структуру.
 | 
			
		||||
  * 
 | 
			
		||||
  * Также остается возможность низкоуровневой настройки по структурам @ref TIM_SettingsTypeDef.
 | 
			
		||||
  * Для этого надо высокоуровневые настройки приравнять к нулю
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef *stim)
 | 
			
		||||
{ // function takes structure for init
 | 
			
		||||
  // check that htim is defined
 | 
			
		||||
  if(check_null_ptr_2(stim, stim->htim.Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
    
 | 
			
		||||
  if(stim->sTickBaseUS) // if tickbase isnt disable
 | 
			
		||||
  {   
 | 
			
		||||
    if(stim->sTimAHBFreqMHz == NULL)
 | 
			
		||||
      return HAL_ERROR;     
 | 
			
		||||
    stim->htim.Init.Prescaler = (stim->sTimAHBFreqMHz*stim->sTickBaseUS) - 1;
 | 
			
		||||
    
 | 
			
		||||
    if ((stim->sTimFreqHz != NULL))
 | 
			
		||||
      stim->htim.Init.Period = ((1000000/stim->sTickBaseUS) / stim->sTimFreqHz) - 1;
 | 
			
		||||
    else if (stim->htim.Init.Period == NULL)
 | 
			
		||||
      stim->htim.Init.Period = 0xFFFF;
 | 
			
		||||
    
 | 
			
		||||
    if(stim->sTickBasePrescaler)
 | 
			
		||||
    {
 | 
			
		||||
      stim->htim.Init.Prescaler = (stim->htim.Init.Prescaler + 1)/stim->sTickBasePrescaler - 1;
 | 
			
		||||
      stim->htim.Init.Period    = (stim->htim.Init.Period + 1)*stim->sTickBasePrescaler - 1;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      stim->sTickBasePrescaler = 1;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // fix overflow of presc and period if need
 | 
			
		||||
  for(int i = 0; (stim->htim.Init.Prescaler > 0xFFFF) || (stim->htim.Init.Period > 0xFFFF); i++)
 | 
			
		||||
  {   
 | 
			
		||||
    if (i>10) // if it isnt fixed after 10 itteration - return HAL_ERRPOR
 | 
			
		||||
    {
 | 
			
		||||
      return HAL_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // if timbase is too big (prescaller too big for choosen base from MHZ)
 | 
			
		||||
    if(stim->htim.Init.Prescaler > 0xFFFF)
 | 
			
		||||
    {
 | 
			
		||||
      // переносим часть пресскалера в период
 | 
			
		||||
      stim->htim.Init.Prescaler = ((stim->htim.Init.Prescaler + 1)/2) - 1;
 | 
			
		||||
      stim->htim.Init.Period = ((stim->htim.Init.Period + 1)*2) - 1;
 | 
			
		||||
      // обновляем TickBase, если есть куда обновлять
 | 
			
		||||
      if(stim->sTickBaseUS > 1)
 | 
			
		||||
        stim->sTickBaseUS /= 2;
 | 
			
		||||
      // обновляем sTickBasePrescaler, если sTickBaseUS - уже в минимуме
 | 
			
		||||
      else if (stim->sTickBaseUS == 1)
 | 
			
		||||
        stim->sTickBasePrescaler *= 2;
 | 
			
		||||
      else // if TickBase = 0 - return error
 | 
			
		||||
        return HAL_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    // if freq is too low (period too big for choosen base)
 | 
			
		||||
    if(stim->htim.Init.Period > 0xFFFF)
 | 
			
		||||
    {   
 | 
			
		||||
      // переносим часть периода в прескалер
 | 
			
		||||
      stim->htim.Init.Period = ((stim->htim.Init.Period + 1)/2) - 1;
 | 
			
		||||
      stim->htim.Init.Prescaler = ((stim->htim.Init.Prescaler + 1)*2) - 1;
 | 
			
		||||
      // обновляем TickBase
 | 
			
		||||
      stim->sTickBaseUS *= 2;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  //-------------TIM BASE INIT----------------
 | 
			
		||||
  // tim base init    
 | 
			
		||||
  TIM_Base_MspInit(&stim->htim, stim->sTimMode);
 | 
			
		||||
  if (HAL_TIM_Base_Init(&stim->htim) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
    
 | 
			
		||||
  //-------------CLOCK SRC INIT---------------
 | 
			
		||||
  // fill sClockSourceConfig if its NULL
 | 
			
		||||
  if (stim->sClockSourceConfig.ClockSource == NULL)
 | 
			
		||||
    stim->sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;  
 | 
			
		||||
  // clock source init    
 | 
			
		||||
  if (HAL_TIM_ConfigClockSource(&stim->htim, &stim->sClockSourceConfig) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  //--------------SLAVE INIT------------------  
 | 
			
		||||
  // if slave mode enables - config it
 | 
			
		||||
  if (stim->sSlaveConfig.SlaveMode)
 | 
			
		||||
  {
 | 
			
		||||
    // slave mode init    
 | 
			
		||||
    if (HAL_TIM_SlaveConfigSynchro(&stim->htim, &stim->sSlaveConfig) != HAL_OK)
 | 
			
		||||
    {
 | 
			
		||||
      MyLibs_Error_Handler();
 | 
			
		||||
      return HAL_ERROR;
 | 
			
		||||
    } 
 | 
			
		||||
  }
 | 
			
		||||
  //--------------MASTER INIT-----------------    
 | 
			
		||||
  // master mode init   
 | 
			
		||||
  if (HAL_TIMEx_MasterConfigSynchronization(&stim->htim, &stim->sMasterConfig) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  } 
 | 
			
		||||
  
 | 
			
		||||
  //--------------BDTR INIT-----------------    
 | 
			
		||||
  if (HAL_TIMEx_ConfigBreakDeadTime(&stim->htim, &stim->sBreakDeadTimeConfig) != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  //----------------IT CLEAR------------------- 
 | 
			
		||||
  __HAL_TIM_CLEAR_IT(&stim->htim, TIM_IT_UPDATE);
 | 
			
		||||
  
 | 
			
		||||
    
 | 
			
		||||
  // обновляем TickBase
 | 
			
		||||
  #ifdef UPDATE_TIM_PARAMS_AFTER_INITIALIZATION
 | 
			
		||||
  stim->sTickBaseUS = (stim->htim.Instance->PSC+1)*stim->sTickBasePrescaler/(stim->sTimAHBFreqMHz);
 | 
			
		||||
  if(stim->sTickBaseUS == 0)  // if prescaler is too high
 | 
			
		||||
  {                           // recalc what is prescaler irl
 | 
			
		||||
    stim->sTickBaseUS = 1;
 | 
			
		||||
    stim->sTickBasePrescaler = stim->sTimAHBFreqMHz/(stim->htim.Instance->PSC+1);
 | 
			
		||||
  }
 | 
			
		||||
  #endif
 | 
			
		||||
  stim->htim.Instance->CNT = 0;
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Инициализация режима энкодер у таймера.
 | 
			
		||||
  * @param  henc Указатель на хендл энкодера.
 | 
			
		||||
  * @param  htim Указатель на хендл таймера.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   Предварительно надо инициализировать таймер @ref TIM_Base_Init.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc, TIM_HandleTypeDef *htim)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(henc, htim, htim->Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  if(check_null_ptr_3(henc->GPIOx, henc->GPIO_PIN_TI1, henc->GPIO_PIN_TI2))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 | 
			
		||||
  HAL_StatusTypeDef RES = HAL_ERROR;
 | 
			
		||||
  henc->htim = htim;
 | 
			
		||||
  
 | 
			
		||||
  // setup channel for pwm
 | 
			
		||||
  RES = HAL_TIM_Encoder_Init(henc->htim, &henc->sConfig);
 | 
			
		||||
  if (RES != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return RES;
 | 
			
		||||
  }
 | 
			
		||||
  // choose port for enable clock
 | 
			
		||||
  RES = GPIO_Clock_Enable(henc->GPIOx);
 | 
			
		||||
  if(RES != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return RES;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  GPIO_InitStruct.Pin = henc->GPIO_PIN_TI1|henc->GPIO_PIN_TI2;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  GPIO_InitStruct.Pull = GPIO_PULLUP;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 | 
			
		||||
  GPIO_InitStruct.Alternate = GPIO_TIM_Alternate_Mapping(henc->htim->Instance);
 | 
			
		||||
  if(GPIO_InitStruct.Alternate)
 | 
			
		||||
    HAL_GPIO_Init(henc->GPIOx, &GPIO_InitStruct);
 | 
			
		||||
  
 | 
			
		||||
  if(henc->GPIO_PIN_SW)
 | 
			
		||||
  {
 | 
			
		||||
    /*Configure switch pin */
 | 
			
		||||
    GPIO_InitStruct.Pin = henc->GPIO_PIN_SW;
 | 
			
		||||
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 | 
			
		||||
    GPIO_InitStruct.Pull = GPIO_PULLUP;
 | 
			
		||||
    HAL_GPIO_Init(henc->GPIOx, &GPIO_InitStruct);
 | 
			
		||||
 | 
			
		||||
    GPIO_Switch_Init(&henc->Sw, henc->GPIOx, henc->GPIO_PIN_SW, 0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
   
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Инициализация выхода ШИМ таймера.
 | 
			
		||||
  * @param  htim        Указатель на хендл таймера.
 | 
			
		||||
  * @param  sConfigOC   Указатель на настрйоки канала таймера.
 | 
			
		||||
  * @param  TIM_CHANNEL Канал таймера для настройки.
 | 
			
		||||
  * @param  GPIOx       Порт для вывода ШИМ.
 | 
			
		||||
  * @param  GPIO_PIN    Пин для вывода ШИМ.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   Предварительно надо инициализировать таймер @ref TIM_Base_Init.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(htim, htim->Instance, sConfigOC))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  if(check_null_ptr_2(GPIOx, GPIO_PIN))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 | 
			
		||||
  HAL_StatusTypeDef RES = HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  // setup channel for pwm
 | 
			
		||||
  RES = HAL_TIM_PWM_ConfigChannel(htim, sConfigOC, TIM_CHANNEL);
 | 
			
		||||
  if (RES != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return RES;
 | 
			
		||||
  }
 | 
			
		||||
  // choose port for enable clock
 | 
			
		||||
  RES = GPIO_Clock_Enable(GPIOx);
 | 
			
		||||
  if(RES != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return RES;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  GPIO_InitStruct.Pin = GPIO_PIN;
 | 
			
		||||
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
			
		||||
  if(sConfigOC->OCPolarity == TIM_OCNPOLARITY_HIGH)
 | 
			
		||||
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
 | 
			
		||||
  else
 | 
			
		||||
    GPIO_InitStruct.Pull = GPIO_PULLUP;
 | 
			
		||||
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  
 | 
			
		||||
  GPIO_InitStruct.Alternate = GPIO_TIM_Alternate_Mapping(htim->Instance);
 | 
			
		||||
  if(GPIO_InitStruct.Alternate)
 | 
			
		||||
    HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Инициализация OC компаратора таймера.
 | 
			
		||||
  * @param  htim        Указатель на хендл таймера.
 | 
			
		||||
  * @param  TIM_CHANNEL Канал таймера для настройки.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @note   Предварительно надо инициализировать таймер @ref TIM_Base_Init.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL)
 | 
			
		||||
{ 
 | 
			
		||||
  if(check_null_ptr_2(htim, htim->Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  TIM_OC_InitTypeDef      sConfigOC = {0};
 | 
			
		||||
  HAL_StatusTypeDef RES = HAL_ERROR;
 | 
			
		||||
  
 | 
			
		||||
  sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
 | 
			
		||||
  sConfigOC.Pulse = 0;
 | 
			
		||||
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 | 
			
		||||
  
 | 
			
		||||
  RES = HAL_TIM_OC_ConfigChannel(htim, &sConfigOC, TIM_CHANNEL);
 | 
			
		||||
  if (RES != HAL_OK)
 | 
			
		||||
  {
 | 
			
		||||
    MyLibs_Error_Handler();
 | 
			
		||||
    return RES;
 | 
			
		||||
  }
 | 
			
		||||
  return RES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
//-------------------------TIM USER FUNCTIONS------------------------ 
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Считать энкодер.
 | 
			
		||||
  * @param  henc Указатель на хендл энкодера.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @details  Читает разницу энкодера, которую он накопил после 
 | 
			
		||||
  *           предыдущего вызова этой функции.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Encoder_Read(TIM_EncoderTypeDef *henc)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_3(henc, henc->htim, henc->htim->Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  uint16_t cnt_now = (uint16_t)henc->htim->Instance->CNT;
 | 
			
		||||
  int16_t diff = (int16_t)(cnt_now - henc->Encoder_Shdw);  // переполнение корректно обрабатывается
 | 
			
		||||
  henc->Encoder_Diff = diff;
 | 
			
		||||
  henc->Encoder_Shdw = cnt_now;
 | 
			
		||||
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Считать кнопку энкодера.
 | 
			
		||||
  * @param  henc Указатель на хендл энкодера.
 | 
			
		||||
  * @return 1 - если кнопка нажата, 
 | 
			
		||||
  *         0 - если отжата, 
 | 
			
		||||
  *         -1 - если ошибка
 | 
			
		||||
  */
 | 
			
		||||
int TIM_Encoder_ReadSwitch(TIM_EncoderTypeDef *henc)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_1(henc))
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
	return GPIO_Read_Switch(&henc->Sw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Задержка в тиках таймера (блокирующая).
 | 
			
		||||
  * @param  htim    Указатель на хендл таймера.
 | 
			
		||||
  * @param  delay   Задержка в тиках таймера.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @details  Формирует задержку с блокировкой программы.
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_2(htim, htim->Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  if(delay >= htim->Instance->ARR)
 | 
			
		||||
  {
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  htim->Instance->CNT = 0;
 | 
			
		||||
  while(1)
 | 
			
		||||
  {
 | 
			
		||||
    if(htim->Instance->CNT > delay)
 | 
			
		||||
    {
 | 
			
		||||
      return HAL_OK;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Начать отсчет неблокирующей задержки.
 | 
			
		||||
  * @param  htim    Указатель на хендл таймера.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @details  Сбрасывает счетчик для начала отсчета неблокирующей задержки.
 | 
			
		||||
  *           @ref TIM_Delay_NonBlocking для проверки статуса задержки
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim)
 | 
			
		||||
{  
 | 
			
		||||
  if(check_null_ptr_2(htim, htim->Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  htim->Instance->CNT = 0;
 | 
			
		||||
  
 | 
			
		||||
  return HAL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Задержка в тиках таймера (неблокирующая).
 | 
			
		||||
  * @param  htim    Указатель на хендл таймера.
 | 
			
		||||
  * @param  delay   Задержка в тиках таймера.
 | 
			
		||||
  * @return HAL status.
 | 
			
		||||
  * @details  Формирует задержку с блокировкой программы.
 | 
			
		||||
  *           Перед ожиданием задержки надо запутстить таймер @ref TIM_Delay_Start
 | 
			
		||||
  * @note     Таймер не должен использоваться на время этой задержки
 | 
			
		||||
  */
 | 
			
		||||
HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay)
 | 
			
		||||
{  
 | 
			
		||||
  if(check_null_ptr_2(htim, htim->Instance))
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
  if(delay >= htim->Instance->ARR)
 | 
			
		||||
  {
 | 
			
		||||
    return HAL_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if(htim->Instance->CNT <= delay)
 | 
			
		||||
  {
 | 
			
		||||
    return HAL_BUSY;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    return HAL_OK;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Инициализация CLK и NVIC таймеров.
 | 
			
		||||
  * @param  htim Указатель на хендл таймера.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с иницилизацией неиспользуемых таймеров,
 | 
			
		||||
            дефайнами в general_tim.h определяются используемые таймеры.
 | 
			
		||||
  */
 | 
			
		||||
void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_2(htim, htim->Instance))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  it_mode = it_mode&TIM_IT_CONF;
 | 
			
		||||
#ifdef USE_TIM1
 | 
			
		||||
  if(htim->Instance==TIM1)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM2 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM1_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM2 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM2
 | 
			
		||||
  if(htim->Instance==TIM2)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM2 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM2_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM2 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM2_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM3
 | 
			
		||||
  if(htim->Instance==TIM3)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM3 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM3_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM3 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM4
 | 
			
		||||
  if(htim->Instance==TIM4)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM4 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM4_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM4 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM4_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM5
 | 
			
		||||
  if(htim->Instance==TIM5)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM5 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM5_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM5 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM5_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM6
 | 
			
		||||
  if(htim->Instance==TIM6)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM6 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM6_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM6 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM7
 | 
			
		||||
  if(htim->Instance==TIM7)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM7 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM7_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM7 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM7_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM7_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM8
 | 
			
		||||
  if(htim->Instance==TIM8)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM8 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM8_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM8 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM9
 | 
			
		||||
  if(htim->Instance==TIM9)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM9 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM9_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM9 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM10
 | 
			
		||||
  if(htim->Instance==TIM10)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM10 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM10_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM10 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }  
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM11
 | 
			
		||||
  if(htim->Instance==TIM11)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM11 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM11_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM11 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM12
 | 
			
		||||
  if(htim->Instance==TIM12)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM12 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM12_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM12 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM13
 | 
			
		||||
  if(htim->Instance==TIM13)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM13 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM13_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM13 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM14
 | 
			
		||||
  if(htim->Instance==TIM14)
 | 
			
		||||
  {
 | 
			
		||||
    /* TIM14 clock enable */
 | 
			
		||||
    __HAL_RCC_TIM14_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    /* TIM14 interrupt Init */
 | 
			
		||||
  if(it_mode)
 | 
			
		||||
  {
 | 
			
		||||
    HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 0, 0);
 | 
			
		||||
    HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/**  
 | 
			
		||||
  * @brief  Деинициализация CLK и NVIC таймеров.
 | 
			
		||||
  * @param  htim Указатель на хендл таймера.
 | 
			
		||||
  * @note   Чтобы не генерировать функцию с деиницилизацией неиспользуемых таймеров,
 | 
			
		||||
            дефайнами в general_tim.h определяются используемые таймеры.
 | 
			
		||||
  */
 | 
			
		||||
void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim)
 | 
			
		||||
{
 | 
			
		||||
  if(check_null_ptr_2(htim, htim->Instance))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
#ifdef USE_TIM1
 | 
			
		||||
  if(htim->Instance==TIM1)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM1_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM1_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM2
 | 
			
		||||
  if(htim->Instance==TIM2)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM2_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM2_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM3
 | 
			
		||||
  if(htim->Instance==TIM3)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM3_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM3_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM4
 | 
			
		||||
  if(htim->Instance==TIM4)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM4_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM4_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM5
 | 
			
		||||
  if(htim->Instance==TIM5)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM5_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM5_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM6
 | 
			
		||||
  if(htim->Instance==TIM6)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM6_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM6_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM7
 | 
			
		||||
  if(htim->Instance==TIM7)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM7_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM7_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM8
 | 
			
		||||
  if(htim->Instance==TIM8)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM8_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM8_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM9
 | 
			
		||||
  if(htim->Instance==TIM9)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM9_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM9_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM10
 | 
			
		||||
  if(htim->Instance==TIM10)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM10_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM10_RELEASE_RESET();
 | 
			
		||||
  }  
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM11
 | 
			
		||||
  if(htim->Instance==TIM11)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM11_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM11_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM12
 | 
			
		||||
  if(htim->Instance==TIM12)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM12_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM12_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM13
 | 
			
		||||
  if(htim->Instance==TIM13)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM13_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM13_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif 
 | 
			
		||||
#ifdef USE_TIM14
 | 
			
		||||
  if(htim->Instance==TIM14)
 | 
			
		||||
  {
 | 
			
		||||
    __HAL_RCC_TIM14_FORCE_RESET();
 | 
			
		||||
    __HAL_RCC_TIM14_RELEASE_RESET();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
//-------------------------TIM INIT FUNCTIONS------------------------
 | 
			
		||||
//-------------------------------------------------------------------
 | 
			
		||||
@ -1,104 +0,0 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@mainpage
 | 
			
		||||
 | 
			
		||||
@section overview Обзор
 | 
			
		||||
MyLibs - это набор библиотек для удобной работы с периферией микроконтроллеров STM32.
 | 
			
		||||
 | 
			
		||||
@subsection features Основные возможности
 | 
			
		||||
 | 
			
		||||
@subsubsection utils_module Общие утилиты (@ref MYLIBS_DEFINES)
 | 
			
		||||
- Макросы для задержек и утилит (@ref DELAYS_DEFINES и @ref UTILS_DEFINES)
 | 
			
		||||
- Трекеры для статистики и отладки  (@ref TRACKERS и @ref TRACE)
 | 
			
		||||
- Эволюционный алгоритм для оптимизации параметров  (@ref EVOLVE_OPTIMIZER)
 | 
			
		||||
- Битовый доступ к регистрам через union  (@ref BIT_ACCESS_DEFINES)
 | 
			
		||||
 | 
			
		||||
@subsubsection trace_module Трассировка @ref TRACE
 | 
			
		||||
- Serial трассировка через SWO и RTT (@ref TRACE_SERIAL)
 | 
			
		||||
- GPIO трассировка для отладки (@ref TRACE_GPIO)
 | 
			
		||||
- Сохранение логов в Flash память (@ref TRACE_RTT_FLASH)
 | 
			
		||||
- Обработка HardFault с сохранением контекста (@ref TRACE_HARDFAULT)
 | 
			
		||||
 | 
			
		||||
@subsubsection gpio_module Модуль GPIO @ref MY_LIBS_GPIO
 | 
			
		||||
- Инициализация портов и тактирования (@ref MYLIBS_GPIO_GENERAL)
 | 
			
		||||
- Управление светодиодами (включение/выключение, моргание, плавное затухание) (@ref MYLIBS_GPIO_LEDS)
 | 
			
		||||
- Работа с кнопками (чтение состояния, фильтрация дребезга) (@ref MYLIBS_GPIO_SWITCH)
 | 
			
		||||
 | 
			
		||||
@subsubsection tim_module Модуль таймеров @ref MY_LIBS_TIM
 | 
			
		||||
- Базовая инициализация таймеров (@ref MYLIBS_TIM_GENERAL)
 | 
			
		||||
- Формирование задержек (блокирующие и неблокирующие) (@ref MYLIBS_TIM_DELAY)
 | 
			
		||||
- Работа с энкодерами (чтение положения, обработка кнопок) (@ref MYLIBS_TIM_ENCODER)
 | 
			
		||||
- Настройка ШИМ и Output Compare (@ref MYLIBS_TIM_OC)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@subsection structure Структура проекта
 | 
			
		||||
 | 
			
		||||
@code
 | 
			
		||||
├── inc/                     # Заголовочные файлы
 | 
			
		||||
│   ├── mylibs_include.h     # Главный include файл
 | 
			
		||||
│   ├── mylibs_config.h      # Конфигурация библиотек
 | 
			
		||||
│   ├── mylibs_defs.h        # Общие определения и макросы
 | 
			
		||||
│   ├── bit_access.h         # Битовый доступ к регистрам
 | 
			
		||||
│   ├── trackers.h           # Трекеры для отладки
 | 
			
		||||
│   ├── trace.h              # Трассировка и логирование
 | 
			
		||||
│   ├── general_gpio.h       # Работа с GPIO
 | 
			
		||||
│   └── general_tim.h        # Работа с таймерами
 | 
			
		||||
└── src/                     # Исходные файлы
 | 
			
		||||
    ├── general_gpio.c       # Реализация GPIO
 | 
			
		||||
    └── general_tim.c        # Реализация TIM
 | 
			
		||||
@endcode
 | 
			
		||||
 | 
			
		||||
@subsection usage_basic Использование
 | 
			
		||||
 | 
			
		||||
Инструкция по подключению:
 | 
			
		||||
 | 
			
		||||
1. Настройте конфигурацию @ref MYLIBS_CONFIG в @ref mylibs_config.h 
 | 
			
		||||
 | 
			
		||||
2. Подключите главный заголовочный файл:
 | 
			
		||||
@code
 | 
			
		||||
#include "mylibs_include.h"
 | 
			
		||||
@endcode
 | 
			
		||||
 | 
			
		||||
3. Используйте нужные модули в своем коде
 | 
			
		||||
 | 
			
		||||
@subsubsection gpio_example Пример работы с GPIO
 | 
			
		||||
 | 
			
		||||
@code
 | 
			
		||||
// Инициализация светодиода
 | 
			
		||||
MX_GPIO_Init();
 | 
			
		||||
GPIO_LEDTypeDef led;
 | 
			
		||||
GPIO_LED_Init(&led, GPIOA, GPIO_PIN_5, 1);
 | 
			
		||||
 | 
			
		||||
// Включение светодиода
 | 
			
		||||
GPIO_LED_On(&led);
 | 
			
		||||
 | 
			
		||||
// Запуск моргания
 | 
			
		||||
GPIO_LED_Blink_Start(&led, 500); // Период 500 мс
 | 
			
		||||
 | 
			
		||||
// В основном цикле
 | 
			
		||||
while (1) {
 | 
			
		||||
GPIO_LED_Dynamic_Handle(&led);
 | 
			
		||||
}
 | 
			
		||||
@endcode
 | 
			
		||||
 | 
			
		||||
@subsubsection tim_example Пример работы с таймером
 | 
			
		||||
 | 
			
		||||
@code
 | 
			
		||||
// Настройка таймера
 | 
			
		||||
TIM_SettingsTypeDef tim_settings = {0};
 | 
			
		||||
tim_settings.htim.Instance = TIM2;
 | 
			
		||||
tim_settings.sTimAHBFreqMHz = SystemCoreClock;
 | 
			
		||||
tim_settings.sTickBaseUS = TIM_TickBase_1MS;
 | 
			
		||||
tim_settings.sTimFreqHz = 1000; // 1 кГц
 | 
			
		||||
tim_settings.sTimMode = TIM_IT_CONF;
 | 
			
		||||
 | 
			
		||||
TIM_Base_Init(&tim_settings);
 | 
			
		||||
HAL_TIM_Base_Start(&tim_settings.htim);
 | 
			
		||||
@endcode
 | 
			
		||||
 | 
			
		||||
@subsection dependencies Зависимости
 | 
			
		||||
 | 
			
		||||
- HAL библиотека STM32
 | 
			
		||||
- SEGGER RTT (опционально, для RTT трассировки)
 | 
			
		||||
- FreeRTOS (опционально, для FreeRTOS задержек)
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										2099
									
								
								RTT/SEGGER_RTT.c
									
									
									
									
									
								
							
							
						
						
									
										2099
									
								
								RTT/SEGGER_RTT.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										513
									
								
								RTT/SEGGER_RTT.h
									
									
									
									
									
								
							
							
						
						
									
										513
									
								
								RTT/SEGGER_RTT.h
									
									
									
									
									
								
							@ -1,513 +0,0 @@
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*                    SEGGER Microcontroller GmbH                     *
 | 
			
		||||
*                        The Embedded Experts                        *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*            (c) 1995 - 2021 SEGGER Microcontroller GmbH             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       www.segger.com     Support: support@segger.com               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       SEGGER RTT * Real Time Transfer for embedded targets         *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* All rights reserved.                                               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* SEGGER strongly recommends to not make any changes                 *
 | 
			
		||||
* to or modify the source code of this software in order to stay     *
 | 
			
		||||
* compatible with the RTT protocol and J-Link.                       *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* Redistribution and use in source and binary forms, with or         *
 | 
			
		||||
* without modification, are permitted provided that the following    *
 | 
			
		||||
* condition is met:                                                  *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* o Redistributions of source code must retain the above copyright   *
 | 
			
		||||
*   notice, this condition and the following disclaimer.             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
 | 
			
		||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
 | 
			
		||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
 | 
			
		||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
 | 
			
		||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
 | 
			
		||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
 | 
			
		||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
 | 
			
		||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
 | 
			
		||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
 | 
			
		||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
 | 
			
		||||
* DAMAGE.                                                            *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       RTT version: 8.10g                                           *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
 | 
			
		||||
---------------------------END-OF-HEADER------------------------------
 | 
			
		||||
File    : SEGGER_RTT.h
 | 
			
		||||
Purpose : Implementation of SEGGER real-time transfer which allows
 | 
			
		||||
          real-time communication on targets which support debugger
 | 
			
		||||
          memory accesses while the CPU is running.
 | 
			
		||||
Revision: $Rev: 25842 $
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef SEGGER_RTT_H
 | 
			
		||||
#define SEGGER_RTT_H
 | 
			
		||||
 | 
			
		||||
#include "SEGGER_RTT_Conf.h"
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines, defaults
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef RTT_USE_ASM
 | 
			
		||||
  //
 | 
			
		||||
  // Some cores support out-of-order memory accesses (reordering of memory accesses in the core)
 | 
			
		||||
  // For such cores, we need to define a memory barrier to guarantee the order of certain accesses to the RTT ring buffers.
 | 
			
		||||
  // Needed for:
 | 
			
		||||
  //   Cortex-M7 (ARMv7-M)
 | 
			
		||||
  //   Cortex-M23 (ARM-v8M)
 | 
			
		||||
  //   Cortex-M33 (ARM-v8M)
 | 
			
		||||
  //   Cortex-A/R (ARM-v7A/R)
 | 
			
		||||
  //
 | 
			
		||||
  // We do not explicitly check for "Embedded Studio" as the compiler in use determines what we support.
 | 
			
		||||
  // You can use an external toolchain like IAR inside ES. So there is no point in checking for "Embedded Studio"
 | 
			
		||||
  //
 | 
			
		||||
  #if (defined __CROSSWORKS_ARM)                  // Rowley Crossworks
 | 
			
		||||
    #define _CC_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    #if (defined __ARM_ARCH_7M__)                 // Cortex-M3
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    #elif (defined __ARM_ARCH_7EM__)              // Cortex-M4/M7
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8M_BASE__)          // Cortex-M23
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8M_MAIN__)          // Cortex-M33
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined(__ARM_ARCH_8_1M_MAIN__))       // Cortex-M85
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #else
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
    #endif
 | 
			
		||||
  #elif (defined __ARMCC_VERSION)
 | 
			
		||||
    //
 | 
			
		||||
    // ARM compiler
 | 
			
		||||
    // ARM compiler V6.0 and later is clang based.
 | 
			
		||||
    // Our ASM part is compatible to clang.
 | 
			
		||||
    //
 | 
			
		||||
    #if (__ARMCC_VERSION >= 6000000)
 | 
			
		||||
      #define _CC_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    #else
 | 
			
		||||
      #define _CC_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM_ARCH_6M__)                 // Cortex-M0 / M1
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0         // No ASM support for this architecture
 | 
			
		||||
    #elif (defined __ARM_ARCH_7M__)               // Cortex-M3
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    #elif (defined __ARM_ARCH_7EM__)              // Cortex-M4/M7
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8M_BASE__)          // Cortex-M23
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8M_MAIN__)          // Cortex-M33
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8_1M_MAIN__)        // Cortex-M85
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__))  // Cortex-A/R 32-bit ARMv7-A/R
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #else
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
    #endif
 | 
			
		||||
  #elif ((defined __GNUC__) || (defined __clang__))
 | 
			
		||||
    //
 | 
			
		||||
    // GCC / Clang
 | 
			
		||||
    //
 | 
			
		||||
    #define _CC_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    // ARM 7/9: __ARM_ARCH_5__ / __ARM_ARCH_5E__ / __ARM_ARCH_5T__ / __ARM_ARCH_5T__ / __ARM_ARCH_5TE__
 | 
			
		||||
    #if (defined __ARM_ARCH_7M__)                 // Cortex-M3
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    #elif (defined __ARM_ARCH_7EM__)              // Cortex-M4/M7
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1         // Only Cortex-M7 needs a DMB but we cannot distinguish M4 and M7 here...
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8M_BASE__)          // Cortex-M23
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8M_MAIN__)          // Cortex-M33
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif (defined __ARM_ARCH_8_1M_MAIN__)        // Cortex-M85
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #elif ((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__))  // Cortex-A/R 32-bit ARMv7-A/R
 | 
			
		||||
      #define _CORE_NEEDS_DMB           1
 | 
			
		||||
      #define RTT__DMB() __asm volatile ("dmb\n" : : :);
 | 
			
		||||
    #else
 | 
			
		||||
      #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
    #endif
 | 
			
		||||
  #elif ((defined __IASMARM__) || (defined __ICCARM__))
 | 
			
		||||
    //
 | 
			
		||||
    // IAR assembler/compiler
 | 
			
		||||
    //
 | 
			
		||||
    #define _CC_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
    #if (__VER__ < 6300000)
 | 
			
		||||
      #define VOLATILE
 | 
			
		||||
    #else
 | 
			
		||||
      #define VOLATILE volatile
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM7M__)                            // Needed for old versions that do not know the define yet
 | 
			
		||||
      #if (__CORE__ == __ARM7M__)                      // Cortex-M3
 | 
			
		||||
        #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM7EM__)
 | 
			
		||||
      #if (__CORE__ == __ARM7EM__)                     // Cortex-M4/M7
 | 
			
		||||
        #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
        #define _CORE_NEEDS_DMB 1
 | 
			
		||||
        #define RTT__DMB() asm VOLATILE ("DMB");
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM8M_BASELINE__)
 | 
			
		||||
      #if (__CORE__ == __ARM8M_BASELINE__)             // Cortex-M23
 | 
			
		||||
        #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
        #define _CORE_NEEDS_DMB 1
 | 
			
		||||
        #define RTT__DMB() asm VOLATILE ("DMB");
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM8M_MAINLINE__)
 | 
			
		||||
      #if (__CORE__ == __ARM8M_MAINLINE__)             // Cortex-M33
 | 
			
		||||
        #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
        #define _CORE_NEEDS_DMB 1
 | 
			
		||||
        #define RTT__DMB() asm VOLATILE ("DMB");
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM8EM_MAINLINE__)
 | 
			
		||||
      #if (__CORE__ == __ARM8EM_MAINLINE__)            // Cortex-???
 | 
			
		||||
        #define _CORE_HAS_RTT_ASM_SUPPORT 1
 | 
			
		||||
        #define _CORE_NEEDS_DMB 1
 | 
			
		||||
        #define RTT__DMB() asm VOLATILE ("DMB");
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM7A__)
 | 
			
		||||
      #if (__CORE__ == __ARM7A__)                      // Cortex-A 32-bit ARMv7-A
 | 
			
		||||
        #define _CORE_NEEDS_DMB 1
 | 
			
		||||
        #define RTT__DMB() asm VOLATILE ("DMB");
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if (defined __ARM7R__)
 | 
			
		||||
      #if (__CORE__ == __ARM7R__)                      // Cortex-R 32-bit ARMv7-R
 | 
			
		||||
        #define _CORE_NEEDS_DMB 1
 | 
			
		||||
        #define RTT__DMB() asm VOLATILE ("DMB");
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
// TBD: __ARM8A__ => Cortex-A 64-bit ARMv8-A
 | 
			
		||||
// TBD: __ARM8R__ => Cortex-R 64-bit ARMv8-R
 | 
			
		||||
  #else
 | 
			
		||||
    //
 | 
			
		||||
    // Other compilers
 | 
			
		||||
    //
 | 
			
		||||
    #define _CC_HAS_RTT_ASM_SUPPORT   0
 | 
			
		||||
    #define _CORE_HAS_RTT_ASM_SUPPORT 0
 | 
			
		||||
  #endif
 | 
			
		||||
  //
 | 
			
		||||
  // If IDE and core support the ASM version, enable ASM version by default
 | 
			
		||||
  //
 | 
			
		||||
  #ifndef _CORE_HAS_RTT_ASM_SUPPORT
 | 
			
		||||
    #define _CORE_HAS_RTT_ASM_SUPPORT 0              // Default for unknown cores
 | 
			
		||||
  #endif
 | 
			
		||||
  #if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT)
 | 
			
		||||
    #define RTT_USE_ASM                           (1)
 | 
			
		||||
  #else
 | 
			
		||||
    #define RTT_USE_ASM                           (0)
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef _CORE_NEEDS_DMB
 | 
			
		||||
  #define _CORE_NEEDS_DMB 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef RTT__DMB
 | 
			
		||||
  #if _CORE_NEEDS_DMB
 | 
			
		||||
    #error "Don't know how to place inline assembly for DMB"
 | 
			
		||||
  #else
 | 
			
		||||
    #define RTT__DMB()
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE
 | 
			
		||||
  #define SEGGER_RTT_CPU_CACHE_LINE_SIZE (0)   // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef SEGGER_RTT_UNCACHED_OFF
 | 
			
		||||
  #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
 | 
			
		||||
    #error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
 | 
			
		||||
  #else
 | 
			
		||||
    #define SEGGER_RTT_UNCACHED_OFF (0)
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
#if RTT_USE_ASM
 | 
			
		||||
  #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
 | 
			
		||||
    #error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef SEGGER_RTT_ASM  // defined when SEGGER_RTT.h is included from assembly file
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines, fixed
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Determine how much we must pad the control block to make it a multiple of a cache line in size
 | 
			
		||||
// Assuming: U8 = 1B
 | 
			
		||||
//           U16 = 2B
 | 
			
		||||
//           U32 = 4B
 | 
			
		||||
//           U8/U16/U32* = 4B
 | 
			
		||||
//
 | 
			
		||||
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE    // Avoid division by zero in case we do not have any cache
 | 
			
		||||
  #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * SEGGER_RTT_CPU_CACHE_LINE_SIZE)
 | 
			
		||||
#else
 | 
			
		||||
  #define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes)
 | 
			
		||||
#endif
 | 
			
		||||
#define SEGGER_RTT__CB_SIZE                              (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24))
 | 
			
		||||
#define SEGGER_RTT__CB_PADDING                           (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE)
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Types
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Description for a circular buffer (also called "ring buffer")
 | 
			
		||||
// which is used as up-buffer (T->H)
 | 
			
		||||
//
 | 
			
		||||
typedef struct {
 | 
			
		||||
  const     char*    sName;         // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
 | 
			
		||||
            char*    pBuffer;       // Pointer to start of buffer
 | 
			
		||||
            unsigned SizeOfBuffer;  // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
 | 
			
		||||
            unsigned WrOff;         // Position of next item to be written by either target.
 | 
			
		||||
  volatile  unsigned RdOff;         // Position of next item to be read by host. Must be volatile since it may be modified by host.
 | 
			
		||||
            unsigned Flags;         // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
 | 
			
		||||
} SEGGER_RTT_BUFFER_UP;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Description for a circular buffer (also called "ring buffer")
 | 
			
		||||
// which is used as down-buffer (H->T)
 | 
			
		||||
//
 | 
			
		||||
typedef struct {
 | 
			
		||||
  const     char*    sName;         // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
 | 
			
		||||
            char*    pBuffer;       // Pointer to start of buffer
 | 
			
		||||
            unsigned SizeOfBuffer;  // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
 | 
			
		||||
  volatile  unsigned WrOff;         // Position of next item to be written by host. Must be volatile since it may be modified by host.
 | 
			
		||||
            unsigned RdOff;         // Position of next item to be read by target (down-buffer).
 | 
			
		||||
            unsigned Flags;         // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
 | 
			
		||||
} SEGGER_RTT_BUFFER_DOWN;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// RTT control block which describes the number of buffers available
 | 
			
		||||
// as well as the configuration for each buffer
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char                    acID[16];                                 // Initialized to "SEGGER RTT"
 | 
			
		||||
  int                     MaxNumUpBuffers;                          // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
 | 
			
		||||
  int                     MaxNumDownBuffers;                        // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
 | 
			
		||||
  SEGGER_RTT_BUFFER_UP    aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS];       // Up buffers, transferring information up from target via debug probe to host
 | 
			
		||||
  SEGGER_RTT_BUFFER_DOWN  aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS];   // Down buffers, transferring information down from host via debug probe to target
 | 
			
		||||
#if SEGGER_RTT__CB_PADDING
 | 
			
		||||
  unsigned char           aDummy[SEGGER_RTT__CB_PADDING];
 | 
			
		||||
#endif
 | 
			
		||||
} SEGGER_RTT_CB;
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Global data
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
extern SEGGER_RTT_CB _SEGGER_RTT;
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT API functions
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
  extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
int          SEGGER_RTT_AllocDownBuffer         (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
 | 
			
		||||
int          SEGGER_RTT_AllocUpBuffer           (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
 | 
			
		||||
int          SEGGER_RTT_ConfigUpBuffer          (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
 | 
			
		||||
int          SEGGER_RTT_ConfigDownBuffer        (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
 | 
			
		||||
int          SEGGER_RTT_GetKey                  (void);
 | 
			
		||||
unsigned     SEGGER_RTT_HasData                 (unsigned BufferIndex);
 | 
			
		||||
int          SEGGER_RTT_HasKey                  (void);
 | 
			
		||||
unsigned     SEGGER_RTT_HasDataUp               (unsigned BufferIndex);
 | 
			
		||||
void         SEGGER_RTT_Init                    (void);
 | 
			
		||||
unsigned     SEGGER_RTT_Read                    (unsigned BufferIndex,       void* pBuffer, unsigned BufferSize);
 | 
			
		||||
unsigned     SEGGER_RTT_ReadNoLock              (unsigned BufferIndex,       void* pData,   unsigned BufferSize);
 | 
			
		||||
int          SEGGER_RTT_SetNameDownBuffer       (unsigned BufferIndex, const char* sName);
 | 
			
		||||
int          SEGGER_RTT_SetNameUpBuffer         (unsigned BufferIndex, const char* sName);
 | 
			
		||||
int          SEGGER_RTT_SetFlagsDownBuffer      (unsigned BufferIndex, unsigned Flags);
 | 
			
		||||
int          SEGGER_RTT_SetFlagsUpBuffer        (unsigned BufferIndex, unsigned Flags);
 | 
			
		||||
int          SEGGER_RTT_WaitKey                 (void);
 | 
			
		||||
unsigned     SEGGER_RTT_Write                   (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
unsigned     SEGGER_RTT_WriteNoLock             (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
unsigned     SEGGER_RTT_WriteSkipNoLock         (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
unsigned     SEGGER_RTT_ASM_WriteSkipNoLock     (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
unsigned     SEGGER_RTT_WriteString             (unsigned BufferIndex, const char* s);
 | 
			
		||||
void         SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
unsigned     SEGGER_RTT_PutChar                 (unsigned BufferIndex, char c);
 | 
			
		||||
unsigned     SEGGER_RTT_PutCharSkip             (unsigned BufferIndex, char c);
 | 
			
		||||
unsigned     SEGGER_RTT_PutCharSkipNoLock       (unsigned BufferIndex, char c);
 | 
			
		||||
unsigned     SEGGER_RTT_GetAvailWriteSpace      (unsigned BufferIndex);
 | 
			
		||||
unsigned     SEGGER_RTT_GetBytesInBuffer        (unsigned BufferIndex);
 | 
			
		||||
//
 | 
			
		||||
// Function macro for performance optimization
 | 
			
		||||
//
 | 
			
		||||
#define      SEGGER_RTT_HASDATA(n)       (((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff)
 | 
			
		||||
 | 
			
		||||
#if RTT_USE_ASM
 | 
			
		||||
  #define SEGGER_RTT_WriteSkipNoLock  SEGGER_RTT_ASM_WriteSkipNoLock
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT transfer functions to send RTT data via other channels.
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
unsigned     SEGGER_RTT_ReadUpBuffer            (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
 | 
			
		||||
unsigned     SEGGER_RTT_ReadUpBufferNoLock      (unsigned BufferIndex, void* pData, unsigned BufferSize);
 | 
			
		||||
unsigned     SEGGER_RTT_WriteDownBuffer         (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
unsigned     SEGGER_RTT_WriteDownBufferNoLock   (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
 | 
			
		||||
 | 
			
		||||
#define      SEGGER_RTT_HASDATA_UP(n)    (((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff)   // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT "Terminal" API functions
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
int     SEGGER_RTT_SetTerminal        (unsigned char TerminalId);
 | 
			
		||||
int     SEGGER_RTT_TerminalOut        (unsigned char TerminalId, const char* s);
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT printf functions (require SEGGER_RTT_printf.c)
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
 | 
			
		||||
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // ifndef(SEGGER_RTT_ASM)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// For some environments, NULL may not be defined until certain headers are included
 | 
			
		||||
//
 | 
			
		||||
#ifndef NULL
 | 
			
		||||
  #define NULL  ((void*)0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Operating modes. Define behavior if buffer is full (not enough space for entire message)
 | 
			
		||||
//
 | 
			
		||||
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP         (0)     // Skip. Do not block, output nothing. (Default)
 | 
			
		||||
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM         (1)     // Trim: Do not block, output as much as fits.
 | 
			
		||||
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL    (2)     // Block: Wait until there is space in the buffer.
 | 
			
		||||
#define SEGGER_RTT_MODE_MASK                  (3)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Control sequences, based on ANSI.
 | 
			
		||||
// Can be used to control color, and clear the screen
 | 
			
		||||
//
 | 
			
		||||
#define RTT_CTRL_RESET                "\x1B[0m"         // Reset to default colors
 | 
			
		||||
#define RTT_CTRL_CLEAR                "\x1B[2J"         // Clear screen, reposition cursor to top left
 | 
			
		||||
 | 
			
		||||
#define RTT_CTRL_TEXT_BLACK           "\x1B[2;30m"
 | 
			
		||||
#define RTT_CTRL_TEXT_RED             "\x1B[2;31m"
 | 
			
		||||
#define RTT_CTRL_TEXT_GREEN           "\x1B[2;32m"
 | 
			
		||||
#define RTT_CTRL_TEXT_YELLOW          "\x1B[2;33m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BLUE            "\x1B[2;34m"
 | 
			
		||||
#define RTT_CTRL_TEXT_MAGENTA         "\x1B[2;35m"
 | 
			
		||||
#define RTT_CTRL_TEXT_CYAN            "\x1B[2;36m"
 | 
			
		||||
#define RTT_CTRL_TEXT_WHITE           "\x1B[2;37m"
 | 
			
		||||
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_BLACK    "\x1B[1;30m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_RED      "\x1B[1;31m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_GREEN    "\x1B[1;32m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_YELLOW   "\x1B[1;33m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_BLUE     "\x1B[1;34m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA  "\x1B[1;35m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_CYAN     "\x1B[1;36m"
 | 
			
		||||
#define RTT_CTRL_TEXT_BRIGHT_WHITE    "\x1B[1;37m"
 | 
			
		||||
 | 
			
		||||
#define RTT_CTRL_BG_BLACK             "\x1B[24;40m"
 | 
			
		||||
#define RTT_CTRL_BG_RED               "\x1B[24;41m"
 | 
			
		||||
#define RTT_CTRL_BG_GREEN             "\x1B[24;42m"
 | 
			
		||||
#define RTT_CTRL_BG_YELLOW            "\x1B[24;43m"
 | 
			
		||||
#define RTT_CTRL_BG_BLUE              "\x1B[24;44m"
 | 
			
		||||
#define RTT_CTRL_BG_MAGENTA           "\x1B[24;45m"
 | 
			
		||||
#define RTT_CTRL_BG_CYAN              "\x1B[24;46m"
 | 
			
		||||
#define RTT_CTRL_BG_WHITE             "\x1B[24;47m"
 | 
			
		||||
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_BLACK      "\x1B[4;40m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_RED        "\x1B[4;41m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_GREEN      "\x1B[4;42m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_YELLOW     "\x1B[4;43m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_BLUE       "\x1B[4;44m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_MAGENTA    "\x1B[4;45m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_CYAN       "\x1B[4;46m"
 | 
			
		||||
#define RTT_CTRL_BG_BRIGHT_WHITE      "\x1B[4;47m"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*************************** End of file ****************************/
 | 
			
		||||
@ -1,242 +0,0 @@
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*                   (c) SEGGER Microcontroller GmbH                  *
 | 
			
		||||
*                        The Embedded Experts                        *
 | 
			
		||||
*                           www.segger.com                           *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
 | 
			
		||||
-------------------------- END-OF-HEADER -----------------------------
 | 
			
		||||
 | 
			
		||||
File    : SEGGER_RTT_ASM_ARMv7M.S
 | 
			
		||||
Purpose : Assembler implementation of RTT functions for ARMv7M
 | 
			
		||||
 | 
			
		||||
Additional information:
 | 
			
		||||
  This module is written to be assembler-independent and works with
 | 
			
		||||
  GCC and clang (Embedded Studio) and IAR.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define SEGGER_RTT_ASM      // Used to control processed input from header file
 | 
			
		||||
#include "SEGGER_RTT.h"
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines, fixed
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define _CCIAR   0
 | 
			
		||||
#define _CCCLANG 1
 | 
			
		||||
 | 
			
		||||
#if (defined __SES_ARM) || (defined __GNUC__) || (defined __clang__)
 | 
			
		||||
  #define _CC_TYPE             _CCCLANG
 | 
			
		||||
  #define _PUB_SYM             .global
 | 
			
		||||
  #define _EXT_SYM             .extern
 | 
			
		||||
  #define _END                 .end
 | 
			
		||||
  #define _WEAK                .weak
 | 
			
		||||
  #define _THUMB_FUNC          .thumb_func
 | 
			
		||||
  #define _THUMB_CODE          .code 16
 | 
			
		||||
  #define _WORD                .word
 | 
			
		||||
  #define _SECTION(Sect, Type, AlignExp) .section Sect ##, "ax"
 | 
			
		||||
  #define _ALIGN(Exp)          .align Exp 
 | 
			
		||||
  #define _PLACE_LITS          .ltorg
 | 
			
		||||
  #define _DATA_SECT_START 
 | 
			
		||||
  #define _C_STARTUP           _start
 | 
			
		||||
  #define _STACK_END           __stack_end__
 | 
			
		||||
  #define _RAMFUNC
 | 
			
		||||
  //
 | 
			
		||||
  // .text     => Link to flash
 | 
			
		||||
  // .fast     => Link to RAM
 | 
			
		||||
  // OtherSect => Usually link to RAM
 | 
			
		||||
  // Alignment is 2^x
 | 
			
		||||
  //
 | 
			
		||||
#elif defined (__IASMARM__)
 | 
			
		||||
  #define _CC_TYPE             _CCIAR
 | 
			
		||||
  #define _PUB_SYM             PUBLIC
 | 
			
		||||
  #define _EXT_SYM             EXTERN
 | 
			
		||||
  #define _END                 END
 | 
			
		||||
  #define _WEAK                _WEAK
 | 
			
		||||
  #define _THUMB_FUNC
 | 
			
		||||
  #define _THUMB_CODE          THUMB
 | 
			
		||||
  #define _WORD                DCD
 | 
			
		||||
  #define _SECTION(Sect, Type, AlignExp) SECTION Sect ## : ## Type ## :REORDER:NOROOT ## (AlignExp)
 | 
			
		||||
  #define _ALIGN(Exp)          alignrom Exp 
 | 
			
		||||
  #define _PLACE_LITS
 | 
			
		||||
  #define _DATA_SECT_START     DATA
 | 
			
		||||
  #define _C_STARTUP           __iar_program_start
 | 
			
		||||
  #define _STACK_END           sfe(CSTACK)
 | 
			
		||||
  #define _RAMFUNC             SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR
 | 
			
		||||
  //
 | 
			
		||||
  // .text     => Link to flash
 | 
			
		||||
  // .textrw   => Link to RAM
 | 
			
		||||
  // OtherSect => Usually link to RAM
 | 
			
		||||
  // NOROOT    => Allows linker to throw away the function, if not referenced
 | 
			
		||||
  // Alignment is 2^x
 | 
			
		||||
  //
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (_CC_TYPE == _CCIAR)
 | 
			
		||||
        NAME SEGGER_RTT_ASM_ARMv7M
 | 
			
		||||
#else
 | 
			
		||||
        .syntax unified
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined (RTT_USE_ASM) && (RTT_USE_ASM == 1)
 | 
			
		||||
        #define SHT_PROGBITS 0x1
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Public / external symbols
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
        _EXT_SYM __aeabi_memcpy
 | 
			
		||||
        _EXT_SYM __aeabi_memcpy4
 | 
			
		||||
        _EXT_SYM _SEGGER_RTT
 | 
			
		||||
 | 
			
		||||
        _PUB_SYM SEGGER_RTT_ASM_WriteSkipNoLock
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       SEGGER_RTT_WriteSkipNoLock
 | 
			
		||||
*
 | 
			
		||||
*  Function description
 | 
			
		||||
*    Stores a specified number of characters in SEGGER RTT
 | 
			
		||||
*    control block which is then read by the host.
 | 
			
		||||
*    SEGGER_RTT_WriteSkipNoLock does not lock the application and
 | 
			
		||||
*    skips all data, if the data does not fit into the buffer.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters
 | 
			
		||||
*    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
 | 
			
		||||
*    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
 | 
			
		||||
*    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
 | 
			
		||||
*                 MUST be > 0!!!
 | 
			
		||||
*                 This is done for performance reasons, so no initial check has do be done.
 | 
			
		||||
*
 | 
			
		||||
*  Return value
 | 
			
		||||
*    1: Data has been copied
 | 
			
		||||
*    0: No space, data has not been copied
 | 
			
		||||
*
 | 
			
		||||
*  Notes
 | 
			
		||||
*    (1) If there is not enough space in the "Up"-buffer, all data is dropped.
 | 
			
		||||
*    (2) For performance reasons this function does not call Init()
 | 
			
		||||
*        and may only be called after RTT has been initialized.
 | 
			
		||||
*        Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
 | 
			
		||||
*/
 | 
			
		||||
        _SECTION(.text, CODE, 2)
 | 
			
		||||
        _ALIGN(2)
 | 
			
		||||
        _THUMB_FUNC
 | 
			
		||||
SEGGER_RTT_ASM_WriteSkipNoLock:   // unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pData, unsigned NumBytes) {
 | 
			
		||||
        //
 | 
			
		||||
        // Cases:
 | 
			
		||||
        //   1) RdOff <= WrOff => Space until wrap-around is sufficient
 | 
			
		||||
        //   2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks)
 | 
			
		||||
        //   3) RdOff <  WrOff => No space in buf
 | 
			
		||||
        //   4) RdOff >  WrOff => Space is sufficient
 | 
			
		||||
        //   5) RdOff >  WrOff => No space in buf
 | 
			
		||||
        //
 | 
			
		||||
        // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough
 | 
			
		||||
        //
 | 
			
		||||
        // Register usage:
 | 
			
		||||
        //   R0 Temporary needed as RdOff, <Tmp> register later on
 | 
			
		||||
        //   R1 pData
 | 
			
		||||
        //   R2 <NumBytes>
 | 
			
		||||
        //   R3 <Tmp> register. Hold free for subroutine calls
 | 
			
		||||
        //   R4 <Rem>
 | 
			
		||||
        //   R5 pRing->pBuffer
 | 
			
		||||
        //   R6 pRing (Points to active struct SEGGER_RTT_BUFFER_DOWN)
 | 
			
		||||
        //   R7 WrOff
 | 
			
		||||
        //
 | 
			
		||||
        PUSH     {R4-R7}
 | 
			
		||||
        ADD      R3,R0,R0, LSL #+1
 | 
			
		||||
        LDR.W    R0,=_SEGGER_RTT                 // pRing = &_SEGGER_RTT.aUp[BufferIndex];
 | 
			
		||||
        ADD      R0,R0,R3, LSL #+3
 | 
			
		||||
        ADD      R6,R0,#+24
 | 
			
		||||
        LDR      R0,[R6, #+16]                   // RdOff = pRing->RdOff;
 | 
			
		||||
        LDR      R7,[R6, #+12]                   // WrOff = pRing->WrOff;
 | 
			
		||||
        LDR      R5,[R6, #+4]                    // pRing->pBuffer
 | 
			
		||||
        CMP      R7,R0
 | 
			
		||||
        BCC.N    _CheckCase4                     // if (RdOff <= WrOff) {                           => Case 1), 2) or 3)
 | 
			
		||||
        //
 | 
			
		||||
        // Handling for case 1, later on identical to case 4
 | 
			
		||||
        //
 | 
			
		||||
        LDR      R3,[R6, #+8]                    //  Avail = pRing->SizeOfBuffer - WrOff - 1u;      => Space until wrap-around (assume 1 byte not usable for case that RdOff == 0)
 | 
			
		||||
        SUBS     R4,R3,R7                        // <Rem> (Used in case we jump into case 2 afterwards)
 | 
			
		||||
        SUBS     R3,R4,#+1                       // <Avail>
 | 
			
		||||
        CMP      R3,R2
 | 
			
		||||
        BCC.N    _CheckCase2                     // if (Avail >= NumBytes) {  => Case 1)?
 | 
			
		||||
_Case4:
 | 
			
		||||
        ADDS     R5,R7,R5                        // pBuffer += WrOff
 | 
			
		||||
        ADDS     R0,R2,R7                        // v = WrOff + NumBytes
 | 
			
		||||
        //
 | 
			
		||||
        // 2x unrolling for the copy loop that is used most of the time
 | 
			
		||||
        // This is a special optimization for small SystemView packets and makes them even faster
 | 
			
		||||
        //
 | 
			
		||||
        _ALIGN(2)
 | 
			
		||||
_LoopCopyStraight:                               // memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
 | 
			
		||||
        LDRB     R3,[R1], #+1
 | 
			
		||||
        STRB     R3,[R5], #+1                    // *pDest++ = *pSrc++
 | 
			
		||||
        SUBS     R2,R2,#+1
 | 
			
		||||
        BEQ      _CSDone
 | 
			
		||||
        LDRB     R3,[R1], #+1
 | 
			
		||||
        STRB     R3,[R5], #+1                    // *pDest++ = *pSrc++
 | 
			
		||||
        SUBS     R2,R2,#+1
 | 
			
		||||
        BNE      _LoopCopyStraight
 | 
			
		||||
_CSDone:
 | 
			
		||||
#if _CORE_NEEDS_DMB                              // Do not slow down cores that do not need a DMB instruction here
 | 
			
		||||
        DMB                                      // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the <WrOff> in the struct
 | 
			
		||||
#endif
 | 
			
		||||
        STR      R0,[R6, #+12]                   // pRing->WrOff = WrOff + NumBytes;
 | 
			
		||||
        MOVS     R0,#+1
 | 
			
		||||
        POP      {R4-R7}
 | 
			
		||||
        BX       LR                              // Return 1
 | 
			
		||||
_CheckCase2:
 | 
			
		||||
        ADDS     R0,R0,R3                        // Avail += RdOff; => Space incl. wrap-around
 | 
			
		||||
        CMP      R0,R2
 | 
			
		||||
        BCC.N    _Case3                          // if (Avail >= NumBytes) {           => Case 2? => If not, we have case 3) (does not fit)
 | 
			
		||||
        //
 | 
			
		||||
        // Handling for case 2
 | 
			
		||||
        //
 | 
			
		||||
        ADDS     R0,R7,R5                        // v = pRing->pBuffer + WrOff => Do not change pRing->pBuffer here because 2nd chunk needs org. value
 | 
			
		||||
        SUBS     R2,R2,R4                        // NumBytes -= Rem;  (Rem = pRing->SizeOfBuffer - WrOff; => Space until end of buffer)
 | 
			
		||||
_LoopCopyBeforeWrapAround:                       // memcpy(pRing->pBuffer + WrOff, pData, Rem); => Copy 1st chunk
 | 
			
		||||
        LDRB     R3,[R1], #+1
 | 
			
		||||
        STRB     R3,[R0], #+1                    // *pDest++ = *pSrc++
 | 
			
		||||
        SUBS     R4,R4,#+1
 | 
			
		||||
        BNE      _LoopCopyBeforeWrapAround
 | 
			
		||||
        //
 | 
			
		||||
        // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used
 | 
			
		||||
        // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element
 | 
			
		||||
        // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks
 | 
			
		||||
        // Therefore, check if 2nd memcpy is necessary at all
 | 
			
		||||
        //
 | 
			
		||||
        ADDS     R4,R2,#+0                       // Save <NumBytes> (needed as counter in loop but must be written to <WrOff> after the loop). Also use this inst to update the flags to skip 2nd loop if possible
 | 
			
		||||
        BEQ.N    _No2ChunkNeeded                 // if (NumBytes) {
 | 
			
		||||
_LoopCopyAfterWrapAround:                        // memcpy(pRing->pBuffer, pData + Rem, NumBytes);
 | 
			
		||||
        LDRB     R3,[R1], #+1                    // pData already points to the next src byte due to copy loop increment before this loop
 | 
			
		||||
        STRB     R3,[R5], #+1                    // *pDest++ = *pSrc++
 | 
			
		||||
        SUBS     R2,R2,#+1
 | 
			
		||||
        BNE      _LoopCopyAfterWrapAround
 | 
			
		||||
_No2ChunkNeeded:
 | 
			
		||||
#if _CORE_NEEDS_DMB                              // Do not slow down cores that do not need a DMB instruction here
 | 
			
		||||
        DMB                                      // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the <WrOff> in the struct
 | 
			
		||||
#endif
 | 
			
		||||
        STR      R4,[R6, #+12]                   // pRing->WrOff = NumBytes; => Must be written after copying data because J-Link may read control block asynchronously while writing into buffer
 | 
			
		||||
        MOVS     R0,#+1
 | 
			
		||||
        POP      {R4-R7}
 | 
			
		||||
        BX       LR                              // Return 1
 | 
			
		||||
_CheckCase4:
 | 
			
		||||
        SUBS     R0,R0,R7
 | 
			
		||||
        SUBS     R0,R0,#+1                       // Avail = RdOff - WrOff - 1u;
 | 
			
		||||
        CMP      R0,R2
 | 
			
		||||
        BCS.N    _Case4                          // if (Avail >= NumBytes) {      => Case 4) == 1) ? => If not, we have case 5) == 3) (does not fit)
 | 
			
		||||
_Case3:
 | 
			
		||||
        MOVS     R0,#+0
 | 
			
		||||
        POP      {R4-R7}
 | 
			
		||||
        BX       LR                              // Return 0
 | 
			
		||||
        _PLACE_LITS
 | 
			
		||||
 | 
			
		||||
#endif  // defined (RTT_USE_ASM) && (RTT_USE_ASM == 1)
 | 
			
		||||
        _END
 | 
			
		||||
 | 
			
		||||
/*************************** End of file ****************************/
 | 
			
		||||
@ -1,429 +0,0 @@
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*                    SEGGER Microcontroller GmbH                     *
 | 
			
		||||
*                        The Embedded Experts                        *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*            (c) 1995 - 2021 SEGGER Microcontroller GmbH             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       www.segger.com     Support: support@segger.com               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       SEGGER RTT * Real Time Transfer for embedded targets         *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* All rights reserved.                                               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* SEGGER strongly recommends to not make any changes                 *
 | 
			
		||||
* to or modify the source code of this software in order to stay     *
 | 
			
		||||
* compatible with the RTT protocol and J-Link.                       *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* Redistribution and use in source and binary forms, with or         *
 | 
			
		||||
* without modification, are permitted provided that the following    *
 | 
			
		||||
* condition is met:                                                  *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* o Redistributions of source code must retain the above copyright   *
 | 
			
		||||
*   notice, this condition and the following disclaimer.             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
 | 
			
		||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
 | 
			
		||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
 | 
			
		||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
 | 
			
		||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
 | 
			
		||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
 | 
			
		||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
 | 
			
		||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
 | 
			
		||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
 | 
			
		||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
 | 
			
		||||
* DAMAGE.                                                            *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       RTT version: 8.10g                                           *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
 | 
			
		||||
---------------------------END-OF-HEADER------------------------------
 | 
			
		||||
File    : SEGGER_RTT_Conf.h
 | 
			
		||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
 | 
			
		||||
          allows real-time communication on targets which support
 | 
			
		||||
          debugger memory accesses while the CPU is running.
 | 
			
		||||
Revision: $Rev: 24316 $
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef SEGGER_RTT_CONF_H
 | 
			
		||||
#define SEGGER_RTT_CONF_H
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_SYSTEMS_ICC__
 | 
			
		||||
  #include <intrinsics.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines, configurable
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Take in and set to correct values for Cortex-A systems with CPU cache
 | 
			
		||||
//
 | 
			
		||||
//#define SEGGER_RTT_CPU_CACHE_LINE_SIZE            (32)          // Largest cache line size (in bytes) in the current system
 | 
			
		||||
//#define SEGGER_RTT_UNCACHED_OFF                   (0xFB000000)  // Address alias where RTT CB and buffers can be accessed uncached
 | 
			
		||||
//
 | 
			
		||||
// Most common case:
 | 
			
		||||
// Up-channel 0: RTT
 | 
			
		||||
// Up-channel 1: SystemView
 | 
			
		||||
//
 | 
			
		||||
#ifndef   SEGGER_RTT_MAX_NUM_UP_BUFFERS
 | 
			
		||||
  #define SEGGER_RTT_MAX_NUM_UP_BUFFERS             (3)     // Max. number of up-buffers (T->H) available on this target    (Default: 3)
 | 
			
		||||
#endif
 | 
			
		||||
//
 | 
			
		||||
// Most common case:
 | 
			
		||||
// Down-channel 0: RTT
 | 
			
		||||
// Down-channel 1: SystemView
 | 
			
		||||
//
 | 
			
		||||
#ifndef   SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
 | 
			
		||||
  #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS           (3)     // Max. number of down-buffers (H->T) available on this target  (Default: 3)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef   BUFFER_SIZE_UP
 | 
			
		||||
  #define BUFFER_SIZE_UP                            (4096)  // Size of the buffer for terminal output of target, up to host (Default: 1k)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef   BUFFER_SIZE_DOWN
 | 
			
		||||
  #define BUFFER_SIZE_DOWN                          (16)    // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef   SEGGER_RTT_PRINTF_BUFFER_SIZE
 | 
			
		||||
  #define SEGGER_RTT_PRINTF_BUFFER_SIZE             (64u)    // Size of buffer for RTT printf to bulk-send chars via RTT     (Default: 64)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef   SEGGER_RTT_MODE_DEFAULT
 | 
			
		||||
  #define SEGGER_RTT_MODE_DEFAULT                   SEGGER_RTT_MODE_NO_BLOCK_TRIM // Mode for pre-initialized terminal channel (buffer 0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT memcpy configuration
 | 
			
		||||
*
 | 
			
		||||
*       memcpy() is good for large amounts of data,
 | 
			
		||||
*       but the overhead is big for small amounts, which are usually stored via RTT.
 | 
			
		||||
*       With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead.
 | 
			
		||||
*
 | 
			
		||||
*       SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions.
 | 
			
		||||
*       This is may be required with memory access restrictions,
 | 
			
		||||
*       such as on Cortex-A devices with MMU.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef   SEGGER_RTT_MEMCPY_USE_BYTELOOP
 | 
			
		||||
  #define SEGGER_RTT_MEMCPY_USE_BYTELOOP              0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop
 | 
			
		||||
#endif
 | 
			
		||||
//
 | 
			
		||||
// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets
 | 
			
		||||
//
 | 
			
		||||
//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__))
 | 
			
		||||
//  #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes)      SEGGER_memcpy((pDest), (pSrc), (NumBytes))
 | 
			
		||||
//#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
 | 
			
		||||
// Otherwise we would probably end up with a mixed string in the buffer.
 | 
			
		||||
// If using  RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
 | 
			
		||||
//
 | 
			
		||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
 | 
			
		||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
 | 
			
		||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
 | 
			
		||||
// (Higher priority = lower priority number)
 | 
			
		||||
// Default value for embOS: 128u
 | 
			
		||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
 | 
			
		||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
 | 
			
		||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
 | 
			
		||||
//
 | 
			
		||||
#ifndef   SEGGER_RTT_MAX_INTERRUPT_PRIORITY
 | 
			
		||||
  #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY         (0x20)   // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for SEGGER Embedded Studio,
 | 
			
		||||
*       Rowley CrossStudio and GCC
 | 
			
		||||
*/
 | 
			
		||||
#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32))
 | 
			
		||||
  #if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                    unsigned int _SEGGER_RTT__LockState;                                         \
 | 
			
		||||
                                  __asm volatile ("mrs   %0, primask  \n\t"                         \
 | 
			
		||||
                                                  "movs  r1, #1       \n\t"                         \
 | 
			
		||||
                                                  "msr   primask, r1  \n\t"                         \
 | 
			
		||||
                                                  : "=r" (_SEGGER_RTT__LockState)                                \
 | 
			
		||||
                                                  :                                                 \
 | 
			
		||||
                                                  : "r1", "cc"                                      \
 | 
			
		||||
                                                  );
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   __asm volatile ("msr   primask, %0  \n\t"                         \
 | 
			
		||||
                                                  :                                                 \
 | 
			
		||||
                                                  : "r" (_SEGGER_RTT__LockState)                                 \
 | 
			
		||||
                                                  :                                                 \
 | 
			
		||||
                                                  );                                                \
 | 
			
		||||
                                }
 | 
			
		||||
  #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__))
 | 
			
		||||
    #ifndef   SEGGER_RTT_MAX_INTERRUPT_PRIORITY
 | 
			
		||||
      #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY   (0x20)
 | 
			
		||||
    #endif
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                    unsigned int _SEGGER_RTT__LockState;                                         \
 | 
			
		||||
                                  __asm volatile ("mrs   %0, basepri  \n\t"                         \
 | 
			
		||||
                                                  "mov   r1, %1       \n\t"                         \
 | 
			
		||||
                                                  "msr   basepri, r1  \n\t"                         \
 | 
			
		||||
                                                  : "=r" (_SEGGER_RTT__LockState)                                \
 | 
			
		||||
                                                  : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY)          \
 | 
			
		||||
                                                  : "r1", "cc"                                      \
 | 
			
		||||
                                                  );
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   __asm volatile ("msr   basepri, %0  \n\t"                         \
 | 
			
		||||
                                                  :                                                 \
 | 
			
		||||
                                                  : "r" (_SEGGER_RTT__LockState)                                 \
 | 
			
		||||
                                                  :                                                 \
 | 
			
		||||
                                                  );                                                \
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
  #elif (defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__))
 | 
			
		||||
    #define SEGGER_RTT_LOCK() {                                                \
 | 
			
		||||
                                 unsigned int _SEGGER_RTT__LockState;                       \
 | 
			
		||||
                                 __asm volatile ("mrs r1, CPSR \n\t"           \
 | 
			
		||||
                                                 "mov %0, r1 \n\t"             \
 | 
			
		||||
                                                 "orr r1, r1, #0xC0 \n\t"      \
 | 
			
		||||
                                                 "msr CPSR_c, r1 \n\t"         \
 | 
			
		||||
                                                 : "=r" (_SEGGER_RTT__LockState)            \
 | 
			
		||||
                                                 :                             \
 | 
			
		||||
                                                 : "r1", "cc"                  \
 | 
			
		||||
                                                 );
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t"              \
 | 
			
		||||
                                                "mrs r1, CPSR \n\t"            \
 | 
			
		||||
                                                "bic r1, r1, #0xC0 \n\t"       \
 | 
			
		||||
                                                "and r0, r0, #0xC0 \n\t"       \
 | 
			
		||||
                                                "orr r1, r1, r0 \n\t"          \
 | 
			
		||||
                                                "msr CPSR_c, r1 \n\t"          \
 | 
			
		||||
                                                :                              \
 | 
			
		||||
                                                : "r" (_SEGGER_RTT__LockState)              \
 | 
			
		||||
                                                : "r0", "r1", "cc"             \
 | 
			
		||||
                                                );                             \
 | 
			
		||||
                            }
 | 
			
		||||
  #elif defined(__riscv) || defined(__riscv_xlen)
 | 
			
		||||
    #define SEGGER_RTT_LOCK()  {                                               \
 | 
			
		||||
                                 unsigned int _SEGGER_RTT__LockState;                       \
 | 
			
		||||
                                 __asm volatile ("csrr  %0, mstatus  \n\t"     \
 | 
			
		||||
                                                 "csrci mstatus, 8   \n\t"     \
 | 
			
		||||
                                                 "andi  %0, %0,  8   \n\t"     \
 | 
			
		||||
                                                 : "=r" (_SEGGER_RTT__LockState)            \
 | 
			
		||||
                                                 :                             \
 | 
			
		||||
                                                 :                             \
 | 
			
		||||
                                                );
 | 
			
		||||
 | 
			
		||||
  #define SEGGER_RTT_UNLOCK()    __asm volatile ("csrr  a1, mstatus  \n\t"     \
 | 
			
		||||
                                                 "or    %0, %0, a1   \n\t"     \
 | 
			
		||||
                                                 "csrs  mstatus, %0  \n\t"     \
 | 
			
		||||
                                                 :                             \
 | 
			
		||||
                                                 : "r"  (_SEGGER_RTT__LockState)            \
 | 
			
		||||
                                                 : "a1"                        \
 | 
			
		||||
                                                );                             \
 | 
			
		||||
                               }
 | 
			
		||||
  #else
 | 
			
		||||
    #define SEGGER_RTT_LOCK()
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for IAR EWARM
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __ICCARM__
 | 
			
		||||
  #if (defined (__ARM6M__)          && (__CORE__ == __ARM6M__))             ||                      \
 | 
			
		||||
      (defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__))
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                  unsigned int _SEGGER_RTT__LockState;                                           \
 | 
			
		||||
                                  _SEGGER_RTT__LockState = __get_PRIMASK();                                      \
 | 
			
		||||
                                  __set_PRIMASK(1);
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   __set_PRIMASK(_SEGGER_RTT__LockState);                                         \
 | 
			
		||||
                                }
 | 
			
		||||
  #elif (defined (__ARM7EM__)         && (__CORE__ == __ARM7EM__))          ||                      \
 | 
			
		||||
        (defined (__ARM7M__)          && (__CORE__ == __ARM7M__))           ||                      \
 | 
			
		||||
        (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__))  ||                      \
 | 
			
		||||
        (defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__))
 | 
			
		||||
    #ifndef   SEGGER_RTT_MAX_INTERRUPT_PRIORITY
 | 
			
		||||
      #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY   (0x20)
 | 
			
		||||
    #endif
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                  unsigned int _SEGGER_RTT__LockState;                                           \
 | 
			
		||||
                                  _SEGGER_RTT__LockState = __get_BASEPRI();                                      \
 | 
			
		||||
                                  __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   __set_BASEPRI(_SEGGER_RTT__LockState);                                         \
 | 
			
		||||
                                }
 | 
			
		||||
  #elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__))                    ||                      \
 | 
			
		||||
        (defined (__ARM7R__) && (__CORE__ == __ARM7R__))
 | 
			
		||||
    #define SEGGER_RTT_LOCK() {                                                                     \
 | 
			
		||||
                                 unsigned int _SEGGER_RTT__LockState;                                            \
 | 
			
		||||
                                 __asm volatile ("mrs r1, CPSR \n\t"                                \
 | 
			
		||||
                                                 "mov %0, r1 \n\t"                                  \
 | 
			
		||||
                                                 "orr r1, r1, #0xC0 \n\t"                           \
 | 
			
		||||
                                                 "msr CPSR_c, r1 \n\t"                              \
 | 
			
		||||
                                                 : "=r" (_SEGGER_RTT__LockState)                                 \
 | 
			
		||||
                                                 :                                                  \
 | 
			
		||||
                                                 : "r1", "cc"                                       \
 | 
			
		||||
                                                 );
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t"                                   \
 | 
			
		||||
                                                "mrs r1, CPSR \n\t"                                 \
 | 
			
		||||
                                                "bic r1, r1, #0xC0 \n\t"                            \
 | 
			
		||||
                                                "and r0, r0, #0xC0 \n\t"                            \
 | 
			
		||||
                                                "orr r1, r1, r0 \n\t"                               \
 | 
			
		||||
                                                "msr CPSR_c, r1 \n\t"                               \
 | 
			
		||||
                                                :                                                   \
 | 
			
		||||
                                                : "r" (_SEGGER_RTT__LockState)                                   \
 | 
			
		||||
                                                : "r0", "r1", "cc"                                  \
 | 
			
		||||
                                                );                                                  \
 | 
			
		||||
                            }
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for IAR RX
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __ICCRX__
 | 
			
		||||
  #define SEGGER_RTT_LOCK()   {                                                                     \
 | 
			
		||||
                                unsigned long _SEGGER_RTT__LockState;                                            \
 | 
			
		||||
                                _SEGGER_RTT__LockState = __get_interrupt_state();                                \
 | 
			
		||||
                                __disable_interrupt();
 | 
			
		||||
 | 
			
		||||
  #define SEGGER_RTT_UNLOCK()   __set_interrupt_state(_SEGGER_RTT__LockState);                                   \
 | 
			
		||||
                              }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for IAR RL78
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __ICCRL78__
 | 
			
		||||
  #define SEGGER_RTT_LOCK()   {                                                                     \
 | 
			
		||||
                                __istate_t _SEGGER_RTT__LockState;                                               \
 | 
			
		||||
                                _SEGGER_RTT__LockState = __get_interrupt_state();                                \
 | 
			
		||||
                                __disable_interrupt();
 | 
			
		||||
 | 
			
		||||
  #define SEGGER_RTT_UNLOCK()   __set_interrupt_state(_SEGGER_RTT__LockState);                                   \
 | 
			
		||||
                              }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for KEIL ARM
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __CC_ARM
 | 
			
		||||
  #if (defined __TARGET_ARCH_6S_M)
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                  unsigned int _SEGGER_RTT__LockState;                                           \
 | 
			
		||||
                                  register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask");                 \
 | 
			
		||||
                                  _SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK;                                              \
 | 
			
		||||
                                  _SEGGER_RTT__PRIMASK = 1u;                                                     \
 | 
			
		||||
                                  __schedule_barrier();
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState;                                              \
 | 
			
		||||
                                  __schedule_barrier();                                             \
 | 
			
		||||
                                }
 | 
			
		||||
  #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
 | 
			
		||||
    #ifndef   SEGGER_RTT_MAX_INTERRUPT_PRIORITY
 | 
			
		||||
      #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY   (0x20)
 | 
			
		||||
    #endif
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                  unsigned int _SEGGER_RTT__LockState;                                           \
 | 
			
		||||
                                  register unsigned char BASEPRI __asm( "basepri");                 \
 | 
			
		||||
                                  _SEGGER_RTT__LockState = BASEPRI;                                              \
 | 
			
		||||
                                  BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY;                      \
 | 
			
		||||
                                  __schedule_barrier();
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   BASEPRI = _SEGGER_RTT__LockState;                                              \
 | 
			
		||||
                                  __schedule_barrier();                                             \
 | 
			
		||||
                                }
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for TI ARM
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __TI_ARM__
 | 
			
		||||
  #if defined (__TI_ARM_V6M0__)
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                  unsigned int _SEGGER_RTT__LockState;                                           \
 | 
			
		||||
                                  _SEGGER_RTT__LockState = __get_PRIMASK();                                      \
 | 
			
		||||
                                  __set_PRIMASK(1);
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   __set_PRIMASK(_SEGGER_RTT__LockState);                                         \
 | 
			
		||||
                                }
 | 
			
		||||
  #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
 | 
			
		||||
    #ifndef   SEGGER_RTT_MAX_INTERRUPT_PRIORITY
 | 
			
		||||
      #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY   (0x20)
 | 
			
		||||
    #endif
 | 
			
		||||
    #define SEGGER_RTT_LOCK()   {                                                                   \
 | 
			
		||||
                                  unsigned int _SEGGER_RTT__LockState;                                           \
 | 
			
		||||
                                  _SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
 | 
			
		||||
 | 
			
		||||
    #define SEGGER_RTT_UNLOCK()   _set_interrupt_priority(_SEGGER_RTT__LockState);                               \
 | 
			
		||||
                                }
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for CCRX
 | 
			
		||||
*/
 | 
			
		||||
#ifdef __RX
 | 
			
		||||
  #include <machine.h>
 | 
			
		||||
  #define SEGGER_RTT_LOCK()   {                                                                     \
 | 
			
		||||
                                unsigned long _SEGGER_RTT__LockState;                                            \
 | 
			
		||||
                                _SEGGER_RTT__LockState = get_psw() & 0x010000;                                   \
 | 
			
		||||
                                clrpsw_i();
 | 
			
		||||
 | 
			
		||||
  #define SEGGER_RTT_UNLOCK()   set_psw(get_psw() | _SEGGER_RTT__LockState);                                     \
 | 
			
		||||
                              }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration for embOS Simulation on Windows
 | 
			
		||||
*       (Can also be used for generic RTT locking with embOS)
 | 
			
		||||
*/
 | 
			
		||||
#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS)
 | 
			
		||||
 | 
			
		||||
void OS_SIM_EnterCriticalSection(void);
 | 
			
		||||
void OS_SIM_LeaveCriticalSection(void);
 | 
			
		||||
 | 
			
		||||
#define SEGGER_RTT_LOCK()       {                                                                   \
 | 
			
		||||
                                  OS_SIM_EnterCriticalSection();
 | 
			
		||||
 | 
			
		||||
#define SEGGER_RTT_UNLOCK()       OS_SIM_LeaveCriticalSection();                                    \
 | 
			
		||||
                                }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       RTT lock configuration fallback
 | 
			
		||||
*/
 | 
			
		||||
#ifndef   SEGGER_RTT_LOCK
 | 
			
		||||
  #define SEGGER_RTT_LOCK()                // Lock RTT (nestable)   (i.e. disable interrupts)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef   SEGGER_RTT_UNLOCK
 | 
			
		||||
  #define SEGGER_RTT_UNLOCK()              // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*************************** End of file ****************************/
 | 
			
		||||
@ -1,394 +0,0 @@
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*                    SEGGER Microcontroller GmbH                     *
 | 
			
		||||
*                        The Embedded Experts                        *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*            (c) 1995 - 2021 SEGGER Microcontroller GmbH             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       www.segger.com     Support: support@segger.com               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       SEGGER RTT * Real Time Transfer for embedded targets         *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* All rights reserved.                                               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* SEGGER strongly recommends to not make any changes                 *
 | 
			
		||||
* to or modify the source code of this software in order to stay     *
 | 
			
		||||
* compatible with the RTT protocol and J-Link.                       *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* Redistribution and use in source and binary forms, with or         *
 | 
			
		||||
* without modification, are permitted provided that the following    *
 | 
			
		||||
* condition is met:                                                  *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* o Redistributions of source code must retain the above copyright   *
 | 
			
		||||
*   notice, this condition and the following disclaimer.             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
 | 
			
		||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
 | 
			
		||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
 | 
			
		||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
 | 
			
		||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
 | 
			
		||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
 | 
			
		||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
 | 
			
		||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
 | 
			
		||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
 | 
			
		||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
 | 
			
		||||
* DAMAGE.                                                            *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       RTT version: 7.54                                           *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
 | 
			
		||||
---------------------------END-OF-HEADER------------------------------
 | 
			
		||||
File    : RTT_Syscalls_KEIL.c
 | 
			
		||||
Purpose : Retargeting module for KEIL MDK-CM3.
 | 
			
		||||
          Low-level functions for using printf() via RTT
 | 
			
		||||
Revision: $Rev: 24316 $
 | 
			
		||||
Notes   : (1) https://wiki.segger.com/Keil_MDK-ARM#RTT_in_uVision
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#if (defined __CC_ARM) || (defined __ARMCC_VERSION)
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <rt_sys.h>
 | 
			
		||||
#include <rt_misc.h>
 | 
			
		||||
 | 
			
		||||
#include "SEGGER_RTT.h"
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       #pragmas
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
#if __ARMCC_VERSION < 6000000
 | 
			
		||||
#pragma import(__use_no_semihosting)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _MICROLIB
 | 
			
		||||
  #pragma import(__use_full_stdio)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines non-configurable
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Standard IO device handles - arbitrary, but any real file system handles must be
 | 
			
		||||
   less than 0x8000. */
 | 
			
		||||
#define STDIN             0x8001    // Standard Input Stream
 | 
			
		||||
#define STDOUT            0x8002    // Standard Output Stream
 | 
			
		||||
#define STDERR            0x8003    // Standard Error Stream
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Public const
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
#if __ARMCC_VERSION < 5000000
 | 
			
		||||
//const char __stdin_name[]  = "STDIN";
 | 
			
		||||
const char __stdout_name[] = "STDOUT";
 | 
			
		||||
const char __stderr_name[] = "STDERR";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Public code
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _ttywrch
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Outputs a character to the console
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    c    - character to output
 | 
			
		||||
*  
 | 
			
		||||
*/
 | 
			
		||||
void _ttywrch(int c) {
 | 
			
		||||
  fputc(c, stdout); // stdout
 | 
			
		||||
  fflush(stdout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_open
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Opens the device/file in order to do read/write operations
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    sName        - sName of the device/file to open
 | 
			
		||||
*    OpenMode    - This parameter is currently ignored
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    != 0     - Handle to the object to open, otherwise 
 | 
			
		||||
*    == 0     -"device" is not handled by this module
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
FILEHANDLE _sys_open(const char * sName, int OpenMode) {
 | 
			
		||||
  (void)OpenMode;
 | 
			
		||||
  // Register standard Input Output devices.
 | 
			
		||||
  if (strcmp(sName, __stdout_name) == 0) {
 | 
			
		||||
    return (STDOUT);
 | 
			
		||||
  } else if (strcmp(sName, __stderr_name) == 0) {
 | 
			
		||||
    return (STDERR);
 | 
			
		||||
  } else
 | 
			
		||||
  return (0);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_close
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Closes the handle to the open device/file
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile    - Handle to a file opened via _sys_open
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    0     - device/file closed
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_close(FILEHANDLE hFile) {
 | 
			
		||||
  (void)hFile;
 | 
			
		||||
  return 0;  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_write
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Writes the data to an open handle.
 | 
			
		||||
*    Currently this function only outputs data to the console
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile    - Handle to a file opened via _sys_open
 | 
			
		||||
*    pBuffer  - Pointer to the data that shall be written
 | 
			
		||||
*    NumBytes      - Number of bytes to write
 | 
			
		||||
*    Mode     - The Mode that shall be used
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    Number of bytes *not* written to the file/device
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_write(FILEHANDLE hFile, const unsigned char * pBuffer, unsigned NumBytes, int Mode) {
 | 
			
		||||
  int r = 0;
 | 
			
		||||
 | 
			
		||||
  (void)Mode;
 | 
			
		||||
  if (hFile == STDOUT) {
 | 
			
		||||
    SEGGER_RTT_Write(0, (const char*)pBuffer, NumBytes);
 | 
			
		||||
		return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_read
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Reads data from an open handle.
 | 
			
		||||
*    Currently this modules does nothing.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile    - Handle to a file opened via _sys_open
 | 
			
		||||
*    pBuffer  - Pointer to buffer to store the read data
 | 
			
		||||
*    NumBytes      - Number of bytes to read
 | 
			
		||||
*    Mode     - The Mode that shall be used
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    Number of bytes read from the file/device
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_read(FILEHANDLE hFile, unsigned char * pBuffer, unsigned NumBytes, int Mode) {
 | 
			
		||||
  (void)hFile;
 | 
			
		||||
  (void)pBuffer;
 | 
			
		||||
  (void)NumBytes;
 | 
			
		||||
  (void)Mode;
 | 
			
		||||
  return (0);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_istty
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    This function shall return whether the opened file 
 | 
			
		||||
*    is a console device or not.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile    - Handle to a file opened via _sys_open
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    1       - Device is     a console
 | 
			
		||||
*    0       - Device is not a console
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_istty(FILEHANDLE hFile) {
 | 
			
		||||
  if (hFile > 0x8000) {
 | 
			
		||||
    return (1);
 | 
			
		||||
  }
 | 
			
		||||
  return (0);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_seek
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Seeks via the file to a specific position
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile  - Handle to a file opened via _sys_open
 | 
			
		||||
*    Pos    - 
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    int       - 
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_seek(FILEHANDLE hFile, long Pos) {
 | 
			
		||||
  (void)hFile;
 | 
			
		||||
  (void)Pos;
 | 
			
		||||
  return (0);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_ensure
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile    - Handle to a file opened via _sys_open
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    int       - 
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_ensure(FILEHANDLE hFile) {
 | 
			
		||||
  (void)hFile;
 | 
			
		||||
  return (-1);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_flen
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Returns the length of the opened file handle
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    hFile    - Handle to a file opened via _sys_open
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    Length of the file
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
long _sys_flen(FILEHANDLE hFile) {
 | 
			
		||||
  (void)hFile;
 | 
			
		||||
  return (0);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_tmpnam
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    This function converts the file number fileno for a temporary 
 | 
			
		||||
*    file to a unique filename, for example, tmp0001.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    pBuffer    - Pointer to a buffer to store the name
 | 
			
		||||
*    FileNum    - file number to convert
 | 
			
		||||
*    MaxLen     - Size of the buffer
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*     1 - Error
 | 
			
		||||
*     0 - Success  
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int _sys_tmpnam2(char * pBuffer, int FileNum, unsigned MaxLen) {
 | 
			
		||||
  (void)pBuffer;
 | 
			
		||||
  (void)FileNum;
 | 
			
		||||
  (void)MaxLen;
 | 
			
		||||
  return (1);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_command_string
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    This function shall execute a system command.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    cmd    - Pointer to the command string
 | 
			
		||||
*    len    - Length of the string
 | 
			
		||||
*  
 | 
			
		||||
*  Return value:
 | 
			
		||||
*    == NULL - Command was not successfully executed
 | 
			
		||||
*    == sCmd - Command was passed successfully
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
char * _sys_command_string(char * cmd, int len) {
 | 
			
		||||
  (void)len;
 | 
			
		||||
  return cmd;  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _sys_exit
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    This function is called when the application returns from main
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    ReturnCode    - Return code from the main function
 | 
			
		||||
*  
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
void _sys_exit(int ReturnCode) {
 | 
			
		||||
  (void)ReturnCode;
 | 
			
		||||
  while (1);  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if __ARMCC_VERSION >= 5000000
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       stdout_putchar
 | 
			
		||||
*
 | 
			
		||||
*  Function description:
 | 
			
		||||
*    Put a character to the stdout
 | 
			
		||||
*
 | 
			
		||||
*  Parameters:
 | 
			
		||||
*    ch    - Character to output
 | 
			
		||||
*  
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
int stdout_putchar(int ch) {
 | 
			
		||||
  (void)ch;
 | 
			
		||||
  return ch;  // Not implemented
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*************************** End of file ****************************/
 | 
			
		||||
@ -1,508 +0,0 @@
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*                    SEGGER Microcontroller GmbH                     *
 | 
			
		||||
*                        The Embedded Experts                        *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*            (c) 1995 - 2021 SEGGER Microcontroller GmbH             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       www.segger.com     Support: support@segger.com               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       SEGGER RTT * Real Time Transfer for embedded targets         *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* All rights reserved.                                               *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* SEGGER strongly recommends to not make any changes                 *
 | 
			
		||||
* to or modify the source code of this software in order to stay     *
 | 
			
		||||
* compatible with the RTT protocol and J-Link.                       *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* Redistribution and use in source and binary forms, with or         *
 | 
			
		||||
* without modification, are permitted provided that the following    *
 | 
			
		||||
* condition is met:                                                  *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* o Redistributions of source code must retain the above copyright   *
 | 
			
		||||
*   notice, this condition and the following disclaimer.             *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
 | 
			
		||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
 | 
			
		||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
 | 
			
		||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
 | 
			
		||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
 | 
			
		||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
 | 
			
		||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
 | 
			
		||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
 | 
			
		||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
 | 
			
		||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
 | 
			
		||||
* DAMAGE.                                                            *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*                                                                    *
 | 
			
		||||
*       RTT version: 8.10g                                           *
 | 
			
		||||
*                                                                    *
 | 
			
		||||
**********************************************************************
 | 
			
		||||
 | 
			
		||||
---------------------------END-OF-HEADER------------------------------
 | 
			
		||||
File    : SEGGER_RTT_printf.c
 | 
			
		||||
Purpose : Replacement for printf to write formatted data via RTT
 | 
			
		||||
Revision: $Rev: 17697 $
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#include "SEGGER_RTT.h"
 | 
			
		||||
#include "SEGGER_RTT_Conf.h"
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Defines, configurable
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
 | 
			
		||||
  #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define FORMAT_FLAG_LEFT_JUSTIFY   (1u << 0)
 | 
			
		||||
#define FORMAT_FLAG_PAD_ZERO       (1u << 1)
 | 
			
		||||
#define FORMAT_FLAG_PRINT_SIGN     (1u << 2)
 | 
			
		||||
#define FORMAT_FLAG_ALTERNATE      (1u << 3)
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Types
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char*     pBuffer;
 | 
			
		||||
  unsigned  BufferSize;
 | 
			
		||||
  unsigned  Cnt;
 | 
			
		||||
 | 
			
		||||
  int   ReturnValue;
 | 
			
		||||
 | 
			
		||||
  unsigned RTTBufferIndex;
 | 
			
		||||
} SEGGER_RTT_PRINTF_DESC;
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Function prototypes
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Static code
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _StoreChar
 | 
			
		||||
*/
 | 
			
		||||
static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
 | 
			
		||||
  unsigned Cnt;
 | 
			
		||||
 | 
			
		||||
  Cnt = p->Cnt;
 | 
			
		||||
  if ((Cnt + 1u) <= p->BufferSize) {
 | 
			
		||||
    *(p->pBuffer + Cnt) = c;
 | 
			
		||||
    p->Cnt = Cnt + 1u;
 | 
			
		||||
    p->ReturnValue++;
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // Write part of string, when the buffer is full
 | 
			
		||||
  //
 | 
			
		||||
  if (p->Cnt == p->BufferSize) {
 | 
			
		||||
    if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
 | 
			
		||||
      p->ReturnValue = -1;
 | 
			
		||||
    } else {
 | 
			
		||||
      p->Cnt = 0u;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _PrintUnsigned
 | 
			
		||||
*/
 | 
			
		||||
static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
 | 
			
		||||
  static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
 | 
			
		||||
  unsigned Div;
 | 
			
		||||
  unsigned Digit;
 | 
			
		||||
  unsigned Number;
 | 
			
		||||
  unsigned Width;
 | 
			
		||||
  char c;
 | 
			
		||||
 | 
			
		||||
  Number = v;
 | 
			
		||||
  Digit = 1u;
 | 
			
		||||
  //
 | 
			
		||||
  // Get actual field width
 | 
			
		||||
  //
 | 
			
		||||
  Width = 1u;
 | 
			
		||||
  while (Number >= Base) {
 | 
			
		||||
    Number = (Number / Base);
 | 
			
		||||
    Width++;
 | 
			
		||||
  }
 | 
			
		||||
  if (NumDigits > Width) {
 | 
			
		||||
    Width = NumDigits;
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // Print leading chars if necessary
 | 
			
		||||
  //
 | 
			
		||||
  if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
 | 
			
		||||
    if (FieldWidth != 0u) {
 | 
			
		||||
      if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
 | 
			
		||||
        c = '0';
 | 
			
		||||
      } else {
 | 
			
		||||
        c = ' ';
 | 
			
		||||
      }
 | 
			
		||||
      while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | 
			
		||||
        FieldWidth--;
 | 
			
		||||
        _StoreChar(pBufferDesc, c);
 | 
			
		||||
        if (pBufferDesc->ReturnValue < 0) {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (pBufferDesc->ReturnValue >= 0) {
 | 
			
		||||
    //
 | 
			
		||||
    // Compute Digit.
 | 
			
		||||
    // Loop until Digit has the value of the highest digit required.
 | 
			
		||||
    // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
 | 
			
		||||
    //
 | 
			
		||||
    while (1) {
 | 
			
		||||
      if (NumDigits > 1u) {       // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
 | 
			
		||||
        NumDigits--;
 | 
			
		||||
      } else {
 | 
			
		||||
        Div = v / Digit;
 | 
			
		||||
        if (Div < Base) {        // Is our divider big enough to extract the highest digit from value? => Done
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      Digit *= Base;
 | 
			
		||||
    }
 | 
			
		||||
    //
 | 
			
		||||
    // Output digits
 | 
			
		||||
    //
 | 
			
		||||
    do {
 | 
			
		||||
      Div = v / Digit;
 | 
			
		||||
      v -= Div * Digit;
 | 
			
		||||
      _StoreChar(pBufferDesc, _aV2C[Div]);
 | 
			
		||||
      if (pBufferDesc->ReturnValue < 0) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      Digit /= Base;
 | 
			
		||||
    } while (Digit);
 | 
			
		||||
    //
 | 
			
		||||
    // Print trailing spaces if necessary
 | 
			
		||||
    //
 | 
			
		||||
    if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
 | 
			
		||||
      if (FieldWidth != 0u) {
 | 
			
		||||
        while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | 
			
		||||
          FieldWidth--;
 | 
			
		||||
          _StoreChar(pBufferDesc, ' ');
 | 
			
		||||
          if (pBufferDesc->ReturnValue < 0) {
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       _PrintInt
 | 
			
		||||
*/
 | 
			
		||||
static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
 | 
			
		||||
  unsigned Width;
 | 
			
		||||
  int Number;
 | 
			
		||||
 | 
			
		||||
  Number = (v < 0) ? -v : v;
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Get actual field width
 | 
			
		||||
  //
 | 
			
		||||
  Width = 1u;
 | 
			
		||||
  while (Number >= (int)Base) {
 | 
			
		||||
    Number = (Number / (int)Base);
 | 
			
		||||
    Width++;
 | 
			
		||||
  }
 | 
			
		||||
  if (NumDigits > Width) {
 | 
			
		||||
    Width = NumDigits;
 | 
			
		||||
  }
 | 
			
		||||
  if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
 | 
			
		||||
    FieldWidth--;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Print leading spaces if necessary
 | 
			
		||||
  //
 | 
			
		||||
  if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
 | 
			
		||||
    if (FieldWidth != 0u) {
 | 
			
		||||
      while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | 
			
		||||
        FieldWidth--;
 | 
			
		||||
        _StoreChar(pBufferDesc, ' ');
 | 
			
		||||
        if (pBufferDesc->ReturnValue < 0) {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // Print sign if necessary
 | 
			
		||||
  //
 | 
			
		||||
  if (pBufferDesc->ReturnValue >= 0) {
 | 
			
		||||
    if (v < 0) {
 | 
			
		||||
      v = -v;
 | 
			
		||||
      _StoreChar(pBufferDesc, '-');
 | 
			
		||||
    } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
 | 
			
		||||
      _StoreChar(pBufferDesc, '+');
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    if (pBufferDesc->ReturnValue >= 0) {
 | 
			
		||||
      //
 | 
			
		||||
      // Print leading zeros if necessary
 | 
			
		||||
      //
 | 
			
		||||
      if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
 | 
			
		||||
        if (FieldWidth != 0u) {
 | 
			
		||||
          while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | 
			
		||||
            FieldWidth--;
 | 
			
		||||
            _StoreChar(pBufferDesc, '0');
 | 
			
		||||
            if (pBufferDesc->ReturnValue < 0) {
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (pBufferDesc->ReturnValue >= 0) {
 | 
			
		||||
        //
 | 
			
		||||
        // Print number without sign
 | 
			
		||||
        //
 | 
			
		||||
        _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       Public code
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************
 | 
			
		||||
*/
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       SEGGER_RTT_vprintf
 | 
			
		||||
*
 | 
			
		||||
*  Function description
 | 
			
		||||
*    Stores a formatted string in SEGGER RTT control block.
 | 
			
		||||
*    This data is read by the host.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters
 | 
			
		||||
*    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
 | 
			
		||||
*    sFormat      Pointer to format string
 | 
			
		||||
*    pParamList   Pointer to the list of arguments for the format string
 | 
			
		||||
*
 | 
			
		||||
*  Return values
 | 
			
		||||
*    >= 0:  Number of bytes which have been stored in the "Up"-buffer.
 | 
			
		||||
*     < 0:  Error
 | 
			
		||||
*/
 | 
			
		||||
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
 | 
			
		||||
  char c;
 | 
			
		||||
  SEGGER_RTT_PRINTF_DESC BufferDesc;
 | 
			
		||||
  int v;
 | 
			
		||||
  unsigned NumDigits;
 | 
			
		||||
  unsigned FormatFlags;
 | 
			
		||||
  unsigned FieldWidth;
 | 
			
		||||
  char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
 | 
			
		||||
 | 
			
		||||
  BufferDesc.pBuffer        = acBuffer;
 | 
			
		||||
  BufferDesc.BufferSize     = SEGGER_RTT_PRINTF_BUFFER_SIZE;
 | 
			
		||||
  BufferDesc.Cnt            = 0u;
 | 
			
		||||
  BufferDesc.RTTBufferIndex = BufferIndex;
 | 
			
		||||
  BufferDesc.ReturnValue    = 0;
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    c = *sFormat;
 | 
			
		||||
    sFormat++;
 | 
			
		||||
    if (c == 0u) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    if (c == '%') {
 | 
			
		||||
      //
 | 
			
		||||
      // Filter out flags
 | 
			
		||||
      //
 | 
			
		||||
      FormatFlags = 0u;
 | 
			
		||||
      v = 1;
 | 
			
		||||
      do {
 | 
			
		||||
        c = *sFormat;
 | 
			
		||||
        switch (c) {
 | 
			
		||||
        case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
 | 
			
		||||
        case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO;     sFormat++; break;
 | 
			
		||||
        case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN;   sFormat++; break;
 | 
			
		||||
        case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE;    sFormat++; break;
 | 
			
		||||
        default:  v = 0; break;
 | 
			
		||||
        }
 | 
			
		||||
      } while (v);
 | 
			
		||||
      //
 | 
			
		||||
      // filter out field with
 | 
			
		||||
      //
 | 
			
		||||
      FieldWidth = 0u;
 | 
			
		||||
      do {
 | 
			
		||||
        c = *sFormat;
 | 
			
		||||
        if ((c < '0') || (c > '9')) {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        sFormat++;
 | 
			
		||||
        FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
 | 
			
		||||
      } while (1);
 | 
			
		||||
 | 
			
		||||
      //
 | 
			
		||||
      // Filter out precision (number of digits to display)
 | 
			
		||||
      //
 | 
			
		||||
      NumDigits = 0u;
 | 
			
		||||
      c = *sFormat;
 | 
			
		||||
      if (c == '.') {
 | 
			
		||||
        sFormat++;
 | 
			
		||||
        do {
 | 
			
		||||
          c = *sFormat;
 | 
			
		||||
          if ((c < '0') || (c > '9')) {
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          sFormat++;
 | 
			
		||||
          NumDigits = NumDigits * 10u + ((unsigned)c - '0');
 | 
			
		||||
        } while (1);
 | 
			
		||||
      }
 | 
			
		||||
      //
 | 
			
		||||
      // Filter out length modifier
 | 
			
		||||
      //
 | 
			
		||||
      c = *sFormat;
 | 
			
		||||
      do {
 | 
			
		||||
        if ((c == 'l') || (c == 'h')) {
 | 
			
		||||
          sFormat++;
 | 
			
		||||
          c = *sFormat;
 | 
			
		||||
        } else {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      } while (1);
 | 
			
		||||
      //
 | 
			
		||||
      // Handle specifiers
 | 
			
		||||
      //
 | 
			
		||||
      switch (c) {
 | 
			
		||||
      case 'c': {
 | 
			
		||||
        char c0;
 | 
			
		||||
        v = va_arg(*pParamList, int);
 | 
			
		||||
        c0 = (char)v;
 | 
			
		||||
        _StoreChar(&BufferDesc, c0);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'd':
 | 
			
		||||
        v = va_arg(*pParamList, int);
 | 
			
		||||
        _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'u':
 | 
			
		||||
        v = va_arg(*pParamList, int);
 | 
			
		||||
        _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'x':
 | 
			
		||||
      case 'X':
 | 
			
		||||
        v = va_arg(*pParamList, int);
 | 
			
		||||
        _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
 | 
			
		||||
        break;
 | 
			
		||||
      case 's':
 | 
			
		||||
        {
 | 
			
		||||
          const char * s = va_arg(*pParamList, const char *);
 | 
			
		||||
          if (s == NULL) {
 | 
			
		||||
            s = "(NULL)";  // Print (NULL) instead of crashing or breaking, as it is more informative to the user.
 | 
			
		||||
          }
 | 
			
		||||
          do {
 | 
			
		||||
            c = *s;
 | 
			
		||||
            s++;
 | 
			
		||||
            if (c == '\0') {
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
           _StoreChar(&BufferDesc, c);
 | 
			
		||||
          } while (BufferDesc.ReturnValue >= 0);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case 'p':
 | 
			
		||||
        v = va_arg(*pParamList, int);
 | 
			
		||||
        _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
 | 
			
		||||
        break;
 | 
			
		||||
      case '%':
 | 
			
		||||
        _StoreChar(&BufferDesc, '%');
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      sFormat++;
 | 
			
		||||
    } else {
 | 
			
		||||
      _StoreChar(&BufferDesc, c);
 | 
			
		||||
    }
 | 
			
		||||
  } while (BufferDesc.ReturnValue >= 0);
 | 
			
		||||
 | 
			
		||||
  if (BufferDesc.ReturnValue > 0) {
 | 
			
		||||
    //
 | 
			
		||||
    // Write remaining data, if any
 | 
			
		||||
    //
 | 
			
		||||
    if (BufferDesc.Cnt != 0u) {
 | 
			
		||||
      SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
 | 
			
		||||
    }
 | 
			
		||||
    BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
 | 
			
		||||
  }
 | 
			
		||||
  return BufferDesc.ReturnValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
*
 | 
			
		||||
*       SEGGER_RTT_printf
 | 
			
		||||
*
 | 
			
		||||
*  Function description
 | 
			
		||||
*    Stores a formatted string in SEGGER RTT control block.
 | 
			
		||||
*    This data is read by the host.
 | 
			
		||||
*
 | 
			
		||||
*  Parameters
 | 
			
		||||
*    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
 | 
			
		||||
*    sFormat      Pointer to format string, followed by the arguments for conversion
 | 
			
		||||
*
 | 
			
		||||
*  Return values
 | 
			
		||||
*    >= 0:  Number of bytes which have been stored in the "Up"-buffer.
 | 
			
		||||
*     < 0:  Error
 | 
			
		||||
*
 | 
			
		||||
*  Notes
 | 
			
		||||
*    (1) Conversion specifications have following syntax:
 | 
			
		||||
*          %[flags][FieldWidth][.Precision]ConversionSpecifier
 | 
			
		||||
*    (2) Supported flags:
 | 
			
		||||
*          -: Left justify within the field width
 | 
			
		||||
*          +: Always print sign extension for signed conversions
 | 
			
		||||
*          0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
 | 
			
		||||
*        Supported conversion specifiers:
 | 
			
		||||
*          c: Print the argument as one char
 | 
			
		||||
*          d: Print the argument as a signed integer
 | 
			
		||||
*          u: Print the argument as an unsigned integer
 | 
			
		||||
*          x: Print the argument as an hexadecimal integer
 | 
			
		||||
*          s: Print the string pointed to by the argument
 | 
			
		||||
*          p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
 | 
			
		||||
*/
 | 
			
		||||
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
 | 
			
		||||
  int r;
 | 
			
		||||
  va_list ParamList;
 | 
			
		||||
 | 
			
		||||
  va_start(ParamList, sFormat);
 | 
			
		||||
  r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
 | 
			
		||||
  va_end(ParamList);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
/*************************** End of file ****************************/
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user