Linux - Embedded & Single-board computerThis forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
mmap is the answer you are looking for, if you look at the ep9301 user guide (or one more appropriate to the chip you are using) you can see where it maps pins to memory.
- snippet of code for ep9302 memory mapping of gpio pins -
Code:
#define GPIO_BASE 0x80840000
/* GPIO memory mapped registers */
volatile unsigned int *PBDR; /* for unit select, lowest 3 bits */
volatile unsigned int *PBDDR;
volatile unsigned int *PEDR;
volatile unsigned int *PEDDR;
int memory_map_open(unsigned char **gpio) {
int fd;
fd = open("/dev/mem", O_RDWR);
if (fd < 0) {
perror("Failed to open /dev/mem");
return fd;
}
*gpio = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
PBDR = (unsigned int *)(*gpio + 0x04);
PBDDR = (unsigned int *)(*gpio + 0x14);
PEDR = (unsigned int *)(*gpio + 0x20);
PEDDR = (unsigned int *)(*gpio + 0x24);
return fd;
}
Then where you want to use the data registers that control the pins just assign the appropriate value to them
*PBDDR = 0xff; /* data direction register, 0xff makes all the pins outputs iirc, been a while since I've read the user guide */
*PBDR = 0x01; /* drive the lowest pin that it controls high */
Last edited by estabroo; 07-19-2008 at 10:51 PM.
Reason: put in code tags
Hi estabroo
thanks for the helpful reply,
i have tested the code (after rewriting it by adding main function,etc.. )and i get this error on Olimex CS-e9302 board
Can you run it in a debugger and find out where the segfault occurred? If not you might have to put in fprintf to stderr messages to narrow it down, does it have a console (serial, vga, ...)? You should also check the value you get back from mmap to make sure it didn't fail. Can you post your code?
Okay the problem is your declaration of gpio. It was ** in the function I posted because it was being passed in by reference, since you have it in the main program you should do this instead
Code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#define GPIO_BASE 0x80840000
/* GPIO memory mapped registers */
volatile unsigned int *PEDR;
volatile unsigned int *PEDDR;
int main (void)
{
//long delay=128000, delay2=100;
unsigned char *gpio;
int fd;
fd = open("/dev/mem", O_RDWR);
if (fd < 0)
{
perror("Failed to open /dev/mem");
return fd;
}
gpio = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
PEDR = (unsigned int *)(gpio + 0x20);
PEDDR = (unsigned int *)(gpio + 0x24);
*PEDDR = 0xff;//set output
*PEDR = 0x02;// turn ON Red LED (port E1)
return 0;
}
I would imagine you'd need to write a kernel module that setup an irq handler function and requested interrupts generated by that gpio be sent to it. Take a look at the set_irq_type and request_irq functions in the kernel.
Hi,
dealing with interrupts can be done only in Kernel space not user space.
just use as estabroo said, "request_irq" to register ur irq number and device name, etc..
then write the handler (ISR).. at the exit of the module just free the irq. http://www.xml.com/ldd/chapter/book/ch09.html
cheers
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.