Home | History | Annotate | Download | only in tml
      1 /*
      2  * Copyright (C) 2010-2014 NXP Semiconductors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * OSAL Implementation for Timers.
     19  */
     20 
     21 #include <signal.h>
     22 #include <phNfcTypes.h>
     23 #include <phOsalNfc_Timer.h>
     24 #include <phNfcCommon.h>
     25 #include <phNxpNciHal.h>
     26 #include <phNxpLog.h>
     27 
     28 #define PH_NFC_MAX_TIMER (5U)
     29 static phOsalNfc_TimerHandle_t         apTimerInfo[PH_NFC_MAX_TIMER];
     30 
     31 extern phNxpNciHal_Control_t nxpncihal_ctrl;
     32 
     33 
     34 /*
     35  * Defines the base address for generating timerid.
     36  */
     37 #define PH_NFC_TIMER_BASE_ADDRESS                   (100U)
     38 
     39 /*
     40  *  Defines the value for invalid timerid returned during timeSetEvent
     41  */
     42 #define PH_NFC_TIMER_ID_ZERO                        (0x00)
     43 
     44 
     45 /*
     46  * Invalid timer ID type. This ID used indicate timer creation is failed */
     47 #define PH_NFC_TIMER_ID_INVALID                     (0xFFFF)
     48 
     49 /* Forward declarations */
     50 static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg);
     51 static void phOsalNfc_DeferredCall (void *pParams);
     52 static void phOsalNfc_Timer_Expired(union sigval sv);
     53 
     54 /*
     55  *************************** Function Definitions ******************************
     56  */
     57 
     58 /*******************************************************************************
     59 **
     60 ** Function         phOsalNfc_Timer_Create
     61 **
     62 ** Description      Creates a timer which shall call back the specified function when the timer expires
     63 **                  Fails if OSAL module is not initialized or timers are already occupied
     64 **
     65 ** Parameters       None
     66 **
     67 ** Returns          TimerId
     68 **                  TimerId value of PH_OSALNFC_TIMER_ID_INVALID indicates that timer is not created                -
     69 **
     70 *******************************************************************************/
     71 uint32_t phOsalNfc_Timer_Create(void)
     72 {
     73     /* dwTimerId is also used as an index at which timer object can be stored */
     74     uint32_t dwTimerId = PH_OSALNFC_TIMER_ID_INVALID;
     75     static struct sigevent se;
     76     phOsalNfc_TimerHandle_t *pTimerHandle;
     77     /* Timer needs to be initialized for timer usage */
     78 
     79         se.sigev_notify = SIGEV_THREAD;
     80         se.sigev_notify_function = phOsalNfc_Timer_Expired;
     81         se.sigev_notify_attributes = NULL;
     82         dwTimerId = phUtilNfc_CheckForAvailableTimer();
     83 
     84         /* Check whether timers are available, if yes create a timer handle structure */
     85         if( (PH_NFC_TIMER_ID_ZERO != dwTimerId) && (dwTimerId <= PH_NFC_MAX_TIMER) )
     86         {
     87             pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwTimerId-1];
     88             /* Build the Timer Id to be returned to Caller Function */
     89             dwTimerId += PH_NFC_TIMER_BASE_ADDRESS;
     90             se.sigev_value.sival_int = (int)dwTimerId;
     91             /* Create POSIX timer */
     92             if(timer_create(CLOCK_REALTIME, &se, &(pTimerHandle->hTimerHandle)) == -1)
     93             {
     94                 dwTimerId = PH_NFC_TIMER_ID_INVALID;
     95             }
     96             else
     97             {
     98                 /* Set the state to indicate timer is ready */
     99                 pTimerHandle->eState = eTimerIdle;
    100                 /* Store the Timer Id which shall act as flag during check for timer availability */
    101                 pTimerHandle->TimerId = dwTimerId;
    102             }
    103         }
    104         else
    105         {
    106             dwTimerId = PH_NFC_TIMER_ID_INVALID;
    107         }
    108 
    109     /* Timer ID invalid can be due to Uninitialized state,Non availability of Timer */
    110     return dwTimerId;
    111 }
    112 
    113 /*******************************************************************************
    114 **
    115 ** Function         phOsalNfc_Timer_Start
    116 **
    117 ** Description      Starts the requested, already created, timer
    118 **                  If the timer is already running, timer stops and restarts with the new timeout value
    119 **                  and new callback function in case any ??????
    120 **                  Creates a timer which shall call back the specified function when the timer expires
    121 **
    122 ** Parameters       dwTimerId             - valid timer ID obtained during timer creation
    123 **                  dwRegTimeCnt          - requested timeout in milliseconds
    124 **                  pApplication_callback - application callback interface to be called when timer expires
    125 **                  pContext              - caller context, to be passed to the application callback function
    126 **
    127 ** Returns          NFC status:
    128 **                  NFCSTATUS_SUCCESS            - the operation was successful
    129 **                  NFCSTATUS_NOT_INITIALISED    - OSAL Module is not initialized
    130 **                  NFCSTATUS_INVALID_PARAMETER  - invalid parameter passed to the function
    131 **                  PH_OSALNFC_TIMER_START_ERROR - timer could not be created due to system error
    132 **
    133 *******************************************************************************/
    134 NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, pphOsalNfc_TimerCallbck_t pApplication_callback, void *pContext)
    135 {
    136     NFCSTATUS wStartStatus= NFCSTATUS_SUCCESS;
    137 
    138     struct itimerspec its;
    139     uint32_t dwIndex;
    140     phOsalNfc_TimerHandle_t *pTimerHandle;
    141     /* Retrieve the index at which the timer handle structure is stored */
    142     dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
    143     pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
    144     /* OSAL Module needs to be initialized for timer usage */
    145         /* Check whether the handle provided by user is valid */
    146         if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
    147                 (NULL != pApplication_callback) )
    148         {
    149             its.it_interval.tv_sec  = 0;
    150             its.it_interval.tv_nsec = 0;
    151             its.it_value.tv_sec     = dwRegTimeCnt / 1000;
    152             its.it_value.tv_nsec    = 1000000 * (dwRegTimeCnt % 1000);
    153             if(its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
    154             {
    155                 /* This would inadvertently stop the timer*/
    156                 its.it_value.tv_nsec = 1;
    157             }
    158             pTimerHandle->Application_callback = pApplication_callback;
    159             pTimerHandle->pContext = pContext;
    160             pTimerHandle->eState = eTimerRunning;
    161             /* Arm the timer */
    162             if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
    163             {
    164                 wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_START_ERROR);
    165             }
    166         }
    167         else
    168         {
    169             wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
    170         }
    171 
    172     return wStartStatus;
    173 }
    174 
    175 /*******************************************************************************
    176 **
    177 ** Function         phOsalNfc_Timer_Stop
    178 **
    179 ** Description      Stops already started timer
    180 **                  Allows to stop running timer. In case timer is stopped, timer callback
    181 **                  will not be notified any more
    182 **
    183 ** Parameters       dwTimerId             - valid timer ID obtained during timer creation
    184 **
    185 ** Returns          NFC status:
    186 **                  NFCSTATUS_SUCCESS            - the operation was successful
    187 **                  NFCSTATUS_NOT_INITIALISED    - OSAL Module is not initialized
    188 **                  NFCSTATUS_INVALID_PARAMETER  - invalid parameter passed to the function
    189 **                  PH_OSALNFC_TIMER_STOP_ERROR  - timer could not be stopped due to system error
    190 **
    191 *******************************************************************************/
    192 NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId)
    193 {
    194     NFCSTATUS wStopStatus=NFCSTATUS_SUCCESS;
    195     static struct itimerspec its = {{0, 0}, {0, 0}};
    196 
    197     uint32_t dwIndex;
    198     phOsalNfc_TimerHandle_t *pTimerHandle;
    199     dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
    200     pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
    201     /* OSAL Module and Timer needs to be initialized for timer usage */
    202         /* Check whether the TimerId provided by user is valid */
    203         if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
    204                 (pTimerHandle->eState != eTimerIdle) )
    205         {
    206             /* Stop the timer only if the callback has not been invoked */
    207             if(pTimerHandle->eState == eTimerRunning)
    208             {
    209                 if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
    210                 {
    211                     wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_STOP_ERROR);
    212                 }
    213                 else
    214                 {
    215                     /* Change the state of timer to Stopped */
    216                     pTimerHandle->eState = eTimerStopped;
    217                 }
    218             }
    219         }
    220         else
    221         {
    222             wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
    223         }
    224 
    225     return wStopStatus;
    226 }
    227 
    228 /*******************************************************************************
    229 **
    230 ** Function         phOsalNfc_Timer_Delete
    231 **
    232 ** Description      Deletes previously created timer
    233 **                  Allows to delete previously created timer. In case timer is running,
    234 **                  it is first stopped and then deleted
    235 **
    236 ** Parameters       dwTimerId             - valid timer ID obtained during timer creation
    237 **
    238 ** Returns          NFC status:
    239 **                  NFCSTATUS_SUCCESS             - the operation was successful
    240 **                  NFCSTATUS_NOT_INITIALISED     - OSAL Module is not initialized
    241 **                  NFCSTATUS_INVALID_PARAMETER   - invalid parameter passed to the function
    242 **                  PH_OSALNFC_TIMER_DELETE_ERROR - timer could not be stopped due to system error
    243 **
    244 *******************************************************************************/
    245 NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId)
    246 {
    247     NFCSTATUS wDeleteStatus = NFCSTATUS_SUCCESS;
    248 
    249     uint32_t dwIndex;
    250     phOsalNfc_TimerHandle_t *pTimerHandle;
    251     dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
    252     pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
    253     /* OSAL Module and Timer needs to be initialized for timer usage */
    254 
    255         /* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
    256         if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId)
    257                 && (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
    258         )
    259         {
    260             /* Cancel the timer before deleting */
    261             if(timer_delete(pTimerHandle->hTimerHandle) == -1)
    262             {
    263                 wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_DELETE_ERROR);
    264             }
    265             /* Clear Timer structure used to store timer related data */
    266             memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
    267         }
    268         else
    269         {
    270             wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
    271         }
    272     return wDeleteStatus;
    273 }
    274 
    275 /*******************************************************************************
    276 **
    277 ** Function         phOsalNfc_Timer_Cleanup
    278 **
    279 ** Description      Deletes all previously created timers
    280 **                  Allows to delete previously created timers. In case timer is running,
    281 **                  it is first stopped and then deleted
    282 **
    283 ** Parameters       None
    284 **
    285 ** Returns          None
    286 **
    287 *******************************************************************************/
    288 void phOsalNfc_Timer_Cleanup(void)
    289 {
    290     /* Delete all timers */
    291     uint32_t dwIndex;
    292     phOsalNfc_TimerHandle_t *pTimerHandle;
    293     for(dwIndex = 0; dwIndex < PH_NFC_MAX_TIMER; dwIndex++)
    294     {
    295         pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
    296         /* OSAL Module and Timer needs to be initialized for timer usage */
    297 
    298         /* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
    299         if( (0x00 != pTimerHandle->TimerId)
    300                 && (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
    301         )
    302         {
    303             /* Cancel the timer before deleting */
    304             if(timer_delete(pTimerHandle->hTimerHandle) == -1)
    305             {
    306                 NXPLOG_TML_E("timer %d delete error!", dwIndex);
    307             }
    308             /* Clear Timer structure used to store timer related data */
    309             memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
    310         }
    311     }
    312 
    313     return;
    314 }
    315 
    316 /*******************************************************************************
    317 **
    318 ** Function         phOsalNfc_DeferredCall
    319 **
    320 ** Description      Invokes the timer callback function after timer expiration.
    321 **                  Shall invoke the callback function registered by the timer caller function
    322 **
    323 ** Parameters       pParams - parameters indicating the ID of the timer
    324 **
    325 ** Returns          None                -
    326 **
    327 *******************************************************************************/
    328 static void phOsalNfc_DeferredCall (void *pParams)
    329 {
    330     /* Retrieve the timer id from the parameter */
    331     uint32_t dwIndex;
    332     phOsalNfc_TimerHandle_t *pTimerHandle;
    333     if(NULL != pParams)
    334     {
    335         /* Retrieve the index at which the timer handle structure is stored */
    336         dwIndex = (uintptr_t)pParams - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
    337         pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
    338         if(pTimerHandle->Application_callback != NULL)
    339         {
    340             /* Invoke the callback function with osal Timer ID */
    341             pTimerHandle->Application_callback((uintptr_t)pParams, pTimerHandle->pContext);
    342         }
    343     }
    344 
    345     return;
    346 }
    347 
    348 /*******************************************************************************
    349 **
    350 ** Function         phOsalNfc_PostTimerMsg
    351 **
    352 ** Description      Posts message on the user thread
    353 **                  Shall be invoked upon expiration of a timer
    354 **                  Shall post message on user thread through which timer callback function shall be invoked
    355 **
    356 ** Parameters       pMsg - pointer to the message structure posted on user thread
    357 **
    358 ** Returns          None                -
    359 **
    360 *******************************************************************************/
    361 static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg)
    362 {
    363 
    364     (void)phDal4Nfc_msgsnd(nxpncihal_ctrl.gDrvCfg.nClientId/*gpphOsalNfc_Context->dwCallbackThreadID*/, pMsg,0);
    365 
    366     return;
    367 }
    368 
    369 /*******************************************************************************
    370 **
    371 ** Function         phOsalNfc_Timer_Expired
    372 **
    373 ** Description      posts message upon expiration of timer
    374 **                  Shall be invoked when any one timer is expired
    375 **                  Shall post message on user thread to invoke respective
    376 **                  callback function provided by the caller of Timer function
    377 **
    378 ** Returns          None
    379 **
    380 *******************************************************************************/
    381 static void phOsalNfc_Timer_Expired(union sigval sv)
    382 {
    383    uint32_t dwIndex;
    384    phOsalNfc_TimerHandle_t *pTimerHandle;
    385 
    386 
    387     dwIndex = ((uint32_t)(sv.sival_int)) - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
    388     pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
    389     /* Timer is stopped when callback function is invoked */
    390     pTimerHandle->eState = eTimerStopped;
    391 
    392     pTimerHandle->tDeferedCallInfo.pDeferedCall = &phOsalNfc_DeferredCall;
    393     pTimerHandle->tDeferedCallInfo.pParam = (void *) ((intptr_t)(sv.sival_int));
    394 
    395     pTimerHandle->tOsalMessage.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
    396     pTimerHandle->tOsalMessage.pMsgData = (void *)&pTimerHandle->tDeferedCallInfo;
    397 
    398 
    399     /* Post a message on the queue to invoke the function */
    400     phOsalNfc_PostTimerMsg ((phLibNfc_Message_t *)&pTimerHandle->tOsalMessage);
    401 
    402     return;
    403 }
    404 
    405 
    406 /*******************************************************************************
    407 **
    408 ** Function         phUtilNfc_CheckForAvailableTimer
    409 **
    410 ** Description      Find an available timer id
    411 **
    412 ** Parameters       void
    413 **
    414 ** Returns          Available timer id
    415 **
    416 *******************************************************************************/
    417 uint32_t phUtilNfc_CheckForAvailableTimer(void)
    418 {
    419     /* Variable used to store the index at which the object structure details
    420        can be stored. Initialize it as not available. */
    421     uint32_t dwIndex = 0x00;
    422     uint32_t dwRetval = 0x00;
    423 
    424 
    425     /* Check whether Timer object can be created */
    426      for(dwIndex = 0x00;
    427              ( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 == dwRetval) ); dwIndex++)
    428      {
    429          if(!(apTimerInfo[dwIndex].TimerId))
    430          {
    431              dwRetval = (dwIndex + 0x01);
    432          }
    433      }
    434 
    435      return (dwRetval);
    436 
    437 }
    438 
    439 /*******************************************************************************
    440 **
    441 ** Function         phOsalNfc_CheckTimerPresence
    442 **
    443 ** Description      Checks the requested timer is present or not
    444 **
    445 ** Parameters       pObjectHandle - timer context
    446 **
    447 ** Returns          NFCSTATUS_SUCCESS if found
    448 **                  Other value if not found
    449 **
    450 *******************************************************************************/
    451 NFCSTATUS phOsalNfc_CheckTimerPresence(void *pObjectHandle)
    452 {
    453     uint32_t dwIndex;
    454     NFCSTATUS wRegisterStatus = NFCSTATUS_INVALID_PARAMETER;
    455 
    456     for(dwIndex = 0x00; ( (dwIndex < PH_NFC_MAX_TIMER) &&
    457             (wRegisterStatus != NFCSTATUS_SUCCESS) ); dwIndex++)
    458     {
    459         /* For Timer, check whether the requested handle is present or not */
    460         if( ((&apTimerInfo[dwIndex]) ==
    461                 (phOsalNfc_TimerHandle_t *)pObjectHandle) &&
    462                 (apTimerInfo[dwIndex].TimerId) )
    463         {
    464             wRegisterStatus = NFCSTATUS_SUCCESS;
    465         }
    466     }
    467     return wRegisterStatus;
    468 
    469 }
    470