GPIO
The phyCORE-RT1170 module provides extensive support for General-Purpose Input/Output (GPIO) pins. These pins can be configured as either inputs or outputs and many signals on the phyCORE Connector are available as GPIOs through pin multiplexing.
The i.MX RT1170 processor includes 13 independent GPIO controllers. For detailed hardware-level information, refer to the GPIO Interface chapter in the Hardware Manual.
GPIO Controller Mapping
Each GPIO controller is exposed as a device node in the system. To list all available GPIO controllers, you can use the Zephyr shell:
uart:~$ gpio devices
Device Other names
gpio@4012c000 gpio1
gpio@40138000 gpio4
gpio@4013c000 gpio5
gpio@40140000 gpio6
gpio@40c5c000 gpio7
gpio@40c60000 gpio8
gpio@40c64000 gpio9
gpio@40c68000 gpio10
gpio@40c6c000 gpio11
gpio@40c70000 gpio12
gpio@40ca0000 gpio13
gpio@40130000 gpio2
gpio@40134000 gpio3
gpio@42008000 fgpio2
gpio@4200c000 fgpio3
You can inspect the available GPIO lines within a specific controller by running:
uart:~$ gpio info gpio1
ngpios: 32
Reserved pin mask: 0x00000000
Reserved Pin Line Name
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Alternatively, run the command without arguments to list all GPIO lines across all controllers:
uart:~$ gpio info
Controlling GPIOs via Shell
The Zephyr GPIO Shell subsystem enables configuration and control of GPIO pins directly from the shell.
To configure a GPIO line (e.g., pin 13 on gpio@40c64000
/ gpio9
) as output:
uart:~$ gpio conf gpio9 13 o
To set the output value of the pin (e.g., turn LED2 located on the carrier-board on):
uart:~$ gpio set gpio9 13 1
To configure the button as input (e.g., pin 10 on gpio@40c68000
/ gpio10
):
uart:~$ gpio conf gpio10 2 i
After configuring a pin as input, you can read its current value:
uart:~$ gpio get gpio10 2
Example: If a button (e.g., S1 on the carrier board) is connected to the pin, press and release it between consecutive gpio get commands to observe the change in value.
Heartbeat LED Example
The heartbeat() function implements a blinking heartbeat LED with a specific pattern. The LED blinks in a sequence of short-short-long-off, where the short blink is 150ms on and 50ms off, and the long pause is 1 second.
GPIO API Usage
The heartbeat() function utilizes the Zephyr GPIO API to control the LED. Here’s a breakdown of the API functions used:
gpio_is_ready_dt()
: Checks if the GPIO device is ready to use. If not, the function returns without configuring the LED.gpio_pin_configure_dt()
: Configures the LED pin as an output using the device tree specification. The GPIO_OUTPUT_ACTIVE flag specifies that the LED pin should be configured as an active output.gpio_pin_set_dt()
: Sets the state of the LED pin. This function is used to turn the LED on (value 1) and off (value 0), creating the blink pattern.
GPIO Pin Configuration
The LED pin is configured using the gpio_pin_configure_dt() function, which takes the device tree specification (led) and configuration flags (GPIO_OUTPUT_ACTIVE). The device tree specification is obtained using the GPIO_DT_SPEC_GET() macro, which retrieves the GPIO specification from the devicetree node identified by the “led0” alias.
Controlling the LED State
The gpio_pin_set_dt() function is used to set the state of the LED pin. By passing the device tree specification (led) and the desired state (0 or 1), the LED can be turned on or off. In this example, the LED state is toggled to create the blink pattern, with error checking to handle any potential issues with setting the pin state.
Source Code
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
/* size of stack area used by each thread */
#define HEARTBEAT_STACKSIZE 1024
/* scheduling priority used by each thread */
#define HEARTBEAT_PRIORITY 5
/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)
/*
* A build error on this line means your board is unsupported.
* See the sample documentation for information on how to fix this.
*/
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
void heartbeat(void)
{
int ret;
if (!gpio_is_ready_dt(&led)) {
return;
}
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
return;
}
while (1) {
ret = gpio_pin_set_dt(&led, 1);
if (ret < 0) {
return;
}
k_sleep(K_MSEC(150));
ret = gpio_pin_set_dt(&led, 0);
if (ret < 0) {
return;
}
k_sleep(K_MSEC(50));
ret = gpio_pin_set_dt(&led, 1);
if (ret < 0) {
return;
}
k_sleep(K_MSEC(150));
ret = gpio_pin_set_dt(&led, 0);
if (ret < 0) {
return;
}
k_sleep(K_SECONDS(1));
}
}
K_THREAD_DEFINE(heartbeat_tid, HEARTBEAT_STACKSIZE, heartbeat, NULL, NULL,
NULL, HEARTBEAT_PRIORITY, 0, 0);
For more information see the heartbeat.c file.