Put SPI functions into a separate file.

Also, make the differenced between PN532 packages
as small as possible.
6 files changed, 269 insertions(+), 257 deletions(-)

M nfc_tags.adb
M pn532.adb
M pn532.ads
A => pn532_bus_spi.adb
A => pn532_bus_spi.ads
M pn532_twi.adb
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