cancel
Showing results for 
Search instead for 
Did you mean: 

ISM330DLC fifo settings issue

amistar
Associate

Hi

I managed to read both accelerometer and gyroscope ISM330DLC in "polling" mode with INT1 pin with 3330 output data rate, but my goal is to reach peak data rate (6660 samples / s) so I need to use FIFO and this is where my problems start, I dont know how to set FIFO properly, results in FIFO are intertwined. Could you show me a problem in my configuration?

 

I have some success with enabling FIFO but I have no clue how to configure it to reach my goal which is reading acc ang gyro via primary SPI with max data rate (6660 Hz) and with lowest latency (low set fifo watermark)

 

My code

 

 

/* Header of application modules */
#include <sensors-board-app/logging.h>
#include <sensors-board-app/ism.h>
#include <sensors-board-app/ism330dlc.h>

/* Header from CubeMX autogenerated code */
#include <main.h>
#include <spi.h>
#include <gpio.h>

/* Constants */

/** @brief Timeout of ISM330 SPI interface */
#define ISM330_SPI_TIMEOUT_MS 100

/* Private data types */

/* Private functions declarations */

static int32_t s_ism330_cb_init(void);

static int32_t s_ism330_cb_deinit(void);

static int32_t s_ism330_cb_read(uint16_t address,
                            uint16_t reg,
                            uint8_t* data,
                            uint16_t len);

static int32_t s_ism330_cb_write(uint16_t address,
                            uint16_t reg,
                            uint8_t* data,
                            uint16_t len);

static int32_t s_ISM330DLC_Init_custom_version(ISM330DLC_Object_t *pObj);

/* Private data */

/** @brief ISM330 library handler */
static ISM330DLC_Object_t ism330_hdl = { 0 };

/** @brief Accelerometer sensitivity */
static float s_acc_sensitivity = 0.0f;

/** @brief Gyroscope sensitivity */
static float s_gyro_sensitivity = 0.0f;

int ism_init(void)
{
    /* ISM330 library IO */
    static ISM330DLC_IO_t ism330_io = {
        .Init = s_ism330_cb_init,
        .DeInit = s_ism330_cb_deinit,
        .BusType = 2, /* 0 means I2C, 1 means SPI 4-Wires, 2 means SPI-3-Wires */
        .Address = 69, /* dont know how to use this in this library */
        .ReadReg = s_ism330_cb_read,
        .WriteReg = s_ism330_cb_write,
        .GetTick = NULL, /* callback not used int this library anyway */
    };

    /* Register ISM330 library callbacks */
    ISM330DLC_RegisterBusIO(&ism330_hdl, &ism330_io);

    /* Iniatialise ISM330 chip using fixed version of ISM330DLC_Init procedure */
    s_ISM330DLC_Init_custom_version(&ism330_hdl);

    /* Check ISM330 ID */
    uint8_t ism330_id = 0;
    ISM330DLC_ReadID(&ism330_hdl, &ism330_id);
    if (ISM330DLC_ID == ism330_id) {
        LOG_INFO("ISM330DLC chip id is valid");
    } else {
        LOG_ERROR("ISM330DLC chip id invalid");
    }

    /* Set ISM330 in high performance mode */
    ism330dlc_xl_power_mode_set(&ism330_hdl.Ctx, ISM330DLC_XL_HIGH_PERFORMANCE);
    ism330dlc_gy_power_mode_set(&ism330_hdl.Ctx, ISM330DLC_GY_HIGH_PERFORMANCE);

    /* Set scale */
    ISM330DLC_GYRO_SetFullScale(&ism330_hdl, 2000);
    ISM330DLC_ACC_GetSensitivity(&ism330_hdl, &s_acc_sensitivity);
    ISM330DLC_GYRO_GetSensitivity(&ism330_hdl, &s_gyro_sensitivity);

    /* Enable toggling interrupt pin on reaching fifo watermark */
    ISM330DLC_Set_Drdy_Mode(&ism330_hdl, ISM330DLC_DRDY_PULSED);
    uint8_t int1_ctrl_reg_value = 0x8;
    ISM330DLC_Write_Reg(&ism330_hdl, ISM330DLC_INT1_CTRL, int1_ctrl_reg_value);

    /* Set output data rate (from 12.5, 208.0 to 1660.0 and even 6660.0) */
    ISM330DLC_ACC_SetOutputDataRate(&ism330_hdl,  104);
    ISM330DLC_GYRO_SetOutputDataRate(&ism330_hdl, 104);
    ISM330DLC_ACC_Enable(&ism330_hdl);
    ISM330DLC_GYRO_Enable(&ism330_hdl);

    /* Set ODF of FIFO */
    ISM330DLC_FIFO_Set_ODR_Value(&ism330_hdl, 104);

    /* Set FIFO decimators */
    ISM330DLC_FIFO_GYRO_Set_Decimation(&ism330_hdl, ISM330DLC_FIFO_GY_NO_DEC);
    ISM330DLC_FIFO_ACC_Set_Decimation(&ism330_hdl, ISM330DLC_FIFO_XL_NO_DEC);

    /* Turn on FIFO */
    ISM330DLC_FIFO_Set_Mode(&ism330_hdl, ISM330DLC_FIFO_MODE);

    /* Set FIFO watermark level */
    ISM330DLC_FIFO_Set_Watermark_Level(&ism330_hdl, 120);

    return 0;
}

