This I2C module comprises three functions that implement I2C master. It is a small and simple version of the protocol with limitations (described below), and expects SCL and SDA on the same port.
The four restrictions of this module are:
Note that on a single port it is impossible to implement clock stretching or multi-master.
Any constants that are to be overridden should be defined in an include file i2c_conf.h.
This constant defines the time in clock ticks between successive bits.
By default set to 1000 for 100 Kbit devices, but it can be overriden to 250 for 400 Kbit devices.
This constant defines the bit value of a high clock on the I2C port.
The default value is 2, meaning that this is on bit 1 of the port. Set to 1, 4, 8, ... for other bits of the port.
This constant defines the bit value of a high data bit on the I2C port.
The default value is 1, meaning that this is on bit 0 of the port. Set to 2, 4, 8, ... for other bits of the port.
This constant defines the bit value of the other bits of the I2C port.
The default value is 0xC, meaning that bits 2 and 3 are kept high. Note that on occassions the other bits are left to float, so external resistors shall be used to reinforce the default value
Function that initialises the ports on an I2C device.
Parameters: |
|
---|
Function that reads data from an I2C device.
Parameters: |
|
---|
Function that writes to a register on an I2C device.
Note that this function uses the same interface as module_i2c but that the fields master_num and clock_mul are ignored by this function.
Parameters: |
|
---|
An example program is shown below. Two unbuffered undirectional ports must be declared. Neither should be configured. In this example, SDA and SCL are connected to the lowest two bits of port 4A:
#include <stdio.h>
#include <xs1.h>
#include "i2c.h"
port i2c = XS1_PORT_4F;
port gpio = XS1_PORT_4E;
The main program calls _write_reg as appropriate:
int main(void)
{
unsigned char data[1];
int x;
int i;
i2c_master_init(i2c);
gpio <: 0xF;
data[0] = 0xFF;
for(int j = 0; j < 1000000; j++) {
for(i = 0x90; i < 0x9E; i += 2) {
if (i == 0x94) i = 0x9C;
data[0] = ~i;
x = i2c_master_write_reg(i, 7, data, 1, i2c);
}
for(i = 0x90; i < 0x9E; i += 2) {
if (i == 0x94) i = 0x9C;
data[0] = i;
x = i2c_master_write_reg(i, 8, data, 1, i2c);
}
}
return 0;
}