You are currently not logged in and your progress will not be saved. Register or Log in

Exercise 2

Controlling an LED through a button (interrupt based)

In this exercise, we will modify the application to use the more power-efficient interrupt-based method, like we explained in GPIO Generic API. Configure the button to generate an interrupt every time it is pressed. Then, inside the interrupt handler (callback function) of the button, we will toggle the LED.

Exercise Steps:

1. Download the base exercise project and extract it in your exercise folder for this course. We are using the previous exercise as a starting point.

2. Open the exercise code base in VS Code, as we did in the previous exercise.

3. Define a variable of type static struct gpio_callback. Search for STEP 3 in main.c and add the line below:

static struct gpio_callback button_cb_data;

4. Configure the interrupt on the pin by calling the function gpio_pin_interrupt_configure().

Search for STEP 4 in main.c and add the following code:  

    ret = gpio_pin_interrupt_configure(dev, SW0_GPIO_PIN, GPIO_INT_EDGE_TO_ACTIVE | GPIO_INT_DEBOUNCE);

5. Define the callback function button_pressed().

Search for STEP 5 and add the following code:

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

6. Initialize the static struct gpio_callback variable.

Search for STEP 6 and add the following line:

    gpio_init_callback(&button_cb_data, button_pressed, BIT(SW0_GPIO_PIN)); 

7. Add the callback function by calling gpio_add_callback().

Search for STEP 7 and add the following line:

    gpio_add_callback(dev, &button_cb_data);

8. We will get rid of all the polling code in the main loop and we will keep the call to the function k_msleep() to put the main thread (covered in Lesson 7) to sleep for a very long time.

9. Increase the sleep time in the main function from 100 ms to 10 minutes. This is done by changing the macro SLEEP_TIME_MS value from 100 to 10*60*1000.

More on this (Lesson 7)

In this example, there are no other high-priority threads running. Therefore, the idle thread will be called automatically to put the CPU to sleep. The CPU will wake up whenever the button is pressed, it will call the ISR which will toggle the LED. Then execution is resumed back to the infinite loop which will call the sleep function again.

Since the main function does not have any functionality aside from configuring the GPIO and the callback function, we let it yield by calling k_msleep() so the RTOS scheduler can select a ready thread to run. A better method would actually be calling k_yield() in the while-loop.

Lesson 7 will cover the different Zephyr system threads.

10. Build the exercise and flash it to the board. Just like in Exercise 1, observe that when button 1 is pressed, the LED is toggled.

You can download the solution for Exercise 2 below.