This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Thingy52 Zephyr RTOS and Sensor MPU6060 sample not working

Hi,

I have been using Thingy52 devices for experiments for quite a while now. I would like now to use Zephyr therefore I played with various sensor samples provided with Zephyr, they all worked out of the box, expect the MPU6050 did not with the following error : 

[00000222] <err> i2c_nrfx_twim: Error 195952641 occurred for message 0

I am very aware that the Thingy52 comes with invensense MPU9250 and not MPU6050 but I do believe the basic registers should be the same. Also within Thingy52 the MPU9250 is connected to the i2C through a GPIO expander.

To run the MPU6050 sample on Thingy52 I did the following:

- update the zephyr/board/arm/thingy52_nrf52832/thingy52_nrf52832.dts (I could have used overaly but I was not sure …) to include the following at the end of the file

&i2c0 {
 compatible = "nordic,nrf-twim";
 status = "okay";
 clock-frequency = <I2C_BITRATE_FAST>;
 sda-pin = <7>;
 scl-pin = <8>;
 mpu6050: mpu6050@68 {
  compatible = "invensense,mpu6050";
  reg = <0x68>;
  status = "okay";
  label = "MPU6050";
  int-gpios = <&gpio0 06 GPIO_ACTIVE_HIGH>;
 };
};

- update the prf.conf to include :

CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_MPU6050=y
CONFIG_MPU6050_TRIGGER_NONE=y
CONFIG_I2C_NRFX=y
CONFIG_I2C_2=y
CONFIG_I2C_2_NRF_TWIM=y
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=2
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
CONFIG_LOG_MODE_NO_OVERFLOW=y
CONFIG_LOG_PRINTK=y
CONFIG_LOG_PRINTK_MAX_STRING_LENGTH=256
CONFIG_LOG_BUFFER_SIZE=4096
CONFIG_LOG_BACKEND_RTT_MESSAGE_SIZE=256
CONFIG_LOG_STRDUP_BUF_COUNT=64
CONFIG_LOG_STRDUP_MAX_STRING=64
CONFIG_LOG_BACKEND_SHOW_COLOR=n
CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP=n
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1024
CONFIG_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n
I searched the web for many hours and tried different thing without much success. I would be grateful for any help. Thank you so much.
  • Hi,

    I did a quick test here, and I was able to reproduce the issue you describe.

    Error 195952641, is the same as NRFX_ERROR_DRV_TWI_ERR_ANACK, so for some reason the address not acknowledged. I will take a closer look, and see if there is anything in Zephyr that is done differently than in Thingy:52 SDK that can explain this.

  • Hi,
    Thank you for coming back.
    In the meantime I did continue the investigation and finally managed to get it to work. The solution as it stands today is as follow:
    0. include in thing52_nrf52832 dts definition, inside  &i2c0 {:  (the main.c need to reflect the change inthe label MPU6050 vs MPU9250)
    mpu9250: mpu9250@68 {
                    compatible = "invensense,mpu6050";
                    reg = <0x68>;
                    label = "MPU9250";
                    status = "okay";
                    int-gpios = <&gpio0 06 GPIO_ACTIVE_HIGH>;
          };
    1. the MPU9250 inside the Thingy52 is NOT powered by default by the analog switch controlled by semtech sx1509, therefore the thingy52 board (zephyr\boards\arm\thingy52_nrf52832\board.c) file need to be updated to do that
    /* SME start : powering up Thingy52 MPU9250 (analog switch) */
    #define MPU6050_VDD_PWR_CTRL_GPIO_PIN 8
    static const struct pwr_ctrl_cfg mpu6050_vdd_pwr_ctrl_cfg = {
     .port = DT_LABEL(DT_INST(0, semtech_sx1509b)),
     .pin = MPU6050_VDD_PWR_CTRL_GPIO_PIN,
    };
    DEVICE_INIT(mpu6050_vdd_pwr_ctrl_init, "", pwr_ctrl_init, NULL,
         &mpu6050_vdd_pwr_ctrl_cfg, POST_KERNEL,
         CONFIG_BOARD_MPU6050_VDD_PWR_CTRL_INIT_PRIORITY);
    /* end */

    2. The initialisation function within (zephyr\boards\arm\thingy52_nrf52832\board.c) works for MPU6050 but not MPU9250, for some reasons MPU9250 needs more time to ramp up, so I have change the 1 ms to 100 ms (not perfecft ..)
    /* SME start : powering up Thingy52 MPU9250 (analog switch) */
    static int mpu9250_pwr_ctrl_init(struct device *dev)
    {
     const struct pwr_ctrl_cfg *cfg = dev->config_info;
     struct device *gpio;
     gpio = device_get_binding(cfg->port);
     if (!gpio) {
      printk("Could not bind device \"%s\"\n", cfg->port);
      return -ENODEV;
     }
     gpio_pin_configure(gpio, cfg->pin, GPIO_OUTPUT_HIGH);
     k_sleep(K_MSEC(100)); /* Wait for the rail to come up and stabilize */
     return 0;
    }
    /* end */
    3. When the MPU9250 starts it "whoami" ID is set by default to "0x71" (though it is clearly written in invensense MPU9250 spec, but still confusing) which confuses the current zephyr MPU6050 driver.
    It is only after few cycle that MPU9250 set its whoami to 0x68!! Why did invensense did not set it to 0x68 in the first place, is beyond me.
    Anyway, the int mpu6050_init(struct device *dev) function within
    zephyr\drivers\sensor\mpu6050\mpu6050.c need to be changed to account for the initialisation of the MPU9250:
    Replacing in int mpu6050_init(struct device *dev) :
    if (id != MPU6050_CHIP_ID) {
      LOG_ERR("Invalid chip ID.");
      return -EINVAL;
     }
    with something like:
    /* accounting for MPU6050 and MPU9250 initialisation behaviour */
    if ( (id != MPU6050_CHIP_ID) && (id ! 0x71) {
      LOG_ERR("Invalid chip ID.");
      return -EINVAL;
     }

    Though MPU9250 is based on MPU6050 (well rather MPU6500) they are subtle difference (beyond the obvious addtion of AK magnetometer) clearly there is a need for a proper MPU9250 driver within Zephyr with include invensense motion driver library (quaternion, fusion, …) and DMP functionalities. While at it drivers for the new generation of motion sensors the like of ICM29848 or Bosch Sensortec BHI270, etc.

Related