Skip to content
Open
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
1 change: 1 addition & 0 deletions ports/psoc-edge/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ SHARED_SRC_C += $(addprefix shared/,\
DRIVERS_SRC_C +=

MOD_SRC_C += \
machine_pin.c \
machine_pdm_pcm.c\
\
modpsocedge.c
Expand Down
227 changes: 227 additions & 0 deletions ports/psoc-edge/machine_pin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#include "py/obj.h"
#include "py/runtime.h"

#include "cy_gpio.h"

#include "extmod/modmachine.h"
#include "extmod/virtpin.h"

#define pin_assert_raise_val(msg, ret) if (ret != CY_RSLT_SUCCESS) { \
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), ret); \
}

enum {GPIO_MODE_NONE = 0, GPIO_MODE_IN, GPIO_MODE_OUT, GPIO_MODE_OPEN_DRAIN};

enum {GPIO_PULL_NONE = 0, GPIO_PULL_UP, GPIO_PULL_DOWN, GPIO_PULL_UP_DOWN};

typedef struct _machine_pin_obj_t {
mp_obj_base_t base;
qstr name;
uint8_t port;
uint8_t pin;
}
machine_pin_obj_t;

// TODO:
// Initial hardcoded pin definitions can go here
// This will be generated by make-pins.py soon
const machine_pin_obj_t machine_pin_p16_0 = {
{ &machine_pin_type },
MP_QSTR_P16_0,
16,
0,
};

static uint32_t get_drive_mode(uint8_t mode, uint8_t pull) {
uint32_t drive_mode = CY_GPIO_DM_INVALID;

if (mode == GPIO_MODE_IN) {
if (pull == GPIO_PULL_UP) {
drive_mode = CY_GPIO_DM_PULLUP;
} else if (pull == GPIO_PULL_DOWN) {
drive_mode = CY_GPIO_DM_PULLDOWN;
} else if (pull == GPIO_PULL_UP_DOWN) {
drive_mode = CY_GPIO_DM_PULLUP_DOWN;
} else {
drive_mode = CY_GPIO_DM_HIGHZ;
}
// TODO: Check if this will be used.
// CY_GPIO_DM_STRONG ??
} else if (mode == GPIO_MODE_OUT) {
if (pull == GPIO_PULL_UP) {
drive_mode = CY_GPIO_DM_PULLUP_IN_OFF;
} else if (pull == GPIO_PULL_DOWN) {
drive_mode = CY_GPIO_DM_PULLDOWN_IN_OFF;
} else if (pull == GPIO_PULL_UP_DOWN) {
drive_mode = CY_GPIO_DM_PULLUP_DOWN_IN_OFF;
} else {
drive_mode = CY_GPIO_DM_STRONG_IN_OFF;
}
} else if (mode == GPIO_MODE_OPEN_DRAIN) {
drive_mode = CY_GPIO_DM_OD_DRIVESLOW_IN_OFF;
// TODO: Check if we support other open drain modes
// CY_GPIO_DM_OD_DRIVESLOW
// CY_GPIO_DM_OD_DRIVESHIGH
} else if (mode == GPIO_MODE_NONE) {
drive_mode = CY_GPIO_DM_INVALID;
}

return drive_mode;
}

static uint8_t get_validated_initial_value(uint8_t mode, uint8_t pull, int8_t value) {
// No value was selected by the user,
// Select it coherent with the pull resistor
// configuration and low by default
if (value == -1) {
return (pull == GPIO_PULL_UP) ? 1 : 0;
}

if (mode == GPIO_MODE_IN) {
if (value == 0 && pull == GPIO_PULL_UP) {
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT("machine.Pin incompatible configuration. Input pull-up can not be initialized low.\n"));
} else if (value == 1 && pull == GPIO_PULL_DOWN) {
mp_raise_msg(&mp_type_Exception, MP_ERROR_TEXT("machine.Pin incompatible configuration. Input pull-down can not be initialized high.\n"));
} else if (pull == GPIO_PULL_NONE || pull == GPIO_PULL_UP_DOWN) {
value = 0; // Default to low
mp_printf(&mp_plat_print, "machine.Pin warning: Initial value is undefined for input pull-none configuration.\n");
}
return value;
}

return value;
}

static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum {
ARG_mode, ARG_pull, ARG_drive, ARG_value
};
static const mp_arg_t allowed_args[] = {
{MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}
};

mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

uint8_t mode = GPIO_MODE_NONE;
if (args[ARG_mode].u_obj != mp_const_none) {
mode = mp_obj_get_uint(args[ARG_mode].u_obj);
}

uint8_t pull = GPIO_PULL_NONE;
if (args[ARG_pull].u_obj != mp_const_none) {
pull = mp_obj_get_uint(args[ARG_pull].u_obj);
}

int8_t value = -1;
if (args[ARG_value].u_obj != mp_const_none) {
value = mp_obj_is_true(args[ARG_value].u_obj);
}

uint32_t drive = CY_GPIO_DRIVE_SEL_0;
if (args[ARG_drive].u_obj != mp_const_none) {
drive = mp_obj_get_uint(args[ARG_drive].u_obj);
}

