Skip to content

zephyr: Construct Pin object with a port instance number. #10859

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

Closed
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
10 changes: 5 additions & 5 deletions docs/zephyr/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Use the :ref:`machine.Pin <machine.Pin>` class::

from machine import Pin

pin = Pin(("GPIO_1", 21), Pin.IN) # create input pin on GPIO1
pin = Pin((1, 21), Pin.IN) # create input pin on GPIO1
print(pin) # print pin port and number

pin.init(Pin.OUT, Pin.PULL_UP, value=1) # reinitialize pin
Expand All @@ -47,13 +47,13 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
pin.on() # set pin to high
pin.off() # set pin to low

pin = Pin(("GPIO_1", 21), Pin.IN) # create input pin on GPIO1
pin = Pin((1, 21), Pin.IN) # create input pin on GPIO1

pin = Pin(("GPIO_1", 21), Pin.OUT, value=1) # set pin high on creation
pin = Pin((1, 21), Pin.OUT, value=1) # set pin high on creation

pin = Pin(("GPIO_1", 21), Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
pin = Pin((1, 21), Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor

switch = Pin(("GPIO_2", 6), Pin.IN) # create input pin for a switch
switch = Pin((2, 6), Pin.IN) # create input pin for a switch
switch.irq(lambda t: print("SW2 changed")) # enable an interrupt when switch state is changed

Hardware I2C bus
Expand Down
6 changes: 3 additions & 3 deletions ports/zephyr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ To blink an LED:
import time
from machine import Pin

LED = Pin(("GPIO_1", 21), Pin.OUT)
LED = Pin((1, 21), Pin.OUT)
while True:
LED.value(1)
time.sleep(0.5)
Expand All @@ -120,8 +120,8 @@ To respond to Pin change IRQs, on a FRDM-K64F board run:

from machine import Pin

SW2 = Pin(("GPIO_2", 6), Pin.IN)
SW3 = Pin(("GPIO_0", 4), Pin.IN)
SW2 = Pin((2, 6), Pin.IN)
SW3 = Pin((0, 4), Pin.IN)

SW2.irq(lambda t: print("SW2 changed"))
SW3.irq(lambda t: print("SW3 changed"))
Expand Down
15 changes: 15 additions & 0 deletions ports/zephyr/boards/frdm_k64f.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2023 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
chosen {
micropython,machine-pin0 = &gpioa;
micropython,machine-pin1 = &gpiob;
micropython,machine-pin2 = &gpioc;
micropython,machine-pin3 = &gpiod;
micropython,machine-pin4 = &gpioe;
};
};
20 changes: 17 additions & 3 deletions ports/zephyr/machine_pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ typedef struct _machine_pin_irq_obj_t {
STATIC const mp_irq_methods_t machine_pin_irq_methods;
const mp_obj_base_t machine_pin_obj_template = {&machine_pin_type};

#define PIN_DEVICE(i, _) MICROPYTHON_CHOSEN_DEVICE(machine_pin, i, _)

STATIC const struct device *const machine_pin_devices[] = {LISTIFY(8, PIN_DEVICE, ())};

void machine_pin_deinit(void) {
for (machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_list); irq != NULL; irq = irq->next) {
machine_pin_obj_t *pin = MP_OBJ_TO_PTR(irq->base.parent);
Expand Down Expand Up @@ -130,13 +134,23 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
}
mp_obj_t *items;
mp_obj_get_array_fixed_n(args[0], 2, &items);
const char *drv_name = mp_obj_str_get_str(items[0]);
int wanted_pin = mp_obj_get_int(items[1]);
const struct device *wanted_port = device_get_binding(drv_name);

const struct device *wanted_port = NULL;
if (mp_obj_is_int(items[0])) {
int drv_instance = mp_obj_get_int(items[0]);
if (drv_instance < ARRAY_SIZE(machine_pin_devices)) {
wanted_port = machine_pin_devices[drv_instance];
}
} else {
const char *drv_name = mp_obj_str_get_str(items[0]);
wanted_port = device_get_binding(drv_name);
}
if (!wanted_port) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid port"));
}

int wanted_pin = mp_obj_get_int(items[1]);

machine_pin_obj_t *pin = m_new_obj(machine_pin_obj_t);
pin->base = machine_pin_obj_template;
pin->port = wanted_port;
Expand Down
7 changes: 7 additions & 0 deletions ports/zephyr/modmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

#include "py/obj.h"

#define MICROPYTHON_CHOSEN(prop, i) \
DT_CHOSEN(DT_CAT3(micropython_, prop, i))

#define MICROPYTHON_CHOSEN_DEVICE(prop, i, _) \
IF_ENABLED(DT_NODE_EXISTS(MICROPYTHON_CHOSEN(prop, i)), \
(DEVICE_DT_GET(MICROPYTHON_CHOSEN(prop, i)),))

extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t machine_i2c_type;
extern const mp_obj_type_t machine_spi_type;
Expand Down