TX2/Xavier Linux GPIO 计算

Linux GPIO子系统

Linux命令行常用echo, cat等操作GPIO:

# 列出Linux GPIO空间目录
$ ls /sys/class/gpio
export  gpiochip232  gpiochip240  gpiochip256  gpiochip320  unexport

# 导出GPIO到用户空间
# GPIO4_CAM_STROBE -> GPIO3_PV.05 -> V=>2, 2*8+256+5=277
$ echo 277 > /sys/class/gpio/export
# 取消导出把export换成unexport

$ ls /sys/class/gpio
export  gpio277  gpiochip232  gpiochip240  gpiochip256  gpiochip320  unexport

# 设置GPIO方向为输出
$ echo out > /sys/class/gpio/gpio277/direction

# 输出高电平
$ echo 1 > /sys/class/gpio/gpio277/value

# 查看电平
$ cat /sys/class/gpio/gpio277/value
1

当然这些命令断电失效, 可以写成脚本设置开机运行, 有兴趣搜索Ubuntu16,或者Ubuntu18设置开机脚本.

TX2 Linux GPIO计算

关于上面277的由来 GPIO4_CAM_STROBE -> GPIO3_PV.05 -> V=>2, 2*8+256+5=277.

原理图中用的是GPIO4_CAM_STROBE这个引脚:

在这里插入图片描述

Jetson TX2 Series Pinmux 这个xls表格:

在这里插入图片描述

表格中 GPIO4_CAM_STROBE -> GPIO3_PV.05.

linux/include/dt-bindings/gpio/tegra186-gpio.h github, linux的代码对TX2端口进行了编号(TX2->tegra186-gpio.h, Xavier->tegra194-gpio.h):

/* GPIOs implemented by main GPIO controller */
#define TEGRA186_MAIN_GPIO_PORT_A 0
#define TEGRA186_MAIN_GPIO_PORT_B 1
#define TEGRA186_MAIN_GPIO_PORT_C 2
#define TEGRA186_MAIN_GPIO_PORT_D 3
#define TEGRA186_MAIN_GPIO_PORT_E 4
#define TEGRA186_MAIN_GPIO_PORT_F 5
#define TEGRA186_MAIN_GPIO_PORT_G 6
#define TEGRA186_MAIN_GPIO_PORT_H 7
#define TEGRA186_MAIN_GPIO_PORT_I 8
#define TEGRA186_MAIN_GPIO_PORT_J 9
#define TEGRA186_MAIN_GPIO_PORT_K 10
#define TEGRA186_MAIN_GPIO_PORT_L 11
#define TEGRA186_MAIN_GPIO_PORT_M 12
#define TEGRA186_MAIN_GPIO_PORT_N 13
#define TEGRA186_MAIN_GPIO_PORT_O 14
#define TEGRA186_MAIN_GPIO_PORT_P 15
#define TEGRA186_MAIN_GPIO_PORT_Q 16
#define TEGRA186_MAIN_GPIO_PORT_R 17
#define TEGRA186_MAIN_GPIO_PORT_T 18
#define TEGRA186_MAIN_GPIO_PORT_X 19
#define TEGRA186_MAIN_GPIO_PORT_Y 20
#define TEGRA186_MAIN_GPIO_PORT_BB 21
#define TEGRA186_MAIN_GPIO_PORT_CC 22

