#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <linux/spi/spidev.h>
#include "common.h"
#include "x86/intel_edison_fab_c.h"
#define PLATFORM_NAME "Intel Edison"
#define SYSFS_CLASS_GPIO "/sys/class/gpio"
-#define SYSFS_PINMODE_PATH "/sys/kernel/debug/gpio_debug/gpio"
+#define DEBUGFS_PINMODE_PATH "/sys/kernel/debug/gpio_debug/gpio"
#define MAX_SIZE 64
#define MAX_MODE_SIZE 8
static int mmap_size;
static unsigned int mmap_count = 0;
+mraa_result_t
+mraa_intel_edison_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb)
+{
+ uint8_t lsb_mode = (uint8_t) lsb;
+
+ // Edison doesn't support LSB_FIRST, we need to react appropriately
+ if (!lsb) {
+ if (ioctl(dev->devfd, SPI_IOC_WR_LSB_FIRST, &lsb_mode) < 0) {
+ syslog(LOG_ERR, "spi: Failed to set bit order");
+ return MRAA_ERROR_INVALID_RESOURCE;
+ }
+ if (ioctl(dev->devfd, SPI_IOC_RD_LSB_FIRST, &lsb_mode) < 0) {
+ syslog(LOG_ERR, "spi: Failed to set bit order");
+ return MRAA_ERROR_INVALID_RESOURCE;
+ }
+ } else {
+ return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
+ }
+
+ dev->lsb = lsb;
+ return MRAA_SUCCESS;
+}
+
static mraa_result_t
mraa_intel_edison_pinmode_change(int sysfs, int mode)
{
}
char buffer[MAX_SIZE];
- snprintf(buffer, MAX_SIZE, SYSFS_PINMODE_PATH "%i/current_pinmux", sysfs);
+ int useDebugFS = 0;
+
+ mraa_gpio_context mode_gpio = mraa_gpio_init_raw(sysfs);
+ if (mode_gpio == NULL) {
+ return MRAA_ERROR_NO_RESOURCES;
+ }
+
+ // first try SYSFS_CLASS_GPIO path
+ snprintf(buffer, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%i/pinmux", sysfs);
int modef = open(buffer, O_WRONLY);
if (modef == -1) {
+ snprintf(buffer, MAX_SIZE, DEBUGFS_PINMODE_PATH "%i/current_pinmux", sysfs);
+ modef = open(buffer, O_WRONLY);
+ useDebugFS = 1;
+ }
+
+ if (modef == -1) {
syslog(LOG_ERR, "edison: Failed to open SoC pinmode for opening");
+ mraa_gpio_close(mode_gpio);
return MRAA_ERROR_INVALID_RESOURCE;
}
mraa_result_t ret = MRAA_SUCCESS;
char mode_buf[MAX_MODE_SIZE];
- int length = sprintf(mode_buf, "mode%u", mode);
+ int length = sprintf(mode_buf, "%s%u", useDebugFS ? "mode" : "", mode);
if (write(modef, mode_buf, length * sizeof(char)) == -1) {
ret = MRAA_ERROR_INVALID_RESOURCE;
}
close(modef);
+ mraa_gpio_close(mode_gpio);
return ret;
}
mraa_result_t
-mraa_intel_edison_gpio_dir_pre(mraa_gpio_context dev, gpio_dir_t dir)
+mraa_intel_edison_gpio_dir_pre(mraa_gpio_context dev, mraa_gpio_dir_t dir)
{
if (dev->phy_pin >= 0) {
}
mraa_result_t
-mraa_intel_edison_gpio_dir_post(mraa_gpio_context dev, gpio_dir_t dir)
+mraa_intel_edison_gpio_dir_post(mraa_gpio_context dev, mraa_gpio_dir_t dir)
{
if (dev->phy_pin >= 0) {
return mraa_gpio_write(tristate, 1);
static mraa_result_t
mraa_intel_edison_misc_spi()
{
- mraa_gpio_write(tristate, 0);
+ // These arrays must have same length
+ static const int gpio_pin_list[] = {263, 240, 262, 241, 242, 243};
+ static int pin_num = sizeof(gpio_pin_list) / sizeof(int);
+ static const int gpio_val_list[] = {1, 0, 1, 0, 0, 0};
+ static const int gpio_dir_list[] = {MRAA_GPIO_OUT, MRAA_GPIO_OUT,
+ MRAA_GPIO_OUT, MRAA_GPIO_OUT,
+ MRAA_GPIO_OUT, MRAA_GPIO_OUT};
+ int i;
+ mraa_result_t ret;
- mraa_gpio_context io10_p1 = mraa_gpio_init_raw(263);
- mraa_gpio_context io10_p2 = mraa_gpio_init_raw(240);
- mraa_gpio_context io11_p1 = mraa_gpio_init_raw(262);
- mraa_gpio_context io11_p2 = mraa_gpio_init_raw(241);
- mraa_gpio_context io12_p1 = mraa_gpio_init_raw(242);
- mraa_gpio_context io13_p1 = mraa_gpio_init_raw(243);
- mraa_gpio_dir(io10_p1, MRAA_GPIO_OUT);
- mraa_gpio_dir(io10_p2, MRAA_GPIO_OUT);
- mraa_gpio_dir(io11_p1, MRAA_GPIO_OUT);
- mraa_gpio_dir(io11_p2, MRAA_GPIO_OUT);
- mraa_gpio_dir(io12_p1, MRAA_GPIO_OUT);
- mraa_gpio_dir(io13_p1, MRAA_GPIO_OUT);
-
- mraa_gpio_write(io10_p1, 1);
- mraa_gpio_write(io10_p2, 0);
- mraa_gpio_write(io11_p1, 1);
- mraa_gpio_write(io11_p2, 0);
- mraa_gpio_write(io12_p1, 0);
- mraa_gpio_write(io13_p1, 0);
-
- mraa_gpio_close(io10_p1);
- mraa_gpio_close(io10_p2);
- mraa_gpio_close(io11_p1);
- mraa_gpio_close(io11_p2);
- mraa_gpio_close(io12_p1);
- mraa_gpio_close(io13_p1);
-
- mraa_intel_edison_pinmode_change(115, 1);
- mraa_intel_edison_pinmode_change(114, 1);
- mraa_intel_edison_pinmode_change(109, 1);
- mraa_gpio_write(tristate, 1);
+ MRAA_RETURN_FOR_ERROR(mraa_gpio_write(tristate, 0));
+
+ for (i = 0; i < pin_num; i++) {
+ mraa_gpio_context io = mraa_gpio_init_raw(gpio_pin_list[i]);
+ if (io != NULL) {
+ ret = mraa_gpio_dir(io, gpio_dir_list[i]);
+ if (ret == MRAA_SUCCESS) {
+ ret = mraa_gpio_write(io, gpio_val_list[i]);
+ }
+
+ //Don't care return value of close()
+ mraa_gpio_close(io);
+ MRAA_RETURN_FOR_ERROR(ret);
+ } else {
+ syslog(LOG_ERR, "edison: Failed to init raw gpio %d!",gpio_pin_list[i]);
+ return MRAA_ERROR_NO_RESOURCES;
+ }
+ }
+
+ MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(115, 1));
+ MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(114, 1));
+ MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(109, 1));
+ MRAA_RETURN_FOR_ERROR(mraa_gpio_write(tristate, 1));
return MRAA_SUCCESS;
}
}
mraa_result_t
-mraa_intel_edison_gpio_mode_replace(mraa_gpio_context dev, gpio_mode_t mode)
+mraa_intel_edison_gpio_mode_replace(mraa_gpio_context dev, mraa_gpio_mode_t mode)
{
if (dev->value_fp != -1) {
if (close(dev->value_fp) != 0) {
}
mraa_result_t
-mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev, gpio_mode_t mode)
+mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode)
{
if (dev->value_fp != -1) {
if (close(dev->value_fp) != 0) {
}
char filepath[MAX_SIZE];
- snprintf(filepath, MAX_SIZE, SYSFS_PINMODE_PATH "%d/current_pullmode", dev->pin);
+ mraa_gpio_context mode_gpio = mraa_gpio_init_raw(dev->pin);
+ if (mode_gpio == NULL) {
+ return MRAA_ERROR_NO_RESOURCES;
+ }
+
+ // first try SYSFS_CLASS_GPIO path
+ snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/pullmode", dev->pin);
int drive = open(filepath, O_WRONLY);
+
+ if (drive == -1) {
+ snprintf(filepath, MAX_SIZE, DEBUGFS_PINMODE_PATH "%d/current_pullmode", dev->pin);
+ drive = open(filepath, O_WRONLY);
+ }
+
if (drive == -1) {
syslog(LOG_ERR, "edison: Failed to open drive for writing");
+ mraa_gpio_close(mode_gpio);
return MRAA_ERROR_INVALID_RESOURCE;
}
int length;
switch (mode) {
case MRAA_GPIO_STRONG:
+ mraa_gpio_close(mode_gpio);
close(drive);
return MRAA_SUCCESS;
case MRAA_GPIO_PULLUP:
length = snprintf(bu, sizeof(bu), "nopull");
break;
default:
+ mraa_gpio_close(mode_gpio);
close(drive);
return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
}
if (write(drive, bu, length * sizeof(char)) == -1) {
syslog(LOG_ERR, "edison: Failed to write to drive mode");
+ mraa_gpio_close(mode_gpio);
close(drive);
return MRAA_ERROR_INVALID_RESOURCE;
}
+ mraa_gpio_close(mode_gpio);
if (close(drive) != 0) {
return MRAA_ERROR_INVALID_RESOURCE;
}
mraa_result_t
mraa_intel_edison_uart_init_pre(int index)
{
+ if (index != 0) {
+ syslog(LOG_ERR, "edison: Failed to write to drive mode");
+ return MRAA_ERROR_INVALID_RESOURCE;
+ }
if (miniboard == 0) {
mraa_gpio_write(tristate, 0);
mraa_gpio_context io0_output = mraa_gpio_init_raw(248);
}
struct stat fd_stat;
- fstat(mmap_fd, &fd_stat);
+ if (fstat(mmap_fd, &fd_stat) != 0) {
+ syslog(LOG_ERR, "edison map: unable to access resource0 file");
+ return MRAA_ERROR_INVALID_HANDLE;
+ }
mmap_size = fd_stat.st_size;
mmap_reg =
return MRAA_ERROR_UNSPECIFIED;
}
- advance_func->gpio_init_post = &mraa_intel_edison_gpio_init_post;
-
- advance_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre;
- advance_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre;
- advance_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq;
- advance_func->spi_init_pre = &mraa_intel_edison_spi_init_pre;
- advance_func->gpio_mode_replace = &mraa_intel_edsion_mb_gpio_mode;
- advance_func->uart_init_pre = &mraa_intel_edison_uart_init_pre;
- advance_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup;
+ 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;
+ }
+ 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);
mraa_board_t*
mraa_intel_edison_fab_c()
{
- 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->gpio_count = 14;
b->aio_count = 6;
- advance_func->gpio_dir_pre = &mraa_intel_edison_gpio_dir_pre;
- advance_func->gpio_init_post = &mraa_intel_edison_gpio_init_post;
- advance_func->gpio_close_pre = &mraa_intel_edison_gpio_close_pre;
- advance_func->gpio_dir_post = &mraa_intel_edison_gpio_dir_post;
- advance_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre;
- advance_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq;
- advance_func->aio_get_valid_fp = &mraa_intel_edison_aio_get_fp;
- advance_func->aio_init_pre = &mraa_intel_edison_aio_init_pre;
- advance_func->aio_init_post = &mraa_intel_edison_aio_init_post;
- advance_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre;
- advance_func->pwm_init_post = &mraa_intel_edison_pwm_init_post;
- advance_func->spi_init_pre = &mraa_intel_edison_spi_init_pre;
- advance_func->spi_init_post = &mraa_intel_edison_spi_init_post;
- advance_func->gpio_mode_replace = &mraa_intel_edison_gpio_mode_replace;
- advance_func->uart_init_pre = &mraa_intel_edison_uart_init_pre;
- advance_func->uart_init_post = &mraa_intel_edison_uart_init_post;
- advance_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup;
+ b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
+ if (b->adv_func == NULL) {
+ goto error;
+ }
+ 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;
}