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.
main.cpp
- Committer:
- shimniok
- Date:
- 2013-05-17
- Revision:
- 3:4e131dfd860a
- Parent:
- 2:0ebd24621d18
File content as of revision 3:4e131dfd860a:
/**
* uBlox UBX Protocol Reader - Wayne Holder
* Ported to mbed - Michael Shimniok
*
* Note: RX pad on 3DR Module is output, TX is input
*/
#include "mbed.h"
void printLatLon(long val);
void sendCmd(unsigned char len, uint8_t data[]);
void printHex(unsigned char val);
#define MAX_LENGTH 512
#define SYNC1 0xB5
#define SYNC2 0x62
#define POSLLH_MSG 0x02
#define SBAS_MSG 0x32
#define VELNED_MSG 0x12
#define STATUS_MSG 0x03
#define SOL_MSG 0x06
#define DOP_MSG 0x04
#define DGPS_MSG 0x31
#define SVINFO_MSG 0x30
#define LONG(X) *(int32_t *)(&data[X])
#define ULONG(X) *(uint32_t *)(&data[X])
#define INT(X) *(int16_t *)(&data[X])
#define UINT(X) *(uint16_t *)(&data[X])
unsigned char state, lstate, code, id, chk1, chk2, ck1, ck2;
unsigned int length, idx, cnt;
bool gpsReady = false;
bool checkOk = false;
unsigned char data[MAX_LENGTH];
long lastTime = 0;
Serial pc(USBTX, USBRX);
Serial gps(p9, p10);
DigitalOut led(LED1);
unsigned char buf[MAX_LENGTH];
int in=0;
int out=0;
void enableMsg(unsigned char id, bool enable, int rate=1)
{
if (!enable) rate = 0;
uint8_t cmdBuf[] = {
0x06, // class CFG
0x01, // id MSG -> CFG-MSG
8, // length, for config message rates
0x01, // class,
id, // id,
0x0, // target 0 rate (DDC/I2C)
rate, // target 1 rate (UART1)
0x0, // target 2 rate (UART2)
0x0, // target 3 rate (USB)
0x0, // target 4 rate (SPI)
0x0, // target 5 rate (reserved)
};
sendCmd(sizeof(cmdBuf), cmdBuf);
}
void rx_handler()
{
buf[in++] = gps.getc();
in &= (MAX_LENGTH-1);
led = !led;
}
int main()
{
pc.baud(115200);
gps.baud(38400);
gps.attach( &rx_handler );
pc.printf("ublox demo starting...\n");
led = 1;
// Configure GPS
uint8_t cmdbuf[40];
for (int i=0; i < 38; i++)
cmdbuf[i] = 0;
cmdbuf[0] = 0x06; // NAV-CFG5
cmdbuf[1] = 0x24; // NAV-CFG5
cmdbuf[2] = 0x00; // X2 bitmask
cmdbuf[3] = 0x01; // bitmask: dynamic model
cmdbuf[4] = 0x04; // U1 automotive dyn model
sendCmd(38, cmdbuf);
// Modify these to control which messages are sent from module
enableMsg(POSLLH_MSG, true); // Enable position messages
enableMsg(SBAS_MSG, false); // Enable SBAS messages
enableMsg(VELNED_MSG, true); // Enable velocity messages
enableMsg(STATUS_MSG, true); // Enable status messages
enableMsg(SOL_MSG, true); // Enable soluton messages
enableMsg(DOP_MSG, false); // Enable DOP messages
enableMsg(SVINFO_MSG, true, 2); // Enable SV info messages
enableMsg(DGPS_MSG, false); // Disable DGPS messages
while (1) {
if (in != out) {
unsigned char cc = buf[out++];
out &= (MAX_LENGTH-1);
switch (state) {
case 0: // wait for sync 1 (0xB5)
ck1 = ck2 = 0;
checkOk = false;
if (cc == SYNC1)
state++;
break;
case 1: // wait for sync 2 (0x62)
if (cc == SYNC2)
state++;
else
state = 0;
break;
case 2: // wait for class code
code = cc;
ck1 += cc;
ck2 += ck1;
state++;
break;
case 3: // wait for Id
id = cc;
ck1 += cc;
ck2 += ck1;
state++;
break;
case 4: // wait for length uint8_t 1
length = cc;
ck1 += cc;
ck2 += ck1;
state++;
break;
case 5: // wait for length uint8_t 2
length |= (unsigned int) cc << 8;
ck1 += cc;
ck2 += ck1;
idx = 0;
state++;
if (length > MAX_LENGTH)
state= 0;
break;
case 6: // wait for <length> payload uint8_ts
data[idx++] = cc;
ck1 += cc;
ck2 += ck1;
if (idx >= length) {
state++;
}
break;
case 7: // wait for checksum 1
chk1 = cc;
state++;
break;
case 8: { // wait for checksum 2
chk2 = cc;
checkOk = ck1 == chk1 && ck2 == chk2;
if (!checkOk) {
pc.printf("Checksum failed\n");
} else {
switch (code) {
case 0x01: // NAV-
// Add blank line between time groups
if (lastTime != ULONG(0)) {
lastTime = ULONG(0);
pc.printf("\nTime: %u\n", ULONG(0) );
}
pc.printf("NAV-");
switch (id) {
case POSLLH_MSG: // NAV-POSLLH
pc.printf("POSLLH: lon = ");
printLatLon(LONG(4));
pc.printf(", lat = ");
printLatLon(LONG(8));
pc.printf(", vAcc = %u", ULONG(24));
pc.printf(" mm, hAcc = %u", ULONG(20));
pc.printf(" mm");
break;
case STATUS_MSG: // NAV-STATUS
pc.printf("STATUS: gpsFix = %d", data[4]);
if (data[5] & 2) {
pc.printf(", dgpsFix");
}
break;
case DOP_MSG: // NAV-DOP
pc.printf("DOP: gDOP = %.1f", ((float) UINT(4))/100.0);
pc.printf(", tDOP = %.1f", ((float) UINT(8))/100.0);
pc.printf(", vDOP = %.1f", ((float) UINT(10))/100.0);
pc.printf(", hDOP = %.1f", ((float) UINT(12))/100.0);
break;
case SOL_MSG: // NAV-SOL
pc.printf("SOL: week = %u", UINT(8));
pc.printf(", gpsFix = ", data[10]);
pc.printf(", pDOP = %.1f", ((float) UINT(44))/ 100.0);
pc.printf(", pAcc = %u", ULONG(24));
pc.printf(" cm, numSV = %d", data[47]);
break;
case VELNED_MSG: // NAV-VELNED
pc.printf("VELNED: gSpeed = %u", ULONG(20));
pc.printf(" cm/sec, sAcc = %u", ULONG(28));
pc.printf(" cm/sec, heading = %.2f", ((float) LONG(24))/100000.0);
pc.printf(" deg, cAcc = %.2f", ((float) LONG(32))/100000.0);
pc.printf(" deg");
break;
case SVINFO_MSG: { // NAV-SVINFO
unsigned int nc = data[4]; // number of channels
pc.printf("SVINFO: channels = %u\n", nc);
for (int ch = 0; ch < nc; ch++) {
pc.printf(" id = %3u (%2u) ", data[9+12*ch], data[12+12*ch]);
for (int q=0; q < data[12+12*ch]/5; q++)
pc.printf("*");
pc.printf("\n");
}
break;
}
case DGPS_MSG: // NAV-DGPS
pc.printf("DGPS: age = %d", LONG(4));
pc.printf(", baseId = %d", INT(8));
pc.printf(", numCh = %d", INT(12));
break;
case SBAS_MSG: // NAV-SBAS
pc.printf("SBAS: geo = ");
switch (data[4]) {
case 133:
pc.printf("Inmarsat 4F3");
break;
case 135:
pc.printf("Galaxy 15");
break;
case 138:
pc.printf("Anik F1R");
break;
default:
pc.printf("%d", data[4]);
break;
}
pc.printf(", mode = ");
switch (data[5]) {
case 0:
pc.printf("disabled");
break;
case 1:
pc.printf("enabled integrity");
break;
case 2:
pc.printf("enabled test mode");
break;
default:
pc.printf("%d", data[5]);
}
pc.printf(", sys = ");
switch (data[6]) {
case 0:
pc.printf("WAAS");
break;
case 1:
pc.printf("EGNOS");
break;
case 2:
pc.printf("MSAS");
break;
case 16:
pc.printf("GPS");
break;
default:
pc.printf("%d", data[6]);
}
break;
default:
printHex(id);
}
pc.printf("\n");
break;
case 0x05: // ACK-
pc.printf("ACK-");
switch (id) {
case 0x00: // ACK-NAK
pc.printf("NAK: ");
break;
case 0x01: // ACK-ACK
pc.printf("ACK: ");
break;
}
printHex(data[0]);
pc.printf(" ");
printHex(data[1]);
pc.printf("\n");
break;
}
}
state = 0;
break;
}
default:
break;
}
}
}
}
// Convert 1e-7 value packed into long into decimal format
void printLatLon (long val)
{
int d = 10000000;
pc.printf("%d.%d", val/d, abs(val%d));
}
void printHex (unsigned char val)
{
pc.printf("%02x", val);
}
void sendCmd (unsigned char len, uint8_t data[])
{
unsigned char chk1 = 0, chk2 = 0;
gps.putc(SYNC1);
gps.putc(SYNC2);
for (unsigned char ii = 0; ii < len; ii++) {
gps.putc(data[ii]);
chk1 += data[ii];
chk2 += chk1;
}
gps.putc(chk1);
gps.putc(chk2);
}