Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,10 @@ msgstr ""
msgid "No pulldown on pin; 1Mohm recommended"
msgstr ""

#: shared-module/touchio/TouchIn.c
msgid "No pullup on pin; 1Mohm recommended"
msgstr ""

#: py/moderrno.c
msgid "No space left on device"
msgstr ""
Expand Down Expand Up @@ -2577,7 +2581,8 @@ msgstr ""
msgid "bits must be 32 or less"
msgstr ""

#: shared-bindings/audiodelays/Echo.c shared-bindings/audiodelays/PitchShift.c
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
#: shared-bindings/audiodelays/PitchShift.c
#: shared-bindings/audiofilters/Distortion.c
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
msgid "bits_per_sample must be 8 or 16"
Expand Down
3 changes: 2 additions & 1 deletion ports/atmel-samd/common-hal/touchio/TouchIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "py/binary.h"
#include "py/mphal.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/Pull.h"
#include "shared-bindings/touchio/TouchIn.h"

// Native touchio only exists for SAMD21
Expand All @@ -38,7 +39,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
}

void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self,
const mcu_pin_obj_t *pin) {
const mcu_pin_obj_t *pin, const digitalio_pull_t pull) {
if (!pin->has_touch) {
raise_ValueError_invalid_pin();
}
Expand Down
3 changes: 2 additions & 1 deletion ports/espressif/common-hal/touchio/TouchIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
#include "py/runtime.h"
#include "peripherals/touch.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/Pull.h"

void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self,
const mcu_pin_obj_t *pin) {
const mcu_pin_obj_t *pin, const digitalio_pull_t pull) {
if (pin->touch_channel == NO_TOUCH_CHANNEL) {
raise_ValueError_invalid_pin();
}
Expand Down
4 changes: 0 additions & 4 deletions ports/raspberrypi/mpconfigport.mk
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ CIRCUITPY_ALARM = 0
# Default PICODVI on because it doesn't require much code in RAM to talk to HSTX.
CIRCUITPY_PICODVI ?= 1

# Our generic touchio uses a pull down and RP2350 A2 hardware doesn't work correctly.
# So, turn touchio off because it doesn't work.
CIRCUITPY_TOUCHIO = 0

# delay in ms before calling cyw43_arch_init_with_country
CIRCUITPY_CYW43_INIT_DELAY ?= 0

Expand Down
21 changes: 14 additions & 7 deletions shared-bindings/touchio/TouchIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,29 @@
//| print("touched!")"""
//|

//| def __init__(self, pin: microcontroller.Pin) -> None:
//| def __init__(self, pin: microcontroller.Pin, pull: Optional[digitalio.Pull] = None) -> None:
//| """Use the TouchIn on the given pin.
//|
//| :param ~microcontroller.Pin pin: the pin to read from"""
//| :param Optional[digitalio.Pull] pull: specify external pull resistor type. If None, assume pull-down or chip-specific implementation
//| ...
//|
static mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw, const mp_obj_t *args) {
// check number of arguments
mp_arg_check_num(n_args, n_kw, 1, 1, false);
size_t n_args, size_t n_kw, const mp_obj_t *all_args) {

// 1st argument is the pin
const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0], MP_QSTR_pin);
enum { ARG_pin, ARG_pull };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_pin, MP_ARG_OBJ | MP_ARG_REQUIRED },
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin);
const digitalio_pull_t pull = validate_pull(args[ARG_pull].u_obj, MP_QSTR_pull);

touchio_touchin_obj_t *self = mp_obj_malloc(touchio_touchin_obj_t, &touchio_touchin_type);
common_hal_touchio_touchin_construct(self, pin);
common_hal_touchio_touchin_construct(self, pin, pull);

return (mp_obj_t)self;
}
Expand Down
3 changes: 2 additions & 1 deletion shared-bindings/touchio/TouchIn.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include "common-hal/microcontroller/Pin.h"
#include "shared-bindings/digitalio/Pull.h"

#if CIRCUITPY_TOUCHIO_USE_NATIVE
#include "common-hal/touchio/TouchIn.h"
Expand All @@ -16,7 +17,7 @@

extern const mp_obj_type_t touchio_touchin_type;

