stm: Factor out GPIO code to its own file. Add functions to set GPIO mode.

GPIO functions are crude, and need to be replaced with better ones!
This commit is contained in:
Damien George 2014-02-16 23:44:23 +00:00
parent 2abbae3419
commit 402dc31aa7
5 changed files with 138 additions and 48 deletions

View File

@ -51,6 +51,7 @@ SRC_C = \
lexerfatfs.c \
pyexec.c \
led.c \
gpio.c \
lcd.c \
servo.c \
flash.c \

130
stm/gpio.c Normal file
View File

@ -0,0 +1,130 @@
// This is a woefully inadequate set of bindings for GPIO control, and
// needs to be replaced with something much better.
#include <stdio.h>
#include <string.h>
#include <stm32f4xx.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_syscfg.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_exti.h>
#include <stm32f4xx_tim.h>
#include <stm32f4xx_pwr.h>
#include <stm32f4xx_rtc.h>
#include <stm32f4xx_usart.h>
#include <stm32f4xx_rng.h>
#include <usbd_storage_msd.h>
#include <stm_misc.h>
#include "nlr.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "misc.h"
#include "parse.h"
#include "obj.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
#include "systick.h"
#include "gpio.h"
void parse_pin_name(mp_obj_t name, GPIO_TypeDef **port, uint *pin) {
const char *pin_name = mp_obj_str_get_str(name);
switch (pin_name[0]) {
case 'A': case 'a': *port = GPIOA; break;
case 'B': case 'b': *port = GPIOB; break;
case 'C': case 'c': *port = GPIOC; break;
case 'D': case 'd': *port = GPIOD; break;
default: goto pin_error;
}
*pin = 0;
for (const char *s = pin_name + 1; *s; s++) {
if (!('0' <= *s && *s <= '9')) {
goto pin_error;
}
*pin = 10 * (*pin) + *s - '0';
}
if (!(0 <= *pin && *pin <= 15)) {
goto pin_error;
}
return;
pin_error:
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not exist", pin_name));
}
mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) {
//assert(1 <= n_args && n_args <= 2);
GPIO_TypeDef *port;
uint pin;
parse_pin_name(args[0], &port, &pin);
if (n_args == 1) {
// get pin
if ((port->IDR & (1 << pin)) != (uint32_t)Bit_RESET) {
return MP_OBJ_NEW_SMALL_INT(1);
} else {
return MP_OBJ_NEW_SMALL_INT(0);
}
} else {
// set pin
if (rt_is_true(args[1])) {
// set pin high
port->BSRRL = 1 << pin;
} else {
// set pin low
port->BSRRH = 1 << pin;
}
return mp_const_none;
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
mp_obj_t pyb_gpio_input(mp_obj_t arg_port_pin, mp_obj_t arg_mode) {
GPIO_TypeDef *port;
uint pin;
parse_pin_name(arg_port_pin, &port, &pin);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = 1 << pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = mp_obj_get_int(arg_mode);
GPIO_Init(port, &GPIO_InitStructure);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(pyb_gpio_input_obj, pyb_gpio_input);
mp_obj_t pyb_gpio_output(mp_obj_t arg_port_pin, mp_obj_t arg_mode) {
GPIO_TypeDef *port;
uint pin;
parse_pin_name(arg_port_pin, &port, &pin);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = 1 << pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
GPIO_InitStructure.GPIO_OType = mp_obj_get_int(arg_mode);
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(port, &GPIO_InitStructure);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(pyb_gpio_output_obj, pyb_gpio_output);
void gpio_init(mp_obj_t mod) {
rt_store_attr(mod, MP_QSTR_gpio, (mp_obj_t)&pyb_gpio_obj);
rt_store_attr(mod, MP_QSTR_gpio_in, (mp_obj_t)&pyb_gpio_input_obj);
rt_store_attr(mod, MP_QSTR_gpio_out, (mp_obj_t)&pyb_gpio_output_obj);
rt_store_attr(mod, qstr_from_str("PULL_NONE"), MP_OBJ_NEW_SMALL_INT(GPIO_PuPd_NOPULL));
rt_store_attr(mod, qstr_from_str("PULL_UP"), MP_OBJ_NEW_SMALL_INT(GPIO_PuPd_UP));
rt_store_attr(mod, qstr_from_str("PULL_DOWN"), MP_OBJ_NEW_SMALL_INT(GPIO_PuPd_DOWN));
rt_store_attr(mod, qstr_from_str("PUSH_PULL"), MP_OBJ_NEW_SMALL_INT(GPIO_OType_PP));
rt_store_attr(mod, qstr_from_str("OPEN_DRAIN"), MP_OBJ_NEW_SMALL_INT(GPIO_OType_OD));
}

1
stm/gpio.h Normal file
View File

@ -0,0 +1 @@
void gpio_init(mp_obj_t mod);

View File

@ -34,6 +34,7 @@
#include "pendsv.h"
#include "pyexec.h"
#include "led.h"
#include "gpio.h"
#include "servo.h"
#include "lcd.h"
#include "storage.h"
@ -259,53 +260,6 @@ static mp_obj_t pyb_standby(void) {
return mp_const_none;
}
mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) {
//assert(1 <= n_args && n_args <= 2);
const char *pin_name = mp_obj_str_get_str(args[0]);
GPIO_TypeDef *port;
switch (pin_name[0]) {
case 'A': case 'a': port = GPIOA; break;
case 'B': case 'b': port = GPIOB; break;
case 'C': case 'c': port = GPIOC; break;
default: goto pin_error;
}
uint pin_num = 0;
for (const char *s = pin_name + 1; *s; s++) {
if (!('0' <= *s && *s <= '9')) {
goto pin_error;
}
pin_num = 10 * pin_num + *s - '0';
}
if (!(0 <= pin_num && pin_num <= 15)) {
goto pin_error;
}
if (n_args == 1) {
// get pin
if ((port->IDR & (1 << pin_num)) != (uint32_t)Bit_RESET) {
return MP_OBJ_NEW_SMALL_INT(1);
} else {
return MP_OBJ_NEW_SMALL_INT(0);
}
} else {
// set pin
if (rt_is_true(args[1])) {
// set pin high
port->BSRRL = 1 << pin_num;
} else {
// set pin low
port->BSRRH = 1 << pin_num;
}
return mp_const_none;
}
pin_error:
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not exist", pin_name));
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4);
uint8_t data[4];
@ -479,11 +433,13 @@ soft_reset:
rt_store_attr(m, MP_QSTR_Servo, rt_make_function_n(1, pyb_Servo));
#endif
rt_store_attr(m, MP_QSTR_I2C, rt_make_function_n(2, pyb_I2C));
rt_store_attr(m, MP_QSTR_gpio, (mp_obj_t)&pyb_gpio_obj);
rt_store_attr(m, MP_QSTR_Usart, rt_make_function_n(2, pyb_Usart));
rt_store_attr(m, qstr_from_str("ADC_all"), (mp_obj_t)&pyb_ADC_all_obj);
rt_store_attr(m, MP_QSTR_ADC, (mp_obj_t)&pyb_ADC_obj);
rt_store_attr(m, qstr_from_str("millis"), rt_make_function_n(0, pyb_millis));
gpio_init(m);
rt_store_name(MP_QSTR_pyb, m);
rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open));

View File

@ -26,6 +26,8 @@ Q(Servo)
Q(SDcard)
Q(I2C)
Q(gpio)
Q(gpio_in)
Q(gpio_out)
Q(Usart)
Q(ADC)
Q(open)