From 0df2e0f417725761c22959fde2a911b36bc07995 Mon Sep 17 00:00:00 2001 From: Daniel Bovensiepen Date: Fri, 22 Sep 2023 00:07:30 +0800 Subject: [PATCH] platform: Add RISC-V architecture with VisionFive Add RISC-V architecture and StarFive JH71x0-based boards VisionFive and VisionFive 2. Signed-off-by: Daniel Bovensiepen Signed-off-by: Zhu Jia Xing --- CMakeLists.txt | 4 +- README.md | 4 + api/mraa/types.h | 2 + api/mraa/types.hpp | 1 + docs/visionfive.md | 108 +++++++++ include/mraa_internal.h | 7 + include/riscv/visionfive.h | 24 ++ src/CMakeLists.txt | 10 + src/mraa.c | 5 +- src/riscv/CMakeLists.txt | 3 + src/riscv/riscv.c | 33 +++ src/riscv/visionfive.c | 460 +++++++++++++++++++++++++++++++++++++ 12 files changed, 659 insertions(+), 2 deletions(-) create mode 100644 docs/visionfive.md create mode 100644 include/riscv/visionfive.h create mode 100644 src/riscv/CMakeLists.txt create mode 100644 src/riscv/riscv.c create mode 100644 src/riscv/visionfive.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b21045c3..b12153e5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,10 +192,12 @@ elseif (DETECTED_ARCH MATCHES "mips") set (MIPSPLAT ON) elseif (DETECTED_ARCH STREQUAL "MOCK") set (MOCKPLAT ON) +elseif (DETECTED_ARCH STREQUAL "riscv64") + set (RISCVPLAT ON) elseif (DETECTED_ARCH STREQUAL "PERIPHERALMAN") set (PERIPHERALMAN ON) else () - message (FATAL_ERROR "Only x86, arm, mips, PERIPHERALMAN and mock platforms currently supported") + message (FATAL_ERROR "Only x86, arm, mips, riscv, PERIPHERALMAN and mock platforms currently supported") endif() if (BUILDSWIGPYTHON OR BUILDTESTS) diff --git a/README.md b/README.md index bb80c57da..ffd489644 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ JSON platform ---- * [Platform loading](../master/docs/jsonplatform.md) +RISC-V +---- +* [VisionFive](../master/docs/visionfive.md) + Installing on your board ======================== diff --git a/api/mraa/types.h b/api/mraa/types.h index fcceaa71f..0d2b56187 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -70,6 +70,8 @@ typedef enum { MRAA_INTEL_ILK = 25, /**< Intel Learning Kit */ MRAA_SIEMENS_IOT2050 = 26, /**< Siemens IOT2050 board */ MRAA_RADXA_ROCK_3C = 27, /**< Radxa ROCK 3 Model C */ + MRAA_VISIONFIVE = 28, /**< StarFive VisionFive board */ + // USB platform extenders start at 256 MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ diff --git a/api/mraa/types.hpp b/api/mraa/types.hpp index 3817c411f..21a76204e 100644 --- a/api/mraa/types.hpp +++ b/api/mraa/types.hpp @@ -64,6 +64,7 @@ typedef enum { INTEL_UPXTREME = 24, /**< The UPXTREME Board */ SIEMENS_IOT2050 = 26, /**< Siemens IOT2050 board */ RADXA_ROCK_3C = 27, /**< Radxa ROCK 3 Model C */ + VISIONFIVE = 28, /**< StarFive VisionFive board */ FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ diff --git a/docs/visionfive.md b/docs/visionfive.md new file mode 100644 index 000000000..7f45bbaf3 --- /dev/null +++ b/docs/visionfive.md @@ -0,0 +1,108 @@ +VisionFive +============ + +The VisionFive is based on the StarFive JH71x0 system on a chip family, which +includes an U74 Dual-Core RISC-V processor and ships with 2/4/8 gigabytes of RAM. + +Revision Support +---------------- + +VisionFive (JH7100) and VisionFive 2 (JH7110). + +Interface notes +--------------- + +PWM is currently not supported. + +Pin Mapping +----------- + +The pin mapping refers to the VisionFive model: + +| MRAA Number | Physical Pin | Function | +|-------------|--------------|----------| +| 1 | P1-01 | 3V3 VCC | +| 2 | P1-02 | 5V VCC | +| 3 | P1-03 | I2C SDA | +| 4 | P1-04 | 5V VCC | +| 5 | P1-05 | I2C SCL | +| 6 | P1-06 | GND | +| 7 | P1-07 | GPIO(46) | +| 8 | P1-08 | UART TX | +| 9 | P1-09 | GND | +| 10 | P1-10 | UART RX | +| 11 | P1-11 | GPIO(44) | +| 12 | P1-12 | GPIO(45) | +| 13 | P1-13 | GPIO(22) | +| 14 | P1-14 | GND | +| 15 | P1-15 | GPIO(20) | +| 16 | P1-16 | GPIO(21) | +| 17 | P1-17 | 3V3 VCC | +| 18 | P1-18 | GPIO(19) | +| 19 | P1-19 | SPI MOSI | +| 20 | P1-20 | GND | +| 21 | P1-21 | SPI MISO | +| 22 | P1-22 | GPIO(17) | +| 23 | P1-23 | SPI SCL | +| 24 | P1-24 | SPI CS0 | +| 25 | P1-25 | GND | +| 26 | P1-26 | SPI CS1 | +| 27 | P1-27 | GPIO(9) | +| 28 | P1-28 | GPIO(10) | +| 29 | P1-29 | GPIO(8) | +| 30 | P1-30 | GND | +| 31 | P1-31 | GPIO(6) | +| 32 | P1-32 | PWM0 | +| 33 | P1-33 | PWM1 | +| 34 | P1-34 | GND | +| 35 | P1-35 | GPIO(3) | +| 36 | P1-36 | GPIO(4) | +| 37 | P1-37 | GPIO(1) | +| 38 | P1-38 | GPIO(2) | +| 39 | P1-39 | GND | +| 40 | P1-40 | GPIO(0) | + +The following pin mapping refers to the VisionFive 2 model: + +| MRAA Number | Physical Pin | Function | +|-------------|--------------|----------| +| 1 | P1-01 | 3V3 VCC | +| 2 | P1-02 | 5V VCC | +| 3 | P1-03 | I2C SDA | +| 4 | P1-04 | 5V VCC | +| 5 | P1-05 | I2C SCL | +| 6 | P1-06 | GND | +| 7 | P1-07 | GPIO(55) | +| 8 | P1-08 | UART TX | +| 9 | P1-09 | GND | +| 10 | P1-10 | UART RX | +| 11 | P1-11 | GPIO(42) | +| 12 | P1-12 | GPIO(38) | +| 13 | P1-13 | GPIO(43) | +| 14 | P1-14 | GND | +| 15 | P1-15 | GPIO(47) | +| 16 | P1-16 | GPIO(54) | +| 17 | P1-17 | 3V3 VCC | +| 18 | P1-18 | GPIO(51) | +| 19 | P1-19 | SPI MOSI | +| 20 | P1-20 | GND | +| 21 | P1-21 | SPI MISO | +| 22 | P1-22 | GPIO(50) | +| 23 | P1-23 | SPI SCL | +| 24 | P1-24 | SPI CS0 | +| 25 | P1-25 | GND | +| 26 | P1-26 | GPIO(56) | +| 27 | P1-27 | GPIO(45) | +| 28 | P1-28 | GPIO(40) | +| 29 | P1-29 | GPIO(37) | +| 30 | P1-30 | GND | +| 31 | P1-31 | GPIO(39) | +| 32 | P1-32 | PWM0 | +| 33 | P1-33 | PWM1 | +| 34 | P1-34 | GND | +| 35 | P1-35 | GPIO(63) | +| 36 | P1-36 | GPIO(36) | +| 37 | P1-37 | GPIO(60) | +| 38 | P1-38 | GPIO(61) | +| 39 | P1-39 | GND | +| 40 | P1-40 | GPIO(44) | diff --git a/include/mraa_internal.h b/include/mraa_internal.h index 169481b48..e9f440630 100644 --- a/include/mraa_internal.h +++ b/include/mraa_internal.h @@ -61,6 +61,13 @@ mraa_platform_t mraa_mips_platform(); * @return mraa_platform_t of the init'ed platform */ mraa_platform_t mraa_mock_platform(); + +/** + * runtime detect running risc-v platforms + * + * @return mraa_platform_t of the init'ed platform + */ +mraa_platform_t mraa_riscv_platform(); /** * runtime detect iio subsystem diff --git a/include/riscv/visionfive.h b/include/riscv/visionfive.h new file mode 100644 index 000000000..5231609a5 --- /dev/null +++ b/include/riscv/visionfive.h @@ -0,0 +1,24 @@ +/* + * Author: Daniel Bovensiepen + * Author: Zhu Jia Xing + * Copyright (c) 2022 Siemens Ltd. China. + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa_internal.h" + +#define MRAA_VISIONFIVE_PINCOUNT 41 + +mraa_board_t * + mraa_visionfive(); + +#ifdef __cplusplus +} +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6c25f91a..f9aa25d7c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -130,6 +130,11 @@ set (mraa_LIB_MOCK_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/mock/mock_board_uart.c ) +set (mraa_LIB_RISCV_SRCS_NOAUTO + ${PROJECT_SOURCE_DIR}/src/riscv/riscv.c + ${PROJECT_SOURCE_DIR}/src/riscv/visionfive.c +) + set (mraa_LIB_PERIPHERALMAN_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/peripheralman/peripheralman.c ) @@ -170,6 +175,11 @@ if (MOCKPLAT) endif () endif() +if (RISCVPLAT) + add_subdirectory(riscv) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DRISCVPLAT=1") +endif() + if (PERIPHERALMAN) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPERIPHERALMAN=1") diff --git a/src/mraa.c b/src/mraa.c index 927d9ab4a..653ea1fa7 100644 --- a/src/mraa.c +++ b/src/mraa.c @@ -153,7 +153,7 @@ imraa_init() // Use runtime ARM platform detection platform_type = mraa_arm_platform(); #elif defined(MIPSPLAT) - // Use runtime ARM platform detection + // Use runtime MIPS platform detection platform_type = mraa_mips_platform(); #elif defined(MOCKPLAT) // Use mock platform @@ -161,6 +161,9 @@ imraa_init() #elif defined(PERIPHERALMAN) // Use peripheralmanager platform_type = mraa_peripheralman_platform(); +#elif defined(RISCVPLAT) + // Use runtime RISC-V platform detection + platform_type = mraa_riscv_platform(); #else #error mraa_ARCH NOTHING #endif diff --git a/src/riscv/CMakeLists.txt b/src/riscv/CMakeLists.txt new file mode 100644 index 000000000..62179930b --- /dev/null +++ b/src/riscv/CMakeLists.txt @@ -0,0 +1,3 @@ +message (INFO " - Adding RISC-V platforms") +set (mraa_LIB_PLAT_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO} + ${mraa_LIB_RISCV_SRCS_NOAUTO} PARENT_SCOPE) diff --git a/src/riscv/riscv.c b/src/riscv/riscv.c new file mode 100644 index 000000000..f093aa048 --- /dev/null +++ b/src/riscv/riscv.c @@ -0,0 +1,33 @@ +/* + * Author: Daniel Bovensiepen + * Author: Zhu Jia Xing + * Copyright (c) 2022 Siemens Ltd. China. + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include "riscv/visionfive.h" +#include "mraa_internal.h" + +mraa_platform_t +mraa_riscv_platform() +{ + mraa_platform_t platform_type = MRAA_UNKNOWN_PLATFORM; + if (mraa_file_contains("/proc/device-tree/compatible", "visionfive")) { + platform_type = MRAA_VISIONFIVE; + } + + switch (platform_type) { + case MRAA_VISIONFIVE: + plat = mraa_visionfive(); + break; + + default: + plat = NULL; + syslog(LOG_ERR, "Unknown Platform, currently not supported by MRAA"); + } + return platform_type; +} diff --git a/src/riscv/visionfive.c b/src/riscv/visionfive.c new file mode 100644 index 000000000..454cc86be --- /dev/null +++ b/src/riscv/visionfive.c @@ -0,0 +1,460 @@ +/* + * Author: Daniel Bovensiepen + * Author: Zhu Jia Xing + * Copyright (c) 2022 Siemens Ltd. China. + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include + +#include "riscv/visionfive.h" +#include "common.h" + +#define MRAA_VISIONFIVE_V1_JH7100 1 +#define MRAA_VISIONFIVE_V2_JH7110 2 + +#define PLATFORM_NAME_VISIONFIVE_V1 "VisionFive" +#define PLATFORM_NAME_VISIONFIVE_V2 "VisionFive-v2" + +/* TODO: currently no TRM doc of JH7100 available, we use dummy values for now */ +#define DEFAULT_PERIOD_US 40000 +#define MAX_PERIOD_US 5000000 +#define MIN_PERIOD_US 1 + +mraa_board_t* +mraa_visionfive() +{ + unsigned char detected_platform = MRAA_VISIONFIVE_V1_JH7100; + int pinbase = 0; + + mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); + if (b == NULL) { + return NULL; + } + + if (mraa_file_contains("/proc/device-tree/compatible", "visionfive-v2")) { + detected_platform = MRAA_VISIONFIVE_V2_JH7110; + } else if (mraa_file_contains("/proc/device-tree/compatible", "visionfive")) { + detected_platform = MRAA_VISIONFIVE_V1_JH7100; + } + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->platform_name = PLATFORM_NAME_VISIONFIVE_V1; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->platform_name = PLATFORM_NAME_VISIONFIVE_V2; + } + + b->phy_pin_count = MRAA_VISIONFIVE_PINCOUNT; + + b->aio_count = 0; + b->adc_raw = 0; + b->adc_supported = 0; + b->pwm_default_period = DEFAULT_PERIOD_US; + b->pwm_max_period = MAX_PERIOD_US; + b->pwm_min_period = MIN_PERIOD_US; + + if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + pinbase = 0; + } else if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + pinbase = 448; + } + + 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*) calloc(MRAA_VISIONFIVE_PINCOUNT, sizeof(mraa_pininfo_t)); + if(b->pins == NULL) { + free(b->adv_func); + goto error; + } + + strncpy(b->pins[0].name, "INVALID", MRAA_PIN_NAME_SIZE); + b->pins[0].capabilities = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[1].name, "3V3", MRAA_PIN_NAME_SIZE); + b->pins[1].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[2].name, "5V", MRAA_PIN_NAME_SIZE); + b->pins[2].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[3].name, "SDA0", MRAA_PIN_NAME_SIZE); + b->pins[3].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[3].gpio.pinmap = pinbase + 48; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[3].gpio.pinmap = pinbase + 58; + } + b->pins[3].gpio.mux_total = 0; + b->pins[3].i2c.pinmap = 0; + b->pins[3].i2c.mux_total = 0; + + strncpy(b->pins[4].name, "5V", MRAA_PIN_NAME_SIZE); + b->pins[4].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[5].name, "SCL0", MRAA_PIN_NAME_SIZE); + b->pins[5].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[5].gpio.pinmap = pinbase + 47; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[5].gpio.pinmap = pinbase + 57; + } + b->pins[5].gpio.mux_total = 0; + b->pins[5].i2c.pinmap = 0; + b->pins[5].i2c.mux_total = 0; + + strncpy(b->pins[6].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[6].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[7].name, "GPIO46", MRAA_PIN_NAME_SIZE); + b->pins[7].gpio.pinmap = pinbase + 46; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[7].name, "GPIO55", MRAA_PIN_NAME_SIZE); + b->pins[7].gpio.pinmap = pinbase + 55; + } + b->pins[7].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[7].gpio.mux_total = 0; + + strncpy(b->pins[8].name, "UART_TX", MRAA_PIN_NAME_SIZE); + b->pins[8].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[8].gpio.pinmap = pinbase + 14; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[8].gpio.pinmap = pinbase + 5; + } + b->pins[8].gpio.mux_total = 0; + b->pins[8].uart.pinmap = 0; + b->pins[8].uart.mux_total = 0; + b->pins[8].uart.parent_id = 0; + + strncpy(b->pins[9].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[9].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[10].name, "UART_RX", MRAA_PIN_NAME_SIZE); + b->pins[10].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[10].gpio.pinmap = pinbase + 13; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[10].gpio.pinmap = pinbase + 6; + } + b->pins[10].gpio.mux_total = 0; + b->pins[10].uart.pinmap = 0; + b->pins[10].uart.mux_total = 0; + b->pins[10].uart.parent_id = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[11].name, "GPIO44", MRAA_PIN_NAME_SIZE); + b->pins[11].gpio.pinmap = pinbase + 44; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[11].name, "GPIO42", MRAA_PIN_NAME_SIZE); + b->pins[11].gpio.pinmap = pinbase + 42; + } + b->pins[11].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[11].gpio.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[12].name, "GPIO45", MRAA_PIN_NAME_SIZE); + b->pins[12].gpio.pinmap = pinbase + 45; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[12].name, "GPIO38", MRAA_PIN_NAME_SIZE); + b->pins[12].gpio.pinmap = pinbase + 38; + } + b->pins[12].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[12].gpio.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[13].name, "GPIO22", MRAA_PIN_NAME_SIZE); + b->pins[13].gpio.pinmap = pinbase + 22; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[13].name, "GPIO43", MRAA_PIN_NAME_SIZE); + b->pins[13].gpio.pinmap = pinbase + 43; + } + b->pins[13].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[13].gpio.mux_total = 0; + + strncpy(b->pins[14].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[14].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[15].name, "GPIO20", MRAA_PIN_NAME_SIZE); + b->pins[15].gpio.pinmap = pinbase + 20; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[15].name, "GPIO47", MRAA_PIN_NAME_SIZE); + b->pins[15].gpio.pinmap = pinbase + 47; + } + b->pins[15].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[15].gpio.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[16].name, "GPIO21", MRAA_PIN_NAME_SIZE); + b->pins[16].gpio.pinmap = pinbase + 21; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[16].name, "GPIO54", MRAA_PIN_NAME_SIZE); + b->pins[16].gpio.pinmap = pinbase + 54; + } + b->pins[16].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[16].gpio.mux_total = 0; + + strncpy(b->pins[17].name, "3V3", MRAA_PIN_NAME_SIZE); + b->pins[17].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[18].name, "GPIO19", MRAA_PIN_NAME_SIZE); + b->pins[18].gpio.pinmap = pinbase + 19; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[18].name, "GPIO51", MRAA_PIN_NAME_SIZE); + b->pins[18].gpio.pinmap = pinbase + 51; + } + b->pins[18].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[18].gpio.mux_total = 0; + + strncpy(b->pins[19].name, "SPI_MOSI", MRAA_PIN_NAME_SIZE); + b->pins[19].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[19].gpio.pinmap = pinbase + 18; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[19].gpio.pinmap = pinbase + 52; + } + b->pins[19].gpio.mux_total = 0; + b->pins[19].spi.pinmap = 0; + b->pins[19].spi.mux_total = 0; + + strncpy(b->pins[20].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[20].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + strncpy(b->pins[21].name, "SPI_MISO", MRAA_PIN_NAME_SIZE); + b->pins[21].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[21].gpio.pinmap = pinbase + 16; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[21].gpio.pinmap = pinbase + 53; + } + b->pins[21].gpio.mux_total = 0; + b->pins[21].spi.pinmap = 0; + b->pins[21].spi.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[22].name, "GPIO17", MRAA_PIN_NAME_SIZE); + b->pins[22].gpio.pinmap = pinbase + 17; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[22].name, "GPIO50", MRAA_PIN_NAME_SIZE); + b->pins[22].gpio.pinmap = pinbase + 50; + } + b->pins[22].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[22].gpio.mux_total = 0; + + strncpy(b->pins[23].name, "SPI_CLK", MRAA_PIN_NAME_SIZE); + b->pins[23].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[23].gpio.pinmap = pinbase + 12; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[23].gpio.pinmap = pinbase + 48; + } + b->pins[23].gpio.mux_total = 0; + b->pins[23].spi.pinmap = 0; + b->pins[23].spi.mux_total = 0; + + strncpy(b->pins[24].name, "SPI_CS0", MRAA_PIN_NAME_SIZE); + b->pins[24].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[24].gpio.pinmap = pinbase + 15; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[24].gpio.pinmap = pinbase + 49; + } + b->pins[24].gpio.mux_total = 0; + b->pins[24].spi.pinmap = 0; + b->pins[24].spi.mux_total = 0; + + strncpy(b->pins[25].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[25].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[26].name, "SPI_CS1", MRAA_PIN_NAME_SIZE); + b->pins[26].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[26].gpio.pinmap = pinbase + 11; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[26].name, "GPIO56", MRAA_PIN_NAME_SIZE); + b->pins[26].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 }; + b->pins[26].gpio.pinmap = pinbase + 56; + } + b->pins[26].gpio.mux_total = 0; + b->pins[26].spi.pinmap = 0; + b->pins[26].spi.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[27].name, "GPIO9", MRAA_PIN_NAME_SIZE); + b->pins[27].gpio.pinmap = pinbase + 9; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[27].name, "GPIO45", MRAA_PIN_NAME_SIZE); + b->pins[27].gpio.pinmap = pinbase + 45; + } + b->pins[27].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[27].gpio.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[28].name, "GPIO10", MRAA_PIN_NAME_SIZE); + b->pins[28].gpio.pinmap = pinbase + 10; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[28].name, "GPI40", MRAA_PIN_NAME_SIZE); + b->pins[28].gpio.pinmap = pinbase + 40; + } + b->pins[28].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[28].gpio.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[29].name, "GPIO8", MRAA_PIN_NAME_SIZE); + b->pins[29].gpio.pinmap = pinbase + 8; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[29].name, "GPIO37", MRAA_PIN_NAME_SIZE); + b->pins[29].gpio.pinmap = pinbase + 37; + } + b->pins[29].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[29].gpio.mux_total = 0; + + strncpy(b->pins[30].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[30].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[31].name, "GPIO6", MRAA_PIN_NAME_SIZE); + b->pins[31].gpio.pinmap = pinbase + 6; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[31].name, "GPIO39", MRAA_PIN_NAME_SIZE); + b->pins[31].gpio.pinmap = pinbase + 39; + } + b->pins[31].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[31].gpio.mux_total = 0; + + strncpy(b->pins[32].name, "PWM0", MRAA_PIN_NAME_SIZE); + b->pins[32].capabilities = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[32].gpio.pinmap = pinbase + 7; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[32].gpio.pinmap = pinbase + 46; + } + b->pins[32].gpio.mux_total = 0; + + strncpy(b->pins[33].name, "PWM1", MRAA_PIN_NAME_SIZE); + b->pins[33].capabilities = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->pins[33].gpio.pinmap = pinbase + 5; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->pins[33].gpio.pinmap = pinbase + 59; + } + b->pins[33].gpio.mux_total = 0; + + strncpy(b->pins[34].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[34].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[35].name, "GPIO3", MRAA_PIN_NAME_SIZE); + b->pins[35].gpio.pinmap = pinbase + 3; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[35].name, "GPIO63", MRAA_PIN_NAME_SIZE); + b->pins[35].gpio.pinmap = pinbase + 63; + } + b->pins[35].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[35].gpio.mux_total = 0; + b->pins[35].uart.pinmap = 0; + b->pins[35].uart.mux_total = 0; + b->pins[35].uart.parent_id = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[36].name, "GPIO4", MRAA_PIN_NAME_SIZE); + b->pins[36].gpio.pinmap = pinbase + 4; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[36].name, "GPIO36", MRAA_PIN_NAME_SIZE); + b->pins[36].gpio.pinmap = pinbase + 36; + } + b->pins[36].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[36].gpio.mux_total = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[37].name, "GPIO1", MRAA_PIN_NAME_SIZE); + b->pins[37].gpio.pinmap = pinbase + 1; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[37].name, "GPIO60", MRAA_PIN_NAME_SIZE); + b->pins[37].gpio.pinmap = pinbase + 60; + } + b->pins[37].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 }; + b->pins[37].gpio.mux_total = 0; + b->pins[37].uart.pinmap = 0; + b->pins[37].uart.mux_total = 0; + b->pins[37].uart.parent_id = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[38].name, "GPIO2", MRAA_PIN_NAME_SIZE); + b->pins[38].gpio.pinmap = pinbase + 2; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[38].name, "GPIO61", MRAA_PIN_NAME_SIZE); + b->pins[38].gpio.pinmap = pinbase + 61; + } + b->pins[38].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[38].gpio.mux_total = 0; + + strncpy(b->pins[39].name, "GND", MRAA_PIN_NAME_SIZE); + b->pins[39].capabilities = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 }; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + strncpy(b->pins[40].name, "GPIO0", MRAA_PIN_NAME_SIZE); + b->pins[40].gpio.pinmap = pinbase + 0; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + strncpy(b->pins[40].name, "GPIO44", MRAA_PIN_NAME_SIZE); + b->pins[40].gpio.pinmap = pinbase + 44; + } + b->pins[40].capabilities = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }; + b->pins[40].gpio.mux_total = 0; + + b->gpio_count = 29; + + b->i2c_bus_count = 1; + b->def_i2c_bus = 0; + + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->i2c_bus[0].bus_id = 1; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->i2c_bus[0].bus_id = 0; + } + + b->i2c_bus[0].sda = 3; + b->i2c_bus[0].scl = 5; + + b->spi_bus_count = 1; + b->def_spi_bus = 0; + if (detected_platform == MRAA_VISIONFIVE_V1_JH7100) { + b->spi_bus[0].bus_id = 0; + } else if (detected_platform == MRAA_VISIONFIVE_V2_JH7110) { + b->spi_bus[0].bus_id = 1; + } + b->spi_bus[0].slave_s = 0; + b->spi_bus[0].cs = 24; + b->spi_bus[0].mosi = 19; + b->spi_bus[0].miso = 21; + b->spi_bus[0].sclk = 23; + + b->uart_dev_count = 2; + b->def_uart_dev = 0; + b->uart_dev[0].rx = 10; + b->uart_dev[0].tx = 8; + b->uart_dev[0].name = "UART0"; + b->uart_dev[0].device_path = "/dev/ttyS0"; + b->uart_dev[1].rx = 37; + b->uart_dev[1].tx = 35; + b->uart_dev[1].name = "UART1"; + b->uart_dev[1].device_path = "/dev/ttyS1"; + + return b; + +error: + syslog(LOG_CRIT, "visionfive: Platform failed to initialise"); + free(b); + + return NULL; +}