sparkfun / SparkFun_ICM-20948_ArduinoLibrary

Arduino support for ICM_20948 w/ portable C backbone
Other
160 stars 69 forks source link

Unable to set full-scale mode #134

Closed LukeDeWaal closed 9 months ago

LukeDeWaal commented 9 months ago

Unable to set full-scale mode

Full-Scale registers reset themselves instantaneously. I thought it was a delay problem, as with #8, but no matter the delay, it does not work.

Your workbench

Steps to reproduce

Code is shown below

Expected behaviour

Initialize DMP

Actual behaviour

Full-scale mode registers fail to be set

2023/12/28-16:42:53  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 1 / 10
2023/12/28-16:42:54  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 2 / 10
2023/12/28-16:42:55  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 3 / 10
2023/12/28-16:42:56  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 4 / 10
2023/12/28-16:42:57  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 5 / 10
2023/12/28-16:42:58  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 6 / 10
2023/12/28-16:42:59  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 7 / 10
2023/12/28-16:43:00  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 8 / 10
2023/12/28-16:43:01  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 9 / 10
2023/12/28-16:43:02  WARN  ICM_20948_wrappers.c            :0173:       Failed to set full-scale mode: 10 / 10
2023/12/28-16:43:03  ERROR ICM_20948_wrappers.c            :0174:       Failed to set full-scale mode
2023/12/28-16:43:03  ERROR pru_manager_thread.c              :0083:       ICM20948 DMP init failed

I2C signals

image

image

C Wrapper Code:

int icm20948_startupDefault(ICM_20948_Device_t* icm_dev, uint8_t minimal){
    int ret = 0;
    ICM_20948_Status_e res = ICM_20948_check_id(icm_dev);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "ICM20948 WHOAMI test failed\n")

    res = ICM_20948_sw_reset(icm_dev);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "ICM20948 SW Reset failed\n");

    usleep(50000);

    res = ICM_20948_sleep(icm_dev, false);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "ICM20948 failed to exit sleep mode\n");

    usleep(1000);

    res = ICM_20948_low_power(icm_dev, false);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "ICM20948 failed to exit low-power mode\n");

    usleep(1000);

    ret = icm20948_enable_magnetometer(icm_dev, minimal);
    if(ret != 0){
        return ret;
    }

    if(minimal){
        return 0;
    }

    res = ICM_20948_set_sample_mode(icm_dev, (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Continuous);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set sample mode\n");

    ICM_20948_fss_t FSS;
    FSS.a = gpm2;   // (ICM_20948_ACCEL_CONFIG_FS_SEL_e)
    FSS.g = dps250; // (ICM_20948_GYRO_CONFIG_1_FS_SEL_e)
    res = ICM_20948_set_full_scale(icm_dev, (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), FSS);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set full-scale mode\n");

    ICM_20948_dlpcfg_t dlpcfg;
    dlpcfg.a = acc_d473bw_n499bw;
    dlpcfg.g = gyr_d361bw4_n376bw5;
    res = ICM_20948_set_dlpf_cfg(icm_dev, (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), dlpcfg);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set DLP CFG\n");

    res = ICM_20948_enable_dlpf(icm_dev, ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr, false);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set Low-Pass Filters\n");

    return ret;
}

