Android下NFC驱动初始化过程的一点分析


相关文章

1、JiangBo-Android NFC分析----http://wenku.baidu.com/link?url=tTD0vVVRFw_5EdcEB5Yycg21ZVuN5nu_ybnVukfU45RFCG-H0exETI5zHiACEFQwgq9Gvq3P9QWgWy_gTHCrMuchS0d8EgG0aNphHnJcnh7


2、Android NFC分析----http://leave001.blog.163.com/blog/static/16269129320122283648327/

3、NFC----http://blog.csdn.net/wangkaiblog/article/details/43085451


4、深入理解NFC----http://blog.csdn.net/wangkaiblog/article/details/42980281





//基于JNI

//com_android_nfc_NativeNfcManager.cpp e:\android\ubetter210\disc1\android4.0\android210-androidfs_v03\android210-androidfs_v03\packages\apps\nfc\Jni855402012-1-31




1、


  
      
int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
{
    nfc_jni_native_monitor_t *nfc_jni_native_monitor;


   nfc_jni_native_monitor = nfc_jni_init_monitor();
   if(nfc_jni_native_monitor == NULL)
   {
      LOGE("NFC Manager cannot recover native monitor %x\n", errno);
      return -1;
   }


   return jniRegisterNativeMethods(e,
      "com/android/nfc/nxp/NativeNfcManager",
      gMethods, NELEM(gMethods));
}


2、


