0% found this document useful (0 votes)
17 views3 pages

To Interact With The General

Uploaded by

psjacome
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views3 pages

To Interact With The General

Uploaded by

psjacome
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 3

To interact with the General-Purpose Input/Output the device pointer as well as the pin number and

(GPIO) peripheral, we can use the generic configuration flags.


API <zephyr/drivers/gpio.h>, which provides user-
The advantage of this API-specific structure is that
friendly functions to interact with GPIO peripherals.
it encapsulates all the information needed to use
The GPIO peripheral can be used to interact with a
the device in a single variable, instead of having to
variety of external components such as switches,
extract it from the devicetree line by line.
buttons, and LEDs.
Let’s take led_0 as an example, which has the
When using any driver in Zephyr, the first step is to
devicetree implementation shown below:
initialize it by retrieving the device pointer. For a
GPIO pin, the first necessary step after that is to
configure the pin to be either an input or an output
pin. Then you can write to an output pin or read
from an input pin. In the following paragraphs,
these four steps will be covered in detail.

Initializing the API From the image above, we can see that the
Some of the generic APIs in Zephyr have API- property containing all this information is
specific structs that contain the previously called gpios, and is the property name to pass
mentioned device pointer, as well as some other to GPIO_DT_SPEC_GET():
information about the device. In the GPIO API, this static const struct gpio_dt_spec led =
is the structure gpio_dt_spec. This structure has GPIO_DT_SPEC_GET(LED0_NODE, gpios);
the device pointer const struct device * port, as
well as the pin number on the device, gpio_pin_t This function will return a struct of
pin, and the device’s configuration type gpio_dt_spec with the device pointer for the
flags, gpio_dt_flags_t dt_flags. GPIO controller, &gpio0, the pin number led.pin =
13 and the flag led.dt_flags = GPIO_ACTIVE_LOW.
The port is the GPIO device controlling the pin. Pins
are usually grouped and controlled by a single GPIO Before using the device pointer contained
port. On most Nordic SoCs, there are either one or in gpio_dt_spec led, we need to check if it’s ready
two GPIO controllers, named GPIO0 or GPIO1. using gpio_is_ready_dt().

To retrieve this structure, we need to use the API- if (!gpio_is_ready_dt(&led)) {


specific function GPIO_DT_SPEC_GET(), which has return 0;
the following signature:
}

Configure a single pin

Similar This is done by calling the


to DEVICE_DT_GET(), GPIO_DT_SPEC_GET() also function gpio_pin_configure_dt().
takes the devicetree node identifier. It also takes With this function, you can configure a pin to be an
the property name of the node. The function will input GPIO_INPUT or an
return a variable of type gpio_dt_spec, containing output GPIO_OUTPUT through the second
parameter flags as shown in the examples below.
The following line configures the pin associated For example, the following line reads the current
with gpio_dt_spec led, which can be denoted status of led.pin saves it in a variable called val.
as led.pin, as an output pin:
val = gpio_pin_get_dt(&led);
gpio_pin_configure_dt(&led, GPIO_OUTPUT);
The drawback of the polling method is that you
You can also specify other hardware characteristics have to repeatedly call gpio_pin_get_dt() to keep
to a pin like the drive strength, pull up/pull down track of the status of a pin. This is usually not
resistors, active high or active low. Different optimal from performance and power perspectives
hardware characteristics can be combined through as it requires the CPU’s constant attention. It’s a
the | operator. Again, this is done using the simple method, yet not power-efficient.
parameter flags.
Interrupt method
The following line configures the pin led.pin as an
In this method, the hardware will notify the CPU
output that is active low.
once there is a change in the status of the pin. This
gpio_pin_configure_dt(&led, GPIO_OUTPUT | is the recommended way to read an input pin as it
GPIO_ACTIVE_LOW); frees the CPU from the burden of repeatedly
polling the status of the pin. You can put the CPU to
Write to an output pin
sleep and only wake it up when there is a change.
Writing to an output pin is straightforward by using
The following are the general steps needed to set
the function gpio_pin_set_dt().
up an interrupt on a GPIO pin.
For example, the following line sets the pin
1. Configure the interrupt on a pin.
associated with gpio_dt_spec led, which can be
denoted as led.pin, to logic 1 “active state”: This is done by calling the
function gpio_pin_interrupt_configure_dt(),
gpio_pin_set_dt(&led, 1);
Through the second parameter flags, you can
this would set pin 13 to logic 1 “active state”.
configure whether you want to trigger the interrupt
You can also use the gpio_pin_toggle_dt() function on rising edge, falling edge, or both. Or change to
to toggle an output pin. logical level 1, logical level 0, or both.

