Backup 1

Committer:
borlanic
Date:
Tue Apr 24 11:45:18 2018 +0000
Revision:
0:02dd72d1d465
BaBoRo_test2 - backup 1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:02dd72d1d465 1 /* mbed Microcontroller Library
borlanic 0:02dd72d1d465 2 * Copyright (c) 2017 ARM Limited
borlanic 0:02dd72d1d465 3 *
borlanic 0:02dd72d1d465 4 * Licensed under the Apache License, Version 2.0 (the "License");
borlanic 0:02dd72d1d465 5 * you may not use this file except in compliance with the License.
borlanic 0:02dd72d1d465 6 * You may obtain a copy of the License at
borlanic 0:02dd72d1d465 7 *
borlanic 0:02dd72d1d465 8 * http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:02dd72d1d465 9 *
borlanic 0:02dd72d1d465 10 * Unless required by applicable law or agreed to in writing, software
borlanic 0:02dd72d1d465 11 * distributed under the License is distributed on an "AS IS" BASIS,
borlanic 0:02dd72d1d465 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:02dd72d1d465 13 * See the License for the specific language governing permissions and
borlanic 0:02dd72d1d465 14 * limitations under the License.
borlanic 0:02dd72d1d465 15 */
borlanic 0:02dd72d1d465 16
borlanic 0:02dd72d1d465 17 #include "mbed_assert.h"
borlanic 0:02dd72d1d465 18 #include "mbed_power_mgmt.h"
borlanic 0:02dd72d1d465 19 #include "mbed_critical.h"
borlanic 0:02dd72d1d465 20 #include "sleep_api.h"
borlanic 0:02dd72d1d465 21 #include "mbed_error.h"
borlanic 0:02dd72d1d465 22 #include "mbed_debug.h"
borlanic 0:02dd72d1d465 23 #include <limits.h>
borlanic 0:02dd72d1d465 24 #include <stdio.h>
borlanic 0:02dd72d1d465 25
borlanic 0:02dd72d1d465 26 #if DEVICE_SLEEP
borlanic 0:02dd72d1d465 27
borlanic 0:02dd72d1d465 28 // deep sleep locking counter. A target is allowed to deep sleep if counter == 0
borlanic 0:02dd72d1d465 29 static uint16_t deep_sleep_lock = 0U;
borlanic 0:02dd72d1d465 30
borlanic 0:02dd72d1d465 31 #ifdef MBED_SLEEP_TRACING_ENABLED
borlanic 0:02dd72d1d465 32
borlanic 0:02dd72d1d465 33 // Number of drivers that can be stored in the structure
borlanic 0:02dd72d1d465 34 #define STATISTIC_COUNT 10
borlanic 0:02dd72d1d465 35
borlanic 0:02dd72d1d465 36 typedef struct sleep_statistic {
borlanic 0:02dd72d1d465 37 const char* identifier;
borlanic 0:02dd72d1d465 38 uint8_t count;
borlanic 0:02dd72d1d465 39 } sleep_statistic_t;
borlanic 0:02dd72d1d465 40
borlanic 0:02dd72d1d465 41 static sleep_statistic_t sleep_stats[STATISTIC_COUNT];
borlanic 0:02dd72d1d465 42
borlanic 0:02dd72d1d465 43 static sleep_statistic_t* sleep_tracker_find(const char *const filename)
borlanic 0:02dd72d1d465 44 {
borlanic 0:02dd72d1d465 45 for (int i = 0; i < STATISTIC_COUNT; ++i) {
borlanic 0:02dd72d1d465 46 if (sleep_stats[i].identifier == filename) {
borlanic 0:02dd72d1d465 47 return &sleep_stats[i];
borlanic 0:02dd72d1d465 48 }
borlanic 0:02dd72d1d465 49 }
borlanic 0:02dd72d1d465 50
borlanic 0:02dd72d1d465 51 return NULL;
borlanic 0:02dd72d1d465 52 }
borlanic 0:02dd72d1d465 53
borlanic 0:02dd72d1d465 54 static sleep_statistic_t* sleep_tracker_add(const char* const filename)
borlanic 0:02dd72d1d465 55 {
borlanic 0:02dd72d1d465 56 for (int i = 0; i < STATISTIC_COUNT; ++i) {
borlanic 0:02dd72d1d465 57 if (sleep_stats[i].identifier == NULL) {
borlanic 0:02dd72d1d465 58 sleep_stats[i].identifier = filename;
borlanic 0:02dd72d1d465 59
borlanic 0:02dd72d1d465 60 return &sleep_stats[i];
borlanic 0:02dd72d1d465 61 }
borlanic 0:02dd72d1d465 62 }
borlanic 0:02dd72d1d465 63
borlanic 0:02dd72d1d465 64 debug("No free indexes left to use in mbed sleep tracker.\r\n");
borlanic 0:02dd72d1d465 65
borlanic 0:02dd72d1d465 66 return NULL;
borlanic 0:02dd72d1d465 67 }
borlanic 0:02dd72d1d465 68
borlanic 0:02dd72d1d465 69 static void sleep_tracker_print_stats(void)
borlanic 0:02dd72d1d465 70 {
borlanic 0:02dd72d1d465 71 debug("Sleep locks held:\r\n");
borlanic 0:02dd72d1d465 72 for (int i = 0; i < STATISTIC_COUNT; ++i) {
borlanic 0:02dd72d1d465 73 if (sleep_stats[i].count == 0) {
borlanic 0:02dd72d1d465 74 continue;
borlanic 0:02dd72d1d465 75 }
borlanic 0:02dd72d1d465 76
borlanic 0:02dd72d1d465 77 if (sleep_stats[i].identifier == NULL) {
borlanic 0:02dd72d1d465 78 return;
borlanic 0:02dd72d1d465 79 }
borlanic 0:02dd72d1d465 80
borlanic 0:02dd72d1d465 81 debug("[id: %s, count: %u]\r\n", sleep_stats[i].identifier,
borlanic 0:02dd72d1d465 82 sleep_stats[i].count);
borlanic 0:02dd72d1d465 83 }
borlanic 0:02dd72d1d465 84 }
borlanic 0:02dd72d1d465 85
borlanic 0:02dd72d1d465 86 void sleep_tracker_lock(const char* const filename, int line)
borlanic 0:02dd72d1d465 87 {
borlanic 0:02dd72d1d465 88 sleep_statistic_t *stat = sleep_tracker_find(filename);
borlanic 0:02dd72d1d465 89
borlanic 0:02dd72d1d465 90 // Entry for this driver does not exist, create one.
borlanic 0:02dd72d1d465 91 if (stat == NULL) {
borlanic 0:02dd72d1d465 92 stat = sleep_tracker_add(filename);
borlanic 0:02dd72d1d465 93 }
borlanic 0:02dd72d1d465 94
borlanic 0:02dd72d1d465 95 core_util_atomic_incr_u8(&stat->count, 1);
borlanic 0:02dd72d1d465 96
borlanic 0:02dd72d1d465 97 debug("LOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
borlanic 0:02dd72d1d465 98 }
borlanic 0:02dd72d1d465 99
borlanic 0:02dd72d1d465 100 void sleep_tracker_unlock(const char* const filename, int line)
borlanic 0:02dd72d1d465 101 {
borlanic 0:02dd72d1d465 102 sleep_statistic_t *stat = sleep_tracker_find(filename);
borlanic 0:02dd72d1d465 103
borlanic 0:02dd72d1d465 104 // Entry for this driver does not exist, something went wrong.
borlanic 0:02dd72d1d465 105 if (stat == NULL) {
borlanic 0:02dd72d1d465 106 debug("Unlocking sleep for driver that was not previously locked: %s, ln: %i\r\n", filename, line);
borlanic 0:02dd72d1d465 107 return;
borlanic 0:02dd72d1d465 108 }
borlanic 0:02dd72d1d465 109
borlanic 0:02dd72d1d465 110 core_util_atomic_decr_u8(&stat->count, 1);
borlanic 0:02dd72d1d465 111
borlanic 0:02dd72d1d465 112 debug("UNLOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
borlanic 0:02dd72d1d465 113 }
borlanic 0:02dd72d1d465 114
borlanic 0:02dd72d1d465 115 #endif // MBED_SLEEP_TRACING_ENABLED
borlanic 0:02dd72d1d465 116
borlanic 0:02dd72d1d465 117 void sleep_manager_lock_deep_sleep_internal(void)
borlanic 0:02dd72d1d465 118 {
borlanic 0:02dd72d1d465 119 core_util_critical_section_enter();
borlanic 0:02dd72d1d465 120 if (deep_sleep_lock == USHRT_MAX) {
borlanic 0:02dd72d1d465 121 core_util_critical_section_exit();
borlanic 0:02dd72d1d465 122 error("Deep sleep lock would overflow (> USHRT_MAX)");
borlanic 0:02dd72d1d465 123 }
borlanic 0:02dd72d1d465 124 core_util_atomic_incr_u16(&deep_sleep_lock, 1);
borlanic 0:02dd72d1d465 125 core_util_critical_section_exit();
borlanic 0:02dd72d1d465 126 }
borlanic 0:02dd72d1d465 127
borlanic 0:02dd72d1d465 128 void sleep_manager_unlock_deep_sleep_internal(void)
borlanic 0:02dd72d1d465 129 {
borlanic 0:02dd72d1d465 130 core_util_critical_section_enter();
borlanic 0:02dd72d1d465 131 if (deep_sleep_lock == 0) {
borlanic 0:02dd72d1d465 132 core_util_critical_section_exit();
borlanic 0:02dd72d1d465 133 error("Deep sleep lock would underflow (< 0)");
borlanic 0:02dd72d1d465 134 }
borlanic 0:02dd72d1d465 135 core_util_atomic_decr_u16(&deep_sleep_lock, 1);
borlanic 0:02dd72d1d465 136 core_util_critical_section_exit();
borlanic 0:02dd72d1d465 137 }
borlanic 0:02dd72d1d465 138
borlanic 0:02dd72d1d465 139 bool sleep_manager_can_deep_sleep(void)
borlanic 0:02dd72d1d465 140 {
borlanic 0:02dd72d1d465 141 return deep_sleep_lock == 0 ? true : false;
borlanic 0:02dd72d1d465 142 }
borlanic 0:02dd72d1d465 143
borlanic 0:02dd72d1d465 144 void sleep_manager_sleep_auto(void)
borlanic 0:02dd72d1d465 145 {
borlanic 0:02dd72d1d465 146 #ifdef MBED_SLEEP_TRACING_ENABLED
borlanic 0:02dd72d1d465 147 sleep_tracker_print_stats();
borlanic 0:02dd72d1d465 148 #endif
borlanic 0:02dd72d1d465 149 core_util_critical_section_enter();
borlanic 0:02dd72d1d465 150 // debug profile should keep debuggers attached, no deep sleep allowed
borlanic 0:02dd72d1d465 151 #ifdef MBED_DEBUG
borlanic 0:02dd72d1d465 152 hal_sleep();
borlanic 0:02dd72d1d465 153 #else
borlanic 0:02dd72d1d465 154 if (sleep_manager_can_deep_sleep()) {
borlanic 0:02dd72d1d465 155 hal_deepsleep();
borlanic 0:02dd72d1d465 156 } else {
borlanic 0:02dd72d1d465 157 hal_sleep();
borlanic 0:02dd72d1d465 158 }
borlanic 0:02dd72d1d465 159 #endif
borlanic 0:02dd72d1d465 160 core_util_critical_section_exit();
borlanic 0:02dd72d1d465 161 }
borlanic 0:02dd72d1d465 162
borlanic 0:02dd72d1d465 163 #else
borlanic 0:02dd72d1d465 164
borlanic 0:02dd72d1d465 165 // locking is valid only if DEVICE_SLEEP is defined
borlanic 0:02dd72d1d465 166 // we provide empty implementation
borlanic 0:02dd72d1d465 167
borlanic 0:02dd72d1d465 168 void sleep_manager_lock_deep_sleep_internal(void)
borlanic 0:02dd72d1d465 169 {
borlanic 0:02dd72d1d465 170
borlanic 0:02dd72d1d465 171 }
borlanic 0:02dd72d1d465 172
borlanic 0:02dd72d1d465 173 void sleep_manager_unlock_deep_sleep_internal(void)
borlanic 0:02dd72d1d465 174 {
borlanic 0:02dd72d1d465 175
borlanic 0:02dd72d1d465 176 }
borlanic 0:02dd72d1d465 177
borlanic 0:02dd72d1d465 178 bool sleep_manager_can_deep_sleep(void)
borlanic 0:02dd72d1d465 179 {
borlanic 0:02dd72d1d465 180 // no sleep implemented
borlanic 0:02dd72d1d465 181 return false;
borlanic 0:02dd72d1d465 182 }
borlanic 0:02dd72d1d465 183
borlanic 0:02dd72d1d465 184 #endif