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.

Source Code

Download the example source code below and compile/run that.

This code optimized with tab size for 4.

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 ;
}
 
//------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------

Compile with gcc and simply run that.

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 |
+------+-----------+------+---+-------+----------+