int icm20948_enable_magnetometer(ICM_20948_Device_t* icm_dev, uint8_t minimal){

    ICM_20948_Status_e res = ICM_20948_i2c_master_passthrough(icm_dev, false);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to disable master passthrough mode\n");
    usleep(1000);
    res = ICM_20948_i2c_master_enable(icm_dev, true);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to enable master mode\n");
    usleep(1000);

    // Mag Reset
    uint8_t data = 0x01;
    res = ICM_20948_i2c_master_single_w(icm_dev, (uint8_t)MAG_AK09916_I2C_ADDR, (uint8_t)AK09916_REG_CNTL3, &data);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to reset magnetometer\n");
    usleep(1000);

    uint8_t tries = 0;
    const uint8_t MAX_MAGNETOMETER_STARTS = 10;
    uint8_t WIA1 = 0, WIA2 = 0;

    while (tries < MAX_MAGNETOMETER_STARTS)
    {
        tries++;

        //See if we can read the WhoIAm register correctly
        res  = ICM_20948_i2c_master_single_r(icm_dev, MAG_AK09916_I2C_ADDR, AK09916_REG_WIA1, &WIA1);
        res |= ICM_20948_i2c_master_single_r(icm_dev, MAG_AK09916_I2C_ADDR, AK09916_REG_WIA2, &WIA2);
        uint16_t WIA = ((uint16_t)WIA1 << 8) | (WIA2);
        if (res == ICM_20948_Stat_Ok && (WIA == MAG_AK09916_WHO_AM_I))
            break; //WIA matched!

        BBBLOG(error, 1, NULL, "Failed to start Magnetometer: %u / %u\n", tries, MAX_MAGNETOMETER_STARTS);
        res = ICM_20948_i2c_master_reset(icm_dev); //Otherwise, reset the master I2C and try again
        BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to reset master mode\n");

        usleep(50000);
    }

    BBBLOG(error, tries == MAX_MAGNETOMETER_STARTS, return -1, "Failed to initialize Magnetometer\n");

    if(minimal){
        return 0;
    }

    AK09916_CNTL2_Reg_t reg;
    reg.MODE = AK09916_mode_cont_100hz;
    reg.reserved_0 = 0; // Make sure the unused bits are clear. Probably redundant, but prevents confusion when looking at the I2C traffic
    res  = ICM_20948_i2c_master_single_r(icm_dev, MAG_AK09916_I2C_ADDR, AK09916_REG_CNTL2, (uint8_t *)&reg);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set Magnetometer Settings\n");
    usleep(1000);
    res = ICM_20948_i2c_controller_configure_peripheral(icm_dev, 0, MAG_AK09916_I2C_ADDR, AK09916_REG_ST1, 9, true, true, false, false, false, 0);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to configure Magnetometer peripheral\n");
    usleep(1000);
    return 0;

}

