From 96d3843fdec20157ddb16abbc849a406d4f11076 Mon Sep 17 00:00:00 2001
From: koalo <koalo@koalo.de>
Date: Thu, 22 Aug 2019 02:23:49 +0200
Subject: [PATCH] feat(bhi160): Provide orientation data

---
 epicardium/epicardium.h        |  8 +++++---
 epicardium/modules/bhi.c       | 11 +++++++++++
 epicardium/modules/stream.h    |  1 +
 pycardium/modules/interrupt.c  |  2 ++
 pycardium/modules/py/bhi160.py | 26 ++++++++++++++++++++++++++
 pycardium/modules/qstrdefs.h   |  1 +
 6 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 0687f9d2..d2565cd7 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -157,11 +157,13 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
 /** BHI */
 #define EPIC_INT_BHI160_ACCELEROMETER   4
 API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer);
-#define EPIC_INT_BHI160_GYROSCOPE       5
+#define EPIC_INT_BHI160_ORIENTATION     5
+API_ISR(EPIC_INT_BHI160_ORIENTATION, epic_isr_bhi160_orientation);
+#define EPIC_INT_BHI160_GYROSCOPE       6
 API_ISR(EPIC_INT_BHI160_GYROSCOPE, epic_isr_bhi160_gyroscope);
 
 /* Number of defined interrupts. */
-#define EPIC_INT_NUM                    6
+#define EPIC_INT_NUM                    7
 /* clang-format on */
 
 /*
@@ -923,7 +925,7 @@ enum bhi160_sensor_type {
 	BHI160_ACCELEROMETER               = 0,
 	/** Magnetometer (**Unimplemented**) */
 	BHI160_MAGNETOMETER                = 1,
-	/** Orientation (**Unimplemented**) */
+	/** Orientation */
 	BHI160_ORIENTATION                 = 2,
 	/** Gyroscope */
 	BHI160_GYROSCOPE                   = 3,
diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c
index 461039e3..bacb88ae 100644
--- a/epicardium/modules/bhi.c
+++ b/epicardium/modules/bhi.c
@@ -88,6 +88,8 @@ static bhy_virtual_sensor_t bhi160_lookup_vs_id(enum bhi160_sensor_type type)
 	switch (type) {
 	case BHI160_ACCELEROMETER:
 		return VS_ID_ACCELEROMETER;
+	case BHI160_ORIENTATION:
+		return VS_ID_ORIENTATION;
 	case BHI160_GYROSCOPE:
 		return VS_ID_GYROSCOPE;
 	default:
@@ -103,6 +105,8 @@ static int bhi160_lookup_sd(enum bhi160_sensor_type type)
 	switch (type) {
 	case BHI160_ACCELEROMETER:
 		return SD_BHI160_ACCELEROMETER;
+	case BHI160_ORIENTATION:
+		return SD_BHI160_ORIENTATION;
 	case BHI160_GYROSCOPE:
 		return SD_BHI160_GYROSCOPE;
 	default:
@@ -237,10 +241,12 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
 			    sensor_data->data_scalar_u16.data;
 		break;
 	case VS_ID_ACCELEROMETER_WAKEUP:
+	case VS_ID_ORIENTATION_WAKEUP:
 	case VS_ID_GYROSCOPE_WAKEUP:
 		wakeup = true;
 		/* fall through */
 	case VS_ID_ACCELEROMETER:
+	case VS_ID_ORIENTATION:
 	case VS_ID_GYROSCOPE:
 		switch (sensor_id) {
 		case VS_ID_ACCELEROMETER_WAKEUP:
@@ -248,6 +254,11 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
 			sensor_type = BHI160_ACCELEROMETER;
 			epic_int    = EPIC_INT_BHI160_ACCELEROMETER;
 			break;
+		case VS_ID_ORIENTATION_WAKEUP:
+		case VS_ID_ORIENTATION:
+			sensor_type = BHI160_ORIENTATION;
+			epic_int    = EPIC_INT_BHI160_ORIENTATION;
+			break;
 		case VS_ID_GYROSCOPE_WAKEUP:
 		case VS_ID_GYROSCOPE:
 			sensor_type = BHI160_GYROSCOPE;
diff --git a/epicardium/modules/stream.h b/epicardium/modules/stream.h
index 668f7862..41064bd5 100644
--- a/epicardium/modules/stream.h
+++ b/epicardium/modules/stream.h
@@ -27,6 +27,7 @@ typedef unsigned int size_t;
 enum stream_descriptor {
 	/** BHI160 */
 	SD_BHI160_ACCELEROMETER,
+	SD_BHI160_ORIENTATION,
 	SD_BHI160_GYROSCOPE,
 	/** Highest descriptor must always be ``SD_MAX``. */
 	SD_MAX,
diff --git a/pycardium/modules/interrupt.c b/pycardium/modules/interrupt.c
index 087facf7..927b936b 100644
--- a/pycardium/modules/interrupt.c
+++ b/pycardium/modules/interrupt.c
@@ -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_ROM_QSTR(MP_QSTR_BHI160_ACCELEROMETER),
 	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ACCELEROMETER) },
+	{ MP_ROM_QSTR(MP_QSTR_BHI160_ORIENTATION),
+	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ORIENTATION) },
 	{ MP_ROM_QSTR(MP_QSTR_BHI160_GYROSCOPE),
 	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_GYROSCOPE) },
 };
diff --git a/pycardium/modules/py/bhi160.py b/pycardium/modules/py/bhi160.py
index 7d318581..afd0fdba 100644
--- a/pycardium/modules/py/bhi160.py
+++ b/pycardium/modules/py/bhi160.py
@@ -96,3 +96,29 @@ class BHI160Gyroscope(BHI160):
                 "z": self.convert_single(sample[2]),
             }
         )
+
+
+class BHI160Orientation(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 = 2
+        self.interrupt_id = interrupt.BHI160_ORIENTATION
+        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[0]),
+                "y": self.convert_single(sample[1]),
+                "z": self.convert_single(sample[2]),
+            }
+        )
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 77978542..d6e4efa1 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -58,6 +58,7 @@ Q(set_callback)
 Q(enable_callback)
 Q(disable_callback)
 Q(BHI160_ACCELEROMETER)
+Q(BHI160_ORIENTATION)
 Q(BHI160_GYROSCOPE)
 Q(RTC_ALARM)
 
-- 
GitLab