1.1 diff -r 000000000000 -r 396b0bd970d3 drivers/device/MicoTimer.c 1.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 +++ b/drivers/device/MicoTimer.c Fri Aug 13 10:49:23 2010 +0100 1.4 @@ -0,0 +1,231 @@ 1.5 +/**************************************************************************** 1.6 +** 1.7 +** Name: MicoTimer.c 1.8 +** 1.9 +** Description: 1.10 +** Implements functions for manipulating LatticeMico32 Timer 1.11 +** 1.12 +** $Revision: $ 1.13 +** 1.14 +** Disclaimer: 1.15 +** 1.16 +** This source code is intended as a design reference which 1.17 +** illustrates how these types of functions can be implemented. It 1.18 +** is the user's responsibility to verify their design for 1.19 +** consistency and functionality through the use of formal 1.20 +** verification methods. Lattice Semiconductor provides no warranty 1.21 +** regarding the use or functionality of this code. 1.22 +** 1.23 +** -------------------------------------------------------------------- 1.24 +** 1.25 +** Lattice Semiconductor Corporation 1.26 +** 5555 NE Moore Court 1.27 +** Hillsboro, OR 97214 1.28 +** U.S.A 1.29 +** 1.30 +** TEL: 1-800-Lattice (USA and Canada) 1.31 +** (503)268-8001 (other locations) 1.32 +** 1.33 +** web: http://www.latticesemi.com 1.34 +** email: techsupport@latticesemi.com 1.35 +** 1.36 +** -------------------------------------------------------------------------- 1.37 +** 1.38 +** Change History (Latest changes on top) 1.39 +** 1.40 +** Ver Date Description 1.41 +** -------------------------------------------------------------------------- 1.42 +** 1.43 +** 3.0 Mar-25-2008 Added Header 1.44 +** 1.45 +**--------------------------------------------------------------------------- 1.46 +*****************************************************************************/ 1.47 + 1.48 + 1.49 +#include "MicoTimer.h" 1.50 +#include "MicoTimerService.h" 1.51 +#include "MicoMacros.h" 1.52 +#include "MicoInterrupts.h" 1.53 + 1.54 + 1.55 + 1.56 +/************************************************************************** 1.57 + * driver-debug functions * 1.58 + **************************************************************************/ 1.59 +#if _MICO_TIMER_DRIVER_DEBUG_ENABLED_ 1.60 +static void MicoTimerDumpCtx(MicoTimerCtx_t *pCtx) 1.61 +{ 1.62 + printf("\n Base : 0x%x", pCtx->base); 1.63 + printf("\n IntrLevel: 0x%x", pCtx->intrLevel); 1.64 + printf("\n Context : 0x%x", pCtx->userCtx); 1.65 + printf("\n Callback : 0x%x", pCtx->callback); 1.66 + return; 1.67 +} 1.68 + 1.69 + 1.70 +void MicoTimerDumpRegs(MicoTimerCtx_t *pCtx) 1.71 +{ 1.72 + MicoTimer_t *pTimer = (MicoTimer_t *)pCtx->base; 1.73 + printf("\n isr-status : 0x%x", pTimer->Status); 1.74 + printf("\n isr-control : 0x%x", pTimer->Control); 1.75 + printf("\n isr-period : 0x%x", pTimer->Period); 1.76 + printf("\n isr-snapshot: 0x%x\n", pTimer->Snapshot); 1.77 +} 1.78 +#endif 1.79 + 1.80 + 1.81 +/****************************************************************************** 1.82 + * Timer interrupt-handler * 1.83 + ******************************************************************************/ 1.84 +static void MicoTimerISR(unsigned int intrLevel, void *pContext) 1.85 +{ 1.86 + /* 1.87 + * flow: 1.88 + * - clear the timeout-bit 1.89 + * - invoke user-registered callback 1.90 + */ 1.91 + MicoTimerCtx_t *ctx = (MicoTimerCtx_t *)pContext; 1.92 + volatile MicoTimer_t *pTimer = (MicoTimer_t *)ctx->base; 1.93 + 1.94 + /* acknowledge the interrupt */ 1.95 + pTimer->Status = 0; 1.96 + 1.97 + /* call the isr */ 1.98 + if(ctx->callback != 0) 1.99 + ((TimerCallback_t)ctx->callback)(ctx->userCtx); 1.100 + 1.101 + return; 1.102 +} 1.103 + 1.104 + 1.105 +/****************************************************************************** 1.106 + * Initializes a timer * 1.107 + *----------------------------------------------------------------------------* 1.108 + * Inputs: * 1.109 + * unsigned int IntNum: Interrupt-level * 1.110 + * Outputs: * 1.111 + * Return values: * 1.112 + * MICO_STATUS_E_INVALID_PARAM * 1.113 + * MICO_STATUS_OK * 1.114 + ******************************************************************************/ 1.115 +void MicoTimerInit( MicoTimerCtx_t *ctx ) 1.116 +{ 1.117 + /* stop the timer (if it was running) */ 1.118 + MicoTimerStop(ctx); 1.119 + 1.120 + /* 1.121 + * Enable interrupts without registering an isr: 1.122 + * this way, any spurious timer interrupt that might have 1.123 + * existed prior to this init being called, will cause the 1.124 + * Mico Interrupt-framework to acknowlede the CPU's interrupt-pending. 1.125 + */ 1.126 + MicoEnableInterrupt(ctx->intrLevel); 1.127 + 1.128 + /* register this timer for lookup service */ 1.129 + ctx->lookupReg.name = ctx->name; 1.130 + ctx->lookupReg.deviceType = "TimerDevice"; 1.131 + ctx->lookupReg.priv = ctx; 1.132 + MicoRegisterDevice( &(ctx->lookupReg) ); 1.133 + 1.134 + /* all done */ 1.135 + return; 1.136 +} 1.137 + 1.138 + 1.139 +/****************************************************************************** 1.140 + * Starts a Mico32 timer * 1.141 + *----------------------------------------------------------------------------* 1.142 + * Inputs: * 1.143 + * MicoTimerCtx_t *ctx: pointer to valid ctx * 1.144 + * * 1.145 + * TimerCallback_t callback: User-provided callback function, called * 1.146 + * in interrupt-context. * 1.147 + * * 1.148 + * void *priv: user-provided data that will be called in the callback * 1.149 + * * 1.150 + * unsigned int timercount: ticks to load counter with * 1.151 + * * 1.152 + * int periodic: if 1, the timer is programmed to auto-load, else * 1.153 + * timer is programmed not to reload on reaching terminal value * 1.154 + * * 1.155 + * Note: user MUST supply a valid ctx. * 1.156 + * user MUST make sure timerCount is non-zero * 1.157 + ******************************************************************************/ 1.158 +mico_status 1.159 +MicoTimerStart( MicoTimerCtx_t *ctx, TimerCallback_t callback, void *priv, unsigned int timerCount, int periodic ) 1.160 +{ 1.161 + volatile MicoTimer_t *pTimer; 1.162 + unsigned int regValue; 1.163 + 1.164 + if( (ctx == 0) || (timerCount == 0) ) 1.165 + return(MICO_STATUS_E_INVALID_PARAM); 1.166 + 1.167 + /* flow: 1.168 + * - stop the timer, 1.169 + * - load new timerCount, 1.170 + * - configure the timer, taking into account the periodicity 1.171 + * - register the isr (user MUST provide an isr) 1.172 + * - start the timer. 1.173 + */ 1.174 + pTimer = (MicoTimer_t *)(ctx->base); 1.175 + regValue = (MICO32_TIMER_CONTROL_START_BIT_MASK|MICO32_TIMER_CONTROL_INT_BIT_MASK); 1.176 + ctx->callback = (void *)callback; 1.177 + ctx->userCtx = priv; 1.178 + 1.179 + MicoRegisterISR(ctx->intrLevel, ctx, MicoTimerISR); 1.180 + 1.181 + if(periodic != 0) 1.182 + regValue |= MICO32_TIMER_CONTROL_CONT_BIT_MASK; 1.183 + 1.184 + 1.185 + pTimer->Control = MICO32_TIMER_CONTROL_STOP_BIT_MASK; 1.186 + pTimer->Period = timerCount; 1.187 + pTimer->Control = regValue; 1.188 + 1.189 + 1.190 + return(MICO_STATUS_OK); 1.191 +} 1.192 + 1.193 + 1.194 +/****************************************************************************** 1.195 + * * 1.196 + * Stops a Mico32 timer * 1.197 + * * 1.198 + *----------------------------------------------------------------------------* 1.199 + * * 1.200 + * Note: user MUST supply a valid ctx. * 1.201 + * * 1.202 + ******************************************************************************/ 1.203 +mico_status 1.204 +MicoTimerStop(MicoTimerCtx_t *ctx) 1.205 +{ 1.206 + volatile MicoTimer_t *pTimer; 1.207 + if(ctx == 0) 1.208 + return(MICO_STATUS_E_INVALID_PARAM); 1.209 + 1.210 + 1.211 + /* stop the timer first and ack any pending interrupts */ 1.212 + pTimer = (MicoTimer_t *)(ctx->base); 1.213 + pTimer->Control = MICO32_TIMER_CONTROL_STOP_BIT_MASK; 1.214 + pTimer->Status = 0; 1.215 + 1.216 + /* all done */ 1.217 + return(MICO_STATUS_OK); 1.218 +} 1.219 + 1.220 + 1.221 +/****************************************************************************** 1.222 + * reads timer-snapshot * 1.223 + *----------------------------------------------------------------------------* 1.224 + * Note: user MUST supply a valid ctx. * 1.225 + ******************************************************************************/ 1.226 +unsigned int MicoTimerSnapshot( MicoTimerCtx_t *ctx) 1.227 +{ 1.228 + volatile MicoTimer_t *pTimer; 1.229 + if(ctx == 0){ 1.230 + return(0); 1.231 + } 1.232 + pTimer = (MicoTimer_t *)(ctx->base); 1.233 + return(pTimer->Snapshot); 1.234 +} 1.235 +