SyterKit 0.4.0.x
SyterKit is a bare-metal framework
Loading...
Searching...
No Matches
Macros | Functions
sys-i2c.c File Reference

System I2C (Inter-Integrated Circuit) driver for Allwinner (sunxi) platforms. More...

#include <io.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <types.h>
#include <timer.h>
#include <common.h>
#include <log.h>
#include <sys-clk.h>
#include "reg-ncat.h"
#include "sys-i2c.h"
Include dependency graph for sys-i2c.c:

Macros

#define I2C_WRITE   0
 I2C write transaction type.
 
#define I2C_READ   1
 I2C read transaction type.
 
#define I2C_OK   0
 I2C operation successful status.
 
#define I2C_NOK   1
 I2C operation failed general status.
 
#define I2C_NACK   2
 I2C operation failed with NACK status.
 
#define I2C_NOK_LA   3 /* Lost arbitration */
 I2C operation failed with lost arbitration status.
 
#define I2C_NOK_TOUT   4 /* time out */
 I2C operation failed with timeout status.
 
#define I2C_START_TRANSMIT   0x08
 I2C status code for successful start condition transmission.
 
#define I2C_RESTART_TRANSMIT   0x10
 I2C status code for successful repeated start condition transmission.
 
#define I2C_ADDRWRITE_ACK   0x18
 I2C status code for successful slave address write with ACK.
 
#define I2C_ADDRREAD_ACK   0x40
 I2C status code for successful slave address read with ACK.
 
#define I2C_DATAWRITE_ACK   0x28
 I2C status code for successful data write with ACK.
 
#define I2C_READY   0xf8
 I2C status code for bus ready state.
 
#define I2C_DATAREAD_NACK   0x58
 I2C status code for successful data read with NACK.
 
#define I2C_DATAREAD_ACK   0x50
 I2C status code for successful data read with ACK.
 

Functions

static int32_t sunxi_i2c_send_byteaddr (sunxi_i2c_t *i2c_dev, uint32_t byteaddr)
 Send a byte address over I2C.
 
static int32_t sunxi_i2c_send_start (sunxi_i2c_t *i2c_dev)
 Generate I2C start condition.
 
static int32_t sunxi_i2c_send_slave_addr (sunxi_i2c_t *i2c_dev, uint32_t saddr, uint32_t rw)
 Send I2C slave address with read/write bit.
 
static int32_t sunxi_i2c_send_restart (sunxi_i2c_t *i2c_dev)
 Generate I2C repeated start condition.
 
static int32_t sunxi_i2c_stop (sunxi_i2c_t *i2c_dev)
 Generate I2C stop condition.
 
static int32_t sunxi_i2c_get_data (sunxi_i2c_t *i2c_dev, uint8_t *data_addr, uint32_t data_count)
 Receive data from I2C device.
 
static int32_t sunxi_i2c_send_data (sunxi_i2c_t *i2c_dev, uint8_t *data_addr, uint32_t data_count)
 Sends data to the I2C device.
 