ism_drdy_e ism_check_drdy(void)
{
    ism_drdy_e retval = ISM_DRDY_ACC_AND_GYRO;

    return retval;
}

int ism_read_acc_gyro(ism_acc_gyro_res_t* results)
{
    /* Collect results */
    ISM330DLC_AxesRaw_t gyro_raw = {0};
    ISM330DLC_AxesRaw_t acc_raw = {0};

    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &gyro_raw.x);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &gyro_raw.y);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &gyro_raw.z);

    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.x));
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.y));
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.z));

    /* Calculate result */
    results->acc_x = (int32_t)((float)((float)acc_raw.x * s_acc_sensitivity));
    results->acc_y = (int32_t)((float)((float)acc_raw.y * s_acc_sensitivity));
    results->acc_z = (int32_t)((float)((float)acc_raw.z * s_acc_sensitivity));
    results->vel_x = (int32_t)((float)((float)gyro_raw.x * s_gyro_sensitivity));
    results->vel_y = (int32_t)((float)((float)gyro_raw.y * s_gyro_sensitivity));
    results->vel_z = (int32_t)((float)((float)gyro_raw.z * s_gyro_sensitivity));

    return 0;
}

int ism_read_temp(float* temp)
{
    int16_t t_raw = 0;
    ism330dlc_temperature_raw_get(&ism330_hdl.Ctx, &t_raw);
    *temp = (((float)t_raw) / 256.0f) + 25.0f;
    return 0;
}

/* Private functions */

static int32_t s_ism330_cb_init(void)
{
    /* Its only stub, all init is already done */
    return 0;
}

static int32_t s_ism330_cb_deinit(void)
{
    /* Its only stub */
    return 0;
}

static int32_t s_ism330_cb_read(uint16_t address,
                            uint16_t reg,
                            uint8_t* data,
                            uint16_t len)
{
    int32_t retval = 0;

    /* Assert CS pin */
    HAL_GPIO_WritePin(ISM_CS_GPIO_Port, ISM_CS_Pin, GPIO_PIN_RESET);

    /* Read request is tagged with read request mask */
    static const uint8_t spi_read_mask = 0x80U;
    uint8_t reg_addr = reg | spi_read_mask;

    /* Write address of register we want to read from */
    const HAL_StatusTypeDef status_write_addr =
            HAL_SPI_Transmit(&hspi3, &reg_addr, 1U, ISM330_SPI_TIMEOUT_MS);
    if (HAL_OK != status_write_addr) {
        retval = -1;
        goto exit;
    }

    /* Read data from selected address */
    if (0 < len) {
        const HAL_StatusTypeDef status_read_data =
                HAL_SPI_Receive(&hspi3, data, len, ISM330_SPI_TIMEOUT_MS);
        if (HAL_OK != status_read_data) {
            retval = -1;
            goto exit;
        }
    } else {
        LOG_ERROR("Fail zero len read");
        retval = -1;
        goto exit;
    }

exit:
    /* Always deassert CS */
    HAL_GPIO_WritePin(ISM_CS_GPIO_Port, ISM_CS_Pin, GPIO_PIN_SET);

    return retval;
}

static int32_t s_ism330_cb_write(uint16_t address,
                            uint16_t reg,
                            uint8_t* data,
                            uint16_t len)
{
    int32_t retval = 0;

    /* Assert CS pin */
    HAL_GPIO_WritePin(ISM_CS_GPIO_Port, ISM_CS_Pin, GPIO_PIN_RESET);

    /* Write address of register we want to write to */
    uint8_t reg_address = reg;
    const HAL_StatusTypeDef status_write_addr =
        HAL_SPI_Transmit(&hspi3, &reg_address, 1, ISM330_SPI_TIMEOUT_MS);
    if (HAL_OK != status_write_addr) {
        retval = -1;
        goto exit;
    }

    /* Write data */
    if (0 < len) {
        const HAL_StatusTypeDef status_write_data =
            HAL_SPI_Transmit(&hspi3, data, len, ISM330_SPI_TIMEOUT_MS);
        if (HAL_OK != status_write_data) {
            retval = -1;
            goto exit;
        }
    } else {
        LOG_ERROR("Fail zero len write");
        retval = -1;
        goto exit;
    }

exit:
    /* Always deassert CS */
    HAL_GPIO_WritePin(ISM_CS_GPIO_Port, ISM_CS_Pin, GPIO_PIN_SET);

    return retval;
}

