Skip to content

Add touchio pullup rp2350 #10227

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -1560,6 +1560,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 @@ -2582,7 +2586,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
24 changes: 16 additions & 8 deletions shared-bindings/touchio/TouchIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,30 @@
//| 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 ~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 that does not require a pull.
//| """
//| ...
//|
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
8 changes: 5 additions & 3 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 All @@ -40,7 +41,8 @@
//| print(touch_pin.value)
//|
//| This example will initialize the the device, and print the
//| :py:data:`~touchio.TouchIn.value`."""
//| :py:data:`~touchio.TouchIn.value`.
//| """

static const mp_rom_map_elem_t touchio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_touchio) },
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