Difference between revisions of "Unit I2CGPIO"
(Created page with "Return to Unit Reference === Description === ---- ''To be documented'' === Constants === ---- ''To be documented'' === Type definitions === ---- ''To...") |
|||
(6 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
---- | ---- | ||
− | ''To be | + | '''GPIO based software I2C Driver unit''' |
+ | |||
+ | This is a software based (bit bang) I2C driver which can implement an I2C interface using any available pair of GPIO pins without the need for a hardware controller. | ||
+ | |||
+ | This driver supports clock stretching and 10bit addresses and can operate with either the default GPIO device or any other suitable GPIO device. | ||
+ | |||
+ | Creating multiple instances on different sets of GPIO pins is fully supported, all instances will appear in the standard Ultibo device tables. | ||
+ | |||
+ | Being a software based driver the clock speed is mostly meaningless, instead a delay parameter can be passed during device creation which determines the interval between high and low states and the length of start and stop conditions. The default delay value equates to approximately a 100KHz clock rate. | ||
+ | |||
+ | To use this driver in place of the default hardware I2C controller on the Raspberry Pi (I2C0 or BSC1) which is on GPIO pins 2 and 3 you simply initialize an instance of the I2CGPIO device by calling the I2CGPIOCreate function like this: | ||
+ | |||
+ | uses | ||
+ | I2C, | ||
+ | GPIO, | ||
+ | I2CGPIO; | ||
+ | |||
+ | var | ||
+ | I2CDevice:PI2CDevice; | ||
+ | GPIODevice:PGPIODevice; | ||
+ | |||
+ | begin | ||
+ | // Get the default GPIO device | ||
+ | GPIODevice:=GPIODeviceGetDefault; | ||
+ | |||
+ | // Create an instance of the I2CGPIO device | ||
+ | I2CDevice:=I2CGPIOCreate(GPIODevice,GPIO_PIN_2,GPIO_PIN_3,4,0,False,False); | ||
+ | |||
+ | // Pass the returned I2CDevice to the standard I2C API functions | ||
+ | ... | ||
+ | end; | ||
+ | |||
+ | The returned I2CDevice instance can be passed to any of the standard I2C API functions to perform I2C reads and writes. As noted above, any available pair of GPIO pins can be used to create a new I2CGPIO device. | ||
+ | |||
+ | If an instance of the I2CGPIO device is no longer required it can be released by calling the I2CGPIODestroy function and passing the I2CDevice instance returned from I2CGPIOCreate. | ||
+ | |||
+ | '''Handling of SDA/SCL''' | ||
+ | |||
+ | If OpenDrain is set to True in I2CGPIOCreate then the SDA/SCL pins will be set to Output and toggled High or Low as required, the driver assumes that the hardware provides the high impedance state required for the I2C protocol. | ||
+ | |||
+ | If OpenDrain is set to False in I2CGPIOCreate then the SDA/SCL pins will be set to Input when the state is High and Output with a value or Low when the state is Low. This will provide the high impedance (floating) state required for the I2C protocol. | ||
+ | |||
+ | If OutputOnly is set to True in I2CGPIOCreate then reading of the SCL value is not used and clock stretching is not supported. | ||
=== Constants === | === Constants === | ||
---- | ---- | ||
− | '' | + | |
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''I2CGPIO specific constants''' <code> I2CGPIO_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>I2CGPIO_I2C_DESCRIPTION = 'GPIO Software I2C';</code> | ||
+ | | style="width: 50%;"|Description of I2CGPIO I2C device | ||
+ | |- | ||
+ | | <code>I2CGPIO_I2C_MAX_SIZE = $FFFF;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>I2CGPIO_I2C_MIN_CLOCK = 10000;</code> | ||
+ | | Arbitrary minimum of 10KHz, actual rate is determined by Delay parameter. | ||
+ | |- | ||
+ | | <code>I2CGPIO_I2C_MAX_CLOCK = 100000;</code> | ||
+ | | Arbitrary maximum of 100KHz, actual rate is determined by Delay parameter. | ||
+ | |- | ||
+ | | <code>I2CGPIO_RETRY_COUNT = 3;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>I2CGPIO_DEFAULT_TIMEOUT = 100;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Type definitions === | === Type definitions === | ||
---- | ---- | ||
− | '' | + | |
+ | '''I2CGPIO device''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PI2CGPIODevice = ^TI2CGPIODevice;</code> | ||
+ | |||
+ | <code>TI2CGPIODevice = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''I2C Properties'' | ||
+ | |- | ||
+ | | <code>I2C:TI2CDevice;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |colspan="2"|''I2CGPIO Properties'' | ||
+ | |- | ||
+ | | <code>GPIO:PGPIODevice;</code> | ||
+ | | The GPIO device this device is connected to | ||
+ | |- | ||
+ | | <code>SDA:LongWord;</code> | ||
+ | | GPIO pin for the SDA line | ||
+ | |- | ||
+ | | <code>SCL:LongWord;</code> | ||
+ | | GPIO pin for the SCL line | ||
+ | |- | ||
+ | | <code>Delay:LongWord;</code> | ||
+ | | Clock and Data delay in microseconds | ||
+ | |- | ||
+ | | <code>Timeout:LongWord;</code> | ||
+ | | Clock timeout in milliseconds | ||
+ | |- | ||
+ | | <code>OutputOnly:LongBool;</code> | ||
+ | | Clock line is output only, no test for SCL high. | ||
+ | |- | ||
+ | | <code>OpenDrain:LongBool;</code> | ||
+ | | Clock and Data are open drain, no need to simulate by switching direction. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Public variables === | === Public variables === | ||
---- | ---- | ||
− | '' | + | ''None defined'' |
=== Function declarations === | === Function declarations === | ||
---- | ---- | ||
− | |||
+ | '''I2CGPIO functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIOCreate(GPIO:PGPIODevice; SDA,SCL,Delay,Timeout:LongWord; OutputOnly,OpenDrain:Boolean):PI2CDevice;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Create and register a new I2CGPIO I2C device connected to the specified GPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIODestroy(I2C:PI2CDevice):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | |||
+ | '''I2CGPIO I2C functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIOStart(I2C:PI2CDevice; Rate:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of I2CDeviceStart API for I2CGPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use I2CDeviceStart instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIOStop(I2C:PI2CDevice):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of I2CDeviceStop API for I2CGPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use I2CDeviceStop instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIORead(I2C:PI2CDevice; Address:Word; Buffer:Pointer; Size:LongWord; var Count:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of I2CDeviceRead API for I2CGPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use I2CDeviceRead instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIOWrite(I2C:PI2CDevice; Address:Word; Buffer:Pointer; Size:LongWord; var Count:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of I2CDeviceWrite API for I2CGPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use I2CDeviceWrite instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIOWriteRead(I2C:PI2CDevice; Address:Word; Initial:Pointer; Len:LongWord; Data:Pointer; Size:LongWord; var Count:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of I2CDeviceWriteRead API for I2CGPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use I2CDeviceWriteRead instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function I2CGPIOWriteWrite(I2C:PI2CDevice; Address:Word; Initial:Pointer; Len:LongWord; Data:Pointer; Size:LongWord; var Count:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of I2CDeviceWriteWrite API for I2CGPIO device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use I2CDeviceWriteWrite instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
Return to [[Unit_Reference|Unit Reference]] | Return to [[Unit_Reference|Unit Reference]] |
Latest revision as of 03:30, 27 May 2022
Return to Unit Reference
Description
GPIO based software I2C Driver unit
This is a software based (bit bang) I2C driver which can implement an I2C interface using any available pair of GPIO pins without the need for a hardware controller.
This driver supports clock stretching and 10bit addresses and can operate with either the default GPIO device or any other suitable GPIO device.
Creating multiple instances on different sets of GPIO pins is fully supported, all instances will appear in the standard Ultibo device tables.
Being a software based driver the clock speed is mostly meaningless, instead a delay parameter can be passed during device creation which determines the interval between high and low states and the length of start and stop conditions. The default delay value equates to approximately a 100KHz clock rate.
To use this driver in place of the default hardware I2C controller on the Raspberry Pi (I2C0 or BSC1) which is on GPIO pins 2 and 3 you simply initialize an instance of the I2CGPIO device by calling the I2CGPIOCreate function like this:
uses I2C, GPIO, I2CGPIO; var I2CDevice:PI2CDevice; GPIODevice:PGPIODevice; begin // Get the default GPIO device GPIODevice:=GPIODeviceGetDefault; // Create an instance of the I2CGPIO device I2CDevice:=I2CGPIOCreate(GPIODevice,GPIO_PIN_2,GPIO_PIN_3,4,0,False,False); // Pass the returned I2CDevice to the standard I2C API functions ... end;
The returned I2CDevice instance can be passed to any of the standard I2C API functions to perform I2C reads and writes. As noted above, any available pair of GPIO pins can be used to create a new I2CGPIO device.
If an instance of the I2CGPIO device is no longer required it can be released by calling the I2CGPIODestroy function and passing the I2CDevice instance returned from I2CGPIOCreate.
Handling of SDA/SCL
If OpenDrain is set to True in I2CGPIOCreate then the SDA/SCL pins will be set to Output and toggled High or Low as required, the driver assumes that the hardware provides the high impedance state required for the I2C protocol.
If OpenDrain is set to False in I2CGPIOCreate then the SDA/SCL pins will be set to Input when the state is High and Output with a value or Low when the state is Low. This will provide the high impedance (floating) state required for the I2C protocol.
If OutputOnly is set to True in I2CGPIOCreate then reading of the SCL value is not used and clock stretching is not supported.
Constants
I2CGPIO_*
I2CGPIO_I2C_DESCRIPTION = 'GPIO Software I2C';
|
Description of I2CGPIO I2C device |
I2CGPIO_I2C_MAX_SIZE = $FFFF;
|
|
I2CGPIO_I2C_MIN_CLOCK = 10000;
|
Arbitrary minimum of 10KHz, actual rate is determined by Delay parameter. |
I2CGPIO_I2C_MAX_CLOCK = 100000;
|
Arbitrary maximum of 100KHz, actual rate is determined by Delay parameter. |
I2CGPIO_RETRY_COUNT = 3;
|
|
I2CGPIO_DEFAULT_TIMEOUT = 100;
|
Type definitions
I2CGPIO device
PI2CGPIODevice = ^TI2CGPIODevice;
TI2CGPIODevice = record
I2C Properties | |
I2C:TI2CDevice;
|
|
I2CGPIO Properties | |
GPIO:PGPIODevice;
|
The GPIO device this device is connected to |
SDA:LongWord;
|
GPIO pin for the SDA line |
SCL:LongWord;
|
GPIO pin for the SCL line |
Delay:LongWord;
|
Clock and Data delay in microseconds |
Timeout:LongWord;
|
Clock timeout in milliseconds |
OutputOnly:LongBool;
|
Clock line is output only, no test for SCL high. |
OpenDrain:LongBool;
|
Clock and Data are open drain, no need to simulate by switching direction. |
Public variables
None defined
Function declarations
I2CGPIO functions
function I2CGPIOCreate(GPIO:PGPIODevice; SDA,SCL,Delay,Timeout:LongWord; OutputOnly,OpenDrain:Boolean):PI2CDevice;
Note | None documented |
---|
function I2CGPIODestroy(I2C:PI2CDevice):LongWord;
Note | None documented |
---|
I2CGPIO I2C functions
function I2CGPIOStart(I2C:PI2CDevice; Rate:LongWord):LongWord;
Note | Not intended to be called directly by applications, use I2CDeviceStart instead. |
---|
function I2CGPIOStop(I2C:PI2CDevice):LongWord;
Note | Not intended to be called directly by applications, use I2CDeviceStop instead. |
---|
function I2CGPIORead(I2C:PI2CDevice; Address:Word; Buffer:Pointer; Size:LongWord; var Count:LongWord):LongWord;
Note | Not intended to be called directly by applications, use I2CDeviceRead instead. |
---|
function I2CGPIOWrite(I2C:PI2CDevice; Address:Word; Buffer:Pointer; Size:LongWord; var Count:LongWord):LongWord;
Note | Not intended to be called directly by applications, use I2CDeviceWrite instead. |
---|
function I2CGPIOWriteRead(I2C:PI2CDevice; Address:Word; Initial:Pointer; Len:LongWord; Data:Pointer; Size:LongWord; var Count:LongWord):LongWord;
Note | Not intended to be called directly by applications, use I2CDeviceWriteRead instead. |
---|
function I2CGPIOWriteWrite(I2C:PI2CDevice; Address:Word; Initial:Pointer; Len:LongWord; Data:Pointer; Size:LongWord; var Count:LongWord):LongWord;
Note | Not intended to be called directly by applications, use I2CDeviceWriteWrite instead. |
---|
Return to Unit Reference