<< >>

Programmers guide to module_i2c_master

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.

Types

r_i2c

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 scl

Port on which clock wire is attached.

Must be on bit 0

port sda

Port on which data wire is attached.

Must be on bit 0

API

void i2c_master_init(struct r_i2c &i2c)

Function that initialises the ports on an I2C device.

Parameters:
  • i2c_master – struct containing the clock and data ports. Both should be declared as unbuffered bidirectional ports.
int i2c_master_rx(int device, unsigned char data[], int nbytes, struct r_i2c &i2c)

Function that reads data from an I2C device.

Parameters:
  • device – Bus address of device, even number between 0x00 and 0xFE.
  • data – Array where data is stored.
  • nbytes – Number of bytes to read and store in data. This parameter must be set to ‘1’ and is ignored in this module. This parameter is provided for compatibililty with module_i2c_master.
  • i2c – struct containing the clock and data ports. Both should be declared as unbuffered bidirectional ports.
int i2c_master_read_reg(int device, int reg_addr, unsigned char data[], int nbytes, struct r_i2c &i2c_master)

Function that reads a register from an I2C device.

Parameters:
  • device – Bus address of device, even number between 0x00 and 0xFE.
  • reg_addr – Address of register to read, value between 0x00 and 0x7F.
  • data – Array where data is stored.
  • nbytes – Number of bytes to read and store in data. This parameter must be set to ‘1’ and is ignored in this module. This parameter is provided for compatibililty with module_i2c_master.
  • i2c_master – struct containing the clock and data ports. Both should be declared as unbuffered bidirectional ports.
int i2c_master_write_reg(int device, int reg_addr, unsigned char data[], int nbytes, struct r_i2c &i2c_master)

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:
  • device – Bus address of device, even number between 0x00 and 0xFE.
  • reg_addr – Address of register to write to, value between 0x00 and 0x7F.
  • data – Array where data is stored.
  • nbytes – Number of bytes to read and store in data. This parameter must be set to ‘1’ and is ignored in this module. This parameter is provided for compatibililty with module_i2c_master.
  • i2c_master – struct containing the clock and data ports. Both should be declared as unbuffered bidirectional ports.

Example

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;
}