cancel
Showing results for 
Search instead for 
Did you mean: 

Dear ST Community, I am currently trying to setup a Finite State Machine (FSM) for the LSM6DSO32. Is there somewhere an example?

THäck.1
Associate II

I'm using the NUCELO-G071RB with the STEVAL-MKI215V1. I tried to use the example code for the LSM6DSO available on github: https://github.com/STMicroelectronics/STMems_Standard_C_drivers/blob/master/lsm6dso_STdC/examples/lsm6dso_fsm.c, since I did not find an example for the LSM6DSO32. Unfortunately I dont get it to work after changing the varaible types and function names so that they fit to the lsm6dso32_reg.h.

Since I dont have the STEVAL-MKI109V3, I cannot use neither the UnicoGUI nor the AlgoBuilder software.

Does anybody have a running example code for the FSM on LSM6DSO32 or a documentation on how to use the provided c code lsm6dso32_reg?

Thank you already in advance! Any help is greatly appreciated!

Greetings

Timm

4 REPLIES 4
Eleon BORLINI
ST Employee

Hi Timm @Timm Häcker​ ,

there should be no difference between the FSM registers of the LSM6DSO32 and the LMS6DSO's ones, so you should be able to run the LSM6DSO drivers on the LSM6DSO32 device. Which error do you get from your code?

By the way, you might try to start from the LSM6DSO32X C drivers instead of LSM6DSO ones.

--> lsm6dso32x_STdC The two devices are the same except from the Machine Learning Core (MLC) block.

-Eleon

THäck.1
Associate II

Hi Eleon,

thank you for your answer!

I checked the drivers for LSM6DSO (lsm6dso_reg.c) and LSM6DSO32X (lsm6dso32x_reg.c). They seem to be identical, as you said, except of course the naming of variables, defines & functions.

My code to setup the FSM is similar to the examples of both sensors (lsm6dso_fsm.c and lsm6dso32x_fsm.c).

