PN532 の 初期化、終了ルーチンを調べる

(Felica/Mifare/NFC チャレンジシリーズ) その他の記事はこちら 「Felica/Mifare/NFC でいろいろ実験」
https://qiita.com/nanbuwks/items/1f416d6e45a87250ee0a

---

ハードウェアハッキングして NFC コントローラの命令を解析する
https://qiita.com/nanbuwks/items/8baa0408e08812258c95

では elechouse のArduinoライブラリの通信内容を解析してみました。

しかしながら、初期化ルーチンはこれだけでは不足しているみたい。改めて初期化ルーチンを調べてみました。今まであれこれ試して調子が良かった、 nfclib の pn53x-tamashell の通信内容を調べてみました。

# 環境

(ターゲット)
- PN532 NFC Module SPI I2C Reader/Writer Breakout Board
  - 電解コンデンサ追加加工済
  - cf., 「NFC モジュールの動作安定性を改善する」
  - https://qiita.com/nanbuwks/items/a9217ba2e8f206b899b1
- Raspberry Pi Model B+ V1.2
- Raspberry Pi OS Lite armhf-2020-12-04
- libnfc 1.8.0
  - cf., 「Raspberry Pi で libnfc + PN532 NFC RFID module」
  - https://qiita.com/nanbuwks/items/0c73add503b354774035

(シリアルハードウエアモニター)
- WEMOS LOLIN32
  - ( ≒ ESP32 DevKitC )
- Arduino 1.8.10 Linux 版
  - portable 化済
  - esp32 by Espressif Systems Version 1.0.3
- Ubuntu Linux 20.04 AMD64


# ESP32 でシリアルのハードウェアモニター

「ハードウェアハッキングして NFC コントローラの命令を解析する」
https://qiita.com/nanbuwks/items/8baa0408e08812258c95

のものより改良して、通信した時刻を表示するようにしました。
以下がESP32 のスケッチです。


```

char dumpbuff[50];
char countbuff[50];
//HardwareSerial Serial1(2);
void setup() {
 Serial.begin(115200);
 Serial2.begin(115200);
}

void loop() {
 unsigned long time,timesec,timemicrosec;
 char timestr[50];
 int counter=0;
 int oldcounter=0;
 for (int counter=0;counter<65536;counter++){
    dumpbuff[0]=0;
    time=micros();
    
    for (int address=0;address<16;address++){
      if (Serial2.available()) {
        int inByte = Serial2.read();
        sprintf(dumpbuff, "%s %02X",dumpbuff,inByte);
      } else {
        sprintf(dumpbuff, "%s --",dumpbuff);        
      }
      delayMicroseconds(20);
    }
    if ( 0 != strcmp(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --",dumpbuff )){ // 空ではなかった場合
      if ( oldcounter != counter -1 )
      {
        Serial.println("...");
      }
      oldcounter=counter; 
      timesec=time/1000000;
      timemicrosec=time % 1000000;
      sprintf(timestr, "%d.%06d ", timesec,timemicrosec);
      Serial.print(timestr);
      sprintf(countbuff, "%07X0: ",counter);
      Serial.print(countbuff);
      Serial.println(dumpbuff);
    }
 }
}
```

配線は、先のリンクと同様に行いました。


# TAMASHELL のログ


RaspberryPi から TAMASHELL を使ったときのログを取ってみました。



```

$ ./pn53x-tamashell
NFC reader: Itead_PN532 opened
```
として起動した時と、

```

> quit
quit
Bye!
```

として終了したときのログを取ってみました。

## 起動した時のログ

```

...
161.637661 000CAC80:  -- -- -- -- 55 55 00 00 00 00 00 00 00 00 00 00
161.638298 000CAC90:  00 00 00 00 00 00 FF 03 FD D4 14 01 17 00 -- --
...
161.641535 000CACE0:  -- -- -- -- -- -- -- 00 00 FF 09 F7 D4 00 00 6C
161.646429 000CACF0:  69 62 6E 66 63 BE 00 00 00 FF 02 FE D4 02 2A 00
161.652592 000CAD00:  00 00 FF 03 FD D4 12 14 06 00 -- -- -- -- -- --
161.658755 000CAD10:  00 00 FF 0C F4 D4 06 63 02 63 03 63 0D 63 38 63
161.664918 000CAD20:  3D B0 00 00 00 FF 08 F8 D4 08 63 02 80 63 03 80
161.671081 000CAD30:  59 00 00 00 FF 04 FC D4 32 01 00 F9 00 -- -- --
161.677244 000CAD40:  00 00 FF 04 FC D4 32 01 01 F8 00 00 00 FF 06 FA
161.683407 000CAD50:  D4 32 05 FF FF FF F8 00 -- -- -- -- -- -- -- --
```

## 終了時のログ


