blob: fc60167b98cce13815ee44a77006dd9506df7aea [file] [log] [blame]
Dave Hylands297446e2014-01-06 00:20:11 -08001#include <stdio.h>
2
Dave Hylands297446e2014-01-06 00:20:11 -08003#include "Arduino.h"
4
Damien Georgeb68d98d2015-01-01 21:13:30 +00005#include "py/nlr.h"
6#include "py/runtime.h"
Dave Hylands4f1b7fe2014-06-15 22:33:14 -07007#include "led.h"
Damien George7a37f642014-07-02 13:42:37 +01008#include MICROPY_HAL_H
Dave Hylands4f1b7fe2014-06-15 22:33:14 -07009#include "pin.h"
10#include "genhdr/pins.h"
11
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070012typedef struct _pyb_led_obj_t {
13 mp_obj_base_t base;
Damien George40f3c022014-07-03 13:25:24 +010014 mp_uint_t led_id;
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070015 const pin_obj_t *led_pin;
16} pyb_led_obj_t;
17
18STATIC const pyb_led_obj_t pyb_led_obj[] = {
19 {{&pyb_led_type}, 1, &MICROPY_HW_LED1},
20#if defined(MICROPY_HW_LED2)
21 {{&pyb_led_type}, 2, &MICROPY_HW_LED2},
22#if defined(MICROPY_HW_LED3)
23 {{&pyb_led_type}, 3, &MICROPY_HW_LED3},
24#if defined(MICROPY_HW_LED4)
25 {{&pyb_led_type}, 4, &MICROPY_HW_LED4},
26#endif
27#endif
28#endif
29};
Dave Hylands4d9dd262014-07-14 22:19:27 -070030#define NUM_LEDS MP_ARRAY_SIZE(pyb_led_obj)
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070031
Dave Hylands297446e2014-01-06 00:20:11 -080032void led_init(void) {
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070033 /* GPIO structure */
34 GPIO_InitTypeDef GPIO_InitStructure;
35
36 /* Configure I/O speed, mode, output type and pull */
37 GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
38 GPIO_InitStructure.Mode = MICROPY_HW_LED_OTYPE;
39 GPIO_InitStructure.Pull = GPIO_NOPULL;
40
41 /* Turn off LEDs and initialize */
42 for (int led = 0; led < NUM_LEDS; led++) {
43 const pin_obj_t *led_pin = pyb_led_obj[led].led_pin;
44 MICROPY_HW_LED_OFF(led_pin);
45 GPIO_InitStructure.Pin = led_pin->pin_mask;
46 HAL_GPIO_Init(led_pin->gpio, &GPIO_InitStructure);
47 }
Dave Hylands297446e2014-01-06 00:20:11 -080048}
49
50void led_state(pyb_led_t led, int state) {
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070051 if (led < 1 || led > NUM_LEDS) {
Dave Hylands297446e2014-01-06 00:20:11 -080052 return;
53 }
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070054 const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
55 //printf("led_state(%d,%d)\n", led, state);
56 if (state == 0) {
57 // turn LED off
58 MICROPY_HW_LED_OFF(led_pin);
59 } else {
60 // turn LED on
61 MICROPY_HW_LED_ON(led_pin);
62 }
Dave Hylands297446e2014-01-06 00:20:11 -080063}
64
65void led_toggle(pyb_led_t led) {
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070066 if (led < 1 || led > NUM_LEDS) {
Dave Hylands297446e2014-01-06 00:20:11 -080067 return;
68 }
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070069 const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
70 GPIO_TypeDef *gpio = led_pin->gpio;
Dave Hylands297446e2014-01-06 00:20:11 -080071
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070072 // We don't know if we're turning the LED on or off, but we don't really
73 // care. Just invert the state.
74 if (gpio->PDOR & led_pin->pin_mask) {
75 // pin is high, make it low
76 gpio->PCOR = led_pin->pin_mask;
77 } else {
78 // pin is low, make it high
79 gpio->PSOR = led_pin->pin_mask;
80 }
Dave Hylands297446e2014-01-06 00:20:11 -080081}
82
83/******************************************************************************/
84/* Micro Python bindings */
85
Dave Hylands6a6ac8e2014-02-10 21:33:03 -080086void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
Dave Hylands297446e2014-01-06 00:20:11 -080087 pyb_led_obj_t *self = self_in;
Dave Hylands6a6ac8e2014-02-10 21:33:03 -080088 (void)kind;
Dave Hylands297446e2014-01-06 00:20:11 -080089 print(env, "<LED %lu>", self->led_id);
90}
91
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070092STATIC mp_obj_t led_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
93 // check arguments
94 mp_arg_check_num(n_args, n_kw, 1, 1, false);
95
96 // get led number
Damien George40f3c022014-07-03 13:25:24 +010097 mp_int_t led_id = mp_obj_get_int(args[0]);
Dave Hylands4f1b7fe2014-06-15 22:33:14 -070098
99 // check led number
100 if (!(1 <= led_id && led_id <= NUM_LEDS)) {
101 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id));
102 }
103
104 // return static led object
105 return (mp_obj_t)&pyb_led_obj[led_id - 1];
106}
107
Dave Hylands297446e2014-01-06 00:20:11 -0800108mp_obj_t led_obj_on(mp_obj_t self_in) {
109 pyb_led_obj_t *self = self_in;
110 led_state(self->led_id, 1);
111 return mp_const_none;
112}
113
114mp_obj_t led_obj_off(mp_obj_t self_in) {
115 pyb_led_obj_t *self = self_in;
116 led_state(self->led_id, 0);
117 return mp_const_none;
118}
119
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700120mp_obj_t led_obj_toggle(mp_obj_t self_in) {
121 pyb_led_obj_t *self = self_in;
122 led_toggle(self->led_id);
123 return mp_const_none;
Dave Hylands297446e2014-01-06 00:20:11 -0800124}
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700125
126STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
127STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
128STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
129
130STATIC const mp_map_elem_t led_locals_dict_table[] = {
131 { MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&led_obj_on_obj },
132 { MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&led_obj_off_obj },
133 { MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&led_obj_toggle_obj },
134};
135
136STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
137
138const mp_obj_type_t pyb_led_type = {
139 { &mp_type_type },
140 .name = MP_QSTR_LED,
141 .print = led_obj_print,
142 .make_new = led_obj_make_new,
143 .locals_dict = (mp_obj_t)&led_locals_dict,
144};