This class provides an API to assist with low power behaviour on an STM32F437 micro, as used on the u-blox C030 board. If you need to operate from battery for any significant period, or are mains powered and don't want to take the planet down with you, you should design your code with this in mind. This library uses the https://developer.mbed.org/users/Sissors/code/WakeUp/ library and so could be extended to support all of the MCUs that library supports.

Dependencies:   WakeUp

Dependents:   example-low-power-sleep aconnoCellularGnss

Committer:
RobMeades
Date:
Mon Jun 05 14:28:14 2017 +0000
Revision:
4:691e6b38fc54
Parent:
1:4f2c412dc013
Update readme.txt.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rob.meades@u-blox.com 1:4f2c412dc013 1 #include "mbed.h"
rob.meades@u-blox.com 1:4f2c412dc013 2 #include "greentea-client/test_env.h"
rob.meades@u-blox.com 1:4f2c412dc013 3 #include "unity.h"
rob.meades@u-blox.com 1:4f2c412dc013 4 #include "utest.h"
rob.meades@u-blox.com 1:4f2c412dc013 5 #include "low_power.h"
rob.meades@u-blox.com 1:4f2c412dc013 6
rob.meades@u-blox.com 1:4f2c412dc013 7 using namespace utest::v1;
rob.meades@u-blox.com 1:4f2c412dc013 8
rob.meades@u-blox.com 1:4f2c412dc013 9 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 10 // COMPILE-TIME MACROS
rob.meades@u-blox.com 1:4f2c412dc013 11 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 12
rob.meades@u-blox.com 1:4f2c412dc013 13 #ifndef NUM_RAND_ITERATIONS
rob.meades@u-blox.com 1:4f2c412dc013 14 // The number of iterations of random input values in various tests
rob.meades@u-blox.com 1:4f2c412dc013 15 #define NUM_RAND_ITERATIONS 1000
rob.meades@u-blox.com 1:4f2c412dc013 16 #endif
rob.meades@u-blox.com 1:4f2c412dc013 17
rob.meades@u-blox.com 1:4f2c412dc013 18 // The duration to sleep for during a test
rob.meades@u-blox.com 1:4f2c412dc013 19 #define SLEEP_DURATION_SECONDS 3
rob.meades@u-blox.com 1:4f2c412dc013 20
rob.meades@u-blox.com 1:4f2c412dc013 21 // Ticker period, should be set such that it will occur
rob.meades@u-blox.com 1:4f2c412dc013 22 // within SLEEP_DURATION_SECONDS
rob.meades@u-blox.com 1:4f2c412dc013 23 #define TICKER_PERIOD_US 1000000
rob.meades@u-blox.com 1:4f2c412dc013 24
rob.meades@u-blox.com 1:4f2c412dc013 25 // The number of Standby mode iterations to run
rob.meades@u-blox.com 1:4f2c412dc013 26 #define NUM_STANDBY_ITERATIONS 2
rob.meades@u-blox.com 1:4f2c412dc013 27
rob.meades@u-blox.com 1:4f2c412dc013 28 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 29 // PRIVATE VARIABLES
rob.meades@u-blox.com 1:4f2c412dc013 30 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 31
rob.meades@u-blox.com 1:4f2c412dc013 32 // An instance of low power
rob.meades@u-blox.com 1:4f2c412dc013 33 static LowPower *gpLowPower = new LowPower();
rob.meades@u-blox.com 1:4f2c412dc013 34
rob.meades@u-blox.com 1:4f2c412dc013 35 // A ticker
rob.meades@u-blox.com 1:4f2c412dc013 36 static Ticker gTicker;
rob.meades@u-blox.com 1:4f2c412dc013 37
rob.meades@u-blox.com 1:4f2c412dc013 38 // A count of ticks
rob.meades@u-blox.com 1:4f2c412dc013 39 static uint32_t gTickCount = 0;
rob.meades@u-blox.com 1:4f2c412dc013 40
rob.meades@u-blox.com 1:4f2c412dc013 41 // The time stored in Backup SRAM
rob.meades@u-blox.com 1:4f2c412dc013 42 // This has to be the first item in Backup SRAM as we check
rob.meades@u-blox.com 1:4f2c412dc013 43 // its location below
rob.meades@u-blox.com 1:4f2c412dc013 44 BACKUP_SRAM
rob.meades@u-blox.com 1:4f2c412dc013 45 static time_t gStandbyTime;
rob.meades@u-blox.com 1:4f2c412dc013 46
rob.meades@u-blox.com 1:4f2c412dc013 47 // The number of iterations of the Standby time test
rob.meades@u-blox.com 1:4f2c412dc013 48 BACKUP_SRAM
rob.meades@u-blox.com 1:4f2c412dc013 49 static uint32_t gNumStandby;
rob.meades@u-blox.com 1:4f2c412dc013 50
rob.meades@u-blox.com 1:4f2c412dc013 51 // An item to take up the rest of Backup SRAM
rob.meades@u-blox.com 1:4f2c412dc013 52 BACKUP_SRAM
rob.meades@u-blox.com 1:4f2c412dc013 53 static char gBackupSram[4096 - sizeof (gStandbyTime) - sizeof (gNumStandby)];
rob.meades@u-blox.com 1:4f2c412dc013 54
rob.meades@u-blox.com 1:4f2c412dc013 55 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 56 // PRIVATE FUNCTIONS
rob.meades@u-blox.com 1:4f2c412dc013 57 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 58
rob.meades@u-blox.com 1:4f2c412dc013 59 // A ticker function that increments gTickCount
rob.meades@u-blox.com 1:4f2c412dc013 60 static void incTickCount(void)
rob.meades@u-blox.com 1:4f2c412dc013 61 {
rob.meades@u-blox.com 1:4f2c412dc013 62 gTickCount++;
rob.meades@u-blox.com 1:4f2c412dc013 63 }
rob.meades@u-blox.com 1:4f2c412dc013 64
rob.meades@u-blox.com 1:4f2c412dc013 65 // Check if the ticker has gone off
rob.meades@u-blox.com 1:4f2c412dc013 66 static bool tickerExpired(void)
rob.meades@u-blox.com 1:4f2c412dc013 67 {
rob.meades@u-blox.com 1:4f2c412dc013 68 return gTickCount > 0;
rob.meades@u-blox.com 1:4f2c412dc013 69 }
rob.meades@u-blox.com 1:4f2c412dc013 70
rob.meades@u-blox.com 1:4f2c412dc013 71 // Set off the ticker and timer
rob.meades@u-blox.com 1:4f2c412dc013 72 static void startTicker (void)
rob.meades@u-blox.com 1:4f2c412dc013 73 {
rob.meades@u-blox.com 1:4f2c412dc013 74 // Reset the counter
rob.meades@u-blox.com 1:4f2c412dc013 75 gTickCount = 0;
rob.meades@u-blox.com 1:4f2c412dc013 76
rob.meades@u-blox.com 1:4f2c412dc013 77 // Start the ticker
rob.meades@u-blox.com 1:4f2c412dc013 78 gTicker.attach_us (&incTickCount, TICKER_PERIOD_US);
rob.meades@u-blox.com 1:4f2c412dc013 79
rob.meades@u-blox.com 1:4f2c412dc013 80 // Make sure that it is running
rob.meades@u-blox.com 1:4f2c412dc013 81 wait_ms ((TICKER_PERIOD_US / 1000) + 1);
rob.meades@u-blox.com 1:4f2c412dc013 82 TEST_ASSERT_EQUAL_UINT32(1, gTickCount);
rob.meades@u-blox.com 1:4f2c412dc013 83
rob.meades@u-blox.com 1:4f2c412dc013 84 // Reset the counter again
rob.meades@u-blox.com 1:4f2c412dc013 85 gTickCount = 0;
rob.meades@u-blox.com 1:4f2c412dc013 86 }
rob.meades@u-blox.com 1:4f2c412dc013 87
rob.meades@u-blox.com 1:4f2c412dc013 88 // Stop the ticker
rob.meades@u-blox.com 1:4f2c412dc013 89 static void stopTicker (void)
rob.meades@u-blox.com 1:4f2c412dc013 90 {
rob.meades@u-blox.com 1:4f2c412dc013 91 // Stop the ticker
rob.meades@u-blox.com 1:4f2c412dc013 92 gTicker.detach();
rob.meades@u-blox.com 1:4f2c412dc013 93
rob.meades@u-blox.com 1:4f2c412dc013 94 // Reset counters
rob.meades@u-blox.com 1:4f2c412dc013 95 gTickCount = 0;
rob.meades@u-blox.com 1:4f2c412dc013 96
rob.meades@u-blox.com 1:4f2c412dc013 97 // Make sure that it has really stopped
rob.meades@u-blox.com 1:4f2c412dc013 98 wait_ms ((TICKER_PERIOD_US / 1000) + 1);
rob.meades@u-blox.com 1:4f2c412dc013 99 TEST_ASSERT_EQUAL_UINT32(0, gTickCount);
rob.meades@u-blox.com 1:4f2c412dc013 100 }
rob.meades@u-blox.com 1:4f2c412dc013 101
rob.meades@u-blox.com 1:4f2c412dc013 102 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 103 // TESTS
rob.meades@u-blox.com 1:4f2c412dc013 104 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 105
rob.meades@u-blox.com 1:4f2c412dc013 106 // Test Stop mode
rob.meades@u-blox.com 1:4f2c412dc013 107 void test_stop_mode() {
rob.meades@u-blox.com 1:4f2c412dc013 108 time_t startTime;
rob.meades@u-blox.com 1:4f2c412dc013 109
rob.meades@u-blox.com 1:4f2c412dc013 110 // Test a short stop
rob.meades@u-blox.com 1:4f2c412dc013 111 startTime = time(NULL);
rob.meades@u-blox.com 1:4f2c412dc013 112 startTicker();
rob.meades@u-blox.com 1:4f2c412dc013 113
rob.meades@u-blox.com 1:4f2c412dc013 114 gpLowPower->enterStop(SLEEP_DURATION_SECONDS * 1000);
rob.meades@u-blox.com 1:4f2c412dc013 115 TEST_ASSERT_FALSE(tickerExpired());
rob.meades@u-blox.com 1:4f2c412dc013 116 TEST_ASSERT(time(NULL) - startTime >= SLEEP_DURATION_SECONDS - 1); // -1 for tolerance
rob.meades@u-blox.com 1:4f2c412dc013 117 stopTicker();
rob.meades@u-blox.com 1:4f2c412dc013 118
rob.meades@u-blox.com 1:4f2c412dc013 119 // Do it again
rob.meades@u-blox.com 1:4f2c412dc013 120 startTime = time(NULL);
rob.meades@u-blox.com 1:4f2c412dc013 121 startTicker();
rob.meades@u-blox.com 1:4f2c412dc013 122 gpLowPower->enterStop(SLEEP_DURATION_SECONDS * 1000);
rob.meades@u-blox.com 1:4f2c412dc013 123 TEST_ASSERT_FALSE(tickerExpired());
rob.meades@u-blox.com 1:4f2c412dc013 124 TEST_ASSERT(time(NULL) - startTime >= SLEEP_DURATION_SECONDS - 1); // -1 for tolerance
rob.meades@u-blox.com 1:4f2c412dc013 125 stopTicker();
rob.meades@u-blox.com 1:4f2c412dc013 126 }
rob.meades@u-blox.com 1:4f2c412dc013 127
rob.meades@u-blox.com 1:4f2c412dc013 128 // Test the number of user interrupts that have been enabled
rob.meades@u-blox.com 1:4f2c412dc013 129 void test_interrupts_enabled() {
rob.meades@u-blox.com 1:4f2c412dc013 130 int32_t userInterruptsEnabled;
rob.meades@u-blox.com 1:4f2c412dc013 131 uint8_t list[NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET];
rob.meades@u-blox.com 1:4f2c412dc013 132
rob.meades@u-blox.com 1:4f2c412dc013 133 // Fill with a known value
rob.meades@u-blox.com 1:4f2c412dc013 134 memset(&(list[0]), 0xff, sizeof (list));
rob.meades@u-blox.com 1:4f2c412dc013 135
rob.meades@u-blox.com 1:4f2c412dc013 136 // Check that we can just get the number back without any parameters
rob.meades@u-blox.com 1:4f2c412dc013 137 userInterruptsEnabled = gpLowPower->numUserInterruptsEnabled();
rob.meades@u-blox.com 1:4f2c412dc013 138
rob.meades@u-blox.com 1:4f2c412dc013 139 #ifdef TARGET_STM
rob.meades@u-blox.com 1:4f2c412dc013 140 TEST_ASSERT_EQUAL_INT32(2, userInterruptsEnabled);
rob.meades@u-blox.com 1:4f2c412dc013 141 #endif
rob.meades@u-blox.com 1:4f2c412dc013 142
rob.meades@u-blox.com 1:4f2c412dc013 143 // Now ask for a list, but only with one entry
rob.meades@u-blox.com 1:4f2c412dc013 144 userInterruptsEnabled = gpLowPower->numUserInterruptsEnabled(&(list[0]), 1);
rob.meades@u-blox.com 1:4f2c412dc013 145 // Check that the second entry is untouched
rob.meades@u-blox.com 1:4f2c412dc013 146 TEST_ASSERT_EQUAL_UINT8(0xff, list[1]);
rob.meades@u-blox.com 1:4f2c412dc013 147 #ifdef TARGET_STM
rob.meades@u-blox.com 1:4f2c412dc013 148 // Check that two interrupts are enabled
rob.meades@u-blox.com 1:4f2c412dc013 149 TEST_ASSERT_EQUAL_INT32(2, userInterruptsEnabled);
rob.meades@u-blox.com 1:4f2c412dc013 150 // Check that the first entry is the RTC Alarm interrupt (used by enableStop())
rob.meades@u-blox.com 1:4f2c412dc013 151 TEST_ASSERT_EQUAL_UINT8(RTC_Alarm_IRQn, list[0]);
rob.meades@u-blox.com 1:4f2c412dc013 152 #endif
rob.meades@u-blox.com 1:4f2c412dc013 153
rob.meades@u-blox.com 1:4f2c412dc013 154 // Now ask for the full list
rob.meades@u-blox.com 1:4f2c412dc013 155 userInterruptsEnabled = gpLowPower->numUserInterruptsEnabled(&(list[0]), sizeof (list));
rob.meades@u-blox.com 1:4f2c412dc013 156 #ifdef TARGET_STM
rob.meades@u-blox.com 1:4f2c412dc013 157 // Check that two interrupts are enabled
rob.meades@u-blox.com 1:4f2c412dc013 158 TEST_ASSERT_EQUAL_INT32(2, userInterruptsEnabled);
rob.meades@u-blox.com 1:4f2c412dc013 159 // Check that the third entry is untouched
rob.meades@u-blox.com 1:4f2c412dc013 160 TEST_ASSERT_EQUAL_UINT8(0xff, list[2]);
rob.meades@u-blox.com 1:4f2c412dc013 161 // Check that the first entry is the RTC Alarm interrupt
rob.meades@u-blox.com 1:4f2c412dc013 162 TEST_ASSERT_EQUAL_UINT8(RTC_Alarm_IRQn, list[0]);
rob.meades@u-blox.com 1:4f2c412dc013 163 // Check that the second entry is the TIM5 interrupt (used for RTOS tick)
rob.meades@u-blox.com 1:4f2c412dc013 164 TEST_ASSERT_EQUAL_UINT8(TIM5_IRQn, list[1]);
rob.meades@u-blox.com 1:4f2c412dc013 165 #endif
rob.meades@u-blox.com 1:4f2c412dc013 166 }
rob.meades@u-blox.com 1:4f2c412dc013 167
rob.meades@u-blox.com 1:4f2c412dc013 168 // Test Standby mode
rob.meades@u-blox.com 1:4f2c412dc013 169 void test_standby_mode() {
rob.meades@u-blox.com 1:4f2c412dc013 170 #ifdef TARGET_STM
rob.meades@u-blox.com 1:4f2c412dc013 171 // Check that the Backup SRAM array has been placed correctly
rob.meades@u-blox.com 1:4f2c412dc013 172 TEST_ASSERT_EQUAL_UINT32 (0x40024000, &gStandbyTime);
rob.meades@u-blox.com 1:4f2c412dc013 173 #endif
rob.meades@u-blox.com 1:4f2c412dc013 174
rob.meades@u-blox.com 1:4f2c412dc013 175 // Fill backup SRAM with 0x42
rob.meades@u-blox.com 1:4f2c412dc013 176 memset (&(gBackupSram[0]), 0x42, sizeof (gBackupSram));
rob.meades@u-blox.com 1:4f2c412dc013 177
rob.meades@u-blox.com 1:4f2c412dc013 178 // Test that we succeeded in doing so
rob.meades@u-blox.com 1:4f2c412dc013 179 for (uint32_t x = 0; x < sizeof (gBackupSram); x++) {
rob.meades@u-blox.com 1:4f2c412dc013 180 TEST_ASSERT_EQUAL_INT8(0x42, gBackupSram[x]);
rob.meades@u-blox.com 1:4f2c412dc013 181 }
rob.meades@u-blox.com 1:4f2c412dc013 182
rob.meades@u-blox.com 1:4f2c412dc013 183 startTicker();
rob.meades@u-blox.com 1:4f2c412dc013 184
rob.meades@u-blox.com 1:4f2c412dc013 185 // Store the current time and the number of iterations in Backup SRAM also
rob.meades@u-blox.com 1:4f2c412dc013 186 gNumStandby = 0;
rob.meades@u-blox.com 1:4f2c412dc013 187 gStandbyTime = time(NULL);
rob.meades@u-blox.com 1:4f2c412dc013 188
rob.meades@u-blox.com 1:4f2c412dc013 189 // Go into Standby mode
rob.meades@u-blox.com 1:4f2c412dc013 190 gpLowPower->enterStandby(SLEEP_DURATION_SECONDS * 1000);
rob.meades@u-blox.com 1:4f2c412dc013 191
rob.meades@u-blox.com 1:4f2c412dc013 192 // At the end of Standby mode the processor will reset and we will
rob.meades@u-blox.com 1:4f2c412dc013 193 // come back again at main(). There we can check if (a) Backup SRAM
rob.meades@u-blox.com 1:4f2c412dc013 194 // is still as we left it and (b) the right amount of time has expired
rob.meades@u-blox.com 1:4f2c412dc013 195
rob.meades@u-blox.com 1:4f2c412dc013 196 // We should never get here
rob.meades@u-blox.com 1:4f2c412dc013 197 TEST_ASSERT(false);
rob.meades@u-blox.com 1:4f2c412dc013 198 }
rob.meades@u-blox.com 1:4f2c412dc013 199
rob.meades@u-blox.com 1:4f2c412dc013 200 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 201 // TEST ENVIRONMENT
rob.meades@u-blox.com 1:4f2c412dc013 202 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 203
rob.meades@u-blox.com 1:4f2c412dc013 204 // Setup the test environment
rob.meades@u-blox.com 1:4f2c412dc013 205 utest::v1::status_t test_setup(const size_t number_of_cases) {
rob.meades@u-blox.com 1:4f2c412dc013 206 // Setup Greentea with a timeout
rob.meades@u-blox.com 1:4f2c412dc013 207 GREENTEA_SETUP(120, "default_auto");
rob.meades@u-blox.com 1:4f2c412dc013 208 return verbose_test_setup_handler(number_of_cases);
rob.meades@u-blox.com 1:4f2c412dc013 209 }
rob.meades@u-blox.com 1:4f2c412dc013 210
rob.meades@u-blox.com 1:4f2c412dc013 211 // Test cases
rob.meades@u-blox.com 1:4f2c412dc013 212 // NOTE: the ability to enter low power states can be influenced by the debug chip
rob.meades@u-blox.com 1:4f2c412dc013 213 // on the mbed board. It may not be possible to run these tests simply
rob.meades@u-blox.com 1:4f2c412dc013 214 // with mbed test as usual as the process of downloading to the board causes the
rob.meades@u-blox.com 1:4f2c412dc013 215 // debug chip to put the target MCU into the wrong state. A way around this is
rob.meades@u-blox.com 1:4f2c412dc013 216 // to download the build, power off the board entirely, power it up again and
rob.meades@u-blox.com 1:4f2c412dc013 217 // then run the tests without the download step, using:
rob.meades@u-blox.com 1:4f2c412dc013 218 //
rob.meades@u-blox.com 1:4f2c412dc013 219 // mbedhtrun --skip-flashing -p COMx:9600
rob.meades@u-blox.com 1:4f2c412dc013 220 // where x is replaced by the COM port where the board is attached.
rob.meades@u-blox.com 1:4f2c412dc013 221 Case cases[] = {
rob.meades@u-blox.com 1:4f2c412dc013 222 Case("Stop mode", test_stop_mode),
rob.meades@u-blox.com 1:4f2c412dc013 223 // This must be run second as test_stop_mode is expected to enable some interrupts
rob.meades@u-blox.com 1:4f2c412dc013 224 Case("Num user interrupts enabled", test_interrupts_enabled),
rob.meades@u-blox.com 1:4f2c412dc013 225 #ifdef TARGET_STM
rob.meades@u-blox.com 1:4f2c412dc013 226 // Standby mode doesn't work while debugging, it's just the way the HW is
rob.meades@u-blox.com 1:4f2c412dc013 227 # ifdef DEBUG
rob.meades@u-blox.com 1:4f2c412dc013 228 # error If you want to run the test suite in debug mode, comment out this line.
rob.meades@u-blox.com 1:4f2c412dc013 229 # else
rob.meades@u-blox.com 1:4f2c412dc013 230 // Standby mode is only implemented for ST micro cores
rob.meades@u-blox.com 1:4f2c412dc013 231 // This must be the last test as it resets us back to main()
rob.meades@u-blox.com 1:4f2c412dc013 232 Case("Standby mode", test_standby_mode)
rob.meades@u-blox.com 1:4f2c412dc013 233 # endif
rob.meades@u-blox.com 1:4f2c412dc013 234 #endif
rob.meades@u-blox.com 1:4f2c412dc013 235 };
rob.meades@u-blox.com 1:4f2c412dc013 236
rob.meades@u-blox.com 1:4f2c412dc013 237 Specification specification(test_setup, cases);
rob.meades@u-blox.com 1:4f2c412dc013 238
rob.meades@u-blox.com 1:4f2c412dc013 239 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 240 // MAIN
rob.meades@u-blox.com 1:4f2c412dc013 241 // ----------------------------------------------------------------
rob.meades@u-blox.com 1:4f2c412dc013 242
rob.meades@u-blox.com 1:4f2c412dc013 243 int main() {
rob.meades@u-blox.com 1:4f2c412dc013 244 bool success = true;
rob.meades@u-blox.com 1:4f2c412dc013 245
rob.meades@u-blox.com 1:4f2c412dc013 246 #ifndef DEBUG
rob.meades@u-blox.com 1:4f2c412dc013 247 gpLowPower->exitDebugMode();
rob.meades@u-blox.com 1:4f2c412dc013 248 #endif
rob.meades@u-blox.com 1:4f2c412dc013 249
rob.meades@u-blox.com 1:4f2c412dc013 250 // If the RTC is running then we must have been
rob.meades@u-blox.com 1:4f2c412dc013 251 // in the Standby mode test and have just come back
rob.meades@u-blox.com 1:4f2c412dc013 252 // from reset, so check that Backup SRAM has the
rob.meades@u-blox.com 1:4f2c412dc013 253 // expected contents and that we've slept for the
rob.meades@u-blox.com 1:4f2c412dc013 254 // expected period
rob.meades@u-blox.com 1:4f2c412dc013 255 if (time(NULL) > 0) {
rob.meades@u-blox.com 1:4f2c412dc013 256 // Check that we are at least SLEEP_DURATION_SECONDS past the time
rob.meades@u-blox.com 1:4f2c412dc013 257 // we entered Standby mode, which is stored in Backup SRAM
rob.meades@u-blox.com 1:4f2c412dc013 258 printf ("Time: %d, recorded time %d.\n", (int) time(NULL), (int) gStandbyTime);
rob.meades@u-blox.com 1:4f2c412dc013 259 if (time(NULL) - gStandbyTime < SLEEP_DURATION_SECONDS - 1) { // -1 for tolerance
rob.meades@u-blox.com 1:4f2c412dc013 260 success = false;
rob.meades@u-blox.com 1:4f2c412dc013 261 TEST_ASSERT(false);
rob.meades@u-blox.com 1:4f2c412dc013 262 }
rob.meades@u-blox.com 1:4f2c412dc013 263
rob.meades@u-blox.com 1:4f2c412dc013 264 // The rest should be the fill value
rob.meades@u-blox.com 1:4f2c412dc013 265 for (uint32_t x = 0; (x < sizeof (gBackupSram)) && success; x++) {
rob.meades@u-blox.com 1:4f2c412dc013 266 if (gBackupSram[x] != 0x42) {
rob.meades@u-blox.com 1:4f2c412dc013 267 success = false;
rob.meades@u-blox.com 1:4f2c412dc013 268 }
rob.meades@u-blox.com 1:4f2c412dc013 269 }
rob.meades@u-blox.com 1:4f2c412dc013 270
rob.meades@u-blox.com 1:4f2c412dc013 271 TEST_ASSERT(success);
rob.meades@u-blox.com 1:4f2c412dc013 272
rob.meades@u-blox.com 1:4f2c412dc013 273 gNumStandby++;
rob.meades@u-blox.com 1:4f2c412dc013 274 if (success && (gNumStandby < NUM_STANDBY_ITERATIONS)) {
rob.meades@u-blox.com 1:4f2c412dc013 275 // Let printf leave the building
rob.meades@u-blox.com 1:4f2c412dc013 276 wait_ms(100);
rob.meades@u-blox.com 1:4f2c412dc013 277 // Go into Standby mode again
rob.meades@u-blox.com 1:4f2c412dc013 278 gStandbyTime = time(NULL);
rob.meades@u-blox.com 1:4f2c412dc013 279 gpLowPower->enterStandby(SLEEP_DURATION_SECONDS * 1000);
rob.meades@u-blox.com 1:4f2c412dc013 280 // Again, we will come back from reset so should never get here
rob.meades@u-blox.com 1:4f2c412dc013 281 TEST_ASSERT(false);
rob.meades@u-blox.com 1:4f2c412dc013 282 } else {
rob.meades@u-blox.com 1:4f2c412dc013 283 // Now we have to implement the end of the suite of tests manually
rob.meades@u-blox.com 1:4f2c412dc013 284 printf ("{{__testcase_finish;Standby mode;%01d;%01d}}\n", success, !success);
rob.meades@u-blox.com 1:4f2c412dc013 285 printf ("{{__testcase_summary;3;%01d}}\n", !success);
rob.meades@u-blox.com 1:4f2c412dc013 286 if (success) {
rob.meades@u-blox.com 1:4f2c412dc013 287 printf("{{end;success}}\n");
rob.meades@u-blox.com 1:4f2c412dc013 288 } else {
rob.meades@u-blox.com 1:4f2c412dc013 289 printf("{{end;failure}}\n");
rob.meades@u-blox.com 1:4f2c412dc013 290 }
rob.meades@u-blox.com 1:4f2c412dc013 291 printf ("{{__exit;%01d}}\n", !success);
rob.meades@u-blox.com 1:4f2c412dc013 292 }
rob.meades@u-blox.com 1:4f2c412dc013 293 } else {
rob.meades@u-blox.com 1:4f2c412dc013 294 // Otherwise, we can just run the test suite
rob.meades@u-blox.com 1:4f2c412dc013 295 success = !Harness::run(specification);
rob.meades@u-blox.com 1:4f2c412dc013 296 }
rob.meades@u-blox.com 1:4f2c412dc013 297
rob.meades@u-blox.com 1:4f2c412dc013 298 return success;
rob.meades@u-blox.com 1:4f2c412dc013 299 }
rob.meades@u-blox.com 1:4f2c412dc013 300
rob.meades@u-blox.com 1:4f2c412dc013 301 // End Of File