```

...
171.410499 00023ED0:  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 00
171.411063 00023EE0:  00 FF 0E F2 D4 06 63 02 63 03 63 05 63 38 63 3C
171.412604 00023EF0:  63 3D 19 00 -- -- -- -- -- -- -- -- -- -- -- --
171.418767 00023F00:  00 00 FF 08 F8 D4 08 63 05 40 63 3C 10 CD 00 --
171.424930 00023F10:  00 00 FF 03 FD D4 52 00 DA 00 00 00 FF 04 FC D4
171.431093 00023F20:  32 01 00 F9 00 -- -- -- -- -- -- -- -- -- -- --
171.437256 00023F30:  00 00 FF 03 FD D4 16 F0 26 00 -- -- -- -- -- --
```

これらを、読み解いていきます。


## ログの読み方

```

...
161.637661 000CAC80:  -- -- -- -- 55 55 00 00 00 00 00 00 00 00 00 00
161.638298 000CAC90:  00 00 00 00 00 00 FF 03 FD D4 14 01 17 00 -- --
```

これの、161.637661 は ESP32 の分析プログラムを起動してからの   秒数:マイクロ秒 で表しています。

プログラムは20マイクロ秒ごとにポーリングし、無ければ NULL とし、-- で表現 、あれば16進数で表示しています。


000CAC80:は NULL も1バイトとした、分析ブログラムを起動してからのバイト数カウントです。

# 初期化ルーチン

### HSU wake up condition
```

55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00
```

### SAMConfiguration
```
00 00 FF 03 FD D4 14 01 17 00
```

これは以下のような構成になっています。

|||
|:---:|:---:|
|  00 | プリアンブル |
| 00 FF | スタートコード |
| 03  | パケット長 |
| FD  | パケット長のチェックサム |
| D4 14 01  |  パケット内容 |
| 17 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
|  D4  |  ホストからPN532の命令|
| 14 | 命令:SAMConfiguration |
| 01 | 命令:SAMを利用しないノーマルモード |


### Diagnose
00 00 FF 09 F7 D4 00 00 6C 69 62 6E 66 63 BE 00


|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 09  | パケット長 |
| F7  | パケット長のチェックサム |
| D4 00 00 6C 69 62 6E 66 63 |  パケット内容 |
| BE | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4  |  ホストからPN532の命令|
| 00 | 命令:NumTst = 0x00: Communication Line Test |
| 00 6C 69 62 6E 66 63 | 通信テスト送信データ |


### GetFirmwareVersion

```

00 00 FF 02 FE D4 02 2A 00 
```

これは以下のような構成になっています。

|||
|:---:|:---:|
|  00 | プリアンブル |
| 00 FF | スタートコード |
| 02  | パケット長 |
| FE  | パケット長のチェックサム |
|  D4 02  |  パケット内容 |
| 2A | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
|  D4  |  ホストからPN532の命令|
| 02 | 命令:GetFirmwareVersion |



### SetParameters

```

00 00 FF 03 FD D4 12 14 06 00
```

これは以下のような構成になっています。

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 03  | パケット長 |
| FD  | パケット長のチェックサム |
| D4 12 14  |  パケット内容 |
| 06 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4  |  ホストからPN532の命令|
| 12 | 命令:SetParameters |
| 14 | 命Flags=0x14:Automatic generation of the RATS in case of
ISO/IEC14443-4 PCD mode , Automatic generation of the ATR_RES in
case of target configuration. |

### ReadRegister

```

00 00 FF 0C F4 D4 06 63 02 63 03 63 0D 63 38 63 3D B0 00 
```


これは以下のような構成になっています。

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 0C  | パケット長 |
| F4  | パケット長のチェックサム |
| D4 06 63 02 63 03 63 0D 63 38 63 3D  |  パケット内容 |
| B0 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4 | ホストからPN532の命令|
| 06 | 命令:ReadRegister |
| 63 02 | Defines the transmission data rate and framing during transmission. |
| 63 03 | Defines the reception data rate and framing during receiving. |
| 63 0D | Allows manual fine tuning of the internal receiver. |
| 63 38 | Contain status flags of the receiver, transmitter and Data Mode Detector. |
| 63 3D | Adjustments for bit oriented frames. |

### WriteRegister

```

00 00 FF 08 F8 D4 08 63 02 80 63 03 80 59 00
```

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 08  | パケット長 |
| F8  | パケット長のチェックサム |
| D4 08 63 02 80 63 03 80 |  パケット内容 |
| 59 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4 | ホストからPN532の命令|
| 08 | 命令:WriteRegister |
| 63 02 |Defines the transmission data rate and framing during transmission. |
| 80 | TxSpeed=106kbit/s , the modulation for transmitting data is inverted. , data transmission is ISO/IEC 14443A/MIFARE and Passive Communication
mode 106 kbit/s |
| 63 03 |  Defines the reception data rate and framing during receiving. |
| 80 |  RxSpeed=106kbit/s ,a not valid received data stream (less than 4 bits received) will be ignored. The receiver will remain active. ,   data reception is ISO/IEC 14443A/MIFARE and Passive Communication mode 106 kbit/s|


