mraa_result_t mraa_gpio_close(mraa_gpio_context dev) { mraa_result_t result = MRAA_SUCCESS; if (dev == NULL) { syslog(LOG_ERR, "gpio: close: context is invalid"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, gpio_close_replace)) { return dev->advance_func->gpio_close_replace(dev); } if (IS_FUNC_DEFINED(dev, gpio_close_pre)) { result = dev->advance_func->gpio_close_pre(dev); } if (dev->value_fp != -1) { close(dev->value_fp); } mraa_gpio_unexport(dev); free(dev); return result; }
static mraa_i2c_context mraa_i2c_init_internal(mraa_adv_func_t* advance_func, unsigned int bus) { mraa_result_t status = MRAA_SUCCESS; if (advance_func == NULL) return NULL; mraa_i2c_context dev = (mraa_i2c_context) calloc(1, sizeof(struct _i2c)); if (dev == NULL) { syslog(LOG_CRIT, "i2c: Failed to allocate memory for context"); return NULL; } dev->advance_func = advance_func; dev->busnum = bus; if (IS_FUNC_DEFINED(dev, i2c_init_pre)) { status = advance_func->i2c_init_pre(bus); if (status != MRAA_SUCCESS) goto init_internal_cleanup; } if (IS_FUNC_DEFINED(dev, i2c_init_bus_replace)) { status = dev->advance_func->i2c_init_bus_replace(dev); if (status != MRAA_SUCCESS) goto init_internal_cleanup; } else { char filepath[32]; snprintf(filepath, 32, "/dev/i2c-%u", bus); if ((dev->fh = open(filepath, O_RDWR)) < 1) { syslog(LOG_ERR, "i2c: Failed to open requested i2c port %s", filepath); status = MRAA_ERROR_NO_RESOURCES; goto init_internal_cleanup; } if (ioctl(dev->fh, I2C_FUNCS, &dev->funcs) < 0) { 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); if (status != MRAA_SUCCESS) goto init_internal_cleanup; } init_internal_cleanup: if (status == MRAA_SUCCESS) { return dev; } else { if (dev != NULL) free(dev); return NULL; } }
mraa_result_t mraa_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode) { if (IS_FUNC_DEFINED(dev, gpio_mode_replace)) return dev->advance_func->gpio_mode_replace(dev, mode); if (IS_FUNC_DEFINED(dev, gpio_mode_pre)) { mraa_result_t pre_ret = (dev->advance_func->gpio_mode_pre(dev, mode)); if (pre_ret != MRAA_SUCCESS) return pre_ret; } if (dev->value_fp != -1) { close(dev->value_fp); dev->value_fp = -1; } char filepath[MAX_SIZE]; snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/drive", dev->pin); int drive = open(filepath, O_WRONLY); if (drive == -1) { syslog(LOG_ERR, "gpio: Failed to open drive for writing"); return MRAA_ERROR_INVALID_RESOURCE; } char bu[MAX_SIZE]; int length; switch (mode) { case MRAA_GPIO_STRONG: length = snprintf(bu, sizeof(bu), "strong"); break; case MRAA_GPIO_PULLUP: length = snprintf(bu, sizeof(bu), "pullup"); break; case MRAA_GPIO_PULLDOWN: length = snprintf(bu, sizeof(bu), "pulldown"); break; case MRAA_GPIO_HIZ: length = snprintf(bu, sizeof(bu), "hiz"); break; default: close(drive); return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; } if (write(drive, bu, length * sizeof(char)) == -1) { syslog(LOG_ERR, "gpio: Failed to write to drive mode"); close(drive); return MRAA_ERROR_INVALID_RESOURCE; } close(drive); if (IS_FUNC_DEFINED(dev, gpio_mode_post)) return dev->advance_func->gpio_mode_post(dev, mode); return MRAA_SUCCESS; }
mraa_result_t mraa_pwm_enable(mraa_pwm_context dev, int enable) { if (!dev) { syslog(LOG_ERR, "pwm: enable: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, pwm_enable_replace)) { return dev->advance_func->pwm_enable_replace(dev, enable); } char bu[MAX_SIZE]; snprintf(bu, MAX_SIZE, "/sys/class/pwm/pwmchip%d/pwm%d/enable", dev->chipid, dev->pin); int enable_f = open(bu, O_RDWR); if (enable_f == -1) { syslog(LOG_ERR, "pwm_enable: pwm%i: Failed to open enable for writing: %s", dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } char out[2]; int size = snprintf(out, sizeof(out), "%d", enable); if (write(enable_f, out, size * sizeof(char)) == -1) { syslog(LOG_ERR, "pwm_enable: pwm%i: Failed to write to enable: %s", dev->pin, strerror(errno)); close(enable_f); return MRAA_ERROR_UNSPECIFIED; } close(enable_f); return MRAA_SUCCESS; }
static mraa_aio_context mraa_aio_init_internal(mraa_adv_func_t* func_table, int aio) { mraa_aio_context dev = calloc(1, sizeof(struct _aio)); if (dev == NULL) { return NULL; } dev->advance_func = func_table; if (IS_FUNC_DEFINED(dev, aio_init_internal_replace)) { if (dev->advance_func->aio_init_internal_replace(dev, aio) == MRAA_SUCCESS) { return dev; } free(dev); return NULL; } // Open valid analog input file and get the pointer. if (MRAA_SUCCESS != aio_get_valid_fp(dev)) { free(dev); return NULL; } return dev; }
static mraa_result_t aio_get_valid_fp(mraa_aio_context dev) { if (dev == NULL) { syslog(LOG_ERR, "aio: get_valid_fp: context is invalid"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, aio_get_valid_fp)) { return dev->advance_func->aio_get_valid_fp(dev); } char file_path[64] = ""; // Open file Analog device input channel raw voltage file for reading. snprintf(file_path, 64, "/sys/bus/iio/devices/iio:device0/in_voltage%d_raw", dev->channel); dev->adc_in_fp = open(file_path, O_RDONLY); if (dev->adc_in_fp == -1) { syslog(LOG_ERR, "aio: Failed to open input raw file %s for reading!", file_path); return MRAA_ERROR_INVALID_RESOURCE; } return MRAA_SUCCESS; }
mraa_result_t mraa_pwm_enable(mraa_pwm_context dev, int enable) { if (IS_FUNC_DEFINED(dev, pwm_enable_replace)) { return dev->advance_func->pwm_enable_replace(dev, enable); } int status; if (enable != 0) { status = 1; } else { status = enable; } char bu[MAX_SIZE]; snprintf(bu, MAX_SIZE, "/sys/class/pwm/pwmchip%d/pwm%d/enable", dev->chipid, dev->pin); int enable_f = open(bu, O_RDWR); if (enable_f == -1) { syslog(LOG_ERR, "pwm: Failed to open enable for writing"); return MRAA_ERROR_INVALID_RESOURCE; } char out[2]; int size = snprintf(out, sizeof(out), "%d", enable); if (write(enable_f, out, size * sizeof(char)) == -1) { syslog(LOG_ERR, "pwm: Failed to write to enable"); close(enable_f); return MRAA_ERROR_INVALID_RESOURCE; } close(enable_f); return MRAA_SUCCESS; }
static int mraa_pwm_read_duty(mraa_pwm_context dev) { if (IS_FUNC_DEFINED(dev, pwm_read_duty_replace)) { return dev->advance_func->pwm_read_duty_replace(dev); } if (dev->duty_fp == -1) { if (mraa_pwm_setup_duty_fp(dev) == 1) { return MRAA_ERROR_INVALID_HANDLE; } } else { lseek(dev->duty_fp, 0, SEEK_SET); } off_t size = lseek(dev->duty_fp, 0, SEEK_END); lseek(dev->duty_fp, 0, SEEK_SET); char output[MAX_SIZE]; ssize_t rb = read(dev->duty_fp, output, size + 1); if (rb < 0) { syslog(LOG_ERR, "pwm: Error in reading duty"); return -1; } char* endptr; long int ret = strtol(output, &endptr, 10); if ('\0' != *endptr && '\n' != *endptr) { syslog(LOG_ERR, "pwm: Error in string converstion"); return -1; } else if (ret > INT_MAX || ret < INT_MIN) { syslog(LOG_ERR, "pwm: Number is invalid"); return -1; } return (int) ret; }
mraa_result_t mraa_uart_set_non_blocking(mraa_uart_context dev, mraa_boolean_t nonblock) { if (!dev) { syslog(LOG_ERR, "uart: non_blocking: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, uart_set_non_blocking_replace)) { return dev->advance_func->uart_set_non_blocking_replace(dev, nonblock); } // get current flags int flags = fcntl(dev->fd, F_GETFL); // update flags with new blocking state according to nonblock bool if (nonblock) { flags |= O_NONBLOCK; } else { flags &= ~O_NONBLOCK; } // set new flags if (fcntl(dev->fd, F_SETFL, flags) < 0) { syslog(LOG_ERR, "uart%i: non_blocking: failed changing fd blocking state: %s", dev->index, strerror(errno)); return MRAA_ERROR_UNSPECIFIED; } return MRAA_SUCCESS; }
mraa_result_t mraa_uart_set_timeout(mraa_uart_context dev, int read, int write, int interchar) { if (!dev) { syslog(LOG_ERR, "uart: set_timeout: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, uart_set_timeout_replace)) { return dev->advance_func->uart_set_timeout_replace(dev, read, write, interchar); } struct termios termio; // get current modes if (tcgetattr(dev->fd, &termio)) { syslog(LOG_ERR, "uart%i: set_timeout: tcgetattr() failed: %s", dev->index, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } if (read > 0) { read = read / 100; if (read == 0) read = 1; } termio.c_lflag &= ~ICANON; /* Set non-canonical mode */ termio.c_cc[VTIME] = read; /* Set timeout in tenth seconds */ if (tcsetattr(dev->fd, TCSANOW, &termio) < 0) { syslog(LOG_ERR, "uart%i: set_timeout: tcsetattr() failed: %s", dev->index, strerror(errno)); return MRAA_ERROR_FEATURE_NOT_SUPPORTED; } return MRAA_SUCCESS; }
mraa_gpio_context mraa_gpio_init(int pin) { mraa_board_t* board = plat; if (board == NULL) { syslog(LOG_ERR, "gpio%i: init: platform not initialised", pin); return NULL; } if (mraa_is_sub_platform_id(pin)) { syslog(LOG_NOTICE, "gpio%i: init: Using sub platform", pin); board = board->sub_platform; if (board == NULL) { syslog(LOG_ERR, "gpio%i: init: Sub platform not initialised", pin); return NULL; } pin = mraa_get_sub_platform_index(pin); } if (board->chardev_capable) { int pins[1] = { pin }; return mraa_gpio_init_multi(pins, 1); } if (pin < 0 || pin >= board->phy_pin_count) { syslog(LOG_ERR, "gpio: init: pin %i beyond platform pin count (%i)", pin, board->phy_pin_count); return NULL; } if (board->pins[pin].capabilities.gpio != 1) { syslog(LOG_ERR, "gpio: init: pin %i not capable of gpio", pin); return NULL; } if (board->pins[pin].gpio.mux_total > 0) { if (mraa_setup_mux_mapped(board->pins[pin].gpio) != MRAA_SUCCESS) { syslog(LOG_ERR, "gpio%i: init: unable to setup muxes", pin); return NULL; } } mraa_gpio_context r = mraa_gpio_init_internal(board->adv_func, board->pins[pin].gpio.pinmap); if (r == NULL) { return NULL; } if (r->phy_pin == -1) r->phy_pin = pin; if (IS_FUNC_DEFINED(r, gpio_init_post)) { mraa_result_t ret = r->advance_func->gpio_init_post(r); if (ret != MRAA_SUCCESS) { free(r); return NULL; } } return r; }
mraa_result_t mraa_spi_frequency(mraa_spi_context dev, int hz) { if (dev == NULL) { syslog(LOG_ERR, "spi: frequency: context is invalid"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, spi_frequency_replace)) { return dev->advance_func->spi_frequency_replace(dev, hz); } int speed = 0; dev->clock = hz; if (ioctl(dev->devfd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) != -1) { if (speed < hz) { // We wanted to never go higher than SPI_IOC_RD_MAX_SPEED_HZ but it // seems a bunch of drivers don't have this set to the actual max // so we only complain about it // dev->clock = speed; syslog(LOG_NOTICE, "spi: Selected speed (%d Hz) is higher than the kernel max allowed speed (%lu Hz)", hz, SPI_IOC_RD_MAX_SPEED_HZ); } } return MRAA_SUCCESS; }
static mraa_result_t mraa_pwm_write_duty(mraa_pwm_context dev, int duty) { if (!dev) { syslog(LOG_ERR, "pwm: write_duty: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, pwm_write_replace)) { return dev->advance_func->pwm_write_replace(dev, duty); } if (dev->duty_fp == -1) { if (mraa_pwm_setup_duty_fp(dev) == 1) { syslog(LOG_ERR, "pwm%i write_duty: Failed to open duty_cycle for writing: %s", dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } } char bu[64]; int length = sprintf(bu, "%d", duty); if (write(dev->duty_fp, bu, length * sizeof(char)) == -1) { syslog(LOG_ERR, "pwm%i write_duty: Failed to write to duty_cycle: %s", dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } return MRAA_SUCCESS; }
static mraa_result_t mraa_pwm_write_period(mraa_pwm_context dev, int period) { if (!dev) { syslog(LOG_ERR, "pwm: write_period: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } 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; } return result; } char bu[MAX_SIZE]; snprintf(bu, MAX_SIZE, "/sys/class/pwm/pwmchip%d/pwm%d/period", dev->chipid, dev->pin); int period_f = open(bu, O_RDWR); if (period_f == -1) { syslog(LOG_ERR, "pwm%i write_period: Failed to open period for writing: %s", dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } char out[MAX_SIZE]; int length = snprintf(out, MAX_SIZE, "%d", period); if (write(period_f, out, length * sizeof(char)) == -1) { close(period_f); syslog(LOG_ERR, "pwm%i write_period: Failed to write to period: %s", dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } close(period_f); dev->period = period; return MRAA_SUCCESS; }
mraa_result_t mraa_uart_set_baudrate(mraa_uart_context dev, unsigned int baud) { if (!dev) { syslog(LOG_ERR, "uart: set_baudrate: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, uart_set_baudrate_replace)) { return dev->advance_func->uart_set_baudrate_replace(dev, baud); } struct termios termio; if (tcgetattr(dev->fd, &termio)) { syslog(LOG_ERR, "uart%i: set_baudrate: tcgetattr() failed: %s", dev->index, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } // set our baud rates speed_t speed = uint2speed(baud); if (speed == B0) { syslog(LOG_ERR, "uart%i: set_baudrate: invalid baudrate: %i", dev->index, baud); return MRAA_ERROR_INVALID_PARAMETER; } cfsetispeed(&termio, speed); cfsetospeed(&termio, speed); // make it so if (tcsetattr(dev->fd, TCSAFLUSH, &termio) < 0) { syslog(LOG_ERR, "uart%i: set_baudrate: tcsetattr() failed: %s", dev->index, strerror(errno)); return MRAA_ERROR_FEATURE_NOT_SUPPORTED; } return MRAA_SUCCESS; }
int mraa_gpio_read(mraa_gpio_context dev) { if (dev == NULL) return -1; if (IS_FUNC_DEFINED(dev, gpio_read_replace)) return dev->advance_func->gpio_read_replace(dev); if (dev->mmap_read != NULL) return dev->mmap_read(dev); if (dev->value_fp == -1) { if (mraa_gpio_get_valfp(dev) != MRAA_SUCCESS) { syslog(LOG_ERR, "gpio: Failed to get value file pointer"); return -1; } } else { // if value_fp is new this is pointless lseek(dev->value_fp, 0, SEEK_SET); } char bu[2]; if (read(dev->value_fp, bu, 2 * sizeof(char)) != 2) { syslog(LOG_ERR, "gpio: Failed to read a sensible value from sysfs"); return -1; } lseek(dev->value_fp, 0, SEEK_SET); return (int) strtol(bu, NULL, 10); }
mraa_result_t mraa_spi_transfer_buf_word(mraa_spi_context dev, uint16_t* data, uint16_t* rxbuf, int length) { if (dev == NULL) { syslog(LOG_ERR, "spi: transfer_buf_word: context is invalid"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, spi_transfer_buf_word_replace)) { return dev->advance_func->spi_transfer_buf_word_replace(dev, data, rxbuf, length); } struct spi_ioc_transfer msg; memset(&msg, 0, sizeof(msg)); msg.tx_buf = (unsigned long) data; msg.rx_buf = (unsigned long) rxbuf; msg.speed_hz = dev->clock; msg.bits_per_word = dev->bpw; msg.delay_usecs = 0; msg.len = length; if (ioctl(dev->devfd, SPI_IOC_MESSAGE(1), &msg) < 0) { syslog(LOG_ERR, "spi: Failed to perform dev transfer"); return MRAA_ERROR_INVALID_RESOURCE; } return MRAA_SUCCESS; }
int mraa_spi_write_word(mraa_spi_context dev, uint16_t data) { if (dev == NULL) { syslog(LOG_ERR, "spi: write_word: context is invalid"); return -1; } if (IS_FUNC_DEFINED(dev, spi_write_word_replace)) { return dev->advance_func->spi_write_word_replace(dev, data); } struct spi_ioc_transfer msg; memset(&msg, 0, sizeof(msg)); uint16_t length = 2; uint16_t recv = 0; msg.tx_buf = (unsigned long) &data; msg.rx_buf = (unsigned long) &recv; msg.speed_hz = dev->clock; msg.bits_per_word = dev->bpw; msg.delay_usecs = 0; msg.len = length; if (ioctl(dev->devfd, SPI_IOC_MESSAGE(1), &msg) < 0) { syslog(LOG_ERR, "spi: Failed to perform dev transfer"); return -1; } return (int) recv; }
mraa_result_t mraa_pwm_write(mraa_pwm_context dev, float percentage) { if (!dev) { syslog(LOG_ERR, "pwm: write: context is NULL"); return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, pwm_write_pre)) { if (dev->advance_func->pwm_write_pre(dev, percentage) != MRAA_SUCCESS) { syslog(LOG_ERR, "mraa_pwm_write (pwm%i): pwm_write_pre failed, see syslog", dev->pin); return MRAA_ERROR_UNSPECIFIED; } } if (dev->period == -1) { if (mraa_pwm_read_period(dev) <= 0) return MRAA_ERROR_NO_DATA_AVAILABLE; } if (percentage > 1.0f) { syslog(LOG_WARNING, "pwm_write: %i%% entered, defaulting to 100%%",(int) percentage * 100); return mraa_pwm_write_duty(dev, dev->period); } return mraa_pwm_write_duty(dev, percentage * dev->period); }
mraa_result_t mraa_i2c_frequency(mraa_i2c_context dev, mraa_i2c_mode_t mode) { if (IS_FUNC_DEFINED(dev, i2c_set_frequency_replace)) { return dev->advance_func->i2c_set_frequency_replace(dev, mode); } return MRAA_ERROR_FEATURE_NOT_SUPPORTED; }
mraa_result_t mraa_gpio_use_mmaped(mraa_gpio_context dev, mraa_boolean_t 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"); return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; }
mraa_result_t mraa_gpio_write(mraa_gpio_context dev, int value) { if (dev == NULL) { syslog(LOG_ERR, "gpio: write: context is invalid"); return MRAA_ERROR_INVALID_HANDLE; } if (dev->mmap_write != NULL) return dev->mmap_write(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; } if (IS_FUNC_DEFINED(dev, gpio_write_replace)) { return dev->advance_func->gpio_write_replace(dev, value); } if (dev->value_fp == -1) { if (mraa_gpio_get_valfp(dev) != MRAA_SUCCESS) { return MRAA_ERROR_INVALID_RESOURCE; } } if (lseek(dev->value_fp, 0, SEEK_SET) == -1) { syslog(LOG_ERR, "gpio%i: write: Failed to lseek 'value': %s", dev->pin, strerror(errno)); return MRAA_ERROR_UNSPECIFIED; } char bu[MAX_SIZE]; int length = snprintf(bu, sizeof(bu), "%d", value); if (write(dev->value_fp, bu, length * sizeof(char)) == -1) { syslog(LOG_ERR, "gpio%i: write: Failed to write to 'value': %s", dev->pin, strerror(errno)); return MRAA_ERROR_UNSPECIFIED; } if (IS_FUNC_DEFINED(dev, gpio_write_post)) return dev->advance_func->gpio_write_post(dev, value); return MRAA_SUCCESS; }
uint16_t mraa_i2c_read_word_data(mraa_i2c_context dev, uint8_t command) { if (IS_FUNC_DEFINED(dev, i2c_read_word_data_replace)) return dev->advance_func->i2c_read_word_data_replace(dev, command); i2c_smbus_data_t d; if (mraa_i2c_smbus_access(dev->fh, I2C_SMBUS_READ, command, I2C_SMBUS_WORD_DATA, &d) < 0) { syslog(LOG_ERR, "i2c: Failed to write"); return 0; } return 0xFFFF & d.word; }
uint8_t mraa_i2c_read_byte(mraa_i2c_context dev) { if (IS_FUNC_DEFINED(dev, i2c_read_byte_replace)) return dev->advance_func->i2c_read_byte_replace(dev); i2c_smbus_data_t d; if (mraa_i2c_smbus_access(dev->fh, I2C_SMBUS_READ, I2C_NOCMD, I2C_SMBUS_BYTE, &d) < 0) { syslog(LOG_ERR, "i2c: Failed to write"); return 0; } return 0x0FF & d.byte; }
mraa_result_t mraa_gpio_edge_mode(mraa_gpio_context dev, mraa_gpio_edge_t mode) { if (dev == NULL) { syslog(LOG_ERR, "gpio: edge_mode: context is invalid"); return MRAA_ERROR_INVALID_HANDLE; } 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; } char filepath[MAX_SIZE]; snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/edge", dev->pin); int edge = open(filepath, O_RDWR); if (edge == -1) { syslog(LOG_ERR, "gpio%i: edge_mode: Failed to open 'edge' for writing: %s", dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } char bu[MAX_SIZE]; int length; switch (mode) { case MRAA_GPIO_EDGE_NONE: length = snprintf(bu, sizeof(bu), "none"); break; case MRAA_GPIO_EDGE_BOTH: length = snprintf(bu, sizeof(bu), "both"); break; case MRAA_GPIO_EDGE_RISING: length = snprintf(bu, sizeof(bu), "rising"); break; case MRAA_GPIO_EDGE_FALLING: length = snprintf(bu, sizeof(bu), "falling"); break; default: close(edge); return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; } if (write(edge, bu, length * sizeof(char)) == -1) { syslog(LOG_ERR, "gpio%i: edge_mode: Failed to write to 'edge': %s", dev->pin, strerror(errno)); close(edge); return MRAA_ERROR_UNSPECIFIED; } close(edge); return MRAA_SUCCESS; }
mraa_result_t mraa_i2c_write_byte(mraa_i2c_context dev, const uint8_t data) { if (IS_FUNC_DEFINED(dev, i2c_write_byte_replace)) { return dev->advance_func->i2c_write_byte_replace(dev, data); } else { if (mraa_i2c_smbus_access(dev->fh, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) < 0) { syslog(LOG_ERR, "i2c: Failed to write"); return MRAA_ERROR_INVALID_HANDLE; } return MRAA_SUCCESS; } }
mraa_result_t mraa_gpio_write(mraa_gpio_context dev, int value) { if (dev == NULL) return MRAA_ERROR_INVALID_HANDLE; if (dev->mmap_write != NULL) return dev->mmap_write(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; } if (IS_FUNC_DEFINED(dev, gpio_write_replace)) { return dev->advance_func->gpio_write_replace(dev, value); } if (dev->value_fp == -1) { if (mraa_gpio_get_valfp(dev) != MRAA_SUCCESS) { return MRAA_ERROR_INVALID_RESOURCE; } } if (lseek(dev->value_fp, 0, SEEK_SET) == -1) { return MRAA_ERROR_INVALID_RESOURCE; } char bu[MAX_SIZE]; int length = snprintf(bu, sizeof(bu), "%d", value); if (write(dev->value_fp, bu, length * sizeof(char)) == -1) { return MRAA_ERROR_INVALID_HANDLE; } if (IS_FUNC_DEFINED(dev, gpio_write_post)) return dev->advance_func->gpio_write_post(dev, value); return MRAA_SUCCESS; }
mraa_result_t mraa_i2c_write_word_data(mraa_i2c_context dev, const uint16_t data, const uint8_t command) { if (IS_FUNC_DEFINED(dev, i2c_write_word_data_replace)) return dev->advance_func->i2c_write_word_data_replace(dev, data, command); i2c_smbus_data_t d; d.word = data; if (mraa_i2c_smbus_access(dev->fh, I2C_SMBUS_WRITE, command, I2C_SMBUS_WORD_DATA, &d) < 0) { syslog(LOG_ERR, "i2c: Failed to write"); return MRAA_ERROR_INVALID_HANDLE; } return MRAA_SUCCESS; }
mraa_gpio_context mraa_gpio_init(int pin) { mraa_board_t* board = plat; if (board == NULL) { 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; if (board == NULL) { syslog(LOG_ERR, "gpio: Sub platform Not Initialised"); return NULL; } 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; } if (board->pins[pin].capabilites.gpio != 1) { syslog(LOG_ERR, "gpio: pin %i not capable of gpio", pin); return NULL; } if (board->pins[pin].gpio.mux_total > 0) { if (mraa_setup_mux_mapped(board->pins[pin].gpio) != MRAA_SUCCESS) { syslog(LOG_ERR, "gpio: unable to setup muxes"); return NULL; } } mraa_gpio_context r = mraa_gpio_init_internal(board->adv_func, board->pins[pin].gpio.pinmap); if (r == NULL) { syslog(LOG_CRIT, "gpio: mraa_gpio_init_raw(%d) returned error", pin); return NULL; } if (r->phy_pin == -1) r->phy_pin = pin; if (IS_FUNC_DEFINED(r, gpio_init_post)) { mraa_result_t ret = r->advance_func->gpio_init_post(r); if (ret != MRAA_SUCCESS) { free(r); return NULL; } } return r; }
mraa_pwm_context mraa_pwm_init_raw(int chipin, int pin) { mraa_pwm_context dev = mraa_pwm_init_internal(plat == NULL ? NULL : plat->adv_func , chipin, pin); if (dev == NULL) { syslog(LOG_CRIT, "pwm: Failed to allocate memory for context"); return NULL; } if (IS_FUNC_DEFINED(dev, pwm_init_raw_replace)) { if (dev->advance_func->pwm_init_raw_replace(dev, pin) == MRAA_SUCCESS) { return dev; } else { free(dev); return NULL; } } char directory[MAX_SIZE]; snprintf(directory, MAX_SIZE, SYSFS_PWM "/pwmchip%d/pwm%d", dev->chipid, dev->pin); struct stat dir; if (stat(directory, &dir) == 0 && S_ISDIR(dir.st_mode)) { syslog(LOG_NOTICE, "pwm_init: pwm%i already exported, continuing", pin); dev->owner = 0; // Not Owner } else { char buffer[MAX_SIZE]; snprintf(buffer, MAX_SIZE, "/sys/class/pwm/pwmchip%d/export", dev->chipid); int export_f = open(buffer, O_WRONLY); if (export_f == -1) { syslog(LOG_ERR, "pwm_init: pwm%i. Failed to open export for writing: %s", pin, strerror(errno)); free(dev); return NULL; } char out[MAX_SIZE]; int size = snprintf(out, MAX_SIZE, "%d", dev->pin); if (write(export_f, out, size * sizeof(char)) == -1) { syslog(LOG_WARNING, "pwm_init: pwm%i. Failed to write to export! (%s) Potentially already in use.", pin, strerror(errno)); close(export_f); free(dev); return NULL; } dev->owner = 1; mraa_pwm_period_us(dev, plat->pwm_default_period); close(export_f); } mraa_pwm_setup_duty_fp(dev); return dev; }