1212#include "py/mphal.h"
1313#include "shared-bindings/touchio/TouchIn.h"
1414#include "shared-bindings/microcontroller/Pin.h"
15+ #include "shared-bindings/digitalio/Pull.h"
1516
16- // This is a capacitive touch sensing routine using a single digital
17- // pin. The pin should be connected to the sensing pad, and to ground
17+ // This is a capacitive touch sensing routine using a single digital pin.
18+ // For pull==PULL_DOWN, the pin should be connected to the sensing pad and to ground
1819// via a 1Mohm or thereabout drain resistor. When a reading is taken,
1920// the pin's capacitance is charged by setting it to a digital output
2021// 'high' for a few microseconds, and then it is changed to a high
2122// impedance input. We measure how long it takes to discharge through
2223// the resistor (around 50us), using a busy-waiting loop, and average
2324// over N_SAMPLES cycles to reduce the effects of noise.
25+ // For the pull=PULL_UP case, the 1M resistor is connected to 3v3, the pin is
26+ // driven 'low' then measure how long it takes to go 'high'.
2427
2528#define N_SAMPLES 10
2629#define TIMEOUT_TICKS 10000
2730
2831static uint16_t get_raw_reading (touchio_touchin_obj_t * self ) {
2932
3033 uint16_t ticks = 0 ;
31-
34+ // state to charge pin to: if pull-down or None, pull HIGH, if pull-up, pull LOW
35+ bool pincharge = !(self -> pull == PULL_UP );
3236 for (uint16_t i = 0 ; i < N_SAMPLES ; i ++ ) {
33- // set pad to digital output high for 10us to charge it
37+ // set pad to digital output 'pincharge' for 10us to charge it
3438
35- common_hal_digitalio_digitalinout_switch_to_output (self -> digitalinout , true , DRIVE_MODE_PUSH_PULL );
39+ common_hal_digitalio_digitalinout_switch_to_output (self -> digitalinout , pincharge , DRIVE_MODE_PUSH_PULL );
3640 mp_hal_delay_us (10 );
3741
3842 // set pad back to an input and take some samples
3943
4044 common_hal_digitalio_digitalinout_switch_to_input (self -> digitalinout , PULL_NONE );
4145
42- while (common_hal_digitalio_digitalinout_get_value (self -> digitalinout )) {
46+ while (common_hal_digitalio_digitalinout_get_value (self -> digitalinout ) == pincharge ) {
4347 if (ticks >= TIMEOUT_TICKS ) {
4448 return TIMEOUT_TICKS ;
4549 }
@@ -49,16 +53,22 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
4953 return ticks ;
5054}
5155
52- void common_hal_touchio_touchin_construct (touchio_touchin_obj_t * self , const mcu_pin_obj_t * pin ) {
56+ void common_hal_touchio_touchin_construct (touchio_touchin_obj_t * self , const mcu_pin_obj_t * pin , const digitalio_pull_t pull ) {
5357 common_hal_mcu_pin_claim (pin );
5458 self -> digitalinout = mp_obj_malloc (digitalio_digitalinout_obj_t , & digitalio_digitalinout_type );
5559
5660 common_hal_digitalio_digitalinout_construct (self -> digitalinout , pin );
5761
62+ self -> pull = pull ;
63+
5864 uint16_t raw_reading = get_raw_reading (self );
5965 if (raw_reading == TIMEOUT_TICKS ) {
6066 common_hal_touchio_touchin_deinit (self );
61- mp_raise_ValueError (MP_ERROR_TEXT ("No pulldown on pin; 1Mohm recommended" ));
67+ if (self -> pull == PULL_UP ) {
68+ mp_raise_ValueError (MP_ERROR_TEXT ("No pullup on pin; 1Mohm recommended" ));
69+ } else {
70+ mp_raise_ValueError (MP_ERROR_TEXT ("No pulldown on pin; 1Mohm recommended" ));
71+ }
6272 }
6373 self -> threshold = raw_reading * 1.05 + 100 ;
6474}
0 commit comments