Skip to content

Commit 1dc4c47

Browse files
committed
touchio.TouchIn sensing working on a single pin! adafruit#1048
1 parent 901db47 commit 1dc4c47

1 file changed

Lines changed: 34 additions & 21 deletions

File tree

ports/nrf/common-hal/touchio/TouchIn.c

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,40 @@ bool touch_enabled = false;
4545

4646
#define CHANNEL_NO 0
4747
#define N_SAMPLES 10
48+
#define K_FACTOR 100000000L
49+
50+
static uint16_t process_samples(nrf_saadc_value_t samples[], int n_samples) {
51+
// XXX sort of like a least squares fit here, with the assumption
52+
// that the timing ('x') is stable (thus we suspend interrupts while
53+
// taking these measurements)
54+
55+
int32_t sumy = 0;
56+
int32_t sumxy = 0;
57+
58+
for (int i = 0; i < N_SAMPLES; i++) {
59+
sumy += samples[i];
60+
sumxy += i*samples[i];
61+
}
62+
63+
// we don't really care about the units, and so we can cut out a
64+
// whole bunch of stuff which is based only on N_SAMPLES, eg:
65+
// n, sum(x), sum(x^2) and sum(x)^2 terms. This leaves only:
66+
67+
int16_t m = (N_SAMPLES - 1) * sumy / 2 - sumxy;
68+
69+
// m is proportional to the charge rate of the capacitor which is
70+
// in reciprocal proportion to the actual capacitance.
71+
return (uint16_t)(K_FACTOR / m);
72+
}
4873

4974
static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
5075

5176
nrf_saadc_value_t samples[N_SAMPLES];
5277

5378
// Configure analog input.
54-
// XXX cloned from AnalogIn and probably overkill
79+
// XXX analogio.AnalogIn and this class both use SAADC channel 0
80+
// all the time and never any other channel. This seems a bit
81+
// silly.
5582

5683
const nrf_saadc_channel_config_t config = {
5784
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
@@ -75,14 +102,15 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
75102
nrf_saadc_channel_init(CHANNEL_NO, &config);
76103
nrf_saadc_buffer_init(samples, N_SAMPLES);
77104

78-
// set pad to digital output high for 20us to charge it
105+
// set pad to digital output high for 10us to charge it
79106

80107
nrf_gpio_cfg_output(self->pin->number);
81108
nrf_gpio_pin_set(self->pin->number);
82109

83-
mp_hal_delay_us(20);
110+
mp_hal_delay_us(10);
84111

85112
// set pad back to an input and take some samples
113+
// IRQs are suspended to make sure our samples are at fixed times.
86114

87115
__disable_irq();
88116

@@ -92,7 +120,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
92120
while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0);
93121
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
94122

95-
// XXX surely there's a better way
123+
// XXX surely there's a better way? PPI?
96124
for (uint32_t i = 0; i < N_SAMPLES; i++) {
97125
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
98126
while (nrf_saadc_event_check(NRF_SAADC_EVENT_DONE) == 0);
@@ -105,7 +133,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
105133
while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0);
106134
nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
107135

108-
// turn off SAADC & set output pin low
136+
// turn off SAADC & set output pin low (to minimize leakage currents)
109137

110138
nrf_gpio_pin_clear(self->pin->number);
111139

@@ -114,23 +142,8 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
114142

115143
nrf_gpio_cfg_output(self->pin->number);
116144

117-
int32_t sumy = 0;
118-
int32_t sumxy = 0;
119-
120-
//mp_printf(MP_PYTHON_PRINTER, "touch");
121-
122-
// XXX sort of like a least squares fit here
123-
124-
for (int i = 0; i < N_SAMPLES; i++) {
125-
//mp_printf(MP_PYTHON_PRINTER, " %d", samples[i]);
126-
sumy += samples[i];
127-
sumxy += i*samples[i];
128-
}
129-
int32_t r = (N_SAMPLES - 1) * sumy / 2 - sumxy;
130-
131-
//mp_printf(MP_PYTHON_PRINTER, " -> %d %d -> %d\n", sumy, sumxy, r);
145+
return process_samples(samples, N_SAMPLES);
132146

133-
return (uint16_t)r;
134147
}
135148

136149
void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self,

0 commit comments

Comments
 (0)