You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
445 lines
17 KiB
445 lines
17 KiB
/*
|
|
* Copyright 2010-2014, 2020 NXP
|
|
*
|
|
* 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 <phNfcCommon.h>
|
|
#include <phNfcTypes.h>
|
|
#include <phNxpLog.h>
|
|
#include <phNxpNciHal.h>
|
|
#include <phOsalNfc_Timer.h>
|
|
#include <signal.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 */
|
|
unsigned long 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;
|
|
}
|