procedure Abort_Write
(This : in out I2C_Port)
procedure Clear_Error
(This : in out I2C_Port)
procedure Configure
(This : in out I2C_Port;
Config : I2C_Config)
procedure Disable
(This : in out I2C_Port;
Deadline : RP.Timer.Time := RP.Timer.Time'Last)
procedure Enable
(This : in out I2C_Port;
Deadline : RP.Timer.Time := RP.Timer.Time'Last)
function Enabled
(This : I2C_Port)
return Boolean
Fast_Mode : constant I2C_Timing :=
(High => 1_160,
Low => 1_330,
Hold => 800,
Spike => 50,
others => <>);
Fast_Mode_Plus : constant I2C_Timing :=
(High => 400,
Low => 600,
Hold => 200,
Spike => 50,
others => <>);
type I2C_Abort_Source is record
No_Ack_Addr_7b : Boolean := False;
No_Ack_Addr_10b_1 : Boolean := False;
No_Ack_Addr_10b_2 : Boolean := False;
No_Ack_Transmit : Boolean := False;
No_Ack_General_Call : Boolean := False;
Invalid_General_Call : Boolean := False;
Invalid_Ack_High_Speed : Boolean := False;
Invalid_Ack_Start : Boolean := False;
No_Restart_High_Speed : Boolean := False;
No_Restart_Start : Boolean := False;
No_Restart_10b_Read : Boolean := False;
Not_Controller_Mode : Boolean := False;
Arbitration_Lost : Boolean := False;
Target_Transmit_Abort : Boolean := False;
Target_Arbitration_Lost : Boolean := False;
Invalid_Target_Read : Boolean := False;
Transfer_Aborted : Boolean := False;
Transmit_Flush_Count : HAL.UInt9 := 0;
end record
with Size => 32;
7 bit address unacknowledged
10 bit address unacknowledged (first byte)
10 bit address unacknowledged (second byte)
Upon controller transmit, the address was acknowledged, but a data byte was not.
No target acknowledged a general call
General call command with read bit set
High speed mode was selected, but an ack was received before the end of the transfer.
A start byte was acknowledged, but only data should be acknowledged.
High speed mode was selected but restart is not enabled
Attempting to send a start byte but restart is not enabled
10 bit read attempted but restart is not enabled
A controller operation was attempted while in target mode
Something pulled SDA low before being addressed by the controller
A target read command was issued while there was still data in the transmit FIFO, transmit aborted.
Something pulled SDA to the wrong state while transmitting in target mode
The read bit was set in the CMD register during a target transmit
User aborted a transfer in controller mode
type I2C_Config is record
Role : I2C_Role := Controller;
Timing : I2C_Timing := Standard_Mode;
end record;
subtype I2C_Number is Natural range 0 .. 1;
type I2C_Port
(Num : I2C_Number;
Periph : not null access RP2040_SVD.I2C.I2C_Peripheral)
is tagged private;
type I2C_Role is (Controller, Target);
type I2C_State is record
Abort_Source : I2C_Abort_Source;
Last_Command : RP2040_SVD.I2C.IC_DATA_CMD_Register;
RX_Remaining : Natural;
TX_Remaining : Natural;
TX_Empty : Boolean;
RX_Empty : Boolean;
Repeated_Start : Boolean;
Is_Error : Boolean;
end record;
type I2C_Status is
(Ok, Timeout, Error);
If a procedure sets Status to Error, the record returned by function State will provide more information useful for debugging.
type I2C_Timing is record
High, Low, Hold, Spike : Nanoseconds;
Rise, Fall : Nanoseconds := 0;
end record;
type Nanoseconds is new Natural;
procedure Read
(This : in out I2C_Port;
Data : out HAL.UInt8;
Status : out I2C_Status;
Deadline : RP.Timer.Time := RP.Timer.Time'Last)
function Read_Ready
(This : I2C_Port)
return Boolean
Returns True if a call to Read would not block
procedure Set_Address
(This : in out I2C_Port;
Addr : HAL.UInt10)
When configured as a Controller, Set_Address indicates the address of the Target for Read and Write. When configured as a Target, Set_Address indicates this device's address.
procedure Set_Address
(This : in out I2C_Port;
Addr : HAL.UInt7)
procedure Set_Timing
(This : in out I2C_Port;
T : I2C_Timing)
Standard_Mode : constant I2C_Timing :=
(High => 5_200,
Low => 4_700,
Hold => 3_450,
others => <>);
procedure Start_Read
(This : in out I2C_Port;
Length : Positive := 1;
Stop : Boolean := True)
If Stop is False, the Controller does not release the bus after this transaction completes and will issue a repeated start before the first byte of the next transaction. Stop has no effect if Role = Target.
procedure Start_Write
(This : in out I2C_Port;
Length : Positive := 1;
Stop : Boolean := True;
Deadline : RP.Timer.Time := RP.Timer.Time'Last)
In Target mode, Start_Write waits until Deadline for the Controller to send our address. If a Deadline is specified and nonblocking behavior is expected, the caller should check the value of Write_Ready before calling Write.
function State
(This : I2C_Port)
return I2C_State
procedure Write
(This : in out I2C_Port;
Data : HAL.UInt8;
Status : out I2C_Status;
Deadline : RP.Timer.Time := RP.Timer.Time'Last)
If Deadline is reached before Write_Ready returns True, Abort_Write will be called and Status is set to Err_Timeout. After a timeout, call Clear_Error before attempting another Write.
function Write_Ready
(This : I2C_Port)
return Boolean
Returns True if a call to Write would not block