int32_t s_ISM330DLC_Init_custom_version(ISM330DLC_Object_t *pObj)
{
    /* Reset all the configuration registers in order to set correctly */
    if (ism330dlc_reset_set(&(pObj->Ctx),PROPERTY_ENABLE) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Original library fn. lacks delay and reinitialisation of 3-wire SPI here */
    HAL_Delay(10);

    /* Enable SPI 3-Wires on the component */
    uint8_t data = 0x0C;
    if (ISM330DLC_Write_Reg(pObj, ISM330DLC_CTRL3_C, data) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Enable register address automatically incremented during a multiple byte
    access with a serial interface. */
    if (ism330dlc_auto_increment_set(&(pObj->Ctx), PROPERTY_ENABLE) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Enable BDU */
    if (ism330dlc_block_data_update_set(&(pObj->Ctx), PROPERTY_ENABLE) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* FIFO mode selection */
    if (ism330dlc_fifo_mode_set(&(pObj->Ctx), ISM330DLC_BYPASS_MODE) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Select default output data rate. */
    pObj->acc_odr = ISM330DLC_XL_ODR_104Hz;

    /* Output data rate selection - power down. */
    if (ism330dlc_xl_data_rate_set(&(pObj->Ctx), ISM330DLC_XL_ODR_OFF) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Full scale selection. */
    if (ism330dlc_xl_full_scale_set(&(pObj->Ctx), ISM330DLC_2g) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Select default output data rate. */
    pObj->gyro_odr = ISM330DLC_GY_ODR_104Hz;

    /* Output data rate selection - power down. */
    if (ism330dlc_gy_data_rate_set(&(pObj->Ctx), ISM330DLC_GY_ODR_OFF) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    /* Full scale selection. */
    if (ism330dlc_gy_full_scale_set(&(pObj->Ctx), ISM330DLC_2000dps) != ISM330DLC_OK)
    {
        return ISM330DLC_ERROR;
    }

    pObj->is_initialized = 1;

    return ISM330DLC_OK;
}

 

 

My results:

 

00:00:00.011: INFO: Sensors Board App booting up...
00:00:00.109: INFO: ISM330DLC chip id is valid
00:00:00.299: INFO: IMU X =  -81 | Y =  221 | Z =   22 | X = 1610 | Y = 17710 | Z = 25270 
00:00:00.318: INFO: IMU X =   -5 | Y =    0 | Z =   23 | X = 5460 | Y = 36540 | Z = 26110 
00:00:00.337: INFO: IMU X =   -4 | Y =    0 | Z =   22 | X = -6930 | Y = 1470 | Z = 25900 
00:00:00.356: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  770 | Y = -1330 | Z = 24780 
00:00:00.375: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  910 | Y = -630 | Z = 26530 
00:00:00.394: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  910 | Y =  140 | Z = 26740 
00:00:00.413: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  910 | Y = -350 | Z = 26530 
00:00:00.432: INFO: IMU X =    0 | Y =    0 | Z =   21 | X =  910 | Y = -560 | Z = 24570 
00:00:00.451: INFO: IMU X =    0 | Y =    0 | Z =   19 | X =  910 | Y = -280 | Z = 23170 
00:00:00.469: INFO: IMU X =    0 | Y =    0 | Z =   20 | X =  980 | Y = -350 | Z = 23800 
00:00:00.488: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  980 | Y = -350 | Z = 25620 
00:00:00.507: INFO: IMU X =    0 | Y =    0 | Z =   24 | X =  980 | Y = -350 | Z = 27160 
00:00:00.526: INFO: IMU X =    0 | Y =    0 | Z =   24 | X =  980 | Y = -350 | Z = 28210 
00:00:00.545: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  980 | Y = -420 | Z = 27160 
00:00:00.564: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  910 | Y = -420 | Z = 27720 
00:00:00.583: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  910 | Y = -420 | Z = 28490 
00:00:00.602: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  910 | Y = -420 | Z = 26390 
00:00:00.621: INFO: IMU X =    0 | Y =    0 | Z =   21 | X =  910 | Y = -420 | Z = 25130 
00:00:00.640: INFO: IMU X =    0 | Y =    0 | Z =   20 | X =  910 | Y = -420 | Z = 24500 
00:00:00.659: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  910 | Y = -350 | Z = 24360 
00:00:00.677: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  910 | Y = -350 | Z = 24570 
00:00:00.696: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  980 | Y = -420 | Z = 25690 
00:00:00.715: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  980 | Y = -280 | Z = 27370 
00:00:00.734: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  910 | Y = -280 | Z = 26110 
00:00:00.753: INFO: IMU X =    0 | Y =    0 | Z =   21 | X =  980 | Y = -350 | Z = 24780 
00:00:00.772: INFO: IMU X =    0 | Y =    0 | Z =   22 | X =  980 | Y = -280 | Z = 24850 
00:00:00.791: INFO: IMU X =    0 | Y =    0 | Z =   23 | X =  910 | Y = -280 | Z = 26250 
00:00:00.810: INFO: IMU X =    0 | Y =    0 | Z = 1043 | X =  910 | Y = -350 | Z = 27790 
00:00:00.838: INFO: IMU X =   -3 | Y =  -19 | Z = 1044 | X = -3850 | Y = -21980 | Z = 1197280 
00:00:00.857: INFO: IMU X =   -3 | Y =  -20 | Z = 1044 | X = -3850 | Y = -23380 | Z = 1198470 
00:00:00.876: INFO: IMU X =   -3 | Y =  -20 | Z = 1044 | X = -3780 | Y = -23940 | Z = 1198540 
00:00:00.895: INFO: IMU X =   -3 | Y =  -22 | Z = 1044 | X = -3780 | Y = -24640 | Z = 1197630 
00:00:00.914: INFO: IMU X =   -3 | Y =  -22 | Z = 1043 | X = -3710 | Y = -24920 | Z = 1197280 
00:00:00.933: INFO: IMU X =   -3 | Y =  -21 | Z = 1043 | X = -3710 | Y = -25480 | Z = 1197070 
00:00:00.951: INFO: IMU X =   -3 | Y =  -19 | Z = 1043 | X = -3710 | Y = -23870 | Z = 1197560 
00:00:00.970: INFO: IMU X =   -3 | Y =  -17 | Z = 1043 | X = -3780 | Y = -21350 | Z = 1198050 
00:00:00.989: INFO: IMU X =   -3 | Y =  -16 | Z = 1043 | X = -3780 | Y = -20720 | Z = 1196930 
00:00:01.008: INFO: IMU X =   -3 | Y =  -18 | Z = 1044 | X = -3710 | Y = -20090 | Z = 1197280 
00:00:01.027: INFO: IMU X =   -3 | Y =  -19 | Z = 1042 | X = -3780 | Y = -21280 | Z = 1197490 
00:00:01.046: INFO: IMU X =   -3 | Y =  -21 | Z = 1045 | X = -3640 | Y = -23590 | Z = 1197280 
00:00:01.065: INFO: IMU X =   -3 | Y =  -23 | Z = 1043 | X = -3920 | Y = -24990 | Z = 1197420 
00:00:01.084: INFO: IMU X =   -3 | Y =  -23 | Z = 1043 | X = -3780 | Y = -26950 | Z = 1197280 
00:00:01.103: INFO: IMU X =   -3 | Y =  -22 | Z = 1043 | X = -3850 | Y = -26040 | Z = 1197980 
00:00:01.122: INFO: IMU X =   -3 | Y =  -20 | Z = 1043 | X = -3780 | Y = -25480 | Z = 1196930 
00:00:01.140: INFO: IMU X =   -3 | Y =  -20 | Z = 1044 | X = -3990 | Y = -23450 | Z = 1198470 
00:00:01.159: INFO: IMU X =   -3 | Y =  -18 | Z = 1042 | X = -3780 | Y = -21420 | Z = 1196580 
00:00:01.178: INFO: IMU X =   -3 | Y =  -18 | Z = 1043 | X = -3990 | Y = -21420 | Z = 1198960 
00:00:01.197: INFO: IMU X =   -3 | Y =  -18 | Z = 1043 | X = -3850 | Y = -20580 | Z = 1196790 
00:00:01.216: INFO: IMU X =   -3 | Y =  -20 | Z = 1042 | X = -3850 | Y = -23030 | Z = 1196580 
00:00:01.235: INFO: IMU X =   -3 | Y =  -22 | Z = 1042 | X = -3710 | Y = -24430 | Z = 1196650 
00:00:01.254: INFO: IMU X =   -3 | Y =  -23 | Z = 1042 | X = -3780 | Y = -25830 | Z = 1197280 
00:00:01.273: INFO: IMU X =   -3 | Y =  -21 | Z = 1043 | X = -3710 | Y = -25410 | Z = 1196090 
00:00:01.292: INFO: IMU X =   -3 | Y =  -20 | Z =    0 | X = -3710 | Y = -24780 | Z = 1197280 
00:00:01.311: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -420 | Y = 27650 | Z =  980 
00:00:01.329: INFO: IMU X =    0 | Y =   25 | Z =    0 | X = -350 | Y = 29820 | Z =  980 
00:00:01.348: INFO: IMU X =    0 | Y =   25 | Z =    0 | X = -420 | Y = 28770 | Z =  980 
00:00:01.367: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -350 | Y = 28140 | Z =  910 
00:00:01.386: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -350 | Y = 26740 | Z =  910 
00:00:01.405: INFO: IMU X =    0 | Y =   21 | Z =    0 | X = -350 | Y = 25970 | Z =  980 
00:00:01.424: INFO: IMU X =    0 | Y =   21 | Z =    0 | X = -350 | Y = 24150 | Z =  910 
00:00:01.443: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -350 | Y = 24640 | Z =  910 
00:00:01.462: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -350 | Y = 26180 | Z =  910 
00:00:01.481: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -350 | Y = 27510 | Z =  980 
00:00:01.500: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -350 | Y = 26740 | Z =  980 
00:00:01.518: INFO: IMU X =    0 | Y =   21 | Z =    0 | X = -350 | Y = 25830 | Z =  910 
00:00:01.537: INFO: IMU X =    0 | Y =   21 | Z =    0 | X = -350 | Y = 23800 | Z =  980 
00:00:01.556: INFO: IMU X =    0 | Y =   21 | Z =    0 | X = -350 | Y = 24360 | Z =  980 
00:00:01.575: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -420 | Y = 25690 | Z =  980 
00:00:01.594: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -350 | Y = 26320 | Z =  910 
00:00:01.613: INFO: IMU X =    0 | Y =   24 | Z =    0 | X = -350 | Y = 27370 | Z =  980 
00:00:01.632: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -420 | Y = 27510 | Z =  980 
00:00:01.651: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -490 | Y = 27300 | Z =  980 
00:00:01.670: INFO: IMU X =    0 | Y =   21 | Z =    0 | X = -420 | Y = 25130 | Z =  980 
00:00:01.689: INFO: IMU X =    0 | Y =   20 | Z =    0 | X = -420 | Y = 24920 | Z =  980 
00:00:01.708: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -350 | Y = 24710 | Z =  910 
00:00:01.726: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -350 | Y = 25480 | Z =  910 
00:00:01.745: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -350 | Y = 26670 | Z =  910 
00:00:01.764: INFO: IMU X =    0 | Y =   24 | Z =    0 | X = -350 | Y = 28700 | Z =  910 
00:00:01.783: INFO: IMU X =    0 | Y =   24 | Z =    0 | X = -350 | Y = 29120 | Z =  910 
00:00:01.802: INFO: IMU X =    0 | Y =   23 | Z =    0 | X = -350 | Y = 27020 | Z =  910 
00:00:01.821: INFO: IMU X =    0 | Y =   22 | Z =    0 | X = -280 | Y = 26180 | Z =  910 
00:00:01.840: INFO: IMU X =    0 | Y =   20 | Z =    0 | X = -350 | Y = 23660 | Z =  910 
00:00:01.859: INFO: IMU X =    0 | Y =   19 | Z =    0 | X = -350 | Y = 22400 | Z =  980 
00:00:01.878: INFO: IMU X =    0 | Y =   20 | Z =    0 | X = -350 | Y = 22820 | Z =  980 
00:00:01.897: INFO: IMU X =  -22 | Y = 1044 | Z =   -3 | X = -25200 | Y = 1196160 | Z = -3780 
00:00:01.915: INFO: IMU X =  -19 | Y = 1042 | Z =   -3 | X = -23730 | Y = 1196370 | Z = -3780 
00:00:01.934: INFO: IMU X =  -18 | Y = 1043 | Z =   -3 | X = -21840 | Y = 1197210 | Z = -3850 
00:00:01.953: INFO: IMU X =  -18 | Y = 1042 | Z =   -3 | X = -21070 | Y = 1197070 | Z = -3850 
00:00:01.972: INFO: IMU X =  -18 | Y = 1042 | Z =   -3 | X = -21000 | Y = 1196790 | Z = -3920 
00:00:01.991: INFO: IMU X =  -19 | Y = 1043 | Z =   -3 | X = -22330 | Y = 1197000 | Z = -3850 
00:00:02.010: INFO: IMU X =  -21 | Y = 1042 | Z =   -3 | X = -23170 | Y = 1196650 | Z = -3850 
00:00:02.029: INFO: IMU X =  -22 | Y = 1041 | Z =   -3 | X = -25550 | Y = 1197840 | Z = -3780 
00:00:02.048: INFO: IMU X =  -21 | Y = 1042 | Z =   -3 | X = -24290 | Y = 1195530 | Z = -3850 
00:00:02.067: INFO: IMU X =  -21 | Y = 1042 | Z =   -3 | X = -24990 | Y = 1195880 | Z = -3780 
00:00:02.086: INFO: IMU X =  -19 | Y = 1042 | Z =   -3 | X = -22260 | Y = 1196440 | Z = -3780 
00:00:02.104: INFO: IMU X =  -19 | Y = 1042 | Z =   -3 | X = -22890 | Y = 1197420 | Z = -3710 
00:00:02.123: INFO: IMU X =  -19 | Y = 1042 | Z =   -3 | X = -22400 | Y = 1196580 | Z = -3780 
00:00:02.142: INFO: IMU X =  -19 | Y = 1043 | Z =   -3 | X = -21910 | Y = 1197000 | Z = -3710 
00:00:02.161: INFO: IMU X =  -20 | Y = 1043 | Z =   -3 | X = -22120 | Y = 1196300 | Z = -3710 
00:00:02.180: INFO: IMU X =  -20 | Y = 1042 | Z =   -3 | X = -24080 | Y = 1195600 | Z = -3780 
00:00:02.199: INFO: IMU X =  -20 | Y = 1043 | Z =   -3 | X = -22680 | Y = 1197280 | Z = -3780 
00:00:02.218: INFO: IMU X =  -20 | Y = 1042 | Z =   -3 | X = -22890 | Y = 1195880 | Z = -3780 
00:00:02.237: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = -24710 | Y = 1197560 | Z = -350 
00:00:02.256: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 26530 | Y =  910 | Z = -350 
00:00:02.275: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 26740 | Y =  980 | Z = -350 
00:00:02.293: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 24360 | Y =  910 | Z = -280 
00:00:02.312: INFO: IMU X =   21 | Y =    0 | Z =    0 | X = 25270 | Y =  910 | Z = -280 
00:00:02.331: INFO: IMU X =   21 | Y =    0 | Z =    0 | X = 24850 | Y =  910 | Z = -350 
00:00:02.350: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 25480 | Y =  910 | Z = -350 
00:00:02.369: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 27370 | Y =  910 | Z = -350 
00:00:02.388: INFO: IMU X =   24 | Y =    0 | Z =    0 | X = 27160 | Y =  980 | Z = -350 
00:00:02.407: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 26740 | Y =  910 | Z = -350 
00:00:02.426: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 26320 | Y =  980 | Z = -350 
00:00:02.445: INFO: IMU X =   21 | Y =    0 | Z =    0 | X = 24080 | Y =  910 | Z = -420 
00:00:02.464: INFO: IMU X =   21 | Y =    0 | Z =    0 | X = 23940 | Y =  910 | Z = -420 
00:00:02.482: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 24990 | Y =  980 | Z = -420 
00:00:02.501: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 25760 | Y =  980 | Z = -350 
00:00:02.520: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 27300 | Y =  910 | Z = -350 
00:00:02.539: INFO: IMU X =   24 | Y =    0 | Z =    0 | X = 28000 | Y =  910 | Z = -350 
00:00:02.558: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 27160 | Y =  910 | Z = -350 
00:00:02.577: INFO: IMU X =   24 | Y =    0 | Z =    0 | X = 27020 | Y =  910 | Z = -350 
00:00:02.596: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 25970 | Y =  910 | Z = -350 
00:00:02.615: INFO: IMU X =   20 | Y =    0 | Z =    0 | X = 26110 | Y =  910 | Z = -280 
00:00:02.634: INFO: IMU X =   20 | Y =    0 | Z =    0 | X = 22890 | Y =  910 | Z = -280 
00:00:02.653: INFO: IMU X =   20 | Y =    0 | Z =    0 | X = 22680 | Y =  910 | Z = -350 
00:00:02.672: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 24850 | Y =  910 | Z = -280 
00:00:02.690: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 26320 | Y =  980 | Z = -280 
00:00:02.709: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 27230 | Y =  910 | Z = -350 
00:00:02.728: INFO: IMU X =   23 | Y =    0 | Z =    0 | X = 27510 | Y =  910 | Z = -350 
00:00:02.747: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 26740 | Y =  910 | Z = -350 
00:00:02.766: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 25270 | Y =  980 | Z = -350 
00:00:02.785: INFO: IMU X =   22 | Y =    0 | Z =    0 | X = 25060 | Y =  910 | Z = -350 
00:00:02.804: INFO: IMU X =   21 | Y =    0 | Z =    0 | X = 24920 | Y =  910 | Z = -420 
00:00:02.823: INFO: IMU X = 1043 | Y =   -3 | Z =  -20 | X = 25970 | Y =  910 | Z = -350 
00:00:02.842: INFO: IMU X = 1042 | Y =   -3 | Z =  -21 | X = 1196440 | Y = -3710 | Z = -24080 
00:00:02.861: INFO: IMU X = 1043 | Y =   -3 | Z =  -20 | X = 1195880 | Y = -3780 | Z = -24080 
00:00:02.879: INFO: IMU X = 1043 | Y =   -3 | Z =  -19 | X = 1196790 | Y = -3780 | Z = -24150 
00:00:02.898: INFO: IMU X = 1043 | Y =   -3 | Z =  -18 | X = 1197280 | Y = -3850 | Z = -22540 
00:00:02.917: INFO: IMU X = 1041 | Y =   -3 | Z =  -20 | X = 1196510 | Y = -3710 | Z = -22820 
00:00:02.936: INFO: IMU X = 1042 | Y =   -3 | Z =  -19 | X = 1197490 | Y = -3850 | Z = -21630 
00:00:02.955: INFO: IMU X = 1041 | Y =   -3 | Z =  -20 | X = 1197140 | Y = -3780 | Z = -22120 
00:00:02.974: INFO: IMU X = 1043 | Y =   -3 | Z =  -19 | X = 1196440 | Y = -3850 | Z = -22820 
00:00:02.993: INFO: IMU X = 1041 | Y =   -3 | Z =  -19 | X = 1197490 | Y = -3920 | Z = -22610 
00:00:03.012: INFO: IMU X = 1042 | Y =   -3 | Z =  -19 | X = 1196580 | Y = -3780 | Z = -23240 
00:00:03.031: INFO: IMU X = 1042 | Y =   -3 | Z =  -21 | X = 1196230 | Y = -3780 | Z = -23380 
00:00:03.050: INFO: IMU X = 1042 | Y =   -3 | Z =  -22 | X = 1197000 | Y = -3780 | Z = -25480 

 

 

 

 

6 REPLIES 6
amistar
Associate

I forgot to add how I want to implement the flow in the program:

- INT1 pin changes state to 1 when FIFO reach watermark, which is set fairly low to keep samples latency as low as possible

- EXTI interrupt handler in STM32F7 MCU queues an event into events queue, then main program loop enqueues this event and performs readout of sample / samples from FIFO

In my code snippet in original post I have unused function "ism_check_drdy" and I call "ism_read_acc_gyro" from the context of event handler in my main program loop.

 

amistar
Associate

If I understand correctly results in FIFO could be mixed up in some manner and I should know the pattern from pattern register, lets try out then this FIFO readout function:

 

int ism_read_acc_gyro(ism_acc_gyro_res_t* results)
{
    /* Collect results */
    ISM330DLC_AxesRaw_t gyro_raw = {0};
    ISM330DLC_AxesRaw_t acc_raw = {0};
    uint16_t pattern[6] = {0};

    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[0]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &gyro_raw.x);
    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[1]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &gyro_raw.y);
    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[2]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &gyro_raw.z);

    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[3]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.x));
    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[4]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.y));
    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[5]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.z));

    /* Calculate result */
    results->acc_x = (int32_t)((float)((float)acc_raw.x * s_acc_sensitivity));
    results->acc_y = (int32_t)((float)((float)acc_raw.y * s_acc_sensitivity));
    results->acc_z = (int32_t)((float)((float)acc_raw.z * s_acc_sensitivity));
    results->vel_x = (int32_t)((float)((float)gyro_raw.x * s_gyro_sensitivity));
    results->vel_y = (int32_t)((float)((float)gyro_raw.y * s_gyro_sensitivity));
    results->vel_z = (int32_t)((float)((float)gyro_raw.z * s_gyro_sensitivity));

    LOG_INFO("Pattern %u %u %u %u %u %u",
        pattern[0], pattern[1], pattern[2],
        pattern[3], pattern[4], pattern[5]);

    return 0;
}

 

