Reputation: 493
I wrote a function to handle inputs from a custom keyboard from userspace. I configured the gpios with "direction"(input) and "edge"(rising) attributes. Then my function uses poll to get an interrupt on the file descriptor:
const unsigned int POLL_TIMEOUT = 3000;
const unsigned int MAX_BUF = 64;
struct pollfd fdset[6];
int nfds = 6;
int KEY_UP_fd, KEY_DOWN_fd, KEY_STOP_fd, KEY_LEFT_fd, KEY_RIGHT_fd, KEY_OK_fd;
char *buf0[MAX_BUF], *buf1[MAX_BUF], *buf2[MAX_BUF],*buf3[MAX_BUF],*buf4[MAX_BUF],*buf5[MAX_BUF];
int len,timeout, rc;
KEY_UP_fd = gpio_fd_open(KEY_UP);
KEY_DOWN_fd = gpio_fd_open(KEY_DOWN);
KEY_STOP_fd = gpio_fd_open(KEY_STOP);
KEY_EVAC_fd = gpio_fd_open(KEY_LEFT);
KEY_CANCEL_fd = gpio_fd_open(KEY_RIGHT);
KEY_OK_fd = gpio_fd_open(KEY_OK);
timeout = POLL_TIMEOUT;
while (1)
{
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = KEY_UP_fd;
fdset[0].events = POLLPRI;
fdset[1].fd = KEY_DOWN_fd;
fdset[1].events = POLLPRI;
fdset[2].fd = KEY_STOP_fd;
fdset[2].events = POLLPRI;
fdset[3].fd = KEY_LEFT_fd;
fdset[3].events = POLLPRI;
fdset[4].fd = KEY_RIGHT_fd;
fdset[4].events = POLLPRI;
fdset[5].fd = KEY_OK_fd;
fdset[5].events = POLLPRI;
rc = poll(fdset, nfds, timeout);
if (rc < 0) {
printf("Error!");
}
if (fdset[0].revents & POLLPRI) {
lseek(fdset[0].fd, 0, SEEK_SET);
len = read(fdset[0].fd, buf0, MAX_BUF);
}
if (fdset[1].revents & POLLPRI) {
lseek(fdset[1].fd, 0, SEEK_SET);
len = read(fdset[1].fd, buf1, MAX_BUF);
}
if (fdset[2].revents & POLLPRI) {
lseek(fdset[2].fd, 0, SEEK_SET);
len = read(fdset[2].fd, buf2, MAX_BUF);
}
if (fdset[3].revents & POLLPRI) {
lseek(fdset[3].fd, 0, SEEK_SET);
len = read(fdset[3].fd, buf3, MAX_BUF);
}
if (fdset[4].revents & POLLPRI) {
lseek(fdset[4].fd, 0, SEEK_SET);
len = read(fdset[4].fd, buf4, MAX_BUF);
}
if (fdset[5].revents & POLLPRI) {
lseek(fdset[5].fd, 0, SEEK_SET);
len = read(fdset[5].fd, buf5, MAX_BUF);
}
fflush(stdout);
Is there a way to add a debouncing feature to the code ? Usually debouncers use "direct" gpio read, not an interrupt, so I don't really know if it is doable at this point.
Upvotes: 1
Views: 1083
Reputation: 21
This works for me while polling.
static inline int microsleep(long micros)
{
struct timespec ts = {0, micros * MICROS_PER_NANO};
struct timespec remainder = {0, 0};
int retval;
while(1)
{
retval = nanosleep(&ts, &remainder);
if (retval < 0)
{
if (errno == EINTR)
{
ts = remainder;
errno = 0;
}
else
{
break;
}
}
else
{
break;
}
}
return retval;
}
Upvotes: 1