From 267c8f11bb1dafd76adc4b362132cd9edf89a842 Mon Sep 17 00:00:00 2001 From: moon2 <moon2protonmail@protonmail.com> Date: Sun, 4 Jun 2023 19:42:18 +0000 Subject: [PATCH] positional captouch output --- README.md | 2 +- components/badge23/captouch.c | 595 ++++++++++-------- components/badge23/espan.c | 39 +- components/badge23/include/badge23/captouch.h | 129 +++- python_payload/README.md | 17 +- python_payload/cap_touch_demo.py | 28 + python_payload/harmonic_demo.py | 2 - python_payload/main.py | 25 +- usermodule/mp_hardware.c | 73 ++- 9 files changed, 605 insertions(+), 305 deletions(-) create mode 100644 python_payload/cap_touch_demo.py diff --git a/README.md b/README.md index af75622748..009902ff64 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Please transfer all .py files in python_payload/ for using the demo payload. $ cd ~ $ git clone https://github.com/espressif/esp-idf.git $ cd esp-idf -$ git checkout v4.4 +$ git checkout v4.4.4 $ git submodule update --init --recursive $ cd esp-idf diff --git a/components/badge23/captouch.c b/components/badge23/captouch.c index 748360ab22..976c18a7f9 100644 --- a/components/badge23/captouch.c +++ b/components/badge23/captouch.c @@ -4,29 +4,61 @@ #include "driver/i2c.h" #include "badge23_hwconfig.h" #include <stdint.h> +#include <freertos/FreeRTOS.h> +#include <freertos/atomic.h> + +#define PETAL_PAD_TIP 0 +#define PETAL_PAD_CCW 1 +#define PETAL_PAD_CW 2 +#define PETAL_PAD_BASE 3 + +#define CIN CDC_NONE 0 +#define CIN_CDC_NEG 1 +#define CIN_CDC_POS 2 +#define CIN_BIAS 3 + +#define AFE_INCR_CAP 1000 #if defined(CONFIG_BADGE23_HW_GEN_P3) || defined(CONFIG_BADGE23_HW_GEN_P4) -static const uint8_t top_map[] = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 8, 8}; //flipped top and bottom from bootstrap reference +static const uint8_t top_map[] = {0, 0, 0, 2, 2, 2, 6, 6, 6, 4, 4, 4}; static const uint8_t top_stages = 12; -static const uint8_t bot_map[] = {0, 0, 0, 2, 2, 2, 6, 6, 6, 4, 4, 4}; //idk y :~) -static const uint8_t bottom_stages = 12; +static const uint8_t bot_map[] = {1, 1, 3, 3, 5, 7, 7, 9, 9, 8, 8, 8}; +static const uint8_t bot_stages = 12; +static const uint8_t top_segment_map[] = {1,3,2,2,3,1,1,3,2,1,3,2}; //PETAL_PAD_* +static const uint8_t bot_segment_map[] = {3,0,3,0,0,0,3,0,3,1,2,3}; //PETAL_PAD_* +static const uint8_t bot_stage_config[] = {0,1,2,3,5,6,7,8,9,10,11,12}; +#define DEFAULT_THRES_TOP 8000 +#define DEFAULT_THRES_BOT 12000 #elif defined(CONFIG_BADGE23_HW_GEN_P1) static const uint8_t top_map[] = {2, 2, 2, 0, 0, 8, 8, 8, 6, 6, 4, 4}; static const uint8_t top_stages = 12; static const uint8_t bot_map[] = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9}; -static const uint8_t bottom_stages = 10; +static const uint8_t bot_stages = 10; +static const uint8_t top_segment_map[] = {1,2,0,1,2,1,2,0,1,2,1,2}; //idk +static const uint8_t bot_segment_map[] = {3,0,3,0,3,0,0,3,0,3}; //idk +static const uint8_t bot_stage_config[] = {0,1,2,3,4,5,6,7,8,9,10,11}; +#define DEFAULT_THRES_TOP 2000 +#define DEFAULT_THRES_BOT 12000 +#define AD7147_ADDR_TOP 0b101101 +#define AD7147_ADDR_BOT 0b101100 #else #error "captouch not implemented for this badge generation" #endif +#if defined(CONFIG_BADGE23_HW_GEN_P4) +#define AD7147_ADDR_TOP 0b101100 +#define AD7147_ADDR_BOT 0b101101 +#elif defined(CONFIG_BADGE23_HW_GEN_P3) +#define AD7147_ADDR_TOP 0b101101 +#define AD7147_ADDR_BOT 0b101100 +#endif + static const char *TAG = "captouch"; #define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ -#define AD7147_BASE_ADDR 0x2C - #define AD7147_REG_PWR_CONTROL 0x00 #define AD7147_REG_STAGE_CAL_EN 0x01 #define AD7147_REG_STAGE_HIGH_INT_ENABLE 0x06 @@ -34,24 +66,36 @@ static const char *TAG = "captouch"; #define TIMEOUT_MS 1000 +#define PETAL_PRESSED_DEBOUNCE 2 + +static struct ad714x_chip *chip_top; +static struct ad714x_chip *chip_bot; + +typedef struct{ + uint8_t config_mask; + uint16_t amb_values[4]; //ordered according to PETAL_PAD_* + uint16_t cdc_values[4]; //ordered according to PETAL_PAD_* + uint16_t thres_values[4]; //ordered according to PETAL_PAD_* + uint8_t pressed; +} petal_t; + +static petal_t petals[10]; + struct ad714x_chip { uint8_t addr; uint8_t gpio; - int afe_offsets[13]; + int pos_afe_offsets[13]; + int neg_afe_offsets[13]; + int neg_afe_offset_swap; int stages; }; -// Captouch sensor chips addresses are swapped on proto3. Whoops. -#if defined(CONFIG_BADGE23_HW_GEN_P3) -#define AD7147_BASE_ADDR_TOP (AD7147_BASE_ADDR) -#define AD7147_BASE_ADDR_BOT (AD7147_BASE_ADDR + 1) -#else -#define AD7147_BASE_ADDR_TOP (AD7147_BASE_ADDR + 1) -#define AD7147_BASE_ADDR_BOT (AD7147_BASE_ADDR) -#endif - -static const struct ad714x_chip chip_top = {.addr = AD7147_BASE_ADDR_TOP, .gpio = 48, .afe_offsets = {24, 12, 16, 33, 30, 28, 31, 27, 22, 24, 18, 19, }, .stages=top_stages}; -static const struct ad714x_chip chip_bot = {.addr = AD7147_BASE_ADDR_BOT, .gpio = 3, .afe_offsets = {3, 2, 1, 1 ,1, 1, 1, 1, 2, 3}, .stages=bottom_stages}; +static struct ad714x_chip chip_top_rev5 = {.addr = AD7147_ADDR_TOP, .gpio = 15, + .pos_afe_offsets = {4, 2, 2, 2, 2, 3, 4, 2, 2, 2, 2, 0}, + .stages=top_stages}; +static struct ad714x_chip chip_bot_rev5 = {.addr = AD7147_ADDR_BOT, .gpio = 15, + .pos_afe_offsets = {3, 2, 1, 1 ,1, 1, 1, 1, 2, 3, 3, 3}, + .stages=bot_stages}; static esp_err_t ad714x_i2c_write(const struct ad714x_chip *chip, const uint16_t reg, const uint16_t data) { @@ -86,10 +130,6 @@ struct ad7147_stage_config { unsigned int pos_peak_detect:3; }; -#define CIN CDC_NONE 0 -#define CIN_CDC_NEG 1 -#define CIN_CDC_POS 2 -#define CIN_BIAS 3 static const uint16_t bank2 = 0x80; @@ -169,73 +209,41 @@ static struct ad7147_stage_config ad714x_default_config(void) }; } -#define ESP_INTR_FLAG_DEFAULT 0 - -static QueueHandle_t gpio_evt_queue = NULL; - -static void IRAM_ATTR gpio_isr_handler(void* arg) -{ - struct ad714x_chip* chip = (struct ad714x_chip *) arg; - xQueueSendFromISR(gpio_evt_queue, &chip, NULL); -} - -static uint16_t pressed_top, pressed_bot; - -static void captouch_chip_readout(struct ad714x_chip * chip){ - uint16_t pressed; - ad714x_i2c_read(chip, 9, &pressed, 1); - ESP_LOGI(TAG, "Addr %x, High interrupt %X", chip->addr, pressed); - - pressed &= ((1 << chip->stages) - 1); - - if(chip == &chip_top) pressed_top = pressed; - if(chip == &chip_bot) pressed_bot = pressed; -} - -void manual_captouch_readout(uint8_t top) -{ - struct ad714x_chip* chip = top ? (&chip_top) : (&chip_bot); - captouch_chip_readout(chip); - //xQueueSend(gpio_evt_queue, &chip, NULL); -} - -void gpio_event_handler(void* arg) -{ - static unsigned long counter = 0; - struct ad714x_chip* chip; - while(true) { - if(xQueueReceive(gpio_evt_queue, &chip, portMAX_DELAY)) { - captouch_chip_readout(chip); - } +static void captouch_configure_stage(struct ad714x_chip * chip, uint8_t stage){ + struct ad7147_stage_config stage_config; + stage_config = ad714x_default_config(); + if(chip == chip_bot){ + stage_config.cinX_connection_setup[bot_stage_config[stage]] = CIN_CDC_POS; + } else { + stage_config.cinX_connection_setup[stage] = CIN_CDC_POS; } + stage_config.pos_afe_offset=chip->pos_afe_offsets[stage]; + ad714x_set_stage_config(chip, stage, &stage_config); } -uint16_t read_captouch(){ - uint16_t petals = 0; - uint16_t top = pressed_top; - uint16_t bot = pressed_bot; - - for(int i=0; i<top_stages; i++) { - if(top & (1 << i)) { - petals |= (1<<top_map[i]); - } - } - - for(int i=0; i<bottom_stages; i++) { - if(bot & (1 << i)) { - petals |= (1<<bot_map[i]); - } +static int8_t captouch_configure_stage_afe_offset(uint8_t top, uint8_t stage, int8_t delta_afe){ + int8_t sat = 0; + struct ad714x_chip * chip = chip_bot; + if(top) chip = chip_top; + int8_t afe = chip->pos_afe_offsets[stage] - chip->neg_afe_offsets[stage]; + if((afe >= 63) && (delta_afe > 0)) sat = 1; + if((afe <= 63) && (delta_afe < 0)) sat = -1; + afe += delta_afe; + if(afe >= 63) afe = 63; + if(afe <= -63)afe = -63; + + if(afe>0){ + chip->pos_afe_offsets[stage] = afe; + chip->neg_afe_offsets[stage] = 0; + } else { + chip->pos_afe_offsets[stage] = 0; + chip->neg_afe_offsets[stage] = -afe; } - - return petals; + captouch_configure_stage(chip, stage); + return sat; } -void captouch_force_calibration(){ - ad714x_i2c_write(&chip_top, 2, (1 << 14)); - ad714x_i2c_write(&chip_bot, 2, (1 << 14)); -} - -static void captouch_init_chip(const struct ad714x_chip* chip, const struct ad7147_device_config device_config) +static void captouch_init_chip(struct ad714x_chip* chip, const struct ad7147_device_config device_config) { uint16_t data; ad714x_i2c_read(chip, AD7147_REG_DEVICE_ID, &data, 1); @@ -244,226 +252,285 @@ static void captouch_init_chip(const struct ad714x_chip* chip, const struct ad71 ad714x_set_device_config(chip, &device_config); for(int i=0; i<chip->stages; i++) { - struct ad7147_stage_config stage_config; - stage_config = ad714x_default_config(); - stage_config.cinX_connection_setup[i] = CIN_CDC_POS; - stage_config.pos_afe_offset=chip->afe_offsets[i]; - ad714x_set_stage_config(chip, i, &stage_config); + captouch_configure_stage(chip, i); } +} - captouch_force_calibration(); - - gpio_config_t io_conf = {}; - io_conf.intr_type = GPIO_INTR_NEGEDGE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = (1ULL << chip->gpio); - io_conf.pull_up_en = 1; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); +static void captouch_init_petals(){ + for(int i = 0; i < 10; i++){ + for(int j = 0; j < 4; j++){ + petals[i].amb_values[j] = 0; + petals[i].cdc_values[j] = 0; + if(i%2){ + petals[i].thres_values[j] = DEFAULT_THRES_BOT; + } else { + petals[i].thres_values[j] = DEFAULT_THRES_TOP; + } + } + petals[i].config_mask = 0; + } + for(int i = 0; i < bot_stages; i++){ + petals[bot_map[i]].config_mask |= 1 << bot_segment_map[i]; + } + for(int i = 0; i < top_stages; i++){ + petals[top_map[i]].config_mask |= 1 << top_segment_map[i]; + } +} - // gpio_isr_handler_add(chip->gpio, gpio_isr_handler, (void *)chip); +int32_t captouch_get_petal_rad(uint8_t petal){ + if(petal > 9) petal = 9; + uint8_t cf = petals[petal].config_mask; + if(cf == 0b1110){ //CCW, CW, BASE + int32_t left = petals[petal].cdc_values[PETAL_PAD_CCW]; + left -= petals[petal].amb_values[PETAL_PAD_CCW]; + int32_t right = petals[petal].cdc_values[PETAL_PAD_CW]; + right -= petals[petal].amb_values[PETAL_PAD_CW]; + int32_t base = petals[petal].cdc_values[PETAL_PAD_BASE]; + base -= petals[petal].amb_values[PETAL_PAD_BASE]; + return (left + right)/2 - base; + } + if(cf == 0b111){ //CCW, CW, TIP + int32_t left = petals[petal].cdc_values[PETAL_PAD_CCW]; + left -= petals[petal].amb_values[PETAL_PAD_CCW]; + int32_t right = petals[petal].cdc_values[PETAL_PAD_CW]; + right -= petals[petal].amb_values[PETAL_PAD_CW]; + int32_t tip = petals[petal].cdc_values[PETAL_PAD_TIP]; + tip -= petals[petal].amb_values[PETAL_PAD_TIP]; + return (-left - right)/2 + tip; + } + if(cf == 0b1001){ //TIP, BASE + int32_t tip = petals[petal].cdc_values[PETAL_PAD_TIP]; + tip -= petals[petal].amb_values[PETAL_PAD_TIP]; + int32_t base = petals[petal].cdc_values[PETAL_PAD_BASE]; + base -= petals[petal].amb_values[PETAL_PAD_BASE]; + return tip - base; + } + if(cf == 0b1){ //TIP + int32_t tip = petals[petal].cdc_values[PETAL_PAD_TIP]; + tip -= petals[petal].amb_values[PETAL_PAD_TIP]; + return tip; + } + return 0; +} +int32_t captouch_get_petal_phi(uint8_t petal){ + if(petal > 9) petal = 9; + uint8_t cf = petals[petal].config_mask; + if((cf == 0b1110) || (cf == 0b110) || (cf == 0b111)){ //CCW, CW, (BASE) + int32_t left = petals[petal].cdc_values[PETAL_PAD_CCW]; + left -= petals[petal].amb_values[PETAL_PAD_CCW]; + int32_t right = petals[petal].cdc_values[PETAL_PAD_CW]; + right -= petals[petal].amb_values[PETAL_PAD_CW]; + return left - right; + } + return 0; } void captouch_init(void) { - //gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); - captouch_init_chip(&chip_top, (struct ad7147_device_config){.sequence_stage_num = 11, + captouch_init_petals(); + chip_top = &chip_top_rev5; + chip_bot = &chip_bot_rev5; + + captouch_init_chip(chip_top, (struct ad7147_device_config){.sequence_stage_num = 11, .decimation = 1, - .stage0_cal_en = 1, - .stage1_cal_en = 1, - .stage2_cal_en = 1, - .stage3_cal_en = 1, - .stage4_cal_en = 1, - .stage5_cal_en = 1, - .stage6_cal_en = 1, - .stage7_cal_en = 1, - .stage8_cal_en = 1, - .stage9_cal_en = 1, - .stage10_cal_en = 1, - .stage11_cal_en = 1, - - .stage0_high_int_enable = 1, - .stage1_high_int_enable = 1, - .stage2_high_int_enable = 1, - .stage3_high_int_enable = 1, - .stage4_high_int_enable = 1, - .stage5_high_int_enable = 1, - .stage6_high_int_enable = 1, - .stage7_high_int_enable = 1, - .stage8_high_int_enable = 1, - .stage9_high_int_enable = 1, - .stage10_high_int_enable = 1, - .stage11_high_int_enable = 1, }); - captouch_init_chip(&chip_bot, (struct ad7147_device_config){.sequence_stage_num = 11, + captouch_init_chip(chip_bot, (struct ad7147_device_config){.sequence_stage_num = 11, .decimation = 1, - .stage0_cal_en = 1, - .stage1_cal_en = 1, - .stage2_cal_en = 1, - .stage3_cal_en = 1, - .stage4_cal_en = 1, - .stage5_cal_en = 1, - .stage6_cal_en = 1, - .stage7_cal_en = 1, - .stage8_cal_en = 1, - .stage9_cal_en = 1, - - .stage0_high_int_enable = 1, - .stage1_high_int_enable = 1, - .stage2_high_int_enable = 1, - .stage3_high_int_enable = 1, - .stage4_high_int_enable = 1, - .stage5_high_int_enable = 1, - .stage6_high_int_enable = 1, - .stage7_high_int_enable = 1, - .stage8_high_int_enable = 1, - .stage9_high_int_enable = 1, }); - - gpio_evt_queue = xQueueCreate(10, sizeof(const struct ad714x_chip*)); - //xTaskCreate(gpio_event_handler, "gpio_event_handler", 2048 * 2, NULL, configMAX_PRIORITIES - 2, NULL); } -static void captouch_print_debug_info_chip(const struct ad714x_chip* chip) -{ - uint16_t data[12] = {0,}; - uint16_t ambient[12] = {0,}; - const int stages = chip->stages; -#if 1 - for(int stage=0; stage<stages; stage++) { - ad714x_i2c_read(chip, 0x0FA + stage * (0x104 - 0xE0), data, 1); - ESP_LOGI(TAG, "stage %d threshold: %X", stage, data[0]); +uint16_t read_captouch(){ + uint16_t bin_petals = 0; + for(int i = 0; i < 10; i++) { + if(petals[i].pressed){ + bin_petals |= (1<<i); + } } + return bin_petals; +} - ad714x_i2c_read(chip, 0xB, data, stages); - ESP_LOGI(TAG, "CDC results: %X %X %X %X %X %X %X %X %X %X %X %X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]); +uint16_t cdc_data[2][12] = {0,}; +uint16_t cdc_ambient[2][12] = {0,}; - for(int stage=0; stage<stages; stage++) { - ad714x_i2c_read(chip, 0x0F1 + stage * (0x104 - 0xE0), &ambient[stage], 1); - ESP_LOGI(TAG, "stage %d ambient: %X diff: %d", stage, ambient[stage], data[stage] - ambient[stage]); - } +static volatile uint32_t calib_active = 0; -#endif -#if 1 - ad714x_i2c_read(chip, 8, data, 1); - ESP_LOGI(TAG, "Low interrupt %X", data[0]); - ad714x_i2c_read(chip, 9, data, 1); - ESP_LOGI(TAG, "High interrupt %X", data[0]); - ad714x_i2c_read(chip, 0x42, data, 1); - ESP_LOGI(TAG, "Proximity %X", data[0]); - //ESP_LOGI(TAG, "CDC result = %X", data[0]); - //if(data[0] > 0xa000) { - //ESP_LOGI(TAG, "Touch! %X", data[0]); - //} -#endif +static uint8_t calib_cycles = 0; +void captouch_force_calibration(){ + if(!calib_cycles){ //last calib has finished + calib_cycles = 16; //goal cycles, can be argument someday + Atomic_Increment_u32(&calib_active); + } } -void captouch_print_debug_info(void) -{ - captouch_print_debug_info_chip(&chip_top); - captouch_print_debug_info_chip(&chip_bot); +uint8_t captouch_calibration_active(){ + return Atomic_CompareAndSwap_u32(&calib_active, 0, 0) == ATOMIC_COMPARE_AND_SWAP_FAILURE; } -void captouch_get_cross(int paddle, int *x, int *y) -{ - uint16_t data[12] = {0,}; - uint16_t ambient[12] = {0,}; - - int result[2] = {0, 0}; - float total = 0; - -#if 0 - if(paddle == 2) { - ad714x_i2c_read(&chip_top, 0xB, data, 3); - //ESP_LOGI(TAG, "CDC results: %X %X %X %X %X %X %X %X %X %X %X %X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]); - for(int stage=0; stage<3; stage++) { - ad714x_i2c_read(&chip_top, 0x0F1 + stage * (0x104 - 0xE0), &ambient[stage], 1); - //ESP_LOGI(TAG, "stage %d ambient: %X diff: %d", stage, ambient[stage], data[stage] - ambient[stage]); +void check_petals_pressed(){ + for(int i = 0; i < 10; i++){ + bool pressed = 0; + bool prev = petals[i].pressed; + for(int j = 0; j < 4; j++){ + if((petals[i].amb_values[j] + + petals[i].thres_values[j]) < + petals[i].cdc_values[j]){ + pressed = 1; + } + } + if(pressed){ + petals[i].pressed = PETAL_PRESSED_DEBOUNCE; + } else if(petals[i].pressed){ + petals[i].pressed--; } - int vectors[][2] = {{0, 0}, {0,240}, {240, 120}}; - total = (data[0] - ambient[0]) + (data[1] - ambient[1]) + (data[2] - ambient[2]); + if(petals[i].pressed && (!prev)){ + // TODO: PETAL_PRESS_CALLBACK + } + if((!petals[i].pressed) && prev){ + // TODO: PETAL_RELEASE_CALLBACK + } + } +} - result[0] = vectors[0][0] * (data[0] - ambient[0]) + vectors[1][0] * (data[1] - ambient[1]) + vectors[2][0] * (data[2] - ambient[2]); - result[1] = vectors[0][1] * (data[0] - ambient[0]) + vectors[1][1] * (data[1] - ambient[1]) + vectors[2][1] * (data[2] - ambient[2]); +void cdc_to_petal(bool bot, bool amb, uint16_t cdc_data[], uint8_t cdc_data_length){ + if(!bot){ + for(int i = 0; i < cdc_data_length; i++){ + if(amb){ + petals[top_map[i]].amb_values[top_segment_map[i]] = cdc_data[i]; + } else { + petals[top_map[i]].cdc_values[top_segment_map[i]] = cdc_data[i]; + } + } + } else { + for(int i = 0; i < cdc_data_length; i++){ + if(amb){ + petals[bot_map[i]].amb_values[bot_segment_map[i]] = cdc_data[i]; + } else { + petals[bot_map[i]].cdc_values[bot_segment_map[i]] = cdc_data[i]; + } + } } +} - if(paddle == 8) { - ad714x_i2c_read(&chip_top, 0xB + 5, data + 5, 3); - //ESP_LOGI(TAG, "CDC results: %X %X %X %X %X %X %X %X %X %X %X %X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]); +uint16_t captouch_get_petal_pad_raw(uint8_t petal, uint8_t pad){ + if(petal > 9) petal = 9; + if(pad > 3) pad = 3; + return petals[petal].cdc_values[pad]; +} +uint16_t captouch_get_petal_pad_calib_ref(uint8_t petal, uint8_t pad){ + if(petal > 9) petal = 9; + if(pad > 3) pad = 3; + return petals[petal].amb_values[pad]; +} +uint16_t captouch_get_petal_pad(uint8_t petal, uint8_t pad){ + if(petal > 9) petal = 9; + if(pad > 3) pad = 3; + if(petals[petal].amb_values[pad] < petals[petal].cdc_values[pad]){ + return petals[petal].cdc_values[pad] - petals[petal].amb_values[pad]; + } + return 0; +} - for(int stage=5; stage<8; stage++) { - ad714x_i2c_read(&chip_top, 0x0F1 + stage * (0x104 - 0xE0), &ambient[stage], 1); - //ESP_LOGI(TAG, "stage %d ambient: %X diff: %d", stage, ambient[stage], data[stage] - ambient[stage]); - } +void captouch_set_petal_pad_threshold(uint8_t petal, uint8_t pad, uint16_t thres){ + if(petal > 9) petal = 9; + if(pad > 3) pad = 3; + petals[petal].thres_values[pad] = thres; +} - int vectors[][2] = {{240, 240}, {240, 0}, {0, 120}}; - total = (data[5] - ambient[5]) + (data[6] - ambient[6]) + (data[7] - ambient[7]); +static int32_t calib_target = 6000; - result[0] = vectors[0][0] * (data[5] - ambient[5]) + vectors[1][0] * (data[6] - ambient[6]) + vectors[2][0] * (data[7] - ambient[7]); - result[1] = vectors[0][1] * (data[5] - ambient[5]) + vectors[1][1] * (data[6] - ambient[6]) + vectors[2][1] * (data[7] - ambient[7]); - } +void captouch_set_calibration_afe_target(uint16_t target){ + calib_target = target; +} - *x = result[0] / total; - *y = result[1] / total; +void captouch_read_cycle(){ + static uint8_t calib_cycle = 0; + static uint8_t calib_div = 1; + static uint32_t ambient_acc[2][12] = {{0,}, {0,}}; + if(calib_cycles){ + if(calib_cycle == 0){ // last cycle has finished, setup new + calib_cycle = calib_cycles; + calib_div = calib_cycles; + for(int j=0;j<12;j++){ + ambient_acc[0][j] = 0; + ambient_acc[1][j] = 0; + } + } + + ad714x_i2c_read(chip_top, 0xB, cdc_ambient[0], chip_top->stages); + ad714x_i2c_read(chip_bot, 0xB, cdc_ambient[1], chip_bot->stages); + for(int j=0;j<12;j++){ + ambient_acc[0][j] += cdc_ambient[0][j]; + ambient_acc[1][j] += cdc_ambient[1][j]; + } + + // TODO: use median instead of average + calib_cycle--; + if(!calib_cycle){ //calib cycle is complete + for(int i = 0; i < 12; i++){ + cdc_ambient[0][i] = ambient_acc[0][i] / calib_div; + cdc_ambient[1][i] = ambient_acc[1][i] / calib_div; + } + cdc_to_petal(0, 1, cdc_ambient[0], 12); + cdc_to_petal(1, 1, cdc_ambient[1], 12); + calib_cycles = 0; + + uint8_t recalib = 0; + for(int i = 0; i < 12; i++){ + for(int j = 0; j < 2; j++){ + int32_t diff = ((int32_t) cdc_ambient[j][i]) - calib_target; + int8_t steps = diff/(AFE_INCR_CAP); + if((steps > 1) || (steps < -1)){ + if(!captouch_configure_stage_afe_offset(1-j, i, steps)){ + recalib = 1; + } + } + } + } + if(recalib){ + calib_cycles = 16; // do another round + } else { + Atomic_Decrement_u32(&calib_active); + } + } + } else { + ad714x_i2c_read(chip_top, 0xB, cdc_data[0], chip_top->stages); + cdc_to_petal(0, 0, cdc_data[0], 12); + + ad714x_i2c_read(chip_bot, 0xB, cdc_data[1], chip_bot->stages); + cdc_to_petal(1, 0, cdc_data[1], 12); + + check_petals_pressed(); + } +} - //ESP_LOGI(TAG, "x=%d y=%d\n", *x, *y); -#endif +static void captouch_print_debug_info_chip(const struct ad714x_chip* chip) +{ + uint16_t *data; + uint16_t *ambient; + const int stages = chip->stages; - const int paddle_info_1[] = { - 4, - 0, - 1, - 2, - 11, - 4, - 9, - 7, - 6, - 9, - }; - const int paddle_info_2[] = { - 3, - 1, - 0, - 3, - 10, - 5, - 8, - 6, - 5, - 8, - }; - - struct ad714x_chip* chip; - if (paddle % 2 == 0) { - chip = &chip_top; + if(chip == chip_top) { + data = cdc_data[0]; + ambient = cdc_ambient[0]; } else { - chip = &chip_bot; + data = cdc_data[1]; + ambient = cdc_ambient[1]; } - ad714x_i2c_read(chip, 0xB, data, 12); - //ESP_LOGI(TAG, "CDC results: %X %X %X %X %X %X %X %X %X %X %X %X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]); + ESP_LOGI(TAG, "CDC results: %X %X %X %X %X %X %X %X %X %X %X %X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]); - for(int stage=0; stage<12; stage++) { - ad714x_i2c_read(chip, 0x0F1 + stage * (0x104 - 0xE0), &ambient[stage], 1); - //ESP_LOGI(TAG, "stage %d ambient: %X diff: %d", stage, ambient[stage], data[stage] - ambient[stage]); + for(int stage=0; stage<stages; stage++) { + ESP_LOGI(TAG, "stage %d ambient: %X diff: %d", stage, ambient[stage], data[stage] - ambient[stage]); } +} - int diff1 = data[paddle_info_1[paddle]] - ambient[paddle_info_1[paddle]]; - int diff2 = data[paddle_info_2[paddle]] - ambient[paddle_info_2[paddle]]; - - ESP_LOGI(TAG, "%10d %10d", diff1, diff2); - - int vectors[][2] = {{240, 240}, {240, 0}, {0, 120}}; - total = ((diff1) + (diff2)); - - result[0] = vectors[0][0] * (diff1) + vectors[1][0] * (diff2); - result[1] = vectors[0][1] * (diff1) + vectors[1][1] * (diff2); - - *x = result[0] / total; - *y = result[1] / total; +void captouch_print_debug_info(void) +{ + captouch_print_debug_info_chip(chip_top); + captouch_print_debug_info_chip(chip_bot); } + diff --git a/components/badge23/espan.c b/components/badge23/espan.c index f8ba3fd9b8..4df670e72a 100644 --- a/components/badge23/espan.c +++ b/components/badge23/espan.c @@ -8,6 +8,7 @@ #include "esp_log.h" #include "driver/i2c.h" #include "driver/spi_master.h" +#include <freertos/timers.h> #include <stdio.h> #include <string.h> @@ -33,6 +34,9 @@ static const char *TAG = "espan"; #error "i2c not implemented for this badge generation" #endif +static QueueHandle_t i2c_queue = NULL; +static uint8_t dummy_data; + static esp_err_t i2c_master_init(void) { int i2c_master_port = I2C_MASTER_NUM; @@ -54,6 +58,18 @@ static esp_err_t i2c_master_init(void) #define CAPTOUCH_POLLING_PERIOD 10 static uint8_t hw_init_done = 0; +void i2c_timer(TimerHandle_t data){ + xQueueSend(i2c_queue, &dummy_data, 0); +} + +void i2c_task(void * data){ + while(1){ + xQueueReceive(i2c_queue, &dummy_data, portMAX_DELAY); + captouch_read_cycle(); + update_button_state(); + } +} + void os_app_main(void) { ESP_LOGI(TAG, "Starting on %s...", badge23_hw_name); @@ -68,21 +84,20 @@ void os_app_main(void) //vTaskDelay(2000 / portTICK_PERIOD_MS); set_global_vol_dB(0); + captouch_force_calibration(); display_init(); - hw_init_done = 1; - while(1) { - manual_captouch_readout(1); - vTaskDelay((CAPTOUCH_POLLING_PERIOD) / portTICK_PERIOD_MS); - manual_captouch_readout(0); - vTaskDelay((CAPTOUCH_POLLING_PERIOD) / portTICK_PERIOD_MS); - update_button_state(); - vTaskDelay((CAPTOUCH_POLLING_PERIOD) / portTICK_PERIOD_MS); - //display_draw_scope(); - } - ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM)); - ESP_LOGI(TAG, "I2C de-initialized successfully"); + i2c_queue = xQueueCreate(1,1); + + TaskHandle_t i2c_task_handle; + //xTaskCreate(&i2c_task, "I2C task", 4096, NULL, configMAX_PRIORITIES , &i2c_task_handle); + xTaskCreatePinnedToCore(&i2c_task, "I2C task", 4096, NULL, configMAX_PRIORITIES-1, &i2c_task_handle, 0); + + + TimerHandle_t i2c_timer_handle = xTimerCreate("I2C timer", pdMS_TO_TICKS(CAPTOUCH_POLLING_PERIOD), pdTRUE, (void *) 0, *i2c_timer); + if( xTimerStart(i2c_timer_handle, 0 ) != pdPASS) ESP_LOGI(TAG, "I2C timer initialization failed"); + hw_init_done = 1; } uint8_t hardware_is_initialized(){ diff --git a/components/badge23/include/badge23/captouch.h b/components/badge23/include/badge23/captouch.h index d5dfd9412a..f62df4985f 100644 --- a/components/badge23/include/badge23/captouch.h +++ b/components/badge23/include/badge23/captouch.h @@ -1,10 +1,129 @@ #pragma once #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(); + + +/* 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); -void gpio_event_handler(void * arg); -void manual_captouch_readout(uint8_t top); -void captouch_get_cross(int paddle, int * x, int * y); -void captouch_force_calibration(); -uint16_t read_captouch(); diff --git a/python_payload/README.md b/python_payload/README.md index 6d55fc3950..e7bf206104 100644 --- a/python_payload/README.md +++ b/python_payload/README.md @@ -12,19 +12,10 @@ INSTRUMENT 1, CHORD ORGAN: all LEDs are lit up in the same color. each top petal INSTRUMENT 2, MELODY PLAYER: the 3 most down-pointing petal LEDs are lit in pink. these 3 petals select between 3 different octaves. depending on octave selection, the remaining petals are lit in blue (low octave), cyan (mid octave) and green (high octave). these "playing petals" provide tones in a major scale. it is a single oscillator system, so pressing more than one "playing petal" results in the oscillator jumping between pitches rapidly, providing a HIDDEN NOISE MODE. the screen is entirely black. author's note: this one didn't turn out well at all and could use a bunch more love. we find it valuable to provide people with a simple instrument to try to play their favorite melodies on, but this ain't it yet. -### current captouch issues +INSTRUMENT 3, WORMS: worms -the current firmware is built around AD7147 captouch controllers and uses their simplified output, where the controller autocalibrates and guesses whether a pad is being touched or not. since the controller was designed to have several mm of material in between (as for a stovetop), it sometimes is wayyyy to sensitive. +INSTRUMENT 4, CAP TOUCH DEBUG: shows 10 dots corresponding to the 10 petals. each gets bigger if the captouch threshold is exceeded (i.e., a touch is registered) and moves with the current position on the petal (1d for 2-segment petals, 2d for 3-segment petals). note that on p3/p4 the inner pad of the bottom petal opposed to the usb c port is currently not registered for technical reasons. -the captouch controller can be forced into recalibration by holding the right shoulder button down while in the menu, however it does keep some internal state and sometimes turning the badge off and on again is the only way to get acceptable captouch performance. +### captouch calibration: -in general, for best performance we recommend the following flow: -- hold the badge as you would hold it for playing (i.e., give it a reasonable initial calibration baseline), then plug in the USB cable on the other side to power up the badge -- wait for the menu to show -- play -- if issues occur or you switch hand position, do a manual recalibration and hope for the best -- if hope is lost powercycle - -the new captouch driver takes raw data from the captouch controller and processes it on the esp32. it is currently being worked on in the raw_captouch branch, but sadly only for p4 badges. - -also some individual pads on some revisions are not responding. the new driver is intended to fix that as well. +the captouch controller can be recalibrated by pressing the left shoulder button while in the menu. the screen shows the text "CAL" while in calibration. the screen background is teal for 0.5s to give the user time to remove their hands, then turns plum for the actual calibration. calibration is intended to get a baseline for pads that are not being touched at the moment, it is recommeded to lie the badge flat on the able while recalibrating. calibration is also performed at startup. diff --git a/python_payload/cap_touch_demo.py b/python_payload/cap_touch_demo.py new file mode 100644 index 0000000000..312b162c92 --- /dev/null +++ b/python_payload/cap_touch_demo.py @@ -0,0 +1,28 @@ +import hardware +import utils +import cmath +import math +import time + +def init(): + pass + +def run(): + hardware.display_fill(0) + time.sleep_ms(30) + 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 + rot = cmath.exp(2j *math.pi * i / 10) + x = x * rot + col = 0b1111100000011111 + if i%2: + col = 0b0000011111111111 + utils.draw_rect(int(x.imag+120-(size/2)),int(x.real+120-(size/2)),size,size,col) + hardware.display_update() + +def foreground(): + pass + diff --git a/python_payload/harmonic_demo.py b/python_payload/harmonic_demo.py index 70e99dfbcd..3207a09cd2 100644 --- a/python_payload/harmonic_demo.py +++ b/python_payload/harmonic_demo.py @@ -22,7 +22,6 @@ def set_chord(i): hue = int(72*(i+0.5)) % 360 set_led_hsv(j, hue, 1, 0.2) chord = chords[i] - print("set chord " +str(i)) update_leds() @@ -39,7 +38,6 @@ def run(): k = int(i/2) synths[k].tone(chord[k]) synths[k].start() - print("synth " +str(k)) def init(): global chord_index diff --git a/python_payload/main.py b/python_payload/main.py index d678944c29..98224b5356 100644 --- a/python_payload/main.py +++ b/python_payload/main.py @@ -4,11 +4,13 @@ import time import harmonic_demo import melodic_demo import demo_worms +import cap_touch_demo MODULES = [ harmonic_demo, melodic_demo, demo_worms, + cap_touch_demo, ] CURRENT_APP_RUN = None @@ -50,6 +52,7 @@ def foreground_menu(): utils.highlight_bottom_petal(0,0,55,55); utils.highlight_bottom_petal(1,55,0,55); utils.highlight_bottom_petal(2,55,55,0); + utils.highlight_bottom_petal(3,0,110,0); display_fill(BACKGROUND_COLOR) display_update() @@ -67,18 +70,36 @@ def set_rel_volume(vol): set_global_volume_dB(VOLUME) time.sleep_ms(100) +def captouch_cal(): + global ctx + display_fill(0b0000000111100111) + ctx.move_to(0,0).rgb(0,255,0).text("cal") + display_update() + time.sleep_ms(500) + display_fill(0b0011100000000111) + ctx.move_to(0,0).rgb(0,255,0).text("cal") + captouch_autocalib() + while(captouch_calibration_active()): + pass + display_fill(0) + display_update() + def main(): global CURRENT_APP_RUN global ctx while not init_done(): pass - captouch_autocalib() + captouch_autocalib() # dry run + while(captouch_calibration_active()): + pass ctx = get_ctx() ctx.text_align = ctx.CENTER ctx.text_baseline = ctx.MIDDLE + captouch_cal() + for module in MODULES: module.init() @@ -88,7 +109,7 @@ def main(): while True: if((get_button(1) == 2) and (CURRENT_APP_RUN == run_menu)): - captouch_autocalib() + captouch_cal() foreground_menu() else: if(get_button(0) == 2): diff --git a/usermodule/mp_hardware.c b/usermodule/mp_hardware.c index 110f082239..632d35ef4f 100644 --- a/usermodule/mp_hardware.c +++ b/usermodule/mp_hardware.c @@ -22,16 +22,21 @@ mp_obj_t mp_ctx_from_ctx(Ctx *ctx); mp_obj_t mp_ctx = NULL; -STATIC mp_obj_t mp_init_done(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t mp_init_done(void) { return mp_obj_new_int(hardware_is_initialized()); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_init_done_obj, 0, 1, mp_init_done); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_init_done_obj, mp_init_done); -STATIC mp_obj_t mp_display_update(size_t n_args, const mp_obj_t *args) { +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_update(void) { display_update(); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_display_update_obj, 0, 1, mp_display_update); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_display_update_obj, mp_display_update); STATIC mp_obj_t mp_display_draw_pixel(size_t n_args, const mp_obj_t *args) { uint16_t x = mp_obj_get_int(args[0]); @@ -65,11 +70,60 @@ STATIC mp_obj_t mp_get_captouch(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_get_captouch_obj, 1, 2, mp_get_captouch); -STATIC mp_obj_t mp_captouch_autocalib(size_t n_args, const mp_obj_t *args) { +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_VAR_BETWEEN(mp_captouch_autocalib_obj, 0, 2, mp_captouch_autocalib); +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_get_button(size_t n_args, const mp_obj_t *args) { uint8_t leftbutton = mp_obj_get_int(args[0]); @@ -151,8 +205,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_reset_ctx_obj, 0, 0, mp_reset_ctx) STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_badge_audio) }, { MP_ROM_QSTR(MP_QSTR_init_done), MP_ROM_PTR(&mp_init_done_obj) }, + { 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_get_button), MP_ROM_PTR(&mp_get_button_obj) }, { MP_ROM_QSTR(MP_QSTR_set_global_volume_dB), MP_ROM_PTR(&mp_set_global_volume_dB_obj) }, { MP_ROM_QSTR(MP_QSTR_count_sources), MP_ROM_PTR(&mp_count_sources_obj) }, -- GitLab