Trying to interface the BMI088 IMU with an i2c multiplexer

@Middleware & OS I’m trying to interface the BMI088 IMU with an i2c multiplexer. The BMI088 has two different addresses for the accelerometer and gyroscope which makes it act like 2 different devices entirely. I have the mux on bus0 in my devicetree and I can address it just fine. I put the IMU on channel 2 of the mux and I have read that each channel on the mux is essentially a bus extension. I cannot find any specific information/examples on how to set up the individual BMI088 acc and gyro addresses on the mux channel in my device tree. Please, I'm making use of STM32 MCU. Could anyone reference any documentation or examples? Here's my i2c bus initializing code
/* Enable the I2C peripheral clock */
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
/* Configure the I2C pins */
GPIOB->MODER |= (GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1); // Set PB6 and PB7 as alternate function
GPIOB->OTYPER |= (GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7); // Set PB6 and PB7 as open-drain
GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7); // Set high speed for PB6 and PB7
/* Configure the I2C peripheral */
I2C1->CR1 &= ~I2C_CR1_PE; // Disable the I2C peripheral
I2C1->CR1 |= I2C_CR1_SWRST; // Software reset the I2C peripheral
I2C1->CR1 &= ~I2C_CR1_SWRST; // Clear the software reset bit
I2C1->CR2 = (uint32_t)400000; // Set the I2C clock frequency to 400 kHz
I2C1->CCR = (uint32_t)((SystemCoreClock + (I2C_SPEED * 2)) / (I2C_SPEED * 4)); // Set the I2C clock control register
I2C1->TRISE = (uint32_t)((SystemCoreClock / 1000000) + 1); // Set the maximum rise time
I2C1->OAR1 = (uint16_t)(0x5A << 1); // Set the I2C slave address to 0x5A (7-bit address)
I2C1->OAR1 |= I2C_OAR1_ADD0; // Set the address mode to 7-bit
I2C1->CR1 |= I2C_CR1_PE; // Enable the I2C peripheral
/* Enable the I2C peripheral clock */
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
/* Configure the I2C pins */
GPIOB->MODER |= (GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1); // Set PB6 and PB7 as alternate function
GPIOB->OTYPER |= (GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7); // Set PB6 and PB7 as open-drain
GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7); // Set high speed for PB6 and PB7
/* Configure the I2C peripheral */
I2C1->CR1 &= ~I2C_CR1_PE; // Disable the I2C peripheral
I2C1->CR1 |= I2C_CR1_SWRST; // Software reset the I2C peripheral
I2C1->CR1 &= ~I2C_CR1_SWRST; // Clear the software reset bit
I2C1->CR2 = (uint32_t)400000; // Set the I2C clock frequency to 400 kHz
I2C1->CCR = (uint32_t)((SystemCoreClock + (I2C_SPEED * 2)) / (I2C_SPEED * 4)); // Set the I2C clock control register
I2C1->TRISE = (uint32_t)((SystemCoreClock / 1000000) + 1); // Set the maximum rise time
I2C1->OAR1 = (uint16_t)(0x5A << 1); // Set the I2C slave address to 0x5A (7-bit address)
I2C1->OAR1 |= I2C_OAR1_ADD0; // Set the address mode to 7-bit
I2C1->CR1 |= I2C_CR1_PE; // Enable the I2C peripheral
Solution:
Also make sure to initialize the I2C multiplexer in your code. After selecting the mux channel, you'll need to address the BMI088's accelerometer and gyroscope accordingly.
Jump to solution
7 Replies
Marvee Amasi
Marvee Amasi5mo ago
Hi this your initialization code is a good starting point for you . Once you configure the device tree with the appropriate select-slave-addr values for each channel, you shouldn't need significant modifications to the core I2C communication logic itself , cus you might just need to adjust the slave address based on the selected channel during communication
UC GEE
UC GEE5mo ago
Ok Thanks @Marvee Amasi I will check it out
RED HAT
RED HAT5mo ago
@UC GEE It sounds like you're trying to set up the BMI088 IMU with an I2C multiplexer, which can be a bit tricky since the IMU has two different addresses. You’ll need to handle the addressing in your device tree by configuring the multiplexer and specifying the channels for the accelerometer and gyroscope separately. I don't have an exact example for your specific setup, but you can refer to how device trees handle I2C multiplexer configurations. Have you checked the STM32 documentation or forums for examples?
UC GEE
UC GEE5mo ago
No ...I have not check STM32 documentation or Forums @RED HAT ... But I will check it out as you have recommended.
UC GEE
UC GEE5mo ago
But please @RED HAT Besides the device tree configuration, are there any other aspects of the code that may need to be adjusted when using the BMI088 with an I2C multiplexer?
RED HAT
RED HAT5mo ago
@UC GEE you need to define the channels in your device tree by specifying each device under the appropriate mux channel. Here’s an example:
i2c1: i2c@40005400 {
mux {
compatible = "i2c-mux";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>; // I2C multiplexer address

channel0: chan0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;

bmi088_acc: accelerometer@18 {
compatible = "bosch,bmi088-acc";
reg = <0x18>; // BMI088 accelerometer address
};
};

channel1: chan1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;

bmi088_gyro: gyroscope@68 {
compatible = "bosch,bmi088-gyro";
reg = <0x68>; // BMI088 gyroscope address
};
};
};
};
i2c1: i2c@40005400 {
mux {
compatible = "i2c-mux";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>; // I2C multiplexer address

channel0: chan0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;

bmi088_acc: accelerometer@18 {
compatible = "bosch,bmi088-acc";
reg = <0x18>; // BMI088 accelerometer address
};
};

channel1: chan1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;

bmi088_gyro: gyroscope@68 {
compatible = "bosch,bmi088-gyro";
reg = <0x68>; // BMI088 gyroscope address
};
};
};
};
Ensure your mux node in the device tree matches your hardware setup. The addresses 0x18 and 0x68 are examples; you’ll need to use the correct addresses for your BMI088.
Solution
RED HAT
RED HAT5mo ago
Also make sure to initialize the I2C multiplexer in your code. After selecting the mux channel, you'll need to address the BMI088's accelerometer and gyroscope accordingly.
Want results from more Discord servers?
Add your server