Private
Public Access
2
0

iio: added event api

Signed-off-by: Lay, Kuan Loon <kuan.loon.lay@intel.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
Lay, Kuan Loon
2015-10-16 09:18:32 +08:00
committed by Brendan Le Foll
parent e5f28ab04c
commit 4c41d2c2df
5 changed files with 379 additions and 0 deletions

188
src/iio/iio.c Normal file → Executable file
View File

@@ -33,6 +33,7 @@
#define IIO_SCAN_ELEM "scan_elements"
#define IIO_SLASH_DEV "/dev/"IIO_DEVICE
#define IIO_SYSFS_DEVICE "/sys/bus/iio/devices/"IIO_DEVICE
#define IIO_EVENTS "events"
mraa_iio_context
mraa_iio_init(int device)
@@ -42,6 +43,8 @@ mraa_iio_init(int device)
}
mraa_iio_get_channel_data(&plat_iio->iio_devices[device]);
mraa_iio_get_event_data(&plat_iio->iio_devices[device]);
return &plat_iio->iio_devices[device];
}
@@ -271,6 +274,191 @@ mraa_iio_trigger_buffer(mraa_iio_context dev, void (*fptr)(char* data), void* ar
return MRAA_SUCCESS;
}
mraa_result_t
mraa_iio_get_event_data(mraa_iio_context dev)
{
const struct dirent *ent;
DIR* dir;
int event_num = 0;
char buf[MAX_SIZE];
char readbuf[32];
int fd;
int ret = 0;
int padint = 0;
int curr_bytes = 0;
char shortbuf, signchar;
memset(buf, 0, MAX_SIZE);
snprintf(buf, MAX_SIZE, IIO_SYSFS_DEVICE "%d/" IIO_EVENTS, dev->num);
dir = opendir(buf);
if (dir != NULL) {
while ((ent = readdir(dir)) != NULL) {
if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), "_en") == 0) {
event_num++;
}
}
dev->event_num = event_num;
mraa_iio_event* event;
dev->events = calloc(event_num, sizeof(mraa_iio_event));
if ( dev->events == NULL)
{
closedir(dir);
return MRAA_ERROR_UNSPECIFIED;
}
rewinddir(dir);
event_num = 0;
while ((ent = readdir(dir)) != NULL)
{
if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), "_en") == 0) {
event = &dev->events[event_num];
event->name = strdup(ent->d_name);
snprintf(buf, MAX_SIZE, IIO_SYSFS_DEVICE "%d/" IIO_EVENTS "/%s", dev->num, ent->d_name);
fd = open(buf, O_RDONLY);
if (fd > 0) {
if (read(fd, readbuf, 2 * sizeof(char)) != 2) {
break;
}
close(fd);
}
event->enabled = ((int) strtol(readbuf, NULL, 10));
//Todo, read other event info.
event_num++;
}
}
closedir(dir);
}
return MRAA_SUCCESS;
}
mraa_result_t
mraa_iio_event_read(mraa_iio_context dev, const char* attribute, float* data)
{
char buf[64];
snprintf(buf, 64, IIO_SYSFS_DEVICE "%d/" IIO_EVENTS "/%s", dev->num, attribute);
int fd = open(buf, O_RDONLY);
if (fd != -1) {
int len = read(fd, &buf, 64);
*data = strtol(buf, NULL, 10);
return MRAA_SUCCESS;
}
return MRAA_ERROR_UNSPECIFIED;
}
mraa_result_t
mraa_iio_event_write(mraa_iio_context dev, const char* attribute, const char* data)
{
int len;
char buf[128];
snprintf(buf, 128, IIO_SYSFS_DEVICE "%d/" IIO_EVENTS "/%s", dev->num, attribute);
int fd = open(buf, O_WRONLY);
if (fd != -1) {
int len = write(fd, data, ( strlen(data) +1 ));
return MRAA_SUCCESS;
}
return MRAA_ERROR_UNSPECIFIED;
}
static mraa_result_t
mraa_iio_event_poll_nonblock(int fd, struct iio_event_data* data)
{
struct pollfd pfd;
if (fd < 0) {
return MRAA_ERROR_INVALID_RESOURCE;
}
pfd.fd = fd;
pfd.events = POLLIN;
// Wait for it forever or until pthread_cancel
// poll is a cancelable point like sleep()
int x = poll(&pfd, 1, -1);
read(fd, data, sizeof(struct iio_event_data));
return MRAA_SUCCESS;
}
mraa_result_t
mraa_iio_event_poll(mraa_iio_context dev, struct iio_event_data* data)
{
char bu[MAX_SIZE];
int ret;
int event_fd;
int fd;
sprintf(bu, IIO_SLASH_DEV "%d", dev->num);
fd = open(bu, 0);
ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd);
close(fd);
if (ret == -1 || event_fd == -1)
return MRAA_ERROR_UNSPECIFIED;
ret = read(event_fd, data, sizeof(struct iio_event_data));
close(event_fd);
return MRAA_SUCCESS;
}
static void*
mraa_iio_event_handler(void* arg)
{
struct iio_event_data data;
mraa_iio_context dev = (mraa_iio_context) arg;
for (;;) {
if (mraa_iio_event_poll_nonblock(dev->fp_event, &data) == MRAA_SUCCESS) {
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
dev->isr_event(&data);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
} else {
// we must have got an error code so die nicely
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
return NULL;
}
}
}
mraa_result_t
mraa_iio_event_setup_callback(mraa_iio_context dev, void (*fptr)(struct iio_event_data* data), void* args)
{
int ret;
char bu[MAX_SIZE];
if (dev->thread_id != 0) {
return MRAA_ERROR_NO_RESOURCES;
}
sprintf(bu, IIO_SLASH_DEV "%d", dev->num);
dev->fp = open(bu, O_RDONLY | O_NONBLOCK);
if (dev->fp == -1) {
return MRAA_ERROR_INVALID_RESOURCE;
}
ret = ioctl(dev->fp, IIO_GET_EVENT_FD_IOCTL, &dev->fp_event);
close(dev->fp);
if (ret == -1 || dev->fp_event == -1)
{
return MRAA_ERROR_UNSPECIFIED;
}
dev->isr_event = fptr;
pthread_create(&dev->thread_id, NULL, mraa_iio_event_handler, (void*) dev);
return MRAA_SUCCESS;
}
mraa_result_t
mraa_iio_event_extract_event(struct iio_event_data* event, int* chan_type, int* modifier, int* type, int* direction, int* channel, int* channel2, int* different)
{
*chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
*modifier= IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
*type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
*direction = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
*channel = IIO_EVENT_CODE_EXTRACT_CHAN(event->id);
*channel2 = IIO_EVENT_CODE_EXTRACT_CHAN2(event->id);
*different = IIO_EVENT_CODE_EXTRACT_DIFF(event->id);
return MRAA_SUCCESS;
}
#if 0
// does stop make any sense on iio devices?
mraa_result_t