GPIO Programming Example

From wiki.gp2x.org

The following is a GPIO programming example for Linux. It should compile with any modern GCC compiler targetted at ARM Linux. It shows how to both read and alter the GPIO's.

F100

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <unistd.h>
#include <stropts.h>
#include <errno.h>

extern int errno;
unsigned long *memregs32;
unsigned short *memregs16;

int memfd;

#define GPIOAPINLVL 0x1180
#define GPIOBPINLVL 0x1182
#define GPIOCPINLVL 0x1184
#define GPIODPINLVL 0x1186
#define GPIOEPINLVL 0x1188
#define GPIOFPINLVL 0x118A
#define GPIOGPINLVL 0x118C
#define GPIOHPINLVL 0x118E
#define GPIOIPINLVL 0x1190
#define GPIOJPINLVL 0x1192
#define GPIOKPINLVL 0x1194
#define GPIOLPINLVL 0x1196
#define GPIOMPINLVL 0x1198
#define GPIONPINLVL 0x119A
#define GPIOOPINLVL 0x119C

#define GPIOAOUT 0x1060
#define GPIOBOUT 0x1062
#define GPIOCOUT 0x1064
#define GPIODOUT 0x1066
#define GPIOEOUT 0x1068
#define GPIOFOUT 0x106A
#define GPIOGOUT 0x106C
#define GPIOHOUT 0x106E
#define GPIOIOUT 0x1070
#define GPIOJOUT 0x1072
#define GPIOKOUT 0x1074
#define GPIOLOUT 0x1076
#define GPIOMOUT 0x1078
#define GPIONOUT 0x107A
#define GPIOOOUT 0x107C

void *trymmap (void *start, size_t length, int prot, int flags, int fd, off_t offset)
{
	char *p;
	int aa;

	printf ("mmap(%X, %X, %X, %X, %X, %X) ... ", (unsigned int)start, length, prot, flags, fd, (unsigned int)offset);
	p = mmap (start, length, prot, flags, fd, offset);
	if (p == (char *)0xFFFFFFFF)
	{
		aa = errno;
		printf ("failed. errno = %d\n", aa);
	}
	else
	{
		printf ("OK! (%X)\n", (unsigned int)p);
	}

	return p;
}

unsigned char initphys (void)
{
	memfd = open("/dev/mem", O_RDWR);
	if (memfd == -1)
	{
		printf ("Open failed\n");
		return 0;
	}

	printf ("/dev/mem opened successfully - fd = %d\n", memfd);

	memregs32 = trymmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0xc0000000);
	if (memregs32 == (unsigned long *)0xFFFFFFFF) return 0;

	memregs16 = (unsigned short *)memregs32;

	return 1;
}

void closephys (void)
{
	close (memfd);
}

int main(void)
{
	int i;
	
	if (!initphys()) return 0;

	printf ("Reading GPIO pins...\n");
	printf ("GPIO-A = %04X\n", memregs16[GPIOAPINLVL >> 1]);
	printf ("GPIO-B = %04X\n", memregs16[GPIOBPINLVL >> 1]);
	printf ("GPIO-C = %04X\n", memregs16[GPIOCPINLVL >> 1]);
	printf ("GPIO-D = %04X\n", memregs16[GPIODPINLVL >> 1]);
	printf ("GPIO-E = %04X\n", memregs16[GPIOEPINLVL >> 1]);
	printf ("GPIO-F = %04X\n", memregs16[GPIOFPINLVL >> 1]);
	printf ("GPIO-G = %04X\n", memregs16[GPIOGPINLVL >> 1]);
	printf ("GPIO-H = %04X\n", memregs16[GPIOHPINLVL >> 1]);
	printf ("GPIO-I = %04X\n", memregs16[GPIOIPINLVL >> 1]);
	printf ("GPIO-J = %04X\n", memregs16[GPIOJPINLVL >> 1]);
	printf ("GPIO-K = %04X\n", memregs16[GPIOKPINLVL >> 1]);
	printf ("GPIO-L = %04X\n", memregs16[GPIOLPINLVL >> 1]);
	printf ("GPIO-M = %04X\n", memregs16[GPIOMPINLVL >> 1]);
	printf ("GPIO-N = %04X\n", memregs16[GPIONPINLVL >> 1]);
	printf ("GPIO-O = %04X\n", memregs16[GPIOOPINLVL >> 1]);

	printf ("Flash battery LED...\n");
	for (i = 0; i < 10; i ++)
	{
		sleep (1);
		memregs16[GPIOHOUT >> 1] ^= 16;
		printf ("%s\n", memregs16[GPIOHPINLVL >> 1] & 16 ? "on" : "off");
	}

	printf ("Control backlight...\n");
	for (i = 0; i < 4; i ++)
	{
		sleep (1);
		memregs16[GPIOHOUT >> 1] ^= 4;
		printf ("%s\n", memregs16[GPIOHPINLVL >> 1] & 4 ? "off" : "on");
	}

	closephys();
	printf("test complete\n");
	return 0;
}



If you are compiling as a C++ app you will need to modify the line

p = mmap (start, length, prot, flags, fd, offset); 

to

p = (char *) mmap (start, length, prot, flags, fd, offset); 



and the line

memregs32 = trymmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0xc0000000); 

to

memregs32 = (long unsigned int*) trymmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0xc0000000); 

to explicitly cast the pointer

F200

#define GPIOHOUT 0x1076
...
memregs16[GPIOHOUT >> 1] ^= 1 << 11; //0x0800;
Personal tools