Home | History | Annotate | Download | only in hal
      1 /*
      2  * Copyright (C) 2012-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 #include <phNxpNciHal_Kovio.h>
     18 #include <phNxpLog.h>
     19 
     20 
     21 #define KOVIO_TIMEOUT 1000    /* Timeout value to wait for RF INTF Activated NTF.*/
     22 #define KOVIO_ACT_NTF_TEMP_BUFF_LEN 64    /* length of temp buffer to manipulate
     23                                     the activated notification to match BCM format*/
     24 #define MAX_WRITE_RETRY 5
     25 
     26 /******************* Global variables *****************************************/
     27 extern phNxpNciHal_Control_t nxpncihal_ctrl;
     28 extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
     29 
     30 int kovio_detected = 0x00;
     31 int send_to_upper_kovio = 0x01;
     32 int disable_kovio=0x00;
     33 bool_t rf_deactive_cmd = FALSE;
     34 static uint8_t rf_deactivate_cmd[]   = { 0x21, 0x06, 0x01, 0x03 }; /* discovery */
     35 static uint8_t rf_deactivated_ntf[]  = { 0x61, 0x06, 0x02, 0x03, 0x01 };
     36 static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};
     37 
     38 static uint32_t kovio_timer;
     39 
     40 /************** Kovio functions ***************************************/
     41 
     42 static NFCSTATUS phNxpNciHal_rf_deactivate(void);
     43 
     44 /*******************************************************************************
     45 **
     46 ** Function         hal_write_cb
     47 **
     48 ** Description      Callback function for hal write.
     49 **
     50 ** Returns          None
     51 **
     52 *******************************************************************************/
     53 static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
     54 {
     55     UNUSED(pContext);
     56     UNUSED(pInfo);
     57     return;
     58 }
     59 
     60 /*******************************************************************************
     61 **
     62 ** Function         kovio_timer_handler
     63 **
     64 ** Description      Callback function for kovio timer.
     65 **
     66 ** Returns          None
     67 **
     68 *******************************************************************************/
     69 static void kovio_timer_handler(uint32_t timerId, void *pContext)
     70 {
     71     UNUSED(timerId);
     72     UNUSED(pContext);
     73     NXPLOG_NCIHAL_D(">> kovio_timer_handler. Did not receive RF_INTF_ACTIVATED_NTF, Kovio TAG must be removed.");
     74 
     75     phOsalNfc_Timer_Delete(kovio_timer);
     76 
     77     kovio_detected = 0x00;
     78     send_to_upper_kovio=0x01;
     79     disable_kovio=0x00;
     80     /*
     81      * send kovio deactivated ntf to upper layer.
     82     */
     83     NXPLOG_NCIHAL_D(">> send kovio deactivated ntf to upper layer.");
     84     if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
     85     {
     86         (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
     87                 sizeof(rf_deactivated_ntf), rf_deactivated_ntf);
     88     }
     89     return;
     90 }
     91 
     92 /*******************************************************************************
     93 **
     94 ** Function         phNxpNciHal_rf_deactivate
     95 **
     96 ** Description      Sends rf deactivate cmd to NFCC
     97 **
     98 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
     99 **
    100 *******************************************************************************/
    101 static NFCSTATUS phNxpNciHal_rf_deactivate()
    102 {
    103     NFCSTATUS status = NFCSTATUS_SUCCESS;
    104     int cb_data;
    105     int retryCnt = 0;
    106 
    107     do
    108     {
    109         retryCnt++;
    110         status = phTmlNfc_Write(rf_deactivate_cmd,
    111                 sizeof(rf_deactivate_cmd),
    112                 (pphTmlNfc_TransactCompletionCb_t) &hal_write_cb, &cb_data);
    113     } while(status != NFCSTATUS_PENDING && retryCnt <= MAX_WRITE_RETRY);
    114 
    115     if(status != NFCSTATUS_PENDING)
    116     {
    117         //phNxpNciHal_emergency_recovery();
    118         if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
    119             nxpncihal_ctrl.hal_open_status == TRUE)
    120         {
    121             NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
    122             //Send the Core Reset NTF to upper layer, which will trigger the recovery.
    123             send_to_upper_kovio = 0;
    124             nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
    125             memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
    126             (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
    127         }
    128     }
    129 
    130     return status;
    131 }
    132 
    133 /*******************************************************************************
    134 **
    135 ** Function         phNxpNciHal_kovio_rsp_ext
    136 **
    137 ** Description      Implements kovio presence check. In BCM controller this is
    138 **                  managed by NFCC. But since PN54X does not handle this, the
    139 **                  presence check is mimiced here.
    140 **                  For the very first time Kovio is detected, NTF has to be
    141 **                  passed on to upper layer. for every NTF, DH send a deactivated
    142 **                  command to NFCC and NFCC follows this up with another activated
    143 **                  notification. When the tag is removed, activated notification
    144 **                  stops coming and this is indicated to upper layer with a HAL
    145 **                  generated deactivated notification.
    146 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
    147 **
    148 *******************************************************************************/
    149 NFCSTATUS phNxpNciHal_kovio_rsp_ext(uint8_t *p_ntf, uint16_t *p_len)
    150 {
    151     NFCSTATUS status = NFCSTATUS_SUCCESS;
    152     uint8_t tBuff[KOVIO_ACT_NTF_TEMP_BUFF_LEN];
    153 
    154     send_to_upper_kovio = 1;
    155     if((p_ntf[0]==0x61)&&(p_ntf[1]==0x05))
    156     {
    157 #if(NFC_NXP_CHIP_TYPE != PN547C2)
    158         if((p_ntf[5]==0x81)&&(p_ntf[6]==0x70))
    159 #else
    160         if((p_ntf[5]==0x8A)&&(p_ntf[6]==0x77))
    161 #endif
    162         {
    163             if (kovio_detected == 0)
    164             {
    165                 if((*p_len-9)<KOVIO_ACT_NTF_TEMP_BUFF_LEN)
    166                 {
    167                     p_ntf[2]+=1;
    168                     memcpy(tBuff, &p_ntf[9], *p_len-9);
    169                     p_ntf[9]=p_ntf[9]+1;
    170                     memcpy(&p_ntf[10], tBuff, *p_len-9);
    171                     *p_len+=1;
    172                 }else
    173                 {
    174                     NXPLOG_NCIHAL_D("Kovio Act ntf payload exceeded temp buffer size");
    175                 }
    176                 kovio_detected = 1;
    177                 kovio_timer = phOsalNfc_Timer_Create();
    178                 NXPLOG_NCIHAL_D("custom kovio timer Created - %d", kovio_timer);
    179             }
    180             else
    181             {
    182                 send_to_upper_kovio = 0;
    183             }
    184 
    185             if (!rf_deactive_cmd)
    186             {
    187                 NXPLOG_NCIHAL_D ("Send RF deactivate command to NFCC");
    188                 status = phNxpNciHal_rf_deactivate ();
    189             }
    190             else
    191             {
    192                 NXPLOG_NCIHAL_D ("RF deactivate command is already sent to NFCC");
    193                 disable_kovio = TRUE;
    194                 send_to_upper_kovio = 0;
    195             }
    196             status = phOsalNfc_Timer_Start(kovio_timer,
    197                     KOVIO_TIMEOUT,
    198                     &kovio_timer_handler,
    199                     NULL);
    200             if (NFCSTATUS_SUCCESS == status)
    201             {
    202                 NXPLOG_NCIHAL_D("kovio timer started");
    203             }
    204             else
    205             {
    206                 NXPLOG_NCIHAL_E("kovio timer not started!!!");
    207                 status  = NFCSTATUS_FAILED;
    208             }
    209         }
    210         else
    211         {
    212             if (kovio_detected == 1)
    213             {
    214                 phNxpNciHal_clean_Kovio_Ext();
    215                 NXPLOG_NCIHAL_D ("Disabling Kovio detection logic as another tag type detected");
    216             }
    217         }
    218     }
    219     else if((p_ntf[0]==0x41)&&(p_ntf[1]==0x06)&&(p_ntf[2]==0x01))
    220     {
    221         rf_deactive_cmd = FALSE;
    222         if(kovio_detected == 1)
    223             send_to_upper_kovio = 0;
    224         if((kovio_detected == 1)&&(disable_kovio==0x01))
    225         {
    226             NXPLOG_NCIHAL_D ("Disabling Kovio detection logic");
    227             phNxpNciHal_clean_Kovio_Ext();
    228             disable_kovio=0x00;
    229         }
    230     }
    231     else if((p_ntf[0]==0x61)&&(p_ntf[1]==0x06)&&(p_ntf[2]==0x02)&&(p_ntf[3]==0x03)&&(p_ntf[4]==0x00))
    232     {
    233         if(kovio_detected == 1)
    234             send_to_upper_kovio = 0;
    235     }
    236     else if((p_ntf[0]==0x61)&&(p_ntf[1]==0x03))
    237     {
    238         if(kovio_detected == 1)
    239             send_to_upper_kovio = 0;
    240     }
    241     return status;
    242 }
    243 /*******************************************************************************
    244 **
    245 ** Function         phNxpNciHal_clean_Kovio_Ext
    246 **
    247 ** Description      Clean up Kovio extension state machine.
    248 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
    249 **
    250 *******************************************************************************/
    251 void phNxpNciHal_clean_Kovio_Ext()
    252 {
    253     NXPLOG_NCIHAL_D(">> Cleaning up Kovio State machine and timer.");
    254     phOsalNfc_Timer_Delete(kovio_timer);
    255     kovio_detected = 0x00;
    256     send_to_upper_kovio=0x01;
    257     disable_kovio=0x00;
    258     /*
    259      * send kovio deactivated ntf to upper layer.
    260     */
    261     NXPLOG_NCIHAL_D(">> send kovio deactivated ntf to upper layer.");
    262     if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
    263     {
    264         (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
    265                 sizeof(rf_deactivated_ntf), rf_deactivated_ntf);
    266     }
    267     return;
    268 }
    269