• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /** \addtogroup hal */
3 /** @{*/
4 /* mbed Microcontroller Library
5  * Copyright (c) 2015 ARM Limited
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 #ifndef MBED_LPTICKER_API_H
21 #define MBED_LPTICKER_API_H
22 
23 #define DEVICE_LPTICKER         1
24 #define LPTICKER_DELAY_TICKS    0
25 
26 #if DEVICE_LPTICKER
27 
28 #include "ticker_api.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /**
35  * \defgroup hal_lp_ticker Low Power Ticker
36  * Low level interface to the low power ticker of a target
37  *
38  * # Defined behavior
39  * * Has a reported frequency between 4KHz and 64KHz - verified by ::lp_ticker_info_test
40  * * Has a counter that is at least 12 bits wide - verified by ::lp_ticker_info_test
41  * * Continues operating in deep sleep mode - verified by ::lp_ticker_deepsleep_test
42  * * All behavior defined by the @ref hal_ticker_shared "ticker specification"
43  *
44  * # Undefined behavior
45  * * See the @ref hal_ticker_shared "ticker specification"
46  * * Calling any function other than lp_ticker_init after calling lp_ticker_free
47  *
48  * # Potential bugs
49  * * Glitches due to ripple counter - Verified by ::lp_ticker_glitch_test
50  *
51  * @see hal_lp_ticker_tests
52  *
53  * @{
54  */
55 
56 /**
57  * \defgroup hal_lp_ticker_tests Low Power Ticker tests
58  * Tests to validate the proper implementation of the low power ticker
59  *
60  * To run the low power ticker hal tests use the command:
61  *
62  *     mbed test -t <toolchain> -m <target> -n tests-mbed_hal-common_ticker*,tests-mbed_hal-lp_ticker*
63  *
64  */
65 
66 typedef void (*ticker_irq_handler_type)(const ticker_data_t *const);
67 
68 /** Set low power ticker IRQ handler
69  *
70  * @param ticker_irq_handler IRQ handler to be connected
71  *
72  * @return previous ticker IRQ handler
73  *
74  * @note by default IRQ handler is set to ::ticker_irq_handler
75  * @note this function is primarily for testing purposes and it's not required part of HAL implementation
76  *
77  */
78 ticker_irq_handler_type set_lp_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler);
79 
80 /** Get low power ticker's data
81  *
82  * @return The low power ticker data
83  */
84 const ticker_data_t *get_lp_ticker_data(void);
85 
86 /** The wrapper for ticker_irq_handler, to pass lp ticker's data
87  *
88  */
89 void lp_ticker_irq_handler(void);
90 
91 /* HAL lp ticker */
92 
93 /** Initialize the low power ticker
94  *
95  * Initialize or re-initialize the ticker. This resets all the
96  * clocking and prescaler registers, along with disabling
97  * the compare interrupt.
98  *
99  * Pseudo Code:
100  * @code
101  * void lp_ticker_init()
102  * {
103  *     // Enable clock gate so processor can read LPTMR registers
104  *     POWER_CTRL |= POWER_CTRL_LPTMR_Msk;
105  *
106  *     // Disable the timer and ensure it is powered down
107  *     LPTMR_CTRL &= ~(LPTMR_CTRL_ENABLE_Msk | LPTMR_CTRL_COMPARE_ENABLE_Msk);
108  *
109  *     // Configure divisors - no division necessary
110  *     LPTMR_PRESCALE = 0;
111  *     LPTMR_CTRL |= LPTMR_CTRL_ENABLE_Msk;
112  *
113  *     // Install the interrupt handler
114  *     NVIC_SetVector(LPTMR_IRQn, (uint32_t)lp_ticker_irq_handler);
115  *     NVIC_EnableIRQ(LPTMR_IRQn);
116  * }
117  * @endcode
118  */
119 void lp_ticker_init(void);
120 
121 /** Deinitialize the lower power ticker
122  *
123  * Powerdown the lp ticker in preparation for sleep, powerdown, or reset.
124  *
125  * After calling this function no other ticker functions should be called except
126  * lp_ticker_init(). Calling any function other than init after freeing is
127  * undefined.
128  *
129  * @note This function stops the ticker from counting.
130  */
131 void lp_ticker_free(void);
132 
133 /** Read the current tick
134  *
135  * If no rollover has occurred, the seconds passed since lp_ticker_init()
136  * was called can be found by dividing the ticks returned by this function
137  * by the frequency returned by ::lp_ticker_get_info.
138  *
139  * @return The current timer's counter value in ticks
140  *
141  * Pseudo Code:
142  * @code
143  * uint32_t lp_ticker_read()
144  * {
145  *     uint16_t count;
146  *     uint16_t last_count;
147  *
148  *     // Loop until the same tick is read twice since this
149  *     // is ripple counter on a different clock domain.
150  *     count = LPTMR_COUNT;
151  *     do {
152  *         last_count = count;
153  *         count = LPTMR_COUNT;
154  *     } while (last_count != count);
155  *
156  *     return count;
157  * }
158  * @endcode
159  */
160 uint32_t lp_ticker_read(void);
161 
162 /** Set interrupt for specified timestamp
163  *
164  * @param timestamp The time in ticks to be set
165  *
166  * @note no special handling needs to be done for times in the past
167  * as the common timer code will detect this and call
168  * lp_ticker_fire_interrupt() if this is the case
169  *
170  * @note calling this function with timestamp of more than the supported
171  * number of bits returned by ::lp_ticker_get_info results in undefined
172  * behavior.
173  *
174  * Pseudo Code:
175  * @code
176  * void lp_ticker_set_interrupt(timestamp_t timestamp)
177  * {
178  *     LPTMR_COMPARE = timestamp;
179  *     LPTMR_CTRL |= LPTMR_CTRL_COMPARE_ENABLE_Msk;
180  * }
181  * @endcode
182  */
183 void lp_ticker_set_interrupt(timestamp_t timestamp);
184 
185 /** Disable low power ticker interrupt
186  *
187  * Pseudo Code:
188  * @code
189  * void lp_ticker_disable_interrupt(void)
190  * {
191  *     // Disable the compare interrupt
192  *     LPTMR_CTRL &= ~LPTMR_CTRL_COMPARE_ENABLE_Msk;
193  * }
194  * @endcode
195  */
196 void lp_ticker_disable_interrupt(void);
197 
198 /** Clear the low power ticker interrupt
199  *
200  * Pseudo Code:
201  * @code
202  * void lp_ticker_clear_interrupt(void)
203  * {
204  *     // Write to the ICR (interrupt clear register) of the LPTMR
205  *     LPTMR_ICR = LPTMR_ICR_COMPARE_Msk;
206  * }
207  * @endcode
208  */
209 void lp_ticker_clear_interrupt(void);
210 
211 /** Set pending interrupt that should be fired right away.
212  *
213  * Pseudo Code:
214  * @code
215  * void lp_ticker_fire_interrupt(void)
216  * {
217  *     NVIC_SetPendingIRQ(LPTMR_IRQn);
218  * }
219  * @endcode
220  */
221 void lp_ticker_fire_interrupt(void);
222 
223 /** Get frequency and counter bits of this ticker.
224  *
225  * Pseudo Code:
226  * @code
227  * const ticker_info_t* lp_ticker_get_info()
228  * {
229  *     static const ticker_info_t info = {
230  *         32768,      // 32KHz
231  *         16          // 16 bit counter
232  *     };
233  *     return &info;
234  * }
235  * @endcode
236  */
237 const ticker_info_t *lp_ticker_get_info(void);
238 void lp_ticker_read_time(uint32_t *msb, uint32_t *lsb);
239 void lp_ticker_set_match_time(uint32_t msb, uint32_t lsb);
240 void lp_ticker_set_match_time_lo(uint32_t time);
241 void lp_ticker_set_ignore_tc_hi(int ignore);
242 
243 /**@}*/
244 
245 #ifdef __cplusplus
246 }
247 #endif
248 
249 #endif
250 
251 #endif
252 
253 /** @}*/
254