db8d39ca8a72489a9227cea23a8d2fac188918f7
[processor-sdk/pdk.git] / packages / ti / osal / src / nonos / timer / v1 / TimerP_nonos.c
1 /*
2  * Copyright (c) 2015-2019, 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_timer.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 dm timer */
53 #define TIMERP_DM_TCLR_START_ONESHOT        (TIMER_ONESHOT_NOCMP_ENABLE)
54 #define TIMERP_DM_TCLR_START_CONTINUOUS     (TIMER_AUTORLD_CMP_ENABLE)
55 #define TIMERP_DM_TCLR_START_DYNAMIC        (0x43U)
56 #define TIMERP_DM_TCLR_STOP_MASK            (0xfffffffeU)
57 #define TIMERP_DM_TWPS_W_PEND_TMAR          (0x10U)
58 #define TIMERP_DM_TWPS_W_PEND_TLDR          (0x4U)
59 #define TIMERP_DM_TWPS_W_PEND_TCRR          (0x2U)
60 #define TIMERP_DM_TWPS_W_PEND_TCLR          (0x1U)
61 #define TIMERP_DM_IRQSTATUS_OVF_IT_FLAG     (0x2U)
62 #define TIMERP_DM_IRQSTATUS_MAT_IT_FLAG     (0x1U)
63 #define TIMERP_DM_TIOCP_CFG_SOFTRESET_FLAG  (0x1U)
64 #define TIMERP_DM_TSICR_POSTED              (0x4U)
65 #define TIMERP_DM_TSICR_READMODE            (0x8U)
66 #define TIMERP_DM_MAX_PERIOD                (0xffffffffU)
69 /* Local Timer Struct */
70 typedef struct TimerP_Struct_s
71 {
72   bool     used;       /* In use or not status */
73   uint32_t timerId;    /* timer Id */
74   uint32_t periodType; /* Period type, default micro seconds */
75   uint32_t freqLo;     /* least siginificant 32-bits of frequency */
76   uint32_t freqHi;     /* most siginificant 32-bits of frequency  */
77   uint32_t startMode;  /* timer start mode */
78   uint32_t runMode;    /* timer run mode   */
79   uint32_t period;     /* Period of a tick */
80   TimerP_Fxn tickFxn;  /* Timer Tick function */
81   void*    arg;        /* Argument passed into the timer function. */
82   uint32_t availMask;   /* Available timer mask */
83   HwiP_Handle hwi;      /* Hwi handle for tickFxn */
84 #if defined (_TMS320C6X)
85   uint32_t eventId;     /* Event Id for C66x */
86 #endif
87   int32_t  intNum;      /* Interrupt Number */
88   uint32_t rollovers;
89   uint32_t savedCurrCount;
90   uint32_t prevThreshold;
91   uint32_t tmar;
92   uint32_t tier;
93   uint32_t twer;
94   uint32_t tclr;
95   uint32_t tsicr;
96   uint32_t tiocpCfg;
98 }TimerP_Struct;
100 /* As static allocation is used, the following provides the structs
101  * The TimerP_Struct pool servers to get an available timer
102  * handle during timer create API call.
103  */
104 TimerP_Struct gTimerStructs[OSAL_NONOS_CONFIGNUM_TIMER] = {0U};
105 static        uint32_t    gTimerInitDone = 0U;
106 static        uint32_t    gTimerAnyMask;
107 #if defined (BUILD_MCU)
108 static        bool        gUpdateFlag = (bool)true;
109 #endif
111 /* external variables */
112 extern uint32_t  gOsalTimerAllocCnt, gOsalTimerPeak;
114 /* Local functions  */
115 static uint32_t TimerP_getTimerBaseAddr(uint32_t timer_id);
116 static void TimerP_dmTimerStub(uintptr_t arg);
117 static void  TimerP_dmTimerInitDevice(TimerP_Struct *timer, uint32_t baseAddr);
118 static bool TimerP_dmTimerCheckOverflow(uint32_t a, uint32_t b);
119 static bool TimerP_dmTimerSetMicroSeconds(TimerP_Struct *timer, uint32_t period);
120 static TimerP_Status TimerP_dmTimerDeviceCfg(TimerP_Struct *timer, uint32_t baseAddr);
121 static TimerP_Status TimerP_dmTimerInitObj(TimerP_Struct *timer, TimerP_Fxn tickFxn, const TimerP_Params *params);
122 static TimerP_Status TimerP_dmTimerInstanceInit(TimerP_Struct *timer, uint32_t id, TimerP_Fxn tickFxn, const TimerP_Params *params);
124 /*
125  * This private function returns the base address of the timer based on
126  * the ID passed in.
127  */
128 static uint32_t TimerP_getTimerBaseAddr(uint32_t timer_id)
130     uint32_t addr;
132     if (timer_id < TimerP_numTimerDevices) {
133 #if defined (BUILD_MCU)
134         if (gUpdateFlag == (bool)true)
135         {
136             TimerP_updateDefaultInfoTbl();
137             gUpdateFlag = (bool)false;
138         }
139 #endif
140       addr = (uint32_t) gDmTimerPInfoTbl[timer_id].baseAddr;
141     }
142     else {
143       addr = (uint32_t)0U;
144     }
145     return (addr);
148 /*
149  * This private function is a stub function for the timer ISR
150  * function that is registered from the application
151  */
152 static void TimerP_dmTimerStub(uintptr_t arg)
154   TimerP_Struct *timer = (TimerP_Struct *) arg;
155   uint32_t baseAddr = TimerP_getTimerBaseAddr(timer->timerId);
157   /* Disable the Timer interrupts */
158   (void)TIMERIntDisable(baseAddr, TIMER_INT_OVF_EN_FLAG);
160   /* acknowledge the interrupt */
161   (void)TIMERIntStatusClear(baseAddr, timer->tier);
163   /* call the user's ISR */
164   timer->tickFxn((uintptr_t)timer->arg);
166    /* Enable the Timer interrupts */
167   (void)TIMERIntEnable(baseAddr, TIMER_INT_OVF_EN_FLAG);
170 /*
171  * This priviate function initializes the timer counter, period and compare
172  * registers
173  */
174 static void  TimerP_dmTimerInitDevice(TimerP_Struct *timer, uint32_t baseAddr)
176   uint32_t key, status;
177   uint32_t tcrr =0, tldr =0;
179   key = (uint32_t)HwiP_disable();
181   (void)TIMERDisable(baseAddr);
182   do {
183     status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCLR);
184   } while (status != (uint32_t) 0u);
186   (void)TIMERCounterSet(baseAddr, tcrr);
188    do {
189     status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCRR);
190   } while (status != (uint32_t) 0u);
192   (void)TIMERReloadSet(baseAddr, tldr);
194   do {
195     status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TLDR);
196   } while (status != (uint32_t) 0u);
199   HwiP_restore(key);
202 /*
203  * This priviate function checks if there is any overflow in
204  * timer period computations
205  */
206 static bool TimerP_dmTimerCheckOverflow(uint32_t a, uint32_t b)
208   return ((b > 0u) && (a > (TimerP_MAX_PERIOD/b)));
211 /*
212  * This is a private function to set the period of the timer
213  * register for a specified micro second value
214  */
215 static bool TimerP_dmTimerSetMicroSeconds(TimerP_Struct *timer, uint32_t period)
217     uint64_t  counts;
218     uint32_t  prdCounts;
219     uint32_t  freqKHz;
220     uint32_t  roundUp;
221     uint32_t  baseAddr = TimerP_getTimerBaseAddr(timer->timerId);
222     uint32_t  status;
223     bool retVal=(bool)true;
225     (void)TimerP_stop(timer);
227     roundUp = ((timer->freqLo % 1000U) >= 500U) ? 1U : 0U;
229     freqKHz = (timer->freqLo / 1000U) + roundUp;
230     if (TimerP_dmTimerCheckOverflow(freqKHz, period/1000U)) {
231             retVal = (bool)false;
232     }
233     else
234     {
235     counts = ((uint64_t)freqKHz * (uint64_t)period) / (uint64_t)1000U;
236     if (counts > 0xffffffffU) {
237         retVal = (bool)false;
238     }
239     else
240     {
241        prdCounts = (uint32_t)(counts - (uint32_t) 1u);
243        timer->period = prdCounts;
244        timer->periodType = (uint32_t)TimerP_PeriodType_COUNTS;
246        if ((timer->runMode == (uint32_t)TimerP_RunMode_CONTINUOUS) ||
247          (timer->runMode == (uint32_t)TimerP_RunMode_ONESHOT)) 
248         {
249            (void)TIMERCounterSet(baseAddr, TimerP_MAX_PERIOD - prdCounts);
251            do {
252              status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCRR);
253            } while (status != (uint32_t) 0u);
255            (void)TIMERReloadSet(baseAddr,TimerP_MAX_PERIOD - prdCounts);
256            do {
257              status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TLDR);
258            } while (status != (uint32_t) 0u);
259         }
260         else
261         {
262           (void)TIMERCounterSet(baseAddr, 0u);
263           do {
264           status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCRR);
265           } while (status != (uint32_t) 0u);
267           (void)TIMERCompareSet(baseAddr, prdCounts);
268           do {
269           status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TMAR);
270           } while (status != (uint32_t) 0u);
271        }
272      }
273    }
274     return(retVal);
277 /*
278  * Thi is a private function to configure the timer registers for a given timer
279  * period
280  */
281 static TimerP_Status TimerP_dmTimerDeviceCfg(TimerP_Struct *timer, uint32_t baseAddr)
283     uint32_t key, tsicr;
284     uint32_t status;
285     TimerP_Status retVal=TimerP_OK;
286     /* initialize the timer */
287     TimerP_dmTimerInitDevice(timer, baseAddr);
289     key = (uint32_t)HwiP_disable();
291     /*if doing soft reset: do it first before setting other flags */
292     if ((timer->tiocpCfg & TIMERP_DM_TIOCP_CFG_SOFTRESET_FLAG) > 0U) {
293      (void)TIMERReset(baseAddr);
294     }
296     HW_WR_REG32(baseAddr + TIMER_TIOCP_CFG,
297                  (~(uint32_t)TIMER_TIOCP_CFG_SOFTRESET_SOFTRESET_VALUE_1));
299     /*xfer 'posted' setting if not current */
300     tsicr = HW_RD_REG32(baseAddr + TIMER_TSICR);
302     if ((timer->tsicr & TIMERP_DM_TSICR_POSTED) > 0U) {
303       if ((tsicr & TIMERP_DM_TSICR_POSTED) == 0U) {
304           (void)TIMERPostedModeConfig(baseAddr, (tsicr | TIMERP_DM_TSICR_POSTED));
305       }
306     }
307     else {
308         if ((tsicr & TIMERP_DM_TSICR_POSTED) != 0U) {
309           (void)TIMERPostedModeConfig(baseAddr, (tsicr & (~(uint32_t)TIMERP_DM_TSICR_POSTED)));
310         }
311     }
313     /* xfer 'readmode' setting if not current */
314     tsicr = HW_RD_REG32(baseAddr + TIMER_TSICR);
316     if ((timer->tsicr & TIMERP_DM_TSICR_READMODE)>0U) {
317         if ((tsicr & TIMERP_DM_TSICR_READMODE) == 0U) {
318             (void)TIMERReadModeConfig(baseAddr, (tsicr | TIMERP_DM_TSICR_READMODE));
319         }
320     }
321     else {
322         if ((tsicr & TIMERP_DM_TSICR_READMODE) != 0U) {
323           (void)TIMERReadModeConfig(baseAddr, (tsicr | (~(uint32_t)TIMERP_DM_TSICR_READMODE)));
324         }
325     }
327     /* set the period */
328     if (timer->periodType == (uint32_t)TimerP_PeriodType_MICROSECS) {
329         if (!TimerP_dmTimerSetMicroSeconds(timer, timer->period)) {
330             HwiP_restore(key);
331             retVal = TimerP_FAILURE;
332         }
333     }
334     else {
335         if ((timer->runMode == (uint32_t)TimerP_RunMode_CONTINUOUS) ||
336             (timer->runMode == (uint32_t)TimerP_RunMode_ONESHOT)) {
338             (void)TIMERCounterSet(baseAddr, TimerP_MAX_PERIOD - timer->period);
339             do {
340               status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCRR);
341             } while (status != (uint32_t) 0u);
343             (void)TIMERReloadSet(baseAddr, TimerP_MAX_PERIOD - timer->period);
344             do {
345               status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TLDR);
346             } while (status != (uint32_t) 0u);
348         }
349         else {
350             (void)TIMERCounterSet(baseAddr,0);
351             do {
352               status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCRR);
353             } while (status != (uint32_t) 0u);
356             (void)TIMERCompareSet(baseAddr, timer->period);
357             do {
358               status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TMAR);
359             } while (status != (uint32_t) 0u);
362         }
363     }
364    
365    if(retVal != TimerP_FAILURE)
366    {
367     if ((timer->runMode == (uint32_t)TimerP_RunMode_CONTINUOUS) ||
368         (timer->runMode == (uint32_t)TimerP_RunMode_ONESHOT)) {
369         (void)TIMERCompareSet(baseAddr, timer->tmar);
370         do {
371           status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TMAR);
372         } while (status != (uint32_t) 0u);
374     }
375     /* Enable the Timer Wakeup events represented by wakeFlags */
376     HW_WR_REG32(baseAddr + TIMER_IRQWAKEEN, timer->twer);
377     HW_WR_REG32(baseAddr + TIMER_IRQENABLE_SET, timer->tier);
378     HW_WR_REG32(baseAddr + TIMER_TCLR, timer->tclr);
379     do {
380       status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCLR);
381     } while (status != (uint32_t) 0u);
383      HwiP_restore(key);
384    } 
385     return (retVal);
388 /*
389  * This is a private function to initialize the timer counter, period and compare
390  * registers before starting the timers
391  */
392 static TimerP_Status TimerP_dmTimerInitObj(TimerP_Struct *timer, TimerP_Fxn tickFxn, const TimerP_Params *params)
394   uint8_t softreset = 1u, emufree = 0u, idlemode = 0u;
395   uint8_t mat_it_ena =0u, ovf_it_ena = 1u, tcar_it_ena =0u;
396   uint8_t mat_wup_ena =0u, ovf_wup_ena = 0u, tcar_wup_ena =0u;
399   timer->tickFxn = tickFxn;
401   timer->tiocpCfg = (uint32_t)( ((uint32_t)softreset << 0U) |
402                                 ((uint32_t)emufree   << 1U) |
403                                 ((uint32_t)idlemode  << 2U));
405   timer->tier     = (uint32_t)( ((uint32_t)mat_it_ena << 0U) |
406                                 ((uint32_t)ovf_it_ena << 1U) |
407                                 ((uint32_t)tcar_it_ena << 2U));
409   timer->twer     = (uint32_t)( ((uint32_t)mat_wup_ena << 0U) |
410                                 ((uint32_t)ovf_wup_ena << 1U) |
411                                 ((uint32_t)tcar_wup_ena << 2U));
413   timer->tclr = 0u;
415   timer->tsicr = 0u;
417   /*
418    * Update the default initializations to user configured values
419    */
420   if ( params->extfreqLo != TimerP_USE_DEFAULT) {
421     timer->freqLo            =  (uint32_t)params->extfreqLo;
422   }
423   else  {
424     if (params->intfreqLo != TimerP_USE_DEFAULT)  {
425       timer->freqLo            = (uint32_t)params->intfreqLo;
426     }
427     else {
428       timer->freqLo            =  (uint32_t)TimerP_getDefaultFreqLo(timer->timerId);
429     }
430   }
432   if ( params->extfreqHi != TimerP_USE_DEFAULT) {
433     timer->freqHi            =  (uint32_t)params->extfreqHi;
434   }
435   else  {
436     if (params->intfreqHi != TimerP_USE_DEFAULT)  {
437       timer->freqHi          = (uint32_t)params->intfreqHi;
438     }
439     else {
440       timer->freqHi          =  (uint32_t)TimerP_getDefaultFreqHi(timer->timerId);
441     }
442   }
444   if ( params->period != 0u) {
445     timer->period                = params->period;
446   }
447   else  {
448     timer->period                = 0u;
449   }
451    if ( params->arg != NULL_PTR) {
452      timer->arg                   = params->arg;
453    }
455    if ( params->intNum != TimerP_USE_DEFAULT) {
456      timer->intNum = params->intNum;
457    }
458    else {
459      timer->intNum = gDmTimerPInfoTbl[timer->timerId].intNum;
460    }
462 #if defined (_TMS320C6X)
463    if ( params->eventId != TimerP_USE_DEFAULT) {
464      timer->eventId = (uint32_t)params->eventId;
465    }
466    else {
467      timer->eventId = (uint32_t)gDmTimerPInfoTbl[timer->timerId].eventId;
468    }
469 #endif
471    timer->periodType = params->periodType;
472    timer->startMode  = params->startMode;
473    timer->runMode    = params->runMode;
474    return(TimerP_OK);
477 /*
478  * This is a private function to initialize the timer instance, that sets up the timer ISR to
479  * a specified timer id and sets up the timer compare, counter and period registers
480  */
481 static TimerP_Status TimerP_dmTimerInstanceInit(TimerP_Struct *timer, uint32_t id, TimerP_Fxn tickFxn, const TimerP_Params *params)
483   TimerP_Status ret = TimerP_OK;
484   uint32_t      key;
485   uint32_t      i;
486   uint32_t      tempId = 0xffffu;
487   OsalRegisterIntrParams_t interruptRegParams;
488   uint32_t      baseAddr;
489   int32_t       intNum;
490   uint32_t      timerPAnyMask = (uint32_t)(TIMERP_ANY_MASK);
492   if ((id != TimerP_ANY) && (id >= TimerP_numTimerDevices)) {
493     ret = TimerP_FAILURE;
494   }
496   /* Get the timer Id */
497   if (ret == TimerP_OK)
498   {
499       /* Set the available timer id mask to all */
500     if (gTimerInitDone == 0U)
501     {
502         gTimerAnyMask  = TIMERP_AVAILABLE_MASK;
503         gTimerInitDone = 1U;
504     }
506     timer->availMask = gTimerAnyMask;
508     key = (uint32_t)HwiP_disable();
510     if (id == TimerP_ANY) {
511         for (i = 0u; i < TimerP_numTimerDevices; i++) {
512             uint32_t shift, nshift;
513             shift  = ((uint32_t) 1u) << i;
514             nshift = ~shift;
515             if (((timerPAnyMask    & shift) != (uint32_t) 0u ) &&
516                 ((timer->availMask & shift) != (uint32_t) 0u )) {
517                  timer->availMask &= nshift;
518                  tempId = i;
519                  break;
520             }
521         }
522     }
523     else
524     {
525           if ((timer->availMask & ((uint32_t)1u << id)) > 0U) 
526           {
527         uint32_t shift, nshift;
528         shift  = ((uint32_t) 1u) << id;
529         nshift = ~shift;
530         timer->availMask &= nshift;
531         tempId = id;
532       }
533     }  
535     gTimerAnyMask =  timer->availMask;
537 #if defined (BUILD_MCU)
538     tempId = TimerP_mapId(tempId);
539 #endif
541     /* Initialize the timer state object */
542     timer->timerId = tempId; /* Record the timer Id */
543     baseAddr = TimerP_getTimerBaseAddr(timer->timerId);
545     HwiP_restore(key);
547     if ((tempId == 0xffffU) || (0x0 == baseAddr)) {
548       ret = TimerP_NOT_AVAILABLE;
549     }
550   }
552   /* Initialize the timer state object */
553   if (ret == TimerP_OK) {
554     ret = TimerP_dmTimerInitObj(timer, tickFxn, params);
555   }
557   /* Create the Hwi Funtion for the tick funtion */
558   if (ret == TimerP_OK)
559   {
560     if (timer->tickFxn != (TimerP_Fxn) NULL_PTR)
561     {
562       /* PDK-6534 If the timers were indeed running (left running from previous)
563             op. The provided ISR could be invoked at un-expected time.
564             Ensure to reset the timer */
566       /* tiocpCfg is populated by tiocpCfg */
567       if ((timer->tiocpCfg & TIMERP_DM_TIOCP_CFG_SOFTRESET_FLAG) > 0U) {
568        (void)TIMERReset(baseAddr);
569       }
571       intNum          = timer->intNum;
572       /* Initialize with defaults */
573       Osal_RegisterInterrupt_initParams(&interruptRegParams);
575       /* Populate the interrupt parameters */
576       interruptRegParams.corepacConfig.arg=(uintptr_t) timer;
577       interruptRegParams.corepacConfig.name=(char *) NULL_PTR;
578       interruptRegParams.corepacConfig.isrRoutine=TimerP_dmTimerStub;
580 #if defined (__ARM_ARCH_7A__) || defined (__aarch64__) || defined (__TI_ARM_V7R4__)
581 #if defined(SOC_AM335x) || defined(SOC_AM437x) || defined(SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200) || defined(SOC_AM64X)
582       interruptRegParams.corepacConfig.triggerSensitivity =  (uint32_t)OSAL_ARM_GIC_TRIG_TYPE_HIGH_LEVEL;
583       interruptRegParams.corepacConfig.priority = 0x20U;
584 #else
585       interruptRegParams.corepacConfig.triggerSensitivity =  (uint32_t)OSAL_ARM_GIC_TRIG_TYPE_EDGE;
586 #endif
587 #endif
589 #if defined(_TMS320C6X)
590       interruptRegParams.corepacConfig.corepacEventNum=(int32_t)timer->eventId; /* Event going in to CPU */
591 #endif
592       interruptRegParams.corepacConfig.intVecNum=intNum; /* Host Interrupt vector */
594       /* Register interrupts */
595       (void)Osal_RegisterInterrupt(&interruptRegParams,&(timer->hwi));
597       if (timer->hwi == NULL_PTR)
598       {
599         ret = TimerP_ISR_HOOK_ERR;
600       }
601     }
602     else
603     {
604       timer->hwi = NULL_PTR;
605     }
606   }
608   /* timer post init */
609   if (ret == TimerP_OK)
610   {
611      ret = TimerP_dmTimerDeviceCfg(timer, baseAddr);
613      if (timer->startMode == (uint32_t)TimerP_StartMode_AUTO) {
614          (void)TimerP_start(timer);
615      }
616   }
618   return (ret);
622 /* Interface functions */
624 /* Default parameter initialization module function
625  * more details on the documentation of this interface
626  * function can be found in the TimerP.h interface
627  * header file */
628 void TimerP_Params_init(TimerP_Params *params)
630     TIMOSAL_Assert((params == NULL_PTR));
632     if(params != NULL_PTR) {
633       /* Set the default values */
634       params->arg         = NULL_PTR;
635       params->extfreqHi   = TimerP_USE_DEFAULT;
636       params->extfreqLo   = TimerP_USE_DEFAULT;
637       params->intfreqHi   = TimerP_USE_DEFAULT;
638       params->intfreqLo   = TimerP_USE_DEFAULT;
639       params->name        = (char *) NULL_PTR;
640       params->period      = 0;
641       params->runMode     = (uint32_t)TimerP_RunMode_CONTINUOUS;
642       params->startMode   = (uint32_t)TimerP_StartMode_AUTO;
643       params->periodType  = (uint32_t)TimerP_PeriodType_MICROSECS;
644       params->intNum      = (int32_t)TimerP_USE_DEFAULT;
645 #if defined (_TMS320C6X)
646     params->eventId     = TimerP_USE_DEFAULT;
647 #endif
648     }  
649     return;
652 /* Timer create module function
653  * more details on the documentation of this interface
654  * function can be found in the TimerP.h interface
655  * header file */
656 TimerP_Handle TimerP_create(int32_t id,
657                             TimerP_Fxn tickFxn,
658                             const TimerP_Params *inParams)
661     uint32_t          i;
662     uintptr_t         key;
663     TimerP_Handle     ret_handle;
664     TimerP_Params    params;
666     if (inParams != NULL_PTR)
667     {
668         params = *inParams;
669     }
670     else
671     {
672         TimerP_Params_init(&params);
673     }
675     key = HwiP_disable();
677     for (i = 0; i < OSAL_NONOS_CONFIGNUM_TIMER; i++)
678     {
679         if (gTimerStructs[i].used == (bool)false)
680         {
681             gTimerStructs[i].used = (bool)true;
683             /* Update statistics */
684             gOsalTimerAllocCnt++;
685             if (gOsalTimerAllocCnt > gOsalTimerPeak)
686             {
687                 gOsalTimerPeak = gOsalTimerAllocCnt;
688             }
690             gTimerStructs[i].timerId  = (uint32_t)id;
692             break;
693         }
694     }
695     HwiP_restore(key);
697     if (i == OSAL_NONOS_CONFIGNUM_TIMER)
698     {
699         ret_handle = NULL_PTR;
700     }
701     else
702     {
703         /* Start the timer for that period/mode */
704         ret_handle = ((TimerP_Handle)&gTimerStructs[i]);
705     }
707     if (ret_handle != NULL_PTR)
708     {
709       if (TimerP_dmTimerInstanceInit(&gTimerStructs[i], (uint32_t) id, tickFxn, &params) != TimerP_OK) {
710         /* Free up the consumed timer memory */
711         gTimerStructs[i].used = (bool)false;
712         ret_handle = NULL_PTR;
713       }
714     }
716     /* start timer if it is auto mode */
717     if ((params.startMode == (uint32_t)TimerP_StartMode_AUTO) &&
718         (ret_handle != NULL_PTR) )
719     {
720        if(TimerP_start((TimerP_Handle)&gTimerStructs[i]) != TimerP_OK) {
721           gTimerStructs[i].used = (bool)false;
722           ret_handle = NULL_PTR;
723        }
724     }
725     return (ret_handle);
729 /* Timer delete module function
730  * more details on the documentation of this interface
731  * function can be found in the TimerP.h interface
732  * header file */
733 TimerP_Status TimerP_delete(TimerP_Handle handle)
735     /* Release or free the memory */
736     uint32_t key;
737     uint32_t index = (uint32_t)(( ((uintptr_t) handle) - ((uintptr_t) gTimerStructs) )/sizeof(TimerP_Struct)); /* struct subtraction */
738     TimerP_Status ret = TimerP_OK;
739     TimerP_Struct *timer = (TimerP_Struct *) handle;
740     TIMOSAL_Assert((handle == NULL_PTR));
742     key = (uint32_t)HwiP_disable();
744     if((timer != NULL_PTR) && ((gTimerStructs[index].used) == (bool)true))
745     {
746       /* clear the ISR that was set before */
747       if(timer->hwi != NULL_PTR) {
748         (void)HwiP_delete(timer->hwi);
749         gTimerStructs[index].used = (bool)false;
750       }
752       /* Found the osal timer object to delete */
753       if (gOsalTimerAllocCnt > 0U)
754       {
755         gOsalTimerAllocCnt--;
756       }
757       ret = TimerP_OK;  
758     } 
759     else
760     {
761       ret = TimerP_FAILURE;     
762     }
764     HwiP_restore(key);
766     return (ret);
770 /* Timer start module function
771  * more details on the documentation of this interface
772  * function can be found in the TimerP.h interface
773  * header file */
774 TimerP_Status TimerP_start(TimerP_Handle handle)
776   uint32_t  key, runMode, status;
777   TimerP_Struct *timer = (TimerP_Struct *) handle;
778   uint32_t max_period = (uint32_t) 0xffffffffU;
779   TimerP_Status retVal = TimerP_OK;
780   uint32_t  eventId;
781   uint32_t baseAddr = TimerP_getTimerBaseAddr(timer->timerId);
783   if (baseAddr == 0U) {
784     retVal = TimerP_NOT_AVAILABLE;
785   }
786   else
787   {
789   key = (uint32_t)HwiP_disable();
791   (void)TimerP_stop(handle);
793   if ((timer->runMode == (uint32_t)TimerP_RunMode_CONTINUOUS) ||
794       (timer->runMode == (uint32_t)TimerP_RunMode_ONESHOT)) {
795     (void)TIMERCounterSet(baseAddr, (max_period - timer->period));             /* set timer count back to period value */
796   }
797   else {
798     (void)TIMERCounterSet(baseAddr, 0);             /* set timer count back to initial value */
799     (void)TIMERCompareSet(baseAddr, timer->period); /* set threshold for first interrupt */
801     timer->prevThreshold  = 0;    /* init previous threshold */
802     timer->rollovers      = 0;    /* init total rollover count */
803     timer->savedCurrCount = 0;
804   }
806   do {
807     status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCRR);
808   } while (status != (uint32_t) 0u);
810   if(timer->hwi != NULL_PTR) {
811 #if defined (_TMS320C6X)
812     eventId = timer->eventId;
813 #else
814     eventId = 0u;
815 #endif
816     Osal_ClearInterrupt(eventId, timer->intNum);
817     Osal_EnableInterrupt(eventId, timer->intNum);
818   }
819   else {
820       retVal = TimerP_FAILURE;
821   }
823   if (timer->runMode == (uint32_t)TimerP_RunMode_CONTINUOUS) {
824       runMode = TIMERP_DM_TCLR_START_CONTINUOUS;
825   }
826   else if (timer->runMode == (uint32_t)TimerP_RunMode_ONESHOT) {
827       runMode = TIMERP_DM_TCLR_START_ONESHOT;
828   }
829   else {
830       runMode = TIMERP_DM_TCLR_START_DYNAMIC;
831   }
833   if (retVal == TimerP_OK) {
834       (void)TIMERModeConfigure(baseAddr, runMode);
836       do {
837         status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCLR);
838       } while (status != (uint32_t) 0u);
840       (void)TIMEREnable(baseAddr);
841   }
842   HwiP_restore(key);
843   }
844   return (retVal);
847 /* Timer stop module function
848  * more details on the documentation of this interface
849  * function can be found in the TimerP.h interface
850  * header file */
852 TimerP_Status TimerP_stop(TimerP_Handle handle)
854   uint32_t  tisr, status;
855   TimerP_Struct *timer = (TimerP_Struct *) handle;
856   TimerP_Status retVal = TimerP_OK;
857   uint32_t eventId;
858   uint32_t baseAddr = TimerP_getTimerBaseAddr(timer->timerId);
860   if (baseAddr == 0U) {
861     retVal = TimerP_NOT_AVAILABLE;
862   }
863   else
864   {
865     (void)TIMERDisable(baseAddr);
867     do {
868       status = (TIMERWritePostedStatusGet(baseAddr) & TIMERP_DM_TWPS_W_PEND_TCLR);
869     } while (status != (uint32_t) 0u);
872     tisr = TIMERIntStatusGet(baseAddr);
875     if(tisr > 0U) {
876       /* Clear all pending interrupts */
877       (void)TIMERIntStatusClear(baseAddr, tisr);
878     }
880     if(timer->hwi != NULL_PTR) {
881 #if defined (_TMS320C6X)
882       eventId = timer->eventId;
883 #else
884       eventId = 0u;
885 #endif
886       Osal_ClearInterrupt(eventId, timer->intNum);
887       Osal_DisableInterrupt(eventId, timer->intNum);
888     }
889     else {
890         retVal = TimerP_FAILURE;
891     }
892   }
893   return(retVal);
896 /* Timer set micro seconds module function
897  * more details on the documentation of this interface
898  * function can be found in the TimerP.h interface
899  * header file */
900 TimerP_Status TimerP_setPeriodMicroSecs(TimerP_Handle handle, uint32_t microsecs)
902   TimerP_Struct *timer = (TimerP_Struct *) handle;
903   TimerP_Status retVal = TimerP_OK;
904   if (!TimerP_dmTimerSetMicroSeconds(timer, microsecs)) {
905     retVal = TimerP_FAILURE;
906   }
907   return (retVal);
910 /* Get time in micro seconds */
911 uint64_t TimerP_getTimeInUsecs(void)
913     TimeStamp_Struct timestamp64;
914     uint64_t         cur_ts, freq;
915     uint32_t         tsFreqKHz;
917     /* Get the timestamp */
918     osalArch_TimestampGet64(&timestamp64);
920     /* Get the frequency of the timeStatmp provider */
921     tsFreqKHz  = (uint32_t)osalArch_TimeStampGetFreqKHz();
923     cur_ts = ((uint64_t) timestamp64.hi << 32U) | timestamp64.lo;
924     freq = (uint64_t) (tsFreqKHz);
926     return ((cur_ts*1000u)/freq);
928 /* This file implements the DM timer osal functions on AM devices */