diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 2cfc527ad173a83e6e5de521caa8838ad49500a2..210453495ba49fda0a25c11d02f6e71b23362677 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -236,11 +236,12 @@ API(API_INTERRUPT_IS_ENABLED, int epic_interrupt_is_enabled(api_int_id_t int_id, /** BHI160 Magnetometer. See :c:func:`epic_isr_bhi160_magnetometer`. */ #define EPIC_INT_BHI160_MAGNETOMETER 8 /** MAX86150 ECG and PPG sensor. See :c:func:`epic_isr_max86150`. */ -#define EPIC_INT_MAX86150 9 +#define EPIC_INT_MAX86150 9 /** Bluetooth Low Energy event. See :c:func:`epic_isr_ble`. */ #define EPIC_INT_BLE 10 +#define EPIC_INT_MAX86150_PROX 11 /* Number of defined interrupts. */ -#define EPIC_INT_NUM 11 +#define EPIC_INT_NUM 12 /* clang-format on */ /* diff --git a/epicardium/modules/max86150.c b/epicardium/modules/max86150.c index 0ed8367e04442a509396fa631acde48c049437c9..890aa7d27621db111e96b7e29f7299000a996c27 100644 --- a/epicardium/modules/max86150.c +++ b/epicardium/modules/max86150.c @@ -139,8 +139,6 @@ static int max86150_handle_sample(struct max86150_sensor_data *data) max86150_stream.was_full = false; } - interrupt_trigger(EPIC_INT_MAX86150); - return 0; } @@ -156,15 +154,23 @@ static int max86150_fetch_fifo(void) // There is a recommendation from Maxim not to read the entire FIFO, but rather a fixed number of samples. // See https://os.mbed.com/users/laserdad/code/MAX86150_ECG_PPG//file/3c728f3d1f10/main.cpp/ // So we should not use max86150_check() but max86150_get_sample(). + int n = 0; while (max86150_get_sample(&sample.red, &sample.ir, &sample.ecg) > 0) { + n++; result = max86150_handle_sample(&sample); // stop in case of errors if (result < 0) { + n = 0; break; } } hwlock_release(HWLOCK_I2C); mutex_unlock(&max86150_mutex); + + if (n > 0) { + interrupt_trigger(EPIC_INT_MAX86150); + } + //LOG_INFO("max86150", "%d", n); return result; } @@ -221,6 +227,20 @@ void vMAX86150Task(void *pvParameters) while (1) { if (max86150_sensor_active) { //LOG_INFO("max86150", "Interrupt!"); + mutex_lock(&max86150_mutex); + hwlock_acquire(HWLOCK_I2C); + + int i1 = max86150_get_int1(); + + hwlock_release(HWLOCK_I2C); + mutex_unlock(&max86150_mutex); + + //LOG_INFO("max86150", "%d", i1); + + if (i1 & 16) { + interrupt_trigger(EPIC_INT_MAX86150_PROX); + } + int ret = max86150_fetch_fifo(); if (ret < 0) { LOG_ERR("max86150", "Unknown error: %d", -ret); diff --git a/lib/vendor/Maxim/MAX86150/max86150.c b/lib/vendor/Maxim/MAX86150/max86150.c index 4bbd68389f9f3822922ae52787a0207ba53f8243..8a49aba676aca0b57fe3dd7d9c3498f3b77cc67e 100644 --- a/lib/vendor/Maxim/MAX86150/max86150.c +++ b/lib/vendor/Maxim/MAX86150/max86150.c @@ -549,6 +549,10 @@ void max86150_setup(const uint8_t ppg_sample_rate) max86150_set_led_ir_amplitude(0x66); max86150_set_led_red_amplitude(0x66); + max86150_set_led_proximity_amplitude(0x66); + max86150_set_proximity_threshold(32); + max86150_set_int_proximity(true); + max86150_set_ecg_sample_rate(MAX86150_ECG_SAMPLERATE_200); max86150_set_ecg_pga_gain(MAX86150_ECG_PGA_GAIN_8); max86150_set_ecg_instrumentation_amplifier_gain( diff --git a/pycardium/modules/interrupt.c b/pycardium/modules/interrupt.c index 1e7fcd89ff85d0940611f37ae170e0321aa04a27..476237a4ad0097ee0cbea3cb1166eb3e187d7fc7 100644 --- a/pycardium/modules/interrupt.c +++ b/pycardium/modules/interrupt.c @@ -99,6 +99,8 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = { MP_OBJ_NEW_SMALL_INT(EPIC_INT_MAX30001_ECG) }, { MP_ROM_QSTR(MP_QSTR_MAX86150), MP_OBJ_NEW_SMALL_INT(EPIC_INT_MAX86150) }, + { MP_ROM_QSTR(MP_QSTR_MAX86150_PROX), + MP_OBJ_NEW_SMALL_INT(EPIC_INT_MAX86150_PROX) }, { MP_ROM_QSTR(MP_QSTR_BLE), MP_OBJ_NEW_SMALL_INT(EPIC_INT_BLE) }, }; diff --git a/pycardium/modules/py/max86150.py b/pycardium/modules/py/max86150.py index 6040eed0a5e3440dd95865b6e9d478b1647f1919..2a476b2f47a27f3fafa2de92e69bcea836cba7bb 100644 --- a/pycardium/modules/py/max86150.py +++ b/pycardium/modules/py/max86150.py @@ -26,7 +26,9 @@ class MAX86150: .. versionadded:: 1.16 """ - def __init__(self, callback=None, sample_buffer_len=128, sample_rate=200): + def __init__( + self, callback=None, sample_buffer_len=128, sample_rate=200, prox_callback=None + ): """ Initializes the MAX86150 (if it is not already running). @@ -37,6 +39,7 @@ class MAX86150: self.stream_id = -uerrno.ENODEV self.interrupt_id = interrupt.MAX86150 self._callback = callback + self._prox_callback = prox_callback self.sample_rate = sample_rate self.sample_buffer_len = sample_buffer_len self.enable_sensor() @@ -48,7 +51,9 @@ class MAX86150: Automatically called when instanciating the sensor object. """ interrupt.disable_callback(self.interrupt_id) + interrupt.disable_callback(interrupt.MAX86150_PROX) interrupt.set_callback(self.interrupt_id, self._interrupt) + interrupt.set_callback(interrupt.MAX86150_PROX, self._prox_interrupt) self.stream_id = sys_max86150.enable_sensor( self.sample_buffer_len, self.sample_rate ) @@ -58,6 +63,9 @@ class MAX86150: if self._callback: interrupt.enable_callback(self.interrupt_id) + if self._prox_callback: + interrupt.enable_callback(interrupt.MAX86150_PROX) + def __enter__(self): return self @@ -74,7 +82,10 @@ class MAX86150: sys_max86150.disable_sensor() interrupt.disable_callback(self.interrupt_id) + interrupt.disable_callback(interrupt.MAX86150) + interrupt.set_callback(self.interrupt_id, None) + interrupt.set_callback(interrupt.MAX86150, None) def read(self): """ @@ -94,3 +105,8 @@ class MAX86150: data = self.read() if self._callback: self._callback(data) + + def _prox_interrupt(self, _): + if self.active: + if self._prox_callback: + self._prox_callback() diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h index 2f144702f7cf929453306eb6e92a132c0394cb84..721509d776b4d180418f530c64a2f14de6180f17 100644 --- a/pycardium/modules/qstrdefs.h +++ b/pycardium/modules/qstrdefs.h @@ -186,6 +186,7 @@ Q(CAMP) /* required for interrupts */ Q(MAX30001_ECG) Q(MAX86150) +Q(MAX86150_PROX) /* ws2812 */ Q(ws2812)