From c9e069e6bc6ef28361a8b39731795621c957eddb Mon Sep 17 00:00:00 2001 From: Justin Kruger <20767264@student.uwa.edu.au> Date: Sat, 7 Sep 2013 20:03:57 +0800 Subject: [PATCH] Add sensors, actuators, PWM code Kept in separate files currently, can test and write proper function once Beaglebone arrives --- BBB code/ActuatorHandler_real.c | 60 ++ BBB code/Adafruit BBIO (c).rar | Bin 0 -> 31316 bytes BBB code/Adafruit_BBIO-0.0.17.tar.gz | Bin 0 -> 33754 bytes BBB code/GetData_real.c | 93 +++ BBB code/PWM_real/pwm.c | 86 +++ BBB code/PWM_real/pwm.h | 21 + .../old}/beagleboard sensors notes.docx | Bin .../old}/simple code examples.c | 0 .../sensors test drivers (c)/generic_buffer.c | 340 --------- sensors/sensors test drivers (c)/iio_utils.h | 654 ------------------ sensors/sensors test drivers (c)/readme.txt | 20 - .../sensors test drivers (c)/script_adc.sh | 5 - .../script_trigger.sh | 1 - sensors/simpleGPIO (c++)/SimpleGPIO.cpp | 233 ------- sensors/simpleGPIO (c++)/SimpleGPIO.h | 72 -- 15 files changed, 260 insertions(+), 1325 deletions(-) create mode 100644 BBB code/ActuatorHandler_real.c create mode 100644 BBB code/Adafruit BBIO (c).rar create mode 100644 BBB code/Adafruit_BBIO-0.0.17.tar.gz create mode 100644 BBB code/GetData_real.c create mode 100644 BBB code/PWM_real/pwm.c create mode 100644 BBB code/PWM_real/pwm.h rename {sensors => BBB code/old}/beagleboard sensors notes.docx (100%) rename {sensors => BBB code/old}/simple code examples.c (100%) delete mode 100644 sensors/sensors test drivers (c)/generic_buffer.c delete mode 100644 sensors/sensors test drivers (c)/iio_utils.h delete mode 100644 sensors/sensors test drivers (c)/readme.txt delete mode 100644 sensors/sensors test drivers (c)/script_adc.sh delete mode 100644 sensors/sensors test drivers (c)/script_trigger.sh delete mode 100644 sensors/simpleGPIO (c++)/SimpleGPIO.cpp delete mode 100644 sensors/simpleGPIO (c++)/SimpleGPIO.h diff --git a/BBB code/ActuatorHandler_real.c b/BBB code/ActuatorHandler_real.c new file mode 100644 index 0000000..783bd41 --- /dev/null +++ b/BBB code/ActuatorHandler_real.c @@ -0,0 +1,60 @@ +void ActuatorHandler(FCGIContext *context, ActuatorId id, const char *set_value) { + char *ptr; + + switch(id) { //Add new actuators here + case ACT_PRESSURE: //Suppose is pressure regulator. 0-700 input (kPa) + //requires PWM control + //TBA, currently in a separate file + //pwm_convert_duty(value); - convert input to required duty cycle + //pwm_set_frequency(PWM_id, freq); - can be done during PWM setup, frequency won't change (50Hz?) + //pwm_set_duty_cycle(PWM_id, duty_cycle); - this is the low/high percentage, will vary with input + //may also need to set polarity? + //if pwm is not setup, run setup functions first + { + int value = strtol(set_value, &ptr, 10); + if (*ptr == '\0' && value >= 0 && value <= 700) { + FCGI_BeginJSON(context, STATUS_OK); + FCGI_JSONKey("description"); + FCGI_JSONValue("\"Set pressure to %d kPa!\"", value); + FCGI_EndJSON(); + } else { + FCGI_RejectJSONEx(context, + STATUS_ERROR, "Invalid pressure specified."); + } + } break; + case ACT_SOLENOID1: + //requires digital control + { + int value = strtol(set_value, &ptr, 10); + if (*ptr == '\0') { + //code to set pin to value + //move this to separate function, will need to be repeated + int fd; + char buffer[10]; + if ((fd = open("/sys/class/gpio/gpio50/value", O_WRONLY)) < 0) //randomly chose pin 50 (each pin can be mapped to a certain switch case as required) + perror("Failed to open pin"); + if (value) { + strncpy(buffer, "1", ARRAY_SIZE(buffer) - 1); //copy value to buffer + } else { + strncpy(buffer, "0", ARRAY_SIZE(buffer) - 1); + } + int write = write(fd, buffer, strlen(buffer)); //write buffer to pin + if (write < 0) perror("Failed to write to pin"); + close(fd); + //code for server + const char *state = "off"; + if (value) + state = "on"; + FCGI_BeginJSON(context, STATUS_OK); + FCGI_JSONKey("description"); + FCGI_JSONValue("\"Solenoid 1 turned %s!\"", state); + FCGI_EndJSON(); + } else { + FCGI_RejectJSON(context, "Invalid actuator value specified"); + } + } break; + default: + FCGI_RejectJSONEx(context, + STATUS_ERROR, "Invalid actuator id specified."); + } +} \ No newline at end of file diff --git a/BBB code/Adafruit BBIO (c).rar b/BBB code/Adafruit BBIO (c).rar new file mode 100644 index 0000000000000000000000000000000000000000..92d6c478734366c5ba09d4047d463f3c841d73ef GIT binary patch literal 31316 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 ML2eHKK5&5l1I5v0CIA2c literal 0 HcmV?d00001 diff --git a/BBB code/Adafruit_BBIO-0.0.17.tar.gz b/BBB code/Adafruit_BBIO-0.0.17.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2f4023f5a72630dfa5f166e3ed7c5fbe9240d81d GIT binary patch literal 33754 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 Wo&F>+&-efN!@l9%vDFL;%nSgBtRVmZ literal 0 HcmV?d00001 diff --git a/BBB code/GetData_real.c b/BBB code/GetData_real.c new file mode 100644 index 0000000..2192772 --- /dev/null +++ b/BBB code/GetData_real.c @@ -0,0 +1,93 @@ +DataPoint * GetData(int sensor_id, DataPoint * d) +{ + //TODO: We should ensure the time is *never* allowed to change on the server if we use gettimeofday + // Another way people might think of getting the time is to count CPU cycles with clock() + // But this will not work because a) CPU clock speed may change on some devices (RPi?) and b) It counts cycles used by all threads + gettimeofday(&(d->time_stamp), NULL); + + switch (sensor_id) + { + //TODO: test buffer size on actual hardware + // maybe map the sensor path to an array/structure that can be looked up via sensor_id? + // not sure about the best place to do unit conversions, especially for nonlinear sensors + case SENSOR_TEST0: + { + int sensor = open("/sys/devices/platform/tsc/ain0", O_RDONLY); //need unique path for each sensor ADC, check path in documentation + char buffer[128]; //ADCs on Beaglebone are 12 bits? + int read = read(sensor, buffer, sizeof(buffer); + if (read != -1) { + buffer[read] = NULL; //string returned by read is not null terminated + int value = atoi(buffer); + double convert = (value/4096) * 1800; //sample conversion from ADC input to 'true value' + d->value = convert; + lseek(sensor, 0, 0); //after read string must be rewound to start of file using lseek + } + else { + perror("Failed to get value from sensor"); + } + close(sensor); + break; + } + case SENSOR_TEST1: + int sensor = open("/sys/devices/platform/tsc/ain1", O_RDONLY); + char buffer[128]; + int read = read(sensor, buffer, sizeof(buffer); + if (read != -1) { + buffer[read] = NULL; + int value = atoi(buffer); + double convert = (value/4096) * 1800; + d->value = convert; + lseek(sensor, 0, 0); + } + else { + perror("Failed to get value from sensor"); + } + close(sensor); + break; + break; + } + //TODO: think about a better way to address individual pins + // i.e. pass an int to a separate function that builds the correct filename + // doesn't really matter if the pins we're using are fixed though + case DIGITAL_TEST0: + int fd = open("/sys/class/gpio/gpio17/value", O_RDONLY) //again need the right addresses for each pin + char ch; //just one character for binary info + lseek(fd, 0, SEEK_SET); + int read = read(fd, &ch, sizeof(ch); + if (read != -1) { + if (ch != '0') { + d->value = 1; + } + else { + d->value = 0; + } + } + else { + perror("Failed to get value from pin"); + } + break; + case DIGITAL_TEST1: + int fd = open("/sys/class/gpio/gpio23/value", O_RDONLY) + char ch; + lseek(fd, 0, SEEK_SET); + int read = read(fd, &ch, sizeof(ch); + if (read != -1) { + if (ch != '0') { + d->value = 1; + } + else { + d->value = 0; + } + } + else { + perror("Failed to get value from pin"); + } + break; + default: + Fatal("Unknown sensor id: %d", sensor_id); + break; + } + usleep(100000); // simulate delay in sensor polling + + return d; +} \ No newline at end of file diff --git a/BBB code/PWM_real/pwm.c b/BBB code/PWM_real/pwm.c new file mode 100644 index 0000000..b58873e --- /dev/null +++ b/BBB code/PWM_real/pwm.c @@ -0,0 +1,86 @@ +#include "pwm.h" + +/* Initialize PWM : +1/ mmap /dev/mem to have write access to system clock +2/ enable system clock (0x0 = disabled, 0x02 = enabled) +3/ set correct pin MUX + +can modify pwm variables through virtual filesystem: +"/sys/class/pwm/ehrpwm.1:0/..." + +pwm drivers reference: +http://processors.wiki.ti.com/index.php/AM335x_PWM_Driver%27s_Guide */ + +void pwm_init(void) +{ + FILE *pwm_mux; + int i; + volatile uint32_t *epwmss1; + + int fd = open("/dev/mem", O_RDWR); + + if(fd < 0) + { + printf("Can't open /dev/mem\n"); + exit(1); + } + + epwmss1 = (volatile uint32_t *) mmap(NULL, LENGTH, PROT_READ|PROT_WRITE, MAP_SHARED, fd, START); + if(epwmss1 == NULL) + { + printf("Can't mmap\n"); + exit(1); + } + else + { + epwmss1[OFFSET_1 / sizeof(uint32_t)] = 0x2; + } + close(fd); + + pwm_mux = fopen("/sys/kernel/debug/omap_mux/gpmc_a2", "w"); + fprintf(pwm_mux, "6"); // pwm is mux mode 6 + fclose(pwm_mux); +} + +//can change filepath of pwm module "/ehrpwm.%d:0/" by passing %d as argument +//depends how many pwm modules we have to run +//TODO: + +void pwm_start(void) +{ + FILE *pwm_run; + pwm_run = fopen("/sys/class/pwm/ehrpwm.1:0/run", "w"); + fprintf(pwm_run, "1"); + fclose(pwm_run); +} + +void pwm_stop(void) +{ + FILE *pwm_run; + + pwm_run = fopen("/sys/class/pwm/ehrpwm.1:0/run", "w"); + fprintf(pwm_run, "0"); + fclose(pwm_run); +} + +//duty_percent is just a regular percentage (i.e. 50 = 50%) + +void pwm_set_duty(int duty_percent) +{ + FILE *pwm_duty; + + pwm_duty = fopen("/sys/class/pwm/ehrpwm.1:0/duty_percent", "w"); + fprintf(pwm_duty, "%d", duty_percent); + fclose(pwm_duty); +} + +//freq is just normal frequency (i.e. 100 = 100Hz) + +void pwm_set_period(int freq) +{ + FILE *pwm_period; + + pwm_period = fopen("/sys/class/pwm/ehrpwm.1:0/period_freq", "w"); + fprintf(pwm_period, "%d", freq); + fclose(pwm_period); +} \ No newline at end of file diff --git a/BBB code/PWM_real/pwm.h b/BBB code/PWM_real/pwm.h new file mode 100644 index 0000000..9c95373 --- /dev/null +++ b/BBB code/PWM_real/pwm.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define START 0x44e00000 // see datasheet of AM335x +#define LENGTH 1024 +#define OFFSET_1 0xcc // offset of PWM1 clock (see datasheet of AM335x p.1018) + +void pwm_init(void); +void pwm_start(void); +void pwm_stop(void); +void pwm_set_duty(int duty_percent); +void pwm_set_period(int freq); \ No newline at end of file diff --git a/sensors/beagleboard sensors notes.docx b/BBB code/old/beagleboard sensors notes.docx similarity index 100% rename from sensors/beagleboard sensors notes.docx rename to BBB code/old/beagleboard sensors notes.docx diff --git a/sensors/simple code examples.c b/BBB code/old/simple code examples.c similarity index 100% rename from sensors/simple code examples.c rename to BBB code/old/simple code examples.c diff --git a/sensors/sensors test drivers (c)/generic_buffer.c b/sensors/sensors test drivers (c)/generic_buffer.c deleted file mode 100644 index 40d0eca..0000000 --- a/sensors/sensors test drivers (c)/generic_buffer.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Industrialio buffer test code. - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is primarily intended as an example application. - * Reads the current buffer setup from sysfs and starts a short capture - * from the specified device, pretty printing the result after appropriate - * conversion. - * - * Command line parameters - * generic_buffer -n -t - * If trigger name is not specified the program assumes you want a dataready - * trigger associated with the device and goes looking for it. - * - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "iio_utils.h" - -/** - * size_from_channelarray() - calculate the storage size of a scan - * @channels: the channel info array - * @num_channels: number of channels - * - * Has the side effect of filling the channels[i].location values used - * in processing the buffer output. - **/ -int size_from_channelarray(struct iio_channel_info *channels, int num_channels) -{ - int bytes = 0; - int i = 0; - while (i < num_channels) { - if (bytes % channels[i].bytes == 0) - channels[i].location = bytes; - else - channels[i].location = bytes - bytes%channels[i].bytes - + channels[i].bytes; - bytes = channels[i].location + channels[i].bytes; - i++; - } - return bytes; -} - -void print2byte(int input, struct iio_channel_info *info) -{ - /* First swap if incorrect endian */ - if (info->be) - input = be16toh((uint16_t)input); - else - input = le16toh((uint16_t)input); - - /* - * Shift before conversion to avoid sign extension - * of left aligned data - */ - input = input >> info->shift; - if (info->is_signed) { - int16_t val = input; - val &= (1 << info->bits_used) - 1; - val = (int16_t)(val << (16 - info->bits_used)) >> - (16 - info->bits_used); - printf("%05f ", ((float)val + info->offset)*info->scale); - } else { - uint16_t val = input; - val &= (1 << info->bits_used) - 1; - printf("%05f ", ((float)val + info->offset)*info->scale); - } -} -/** - * process_scan() - print out the values in SI units - * @data: pointer to the start of the scan - * @channels: information about the channels. Note - * size_from_channelarray must have been called first to fill the - * location offsets. - * @num_channels: number of channels - **/ -void process_scan(char *data, - struct iio_channel_info *channels, - int num_channels) -{ - int k; - for (k = 0; k < num_channels; k++) - switch (channels[k].bytes) { - /* only a few cases implemented so far */ - case 2: - print2byte(*(uint16_t *)(data + channels[k].location), - &channels[k]); - break; - case 4: - if (!channels[k].is_signed) { - uint32_t val = *(uint32_t *) - (data + channels[k].location); - printf("%05f ", ((float)val + - channels[k].offset)* - channels[k].scale); - - } - break; - case 8: - if (channels[k].is_signed) { - int64_t val = *(int64_t *) - (data + - channels[k].location); - if ((val >> channels[k].bits_used) & 1) - val = (val & channels[k].mask) | - ~channels[k].mask; - /* special case for timestamp */ - if (channels[k].scale == 1.0f && - channels[k].offset == 0.0f) - printf("%" PRId64 " ", val); - else - printf("%05f ", ((float)val + - channels[k].offset)* - channels[k].scale); - } - break; - default: - break; - } - printf("\n"); -} - -int main(int argc, char **argv) -{ - unsigned long num_loops = 2; - unsigned long timedelay = 1000000; - unsigned long buf_len = 128; - - int ret, c, i, j, toread; - int fp; - - int num_channels; - char *trigger_name = NULL, *device_name = NULL; - char *dev_dir_name, *buf_dir_name; - - int datardytrigger = 1; - char *data; - ssize_t read_size; - int dev_num, trig_num; - char *buffer_access; - int scan_size; - int noevents = 0; - char *dummy; - - struct iio_channel_info *channels; - - while ((c = getopt(argc, argv, "l:w:c:et:n:")) != -1) { - switch (c) { - case 'n': - device_name = optarg; - break; - case 't': - trigger_name = optarg; - datardytrigger = 0; - break; - case 'e': - noevents = 1; - break; - case 'c': - num_loops = strtoul(optarg, &dummy, 10); - break; - case 'w': - timedelay = strtoul(optarg, &dummy, 10); - break; - case 'l': - buf_len = strtoul(optarg, &dummy, 10); - break; - case '?': - return -1; - } - } - - if (device_name == NULL) - return -1; - - /* Find the device requested */ - dev_num = find_type_by_name(device_name, "iio:device"); - if (dev_num < 0) { - printf("Failed to find the %s\n", device_name); - ret = -ENODEV; - goto error_ret; - } - printf("iio device number being used is %d\n", dev_num); - - asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); - if (trigger_name == NULL) { - /* - * Build the trigger name. If it is device associated its - * name is _dev[n] where n matches the device - * number found above - */ - ret = asprintf(&trigger_name, - "%s-dev%d", device_name, dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - } - - /* Verify the trigger exists */ - trig_num = find_type_by_name(trigger_name, "trigger"); - if (trig_num < 0) { - printf("Failed to find the trigger %s\n", trigger_name); - ret = -ENODEV; - goto error_free_triggername; - } - printf("iio trigger number being used is %d\n", trig_num); - - /* - * Parse the files in scan_elements to identify what channels are - * present - */ - ret = build_channel_array(dev_dir_name, &channels, &num_channels); - if (ret) { - printf("Problem reading scan element information\n"); - printf("diag %s\n", dev_dir_name); - goto error_free_triggername; - } - - /* - * Construct the directory name for the associated buffer. - * As we know that the lis3l02dq has only one buffer this may - * be built rather than found. - */ - ret = asprintf(&buf_dir_name, - "%siio:device%d/buffer", iio_dir, dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_triggername; - } - printf("%s %s\n", dev_dir_name, trigger_name); - /* Set the device trigger to be the data ready trigger found above */ - ret = write_sysfs_string_and_verify("trigger/current_trigger", - dev_dir_name, - trigger_name); - if (ret < 0) { - printf("Failed to write current_trigger file\n"); - goto error_free_buf_dir_name; - } - - /* Setup ring buffer parameters */ - ret = write_sysfs_int("length", buf_dir_name, buf_len); - if (ret < 0) - goto error_free_buf_dir_name; - - /* Enable the buffer */ - ret = write_sysfs_int("enable", buf_dir_name, 1); - if (ret < 0) - goto error_free_buf_dir_name; - scan_size = size_from_channelarray(channels, num_channels); - data = malloc(scan_size*buf_len); - if (!data) { - ret = -ENOMEM; - goto error_free_buf_dir_name; - } - - ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_data; - } - - /* Attempt to open non blocking the access dev */ - fp = open(buffer_access, O_RDONLY | O_NONBLOCK); - if (fp == -1) { /* If it isn't there make the node */ - printf("Failed to open %s\n", buffer_access); - ret = -errno; - goto error_free_buffer_access; - } - - /* Wait for events 10 times */ - for (j = 0; j < num_loops; j++) { - if (!noevents) { - struct pollfd pfd = { - .fd = fp, - .events = POLLIN, - }; - - poll(&pfd, 1, -1); - toread = buf_len; - - } else { - usleep(timedelay); - toread = 64; - } - - read_size = read(fp, - data, - toread*scan_size); - if (read_size == -EAGAIN) { - printf("nothing available\n"); - continue; - } - for (i = 0; i < read_size/scan_size; i++) - process_scan(data + scan_size*i, - channels, - num_channels); - } - - /* Stop the buffer */ - ret = write_sysfs_int("enable", buf_dir_name, 0); - if (ret < 0) - goto error_close_buffer_access; - - /* Disconnect the trigger - just write a dummy name. */ - write_sysfs_string("trigger/current_trigger", - dev_dir_name, "NULL"); - -error_close_buffer_access: - close(fp); -error_free_data: - free(data); -error_free_buffer_access: - free(buffer_access); -error_free_buf_dir_name: - free(buf_dir_name); -error_free_triggername: - if (datardytrigger) - free(trigger_name); -error_ret: - return ret; -} diff --git a/sensors/sensors test drivers (c)/iio_utils.h b/sensors/sensors test drivers (c)/iio_utils.h deleted file mode 100644 index cf32ae0..0000000 --- a/sensors/sensors test drivers (c)/iio_utils.h +++ /dev/null @@ -1,654 +0,0 @@ -/* IIO - useful set of util functionality - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Made up value to limit allocation sizes */ -#define IIO_MAX_NAME_LENGTH 30 - -#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" -#define FORMAT_TYPE_FILE "%s_type" - -const char *iio_dir = "/sys/bus/iio/devices/"; - -/** - * iioutils_break_up_name() - extract generic name from full channel name - * @full_name: the full channel name - * @generic_name: the output generic channel name - **/ -inline int iioutils_break_up_name(const char *full_name, - char **generic_name) -{ - char *current; - char *w, *r; - char *working; - current = strdup(full_name); - working = strtok(current, "_\0"); - w = working; - r = working; - - while (*r != '\0') { - if (!isdigit(*r)) { - *w = *r; - w++; - } - r++; - } - *w = '\0'; - *generic_name = strdup(working); - free(current); - - return 0; -} - -/** - * struct iio_channel_info - information about a given channel - * @name: channel name - * @generic_name: general name for channel type - * @scale: scale factor to be applied for conversion to si units - * @offset: offset to be applied for conversion to si units - * @index: the channel index in the buffer output - * @bytes: number of bytes occupied in buffer output - * @mask: a bit mask for the raw output - * @is_signed: is the raw value stored signed - * @enabled: is this channel enabled - **/ -struct iio_channel_info { - char *name; - char *generic_name; - float scale; - float offset; - unsigned index; - unsigned bytes; - unsigned bits_used; - unsigned shift; - uint64_t mask; - unsigned be; - unsigned is_signed; - unsigned enabled; - unsigned location; -}; - -/** - * iioutils_get_type() - find and process _type attribute data - * @is_signed: output whether channel is signed - * @bytes: output how many bytes the channel storage occupies - * @mask: output a bit mask for the raw data - * @be: big endian - * @device_dir: the iio device directory - * @name: the channel name - * @generic_name: the channel type name - **/ -inline int iioutils_get_type(unsigned *is_signed, - unsigned *bytes, - unsigned *bits_used, - unsigned *shift, - uint64_t *mask, - unsigned *be, - const char *device_dir, - const char *name, - const char *generic_name) -{ - FILE *sysfsfp; - int ret; - DIR *dp; - char *scan_el_dir, *builtname, *builtname_generic, *filename = 0; - char signchar, endianchar; - unsigned padint; - const struct dirent *ent; - - ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - ret = asprintf(&builtname, FORMAT_TYPE_FILE, name); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_scan_el_dir; - } - ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_builtname; - } - - dp = opendir(scan_el_dir); - if (dp == NULL) { - ret = -errno; - goto error_free_builtname_generic; - } - while (ent = readdir(dp), ent != NULL) - /* - * Do we allow devices to override a generic name with - * a specific one? - */ - if ((strcmp(builtname, ent->d_name) == 0) || - (strcmp(builtname_generic, ent->d_name) == 0)) { - ret = asprintf(&filename, - "%s/%s", scan_el_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_closedir; - } - sysfsfp = fopen(filename, "r"); - if (sysfsfp == NULL) { - printf("failed to open %s\n", filename); - ret = -errno; - goto error_free_filename; - } - - ret = fscanf(sysfsfp, - "%ce:%c%u/%u>>%u", - &endianchar, - &signchar, - bits_used, - &padint, shift); - if (ret < 0) { - printf("failed to pass scan type description\n"); - ret = -errno; - goto error_close_sysfsfp; - } - *be = (endianchar == 'b'); - *bytes = padint / 8; - if (*bits_used == 64) - *mask = ~0; - else - *mask = (1 << *bits_used) - 1; - if (signchar == 's') - *is_signed = 1; - else - *is_signed = 0; - fclose(sysfsfp); - free(filename); - - filename = 0; - sysfsfp = 0; - } -error_close_sysfsfp: - if (sysfsfp) - fclose(sysfsfp); -error_free_filename: - if (filename) - free(filename); -error_closedir: - closedir(dp); -error_free_builtname_generic: - free(builtname_generic); -error_free_builtname: - free(builtname); -error_free_scan_el_dir: - free(scan_el_dir); -error_ret: - return ret; -} - -inline int iioutils_get_param_float(float *output, - const char *param_name, - const char *device_dir, - const char *name, - const char *generic_name) -{ - FILE *sysfsfp; - int ret; - DIR *dp; - char *builtname, *builtname_generic; - char *filename = NULL; - const struct dirent *ent; - - ret = asprintf(&builtname, "%s_%s", name, param_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - ret = asprintf(&builtname_generic, - "%s_%s", generic_name, param_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_free_builtname; - } - dp = opendir(device_dir); - if (dp == NULL) { - ret = -errno; - goto error_free_builtname_generic; - } - while (ent = readdir(dp), ent != NULL) - if ((strcmp(builtname, ent->d_name) == 0) || - (strcmp(builtname_generic, ent->d_name) == 0)) { - ret = asprintf(&filename, - "%s/%s", device_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_closedir; - } - sysfsfp = fopen(filename, "r"); - if (!sysfsfp) { - ret = -errno; - goto error_free_filename; - } - fscanf(sysfsfp, "%f", output); - break; - } -error_free_filename: - if (filename) - free(filename); -error_closedir: - closedir(dp); -error_free_builtname_generic: - free(builtname_generic); -error_free_builtname: - free(builtname); -error_ret: - return ret; -} - -/** - * bsort_channel_array_by_index() - reorder so that the array is in index order - * - **/ - -inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array, - int cnt) -{ - - struct iio_channel_info temp; - int x, y; - - for (x = 0; x < cnt; x++) - for (y = 0; y < (cnt - 1); y++) - if ((*ci_array)[y].index > (*ci_array)[y+1].index) { - temp = (*ci_array)[y + 1]; - (*ci_array)[y + 1] = (*ci_array)[y]; - (*ci_array)[y] = temp; - } -} - -/** - * build_channel_array() - function to figure out what channels are present - * @device_dir: the IIO device directory in sysfs - * @ - **/ -inline int build_channel_array(const char *device_dir, - struct iio_channel_info **ci_array, - int *counter) -{ - DIR *dp; - FILE *sysfsfp; - int count, i; - struct iio_channel_info *current; - int ret; - const struct dirent *ent; - char *scan_el_dir; - char *filename; - - *counter = 0; - ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); - if (ret < 0) { - ret = -ENOMEM; - goto error_ret; - } - dp = opendir(scan_el_dir); - if (dp == NULL) { - ret = -errno; - goto error_free_name; - } - while (ent = readdir(dp), ent != NULL) - if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), - "_en") == 0) { - ret = asprintf(&filename, - "%s/%s", scan_el_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - goto error_close_dir; - } - sysfsfp = fopen(filename, "r"); - if (sysfsfp == NULL) { - ret = -errno; - free(filename); - goto error_close_dir; - } - fscanf(sysfsfp, "%u", &ret); - if (ret == 1) - (*counter)++; - fclose(sysfsfp); - free(filename); - } - *ci_array = malloc(sizeof(**ci_array) * (*counter)); - if (*ci_array == NULL) { - ret = -ENOMEM; - goto error_close_dir; - } - seekdir(dp, 0); - count = 0; - while (ent = readdir(dp), ent != NULL) { - if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), - "_en") == 0) { - current = &(*ci_array)[count++]; - ret = asprintf(&filename, - "%s/%s", scan_el_dir, ent->d_name); - if (ret < 0) { - ret = -ENOMEM; - /* decrement count to avoid freeing name */ - count--; - goto error_cleanup_array; - } - sysfsfp = fopen(filename, "r"); - if (sysfsfp == NULL) { - free(filename); - ret = -errno; - goto error_cleanup_array; - } - fscanf(sysfsfp, "%u", ¤t->enabled); - fclose(sysfsfp); - - if (!current->enabled) { - free(filename); - count--; - continue; - } - - current->scale = 1.0; - current->offset = 0; - current->name = strndup(ent->d_name, - strlen(ent->d_name) - - strlen("_en")); - if (current->name == NULL) { - free(filename); - ret = -ENOMEM; - goto error_cleanup_array; - } - /* Get the generic and specific name elements */ - ret = iioutils_break_up_name(current->name, - ¤t->generic_name); - if (ret) { - free(filename); - goto error_cleanup_array; - } - ret = asprintf(&filename, - "%s/%s_index", - scan_el_dir, - current->name); - if (ret < 0) { - free(filename); - ret = -ENOMEM; - goto error_cleanup_array; - } - sysfsfp = fopen(filename, "r"); - fscanf(sysfsfp, "%u", ¤t->index); - fclose(sysfsfp); - free(filename); - /* Find the scale */ - ret = iioutils_get_param_float(¤t->scale, - "scale", - device_dir, - current->name, - current->generic_name); - if (ret < 0) - goto error_cleanup_array; - ret = iioutils_get_param_float(¤t->offset, - "offset", - device_dir, - current->name, - current->generic_name); - if (ret < 0) - goto error_cleanup_array; - ret = iioutils_get_type(¤t->is_signed, - ¤t->bytes, - ¤t->bits_used, - ¤t->shift, - ¤t->mask, - ¤t->be, - device_dir, - current->name, - current->generic_name); - } - } - - closedir(dp); - /* reorder so that the array is in index order */ - bsort_channel_array_by_index(ci_array, *counter); - - return 0; - -error_cleanup_array: - for (i = count - 1; i >= 0; i--) - free((*ci_array)[i].name); - free(*ci_array); -error_close_dir: - closedir(dp); -error_free_name: - free(scan_el_dir); -error_ret: - return ret; -} - -/** - * find_type_by_name() - function to match top level types by name - * @name: top level type instance name - * @type: the type of top level instance being sort - * - * Typical types this is used for are device and trigger. - **/ -inline int find_type_by_name(const char *name, const char *type) -{ - const struct dirent *ent; - int number, numstrlen; - - FILE *nameFile; - DIR *dp; - char thisname[IIO_MAX_NAME_LENGTH]; - char *filename; - - dp = opendir(iio_dir); - if (dp == NULL) { - printf("No industrialio devices available\n"); - return -ENODEV; - } - - while (ent = readdir(dp), ent != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0 && - strlen(ent->d_name) > strlen(type) && - strncmp(ent->d_name, type, strlen(type)) == 0) { - numstrlen = sscanf(ent->d_name + strlen(type), - "%d", - &number); - /* verify the next character is not a colon */ - if (strncmp(ent->d_name + strlen(type) + numstrlen, - ":", - 1) != 0) { - filename = malloc(strlen(iio_dir) - + strlen(type) - + numstrlen - + 6); - if (filename == NULL) { - closedir(dp); - return -ENOMEM; - } - sprintf(filename, "%s%s%d/name", - iio_dir, - type, - number); - nameFile = fopen(filename, "r"); - if (!nameFile) { - free(filename); - continue; - } - free(filename); - fscanf(nameFile, "%s", thisname); - fclose(nameFile); - if (strcmp(name, thisname) == 0) { - closedir(dp); - return number; - } - } - } - } - closedir(dp); - return -ENODEV; -} - -inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) -{ - int ret; - FILE *sysfsfp; - int test; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - if (temp == NULL) - return -ENOMEM; - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) { - printf("failed to open %s\n", temp); - ret = -errno; - goto error_free; - } - fprintf(sysfsfp, "%d", val); - fclose(sysfsfp); - if (verify) { - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - printf("failed to open %s\n", temp); - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%d", &test); - fclose(sysfsfp); - if (test != val) { - printf("Possible failure in int write %d to %s%s\n", - val, - basedir, - filename); - ret = -1; - } - } -error_free: - free(temp); - return ret; -} - -int write_sysfs_int(char *filename, char *basedir, int val) -{ - return _write_sysfs_int(filename, basedir, val, 0); -} - -int write_sysfs_int_and_verify(char *filename, char *basedir, int val) -{ - return _write_sysfs_int(filename, basedir, val, 1); -} - -int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) -{ - int ret = 0; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - if (temp == NULL) { - printf("Memory allocation failed\n"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) { - printf("Could not open %s\n", temp); - ret = -errno; - goto error_free; - } - fprintf(sysfsfp, "%s", val); - fclose(sysfsfp); - if (verify) { - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - printf("could not open file to verify\n"); - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%s", temp); - fclose(sysfsfp); - if (strcmp(temp, val) != 0) { - printf("Possible failure in string write of %s " - "Should be %s " - "written to %s\%s\n", - temp, - val, - basedir, - filename); - ret = -1; - } - } -error_free: - free(temp); - - return ret; -} - -/** - * write_sysfs_string_and_verify() - string write, readback and verify - * @filename: name of file to write to - * @basedir: the sysfs directory in which the file is to be found - * @val: the string to write - **/ -int write_sysfs_string_and_verify(char *filename, char *basedir, char *val) -{ - return _write_sysfs_string(filename, basedir, val, 1); -} - -int write_sysfs_string(char *filename, char *basedir, char *val) -{ - return _write_sysfs_string(filename, basedir, val, 0); -} - -int read_sysfs_posint(char *filename, char *basedir) -{ - int ret; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - if (temp == NULL) { - printf("Memory allocation failed"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%d\n", &ret); - fclose(sysfsfp); -error_free: - free(temp); - return ret; -} - -int read_sysfs_float(char *filename, char *basedir, float *val) -{ - float ret = 0; - FILE *sysfsfp; - char *temp = malloc(strlen(basedir) + strlen(filename) + 2); - if (temp == NULL) { - printf("Memory allocation failed"); - return -ENOMEM; - } - sprintf(temp, "%s/%s", basedir, filename); - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) { - ret = -errno; - goto error_free; - } - fscanf(sysfsfp, "%f\n", val); - fclose(sysfsfp); -error_free: - free(temp); - return ret; -} diff --git a/sensors/sensors test drivers (c)/readme.txt b/sensors/sensors test drivers (c)/readme.txt deleted file mode 100644 index 80ca9a3..0000000 --- a/sensors/sensors test drivers (c)/readme.txt +++ /dev/null @@ -1,20 +0,0 @@ -This is a userspace application which accesses the adc via /dev/iio in continuous sampling mode. - -The application scans the scan_elements folder in /dev/iio/devices/iio:deviceX/scan_elements for enabled channels. - -Creates a data structure. - -Sets the buffer size. Enables the buffer. And reads from the dev file for the driver. - -The source code is located under kernel sources "drivers/staging/iio/Documentation/generic_buffer.c". - -How to compile: - -arm-arago-linux-gnueabi-gcc --static generic_buffer.c -o generic_buffer - -or - --gcc --static generic_buffer.c -o generic_buffer - - -SOURCE: https://github.com/ZubairLK/adc-iio-continuous-sampling-userspace \ No newline at end of file diff --git a/sensors/sensors test drivers (c)/script_adc.sh b/sensors/sensors test drivers (c)/script_adc.sh deleted file mode 100644 index 2afcb63..0000000 --- a/sensors/sensors test drivers (c)/script_adc.sh +++ /dev/null @@ -1,5 +0,0 @@ -echo 1 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger -echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage7_en -echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage5_en -generic_buffer -n TI-am335x-adc -t sysfstrig1 -l 128 - diff --git a/sensors/sensors test drivers (c)/script_trigger.sh b/sensors/sensors test drivers (c)/script_trigger.sh deleted file mode 100644 index cdaf2d1..0000000 --- a/sensors/sensors test drivers (c)/script_trigger.sh +++ /dev/null @@ -1 +0,0 @@ -echo 1 > /sys/bus/iio/devices/trigger0/trigger_now diff --git a/sensors/simpleGPIO (c++)/SimpleGPIO.cpp b/sensors/simpleGPIO (c++)/SimpleGPIO.cpp deleted file mode 100644 index ab17a98..0000000 --- a/sensors/simpleGPIO (c++)/SimpleGPIO.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * SimpleGPIO.cpp - * - * Modifications by Derek Molloy, School of Electronic Engineering, DCU - * www.eeng.dcu.ie/~molloyd/ - * Almost entirely based on Software by RidgeRun: - * - * Copyright (c) 2011, RidgeRun - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the RidgeRun. - * 4. Neither the name of the RidgeRun nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SimpleGPIO.h" -#include -#include -#include -#include -#include -#include -#include - -/**************************************************************** - * gpio_export - ****************************************************************/ -int gpio_export(unsigned int gpio) -{ - int fd, len; - char buf[MAX_BUF]; - - fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY); - if (fd < 0) { - perror("gpio/export"); - return fd; - } - - len = snprintf(buf, sizeof(buf), "%d", gpio); - write(fd, buf, len); - close(fd); - - return 0; -} - -/**************************************************************** - * gpio_unexport - ****************************************************************/ -int gpio_unexport(unsigned int gpio) -{ - int fd, len; - char buf[MAX_BUF]; - - fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY); - if (fd < 0) { - perror("gpio/export"); - return fd; - } - - len = snprintf(buf, sizeof(buf), "%d", gpio); - write(fd, buf, len); - close(fd); - return 0; -} - -/**************************************************************** - * gpio_set_dir - ****************************************************************/ -int gpio_set_dir(unsigned int gpio, PIN_DIRECTION out_flag) -{ - int fd; - char buf[MAX_BUF]; - - snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio); - - fd = open(buf, O_WRONLY); - if (fd < 0) { - perror("gpio/direction"); - return fd; - } - - if (out_flag == OUTPUT_PIN) - write(fd, "out", 4); - else - write(fd, "in", 3); - - close(fd); - return 0; -} - -/**************************************************************** - * gpio_set_value - ****************************************************************/ -int gpio_set_value(unsigned int gpio, PIN_VALUE value) -{ - int fd; - char buf[MAX_BUF]; - - snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); - - fd = open(buf, O_WRONLY); - if (fd < 0) { - perror("gpio/set-value"); - return fd; - } - - if (value==LOW) - write(fd, "0", 2); - else - write(fd, "1", 2); - - close(fd); - return 0; -} - -/**************************************************************** - * gpio_get_value - ****************************************************************/ -int gpio_get_value(unsigned int gpio, unsigned int *value) -{ - int fd; - char buf[MAX_BUF]; - char ch; - - snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); - - fd = open(buf, O_RDONLY); - if (fd < 0) { - perror("gpio/get-value"); - return fd; - } - - read(fd, &ch, 1); - - if (ch != '0') { - *value = 1; - } else { - *value = 0; - } - - close(fd); - return 0; -} - - -/**************************************************************** - * gpio_set_edge - ****************************************************************/ - -int gpio_set_edge(unsigned int gpio, char *edge) -{ - int fd; - char buf[MAX_BUF]; - - snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio); - - fd = open(buf, O_WRONLY); - if (fd < 0) { - perror("gpio/set-edge"); - return fd; - } - - write(fd, edge, strlen(edge) + 1); - close(fd); - return 0; -} - -/**************************************************************** - * gpio_fd_open - ****************************************************************/ - -int gpio_fd_open(unsigned int gpio) -{ - int fd; - char buf[MAX_BUF]; - - snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); - - fd = open(buf, O_RDONLY | O_NONBLOCK ); - if (fd < 0) { - perror("gpio/fd_open"); - } - return fd; -} - -/**************************************************************** - * gpio_fd_close - ****************************************************************/ - -int gpio_fd_close(int fd) -{ - return close(fd); -} - - -/**************************************************************** - * gpio_omap_mux_setup - Allow us to setup the omap mux mode for a pin - ****************************************************************/ -int gpio_omap_mux_setup(const char *omap_pin0_name, const char *mode) -{ - int fd; - char buf[MAX_BUF]; - snprintf(buf, sizeof(buf), SYSFS_OMAP_MUX_DIR "%s", omap_pin0_name); - fd = open(buf, O_WRONLY); - if (fd < 0) { - perror("failed to open OMAP_MUX"); - return fd; - } - write(fd, mode, strlen(mode) + 1); - close(fd); - return 0; -} \ No newline at end of file diff --git a/sensors/simpleGPIO (c++)/SimpleGPIO.h b/sensors/simpleGPIO (c++)/SimpleGPIO.h deleted file mode 100644 index edbd78a..0000000 --- a/sensors/simpleGPIO (c++)/SimpleGPIO.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SimpleGPIO.h - * - * Copyright Derek Molloy, School of Electronic Engineering, Dublin City University - * www.eeng.dcu.ie/~molloyd/ - * - * Based on Software by RidgeRun - * Copyright (c) 2011, RidgeRun - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the RidgeRun. - * 4. Neither the name of the RidgeRun nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SIMPLEGPIO_H_ -#define SIMPLEGPIO_H_ - - /**************************************************************** - * Constants - ****************************************************************/ - -#define SYSFS_GPIO_DIR "/sys/class/gpio" -#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */ -#define MAX_BUF 64 -#define SYSFS_OMAP_MUX_DIR "/sys/kernel/debug/omap_mux/" - -enum PIN_DIRECTION{ - INPUT_PIN=0, - OUTPUT_PIN=1 -}; - -enum PIN_VALUE{ - LOW=0, - HIGH=1 -}; - -/**************************************************************** - * gpio_export - ****************************************************************/ -int gpio_export(unsigned int gpio); -int gpio_unexport(unsigned int gpio); -int gpio_set_dir(unsigned int gpio, PIN_DIRECTION out_flag); -int gpio_set_value(unsigned int gpio, PIN_VALUE value); -int gpio_get_value(unsigned int gpio, unsigned int *value); -int gpio_set_edge(unsigned int gpio, char *edge); -int gpio_fd_open(unsigned int gpio); -int gpio_fd_close(int fd); -int gpio_omap_mux_setup(const char *omap_pin0_name, const char *mode); - -#endif /* SIMPLEGPIO_H_ */ \ No newline at end of file -- 2.20.1