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;