gpio_pin_toggle_dt(&led); The following line will configure an interrupt


on dev.pin on the change to logical level 1.
Read from an input pin
gpio_pin_interrupt_configure_dt(&button,GPIO_IN
Reading a pin configured as an input is not as
T_EDGE_TO_ACTIVE);
straightforward as writing to a pin configured as an
output. There are two possible methods to read All interrupt flag options are documented here,
the status of an input pin: under GPIO interrupt configuration flags.

Polling method 2. Define the callback function pin_isr().

Polling means continuously reading the status of The callback function is called when an interrupt is
the pin to check if it has changed. To read the triggered.
current status of a pin, all you need to do is to call
Definition
the function gpio_pin_get_dt(),
Callback function: Also known as an interrupt For example, the following line will initialize
handler or an Interrupt Service Routine (ISR). It the pin_cb_data variable with the callback
runs asynchronously in response to a hardware or function pin_isr and the bit mask of pin dev.pin.
software interrupt. In general, ISRs have higher Note the use of the macro BIT(n), which simply gets
priority than all threads (covered in Lesson 7). It an unsigned integer with bit position n set.
preempts the execution of the current thread,
gpio_init_callback(&pin_cb_data, pin_isr,
allowing an action to take place immediately.
BIT(dev.pin));
Thread execution resumes only once all ISR work
has been completed. For example, the following line adds the callback
function that we set up in the previous steps.
The signature (prototype) of the callback function is
shown below: gpio_add_callback(button.port, &pin_cb_data);

void pin_isr(const struct device *dev, struct 1. Include modules


gpio_callback *cb, gpio_port_pins_t pins);
The blinky sample uses the following modules in
What you put inside the body of an ISR is highly the nRF Connect SDK:
application-dependent. For instance, the following
 Kernel services <zephyr/kernel.h> for the
ISR toggles a LED every time the interrupt is
sleep function k_msleep(). This header is
triggered.
called the Public kernel API header.
void pin_isr(const struct device *dev, struct
 The generic GPIO
gpio_callback *cb, uint32_t pins)
interface <zephyr/drivers/gpio.h> for the
{ structure gpio_dt_spec, the
macros GPIO_DT_SPEC_GET(), and the
gpio_pin_toggle_dt(&led);
functions, gpio_is_ready_dt(), gpio_pin_con
} figure_dt() and gpio_pin_toggle_dt().

Define a variable of type static  Define the node identifier


struct gpio_callback as shown in the code line  The line below uses the devicetree
below. macro DT_ALIAS() to get the node
static struct gpio_callback pin_cb_data; identifier symbol LED0_NODE, which will
represent LED1
The pin_cb_data gpio callback variable will hold (node led_0). Remember from
information such as the pin number and the the Devicetree section that led_0 node
function to be called when an interrupt occurs is defined in the devicetree of the
(callback function). DK. LED0_NODE is now the source code
4. Initialize the gpio callback symbol that represents the hardware for
variable pin_cb_data using gpio_init_callback(). LED1.
 The DT_ALIAS() macro gets the node
This gpio_callback struct variable stores the identifier from the node’s alias, which as
address of the callback function and the bitmask we saw in the Devicetree section,
relevant to the pin. Use the is led0.
function gpio_init_callback() to do this initialization.

You might also like