I2C

Registers

struct i2c_register_map

This struct maps the registers of the BSC controller. The names of the struct members correspond to the registers from the Datasheet:

struct i2c_register_map {
    uint32_t C;
    uint32_t S;
    uint32_t DLEN;
    uint32_t A;
    uint32_t FIFO;
    uint32_t DIV;
    uint32_t DEL;
    uint32_t CLKT;
};
extern volatile struct i2c_register_map *I2C
I2C = (volatile struct i2c_register_map *)i2c_base_ptr;

By using this variable, the registers of the I2C can be accessed like this I2C->FIFO.

Functions

int i2c_map(void)

This function maps the I2C registers. It calls peripheral_map() with the values I2C_OFFSET and I2C_SIZE. I2C_OFFSET is defined in i2c.c. On error -1 is returned.

void i2c_unmap(void)

This function unmaps the I2C registers.

void i2c_set_address(uint8_t addr)

This function sets the address of the I2C device to communicate with. The address is a seven bit value.

void i2c_set_clkdiv(uint16_t divisor)

This function sets the clock divisor of the BSC controller.

Note

The clock source is the core clock with a frequency, according to the Datasheet, of 150 MHz and according to this file and other sources of 250 MHz. When I tested the clock speed of I2C and SPI with a logic analyzer, it seems that 250 MHz is correct (at least for the Raspberry Pi Zero I use).

void i2c_set_clkstr(uint16_t clkstr)

This function sets the clock stretch timeout (or delay). This means that the master will wait clkstr cycles after the rising clock edge for the slave to respond. After this the timeout flag is set. This can often be left at reset value 0x40.

void i2c_start(void)

Starts the BSC controller and clears the flag register.

void i2c_stop(void)

Disables the BSC controller.

void i2c_write_byte(uint8_t byte)

Write a byte of data.

uint8_t i2c_read_byte(void)

This function receives a byte of data and returns it.

void i2c_write_data(const uint8_t *data, uint16_t length)

This function writes length bytes of data pointed to by data.

void i2c_read_data(uint8_t *data, uint16_t length)

This function receives length bytes of data and writes them to the array data.

void i2c_write_register(uint8_t reg, uint8_t data)

This function writes to bytes of data. First reg and then data.

Note

You cannot use two calls to i2c_write_byte() instead of this function because this is only one transmission, while two times i2c_write_byte() would be two different transmissons.

uint8_t i2c_read_register(uint8_t reg)

In contrast to i2c_write_register() you can use a call to i2c_write_byte() and to i2c_read_byte(). This is because I2C needs to make two transmissions anyway to change the read / write bit.

Useful Values

I2C_FIFO_SIZE The size of the I2C FIFO
I2C_C_I2CEN Enable I2C
I2C_C_ST Start transfer
I2C_C_CLEAR Clear the FIFO
I2C_C_READ This transfer read from the slave
I2C_S_RXS FIFO can be read
I2C_S_TXD FIFO is full
I2C_S_DONE Transfer done