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

Detect High to Low and Low to High EDGE using GPIO PORT Event

Hi,

I am using the pin change interrupt example provided in the SDK examples. By setting the input sense to NRF_GPIOTE_POLARITY_LOTOHI, the interrupt handler is called and in that i again set the input sense to NRF_GPIOTE_POLARITY_HITOLO so that next time it senses the high to low edge. But it never senses HITOLO. I am not able to find the reason for why this is happening.

Here is a example of the code

nrf_drv_gpiote_init();
nrf_drv_gpiote_out_init = GPIOTE_CONFIG_OUT_SIMPLE(false);
nrf_drv_gpiote_in_config_t in_config;
in_config.sense = NRF_GPIOTE_POLARITY_LOTOHI;
nrf_drv_gpiote_in_init(PIN_IN, &in_config, gpiote_event_handler);

Now in the event handler gpiote_event_handler case GPIOTE_CONFIG_POLARITY_LoToHi gets called in which i perform LED toggling and set the

in_config.sense = NRF_GPIOTE_POLARITY_HITOLO

Now the next time it should sense High to Low Edge but it never goes into the case GPIOTE_CONFIG_POLARITY_HiToLo

What could be the reason for this? I am using S110 and SDK10.

Parents
  • Looking at the nrf_drv_gpiote_in_init() function we see that in order for the sense to be changed the driver has to operate in high accuracy mode.

    ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,
                                      nrf_drv_gpiote_in_config_t const * p_config,
                                      nrf_drv_gpiote_evt_handler_t evt_handler)
    {
        ASSERT(pin < NUMBER_OF_PINS);
        ret_code_t result = NRF_SUCCESS;
        /* Only one GPIOTE channel can be assigned to one physical pin. */
        if (pin_in_use_by_gpiote(pin))
        {
            result = NRF_ERROR_INVALID_STATE;
        }
        else
        {
            int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy);
            if (channel != NO_CHANNELS)
            {
                if (p_config->is_watcher)
                {
                    nrf_gpio_cfg_watcher(pin);
                }
                else
                {
                    nrf_gpio_cfg_input(pin,p_config->pull);
                }
    
                if (p_config->hi_accuracy)
                {
                    nrf_gpiote_event_configure(channel, pin,p_config->sense);
                }
                else
                {
                    m_cb.port_handlers_pins[channel-NUMBER_OF_GPIO_TE] |= (p_config->sense)<< SENSE_FIELD_POS;
                }
            }
            else
            {
                result = NRF_ERROR_NO_MEM;
            }
        }
        return result;
    }
    

    Alternately you can just write to the register CONFIG[n] and set the polarity yourself, please refer to chapter 15 of the nRF 51 reference manual.

    Best regards,

    Øyvind

Reply
  • Looking at the nrf_drv_gpiote_in_init() function we see that in order for the sense to be changed the driver has to operate in high accuracy mode.

    ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,
                                      nrf_drv_gpiote_in_config_t const * p_config,
                                      nrf_drv_gpiote_evt_handler_t evt_handler)
    {
        ASSERT(pin < NUMBER_OF_PINS);
        ret_code_t result = NRF_SUCCESS;
        /* Only one GPIOTE channel can be assigned to one physical pin. */
        if (pin_in_use_by_gpiote(pin))
        {
            result = NRF_ERROR_INVALID_STATE;
        }
        else
        {
            int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy);
            if (channel != NO_CHANNELS)
            {
                if (p_config->is_watcher)
                {
                    nrf_gpio_cfg_watcher(pin);
                }
                else
                {
                    nrf_gpio_cfg_input(pin,p_config->pull);
                }
    
                if (p_config->hi_accuracy)
                {
                    nrf_gpiote_event_configure(channel, pin,p_config->sense);
                }
                else
                {
                    m_cb.port_handlers_pins[channel-NUMBER_OF_GPIO_TE] |= (p_config->sense)<< SENSE_FIELD_POS;
                }
            }
            else
            {
                result = NRF_ERROR_NO_MEM;
            }
        }
        return result;
    }
    

    Alternately you can just write to the register CONFIG[n] and set the polarity yourself, please refer to chapter 15 of the nRF 51 reference manual.

    Best regards,

    Øyvind

Children
Related