[PDK-6649] OSAL: nonos: Fix TimerP_delete to update gTimerAnyMask
[processor-sdk/pdk.git] / packages / ti / osal / src / nonos / timer / v0 / TimerP_nonos.c
1 /*
2  * Copyright (c) 2015-2020, 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  *  ======== TimerP_nonos.c ========
34  */
37 #include <stdint.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
40 #include <string.h>
42 #include <ti/osal/TimerP.h>
43 #include <ti/csl/soc.h>
44 #include <ti/csl/csl_tmr.h>
45 #include <ti/csl/csl_tmrAux.h>
46 #include <ti/csl/arch/csl_arch.h>
47 #include <ti/osal/src/nonos/Nonos_config.h>
49 /* Timer 64 Implementation */
50 extern void Osal_DebugP_assert(int32_t expression, const char *file, int32_t line);
51 #define TIMOSAL_Assert(expression) (Osal_DebugP_assert(((int32_t)((expression)?1:0)),\
52                                                   __FILE__, __LINE__))
55 /* Local Timer Struct */
56 typedef struct TimerP_Struct
57 {
58   bool     used;       /* In use or not status */
59   CSL_TmrHandle hTmr;  /* CSL Timer Handle */
60   uint32_t id;         /* timer Id */
61   uint32_t periodType; /* Period type, default micro seconds */
62   uint32_t freqLo;     /* least siginificant 32-bits of frequency */
63   uint32_t freqHi;     /* most siginificant 32-bits of frequency  */
64   uint32_t startMode;  /* timer start mode */
65   uint32_t runMode;    /* timer run mode   */
66   uint32_t period;     /* Period of a tick */
67   TimerP_Fxn tickFxn;  /* Timer Tick function */
68   void*    arg;        /* Argument passed into the timer function. */
69   uint32_t availMask;   /* Available timer mask */
70   HwiP_Handle hwi;      /* Hwi handle for tickFxn */
71 #if defined (_TMS320C6X)
72   uint32_t eventId;     /* Event Id for C66x */
73 #endif
74   int32_t  intNum;      /* Interrupt Number */
75   TimerP_Timer64Mode mode;
76   TimerP_Timer64Half timerHalf; /*!< timer half for 64bit timer */
77   uint32_t   prescalar;
78   uint32_t   intCtl;
79   CSL_TmrObj TmrObj;   /* CSL timer Object */
80 }TimerP_Struct;
82 /* As static allocation is used, the following provides the structs
83  * The TimerP_Struct pool servers to get an available timer
84  * handle during timer create API call.
85  */
86 TimerP_Struct gTimerStructs[OSAL_NONOS_CONFIGNUM_TIMER];
87 static        uint32_t     gTimerInitDone = 0U;
88 static        uint32_t     gTimerAnyMask;
90 /* Local functions  */
91 static uint32_t TimerP_getTimerBaseAddr(uint32_t timer_id);
92 static void  TimerP_timer64InitDevice(TimerP_Struct *timer, uint32_t baseAddr);
93 static bool TimerP_timer64CheckOverflow(uint32_t a, uint32_t b);
94 static bool TimerP_timer64SetMicroSeconds(TimerP_Struct *timer, uint32_t period);
95 static TimerP_Status TimerP_timer64DeviceCfg(TimerP_Struct *timer, uint32_t baseAddr);
96 static TimerP_Status TimerP_timer64InitObj(TimerP_Struct *timer, TimerP_Fxn tickFxn,
97                                            const TimerP_Params *params);
98 static TimerP_Status TimerP_timer64InstanceInit(TimerP_Struct *timer, uint32_t id,
99                                                 TimerP_Fxn tickFxn, const TimerP_Params *params);
102 /* Below function returns the bit width of the number
103  * by computing number of redundant sign bits used or
104  * sign extended in the given 32 bits
105  */
106 #if defined(_TMS320C6X)
107   #define TimerP_maxbit(bits) (31 - _norm(bits))
108 #else
109 #if defined (__TI_ARM__)
110 static uint32_t TimerP_maxbit(uint32_t bits)
112       register uint32_t __R5, __R0;
114       __R5 = 0; /* to avoid compiler warning*/
115           __R0 = bits;
116           __R0 = __R0;
118           asm("    clz   r5, r0\n"
119               "    rsb   r5, r5, #31\n");
121       return (uint32_t)__R5;
122   }
123 #else
124 static uint32_t TimerP_maxbit(uint32_t bits)
126       uint32_t retVal;
127       __asm__ __volatile__ (
128         "clz %0, %1\n\t"
129         "rsb %0, %0, #31"
130         : "=r" (retVal)
131         : "r" (bits)
132         : "cc"            );
133       return retVal;
134   }
135 #endif
136 #endif
138 /*
139  * This private function returns the base address of the timer based on
140  * the ID passed in.
141  */
142 static uint32_t TimerP_getTimerBaseAddr(uint32_t timer_id)
144     uint32_t addr;
146     if (timer_id < TimerP_numTimerDevices) {
147       addr = (uint32_t) gTimer64InfoTbl[timer_id].baseAddr;
148     }
149     else {
150       addr = (uint32_t) NULL_PTR;
151     }
152     return (addr);
155 /*
156  * This priviate function initializes the timer counter, period and compare
157  * registers
158  */
159 static void  TimerP_timer64InitDevice(TimerP_Struct *timer, uint32_t baseAddr)
161     uint32_t hwiKey;
162     CSL_TmrHwSetup              hwSetup = CSL_TMR_HWSETUP_DEFAULTS;
163     CSL_Status                  status;
165     /* Clear local data structures */
166     (void)memset(&timer->TmrObj, 0, sizeof(CSL_TmrObj));
168     hwiKey = HwiP_disable();
170     /* Open the timer. */
171     timer->hTmr =  CSL_tmrOpen(&timer->TmrObj, timer->id, NULL_PTR, &status);
173     if (timer->hTmr != NULL_PTR) {
174       /* Configure the timer. */
175       CSL_tmrHwSetup(timer->hTmr, &hwSetup);
177       if (timer->hwi) {
178           /* clear any previously latched timer interrupts */
179           HwiP_clearInterrupt(timer->intNum);
180           HwiP_disableInterrupt(timer->intNum);
181       }
182     }
184     HwiP_restore(hwiKey);
187 /*
188  * This priviate function checks if there is any overflow in
189  * timer period computations
190  */
191 static bool TimerP_timer64CheckOverflow(uint32_t a, uint32_t b)
193   return ((b > 0) && (a > TimerP_MAX_PERIOD/b));
196 /*
197  * This is a private function to set the period of the timer
198  * register for a specified micro second value
199  */
200 static bool TimerP_timer64SetMicroSeconds(TimerP_Struct *timer, uint32_t period)
202     uint64_t  counts;
203     uint32_t  prdCounts, pscCounts;
204     uint32_t  freqKHz, shift = 0;
205     bool      ret = TRUE;
207     TimerP_stop(timer);
209     freqKHz = (timer->freqLo / 1000);
210     if (TimerP_timer64CheckOverflow(freqKHz, period/1000)) {
211             return (FALSE);
212     }
214     counts = ((uint64_t)freqKHz * (uint64_t)period) / (uint64_t)1000;
215     if (counts > 0xffffffff) {
216       pscCounts = counts >> 32;
217       if (pscCounts) {
218           shift = TimerP_maxbit(pscCounts) + 1;
219           pscCounts = (1 << shift) - 1;
220       }
221       prdCounts = (counts >> shift);
222     }
223     else {
224       prdCounts = counts;
225       pscCounts = 0;
226     }
228     timer->period     = prdCounts;
229     timer->periodType = TimerP_PeriodType_COUNTS;
230     timer->prescalar  = pscCounts;
232     if (timer->mode != TimerP_Timer64Mode_64BITGPTIMER ) {
233       if (pscCounts != 0) {
234         ret = FALSE;
235       }
236     }
238     return(ret);
241 /*
242  * Thi is a private function to configure the timer registers for a given timer
243  * period
244  */
245 static TimerP_Status TimerP_timer64DeviceCfg(TimerP_Struct *timer, uint32_t baseAddr)
247   uint32_t      key;
249   key = HwiP_disable();
251   /* initialize the timer */
252   TimerP_timer64InitDevice(timer, baseAddr);
254   /* compute and get the period */
255   if (timer->periodType == TimerP_PeriodType_MICROSECS) {
256       if (!TimerP_timer64SetMicroSeconds(timer, timer->period)) {
257           HwiP_restore(key);
258           return (TimerP_FAILURE);
259       }
260   }
262   HwiP_restore(key);
264   return (TimerP_OK);
267 /*
268  * This is a private function to initialize the timer counter, period and compare
269  * registers before starting the timers
270  */
271 static TimerP_Status TimerP_timer64InitObj(TimerP_Struct *timer, TimerP_Fxn tickFxn, const TimerP_Params *params)
273   timer->tickFxn = tickFxn;
275   /*
276    * Update the default initializations to user configured values
277    */
278   if ( params->extfreqLo != TimerP_USE_DEFAULT) {
279     timer->freqLo            =  params->extfreqLo;
280   }
281   else  {
282     if (params->intfreqLo != TimerP_USE_DEFAULT)  {
283       timer->freqLo            = params->intfreqLo;
284     }
285     else {
286       timer->freqLo            =  TimerP_getDefaultFreqLo(timer->id);
287     }
288   }
290   if ( params->extfreqHi != TimerP_USE_DEFAULT) {
291     timer->freqHi            =  params->extfreqHi;
292   }
293   else  {
294     if (params->intfreqHi != TimerP_USE_DEFAULT)  {
295       timer->freqHi          = params->intfreqHi;
296     }
297     else {
298       timer->freqHi            =  TimerP_getDefaultFreqHi(timer->id);
299     }
300   }
302   if ( params->period != 0) {
303     timer->period                = params->period;
304   }
305   else  {
306     timer->period                = 0;
307   }
309    if ( params->arg != (void*) NULL_PTR) {
310      timer->arg                   = params->arg;
311    }
313    if ( params->intNum != TimerP_USE_DEFAULT) {
314      timer->intNum = params->intNum;
315    }
316    else {
317      timer->intNum = gTimer64InfoTbl[timer->id].intNumLo;
318    }
320 #if defined (_TMS320C6X)
321    if ( params->eventId != TimerP_USE_DEFAULT) {
322      timer->eventId = params->eventId;
323    }
324    else {
325      timer->eventId = gTimer64InfoTbl[timer->id].eventIdLo;
326    }
327 #endif
329    timer->periodType = params->periodType;
330    timer->startMode  = params->startMode;
331    timer->runMode    = params->runMode;
332    timer->mode       = params->timerMode;
333    return(TimerP_OK);
337 static TimerP_Status TimerP_timer64InstanceInit(TimerP_Struct *timer, uint32_t id, TimerP_Fxn tickFxn, const TimerP_Params *params)
339   TimerP_Status ret = TimerP_OK;
340   uint32_t      key;
341   int32_t       i;
342   uint32_t      tempId = 0xffff;
343   OsalRegisterIntrParams_t interruptRegParams;
344   uint32_t      baseAddr, intNum;
345   uint32_t      timerPAnyMask = (uint32_t)(TIMERP_ANY_MASK);
347   if ((id != TimerP_ANY) && (id >= TimerP_numTimerDevices)) {
348     ret = TimerP_FAILURE;
349   }
351   /* Get the timer Id */
352   if (ret == TimerP_OK)
353   {
354     /* Set the available timer id mask to all */
355     if (gTimerInitDone == 0U)
356     {
357         gTimerAnyMask  = TIMERP_AVAILABLE_MASK;
358         gTimerInitDone = 1U;
359     }
361     timer->availMask = gTimerAnyMask;
363     key = HwiP_disable();
365     if (id == TimerP_ANY) {
366         for (i = 0; i < TimerP_numTimerDevices; i++) {
367             if ((timerPAnyMask & (1 << i)) &&
368                 (timer->availMask & (1 << i))) {
369                  timer->availMask &= ~(1 << i);
370                 tempId = i;
371                 break;
372             }
373         }
374     }
375     else if (timer->availMask & (1 << id)) {
376         timer->availMask &= ~(1 << id);
377         tempId = id;
378     }
380     gTimerAnyMask = timer->availMask;
382     HwiP_restore(key);
384     if (tempId == 0xffff) {
385       ret = TimerP_NOT_AVAILABLE;
386     }
387   }
389   /* Initialize the timer state object */
390   timer->id = tempId; /* Record the timer Id */
391   if (ret == TimerP_OK) {
392      baseAddr = TimerP_getTimerBaseAddr(tempId);
393      ret = TimerP_timer64InitObj(timer, tickFxn, params);
394   }
396   /* Create the Hwi Funtion for the tick funtion */
397   if (ret == TimerP_OK)
398   {
399     if (timer->tickFxn != NULL_PTR)
400     {
401       intNum          = timer->intNum;
402       /* Initialize with defaults */
403       Osal_RegisterInterrupt_initParams(&interruptRegParams);
405       /* Populate the interrupt parameters */
406       interruptRegParams.corepacConfig.arg=(uintptr_t) timer;
407       interruptRegParams.corepacConfig.name=NULL_PTR;
408       interruptRegParams.corepacConfig.isrRoutine=timer->tickFxn;
409       interruptRegParams.corepacConfig.priority = 0x20U;
410 #if defined (__ARM_ARCH_7A__) && !defined(SOC_K2G)
411       interruptRegParams.corepacConfig.triggerSensitivity =  OSAL_ARM_GIC_TRIG_TYPE_EDGE;
412 #endif
414 #if defined(_TMS320C6X)
415       interruptRegParams.corepacConfig.corepacEventNum=timer->eventId; /* Event going in to CPU */
416 #endif
417       interruptRegParams.corepacConfig.intVecNum=intNum; /* Host Interrupt vector */
418       /* Register interrupts */
419       Osal_RegisterInterrupt(&interruptRegParams,&(timer->hwi));
421       if (timer->hwi == NULL_PTR)
422       {
423         ret = TimerP_ISR_HOOK_ERR;
424       }
425     }
426     else
427     {
428       timer->hwi = NULL_PTR;
429     }
430   }
432   /* timer post init */
433   if (ret == TimerP_OK)
434   {
435      ret = TimerP_timer64DeviceCfg(timer, baseAddr);
437      if (timer->startMode == TimerP_StartMode_AUTO)
438         TimerP_start(timer);
439   }
441   return (ret);
445 /* Interface functions */
447 /* Default parameter initialization module function
448  * more details on the documentation of this interface
449  * function can be found in the TimerP.h interface
450  * header file */
451 void TimerP_Params_init(TimerP_Params *params)
453     TIMOSAL_Assert((params == NULL_PTR));
455     /* Set the default values */
456     params->arg         = (void *) NULL_PTR;
457     params->extfreqHi   = TimerP_USE_DEFAULT;
458     params->extfreqLo   = TimerP_USE_DEFAULT;
459     params->intfreqHi   = TimerP_USE_DEFAULT;
460     params->intfreqLo   = TimerP_USE_DEFAULT;
461     params->name        = NULL_PTR;
462     params->period      = 0;
463     params->runMode     = TimerP_RunMode_CONTINUOUS;
464     params->startMode   = TimerP_StartMode_AUTO;
465     params->periodType  = TimerP_PeriodType_MICROSECS;
466     params->intNum      = TimerP_USE_DEFAULT;
467     params->timerHalf   = TimerP_Timer64Half_DEFAULT;
468     params->timerMode   = TimerP_Timer64Mode_UNCHAINED;
470 #if defined (_TMS320C6X)
471     params->eventId     = TimerP_USE_DEFAULT;
472 #endif
474     return;
477 /* Timer create module function
478  * more details on the documentation of this interface
479  * function can be found in the TimerP.h interface
480  * header file */
481 TimerP_Handle TimerP_create(int32_t id,
482                             TimerP_Fxn tickFxn,
483                             const TimerP_Params *params)
486     uint32_t          i;
487     uintptr_t         key;
488     TimerP_Handle     ret_handle;
489     key = HwiP_disable();
491     for (i = 0u; i < OSAL_NONOS_CONFIGNUM_TIMER; i++)
492     {
493         if (gTimerStructs[i].used == false)
494         {
495             gTimerStructs[i].used = true;
496             if (params != NULL_PTR)
497             {
498                 gTimerStructs[i].id  = id;
499             }
501             break;
502         }
503     }
504     HwiP_restore(key);
506     if (i == OSAL_NONOS_CONFIGNUM_TIMER)
507     {
508         ret_handle = (TimerP_Handle) NULL_PTR;
509     }
510     else
511     {
512         /* Start the timer for that period/mode */
513         ret_handle = ((TimerP_Handle)&gTimerStructs[i]);
514     }
516     if (ret_handle != (TimerP_Handle)NULL_PTR)
517     {
518       if (TimerP_timer64InstanceInit(&gTimerStructs[i], id, tickFxn, params) != TimerP_OK) {
519         /* Free up the consumed timer memory */
520         gTimerStructs[i].used = false;
521         ret_handle = (TimerP_Handle) NULL_PTR;
522       }
523     }
525     /* start timer if it is auto mode */
526     if ((params->startMode == TimerP_StartMode_AUTO) &&
527         (ret_handle != (TimerP_Handle)(NULL_PTR)) )
528     {
529        if(TimerP_start((TimerP_Handle)&gTimerStructs[i]) != TimerP_OK) {
530           gTimerStructs[i].used = false;
531           ret_handle = (TimerP_Handle)NULL_PTR;
532        }
533     }
534     return (ret_handle);
538 /* Timer delete module function
539  * more details on the documentation of this interface
540  * function can be found in the TimerP.h interface
541  * header file */
542 TimerP_Status TimerP_delete(TimerP_Handle handle)
544       /* Release or free the memory */
545       uint32_t key;
546       uint32_t id;
547       TimerP_Status ret = TimerP_OK;
548       int index = ((uint32_t) handle - (uint32_t) gTimerStructs); /* struct subtraction */
549       TimerP_Struct *timer = (TimerP_Struct *) handle;
551       TIMOSAL_Assert((handle == NULL_PTR));
553       key = HwiP_disable();
555       if((timer != NULL_PTR) && ((gTimerStructs[index].used) == (bool)true)) {
556         /* clear the ISR that was set before */
557         if(timer->hwi != NULL_PTR) {
558           HwiP_delete(timer->hwi);
559         }
560         /* reset the timer's bit field in the mask and clear the used flag */
561         gTimerStructs[index].used = (bool)false;
562         id = gTimerStructs[index].timerId;
563         uint32_t shift = ((uint32_t) 1u) << id;
564         if(((gTimerAnyMask & shift)) == 0U)
565         {
566           gTimerAnyMask |= shift;
567         }
568         else
569         {
570           ret = TimerP_FAILURE; 
571         }
572       }
573       else
574       {
575         ret = TimerP_FAILURE;
576       }
578       HwiP_restore(key);
580       return (ret);
584 /* Timer start module function
585  * more details on the documentation of this interface
586  * function can be found in the TimerP.h interface
587  * header file */
588 TimerP_Status TimerP_start(TimerP_Handle handle)
590   uint32_t key;
591   CSL_TmrHwSetup hwSetup = CSL_TMR_HWSETUP_DEFAULTS;
592   CSL_TmrMode    runMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
593   CSL_TmrEnamode timeCountMode;
594   CSL_TmrHwControlCmd startCmd;
595   TimerP_Struct *timer = (TimerP_Struct *) handle;
596   TIMOSAL_Assert((handle == NULL_PTR));
597   uint32_t       eventId;
598   TimerP_Status  status = TimerP_OK;
600   key = HwiP_disable();
602   switch (timer->mode)
603   {
604       case TimerP_Timer64Mode_64BITGPTIMER:
605         runMode = CSL_TMR_TIMMODE_GPT;
606         break;
607       case TimerP_Timer64Mode_CHAINED:
608         runMode = CSL_TMR_TIMMODE_DUAL_CHAINED;
609         break;
610       case TimerP_Timer64Mode_UNCHAINED:
611         runMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
612         break;
613   }
615   switch (timer->runMode)
616   {
617       case TimerP_RunMode_CONTINUOUS:
618         timeCountMode = CSL_TMR_ENAMODE_CONT;
619         break;
620       case TimerP_RunMode_ONESHOT:
621         timeCountMode = CSL_TMR_ENAMODE_ENABLE;
622         break;
623   }
625   switch (timer->timerHalf)
626   {
627       case TimerP_Timer64Half_LOWER:
628         startCmd = CSL_TMR_CMD_START_TIMLO;
629         break;
630       case TimerP_Timer64Half_UPPER:
631         startCmd = CSL_TMR_CMD_START_TIMHI;
632         break;
633       default:
634         startCmd = CSL_TMR_CMD_START64;
635         break;
636   }
638   if(timer->hwi != NULL_PTR) {
639 #if defined (_TMS320C6X)
640     eventId = timer->eventId;
641 #else
642     eventId = 0u;
643 #endif
644     Osal_ClearInterrupt(eventId, timer->intNum);
645     Osal_EnableInterrupt(eventId, timer->intNum);
646   }
647   else {
648       status = TimerP_FAILURE;
649   }
651   /* Load the period values */
652   if (timer->mode == TimerP_Timer64Mode_64BITGPTIMER) {
653     /* Reset the Timer */
654     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET64, NULL_PTR);
656     /* Set the timer mode*/
657     hwSetup.tmrTimerMode = runMode;
658     CSL_tmrHwSetup(timer->hTmr, &hwSetup);
660     /* Load the period register */
661     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDLO, (void *)&timer->period);
663     /* Load the period register */
664     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDHI, (void *)&timer->prescalar);
665   }
666   else {
667     if (timer->timerHalf == TimerP_Timer64Half_LOWER) {
668       /* Reset the Timer */
669       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMLO, NULL_PTR);
671       /* Set the timer mode*/
672       hwSetup.tmrTimerMode = runMode;
673       CSL_tmrHwSetup(timer->hTmr, &hwSetup);
675       /* Load the period register */
676       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDLO, (void *)&timer->period);
677     }
678     else {
679       /* Reset the Timer */
680       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL_PTR);
682       /* Set the timer mode*/
683       hwSetup.tmrTimerMode = runMode;
684       CSL_tmrHwSetup(timer->hTmr, &hwSetup);
686       /* Load the period register */
687       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDHI, (void *)&timer->period);
688     }
689   }
691   /* Start the timer in a given Mode. */
692   CSL_tmrHwControl(timer->hTmr, startCmd, (void *)&timeCountMode);
694   HwiP_restore(key);
696   return (status);
699 /* Timer stop module function
700  * more details on the documentation of this interface
701  * function can be found in the TimerP.h interface
702  * header file */
704 TimerP_Status TimerP_stop(TimerP_Handle handle)
706   TimerP_Struct *timer = (TimerP_Struct *) handle;
707   TIMOSAL_Assert((handle == NULL_PTR));
708   uint32_t          eventId;
709   TimerP_Status     status = TimerP_OK;
711   if ((timer->mode == TimerP_Timer64Mode_CHAINED) || (timer->timerHalf == TimerP_Timer64Half_LOWER)) {
712     /* Stop the Timer */
713     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMLO, NULL_PTR);
714   }
715   else {
716     /* Stop the Timer */
717     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL_PTR);
718   }
720   if(timer != NULL_PTR) {
721 #if defined (_TMS320C6X)
722     eventId = timer->eventId;
723 #else
724     eventId = 0u;
725 #endif
726       Osal_ClearInterrupt(eventId, timer->intNum);
727       Osal_DisableInterrupt(eventId, timer->intNum);
728   }
729   else {
730       status = TimerP_FAILURE;
731   }
733   return(status);
736 /* Timer set micro seconds module function
737  * more details on the documentation of this interface
738  * function can be found in the TimerP.h interface
739  * header file */
740 TimerP_Status TimerP_setPeriodMicroSecs(TimerP_Handle handle, uint32_t microsecs)
742   TimerP_Struct *timer = (TimerP_Struct *) handle;
744   if (!TimerP_timer64SetMicroSeconds(timer, microsecs)) {
745     return (TimerP_FAILURE);
746   }
747   else {
748     return (TimerP_OK);
749   }
752 /* Timer clear the interrupt module function
753  * more details on the documentation of this interface
754  * function can be found in the TimerP.h interface
755  */
756 TimerP_Status TimerP_ClearInterrupt(TimerP_Handle handle)
758     TimerP_Struct *timer = (TimerP_Struct *) handle;
759     HwiP_clearInterrupt(timer->intNum);
761     return (TimerP_OK);
763 #if defined (SOC_OMAPL137) || defined (SOC_OMAPL138)
764 /* Below API is not supported for OMAPL13X SoCs for bare metal */
765 #else
766 /* Get time in micro seconds */
767 uint64_t TimerP_getTimeInUsecs(void)
769     TimeStamp_Struct timestamp64;
770     uint64_t         cur_ts, freq;
771     int32_t             tsFreqKHz;
773     osalArch_TimestampGet64(&timestamp64);
775     /* Get the frequency of the timeStatmp provider */
776     tsFreqKHz  = osalArch_TimeStampGetFreqKHz();
778     cur_ts = ((uint64_t) timestamp64.hi << 32) | timestamp64.lo;
779     freq = ((uint64_t) 0U << 32) | (tsFreqKHz);
781     return ((cur_ts*1000u)/freq);
783 #endif
784 /* This would implement the gp timer on KeyStone devices */