2 * Copyright (C) 2010 NXP Semiconductors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * =========================================================================== *
21 * \file phHciNfc_PollingLoop.c *
22 * \brief HCI polling loop Management Routines. *
25 * Project: NFC-FRI-1.1 *
27 * $Date: Mon Mar 29 17:34:48 2010 $ *
28 * $Author: ing04880 $ *
30 * $Aliases: NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
32 * =========================================================================== *
36 ***************************** Header File Inclusion ****************************
38 #include <phNfcCompId.h>
39 #include <phNfcHalTypes.h>
40 #include <phHciNfc_Pipe.h>
41 #include <phHciNfc_PollingLoop.h>
42 #include <phOsalNfc.h>
44 ****************************** Macro Definitions *******************************
47 /* Registry index to which command has to be sent */
48 #define PL_PAUSE_INDEX 0x08U
49 #define PL_EMULATION_INDEX 0x07U
50 #define PL_RD_PHASES_INDEX 0x06U
51 #define PL_DISABLE_TARGET_INDEX 0x09U
54 #define NXP_EVT_CLK_ACK 0x01U
55 #define NXP_EVT_CLK_REQUEST 0x02U
56 #define NXP_EVT_ACTIVATE_RDPHASES 0x03U
57 #define NXP_EVT_DEACTIVATE_RDPHASES 0x04U
60 #define PL_DURATION_LENGTH 0x02U
61 #define PL_BYTE_LEN_1 0x01U
63 #define PL_BIT_FIELD_ENABLED 0x01U
66 #define PL_EMULATION_FACTOR 0x0AU
67 /* Default duration (100 ms * 1000) micro seconds,
68 always duration shall be less then 3145680
70 #define PL_DEFAULT_DURATION 100000U
71 /* Maximum duration */
72 #define PL_MAX_DURATION 3145000U
73 #define PL_DURATION_MIN_VALUE 48U
74 #define PL_DURATION_CALC(duration) \
75 ((uint16_t)((duration)/PL_DURATION_MIN_VALUE))
78 *************************** Structure and Enumeration ***************************
81 typedef enum phHciNfc_Poll_Seq{
88 PL_GET_DISABLE_TARGET,
89 PL_SET_DISABLE_TARGET,
91 } phHciNfc_Poll_Seq_t;
93 /* Information structure for the polling loop Gate */
94 typedef struct phHciNfc_PollLoop_Info{
95 /* Current running Sequence of the polling loop Management */
96 phHciNfc_Poll_Seq_t current_seq;
97 /* Next running Sequence of the polling loop Management */
98 phHciNfc_Poll_Seq_t next_seq;
99 /* Pointer to the polling loop pipe information */
100 phHciNfc_Pipe_Info_t *p_pipe_info;
102 } phHciNfc_PollLoop_Info_t;
105 *************************** Static Function Declaration **************************
110 phHciNfc_PollLoop_InfoUpdate(
111 phHciNfc_sContext_t *psHciContext,
117 * \ingroup grp_hci_nfc
119 * The phHciNfc_Recv_Pl_Response function interprets the received polling loop
120 * response from the Host Controller Gate.
122 * \param[in] psHciContext psHciContext is the pointer to HCI Layer
124 * \param[in] pHwRef pHwRef is the Information of
125 * the Device Interface Link .
126 * \param[in,out] pResponse Response received from the Host Cotroller
128 * \param[in] length length contains the length of the
129 * response received from the Host Controller.
131 * \retval NFCSTATUS_PENDING Polling loop gate Response to be received
133 * \retval NFCSTATUS_SUCCESS Polling loop gate Response received
135 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
136 * could not be interpreted properly.
137 * \retval Other errors Errors related to the other layers
143 phHciNfc_Recv_PollLoop_Response(
156 phHciNfc_Recv_PollLoop_Event(
167 *************************** Function Definitions ***************************
171 phHciNfc_PollLoop_Get_PipeID(
172 phHciNfc_sContext_t *psHciContext,
176 NFCSTATUS status = NFCSTATUS_SUCCESS;
178 if( (NULL != psHciContext)
179 && ( NULL != ppipe_id )
180 && ( NULL != psHciContext->p_poll_loop_info )
183 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
184 p_poll_info = (phHciNfc_PollLoop_Info_t *)
185 psHciContext->p_poll_loop_info ;
186 *ppipe_id = p_poll_info->pipe_id ;
190 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
196 phHciNfc_PollLoop_Init_Resources(
197 phHciNfc_sContext_t *psHciContext
200 NFCSTATUS status = NFCSTATUS_SUCCESS;
201 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
202 if( NULL == psHciContext )
204 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
209 ( NULL == psHciContext->p_poll_loop_info )
210 && (phHciNfc_Allocate_Resource((void **)(&p_poll_info),
211 sizeof(phHciNfc_PollLoop_Info_t))== NFCSTATUS_SUCCESS)
214 psHciContext->p_poll_loop_info = p_poll_info;
215 p_poll_info->current_seq = PL_PIPE_OPEN;
216 p_poll_info->next_seq = PL_PIPE_CLOSE;
217 p_poll_info->pipe_id = (uint8_t)HCI_UNKNOWN_PIPE_ID;
221 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);
229 * \brief Initialisation of polling loop Gate and Establish the Session .
231 * This function initialses the polling loop Gates and
232 * all the required pipes and sets the Session ID
236 phHciNfc_PollLoop_Initialise(
237 phHciNfc_sContext_t *psHciContext,
241 NFCSTATUS status = NFCSTATUS_SUCCESS;
243 if( NULL == psHciContext )
245 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
249 if( NULL == psHciContext->p_poll_loop_info )
251 status = PHNFCSTVAL(CID_NFC_HCI,
252 NFCSTATUS_INVALID_HCI_INFORMATION);
256 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
257 phHciNfc_Pipe_Info_t *p_pipe_info = NULL;
258 p_poll_info = (phHciNfc_PollLoop_Info_t *)
259 psHciContext->p_poll_loop_info ;
260 p_pipe_info = p_poll_info->p_pipe_info;
261 if(NULL == p_pipe_info )
263 status = PHNFCSTVAL(CID_NFC_HCI,
264 NFCSTATUS_INVALID_HCI_SEQUENCE);
268 HCI_PRINT("Polling loop open pipe in progress ...\n");
269 status = phHciNfc_Open_Pipe( psHciContext,
270 pHwRef, p_pipe_info );
271 if(NFCSTATUS_SUCCESS == status)
273 p_poll_info->next_seq = PL_PIPE_CLOSE;
282 phHciNfc_PollLoop_Release(
283 phHciNfc_sContext_t *psHciContext,
287 NFCSTATUS status = NFCSTATUS_SUCCESS;
288 if( (NULL == psHciContext) || (NULL == pHwRef) )
290 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
294 if( NULL != psHciContext->p_poll_loop_info )
296 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
297 p_poll_info = (phHciNfc_PollLoop_Info_t *)
298 psHciContext->p_poll_loop_info ;
299 if (PL_PIPE_CLOSE == p_poll_info->current_seq)
301 phHciNfc_Pipe_Info_t *p_pipe_info = NULL;
302 p_pipe_info = p_poll_info->p_pipe_info;
303 if(NULL == p_pipe_info )
305 status = PHNFCSTVAL(CID_NFC_HCI,
306 NFCSTATUS_INVALID_HCI_SEQUENCE);
310 HCI_PRINT("Polling loop close pipe in progress ...\n");
311 status = phHciNfc_Close_Pipe( psHciContext,
312 pHwRef, p_pipe_info );
313 if(status == NFCSTATUS_SUCCESS)
315 p_poll_info->next_seq = PL_PIPE_OPEN;
321 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_SEQUENCE);
322 } /* End of if (PL_PIPE_CLOSE == p_pl_info->cur_seq) */
326 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
327 } /* End of if( NULL != psHciContext->p_poll_loop_info ) */
328 } /* End of if( (NULL == psHciContext) || (NULL == pHwRef) ) */
333 phHciNfc_PollLoop_Cfg (
340 NFCSTATUS status = NFCSTATUS_SUCCESS;
341 phHciNfc_sContext_t *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
343 static uint16_t pl_duration = 0;
345 /* To remove "warning (VS C4100) : unreferenced formal parameter" */
346 PHNFC_UNUSED_VARIABLE(pcfg_info);
348 if( (NULL == psHciContext)
352 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
354 else if(NULL == psHciContext->p_poll_loop_info)
356 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
360 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
361 phHciNfc_Pipe_Info_t *p_pipe_info=NULL;
362 phHal_sADD_Cfg_t *p_poll_cfg = NULL;
365 p_poll_cfg = (phHal_sADD_Cfg_t*)psHciContext->p_config_params;
366 p_poll_info = (phHciNfc_PollLoop_Info_t *)
367 psHciContext->p_poll_loop_info ;
368 p_pipe_info = p_poll_info->p_pipe_info;
369 if((NULL == p_pipe_info) || (NULL == p_poll_cfg))
371 status = PHNFCSTVAL(CID_NFC_HCI,
372 NFCSTATUS_INVALID_HCI_SEQUENCE);
381 Data memory has to be copied to
382 param_info and also depending on the
383 CARD_EMULATION or PAUSE, change the
384 p_pipe_info->reg_index
386 if(p_poll_cfg->Duration > PL_MAX_DURATION)
388 p_poll_cfg->Duration = PL_MAX_DURATION;
393 p_poll_cfg->PollDevInfo.PollCfgInfo.DisableCardEmulation)
395 p_poll_cfg->Duration = ((p_poll_cfg->Duration <
396 PL_DURATION_MIN_VALUE)?
397 (PL_DEFAULT_DURATION *
398 PL_EMULATION_FACTOR):
399 p_poll_cfg->Duration );
400 p_pipe_info->reg_index = PL_EMULATION_INDEX;
404 p_poll_cfg->Duration = ((p_poll_cfg->Duration <
405 PL_DURATION_MIN_VALUE)?
406 PL_DEFAULT_DURATION :
407 p_poll_cfg->Duration);
408 p_pipe_info->reg_index = PL_PAUSE_INDEX;
410 p_pipe_info->param_length = PL_DURATION_LENGTH;
412 /* Calculate duration */
413 pl_duration = (uint16_t)
414 PL_DURATION_CALC(p_poll_cfg->Duration);
416 /* Swap the 2 byte value */
417 pl_duration = (uint16_t)((pl_duration << BYTE_SIZE) |
418 ((uint8_t)(pl_duration >> BYTE_SIZE)));
419 /* Copy the duration from poll config structure,
420 provided by the upper layer */
421 p_pipe_info->param_info = (void *)&(pl_duration);
423 pipeid = p_poll_info->pipe_id ;
424 if (PL_GET_DURATION == p_poll_info->current_seq)
427 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
428 pipeid, (uint8_t)ANY_GET_PARAMETER);
429 if (NFCSTATUS_PENDING == status)
431 p_poll_info->next_seq = PL_PIPE_CLOSE;
432 status = NFCSTATUS_SUCCESS;
438 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
439 pipeid, (uint8_t)ANY_SET_PARAMETER);
440 if(NFCSTATUS_PENDING == status )
442 #ifdef ENABLE_VERIFY_PARAM
443 p_poll_info->next_seq = PL_GET_DURATION;
445 status = NFCSTATUS_SUCCESS;
446 #endif /* #ifdef ENABLE_VERIFY_PARAM */
453 poll_cfg = (uint8_t) p_poll_cfg->PollDevInfo.PollEnabled;
454 p_pipe_info->param_length = PL_BYTE_LEN_1;
455 p_pipe_info->reg_index = PL_RD_PHASES_INDEX;
457 /* Data memory has to be copied to
459 p_pipe_info->param_info = (void *)&(poll_cfg);
460 pipeid = p_poll_info->pipe_id ;
461 if (PL_GET_RD_PHASES == p_poll_info->current_seq)
464 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
465 pipeid, (uint8_t)ANY_GET_PARAMETER);
466 if (NFCSTATUS_PENDING == status)
468 status = NFCSTATUS_SUCCESS;
474 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
475 pipeid, (uint8_t)ANY_SET_PARAMETER);
476 if(NFCSTATUS_PENDING == status )
478 #ifdef ENABLE_VERIFY_PARAM
479 p_poll_info->next_seq = PL_GET_RD_PHASES;
481 status = NFCSTATUS_SUCCESS;
482 #endif /* #ifdef ENABLE_VERIFY_PARAM */
487 case PL_DISABLE_TARGET:
489 if (NULL == pcfg_info)
491 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
495 /* poll_cfg = (uint8_t) p_poll_cfg->NfcIP_Tgt_Disable; */
496 p_pipe_info->param_length = PL_BYTE_LEN_1;
497 p_pipe_info->reg_index = PL_DISABLE_TARGET_INDEX;
499 /* Data memory has to be copied to
501 p_pipe_info->param_info = pcfg_info;
502 pipeid = p_poll_info->pipe_id ;
503 if (PL_GET_DISABLE_TARGET == p_poll_info->current_seq)
506 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
507 pipeid, (uint8_t)ANY_GET_PARAMETER);
508 if (NFCSTATUS_PENDING == status)
510 status = NFCSTATUS_SUCCESS;
516 phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef,
517 pipeid, (uint8_t)ANY_SET_PARAMETER);
518 if( NFCSTATUS_PENDING == status )
520 #ifdef ENABLE_VERIFY_PARAM
521 /* p_poll_info->current_seq = PL_GET_DISABLE_TARGET; */
522 p_poll_info->next_seq = PL_GET_DISABLE_TARGET;
524 status = NFCSTATUS_SUCCESS;
525 #endif /* #ifdef ENABLE_VERIFY_PARAM */
533 status = PHNFCSTVAL(CID_NFC_HCI,
534 NFCSTATUS_INVALID_PARAMETER);
543 /* Function to assign pipe ID */
545 phHciNfc_PollLoop_Update_PipeInfo(
546 phHciNfc_sContext_t *psHciContext,
548 phHciNfc_Pipe_Info_t *pPipeInfo
551 NFCSTATUS status = NFCSTATUS_SUCCESS;
553 if( NULL == psHciContext )
555 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
557 else if ( NULL == psHciContext->p_poll_loop_info )
559 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
563 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
564 p_poll_info = (phHciNfc_PollLoop_Info_t *)
565 psHciContext->p_poll_loop_info ;
566 /* Update the pipe_id of the ID Mgmt Gate obtained from the HCI Response */
567 p_poll_info->pipe_id = pipeID;
568 p_poll_info->p_pipe_info = pPipeInfo;
569 if (NULL != pPipeInfo)
571 /* Update the Response Receive routine of the IDMgmt Gate */
572 pPipeInfo->recv_resp = &phHciNfc_Recv_PollLoop_Response;
573 /* Update the event Receive routine of the IDMgmt Gate */
574 pPipeInfo->recv_event = &phHciNfc_Recv_PollLoop_Event;
583 phHciNfc_Recv_PollLoop_Response(
594 NFCSTATUS status = NFCSTATUS_SUCCESS;
595 phHciNfc_sContext_t *psHciContext =
596 (phHciNfc_sContext_t *)psContext ;
599 if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse)
602 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
604 else if( NULL == psHciContext->p_poll_loop_info )
606 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
610 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
611 uint8_t prev_cmd = ANY_GET_PARAMETER;
612 p_poll_info = (phHciNfc_PollLoop_Info_t *)
613 psHciContext->p_poll_loop_info ;
614 if( NULL == p_poll_info->p_pipe_info)
616 status = PHNFCSTVAL(CID_NFC_HCI,
617 NFCSTATUS_INVALID_HCI_SEQUENCE);
621 prev_cmd = p_poll_info->p_pipe_info->prev_msg ;
624 case ANY_SET_PARAMETER:
626 HCI_PRINT("Polling loop Set Param complete\n");
629 case ANY_GET_PARAMETER:
631 status = phHciNfc_PollLoop_InfoUpdate(psHciContext,
632 p_poll_info->p_pipe_info->reg_index,
633 &pResponse[HCP_HEADER_LEN],
634 (uint8_t)(length - HCP_HEADER_LEN));
639 HCI_PRINT("Polling loop open pipe complete\n");
644 HCI_PRINT("Polling loop close pipe complete\n");
649 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
653 if( NFCSTATUS_SUCCESS == status )
655 p_poll_info->p_pipe_info->prev_status = NFCSTATUS_SUCCESS;
656 p_poll_info->current_seq = p_poll_info->next_seq;
665 phHciNfc_Recv_PollLoop_Event(
676 NFCSTATUS status = NFCSTATUS_SUCCESS;
677 phHciNfc_sContext_t *psHciContext =
678 (phHciNfc_sContext_t *)psContext ;
679 if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
680 || (length <= HCP_HEADER_LEN))
682 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
684 else if( NULL == psHciContext->p_poll_loop_info )
686 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
690 phHciNfc_HCP_Packet_t *p_packet = NULL;
691 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
692 phHciNfc_HCP_Message_t *message = NULL;
693 static phHal_sEventInfo_t event_info;
694 uint8_t instruction=0;
696 p_poll_info = (phHciNfc_PollLoop_Info_t *)
697 psHciContext->p_poll_loop_info ;
699 PHNFC_UNUSED_VARIABLE(p_poll_info);
700 p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
701 message = &p_packet->msg.message;
702 /* Get the instruction bits from the Message Header */
703 instruction = (uint8_t) GET_BITS8( message->msg_header,
704 HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
708 case NXP_EVT_CLK_ACK:
712 case NXP_EVT_CLK_REQUEST:
716 case NXP_EVT_ACTIVATE_RDPHASES:
718 HCI_PRINT("Polling loop activate read phase complete\n");
719 event_info.eventHost = phHal_eHostController;
720 event_info.eventType = NFC_UICC_RDPHASES_ACTIVATE_REQ;
721 event_info.eventInfo.rd_phases = pEvent[HCP_HEADER_LEN];
722 ((phHal_sHwReference_t *)pHwRef)->uicc_rdr_active = TRUE;
723 phHciNfc_Notify_Event((void *)psHciContext,
729 case NXP_EVT_DEACTIVATE_RDPHASES:
731 HCI_PRINT("Polling loop deactivate read phase complete\n");
732 event_info.eventHost = phHal_eHostController;
733 event_info.eventType = NFC_UICC_RDPHASES_DEACTIVATE_REQ;
734 event_info.eventInfo.rd_phases = pEvent[HCP_HEADER_LEN];
735 ((phHal_sHwReference_t *)pHwRef)->uicc_rdr_active = FALSE;
736 phHciNfc_Notify_Event((void *)psHciContext,
744 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
755 phHciNfc_PollLoop_InfoUpdate(
756 phHciNfc_sContext_t *psHciContext,
762 NFCSTATUS status = NFCSTATUS_SUCCESS;
763 phHciNfc_PollLoop_Info_t *p_poll_info=NULL;
764 p_poll_info = (phHciNfc_PollLoop_Info_t *)
765 (psHciContext->p_poll_loop_info );
766 /* To remove "warning (VS 4100) : unreferenced formal parameter" */
767 PHNFC_UNUSED_VARIABLE(reg_value);
768 PHNFC_UNUSED_VARIABLE(reg_length);
769 /* Variable was set but never used (ARM warning) */
770 PHNFC_UNUSED_VARIABLE(p_poll_info);
773 case PL_EMULATION_INDEX:
776 HCI_PRINT_BUFFER("\tPoll duration", reg_value, reg_length);
779 case PL_RD_PHASES_INDEX:
781 HCI_PRINT_BUFFER("\tPoll read phase", reg_value, reg_length);
784 #if defined (CLK_REQUEST)
785 case PL_CLK_REQUEST_INDEX:
787 HCI_PRINT_BUFFER("\tPoll clock request", reg_value, reg_length);
790 #endif /* #if defined (CLK_REQUEST) */
791 #if defined (INPUT_CLK)
792 case PL_INPUT_CLK_INDEX:
794 HCI_PRINT_BUFFER("\tPoll input clock", reg_value, reg_length);
797 #endif/* #if defined (INPUT_CLK) */
800 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);