This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Trying to understand C code of an interrupt handler for buttons on TM4C123GXL



Hi to all of you!

I' m quite new to the world of "programming" and I' m trying to understand this piece of code written for the TM4C123GH6PM in the EK-TM4C123GXL Launchpad.

It' s the interrupt handler for the GPIO PORTF.

Though there are also some comments in the code below, I can't understand it completely.

The buttons used in the launchpad are: SW1 (connected to PF4) and SW2 (connected to PF0).

Here' s the code:

#define KEY_ENABLED_BUTTONS ( GPIO_INT_PIN_0 | GPIO_INT_PIN_4 )

static volatile uint32_t active_buttons;
static uint32_t fall_debounce;


void isr_keyboard (void)
{
	uint32_t int_status = HWREG(GPIO_PORTF_BASE + GPIO_O_RIS);
	uint32_t key_status = ~int_status | ~KEY_ENABLED_BUTTONS;
	/* compute just-pressed button mask */
	uint32_t pressed_buttons = ~(key_status | active_buttons);
	/* record button state */
	active_buttons |= pressed_buttons;
	fall_debounce |= pressed_buttons;
	/* Numb the port to debounce the key */
	HWREG(GPIO_PORTF_BASE + GPIO_O_IM) &= ~pressed_buttons;
        /* acknowledge interrupt */
        HWREG(GPIO_PORTF_BASE + GPIO_O_ICR) = int_status;

}

Could you help me to it, explaining me what ever line does? Thank you.

  • Hello Rain Bow,

    In simple words: It reads the interrupt status, masks the same with the enabled switches for interrupt and clears the interrupt status.

    The debounce logic involves reading the state of pin and disabling the Interrupt Mask, so that if there are multiple edges to the interrupt, it does no retrigger the interrupt for some time.

    Regards
    Amit
  • Thank you for the answer, Amit.

    Now I was thinking: if the pressed button is SW2, so the switch connected to PF0, I have: int_status=0x00000001.

    Besides, the value of KEY_ENABLED_BUTTONS is equal to (0x00000001 | 0x00000010), so 0x00000011.

    So, the value of key_status I think is: (~0x00000001 | ~0x00000011), so (0x1111111E | 0x111111EE) = 0x1111111E

    So, the value of pressed_buttons is: (~0x1111111E | 0x00000000), so (0x00000001 | 0x00000000) = 0x00000001

    So, since HWREG(GPIO_PORTF_BASE + GPIO_O_IM) &= ~pressed_buttons,

    the GPIOIM register has its bit 0 cleared,

    and, since HWREG(GPIO_PORTF_BASE + GPIO_O_ICR) = int_status,

    the GPIOICR register has its bit 0 setted.

    Am I right, or are there any errors?
  • Hello Rain Bow,

    You are confusing hex and binary. ~0x00000001 is 0xFFFFFFFE and not 0x1111111E

    Also note that there are 8 pins in a GPIO Port so the lower 8 bits would be used eventually.

    Regards
    Amit
  • Oh, sorry for the mistake!
    Yes, you're right, I've confused hex and binary in my notation, but in my head I was thinking right!

    So, aside this oversight, is my post above correct?

    PS: I know that a GPIO Port uses only the first 8 bits (0:7) of its registers, but, anyway, thanks for the observation!
  • Hello Rain Bow

    So, the value of key_status I think is: (~0x00000001 | ~0x00000011), so (0x1111111E | 0x111111EE) = 0x1111111E

    would be

    So, the value of key_status I think is: (~0x00000001 | ~0x00000011), so (0xFFFFFFFE | 0xFFFFFFEE) = 0xFFFFFFFE

    and so would the rest of the computation.

    Regards
    Amit