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

GPIOTE can toggle led but cannot set boolean

board: nRF52 DK

[update - fixed this - see #2]

When I use the following (shortened) code, the LED blinks when I press button 2 but I see no logs. NRF_LOG_INFO() is working in other areas of the code.

#define BMA_TAP_INTERRUPT_PIN BUTTON_2
bool foo = false;

void bma_tap_interrupt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    nrf_drv_gpiote_out_toggle(LED1);
    foo = true;
}

void bma_enable_tap_interrupt(uint32_t pin, nrf_drv_gpiote_evt_handler_t evt_handler)
{
    ret_code_t ret_code;

    if (!nrf_drv_gpiote_is_init())
    {
        ret_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(ret_code);
    }

    nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    gpiote_config.pull = NRF_GPIO_PIN_PULLUP;

    ret_code = nrf_drv_gpiote_in_init(pin, &gpiote_config, evt_handler);
    APP_ERROR_CHECK(ret_code);

    nrf_drv_gpiote_in_event_enable(pin, true);

    NRF_LOG_INFO("initialised pin %d for tap intr", pin);

    /** for debug **/
    nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);

    ret_code = nrf_drv_gpiote_out_init(LED1, &out_config);
    APP_ERROR_CHECK(ret_code);
    /** for debug **/
}

int main(void)
{
    bma_enable_tap_interrupt(BMA_TAP_INTERRUPT_PIN, bma_tap_interrupt_handler);

    for (;;)
    {
        if (foo)
        {
            NRF_LOG_INFO("bar");
            foo = false;
        }
        idle_state_handle();
    }
}

It doesn't make sense to me that nrf_drv_gpiote_out_toggle(LED1) gets called but foo does not get set to true.

[#2]

For an extra challenge, when I add the following function call to main (setup pins: sck=2, dout=26), LED1 turns on but pressing button 2 does not actuate the led anymore.

void hx711_init(enum hx711_mode mode, struct hx711_setup *setup, hx711_evt_handler_t callback)
{
    ret_code_t ret_code;
    hx711_callback = callback;
    m_setup = setup;
    m_mode = mode;

    if (m_setup != NULL)
    {
        nrf_gpio_cfg_output(m_setup->pd_sck);
        nrf_gpio_pin_set(m_setup->pd_sck);

        if (!nrf_drv_gpiote_is_init())
        {
            ret_code = nrf_drv_gpiote_init();
            APP_ERROR_CHECK(ret_code);
        }

        nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
        nrf_gpio_cfg_input(m_setup->dout, NRF_GPIO_PIN_NOPULL);
        ret_code = nrf_drv_gpiote_in_init(m_setup->dout, &gpiote_config, gpiote_evt_handler);
        APP_ERROR_CHECK(ret_code);


        /* Set up timers, gpiote, and ppi for clock signal generation*/
        NRF_TIMER1->CC[0]     = 1;
        NRF_TIMER1->CC[1]     = HX711_DEFAULT_TIMER_COMPARE;
        NRF_TIMER1->CC[2]     = HX711_DEFAULT_TIMER_COUNTERTOP;
        NRF_TIMER1->SHORTS    = (uint32_t) (1 << 2);    //COMPARE2_CLEAR
        NRF_TIMER1->PRESCALER = 0;

        NRF_TIMER2->CC[0]     = m_mode;
        NRF_TIMER2->MODE      = 2;

        NRF_GPIOTE->CONFIG[1] = (uint32_t) (3 | (m_setup->pd_sck << 8) | (1 << 16) | (1 << 20));

        NRF_PPI->CH[0].EEP   = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0];
        NRF_PPI->CH[0].TEP   = (uint32_t) &NRF_GPIOTE->TASKS_SET[1];
        NRF_PPI->CH[1].EEP   = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[1];
        NRF_PPI->CH[1].TEP   = (uint32_t) &NRF_GPIOTE->TASKS_CLR[1];
        NRF_PPI->FORK[1].TEP = (uint32_t) &NRF_TIMER2->TASKS_COUNT; // Increment on falling edge
        NRF_PPI->CH[2].EEP   = (uint32_t) &NRF_TIMER2->EVENTS_COMPARE[0];
        NRF_PPI->CH[2].TEP   = (uint32_t) &NRF_TIMER1->TASKS_SHUTDOWN;
        NRF_PPI->CHEN = NRF_PPI->CHEN | 7;
    }
    else
    {
        NRF_LOG_WARNING("hx711 setup has not been assigned yet");
    }
}

For this problem, I suspect it has something to do with GPIOTE channels, but I can't watch the registers because my vscode cortex debugger is not working right now. I'm not overlapping  any pins I believe.

  • I added the fix to main after initialising both gpiote channels (using hx711_init and bma_enable_tap_interrupt)

    #define BMA_TAP_INTERRUPT_PIN BUTTON_2
    bool foo = false;
    
    void bma_tap_interrupt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        nrf_drv_gpiote_out_toggle(LED1);
        foo = true;
    }
    
    void bma_enable_tap_interrupt(uint32_t pin, nrf_drv_gpiote_evt_handler_t evt_handler)
    {
        ret_code_t ret_code;
    
        if (!nrf_drv_gpiote_is_init())
        {
            ret_code = nrf_drv_gpiote_init();
            APP_ERROR_CHECK(ret_code);
        }
    
        nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
        gpiote_config.pull = NRF_GPIO_PIN_PULLUP;
    
        ret_code = nrf_drv_gpiote_in_init(pin, &gpiote_config, evt_handler);
        APP_ERROR_CHECK(ret_code);
    
        nrf_drv_gpiote_in_event_enable(pin, true);
    
        NRF_LOG_INFO("initialised pin %d for tap intr", pin);
    
        /** for debug **/
        nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
        ret_code = nrf_drv_gpiote_out_init(LED1, &out_config);
        APP_ERROR_CHECK(ret_code);
        /** for debug **/
    }
    
    int main(void)
    {
        hx711_init() // when this is commented out, the bma tap interrupt works
        bma_enable_tap_interrupt(BMA_TAP_INTERRUPT_PIN, bma_tap_interrupt_handler);
        
        /* Add fix for errata 155 */
        uint32_t GPIOTE_CH_USED = 0;
        uint32_t GPIOTE_CH_USED_1 = 1;
        *(volatile uint32_t *)(NRF_GPIOTE_BASE + 0x600 + (4 * GPIOTE_CH_USED)) = 1;
        *(volatile uint32_t *)(NRF_GPIOTE_BASE + 0x600 + (4 * (GPIOTE_CH_USED_1))) = 1;
    
        for (;;)
        {
            if (foo)
            {
                NRF_LOG_INFO("bar");
                foo = false;
            }
            idle_state_handle();
        }
    }

    Still having the issue where when hx711_init() is called, pressing button 2 no longer triggers bma_tap_interrupt_handler(). When hx711_init() is commented out everything works fine

  • Hi,

    mbards said:
    Still having the issue where when hx711_init() is called, pressing button 2 no longer triggers bma_tap_interrupt_handler(). When hx711_init() is commented out everything works fine

    Could that be related to the NRF_GPIOTE->CONFIG[1] call inside that function? That seems to overwrite your "LED1" configuration? You should check the pin and action, as mentioned earlier; if the pin pulse is very short, the handler will be called twice in a short time frame, and its likely that your program will not work as intended.

     

    Kind regards,

    Håkon

Related