Skip to content

Added mbed hal support for gpio and adc #227

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions embed/embed.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# where embed object files go (they have a name prefix to prevent filename clashes)
EMBED_BUILD = $(BUILD)/embed

# embed object files
EMBED_O_BASENAME = \
hal_gpio.o \

# prepend the build destination prefix to the embed object files
EMBED_O = $(addprefix $(EMBED_BUILD)/, $(EMBED_O_BASENAME))

# Relative to the top of the mbed tree

MBED_TOP = $(TOP)/../mbed/libraries/mbed
MBED_API = $(MBED_TOP)/api
MBED_COMMON = $(MBED_TOP)/common
MBED_HAL_INC = $(MBED_TOP)/hal
MBED_HAL_SRC = $(MBED_TOP)/targets/hal/TARGET_STM/TARGET_STM32F4XX

CFLAGS_EMBED = -I$(TOP)/embed -I$(MBED_API) -I$(MBED_HAL_INC) -I$(MBED_HAL_SRC)

vpath %.c $(MBED_HAL_SRC)
SRC_HAL = \
pinmap.c \
analogin_api.c \
gpio_api.c \

vpath %.c $(MBED_COMMON)
SRC_HAL += \
pinmap_common.c \
exit.c \

7 changes: 7 additions & 0 deletions embed/hal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
typedef struct {
const char *const_name;
machine_int_t const_val;
} hal_int_const;

void hal_target_init_Gpio_class(mp_obj_t gpio_class_type);

83 changes: 83 additions & 0 deletions embed/hal_gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include <stdio.h>
#include <stddef.h>
#include <string.h>

#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "map.h"

#include "gpio_api.h"
#include "hal.h"
#include "hal_gpio.h"

static mp_obj_t gpio_obj_mode(mp_obj_t self_in, mp_obj_t mode_obj) {
hal_gpio_obj_t *self = self_in;
int mode = mp_obj_get_int(mode_obj);
gpio_mode(&self->gpio, mode);
return mp_const_none;
}

static mp_obj_t gpio_obj_dir(mp_obj_t self_in, mp_obj_t dir_obj) {
hal_gpio_obj_t *self = self_in;
int dir = mp_obj_get_int(dir_obj);
gpio_dir(&self->gpio, dir);
return mp_const_none;
}

static mp_obj_t gpio_obj_read(mp_obj_t self_in) {
hal_gpio_obj_t *self = self_in;
return MP_OBJ_NEW_SMALL_INT(gpio_read(&self->gpio));
}

static mp_obj_t gpio_obj_write(mp_obj_t self_in, mp_obj_t value_obj) {
hal_gpio_obj_t *self = self_in;
int value = mp_obj_get_int(value_obj);
gpio_dir(&self->gpio, value);
return mp_const_none;
}

static void gpio_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
hal_gpio_obj_t *self = self_in;
print(env, "<GPIO %u>", self->pin);
}

static MP_DEFINE_CONST_FUN_OBJ_2(gpio_obj_mode_obj, gpio_obj_mode);
static MP_DEFINE_CONST_FUN_OBJ_2(gpio_obj_dir_obj, gpio_obj_dir);
static MP_DEFINE_CONST_FUN_OBJ_1(gpio_obj_read_obj, gpio_obj_read);
static MP_DEFINE_CONST_FUN_OBJ_2(gpio_obj_write_obj, gpio_obj_write);

static bool gpio_call_kwarg(mp_obj_t param, mp_obj_t key, mp_obj_t value) {
hal_gpio_obj_t *self = param;
mp_obj_t fn = rt_load_attr(self, mp_obj_str_get_qstr(key));
if (fn != MP_OBJ_NULL) {
rt_call_function_1(fn, value);
}
return true;
}

mp_obj_t hal_Gpio_init(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
hal_gpio_obj_t *self = args[0];
int pin = mp_obj_get_int(args[1]);
gpio_init(&self->gpio, pin, PIN_INPUT);
mp_map_walk(kwargs, gpio_call_kwarg, self);
return mp_const_none;
}

MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN_KW(hal_Gpio_init_obj, 2, 2, hal_Gpio_init);