#define TEGRA186_MAIN_GPIO(port, offset) \
    ((TEGRA186_MAIN_GPIO_PORT_##port * 8) + offset)

/* GPIOs implemented by AON GPIO controller */
#define TEGRA186_AON_GPIO_PORT_S 0
#define TEGRA186_AON_GPIO_PORT_U 1
#define TEGRA186_AON_GPIO_PORT_V 2
#define TEGRA186_AON_GPIO_PORT_W 3
#define TEGRA186_AON_GPIO_PORT_Z 4
#define TEGRA186_AON_GPIO_PORT_AA 5
#define TEGRA186_AON_GPIO_PORT_EE 6
#define TEGRA186_AON_GPIO_PORT_FF 7

#define TEGRA186_AON_GPIO(port, offset) \
    ((TEGRA186_AON_GPIO_PORT_##port * 8) + offset)

其中的:

  • TEGRA186_MAIN_GPIO, 也就是tegra-gpio, at base index 320, 来源 TX2 GPIO Changes
  • TEGRA186_AON_GPIO, 也就是tegra-gpio-aon, at base index 256
  • offset = base + pin
  • TEGRA186_AON_GPIO_PORT_V对应2, 属于tegra-gpio-aon组, 基值是256, 那么 GPIO3_PV.05 对应的就是TEGRA186_MAIN_GPIO(V, (256+5)) => ((TEGRA186_MAIN_GPIO_PORT_V* 8) + offset) = 2*8+256+5 = 277.

Xavier Linux GPIO计算

tegra194-gpio.h, 这里把Xavier的 linux/include/dt-bindings/gpio/tegra194-gpio.h github也贴过来方便查阅:

#ifndef _DT_BINDINGS_GPIO_TEGRA194_GPIO_H
#define _DT_BINDINGS_GPIO_TEGRA194_GPIO_H

#include <dt-bindings/gpio/gpio.h>

/* GPIOs implemented by main GPIO controller */
#define TEGRA194_MAIN_GPIO_PORT_A 0
#define TEGRA194_MAIN_GPIO_PORT_B 1
#define TEGRA194_MAIN_GPIO_PORT_C 2
#define TEGRA194_MAIN_GPIO_PORT_D 3
#define TEGRA194_MAIN_GPIO_PORT_E 4
#define TEGRA194_MAIN_GPIO_PORT_F 5
#define TEGRA194_MAIN_GPIO_PORT_G 6
#define TEGRA194_MAIN_GPIO_PORT_H 7
#define TEGRA194_MAIN_GPIO_PORT_I 8
#define TEGRA194_MAIN_GPIO_PORT_J 9
#define TEGRA194_MAIN_GPIO_PORT_K 10
#define TEGRA194_MAIN_GPIO_PORT_L 11
#define TEGRA194_MAIN_GPIO_PORT_M 12
#define TEGRA194_MAIN_GPIO_PORT_N 13
#define TEGRA194_MAIN_GPIO_PORT_O 14
#define TEGRA194_MAIN_GPIO_PORT_P 15
#define TEGRA194_MAIN_GPIO_PORT_Q 16
#define TEGRA194_MAIN_GPIO_PORT_R 17
#define TEGRA194_MAIN_GPIO_PORT_S 18
#define TEGRA194_MAIN_GPIO_PORT_T 19
#define TEGRA194_MAIN_GPIO_PORT_U 20
#define TEGRA194_MAIN_GPIO_PORT_V 21
#define TEGRA194_MAIN_GPIO_PORT_W 22
#define TEGRA194_MAIN_GPIO_PORT_X 23
#define TEGRA194_MAIN_GPIO_PORT_Y 24
#define TEGRA194_MAIN_GPIO_PORT_Z 25
#define TEGRA194_MAIN_GPIO_PORT_FF 26
#define TEGRA194_MAIN_GPIO_PORT_GG 27

#define TEGRA194_MAIN_GPIO(port, offset) \
    ((TEGRA194_MAIN_GPIO_PORT_##port * 8) + offset)

/* GPIOs implemented by AON GPIO controller */
#define TEGRA194_AON_GPIO_PORT_AA 0
#define TEGRA194_AON_GPIO_PORT_BB 1
#define TEGRA194_AON_GPIO_PORT_CC 2
#define TEGRA194_AON_GPIO_PORT_DD 3
#define TEGRA194_AON_GPIO_PORT_EE 4

#define TEGRA194_AON_GPIO(port, offset) \
    ((TEGRA194_AON_GPIO_PORT_##port * 8) + offset)

#endif

基地值也变了:

  • tegra-gpio, at base index 288
  • tegra-gpio-aon, at base index 248

如 原理图中的信号 SPI1_SCK:

  • 查 [Jetson AGX Xavier Pinmux] 表格, 对应 GPIO3_PZ.03
  • 上面头文件tegra194-gpio.h定义了#define TEGRA194_MAIN_GPIO_PORT_Z 25
  • TEGRA194_MAIN_GPIO, 也就是tegra-gpio, 基值为288
  • Linux GPIO计算结果: 25*8 + 288 + 3 = 491

参考

Tegra Wiki 里面写了模型号 TX2->T186, Xavier->T194:

在这里插入图片描述

Xavier GPIO Changes 里面指出了tegra-gpio基值288, tegra-gpio-aon基值248.

TX2 GPIO Changes 里面指出了tegra-gpio基值320, tegra-gpio-aon基值256.

Jetson TX2 Series Pinmux excel表格可以查TX2信号名与引脚标号的对应关系.

Jetson AGX Xavier Pinmux excel表格可以查Xavier信号名与引脚标号的对应关系.

Jeson Pinmux

NVIDIA Jetson TX2 J21 Header Pinout JetsonHacks

NVIDIA Jetson AGX Xavier GPIO Header Pinout JetsonHacks

用C快捷计算TX2 Linux GPIO

顺手撸了个TX2的tx2_pinout.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

// #define TEGRA186_MAIN_GPIO_BASE 320
// #define TEGRA186_AON_GPIO_BASE  256

char port_array[33][3] = {"P0","P1",
                          "S","U","V","W","Z","AA","EE","FF", \
                          "A","B","C","D","E","F","G","H", \
                          "I","J","K","L","M","N","O","P", \
                          "Q","R","T","X","Y","BB","CC"};

char *strupr(char *str){
    char *orign=str;
    for (; *str!='\0'; str++)
        *str = toupper(*str);
    return orign;
}

int main(int argc, char **argv)
{
    if(argc >= 3) {
        //printf("%d, %s, %s, %s\n", argc, argv[0], argv[1], argv[2]);
        for(int i = 0; i < 33; i++) {
            if( (strcmp(port_array[i], strupr(argv[1])) == 0) && (atoi(argv[2]) < 8)) {
                printf("%s.%s Linux GPIO: %d\n", argv[1], argv[2], i * 8 + atoi(argv[2]) + 240);
                return 0;
            }
        }
    } 

    printf("Segmentation fault, input like \"./tx2_pinout AA 02\"\n");

    return 0;
}

gcc -o tx2_pinout tx2_pinout.c, 然后测试一下:

$ ./tx2_pinout A 04
A.04 Linux GPIO: 324

$ ./tx2_pinout P1 6
P1.6 Linux GPIO: 254

$ ./tx2_pinout N 04
N.04 Linux GPIO: 428

$ ./tx2_pinout EE 01
EE.01 Linux GPIO: 305

其中, ./tx2_pinout P1 6指P16. 这里的P0, P1是为了迎合 TX2用I2C通过TCA9539扩展的GPIO对应的P16, P17的计算, 这个基值是240:

在这里插入图片描述

可参考Jetson TX2 GPIO mapping

用C快捷计算Xavier Linux GPIO

再顺手撸个Xavier的xavier_pinout.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

// #define TEGRA194_MAIN_GPIO_BASE 288
// #define TEGRA194_AON_GPIO_BASE  248

char port_array[33][3] = {"AA","BB", "CC", "DD", "EE", \
                          "A","B","C","D","E","F","G", \
                          "H","I","J","K","L","M","N", \
                          "O","P","Q","R","S","T", \
                          "U","V","W","X","Y","Z", \
                          "FF","GG"};

char *strupr(char *str){
    char *orign=str;
    for (; *str!='\0'; str++)
        *str = toupper(*str);
    return orign;
}

int main(int argc, char **argv)
{
    if(argc >= 3) {
        //printf("%d, %s, %s, %s\n", argc, argv[0], argv[1], argv[2]);
        for(int i = 0; i < 33; i++) {
            if( (strcmp(port_array[i], strupr(argv[1])) == 0) && (atoi(argv[2]) < 8)) {
                printf("%s.%s Linux GPIO: %d\n", argv[1], argv[2], i * 8 + atoi(argv[2]) + 248);
                return 0;
            }
        }
    } 

    printf("Segmentation fault, input like \"./tx2_pinout AA 02\"\n");

    return 0;
}

gcc -o xavier_pinout xavier_pinout.c, 然后测试一下:

$ ./xavier_pinout Q 06
Q.06 Linux GPIO: 422

$ ./xavier_pinout R 02
R.02 Linux GPIO: 426

$ ./xavier_pinout B 00
B.00 Linux GPIO: 296

$ ./xavier_pinout BB 00
BB.00 Linux GPIO: 256

$ ./xavier_pinout CC 07
CC.07 Linux GPIO: 271

$ ./xavier_pinout I 01
I.01 Linux GPIO: 353

可以和 Jetson AGX Xavier GPIO Expansion Header Mapping 对照结果.

Debug

有时出现错误:

$ ls /sys/class/gpio
export  gpio245  gpiochip232  gpiochip240  gpiochip256  gpiochip320  unexport

$ echo 247 > /sys/class/gpio/export
-bash: echo: write error: Device or resource busy

用sudo, unexport也不行, 可以sudo cat /sys/kernel/debug/gpio查看:

$ sudo cat /sys/kernel/debug/gpio
gpiochip3: GPIOs 232-239, parent: platform/max77620-gpio, max77620-gpio, can sleep:
 gpio-232 (                    |external-connection:) in  hi
 gpio-237 (                    |spmic_gpio_input    ) in  hi
 gpio-238 (                    |spmic_gpio_input    ) in  hi

gpiochip2: GPIOs 240-255, parent: i2c/0-0074, tca9539, can sleep:
 gpio-240 (                    |vdd-usb2-5v         ) out lo
 gpio-241 (                    |en-vdd-ts-1v8       ) out hi
 gpio-242 (                    |en-vdd-ts-hv-3v3    ) out hi
 gpio-243 (                    |en-vdd-disp-3v3     ) out lo
 gpio-244 (                    |vdd-fan             ) out hi
 gpio-245 (                    |sysfs               ) out hi
 gpio-247 (                    |en-mdm-pwr-3v7      ) out lo
...

可以看到, 247已经用作输出0被占用了, 这种需要修改刷写设备树了.

微信公众号

欢迎扫描二维码关注本人微信公众号, 及时获取或者发送给我最新消息:
在这里插入图片描述

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值