1 /**
2  * \file
3  *
4  * \brief SAM DUALTIMER Driver for SAMB11
5  *
6  * Copyright (C) 2015 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #ifndef DUALTIMER_H_INCLUDED
47 #define DUALTIMER_H_INCLUDED
48 
49 /**
50  * \defgroup asfdoc_samb_dualtimer_group SAM DUALTIMER
51  *
52  * This driver for Atmel&reg; | SMART SAM devices provides an interface for the
53  * configuration and management of the device's DUALTIMER functionality.
54  *
55  * The following peripherals are used by this module:
56  *  - DUALTIMER
57  *
58  * The following devices can use this module:
59  *  - Atmel | SMART SAM B11
60  *
61  * The outline of this documentation is as follows:
62  *  - \ref asfdoc_samb_dualtimer_prerequisites
63  *  - \ref asfdoc_samb_dualtimer_module_overview
64  *  - \ref asfdoc_samb_dualtimer_special_considerations
65  *  - \ref asfdoc_samb_dualtimer_extra_info
66  *  - \ref asfdoc_samb_dualtimer_examples
67  *  - \ref asfdoc_samb_dualtimer_api_overview
68  *
69  *
70  * \section asfdoc_samb_dualtimer_prerequisites Prerequisites
71  *
72  * There are no prerequisites for this module.
73  *
74  *
75  * \section asfdoc_samb_dualtimer_module_overview Module Overview
76  *  The dual-input timers module provides a set of timing and counting related functionality,
77  * and each timer could setup respective. The module can be configured to use an 16-,
78  * or 32-bit down-counter that can generate interrupts when they reach 0.
79  *
80  * \subsection asfdoc_samb_dual_timer_module_overview_counter_mode Counter Mode
81  * For each timer, the following modes of operation are available:
82  * - One-shot timer mode
83  *
84  *   The counter generates an interrupt once. When the counter reaches 0,
85  *   it halts until you reprogram it. You can do this using one of the following:
86  *
87  *   1. Clearing the one-shot count bit in the control register, in which case the
88  *     count proceeds according to the selection of Free-running or Periodic mode.
89  *
90  *   2. Writing a new value to the Load Value register.
91  * - Free-running Mode
92  *
93  *   The counter wraps after reaching its zero value, and continues to count down from
94  *   the maximum value. This is the default mode.
95  * - Periodic Mode
96  *
97  *   The counter generates an interrupt at a constant interval, reloading the original
98  *   value after wrapping past zero.
99  *
100  * \subsection asfdoc_samb_dual_timer_module_overview_counter_size Counter Size
101  * Each timer module can be configured in one of two different counter
102  * sizes; 16-, and 32-bit. The size of the counter determines the maximum
103  * value it can count to before an overflow occurs and the count is reset back
104  * to zero. \ref asfdoc_sam0_count_size_vs_top "The table below" shows the
105  * maximum values for each of the possible counter sizes.
106  *
107  * \anchor asfdoc_sam0_count_size_vs_top
108  * <table>
109  *  <caption>Timer Counter Sizes and Their Maximum Count Values</caption>
110  *  <tr>
111  *    <th>Counter size</th>
112  *    <th>Max. (hexadecimal)</th>
113  *    <th>Max. (decimal)</th>
114  *  </tr>
115  *  <tr>
116  *    <td>16-bit</td>
117  *    <td>0xFFFF</td>
118  *    <td>65,535</td>
119  *  </tr>
120  *  <tr>
121  *    <td>32-bit</td>
122  *    <td>0xFFFFFFFF</td>
123  *    <td>4,294,967,295</td>
124  *  </tr>
125  * </table>
126  *
127  * \subsection asfdoc_samb_dual_timer_module_overview_clock Clock Settings
128  *
129  * \subsubsection asfdoc_sam0_dual_timer_module_overview_clock_selection Clock Selection
130  * The timers contain the PCLK and TIMCLK clock inputs. PCLK is the main APB system
131  * clock, and is used by the register interface. TIMCLK is the input to the prescale
132  * units and the decrementing counters.
133  *
134  * This provision of two clock inputs enables the counters to continue to run while
135  * the APB system is in a sleep state when PCLK is disabled. External system control
136  * logic must handle the changeover periods when PCLK is disabled and enabled to ensure
137  * that the PCLK and TIMCLK inputs are fed with synchronous signals when any register
138  * access is to occur.
139  *
140  * \subsubsection asfdoc_sam0_dual_timer_module_overview_clock_prescaler Prescaler
141  * Each timer module in the SAM B11 has its own individual clock prescaler, which can
142  * be used to divide the input clock frequency used in the counter. This prescaler
143  * only scales the clock used to provide clock pulses for the counter to count, the clock
144  * can be divide to 1, 16, or 256.
145  *
146  * \section asfdoc_samb_dualtimer_special_considerations Special Considerations
147  *
148  * There are no special considerations for this module.
149  *
150  * \section asfdoc_samb_dualtimer_extra_info Extra Information
151  *
152  * For extra information, see \ref asfdoc_samb_dualtimer_extra. This includes:
153  *  - \ref asfdoc_samb_dualtimer_extra_acronyms
154  *  - \ref asfdoc_samb_dualtimer_extra_dependencies
155  *  - \ref asfdoc_samb_dualtimer_extra_errata
156  *  - \ref asfdoc_samb_dualtimer_extra_history
157  *
158  *
159  * \section asfdoc_samb_dualtimer_examples Examples
160  *
161  * For a list of examples related to this driver, see
162  * \ref asfdoc_samb_dualtimer_exqsg.
163  *
164  *
165  * \section asfdoc_samb_dualtimer_api_overview API Overview
166  * @{
167  */
168 
169 #include <compiler.h>
170 #include <system_sam_b.h>
171 
172 #ifdef __cplusplus
173 extern "C" {
174 #endif
175 
176 /** Type definition for a DUALTIMER module callback function. */
177 typedef void (*dualtimer_callback_t)(void);
178 
179 /**
180  * \brief Specifies the timer1 or timer2.
181  *
182  * This enum specifies duatimer timer1 or timer2.
183  */
184 enum dualtimer_timer {
185 	/** Dualtimer timer1 */
186 	DUALTIMER_TIMER1 = 0,
187 	/** Dualtimer timer2 */
188 	DUALTIMER_TIMER2,
189 };
190 
191 /**
192  * \brief DUALTIMER module clock input.
193  *
194  * DUALTIMER module clock.
195  */
196 enum dualtimer_clock_input {
197 	/** source from clock input 0: 26MHz */
198 	DUALTIMER_CLK_INPUT_0 = 0,
199 	/** source from clock input 1: 13MHz */
200 	DUALTIMER_CLK_INPUT_1,
201 	/** source from clock input 2: 6.5MHz */
202 	DUALTIMER_CLK_INPUT_2,
203 	/** source from clock input 3: 3MHz*/
204 	DUALTIMER_CLK_INPUT_3,
205 };
206 
207 /**
208  * \brief Specifies if the counter is 16-bit, or 32-bit.
209  *
210  * This enum specifies counter with one-shot, free running or periodic counter mode.
211  */
212 enum dualtimer_counter_mode {
213 	/** Counter in one-shot mode */
214 	DUALTIMER_ONE_SHOT_MODE = 0,
215 	/** Counter is in free-running mode */
216 	DUALTIMER_FREE_RUNNING_MODE,
217 	/** Counter is in periodic mode */
218 	DUALTIMER_PERIODIC_MODE,
219 };
220 
221 /**
222  * \brief Dualtimer counter mode enum.
223  *
224  * This enum specify the maximum value it is possible to count to.
225  */
226 enum dualtimer_counter_size {
227 	/** 16-bit counter */
228 	DUALTIMER_COUNTER_SIZE_16BIT = 0,
229 	/** 32-bit counter */
230 	DUALTIMER_COUNTER_SIZE_32BIT,
231 };
232 
233 /**
234  * \brief Dualtimer clock prescaler values.
235  *
236  * This enum is used to choose the clock prescaler
237  * configuration. The prescaler divides the clock frequency of the
238  * Dual Timer module to make the counter count slower.
239  */
240 enum dualtimer_clock_prescaler {
241 	/** Divide clock by 1 */
242 	DUALTIMER_CLOCK_PRESCALER_DIV1 = 0,
243 	/** Divide clock by 16 */
244 	DUALTIMER_CLOCK_PRESCALER_DIV16,
245 	/** Divide clock by 256 */
246 	DUALTIMER_CLOCK_PRESCALER_DIV256,
247 };
248 
249 /**
250  * \brief Dualtimer set counter.
251  *
252  * This enum is used to choose set the load register or
253  * background load register. The difference to set load
254  * register is that writes to background register do not
255  * cause the counter to immediately restart from the new value.
256  */
257 enum dualtimer_set_register {
258 	/** Set current counter */
259 	DUALTIMER_SET_CURRUNT_REG = 0,
260 	/** Set background counter */
261 	DUALTIMER_SET_BG_REG,
262 };
263 
264 /**
265  * \brief Dualtimer private configuration structure.
266  *
267  * Private configuration struct for Dualtimer instance.
268  */
269 struct dualtimer_private_config {
270 	/** Enable timer */
271 	bool timer_enable;
272 	/** Selects one-shot or wrapping counter mode */
273 	enum dualtimer_counter_mode counter_mode;
274 	/** Selects 16-bit or 32- bit counter size */
275 	enum dualtimer_counter_size counter_size;
276 	/** Selects the prescaler value */
277 	enum dualtimer_clock_prescaler clock_prescaler;
278 	/** Enable the interrupt */
279 	bool interrup_enable;
280 	/** Counter load value */
281 	uint32_t load_value;
282 };
283 
284 /**
285  * \brief Dualtimer configuration structure.
286  *
287  * Configuration struct for Dualtimer instance. This structure should be
288  * initialized by the \ref dualtimer_get_config_defaults function before being
289  * modified by the user application.
290  */
291 struct dualtimer_config {
292 	/** Timer1 private configuration */
293 	struct dualtimer_private_config timer1;
294 	/** Timer2 private configuration */
295 	struct dualtimer_private_config timer2;
296 	/** Selects Dualtimer clock frequency */
297 	enum dualtimer_clock_input clock_source;
298 };
299 
300 /**
301  * \name Configuration and Initialization
302  * @{
303  */
304 void dualtimer_get_config_defaults(struct dualtimer_config *config);
305 void dualtimer_init(const struct dualtimer_config *config);
306 /** @} */
307 
308 /**
309  * \name Get and set value
310  * @{
311  */
312 uint32_t dualtimer_get_value(enum dualtimer_timer timer);
313 void dualtimer_set_counter(enum dualtimer_timer timer,
314 		enum dualtimer_set_register cur_bg, uint32_t value);
315 /** @} */
316 
317 /**
318  * \name Get and Clear status
319  * @{
320  */
321 uint8_t dualtimer_get_status(enum dualtimer_timer timer);
322 uint8_t dualtimer_get_interrupt_status(enum dualtimer_timer timer);
323 void dualtimer_clear_interrupt_status(enum dualtimer_timer timer);
324 /** @} */
325 
326 /**
327  * \name Enable and disable module
328  * @{
329  */
330 void dualtimer_enable(enum dualtimer_timer timer);
331 void dualtimer_disable(enum dualtimer_timer timer);
332 /** @} */
333 
334 /**
335  * \name Callback
336  * @{
337  */
338 void dualtimer_register_callback(enum dualtimer_timer timer, dualtimer_callback_t fun);
339 void dualtimer_unregister_callback(enum dualtimer_timer timer);
340 /** @} */
341 
342 /** @}*/
343 
344 #ifdef __cplusplus
345 }
346 #endif
347 
348 /**
349  * \page asfdoc_samb_dualtimer_extra Extra Information for DUALTIMER Driver
350  *
351  * \section asfdoc_samb_dualtimer_extra_acronyms Acronyms
352  * Below is a table listing the acronyms used in this module, along with their
353  * intended meanings.
354  * <table>
355  *	<tr>
356  *		<th>Acronym</th>
357  *		<th>Description</th>
358  *	</tr>
359  *	<tr>
360  *		<td>DUALTIMER</td>
361  *		<td>Dualtimer</td>
362  *	</tr>
363  * </table>
364  *
365  * \section asfdoc_samb_dualtimer_extra_dependencies Dependencies
366  * There are no dependencies related to this driver.
367  *
368  *
369  * \section asfdoc_samb_dualtimer_extra_errata Errata
370  * There are no errata related to this driver.
371  *
372  *
373  * \section asfdoc_samb_dualtimer_extra_history Module History
374  * An overview of the module history is presented in the table below, with
375  * details on the enhancements and fixes made to the module since its first
376  * release. The current version of this corresponds to the newest version in
377  * the table.
378  *
379  * <table>
380  *  <tr>
381  *      <th>Changelog</th>
382  *  </tr>
383  *  <tr>
384  *      <td>Initial Release</td>
385  *  </tr>
386  * </table>
387  */
388 
389 /**
390  * \page asfdoc_samb_dualtimer_exqsg Examples for DUALTIMER Driver
391  *
392  * This is a list of the available Quick Start guides (QSGs) and example
393  * applications for \ref asfdoc_samb_dualtimer_group. QSGs are simple examples with
394  * step-by-step instructions to configure and use this driver in a selection of
395  * use cases. Note that QSGs can be compiled as a standalone application or be
396  * added to the user application.
397  *
398  *  - \subpage asfdoc_samb_dualtimer_basic_use_case
399  *
400  * \page asfdoc_samb_dualtimer_document_revision_history Document Revision History
401  *
402  * <table>
403  *  <tr>
404  *    <th>Doc. Rev.</td>
405  *    <th>Date</td>
406  *    <th>Comments</td>
407  *  </tr>
408  *  <tr>
409  *    <td>A</td>
410  *    <td>09/2015</td>
411  *    <td>Initial release</td>
412  *  </tr>
413  * </table>
414  */
415 
416 #endif