Skip to content
Snippets Groups Projects
Verified Commit 344d06a1 authored by koalo's avatar koalo Committed by rahix
Browse files

feat(bhi160): Provide Gyroscope data

parent 3c021925
No related branches found
No related tags found
No related merge requests found
...@@ -157,9 +157,11 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id)); ...@@ -157,9 +157,11 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
/** TODO: BHI */ /** TODO: BHI */
#define EPIC_INT_BHI160_ACCELEROMETER 4 #define EPIC_INT_BHI160_ACCELEROMETER 4
API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer); API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer);
#define EPIC_INT_BHI160_GYROSCOPE 5
API_ISR(EPIC_INT_BHI160_GYROSCOPE, epic_isr_bhi160_gyroscope);
/* Number of defined interrupts. */ /* Number of defined interrupts. */
#define EPIC_INT_NUM 5 #define EPIC_INT_NUM 6
/* clang-format on */ /* clang-format on */
/* /*
...@@ -923,7 +925,7 @@ enum bhi160_sensor_type { ...@@ -923,7 +925,7 @@ enum bhi160_sensor_type {
BHI160_MAGNETOMETER = 1, BHI160_MAGNETOMETER = 1,
/** Orientation (**Unimplemented**) */ /** Orientation (**Unimplemented**) */
BHI160_ORIENTATION = 2, BHI160_ORIENTATION = 2,
/** Gyroscope (**Unimplemented**) */ /** Gyroscope */
BHI160_GYROSCOPE = 3, BHI160_GYROSCOPE = 3,
/** Gravity (**Unimplemented**) */ /** Gravity (**Unimplemented**) */
BHI160_GRAVITY = 4, BHI160_GRAVITY = 4,
......
...@@ -73,6 +73,7 @@ static size_t bhi160_lookup_data_size(enum bhi160_sensor_type type) ...@@ -73,6 +73,7 @@ static size_t bhi160_lookup_data_size(enum bhi160_sensor_type type)
case BHI160_ACCELEROMETER: case BHI160_ACCELEROMETER:
case BHI160_MAGNETOMETER: case BHI160_MAGNETOMETER:
case BHI160_ORIENTATION: case BHI160_ORIENTATION:
case BHI160_GYROSCOPE:
return sizeof(struct bhi160_data_vector); return sizeof(struct bhi160_data_vector);
default: default:
return 0; return 0;
...@@ -87,6 +88,8 @@ static bhy_virtual_sensor_t bhi160_lookup_vs_id(enum bhi160_sensor_type type) ...@@ -87,6 +88,8 @@ static bhy_virtual_sensor_t bhi160_lookup_vs_id(enum bhi160_sensor_type type)
switch (type) { switch (type) {
case BHI160_ACCELEROMETER: case BHI160_ACCELEROMETER:
return VS_ID_ACCELEROMETER; return VS_ID_ACCELEROMETER;
case BHI160_GYROSCOPE:
return VS_ID_GYROSCOPE;
default: default:
return -1; return -1;
} }
...@@ -100,6 +103,8 @@ static int bhi160_lookup_sd(enum bhi160_sensor_type type) ...@@ -100,6 +103,8 @@ static int bhi160_lookup_sd(enum bhi160_sensor_type type)
switch (type) { switch (type) {
case BHI160_ACCELEROMETER: case BHI160_ACCELEROMETER:
return SD_BHI160_ACCELEROMETER; return SD_BHI160_ACCELEROMETER;
case BHI160_GYROSCOPE:
return SD_BHI160_GYROSCOPE;
default: default:
return -1; return -1;
} }
...@@ -134,9 +139,14 @@ int epic_bhi160_enable_sensor( ...@@ -134,9 +139,14 @@ int epic_bhi160_enable_sensor(
return -ENOMEM; return -ENOMEM;
} }
stream_register(bhi160_lookup_sd(sensor_type), stream); int streamret = stream_register(bhi160_lookup_sd(sensor_type), stream);
if (streamret < 0) {
xSemaphoreGive(bhi160_mutex);
hwlock_release(HWLOCK_I2C);
return streamret;
}
bhy_enable_virtual_sensor( int bhyret = bhy_enable_virtual_sensor(
vs_id, vs_id,
VS_WAKEUP, VS_WAKEUP,
config->sample_rate, config->sample_rate,
...@@ -145,6 +155,11 @@ int epic_bhi160_enable_sensor( ...@@ -145,6 +155,11 @@ int epic_bhi160_enable_sensor(
0, 0,
config->dynamic_range /* dynamic range is sensor dependent */ config->dynamic_range /* dynamic range is sensor dependent */
); );
if (bhyret != BHY_SUCCESS) {
xSemaphoreGive(bhi160_mutex);
hwlock_release(HWLOCK_I2C);
return bhyret;
}
xSemaphoreGive(bhi160_mutex); xSemaphoreGive(bhi160_mutex);
} else { } else {
hwlock_release(HWLOCK_I2C); hwlock_release(HWLOCK_I2C);
...@@ -152,7 +167,7 @@ int epic_bhi160_enable_sensor( ...@@ -152,7 +167,7 @@ int epic_bhi160_enable_sensor(
} }
hwlock_release(HWLOCK_I2C); hwlock_release(HWLOCK_I2C);
return 0; return bhi160_lookup_sd(sensor_type);
} }
int epic_bhi160_disable_sensor(enum bhi160_sensor_type sensor_type) int epic_bhi160_disable_sensor(enum bhi160_sensor_type sensor_type)
...@@ -231,6 +246,24 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data) ...@@ -231,6 +246,24 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
api_interrupt_trigger(EPIC_INT_BHI160_ACCELEROMETER); api_interrupt_trigger(EPIC_INT_BHI160_ACCELEROMETER);
} }
break; break;
case VS_ID_GYROSCOPE:
case VS_ID_GYROSCOPE_WAKEUP:
MXC_ASSERT(data_type == BHY_DATA_TYPE_VECTOR);
if (bhi160_streams[BHI160_GYROSCOPE].queue == NULL) {
break;
}
data_vector.x = sensor_data->data_vector.x;
data_vector.y = sensor_data->data_vector.y;
data_vector.z = sensor_data->data_vector.z;
xQueueSend(
bhi160_streams[BHI160_GYROSCOPE].queue,
&data_vector,
BHI160_MUTEX_WAIT_MS
);
if (sensor_id == VS_ID_GYROSCOPE_WAKEUP) {
api_interrupt_trigger(EPIC_INT_BHI160_GYROSCOPE);
}
break;
default: default:
break; break;
} }
......
...@@ -25,8 +25,9 @@ typedef unsigned int size_t; ...@@ -25,8 +25,9 @@ typedef unsigned int size_t;
* Please keep IDs in sequential order. * Please keep IDs in sequential order.
*/ */
enum stream_descriptor { enum stream_descriptor {
/** BHI160 Accelerometer */ /** BHI160 */
SD_BHI160_ACCELEROMETER, SD_BHI160_ACCELEROMETER,
SD_BHI160_GYROSCOPE,
/** Highest descriptor must always be ``SD_MAX``. */ /** Highest descriptor must always be ``SD_MAX``. */
SD_MAX, SD_MAX,
}; };
......
...@@ -23,17 +23,17 @@ STATIC mp_obj_t mp_bhi160_enable_sensor(size_t n_args, const mp_obj_t *args) ...@@ -23,17 +23,17 @@ STATIC mp_obj_t mp_bhi160_enable_sensor(size_t n_args, const mp_obj_t *args)
cfg.sample_rate = mp_obj_get_int(args[2]); cfg.sample_rate = mp_obj_get_int(args[2]);
cfg.dynamic_range = mp_obj_get_int(args[3]); cfg.dynamic_range = mp_obj_get_int(args[3]);
int sd = epic_bhi160_enable_sensor(sensor_type, &cfg); int stream_id = epic_bhi160_enable_sensor(sensor_type, &cfg);
return MP_OBJ_NEW_SMALL_INT(sd); return MP_OBJ_NEW_SMALL_INT(stream_id);
} }
STATIC mp_obj_t mp_bhi160_read_sensor(mp_obj_t stream_id_in) STATIC mp_obj_t mp_bhi160_read_sensor(mp_obj_t stream_id_in)
{ {
struct bhi160_data_vector buf[100]; struct bhi160_data_vector buf[100];
int sd = mp_obj_get_int(stream_id_in); int stream_id = mp_obj_get_int(stream_id_in);
int n = epic_stream_read(sd, buf, sizeof(buf)); int n = epic_stream_read(stream_id, buf, sizeof(buf));
mp_obj_list_t *list = mp_obj_new_list(0, NULL); mp_obj_list_t *list = mp_obj_new_list(0, NULL);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
......
...@@ -87,6 +87,8 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = { ...@@ -87,6 +87,8 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = {
MP_OBJ_NEW_SMALL_INT(EPIC_INT_RTC_ALARM) }, MP_OBJ_NEW_SMALL_INT(EPIC_INT_RTC_ALARM) },
{ MP_ROM_QSTR(MP_QSTR_BHI160_ACCELEROMETER), { MP_ROM_QSTR(MP_QSTR_BHI160_ACCELEROMETER),
MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ACCELEROMETER) }, MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ACCELEROMETER) },
{ MP_ROM_QSTR(MP_QSTR_BHI160_GYROSCOPE),
MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_GYROSCOPE) },
}; };
static MP_DEFINE_CONST_DICT( static MP_DEFINE_CONST_DICT(
interrupt_module_globals, interrupt_module_globals_table interrupt_module_globals, interrupt_module_globals_table
......
...@@ -2,20 +2,21 @@ import sys_bhi160 ...@@ -2,20 +2,21 @@ import sys_bhi160
import interrupt import interrupt
class BHI160Accelerometer: class BHI160:
def __init__( def enable_sensor(self):
self, sample_rate=4, dynamic_range=2, callback=None, sample_buffer_len=200 interrupt.disable_callback(self.interrupt_id)
): interrupt.set_callback(self.interrupt_id, self._interrupt)
interrupt.disable_callback(interrupt.BHI160_ACCELEROMETER) self.stream_id = sys_bhi160.enable_sensor(
interrupt.set_callback( self.sensor_id, self.sample_buffer_len, self.sample_rate, self.dynamic_range
interrupt.BHI160_ACCELEROMETER, self._accelerometer_interrupt
) )
self.acc_sd = sys_bhi160.enable_sensor(
0, sample_buffer_len, sample_rate, dynamic_range if self.stream_id < 0:
) raise ValueError("Enable sensor returned %i", self.stream_id)
self._callback = callback
if callback: self.active = True
interrupt.enable_callback(interrupt.BHI160_ACCELEROMETER)
if self._callback:
interrupt.enable_callback(self.interrupt_id)
def __enter__(self): def __enter__(self):
return self return self
...@@ -24,33 +25,74 @@ class BHI160Accelerometer: ...@@ -24,33 +25,74 @@ class BHI160Accelerometer:
self.close() self.close()
def close(self): def close(self):
if self.acc_sd is not None: if self.active:
self.acc_sd = None self.active = False
self.acc_sd = sys_bhi160.disable_sensor(0) sys_bhi160.disable_sensor(self.sensor_id)
interrupt.disable_callback(interrupt.BHI160_ACCELEROMETER) interrupt.disable_callback(self.interrupt_id)
interrupt.set_callback(interrupt.BHI160_ACCELEROMETER, None) interrupt.set_callback(self.interrupt_id, None)
def convert(self, value):
return 2 * value / 32768.0
def read(self): def read(self):
result = [] result = []
if self.acc_sd is not None: if self.active:
for sample in sys_bhi160.read_sensor(self.acc_sd): for sample in sys_bhi160.read_sensor(self.stream_id):
result.append( result.append(self.convert(sample))
dict(
{
"x": self.convert(sample.x()),
"y": self.convert(sample.y()),
"z": self.convert(sample.z()),
}
)
)
return result return result
def _accelerometer_interrupt(self, _): def _interrupt(self, _):
if self.acc_sd is not None: if self.active:
data = sys_bhi160.read_sensor(self.acc_sd) data = self.read()
print(data) print(data)
if self._callback: if self._callback:
self._callback(data) self._callback(data)
class BHI160Accelerometer(BHI160):
def __init__(
self, sample_rate=4, dynamic_range=2, callback=None, sample_buffer_len=200
):
self.sample_rate = sample_rate
self.dynamic_range = dynamic_range
self.callback = callback
self.sample_buffer_len = sample_buffer_len
self.sensor_id = 0
self.interrupt_id = interrupt.BHI160_ACCELEROMETER
self._callback = callback
self.enable_sensor()
def convert_single(self, value):
return 2 * value / 32768.0
def convert(self, sample):
return dict(
{
"x": self.convert_single(sample.x()),
"y": self.convert_single(sample.y()),
"z": self.convert_single(sample.z()),
}
)
class BHI160Gyroscope(BHI160):
def __init__(
self, sample_rate=4, dynamic_range=2, callback=None, sample_buffer_len=200
):
self.sample_rate = sample_rate
self.dynamic_range = dynamic_range
self.callback = callback
self.sample_buffer_len = sample_buffer_len
self.sensor_id = 3
self.interrupt_id = interrupt.BHI160_GYROSCOPE
self._callback = callback
self.enable_sensor()
def convert_single(self, value):
return 360 * value / 32768.0
def convert(self, sample):
return dict(
{
"x": self.convert_single(sample.x()),
"y": self.convert_single(sample.y()),
"z": self.convert_single(sample.z()),
}
)
...@@ -58,6 +58,7 @@ Q(set_callback) ...@@ -58,6 +58,7 @@ Q(set_callback)
Q(enable_callback) Q(enable_callback)
Q(disable_callback) Q(disable_callback)
Q(BHI160_ACCELEROMETER) Q(BHI160_ACCELEROMETER)
Q(BHI160_GYROSCOPE)
Q(RTC_ALARM) Q(RTC_ALARM)
/* bhi160 */ /* bhi160 */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment