Getting LSM6DS3 to Work on XIAO MG24 Sense with Gecko SDK (I2C)

Hi all,

I’m developing firmware for the XIAO MG24 Sense using the Gecko SDK in Simplicity Studio, and I’m currently working on ensuring the onboard LSM6DS3 sensor functions correctly.

Based on a suggestion by @grobasoz, I’m using a platform-agnostic driver from ST by STMicroelectronics

To simplify things, I first wanted to confirm the sensor can be probed over I2C by reading the WHO_AM_I register (0x0F, expecting 0x69). For reference, I looked at the Seeed Arduino driver.

From what I understand:

  • PD5 needs to be configured as output and driven high to power the sensor.
  • Wire1 is used, which maps to I2C1 on the XIAO MG24, corresponding to PB3 (SDA1) and PB2 (SCL1).

Here’s a snippet of my sl_i2cspm_I2C_config.h defining I2C1 and my pins:

#define SL_I2CSPM_I2C_PERIPHERAL      I2C1
#define SL_I2CSPM_I2C_PERIPHERAL_NO   1
#define SL_I2CSPM_I2C_SCL_PORT        gpioPortB
#define SL_I2CSPM_I2C_SCL_PIN         2
#define SL_I2CSPM_I2C_SDA_PORT        gpioPortB
#define SL_I2CSPM_I2C_SDA_PIN         3

And here’s my simplified I2C probing code:

#define LSM6DS3_ADDR       0x6A
#define WHO_AM_I_REG       0x0F
#define EXPECTED_WHOAMI    0x69

bool probe_lsm6ds3(void)
{
    uint8_t who = 0;
    uint8_t cmd = WHO_AM_I_REG;

    I2C_TransferSeq_TypeDef seq = {
        .addr  = LSM6DS3_ADDR << 1,
        .flags = I2C_FLAG_WRITE_READ
    };

    seq.buf[0].data = &cmd;
    seq.buf[0].len  = 1;
    seq.buf[1].data = &who;
    seq.buf[1].len  = 1;

    I2C_TransferReturn_TypeDef ret = I2CSPM_Transfer(SL_I2CSPM_I2C_PERIPHERAL, &seq);
    printf("Transfer result: %d, WHO_AM_I = 0x%02X\r\n", ret, who);
    return ((ret == i2cTransferDone) && (who == EXPECTED_WHOAMI));
}

void app_init(void)
{

    // 1) Power‐up the LSM6DS3 (PD5)
    CMU_ClockEnable(cmuClock_GPIO, true); // Not sure if I need this
    GPIO_PinModeSet(gpioPortD, 5, gpioModePushPull, 1);
    sl_sleeptimer_delay_millisecond(100);

    // 2) initialize I2C instance
    sl_i2cspm_init_instances();
    sl_sleeptimer_delay_millisecond(100);

    // 3) Probing LSM6DS3 sensor via I2C
    if (!probe_lsm6ds3()) {
        printf("Could not probe LSM6DS3...\r\n");
    }
}

Despite that, I’m not getting the expected response from the sensor (or I2C might not be transferring at all). I2C_TransferReturn_TypeDef ret = I2CSPM_Transfer(SL_I2CSPM_I2C_PERIPHERAL, &seq); returns i2cTransferInProgress.

Has anyone here successfully used I2C peripherals (esp. LSM6DS3) with the Gecko SDK and the XIAO MG24 Sense?

Thanks in advance!

Mattt

Hi there,

So, Not a direct ANSWER to your specific Question, so disregard if so.
However, You may gain some incite from this example, demo code with compiler output & video. Perhaps as a sanity check before leaving the planet on Simplicity studio. :grin: to embark on the IMU journey :crossed_fingers:

towards the end of the thread.

HTH
GL :slight_smile: PJ :v:

or

:v:

@mattmagic - I tested your code here and it works fine - with a little change.
The EXPECTED_WHOAMI should be 0x6A (LSM6D3TR-C)
Rather check the response is OK and then check the response value…

