/* * Author: Dan O'Donovan * Copyright (c) 2015 Emutex Ltd. * Copyright (c) 2014 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 #include #include #include #include "common.h" #include "x86/up.h" #define PLATFORM_NAME "UP" #define I2C_BUS_DEFAULT 1 #define MAX_LENGTH 8 #define I2CNAME "designware" static mraa_result_t set_pininfo(mraa_board_t* board, int mraa_index, char* name, mraa_pincapabilities_t caps, int sysfs_pin) { if (mraa_index < board->phy_pin_count) { mraa_pininfo_t* pin_info = &board->pins[mraa_index]; strncpy(pin_info->name, name, MAX_LENGTH); pin_info->capabilites = caps; if (caps.gpio) { pin_info->gpio.pinmap = sysfs_pin; pin_info->gpio.mux_total = 0; } if (caps.i2c) { pin_info->i2c.pinmap = 1; pin_info->i2c.mux_total = 0; } if (caps.pwm) { int controller = 0; if (strncmp(name, "PWM", 3) == 0 && strlen(name) > 3 && isdigit(name[3])) controller = name[3] - '0'; pin_info->pwm.parent_id = controller; pin_info->pwm.pinmap = 0; pin_info->pwm.mux_total = 0; } if (caps.spi) { pin_info->spi.mux_total = 0; } return MRAA_SUCCESS; } return MRAA_ERROR_INVALID_RESOURCE; } static mraa_result_t get_pin_index(mraa_board_t* board, char* name, int* pin_index) { int i; for (i = 0; i < board->phy_pin_count; ++i) { if (strncmp(name, board->pins[i].name, MAX_LENGTH) == 0) { *pin_index = i; return MRAA_SUCCESS; } } return MRAA_ERROR_INVALID_RESOURCE; } mraa_board_t* mraa_up_board() { mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); struct utsname running_uname; int uname_major, uname_minor, max_pins[27]; if (b == NULL) { return NULL; } b->platform_name = PLATFORM_NAME; b->phy_pin_count = MRAA_UP_PINCOUNT; b->gpio_count = MRAA_UP_GPIOCOUNT; b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_UP_PINCOUNT); if (b->pins == NULL) { 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; } sscanf(running_uname.release, "%d.%d", &uname_major, &uname_minor); set_pininfo(b, 0, "INVALID", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 1, "3.3v", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 2, "5v", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 3, "I2C1_SDA", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }, 2); set_pininfo(b, 4, "5v", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 5, "I2C1_SCL", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }, 3); set_pininfo(b, 6, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 7, "GPIO4", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 4); set_pininfo(b, 8, "UART1_TX", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }, 14); set_pininfo(b, 9, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 10, "UART1_RX", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }, 15); set_pininfo(b, 11, "GPIO17", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 17); set_pininfo(b, 12, "I2S_CLK", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 18); set_pininfo(b, 13, "UART2_RX", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 1 }, 27); set_pininfo(b, 14, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 15, "GPIO22", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }, 22); set_pininfo(b, 16, "GPIO23", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 23); set_pininfo(b, 17, "3.3v", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 18, "GPIO24", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 24); set_pininfo(b, 19, "SPI_MOSI", (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }, 10); set_pininfo(b, 20, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 21, "SPI_MISO", (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }, 9); set_pininfo(b, 22, "UART2_TX", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }, 25); set_pininfo(b, 23, "SPI_CLK", (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }, 11); set_pininfo(b, 24, "SPI_CS0", (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }, 8); set_pininfo(b, 25, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 26, "SPI_CS1", (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }, 7); set_pininfo(b, 27, "ID_SD", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }, 0); set_pininfo(b, 28, "ID_SC", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }, 1); set_pininfo(b, 29, "GPIO5", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 5); set_pininfo(b, 30, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 31, "GPIO6", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 6); set_pininfo(b, 32, "PWM0", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, 12); set_pininfo(b, 33, "PWM1", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, 13); set_pininfo(b, 34, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 35, "I2S_FRM", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 19); set_pininfo(b, 36, "GPIO16", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 16); set_pininfo(b, 37, "GPIO26", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 26); set_pininfo(b, 38, "I2S_DIN", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 20); set_pininfo(b, 39, "GND", (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }, -1); set_pininfo(b, 40, "I2S_DOUT", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, 21); // Set number of i2c adaptors usable from userspace b->i2c_bus_count = 2; // Configure i2c adaptor #0 (default) // (For consistency with Raspberry Pi 2, use I2C1 as our primary I2C bus) b->i2c_bus[0].bus_id = 1; get_pin_index(b, "I2C1_SDA", &(b->i2c_bus[0].sda)); get_pin_index(b, "I2C1_SCL", &(b->i2c_bus[0].scl)); // Configure i2c adaptor #1 // (normally reserved for accessing HAT EEPROM) b->i2c_bus[1].bus_id = 0; get_pin_index(b, "I2C0_SDA", &(b->i2c_bus[1].sda)); get_pin_index(b, "I2C0_SCL", &(b->i2c_bus[1].scl)); b->def_i2c_bus = 0; // Configure PWM b->pwm_default_period = 500; b->pwm_max_period = 3413; b->pwm_min_period = 1; // Configure SPI #0 CS0 (default) b->spi_bus_count = 2; b->spi_bus[0].bus_id = 2; b->spi_bus[0].slave_s = 0; get_pin_index(b, "SPI_CS0", &(b->spi_bus[0].cs)); get_pin_index(b, "SPI_MOSI", &(b->spi_bus[0].mosi)); get_pin_index(b, "SPI_MISO", &(b->spi_bus[0].miso)); get_pin_index(b, "SPI_CLK", &(b->spi_bus[0].sclk)); b->def_spi_bus = 0; // Configure SPI #0 CS1 b->spi_bus[1].bus_id = 2; b->spi_bus[1].slave_s = 1; get_pin_index(b, "SPI_CS1", &(b->spi_bus[1].cs)); get_pin_index(b, "SPI_MOSI", &(b->spi_bus[1].mosi)); get_pin_index(b, "SPI_MISO", &(b->spi_bus[1].miso)); get_pin_index(b, "SPI_CLK", &(b->spi_bus[1].sclk)); // Configure UART #1 (default) b->uart_dev_count = 2; get_pin_index(b, "UART1_RX", &(b->uart_dev[0].rx)); get_pin_index(b, "UART1_TX", &(b->uart_dev[0].tx)); b->uart_dev[0].device_path = "/dev/ttyS1"; b->def_uart_dev = 0; // Configure UART #2 get_pin_index(b, "UART2_RX", &(b->uart_dev[1].rx)); get_pin_index(b, "UART2_TX", &(b->uart_dev[1].tx)); b->uart_dev[1].device_path = "/dev/ttyS2"; return b; error: syslog(LOG_CRIT, "up: Platform failed to initialise"); free(b); return NULL; }