The problem that keys occupy the process

SDK:17.1.0
application: ble_app_uart(+ble_app_buttonless dfu service)
bootloader:secure bootloader pca10040e_s112_ble

Background:
There is only one key(pin:31) on the PCBA board, through which you can enter the DFU and wake up from power off mode to enter the main application.

Content of application:

One button,six LEDs.
app_pwm(TIMER1)1.timeout of 1ms    2.calculate the key input time

drv_pwm:Realize pwm output of LED

When the key starts, you can change the light mode by pressing the button.

But 
mainloop and app_timeout_handler do not run when the key is pressed and not released. Only when the key is released will the program work properly. When I was debugging, I found that after pressing a key, the port_event_handler kept getting stuck.

static void port_event_handle(uint32_t * latch)
{
    do {
        for (uint32_t i = 0; i < NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++)
        {
            if (m_cb.port_handlers_pins[i] == PIN_NOT_USED)
            {
                continue;
            }

            /* Process pin further only if LATCH bit associated with this pin was set. */
            nrfx_gpiote_pin_t pin = port_handler_pin_get(i);
            if (nrf_bitmask_bit_is_set(pin, latch))
            {
                nrf_gpiote_polarity_t polarity = port_handler_polarity_get(i);
                nrf_gpio_pin_sense_t sense     = nrf_gpio_pin_sense_get(pin);

                NRFX_LOG_DEBUG("PORT event for pin: %d, polarity: %d.", pin, polarity);

                /* 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;
                nrf_gpio_cfg_sense_set(pin, next_sense);

                /* Try to clear LATCH bit corresponding to currently processed pin.
                 * This may not succeed if the pin's state changed during the interrupt processing
                 * and now it matches the new sense configuration. In such case,
                 * the pin will be processed again in another iteration of the outer loop. */
                nrf_gpio_pin_latch_clear(pin);

                /* Invoke user handler only if the sensed pin level
                 * matches its polarity configuration. */
                nrfx_gpiote_evt_handler_t handler =
                    channel_handler_get((uint32_t)channel_port_get(pin));
                if (handler &&
                    ((polarity == NRF_GPIOTE_POLARITY_TOGGLE) ||
                     (sense == NRF_GPIO_PIN_SENSE_HIGH && polarity == NRF_GPIOTE_POLARITY_LOTOHI) ||
                     (sense == NRF_GPIO_PIN_SENSE_LOW && polarity == NRF_GPIOTE_POLARITY_HITOLO)))
                {
                    handler(pin, polarity);
                }
            }
        }
    } while (latch_pending_read_and_check(latch));
}


I think this is usually caused by nrf_delay_ms, but I didn't use it in the code. Timing is achieved by app_pwm.

Hopefully I've made it clear enough that you can read it. I don't quite understand this phenomenon. Could you give me some ideas to solve the problem?5554.sdk_config.h

  • kenyon said:
    I got to the root of the problem. As you described, sense and port event conflict in gpiote. I configured the NRF_GPIO_PIN_SENSE_LOW trigger mode in the key to do the wake-up foot. Then in app_pwm there is the function of configuring gpiote. I did not redefine the trigger mode of the key to NRF_GPIO_PIN_SENSE_NONE when the key woke up. Therefore, the subsequent pwm work and keys occupy gpiote at the same time, resulting in the entire program working abnormal. Although I changed the key trigger mode to NRF_GPIO_PIN_SENSE_NONE after waking up, the program returned to normal

    Great!

    kenyon said:
    But I wonder if there is an easier way to deal with this gpiote occupancy conflict. Because I have no problem configuring gpiote function in key and pwm in SDK11 products.

    No, I'm not aware of any other ways. There have been several changes to the gpiote driver since SDK 11.

  • Hi Sigurd,

    Kenyon and I found that:

    1. The PWM module "app_pwm" enabled "Port Event" in "nrfx_gpiote_init". (This is ok.)
    2. Our sense button (P0.01) will trigger the "Port Event" and its ISR "port_event_handle". (This is ok.)
    3. Then the "nrf_gpio_latches_read_and_clear" will clear the register "LATCH" which makes our key scanning routine can not get any change of bit P0.01 of register "IN". (This is something wrong we think.)

    So our questions are:

    • Should "nrf_gpio_latches_read_and_clear" check the owner of each bit before clearing?
    • Does the clearing of the bit of "LATCH" indeed affect the register "IN" as we tested?

    Thanks!

  • Hi Sigurd,

    I think you may not receive the update of this ticket anymore since it's "Verified Answer".

    So I created another ticket: Nordic DevZone (nordicsemi.com).

    Thanks!

Related