Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BufferedSerial FatFileSystemCpp mbed
Diff: main.cpp
- 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 }