@@ 30,6 30,91 @@ package body NFC_Main is
procedure Print_Str (Place : System.Address);
+ procedure Read_Mifare_Classic_Tag (NFC_ID : PN532.PN532_Buf) is
+ Status : Boolean;
+ Key_A : PN532.PN532_Buf_6 := (255, 255, 255, 255, 255, 255);
+ MAD_Key_A : PN532.PN532_Buf_6 :=
+ (16#A0#, 16#A1#, 16#A2#, 16#A3#, 16#A4#, 16#A5#);
+ Key_B : PN532.PN532_Buf_6 := (255, 255, 255, 255, 255, 255);
+ Data : PN532.PN532_Buf (1 .. 16);
+ NFC_Data : PN532.PN532_Buf (1 .. 48);
+ Len : Unsigned_8;
+ begin
+ AVR.UART.Put ("UID len: ");
+ AVR.UART.Put (Unsigned_8 (NFC_ID'Length), 10);
+ AVR.UART.CRLF;
+ PN532.PN532_Authenticate_Mifare_Classic_Tag_Block
+ (Block_Number => 0,
+ UID => NFC_ID,
+ Key => PN532.AUTH_A,
+ Key_Data => MAD_Key_A,
+ Status => Status);
+ if Status then
+ AVR.UART.Put ("Classic tag auth OK");
+ AVR.UART.CRLF;
+ else
+ AVR.UART.Put ("Classic tag auth FAILED");
+ AVR.UART.CRLF;
+ end if;
+
+ if False then
+ PN532.PN532_Read_NFC_Forum_Type_2_Tag_Block
+ (Block => 0,
+ Buf => Data,
+ Byte_Count => Len,
+ Status => Status);
+ if Status then
+ AVR.UART.Put ("BLOCK 00: ");
+ for I in Unsigned_8 range 1 .. Len loop
+ AVR.UART.Put (Data => Data (I), Base => 16);
+ AVR.UART.Put (" ");
+ end loop;
+ AVR.UART.CRLF;
+ else
+ AVR.UART.Put ("Read failed");
+ AVR.UART.CRLF;
+ end if;
+ end if;
+ for B in Unsigned_8 range 0 .. 7 loop
+
+ if B mod 4 = 0 and B > 0 then
+ PN532.PN532_Authenticate_Mifare_Classic_Tag_Block
+ (Block_Number => B,
+ UID => NFC_ID,
+ Key => PN532.AUTH_B,
+ Key_Data => Key_B,
+ Status => Status);
+ end if;
+ PN532.PN532_Read_NFC_Forum_Type_2_Tag_Block
+ (Block => B, -- (B + 1)*4,
+ Buf => Data,
+ Byte_Count => Len,
+ Status => Status);
+ if not Status then
+ AVR.UART.Put ("Failed to read block ");
+ AVR.UART.Put (Data => B, Base => 16);
+ AVR.UART.CRLF;
+ exit;
+ end if;
+ if B*16 + 16 < NFC_Data'Last then
+ NFC_Data (B*16 + 1 .. B*16 +16) := Data;
+ end if;
+
+ AVR.UART.Put ("BLOCK ");
+ AVR.UART.Put (Data => B, Base => 16);
+ AVR.UART.Put (" from "); AVR.UART.Put (B*16 +1, Base => 10);
+ AVR.UART.Put (" to "); AVR.UART.Put (B*16 + 16, Base => 10);
+ AVR.UART.Put (": ");
+ for I in Unsigned_8 range 1 .. Len loop
+ AVR.UART.Put (Data => Data (I), Base => 16);
+ AVR.UART.Put (" ");
+ end loop;
+ AVR.UART.CRLF;
+ end loop;
+
+
+ end Read_Mifare_Classic_Tag;
+
-- Read NFC Forum type 2 tag (like NXP Mifare Ultralight or NXP NTAG)
--
-- First 4 blocks are special */
@@ 302,6 387,8 @@ package body NFC_Main is
procedure Read_Tag is
Sel_Res : Unsigned_8;
Sens_Res : Unsigned_16;
+ NFC_ID : PN532.PN532_Buf (1..16);
+ NFC_ID_Len : Unsigned_8;
Status : Boolean;
begin
AVR.UART.Put ("Reading NFC tag");
@@ 312,16 399,31 @@ package body NFC_Main is
loop
PN532.PN532_Detect_Tag (Sens_Res => Sens_Res,
Sel_Res => Sel_Res,
+ NFC_ID => NFC_ID,
+ NFC_ID_Len => NFC_ID_Len,
Status => Status);
if Status then
-- NFC Forum type 2 tag
if Sel_Res = 16#00# and Sens_Res = 16#4400# then
Read_Forum_Type_2_Tag;
-- NFC Forum type 4 tag
+ elsif Sel_Res = 16#08# and Sens_Res = 16#0400# then
+ AVR.UART.Put ("Mifare classic tag MF1S503");
+ AVR.UART.CRLF;
+ Read_Mifare_Classic_Tag
+ (NFC_ID (NFC_ID'First..NFC_ID'First + NFC_ID_Len - 1));
+ elsif Sel_Res = 16#08# and Sens_Res = 16#4400# then
+ AVR.UART.Put ("Mifare classic tag MF1S500");
+ AVR.UART.CRLF;
+ Read_Mifare_Classic_Tag
+ (NFC_ID (NFC_ID'First..NFC_ID'First + NFC_ID_Len - 1));
elsif Sel_Res = 16#20# and Sens_Res = 16#4403# then
Read_Forum_Type_4_Tag;
else
- AVR.UART.Put ("Unknown tag detected");
+ AVR.UART.Put ("Unknown tag detected: ");
+ AVR.UART.Put (Sel_Res, 16);
+ AVR.UART.Put (" ");
+ AVR.UART.Put (Sens_Res, 16);
AVR.UART.CRLF;
end if;
@@ 352,6 454,8 @@ package body NFC_Main is
Ch : Character;
Len : Unsigned_8 := 0;
My_String : PN532.PN532_Buf (1..8);
+ NFC_ID : PN532.PN532_Buf (1..7);
+ NFC_ID_Len : Unsigned_8;
Sel_Res : Unsigned_8;
Sens_Res : Unsigned_16;
Status : Boolean;
@@ 387,6 491,8 @@ package body NFC_Main is
loop
PN532.PN532_Detect_Tag (Sens_Res => Sens_Res,
Sel_Res => Sel_Res,
+ NFC_ID => NFC_ID,
+ NFC_ID_Len => NFC_ID_Len,
Status => Status);
if Status then
-- NFC Forum type 2 tag
@@ 333,6 333,8 @@ package body PN532 is
procedure PN532_Detect_Tag
(Sens_Res : out Unsigned_16;
Sel_Res : out Unsigned_8;
+ NFC_ID : out PN532_Buf;
+ NFC_ID_Len : out Unsigned_8;
Status : out Boolean)
is
Cmd : PN532_Buf (1..3) :=
@@ 372,6 374,12 @@ package body PN532 is
Sens_Res := Unsigned_16 (Reply (5)) * 256 or Unsigned_16 (Reply (4));
Sel_Res := Reply (6);
+ NFC_ID_Len := Reply (7);
+ if NFC_ID_Len > NFC_ID'Length then
+ NFC_ID_Len := NFC_ID'Length;
+ end if;
+ NFC_ID := Reply (8..7 + NFC_ID_Len);
+
Status := Ok;
end PN532_Detect_Tag;
@@ 486,30 494,41 @@ package body PN532 is
Cmd (4) := Unsigned_8 (Block_Number);
Cmd (5..4 + Key_Data'Length) := Key_Data;
if UID'Length > 10 then
+ Log ("UID too big");
Status := False;
return;
end if;
Cmd (11..10 + UID'Length) := UID;
- Ok := PN532_Send_Command (Cmd, PN532_TIMEOUT_VALUE);
+ Log (Cmd (1..10+UID'Length));
+ Ok := PN532_Send_Command (Cmd (1..10+UID'Length), PN532_TIMEOUT_VALUE);
if not Ok then
+ Log ("Send command failed");
Status := False;
return;
end if;
if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE) then
+ Log ("timeout");
Status := False;
return;
end if;
PN532_Read_Data (Reply, Reply_Len, Ok);
+ Log ("Reply:");
+ Log (Reply (1..Reply_Len));
if (not Ok) or (Reply_Len < 3) then
+ Log ("Read data failed");
Status := False;
return;
end if;
- if Reply (2) /= 0 then -- status code not ok?
+ if Reply (2) = 16#14# then -- Mifare authentication error
+ Log ("Mifare auth error");
+ Status := False;
+ return;
+ elsif Reply (2) /= 0 then -- status code not ok?
Status := False;
return;
end if;