void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin);
void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin, digitalio_pull_t pull);
void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self);
bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t *self);
bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self);
Expand Down
5 changes: 3 additions & 2 deletions shared-bindings/touchio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
//| For more information about working with the `touchio` module in CircuitPython,
//| see `this Learn guide page <https://learn.adafruit.com/circuitpython-essentials/circuitpython-cap-touch>`_.
//|
//| **Limitations**: `touchio` is available on Raspberry Pi RP2040 builds,
//| but not on RP2350, due to GPIO hardware limitations.
//| **Limitations**: `touchio` on RP2350 must have a pull-up resistor to 3.3V
//| instead of ground and set the `pull=Pull.UP` parameter when constructing
//| a `TouchIn` object, due to GPIO hardware limitations.
//|
//| Example::
//|
Expand Down
26 changes: 18 additions & 8 deletions shared-module/touchio/TouchIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,38 @@
#include "py/mphal.h"
#include "shared-bindings/touchio/TouchIn.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/Pull.h"

// This is a capacitive touch sensing routine using a single digital
// pin. The pin should be connected to the sensing pad, and to ground
// This is a capacitive touch sensing routine using a single digital pin.
// For pull==PULL_DOWN, the pin should be connected to the sensing pad and to ground
// via a 1Mohm or thereabout drain resistor. When a reading is taken,
// the pin's capacitance is charged by setting it to a digital output
// 'high' for a few microseconds, and then it is changed to a high
// impedance input. We measure how long it takes to discharge through
// the resistor (around 50us), using a busy-waiting loop, and average
// over N_SAMPLES cycles to reduce the effects of noise.
// For the pull=PULL_UP case, the 1M resistor is connected to 3v3, the pin is
// driven 'low' then measure how long it takes to go 'high'.

#define N_SAMPLES 10
#define TIMEOUT_TICKS 10000

static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {

uint16_t ticks = 0;

// state to charge pin to: if pull-down or None, pull HIGH, if pull-up, pull LOW
bool pincharge = !(self->pull == PULL_UP);
for (uint16_t i = 0; i < N_SAMPLES; i++) {
// set pad to digital output high for 10us to charge it
// set pad to digital output 'pincharge' for 10us to charge it

common_hal_digitalio_digitalinout_switch_to_output(self->digitalinout, true, DRIVE_MODE_PUSH_PULL);
common_hal_digitalio_digitalinout_switch_to_output(self->digitalinout, pincharge, DRIVE_MODE_PUSH_PULL);
mp_hal_delay_us(10);

// set pad back to an input and take some samples

common_hal_digitalio_digitalinout_switch_to_input(self->digitalinout, PULL_NONE);

while (common_hal_digitalio_digitalinout_get_value(self->digitalinout)) {
while (common_hal_digitalio_digitalinout_get_value(self->digitalinout) == pincharge) {
if (ticks >= TIMEOUT_TICKS) {
return TIMEOUT_TICKS;
}
Expand All @@ -49,16 +53,22 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
return ticks;
}

void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin) {
void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin, const digitalio_pull_t pull) {
common_hal_mcu_pin_claim(pin);
self->digitalinout = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type);

common_hal_digitalio_digitalinout_construct(self->digitalinout, pin);

self->pull = pull;

uint16_t raw_reading = get_raw_reading(self);
if (raw_reading == TIMEOUT_TICKS) {
common_hal_touchio_touchin_deinit(self);
mp_raise_ValueError(MP_ERROR_TEXT("No pulldown on pin; 1Mohm recommended"));
if (self->pull == PULL_UP) {
mp_raise_ValueError(MP_ERROR_TEXT("No pullup on pin; 1Mohm recommended"));
} else {
mp_raise_ValueError(MP_ERROR_TEXT("No pulldown on pin; 1Mohm recommended"));
}
}
self->threshold = raw_reading * 1.05 + 100;
}
Expand Down
1 change: 1 addition & 0 deletions shared-module/touchio/TouchIn.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
typedef struct {
mp_obj_base_t base;
digitalio_digitalinout_obj_t *digitalinout;
digitalio_pull_t pull;
uint16_t threshold;
} touchio_touchin_obj_t;

Expand Down
Loading