298f81767a6cac322e7ef8bd7986ab38cba1a89c
[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       TimerP_Status ret = TimerP_OK;
547       int index = ((uint32_t) handle - (uint32_t) gTimerStructs); /* struct subtraction */
548       TimerP_Struct *timer = (TimerP_Struct *) handle;
550       TIMOSAL_Assert((handle == NULL_PTR));
552       key = HwiP_disable();
554       if((timer != NULL_PTR) && ((gTimerStructs[index].used) == (bool)true)) {
555         /* clear the ISR that was set before */
556         if(timer->hwi != NULL_PTR) {
557           HwiP_delete(timer->hwi);
558           gTimerStructs[index].used  = false;
559         }
560       }
561       else
562       {
563         ret = TimerP_FAILURE;
564       }
566       HwiP_restore(key);
568       return (ret);
572 /* Timer start module function
573  * more details on the documentation of this interface
574  * function can be found in the TimerP.h interface
575  * header file */
576 TimerP_Status TimerP_start(TimerP_Handle handle)
578   uint32_t key;
579   CSL_TmrHwSetup hwSetup = CSL_TMR_HWSETUP_DEFAULTS;
580   CSL_TmrMode    runMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
581   CSL_TmrEnamode timeCountMode;
582   CSL_TmrHwControlCmd startCmd;
583   TimerP_Struct *timer = (TimerP_Struct *) handle;
584   TIMOSAL_Assert((handle == NULL_PTR));
585   uint32_t       eventId;
586   TimerP_Status  status = TimerP_OK;
588   key = HwiP_disable();
590   switch (timer->mode)
591   {
592       case TimerP_Timer64Mode_64BITGPTIMER:
593         runMode = CSL_TMR_TIMMODE_GPT;
594         break;
595       case TimerP_Timer64Mode_CHAINED:
596         runMode = CSL_TMR_TIMMODE_DUAL_CHAINED;
597         break;
598       case TimerP_Timer64Mode_UNCHAINED:
599         runMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
600         break;
601   }
603   switch (timer->runMode)
604   {
605       case TimerP_RunMode_CONTINUOUS:
606         timeCountMode = CSL_TMR_ENAMODE_CONT;
607         break;
608       case TimerP_RunMode_ONESHOT:
609         timeCountMode = CSL_TMR_ENAMODE_ENABLE;
610         break;
611   }
613   switch (timer->timerHalf)
614   {
615       case TimerP_Timer64Half_LOWER:
616         startCmd = CSL_TMR_CMD_START_TIMLO;
617         break;
618       case TimerP_Timer64Half_UPPER:
619         startCmd = CSL_TMR_CMD_START_TIMHI;
620         break;
621       default:
622         startCmd = CSL_TMR_CMD_START64;
623         break;
624   }
626   if(timer->hwi != NULL_PTR) {
627 #if defined (_TMS320C6X)
628     eventId = timer->eventId;
629 #else
630     eventId = 0u;
631 #endif
632     Osal_ClearInterrupt(eventId, timer->intNum);
633     Osal_EnableInterrupt(eventId, timer->intNum);
634   }
635   else {
636       status = TimerP_FAILURE;
637   }
639   /* Load the period values */
640   if (timer->mode == TimerP_Timer64Mode_64BITGPTIMER) {
641     /* Reset the Timer */
642     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET64, NULL_PTR);
644     /* Set the timer mode*/
645     hwSetup.tmrTimerMode = runMode;
646     CSL_tmrHwSetup(timer->hTmr, &hwSetup);
648     /* Load the period register */
649     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDLO, (void *)&timer->period);
651     /* Load the period register */
652     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDHI, (void *)&timer->prescalar);
653   }
654   else {
655     if (timer->timerHalf == TimerP_Timer64Half_LOWER) {
656       /* Reset the Timer */
657       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMLO, NULL_PTR);
659       /* Set the timer mode*/
660       hwSetup.tmrTimerMode = runMode;
661       CSL_tmrHwSetup(timer->hTmr, &hwSetup);
663       /* Load the period register */
664       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDLO, (void *)&timer->period);
665     }
666     else {
667       /* Reset the Timer */
668       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL_PTR);
670       /* Set the timer mode*/
671       hwSetup.tmrTimerMode = runMode;
672       CSL_tmrHwSetup(timer->hTmr, &hwSetup);
674       /* Load the period register */
675       CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_LOAD_PRDHI, (void *)&timer->period);
676     }
677   }
679   /* Start the timer in a given Mode. */
680   CSL_tmrHwControl(timer->hTmr, startCmd, (void *)&timeCountMode);
682   HwiP_restore(key);
684   return (status);
687 /* Timer stop module function
688  * more details on the documentation of this interface
689  * function can be found in the TimerP.h interface
690  * header file */
692 TimerP_Status TimerP_stop(TimerP_Handle handle)
694   TimerP_Struct *timer = (TimerP_Struct *) handle;
695   TIMOSAL_Assert((handle == NULL_PTR));
696   uint32_t          eventId;
697   TimerP_Status     status = TimerP_OK;
699   if ((timer->mode == TimerP_Timer64Mode_CHAINED) || (timer->timerHalf == TimerP_Timer64Half_LOWER)) {
700     /* Stop the Timer */
701     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMLO, NULL_PTR);
702   }
703   else {
704     /* Stop the Timer */
705     CSL_tmrHwControl(timer->hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL_PTR);
706   }
708   if(timer != NULL_PTR) {
709 #if defined (_TMS320C6X)
710     eventId = timer->eventId;
711 #else
712     eventId = 0u;
713 #endif
714       Osal_ClearInterrupt(eventId, timer->intNum);
715       Osal_DisableInterrupt(eventId, timer->intNum);
716   }
717   else {
718       status = TimerP_FAILURE;
719   }
721   return(status);
724 /* Timer set micro seconds module function
725  * more details on the documentation of this interface
726  * function can be found in the TimerP.h interface
727  * header file */
728 TimerP_Status TimerP_setPeriodMicroSecs(TimerP_Handle handle, uint32_t microsecs)
730   TimerP_Struct *timer = (TimerP_Struct *) handle;
732   if (!TimerP_timer64SetMicroSeconds(timer, microsecs)) {
733     return (TimerP_FAILURE);
734   }
735   else {
736     return (TimerP_OK);
737   }
740 /* Timer clear the interrupt module function
741  * more details on the documentation of this interface
742  * function can be found in the TimerP.h interface
743  */
744 TimerP_Status TimerP_ClearInterrupt(TimerP_Handle handle)
746     TimerP_Struct *timer = (TimerP_Struct *) handle;
747     HwiP_clearInterrupt(timer->intNum);
749     return (TimerP_OK);
751 #if defined (SOC_OMAPL137) || defined (SOC_OMAPL138)
752 /* Below API is not supported for OMAPL13X SoCs for bare metal */
753 #else
754 /* Get time in micro seconds */
755 uint64_t TimerP_getTimeInUsecs(void)
757     TimeStamp_Struct timestamp64;
758     uint64_t         cur_ts, freq;
759     int32_t             tsFreqKHz;
761     osalArch_TimestampGet64(&timestamp64);
763     /* Get the frequency of the timeStatmp provider */
764     tsFreqKHz  = osalArch_TimeStampGetFreqKHz();
766     cur_ts = ((uint64_t) timestamp64.hi << 32) | timestamp64.lo;
767     freq = ((uint64_t) 0U << 32) | (tsFreqKHz);
769     return ((cur_ts*1000u)/freq);
771 #endif
772 /* This would implement the gp timer on KeyStone devices */