Fri, 13 Aug 2010 10:49:23 +0100
Initial import, Timer v3.0
1 /****************************************************************************
2 **
3 ** Name: MicoTimer.c
4 **
5 ** Description:
6 ** Implements functions for manipulating LatticeMico32 Timer
7 **
8 ** $Revision: $
9 **
10 ** Disclaimer:
11 **
12 ** This source code is intended as a design reference which
13 ** illustrates how these types of functions can be implemented. It
14 ** is the user's responsibility to verify their design for
15 ** consistency and functionality through the use of formal
16 ** verification methods. Lattice Semiconductor provides no warranty
17 ** regarding the use or functionality of this code.
18 **
19 ** --------------------------------------------------------------------
20 **
21 ** Lattice Semiconductor Corporation
22 ** 5555 NE Moore Court
23 ** Hillsboro, OR 97214
24 ** U.S.A
25 **
26 ** TEL: 1-800-Lattice (USA and Canada)
27 ** (503)268-8001 (other locations)
28 **
29 ** web: http://www.latticesemi.com
30 ** email: techsupport@latticesemi.com
31 **
32 ** --------------------------------------------------------------------------
33 **
34 ** Change History (Latest changes on top)
35 **
36 ** Ver Date Description
37 ** --------------------------------------------------------------------------
38 **
39 ** 3.0 Mar-25-2008 Added Header
40 **
41 **---------------------------------------------------------------------------
42 *****************************************************************************/
45 #include "MicoTimer.h"
46 #include "MicoTimerService.h"
47 #include "MicoMacros.h"
48 #include "MicoInterrupts.h"
52 /**************************************************************************
53 * driver-debug functions *
54 **************************************************************************/
55 #if _MICO_TIMER_DRIVER_DEBUG_ENABLED_
56 static void MicoTimerDumpCtx(MicoTimerCtx_t *pCtx)
57 {
58 printf("\n Base : 0x%x", pCtx->base);
59 printf("\n IntrLevel: 0x%x", pCtx->intrLevel);
60 printf("\n Context : 0x%x", pCtx->userCtx);
61 printf("\n Callback : 0x%x", pCtx->callback);
62 return;
63 }
66 void MicoTimerDumpRegs(MicoTimerCtx_t *pCtx)
67 {
68 MicoTimer_t *pTimer = (MicoTimer_t *)pCtx->base;
69 printf("\n isr-status : 0x%x", pTimer->Status);
70 printf("\n isr-control : 0x%x", pTimer->Control);
71 printf("\n isr-period : 0x%x", pTimer->Period);
72 printf("\n isr-snapshot: 0x%x\n", pTimer->Snapshot);
73 }
74 #endif
77 /******************************************************************************
78 * Timer interrupt-handler *
79 ******************************************************************************/
80 static void MicoTimerISR(unsigned int intrLevel, void *pContext)
81 {
82 /*
83 * flow:
84 * - clear the timeout-bit
85 * - invoke user-registered callback
86 */
87 MicoTimerCtx_t *ctx = (MicoTimerCtx_t *)pContext;
88 volatile MicoTimer_t *pTimer = (MicoTimer_t *)ctx->base;
90 /* acknowledge the interrupt */
91 pTimer->Status = 0;
93 /* call the isr */
94 if(ctx->callback != 0)
95 ((TimerCallback_t)ctx->callback)(ctx->userCtx);
97 return;
98 }
101 /******************************************************************************
102 * Initializes a timer *
103 *----------------------------------------------------------------------------*
104 * Inputs: *
105 * unsigned int IntNum: Interrupt-level *
106 * Outputs: *
107 * Return values: *
108 * MICO_STATUS_E_INVALID_PARAM *
109 * MICO_STATUS_OK *
110 ******************************************************************************/
111 void MicoTimerInit( MicoTimerCtx_t *ctx )
112 {
113 /* stop the timer (if it was running) */
114 MicoTimerStop(ctx);
116 /*
117 * Enable interrupts without registering an isr:
118 * this way, any spurious timer interrupt that might have
119 * existed prior to this init being called, will cause the
120 * Mico Interrupt-framework to acknowlede the CPU's interrupt-pending.
121 */
122 MicoEnableInterrupt(ctx->intrLevel);
124 /* register this timer for lookup service */
125 ctx->lookupReg.name = ctx->name;
126 ctx->lookupReg.deviceType = "TimerDevice";
127 ctx->lookupReg.priv = ctx;
128 MicoRegisterDevice( &(ctx->lookupReg) );
130 /* all done */
131 return;
132 }
135 /******************************************************************************
136 * Starts a Mico32 timer *
137 *----------------------------------------------------------------------------*
138 * Inputs: *
139 * MicoTimerCtx_t *ctx: pointer to valid ctx *
140 * *
141 * TimerCallback_t callback: User-provided callback function, called *
142 * in interrupt-context. *
143 * *
144 * void *priv: user-provided data that will be called in the callback *
145 * *
146 * unsigned int timercount: ticks to load counter with *
147 * *
148 * int periodic: if 1, the timer is programmed to auto-load, else *
149 * timer is programmed not to reload on reaching terminal value *
150 * *
151 * Note: user MUST supply a valid ctx. *
152 * user MUST make sure timerCount is non-zero *
153 ******************************************************************************/
154 mico_status
155 MicoTimerStart( MicoTimerCtx_t *ctx, TimerCallback_t callback, void *priv, unsigned int timerCount, int periodic )
156 {
157 volatile MicoTimer_t *pTimer;
158 unsigned int regValue;
160 if( (ctx == 0) || (timerCount == 0) )
161 return(MICO_STATUS_E_INVALID_PARAM);
163 /* flow:
164 * - stop the timer,
165 * - load new timerCount,
166 * - configure the timer, taking into account the periodicity
167 * - register the isr (user MUST provide an isr)
168 * - start the timer.
169 */
170 pTimer = (MicoTimer_t *)(ctx->base);
171 regValue = (MICO32_TIMER_CONTROL_START_BIT_MASK|MICO32_TIMER_CONTROL_INT_BIT_MASK);
172 ctx->callback = (void *)callback;
173 ctx->userCtx = priv;
175 MicoRegisterISR(ctx->intrLevel, ctx, MicoTimerISR);
177 if(periodic != 0)
178 regValue |= MICO32_TIMER_CONTROL_CONT_BIT_MASK;
181 pTimer->Control = MICO32_TIMER_CONTROL_STOP_BIT_MASK;
182 pTimer->Period = timerCount;
183 pTimer->Control = regValue;
186 return(MICO_STATUS_OK);
187 }
190 /******************************************************************************
191 * *
192 * Stops a Mico32 timer *
193 * *
194 *----------------------------------------------------------------------------*
195 * *
196 * Note: user MUST supply a valid ctx. *
197 * *
198 ******************************************************************************/
199 mico_status
200 MicoTimerStop(MicoTimerCtx_t *ctx)
201 {
202 volatile MicoTimer_t *pTimer;
203 if(ctx == 0)
204 return(MICO_STATUS_E_INVALID_PARAM);
207 /* stop the timer first and ack any pending interrupts */
208 pTimer = (MicoTimer_t *)(ctx->base);
209 pTimer->Control = MICO32_TIMER_CONTROL_STOP_BIT_MASK;
210 pTimer->Status = 0;
212 /* all done */
213 return(MICO_STATUS_OK);
214 }
217 /******************************************************************************
218 * reads timer-snapshot *
219 *----------------------------------------------------------------------------*
220 * Note: user MUST supply a valid ctx. *
221 ******************************************************************************/
222 unsigned int MicoTimerSnapshot( MicoTimerCtx_t *ctx)
223 {
224 volatile MicoTimer_t *pTimer;
225 if(ctx == 0){
226 return(0);
227 }
228 pTimer = (MicoTimer_t *)(ctx->base);
229 return(pTimer->Snapshot);
230 }