@grobasoz Great news! I tried a few more things yesterday as well, but unfortunately, still no success. One of the tests I ran was a basic I2C scan, but it consistently returns i2cTransferInProgress.

Here’s the scan code I used:

void scan_i2c_bus(void)
{
  uint8_t dummy = 0x00;
  I2C_TransferSeq_TypeDef seq;
  printf("Scanning I2C1 (PB2/PB3)...\r\n");

  for (uint8_t addr = 3; addr < 0x78; addr++) {
    seq.addr  = addr << 1;
    seq.flags = I2C_FLAG_WRITE;
    seq.buf[0].data = &dummy;
    seq.buf[0].len  = 1;

    I2C_TransferReturn_TypeDef ret = I2CSPM_Transfer(SL_I2CSPM_I2C_PERIPHERAL, &seq);
    printf("  0x%02X - %d\r\n", addr, ret);
    if (ret == i2cTransferDone) {
      printf("  Found device at 0x%02X\r\n", addr);
    }

    sl_sleeptimer_delay_millisecond(5); // brief delay for readability
  }

  printf("Scan complete.\r\n");
}

I also re-tested the example you posted, but I’m still getting i2cTransferInProgress.
Here’s the output: Transfer result: 1, WHO_AM_I = 0x00

Would you mind sharing the project or code you used? I suspect that my configuration or code might be incorrect elsewhere. Thanks!

@mattmagic - Code attached…

// Forum Test
#include "sl_i2cspm_instances.h"

#define LSM6DS3_ADDR       0x6A
#define WHO_AM_I_REG       0x0F
#define EXPECTED_WHOAMI    0x69

uint8_t probe_lsm6ds3(void)
{
    uint8_t who = 0;
    uint8_t cmd = WHO_AM_I_REG;

    I2C_TransferSeq_TypeDef seq = {
        .addr  = LSM6DS3_ADDR << 1,
        .flags = I2C_FLAG_WRITE_READ
    };

    seq.buf[0].data = &cmd;
    seq.buf[0].len  = 1;
    seq.buf[1].data = &who;
    seq.buf[1].len  = 1;

    I2C_TransferReturn_TypeDef ret = I2CSPM_Transfer(SL_I2CSPM_I2C_PERIPHERAL, &seq);
    printf("Transfer result: %d, WHO_AM_I = 0x%02X\r\n", ret, who);
    if (ret == i2cTransferDone)
      return who;
    else
      return 0;
}

void app_init(void)
{
    if (probe_lsm6ds3() == 0) {
        printf("Could not probe LSM6DS3...\r\n");
    }
    else
    {
      printf("Found LSM6DS3!!!\r\n");
    }
}

Do you have an actual 'MG24 Sense connected?

@grobasoz Hmm, still no luck on my side. I’m getting the same result:

Transfer result: 1, WHO_AM_I = 0x00

Which means i2cTransferInProgress again.

Quick question - are you pulling PD5 high to enable the sensor?

Would you mind sharing your full project? I’d really like to compare and see where I might have gone wrong.

@mattmagic - What version of SDK are you using?

Edit>

Yes, but in the project file - see GPIO component.

1 Like

@grobasoz I am using the Gecko SDK 4.4.5

@mattmagic - File is too big to send here… attached is the hex.
XIAO_MG24_IMUTest.zip (314.7 KB)

1 Like

Ok your binary works on my hardware…
Where can I find the GPIO component in the project file? Do I need to install something?

Here is my sl_system_init.c:

#include "sl_event_handler.h"

void sl_system_init(void)
{
  sl_platform_init();
  sl_driver_init();
  sl_service_init();
  sl_stack_init();
  sl_internal_app_init();
}

And my sl_event_handler.c

void sl_platform_init(void)
{
  CHIP_Init();
  sl_device_init_nvic();
  sl_device_init_dcdc();
  sl_device_init_clocks();
  sl_device_init_emu();
}

