2024-04-24 14:50:24 +02:00
|
|
|
/*
|
|
|
|
* Chu Pico Silder Keys
|
|
|
|
* WHowe <github.com/whowechina>
|
|
|
|
*
|
|
|
|
* MPR121 CapSense based Keys
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "slider.h"
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
2024-11-17 04:39:44 +01:00
|
|
|
#include <stdio.h>
|
2024-04-24 14:50:24 +02:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "hardware/gpio.h"
|
|
|
|
#include "hardware/i2c.h"
|
|
|
|
|
|
|
|
#include "board_defs.h"
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "mpr121.h"
|
|
|
|
|
|
|
|
#define MPR121_ADDR 0x5A
|
|
|
|
|
|
|
|
static uint16_t readout[36];
|
|
|
|
static uint16_t touch[3];
|
|
|
|
static unsigned touch_count[36];
|
2024-11-17 04:39:44 +01:00
|
|
|
static bool present[3];
|
2024-04-24 14:50:24 +02:00
|
|
|
|
|
|
|
void slider_init()
|
|
|
|
{
|
|
|
|
i2c_init(I2C_PORT, I2C_FREQ);
|
|
|
|
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
|
|
|
|
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
|
|
|
|
gpio_pull_up(I2C_SDA);
|
|
|
|
gpio_pull_up(I2C_SCL);
|
|
|
|
|
|
|
|
for (int m = 0; m < 3; m++) {
|
2024-11-17 04:39:44 +01:00
|
|
|
present[m] = mpr121_init(MPR121_ADDR + m);
|
2024-04-24 14:50:24 +02:00
|
|
|
}
|
|
|
|
slider_update_config();
|
|
|
|
}
|
|
|
|
|
2024-11-17 04:39:44 +01:00
|
|
|
const char *slider_sensor_status()
|
|
|
|
{
|
|
|
|
static char status[64];
|
|
|
|
snprintf(status, sizeof(status), "Sensors: %02X:%s %02X:%s %02X:%s",
|
|
|
|
MPR121_ADDR, present[0] ? "OK" : "ERR",
|
|
|
|
MPR121_ADDR + 1, present[1] ? "OK" : "ERR",
|
|
|
|
MPR121_ADDR + 2, present[2] ? "OK" : "ERR");
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2024-04-24 14:50:24 +02:00
|
|
|
void slider_update()
|
|
|
|
{
|
|
|
|
static uint16_t last_touched[3];
|
|
|
|
|
|
|
|
touch[0] = mpr121_touched(MPR121_ADDR);
|
|
|
|
touch[1] = mpr121_touched(MPR121_ADDR + 1);
|
|
|
|
touch[2] = mpr121_touched(MPR121_ADDR + 2);
|
|
|
|
|
|
|
|
for (int m = 0; m < 3; m++) {
|
|
|
|
uint16_t just_touched = touch[m] & ~last_touched[m];
|
|
|
|
last_touched[m] = touch[m];
|
|
|
|
for (int i = 0; i < 12; i++) {
|
|
|
|
if (just_touched & (1 << i)) {
|
|
|
|
touch_count[m * 12 + i]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint16_t *slider_raw()
|
|
|
|
{
|
|
|
|
mpr121_raw(MPR121_ADDR, readout, 12);
|
|
|
|
mpr121_raw(MPR121_ADDR + 1, readout + 12, 12);
|
|
|
|
mpr121_raw(MPR121_ADDR + 2, readout + 24, 12);
|
|
|
|
return readout;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool slider_touched(unsigned key)
|
|
|
|
{
|
|
|
|
if (key >= 32) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return touch[key / 12] & (1 << (key % 12));
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned slider_count(unsigned key)
|
|
|
|
{
|
|
|
|
if (key >= 32) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return touch_count[key];
|
|
|
|
}
|
|
|
|
|
|
|
|
void slider_reset_stat()
|
|
|
|
{
|
|
|
|
memset(touch_count, 0, sizeof(touch_count));
|
|
|
|
}
|
|
|
|
|
|
|
|
void slider_update_config()
|
|
|
|
{
|
|
|
|
for (int m = 0; m < 3; m++) {
|
|
|
|
mpr121_debounce(MPR121_ADDR + m, chu_cfg->sense.debounce_touch,
|
|
|
|
chu_cfg->sense.debounce_release);
|
|
|
|
mpr121_sense(MPR121_ADDR + m, chu_cfg->sense.global,
|
|
|
|
chu_cfg->sense.keys + m * 12,
|
|
|
|
m != 2 ? 12 : 8);
|
|
|
|
mpr121_filter(MPR121_ADDR + m, chu_cfg->sense.filter >> 6,
|
|
|
|
(chu_cfg->sense.filter >> 4) & 0x03,
|
|
|
|
chu_cfg->sense.filter & 0x07);
|
|
|
|
}
|
|
|
|
}
|