led.c 5.03 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
11
12
13
14
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
/* LED numbers, used internally */
#define PYB_LED_1   (1)
#define PYB_LED_2   (2)
#define PYB_LED_3   (3)
#define PYB_LED_4   (4)

#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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    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);
    PYB_LED_OFF(PYB_LED3_PORT, PYB_LED1_PIN);
    PYB_LED_OFF(PYB_LED4_PORT, PYB_LED2_PIN);

    /* 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
        case PYB_LED_1:
            pin  = PYB_LED1_PIN; 
            port = PYB_LED1_PORT; 
            break;
        case PYB_LED_2:
            pin  = PYB_LED2_PIN; 
            port = PYB_LED2_PORT; 
            break;
        case PYB_LED_3:
            pin  = PYB_LED3_PIN; 
            port = PYB_LED3_PORT; 
            break;
        case PYB_LED_4:
            pin  = PYB_LED4_PIN; 
            port = PYB_LED4_PORT; 
            break;
        default: 
            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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
        case PYB_LED_1:
            pin  = PYB_LED1_PIN; 
            port = PYB_LED1_PORT; 
            break;
        case PYB_LED_2:
            pin  = PYB_LED2_PIN; 
            port = PYB_LED2_PORT; 
            break;
        case PYB_LED_3:
            pin  = PYB_LED3_PIN; 
            port = PYB_LED3_PORT; 
            break;
        case PYB_LED_4:
            pin  = PYB_LED4_PIN; 
            port = PYB_LED4_PORT; 
            break;
        default: 
            return;
140
    }
141

142
    if (!(port->ODR & pin)) {
143
144
        // turn LED off 
        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
159
160
161
162
163
164
165

/******************************************************************************/
/* 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) {
    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
179
180
181
182
    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);

static const mp_obj_type_t led_obj_type = {
    { &mp_const_type },
    "Led",
    led_obj_print, // print
183
    NULL, // make_new
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    NULL, // call_n
    NULL, // unary_op
    NULL, // binary_op
    NULL, // getiter
    NULL, // iternext
    { // method list
        { "on", &led_obj_on_obj },
        { "off", &led_obj_off_obj },
        { NULL, NULL },
    }
};

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