'ODROID-N2' on this page refers to the ODROID-N2 series (N2, N2+, N2L).
GPIO Status Check Program
You can check the current status of all of the GPIO pins which are extensible.
Simply Check out current pin MUX selections, directions, values, and PU/PD statuses with this program.
Refer to Expansion Connectors document for further information.
ODROID-N2
J2 - 2x20 PINS
Default Pin State | GPIO & Export No | Net Name | Pin Number | Pin Number | Net Name | GPIO & Export No | Default Pin State |
---|---|---|---|---|---|---|---|
- | - | 3.3V | 1 | 2 | 5.0V | - | - |
I(P/D) | GPIOX.17 (#493) | I2C0_SDA | 3 | 4 | 5.0V | - | - |
I(P/U) | GPIOX.18 (#494) | I2C0_SCL | 5 | 6 | GND | - | - |
I(P/D) | GPIOA.13 (#473) | 7 | 8 | TXD1 | GPIOX.12 (#488) | I(P/U) | |
- | - | GND | 9 | 10 | RXD1 | GPIOX.13 (#489) | I(P/U) |
I(P/U) | GPIOX.3 (#479) | 11 | 12 | PWM_E | GPIOX.16 (#492) | I(P/U) | |
I(P/U) | GPIOX.4 (#480) | 13 | 14 | GND | - | - | |
I(P/U) | GPIOX.7 (#483) | PWM_F | 15 | 16 | GPIOX.0 (#476) | I(P/U) | |
- | - | 3.3V | 17 | 18 | GPIOX.1 (#477) | I(P/U) | |
I(P/U) | GPIOX.8 (#484) | SPI0_MOSI | 19 | 20 | GND | - | - |
I(P/U) | GPIOX.9 (#485) | SPI0_MISO | 21 | 22 | GPIOX.2 (#478) | I(P/U) | |
I(P/U) | GPIOX.11 (#487) | SPI0_CLK | 23 | 24 | SPI0_SS0 | GPIOX.10 (#486) | I(P/U) |
- | - | GND | 25 | 26 | SPI0_SS1 | GPIOA.4 (#464) | I(P/D) |
I(P/U) | GPIOA.14 (#474) | I2C1_SDA | 27 | 28 | I2C1_SCL | GPIOA.15 (#475) | I(P/U) |
I(P/U) | GPIOX.14 (#490) | 29 | 30 | GND | - | - | |
I(P/U) | GPIOX.15 (#491) | 31 | 32 | GPIOA.12 (#472) | I(P/D) | ||
I(P/U) | GPIOX.5 (#481) | PWM_C | 33 | 34 | GND | - | - |
I(P/D) | GPIOX.6 (#482) | PWM_D | 35 | 36 | GPIOX.19 (#495) | - | |
ADC.AIN3 | 37 | 38 | REF 1.8V | ||||
- | - | GND | 39 | 40 | ADC.AIN2 |
ODROID-C4
J2 - 2x20 PINS
Default Pin State | GPIO & Export No | Net Name | Pin Number | Pin Number | Net Name | GPIO & Export No | Default Pin State |
---|---|---|---|---|---|---|---|
- | - | 3.3V | 1 | 2 | 5.0V | - | - |
I(P/D) | GPIOX.17 (#493) | I2C0_SDA | 3 | 4 | 5.0V | - | - |
I(P/U) | GPIOX.18 (#494) | I2C0_SCL | 5 | 6 | GND | - | - |
I(P/D) | GPIOX.5 (#481) | PWM_C | 7 | 8 | TXD1 | GPIOX.12 (#488) | I(P/U) |
- | - | GND | 9 | 10 | RXD1 | GPIOX.13 (#489) | I(P/U) |
I(P/U) | GPIOX.3 (#479) | PWM_D | 11 | 12 | PWM_E | GPIOX.16 (#492) | I(P/U) |
I(P/U) | GPIOX.4 (#480) | 13 | 14 | GND | - | - | |
I(P/U) | GPIOX.7 (#483) | PWM_F | 15 | 16 | GPIOX.0 (#476) | I(P/U) | |
- | - | 3.3V | 17 | 18 | GPIOX.1 (#477) | I(P/U) | |
I(P/U) | GPIOX.8 (#484) | SPI0_MOSI | 19 | 20 | GND | - | - |
I(P/U) | GPIOX.9 (#485) | SPI0_MISO | 21 | 22 | GPIOX.2 (#478) | I(P/U) | |
I(P/U) | GPIOX.11 (#487) | SPI0_SCLK | 23 | 24 | SPI0_CS0 | GPIOX.10 (#486) | I(P/U) |
- | - | GND | 25 | 26 | SPI0_CS1 | GPIOH.6 (#433) | I(P/D) |
I(P/U) | GPIOA.14 (#474) | I2C1_SDA | 27 | 28 | I2C1_SCL | GPIOA.15 (#475) | I(P/U) |
I(P/U) | GPIOX.14 (#490) | 29 | 30 | GND | - | - | |
I(P/U) | GPIOX.15 (#491) | 31 | 32 | GPIOH.7 (#434) | I(P/D) | ||
I(P/U) | GPIOX.6 (#482) | PWM_A | 33 | 34 | GND | - | - |
I(P/D) | GPIOX.19 (#495) | PWM_B | 35 | 36 | GPIOH.5 (#432) | - | |
ADC.AIN2 | 37 | 38 | REF 1.8V | ||||
- | - | GND | 39 | 40 | ADC.AIN0 |
ODROID-C2
J2 - 2x20 PINS
GPIO | wPi | Name | Alternative | Mode | V | PU/PD | PIN | PIN | PU/PD | V | Mode | Alternative | Name | wPi | GPIO |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | - | 3.3V | - | - | - | - | 1 | 2 | - | - | - | - | 5.0V | - | - |
205 | - | I2CA_SDA | - | IN | 1 | - | 3 | 4 | - | - | - | - | 5.0V | - | - |
206 | - | I2CA_SCL | - | IN | 1 | - | 5 | 6 | - | - | - | - | GND | - | - |
249 | 7 | GPIOX.21 | - | IN | 1 | P/U | 7 | 8 | P/U | 1 | ALT2 | /dev/ttyS1 | TXD1 | - | 240 |
- | - | GND | - | - | - | - | 9 | 10 | P/U | 1 | ALT2 | /dev/ttyS1 | RXD1 | - | 241 |
247 | 0 | GPIOX.19 | - | IN | 1 | P/U | 11 | 12 | P/D | 0 | IN | - | GPIOX.10 | 1 | 238 |
239 | 2 | GPIOX.11 | - | IN | 1 | P/U | 13 | 14 | - | - | - | - | GND | - | - |
237 | 3 | GPIOX.9 | - | IN | 1 | P/U | 15 | 16 | P/U | 1 | IN | - | GPIOX.8 | 4 | 236 |
- | - | 3.3V | - | - | - | - | 17 | 18 | P/U | 1 | IN | - | GPIOX.5 | 5 | 233 |
235 | 12 | GPIOX.7 | PWM1 | IN | 1 | P/U | 19 | 20 | - | - | - | - | GND | - | - |
232 | 13 | GPIOX.4 | - | IN | 1 | P/U | 21 | 22 | P/U | 1 | IN | - | GPIOX.3 | 6 | 231 |
230 | 14 | GPIOX.2 | - | IN | 1 | P/U | 23 | 24 | P/U | 1 | IN | - | GPIOX.1 | 10 | 229 |
- | - | GND | - | - | - | - | 25 | 26 | P/D | 0 | IN | - | GPIOY.14 | 11 | 225 |
207 | - | I2CB_SDA | - | IN | 1 | - | 27 | 28 | - | 1 | IN | - | I2CB_SCL | - | 208 |
228 | 21 | GPIOX.0 | - | IN | 1 | P/U | 29 | 30 | - | - | - | - | GND | - | - |
219 | 22 | GPIOY.8 | - | IN | 1 | P/U | 31 | 32 | P/U | 1 | IN | - | GPIOY.13 | 26 | 224 |
234 | 23 | GPIOX.6 | PWM0 | IN | 0 | P/D | 33 | 34 | - | - | - | - | GND | - | - |
214 | 24 | GPIOY.3 | - | IN | 1 | P/U | 35 | 36 | P/U | 1 | IN | - | GPIOY.7 | 27 | 218 |
- | - | ADC.AIN1 | 10bit ADC (0~1.8V) | - | - | - | 37 | 38 | - | - | - | - | 1.8V REF | - | - |
- | - | GND | - | - | - | - | 39 | 40 | - | - | - | 10bit ADC(00~1.8V) | ADC.AIN0 | - | - |
Source Code
Download the example source code below and compile/run that.
This code optimized with tab size for 4.
ODROID-N2
- gpio_status_n2.c
//------------------------------------------------------------------------------------------------------------ // // ODROID-N2 GPIO Status Check Application. // // Compile : gcc -o <create excute file name> <source file name> // Run : sudo ./<created excute file name> // //------------------------------------------------------------------------------------------------------------ #include <stdio.h> #include <stdarg.h> #include <stdint.h> #include <stdlib.h> #include <ctype.h> #include <poll.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <time.h> #include <fcntl.h> #include <pthread.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/ioctl.h> //------------------------------------------------------------------------------ // // Global handle Define // //------------------------------------------------------------------------------ // MMAP Address for GPIO #define GPIO_REG_MAP 0xFF634000 #define GPIO_PIN_BASE 410 #define BLOCK_SIZE (4*1024) static volatile unsigned int *gpio; //------------------------------------------------------------------------------ #define GPIOA_PIN_START (GPIO_PIN_BASE + 50) #define GPIOA_PIN_END (GPIO_PIN_BASE + 65) #define GPIOA_FSEL_REG_OFFSET 0x120 #define GPIOA_OUTP_REG_OFFSET 0x121 #define GPIOA_INP_REG_OFFSET 0x122 #define GPIOA_PUPD_REG_OFFSET 0x13F #define GPIOA_PUEN_REG_OFFSET 0x14D //------------------------------------------------------------------------------ #define GPIOX_PIN_START (GPIO_PIN_BASE + 66) #define GPIOX_PIN_END (GPIO_PIN_BASE + 85) #define GPIOX_FSEL_REG_OFFSET 0x116 #define GPIOX_OUTP_REG_OFFSET 0x117 #define GPIOX_INP_REG_OFFSET 0x118 #define GPIOX_PUPD_REG_OFFSET 0x13C #define GPIOX_PUEN_REG_OFFSET 0x14A //------------------------------------------------------------------------------ // GPIOA Banks Pin MUX Control Register Address 0xFF6346F4 ~ 0xFF6346FB (MUX_D ~ MUX_E) #define PERIPHS_PIN_MUX_D 0x1BD #define PERIPHS_PIN_MUX_E 0x1BE // GPIOX Banks Pin MUX Control Register Address 0xFF6346CC ~ 0xFF6346D5 (MUX_3 ~ MUX_5) #define PERIPHS_PIN_MUX_3 0x1B3 #define PERIPHS_PIN_MUX_4 0x1B4 #define PERIPHS_PIN_MUX_5 0x1B5 //------------------------------------------------------------------------------ #define BIT(x) (1 << x) //------------------------------------------------------------------------------ const char MODE_STR[10][5] = { " - ", "ALT1", "ALT2", "ALT3", "ALT4", "ALT5", "ALT6", "ALT7", "IN", "OUT", }; //------------------------------------------------------------------------------ const char PUPD_STR[3][5] = { " - ", "P/U", "P/D", }; //------------------------------------------------------------------------------ struct header_info { int gpio; char name[10]; }; //------------------------------------------------------------------------------ const struct header_info header_J2[40] = { { -1, "3.3V" }, { -1, "5.0V" }, { 493, "I2C2_SDA" }, { -1, "5.0V" }, { 494, "I2C2_SCL" }, { -1, "GND" }, { 473, "GPIOA.13" }, { 488, "UARTB_TX" }, { -1, "GND" }, { 489, "UARTB_RX" }, { 479, "GPIOX.3" }, { 492, "GPIOX_16" }, { 480, "GPIOX.4" }, { -1, "GND" }, { 483, "GPIOX.7" }, { 476, "GPIOX.0" }, { -1, "3.3V" }, { 477, "GPIOX.1" }, { 484, "MOSI" }, { -1, "GND" }, { 485, "MISO" }, { 478, "GPIOX.2" }, { 487, "SCLK" }, { 486, "SS0" }, { -1, "GND" }, { 464, "GPIOA.4" }, { 474, "I2C3_SDA" }, { 475, "I2C3_SCL" }, { 490, "GPIOX.14" }, { -1, "GND" }, { 491, "GPIOX.15" }, { 472, "GPIOA.12" }, { 481, "GPIOX.5" }, { -1, "GND" }, { 482, "GPIOX.6" }, { 495, "GPIOX.19" }, { -1, "ADC.AIN0" }, { -1, "1.8V REF" }, { -1, "GND" }, { -1, "ADC.AIN1" }, }; //------------------------------------------------------------------------------ const struct header_info header_J7[7] = { { -1, "GND" }, { 471, "GPIOA.11" }, { -1, "5.0V" }, { 460, "GPIOA.0" }, { 462, "GPIOA.2" }, { 461, "GPIOA.1" }, { 463, "GPIOA.3" }, }; //------------------------------------------------------------------------------------------------------------ int get_mode_gpioa(int pin) { int mode; switch(pin) { case 0: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 0) & 0xF; break; case 1: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 4) & 0xF; break; case 2: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 8) & 0xF; break; case 3: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 12) & 0xF; break; case 4: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 16) & 0xF; break; case 11: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 12) & 0xF; break; case 12: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 16) & 0xF; break; case 13: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 20) & 0xF; break; case 14: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 24) & 0xF; break; case 15: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 28) & 0xF; break; default : return 0; } return mode ?: *(gpio + GPIOA_FSEL_REG_OFFSET) & BIT(pin) ? 8 : 9; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpiox(int pin) { int mode; switch(pin) { case 0: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 0) & 0xF; break; case 1: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 4) & 0xF; break; case 2: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 8) & 0xF; break; case 3: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 12) & 0xF; break; case 4: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 16) & 0xF; break; case 5: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 20) & 0xF; break; case 6: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 24) & 0xF; break; case 7: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 28) & 0xF; break; case 8: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 0) & 0xF; break; case 9: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 4) & 0xF; break; case 10: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 8) & 0xF; break; case 11: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 12) & 0xF; break; case 12: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 16) & 0xF; break; case 13: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 20) & 0xF; break; case 14: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 24) & 0xF; break; case 15: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 28) & 0xF; break; case 16: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 0) & 0xF; break; case 17: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 4) & 0xF; break; case 18: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 8) & 0xF; break; case 19: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 12) & 0xF; break; default : return 0; } return mode ?: *(gpio + GPIOX_FSEL_REG_OFFSET) & BIT(pin) ? 8 : 9; } //------------------------------------------------------------------------------------------------------------ int get_mode (int pin) { switch (pin) { case GPIOA_PIN_START...GPIOA_PIN_END: return get_mode_gpioa(pin - GPIOA_PIN_START); case GPIOX_PIN_START...GPIOX_PIN_END: return get_mode_gpiox(pin - GPIOX_PIN_START); default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ int get_pupd (int pin) { switch (pin) { case GPIOA_PIN_START...GPIOA_PIN_END: if (*(gpio + GPIOA_PUEN_REG_OFFSET) & BIT(pin - GPIOA_PIN_START)) { return *(gpio + GPIOA_PUPD_REG_OFFSET) & BIT(pin - GPIOA_PIN_START) ? 1 : 2; } break; case GPIOX_PIN_START...GPIOX_PIN_END: if (*(gpio + GPIOX_PUEN_REG_OFFSET) & BIT(pin - GPIOX_PIN_START)) { return *(gpio + GPIOX_PUPD_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 2; } break; default : break; } return 0; // PU/PD disable } //------------------------------------------------------------------------------------------------------------ int get_status (int pin) { switch (pin) { case GPIOA_PIN_START...GPIOA_PIN_END: return *(gpio + GPIOA_INP_REG_OFFSET) & BIT(pin - GPIOA_PIN_START) ? 1 : 0; case GPIOX_PIN_START...GPIOX_PIN_END: return *(gpio + GPIOX_INP_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 0; default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ // // system init // //------------------------------------------------------------------------------------------------------------ int system_init(void) { int fd; if ((fd = open("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) { fprintf(stderr, "/dev/gpiomem open error!\n"); fflush(stdout); return -1; } gpio = (unsigned int *) mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_REG_MAP); if (gpio < 0) { fprintf(stderr, "mmap error!\n"); fflush(stdout); return -1; } return 0; } //------------------------------------------------------------------------------------------------------------ // // Start Program // //------------------------------------------------------------------------------------------------------------ int main (int argc, char *argv[]) { int i; if (system_init() < 0) { fprintf (stderr, "%s: System Init failed\n", __func__); fflush(stdout); return -1; } printf("+------+----------+------+---+-------+--- J2 ---+-------+---+------+----------+------+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical | PU/PD | V | Mode | Name | GPIO |\n"); printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); for (i = 0; i < 40; i += 2) { if (header_J2[i].gpio != -1) { printf("| %3d | %8s | %4s | %d | %4s | %2d |", header_J2[i].gpio, header_J2[i].name, MODE_STR[get_mode(header_J2[i].gpio)], get_status(header_J2[i].gpio), PUPD_STR[get_pupd(header_J2[i].gpio)], i + 1); } else { printf("| - | %8s | - | - | - | %2d |", header_J2[i].name, i + 1); } if (header_J2[i+1].gpio != -1) { printf("| %2d | %4s | %d | %4s | %8s | %3d |\n", i + 2, PUPD_STR[get_pupd(header_J2[i+1].gpio)], get_status(header_J2[i+1].gpio), MODE_STR[get_mode(header_J2[i+1].gpio)], header_J2[i+1].name, header_J2[i+1].gpio); } else { printf("| %2d | - | - | - | %8s | - |\n", i + 2, header_J2[i+1].name); } } printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); printf("+------+-----------+------+---+-------+--- J7 ---+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical |\n"); printf("+------+-----------+------+---+-------+----------+\n"); for(i = 0; i < 7; i ++) { if (header_J7[i].gpio != -1) { printf("| %3d | %9s | %4s | %d | %4s | %2d |\n", header_J7[i].gpio, header_J7[i].name, MODE_STR[get_mode(header_J7[i].gpio)], get_status(header_J7[i].gpio), PUPD_STR[get_pupd(header_J7[i].gpio)], i + 1); } else { printf("| - | %9s | - | - | - | %2d |\n", header_J7[i].name, i + 1); } } printf("+------+-----------+------+---+-------+----------+\n"); fflush(stdout); return 0 ; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
ODROID-C4
- gpio_status_c4.c
//------------------------------------------------------------------------------------------------------------ // // ODROID-C4 GPIO Status Check Application. // // Compile : gcc -o <create excute file name> <source file name> // Run : sudo ./<created excute file name> // //------------------------------------------------------------------------------------------------------------ #include <stdio.h> #include <stdarg.h> #include <stdint.h> #include <stdlib.h> #include <ctype.h> #include <poll.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <time.h> #include <fcntl.h> #include <pthread.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/ioctl.h> //------------------------------------------------------------------------------ // // Global handle Define // //------------------------------------------------------------------------------ // MMAP Address for GPIO #define GPIO_REG_MAP 0xFF634000 #define GPIO_PIN_BASE 410 #define BLOCK_SIZE (4*1024) static volatile unsigned int *gpio; //------------------------------------------------------------------------------ #define GPIOH_PIN_START (GPIO_PIN_BASE + 17) #define GPIOH_PIN_END (GPIO_PIN_BASE + 25) #define GPIOH_FSEL_REG_OFFSET 0x119 #define GPIOH_OUTP_REG_OFFSET 0x11A #define GPIOH_INP_REG_OFFSET 0x11B #define GPIOH_PUPD_REG_OFFSET 0x13D #define GPIOH_PUEN_REG_OFFSET 0x14B //------------------------------------------------------------------------------ #define GPIOA_PIN_START (GPIO_PIN_BASE + 50) #define GPIOA_PIN_END (GPIO_PIN_BASE + 65) #define GPIOA_FSEL_REG_OFFSET 0x120 #define GPIOA_OUTP_REG_OFFSET 0x121 #define GPIOA_INP_REG_OFFSET 0x122 #define GPIOA_PUPD_REG_OFFSET 0x13F #define GPIOA_PUEN_REG_OFFSET 0x14D //------------------------------------------------------------------------------ #define GPIOX_PIN_START (GPIO_PIN_BASE + 66) #define GPIOX_PIN_END (GPIO_PIN_BASE + 85) #define GPIOX_FSEL_REG_OFFSET 0x116 #define GPIOX_OUTP_REG_OFFSET 0x117 #define GPIOX_INP_REG_OFFSET 0x118 #define GPIOX_PUPD_REG_OFFSET 0x13C #define GPIOX_PUEN_REG_OFFSET 0x14A //------------------------------------------------------------------------------ #define GPIOAO_PIN_START (GPIO_PIN_BASE + 86) #define GPIOAO_PIN_END (GPIO_PIN_BASE + 97) #define GPIOAO_FSEL_REG_OFFSET 0x109 #define GPIOAO_OUTP_REG_OFFSET 0x10D #define GPIOAO_INP_REG_OFFSET 0x10A #define GPIOAO_PUPD_REG_OFFSET 0x10B #define GPIOAO_PUEN_REG_OFFSET 0x10C //------------------------------------------------------------------------------ // GPIOH Banks Pin MUX Control Register Address 0xFF6346EC ~ 0xFF6346F0 (MUX_B) #define PERIPHS_PIN_MUX_B 0x1BB // GPIOA Banks Pin MUX Control Register Address 0xFF6346F4 ~ 0xFF6346FB (MUX_D ~ MUX_E) #define PERIPHS_PIN_MUX_D 0x1BD #define PERIPHS_PIN_MUX_E 0x1BE // GPIOX Banks Pin MUX Control Register Address 0xFF6346CC ~ 0xFF6346D5 (MUX_3 ~ MUX_5) #define PERIPHS_PIN_MUX_3 0x1B3 #define PERIPHS_PIN_MUX_4 0x1B4 #define PERIPHS_PIN_MUX_5 0x1B5 // GPIOAO Banks Pin MUX Control Register Address 0xFF634414 ~ 0xFF634418 (MUX_REG_0 ~ MUX_REG_1) #define AO_RTI_PINMUX_REG0 0x105 #define AO_RTI_PINMUX_REG1 0x106 //------------------------------------------------------------------------------ #define BIT(x) (1 << x) //------------------------------------------------------------------------------ const char MODE_STR[10][5] = { " - ", "ALT1", "ALT2", "ALT3", "ALT4", "ALT5", "ALT6", "ALT7", "IN", "OUT", }; //------------------------------------------------------------------------------ const char PUPD_STR[3][5] = { " - ", "P/U", "P/D", }; //------------------------------------------------------------------------------ struct header_info { int gpio; char name[10]; }; //------------------------------------------------------------------------------ const struct header_info header_J2[40] = { { -1, "3.3V" }, { -1, "5.0V" }, { 493, "I2C2_SDA" }, { -1, "5.0V" }, { 494, "I2C2_SCL" }, { -1, "GND" }, { 481, "GPIOX.5" }, { 488, "UARTB_TX" }, { -1, "GND" }, { 489, "UARTB_RX" }, { 479, "GPIOX.3" }, { 492, "GPIOX_16" }, { 480, "GPIOX.4" }, { -1, "GND" }, { 483, "GPIOX.7" }, { 476, "GPIOX.0" }, { -1, "3.3V" }, { 477, "GPIOX.1" }, { 484, "MOSI" }, { -1, "GND" }, { 485, "MISO" }, { 478, "GPIOX.2" }, { 487, "SCLK" }, { 486, "SS0" }, { -1, "GND" }, { 433, "GPIOH.6" }, { 474, "I2C3_SDA" }, { 475, "I2C3_SCL" }, { 490, "GPIOX.14" }, { -1, "GND" }, { 491, "GPIOX.15" }, { 434, "GPIOH.7" }, { 482, "GPIOX.6" }, { -1, "GND" }, { 495, "GPIOX.19" }, { 432, "GPIOH.5" }, { -1, "ADC.AIN2" }, { -1, "1.8V REF" }, { -1, "GND" }, { -1, "ADC.AIN0" }, }; //------------------------------------------------------------------------------ const struct header_info header_J7[7] = { { -1, "GND" }, { 506, "GPIOAO.10" }, { -1, "5.0V" }, { 505, "GPIOAO.9" }, { 503, "GPIOAO.7" }, { 504, "GPIOAO.8" }, { 500, "GPIOAO.4" }, }; //------------------------------------------------------------------------------------------------------------ int get_mode_gpioh(int pin) { int mode; switch(pin) { case 5: mode = (*(gpio + PERIPHS_PIN_MUX_B) >> 20) & 0xF; break; case 6: mode = (*(gpio + PERIPHS_PIN_MUX_B) >> 24) & 0xF; break; case 7: mode = (*(gpio + PERIPHS_PIN_MUX_B) >> 28) & 0xF; break; default : return 0; } return mode ?: *(gpio + GPIOH_FSEL_REG_OFFSET) & BIT(pin) ? 8 : 9; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpioa(int pin) { int mode; switch(pin) { case 0: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 0) & 0xF; break; case 1: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 4) & 0xF; break; case 2: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 8) & 0xF; break; case 3: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 12) & 0xF; break; case 4: mode = (*(gpio + PERIPHS_PIN_MUX_D) >> 16) & 0xF; break; case 11: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 12) & 0xF; break; case 12: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 16) & 0xF; break; case 13: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 20) & 0xF; break; case 14: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 24) & 0xF; break; case 15: mode = (*(gpio + PERIPHS_PIN_MUX_E) >> 28) & 0xF; break; default : return 0; } return mode ?: *(gpio + GPIOA_FSEL_REG_OFFSET) & BIT(pin) ? 8 : 9; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpiox(int pin) { int mode; switch(pin) { case 0: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 0) & 0xF; break; case 1: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 4) & 0xF; break; case 2: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 8) & 0xF; break; case 3: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 12) & 0xF; break; case 4: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 16) & 0xF; break; case 5: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 20) & 0xF; break; case 6: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 24) & 0xF; break; case 7: mode = (*(gpio + PERIPHS_PIN_MUX_3) >> 28) & 0xF; break; case 8: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 0) & 0xF; break; case 9: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 4) & 0xF; break; case 10: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 8) & 0xF; break; case 11: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 12) & 0xF; break; case 12: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 16) & 0xF; break; case 13: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 20) & 0xF; break; case 14: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 24) & 0xF; break; case 15: mode = (*(gpio + PERIPHS_PIN_MUX_4) >> 28) & 0xF; break; case 16: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 0) & 0xF; break; case 17: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 4) & 0xF; break; case 18: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 8) & 0xF; break; case 19: mode = (*(gpio + PERIPHS_PIN_MUX_5) >> 12) & 0xF; break; default : return 0; } return mode ?: *(gpio + GPIOX_FSEL_REG_OFFSET) & BIT(pin) ? 8 : 9; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpioao(int pin) { int mode; switch(pin) { case 4: mode = (*(gpio + AO_RTI_PINMUX_REG0) >> 16) & 0xF; break; case 7: mode = (*(gpio + AO_RTI_PINMUX_REG0) >> 28) & 0xF; break; case 8: mode = (*(gpio + AO_RTI_PINMUX_REG1) >> 0) & 0xF; break; case 9: mode = (*(gpio + AO_RTI_PINMUX_REG1) >> 4) & 0xF; break; case 10: mode = (*(gpio + AO_RTI_PINMUX_REG1) >> 8) & 0xF; break; default : return 0; } return mode ?: *(gpio + GPIOAO_FSEL_REG_OFFSET) & BIT(pin) ? 8 : 9; } //------------------------------------------------------------------------------------------------------------ int get_mode (int pin) { switch (pin) { case GPIOH_PIN_START...GPIOH_PIN_END: return get_mode_gpioh(pin - GPIOH_PIN_START); case GPIOA_PIN_START...GPIOA_PIN_END: return get_mode_gpioa(pin - GPIOA_PIN_START); case GPIOX_PIN_START...GPIOX_PIN_END: return get_mode_gpiox(pin - GPIOX_PIN_START); case GPIOAO_PIN_START...GPIOAO_PIN_END: return get_mode_gpioao(pin - GPIOAO_PIN_START); default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ int get_pupd (int pin) { switch (pin) { case GPIOH_PIN_START...GPIOH_PIN_END: if (*(gpio + GPIOH_PUEN_REG_OFFSET) & BIT(pin - GPIOH_PIN_START)) { return *(gpio + GPIOH_PUPD_REG_OFFSET) & BIT(pin - GPIOH_PIN_START) ? 1 : 2; } case GPIOA_PIN_START...GPIOA_PIN_END: if (*(gpio + GPIOA_PUEN_REG_OFFSET) & BIT(pin - GPIOA_PIN_START)) { return *(gpio + GPIOA_PUPD_REG_OFFSET) & BIT(pin - GPIOA_PIN_START) ? 1 : 2; } break; case GPIOX_PIN_START...GPIOX_PIN_END: if (*(gpio + GPIOX_PUEN_REG_OFFSET) & BIT(pin - GPIOX_PIN_START)) { return *(gpio + GPIOX_PUPD_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 2; } case GPIOAO_PIN_START...GPIOAO_PIN_END: if (*(gpio + GPIOAO_PUEN_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START)) { return *(gpio + GPIOAO_PUPD_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START) ? 1 : 2; } break; default : break; } return 0; // PU/PD disable } //------------------------------------------------------------------------------------------------------------ int get_status (int pin) { switch (pin) { case GPIOH_PIN_START...GPIOH_PIN_END: return *(gpio + GPIOH_INP_REG_OFFSET) & BIT(pin - GPIOH_PIN_START) ? 1 : 0; case GPIOA_PIN_START...GPIOA_PIN_END: return *(gpio + GPIOA_INP_REG_OFFSET) & BIT(pin - GPIOA_PIN_START) ? 1 : 0; case GPIOX_PIN_START...GPIOX_PIN_END: return *(gpio + GPIOX_INP_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 0; case GPIOAO_PIN_START...GPIOAO_PIN_END: return *(gpio + GPIOAO_INP_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START) ? 1 : 0; default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ // // system init // //------------------------------------------------------------------------------------------------------------ int system_init(void) { int fd; if ((fd = open("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) { fprintf(stderr, "/dev/gpiomem open error!\n"); fflush(stdout); return -1; } gpio = (unsigned int *) mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_REG_MAP); if (gpio < 0) { fprintf(stderr, "mmap error!\n"); fflush(stdout); return -1; } return 0; } //------------------------------------------------------------------------------------------------------------ // // Start Program // //------------------------------------------------------------------------------------------------------------ int main (int argc, char *argv[]) { int i; if (system_init() < 0) { fprintf (stderr, "%s: System Init failed\n", __func__); fflush(stdout); return -1; } printf("+------+----------+------+---+-------+--- J2 ---+-------+---+------+----------+------+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical | PU/PD | V | Mode | Name | GPIO |\n"); printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); for (i = 0; i < 40; i += 2) { if (header_J2[i].gpio != -1) { printf("| %3d | %8s | %4s | %d | %4s | %2d |", header_J2[i].gpio, header_J2[i].name, MODE_STR[get_mode(header_J2[i].gpio)], get_status(header_J2[i].gpio), PUPD_STR[get_pupd(header_J2[i].gpio)], i + 1); } else { printf("| - | %8s | - | - | - | %2d |", header_J2[i].name, i + 1); } if (header_J2[i+1].gpio != -1) { printf("| %2d | %4s | %d | %4s | %8s | %3d |\n", i + 2, PUPD_STR[get_pupd(header_J2[i+1].gpio)], get_status(header_J2[i+1].gpio), MODE_STR[get_mode(header_J2[i+1].gpio)], header_J2[i+1].name, header_J2[i+1].gpio); } else { printf("| %2d | - | - | - | %8s | - |\n", i + 2, header_J2[i+1].name); } } printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); printf("+------+-----------+------+---+-------+--- J7 ---+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical |\n"); printf("+------+-----------+------+---+-------+----------+\n"); for(i = 0; i < 7; i ++) { if (header_J7[i].gpio != -1) { printf("| %3d | %9s | %4s | %d | %4s | %2d |\n", header_J7[i].gpio, header_J7[i].name, MODE_STR[get_mode(header_J7[i].gpio)], get_status(header_J7[i].gpio), PUPD_STR[get_pupd(header_J7[i].gpio)], i + 1); } else { printf("| - | %9s | - | - | - | %2d |\n", header_J7[i].name, i + 1); } } printf("+------+-----------+------+---+-------+----------+\n"); fflush(stdout); return 0 ; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
ODROID-C2
- gpio_status_c2.c
//------------------------------------------------------------------------------------------------------------ // // ODROID-C2 GPIO Status Check Application. // // Compile : gcc -o <create excute file name> <source file name> // Run : sudo ./<created excute file name> // //------------------------------------------------------------------------------------------------------------ #include <stdio.h> #include <stdarg.h> #include <stdint.h> #include <stdlib.h> #include <ctype.h> #include <poll.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <time.h> #include <fcntl.h> #include <pthread.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/ioctl.h> //------------------------------------------------------------------------------ // // Global handle Define // //------------------------------------------------------------------------------ // MMAP Address for GPIO // GPIO Banks Control Register Address 0xC8834400 #define GPIO_REG_MAP 0xC8834000 // GPIO AO Control Register Address 0xC8100000 #define GPIO_AO_REG_MAP 0xC8100000 #define BLOCK_SIZE (4*1024) static volatile unsigned int *gpio; static volatile unsigned int *gpio_ao; static volatile unsigned int *ao_in; //------------------------------------------------------------------------------ // refer kernel/include/dt-bindings/gpio/gxbb.h #define GPIOAO_OFFSET 122 #define GPIOAO_PIN_START (GPIOAO_OFFSET + 0) #define GPIOAO_PIN_END (GPIOAO_OFFSET + 13) #define GPIOAO_FSEL_REG_OFFSET 0x09 #define GPIOAO_OUTP_REG_OFFSET 0x09 #define GPIOAO_INP_REG_OFFSET 0x0A #define GPIOAO_PUPD_REG_OFFSET 0x0B #define GPIOAO_PUEN_REG_OFFSET 0x0B //------------------------------------------------------------------------------ #define GPIO_BANKS_OFFSET 136 #define GPIODV_PIN_START (GPIO_BANKS_OFFSET + 45) #define GPIODV_PIN_END (GPIO_BANKS_OFFSET + 74) #define GPIODV_FSEL_REG_OFFSET 0x10C #define GPIODV_OUTP_REG_OFFSET 0x10D #define GPIODV_INP_REG_OFFSET 0x10E #define GPIODV_PUPD_REG_OFFSET 0x13A #define GPIODV_PUEN_REG_OFFSET 0x148 //------------------------------------------------------------------------------ #define GPIOY_PIN_START (GPIO_BANKS_OFFSET + 75) #define GPIOY_PIN_END (GPIO_BANKS_OFFSET + 91) #define GPIOY_FSEL_REG_OFFSET 0x10F #define GPIOY_OUTP_REG_OFFSET 0x110 #define GPIOY_INP_REG_OFFSET 0x111 #define GPIOY_PUPD_REG_OFFSET 0x13D #define GPIOY_PUEN_REG_OFFSET 0x149 //------------------------------------------------------------------------------ #define GPIOX_PIN_START (GPIO_BANKS_OFFSET + 92) #define GPIOX_PIN_END (GPIO_BANKS_OFFSET + 114) #define GPIOX_FSEL_REG_OFFSET 0x118 #define GPIOX_OUTP_REG_OFFSET 0x119 #define GPIOX_INP_REG_OFFSET 0x11A #define GPIOX_PUPD_REG_OFFSET 0x13E #define GPIOX_PUEN_REG_OFFSET 0x14C //------------------------------------------------------------------------------ // GPIO Banks Pin Mux Control Register Address 0xC88344B0 ~ 0xC88344D4 (REG0 ~ REG9) #define MUX_REG0 0x12C #define MUX_REG1 0x12D #define MUX_REG2 0x12E #define MUX_REG3 0x12F #define MUX_REG4 0x130 #define MUX_REG5 0x131 #define MUX_REG6 0x132 #define MUX_REG7 0x133 #define MUX_REG8 0x134 #define MUX_REG9 0x135 // GPIO AO Pin Mux Control Register Address 0xC8100014/0xC8100018 (AO_REG, A0_REG2) #define AO_MUX_REG1 0x005 #define AO_MUX_REG2 0x006 //------------------------------------------------------------------------------ #define BIT(x) (1 << x) //------------------------------------------------------------------------------ const char MODE_STR[9][5] = { " - ", "ALT1", "ALT2", "ALT3", "ALT4", "ALT5", "ALT6", "IN", "OUT", }; //------------------------------------------------------------------------------ const char PUPD_STR[3][5] = { " - ", "P/U", "P/D", }; //------------------------------------------------------------------------------ struct header_info { int gpio; char name[10]; }; //------------------------------------------------------------------------------ const struct header_info header_J2[40] = { { -1, "3.3V" }, { -1, "5.0V" }, { 205, "I2CA_SDA" }, { -1, "5.0V" }, { 206, "I2CA_SCL" }, { -1, "GND" }, { 249, "GPIOX.21" }, { 240, "GPIOX.12" }, { -1, "GND" }, { 241, "GPIOX.13" }, { 247, "GPIOX.19" }, { 238, "GPIOX.10" }, { 239, "GPIOX.11" }, { -1, "GND" }, { 237, "GPIOX.9" }, { 236, "GPIOX.8" }, { -1, "3.3V" }, { 233, "GPIOX.5" }, { 235, "GPIOX.7" }, { -1, "GND" }, { 232, "GPIOX.4" }, { 231, "GPIOX.3" }, { 230, "GPIOX.2" }, { 229, "GPIOX.1" }, { -1, "GND" }, { 225, "GPIOY.14" }, { 207, "I2CB_SDA" }, { 208, "I2CB_SCL" }, { 228, "GPIOX.0" }, { -1, "GND" }, { 219, "GPIOY.8" }, { 224, "GPIOY.13" }, { 234, "GPIOX.6" }, { -1, "GND" }, { 214, "GPIOY.3" }, { 218, "GPIOY.7" }, { -1, "ADC.AIN0" }, { -1, "1.8V REF" }, { -1, "GND" }, { -1, "ADC.AIN1" }, }; //------------------------------------------------------------------------------ const struct header_info header_J7[7] = { { -1, "GND" }, { 128, "GPIOAO.6" }, { -1, "5.0V" }, { 130, "GPIOAO.8" }, { 132, "GPIOAO.10" }, { 131, "GPIOAO.9" }, { 133, "GPIOAO.11" }, }; //------------------------------------------------------------------------------------------------------------ int get_mode_gpiox (int pin) { switch(pin) { case 0: if (*(gpio + MUX_REG8) & BIT(5)) return 1; break; case 1: if (*(gpio + MUX_REG8) & BIT(4)) return 1; break; case 2: if (*(gpio + MUX_REG8) & BIT(3)) return 1; break; case 3: if (*(gpio + MUX_REG8) & BIT(2)) return 1; break; case 4: if (*(gpio + MUX_REG8) & BIT(1)) return 1; break; case 5: if (*(gpio + MUX_REG8) & BIT(0)) return 1; break; case 6: if (*(gpio + MUX_REG3) & BIT(9)) return 4; if (*(gpio + MUX_REG3) & BIT(17)) return 5; break; case 7: if (*(gpio + MUX_REG8) & BIT(11)) return 1; if (*(gpio + MUX_REG3) & BIT(8)) return 4; if (*(gpio + MUX_REG3) & BIT(18)) return 5; break; case 8: if (*(gpio + MUX_REG4) & BIT(7)) return 1; if (*(gpio + MUX_REG3) & BIT(30)) return 3; if (*(gpio + MUX_REG3) & BIT(10)) return 4; break; case 9: if (*(gpio + MUX_REG4) & BIT(6)) return 1; if (*(gpio + MUX_REG3) & BIT(29)) return 3; if (*(gpio + MUX_REG3) & BIT(7)) return 4; break; case 10: if (*(gpio + MUX_REG3) & BIT(28)) return 3; break; case 11: if (*(gpio + MUX_REG3) & BIT(27)) return 3; break; case 12: if (*(gpio + MUX_REG4) & BIT(13)) return 2; if (*(gpio + MUX_REG4) & BIT(17)) return 3; break; case 13: if (*(gpio + MUX_REG4) & BIT(12)) return 2; if (*(gpio + MUX_REG4) & BIT(16)) return 3; break; case 14: if (*(gpio + MUX_REG4) & BIT(11)) return 2; if (*(gpio + MUX_REG4) & BIT(15)) return 3; break; case 15: if (*(gpio + MUX_REG4) & BIT(10)) return 2; if (*(gpio + MUX_REG4) & BIT(14)) return 3; break; case 19: if (*(gpio + MUX_REG2) & BIT(22)) return 2; if (*(gpio + MUX_REG2) & BIT(30)) return 5; break; case 20: case 21: break; default : return 0; } return *(gpio + GPIOX_FSEL_REG_OFFSET) & BIT(pin) ? 7 : 8; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpioy (int pin) { switch(pin) { case 0: if (*(gpio + MUX_REG2) & BIT(19)) return 1; if (*(gpio + MUX_REG3) & BIT(2)) return 2; if (*(gpio + MUX_REG1) & BIT(0)) return 5; break; case 1: if (*(gpio + MUX_REG2) & BIT(18)) return 1; if (*(gpio + MUX_REG3) & BIT(1)) return 2; if (*(gpio + MUX_REG1) & BIT(1)) return 5; break; case 2: if (*(gpio + MUX_REG2) & BIT(17)) return 1; if (*(gpio + MUX_REG3) & BIT(0)) return 2; break; case 3: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(4)) return 2; if (*(gpio + MUX_REG1) & BIT(2)) return 5; break; case 4: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(12)) return 4; break; case 5: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(13)) return 4; break; case 6: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(3)) return 5; break; case 7: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(4)) return 5; break; case 8: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(5)) return 5; break; case 9: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(6)) return 5; break; case 10: if (*(gpio + MUX_REG2) & BIT(16)) return 1; if (*(gpio + MUX_REG3) & BIT(5)) return 2; if (*(gpio + MUX_REG1) & BIT(7)) return 5; break; case 11: if (*(gpio + MUX_REG3) & BIT(3)) return 2; if (*(gpio + MUX_REG1) & BIT(19)) return 3; if (*(gpio + MUX_REG1) & BIT(8)) return 5; break; case 12: if (*(gpio + MUX_REG1) & BIT(18)) return 3; if (*(gpio + MUX_REG1) & BIT(9)) return 5; break; case 13: if (*(gpio + MUX_REG1) & BIT(17)) return 3; if (*(gpio + MUX_REG1) & BIT(10)) return 5; break; case 14: if (*(gpio + MUX_REG1) & BIT(16)) return 3; if (*(gpio + MUX_REG1) & BIT(11)) return 5; break; case 15: if (*(gpio + MUX_REG2) & BIT(20)) return 1; if (*(gpio + MUX_REG1) & BIT(20)) return 4; if (*(gpio + MUX_REG1) & BIT(22)) return 5; break; case 16: if (*(gpio + MUX_REG2) & BIT(21)) return 1; if (*(gpio + MUX_REG1) & BIT(21)) return 4; break; default : return 0; } return *(gpio + GPIOY_FSEL_REG_OFFSET) & BIT(pin) ? 7 : 8; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpiodv (int pin) { switch(pin) { case 24: if (*(gpio + MUX_REG0) & BIT(7)) return 1; if (*(gpio + MUX_REG0) & BIT(12)) return 2; if (*(gpio + MUX_REG5) & BIT(12)) return 3; if (*(gpio + MUX_REG2) & BIT(29)) return 5; if (*(gpio + MUX_REG7) & BIT(26)) return 6; break; case 25: if (*(gpio + MUX_REG0) & BIT(6)) return 1; if (*(gpio + MUX_REG0) & BIT(11)) return 2; if (*(gpio + MUX_REG5) & BIT(11)) return 3; if (*(gpio + MUX_REG2) & BIT(28)) return 5; if (*(gpio + MUX_REG7) & BIT(27)) return 6; break; case 26: if (*(gpio + MUX_REG0) & BIT(10)) return 2; if (*(gpio + MUX_REG5) & BIT(10)) return 3; if (*(gpio + MUX_REG2) & BIT(27)) return 5; if (*(gpio + MUX_REG7) & BIT(24)) return 6; break; case 27: if (*(gpio + MUX_REG0) & BIT(9)) return 2; if (*(gpio + MUX_REG5) & BIT(9)) return 3; if (*(gpio + MUX_REG5) & BIT(8)) return 4; if (*(gpio + MUX_REG2) & BIT(26)) return 5; if (*(gpio + MUX_REG7) & BIT(25)) return 6; break; case 28: if (*(gpio + MUX_REG3) & BIT(20)) return 5; if (*(gpio + MUX_REG7) & BIT(22)) return 6; break; case 29: if (*(gpio + MUX_REG3) & BIT(22)) return 4; if (*(gpio + MUX_REG3) & BIT(21)) return 5; if (*(gpio + MUX_REG7) & BIT(23)) return 6; break; default : return 0; } return *(gpio + GPIODV_FSEL_REG_OFFSET) & BIT(pin) ? 7 : 8; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpioao (int pin) { switch(pin) { case 0: if (*(gpio_ao + AO_MUX_REG1) & BIT(12)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(26)) return 2; break; case 1: if (*(gpio_ao + AO_MUX_REG1) & BIT(11)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(25)) return 2; break; case 2: if (*(gpio_ao + AO_MUX_REG1) & BIT(10)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(8)) return 2; break; case 3: if (*(gpio_ao + AO_MUX_REG1) & BIT(9)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(7)) return 2; if (*(gpio_ao + AO_MUX_REG1) & BIT(22)) return 3; break; case 4: if (*(gpio_ao + AO_MUX_REG1) & BIT(24)) return 2; if (*(gpio_ao + AO_MUX_REG1) & BIT(6)) return 3; if (*(gpio_ao + AO_MUX_REG1) & BIT(2)) return 4; break; case 5: if (*(gpio_ao + AO_MUX_REG1) & BIT(25)) return 2; if (*(gpio_ao + AO_MUX_REG1) & BIT(5)) return 3; if (*(gpio_ao + AO_MUX_REG1) & BIT(1)) return 4; break; case 6: if (*(gpio_ao + AO_MUX_REG1) & BIT(18)) return 3; if (*(gpio_ao + AO_MUX_REG1) & BIT(16)) return 4; return 2; case 7: if (*(gpio_ao + AO_MUX_REG1) & BIT(0)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(21)) return 2; break; case 8: if (*(gpio_ao + AO_MUX_REG1) & BIT(30)) return 4; return 3; case 9: if (*(gpio_ao + AO_MUX_REG1) & BIT(29)) return 4; return 2; case 10: if (*(gpio_ao + AO_MUX_REG1) & BIT(28)) return 4; return 2; case 11: if (*(gpio_ao + AO_MUX_REG1) & BIT(27)) return 4; return 3; case 12: if (*(gpio_ao + AO_MUX_REG1) & BIT(15)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(14)) return 2; if (*(gpio_ao + AO_MUX_REG1) & BIT(17)) return 3; if (*(gpio_ao + AO_MUX_REG2) & BIT(0)) return 4; break; case 13: if (*(gpio_ao + AO_MUX_REG1) & BIT(31)) return 1; if (*(gpio_ao + AO_MUX_REG1) & BIT(4)) return 2; if (*(gpio_ao + AO_MUX_REG1) & BIT(3)) return 3; if (*(gpio_ao + AO_MUX_REG2) & BIT(1)) return 4; break; default : return 0; } return *(gpio_ao + GPIOAO_FSEL_REG_OFFSET) & BIT(pin) ? 7 : 8; } //------------------------------------------------------------------------------------------------------------ int get_mode (int pin) { switch (pin) { case GPIOX_PIN_START...GPIOX_PIN_END: return get_mode_gpiox(pin - GPIOX_PIN_START); case GPIOY_PIN_START...GPIOY_PIN_END: return get_mode_gpioy(pin - GPIOY_PIN_START); case GPIODV_PIN_START...GPIODV_PIN_END: return get_mode_gpiodv(pin - GPIODV_PIN_START); case GPIOAO_PIN_START...GPIOAO_PIN_END: return get_mode_gpioao(pin - GPIOAO_PIN_START); default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ int get_pupd (int pin) { switch (pin) { case GPIOX_PIN_START...GPIOX_PIN_END: if (*(gpio + GPIOX_PUEN_REG_OFFSET) & BIT(pin - GPIOX_PIN_START)) { return *(gpio + GPIOX_PUPD_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 2; } break; case GPIOY_PIN_START...GPIOY_PIN_END: if (*(gpio + GPIOY_PUEN_REG_OFFSET) & BIT(pin - GPIOY_PIN_START)) { return *(gpio + GPIOY_PUPD_REG_OFFSET) & BIT(pin - GPIOY_PIN_START) ? 1 : 2; } break; case GPIODV_PIN_START...GPIODV_PIN_END: if (*(gpio + GPIODV_PUEN_REG_OFFSET) & BIT(pin - GPIODV_PIN_START)) { return *(gpio + GPIODV_PUPD_REG_OFFSET) & BIT(pin - GPIODV_PIN_START) ? 1 : 2; } break; case GPIOAO_PIN_START...GPIOAO_PIN_END: if (*(gpio_ao + GPIOAO_PUEN_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START)) { return *(gpio_ao + GPIOAO_PUPD_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START + 16) ? 1 : 2; } break; default : break; } return 0; // PU/PD disable } //------------------------------------------------------------------------------------------------------------ int get_status (int pin) { switch (pin) { case GPIOX_PIN_START...GPIOX_PIN_END: return *(gpio + GPIOX_INP_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 0; case GPIOY_PIN_START...GPIOY_PIN_END: return *(gpio + GPIOY_INP_REG_OFFSET) & BIT(pin - GPIOY_PIN_START) ? 1 : 0; case GPIODV_PIN_START...GPIODV_PIN_END: return *(gpio + GPIODV_INP_REG_OFFSET) & BIT(pin - GPIODV_PIN_START) ? 1 : 0; case GPIOAO_PIN_START...GPIOAO_PIN_END: return *(gpio_ao + GPIOAO_INP_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START) ? 1 : 0; default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ // // system init // //------------------------------------------------------------------------------------------------------------ int system_init(void) { int fd; if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) { fprintf(stderr, "/dev/mem open error!\n"); fflush(stdout); return -1; } gpio = (unsigned int *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_REG_MAP); gpio_ao = (unsigned int *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_AO_REG_MAP); if((unsigned int)gpio == -1 || (unsigned int)gpio_ao == -1) { fprintf(stderr, "mmap error!\n"); fflush(stdout); return -1; } return 0; } //------------------------------------------------------------------------------------------------------------ // // Start Program // //------------------------------------------------------------------------------------------------------------ int main (int argc, char *argv[]) { int i; if (system_init() < 0) { fprintf (stderr, "%s: System Init failed\n", __func__); fflush(stdout); return -1; } printf("+------+----------+------+---+-------+--- J2 ---+-------+---+------+----------+------+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical | PU/PD | V | Mode | Name | GPIO |\n"); printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); for (i = 0; i < 40; i += 2) { if (header_J2[i].gpio != -1) { printf("| %3d | %8s | %4s | %d | %4s | %2d |", header_J2[i].gpio, header_J2[i].name, MODE_STR[get_mode(header_J2[i].gpio)], get_status(header_J2[i].gpio), PUPD_STR[get_pupd(header_J2[i].gpio)], i + 1); } else { printf("| - | %8s | - | - | - | %2d |", header_J2[i].name, i + 1); } if (header_J2[i+1].gpio != -1) { printf("| %2d | %4s | %d | %4s | %8s | %3d |\n", i + 2, PUPD_STR[get_pupd(header_J2[i+1].gpio)], get_status(header_J2[i+1].gpio), MODE_STR[get_mode(header_J2[i+1].gpio)], header_J2[i+1].name, header_J2[i+1].gpio); } else { printf("| %2d | - | - | - | %8s | - |\n", i + 2, header_J2[i+1].name); } } printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); printf("+------+-----------+------+---+-------+--- J7 ---+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical |\n"); printf("+------+-----------+------+---+-------+----------+\n"); for(i = 0; i < 7; i ++) { if (header_J7[i].gpio != -1) { printf("| %3d | %9s | %4s | %d | %4s | %2d |\n", header_J7[i].gpio, header_J7[i].name, MODE_STR[get_mode(header_J7[i].gpio)], get_status(header_J7[i].gpio), PUPD_STR[get_pupd(header_J7[i].gpio)], i + 1); } else { printf("| - | %9s | - | - | - | %2d |\n", header_J7[i].name, i + 1); } } printf("+------+-----------+------+---+-------+----------+\n"); fflush(stdout); return 0 ; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
Example
Compile with gcc and simply run that.
ODROID-N2
- target
root@odroid:~# gcc -o gpio_status_n2 gpio_status_n2.c root@odroid:~# ./gpio_status_n2 +------+----------+------+---+-------+--- J2 ---+-------+---+------+----------+------+ | GPIO | Name | Mode | V | PU/PD | Physical | PU/PD | V | Mode | Name | GPIO | +------+----------+------+---+-------+----++----+-------+---+------+----------+------+ | - | 3.3V | - | - | - | 1 || 2 | - | - | - | 5.0V | - | | 493 | I2C2_SDA | IN | 1 | P/D | 3 || 4 | - | - | - | 5.0V | - | | 494 | I2C2_SCL | IN | 1 | P/U | 5 || 6 | - | - | - | GND | - | | 473 | GPIOA.13 | IN | 0 | P/D | 7 || 8 | P/U | 1 | IN | UARTB_TX | 488 | | - | GND | - | - | - | 9 || 10 | P/U | 1 | IN | UARTB_RX | 489 | | 479 | GPIOX.3 | IN | 1 | P/U | 11 || 12 | P/U | 1 | IN | GPIOX_16 | 492 | | 480 | GPIOX.4 | IN | 1 | P/U | 13 || 14 | - | - | - | GND | - | | 483 | GPIOX.7 | IN | 1 | P/U | 15 || 16 | P/U | 1 | IN | GPIOX.0 | 476 | | - | 3.3V | - | - | - | 17 || 18 | P/U | 1 | IN | GPIOX.1 | 477 | | 484 | MOSI | IN | 1 | P/U | 19 || 20 | - | - | - | GND | - | | 485 | MISO | IN | 1 | P/U | 21 || 22 | P/U | 1 | IN | GPIOX.2 | 478 | | 487 | SCLK | IN | 1 | P/U | 23 || 24 | P/U | 1 | IN | SS0 | 486 | | - | GND | - | - | - | 25 || 26 | P/D | 0 | IN | GPIOA.4 | 464 | | 474 | I2C3_SDA | IN | 1 | P/U | 27 || 28 | P/U | 1 | IN | I2C3_SCL | 475 | | 490 | GPIOX.14 | IN | 1 | P/U | 29 || 30 | - | - | - | GND | - | | 491 | GPIOX.15 | IN | 1 | P/U | 31 || 32 | P/D | 0 | IN | GPIOA.12 | 472 | | 481 | GPIOX.5 | IN | 1 | P/U | 33 || 34 | - | - | - | GND | - | | 482 | GPIOX.6 | IN | 0 | P/D | 35 || 36 | - | 0 | IN | GPIOX.19 | 495 | | - | ADC.AIN0 | - | - | - | 37 || 38 | - | - | - | 1.8V REF | - | | - | GND | - | - | - | 39 || 40 | - | - | - | ADC.AIN1 | - | +------+----------+------+---+-------+----++----+-------+---+------+----------+------+ +------+-----------+------+---+-------+--- J7 ---+ | GPIO | Name | Mode | V | PU/PD | Physical | +------+-----------+------+---+-------+----------+ | - | GND | - | - | - | 1 | | 471 | GPIOA.11 | ALT1 | 1 | P/D | 2 | | - | 5.0V | - | - | - | 3 | | 460 | GPIOA.0 | IN | 0 | P/D | 4 | | 462 | GPIOA.2 | IN | 0 | P/D | 5 | | 461 | GPIOA.1 | IN | 0 | P/D | 6 | | 463 | GPIOA.3 | IN | 0 | P/D | 7 | +------+-----------+------+---+-------+----------+
ODROID-C4
- target
root@odroid:~# gcc -o gpio_status_c4 gpio_status_c4.c root@odroid:~# ./gpio_status_c4 +------+----------+------+---+-------+--- J2 ---+-------+---+------+----------+------+ | GPIO | Name | Mode | V | PU/PD | Physical | PU/PD | V | Mode | Name | GPIO | +------+----------+------+---+-------+----++----+-------+---+------+----------+------+ | - | 3.3V | - | - | - | 1 || 2 | - | - | - | 5.0V | - | | 493 | I2C2_SDA | IN | 1 | P/D | 3 || 4 | - | - | - | 5.0V | - | | 494 | I2C2_SCL | IN | 1 | P/U | 5 || 6 | - | - | - | GND | - | | 481 | GPIOX.5 | IN | 1 | P/U | 7 || 8 | P/U | 1 | ALT1 | UARTB_TX | 488 | | - | GND | - | - | - | 9 || 10 | P/U | 1 | ALT1 | UARTB_RX | 489 | | 479 | GPIOX.3 | IN | 1 | P/U | 11 || 12 | P/U | 1 | IN | GPIOX_16 | 492 | | 480 | GPIOX.4 | IN | 1 | P/U | 13 || 14 | - | - | - | GND | - | | 483 | GPIOX.7 | IN | 0 | P/U | 15 || 16 | P/U | 1 | IN | GPIOX.0 | 476 | | - | 3.3V | - | - | - | 17 || 18 | P/U | 1 | IN | GPIOX.1 | 477 | | 484 | MOSI | IN | 1 | P/U | 19 || 20 | - | - | - | GND | - | | 485 | MISO | IN | 1 | P/U | 21 || 22 | P/U | 1 | IN | GPIOX.2 | 478 | | 487 | SCLK | IN | 1 | P/U | 23 || 24 | P/U | 1 | IN | SS0 | 486 | | - | GND | - | - | - | 25 || 26 | P/D | 0 | OUT | GPIOH.6 | 433 | | 474 | I2C3_SDA | ALT2 | 1 | P/U | 27 || 28 | P/U | 1 | ALT2 | I2C3_SCL | 475 | | 490 | GPIOX.14 | ALT1 | 1 | P/U | 29 || 30 | - | - | - | GND | - | | 491 | GPIOX.15 | ALT1 | 1 | P/U | 31 || 32 | P/D | 0 | IN | GPIOH.7 | 434 | | 482 | GPIOX.6 | IN | 0 | P/D | 33 || 34 | - | - | - | GND | - | | 495 | GPIOX.19 | IN | 0 | - | 35 || 36 | P/D | 1 | OUT | GPIOH.5 | 432 | | - | ADC.AIN2 | - | - | - | 37 || 38 | - | - | - | 1.8V REF | - | | - | GND | - | - | - | 39 || 40 | - | - | - | ADC.AIN0 | - | +------+----------+------+---+-------+----++----+-------+---+------+----------+------+ +------+-----------+------+---+-------+--- J7 ---+ | GPIO | Name | Mode | V | PU/PD | Physical | +------+-----------+------+---+-------+----------+ | - | GND | - | - | - | 1 | | 506 | GPIOAO.10 | OUT | 0 | - | 2 | | - | 5.0V | - | - | - | 3 | | 505 | GPIOAO.9 | OUT | 0 | - | 4 | | 503 | GPIOAO.7 | OUT | 0 | - | 5 | | 504 | GPIOAO.8 | OUT | 0 | - | 6 | | 500 | GPIOAO.4 | OUT | 0 | - | 7 | +------+-----------+------+---+-------+----------+