This module implements multi-master I2C, and can be instantiated with different bus speeds for each instantiation.
This I2C module comprises four functions that implement I2C master. A simpler restrictive version is available in the module module_i2c_simple.
Struct that holds the data for instantiating the I2C module - it just comprises two ports (the clock port and the data port), the only other settable parameter is the speed of the bus which is a compile time define.
Structure Members:
Port on which clock wire is attached.
Must be on bit 0
Port on which data wire is attached.
Must be on bit 0
Function that initialises the ports on an I2C device.
Parameters: |
|
---|
Function that reads data from an I2C device.
Parameters: |
|
---|
Function that reads a register 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, SCL is connected to the lowest bit of port 4C, and SDA is connected to port 1G. Note that in comparison with module_i2c_simple the clock speed is defined as part of the I2C bus-declaration:
#include <stdio.h>
#include <xs1.h>
#include "i2c.h"
struct r_i2c i2cOne = {
XS1_PORT_1B,
XS1_PORT_1A,
1008,
};
struct r_i2c i2cTwo = {
XS1_PORT_1F,
XS1_PORT_1E,
1000,
};
The main program calls _read_reg and _write_reg as appropriate:
void beMaster(int id, int device, struct r_i2c &i2cPorts, streaming chanend sync) {
unsigned char data[10];
timer t; unsigned t0, t1, time[10];
i2c_master_init(i2cPorts);
for(int i = 0; i < 10; i++) {
sync <: 1;
sync :> int _;
t :> t0;
if (i2c_master_read_reg(device, 0x0, data, 1, i2cPorts)) {
t :> t1;
if (data[0] != 0xff) {
// printf("%d %3d: %02x\n", id, i, data[0]);
}
time[i] = t1-t0;
} else {
printf("%d: Fail\n", id);
}
}
for(int i = 0; i < 10; i++) {
printf("%d: %d\n", id, time[i]);
}
}
int main(void) {
streaming chan sync;
unsigned char data[1];
par {
beMaster(0, 82, i2cOne, sync);
beMaster(1, 82, i2cTwo, sync);
}
i2c_master_write_reg(82, 0x0, data, 1, i2cOne);
return 0;
}