Using I2C Master Mode in FreeRTOS Print

 

This application note explains how to use the STM32H7 I2C Master mode in the FreeRTOS demo application.


Understanding I2C Master Mode Interfaces

FreeRTOS I2C Master Mode Implementation

The FreeRTOS BSP provides a device driver for the I2C Master mode operation. The driver is configured (enabled / disabled) at the BSP build time, using the HAL_I2C_MODULE_ENABLED configuration option, defined in the stm32h7xx_hal_conf.h file.


FreeRTOS I2C Master Mode C-Binding API

The I2C Master Mode driver implements the following C-binding API:

Function Description Comments
I2C_HandleTypeDef * i2c_init(uint32_t bus, uint32_t freq)
Initialize a specified I2C bus bus is the I2C interface (1 to 4 corresponding to the number of the I2C bus interface); freq is I2C bus frequency: 100 corresponding to 100KHz operation, 400 corresponding to 400KHz operation; returns the I2C interface handle or 0 in case of error
uint32_t i2c_read(I2C_HandleTypeDef * hi2c, uint16_t i2c_addr, uint16_t mode, uint16_t data_addr, uint8_t * data, uint16_t size)
Read a specified I2C device on a specified I2C interface mode defines how the data_addr parameter is interpreted, allowed values are: 0 - 8 bits address, 1 - 16 bits address; data_addr - address (offset) at specified i2c_addr; returns 0 or the I2C error code, which can be one of the following: 0x01 (BERR), 0x02 (ARLO), 0x04 (ACKF), 0x08 (OVR), 0x10 (DMA transfer error), 0x20 (timeout error), 0x40 (size management error); Implementation is interrupt-driven
uint32_t i2c_write(I2C_HandleTypeDef * hi2c, uint16_t i2c_addr, uint16_t mode, uint16_t data_addr, uint8_t * data, uint16_t size)
Write a specified I2C device on a specified I2C interface mode defines how the data_addr parameter is interpreted, allowed values are: 0 - 8 bits address, 1 - 16 bits address; data_addr - address (offset) at specified i2c_addr; returns 0 or the I2C error code, which can be one of the following: 0x01 (BERR), 0x02 (ARLO), 0x04 (ACKF), 0x08 (OVR), 0x10 (DMA transfer error), 0x20 (timeout error), 0x40 (size management error); Implementation is interrupt-driven
int i2c_fastmode_enable(I2C_HandleTypeDef * hi2c)
Switch a specified I2C bus to 400KHz operation
int i2c_fastmode_disable(I2C_HandleTypeDef * hi2c)
Switch a specified I2C bus to `100KHz operation


I2C Master Mode CLI Command

The FreeRTOS application implements the following I2C Master mode related CLI commands:

Command Description Comments
i2c_read bus i2c_addr:mode data_addr count
Read a specified I2C device on a specified I2C interface bus is the I2C interface (1 to 4 corresponding to the number of the I2C bus interface); mode is optional and defines how the data_addr parameter is interpreted, allowed values are: 0 - 8 bits address, 1 - 16 bits address; data_addr - address (offset) at specified i2c_addr
i2c_write bus i2c_addr:mode data_addr data
Write a specified I2C device on a specified I2C interface bus is the I2C interface (1 to 4 corresponding to the number of the I2C bus interface); mode is optional and defines how the data_addr parameter is interpreted, allowed values are: 0 - 8 bits address, 1 - 16 bits address; data_addr - address (offset) at specified i2c_addr
i2c_scan bus
Scan a I2C interface bus is the I2C interface (1 to 4 corresponding to the number of the I2C bus interface.) This commands writes an arbitrary value to each found I2C device, potentially resetting it to default state; if any of I2C devices had previously been configured by application code, it needs to be reconfigured after i2c_scan has been called


Validating I2C Master Operation

Scanning I2C Buses

Use the following step-wise procedure to scan the I2C buses:

  1. Scan I2C bus 1:

    CLI> i2c_scan 1
    Scanning........
    I2C1: 0x50 0x58 0x5d

  2. Scan I2C bus 4:

    CLI> i2c_scan 4
    Scanning........
    I2C4:

Reading I2C EEPRIOM

Use the following step-wise procedure to read the I2C EEPROM:

  1. From the FreeRTOS CLI, read 4 bytes from the EEPROM:
  2. CLI> i2c_read 1 50 14 4
    14: ff ff ff ff

  3. Update the 4 bytes of the EEPROM (the same offset that was just read in the previous command):

    CLI> i2c_write 1 50 14 0x1a2b3c4d
    Done

  4. Read the 4 bytes of the EEPROM back, confirm that the read data matches the written data:

    CLI> i2c_read 1 50 14 4
    14: 1a 2b 3c 4d

Reading Data from I2C Touch Controller

If your starter kit includes the LCD, use the following step-wise procedure to read the configured resolution from the I2C touch controller:

  1. Scan I2C bus 1:
  2. CLI> i2c_scan 1
    Scanning........
    I2C1: 0x14

  3. From the FreeRTOS CLI, read the configured X axis resolution from the I2C touch controller configuration register:
  4. CLI> i2c_read 1 14 8048 2
    8048: e0 01 // 480

  5. From the FreeRTOS CLI, read the configured Y axis resolution from the I2C touch controller configuration register:
  6. CLI> i2c_read 1 14 804a 2
    804a: 10 01 // 272

  7. Verify that the configured values are equal to the LCD resolution.

The configuration values are written by the I2C touch controller driver on start-up and it is recommended not to modify them at runtime.