Notes on I2C Programming for ESP32
I’m new to programming the ESP32 and I want to use the I2C peripheral to interface with the Hillcrest BNO080 sensor hub.
General Stuff
The ESP32 Technical Reference Manual has hardware architecture and register level information.
The esp-idf code base doesn’t seem to have any i2c driver. There are header files that give access to the I2C peripheral registers, though. These are detailed in “Findings in esp-idf” below.
Findings in esp-idf
in components/esp32/include/soc/i2c_struct.h, a structure is defined that maps onto the I2C peripheral. Two instances of this are declared, I2C0 and I2C1. And components/esp32/ld/esp32.peripherals.ld contains the lines:
PROVIDE ( I2C0 = 0x3ff53000 );
PROVIDE ( I2C1 = 0x3ff67000 );
So I think I should be able to access the peripherals from C with statements like:
I2C0.int_clr.rx_rec_full = 1; // clear the interrupt
if (I2C0.status_reg.bus_busy) ...
There is also a file components/esp32/include/soc/i2c_reg.h. It has defines such as
#define I2C_INT_STATUS_REG(i) (REG_I2C_BASE(i) + 0x002c)
...
/* I2C_BUS_BUSY : RO ;bitpos:[4] ;default: 1'b0 ; */
/*description: 1:I2C bus is busy transferring data. 0:I2C bus is in idle state.*/
#define I2C_BUS_BUSY (BIT(4))
So I could also write code like:
if (I2C_INT_STATUS_REG(0) & I2C_BUS_BUSY) ...
Why they provide support for both styles, I don’t know.
The _reg.h files are used extensively in the ESP-IDF code base. The _struct.h are only used in 6 ESP-IDF source files.
So, yeah, it looks like I have to write register-level code to use the I2C bus.
Steps for BNO080 driver
System Initialization
Overall initialization sequence:
- Configure I/O Mux
- Enable I2C peripheral
- Configure I2C peripheral for Master operation
- Enable INTN GPIO pin for interrupt use
- Enable interrupt on INTN
Writing I2C
- Initiate operation to be processed by interrupts?
- Start generation
- Send address
- Send data
- Stop generation
Reading I2C
- Initiate operation to be processed by interrupts?
- Start generation
- Send address
- Read data
- Stop generation
Detecting INTN
- Configure I/O Mux
- TBD
Controlling GPIO lines
- Configure I/O Mux
- TBD
Supporting modules
Write drivers to provide higher level access to features:
- I2C master
- GPIO output
- GPIO input with interrupt
- (SPI master)
- (PWM generation for BLDC control)
- (PWM generation for R/C servo)