mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Nov 08 13:50:44 2017 +0000
Revision:
177:d650f5d4c87a
Parent:
174:b96e65c34a4d
Child:
182:a56a73fd2a6f
This updates the lib to the mbed lib v 155

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 154:37f96f9d4de2 1 /* mbed Microcontroller Library
<> 154:37f96f9d4de2 2 * Copyright (c) 2016 ARM Limited
<> 154:37f96f9d4de2 3 *
<> 154:37f96f9d4de2 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 154:37f96f9d4de2 5 * you may not use this file except in compliance with the License.
<> 154:37f96f9d4de2 6 * You may obtain a copy of the License at
<> 154:37f96f9d4de2 7 *
<> 154:37f96f9d4de2 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 154:37f96f9d4de2 9 *
<> 154:37f96f9d4de2 10 * Unless required by applicable law or agreed to in writing, software
<> 154:37f96f9d4de2 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 154:37f96f9d4de2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 154:37f96f9d4de2 13 * See the License for the specific language governing permissions and
<> 154:37f96f9d4de2 14 * limitations under the License.
<> 154:37f96f9d4de2 15 */
<> 154:37f96f9d4de2 16
<> 154:37f96f9d4de2 17 #if DEVICE_LOWPOWERTIMER
<> 154:37f96f9d4de2 18
<> 154:37f96f9d4de2 19 #include "lp_ticker_api.h"
<> 154:37f96f9d4de2 20 #include "fsl_rtc.h"
<> 154:37f96f9d4de2 21 #include "fsl_lptmr.h"
<> 154:37f96f9d4de2 22 #include "cmsis.h"
<> 154:37f96f9d4de2 23 #include "rtc_api.h"
<> 154:37f96f9d4de2 24
<> 154:37f96f9d4de2 25 #define MAX_SEC_BITS (12)
<> 154:37f96f9d4de2 26 #define MAX_SEC_MASK ((1 << MAX_SEC_BITS) - 1)
<> 154:37f96f9d4de2 27 #define SEC_IN_USEC (1000000)
<> 154:37f96f9d4de2 28 #define OSC32K_CLK_HZ (32768)
<> 154:37f96f9d4de2 29 #define MAX_LPTMR_SLEEP ((1 << 16) - 1)
<> 154:37f96f9d4de2 30
<> 154:37f96f9d4de2 31 static bool lp_ticker_inited = false;
<> 154:37f96f9d4de2 32 static int lptmr_schedule = 0;
<> 154:37f96f9d4de2 33
<> 154:37f96f9d4de2 34 static void rtc_isr(void)
<> 154:37f96f9d4de2 35 {
AnnaBridge 167:e84263d55307 36 uint32_t sr = RTC->SR;
AnnaBridge 167:e84263d55307 37 if (sr & RTC_SR_TOF_MASK) {
AnnaBridge 167:e84263d55307 38 // Reset RTC to 0 so it keeps counting
AnnaBridge 167:e84263d55307 39 RTC_StopTimer(RTC);
AnnaBridge 167:e84263d55307 40 RTC->TSR = 0;
AnnaBridge 167:e84263d55307 41 RTC_StartTimer(RTC);
AnnaBridge 167:e84263d55307 42 } else if (sr & RTC_SR_TAF_MASK) {
AnnaBridge 167:e84263d55307 43 RTC_DisableInterrupts(RTC, kRTC_AlarmInterruptEnable);
AnnaBridge 167:e84263d55307 44 RTC->TAR = 0; /* Write clears the IRQ flag */
<> 154:37f96f9d4de2 45
AnnaBridge 167:e84263d55307 46 /* Wait subsecond remainder if any */
AnnaBridge 167:e84263d55307 47 if (lptmr_schedule) {
AnnaBridge 167:e84263d55307 48 LPTMR_SetTimerPeriod(LPTMR0, lptmr_schedule);
AnnaBridge 167:e84263d55307 49 LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
AnnaBridge 167:e84263d55307 50 LPTMR_StartTimer(LPTMR0);
AnnaBridge 167:e84263d55307 51 } else {
AnnaBridge 167:e84263d55307 52 lp_ticker_irq_handler();
AnnaBridge 167:e84263d55307 53 }
AnnaBridge 167:e84263d55307 54 } else if (sr & RTC_SR_TIF_MASK) {
AnnaBridge 167:e84263d55307 55 RTC_DisableInterrupts(RTC, kRTC_TimeOverflowInterruptEnable);
<> 154:37f96f9d4de2 56 }
<> 154:37f96f9d4de2 57 }
<> 154:37f96f9d4de2 58
<> 154:37f96f9d4de2 59 static void lptmr_isr(void)
<> 154:37f96f9d4de2 60 {
<> 154:37f96f9d4de2 61 LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
<> 154:37f96f9d4de2 62 LPTMR_StopTimer(LPTMR0);
<> 154:37f96f9d4de2 63
<> 154:37f96f9d4de2 64 lp_ticker_irq_handler();
<> 154:37f96f9d4de2 65 }
<> 154:37f96f9d4de2 66
<> 154:37f96f9d4de2 67 /** Initialize the low power ticker
<> 154:37f96f9d4de2 68 *
<> 154:37f96f9d4de2 69 */
<> 154:37f96f9d4de2 70 void lp_ticker_init(void)
<> 154:37f96f9d4de2 71 {
<> 154:37f96f9d4de2 72 lptmr_config_t lptmrConfig;
<> 154:37f96f9d4de2 73
<> 154:37f96f9d4de2 74 if (lp_ticker_inited) {
<> 154:37f96f9d4de2 75 return;
<> 154:37f96f9d4de2 76 }
<> 154:37f96f9d4de2 77 lp_ticker_inited = true;
<> 154:37f96f9d4de2 78
<> 154:37f96f9d4de2 79 /* Setup low resolution clock - RTC */
<> 154:37f96f9d4de2 80 if (!rtc_isenabled()) {
<> 154:37f96f9d4de2 81 rtc_init();
<> 154:37f96f9d4de2 82 RTC_DisableInterrupts(RTC, kRTC_AlarmInterruptEnable | kRTC_SecondsInterruptEnable);
<> 154:37f96f9d4de2 83 RTC_StartTimer(RTC);
<> 154:37f96f9d4de2 84 }
<> 154:37f96f9d4de2 85
AnnaBridge 167:e84263d55307 86 RTC->TAR = 0; /* Write clears the IRQ flag */
<> 154:37f96f9d4de2 87 NVIC_ClearPendingIRQ(RTC_IRQn);
<> 154:37f96f9d4de2 88 NVIC_SetVector(RTC_IRQn, (uint32_t)rtc_isr);
<> 154:37f96f9d4de2 89 NVIC_EnableIRQ(RTC_IRQn);
<> 154:37f96f9d4de2 90
<> 154:37f96f9d4de2 91 /* Setup high resolution clock - LPTMR */
<> 154:37f96f9d4de2 92 LPTMR_GetDefaultConfig(&lptmrConfig);
<> 154:37f96f9d4de2 93 /* Use 32kHz drive */
<> 154:37f96f9d4de2 94 CLOCK_SetXtal32Freq(OSC32K_CLK_HZ);
<> 154:37f96f9d4de2 95 lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_2;
<> 154:37f96f9d4de2 96 LPTMR_Init(LPTMR0, &lptmrConfig);
<> 154:37f96f9d4de2 97 LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
<> 154:37f96f9d4de2 98 NVIC_ClearPendingIRQ(LPTMR0_IRQn);
<> 154:37f96f9d4de2 99 NVIC_SetVector(LPTMR0_IRQn, (uint32_t)lptmr_isr);
<> 154:37f96f9d4de2 100 EnableIRQ(LPTMR0_IRQn);
<> 154:37f96f9d4de2 101 }
<> 154:37f96f9d4de2 102
<> 154:37f96f9d4de2 103 /** Read the current counter
<> 154:37f96f9d4de2 104 *
<> 154:37f96f9d4de2 105 * @return The current timer's counter value in microseconds
<> 154:37f96f9d4de2 106 */
<> 154:37f96f9d4de2 107 uint32_t lp_ticker_read(void)
<> 154:37f96f9d4de2 108 {
<> 154:37f96f9d4de2 109 uint32_t sec, pre;
<> 154:37f96f9d4de2 110
<> 154:37f96f9d4de2 111 if (!lp_ticker_inited) {
<> 154:37f96f9d4de2 112 lp_ticker_init();
<> 154:37f96f9d4de2 113 }
<> 154:37f96f9d4de2 114
<> 154:37f96f9d4de2 115 sec = RTC->TSR; /* 32b: Seconds */
<> 154:37f96f9d4de2 116 pre = RTC->TPR; /* 16b: Increments every 32.768kHz clock cycle (30us) */
<> 154:37f96f9d4de2 117
<> 154:37f96f9d4de2 118 /* Final value: 11b (4095) for sec and 21b for usec (pre can reach 1,000,000us which is close to 1<<20) */
<> 154:37f96f9d4de2 119 uint32_t ret = (((sec & MAX_SEC_MASK) * SEC_IN_USEC) + (((uint64_t)pre * SEC_IN_USEC) / OSC32K_CLK_HZ));
<> 154:37f96f9d4de2 120
<> 154:37f96f9d4de2 121 return ret;
<> 154:37f96f9d4de2 122 }
<> 154:37f96f9d4de2 123
<> 154:37f96f9d4de2 124 /** Set interrupt for specified timestamp
<> 154:37f96f9d4de2 125 *
<> 154:37f96f9d4de2 126 * @param timestamp The time in microseconds to be set
<> 154:37f96f9d4de2 127 */
<> 154:37f96f9d4de2 128 void lp_ticker_set_interrupt(timestamp_t timestamp)
<> 154:37f96f9d4de2 129 {
<> 154:37f96f9d4de2 130 uint32_t now_us, delta_us, delta_ticks;
<> 154:37f96f9d4de2 131
<> 154:37f96f9d4de2 132 if (!lp_ticker_inited) {
<> 154:37f96f9d4de2 133 lp_ticker_init();
<> 154:37f96f9d4de2 134 }
<> 154:37f96f9d4de2 135
<> 154:37f96f9d4de2 136 lptmr_schedule = 0;
<> 154:37f96f9d4de2 137 now_us = lp_ticker_read();
<> 154:37f96f9d4de2 138 delta_us = timestamp > now_us ? timestamp - now_us : (uint32_t)((uint64_t)timestamp + 0xFFFFFFFF - now_us);
<> 154:37f96f9d4de2 139
<> 154:37f96f9d4de2 140 /* Checking if LPTRM can handle this sleep */
<> 154:37f96f9d4de2 141 delta_ticks = USEC_TO_COUNT(delta_us, CLOCK_GetFreq(kCLOCK_Er32kClk));
AnnaBridge 177:d650f5d4c87a 142 if (delta_ticks == 0) {
AnnaBridge 177:d650f5d4c87a 143 /* The requested delay is less than the minimum resolution of this counter */
AnnaBridge 177:d650f5d4c87a 144 delta_ticks = 1;
AnnaBridge 177:d650f5d4c87a 145 }
AnnaBridge 177:d650f5d4c87a 146
<> 154:37f96f9d4de2 147 if (delta_ticks > MAX_LPTMR_SLEEP) {
<> 154:37f96f9d4de2 148 /* Using RTC if wait time is over 16b (2s @32kHz) */
<> 154:37f96f9d4de2 149 uint32_t delta_sec;
<> 154:37f96f9d4de2 150
<> 154:37f96f9d4de2 151 delta_us += COUNT_TO_USEC(RTC->TPR, CLOCK_GetFreq(kCLOCK_Er32kClk)); /* Accounting for started second */
<> 154:37f96f9d4de2 152 delta_sec = delta_us / SEC_IN_USEC;
<> 154:37f96f9d4de2 153 delta_us -= delta_sec * SEC_IN_USEC;
<> 154:37f96f9d4de2 154
<> 154:37f96f9d4de2 155 RTC->TAR = RTC->TSR + delta_sec - 1;
<> 154:37f96f9d4de2 156
<> 154:37f96f9d4de2 157 RTC_EnableInterrupts(RTC, kRTC_AlarmInterruptEnable);
<> 154:37f96f9d4de2 158
<> 154:37f96f9d4de2 159 /* Set aditional, subsecond, sleep time */
<> 154:37f96f9d4de2 160 if (delta_us) {
<> 154:37f96f9d4de2 161 lptmr_schedule = USEC_TO_COUNT(delta_us, CLOCK_GetFreq(kCLOCK_Er32kClk));
AnnaBridge 177:d650f5d4c87a 162 if (lptmr_schedule == 0) {
AnnaBridge 177:d650f5d4c87a 163 /* The requested delay is less than the minimum resolution of this counter */
AnnaBridge 177:d650f5d4c87a 164 lptmr_schedule = 1;
AnnaBridge 177:d650f5d4c87a 165 }
AnnaBridge 177:d650f5d4c87a 166
<> 154:37f96f9d4de2 167 }
<> 154:37f96f9d4de2 168 } else {
<> 154:37f96f9d4de2 169 /* Below RTC resolution using LPTMR */
<> 154:37f96f9d4de2 170 LPTMR_SetTimerPeriod(LPTMR0, delta_ticks);
<> 154:37f96f9d4de2 171 LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
<> 154:37f96f9d4de2 172 LPTMR_StartTimer(LPTMR0);
<> 154:37f96f9d4de2 173 }
<> 154:37f96f9d4de2 174 }
<> 154:37f96f9d4de2 175
AnnaBridge 174:b96e65c34a4d 176 void lp_ticker_fire_interrupt(void)
AnnaBridge 174:b96e65c34a4d 177 {
AnnaBridge 174:b96e65c34a4d 178 NVIC_SetPendingIRQ(LPTMR0_IRQn);
AnnaBridge 174:b96e65c34a4d 179 }
AnnaBridge 174:b96e65c34a4d 180
<> 154:37f96f9d4de2 181 /** Disable low power ticker interrupt
<> 154:37f96f9d4de2 182 *
<> 154:37f96f9d4de2 183 */
<> 154:37f96f9d4de2 184 void lp_ticker_disable_interrupt(void)
<> 154:37f96f9d4de2 185 {
<> 154:37f96f9d4de2 186 LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
<> 154:37f96f9d4de2 187 RTC_DisableInterrupts(RTC, kRTC_AlarmInterruptEnable);
<> 154:37f96f9d4de2 188 }
<> 154:37f96f9d4de2 189
<> 154:37f96f9d4de2 190 /** Clear the low power ticker interrupt
<> 154:37f96f9d4de2 191 *
<> 154:37f96f9d4de2 192 */
<> 154:37f96f9d4de2 193 void lp_ticker_clear_interrupt(void)
<> 154:37f96f9d4de2 194 {
<> 154:37f96f9d4de2 195 RTC->TAR = 0; /* Write clears the IRQ flag */
<> 154:37f96f9d4de2 196 LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
<> 154:37f96f9d4de2 197 }
AnnaBridge 174:b96e65c34a4d 198
<> 154:37f96f9d4de2 199 #endif /* DEVICE_LOWPOWERTIMER */