Hi I am currently working on a project which requires interfacing BMG250 with ESP32. I am currently using ESP-IDF. I am stuck at the initialization of the bmg250. I browsed the API for BMI160 and I notice major differences. It seems like there are missing parts on the API provided at https://github.com/BoschSensortec/BMG250-API. I have tried accessing the BMG250 using the i2c_tools example for ESP-IDF API Reference. I was able to detect the I2C address (0x68), read the default of values of some registers as well as write on some registers. Hence, I already ruled out the hardware side (connections from esp32 to bmg250 module) from the probable causes of may failed bmg250 initialization. See figure below. Here's my code for your review. #include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/i2c.h" #include "sdkconfig.h" #include "bmg250.h" #include "bmg250_defs.h" //static const char *TAG = "gyro"; #define _I2C_NUMBER(num) I2C_NUM_##num #define I2C_NUMBER(num) _I2C_NUMBER(num) #define I2C_MASTER_SCL_IO 19 /*!< gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO 18 /*!< gpio number for I2C master data */ #define I2C_MASTER_NUM 0 /*!< I2C port number for master dev */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define ESP_SLAVE_ADDR 0x68 /*!< ESP32 slave address, you can set any 7bit value */ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */ #define NACK_VAL 0x1 /*!< I2C nack value */ esp_err_t i2c_master_read_slave_reg(uint8_t i2c_addr, uint8_t i2c_reg, uint8_t* data_rd, size_t size) { if (size == 0) { return ESP_OK; } i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( i2c_addr << 1 ), ACK_CHECK_EN); i2c_master_write_byte(cmd, i2c_reg, ACK_CHECK_EN); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( i2c_addr << 1 ) | READ_BIT, ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) { i2c_master_read_slave_reg(i2c_addr, reg_addr, reg_data, length); /* Implement the I2C read routine according to the target machine. */ return -1; } esp_err_t i2c_master_write_slave_reg(uint8_t i2c_addr, uint8_t i2c_reg, uint8_t* data_wr, uint16_t size) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( i2c_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, i2c_reg, ACK_CHECK_EN); i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } int8_t i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) { i2c_master_write_slave_reg(i2c_addr, reg_addr, reg_data, length); /* Implement the I2C write routine according to the target machine. */ return -1; } void i2c_master_init(void) { i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_io_num = I2C_MASTER_SCL_IO, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ }; if(i2c_param_config(I2C_MASTER_NUM, &conf) != ESP_OK) { printf("\nError configuring I2C\n"); } else { printf("\nSuccessful configuring I2C\n"); } if(i2c_driver_install(I2C_MASTER_NUM, // i2c port 1 I2C_MODE_MASTER, // master mode 0, // does not need rx buffer 0, // does not need tx buffer 0) != ESP_OK) { printf("\nError installing I2C driver!\n"); } else { printf("\nSuccessful installing I2C driver\n"); } } void print_rslt(const char api_name[], int8_t rslt) { if (rslt != BMG250_OK) { printf("%s\t", api_name); if (rslt == BMG250_E_NULL_PTR) { printf("Error [%d] : Null pointer error\r\n", rslt); } else if (rslt == BMG250_E_COM_FAIL) { printf("Error [%d] : Bus communication failed\r\n", rslt); } else if (rslt == BMG250_E_INVALID_TEMPERATURE) { printf("Error [%d] : Invalid Temperature\r\n", rslt); } else if (rslt == BMG250_E_DEV_NOT_FOUND) { printf("Error [%d] : Device not found\r\n", rslt); } else { /* For more error codes refer "*_defs.h" */ printf("Error [%d] : Unknown error code\r\n", rslt); } } } void delay_ms(uint32_t period_ms) { //vTaskDelay(period_ms / portTICK_RATE_MS); } void i2c_gyro_task(void* arg) { struct bmg250_dev gyro; struct bmg250_cfg gyro_cfg; struct bmg250_sensor_data gyro_data; //gyro.chip_id = BMG250_CHIP_ID; gyro.delay_ms = delay_ms; gyro.dev_id = BMG250_I2C_ADDR; gyro.intf = BMG250_I2C_INTF; gyro.read = i2c_reg_read; gyro.write = i2c_reg_write; gyro.power_mode = BMG250_GYRO_NORMAL_MODE; int8_t rslt = BMG250_OK; rslt = bmg250_init(&gyro); print_rslt(" bmg250_init status", rslt); rslt = bmg250_get_sensor_settings(&gyro_cfg, &gyro); print_rslt(" bmg250_get_sensor_settings status ", rslt); gyro_cfg.odr = BMG250_ODR_100HZ; gyro_cfg.range = BMG250_RANGE_1000_DPS; gyro_cfg.bw = BMG250_BW_NORMAL_MODE; rslt = bmg250_set_sensor_settings(&gyro_cfg, &gyro); print_rslt(" bmg250_set_sensor_settings status ", rslt); while (1) { rslt = bmg250_get_sensor_data(BMG250_DATA_TIME_SEL, &gyro_data, &gyro); printf("Gyro data X: %d \t Y: %d Z: %d \t Sensor-time : %zu\n", gyro_data.x, gyro_data.y, gyro_data.z, gyro_data.sensortime); gyro.delay_ms(10); } } void app_main(void) { i2c_master_init(); xTaskCreate(i2c_gyro_task, "i2c_gyro_task_0", 1024 * 2, (void* ) 0, 10, NULL); ======================================================================================================== Here's the sample output from the serial monitor of the esp32 I (0) cpu_start: App cpu up. I (245) heap_init: Initializing. RAM available for dynamic allocation: I (252) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (258) heap_init: At 3FFB28F8 len 0002D708 (181 KiB): DRAM I (264) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (271) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (277) heap_init: At 4008B234 len 00014DCC (83 KiB): IRAM I (283) cpu_start: Pro cpu start user code I (302) spi_flash: detected chip: generic I (302) spi_flash: flash io: dio W (302) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header. I (313) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. Successful configuring I2C Successful installing I2C driver bmg250_init status Error [-3] : Device not found bmg250_get_sensor_settings status Error [-2] : Bus communication failed bmg250_set_sensor_settings status Error [-2] : Bus communication failed Gyro data X: 80 Y: 16379 Z: 0 Sensor-time : 0 Gyro data X: 80 Y: 16379 Z: 0 Sensor-time : 0 Gyro data X: 80 Y: 16379 Z: 0 Sensor-time : 0 Can you please provide insights or point out problems with my code. Thank you very much
... View more