中级
20 分钟

使用PN7160A1HN/C100和dsPIC30F4011将NFC功能集成到各种应用中

符合NFC论坛和NCI 2.0标准的近场通信(NFC)

NFC 7 Click - I2C with EasyPIC v7 for dsPIC30

已发布 12月 30, 2024

点击板

NFC 7 Click - I2C

开发板

EasyPIC v7 for dsPIC30

编译器

NECTO Studio

微控制器单元

dsPIC30F4011

具有高灵敏度和低功耗的 NFC 功能,非常适合移动设备和智能家居网关

A

A

硬件概览

它是如何工作的?

NFC 7 Click 基于 NXP 的 PN7160,这是一款近场通信(NFC)控制器,旨在符合 NFC Forum 和 NCI 2.0 标准,能够为各种 NFC 应用提供强大的集成能力。本版本的 NFC 7 Click 仅通过 I2C 接口(PN7160A1HN/C100)与主 MCU 通信,采用优化架构以实现低功耗。PN7160 提供多种省电模式,包括硬件关机模式、由固件激活的待机模式以及低功耗轮询循环进行自动设备发现,确保在各种操作场景下高效使用能源。NFC 7 Click 特别适用于便携式和低功耗应用场景,在这些场景中,可靠的 NFC 功能至关重要,包括移动设备、可穿戴技术、个人数字助理、消费电子设备以及智能家居网关。PN7160 的核心是新一代射频无接触前端,支持符合 NFCIP-1 和 NFCIP-2 以及 ISO/IEC 14443、ISO/IEC 15693、MIFARE 和 FeliCa 标准的传输模式。其先进设计显著

提高了性能,提供更高的灵敏度和主动负载调制能力。这些改进使 NFC 7 Click 即使在集成的小天线设计中,也能保持可靠通信。PN7160 引入了增强的动态负载调制幅度(DLMA),可根据外部场强动态调整调制幅度。在卡片仿真模式下,此功能延长了通信距离,并确保 A、B 和 F 型通信具有 5° 精度的独立相位调整。此外,动态功率控制使电路板在读取模式下能够以最大功率运行,同时不会超出标准定义的限制,即使在零距离时也是如此。在独立卡片功能中,PN7160 一旦由主 MCU 配置完成,即可自主运行,让被动集成电路卡(PICC)功能无需主机持续供电,从而成为高能效和始终在线 NFC 应用的理想解决方案。如前所述,NFC 7 Click 使用标准的两线 I2C 通信协议,允许主 MCU 以高达 3.4MHz 的时钟频率(高速模式)控制 PN7160。在此 I2C 版本的电路板

中,必须填充 ADDR SEL 跳线以选择所需的 I2C 地址,确保与主设备的正确通信。此外,电路板背面包含一组电阻,根据电路板版本需要填充;在本例中,仅填充 I2C 所需位置的电阻以支持 I2C 功能。除了接口引脚,NFC 7 Click 包括 VEN 引脚,用于将设备置于硬件关机模式,以在不使用时节省能源。它还使用 IRQ 引脚处理中断请求,为主 MCU 提供一种机制,以快速响应事件,例如标签检测、操作完成或错误,从而增强基于 NFC 的应用的整体响应能力和效率。该 Click 电路板™ 可通过 VCC SEL 跳线选择使用 3.3V 或 5V 逻辑电压电平运行。这样,3.3V 和 5V 的主 MCU 都可以正确使用通信线路。此外,该电路板配备了一个库,其中包含易于使用的功能和示例代码,可用作进一步开发的参考。

NFC 7 Click (I2C) hardware overview image

功能概述

开发板

EasyPIC v7 for dsPIC30 是第七代PIC开发板,专为快速开发嵌入式应用而设计。它支持广泛的16位PIC微控制器,来自Microchip,并具有一系列独特功能,如强大的板载mikroProg程序员和通过USB的在线电路调试器。开发板布局合理,设计周到,使得最终用户可以在一个地方找到所有必要的元素,如开关、按钮、指示灯、连接器等。EasyPIC v7 for dsPIC30 通过每个端口的三种不同连接器,比以往更高效地连接附件板、传感器和自定义电子产品。EasyPIC v7 for 

