Hi,
I would like to access some gpio (some in input, other in output) in a program to use with Led and button.
The code below seems to work but as no effect on the led itself (even if the DR is effectively change)
May be I m not using the good offset in mmap (GPIO_BASE ?) at first I use 0x10015000 but after some search in the kernel source I tried with the virtual address 0xf4015000.
PS: I checked the different value of DDIR (out), GIUS (inuse) and GPR and all seems fine.
I would really appreciate some help here
#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>unsigned long *memregs32;int memfd;#define GPIO_BASE 0xf4015000//#define GPIO_BASE 0x10015000void *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, GPIO_BASE); if (memregs32 == (unsigned long *)0xFFFFFFFF) return 0; return 1;}void closephys (void){ close (memfd);}int main(void){ int i; if (!initphys()) return 0; printf ("Reading GPIO pins...\n"); printf ("DDIR = %08X\n", memregs32[0x400]); printf ("OCR1 = %08X\n", memregs32[0x404]); printf ("OCR2 = %08X\n", memregs32[0x408]); memregs32[0x408] |= 0x300; printf ("OCR2 = %08X\n", memregs32[0x408]); printf ("ICONFA1 = %08X\n", memregs32[0x40C]); printf ("ICONFA2 = %08X\n", memregs32[0x410]); printf ("ICONFB1 = %08X\n", memregs32[0x414]); printf ("ICONFB2 = %08X\n", memregs32[0x418]); printf ("DR = %08X\n", memregs32[0x41C]); printf ("GIUS = %08X\n", memregs32[0x420]); printf ("SSR = %08X\n", memregs32[0x424]); printf ("ICR1 = %08X\n", memregs32[0x428]); printf ("ICR2 = %08X\n", memregs32[0x42C]); printf ("IMR = %08X\n", memregs32[0x430]); printf ("ISR = %08X\n", memregs32[0x434]); printf ("GPR = %08X\n", memregs32[0x438]); printf ("SWR = %08X\n", memregs32[0x43C]); printf ("PUEN = %08X\n", memregs32[0x440]); printf ("Flash battery LED...\n"); for (i = 0; i < 9; i ++) { memregs32[0x41C] ^= 0x00100000; printf ("%s\n", memregs32[0x41C] & 0x00100000 ? "on" : "off"); } closephys(); printf("test complete\n"); return 0;}
It should be the physical address as GPIO_BASE, i.e. 0x10015000
The problem seems to be that since the pointer *memregs32 is of type long every address from GPIO_BASE will actually be 4 bytes.
Therefore every address accessed using memregs32 should be divided by 4, something like:
...memregs32[0x400/4]...
I think...
Hi,
I'm facing the same kind of problem. Trying to draw a gpio-signal first low and then high but no matter what I attempt it doesn't work. No action at all while measuring with an oscilloscope so if you have come up with something new I would really appreciate if you could share it
(Or if someone else has some info?!)
Br,
Andreas
Well for now I use the sysfs interface to read my gpio but when I try to change the value of an output gpio, the change doesn't take effect even if no error is return.So I m stuck there.
here an example : http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gpio-sysfs
It would be nice to know the gpio base address to use with mmap for the imx27.