blob: bdd4cbaefa2459e9df336ffc0584f53432a52715 [file] [log] [blame]
/*
* Copyright (C) 2010-2014 NXP Semiconductors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* OSAL Implementation for Timers.
*/
#include <signal.h>
#include <phNfcTypes.h>
#include <phOsalNfc_Timer.h>
#include <phNfcCommon.h>
#include <phNxpNciHal.h>
#include <phNxpLog.h>
#define PH_NFC_MAX_TIMER (5U)
static phOsalNfc_TimerHandle_t apTimerInfo[PH_NFC_MAX_TIMER];
extern phNxpNciHal_Control_t nxpncihal_ctrl;
/*
* Defines the base address for generating timerid.
*/
#define PH_NFC_TIMER_BASE_ADDRESS (100U)
/*
* Defines the value for invalid timerid returned during timeSetEvent
*/
#define PH_NFC_TIMER_ID_ZERO (0x00)
/*
* Invalid timer ID type. This ID used indicate timer creation is failed */
#define PH_NFC_TIMER_ID_INVALID (0xFFFF)
/* Forward declarations */
static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg);
static void phOsalNfc_DeferredCall (void *pParams);
static void phOsalNfc_Timer_Expired(union sigval sv);
/*
*************************** Function Definitions ******************************
*/
/*******************************************************************************
**
** Function phOsalNfc_Timer_Create
**
** Description Creates a timer which shall call back the specified function when the timer expires
** Fails if OSAL module is not initialized or timers are already occupied
**
** Parameters None
**
** Returns TimerId
** TimerId value of PH_OSALNFC_TIMER_ID_INVALID indicates that timer is not created -
**
*******************************************************************************/
uint32_t phOsalNfc_Timer_Create(void)
{
/* dwTimerId is also used as an index at which timer object can be stored */
uint32_t dwTimerId = PH_OSALNFC_TIMER_ID_INVALID;
static struct sigevent se;
phOsalNfc_TimerHandle_t *pTimerHandle;
/* Timer needs to be initialized for timer usage */
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = phOsalNfc_Timer_Expired;
se.sigev_notify_attributes = NULL;
dwTimerId = phUtilNfc_CheckForAvailableTimer();
/* Check whether timers are available, if yes create a timer handle structure */
if( (PH_NFC_TIMER_ID_ZERO != dwTimerId) && (dwTimerId <= PH_NFC_MAX_TIMER) )
{
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwTimerId-1];
/* Build the Timer Id to be returned to Caller Function */
dwTimerId += PH_NFC_TIMER_BASE_ADDRESS;
se.sigev_value.sival_int = (int)dwTimerId;
/* Create POSIX timer */
if(timer_create(CLOCK_REALTIME, &se, &(pTimerHandle->hTimerHandle)) == -1)
{
dwTimerId = PH_NFC_TIMER_ID_INVALID;
}
else
{
/* Set the state to indicate timer is ready */
pTimerHandle->eState = eTimerIdle;
/* Store the Timer Id which shall act as flag during check for timer availability */
pTimerHandle->TimerId = dwTimerId;
}
}
else
{
dwTimerId = PH_NFC_TIMER_ID_INVALID;
}
/* Timer ID invalid can be due to Uninitialized state,Non availability of Timer */
return dwTimerId;
}
/*******************************************************************************
**
** Function phOsalNfc_Timer_Start
**
** Description Starts the requested, already created, timer
** If the timer is already running, timer stops and restarts with the new timeout value
** and new callback function in case any ??????
** Creates a timer which shall call back the specified function when the timer expires
**
** Parameters dwTimerId - valid timer ID obtained during timer creation
** dwRegTimeCnt - requested timeout in milliseconds
** pApplication_callback - application callback interface to be called when timer expires
** pContext - caller context, to be passed to the application callback function
**
** Returns NFC status:
** NFCSTATUS_SUCCESS - the operation was successful
** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized
** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to the function
** PH_OSALNFC_TIMER_START_ERROR - timer could not be created due to system error
**
*******************************************************************************/
NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, pphOsalNfc_TimerCallbck_t pApplication_callback, void *pContext)
{
NFCSTATUS wStartStatus= NFCSTATUS_SUCCESS;
struct itimerspec its;
uint32_t dwIndex;
phOsalNfc_TimerHandle_t *pTimerHandle;
/* Retrieve the index at which the timer handle structure is stored */
dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
/* OSAL Module needs to be initialized for timer usage */
/* Check whether the handle provided by user is valid */
if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
(NULL != pApplication_callback) )
{
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
its.it_value.tv_sec = dwRegTimeCnt / 1000;
its.it_value.tv_nsec = 1000000 * (dwRegTimeCnt % 1000);
if(its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
{
/* This would inadvertently stop the timer*/
its.it_value.tv_nsec = 1;
}
pTimerHandle->Application_callback = pApplication_callback;
pTimerHandle->pContext = pContext;
pTimerHandle->eState = eTimerRunning;
/* Arm the timer */
if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
{
wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_START_ERROR);
}
}
else
{
wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
}
return wStartStatus;
}
/*******************************************************************************
**
** Function phOsalNfc_Timer_Stop
**
** Description Stops already started timer
** Allows to stop running timer. In case timer is stopped, timer callback
** will not be notified any more
**
** Parameters dwTimerId - valid timer ID obtained during timer creation
**
** Returns NFC status:
** NFCSTATUS_SUCCESS - the operation was successful
** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized
** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to the function
** PH_OSALNFC_TIMER_STOP_ERROR - timer could not be stopped due to system error
**
*******************************************************************************/
NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId)
{
NFCSTATUS wStopStatus=NFCSTATUS_SUCCESS;
static struct itimerspec its = {{0, 0}, {0, 0}};
uint32_t dwIndex;
phOsalNfc_TimerHandle_t *pTimerHandle;
dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
/* OSAL Module and Timer needs to be initialized for timer usage */
/* Check whether the TimerId provided by user is valid */
if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
(pTimerHandle->eState != eTimerIdle) )
{
/* Stop the timer only if the callback has not been invoked */
if(pTimerHandle->eState == eTimerRunning)
{
if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
{
wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_STOP_ERROR);
}
else
{
/* Change the state of timer to Stopped */
pTimerHandle->eState = eTimerStopped;
}
}
}
else
{
wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
}
return wStopStatus;
}
/*******************************************************************************
**
** Function phOsalNfc_Timer_Delete
**
** Description Deletes previously created timer
** Allows to delete previously created timer. In case timer is running,
** it is first stopped and then deleted
**
** Parameters dwTimerId - valid timer ID obtained during timer creation
**
** Returns NFC status:
** NFCSTATUS_SUCCESS - the operation was successful
** NFCSTATUS_NOT_INITIALISED - OSAL Module is not initialized
** NFCSTATUS_INVALID_PARAMETER - invalid parameter passed to the function
** PH_OSALNFC_TIMER_DELETE_ERROR - timer could not be stopped due to system error
**
*******************************************************************************/
NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId)
{
NFCSTATUS wDeleteStatus = NFCSTATUS_SUCCESS;
uint32_t dwIndex;
phOsalNfc_TimerHandle_t *pTimerHandle;
dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
/* OSAL Module and Timer needs to be initialized for timer usage */
/* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId)
&& (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
)
{
/* Cancel the timer before deleting */
if(timer_delete(pTimerHandle->hTimerHandle) == -1)
{
wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_DELETE_ERROR);
}
/* Clear Timer structure used to store timer related data */
memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
}
else
{
wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
}
return wDeleteStatus;
}
/*******************************************************************************
**
** Function phOsalNfc_Timer_Cleanup
**
** Description Deletes all previously created timers
** Allows to delete previously created timers. In case timer is running,
** it is first stopped and then deleted
**
** Parameters None
**
** Returns None
**
*******************************************************************************/
void phOsalNfc_Timer_Cleanup(void)
{
/* Delete all timers */
uint32_t dwIndex;
phOsalNfc_TimerHandle_t *pTimerHandle;
for(dwIndex = 0; dwIndex < PH_NFC_MAX_TIMER; dwIndex++)
{
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
/* OSAL Module and Timer needs to be initialized for timer usage */
/* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
if( (0x00 != pTimerHandle->TimerId)
&& (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
)
{
/* Cancel the timer before deleting */
if(timer_delete(pTimerHandle->hTimerHandle) == -1)
{
NXPLOG_TML_E("timer %d delete error!", dwIndex);
}
/* Clear Timer structure used to store timer related data */
memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
}
}
return;
}
/*******************************************************************************
**
** Function phOsalNfc_DeferredCall
**
** Description Invokes the timer callback function after timer expiration.
** Shall invoke the callback function registered by the timer caller function
**
** Parameters pParams - parameters indicating the ID of the timer
**
** Returns None -
**
*******************************************************************************/
static void phOsalNfc_DeferredCall (void *pParams)
{
/* Retrieve the timer id from the parameter */
uint32_t dwIndex;
phOsalNfc_TimerHandle_t *pTimerHandle;
if(NULL != pParams)
{
/* Retrieve the index at which the timer handle structure is stored */
dwIndex = (uintptr_t)pParams - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
if(pTimerHandle->Application_callback != NULL)
{
/* Invoke the callback function with osal Timer ID */
pTimerHandle->Application_callback((uintptr_t)pParams, pTimerHandle->pContext);
}
}
return;
}
/*******************************************************************************
**
** Function phOsalNfc_PostTimerMsg
**
** Description Posts message on the user thread
** Shall be invoked upon expiration of a timer
** Shall post message on user thread through which timer callback function shall be invoked
**
** Parameters pMsg - pointer to the message structure posted on user thread
**
** Returns None -
**
*******************************************************************************/
static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg)
{
(void)phDal4Nfc_msgsnd(nxpncihal_ctrl.gDrvCfg.nClientId/*gpphOsalNfc_Context->dwCallbackThreadID*/, pMsg,0);
return;
}
/*******************************************************************************
**
** Function phOsalNfc_Timer_Expired
**
** Description posts message upon expiration of timer
** Shall be invoked when any one timer is expired
** Shall post message on user thread to invoke respective
** callback function provided by the caller of Timer function
**
** Returns None
**
*******************************************************************************/
static void phOsalNfc_Timer_Expired(union sigval sv)
{
uint32_t dwIndex;
phOsalNfc_TimerHandle_t *pTimerHandle;
dwIndex = ((uint32_t)(sv.sival_int)) - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
/* Timer is stopped when callback function is invoked */
pTimerHandle->eState = eTimerStopped;
pTimerHandle->tDeferedCallInfo.pDeferedCall = &phOsalNfc_DeferredCall;
pTimerHandle->tDeferedCallInfo.pParam = (void *) ((intptr_t)(sv.sival_int));
pTimerHandle->tOsalMessage.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
pTimerHandle->tOsalMessage.pMsgData = (void *)&pTimerHandle->tDeferedCallInfo;
/* Post a message on the queue to invoke the function */
phOsalNfc_PostTimerMsg ((phLibNfc_Message_t *)&pTimerHandle->tOsalMessage);
return;
}
/*******************************************************************************
**
** Function phUtilNfc_CheckForAvailableTimer
**
** Description Find an available timer id
**
** Parameters void
**
** Returns Available timer id
**
*******************************************************************************/
uint32_t phUtilNfc_CheckForAvailableTimer(void)
{
/* Variable used to store the index at which the object structure details
can be stored. Initialize it as not available. */
uint32_t dwIndex = 0x00;
uint32_t dwRetval = 0x00;
/* Check whether Timer object can be created */
for(dwIndex = 0x00;
( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 == dwRetval) ); dwIndex++)
{
if(!(apTimerInfo[dwIndex].TimerId))
{
dwRetval = (dwIndex + 0x01);
}
}
return (dwRetval);
}
/*******************************************************************************
**
** Function phOsalNfc_CheckTimerPresence
**
** Description Checks the requested timer is present or not
**
** Parameters pObjectHandle - timer context
**
** Returns NFCSTATUS_SUCCESS if found
** Other value if not found
**
*******************************************************************************/
NFCSTATUS phOsalNfc_CheckTimerPresence(void *pObjectHandle)
{
uint32_t dwIndex;
NFCSTATUS wRegisterStatus = NFCSTATUS_INVALID_PARAMETER;
for(dwIndex = 0x00; ( (dwIndex < PH_NFC_MAX_TIMER) &&
(wRegisterStatus != NFCSTATUS_SUCCESS) ); dwIndex++)
{
/* For Timer, check whether the requested handle is present or not */
if( ((&apTimerInfo[dwIndex]) ==
(phOsalNfc_TimerHandle_t *)pObjectHandle) &&
(apTimerInfo[dwIndex].TimerId) )
{
wRegisterStatus = NFCSTATUS_SUCCESS;
}
}
return wRegisterStatus;
}