A GPS disciplined clock
Dependencies: net lpc1768 crypto clock web log
gps/pps.c
- Committer:
- andrewboyson
- Date:
- 2018-12-04
- Revision:
- 14:1bce51823be0
- Parent:
- 13:dc986dce561b
- Child:
- 15:e5bfa0cd1ff8
File content as of revision 14:1bce51823be0:
#include <stdbool.h> #include <time.h> #include "log.h" #include "clksync.h" #include "hrtimer.h" #include "gpio.h" #include "bitband.h" #define CONFIDENCE_OK 60 #define IO0INTENR_ADDR 0x40028090 #define IO0INTCLR_ADDR 0x4002808C #define ISER0_ADDR 0xE000E100 #define FIX_PIN FIO0PIN(23) #define ENABLE_DIR FIO0DIR(24) #define ENABLE_SET FIO0SET(24) #define ENABLE_CLR FIO0CLR(24) #define PPS_PIN FIO0PIN(17) #define PPS_INT_ENR BIT_BAND4(IO0INTENR_ADDR, 17) = 1 #define PPS_INT_CLR BIT_BAND4(IO0INTCLR_ADDR, 17) = 1 #define ISER0 *((volatile unsigned *) ISER0_ADDR) static uint32_t msTimer; static volatile bool hadPulse; time_t PpsTime = 0; int PpsMsSinceLastPulse = 0; bool PpsStable = false; static int confidence = 0; void PpsConfidenceNone() { confidence = 0; } void PpsConfidenceIncrease() { confidence++; if (confidence > CONFIDENCE_OK) confidence = CONFIDENCE_OK; } __irq void PpsHandler() { PPS_INT_CLR; ClkSyncPpsI(); hadPulse = true; } static void pulseN() { PpsTime += (PpsMsSinceLastPulse + 500) / 1000; int ppsOffset = PpsMsSinceLastPulse % 1000; if (ppsOffset != 999 && ppsOffset != 0) { LogTimeF("GPS %4d ms PPS interval is not 999 or 000 ms - sync disabled\r\n", PpsMsSinceLastPulse); confidence = 0; } if (confidence == CONFIDENCE_OK) ClkSyncPpsN(PpsTime); } void PpsMain() { //Handle time since last pulse PpsMsSinceLastPulse = HrTimerSinceMs(msTimer); bool pulseHasStopped = PpsMsSinceLastPulse > 1000; static bool pulseWasStopped = false; if ( pulseHasStopped) PpsConfidenceNone(); if ( pulseHasStopped && !pulseWasStopped) LogTimeF("GPS %4d ms PPS pulses have stopped - sync disabled\r\n", PpsMsSinceLastPulse); if (!pulseHasStopped && pulseWasStopped) LogTimeF("GPS %4d ms PPS pulses have started\r\n", PpsMsSinceLastPulse); pulseWasStopped = pulseHasStopped; //Handle the arrival of a pulse if (hadPulse) { msTimer = HrTimerCount(); pulseN(); hadPulse = false; pulseHasStopped = false; //This gets the signal 1 scan before the ms is reset } //Settle time after disruption bool isStable = confidence == CONFIDENCE_OK; static bool lastStable = false; if (isStable && !lastStable) LogTimeF("GPS %4d ms stable - sync enabled\r\n", PpsMsSinceLastPulse); lastStable = isStable; } void PpsInit() { msTimer = HrTimerCount(); ENABLE_CLR; //Set the enable to low to reset the GPS ENABLE_DIR = 1; //Set the enable pin direction to 1 == output while (HrTimerSinceMs(msTimer) < 10) __nop(); ENABLE_SET; //Set the enable to high PPS_INT_ENR; //Set the PPS pin to be interrupt on rise ISER0 |= 1 << 21; //6.5.1 bit1 == Interrupt set enable for EINT3. It MUST be enabled even for GPIO interrupts - I checked. }