/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] =
{
   {"doDownload", "()Z",
        (void *)com_android_nfc_NfcManager_doDownload},


   {"initializeNativeStructure", "()Z",
      (void *)com_android_nfc_NfcManager_init_native_struc},


   {"initialize", "()Z",
      (void *)com_android_nfc_NfcManager_initialize},
 
   {"deinitialize", "()Z",
      (void *)com_android_nfc_NfcManager_deinitialize},
      
   {"enableDiscovery", "()V",
      (void *)com_android_nfc_NfcManager_enableDiscovery},


   {"doGetSecureElementList", "()[I",
      (void *)com_android_nfc_NfcManager_doGetSecureElementList},
      
   {"doSelectSecureElement", "()V",
      (void *)com_android_nfc_NfcManager_doSelectSecureElement},
      
   {"doDeselectSecureElement", "()V",
      (void *)com_android_nfc_NfcManager_doDeselectSecureElement},
      
   {"doCheckLlcp", "()Z",
      (void *)com_android_nfc_NfcManager_doCheckLlcp},
      
   {"doActivateLlcp", "()Z",
      (void *)com_android_nfc_NfcManager_doActivateLlcp},
            
   {"doCreateLlcpConnectionlessSocket", "(I)Lcom/android/nfc/nxp/NativeLlcpConnectionlessSocket;",
      (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
        
   {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/nxp/NativeLlcpServiceSocket;",
      (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
      
   {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/nxp/NativeLlcpSocket;",
      (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
      
   {"doGetLastError", "()I",
      (void *)com_android_nfc_NfcManager_doGetLastError},


   {"disableDiscovery", "()V",
      (void *)com_android_nfc_NfcManager_disableDiscovery},


   {"doSetTimeout", "(II)Z",
      (void *)com_android_nfc_NfcManager_doSetTimeout},


   {"doGetTimeout", "(I)I",
      (void *)com_android_nfc_NfcManager_doGetTimeout},


   {"doResetTimeouts", "()V",
      (void *)com_android_nfc_NfcManager_doResetTimeouts},


   {"doAbort", "()V",
      (void *)com_android_nfc_NfcManager_doAbort},


   {"doDump", "()Ljava/lang/String;",
      (void *)com_android_nfc_NfcManager_doDump},
};   




3、




/* Init/Deinit method */
static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
{
   struct nfc_jni_native_data *nat = NULL;
   int init_result = JNI_FALSE;
#ifdef TNFC_EMULATOR_ONLY
   char value[PROPERTY_VALUE_MAX];
#endif
   jboolean result;
   
   CONCURRENCY_LOCK();


#ifdef TNFC_EMULATOR_ONLY
   if (!property_get("ro.kernel.qemu", value, 0))
   {
      LOGE("NFC Initialization failed: not running in an emulator\n");
      goto clean_and_return;
   }
#endif


   /* Retrieve native structure address */
   nat = nfc_jni_get_nat(e, o);


   nat->seId = SMX_SECURE_ELEMENT_ID;


   nat->lto = 150;  // LLCP_LTO
   nat->miu = 128; // LLCP_MIU
   nat->wks = 1;  // LLCP_WKS
   nat->opt = 0;  // LLCP_OPT
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
   nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;


   nat->registry_info.MifareUL = TRUE;
   nat->registry_info.MifareStd = TRUE;
   nat->registry_info.ISO14443_4A = TRUE;
   nat->registry_info.ISO14443_4B = TRUE;
   nat->registry_info.Jewel = TRUE;
   nat->registry_info.Felica = TRUE;
   nat->registry_info.NFC = TRUE;
   nat->registry_info.ISO15693 = TRUE;


   exported_nat = nat;


   /* Perform the initialization */
   init_result = nfc_jni_initialize(nat);


clean_and_return:
   CONCURRENCY_UNLOCK();


   /* Convert the result and return */
   return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
}


4、




/* Initialization function */
static int nfc_jni_initialize(struct nfc_jni_native_data *nat) {
   struct timespec ts;
   uint8_t resp[16];
   NFCSTATUS status;
   phLibNfc_StackCapabilities_t caps;
   phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
   uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0;
   phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo;
   struct nfc_jni_callback_data cb_data;
   uint8_t firmware_status;
   uint8_t update = TRUE;
   int result = JNI_FALSE;
   const hw_module_t* hw_module;
   nfc_pn544_device_t* pn544_dev = NULL;
   int ret = 0;
   LOGD("Start Initialization\n");


   /* Create the local semaphore */
   if (!nfc_cb_data_init(&cb_data, NULL))
   {
      goto clean_and_return;
   }
   /* Get EEPROM values and device port from product-specific settings */
   ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module);
   if (ret) {
      LOGE("hw_get_module() failed.");
      goto clean_and_return;
   }
   ret = nfc_pn544_open(hw_module, &pn544_dev);
   if (ret) {
      LOGE("Could not open pn544 hw_module.");
      goto clean_and_return;
   }
   if (pn544_dev->num_eeprom_settings == 0 || pn544_dev->eeprom_settings == NULL) {
       LOGE("Could not load EEPROM settings");
       goto clean_and_return;
   }


   /* Reset device connected handle */
   device_connected_flag = 0;


   /* Reset stored handle */
   storedHandle = 0;


   /* Initialize Driver */
   if(!driverConfigured)
   {
       nfc_jni_configure_driver(nat);
   }


   /* ====== INITIALIZE ======= */


   TRACE("phLibNfc_Mgt_Initialize()");
   REENTRANCE_LOCK();
   status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data);
   REENTRANCE_UNLOCK();
   if(status != NFCSTATUS_PENDING)
   {
      LOGE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
      update = FALSE;
      goto force_download;
   }
   TRACE("phLibNfc_Mgt_Initialize returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
  
   /* Wait for callback response */
   if(sem_wait(&cb_data.sem))
   {
      LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
      goto clean_and_return;
   }


   /* Initialization Status */
   if(cb_data.status != NFCSTATUS_SUCCESS)
   {
      update = FALSE;
      goto force_download;
   }


   /* ====== CAPABILITIES ======= */


   REENTRANCE_LOCK();
   status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat);
   REENTRANCE_UNLOCK();
   if (status != NFCSTATUS_SUCCESS)
   {
      LOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   }
   else
   {
       LOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
             caps.psDevCapabilities.hal_version,
             caps.psDevCapabilities.fw_version,
             caps.psDevCapabilities.hw_version,
             caps.psDevCapabilities.model_id,
             caps.psDevCapabilities.hci_version,
             caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
             caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
             caps.psDevCapabilities.firmware_update_info);
   }


   /* ====== FIRMWARE VERSION ======= */
   if(caps.psDevCapabilities.firmware_update_info)
   {
force_download:
       for (i=0; i<3; i++)
       {
           TRACE("Firmware version not UpToDate");
           status = nfc_jni_download(nat, update);
           if(status == NFCSTATUS_SUCCESS)
           {
               LOGI("Firmware update SUCCESS");
               break;
           }
           LOGW("Firmware update FAILED");
           update = FALSE;
       }
       if(i>=3)
       {
           LOGE("Unable to update firmware, giving up");
           goto clean_and_return;
       }
   }
   else
   {
       TRACE("Firmware version UpToDate");
   }


   /* ====== EEPROM SETTINGS ======= */


   // Update EEPROM settings
   TRACE("******  START EEPROM SETTINGS UPDATE ******");
   for (i = 0; i < pn544_dev->num_eeprom_settings; i++)
   {
      gInputParam.buffer = &(pn544_dev->eeprom_settings[i*4]);
      gInputParam.length = 0x04;
      gOutputParam.buffer = resp;


      TRACE("> EEPROM SETTING: %d", i);


      REENTRANCE_LOCK();
      status = phLibNfc_Mgt_IoCtl(gHWRef, NFC_MEM_WRITE, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
      REENTRANCE_UNLOCK();
      if (status != NFCSTATUS_PENDING) {
         LOGE("phLibNfc_Mgt_IoCtl() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
         goto clean_and_return;
      }
      /* Wait for callback response */
      if(sem_wait(&cb_data.sem))
      {
         LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
         goto clean_and_return;
      }


      /* Initialization Status */
      if (cb_data.status != NFCSTATUS_SUCCESS)
      {
         goto clean_and_return;
      }
   }
   TRACE("******  ALL EEPROM SETTINGS UPDATED  ******");


   /* ====== SECURE ELEMENTS ======= */


   REENTRANCE_LOCK();
   LOGD("phLibNfc_SE_GetSecureElementList()");
   status = phLibNfc_SE_GetSecureElementList(SE_List, &No_SE);
   REENTRANCE_UNLOCK();
   if (status != NFCSTATUS_SUCCESS)
   {
      LOGD("phLibNfc_SE_GetSecureElementList(): Error");
      goto clean_and_return;
   }


   LOGD("\n> Number of Secure Element(s) : %d\n", No_SE);
   /* Display Secure Element information */
   for (i = 0; i < No_SE; i++)
   {
      if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) {
         LOGD("phLibNfc_SE_GetSecureElementList(): SMX detected, handle=%p", (void*)SE_List[i].hSecureElement);
      } else if (SE_List[i].eSE_Type == phLibNfc_SE_Type_UICC) {
         LOGD("phLibNfc_SE_GetSecureElementList(): UICC detected, handle=%p", (void*)SE_List[i].hSecureElement);
      }


      /* Set SE mode - Off */
      REENTRANCE_LOCK();
      status = phLibNfc_SE_SetMode(SE_List[i].hSecureElement,
            phLibNfc_SE_ActModeOff, nfc_jni_se_set_mode_callback,
            (void *)&cb_data);
      REENTRANCE_UNLOCK();
      if (status != NFCSTATUS_PENDING)
      {
         LOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status,
               nfc_jni_get_status_name(status));
         goto clean_and_return;
      }
      LOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status,
            nfc_jni_get_status_name(status));


      /* Wait for callback response */
      if(sem_wait(&cb_data.sem))
      {
         LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
         goto clean_and_return;
      }
   }


   /* ====== LLCP ======= */


   /* LLCP Params */
   TRACE("******  NFC Config Mode NFCIP1 - LLCP ******");
   LlcpConfigInfo.miu    = nat->miu;
   LlcpConfigInfo.lto    = nat->lto;
   LlcpConfigInfo.wks    = nat->wks;
   LlcpConfigInfo.option = nat->opt;


   REENTRANCE_LOCK();
   status = phLibNfc_Mgt_SetLlcp_ConfigParams(&LlcpConfigInfo,
                                              nfc_jni_llcpcfg_callback,
                                              (void *)&cb_data);
   REENTRANCE_UNLOCK();
   if(status != NFCSTATUS_PENDING)
   {
      LOGE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status,
           nfc_jni_get_status_name(status));
      goto clean_and_return;
   }
   TRACE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status,
         nfc_jni_get_status_name(status));


   /* Wait for callback response */
   if(sem_wait(&cb_data.sem))
   {
      LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
      goto clean_and_return;
   }


   /* ===== DISCOVERY ==== */
   nat->discovery_cfg.NfcIP_Mode = get_p2p_mode();  //initiator
   nat->discovery_cfg.Duration = 300000; /* in ms */
   nat->discovery_cfg.NfcIP_Tgt_Disable = get_p2p_target_disable();


   /* Register for the card emulation mode */
   REENTRANCE_LOCK();
   ret = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat);
   REENTRANCE_UNLOCK();
   if(ret != NFCSTATUS_SUCCESS)
   {
        LOGD("phLibNfc_SE_NtfRegister returned 0x%02x",ret);
        goto clean_and_return;
   }
   TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", ret);




   /* ====== END ======= */


   LOGI("NFC Initialized");


   result = TRUE;


