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:
Scan I2C bus 1:
CLI> i2c_scan 1 Scanning........ I2C1: 0x50 0x58 0x5d
Scan I2C bus 4:
CLI> i2c_scan 4 Scanning........ I2C4:
Reading I2C EEPRIOM
Use the following step-wise procedure to read the I2C EEPROM:
From the FreeRTOS CLI, read 4 bytes from the EEPROM:
CLI> i2c_read 1 50 14 4 14: ff ff ff ff
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
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:
Scan I2C bus 1:
CLI> i2c_scan 1 Scanning........ I2C1: 0x14
From the FreeRTOS CLI, read the configured X axis resolution from the I2C touch controller configuration register:
CLI> i2c_read 1 14 8048 2 8048: e0 01 // 480
From the FreeRTOS CLI, read the configured Y axis resolution from the I2C touch controller configuration register:
CLI> i2c_read 1 14 804a 2 804a: 10 01 // 272
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.