From f727c01d2e1ebe783e846a18b12703e23a2dcaa7 Mon Sep 17 00:00:00 2001 From: Gunjan Gupta Date: Wed, 2 Aug 2023 03:16:13 +0530 Subject: [PATCH] Add support for Orange Pi Prime --- README.md | 1 + api/mraa/types.h | 35 ++++++++ api/mraa/types.hpp | 35 ++++++++ docs/index.java.md | 1 + docs/index.md | 1 + docs/orange_pi_prime.md | 51 ++++++++++++ include/arm/orange_pi_prime.h | 26 ++++++ src/CMakeLists.txt | 1 + src/arm/arm.c | 6 ++ src/arm/orange_pi_prime.c | 151 ++++++++++++++++++++++++++++++++++ 10 files changed, 308 insertions(+) create mode 100644 docs/orange_pi_prime.md create mode 100644 include/arm/orange_pi_prime.h create mode 100644 src/arm/orange_pi_prime.c diff --git a/README.md b/README.md index 87a66c5..47f1d25 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ ARM * [Radxa ROCK 5A](../master/docs/radxa_rock_5a.md) * [Radxa ROCK 5B](../master/docs/radxa_rock_5b.md) * [Rock Pi 4](../master/docs/rockpi4.md) +* [Orange Pi Prime](../master/docs/orange_pi_prime.md) MIPS --- diff --git a/api/mraa/types.h b/api/mraa/types.h index 14b70c9..7d78fc2 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -73,6 +73,7 @@ typedef enum { MRAA_VISIONFIVE = 28, /**< StarFive VisionFive board */ MRAA_RADXA_ROCK_5A = 29, /**< Radxa ROCK 5 Model A */ MRAA_RADXA_ROCK_5B = 30, /**< Radxa ROCK 5 Model B */ + MRAA_ORANGE_PI_PRIME = 31, /**< Orange Pi Prime board */ // USB platform extenders start at 256 MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ @@ -350,6 +351,40 @@ typedef enum { MRAA_RASPBERRY_WIRING_PIN29 = 40 } mraa_raspberry_wiring_t; +/** + * Orange Pi Prime GPIO numbering enum + */ +typedef enum { + MRAA_ORANGE_PI_PRIME_PIN3 = 3, + MRAA_ORANGE_PI_PRIME_PIN5 = 5, + MRAA_ORANGE_PI_PRIME_PIN7 = 7, + MRAA_ORANGE_PI_PRIME_PIN8 = 8, + MRAA_ORANGE_PI_PRIME_PIN10 = 10, + MRAA_ORANGE_PI_PRIME_PIN11 = 11, + MRAA_ORANGE_PI_PRIME_PIN12 = 12, + MRAA_ORANGE_PI_PRIME_PIN13 = 13, + MRAA_ORANGE_PI_PRIME_PIN15 = 15, + MRAA_ORANGE_PI_PRIME_PIN16 = 16, + MRAA_ORANGE_PI_PRIME_PIN18 = 18, + MRAA_ORANGE_PI_PRIME_PIN19 = 19, + MRAA_ORANGE_PI_PRIME_PIN21 = 21, + MRAA_ORANGE_PI_PRIME_PIN22 = 22, + MRAA_ORANGE_PI_PRIME_PIN23 = 23, + MRAA_ORANGE_PI_PRIME_PIN24 = 24, + MRAA_ORANGE_PI_PRIME_PIN26 = 26, + MRAA_ORANGE_PI_PRIME_PIN27 = 27, + MRAA_ORANGE_PI_PRIME_PIN28 = 28, + MRAA_ORANGE_PI_PRIME_PIN29 = 29, + MRAA_ORANGE_PI_PRIME_PIN31 = 31, + MRAA_ORANGE_PI_PRIME_PIN32 = 32, + MRAA_ORANGE_PI_PRIME_PIN33 = 33, + MRAA_ORANGE_PI_PRIME_PIN35 = 35, + MRAA_ORANGE_PI_PRIME_PIN36 = 36, + MRAA_ORANGE_PI_PRIME_PIN37 = 37, + MRAA_ORANGE_PI_PRIME_PIN38 = 38, + MRAA_ORANGE_PI_PRIME_PIN40 = 40 +} mraa_orange_pi_prime_wiring_t; + /** * MRAA return codes */ diff --git a/api/mraa/types.hpp b/api/mraa/types.hpp index 1a464d6..d47ed1e 100644 --- a/api/mraa/types.hpp +++ b/api/mraa/types.hpp @@ -67,6 +67,7 @@ typedef enum { VISIONFIVE = 28, /**< StarFive VisionFive board */ RADXA_ROCK_5A = 29, /**< Radxa ROCK 5 Model A */ RADXA_ROCK_5B = 30, /**< Radxa ROCK 5 Model B */ + ORANGE_PI_PRIME = 31, /**< Orange Pi Prime board */ FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ @@ -341,6 +342,40 @@ typedef enum { RASPBERRY_WIRING_PIN29 = 40 } RaspberryWiring; +/** + * Orange Pi Prime GPIO numbering enum + */ +typedef enum { + ORANGE_PI_PRIME_PIN3 = 3, + ORANGE_PI_PRIME_PIN5 = 5, + ORANGE_PI_PRIME_PIN7 = 7, + ORANGE_PI_PRIME_PIN8 = 8, + ORANGE_PI_PRIME_PIN10 = 10, + ORANGE_PI_PRIME_PIN11 = 11, + ORANGE_PI_PRIME_PIN12 = 12, + ORANGE_PI_PRIME_PIN13 = 13, + ORANGE_PI_PRIME_PIN15 = 15, + ORANGE_PI_PRIME_PIN16 = 16, + ORANGE_PI_PRIME_PIN18 = 18, + ORANGE_PI_PRIME_PIN19 = 19, + ORANGE_PI_PRIME_PIN21 = 21, + ORANGE_PI_PRIME_PIN22 = 22, + ORANGE_PI_PRIME_PIN23 = 23, + ORANGE_PI_PRIME_PIN24 = 24, + ORANGE_PI_PRIME_PIN26 = 26, + ORANGE_PI_PRIME_PIN27 = 27, + ORANGE_PI_PRIME_PIN28 = 28, + ORANGE_PI_PRIME_PIN29 = 29, + ORANGE_PI_PRIME_PIN31 = 31, + ORANGE_PI_PRIME_PIN32 = 32, + ORANGE_PI_PRIME_PIN33 = 33, + ORANGE_PI_PRIME_PIN35 = 35, + ORANGE_PI_PRIME_PIN36 = 36, + ORANGE_PI_PRIME_PIN37 = 37, + ORANGE_PI_PRIME_PIN38 = 38, + ORANGE_PI_PRIME_PIN40 = 40 +} OrangePiPrimeWiring; + /** * MRAA return codes */ diff --git a/docs/index.java.md b/docs/index.java.md index 22d5a3b..845746d 100644 --- a/docs/index.java.md +++ b/docs/index.java.md @@ -53,6 +53,7 @@ Specific platform information for supported platforms is documented here: - @ref ft4222 - @ref iei-tank - @ref up-xtreme +- @ref _orange_pi_prime ## DEBUGGING diff --git a/docs/index.md b/docs/index.md index 7644bec..607184e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,6 +61,7 @@ Specific platform information for supported platforms is documented here: - @ref omega2 - @ref iei-tank - @ref upXtreme +- @ref _orange_pi_prime ## DEBUGGING diff --git a/docs/orange_pi_prime.md b/docs/orange_pi_prime.md new file mode 100644 index 0000000..75fea38 --- /dev/null +++ b/docs/orange_pi_prime.md @@ -0,0 +1,51 @@ +Orange Pi Prime Single Board Computer {#_orange_pi_prime} +============================= + +Orange Pi Prime is a Allwinner H5 based SBC(Single Board Computer) by Orange Pi. It can run android or some Linux distributions. Orange Pi Prime features a quad core ARM processor, 2GB DDR3, HDMI, CSI, 3.5mm jack with CVBS video out, onboard mic, 802.11 b/g/n WIFI, Bluetooth 4.0, USB Port, Ethernet, 40-pin expansion header. Also, Orange Pi Prime supports USB OTG and has barrel jack for power. + +Board Support +------------- + +- [Orange Pi Prime](http://www.orangepi.org/orangepiwiki/index.php/Orange_Pi_Prime) + +Interface notes +--------------- + +- On Armbian, use armbian-config to enable UART, I2C, PWM and SPI on expansion header. + +Pin Mapping +----------- + +Orange Pi Prime has a 40-pin expansion header. + +|Additional Function | Primary Function| PIN | PIN | Primary Function | Additional Function | +|--------------------|------------------|:------|------:|--------------------|---------------------| +| | +3.3V | 1 | 2 | +5.0V | | +| I2C0_SDA | PA12 | 3 | 4 | +5.0V | | +| I2C0_SCK | PA11 | 5 | 6 | GND | | +| | PA6 | 7 | 8 | PC5 | | +| | GND | 9 | 10 | PC6 | | +| UART2_RX | PA1 | 11 | 12 | PD14 | | +| UART2_TX | PA0 | 13 | 14 | GND | | +| UART2_CTS | PA3 | 15 | 16 | PC4 | | +| | +3.3V | 17 | 18 | PC7 | | +| SPI1_MOSI | PA15 | 19 | 20 | GND | | +| SPI1_MISO | PA16 | 21 | 22 | PA2 | UART2_RTS | +| SPI1_CLK | PA14 | 23 | 24 | PA13 | SPI1_CS | +| | GND | 25 | 26 | PC8 | | +| I2C1_SDA | PA19 | 27 | 28 | PA18 | I2C1_SCK | +| | PA7 | 29 | 30 | GND | | +| | PA8 | 31 | 32 | PC9 | | +| | PA9 | 33 | 34 | GND | | +| | PA10 | 35 | 36 | PC10 | | +| | PD11 | 37 | 38 | PC11 | | +| | GND | 39 | 40 | PC12 | | + +Resources +--------- + +The following links will take you to additional Orange Pi Prime resources + +- [Armbian for Orange Pi Prime](https://www.armbian.com/orange-pi-prime/) +- [Armbian forum for Orange Pi Prime](https://forum.armbian.com/forum/136-orange-pi-prime/) +- [Armbian Github Repo](https://github.com/armbian) diff --git a/include/arm/orange_pi_prime.h b/include/arm/orange_pi_prime.h new file mode 100644 index 0000000..bcd2e9f --- /dev/null +++ b/include/arm/orange_pi_prime.h @@ -0,0 +1,26 @@ +/* + * Author: Gunjan + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa_internal.h" + +#define MRAA_ORANGE_PI_PRIME_GPIO_COUNT 28 +#define MRAA_ORANGE_PI_PRIME_I2C_COUNT 2 +#define MRAA_ORANGE_PI_PRIME_SPI_COUNT 1 +#define MRAA_ORANGE_PI_PRIME_UART_COUNT 1 +#define MRAA_ORANGE_PI_PRIME_PIN_COUNT 40 + +mraa_board_t * + mraa_orange_pi_prime(); + +#ifdef __cplusplus +} +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ae3df2..c784499 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,6 +115,7 @@ set (mraa_LIB_ARM_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/arm/siemens/iot2050.c ${PROJECT_SOURCE_DIR}/src/arm/siemens/platform.c ${PROJECT_SOURCE_DIR}/src/arm/siemens/platform_iot2050.c + ${PROJECT_SOURCE_DIR}/src/arm/orange_pi_prime.c ) set (mraa_LIB_MIPS_SRCS_NOAUTO diff --git a/src/arm/arm.c b/src/arm/arm.c index 54fea0b..82560da 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -21,6 +21,7 @@ #include "arm/raspberry_pi.h" #include "arm/adlink_ipi.h" #include "arm/siemens/iot2050.h" +#include "arm/orange_pi_prime.h" #include "mraa_internal.h" @@ -111,6 +112,8 @@ mraa_arm_platform() platform_type = MRAA_ADLINK_IPI; else if (mraa_file_contains("/proc/device-tree/model", "SIMATIC IOT2050")) platform_type = MRAA_SIEMENS_IOT2050; + else if (mraa_file_contains("/proc/device-tree/model", "Xunlong Orange Pi Prime")) + platform_type = MRAA_ORANGE_PI_PRIME; } switch (platform_type) { @@ -149,6 +152,9 @@ mraa_arm_platform() case MRAA_SIEMENS_IOT2050: plat = mraa_siemens_iot2050(); break; + case MRAA_ORANGE_PI_PRIME: + plat = mraa_orange_pi_prime(); + break; default: plat = NULL; syslog(LOG_ERR, "Unknown Platform, currently not supported by MRAA"); diff --git a/src/arm/orange_pi_prime.c b/src/arm/orange_pi_prime.c new file mode 100644 index 0000000..fe91e63 --- /dev/null +++ b/src/arm/orange_pi_prime.c @@ -0,0 +1,151 @@ +/* + * Author: Gunjan + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +#include "arm/orange_pi_prime.h" +#include "common.h" + +#define DT_BASE "/proc/device-tree" + +#define PLATFORM_NAME_ORANGE_PI_PRIME "Xunlong Orange Pi Prime" +#define MAX_SIZE 64 + +#define ORANGE_PI_PRIME_SPI_CS_DEV "/dev/spidev1.1" + +#define ORANGE_PI_PRIME_SERIALDEV "/dev/ttyS2" + +void +mraa_orange_pi_prime_pininfo(mraa_board_t* board, int index, int sysfs_pin, mraa_pincapabilities_t pincapabilities_t, char* fmt, ...) +{ + va_list arg_ptr; + if (index > board->phy_pin_count) + return; + + mraa_pininfo_t* pininfo = &board->pins[index]; + va_start(arg_ptr, fmt); + vsnprintf(pininfo->name, MRAA_PIN_NAME_SIZE, fmt, arg_ptr); + + if( pincapabilities_t.gpio == 1 ) { + pininfo->gpio.gpio_chip = 1; + pininfo->gpio.gpio_line = sysfs_pin; + } + + pininfo->capabilities = pincapabilities_t; + + va_end(arg_ptr); + pininfo->gpio.pinmap = sysfs_pin; + pininfo->gpio.mux_total = 0; +} + +mraa_board_t* +mraa_orange_pi_prime() +{ + mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t)); + if (b == NULL) { + return NULL; + } + + b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t)); + if (b->adv_func == NULL) { + free(b); + return NULL; + } + + b->chardev_capable = 1; + + // pin mux for buses are setup using device tree overlays + // so tell mraa to ignore them + b->no_bus_mux = 1; + b->phy_pin_count = MRAA_ORANGE_PI_PRIME_PIN_COUNT + 1; + b->platform_name = PLATFORM_NAME_ORANGE_PI_PRIME; + + // uart2 + b->uart_dev_count = MRAA_ORANGE_PI_PRIME_UART_COUNT; + b->def_uart_dev = 0; + b->uart_dev[0].device_path = ORANGE_PI_PRIME_SERIALDEV; + + // I2C + b->i2c_bus_count = MRAA_ORANGE_PI_PRIME_I2C_COUNT; + b->def_i2c_bus = 0; + b->i2c_bus[0].bus_id = 0; + b->i2c_bus[1].bus_id = 1; + + // SPI + b->spi_bus_count = MRAA_ORANGE_PI_PRIME_SPI_COUNT; + b->def_spi_bus = 0; + b->spi_bus[0].bus_id = 1; + + // Depending on the overlay parameter, we might have slave select + if (mraa_file_exist(ORANGE_PI_PRIME_SPI_CS_DEV)) { + b->spi_bus[0].slave_s = 1; + } + + b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count); + if (b->pins == NULL) { + free(b->adv_func); + free(b); + return NULL; + } + + // no analog I/O + b->aio_count = 0; + b->adc_raw = 0; + b->adc_supported = 0; + + // Orange Pi Prime documentation shows pin 7 (PA6) as pwm1 pin + // but Allwinner H5 doesn't list pwm as a function for PA6. + // Hence no PWM for this board + b->pwm_dev_count = 0; + + mraa_orange_pi_prime_pininfo(b, 0, -1, (mraa_pincapabilities_t){0,0,0,0,0,0,0,0}, "INVALID"); + mraa_orange_pi_prime_pininfo(b, 1, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "3V3"); + mraa_orange_pi_prime_pininfo(b, 2, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "5V"); + mraa_orange_pi_prime_pininfo(b, 3, 12, (mraa_pincapabilities_t){1,1,0,0,0,1,0,0}, "I2C0_SDA"); + mraa_orange_pi_prime_pininfo(b, 4, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "5V"); + mraa_orange_pi_prime_pininfo(b, 5, 11, (mraa_pincapabilities_t){1,1,0,0,0,1,0,0}, "I2C0_SCK"); + mraa_orange_pi_prime_pininfo(b, 6, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 7, 6, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PA6"); + mraa_orange_pi_prime_pininfo(b, 8, 69, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC5"); + mraa_orange_pi_prime_pininfo(b, 9, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 10, 70, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC6"); + mraa_orange_pi_prime_pininfo(b, 11, 1, (mraa_pincapabilities_t){1,1,0,0,0,0,0,1}, "UART2_RX"); + mraa_orange_pi_prime_pininfo(b, 12, 110, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PD14"); + mraa_orange_pi_prime_pininfo(b, 13, 0, (mraa_pincapabilities_t){1,1,0,0,0,0,0,1}, "UART2_TX"); + mraa_orange_pi_prime_pininfo(b, 14, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 15, 3, (mraa_pincapabilities_t){1,1,0,0,0,0,0,1}, "UART2_CTS"); + mraa_orange_pi_prime_pininfo(b, 16, 68, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC4"); + mraa_orange_pi_prime_pininfo(b, 17, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "3V3"); + mraa_orange_pi_prime_pininfo(b, 18, 71, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC7"); + mraa_orange_pi_prime_pininfo(b, 19, 15, (mraa_pincapabilities_t){1,1,0,0,1,0,0,0}, "SPI1_MOSI"); + mraa_orange_pi_prime_pininfo(b, 20, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 21, 16, (mraa_pincapabilities_t){1,1,0,0,1,0,0,0}, "SPI1_MISO"); + mraa_orange_pi_prime_pininfo(b, 22, 2, (mraa_pincapabilities_t){1,1,0,0,0,0,0,1}, "UART2_RTS"); + mraa_orange_pi_prime_pininfo(b, 23, 14, (mraa_pincapabilities_t){1,1,0,0,1,0,0,0}, "SPI1_CLK"); + mraa_orange_pi_prime_pininfo(b, 24, 13, (mraa_pincapabilities_t){1,1,0,0,1,0,0,0}, "SPI1_CS"); + mraa_orange_pi_prime_pininfo(b, 25, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 26, 72, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC8"); + mraa_orange_pi_prime_pininfo(b, 27, 19, (mraa_pincapabilities_t){1,1,0,0,0,1,0,0}, "I2C1_SDA"); + mraa_orange_pi_prime_pininfo(b, 28, 18, (mraa_pincapabilities_t){1,1,0,0,0,1,0,0}, "I2C1_SCK"); + mraa_orange_pi_prime_pininfo(b, 29, 7, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PA7"); + mraa_orange_pi_prime_pininfo(b, 30, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 31, 8, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PA8"); + mraa_orange_pi_prime_pininfo(b, 32, 73, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC9"); + mraa_orange_pi_prime_pininfo(b, 33, 9, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PA9"); + mraa_orange_pi_prime_pininfo(b, 34, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 35, 10, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PA10"); + mraa_orange_pi_prime_pininfo(b, 36, 74, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC10"); + mraa_orange_pi_prime_pininfo(b, 37, 107, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PD11"); + mraa_orange_pi_prime_pininfo(b, 38, 75, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC11"); + mraa_orange_pi_prime_pininfo(b, 39, -1, (mraa_pincapabilities_t){1,0,0,0,0,0,0,0}, "GND"); + mraa_orange_pi_prime_pininfo(b, 40, 76, (mraa_pincapabilities_t){1,1,0,0,0,0,0,0}, "PC12"); + + return b; +}