clean_and_return:
   if (result != TRUE)
   {
      if(nat)
      {
         kill_client(nat);
      }
   }
   if (pn544_dev != NULL) {
       nfc_pn544_close(pn544_dev);
   }
   nfc_cb_data_deinit(&cb_data);


   return result;
}
5、






static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat)
{
    char value[PROPERTY_VALUE_MAX];
    int result = FALSE;
    NFCSTATUS status;


    /* ====== CONFIGURE DRIVER ======= */
    /* Configure hardware link */
    gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);


    TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x, 0x%08x)", gDrvCfg.nClientId);
    REENTRANCE_LOCK();
    status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
    REENTRANCE_UNLOCK();
    if(status == NFCSTATUS_ALREADY_INITIALISED) {
           LOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
    }
    else if(status != NFCSTATUS_SUCCESS)
    {
        LOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
        goto clean_and_return;
    }
    TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));


    if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0)
    {
        LOGE("pthread_create failed");
        goto clean_and_return;
    }


    driverConfigured = TRUE;


clean_and_return:
    return result;
}


//phLibNfc.c e:\android\ubetter210\disc1\android4.0\android210-androidfs_v03\android210-androidfs_v03\external\libnfc-nxp\Src352792012-1-31




6、


/*
*************************** Function Definitions ******************************
*/


