mraa.c: Added init platform from json file
Signed-off-by: Houman Brinjcargorabi <houman.brinjcargorabi@intel.com> Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
committed by
Brendan Le Foll
parent
346f447c4d
commit
8ba8ce3b26
@@ -44,6 +44,7 @@
|
||||
if (res != MRAA_SUCCESS) \
|
||||
return res;} while(0)
|
||||
|
||||
|
||||
/** @file
|
||||
*
|
||||
* This file defines the basic shared values for libmraa
|
||||
@@ -306,6 +307,16 @@ mraa_result_t mraa_remove_subplatform(mraa_platform_t subplatformtype);
|
||||
*/
|
||||
void* mraa_init_io(const char* desc);
|
||||
|
||||
/**
|
||||
* Instantiate an unknown board using a json file
|
||||
*
|
||||
* @param Path to the json file, relative to the folder the program
|
||||
* was initially run in or a direct path
|
||||
*
|
||||
* @return mraa_result indicating success
|
||||
*/
|
||||
mraa_result_t mraa_init_json_platform(const char* path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -327,4 +327,18 @@ initIo(std::string desc)
|
||||
return new T(mraa_init_io(desc.c_str()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an unknown board using a json file
|
||||
*
|
||||
* @param Path to the json file, relative to the folder the program
|
||||
* was initially run in or a direct path
|
||||
*
|
||||
* @return Result indicating success
|
||||
*/
|
||||
inline Result
|
||||
initJsonPlatform(std::string path)
|
||||
{
|
||||
return (Result) mraa_init_json_platform(path.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ extern "C" {
|
||||
#include "mraa_lang_func.h"
|
||||
|
||||
extern mraa_board_t* plat;
|
||||
extern char* platform_name;
|
||||
extern mraa_iio_info_t* plat_iio;
|
||||
extern mraa_lang_func_t* lang_func;
|
||||
|
||||
|
||||
@@ -40,6 +40,46 @@
|
||||
#define MRAA_IO_SETUP_FAILURE -2
|
||||
#define MRAA_NO_SUCH_IO -1
|
||||
|
||||
// Json platform keys
|
||||
#define INDEX_KEY "index"
|
||||
#define NAME_KEY "name"
|
||||
#define PIN_COUNT_KEY "pin_count"
|
||||
#define GPIO_COUNT_KEY "gpio_count"
|
||||
#define AIO_COUNT_KEY "aio_count"
|
||||
#define SPI_COUNT_KEY "spi_count"
|
||||
#define I2C_COUNT_KEY "i2c_count"
|
||||
#define UART_COUNT_KEY "uart_count"
|
||||
#define PWMDEFAULT_KEY "pwmDefPeriod"
|
||||
#define PWMMAX_KEY "pwmMaxPeriod"
|
||||
#define PWMMIN_KEY "pwmMinPeriod"
|
||||
#define LABEL_KEY "label"
|
||||
#define DEFAULT_KEY "default"
|
||||
#define INVALID_KEY "invalid"
|
||||
#define SCLPIN_KEY "sclpin"
|
||||
#define SDAPIN_KEY "sdapin"
|
||||
#define CHIP_ID_KEY "chipID"
|
||||
#define RAW_PIN_KEY "rawpin"
|
||||
#define RXPIN_KEY "rx"
|
||||
#define TXPIN_KEY "tx"
|
||||
#define UART_PATH_KEY "path"
|
||||
#define CLOCK_KEY "clock"
|
||||
#define MISO_KEY "miso"
|
||||
#define MOSI_KEY "mosi"
|
||||
#define CS_KEY "chipselect"
|
||||
#define PIN_KEY "pin"
|
||||
#define IO_KEY "layout"
|
||||
#define PLATFORM_KEY "platform"
|
||||
|
||||
// IO keys
|
||||
#define GPIO_KEY "GPIO"
|
||||
#define SPI_KEY "SPI"
|
||||
#define UART_KEY "UART"
|
||||
#define I2C_KEY "I2C"
|
||||
#define PWM_KEY "PWM"
|
||||
#define AIO_KEY "AIO"
|
||||
|
||||
#define MRAA_JSONPLAT_ENV_VAR "MRAA_JSON_PLATFORM"
|
||||
|
||||
#ifdef FIRMATA
|
||||
struct _firmata {
|
||||
/*@*/
|
||||
|
||||
716
src/json/jsonplatform.c
Normal file
716
src/json/jsonplatform.c
Normal file
@@ -0,0 +1,716 @@
|
||||
/*
|
||||
* Author: Houman Brinjcargorabi <Houman.Brinjcargorabi@intel.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include <json-c/json.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "mraa_internal.h"
|
||||
|
||||
typedef mraa_result_t (*init_plat_func_t)(json_object*, mraa_board_t*, int);
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_get_pin(json_object* jobj, const char* io, const char* key, int index, int* pin)
|
||||
{
|
||||
json_object* jobj_temp = NULL;
|
||||
if (json_object_object_get_ex(jobj, key, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_int)) {
|
||||
syslog(LOG_ERR, "init_json_platform: %s %s at position: %d is not an int", io, key, index);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
*pin = (unsigned int) json_object_get_int(jobj_temp);
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
syslog(LOG_ERR, "init_json_platform: No %s specified for %s at position: %d", key, io, index);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_get_index(json_object* jobj, const char* io, const char* key, int index, int* pos, int upper)
|
||||
{
|
||||
json_object* jobj_temp = NULL;
|
||||
if (json_object_object_get_ex(jobj, key, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_int)) {
|
||||
syslog(LOG_ERR, "init_json_platform: %s index at position: %d not an int", io, index);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
|
||||
*pos = (int) json_object_get_int(jobj_temp);
|
||||
if (*pos < 0 || *pos > upper) {
|
||||
syslog(LOG_ERR,
|
||||
"init_json_platform: %s %s at position: %d, gave: %d which was out of range", io,
|
||||
key, index, *pos);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
syslog(LOG_ERR, "init_json_platform: An %s was not found for the %s", key, io);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_platform(json_object* jobj_platform, mraa_board_t* board, int index)
|
||||
{
|
||||
json_object* jobj_temp = NULL;
|
||||
const char* temp_string = NULL;
|
||||
int temp_count = 0;
|
||||
int length = 0;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
|
||||
// Set the platform name
|
||||
if (json_object_object_get_ex(jobj_platform, NAME_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_string)) {
|
||||
syslog(LOG_ERR, "init_json_platform: Platform name not a string");
|
||||
return MRAA_ERROR_NO_RESOURCES;
|
||||
}
|
||||
temp_string = json_object_get_string(jobj_temp);
|
||||
if (temp_string == NULL || (length = strlen(temp_string)) == 0) {
|
||||
syslog(LOG_ERR, "init_json_platform: Empty string provided for \"%s\" key in platform", NAME_KEY);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
board->platform_name = (char*) calloc(length, sizeof(char));
|
||||
strncpy(board->platform_name, temp_string, length);
|
||||
} else {
|
||||
syslog(LOG_ERR, "init_json_platform: No \"%s\" key in platform", NAME_KEY);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
|
||||
// Get the physical pincount
|
||||
ret = mraa_init_json_platform_get_pin(jobj_platform, PLATFORM_KEY, PIN_COUNT_KEY, index,
|
||||
&(board->phy_pin_count));
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup the pins
|
||||
board->pins = (mraa_pininfo_t*) calloc(board->phy_pin_count, sizeof(mraa_pininfo_t));
|
||||
if (board->pins == NULL) {
|
||||
syslog(LOG_ERR, "init_json_platform: Unable to allocate space for the pins");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
|
||||
// set the inital counts to -1 so we know if they don't exist
|
||||
board->gpio_count = -1;
|
||||
board->aio_count = -1;
|
||||
board->uart_dev_count = -1;
|
||||
board->i2c_bus_count = -1;
|
||||
board->spi_bus_count = -1;
|
||||
|
||||
// Check to see if they've provided a GPIO count
|
||||
ret = mraa_init_json_platform_get_index(jobj_platform, PLATFORM_KEY, GPIO_COUNT_KEY, index,
|
||||
&(board->gpio_count), board->phy_pin_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check to see if they've provided a AIO count
|
||||
ret = mraa_init_json_platform_get_index(jobj_platform, PLATFORM_KEY, AIO_COUNT_KEY, index,
|
||||
&(board->aio_count), board->phy_pin_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check to see if they've provided a UART count
|
||||
ret = mraa_init_json_platform_get_index(jobj_platform, PLATFORM_KEY, UART_COUNT_KEY, index,
|
||||
&(board->uart_dev_count), 6);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
// Check to see if they've provided a I2C count
|
||||
ret = mraa_init_json_platform_get_index(jobj_platform, PLATFORM_KEY, I2C_COUNT_KEY, index,
|
||||
&(board->i2c_bus_count), 12);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
// Check to see if they've provided a SPI count
|
||||
ret = mraa_init_json_platform_get_index(jobj_platform, PLATFORM_KEY, SPI_COUNT_KEY, index,
|
||||
&(board->spi_bus_count), 12);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set the PWM default numbers
|
||||
board->pwm_default_period = -1;
|
||||
board->pwm_max_period = -1;
|
||||
board->pwm_min_period = -1;
|
||||
|
||||
// Setup the PWM rates if they exist
|
||||
ret = mraa_init_json_platform_get_pin(jobj_platform, PLATFORM_KEY, PWMDEFAULT_KEY, index,
|
||||
&(board->pwm_default_period));
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
ret = mraa_init_json_platform_get_pin(jobj_platform, PLATFORM_KEY, PWMMAX_KEY, index,
|
||||
&(board->pwm_max_period));
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
ret = mraa_init_json_platform_get_pin(jobj_platform, PLATFORM_KEY, PWMMIN_KEY, index,
|
||||
&(board->pwm_min_period));
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// A hacky logical xor to ensure the value's have all been set or none should have been set
|
||||
// Here we infer that IF A != B and B != C then A == C since they're working on binary values
|
||||
if (((board->pwm_default_period == -1) != (board->pwm_max_period == -1)) ||
|
||||
((board->pwm_min_period == -1) != (board->pwm_max_period == -1))) {
|
||||
syslog(LOG_ERR, "init_json_platform: One of more PWM settings missing in the platform"
|
||||
"configuration");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
// Set our platform type
|
||||
board->platform_type = MRAA_JSON_PLATFORM;
|
||||
board->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_io(json_object* jobj_io, mraa_board_t* board, int index)
|
||||
{
|
||||
const char* temp_string = NULL;
|
||||
json_object* jobj_temp = NULL;
|
||||
int pos = 0;
|
||||
int invalid = 0;
|
||||
pos = index;
|
||||
|
||||
// set the label for the IO
|
||||
if (json_object_object_get_ex(jobj_io, LABEL_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_string)) {
|
||||
syslog(LOG_ERR, "init_json_platform: IO label at position: %d not a string", index);
|
||||
return MRAA_ERROR_NO_RESOURCES;
|
||||
}
|
||||
temp_string = json_object_get_string(jobj_temp);
|
||||
// set the gpio label
|
||||
strncpy(board->pins[pos].name, temp_string, 8);
|
||||
} else {
|
||||
syslog(LOG_ERR, "init_json_platform: No IO Label");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
if (json_object_object_get_ex(jobj_io, INVALID_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_boolean)) {
|
||||
syslog(LOG_ERR, "init_json_platform: Default I2C device key has an incorrect value");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
invalid = json_object_get_boolean(jobj_temp);
|
||||
}
|
||||
if (invalid) {
|
||||
board->pins[pos].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
} else {
|
||||
board->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_gpio(json_object* jobj_gpio, mraa_board_t* board, int index)
|
||||
{
|
||||
int pos = 0;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
|
||||
// Get the gpio index
|
||||
ret = mraa_init_json_platform_get_index(jobj_gpio, GPIO_KEY, INDEX_KEY, index, &pos,
|
||||
board->phy_pin_count - 1);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
// Get the gpio sysfs pin;
|
||||
ret = mraa_init_json_platform_get_pin(jobj_gpio, GPIO_KEY, RAW_PIN_KEY, index,
|
||||
&(board->pins[pos].gpio.pinmap));
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
board->pins[pos].capabilites.gpio = 1;
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_aio(json_object* jobj_aio, mraa_board_t* board, int index)
|
||||
{
|
||||
int pos = 0;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
|
||||
// Get the gpio index
|
||||
ret = mraa_init_json_platform_get_index(jobj_aio, AIO_KEY, INDEX_KEY, index, &pos, board->phy_pin_count - 1);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the gpio sysfs pin;
|
||||
ret = mraa_init_json_platform_get_pin(jobj_aio, AIO_KEY, RAW_PIN_KEY, index,
|
||||
&(board->pins[pos].aio.pinmap));
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
board->pins[pos].capabilites.aio = 1;
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_i2c(json_object* jobj_i2c, mraa_board_t* board, int index)
|
||||
{
|
||||
int pos = 0;
|
||||
int pin = 0;
|
||||
int sysfs_pin = 0;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
json_object* jobj_temp = NULL;
|
||||
|
||||
// Get the I2C bus array index
|
||||
ret = mraa_init_json_platform_get_index(jobj_i2c, I2C_KEY, INDEX_KEY, index, &pos, board->i2c_bus_count - 1);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
// Get the sysfs pin
|
||||
ret = mraa_init_json_platform_get_pin(jobj_i2c, I2C_KEY, RAW_PIN_KEY, index, &sysfs_pin);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
// Setup the sda pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_i2c, I2C_KEY, SDAPIN_KEY, index, &pin,
|
||||
board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->i2c_bus[pos].sda = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.i2c = 1;
|
||||
board->pins[pin].i2c.pinmap = sysfs_pin;
|
||||
board->i2c_bus[pos].sda = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
// Setup the scl pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_i2c, I2C_KEY, SCLPIN_KEY, index, &pin,
|
||||
board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->i2c_bus[pos].scl = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.i2c = 1;
|
||||
board->pins[pin].i2c.pinmap = sysfs_pin;
|
||||
board->i2c_bus[pos].scl = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
||||
board->i2c_bus[pos].bus_id = pos;
|
||||
|
||||
// check to see if this i2c is the default one
|
||||
if (json_object_object_get_ex(jobj_i2c, DEFAULT_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_boolean)) {
|
||||
syslog(LOG_ERR, "init_json_platform: Default I2C device key has an incorrect value");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
if (json_object_get_boolean(jobj_temp)) {
|
||||
board->def_i2c_bus = pos;
|
||||
}
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_pwm(json_object* jobj_pwm, mraa_board_t* board, int index)
|
||||
{
|
||||
int pos = 0;
|
||||
int parent_id = 0;
|
||||
int sysfs_pin = 0;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
|
||||
// Get the index into the physical pin array
|
||||
ret = mraa_init_json_platform_get_index(jobj_pwm, PWM_KEY, INDEX_KEY, index, &pos, board->phy_pin_count - 1);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
// Get the parent id
|
||||
ret = mraa_init_json_platform_get_pin(jobj_pwm, PWM_KEY, CHIP_ID_KEY, index, &parent_id);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
// Get the sysfs pin
|
||||
ret = mraa_init_json_platform_get_pin(jobj_pwm, PWM_KEY, RAW_PIN_KEY, index, &sysfs_pin);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
board->pins[pos].capabilites.pwm = 1;
|
||||
board->pins[pos].pwm.pinmap = sysfs_pin;
|
||||
board->pins[pos].pwm.parent_id = parent_id;
|
||||
return ret;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_spi(json_object* jobj_spi, mraa_board_t* board, int index)
|
||||
{
|
||||
int pos = 0;
|
||||
int pin = 0;
|
||||
int parent_id = 0;
|
||||
json_object* jobj_temp = NULL;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
|
||||
// Get the index into the physical pin array
|
||||
ret = mraa_init_json_platform_get_index(jobj_spi, SPI_KEY, INDEX_KEY, index, &pos, board->spi_bus_count - 1);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the parent id
|
||||
ret = mraa_init_json_platform_get_pin(jobj_spi, SPI_KEY, CHIP_ID_KEY, index, &parent_id);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup the clock pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_spi, SPI_KEY, CLOCK_KEY, index, &pin, board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->spi_bus[pos].sclk = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.spi = 1;
|
||||
board->pins[pin].spi.parent_id = parent_id;
|
||||
board->spi_bus[pos].sclk = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
// Setup the MISO pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_spi, SPI_KEY, MISO_KEY, index, &pin, board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->spi_bus[pos].miso = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.spi = 1;
|
||||
board->pins[pin].spi.parent_id = parent_id;
|
||||
board->spi_bus[pos].miso = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
// Setup the MOSI pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_spi, SPI_KEY, MOSI_KEY, index, &pin, board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->spi_bus[pos].mosi = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.spi = 1;
|
||||
board->pins[pin].spi.parent_id = parent_id;
|
||||
board->spi_bus[pos].mosi = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
// Setup the CS pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_spi, SPI_KEY, CS_KEY, index, &pin, board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->spi_bus[pos].cs = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.spi = 1;
|
||||
board->pins[pin].spi.parent_id = parent_id;
|
||||
board->spi_bus[pos].cs = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
// check to see if this SPI is the default one
|
||||
if (json_object_object_get_ex(jobj_spi, DEFAULT_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_boolean)) {
|
||||
syslog(LOG_ERR, "init_json_platform: Default I2C device key has an incorrect value");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
if (json_object_get_boolean(jobj_temp)) {
|
||||
board->def_spi_bus = pos;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_uart(json_object* jobj_uart, mraa_board_t* board, int index)
|
||||
{
|
||||
json_object* jobj_temp = NULL;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
int pos = 0;
|
||||
int pin = 0;
|
||||
int sysfs_pin = 0;
|
||||
int parent_id = 0;
|
||||
int length = 0;
|
||||
const char* temp_string = NULL;
|
||||
|
||||
// Get the index into the uart bus
|
||||
ret = mraa_init_json_platform_get_index(jobj_uart, UART_KEY, INDEX_KEY, index, &pos,
|
||||
board->uart_dev_count - 1);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the parent id
|
||||
ret = mraa_init_json_platform_get_pin(jobj_uart, UART_KEY, CHIP_ID_KEY, index, &parent_id);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
// Get the sysfs pin
|
||||
ret = mraa_init_json_platform_get_pin(jobj_uart, UART_KEY, RAW_PIN_KEY, index, &sysfs_pin);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup the rx pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_uart, UART_KEY, RXPIN_KEY, index, &pin,
|
||||
board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->uart_dev[pos].rx = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.uart = 1;
|
||||
board->pins[pin].uart.pinmap = sysfs_pin;
|
||||
board->pins[pin].uart.parent_id = parent_id;
|
||||
board->uart_dev[pos].rx = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup the TX pin
|
||||
ret = mraa_init_json_platform_get_index(jobj_uart, UART_KEY, TXPIN_KEY, index, &pin,
|
||||
board->phy_pin_count - 1);
|
||||
if (ret == MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
board->uart_dev[pos].tx = -1;
|
||||
} else if (ret == MRAA_SUCCESS) {
|
||||
board->pins[pin].capabilites.uart = 1;
|
||||
board->pins[pin].uart.pinmap = sysfs_pin;
|
||||
board->pins[pin].uart.parent_id = parent_id;
|
||||
board->uart_dev[pos].tx = pin;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup the path
|
||||
if (json_object_object_get_ex(jobj_uart, UART_PATH_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_string)) {
|
||||
syslog(LOG_ERR, "init_json_platform: UART Path at index: %d was not a string", index);
|
||||
return MRAA_ERROR_NO_RESOURCES;
|
||||
}
|
||||
temp_string = json_object_get_string(jobj_temp);
|
||||
if (temp_string == NULL || (length = strlen(temp_string)) == 0) {
|
||||
syslog(LOG_ERR, "init_json_platform: UART Path at index: %d was empty", index);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
board->uart_dev[pos].device_path = (char*) calloc(length, sizeof(char));
|
||||
strncpy(board->uart_dev[pos].device_path, temp_string, length);
|
||||
} else {
|
||||
syslog(LOG_ERR, "init_json_platform: UART config at index: %d needs a path", index);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
|
||||
// If this element is supposed to be default set it.
|
||||
if (json_object_object_get_ex(jobj_uart, DEFAULT_KEY, &jobj_temp)) {
|
||||
if (!json_object_is_type(jobj_temp, json_type_boolean)) {
|
||||
syslog(LOG_ERR, "init_json_platform: Default UART device key has an incorrect value");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
if (json_object_get_boolean(jobj_temp)) {
|
||||
board->def_uart_dev = pos;
|
||||
}
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_loop(json_object* jobj_platform, const char* obj_key, mraa_board_t* board, init_plat_func_t func)
|
||||
{
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
int i = 0, array_length = 0;
|
||||
json_object *jobj_temp = NULL, *jobj_io = NULL;
|
||||
if (json_object_object_get_ex(jobj_platform, obj_key, &jobj_temp)) {
|
||||
array_length = json_object_array_length(jobj_temp);
|
||||
for (i = 0; i < array_length; i++) {
|
||||
// Get the json object at position i
|
||||
jobj_io = json_object_array_get_idx(jobj_temp, i);
|
||||
// Check to see it's the right type
|
||||
if (!json_object_is_type(jobj_io, json_type_object)) {
|
||||
syslog(LOG_ERR, "init_json_platform: One of more of the elements in the \"%s\" "
|
||||
"array where not JSON objects",
|
||||
obj_key);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
ret = (*func)(jobj_io, board, i);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
syslog(LOG_ERR, "init_json_platform: No \"%s\" info found in json file", obj_key);
|
||||
ret = MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform_size_check(json_object* jobj_platform,
|
||||
const char* obj_key,
|
||||
mraa_board_t* board,
|
||||
init_plat_func_t func,
|
||||
int range)
|
||||
{
|
||||
json_object* jobj_temp = NULL;
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
int array_length = 0;
|
||||
if (json_object_object_get_ex(jobj_platform, obj_key, &jobj_temp)) {
|
||||
// Make sure the value for the key is an array
|
||||
if (!json_object_is_type(jobj_temp, json_type_array)) {
|
||||
syslog(LOG_ERR, "init_json_platform: json key \"%s\" should be an array", obj_key);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
// make sure we don't have more than our range
|
||||
array_length = json_object_array_length(jobj_temp);
|
||||
if (array_length > range) {
|
||||
syslog(LOG_ERR,
|
||||
"init_json_platform: The size of the %s array given was %d, max was: %d",
|
||||
obj_key, array_length, range);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
ret = mraa_init_json_platform_loop(jobj_platform, obj_key, board, func);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
syslog(LOG_NOTICE, "init_json_platform: %s wasn't found in the json file", obj_key);
|
||||
return MRAA_ERROR_NO_DATA_AVAILABLE;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
mraa_init_json_platform(const char* platform_json)
|
||||
{
|
||||
mraa_result_t ret = MRAA_SUCCESS;
|
||||
char* buffer = NULL;
|
||||
struct stat st;
|
||||
int file_lock = 0, array_length = 0, i = 0;
|
||||
json_object *jobj_platform = NULL, *jobj_temp = NULL;
|
||||
mraa_board_t* board = NULL;
|
||||
|
||||
// Try to lock the file for use
|
||||
if ((file_lock = open(platform_json, O_RDONLY)) == -1) {
|
||||
syslog(LOG_ERR, "init_json_platform: Failed to open platform file");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
|
||||
if (fstat(file_lock, &st) != 0 || (!S_ISREG(st.st_mode))) {
|
||||
syslog(LOG_ERR, "init_json_platform: Failed to retrieve information about a file or the "
|
||||
"file specified is not actually a file");
|
||||
close(file_lock);
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
|
||||
buffer = mmap(0, st.st_size, PROT_READ, MAP_SHARED, file_lock, 0);
|
||||
close(file_lock);
|
||||
if (buffer == MAP_FAILED) {
|
||||
syslog(LOG_ERR, "init_json_platform: Failed to read platform file");
|
||||
return MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
|
||||
// Parse the json file
|
||||
jobj_platform = json_tokener_parse(buffer);
|
||||
// Allocate some memory for the board information
|
||||
board = (mraa_board_t*) calloc(1, sizeof(mraa_board_t));
|
||||
if (board == NULL) {
|
||||
munmap(buffer, st.st_size);
|
||||
return MRAA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
// Call our helper to go through and init our board for the "Platform" data
|
||||
ret = mraa_init_json_platform_loop(jobj_platform, PLATFORM_KEY, board, mraa_init_json_platform_platform);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup the IO's with their labels
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, IO_KEY, board,
|
||||
mraa_init_json_platform_io, board->phy_pin_count);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup GPIO
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, GPIO_KEY, board,
|
||||
mraa_init_json_platform_gpio, board->phy_pin_count);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup AIO
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, AIO_KEY, board,
|
||||
mraa_init_json_platform_aio, board->phy_pin_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup SPI
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, SPI_KEY, board,
|
||||
mraa_init_json_platform_spi, board->spi_bus_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup I2C
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, I2C_KEY, board,
|
||||
mraa_init_json_platform_i2c, board->i2c_bus_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup UART
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, UART_KEY, board,
|
||||
mraa_init_json_platform_uart, board->uart_dev_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
for (i = 0; i < board->uart_dev_count; i++) {
|
||||
if (board->uart_dev[i].device_path != NULL) {
|
||||
free(plat->uart_dev[i].device_path);
|
||||
}
|
||||
}
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Setup PWM
|
||||
ret = mraa_init_json_platform_size_check(jobj_platform, PWM_KEY, board,
|
||||
mraa_init_json_platform_pwm, board->phy_pin_count);
|
||||
if (ret != MRAA_SUCCESS && ret != MRAA_ERROR_NO_DATA_AVAILABLE) {
|
||||
goto unsuccessful;
|
||||
}
|
||||
|
||||
// Free the old empty platform
|
||||
free(plat);
|
||||
// Set the new one in it's place
|
||||
plat = board;
|
||||
platform_name = plat->platform_name;
|
||||
|
||||
// We made it to the end without anything going wrong, just cleanup
|
||||
ret = MRAA_SUCCESS;
|
||||
syslog(LOG_NOTICE, "init_json_platform: Platform %s initialised via json", platform_name);
|
||||
goto cleanup;
|
||||
|
||||
unsuccessful:
|
||||
free(board->platform_name);
|
||||
free(board->pins);
|
||||
free(board->adv_func);
|
||||
free(board);
|
||||
cleanup:
|
||||
json_object_put(jobj_platform);
|
||||
munmap(buffer, st.st_size);
|
||||
return ret;
|
||||
}
|
||||
63
src/mraa.c
63
src/mraa.c
@@ -40,9 +40,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#if defined(IMRAA)
|
||||
#include <json-c/json.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -59,13 +61,14 @@
|
||||
#include "spi.h"
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
#define IIO_DEVICE_WILDCARD "iio:device*"
|
||||
|
||||
|
||||
mraa_board_t* plat = NULL;
|
||||
mraa_iio_info_t* plat_iio = NULL;
|
||||
mraa_lang_func_t* lang_func = NULL;
|
||||
|
||||
static char* platform_name = NULL;
|
||||
char* platform_name = NULL;
|
||||
static char* platform_long_name = NULL;
|
||||
|
||||
static int num_i2c_devices = 0;
|
||||
@@ -99,7 +102,9 @@ imraa_init()
|
||||
if (plat != NULL) {
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
char* env_var;
|
||||
mraa_result_t ret;
|
||||
mraa_platform_t platform_type = MRAA_NULL_PLATFORM;
|
||||
uid_t proc_euid = geteuid();
|
||||
struct passwd* proc_user = getpwuid(proc_euid);
|
||||
|
||||
@@ -113,19 +118,34 @@ imraa_init()
|
||||
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);
|
||||
|
||||
mraa_platform_t platform_type;
|
||||
// Check to see if the enviroment variable has been set
|
||||
env_var = getenv(MRAA_JSONPLAT_ENV_VAR);
|
||||
if (env_var != NULL) {
|
||||
// We only care about success, the init will write to syslog if things went wrong
|
||||
switch ((ret = mraa_init_json_platform(env_var))) {
|
||||
case MRAA_SUCCESS:
|
||||
platform_type = plat->platform_type;
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_NOTICE, "libmraa was unable to initialise a platform from json");
|
||||
}
|
||||
}
|
||||
|
||||
// Not an else because if the env var didn't load what we wanted maybe we can still load something
|
||||
if (platform_type == MRAA_NULL_PLATFORM) {
|
||||
#if defined(X86PLAT)
|
||||
// Use runtime x86 platform detection
|
||||
platform_type = mraa_x86_platform();
|
||||
// Use runtime x86 platform detection
|
||||
platform_type = mraa_x86_platform();
|
||||
#elif defined(ARMPLAT)
|
||||
// Use runtime ARM platform detection
|
||||
platform_type = mraa_arm_platform();
|
||||
// Use runtime ARM platform detection
|
||||
platform_type = mraa_arm_platform();
|
||||
#elif defined(MOCKPLAT)
|
||||
// Use mock platform
|
||||
platform_type = mraa_mock_platform();
|
||||
// Use mock platform
|
||||
platform_type = mraa_mock_platform();
|
||||
#else
|
||||
#error mraa_ARCH NOTHING
|
||||
#endif
|
||||
}
|
||||
|
||||
if (plat != NULL) {
|
||||
plat->platform_type = platform_type;
|
||||
@@ -206,6 +226,7 @@ mraa_init()
|
||||
void
|
||||
mraa_deinit()
|
||||
{
|
||||
int i = 0;
|
||||
if (plat != NULL) {
|
||||
if (plat->pins != NULL) {
|
||||
free(plat->pins);
|
||||
@@ -217,6 +238,19 @@ mraa_deinit()
|
||||
}
|
||||
free(sub_plat);
|
||||
}
|
||||
#if defined(JSONPLAT)
|
||||
if (plat->platform_type == MRAA_JSON_PLATFORM) {
|
||||
// Free the platform name
|
||||
free(plat->platform_name);
|
||||
|
||||
// Free the UART device path
|
||||
for (i = 0; i < plat->uart_dev_count; i++) {
|
||||
if (plat->uart_dev[i].device_path != NULL) {
|
||||
free(plat->uart_dev[i].device_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
free(plat);
|
||||
|
||||
}
|
||||
@@ -1235,3 +1269,12 @@ mraa_init_io(const char* desc)
|
||||
syslog(LOG_ERR, "mraa_init_io: Invalid IO type given.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifndef JSONPLAT
|
||||
mraa_result_t
|
||||
mraa_init_json_platform(const char* desc)
|
||||
{
|
||||
return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user