dsPIC30 开发板的每个部分都包含了使同一板块运行最高效的必要组件。一个集成的mikroProg,一个快速的USB 2.0程序员,带有mikroICD硬件在线电路调试 器,提供许多有价值的编程/调试选项和与Mikroe软件环境的无缝集成。此外,它还包括一个干净且调节过的开发板电源供应模块。它可以使用多种外部电源,包括外部12V电源供应,7-23V交流或9-32V直流通过DC连接器/螺丝端子,以及通过USB Type-B(USB-B)连接器的电源。通信选项如USB-UART、RS-232

和CAN也包括在内,与广受好评的mikroBUS™标 准、三种显示选项(7段、图形和基于字符的LCD)以及几种不同的DIP插座一起,覆盖了广泛的16位dsPIC/PIC24 MCU。EasyPIC v7 for dsPIC30 是Mikroe快速开发生态系统的一个组成部分。它由Mikroe软件工具原生支持,得益于大量不同的Click板™(超过一千块板),其数量每天都在增长,它涵盖了原型制作和开发的许多方面。

EasyPIC v7 for dsPIC30 horizontal image

微控制器概述 

MCU卡片 / MCU

dsPIC30F4011

建筑

dsPIC

MCU 内存 (KB)

48

硅供应商

Microchip

引脚数

40

RAM (字节)

2048

你完善了我!

配件

运行在 13.56MHz 的 RFID 标签符合 ISO14443-A 标准,确保了高频通信。这种近距离卡技术,通常以 MIFARE 卡为代表,在访问控制、公共交通和支付系统等应用中实现了安全且无接触的交互。ISO14443-A 标准定义了通信协议,并包含防冲突机制以便同时处理多个卡片。这些 RFID 标签具有可变的内存容量,从几字节到几千字节不等,满足不同应用需求。为确保数据安全,该标准集成了加密和身份验证等功能。以 MIFARE 技术为代表的这些标签因其高效性而广泛应用,在多种识别和访问场景中显著提高了便利性和安全性。

NFC 7 Click (I2C) accessories 1 image

使用的MCU引脚

mikroBUS™映射器

NC
NC
AN
ID SEL
RA11
RST
ID COMM
RB11
CS
NC
NC
SCK
NC
NC
MISO
NC
NC
MOSI
Power Supply
3.3V
3.3V
Ground
GND
GND
Hard Power-Down Mode
RD2
PWM
Interrupt Request
RD8
INT
NC
NC
TX
NC
NC
RX
I2C Clock
RF3
SCL
I2C Data
RF2
SDA
Power Supply
5V
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

NFC 7 Click (I2C) Schematic schematic

一步一步来

项目组装

EasyPIC v7 for dsPIC30 front image hardware assembly

从选择您的开发板和Click板™开始。以EasyPIC v7 for dsPIC30作为您的开发板开始。

EasyPIC v7 for dsPIC30 front image hardware assembly
GNSS2 Click front image hardware assembly
GNSS2 Click complete accessories setup image hardware assembly
EasyPIC for dsPIC30 v7 Access MB 1 - upright/background hardware assembly
Necto image step 2 hardware assembly
Necto image step 3 hardware assembly
Necto image step 4 hardware assembly
NECTO Compiler Selection Step Image hardware assembly
NECTO Output Selection Step Image hardware assembly
Necto image step 6 hardware assembly
Necto DIP image step 7 hardware assembly
EasyPIC PRO v7a Display Selection Necto Step hardware assembly
Necto image step 9 hardware assembly
Necto image step 10 hardware assembly
Necto PreFlash Image hardware assembly

实时跟踪您的结果

