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 .. 81;
- subtype Buffer_Range is Nat8 range 1 .. 81;
+ subtype Buffer_Index is Nat8 range 0 .. 90;
+ subtype Buffer_Range is Nat8 range 1 .. 90;
type Data_Buffer is array (Buffer_Range range <>) of Nat8;
end AVR.I2C;
M generic_pn532.adb +28 -37
@@ 28,6 28,8 @@ use Interfaces;
package body Generic_PN532 is
+ Data_Buffer : PN532_Buf (1..90);
+
PN532_FIRMWARE_VERSION : constant := 16#02#;
PN532_SAMCONFIG : constant := 16#14#;
PN532_IN_LIST_PASSIVE_TARGET : constant := 16#4A#;
@@ 219,7 221,7 @@ package body Generic_PN532 is
1, -- card number
MIFARE_READ_CARD_CMD,
0); -- Block number
- Reply : PN532_Buf (1..40);
+ -- Reply : PN532_Buf (1..40);
Reply_Len : Unsigned_8;
Len : Unsigned_8;
Ok : Boolean;
@@ 237,21 239,21 @@ package body Generic_PN532 is
return;
end if;
- PN532_Read_Data (Reply, Reply_Len, Ok);
+ PN532_Read_Data (Data_Buffer, Reply_Len, Ok);
if (not Ok) or (Reply_Len < 3) then
Status := False;
return;
end if;
- if Reply (2) /= 0 then -- status code not ok?
+ if Data_Buffer (2) /= 0 then -- status code not ok?
Status := False;
return;
end if;
Len := Unsigned_8'Min (Reply_Len - 3, Buf'Length);
Byte_Count := Len;
- Buf (1..Len) := Reply (3 .. Len + 2);
+ Buf (1..Len) := Data_Buffer (3 .. Len + 2);
Status := True;
end PN532_Read_NFC_Forum_Type_2_Tag_Block;
@@ 432,7 434,7 @@ package body Generic_PN532 is
16#0C#, -- first or only occurrence
16#02#, -- two bytes data
Unsigned_8 (File_ID / 256), Unsigned_8 (File_ID and 16#FF#));
- Reply : PN532_Buf (1..40);
+
Reply_Len : Unsigned_8;
Ok : Boolean;
begin
@@ 445,21 447,21 @@ package body Generic_PN532 is
return False;
end if;
- PN532_Read_Data (Reply, Reply_Len, Ok);
+ PN532_Read_Data (Data_Buffer, Reply_Len, Ok);
if (not Ok) or (Reply_Len < 5) then
return False;
end if;
- if Reply (2) /= 0 then -- status code not ok?
+ if Data_Buffer (2) /= 0 then -- status code not ok?
return False;
end if;
- if Reply (Reply_Len - 2) = 16#90# and Reply (Reply_Len - 1) = 16#00# then
+ if Data_Buffer (Reply_Len - 2) = 16#90# and Data_Buffer (Reply_Len - 1) = 16#00# then
-- ok
return True;
- elsif Reply (Reply_Len - 2) = 16#6A#
- and Reply (Reply_Len - 1) = 16#82#
+ elsif Data_Buffer (Reply_Len - 2) = 16#6A#
+ and Data_Buffer (Reply_Len - 1) = 16#82#
then -- file not found
return False;
end if;
@@ 476,64 478,54 @@ package body Generic_PN532 is
Byte_Count : out Unsigned_8;
Status : out Boolean)
is
- Cmd : PN532_Buf (1..7);
+ -- Data : PN532_Buf (1..90);
Len : Unsigned_8;
- Reply : PN532_Buf (1..70);
+ -- Reply : PN532_Buf (1..90);
Reply_Len : Unsigned_8 := 0;
Ok : Boolean;
begin
- Len := Buf'Length;
- if Len > Reply'Length then
- Len := Reply'Length;
- end if;
- Cmd (1) := PN532_IN_DATA_EXCHANGE;
- Cmd (2) := 1; -- card number
- Cmd (3) := 16#00#; -- class
- Cmd (4) := 16#B0#; -- instruction
- Cmd (5) := Unsigned_8 (Offset and 16#FF#);
- Cmd (6) := Unsigned_8 (Offset / 256);
- Cmd (7) := Len;
+ Len := Unsigned_8'Min (Buf'Length, Data_Buffer'Length);
+
+ Data_Buffer (1) := PN532_IN_DATA_EXCHANGE;
+ Data_Buffer (2) := 1; -- card number
+ Data_Buffer (3) := 16#00#; -- class
+ Data_Buffer (4) := 16#B0#; -- instruction
+ Data_Buffer (5) := Unsigned_8 (Offset and 16#FF#);
+ Data_Buffer (6) := Unsigned_8 (Offset / 256);
+ Data_Buffer (7) := Len;
- Ok := PN532_Send_Command (Cmd, PN532_TIMEOUT_VALUE);
+ Ok := PN532_Send_Command (Data_Buffer (1..7), PN532_TIMEOUT_VALUE);
if not Ok then
Status := False;
return;
end if;
if not PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE * 30) then
- Log ("read binary: timeout");
Status := False;
return;
end if;
- PN532_Read_Data (Reply, Reply_Len, Ok);
+ PN532_Read_Data (Data_Buffer, 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");
+ if Data_Buffer (2) /= 0 then -- status code not ok?
Status := False;
return;
end if;
- if Reply (Reply_Len - 2) = 16#90# and Reply (Reply_Len - 1) = 16#00# then
+ if Data_Buffer (Reply_Len - 2) = 16#90# and Data_Buffer (Reply_Len - 1) = 16#00# then
-- ok, copying buffer
Len := Reply_Len - 5;
- Buf (Buf'First .. Buf'First + Len) := Reply (3 .. 3 + Len);
+ Buf (Buf'First .. Buf'First + Len) := Data_Buffer (3 .. 3 + Len);
Byte_Count := Len;
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;
@@ 609,7 601,6 @@ package body Generic_PN532 is
Reply_Len : Unsigned_8;
begin
if Buf'Length + Buf2'Length >= Cmd'Length - 2 then
- -- Log ("PN532_Set_Data: Buf too big");
return False;
end if;
M ndef.adb +13 -13
@@ 77,7 77,7 @@ package body NDEF is
Found := False;
Location := Pos;
end Find_NDEF_TLV;
-
+
-- type NDEF_Record is record
-- Message_Location : NDEF_Message_Location;
-- Chunked : Boolean;
@@ 87,12 87,12 @@ package body NDEF is
-- 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 4
-- Payload len 3
-- Payload len 2
-- Payload len 1
@@ 109,7 109,7 @@ package body NDEF is
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;
@@ 118,21 118,21 @@ package body NDEF is
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);
+ NDEF_Header.TNF := To_TNF (Header_Bits 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);
@@ 142,7 142,7 @@ package body NDEF is
return;
end if;
Current_Location := Current_Location + 1;
-
+
-- ID Length
if NDEF_Header.ID_Length_Present then
ID_Len := Data (Current_Location);
@@ 150,7 150,7 @@ package body NDEF is
else
ID_Len := 0;
end if;
-
+
-- Type
if Type_Len > 1 then -- types longer than 1 byte not supported
Status := False;
@@ 159,12 159,12 @@ package body NDEF is
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;
M ndef.ads +3 -1
@@ 45,6 45,8 @@ package NDEF is
TNF_RESERVED => 7);
function To_TNF is
new Ada.Unchecked_Conversion (Interfaces.Unsigned_8, Type_Name_Format);
+ function TNF_To_Unsigned_8 is
+ new Ada.Unchecked_Conversion (Type_Name_Format, Interfaces.Unsigned_8);
type NDEF_Record is record
Message_Location : NDEF_Message_Location;
@@ 62,7 64,7 @@ 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;
M nfc_tags.adb +88 -16
@@ 48,6 48,53 @@ package body NFC_Tags is
PN532_Read_Data => PN532_BUS_I2C.PN532_Read_Data);
procedure Print_Str (Place : System.Address);
+
+ procedure Print_NDEF_Record (NFC_Data : PN532_Buf;
+ NDEF_Header : NDEF.NDEF_Record)
+ is
+ use type NDEF.Type_Name_Format;
+
+ Data_End : Unsigned_8;
+ begin
+ Data_End := Unsigned_8'Min
+ (NFC_Data'Last,
+ NDEF_Header.Payload_Offset + NDEF_Header.Payload_Length - 1);
+ if Data_End < NDEF_Header.Payload_Offset + NDEF_Header.Payload_Length - 1 then
+ AVR.UART.Put ("Note: printing truncated");
+ AVR.UART.CRLF;
+ AVR.UART.Put (Data_End, 10);
+ AVR.UART.CRLF;
+ AVR.UART.Put (NDEF_Header.Payload_Offset + NDEF_Header.Payload_Length - 1, 10);
+ AVR.UART.CRLF;
+ end if;
+
+ AVR.UART.Put ("TNF: ");
+ AVR.UART.Put (Data => NDEF.TNF_To_Unsigned_8 (NDEF_Header.TNF), Base => 16);
+ AVR.UART.CRLF;
+ 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;
+ AVR.UART.Put ("NDEF Payload length: ");
+ AVR.UART.Put (Data => NDEF_Header.Payload_Length, Base => 10);
+ AVR.UART.CRLF;
+
+ if NDEF_Header.TNF = NDEF.TNF_WELL_KNOWN then
+ if NDEF_Header.NDEF_Type = Character'Pos ('U') then
+ if NFC_Data (NDEF_Header.Payload_Offset) = 1 then -- https
+ AVR.UART.Put ("http://");
+ elsif NFC_Data (NDEF_Header.Payload_Offset) = 4 then -- https
+ AVR.UART.Put ("https://");
+ end if;
+ for I in NDEF_Header.Payload_Offset + 1 .. Data_End loop
+ AVR.UART.Put (Character'Val (NFC_Data (I)));
+ end loop;
+ AVR.UART.CRLF;
+ end if;
+ end if;
+ end Print_NDEF_Record;
procedure Read_Mifare_Classic_Tag (NFC_ID : PN532_Buf) is
Status : Boolean;
@@ 59,9 106,9 @@ package body NFC_Tags is
NFC_Data : 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;
+-- 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,
@@ 119,7 166,7 @@ package body NFC_Tags is
NFC_Data (B*16 + 1 .. B*16 +16) := Data;
end if;
- AVR.UART.Put ("BLOCK ");
+ Print_Str(PM_Strings.BLOCK_PM'Address);
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);
@@ 149,6 196,7 @@ package body NFC_Tags is
Data : PN532_Buf (1 .. 16);
NFC_Data : PN532_Buf (1 .. 48);
NDEF_Loc : Unsigned_8 := 0;
+ NDEF_Header : NDEF.NDEF_Record;
begin
Print_Str (PM_Strings.Type_2_Tag_PM'Address); AVR.UART.CRLF;
PN532.PN532_Read_NFC_Forum_Type_2_Tag_Block
@@ 172,8 220,7 @@ package body NFC_Tags is
AVR.UART.Put (" bytes"); AVR.UART.CRLF;
if Card_Block_Count > 50 then
- AVR.UART.Put ("Reading first 50 blocks");
- AVR.UART.CRLF;
+ -- Reading only the first 50 blocks
Card_Block_Count := 50;
end if;
@@ 194,7 241,7 @@ package body NFC_Tags is
NFC_Data (B*16 + 1 .. B*16 +16) := Data;
end if;
- AVR.UART.Put ("BLOCK ");
+ Print_Str (PM_Strings.BLOCK_PM'Address);
AVR.UART.Put (Data => (B + 1)*4, 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);
@@ 214,6 261,11 @@ package body NFC_Tags is
AVR.UART.Put ("NDEF message at ");
AVR.UART.Put (Data => NDEF_Loc, Base => 10);
AVR.UART.CRLF;
+
+ NDEF.Read_NDEF_Record (NDEF.NDEF_Array (NFC_Data), NDEF_Loc, NDEF_Header, Status);
+ if Status then
+ Print_NDEF_Record (NFC_Data, NDEF_Header);
+ end if;
else
AVR.UART.Put ("No NDEF TLV found");
AVR.UART.CRLF;
@@ 222,7 274,6 @@ package body NFC_Tags is
AVR.UART.Put ("Failed to read block from the tag");
AVR.UART.CRLF;
end if;
-
end Read_Forum_Type_2_Tag;
procedure Write_Forum_Type_2_Tag (Data : PN532_Buf) is
@@ 268,9 319,11 @@ package body NFC_Tags is
end Write_Forum_Type_2_Tag;
procedure Read_Forum_Type_4_Tag is
+ use type NDEF.Type_Name_Format;
+
Status : Boolean;
Data : PN532_Buf (1 .. 16);
- NFC_Data : PN532_Buf (1 .. 64);
+ NFC_Data : PN532_Buf (1 .. 80);
Len : Unsigned_8;
NDEF_ID : Unsigned_16;
NDEF_Len : Unsigned_16;
@@ 331,16 384,35 @@ 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;
+ Print_NDEF_Record (NFC_Data, NDEF_Header);
+-- AVR.UART.Put ("TNF: ");
+-- AVR.UART.Put (Data => NDEF.TNF_To_Unsigned_8 (NDEF_Header.TNF), Base => 16);
+-- AVR.UART.CRLF;
+-- 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;
+-- AVR.UART.Put ("NDEF Payload length: ");
+-- AVR.UART.Put (Data => NDEF_Header.Payload_Length, Base => 10);
+-- AVR.UART.CRLF;
+--
+-- if NDEF_Header.TNF = NDEF.TNF_WELL_KNOWN then
+-- if NDEF_Header.NDEF_Type = Character'Pos ('U') then
+-- if NFC_Data (NDEF_Header.Payload_Offset) = 4 then -- https
+-- AVR.UART.Put ("https://");
+-- end if;
+-- for I in NDEF_Header.Payload_Offset + 1 .. (NDEF_Header.Payload_Offset + NDEF_Header.Payload_Length - 1) loop
+-- AVR.UART.Put (Character'Val (NFC_Data (I)));
+-- end loop;
+-- AVR.UART.CRLF;
+-- end if;
+-- end if;
else
AVR.UART.Put ("Failed to parse NDEF record");
AVR.UART.CRLF;
M pm_strings.ads +3 -0
@@ 38,6 38,7 @@ package PM_Strings is
SAM_Failed_Str : constant AVR.Strings.AVR_String := "SAM config FAILED";
Type_2_Tag_Str : constant AVR.Strings.AVR_String := "NFC Forum Type 2 tag";
Type_4_Tag_Failed_Str : constant AVR.Strings.AVR_String := "Failed to select type 4 tag";
+ BLOCK_Str : constant AVR.Strings.AVR_String := "BLOCK ";
Select_Action_PM : constant Text_In_Progmem := (Select_Action_Str'Length, Select_Action_Str);
Read_NFC_PM : constant Text_In_Progmem := (Read_NFC_Str'Length, Read_NFC_Str);
@@ 54,6 55,7 @@ package PM_Strings is
SAM_Failed_PM : constant Text_In_Progmem := (SAM_Failed_Str'Length, SAM_Failed_Str);
Type_2_Tag_PM : constant Text_In_Progmem := (Type_2_Tag_Str'Length, Type_2_Tag_Str);
Type_4_Tag_Failed_PM : constant Text_In_Progmem := (Type_4_Tag_Failed_Str'Length, Type_4_Tag_Failed_Str);
+ BLOCK_PM : constant Text_In_Progmem := (BLOCK_Str'Length, BLOCK_STR);
pragma Linker_Section (Select_Action_PM, ".progmem");
pragma Linker_Section (Read_NFC_PM, ".progmem");
@@ 70,4 72,5 @@ package PM_Strings is
pragma Linker_Section (SAM_Failed_PM, ".progmem");
pragma Linker_Section (Type_2_Tag_PM, ".progmem");
pragma Linker_Section (Type_4_Tag_Failed_PM, ".progmem");
+ pragma Linker_Section (BLOCK_PM, ".progmem");
end PM_Strings;
M pn532_bus_i2c.adb +1 -1
@@ 139,7 139,7 @@ package body PN532_BUS_I2C is
Msg_Len : Unsigned_8;
Ready_Status : Unsigned_8;
begin
- AVR.I2C.Master.Request (PN532_I2C_ADDRESS, 80);
+ AVR.I2C.Master.Request (PN532_I2C_ADDRESS, AVR.I2C.Buffer_Range'Last);
loop
exit when AVR.I2C.Master.Data_Is_Available;