Add software I2C example.
A => examples/soft-i2c/Makefile +12 -0
@@ 0,0 1,12 @@ 
+
+test_i2c.elf: soft_i2c.adb uno_i2c.adb soft_i2c.ads
+	avr-gnatmake -p -XBOARD=arduino_uno -P i2c
+
+test_i2c.hex: test_i2c.elf
+	avr-objcopy -Obinary -R .eeprom test_i2c.elf test_i2c.hex
+
+clean:
+	avr-gnatclean -XBOARD=arduino_uno -P i2c
+
+.PHONY: clean
+

          
A => examples/soft-i2c/i2c.gpr +7 -0
@@ 0,0 1,7 @@ 
+project I2C extends "avr_app" is
+   for Main use ("test_i2c.adb");
+   for Object_Dir use "objects";
+   for Exec_Dir use ".";
+
+   for Source_Dirs use (".");
+end I2C;

          
A => examples/soft-i2c/soft_i2c.adb +139 -0
@@ 0,0 1,139 @@ 
+--
+-- Copyright (c) 2017 Tero Koskinen <tero.koskinen@iki.fi>
+--
+-- Permission to use, copy, modify, and distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+package body Soft_I2C is
+   use type Interfaces.Unsigned_8;
+
+   procedure Start is
+   begin
+      Pull_SDA_Down;
+      Delay_T_HD_STA;
+      Pull_SCL_Down;
+      Delay_T_Low_Half;
+   end Start;
+
+   procedure Stop is
+   begin
+      Pull_SDA_Down;
+      Delay_T_Low_Half;
+      Release_SCL_Up;
+      Delay_T_SU_STO;
+      Release_SDA_Up;
+      Delay_T_Buf;
+   end Stop;
+
+   procedure Write_Byte (Byte : Interfaces.Unsigned_8;
+                         Status : out Error_Status)
+   is
+      B : Interfaces.Unsigned_8 := Byte;
+      Nack : Boolean;
+   begin
+      for I in Interfaces.Unsigned_8 range 0..7 loop
+         if (B and 2#1000_0000#) = 2#1000_0000# then
+            Release_SDA_Up;
+         else
+            Pull_SDA_Down;
+         end if;
+
+         Delay_T_Low_Half;
+         Release_SCL_Up;
+         Delay_T_High;
+         Pull_SCL_Down;
+         Delay_T_Low_Half;
+         B := B * 2;
+      end loop;
+
+      Release_SDA_Up;
+      Delay_T_Low_Half;
+      Release_SCL_Up;
+      Delay_T_High;
+
+      -- Read the bus state
+      Nack := SDA_State;
+      Pull_SCL_Down;
+      Delay_T_Low_Half;
+
+      if not Nack then
+         Status := SOFT_I2C_OK;
+      else
+         Status := SOFT_I2C_NACK;
+      end if;
+   end Write_Byte;
+
+   procedure Read_Byte (Byte : out Interfaces.Unsigned_8; Ack : Boolean)
+   is
+      Bit : Boolean;
+      B : Interfaces.Unsigned_8 := 0;
+   begin
+      Release_SDA_Up;
+
+      for I in Interfaces.Unsigned_8 range 0 .. 7 loop
+         Delay_T_Low_Half;
+         Release_SCL_Up;
+         Delay_T_High;
+
+         Bit := SDA_State;
+         Pull_SCL_Down;
+         Delay_T_Low_Half;
+
+         B := B * 2;
+         if Bit then
+            B := B or 1;
+         end if;
+      end loop;
+
+      if Ack then
+         Pull_SDA_Down;
+      else
+         Release_SDA_Up;
+      end if;
+
+      Delay_T_Low_Half;
+      Release_SCL_Up;
+      Delay_T_High;
+      Pull_SCL_Down;
+      Delay_T_Low_Half;
+
+      Byte := B;
+   end Read_Byte;
+
+   procedure Write (Address : Interfaces.Unsigned_8; Bytes : Byte_Array;
+                    Status : out Error_Status)
+   is
+      Err : Error_Status;
+   begin
+      Start;
+      Write_Byte (Address and 2#1111_1110#, Err);
+      for I in Bytes'Range loop
+         Write_Byte (Bytes (I), Status);
+         exit when Err /= SOFT_I2C_OK;
+      end loop;
+      Stop;
+   end Write;
+
+   procedure Read (Address : Interfaces.Unsigned_8; Bytes : in out Byte_Array)
+   is
+      Status : Error_Status;
+   begin
+      Start;
+      Write_Byte (Address or 1, Status);
+      for I in Bytes'Range loop
+         Read_Byte (Bytes (I), I /= Bytes'Last);
+         exit when Status /= SOFT_I2C_OK;
+      end loop;
+      Stop;
+   end Read;
+end Soft_I2C;

          
A => examples/soft-i2c/soft_i2c.ads +50 -0
@@ 0,0 1,50 @@ 
+--
+-- Copyright (c) 2017 Tero Koskinen <tero.koskinen@iki.fi>
+--
+-- Permission to use, copy, modify, and distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+with Interfaces;
+
+generic
+   with procedure Pull_SDA_Down;
+   with procedure Release_SDA_Up;
+   with procedure Pull_SCL_Down;
+   with procedure Release_SCL_Up;
+   with procedure Delay_T_HD_STA; -- 4.0
+   with procedure Delay_T_SU_STO; -- 4.0
+   with procedure Delay_T_Buf; -- 4.7..5
+   with procedure Delay_T_Low_Half; -- 2.4
+   with procedure Delay_T_High; -- 5
+   with function SDA_State return Boolean;
+package Soft_I2C is
+
+   type Byte_Array is
+     array (Interfaces.Unsigned_8 range <>) of Interfaces.Unsigned_8;
+
+   type Error_Status is
+     (SOFT_I2C_OK,
+      SOFT_I2C_NACK,
+      SOFT_I2C_FAILED);
+
+   procedure Start;
+   procedure Stop;
+   procedure Write_Byte (Byte : Interfaces.Unsigned_8;
+                         Status : out Error_Status);
+   procedure Read_Byte (Byte : out Interfaces.Unsigned_8; Ack : Boolean);
+
+   procedure Write (Address : Interfaces.Unsigned_8; Bytes : Byte_Array;
+                    Status  : out Error_Status);
+
+   procedure Read (Address : Interfaces.Unsigned_8; Bytes : in out Byte_Array);
+end Soft_I2C;

          
A => examples/soft-i2c/test_i2c.adb +53 -0
@@ 0,0 1,53 @@ 
+--
+-- Copyright (c) 2017 Tero Koskinen <tero.koskinen@iki.fi>
+--
+-- Permission to use, copy, modify, and distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+with Interfaces;
+with AVR.UART;
+with AVR.Real_Time.Delays;
+with Uno_I2C;
+
+procedure Test_I2C is
+   use type Interfaces.Unsigned_8;
+
+   TMP102_Address : constant := 16#90#;
+   Data : Uno_I2C.I2C.Byte_Array (1..2) := (0, 0);
+   Cmd : Uno_I2C.I2C.Byte_Array (1..1) := (1 => 16#00#);
+   Status : Uno_I2C.I2C.Error_Status;
+   Temp_Value : Integer;
+begin
+   AVR.UART.Init (103);
+   loop
+      Data := (0, 0);
+      Uno_I2C.Write (Address => TMP102_Address, Bytes => Cmd, Status => Status);
+      Uno_I2C.Read (Address => TMP102_Address, Bytes => Data);
+      Temp_Value := Integer (Data (1)) * 256;
+      Temp_Value := Temp_Value + Integer (Data (2));
+      Temp_Value := Temp_Value / 256; -- Basically we ignore the second byte
+
+      AVR.UART.Put ("T:");
+      
+      if Temp_Value > 0 then
+         Data (1) := Interfaces.Unsigned_8 (Temp_Value);
+      else
+         AVR.UART.Put ("-");
+         Data (1) := Interfaces.Unsigned_8 (-Temp_Value);
+      end if;
+      AVR.UART.Put (Data (1), Base => 10);
+      AVR.UART.Put (" C");
+      AVR.UART.CRLF;
+      delay 2.0;
+   end loop;
+end Test_I2C;

          
A => examples/soft-i2c/uno_i2c.adb +55 -0
@@ 0,0 1,55 @@ 
+--
+-- Copyright (c) 2017 Tero Koskinen <tero.koskinen@iki.fi>
+--
+-- Permission to use, copy, modify, and distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+with Soft_I2C;
+with AVR.Wait;
+with AVR.MCU;
+with AVR;
+
+package body Uno_I2C is
+   use AVR;
+   use AVR.MCU;
+   SDA_Bit : constant := 0;
+   SCL_Bit : constant := 1;
+
+   procedure Pull_SDA_Down is
+   begin
+      DDRC_Bits (SDA_Bit) := DD_Output;
+      PORTC_Bits (SDA_Bit) := False;
+   end Pull_SDA_Down;
+
+   procedure Release_SDA_Up is
+   begin
+      DDRC_Bits (SDA_Bit) := DD_Input;
+   end Release_SDA_Up;
+
+   procedure Pull_SCL_Down is
+   begin
+      DDRC_Bits (SCL_Bit) := DD_Output;
+      PORTC_Bits (SCL_Bit) := False;
+   end Pull_SCL_Down;
+
+   procedure Release_SCL_Up is
+   begin
+      DDRC_Bits (SCL_Bit) := DD_Input;
+   end Release_SCL_Up;
+
+   function Read_SDA_Pin return Boolean is
+   begin
+      DDRC_Bits (SDA_Bit) := DD_Input;
+      return PINC_Bits (SDA_Bit);
+   end Read_SDA_Pin;
+end Uno_I2C;

          
A => examples/soft-i2c/uno_i2c.ads +61 -0
@@ 0,0 1,61 @@ 
+--
+-- Copyright (c) 2017 Tero Koskinen <tero.koskinen@iki.fi>
+--
+-- Permission to use, copy, modify, and distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+with Interfaces;
+with Soft_I2C;
+with AVR.Wait;
+
+package Uno_I2C is
+   procedure Pull_SDA_Down;
+   procedure Release_SDA_Up;
+   procedure Pull_SCL_Down;
+   procedure Release_SCL_Up;
+   function Read_SDA_Pin return Boolean;
+
+   procedure Delay_4_0 is
+      new AVR.Wait.Generic_Wait_USecs
+        (Crystal_Hertz => 16_000_000,
+         Micro_Seconds => 4);
+
+   procedure Delay_2_4 is
+      new AVR.Wait.Generic_Wait_USecs
+        (Crystal_Hertz => 16_000_000,
+         Micro_Seconds => 3);
+
+   procedure Delay_5_0 is
+      new AVR.Wait.Generic_Wait_USecs
+        (Crystal_Hertz => 16_000_000,
+         Micro_Seconds => 4);
+
+   package I2C is new Soft_I2C
+     (Pull_SDA_Down    => Pull_SDA_Down,
+      Release_SDA_Up   => Release_SDA_Up,
+      Pull_SCL_Down    => Pull_SCL_Down,
+      Release_SCL_Up   => Release_SCL_Up,
+      Delay_T_HD_STA   => Delay_4_0,
+      Delay_T_SU_STO   => Delay_4_0,
+      Delay_T_Buf      => Delay_5_0,
+      Delay_T_Low_Half => Delay_2_4,
+      Delay_T_High     => Delay_5_0,
+      SDA_State        => Read_SDA_Pin);
+
+   procedure Write (Address : Interfaces.Unsigned_8;
+                    Bytes   : I2C.Byte_Array;
+                    Status  : out I2C.Error_Status) renames I2C.Write;
+   procedure Read (Address : Interfaces.Unsigned_8;
+                   Bytes   : in out I2C.Byte_Array)
+      renames I2C.Read;
+end Uno_I2C;