The results is:

00:00:11.498: INFO: Pattern 1 5 3 1 5 3
00:00:11.498: INFO: IMU X =  -41 | Y =   -3 | Z = 1043 | X = -46270 | Y = -3710 | Z = 1195110 

 

It looks interesting, because I would expect 3th result to be Z axis of accelerometer, and it looks correct, but why I get pattern of 1, 5, 3, 1, 5, 3, instead of something like "0, 1, 2, 3, 4, 5" from page 92 of application note AN5125 when I set the same ODR settings as application note in this example (acc 104 Hz, gyro 104 Hz, FIFO 104 Hz, watermark = 120)

Ok I did try another settings: init:

int ism_init(void)
{
    /* ISM330 library IO */
    static ISM330DLC_IO_t ism330_io = {
        .Init = s_ism330_cb_init,
        .DeInit = s_ism330_cb_deinit,
        .BusType = 2, /* 0 means I2C, 1 means SPI 4-Wires, 2 means SPI-3-Wires */
        .Address = 69, /* dont know how to use this in this library */
        .ReadReg = s_ism330_cb_read,
        .WriteReg = s_ism330_cb_write,
        .GetTick = NULL, /* callback not used int this library anyway */
    };

    /* Register ISM330 library callbacks */
    ISM330DLC_RegisterBusIO(&ism330_hdl, &ism330_io);

    /* Iniatialise ISM330 chip using fixed version of ISM330DLC_Init procedure */
    s_ISM330DLC_Init_custom_version(&ism330_hdl);

    /* Check ISM330 ID */
    uint8_t ism330_id = 0;
    ISM330DLC_ReadID(&ism330_hdl, &ism330_id);
    if (ISM330DLC_ID == ism330_id) {
        LOG_INFO("ISM330DLC chip id is valid");
    } else {
        LOG_ERROR("ISM330DLC chip id invalid");
    }

    /* Set ISM330 in high performance mode */
    ism330dlc_xl_power_mode_set(&ism330_hdl.Ctx, ISM330DLC_XL_HIGH_PERFORMANCE);

    /* Set scale */
    ISM330DLC_ACC_GetSensitivity(&ism330_hdl, &s_acc_sensitivity);

    /* Enable toggling interrupt pin on reaching fifo watermark */
    ISM330DLC_Set_Drdy_Mode(&ism330_hdl, ISM330DLC_DRDY_PULSED);
    uint8_t int1_ctrl_reg_value = 0x08;
    ISM330DLC_Write_Reg(&ism330_hdl, ISM330DLC_INT1_CTRL, int1_ctrl_reg_value);

    /* Set output data rate (from 12.5, 208.0 to 1660.0 and even 6660.0) */
    ISM330DLC_ACC_SetOutputDataRate(&ism330_hdl,  52.0);
    ISM330DLC_ACC_Enable(&ism330_hdl);

    /* Set ODF of FIFO */
    ISM330DLC_FIFO_Set_ODR_Value(&ism330_hdl, 52.0);

    /* Set FIFO decimators */
    ISM330DLC_FIFO_ACC_Set_Decimation(&ism330_hdl, ISM330DLC_FIFO_XL_NO_DEC);

    /* Set FIFO watermark level */
    ISM330DLC_FIFO_Set_Watermark_Level(&ism330_hdl, 6);

    /* Dont stop on FTH */
    ISM330DLC_FIFO_Set_Stop_On_Fth(&ism330_hdl, 0);

    /* Turn on FIFO */
    ISM330DLC_FIFO_Set_Mode(&ism330_hdl, ISM330DLC_STREAM_MODE);

    return 0;
}

 

