Program to demonstrate the use of the LowPowerSleep class on the u-blox C030 platform.

Dependencies:   gnss low-power-sleep

main.cpp

Committer:
rob.meades@u-blox.com
Date:
2017-07-31
Revision:
6:356d18b0e389
Parent:
5:65094452a0c5

File content as of revision 6:356d18b0e389:

/* mbed Microcontroller Library
 * Copyright (c) 2017 u-blox
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mbed.h"
#include "low_power.h"
#include "gnss.h"

#define GNSS_WAIT_TIME_SECONDS 120
#define STOP_TIME_SECONDS 5
#define STANDBY_TIME_SECONDS 5
#define CHECK_TALKER(s) ((buffer[3] == s[0]) && (buffer[4] == s[1]) && (buffer[5] == s[2]))
#define BACKUP_SRAM_STRING "Back from Standby mode!"

// Put the time at the start of back-up SRAM
BACKUP_SRAM
static time_t timeNow;

// The rest of backup SRAM
BACKUP_SRAM
static char backupSram[BACKUP_SRAM_SIZE - sizeof (timeNow)];

// LEDs
DigitalOut ledRed(LED1, 1);
DigitalOut ledGreen(LED2, 1);
DigitalOut ledBlue(LED3, 1);

/* IMPORTANT: this code puts the STM32F4xx chip into its lowest power state.
 * The ability to do this is affected by the state of the debug chip on the C030
 * board. To be sure that this code executes correctly, you MUST completely
 * power off the board after downloading code, and power it back on again.
 */

/* This example program for the u-blox C030 board demonstrates the use of
 * the low power driver.  It waits for GNSS to obtain the time, entering Stop
 * mode while waiting for the GNSS to return results and, once the time has
 * been obtained, it enters Standby mode, putting some stored information
 * into backup SRAM where it will remain safe during Standby mode.
 * Note: the use of GNSS is in no way related to the LowPowerSleep class,
 * it's simply something to do in this demonstration.
 * Progress may be monitored with a serial terminal running at 9600 baud.
 * The LED on the C030 board will turn green when this program is operating
 * correctly, flash white when GNSS time is received, and turn red if GNSS
 * time was not received or there is a failure.
 */

// Get the time from GNSS
static bool gnssGetTime(GnssSerial *gnss)
{
    char buffer[256];
    bool gotTime = false;
    int gnssReturnCode;
    int32_t length;
    
    while ((gnssReturnCode = gnss->getMessage(buffer, sizeof(buffer))) > 0) {
        length = LENGTH(gnssReturnCode);

        if ((PROTOCOL(gnssReturnCode) == GnssParser::NMEA) && (length > 6)) {
            // Talker is $GA=Galileo $GB=Beidou $GL=Glonass $GN=Combined $GP=GNSS
            if ((buffer[0] == '$') || buffer[1] == 'G') {
                if (CHECK_TALKER("GGA") || CHECK_TALKER("GNS")) {
                    const char *timeString = NULL;
                    // Retrieve the time
                    timeString = gnss->findNmeaItemPos(1, buffer, buffer + length);
                    if (timeString != NULL) {
                        gotTime = true;
                        printf("\nGNSS: time is %.6s (UTC).\n", timeString);
                        ledBlue = 0;
                        ledGreen = 0;
                        ledRed = 0;
                        wait_ms(1000);        
                    }
                }
            }
        }
    }
    
    return gotTime;
}

// Main
int main()
{
    GnssSerial gnss;
    LowPower lowPower;
    bool gotTime = false;

    // First exit Debug mode on the chip, otherwise it will not be
    // able to enter Standby mode
    lowPower.exitDebugMode();

    ledGreen = 0;
    ledRed = 1;
    ledBlue = 1;
        
    // Initialise GNSS
    if (gnss.init()) {
        if (time(NULL) != 0) {
            // If the RTC is running, we must have been awake previously
            printf ("Awake from Standby mode after %d second(s).\n", 
                    (int) (time(NULL) - timeNow));
            printf ("Backup RAM contains \"%.*s\".\n\n", sizeof(BACKUP_SRAM_STRING),
                     backupSram);
        } else {
            printf("\n\nStarting up from a cold start.\n");
            printf("IMPORTANT: this code puts the STM32F4xx chip into its lowest power state.\n");
            printf("The ability to do this is affected by the state of the debug chip on the C030\n");
            printf("board. To be sure that this code executes correctly, you must completely power\n");
            printf("off the board after downloading code, and power it back on again.\n\n");
        }

        printf ("Waiting up to %d second(s) for GNSS to receive the time...\n", GNSS_WAIT_TIME_SECONDS);
        for (uint32_t x = 0; (x < GNSS_WAIT_TIME_SECONDS) && !gotTime; x+= STOP_TIME_SECONDS) {
            gotTime = gnssGetTime(&gnss);

            if (!gotTime) {
                printf ("  Entering Stop mode for %d second(s) while waiting...\n", STOP_TIME_SECONDS);
                // Let the printf leave the building
                wait_ms(100);
                time_t y = time(NULL);
                lowPower.enterStop(STOP_TIME_SECONDS * 1000);
                printf ("  Awake from Stop mode after %d second(s).\n", (int) (time(NULL) - y));
            }
        }

        ledGreen = 1;
        ledRed = 1;
        ledBlue = 1;
        if (!gotTime) {
            ledRed = 0;
        }
        
        printf ("\nPutting \"%s\" into BKPSRAM...\n", BACKUP_SRAM_STRING);
        memcpy (backupSram, BACKUP_SRAM_STRING, sizeof(BACKUP_SRAM_STRING));

        printf ("Entering Standby mode, losing all RAM contents, for %d second(s)...\n\n", STANDBY_TIME_SECONDS);
        // Let the printf leave the building
        wait_ms(100);
        // We will return at the start of main() when the Standby time expires
        timeNow = time(NULL);
        lowPower.enterStandby(STANDBY_TIME_SECONDS * 1000);
    } else {
        printf("Unable to initialise GNSS.\n");
    }
    
    ledRed = 0;
    ledGreen = 1;
    ledBlue = 1;
    printf("Should never get here.\n");
    MBED_ASSERT(false);
}

// End Of File