Skip to content

Commit 4a09329

Browse files
committed
hugely simplified version of the touchio.TouchIn.get_raw_reading code (adafruit#1048)
1 parent 1dc4c47 commit 4a09329

1 file changed

Lines changed: 15 additions & 99 deletions

File tree

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

Lines changed: 15 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -37,120 +37,36 @@
3737
#include "supervisor/shared/translate.h"
3838

3939
#include "nrf.h"
40-
#include "nrfx/hal/nrf_saadc.h"
4140

42-
#include "tick.h"
43-
44-
bool touch_enabled = false;
45-
46-
#define CHANNEL_NO 0
4741
#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-
}
42+
#define TIMEOUT_US 10000
7343

7444
static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
7545

76-
nrf_saadc_value_t samples[N_SAMPLES];
77-
78-
// Configure analog input.
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.
82-
83-
const nrf_saadc_channel_config_t config = {
84-
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
85-
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
86-
.gain = NRF_SAADC_GAIN1_6,
87-
.reference = NRF_SAADC_REFERENCE_INTERNAL,
88-
.acq_time = NRF_SAADC_ACQTIME_3US,
89-
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
90-
.burst = NRF_SAADC_BURST_DISABLED,
91-
.pin_p = NRF_SAADC_INPUT_VDD,
92-
.pin_n = NRF_SAADC_INPUT_VDD,
93-
};
94-
95-
nrf_saadc_resolution_set(NRF_SAADC_RESOLUTION_14BIT);
96-
nrf_saadc_oversample_set(NRF_SAADC_OVERSAMPLE_DISABLED);
97-
nrf_saadc_enable();
46+
uint16_t ticks = 0;
9847

99-
for (uint32_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; i++)
100-
nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
48+
for (uint16_t i = 0; i < N_SAMPLES; i++) {
49+
// set pad to digital output high for 10us to charge it
10150

102-
nrf_saadc_channel_init(CHANNEL_NO, &config);
103-
nrf_saadc_buffer_init(samples, N_SAMPLES);
51+
nrf_gpio_cfg_output(self->pin->number);
52+
nrf_gpio_pin_set(self->pin->number);
53+
mp_hal_delay_us(10);
10454

105-
// set pad to digital output high for 10us to charge it
55+
// set pad back to an input and take some samples
10656

107-
nrf_gpio_cfg_output(self->pin->number);
108-
nrf_gpio_pin_set(self->pin->number);
57+
nrf_gpio_cfg_input(self->pin->number, NRF_GPIO_PIN_NOPULL);
10958

110-
mp_hal_delay_us(10);
111-
112-
// set pad back to an input and take some samples
113-
// IRQs are suspended to make sure our samples are at fixed times.
114-
115-
__disable_irq();
116-
117-
nrf_saadc_channel_input_set(CHANNEL_NO, self->pin->adc_channel, self->pin->adc_channel);
118-
119-
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
120-
while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0);
121-
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
122-
123-
// XXX surely there's a better way? PPI?
124-
for (uint32_t i = 0; i < N_SAMPLES; i++) {
125-
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
126-
while (nrf_saadc_event_check(NRF_SAADC_EVENT_DONE) == 0);
127-
nrf_saadc_event_clear(NRF_SAADC_EVENT_DONE);
59+
while(nrf_gpio_pin_read(self->pin->number)) {
60+
if (ticks >= TIMEOUT_US) return TIMEOUT_US;
61+
ticks++;
62+
mp_hal_delay_us(1);
63+
}
12864
}
129-
130-
__enable_irq();
131-
132-
nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
133-
while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0);
134-
nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
135-
136-
// turn off SAADC & set output pin low (to minimize leakage currents)
137-
138-
nrf_gpio_pin_clear(self->pin->number);
139-
140-
nrf_saadc_channel_input_set(CHANNEL_NO, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
141-
nrf_saadc_disable();
142-
143-
nrf_gpio_cfg_output(self->pin->number);
144-
145-
return process_samples(samples, N_SAMPLES);
146-
65+
return ticks;
14766
}
14867

14968
void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self,
15069
const mcu_pin_obj_t *pin) {
151-
if (!pin->adc_channel) {
152-
mp_raise_ValueError(translate("Invalid pin"));
153-
}
15470
self->pin = pin;
15571
claim_pin(pin);
15672
}

0 commit comments

Comments
 (0)