1 /*
2  * Copyright (c) 2017-2019, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*!*****************************************************************************
33  *  @file       TimerCC32XX.h
34  *  @brief      Timer driver interface for CC32XX devices
35  *
36  *  # Operation #
37  *  This driver implements half and full width general purpose timers for the
38  *  CC32XX device. For CC32XX devices, the system clock is 80 MHz and a 16-bit
39  *  timer has an 8-bit prescaler. The desired period may not always be
40  *  achieved due to hardware limitations, such as the aforementioned. The timer
41  *  resolution is limited to 12.5ns due to the 80 MHz clock. A timer period no
42  *  greater than 209,714us can be achieved when operating in 16-bit mode.
43  *  Similarly, a period no greater than 53,687,090us can be achieved when
44  *  operating in 32-bit mode. The same time constraints apply to the 16-bit
45  *  timer when attempting to use a frequency less than 5 Hertz. For additional
46  *  details, refer to the device's technical reference manual.
47  *
48  *  The timer always operates in count down mode. When using a half width timer,
49  *  an 8-bit prescaler will be implemented by the driver if necessary. If the
50  *  timer is operating in Timer_FREE_RUNNING, the timer will count down from the
51  *  specified period to 0 before restarting.
52  *
53  *  When using a half width timer, Timer_getCount() will return the
54  *  value of the counter in bits 15:0 and bits 23:16 will contain the
55  *  current free-running value of the prescaler. Bits 31:24 are always 0.
56  *  When using a full width timer, Timer_getCount() will return the
57  *  the value of the 32-bit timer.
58  *
59  *  #Timer_ONESHOT_CALLBACK is non-blocking. After Timer_start() is called,
60  *  the calling thread will continue execution. When the timer interrupt
61  *  is triggered, the specified callback function will be called. The timer
62  *  will not generate another interrupt unless Timer_start() is called again.
63  *  Calling Timer_stop() or Timer_close() after Timer_start() but, before the
64  *  timer interrupt, will prevent the specified callback from ever being
65  *  invoked.
66  *
67  *  #Timer_ONESHOT_BLOCKING is a blocking call. A semaphore is used to block
68  *  the calling thead's execution until the timer generates an interrupt. If
69  *  Timer_stop() is called, the calling thread will become unblocked
70  *  immediately. The behavior of the timer in this mode is similar to a sleep
71  *  function.
72  *
73  *  #Timer_CONTINUOUS_CALLBACK is non-blocking. After Timer_start() is called,
74  *  the calling thread will continue execution. When the timer interrupt is
75  *  treiggered, the specified callback function will be called. The timer is
76  *  automatically restarted and will continue to periodically generate
77  *  interrupts until Timer_stop() is called.
78  *
79  *  #Timer_FREE_RUNNING is non-blocking. After Timer_start() is called,
80  *  the calling thread will continue execution. The timer will not
81  *  generate an interrupt in this mode. The timer will count down from the
82  *  specified period until it reaches 0. The timer will automatically reload
83  *  the period and start over. The timer will continue running until
84  *  Timer_stop() is called.
85  *
86  *  # Resource Allocation #
87  *  Each general purpose timer block contains two timers, Timer A and Timer B,
88  *  that can be configured to operate independently; or concatenated to operate
89  *  as one 32-bit timer. This behavior is managed through a set of resource
90  *  allocation APIs. For example, the TimerCC32XX_allocateTimerResource API
91  *  will allocate a timer for exclusive use. Any attempt to allocate this
92  *  resource in the future will result in a false value being returned from the
93  *  allocation API. To free a timer resource, the TimerCC32XX_freeTimerResource
94  *  is used. The application is not responsible for calling these allocation
95  * APIs directly.
96  *
97  *  ============================================================================
98  */
99 
100 #ifndef ti_drivers_timer_TimerCC32XX__include
101 #define ti_drivers_timer_TimerCC32XX__include
102 
103 #include <stdbool.h>
104 #include <stdint.h>
105 
106 #include <ti/drivers/Timer.h>
107 #include <ti/drivers/Power.h>
108 #include <ti/drivers/dpl/HwiP.h>
109 #include <ti/drivers/dpl/SemaphoreP.h>
110 
111 #ifdef __cplusplus
112 extern "C"
113 {
114 #endif
115 
116 /*!
117  *  @def    TimerCC32XX_SubTimer
118  *
119  *  @brief  Sub-timers on the CC32XX
120  *
121  *  The timer peripheral supports full width and half width timer operation.
122  *  Use the definitions in this enumerated type to specify a full width timer
123  *  (32-bit) or half width timer (16-bit) in the hardware attributes. There are
124  *  two half width timers per single timer peripheral. A 16-bit timer on this
125  *  device has an 8-bit prescaler.
126  */
127 typedef enum {
128     TimerCC32XX_timer16A = 0x0001,    /*!< Half width timer A */
129     TimerCC32XX_timer16B = 0x0002,    /*!< Half width timer B */
130     TimerCC32XX_timer32  = 0x0003,    /*!< Full width timer   */
131 } TimerCC32XX_SubTimer;
132 
133 extern const Timer_FxnTable TimerCC32XX_fxnTable;
134 
135 /*!
136  *  @brief TimerCC32XX Hardware Attributes
137  *
138  *  Timer hardware attributes that tell the TimerCC32XX driver specific hardware
139  *  configurations and interrupt/priority settings.
140  *
141  *  A sample structure is shown below:
142  *  @code
143  *  const TimerCC32XX_HWAttrs timerCC32XXHWAttrs[] =
144  *  {
145  *      {
146  *          .baseAddress = TIMERA0_BASE,
147  *          .subTimer = TimerCC32XX_timer32,
148  *          .intNum = INT_TIMERA0A,
149  *          .intPriority = ~0
150  *      },
151  *      {
152  *          .baseAddress = TIMERA1_BASE,
153  *          .subTimer = TimerCC32XX_timer16A,
154  *          .intNum = INT_TIMERA1A,
155  *          .intPriority = ~0
156  *      },
157  *      {
158  *          .baseAddress = TIMERA1_BASE,
159  *          .subTimer = TimerCC32XX_timer16B,
160  *          .intNum = INT_TIMERA1B,
161  *          .intPriority = ~0
162  *      }
163  *  };
164  *  @endcode
165  */
166 typedef struct {
167     /*! The base address of the timer peripheral. */
168     uint32_t             baseAddress;
169 
170     /*! Specifies a full width timer or half-width timer. */
171     TimerCC32XX_SubTimer subTimer;
172 
173     /*! The hardware interrupt number for the timer peripheral. */
174     uint32_t             intNum;
175 
176     /*! The interrupt priority. */
177     uint32_t             intPriority;
178 } TimerCC32XX_HWAttrs;
179 
180 /*!
181  *  @brief TimerCC32XX_Object
182  *
183  *  The application must not access any member variables of this structure!
184  */
185 typedef struct {
186     HwiP_Handle         hwiHandle;
187     Power_NotifyObj     notifyObj;
188     SemaphoreP_Handle   timerSem;
189     Timer_CallBackFxn   callBack;
190     Timer_Mode          mode;
191     uint32_t            timer;
192     uint32_t            period;
193     uint32_t            prescaler;
194     bool                isRunning;
195 } TimerCC32XX_Object;
196 
197 /*!
198  *  @brief  Function to allocate a timer peripheral.
199  *
200  *  This function is intended to be used by any driver which implements a
201  *  timer hardware peripheral. Calling this function will enable power to the
202  *  timer peripheral specified by the parameter, baseAddress.
203  *
204  *  @param  baseAddress The base address of a timer hardware peripheral.
205  *
206  *  @param  subTimer    The TimerCC32XX_subTimer to be allocated.
207  *
208  *  @return A bool returning true if the timer resource was successfully
209  *          allocated. If the base address is not valid or if the resource is
210  *          not available, false is returned.
211  *
212  *  @sa     TimerCC32XX_freeTimerResource()
213  */
214 extern bool TimerCC32XX_allocateTimerResource(uint32_t baseAddress,
215     TimerCC32XX_SubTimer subTimer);
216 
217 /*!
218  *  @brief  Function to de-allocate a timer peripheral.
219  *
220  *  This function is intended to be used by any driver which implements a
221  *  timer hardware peripheral. Calling this function will disable power to the
222  *  timer peripheral specified by the parameter, baseAddress, if and only if
223  *  the timer peripheral is no longer in use.
224  *
225  *  @pre    A successful call to TimerCC32XX_allocateTimerResource() using the
226  *          baseAddress and subTimer must have been made prior to calling this
227  *          API.
228  *
229  *  @param  baseAddress The base address of a timer hardware peripheral.
230  *
231  *  @param  subTimer    The TimerCC32XX_subTimer to be freed.
232  *
233  *  @sa     TimerCC32XX_allocateTimerResource()
234  */
235 extern void TimerCC32XX_freeTimerResource(uint32_t baseAddress,
236     TimerCC32XX_SubTimer subTimer);
237 
238 #ifdef __cplusplus
239 }
240 #endif
241 
242 #endif /* ti_drivers_timer_TimerCC32XX__include */
243