int icm20948_initialize_DMP(ICM_20948_Device_t* icm_dev){
    ICM_20948_Status_e res = ICM_20948_i2c_controller_configure_peripheral(icm_dev, 0, MAG_AK09916_I2C_ADDR, AK09916_REG_RSV2, 10, true, true, false, true, true, 0);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to configure i2c peripheral 0\n");
    usleep(1000);

    res = ICM_20948_i2c_controller_configure_peripheral(icm_dev, 1, MAG_AK09916_I2C_ADDR, AK09916_REG_CNTL2, 1, false, true, false, false, false, AK09916_mode_single);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to configure i2c peripheral 1\n");
    usleep(100000);

    res = ICM_20948_set_bank(icm_dev, 3u);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set bank\n");
    usleep(10000);

    uint8_t mstODRcfg = 0x04;
    res = ICM_20948_execute_w(icm_dev, AGB3_REG_I2C_MST_ODR_CONFIG, &mstODRcfg, 1);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to execute write\n");
    usleep(100000);

    res = ICM_20948_set_clock_source(icm_dev, ICM_20948_Clock_Auto);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set clock source\n");
    usleep(100000);

    res = ICM_20948_set_bank(icm_dev, 0u);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set bank\n");
    usleep(1000);

    uint8_t pwrMgmt = 0x40;
    res = ICM_20948_execute_w(icm_dev, AGB0_REG_PWR_MGMT_2, &pwrMgmt, 1);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to execute write\n");
    sleep(1);

    res = ICM_20948_set_sample_mode(icm_dev, (ICM_20948_InternalSensorID_bm)ICM_20948_Internal_Mst, (ICM_20948_LP_CONFIG_CYCLE_e)ICM_20948_Sample_Mode_Cycled);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set sample mode\n");
    sleep(1);

    res = ICM_20948_enable_FIFO(icm_dev, 0);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to disable FIFO\n");
    usleep(10000);

    res = ICM_20948_enable_DMP(icm_dev, 0);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to disable DMP\n");
    usleep(10000);

    ICM_20948_fss_t myFSS; // This uses a "Full Scale Settings" structure that can contain values for all configurable sensors
    myFSS.a = gpm4;         // (ICM_20948_ACCEL_CONFIG_FS_SEL_e)
                            // gpm2
                            // gpm4
                            // gpm8
                            // gpm16
    myFSS.g = dps2000;      // (ICM_20948_GYRO_CONFIG_1_FS_SEL_e)
                            // dps250
                            // dps500
                            // dps1000
                            // dps2000
    uint8_t tries = 1;
    const uint8_t max_tries = 10;
    _try_set_fullscale:
    res = ICM_20948_set_full_scale(icm_dev, (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS);
    BBBLOG(warn, (res != ICM_20948_Stat_Ok) && (tries <= max_tries), sleep(1); tries++; goto _try_set_fullscale;, "Failed to set full-scale mode: %u / %u\n", tries, max_tries);
    BBBLOG(error, (res != ICM_20948_Stat_Ok) && (tries > max_tries), return -1;, "Failed to set full-scale mode\n", tries, max_tries);

    usleep(1000);

    res = ICM_20948_enable_dlpf(icm_dev, ICM_20948_Internal_Gyr, true);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to enable DLPF\n");
    usleep(1000);

    ICM_20948_set_bank(icm_dev, 0u);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set bank\n");
    usleep(1000);

    uint8_t zero = 0x00;
    res = ICM_20948_execute_w(icm_dev, AGB0_REG_FIFO_EN_1, &zero, 1);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to execute write\n");
    usleep(1000);

    res = ICM_20948_execute_w(icm_dev, AGB0_REG_FIFO_EN_2, &zero, 1);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to execute write\n");
    usleep(1000);

    ICM_20948_INT_enable_t en;
    res  = ICM_20948_int_enable(icm_dev, NULL, &en);
    en.RAW_DATA_0_RDY_EN = false;
    res |= ICM_20948_int_enable(icm_dev, &en, &en);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to enable interrupt\n");
    usleep(1000);

    res = ICM_20948_reset_FIFO(icm_dev);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to reset FIFO\n");
    usleep(1000);

    ICM_20948_smplrt_t mySmplrt;
    mySmplrt.g = 19; // ODR is computed as follows: 1.1 kHz/(1+GYRO_SMPLRT_DIV[7:0]). 19 = 55Hz. InvenSense Nucleo example uses 19 (0x13).
    mySmplrt.a = 19; // ODR is computed as follows: 1.125 kHz/(1+ACCEL_SMPLRT_DIV[11:0]). 19 = 56.25Hz. InvenSense Nucleo example uses 19 (0x13).
                    //mySmplrt.g = 4; // 225Hz
                    //mySmplrt.a = 4; // 225Hz
                    //mySmplrt.g = 8; // 112Hz
                    //mySmplrt.a = 8; // 112Hz
    res = ICM_20948_set_sample_rate(icm_dev, (ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), mySmplrt);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set sample rate\n");
    usleep(1000);

    res = ICM_20948_set_dmp_start_address(icm_dev, DMP_START_ADDRESS);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set DMP start address\n");
    usleep(1000);

    res = ICM_20948_firmware_load(icm_dev);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to load firmware\n");
    usleep(1000);

    res = ICM_20948_set_dmp_start_address(icm_dev, DMP_START_ADDRESS);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set DMP start address\n");
    usleep(1000);

    res = ICM_20948_set_bank(icm_dev, 0u);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set bank\n");
    usleep(1000);

    uint8_t fix = 0x48;
    res = ICM_20948_execute_w(icm_dev, AGB0_REG_HW_FIX_DISABLE, &fix, 1);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to execute write\n");
    usleep(1000);

    res = ICM_20948_set_bank(icm_dev, 0u);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set bank\n");
    usleep(1000);

    uint8_t fifoPrio = 0xE4;
    res = ICM_20948_execute_w(icm_dev, AGB0_REG_SINGLE_FIFO_PRIORITY_SEL, &fifoPrio, 1);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to execute write\n");

    const unsigned char accScale[4] = {0x04, 0x00, 0x00, 0x00};
    const unsigned char accScale2[4] = {0x00, 0x04, 0x00, 0x00};
    const unsigned char mountMultiplierZero[4] = {0x00, 0x00, 0x00, 0x00};
    const unsigned char mountMultiplierPlus[4] = {0x09, 0x99, 0x99, 0x99};  // Value taken from InvenSense Nucleo example
    const unsigned char mountMultiplierMinus[4] = {0xF6, 0x66, 0x66, 0x67}; // Value taken from InvenSense Nucleo example
    const unsigned char b2sMountMultiplierZero[4] = {0x00, 0x00, 0x00, 0x00};
    const unsigned char b2sMountMultiplierPlus[4] = {0x40, 0x00, 0x00, 0x00}; // Value taken from InvenSense Nucleo example

    res = inv_icm20948_write_mems(icm_dev, ACC_SCALE, 4, &accScale[0]);
    res |= inv_icm20948_write_mems(icm_dev, ACC_SCALE2, 4, &accScale2[0]);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to write ACC_SCALE to DMP memory\n");

    res = inv_icm20948_write_mems(icm_dev, CPASS_MTX_00, 4, &mountMultiplierPlus[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_01, 4, &mountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_02, 4, &mountMultiplierZero[0]);
    usleep(1000);

    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_10, 4, &mountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_11, 4, &mountMultiplierMinus[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_12, 4, &mountMultiplierZero[0]);
    usleep(1000);

    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_20, 4, &mountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_21, 4, &mountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_MTX_22, 4, &mountMultiplierMinus[0]);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to write CPASS Matrix to DMP memory\n");
    usleep(1000);

    res = inv_icm20948_write_mems(icm_dev, B2S_MTX_00, 4, &b2sMountMultiplierPlus[0]);
    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_01, 4, &b2sMountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_02, 4, &b2sMountMultiplierZero[0]);
    usleep(1000);

    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_10, 4, &b2sMountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_11, 4, &b2sMountMultiplierPlus[0]);
    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_12, 4, &b2sMountMultiplierZero[0]);
    usleep(1000);

    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_20, 4, &b2sMountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_21, 4, &b2sMountMultiplierZero[0]);
    res |= inv_icm20948_write_mems(icm_dev, B2S_MTX_22, 4, &b2sMountMultiplierPlus[0]);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to write B2S Matrix to DMP memory\n");
    usleep(1000);

    // Configure the DMP Gyro Scaling Factor
    // @param[in] gyro_div Value written to GYRO_SMPLRT_DIV register, where
    //            0=1125Hz sample rate, 1=562.5Hz sample rate, ... 4=225Hz sample rate, ...
    //            10=102.2727Hz sample rate, ... etc.
    // @param[in] gyro_level 0=250 dps, 1=500 dps, 2=1000 dps, 3=2000 dps
    res = inv_icm20948_set_gyro_sf(icm_dev, 19, 3);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set Gyro SF\n");
    usleep(1000);

    const unsigned char gyroFullScale[4] = {0x10, 0x00, 0x00, 0x00}; // 2000dps : 2^28
    const unsigned char accelOnlyGain[4] = {0x03, 0xA4, 0x92, 0x49}; // 56Hz
    const unsigned char accelAlphaVar[4] = {0x34, 0x92, 0x49, 0x25}; // 56Hz
    const unsigned char accelAVar[4] = {0x0B, 0x6D, 0xB6, 0xDB}; // 56Hz
    const unsigned char accelCalRate[4] = {0x00, 0x00, 0x00, 0x00}; // Value taken from InvenSense Nucleo example
    const unsigned char compassRate[2] = {0x00, 0x45}; // 69Hz

    res = inv_icm20948_write_mems(icm_dev, GYRO_FULLSCALE, 4, &gyroFullScale[0]);
    res |= inv_icm20948_write_mems(icm_dev, ACCEL_ONLY_GAIN, 4, &accelOnlyGain[0]);
    res |= inv_icm20948_write_mems(icm_dev, ACCEL_ALPHA_VAR, 4, &accelAlphaVar[0]);
    res |= inv_icm20948_write_mems(icm_dev, ACCEL_A_VAR, 4, &accelAVar[0]);
    res |= inv_icm20948_write_mems(icm_dev, ACCEL_CAL_RATE, 2, &accelCalRate[0]);
    res |= inv_icm20948_write_mems(icm_dev, CPASS_TIME_BUFFER, 2, &compassRate[0]);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to write Sensor Settings to DMP memory\n");

    return 0;

}

