Program to demonstrate the use of the LowPowerSleep class on the u-blox C030 platform.
Dependencies: gnss low-power-sleep
main.cpp@6:356d18b0e389, 2017-07-31 (annotated)
- Committer:
- rob.meades@u-blox.com
- Date:
- Mon Jul 31 11:19:44 2017 +0100
- Revision:
- 6:356d18b0e389
- Parent:
- 5:65094452a0c5
Point mbed-os library at ARMmbed master.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RobMeades | 0:84e316af0e0c | 1 | /* mbed Microcontroller Library |
RobMeades | 0:84e316af0e0c | 2 | * Copyright (c) 2017 u-blox |
RobMeades | 0:84e316af0e0c | 3 | * |
RobMeades | 0:84e316af0e0c | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
RobMeades | 0:84e316af0e0c | 5 | * you may not use this file except in compliance with the License. |
RobMeades | 0:84e316af0e0c | 6 | * You may obtain a copy of the License at |
RobMeades | 0:84e316af0e0c | 7 | * |
RobMeades | 0:84e316af0e0c | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
RobMeades | 0:84e316af0e0c | 9 | * |
RobMeades | 0:84e316af0e0c | 10 | * Unless required by applicable law or agreed to in writing, software |
RobMeades | 0:84e316af0e0c | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
RobMeades | 0:84e316af0e0c | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
RobMeades | 0:84e316af0e0c | 13 | * See the License for the specific language governing permissions and |
RobMeades | 0:84e316af0e0c | 14 | * limitations under the License. |
RobMeades | 0:84e316af0e0c | 15 | */ |
RobMeades | 0:84e316af0e0c | 16 | |
RobMeades | 0:84e316af0e0c | 17 | #include "mbed.h" |
RobMeades | 0:84e316af0e0c | 18 | #include "low_power.h" |
RobMeades | 0:84e316af0e0c | 19 | #include "gnss.h" |
RobMeades | 0:84e316af0e0c | 20 | |
RobMeades | 0:84e316af0e0c | 21 | #define GNSS_WAIT_TIME_SECONDS 120 |
RobMeades | 0:84e316af0e0c | 22 | #define STOP_TIME_SECONDS 5 |
RobMeades | 0:84e316af0e0c | 23 | #define STANDBY_TIME_SECONDS 5 |
rob.meades@u-blox.com | 1:633244b5186b | 24 | #define CHECK_TALKER(s) ((buffer[3] == s[0]) && (buffer[4] == s[1]) && (buffer[5] == s[2])) |
RobMeades | 0:84e316af0e0c | 25 | #define BACKUP_SRAM_STRING "Back from Standby mode!" |
RobMeades | 0:84e316af0e0c | 26 | |
RobMeades | 0:84e316af0e0c | 27 | // Put the time at the start of back-up SRAM |
RobMeades | 0:84e316af0e0c | 28 | BACKUP_SRAM |
RobMeades | 0:84e316af0e0c | 29 | static time_t timeNow; |
RobMeades | 0:84e316af0e0c | 30 | |
RobMeades | 0:84e316af0e0c | 31 | // The rest of backup SRAM |
RobMeades | 0:84e316af0e0c | 32 | BACKUP_SRAM |
RobMeades | 0:84e316af0e0c | 33 | static char backupSram[BACKUP_SRAM_SIZE - sizeof (timeNow)]; |
RobMeades | 0:84e316af0e0c | 34 | |
RobMeades | 0:84e316af0e0c | 35 | // LEDs |
RobMeades | 0:84e316af0e0c | 36 | DigitalOut ledRed(LED1, 1); |
RobMeades | 0:84e316af0e0c | 37 | DigitalOut ledGreen(LED2, 1); |
RobMeades | 0:84e316af0e0c | 38 | DigitalOut ledBlue(LED3, 1); |
RobMeades | 0:84e316af0e0c | 39 | |
RobMeades | 0:84e316af0e0c | 40 | /* IMPORTANT: this code puts the STM32F4xx chip into its lowest power state. |
RobMeades | 0:84e316af0e0c | 41 | * The ability to do this is affected by the state of the debug chip on the C030 |
RobMeades | 0:84e316af0e0c | 42 | * board. To be sure that this code executes correctly, you MUST completely |
RobMeades | 0:84e316af0e0c | 43 | * power off the board after downloading code, and power it back on again. |
RobMeades | 0:84e316af0e0c | 44 | */ |
RobMeades | 0:84e316af0e0c | 45 | |
RobMeades | 0:84e316af0e0c | 46 | /* This example program for the u-blox C030 board demonstrates the use of |
rob.meades@u-blox.com | 5:65094452a0c5 | 47 | * the low power driver. It waits for GNSS to obtain the time, entering Stop |
rob.meades@u-blox.com | 5:65094452a0c5 | 48 | * mode while waiting for the GNSS to return results and, once the time has |
rob.meades@u-blox.com | 1:633244b5186b | 49 | * been obtained, it enters Standby mode, putting some stored information |
rob.meades@u-blox.com | 5:65094452a0c5 | 50 | * into backup SRAM where it will remain safe during Standby mode. |
rob.meades@u-blox.com | 5:65094452a0c5 | 51 | * Note: the use of GNSS is in no way related to the LowPowerSleep class, |
rob.meades@u-blox.com | 5:65094452a0c5 | 52 | * it's simply something to do in this demonstration. |
rob.meades@u-blox.com | 1:633244b5186b | 53 | * Progress may be monitored with a serial terminal running at 9600 baud. |
rob.meades@u-blox.com | 1:633244b5186b | 54 | * The LED on the C030 board will turn green when this program is operating |
rob.meades@u-blox.com | 1:633244b5186b | 55 | * correctly, flash white when GNSS time is received, and turn red if GNSS |
rob.meades@u-blox.com | 1:633244b5186b | 56 | * time was not received or there is a failure. |
RobMeades | 0:84e316af0e0c | 57 | */ |
RobMeades | 0:84e316af0e0c | 58 | |
rob.meades@u-blox.com | 1:633244b5186b | 59 | // Get the time from GNSS |
rob.meades@u-blox.com | 1:633244b5186b | 60 | static bool gnssGetTime(GnssSerial *gnss) |
rob.meades@u-blox.com | 1:633244b5186b | 61 | { |
rob.meades@u-blox.com | 1:633244b5186b | 62 | char buffer[256]; |
rob.meades@u-blox.com | 1:633244b5186b | 63 | bool gotTime = false; |
rob.meades@u-blox.com | 1:633244b5186b | 64 | int gnssReturnCode; |
rob.meades@u-blox.com | 1:633244b5186b | 65 | int32_t length; |
rob.meades@u-blox.com | 1:633244b5186b | 66 | |
rob.meades@u-blox.com | 1:633244b5186b | 67 | while ((gnssReturnCode = gnss->getMessage(buffer, sizeof(buffer))) > 0) { |
rob.meades@u-blox.com | 1:633244b5186b | 68 | length = LENGTH(gnssReturnCode); |
rob.meades@u-blox.com | 1:633244b5186b | 69 | |
rob.meades@u-blox.com | 1:633244b5186b | 70 | if ((PROTOCOL(gnssReturnCode) == GnssParser::NMEA) && (length > 6)) { |
rob.meades@u-blox.com | 1:633244b5186b | 71 | // Talker is $GA=Galileo $GB=Beidou $GL=Glonass $GN=Combined $GP=GNSS |
rob.meades@u-blox.com | 1:633244b5186b | 72 | if ((buffer[0] == '$') || buffer[1] == 'G') { |
rob.meades@u-blox.com | 1:633244b5186b | 73 | if (CHECK_TALKER("GGA") || CHECK_TALKER("GNS")) { |
rob.meades@u-blox.com | 1:633244b5186b | 74 | const char *timeString = NULL; |
rob.meades@u-blox.com | 1:633244b5186b | 75 | // Retrieve the time |
rob.meades@u-blox.com | 1:633244b5186b | 76 | timeString = gnss->findNmeaItemPos(1, buffer, buffer + length); |
rob.meades@u-blox.com | 1:633244b5186b | 77 | if (timeString != NULL) { |
rob.meades@u-blox.com | 1:633244b5186b | 78 | gotTime = true; |
rob.meades@u-blox.com | 1:633244b5186b | 79 | printf("\nGNSS: time is %.6s (UTC).\n", timeString); |
rob.meades@u-blox.com | 1:633244b5186b | 80 | ledBlue = 0; |
rob.meades@u-blox.com | 1:633244b5186b | 81 | ledGreen = 0; |
rob.meades@u-blox.com | 1:633244b5186b | 82 | ledRed = 0; |
rob.meades@u-blox.com | 1:633244b5186b | 83 | wait_ms(1000); |
rob.meades@u-blox.com | 1:633244b5186b | 84 | } |
rob.meades@u-blox.com | 1:633244b5186b | 85 | } |
rob.meades@u-blox.com | 1:633244b5186b | 86 | } |
rob.meades@u-blox.com | 1:633244b5186b | 87 | } |
rob.meades@u-blox.com | 1:633244b5186b | 88 | } |
rob.meades@u-blox.com | 1:633244b5186b | 89 | |
rob.meades@u-blox.com | 1:633244b5186b | 90 | return gotTime; |
rob.meades@u-blox.com | 1:633244b5186b | 91 | } |
rob.meades@u-blox.com | 1:633244b5186b | 92 | |
rob.meades@u-blox.com | 1:633244b5186b | 93 | // Main |
RobMeades | 0:84e316af0e0c | 94 | int main() |
RobMeades | 0:84e316af0e0c | 95 | { |
RobMeades | 0:84e316af0e0c | 96 | GnssSerial gnss; |
RobMeades | 0:84e316af0e0c | 97 | LowPower lowPower; |
RobMeades | 0:84e316af0e0c | 98 | bool gotTime = false; |
RobMeades | 0:84e316af0e0c | 99 | |
RobMeades | 0:84e316af0e0c | 100 | // First exit Debug mode on the chip, otherwise it will not be |
RobMeades | 0:84e316af0e0c | 101 | // able to enter Standby mode |
RobMeades | 0:84e316af0e0c | 102 | lowPower.exitDebugMode(); |
RobMeades | 0:84e316af0e0c | 103 | |
rob.meades@u-blox.com | 1:633244b5186b | 104 | ledGreen = 0; |
rob.meades@u-blox.com | 1:633244b5186b | 105 | ledRed = 1; |
rob.meades@u-blox.com | 1:633244b5186b | 106 | ledBlue = 1; |
rob.meades@u-blox.com | 1:633244b5186b | 107 | |
RobMeades | 0:84e316af0e0c | 108 | // Initialise GNSS |
rob.meades@u-blox.com | 1:633244b5186b | 109 | if (gnss.init()) { |
rob.meades@u-blox.com | 1:633244b5186b | 110 | if (time(NULL) != 0) { |
rob.meades@u-blox.com | 1:633244b5186b | 111 | // If the RTC is running, we must have been awake previously |
rob.meades@u-blox.com | 1:633244b5186b | 112 | printf ("Awake from Standby mode after %d second(s).\n", |
rob.meades@u-blox.com | 1:633244b5186b | 113 | (int) (time(NULL) - timeNow)); |
rob.meades@u-blox.com | 1:633244b5186b | 114 | printf ("Backup RAM contains \"%.*s\".\n\n", sizeof(BACKUP_SRAM_STRING), |
rob.meades@u-blox.com | 1:633244b5186b | 115 | backupSram); |
rob.meades@u-blox.com | 1:633244b5186b | 116 | } else { |
rob.meades@u-blox.com | 1:633244b5186b | 117 | printf("\n\nStarting up from a cold start.\n"); |
rob.meades@u-blox.com | 1:633244b5186b | 118 | printf("IMPORTANT: this code puts the STM32F4xx chip into its lowest power state.\n"); |
rob.meades@u-blox.com | 1:633244b5186b | 119 | printf("The ability to do this is affected by the state of the debug chip on the C030\n"); |
rob.meades@u-blox.com | 1:633244b5186b | 120 | printf("board. To be sure that this code executes correctly, you must completely power\n"); |
rob.meades@u-blox.com | 1:633244b5186b | 121 | printf("off the board after downloading code, and power it back on again.\n\n"); |
rob.meades@u-blox.com | 1:633244b5186b | 122 | } |
RobMeades | 0:84e316af0e0c | 123 | |
rob.meades@u-blox.com | 1:633244b5186b | 124 | printf ("Waiting up to %d second(s) for GNSS to receive the time...\n", GNSS_WAIT_TIME_SECONDS); |
rob.meades@u-blox.com | 1:633244b5186b | 125 | for (uint32_t x = 0; (x < GNSS_WAIT_TIME_SECONDS) && !gotTime; x+= STOP_TIME_SECONDS) { |
rob.meades@u-blox.com | 1:633244b5186b | 126 | gotTime = gnssGetTime(&gnss); |
RobMeades | 0:84e316af0e0c | 127 | |
rob.meades@u-blox.com | 1:633244b5186b | 128 | if (!gotTime) { |
rob.meades@u-blox.com | 1:633244b5186b | 129 | printf (" Entering Stop mode for %d second(s) while waiting...\n", STOP_TIME_SECONDS); |
rob.meades@u-blox.com | 1:633244b5186b | 130 | // Let the printf leave the building |
rob.meades@u-blox.com | 1:633244b5186b | 131 | wait_ms(100); |
rob.meades@u-blox.com | 1:633244b5186b | 132 | time_t y = time(NULL); |
rob.meades@u-blox.com | 1:633244b5186b | 133 | lowPower.enterStop(STOP_TIME_SECONDS * 1000); |
rob.meades@u-blox.com | 1:633244b5186b | 134 | printf (" Awake from Stop mode after %d second(s).\n", (int) (time(NULL) - y)); |
RobMeades | 0:84e316af0e0c | 135 | } |
RobMeades | 0:84e316af0e0c | 136 | } |
RobMeades | 0:84e316af0e0c | 137 | |
rob.meades@u-blox.com | 1:633244b5186b | 138 | ledGreen = 1; |
rob.meades@u-blox.com | 1:633244b5186b | 139 | ledRed = 1; |
rob.meades@u-blox.com | 1:633244b5186b | 140 | ledBlue = 1; |
RobMeades | 0:84e316af0e0c | 141 | if (!gotTime) { |
rob.meades@u-blox.com | 1:633244b5186b | 142 | ledRed = 0; |
RobMeades | 0:84e316af0e0c | 143 | } |
rob.meades@u-blox.com | 1:633244b5186b | 144 | |
rob.meades@u-blox.com | 1:633244b5186b | 145 | printf ("\nPutting \"%s\" into BKPSRAM...\n", BACKUP_SRAM_STRING); |
rob.meades@u-blox.com | 1:633244b5186b | 146 | memcpy (backupSram, BACKUP_SRAM_STRING, sizeof(BACKUP_SRAM_STRING)); |
RobMeades | 0:84e316af0e0c | 147 | |
rob.meades@u-blox.com | 1:633244b5186b | 148 | printf ("Entering Standby mode, losing all RAM contents, for %d second(s)...\n\n", STANDBY_TIME_SECONDS); |
rob.meades@u-blox.com | 1:633244b5186b | 149 | // Let the printf leave the building |
rob.meades@u-blox.com | 1:633244b5186b | 150 | wait_ms(100); |
rob.meades@u-blox.com | 1:633244b5186b | 151 | // We will return at the start of main() when the Standby time expires |
rob.meades@u-blox.com | 1:633244b5186b | 152 | timeNow = time(NULL); |
rob.meades@u-blox.com | 1:633244b5186b | 153 | lowPower.enterStandby(STANDBY_TIME_SECONDS * 1000); |
rob.meades@u-blox.com | 1:633244b5186b | 154 | } else { |
rob.meades@u-blox.com | 1:633244b5186b | 155 | printf("Unable to initialise GNSS.\n"); |
RobMeades | 0:84e316af0e0c | 156 | } |
RobMeades | 0:84e316af0e0c | 157 | |
rob.meades@u-blox.com | 1:633244b5186b | 158 | ledRed = 0; |
RobMeades | 0:84e316af0e0c | 159 | ledGreen = 1; |
RobMeades | 0:84e316af0e0c | 160 | ledBlue = 1; |
RobMeades | 0:84e316af0e0c | 161 | printf("Should never get here.\n"); |
RobMeades | 0:84e316af0e0c | 162 | MBED_ASSERT(false); |
RobMeades | 0:84e316af0e0c | 163 | } |
RobMeades | 0:84e316af0e0c | 164 | |
RobMeades | 0:84e316af0e0c | 165 | // End Of File |