diff --git a/components/badge23/CMakeLists.txt b/components/badge23/CMakeLists.txt index 8f910586a2827a8b6a586bdbef80778c6da61e23..02bcc745a35a2448901b68ab713a63cb29ba5ea9 100644 --- a/components/badge23/CMakeLists.txt +++ b/components/badge23/CMakeLists.txt @@ -1,8 +1,2 @@ idf_component_register( - SRCS - captouch.c - INCLUDE_DIRS - include - REQUIRES - flow3r_bsp ) diff --git a/components/badge23/captouch.c b/components/badge23/captouch.c deleted file mode 100644 index ffff6f214aedecb26e633f07c0f1140ea6eb7af0..0000000000000000000000000000000000000000 --- a/components/badge23/captouch.c +++ /dev/null @@ -1,293 +0,0 @@ -#include "badge23/captouch.h" - -#include "esp_err.h" -#include "esp_log.h" - -#include "flow3r_bsp_captouch.h" -#include "sdkconfig.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/task.h" - -#include <string.h> - -static const char *TAG = "st3m-captouch"; - -// A simple, non-concurrent ringbuffer. I feel like I've already implemented -// this once in this codebase. -// -// TODO(q3k): unify/expose as common st3m API. -typedef struct { - size_t write_ix; - bool wrapped; - uint16_t buf[4]; -} ringbuffer_t; - -// Size of ringbuffer, in elements. -static inline size_t ringbuffer_size(const ringbuffer_t *rb) { - return sizeof(rb->buf) / sizeof(uint16_t); -} - -// Write to ringbuffer. -static void ringbuffer_write(ringbuffer_t *rb, uint16_t data) { - rb->buf[rb->write_ix] = data; - rb->write_ix++; - if (rb->write_ix >= ringbuffer_size(rb)) { - rb->write_ix = 0; - rb->wrapped = true; - } -} - -// Get ringbuffer average (mean), or 0 if no values have yet been inserted. -static uint16_t ringbuffer_avg(const ringbuffer_t *rb) { - int32_t res = 0; - if (rb->wrapped) { - for (size_t i = 0; i < ringbuffer_size(rb); i++) { - res += rb->buf[i]; - } - res /= ringbuffer_size(rb); - return res; - } - if (rb->write_ix == 0) { - return 0; - } - for (size_t i = 0; i < rb->write_ix; i++) { - res += rb->buf[i]; - } - res /= rb->write_ix; - return res; -} - -// Get last inserted value, or 0 if no value have yet been inserted. -static uint16_t ringbuffer_last(const ringbuffer_t *rb) { - if (rb->write_ix == 0) { - if (rb->wrapped) { - return rb->buf[ringbuffer_size(rb) - 1]; - } - return 0; - } - return rb->buf[rb->write_ix - 1]; -} - -// TODO(q3k): expose these as user structs? - -typedef struct { - ringbuffer_t rb; - bool pressed; -} 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; -} st3m_captouch_petal_top_t; - -typedef struct { - st3m_captouch_petal_pad_t base; - st3m_captouch_petal_pad_t tip; - bool pressed; -} st3m_captouch_petal_bottom_t; - -typedef struct { - flow3r_bsp_captouch_state_t raw; - - st3m_captouch_petal_top_t top[5]; - st3m_captouch_petal_bottom_t bottom[5]; -} st3m_captouch_state_t; - -static SemaphoreHandle_t _mu = NULL; -static st3m_captouch_state_t _state = {}; -static bool _request_calibration = false; -static bool _calibrating = false; - -static inline void _pad_feed(st3m_captouch_petal_pad_t *pad, uint16_t data, - bool top) { - ringbuffer_write(&pad->rb, data); - int32_t thres = top ? 8000 : 12000; - pad->pressed = data > thres; -} - -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 = -#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, - false); - _pad_feed(&_state.bottom[i].tip, _state.raw.petals[i * 2 + 1].tip.raw, - false); - _state.bottom[i].pressed = - _state.bottom[i].base.pressed || _state.bottom[i].tip.pressed; - } - if (_request_calibration) { - _request_calibration = false; - flow3r_bsp_captouch_calibrate(); - } - _calibrating = flow3r_bsp_captouch_calibrating(); - xSemaphoreGive(_mu); -} - -void captouch_init(void) { - assert(_mu == NULL); - _mu = xSemaphoreCreateMutex(); - assert(_mu != NULL); - - esp_err_t ret = flow3r_bsp_captouch_init(_on_data); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Captouch init failed: %s", esp_err_to_name(ret)); - } -} - -void captouch_print_debug_info(void) { - // Deprecated no-op, will be removed. -} - -void captouch_read_cycle(void) { - // Deprecated no-op, will be removed. - // (now handled by interrupt) -} - -void captouch_set_calibration_afe_target(uint16_t target) { - // Deprecated no-op, will be removed. -} - -void captouch_force_calibration() { - xSemaphoreTake(_mu, portMAX_DELAY); - _request_calibration = true; - xSemaphoreGive(_mu); -} - -uint8_t captouch_calibration_active() { - xSemaphoreTake(_mu, portMAX_DELAY); - bool res = _calibrating || _request_calibration; - xSemaphoreGive(_mu); - return res; -} - -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; - } - for (size_t i = 0; i < 5; i++) { - bool base = _state.bottom[i].base.pressed; - bool tip = _state.bottom[i].tip.pressed; - state->petals[i * 2 + 1].pads.base_pressed = base; - state->petals[i * 2 + 1].pads.tip_pressed = tip; - state->petals[i * 2 + 1].pressed = base || tip; - } - xSemaphoreGive(_mu); -} - -uint16_t read_captouch(void) { - xSemaphoreTake(_mu, portMAX_DELAY); - uint16_t res = 0; - for (size_t i = 0; i < 5; i++) { - if (_state.top[i].pressed) res |= (1 << (i * 2)); - } - for (size_t i = 0; i < 5; i++) { - if (_state.bottom[i].pressed) res |= (1 << (i * 2 + 1)); - } - xSemaphoreGive(_mu); - return res; -} - -void captouch_set_petal_pad_threshold(uint8_t petal, uint8_t pad, - uint16_t thres) { - // Deprecated no-op, will be removed. -} - -uint16_t captouch_get_petal_pad_raw(uint8_t petal, uint8_t pad) { - // Deprecated no-op, will be removed. - return 0; -} - -uint16_t captouch_get_petal_pad_calib_ref(uint8_t petal, uint8_t pad) { - // Deprecated no-op, will be removed. - return 0; -} - -uint16_t captouch_get_petal_pad(uint8_t petal, uint8_t pad) { - // Deprecated no-op, will be removed. - return 0; -} - -int32_t captouch_get_petal_phi(uint8_t petal) { - bool top = (petal % 2) == 0; - if (top) { - 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); - xSemaphoreGive(_mu); - return left - right; - } else { - return 0; - } -} - -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); - int32_t right = ringbuffer_avg(&_state.top[ix].cw.rb); - 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); - int32_t tip = ringbuffer_avg(&_state.bottom[ix].tip.rb); - int32_t base = ringbuffer_avg(&_state.bottom[ix].base.rb); - xSemaphoreGive(_mu); - return tip - base; - } -} diff --git a/components/badge23/include/badge23/captouch.h b/components/badge23/include/badge23/captouch.h deleted file mode 100644 index d25e5ae85d2dd20787a5d45b18ddd0af516cda9f..0000000000000000000000000000000000000000 --- a/components/badge23/include/badge23/captouch.h +++ /dev/null @@ -1,162 +0,0 @@ -#pragma once -#include <stdbool.h> -#include <stdint.h> - -/* GENERAL INFORMATION - * - * petal index: 0 is the top petal above the USB-C jack, increases ccw so - * that bottom petals are uneven and top petals even. - * TODO: LEDs are indexed differently, this should be - * harmonized in the impending API refactor. - * - * captouch data: full uint16_t range per stage, higher values indicate touch. - * pad index: defined in captouch.c - * - * - * IOU: the internals are still subject to major restructuring and are not - * documented as of yet. will do once the data structures actually make sense - * and are not duct tape upon duct tape. - */ - -/* polls data from both captouch chips and processes it, either by updating - * the captouch data exposed to the user or running a calibration cycle. - * - * the captouch chips has updated their registers every 9.2ms, so the fn - * should be called every 10ms or so. - * - * this will be replaced someday by an interrupt event triggered system, - * but this would ideally already implement configuration switching to - * optimize latency by grouping pads and to expose the unused pad which - * is a nontrivial task for another day. - */ -void captouch_read_cycle(void); - -/* the captouch chip can generate an "afe" offset in the analog domain before - * the ADC to optimize the readout range. according to the datasheet this should - * be in the middle of the 16bit delta sigma ADC range (without much reasoning - * supplied), however we found that having a higher range is beneficial. - * - * the calibration cycle is optimizing the afe coefficients so that the output - * of the "untouched" pads is close to the target set with this with this - * function/ - * - * default target: 6000, manufacturer recommendation: 32676 - */ -void captouch_set_calibration_afe_target(uint16_t target); - -/* starts a a calibration cycle which is intended to run when the captouch - * pads are not being touched. the cycle consists of two parts: - * - * 1) optimize the afe coefficients (see captouch_set_calibration_afe_target) - * - * 2) with the new afe coefficients applied, average the readings in the - * untouched state into a software calibration list which is normally - * subtracted from the captouch outputs. this makes up for the limited - * resolution of the of the afe coefficient calibration. - */ -void captouch_force_calibration(); - -/* indicates if a calibration cycle is currently active. the readings for - * captouch_read_cycle and captouch_get_petal_* during a calibration cycle. - * - * 1: calibration cycle active - * 0: calibration cycle inactive - */ -uint8_t captouch_calibration_active(); - -typedef struct { - // Not all pads are present on all petals. - // Top petals have a base, cw and ccw pad. - // Bottom petlas have a base and a tip. - - // Is the tip pressed down? - bool tip_pressed; - // Is the base pressed down? - bool base_pressed; - // Is the clockwise pad pressed down? - bool cw_pressed; - // Is the counter-clockwise pad pressed down? - bool ccw_pressed; -} captouch_pad_state_t; - -typedef struct { - captouch_pad_state_t pads; - // Are any of the pads pressed down? - bool pressed; -} captouch_petal_state_t; - -typedef struct { - captouch_petal_state_t petals[10]; -} captouch_state_t; - -/* Extened/new API for reading captouch state. Allows for access to individual - * pad data. - * - * Likely to evolce into the new st3m api for captouch. - */ -void read_captouch_ex(captouch_state_t *state); - -/* returns uint16_t which encodes each petal "touched" state as the bit - * corresponding to the petal index. "touched" is determined by checking if - * any of the pads belonging to the petal read a value higher than their - * calibration value plus their threshold (see captouch_set_petal_pad_threshold) - */ -uint16_t read_captouch(void); - -/* sets threshold for a petal pad above which read_captouch considers a pad as - * touched. - * - * petal: petal index - * pad: pad index - * thres: threshold value - */ -void captouch_set_petal_pad_threshold(uint8_t petal, uint8_t pad, - uint16_t thres); - -/* returns last read captouch value from a petal pad without subtracting its - * calibration reference. typically only needed for debugging. - * - * petal: petal index - * pad: pad index - */ -uint16_t captouch_get_petal_pad_raw(uint8_t petal, uint8_t pad); - -/* returns calibration reference for a petal pad. - * - * petal: petal index - * pad: pad index - */ -uint16_t captouch_get_petal_pad_calib_ref(uint8_t petal, uint8_t pad); - -/* returns calibrated value from petal. clamps below 0. - * - * petal: petal index - * pad: pad index - */ -uint16_t captouch_get_petal_pad(uint8_t petal, uint8_t pad); - -/* estimates the azimuthal finger position on a petal in arbitrary units. - * returns 0 if hardware doesn't support this. - * - * petal: petal index - * pad: pad index - */ -int32_t captouch_get_petal_phi(uint8_t petal); - -/* estimates the radial finger position on a petal in arbitrary units. - * returns 0 if hardware doesn't support this. - * - * petal: petal index - * pad: pad index - */ -int32_t captouch_get_petal_rad(uint8_t petal); - -/* configures the captouch chips, prefills internal structs etc. - */ -void captouch_init(void); - -/* TODO: didn't look into what it does, never used it, just copied it from - * the hardware verification firmware along with the rest. didn't break it - * _intentionally_ but never tested it either. - */ -void captouch_print_debug_info(void); diff --git a/components/st3m/CMakeLists.txt b/components/st3m/CMakeLists.txt index c894750319ebf70e23a392867b86ca6fcc3a51f7..4b8d4f8d3a1f7f034e9fc9a011a6e32bc135566c 100644 --- a/components/st3m/CMakeLists.txt +++ b/components/st3m/CMakeLists.txt @@ -15,6 +15,8 @@ idf_component_register( st3m_usb.c st3m_console.c st3m_mode.c + st3m_captouch.c + st3m_ringbuffer.c INCLUDE_DIRS . REQUIRES diff --git a/components/st3m/st3m_board_startup.c b/components/st3m/st3m_board_startup.c index 808e9d7ea0cea3abc33a8ccb364fd0428e21e819..659c7719552cda346532d60677bcd3dd5b644586 100644 --- a/components/st3m/st3m_board_startup.c +++ b/components/st3m/st3m_board_startup.c @@ -1,6 +1,7 @@ #include "bl00mbox.h" #include "flow3r_bsp.h" #include "st3m_audio.h" +#include "st3m_captouch.h" #include "st3m_console.h" #include "st3m_fs.h" #include "st3m_gfx.h" @@ -67,6 +68,7 @@ void st3m_board_startup(void) { st3m_mode_update_display(NULL); st3m_leds_init(); st3m_io_init(); + st3m_captouch_init(); st3m_mode_set(st3m_mode_kind_starting, "micropython"); st3m_mode_update_display(NULL); diff --git a/components/st3m/st3m_captouch.c b/components/st3m/st3m_captouch.c new file mode 100644 index 0000000000000000000000000000000000000000..bf25555aa4af91f14205e95197c01127235c6332 --- /dev/null +++ b/components/st3m/st3m_captouch.c @@ -0,0 +1,118 @@ +#include "st3m_captouch.h" + +#include "esp_err.h" +#include "esp_log.h" + +#include "flow3r_bsp_captouch.h" +#include "sdkconfig.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" + +#include <string.h> + +static const char *TAG = "st3m-captouch"; + +static SemaphoreHandle_t _mu = NULL; +static st3m_captouch_state_t _state = {}; +static bool _request_calibration = false; +static bool _calibrating = false; + +static inline void _pad_feed(st3m_petal_pad_state_t *pad, uint16_t data, + bool top) { + ringbuffer_write(&pad->rb, data); + int32_t thres = top ? 8000 : 12000; + pad->pressed = data > thres; +} + +static inline void _petal_process(st3m_petal_state_t *petal, bool top) { + if (top) { + petal->pressed = + petal->base.pressed || petal->ccw.pressed || petal->cw.pressed; + int32_t left = ringbuffer_avg(&petal->ccw.rb); + int32_t right = ringbuffer_avg(&petal->cw.rb); + int32_t base = ringbuffer_avg(&petal->base.rb); + petal->pos_distance = (left + right) / 2 - base; + petal->pos_angle = left - right; +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + petal->pos_distance = -petal->pos_distance; +#endif + } else { + petal->pressed = petal->base.pressed || petal->tip.pressed; + int32_t base = ringbuffer_avg(&petal->base.rb); + int32_t tip = ringbuffer_avg(&petal->tip.rb); + petal->pos_distance = tip - base; + petal->pos_angle = 0; + } +} + +static void _on_data(const flow3r_bsp_captouch_state_t *st) { + xSemaphoreTake(_mu, portMAX_DELAY); + + for (size_t ix = 0; ix < 10; ix++) { + bool top = (ix % 2) == 0; + + if (top) { +#if defined(CONFIG_FLOW3R_HW_GEN_P3) + // Hack for P3 badges, pretend tip is base. + _pad_feed(&_state.petals[ix].base, st->petals[ix].tip.raw, true); +#else + _pad_feed(&_state.petals[ix].base, st->petals[ix].base.raw, true); +#endif + _pad_feed(&_state.petals[ix].cw, st->petals[ix].cw.raw, true); + _pad_feed(&_state.petals[ix].ccw, st->petals[ix].ccw.raw, true); + _petal_process(&_state.petals[ix], true); + } else { + _pad_feed(&_state.petals[ix].base, st->petals[ix].base.raw, false); + _pad_feed(&_state.petals[ix].tip, st->petals[ix].tip.raw, false); + _petal_process(&_state.petals[ix], false); + } + } + + if (_request_calibration) { + _request_calibration = false; + flow3r_bsp_captouch_calibrate(); + } + _calibrating = flow3r_bsp_captouch_calibrating(); + xSemaphoreGive(_mu); +} + +void st3m_captouch_init(void) { + assert(_mu == NULL); + _mu = xSemaphoreCreateMutex(); + assert(_mu != NULL); + + esp_err_t ret = flow3r_bsp_captouch_init(_on_data); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Captouch init failed: %s", esp_err_to_name(ret)); + } +} + +bool st3m_captouch_calibrating(void) { + xSemaphoreTake(_mu, portMAX_DELAY); + bool res = _calibrating || _request_calibration; + xSemaphoreGive(_mu); + return res; +} + +void st3m_captouch_request_calibration(void) { + xSemaphoreTake(_mu, portMAX_DELAY); + _request_calibration = true; + xSemaphoreGive(_mu); +} + +void st3m_captouch_get_all(st3m_captouch_state_t *dest) { + xSemaphoreTake(_mu, portMAX_DELAY); + memcpy(dest, &_state, sizeof(_state)); + xSemaphoreGive(_mu); +} + +void st3m_captouch_get_petal(st3m_petal_state_t *dest, uint8_t petal_ix) { + if (petal_ix > 9) { + petal_ix = 9; + } + xSemaphoreTake(_mu, portMAX_DELAY); + memcpy(dest, &_state.petals[petal_ix], sizeof(_state.petals[petal_ix])); + xSemaphoreGive(_mu); +} \ No newline at end of file diff --git a/components/st3m/st3m_captouch.h b/components/st3m/st3m_captouch.h new file mode 100644 index 0000000000000000000000000000000000000000..9c1184da3a9ddcaf24f8e0753ff56d4d64d84a1b --- /dev/null +++ b/components/st3m/st3m_captouch.h @@ -0,0 +1,112 @@ +#pragma once + +// GENERAL INFORMATION +// +// Geometry: +// +// The badge has 10 petals, 5 top petals (on the top PCB) and 5 bottom petals +// (on the bottom PCB). Each petal is made up of pads. Top petals have 3 pads, +// bottom petals have 2 pads. +// +// Every pad on a petal has a kind. The kind infidicates the relative position +// of the pad within the petal. +// +// tip: pad closest to the outside of the badge +// base: pad closest to the inside of the badge +// cw: pad going clockwise around the badge +// ccw: pad going counter-clockwise around the badge +// +// Top petals have base, cw, ccw pads. Bottom petals have tip, base pads. +// +// NOTE: if you have a 'proto3' badge, it has a slightly different top petal +// layout (tip, cw, ccw). This API pretends base == tip in this case. +// +// Petals are numbered. 0 is the top petal above the USB-C jack, increases +// counter-clockwise so that bottom petals are uneven and top petals even. +// +// Processing: +// +// Every time new capacitive touch data is available, a 'raw' value is extracted +// for each pad. This value is then used to calcualte the following information: +// +// 1. Per-pad touch: if the raw value exceeds some threshold, the pad is +// considered to be touched. +// 2. Per-petal touch: if any of a pad's petals is considered to be touched, +// the petal is also considered to be touched. +// 3. Per-petal position: petals allow for estimting a polar coordinate of +// touch. Top petals have two degrees of freedom, bottom petals have a +// single degree of freedom (distance from center). + +#include "st3m_ringbuffer.h" + +// NOTE: keep the enum definitions below in-sync with flow3r_bsp_captouch.h, as +// they are converted by numerical value internally. + +// One of the four possible touch points (pads) on a petal. Top petals have +// base/cw/ccw. Bottom petals have base/tip. +typedef enum { + // Pad away from centre of badge. + st3m_petal_pad_tip = 0, + // Pad going counter-clockwise around the badge. + st3m_petal_pad_ccw = 1, + // Pad going clockwise around the badge. + st3m_petal_pad_cw = 2, + // Pad going towards the centre of the badge. + st3m_petal_pad_base = 3, +} st3m_petal_pad_kind_t; + +// Each petal can be either top or bottom (that is, on the bottom PCB or top +// PCB). +typedef enum { + // Petal on the top layer. Has base, cw, ccw pads. + st3m_petal_top = 0, + // petal on the bottom layer. Has base and tip fields. + st3m_petal_bottom = 1, +} st3m_petal_kind_t; + +// State of capacitive touch for a petal's pad. +typedef struct { + // Raw data ringbuffer. + st3m_ringbuffer_t rb; + // Whether the pad is currently being touched. Calculated from ringbuffer + // data. + bool pressed; +} st3m_petal_pad_state_t; + +// State of capacitive touch for a petal. +typedef struct { + // Is this a top or bottom petal? + st3m_petal_kind_t kind; + + // Valid if top or bottom. + st3m_petal_pad_state_t base; + // Valid if bottom. + st3m_petal_pad_state_t tip; + // Valid if top. + st3m_petal_pad_state_t cw; + // Valid if top. + st3m_petal_pad_state_t ccw; + + // Whether the petal is currently being touched. Calculated from individual + // pad data. + bool pressed; + + // Touch position on petal, calculated from pad data. + // + // Arbitrary units around (0, 0). + // TODO(q3k): normalize and document. + float pos_distance; + float pos_angle; +} st3m_petal_state_t; + +typedef struct { + // Petal 0 is a top petal next to the USB socket. Then, all other petals + // follow counter-clockwise. + st3m_petal_state_t petals[10]; +} st3m_captouch_state_t; + +void st3m_captouch_init(void); +bool st3m_captouch_calibrating(void); +void st3m_captouch_request_calibration(void); +void st3m_captouch_get_all(st3m_captouch_state_t *dest); +void st3m_captouch_get_petal(st3m_petal_state_t *dest, uint8_t petal_ix); \ No newline at end of file diff --git a/components/st3m/st3m_io.c b/components/st3m/st3m_io.c index 7c78b0d5131faf441f296e66e4fc245825b083dd..10e14887c1455c6e310b8b41333cdb2b0425298a 100644 --- a/components/st3m/st3m_io.c +++ b/components/st3m/st3m_io.c @@ -113,16 +113,10 @@ uint8_t st3m_io_badge_link_enable(uint8_t pin_mask) { return st3m_io_badge_link_set(pin_mask, 1); } -// Imports from badge23, will be removed once captouch gets moved to bsp/st3m. -void captouch_read_cycle(void); -void captouch_init(void); -void captouch_force_calibration(void); - static void _task(void *data) { TickType_t last_wake = xTaskGetTickCount(); while (1) { vTaskDelayUntil(&last_wake, pdMS_TO_TICKS(10)); // 100 Hz - captouch_read_cycle(); _update_button_state(); } } @@ -135,8 +129,6 @@ void st3m_io_init(void) { } } - captouch_init(); - captouch_force_calibration(); st3m_io_badge_link_disable(BADGE_LINK_PIN_MASK_ALL); xTaskCreate(&_task, "io", 4096, NULL, configMAX_PRIORITIES - 1, NULL); diff --git a/components/st3m/st3m_ringbuffer.c b/components/st3m/st3m_ringbuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..b32fd3125d09022cc9e3aa3edb84cfc96c2afe18 --- /dev/null +++ b/components/st3m/st3m_ringbuffer.c @@ -0,0 +1,39 @@ +#include "st3m_ringbuffer.h" + +void ringbuffer_write(st3m_ringbuffer_t *rb, uint16_t data) { + rb->buf[rb->write_ix] = data; + rb->write_ix++; + if (rb->write_ix >= ringbuffer_size(rb)) { + rb->write_ix = 0; + rb->wrapped = true; + } +} + +uint16_t ringbuffer_avg(const st3m_ringbuffer_t *rb) { + int32_t res = 0; + if (rb->wrapped) { + for (size_t i = 0; i < ringbuffer_size(rb); i++) { + res += rb->buf[i]; + } + res /= ringbuffer_size(rb); + return res; + } + if (rb->write_ix == 0) { + return 0; + } + for (size_t i = 0; i < rb->write_ix; i++) { + res += rb->buf[i]; + } + res /= rb->write_ix; + return res; +} + +uint16_t ringbuffer_last(const st3m_ringbuffer_t *rb) { + if (rb->write_ix == 0) { + if (rb->wrapped) { + return rb->buf[ringbuffer_size(rb) - 1]; + } + return 0; + } + return rb->buf[rb->write_ix - 1]; +} diff --git a/components/st3m/st3m_ringbuffer.h b/components/st3m/st3m_ringbuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..4fc97cf2d67fe8f2b5284eb6ca09c09403d0b0df --- /dev/null +++ b/components/st3m/st3m_ringbuffer.h @@ -0,0 +1,29 @@ +#pragma once + +// A simple, non-concurrent ringbuffer. +// +// TODO(q3k): make generic and use from scope code + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +typedef struct { + size_t write_ix; + bool wrapped; + uint16_t buf[4]; +} st3m_ringbuffer_t; + +// Size of ringbuffer, in elements. +inline size_t ringbuffer_size(const st3m_ringbuffer_t *rb) { + return sizeof(rb->buf) / sizeof(uint16_t); +} + +// Write to ringbuffer. +void ringbuffer_write(st3m_ringbuffer_t *rb, uint16_t data); + +// Get ringbuffer average (mean), or 0 if no values have yet been inserted. +uint16_t ringbuffer_avg(const st3m_ringbuffer_t *rb); + +// Get last inserted value, or 0 if no value have yet been inserted. +uint16_t ringbuffer_last(const st3m_ringbuffer_t *rb); \ No newline at end of file diff --git a/python_payload/apps/cap_touch_demo.py b/python_payload/apps/cap_touch_demo.py index 2f9e426bb987c4e1e65adee542065b6d50234a4d..b7006f60a39ae882dcdc58a4131b197d9a66ff6e 100644 --- a/python_payload/apps/cap_touch_demo.py +++ b/python_payload/apps/cap_touch_demo.py @@ -7,7 +7,8 @@ import cmath import math import time -import hardware +import captouch + from st3m import utils, application, ui, event @@ -50,19 +51,15 @@ class CapTouchDemo(application.Application): def main_foreground(self): self.dots = [] + cps = captouch.read() for i in range(10): - size = (hardware.get_captouch(i) * 4) + 4 - size += int( - max( - 0, - sum( - [hardware.captouch_get_petal_pad(i, x) for x in range(0, 3 + 1)] - ) - / 8000, - ) - ) - x = 70 + (hardware.captouch_get_petal_rad(i) / 1000) - x += (hardware.captouch_get_petal_phi(i) / 600) * 1j + petal = cps.petals[i] + (rad, phi) = petal.position + size = 4 + if petal.pressed: + size += 4 + x = 70 + (rad / 1000) + x += (phi / 600) * 1j rot = cmath.exp(2j * math.pi * i / 10) x = x * rot @@ -78,7 +75,7 @@ class CapTouchDemo(application.Application): def do_autocalib(self, data): log.info("Performing captouch autocalibration") - hardware.captouch_autocalib() + captouch.calibration_request() self.last_calib = 50 diff --git a/python_payload/apps/harmonic_demo.py b/python_payload/apps/harmonic_demo.py index 9301bea890c28e7aa919d0011f826947c3a11676..f62e963e4f0a21c8a6a7fac7ae2b16d47bf38007 100644 --- a/python_payload/apps/harmonic_demo.py +++ b/python_payload/apps/harmonic_demo.py @@ -1,5 +1,6 @@ from bl00mbox import tinysynth from hardware import * +import captouch import leds @@ -65,8 +66,9 @@ class HarmonicApp(Application): def main_foreground(self): if self.color_intensity > 0: self.color_intensity -= self.color_intensity / 20 + cts = captouch.read() for i in range(10): - if get_captouch(i): + if cts.petals[i].pressed: if i % 2: k = int((i - 1) / 2) self._set_chord(k) diff --git a/python_payload/apps/melodic_demo.py b/python_payload/apps/melodic_demo.py index 7b37378bc0aea44e59810bb7b97dcbb5c2ab9a9e..ce7dce09cd907bcf28fea27e14a81f59aaeed56d 100644 --- a/python_payload/apps/melodic_demo.py +++ b/python_payload/apps/melodic_demo.py @@ -1,5 +1,6 @@ from bl00mbox import tinysynth from hardware import * +import captouch import leds octave = 0 @@ -40,8 +41,9 @@ def run(): global scale global octave global synths + cts = captouch.read() for i in range(10): - if get_captouch(i): + if cts.petals[i].pressed: if i == 4: octave = -1 adjust_playing_field_to_octave() diff --git a/python_payload/main.py b/python_payload/main.py index f2b0b0ac6a51c6af419d28f362bcda60a58cd66d..ff80588fea09617c2f9025c0c20ea39a74ed1ba3 100644 --- a/python_payload/main.py +++ b/python_payload/main.py @@ -22,10 +22,10 @@ ts_end = time.time() log.info(f"boot took {ts_end-ts_start} seconds") # TODO persistent settings -from st3m.system import hardware, audio +from st3m.system import audio, captouch log.info("calibrating captouch, reset volume") -hardware.captouch_autocalib() +captouch.calibration_request() audio.set_volume_dB(0) # Start default app diff --git a/python_payload/mypystubs/captouch.pyi b/python_payload/mypystubs/captouch.pyi index 1b8822d50dfc0ac389b898d2a048bc5d09fa3f9c..99edb701794e2b1ca6f2d90fb10df11606cbc62e 100644 --- a/python_payload/mypystubs/captouch.pyi +++ b/python_payload/mypystubs/captouch.pyi @@ -58,6 +58,20 @@ class CaptouchPetalState(Protocol): State of individual pads of the petal. """ ... + @property + def position(seld) -> Tuple[int, int]: + """ + Polar coordinates of touch on petal in the form of a (distance, angle) + tuple. + + The units are arbitrary, but centered around (0, 0). + + An increase in distance means the touch is further away from the centre + of the badge. + + An increase in angle means the touch is more counter-clockwise. + """ + ... class CaptouchState(Protocol): """ @@ -89,3 +103,10 @@ def calibration_active() -> bool: Returns true if the captouch system is current recalibrating. """ ... + +def calibration_request() -> None: + """ + Attempts to start calibration of captouch controllers. No-op if a + calibration is already active. + """ + ... diff --git a/python_payload/mypystubs/hardware.pyi b/python_payload/mypystubs/hardware.pyi index 7134d33247efa91e4c9406854d5e2f99357a1172..e6aab870e8d8385648cb89201c571abf521ad9bd 100644 --- a/python_payload/mypystubs/hardware.pyi +++ b/python_payload/mypystubs/hardware.pyi @@ -12,15 +12,6 @@ def usb_connected() -> bool: ... def usb_console_active() -> bool: ... def version() -> str: ... def i2c_scan() -> list[int]: ... -def captouch_calibration_active() -> int: ... -def get_captouch(ix: int) -> bool: ... -def captouch_get_petal_pad_raw(petal: int, pad: int) -> int: ... -def captouch_get_petal_pad(petal: int, pad: int) -> int: ... -def captouch_get_petal_rad(petal: int) -> int: ... -def captouch_get_petal_phi(petal: int) -> int: ... -def captouch_set_petal_pad_threshold(petal: int, pad: int, thres: int) -> None: ... -def captouch_autocalib() -> None: ... -def captouch_set_calibration_afe_target(target: int) -> None: ... def menu_button_get() -> int: ... def application_button_get() -> int: ... def left_button_get() -> int: ... diff --git a/python_payload/st3m/event.py b/python_payload/st3m/event.py index 9d5429eb162803a2da701c614c385c3e40a52cb3..e48505e3a69408b4534c47f2c05db4dd04041e56 100644 --- a/python_payload/st3m/event.py +++ b/python_payload/st3m/event.py @@ -3,7 +3,7 @@ from st3m import logging log = logging.Log(__name__, level=logging.INFO) log.info("import") -from st3m.system import hardware +from st3m.system import hardware, captouch import kernel import time @@ -124,14 +124,17 @@ class Engine: ) # captouch + cps = captouch.read() for i in range(0, 10): + petal = cps.petals[i] + (radius, angle) = petal.position input_state.append( { "type": "captouch", "index": i, - "value": hardware.get_captouch(i), - "radius": hardware.captouch_get_petal_rad(i), - "angle": hardware.captouch_get_petal_phi(i), + "value": petal.pressed, + "radius": radius, + "angle": angle, } ) diff --git a/python_payload/st3m/system/__init__.py b/python_payload/st3m/system/__init__.py index 3b3aaf1b374dae9c7951e51d3a7f641a6c1a6c76..f2512322c2b05e13b73849779ca80d1a941cfcfd 100644 --- a/python_payload/st3m/system/__init__.py +++ b/python_payload/st3m/system/__init__.py @@ -1,4 +1,5 @@ import hardware as _hardware +import captouch as _captouch class NamedObject: @@ -36,4 +37,5 @@ except ModuleNotFoundError: hardware = _hardware +captouch = _captouch audio = _audio diff --git a/sim/fakes/bl00mbox.py b/sim/fakes/bl00mbox.py index 7be5719b27f48a71d36f1f2c1393a3e0004d7b59..c9c644ecfd11f3c62ddbc7c7fdebadb6e707e3b0 100644 --- a/sim/fakes/bl00mbox.py +++ b/sim/fakes/bl00mbox.py @@ -1,5 +1,5 @@ class tinysynth: - def __init__(self, a, b): + def __init__(self, a): pass def decay(self, a): @@ -13,3 +13,6 @@ class tinysynth: def start(self): pass + + def sustain(self, a): + pass diff --git a/sim/fakes/captouch.py b/sim/fakes/captouch.py index a7c4f3d46366968ad22ebc45edaccf87905e172a..2deb829a6aab23fdfc97c28cb0d590f569e774b4 100644 --- a/sim/fakes/captouch.py +++ b/sim/fakes/captouch.py @@ -29,6 +29,7 @@ class CaptouchPetalState: def __init__(self, ix: int, pads: CaptouchPetalPadsState): self._pads = pads self._ix = ix + self.position = (0, 0) @property def pressed(self) -> bool: @@ -85,3 +86,7 @@ def read() -> CaptouchState: def calibration_active() -> bool: return False + + +def calibration_request() -> None: + return diff --git a/sim/fakes/hardware.py b/sim/fakes/hardware.py index 4afe93921058c0facc39d19027ae112637f58780..4b8d78381e6f605e34cab4941b0458a308123442 100644 --- a/sim/fakes/hardware.py +++ b/sim/fakes/hardware.py @@ -422,14 +422,6 @@ def init_done(): return True -def captouch_autocalib(): - pass - - -def captouch_calibration_active(): - return False - - import ctx @@ -534,25 +526,6 @@ def menu_button_get_left(): return menu_button_left -def get_captouch(a): - _sim.process_events() - _sim.render_gui_lazy() - return _sim.petals.state_for_petal(a) - - -# TODO(iggy/q3k do proper positional captouch) -def captouch_get_petal_rad(a): - return 0 - - -def captouch_get_petal_phi(a): - return 0 - - -def captouch_get_petal_pad(i, x): - return 0 - - def freertos_sleep(ms): import _time diff --git a/usermodule/mp_captouch.c b/usermodule/mp_captouch.c index 4203140a2e88fc89da0e95f1c42e2bdb43715c6b..21d26b048b3611778524d54b506da0c9177be7c6 100644 --- a/usermodule/mp_captouch.c +++ b/usermodule/mp_captouch.c @@ -1,16 +1,23 @@ #include "py/builtin.h" #include "py/runtime.h" -#include "badge23/captouch.h" +#include "st3m_captouch.h" #include <string.h> STATIC mp_obj_t mp_captouch_calibration_active(void) { - return mp_obj_new_int(captouch_calibration_active()); + return mp_obj_new_int(st3m_captouch_calibrating()); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_captouch_calibration_active_obj, mp_captouch_calibration_active); +STATIC mp_obj_t mp_captouch_calibration_request(void) { + st3m_captouch_request_calibration(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_captouch_calibration_request_obj, + mp_captouch_calibration_request); + typedef struct { mp_obj_base_t base; mp_obj_t petal; @@ -30,7 +37,7 @@ const mp_obj_type_t captouch_petal_state_type; typedef struct { mp_obj_base_t base; mp_obj_t petals; - captouch_state_t underlying; + st3m_captouch_state_t underlying; } mp_captouch_state_t; const mp_obj_type_t captouch_state_type; @@ -44,28 +51,28 @@ STATIC void mp_captouch_petal_pads_state_attr(mp_obj_t self_in, qstr attr, mp_captouch_petal_state_t *petal = MP_OBJ_TO_PTR(self->petal); mp_captouch_state_t *captouch = MP_OBJ_TO_PTR(petal->captouch); - captouch_petal_state_t *state = &captouch->underlying.petals[petal->ix]; + st3m_petal_state_t *state = &captouch->underlying.petals[petal->ix]; bool top = (petal->ix % 2) == 0; if (top) { switch (attr) { case MP_QSTR_base: - dest[0] = mp_obj_new_bool(state->pads.base_pressed); + dest[0] = mp_obj_new_bool(state->base.pressed); break; case MP_QSTR_cw: - dest[0] = mp_obj_new_bool(state->pads.cw_pressed); + dest[0] = mp_obj_new_bool(state->cw.pressed); break; case MP_QSTR_ccw: - dest[0] = mp_obj_new_bool(state->pads.ccw_pressed); + dest[0] = mp_obj_new_bool(state->ccw.pressed); break; } } else { switch (attr) { case MP_QSTR_tip: - dest[0] = mp_obj_new_bool(state->pads.tip_pressed); + dest[0] = mp_obj_new_bool(state->tip.pressed); break; case MP_QSTR_base: - dest[0] = mp_obj_new_bool(state->pads.base_pressed); + dest[0] = mp_obj_new_bool(state->base.pressed); break; } } @@ -79,7 +86,7 @@ STATIC void mp_captouch_petal_state_attr(mp_obj_t self_in, qstr attr, } mp_captouch_state_t *captouch = MP_OBJ_TO_PTR(self->captouch); - captouch_petal_state_t *state = &captouch->underlying.petals[self->ix]; + st3m_petal_state_t *state = &captouch->underlying.petals[self->ix]; bool top = (self->ix % 2) == 0; @@ -96,6 +103,14 @@ STATIC void mp_captouch_petal_state_attr(mp_obj_t self_in, qstr attr, case MP_QSTR_pads: dest[0] = self->pads; break; + case MP_QSTR_position: { + mp_obj_t items[2] = { + mp_obj_new_int(state->pos_distance), + mp_obj_new_int(state->pos_angle), + }; + dest[0] = mp_obj_new_tuple(2, items); + break; + } } } @@ -123,10 +138,10 @@ MP_DEFINE_CONST_OBJ_TYPE(captouch_petal_state_type, MP_QSTR_CaptouchPetalState, MP_DEFINE_CONST_OBJ_TYPE(captouch_state_type, MP_QSTR_CaptouchState, MP_TYPE_FLAG_NONE, attr, mp_captouch_state_attr); -STATIC mp_obj_t mp_captouch_state_new(const captouch_state_t *underlying) { +STATIC mp_obj_t mp_captouch_state_new(const st3m_captouch_state_t *underlying) { mp_captouch_state_t *captouch = m_new_obj(mp_captouch_state_t); captouch->base.type = &captouch_state_type; - memcpy(&captouch->underlying, underlying, sizeof(captouch_state_t)); + memcpy(&captouch->underlying, underlying, sizeof(st3m_captouch_state_t)); captouch->petals = mp_obj_new_list(0, NULL); for (int i = 0; i < 10; i++) { @@ -148,8 +163,8 @@ STATIC mp_obj_t mp_captouch_state_new(const captouch_state_t *underlying) { } STATIC mp_obj_t mp_captouch_read(void) { - captouch_state_t st; - read_captouch_ex(&st); + st3m_captouch_state_t st; + st3m_captouch_get_all(&st); return mp_captouch_state_new(&st); } @@ -158,7 +173,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_captouch_read_obj, mp_captouch_read); STATIC const mp_rom_map_elem_t globals_table[] = { { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_captouch_read_obj) }, { MP_ROM_QSTR(MP_QSTR_calibration_active), - MP_ROM_PTR(&mp_captouch_calibration_active_obj) } + MP_ROM_PTR(&mp_captouch_calibration_active_obj) }, + { MP_ROM_QSTR(MP_QSTR_calibration_request), + MP_ROM_PTR(&mp_captouch_calibration_request_obj) }, }; STATIC MP_DEFINE_CONST_DICT(globals, globals_table); diff --git a/usermodule/mp_hardware.c b/usermodule/mp_hardware.c index 0c7cce149c3a485e5d95506ae902f8cbfd81dcdd..7f30eafeab0f1a8941efe710d9988ef599c41968 100644 --- a/usermodule/mp_hardware.c +++ b/usermodule/mp_hardware.c @@ -10,8 +10,6 @@ #include "py/mphal.h" #include "py/runtime.h" -#include "badge23/captouch.h" - #include "flow3r_bsp.h" #include "st3m_console.h" #include "st3m_gfx.h" @@ -26,12 +24,6 @@ mp_obj_t mp_ctx_from_ctx(Ctx *ctx); -STATIC mp_obj_t mp_captouch_calibration_active(void) { - return mp_obj_new_int(captouch_calibration_active()); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_captouch_calibration_active_obj, - mp_captouch_calibration_active); - STATIC mp_obj_t mp_display_set_backlight(mp_obj_t percent_in) { uint8_t percent = mp_obj_get_int(percent_in); flow3r_bsp_display_set_backlight(percent); @@ -40,80 +32,6 @@ STATIC mp_obj_t mp_display_set_backlight(mp_obj_t percent_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_display_set_backlight_obj, mp_display_set_backlight); -STATIC mp_obj_t mp_get_captouch(size_t n_args, const mp_obj_t *args) { - uint16_t captouch = read_captouch(); - uint16_t pad = mp_obj_get_int(args[0]); - uint8_t output = (captouch >> pad) & 1; - - return mp_obj_new_int(output); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_get_captouch_obj, 1, 2, - mp_get_captouch); - -STATIC mp_obj_t mp_captouch_get_petal_pad_raw(mp_obj_t petal_in, - mp_obj_t pad_in) { - uint8_t petal = mp_obj_get_int(petal_in); - uint8_t pad = mp_obj_get_int(pad_in); - uint16_t output = captouch_get_petal_pad_raw(petal, pad); - - return mp_obj_new_int(output); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_captouch_get_petal_pad_raw_obj, - mp_captouch_get_petal_pad_raw); - -STATIC mp_obj_t mp_captouch_get_petal_pad(mp_obj_t petal_in, mp_obj_t pad_in) { - uint8_t petal = mp_obj_get_int(petal_in); - uint8_t pad = mp_obj_get_int(pad_in); - return mp_obj_new_int(captouch_get_petal_pad(petal, pad)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_captouch_get_petal_pad_obj, - mp_captouch_get_petal_pad); - -STATIC mp_obj_t mp_captouch_get_petal_rad(mp_obj_t petal_in) { - uint8_t petal = mp_obj_get_int(petal_in); - int32_t ret = captouch_get_petal_rad(petal); - - return mp_obj_new_int(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_captouch_get_petal_rad_obj, - mp_captouch_get_petal_rad); - -STATIC mp_obj_t mp_captouch_get_petal_phi(mp_obj_t petal_in) { - uint8_t petal = mp_obj_get_int(petal_in); - int32_t ret = captouch_get_petal_phi(petal); - - return mp_obj_new_int(ret); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_captouch_get_petal_phi_obj, - mp_captouch_get_petal_phi); - -STATIC mp_obj_t mp_captouch_set_petal_pad_threshold(mp_obj_t petal_in, - mp_obj_t pad_in, - mp_obj_t thres_in) { - uint8_t petal = mp_obj_get_int(petal_in); - uint8_t pad = mp_obj_get_int(pad_in); - uint16_t thres = mp_obj_get_int(thres_in); - captouch_set_petal_pad_threshold(petal, pad, thres); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_captouch_set_petal_pad_threshold_obj, - mp_captouch_set_petal_pad_threshold); - -STATIC mp_obj_t mp_captouch_autocalib(void) { - captouch_force_calibration(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_captouch_autocalib_obj, - mp_captouch_autocalib); - -STATIC mp_obj_t mp_captouch_set_calibration_afe_target(mp_obj_t target_in) { - uint16_t target = mp_obj_get_int(target_in); - captouch_set_calibration_afe_target(target); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_captouch_set_calibration_afe_target_obj, - mp_captouch_set_calibration_afe_target); - STATIC mp_obj_t mp_menu_button_set_left(mp_obj_t left) { st3m_io_menu_button_set_left(mp_obj_get_int(left)); return mp_const_none; @@ -272,24 +190,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_usb_console_active_obj, STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hardware) }, - { MP_ROM_QSTR(MP_QSTR_captouch_calibration_active), - MP_ROM_PTR(&mp_captouch_calibration_active_obj) }, - { MP_ROM_QSTR(MP_QSTR_get_captouch), MP_ROM_PTR(&mp_get_captouch_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_get_petal_pad_raw), - MP_ROM_PTR(&mp_captouch_get_petal_pad_raw_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_get_petal_pad), - MP_ROM_PTR(&mp_captouch_get_petal_pad_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_get_petal_rad), - MP_ROM_PTR(&mp_captouch_get_petal_rad_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_get_petal_phi), - MP_ROM_PTR(&mp_captouch_get_petal_phi_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_set_petal_pad_threshold), - MP_ROM_PTR(&mp_captouch_set_petal_pad_threshold_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_autocalib), - MP_ROM_PTR(&mp_captouch_autocalib_obj) }, - { MP_ROM_QSTR(MP_QSTR_captouch_set_calibration_afe_target), - MP_ROM_PTR(&mp_captouch_set_calibration_afe_target_obj) }, - { MP_ROM_QSTR(MP_QSTR_menu_button_get), MP_ROM_PTR(&mp_menu_button_get_obj) }, { MP_ROM_QSTR(MP_QSTR_application_button_get),