### RFConfiguration

```

00 00 FF 04 FC D4 32 01 00 F9 00

```

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 04  | パケット長 |
| FC  | パケット長のチェックサム |
| D4 32 01 00 |  パケット内容 |
| F9 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4 | ホストからPN532の命令|
| 32 | 命令:RFConfiguration |
| 01 | CfgItem=0x01:RF field |
| 00 | AutoRFCA is off,RF if off  |



### RFConfiguration

```

00 00 FF 04 FC D4 32 01 01 F8 00 
```

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 04  | パケット長 |
| FC  | パケット長のチェックサム |
| D4 32 01 00 |  パケット内容 |
| F8 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4 | ホストからPN532の命令|
| 32 | 命令:RFConfiguration |
| 01 | CfgItem=0x01:RF field |
| 01 | AutoRFCA is off,RF if on  |


これは先の命令と合わせ、RFをOFF→ONにしているだけですが、ログを見ると2つの命令発行の間に数ミリ秒~数十ミリ秒の間が空いていることがわかります。

### RFConfiguration


```

00 00 FF 06 FA D4 32 05 FF FF FF F8 00
```

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 06  | パケット長 |
| FA  | パケット長のチェックサム |
| D4 32 05 FF FF FF |  パケット内容 |
| F8 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4 | ホストからPN532の命令|
| 32 | 命令:RFConfiguration |
| 05 | CfgItem = 0x05:MaxRetries |
| FF | MxRtyATR=0xFF: try eternally|
| FF | MxRtyPSL=0xFF: try eternally|
| FF | MxRtyPassiveActivation=0xFF:infinitely |


# 終了処理

### ReadRegister

```

 00 00 FF 0E F2 D4 06 63 02 63 03 63 05 63 38 63 3C 63 3D 19 00
```


これは以下のような構成になっています。

これは以下のような構成になっています。

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 0E  | パケット長 |
| F2  | パケット長のチェックサム |
| D4 06 63 02 63 03 63 05 63 38 63 3C 63 3D  |  パケット内容 |
| 19 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4 | ホストからPN532の命令|
| 06 | 命令:ReadRegister |
| 63 02 | Defines the transmission data rate and framing during transmission. |
| 63 03 | Defines the reception data rate and framing during receiving. |
| 63 05 | Controls the setting of the antenna driver. |
| 63 38 | Contain status flags of the receiver, transmitter and Data Mode Detector. |
| 63 3C | Contains miscellaneous control bits. |
| 63 3D | Adjustments for bit oriented frames. |




### WriteRegister


00 00 FF 08 F8 D4 08 63 05 40 63 3C 10 CD 00

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 08  | パケット長 |
| F8  | パケット長のチェックサム |
| D4 08 63 05 40 63 3C 10  |  パケット内容 |
| CD | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4  |  ホストからPN532の命令|
| 08 | 命令:WriteRegister |
| 63 05 | Controls the settings of the antenna driver |
| 40 | Force100ASK forces a 100% ASK modulation independent of
the setting in CIU_ModGsP register. |
| 63 3C | Contains miscellaneous control bits. |
| 10 | the PN532 acts as Initiator or Reader/Writer, otherwise it acts as Target. or a Card. |


### InRelease

00 00 FF 03 FD D4 52 00 DA 00 


|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 03  | パケット長 |
| FD  | パケット長のチェックサム |
| D4 52 00  |  パケット内容 |
| DA | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4  |  ホストからPN532の命令|
| 52 | 命令:InRelease |
| 00 | すべてのターゲット |

### RFConfiguration

00 00 FF 04 FC D4 32 01 00 F9 00

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 04 | パケット長 |
| FC  | パケット長のチェックサム |
| D4 32 01 00  |  パケット内容 |
| F9 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4  |  ホストからPN532の命令|
| 32 | 命令:RFConfiguration |
| 01 | CfgItem = 0x01:RF field |
| 00 | AutoRFCA is off,RF if off |

### PowerDown

00 00 FF 03 FD D4 16 F0 26 00

|||
|:---:|:---:|
| 00 | プリアンブル |
| 00 FF | スタートコード |
| 03 | パケット長 |
| FD  | パケット長のチェックサム |
| D4 16 F0  |  パケット内容 |
| 26 | パケット内容のチェックサム |
| 00 | ポストアンブル |

となり、パケット内容は以下の構成になっています。

|パケット内容|意味|
|:---:|:---:|
| D4  |  ホストからPN532の命令|
| 16 | 命令:PowerDown |
| F0 | WakeUpEnable parameter=0xF0:I2C,GPIO,SPI,HSU selected|