Modified for BG96

Fork of mbed-dev by mbed official

Committer:
WaleedElmughrabi
Date:
Thu Sep 20 16:11:23 2018 +0000
Revision:
188:60408c49b6d4
Parent:
187:0387e8f68319
Fork modified for BG96 error

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
Anna Bridge 186:707f6e361f3e 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
<> 154:37f96f9d4de2 154 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
AnnaBridge 172:7d866c31b3c5 155
AnnaBridge 172:7d866c31b3c5 156 // Enable IRQs
AnnaBridge 172:7d866c31b3c5 157 core_util_critical_section_exit();
<> 154:37f96f9d4de2 158 }
<> 154:37f96f9d4de2 159
AnnaBridge 187:0387e8f68319 160 extern int serial_is_tx_ongoing(void);
AnnaBridge 187:0387e8f68319 161
<> 160:d5399cc887bb 162 void hal_deepsleep(void)
<> 154:37f96f9d4de2 163 {
AnnaBridge 187:0387e8f68319 164 /* WORKAROUND:
AnnaBridge 187:0387e8f68319 165 * MBED serial driver does not handle deepsleep lock
AnnaBridge 187:0387e8f68319 166 * to prevent entering deepsleep until HW serial FIFO is empty.
AnnaBridge 187:0387e8f68319 167 * This is tracked in mbed issue 4408.
AnnaBridge 187:0387e8f68319 168 * For now, we're checking all Serial HW FIFO. If any transfer is ongoing
AnnaBridge 187:0387e8f68319 169 * we're not entering deep sleep and returning immediately. */
AnnaBridge 187:0387e8f68319 170 if(serial_is_tx_ongoing()) {
AnnaBridge 187:0387e8f68319 171 return;
AnnaBridge 187:0387e8f68319 172 }
AnnaBridge 187:0387e8f68319 173
AnnaBridge 172:7d866c31b3c5 174 // Disable IRQs
AnnaBridge 172:7d866c31b3c5 175 core_util_critical_section_enter();
AnnaBridge 172:7d866c31b3c5 176
AnnaBridge 187:0387e8f68319 177 save_timer_ctx();
<> 154:37f96f9d4de2 178
<> 154:37f96f9d4de2 179 // Request to enter STOP mode with regulator in low power mode
<> 154:37f96f9d4de2 180 #if TARGET_STM32L4
<> 160:d5399cc887bb 181 int pwrClockEnabled = __HAL_RCC_PWR_IS_CLK_ENABLED();
<> 160:d5399cc887bb 182 int lowPowerModeEnabled = PWR->CR1 & PWR_CR1_LPR;
Anna Bridge 180:96ed750bd169 183
<> 160:d5399cc887bb 184 if (!pwrClockEnabled) {
<> 160:d5399cc887bb 185 __HAL_RCC_PWR_CLK_ENABLE();
<> 160:d5399cc887bb 186 }
<> 160:d5399cc887bb 187 if (lowPowerModeEnabled) {
<> 156:95d6b41a828b 188 HAL_PWREx_DisableLowPowerRunMode();
<> 160:d5399cc887bb 189 }
Anna Bridge 180:96ed750bd169 190
<> 160:d5399cc887bb 191 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
Anna Bridge 180:96ed750bd169 192
<> 160:d5399cc887bb 193 if (lowPowerModeEnabled) {
<> 156:95d6b41a828b 194 HAL_PWREx_EnableLowPowerRunMode();
<> 160:d5399cc887bb 195 }
<> 160:d5399cc887bb 196 if (!pwrClockEnabled) {
<> 156:95d6b41a828b 197 __HAL_RCC_PWR_CLK_DISABLE();
<> 156:95d6b41a828b 198 }
<> 154:37f96f9d4de2 199 #else /* TARGET_STM32L4 */
<> 154:37f96f9d4de2 200 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
<> 154:37f96f9d4de2 201 #endif /* TARGET_STM32L4 */
AnnaBridge 187:0387e8f68319 202
Anna Bridge 186:707f6e361f3e 203 // Verify Clock Out of Deep Sleep
Anna Bridge 186:707f6e361f3e 204 ForceClockOutofDeepSleep();
AnnaBridge 172:7d866c31b3c5 205
<> 154:37f96f9d4de2 206 // After wake-up from STOP reconfigure the PLL
<> 154:37f96f9d4de2 207 SetSysClock();
<> 154:37f96f9d4de2 208
Anna Bridge 186:707f6e361f3e 209 /* Wait for clock to be stabilized.
Anna Bridge 186:707f6e361f3e 210 * TO DO: a better way of doing this, would be to rely on
Anna Bridge 186:707f6e361f3e 211 * HW Flag. At least this ensures proper operation out of
Anna Bridge 186:707f6e361f3e 212 * deep sleep */
Anna Bridge 186:707f6e361f3e 213 wait_loop(500);
Anna Bridge 186:707f6e361f3e 214
AnnaBridge 187:0387e8f68319 215 restore_timer_ctx();
<> 160:d5399cc887bb 216
Anna Bridge 186:707f6e361f3e 217 // Enable IRQs
AnnaBridge 187:0387e8f68319 218 core_util_critical_section_exit();
<> 154:37f96f9d4de2 219 }
<> 154:37f96f9d4de2 220
<> 154:37f96f9d4de2 221 #endif