NFCSTATUS phLibNfc_Mgt_ConfigureDriver (pphLibNfc_sConfig_t     psConfig,
                                        void **                 ppDriverHandle)
{
    if(NULL != gpphLibContext)
    {
        return NFCSTATUS_ALREADY_INITIALISED;
    }   


    return phDal4Nfc_Config(psConfig, ppDriverHandle);
}




//phDal4Nfc.c e:\android\ubetter210\disc1\android4.0\android210-androidfs_v03\android210-androidfs_v03\external\libnfc-nxp\Linux_x86355332012-1-31




7、




/*-----------------------------------------------------------------------------


FUNCTION: phDal4Nfc_Config


PURPOSE: Configure the serial port.


-----------------------------------------------------------------------------*/
NFCSTATUS phDal4Nfc_Config(pphDal4Nfc_sConfig_t config,void **phwref)
{
   NFCSTATUS                       retstatus = NFCSTATUS_SUCCESS;
   const hw_module_t* hw_module;
   nfc_pn544_device_t* pn544_dev;
   uint8_t num_eeprom_settings;
   uint8_t* eeprom_settings;
   int ret;


   /* Retrieve the hw module from the Android NFC HAL */
   ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module);
   if (ret) {
       LOGE("hw_get_module() failed");
       return NFCSTATUS_FAILED;
   }
   ret = nfc_pn544_open(hw_module, &pn544_dev);
   if (ret) {
       LOGE("Could not open pn544 hw_module");
       return NFCSTATUS_FAILED;
   }
   config->deviceNode = pn544_dev->device_node;
   if (config->deviceNode == NULL) {
       LOGE("deviceNode NULL");
       return NFCSTATUS_FAILED;
   }


   DAL_PRINT("phDal4Nfc_Config");


   if ((config == NULL) || (phwref == NULL))
      return NFCSTATUS_INVALID_PARAMETER;


   /* Register the link callbacks */
   memset(&gLinkFunc, 0, sizeof(phDal4Nfc_link_cbk_interface_t));
   switch(pn544_dev->linktype)
   {
      case PN544_LINK_TYPE_UART:
      case PN544_LINK_TYPE_USB:
      {
DAL_PRINT("UART link Config");
         /* Uart link interface */
         gLinkFunc.init               = phDal4Nfc_uart_initialize;
         gLinkFunc.open_from_handle   = phDal4Nfc_uart_set_open_from_handle;
         gLinkFunc.is_opened          = phDal4Nfc_uart_is_opened;
         gLinkFunc.flush              = phDal4Nfc_uart_flush;
         gLinkFunc.close              = phDal4Nfc_uart_close;
         gLinkFunc.open_and_configure = phDal4Nfc_uart_open_and_configure;
         gLinkFunc.read               = phDal4Nfc_uart_read;
         gLinkFunc.write              = phDal4Nfc_uart_write;
         gLinkFunc.reset              = phDal4Nfc_uart_reset;
      }
      break;


      case PN544_LINK_TYPE_I2C:
      {
DAL_PRINT("I2C link Config");
         /* i2c link interface */
         gLinkFunc.init               = phDal4Nfc_i2c_initialize;
         gLinkFunc.open_from_handle   = phDal4Nfc_i2c_set_open_from_handle;
         gLinkFunc.is_opened          = phDal4Nfc_i2c_is_opened;
         gLinkFunc.flush              = phDal4Nfc_i2c_flush;
         gLinkFunc.close              = phDal4Nfc_i2c_close;
         gLinkFunc.open_and_configure = phDal4Nfc_i2c_open_and_configure;
         gLinkFunc.read               = phDal4Nfc_i2c_read;
         gLinkFunc.write              = phDal4Nfc_i2c_write;
         gLinkFunc.reset              = phDal4Nfc_i2c_reset;
         break;
      }


      default:
      {
         /* Shound not happen : Bad parameter */
         return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_PARAMETER);
      }
   }


   gLinkFunc.init(); /* So that link interface can initialize its internal state */
   retstatus = gLinkFunc.open_and_configure(config, phwref);
   if (retstatus != NFCSTATUS_SUCCESS)
      return retstatus;


   /* Iniatilize the DAL context */
   (void)memset(&gDalContext,0,sizeof(phDal4Nfc_SContext_t));
   pgDalContext = &gDalContext;
   
   /* Reset the Reader Thread values to NULL */
   memset((void *)&gReadWriteContext,0,sizeof(gReadWriteContext));
   gReadWriteContext.nReadThreadAlive     = TRUE;
   gReadWriteContext.nWriteBusy = FALSE;
   gReadWriteContext.nWaitingOnWrite = FALSE;
   
   /* Prepare the message queue for the defered calls */
