The CYW20719 and CYW20735 provides one I2C compatible master interface to communicate serially with I2C slave devices.
The I2C module features includes support for:
- 7-bit addressing mode.
- Clock stretching as a master.
- 100 kHz (Standard Mode), 400 kHz (Fast Mode), 800 kHz (Proprietary), and 1 MHz (Fast Mode+) SCL clock frequencies.
- Multi-slave operation.
1. I2C Clock
The I2C clock SCL is provided by the master on the I2C bus. When the I2C module is in master mode, the serial clock generator generates the SCL clock from the transport clock of 24 MHz. The wiced_hal_i2c_set_speed() function allows you to set the clock rate of SCL to any of the speeds listed in the introduction. The I2C block has 64 bytes of RX and TX FIFO for the transaction buffer, and thus each I2C transaction payload can be a maximum of 64 bytes.
Example frequencies for a 24-MHz system clock are given in the enum values description. The I2CM_SPEED_100KHz is set to 240 which is the dividing parameter, that is, when 24,000,000 divided by 240, it results in 100 kHz. Trying to use Multi-master will result in undefined behavior because the clocks from two or more masters will not be synchronized. Also, note that the proprietary 800 kHz mode is not expected to work on all I2C slaves. The wiced_hal_i2c_get_speed() function allows you to get the current clock frequency of the I2C block.
2. I2C Initialization
The I2C module registers are initialized by calling wiced_hal_i2c_init() from wiced_hal_i2c.h. This function call initializes the I2C driver and its private values. It is required to call the above function before using I2C as some modules can turn this off for power saving. This function call ensures that the clock signal to this hardware block is turned on with the default SCL clock frequency of 100 kHz. Therefore, the wiced_hal_i2c_set_speed() function must be called after the wiced_hal_i2c_init() function if you want to use a speed other than 100 kHz.
3. I2C Operations
The I2C Master module supports two modes of operations: Master write and Master Read. The modes are discussed in the following sections.
I2C Master Write
The wiced_hal_i2c_write() function writes data to the I2C hardware addressing a slave address. Although any arbitrary length of data may be written to the slave, atomic transactions greater than the hardware's capability are not possible and the data will be split into multiple transactions. This is a blocking call. The I2C module waits until the I2C bus is free and then, it generates a START condition, transmits the 7-bit slave address followed by a 0 for write cycle's address phase. If there is an acknowledge returned, the I2C master will then start to transmit the data.
I2C Master Read
The wiced_hal_i2c_read() function reads data into the given buffer from the I2C hardware addressing a particular slave address. This is a blocking call. The I2C module waits until the I2C bus is free. When the I2C bus is free, it generates a START condition, sends the slave address, and transfers a receive direction bit. It then generates an interrupt, and the first byte is received. The I2C Master will release the SDA line for the slave device to transmit data only if it receives an acknowledge bit after it transmits the direction bit.
I2C Master Combined Write and then Read
The wiced_hal_i2c_combined_read() function executes a write transaction followed by a read transaction with a repeated start condition between the first and the second. In the first transaction, data is written to the slave address and after the repeated start, data is read from the slave in the second transaction. This operation is usually used to read a slave device's registers with the first write transaction specifying the slave's register address that needs to be read.
4. I2C Bus Error
If the I2C master read or write operation is successful, the corresponding function will return I2CM_SUCCESS. When an attempted I2C operation fails because of no acknowledgement from the slave, I2CM_OP_FAILED is returned and the SDA and SCL lines are released (the STOP condition is not transmitted). I2CM_BUSY is returned when the I2C hardware block is busy with another transaction.