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;