Feedback
Feedback

If you are having issues with the exercises, please create a ticket on DevZone: devzone.nordicsemi.com
Click or drag files to this area to upload. You can upload up to 2 files.

Exercise 2

v2.8.x-v2.7.0

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. In VS Code, select Open an existing application, like we did in the previous exercise.

2. In the GitHub repository for this course, open the exercise code base for this exercise, found in l2/l2_e2 of the directory 2.8.x-v2.7.0.

3. Configure the interrupt on the button’s pin.

Configure an interrupt on the pin associated with the button by calling the function gpio_pin_interrupt_configure_dt().

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

ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
C

4. Define the callback function button_pressed().

Define the callback function that will run when the button is pressed to toggle the LED.

Search for STEP 4 and add the following code:

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    gpio_pin_toggle_dt(&led);
}
C

5. Define a variable of type static struct gpio_callback.

Search for STEP 5 in main.c and add the line below:

static struct gpio_callback button_cb_data;
C

6. Initialize the static struct gpio_callback variable.

Initialize the struct gpio_callback button_cb_data by passing this variable, along with the callback function and the bit mask for the GPIO pin button.pin to gpio_init_callback().

Search for STEP 6 and add the following line:

gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); 	
C

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

Search for STEP 7 and add the following line:

gpio_add_callback(button.port, &button_cb_data);
C

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

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. Observe that when button 1 is pressed, the LED1 is toggled (on nRF54 DKs, it’s button 0 and LED0).

The solution for this exercise can be found in the GitHub repository, l2/l2_2_sol of the directory v2.8.x-v2.7.0

v2.6.2-v2.0.0

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. In VS Code, select Open an existing application, like we did in the previous exercise.

2. In the GitHub repository for this course, open the exercise code base for this exercise, found in l2/l2_e2 of the directory v2.6.2-v2.0.0.

3. Configure the interrupt on the button’s pin.

Configure an interrupt on the pin associated with the button by calling the function gpio_pin_interrupt_configure_dt().

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

ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
C

4. Define the callback function button_pressed().

Define the callback function that will run when the button is pressed to toggle the LED.

Search for STEP 4 and add the following code:

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    gpio_pin_toggle_dt(&led);
}
C

5. Define a variable of type static struct gpio_callback.

Search for STEP 5 in main.c and add the line below:

static struct gpio_callback button_cb_data;
C

6. Initialize the static struct gpio_callback variable.

Initialize the struct gpio_callback button_cb_data by passing this variable, along with the callback function and the bit mask for the GPIO pin button.pin to gpio_init_callback().

Search for STEP 6 and add the following line:

gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); 	
C

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

Search for STEP 7 and add the following line:

gpio_add_callback(button.port, &button_cb_data);
C

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

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. Observe that when button 1 is pressed, the LED is toggled.

The solution for this exercise can be found in the GitHub repository, l2/l2_2_sol of the directory v2.6.2-v2.0.0

v1.9.1-v1.6.0

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. In VS Code, select Add an existing application, like we did in the previous exercise.

2. In the GitHub repository for this course, open the exercise code base for this exercise, found in l2/l2_e2 of the directory v1.9.1-v1.6.0.

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)
{
    gpio_pin_toggle(dev,PIN);
}

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

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.

The solution for this exercise can be found in the GitHub repository, l2/2_2_sol of the directory v1.9.1-v1.6.0.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.