diff --git a/include/mraa_adv_func.h b/include/mraa_adv_func.h index 968ff90..2bd0ffd 100644 --- a/include/mraa_adv_func.h +++ b/include/mraa_adv_func.h @@ -31,7 +31,6 @@ // FIXME: Nasty macro to test for presence of function in context structure function table #define IS_FUNC_DEFINED(dev, func) (dev != NULL && dev->advance_func != NULL && dev->advance_func->func != NULL) - typedef struct { mraa_result_t (*gpio_init_internal_replace) (int pin); mraa_result_t (*gpio_init_pre) (int pin); diff --git a/include/mraa_internal.h b/include/mraa_internal.h index 20149b8..93babe7 100644 --- a/include/mraa_internal.h +++ b/include/mraa_internal.h @@ -35,9 +35,6 @@ extern "C" { #include "mraa_adv_func.h" extern mraa_board_t* plat; -// TODO: Remove global advance_func and use module context instead -extern mraa_adv_func_t* advance_func; - /** * Takes in pin information and sets up the multiplexors. diff --git a/include/mraa_internal_types.h b/include/mraa_internal_types.h index 7cba010..cdb5950 100644 --- a/include/mraa_internal_types.h +++ b/include/mraa_internal_types.h @@ -50,7 +50,7 @@ struct _gpio { mraa_boolean_t owner; /**< If this context originally exported the pin */ mraa_result_t (*mmap_write) (mraa_gpio_context dev, int value); int (*mmap_read) (mraa_gpio_context dev); - mraa_adv_func_t* advance_func; /**< override function table */ + mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ }; @@ -64,7 +64,7 @@ struct _i2c { int addr; /**< the address of the i2c slave */ unsigned long funcs; /**< /dev/i2c-* device capabilities as per https://www.kernel.org/doc/Documentation/i2c/functionality */ void *handle; /**< generic handle for non-standard drivers that don't use file descriptors */ - mraa_adv_func_t* advance_func; /**< override function table */ + mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ }; @@ -78,6 +78,7 @@ struct _spi { int clock; /**< clock to run transactions at */ mraa_boolean_t lsb; /**< least significant bit mode */ unsigned int bpw; /**< Bits per word */ + mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ }; @@ -91,6 +92,7 @@ struct _pwm { int duty_fp; /**< File pointer to duty file */ int period; /**< Cache the period to speed up setting duty */ mraa_boolean_t owner; /**< Owner of pwm context*/ + mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ }; @@ -98,9 +100,12 @@ struct _pwm { * A structure representing a Analog Input Channel */ struct _aio { + /*@{*/ unsigned int channel; /**< the channel as on board and ADC module */ int adc_in_fp; /**< File Pointer to raw sysfs */ int value_bit; /**< 10 bits by default. Can be increased if board */ + mraa_adv_func_t* advance_func; /**< override function table */ + /*@}*/ }; /** @@ -111,6 +116,7 @@ struct _uart { int index; /**< the uart index, as known to the os. */ const char* path; /**< the uart device path. */ int fd; /**< file descriptor for device. */ + mraa_adv_func_t* advance_func; /**< override function table */ /*@}*/ }; diff --git a/src/aio/aio.c b/src/aio/aio.c index 3fe413b..4984a32 100644 --- a/src/aio/aio.c +++ b/src/aio/aio.c @@ -1,6 +1,7 @@ /* * Author: Nandkishor Sonar - * Copyright (c) 2014 Intel Corporation. + * Author: Brendan Le Foll + * Copyright (c) 2014, 2015 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -36,8 +37,9 @@ static int raw_bits; static mraa_result_t aio_get_valid_fp(mraa_aio_context dev) { - if (advance_func->aio_get_valid_fp != NULL) - return advance_func->aio_get_valid_fp(dev); + if (IS_FUNC_DEFINED(dev, aio_get_valid_fp)) { + return dev->advance_func->aio_get_valid_fp(dev); + } char file_path[64] = ""; @@ -53,6 +55,16 @@ aio_get_valid_fp(mraa_aio_context dev) return MRAA_SUCCESS; } +static mraa_aio_context +mraa_aio_init_internal(mraa_adv_func_t* func_table) +{ + mraa_aio_context dev = malloc(sizeof(struct _aio)); + if (dev == NULL) { + return NULL; + } + dev->advance_func = func_table; +} + mraa_aio_context mraa_aio_init(unsigned int aio) { @@ -60,8 +72,23 @@ mraa_aio_init(unsigned int aio) syslog(LOG_ERR, "aio: Platform not initialised"); return NULL; } - if (advance_func->aio_init_pre != NULL) { - mraa_result_t pre_ret = (advance_func->aio_init_pre(aio)); + if (mraa_is_sub_platform_id(aio)) { + syslog(LOG_NOTICE, "aio: Using sub platform is not supported"); + return NULL; + } + + // Create ADC device connected to specified channel + mraa_aio_context dev = mraa_aio_init_internal(plat->adv_func); + if (dev == NULL) { + syslog(LOG_ERR, "aio: Insufficient memory for specified input channel %d", aio); + return NULL; + } + int pin = aio + plat->gpio_count; + dev->channel = plat->pins[pin].aio.pinmap; + dev->value_bit = DEFAULT_BITS; + + if (IS_FUNC_DEFINED(dev, aio_init_pre)) { + mraa_result_t pre_ret = (dev->advance_func->aio_init_pre(aio)); if (pre_ret != MRAA_SUCCESS) return NULL; } @@ -70,8 +97,6 @@ mraa_aio_init(unsigned int aio) return NULL; } - int pin = aio + plat->gpio_count; - if (plat->pins[pin].capabilites.aio != 1) { syslog(LOG_ERR, "aio: pin uncapable of aio"); return NULL; @@ -84,17 +109,6 @@ mraa_aio_init(unsigned int aio) } } - // Create ADC device connected to specified channel - mraa_aio_context dev = malloc(sizeof(struct _aio)); - if (dev == NULL) { - syslog(LOG_ERR, "aio: Insufficient memory for specified input channel " - "%d\n", - aio); - return NULL; - } - dev->channel = plat->pins[pin].aio.pinmap; - dev->value_bit = DEFAULT_BITS; - // Open valid analog input file and get the pointer. if (MRAA_SUCCESS != aio_get_valid_fp(dev)) { free(dev); @@ -102,8 +116,8 @@ mraa_aio_init(unsigned int aio) } raw_bits = mraa_adc_raw_bits(); - if (advance_func->aio_init_post != NULL) { - mraa_result_t ret = advance_func->aio_init_post(dev); + if (IS_FUNC_DEFINED(dev, aio_init_post)) { + mraa_result_t ret = dev->advance_func->aio_init_post(dev); if (ret != MRAA_SUCCESS) { free(dev); return NULL; diff --git a/src/arm/banana.c b/src/arm/banana.c index c3dfb32..432d5ab 100644 --- a/src/arm/banana.c +++ b/src/arm/banana.c @@ -287,11 +287,22 @@ mraa_banana() } } - b->pins = (mraa_pininfo_t*) calloc(b->phy_pin_count, sizeof(mraa_pininfo_t)); + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b); + return NULL; + } - advance_func->spi_init_pre = &mraa_banana_spi_init_pre; - advance_func->i2c_init_pre = &mraa_banana_i2c_init_pre; - advance_func->gpio_mmap_setup = &mraa_banana_mmap_setup; + b->pins = (mraa_pininfo_t*) calloc(b->phy_pin_count, sizeof(mraa_pininfo_t)); + if (b->pins == NULL) { + free(b->adv_func); + free(b); + return NULL; + } + + b->adv_func->spi_init_pre = &mraa_banana_spi_init_pre; + b->adv_func->i2c_init_pre = &mraa_banana_i2c_init_pre; + b->adv_func->gpio_mmap_setup = &mraa_banana_mmap_setup; strncpy(b->pins[0].name, "INVALID", MRAA_PIN_NAME_SIZE); b->pins[0].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/src/arm/beaglebone.c b/src/arm/beaglebone.c index f03eb45..6511e47 100644 --- a/src/arm/beaglebone.c +++ b/src/arm/beaglebone.c @@ -513,11 +513,20 @@ mraa_beaglebone() b->pwm_min_period = 1; b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count); + if (b->pins == NULL) { + goto error; + } - advance_func->uart_init_pre = &mraa_beaglebone_uart_init_pre; - advance_func->spi_init_pre = &mraa_beaglebone_spi_init_pre; - advance_func->i2c_init_pre = &mraa_beaglebone_i2c_init_pre; - advance_func->pwm_init_replace = &mraa_beaglebone_pwm_init_replace; + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b->pins); + goto error; + } + + b->adv_func->uart_init_pre = &mraa_beaglebone_uart_init_pre; + b->adv_func->spi_init_pre = &mraa_beaglebone_spi_init_pre; + b->adv_func->i2c_init_pre = &mraa_beaglebone_i2c_init_pre; + b->adv_func->pwm_init_replace = &mraa_beaglebone_pwm_init_replace; strncpy(b->pins[0].name, "INVALID", MRAA_PIN_NAME_SIZE); b->pins[0].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/src/arm/raspberry_pi.c b/src/arm/raspberry_pi.c index 36ecc8c..bf09643 100644 --- a/src/arm/raspberry_pi.c +++ b/src/arm/raspberry_pi.c @@ -271,13 +271,25 @@ mraa_raspberry_pi() if (b->phy_pin_count == 0) { free(b); syslog(LOG_ERR, "raspberrypi: Failed to detect platform revision"); - return NULL; + return NULL; } - b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count); - advance_func->spi_init_pre = &mraa_raspberry_pi_spi_init_pre; - advance_func->i2c_init_pre = &mraa_raspberry_pi_i2c_init_pre; - advance_func->gpio_mmap_setup = &mraa_raspberry_pi_mmap_setup; + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b); + return NULL; + } + + b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count); + if (b->pins == NULL) { + free(b->adv_func); + free(b); + return NULL; + } + + b->adv_func->spi_init_pre = &mraa_raspberry_pi_spi_init_pre; + b->adv_func->i2c_init_pre = &mraa_raspberry_pi_i2c_init_pre; + b->adv_func->gpio_mmap_setup = &mraa_raspberry_pi_mmap_setup; strncpy(b->pins[0].name, "INVALID", MRAA_PIN_NAME_SIZE); b->pins[0].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/src/gpio/gpio.c b/src/gpio/gpio.c index f66cfa9..ae5062b 100644 --- a/src/gpio/gpio.c +++ b/src/gpio/gpio.c @@ -1,7 +1,7 @@ /* * Author: Thomas Ingleby * Author: Brendan Le Foll - * Copyright (c) 2014 Intel Corporation. + * Copyright (c) 2014, 2015 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -52,7 +52,6 @@ mraa_gpio_get_valfp(mraa_gpio_context dev) return MRAA_SUCCESS; } - static mraa_gpio_context mraa_gpio_init_internal(mraa_adv_func_t* func_table, int pin) { @@ -68,10 +67,10 @@ mraa_gpio_init_internal(mraa_adv_func_t* func_table, int pin) syslog(LOG_CRIT, "gpio: Failed to allocate memory for context"); return NULL; } - + dev->advance_func = func_table; - dev->pin = pin; - + dev->pin = pin; + if (IS_FUNC_DEFINED(dev, gpio_init_internal_replace)) { status = dev->advance_func->gpio_init_internal_replace(pin); if (status == MRAA_SUCCESS) @@ -79,7 +78,7 @@ mraa_gpio_init_internal(mraa_adv_func_t* func_table, int pin) else goto init_internal_cleanup; } - + if (IS_FUNC_DEFINED(dev, gpio_init_pre)) { status = dev->advance_func->gpio_init_pre(pin); if (status != MRAA_SUCCESS) @@ -131,7 +130,7 @@ mraa_gpio_init(int pin) syslog(LOG_ERR, "gpio: platform not initialised"); return NULL; } - + if (mraa_is_sub_platform_id(pin)) { syslog(LOG_NOTICE, "gpio: Using sub platform"); board = board->sub_platform; @@ -141,7 +140,7 @@ mraa_gpio_init(int pin) } pin = mraa_get_sub_platform_index(pin); } - + if (pin < 0 || pin > board->phy_pin_count) { syslog(LOG_ERR, "gpio: pin %i beyond platform definition", pin); return NULL; @@ -215,7 +214,7 @@ mraa_gpio_interrupt_handler(void* arg) mraa_gpio_context dev = (mraa_gpio_context) arg; if (IS_FUNC_DEFINED(dev, gpio_interrupt_handler_replace)) return dev->advance_func->gpio_interrupt_handler_replace(dev); - + mraa_result_t ret; // open gpio value with open(3) @@ -273,7 +272,7 @@ mraa_gpio_edge_mode(mraa_gpio_context dev, mraa_gpio_edge_t mode) { if (IS_FUNC_DEFINED(dev, gpio_edge_mode_replace)) return dev->advance_func->gpio_edge_mode_replace(dev, mode); - + if (dev->value_fp != -1) { close(dev->value_fp); dev->value_fp = -1; @@ -375,7 +374,7 @@ mraa_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) return dev->advance_func->gpio_mode_replace(dev, mode); if (IS_FUNC_DEFINED(dev, gpio_mode_pre)) { - mraa_result_t pre_ret = (advance_func->gpio_mode_pre(dev, mode)); + mraa_result_t pre_ret = (dev->advance_func->gpio_mode_pre(dev, mode)); if (pre_ret != MRAA_SUCCESS) return pre_ret; } @@ -420,7 +419,7 @@ mraa_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) } close(drive); - if (IS_FUNC_DEFINED(dev, gpio_mode_post)) + if (IS_FUNC_DEFINED(dev, gpio_mode_post)) return dev->advance_func->gpio_mode_post(dev, mode); return MRAA_SUCCESS; } @@ -431,7 +430,7 @@ mraa_gpio_dir(mraa_gpio_context dev, mraa_gpio_dir_t dir) if (IS_FUNC_DEFINED(dev, gpio_dir_replace)) { return dev->advance_func->gpio_dir_replace(dev, dir); } - + if (IS_FUNC_DEFINED(dev, gpio_dir_pre)) { mraa_result_t pre_ret = (dev->advance_func->gpio_dir_pre(dev, dir)); if (pre_ret != MRAA_SUCCESS) { @@ -535,8 +534,8 @@ mraa_gpio_write(mraa_gpio_context dev, int value) if (dev->mmap_write != NULL) return dev->mmap_write(dev, value); - if (advance_func->gpio_write_pre != NULL) { - mraa_result_t pre_ret = (advance_func->gpio_write_pre(dev, value)); + if (IS_FUNC_DEFINED(dev, gpio_write_pre)) { + mraa_result_t pre_ret = (dev->advance_func->gpio_write_pre(dev, value)); if (pre_ret != MRAA_SUCCESS) return pre_ret; } @@ -557,8 +556,8 @@ mraa_gpio_write(mraa_gpio_context dev, int value) return MRAA_ERROR_INVALID_HANDLE; } - if (advance_func->gpio_write_post != NULL) - return advance_func->gpio_write_post(dev, value); + if (IS_FUNC_DEFINED(dev, gpio_write_post)) + return dev->advance_func->gpio_write_post(dev, value); return MRAA_SUCCESS; } @@ -597,8 +596,8 @@ mraa_gpio_close(mraa_gpio_context dev) { mraa_result_t result = MRAA_SUCCESS; - if (advance_func->gpio_close_pre != NULL) { - result = advance_func->gpio_close_pre(dev); + if (IS_FUNC_DEFINED(dev, gpio_close_pre)) { + result = dev->advance_func->gpio_close_pre(dev); } if (dev->value_fp != -1) { @@ -623,8 +622,8 @@ mraa_gpio_owner(mraa_gpio_context dev, mraa_boolean_t own) mraa_result_t mraa_gpio_use_mmaped(mraa_gpio_context dev, mraa_boolean_t mmap_en) { - if (advance_func->gpio_mmap_setup != NULL) { - return advance_func->gpio_mmap_setup(dev, mmap_en); + if (IS_FUNC_DEFINED(dev, gpio_mmap_setup)) { + return dev->advance_func->gpio_mmap_setup(dev, mmap_en); } syslog(LOG_ERR, "gpio: mmap not implemented on this platform"); diff --git a/src/i2c/i2c.c b/src/i2c/i2c.c index 642dc74..c305518 100644 --- a/src/i2c/i2c.c +++ b/src/i2c/i2c.c @@ -68,7 +68,7 @@ mraa_i2c_smbus_access(int fh, uint8_t read_write, uint8_t command, int size, i2c return ioctl(fh, I2C_SMBUS, &args); } -static mraa_i2c_context +static mraa_i2c_context mraa_i2c_init_internal(mraa_adv_func_t* advance_func, unsigned int bus) { mraa_result_t status = MRAA_SUCCESS; @@ -81,7 +81,7 @@ mraa_i2c_init_internal(mraa_adv_func_t* advance_func, unsigned int bus) syslog(LOG_CRIT, "i2c: Failed to allocate memory for context"); return NULL; } - + dev->advance_func = advance_func; dev->busnum = bus; @@ -108,7 +108,7 @@ mraa_i2c_init_internal(mraa_adv_func_t* advance_func, unsigned int bus) syslog(LOG_CRIT, "i2c: Failed to get I2C_FUNC map from device"); dev->funcs = 0; } - } + } if (IS_FUNC_DEFINED(dev, i2c_init_post)) { status = dev->advance_func->i2c_init_post(dev); @@ -182,8 +182,8 @@ mraa_i2c_init(int bus) } -mraa_i2c_context -mraa_i2c_init_raw(unsigned int bus) +mraa_i2c_context +mraa_i2c_init_raw(unsigned int bus) { return mraa_i2c_init_internal(plat == NULL ? NULL : plat->adv_func, bus); } diff --git a/src/mraa.c b/src/mraa.c index 0121895..0ad08b3 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -108,10 +108,6 @@ mraa_init() #if defined(X86PLAT) // Use runtime x86 platform detection platform_type = mraa_x86_platform(); - // x86 platforms have advanced_func table in board config structure - free(advance_func); - if (plat != NULL) - advance_func = plat->adv_func; #elif defined(ARMPLAT) // Use runtime ARM platform detection platform_type = mraa_arm_platform(); @@ -158,14 +154,14 @@ mraa_deinit() free(plat->pins); } mraa_board_t* sub_plat = plat->sub_platform; - if (sub_plat != NULL) { + if (sub_plat != NULL) { if (sub_plat->pins != NULL) { free(sub_plat->pins); } - free(sub_plat); + free(sub_plat); } free(plat); - + } closelog(); } @@ -264,13 +260,12 @@ mraa_result_print(mraa_result_t result) } -mraa_boolean_t +mraa_boolean_t mraa_has_sub_platform() { return (plat != NULL) && (plat->sub_platform != NULL); } - mraa_boolean_t mraa_pin_mode_test(int pin, mraa_pinmodes_t mode) { @@ -416,7 +411,7 @@ mraa_get_platform_name() strncpy(platform_name, plat->platform_name, MAX_PLATFORM_NAME_LENGTH); if (mraa_has_sub_platform()) { strncat(platform_name, " + ", MAX_PLATFORM_NAME_LENGTH); - strncat(platform_name, plat->sub_platform->platform_name, MAX_PLATFORM_NAME_LENGTH); + strncat(platform_name, plat->sub_platform->platform_name, MAX_PLATFORM_NAME_LENGTH); } return platform_name; } @@ -491,7 +486,7 @@ mraa_get_pin_name(int pin) int mraa_get_default_i2c_bus(uint8_t platform_offset) { - if (plat == NULL) + if (plat == NULL) return -1; if (platform_offset == MRAA_MAIN_PLATFORM_OFFSET) { return plat->def_i2c_bus; @@ -717,13 +712,13 @@ mraa_is_sub_platform_id(int pin_or_bus) return (pin_or_bus & MRAA_SUB_PLATFORM_MASK) != 0; } -int +int mraa_get_sub_platform_id(int pin_or_bus) { return pin_or_bus | MRAA_SUB_PLATFORM_MASK; } -int +int mraa_get_sub_platform_index(int pin_or_bus) { return pin_or_bus & (~MRAA_SUB_PLATFORM_MASK); diff --git a/src/pwm/pwm.c b/src/pwm/pwm.c index f0fd7f7..420e32c 100644 --- a/src/pwm/pwm.c +++ b/src/pwm/pwm.c @@ -1,6 +1,7 @@ /* * Author: Thomas Ingleby - * Copyright (c) 2014 Intel Corporation. + * Author: Brendan Le Foll + * Copyright (c) 2014, 2015 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -49,8 +50,8 @@ mraa_pwm_setup_duty_fp(mraa_pwm_context dev) static mraa_result_t mraa_pwm_write_period(mraa_pwm_context dev, int period) { - if (advance_func->pwm_period_replace != NULL) { - mraa_result_t result = advance_func->pwm_period_replace(dev, period); + if (IS_FUNC_DEFINED(dev, pwm_period_replace)) { + mraa_result_t result = dev->advance_func->pwm_period_replace(dev, period); if (result == MRAA_SUCCESS) { dev->period = period; } @@ -158,26 +159,46 @@ mraa_pwm_read_duty(mraa_pwm_context dev) return (int) ret; } +static mraa_pwm_context +mraa_pwm_init_internal(mraa_adv_func_t* func_table, int chipin, int pin) +{ + mraa_pwm_context dev = (mraa_pwm_context) malloc(sizeof(struct _pwm)); + if (dev == NULL) { + return NULL; + } + dev->duty_fp = -1; + dev->chipid = chipin; + dev->pin = pin; + dev->period = -1; + dev->advance_func = func_table; + + return dev; +} + mraa_pwm_context mraa_pwm_init(int pin) { - if (advance_func->pwm_init_replace != NULL) { - return advance_func->pwm_init_replace(pin); - } - - if (advance_func->pwm_init_pre != NULL) { - if (advance_func->pwm_init_pre(pin) != MRAA_SUCCESS) - return NULL; - } if (plat == NULL) { syslog(LOG_ERR, "pwm: Platform Not Initialised"); return NULL; } + if (mraa_is_sub_platform_id(pin)) { + syslog(LOG_NOTICE, "pwm: Using sub platform is not supported"); + return NULL; + } if (plat->pins[pin].capabilites.pwm != 1) { syslog(LOG_ERR, "pwm: pin not capable of pwm"); return NULL; } + if (plat->adv_func->pwm_init_replace != NULL) { + return plat->adv_func->pwm_init_replace(pin); + } + if (plat->adv_func->pwm_init_pre != NULL) { + if (plat->adv_func->pwm_init_pre(pin) != MRAA_SUCCESS) + return NULL; + } + if (plat->pins[pin].capabilites.gpio == 1) { // This deserves more investigation mraa_gpio_context mux_i; @@ -210,9 +231,9 @@ mraa_pwm_init(int pin) int chip = plat->pins[pin].pwm.parent_id; int pinn = plat->pins[pin].pwm.pinmap; - if (advance_func->pwm_init_post != NULL) { + if (plat->adv_func->pwm_init_post != NULL) { mraa_pwm_context pret = mraa_pwm_init_raw(chip, pinn); - mraa_result_t ret = advance_func->pwm_init_post(pret); + mraa_result_t ret = plat->adv_func->pwm_init_post(pret); if (ret != MRAA_SUCCESS) { free(pret); return NULL; @@ -225,13 +246,9 @@ mraa_pwm_init(int pin) mraa_pwm_context mraa_pwm_init_raw(int chipin, int pin) { - mraa_pwm_context dev = (mraa_pwm_context) malloc(sizeof(struct _pwm)); + mraa_pwm_context dev = mraa_pwm_init_internal(plat == NULL ? NULL : plat->adv_func , chipin, pin); if (dev == NULL) return NULL; - dev->duty_fp = -1; - dev->chipid = chipin; - dev->pin = pin; - dev->period = -1; char directory[MAX_SIZE]; snprintf(directory, MAX_SIZE, SYSFS_PWM "/pwmchip%d/pwm%d", dev->chipid, dev->pin); diff --git a/src/spi/spi.c b/src/spi/spi.c index 5eb5b4f..d270451 100644 --- a/src/spi/spi.c +++ b/src/spi/spi.c @@ -1,6 +1,7 @@ /* * Author: Thomas Ingleby - * Copyright (c) 2014 Intel Corporation. + * Author: Brendan Le Foll + * Copyright (c) 2014, 2015 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -36,6 +37,18 @@ #define MAX_SIZE 64 #define SPI_MAX_LENGTH 4096 +static mraa_spi_context +mraa_spi_init_internal(mraa_adv_func_t* func_table) +{ + mraa_spi_context dev = (mraa_spi_context) calloc(1, sizeof(struct _spi)); + if (dev == NULL) { + return NULL; + } + dev->advance_func = func_table; + + return dev; +} + mraa_spi_context mraa_spi_init(int bus) { @@ -43,6 +56,10 @@ mraa_spi_init(int bus) syslog(LOG_ERR, "spi: Platform Not Initialised"); return NULL; } + if (mraa_is_sub_platform_id(bus)) { + syslog(LOG_ERR, "spi: Spi module doesn't support subplatforms"); + return NULL; + } if (plat->spi_bus_count == 0) { syslog(LOG_ERR, "spi: no spi buses defined in platform"); return NULL; @@ -54,9 +71,10 @@ mraa_spi_init(int bus) syslog(LOG_ERR, "spi: requested bus above spi bus count"); return NULL; } - if (advance_func->spi_init_pre != NULL) { - if (advance_func->spi_init_pre(bus) != MRAA_SUCCESS) + if (plat->adv_func->spi_init_pre != NULL) { + if (plat->adv_func->spi_init_pre(bus) != MRAA_SUCCESS) { return NULL; + } } int pos = plat->spi_bus[bus].sclk; @@ -92,8 +110,8 @@ mraa_spi_init(int bus) } mraa_spi_context dev = mraa_spi_init_raw(plat->spi_bus[bus].bus_id, plat->spi_bus[bus].slave_s); - if (advance_func->spi_init_post != NULL) { - mraa_result_t ret = advance_func->spi_init_post(dev); + if (plat->adv_func->spi_init_post != NULL) { + mraa_result_t ret = plat->adv_func->spi_init_post(dev); if (ret != MRAA_SUCCESS) { free(dev); return NULL; @@ -106,12 +124,11 @@ mraa_spi_init(int bus) mraa_spi_context mraa_spi_init_raw(unsigned int bus, unsigned int cs) { - mraa_spi_context dev = (mraa_spi_context) malloc(sizeof(struct _spi)); + mraa_spi_context dev = mraa_spi_init_internal(plat == NULL ? NULL : plat->adv_func); if (dev == NULL) { syslog(LOG_CRIT, "spi: Failed to allocate memory for context"); return NULL; } - memset(dev, 0, sizeof(struct _spi)); char path[MAX_SIZE]; sprintf(path, "/dev/spidev%u.%u", bus, cs); @@ -196,8 +213,8 @@ mraa_spi_frequency(mraa_spi_context dev, int hz) mraa_result_t mraa_spi_lsbmode(mraa_spi_context dev, mraa_boolean_t lsb) { - if (advance_func->spi_lsbmode_replace != NULL) { - return advance_func->spi_lsbmode_replace(dev, lsb); + if (IS_FUNC_DEFINED(dev, spi_lsbmode_replace)) { + return dev->advance_func->spi_lsbmode_replace(dev, lsb); } uint8_t lsb_mode = (uint8_t) lsb; diff --git a/src/uart/uart.c b/src/uart/uart.c index 76cf9a2..04a6e5e 100644 --- a/src/uart/uart.c +++ b/src/uart/uart.c @@ -107,6 +107,21 @@ uint2speed(unsigned int speed) } } +static mraa_uart_context +mraa_uart_init_internal(mraa_adv_func_t* func_table) +{ + mraa_uart_context dev = (mraa_uart_context) calloc(1, sizeof(struct _uart)); + if (dev == NULL) { + syslog(LOG_CRIT, "uart: Failed to allocate memory for context"); + return NULL; + } + dev->index = -1; + dev->fd = -1; + dev->advance_func = func_table; + + return dev; +} + mraa_uart_context mraa_uart_init(int index) { @@ -115,8 +130,13 @@ mraa_uart_init(int index) return NULL; } - if (advance_func->uart_init_pre != NULL) { - if (advance_func->uart_init_pre(index) != MRAA_SUCCESS) { + if (mraa_is_sub_platform_id(index)) { + syslog(LOG_NOTICE, "pwm: Using sub platform is not supported"); + return NULL; + } + + if (plat->adv_func->uart_init_pre != NULL) { + if (plat->adv_func->uart_init_pre(index) != MRAA_SUCCESS) { syslog(LOG_ERR, "uart: failure in pre-init platform hook"); return NULL; } @@ -158,8 +178,8 @@ mraa_uart_init(int index) } dev->index = index; //Set the board Index. - if (advance_func->uart_init_post != NULL) { - mraa_result_t ret = advance_func->uart_init_post(dev); + if (IS_FUNC_DEFINED(dev, uart_init_post)) { + mraa_result_t ret = dev->advance_func->uart_init_post(dev); if (ret != MRAA_SUCCESS) { free(dev); return NULL; @@ -172,15 +192,11 @@ mraa_uart_init(int index) mraa_uart_context mraa_uart_init_raw(const char* path) { - mraa_uart_context dev = (mraa_uart_context) malloc(sizeof(struct _uart)); + mraa_uart_context dev = mraa_uart_init_internal(plat == NULL ? NULL : plat->adv_func); if (dev == NULL) { - syslog(LOG_CRIT, "uart: Failed to allocate memory for context"); + syslog(LOG_ERR, "uart: Failed to allocate memory for context"); return NULL; } - memset(dev, 0, sizeof(struct _uart)); - - dev->index = -1; - dev->fd = -1; dev->path = path; if (!dev->path) { diff --git a/src/x86/intel_de3815.c b/src/x86/intel_de3815.c index 83298d4..762b6aa 100644 --- a/src/x86/intel_de3815.c +++ b/src/x86/intel_de3815.c @@ -57,6 +57,12 @@ mraa_intel_de3815() goto error; } + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b->pins); + goto error; + } + strncpy(b->pins[0].name, "1.8v", 8); b->pins[0].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/src/x86/intel_edison_fab_c.c b/src/x86/intel_edison_fab_c.c index 10ed8b6..944ab93 100644 --- a/src/x86/intel_edison_fab_c.c +++ b/src/x86/intel_edison_fab_c.c @@ -760,19 +760,19 @@ mraa_intel_edison_miniboard(mraa_board_t* b) return MRAA_ERROR_UNSPECIFIED; } - mraa_adv_func_t* adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); - if (adv_func == NULL) { + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b->pins); return MRAA_ERROR_UNSPECIFIED; } - adv_func->gpio_init_post = &mraa_intel_edison_gpio_init_post; - adv_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre; - adv_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre; - adv_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq; - adv_func->spi_init_pre = &mraa_intel_edison_spi_init_pre; - adv_func->gpio_mode_replace = &mraa_intel_edsion_mb_gpio_mode; - adv_func->uart_init_pre = &mraa_intel_edison_uart_init_pre; - adv_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup; - b->adv_func = adv_func; + b->adv_func->gpio_init_post = &mraa_intel_edison_gpio_init_post; + b->adv_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre; + b->adv_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre; + b->adv_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq; + b->adv_func->spi_init_pre = &mraa_intel_edison_spi_init_pre; + b->adv_func->gpio_mode_replace = &mraa_intel_edsion_mb_gpio_mode; + b->adv_func->uart_init_pre = &mraa_intel_edison_uart_init_pre; + b->adv_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup; int pos = 0; strncpy(b->pins[pos].name, "J17-1", 8); @@ -1141,32 +1141,32 @@ mraa_intel_edison_fab_c() b->gpio_count = 14; b->aio_count = 6; - mraa_adv_func_t* adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); - if (adv_func == NULL) { - return NULL; + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + goto error; } - adv_func->gpio_dir_pre = &mraa_intel_edison_gpio_dir_pre; - adv_func->gpio_init_post = &mraa_intel_edison_gpio_init_post; - adv_func->gpio_close_pre = &mraa_intel_edison_gpio_close_pre; - adv_func->gpio_dir_post = &mraa_intel_edison_gpio_dir_post; - adv_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre; - adv_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq; - adv_func->aio_get_valid_fp = &mraa_intel_edison_aio_get_fp; - adv_func->aio_init_pre = &mraa_intel_edison_aio_init_pre; - adv_func->aio_init_post = &mraa_intel_edison_aio_init_post; - adv_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre; - adv_func->pwm_init_post = &mraa_intel_edison_pwm_init_post; - adv_func->spi_init_pre = &mraa_intel_edison_spi_init_pre; - adv_func->spi_init_post = &mraa_intel_edison_spi_init_post; - adv_func->gpio_mode_replace = &mraa_intel_edison_gpio_mode_replace; - adv_func->uart_init_pre = &mraa_intel_edison_uart_init_pre; - adv_func->uart_init_post = &mraa_intel_edison_uart_init_post; - adv_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup; - adv_func->spi_lsbmode_replace = &mraa_intel_edison_spi_lsbmode_replace; - b->adv_func = adv_func; + b->adv_func->gpio_dir_pre = &mraa_intel_edison_gpio_dir_pre; + b->adv_func->gpio_init_post = &mraa_intel_edison_gpio_init_post; + b->adv_func->gpio_close_pre = &mraa_intel_edison_gpio_close_pre; + b->adv_func->gpio_dir_post = &mraa_intel_edison_gpio_dir_post; + b->adv_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre; + b->adv_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq; + b->adv_func->aio_get_valid_fp = &mraa_intel_edison_aio_get_fp; + b->adv_func->aio_init_pre = &mraa_intel_edison_aio_init_pre; + b->adv_func->aio_init_post = &mraa_intel_edison_aio_init_post; + b->adv_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre; + b->adv_func->pwm_init_post = &mraa_intel_edison_pwm_init_post; + b->adv_func->spi_init_pre = &mraa_intel_edison_spi_init_pre; + b->adv_func->spi_init_post = &mraa_intel_edison_spi_init_post; + b->adv_func->gpio_mode_replace = &mraa_intel_edison_gpio_mode_replace; + b->adv_func->uart_init_pre = &mraa_intel_edison_uart_init_pre; + b->adv_func->uart_init_post = &mraa_intel_edison_uart_init_post; + b->adv_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup; + b->adv_func->spi_lsbmode_replace = &mraa_intel_edison_spi_lsbmode_replace; b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_INTEL_EDISON_PINCOUNT); if (b->pins == NULL) { + free(b->adv_func); goto error; } diff --git a/src/x86/intel_galileo_rev_d.c b/src/x86/intel_galileo_rev_d.c index 28992a5..9b6eef5 100644 --- a/src/x86/intel_galileo_rev_d.c +++ b/src/x86/intel_galileo_rev_d.c @@ -160,16 +160,16 @@ mraa_intel_galileo_rev_d() b->pwm_max_period = 7968; b->pwm_min_period = 1; - mraa_adv_func_t* advance_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); - if (advance_func == NULL) { + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { return NULL; } - advance_func->gpio_mmap_setup = &mraa_intel_galileo_g1_mmap_setup; - advance_func->spi_lsbmode_replace = &mraa_intel_galileo_g1_spi_lsbmode_replace; - b->adv_func = advance_func; + b->adv_func->gpio_mmap_setup = &mraa_intel_galileo_g1_mmap_setup; + b->adv_func->spi_lsbmode_replace = &mraa_intel_galileo_g1_spi_lsbmode_replace; b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_INTEL_GALILEO_REV_D_PINCOUNT); if (b->pins == NULL) { + free(b->adv_func); goto error; } diff --git a/src/x86/intel_galileo_rev_g.c b/src/x86/intel_galileo_rev_g.c index e84d310..cee8d4f 100644 --- a/src/x86/intel_galileo_rev_g.c +++ b/src/x86/intel_galileo_rev_g.c @@ -335,21 +335,21 @@ mraa_intel_galileo_gen2() b->pwm_max_period = 41666; b->pwm_min_period = 666; - mraa_adv_func_t* advance_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); - if (advance_func == NULL) { - return NULL; + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + goto error; } - advance_func->gpio_close_pre = &mraa_intel_galileo_gen2_gpio_close_pre; - advance_func->gpio_dir_pre = &mraa_intel_galileo_gen2_dir_pre; - advance_func->i2c_init_pre = &mraa_intel_galileo_gen2_i2c_init_pre; - advance_func->pwm_period_replace = &mraa_intel_galileo_gen2_pwm_period_replace; - advance_func->gpio_mode_replace = &mraa_intel_galileo_gen2_gpio_mode_replace; - advance_func->uart_init_pre = &mraa_intel_galileo_gen2_uart_init_pre; - advance_func->gpio_mmap_setup = &mraa_intel_galileo_g2_mmap_setup; - b->adv_func = advance_func; + b->adv_func->gpio_close_pre = &mraa_intel_galileo_gen2_gpio_close_pre; + b->adv_func->gpio_dir_pre = &mraa_intel_galileo_gen2_dir_pre; + b->adv_func->i2c_init_pre = &mraa_intel_galileo_gen2_i2c_init_pre; + b->adv_func->pwm_period_replace = &mraa_intel_galileo_gen2_pwm_period_replace; + b->adv_func->gpio_mode_replace = &mraa_intel_galileo_gen2_gpio_mode_replace; + b->adv_func->uart_init_pre = &mraa_intel_galileo_gen2_uart_init_pre; + b->adv_func->gpio_mmap_setup = &mraa_intel_galileo_g2_mmap_setup; b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_INTEL_GALILEO_GEN_2_PINCOUNT); if (b->pins == NULL) { + free(b->adv_func); goto error; } diff --git a/src/x86/intel_minnow_max.c b/src/x86/intel_minnow_max.c index c3ecda8..8891a22 100644 --- a/src/x86/intel_minnow_max.c +++ b/src/x86/intel_minnow_max.c @@ -97,9 +97,6 @@ mraa_intel_minnow_max() b->platform_name = PLATFORM_NAME; b->phy_pin_count = MRAA_INTEL_MINNOW_MAX_PINCOUNT; b->gpio_count = MRAA_INTEL_MINNOW_MAX_PINCOUNT; - b->aio_count = 0; - b->adc_raw = 0; - b->adc_supported = 0; b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_INTEL_MINNOW_MAX_PINCOUNT); @@ -107,7 +104,15 @@ mraa_intel_minnow_max() goto error; } + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b->pins); + goto error; + } + if (uname(&running_uname) != 0) { + free(b->pins); + free(b->adv_func); goto error; } diff --git a/src/x86/intel_nuc5.c b/src/x86/intel_nuc5.c index ef61cab..8562649 100644 --- a/src/x86/intel_nuc5.c +++ b/src/x86/intel_nuc5.c @@ -38,22 +38,22 @@ mraa_board_t* mraa_intel_nuc5() { - mraa_board_t* b = (mraa_board_t*) malloc(sizeof(mraa_board_t)); + mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); if (b == NULL) { return NULL; } b->platform_name = PLATFORM_NAME; b->phy_pin_count = MRAA_INTEL_NUC5_PINCOUNT; - b->aio_count = 0; - b->adc_raw = 0; - b->adc_supported = 0; - b->pwm_default_period = 0; - b->pwm_max_period = 0; - b->pwm_min_period = 0; + + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + goto error; + } b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_INTEL_NUC5_PINCOUNT); if (b->pins == NULL) { + free(b->adv_func); goto error; } @@ -134,11 +134,6 @@ mraa_intel_nuc5() b->def_i2c_bus = b->i2c_bus[0].bus_id; } - - b->spi_bus_count = 0; - b->def_spi_bus = 0; - b->uart_dev_count = 0; - return b; error: syslog(LOG_CRIT, "nuc5: Platform failed to initialise");