Getting the Trigger Source for a interrupt inside a Signle Callback Function

Hi,

I am new to Nordic Semiconductors and Zephyr destribution.

I am trying to create a single callback function for multiple external interrupts from same port for a code library development.

Here is my code in IO.c library class:

ErrorCode configurePinInterrupt(PinList pin,button_event_handler_t buttonHandlerFn,gpio_flags_t interruptFlags){

    int ret = 0;
    uint8_t index = getPinIndex(pin);

    pressedButtonHandler = buttonHandlerFn;

    ret = gpio_pin_interrupt_configure_dt(&PinInfos[index].pinSpec,interruptFlags);

    if(ret!=0){
        setGPIO(LED1,HIGH);
        return GPIO_Pin_Set_Error;
    }
        
    gpio_init_callback(&intrcallBackStruct,interruptCallbackFn,BIT(PinInfos[index].pinSpec.pin));

    ret = gpio_add_callback(PinInfos[index].pinSpec.port,&intrcallBackStruct);
    if(ret!=0){
        setGPIO(LED1,HIGH);
        return GPIO_Pin_Set_Error;
    }
    
    return NO_ERROR;
}

static K_WORK_DELAYABLE_DEFINE (interruptDebouncing,buttonPressDebouncingHandler);

void interruptCallbackFn(const struct device *dev,struct gpio_callback *cb,uint32_t pins){

    currentPressedPin = Enable3V3;
    
    k_work_reschedule(&interruptDebouncing,K_MSEC(15));

}

void buttonPressDebouncingHandler(struct k_work buttonInterruptWork){

    ARG_UNUSED(buttonInterruptWork);

    int value = gpio_pin_get_dt(&PinInfos[getPinIndex(currentPressedPin)].pinSpec)?Button_Is_Pressed:Button_Is_Released;

    switch (value)
    {
        case Button_Is_Pressed:
            setGPIO(LED2,LOW);
            break;
        case Button_Is_Released:
            pressedButtonHandler(currentPressedPin);
            break;
    }

}

I need to find the pin number of the pin/pin spec inside "interruptCallbackFn" to differentiate between multiple external interrupt events.

Then I can pass that value to the main.c via pressedButtonHandler method.

Is there a way this can be done?

To make it easy:

1. A user can call the function "configurePinInterrupt" from main.c to configure interrupts for individual pins as below.

configurePinInterrupt(Enable3V3,enable3V3ButtonPressed,GPIO_INT_EDGE_RISING);
2. Then following method is invoked by the IO.c class, whenever an interrupt is generated.
void enable3V3ButtonPressed(PinList pin){

	switch (pin)
	{
		case Enable3V3:
			setGPIO(LED2,HIGH);
			break;
		
		default:
			break;
	}
}
Is there any possibility to achieve this functionality only using single callback function inside IO.c ?
Parents Reply
  • If you looked at the code, it printed 2048 and 4096 for those callbacks, and the switch case just uses 2048 and 4096.

    The reason for this is that it gives you the pin value in bit form. 

    Button0 was Pin 11

    Button1 was Pin 12.

    1 << 11 (Which is pin 11) = 2048

    1 << 12 (Which is pin 12) = 4096.

    Here's a visual aid.

    and within the device tree for the nRF52840dk this project was for:

    The callbacks in the example I gave say button1 and button2 in the printk, but it's button0 and button1. (I fixed this in the new commit just now.)

    I modified the project I linked you previously with some helpful print statements to illustrate this, as well as added button2 (pin24).

    You can identify the pin from the pins variable using & with the bit, or left shifting with the pin number.

    // Identifying pin # with shifting
    pins & (1 << pin_num)
    
    // Identifying pin # with bit
    pins & BIT(pin_num)

    As a heads up though, remember a switch case wants constant expressions. (Hence why I define the pinmsks at the top for the modified project)

    Here is the new output:

    best wishes,

Children
Related