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