123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 |
- /* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include "stdio.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "freertos/timers.h"
- #include "freertos/semphr.h"
- #include "freertos/event_groups.h"
- #include "esp_idf_version.h"
- #include "esp_log.h"
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- #include "esp_adc/adc_cali.h"
- #endif
- #include "unity.h"
- #include "iot_button.h"
- #include "sdkconfig.h"
- static const char *TAG = "BUTTON TEST";
- #define TEST_MEMORY_LEAK_THRESHOLD (-400)
- #define BUTTON_IO_NUM 0
- #define BUTTON_ACTIVE_LEVEL 0
- #define BUTTON_NUM 16
- #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
- #define ADC_BUTTON_WIDTH SOC_ADC_RTC_MAX_BITWIDTH
- #else
- #define ADC_BUTTON_WIDTH ADC_WIDTH_MAX - 1
- #endif
- static size_t before_free_8bit;
- static size_t before_free_32bit;
- static button_handle_t g_btns[BUTTON_NUM] = {0};
- static int get_btn_index(button_handle_t btn)
- {
- for (size_t i = 0; i < BUTTON_NUM; i++) {
- if (btn == g_btns[i]) {
- return i;
- }
- }
- return -1;
- }
- static void button_press_down_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_PRESS_DOWN, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_DOWN", get_btn_index((button_handle_t)arg));
- }
- static void button_press_up_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_PRESS_UP, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_UP[%d]", get_btn_index((button_handle_t)arg), iot_button_get_ticks_time((button_handle_t)arg));
- }
- static void button_press_repeat_cb(void *arg, void *data)
- {
- ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_REPEAT[%d]", get_btn_index((button_handle_t)arg), iot_button_get_repeat((button_handle_t)arg));
- }
- static void button_single_click_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_SINGLE_CLICK, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_SINGLE_CLICK", get_btn_index((button_handle_t)arg));
- }
- static void button_double_click_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_DOUBLE_CLICK, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_DOUBLE_CLICK", get_btn_index((button_handle_t)arg));
- }
- static void button_long_press_start_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_LONG_PRESS_START, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_LONG_PRESS_START", get_btn_index((button_handle_t)arg));
- }
- static void button_long_press_hold_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_LONG_PRESS_HOLD, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_LONG_PRESS_HOLD[%d],count is [%d]", get_btn_index((button_handle_t)arg), iot_button_get_ticks_time((button_handle_t)arg), iot_button_get_long_press_hold_cnt((button_handle_t)arg));
- }
- static void button_press_repeat_done_cb(void *arg, void *data)
- {
- TEST_ASSERT_EQUAL_HEX(BUTTON_PRESS_REPEAT_DONE, iot_button_get_event(arg));
- ESP_LOGI(TAG, "BTN%d: BUTTON_PRESS_REPEAT_DONE[%d]", get_btn_index((button_handle_t)arg), iot_button_get_repeat((button_handle_t)arg));
- }
- static esp_err_t custom_button_gpio_init(void *param)
- {
- button_gpio_config_t *cfg = (button_gpio_config_t *)param;
- return button_gpio_init(cfg);
- }
- static uint8_t custom_button_gpio_get_key_value(void *param)
- {
- button_gpio_config_t *cfg = (button_gpio_config_t *)param;
- return button_gpio_get_key_level((void *)cfg->gpio_num);
- }
- static esp_err_t custom_button_gpio_deinit(void *param)
- {
- button_gpio_config_t *cfg = (button_gpio_config_t *)param;
- return button_gpio_deinit(cfg->gpio_num);
- }
- TEST_CASE("custom button test", "[button][iot]")
- {
- button_gpio_config_t *gpio_cfg = calloc(1, sizeof(button_gpio_config_t));
- gpio_cfg->active_level = 0;
- gpio_cfg->gpio_num = 0;
- button_config_t cfg = {
- .type = BUTTON_TYPE_CUSTOM,
- .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
- .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
- .custom_button_config = {
- .button_custom_init = custom_button_gpio_init,
- .button_custom_deinit = custom_button_gpio_deinit,
- .button_custom_get_key_value = custom_button_gpio_get_key_value,
- .active_level = 0,
- .priv = gpio_cfg,
- },
- };
- g_btns[0] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[0]);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
- while (1) {
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- iot_button_delete(g_btns[0]);
- }
- TEST_CASE("gpio button test", "[button][iot]")
- {
- button_config_t cfg = {
- .type = BUTTON_TYPE_GPIO,
- .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
- .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
- .gpio_button_config = {
- .gpio_num = 0,
- .active_level = 0,
- },
- };
- g_btns[0] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[0]);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
- while (1) {
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- iot_button_delete(g_btns[0]);
- }
- TEST_CASE("gpio button test power save", "[button][iot][power save]")
- {
- button_config_t cfg = {
- .type = BUTTON_TYPE_GPIO,
- .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
- .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
- .gpio_button_config = {
- .gpio_num = 0,
- .active_level = 0,
- },
- };
- g_btns[0] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[0]);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
- iot_button_register_cb(g_btns[0], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
- TEST_ASSERT_EQUAL(ESP_OK, iot_button_stop());
- vTaskDelay(pdMS_TO_TICKS(1000));
- TEST_ASSERT_EQUAL(ESP_OK, iot_button_resume());
- while (1)
- {
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- iot_button_delete(g_btns[0]);
- }
- TEST_CASE("matrix keyboard button test","[button][matrix key]")
- {
- int32_t row_gpio[4] = {4,5,6,7};
- int32_t col_gpio[4] = {3,8,16,15};
- button_config_t cfg = {
- .type = BUTTON_TYPE_MATRIX,
- .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
- .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
- .matrix_button_config = {
- .row_gpio_num = 0,
- .col_gpio_num = 0,
- }
- };
- for (int i=0;i<4;i++){
- cfg.matrix_button_config.row_gpio_num = row_gpio[i];
- for (int j=0;j<4;j++) {
- cfg.matrix_button_config.col_gpio_num = col_gpio[j];
- g_btns[i*4+j] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[i*4+j]);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_PRESS_UP, button_press_up_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
- iot_button_register_cb(g_btns[i*4+j], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
- }
- }
- while (1)
- {
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- for (int i=0;i<4;i++){
- for (int j=0;j<4;j++) {
- iot_button_delete(g_btns[i*4+j]);
- }
- }
- }
- #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
- TEST_CASE("adc button test", "[button][iot]")
- {
- /** ESP32-S3-Korvo board */
- const uint16_t vol[6] = {380, 820, 1180, 1570, 1980, 2410};
- button_config_t cfg = {0};
- cfg.type = BUTTON_TYPE_ADC;
- cfg.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS;
- cfg.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS;
- for (size_t i = 0; i < 6; i++) {
- cfg.adc_button_config.adc_channel = 7,
- cfg.adc_button_config.button_index = i;
- if (i == 0) {
- cfg.adc_button_config.min = (0 + vol[i]) / 2;
- } else {
- cfg.adc_button_config.min = (vol[i - 1] + vol[i]) / 2;
- }
- if (i == 5) {
- cfg.adc_button_config.max = (vol[i] + 3000) / 2;
- } else {
- cfg.adc_button_config.max = (vol[i] + vol[i + 1]) / 2;
- }
- g_btns[i] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[i]);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_UP, button_press_up_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
- }
- while (1) {
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- for (size_t i = 0; i < 6; i++) {
- iot_button_delete(g_btns[i]);
- }
- }
- #else
- static esp_err_t adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle)
- {
- adc_cali_handle_t handle = NULL;
- esp_err_t ret = ESP_FAIL;
- bool calibrated = false;
- #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
- if (!calibrated) {
- ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting");
- adc_cali_curve_fitting_config_t cali_config = {
- .unit_id = unit,
- .atten = atten,
- .bitwidth = ADC_BUTTON_WIDTH,
- };
- ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
- if (ret == ESP_OK) {
- calibrated = true;
- }
- }
- #endif
- #if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
- if (!calibrated) {
- ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting");
- adc_cali_line_fitting_config_t cali_config = {
- .unit_id = unit,
- .atten = atten,
- .bitwidth = ADC_BUTTON_WIDTH,
- };
- ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
- if (ret == ESP_OK) {
- calibrated = true;
- }
- }
- #endif
- *out_handle = handle;
- if (ret == ESP_OK) {
- ESP_LOGI(TAG, "Calibration Success");
- } else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
- ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
- } else {
- ESP_LOGE(TAG, "Invalid arg or no memory");
- }
- return calibrated ? ESP_OK : ESP_FAIL;
- }
- TEST_CASE("adc button idf5 drive test", "[button][iot]")
- {
- adc_oneshot_unit_handle_t adc1_handle;
- adc_cali_handle_t adc1_cali_handle;
- adc_oneshot_unit_init_cfg_t init_config = {
- .unit_id = ADC_UNIT_1,
- };
- esp_err_t ret = adc_oneshot_new_unit(&init_config, &adc1_handle);
- TEST_ASSERT_TRUE(ret == ESP_OK);
- adc_calibration_init(ADC_UNIT_1, ADC_ATTEN_DB_11, &adc1_cali_handle);
- /** ESP32-S3-Korvo board */
- const uint16_t vol[6] = {380, 820, 1180, 1570, 1980, 2410};
- button_config_t cfg = {0};
- cfg.type = BUTTON_TYPE_ADC;
- cfg.long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS;
- cfg.short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS;
- for (size_t i = 0; i < 6; i++) {
- cfg.adc_button_config.adc_handle = &adc1_handle;
- cfg.adc_button_config.adc_channel = 7,
- cfg.adc_button_config.button_index = i;
- if (i == 0) {
- cfg.adc_button_config.min = (0 + vol[i]) / 2;
- } else {
- cfg.adc_button_config.min = (vol[i - 1] + vol[i]) / 2;
- }
- if (i == 5) {
- cfg.adc_button_config.max = (vol[i] + 3000) / 2;
- } else {
- cfg.adc_button_config.max = (vol[i] + vol[i + 1]) / 2;
- }
- g_btns[i] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[i]);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_DOWN, button_press_down_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_UP, button_press_up_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT, button_press_repeat_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_DOUBLE_CLICK, button_double_click_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_START, button_long_press_start_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_LONG_PRESS_HOLD, button_long_press_hold_cb, NULL);
- iot_button_register_cb(g_btns[i], BUTTON_PRESS_REPEAT_DONE, button_press_repeat_done_cb, NULL);
- }
- while (1) {
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- for (size_t i = 0; i < 6; i++) {
- iot_button_delete(g_btns[i]);
- }
- }
- #endif
- #define GPIO_OUTPUT_IO_45 45
- static EventGroupHandle_t g_check = NULL;
- static SemaphoreHandle_t g_auto_check_pass = NULL;
- static const char* button_event_str[BUTTON_EVENT_MAX] = {
- "BUTTON_PRESS_DOWN",
- "BUTTON_PRESS_UP",
- "BUTTON_PRESS_REPEAT",
- "BUTTON_PRESS_REPEAT_DONE",
- "BUTTON_SINGLE_CLICK",
- "BUTTON_DOUBLE_CLICK",
- "BUTTON_MULTIPLE_CLICK",
- "BUTTON_LONG_PRESS_START",
- "BUTTON_LONG_PRESS_HOLD",
- "BUTTON_LONG_PRESS_UP"
- };
- static button_event_t state = BUTTON_PRESS_DOWN;
- static void button_auto_press_test_task(void *arg)
- {
- // test BUTTON_PRESS_DOWN
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- // // test BUTTON_PRESS_UP
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(200));
- // test BUTTON_PRESS_REPEAT
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- // test BUTTON_PRESS_REPEAT_DONE
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(200));
- // test BUTTON_SINGLE_CLICK
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(200));
- // test BUTTON_DOUBLE_CLICK
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(200));
- // test BUTTON_MULTIPLE_CLICK
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- for (int i = 0; i < 4; i++) {
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- vTaskDelay(pdMS_TO_TICKS(100));
- // test BUTTON_LONG_PRESS_START
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(1600));
- // test BUTTON_LONG_PRESS_HOLD and BUTTON_LONG_PRESS_UP
- xEventGroupWaitBits(g_check, BIT(0) | BIT(1), pdTRUE, pdTRUE, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- ESP_LOGI(TAG, "Auto Press Success!");
- vTaskDelete(NULL);
- }
- static void button_auto_check_cb_1(void *arg, void *data)
- {
- if (iot_button_get_event(g_btns[0]) == state) {
- xEventGroupSetBits(g_check, BIT(1));
- }
- }
- static void button_auto_check_cb(void *arg, void *data)
- {
- if (iot_button_get_event(g_btns[0]) == state) {
- ESP_LOGI(TAG, "Auto check: button event %s pass", button_event_str[state]);
- xEventGroupSetBits(g_check, BIT(0));
- if (++state >= BUTTON_EVENT_MAX) {
- xSemaphoreGive(g_auto_check_pass);
- return;
- }
- }
- }
- TEST_CASE("gpio button auto-test", "[button][iot][auto]")
- {
- state = BUTTON_PRESS_DOWN;
- g_check = xEventGroupCreate();
- g_auto_check_pass = xSemaphoreCreateBinary();
- xEventGroupSetBits(g_check, BIT(0) | BIT(1));
- button_config_t cfg = {
- .type = BUTTON_TYPE_GPIO,
- .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
- .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
- .gpio_button_config = {
- .gpio_num = 0,
- .active_level = 0,
- },
- };
- g_btns[0] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[0]);
- /* register iot_button callback for all the button_event */
- for (uint8_t i = 0; i < BUTTON_EVENT_MAX; i++) {
- if (i == BUTTON_MULTIPLE_CLICK) {
- button_event_config_t btn_cfg;
- btn_cfg.event = i;
- btn_cfg.event_data.multiple_clicks.clicks = 4;
- iot_button_register_event_cb(g_btns[0], btn_cfg, button_auto_check_cb_1, NULL);
- iot_button_register_event_cb(g_btns[0], btn_cfg, button_auto_check_cb, NULL);
- } else {
- iot_button_register_cb(g_btns[0], i, button_auto_check_cb_1, NULL);
- iot_button_register_cb(g_btns[0], i, button_auto_check_cb, NULL);
- }
- }
- TEST_ASSERT_EQUAL(ESP_OK, iot_button_set_param(g_btns[0], BUTTON_LONG_PRESS_TIME_MS, (void *)1500));
- gpio_config_t io_conf = {
- .intr_type = GPIO_INTR_DISABLE,
- .mode = GPIO_MODE_OUTPUT,
- .pin_bit_mask = (1ULL << GPIO_OUTPUT_IO_45),
- .pull_down_en = 0,
- .pull_up_en = 0,
- };
- gpio_config(&io_conf);
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- xTaskCreate(button_auto_press_test_task, "button_auto_press_test_task", 1024 * 4, NULL, 10, NULL);
- TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(g_auto_check_pass, pdMS_TO_TICKS(6000)));
- for (uint8_t i = 0; i < BUTTON_EVENT_MAX; i++) {
- button_event_config_t btn_cfg;
- btn_cfg.event = i;
- if (i == BUTTON_MULTIPLE_CLICK) {
- btn_cfg.event_data.multiple_clicks.clicks = 4;
- } else if ( i == BUTTON_LONG_PRESS_UP || i == BUTTON_LONG_PRESS_START) {
- btn_cfg.event_data.long_press.press_time = 1500;
- }
- iot_button_unregister_event(g_btns[0], btn_cfg, button_auto_check_cb);
- iot_button_unregister_event(g_btns[0], btn_cfg, button_auto_check_cb_1);
- }
- TEST_ASSERT_EQUAL(ESP_OK,iot_button_delete(g_btns[0]));
- vEventGroupDelete(g_check);
- vSemaphoreDelete(g_auto_check_pass);
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- #define TOLERANCE CONFIG_BUTTON_LONG_PRESS_TOLERANCE_MS
- uint16_t long_press_time[5] = {2000, 2500, 3000, 3500, 4000};
- static SemaphoreHandle_t long_press_check = NULL;
- static SemaphoreHandle_t long_press_auto_check_pass = NULL;
- unsigned int status = 0;
- static void button_auto_long_press_test_task(void *arg)
- {
- // Test for BUTTON_LONG_PRESS_START
- for (int i = 0; i < 5; i++) {
- xSemaphoreTake(long_press_check, portMAX_DELAY);
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- status = (BUTTON_LONG_PRESS_START << 16) | long_press_time[i];
- if (i > 0)
- vTaskDelay(pdMS_TO_TICKS(long_press_time[i] - long_press_time[i - 1]));
- else
- vTaskDelay(pdMS_TO_TICKS(long_press_time[i]));
- }
- vTaskDelay(pdMS_TO_TICKS(100));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- xSemaphoreGive(long_press_auto_check_pass);
- vTaskDelay(pdMS_TO_TICKS(100));
- // Test for BUTTON_LONG_PRESS_UP
- for (int i = 0; i < 5; i++) {
- xSemaphoreTake(long_press_check, portMAX_DELAY);
- status = (BUTTON_LONG_PRESS_UP << 16) | long_press_time[i];
- gpio_set_level(GPIO_OUTPUT_IO_45, 0);
- vTaskDelay(pdMS_TO_TICKS(long_press_time[i] + 10));
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- }
- ESP_LOGI(TAG, "Auto Long Press Success!");
- vTaskDelete(NULL);
- }
- static void button_long_press_auto_check_cb(void *arg, void *data)
- {
- uint32_t value = (uint32_t)data;
- uint16_t event = (0xffff0000 & value) >> 16;
- uint16_t time = 0xffff & value;
- uint16_t ticks_time = iot_button_get_ticks_time(g_btns[0]);
- if (status == value && abs(ticks_time - time) <= TOLERANCE) {
- ESP_LOGI(TAG, "Auto check: button event: %s and time: %d pass", button_event_str[event], time);
- if (event == BUTTON_LONG_PRESS_UP && time == long_press_time[4]) {
- xSemaphoreGive(long_press_auto_check_pass);
- }
- xSemaphoreGive(long_press_check);
- }
- }
- TEST_CASE("gpio button long_press auto-test", "[button][long_press][auto]")
- {
- ESP_LOGI(TAG, "Starting the test");
- long_press_check = xSemaphoreCreateBinary();
- long_press_auto_check_pass = xSemaphoreCreateBinary();
- xSemaphoreGive(long_press_check);
- button_config_t cfg = {
- .type = BUTTON_TYPE_GPIO,
- .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
- .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
- .gpio_button_config = {
- .gpio_num = 0,
- .active_level = 0,
- },
- };
- g_btns[0] = iot_button_create(&cfg);
- TEST_ASSERT_NOT_NULL(g_btns[0]);
- button_event_config_t btn_cfg;
- btn_cfg.event = BUTTON_LONG_PRESS_START;
- for (int i = 0; i < 5; i++) {
- btn_cfg.event_data.long_press.press_time = long_press_time[i];
- uint32_t data = (btn_cfg.event << 16) | long_press_time[i];
- iot_button_register_event_cb(g_btns[0], btn_cfg, button_long_press_auto_check_cb, (void*)data);
- }
- gpio_config_t io_conf = {
- .intr_type = GPIO_INTR_DISABLE,
- .mode = GPIO_MODE_OUTPUT,
- .pin_bit_mask = (1ULL << GPIO_OUTPUT_IO_45),
- .pull_down_en = 0,
- .pull_up_en = 0,
- };
- gpio_config(&io_conf);
- gpio_set_level(GPIO_OUTPUT_IO_45, 1);
- xTaskCreate(button_auto_long_press_test_task, "button_auto_long_press_test_task", 1024 * 4, NULL, 10, NULL);
- xSemaphoreTake(long_press_auto_check_pass, portMAX_DELAY);
- iot_button_unregister_cb(g_btns[0], BUTTON_LONG_PRESS_START);
- btn_cfg.event = BUTTON_LONG_PRESS_UP;
- for (int i = 0; i < 5; i++) {
- btn_cfg.event_data.long_press.press_time = long_press_time[i];
- uint32_t data = (btn_cfg.event << 16) | long_press_time[i];
- iot_button_register_event_cb(g_btns[0], btn_cfg, button_long_press_auto_check_cb, (void*)data);
- }
- TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(long_press_auto_check_pass, pdMS_TO_TICKS(17000)));
- TEST_ASSERT_EQUAL(ESP_OK,iot_button_delete(g_btns[0]));
- vSemaphoreDelete(long_press_check);
- vSemaphoreDelete(long_press_auto_check_pass);
- vTaskDelay(pdMS_TO_TICKS(100));
- }
- static void check_leak(size_t before_free, size_t after_free, const char *type)
- {
- ssize_t delta = after_free - before_free;
- printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
- TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
- }
- void setUp(void)
- {
- before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
- before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
- }
- void tearDown(void)
- {
- size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
- size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
- check_leak(before_free_8bit, after_free_8bit, "8BIT");
- check_leak(before_free_32bit, after_free_32bit, "32BIT");
- }
- void app_main(void)
- {
- printf("USB STREAM TEST \n");
- unity_run_menu();
- }
|