From 230016c4ee8a1cc341b05b8615b953a5b08581da 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 | 4 +-- epicardium/modules/bhi.c | 4 +++ epicardium/modules/serial.c | 2 +- pycardium/meson.build | 1 + pycardium/modules/bhi160-sys.c | 61 ++++++++++++++++++++++++++++++++ pycardium/modules/interrupt.c | 2 +- pycardium/modules/py/bhi160.py | 32 +++++++++++++++++ pycardium/modules/py/meson.build | 1 + pycardium/modules/qstrdefs.h | 6 +++- pycardium/mpconfigport.h | 1 + 10 files changed, 109 insertions(+), 5 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 85fc686f..da8444a1 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -99,8 +99,8 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id)); /** ``^C`` interrupt. See :c:func:`epic_isr_ctrl_c` for details. */ #define EPIC_INT_CTRL_C 1 /* Debug interrupt, please ignore */ -#define EPIC_INT_BHI160_TEST 2 -API_ISR(EPIC_INT_BHI160_TEST, epic_isr_bhi160_test); +#define EPIC_INT_BHI160_ACCELEROMETER 2 +API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer); /* Number of defined interrupts. */ #define EPIC_INT_NUM 3 diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c index 79ce0a72..b237dd53 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" @@ -215,6 +216,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/epicardium/modules/serial.c b/epicardium/modules/serial.c index bf341fe7..25fe11e4 100644 --- a/epicardium/modules/serial.c +++ b/epicardium/modules/serial.c @@ -62,7 +62,7 @@ static void enqueue_char(char chr) if (chr == 0x0e) { /* Control-N */ - api_interrupt_trigger(EPIC_INT_BHI160_TEST); + /* Unused at the moment. Used to trigger test functions when needed */ } if (xQueueSend(read_queue, &chr, 100) == errQUEUE_FULL) { diff --git a/pycardium/meson.build b/pycardium/meson.build index cf5f5ba5..763431b3 100644 --- a/pycardium/meson.build +++ b/pycardium/meson.build @@ -1,6 +1,7 @@ name = 'pycardium' modsrc = files( + 'modules/bhi160-sys.c', 'modules/interrupt.c', 'modules/leds.c', 'modules/sys_display.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 8a1a4c28..416aeaf5 100644 --- a/pycardium/modules/interrupt.c +++ b/pycardium/modules/interrupt.c @@ -81,7 +81,7 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = { MP_ROM_PTR(&interrupt_enable_callback_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_callback), MP_ROM_PTR(&interrupt_disable_callback_obj) }, - { MP_ROM_QSTR(MP_QSTR_BHI160), MP_OBJ_NEW_SMALL_INT(2) }, + { MP_ROM_QSTR(MP_QSTR_BHI160_ACCELEROMETER), MP_OBJ_NEW_SMALL_INT(2) }, }; 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..b03ba52c --- /dev/null +++ b/pycardium/modules/py/bhi160.py @@ -0,0 +1,32 @@ +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(): + if self.acc_sd != 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 != 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 eab92f95..d164445c 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 e8ac9dac..b60308a5 100644 --- a/pycardium/modules/qstrdefs.h +++ b/pycardium/modules/qstrdefs.h @@ -29,7 +29,11 @@ Q(vibrate) Q(set_callback) Q(enable_callback) Q(disable_callback) -Q(BHI160) +Q(BHI160_ACCELEROMETER) + +Q(sys_bhi160) +Q(enable_sensor) +Q(read_sensor) /* display */ Q(sys_display) diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h index 9bed1f60..2f220b00 100644 --- a/pycardium/mpconfigport.h +++ b/pycardium/mpconfigport.h @@ -38,6 +38,7 @@ /* Modules */ #define MODULE_UTIME_ENABLED (1) +#define MODULE_BHI160_ENABLED (1) #define MODULE_LEDS_ENABLED (1) #define MODULE_VIBRA_ENABLED (1) #define MODULE_INTERRUPT_ENABLED (1) -- GitLab