mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 154:37f96f9d4de2 1 /* mbed Microcontroller Library
<> 154:37f96f9d4de2 2 *******************************************************************************
Anna Bridge 186:707f6e361f3e 3 * Copyright (c) 2018, STMicroelectronics
<> 154:37f96f9d4de2 4 * All rights reserved.
<> 154:37f96f9d4de2 5 *
<> 154:37f96f9d4de2 6 * Redistribution and use in source and binary forms, with or without
<> 154:37f96f9d4de2 7 * modification, are permitted provided that the following conditions are met:
<> 154:37f96f9d4de2 8 *
<> 154:37f96f9d4de2 9 * 1. Redistributions of source code must retain the above copyright notice,
<> 154:37f96f9d4de2 10 * this list of conditions and the following disclaimer.
<> 154:37f96f9d4de2 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
<> 154:37f96f9d4de2 12 * this list of conditions and the following disclaimer in the documentation
<> 154:37f96f9d4de2 13 * and/or other materials provided with the distribution.
<> 154:37f96f9d4de2 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
<> 154:37f96f9d4de2 15 * may be used to endorse or promote products derived from this software
<> 154:37f96f9d4de2 16 * without specific prior written permission.
<> 154:37f96f9d4de2 17 *
<> 154:37f96f9d4de2 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
<> 154:37f96f9d4de2 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
<> 154:37f96f9d4de2 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 154:37f96f9d4de2 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
<> 154:37f96f9d4de2 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
<> 154:37f96f9d4de2 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
<> 154:37f96f9d4de2 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
<> 154:37f96f9d4de2 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
<> 154:37f96f9d4de2 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
<> 154:37f96f9d4de2 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 154:37f96f9d4de2 28 *******************************************************************************
<> 154:37f96f9d4de2 29 */
<> 154:37f96f9d4de2 30 #if DEVICE_SLEEP
<> 154:37f96f9d4de2 31
<> 160:d5399cc887bb 32 #include "sleep_api.h"
Anna Bridge 186:707f6e361f3e 33 #include "us_ticker_api.h"
AnnaBridge 187:0387e8f68319 34 #include "us_ticker_data.h"
Anna Bridge 186:707f6e361f3e 35 #include "mbed_critical.h"
Anna Bridge 186:707f6e361f3e 36 #include "mbed_error.h"
Anna Bridge 186:707f6e361f3e 37
AnnaBridge 187:0387e8f68319 38 extern void save_timer_ctx(void);
AnnaBridge 187:0387e8f68319 39 extern void restore_timer_ctx(void);
Anna Bridge 186:707f6e361f3e 40
Anna Bridge 186:707f6e361f3e 41 /* Wait loop - assuming tick is 1 us */
Anna Bridge 186:707f6e361f3e 42 static void wait_loop(uint32_t timeout)
Anna Bridge 186:707f6e361f3e 43 {
Anna Bridge 186:707f6e361f3e 44 uint32_t t1, t2, elapsed = 0;
Anna Bridge 186:707f6e361f3e 45 t1 = us_ticker_read();
Anna Bridge 186:707f6e361f3e 46 do {
Anna Bridge 186:707f6e361f3e 47 t2 = us_ticker_read();
Anna Bridge 186:707f6e361f3e 48 elapsed = (t2 > t1) ? (t2 - t1) : ((uint64_t)t2 + 0xFFFFFFFF - t1 + 1);
Anna Bridge 186:707f6e361f3e 49 } while (elapsed < timeout);
Anna Bridge 186:707f6e361f3e 50 return;
Anna Bridge 186:707f6e361f3e 51 }
Anna Bridge 186:707f6e361f3e 52
AnnaBridge 187:0387e8f68319 53
AnnaBridge 187:0387e8f68319 54 static void ForcePeriphOutofDeepSleep(void)
Anna Bridge 186:707f6e361f3e 55 {
AnnaBridge 187:0387e8f68319 56 uint32_t pFLatency = 0;
Anna Bridge 186:707f6e361f3e 57 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
AnnaBridge 187:0387e8f68319 58
AnnaBridge 187:0387e8f68319 59 /* Get the Clocks configuration according to the internal RCC registers */
AnnaBridge 187:0387e8f68319 60 HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
AnnaBridge 187:0387e8f68319 61
AnnaBridge 187:0387e8f68319 62 #ifdef RCC_CLOCKTYPE_PCLK2
AnnaBridge 187:0387e8f68319 63 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
AnnaBridge 187:0387e8f68319 64 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
AnnaBridge 187:0387e8f68319 65 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
AnnaBridge 189:f392fc9709a3 66 #else /* RCC_CLOCKTYPE_PCLK2 */
AnnaBridge 187:0387e8f68319 67 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
AnnaBridge 187:0387e8f68319 68 | RCC_CLOCKTYPE_PCLK1);
AnnaBridge 189:f392fc9709a3 69 #endif /* RCC_CLOCKTYPE_PCLK2 */
AnnaBridge 189:f392fc9709a3 70
AnnaBridge 189:f392fc9709a3 71 #if defined (RCC_SYSCLKSOURCE_MSI) /* STM32Lx */
AnnaBridge 189:f392fc9709a3 72 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
AnnaBridge 189:f392fc9709a3 73 #else /* defined RCC_SYSCLKSOURCE_MSI */
AnnaBridge 187:0387e8f68319 74 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
AnnaBridge 189:f392fc9709a3 75 #endif /* defined RCC_SYSCLKSOURCE_MSI */
AnnaBridge 189:f392fc9709a3 76
AnnaBridge 189:f392fc9709a3 77 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
AnnaBridge 189:f392fc9709a3 78 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
AnnaBridge 189:f392fc9709a3 79
AnnaBridge 187:0387e8f68319 80 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK) {
AnnaBridge 189:f392fc9709a3 81 error("ForcePeriphOutofDeepSleep clock issue\r\n");
AnnaBridge 187:0387e8f68319 82 }
AnnaBridge 187:0387e8f68319 83 }
AnnaBridge 187:0387e8f68319 84
AnnaBridge 189:f392fc9709a3 85
AnnaBridge 187:0387e8f68319 86 static void ForceOscOutofDeepSleep(void)
AnnaBridge 187:0387e8f68319 87 {
Anna Bridge 186:707f6e361f3e 88 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
Anna Bridge 186:707f6e361f3e 89
Anna Bridge 186:707f6e361f3e 90 /* Enable Power Control clock */
Anna Bridge 186:707f6e361f3e 91 __HAL_RCC_PWR_CLK_ENABLE();
Anna Bridge 186:707f6e361f3e 92
Anna Bridge 186:707f6e361f3e 93 /* Get the Oscillators configuration according to the internal RCC registers */
Anna Bridge 186:707f6e361f3e 94 HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
Anna Bridge 186:707f6e361f3e 95
AnnaBridge 189:f392fc9709a3 96 #if defined (RCC_SYSCLKSOURCE_MSI) /* STM32Lx */
Anna Bridge 186:707f6e361f3e 97 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
Anna Bridge 186:707f6e361f3e 98 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
Anna Bridge 186:707f6e361f3e 99 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
Anna Bridge 186:707f6e361f3e 100 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range
Anna Bridge 186:707f6e361f3e 101 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
AnnaBridge 189:f392fc9709a3 102 #else /* defined RCC_SYSCLKSOURCE_MSI */
Anna Bridge 186:707f6e361f3e 103 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
Anna Bridge 186:707f6e361f3e 104 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
Anna Bridge 186:707f6e361f3e 105 RCC_OscInitStruct.HSICalibrationValue = 16;
Anna Bridge 186:707f6e361f3e 106 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
AnnaBridge 189:f392fc9709a3 107 #endif /* defined RCC_SYSCLKSOURCE_MSI */
AnnaBridge 189:f392fc9709a3 108
Anna Bridge 186:707f6e361f3e 109 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
AnnaBridge 189:f392fc9709a3 110 error("ForceOscOutofDeepSleep clock issue\r\n");
Anna Bridge 186:707f6e361f3e 111 }
AnnaBridge 187:0387e8f68319 112 }
Anna Bridge 186:707f6e361f3e 113
<> 160:d5399cc887bb 114
<> 160:d5399cc887bb 115 void hal_sleep(void)
<> 154:37f96f9d4de2 116 {
AnnaBridge 172:7d866c31b3c5 117 // Disable IRQs
AnnaBridge 172:7d866c31b3c5 118 core_util_critical_section_enter();
AnnaBridge 172:7d866c31b3c5 119
<> 154:37f96f9d4de2 120 // Request to enter SLEEP mode
AnnaBridge 189:f392fc9709a3 121 #ifdef PWR_CR1_LPR
AnnaBridge 188:bcfe06ba3d64 122 // State Transitions (see 5.3 Low-power modes, Fig. 13):
AnnaBridge 188:bcfe06ba3d64 123 // * (opt): Low Power Run (LPR) Mode -> Run Mode
AnnaBridge 188:bcfe06ba3d64 124 // * Run Mode -> Sleep
AnnaBridge 188:bcfe06ba3d64 125 // --- Wait for Interrupt --
AnnaBridge 188:bcfe06ba3d64 126 // * Sleep -> Run Mode
AnnaBridge 188:bcfe06ba3d64 127 // * (opt): Run Mode -> Low Power Run Mode
AnnaBridge 188:bcfe06ba3d64 128
AnnaBridge 188:bcfe06ba3d64 129 // [5.4.1 Power control register 1 (PWR_CR1)]
AnnaBridge 189:f392fc9709a3 130 // LPR: When this bit is set, the regulator is switched from main mode (MR) to low-power mode (LPR).
AnnaBridge 188:bcfe06ba3d64 131 int lowPowerMode = PWR->CR1 & PWR_CR1_LPR;
AnnaBridge 188:bcfe06ba3d64 132 if (lowPowerMode) {
AnnaBridge 188:bcfe06ba3d64 133 HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 188:bcfe06ba3d64 134 } else {
AnnaBridge 188:bcfe06ba3d64 135 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 188:bcfe06ba3d64 136 }
AnnaBridge 188:bcfe06ba3d64 137 #else
<> 154:37f96f9d4de2 138 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 188:bcfe06ba3d64 139 #endif
AnnaBridge 172:7d866c31b3c5 140
AnnaBridge 172:7d866c31b3c5 141 // Enable IRQs
AnnaBridge 172:7d866c31b3c5 142 core_util_critical_section_exit();
<> 154:37f96f9d4de2 143 }
<> 154:37f96f9d4de2 144
AnnaBridge 187:0387e8f68319 145 extern int serial_is_tx_ongoing(void);
AnnaBridge 188:bcfe06ba3d64 146 extern int mbed_sdk_inited;
AnnaBridge 187:0387e8f68319 147
<> 160:d5399cc887bb 148 void hal_deepsleep(void)
<> 154:37f96f9d4de2 149 {
AnnaBridge 187:0387e8f68319 150 /* WORKAROUND:
AnnaBridge 187:0387e8f68319 151 * MBED serial driver does not handle deepsleep lock
AnnaBridge 187:0387e8f68319 152 * to prevent entering deepsleep until HW serial FIFO is empty.
AnnaBridge 187:0387e8f68319 153 * This is tracked in mbed issue 4408.
AnnaBridge 187:0387e8f68319 154 * For now, we're checking all Serial HW FIFO. If any transfer is ongoing
AnnaBridge 187:0387e8f68319 155 * we're not entering deep sleep and returning immediately. */
AnnaBridge 189:f392fc9709a3 156 if (serial_is_tx_ongoing()) {
AnnaBridge 187:0387e8f68319 157 return;
AnnaBridge 187:0387e8f68319 158 }
AnnaBridge 187:0387e8f68319 159
AnnaBridge 172:7d866c31b3c5 160 // Disable IRQs
AnnaBridge 172:7d866c31b3c5 161 core_util_critical_section_enter();
AnnaBridge 172:7d866c31b3c5 162
AnnaBridge 187:0387e8f68319 163 save_timer_ctx();
<> 154:37f96f9d4de2 164
<> 154:37f96f9d4de2 165 // Request to enter STOP mode with regulator in low power mode
AnnaBridge 189:f392fc9709a3 166 #ifdef PWR_CR1_LPMS_STOP2 /* STM32L4 */
<> 160:d5399cc887bb 167 int pwrClockEnabled = __HAL_RCC_PWR_IS_CLK_ENABLED();
<> 160:d5399cc887bb 168 int lowPowerModeEnabled = PWR->CR1 & PWR_CR1_LPR;
Anna Bridge 180:96ed750bd169 169
<> 160:d5399cc887bb 170 if (!pwrClockEnabled) {
<> 160:d5399cc887bb 171 __HAL_RCC_PWR_CLK_ENABLE();
<> 160:d5399cc887bb 172 }
<> 160:d5399cc887bb 173 if (lowPowerModeEnabled) {
<> 156:95d6b41a828b 174 HAL_PWREx_DisableLowPowerRunMode();
<> 160:d5399cc887bb 175 }
Anna Bridge 180:96ed750bd169 176
<> 160:d5399cc887bb 177 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
Anna Bridge 180:96ed750bd169 178
<> 160:d5399cc887bb 179 if (lowPowerModeEnabled) {
<> 156:95d6b41a828b 180 HAL_PWREx_EnableLowPowerRunMode();
<> 160:d5399cc887bb 181 }
<> 160:d5399cc887bb 182 if (!pwrClockEnabled) {
<> 156:95d6b41a828b 183 __HAL_RCC_PWR_CLK_DISABLE();
<> 156:95d6b41a828b 184 }
AnnaBridge 189:f392fc9709a3 185 #else /* PWR_CR1_LPMS_STOP2 */
<> 154:37f96f9d4de2 186 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
AnnaBridge 189:f392fc9709a3 187 #endif /* PWR_CR1_LPMS_STOP2 */
AnnaBridge 187:0387e8f68319 188
AnnaBridge 188:bcfe06ba3d64 189 /* Prevent HAL_GetTick() from using ticker_read_us() to read the
AnnaBridge 188:bcfe06ba3d64 190 * us_ticker timestamp until the us_ticker context is restored. */
AnnaBridge 188:bcfe06ba3d64 191 mbed_sdk_inited = 0;
AnnaBridge 188:bcfe06ba3d64 192
AnnaBridge 189:f392fc9709a3 193 /* We've seen unstable PLL CLK configuration when DEEP SLEEP exits just few µs after being entered
AnnaBridge 189:f392fc9709a3 194 * So we need to force clock init out of Deep Sleep.
AnnaBridge 189:f392fc9709a3 195 * This init has been split into 2 separate functions so that the involved structures are not allocated on the stack in parallel.
AnnaBridge 189:f392fc9709a3 196 * This will reduce the maximum stack usage in case on non-optimized / debug compilers settings
AnnaBridge 189:f392fc9709a3 197 */
AnnaBridge 189:f392fc9709a3 198 ForceOscOutofDeepSleep();
AnnaBridge 189:f392fc9709a3 199 ForcePeriphOutofDeepSleep();
AnnaBridge 172:7d866c31b3c5 200
<> 154:37f96f9d4de2 201 // After wake-up from STOP reconfigure the PLL
<> 154:37f96f9d4de2 202 SetSysClock();
<> 154:37f96f9d4de2 203
Anna Bridge 186:707f6e361f3e 204 /* Wait for clock to be stabilized.
Anna Bridge 186:707f6e361f3e 205 * TO DO: a better way of doing this, would be to rely on
Anna Bridge 186:707f6e361f3e 206 * HW Flag. At least this ensures proper operation out of
Anna Bridge 186:707f6e361f3e 207 * deep sleep */
Anna Bridge 186:707f6e361f3e 208 wait_loop(500);
Anna Bridge 186:707f6e361f3e 209
AnnaBridge 187:0387e8f68319 210 restore_timer_ctx();
<> 160:d5399cc887bb 211
AnnaBridge 188:bcfe06ba3d64 212 /* us_ticker context restored, allow HAL_GetTick() to read the us_ticker
AnnaBridge 188:bcfe06ba3d64 213 * timestamp via ticker_read_us() again. */
AnnaBridge 188:bcfe06ba3d64 214 mbed_sdk_inited = 1;
AnnaBridge 188:bcfe06ba3d64 215
Anna Bridge 186:707f6e361f3e 216 // Enable IRQs
AnnaBridge 187:0387e8f68319 217 core_util_critical_section_exit();
<> 154:37f96f9d4de2 218 }
<> 154:37f96f9d4de2 219
<> 154:37f96f9d4de2 220 #endif