应用程序输出

1. 应用程序输出 - 在调试模式下,“应用程序输出”窗口支持实时数据监控,直接提供执行结果的可视化。请按照提供的教程正确配置环境,以确保数据正确显示。

2. UART 终端 - 使用UART Terminal通过USB to UART converter监视数据传输,实现Click board™与开发系统之间的直接通信。请根据项目需求配置波特率和其他串行设置,以确保正常运行。有关分步设置说明,请参考提供的教程

3. Plot 输出 - Plot功能提供了一种强大的方式来可视化实时传感器数据,使趋势分析、调试和多个数据点的对比变得更加直观。要正确设置,请按照提供的教程,其中包含使用Plot功能显示Click board™读数的分步示例。在代码中使用Plot功能时,请使用以下函数:plot(insert_graph_name, variable_name);。这是一个通用格式,用户需要将“insert_graph_name”替换为实际图表名称,并将“variable_name”替换为要显示的参数。

软件支持

库描述

该库包含 NFC 2 Click (I2C) 驱动程序的 API。

关键功能:

  • nfc7i2c_wait_discovery - 此函数等待直到发现远程 NFC 设备。

  • nfc7i2c_presence_check - 此函数等待直到已发现的目标设备被移除。

  • nfc7i2c_stop_discovery - 此函数停止射频发现过程。

开源

代码示例

完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio 应用程序代码也可以在MIKROE的GitHub账户中找到。

/*!
 * @file main.c
 * @brief NFC 7 I2C Click example
 *
 * # Description
 * This example demonstrates the use of NFC 7 I2C Click board by handling the detection
 * and processing of various NFC technologies and protocols, and ensuring the application
 * can respond to different NFC card types (A,B,F,V).
 *
 * The demo application is composed of two sections :
 *
 * ## Application Init
 * Initializes the driver and logger, performs the Click default configuration and
 * reads the device firmware version.
 *
 * ## Application Task
 * Waits for an NFC device to be discovered, checks if it supports a known NFC technology, 
 * and then handles the device based on its protocol. The application continues processing
 * the device (reading and writing information) and waits until the card is removed.
 * Once the card is removed, the discovery process is restarted to detect a new NFC device.
 *
 * @author Stefan Filipovic
 *
 */

#include "board.h"
#include "log.h"
#include "nfc7i2c.h"

static nfc7i2c_t nfc7i2c;
static log_t logger;

/**
 * @brief NFC 7 I2C handle ISO14443-3A function.
 * @details This function handles discovered ISO14443-3A / Type 2 Tag (T2T) card by performing
 * read/write data to memory block 32.
 * @param[in] ctx : Click context object.
 * See #nfc7i2c_t object definition for detailed explanation.
 * @return None.
 * @note None.
 */
static void nfc7i2c_handle_iso14443_3a ( nfc7i2c_t *ctx );

/**
 * @brief NFC 7 I2C handle ISO14443-4 function.
 * @details This function handles discovered ISO14443-4 (ISO-DEP) card by selecting the PPSE
 * (Paypass Payment System Environment) application.
 * @param[in] ctx : Click context object.
 * See #nfc7i2c_t object definition for detailed explanation.
 * @return None.
 * @note None.
 */
static void nfc7i2c_handle_iso14443_4 ( nfc7i2c_t *ctx );

/**
 * @brief NFC 7 I2C handle ISO15693 function.
 * @details This function handles discovered ISO15693 card by performing read/write data
 * to memory block 32.
 * @param[in] ctx : Click context object.
 * See #nfc7i2c_t object definition for detailed explanation.
 * @return None.
 * @note None.
 */
static void nfc7i2c_handle_iso15693 ( nfc7i2c_t *ctx );

/**
 * @brief NFC 7 I2C handle mifare function.
 * @details This function handles discovered MIFARE card by performing read/write data
 * to memory block 32.
 * @param[in] ctx : Click context object.
 * See #nfc7i2c_t object definition for detailed explanation.
 * @return None.
 * @note None.
 */
