Skip to content
Snippets Groups Projects
Commit 614f7bb8 authored by trilader's avatar trilader
Browse files

Implement Python module for wristband GPIO access (Fixes #31)

parent 1e7b2265
No related branches found
No related tags found
No related merge requests found
Pipeline #2226 passed
...@@ -90,6 +90,11 @@ typedef _Bool bool; ...@@ -90,6 +90,11 @@ typedef _Bool bool;
#define API_LIGHT_SENSOR_STOP 0x82 #define API_LIGHT_SENSOR_STOP 0x82
#define API_BUTTONS_READ 0x90 #define API_BUTTONS_READ 0x90
#define API_GPIO_SET_PIN_MODE 0x100
#define API_GPIO_GET_PIN_MODE 0x101
#define API_GPIO_WRITE_PIN 0x102
#define API_GPIO_READ_PIN 0x103
/* clang-format on */ /* clang-format on */
typedef uint32_t api_int_id_t; typedef uint32_t api_int_id_t;
...@@ -338,6 +343,29 @@ enum epic_button { ...@@ -338,6 +343,29 @@ enum epic_button {
*/ */
API(API_BUTTONS_READ, uint8_t epic_buttons_read(uint8_t mask)); API(API_BUTTONS_READ, uint8_t epic_buttons_read(uint8_t mask));
/**
* Wristband GPIO
*/
enum gpio_button {
GPIO_WRISTBAND_1 = 1,
GPIO_WRISTBAND_2 = 2,
GPIO_WRISTBAND_3 = 3,
GPIO_WRISTBAND_4 = 4,
};
enum gpio_mode {
GPIO_MODE_IN = (1<<0),
GPIO_MODE_OUT = (1<<1),
GPIO_PULL_UP = (1<<6),
GPIO_PULL_DOWN = (1<<7),
};
API(API_GPIO_SET_PIN_MODE, void epic_gpio_set_pin_mode(uint8_t pin, uint8_t mode));
API(API_GPIO_GET_PIN_MODE, uint8_t epic_gpio_get_pin_mode(uint8_t pin));
API(API_GPIO_WRITE_PIN, void epic_gpio_write_pin(uint8_t pin, bool on));
API(API_GPIO_READ_PIN, uint32_t epic_gpio_read_pin(uint8_t pin));
/** /**
* LEDs * LEDs
* ==== * ====
......
#include "epicardium.h"
#include "gpio.h"
#include "max32665.h"
/*
* Despite what the schematic (currently, 2019-08-18) says these are the correct
* pins for wristband GPIO 1-4 (not 0-3 as the schematic states)
*/
static gpio_cfg_t gpio_configs[] = {
[GPIO_WRISTBAND_1] = { PORT_0, PIN_21, GPIO_FUNC_OUT, GPIO_PAD_NONE },
[GPIO_WRISTBAND_2] = { PORT_0, PIN_22, GPIO_FUNC_OUT, GPIO_PAD_NONE },
[GPIO_WRISTBAND_3] = { PORT_0, PIN_29, GPIO_FUNC_OUT, GPIO_PAD_NONE },
[GPIO_WRISTBAND_4] = { PORT_0, PIN_20, GPIO_FUNC_OUT, GPIO_PAD_NONE },
};
void epic_gpio_set_pin_mode(uint8_t pin, uint8_t mode)
{
if (pin < GPIO_WRISTBAND_1 || pin > GPIO_WRISTBAND_4)
return;
gpio_cfg_t *cfg = &gpio_configs[pin];
uint32_t func_value = 0;
if (mode & GPIO_MODE_IN)
func_value |= GPIO_FUNC_IN;
if (mode & GPIO_MODE_OUT)
func_value |= GPIO_FUNC_OUT;
uint32_t pad_value = 0;
if (mode & GPIO_PULL_UP)
pad_value |= GPIO_PAD_PULL_UP;
if (mode & GPIO_PULL_DOWN)
pad_value |= GPIO_PAD_PULL_DOWN;
cfg->func = func_value;
cfg->pad = pad_value;
GPIO_Config(cfg);
}
uint8_t epic_gpio_get_pin_mode(uint8_t pin)
{
if (pin < GPIO_WRISTBAND_1 || pin > GPIO_WRISTBAND_4)
return 0;
gpio_cfg_t *cfg = &gpio_configs[pin];
uint8_t res = 0;
if ((cfg->func & GPIO_FUNC_IN) == GPIO_FUNC_IN)
res |= GPIO_MODE_IN;
if ((cfg->func & GPIO_FUNC_OUT) == GPIO_FUNC_OUT)
res |= GPIO_MODE_OUT;
if ((cfg->pad & GPIO_PAD_PULL_UP) == GPIO_PAD_PULL_UP)
res |= GPIO_PULL_UP;
if ((cfg->pad & GPIO_PAD_PULL_DOWN) == GPIO_PAD_PULL_DOWN)
res |= GPIO_PULL_DOWN;
return res;
}
void epic_gpio_write_pin(uint8_t pin, bool on)
{
if (pin < GPIO_WRISTBAND_1 || pin > GPIO_WRISTBAND_4)
return;
gpio_cfg_t *cfg = &gpio_configs[pin];
if (on)
GPIO_OutSet(cfg);
else
GPIO_OutClr(cfg);
}
uint32_t epic_gpio_read_pin(uint8_t pin)
{
if (pin < GPIO_WRISTBAND_1 || pin > GPIO_WRISTBAND_4)
return 0U;
gpio_cfg_t *cfg = &gpio_configs[pin];
if ((cfg->func & GPIO_FUNC_OUT) == GPIO_FUNC_OUT) {
return GPIO_OutGet(cfg);
} else if ((cfg->func & GPIO_FUNC_IN) == GPIO_FUNC_IN) {
return GPIO_InGet(cfg);
} else {
return -1;
}
}
...@@ -3,6 +3,7 @@ module_sources = files( ...@@ -3,6 +3,7 @@ module_sources = files(
'dispatcher.c', 'dispatcher.c',
'display.c', 'display.c',
'fileops.c', 'fileops.c',
'gpio.c',
'hardware.c', 'hardware.c',
'leds.c', 'leds.c',
'lifecycle.c', 'lifecycle.c',
......
...@@ -4,6 +4,7 @@ modsrc = files( ...@@ -4,6 +4,7 @@ modsrc = files(
'modules/buttons.c', 'modules/buttons.c',
'modules/fat_file.c', 'modules/fat_file.c',
'modules/fat_reader_import.c', 'modules/fat_reader_import.c',
'modules/gpio.c',
'modules/interrupt.c', 'modules/interrupt.c',
'modules/sys_leds.c', 'modules/sys_leds.c',
'modules/light_sensor.c', 'modules/light_sensor.c',
......
#include "py/obj.h"
#include "epicardium.h"
static mp_obj_t mp_gpio_set_mode(mp_obj_t pin_obj, mp_obj_t mode_obj)
{
int pin = mp_obj_get_int(pin_obj);
int mode = mp_obj_get_int(mode_obj);
epic_gpio_set_pin_mode(pin, mode);
return mp_const_none;
};
static MP_DEFINE_CONST_FUN_OBJ_2(gpio_set_mode, mp_gpio_set_mode);
static mp_obj_t mp_gpio_get_mode(mp_obj_t pin_obj)
{
int pin = mp_obj_get_int(pin_obj);
uint8_t mode = epic_gpio_get_pin_mode(pin);
return MP_OBJ_NEW_SMALL_INT(mode);
};
static MP_DEFINE_CONST_FUN_OBJ_1(gpio_get_mode, mp_gpio_get_mode);
static mp_obj_t mp_gpio_read(mp_obj_t pin_obj)
{
int pin = mp_obj_get_int(pin_obj);
uint32_t value = epic_gpio_read_pin(pin);
return MP_OBJ_NEW_SMALL_INT(value);
};
static MP_DEFINE_CONST_FUN_OBJ_1(gpio_read, mp_gpio_read);
static mp_obj_t mp_gpio_write(mp_obj_t pin_obj, mp_obj_t on_obj)
{
int pin = mp_obj_get_int(pin_obj);
bool on = mp_obj_is_true(on_obj);
epic_gpio_write_pin(pin, on);
return mp_const_none;
};
static MP_DEFINE_CONST_FUN_OBJ_2(gpio_write, mp_gpio_write);
static const mp_rom_map_elem_t gpio_module_modes_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mode) },
{ MP_ROM_QSTR(MP_QSTR_INPUT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IN) },
{ MP_ROM_QSTR(MP_QSTR_OUTPUT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUT) },
{ MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULL_UP) },
{ MP_ROM_QSTR(MP_QSTR_PULL_DOWN),
MP_OBJ_NEW_SMALL_INT(GPIO_PULL_DOWN) },
};
static MP_DEFINE_CONST_DICT(gpio_module_modes_dict, gpio_module_modes_table);
const mp_obj_module_t gpio_module_modes = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&gpio_module_modes_dict,
};
/* The globals table for this module */
static const mp_rom_map_elem_t gpio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gpio) },
{ MP_ROM_QSTR(MP_QSTR_set_mode), MP_ROM_PTR(&gpio_set_mode) },
{ MP_ROM_QSTR(MP_QSTR_get_mode), MP_ROM_PTR(&gpio_get_mode) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&gpio_read) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&gpio_write) },
{ MP_ROM_QSTR(MP_QSTR_WRISTBAND_1),
MP_OBJ_NEW_SMALL_INT(GPIO_WRISTBAND_1) },
{ MP_ROM_QSTR(MP_QSTR_WRISTBAND_2),
MP_OBJ_NEW_SMALL_INT(GPIO_WRISTBAND_2) },
{ MP_ROM_QSTR(MP_QSTR_WRISTBAND_3),
MP_OBJ_NEW_SMALL_INT(GPIO_WRISTBAND_3) },
{ MP_ROM_QSTR(MP_QSTR_WRISTBAND_4),
MP_OBJ_NEW_SMALL_INT(GPIO_WRISTBAND_4) },
{ MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&gpio_module_modes) },
};
static MP_DEFINE_CONST_DICT(gpio_module_globals, gpio_module_globals_table);
const mp_obj_module_t gpio_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&gpio_module_globals,
};
/* This is a special macro that will make MicroPython aware of this module */
/* clang-format off */
MP_REGISTER_MODULE(MP_QSTR_gpio, gpio_module, MODULE_GPIO_ENABLED);
...@@ -100,3 +100,18 @@ Q(exit) ...@@ -100,3 +100,18 @@ Q(exit)
Q(exec) Q(exec)
Q(listdir) Q(listdir)
Q(unlink) Q(unlink)
/* gpio */
Q(gpio)
Q(set_mode)
Q(get_mode)
Q(read)
Q(write)
Q(WRISTBAND_1)
Q(WRISTBAND_2)
Q(WRISTBAND_3)
Q(WRISTBAND_4)
Q(INPUT)
Q(OUTPUT)
Q(PULL_UP)
Q(PULL_DOWN)
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
/* Modules */ /* Modules */
#define MODULE_BUTTONS_ENABLED (1) #define MODULE_BUTTONS_ENABLED (1)
#define MODULE_DISPLAY_ENABLED (1) #define MODULE_DISPLAY_ENABLED (1)
#define MODULE_GPIO_ENABLED (1)
#define MODULE_INTERRUPT_ENABLED (1) #define MODULE_INTERRUPT_ENABLED (1)
#define MODULE_LEDS_ENABLED (1) #define MODULE_LEDS_ENABLED (1)
#define MODULE_LIGHT_SENSOR_ENABLED (1) #define MODULE_LIGHT_SENSOR_ENABLED (1)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment