Racelogic / Mbed 2 deprecated VIPS_LTC_RAW_IMU

Dependencies:   BufferedSerial FatFileSystemCpp mbed

Revision:
1:dd1f7e162f91
Parent:
0:97661408d0f9
Child:
2:a79201e302d7
--- a/main.cpp	Fri Jan 15 11:49:01 2021 +0000
+++ b/main.cpp	Fri Jan 15 15:44:39 2021 +0000
@@ -56,150 +56,193 @@
 float remainingClockError;
 bool ppmCorrection;
 
+struct outputFormat_s {
+    uint32_t header; // 2 byte header + 2 byte length
+    uint32_t mask;
+    uint32_t time;
+    double x;
+    double y;
+    float z;
+    float roll;
+    float pitch;
+    float yaw;
+    uint16_t checksum;
+} __attribute__((packed)) ;
 
-void sendPosition(position *posPtr) {
+struct outputFormat_s packetOut;
+
+void prepPacketOut()
+{
+    uint8_t bytes[4];
+    bytes[0]=0x24;
+    bytes[1]=0x9d;
+    *(uint16_t*)(bytes+2) = sizeof(struct outputFormat_s);
+    packetOut.header = *(uint32_t*)bytes;
+    packetOut.mask = 0x04;
+}
+
+void sendPosition(position *posPtr)
+{
     if (posPtr) {
-      COM1.write(posPtr, sizeof(position));
-      COM3.write(posPtr, sizeof(position));
-      printf("send\r\n");
+        packetOut.time = posPtr->time;
+        packetOut.x = posPtr->X;
+        packetOut.y = posPtr->Y;
+        packetOut.z = posPtr->Height;
+        packetOut.roll = posPtr->roll;
+        packetOut.pitch = posPtr->pitch;
+        packetOut.yaw = posPtr->yaw;
+        VIPSSerial::getCRC((void *)&packetOut, sizeof(struct outputFormat_s)-2, (void *)&packetOut.checksum);
+        COM1.write(&packetOut, sizeof(struct outputFormat_s));
+        COM3.write(&packetOut, sizeof(struct outputFormat_s));
+//      printf("send\r\n");
     }
 }
 
 
-void OnPPSEdge() {
-  if (PPSHigh) {
-    PPS = 0;
-    PPSHigh = false;
-  } else {
-    PPS = 1;
-    PPSHigh = true;
+void OnPPSEdge()
+{
+    if (PPSHigh) {
+        PPS = 0;
+        led3=1;
+        PPSHigh = false;
+    } else {
+        led3=0;
+        PPS = 1;
+        PPSHigh = true;
 
-    if (resync && !ppmCorrection) {
-      PPSOutputTimer.detach();
-      PPSOutputTimer.attach(callback(OnPPSEdge), resyncPeriod);
-      resync = false;
-      resyncDone = true;
-    } else if (resyncDone) {
-      resyncDone = false;
-      PPSOutputTimer.detach();
-      PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000);
-      remainingClockError = 0;
-    }
-
-    if ((VBOXTicks % 100) == 0) {
-      lastPPSSecondStart = inputTimer.read_us();
-      second = 1;
-      remainingClockError+=PPMHighAcc;
-      int adjustment = (int)(remainingClockError/2);
-      if (!resyncDone && ((adjustment > 2)|| (adjustment <-2))) {
+        if (resync && !ppmCorrection) {
             PPSOutputTimer.detach();
-            PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000+adjustment-timerOverheadTime);
-            ppmCorrection=true;
-            remainingClockError-=2*adjustment;
-        }
-    } else {
-      if ((VBOXTicks % 100) == 1) {
-        second = 0;
-        if (ppmCorrection) {
+            PPSOutputTimer.attach_us(callback(OnPPSEdge), resyncPeriod);
+            resync = false;
+            resyncDone = true;
+        } else if (resyncDone) {
+            resyncDone = false;
             PPSOutputTimer.detach();
             PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000);
-            ppmCorrection=false;
+            remainingClockError = 0;
         }
-      } 
-    }
 
-    VBOXTicks++;
-    if (VBOXTicks >= (24 * 60 * 60 * 100))
-      VBOXTicks -= (24 * 60 * 60 * 100);
-  }
+        if ((VBOXTicks % 100) == 0) {
+            lastPPSSecondStart = inputTimer.read_us();
+            second = 1;
+            remainingClockError+=PPMHighAcc;
+            int adjustment = (int)(remainingClockError/2);
+            if (!resyncDone && ((adjustment > 2)|| (adjustment <-2))) {
+                PPSOutputTimer.detach();
+                PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000+adjustment-timerOverheadTime);
+                ppmCorrection=true;
+                remainingClockError-=2*adjustment;
+            }
+        } else {
+            if ((VBOXTicks % 100) == 1) {
+                second = 0;
+                if (ppmCorrection) {
+                    PPSOutputTimer.detach();
+                    PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000);
+                    ppmCorrection=false;
+                }
+            }
+        }
+
+        VBOXTicks++;
+        if (VBOXTicks >= (24 * 60 * 60 * 100))
+            VBOXTicks -= (24 * 60 * 60 * 100);
+    }
 }
 
