2014-04-22 15:51:28 +01:00
|
|
|
/*
|
|
|
|
|
* Author: Brendan Le Foll <brendan.le.foll@intel.com>
|
2014-05-01 16:55:23 +01:00
|
|
|
* Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
|
2016-01-20 15:58:06 +00:00
|
|
|
* Copyright (c) 2014-2016 Intel Corporation.
|
2014-04-22 15:51:28 +01:00
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
|
* the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
|
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
|
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
|
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-07-10 17:52:50 +01:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
#if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600
|
|
|
|
|
#define _XOPEN_SOURCE 600 /* Get nftw() and S_IFSOCK declarations */
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-04-29 15:01:24 +01:00
|
|
|
#include <stddef.h>
|
2014-05-19 09:50:58 +01:00
|
|
|
#include <stdlib.h>
|
2014-06-04 14:39:41 +01:00
|
|
|
#include <sched.h>
|
|
|
|
|
#include <string.h>
|
2014-12-15 22:40:57 +01:00
|
|
|
#include <pwd.h>
|
2015-02-15 12:47:11 +01:00
|
|
|
#include <glob.h>
|
2015-07-10 17:52:50 +01:00
|
|
|
#include <ftw.h>
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
2014-04-29 15:01:24 +01:00
|
|
|
|
2014-06-24 17:24:54 +01:00
|
|
|
#include "mraa_internal.h"
|
2016-03-07 14:49:42 +00:00
|
|
|
#include "firmata/firmata_mraa.h"
|
2014-04-29 15:01:24 +01:00
|
|
|
#include "gpio.h"
|
2014-04-28 00:29:14 +01:00
|
|
|
#include "version.h"
|
2014-04-08 18:43:26 +01:00
|
|
|
|
2015-10-06 23:14:08 +02:00
|
|
|
#define IIO_DEVICE_WILDCARD "iio:device*"
|
2014-07-14 16:56:12 +01:00
|
|
|
mraa_board_t* plat = NULL;
|
2015-10-06 11:51:56 +01:00
|
|
|
mraa_iio_info_t* plat_iio = NULL;
|
2016-02-26 13:50:07 -08:00
|
|
|
mraa_lang_func_t* lang_func = NULL;
|
2015-08-20 12:08:57 -07:00
|
|
|
|
2016-01-20 16:01:52 +00:00
|
|
|
static char* platform_name = NULL;
|
|
|
|
|
static char* platform_long_name = NULL;
|
2014-04-29 15:01:24 +01:00
|
|
|
|
2015-09-28 16:26:53 +01:00
|
|
|
static int num_i2c_devices = 0;
|
|
|
|
|
static int num_iio_devices = 0;
|
|
|
|
|
|
2015-03-23 14:39:12 +00:00
|
|
|
const char*
|
2014-06-24 17:24:54 +01:00
|
|
|
mraa_get_version()
|
2014-04-08 18:43:26 +01:00
|
|
|
{
|
2014-04-28 00:29:14 +01:00
|
|
|
return gVERSION;
|
2014-04-08 18:43:26 +01:00
|
|
|
}
|
2014-04-29 15:01:24 +01:00
|
|
|
|
2014-09-25 14:31:04 +01:00
|
|
|
mraa_result_t
|
|
|
|
|
mraa_set_log_level(int level)
|
|
|
|
|
{
|
|
|
|
|
if (level <= 7 && level >= 0) {
|
|
|
|
|
setlogmask(LOG_UPTO(level));
|
2015-08-14 11:15:57 +01:00
|
|
|
syslog(LOG_DEBUG, "Loglevel %d is set", level);
|
2014-09-25 14:31:04 +01:00
|
|
|
return MRAA_SUCCESS;
|
|
|
|
|
}
|
2015-08-14 11:15:57 +01:00
|
|
|
syslog(LOG_NOTICE, "Invalid loglevel %d requested", level);
|
2014-09-25 14:31:04 +01:00
|
|
|
return MRAA_ERROR_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-28 16:26:53 +01:00
|
|
|
|
2015-03-01 10:22:13 +00:00
|
|
|
#if (defined SWIGPYTHON) || (defined SWIG)
|
|
|
|
|
mraa_result_t
|
|
|
|
|
#else
|
2014-06-24 17:24:54 +01:00
|
|
|
mraa_result_t __attribute__((constructor))
|
2015-03-01 10:22:13 +00:00
|
|
|
#endif
|
2014-06-24 17:24:54 +01:00
|
|
|
mraa_init()
|
2014-04-29 15:01:24 +01:00
|
|
|
{
|
2014-12-09 18:31:20 +00:00
|
|
|
if (plat != NULL) {
|
2016-03-01 12:12:46 -08:00
|
|
|
return MRAA_SUCCESS;
|
2014-12-09 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-15 22:40:57 +01:00
|
|
|
uid_t proc_euid = geteuid();
|
2015-03-23 14:39:12 +00:00
|
|
|
struct passwd* proc_user = getpwuid(proc_euid);
|
2014-12-15 22:40:57 +01:00
|
|
|
|
2014-09-25 14:31:04 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
|
setlogmask(LOG_UPTO(LOG_DEBUG));
|
|
|
|
|
#else
|
|
|
|
|
setlogmask(LOG_UPTO(LOG_NOTICE));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
openlog("libmraa", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
2015-03-23 14:39:12 +00:00
|
|
|
syslog(LOG_NOTICE, "libmraa version %s initialised by user '%s' with EUID %d",
|
|
|
|
|
mraa_get_version(), (proc_user != NULL) ? proc_user->pw_name : "<unknown>", proc_euid);
|
2014-12-15 22:40:57 +01:00
|
|
|
|
2015-07-01 10:24:39 -07:00
|
|
|
mraa_platform_t platform_type;
|
2015-06-26 09:59:40 +01:00
|
|
|
#if defined(X86PLAT)
|
2014-11-21 00:01:08 +00:00
|
|
|
// Use runtime x86 platform detection
|
|
|
|
|
platform_type = mraa_x86_platform();
|
2015-06-26 09:59:40 +01:00
|
|
|
#elif defined(ARMPLAT)
|
|
|
|
|
// Use runtime ARM platform detection
|
|
|
|
|
platform_type = mraa_arm_platform();
|
|
|
|
|
#else
|
|
|
|
|
#error mraa_ARCH NOTHING
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-01-20 16:01:52 +00:00
|
|
|
if (plat != NULL) {
|
2015-07-01 10:24:39 -07:00
|
|
|
plat->platform_type = platform_type;
|
2016-01-20 16:01:52 +00:00
|
|
|
} else {
|
|
|
|
|
platform_name = NULL;
|
|
|
|
|
}
|
2015-07-01 10:24:39 -07:00
|
|
|
|
2016-03-01 11:15:43 -08:00
|
|
|
// Create null base platform if one doesn't already exist
|
2015-05-27 15:36:46 -07:00
|
|
|
if (plat == NULL) {
|
|
|
|
|
plat = (mraa_board_t*) calloc(1, sizeof(mraa_board_t));
|
|
|
|
|
if (plat != NULL) {
|
2015-08-20 12:08:57 -07:00
|
|
|
plat->platform_type = MRAA_NULL_PLATFORM;
|
2015-10-06 11:51:56 +01:00
|
|
|
plat->platform_name = "Unknown platform";
|
2015-07-01 10:24:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
2016-03-01 11:15:43 -08:00
|
|
|
|
|
|
|
|
#if defined(USBPLAT)
|
2016-02-11 10:16:58 +00:00
|
|
|
// Now detect sub platform, note this is not an else since we could be in
|
|
|
|
|
// an error case and fall through to MRAA_ERROR_PLATFORM_NOT_INITIALISED
|
2015-07-01 10:24:39 -07:00
|
|
|
if (plat != NULL) {
|
|
|
|
|
mraa_platform_t usb_platform_type = mraa_usb_platform_extender(plat);
|
2016-02-11 10:16:58 +00:00
|
|
|
// if we have no known platform just replace usb platform with platform
|
2015-08-11 11:54:11 +01:00
|
|
|
if (plat->platform_type == MRAA_UNKNOWN_PLATFORM && usb_platform_type != MRAA_UNKNOWN_PLATFORM) {
|
2015-07-01 10:24:39 -07:00
|
|
|
plat->platform_type = usb_platform_type;
|
2015-05-27 15:36:46 -07:00
|
|
|
}
|
|
|
|
|
}
|
2014-11-21 00:01:08 +00:00
|
|
|
if (plat == NULL) {
|
|
|
|
|
printf("mraa: FATAL error, failed to initialise platform\n");
|
|
|
|
|
return MRAA_ERROR_PLATFORM_NOT_INITIALISED;
|
2014-06-16 18:45:59 +01:00
|
|
|
}
|
2015-06-26 09:59:40 +01:00
|
|
|
#endif
|
2014-12-15 22:40:57 +01:00
|
|
|
|
2016-03-07 14:49:42 +00:00
|
|
|
#if defined(FIRMATA)
|
|
|
|
|
// look for USB id 8087:0aba -> genuino/arduino 101
|
|
|
|
|
#endif
|
|
|
|
|
|
2015-12-03 15:24:10 -08:00
|
|
|
// Look for IIO devices
|
|
|
|
|
mraa_iio_detect();
|
2015-12-03 12:30:59 -08:00
|
|
|
|
2016-01-20 16:01:52 +00:00
|
|
|
if (plat != NULL) {
|
|
|
|
|
int length = strlen(plat->platform_name) + 1;
|
|
|
|
|
if (mraa_has_sub_platform()) {
|
2016-02-12 11:27:02 +00:00
|
|
|
// Account for ' + ' chars
|
|
|
|
|
length += strlen(plat->sub_platform->platform_name) + 3;
|
2016-01-20 16:01:52 +00:00
|
|
|
}
|
|
|
|
|
platform_name = calloc(length, sizeof(char));
|
|
|
|
|
if (mraa_has_sub_platform()) {
|
|
|
|
|
snprintf(platform_name, length, "%s + %s", plat->platform_name, plat->sub_platform->platform_name);
|
|
|
|
|
} else {
|
|
|
|
|
strncpy(platform_name, plat->platform_name, length);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-26 13:50:07 -08:00
|
|
|
lang_func = (mraa_lang_func_t*) calloc(1, sizeof(mraa_lang_func_t));
|
2016-03-01 15:50:55 +00:00
|
|
|
if (lang_func == NULL) {
|
|
|
|
|
return MRAA_ERROR_NO_RESOURCES;
|
|
|
|
|
}
|
2016-02-26 13:50:07 -08:00
|
|
|
|
2015-07-30 12:15:03 -07:00
|
|
|
syslog(LOG_NOTICE, "libmraa initialised for platform '%s' of type %d", mraa_get_platform_name(), mraa_get_platform_type());
|
2014-06-24 17:24:54 +01:00
|
|
|
return MRAA_SUCCESS;
|
2014-04-29 15:01:24 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-01 16:38:41 +01:00
|
|
|
void
|
|
|
|
|
mraa_deinit()
|
|
|
|
|
{
|
2014-12-16 22:12:18 +01:00
|
|
|
if (plat != NULL) {
|
|
|
|
|
if (plat->pins != NULL) {
|
|
|
|
|
free(plat->pins);
|
|
|
|
|
}
|
2015-07-27 09:32:39 -07:00
|
|
|
mraa_board_t* sub_plat = plat->sub_platform;
|
2015-09-03 15:28:36 +01:00
|
|
|
if (sub_plat != NULL) {
|
2015-07-27 09:32:39 -07:00
|
|
|
if (sub_plat->pins != NULL) {
|
|
|
|
|
free(sub_plat->pins);
|
|
|
|
|
}
|
2015-09-03 15:28:36 +01:00
|
|
|
free(sub_plat);
|
2015-07-27 09:32:39 -07:00
|
|
|
}
|
2014-12-16 22:12:18 +01:00
|
|
|
free(plat);
|
2015-09-03 15:28:36 +01:00
|
|
|
|
2014-12-16 22:12:18 +01:00
|
|
|
}
|
2015-10-06 11:51:56 +01:00
|
|
|
if (plat_iio != NULL) {
|
|
|
|
|
free(plat_iio);
|
|
|
|
|
}
|
2014-09-25 14:31:04 +01:00
|
|
|
closelog();
|
2014-07-01 16:38:41 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-04 14:39:41 +01:00
|
|
|
int
|
2014-06-24 17:24:54 +01:00
|
|
|
mraa_set_priority(const unsigned int priority)
|
2014-06-04 14:39:41 +01:00
|
|
|
{
|
|
|
|
|
struct sched_param sched_s;
|
|
|
|
|
|
|
|
|
|
memset(&sched_s, 0, sizeof(struct sched_param));
|
|
|
|
|
if (priority > sched_get_priority_max(SCHED_RR)) {
|
|
|
|
|
sched_s.sched_priority = sched_get_priority_max(SCHED_RR);
|
2015-03-23 14:39:12 +00:00
|
|
|
} else {
|
2014-06-04 14:39:41 +01:00
|
|
|
sched_s.sched_priority = priority;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sched_setscheduler(0, SCHED_RR, &sched_s);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-03 12:30:59 -08:00
|
|
|
static int
|
|
|
|
|
mraa_count_iio_devices(const char* path, const struct stat* sb, int flag, struct FTW* ftwb)
|
|
|
|
|
{
|
|
|
|
|
// we are only interested in files with specific names
|
|
|
|
|
if (fnmatch(IIO_DEVICE_WILDCARD, basename(path), 0) == 0) {
|
|
|
|
|
num_iio_devices++;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2015-12-02 14:39:17 -08:00
|
|
|
|
|
|
|
|
mraa_result_t
|
|
|
|
|
mraa_iio_detect()
|
|
|
|
|
{
|
|
|
|
|
plat_iio = (mraa_iio_info_t*) calloc(1, sizeof(mraa_iio_info_t));
|
2015-12-21 15:27:15 +00:00
|
|
|
plat_iio->iio_device_count = num_iio_devices;
|
2015-12-02 14:39:17 -08:00
|
|
|
// Now detect IIO devices, linux only
|
|
|
|
|
// find how many iio devices we have if we haven't already
|
|
|
|
|
if (num_iio_devices == 0) {
|
|
|
|
|
if (nftw("/sys/bus/iio/devices", &mraa_count_iio_devices, 20, FTW_PHYS) == -1) {
|
|
|
|
|
return MRAA_ERROR_UNSPECIFIED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
char name[64], filepath[64];
|
|
|
|
|
int fd, len, i;
|
|
|
|
|
plat_iio->iio_device_count = num_iio_devices;
|
|
|
|
|
plat_iio->iio_devices = calloc(num_iio_devices, sizeof(struct _iio));
|
|
|
|
|
struct _iio* device;
|
|
|
|
|
for (i=0; i < num_iio_devices; i++) {
|
|
|
|
|
device = &plat_iio->iio_devices[i];
|
|
|
|
|
device->num = i;
|
|
|
|
|
snprintf(filepath, 64, "/sys/bus/iio/devices/iio:device%d/name", i);
|
|
|
|
|
fd = open(filepath, O_RDONLY);
|
2015-12-21 15:15:15 +00:00
|
|
|
if (fd != -1) {
|
2015-12-02 14:39:17 -08:00
|
|
|
len = read(fd, &name, 64);
|
|
|
|
|
if (len > 1) {
|
|
|
|
|
// remove any trailing CR/LF symbols
|
|
|
|
|
name[strcspn(name, "\r\n")] = '\0';
|
|
|
|
|
len = strlen(name);
|
|
|
|
|
// use strndup
|
|
|
|
|
device->name = malloc((sizeof(char) * len) + sizeof(char));
|
|
|
|
|
strncpy(device->name, name, len+1);
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return MRAA_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-30 18:09:27 +00:00
|
|
|
mraa_result_t
|
2014-06-24 17:24:54 +01:00
|
|
|
mraa_setup_mux_mapped(mraa_pin_t meta)
|
2014-04-30 11:13:36 +01:00
|
|
|
{
|
|
|
|
|
int mi;
|
2016-03-12 23:46:17 +03:00
|
|
|
mraa_result_t ret;
|
|
|
|
|
mraa_gpio_context mux_i = NULL;
|
|
|
|
|
int last_pin = -1;
|
2014-12-10 15:29:08 +00:00
|
|
|
|
2014-05-02 11:52:40 +01:00
|
|
|
for (mi = 0; mi < meta.mux_total; mi++) {
|
2014-12-15 11:47:21 +00:00
|
|
|
|
2016-03-12 23:46:17 +03:00
|
|
|
switch(meta.mux[mi].pincmd) {
|
|
|
|
|
case PINCMD_UNDEFINED: // used for backward compatibility
|
|
|
|
|
if(meta.mux[mi].pin != last_pin) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
|
|
|
|
|
if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE;
|
|
|
|
|
last_pin = meta.mux[mi].pin;
|
|
|
|
|
}
|
|
|
|
|
// this function will sometimes fail, however this is not critical as
|
|
|
|
|
// long as the write succeeds - Test case galileo gen2 pin2
|
|
|
|
|
mraa_gpio_dir(mux_i, MRAA_GPIO_OUT);
|
|
|
|
|
ret = mraa_gpio_write(mux_i, meta.mux[mi].value);
|
|
|
|
|
if(ret != MRAA_SUCCESS) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
return MRAA_ERROR_INVALID_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PINCMD_SET_VALUE:
|
|
|
|
|
if(meta.mux[mi].pin != last_pin) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
|
|
|
|
|
if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE;
|
|
|
|
|
last_pin = meta.mux[mi].pin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = mraa_gpio_write(mux_i, meta.mux[mi].value);
|
|
|
|
|
|
|
|
|
|
if(ret != MRAA_SUCCESS) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
return MRAA_ERROR_INVALID_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PINCMD_SET_DIRECTION:
|
|
|
|
|
if(meta.mux[mi].pin != last_pin) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
|
|
|
|
|
if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE;
|
|
|
|
|
last_pin = meta.mux[mi].pin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = mraa_gpio_dir(mux_i, meta.mux[mi].value);
|
|
|
|
|
|
|
|
|
|
if(ret != MRAA_SUCCESS) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
return MRAA_ERROR_INVALID_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PINCMD_SET_IN_VALUE:
|
|
|
|
|
if(meta.mux[mi].pin != last_pin) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
|
|
|
|
|
if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE;
|
|
|
|
|
last_pin = meta.mux[mi].pin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = mraa_gpio_dir(mux_i, MRAA_GPIO_IN);
|
|
|
|
|
|
|
|
|
|
if(ret == MRAA_SUCCESS)
|
|
|
|
|
ret = mraa_gpio_write(mux_i, meta.mux[mi].value);
|
|
|
|
|
|
|
|
|
|
if(ret != MRAA_SUCCESS) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
return MRAA_ERROR_INVALID_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PINCMD_SET_OUT_VALUE:
|
|
|
|
|
if(meta.mux[mi].pin != last_pin) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
|
|
|
|
|
if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE;
|
|
|
|
|
last_pin = meta.mux[mi].pin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = mraa_gpio_dir(mux_i, MRAA_GPIO_OUT);
|
|
|
|
|
|
|
|
|
|
if(ret == MRAA_SUCCESS)
|
|
|
|
|
ret = mraa_gpio_write(mux_i, meta.mux[mi].value);
|
|
|
|
|
|
|
|
|
|
if(ret != MRAA_SUCCESS) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
return MRAA_ERROR_INVALID_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PINCMD_SET_MODE:
|
|
|
|
|
if(meta.mux[mi].pin != last_pin) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
|
|
|
|
|
if (mux_i == NULL) return MRAA_ERROR_INVALID_HANDLE;
|
|
|
|
|
last_pin = meta.mux[mi].pin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = mraa_gpio_mode(mux_i, meta.mux[mi].value);
|
|
|
|
|
|
|
|
|
|
if(ret != MRAA_SUCCESS) {
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
|
|
|
|
mraa_gpio_close(mux_i);
|
|
|
|
|
}
|
|
|
|
|
return MRAA_ERROR_INVALID_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PINCMD_SKIP:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
syslog(LOG_NOTICE, "mraa_setup_mux_mapped: wrong command %d on pin %d with value %d", meta.mux[mi].pincmd, meta.mux[mi].pin, meta.mux[mi].value);
|
|
|
|
|
break;
|
2014-12-10 15:29:08 +00:00
|
|
|
}
|
2016-03-12 23:46:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mux_i != NULL) {
|
|
|
|
|
mraa_gpio_owner(mux_i, 0);
|
2014-12-10 15:29:08 +00:00
|
|
|
mraa_gpio_close(mux_i);
|
2014-04-30 11:13:36 +01:00
|
|
|
}
|
2014-12-10 15:29:08 +00:00
|
|
|
|
2014-06-24 17:24:54 +01:00
|
|
|
return MRAA_SUCCESS;
|
2014-04-30 11:13:36 +01:00
|
|
|
}
|
|
|
|
|
|
2014-05-06 15:29:42 +01:00
|
|
|
void
|
2014-06-24 17:24:54 +01:00
|
|
|
mraa_result_print(mraa_result_t result)
|
2014-05-06 15:29:42 +01:00
|
|
|
{
|
|
|
|
|
switch (result) {
|
2014-09-25 14:31:04 +01:00
|
|
|
case MRAA_SUCCESS:
|
|
|
|
|
fprintf(stdout, "MRAA: SUCCESS\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_FEATURE_NOT_IMPLEMENTED:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Feature not implemented.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_FEATURE_NOT_SUPPORTED:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Feature not supported by Hardware.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_INVALID_VERBOSITY_LEVEL:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Invalid verbosity level.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_INVALID_PARAMETER:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Invalid parameter.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_INVALID_HANDLE:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Invalid Handle.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_NO_RESOURCES:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: No resources.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_INVALID_RESOURCE:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Invalid resource.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_INVALID_QUEUE_TYPE:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Invalid Queue Type.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_NO_DATA_AVAILABLE:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: No Data available.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_INVALID_PLATFORM:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Platform not recognised.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_PLATFORM_NOT_INITIALISED:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Platform not initialised.\n");
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_ERROR_UNSPECIFIED:
|
2014-09-25 14:31:04 +01:00
|
|
|
fprintf(stdout, "MRAA: Unspecified Error.\n");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(stdout, "MRAA: Unrecognised error.\n");
|
|
|
|
|
break;
|
2014-05-06 15:29:42 +01:00
|
|
|
}
|
|
|
|
|
}
|
2014-05-07 15:54:59 +01:00
|
|
|
|
2015-07-27 09:32:39 -07:00
|
|
|
|
2015-09-03 15:28:36 +01:00
|
|
|
mraa_boolean_t
|
2015-07-28 16:35:18 -07:00
|
|
|
mraa_has_sub_platform()
|
|
|
|
|
{
|
|
|
|
|
return (plat != NULL) && (plat->sub_platform != NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-27 09:32:39 -07:00
|
|
|
mraa_boolean_t
|
2015-08-20 12:08:57 -07:00
|
|
|
mraa_pin_mode_test(int pin, mraa_pinmodes_t mode)
|
2015-07-27 09:32:39 -07:00
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat == NULL)
|
2015-07-27 09:32:39 -07:00
|
|
|
return 0;
|
|
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
mraa_board_t* current_plat = plat;
|
|
|
|
|
if (mraa_is_sub_platform_id(pin)) {
|
2015-07-27 09:32:39 -07:00
|
|
|
current_plat = plat->sub_platform;
|
2015-08-20 12:08:57 -07:00
|
|
|
if (current_plat == NULL) {
|
|
|
|
|
syslog(LOG_ERR, "mraa_pin_mode_test: Sub platform Not Initialised");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
pin = mraa_get_sub_platform_index(pin);
|
|
|
|
|
}
|
2015-07-27 09:32:39 -07:00
|
|
|
|
2015-08-11 11:45:55 +01:00
|
|
|
if (current_plat == NULL || current_plat->platform_type == MRAA_UNKNOWN_PLATFORM) {
|
2015-04-04 18:27:44 +01:00
|
|
|
return 0;
|
2014-05-07 16:07:58 +01:00
|
|
|
}
|
2015-07-27 09:32:39 -07:00
|
|
|
if (pin > (current_plat->phy_pin_count - 1) || pin < 0)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2015-03-23 14:39:12 +00:00
|
|
|
switch (mode) {
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_VALID:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.valid == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_GPIO:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.gpio == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_PWM:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.pwm == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_FAST_GPIO:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.fast_gpio == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_SPI:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.spi == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_I2C:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.i2c == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-06-24 17:24:54 +01:00
|
|
|
case MRAA_PIN_AIO:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.aio == 1)
|
2014-05-07 15:54:59 +01:00
|
|
|
return 1;
|
|
|
|
|
break;
|
2014-12-18 14:11:25 +00:00
|
|
|
case MRAA_PIN_UART:
|
2015-07-27 09:32:39 -07:00
|
|
|
if (current_plat->pins[pin].capabilites.uart == 1)
|
2014-12-18 14:11:25 +00:00
|
|
|
return 1;
|
2015-01-05 23:04:50 +00:00
|
|
|
break;
|
2014-12-18 14:13:04 +00:00
|
|
|
default:
|
|
|
|
|
syslog(LOG_NOTICE, "requested pinmode invalid");
|
|
|
|
|
break;
|
2014-05-07 15:54:59 +01:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2014-05-29 16:30:07 +01:00
|
|
|
|
2015-03-23 14:39:12 +00:00
|
|
|
mraa_platform_t
|
|
|
|
|
mraa_get_platform_type()
|
2014-06-20 18:00:19 +01:00
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat == NULL)
|
2015-07-01 10:24:39 -07:00
|
|
|
return MRAA_UNKNOWN_PLATFORM;
|
2015-08-20 12:08:57 -07:00
|
|
|
return plat->platform_type;
|
2014-06-20 18:00:19 +01:00
|
|
|
}
|
2014-06-25 17:32:41 +01:00
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
int
|
|
|
|
|
mraa_get_platform_combined_type()
|
|
|
|
|
{
|
|
|
|
|
int type = mraa_get_platform_type();
|
|
|
|
|
int sub_type = mraa_has_sub_platform() ? plat->sub_platform->platform_type : MRAA_UNKNOWN_PLATFORM;
|
|
|
|
|
return type | (sub_type << 8);
|
|
|
|
|
}
|
2015-07-23 14:56:03 -07:00
|
|
|
|
2014-06-25 17:32:41 +01:00
|
|
|
unsigned int
|
|
|
|
|
mraa_adc_raw_bits()
|
|
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat == NULL)
|
2014-06-25 17:32:41 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat->aio_count == 0)
|
2014-06-25 17:32:41 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
return plat->adc_raw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
|
mraa_get_platform_adc_raw_bits(uint8_t platform_offset)
|
|
|
|
|
{
|
|
|
|
|
if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET)
|
|
|
|
|
return mraa_adc_raw_bits();
|
|
|
|
|
else {
|
|
|
|
|
if (!mraa_has_sub_platform())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (plat->sub_platform->aio_count == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return plat->sub_platform->adc_raw;
|
|
|
|
|
}
|
2014-06-25 17:32:41 +01:00
|
|
|
}
|
|
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
|
2014-06-25 17:32:41 +01:00
|
|
|
unsigned int
|
|
|
|
|
mraa_adc_supported_bits()
|
|
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat == NULL)
|
2014-06-25 17:32:41 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat->aio_count == 0)
|
2014-06-25 17:32:41 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
return plat->adc_supported;
|
2014-06-25 17:32:41 +01:00
|
|
|
}
|
2014-07-10 00:55:50 +01:00
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
unsigned int
|
|
|
|
|
mraa_get_platform_adc_supported_bits(int platform_offset)
|
|
|
|
|
{
|
|
|
|
|
if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET)
|
|
|
|
|
return mraa_adc_supported_bits();
|
|
|
|
|
else {
|
|
|
|
|
if (!mraa_has_sub_platform())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (plat->sub_platform->aio_count == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return plat->sub_platform->adc_supported;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-20 15:58:28 +00:00
|
|
|
const char*
|
2014-11-26 15:15:55 +00:00
|
|
|
mraa_get_platform_name()
|
|
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
return platform_name;
|
2014-11-26 15:15:55 +00:00
|
|
|
}
|
2015-01-21 15:11:03 +00:00
|
|
|
|
2016-01-20 15:58:06 +00:00
|
|
|
const char*
|
|
|
|
|
mraa_get_platform_version(int platform_offset)
|
|
|
|
|
{
|
|
|
|
|
if (plat == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) {
|
|
|
|
|
return plat->platform_version;
|
|
|
|
|
} else {
|
|
|
|
|
return plat->sub_platform->platform_version;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-25 15:04:38 +08:00
|
|
|
int
|
|
|
|
|
mraa_get_i2c_bus_count()
|
|
|
|
|
{
|
|
|
|
|
if (plat == NULL) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return plat->i2c_bus_count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
mraa_get_i2c_bus_id(unsigned i2c_bus)
|
|
|
|
|
{
|
|
|
|
|
if (plat == NULL) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i2c_bus >= plat->i2c_bus_count) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plat->i2c_bus[i2c_bus].bus_id;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-21 15:11:03 +00:00
|
|
|
unsigned int
|
|
|
|
|
mraa_get_pin_count()
|
|
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat == NULL) {
|
2015-01-21 15:11:03 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
2015-08-20 12:08:57 -07:00
|
|
|
return plat->phy_pin_count;
|
2015-01-21 15:11:03 +00:00
|
|
|
}
|
2015-02-15 12:47:11 +01:00
|
|
|
|
2015-08-20 12:08:57 -07:00
|
|
|
unsigned int
|
|
|
|
|
mraa_get_platform_pin_count(uint8_t platform_offset)
|
|
|
|
|
{
|
|
|
|
|
if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET)
|
|
|
|
|
return mraa_get_pin_count();
|
|
|
|
|
else {
|
|
|
|
|
if (mraa_has_sub_platform())
|
|
|
|
|
return plat->sub_platform->phy_pin_count;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2015-04-04 18:52:35 +01:00
|
|
|
char*
|
|
|
|
|
mraa_get_pin_name(int pin)
|
|
|
|
|
{
|
2015-08-20 12:08:57 -07:00
|
|
|
if (plat == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
mraa_board_t* current_plat = plat;
|
|
|
|
|
if (mraa_is_sub_platform_id(pin)) {
|
|
|
|
|
current_plat = plat->sub_platform;
|
|
|
|
|
if (current_plat == NULL) {
|
|
|
|
|
syslog(LOG_ERR, "mraa_get_pin_name: Sub platform Not Initialised");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
pin = mraa_get_sub_platform_index(pin);
|
2015-04-04 18:52:35 +01:00
|
|
|
}
|
2015-08-20 12:08:57 -07:00
|
|
|
|
2015-07-27 09:32:39 -07:00
|
|
|
if (pin > (current_plat->phy_pin_count - 1) || pin < 0)
|
2015-04-04 18:52:35 +01:00
|
|
|
return NULL;
|
2015-07-27 09:32:39 -07:00
|
|
|
return (char*) current_plat->pins[pin].name;
|
2015-04-04 18:52:35 +01:00
|
|
|
}
|
|
|
|
|
|
2015-05-27 15:36:46 -07:00
|
|
|
int
|
2015-08-20 12:08:57 -07:00
|
|
|
mraa_get_default_i2c_bus(uint8_t platform_offset)
|
2015-05-27 15:36:46 -07:00
|
|
|
{
|
2015-09-03 15:28:36 +01:00
|
|
|
if (plat == NULL)
|
2015-05-27 15:36:46 -07:00
|
|
|
return -1;
|
2015-08-20 12:08:57 -07:00
|
|
|
if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) {
|
|
|
|
|
return plat->def_i2c_bus;
|
|
|
|
|
} else {
|
|
|
|
|
if (mraa_has_sub_platform())
|
|
|
|
|
return plat->sub_platform->def_i2c_bus;
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2015-05-27 15:36:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2015-02-15 12:47:11 +01:00
|
|
|
mraa_boolean_t
|
2015-04-04 18:41:13 +01:00
|
|
|
mraa_file_exist(const char* filename)
|
2015-03-23 14:39:12 +00:00
|
|
|
{
|
2015-02-15 12:47:11 +01:00
|
|
|
glob_t results;
|
|
|
|
|
results.gl_pathc = 0;
|
|
|
|
|
glob(filename, 0, NULL, &results);
|
|
|
|
|
int file_found = results.gl_pathc == 1;
|
|
|
|
|
globfree(&results);
|
|
|
|
|
return file_found;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 18:52:35 +01:00
|
|
|
mraa_boolean_t
|
|
|
|
|
mraa_file_contains(const char* filename, const char* content)
|
2015-03-18 20:48:14 +01:00
|
|
|
{
|
2015-04-04 18:52:35 +01:00
|
|
|
mraa_boolean_t found = 0;
|
|
|
|
|
if ((filename == NULL) || (content == NULL)) {
|
|
|
|
|
return 0;
|
2015-03-18 20:48:14 +01:00
|
|
|
}
|
2015-04-04 18:52:35 +01:00
|
|
|
|
|
|
|
|
char* file = mraa_file_unglob(filename);
|
|
|
|
|
if (file != NULL) {
|
|
|
|
|
size_t len = 1024;
|
mraa: Prefer calloc over malloc
Switch to using calloc on all calls to malloc where the memory isn't
initialized. For things like the mraa_board_t, not allocating all to zero
causes issues such as with the sub_platform member, where if that's not zero
mraa_get_platform_type will try to dereference a random memory location for the
sub_platform->platform_name, which can result in segmentation faults and other
issues.
Note that in some places where immediately after the malloc call is a copy
operation, there is no need for calloc, as all the memory gets overwritten
anyways, but in cases where there may or may not be memory written to (such as
in mraa_file_contains, with reading from a file), even though in most cases the
memory is overwritten, it could be the case that the read operation does
nothing, but the memory still has non-zero values, by virtue of the fact it
wasn't overwritten.
Signed-off-by: Ian Johnson <ijohnson@wolfram.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
2016-01-17 09:39:45 -06:00
|
|
|
char* line = calloc(len, sizeof(char));
|
2015-08-14 15:36:50 +01:00
|
|
|
if (line == NULL) {
|
2015-08-20 19:09:42 +01:00
|
|
|
free(file);
|
2015-08-14 15:36:50 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
2015-04-04 18:52:35 +01:00
|
|
|
FILE* fh = fopen(file, "r");
|
2015-08-13 15:25:59 +01:00
|
|
|
if (fh == NULL) {
|
2015-08-20 19:09:42 +01:00
|
|
|
free(file);
|
2015-08-14 15:36:50 +01:00
|
|
|
free(line);
|
2015-08-13 15:25:59 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
2015-04-04 18:52:35 +01:00
|
|
|
while ((getline(&line, &len, fh) != -1) && (found == 0)) {
|
|
|
|
|
if (strstr(line, content)) {
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(fh);
|
|
|
|
|
free(file);
|
|
|
|
|
free(line);
|
|
|
|
|
}
|
|
|
|
|
return found;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mraa_boolean_t
|
|
|
|
|
mraa_file_contains_both(const char* filename, const char* content, const char* content2)
|
|
|
|
|
{
|
|
|
|
|
mraa_boolean_t found = 0;
|
|
|
|
|
if ((filename == NULL) || (content == NULL)) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* file = mraa_file_unglob(filename);
|
|
|
|
|
if (file != NULL) {
|
|
|
|
|
size_t len = 1024;
|
mraa: Prefer calloc over malloc
Switch to using calloc on all calls to malloc where the memory isn't
initialized. For things like the mraa_board_t, not allocating all to zero
causes issues such as with the sub_platform member, where if that's not zero
mraa_get_platform_type will try to dereference a random memory location for the
sub_platform->platform_name, which can result in segmentation faults and other
issues.
Note that in some places where immediately after the malloc call is a copy
operation, there is no need for calloc, as all the memory gets overwritten
anyways, but in cases where there may or may not be memory written to (such as
in mraa_file_contains, with reading from a file), even though in most cases the
memory is overwritten, it could be the case that the read operation does
nothing, but the memory still has non-zero values, by virtue of the fact it
wasn't overwritten.
Signed-off-by: Ian Johnson <ijohnson@wolfram.com>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
2016-01-17 09:39:45 -06:00
|
|
|
char* line = calloc(len, sizeof(char));
|
2015-08-14 15:36:50 +01:00
|
|
|
if (line == NULL) {
|
2015-08-20 19:09:42 +01:00
|
|
|
free(file);
|
2015-08-14 15:36:50 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
2015-04-04 18:52:35 +01:00
|
|
|
FILE* fh = fopen(file, "r");
|
2015-08-13 15:25:59 +01:00
|
|
|
if (fh == NULL) {
|
2015-08-20 19:09:42 +01:00
|
|
|
free(file);
|
2015-08-14 15:36:50 +01:00
|
|
|
free(line);
|
2015-08-13 15:25:59 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
2015-04-04 18:52:35 +01:00
|
|
|
while ((getline(&line, &len, fh) != -1) && (found == 0)) {
|
|
|
|
|
if (strstr(line, content) && strstr(line, content2)) {
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(fh);
|
|
|
|
|
free(file);
|
|
|
|
|
free(line);
|
|
|
|
|
}
|
|
|
|
|
return found;
|
2015-03-18 20:48:14 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 12:47:11 +01:00
|
|
|
char*
|
2015-04-04 18:41:13 +01:00
|
|
|
mraa_file_unglob(const char* filename)
|
2015-03-23 14:39:12 +00:00
|
|
|
{
|
2015-02-15 12:47:11 +01:00
|
|
|
glob_t results;
|
2015-03-23 14:39:12 +00:00
|
|
|
char* res = NULL;
|
2015-02-15 12:47:11 +01:00
|
|
|
results.gl_pathc = 0;
|
|
|
|
|
glob(filename, 0, NULL, &results);
|
|
|
|
|
if (results.gl_pathc == 1)
|
|
|
|
|
res = strdup(results.gl_pathv[0]);
|
|
|
|
|
globfree(&results);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mraa_boolean_t
|
2015-04-04 18:41:13 +01:00
|
|
|
mraa_link_targets(const char* filename, const char* targetname)
|
2015-03-23 14:39:12 +00:00
|
|
|
{
|
2015-02-15 12:47:11 +01:00
|
|
|
int size = 100;
|
|
|
|
|
int nchars = 0;
|
2015-03-23 14:39:12 +00:00
|
|
|
char* buffer = NULL;
|
|
|
|
|
while (nchars == 0) {
|
|
|
|
|
buffer = (char*) realloc(buffer, size);
|
2015-02-15 12:47:11 +01:00
|
|
|
if (buffer == NULL)
|
|
|
|
|
return 0;
|
2015-03-23 14:39:12 +00:00
|
|
|
nchars = readlink(filename, buffer, size);
|
|
|
|
|
if (nchars < 0) {
|
2015-02-15 12:47:11 +01:00
|
|
|
free(buffer);
|
|
|
|
|
return 0;
|
2015-07-01 10:52:31 +01:00
|
|
|
} else {
|
|
|
|
|
buffer[nchars] = '\0';
|
2015-02-15 12:47:11 +01:00
|
|
|
}
|
|
|
|
|
if (nchars >= size) {
|
2015-03-23 14:39:12 +00:00
|
|
|
size *= 2;
|
|
|
|
|
nchars = 0;
|
2015-02-15 12:47:11 +01:00
|
|
|
}
|
|
|
|
|
}
|
2015-03-23 14:39:12 +00:00
|
|
|
if (strstr(buffer, targetname)) {
|
2015-02-15 12:47:11 +01:00
|
|
|
free(buffer);
|
|
|
|
|
return 1;
|
2015-03-23 14:39:12 +00:00
|
|
|
} else {
|
2015-02-15 12:47:11 +01:00
|
|
|
free(buffer);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-10 17:52:50 +01:00
|
|
|
|
|
|
|
|
static int
|
2015-09-28 16:26:53 +01:00
|
|
|
mraa_count_i2c_files(const char* path, const struct stat* sb, int flag, struct FTW* ftwb)
|
2015-07-10 17:52:50 +01:00
|
|
|
{
|
|
|
|
|
switch (sb->st_mode & S_IFMT) {
|
|
|
|
|
case S_IFLNK:
|
|
|
|
|
num_i2c_devices++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
mraa_find_i2c_bus(const char* devname, int startfrom)
|
|
|
|
|
{
|
2015-07-15 13:50:28 +01:00
|
|
|
char path[64];
|
2015-07-10 17:52:50 +01:00
|
|
|
int fd;
|
|
|
|
|
int i = startfrom;
|
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
|
|
// because feeding mraa_find_i2c_bus result back into the function is
|
|
|
|
|
// useful treat -1 as 0
|
|
|
|
|
if (startfrom < 0) {
|
|
|
|
|
startfrom = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find how many i2c buses we have if we haven't already
|
|
|
|
|
if (num_i2c_devices == 0) {
|
2015-09-28 16:26:53 +01:00
|
|
|
if (nftw("/sys/class/i2c-dev/", &mraa_count_i2c_files, 20, FTW_PHYS) == -1) {
|
2015-07-10 17:52:50 +01:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// i2c devices are numbered numerically so 0 must exist otherwise there is
|
|
|
|
|
// no i2c-dev loaded
|
|
|
|
|
if (mraa_file_exist("/sys/class/i2c-dev/i2c-0")) {
|
|
|
|
|
for (i; i < num_i2c_devices; i++) {
|
|
|
|
|
off_t size, err;
|
|
|
|
|
snprintf(path, 64, "/sys/class/i2c-dev/i2c-%u/name", i);
|
|
|
|
|
fd = open(path, O_RDONLY);
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
size = lseek(fd, 0, SEEK_END);
|
|
|
|
|
if (size < 0) {
|
|
|
|
|
syslog(LOG_WARNING, "mraa: failed to seek i2c filename file");
|
|
|
|
|
close(fd);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
err = lseek(fd, 0, SEEK_SET);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
syslog(LOG_WARNING, "mraa: failed to seek i2c filename file");
|
|
|
|
|
close(fd);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-07-15 13:50:28 +01:00
|
|
|
char* value = malloc(size);
|
|
|
|
|
if (value == NULL) {
|
|
|
|
|
syslog(LOG_ERR, "mraa: failed to allocate memory for i2c file");
|
|
|
|
|
close(fd);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-07-10 17:52:50 +01:00
|
|
|
ssize_t r = read(fd, value, size);
|
|
|
|
|
if (r > 0) {
|
|
|
|
|
if (strcasestr(value, devname) != NULL) {
|
2015-07-15 13:50:28 +01:00
|
|
|
free(value);
|
2015-07-10 17:52:50 +01:00
|
|
|
close(fd);
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
syslog(LOG_ERR, "mraa: sysfs i2cdev failed");
|
|
|
|
|
}
|
2015-07-15 13:50:28 +01:00
|
|
|
free(value);
|
2015-07-10 17:52:50 +01:00
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
syslog(LOG_WARNING, "mraa: no i2c-dev detected, load i2c-dev");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2015-06-26 14:22:09 -07:00
|
|
|
|
|
|
|
|
mraa_boolean_t
|
2015-08-10 17:16:00 -07:00
|
|
|
mraa_is_sub_platform_id(int pin_or_bus)
|
2015-06-26 14:22:09 -07:00
|
|
|
{
|
2015-07-01 10:24:39 -07:00
|
|
|
return (pin_or_bus & MRAA_SUB_PLATFORM_MASK) != 0;
|
2015-06-26 14:22:09 -07:00
|
|
|
}
|
|
|
|
|
|
2015-09-03 15:28:36 +01:00
|
|
|
int
|
2015-08-10 17:16:00 -07:00
|
|
|
mraa_get_sub_platform_id(int pin_or_bus)
|
2015-06-26 14:22:09 -07:00
|
|
|
{
|
|
|
|
|
return pin_or_bus | MRAA_SUB_PLATFORM_MASK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-03 15:28:36 +01:00
|
|
|
int
|
2015-06-26 14:22:09 -07:00
|
|
|
mraa_get_sub_platform_index(int pin_or_bus)
|
|
|
|
|
{
|
|
|
|
|
return pin_or_bus & (~MRAA_SUB_PLATFORM_MASK);
|
|
|
|
|
}
|
2015-09-28 16:26:53 +01:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
mraa_get_iio_device_count()
|
|
|
|
|
{
|
2015-10-06 11:51:56 +01:00
|
|
|
return plat_iio->iio_device_count;
|
2015-09-28 16:26:53 +01:00
|
|
|
}
|
2016-03-07 14:49:42 +00:00
|
|
|
|
|
|
|
|
mraa_result_t
|
|
|
|
|
mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev)
|
|
|
|
|
{
|
|
|
|
|
#ifdef FIRMATA
|
|
|
|
|
if (subplatformtype == MRAA_GENERIC_FIRMATA) {
|
|
|
|
|
if (mraa_firmata_platform(plat, uart_dev) == MRAA_GENERIC_FIRMATA) {
|
|
|
|
|
syslog(LOG_NOTICE, "mraa: Added firmata subplatform");
|
|
|
|
|
return MRAA_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return MRAA_ERROR_INVALID_PARAMETER;
|
|
|
|
|
}
|