From 56ba08a98f03f20ba5a84c5f8ed525e8cc9679f5 Mon Sep 17 00:00:00 2001 From: Michael Ring Date: Tue, 31 Mar 2015 22:44:55 +0200 Subject: [PATCH] banana: Add bananapi support Signed-off-by: Michael Ring Signed-off-by: Brendan Le Foll --- api/mraa/types.h | 1 + include/arm/banana.h | 41 +++ src/arm/CMakeLists.txt | 1 + src/arm/arm.c | 16 ++ src/arm/banana.c | 570 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 629 insertions(+) create mode 100644 include/arm/banana.h create mode 100644 src/arm/banana.c diff --git a/api/mraa/types.h b/api/mraa/types.h index d7554d7..52fa312 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -44,6 +44,7 @@ typedef enum { MRAA_INTEL_MINNOWBOARD_MAX = 4, /**< The Intel Minnow Board Max */ MRAA_RASPBERRY_PI = 5, /**< The different Raspberry PI Models -like A,B,A+,B+ */ MRAA_BEAGLEBONE = 6, /**< The different BeagleBone Black Modes B/C */ + MRAA_BANANA = 7, /**< Allwinner A20 based Banana Pi and Banana Pro */ MRAA_UNKNOWN_PLATFORM = 99 /**< An unknown platform type, typically will load INTEL_GALILEO_GEN1 */ diff --git a/include/arm/banana.h b/include/arm/banana.h new file mode 100644 index 0000000..3c25cfa --- /dev/null +++ b/include/arm/banana.h @@ -0,0 +1,41 @@ +/* + * Author: Thomas Ingleby + * Author: Michael Ring + * 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. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa_internal.h" + +#define MRAA_BANANA_PI_PINCOUNT 35 +#define MRAA_BANANA_PRO_PINCOUNT 41 + +mraa_board_t* mraa_banana(); + +#ifdef __cplusplus +} +#endif diff --git a/src/arm/CMakeLists.txt b/src/arm/CMakeLists.txt index d9017fd..973dc5a 100644 --- a/src/arm/CMakeLists.txt +++ b/src/arm/CMakeLists.txt @@ -3,5 +3,6 @@ set (mraa_LIB_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO} ${PROJECT_SOURCE_DIR}/src/arm/arm.c ${PROJECT_SOURCE_DIR}/src/arm/raspberry_pi.c ${PROJECT_SOURCE_DIR}/src/arm/beaglebone.c + ${PROJECT_SOURCE_DIR}/src/arm/banana.c PARENT_SCOPE ) diff --git a/src/arm/arm.c b/src/arm/arm.c index 7278418..e74e1cc 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -29,6 +29,7 @@ #include "mraa_internal.h" #include "arm/raspberry_pi.h" #include "arm/beaglebone.h" +#include "arm/banana.h" mraa_platform_t mraa_arm_platform() @@ -49,6 +50,18 @@ mraa_arm_platform() if (strstr(line, "Generic AM33XX")) { platform_type = MRAA_BEAGLEBONE; } + if (strstr(line, "sun7i")) { + if (mraa_file_contains("/sys/firmware/devicetree/base/model", "Banana Pro")) { + platform_type = MRAA_BANANA; + } + if (mraa_file_contains("/sys/firmware/devicetree/base/model", "Banana Pi")) { + platform_type = MRAA_BANANA; + } + // For old kernels + if (mraa_file_exist("/sys/class/leds/green:ph24:led1")) { + platform_type = MRAA_BANANA; + } + } } } fclose(fh); @@ -62,6 +75,9 @@ mraa_arm_platform() case MRAA_BEAGLEBONE: plat = mraa_beaglebone(); break; + case MRAA_BANANA: + plat = mraa_banana(); + break; default: plat = NULL; syslog(LOG_ERR, "Unknown Platform, currently not supported by MRAA"); diff --git a/src/arm/banana.c b/src/arm/banana.c new file mode 100644 index 0000000..7d79b00 --- /dev/null +++ b/src/arm/banana.c @@ -0,0 +1,570 @@ +/* + * Author: Thomas Ingleby + * Author: Michael Ring + * 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 + +#include "common.h" +#include "arm/banana.h" + +#define PLATFORM_NAME_BANANA_PI "Banana Pi" +#define PLATFORM_BANANA_PI 1 +#define PLATFORM_NAME_BANANA_PRO "Banana Pro" +#define PLATFORM_BANANA_PRO 2 +#define MMAP_PATH "/dev/mem" +#define DT_BASE "/sys/firmware/devicetree/base" + +#define SUNXI_BASE (0x01C20000) +#define SUNXI_BLOCK_SIZE (4 * 1024) +#define SUNXI_GPIO_DAT 0x0810 +#define SUNXI_GPIO_PORT_OFFSET 0x0024 +#define MAX_SIZE 64 + +// MMAP +static uint8_t* mmap_reg = NULL; +static int mmap_fd = 0; +static int mmap_size; +static unsigned int mmap_count = 0; +static int platform_detected = 0; + +const char* serialdev[] = { "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3", + "/dev/ttyS4", "/dev/ttyS5", "/dev/ttyS6", "/dev/ttyS7" }; +const char* seriallink[] = { "/sys/class/tty/ttyS0", "/sys/class/tty/ttyS1", "/sys/class/tty/ttyS2", + "/sys/class/tty/ttyS3", "/sys/class/tty/ttyS4", "/sys/class/tty/ttyS5", + "/sys/class/tty/ttyS6", "/sys/class/tty/ttyS7" }; +const char* i2clink[] = { + "/sys/class/i2c-dev/i2c-0", "/sys/class/i2c-dev/i2c-1", "/sys/class/i2c-dev/i2c-2", + "/sys/class/i2c-dev/i2c-3", "/sys/class/i2c-dev/i2c-4", +}; +const char* spilink[] = { "/sys/class/spidev/i2c-0", + "/sys/class/spidev/i2c-1", + "/sys/class/spidev/i2c-2", + "/sys/class/spidev/i2c-3" }; + +mraa_result_t +mraa_banana_spi_init_pre(int index) +{ + char devpath[MAX_SIZE]; + sprintf(devpath, "/dev/spidev%u.0", plat->spi_bus[index].bus_id); + if (!mraa_file_exist(devpath)) { + syslog(LOG_INFO, "spi: trying modprobe for spi-sun4i"); + system("modprobe spi-sun4i >/dev/null 2>&1"); + syslog(LOG_INFO, "spi: trying modprobe for spidev"); + system("modprobe spidev >/dev/null 2>&1"); + } + if (!mraa_file_exist(devpath)) { + syslog(LOG_ERR, "spi: Device not initialized"); + syslog(LOG_ERR, "spi: If you run a kernel >=3.18 then most likely spi support does not yet " + "fully work."); + return MRAA_ERROR_NO_RESOURCES; + } + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_banana_i2c_init_pre(unsigned int bus) +{ + char devpath[MAX_SIZE]; + sprintf(devpath, "/dev/i2c-%u", bus); + if (!mraa_file_exist(devpath)) { + syslog(LOG_INFO, "i2c: trying modprobe for i2c-dev"); + system("modprobe i2c-dev >/dev/null 2>&1"); + } + if (!mraa_file_exist(devpath)) { + syslog(LOG_ERR, "i2c: Device not initialized"); + return MRAA_ERROR_NO_RESOURCES; + } + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_banana_mmap_write(mraa_gpio_context dev, int value) +{ + uint32_t readvalue = + *(volatile uint32_t*) (mmap_reg + SUNXI_GPIO_DAT + (dev->pin / 32) * SUNXI_GPIO_PORT_OFFSET); + volatile uint32_t* addr; + if (value) { + *(volatile uint32_t*) (mmap_reg + SUNXI_GPIO_DAT + (dev->pin / 32) * SUNXI_GPIO_PORT_OFFSET) = + (uint32_t)((1 << (dev->pin % 32)) | readvalue); + } else { + *(volatile uint32_t*) (mmap_reg + SUNXI_GPIO_DAT + (dev->pin / 32) * SUNXI_GPIO_PORT_OFFSET) = + (uint32_t)(~(1 << (dev->pin % 32)) & readvalue); + } + return MRAA_SUCCESS; +} + +int +mraa_banana_mmap_read(mraa_gpio_context dev) +{ + uint32_t value = + *(volatile uint32_t*) (mmap_reg + SUNXI_GPIO_DAT + (dev->pin / 32) * SUNXI_GPIO_PORT_OFFSET); + if (value & (uint32_t)(1 << (dev->pin % 32))) { + return 1; + } + return 0; +} + +static mraa_result_t +mraa_banana_mmap_unsetup() +{ + if (mmap_reg == NULL) { + syslog(LOG_ERR, "banana mmap: cannot unsetup NULLed mmap"); + return MRAA_ERROR_INVALID_RESOURCE; + } + munmap(mmap_reg, mmap_size); + mmap_reg = NULL; + if (close(mmap_fd) != 0) { + return MRAA_ERROR_INVALID_RESOURCE; + } + return MRAA_SUCCESS; +} + +mraa_result_t +mraa_banana_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en) +{ + if (dev == NULL) { + syslog(LOG_ERR, "Banana mmap: context not valid"); + return MRAA_ERROR_INVALID_HANDLE; + } + + if (en == 0) { + if (dev->mmap_write == NULL && dev->mmap_read == NULL) { + syslog(LOG_ERR, "Banana mmap: can't disable disabled mmap gpio"); + return MRAA_ERROR_INVALID_PARAMETER; + } + dev->mmap_write = NULL; + dev->mmap_read = NULL; + mmap_count--; + if (mmap_count == 0) { + return mraa_banana_mmap_unsetup(); + } + return MRAA_SUCCESS; + } + + if (dev->mmap_write != NULL && dev->mmap_read != NULL) { + syslog(LOG_ERR, "Banana mmap: can't enable enabled mmap gpio"); + return MRAA_ERROR_INVALID_PARAMETER; + } + + // Might need to make some elements of this thread safe. + // For example only allow one thread to enter the following block + // to prevent mmap'ing twice. + if (mmap_reg == NULL) { + if ((mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) { + syslog(LOG_ERR, "Banana mmap: unable to open /dev/mem file"); + return MRAA_ERROR_INVALID_HANDLE; + } + + mmap_reg = (uint8_t*) mmap(NULL, SUNXI_BLOCK_SIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, mmap_fd, SUNXI_BASE); + if (mmap_reg == MAP_FAILED) { + syslog(LOG_ERR, "Banana mmap: failed to mmap"); + mmap_reg = NULL; + close(mmap_fd); + return MRAA_ERROR_NO_RESOURCES; + } + } + dev->mmap_write = &mraa_banana_mmap_write; + dev->mmap_read = &mraa_banana_mmap_read; + mmap_count++; + + return MRAA_SUCCESS; +} + +mraa_board_t* +mraa_banana() +{ + mraa_board_t* b = (mraa_board_t*) malloc(sizeof(mraa_board_t)); + if (b == NULL) { + return NULL; + } + + platform_detected = 0; + int i2c2 = -1; + int spi0 = -1; + int uart2 = -1; + int uart3 = -1; + int uart4 = -1; + int uart7 = -1; + + if (mraa_file_exist(DT_BASE "/model")) { + // We are on a modern kernel, great!!!! + if (mraa_file_contains(DT_BASE "/model", "Banana Pro")) { + b->platform_name = PLATFORM_NAME_BANANA_PRO; + platform_detected = PLATFORM_BANANA_PRO; + b->phy_pin_count = MRAA_BANANA_PRO_PINCOUNT; + } + + if (mraa_file_contains(DT_BASE "/model", "Banana Pi")) { + b->platform_name = PLATFORM_NAME_BANANA_PI; + platform_detected = PLATFORM_BANANA_PI; + b->phy_pin_count = MRAA_BANANA_PI_PINCOUNT; + } + if (mraa_file_contains(DT_BASE "/soc@01c00000/i2c@01c2b400/status", "okay")) { + i2c2 = 1; + } + if (mraa_file_contains(DT_BASE "/soc@01c00000/spi@01c05000/status", "okay")) { + spi0 = 1; + } + } else { + if (mraa_file_exist("/sys/class/leds/green:ph24:led1")) { + if (mraa_file_exist("/sys/class/leds/blue:pg02:led2")) { + b->platform_name = PLATFORM_NAME_BANANA_PRO; + platform_detected = PLATFORM_BANANA_PRO; + b->phy_pin_count = MRAA_BANANA_PRO_PINCOUNT; + } else { + b->platform_name = PLATFORM_NAME_BANANA_PI; + platform_detected = PLATFORM_BANANA_PI; + b->phy_pin_count = MRAA_BANANA_PI_PINCOUNT; + } + if (mraa_file_exist("/sys/class/i2c-dev/i2c-2")) { + i2c2 = 1; + } + + + if (mraa_file_exist("/sys/class/spi_master/spi0")) { + spi0 = 1; + } + } + } + + if (platform_detected == 0) { + syslog(LOG_ERR, "mraa: Could not detect Banana Pi or Banana Pro"); + return NULL; + } + + int devnum; + for (devnum = 0; devnum < 8; devnum++) { + if (mraa_link_targets(seriallink[devnum], "1c28800")) { + uart2 = devnum; + } + if (mraa_link_targets(seriallink[devnum], "1c28c00")) { + uart3 = devnum; + } + if (mraa_link_targets(seriallink[devnum], "1c29000")) { + uart4 = devnum; + } + if (mraa_link_targets(seriallink[devnum], "1c29c00")) { + uart7 = devnum; + } + } + + for (devnum = 0; devnum < 5; devnum++) { + if (mraa_link_targets(i2clink[devnum], "1c2b400")) { + i2c2 = devnum; + } + } + + for (devnum = 0; devnum < 4; devnum++) { + if (mraa_link_targets(spilink[devnum], "1c05000")) { + spi0 = devnum; + } + } + + b->pins = (mraa_pininfo_t*) calloc(b->phy_pin_count, sizeof(mraa_pininfo_t)); + + 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; + + strncpy(b->pins[0].name, "INVALID", 8); + b->pins[0].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[1].name, "3V3", 8); + b->pins[1].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[2].name, "5V", 8); + b->pins[2].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (i2c2 == 1) { + strncpy(b->pins[3].name, "TWI2-SDA", 8); // PB21 Pin53 TWI2-SDA + b->pins[3].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }; + } else { + strncpy(b->pins[3].name, "PB21", 8); // PB21 Pin53 TWI2-SDA + b->pins[3].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + } + b->pins[3].gpio.pinmap = 53; + + strncpy(b->pins[4].name, "5V", 8); + b->pins[4].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (i2c2 == 1) { + strncpy(b->pins[5].name, "TWI2-SCK", 8); // PB20 Pin52 TWI2-SCK + b->pins[5].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }; + } else { + strncpy(b->pins[5].name, "PB20", 8); // PB20 Pin52 TWI2-SCK + b->pins[5].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + } + b->pins[5].gpio.pinmap = 52; + + strncpy(b->pins[6].name, "GND", 8); + b->pins[6].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[7].name, "PH02", 8); // PH2 Pin226 + b->pins[7].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[7].gpio.pinmap = 226; + + if (platform_detected == PLATFORM_BANANA_PRO) { + strncpy(b->pins[8].name, "UART4_TX", 8); // PH4 Pin228 UART4_TX + b->pins[8].gpio.pinmap = 228; + } else { + strncpy(b->pins[8].name, "UART3_TX", 8); // PH0 Pin224 UART3_TX + b->pins[8].gpio.pinmap = 224; + } + b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + + strncpy(b->pins[9].name, "GND", 8); + b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (platform_detected == PLATFORM_BANANA_PRO) { + strncpy(b->pins[10].name, "UART4_RX", 8); // PH5 Pin229 UART4_RX + b->pins[10].gpio.pinmap = 229; + } else { + strncpy(b->pins[10].name, "UART3_RX", 8); // PH1 Pin225 UART3_RX + b->pins[10].gpio.pinmap = 225; + } + b->pins[10].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + + strncpy(b->pins[11].name, "PI19", 8); // PI19 Pin275 IO+UART2_RX + b->pins[11].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[11].gpio.pinmap = 275; + + strncpy(b->pins[12].name, "PI03", 8); // PI3 Pin259 PWM + b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + b->pins[12].gpio.pinmap = 259; + + strncpy(b->pins[13].name, "PI18", 8); // PI18 Pin274 UART2_TX + b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[13].gpio.pinmap = 274; + + strncpy(b->pins[14].name, "GND", 8); + b->pins[14].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[15].name, "PI17", 8); // PI17 Pin273 UART2_CTS + b->pins[15].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[15].gpio.pinmap = 273; + + strncpy(b->pins[16].name, "PH20", 8); // PH20 Pin 244 CAN_TX + b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[16].gpio.pinmap = 244; + + strncpy(b->pins[17].name, "3V3", 8); + b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[18].name, "PH21", 8); // PH21 Pin245 CAN_RX + b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[18].gpio.pinmap = 245; + + strncpy(b->pins[19].name, "SPI0MOSI", 8); // PI12 SPI0 + b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[19].gpio.pinmap = 268; + + strncpy(b->pins[20].name, "GND", 8); + b->pins[20].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[21].name, "SPI0MISO", 8); // PI13 SPI0 + b->pins[21].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[21].gpio.pinmap = 269; + + strncpy(b->pins[22].name, "PI16", 8); // PI16 UART2_RTS + b->pins[22].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[22].gpio.pinmap = 272; + + strncpy(b->pins[23].name, "SPI0CLK", 8); // PI11 SPI0 + b->pins[23].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[23].gpio.pinmap = 267; + + strncpy(b->pins[24].name, "SPI0CS0", 8); // PI10 SPI0 + b->pins[24].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[24].gpio.pinmap = 266; + + strncpy(b->pins[25].name, "GND", 8); + b->pins[25].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[26].name, "SPI0CS1", 8); // PI14 SPI0 + b->pins[26].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[26].gpio.pinmap = 270; + + if (platform_detected == PLATFORM_BANANA_PI) { + strncpy(b->pins[27].name, "5V", 8); + b->pins[27].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[28].name, "3V3", 8); + b->pins[28].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[29].name, "PH05", 8); // PH5 + b->pins[29].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[29].gpio.pinmap = 229; + + strncpy(b->pins[30].name, "PI21", 8); // PI21 UART7_RX + b->pins[30].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[30].gpio.pinmap = 277; + + strncpy(b->pins[31].name, "PH03", 8); // PH3 + b->pins[31].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[31].gpio.pinmap = 227; + + strncpy(b->pins[32].name, "PI20", 8); // PI20 UART7_TX + b->pins[32].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[32].gpio.pinmap = 276; + + strncpy(b->pins[33].name, "GND", 8); + b->pins[33].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[34].name, "GND", 8); + b->pins[34].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + } + + if (platform_detected == PLATFORM_BANANA_PRO) { + + strncpy(b->pins[27].name, "HAT_SDA", 8); // PI1 TWI3-SDA i2c3 + b->pins[27].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + b->pins[27].gpio.pinmap = 257; + + strncpy(b->pins[28].name, "HAT_SCK", 8); // PI0 TWI3-SCK i2c3 + b->pins[28].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + b->pins[28].gpio.pinmap = 256; + + strncpy(b->pins[29].name, "PB03", 8); // PB3 IR0_TX/SPDIF_MCLK + b->pins[29].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[29].gpio.pinmap = 35; + + strncpy(b->pins[30].name, "GND", 8); + b->pins[30].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[31].name, "PI21", 8); // PI21 UART7_RX + b->pins[31].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[31].gpio.pinmap = 277; + + strncpy(b->pins[32].name, "PI20", 8); // PI20 UART7_TX + b->pins[32].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[32].gpio.pinmap = 276; + + strncpy(b->pins[33].name, "PB13", 8); // PB13 SPDIF_D0 + b->pins[33].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[33].gpio.pinmap = 45; + + strncpy(b->pins[34].name, "GND", 8); + b->pins[34].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[35].name, "PB07", 8); // PB07 I2S0_LRCK + b->pins[35].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[35].gpio.pinmap = 39; + + strncpy(b->pins[36].name, "PB06", 8); // PB06 I2S0BCLK + b->pins[36].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[36].gpio.pinmap = 38; + + strncpy(b->pins[37].name, "PB05", 8); // PB05 I2S0MCK + b->pins[37].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[37].gpio.pinmap = 37; + + strncpy(b->pins[38].name, "PB12", 8); // PB12 I2S0_DI + b->pins[38].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[38].gpio.pinmap = 44; + + strncpy(b->pins[39].name, "GND", 8); + b->pins[39].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[40].name, "PB08", 8); // PB08 I2S0_DO0 + b->pins[40].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[40].gpio.pinmap = 40; + } + + b->aio_count = 0; + b->adc_raw = 0; + b->adc_supported = 0; + b->pwm_default_period = 500; + b->pwm_max_period = 2147483; + b->pwm_min_period = 1; + + b->gpio_count = 0; + int i; + for (i = 0; i < b->phy_pin_count; i++) { + if (b->pins[i].capabilites.gpio) { + b->gpio_count++; + } + } + + // BUS DEFINITIONS + b->i2c_bus_count = 0; + b->def_i2c_bus = 0; + if (i2c2 >= 0) { + b->i2c_bus[b->i2c_bus_count].bus_id = i2c2; + b->i2c_bus[b->i2c_bus_count].sda = 3; + b->i2c_bus[b->i2c_bus_count].scl = 5; + b->i2c_bus_count++; + } + + b->spi_bus_count = 0; + b->def_spi_bus = 0; + if (spi0 >= 0) { + b->spi_bus[b->spi_bus_count].bus_id = spi0; + b->spi_bus[b->spi_bus_count].slave_s = 0; + b->spi_bus[b->spi_bus_count].cs = 24; + b->spi_bus[b->spi_bus_count].mosi = 19; + b->spi_bus[b->spi_bus_count].miso = 21; + b->spi_bus[b->spi_bus_count].sclk = 23; + b->spi_bus_count++; + } + + b->uart_dev_count = 0; + b->def_uart_dev = 0; + if ((uart3 >= 0) && (platform_detected == PLATFORM_BANANA_PI)) { + b->def_uart_dev = b->uart_dev_count; + b->uart_dev[b->uart_dev_count].device_path = serialdev[uart3]; + b->uart_dev[b->uart_dev_count].rx = 11; + b->uart_dev[b->uart_dev_count].tx = 13; + b->uart_dev_count++; + } + if ((uart4 >= 0) && (platform_detected == PLATFORM_BANANA_PRO)) { + b->def_uart_dev = b->uart_dev_count; + b->uart_dev[b->uart_dev_count].device_path = serialdev[uart4]; + b->uart_dev[b->uart_dev_count].rx = 10; + b->uart_dev[b->uart_dev_count].tx = 8; + b->uart_dev_count++; + } + if (uart7 >= 0) { + b->uart_dev[b->uart_dev_count].device_path = serialdev[uart7]; + if (platform_detected == PLATFORM_BANANA_PRO) { + b->uart_dev[b->uart_dev_count].rx = 31; + b->uart_dev[b->uart_dev_count].tx = 32; + } else { + b->uart_dev[b->uart_dev_count].rx = 30; + b->uart_dev[b->uart_dev_count].tx = 32; + } + b->uart_dev_count++; + } + if (uart2 >= 0) { + b->uart_dev[b->uart_dev_count].device_path = serialdev[uart2]; + b->uart_dev[b->uart_dev_count].rx = 11; + b->uart_dev[b->uart_dev_count].tx = 13; + b->uart_dev_count++; + } + return b; +} \ No newline at end of file