void lsm6dso32_fsm(void)
{
  /* Variable declaration */
  stmdev_ctx_t               	dev_ctx;
  lsm6dso32_pin_int1_route_t   	pin_int1;
  lsm6dso32_emb_fsm_enable_t   	fsm_enable;
//  lsm6dso32_emb_sens_t         	emb_sens; 
  lsm6dso32_fsm_out_t          	fsm_out;
  lsm6dso32_all_sources_t      	status;
  uint16_t                   	fsm_addr;
  /* Initialize mems driver interface */
  dev_ctx.write_reg = platform_write;
  dev_ctx.read_reg  = platform_read;
  dev_ctx.handle    = &SENSOR_BUS;
  /* Init test platform */
  platform_init();
  /* Wait sensor boot time */
  platform_delay(BOOT_TIME);
  /* Check device ID */
  lsm6dso32_device_id_get(&dev_ctx, &whoamI);
 
  if (whoamI != LSM6DSO32_ID)
    while (1);
 
  /* Restore default configuration (not FSM) */
  lsm6dso32_reset_set(&dev_ctx, PROPERTY_ENABLE);
 
  do {
    lsm6dso32_reset_get(&dev_ctx, &rst);
  } while (rst);
 
  /* Disable I3C interface */
  lsm6dso32_i3c_disable_set(&dev_ctx, LSM6DSO32_I3C_DISABLE);
  /* Enable Block Data Update */
  lsm6dso32_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
  /* Set full scale */
  lsm6dso32_xl_full_scale_set(&dev_ctx, LSM6DSO32_4g);
  lsm6dso32_gy_full_scale_set(&dev_ctx, LSM6DSO32_2000dps);
  /* Route signals on interrupt pin 1 */
  lsm6dso32_pin_int1_route_get(&dev_ctx, &pin_int1);
 
  pin_int1.fsm_int1_a.int1_fsm1	= PROPERTY_ENABLE;
  pin_int1.fsm_int1_a.int1_fsm2	= PROPERTY_ENABLE;
  pin_int1.fsm_int1_a.int1_fsm3	= PROPERTY_ENABLE;
  pin_int1.fsm_int1_a.int1_fsm4	= PROPERTY_ENABLE;
  pin_int1.fsm_int1_a.int1_fsm5	= PROPERTY_ENABLE;
  pin_int1.fsm_int1_a.int1_fsm6	= PROPERTY_ENABLE;
  pin_int1.fsm_int1_a.int1_fsm7	= PROPERTY_ENABLE;
//  pin_int1.md1_cfg.int1_double_tap= PROPERTY_DISABLE;
//  pin_int1.md1_cfg.int1_wu 		= PROPERTY_DISABLE;
//  pin_int1.md1_cfg.int1_single_tap= PROPERTY_DISABLE;
//  pin_int1.md1_cfg.int1_emb_func	= PROPERTY_ENABLE;
  lsm6dso32_pin_int1_route_set(&dev_ctx, &pin_int1);
  /* Configure interrupt pin mode notification */
  lsm6dso32_int_notification_set(&dev_ctx,
                               LSM6DSO32_BASE_PULSED_EMB_LATCHED);
  /* Start Finite State Machine configuration */
  /* Reset Long Counter */
  lsm6dso32_long_cnt_int_value_set(&dev_ctx, 0x0000U);
  /* Set the first address where the programs are written */
  #define LSM6DSO32_START_FSM_ADD                0x0400U  // identical with LSM6DSO and LSM6DSO32X
  lsm6dso32_fsm_start_address_set(&dev_ctx, LSM6DSO32_START_FSM_ADD);
  /* Set the number of the programs */
  lsm6dso32_fsm_number_of_programs_set(&dev_ctx, 7);
  /* Enable final state machine */
  fsm_enable.fsm_enable_a.fsm1_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm2_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm3_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm4_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm5_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm6_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm7_en    = PROPERTY_ENABLE ;
  fsm_enable.fsm_enable_a.fsm8_en    = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm9_en    = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm10_en   = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm11_en   = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm12_en   = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm13_en   = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm14_en   = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm15_en   = PROPERTY_DISABLE;
  fsm_enable.fsm_enable_b.fsm16_en   = PROPERTY_DISABLE;
  lsm6dso32_fsm_enable_set(&dev_ctx, &fsm_enable);
  /* Set Finite State Machine data rate */
  lsm6dso32_fsm_data_rate_set(&dev_ctx, LSM6DSO32_ODR_FSM_26Hz);
  /* Write Programs */
  fsm_addr = LSM6DSO32_START_FSM_ADD;
  /* Glance */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr, (uint8_t *)lsm6so_prg_glance,
                      sizeof(lsm6so_prg_glance));
  fsm_addr += sizeof(lsm6so_prg_glance);
  /* motion */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr, (uint8_t *)lsm6so_prg_motion,
                      sizeof(lsm6so_prg_motion));
  fsm_addr += sizeof(lsm6so_prg_motion);
  /* no_motion */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr,
                      (uint8_t *)lsm6so_prg_no_motion,
                      sizeof(lsm6so_prg_no_motion));
  fsm_addr += sizeof(lsm6so_prg_no_motion);
  /* wakeup */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr, (uint8_t *)lsm6so_prg_wakeup,
                      sizeof(lsm6so_prg_wakeup));
  fsm_addr += sizeof(lsm6so_prg_wakeup);
  /* pickup */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr, (uint8_t *)lsm6so_prg_pickup,
                      sizeof(lsm6so_prg_pickup));
  fsm_addr += sizeof(lsm6so_prg_pickup);
  /* orientation */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr,
                      (uint8_t *)lsm6so_prg_orientation,
                      sizeof(lsm6so_prg_orientation));
  fsm_addr += sizeof(lsm6so_prg_orientation);
  /* wrist_tilt */
  lsm6dso32_ln_pg_write(&dev_ctx, fsm_addr,
                      (uint8_t *)lsm6so_prg_wrist_tilt,
                      sizeof(lsm6so_prg_wrist_tilt));
//  emb_sens.fsm = PROPERTY_ENABLE;
  lsm6dso32_emb_fsm_en_set(&dev_ctx, 1);
  /* End Finite State Machine configuration */
  /* Set Output Data Rate */
  lsm6dso32_xl_data_rate_set(&dev_ctx, LSM6DSO32_XL_ODR_104Hz_HIGH_PERF);
  lsm6dso32_gy_data_rate_set(&dev_ctx, LSM6DSO32_GY_ODR_104Hz_HIGH_PERF);
  sprintf((char *)tx_buffer, "fsm initialized \r\n");
	tx_com(tx_buffer, strlen((char const *)tx_buffer));
	/* Main loop */
  while (1) {
    /* Read interrupt source registers in polling mode (no int) */
    lsm6dso32_all_sources_get(&dev_ctx, &status);
 
    if (status.fsm_status_a.is_fsm1) {
      sprintf((char *)tx_buffer, "glance detected\r\n");
      tx_com(tx_buffer, strlen((char const *)tx_buffer));
    }
 
[...]
 
    HAL_Delay(20);
  }
}

[code snippet 1]

