From 910a8968787deb231dfebb846fcac3aed9d37df6 Mon Sep 17 00:00:00 2001 From: Sergey Ko Date: Thu, 5 Dec 2024 16:54:06 -0600 Subject: [PATCH 1/4] radxa zero (rev. 1.51) support --- api/mraa/types.h | 1 + include/arm/radxa_zero_151.h | 30 +++++++ include/mraa_internal.h | 2 +- src/CMakeLists.txt | 1 + src/arm/arm.c | 6 ++ src/arm/radxa_zero_151.c | 150 +++++++++++++++++++++++++++++++++++ 6 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 include/arm/radxa_zero_151.h create mode 100644 src/arm/radxa_zero_151.c diff --git a/api/mraa/types.h b/api/mraa/types.h index 843f182ee..9152b1477 100644 --- a/api/mraa/types.h +++ b/api/mraa/types.h @@ -79,6 +79,7 @@ typedef enum { MRAA_RADXA_CM5_IO = 34, /**< Radxa CM5 IO */ MRAA_RADXA_ROCK_3A = 35, /**< Radxa ROCK 3 Model A */ MRAA_RADXA_E25 = 36, /**< Radxa E25 */ + MRAA_RADXA_ZERO = 40, /**< Radxa Zero */ // USB platform extenders start at 256 MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */ diff --git a/include/arm/radxa_zero_151.h b/include/arm/radxa_zero_151.h new file mode 100644 index 000000000..6cb8e0361 --- /dev/null +++ b/include/arm/radxa_zero_151.h @@ -0,0 +1,30 @@ +/* + * Author: Sergey Ko + * Copyright (c) Radxa Limited. + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mraa_internal.h" + +#define MRAA_RADXA_ZERO_151_GPIO_COUNT 23 +#define MRAA_RADXA_ZERO_151_I2C_COUNT 2 +#define MRAA_RADXA_ZERO_151_SPI_COUNT 2 +#define MRAA_RADXA_ZERO_151_UART_COUNT 3 +#define MRAA_RADXA_ZERO_151_PWM_COUNT 2 +#define MRAA_RADXA_ZERO_151_AIO_COUNT 0 +#define MRAA_RADXA_ZERO_151_PIN_COUNT 40 +#define PLATFORM_NAME_RADXA_ZERO "Radxa Zero" + +mraa_board_t * + mraa_radxa_zero(); + +#ifdef __cplusplus +} +#endif diff --git a/include/mraa_internal.h b/include/mraa_internal.h index e9f440630..c69c6d925 100644 --- a/include/mraa_internal.h +++ b/include/mraa_internal.h @@ -61,7 +61,7 @@ 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 * diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10a1d9411..59d6afc51 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -114,6 +114,7 @@ set (mraa_LIB_ARM_SRCS_NOAUTO ${PROJECT_SOURCE_DIR}/src/arm/radxa_e25.c ${PROJECT_SOURCE_DIR}/src/arm/radxa_rock_5a.c ${PROJECT_SOURCE_DIR}/src/arm/radxa_rock_5b.c + ${PROJECT_SOURCE_DIR}/src/arm/radxa_zero_151.c ${PROJECT_SOURCE_DIR}/src/arm/radxa_cm5_io.c ${PROJECT_SOURCE_DIR}/src/arm/rockpi4.c ${PROJECT_SOURCE_DIR}/src/arm/adlink_ipi.c diff --git a/src/arm/arm.c b/src/arm/arm.c index 093021006..7f888e61d 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -17,6 +17,7 @@ #include "arm/radxa_rock_3c.h" #include "arm/radxa_rock_5a.h" #include "arm/radxa_rock_5b.h" +#include "arm/radxa_zero_151.h" #include "arm/radxa_cm5_io.h" #include "arm/rockpi4.h" #include "arm/de_nano_soc.h" @@ -117,6 +118,8 @@ mraa_arm_platform() platform_type = MRAA_RADXA_ROCK_5A; else if (mraa_file_contains("/proc/device-tree/model", PLATFORM_NAME_RADXA_ROCK_5B)) platform_type = MRAA_RADXA_ROCK_5B; + else if (mraa_file_contains("/proc/device-tree/model", PLATFORM_NAME_RADXA_ZERO)) + platform_type = MRAA_RADXA_ZERO; else if (mraa_file_contains("/proc/device-tree/model", PLATFORM_NAME_RADXA_CM5_IO)) platform_type = MRAA_RADXA_CM5_IO; else if (mraa_file_contains("/proc/device-tree/model", "ROCK Pi 4") || @@ -171,6 +174,9 @@ mraa_arm_platform() case MRAA_RADXA_ROCK_5B: plat = mraa_radxa_rock_5b(); break; + case MRAA_RADXA_ZERO: + plat = mraa_radxa_zero(); + break; case MRAA_RADXA_CM5_IO: plat = mraa_radxa_cm5_io(); break; diff --git a/src/arm/radxa_zero_151.c b/src/arm/radxa_zero_151.c new file mode 100644 index 000000000..99eae14fe --- /dev/null +++ b/src/arm/radxa_zero_151.c @@ -0,0 +1,150 @@ +/* + * Author: Sergey Ko + * Copyright (c) Radxa Limited. + * + * SPDX-License-Identifier: MIT + */ + +#include "arm/radxa_zero_151.h" +#include "common.h" +#include +#include +#include +#include +#include + +const char* radxa_zero_151_serialdev[MRAA_RADXA_ZERO_151_UART_COUNT] = { "/dev/ttyAML0", "/dev/ttyAML1", "/dev/ttyAML4" }; + +void +mraa_radxa_zero_pininfo(mraa_board_t* board, + int index, + int gpio_chip, + int gpio_line, + mraa_pincapabilities_t pincapabilities_t, + char* pin_name) +{ + + if (index > board->phy_pin_count) + return; + + mraa_pininfo_t* pininfo = &board->pins[index]; + strncpy(pininfo->name, pin_name, MRAA_PIN_NAME_SIZE); + + if (pincapabilities_t.gpio == 1) { + pininfo->gpio.gpio_chip = gpio_chip; + pininfo->gpio.gpio_line = gpio_line; + } + + pininfo->capabilities = pincapabilities_t; + + pininfo->gpio.mux_total = 0; +} + +mraa_board_t* +mraa_radxa_zero() +{ + 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; + } + + // pin mux for buses are setup by default by kernel so tell mraa to ignore them + b->no_bus_mux = 1; + b->phy_pin_count = MRAA_RADXA_ZERO_151_PIN_COUNT + 1; + + b->platform_name = PLATFORM_NAME_RADXA_ZERO; + b->chardev_capable = 1; + + // UART + b->uart_dev_count = MRAA_RADXA_ZERO_151_UART_COUNT; + b->def_uart_dev = 0; + b->uart_dev[0].index = 0; + b->uart_dev[1].index = 1; + b->uart_dev[2].index = 2; + b->uart_dev[0].device_path = (char*) radxa_zero_151_serialdev[0]; + b->uart_dev[1].device_path = (char*) radxa_zero_151_serialdev[1]; + b->uart_dev[2].device_path = (char*) radxa_zero_151_serialdev[2]; + + // I2C + b->i2c_bus_count = MRAA_RADXA_ZERO_151_I2C_COUNT; + b->def_i2c_bus = 0; + b->i2c_bus[0].bus_id = 3; + b->i2c_bus[1].bus_id = 5; + // b->i2c_bus[2].bus_id = 1; + + // SPI + b->spi_bus_count = MRAA_RADXA_ZERO_151_SPI_COUNT; + b->def_spi_bus = 0; + b->spi_bus[0].bus_id = 0; + b->spi_bus[1].bus_id = 1; + + // PWM + b->pwm_dev_count = MRAA_RADXA_ZERO_151_PWM_COUNT; + b->pwm_default_period = 500; + b->pwm_max_period = 2147483; + b->pwm_min_period = 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; + } + + b->pins[18].pwm.parent_id = 6; // PWM18 + b->pins[18].pwm.mux_total = 0; + b->pins[18].pwm.pinmap = 0; + b->pins[40].pwm.parent_id = 2; // PWM40 + b->pins[40].pwm.mux_total = 0; + b->pins[40].pwm.pinmap = 0; + + mraa_radxa_zero_pininfo(b, 0, -1, -1, (mraa_pincapabilities_t) { 0, 0, 0, 0, 0, 0, 0, 0 }, "INVALID"); + mraa_radxa_zero_pininfo(b, 1, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "3V3"); + mraa_radxa_zero_pininfo(b, 2, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "5V"); + mraa_radxa_zero_pininfo(b, 3, 0, 72, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 1, 0, 0 }, "I2C_EE_SDA"); // GPIOA_14 + mraa_radxa_zero_pininfo(b, 4, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "5V"); + mraa_radxa_zero_pininfo(b, 5, 1, 5, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 1, 0, 0 }, "I2C_EE_SCL"); // GPIOA_15 + mraa_radxa_zero_pininfo(b, 6, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 7, 1, 4, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 1, 0, 1 }, "I2C_AO_SDA"); // GPIOA_3 + mraa_radxa_zero_pininfo(b, 8, 1, 0, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 1 }, "UART_AO_TX"); // GPIOAO_0 + mraa_radxa_zero_pininfo(b, 9, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 10, 1, 1, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 1 }, "UART_AO_RX"); // GPIOAO_1 + mraa_radxa_zero_pininfo(b, 11, 1, 2, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 1, 0, 1 }, "I2C_AO_SCL"); // GPIOAO_2 + mraa_radxa_zero_pininfo(b, 12, 0, 74, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 0, 0, 0 }, "SPI_A_MISO"); // GPIOX_9 + mraa_radxa_zero_pininfo(b, 13, 0, 76, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 1, 0, 0 }, "I2C_EE_SCL"); // GPIOX_11 + mraa_radxa_zero_pininfo(b, 14, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 15, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "SARADC_CH1"); + mraa_radxa_zero_pininfo(b, 16, 0, 75, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 1, 0, 0 }, "I2C_EE_SDA"); // GPIOX_10 + mraa_radxa_zero_pininfo(b, 17, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "3V3"); + mraa_radxa_zero_pininfo(b, 18, 0, 73, (mraa_pincapabilities_t) { 1, 1, 1, 0, 1, 0, 0, 0 }, "SPI_A_MOSI"); // GPIOX_8 + mraa_radxa_zero_pininfo(b, 19, 0, 20, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 0, 0, 0 }, "SPI_B_MOSI"); // GPIOH_4 + mraa_radxa_zero_pininfo(b, 20, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 21, 0, 21, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 0, 0, 0 }, "SPI_B_MISO"); // GPIOH_5 + mraa_radxa_zero_pininfo(b, 22, 0, 48, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 0 }, "GPIOC_7"); + mraa_radxa_zero_pininfo(b, 23, 0, 23, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 1, 0, 1 }, "I2C_EE_SCL"); // GPIOH_7 + mraa_radxa_zero_pininfo(b, 24, 0, 22, (mraa_pincapabilities_t) { 1, 1, 0, 0, 1, 1, 0, 1 }, "UART_EE_RX"); // GPIOH_6 + mraa_radxa_zero_pininfo(b, 25, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 26, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "SARADC_CH2"); + mraa_radxa_zero_pininfo(b, 27, 1, 3, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 1, 0, 1 }, "I2C_AO_SDA"); // GPIOAO_3 + mraa_radxa_zero_pininfo(b, 28, 1, 2, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 1, 0, 1 }, "I2C_AO_SCL"); // GPIOAO_2 + mraa_radxa_zero_pininfo(b, 29, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "NC"); + mraa_radxa_zero_pininfo(b, 30, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 31, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "NC"); + mraa_radxa_zero_pininfo(b, 32, 1, 4, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 0 }, "GPIOAO_4"); + mraa_radxa_zero_pininfo(b, 33, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "NC"); + mraa_radxa_zero_pininfo(b, 34, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 35, 1, 8, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 1 }, "UART_AO_TX"); // GPIOAO_8 + mraa_radxa_zero_pininfo(b, 36, 0, 24, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 0 }, "GPIOH_8"); + mraa_radxa_zero_pininfo(b, 37, 1, 9, (mraa_pincapabilities_t) { 1, 1, 0, 0, 0, 0, 0, 1 }, "UART_AO_RX"); // GPIOAO_9 + mraa_radxa_zero_pininfo(b, 38, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "NC"); + mraa_radxa_zero_pininfo(b, 39, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "GND"); + mraa_radxa_zero_pininfo(b, 40, 1, 11, (mraa_pincapabilities_t) { 1, 1, 1, 0, 0, 0, 0, 0 }, "PWMAO_A"); // GPIOAO_11 + + return b; +} From 3bdc4d38b80340bf2b417fb0f32deb6e679c358a Mon Sep 17 00:00:00 2001 From: Sergey Ko Date: Thu, 12 Dec 2024 16:33:35 -0600 Subject: [PATCH 2/4] Radxa Zero hw. description fix, amplified syslog debug info in pwm.c --- examples/c/pwm.c | 9 +++++---- include/arm/radxa_zero_151.h | 2 +- src/arm/radxa_zero_151.c | 22 +++++++++++----------- src/pwm/pwm.c | 34 +++++++++++++++++----------------- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/examples/c/pwm.c b/examples/c/pwm.c index 481433b02..9fa896951 100644 --- a/examples/c/pwm.c +++ b/examples/c/pwm.c @@ -68,6 +68,11 @@ main(void) while (flag) { value = value + 0.01f; + /* avoid syslog warnings: pwm_write: 100%% entered, defaulting to 100% */ + if (value >= 1.0f) { + value = 0.0f; + } + /* write PWM duty cyle */ status = mraa_pwm_write(pwm, value); if (status != MRAA_SUCCESS) { @@ -76,10 +81,6 @@ main(void) usleep(50000); - if (value >= 1.0f) { - value = 0.0f; - } - /* read PWM duty cyle */ output = mraa_pwm_read(pwm); fprintf(stdout, "PWM value is %f\n", output); diff --git a/include/arm/radxa_zero_151.h b/include/arm/radxa_zero_151.h index 6cb8e0361..991aee889 100644 --- a/include/arm/radxa_zero_151.h +++ b/include/arm/radxa_zero_151.h @@ -14,7 +14,7 @@ extern "C" { #include "mraa_internal.h" #define MRAA_RADXA_ZERO_151_GPIO_COUNT 23 -#define MRAA_RADXA_ZERO_151_I2C_COUNT 2 +#define MRAA_RADXA_ZERO_151_I2C_COUNT 3 #define MRAA_RADXA_ZERO_151_SPI_COUNT 2 #define MRAA_RADXA_ZERO_151_UART_COUNT 3 #define MRAA_RADXA_ZERO_151_PWM_COUNT 2 diff --git a/src/arm/radxa_zero_151.c b/src/arm/radxa_zero_151.c index 99eae14fe..f0975808c 100644 --- a/src/arm/radxa_zero_151.c +++ b/src/arm/radxa_zero_151.c @@ -64,9 +64,9 @@ mraa_radxa_zero() // UART b->uart_dev_count = MRAA_RADXA_ZERO_151_UART_COUNT; b->def_uart_dev = 0; - b->uart_dev[0].index = 0; - b->uart_dev[1].index = 1; - b->uart_dev[2].index = 2; + b->uart_dev[0].index = 0; // GPIOAO-0, GPIOAO-1 + b->uart_dev[1].index = 1; // GPIOAO-2, GPIOAO-3 / GPIOAO-8, GPIOAO-9 + b->uart_dev[2].index = 4; // GPIOH_6, GPIOH_7, GPIOH_4, GPIOH_5 b->uart_dev[0].device_path = (char*) radxa_zero_151_serialdev[0]; b->uart_dev[1].device_path = (char*) radxa_zero_151_serialdev[1]; b->uart_dev[2].device_path = (char*) radxa_zero_151_serialdev[2]; @@ -74,15 +74,15 @@ mraa_radxa_zero() // I2C b->i2c_bus_count = MRAA_RADXA_ZERO_151_I2C_COUNT; b->def_i2c_bus = 0; - b->i2c_bus[0].bus_id = 3; - b->i2c_bus[1].bus_id = 5; - // b->i2c_bus[2].bus_id = 1; + b->i2c_bus[0].bus_id = 1; // GPIOH-6, GPIOH-7 / GPIOX-10, GPIOX-11 + b->i2c_bus[1].bus_id = 3; // GPIOA-14, GPIOA-15 + b->i2c_bus[2].bus_id = 4; // GPIOAO-2, GPIOAO-3 // SPI b->spi_bus_count = MRAA_RADXA_ZERO_151_SPI_COUNT; b->def_spi_bus = 0; - b->spi_bus[0].bus_id = 0; - b->spi_bus[1].bus_id = 1; + b->spi_bus[0].bus_id = 0; // GPIOX_10, GPIOX_11, GPIOX_8, GPIOX_9 + b->spi_bus[1].bus_id = 1; // GPIOH_6, GPIOH_7, GPIOH_4, GPIOH_5 // PWM b->pwm_dev_count = MRAA_RADXA_ZERO_151_PWM_COUNT; @@ -97,12 +97,12 @@ mraa_radxa_zero() return NULL; } - b->pins[18].pwm.parent_id = 6; // PWM18 + b->pins[18].pwm.parent_id = 0; // GPIOX_8 b->pins[18].pwm.mux_total = 0; b->pins[18].pwm.pinmap = 0; - b->pins[40].pwm.parent_id = 2; // PWM40 + b->pins[40].pwm.parent_id = 2; // GPIOAO_11 b->pins[40].pwm.mux_total = 0; - b->pins[40].pwm.pinmap = 0; + b->pins[40].pwm.pinmap = 1; mraa_radxa_zero_pininfo(b, 0, -1, -1, (mraa_pincapabilities_t) { 0, 0, 0, 0, 0, 0, 0, 0 }, "INVALID"); mraa_radxa_zero_pininfo(b, 1, -1, -1, (mraa_pincapabilities_t) { 1, 0, 0, 0, 0, 0, 0, 0 }, "3V3"); diff --git a/src/pwm/pwm.c b/src/pwm/pwm.c index cdf57f302..04857b198 100644 --- a/src/pwm/pwm.c +++ b/src/pwm/pwm.c @@ -52,14 +52,14 @@ mraa_pwm_write_period(mraa_pwm_context dev, int period) int period_f = open(bu, O_RDWR); if (period_f == -1) { - syslog(LOG_ERR, "pwm%i write_period: Failed to open period for writing: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i write_period: Failed to open period for writing: %s", dev->chipid, dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } char out[MAX_SIZE]; int length = snprintf(out, MAX_SIZE, "%d", period); if (write(period_f, out, length * sizeof(char)) == -1) { close(period_f); - syslog(LOG_ERR, "pwm%i write_period: Failed to write to period: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i write_period: Failed to write to period: %s", dev->chipid, dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } @@ -81,7 +81,7 @@ mraa_pwm_write_duty(mraa_pwm_context dev, int duty) } if (dev->duty_fp == -1) { if (mraa_pwm_setup_duty_fp(dev) == 1) { - syslog(LOG_ERR, "pwm%i write_duty: Failed to open duty_cycle for writing: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i write_duty: Failed to open duty_cycle for writing: %s", dev->chipid, dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } } @@ -89,7 +89,7 @@ mraa_pwm_write_duty(mraa_pwm_context dev, int duty) int length = snprintf(bu, MAX_SIZE, "%d", duty); if (write(dev->duty_fp, bu, length * sizeof(char)) == -1) { - syslog(LOG_ERR, "pwm%i write_duty: Failed to write to duty_cycle: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i write_duty: Failed to write to duty_cycle: %s", dev->chipid, dev->pin, strerror(errno)); return MRAA_ERROR_INVALID_RESOURCE; } return MRAA_SUCCESS; @@ -113,7 +113,7 @@ mraa_pwm_read_period(mraa_pwm_context dev) int period_f = open(bu, O_RDWR); if (period_f == -1) { - syslog(LOG_ERR, "pwm%i read_period: Failed to open period for reading: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_period: Failed to open period for reading: %s", dev->chipid, dev->pin, strerror(errno)); return 0; } @@ -121,17 +121,17 @@ mraa_pwm_read_period(mraa_pwm_context dev) close(period_f); if (rb < 0) { - syslog(LOG_ERR, "pwm%i read_period: Failed to read period: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_period: Failed to read period: %s", dev->chipid, dev->pin, strerror(errno)); return -1; } char* endptr; long int ret = strtol(output, &endptr, 10); if ('\0' != *endptr && '\n' != *endptr) { - syslog(LOG_ERR, "pwm%i read_period: Error in string conversion", dev->pin); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_period: Error in string conversion", dev->chipid, dev->pin); return -1; } else if (ret > INT_MAX || ret < INT_MIN) { - syslog(LOG_ERR, "pwm%i read_period: Number is invalid", dev->pin); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_period: Number is invalid", dev->chipid, dev->pin); return -1; } dev->period = (int) ret; @@ -152,8 +152,8 @@ mraa_pwm_read_duty(mraa_pwm_context dev) if (dev->duty_fp == -1) { if (mraa_pwm_setup_duty_fp(dev) == 1) { - syslog(LOG_ERR, "pwm%i read_duty: Failed to open duty_cycle for reading: %s", - dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_duty: Failed to open duty_cycle for reading: %s", + dev->chipid, dev->pin, strerror(errno)); return -1; } } else { @@ -163,17 +163,17 @@ mraa_pwm_read_duty(mraa_pwm_context dev) char output[MAX_SIZE]; ssize_t rb = read(dev->duty_fp, output, MAX_SIZE); if (rb < 0) { - syslog(LOG_ERR, "pwm%i read_duty: Failed to read duty_cycle: %s", dev->pin, strerror(errno)); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_duty: Failed to read duty_cycle: %s", dev->chipid, dev->pin, strerror(errno)); return -1; } char* endptr; long int ret = strtol(output, &endptr, 10); if ('\0' != *endptr && '\n' != *endptr) { - syslog(LOG_ERR, "pwm%i read_duty: Error in string conversion", dev->pin); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_duty: Error in string conversion", dev->chipid, dev->pin); return -1; } else if (ret > INT_MAX || ret < INT_MIN) { - syslog(LOG_ERR, "pwm%i read_duty: Number is invalid", dev->pin); + syslog(LOG_ERR, "pwmchip%i/pwm%i read_duty: Number is invalid", dev->chipid, dev->pin); return -1; } return (int) ret; @@ -289,14 +289,14 @@ mraa_pwm_init_raw(int chipin, int pin) snprintf(directory, MAX_SIZE, SYSFS_PWM "/pwmchip%d/pwm%d", dev->chipid, dev->pin); struct stat dir; if (stat(directory, &dir) == 0 && S_ISDIR(dir.st_mode)) { - syslog(LOG_NOTICE, "pwm_init: pwm%i already exported, continuing", pin); + syslog(LOG_NOTICE, "pwm_init: pwmchip%i/pwm%i already exported, continuing", dev->chipid, dev->pin); dev->owner = 0; // Not Owner } else { char buffer[MAX_SIZE]; snprintf(buffer, MAX_SIZE, "/sys/class/pwm/pwmchip%d/export", dev->chipid); int export_f = open(buffer, O_WRONLY); if (export_f == -1) { - syslog(LOG_ERR, "pwm_init: pwm%i. Failed to open export for writing: %s", pin, strerror(errno)); + syslog(LOG_ERR, "pwm_init: pwmchip%i/pwm%i. Failed to open export for writing: %s", dev->chipid, dev->pin, strerror(errno)); free(dev); return NULL; } @@ -304,7 +304,7 @@ mraa_pwm_init_raw(int chipin, int pin) char out[MAX_SIZE]; int size = snprintf(out, MAX_SIZE, "%d", dev->pin); if (write(export_f, out, size * sizeof(char)) == -1) { - syslog(LOG_WARNING, "pwm_init: pwm%i. Failed to write to export! (%s) Potentially already in use.", pin, strerror(errno)); + syslog(LOG_WARNING, "pwm_init: pwmchip%i/pwm%i. Failed to write to export! (%s) Potentially already in use.", dev->chipid, dev->pin, strerror(errno)); close(export_f); free(dev); return NULL; @@ -329,7 +329,7 @@ mraa_pwm_write(mraa_pwm_context dev, float percentage) if (IS_FUNC_DEFINED(dev, pwm_write_pre)) { if (dev->advance_func->pwm_write_pre(dev, percentage) != MRAA_SUCCESS) { - syslog(LOG_ERR, "mraa_pwm_write (pwm%i): pwm_write_pre failed, see syslog", dev->pin); + syslog(LOG_ERR, "mraa_pwm_write (pwmchip%i/pwm%i): pwm_write_pre failed, see syslog", dev->chipid, dev->pin); return MRAA_ERROR_UNSPECIFIED; } } From 53f1d89f53a248e3180e0bb0ddbd14029944aed0 Mon Sep 17 00:00:00 2001 From: Sergey Ko Date: Mon, 16 Dec 2024 14:35:12 -0600 Subject: [PATCH 3/4] radxa zero i2c fix --- include/arm/radxa_zero_151.h | 2 +- src/arm/radxa_zero_151.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/arm/radxa_zero_151.h b/include/arm/radxa_zero_151.h index 991aee889..9c135e42d 100644 --- a/include/arm/radxa_zero_151.h +++ b/include/arm/radxa_zero_151.h @@ -14,7 +14,7 @@ extern "C" { #include "mraa_internal.h" #define MRAA_RADXA_ZERO_151_GPIO_COUNT 23 -#define MRAA_RADXA_ZERO_151_I2C_COUNT 3 +#define MRAA_RADXA_ZERO_151_I2C_COUNT 4 #define MRAA_RADXA_ZERO_151_SPI_COUNT 2 #define MRAA_RADXA_ZERO_151_UART_COUNT 3 #define MRAA_RADXA_ZERO_151_PWM_COUNT 2 diff --git a/src/arm/radxa_zero_151.c b/src/arm/radxa_zero_151.c index f0975808c..4b09c95d5 100644 --- a/src/arm/radxa_zero_151.c +++ b/src/arm/radxa_zero_151.c @@ -74,9 +74,10 @@ mraa_radxa_zero() // I2C b->i2c_bus_count = MRAA_RADXA_ZERO_151_I2C_COUNT; b->def_i2c_bus = 0; - b->i2c_bus[0].bus_id = 1; // GPIOH-6, GPIOH-7 / GPIOX-10, GPIOX-11 - b->i2c_bus[1].bus_id = 3; // GPIOA-14, GPIOA-15 - b->i2c_bus[2].bus_id = 4; // GPIOAO-2, GPIOAO-3 + b->i2c_bus[0].bus_id = 1; // GPIOAO-2, GPIOAO-3 + b->i2c_bus[1].bus_id = 3; // GPIOX-10, GPIOX-11 + b->i2c_bus[2].bus_id = 4; // GPIOH-6, GPIOH-7 + b->i2c_bus[3].bus_id = 5; // GPIOA-14, GPIOA-15 // SPI b->spi_bus_count = MRAA_RADXA_ZERO_151_SPI_COUNT; @@ -97,10 +98,10 @@ mraa_radxa_zero() return NULL; } - b->pins[18].pwm.parent_id = 0; // GPIOX_8 + b->pins[18].pwm.parent_id = 0; // GPIOX_8 b->pins[18].pwm.mux_total = 0; b->pins[18].pwm.pinmap = 0; - b->pins[40].pwm.parent_id = 2; // GPIOAO_11 + b->pins[40].pwm.parent_id = 2; // GPIOAO_11 b->pins[40].pwm.mux_total = 0; b->pins[40].pwm.pinmap = 1; From 021a934d126baff020518971af537200dd8de9f8 Mon Sep 17 00:00:00 2001 From: Sergey Ko Date: Mon, 16 Dec 2024 15:24:30 -0600 Subject: [PATCH 4/4] README update, added Radxa Zero --- README.md | 1 + docs/radxa_zero.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 docs/radxa_zero.md diff --git a/README.md b/README.md index 3c7dc2f26..8dab274ef 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ ARM * [Radxa ROCK 3C](../master/docs/radxa_rock_3c.md) * [Radxa ROCK 5A](../master/docs/radxa_rock_5a.md) * [Radxa ROCK 5B](../master/docs/radxa_rock_5b.md) +* [Radxa ZERO](../master/docs/radxa_zero.md) * [Radxa ZERO3](../master/docs/radxa_zero3.md) * [Rock Pi 4](../master/docs/rockpi4.md) * [Orange Pi Prime](../master/docs/orange_pi_prime.md) diff --git a/docs/radxa_zero.md b/docs/radxa_zero.md new file mode 100644 index 000000000..e128bbae5 --- /dev/null +++ b/docs/radxa_zero.md @@ -0,0 +1,44 @@ +Radxa ZERO {#_Radxa} +===================== + +Radxa Zero is an ultra thin SBC in small form factor with powerful performance based on Amlogic S905Y2. It can run Android and selected Linux distributions. + +Radxa Zero features a quad core 64-bit ARM processor, up to 4GB 32bit LPDDR4 memory, HDMI output at 4K@60, WiFi and BT connectivity, USB 3.0, and 40-pin GPIO header. Additionally, the power port can also be used for USB 2.0 OTG to connect more peripheral. + +Radxa Zero comes in multiple configurations to suit your need. Please check Models & SKU for detail. + +Pin Mapping (rev. 1.51) +----------- + +| GPIO number | Function4 | Function3 | Function2 | Function1 | Pin# | Pin# | Function1 | Function2 | Function3 | Function4 | GPIO number | +|:-----:|:-----:|:-----:|:-----:|:-----:|-----:|:-----|:-----:|:-----:|:-----:|:-----:|:-----:| +| | | | | +3.3V | **1** | **2** | +5.0V | | | | || +| 490 | | | I2C_EE_M3_SDA | GPIOA_14 (*) | **3** | **4** | +5.0V | | | || +| 491 | | | I2C_EE_M3_SCL | GPIOA_15 (*) | **5** | **6** | GND | | | || +| 415 | I2C_AO_S0_SDA | UART_AO_B_RX | I2C_AO_M0_SDA | GPIOAO_3 | **7** | **8** | GPIOAO_0 | UART_AO_A_TXD | | | 412 | +| | | | GND | | **9** | **10** | GPIOAO_1 | UART_AO_A_RXD | | | 413 | +| 414 | I2C_AO_S0_SCL | UART_AO_B_TX | I2C_AO_M0_SCL | GPIOAO_2 | **11** | **12** | GPIOX_9 | SPI_A_MISO | TDMA_D0 | | 501 | +| 503 | TDMA_SCLK | I2C_EE_M1_SCL |SPI_A_SCLK | GPIOX_11 | **13** | **14** | GND | | | | +| | | | SARADC_CH1 | | **15** | **16** | GPIOX_10 | SPI_A_SS0 | I2C_EE_M1_SDA | TDMA_FS | 502 | +| | | | +3.3V | | **17** | **18** | GPIOX_8 | SPI_A_MOSI | PWM_C | TDMA_D1 | 500 | +| 447 | SPI_B_MOSI | UART_EE_C_RTS | GPIOH_4 | | **19** | **20** | GND | | | | +| 448 | PWM_F | SPI_B_MISO | UART_EE_C_CTS | GPIOH_5 | **21** | **22** | GPIOC_7 | - | | | 475 | +| 450 | I2C_EE_M1_SCL | SPI_B_SCLK | UART_EE_C_TX | GPIOH_7 | **23** | **24** | GPIOH_6 | UART_EE_C_RX | SPI_B_SS0 | I2C_EE_M1_SDA | 449 | +| | | | GND | | **25** | **26** | SARADC_CH2 | | | || +| 415 | I2C_AO_S0_SDA | UART_AO_B_RX | I2C_AO_M0_SDA | GPIOAO_3 | **27** | **28** | GPIOAO_2 | I2C_AO_M0_SCL | ART_AO_B_TX | I2C_AO_S0_SCL | 414 | +| | | | NC | | **29** | **30** | GND | | | | +| | | | NC | | **31** | **32** | GPIOAO_4 | PWMAO_C | | | 416 | +| | | | NC | | **33** | **34** | GND | | | | +| 420 | | | UART_AO_B_TX | GPIOAO_8 | **35** | **36** | GPIOH_8 | - | | | 451 | +| 421 | | | UART_AO_B_RX | GPIOAO_9 | **37** | **38** | NC | | | | +| | | | GND | | **39** | **40** | GPIOAO_11 | PWMAO_A | | | 423 | + +Supports +-------- + +You can find additional product support in the following channels: + +- [Product Info](https://docs.radxa.com/en/zero/zero) +- [Wiki](https://wiki.radxa.com/Zero) +- [Forums](https://forum.radxa.com/c/zero) +- [Github](https://github.com/radxa)