drivers/device/MicoTimer.c

Fri, 13 Aug 2010 10:49:23 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 13 Aug 2010 10:49:23 +0100
changeset 0
396b0bd970d3
permissions
-rw-r--r--

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 }