A GPS disciplined clock
Dependencies: net lpc1768 crypto clock web log
gps/nmea/nmea-cmd.c
- Committer:
- andrewboyson
- Date:
- 2019-11-18
- Revision:
- 84:baec7c1f5618
- Parent:
- 78:8a29cad1b131
File content as of revision 84:baec7c1f5618:
#include <stdint.h> #include <stdbool.h> #include "mstimer.h" #include "log.h" #include "uart1.h" #include "nmea.h" #include "gps.h" bool NmeaCmdTrace = false; int NmeaCmdAckItem = -1; int NmeaCmdAckStatus = 0; static uint32_t msTimerCommand = 0; static void sendCommand(const char* command) { const char* p = command; NmeaCmdAckItem = -1; NmeaCmdAckStatus = 0; char checksum = 0; if (NmeaCmdTrace) GpsLog("NMEA sent command $"); while (Uart1PutC('$')); if (NmeaCmdTrace) Log(command); while (*p) { if (!Uart1PutC(*p)) { checksum ^= *p; p++; } } char csUpper = checksum >> 4; char csLower = checksum & 0xF; if (csUpper >= 10) csUpper += 'A' - 10; else csUpper += '0'; if (csLower >= 10) csLower += 'A' - 10; else csLower += '0'; if (NmeaCmdTrace) LogChar('*'); while (Uart1PutC('*')); if (NmeaCmdTrace) LogChar(csUpper); while (Uart1PutC(csUpper)); if (NmeaCmdTrace) LogChar(csLower); while (Uart1PutC(csLower)); if (NmeaCmdTrace) LogChar('\r'); while (Uart1PutC('\r')); if (NmeaCmdTrace) LogChar('\n'); while (Uart1PutC('\n')); } #define STATUS_DO_NOTHING 0 #define STATUS_INITIAL_WAIT 1 #define STATUS_AUTO_BAUDED 2 #define STATUS_SENT_TEST 3 #define STATUS_CHANGED_BAUD 4 #define STATUS_CHANGED_OUTPUTS 5 #define BAUD 9600 #define BAUD_STRING(X) STRINGIFY(X) // BAUD_STRING(BAUD) ==> STRINGIFY(19200) - BAUD is expanded to 19200 #define STRINGIFY(X) #X // STRINGIFY(19200) ==> "19200" - NB STRINGIFY[BAUD] ==> "BAUD" not "19200" as #X is not expanded! static int baud = BAUD; static void nextBaud() { switch (baud) { case 115200: baud = 4800; break; case 57600: baud = 115200; break; case 38400: baud = 57600; break; case 19200: baud = 38400; break; case 14400: baud = 19200; break; case 9600: baud = 14400; break; case 4800: baud = 9600; break; default : baud = 9600; break; } Uart1SetBaud(baud); } static int doStartInitialWait() { GpsLog("NMEA starting initial wait\r\n"); msTimerCommand = MsTimerCount; return STATUS_INITIAL_WAIT; } static int doSendTest() { GpsLog("NMEA sending test command\r\n"); msTimerCommand = MsTimerCount; sendCommand("PMTK000"); return STATUS_SENT_TEST; } static int doAutoBaud() { nextBaud(); GpsLog("NMEA auto bauded uart to %d and sending test command\r\n", baud); msTimerCommand = MsTimerCount; sendCommand("PMTK000"); return STATUS_AUTO_BAUDED; } static int doChangeBaud() { GpsLog("NMEA sending command to change baud to %d\r\n", BAUD); msTimerCommand = MsTimerCount; sendCommand("PMTK251," BAUD_STRING(BAUD)); Uart1SetBaud(BAUD); return STATUS_CHANGED_BAUD; } static int doChangeOutputs() { GpsLog("NMEA sending command to change message intervals\r\n"); msTimerCommand = MsTimerCount; sendCommand("PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0"); return STATUS_CHANGED_OUTPUTS; } static int doModuleReady() { GpsLog("NMEA module is ready\r\n"); NmeaModuleReadiness = NMEA_READINESS_READY; return STATUS_DO_NOTHING; } static int status = STATUS_DO_NOTHING; void NmeaCmdSetup() { if (!status) status = doSendTest(); } void NmeaCmdStartup() { status = doStartInitialWait(); } void NmeaCmdMain() { switch (status) { case STATUS_DO_NOTHING: break; case STATUS_INITIAL_WAIT: if (MsTimerRelative(msTimerCommand, 2000) ) status = doSendTest(); break; case STATUS_AUTO_BAUDED: if (NmeaCmdAckItem == 000 && NmeaCmdAckStatus == 3 && baud == BAUD) status = doChangeOutputs(); else if (NmeaCmdAckItem == 000 && NmeaCmdAckStatus == 3 && baud != BAUD) status = doChangeBaud(); else if (MsTimerRelative(msTimerCommand, 500) ) status = doAutoBaud(); break; case STATUS_CHANGED_BAUD: if (NmeaCmdAckItem == 251 && NmeaCmdAckStatus == 3 ) status = doChangeOutputs(); else if (MsTimerRelative(msTimerCommand, 700) ) status = doSendTest(); break; case STATUS_SENT_TEST: if (NmeaCmdAckItem == 000 && NmeaCmdAckStatus == 3 ) status = doChangeOutputs(); else if (MsTimerRelative(msTimerCommand, 500) ) status = doAutoBaud(); break; case STATUS_CHANGED_OUTPUTS: if (NmeaCmdAckItem == 314 && NmeaCmdAckStatus == 3 ) status = doModuleReady(); else if (MsTimerRelative(msTimerCommand, 500) ) status = doAutoBaud(); break; } } void NmeaCmdInit() { Uart1Init(BAUD); }