mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Parent:
187:0387e8f68319
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

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
Anna Bridge 186:707f6e361f3e 54 // On L4 platforms we've seen unstable PLL CLK configuraiton
AnnaBridge 188:bcfe06ba3d64 55 // when DEEP SLEEP exits just few µs after being entered
Anna Bridge 186:707f6e361f3e 56 // So we need to force MSI usage before setting clocks again
AnnaBridge 187:0387e8f68319 57 static void ForcePeriphOutofDeepSleep(void)
Anna Bridge 186:707f6e361f3e 58 {
AnnaBridge 187:0387e8f68319 59 uint32_t pFLatency = 0;
Anna Bridge 186:707f6e361f3e 60 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
AnnaBridge 187:0387e8f68319 61
AnnaBridge 187:0387e8f68319 62 #if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */
AnnaBridge 187:0387e8f68319 63 /* Get the Clocks configuration according to the internal RCC registers */
AnnaBridge 187:0387e8f68319 64 HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
AnnaBridge 187:0387e8f68319 65
AnnaBridge 187:0387e8f68319 66 // Select HSI ss system clock source as a first step
AnnaBridge 187:0387e8f68319 67 #ifdef RCC_CLOCKTYPE_PCLK2
AnnaBridge 187:0387e8f68319 68 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
AnnaBridge 187:0387e8f68319 69 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
AnnaBridge 187:0387e8f68319 70 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
AnnaBridge 187:0387e8f68319 71 #else
AnnaBridge 187:0387e8f68319 72 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
AnnaBridge 187:0387e8f68319 73 | RCC_CLOCKTYPE_PCLK1);
AnnaBridge 187:0387e8f68319 74 #endif
AnnaBridge 187:0387e8f68319 75 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
AnnaBridge 187:0387e8f68319 76 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
AnnaBridge 187:0387e8f68319 77 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
AnnaBridge 187:0387e8f68319 78 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK) {
AnnaBridge 187:0387e8f68319 79 error("clock issue\r\n");
AnnaBridge 187:0387e8f68319 80 }
AnnaBridge 187:0387e8f68319 81 #else /* HSI used on others */
AnnaBridge 187:0387e8f68319 82 /* Get the Clocks configuration according to the internal RCC registers */
AnnaBridge 187:0387e8f68319 83 HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
AnnaBridge 187:0387e8f68319 84
AnnaBridge 187:0387e8f68319 85 /**Initializes the CPU, AHB and APB busses clocks
AnnaBridge 187:0387e8f68319 86 */
AnnaBridge 187:0387e8f68319 87 #ifdef RCC_CLOCKTYPE_PCLK2
AnnaBridge 187:0387e8f68319 88 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
AnnaBridge 187:0387e8f68319 89 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
AnnaBridge 187:0387e8f68319 90 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
AnnaBridge 187:0387e8f68319 91 #else
AnnaBridge 187:0387e8f68319 92 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
AnnaBridge 187:0387e8f68319 93 | RCC_CLOCKTYPE_PCLK1);
AnnaBridge 187:0387e8f68319 94 #endif
AnnaBridge 187:0387e8f68319 95 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
AnnaBridge 187:0387e8f68319 96 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
AnnaBridge 187:0387e8f68319 97 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
AnnaBridge 187:0387e8f68319 98 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK) {
AnnaBridge 187:0387e8f68319 99 error("clock issue");
AnnaBridge 187:0387e8f68319 100 }
AnnaBridge 187:0387e8f68319 101 #endif // TARGET_STM32L4
AnnaBridge 187:0387e8f68319 102 }
AnnaBridge 187:0387e8f68319 103
AnnaBridge 187:0387e8f68319 104 static void ForceOscOutofDeepSleep(void)
AnnaBridge 187:0387e8f68319 105 {
Anna Bridge 186:707f6e361f3e 106 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
Anna Bridge 186:707f6e361f3e 107
Anna Bridge 186:707f6e361f3e 108 /* Enable Power Control clock */
Anna Bridge 186:707f6e361f3e 109 __HAL_RCC_PWR_CLK_ENABLE();
Anna Bridge 186:707f6e361f3e 110
Anna Bridge 186:707f6e361f3e 111 /* Get the Oscillators configuration according to the internal RCC registers */
Anna Bridge 186:707f6e361f3e 112 HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
Anna Bridge 186:707f6e361f3e 113
Anna Bridge 186:707f6e361f3e 114 #if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */
Anna Bridge 186:707f6e361f3e 115 /**Initializes the CPU, AHB and APB busses clocks
Anna Bridge 186:707f6e361f3e 116 */
Anna Bridge 186:707f6e361f3e 117 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
Anna Bridge 186:707f6e361f3e 118 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
Anna Bridge 186:707f6e361f3e 119 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
Anna Bridge 186:707f6e361f3e 120 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range
Anna Bridge 186:707f6e361f3e 121 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
Anna Bridge 186:707f6e361f3e 122 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Anna Bridge 186:707f6e361f3e 123 error("clock issue\r\n");
Anna Bridge 186:707f6e361f3e 124 }
Anna Bridge 186:707f6e361f3e 125 #else /* HSI used on others */
Anna Bridge 186:707f6e361f3e 126 /**Initializes the CPU, AHB and APB busses clocks
Anna Bridge 186:707f6e361f3e 127 */
Anna Bridge 186:707f6e361f3e 128 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
Anna Bridge 186:707f6e361f3e 129 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
Anna Bridge 186:707f6e361f3e 130 RCC_OscInitStruct.HSICalibrationValue = 16;
Anna Bridge 186:707f6e361f3e 131 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
Anna Bridge 186:707f6e361f3e 132 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Anna Bridge 186:707f6e361f3e 133 error("clock issue");
Anna Bridge 186:707f6e361f3e 134 }
AnnaBridge 187:0387e8f68319 135 #endif // TARGET_STM32L4
AnnaBridge 187:0387e8f68319 136 }
Anna Bridge 186:707f6e361f3e 137
AnnaBridge 187:0387e8f68319 138 /* The content of this function has been split into 2 separate functions
AnnaBridge 187:0387e8f68319 139 so that the involved structures are not allocated on the stack in parallel.
AnnaBridge 187:0387e8f68319 140 This will reduce the maximum stack usage in case on non-optimized / debug
AnnaBridge 187:0387e8f68319 141 compilers settings */
AnnaBridge 187:0387e8f68319 142 static void ForceClockOutofDeepSleep(void)
AnnaBridge 187:0387e8f68319 143 {
AnnaBridge 187:0387e8f68319 144 ForceOscOutofDeepSleep();
AnnaBridge 187:0387e8f68319 145 ForcePeriphOutofDeepSleep();
Anna Bridge 186:707f6e361f3e 146 }
<> 160:d5399cc887bb 147
<> 160:d5399cc887bb 148 void hal_sleep(void)
<> 154:37f96f9d4de2 149 {
AnnaBridge 172:7d866c31b3c5 150 // Disable IRQs
AnnaBridge 172:7d866c31b3c5 151 core_util_critical_section_enter();
AnnaBridge 172:7d866c31b3c5 152
<> 154:37f96f9d4de2 153 // Request to enter SLEEP mode
AnnaBridge 188:bcfe06ba3d64 154 #if TARGET_STM32L4
AnnaBridge 188:bcfe06ba3d64 155 // State Transitions (see 5.3 Low-power modes, Fig. 13):
AnnaBridge 188:bcfe06ba3d64 156 // * (opt): Low Power Run (LPR) Mode -> Run Mode
AnnaBridge 188:bcfe06ba3d64 157 // * Run Mode -> Sleep
AnnaBridge 188:bcfe06ba3d64 158 // --- Wait for Interrupt --
AnnaBridge 188:bcfe06ba3d64 159 // * Sleep -> Run Mode
AnnaBridge 188:bcfe06ba3d64 160 // * (opt): Run Mode -> Low Power Run Mode
AnnaBridge 188:bcfe06ba3d64 161
AnnaBridge 188:bcfe06ba3d64 162 // [5.4.1 Power control register 1 (PWR_CR1)]
AnnaBridge 188:bcfe06ba3d64 163 // LPR: When this bit is set, the regulator is switched from main mode (MR) to low-power mode (LPR).
AnnaBridge 188:bcfe06ba3d64 164 int lowPowerMode = PWR->CR1 & PWR_CR1_LPR;
AnnaBridge 188:bcfe06ba3d64 165 if (lowPowerMode) {
AnnaBridge 188:bcfe06ba3d64 166 HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 188:bcfe06ba3d64 167 } else {
AnnaBridge 188:bcfe06ba3d64 168 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 188:bcfe06ba3d64 169 }
AnnaBridge 188:bcfe06ba3d64 170 #else
<> 154:37f96f9d4de2 171 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 188:bcfe06ba3d64 172 #endif
AnnaBridge 172:7d866c31b3c5 173
AnnaBridge 172:7d866c31b3c5 174 // Enable IRQs
AnnaBridge 172:7d866c31b3c5 175 core_util_critical_section_exit();
<> 154:37f96f9d4de2 176 }
<> 154:37f96f9d4de2 177
AnnaBridge 187:0387e8f68319 178 extern int serial_is_tx_ongoing(void);
AnnaBridge 188:bcfe06ba3d64 179 extern int mbed_sdk_inited;
AnnaBridge 187:0387e8f68319 180
<> 160:d5399cc887bb 181 void hal_deepsleep(void)
<> 154:37f96f9d4de2 182 {
AnnaBridge 187:0387e8f68319 183 /* WORKAROUND:
AnnaBridge 187:0387e8f68319 184 * MBED serial driver does not handle deepsleep lock
AnnaBridge 187:0387e8f68319 185 * to prevent entering deepsleep until HW serial FIFO is empty.
AnnaBridge 187:0387e8f68319 186 * This is tracked in mbed issue 4408.
AnnaBridge 187:0387e8f68319 187 * For now, we're checking all Serial HW FIFO. If any transfer is ongoing
AnnaBridge 187:0387e8f68319 188 * we're not entering deep sleep and returning immediately. */
AnnaBridge 187:0387e8f68319 189 if(serial_is_tx_ongoing()) {
AnnaBridge 187:0387e8f68319 190 return;
AnnaBridge 187:0387e8f68319 191 }
AnnaBridge 187:0387e8f68319 192
AnnaBridge 172:7d866c31b3c5 193 // Disable IRQs
AnnaBridge 172:7d866c31b3c5 194 core_util_critical_section_enter();
AnnaBridge 172:7d866c31b3c5 195
AnnaBridge 187:0387e8f68319 196 save_timer_ctx();
<> 154:37f96f9d4de2 197
<> 154:37f96f9d4de2 198 // Request to enter STOP mode with regulator in low power mode
<> 154:37f96f9d4de2 199 #if TARGET_STM32L4
<> 160:d5399cc887bb 200 int pwrClockEnabled = __HAL_RCC_PWR_IS_CLK_ENABLED();
<> 160:d5399cc887bb 201 int lowPowerModeEnabled = PWR->CR1 & PWR_CR1_LPR;
Anna Bridge 180:96ed750bd169 202
<> 160:d5399cc887bb 203 if (!pwrClockEnabled) {
<> 160:d5399cc887bb 204 __HAL_RCC_PWR_CLK_ENABLE();
<> 160:d5399cc887bb 205 }
<> 160:d5399cc887bb 206 if (lowPowerModeEnabled) {
<> 156:95d6b41a828b 207 HAL_PWREx_DisableLowPowerRunMode();
<> 160:d5399cc887bb 208 }
Anna Bridge 180:96ed750bd169 209
<> 160:d5399cc887bb 210 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
Anna Bridge 180:96ed750bd169 211
<> 160:d5399cc887bb 212 if (lowPowerModeEnabled) {
<> 156:95d6b41a828b 213 HAL_PWREx_EnableLowPowerRunMode();
<> 160:d5399cc887bb 214 }
<> 160:d5399cc887bb 215 if (!pwrClockEnabled) {
<> 156:95d6b41a828b 216 __HAL_RCC_PWR_CLK_DISABLE();
<> 156:95d6b41a828b 217 }
<> 154:37f96f9d4de2 218 #else /* TARGET_STM32L4 */
<> 154:37f96f9d4de2 219 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
<> 154:37f96f9d4de2 220 #endif /* TARGET_STM32L4 */
AnnaBridge 187:0387e8f68319 221
AnnaBridge 188:bcfe06ba3d64 222 /* Prevent HAL_GetTick() from using ticker_read_us() to read the
AnnaBridge 188:bcfe06ba3d64 223 * us_ticker timestamp until the us_ticker context is restored. */
AnnaBridge 188:bcfe06ba3d64 224 mbed_sdk_inited = 0;
AnnaBridge 188:bcfe06ba3d64 225
Anna Bridge 186:707f6e361f3e 226 // Verify Clock Out of Deep Sleep
Anna Bridge 186:707f6e361f3e 227 ForceClockOutofDeepSleep();
AnnaBridge 172:7d866c31b3c5 228
<> 154:37f96f9d4de2 229 // After wake-up from STOP reconfigure the PLL
<> 154:37f96f9d4de2 230 SetSysClock();
<> 154:37f96f9d4de2 231
Anna Bridge 186:707f6e361f3e 232 /* Wait for clock to be stabilized.
Anna Bridge 186:707f6e361f3e 233 * TO DO: a better way of doing this, would be to rely on
Anna Bridge 186:707f6e361f3e 234 * HW Flag. At least this ensures proper operation out of
Anna Bridge 186:707f6e361f3e 235 * deep sleep */
Anna Bridge 186:707f6e361f3e 236 wait_loop(500);
Anna Bridge 186:707f6e361f3e 237
AnnaBridge 187:0387e8f68319 238 restore_timer_ctx();
<> 160:d5399cc887bb 239
AnnaBridge 188:bcfe06ba3d64 240 /* us_ticker context restored, allow HAL_GetTick() to read the us_ticker
AnnaBridge 188:bcfe06ba3d64 241 * timestamp via ticker_read_us() again. */
AnnaBridge 188:bcfe06ba3d64 242 mbed_sdk_inited = 1;
AnnaBridge 188:bcfe06ba3d64 243
Anna Bridge 186:707f6e361f3e 244 // Enable IRQs
AnnaBridge 187:0387e8f68319 245 core_util_critical_section_exit();
<> 154:37f96f9d4de2 246 }
<> 154:37f96f9d4de2 247
<> 154:37f96f9d4de2 248 #endif