GPIO Control Program Description
1. Overview¶
This document mainly introduces how to configure padmux on PCUPID to implement GPIO multiplexing function, mainly referring to [GPIO User Guide]".
2. Keywords¶
dts/dtsi:
Linux device tree files are usually used to describe peripherals supported by the CPU. The attribute values contained in the peripheral nodes can be used to configure the peripherals.
padmux:
Pin multiplexing is used to connect the module function pins to specific external pins to open up signal connections.
Table 1: PCUPID GPIO index and PAD correspondence table
| Pad Name | GPIO Index | Pad Name | GPIO Index | Pad Name | GPIO Index | Pad Name | GPIO Index |
|---|---|---|---|---|---|---|---|
| PAD_UART0_TX | 0 | PAD_GPIOE_28 | 37 | PAD_GPIOB_04 | 74 | PAD_SAR_ADC0_05 | 111 |
| PAD_PWM_OUT00 | 1 | PAD_GPIOA_00 | 38 | PAD_GPIOB_05 | 75 | PAD_SAR_ADC0_06 | 112 |
| PAD_PWM_OUT01 | 2 | PAD_GPIOA_01 | 39 | PAD_GPIOB_06 | 76 | PAD_SAR_ADC0_07 | 113 |
| PAD_SPI_CK | 3 | PAD_GPIOA_02 | 40 | PAD_GPIOB_07 | 77 | PAD_SAR_ADC0_08 | 114 |
| PAD_SPI_HLD | 4 | PAD_GPIOA_03 | 41 | PAD_GPIOB_08 | 78 | PAD_SAR_ADC0_09 | 115 |
| PAD_SPI_CZ | 5 | PAD_GPIOA_04 | 42 | PAD_OUTP_RX0_CH0 | 79 | PAD_SAR_ADC0_10 | 116 |
| PAD_SPI_WPZ | 6 | PAD_GPIOA_05 | 43 | PAD_OUTN_RX0_CH0 | 80 | PAD_SAR_ADC0_11 | 117 |
| PAD_SPI_DI | 7 | PAD_GPIOA_06 | 44 | PAD_OUTP_RX0_CH1 | 81 | PAD_SAR_ADC0_12 | 118 |
| PAD_SPI_DO | 8 | PAD_GPIOA_07 | 45 | PAD_OUTN_RX0_CH1 | 82 | PAD_SAR_ADC0_13 | 119 |
| PAD_GPIOE_00 | 9 | PAD_GPIOA_08 | 46 | PAD_OUTP_RX0_CH2 | 83 | PAD_SAR_ADC0_14 | 120 |
| PAD_GPIOE_01 | 10 | PAD_GPIOA_09 | 47 | PAD_OUTN_RX0_CH2 | 84 | PAD_PWM_ADC01 | 121 |
| PAD_GPIOE_02 | 11 | PAD_GPIOA_10 | 48 | PAD_OUTP_RX0_CH3 | 85 | PAD_PWM_ADC00 | 122 |
| PAD_GPIOE_03 | 12 | PAD_GPIOA_11 | 49 | PAD_OUTN_RX0_CH3 | 86 | PAD_GPIOD_01 | 123 |
| PAD_GPIOE_04 | 13 | PAD_EMMC_RST | 50 | PAD_GPIOC_00 | 87 | PAD_GPIOD_02 | 124 |
| PAD_GPIOE_05 | 14 | PAD_EMMC_CLK | 51 | PAD_GPIOC_01 | 88 | PAD_GPIOD_03 | 125 |
| PAD_GPIOE_06 | 15 | PAD_EMMC_CMD | 52 | PAD_GPIOC_02 | 89 | PAD_GPIOD_00 | 126 |
| PAD_GPIOE_07 | 16 | PAD_EMMC_DS | 53 | PAD_GPIOC_03 | 90 | PAD_UART0_RX | 127 |
| PAD_GPIOE_08 | 17 | PAD_EMMC_D3 | 54 | PAD_GPIOC_04 | 91 | PAD_PM_GPIO4 | 128 |
| PAD_GPIOE_09 | 18 | PAD_EMMC_D4 | 55 | PAD_GPIOC_05 | 92 | PAD_PM_GPIO5 | 129 |
| PAD_GPIOE_10 | 19 | PAD_EMMC_D0 | 56 | PAD_GPIOC_06 | 93 | PAD_PM_PWM1_OUT | 130 |
| PAD_GPIOE_11 | 20 | PAD_EMMC_D5 | 57 | PAD_GPIOC_07 | 94 | PAD_PM_I2C_SDA | 131 |
| PAD_GPIOE_12 | 21 | PAD_EMMC_D1 | 58 | PAD_GPIOC_08 | 95 | PAD_PM_PWM0_OUT | 132 |
| PAD_GPIOE_13 | 22 | PAD_EMMC_D6 | 59 | PAD_OUTP_CH0 | 96 | PAD_PM_I2C_SCL | 133 |
| PAD_GPIOE_14 | 23 | PAD_EMMC_D2 | 60 | PAD_OUTN_CH0 | 97 | PAD_PM_GPIO1 | 134 |
| PAD_GPIOE_15 | 24 | PAD_EMMC_D7 | 61 | PAD_OUTP_CH1 | 98 | PAD_PM_GPIO3 | 135 |
| PAD_GPIOE_16 | 25 | PAD_GPIOA_12 | 62 | PAD_OUTN_CH1 | 99 | PAD_PM_UART1_TX | 136 |
| PAD_GPIOE_17 | 26 | PAD_GPIOA_13 | 63 | PAD_OUTP_CH2 | 100 | PAD_PM_GPIO2 | 137 |
| PAD_GPIOE_18 | 27 | PAD_GPIOA_14 | 64 | PAD_OUTN_CH2 | 101 | PAD_PM_GPIO7 | 138 |
| PAD_GPIOE_19 | 28 | PAD_GPIOA_15 | 65 | PAD_OUTP_CH3 | 102 | PAD_PM_GPIO6 | 139 |
| PAD_GPIOE_20 | 29 | PAD_GPIOA_16 | 66 | PAD_OUTN_CH3 | 103 | PAD_PM_UART1_RX | 140 |
| PAD_GPIOE_21 | 30 | PAD_GPIOA_17 | 67 | PAD_OUTP_CH4 | 104 | PAD_PM_ADC00_IN | 141 |
| PAD_GPIOE_22 | 31 | PAD_GPIOA_18 | 68 | PAD_OUTN_CH4 | 105 | PAD_PM_GPIO0 | 142 |
| PAD_GPIOE_23 | 32 | PAD_GPIOA_19 | 69 | PAD_SAR_ADC0_00 | 106 | ||
| PAD_GPIOE_24 | 33 | PAD_GPIOB_00 | 70 | PAD_SAR_ADC0_01 | 107 | ||
| PAD_GPIOE_25 | 34 | PAD_GPIOB_01 | 71 | PAD_SAR_ADC0_02 | 108 | ||
| PAD_GPIOE_26 | 35 | PAD_GPIOB_02 | 72 | PAD_SAR_ADC0_03 | 109 | ||
| PAD_GPIOE_27 | 36 | PAD_GPIOB_03 | 73 | PAD_SAR_ADC0_04 | 110 |
3.Uboot configuration¶
3.1. uboot config is configured as follows
[*] SigmaStar drivers --->
[*] SigmaStar GPIO
[*] SigmaStar padmux
3.2. DTS configuration is as follows, compatible is generally not modified, status is configured as okay/disabled as needed.
gpio: gpio {
compatible = "sstar,gpio";
tatus = "okay";
};
3.3. Use of uboot cmd
gpio input <gpio#> --> gpio input 69 // gpio69 set as input gpio set <gpio#> --> gpio set 10 // gpio10 set as output high gpio clear <gpio#> --> gpio clear 49 // gpio49 set as output low gpio toggle <gpio#> --> gpio toggle 49 // gpio49 level toggle gpio status <gpio#> --> gpio status 20 // gpio20 status
4. kernel related configuration¶
4.1. kernel config configuration instructions
Device Drivers --->
[*] GPIO Support --->
[*] /sys/class/gpio/... (sysfs interface)
[*] SStar SoC platform drivers --->
[*] Sstar GPIO driver
[*] Sstar PADMUX driver
4.2. dts parameter configuration instructions
gpio: gpio {
compatible = "sstar,gpio";
#gpio-cells = <2>;
status = "okay";
};
| Properties | Description | Notes |
|---|---|---|
| compatible | Used to match the driver for driver registration | Modification is prohibited |
| #gpio-cells | Declare the number of device node gpio cells | Configuring 2 means the first cell is the gpio number, and the second cell indicates the gpio effective level |
| status | Driver switch | Configure as needed, ok/disabled |
5. Introduction to reuse functions¶
When you need to use the GPIO multiplexing function, you first need to obtain the name of the PIN to be operated and the mux mode to be multiplexed, and configure them in xxx-padmux.dtsi:
<PAD_GPIOC_02 PINMUX_FOR_I2S0_MCK_MODE_1 MDRV_PUSE_I2S0_MCK>, <PAD_GPIOC_03 PINMUX_FOR_I2S0_RX_MODE_1 MDRV_PUSE_I2S0_RX_BCK>, <PAD_GPIOC_04 PINMUX_FOR_I2S0_RX_MODE_1 MDRV_PUSE_I2S0_RX_WCK>, <PAD_GPIOC_05 PINMUX_FOR_I2S0_RX_MODE_1 MDRV_PUSE_I2S0_RX_SDI>, <PAD_GPIOC_06 PINMUX_FOR_I2S0_TX_MODE_1 MDRV_PUSE_I2S0_TX_SDO>, <PAD_GPIOC_07 PINMUX_FOR_I2S0_TX_MODE_1 MDRV_PUSE_I2S0_TX_BCK>, <PAD_GPIOC_08 PINMUX_FOR_I2S0_TX_MODE_1 MDRV_PUSE_I2S0_TX_WCK>,
As shown in the above I2S0 configuration, the first column is the pad name, which can be obtained from Table 1 (or refer to /drivers/sstar/include/pcupid/gpio.h), the second column indicates the pad multiplexing mode (refer to /drivers/sstar/include/pcupid/padmux.h), and the third column is the name of the current padmux configuration (refer to /drivers/sstar/include/drv_puse.h), which is also the function of the pad in the current mode.
Taking PAD_GPIOC_02 as an example, the modes it supports are shown in Table 2. When the pad is used as the MCLK output master clock signal of I2S0, it needs to be configured as PINMUX_FOR_I2S0_MCK_MODE_1 ; and when used as PWM2, it needs to be configured as PINMUX_FOR_PWM2_MODE_1 .
Table 2: List of modes supported by PAD_GPIOC_02
| mode | mode | mode |
|---|---|---|
| PINMUX_FOR_GPIO_MODE | PINMUX_FOR_FUART_MODE_2 | PINMUX_FOR_FUART_2W_MODE_2 |
| PINMUX_FOR_I2S0_MCK_MODE_1 | PINMUX_FOR_BT656_OUT_MODE_1 | PINMUX_FOR_TTL24_MODE_1 |
| PINMUX_FOR_TTL18_MODE_1 | PINMUX_FOR_TTL18_MODE_2 | PINMUX_FOR_TTL16_MODE_1 |
| PINMUX_FOR_TTL16_MODE_2 | PINMUX_FOR_TTL_SRGB8_MODE_1 | PINMUX_FOR_LCD8_MODE_1 |
| PINMUX_FOR_LCD16_MODE_1 | PINMUX_FOR_LCD18_MODE_1 | PINMUX_FOR_PWM2_MODE_1 |
| PINMUX_FOR_IR2_IN_MODE_1 | PINMUX_FOR_PSPI0_G_MODE_1 | PINMUX_FOR_PSPI1_4W_MODE_2 |
After the configuration is complete, you need to check whether other pads are configured in the same mode, or the same pad is configured in another mode. This will cause conflicts and may make the configured padmux invalid. You need to comment it out or reselect the pad.
// Take DMIC as an example to demonstrate the conflict situation //SDMMC1 ... <PAD_GPIOA_07 PINMUX_FOR_GPIO_MODE MDRV_PUSE_SDIO0_PWR>, ... //DMIC <PAD_GPIOA_07 PINMUX_FOR_DMIC_8CH_MODE_3 MDRV_PUSE_DMIC0_CLK>, ...
As shown above, the PAD_GPIO_07 pin is configured in dtsi at the same time, and is configured in GPIO mode and DMIC respectively, used as SDIO pwr and DMIC clk. If one of the configurations is not commented out, one of the configured functions is destined to be due to pin conflict. It is not available.
To summarize the things to note:
-
A pad can only be configured in one mode. If multiple modes are configured, conflicts will occur.
-
One MDRV_PUSE_XXX can only correspond to one set of pad configurations. There cannot be multiple sets of the same MDRV_PUSE_XXX configurations, otherwise there will be conflicts;
-
The configured pad and mode need to correspond.
6. Sample code¶
The user space control gpio code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define GPIO_93_PIN "93"
#define GPIO_DIR_VAL "out"
#define GPIO_VAL_H "1"
#define GPIO_VAL_L "0"
int main(int argc, char *argv[])
{
char buff[2] = {0};
int gpio_val_fd = 0;
int gpio_dir_fd = 0;
int gpio_export_fd = 0;
int pin_val = 0;
gpio_export_fd = open("/sys/class/gpio/export", O_WRONLY);
if (gpio_export_fd < 0)
{
printf("open gpio export failed\n");
return -1;
}
else
{
write(gpio_export_fd, GPIO_93_PIN, sizeof(GPIO_93_PIN));
}
gpio_dir_fd = open("/sys/devices/gpiochip0/gpio/gpio93/direction", O_RDWR);
if (gpio_val_fd < 0)
{
close(gpio_export_fd);
printf("open direction failed\n");
return -2;
}
write(gpio_dir_fd, GPIO_DIR_VAL, sizeof(GPIO_DIR_VAL));
gpio_val_fd = open("/sys/class/gpio/gpio93/value", O_RDWR);
if (gpio_val_fd == -1)
{
printf("gpio open failed\n");
close(gpio_export_fd);
close(gpio_dir_fd);
return -3;
}
else
{
printf("/sys/class/gpio/gpio93/value\n");
}
memset(buff, 0, 2);
read(gpio_val_fd, buff, 1);
pin_val = atoi(buff);
printf("first read gpio val %d, %s\n", pin_val, buff);
write(gpio_val_fd, GPIO_VAL_H, sizeof(GPIO_VAL_H));
close(gpio_val_fd);
gpio_val_fd = open("/sys/class/gpio/gpio93/value", O_RDWR);
memset(buff, 0, 2);
read(gpio_val_fd, buff, 1);
pin_val = atoi(buff);
printf("after write 1,second read gpio val %d, %s\n", pin_val, buff);
write(gpio_val_fd, GPIO_VAL_L, sizeof(GPIO_VAL_L));
close(gpio_val_fd);
gpio_val_fd = open("/sys/class/gpio/gpio93/value", O_RDWR);
memset(buff, 0, 2);
read(gpio_val_fd, buff, 1);
pin_val = atoi(buff);
printf("after write 0, third read gpio val %d, %s\n", pin_val, buff);
close(gpio_export_fd);
close(gpio_dir_fd);
close(gpio_val_fd);
return 0;
}
GPIO 93 corresponds to PAD_GPIOC_06, and the padmux configuration is as PINMUX_FOR_GPIO_MODE shown below:
<PAD_GPIOC_06 PINMUX_FOR_GPIO_MODE MDRV_PUSE_PSPI1_CS>,
In the demo, the controlled GPIO pin is first written to /sys/class/gpio/export, then /sys/devices/gpiochip0/gpio/gpio93/direction is set to output, the output level value is written to /sys/class/gpio/gpio93/value as 1, the pin value is read and then 0 is written, and finally the level value is read again.