static int _sunxi_i2c_read (sunxi_i2c_t *i2c_dev, uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
 sunxi_i2c read function
 
static int _sunxi_i2c_write (sunxi_i2c_t *i2c_dev, uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
 sunxi_i2c write function
 
int sunxi_i2c_write (sunxi_i2c_t *i2c_dev, uint8_t addr, uint32_t reg, uint8_t data)
 Write a single byte to I2C device register.
 
int sunxi_i2c_read (sunxi_i2c_t *i2c_dev, uint8_t addr, uint32_t reg, uint8_t *data)
 Read a single byte from I2C device register.
 
static void sunxi_i2c_bus_reset (sunxi_i2c_t *i2c_dev)
 Resets the I2C bus for the specified I2C device.
 
static void sunxi_i2c_set_clock (sunxi_i2c_t *i2c_dev)
 Configures the clock settings for the specified I2C device.
 
static void sunxi_i2c_bus_clk_open (sunxi_i2c_t *i2c_dev)
 Opens the clock for the specified I2C device.
 
static void sunxi_i2c_bus_en (sunxi_i2c_t *i2c_dev)
 Enables the I2C bus for the specified I2C device.
 
void sunxi_i2c_init (sunxi_i2c_t *i2c_dev)
 Initialize I2C controller and bus.
 

Detailed Description

System I2C (Inter-Integrated Circuit) driver for Allwinner (sunxi) platforms.

This file implements I2C communication functionality for Allwinner SoCs, supporting standard I2C master operations including initialization, read/write transactions, clock configuration, and bus reset. The driver handles both 100kHz (standard) and 400kHz (fast) I2C speeds.

Macro Definition Documentation

◆ I2C_ADDRREAD_ACK

#define I2C_ADDRREAD_ACK   0x40

I2C status code for successful slave address read with ACK.

◆ I2C_ADDRWRITE_ACK

#define I2C_ADDRWRITE_ACK   0x18

I2C status code for successful slave address write with ACK.

◆ I2C_DATAREAD_ACK

#define I2C_DATAREAD_ACK   0x50

I2C status code for successful data read with ACK.

◆ I2C_DATAREAD_NACK

#define I2C_DATAREAD_NACK   0x58

I2C status code for successful data read with NACK.

◆ I2C_DATAWRITE_ACK

#define I2C_DATAWRITE_ACK   0x28

I2C status code for successful data write with ACK.

◆ I2C_NACK

#define I2C_NACK   2

I2C operation failed with NACK status.

◆ I2C_NOK

#define I2C_NOK   1

I2C operation failed general status.

◆ I2C_NOK_LA

#define I2C_NOK_LA   3 /* Lost arbitration */

I2C operation failed with lost arbitration status.

◆ I2C_NOK_TOUT

#define I2C_NOK_TOUT   4 /* time out */

I2C operation failed with timeout status.

◆ I2C_OK

#define I2C_OK   0

I2C operation successful status.

◆ I2C_READ

#define I2C_READ   1

I2C read transaction type.

◆ I2C_READY

#define I2C_READY   0xf8

I2C status code for bus ready state.

◆ I2C_RESTART_TRANSMIT

#define I2C_RESTART_TRANSMIT   0x10

I2C status code for successful repeated start condition transmission.

◆ I2C_START_TRANSMIT

#define I2C_START_TRANSMIT   0x08

I2C status code for successful start condition transmission.

◆ I2C_WRITE

#define I2C_WRITE   0

I2C write transaction type.

Function Documentation

◆ _sunxi_i2c_read()

static int _sunxi_i2c_read ( sunxi_i2c_t i2c_dev,
uint8_t  chip,
uint32_t  addr,
int  alen,
uint8_t buffer,
int  len 
)
static

sunxi_i2c read function

Parameters
i2c_devPointer to the sunxi_i2c controller device structure
chipDevice address
addrRegister to be read from in the device
alenLength of the register address
bufferBuffer to store the read data
lenLength of the data to be read
Returns
int Number of status

Internal I2C read function

Performs a complete I2C read transaction, including start, address, register, and data transfer.

Parameters
i2c_devPointer to the I2C device structure
chipDevice address
addrRegister address to read from
alenLength of the register address (1-3 bytes)
bufferBuffer to store read data
lenNumber of bytes to read
Returns
I2C_OK on success, negative error code on failure

◆ _sunxi_i2c_write()

static int _sunxi_i2c_write ( sunxi_i2c_t i2c_dev,
uint8_t  chip,
uint32_t  addr,
int  alen,
uint8_t buffer,
int  len 
)
static

sunxi_i2c write function

Parameters
i2c_devPointer to the sunxi_i2c controller device structure
chipDevice address
addrRegister to be read/written in the device
alenLength of the register address
bufferData to be written/read
lenLength of the data
Returns
int Number of status

Internal I2C write function

Performs a complete I2C write transaction, including start, address, register, and data transfer.

Parameters
i2c_devPointer to the I2C device structure
chipDevice address
addrRegister address to write to
alenLength of the register address (1-3 bytes)
bufferBuffer containing data to write
lenNumber of bytes to write
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_bus_clk_open()

static void sunxi_i2c_bus_clk_open ( sunxi_i2c_t i2c_dev)
inlinestatic

Opens the clock for the specified I2C device.

This function de-asserts the reset signal for the I2C clock and enables the clock gating. It first de-asserts the reset, then clears the clock gating bit, waits for a brief period, and finally re-enables the clock.

Parameters
i2c_devPointer to the I2C device structure that contains the clock control registers' base address and offsets.
Note
The function uses a delay to ensure that the clock gating changes take effect before proceeding.

◆ sunxi_i2c_bus_en()

static void sunxi_i2c_bus_en ( sunxi_i2c_t i2c_dev)
inlinestatic

Enables the I2C bus for the specified I2C device.

This function sets the control register to enable the I2C bus and clears any error flags by writing to the error flag register.

Parameters
i2c_devPointer to the I2C device structure that contains the base address for the I2C hardware registers.
Note
This function should be called before performing any I2C transactions to ensure that the bus is enabled.

◆ sunxi_i2c_bus_reset()

static void sunxi_i2c_bus_reset ( sunxi_i2c_t i2c_dev)
static

Resets the I2C bus for the specified I2C device.

This function attempts to reset the I2C control by toggling the SCL and SDA lines until the bus is idle. It first checks the control register to determine if a reset is needed, and then it performs the necessary toggling of the lines.

Parameters
i2c_devPointer to the I2C device structure that contains the base address for the I2C hardware registers.
Note
The function uses a timeout mechanism to prevent infinite loops in case the reset process fails.
Warning
Ensure that this function is called when the I2C device is in a known state to avoid unintended behavior.

◆ sunxi_i2c_get_data()

static int32_t sunxi_i2c_get_data ( sunxi_i2c_t i2c_dev,
uint8_t data_addr,
uint32_t  data_count 
)
static

Receive data from I2C device.

Receives multiple bytes of data from an I2C device, handling ACK/NACK appropriately.

Parameters
i2c_devPointer to the I2C device structure
data_addrBuffer to store received data
data_countNumber of bytes to receive
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_init()

void sunxi_i2c_init ( sunxi_i2c_t i2c_dev)

Initialize I2C controller and bus.

Initializes the I2C controller by configuring GPIO pins, enabling clocks, resetting the bus, setting clock frequency, and enabling the I2C controller.

Parameters
i2c_devPointer to the I2C device structure containing configuration parameters

◆ sunxi_i2c_read()

int sunxi_i2c_read ( sunxi_i2c_t i2c_dev,
uint8_t  addr,
uint32_t  reg,
uint8_t data 
)

Read a single byte from I2C device register.

sunxi_i2c read function

Reads a single byte from a specified register on an I2C device.

Parameters
i2c_devPointer to the I2C device structure
addrI2C device address
regRegister address to read from
dataPointer to store the read byte
Returns
I2C_OK on success, I2C_NOK if I2C controller is not initialized

◆ sunxi_i2c_send_byteaddr()

static int32_t sunxi_i2c_send_byteaddr ( sunxi_i2c_t i2c_dev,
uint32_t  byteaddr 
)
static

Send a byte address over I2C.

Sends a single byte address to the I2C device and waits for acknowledgment.

Parameters
i2c_devPointer to the I2C device structure
byteaddrByte address to send
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_send_data()

static int32_t sunxi_i2c_send_data ( sunxi_i2c_t i2c_dev,
uint8_t data_addr,
uint32_t  data_count 
)
static

Sends data to the I2C device.

This function sends a specified number of bytes of data to the I2C device. It writes data to the data register and waits for the acknowledgment from the device for each byte sent. If a timeout occurs while waiting for acknowledgment, the function will return an error code.

Parameters
i2c_devPointer to the I2C device structure containing the device's configuration and register base address.
data_addrPointer to the data buffer that contains the data to be sent.
data_countThe number of bytes to send from the data buffer.
Returns
I2C_OK on success, or a negative error code on failure. Possible error codes include:
  • I2C_NOK_TOUT: Timeout occurred while waiting for the I2C device to acknowledge data.

◆ sunxi_i2c_send_restart()

static int32_t sunxi_i2c_send_restart ( sunxi_i2c_t i2c_dev)
static

Generate I2C repeated start condition.

Generates a repeated start condition on the I2C bus to change operation mode.

Parameters
i2c_devPointer to the I2C device structure
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_send_slave_addr()

static int32_t sunxi_i2c_send_slave_addr ( sunxi_i2c_t i2c_dev,
uint32_t  saddr,
uint32_t  rw 
)
static

Send I2C slave address with read/write bit.

Transmits the slave address along with read/write bit and waits for acknowledgment.

Parameters
i2c_devPointer to the I2C device structure
saddrSlave device address
rwRead (1) or Write (0) operation
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_send_start()

static int32_t sunxi_i2c_send_start ( sunxi_i2c_t i2c_dev)
static

Generate I2C start condition.

Generates a start condition on the I2C bus to initiate communication.

Parameters
i2c_devPointer to the I2C device structure
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_set_clock()

static void sunxi_i2c_set_clock ( sunxi_i2c_t i2c_dev)
static

Configures the clock settings for the specified I2C device.

This function calculates and sets the appropriate clock divider values based on the desired I2C speed and the source clock frequency. It finds suitable values for clk_m and clk_n, and adjusts the clock control register accordingly.

Parameters
i2c_devPointer to the I2C device structure that contains the base address for the I2C hardware registers and clock configuration parameters.
Note
The function adjusts the clock settings to ensure the I2C speed is achievable with the given source clock. It handles both 100kHz and 400kHz configurations.
Warning
Ensure that the parent clock frequency is set correctly before calling this function to avoid incorrect clock settings.

◆ sunxi_i2c_stop()

static int32_t sunxi_i2c_stop ( sunxi_i2c_t i2c_dev)
static

Generate I2C stop condition.

Generates a stop condition on the I2C bus to terminate communication.

Parameters
i2c_devPointer to the I2C device structure
Returns
I2C_OK on success, negative error code on failure

◆ sunxi_i2c_write()

int sunxi_i2c_write ( sunxi_i2c_t i2c_dev,
uint8_t  addr,
uint32_t  reg,
uint8_t  data 
)

Write a single byte to I2C device register.

sunxi_i2c write function

Writes a single byte to a specified register on an I2C device.

Parameters
i2c_devPointer to the I2C device structure
addrI2C device address
regRegister address to write to
dataByte value to write
Returns
I2C_OK on success, I2C_NOK if I2C controller is not initialized