15d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*
25d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Copyright (C) 2010 NXP Semiconductors
35d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
45d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
55d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * you may not use this file except in compliance with the License.
65d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * You may obtain a copy of the License at
75d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
85d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
95d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Unless required by applicable law or agreed to in writing, software
115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * See the License for the specific language governing permissions and
145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * limitations under the License.
155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \file phOsalNfc_Timer.c
195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief OSAL Timer Implementation for linux
205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Project: Trusted NFC Linux Light
225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * $Date: 03 aug 2009
245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * $Author: Jérémie Corbier
255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * $Revision: 1.0
265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <stdlib.h>
305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <signal.h>
315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <time.h>
325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phOsalNfc.h>
345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phOsalNfc_Timer.h>
355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <stdio.h>
365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phDal4Nfc_messageQueueLib.h>
385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#define NSECS 1000000
405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#define MAX_NO_TIMERS 16
415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*!
435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \struct phOsalNfc_Timer
445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Internal OSAL timer structure
455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellystruct phOsalNfc_Timer
475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timer_t handle;         /*!< System timer handle. */
495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   ppCallBck_t callback;   /*!< Callback to be called when timer expires. */
505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   void* pContext;         /*!< Callback context. */
515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#ifdef NXP_MESSAGING
525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   void *ptr;
535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif
545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   int nIsStopped;
555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly};
565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellystatic struct phOsalNfc_Timer timers[MAX_NO_TIMERS] =
585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {0, NULL, NULL
605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#ifdef NXP_MESSAGING
615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly     , NULL
625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif
635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly     , 0
645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   },
655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly};
665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#ifdef NXP_MESSAGING
685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyextern int nDeferedCallMessageQueueId;
695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phOsalNfc_Timer_DeferredCall(void *params)
715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   phOsalNfc_Timer_Msg_t *timer_msg;
735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(params == NULL)
755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timer_msg = (phOsalNfc_Timer_Msg_t *)params;
785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
795d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if((timer_msg != NULL) && (timer_msg->pCallBck != NULL))
805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      timer_msg->pCallBck(timer_msg->TimerId, timer_msg->pContext);
815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if ((timer_msg->TimerId >= MAX_NO_TIMERS) || (timer_msg->TimerId < 0))
835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      printf("Bad TimerId=%d, should be <= to %d\n", timer_msg->TimerId, MAX_NO_TIMERS);
855d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
865d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   else
875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
885d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(timers[timer_msg->TimerId].ptr != NULL)
895d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
905d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         phOsalNfc_FreeMemory(timers[timer_msg->TimerId].ptr);
915d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         timers[timer_msg->TimerId].ptr = NULL;
925d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
935d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
945d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   phOsalNfc_FreeMemory(timer_msg);
955d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
965d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif
975d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
985d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*!
995d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief System timer callback.
1005d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        This callback is called by Linux whenever one the timers expires.  It
1015d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        calls the corresponding registered callback.
1025d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
1035d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \param sv structure storing the expired timer ID.
1045d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
1055d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellystatic void phOsalNfc_Timer_Expired(union sigval sv)
1065d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
1075d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t timerid = (uint32_t)(sv.sival_int);
1085d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1095d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if((timerid < MAX_NO_TIMERS)&&(timers[timerid].nIsStopped == 1))
1105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
1115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      //printf("phOsalNfc_Timer_Expired : Expired but already stopped TimerId=%d\n", timerid);
1125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
1135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
1145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timerid < MAX_NO_TIMERS)
1165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
1175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#ifndef CYCLIC_TIMER
1185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      phOsalNfc_Timer_Stop(timerid);
1195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#else
1205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif
1225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#ifdef NXP_MESSAGING
1235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      phOsalNfc_Timer_Msg_t *timer_msg;
1245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      phOsalNfc_DeferedCalldInfo_t *osal_defer_msg;
1255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      phDal4Nfc_Message_Wrapper_t wrapper;
1265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      timer_msg = phOsalNfc_GetMemory(sizeof(phOsalNfc_Timer_Msg_t));
1285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(timer_msg == NULL)
1295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         phOsalNfc_RaiseException(phOsalNfc_e_NoMemory, 0);
1305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      osal_defer_msg = phOsalNfc_GetMemory(sizeof(phOsalNfc_DeferedCalldInfo_t));
1325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(osal_defer_msg == NULL)
1335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
1345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         phOsalNfc_FreeMemory(timer_msg);
1355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         phOsalNfc_RaiseException(phOsalNfc_e_NoMemory, 0);
1365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
1375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      timer_msg->TimerId = timerid;
1395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      timer_msg->pCallBck = timers[timerid].callback;
1405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      timer_msg->pContext = timers[timerid].pContext;
1415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      osal_defer_msg->pCallback = phOsalNfc_Timer_DeferredCall;
1435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      osal_defer_msg->pParameter = timer_msg;
1445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      wrapper.mtype = 1;
1465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      wrapper.msg.eMsgType = PH_OSALNFC_TIMER_MSG;
1475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      wrapper.msg.pMsgData = osal_defer_msg;
1485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      wrapper.msg.Size = sizeof(phOsalNfc_DeferedCalldInfo_t);
1495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      timers[timerid].ptr = osal_defer_msg;
1515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      phDal4Nfc_msgsnd(nDeferedCallMessageQueueId, (void *)&wrapper,
1535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         sizeof(phOsalNfc_Message_t), 0);
1545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#else
1555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      (timers[timerid].callback)(timerid, timers[timerid].pContext);
1565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif
1575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
1585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
1595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellystatic void phOsalNfc_Timer_Dummy_Cb(uint32_t timerid, void *pContext) {}
1615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*!
1635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief Creates a new timer.
1645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        This function checks whether there is an available timer slot.  If
1655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        this is the case, then it reserves it for future usage and returns its
1665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        ID.
1675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
1685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \return a valid timer ID or PH_OSALNFC_INVALID_TIMER_ID if an error occured.
1695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
1705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phOsalNfc_Timer_Create(void)
1715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
1725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t timerid;
1735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   struct sigevent se;
1745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   se.sigev_notify = SIGEV_THREAD;
1765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   se.sigev_notify_function = phOsalNfc_Timer_Expired;
1775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   se.sigev_notify_attributes = NULL;
1785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1795d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Look for available timer slot */
1805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   for(timerid = 0; timerid < MAX_NO_TIMERS; timerid++)
1815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(timers[timerid].callback == NULL)
1825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         break;
1835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timerid == MAX_NO_TIMERS)
1845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PH_OSALNFC_INVALID_TIMER_ID;
1855d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1865d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   se.sigev_value.sival_int = (int)timerid;
1875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1885d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Create POSIX timer */
1895d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timer_create(CLOCK_REALTIME, &se, &(timers[timerid].handle)) == -1)
1905d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PH_OSALNFC_INVALID_TIMER_ID;
1915d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[timerid].callback = phOsalNfc_Timer_Dummy_Cb;
1925d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#ifdef NXP_MESSAGING
1935d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[timerid].ptr = NULL;
1945d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif
1955d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1965d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return timerid;
1975d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
1985d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1995d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*!
2005d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief Starts a timer.
2015d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        This function starts the timer \a TimerId with an expiration time of
2025d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        \a RegTimeCnt milliseconds.  Each time it expires, \a
2035d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        Application_callback is called.
2045d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
2055d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \param TimerId a valid timer ID.
2065d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \param RegTimeCnt expiration time in milliseconds.
2075d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \param Application_callback callback to be called when timer expires.
2085d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2095d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phOsalNfc_Timer_Start(uint32_t TimerId,
2105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                           uint32_t RegTimeCnt,
2115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                           ppCallBck_t  Application_callback,
2125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                           void *pContext)
2135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
2145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   struct itimerspec its;
2155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(TimerId >= MAX_NO_TIMERS)
2175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(Application_callback == NULL)
2195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timers[TimerId].callback == NULL)
2215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   its.it_interval.tv_sec  = 0;
2245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   its.it_interval.tv_nsec = 0;
22599eeb8ab747ce32a0b99a9abfe1c06eb6d583abcSylvain Fonteneau   its.it_value.tv_sec     = RegTimeCnt / 1000;
22699eeb8ab747ce32a0b99a9abfe1c06eb6d583abcSylvain Fonteneau   its.it_value.tv_nsec    = 1000000 * (RegTimeCnt % 1000);
22729e144ebf81b0f09b3fe4c26b67485ce836909c6Jan Brands   if(its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
22829e144ebf81b0f09b3fe4c26b67485ce836909c6Jan Brands   {
22929e144ebf81b0f09b3fe4c26b67485ce836909c6Jan Brands     // this would inadvertently stop the timer
23029e144ebf81b0f09b3fe4c26b67485ce836909c6Jan Brands     its.it_value.tv_nsec = 1;
23129e144ebf81b0f09b3fe4c26b67485ce836909c6Jan Brands   }
2325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[TimerId].callback = Application_callback;
2345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[TimerId].pContext = pContext;
2355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[TimerId].nIsStopped = 0;
2365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timer_settime(timers[TimerId].handle, 0, &its, NULL);
2385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
2395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*!
2415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief Stops a timer.
2425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        This function stops an already started timer.
2435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
2445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \param TimerId a valid timer ID.
2455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phOsalNfc_Timer_Stop(uint32_t TimerId)
2475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
2485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   struct itimerspec its = {{0, 0}, {0, 0}};
2495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(TimerId >= MAX_NO_TIMERS)
2515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timers[TimerId].callback == NULL)
2535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timers[TimerId].nIsStopped == 1)
2555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[TimerId].nIsStopped = 1;
2585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timer_settime(timers[TimerId].handle, 0, &its, NULL);
2595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
2605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*!
2625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief Deletes a timer.
2635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *        This function deletes a timer.
2645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
2655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \param TimerId a valid timer ID.
2665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phOsalNfc_Timer_Delete(uint32_t TimerId)
2685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
2695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(TimerId >= MAX_NO_TIMERS)
2705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if(timers[TimerId].callback == NULL)
2725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return;
2735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timer_delete(timers[TimerId].handle);
2755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[TimerId].callback = NULL;
2775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   timers[TimerId].pContext = NULL;
2785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
279