Readout function called after receiving fifo watermark reached event on INT1:

int ism_read_acc_gyro(ism_acc_gyro_res_t* results)
{
    /* Collect results */
    ISM330DLC_AxesRaw_t acc_raw = {0};
    uint16_t pattern[3] = {0};

    uint16_t samples_number = 0;
    ISM330DLC_FIFO_Get_Num_Samples(&ism330_hdl, &samples_number);

    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[0]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.x));
    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[1]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.y));
    ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern[2]);
    ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, &(acc_raw.z));

    /* Calculate result */
    results->acc_x = (int32_t)((float)((float)acc_raw.x * s_acc_sensitivity));
    results->acc_y = (int32_t)((float)((float)acc_raw.y * s_acc_sensitivity));
    results->acc_z = (int32_t)((float)((float)acc_raw.z * s_acc_sensitivity));

    LOG_INFO("Samples %u Pattern %u %u %u",
        samples_number,
        pattern[0], pattern[1], pattern[2]);

    return 0;
}

 

Result:

00:00:00.011: INFO: Sensors Board App booting up...
00:00:00.109: INFO: ISM330DLC chip id is valid
00:00:00.148: INFO: Samples 6 Pattern 0 1 2
00:00:00.148: INFO: IMU X = 1025 | Y = 1035 | Z = 1035 | X =    0 | Y =    0 | Z =    0 
00:00:00.185: INFO: Samples 6 Pattern 0 1 2
00:00:00.185: INFO: IMU X = 1037 | Y = 1036 | Z = 1036 | X =    0 | Y =    0 | Z =    0 
00:00:00.222: INFO: Samples 6 Pattern 0 1 2
00:00:00.222: INFO: IMU X = 1035 | Y = 1036 | Z = 1036 | X =    0 | Y =    0 | Z =    0 
00:00:00.259: INFO: Samples 6 Pattern 0 1 2
00:00:00.259: INFO: IMU X = 1037 | Y = 1036 | Z = 1036 | X =    0 | Y =    0 | Z =    0 
00:00:00.296: INFO: Samples 6 Pattern 0 1 2
00:00:00.297: INFO: IMU X = 1037 | Y = 1036 | Z = 1036 | X =    0 | Y =    0 | Z =    0 
00:00:00.334: INFO: Samples 6 Pattern 0 1 2
00:00:00.334: INFO: IMU X = 1036 | Y = 1036 | Z = 1036 | X =    0 | Y =    0 | Z =    0 
00:00:00.371: INFO: Samples 6 Pattern 0 1 2
00:00:00.371: INFO: IMU X = 1037 | Y = 1035 | Z = 1035 | X =    0 | Y =    0 | Z =    0 
00:00:00.408: INFO: Samples 6 Pattern 0 1 2
00:00:00.408: INFO: IMU X = 1035 | Y = 1035 | Z = 1035 | X =    0 | Y =    0 | Z =    0

 

