diff --git a/components/badge23/captouch.c b/components/badge23/captouch.c index ae3da7c263b7a590ed38f37f57984b6e7c34fb7f..ffff6f214aedecb26e633f07c0f1140ea6eb7af0 100644 --- a/components/badge23/captouch.c +++ b/components/badge23/captouch.c @@ -4,6 +4,7 @@ #include "esp_log.h" #include "flow3r_bsp_captouch.h" +#include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" @@ -77,7 +78,11 @@ typedef struct { } st3m_captouch_petal_pad_t; typedef struct { +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + st3m_captouch_petal_pad_t tip; +#else st3m_captouch_petal_pad_t base; +#endif st3m_captouch_petal_pad_t cw; st3m_captouch_petal_pad_t ccw; bool pressed; @@ -112,12 +117,20 @@ static void _on_data(const flow3r_bsp_captouch_state_t *st) { xSemaphoreTake(_mu, portMAX_DELAY); memcpy(&_state, st, sizeof(flow3r_bsp_captouch_state_t)); for (size_t i = 0; i < 5; i++) { +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + _pad_feed(&_state.top[i].tip, _state.raw.petals[i * 2].tip.raw, true); +#else _pad_feed(&_state.top[i].base, _state.raw.petals[i * 2].base.raw, true); +#endif _pad_feed(&_state.top[i].cw, _state.raw.petals[i * 2].cw.raw, true); _pad_feed(&_state.top[i].ccw, _state.raw.petals[i * 2].ccw.raw, true); - _state.top[i].pressed = _state.top[i].base.pressed || - _state.top[i].cw.pressed || - _state.top[i].ccw.pressed; + _state.top[i].pressed = +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + _state.top[i].tip.pressed || +#else + _state.top[i].base.pressed || +#endif + _state.top[i].cw.pressed || _state.top[i].ccw.pressed; } for (size_t i = 0; i < 5; i++) { _pad_feed(&_state.bottom[i].base, _state.raw.petals[i * 2 + 1].base.raw, @@ -176,10 +189,18 @@ void read_captouch_ex(captouch_state_t *state) { memset(state, 0, sizeof(captouch_state_t)); xSemaphoreTake(_mu, portMAX_DELAY); for (size_t i = 0; i < 5; i++) { +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + bool base = _state.top[i].tip.pressed; +#else bool base = _state.top[i].base.pressed; +#endif bool cw = _state.top[i].cw.pressed; bool ccw = _state.top[i].ccw.pressed; +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + state->petals[i * 2].pads.tip_pressed = base; +#else state->petals[i * 2].pads.base_pressed = base; +#endif state->petals[i * 2].pads.cw_pressed = cw; state->petals[i * 2].pads.ccw_pressed = ccw; state->petals[i * 2].pressed = base || cw || ccw; @@ -244,6 +265,15 @@ int32_t captouch_get_petal_phi(uint8_t petal) { int32_t captouch_get_petal_rad(uint8_t petal) { bool top = (petal % 2) == 0; if (top) { +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + size_t ix = petal / 2; + xSemaphoreTake(_mu, portMAX_DELAY); + int32_t left = ringbuffer_avg(&_state.top[ix].ccw.rb); + int32_t right = ringbuffer_avg(&_state.top[ix].cw.rb); + int32_t tip = ringbuffer_avg(&_state.top[ix].tip.rb); + xSemaphoreGive(_mu); + return tip - (left + right) / 2; +#else size_t ix = petal / 2; xSemaphoreTake(_mu, portMAX_DELAY); int32_t left = ringbuffer_avg(&_state.top[ix].ccw.rb); @@ -251,6 +281,7 @@ int32_t captouch_get_petal_rad(uint8_t petal) { int32_t base = ringbuffer_avg(&_state.top[ix].base.rb); xSemaphoreGive(_mu); return (left + right) / 2 - base; +#endif } else { size_t ix = (petal - 1) / 2; xSemaphoreTake(_mu, portMAX_DELAY); diff --git a/components/flow3r_bsp/flow3r_bsp_captouch.c b/components/flow3r_bsp/flow3r_bsp_captouch.c index 1246bebbb27d5766c8136caead1d2af024b76797..146b66e84c6f7983e4d8f5a9fac03f0913158506 100644 --- a/components/flow3r_bsp/flow3r_bsp_captouch.c +++ b/components/flow3r_bsp/flow3r_bsp_captouch.c @@ -17,6 +17,45 @@ typedef struct { petal_kind_t pad_kind; } pad_mapping_t; +#if defined(CONFIG_FLOW3R_HW_GEN_P3) +static const pad_mapping_t _map_top[12] = { + { 0, petal_pad_tip }, // 0 + { 0, petal_pad_ccw }, // 1 + { 0, petal_pad_cw }, // 2 + { 2, petal_pad_cw }, // 3 + { 2, petal_pad_ccw }, // 4 + { 2, petal_pad_tip }, // 5 + { 6, petal_pad_tip }, // 6 + { 6, petal_pad_ccw }, // 7 + { 6, petal_pad_cw }, // 8 + { 4, petal_pad_cw }, // 9 + { 4, petal_pad_ccw }, // 10 + { 4, petal_pad_tip }, // 11 +}; +static const pad_mapping_t _map_bot[13] = { + { 1, petal_pad_base }, // 0 + { 1, petal_pad_tip }, // 1 + + { 3, petal_pad_base }, // 2 + { 3, petal_pad_tip }, // 3 + + { 5, petal_pad_base }, // 4 + { 5, petal_pad_tip }, // 5 + + { 7, petal_pad_tip }, // 6 + { 7, petal_pad_base }, // 7 + + { 9, petal_pad_tip }, // 8 + { 9, petal_pad_base }, // 9 + + { 8, petal_pad_tip }, // 10 + { 8, petal_pad_cw }, // 11 + { 8, petal_pad_ccw }, // 12 +}; +static gpio_num_t _interrupt_gpio_top = GPIO_NUM_15; +static gpio_num_t _interrupt_gpio_bot = GPIO_NUM_15; +static bool _interrupt_shared = true; +#elif defined(CONFIG_FLOW3R_HW_GEN_P4) || defined(CONFIG_FLOW3R_HW_GEN_P6) static const pad_mapping_t _map_top[12] = { { 0, petal_pad_ccw }, // 0 { 0, petal_pad_base }, // 1 @@ -31,21 +70,6 @@ static const pad_mapping_t _map_top[12] = { { 4, petal_pad_base }, // 10 { 4, petal_pad_cw }, // 11 }; - -static ad7147_chip_t _top = { - .name = "top", - .nchannels = 12, - .sequences = { - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - }, - { - -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, - }, - }, -}; - static const pad_mapping_t _map_bot[13] = { { 1, petal_pad_base }, // 0 { 1, petal_pad_tip }, // 1 @@ -66,6 +90,33 @@ static const pad_mapping_t _map_bot[13] = { { 8, petal_pad_cw }, // 11 { 8, petal_pad_base }, // 12 }; +#if defined(CONFIG_FLOW3R_HW_GEN_P4) +static gpio_num_t _interrupt_gpio_top = GPIO_NUM_15; +static gpio_num_t _interrupt_gpio_bot = GPIO_NUM_15; +static bool _interrupt_shared = true; +#else +static gpio_num_t _interrupt_gpio_top = GPIO_NUM_15; +static gpio_num_t _interrupt_gpio_bot = GPIO_NUM_16; +static bool _interrupt_shared = false; +#endif + +#else +#error "captouch not implemented for this badge generation" +#endif + +static ad7147_chip_t _top = { + .name = "top", + .nchannels = 12, + .sequences = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + }, + { + -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, + }, + }, +}; static ad7147_chip_t _bot = { .name = "bot", @@ -109,9 +160,6 @@ static ad7147_chip_t _bot = { }, }; -static gpio_num_t _interrupt_gpio_top = GPIO_NUM_15; -static gpio_num_t _interrupt_gpio_bot = GPIO_NUM_16; - static flow3r_bsp_captouch_callback_t _callback = NULL; static flow3r_bsp_captouch_state_t _state = {}; @@ -168,6 +216,14 @@ static void _task(void *data) { ESP_LOGE(TAG, "Queue receive failed"); return; } + bool top = !bot; + + if (_interrupt_shared) { + // No way to know which captouch chip triggered the interrupt, so + // process both. + top = true; + bot = true; + } if (bot) { if ((ret = flow3r_bsp_ad7147_chip_process(&_bot)) != ESP_OK) { @@ -181,7 +237,8 @@ static void _task(void *data) { } else { bot_ok = true; } - } else { + } + if (top) { if ((ret = flow3r_bsp_ad7147_chip_process(&_top)) != ESP_OK) { if (top_ok) { ESP_LOGE(TAG, @@ -265,10 +322,14 @@ esp_err_t flow3r_bsp_captouch_init(flow3r_bsp_captouch_callback_t callback) { ESP_LOGE(TAG, "Failed to add bottom captouch ISR"); return ret; } - if ((ret = _gpio_interrupt_setup(_interrupt_gpio_top, _top_isr)) != - ESP_OK) { - ESP_LOGE(TAG, "Failed to add top captouch ISR"); - return ret; + if (!_interrupt_shared) { + // On badges with shared interrupts, only install the 'bot' ISR as a + // shared ISR. + if ((ret = _gpio_interrupt_setup(_interrupt_gpio_top, _top_isr)) != + ESP_OK) { + ESP_LOGE(TAG, "Failed to add top captouch ISR"); + return ret; + } } xTaskCreate(&_task, "captouch", 4096, NULL, configMAX_PRIORITIES - 1, NULL);