diff options
Diffstat (limited to 'teensy/led.c')
-rw-r--r-- | teensy/led.c | 137 |
1 files changed, 101 insertions, 36 deletions
diff --git a/teensy/led.c b/teensy/led.c index e2a0574168..d825f32198 100644 --- a/teensy/led.c +++ b/teensy/led.c @@ -1,53 +1,115 @@ #include <stdio.h> -#include "misc.h" +#include "Arduino.h" + #include "mpconfig.h" +#include HAL_H +#include "nlr.h" +#include "misc.h" #include "qstr.h" #include "obj.h" +#include "runtime.h" #include "led.h" +#include "pin.h" +#include "genhdr/pins.h" -#include "Arduino.h" + +typedef struct _pyb_led_obj_t { + mp_obj_base_t base; + machine_uint_t led_id; + const pin_obj_t *led_pin; +} pyb_led_obj_t; + +STATIC const pyb_led_obj_t pyb_led_obj[] = { + {{&pyb_led_type}, 1, &MICROPY_HW_LED1}, +#if defined(MICROPY_HW_LED2) + {{&pyb_led_type}, 2, &MICROPY_HW_LED2}, +#if defined(MICROPY_HW_LED3) + {{&pyb_led_type}, 3, &MICROPY_HW_LED3}, +#if defined(MICROPY_HW_LED4) + {{&pyb_led_type}, 4, &MICROPY_HW_LED4}, +#endif +#endif +#endif +}; +#define NUM_LEDS ARRAY_SIZE(pyb_led_obj) void led_init(void) { + /* GPIO structure */ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Configure I/O speed, mode, output type and pull */ + GPIO_InitStructure.Speed = GPIO_SPEED_LOW; + GPIO_InitStructure.Mode = MICROPY_HW_LED_OTYPE; + GPIO_InitStructure.Pull = GPIO_NOPULL; + + /* Turn off LEDs and initialize */ + for (int led = 0; led < NUM_LEDS; led++) { + const pin_obj_t *led_pin = pyb_led_obj[led].led_pin; + MICROPY_HW_LED_OFF(led_pin); + GPIO_InitStructure.Pin = led_pin->pin_mask; + HAL_GPIO_Init(led_pin->gpio, &GPIO_InitStructure); + } } void led_state(pyb_led_t led, int state) { - uint8_t pin; - - if (led == 0) { - pin = LED_BUILTIN; - } else { + if (led < 1 || led > NUM_LEDS) { return; } - digitalWrite(pin, state); + const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin; + //printf("led_state(%d,%d)\n", led, state); + if (state == 0) { + // turn LED off + MICROPY_HW_LED_OFF(led_pin); + } else { + // turn LED on + MICROPY_HW_LED_ON(led_pin); + } } void led_toggle(pyb_led_t led) { - uint8_t pin; - - if (led == 0) { - pin = LED_BUILTIN; - } else { + if (led < 1 || led > NUM_LEDS) { return; } - - digitalWrite(pin, !digitalRead(pin)); + const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin; + GPIO_TypeDef *gpio = led_pin->gpio; + + // We don't know if we're turning the LED on or off, but we don't really + // care. Just invert the state. + if (gpio->PDOR & led_pin->pin_mask) { + // pin is high, make it low + gpio->PCOR = led_pin->pin_mask; + } else { + // pin is low, make it high + gpio->PSOR = led_pin->pin_mask; + } } /******************************************************************************/ /* Micro Python bindings */ -typedef struct _pyb_led_obj_t { - mp_obj_base_t base; - uint led_id; -} pyb_led_obj_t; - void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pyb_led_obj_t *self = self_in; (void)kind; print(env, "<LED %lu>", self->led_id); } +STATIC mp_obj_t led_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 1, 1, false); + + // get led number + machine_int_t led_id = mp_obj_get_int(args[0]); + + // check led number + if (!(1 <= led_id && led_id <= NUM_LEDS)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id)); + } + + // return static led object + return (mp_obj_t)&pyb_led_obj[led_id - 1]; +} + mp_obj_t led_obj_on(mp_obj_t self_in) { pyb_led_obj_t *self = self_in; led_state(self->led_id, 1); @@ -60,25 +122,28 @@ mp_obj_t led_obj_off(mp_obj_t self_in) { return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on); -static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off); +mp_obj_t led_obj_toggle(mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + led_toggle(self->led_id); + return mp_const_none; +} -static const mp_method_t led_methods[] = { - { "on", &led_obj_on_obj }, - { "off", &led_obj_off_obj }, - { NULL, NULL }, +STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle); + +STATIC const mp_map_elem_t led_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&led_obj_on_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&led_obj_off_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&led_obj_toggle_obj }, }; -static const mp_obj_type_t led_obj_type = { +STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table); + +const mp_obj_type_t pyb_led_type = { { &mp_type_type }, - .name = MP_QSTR_Led, + .name = MP_QSTR_LED, .print = led_obj_print, - .methods = led_methods, + .make_new = led_obj_make_new, + .locals_dict = (mp_obj_t)&led_locals_dict, }; - -mp_obj_t pyb_Led(mp_obj_t led_id) { - pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t); - o->base.type = &led_obj_type; - o->led_id = mp_obj_get_int(led_id); - return o; -} |