diff --git a/CMakeLists.txt b/CMakeLists.txt index 568a4d2..8a0b85c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ else() # Add key include paths target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/dev + ${CMAKE_CURRENT_LIST_DIR}/examples ) # Compilation definition information diff --git a/dev/lwbtn_opts.h b/dev/lwbtn_opts.h index 4234c14..a3d8792 100644 --- a/dev/lwbtn_opts.h +++ b/dev/lwbtn_opts.h @@ -41,10 +41,4 @@ * copy & replace here settings you want to change values */ -/* Press config */ -#define LWBTN_CFG_TIME_DEBOUNCE_PRESS 20 /* No debounce for press event */ - -/* Release config */ -#define LWBTN_CFG_TIME_DEBOUNCE_RELEASE 20 /* No debounce for release event */ - #endif /* LWBTN_HDR_OPTS_H */ diff --git a/examples/LwBTN-NUCLEO-L011K4/.vscode/settings.json b/examples/LwBTN-NUCLEO-L011K4/.vscode/settings.json index 8bf0ebf..462a80f 100644 --- a/examples/LwBTN-NUCLEO-L011K4/.vscode/settings.json +++ b/examples/LwBTN-NUCLEO-L011K4/.vscode/settings.json @@ -2,6 +2,8 @@ "files.associations": { "lwbtn.h": "c", "lwbtn_opt.h": "c", - "lwbtn_opts.h": "c" + "lwbtn_opts.h": "c", + "main.h": "c", + "stm32l0xx_hal.h": "c" } } \ No newline at end of file diff --git a/examples/LwBTN-NUCLEO-L011K4/CMakeLists.txt b/examples/LwBTN-NUCLEO-L011K4/CMakeLists.txt index 8b23b14..c9185b0 100644 --- a/examples/LwBTN-NUCLEO-L011K4/CMakeLists.txt +++ b/examples/LwBTN-NUCLEO-L011K4/CMakeLists.txt @@ -28,7 +28,10 @@ set(cpu_PARAMS ) # Sources -set(sources_SRCS) +set(sources_SRCS + # Add test file + ${CMAKE_CURRENT_SOURCE_DIR}/../test.c +) # Include directories for each compiler set(include_c_DIRS) @@ -36,7 +39,10 @@ set(include_cxx_DIRS) set(include_asm_DIRS) # Symbols definition for each compiler -set(symbols_c_SYMB) +set(symbols_c_SYMB + "STM32" # Used for test macros + "RUN_TEST"# Defined to run the test +) set(symbols_cxx_SYMB) set(symbols_asm_SYMB) @@ -90,8 +96,8 @@ target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE target_link_libraries(${CMAKE_PROJECT_NAME} ${link_LIBS}) # Add LwBTN library itself -#add_subdirectory("../../lwbtn" lwbtn) -#target_link_libraries(${CMAKE_PROJECT_NAME} lwbtn) +add_subdirectory("../../lwbtn" lwbtn) +target_link_libraries(${CMAKE_PROJECT_NAME} lwbtn) # Compiler options target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE diff --git a/examples/LwBTN-NUCLEO-L011K4/Core/Inc/lwbtn_opts.h b/examples/LwBTN-NUCLEO-L011K4/Core/Inc/lwbtn_opts.h index 98dc778..a3d8792 100644 --- a/examples/LwBTN-NUCLEO-L011K4/Core/Inc/lwbtn_opts.h +++ b/examples/LwBTN-NUCLEO-L011K4/Core/Inc/lwbtn_opts.h @@ -41,10 +41,4 @@ * copy & replace here settings you want to change values */ -/* Press config */ -#define LWBTN_CFG_TIME_DEBOUNCE_PRESS 20 /* Debounce in ms for press */ - -/* Release config */ -#define LWBTN_CFG_TIME_DEBOUNCE_RELEASE 0 /* Debounce in ms for release */ - #endif /* LWBTN_HDR_OPTS_H */ diff --git a/examples/LwBTN-NUCLEO-L011K4/Core/Inc/main.h b/examples/LwBTN-NUCLEO-L011K4/Core/Inc/main.h index 5f040dc..6030939 100644 --- a/examples/LwBTN-NUCLEO-L011K4/Core/Inc/main.h +++ b/examples/LwBTN-NUCLEO-L011K4/Core/Inc/main.h @@ -57,10 +57,12 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ -#define BTN_Pin GPIO_PIN_12 -#define BTN_GPIO_Port GPIOA -#define OUT_Pin GPIO_PIN_3 -#define OUT_GPIO_Port GPIOB +#define BTN_Pin GPIO_PIN_12 +#define BTN_GPIO_Port GPIOA +#define OUT_Pin GPIO_PIN_3 +#define OUT_GPIO_Port GPIOB +#define OUT_CLICK_Pin GPIO_PIN_4 +#define OUT_CLICK_GPIO_Port GPIOB /* USER CODE BEGIN Private defines */ diff --git a/examples/LwBTN-NUCLEO-L011K4/Core/Src/main.c b/examples/LwBTN-NUCLEO-L011K4/Core/Src/main.c index b8277b8..8de6d78 100644 --- a/examples/LwBTN-NUCLEO-L011K4/Core/Src/main.c +++ b/examples/LwBTN-NUCLEO-L011K4/Core/Src/main.c @@ -18,41 +18,14 @@ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" -#define LWBTN_RUN 0 -#if LWBTN_RUN #include "lwbtn/lwbtn.h" -#endif /* LWBTN_RUN */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); -#if LWBTN_RUN -static lwbtn_btn_t btns[1]; /* Just one button */ - -/* Get state function */ -static uint8_t -prv_get_state(struct lwbtn* lwobj, struct lwbtn_btn* btn) { - /* It is just one button, so we can ignore btn check... - Button is "pressed" when low */ - return HAL_GPIO_ReadPin(BTN_GPIO_Port, BTN_Pin) == GPIO_PIN_RESET; -} - -/* Button event function */ -static void -prv_evt_fn(struct lwbtn* lwobj, struct lwbtn_btn* btn, lwbtn_evt_t evt) { - /* It is just one button, so we can ignore btn check... */ - switch (evt) { - case LWBTN_EVT_ONPRESS: - case LWBTN_EVT_ONRELEASE: { - HAL_GPIO_WritePin(OUT_GPIO_Port, OUT_Pin, evt == LWBTN_EVT_ONPRESS ? GPIO_PIN_SET : GPIO_PIN_RESET); - break; - } - default: - break; - } -} -#endif /* LWBTN_RUN */ +/* External test function */ +extern void test_stm32(void); /** * @brief The application entry point. @@ -69,18 +42,10 @@ main(void) { /* Initialize all configured peripherals */ MX_GPIO_Init(); - /* Initialize LwBTN library */ -#if LWBTN_RUN - lwbtn_init(btns, sizeof(btns) / sizeof(btns[0]), prv_get_state, prv_evt_fn); -#endif /* LWBTN_RUN */ + /* Run test program */ + test_stm32(); - /* Infinite loop */ - while (1) { -#if LWBTN_RUN - lwbtn_process(HAL_GetTick()); -#endif /* LWBTN_RUN */ - } - /* USER CODE END 3 */ + while (1) {} } /** @@ -92,13 +57,13 @@ SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - /** Configure the main internal regulator output voltage - */ + /* Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - /** Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ + /* + * Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; @@ -106,21 +71,16 @@ SystemClock_Config(void) { RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - Error_Handler(); - } + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {} - /** 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_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { - Error_Handler(); - } + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {} } /** @@ -140,11 +100,14 @@ MX_GPIO_Init(void) { /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(OUT_GPIO_Port, OUT_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(OUT_CLICK_GPIO_Port, OUT_CLICK_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(BTN_GPIO_Port, BTN_Pin, GPIO_PIN_RESET); - /*Configure GPIO pin : BTN_Pin */ + /* Configure GPIO pin : BTN_Pin */ GPIO_InitStruct.Pin = BTN_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(BTN_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : OUT_Pin */ @@ -154,40 +117,13 @@ MX_GPIO_Init(void) { GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(OUT_GPIO_Port, &GPIO_InitStruct); + /*Configure GPIO pin : OUT_CLICK_Pin */ + GPIO_InitStruct.Pin = OUT_CLICK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(OUT_CLICK_GPIO_Port, &GPIO_InitStruct); + /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } - -/* USER CODE BEGIN 4 */ - -/* USER CODE END 4 */ - -/** - * @brief This function is executed in case of error occurrence. - * @retval None - */ -void -Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) {} - /* USER CODE END Error_Handler_Debug */ -} - -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void -assert_failed(uint8_t* file, uint32_t line) { - /* USER CODE BEGIN 6 */ - /* 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) */ - /* USER CODE END 6 */ -} -#endif /* USE_FULL_ASSERT */ diff --git a/examples/test.c b/examples/test.c index dce14bb..56b0738 100644 --- a/examples/test.c +++ b/examples/test.c @@ -1,7 +1,13 @@ -#include "lwbtn/lwbtn.h" -#include "windows.h" #include #include +#include "test.h" +#if defined(WIN32) +#include "windows.h" +#endif /* defined(WIN32) */ +#if defined(STM32) +#include "stm32l0xx_hal.h" +#include "main.h" +#endif /* defined(STM32) */ /** * \brief Input state information @@ -24,10 +30,10 @@ typedef struct { #define MAX_TIME_MS 5000 /* Tests to run */ -#define TEST1 1 -#define TEST2 1 -#define TEST3 1 -#define TEST4 1 +#define TEST1 0 +#define TEST2 0 +#define TEST3 0 +#define TEST4 0 #define TEST5 1 /* List of used buttons -> test case */ @@ -219,30 +225,39 @@ prv_get_state_for_time(uint32_t time) { /* Get button state */ static uint8_t prv_btn_get_state(struct lwbtn* lw, struct lwbtn_btn* btn) { + uint8_t state = prv_get_state_for_time(time_current); + +#if defined(STM32) + HAL_GPIO_WritePin(BTN_GPIO_Port, BTN_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET); +#endif /* defined(STM32) */ + (void)btn; (void)lw; - return prv_get_state_for_time(time_current); + return state; } /* Process button event */ static void prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { +#if defined(WIN32) const char* s; uint32_t color, keepalive_cnt = 0, diff_time; - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); static uint32_t time_prev; static uint32_t array_index = 0; - const btn_test_evt_t* test_evt_data; + const btn_test_evt_t* test_evt_data = NULL; + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); /* Test errors variable */ uint32_t test_errors = 0; if (array_index >= sizeof(test_events) / sizeof(test_events[0])) { +#if defined(WIN32) SetConsoleTextAttribute(hConsole, FOREGROUND_RED); printf("[%7u] ERROR! Array index is out of bounds!\r\n", (unsigned)time_current); SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - return; +#endif /* defined(WIN32) */ + } else { + test_evt_data = &test_events[array_index]; } - test_evt_data = &test_events[array_index]; /* Handle timing */ diff_time = time_current - time_prev; @@ -252,7 +267,7 @@ prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { #endif /* Event type must match */ - test_errors += test_evt_data->evt != evt; + test_errors += test_evt_data == NULL || test_evt_data->evt != evt; /* Get event string */ if (0) { @@ -261,7 +276,7 @@ prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { s = "KEEPALIVE"; color = FOREGROUND_RED; - test_errors += test_evt_data->keepalive_cnt != keepalive_cnt; + test_errors += test_evt_data == NULL || test_evt_data->keepalive_cnt != keepalive_cnt; #endif /* LWBTN_CFG_USE_KEEPALIVE */ } else if (evt == LWBTN_EVT_ONPRESS) { s = " ONPRESS"; @@ -273,12 +288,14 @@ prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { } else if (evt == LWBTN_EVT_ONCLICK) { s = " ONCLICK"; color = FOREGROUND_RED | FOREGROUND_GREEN; + is_click = 1; - test_errors += test_evt_data->conseq_clicks != btn->click.cnt; + test_errors += test_evt_data == NULL || test_evt_data->conseq_clicks != btn->click.cnt; } else { s = " UNKNOWN"; color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; } + SetConsoleTextAttribute(hConsole, color); printf("[%7u][%6u] evt: %s, keep-alive cnt: %3u, click cnt: %3u\r\n", (unsigned)time_current, (unsigned)diff_time, s, (unsigned)keepalive_cnt, (unsigned)btn->click.cnt); @@ -286,11 +303,22 @@ prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { printf("TEST FAILED...\r\n"); } SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - (void)lw; - ++array_index; /* Go to next step in next event */ +#else + /* Control GPIO pin in STM32 */ + if (evt == LWBTN_EVT_ONPRESS) { + HAL_GPIO_WritePin(OUT_GPIO_Port, OUT_Pin, GPIO_PIN_SET); + } else if (evt == LWBTN_EVT_ONRELEASE) { + HAL_GPIO_WritePin(OUT_GPIO_Port, OUT_Pin, GPIO_PIN_RESET); + } else if (evt == LWBTN_EVT_ONCLICK) { + is_click = 1; + HAL_GPIO_WritePin(OUT_CLICK_GPIO_Port, OUT_CLICK_Pin, GPIO_PIN_SET); + } +#endif /* defined(WIN32) */ + (void)lw; } +#if defined(WIN32) /** * \brief Test function */ @@ -308,3 +336,35 @@ test_win32(void) { } return 0; } +#endif /* defined(WIN32) */ + +#if defined(STM32) + +int +test_stm32(void) { + uint32_t tick, tick_old = 0; + + /* Define buttons */ + lwbtn_init_ex(NULL, btns, sizeof(btns) / sizeof(btns[0]), prv_btn_get_state, prv_btn_event); + + /* Counter simulates ms tick */ + tick_old = 0; + for (size_t i = 0; i < MAX_TIME_MS; ++i) { + /* Wait for a tick to have real time data */ + while ((tick = HAL_GetTick()) == tick_old) {} + tick_old = tick; + + /* Reset from previous click event */ + if (is_click) { + HAL_GPIO_WritePin(OUT_CLICK_GPIO_Port, OUT_CLICK_Pin, GPIO_PIN_RESET); + is_click = 0; + } + + /* Set current tick time in ms */ + time_current = i; /* Set current time used in callback */ + lwbtn_process(i); /* Now run processing */ + } + return 0; +} + +#endif /* defined(STM32) */ diff --git a/examples/test.h b/examples/test.h new file mode 100644 index 0000000..769a612 --- /dev/null +++ b/examples/test.h @@ -0,0 +1,6 @@ +#ifndef TEST_HDR_H +#define TEST_HDR_H + +#include "lwbtn/lwbtn.h" + +#endif /* TEST_HDR_H */