cy_stc_gpio_pin_config_t pin_config = {
.outVal = get_validated_initial_value(mode, pull, value),
.driveMode = get_drive_mode(mode, pull),
.hsiom = HSIOM_SEL_GPIO,
.intEdge = CY_GPIO_INTR_DISABLE,
.intMask = 0UL,
.vtrip = CY_GPIO_VTRIP_CMOS,
.slewRate = CY_GPIO_SLEW_FAST,
.driveSel = drive,
.vregEn = 0UL,
.ibufMode = 0UL,
.vtripSel = 0UL,
.vrefSel = 0UL,
.vohSel = 0UL,
.pullUpRes = CY_GPIO_PULLUP_RES_DISABLE,
.nonSec = 1,
};

cy_en_gpio_status_t rslt = Cy_GPIO_Pin_Init(Cy_GPIO_PortToAddr(self->port), self->pin, &pin_config);
pin_assert_raise_val("Pin initialization failed (PSE PDL error code: %lx)", rslt);

return mp_const_none;
}

mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {

mp_arg_check_num(n_args, n_kw, 1, 6, true);

const machine_pin_obj_t *self = &machine_pin_p16_0; // TODO: This will be change by the proper pin allocation/find function machine_pin_finf(args[0]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead have a LUT for this pin so that we can extend it for other tests till we have pins generated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let´s discuss in the pairing how I should do that :)


if (n_args > 1 || n_kw > 0) {
// pin mode given, so configure this GPIO
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
machine_pin_obj_init_helper(self, n_args - 1, args + 1, &kw_args); // skipping "id" as an arg as it is a part of self*.
}

return MP_OBJ_FROM_PTR(self);
}

static mp_obj_t machine_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_obj_init_obj, 1, machine_pin_obj_init);

static void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
// TODO: Placeholder.
}

static mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
// TODO: Placeholder.
return mp_const_none;
}

static mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
// TODO: Placeholder.
return 0;
}

static const mp_pin_p_t pin_pin_p = {
.ioctl = pin_ioctl,
};

static const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
// Instance methods
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_obj_init_obj) },

// Const
{ MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_IN) },
{ MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUT) },
{ MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_OPEN_DRAIN) },

{ MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULL_UP) },
{ MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) },
{ MP_ROM_QSTR(MP_QSTR_PULL_UP_DOWN), MP_ROM_INT(GPIO_PULL_UP_DOWN) },

{ MP_ROM_QSTR(MP_QSTR_DRIVE_0), MP_ROM_INT(CY_GPIO_DRIVE_SEL_0) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_1), MP_ROM_INT(CY_GPIO_DRIVE_SEL_1) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_2), MP_ROM_INT(CY_GPIO_DRIVE_SEL_2) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_3), MP_ROM_INT(CY_GPIO_DRIVE_SEL_3) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_4), MP_ROM_INT(CY_GPIO_DRIVE_SEL_4) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_5), MP_ROM_INT(CY_GPIO_DRIVE_SEL_5) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_6), MP_ROM_INT(CY_GPIO_DRIVE_SEL_6) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_7), MP_ROM_INT(CY_GPIO_DRIVE_SEL_7) }
};

static MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table);


MP_DEFINE_CONST_OBJ_TYPE(
machine_pin_type,
MP_QSTR_Pin,
MP_TYPE_FLAG_NONE,
make_new, mp_pin_make_new,
print, machine_pin_print,
call, machine_pin_call,
protocol, &pin_pin_p,
locals_dict, &machine_pin_locals_dict
);
1 change: 1 addition & 0 deletions ports/psoc-edge/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) {

#define MICROPY_PY_MACHINE_EXTRA_GLOBALS \
/* Modules */ \
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \
{ MP_ROM_QSTR(MP_QSTR_PDM_PCM), MP_ROM_PTR(&machine_pdm_pcm_type) }, \

#endif // MICROPY_PY_MACHINE
2 changes: 2 additions & 0 deletions ports/psoc-edge/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
#define MICROPY_PY_MACHINE_PDM_PCM (1)
#define MICROPY_PY_MACHINE_PDM_PCM_RING_BUF (1)

#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new

#define MICROPY_LOGGER_DEBUG (1)

// type definitions for the specific machine
Expand Down
5 changes: 5 additions & 0 deletions tests/ports/psoc-edge/board_ext_hw/single/pin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from machine import Pin

pin1_name = "P16_0"

pin_out = Pin(pin1_name, mode=Pin.OUT, value=True)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the other tests will be added after pin generations is it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will start the test with 2 hardcoded pins, and add the rest of the machine.Pin() tests. With the creation of the pin class I will understand all the machine_pin_obj requirements, and from there I can handle the pin generation from make-pins.py.
Then there are the alternative functions, which some ports handle them from the Pin class... In PSOC6 the usage of the HAL prevented us from doing this. But in this case, I am not sure if we can/should stick to that approach.

Empty file.
6 changes: 6 additions & 0 deletions tests/ports/psoc-edge/test-plan.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
- name: no-extended-hardware
test:
script: ports/psoc-edge/board_only_hw/single
device:
- board: KIT_PSE84_AI

- name: pin
test:
script: ports/psoc-edge/board_ext_hw/single/pin.py
device:
- board: KIT_PSE84_AI
Loading