No ACL setup yet! Denying access to everyone.
en:edu:zmitac:s2:aih:lab:nrf52gpio

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:edu:zmitac:s2:aih:lab:nrf52gpio [2023/11/26 01:45] – ktokarzen:edu:zmitac:s2:aih:lab:nrf52gpio [2025/11/14 10:59] (current) – [Tasks for the laboratory on GPIO] ktokarz
Line 166: Line 166:
 } }
 </code> </code>
 +Some explanation of the "volatile" qualifier present in the example could help to clear some doubts. In general compilation and run of the above example without "volatile" should work properly. The troubles could start if there is some other part of the code that modifies the same registers. Because of optimization compiler could not read the port state but set it only, which could result in unexpected modification of other outputs. In general volatile qualifier should be used whenever the value of the variable could change unexpectedly. In practice, only three types of variables could change:
 +  * Shared global variable modified by an interrupt service routine, used also in the main program
 +  * Shared global variable within a multi-threaded application used by more than one thread
 +  * Memory-mapped peripheral registers
 +In our example, we have that third situation.
  
 ===== Button example ===== ===== Button example =====
Line 209: Line 214:
 ===== Tasks for the laboratory on GPIO ===== ===== Tasks for the laboratory on GPIO =====
   - Import the Blinky (zephyr_blink) example in the VS Code, as shown in the introduction to PlatformIO document.   - Import the Blinky (zephyr_blink) example in the VS Code, as shown in the introduction to PlatformIO document.
-  - Find a zephyr-button example. It's not importable as the project, so the simplest solution is to replace files main.c and prj.conf in the already imported project (e.g. Blinky). Files can be found in the folder <code>..\.platformio\packages\framework-zephyr\samples\basic\button\src</code>+  - Find a zephyr-button example. It's not importable as the project, so the simplest solution is to replace files main.c and prj.conf in the already imported project (e.g. Blinky). Files can be found in the folder <code>..\.platformio\packages\framework-zephyr\samples\basic\button\src</code> The Zephyr-button code is also attached to this instruction at the bottom.
   - Merge two projects “blink”, and “button” together to obtain the program that blinks LED0 continuously, calls the callback function with the interrupt generated with Button0, and controls the state of LED1 with Button1.   - Merge two projects “blink”, and “button” together to obtain the program that blinks LED0 continuously, calls the callback function with the interrupt generated with Button0, and controls the state of LED1 with Button1.
  
  
 +===== The code for the laboratory on GPIO =====
 +==== The Zephyr-button code example ====
 +<code c>
 +/*
 + * Copyright (c) 2016 Open-RnD Sp. z o.o.
 + * Copyright (c) 2020 Nordic Semiconductor ASA
 + *
 + * SPDX-License-Identifier: Apache-2.0
 + */
 + 
 +#include <zephyr/kernel.h>
 +#include <zephyr/device.h>
 +#include <zephyr/drivers/gpio.h>
 +#include <zephyr/sys/util.h>
 +#include <zephyr/sys/printk.h>
 +#include <inttypes.h>
 + 
 +#define SLEEP_TIME_MS 1
 + 
 +/*
 + * Get button configuration from the devicetree sw0 alias. This is mandatory.
 + */
 +#define SW0_NODE DT_ALIAS(sw0)
 +#if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
 +#error "Unsupported board: sw0 devicetree alias is not defined"
 +#endif
 +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios,
 +      {0});
 +static struct gpio_callback button_cb_data;
 + 
 +/*
 + * The led0 devicetree alias is optional. If present, we'll use it
 + * to turn on the LED whenever the button is pressed.
 + */
 +static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,
 +     {0});
 + 
 +void button_pressed(const struct device *dev, struct gpio_callback *cb,
 +    uint32_t pins)
 +{
 +printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());
 +}
 + 
 +int main(void)
 +{
 +int ret;
 + 
 +if (!gpio_is_ready_dt(&button)) {
 +printk("Error: button device %s is not ready\n",
 +       button.port->name);
 +return 0;
 +}
 + 
 +ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
 +if (ret != 0) {
 +printk("Error %d: failed to configure %s pin %d\n",
 +       ret, button.port->name, button.pin);
 +return 0;
 +}
 + 
 +ret = gpio_pin_interrupt_configure_dt(&button,
 +      GPIO_INT_EDGE_TO_ACTIVE);
 +if (ret != 0) {
 +printk("Error %d: failed to configure interrupt on %s pin %d\n",
 +ret, button.port->name, button.pin);
 +return 0;
 +}
 + 
 +gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
 +gpio_add_callback(button.port, &button_cb_data);
 +printk("Set up button at %s pin %d\n", button.port->name, button.pin);
 + 
 +if (led.port && !gpio_is_ready_dt(&led)) {
 +printk("Error %d: LED device %s is not ready; ignoring it\n",
 +       ret, led.port->name);
 +led.port = NULL;
 +}
 +if (led.port) {
 +ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT);
 +if (ret != 0) {
 +printk("Error %d: failed to configure LED device %s pin %d\n",
 +       ret, led.port->name, led.pin);
 +led.port = NULL;
 +} else {
 +printk("Set up LED at %s pin %d\n", led.port->name, led.pin);
 +}
 +}
 + 
 +printk("Press the button\n");
 +if (led.port) {
 +while (1) {
 +/* If we have an LED, match its state to the button's. */
 +int val = gpio_pin_get_dt(&button);
 + 
 +if (val >= 0) {
 +gpio_pin_set_dt(&led, val);
 +}
 +k_msleep(SLEEP_TIME_MS);
 +}
 +}
 +return 0;
 +}
 +</code>
en/edu/zmitac/s2/aih/lab/nrf52gpio.1700959504.txt.gz · Last modified: by ktokarz