Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the MicroPython project, http://micropython.org/ |
| 3 | * |
| 4 | * Development of the code in this file was sponsored by Microbric Pty Ltd |
| 5 | * |
| 6 | * The MIT License (MIT) |
| 7 | * |
| 8 | * Copyright (c) 2016 Damien P. George |
| 9 | * |
| 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 11 | * of this software and associated documentation files (the "Software"), to deal |
| 12 | * in the Software without restriction, including without limitation the rights |
| 13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 14 | * copies of the Software, and to permit persons to whom the Software is |
| 15 | * furnished to do so, subject to the following conditions: |
| 16 | * |
| 17 | * The above copyright notice and this permission notice shall be included in |
| 18 | * all copies or substantial portions of the Software. |
| 19 | * |
| 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 26 | * THE SOFTWARE. |
| 27 | */ |
| 28 | |
| 29 | #include <stdio.h> |
| 30 | #include <string.h> |
| 31 | |
| 32 | #include "driver/gpio.h" |
Damien George | e5d2ddd | 2021-04-15 13:02:34 +1000 | [diff] [blame] | 33 | #include "driver/rtc_io.h" |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 34 | |
| 35 | #include "py/runtime.h" |
| 36 | #include "py/mphal.h" |
Nicko van Someren | 14ab81e | 2018-07-01 20:27:10 -0600 | [diff] [blame] | 37 | #include "mphalport.h" |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 38 | #include "modmachine.h" |
| 39 | #include "extmod/virtpin.h" |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 40 | #include "machine_rtc.h" |
| 41 | #include "modesp32.h" |
| 42 | |
Damien George | 673db93 | 2019-03-26 15:21:23 +1100 | [diff] [blame] | 43 | // Used to implement a range of pull capabilities |
| 44 | #define GPIO_PULL_DOWN (1) |
| 45 | #define GPIO_PULL_UP (2) |
| 46 | #define GPIO_PULL_HOLD (4) |
Damien George | ddc9346 | 2019-03-08 23:51:39 +1100 | [diff] [blame] | 47 | |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 48 | typedef struct _machine_pin_obj_t { |
| 49 | mp_obj_base_t base; |
| 50 | gpio_num_t id; |
| 51 | } machine_pin_obj_t; |
| 52 | |
| 53 | typedef struct _machine_pin_irq_obj_t { |
| 54 | mp_obj_base_t base; |
| 55 | gpio_num_t id; |
| 56 | } machine_pin_irq_obj_t; |
| 57 | |
| 58 | STATIC const machine_pin_obj_t machine_pin_obj[] = { |
| 59 | {{&machine_pin_type}, GPIO_NUM_0}, |
| 60 | {{&machine_pin_type}, GPIO_NUM_1}, |
| 61 | {{&machine_pin_type}, GPIO_NUM_2}, |
| 62 | {{&machine_pin_type}, GPIO_NUM_3}, |
| 63 | {{&machine_pin_type}, GPIO_NUM_4}, |
| 64 | {{&machine_pin_type}, GPIO_NUM_5}, |
| 65 | {{&machine_pin_type}, GPIO_NUM_6}, |
| 66 | {{&machine_pin_type}, GPIO_NUM_7}, |
| 67 | {{&machine_pin_type}, GPIO_NUM_8}, |
| 68 | {{&machine_pin_type}, GPIO_NUM_9}, |
| 69 | {{&machine_pin_type}, GPIO_NUM_10}, |
| 70 | {{&machine_pin_type}, GPIO_NUM_11}, |
| 71 | {{&machine_pin_type}, GPIO_NUM_12}, |
| 72 | {{&machine_pin_type}, GPIO_NUM_13}, |
| 73 | {{&machine_pin_type}, GPIO_NUM_14}, |
| 74 | {{&machine_pin_type}, GPIO_NUM_15}, |
| 75 | {{&machine_pin_type}, GPIO_NUM_16}, |
| 76 | {{&machine_pin_type}, GPIO_NUM_17}, |
| 77 | {{&machine_pin_type}, GPIO_NUM_18}, |
| 78 | {{&machine_pin_type}, GPIO_NUM_19}, |
| 79 | {{NULL}, -1}, |
| 80 | {{&machine_pin_type}, GPIO_NUM_21}, |
Damien George | 66a86a0 | 2021-02-18 21:24:34 +1100 | [diff] [blame] | 81 | #if CONFIG_IDF_TARGET_ESP32 |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 82 | {{&machine_pin_type}, GPIO_NUM_22}, |
| 83 | {{&machine_pin_type}, GPIO_NUM_23}, |
| 84 | {{NULL}, -1}, |
| 85 | {{&machine_pin_type}, GPIO_NUM_25}, |
Damien George | 66a86a0 | 2021-02-18 21:24:34 +1100 | [diff] [blame] | 86 | #else |
| 87 | {{NULL}, -1}, |
| 88 | {{NULL}, -1}, |
| 89 | {{NULL}, -1}, |
| 90 | {{NULL}, -1}, |
| 91 | #endif |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 92 | {{&machine_pin_type}, GPIO_NUM_26}, |
| 93 | {{&machine_pin_type}, GPIO_NUM_27}, |
| 94 | {{NULL}, -1}, |
| 95 | {{NULL}, -1}, |
| 96 | {{NULL}, -1}, |
| 97 | {{NULL}, -1}, |
| 98 | {{&machine_pin_type}, GPIO_NUM_32}, |
| 99 | {{&machine_pin_type}, GPIO_NUM_33}, |
| 100 | {{&machine_pin_type}, GPIO_NUM_34}, |
| 101 | {{&machine_pin_type}, GPIO_NUM_35}, |
| 102 | {{&machine_pin_type}, GPIO_NUM_36}, |
| 103 | {{&machine_pin_type}, GPIO_NUM_37}, |
| 104 | {{&machine_pin_type}, GPIO_NUM_38}, |
| 105 | {{&machine_pin_type}, GPIO_NUM_39}, |
| 106 | }; |
| 107 | |
| 108 | // forward declaration |
| 109 | STATIC const machine_pin_irq_obj_t machine_pin_irq_object[]; |
| 110 | |
| 111 | void machine_pins_init(void) { |
| 112 | static bool did_install = false; |
| 113 | if (!did_install) { |
| 114 | gpio_install_isr_service(0); |
| 115 | did_install = true; |
| 116 | } |
| 117 | memset(&MP_STATE_PORT(machine_pin_irq_handler[0]), 0, sizeof(MP_STATE_PORT(machine_pin_irq_handler))); |
| 118 | } |
| 119 | |
| 120 | void machine_pins_deinit(void) { |
| 121 | for (int i = 0; i < MP_ARRAY_SIZE(machine_pin_obj); ++i) { |
| 122 | if (machine_pin_obj[i].id != (gpio_num_t)-1) { |
| 123 | gpio_isr_handler_remove(machine_pin_obj[i].id); |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | |
Damien George | e7ab475 | 2019-01-27 16:15:47 +1100 | [diff] [blame] | 128 | STATIC void machine_pin_isr_handler(void *arg) { |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 129 | machine_pin_obj_t *self = arg; |
| 130 | mp_obj_t handler = MP_STATE_PORT(machine_pin_irq_handler)[self->id]; |
| 131 | mp_sched_schedule(handler, MP_OBJ_FROM_PTR(self)); |
Nicko van Someren | 14ab81e | 2018-07-01 20:27:10 -0600 | [diff] [blame] | 132 | mp_hal_wake_main_task_from_isr(); |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | gpio_num_t machine_pin_get_id(mp_obj_t pin_in) { |
| 136 | if (mp_obj_get_type(pin_in) != &machine_pin_type) { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 137 | mp_raise_ValueError(MP_ERROR_TEXT("expecting a pin")); |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 138 | } |
| 139 | machine_pin_obj_t *self = pin_in; |
| 140 | return self->id; |
| 141 | } |
| 142 | |
| 143 | STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { |
| 144 | machine_pin_obj_t *self = self_in; |
| 145 | mp_printf(print, "Pin(%u)", self->id); |
| 146 | } |
| 147 | |
| 148 | // pin.init(mode, pull=None, *, value) |
| 149 | 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) { |
| 150 | enum { ARG_mode, ARG_pull, ARG_value }; |
| 151 | static const mp_arg_t allowed_args[] = { |
| 152 | { MP_QSTR_mode, MP_ARG_OBJ, {.u_obj = mp_const_none}}, |
Damien George | 349b545 | 2019-02-28 12:38:28 +1100 | [diff] [blame] | 153 | { MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)}}, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 154 | { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, |
| 155 | }; |
| 156 | |
| 157 | // parse args |
| 158 | mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; |
| 159 | mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); |
| 160 | |
Damien George | e5d2ddd | 2021-04-15 13:02:34 +1000 | [diff] [blame] | 161 | // reset the pin to digital if this is a mode-setting init (grab it back from ADC) |
Jonathan Hogg | 8a917ad | 2020-11-09 13:11:52 +0000 | [diff] [blame] | 162 | if (args[ARG_mode].u_obj != mp_const_none) { |
Damien George | e5d2ddd | 2021-04-15 13:02:34 +1000 | [diff] [blame] | 163 | if (rtc_gpio_is_valid_gpio(self->id)) { |
| 164 | rtc_gpio_deinit(self->id); |
| 165 | } |
Jonathan Hogg | 8a917ad | 2020-11-09 13:11:52 +0000 | [diff] [blame] | 166 | } |
| 167 | |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 168 | // configure the pin for gpio |
| 169 | gpio_pad_select_gpio(self->id); |
| 170 | |
| 171 | // set initial value (do this before configuring mode/pull) |
| 172 | if (args[ARG_value].u_obj != MP_OBJ_NULL) { |
| 173 | gpio_set_level(self->id, mp_obj_is_true(args[ARG_value].u_obj)); |
| 174 | } |
| 175 | |
| 176 | // configure mode |
| 177 | if (args[ARG_mode].u_obj != mp_const_none) { |
| 178 | mp_int_t pin_io_mode = mp_obj_get_int(args[ARG_mode].u_obj); |
| 179 | if (self->id >= 34 && (pin_io_mode & GPIO_MODE_DEF_OUTPUT)) { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 180 | mp_raise_ValueError(MP_ERROR_TEXT("pin can only be input")); |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 181 | } else { |
| 182 | gpio_set_direction(self->id, pin_io_mode); |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | // configure pull |
Damien George | 349b545 | 2019-02-28 12:38:28 +1100 | [diff] [blame] | 187 | if (args[ARG_pull].u_obj != MP_OBJ_NEW_SMALL_INT(-1)) { |
Damien George | 673db93 | 2019-03-26 15:21:23 +1100 | [diff] [blame] | 188 | int mode = 0; |
| 189 | if (args[ARG_pull].u_obj != mp_const_none) { |
| 190 | mode = mp_obj_get_int(args[ARG_pull].u_obj); |
| 191 | } |
| 192 | if (mode & GPIO_PULL_DOWN) { |
| 193 | gpio_pulldown_en(self->id); |
Damien George | 349b545 | 2019-02-28 12:38:28 +1100 | [diff] [blame] | 194 | } else { |
Damien George | 673db93 | 2019-03-26 15:21:23 +1100 | [diff] [blame] | 195 | gpio_pulldown_dis(self->id); |
| 196 | } |
| 197 | if (mode & GPIO_PULL_UP) { |
| 198 | gpio_pullup_en(self->id); |
| 199 | } else { |
| 200 | gpio_pullup_dis(self->id); |
| 201 | } |
| 202 | if (mode & GPIO_PULL_HOLD) { |
| 203 | gpio_hold_en(self->id); |
| 204 | } else if (GPIO_IS_VALID_OUTPUT_GPIO(self->id)) { |
| 205 | gpio_hold_dis(self->id); |
Damien George | 349b545 | 2019-02-28 12:38:28 +1100 | [diff] [blame] | 206 | } |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 207 | } |
| 208 | |
| 209 | return mp_const_none; |
| 210 | } |
| 211 | |
| 212 | // constructor(id, ...) |
| 213 | 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) { |
| 214 | mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); |
| 215 | |
| 216 | // get the wanted pin object |
| 217 | int wanted_pin = mp_obj_get_int(args[0]); |
| 218 | const machine_pin_obj_t *self = NULL; |
| 219 | if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_obj)) { |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 220 | self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin]; |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 221 | } |
| 222 | if (self == NULL || self->base.type == NULL) { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 223 | mp_raise_ValueError(MP_ERROR_TEXT("invalid pin")); |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | if (n_args > 1 || n_kw > 0) { |
| 227 | // pin mode given, so configure this GPIO |
| 228 | mp_map_t kw_args; |
| 229 | mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); |
| 230 | machine_pin_obj_init_helper(self, n_args - 1, args + 1, &kw_args); |
| 231 | } |
| 232 | |
| 233 | return MP_OBJ_FROM_PTR(self); |
| 234 | } |
| 235 | |
| 236 | // fast method for getting/setting pin value |
| 237 | 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) { |
| 238 | mp_arg_check_num(n_args, n_kw, 0, 1, false); |
| 239 | machine_pin_obj_t *self = self_in; |
| 240 | if (n_args == 0) { |
| 241 | // get pin |
| 242 | return MP_OBJ_NEW_SMALL_INT(gpio_get_level(self->id)); |
| 243 | } else { |
| 244 | // set pin |
| 245 | gpio_set_level(self->id, mp_obj_is_true(args[0])); |
| 246 | return mp_const_none; |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | // pin.init(mode, pull) |
| 251 | STATIC mp_obj_t machine_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { |
| 252 | return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args); |
| 253 | } |
| 254 | MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_obj_init); |
| 255 | |
| 256 | // pin.value([value]) |
| 257 | STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { |
| 258 | return machine_pin_call(args[0], n_args - 1, 0, args + 1); |
| 259 | } |
| 260 | STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value); |
| 261 | |
Damien George | 90f86a0 | 2019-01-16 17:33:56 +1100 | [diff] [blame] | 262 | // pin.off() |
| 263 | STATIC mp_obj_t machine_pin_off(mp_obj_t self_in) { |
| 264 | machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 265 | gpio_set_level(self->id, 0); |
| 266 | return mp_const_none; |
| 267 | } |
| 268 | STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_off_obj, machine_pin_off); |
| 269 | |
| 270 | // pin.on() |
| 271 | STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) { |
| 272 | machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 273 | gpio_set_level(self->id, 1); |
| 274 | return mp_const_none; |
| 275 | } |
| 276 | STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on); |
| 277 | |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 278 | // pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING) |
| 279 | STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 280 | enum { ARG_handler, ARG_trigger, ARG_wake }; |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 281 | static const mp_arg_t allowed_args[] = { |
| 282 | { MP_QSTR_handler, MP_ARG_OBJ, {.u_obj = mp_const_none} }, |
| 283 | { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE} }, |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 284 | { MP_QSTR_wake, MP_ARG_OBJ, {.u_obj = mp_const_none} }, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 285 | }; |
| 286 | machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); |
| 287 | mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; |
| 288 | mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); |
| 289 | |
| 290 | if (n_args > 1 || kw_args->used != 0) { |
| 291 | // configure irq |
| 292 | mp_obj_t handler = args[ARG_handler].u_obj; |
| 293 | uint32_t trigger = args[ARG_trigger].u_int; |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 294 | mp_obj_t wake_obj = args[ARG_wake].u_obj; |
| 295 | |
| 296 | if ((trigger == GPIO_PIN_INTR_LOLEVEL || trigger == GPIO_PIN_INTR_HILEVEL) && wake_obj != mp_const_none) { |
| 297 | mp_int_t wake; |
| 298 | if (mp_obj_get_int_maybe(wake_obj, &wake)) { |
| 299 | if (wake < 2 || wake > 7) { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 300 | mp_raise_ValueError(MP_ERROR_TEXT("bad wake value")); |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 301 | } |
| 302 | } else { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 303 | mp_raise_ValueError(MP_ERROR_TEXT("bad wake value")); |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 304 | } |
| 305 | |
| 306 | if (machine_rtc_config.wake_on_touch) { // not compatible |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 307 | mp_raise_ValueError(MP_ERROR_TEXT("no resources")); |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 308 | } |
| 309 | |
| 310 | if (!RTC_IS_VALID_EXT_PIN(self->id)) { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 311 | mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for wake")); |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 312 | } |
| 313 | |
| 314 | if (machine_rtc_config.ext0_pin == -1) { |
| 315 | machine_rtc_config.ext0_pin = self->id; |
| 316 | } else if (machine_rtc_config.ext0_pin != self->id) { |
Jim Mussared | def76fe | 2020-03-02 22:35:22 +1100 | [diff] [blame] | 317 | mp_raise_ValueError(MP_ERROR_TEXT("no resources")); |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 318 | } |
| 319 | |
| 320 | machine_rtc_config.ext0_level = trigger == GPIO_PIN_INTR_LOLEVEL ? 0 : 1; |
| 321 | machine_rtc_config.ext0_wake_types = wake; |
| 322 | } else { |
| 323 | if (machine_rtc_config.ext0_pin == self->id) { |
| 324 | machine_rtc_config.ext0_pin = -1; |
| 325 | } |
| 326 | |
| 327 | if (handler == mp_const_none) { |
| 328 | handler = MP_OBJ_NULL; |
| 329 | trigger = 0; |
| 330 | } |
| 331 | gpio_isr_handler_remove(self->id); |
| 332 | MP_STATE_PORT(machine_pin_irq_handler)[self->id] = handler; |
| 333 | gpio_set_intr_type(self->id, trigger); |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 334 | gpio_isr_handler_add(self->id, machine_pin_isr_handler, (void *)self); |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 335 | } |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 336 | } |
| 337 | |
| 338 | // return the irq object |
| 339 | return MP_OBJ_FROM_PTR(&machine_pin_irq_object[self->id]); |
| 340 | } |
| 341 | STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_irq_obj, 1, machine_pin_irq); |
| 342 | |
| 343 | STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { |
| 344 | // instance methods |
| 345 | { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) }, |
| 346 | { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) }, |
Damien George | 90f86a0 | 2019-01-16 17:33:56 +1100 | [diff] [blame] | 347 | { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_off_obj) }, |
| 348 | { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) }, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 349 | { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) }, |
| 350 | |
| 351 | // class constants |
| 352 | { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_INPUT) }, |
| 353 | { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_INPUT_OUTPUT) }, |
| 354 | { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_INPUT_OUTPUT_OD) }, |
Damien George | 673db93 | 2019-03-26 15:21:23 +1100 | [diff] [blame] | 355 | { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULL_UP) }, |
| 356 | { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) }, |
| 357 | { MP_ROM_QSTR(MP_QSTR_PULL_HOLD), MP_ROM_INT(GPIO_PULL_HOLD) }, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 358 | { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_PIN_INTR_POSEDGE) }, |
| 359 | { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_PIN_INTR_NEGEDGE) }, |
Eric Poulsen | abec47a | 2018-02-15 07:59:28 -0800 | [diff] [blame] | 360 | { MP_ROM_QSTR(MP_QSTR_WAKE_LOW), MP_ROM_INT(GPIO_PIN_INTR_LOLEVEL) }, |
| 361 | { MP_ROM_QSTR(MP_QSTR_WAKE_HIGH), MP_ROM_INT(GPIO_PIN_INTR_HILEVEL) }, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 362 | }; |
| 363 | |
| 364 | STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { |
| 365 | (void)errcode; |
| 366 | machine_pin_obj_t *self = self_in; |
| 367 | |
| 368 | switch (request) { |
| 369 | case MP_PIN_READ: { |
| 370 | return gpio_get_level(self->id); |
| 371 | } |
| 372 | case MP_PIN_WRITE: { |
| 373 | gpio_set_level(self->id, arg); |
| 374 | return 0; |
| 375 | } |
| 376 | } |
| 377 | return -1; |
| 378 | } |
| 379 | |
| 380 | STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); |
| 381 | |
| 382 | STATIC const mp_pin_p_t pin_pin_p = { |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 383 | .ioctl = pin_ioctl, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 384 | }; |
| 385 | |
| 386 | const mp_obj_type_t machine_pin_type = { |
| 387 | { &mp_type_type }, |
| 388 | .name = MP_QSTR_Pin, |
| 389 | .print = machine_pin_print, |
| 390 | .make_new = mp_pin_make_new, |
| 391 | .call = machine_pin_call, |
| 392 | .protocol = &pin_pin_p, |
| 393 | .locals_dict = (mp_obj_t)&machine_pin_locals_dict, |
| 394 | }; |
| 395 | |
| 396 | /******************************************************************************/ |
| 397 | // Pin IRQ object |
| 398 | |
| 399 | STATIC const mp_obj_type_t machine_pin_irq_type; |
| 400 | |
| 401 | STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { |
| 402 | {{&machine_pin_irq_type}, GPIO_NUM_0}, |
| 403 | {{&machine_pin_irq_type}, GPIO_NUM_1}, |
| 404 | {{&machine_pin_irq_type}, GPIO_NUM_2}, |
| 405 | {{&machine_pin_irq_type}, GPIO_NUM_3}, |
| 406 | {{&machine_pin_irq_type}, GPIO_NUM_4}, |
| 407 | {{&machine_pin_irq_type}, GPIO_NUM_5}, |
| 408 | {{&machine_pin_irq_type}, GPIO_NUM_6}, |
| 409 | {{&machine_pin_irq_type}, GPIO_NUM_7}, |
| 410 | {{&machine_pin_irq_type}, GPIO_NUM_8}, |
| 411 | {{&machine_pin_irq_type}, GPIO_NUM_9}, |
| 412 | {{&machine_pin_irq_type}, GPIO_NUM_10}, |
| 413 | {{&machine_pin_irq_type}, GPIO_NUM_11}, |
| 414 | {{&machine_pin_irq_type}, GPIO_NUM_12}, |
| 415 | {{&machine_pin_irq_type}, GPIO_NUM_13}, |
| 416 | {{&machine_pin_irq_type}, GPIO_NUM_14}, |
| 417 | {{&machine_pin_irq_type}, GPIO_NUM_15}, |
| 418 | {{&machine_pin_irq_type}, GPIO_NUM_16}, |
| 419 | {{&machine_pin_irq_type}, GPIO_NUM_17}, |
| 420 | {{&machine_pin_irq_type}, GPIO_NUM_18}, |
| 421 | {{&machine_pin_irq_type}, GPIO_NUM_19}, |
| 422 | {{NULL}, -1}, |
| 423 | {{&machine_pin_irq_type}, GPIO_NUM_21}, |
Damien George | 66a86a0 | 2021-02-18 21:24:34 +1100 | [diff] [blame] | 424 | #if CONFIG_IDF_TARGET_ESP32 |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 425 | {{&machine_pin_irq_type}, GPIO_NUM_22}, |
| 426 | {{&machine_pin_irq_type}, GPIO_NUM_23}, |
| 427 | {{NULL}, -1}, |
| 428 | {{&machine_pin_irq_type}, GPIO_NUM_25}, |
Damien George | 66a86a0 | 2021-02-18 21:24:34 +1100 | [diff] [blame] | 429 | #else |
| 430 | {{NULL}, -1}, |
| 431 | {{NULL}, -1}, |
| 432 | {{NULL}, -1}, |
| 433 | {{NULL}, -1}, |
| 434 | #endif |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 435 | {{&machine_pin_irq_type}, GPIO_NUM_26}, |
| 436 | {{&machine_pin_irq_type}, GPIO_NUM_27}, |
| 437 | {{NULL}, -1}, |
| 438 | {{NULL}, -1}, |
| 439 | {{NULL}, -1}, |
| 440 | {{NULL}, -1}, |
| 441 | {{&machine_pin_irq_type}, GPIO_NUM_32}, |
| 442 | {{&machine_pin_irq_type}, GPIO_NUM_33}, |
| 443 | {{&machine_pin_irq_type}, GPIO_NUM_34}, |
| 444 | {{&machine_pin_irq_type}, GPIO_NUM_35}, |
| 445 | {{&machine_pin_irq_type}, GPIO_NUM_36}, |
| 446 | {{&machine_pin_irq_type}, GPIO_NUM_37}, |
| 447 | {{&machine_pin_irq_type}, GPIO_NUM_38}, |
| 448 | {{&machine_pin_irq_type}, GPIO_NUM_39}, |
| 449 | }; |
| 450 | |
| 451 | STATIC mp_obj_t machine_pin_irq_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { |
| 452 | machine_pin_irq_obj_t *self = self_in; |
| 453 | mp_arg_check_num(n_args, n_kw, 0, 0, false); |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 454 | machine_pin_isr_handler((void *)&machine_pin_obj[self->id]); |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 455 | return mp_const_none; |
| 456 | } |
| 457 | |
| 458 | STATIC mp_obj_t machine_pin_irq_trigger(size_t n_args, const mp_obj_t *args) { |
| 459 | machine_pin_irq_obj_t *self = args[0]; |
| 460 | uint32_t orig_trig = GPIO.pin[self->id].int_type; |
| 461 | if (n_args == 2) { |
| 462 | // set trigger |
| 463 | gpio_set_intr_type(self->id, mp_obj_get_int(args[1])); |
| 464 | } |
| 465 | // return original trigger value |
| 466 | return MP_OBJ_NEW_SMALL_INT(orig_trig); |
| 467 | } |
| 468 | STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_irq_trigger_obj, 1, 2, machine_pin_irq_trigger); |
| 469 | |
| 470 | STATIC const mp_rom_map_elem_t machine_pin_irq_locals_dict_table[] = { |
| 471 | { MP_ROM_QSTR(MP_QSTR_trigger), MP_ROM_PTR(&machine_pin_irq_trigger_obj) }, |
| 472 | }; |
| 473 | STATIC MP_DEFINE_CONST_DICT(machine_pin_irq_locals_dict, machine_pin_irq_locals_dict_table); |
| 474 | |
| 475 | STATIC const mp_obj_type_t machine_pin_irq_type = { |
| 476 | { &mp_type_type }, |
| 477 | .name = MP_QSTR_IRQ, |
| 478 | .call = machine_pin_irq_call, |
Damien George | 69661f3 | 2020-02-27 15:36:53 +1100 | [diff] [blame] | 479 | .locals_dict = (mp_obj_dict_t *)&machine_pin_irq_locals_dict, |
Damien George | bc08c88 | 2016-12-06 12:20:10 +1100 | [diff] [blame] | 480 | }; |