static void nfc7i2c_handle_mifare ( nfc7i2c_t *ctx );

/**
 * @brief NFC 7 I2C display card info function.
 * @details This function parses and displays the discovered card info on the USB UART.
 * @param[in] rf_intf : Discovered NFC remote device properties.
 * @return None.
 * @note None.
 */
static void nfc7i2c_display_card_info ( nfc7i2c_rf_intf_t rf_intf );

void application_init ( void ) 
{
    log_cfg_t log_cfg;  /**< Logger config object. */
    nfc7i2c_cfg_t nfc7i2c_cfg;  /**< Click config object. */

    /** 
     * Logger initialization.
     * Default baud rate: 115200
     * Default log level: LOG_LEVEL_DEBUG
     * @note If USB_UART_RX and USB_UART_TX 
     * are defined as HAL_PIN_NC, you will 
     * need to define them manually for log to work. 
     * See @b LOG_MAP_USB_UART macro definition for detailed explanation.
     */
    LOG_MAP_USB_UART( log_cfg );
    log_init( &logger, &log_cfg );
    log_info( &logger, " Application Init " );

    // Click initialization.
    nfc7i2c_cfg_setup( &nfc7i2c_cfg );
    NFC7I2C_MAP_MIKROBUS( nfc7i2c_cfg, MIKROBUS_1 );
    if ( I2C_MASTER_ERROR == nfc7i2c_init( &nfc7i2c, &nfc7i2c_cfg ) ) 
    {
        log_error( &logger, " Communication init." );
        for ( ; ; );
    }
    
    if ( NFC7I2C_ERROR == nfc7i2c_default_cfg ( &nfc7i2c ) )
    {
        log_error( &logger, " Default configuration." );
        for ( ; ; );
    }
    log_printf( &logger, " FW version: %.2X.%.2X.%.2X\r\n", 
                ( uint16_t ) nfc7i2c.fw_version[ 0 ], 
                ( uint16_t ) nfc7i2c.fw_version[ 1 ], 
                ( uint16_t ) nfc7i2c.fw_version[ 2 ] );
    
    log_info( &logger, " Application Task " );
}

