171 lines
5.4 KiB
C
171 lines
5.4 KiB
C
|
/***************************************************************************
|
||
|
* __________ __ ___.
|
||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||
|
* \/ \/ \/ \/ \/
|
||
|
* $Id$
|
||
|
*
|
||
|
* Copyright (C) 2012 Amaury Pouly
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||
|
* KIND, either express or implied.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
/** Driver for the Freescale MPR121 Capacitive Proximity Sensor */
|
||
|
#include "system.h"
|
||
|
|
||
|
#define ELECTRODE_COUNT 12
|
||
|
#define ELE_GPIO_FIRST 4
|
||
|
#define ELE_GPIO_LAST 11
|
||
|
|
||
|
/* gpio config (encoding: [0]=en,[1]=dir,[2]=ctl[1],[3]=ctl[0]) */
|
||
|
#define ELE_GPIO_DISABLE 0
|
||
|
#define ELE_GPIO_INPUT 1
|
||
|
#define ELE_GPIO_INPUT_PULLDOWN 9 /* input with pull-down */
|
||
|
#define ELE_GPIO_INPUT_PULLUP 13 /* input with pull-up */
|
||
|
#define ELE_GPIO_OUTPUT 3
|
||
|
#define ELE_GPIO_OUTPUT_OPEN 11 /* open drain low-side */
|
||
|
#define ELE_GPIO_OUTPUT_OPEN_LED 15 /* open drain high-side (led driver) */
|
||
|
|
||
|
/* internal use */
|
||
|
#define ELE_GPIO_EN(val) ((val) & 1)
|
||
|
#define ELE_GPIO_DIR(val) (((val) >> 1) & 1)
|
||
|
#define ELE_GPIO_CTL0(val) (((val) >> 3) & 1)
|
||
|
#define ELE_GPIO_CTL1(val) (((val) >> 1) & 1)
|
||
|
|
||
|
struct mpr121_electrode_config_t
|
||
|
{
|
||
|
uint8_t bv; /* baseline value */
|
||
|
uint8_t tth; /* touch threshold */
|
||
|
uint8_t rth; /* release threshold */
|
||
|
uint8_t cdc; /* charge current (optional if auto-conf) */
|
||
|
uint8_t cdt; /* charge time (optional if auto-conf) */
|
||
|
int gpio; /* gpio config */
|
||
|
};
|
||
|
|
||
|
struct mpr121_baseline_filter_config_t
|
||
|
{
|
||
|
uint8_t mhd; /* max half delta (except for touched) */
|
||
|
uint8_t nhd; /* noise half delta */
|
||
|
uint8_t ncl; /* noise count limit */
|
||
|
uint8_t fdl; /* filter delay count limit */
|
||
|
};
|
||
|
|
||
|
struct mpr121_baseline_filters_config_t
|
||
|
{
|
||
|
struct mpr121_baseline_filter_config_t rising;
|
||
|
struct mpr121_baseline_filter_config_t falling;
|
||
|
struct mpr121_baseline_filter_config_t touched;
|
||
|
};
|
||
|
|
||
|
struct mpr121_debounce_config_t
|
||
|
{
|
||
|
uint8_t dt; /* debounce count for touch */
|
||
|
uint8_t dr; /* debounce count for release */
|
||
|
};
|
||
|
|
||
|
/* first filter iterations */
|
||
|
#define FFI_6_SAMPLES 0
|
||
|
#define FFI_10_SAMPLES 1
|
||
|
#define FFI_18_SAMPLES 2
|
||
|
#define FFI_34_SAMPLES 3
|
||
|
/* charge discharge current */
|
||
|
#define CDC_DISABLE 0
|
||
|
#define CDC_uA(ua) (ua)
|
||
|
/* charge discharge time */
|
||
|
#define CDT_DISABLE 0
|
||
|
#define CDT_log_us(lus) (lus) /* actual value = 2^{us-2} µs */
|
||
|
/* second filter iterations */
|
||
|
#define SFI_4_SAMPLES 0
|
||
|
#define SFI_6_SAMPLES 1
|
||
|
#define SFI_10_SAMPLES 2
|
||
|
#define SFI_18_SAMPLES 3
|
||
|
/* Eletrode sample interval */
|
||
|
#define ESI_log_ms(lms) (lms) /* actual value = 2^{lms} ms */
|
||
|
|
||
|
struct mpr121_global_config_t
|
||
|
{
|
||
|
uint8_t ffi; /* first filter iterations */
|
||
|
uint8_t cdc; /* global charge discharge current */
|
||
|
uint8_t cdt; /* global charge discharge time */
|
||
|
uint8_t sfi; /* second first iterations */
|
||
|
uint8_t esi; /* electrode sample interval */
|
||
|
};
|
||
|
|
||
|
#define RETRY_NEVER 0
|
||
|
#define RETRY_2_TIMES 1
|
||
|
#define RETRY_4_TIMES 2
|
||
|
#define RETRY_8_TIMES 3
|
||
|
|
||
|
struct mpr121_auto_config_t
|
||
|
{
|
||
|
bool en; /* auto-conf enable */
|
||
|
bool ren; /* auto-reconf enable */
|
||
|
uint8_t retry; /* retry count */
|
||
|
bool scts; /* skip charge time search */
|
||
|
uint8_t usl; /* upper-side limit */
|
||
|
uint8_t lsl; /* lower-side limit */
|
||
|
uint8_t tl; /* target level */
|
||
|
bool acfie; /* auto-conf fail interrupt en */
|
||
|
bool arfie; /* auto-reconf fail interrupt en */
|
||
|
bool oorie; /* out of range interrupt en */
|
||
|
};
|
||
|
|
||
|
/* electrode mode */
|
||
|
#define ELE_DISABLE 0
|
||
|
#define ELE_EN0_x(x) ((x) + 1)
|
||
|
/* eleprox mode */
|
||
|
#define ELEPROX_DISABLE 0
|
||
|
#define ELEPROX_EN0_1 1
|
||
|
#define ELEPROX_EN0_3 2
|
||
|
#define ELEPROX_EN0_11 3
|
||
|
/* calibration lock */
|
||
|
#define CL_SLOW_TRACK 0
|
||
|
#define CL_DISABLE 1
|
||
|
#define CL_TRACK 2
|
||
|
#define CL_FAST_TRACK 3
|
||
|
|
||
|
struct mpr121_config_t
|
||
|
{
|
||
|
struct mpr121_electrode_config_t ele[ELECTRODE_COUNT];
|
||
|
struct mpr121_electrode_config_t eleprox;
|
||
|
struct
|
||
|
{
|
||
|
struct mpr121_baseline_filters_config_t ele;
|
||
|
struct mpr121_baseline_filters_config_t eleprox;
|
||
|
}filters;
|
||
|
struct mpr121_debounce_config_t debounce;
|
||
|
struct mpr121_global_config_t global;
|
||
|
struct mpr121_auto_config_t autoconf;
|
||
|
uint8_t ele_en; /* eletroce mode */
|
||
|
uint8_t eleprox_en; /* proximity mode */
|
||
|
uint8_t cal_lock; /* calibration lock */
|
||
|
};
|
||
|
|
||
|
/* gpio value */
|
||
|
#define ELE_GPIO_CLR 0
|
||
|
#define ELE_GPIO_SET 1
|
||
|
#define ELE_GPIO_TOG 2
|
||
|
/* pwm value */
|
||
|
#define ELE_PWM_DISABLE 0
|
||
|
#define ELE_PWM_DUTY(x) (x)
|
||
|
#define ELE_PWM_MIN_DUTY 1
|
||
|
#define ELE_PWM_MAX_DUTY 15
|
||
|
|
||
|
int mpr121_init(int dev_i2c_addr);
|
||
|
int mpr121_soft_reset(void);
|
||
|
int mpr121_set_config(struct mpr121_config_t *conf);
|
||
|
/* gpios are only implemented for electrode>=4 */
|
||
|
int mpr121_set_gpio_output(int ele, int gpio_val);
|
||
|
int mpr121_set_gpio_pwm(int ele, int pwm);
|
||
|
/* get electrode status (bitmap) */
|
||
|
int mpr121_get_touch_status(unsigned *status);
|