#ifdef USE_MQ_MESSAGE_QUEUE
   nDeferedCallMessageQueueId = mq_open(MQ_NAME_IDENTIFIER, O_CREAT|O_RDWR, 0666, &MQ_QUEUE_ATTRIBUTES);
#else
   nDeferedCallMessageQueueId = config->nClientId;
#endif


   gDalContext.pDev = pn544_dev;


   /* Start Read and Write Threads */
   if(NFCSTATUS_SUCCESS != phDal4Nfc_StartThreads())
   {
      return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_FAILED);
   }


   gDalContext.hw_valid = TRUE;
   phDal4Nfc_Reset(1);
   phDal4Nfc_Reset(0);
   phDal4Nfc_Reset(1);


   return NFCSTATUS_SUCCESS;
}


int hw_get_module(const char *id, const struct hw_module_t **module)
{
    return hw_get_module_by_class(id, NULL, module);
}






static inline int nfc_pn544_open(const struct hw_module_t* module,
        nfc_pn544_device_t** dev) {
    return module->methods->open(module, NFC_PN544_CONTROLLER,
        (struct hw_device_t**) dev);
}








/*
 * Generic device handling
 */


static int nfc_open(const hw_module_t* module, const char* name,
        hw_device_t** device) {
    if (strcmp(name, NFC_PN544_CONTROLLER) == 0) {
        nfc_pn544_device_t *dev = calloc(1, sizeof(nfc_pn544_device_t));


        dev->common.tag = HARDWARE_DEVICE_TAG;
        dev->common.version = 0;
        dev->common.module = (struct hw_module_t*) module;
        dev->common.close = pn544_close;


        dev->num_eeprom_settings = sizeof(pn544_eedata_settings) / 4;
        dev->eeprom_settings = (uint8_t*)pn544_eedata_settings;
        dev->linktype = PN544_LINK_TYPE_UART;
        dev->device_node = "/dev/ttyO3";
        dev->enable_i2c_workaround = 0;
        *device = (hw_device_t*) dev;
        return 0;
    } else {
        return -EINVAL;
    }
}






