bosch_bmp280: timestamp baro samples when sampling

Bug: 30640353
Change-Id: I2676eb23f0a6aa2d50228b49e654131eb4f0ec50
diff --git a/firmware/os/drivers/bosch_bmp280/bosch_bmp280.c b/firmware/os/drivers/bosch_bmp280/bosch_bmp280.c
index d6c040c..fbdc97c 100644
--- a/firmware/os/drivers/bosch_bmp280/bosch_bmp280.c
+++ b/firmware/os/drivers/bosch_bmp280/bosch_bmp280.c
@@ -25,12 +25,13 @@
 #include <nanohubPacket.h>
 #include <sensors.h>
 #include <seos.h>
+#include <slab.h>
 #include <timer.h>
 #include <util.h>
 
 #define BMP280_APP_ID APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 5)
 
-#define BMP280_APP_VERSION 2
+#define BMP280_APP_VERSION 3
 
 #define I2C_BUS_ID                      0
 #define I2C_SPEED                       400000
@@ -48,6 +49,10 @@
 #define BOSCH_BMP280_MAX_PENDING_I2C_REQUESTS   4
 #define BOSCH_BMP280_MAX_I2C_TRANSFER_SIZE      24
 
+// This defines how many baro events we could handle being backed up in the
+// queue. Use this to size our slab
+#define MAX_BARO_EVENTS  4
+
 // temp: 2x oversampling, baro: 16x oversampling, power: normal
 #define CTRL_ON    ((2 << 5) | (5 << 2) | 3)
 // temp: 2x oversampling, baro: 16x oversampling, power: sleep
@@ -94,6 +99,8 @@
 {
     struct BMP280CompParams comp;
 
+    struct SlabAllocator *evtSlab;
+
     uint32_t id;
     uint32_t baroHandle;
     uint32_t tempHandle;
@@ -189,6 +196,31 @@
     return (ret == 0);
 }
 
+static bool baroAllocateEvt(struct SingleAxisDataEvent **evPtr, float sample, uint64_t time)
+{
+    struct SingleAxisDataEvent *ev;
+
+    *evPtr = slabAllocatorAlloc(mTask.evtSlab);
+
+    ev = *evPtr;
+    if (!ev) {
+        osLog(LOG_ERROR, "[BMP280] slabAllocatorAlloc() failed\n");
+        return false;
+    }
+
+    memset(&ev->samples[0].firstSample, 0x00, sizeof(struct SensorFirstSample));
+    ev->referenceTime = time;
+    ev->samples[0].firstSample.numSamples = 1;
+    ev->samples[0].fdata = sample;
+
+    return true;
+}
+
+static void baroFreeEvt(void *ptr)
+{
+    slabAllocatorFree(mTask.evtSlab, ptr);
+}
+
 /* sensor callbacks from nanohub */
 
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
@@ -344,7 +376,7 @@
     .sensorName = "Pressure",
     .supportedRates = baroSupportedRates,
     .sensorType = SENS_TYPE_BARO,
-    .numAxis = NUM_AXIS_EMBEDDED,
+    .numAxis = NUM_AXIS_ONE,
     .interrupt = NANOHUB_INT_NONWAKEUP,
     .minSamples = 300
 };
@@ -425,7 +457,9 @@
 
 static void handleI2cEvent(struct I2cTransfer *xfer)
 {
-    union EmbeddedDataPoint sample;
+    union EmbeddedDataPoint embeddedSample;
+    struct SingleAxisDataEvent *baroSample;
+
     struct I2cTransfer *newXfer;
 
     switch (xfer->state) {
@@ -507,14 +541,17 @@
 
                     writeRegister(BOSCH_BMP280_REG_CTRL_MEAS, CTRL_SLEEP, STATE_IDLE);
                 } else {
-                    sample.fdata = pressure_Pa * 0.01f;
-                    osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_BARO), sample.vptr, NULL);
+                    if (baroAllocateEvt(&baroSample, pressure_Pa * 0.01f, sensorGetTime())) {
+                        if (!osEnqueueEvtOrFree(EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(SENS_TYPE_BARO), baroSample, baroFreeEvt)) {
+                            osLog(LOG_ERROR, "[BMP280] failed to enqueue baro sample\n");
+                        }
+                    }
                 }
             }
 
             if (mTask.tempOn && mTask.tempReading) {
-                sample.fdata = temp_centigrade;
-                osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_TEMP), sample.vptr, NULL);
+                embeddedSample.fdata = temp_centigrade;
+                osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_TEMP), embeddedSample.vptr, NULL);
             }
 
             mTask.baroReading = false;
@@ -592,6 +629,12 @@
     mTask.baroHandle = sensorRegister(&sensorInfoBaro, &sensorOpsBaro, NULL, false);
     mTask.tempHandle = sensorRegister(&sensorInfoTemp, &sensorOpsTemp, NULL, false);
 
+    mTask.evtSlab = slabAllocatorNew(sizeof(struct SingleAxisDataEvent) + sizeof(struct SingleAxisDataPoint), 4, MAX_BARO_EVENTS);
+    if (!mTask.evtSlab) {
+        osLog(LOG_ERROR, "[BMP280] slabAllocatorNew() failed\n");
+        return false;
+    }
+
     osEventSubscribe(taskId, EVT_APP_START);
 
     return true;
@@ -599,7 +642,7 @@
 
 static void endTask(void)
 {
-
+    slabAllocatorDestroy(mTask.evtSlab);
 }
 
 INTERNAL_APP_INIT(BMP280_APP_ID, BMP280_APP_VERSION, startTask, endTask, handleEvent);