This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to prevent a reset due to DETECT signal from GPIO?

Hello everyone,

I'm facing a weird issue where the nRF52832 would reset and upon reading the RESETREAS reg, the value is 0x10001 which, from the data sheet, indicates that there was a "Reset from pin" and also a "reset due to wake up from System OFF mode when the wakeup is triggered from DETECT from GPIO". This happens when sensor is just lying on my desk and there is little to no movement to it. 

It's connected to a Segger J-Link which I'm using to flash and log data from the sensor.

To give some more information, I'm using FreeRTOS and NOT using any softdevice and I'm also running a custom firmware and not any of the examples.

The sensor is reading from an accelerometer interfaced to nRF52 using I2C and there's an interrupt pin of the accelerometer interfaced to one of the GPIOs (configured as an interrupt too)  of nRF52. The interrupt from the the accelerometer is used to indicate when data is ready to be read. This allows to nRF52 to sleep and only read when data is ready.

The configuration of the GPIO as interrupt is as follows:

// using an array here to make it easier for future use
// in case if more gpio need to init as interrupt
static const uint8_t accel_isr_pin[] = {2};
static void interrupt_init(void)
{
    ret_code_t ret_val = NRF_SUCCESS;

    if (nrf_drv_gpiote_is_init() == false) {
        ret_val = nrf_drv_gpiote_init();
        if (ret_val != NRF_SUCCESS) {
            trace(TRACE_DEBUG, "error: %d", ret_val);
        }
    }

    nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);	// edge sense from low to high
    config.pull = NRF_GPIO_PIN_PULLDOWN;

    for (uint8_t i = 0; i < sizeof(isr_pin); i++) {						// configure and enable interrupt lines
        ret_val = nrf_drv_gpiote_in_init(accel_isr_pin[i], &config, accel_event_handler);
        if (ret_val != NRF_SUCCESS)
            trace(TRACE_DEBUG, "error: %d", ret_val);
        nrf_drv_gpiote_in_event_enable(accel_isr_pin[i], true);
    }
}

Following are my questions:

1. Is the chip reset stemming from an interrupt received from the accelerometer when the chip is in sleep mode? If yes, how can I prevent the chip from not resetting?

2. Is there anything wrong with the initialization function?

I would really appreciate if someone can help me with this issue.

Thank you,

Dhaval

Parents
  • I had similar issues some time ago; if you are using System Off mode (not clear from the above) then this is correct behaviour. If you are using On mode to sleep this is unexpected. This code ensures that only the accelerometer (push button in this case) can exit sleep.

      .

        // Ensure no pin other than the push-button can instigate wake up
        for (uint32_t i=0; i<32; i++)
        {
            if (i == PB_ALERT_PIN) continue;
            // Put all other pins into default configuration, minimum power consumption
            NRF_P0->PIN_CNF[i] = 0x00000002;
            NRF_P0->LATCH = (1 << i);
        }
    
        // Ensure push-button does not have a pending wake up
        NRF_P0->LATCH = (1 << PB_ALERT_PIN);
    
        // Store action to take on wakeup in general purpose retention register
        //nrf_power_gpregret_set(0, 2);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        APP_ERROR_CHECK(err_code);
        // Ensure this function doesn't exit
        while(1) ;
    

    Slightly unrelated, but perhaps relevant, is what happens on a wakeup; if the design raises the power supply from (say) to 1.7 volts to (say) 3 volts then the nRF52832 will likely reset - confusing but covered in the manual.

    // The nRF52832 resets when changing the regulator from regulate (normal mode 1.7 volts) to
    // bypass mode (low-power RTC mode direct battery volts about 3 volts):
    // "A step increase in supply voltage of 300 mV or more, with rise time of 300 ms or less, within
    // the valid supply range, may result in a system reset."
    
    .

Reply
  • I had similar issues some time ago; if you are using System Off mode (not clear from the above) then this is correct behaviour. If you are using On mode to sleep this is unexpected. This code ensures that only the accelerometer (push button in this case) can exit sleep.

      .

        // Ensure no pin other than the push-button can instigate wake up
        for (uint32_t i=0; i<32; i++)
        {
            if (i == PB_ALERT_PIN) continue;
            // Put all other pins into default configuration, minimum power consumption
            NRF_P0->PIN_CNF[i] = 0x00000002;
            NRF_P0->LATCH = (1 << i);
        }
    
        // Ensure push-button does not have a pending wake up
        NRF_P0->LATCH = (1 << PB_ALERT_PIN);
    
        // Store action to take on wakeup in general purpose retention register
        //nrf_power_gpregret_set(0, 2);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        APP_ERROR_CHECK(err_code);
        // Ensure this function doesn't exit
        while(1) ;
    

    Slightly unrelated, but perhaps relevant, is what happens on a wakeup; if the design raises the power supply from (say) to 1.7 volts to (say) 3 volts then the nRF52832 will likely reset - confusing but covered in the manual.

    // The nRF52832 resets when changing the regulator from regulate (normal mode 1.7 volts) to
    // bypass mode (low-power RTC mode direct battery volts about 3 volts):
    // "A step increase in supply voltage of 300 mV or more, with rise time of 300 ms or less, within
    // the valid supply range, may result in a system reset."
    
    .

Children
  • Hi ,

    Thank you for the prompt reply and sharing the code snippets. Good to know that a voltage change might trigger a reset too.

    Since I don't use a softdevice, I use the following which activates the deep sleep mode instead of using sd_power_system_off(). Is it same as the System OFF mode?

    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    I had a question about your following code snippet:

    // Ensure no pin other than the push-button can instigate wake up
    for (uint32_t i=0; i<32; i++)
    {
        if (i == PB_ALERT_PIN) continue;
        // Put all other pins into default configuration, minimum power consumption
        NRF_P0->PIN_CNF[i] = 0x00000002;
        NRF_P0->LATCH = (1 << i);
    }

    Could you confirm if I understand the behavior correctly? Before going to sleep, you disconnect the input buffer of all pins except the push button pin.

    Also, what would need to be done after you wake up? You would need to connect the input buffers again, is that correct?

    The problem with my code is that since there's no softdevice and I'm using FreeRTOS I'm not actively putting the system to sleep. It does go in sleep mode but it's not controlled by me. Any idea how would I prevent a system reset in that case?

    I do rely on the interrupt coming from the accelerometer to decide when to do processing though. So technically, when I get an inactivity interrupt from the accelerometer, I stop my processing and assume the system goes to sleep (verified by checking current consumption when this happens which is ~70uA).

    Any thoughts what would be a workaround?

    Thanks,

  • I don't use SCB, which might be an issue .. maybe have a look at the sleep examples; I'm not sure what your design intention is, but the reason to place all pins in default mode with inputs disconnected (except for accelerometer) is to minimize power drain (total board < 2uA) but this does assume the hardware is designed to have the nRF52832 floating all pins (as it does in reset and system off). FreeRTOS has some assembler to control the sleep modes, but I haven't looked at that for a long time as I don't use that OS, but it won't be System Off. System Off doesn't usually work for an RTOS or RTC system, the sleep mode is required. I have external pin triggers so can use system off. As you note, all pins have to be configured again on wakeup (reset); the wakeup reason and a stored memory area (or the retention registers) indicate why system off was initiated, which allows control, for example, of a reset caused by releasing the Bypass on a regulator for low-Iq mode which causes the 1.9 volt rail to jump to coin cell level (around 2.7 volts) and induce the unwanted reset. Board consumption below 2uA is difficult without bypassing the regulators to remove the Iq, hence the voltage rise.

Related