static struct hw_module_methods_t nfc_module_methods = {
    .open = nfc_open,
};










//phDal4Nfc_messageQueueLib.h e:\android\ubetter210\disc1\android4.0\android210-androidfs_v03\android210-androidfs_v03\external\libnfc-nxp\Src14372012-1-31




8、




/*-----------------------------------------------------------------------------


FUNCTION: phDal4Nfc_uart_close


PURPOSE:  Closes the link


-----------------------------------------------------------------------------*/


NFCSTATUS phDal4Nfc_uart_open_and_configure(pphDal4Nfc_sConfig_t pConfig, void ** pLinkHandle)
{
   int          nComStatus;
   NFCSTATUS    nfcret = NFCSTATUS_SUCCESS;
   int          ret;


   DAL_ASSERT_STR(gComPortContext.nOpened==0, "Trying to open but already done!");


   srand(time(NULL));


   /* open communication port handle */
   gComPortContext.nHandle = open(pConfig->deviceNode, O_RDWR | O_NOCTTY);
   if (gComPortContext.nHandle < 0)
   {
      *pLinkHandle = NULL;
      return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
   }


   gComPortContext.nOpened = 1;
   *pLinkHandle = (void*)gComPortContext.nHandle;


   /*
    *  Now configure the com port
    */
   ret = tcgetattr(gComPortContext.nHandle, &gComPortContext.nIoConfigBackup); /* save the old io config */
   if (ret == -1)
   {
      /* tcgetattr failed -- it is likely that the provided port is invalid */
      *pLinkHandle = NULL;
      return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
   }
   ret = fcntl(gComPortContext.nHandle, F_SETFL, 0); /* Makes the read blocking (default).  */
   DAL_ASSERT_STR(ret != -1, "fcntl failed");
   /* Configures the io */
   memset((void *)&gComPortContext.nIoConfig, (int)0, (size_t)sizeof(struct termios));
   /*
    BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
    CRTSCTS : output hardware flow control (only used if the cable has
              all necessary lines. See sect. 7 of Serial-HOWTO)
    CS8     : 8n1 (8bit,no parity,1 stopbit)
    CLOCAL  : local connection, no modem contol
    CREAD   : enable receiving characters
   */
   gComPortContext.nIoConfig.c_cflag = DAL_BAUD_RATE | CS8 | CLOCAL | CREAD;  /* Control mode flags */
   gComPortContext.nIoConfig.c_iflag = IGNPAR;                                          /* Input   mode flags : IGNPAR  Ignore parity errors */
   gComPortContext.nIoConfig.c_oflag = 0;                                               /* Output  mode flags */
   gComPortContext.nIoConfig.c_lflag = 0;                                               /* Local   mode flags. Read mode : non canonical, no echo */
   gComPortContext.nIoConfig.c_cc[VTIME] = 0;                                           /* Control characters. No inter-character timer */
   gComPortContext.nIoConfig.c_cc[VMIN]  = 1;                                           /* Control characters. Read is blocking until X characters are read */


   /*
      TCSANOW  Make changes now without waiting for data to complete
      TCSADRAIN   Wait until everything has been transmitted
      TCSAFLUSH   Flush input and output buffers and make the change
   */
   ret = tcsetattr(gComPortContext.nHandle, TCSANOW, &gComPortContext.nIoConfig);
   DAL_ASSERT_STR(ret != -1, "tcsetattr failed");


   /*
      On linux the DTR signal is set by default. That causes a problem for pn544 chip
      because this signal is connected to "reset". So we clear it. (on windows it is cleared by default).
   */
   ret = ioctl(gComPortContext.nHandle, TIOCMGET, &nComStatus);
   DAL_ASSERT_STR(ret != -1, "ioctl TIOCMGET failed");
   nComStatus &= ~TIOCM_DTR;
   ret = ioctl(gComPortContext.nHandle, TIOCMSET, &nComStatus);
   DAL_ASSERT_STR(ret != -1, "ioctl TIOCMSET failed");
   DAL_DEBUG("Com port status=%d\n", nComStatus);
   usleep(10000); /* Mandatory sleep so that the DTR line is ready before continuing */


   return nfcret;
}





  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值