led.c 4.94 KB
Newer Older
1
#include <stdio.h>
2
3
#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
4
5
6
7

#include "misc.h"
#include "mpconfig.h"
#include "obj.h"
8
9
#include "led.h"

10
/* LED numbers, used internally */
Damien George's avatar
Damien George committed
11
12
13
14
#define PYB_LED_1   (1)
#define PYB_LED_2   (2)
#define PYB_LED_3   (3)
#define PYB_LED_4   (4)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

#if defined(PYBOARD)
    #define PYB_LED1_PORT   (GPIOA)
    #define PYB_LED1_PIN    (GPIO_Pin_8)

    #define PYB_LED2_PORT   (GPIOA)
    #define PYB_LED2_PIN    (GPIO_Pin_10)

    #define PYB_LED3_PORT   (GPIOC)
    #define PYB_LED3_PIN    (GPIO_Pin_4)

    #define PYB_LED4_PORT   (GPIOC)
    #define PYB_LED4_PIN    (GPIO_Pin_5)

    #define PYB_OTYPE       (GPIO_OType_OD)

    #define PYB_LED_ON(port, pin)  (port->BSRRH = pin)
    #define PYB_LED_OFF(port, pin) (port->BSRRL = pin)

#elif defined(STM32F4DISC)
    #define PYB_LED1_PORT   (GPIOD)
    #define PYB_LED1_PIN    (GPIO_Pin_14)

    #define PYB_LED2_PORT   (GPIOD)
    #define PYB_LED2_PIN    (GPIO_Pin_12)

    #define PYB_LED3_PORT   (GPIOD)
    #define PYB_LED3_PIN    (GPIO_Pin_15)

    #define PYB_LED4_PORT   (GPIOD)
    #define PYB_LED4_PIN    (GPIO_Pin_13)

    #define PYB_OTYPE       (GPIO_OType_PP)

    #define PYB_LED_ON(port, pin)  (port->BSRRL = pin)
    #define PYB_LED_OFF(port, pin) (port->BSRRH = pin)
#endif
52

53
void led_init(void) {
54
    /* GPIO structure */
55
    GPIO_InitTypeDef GPIO_InitStructure;
56
57

    /* Configure I/O speed, mode, output type and pull */
58
59
60
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
61
62
63
64
65
    GPIO_InitStructure.GPIO_OType = PYB_OTYPE;

    /* Turn off LEDs */
    PYB_LED_OFF(PYB_LED1_PORT, PYB_LED1_PIN);
    PYB_LED_OFF(PYB_LED2_PORT, PYB_LED2_PIN);
mux's avatar
mux committed
66
67
    PYB_LED_OFF(PYB_LED3_PORT, PYB_LED3_PIN);
    PYB_LED_OFF(PYB_LED4_PORT, PYB_LED4_PIN);
68
69
70
71
72
73
74
75
76
77
78
79
80

    /* Initialize LEDs */
    GPIO_InitStructure.GPIO_Pin = PYB_LED1_PIN;
    GPIO_Init(PYB_LED1_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = PYB_LED2_PIN;
    GPIO_Init(PYB_LED2_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = PYB_LED3_PIN;
    GPIO_Init(PYB_LED3_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = PYB_LED4_PIN;
    GPIO_Init(PYB_LED4_PORT, &GPIO_InitStructure);
81
82
83
84
85
}

void led_state(pyb_led_t led, int state) {
    GPIO_TypeDef *port;
    uint32_t pin;
86

87
    switch (led) {
88
        case PYB_LED_1:
89
90
            pin  = PYB_LED1_PIN;
            port = PYB_LED1_PORT;
91
92
            break;
        case PYB_LED_2:
93
94
            pin  = PYB_LED2_PIN;
            port = PYB_LED2_PORT;
95
96
            break;
        case PYB_LED_3:
97
98
            pin  = PYB_LED3_PIN;
            port = PYB_LED3_PORT;
99
100
            break;
        case PYB_LED_4:
101
102
            pin  = PYB_LED4_PIN;
            port = PYB_LED4_PORT;
103
            break;
104
        default:
105
            return;
106
    }
107

108
    if (state == 0) {
109
110
        // turn LED off
        PYB_LED_OFF(port, pin);
111
    } else {
112
113
        // turn LED on
        PYB_LED_ON(port, pin);
114
115
116
117
118
119
    }
}

void led_toggle(pyb_led_t led) {
    GPIO_TypeDef *port;
    uint32_t pin;
120

121
    switch (led) {
122
        case PYB_LED_1:
123
124
            pin  = PYB_LED1_PIN;
            port = PYB_LED1_PORT;
125
126
            break;
        case PYB_LED_2:
127
128
            pin  = PYB_LED2_PIN;
            port = PYB_LED2_PORT;
129
130
            break;
        case PYB_LED_3:
131
132
            pin  = PYB_LED3_PIN;
            port = PYB_LED3_PORT;
133
134
            break;
        case PYB_LED_4:
135
136
            pin  = PYB_LED4_PIN;
            port = PYB_LED4_PORT;
137
            break;
138
        default:
139
            return;
140
    }
141

142
    if (!(port->ODR & pin)) {
143
        // turn LED off
144
        PYB_LED_OFF(port, pin);
145
146
    } else {
        // turn LED on (output low)
147
        PYB_LED_ON(port, pin);
148
149
    }
}
150
151
152
153
154
155
156
157
158

/******************************************************************************/
/* Micro Python bindings                                                      */

typedef struct _pyb_led_obj_t {
    mp_obj_base_t base;
    uint led_id;
} pyb_led_obj_t;

159
void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
160
161
162
163
164
165
    pyb_led_obj_t *self = self_in;
    print(env, "<LED %lu>", self->led_id);
}

mp_obj_t led_obj_on(mp_obj_t self_in) {
    pyb_led_obj_t *self = self_in;
166
    led_state(self->led_id, 1);
167
168
169
170
171
    return mp_const_none;
}

mp_obj_t led_obj_off(mp_obj_t self_in) {
    pyb_led_obj_t *self = self_in;
172
    led_state(self->led_id, 0);
173
174
175
176
177
178
    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);

179
180
181
182
183
184
static const mp_method_t led_methods[] = {
    { "on", &led_obj_on_obj },
    { "off", &led_obj_off_obj },
    { NULL, NULL },
};

185
186
187
static const mp_obj_type_t led_obj_type = {
    { &mp_const_type },
    "Led",
188
    .print = led_obj_print,
189
    .methods = led_methods,
190
191
192
193
194
195
196
197
};

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;
}