PIN_CNF Sense change state

Hello, I am developing a custom board based on nRF52832 that should spend most of it's time in SystemOFF mode. Eventually, it will wake up on an GPIO event caused by the external magnetic switch (LF11115TMR). Now, the switch behaves funny - it retains its state until a magnet is brought close to it. When I move the magnet close to it, it switches to low and stays until the magnet is moved back close to it. Then it switches high and stays there. 

The problem is how to configure the nRF52832: if I set PIN_CNF to sense either low or high, it will keep on waking up constantly, since the switch doesn't change its state until the magnet is brought nearby. The solution I found is to check the state of the switch before going SystemOFF and changing the PIN_CNF accordingly. So the code looks like this:

void sleep_mode_enter(void){

    printf("\n\rEntering SystemOFF sleep mode...");
    nrf_delay_ms(500);
    uint32_t tmr_state = nrf_gpio_pin_read(TMR_SWITCH);

    // Prepare wakeup buttons.
    if (tmr_state)
        nrf_gpio_cfg_sense_set(TMR_SWITCH, NRF_GPIO_PIN_SENSE_LOW);    
    else
        nrf_gpio_cfg_sense_set(TMR_SWITCH, NRF_GPIO_PIN_SENSE_HIGH); 

    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    sd_power_system_off();
}

And this turned out to be working fine...but only half the time. My system either goes to sleep like everything's fine or it ends up in an infinite reset loop hell. When I look into the debugger I see that PIN_CNF has been modified outside of my above function. Digging deeper in the stack, found that function port_event_handle() in nrfx_gpiote.c has some funny reconfiguration:

/* Reconfigure sense to the opposite level, so the internal PINx.DETECT signal
 * can be deasserted. Therefore PORT event generated again,
 * unless some other PINx.DETECT signal is still active. */
nrf_gpio_pin_sense_t next_sense =
    (sense == NRF_GPIO_PIN_SENSE_HIGH) ? NRF_GPIO_PIN_SENSE_LOW :
                                         NRF_GPIO_PIN_SENSE_HIGH;

that changes my sense inputs. Now, what to make of it? How to circumvent this without modifying nrfx_gpiote.c and is there a better approach in configuring wake-up pin for my application?

Best, 

W.

Parents
  • I suspect we are encountering similar problems.  Unfortunately I've not yet come up with the answer!

    I'm also working on a project with the nRF52832 spending most of its time in System OFF.  In mine, I have one of three different GPIO configured to trigger the device out of sleep mode. I then check the status of RESETREAS and LATCH, to determine what caused the exit from System Off (GPIO, NFC, harware reset etc) and in the case of a GPIO trigger, which GPIO caused it (via LATCH)

    I'm having two issues, which I am not sure if they are related:

    1.  There is upwards of a 500msec delay between my GPIO triggering, and my main.c code starting up.  Still working with the Nordic engineers on why this is, but I would be interested to see if you have something similar going on.  I just measure this by toggling a GPIO as the first thing I do in my code, then measuring the time between the GPIO trigger and this GPIO toggle on my scope

    2. If I get a second GPIO trigger in this 500msec period, it seems to reset my chip again, and I lose the contents of the LATCH register.  The RESETREAS register remains valid, but LATCH ends up getting reset to 0, which means I can't determine which GPIO caused the exit from System OFF.  I've even tried having a SYS_INIT call in PRE_KERNEL_2, where I make a change to the PIN_CNF[x] register for the appropriate GPIO, using

    NRF_GPIO->PIN_CNF[x] &= 0x02;

    so that I am disabling any influence these GPIO might have on the DETECT signal as early as possible.  That code gets run within the first 200-400usec of the GPIO trigger, when my trigger signal is still in the active state.  But its still not resolving my "sets LATCH to 0" problem.

    Sorry I'm not helping solve your issue, but between what I am doing, and what you are doing, we might collectively get to the bottom of it!

    Cheers,

    Mike

  • Hi Mike,

     

    You seem to be using NCS, based on the defines that you mention. When booting up, it requires the LFCLK source to run, which can take several 100 ms to start up.

    This will occur before main() is entered, and you've mitigated this issue by configuring your GPIOs in PRE_KERNEL, which is the preferred solution.

    Regarding LATCH issues, there are certain erratum's related to this that you should be aware of:

    https://infocenter.nordicsemi.com/topic/errata_nRF52832_Rev3/ERR/nRF52832/Rev3/latest/anomaly_832_173.html#anomaly_832_173

    https://infocenter.nordicsemi.com/topic/errata_nRF52832_Rev3/ERR/nRF52832/Rev3/latest/anomaly_832_210.html#anomaly_832_210

     

    That being mentioned, if you have an on-going thread, please use this thread to continue discussing your specific scenario.

     

    Kind regards,

    Håkon

  • Thanks Hakon.  That explains the start up delay.  I think I can work around that with my SYS_INIT approach.

    Looks like my issue with the LATCH register is related to having the following in my proj.config

    CONFIG_BOOTLOADER_MCUBOOT=y
    With that enabled, I will get LATCH reset if I have a second GPIO trigger within the 400msec start up period, even if I disable all inputs within my SYS_INIT function.  Without that in my proj.config, things seem to run as I would like them to - the first GPIO will trigger the device out of System OFF and any subsequent ones are just ignored.
    I have the CONFIG_BOOTLOADER_MCUBOOT=y in my proj.config because in my end applicaiton, I want to implement OTA DFU, and it was indicated in the example code that was required.
    Are you able to explain why that is impacting the LATCH register, but not the RESETREAS register, and whether there is a way to fix it and still be able to do OTA DFU?

    Regards,
    Mike
  • Hi Mike,

     

    Sounds like mcuboot is consuming your event.

    Try to disable CONFIG_GPIO in mcuboot. This can be done by creating the folder my_project/child_image/

     

    And in the child_image catalog, you create the file "mcuboot.conf" holding:

    CONFIG_GPIO=n

     

    Kind regards,

    Håkon

Reply Children
No Data
Related