void hal_init_Gpio_class(mp_obj_t module_obj) {
mp_obj_t gpio_class_type = mp_obj_new_type("Gpio", mp_const_empty_tuple, mp_obj_new_dict(0));
((mp_obj_type_t *)gpio_class_type)->print = gpio_obj_print;
rt_store_attr(gpio_class_type, QSTR_FROM_STR_STATIC("__init__"), (mp_obj_t)&hal_Gpio_init_obj);
rt_store_attr(gpio_class_type, QSTR_FROM_STR_STATIC("dir"), (mp_obj_t)&gpio_obj_dir_obj);
rt_store_attr(gpio_class_type, QSTR_FROM_STR_STATIC("mode"), (mp_obj_t)&gpio_obj_mode_obj);
rt_store_attr(gpio_class_type, QSTR_FROM_STR_STATIC("read"), (mp_obj_t)&gpio_obj_read_obj);
rt_store_attr(gpio_class_type, QSTR_FROM_STR_STATIC("write"), (mp_obj_t)&gpio_obj_write_obj);
rt_store_attr(module_obj, QSTR_FROM_STR_STATIC("Gpio"), gpio_class_type);

// Allow the target to add its own constants and methods
hal_target_init_Gpio_class(gpio_class_type);
}
8 changes: 8 additions & 0 deletions embed/hal_gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
typedef struct {
mp_obj_base_t base;
PinName pin;
gpio_t gpio;
} hal_gpio_obj_t;

void hal_init_Gpio_class(mp_obj_t module_obj);

15 changes: 15 additions & 0 deletions py/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
}
}

void mp_map_walk(mp_map_t *map, bool (*fn)(void *param, mp_obj_t key, mp_obj_t value), void *param) {
uint pos;
if (!map) {
return;
}
for (pos = 0; pos < map->alloc; pos++) {
mp_map_elem_t *elem = &map->table[pos];
if (elem->key != NULL) {
if (!fn(param, elem->key, elem->value)) {
return;
}
}
}
}

/******************************************************************************/
/* set */

Expand Down
1 change: 1 addition & 0 deletions py/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mp_map_t *mp_map_new(int n);
void mp_map_deinit(mp_map_t *map);
void mp_map_free(mp_map_t *map);
mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
void mp_map_walk(mp_map_t *map, bool (*fn)(mp_obj_t param, mp_obj_t key, mp_obj_t value), mp_obj_t param);
void mp_map_clear(mp_map_t *map);

