Example program to demonstrate the use of the UbloxATCellularInterfaceExt class, providing FTP, HTTP, and CellLocate support. It may be used on the C027 and C030 (non-N2xx flavour) boards.

Dependencies:   gnss ublox-at-cellular-interface-ext ublox-cellular-base ublox-cellular-driver-gen

Fork of example-ublox-at-cellular-interface-ext by u-blox

Committer:
rob.meades@u-blox.com
Date:
Thu Jun 08 09:11:45 2017 +0100
Revision:
4:13a84f6cc800
Parent:
1:628f51c3511f
Child:
5:540b2d19fc5c
Update example to use button press and tidied up LED stuff.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rob.meades@u-blox.com 1:628f51c3511f 1 /* mbed Microcontroller Library
rob.meades@u-blox.com 1:628f51c3511f 2 * Copyright (c) 2017 u-blox
rob.meades@u-blox.com 1:628f51c3511f 3 *
rob.meades@u-blox.com 1:628f51c3511f 4 * Licensed under the Apache License, Version 2.0 (the "License");
rob.meades@u-blox.com 1:628f51c3511f 5 * you may not use this file except in compliance with the License.
rob.meades@u-blox.com 1:628f51c3511f 6 * You may obtain a copy of the License at
rob.meades@u-blox.com 1:628f51c3511f 7 *
rob.meades@u-blox.com 1:628f51c3511f 8 * http://www.apache.org/licenses/LICENSE-2.0
rob.meades@u-blox.com 1:628f51c3511f 9 *
rob.meades@u-blox.com 1:628f51c3511f 10 * Unless required by applicable law or agreed to in writing, software
rob.meades@u-blox.com 1:628f51c3511f 11 * distributed under the License is distributed on an "AS IS" BASIS,
rob.meades@u-blox.com 1:628f51c3511f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rob.meades@u-blox.com 1:628f51c3511f 13 * See the License for the specific language governing permissions and
rob.meades@u-blox.com 1:628f51c3511f 14 * limitations under the License.
rob.meades@u-blox.com 1:628f51c3511f 15 */
rob.meades@u-blox.com 1:628f51c3511f 16
rob.meades@u-blox.com 1:628f51c3511f 17 #include "mbed.h"
rob.meades@u-blox.com 1:628f51c3511f 18 #include "UbloxATCellularInterfaceExt.h"
rob.meades@u-blox.com 1:628f51c3511f 19 #include "gnss.h"
rob.meades@u-blox.com 1:628f51c3511f 20
rob.meades@u-blox.com 1:628f51c3511f 21 // The credentials of the SIM in the board. If PIN checking is enabled
rob.meades@u-blox.com 1:628f51c3511f 22 // for your SIM card you must set this to the required PIN.
rob.meades@u-blox.com 1:628f51c3511f 23 #define PIN "0000"
rob.meades@u-blox.com 1:628f51c3511f 24
rob.meades@u-blox.com 1:628f51c3511f 25 // Network credentials. You should set this according to your
rob.meades@u-blox.com 1:628f51c3511f 26 // network/SIM card. For C030 boards, leave the parameters as NULL
rob.meades@u-blox.com 1:628f51c3511f 27 // otherwise, if you do not know the APN for your network, you may
rob.meades@u-blox.com 4:13a84f6cc800 28 // either try the fairly common "internet" for the APN (and leave the
rob.meades@u-blox.com 1:628f51c3511f 29 // username and password NULL), or you may leave all three as NULL and then
rob.meades@u-blox.com 1:628f51c3511f 30 // a lookup will be attempted for a small number of known networks
rob.meades@u-blox.com 1:628f51c3511f 31 // (see APN_db.h in mbed-os/features/netsocket/cellular/utils).
rob.meades@u-blox.com 1:628f51c3511f 32 #define APN NULL
rob.meades@u-blox.com 1:628f51c3511f 33 #define USERNAME NULL
rob.meades@u-blox.com 1:628f51c3511f 34 #define PASSWORD NULL
rob.meades@u-blox.com 1:628f51c3511f 35
rob.meades@u-blox.com 1:628f51c3511f 36 // LEDs
rob.meades@u-blox.com 1:628f51c3511f 37 DigitalOut ledRed(LED1, 1);
rob.meades@u-blox.com 1:628f51c3511f 38 DigitalOut ledGreen(LED2, 1);
rob.meades@u-blox.com 1:628f51c3511f 39 DigitalOut ledBlue(LED3, 1);
rob.meades@u-blox.com 1:628f51c3511f 40
rob.meades@u-blox.com 4:13a84f6cc800 41 // The user button
rob.meades@u-blox.com 4:13a84f6cc800 42 volatile bool buttonPressed = false;
rob.meades@u-blox.com 4:13a84f6cc800 43
rob.meades@u-blox.com 4:13a84f6cc800 44 static void good() {
rob.meades@u-blox.com 4:13a84f6cc800 45 ledGreen = 0;
rob.meades@u-blox.com 4:13a84f6cc800 46 ledBlue = 1;
rob.meades@u-blox.com 4:13a84f6cc800 47 ledRed = 1;
rob.meades@u-blox.com 4:13a84f6cc800 48 }
rob.meades@u-blox.com 4:13a84f6cc800 49
rob.meades@u-blox.com 4:13a84f6cc800 50 static void bad() {
rob.meades@u-blox.com 4:13a84f6cc800 51 ledRed = 0;
rob.meades@u-blox.com 4:13a84f6cc800 52 ledGreen = 1;
rob.meades@u-blox.com 4:13a84f6cc800 53 ledBlue = 1;
rob.meades@u-blox.com 4:13a84f6cc800 54 }
rob.meades@u-blox.com 4:13a84f6cc800 55
rob.meades@u-blox.com 4:13a84f6cc800 56 static void event() {
rob.meades@u-blox.com 1:628f51c3511f 57 ledBlue = 0;
rob.meades@u-blox.com 1:628f51c3511f 58 ledRed = 1;
rob.meades@u-blox.com 1:628f51c3511f 59 ledGreen = 1;
rob.meades@u-blox.com 4:13a84f6cc800 60 }
rob.meades@u-blox.com 4:13a84f6cc800 61
rob.meades@u-blox.com 4:13a84f6cc800 62 static void pulseEvent() {
rob.meades@u-blox.com 4:13a84f6cc800 63 event();
rob.meades@u-blox.com 1:628f51c3511f 64 wait_ms(500);
rob.meades@u-blox.com 4:13a84f6cc800 65 good();
rob.meades@u-blox.com 4:13a84f6cc800 66 }
rob.meades@u-blox.com 4:13a84f6cc800 67
rob.meades@u-blox.com 4:13a84f6cc800 68 static void ledOff() {
rob.meades@u-blox.com 1:628f51c3511f 69 ledBlue = 1;
rob.meades@u-blox.com 1:628f51c3511f 70 ledRed = 1;
rob.meades@u-blox.com 4:13a84f6cc800 71 ledGreen = 1;
rob.meades@u-blox.com 1:628f51c3511f 72 }
rob.meades@u-blox.com 1:628f51c3511f 73
rob.meades@u-blox.com 1:628f51c3511f 74 static void printCellLocateData(UbloxATCellularInterfaceExt::CellLocData *pData)
rob.meades@u-blox.com 1:628f51c3511f 75 {
rob.meades@u-blox.com 1:628f51c3511f 76 char timeString[25];
rob.meades@u-blox.com 1:628f51c3511f 77
rob.meades@u-blox.com 1:628f51c3511f 78 printf("Cell Locate data:\n");
rob.meades@u-blox.com 1:628f51c3511f 79 if (strftime(timeString, sizeof(timeString), "%F %T", (const tm *) &(pData->time)) > 0) {
rob.meades@u-blox.com 1:628f51c3511f 80 printf(" time: %s\n", timeString);
rob.meades@u-blox.com 1:628f51c3511f 81 }
rob.meades@u-blox.com 1:628f51c3511f 82 printf(" longitude: %.6f\n", pData->longitude);
rob.meades@u-blox.com 1:628f51c3511f 83 printf(" latitude: %.6f\n", pData->latitude);
rob.meades@u-blox.com 1:628f51c3511f 84 printf(" altitude: %d metre(s)\n", pData->altitude);
rob.meades@u-blox.com 1:628f51c3511f 85 switch (pData->sensor) {
rob.meades@u-blox.com 1:628f51c3511f 86 case UbloxATCellularInterfaceExt::CELL_LAST:
rob.meades@u-blox.com 1:628f51c3511f 87 printf(" sensor type: last\n");
rob.meades@u-blox.com 1:628f51c3511f 88 break;
rob.meades@u-blox.com 1:628f51c3511f 89 case UbloxATCellularInterfaceExt::CELL_GNSS:
rob.meades@u-blox.com 1:628f51c3511f 90 printf(" sensor type: GNSS\n");
rob.meades@u-blox.com 1:628f51c3511f 91 break;
rob.meades@u-blox.com 1:628f51c3511f 92 case UbloxATCellularInterfaceExt::CELL_LOCATE:
rob.meades@u-blox.com 1:628f51c3511f 93 printf(" sensor type: Cell Locate\n");
rob.meades@u-blox.com 1:628f51c3511f 94 break;
rob.meades@u-blox.com 1:628f51c3511f 95 case UbloxATCellularInterfaceExt::CELL_HYBRID:
rob.meades@u-blox.com 1:628f51c3511f 96 printf(" sensor type: hybrid\n");
rob.meades@u-blox.com 1:628f51c3511f 97 break;
rob.meades@u-blox.com 1:628f51c3511f 98 default:
rob.meades@u-blox.com 1:628f51c3511f 99 printf(" sensor type: unknown\n");
rob.meades@u-blox.com 1:628f51c3511f 100 break;
rob.meades@u-blox.com 1:628f51c3511f 101 }
rob.meades@u-blox.com 1:628f51c3511f 102 printf(" uncertainty: %d metre(s)\n", pData->uncertainty);
rob.meades@u-blox.com 1:628f51c3511f 103 printf(" speed: %d metre(s)/second\n", pData->speed);
rob.meades@u-blox.com 1:628f51c3511f 104 printf(" direction: %d degree(s)\n", pData->direction);
rob.meades@u-blox.com 1:628f51c3511f 105 printf(" vertical accuracy: %d metre(s)/second\n", pData->speed);
rob.meades@u-blox.com 1:628f51c3511f 106 printf(" satellite(s) used: %d\n", pData->svUsed);
rob.meades@u-blox.com 4:13a84f6cc800 107 printf("I am here: "
rob.meades@u-blox.com 1:628f51c3511f 108 "https://maps.google.com/?q=%.5f,%.5f\n", pData->latitude, pData->longitude);
rob.meades@u-blox.com 1:628f51c3511f 109 }
rob.meades@u-blox.com 1:628f51c3511f 110
rob.meades@u-blox.com 4:13a84f6cc800 111 static void cbButton()
rob.meades@u-blox.com 4:13a84f6cc800 112 {
rob.meades@u-blox.com 4:13a84f6cc800 113 buttonPressed = true;
rob.meades@u-blox.com 4:13a84f6cc800 114 pulseEvent();
rob.meades@u-blox.com 4:13a84f6cc800 115 }
rob.meades@u-blox.com 4:13a84f6cc800 116
rob.meades@u-blox.com 1:628f51c3511f 117 /* This example program for the u-blox C030 and C027 boards instantiates
rob.meades@u-blox.com 1:628f51c3511f 118 * the UbloxAtCellularInterface to do FTP, HTTP and CellLocate operations.
rob.meades@u-blox.com 1:628f51c3511f 119 * It uses test.rebex.net for FTP testing and mbed.org for HTTP GET testing.
rob.meades@u-blox.com 1:628f51c3511f 120 * Progress may be monitored with a serial terminal running at 9600 baud.
rob.meades@u-blox.com 1:628f51c3511f 121 * The LED on the C030 board will turn green when this program is
rob.meades@u-blox.com 1:628f51c3511f 122 * operating correctly, pulse blue when an FTP get, HTTP get or CellLocate
rob.meades@u-blox.com 1:628f51c3511f 123 * operation is completed and turn red if there is a failure.
rob.meades@u-blox.com 1:628f51c3511f 124 */
rob.meades@u-blox.com 1:628f51c3511f 125
rob.meades@u-blox.com 1:628f51c3511f 126 int main()
rob.meades@u-blox.com 1:628f51c3511f 127 {
rob.meades@u-blox.com 1:628f51c3511f 128 UbloxATCellularInterfaceExt *interface = new UbloxATCellularInterfaceExt();
rob.meades@u-blox.com 1:628f51c3511f 129 UbloxATCellularInterfaceExt::Error *err;
rob.meades@u-blox.com 1:628f51c3511f 130 UbloxATCellularInterfaceExt::CellLocData data;
rob.meades@u-blox.com 1:628f51c3511f 131 char buf[1024];
rob.meades@u-blox.com 1:628f51c3511f 132 int httpProfile;
rob.meades@u-blox.com 1:628f51c3511f 133 int numRes;
rob.meades@u-blox.com 1:628f51c3511f 134 GnssSerial gnssSerial;
rob.meades@u-blox.com 4:13a84f6cc800 135 InterruptIn userButton(SW0);
rob.meades@u-blox.com 4:13a84f6cc800 136
rob.meades@u-blox.com 4:13a84f6cc800 137 // Attach a function to the user button
rob.meades@u-blox.com 4:13a84f6cc800 138 userButton.rise(&cbButton);
rob.meades@u-blox.com 1:628f51c3511f 139
rob.meades@u-blox.com 1:628f51c3511f 140 // Power up GNSS for the Cell Locate bit
rob.meades@u-blox.com 1:628f51c3511f 141 gnssSerial.init();
rob.meades@u-blox.com 4:13a84f6cc800 142 good();
rob.meades@u-blox.com 4:13a84f6cc800 143 printf("Starting up, please wait up to 180 seconds for network registration to complete...\n");
rob.meades@u-blox.com 1:628f51c3511f 144 if (interface->init(PIN)) {
rob.meades@u-blox.com 4:13a84f6cc800 145 pulseEvent();
rob.meades@u-blox.com 4:13a84f6cc800 146 printf("Registered, connecting to the packet network...\n");
rob.meades@u-blox.com 1:628f51c3511f 147 for (int x = 0; interface->connect(PIN, APN, USERNAME, PASSWORD) != 0; x++) {
rob.meades@u-blox.com 1:628f51c3511f 148 if (x > 0) {
rob.meades@u-blox.com 4:13a84f6cc800 149 bad();
rob.meades@u-blox.com 4:13a84f6cc800 150 printf("Retrying (have you checked that an antenna is plugged in and your APN is correct?)...\n");
rob.meades@u-blox.com 1:628f51c3511f 151 }
rob.meades@u-blox.com 1:628f51c3511f 152 }
rob.meades@u-blox.com 4:13a84f6cc800 153 pulseEvent();
rob.meades@u-blox.com 1:628f51c3511f 154
rob.meades@u-blox.com 1:628f51c3511f 155 // FTP OPERATIONS
rob.meades@u-blox.com 1:628f51c3511f 156 // Reset FTP parameters to default then set things up
rob.meades@u-blox.com 4:13a84f6cc800 157 printf("=== FTP ===\n");
rob.meades@u-blox.com 1:628f51c3511f 158 interface->ftpResetPar();
rob.meades@u-blox.com 1:628f51c3511f 159 interface->ftpSetTimeout(60000);
rob.meades@u-blox.com 1:628f51c3511f 160 interface->ftpSetPar(UbloxATCellularInterfaceExt::FTP_SERVER_NAME, "test.rebex.net");
rob.meades@u-blox.com 1:628f51c3511f 161 interface->ftpSetPar(UbloxATCellularInterfaceExt::FTP_USER_NAME, "demo");
rob.meades@u-blox.com 1:628f51c3511f 162 interface->ftpSetPar(UbloxATCellularInterfaceExt::FTP_PASSWORD, "password");
rob.meades@u-blox.com 1:628f51c3511f 163 interface->ftpSetPar(UbloxATCellularInterfaceExt::FTP_MODE, "1");
rob.meades@u-blox.com 1:628f51c3511f 164
rob.meades@u-blox.com 1:628f51c3511f 165 // Log into the FTP server
rob.meades@u-blox.com 4:13a84f6cc800 166 printf("Logging into FTP server \"test.rebex.net\"...\n");
rob.meades@u-blox.com 1:628f51c3511f 167 err = interface->ftpCommand(UbloxATCellularInterfaceExt::FTP_LOGIN);
rob.meades@u-blox.com 1:628f51c3511f 168 if (err == NULL) {
rob.meades@u-blox.com 4:13a84f6cc800 169 pulseEvent();
rob.meades@u-blox.com 1:628f51c3511f 170 // Get a directory listing from the server
rob.meades@u-blox.com 1:628f51c3511f 171 if (interface->ftpCommand(UbloxATCellularInterfaceExt::FTP_LS,
rob.meades@u-blox.com 1:628f51c3511f 172 NULL, NULL, 0, buf, sizeof (buf)) == NULL) {
rob.meades@u-blox.com 4:13a84f6cc800 173 pulseEvent();
rob.meades@u-blox.com 4:13a84f6cc800 174 printf ("Directory listing of FTP server:\n"
rob.meades@u-blox.com 4:13a84f6cc800 175 "--------------------------------\n%s"
rob.meades@u-blox.com 4:13a84f6cc800 176 "--------------------------------\n", buf);
rob.meades@u-blox.com 1:628f51c3511f 177 }
rob.meades@u-blox.com 1:628f51c3511f 178 // FTP GET a file known to be on test.rebex.net into the module file system
rob.meades@u-blox.com 1:628f51c3511f 179 if (interface->ftpCommand(UbloxATCellularInterfaceExt::FTP_GET_FILE, "readme.txt") == NULL) {
rob.meades@u-blox.com 4:13a84f6cc800 180 pulseEvent();
rob.meades@u-blox.com 1:628f51c3511f 181 // Read the file from the module file system into buf
rob.meades@u-blox.com 1:628f51c3511f 182 if (interface->readFile("readme.txt", buf, sizeof (buf))) {
rob.meades@u-blox.com 4:13a84f6cc800 183 printf("FTP GET of file \"readme.txt\" completed. The file contained:\n"
rob.meades@u-blox.com 4:13a84f6cc800 184 "-------------------------------------------------------------\n%s"
rob.meades@u-blox.com 4:13a84f6cc800 185 "-------------------------------------------------------------\n", buf);
rob.meades@u-blox.com 1:628f51c3511f 186 }
rob.meades@u-blox.com 1:628f51c3511f 187 }
rob.meades@u-blox.com 1:628f51c3511f 188 } else {
rob.meades@u-blox.com 4:13a84f6cc800 189 bad();
rob.meades@u-blox.com 1:628f51c3511f 190 printf ("Unable to log in, error class %d, error code %d.\n", err->eClass, err->eCode);
rob.meades@u-blox.com 1:628f51c3511f 191 }
rob.meades@u-blox.com 1:628f51c3511f 192
rob.meades@u-blox.com 1:628f51c3511f 193 // HTTP OPERATIONS
rob.meades@u-blox.com 1:628f51c3511f 194 // Set up HTTP parameters
rob.meades@u-blox.com 4:13a84f6cc800 195 printf("=== HTTP ===\n");
rob.meades@u-blox.com 4:13a84f6cc800 196 printf("Performing HTTP GET on \"mbed.org\"...\n");
rob.meades@u-blox.com 1:628f51c3511f 197 httpProfile = interface->httpAllocProfile();
rob.meades@u-blox.com 1:628f51c3511f 198 interface->httpSetTimeout(httpProfile, 30000);
rob.meades@u-blox.com 1:628f51c3511f 199 interface->httpSetPar(httpProfile, UbloxATCellularInterfaceExt::HTTP_SERVER_NAME, "mbed.org");
rob.meades@u-blox.com 1:628f51c3511f 200
rob.meades@u-blox.com 1:628f51c3511f 201 // Do the HTTP command
rob.meades@u-blox.com 1:628f51c3511f 202 err = interface->httpCommand(httpProfile, UbloxATCellularInterfaceExt::HTTP_GET,
rob.meades@u-blox.com 1:628f51c3511f 203 "/media/uploads/mbed_official/hello.txt",
rob.meades@u-blox.com 1:628f51c3511f 204 NULL, NULL, 0, NULL,
rob.meades@u-blox.com 1:628f51c3511f 205 buf, sizeof (buf));
rob.meades@u-blox.com 1:628f51c3511f 206 if (err == NULL) {
rob.meades@u-blox.com 4:13a84f6cc800 207 pulseEvent();
rob.meades@u-blox.com 4:13a84f6cc800 208 printf("HTTP GET of \"/media/uploads/mbed_official/hello.txt\" completed. The response contained:\n"
rob.meades@u-blox.com 4:13a84f6cc800 209 "------------------------------------------------------------------------------------\n%s"
rob.meades@u-blox.com 4:13a84f6cc800 210 "------------------------------------------------------------------------------------\n", buf);
rob.meades@u-blox.com 1:628f51c3511f 211 } else {
rob.meades@u-blox.com 4:13a84f6cc800 212 bad();
rob.meades@u-blox.com 4:13a84f6cc800 213 printf("Unable to get \"/media/uploads/mbed_official/hello.txt\" from \"mbed.org\", "
rob.meades@u-blox.com 4:13a84f6cc800 214 "error class %d, error code %d.\n", err->eClass, err->eCode);
rob.meades@u-blox.com 1:628f51c3511f 215 }
rob.meades@u-blox.com 1:628f51c3511f 216
rob.meades@u-blox.com 1:628f51c3511f 217 // CELL LOCATE OPERATIONS (in a loop)
rob.meades@u-blox.com 4:13a84f6cc800 218 printf("=== Cell Locate ===\n");
rob.meades@u-blox.com 4:13a84f6cc800 219 printf("Sending Cell Locate requests in a loop until user button is pressed...\n");
rob.meades@u-blox.com 4:13a84f6cc800 220 while (!buttonPressed) {
rob.meades@u-blox.com 1:628f51c3511f 221 interface->cellLocSrvUdp();
rob.meades@u-blox.com 1:628f51c3511f 222 interface->cellLocConfig(1); // Deep scan mode
rob.meades@u-blox.com 4:13a84f6cc800 223 printf("Sending Cell Locate request...\n");
rob.meades@u-blox.com 1:628f51c3511f 224 if (interface->cellLocRequest(UbloxATCellularInterfaceExt::CELL_HYBRID, 10, 100,
rob.meades@u-blox.com 1:628f51c3511f 225 (UbloxATCellularInterfaceExt::CellRespType) 1, 1)) {
rob.meades@u-blox.com 1:628f51c3511f 226 // Wait for the response
rob.meades@u-blox.com 1:628f51c3511f 227 numRes = 0;
rob.meades@u-blox.com 1:628f51c3511f 228 for (int x = 0; (numRes == 0) && (x < 10); x++) {
rob.meades@u-blox.com 1:628f51c3511f 229 numRes = interface->cellLocGetRes();
rob.meades@u-blox.com 1:628f51c3511f 230 }
rob.meades@u-blox.com 1:628f51c3511f 231
rob.meades@u-blox.com 1:628f51c3511f 232 if (numRes > 0) {
rob.meades@u-blox.com 1:628f51c3511f 233 interface->cellLocGetData(&data);
rob.meades@u-blox.com 1:628f51c3511f 234 if (data.validData) {
rob.meades@u-blox.com 4:13a84f6cc800 235 pulseEvent();
rob.meades@u-blox.com 1:628f51c3511f 236 printCellLocateData(&data);
rob.meades@u-blox.com 1:628f51c3511f 237 }
rob.meades@u-blox.com 1:628f51c3511f 238 } else {
rob.meades@u-blox.com 4:13a84f6cc800 239 bad();
rob.meades@u-blox.com 4:13a84f6cc800 240 printf("No response from Cell Locate server.\n");
rob.meades@u-blox.com 1:628f51c3511f 241 }
rob.meades@u-blox.com 1:628f51c3511f 242 }
rob.meades@u-blox.com 1:628f51c3511f 243 wait_ms(5000);
rob.meades@u-blox.com 1:628f51c3511f 244 }
rob.meades@u-blox.com 1:628f51c3511f 245
rob.meades@u-blox.com 4:13a84f6cc800 246 pulseEvent();
rob.meades@u-blox.com 4:13a84f6cc800 247 printf("User button was pressed, stopping...\n");
rob.meades@u-blox.com 4:13a84f6cc800 248 gnssSerial.powerOff();
rob.meades@u-blox.com 4:13a84f6cc800 249 interface->disconnect();
rob.meades@u-blox.com 4:13a84f6cc800 250 interface->deinit();
rob.meades@u-blox.com 4:13a84f6cc800 251 ledOff();
rob.meades@u-blox.com 4:13a84f6cc800 252 printf("Stopped.\n");
rob.meades@u-blox.com 1:628f51c3511f 253 } else {
rob.meades@u-blox.com 4:13a84f6cc800 254 bad();
rob.meades@u-blox.com 1:628f51c3511f 255 printf("Unable to initialise the interface.\n");
rob.meades@u-blox.com 1:628f51c3511f 256 }
rob.meades@u-blox.com 1:628f51c3511f 257 }
rob.meades@u-blox.com 1:628f51c3511f 258
rob.meades@u-blox.com 1:628f51c3511f 259 // End Of File