-void OnPPSCync() {
-  PPS = 1;
-  PPSOutputTimer.detach();
-  PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000);
-  PPSHigh = true;
-  VBOXTicks++;
-  ppsActive = true;
-  led1 = 1;
+void OnPPSCync()
+{
+    PPS = 1;
+    led3=0;
+    PPSOutputTimer.detach();
+    PPSOutputTimer.attach_us(callback(OnPPSEdge), 5000);
+    PPSHigh = true;
+    VBOXTicks++;
+    ppsActive = true;
+    led1 = 1;
 }
 
-const char *ticksToTime(unsigned long vboxTickCount) {
-  static char timeString[32];
-  int hours = vboxTickCount / 360000;
-  int minutes = (vboxTickCount / 6000) % 60;
-  int seconds = (vboxTickCount / 100) % 60;
-  int ms = 10 * (vboxTickCount % 100);
-  sprintf(timeString, "%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
-  return timeString;
+const char *ticksToTime(unsigned long vboxTickCount)
+{
+    static char timeString[32];
+    int hours = vboxTickCount / 360000;
+    int minutes = (vboxTickCount / 6000) % 60;
+    int seconds = (vboxTickCount / 100) % 60;
+    int ms = 10 * (vboxTickCount % 100);
+    sprintf(timeString, "%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
+    return timeString;
 }
 
-bool isStartOfSecond(int minutes, int seconds, int frame, bool dropFrame) {
-  if (frame == 0)
-    return true;
-  if (dropFrame && (2 == frame) && (0 == seconds) && (minutes % 10 != 0))
-    return true;
-  return false;
+bool isStartOfSecond(int minutes, int seconds, int frame, bool dropFrame)
+{
+    if (frame == 0)
+        return true;
+    if (dropFrame && (2 == frame) && (0 == seconds) && (minutes % 10 != 0))
+        return true;
+    return false;
 }
 
 
-int getClosestRateIndex(long int framePeriodUS) {
-  int indexOver = 1;
-  while (framePeriodUS <= frameRateInfo::FramePeriods[indexOver])
-    indexOver++;
-  float amountOver = framePeriodUS - frameRateInfo::FramePeriods[indexOver];
-  float amountUnder = frameRateInfo::FramePeriods[indexOver - 1] - framePeriodUS;
-  if (amountOver > amountUnder)
-    return indexOver - 1;
-  return indexOver;
+int getClosestRateIndex(long int framePeriodUS)
+{
+    int indexOver = 1;
+    while (framePeriodUS <= frameRateInfo::FramePeriods[indexOver])
+        indexOver++;
+    float amountOver = framePeriodUS - frameRateInfo::FramePeriods[indexOver];
+    float amountUnder = frameRateInfo::FramePeriods[indexOver - 1] - framePeriodUS;
+    if (amountOver > amountUnder)
+        return indexOver - 1;
+    return indexOver;
 }
 
 // frame rate and clock error calculation
-void frameRateMeasure(uint32_t frameStartTime, bool dropFrame=false) {
-  frameToggle =!frameToggle;
-  static int frameRateCount = 0;
-  static uint32_t rateCalcStartTime;
-  if (frameRateCount == 0) {
-    rateCalcStartTime = frameStartTime;
-    frameRateCount = 1;
-  } else {
-    if (frameRateCount == framesToCount) {
-      uint32_t timeTaken = frameStartTime - rateCalcStartTime;
-      long int timePerFrame = timeTaken / framesToCount;
-      detectedRate.setRate(getClosestRateIndex(timePerFrame));
-      float TrueSeconds = framesToCount / detectedRate.currentRate();
-      // +ve PPM means I counted more than real time = my clock is fast.
-      float ppmError = (timeTaken - (1000000 * TrueSeconds)) / TrueSeconds;
-      if ((ppmError<250) && (ppmError>-250)) { // something went very wrong with ppm calculation.
-          if (PPMHighAcc!=0) {
-            PPMTrackTotal -= PPMErrors[PPMTrackIndex];
-            PPMTrackTotal += ppmError;
-            PPMErrors[PPMTrackIndex++] = ppmError;
-            PPMHighAcc = PPMTrackTotal / _longPPMTrackLen_;
-        } else { // first time
-              for (int i=0;i<_longPPMTrackLen_;i++)
-                PPMErrors[i] = ppmError;
-            PPMTrackTotal = ppmError*_longPPMTrackLen_;
-            PPMHighAcc = ppmError;
+void frameRateMeasure(uint32_t frameStartTime, bool dropFrame=false)
+{
+    frameToggle =!frameToggle;
+    static int frameRateCount = 0;
+    static uint32_t rateCalcStartTime;
+    if (frameRateCount == 0) {
+        rateCalcStartTime = frameStartTime;
+        frameRateCount = 1;
+    } else {
+        if (frameRateCount == framesToCount) {
+            uint32_t timeTaken = frameStartTime - rateCalcStartTime;
+            long int timePerFrame = timeTaken / framesToCount;
+            detectedRate.setRate(getClosestRateIndex(timePerFrame));
+            float TrueSeconds = framesToCount / detectedRate.currentRate();
+            // +ve PPM means I counted more than real time = my clock is fast.
+            float ppmError = (timeTaken - (1000000 * TrueSeconds)) / TrueSeconds;
+            if ((ppmError<250) && (ppmError>-250)) { // something went very wrong with ppm calculation.
+                if (PPMHighAcc!=0) {
+                    PPMTrackTotal -= PPMErrors[PPMTrackIndex];
+                    PPMTrackTotal += ppmError;
+                    PPMErrors[PPMTrackIndex++] = ppmError;
+                    PPMHighAcc = PPMTrackTotal / _longPPMTrackLen_;
+                } else { // first time
+                    for (int i=0; i<_longPPMTrackLen_; i++)
+                        PPMErrors[i] = ppmError;
+                    PPMTrackTotal = ppmError*_longPPMTrackLen_;
+                    PPMHighAcc = ppmError;
+                }
+                if (PPMTrackIndex == _longPPMTrackLen_)
+                    PPMTrackIndex = 0;
+                printf("Frame rate detected as %s. My clock is %.4f ppm fast\r\n", detectedRate.frameRateString(), PPMHighAcc);
+            } else {
+                printf("Frame rate unclear\r\n");
+                PPMHighAcc=0;
+                detectedRate.setRate(0);
+            }
+            frameRateCount = 0;
+        } else {
+            frameRateCount++;
         }
-          if (PPMTrackIndex == _longPPMTrackLen_)
-            PPMTrackIndex = 0;
-        printf("Frame rate detected as %s. My clock is %.4f ppm fast\r\n", detectedRate.frameRateString(), PPMHighAcc);
-      } else {
-          printf("Frame rate unclear\r\n");
-          PPMHighAcc=0;
-          detectedRate.setRate(0);
-      }
-      frameRateCount = 0;
-    } else {
-      frameRateCount++;
     }
-  }
 }
 
 
 //called once per frame to output the current postition
-void framePositionOutput() {
+void framePositionOutput()
+{
     sendPosition(VIPS.sendPositionForTime(TimeSinceLastFrame.read_us()));
     TimeSinceLastFrame.reset();
 }
@@ -208,208 +251,214 @@
 // frameStartTime = time of inputTimer at the start of the first bit of the
 // frame. dropFrame = true if the protocol includes frameDrops
 void frameComplete(int hours, int minutes, int seconds, int frame,
-                   bool dropFrame, uint32_t frameStartTime) {
-  static int lastFrame = 0;
-  static float ppmError;
-  static int outCount = 0;
-  if ((frame != (lastFrame + 1)) && detectedRate.currentRate()) {
-    long timeSinceSecondStart = detectedRate.getOffsetFromSecondStart(minutes, seconds, frame);
+                   bool dropFrame, uint32_t frameStartTime)
+{
+    static int lastFrame = 0;
+    static float ppmError;
+    static int outCount = 0;
+    if ((frame != (lastFrame + 1)) && detectedRate.currentRate()) {
+        long timeSinceSecondStart = detectedRate.getOffsetFromSecondStart(minutes, seconds, frame);
 //    printf("Time Code %02d:%02d:%02d:%02d - VBOX time %s\r", hours, minutes, seconds, frame, ticksToTime(VBOXTicks));
-    uint32_t ThisSecondStart = frameStartTime - timeSinceSecondStart;
-    if (!ppsRunning) {
-      uint32_t nextSecondStart = ThisSecondStart + 1000000 + (int)(ppmError + 0.5);
-      ppsRunning = true;
-      __disable_irq();
-      uint32_t nextSec =  nextSecondStart - inputTimer.read_us();
-      PPSsyncTimer.attach(callback(OnPPSCync), nextSec);
-      __enable_irq();
-      printf("PPS start scheduled for %0.3f seconds.\r\n", nextSec / 1000000.0f);
-      VBOXTicks = (hours * 3600 + minutes * 60 + (seconds + 1)) * 100;
-    } else if (detectedRate.isSyncable()) { // PPS running and from a syncable source
-      long timeError = (lastPPSSecondStart - ThisSecondStart);
-      if (timeError < -500000)
-        timeError += 1000000;
-      timeError = timeError % 1000000;
+        uint32_t ThisSecondStart = frameStartTime - timeSinceSecondStart;
+        if (!ppsRunning) {
+            uint32_t nextSecondStart = ThisSecondStart + 1000000 + (int)(ppmError + 0.5);
+            ppsRunning = true;
+            __disable_irq();
+            uint32_t nextSec =  nextSecondStart - inputTimer.read_us();
+            PPSsyncTimer.attach_us(callback(OnPPSCync), nextSec);
+            __enable_irq();
+            printf("PPS start scheduled for %0.3f seconds.\r\n", nextSec / 1000000.0f);
+            VBOXTicks = (hours * 3600 + minutes * 60 + (seconds + 1)) * 100;
+        } else if (detectedRate.isSyncable()) { // PPS running and from a syncable source
+            long timeError = (lastPPSSecondStart - ThisSecondStart);
+            if (timeError < -500000)
+                timeError += 1000000;
+            timeError = timeError % 1000000;
 //      printf("PPS error measured as %ld us.\r", timeError);
 
-      if ((timeError > MaxTimeErrorUS) || (timeError < -MaxTimeErrorUS)) {
-        outCount++;
-        if (outCount > 3) {
-          int newPeriod = 5000 - timeError / 2;
-          if (newPeriod < 4500)
-            newPeriod = 4500;
-          if (newPeriod > 5500)
-            newPeriod = 5500;
+            if ((timeError > MaxTimeErrorUS) || (timeError < -MaxTimeErrorUS)) {
+                outCount++;
+                if (outCount > 3) {
+                    int newPeriod = 5000 - timeError / 2;
+                    if (newPeriod < 4500)
+                        newPeriod = 4500;
+                    if (newPeriod > 5500)
+                        newPeriod = 5500;
 
-    //      printf("Resync attempt. Error was %ld. 1 cycle at %d us\r\n", timeError, newPeriod);
-          __disable_irq();
-          resyncPeriod = newPeriod - timerOverheadTime;
-          resync = true;
-          __enable_irq();
-        }
-      } else
-        outCount = 0;
-    } // either no PPS and can't start it yet or running from unsyncable source
-      // so just free run.
-  }
-  lastFrame = frame;
+                    //      printf("Resync attempt. Error was %ld. 1 cycle at %d us\r\n", timeError, newPeriod);
+                    __disable_irq();
+                    resyncPeriod = newPeriod - timerOverheadTime;
+                    resync = true;
+                    __enable_irq();
+                }
+            } else
+                outCount = 0;
+        } // either no PPS and can't start it yet or running from unsyncable source
+        // so just free run.
+    }
+    lastFrame = frame;
 
     // frame rate and clock error calculation
-  frameRateMeasure(frameStartTime, dropFrame);
-  framePositionOutput();  
+    frameRateMeasure(frameStartTime, dropFrame);
+    framePositionOutput();
 }
 
 // called by background loop at the end of each frame when running from a sync signal not timecode
-void framePulse(uint32_t frameStartTime) {
-  static int outCount = 0;
-  uint32_t patternStartTime;
-  if (detectedRate.isValid()) {
-    uint32_t ThisSecondStart = frameStartTime ;
-    if (!ppsRunning) {
-      uint32_t pulseStartTime = frameStartTime + (int)(detectedRate.currentPeriodUS()*5+0.5f);
-      uint32_t timeTillStart =  pulseStartTime - inputTimer.read_us();
-      ppsRunning = true;
-      __disable_irq();
-      PPSsyncTimer.attach_us(callback(OnPPSCync), timeTillStart);
-      __enable_irq();
-      printf("PPS start scheduled for %0.3f seconds.\r\n",
-             timeTillStart / 1000000.0f);
-      VBOXTicks = 0;
-      outCount = 0;
-    } else {
+void framePulse(uint32_t frameStartTime)
+{
+    static int outCount = 0;
+    uint32_t patternStartTime;
+    if (detectedRate.isValid()) {
+        uint32_t ThisSecondStart = frameStartTime ;
+        if (!ppsRunning) {
+            uint32_t pulseStartTime = frameStartTime + (int)(detectedRate.currentPeriodUS()*5+0.5f);
+            uint32_t timeTillStart =  pulseStartTime - inputTimer.read_us();
+            ppsRunning = true;
+            __disable_irq();
+            PPSsyncTimer.attach_us(callback(OnPPSCync), timeTillStart);
+            __enable_irq();
+            printf("PPS start scheduled for %0.3f seconds.\r\n",
+                   timeTillStart / 1000000.0f);
+            VBOXTicks = 0;
+            outCount = 0;
+        } else {
 //        if (outCount == 0)
 //            patternStartTime = inputTimer.elapsed_time();
 //        else {
 //            expectedTotalUS = outCount
 //        }
+        }
     }
-  }
-  // frame rate and clock error calculation
-  frameRateMeasure(frameStartTime, false);
-  framePositionOutput();  
-  }
+    // frame rate and clock error calculation
+    frameRateMeasure(frameStartTime, false);
+    framePositionOutput();
+}
 
 volatile bool NewFramePulse= false;
 uint32_t FramePulseTime;
 volatile int framesIn = 0;
-void OnPPFInputStartup(void) {
+void OnPPFInputStartup(void)
+{
     framesIn++;
 }
 
 volatile int SyncInCount = 0;
-void OnSyncInputStartup(void) {
+void OnSyncInputStartup(void)
+{
     SyncInCount++;
 }
 
 
-void OnPPFInput(void) {
+void OnPPFInput(void)
+{
     FramePulseTime = inputTimer.read_us();
     NewFramePulse = true;
 }
 
 
-int main() {
-  pc.baud(115200);
-//  COM1.baud(115200);
-//  COM3.baud(115200);
-  inputTimer.reset();
-  inputTimer.start();
+int main()
+{
+    pc.baud(115200);
+    COM1.baud(115200);
+    COM3.baud(115200);
+    inputTimer.reset();
+    inputTimer.start();
 
-  pc.printf("Startup\r\n");
-  led1 = 0;
-//  LTCInput.setInputTimer(&inputTimer);
-//  PPFin.rise(callback(&OnPPFInputStartup));
+    pc.printf("Startup\r\n");
+    led1 = 1;
 
-  while (true) {
-      pc.putc('.');
-      led1=!led1;
-      wait_us(1000*100);
-      }
+    prepPacketOut();
+    LTCInput.setInputTimer(&inputTimer);
+    PPFin.rise(callback(&OnPPFInputStartup));
+    VIPS.run();
+
+    pc.printf("armed\r\n");
+    led2 = 1;
 
-  for (int i = 0; i < _longPPMTrackLen_; i++)
-    PPMErrors[i] = 0;
-  pc.printf("Startup\r\n");
-  PPMTrackIndex = 0;
-  PPMTrackTotal = 0;
-  remainingClockError = 0;
-  bool GenLockOnlyMode = false;
-  bool GenLockToSync = false;
+    for (int i = 0; i < _longPPMTrackLen_; i++)
+        PPMErrors[i] = 0;
+    pc.printf("Startup\r\n");
+    PPMTrackIndex = 0;
+    PPMTrackTotal = 0;
+    remainingClockError = 0;
+    bool GenLockOnlyMode = false;
+    bool GenLockToSync = false;
 
-  TimeSinceLastFrame.reset();
-  TimeSinceLastFrame.start();
-  while (true) {
-    pc.printf("Waiting for sync\r\n");
-    PPFin.rise(callback(&OnPPFInputStartup));
-    Syncin.rise(callback(&OnSyncInputStartup));
-    framesIn = 0;
-    SyncInCount = 0;
-    GenLockOnlyMode = false;
-    GenLockToSync = false;
-    while (!LTCInput.searchForSync()) {
-      if (framesIn == 100) {
-        GenLockOnlyMode = true;
-        break;
-      }
-      if ((SyncInCount == 100) && (framesIn<45)) { // prefer frame input pin, sync may be twice as high for interlaced systems.
-        GenLockOnlyMode = true;
-        GenLockToSync= true;
-        break;
-      }
+    TimeSinceLastFrame.reset();
+    TimeSinceLastFrame.start();
+    while (true) {
+        pc.printf("Waiting for sync\r\n");
+        PPFin.rise(callback(&OnPPFInputStartup));
+        Syncin.rise(callback(&OnSyncInputStartup));
+        framesIn = 0;
+        SyncInCount = 0;
+        GenLockOnlyMode = false;
+        GenLockToSync = false;
+        while (!LTCInput.searchForSync()) {
+            if (framesIn == 100) {
+                GenLockOnlyMode = true;
+                break;
+            }
+            if ((SyncInCount == 100) && (framesIn<45)) { // prefer frame input pin, sync may be twice as high for interlaced systems.
+                GenLockOnlyMode = true;
+                GenLockToSync= true;
+                break;
+            }
+
+            int message = VIPS.getStatusMessage();
+            if (message)
+                pc.printf("%s\r\n",VIPSStatusMessages[message-1]);
 
-      int message = VIPS.getStatusMessage();
-      if (message)
-          pc.printf("%s\r\n",VIPSStatusMessages[message-1]);
-        
-    }
-    if (GenLockOnlyMode) {
-        if (GenLockToSync) {
-            pc.printf("No LTC detected for 100 frames. Falling back to genlock on sync input\r\n");
-            Syncin.rise(callback(&OnPPFInput));
-            PPFin.rise(NULL);
-        } else {
-            pc.printf("No LTC detected for 100 frames. Falling back to genlock on frame input\r\n");
-            PPFin.rise(callback(&OnPPFInput));
-            Syncin.rise(NULL);
-        }
-      uint32_t lastframeTime = inputTimer.read_us();
-
-      while (true) {
-        if (NewFramePulse) { // running on a frame
-//            printf("frame\r");
-          lastframeTime = FramePulseTime;
-          framePulse(lastframeTime);
-          NewFramePulse = false;
-        }
-        if ((inputTimer.read_us()-lastframeTime) > 1000000) {
-          pc.printf("No frames for > 1 second\r\n");
-            break;
         }
-        int message = VIPS.getStatusMessage();
-        if (message)
-            pc.printf("%s\r\n",VIPSStatusMessages[message-1]);
-      }
-    } else { // not genlock
-      pc.printf("Got LTC sync\r\n");
-      PPFin.rise(NULL);        
-      while (LTCInput.synced()) {
-        position *posPtr = VIPS.getWaitingPostion();
-        if (posPtr) {
-            sendPosition(posPtr);
+        if (GenLockOnlyMode) {
+            if (GenLockToSync) {
+                pc.printf("No LTC detected for 100 frames. Falling back to genlock on sync input\r\n");
+                Syncin.rise(callback(&OnPPFInput));
+                PPFin.rise(NULL);
+            } else {
+                pc.printf("No LTC detected for 100 frames. Falling back to genlock on frame input\r\n");
+                PPFin.rise(callback(&OnPPFInput));
+                Syncin.rise(NULL);
+            }
+            uint32_t lastframeTime = inputTimer.read_us();
+
+            while (true) {
+                if (NewFramePulse) { // running on a frame
+//            printf("frame\r");
+                    lastframeTime = FramePulseTime;
+                    framePulse(lastframeTime);
+                    NewFramePulse = false;
+                }
+                if ((inputTimer.read_us()-lastframeTime) > 1000000) {
+                    pc.printf("No frames for > 1 second\r\n");
+                    break;
+                }
+                int message = VIPS.getStatusMessage();
+                if (message)
+                    pc.printf("%s\r\n",VIPSStatusMessages[message-1]);
+            }
+        } else { // not genlock
+            pc.printf("Got LTC sync\r\n");
+            PPFin.rise(NULL);
+            while (LTCInput.synced()) {
+                position *posPtr = VIPS.getWaitingPostion();
+                if (posPtr) {
+                    sendPosition(posPtr);
+                }
+                if (LTCInput.readWaitingData()) {
+                    if (LTCInput.synced()) {
+                        const LTCDecode::LTCData_t *frameData = LTCInput.getLastFrame();
+                        detectedRate.setDrop(frameData->frameDrop);
+                        frameComplete(frameData->hours, frameData->minutes,
+                                      frameData->seconds, frameData->frame,
+                                      frameData->frameDrop, frameData->frameStartTime);
+                    } // end if good frame
+                }   // end if new data
+                int message = VIPS.getStatusMessage();
+                if (message)
+                    pc.printf("%s\r\n",VIPSStatusMessages[message-1]);
+            }     // end while synced
+            pc.printf("Sync lost\r");
         }
-        if (LTCInput.readWaitingData()) {
-          if (LTCInput.synced()) {
-            const LTCDecode::LTCData_t *frameData = LTCInput.getLastFrame();
-            detectedRate.setDrop(frameData->frameDrop);
-            frameComplete(frameData->hours, frameData->minutes,
-                          frameData->seconds, frameData->frame,
-                          frameData->frameDrop, frameData->frameStartTime);
-          } // end if good frame
-        }   // end if new data
-        int message = VIPS.getStatusMessage();
-        if (message)
-            pc.printf("%s\r\n",VIPSStatusMessages[message-1]);
-      }     // end while synced
-      pc.printf("Sync lost\r");
-    }
-  } // end while true
+    } // end while true
 }