M nfc_tags.adb +2 -2
@@ 18,7 18,7 @@
with System;
with PM_Strings;
with NDEF;
-with PN532_TWI;
+with PN532;
with AVR.UART;
with AVR.Interrupts;
with Interfaces;
@@ 31,7 31,7 @@ package body NFC_Tags is
use Interfaces;
use PN532_Types;
- package PN532 renames PN532_TWI;
+ -- package PN532 renames PN532_TWI;
procedure Print_Str (Place : System.Address);
M pn532.adb +21 -197
@@ 17,17 17,29 @@
with System;
with Interfaces;
-with SPI;
with AVR.Real_Time.Clock;
pragma Unreferenced(AVR.Real_Time.Clock);
with AVR.UART;
with AVR.Strings;
with AVR.Programspace;
+with PN532_BUS_SPI;
use Interfaces;
package body PN532 is
+ procedure Init renames PN532_BUS_SPI.Init;
+ function PN532_Busy return Boolean renames PN532_BUS_SPI.PN532_Busy;
+ procedure PN532_Write (Cmd : PN532_Buf) renames PN532_BUS_SPI.PN532_Write;
+ procedure PN532_Read_Raw (Buf : out PN532_Buf) renames PN532_BUS_SPI.PN532_Read_Raw;
+ procedure PN532_Read_Data
+ (Buf : out PN532_Buf;
+ Len : out Unsigned_8;
+ Status : out Boolean) renames PN532_BUS_SPI.PN532_Read_Data;
+ procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8)
+ renames PN532_BUS_SPI.PN532_Read_Reply;
+
+
PN532_FIRMWARE_VERSION : constant := 16#02#;
PN532_SAMCONFIG : constant := 16#14#;
PN532_IN_LIST_PASSIVE_TARGET : constant := 16#4A#;
@@ 36,13 48,7 @@ package body PN532 is
PN532_TG_GET_DATA : constant := 16#86#;
PN532_TG_SET_DATA : constant := 16#8E#;
- SPI_STATUS : constant := 2#10#;
- SPI_WRITE : constant := 2#01#;
- SPI_READ : constant := 2#11#;
-
- HOST_TO_PN532 : constant := 16#D4#;
-
- PN532_TIMEOUT_VALUE : constant := 2000;
+ PN532_TIMEOUT_VALUE : constant := 20000;
PN532_106_KBPS_ISOIEC_14443_A : constant := 0;
@@ 51,8 57,6 @@ package body PN532 is
MIFARE_AUTH_KEY_A_CMD : constant := 16#60#;
MIFARE_AUTH_KEY_B_CMD : constant := 16#61#;
- type Reply_Type is (REPLY_ACK, REPLY_NACK, REPLY_ERROR);
-
type Buf_In_Progmem (Len : AVR.Nat8) is record
Text : PN532_Buf (1..Len);
end record;
@@ 77,67 81,6 @@ package body PN532 is
AVR.UART.CRLF;
end Log;
- procedure PN532_Delay is
- begin
- delay 0.002;
- end PN532_Delay;
- pragma Inline (PN532_Delay);
-
- procedure PN532_SPI_Enable is
- begin
- SPI.SS_Out := False;
- end PN532_SPI_Enable;
- pragma Inline (PN532_SPI_Enable);
-
- procedure PN532_SPI_Disable is
- begin
- SPI.SS_Out := True;
- end PN532_SPI_Disable;
- pragma Inline (PN532_SPI_Disable);
-
- procedure PN532_Write (Cmd : PN532_Buf) is
- Checksum : Unsigned_8 := 16#FF#;
- Len : Unsigned_8 := Cmd'Length + 1;
- begin
- PN532_SPI_Enable;
- PN532_Delay;
-
- SPI.Send(SPI_WRITE);
-
- SPI.Send(0);
- SPI.Send(0);
- SPI.Send(16#FF#);
-
- SPI.Send (Len);
- SPI.Send ((not Len) + 1);
-
- SPI.Send(HOST_TO_PN532);
-
- Checksum := Checksum + HOST_TO_PN532;
-
- for I in Cmd'Range loop
- SPI.Send (Cmd (I));
- Checksum := Checksum + Cmd (I);
- end loop;
-
- SPI.Send(not Checksum);
- SPI.Send(0);
-
- PN532_SPI_Disable;
- end PN532_Write;
-
- function PN532_Busy return Boolean is
- Status : Unsigned_8;
- begin
- PN532_SPI_Enable;
- PN532_Delay;
- SPI.Send (SPI_STATUS);
- Status := SPI.Read;
- PN532_SPI_Disable;
-
- return Status /= 1;
- end PN532_Status;
-
function PN532_Wait_For_Ready (Timeout : Unsigned_32) return Boolean is
Counter : Unsigned_32 := 0;
begin
@@ 153,47 96,6 @@ package body PN532 is
return True;
end PN532_Wait_For_Ready;
- procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8) is
- Buf : PN532_Buf (1..6);
- Len : Unsigned_8;
- begin
- PN532_SPI_Enable;
- PN532_Delay;
- SPI.Send (SPI_READ);
- Code := 0;
-
- for I in Buf'Range loop
- Buf (I) := SPI.Read;
- end loop;
-
- if Buf (1) = 0 and Buf (2) = 0 and Buf (3) = 16#FF# then
- if Buf (4) = 0 and Buf (5) = 16#FF# and Buf (6) = 0 then -- ACK
- Reply := REPLY_ACK;
- elsif Buf(4) = 16#FF# and Buf(5) = 0 and Buf (6) = 0 then -- NACK
- Reply := REPLY_NACK;
- else -- ERROR
- Reply := REPLY_ERROR;
- Len := Buf (4);
- if Buf (5) + Len = 0 then -- checksum ok
- Code := Buf (6);
- Buf (1) := SPI.Read;
- Buf (2) := SPI.Read;
- end if;
- end if;
- else
- -- Log ("Unknown reply");
- -- for I in Buf'Range loop
- -- AVR.UART.Put (Data => Buf (I), Base => 16);
- -- AVR.UART.Put (" ");
- -- end loop;
- -- AVR.UART.CRLF;
- Reply := REPLY_ERROR;
- Code := 255;
- end if;
-
- PN532_SPI_Disable;
- end PN532_Read_Reply;
-
function PN532_Send_Command (Cmd : PN532_Buf; Timeout : Unsigned_32)
return Boolean
is
@@ 218,76 120,6 @@ package body PN532 is
return True;
end PN532_Send_Command;
- procedure PN532_Read_Raw (Buf : out PN532_Buf) is
- begin
- PN532_SPI_Enable;
- PN532_Delay;
-
- SPI.Send (SPI_READ);
-
- for I in Buf'Range loop
- Buf (I) := SPI.Read;
- end loop;
-
- PN532_SPI_Disable;
- end PN532_Read_Raw;
-
- procedure PN532_Read_Data
- (Buf : out PN532_Buf;
- Len : out Unsigned_8;
- Status : out Boolean)
- is
- Header : PN532_Buf (1..6);
- Checksum : Unsigned_8 := 16#FF#;
- Msg_Len : Unsigned_8;
- begin
- PN532_SPI_Enable;
- PN532_Delay;
-
- SPI.Send (SPI_READ);
-
- for I in Header'Range loop
- Header (I) := SPI.Read;
- end loop;
-
- if not (Header (2) = 0 and Header (3) = 16#FF#) then
- -- Log ("PN532_Read_Data: Invalid header");
- PN532_SPI_Disable;
- Status := False;
- return;
- end if;
-
- Msg_Len := Header (4);
- if Msg_Len + Header (5) /= 0 then
- PN532_SPI_Disable;
- Status := False;
- -- Log ("PN532_Read_Data: Invalid header len checksum");
- return;
- end if;
-
- Checksum := Checksum + Header (6);
-
- Msg_Len := Unsigned_8'Min (Buf'Length, Msg_Len);
-
- for I in Unsigned_8 range 1 .. Msg_Len loop
- Buf (I) := SPI.Read;
- Checksum := Checksum + Buf (I);
- end loop;
-
- Header (1) := SPI.Read;
- Header (2) := SPI.Read;
- Header (1) := not Header (1);
-
- if Checksum /= Header (1) then
- -- Log ("PN532_Read_Data: Invalid checksum");
- Status := False;
- else
- Status := True;
- Len := Msg_Len;
- end if;
-
- PN532_SPI_Disable;
- end PN532_Read_Data;
function PN532_SAM_Config return Boolean is
Cmd : PN532_Buf := ( PN532_SAMCONFIG,
@@ 302,6 134,12 @@ package body PN532 is
if not Status then
return False;
end if;
+
+ Status := PN532_Wait_For_Ready (PN532_TIMEOUT_VALUE);
+ if not Status then
+ Log ("timeout2");
+ return False;
+ end if;
PN532_Read_Data (Reply, Len, Status);
if Status and Reply (1) = 16#15# then
@@ 354,7 192,7 @@ package body 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
Status := False;
return;
end if;
@@ 1041,18 879,4 @@ package body PN532 is
end loop;
end PN532_NFC_Forum_Type_4_Emulate;
- procedure Init is
- begin
- Log ("PN532.Init");
- SPI.Init;
-
- PN532_SPI_Disable;
- PN532_Delay;
- PN532_SPI_Enable;
-
- SPI.Send(16#55#);
-
- delay 0.9;
- PN532_SPI_Disable;
- end Init;
end PN532;
M pn532.ads +3 -2
@@ 16,10 16,11 @@
--
with Interfaces;
+with PN532_Types;
+
+use PN532_Types;
package PN532 is
- type PN532_Buf is array
- (Interfaces.Unsigned_8 range <>) of Interfaces.Unsigned_8;
subtype PN532_Buf_4 is PN532_Buf (1..4);
subtype PN532_Buf_6 is PN532_Buf (1..6);
A => pn532_bus_spi.adb +200 -0
@@ 0,0 1,200 @@
+with Interfaces;
+with SPI;
+with AVR.Real_Time.Clock;
+pragma Unreferenced(AVR.Real_Time.Clock);
+
+use Interfaces;
+
+package body PN532_BUS_SPI is
+ SPI_STATUS : constant := 2#10#;
+ SPI_WRITE : constant := 2#01#;
+ SPI_READ : constant := 2#11#;
+
+ procedure PN532_Delay is
+ begin
+ delay 0.002;
+ end PN532_Delay;
+ pragma Inline (PN532_Delay);
+
+ procedure PN532_SPI_Enable is
+ begin
+ SPI.SS_Out := False;
+ end PN532_SPI_Enable;
+ pragma Inline (PN532_SPI_Enable);
+
+ procedure PN532_SPI_Disable is
+ begin
+ SPI.SS_Out := True;
+ end PN532_SPI_Disable;
+ pragma Inline (PN532_SPI_Disable);
+
+ procedure Init is
+ begin
+ delay 0.1;
+ SPI.Init;
+
+ PN532_SPI_Disable;
+ PN532_Delay;
+ PN532_SPI_Enable;
+
+ SPI.Send(16#55#);
+
+ delay 0.9;
+ PN532_SPI_Disable;
+ end Init;
+
+ procedure PN532_Write (Cmd : PN532_Buf) is
+ Checksum : Unsigned_8 := 16#FF#;
+ Len : Unsigned_8 := Cmd'Length + 1;
+ begin
+ PN532_SPI_Enable;
+ PN532_Delay;
+
+ SPI.Send(SPI_WRITE);
+
+ SPI.Send(0);
+ SPI.Send(0);
+ SPI.Send(16#FF#);
+
+ SPI.Send (Len);
+ SPI.Send ((not Len) + 1);
+
+ SPI.Send(HOST_TO_PN532);
+
+ Checksum := Checksum + HOST_TO_PN532;
+
+ for I in Cmd'Range loop
+ SPI.Send (Cmd (I));
+ Checksum := Checksum + Cmd (I);
+ end loop;
+
+ SPI.Send(not Checksum);
+ SPI.Send(0);
+
+ PN532_SPI_Disable;
+ end PN532_Write;
+
+ function PN532_Busy return Boolean is
+ Status : Unsigned_8;
+ begin
+ PN532_SPI_Enable;
+ PN532_Delay;
+ SPI.Send (SPI_STATUS);
+ Status := SPI.Read;
+ PN532_SPI_Disable;
+
+ return Status /= 1;
+ end PN532_Busy;
+
+ procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8) is
+ Buf : PN532_Buf (1..6);
+ Len : Unsigned_8;
+ begin
+ PN532_SPI_Enable;
+ PN532_Delay;
+ SPI.Send (SPI_READ);
+ Code := 0;
+
+ for I in Buf'Range loop
+ Buf (I) := SPI.Read;
+ end loop;
+
+ if Buf (1) = 0 and Buf (2) = 0 and Buf (3) = 16#FF# then
+ if Buf (4) = 0 and Buf (5) = 16#FF# and Buf (6) = 0 then -- ACK
+ Reply := REPLY_ACK;
+ elsif Buf(4) = 16#FF# and Buf(5) = 0 and Buf (6) = 0 then -- NACK
+ Reply := REPLY_NACK;
+ else -- ERROR
+ Reply := REPLY_ERROR;
+ Len := Buf (4);
+ if Buf (5) + Len = 0 then -- checksum ok
+ Code := Buf (6);
+ Buf (1) := SPI.Read;
+ Buf (2) := SPI.Read;
+ end if;
+ end if;
+ else
+ -- Log ("Unknown reply");
+ -- for I in Buf'Range loop
+ -- AVR.UART.Put (Data => Buf (I), Base => 16);
+ -- AVR.UART.Put (" ");
+ -- end loop;
+ -- AVR.UART.CRLF;
+ Reply := REPLY_ERROR;
+ Code := 255;
+ end if;
+
+ PN532_SPI_Disable;
+ end PN532_Read_Reply;
+
+ procedure PN532_Read_Raw (Buf : out PN532_Buf) is
+ begin
+ PN532_SPI_Enable;
+ PN532_Delay;
+
+ SPI.Send (SPI_READ);
+
+ for I in Buf'Range loop
+ Buf (I) := SPI.Read;
+ end loop;
+
+ PN532_SPI_Disable;
+ end PN532_Read_Raw;
+
+ procedure PN532_Read_Data
+ (Buf : out PN532_Buf;
+ Len : out Unsigned_8;
+ Status : out Boolean)
+ is
+ Header : PN532_Buf (1..6);
+ Checksum : Unsigned_8 := 16#FF#;
+ Msg_Len : Unsigned_8;
+ begin
+ PN532_SPI_Enable;
+ PN532_Delay;
+
+ SPI.Send (SPI_READ);
+
+ for I in Header'Range loop
+ Header (I) := SPI.Read;
+ end loop;
+
+ if not (Header (2) = 0 and Header (3) = 16#FF#) then
+ -- Log ("PN532_Read_Data: Invalid header");
+ PN532_SPI_Disable;
+ Status := False;
+ return;
+ end if;
+
+ Msg_Len := Header (4);
+ if Msg_Len + Header (5) /= 0 then
+ PN532_SPI_Disable;
+ Status := False;
+ -- Log ("PN532_Read_Data: Invalid header len checksum");
+ return;
+ end if;
+
+ Checksum := Checksum + Header (6);
+
+ Msg_Len := Unsigned_8'Min (Buf'Length, Msg_Len);
+
+ for I in Unsigned_8 range 1 .. Msg_Len loop
+ Buf (I) := SPI.Read;
+ Checksum := Checksum + Buf (I);
+ end loop;
+
+ Header (1) := SPI.Read;
+ Header (2) := SPI.Read;
+ Header (1) := not Header (1);
+
+ if Checksum /= Header (1) then
+ -- Log ("PN532_Read_Data: Invalid checksum");
+ Status := False;
+ else
+ Status := True;
+ Len := Msg_Len;
+ end if;
+
+ PN532_SPI_Disable;
+ end PN532_Read_Data;
+end PN532_BUS_SPI;
A => pn532_bus_spi.ads +23 -0
@@ 0,0 1,23 @@
+with Interfaces;
+with PN532_Types;
+
+use PN532_Types;
+use Interfaces;
+
+package PN532_BUS_SPI is
+ procedure Init;
+
+ function PN532_Busy return Boolean;
+
+ procedure PN532_Write (Cmd : PN532_Buf);
+
+ procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8);
+
+ procedure PN532_Read_Raw (Buf : out PN532_Buf);
+
+ procedure PN532_Read_Data
+ (Buf : out PN532_Buf;
+ Len : out Unsigned_8;
+ Status : out Boolean);
+
+end PN532_BUS_SPI;
No newline at end of file
M pn532_twi.adb +20 -56
@@ 23,21 23,35 @@ with AVR.UART;
with AVR.Strings;
with AVR.Programspace;
with AVR;
-with PN532_BUS_I2C;
+-- with PN532_BUS_I2C;
+with PN532_BUS_SPI;
use Interfaces;
package body PN532_TWI is
use AVR;
- procedure Init renames PN532_BUS_I2C.Init;
- function PN532_Busy return Boolean renames PN532_BUS_I2C.PN532_Busy;
- procedure PN532_Write (Cmd : PN532_Buf) renames PN532_BUS_I2C.PN532_Write;
- procedure PN532_Read_Raw (Buf : out PN532_Buf) renames PN532_BUS_I2C.PN532_Read_Raw;
+-- procedure Init renames PN532_BUS_I2C.Init;
+-- function PN532_Busy return Boolean renames PN532_BUS_I2C.PN532_Busy;
+-- procedure PN532_Write (Cmd : PN532_Buf) renames PN532_BUS_I2C.PN532_Write;
+-- procedure PN532_Read_Raw (Buf : out PN532_Buf) renames PN532_BUS_I2C.PN532_Read_Raw;
+-- procedure PN532_Read_Data
+-- (Buf : out PN532_Buf;
+-- Len : out Unsigned_8;
+-- Status : out Boolean) renames PN532_BUS_I2C.PN532_Read_Data;
+-- procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8)
+-- renames PN532_BUS_I2C.PN532_Read_Reply;
+
+ procedure Init renames PN532_BUS_SPI.Init;
+ function PN532_Busy return Boolean renames PN532_BUS_SPI.PN532_Busy;
+ procedure PN532_Write (Cmd : PN532_Buf) renames PN532_BUS_SPI.PN532_Write;
+ procedure PN532_Read_Raw (Buf : out PN532_Buf) renames PN532_BUS_SPI.PN532_Read_Raw;
procedure PN532_Read_Data
(Buf : out PN532_Buf;
Len : out Unsigned_8;
- Status : out Boolean) renames PN532_BUS_I2C.PN532_Read_Data;
+ Status : out Boolean) renames PN532_BUS_SPI.PN532_Read_Data;
+ procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8)
+ renames PN532_BUS_SPI.PN532_Read_Reply;
PN532_FIRMWARE_VERSION : constant := 16#02#;
@@ 96,56 110,6 @@ package body PN532_TWI is
return True;
end PN532_Wait_For_Ready;
- procedure PN532_Read_Reply (Reply : out Reply_Type; Code : out Unsigned_8)
- renames PN532_BUS_I2C.PN532_Read_Reply;
--- is
--- Buf : PN532_Buf (1..6);
--- Len : Unsigned_8;
--- Ok : Unsigned_8;
--- begin
--- AVR.I2C.Master.Request (PN532_I2C_ADDRESS, 7);
--- Code := 0;
---
--- loop
--- exit when AVR.I2C.Master.Data_Is_Available;
--- end loop;
--- Ok := AVR.I2C.Master.Get;
--- if (Ok and 1) /= 1 then
--- Reply := REPLY_ERROR;
--- return;
--- end if;
---
--- for I in Buf'Range loop
--- loop
--- exit when AVR.I2C.Master.Data_Is_Available;
--- end loop;
--- Buf (I) := AVR.I2C.Master.Get;
--- end loop;
---
--- if Buf (1) = 0 and Buf (2) = 0 and Buf (3) = 16#FF# then
--- if Buf (4) = 0 and Buf (5) = 16#FF# and Buf (6) = 0 then -- ACK
--- Reply := REPLY_ACK;
--- elsif Buf(4) = 16#FF# and Buf(5) = 0 and Buf (6) = 0 then -- NACK
--- Reply := REPLY_NACK;
--- else -- ERROR
--- Reply := REPLY_ERROR;
--- Len := Buf (4);
--- if Buf (5) + Len = 0 then -- checksum ok
--- Code := Buf (6);
--- end if;
--- end if;
--- else
--- -- Log ("Unknown reply");
--- -- for I in Buf'Range loop
--- -- AVR.UART.Put (Data => Buf (I), Base => 16);
--- -- AVR.UART.Put (" ");
--- -- end loop;
--- -- AVR.UART.CRLF;
--- Reply := REPLY_ERROR;
--- Code := 255;
--- end if;
--- end PN532_Read_Reply;
-
function PN532_Send_Command (Cmd : PN532_Buf; Timeout : Unsigned_32)
return Boolean
is