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

  • I found that the gpiote used by app_pwm conflicts with the key(pin31), which is really strange. All I have to do is mask app_pwm_init and the key will work.

  • Hi,

    kenyon said:
    I found that the gpiote used by app_pwm conflicts with the key(pin31), which is really strange. All I have to do is mask app_pwm_init and the key will work.

    So the issue is solved?

  • Hi Sigurd.
    Have not.
    I just found the crux of the conflict, but didn't know how to solve it. Because I looked at the code and found that pin31 was not reused anywhere else, and pin31 did not use interrupts for keystrokes. But once I've initialized both the keystroke and app_pwm, as soon as I press the keystroke, it goes to gpiote's handler and causes both Bluetooth and ble processes to fail, but when I release the keystroke, it works again. So I don't know how to solve this problem?

  • Hi,

    Could be similar to the issue as in this post here,  nrfx_gpiote_irq_handler() stucks when using TWIM  , I believe the issue there was doing both nrf_gpio_cfg_sense_input() and nrf_drv_gpiote_in_init() on the same pin. i.e. using gpio API to set sense input, and again using the GPIOTE API to configure the sense parameter. So if you try using the PIN for multiple things, and with different APIs, this could happen it seems.

  • Hi Sigurd.
    I didn't do sense and gpiote with the same pin. key(pin31) just use for sense.app pwm use no pin.
    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. 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.

    Thanks for your reply!

Related