void mp_set_init(mp_set_t *set, int n);
Expand Down
1 change: 1 addition & 0 deletions py/obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 3, 3, (mp_fun_3_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN_KW(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, n_args_min, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)

// These macros are used to declare and define constant staticmethond and classmethod objects
Expand Down
10 changes: 9 additions & 1 deletion stm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ QSTR_DEFS = qstrdefsport.h

# include py core make definitions
include ../py/py.mk
include ../embed/embed.mk

CMSIS_DIR=cmsis
STMPERIPH_DIR=stmperiph
Expand All @@ -23,6 +24,7 @@ CFLAGS += -I$(STMUSBD_DIR)
CFLAGS += -I$(STMUSBH_DIR)
CFLAGS += -I$(FATFS_DIR)
#CFLAGS += -I$(CC3K_DIR)
CFLAGS += $(CFLAGS_EMBED)

#Debugging/Optimization
ifeq ($(DEBUG), 1)
Expand Down Expand Up @@ -63,6 +65,7 @@ SRC_C = \
adc.c \
rtc.c \
file.c \
hal_target_gpio.c \
# pybwlan.c \

SRC_S = \
Expand Down Expand Up @@ -145,11 +148,16 @@ SRC_CC3K = $(addprefix $(CC3K_DIR)/,\
pybcc3k.c \
)

OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_STMPERIPH:.c=.o) $(SRC_STMUSB:.c=.o))
OBJ = $(PY_O) $(EMBED_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_STMPERIPH:.c=.o) $(SRC_STMUSB:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBD:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
OBJ += $(addprefix $(BUILD)/hal/, $(SRC_HAL:.c=.o))

$(BUILD)/hal/%.o: %.c
$(compile_c)

all: $(BUILD) $(BUILD)/flash.dfu

Expand Down
14 changes: 14 additions & 0 deletions stm/cmsis/cmsis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* mbed Microcontroller Library - CMSIS
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* A generic CMSIS include header, pulling in STM32F407 specifics
*/

#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H

#include "stm32f4xx.h"
#include "cmsis_nvic.h"

#endif

26 changes: 26 additions & 0 deletions stm/cmsis/cmsis_nvic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* mbed Microcontroller Library - cmsis_nvic
* Copyright (c) 2009-2011 ARM Limited. All rights reserved.
*
* CMSIS-style functionality to support dynamic vectors
*/

#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H

#define NVIC_NUM_VECTORS (16 + 81) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16

#include "cmsis.h"

#ifdef __cplusplus
extern "C" {
#endif

void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
uint32_t NVIC_GetVector(IRQn_Type IRQn);

#ifdef __cplusplus
}
#endif

#endif
50 changes: 50 additions & 0 deletions stm/hal_target_gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <string.h>

#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"

#include "gpio_api.h"
#include "hal.h"
#include "hal_gpio.h"

const static hal_int_const target_gpio_const[] = {
{ "DIR_INPUT", 0 },
{ "DIR_OUTPUT", 1 },

{ "PUD_NONE", 0 },
{ "PUD_UP", 1 },
{ "PUD_DOWN", 2 },
{ "PUD_OPEN_DRAIN", 3 },

{ "SPEED_LOW", 0 },
{ "SPEED_MEDIUM", 1 },
{ "SPEED_FAST", 2 },
{ "SPEED_HIGH", 3 },

{ NULL, 0 }
};

static mp_obj_t gpio_obj_speed(mp_obj_t self_in, mp_obj_t speed_obj) {
hal_gpio_obj_t *self = self_in;
int speed = mp_obj_get_int(speed_obj) & 3;

uint32_t port_index = (uint32_t) self->pin >> 4;
GPIO_TypeDef *port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (port_index << 10));

int pin_shift = (self->pin & 0x0f) << 1;
port_reg->OSPEEDR = (port_reg->OSPEEDR & ~(3 << pin_shift)) | (speed << pin_shift);

return mp_const_none;
}

static MP_DEFINE_CONST_FUN_OBJ_2(gpio_obj_speed_obj, gpio_obj_speed);

void hal_target_init_Gpio_class(mp_obj_t gpio_class_type) {
for (const hal_int_const *c = target_gpio_const; c->const_name != NULL; c++) {
rt_store_attr(gpio_class_type, qstr_from_str(c->const_name), MP_OBJ_NEW_SMALL_INT(c->const_val));
}
rt_store_attr(gpio_class_type, QSTR_FROM_STR_STATIC("speed"), (mp_obj_t)&gpio_obj_speed_obj);
}
11 changes: 10 additions & 1 deletion stm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include "adc.h"
#include "rtc.h"
#include "file.h"
#include "gpio_api.h"
#include "hal.h"
#include "hal_gpio.h"

int errno;

Expand Down Expand Up @@ -72,6 +75,11 @@ void __fatal_error(const char *msg) {
}
}

// mbed_die is provided for the mbed hal routines
void mbed_die(void) {
__fatal_error("mbed_die");
}

static mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
static mp_obj_t pyb_config_main = MP_OBJ_NULL;

Expand Down Expand Up @@ -319,7 +327,7 @@ int readline(vstr_t *line, const char *prompt) {
return 1;
} else if (c == 27) {
escape = true;
} else if (c == 127) {
} else if (c == 127 || c == 8) {
if (vstr_len(line) > len) {
vstr_cut_tail(line, 1);
stdout_tx_str("\b \b");
Expand Down Expand Up @@ -670,6 +678,7 @@ int main(void) {
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);
hal_target_init_Gpio_class(m);
rt_store_name(MP_QSTR_pyb, m);

rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open));
Expand Down
2 changes: 2 additions & 0 deletions stm/qstrdefsport.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ Q(rand)
Q(Led)
Q(Servo)
Q(I2C)
Q(Gpio)
Q(gpio)
Q(Usart)
Q(ADC)
Q(Adc)
Q(open)