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

hack(ptt): trivial PTT implementation

parent ad28755b
No related branches found
No related tags found
No related merge requests found
Pipeline #5045 failed
......@@ -239,8 +239,9 @@ API(API_INTERRUPT_IS_ENABLED, int epic_interrupt_is_enabled(api_int_id_t int_id,
#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 */
/*
......
......@@ -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,21 @@ 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);
......
......@@ -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(
......
import ble_hid
import buttons
import max86150
import leds
import vibra
import display
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import time
class Proximity:
def __init__(self, callback):
self.callback = callback
self.pressed = False
def open(self):
def callback(datasets):
if len(datasets) > 0 and self.pressed:
pressed = True
for val in datasets:
# Threshold of proximity interrupt
if val.infrared < 32 * 2**10:
pressed = False
if not pressed:
self.pressed = pressed
self.callback(self.pressed)
def prox():
self.pressed = True
self.callback(self.pressed)
self.sensor = max86150.MAX86150(callback=callback, prox_callback=prox, sample_rate=400)
def close(self):
if self.self is not None:
self.sensor.close()
self.sensor = None
def prox_callback(state):
if state:
k.press(Keycode.LEFT_CONTROL)
leds.set_rocket(1, 31)
vibra.vibrate(20)
disp.print("Speak now")
disp.update()
disp.backlight(20)
else:
k.release(Keycode.LEFT_CONTROL)
leds.set_rocket(1, 0)
disp.backlight(0)
disp = display.open()
disp.clear().update()
disp.backlight(0)
sensor = Proximity(prox_callback).open()
k = Keyboard(ble_hid.devices)
b_old = buttons.read()
while True:
b_new = buttons.read()
if not b_old == b_new:
b_old = b_new
if b_new == buttons.TOP_RIGHT:
k.press(Keycode.LEFT_CONTROL)
else:
k.release(Keycode.LEFT_CONTROL)
time.sleep(0.05)
......@@ -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) },
};
......
......@@ -26,7 +26,7 @@ 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 +37,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 +49,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 +61,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 +80,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 +103,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()
......@@ -186,6 +186,7 @@ Q(CAMP)
/* required for interrupts */
Q(MAX30001_ECG)
Q(MAX86150)
Q(MAX86150_PROX)
/* ws2812 */
Q(ws2812)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment