[PDK-6649] OSAL: nonos: Fix TimerP_delete to update gTimerAnyMask
[processor-sdk/pdk.git] / packages / ti / osal / src / nonos / timer / v2 / TimerP_nonos.c
1 /*
2  * Copyright (c) 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_csl_nonos.c ========
34  */
37 #include <stdint.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
41 #include <ti/osal/TimerP.h>
42 #include <ti/csl/soc.h>
43 #include <ti/csl/csl_rti.h>
44 #include <ti/csl/arch/csl_arch.h>
45 #include <ti/osal/src/nonos/Nonos_config.h>
47 /* DM Timer Implementation */
48 extern void Osal_DebugP_assert(int32_t expression, const char *file, int32_t line);
49 #define TIMOSAL_Assert(expression) (Osal_DebugP_assert(((int32_t)((expression)?1:0)),\
50                                                   __FILE__, __LINE__))
52 /* Local defines for the rti timer */
53 #define TIMERP_RTI_MAX_PERIOD                (0xffffffffU)
54 #define TIMERP_PRESCALER_DEF                 (1U)
55 /* Local Timer Struct */
56 typedef struct TimerP_Struct_s
57 {
58   bool     used;       /* In use or not status */
59   uint32_t id;         /* timer Id */
60   uint32_t periodType; /* Period type, default micro seconds */
61   uint32_t freqLo;     /* least siginificant 32-bits of frequency */
62   uint32_t freqHi;     /* most siginificant 32-bits of frequency  */
63   uint32_t startMode;  /* timer start mode */
64   uint32_t runMode;    /* timer run mode   */
65   uint32_t period;     /* Period of a tick */
66   TimerP_Fxn tickFxn;  /* Timer Tick function */
67   void*    arg;        /* Argument passed into the timer function. */
68   uint32_t availMask;   /* Available timer mask */
69   HwiP_Handle hwi;      /* Hwi handle for tickFxn */
70   int32_t  eventId;     /* Event Id for C66x */
71   int32_t  intNum;      /* Interrupt Number */
72   uint32_t prescaler;
73 }TimerP_Struct;
75 /* As static allocation is used, the following provides the structs
76  * The TimerP_Struct pool servers to get an available timer
77  * handle during timer create API call.
78  */
79 TimerP_Struct gTimerStructs[OSAL_NONOS_CONFIGNUM_TIMER];
80 static        uint32_t    gTimerInitDone = 0U;
81 static        uint32_t    gTimerAnyMask;
83 /* external variables */
84 extern uint32_t  gOsalTimerAllocCnt, gOsalTimerPeak;
86 /* Local functions  */
87 static uint32_t TimerP_getTimerBaseAddr(uint32_t timer_id);
88 static void TimerP_rtiTimerStub(uintptr_t arg);
89 static void  TimerP_rtiTimerInitDevice(const TimerP_Struct *timer, uint32_t baseAddr);
90 static bool TimerP_rtiTimerCheckOverflow(uint32_t a, uint32_t b);
91 static bool TimerP_rtiTimerSetMicroSeconds(TimerP_Struct *timer, uint32_t period);
92 static TimerP_Status TimerP_rtiTimerDeviceCfg(TimerP_Struct *timer, uint32_t baseAddr);
93 static TimerP_Status TimerP_rtiTimerInitObj(TimerP_Struct *timer, TimerP_Fxn tickFxn, const TimerP_Params *params);
94 static TimerP_Status TimerP_rtiTimerInstanceInit(TimerP_Struct *timer, uint32_t id, TimerP_Fxn tickFxn, const TimerP_Params *params);
96 /*
97  * This private function returns the base address of the timer based on
98  * the ID passed in.
99  */
100 static uint32_t TimerP_getTimerBaseAddr(uint32_t timer_id)
102   uint32_t addr;
104   if (timer_id < TimerP_numTimerDevices) {
105     addr = (uint32_t) gRtiTimerPInfoTbl[timer_id].baseAddr;
106   }
107   else {
108     addr = (uint32_t)0U;
109   }
110   return (addr);
113 /*
114  * This private function is a stub function for the timer ISR
115  * function that is registered from the application
116  */
117 static void TimerP_rtiTimerStub(uintptr_t arg)
119   TimerP_Struct *timer = (TimerP_Struct *) arg;
120   uint32_t baseAddr = TimerP_getTimerBaseAddr(timer->id);
122   /* Disable the Timer interrupts */
124   if (timer->runMode == (uint32_t)TimerP_RunMode_ONESHOT) {
125     (void)TimerP_stop((TimerP_Handle) timer);
126   }
128   /* acknowledge the interrupt */
129   if ((timer->id & 0x01U) != 0U) {
130     (void)RTITmrIntStatusClear(baseAddr, RTI_TMR_INT_INT1_FLAG);
131   }
132   else {
133     (void)RTITmrIntStatusClear(baseAddr, RTI_TMR_INT_INT0_FLAG);
134   }
136   /* call the user's ISR */
137   timer->tickFxn((uintptr_t)timer->arg);
139   /* Enable the Timer interrupts */
142 /*
143  * This priviate function initializes the timer registers
144  */
145 static void  TimerP_rtiTimerInitDevice(const TimerP_Struct *timer, uint32_t baseAddr)
147   uint32_t key;
149   key = (uint32_t)HwiP_disable();
151   if ((timer->id & 0x01U) != 0U) {
152     (void)RTITmrClear(baseAddr, RTI_TMR_CNT_BLK_INDEX_1, RTI_TMR_CMP_BLK_INDEX_1);
153   }
154   else {
155     (void)RTITmrClear(baseAddr, RTI_TMR_CNT_BLK_INDEX_0, RTI_TMR_CMP_BLK_INDEX_0);
156   }
158   if (timer->hwi != NULL_PTR) {
159     /* clear any previously latched timer interrupts */
160     Osal_ClearInterrupt(timer->eventId, timer->intNum);
161     Osal_DisableInterrupt(timer->eventId, timer->intNum);
162   }
164   HwiP_restore(key);
167 /*
168  * This priviate function checks if there is any overflow in
169  * timer period computations, i.e. the period is too big.
170  */
171 static bool TimerP_rtiTimerCheckOverflow(uint32_t a, uint32_t b)
173   return ((b > 0U) && (a > (TimerP_MAX_PERIOD/b)));
176 /*
177  * This is a private function to set the period of the timer
178  * register for a specified micro second value
179  */
180 static bool TimerP_rtiTimerSetMicroSeconds(TimerP_Struct *timer, uint32_t period)
182   uint64_t  counts;
183   uint32_t  freqKHz;
184   bool      ret = (bool) true;
186   (void)TimerP_stop(timer);
188   /*
189    * The frequency of FRC is equal to the clock rate divided by (prescaler + 1)
190    */
191   freqKHz = ((timer->freqLo/(TIMERP_PRESCALER_DEF+1U)) + 500U)/ 1000U;
192   if (TimerP_rtiTimerCheckOverflow(freqKHz, period/1000U)) {
193     ret = (bool) false;
194   }
196   if (ret == (bool) true) {
197     counts = ((uint64_t)freqKHz * (uint64_t)period) / (uint64_t)1000U;
198     if (counts > 0xffffffffU) {
199       ret = (bool) false;
200     }
201   }
203   if (ret == (bool) true) {
204     timer->period = (uint32_t)counts;
205     timer->periodType = (uint32_t)TimerP_PeriodType_COUNTS;
206     timer->prescaler = TIMERP_PRESCALER_DEF;
207   }
208   return(ret);
211 /*
212  * Thi is a private function to configure the timer registers for a given timer
213  * period
214  */
215 static TimerP_Status TimerP_rtiTimerDeviceCfg(TimerP_Struct *timer, uint32_t baseAddr)
217   uint32_t key;
218   TimerP_Status retVal=TimerP_OK;
219   rtiTmrConfig_t rtiCfg;
221   /* initialize the timer */
222   TimerP_rtiTimerInitDevice(timer, baseAddr);
224   key = (uint32_t)HwiP_disable();
226   /* set the period */
227   if (timer->periodType == (uint32_t)TimerP_PeriodType_MICROSECS) {
228     if (!TimerP_rtiTimerSetMicroSeconds(timer, timer->period)) {
229       HwiP_restore(key);
230       retVal = TimerP_FAILURE;
231     }
232   }
234   if(retVal == TimerP_OK)
235   {
236     /* Set prescaler, enable interrupt and select counter for comparator */
237     /* Use internal up-counter to clock free-running counter 0 */
238     rtiCfg.clkSrc = RTI_TMR_CLK_SRC_COUNTER;
239     rtiCfg.period = timer->period;
240     rtiCfg.prescaler = timer->prescaler;
241     if ((timer->id & 0x01U) != 0U) {
242       rtiCfg.cntBlkIndex = RTI_TMR_CNT_BLK_INDEX_1;
243       rtiCfg.cmpBlkIndex = RTI_TMR_CMP_BLK_INDEX_1;
244     }
245     else {
246       rtiCfg.cntBlkIndex = RTI_TMR_CNT_BLK_INDEX_0;
247       rtiCfg.cmpBlkIndex = RTI_TMR_CMP_BLK_INDEX_0;
248     }
249     (void)RTITmrConfigure(baseAddr, &rtiCfg);
250     HwiP_restore(key);
251   }
253   return (retVal);
256 /*
257  * This is a private function to initialize the timer counter, period and compare
258  * registers before starting the timers
259  */
260 static TimerP_Status TimerP_rtiTimerInitObj(TimerP_Struct *timer, TimerP_Fxn tickFxn, const TimerP_Params *params)
262   timer->tickFxn = tickFxn;
264   /*
265    * Update the default initializations to user configured values
266    */
267   if ( params->extfreqLo != TimerP_USE_DEFAULT) {
268     timer->freqLo   = (uint32_t)params->extfreqLo;
269   }
270   else  {
271     if (params->intfreqLo != TimerP_USE_DEFAULT)  {
272       timer->freqLo = (uint32_t)params->intfreqLo;
273     }
274     else {
275       timer->freqLo = (uint32_t)TimerP_getDefaultFreqLo(timer->id);
276     }
277   }
279   if ( params->extfreqHi != TimerP_USE_DEFAULT) {
280     timer->freqHi   =  (uint32_t)params->extfreqHi;
281   }
282   else  {
283     if (params->intfreqHi != TimerP_USE_DEFAULT)  {
284       timer->freqHi = (uint32_t)params->intfreqHi;
285     }
286     else {
287       timer->freqHi =  (uint32_t)TimerP_getDefaultFreqHi(timer->id);
288     }
289   }
291   if ( params->period != 0u) {
292     timer->period   = params->period;
293   }
294   else  {
295     timer->period   = 0u;
296   }
298   if ( params->arg != NULL_PTR) {
299     timer->arg     = params->arg;
300   }
302   if ( params->intNum != TimerP_USE_DEFAULT) {
303     timer->intNum = params->intNum;
304   }
305   else {
306     timer->intNum = gRtiTimerPInfoTbl[timer->id].intNum;
307   }
309 #if defined (_TMS320C6X)
310   if ( params->eventId != TimerP_USE_DEFAULT) {
311     timer->eventId = params->eventId;
312   }
313   else {
314     timer->eventId = gRtiTimerPInfoTbl[timer->id].eventId;
315   }
316 #else
317   timer->eventId = 0;
318 #endif
320   timer->periodType = params->periodType;
321   timer->startMode  = params->startMode;
322   timer->runMode    = params->runMode;
324   return(TimerP_OK);
327 /*
328  * This is a private function to initialize the timer instance, that sets up the timer ISR to
329  * a specified timer id and sets up the timer compare, counter and period registers
330  */
331 static TimerP_Status TimerP_rtiTimerInstanceInit(TimerP_Struct *timer, uint32_t id, TimerP_Fxn tickFxn, const TimerP_Params *params)
333   TimerP_Status ret = TimerP_OK;
334   uint32_t      key;
335   uint32_t      i;
336   uint32_t      tempId = 0xffffu;
337   OsalRegisterIntrParams_t interruptRegParams;
338   uint32_t      baseAddr;
339   int32_t       intNum;
340   uint32_t      timerPAnyMask = (uint32_t)(TIMERP_ANY_MASK);
342   if ((id != TimerP_ANY) && (id >= TimerP_numTimerDevices)) {
343     ret = TimerP_FAILURE;
344   }
346   /* Get the timer Id */
347   if (ret == TimerP_OK)
348   {
349       /* Set the available timer id mask to all */
350     if (gTimerInitDone == 0U)
351     {
352       gTimerAnyMask  = TIMERP_AVAILABLE_MASK;
353       gTimerInitDone = 1U;
354     }
356     timer->availMask = gTimerAnyMask;
358     key = (uint32_t)HwiP_disable();
360     if (id == TimerP_ANY) {
361       for (i = 0U; i < TimerP_numTimerDevices; i++) {
362         uint32_t shift, nshift;
363         shift  = ((uint32_t) 1U) << i;
364         nshift = ~shift;
365         if (((timerPAnyMask    & shift) != (uint32_t) 0U ) &&
366             ((timer->availMask & shift) != (uint32_t) 0U )) {
367           timer->availMask &= nshift;
368           tempId = i;
369           break;
370         }
371       }
372     }
373     else
374     {
375           if ((timer->availMask & ((uint32_t)1u << id)) > 0U)
376           {
377         uint32_t shift, nshift;
378         shift  = ((uint32_t) 1u) << id;
379         nshift = ~shift;
380         timer->availMask &= nshift;
381         tempId = id;
382       }
383     }
385     gTimerAnyMask =  timer->availMask;
387     /* Initialize the timer state object */
388     timer->id = tempId; /* Record the timer Id */
389     baseAddr = TimerP_getTimerBaseAddr(timer->id);
391     HwiP_restore(key);
393     if (tempId == 0xffffU) {
394       ret = TimerP_NOT_AVAILABLE;
395     }
396   }
398   /* Initialize the timer state object */
399   if (ret == TimerP_OK) {
400     ret = TimerP_rtiTimerInitObj(timer, tickFxn, params);
401   }
403   /* Create the Hwi Funtion for the tick funtion */
404   if (ret == TimerP_OK)
405   {
406     if (timer->tickFxn != (TimerP_Fxn) NULL_PTR)
407     {
408       intNum          = timer->intNum;
409       /* Initialize with defaults */
410       Osal_RegisterInterrupt_initParams(&interruptRegParams);
412       /* Populate the interrupt parameters */
413       interruptRegParams.corepacConfig.arg=(uintptr_t) timer;
414       interruptRegParams.corepacConfig.name=(char *) NULL_PTR;
415       interruptRegParams.corepacConfig.isrRoutine=TimerP_rtiTimerStub;
417 #if defined (__ARM_ARCH_7A__) || defined (__aarch64__) || defined (__TI_ARM_V7R4__)
418 #if defined(SOC_AM335x) || defined(SOC_AM437x) || defined(SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200)
419       interruptRegParams.corepacConfig.triggerSensitivity =  (uint32_t)OSAL_ARM_GIC_TRIG_TYPE_HIGH_LEVEL;
420       interruptRegParams.corepacConfig.priority = 0x20U;
421 #else
422       interruptRegParams.corepacConfig.triggerSensitivity =  (uint32_t)OSAL_ARM_GIC_TRIG_TYPE_EDGE;
423 #endif
424 #endif
426 #if defined(_TMS320C6X)
427       interruptRegParams.corepacConfig.corepacEventNum= timer->eventId; /* Event going in to CPU */
428 #endif
429       interruptRegParams.corepacConfig.intVecNum=intNum; /* Host Interrupt vector */
431       /* Register interrupts */
432       (void)Osal_RegisterInterrupt(&interruptRegParams,&(timer->hwi));
434       if (timer->hwi == NULL_PTR)
435       {
436         ret = TimerP_ISR_HOOK_ERR;
437       }
438     }
439     else
440     {
441       timer->hwi = NULL_PTR;
442     }
443   }
445   /* timer post init */
446   if (ret == TimerP_OK)
447   {
448      ret = TimerP_rtiTimerDeviceCfg(timer, baseAddr);
450      if (timer->startMode == (uint32_t)TimerP_StartMode_AUTO) {
451          (void)TimerP_start(timer);
452      }
453   }
455   return (ret);
459 /* Interface functions */
461 /* Default parameter initialization module function
462  * more details on the documentation of this interface
463  * function can be found in the TimerP.h interface
464  * header file */
465 void TimerP_Params_init(TimerP_Params *params)
467     TIMOSAL_Assert((params == NULL_PTR));
469     if(params != NULL_PTR) {
470       /* Set the default values */
471       params->arg         = NULL_PTR;
472       params->extfreqHi   = TimerP_USE_DEFAULT;
473       params->extfreqLo   = TimerP_USE_DEFAULT;
474       params->intfreqHi   = TimerP_USE_DEFAULT;
475       params->intfreqLo   = TimerP_USE_DEFAULT;
476       params->name        = (char *) NULL_PTR;
477       params->period      = 0;
478       params->runMode     = (uint32_t)TimerP_RunMode_CONTINUOUS;
479       params->startMode   = (uint32_t)TimerP_StartMode_AUTO;
480       params->periodType  = (uint32_t)TimerP_PeriodType_MICROSECS;
481       params->intNum      = (int32_t)TimerP_USE_DEFAULT;
482 #if defined (_TMS320C6X)
483       params->eventId     = TimerP_USE_DEFAULT;
484 #endif
485     }
486     return;
489 /* Timer create module function
490  * more details on the documentation of this interface
491  * function can be found in the TimerP.h interface
492  * header file */
493 TimerP_Handle TimerP_create(int32_t id,
494                             TimerP_Fxn tickFxn,
495                             const TimerP_Params *inParams)
498   uint32_t          i;
499   uintptr_t         key;
500   TimerP_Handle     ret_handle;
501   TimerP_Params     params;
503   if (inParams != NULL_PTR)
504   {
505     params = *inParams;
506   }
507   else
508   {
509     TimerP_Params_init(&params);
510   }
512   key = HwiP_disable();
514   for (i = 0; i < OSAL_NONOS_CONFIGNUM_TIMER; i++)
515   {
516     if (gTimerStructs[i].used == (bool)false)
517     {
518       gTimerStructs[i].used = (bool)true;
520       /* Update statistics */
521       gOsalTimerAllocCnt++;
522       if (gOsalTimerAllocCnt > gOsalTimerPeak)
523       {
524           gOsalTimerPeak = gOsalTimerAllocCnt;
525       }
527       gTimerStructs[i].id  = (uint32_t)id;
529       break;
530     }
531   }
533   HwiP_restore(key);
535   if (i == OSAL_NONOS_CONFIGNUM_TIMER)
536   {
537     ret_handle = NULL_PTR;
538   }
539   else
540   {
541     /* Start the timer for that period/mode */
542     ret_handle = ((TimerP_Handle)&gTimerStructs[i]);
543   }
545   if (ret_handle != NULL_PTR)
546   {
547     if (TimerP_rtiTimerInstanceInit(&gTimerStructs[i], (uint32_t) id, tickFxn, &params) != TimerP_OK) {
548       /* Free up the consumed timer memory */
549       gTimerStructs[i].used = (bool)false;
550       ret_handle = NULL_PTR;
551     }
552   }
554   /* start timer if it is auto mode */
555   if ((params.startMode == (uint32_t)TimerP_StartMode_AUTO) &&
556       (ret_handle != NULL_PTR) )
557   {
558      if(TimerP_start((TimerP_Handle)&gTimerStructs[i]) != TimerP_OK) {
559         gTimerStructs[i].used = (bool)false;
560         /* TBD: should we call TimerP_delete() here? */
561         ret_handle = NULL_PTR;
562      }
563   }
564   return (ret_handle);
568 /* Timer delete module function
569  * more details on the documentation of this interface
570  * function can be found in the TimerP.h interface
571  * header file */
572 TimerP_Status TimerP_delete(TimerP_Handle handle)
574   /* Release or free the memory */
575   uint32_t key;
576   uint32_t id;
577   uint32_t index = (uint32_t)(( ((uintptr_t) handle) - ((uintptr_t) gTimerStructs) )/sizeof(TimerP_Struct)); /* struct subtraction */
578   TimerP_Status ret = TimerP_OK;
579   TimerP_Struct *timer = (TimerP_Struct *) handle;
580   TIMOSAL_Assert((handle == NULL_PTR));
582   key = (uint32_t)HwiP_disable();
584   if((timer != NULL_PTR) && (gTimerStructs[index].used))
585   {
586     /* clear the ISR that was set before */
587     if (timer->hwi != NULL) {
588       (void)HwiP_delete(timer->hwi);
589     }
591     /* reset the timer's bit field in the mask and clear the used flag */
592     gTimerStructs[index].used = (bool)false;
593     id = gTimerStructs[index].timerId;
594     uint32_t shift = ((uint32_t) 1u) << id;
595     if(((gTimerAnyMask & shift)) == 0U)
596     {
597       gTimerAnyMask |= shift;
598     }
599     else
600     {
601       ret = TimerP_FAILURE;     
602     }
603     /* Found the osal timer object to delete */
604     if (gOsalTimerAllocCnt > 0U)
605     {
606       gOsalTimerAllocCnt--;
607     }
608   }
609   else
610   {
611     ret = TimerP_FAILURE;
612   }
614   HwiP_restore(key);
616   return (ret);
620 /* Timer start module function
621  * more details on the documentation of this interface
622  * function can be found in the TimerP.h interface
623  * header file */
624 TimerP_Status TimerP_start(TimerP_Handle handle)
626   uint32_t  key;
627   TimerP_Struct *timer = (TimerP_Struct *) handle;
628   TimerP_Status retVal = TimerP_OK;
630   uint32_t baseAddr = TimerP_getTimerBaseAddr(timer->id);
632   if (baseAddr == 0U) {
633     retVal = TimerP_NOT_AVAILABLE;
634   }
635   else
636   {
638     key = (uint32_t)HwiP_disable();
640     (void)TimerP_stop(handle);
642     if ((timer->id & 0x01U) != 0U) {
643       (void)RTITmrIntStatusClear(baseAddr, RTI_TMR_INT_INT1_FLAG);
644     }
645     else {
646       (void)RTITmrIntStatusClear(baseAddr, RTI_TMR_INT_INT0_FLAG);
647     }
648     if(timer->hwi != NULL_PTR) {
649       Osal_ClearInterrupt(timer->eventId, timer->intNum);
650       Osal_EnableInterrupt(timer->eventId, timer->intNum);
651     }
653     if ((timer->id & 0x01U) != 0U) {
654       (void)RTITmrEnable(baseAddr, RTI_TMR_CNT_BLK_INDEX_1);
655     }
656     else {
657       (void)RTITmrEnable(baseAddr, RTI_TMR_CNT_BLK_INDEX_0);
658     }
660     HwiP_restore(key);
661   }
662   return (retVal);
665 /* Timer stop module function
666  * more details on the documentation of this interface
667  * function can be found in the TimerP.h interface
668  * header file */
670 TimerP_Status TimerP_stop(TimerP_Handle handle)
672   uint32_t  key;
673   TimerP_Struct *timer = (TimerP_Struct *) handle;
674   TimerP_Status retVal = TimerP_OK;
676   uint32_t baseAddr = TimerP_getTimerBaseAddr(timer->id);
678   if (baseAddr == 0U) {
679     retVal = TimerP_NOT_AVAILABLE;
680   }
681   else
682   {
683     key = (uint32_t)HwiP_disable();
685     if ((timer->id & 0x01U) != 0U) {
686       (void)RTITmrDisable(baseAddr, RTI_TMR_CNT_BLK_INDEX_1);
687     }
688     else {
689       (void)RTITmrDisable(baseAddr, RTI_TMR_CNT_BLK_INDEX_0);
690     }
692     if(timer->hwi != NULL_PTR) {
693       Osal_ClearInterrupt(timer->eventId, timer->intNum);
694       Osal_DisableInterrupt(timer->eventId, timer->intNum);
695     }
697     HwiP_restore(key);
698   }
700   return(retVal);
703 /* Timer set micro seconds module function
704  * more details on the documentation of this interface
705  * function can be found in the TimerP.h interface
706  * header file */
707 TimerP_Status TimerP_setPeriodMicroSecs(TimerP_Handle handle, uint32_t microsecs)
709   TimerP_Struct *timer = (TimerP_Struct *) handle;
710   TimerP_Status retVal = TimerP_OK;
711   if (!TimerP_rtiTimerSetMicroSeconds(timer, microsecs)) {
712     retVal = TimerP_FAILURE;
713   }
714   return (retVal);
717 /* Get time in micro seconds */
718 uint64_t TimerP_getTimeInUsecs(void)
720     TimeStamp_Struct timestamp64;
721     uint64_t         cur_ts, freq;
722     uint32_t         tsFreqKHz;
724     /* Get the timestamp */
725     osalArch_TimestampGet64(&timestamp64);
727     /* Get the frequency of the timeStatmp provider */
728     tsFreqKHz  = (uint32_t)osalArch_TimeStampGetFreqKHz();
730     cur_ts = ((uint64_t) timestamp64.hi << 32U) | timestamp64.lo;
731     freq = (uint64_t) (tsFreqKHz);
733     return ((cur_ts*1000u)/freq);
735 /* This file implements the RTI timer osal functions on devices */