There is a difference for line 42-53, because the struct lsm6dso32_pin_int1_route_t is defined differently than lsm6dso32x_pin_int1_route_t. Also function lsm6dso32_pin_int1_route_set(stmdev_ctx_t *ctx, lsm6dso32_pin_int1_route_t *val) is different to lsm6dso32x_pin_int1_route_set(stmdev_ctx_t *ctx,lsm6dso32x_pin_int1_route_t val).

THäck.1
Associate II

I tried to adapt the example for the drivers of lsm6dso32 (lsm6dso32_reg.c).

If I run the above code, I dont get an compiler error. The programm would try to execute ll 53 [code snippet 1]. During execution of function lsm6dso32_pin_int1_route_set(...), it would move until ll 70-71 [code snippet 2].

int32_t lsm6dso32_pin_int1_route_set(stmdev_ctx_t *ctx,
                                     lsm6dso32_pin_int1_route_t *val)
{
  lsm6dso32_pin_int2_route_t pin_int2_route;
  lsm6dso32_tap_cfg2_t tap_cfg2;
  int32_t ret;
 
  ret = lsm6dso32_mem_bank_set(ctx, LSM6DSO32_EMBEDDED_FUNC_BANK);
 
  if (ret == 0)
  {
    ret = lsm6dso32_write_reg(ctx, LSM6DSO32_EMB_FUNC_INT1,
                              (uint8_t *)&val->emb_func_int1, 1);
  }
 
  if (ret == 0)
  {
    ret = lsm6dso32_write_reg(ctx, LSM6DSO32_FSM_INT1_A,
                              (uint8_t *)&val->fsm_int1_a, 1);
  }
 
  if (ret == 0)
  {
    ret = lsm6dso32_write_reg(ctx, LSM6DSO32_FSM_INT1_B,
                              (uint8_t *)&val->fsm_int1_b, 1);
  }
 
  if (ret == 0)
  {
    ret = lsm6dso32_mem_bank_set(ctx, LSM6DSO32_USER_BANK);
  }
 
  if (ret == 0)
  {
    if ((val->emb_func_int1.int1_fsm_lc
         | val->emb_func_int1.int1_sig_mot
         | val->emb_func_int1.int1_step_detector
         | val->emb_func_int1.int1_tilt
         | val->fsm_int1_a.int1_fsm1
         | val->fsm_int1_a.int1_fsm2
         | val->fsm_int1_a.int1_fsm3
         | val->fsm_int1_a.int1_fsm4
         | val->fsm_int1_a.int1_fsm5
         | val->fsm_int1_a.int1_fsm6
         | val->fsm_int1_a.int1_fsm7
         | val->fsm_int1_a.int1_fsm8
         | val->fsm_int1_b.int1_fsm9
         | val->fsm_int1_b.int1_fsm10
         | val->fsm_int1_b.int1_fsm11
         | val->fsm_int1_b.int1_fsm12
         | val->fsm_int1_b.int1_fsm13
         | val->fsm_int1_b.int1_fsm14
         | val->fsm_int1_b.int1_fsm15
         | val->fsm_int1_b.int1_fsm16) != PROPERTY_DISABLE)
    {
      val->md1_cfg.int1_emb_func = PROPERTY_ENABLE;
    }
 
    else
    {
      val->md1_cfg.int1_emb_func = PROPERTY_DISABLE;
    }
 
    ret = lsm6dso32_write_reg(ctx, LSM6DSO32_INT1_CTRL,
                              (uint8_t *)&val->int1_ctrl, 1);
  }
 
  if (ret == 0)
  {
    ret = lsm6dso32_write_reg(ctx, LSM6DSO32_MD1_CFG,
                              (uint8_t *)&val->md1_cfg, 1);
  }
[...]
}

[code snippet 2]

Finally it would throw an HAL_ERROR while executing

if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)

[code snippet 3]

in file stm32g0xx_hal_i2c.c and jump to the HardFault_Handler in stm32g0xx_it.c.

So it seems like the sensor is not communicating anymore via I2C?

I guess I will try your suggestion and use the lsm6dso32x_reg.c for lsm6dso32. Or at least the implementation for setting up the fsm. Maybe this works...

Sorry for this very long post! This seemed to me, being the only possibility to adequately describe the behaviour I get. If you would make yourself the effort and try to solve my problem I would be very grateful!

Thank you already in advance!

-Timm

Eleon BORLINI
ST Employee

Hi Timm @Timm Häcker​ ,

It is strange that the I2C suddenly stops working... can you try with the SPI protocol, or you cannot due to hardware restriction?

>> I guess I will try your suggestion and use the lsm6dso32x_reg.c for lsm6dso32. Or at least the implementation for setting up the fsm. Maybe this works...

Ok sure, please let me know if there are any updates.

-Eleon