vsync: use SingleAxisDataEvent for sample event
This allows us to timestamp the event in the ISR rather than waiting for
it to be timestamped in hostIntf.
Bug: 30020326
Change-Id: I36dcbb09c05f52b3813f006981757e14d7cc89a3
diff --git a/firmware/src/drivers/vsync/vsync.c b/firmware/src/drivers/vsync/vsync.c
index e423494..c6d55aa 100644
--- a/firmware/src/drivers/vsync/vsync.c
+++ b/firmware/src/drivers/vsync/vsync.c
@@ -26,6 +26,7 @@
#include <nanohubPacket.h>
#include <sensors.h>
#include <seos.h>
+#include <slab.h>
#include <timer.h>
#include <plat/inc/gpio.h>
#include <plat/inc/exti.h>
@@ -33,7 +34,11 @@
#include <variant/inc/variant.h>
#define VSYNC_APP_ID APP_ID_MAKE(APP_ID_VENDOR_GOOGLE, 7)
-#define VSYNC_APP_VERSION 1
+#define VSYNC_APP_VERSION 2
+
+// This defines how many vsync events we could handle being backed up in the
+// queue. Use this to size our slab
+#define MAX_VSYNC_EVENTS 4
#ifndef VSYNC_PIN
#error "VSYNC_PIN is not defined; please define in variant.h"
@@ -47,6 +52,8 @@
osLog(LOG_INFO, "%s " fmt, "[VSYNC]", ##__VA_ARGS__); \
} while (0);
+#define ERROR_PRINT(fmt, ...) INFO_PRINT("%s" fmt, "ERROR: ", ##__VA_ARGS__); \
+
#define DEBUG_PRINT(fmt, ...) do { \
if (enable_debug) { \
INFO_PRINT(fmt, ##__VA_ARGS__); \
@@ -59,6 +66,8 @@
{
struct Gpio *pin;
struct ChainedIsr isr;
+ struct SlabAllocator *evtSlab;
+
uint32_t id;
uint32_t sensorHandle;
@@ -66,18 +75,46 @@
bool on;
} mTask;
+static bool vsyncAllocateEvt(struct SingleAxisDataEvent **evPtr, uint64_t time)
+{
+ struct SingleAxisDataEvent *ev;
+
+ *evPtr = slabAllocatorAlloc(mTask.evtSlab);
+
+ ev = *evPtr;
+ if (!ev) {
+ ERROR_PRINT("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].idata = 1;
+
+ return true;
+}
+
+static void vsyncFreeEvt(void *ptr)
+{
+ slabAllocatorFree(mTask.evtSlab, ptr);
+}
+
static bool vsyncIsr(struct ChainedIsr *localIsr)
{
struct SensorTask *data = container_of(localIsr, struct SensorTask, isr);
- union EmbeddedDataPoint sample;
+ struct SingleAxisDataEvent *ev;
if (!extiIsPendingGpio(data->pin)) {
return false;
}
if (data->on) {
- sample.idata = 1;
- osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_VSYNC), sample.vptr, NULL);
+ if (vsyncAllocateEvt(&ev, sensorGetTime())) {
+ if (!osEnqueueEvtOrFree(EVENT_TYPE_BIT_DISCARDABLE | sensorGetMyEventType(SENS_TYPE_VSYNC), ev, vsyncFreeEvt)) {
+ ERROR_PRINT("osEnqueueEvtOrFree() failed\n");
+ }
+ }
}
extiClearPendingGpio(data->pin);
@@ -104,7 +141,7 @@
{
.sensorName = "Camera Vsync",
.sensorType = SENS_TYPE_VSYNC,
- .numAxis = NUM_AXIS_EMBEDDED,
+ .numAxis = NUM_AXIS_ONE,
.interrupt = NANOHUB_INT_NONWAKEUP,
.minSamples = 20,
};
@@ -162,6 +199,12 @@
mTask.pin = gpioRequest(VSYNC_PIN);
mTask.isr.func = vsyncIsr;
+ mTask.evtSlab = slabAllocatorNew(sizeof(struct SingleAxisDataEvent) + sizeof(struct SingleAxisDataPoint), 4, MAX_VSYNC_EVENTS);
+ if (!mTask.evtSlab) {
+ ERROR_PRINT("slabAllocatorNew() failed\n");
+ return false;
+ }
+
return true;
}