[wip] added encoder
This commit is contained in:
3
firmware/.vscode/c_cpp_properties.json
vendored
3
firmware/.vscode/c_cpp_properties.json
vendored
@@ -20,7 +20,8 @@
|
|||||||
"UNICODE",
|
"UNICODE",
|
||||||
"_UNICODE",
|
"_UNICODE",
|
||||||
"STM32F303xE",
|
"STM32F303xE",
|
||||||
"USE_HAL_DRIVER"
|
"USE_HAL_DRIVER",
|
||||||
|
"ULOG_ENABLED"
|
||||||
],
|
],
|
||||||
"compilerPath": "C:/MyApps/arm-gcc/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc.exe",
|
"compilerPath": "C:/MyApps/arm-gcc/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc.exe",
|
||||||
"cStandard": "c11",
|
"cStandard": "c11",
|
||||||
|
|||||||
56
firmware/.vscode/launch.json
vendored
56
firmware/.vscode/launch.json
vendored
@@ -27,36 +27,36 @@
|
|||||||
"type": "console",
|
"type": "console",
|
||||||
"timestamp": true
|
"timestamp": true
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
"label": "RTT graph",
|
// "label": "RTT graph",
|
||||||
"port": 0,
|
// "port": 0,
|
||||||
"encoding": "unsigned",
|
// "encoding": "unsigned",
|
||||||
"graphId": "1",
|
// "graphId": "1",
|
||||||
"scale": 1
|
// "scale": 1
|
||||||
}
|
// }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"graphConfig": [
|
// "graphConfig": [
|
||||||
{
|
// {
|
||||||
"label": "Graph 1",
|
// "label": "Graph 1",
|
||||||
"type": "realtime",
|
// "type": "realtime",
|
||||||
"minimum": 0,
|
// "minimum": 0,
|
||||||
"maximum": 65535,
|
// "maximum": 65535,
|
||||||
"timespan": 30,
|
// "timespan": 30,
|
||||||
"plots": [
|
// "plots": [
|
||||||
{
|
// {
|
||||||
"graphId": "1",
|
// "graphId": "1",
|
||||||
"label": "data 1",
|
// "label": "data 1",
|
||||||
"color": "#53753c",
|
// "color": "#53753c",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
"graphId": "2",
|
// "graphId": "2",
|
||||||
"label": "data 2",
|
// "label": "data 2",
|
||||||
"color": "#955f20"
|
// "color": "#955f20"
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
3
firmware/.vscode/settings.json
vendored
3
firmware/.vscode/settings.json
vendored
@@ -14,6 +14,7 @@
|
|||||||
"disp_layout_template.h": "c",
|
"disp_layout_template.h": "c",
|
||||||
"disp_layout_types.h": "c",
|
"disp_layout_types.h": "c",
|
||||||
"ctrl_app_types.h": "c",
|
"ctrl_app_types.h": "c",
|
||||||
"tim.h": "c"
|
"tim.h": "c",
|
||||||
|
"ulog.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
/* USER CODE BEGIN Header */
|
/* USER CODE BEGIN Header */
|
||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file : main.h
|
* @file : main.h
|
||||||
* @brief : Header for main.c file.
|
* @brief : Header for main.c file.
|
||||||
* This file contains the common defines of the application.
|
* This file contains the common defines of the application.
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @attention
|
* @attention
|
||||||
*
|
*
|
||||||
* Copyright (c) 2023 STMicroelectronics.
|
* Copyright (c) 2023 STMicroelectronics.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This software is licensed under terms that can be found in the LICENSE file
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
* in the root directory of this software component.
|
* in the root directory of this software component.
|
||||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
/* USER CODE END Header */
|
/* USER CODE END Header */
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
@@ -23,7 +23,8 @@
|
|||||||
#define __MAIN_H
|
#define __MAIN_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
@@ -31,26 +32,27 @@ extern "C" {
|
|||||||
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
|
// #include "SEGGER_RTT.h"
|
||||||
|
#include "ulog.h"
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* USER CODE END Includes */
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN ET */
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* USER CODE END ET */
|
||||||
/* USER CODE BEGIN ET */
|
|
||||||
|
|
||||||
/* USER CODE END ET */
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN EC */
|
||||||
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* USER CODE END EC */
|
||||||
/* USER CODE BEGIN EC */
|
|
||||||
|
|
||||||
/* USER CODE END EC */
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN EM */
|
||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
/* USER CODE END EM */
|
||||||
/* USER CODE BEGIN EM */
|
|
||||||
|
|
||||||
/* USER CODE END EM */
|
/* Exported functions prototypes ---------------------------------------------*/
|
||||||
|
void Error_Handler(void);
|
||||||
/* Exported functions prototypes ---------------------------------------------*/
|
|
||||||
void Error_Handler(void);
|
|
||||||
|
|
||||||
/* USER CODE BEGIN EFP */
|
/* USER CODE BEGIN EFP */
|
||||||
|
|
||||||
@@ -91,9 +93,9 @@ void Error_Handler(void);
|
|||||||
#define ST7565_A0_GPIO_Port GPIOD
|
#define ST7565_A0_GPIO_Port GPIOD
|
||||||
#define SWO_Pin GPIO_PIN_3
|
#define SWO_Pin GPIO_PIN_3
|
||||||
#define SWO_GPIO_Port GPIOB
|
#define SWO_GPIO_Port GPIOB
|
||||||
/* USER CODE BEGIN Private defines */
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
/* USER CODE END Private defines */
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "display_gfx.h"
|
#include "display_gfx.h"
|
||||||
#include "disp_layout.h"
|
#include "disp_layout.h"
|
||||||
#include "st7565.h"
|
#include "st7565.h"
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -57,7 +58,7 @@ APP_data_t app_data;
|
|||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
void SystemClock_Config(void);
|
void SystemClock_Config(void);
|
||||||
/* USER CODE BEGIN PFP */
|
/* USER CODE BEGIN PFP */
|
||||||
|
void RTT_console_logger(ulog_level_t severity, char *msg);
|
||||||
/* USER CODE END PFP */
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
@@ -66,41 +67,47 @@ void SystemClock_Config(void);
|
|||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The application entry point.
|
* @brief The application entry point.
|
||||||
* @retval int
|
* @retval int
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* MCU Configuration--------------------------------------------------------*/
|
/* MCU Configuration--------------------------------------------------------*/
|
||||||
|
|
||||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||||
HAL_Init();
|
HAL_Init();
|
||||||
|
|
||||||
/* USER CODE BEGIN Init */
|
/* USER CODE BEGIN Init */
|
||||||
|
|
||||||
/* USER CODE END Init */
|
/* USER CODE END Init */
|
||||||
|
|
||||||
/* Configure the system clock */
|
/* Configure the system clock */
|
||||||
SystemClock_Config();
|
SystemClock_Config();
|
||||||
|
|
||||||
/* USER CODE BEGIN SysInit */
|
/* USER CODE BEGIN SysInit */
|
||||||
|
|
||||||
/* USER CODE END SysInit */
|
/* USER CODE END SysInit */
|
||||||
|
|
||||||
|
/* Initialize all configured peripherals */
|
||||||
|
MX_GPIO_Init();
|
||||||
|
MX_USART2_UART_Init();
|
||||||
|
MX_SPI2_Init();
|
||||||
|
MX_I2C1_Init();
|
||||||
|
MX_SPI3_Init();
|
||||||
|
MX_TIM2_Init();
|
||||||
|
MX_TIM3_Init();
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
ulog_init();
|
||||||
|
ulog_subscribe(RTT_console_logger, ULOG_DEBUG_LEVEL);
|
||||||
|
|
||||||
/* Initialize all configured peripherals */
|
|
||||||
MX_GPIO_Init();
|
|
||||||
MX_USART2_UART_Init();
|
|
||||||
MX_SPI2_Init();
|
|
||||||
MX_I2C1_Init();
|
|
||||||
MX_SPI3_Init();
|
|
||||||
MX_TIM2_Init();
|
|
||||||
MX_TIM3_Init();
|
|
||||||
/* USER CODE BEGIN 2 */
|
|
||||||
APP_init(&app_data);
|
APP_init(&app_data);
|
||||||
|
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
|
||||||
|
// SEGGER_RTT_WriteString(0, "App start...\n");
|
||||||
|
ULOG_INFO("start app...");
|
||||||
|
|
||||||
hst7565.hspi = &hspi3;
|
hst7565.hspi = &hspi3;
|
||||||
hst7565.cs_port = ST7565_CS_GPIO_Port;
|
hst7565.cs_port = ST7565_CS_GPIO_Port;
|
||||||
@@ -111,10 +118,10 @@ int main(void)
|
|||||||
hst7565.rst_pin = ST7565_RST_Pin;
|
hst7565.rst_pin = ST7565_RST_Pin;
|
||||||
ST7565_Init(&hst7565, &disp);
|
ST7565_Init(&hst7565, &disp);
|
||||||
|
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
DISP_clearScreen(&disp);
|
DISP_clearScreen(&disp);
|
||||||
ST7565_DisplayAll(&hst7565);
|
ST7565_DisplayAll(&hst7565);
|
||||||
|
|
||||||
@@ -128,95 +135,99 @@ int main(void)
|
|||||||
ST7565_DisplayAll(&hst7565);
|
ST7565_DisplayAll(&hst7565);
|
||||||
LAY_drawDisplayLayout(&disp, &app_data);
|
LAY_drawDisplayLayout(&disp, &app_data);
|
||||||
}
|
}
|
||||||
/* USER CODE END WHILE */
|
/* USER CODE END WHILE */
|
||||||
|
|
||||||
/* USER CODE BEGIN 3 */
|
/* USER CODE BEGIN 3 */
|
||||||
}
|
}
|
||||||
/* USER CODE END 3 */
|
/* USER CODE END 3 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System Clock Configuration
|
* @brief System Clock Configuration
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void SystemClock_Config(void)
|
void SystemClock_Config(void)
|
||||||
{
|
{
|
||||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||||
|
|
||||||
/** Initializes the RCC Oscillators according to the specified parameters
|
/** Initializes the RCC Oscillators according to the specified parameters
|
||||||
* in the RCC_OscInitTypeDef structure.
|
* in the RCC_OscInitTypeDef structure.
|
||||||
*/
|
*/
|
||||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
|
||||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
|
||||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||||
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
|
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
|
||||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||||
{
|
{
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initializes the CPU, AHB and APB buses clocks
|
/** Initializes the CPU, AHB and APB buses clocks
|
||||||
*/
|
*/
|
||||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
|
||||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
|
||||||
|
|
||||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||||
{
|
{
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_I2C1
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_TIM2 | RCC_PERIPHCLK_TIM34;
|
||||||
|RCC_PERIPHCLK_TIM2|RCC_PERIPHCLK_TIM34;
|
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
|
||||||
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
|
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
|
||||||
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
|
PeriphClkInit.Tim2ClockSelection = RCC_TIM2CLK_HCLK;
|
||||||
PeriphClkInit.Tim2ClockSelection = RCC_TIM2CLK_HCLK;
|
PeriphClkInit.Tim34ClockSelection = RCC_TIM34CLK_HCLK;
|
||||||
PeriphClkInit.Tim34ClockSelection = RCC_TIM34CLK_HCLK;
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
{
|
||||||
{
|
Error_Handler();
|
||||||
Error_Handler();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
|
void RTT_console_logger(ulog_level_t severity, char *msg)
|
||||||
|
{
|
||||||
|
SEGGER_RTT_printf(0, "[%s]: %s\n",
|
||||||
|
// HAL_GetTick(), // user defined function
|
||||||
|
ulog_level_name(severity),
|
||||||
|
msg);
|
||||||
|
}
|
||||||
/* USER CODE END 4 */
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is executed in case of error occurrence.
|
* @brief This function is executed in case of error occurrence.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void Error_Handler(void)
|
void Error_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN Error_Handler_Debug */
|
/* USER CODE BEGIN Error_Handler_Debug */
|
||||||
/* User can add his own implementation to report the HAL error return state */
|
/* User can add his own implementation to report the HAL error return state */
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/* USER CODE END Error_Handler_Debug */
|
/* USER CODE END Error_Handler_Debug */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_FULL_ASSERT
|
#ifdef USE_FULL_ASSERT
|
||||||
/**
|
/**
|
||||||
* @brief Reports the name of the source file and the source line number
|
* @brief Reports the name of the source file and the source line number
|
||||||
* where the assert_param error has occurred.
|
* where the assert_param error has occurred.
|
||||||
* @param file: pointer to the source file name
|
* @param file: pointer to the source file name
|
||||||
* @param line: assert_param error line source number
|
* @param line: assert_param error line source number
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void assert_failed(uint8_t *file, uint32_t line)
|
void assert_failed(uint8_t *file, uint32_t line)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN 6 */
|
/* USER CODE BEGIN 6 */
|
||||||
/* User can add his own implementation to report the file name and line number,
|
/* User can add his own implementation to report the file name and line number,
|
||||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||||
/* USER CODE END 6 */
|
/* USER CODE END 6 */
|
||||||
}
|
}
|
||||||
#endif /* USE_FULL_ASSERT */
|
#endif /* USE_FULL_ASSERT */
|
||||||
|
|||||||
@@ -91,12 +91,15 @@ C_SOURCES += ../shared_libs/disp_layout/disp_layout.c
|
|||||||
C_SOURCES += ../shared_libs/controllers/ctrl_bottom_button.c
|
C_SOURCES += ../shared_libs/controllers/ctrl_bottom_button.c
|
||||||
C_SOURCES += ../shared_libs/controllers/ctrl_channel_button.c
|
C_SOURCES += ../shared_libs/controllers/ctrl_channel_button.c
|
||||||
C_SOURCES += ../shared_libs/controllers/ctrl_app.c
|
C_SOURCES += ../shared_libs/controllers/ctrl_app.c
|
||||||
|
C_SOURCES += ../shared_libs/controllers/ctrl_encoder.c
|
||||||
|
|
||||||
# utils/printf
|
# utils/printf
|
||||||
C_SOURCES += ../shared_libs/utils/printf/printf.c
|
C_SOURCES += ../shared_libs/utils/printf/printf.c
|
||||||
# utils/rtt
|
# utils/rtt
|
||||||
C_SOURCES += ../shared_libs/utils/rtt/SEGGER_RTT.c
|
C_SOURCES += ../shared_libs/utils/rtt/SEGGER_RTT.c
|
||||||
C_SOURCES += ../shared_libs/utils/rtt/SEGGER_RTT_printf.c
|
C_SOURCES += ../shared_libs/utils/rtt/SEGGER_RTT_printf.c
|
||||||
|
# utils/ulog
|
||||||
|
C_SOURCES += ../shared_libs/utils/ulog/ulog.c
|
||||||
|
|
||||||
# ASM sources
|
# ASM sources
|
||||||
ASM_SOURCES = \
|
ASM_SOURCES = \
|
||||||
@@ -145,7 +148,8 @@ AS_DEFS =
|
|||||||
# C defines
|
# C defines
|
||||||
C_DEFS = \
|
C_DEFS = \
|
||||||
-DUSE_HAL_DRIVER \
|
-DUSE_HAL_DRIVER \
|
||||||
-DSTM32F303xE
|
-DSTM32F303xE \
|
||||||
|
-DULOG_ENABLED
|
||||||
|
|
||||||
|
|
||||||
# AS includes
|
# AS includes
|
||||||
@@ -181,6 +185,7 @@ C_INCLUDES += -I../shared_libs/controllers
|
|||||||
# utils includes
|
# utils includes
|
||||||
C_INCLUDES += -I../shared_libs/utils/printf
|
C_INCLUDES += -I../shared_libs/utils/printf
|
||||||
C_INCLUDES += -I../shared_libs/utils/rtt
|
C_INCLUDES += -I../shared_libs/utils/rtt
|
||||||
|
C_INCLUDES += -I../shared_libs/utils/ulog
|
||||||
|
|
||||||
|
|
||||||
# compile gcc flags
|
# compile gcc flags
|
||||||
|
|||||||
@@ -2,18 +2,16 @@
|
|||||||
#include "hw_button.h"
|
#include "hw_button.h"
|
||||||
#include "ctrl_bottom_button.h"
|
#include "ctrl_bottom_button.h"
|
||||||
#include "ctrl_channel_button.h"
|
#include "ctrl_channel_button.h"
|
||||||
|
#include "ctrl_encoder.h"
|
||||||
|
|
||||||
#include "ctrl_app.h"
|
#include "ctrl_app.h"
|
||||||
|
|
||||||
#define FUN_GEN_FOCUS_MAX 6U
|
|
||||||
#define PWM_GEN_FOCUS_MAX 4U
|
|
||||||
|
|
||||||
typedef void (*btn_action_t)(void);
|
typedef void (*btn_action_t)(void);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
btn_action_t command;
|
btn_action_t command;
|
||||||
BITMAP_buttonName_t bitmap_name;
|
BITMAP_buttonName_t bitmap_name;
|
||||||
} CMD_button_t;
|
} CMD_button_t;
|
||||||
|
|
||||||
static GEN_fg_t func_gen[3];
|
static GEN_fg_t func_gen[3];
|
||||||
@@ -21,382 +19,528 @@ static GEN_pwm_t pwm_gen[3];
|
|||||||
|
|
||||||
static const CMD_button_t btn_command[BTN_STATE_MAX][DISP_BTN_MAX];
|
static const CMD_button_t btn_command[BTN_STATE_MAX][DISP_BTN_MAX];
|
||||||
static const LAY_dispBtn_t btn_hw_to_disp[BTN_BOT_MAX] = {DISP_BTN_1, DISP_BTN_2, DISP_BTN_3, DISP_BTN_4, DISP_BTN_5};
|
static const LAY_dispBtn_t btn_hw_to_disp[BTN_BOT_MAX] = {DISP_BTN_1, DISP_BTN_2, DISP_BTN_3, DISP_BTN_4, DISP_BTN_5};
|
||||||
|
static const uint32_t pow_of_10[7] = {1, 10, 100, 1000, 10000, 100000, 1000000};
|
||||||
|
|
||||||
static HW_BotBtnName_t last_key;
|
static HW_BotBtnName_t last_key;
|
||||||
static APP_data_t *_app_data;
|
static APP_data_t *_app_data;
|
||||||
|
|
||||||
static const GENERATOR_t generators[CHANNEL_MAX] = {
|
static const GENERATOR_t generators[CHANNEL_MAX] = {
|
||||||
{.gen_type = GEN_FG_TYPE, .gen = &func_gen[0]},
|
{.gen_type = GEN_FG_TYPE, .gen = &func_gen[0]},
|
||||||
{.gen_type = GEN_FG_TYPE, .gen = &func_gen[1]},
|
{.gen_type = GEN_FG_TYPE, .gen = &func_gen[1]},
|
||||||
{.gen_type = GEN_FG_TYPE, .gen = &func_gen[2]},
|
{.gen_type = GEN_FG_TYPE, .gen = &func_gen[2]},
|
||||||
{.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[0]},
|
{.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[0]},
|
||||||
{.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[1]},
|
{.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[1]},
|
||||||
{.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[2]},
|
{.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[2]},
|
||||||
};
|
};
|
||||||
|
|
||||||
void APP_init(APP_data_t *app_data)
|
void APP_init(APP_data_t *app_data)
|
||||||
{
|
{
|
||||||
_app_data = app_data;
|
_app_data = app_data;
|
||||||
_app_data->freq_focus_digit = 0;
|
_app_data->freq_focus_digit = 4;
|
||||||
_app_data->ampl_focus_digit = 0;
|
_app_data->ampl_focus_digit = 1;
|
||||||
_app_data->offs_focus_digit = 0;
|
_app_data->offs_focus_digit = 1;
|
||||||
_app_data->phas_focus_digit = 0;
|
_app_data->phas_focus_digit = 0;
|
||||||
_app_data->duty_focus_digit = 0;
|
_app_data->duty_focus_digit = 0;
|
||||||
|
|
||||||
_app_data->curr_gen_type = GEN_FG_TYPE;
|
_app_data->curr_gen_type = GEN_FG_TYPE;
|
||||||
_app_data->generator = generators[CHANNEL1].gen;
|
_app_data->generator = generators[CHANNEL1].gen;
|
||||||
|
|
||||||
_app_data->curr_state_lay = LAY_MAIN;
|
_app_data->curr_state_lay = LAY_MAIN;
|
||||||
_app_data->curr_state_btn = BTN_MAIN_FG;
|
_app_data->curr_state_btn = BTN_MAIN_FG;
|
||||||
|
|
||||||
_app_data->isChannelChange = 1;
|
_app_data->isChannelChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isButtonBlink = 1;
|
_app_data->isButtonBlink = 1;
|
||||||
|
|
||||||
CTRL_buttonsInit();
|
CTRL_buttonsInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTRL_buttonsInit(void)
|
void CTRL_buttonsInit(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
CTRL_bottomButtonInit();
|
CTRL_bottomButtonInit();
|
||||||
// CTRL_channelButtonInit();
|
// CTRL_channelButtonInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTRL_buttonsHandler(void)
|
void CTRL_buttonsHandler(void)
|
||||||
{
|
{
|
||||||
CTRL_bottomButtonsHandler();
|
CTRL_bottomButtonsHandler();
|
||||||
CTRL_channelButtonsHandler();
|
CTRL_channelButtonsHandler();
|
||||||
|
CTRL_encoderHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTRL_pushedDispBtnEvent(ButtonKey_t *key)
|
void CTRL_pushedDispBtnEvent(ButtonKey_t *key)
|
||||||
{
|
{
|
||||||
last_key = btn_hw_to_disp[key->instance];
|
ULOG_TRACE("Disp btn: %d", key->instance);
|
||||||
btn_command[_app_data->curr_state_btn][last_key].command();
|
last_key = btn_hw_to_disp[key->instance];
|
||||||
|
btn_command[_app_data->curr_state_btn][last_key].command();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTRL_pushedChanBtnEvent(ButtonKey_t *key)
|
void CTRL_pushedChanBtnEvent(ButtonKey_t *key)
|
||||||
{
|
{
|
||||||
UNUSED(key);
|
ULOG_TRACE("Chan btn: %d", key->instance);
|
||||||
|
UNUSED(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _changeValueFunGen(int8_t dir)
|
||||||
|
{
|
||||||
|
GEN_fg_t *gen = (GEN_fg_t *)_app_data->generator;
|
||||||
|
|
||||||
|
switch (_app_data->curr_state_lay)
|
||||||
|
{
|
||||||
|
case LAY_FREQ:
|
||||||
|
{
|
||||||
|
uint32_t new_freq = dir * pow_of_10[_app_data->freq_focus_digit] + gen->frequency;
|
||||||
|
ULOG_DEBUG("<FG> New freq: %lu", new_freq);
|
||||||
|
if (new_freq > MAX_FREQ)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->frequency = new_freq;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_AMPL:
|
||||||
|
{
|
||||||
|
uint16_t new_ampl = dir * pow_of_10[_app_data->ampl_focus_digit] + gen->amplitude;
|
||||||
|
ULOG_DEBUG("<FG> New ampl: %u", new_ampl);
|
||||||
|
if (gen->offset + new_ampl > MAX_VOLT_POS || gen->offset - new_ampl < MAX_VOLT_NEG)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->amplitude = new_ampl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_OFFS:
|
||||||
|
{
|
||||||
|
int16_t new_offs = dir * pow_of_10[_app_data->offs_focus_digit] + gen->offset;
|
||||||
|
ULOG_DEBUG("<FG> New offs: %i", new_offs);
|
||||||
|
if (new_offs + gen->amplitude > MAX_VOLT_POS || new_offs - gen->amplitude < MAX_VOLT_NEG)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->offset = new_offs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_PHAS:
|
||||||
|
{
|
||||||
|
uint16_t new_phas = dir * pow_of_10[_app_data->phas_focus_digit] + gen->phase;
|
||||||
|
ULOG_DEBUG("<FG> New phas: %u", new_phas);
|
||||||
|
if (new_phas > MAX_PHAS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->phase = new_phas;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ULOG_ERROR("%s:%d: Unknown layout: %d", __FILE__, __LINE__, _app_data->curr_state_lay);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _changeValuePwmGen(int8_t dir)
|
||||||
|
{
|
||||||
|
GEN_pwm_t *gen = (GEN_pwm_t *)_app_data->generator;
|
||||||
|
|
||||||
|
switch (_app_data->curr_state_lay)
|
||||||
|
{
|
||||||
|
case LAY_FREQ:
|
||||||
|
{
|
||||||
|
uint32_t new_freq = dir * pow_of_10[_app_data->freq_focus_digit] + gen->frequency;
|
||||||
|
ULOG_DEBUG("<FG> New freq: %lu", new_freq);
|
||||||
|
if (new_freq > MAX_FREQ)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->frequency = new_freq;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_AMPL:
|
||||||
|
{
|
||||||
|
uint16_t new_ampl = dir * pow_of_10[_app_data->ampl_focus_digit] + gen->amplitude;
|
||||||
|
ULOG_DEBUG("<FG> New ampl: %u", new_ampl);
|
||||||
|
if (gen->offset + new_ampl > MAX_VOLT_POS || gen->offset - new_ampl < MAX_VOLT_NEG)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->amplitude = new_ampl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_OFFS:
|
||||||
|
{
|
||||||
|
int16_t new_offs = dir * pow_of_10[_app_data->offs_focus_digit] + gen->offset;
|
||||||
|
ULOG_DEBUG("<FG> New offs: %i", new_offs);
|
||||||
|
if (new_offs + gen->amplitude > MAX_VOLT_POS || new_offs - gen->amplitude < MAX_VOLT_NEG)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->offset = new_offs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_PHAS:
|
||||||
|
{
|
||||||
|
uint16_t new_phas = dir * pow_of_10[_app_data->phas_focus_digit] + gen->phase;
|
||||||
|
ULOG_DEBUG("<FG> New phas: %u", new_phas);
|
||||||
|
if (new_phas > MAX_PHAS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->phase = new_phas;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LAY_DUTY:
|
||||||
|
{
|
||||||
|
uint8_t new_duty = dir * pow_of_10[_app_data->duty_focus_digit] + gen->duty;
|
||||||
|
ULOG_DEBUG("<FG> New duty: %u", new_duty);
|
||||||
|
if (new_duty > MAX_DUTY)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen->duty = new_duty;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTRL_encoderEvent(int8_t enc)
|
||||||
|
{
|
||||||
|
ULOG_TRACE("Enco event: %i", enc);
|
||||||
|
switch (_app_data->curr_gen_type)
|
||||||
|
{
|
||||||
|
case GEN_FG_TYPE:
|
||||||
|
_changeValueFunGen(enc / 2);
|
||||||
|
break;
|
||||||
|
case GEN_PWM_TYPE:
|
||||||
|
_changeValuePwmGen(enc / 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ULOG_ERROR("%s:%d: Unknown generator type.", __FILE__, __LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BITMAP_buttonName_t CTRL_getBitmapName(LAY_dispBtn_t disp_btn)
|
inline BITMAP_buttonName_t CTRL_getBitmapName(LAY_dispBtn_t disp_btn)
|
||||||
{
|
{
|
||||||
return btn_command[_app_data->curr_state_btn][disp_btn].bitmap_name;
|
return btn_command[_app_data->curr_state_btn][disp_btn].bitmap_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _doNoting(void)
|
static void _doNoting(void)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _backToMain(void)
|
static void _backToMain(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_MAIN;
|
_app_data->curr_state_lay = LAY_MAIN;
|
||||||
|
|
||||||
switch (_app_data->curr_gen_type)
|
switch (_app_data->curr_gen_type)
|
||||||
{
|
{
|
||||||
case GEN_FG_TYPE:
|
case GEN_FG_TYPE:
|
||||||
_app_data->curr_state_btn = BTN_MAIN_FG;
|
_app_data->curr_state_btn = BTN_MAIN_FG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GEN_PWM_TYPE:
|
case GEN_PWM_TYPE:
|
||||||
_app_data->curr_state_btn = BTN_MAIN_PWM;
|
_app_data->curr_state_btn = BTN_MAIN_PWM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _blockFocusAtMaxAndMin(void)
|
static void _blockFocusAtMaxAndMin(void)
|
||||||
{
|
{
|
||||||
switch (_app_data->curr_state_btn)
|
switch (_app_data->curr_state_btn)
|
||||||
{
|
{
|
||||||
case BTN_FREQ_MIN:
|
case BTN_FREQ_MIN:
|
||||||
if (_app_data->freq_focus_digit > 0)
|
if (_app_data->freq_focus_digit > 0)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_btn = BTN_FREQ;
|
_app_data->curr_state_btn = BTN_FREQ;
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BTN_FREQ_MAX:
|
case BTN_FREQ_MAX:
|
||||||
if (_app_data->freq_focus_digit < FUN_GEN_FOCUS_MAX)
|
if (_app_data->freq_focus_digit < FUN_GEN_FOCUS_MAX)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_btn = BTN_FREQ;
|
_app_data->curr_state_btn = BTN_FREQ;
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BTN_FREQ:
|
case BTN_FREQ:
|
||||||
if (_app_data->freq_focus_digit == 0)
|
if (_app_data->freq_focus_digit == 0)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_btn = BTN_FREQ_MIN;
|
_app_data->curr_state_btn = BTN_FREQ_MIN;
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
}
|
}
|
||||||
else if (_app_data->freq_focus_digit == FUN_GEN_FOCUS_MAX)
|
else if (_app_data->freq_focus_digit == FUN_GEN_FOCUS_MAX)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_btn = BTN_FREQ_MAX;
|
_app_data->curr_state_btn = BTN_FREQ_MAX;
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enterToFreqLayout(void)
|
static void _enterToFreqLayout(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_FREQ;
|
_app_data->curr_state_lay = LAY_FREQ;
|
||||||
_app_data->curr_state_btn = BTN_FREQ;
|
_app_data->curr_state_btn = BTN_FREQ;
|
||||||
_blockFocusAtMaxAndMin();
|
_blockFocusAtMaxAndMin();
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enterToAmplLayout(void)
|
static void _enterToAmplLayout(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_AMPL;
|
_app_data->curr_state_lay = LAY_AMPL;
|
||||||
_app_data->curr_state_btn = BTN_AMPL;
|
_app_data->curr_state_btn = BTN_AMPL;
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enterToOffslLayout(void)
|
static void _enterToOffslLayout(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_OFFS;
|
_app_data->curr_state_lay = LAY_OFFS;
|
||||||
_app_data->curr_state_btn = BTN_OFFS;
|
_app_data->curr_state_btn = BTN_OFFS;
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enterToPhasLayout(void)
|
static void _enterToPhasLayout(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_PHAS;
|
_app_data->curr_state_lay = LAY_PHAS;
|
||||||
_app_data->curr_state_btn = BTN_PHAS;
|
_app_data->curr_state_btn = BTN_PHAS;
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enterToDutyLayout(void)
|
static void _enterToDutyLayout(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_DUTY;
|
_app_data->curr_state_lay = LAY_DUTY;
|
||||||
_app_data->curr_state_btn = BTN_DUTY;
|
_app_data->curr_state_btn = BTN_DUTY;
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enterToWavelLayout(void)
|
static void _enterToWavelLayout(void)
|
||||||
{
|
{
|
||||||
_app_data->curr_state_lay = LAY_WAVE;
|
_app_data->curr_state_lay = LAY_WAVE;
|
||||||
_app_data->curr_state_btn = BTN_WAVE;
|
_app_data->curr_state_btn = BTN_WAVE;
|
||||||
|
|
||||||
_app_data->isButtonChange = 1;
|
_app_data->isButtonChange = 1;
|
||||||
_app_data->isGraphChange = 1;
|
_app_data->isGraphChange = 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _moveToLeftFocusFreqNumber(void)
|
static void _moveToLeftFocusFreqNumber(void)
|
||||||
{
|
{
|
||||||
_app_data->freq_focus_digit += 1;
|
_app_data->freq_focus_digit += 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
|
|
||||||
_blockFocusAtMaxAndMin();
|
_blockFocusAtMaxAndMin();
|
||||||
_app_data->timer_blink[last_key] = 2;
|
_app_data->timer_blink[last_key] = 2;
|
||||||
_app_data->isButtonBlink |= (1 << last_key);
|
_app_data->isButtonBlink |= (1 << last_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _moveToRighttFocusFreqNumber(void)
|
static void _moveToRighttFocusFreqNumber(void)
|
||||||
{
|
{
|
||||||
_app_data->freq_focus_digit -= 1;
|
_app_data->freq_focus_digit -= 1;
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
|
|
||||||
_blockFocusAtMaxAndMin();
|
_blockFocusAtMaxAndMin();
|
||||||
_app_data->timer_blink[last_key] = 2;
|
_app_data->timer_blink[last_key] = 2;
|
||||||
_app_data->isButtonBlink |= (1 << last_key);
|
_app_data->isButtonBlink |= (1 << last_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _setTo0_01xFocusNumber(void)
|
static void _setTo0_01xFocusNumber(void)
|
||||||
{
|
{
|
||||||
switch (_app_data->curr_state_lay)
|
switch (_app_data->curr_state_lay)
|
||||||
{
|
{
|
||||||
case LAY_AMPL:
|
case LAY_AMPL:
|
||||||
_app_data->ampl_focus_digit = 0;
|
_app_data->ampl_focus_digit = 0;
|
||||||
break;
|
break;
|
||||||
case LAY_OFFS:
|
case LAY_OFFS:
|
||||||
_app_data->offs_focus_digit = 0;
|
_app_data->offs_focus_digit = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_app_data->timer_blink[last_key] = 2;
|
_app_data->timer_blink[last_key] = 2;
|
||||||
_app_data->isButtonBlink |= (1 << last_key);
|
_app_data->isButtonBlink |= (1 << last_key);
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
static void _setTo0_1xFocusNumber(void)
|
static void _setTo0_1xFocusNumber(void)
|
||||||
{
|
{
|
||||||
switch (_app_data->curr_state_lay)
|
switch (_app_data->curr_state_lay)
|
||||||
{
|
{
|
||||||
case LAY_AMPL:
|
case LAY_AMPL:
|
||||||
_app_data->ampl_focus_digit = 1;
|
_app_data->ampl_focus_digit = 1;
|
||||||
break;
|
break;
|
||||||
case LAY_OFFS:
|
case LAY_OFFS:
|
||||||
_app_data->offs_focus_digit = 1;
|
_app_data->offs_focus_digit = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_app_data->timer_blink[last_key] = 2;
|
_app_data->timer_blink[last_key] = 2;
|
||||||
_app_data->isButtonBlink |= (1 << last_key);
|
_app_data->isButtonBlink |= (1 << last_key);
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
static void _setTo1xFocusNumber(void)
|
static void _setTo1xFocusNumber(void)
|
||||||
{
|
{
|
||||||
switch (_app_data->curr_state_lay)
|
switch (_app_data->curr_state_lay)
|
||||||
{
|
{
|
||||||
case LAY_AMPL:
|
case LAY_AMPL:
|
||||||
_app_data->ampl_focus_digit = 2;
|
_app_data->ampl_focus_digit = 2;
|
||||||
break;
|
break;
|
||||||
case LAY_OFFS:
|
case LAY_OFFS:
|
||||||
_app_data->offs_focus_digit = 2;
|
_app_data->offs_focus_digit = 2;
|
||||||
break;
|
break;
|
||||||
case LAY_PHAS:
|
case LAY_PHAS:
|
||||||
_app_data->offs_focus_digit = 0;
|
_app_data->phas_focus_digit = 0;
|
||||||
break;
|
break;
|
||||||
case LAY_DUTY:
|
case LAY_DUTY:
|
||||||
_app_data->offs_focus_digit = 0;
|
_app_data->duty_focus_digit = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_app_data->timer_blink[last_key] = 2;
|
_app_data->timer_blink[last_key] = 2;
|
||||||
_app_data->isButtonBlink |= (1 << last_key);
|
_app_data->isButtonBlink |= (1 << last_key);
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
static void _setTo10xFocusNumber(void)
|
static void _setTo10xFocusNumber(void)
|
||||||
{
|
{
|
||||||
switch (_app_data->curr_state_lay)
|
switch (_app_data->curr_state_lay)
|
||||||
{
|
{
|
||||||
case LAY_AMPL:
|
case LAY_AMPL:
|
||||||
_app_data->ampl_focus_digit = 3;
|
_app_data->ampl_focus_digit = 3;
|
||||||
break;
|
break;
|
||||||
case LAY_OFFS:
|
case LAY_OFFS:
|
||||||
_app_data->offs_focus_digit = 3;
|
_app_data->offs_focus_digit = 3;
|
||||||
break;
|
break;
|
||||||
case LAY_PHAS:
|
case LAY_PHAS:
|
||||||
_app_data->offs_focus_digit = 1;
|
_app_data->phas_focus_digit = 1;
|
||||||
break;
|
break;
|
||||||
case LAY_DUTY:
|
case LAY_DUTY:
|
||||||
_app_data->offs_focus_digit = 1;
|
_app_data->duty_focus_digit = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_app_data->timer_blink[last_key] = 2;
|
_app_data->timer_blink[last_key] = 2;
|
||||||
_app_data->isButtonBlink |= (1 << last_key);
|
_app_data->isButtonBlink |= (1 << last_key);
|
||||||
_app_data->isValueChange = 1;
|
_app_data->isValueChange = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const CMD_button_t btn_command[BTN_STATE_MAX][DISP_BTN_MAX] = {
|
static const CMD_button_t btn_command[BTN_STATE_MAX][DISP_BTN_MAX] = {
|
||||||
{
|
{
|
||||||
// BTN_MAIN_FG
|
// BTN_MAIN_FG
|
||||||
{_enterToFreqLayout, BITMAP_BTN_FREQ},
|
{_enterToFreqLayout, BITMAP_BTN_FREQ},
|
||||||
{_enterToAmplLayout, BITMAP_BTN_AMPL},
|
{_enterToAmplLayout, BITMAP_BTN_AMPL},
|
||||||
{_enterToOffslLayout, BITMAP_BTN_OFFS},
|
{_enterToOffslLayout, BITMAP_BTN_OFFS},
|
||||||
{_enterToPhasLayout, BITMAP_BTN_PHAS},
|
{_enterToPhasLayout, BITMAP_BTN_PHAS},
|
||||||
{_enterToWavelLayout, BITMAP_BTN_WAVE},
|
{_enterToWavelLayout, BITMAP_BTN_WAVE},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_MAIN_PWM
|
// BTN_MAIN_PWM
|
||||||
{_enterToFreqLayout, BITMAP_BTN_FREQ},
|
{_enterToFreqLayout, BITMAP_BTN_FREQ},
|
||||||
{_enterToAmplLayout, BITMAP_BTN_AMPL},
|
{_enterToAmplLayout, BITMAP_BTN_AMPL},
|
||||||
{_enterToOffslLayout, BITMAP_BTN_OFFS},
|
{_enterToOffslLayout, BITMAP_BTN_OFFS},
|
||||||
{_enterToPhasLayout, BITMAP_BTN_PHAS},
|
{_enterToPhasLayout, BITMAP_BTN_PHAS},
|
||||||
{_enterToDutyLayout, BITMAP_BTN_NONE},
|
{_enterToDutyLayout, BITMAP_BTN_NONE},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_FREQ
|
// BTN_FREQ
|
||||||
{_moveToLeftFocusFreqNumber, BITMAP_BTN_LEFT},
|
{_moveToLeftFocusFreqNumber, BITMAP_BTN_LEFT},
|
||||||
{_moveToRighttFocusFreqNumber, BITMAP_BTN_RIGHT},
|
{_moveToRighttFocusFreqNumber, BITMAP_BTN_RIGHT},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_FREQ_MIN
|
// BTN_FREQ_MIN
|
||||||
{_moveToLeftFocusFreqNumber, BITMAP_BTN_LEFT},
|
{_moveToLeftFocusFreqNumber, BITMAP_BTN_LEFT},
|
||||||
{_doNoting, BITMAP_BTN_EMPTY},
|
{_doNoting, BITMAP_BTN_EMPTY},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_FREQ_MAX
|
// BTN_FREQ_MAX
|
||||||
{_doNoting, BITMAP_BTN_EMPTY},
|
{_doNoting, BITMAP_BTN_EMPTY},
|
||||||
{_moveToRighttFocusFreqNumber, BITMAP_BTN_RIGHT},
|
{_moveToRighttFocusFreqNumber, BITMAP_BTN_RIGHT},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_AMPL
|
// BTN_AMPL
|
||||||
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
||||||
{_setTo0_1xFocusNumber, BITMAP_BTN_X0_1},
|
{_setTo0_1xFocusNumber, BITMAP_BTN_X0_1},
|
||||||
{_setTo0_01xFocusNumber, BITMAP_BTN_X0_01},
|
{_setTo0_01xFocusNumber, BITMAP_BTN_X0_01},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_OFFS
|
// BTN_OFFS
|
||||||
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
||||||
{_setTo0_1xFocusNumber, BITMAP_BTN_X0_1},
|
{_setTo0_1xFocusNumber, BITMAP_BTN_X0_1},
|
||||||
{_setTo0_01xFocusNumber, BITMAP_BTN_X0_01},
|
{_setTo0_01xFocusNumber, BITMAP_BTN_X0_01},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_PHAS
|
// BTN_PHAS
|
||||||
{_setTo10xFocusNumber, BITMAP_BTN_X10},
|
{_setTo10xFocusNumber, BITMAP_BTN_X10},
|
||||||
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_DUTY
|
// BTN_DUTY
|
||||||
{_setTo10xFocusNumber, BITMAP_BTN_X10},
|
{_setTo10xFocusNumber, BITMAP_BTN_X10},
|
||||||
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
{_setTo1xFocusNumber, BITMAP_BTN_X1},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BTN_WAVE
|
// BTN_WAVE
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_doNoting, BITMAP_BTN_NONE},
|
{_doNoting, BITMAP_BTN_NONE},
|
||||||
{_backToMain, BITMAP_BTN_BACK},
|
{_backToMain, BITMAP_BTN_BACK},
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ typedef struct
|
|||||||
uint16_t phase;
|
uint16_t phase;
|
||||||
uint8_t wave;
|
uint8_t wave;
|
||||||
uint8_t enabled;
|
uint8_t enabled;
|
||||||
uint8_t connected;
|
uint8_t link;
|
||||||
} GEN_fg_t;
|
} GEN_fg_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -59,4 +59,5 @@ void CTRL_buttonsInit(void);
|
|||||||
void CTRL_buttonsHandler(void);
|
void CTRL_buttonsHandler(void);
|
||||||
void CTRL_pushedDispBtnEvent(ButtonKey_t *key);
|
void CTRL_pushedDispBtnEvent(ButtonKey_t *key);
|
||||||
void CTRL_pushedChanBtnEvent(ButtonKey_t *key);
|
void CTRL_pushedChanBtnEvent(ButtonKey_t *key);
|
||||||
|
void CTRL_encoderEvent(int8_t enc);
|
||||||
BITMAP_buttonName_t CTRL_getBitmapName(LAY_dispBtn_t disp_btn);
|
BITMAP_buttonName_t CTRL_getBitmapName(LAY_dispBtn_t disp_btn);
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define FUN_GEN_FOCUS_MAX 6U
|
||||||
|
#define PWM_GEN_FOCUS_MAX 4U
|
||||||
|
#define MAX_FREQ 1000000U
|
||||||
|
#define MAX_VOLT_POS 500
|
||||||
|
#define MAX_VOLT_NEG -500
|
||||||
|
#define MAX_PHAS 360
|
||||||
|
#define MAX_DUTY 100
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GEN_FG_TYPE,
|
GEN_FG_TYPE,
|
||||||
|
|||||||
16
firmware/shared_libs/controllers/ctrl_encoder.c
Normal file
16
firmware/shared_libs/controllers/ctrl_encoder.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include "main.h"
|
||||||
|
#include "tim.h"
|
||||||
|
#include "ctrl_app.h"
|
||||||
|
|
||||||
|
void CTRL_encoderHandler(void)
|
||||||
|
{
|
||||||
|
static uint8_t cnt;
|
||||||
|
if (htim3.Instance->CNT == cnt || htim3.Instance->CNT % 2 == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEGGER_RTT_printf(0, "TIM3.cnt: %d\n", htim3.Instance->CNT);
|
||||||
|
CTRL_encoderEvent(htim3.Instance->CNT - cnt);
|
||||||
|
cnt = (uint8_t)htim3.Instance->CNT;
|
||||||
|
}
|
||||||
3
firmware/shared_libs/controllers/ctrl_encoder.h
Normal file
3
firmware/shared_libs/controllers/ctrl_encoder.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void CTRL_encoderHandler(void);
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
const uint8_t btn_pos_x[DISP_BTN_MAX] = {0, 26, 52, 78, 104};
|
const uint8_t btn_pos_x[DISP_BTN_MAX] = {0, 26, 52, 78, 104};
|
||||||
const uint8_t marker_freq_pos_x[FREQ_MAX_DIGIT] = {76, 84, 90, 96, 105, 111, 118};
|
const uint8_t marker_freq_pos_x[FREQ_MAX_DIGIT] = {76, 84, 90, 96, 105, 111, 118};
|
||||||
const uint8_t marker_ampl_pos_x[AMPL_MAX_DIGIT] = {82, 94, 100};
|
const uint8_t marker_ampl_pos_x[AMPL_MAX_DIGIT] = {82, 94, 100};
|
||||||
|
const uint8_t marker_phas_pos_x[AMPL_MAX_DIGIT] = {82, 88, 96};
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const GFX_bitmap_t marker_down = {05, 03, (uint8_t[]){0x01,0x03,0x07,0x03,0x01}};// res: 5x3(8) - 5 bytes
|
const GFX_bitmap_t marker_down = {05, 03, (uint8_t[]){0x01,0x03,0x07,0x03,0x01}};// res: 5x3(8) - 5 bytes
|
||||||
@@ -28,7 +29,6 @@ static void _drawFreqValue(GFX_display_t *disp, uint32_t freq, uint8_t pos_y)
|
|||||||
uint8_t data[8];
|
uint8_t data[8];
|
||||||
snprintf((char *)data, 8, "%07u", freq);
|
snprintf((char *)data, 8, "%07u", freq);
|
||||||
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[0], 0}, 76, pos_y, BM_NORMAL);
|
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[0], 0}, 76, pos_y, BM_NORMAL);
|
||||||
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[0], 0}, 76, pos_y, BM_NORMAL);
|
|
||||||
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[1], data[2], data[3], 0}, 84, pos_y, BM_NORMAL);
|
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[1], data[2], data[3], 0}, 84, pos_y, BM_NORMAL);
|
||||||
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[4], data[5], data[6], 0}, 105, pos_y, BM_NORMAL);
|
DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[4], data[5], data[6], 0}, 105, pos_y, BM_NORMAL);
|
||||||
}
|
}
|
||||||
@@ -44,6 +44,10 @@ static void _drawOffsValue(GFX_display_t *disp, int16_t offs, uint8_t pos_y)
|
|||||||
{
|
{
|
||||||
uint8_t data[8];
|
uint8_t data[8];
|
||||||
snprintf((char *)data, 8, "%+01d.%02d V", offs / 100, abs(offs) % 100);
|
snprintf((char *)data, 8, "%+01d.%02d V", offs / 100, abs(offs) % 100);
|
||||||
|
if (offs < 0)
|
||||||
|
{
|
||||||
|
data[0] = '-';
|
||||||
|
}
|
||||||
DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL);
|
DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,12 +58,12 @@ static void _drawPhasValue(GFX_display_t *disp, uint16_t phase, uint8_t pos_y)
|
|||||||
DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL);
|
DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawDutyValue(GFX_display_t *disp, uint8_t duty, uint8_t pos_y)
|
// static void _drawDutyValue(GFX_display_t *disp, uint8_t duty, uint8_t pos_y)
|
||||||
{
|
// {
|
||||||
uint8_t data[8];
|
// uint8_t data[8];
|
||||||
snprintf((char *)data, 8, "%03u%%", duty);
|
// snprintf((char *)data, 8, "%03u%%", duty);
|
||||||
DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL);
|
// DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static void _blinkButtons(GFX_display_t *disp, APP_data_t *app_data)
|
static void _blinkButtons(GFX_display_t *disp, APP_data_t *app_data)
|
||||||
{
|
{
|
||||||
@@ -168,7 +172,7 @@ static void _drawPhaseValueHelper(GFX_display_t *disp, uint32_t phase, uint8_t f
|
|||||||
DISP_clearRegion(disp, 64, 13, 66, 40);
|
DISP_clearRegion(disp, 64, 13, 66, 40);
|
||||||
DISP_writeString(disp, &font5x7Info, (uint8_t *)"P:", 64, 20, BM_NORMAL);
|
DISP_writeString(disp, &font5x7Info, (uint8_t *)"P:", 64, 20, BM_NORMAL);
|
||||||
_drawPhasValue(disp, phase, 20);
|
_drawPhasValue(disp, phase, 20);
|
||||||
DISP_drawBitmap(disp, &marker_down, marker_ampl_pos_x[(AMPL_MAX_DIGIT - 1) - focus_digit], 15, BM_NORMAL);
|
DISP_drawBitmap(disp, &marker_down, marker_phas_pos_x[(AMPL_MAX_DIGIT - 1) - focus_digit], 15, BM_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawFuncGenValues(GFX_display_t *disp, APP_data_t *app_data)
|
static void _drawFuncGenValues(GFX_display_t *disp, APP_data_t *app_data)
|
||||||
@@ -178,19 +182,19 @@ static void _drawFuncGenValues(GFX_display_t *disp, APP_data_t *app_data)
|
|||||||
{
|
{
|
||||||
case LAY_FREQ:
|
case LAY_FREQ:
|
||||||
_drawFreqValueHelper(disp, fun_gen->frequency, app_data->freq_focus_digit);
|
_drawFreqValueHelper(disp, fun_gen->frequency, app_data->freq_focus_digit);
|
||||||
_drawMeterHelper(disp, "1", "1M", _calcMarkerPos(990000, 1000000));
|
_drawMeterHelper(disp, "1", "1M", _calcMarkerPos(fun_gen->frequency, MAX_FREQ));
|
||||||
break;
|
break;
|
||||||
case LAY_AMPL:
|
case LAY_AMPL:
|
||||||
_drawAmplValueHelper(disp, fun_gen->amplitude, app_data->ampl_focus_digit);
|
_drawAmplValueHelper(disp, fun_gen->amplitude, app_data->ampl_focus_digit);
|
||||||
_drawMeterHelper(disp, "0V", "5V", _calcMarkerPos(100, 500));
|
_drawMeterHelper(disp, "0V", "5V", _calcMarkerPos(fun_gen->amplitude, MAX_VOLT_POS));
|
||||||
break;
|
break;
|
||||||
case LAY_OFFS:
|
case LAY_OFFS:
|
||||||
_drawOffsValueHelper(disp, fun_gen->offset, app_data->offs_focus_digit);
|
_drawOffsValueHelper(disp, fun_gen->offset, app_data->offs_focus_digit);
|
||||||
_drawMeterHelper(disp, "-5V", "+5V", _calcMarkerPos(100 + 250, 500 + 250));
|
_drawMeterHelper(disp, "-5V", "+5V", _calcMarkerPos(MAX_VOLT_POS + fun_gen->offset, MAX_VOLT_POS * 2));
|
||||||
break;
|
break;
|
||||||
case LAY_PHAS:
|
case LAY_PHAS:
|
||||||
_drawPhaseValueHelper(disp, fun_gen->phase, app_data->phas_focus_digit);
|
_drawPhaseValueHelper(disp, fun_gen->phase, app_data->phas_focus_digit);
|
||||||
_drawMeterHelper(disp, "0", "360", _calcMarkerPos(100, 500));
|
_drawMeterHelper(disp, "0", "360", _calcMarkerPos(fun_gen->phase, MAX_PHAS));
|
||||||
break;
|
break;
|
||||||
case LAY_MAIN:
|
case LAY_MAIN:
|
||||||
DISP_clearRegion(disp, 62, 13, 66, 40);
|
DISP_clearRegion(disp, 62, 13, 66, 40);
|
||||||
@@ -213,7 +217,7 @@ static void _drawFuncGenValues(GFX_display_t *disp, APP_data_t *app_data)
|
|||||||
|
|
||||||
static void _drawPwmGenValues(GFX_display_t *disp, APP_data_t *app_data)
|
static void _drawPwmGenValues(GFX_display_t *disp, APP_data_t *app_data)
|
||||||
{
|
{
|
||||||
GEN_pwm_t *pwm_gen = app_data->generator;
|
// GEN_pwm_t *pwm_gen = app_data->generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawValues(GFX_display_t *disp, APP_data_t *app_data)
|
static void _drawValues(GFX_display_t *disp, APP_data_t *app_data)
|
||||||
@@ -251,14 +255,14 @@ static void _drawOffsetLine(GFX_display_t *disp, int16_t offs, uint32_t ampl)
|
|||||||
DISP_drawHorizontalLine(disp, 2, 31 + offs_shift, 57, GFX_WHITE);
|
DISP_drawHorizontalLine(disp, 2, 31 + offs_shift, 57, GFX_WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawMaxAmpLine(GFX_display_t *disp, int16_t offs, uint32_t ampl)
|
// static void _drawMaxAmpLine(GFX_display_t *disp, int16_t offs, uint32_t ampl)
|
||||||
{
|
// {
|
||||||
DISP_drawHorizontalLine(disp, 2, 12, 57, GFX_WHITE);
|
// DISP_drawHorizontalLine(disp, 2, 12, 57, GFX_WHITE);
|
||||||
DISP_drawBitmap(disp, &marker_up, 0, 13, BM_NORMAL);
|
// DISP_drawBitmap(disp, &marker_up, 0, 13, BM_NORMAL);
|
||||||
|
|
||||||
DISP_drawHorizontalLine(disp, 2, 51, 57, GFX_WHITE);
|
// DISP_drawHorizontalLine(disp, 2, 51, 57, GFX_WHITE);
|
||||||
DISP_drawBitmap(disp, &marker_down, 0, 48, BM_NORMAL);
|
// DISP_drawBitmap(disp, &marker_down, 0, 48, BM_NORMAL);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static void _drawFunGenGraph(GFX_display_t *disp, APP_data_t *app_data)
|
static void _drawFunGenGraph(GFX_display_t *disp, APP_data_t *app_data)
|
||||||
{
|
{
|
||||||
|
|||||||
154
firmware/shared_libs/utils/ulog/ulog.c
Normal file
154
firmware/shared_libs/utils/ulog/ulog.c
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 R. Dunbar Poor <rdpoor@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file ulog.c
|
||||||
|
*
|
||||||
|
* \brief uLog: lightweight logging for embedded systems
|
||||||
|
*
|
||||||
|
* See ulog.h for sparse documentation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ulog.h"
|
||||||
|
|
||||||
|
#ifdef ULOG_ENABLED // whole file...
|
||||||
|
|
||||||
|
// #include <stdio.h>
|
||||||
|
#include "printf.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// types and definitions
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ulog_function_t fn;
|
||||||
|
ulog_level_t threshold;
|
||||||
|
} subscriber_t;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// local storage
|
||||||
|
|
||||||
|
static subscriber_t s_subscribers[ULOG_MAX_SUBSCRIBERS];
|
||||||
|
static char s_message[ULOG_MAX_MESSAGE_LENGTH];
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// user-visible code
|
||||||
|
|
||||||
|
void ulog_init()
|
||||||
|
{
|
||||||
|
memset(s_subscribers, 0, sizeof(s_subscribers));
|
||||||
|
}
|
||||||
|
|
||||||
|
// search the s_subscribers table to install or update fn
|
||||||
|
ulog_err_t ulog_subscribe(ulog_function_t fn, ulog_level_t threshold)
|
||||||
|
{
|
||||||
|
int available_slot = -1;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ULOG_MAX_SUBSCRIBERS; i++)
|
||||||
|
{
|
||||||
|
if (s_subscribers[i].fn == fn)
|
||||||
|
{
|
||||||
|
// already subscribed: update threshold and return immediately.
|
||||||
|
s_subscribers[i].threshold = threshold;
|
||||||
|
return ULOG_ERR_NONE;
|
||||||
|
}
|
||||||
|
else if (s_subscribers[i].fn == NULL)
|
||||||
|
{
|
||||||
|
// found a free slot
|
||||||
|
available_slot = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fn is not yet a subscriber. assign if possible.
|
||||||
|
if (available_slot == -1)
|
||||||
|
{
|
||||||
|
return ULOG_ERR_SUBSCRIBERS_EXCEEDED;
|
||||||
|
}
|
||||||
|
s_subscribers[available_slot].fn = fn;
|
||||||
|
s_subscribers[available_slot].threshold = threshold;
|
||||||
|
return ULOG_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search the s_subscribers table to remove
|
||||||
|
ulog_err_t ulog_unsubscribe(ulog_function_t fn)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ULOG_MAX_SUBSCRIBERS; i++)
|
||||||
|
{
|
||||||
|
if (s_subscribers[i].fn == fn)
|
||||||
|
{
|
||||||
|
s_subscribers[i].fn = NULL; // mark as empty
|
||||||
|
return ULOG_ERR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ULOG_ERR_NOT_SUBSCRIBED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ulog_level_name(ulog_level_t severity)
|
||||||
|
{
|
||||||
|
switch (severity)
|
||||||
|
{
|
||||||
|
case ULOG_TRACE_LEVEL:
|
||||||
|
return "TRACE";
|
||||||
|
case ULOG_DEBUG_LEVEL:
|
||||||
|
return "DEBUG";
|
||||||
|
case ULOG_INFO_LEVEL:
|
||||||
|
return "INFO";
|
||||||
|
case ULOG_WARNING_LEVEL:
|
||||||
|
return "WARNING";
|
||||||
|
case ULOG_ERROR_LEVEL:
|
||||||
|
return "ERROR";
|
||||||
|
case ULOG_CRITICAL_LEVEL:
|
||||||
|
return "CRITICAL";
|
||||||
|
case ULOG_ALWAYS_LEVEL:
|
||||||
|
return "ALWAYS";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ulog_message(ulog_level_t severity, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int i;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(s_message, ULOG_MAX_MESSAGE_LENGTH, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
for (i = 0; i < ULOG_MAX_SUBSCRIBERS; i++)
|
||||||
|
{
|
||||||
|
if (s_subscribers[i].fn != NULL)
|
||||||
|
{
|
||||||
|
if (severity >= s_subscribers[i].threshold)
|
||||||
|
{
|
||||||
|
s_subscribers[i].fn(severity, s_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// private code
|
||||||
|
|
||||||
|
#endif // #ifdef ULOG_ENABLED
|
||||||
188
firmware/shared_libs/utils/ulog/ulog.h
Normal file
188
firmware/shared_libs/utils/ulog/ulog.h
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/**
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 R. Dunbar Poor <rdpoor@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief uLog: lightweight logging for embedded systems
|
||||||
|
*
|
||||||
|
* A quick intro by example:
|
||||||
|
*
|
||||||
|
* #include "ulog.h"
|
||||||
|
*
|
||||||
|
* // To use uLog, you must define a function to process logging messages.
|
||||||
|
* // It can write the messages to a console, to a file, to an in-memory
|
||||||
|
* // buffer: the choice is yours. And you get to choose the format of
|
||||||
|
* // the message. This example prints to the console. One caveat: msg
|
||||||
|
* // is a static string and will be over-written at the next call to ULOG.
|
||||||
|
* // You may print it or copy it, but saving a pointer to it will lead to
|
||||||
|
* // confusion and astonishment.
|
||||||
|
* //
|
||||||
|
* void my_console_logger(ulog_level_t level, const char *msg) {
|
||||||
|
* printf("%s [%s]: %s\n",
|
||||||
|
* get_timestamp(),
|
||||||
|
* ulog_level_name(level),
|
||||||
|
* msg);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* int main() {
|
||||||
|
* ULOG_INIT();
|
||||||
|
*
|
||||||
|
* // log to the console messages that are WARNING or more severe. You
|
||||||
|
* // can re-subscribe at any point to change the severity level.
|
||||||
|
* ULOG_SUBSCRIBE(my_console_logger, ULOG_WARNING);
|
||||||
|
*
|
||||||
|
* // log to a file messages that are DEBUG or more severe
|
||||||
|
* ULOG_SUBSCRIBE(my_file_logger, ULOG_DEBUG);
|
||||||
|
*
|
||||||
|
* int arg = 42;
|
||||||
|
* ULOG_INFO("Arg is %d", arg); // logs to file but not console
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ULOG_H_
|
||||||
|
#define ULOG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ULOG_TRACE_LEVEL = 100,
|
||||||
|
ULOG_DEBUG_LEVEL,
|
||||||
|
ULOG_INFO_LEVEL,
|
||||||
|
ULOG_WARNING_LEVEL,
|
||||||
|
ULOG_ERROR_LEVEL,
|
||||||
|
ULOG_CRITICAL_LEVEL,
|
||||||
|
ULOG_ALWAYS_LEVEL
|
||||||
|
} ulog_level_t;
|
||||||
|
|
||||||
|
// The following macros enable or disable uLog. If `ULOG_ENABLED` is
|
||||||
|
// defined at compile time, a macro such as `ULOG_INFO(...)` expands
|
||||||
|
// into `ulog_message(ULOG_INFO_LEVEL, ...)`. If `ULOG_ENABLED` is not
|
||||||
|
// defined, then the same macro expands into `do {} while(0)` and will
|
||||||
|
// not generate any code at all.
|
||||||
|
//
|
||||||
|
// There are two ways to enable uLog: you can uncomment the following
|
||||||
|
// line, or -- if it is commented out -- you can add -DULOG_ENABLED to
|
||||||
|
// your compiler switches.
|
||||||
|
// #define ULOG_ENABLED
|
||||||
|
|
||||||
|
#ifdef ULOG_ENABLED
|
||||||
|
#define ULOG_INIT() ulog_init()
|
||||||
|
#define ULOG_SUBSCRIBE(a, b) ulog_subscribe(a, b)
|
||||||
|
#define ULOG_UNSUBSCRIBE(a) ulog_unsubscribe(a)
|
||||||
|
#define ULOG_LEVEL_NAME(a) ulog_level_name(a)
|
||||||
|
#define ULOG(...) ulog_message(__VA_ARGS__)
|
||||||
|
#define ULOG_TRACE(...) ulog_message(ULOG_TRACE_LEVEL, __VA_ARGS__)
|
||||||
|
#define ULOG_DEBUG(...) ulog_message(ULOG_DEBUG_LEVEL, __VA_ARGS__)
|
||||||
|
#define ULOG_INFO(...) ulog_message(ULOG_INFO_LEVEL, __VA_ARGS__)
|
||||||
|
#define ULOG_WARNING(...) ulog_message(ULOG_WARNING_LEVEL, __VA_ARGS__)
|
||||||
|
#define ULOG_ERROR(...) ulog_message(ULOG_ERROR_LEVEL, __VA_ARGS__)
|
||||||
|
#define ULOG_CRITICAL(...) ulog_message(ULOG_CRITICAL_LEVEL, __VA_ARGS__)
|
||||||
|
#define ULOG_ALWAYS(...) ulog_message(ULOG_ALWAYS_LEVEL, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
// uLog vanishes when disabled at compile time...
|
||||||
|
#define ULOG_INIT() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_SUBSCRIBE(a, b) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_UNSUBSCRIBE(a) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_LEVEL_NAME(a) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG(s, f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_TRACE(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_DEBUG(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_INFO(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_WARNING(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_ERROR(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_CRITICAL(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define ULOG_ALWAYS(f, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ULOG_ERR_NONE = 0,
|
||||||
|
ULOG_ERR_SUBSCRIBERS_EXCEEDED,
|
||||||
|
ULOG_ERR_NOT_SUBSCRIBED,
|
||||||
|
} ulog_err_t;
|
||||||
|
|
||||||
|
// define the maximum number of concurrent subscribers
|
||||||
|
#ifndef ULOG_MAX_SUBSCRIBERS
|
||||||
|
#define ULOG_MAX_SUBSCRIBERS 6
|
||||||
|
#endif
|
||||||
|
// maximum length of formatted log message
|
||||||
|
#ifndef ULOG_MAX_MESSAGE_LENGTH
|
||||||
|
#define ULOG_MAX_MESSAGE_LENGTH 120
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief: prototype for uLog subscribers.
|
||||||
|
*/
|
||||||
|
typedef void (*ulog_function_t)(ulog_level_t severity, char *msg);
|
||||||
|
|
||||||
|
void ulog_init(void);
|
||||||
|
ulog_err_t ulog_subscribe(ulog_function_t fn, ulog_level_t threshold);
|
||||||
|
ulog_err_t ulog_unsubscribe(ulog_function_t fn);
|
||||||
|
const char *ulog_level_name(ulog_level_t level);
|
||||||
|
void ulog_message(ulog_level_t severity, const char *fmt, ...);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ULOG_H_ */
|
||||||
Reference in New Issue
Block a user