Skip to content
Snippets Groups Projects
Commit a94eabde authored by schneider's avatar schneider
Browse files

Merge branch 'schneider/max30001-pycardium' into schneider/max30001

parents 1a51d3b3 17121b50
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,7 @@ modsrc = files( ...@@ -9,6 +9,7 @@ modsrc = files(
'modules/interrupt.c', 'modules/interrupt.c',
'modules/sys_leds.c', 'modules/sys_leds.c',
'modules/light_sensor.c', 'modules/light_sensor.c',
'modules/max30001-sys.c',
'modules/os.c', 'modules/os.c',
'modules/personal_state.c', 'modules/personal_state.c',
'modules/power.c', 'modules/power.c',
......
...@@ -91,6 +91,9 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = { ...@@ -91,6 +91,9 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = {
MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ORIENTATION) }, MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ORIENTATION) },
{ MP_ROM_QSTR(MP_QSTR_BHI160_GYROSCOPE), { MP_ROM_QSTR(MP_QSTR_BHI160_GYROSCOPE),
MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_GYROSCOPE) }, MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_GYROSCOPE) },
{ MP_ROM_QSTR(MP_QSTR_MAX30001_ECG),
MP_OBJ_NEW_SMALL_INT(EPIC_INT_MAX30001_ECG) },
}; };
static MP_DEFINE_CONST_DICT( static MP_DEFINE_CONST_DICT(
interrupt_module_globals, interrupt_module_globals_table interrupt_module_globals, interrupt_module_globals_table
......
#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_max30001_enable_sensor(size_t n_args, const mp_obj_t *args)
{
struct max30001_sensor_config cfg = { 0 };
cfg.usb = mp_obj_is_true(args[0]);
cfg.bias = mp_obj_is_true(args[1]);
cfg.sample_rate = mp_obj_get_int(args[2]);
cfg.sample_buffer_len = mp_obj_get_int(args[3]);
int stream_id = epic_max30001_enable_sensor(&cfg);
return MP_OBJ_NEW_SMALL_INT(stream_id);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mp_max30001_enable_sensor_obj, 4, 4, mp_max30001_enable_sensor
);
STATIC mp_obj_t mp_max30001_read_sensor(mp_obj_t stream_id_in)
{
int16_t buf[256];
int stream_id = mp_obj_get_int(stream_id_in);
int n = epic_stream_read(stream_id, buf, sizeof(buf));
mp_obj_list_t *list = mp_obj_new_list(0, NULL);
for (int i = 0; i < n; i++) {
mp_obj_list_append(list, mp_obj_new_int(buf[i]));
}
return MP_OBJ_FROM_PTR(list);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(
mp_max30001_read_sensor_obj, mp_max30001_read_sensor
);
STATIC mp_obj_t mp_max30001_disable_sensor(void)
{
int ret = epic_max30001_disable_sensor();
return MP_OBJ_NEW_SMALL_INT(ret);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(
mp_max30001_disable_sensor_obj, mp_max30001_disable_sensor
);
STATIC const mp_rom_map_elem_t max30001_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys_max30001) },
{ MP_ROM_QSTR(MP_QSTR_enable_sensor),
MP_ROM_PTR(&mp_max30001_enable_sensor_obj) },
{ MP_ROM_QSTR(MP_QSTR_read_sensor),
MP_ROM_PTR(&mp_max30001_read_sensor_obj) },
{ MP_ROM_QSTR(MP_QSTR_disable_sensor),
MP_ROM_PTR(&mp_max30001_disable_sensor_obj) },
};
STATIC MP_DEFINE_CONST_DICT(
max30001_module_globals, max30001_module_globals_table
);
// Define module object.
const mp_obj_module_t max30001_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&max30001_module_globals,
};
/* clang-format off */
// Register the module to make it available in Python
MP_REGISTER_MODULE(MP_QSTR_sys_max30001, max30001_module, MODULE_MAX30001_ENABLED);
import sys_max30001
import interrupt
import ucollections
class MAX30001:
def __init__(
self,
usb=False,
bias=True,
sample_rate=128,
callback=None,
sample_buffer_len=256,
):
self.sample_rate = sample_rate
self.callback = callback
self.sample_buffer_len = sample_buffer_len
self.interrupt_id = interrupt.MAX30001_ECG
self.usb = usb
self.bias = bias
self._callback = callback
self.enable_sensor()
def enable_sensor(self):
interrupt.disable_callback(self.interrupt_id)
interrupt.set_callback(self.interrupt_id, self._interrupt)
self.stream_id = sys_max30001.enable_sensor(
self.usb, self.bias, self.sample_rate, self.sample_buffer_len
)
if self.stream_id < 0:
raise ValueError("Enable sensor returned %i", self.stream_id)
self.active = True
if self._callback:
interrupt.enable_callback(self.interrupt_id)
def __enter__(self):
return self
def __exit__(self, _et, _ev, _t):
self.close()
def close(self):
if self.active:
self.active = False
ret = sys_max30001.disable_sensor(self.sensor_id)
if ret < 0:
raise ValueError("Disable sensor returned %i", ret)
interrupt.disable_callback(self.interrupt_id)
interrupt.set_callback(self.interrupt_id, None)
def read(self):
if self.active:
return sys_max30001.read_sensor(self.stream_id)
return []
def _interrupt(self, _):
if self.active:
data = self.read()
if self._callback:
self._callback(data)
...@@ -4,6 +4,7 @@ python_modules = files( ...@@ -4,6 +4,7 @@ python_modules = files(
'htmlcolor.py', 'htmlcolor.py',
'display.py', 'display.py',
'leds.py', 'leds.py',
'max30001.py',
'pride.py', 'pride.py',
'ledfx.py', 'ledfx.py',
'simple_menu.py', 'simple_menu.py',
......
...@@ -163,3 +163,5 @@ Q(NO_CONTACT) ...@@ -163,3 +163,5 @@ Q(NO_CONTACT)
Q(CHAOS) Q(CHAOS)
Q(COMMUNICATION) Q(COMMUNICATION)
Q(CAMP) Q(CAMP)
Q(MAX30001_ECG)
...@@ -53,6 +53,7 @@ int mp_hal_trng_read_int(void); ...@@ -53,6 +53,7 @@ int mp_hal_trng_read_int(void);
#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)
#define MODULE_MAX30001_ENABLED (1)
#define MODULE_OS_ENABLED (1) #define MODULE_OS_ENABLED (1)
#define MODULE_PERSONAL_STATE_ENABLED (1) #define MODULE_PERSONAL_STATE_ENABLED (1)
#define MODULE_POWER_ENABLED (1) #define MODULE_POWER_ENABLED (1)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment