takashi kadono
/
Nucleo446_SSD1331
Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466
mbed-os/TESTS/mbed_hal/sleep/main.cpp@3:f3764f852aa8, 2018-10-11 (annotated)
- Committer:
- kadonotakashi
- Date:
- Thu Oct 11 02:27:46 2018 +0000
- Revision:
- 3:f3764f852aa8
- Parent:
- 0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kadonotakashi | 0:8fdf9a60065b | 1 | /* mbed Microcontroller Library |
kadonotakashi | 0:8fdf9a60065b | 2 | * Copyright (c) 2017 ARM Limited |
kadonotakashi | 0:8fdf9a60065b | 3 | * |
kadonotakashi | 0:8fdf9a60065b | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
kadonotakashi | 0:8fdf9a60065b | 5 | * you may not use this file except in compliance with the License. |
kadonotakashi | 0:8fdf9a60065b | 6 | * You may obtain a copy of the License at |
kadonotakashi | 0:8fdf9a60065b | 7 | * |
kadonotakashi | 0:8fdf9a60065b | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
kadonotakashi | 0:8fdf9a60065b | 9 | * |
kadonotakashi | 0:8fdf9a60065b | 10 | * Unless required by applicable law or agreed to in writing, software |
kadonotakashi | 0:8fdf9a60065b | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
kadonotakashi | 0:8fdf9a60065b | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
kadonotakashi | 0:8fdf9a60065b | 13 | * See the License for the specific language governing permissions and |
kadonotakashi | 0:8fdf9a60065b | 14 | * limitations under the License. |
kadonotakashi | 0:8fdf9a60065b | 15 | */ |
kadonotakashi | 0:8fdf9a60065b | 16 | |
kadonotakashi | 0:8fdf9a60065b | 17 | #if !DEVICE_SLEEP |
kadonotakashi | 0:8fdf9a60065b | 18 | #error [NOT_SUPPORTED] sleep not supported for this target |
kadonotakashi | 0:8fdf9a60065b | 19 | #endif |
kadonotakashi | 0:8fdf9a60065b | 20 | |
kadonotakashi | 0:8fdf9a60065b | 21 | #include "mbed.h" |
kadonotakashi | 0:8fdf9a60065b | 22 | |
kadonotakashi | 0:8fdf9a60065b | 23 | #include "utest/utest.h" |
kadonotakashi | 0:8fdf9a60065b | 24 | #include "unity/unity.h" |
kadonotakashi | 0:8fdf9a60065b | 25 | #include "greentea-client/test_env.h" |
kadonotakashi | 0:8fdf9a60065b | 26 | #include "mbed_lp_ticker_wrapper.h" |
kadonotakashi | 0:8fdf9a60065b | 27 | |
kadonotakashi | 0:8fdf9a60065b | 28 | #include "sleep_api_tests.h" |
kadonotakashi | 0:8fdf9a60065b | 29 | |
kadonotakashi | 0:8fdf9a60065b | 30 | #define US_PER_S 1000000 |
kadonotakashi | 0:8fdf9a60065b | 31 | |
kadonotakashi | 0:8fdf9a60065b | 32 | /* Flush serial buffer before deep sleep |
kadonotakashi | 0:8fdf9a60065b | 33 | * |
kadonotakashi | 0:8fdf9a60065b | 34 | * Since deepsleep() may shut down the UART peripheral, we wait for some time |
kadonotakashi | 0:8fdf9a60065b | 35 | * to allow for hardware serial buffers to completely flush. |
kadonotakashi | 0:8fdf9a60065b | 36 | * |
kadonotakashi | 0:8fdf9a60065b | 37 | * Take NUMAKER_PFM_NUC472 as an example: |
kadonotakashi | 0:8fdf9a60065b | 38 | * Its UART peripheral has 16-byte Tx FIFO. With baud rate set to 9600, flush |
kadonotakashi | 0:8fdf9a60065b | 39 | * Tx FIFO would take: 16 * 8 * 1000 / 9600 = 13.3 (ms). So set wait time to |
kadonotakashi | 0:8fdf9a60065b | 40 | * 20ms here for safe. |
kadonotakashi | 0:8fdf9a60065b | 41 | * |
kadonotakashi | 0:8fdf9a60065b | 42 | * This should be replaced with a better function that checks if the |
kadonotakashi | 0:8fdf9a60065b | 43 | * hardware buffers are empty. However, such an API does not exist now, |
kadonotakashi | 0:8fdf9a60065b | 44 | * so we'll use the busy_wait_ms() function for now. |
kadonotakashi | 0:8fdf9a60065b | 45 | */ |
kadonotakashi | 0:8fdf9a60065b | 46 | #define SERIAL_FLUSH_TIME_MS 20 |
kadonotakashi | 0:8fdf9a60065b | 47 | |
kadonotakashi | 0:8fdf9a60065b | 48 | using namespace utest::v1; |
kadonotakashi | 0:8fdf9a60065b | 49 | |
kadonotakashi | 0:8fdf9a60065b | 50 | static char info[512] = {0}; |
kadonotakashi | 0:8fdf9a60065b | 51 | |
kadonotakashi | 0:8fdf9a60065b | 52 | /* The following ticker frequencies are possible: |
kadonotakashi | 0:8fdf9a60065b | 53 | * high frequency ticker: 250 KHz (1 tick per 4 us) - 8 Mhz (1 tick per 1/8 us) |
kadonotakashi | 0:8fdf9a60065b | 54 | * low power ticker: 8 KHz (1 tick per 125 us) - 64 KHz (1 tick per ~15.6 us) |
kadonotakashi | 0:8fdf9a60065b | 55 | */ |
kadonotakashi | 0:8fdf9a60065b | 56 | |
kadonotakashi | 0:8fdf9a60065b | 57 | /* Used for regular sleep mode, a target should be awake within 10 us. Define us delta value as follows: |
kadonotakashi | 0:8fdf9a60065b | 58 | * delta = default 10 us + worst ticker resolution + extra time for code execution */ |
kadonotakashi | 0:8fdf9a60065b | 59 | #if defined(MBED_CPU_STATS_ENABLED) |
kadonotakashi | 0:8fdf9a60065b | 60 | /* extra 25us for stats computation (for more details see MBED_CPU_STATS_ENABLED) */ |
kadonotakashi | 0:8fdf9a60065b | 61 | static const uint32_t sleep_mode_delta_us = (10 + 4 + 5 + 25); |
kadonotakashi | 0:8fdf9a60065b | 62 | #else |
kadonotakashi | 0:8fdf9a60065b | 63 | static const uint32_t sleep_mode_delta_us = (10 + 4 + 5); |
kadonotakashi | 0:8fdf9a60065b | 64 | #endif |
kadonotakashi | 0:8fdf9a60065b | 65 | |
kadonotakashi | 0:8fdf9a60065b | 66 | /* Used for deep-sleep mode, a target should be awake within 10 ms. Define us delta value as follows: |
kadonotakashi | 0:8fdf9a60065b | 67 | * delta = default 10 ms + worst ticker resolution + extra time for code execution */ |
kadonotakashi | 0:8fdf9a60065b | 68 | static const uint32_t deepsleep_mode_delta_us = (10000 + 125 + 5); |
kadonotakashi | 0:8fdf9a60065b | 69 | |
kadonotakashi | 0:8fdf9a60065b | 70 | unsigned int ticks_to_us(unsigned int ticks, unsigned int freq) |
kadonotakashi | 0:8fdf9a60065b | 71 | { |
kadonotakashi | 0:8fdf9a60065b | 72 | return (unsigned int)((unsigned long long) ticks * US_PER_S / freq); |
kadonotakashi | 0:8fdf9a60065b | 73 | } |
kadonotakashi | 0:8fdf9a60065b | 74 | |
kadonotakashi | 0:8fdf9a60065b | 75 | unsigned int us_to_ticks(unsigned int us, unsigned int freq) |
kadonotakashi | 0:8fdf9a60065b | 76 | { |
kadonotakashi | 0:8fdf9a60065b | 77 | return (unsigned int)((unsigned long long) us * freq / US_PER_S); |
kadonotakashi | 0:8fdf9a60065b | 78 | } |
kadonotakashi | 0:8fdf9a60065b | 79 | |
kadonotakashi | 0:8fdf9a60065b | 80 | unsigned int overflow_protect(unsigned int timestamp, unsigned int ticker_width) |
kadonotakashi | 0:8fdf9a60065b | 81 | { |
kadonotakashi | 0:8fdf9a60065b | 82 | unsigned int counter_mask = ((1 << ticker_width) - 1); |
kadonotakashi | 0:8fdf9a60065b | 83 | |
kadonotakashi | 0:8fdf9a60065b | 84 | return (timestamp & counter_mask); |
kadonotakashi | 0:8fdf9a60065b | 85 | } |
kadonotakashi | 0:8fdf9a60065b | 86 | |
kadonotakashi | 0:8fdf9a60065b | 87 | bool compare_timestamps(unsigned int delta_ticks, unsigned int ticker_width, unsigned int expected, unsigned int actual) |
kadonotakashi | 0:8fdf9a60065b | 88 | { |
kadonotakashi | 0:8fdf9a60065b | 89 | const unsigned int counter_mask = ((1 << ticker_width) - 1); |
kadonotakashi | 0:8fdf9a60065b | 90 | |
kadonotakashi | 0:8fdf9a60065b | 91 | const unsigned int lower_bound = ((expected - delta_ticks) & counter_mask); |
kadonotakashi | 0:8fdf9a60065b | 92 | const unsigned int upper_bound = ((expected + delta_ticks) & counter_mask); |
kadonotakashi | 0:8fdf9a60065b | 93 | |
kadonotakashi | 0:8fdf9a60065b | 94 | if (lower_bound < upper_bound) { |
kadonotakashi | 0:8fdf9a60065b | 95 | if (actual >= lower_bound && actual <= upper_bound) { |
kadonotakashi | 0:8fdf9a60065b | 96 | return true; |
kadonotakashi | 0:8fdf9a60065b | 97 | } else { |
kadonotakashi | 0:8fdf9a60065b | 98 | return false; |
kadonotakashi | 0:8fdf9a60065b | 99 | } |
kadonotakashi | 0:8fdf9a60065b | 100 | } else { |
kadonotakashi | 0:8fdf9a60065b | 101 | if ((actual >= lower_bound && actual <= counter_mask) || (actual >= 0 && actual <= upper_bound)) { |
kadonotakashi | 0:8fdf9a60065b | 102 | return true; |
kadonotakashi | 0:8fdf9a60065b | 103 | } else { |
kadonotakashi | 0:8fdf9a60065b | 104 | return false; |
kadonotakashi | 0:8fdf9a60065b | 105 | } |
kadonotakashi | 0:8fdf9a60065b | 106 | } |
kadonotakashi | 0:8fdf9a60065b | 107 | } |
kadonotakashi | 0:8fdf9a60065b | 108 | |
kadonotakashi | 0:8fdf9a60065b | 109 | void busy_wait_ms(int ms) |
kadonotakashi | 0:8fdf9a60065b | 110 | { |
kadonotakashi | 0:8fdf9a60065b | 111 | const ticker_info_t *info = us_ticker_get_info(); |
kadonotakashi | 0:8fdf9a60065b | 112 | uint32_t mask = (1 << info->bits) - 1; |
kadonotakashi | 0:8fdf9a60065b | 113 | int delay = (int)((uint64_t)ms * info->frequency / 1000); |
kadonotakashi | 0:8fdf9a60065b | 114 | |
kadonotakashi | 0:8fdf9a60065b | 115 | uint32_t prev = us_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 116 | while (delay > 0) { |
kadonotakashi | 0:8fdf9a60065b | 117 | uint32_t next = us_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 118 | delay -= (next - prev) & mask; |
kadonotakashi | 0:8fdf9a60065b | 119 | prev = next; |
kadonotakashi | 0:8fdf9a60065b | 120 | } |
kadonotakashi | 0:8fdf9a60065b | 121 | } |
kadonotakashi | 0:8fdf9a60065b | 122 | |
kadonotakashi | 0:8fdf9a60065b | 123 | void us_ticker_isr(const ticker_data_t *const ticker_data) |
kadonotakashi | 0:8fdf9a60065b | 124 | { |
kadonotakashi | 0:8fdf9a60065b | 125 | us_ticker_clear_interrupt(); |
kadonotakashi | 0:8fdf9a60065b | 126 | } |
kadonotakashi | 0:8fdf9a60065b | 127 | |
kadonotakashi | 0:8fdf9a60065b | 128 | #ifdef DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 129 | void lp_ticker_isr(const ticker_data_t *const ticker_data) |
kadonotakashi | 0:8fdf9a60065b | 130 | { |
kadonotakashi | 0:8fdf9a60065b | 131 | lp_ticker_clear_interrupt(); |
kadonotakashi | 0:8fdf9a60065b | 132 | } |
kadonotakashi | 0:8fdf9a60065b | 133 | #endif |
kadonotakashi | 0:8fdf9a60065b | 134 | |
kadonotakashi | 0:8fdf9a60065b | 135 | /* Test that wake-up time from sleep should be less than 10 us and |
kadonotakashi | 0:8fdf9a60065b | 136 | * high frequency ticker interrupt can wake-up target from sleep. */ |
kadonotakashi | 0:8fdf9a60065b | 137 | void sleep_usticker_test() |
kadonotakashi | 0:8fdf9a60065b | 138 | { |
kadonotakashi | 0:8fdf9a60065b | 139 | const ticker_data_t *ticker = get_us_ticker_data(); |
kadonotakashi | 0:8fdf9a60065b | 140 | const unsigned int ticker_freq = ticker->interface->get_info()->frequency; |
kadonotakashi | 0:8fdf9a60065b | 141 | const unsigned int ticker_width = ticker->interface->get_info()->bits; |
kadonotakashi | 0:8fdf9a60065b | 142 | |
kadonotakashi | 0:8fdf9a60065b | 143 | const ticker_irq_handler_type us_ticker_irq_handler_org = set_us_ticker_irq_handler(us_ticker_isr); |
kadonotakashi | 0:8fdf9a60065b | 144 | |
kadonotakashi | 0:8fdf9a60065b | 145 | /* Give some time Green Tea to finish UART transmission before entering |
kadonotakashi | 0:8fdf9a60065b | 146 | * sleep mode. |
kadonotakashi | 0:8fdf9a60065b | 147 | */ |
kadonotakashi | 0:8fdf9a60065b | 148 | busy_wait_ms(SERIAL_FLUSH_TIME_MS); |
kadonotakashi | 0:8fdf9a60065b | 149 | |
kadonotakashi | 0:8fdf9a60065b | 150 | /* Test only sleep functionality. */ |
kadonotakashi | 0:8fdf9a60065b | 151 | sleep_manager_lock_deep_sleep(); |
kadonotakashi | 0:8fdf9a60065b | 152 | TEST_ASSERT_FALSE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should be locked"); |
kadonotakashi | 0:8fdf9a60065b | 153 | |
kadonotakashi | 0:8fdf9a60065b | 154 | /* Testing wake-up time 10 us. */ |
kadonotakashi | 0:8fdf9a60065b | 155 | for (timestamp_t i = 100; i < 1000; i += 100) { |
kadonotakashi | 0:8fdf9a60065b | 156 | /* note: us_ticker_read() operates on ticks. */ |
kadonotakashi | 0:8fdf9a60065b | 157 | const timestamp_t start_timestamp = us_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 158 | const timestamp_t next_match_timestamp = overflow_protect(start_timestamp + us_to_ticks(i, ticker_freq), |
kadonotakashi | 0:8fdf9a60065b | 159 | ticker_width); |
kadonotakashi | 0:8fdf9a60065b | 160 | |
kadonotakashi | 0:8fdf9a60065b | 161 | us_ticker_set_interrupt(next_match_timestamp); |
kadonotakashi | 0:8fdf9a60065b | 162 | |
kadonotakashi | 0:8fdf9a60065b | 163 | sleep(); |
kadonotakashi | 0:8fdf9a60065b | 164 | |
kadonotakashi | 0:8fdf9a60065b | 165 | const unsigned int wakeup_timestamp = us_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 166 | |
kadonotakashi | 0:8fdf9a60065b | 167 | sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d, delay ticks: %d, wake up after ticks: %d", |
kadonotakashi | 0:8fdf9a60065b | 168 | us_to_ticks(sleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, wakeup_timestamp, us_to_ticks(i, ticker_freq) , wakeup_timestamp - start_timestamp); |
kadonotakashi | 0:8fdf9a60065b | 169 | |
kadonotakashi | 0:8fdf9a60065b | 170 | TEST_ASSERT_MESSAGE(compare_timestamps(us_to_ticks(sleep_mode_delta_us, ticker_freq), |
kadonotakashi | 0:8fdf9a60065b | 171 | ticker_width, next_match_timestamp, wakeup_timestamp), info); |
kadonotakashi | 0:8fdf9a60065b | 172 | } |
kadonotakashi | 0:8fdf9a60065b | 173 | |
kadonotakashi | 0:8fdf9a60065b | 174 | set_us_ticker_irq_handler(us_ticker_irq_handler_org); |
kadonotakashi | 0:8fdf9a60065b | 175 | |
kadonotakashi | 0:8fdf9a60065b | 176 | sleep_manager_unlock_deep_sleep(); |
kadonotakashi | 0:8fdf9a60065b | 177 | TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); |
kadonotakashi | 0:8fdf9a60065b | 178 | } |
kadonotakashi | 0:8fdf9a60065b | 179 | |
kadonotakashi | 0:8fdf9a60065b | 180 | #ifdef DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 181 | |
kadonotakashi | 0:8fdf9a60065b | 182 | /* Test that wake-up time from sleep should be less than 10 ms and |
kadonotakashi | 0:8fdf9a60065b | 183 | * low power ticker interrupt can wake-up target from sleep. */ |
kadonotakashi | 0:8fdf9a60065b | 184 | void deepsleep_lpticker_test() |
kadonotakashi | 0:8fdf9a60065b | 185 | { |
kadonotakashi | 0:8fdf9a60065b | 186 | const ticker_data_t *ticker = get_lp_ticker_data(); |
kadonotakashi | 0:8fdf9a60065b | 187 | const unsigned int ticker_freq = ticker->interface->get_info()->frequency; |
kadonotakashi | 0:8fdf9a60065b | 188 | const unsigned int ticker_width = ticker->interface->get_info()->bits; |
kadonotakashi | 0:8fdf9a60065b | 189 | |
kadonotakashi | 0:8fdf9a60065b | 190 | const ticker_irq_handler_type lp_ticker_irq_handler_org = set_lp_ticker_irq_handler(lp_ticker_isr); |
kadonotakashi | 0:8fdf9a60065b | 191 | |
kadonotakashi | 0:8fdf9a60065b | 192 | /* Give some time Green Tea to finish UART transmission before entering |
kadonotakashi | 0:8fdf9a60065b | 193 | * deep-sleep mode. |
kadonotakashi | 0:8fdf9a60065b | 194 | */ |
kadonotakashi | 0:8fdf9a60065b | 195 | busy_wait_ms(SERIAL_FLUSH_TIME_MS); |
kadonotakashi | 0:8fdf9a60065b | 196 | |
kadonotakashi | 0:8fdf9a60065b | 197 | TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should not be locked"); |
kadonotakashi | 0:8fdf9a60065b | 198 | |
kadonotakashi | 0:8fdf9a60065b | 199 | /* Testing wake-up time 10 ms. */ |
kadonotakashi | 0:8fdf9a60065b | 200 | for (timestamp_t i = 20000; i < 200000; i += 20000) { |
kadonotakashi | 0:8fdf9a60065b | 201 | /* note: lp_ticker_read() operates on ticks. */ |
kadonotakashi | 0:8fdf9a60065b | 202 | const timestamp_t start_timestamp = lp_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 203 | const timestamp_t next_match_timestamp = overflow_protect(start_timestamp + us_to_ticks(i, ticker_freq), ticker_width); |
kadonotakashi | 0:8fdf9a60065b | 204 | |
kadonotakashi | 0:8fdf9a60065b | 205 | lp_ticker_set_interrupt(next_match_timestamp); |
kadonotakashi | 0:8fdf9a60065b | 206 | |
kadonotakashi | 0:8fdf9a60065b | 207 | sleep(); |
kadonotakashi | 0:8fdf9a60065b | 208 | |
kadonotakashi | 0:8fdf9a60065b | 209 | const timestamp_t wakeup_timestamp = lp_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 210 | |
kadonotakashi | 0:8fdf9a60065b | 211 | sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d, delay ticks: %d, wake up after ticks: %d", |
kadonotakashi | 0:8fdf9a60065b | 212 | us_to_ticks(deepsleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, wakeup_timestamp, us_to_ticks(i, ticker_freq) , wakeup_timestamp - start_timestamp); |
kadonotakashi | 0:8fdf9a60065b | 213 | |
kadonotakashi | 0:8fdf9a60065b | 214 | TEST_ASSERT_MESSAGE(compare_timestamps(us_to_ticks(deepsleep_mode_delta_us, ticker_freq), ticker_width, |
kadonotakashi | 0:8fdf9a60065b | 215 | next_match_timestamp, wakeup_timestamp), info); |
kadonotakashi | 0:8fdf9a60065b | 216 | } |
kadonotakashi | 0:8fdf9a60065b | 217 | |
kadonotakashi | 0:8fdf9a60065b | 218 | set_lp_ticker_irq_handler(lp_ticker_irq_handler_org); |
kadonotakashi | 0:8fdf9a60065b | 219 | |
kadonotakashi | 0:8fdf9a60065b | 220 | } |
kadonotakashi | 0:8fdf9a60065b | 221 | |
kadonotakashi | 0:8fdf9a60065b | 222 | void deepsleep_high_speed_clocks_turned_off_test() |
kadonotakashi | 0:8fdf9a60065b | 223 | { |
kadonotakashi | 0:8fdf9a60065b | 224 | const ticker_data_t *us_ticker = get_us_ticker_data(); |
kadonotakashi | 0:8fdf9a60065b | 225 | const ticker_data_t *lp_ticker = get_lp_ticker_data(); |
kadonotakashi | 0:8fdf9a60065b | 226 | const unsigned int us_ticker_freq = us_ticker->interface->get_info()->frequency; |
kadonotakashi | 0:8fdf9a60065b | 227 | const unsigned int lp_ticker_freq = lp_ticker->interface->get_info()->frequency; |
kadonotakashi | 0:8fdf9a60065b | 228 | const unsigned int us_ticker_width = us_ticker->interface->get_info()->bits; |
kadonotakashi | 0:8fdf9a60065b | 229 | const unsigned int lp_ticker_width = lp_ticker->interface->get_info()->bits; |
kadonotakashi | 0:8fdf9a60065b | 230 | const unsigned int us_ticker_mask = ((1 << us_ticker_width) - 1); |
kadonotakashi | 0:8fdf9a60065b | 231 | |
kadonotakashi | 0:8fdf9a60065b | 232 | /* Give some time Green Tea to finish UART transmission before entering |
kadonotakashi | 0:8fdf9a60065b | 233 | * deep-sleep mode. |
kadonotakashi | 0:8fdf9a60065b | 234 | */ |
kadonotakashi | 0:8fdf9a60065b | 235 | busy_wait_ms(SERIAL_FLUSH_TIME_MS); |
kadonotakashi | 0:8fdf9a60065b | 236 | |
kadonotakashi | 0:8fdf9a60065b | 237 | TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should not be locked"); |
kadonotakashi | 0:8fdf9a60065b | 238 | |
kadonotakashi | 0:8fdf9a60065b | 239 | const unsigned int us_ticks_before_sleep = us_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 240 | |
kadonotakashi | 0:8fdf9a60065b | 241 | const timestamp_t wakeup_time = lp_ticker_read() + us_to_ticks(20000, lp_ticker_freq); |
kadonotakashi | 0:8fdf9a60065b | 242 | lp_ticker_set_interrupt(wakeup_time); |
kadonotakashi | 0:8fdf9a60065b | 243 | |
kadonotakashi | 0:8fdf9a60065b | 244 | sleep(); |
kadonotakashi | 0:8fdf9a60065b | 245 | |
kadonotakashi | 0:8fdf9a60065b | 246 | const unsigned int us_ticks_after_sleep = us_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 247 | const unsigned int lp_ticks_after_sleep = lp_ticker_read(); |
kadonotakashi | 0:8fdf9a60065b | 248 | |
kadonotakashi | 0:8fdf9a60065b | 249 | /* High freqency ticker should be disabled in deep-sleep mode. We expect that time difference between |
kadonotakashi | 0:8fdf9a60065b | 250 | * ticker reads before and after the sleep represents only code execution time between calls. |
kadonotakashi | 0:8fdf9a60065b | 251 | * Since we went to sleep for about 20 ms check if time counted by high frequency timer does not |
kadonotakashi | 0:8fdf9a60065b | 252 | * exceed 1 ms. |
kadonotakashi | 0:8fdf9a60065b | 253 | */ |
kadonotakashi | 0:8fdf9a60065b | 254 | const unsigned int us_ticks_diff = (us_ticks_before_sleep <= us_ticks_after_sleep) ? (us_ticks_after_sleep - us_ticks_before_sleep) : (us_ticker_mask - us_ticks_before_sleep + us_ticks_after_sleep + 1); |
kadonotakashi | 0:8fdf9a60065b | 255 | |
kadonotakashi | 0:8fdf9a60065b | 256 | TEST_ASSERT_UINT32_WITHIN(1000, 0, ticks_to_us(us_ticks_diff, us_ticker_freq)); |
kadonotakashi | 0:8fdf9a60065b | 257 | |
kadonotakashi | 0:8fdf9a60065b | 258 | sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d", |
kadonotakashi | 0:8fdf9a60065b | 259 | us_to_ticks(deepsleep_mode_delta_us, lp_ticker_freq), lp_ticker_width, wakeup_time, lp_ticks_after_sleep); |
kadonotakashi | 0:8fdf9a60065b | 260 | |
kadonotakashi | 0:8fdf9a60065b | 261 | /* Check if we have woken-up after expected time. */ |
kadonotakashi | 0:8fdf9a60065b | 262 | TEST_ASSERT_MESSAGE(compare_timestamps(us_to_ticks(deepsleep_mode_delta_us, lp_ticker_freq), lp_ticker_width, |
kadonotakashi | 0:8fdf9a60065b | 263 | wakeup_time, lp_ticks_after_sleep), info); |
kadonotakashi | 0:8fdf9a60065b | 264 | } |
kadonotakashi | 0:8fdf9a60065b | 265 | |
kadonotakashi | 0:8fdf9a60065b | 266 | #endif |
kadonotakashi | 0:8fdf9a60065b | 267 | |
kadonotakashi | 0:8fdf9a60065b | 268 | utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) |
kadonotakashi | 0:8fdf9a60065b | 269 | { |
kadonotakashi | 0:8fdf9a60065b | 270 | greentea_case_failure_abort_handler(source, reason); |
kadonotakashi | 0:8fdf9a60065b | 271 | return STATUS_CONTINUE; |
kadonotakashi | 0:8fdf9a60065b | 272 | } |
kadonotakashi | 0:8fdf9a60065b | 273 | |
kadonotakashi | 0:8fdf9a60065b | 274 | utest::v1::status_t greentea_test_setup(const size_t number_of_cases) |
kadonotakashi | 0:8fdf9a60065b | 275 | { |
kadonotakashi | 0:8fdf9a60065b | 276 | GREENTEA_SETUP(60, "default_auto"); |
kadonotakashi | 0:8fdf9a60065b | 277 | /* Suspend RTOS Kernel to enable sleep modes. */ |
kadonotakashi | 0:8fdf9a60065b | 278 | osKernelSuspend(); |
kadonotakashi | 0:8fdf9a60065b | 279 | #if DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 280 | ticker_suspend(get_lp_ticker_data()); |
kadonotakashi | 0:8fdf9a60065b | 281 | #if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) |
kadonotakashi | 0:8fdf9a60065b | 282 | lp_ticker_wrapper_suspend(); |
kadonotakashi | 0:8fdf9a60065b | 283 | #endif |
kadonotakashi | 0:8fdf9a60065b | 284 | #endif |
kadonotakashi | 0:8fdf9a60065b | 285 | ticker_suspend(get_us_ticker_data()); |
kadonotakashi | 0:8fdf9a60065b | 286 | |
kadonotakashi | 0:8fdf9a60065b | 287 | us_ticker_init(); |
kadonotakashi | 0:8fdf9a60065b | 288 | #if DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 289 | lp_ticker_init(); |
kadonotakashi | 0:8fdf9a60065b | 290 | #endif |
kadonotakashi | 0:8fdf9a60065b | 291 | |
kadonotakashi | 0:8fdf9a60065b | 292 | return greentea_test_setup_handler(number_of_cases); |
kadonotakashi | 0:8fdf9a60065b | 293 | } |
kadonotakashi | 0:8fdf9a60065b | 294 | |
kadonotakashi | 0:8fdf9a60065b | 295 | void greentea_test_teardown(const size_t passed, const size_t failed, const failure_t failure) |
kadonotakashi | 0:8fdf9a60065b | 296 | { |
kadonotakashi | 0:8fdf9a60065b | 297 | ticker_resume(get_us_ticker_data()); |
kadonotakashi | 0:8fdf9a60065b | 298 | #if DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 299 | #if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) |
kadonotakashi | 0:8fdf9a60065b | 300 | lp_ticker_wrapper_resume(); |
kadonotakashi | 0:8fdf9a60065b | 301 | #endif |
kadonotakashi | 0:8fdf9a60065b | 302 | ticker_resume(get_lp_ticker_data()); |
kadonotakashi | 0:8fdf9a60065b | 303 | #endif |
kadonotakashi | 0:8fdf9a60065b | 304 | osKernelResume(0); |
kadonotakashi | 0:8fdf9a60065b | 305 | |
kadonotakashi | 0:8fdf9a60065b | 306 | greentea_test_teardown_handler(passed, failed, failure); |
kadonotakashi | 0:8fdf9a60065b | 307 | } |
kadonotakashi | 0:8fdf9a60065b | 308 | |
kadonotakashi | 0:8fdf9a60065b | 309 | Case cases[] = { |
kadonotakashi | 0:8fdf9a60065b | 310 | Case("sleep - source of wake-up - us ticker", sleep_usticker_test, greentea_failure_handler), |
kadonotakashi | 0:8fdf9a60065b | 311 | #if DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 312 | Case("deep-sleep - source of wake-up - lp ticker", deepsleep_lpticker_test, greentea_failure_handler), |
kadonotakashi | 0:8fdf9a60065b | 313 | Case("deep-sleep - high-speed clocks are turned off", deepsleep_high_speed_clocks_turned_off_test, greentea_failure_handler), |
kadonotakashi | 0:8fdf9a60065b | 314 | #endif |
kadonotakashi | 0:8fdf9a60065b | 315 | }; |
kadonotakashi | 0:8fdf9a60065b | 316 | |
kadonotakashi | 0:8fdf9a60065b | 317 | Specification specification(greentea_test_setup, cases, greentea_test_teardown); |
kadonotakashi | 0:8fdf9a60065b | 318 | |
kadonotakashi | 0:8fdf9a60065b | 319 | int main() |
kadonotakashi | 0:8fdf9a60065b | 320 | { |
kadonotakashi | 0:8fdf9a60065b | 321 | Harness::run(specification); |
kadonotakashi | 0:8fdf9a60065b | 322 | } |