M avr-i2c.ads +2 -2
@@ 47,8 47,8 @@ package AVR.I2C is
type I2C_Address is new Nat8 range 0 .. 127;
- subtype Buffer_Index is Nat8 range 0 .. 64;
- subtype Buffer_Range is Nat8 range 1 .. 64;
+ subtype Buffer_Index is Nat8 range 0 .. 81;
+ subtype Buffer_Range is Nat8 range 1 .. 81;
type Data_Buffer is array (Buffer_Range range <>) of Nat8;
end AVR.I2C;
M generic_pn532.adb +24 -10
@@ 115,7 115,7 @@ package body Generic_PN532 is
20, -- timeout (50 * 20) ms
1);
Status : Boolean;
- Reply : PN532_Buf (1..1) := (1 => 0);
+ Reply : PN532_Buf (1..5);
Len : Unsigned_8;
begin
Status := PN532_Send_Command (Cmd, PN532_TIMEOUT_VALUE);
@@ 125,7 125,6 @@ package body Generic_PN532 is
Status := PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE);
if not Status then
- Log ("timeout2");
return False;
end if;
@@ 336,23 335,23 @@ package body Generic_PN532 is
end if;
if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE) then
- Log ("timeout");
+ -- Log ("timeout");
Status := False;
return;
end if;
PN532_Read_Data (Reply, Reply_Len, Ok);
- Log ("Reply:");
- Log (Reply (1..Reply_Len));
+ -- Log ("Reply:");
+ -- Log (Reply (1..Reply_Len));
if (not Ok) or (Reply_Len < 3) then
- Log ("Read data failed");
+ -- Log ("Read data failed");
Status := False;
return;
end if;
if Reply (2) = 16#14# then -- Mifare authentication error
- Log ("Mifare auth error");
+ -- Log ("Mifare auth error");
Status := False;
return;
elsif Reply (2) /= 0 then -- status code not ok?
@@ 387,17 386,20 @@ package body Generic_PN532 is
return False;
end if;
- if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE) then
+ if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE * 30) then
+ -- Log ("select: PN532_Wait_For_Ready failed");
return False;
end if;
PN532_Read_Data (Data, Reply_Len, Ok);
if (not Ok) or (Reply_Len < 5) then
+ -- Log ("select: PN532_Read_Data failed");
return False;
end if;
if Data (2) /= 0 then -- status code not ok?
+ Log ("select: PN532_Read_Data - status code invalid");
return False;
end if;
@@ 406,7 408,11 @@ package body Generic_PN532 is
return True;
elsif Data (Reply_Len - 2) = 16#6A# and Data (Reply_Len - 1) = 16#82# then
-- application not found
+ Log ("select: application not found");
null;
+ else
+ Log ("select: unknown status");
+ Log (Data (1..Reply_Len));
end if;
return False;
@@ 473,7 479,7 @@ package body Generic_PN532 is
Cmd : PN532_Buf (1..7);
Len : Unsigned_8;
Reply : PN532_Buf (1..70);
- Reply_Len : Unsigned_8;
+ Reply_Len : Unsigned_8 := 0;
Ok : Boolean;
begin
Len := Buf'Length;
@@ 494,7 500,8 @@ package body Generic_PN532 is
return;
end if;
- if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE) then
+ if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE * 30) then
+ Log ("read binary: timeout");
Status := False;
return;
end if;
@@ 502,11 509,16 @@ package body Generic_PN532 is
PN532_Read_Data (Reply, Reply_Len, Ok);
if (not Ok) or (Reply_Len < 5) then
+ if not Ok then
+ Log ("read binary: not ok");
+ end if;
+ Log (Reply (1..Reply_Len));
Status := False;
return;
end if;
if Reply (2) /= 0 then -- status code not ok?
+ Log ("status invalid");
Status := False;
return;
end if;
@@ 520,6 532,8 @@ package body Generic_PN532 is
Status := True;
else
Status := False;
+ -- Log ("read binary: reply invalid");
+ Log (Reply (1..Reply_Len));
-- AVR.UART.Put ("Read failed"); AVR.UART.CRLF;
end if;
end PN532_NFC_Forum_Type_4_Read_Binary;
M ndef.adb +91 -0
@@ 77,4 77,95 @@ package body NDEF is
Found := False;
Location := Pos;
end Find_NDEF_TLV;
+
+-- type NDEF_Record is record
+-- Message_Location : NDEF_Message_Location;
+-- Chunked : Boolean;
+-- Short_Record : Boolean;
+-- ID_Length_Present : Boolean;
+-- TNF : Type_Name_Format;
+-- Payload_Offset : Interfaces.Unsigned_8;
+-- Payload_Length : Interfaces.Unsigned_8;
+-- end record;
+
+ -- Parse the NDEF record from the data
+ -- Header format:
+ -- MB|ME|CF|SR|IL|TNF
+ -- Type Length
+ -- Payload len 4
+ -- Payload len 3
+ -- Payload len 2
+ -- Payload len 1
+ -- ID Len
+ -- Type
+ -- ID
+ -- Payload
+ procedure Read_NDEF_Record (Data : NDEF_Array;
+ Start : Interfaces.Unsigned_8;
+ NDEF_Header : out NDEF_Record;
+ Status : out Boolean)
+ is
+ CF_Mask : constant Unsigned_8 := 2#0010_0000#;
+ SR_Mask : constant Unsigned_8 := 2#0001_0000#;
+ ID_Len_Mask : constant Unsigned_8 := 2#0000_1000#;
+ TNF_Mask : constant Unsigned_8 := 2#0000_0111#;
+
+ Current_Location : Unsigned_8 := Start;
+ Type_Len : Unsigned_8;
+ ID_Len : Unsigned_8 := 0;
+ begin
+ if Start > Data'Last then
+ Status := False;
+ return;
+ end if;
+
+ declare
+ Header_Bits : constant Unsigned_8 := Data (Current_Location);
+ begin
+ NDEF_Header.Chunked := (Header_Bits and CF_Mask) = CF_Mask;
+ NDEF_Header.Short_Record := (Header_Bits and SR_Mask) = SR_Mask;
+ NDEF_Header.ID_Length_Present := (Header_Bits and ID_Len_Mask) = ID_Len_Mask;
+ NDEF_Header.TNF := To_TNF (ID_Len_Mask and TNF_Mask);
+ end;
+ Current_Location := Current_Location + 1;
+
+ -- Read Type length
+ Type_Len := Data (Current_Location);
+ Current_Location := Current_Location + 1;
+
+ -- Read Payload length
+ if NDEF_Header.Short_Record then
+ NDEF_Header.Payload_Length := Data (Current_Location);
+ else
+ -- Long payload length not supported (not enough memory)
+ Status := False;
+ return;
+ end if;
+ Current_Location := Current_Location + 1;
+
+ -- ID Length
+ if NDEF_Header.ID_Length_Present then
+ ID_Len := Data (Current_Location);
+ Current_Location := Current_Location + 1;
+ else
+ ID_Len := 0;
+ end if;
+
+ -- Type
+ if Type_Len > 1 then -- types longer than 1 byte not supported
+ Status := False;
+ return;
+ else
+ NDEF_Header.NDEF_Type := Data (Current_Location);
+ end if;
+ Current_Location := Current_Location + 1;
+
+ -- ID, skip it
+ Current_Location := Current_Location + ID_Len;
+
+ NDEF_Header.Payload_Offset := Current_Location;
+
+ Status := True;
+ return;
+ end Read_NDEF_Record;
end NDEF;
M ndef.ads +6 -0
@@ 52,6 52,7 @@ package NDEF is
Short_Record : Boolean;
ID_Length_Present : Boolean;
TNF : Type_Name_Format;
+ NDEF_Type : Interfaces.Unsigned_8;
Payload_Offset : Interfaces.Unsigned_8;
Payload_Length : Interfaces.Unsigned_8;
end record;
@@ 61,4 62,9 @@ package NDEF is
Location : out Interfaces.Unsigned_8;
TLV_Len : out Interfaces.Unsigned_8;
Found : out Boolean);
+
+ procedure Read_NDEF_Record (Data : NDEF_Array;
+ Start : Interfaces.Unsigned_8;
+ NDEF_Header : out NDEF_Record;
+ Status : out Boolean);
end NDEF;
M nfc_tags.adb +34 -16
@@ 18,7 18,7 @@
with System;
with PM_Strings;
with NDEF;
-with PN532_BUS_SPI;
+with PN532_BUS_I2C;
with Generic_PN532;
with AVR.UART;
with AVR.Interrupts;
@@ 32,20 32,20 @@ package body NFC_Tags is
use Interfaces;
use PN532_Types;
+-- package PN532 is new Generic_PN532
+-- (PN532_Init => PN532_BUS_SPI.PN532_Init,
+-- PN532_Busy => PN532_BUS_SPI.PN532_Busy,
+-- PN532_Write => PN532_BUS_SPI.PN532_Write,
+-- PN532_Read_Reply => PN532_BUS_SPI.PN532_Read_Reply,
+-- PN532_Read_Raw => PN532_BUS_SPI.PN532_Read_Raw,
+-- PN532_Read_Data => PN532_BUS_SPI.PN532_Read_Data);
package PN532 is new Generic_PN532
- (PN532_Init => PN532_BUS_SPI.PN532_Init,
- PN532_Busy => PN532_BUS_SPI.PN532_Busy,
- PN532_Write => PN532_BUS_SPI.PN532_Write,
- PN532_Read_Reply => PN532_BUS_SPI.PN532_Read_Reply,
- PN532_Read_Raw => PN532_BUS_SPI.PN532_Read_Raw,
- PN532_Read_Data => PN532_BUS_SPI.PN532_Read_Data);
--- package PN532 is new Generic_PN532
--- (PN532_Init => PN532_BUS_I2C.PN532_Init,
--- PN532_Busy => PN532_BUS_I2C.PN532_Busy,
--- PN532_Write => PN532_BUS_I2C.PN532_Write,
--- PN532_Read_Reply => PN532_BUS_I2C.PN532_Read_Reply,
--- PN532_Read_Raw => PN532_BUS_I2C.PN532_Read_Raw,
--- PN532_Read_Data => PN532_BUS_I2C.PN532_Read_Data);
+ (PN532_Init => PN532_BUS_I2C.PN532_Init,
+ PN532_Busy => PN532_BUS_I2C.PN532_Busy,
+ PN532_Write => PN532_BUS_I2C.PN532_Write,
+ PN532_Read_Reply => PN532_BUS_I2C.PN532_Read_Reply,
+ PN532_Read_Raw => PN532_BUS_I2C.PN532_Read_Raw,
+ PN532_Read_Data => PN532_BUS_I2C.PN532_Read_Data);
procedure Print_Str (Place : System.Address);
@@ 130,8 130,6 @@ package body NFC_Tags is
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)
@@ 276,6 274,7 @@ package body NFC_Tags is
Len : Unsigned_8;
NDEF_ID : Unsigned_16;
NDEF_Len : Unsigned_16;
+ NDEF_Header : NDEF.NDEF_Record;
begin
if not PN532.PN532_NFC_Forum_Type_4_Select_Application then
Print_Str (PM_Strings.Type_4_Tag_Failed_PM'Address); AVR.UART.CRLF;
@@ 332,6 331,20 @@ package body NFC_Tags is
AVR.UART.Put (" ");
end loop;
AVR.UART.CRLF;
+
+ -- Read first record
+ NDEF.Read_NDEF_Record (NDEF.NDEF_Array (NFC_Data), 3, NDEF_Header, Status);
+ if Status then
+ AVR.UART.Put ("NDEF record at ");
+ AVR.UART.Put (Data => NDEF_Header.Payload_Offset, Base => 10);
+ AVR.UART.CRLF;
+ AVR.UART.Put ("NDEF type: ");
+ AVR.UART.Put (Data => NDEF_Header.NDEF_Type, Base => 16);
+ AVR.UART.CRLF;
+ else
+ AVR.UART.Put ("Failed to parse NDEF record");
+ AVR.UART.CRLF;
+ end if;
end Read_Forum_Type_4_Tag;
procedure Update_Forum_Type_4_Tag (New_Content : PN532_Buf)
@@ 438,6 451,10 @@ package body NFC_Tags is
(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;
+ elsif Sel_Res = 16#28# and Sens_Res = 16#4400# then -- Yubikey NEO
+ -- Read_Mifare_Classic_Tag
+ -- (NFC_ID (NFC_ID'First..NFC_ID'First + NFC_ID_Len - 1));
+ Read_Forum_Type_4_Tag;
else
AVR.UART.Put ("Unknown tag detected: ");
AVR.UART.Put (Sel_Res, 16);
@@ 576,6 593,7 @@ package body NFC_Tags is
AVR.UART.CRLF;
-- AVR.UART.Put ("No reader detected, exiting");
-- AVR.UART.CRLF;
+ Counter := 0;
end if;
end loop;
Print_Str (PM_Strings.Emulation_Over_PM'Address);
M pn532_bus_i2c.adb +26 -2
@@ 3,6 3,8 @@ with AVR.MCU;
with AVR.I2C;
with AVR.I2C.Master;
+with AVR.UART;
+
package body PN532_BUS_I2C is
use AVR;
@@ 137,7 139,8 @@ package body PN532_BUS_I2C is
Msg_Len : Unsigned_8;
Ready_Status : Unsigned_8;
begin
- AVR.I2C.Master.Request (PN532_I2C_ADDRESS, 60);
+ AVR.I2C.Master.Request (PN532_I2C_ADDRESS, 80);
+
loop
exit when AVR.I2C.Master.Data_Is_Available;
end loop;
@@ 150,17 153,24 @@ package body PN532_BUS_I2C is
if not (Header (2) = 0 and Header (3) = 16#FF#) then
-- invalid header
Status := False;
+
+ -- AVR.UART.Put("inv. head"); AVR.UART.CRLF;
return;
end if;
Msg_Len := Header (4);
if Msg_Len + Header (5) /= 0 then
Status := False;
+ -- AVR.UART.Put("inv. head len crc"); AVR.UART.CRLF;
return;
end if;
Checksum := Checksum + Header (6);
+ if Buf'Length < Msg_Len then
+ AVR.UART.Put ("Buffer too small");
+ AVR.UART.CRLF;
+ end if;
Msg_Len := Unsigned_8'Min (Buf'Length, Msg_Len);
for I in Unsigned_8 range 1 .. Msg_Len loop
@@ 173,7 183,21 @@ package body PN532_BUS_I2C is
Header (1) := not Header (1);
if Checksum /= Header (1) then
- -- Log ("PN532_Read_Data: Invalid checksum");
+-- -- Log ("PN532_Read_Data: Invalid checksum");
+-- AVR.UART.Put("inv. head crc"); AVR.UART.CRLF;
+--
+-- AVR.UART.Put ("Msg_Len: ");
+-- AVR.UART.Put (Data => Msg_Len, Base => 10);
+-- AVR.UART.CRLF;
+-- AVR.UART.Put ("Buf'Length: ");
+-- AVR.UART.Put (Data => Unsigned_8 (Buf'Length), Base => 10);
+-- AVR.UART.CRLF;
+--
+-- for I in Unsigned_8 range 1 .. Msg_Len loop
+-- AVR.UART.Put (Data => Buf (I), Base => 16);
+-- AVR.UART.Put (" ");
+-- end loop;
+-- AVR.UART.CRLF;
Status := False;
else
Status := True;