XIAO BLE Sense - LSM6DS3 INT1 Single Tap Interrupt

Hi, PJ_Glasso

I am experiencing same problem as esmunus but I just want to stay on BSP nrf52 v1.1.8
NRF_POWER->SYSTEMOFF = 1;

#define NRF_POWER_S ((NRF_POWER_Type*) NRF_POWER_S_BASE)

Do you know what is the peripheralAddr in your BSP 2.9.1?

What I found for nrf52840 seems it needs to be 0x40000000UL

Hi there,
cores/nRF5/nordic/nrfx/mdk/nrf52840_peripherals.h
but I don’t think the issue is that , I believe if you use the GPIO number and the delay it will work with the 1.1.8 BSP.
HTH
GL :slight_smile: PJ :v:

Hi,

Yeah, doesn’t look like there would be a register problem. I am not sure where did you mean to use GPIO number?

The following goes to system_off it stays off with intention to test the power off

void goToPowerOff() {
  Serial.println("Going to System OFF");
  //Ensure interrupt pin from IMU is set to wake up device
  // nrf_gpio_cfg_sense_input(digitalPinToInterrupt(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
  delay(200);
  // Trigger System OFF
  NRF_POWER->SYSTEMOFF = 1;
}

The following wakes up immediately

void goToPowerOff() {
  Serial.println("Going to System OFF");
  //Ensure interrupt pin from IMU is set to wake up device
  nrf_gpio_cfg_sense_input(digitalPinToInterrupt(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
  delay(200);
  // Trigger System OFF
  NRF_POWER->SYSTEMOFF = 1;
}

Thanks, RW

Hi there,
Yes, So I went back and found the one that works with 1.1.8 as well, it’s a single nudge/tap and could be adjusted to the same function as the original, but this one sleeps properly and shuts down the flash also. It stays asleep until you beat it up a little (low sensitivity)
You can blend these two together and get what you need.
HTH
GL :slight_smile: PJ :v:

// This is compiled with BSP 1.1.8 , sleeps AOK, and wakes up with a nudge via the Tap 
// interrupt as GPIO
// toasted and poached by PJG 4/29/24
//
#include <Adafruit_SPIFlash.h>
#include <LSM6DS3.h>
#include <nrf52840.h>
#include <Wire.h>

Adafruit_FlashTransport_QSPI flashTransport;
LSM6DS3 myIMU; // Default is I2C mode

void QSPIF_sleep(void)
{
  flashTransport.begin();
  flashTransport.runCommand(0xB9);
  flashTransport.end();
}

void setupWakeUpInterrupt()
{
  // Start with LSM6DS3 in disabled to save power
  myIMU.settings.gyroEnabled = 0;
  myIMU.settings.accelEnabled = 0;

  myIMU.begin();

  // Set up the accelerometer for Wake-up interrupt.
  // Per the application note, use a two step set up to avoid spurious interrupts
  // Set up values are from the application note, and then adjusted for minimum power

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_DUR, 0x00); // No duration
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_THS, 0x02); // Set wake-up threshold
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x80);    // Enable interrupts and apply slope filter; latch mode disabled
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x70);    // Turn on the accelerometer
                                                           // ODR_XL = 833 Hz, FS_XL = ±2 g
  delay(4);                                                // Delay time per application note
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0xB0);    // ODR_XL = 1.6 Hz
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL6_G, 0x10);     // High-performance operating mode disabled for accelerometer
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x20);     // Wake-up interrupt driven to INT1 pin

  // Set up the sense mechanism to generate the DETECT signal to wake from system_off
  // No need to attach a handler, if just waking with the GPIO input.
	pinMode(PIN_LSM6DS3TR_C_INT1, INPUT_PULLDOWN_SENSE);

  return;
}

void setup()
{
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  
  digitalWrite(LED_RED, HIGH);
  digitalWrite(LED_GREEN, HIGH);

  QSPIF_sleep();

  // Flash green to see power on, reset, and wake from system_off
  digitalWrite(LED_GREEN, LOW);
  delay(1000);
  digitalWrite(LED_GREEN, HIGH);;

  // Minimizes power when bluetooth is used
  NRF_POWER->DCDCEN = 1;
}

void loop()
{
  // FreeRTOS will automatically put the system in system_on sleep mode here
  delay(10000); // Measure idle loop power during this period

  // Flash red before system_off sleep
  digitalWrite(LED_RED, LOW);
  delay(1000);
  digitalWrite(LED_RED, HIGH);;

  // Setup up double tap interrupt to wake back up
  setupWakeUpInterrupt();

  // Execution should not go beyond this
  NRF_POWER->SYSTEMOFF=1;
}

The Led will turn green when it wakes up ! :grin:

Hi,

Try to use digitalPinToPinName instead of digitalPinToInterrupt when calling nrf_gpio_cfg_sense_input, which will expect a nrf_gpio pin input (should be P0.11). However, digitalPinToInterrupt will only return the Arduino pin number, they are not matched. digitalPinToPinName(P) will do the pin mapping, g_ADigitalPinMap[P] will also work, actually which is the definition of digitalPinToPinName.

nrf_gpio_cfg_sense_input(digitalPinToPinName(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);

Hi,

Thanks!
That was a solution for me.

nrf_gpio_cfg_sense_input(digitalPinToPinName(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);

part of setup

  // Attach interrupt signal from myIMU for wake up function
  pinMode(int1Pin, INPUT_PULLDOWN);
  // Attach interrupt to the IMU
  attachInterrupt(digitalPinToInterrupt(int1Pin), int1ISR, RISING);
  // Attach interrupt to the IMU for wakeups
  nrf_gpio_cfg_sense_input(digitalPinToPinName(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);

  setupDoubleTapInterrupt();

and my goToPoweOff

void goToPowerOff() {
  Serial.println("Going to System OFF");
 // Delay to allow serial to print
  delay(500);
  // Trigger System OFF
  NRF_POWER->SYSTEMOFF = 1;
}

Hi,

Is it expected that when you trigger SYSTEM_OFF, the nrf52840 stays in its last state? I have turned on LED_RED ON before triggering SYSTEM_OFF, and it stays ON. Is this expected behavior?

Hi there,
It is, and will be reflected in the power draw asleep. You can shutdown the SD as well may override that behavior?
Some users also “flush” the serial port in order to avoid any spurious uart interrupts.
HTH
GL :slight_smile: PJ :v:

Hi,

I tried to replace NRF_POWER->SYSTEMOFF = 1; with
sd_power_system_off();
Is that what you mean by using SD?

With the following system doesn’t stay OFF

void goToPowerOff() {
  Serial.println("Going to System OFF");
 // Delay to allow serial to print
  delay(500);
  // Trigger System OFF
  // NRF_POWER->SYSTEMOFF = 1;
  sd_power_system_off();
}

Hi there,
No it won’t by itself, You need both to be most power efficient is what I was getting at.
The example I posted Does stay asleep and wakes up with movement.
HTH
GL :slight_smile: PJ