void sl_driver_init(void)
{
  CMU_ClockEnable(cmuClock_GPIO, true);
  GPIO_PinModeSet(gpioPortD, 5, gpioModePushPull, 1);
  for (int i = 0; i < 100000; i++) {}

  sl_i2cspm_init_instances();
  sl_simple_led_init_instances();
}

void sl_service_init(void)
{
  sl_sleeptimer_init();
  sl_iostream_init_instances();
}

void sl_stack_init(void)
{
}

void sl_internal_app_init(void)
{
}

void sl_platform_process_action(void)
{
}

void sl_service_process_action(void)
{
}

void sl_stack_process_action(void)
{
}

void sl_internal_app_process_action(void)
{
}

void sl_iostream_init_instances(void)
{
  sl_iostream_usart_init_instances();
}

@mattmagic - The GPIO Init is part of the components.

You shouldn’t modify those files you showed… they’re automatically “generated” and will get overwritten.

Start with app_init and app_process_action in main.c (I suppose equivalent to Arduino’s setup and loop).

The latter should be non-blocking!

I can only try this on GSDK 4.4.6 - I normally use SiSDK 2024.12.2

Let me know if you want some more help… I started a simple outline of steps need to get this going… but then got bored :frowning:

2 Likes

@grobasoz, ok, I switched to the SiSDK 2024.12.2. Not sure if this makes a difference, but which compiler and Part in the configuration are you using?
I am using the GNU 12.2.1 and EFR32MG24B220F1536IM48.

@mattmagic - I restarted the app in 4.4.6 but can switch back to the latest SDK for a demo.

When I get back to the office I will create a new app for posting to my GitHub repository for you. I’ll continue documenting the steps I took as well.

I just need to know what application you are trying to build? I’m guessing BLE still?
If so, what do you want in the GATT apart from Motion?

The compiler and chip you have chosen is what I normally use for Xiao MG24 development as well.

A few checks you may want to make before I get code completed for you… in SS5.
Ensure that the clocks are set correctly, see Clock Manager.
For BLE set high precision on the LFRCO or use LFXO.
Set the DCDC to disabled and bypass.
Add the GPIO settings.
Add the I2C via the I2CSPM component.

There are a few other settings but I can’t remember all of them without being in front of my computer.

1 Like

@grobasoz thanks again for the detailed help — I very much appreciate it!

Yes, BLE is still part of my goal, but I think I’ll figure it out once the IMU is up and running — I don’t want to waste more of your time.

To your checks:

  1. Clock Manager: I haven’t made any changes there yet — I’m still using the default configuration. I’ll read up on it to see if anything needs adjusting.
  2. DCDC: I’ve disabled and set it to bypass as suggested. Does this setting influence the onboard IMU or power rails for I2C devices? (Just making sure I understand the implication.)
  3. GPIO: Configured PD5 as you showed to pull it high — that part looks good.
  4. I2C via I2CSPM: I’ve added this, but I suspect this might be where the issues are still occurring. I’ll double-check the I2C routing and pin mux to ensure it matches what the IMU expects.

I appreciate your offer to post a new GitHub app — that will help a lot with aligning on a known-good baseline.

Just wanted to follow up on this in case anyone else runs into a similar issue.

As it turns out, the problem was due to a mismatch in the I2C pin definitions — the SDA and SCL were swapped. Big thanks to @grobasoz for spotting the issue!

For anyone using the XIAO MG24 with the Arduino framework: the comment for the I2C pin definitions might be incorrect, which I had used as a source. According to the official XIAO MG24 schematic (KiCAD PDF), the correct wiring is:

#define SL_I2CSPM_I2C_PERIPHERAL      I2C0
#define SL_I2CSPM_I2C_PERIPHERAL_NO   1
#define SL_I2CSPM_I2C_SCL_PORT        gpioPortB
#define SL_I2CSPM_I2C_SCL_PIN         3
#define SL_I2CSPM_I2C_SDA_PORT        gpioPortB
#define SL_I2CSPM_I2C_SDA_PIN         2

Thanks again, @grobasoz — your help saved me a lot of time! :grin:

1 Like