void application_task ( void ) 
{
    nfc7i2c_rf_intf_t rf_intf;
    log_printf( &logger, " WAITING FOR DEVICE DISCOVERY\r\n\n" );
    if ( NFC7I2C_OK == nfc7i2c_wait_discovery ( &nfc7i2c, &rf_intf ) )
    {
        if ( ( NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_NFC_A == rf_intf.mode_tech ) || 
             ( NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_NFC_B == rf_intf.mode_tech ) || 
             ( NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_NFC_F == rf_intf.mode_tech ) || 
             ( NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_15693 == rf_intf.mode_tech ) )
        {
            for ( ; ; )
            {
                nfc7i2c_display_card_info ( rf_intf );

                switch ( rf_intf.protocol )
                {
                    case NFC7I2C_NCI_RF_PROT_T2T:
                    {
                        nfc7i2c_handle_iso14443_3a ( &nfc7i2c );
                        break;
                    }
                    case NFC7I2C_NCI_RF_PROT_ISODEP:
                    {
                        nfc7i2c_handle_iso14443_4 ( &nfc7i2c );
                        break;
                    }
                    case NFC7I2C_NCI_RF_PROT_T5T:
                    {
                        nfc7i2c_handle_iso15693 ( &nfc7i2c );
                        break;
                    }
                    case NFC7I2C_NCI_RF_PROT_MIFARE:
                    {
                        nfc7i2c_handle_mifare ( &nfc7i2c );
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
                if ( !rf_intf.more_tags )
                {
                    break;
                }
                nfc7i2c_reader_act_next ( &nfc7i2c, &rf_intf );
            }
            
            nfc7i2c_presence_check ( &nfc7i2c, &rf_intf );
            log_printf ( &logger, " - CARD REMOVED\r\n\n" );

            nfc7i2c_stop_discovery ( &nfc7i2c );
            while ( NFC7I2C_OK != nfc7i2c_start_discovery ( &nfc7i2c ) );
        }
        else
        {
            log_printf ( &logger, " - WRONG DISCOVERY\r\n\n" );
        }
    }
}

int main ( void ) 
{
    /* Do not remove this line or clock might not be set correctly. */
    #ifdef PREINIT_SUPPORTED
    preinit();
    #endif
    
    application_init( );
    
    for ( ; ; ) 
    {
        application_task( );
    }

    return 0;
}

static void nfc7i2c_handle_iso14443_3a ( nfc7i2c_t *ctx )
{
    #define BLK_NB_ISO14443_3A      32
    #define DATA_WRITE_ISO14443_3A  0x11, 0x22, 0x33, 0x44
    uint8_t rd_block[ ] = { NFC7I2C_T2T_CMD_READ, BLK_NB_ISO14443_3A };
    uint8_t wr_block[ ] = { NFC7I2C_T2T_CMD_WRITE, BLK_NB_ISO14443_3A, DATA_WRITE_ISO14443_3A };
    err_t error_flag = NFC7I2C_OK;

    // Read block
    ctx->pkt_data.payload_len = sizeof ( rd_block );
    memcpy ( ctx->pkt_data.payload, rd_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_NCI_STAT_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Read block %u failed with error %.2X\r\n", 
                     ( uint16_t ) rd_block[ 1 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Read block %u: ", ( uint16_t ) rd_block[ 1 ] );
    for ( uint8_t cnt = 0; cnt < 4; cnt++ )
    {
        log_printf( &logger, "%.2X ", ( uint16_t ) ctx->pkt_data.payload[ cnt ] );
    }
    log_printf( &logger, "\r\n" );

    // Write block
    ctx->pkt_data.payload_len = sizeof ( wr_block );
    memcpy ( ctx->pkt_data.payload, wr_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || ( NFC7I2C_T2T_ACK != ctx->pkt_data.payload[ 0 ] ) )
    {
        log_printf ( &logger, " Write block %u failed with error %.2X\r\n", 
                     ( uint16_t ) wr_block[ 1 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Block %u written\r\n", ( uint16_t ) wr_block[ 1 ] );
    
    // Read back block
    ctx->pkt_data.payload_len = sizeof ( rd_block );
    memcpy ( ctx->pkt_data.payload, rd_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_NCI_STAT_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Read block %u failed with error %.2X\r\n", 
                     ( uint16_t ) rd_block[ 1 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Read block %u: ", ( uint16_t ) rd_block[ 1 ] );
    for ( uint8_t cnt = 0; cnt < 4; cnt++ )
    {
        log_printf( &logger, "%.2X ", ( uint16_t ) ctx->pkt_data.payload[ cnt ] );
    }
    log_printf( &logger, "\r\n" );
}

static void nfc7i2c_handle_iso14443_4 ( nfc7i2c_t *ctx )
{
    err_t error_flag = NFC7I2C_OK;

    ctx->pkt_data.payload_len = strlen ( NFC7I2C_T4T_PPSE_APDU ) + 6;
    ctx->pkt_data.payload[ 0 ] = NFC7I2C_T4T_CLA_NO_SECURE;
    ctx->pkt_data.payload[ 1 ] = NFC7I2C_T4T_INS_SELECT;
    ctx->pkt_data.payload[ 2 ] = NFC7I2C_T4T_P1_SELECT_BY_NAME;
    ctx->pkt_data.payload[ 3 ] = NFC7I2C_T4T_P2_ONLY_OCCURANCE;
    ctx->pkt_data.payload[ 4 ] = strlen ( NFC7I2C_T4T_PPSE_APDU );
    memcpy ( &ctx->pkt_data.payload[ 5 ], NFC7I2C_T4T_PPSE_APDU, strlen ( NFC7I2C_T4T_PPSE_APDU ) );
    ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] = NFC7I2C_T4T_LE_RSP_MAY_PRESENT;
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_T4T_RSP_COMPLETE_1 != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 2 ] ) || 
         ( NFC7I2C_T4T_RSP_COMPLETE_2 != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Select PPSE failed with error %.2X %.2X\r\n", 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Select PPSE Application succeed\r\n" );
}

static void nfc7i2c_handle_iso15693 ( nfc7i2c_t *ctx )
{
    #define BLK_NB_ISO15693     32
    #define DATA_WRITE_ISO15693 0x11, 0x22, 0x33, 0x44
    uint8_t rd_block[ ] = { NFC7I2C_ISO15693_FLAG_DR_HIGH, NFC7I2C_ISO15693_CMD_READ_SINGLE, BLK_NB_ISO15693 };
    uint8_t wr_block[ ] = { NFC7I2C_ISO15693_FLAG_DR_HIGH, NFC7I2C_ISO15693_CMD_WRITE_SINGLE, 
                            BLK_NB_ISO15693, DATA_WRITE_ISO15693 };
    err_t error_flag = NFC7I2C_OK;

    // Read
    ctx->pkt_data.payload_len = sizeof ( rd_block );
    memcpy ( ctx->pkt_data.payload, rd_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_ISO15693_RSP_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Read block %u failed with error %.2X\r\n", 
                     ( uint16_t ) rd_block[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Read block %u: ", ( uint16_t ) rd_block[ 2 ] );
    for ( uint8_t cnt = 0; cnt < ( ctx->pkt_data.payload_len - 2 ); cnt++ )
    {
        log_printf( &logger, "%.2X ", ( uint16_t ) ctx->pkt_data.payload[ cnt + 1 ] );
    }
    log_printf( &logger, "\r\n" );

    // Write
    ctx->pkt_data.payload_len = sizeof ( wr_block );
    memcpy ( ctx->pkt_data.payload, wr_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_ISO15693_RSP_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Write block %u failed with error %.2X\r\n", 
                     ( uint16_t ) wr_block[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Block %u written\r\n", ( uint16_t ) wr_block[ 2 ] );
    
    // Read back
    ctx->pkt_data.payload_len = sizeof ( rd_block );
    memcpy ( ctx->pkt_data.payload, rd_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_ISO15693_RSP_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Read block %u failed with error %.2X\r\n", 
                     ( uint16_t ) rd_block[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Read block %u: ", ( uint16_t ) rd_block[ 2 ] );
    for ( uint8_t cnt = 0; cnt < ( ctx->pkt_data.payload_len - 2 ); cnt++ )
    {
        log_printf( &logger, "%.2X ", ( uint16_t ) ctx->pkt_data.payload[ cnt + 1 ] );
    }
    log_printf( &logger, "\r\n" );
}

static void nfc7i2c_handle_mifare ( nfc7i2c_t *ctx )
{
    #define BLK_NB_MFC      32 // Do not use first 4 blocks and sector trailer blocks (7, 11, 15, etc)
    #define KEY_MFC         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
    #define DATA_WRITE_MFC  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
    uint8_t authenticate[ ] = { NFC7I2C_MFC_REQ_AUTHENTICATE, BLK_NB_MFC / 4, NFC7I2C_MFC_KEY_SELECTOR_A_EMB, KEY_MFC };
    uint8_t rd_block[ ] = { NFC7I2C_MFC_REQ_XCHG_DATA, NFC7I2C_MFC_CMD_READ, BLK_NB_MFC };
    uint8_t wr_part1[ ] = { NFC7I2C_MFC_REQ_XCHG_DATA, NFC7I2C_MFC_CMD_WRITE, BLK_NB_MFC };
    uint8_t wr_part2[ ] = { NFC7I2C_MFC_REQ_XCHG_DATA, DATA_WRITE_MFC };
    err_t error_flag = NFC7I2C_OK;

    if ( ( BLK_NB_MFC < 4 ) || ( 3 == ( BLK_NB_MFC % 4 ) ) )
    {
        log_printf ( &logger, " Block %u is a sector trailer block\r\n", ( uint16_t ) BLK_NB_MFC );
        return;
    }
    // Authenticate
    ctx->pkt_data.payload_len = sizeof ( authenticate );
    memcpy ( ctx->pkt_data.payload, authenticate, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_NCI_STAT_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Authenticate sector %u failed with error %.2X\r\n", 
                     ( uint16_t ) authenticate[ 1 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Authenticate sector %u succeed\r\n", ( uint16_t ) authenticate[ 1 ] );

    // Read block
    ctx->pkt_data.payload_len = sizeof ( rd_block );
    memcpy ( ctx->pkt_data.payload, rd_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_NCI_STAT_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Read block %u failed with error %.2X\r\n", 
                     ( uint16_t ) rd_block[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Read block %u: ", ( uint16_t ) rd_block[ 2 ] );
    for ( uint8_t cnt = 0; cnt < ( ctx->pkt_data.payload_len - 2 ); cnt++ )
    {
        log_printf( &logger, "%.2X ", ( uint16_t ) ctx->pkt_data.payload[ cnt + 1 ] );
    }
    log_printf( &logger, "\r\n" );

    // Write block
    ctx->pkt_data.payload_len = sizeof ( wr_part1 );
    memcpy ( ctx->pkt_data.payload, wr_part1, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || ( NFC7I2C_MFC_ACK != ctx->pkt_data.payload[ 1 ] ) )
    {
        log_printf ( &logger, " Write block %u failed with error %.2X\r\n", 
                     ( uint16_t ) wr_part1[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    ctx->pkt_data.payload_len = sizeof ( wr_part2 );
    memcpy ( ctx->pkt_data.payload, wr_part2, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || ( NFC7I2C_MFC_ACK != ctx->pkt_data.payload[ 1 ] ) )
    {
        log_printf ( &logger, " Write block %u failed with error %.2X\r\n", 
                     ( uint16_t ) wr_part1[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Block %u written\r\n", ( uint16_t ) wr_part1[ 2 ] );
    
    // Read back
    ctx->pkt_data.payload_len = sizeof ( rd_block );
    memcpy ( ctx->pkt_data.payload, rd_block, ctx->pkt_data.payload_len );
    error_flag = nfc7i2c_reader_tag_cmd ( ctx, &ctx->pkt_data );
    if ( ( NFC7I2C_OK != error_flag ) || 
         ( NFC7I2C_NCI_STAT_OK != ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] ) )
    {
        log_printf ( &logger, " Read block %u failed with error %.2X\r\n", 
                     ( uint16_t ) rd_block[ 2 ], 
                     ( uint16_t ) ctx->pkt_data.payload[ ctx->pkt_data.payload_len - 1 ] );
        return;
    }
    log_printf ( &logger, " Read block %u: ", ( uint16_t ) rd_block[ 2 ] );
    for ( uint8_t cnt = 0; cnt < ( ctx->pkt_data.payload_len - 2 ); cnt++ )
    {
        log_printf( &logger, "%.2X ", ( uint16_t ) ctx->pkt_data.payload[ cnt + 1 ] );
    }
    log_printf( &logger, "\r\n" );
}

static void nfc7i2c_display_card_info ( nfc7i2c_rf_intf_t rf_intf )
{
    switch ( rf_intf.protocol )
    {
        case NFC7I2C_NCI_RF_PROT_T1T:
        case NFC7I2C_NCI_RF_PROT_T2T:
        case NFC7I2C_NCI_RF_PROT_T3T:
        case NFC7I2C_NCI_RF_PROT_ISODEP:
        {
            log_printf( &logger, " - POLL MODE: Remote T%uT activated\r\n", ( uint16_t ) rf_intf.protocol );
            break;
        }
        case NFC7I2C_NCI_RF_PROT_T5T:
        {
            log_printf( &logger, " - POLL MODE: Remote ISO15693 card activated\r\n" );
            break;
        }
        case NFC7I2C_NCI_RF_PROT_MIFARE:
        {
            log_printf( &logger, " - POLL MODE: Remote MIFARE card activated\r\n" );
            break;
        }
        default:
        {
            log_printf( &logger, " - POLL MODE: Undetermined target\r\n" );
            return;
        }
    }

    switch ( rf_intf.mode_tech )
    {
        case NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_NFC_A:
        {
            log_printf( &logger, "\tSENS_RES = %.2X %.2X\r\n", 
                        ( uint16_t ) rf_intf.info.nfc_app.sens_res[ 0 ], 
                        ( uint16_t ) rf_intf.info.nfc_app.sens_res[ 1 ] );
            log_printf( &logger, "\tNFCID = " );
            for ( uint8_t cnt = 0; cnt < rf_intf.info.nfc_app.nfc_id_len; cnt++ )
            {
                log_printf( &logger, "%.2X ", ( uint16_t ) rf_intf.info.nfc_app.nfc_id[ cnt ] );
            }
            log_printf( &logger, "\r\n" );
            if ( 0 != rf_intf.info.nfc_app.sel_res_len )
            {
                log_printf( &logger, "\tSEL_RES = %.2X\r\n", ( uint16_t ) rf_intf.info.nfc_app.sens_res[ 0 ] );
            }
            break;
        }
        case NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_NFC_B:
        {
            if ( 0 != rf_intf.info.nfc_bpp.sens_res_len )
            {
                log_printf( &logger, "\tSENS_RES = " );
                for ( uint8_t cnt = 0; cnt < rf_intf.info.nfc_bpp.sens_res_len; cnt++ )
                {
                    log_printf( &logger, "%.2X ", ( uint16_t ) rf_intf.info.nfc_bpp.sens_res[ cnt ] );
                }
                log_printf( &logger, "\r\n" );
            }
            break;
        }
        case NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_NFC_F:
        {
            log_printf( &logger, "\tBitrate = %s\r\n", ( char * ) 
                        ( ( 1 == rf_intf.info.nfc_fpp.bitrate ) ? "212" : "424" ) );
            if ( 0 != rf_intf.info.nfc_fpp.sens_res_len )
            {
                log_printf( &logger, "\tSENS_RES = " );
                for ( uint8_t cnt = 0; cnt < rf_intf.info.nfc_fpp.sens_res_len; cnt++ )
                {
                    log_printf( &logger, "%.2X ", ( uint16_t ) rf_intf.info.nfc_fpp.sens_res[ cnt ] );
                }
                log_printf( &logger, "\r\n" );
            }
            break;
        }
        case NFC7I2C_NCI_RF_TECH_PASSIVE_POLL_15693:
        {
            log_printf( &logger, "\tID = " );
            for ( uint8_t cnt = 0; cnt < sizeof ( rf_intf.info.nfc_vpp.id ); cnt++ )
            {
                log_printf( &logger, "%.2X ", ( uint16_t ) rf_intf.info.nfc_vpp.id[ cnt ] );
            }
            log_printf( &logger, "\r\n" );
            log_printf( &logger, "\tAFI = %.2X\r\n", ( uint16_t ) rf_intf.info.nfc_vpp.afi );
            log_printf( &logger, "\tDSFID = %.2X\r\n", ( uint16_t ) rf_intf.info.nfc_vpp.dsf_id );
            break;
        }
        default:
        {
            break;
        }
    }
}

// ------------------------------------------------------------------------ END

额外支持

资源

喜欢这个项目吗?

'购买此套件' 按钮会直接带您进入购物车,您可以在购物车中轻松添加或移除产品。