int icm20948_enable_DMP_sensor(ICM_20948_Device_t* icm_dev){
    ICM_20948_Status_e res = inv_icm20948_enable_dmp_sensor(icm_dev, INV_ICM20948_SENSOR_ORIENTATION, true);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to enable DMP Sensor\n");
    return 0;
}

int icm20948_enable_DMP(ICM_20948_Device_t* icm_dev){
    ICM_20948_Status_e res = ICM_20948_enable_DMP(icm_dev, true);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to enable DMP\n");
    return 0;
}

int icm20948_enable_FIFO(ICM_20948_Device_t* icm_dev){
    ICM_20948_Status_e res = ICM_20948_enable_FIFO(icm_dev, true);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to enable FIFO\n");
    return 0;
}

int icm20948_reset_FIFO(ICM_20948_Device_t* icm_dev){
    ICM_20948_Status_e res = ICM_20948_reset_FIFO(icm_dev);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to reset FIFO\n");
    return 0;
}

int icm20948_reset_DMP(ICM_20948_Device_t* icm_dev){
    ICM_20948_Status_e res = ICM_20948_reset_DMP(icm_dev);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to reset DMP\n");
    return 0;
}

int icm20948_set_DMP_ODR(ICM_20948_Device_t* icm_dev, uint16_t ODR){
    // Configuring DMP to output data at multiple ODRs:
    // DMP is capable of outputting multiple sensor data at different rates to FIFO.
    // Setting value can be calculated as follows:
    // Value = (DMP running rate / ODR ) - 1
    // E.g. For a 5Hz ODR rate when DMP is running at 55Hz, value = (55/5) - 1 = 10.
    // ODR = 0 is maximum rate
    ICM_20948_Status_e res = inv_icm20948_set_dmp_sensor_period(icm_dev, DMP_ODR_Reg_Quat9, ODR);
    BBBLOG(error, res != ICM_20948_Stat_Ok, return -1, "Failed to set DMP ODR\n");
    return 0;
}

