2026-04-11 5:46 PM
I notice there is now a github repo with FSM examples; very useful!
However, in comparing what I have been successfully using, for example, for shake detection on the LSM6DSV (or LSM6DSV80X) where 30 lines are written to page 0x7A:
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0xC0 | 0x20 | 0x02); // write to CONFIG_A (three thresholds, two masks, two short timers)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to CONFIG_B
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x1E); // write to SIZE (30 byte program)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to SETTINGS
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to RESET POINTER
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to PROGRAM POINTER
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x66); // write to THRESH1 LSB
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x3E); // write to THRESH1 MSB (set to + 1.6 g)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x66); // write to THRESH2 LSB
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0xBE); // write to THRESH2 MSB (set to -1.6 g)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0xCD); // write to THRESH3 LSB
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x3C); // write to THRESH3 MSB (set to + 1.2 g)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0xC0); // write to MASKA (+X and -X)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to TMASKA
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x02); // write to MASKB (+V)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to TMASKB
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to TC
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x10); // write to TIMER3 (16 samples at 30 Hz = 0.62 seconds)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x05); // write to TIMER4 ( 5 samples at 30 Hz = 0.19 seconds)
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x66); // write to SELMA Select MASKA and TMASKA as current mask
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0xCC); // write to SELTHR1 Selects THRESH1 instead of THRESH3
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x35); // write to TI3 ! GNTH1 look for over/under/over threshold events == shaking
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x38); // write to TI3 ! LNTH2
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x35); // write to TI3 ! GNTH1
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x77); // write to SELMB Select MASKB and TMASKB as current mask
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0xDD); // write to SELTHR3 Selects THRESH3 instead of THRESH1
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x03); // write to NOP | TI3
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x54); // write to GNTH1 | TI4
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x22); // write to CONTREL Continues execution from reset pointer, resetting temporary mask
_i2c_bus->writeByte(i2cAddress, LSM6DSV80X_PAGE_VALUE, 0x00); // write to STOP
There is now a different example (see here:(
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x02, .data = 0x11 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x08, .data = 0x7A },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x01 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x01 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x04 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x02, .data = 0x41 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x08, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x51 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x10 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x18 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x0D },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x3E },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x80 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x08 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x7C },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x41 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x5C },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x12 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x15 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x3C },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x35 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x22 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x35 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x3C },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x09, .data = 0x22 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x04, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x05, .data = 0x01 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x17, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x02, .data = 0x01 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x01, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x14, .data = 0x80 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x10, .data = 0x28 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x11, .data = 0x00 },
{ .type = MEMS_CONF_OP_TYPE_WRITE, .address = 0x5E, .data = 0x02 }
where there are 6 lines written to page 0x7A and then the rest of the 24-line program is written to page 0x00.
This seems to be a common strategy throughout the FSM example repository. Could you please explain the logic behind this? Why wouldn't I just continue to write the entire 30-line FSM rprogram to page 0x7A as in the FSM application note? Any clarity on this procedure would be much appreciated! Thank you.
Solved! Go to Solution.
2026-04-12 10:01 AM
OK, nevermind. I see that the first page write is to page 0 and starts at register 0x7A to configure the FSM. The second write is to page 0x40, which is the page specified in the first section where the program starts. What threw me was the fact that the shake detection program is different from the one I had been using and is shorter (24 bytes instead of the 30 bytes of my original). But I understand now what is going on.
2026-04-12 10:01 AM
OK, nevermind. I see that the first page write is to page 0 and starts at register 0x7A to configure the FSM. The second write is to page 0x40, which is the page specified in the first section where the program starts. What threw me was the fact that the shake detection program is different from the one I had been using and is shorter (24 bytes instead of the 30 bytes of my original). But I understand now what is going on.