Pattern looks good, but result of Z axis is repeated over all axes.

@Eleon BORLINI

 

Hi @amistar ,

Try this improved version of the code:

int ism_read_acc_gyro(ism_acc_gyro_res_t* results)
{
    /* Collect results */
    ISM330DLC_AxesRaw_t acc_raw = {0};
    uint16_t pattern = 0;

    uint16_t samples_number = 0;
    if (ISM330DLC_FIFO_Get_Num_Samples(&ism330_hdl, &samples_number) != ISM330DLC_OK) {
        LOG_ERROR("Failed to get number of samples from FIFO");
        return -1;
    }

    if (samples_number < 3) {
        LOG_ERROR("Insufficient samples in FIFO");
        return -1;
    }

    for (int i = 0; i < 3; i++) {
        if (ISM330DLC_FIFO_Get_Pattern(&ism330_hdl, &pattern) != ISM330DLC_OK) {
            LOG_ERROR("Failed to get FIFO pattern");
            return -1;
        }

        if (ISM330DLC_FIFO_Get_Data_Word(&ism330_hdl, ((uint16_t*)&acc_raw) + i) != ISM330DLC_OK) {
            LOG_ERROR("Failed to get data word for axis %d", i);
            return -1;
        }
    }

    /* Calculate result */
    results->acc_x = (int32_t)((float)((float)acc_raw.x * s_acc_sensitivity));
    results->acc_y = (int32_t)((float)((float)acc_raw.y * s_acc_sensitivity));
    results->acc_z = (int32_t)((float)((float)acc_raw.z * s_acc_sensitivity));

    LOG_INFO("Samples %u Pattern %u %u %u",
        samples_number,
        pattern, pattern, pattern);

    LOG_INFO("IMU X = %d | Y = %d | Z = %d",
        results->acc_x, results->acc_y, results->acc_z);

    return 0;
}

In this code, I used a loop to read the data for each axis (X, Y, Z) and checked that the data is read correctly. In addition, I added an error check for each read. Make sure the ISM330DLC_FIFO_Get_Data_Word function is correctly implemented and reads the data in the correct order.

If the problem persists, it might be useful to add additional debug logs to verify the values read from the FIFO before calculating them.

 

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Thank you, but this did not helped, it looks like I have to stay with polling readout at 3380 rate which works perfectly.

I am using this library https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/ism330dlc_STdC/examples

Could you please point which other device is the most similar or add ticket in your company work management tool for your teammates to create FIFO example for ISM330DLC ? Because there is no FIFO example for ISM330DLC and other devices often are different from it, for example they use tagging results instead of using pattern.

Best regards

Hi @amistar ,

Ok, I will notice this to the team.

In the meantime, you can look at the LSM6DSM FIFO examples. Indeed, the FIFO of LSM6DSM and ISM330DLC are pretty similar.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.