led.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <stdio.h>
  2. #include "Arduino.h"
  3. #include "py/runtime.h"
  4. #include "py/mphal.h"
  5. #include "led.h"
  6. #include "pin.h"
  7. #include "genhdr/pins.h"
  8. typedef struct _pyb_led_obj_t {
  9. mp_obj_base_t base;
  10. mp_uint_t led_id;
  11. const pin_obj_t *led_pin;
  12. } pyb_led_obj_t;
  13. STATIC const pyb_led_obj_t pyb_led_obj[] = {
  14. {{&pyb_led_type}, 1, &MICROPY_HW_LED1},
  15. #if defined(MICROPY_HW_LED2)
  16. {{&pyb_led_type}, 2, &MICROPY_HW_LED2},
  17. #if defined(MICROPY_HW_LED3)
  18. {{&pyb_led_type}, 3, &MICROPY_HW_LED3},
  19. #if defined(MICROPY_HW_LED4)
  20. {{&pyb_led_type}, 4, &MICROPY_HW_LED4},
  21. #endif
  22. #endif
  23. #endif
  24. };
  25. #define NUM_LEDS MP_ARRAY_SIZE(pyb_led_obj)
  26. void led_init(void) {
  27. /* GPIO structure */
  28. GPIO_InitTypeDef GPIO_InitStructure;
  29. /* Configure I/O speed, mode, output type and pull */
  30. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
  31. GPIO_InitStructure.Mode = MICROPY_HW_LED_OTYPE;
  32. GPIO_InitStructure.Pull = GPIO_NOPULL;
  33. /* Turn off LEDs and initialize */
  34. for (int led = 0; led < NUM_LEDS; led++) {
  35. const pin_obj_t *led_pin = pyb_led_obj[led].led_pin;
  36. MICROPY_HW_LED_OFF(led_pin);
  37. GPIO_InitStructure.Pin = led_pin->pin_mask;
  38. HAL_GPIO_Init(led_pin->gpio, &GPIO_InitStructure);
  39. }
  40. }
  41. void led_state(pyb_led_t led, int state) {
  42. if (led < 1 || led > NUM_LEDS) {
  43. return;
  44. }
  45. const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
  46. //printf("led_state(%d,%d)\n", led, state);
  47. if (state == 0) {
  48. // turn LED off
  49. MICROPY_HW_LED_OFF(led_pin);
  50. } else {
  51. // turn LED on
  52. MICROPY_HW_LED_ON(led_pin);
  53. }
  54. }
  55. void led_toggle(pyb_led_t led) {
  56. if (led < 1 || led > NUM_LEDS) {
  57. return;
  58. }
  59. const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
  60. GPIO_TypeDef *gpio = led_pin->gpio;
  61. // We don't know if we're turning the LED on or off, but we don't really
  62. // care. Just invert the state.
  63. if (gpio->PDOR & led_pin->pin_mask) {
  64. // pin is high, make it low
  65. gpio->PCOR = led_pin->pin_mask;
  66. } else {
  67. // pin is low, make it high
  68. gpio->PSOR = led_pin->pin_mask;
  69. }
  70. }
  71. /******************************************************************************/
  72. /* MicroPython bindings */
  73. void led_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  74. pyb_led_obj_t *self = self_in;
  75. (void)kind;
  76. mp_printf(print, "<LED %lu>", self->led_id);
  77. }
  78. STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, uint n_args, uint n_kw, const mp_obj_t *args) {
  79. // check arguments
  80. mp_arg_check_num(n_args, n_kw, 1, 1, false);
  81. // get led number
  82. mp_int_t led_id = mp_obj_get_int(args[0]);
  83. // check led number
  84. if (!(1 <= led_id && led_id <= NUM_LEDS)) {
  85. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id));
  86. }
  87. // return static led object
  88. return (mp_obj_t)&pyb_led_obj[led_id - 1];
  89. }
  90. mp_obj_t led_obj_on(mp_obj_t self_in) {
  91. pyb_led_obj_t *self = self_in;
  92. led_state(self->led_id, 1);
  93. return mp_const_none;
  94. }
  95. mp_obj_t led_obj_off(mp_obj_t self_in) {
  96. pyb_led_obj_t *self = self_in;
  97. led_state(self->led_id, 0);
  98. return mp_const_none;
  99. }
  100. mp_obj_t led_obj_toggle(mp_obj_t self_in) {
  101. pyb_led_obj_t *self = self_in;
  102. led_toggle(self->led_id);
  103. return mp_const_none;
  104. }
  105. STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
  106. STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
  107. STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
  108. STATIC const mp_rom_map_elem_t led_locals_dict_table[] = {
  109. { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_obj_on_obj) },
  110. { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_obj_off_obj) },
  111. { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_obj_toggle_obj) },
  112. };
  113. STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
  114. const mp_obj_type_t pyb_led_type = {
  115. { &mp_type_type },
  116. .name = MP_QSTR_LED,
  117. .print = led_obj_print,
  118. .make_new = led_obj_make_new,
  119. .locals_dict = (mp_obj_t)&led_locals_dict,
  120. };