Calling Code

    ICM_20948_Serif_t icm_serif;
    icm_serif.read = &icm_read;
    icm_serif.write = &icm_write;
    ICM_20948_Device_t icm_dev;
    ICM_20948_init_struct(&icm_dev);
    ICM_20948_link_serif(&icm_dev, &icm_serif);
    res = icm20948_startupDefault(&icm_dev, 1);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 minimal setup failed\n");
    res = icm20948_initialize_DMP(&icm_dev);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 DMP init failed\n");
    res = icm20948_enable_DMP_sensor(&icm_dev);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 DMP sensor init failed\n");
    res = icm20948_set_DMP_ODR(&icm_dev, 10); // 5 Hz ODR
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 DMP ODR setting failed\n");
    res = icm20948_enable_FIFO(&icm_dev);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 enable FIFO failed\n");
    res = icm20948_enable_DMP(&icm_dev);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 enable DMP failed\n");
    res = icm20948_reset_DMP(&icm_dev);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 reset DMP failed\n");
    res = icm20948_reset_FIFO(&icm_dev);
    BBBLOG(error, res != 0, goto cleaning, "ICM20948 reset FIFO failed\n");
PaulZC commented 9 months ago

Hi Luke (@LukeDeWaal ),

I'm not sure how we can help you here. This looks like a hardware issue between the Beaglebone and the ICM20948. Not an issue with this library?

I'm happy to leave this open in case anyone else can help.

Best wishes, Paul

PaulZC commented 9 months ago

Perhaps check the I2C signal voltages. If you are using a Saleae analyzer, try enabling the analog inputs. Check the voltages and the rise/fall times. Perhaps what the (digital) analyzer is reporting is different to what the Beaglebone receives?

LukeDeWaal commented 9 months ago

Hi Paul,

I'm not sure how we can help you here. This looks like a hardware issue between the Beaglebone and the ICM20948. Not an issue with this library?

I understand it isn't so much an issue with this library, but I figured most people active within this repository have a better chance of helping me with this issue. From what I've seen, you seem to know this repo better than your back pocket 😄

Perhaps check the I2C signal voltages. If you are using a Saleae analyzer, try enabling the analog inputs. Check the voltages and the rise/fall times. Perhaps what the (digital) analyzer is reporting is different to what the Beaglebone receives?

I don't own an oscilloscope or analog signal analyzer sadly, but I did manage to progress with this issue; in particular, after shortening the I2C lines the sensor behaved as expected. I suppose there was too much noise on the I2C bus. I will close this issue as it was a hardware fault all along! (Gotta love microelectronics eh 🙄 )