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

channel_port_alloc function

I'm going through pin_change_int example and can't understand how we tell controller where locate the function for our event. Probably it occures in channel_port_alloc that locate inside nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler); but where we point the function pointer... it seems we just fill out m_cb structure

static int8_t channel_port_alloc(uint32_t pin,nrf_drv_gpiote_evt_handler_t handler, bool channel)
{
    int8_t channel_id = NO_CHANNELS;
    uint32_t i;

    uint32_t start_idx = channel ? 0 : GPIOTE_CH_NUM; //(0, 8)
    uint32_t end_idx = channel ? GPIOTE_CH_NUM : (GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS);// (8, 9)
    //critical section
	 
    for (i = start_idx; i < end_idx; i++)
    {
        if (m_cb.handlers[i] == FORBIDDEN_HANDLER_ADDRESS)
        {
            pin_in_use_by_te_set(pin, i, handler, channel);
            channel_id = i;
            break;
        }
    }
    //critical section
    return channel_id;
}



_STATIC_INLINE void pin_in_use_by_te_set(uint32_t pin,
                                          uint32_t channel_id,
                                          nrf_drv_gpiote_evt_handler_t handler,
                                          bool is_channel)
{
    m_cb.pin_assignments[pin] = channel_id;
    m_cb.handlers[channel_id] = handler;
    if (!is_channel)
    {
        m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)pin;
    }
}
Parents
  • You should read the GPIOTE and GPIO chapters in the Product Specification.

    Here is also some code that will set up PORT event on button 1 and IN event on button 2:

    void gpiote_int_init()
    {
        nrf_gpio_cfg_sense_input(BUTTON_1, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
        nrf_gpio_cfg_input(BUTTON_2, NRF_GPIO_PIN_PULLUP);
    
        NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_MODE_Event       << GPIOTE_CONFIG_MODE_Pos)
                                |(GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                                |(BUTTON_2                      << GPIOTE_CONFIG_PSEL_Pos);
        
        NRF_GPIOTE->EVENTS_IN[0] = 0;
        NRF_GPIOTE->EVENTS_PORT = 0;
        
        NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_PORT_Enabled << GPIOTE_INTENSET_PORT_Pos);
        NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos);
        
        NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_LOW);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    }
    
    void GPIOTE_IRQHandler(void)
    {
        if(NRF_GPIOTE->EVENTS_PORT != 0)
        {
            NRF_GPIOTE->EVENTS_PORT = 0;
            //code on PORT event
        }
        if(NRF_GPIOTE->EVENTS_IN[0] != 0)
        {
            NRF_GPIOTE->EVENTS_IN[0] = 0;
            //code on IN[0] event
        } 
    }
    

    Call gpiote_int_init() in main (before while loop). The IRQ handler will be called when one of the buttons is pressed. nrf_gpio_cfg_.. functions set up the GPIO register, go to the definition of this functions to see how they set up the GPIO register. Hope this helps you understand how it works.

Reply
  • You should read the GPIOTE and GPIO chapters in the Product Specification.

    Here is also some code that will set up PORT event on button 1 and IN event on button 2:

    void gpiote_int_init()
    {
        nrf_gpio_cfg_sense_input(BUTTON_1, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
        nrf_gpio_cfg_input(BUTTON_2, NRF_GPIO_PIN_PULLUP);
    
        NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_MODE_Event       << GPIOTE_CONFIG_MODE_Pos)
                                |(GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)
                                |(BUTTON_2                      << GPIOTE_CONFIG_PSEL_Pos);
        
        NRF_GPIOTE->EVENTS_IN[0] = 0;
        NRF_GPIOTE->EVENTS_PORT = 0;
        
        NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_PORT_Enabled << GPIOTE_INTENSET_PORT_Pos);
        NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos);
        
        NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_LOW);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    }
    
    void GPIOTE_IRQHandler(void)
    {
        if(NRF_GPIOTE->EVENTS_PORT != 0)
        {
            NRF_GPIOTE->EVENTS_PORT = 0;
            //code on PORT event
        }
        if(NRF_GPIOTE->EVENTS_IN[0] != 0)
        {
            NRF_GPIOTE->EVENTS_IN[0] = 0;
            //code on IN[0] event
        } 
    }
    

    Call gpiote_int_init() in main (before while loop). The IRQ handler will be called when one of the buttons is pressed. nrf_gpio_cfg_.. functions set up the GPIO register, go to the definition of this functions to see how they set up the GPIO register. Hope this helps you understand how it works.

Children
No Data
Related