From 25fc893968b1755fb94882650645e54ad73b4f7c Mon Sep 17 00:00:00 2001 From: schneider <schneider@blinkenlichts.net> Date: Sat, 27 Jul 2019 01:32:41 +0200 Subject: [PATCH] feat(bhi160): Initial Python support for the accelerometer --- epicardium/epicardium.h | 5 ++- epicardium/modules/bhi.c | 4 +++ pycardium/meson.build | 1 + pycardium/modules/bhi160-sys.c | 61 ++++++++++++++++++++++++++++++++ pycardium/modules/interrupt.c | 2 ++ pycardium/modules/py/bhi160.py | 38 ++++++++++++++++++++ pycardium/modules/py/meson.build | 1 + pycardium/modules/qstrdefs.h | 7 +++- pycardium/mpconfigport.h | 1 + 9 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 pycardium/modules/bhi160-sys.c create mode 100644 pycardium/modules/py/bhi160.py diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 930eb876..56158107 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -156,9 +156,12 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id)); #define EPIC_INT_UART_RX 2 /** RTC Alarm interrupt. See :c:func:`epic_isr_rtc_alarm` */ #define EPIC_INT_RTC_ALARM 3 +/** TODO: BHI */ +#define EPIC_INT_BHI160_ACCELEROMETER 4 +API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer); /* Number of defined interrupts. */ -#define EPIC_INT_NUM 4 +#define EPIC_INT_NUM 5 /* clang-format on */ /* diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c index 5e05e672..e824f70d 100644 --- a/epicardium/modules/bhi.c +++ b/epicardium/modules/bhi.c @@ -11,6 +11,7 @@ #include "semphr.h" #include "queue.h" +#include "api/interrupt-sender.h" #include "epicardium.h" #include "modules/log.h" #include "modules/modules.h" @@ -211,6 +212,9 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data) &data_vector, BHI160_MUTEX_WAIT_MS ); + if (sensor_id == VS_ID_ACCELEROMETER_WAKEUP) { + api_interrupt_trigger(EPIC_INT_BHI160_ACCELEROMETER); + } break; default: break; diff --git a/pycardium/meson.build b/pycardium/meson.build index f0a3798a..2c43f62f 100644 --- a/pycardium/meson.build +++ b/pycardium/meson.build @@ -1,6 +1,7 @@ name = 'pycardium' modsrc = files( + 'modules/bhi160-sys.c', 'modules/buttons.c', 'modules/fat_file.c', 'modules/fat_reader_import.c', diff --git a/pycardium/modules/bhi160-sys.c b/pycardium/modules/bhi160-sys.c new file mode 100644 index 00000000..35d81b25 --- /dev/null +++ b/pycardium/modules/bhi160-sys.c @@ -0,0 +1,61 @@ +#include "py/obj.h" +#include "py/runtime.h" +#include "py/builtin.h" +#include "epicardium.h" +#include "api/common.h" +#include "mphalport.h" + +STATIC mp_obj_t mp_bhi160_enable_sensor(size_t n_args, const mp_obj_t *args) +{ + int sensor_type = mp_obj_get_int(args[0]); + + struct bhi160_sensor_config cfg = { 0 }; + cfg.sample_buffer_len = mp_obj_get_int(args[1]); + cfg.sample_rate = mp_obj_get_int(args[2]); + cfg.dynamic_range = mp_obj_get_int(args[3]); + + //cfg.sample_buffer_len = 200; + //cfg.sample_rate = 4; + //cfg.dynamic_range = 2; + + int sd = epic_bhi160_enable_sensor(sensor_type, &cfg); + + return MP_OBJ_NEW_SMALL_INT(sd); +} + +STATIC mp_obj_t mp_bhi160_read_sensor(mp_obj_t stream_id_in) +{ + struct bhi160_data_vector buf[100]; + int sd = mp_obj_get_int(stream_id_in); + + int n = epic_stream_read(sd, buf, sizeof(buf)); + + return MP_OBJ_NEW_SMALL_INT(n); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( + mp_bhi160_enable_sensor_obj, 4, 4, mp_bhi160_enable_sensor +); + +STATIC MP_DEFINE_CONST_FUN_OBJ_1( + mp_bhi160_read_sensor_obj, mp_bhi160_read_sensor +); + +STATIC const mp_rom_map_elem_t bhi160_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys_bhi160) }, + { MP_ROM_QSTR(MP_QSTR_enable_sensor), + MP_ROM_PTR(&mp_bhi160_enable_sensor_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_sensor), + MP_ROM_PTR(&mp_bhi160_read_sensor_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bhi160_module_globals, bhi160_module_globals_table); + +// Define module object. +const mp_obj_module_t bhi160_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&bhi160_module_globals, +}; + +/* clang-format off */ +// Register the module to make it available in Python +MP_REGISTER_MODULE(MP_QSTR_sys_bhi160, bhi160_module, MODULE_BHI160_ENABLED); diff --git a/pycardium/modules/interrupt.c b/pycardium/modules/interrupt.c index 10770a19..90dd700a 100644 --- a/pycardium/modules/interrupt.c +++ b/pycardium/modules/interrupt.c @@ -85,6 +85,8 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = { /* Interrupt Numbers */ { MP_ROM_QSTR(MP_QSTR_RTC_ALARM), MP_OBJ_NEW_SMALL_INT(EPIC_INT_RTC_ALARM) }, + { MP_ROM_QSTR(MP_QSTR_BHI160_ACCELEROMETER), + MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ACCELEROMETER) }, }; static MP_DEFINE_CONST_DICT( interrupt_module_globals, interrupt_module_globals_table diff --git a/pycardium/modules/py/bhi160.py b/pycardium/modules/py/bhi160.py new file mode 100644 index 00000000..4d13895f --- /dev/null +++ b/pycardium/modules/py/bhi160.py @@ -0,0 +1,38 @@ +import sys_bhi160 +import interrupt + + +class BHI160Accelerometer: + def __init__( + self, sample_rate=4, dynamic_range=2, callback=None, sample_buffer_len=200 + ): + interrupt.disable_callback(interrupt.BHI160_ACCELEROMETER) + interrupt.set_callback( + interrupt.BHI160_ACCELEROMETER, self._accelerometer_interrupt + ) + self.acc_sd = sys_bhi160.enable_sensor( + 0, sample_buffer_len, sample_rate, dynamic_range + ) + self._callback = callback + if callback: + interrupt.enable_callback(interrupt.BHI160_ACCELEROMETER) + + def __enter__(self): + return self + + def __exit__(self, _et, _ev, _t): + self.close() + + def close(self): + if self.acc_sd is not None: + self.acc_sd = None + self.acc_sd = sys_bhi160.disable_sensor(0) + interrupt.disable_callback(interrupt.BHI160_ACCELEROMETER) + interrupt.set_callback(interrupt.BHI160_ACCELEROMETER, None) + + def _accelerometer_interrupt(self, _): + if self.acc_sd is not None: + data = sys_bhi160.read_sensor(self.acc_sd) + print(data) + if self._callback: + self._callback(data) diff --git a/pycardium/modules/py/meson.build b/pycardium/modules/py/meson.build index 2818ffa3..9bd34944 100644 --- a/pycardium/modules/py/meson.build +++ b/pycardium/modules/py/meson.build @@ -1,4 +1,5 @@ python_modules = files( + 'bhi160.py', 'color.py', 'htmlcolor.py', 'display.py', diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h index 60c5c56c..4d9ff17a 100644 --- a/pycardium/modules/qstrdefs.h +++ b/pycardium/modules/qstrdefs.h @@ -57,9 +57,14 @@ Q(vibrate) Q(set_callback) Q(enable_callback) Q(disable_callback) -Q(BHI160) +Q(BHI160_ACCELEROMETER) Q(RTC_ALARM) +/* bhi160 */ +Q(sys_bhi160) +Q(enable_sensor) +Q(read_sensor) + /* display */ Q(sys_display) Q(display) diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h index af27e146..b8486798 100644 --- a/pycardium/mpconfigport.h +++ b/pycardium/mpconfigport.h @@ -45,6 +45,7 @@ int mp_hal_trng_read_int(void); #define MICROPY_PY_UERRNO (1) /* Modules */ +#define MODULE_BHI160_ENABLED (1) #define MODULE_BME680_ENABLED (1) #define MODULE_BUTTONS_ENABLED (1) #define MODULE_DISPLAY_ENABLED (1) -- GitLab