diff --git a/Documentation/platforms/arm/a64/boards/pinephone/index.rst b/Documentation/platforms/arm/a64/boards/pinephone/index.rst index 8e7b9fa3bea..d53a662d562 100644 --- a/Documentation/platforms/arm/a64/boards/pinephone/index.rst +++ b/Documentation/platforms/arm/a64/boards/pinephone/index.rst @@ -12,7 +12,8 @@ Features - **GPU:** ARM Mali400 MP2 - **Interrupt Controller:** ARM GIC PL400 (Generic Interrupt Controller v2) - **Display Engine:** Allwinner Display Engine 2.0 (MIPI DSI with DMA) -- **Display:** Xingbangda XBD599 HD IPS Capacitive Touchscreen (5.95 inches, 1440x720 resolution, 16M colors, PWM Backlight) +- **Display:** Xingbangda XBD599 HD IPS Display (5.95 inches, 1440x720 resolution, 16M colors, PWM Backlight) +- **Touch Panel:** Goodix GT917S Capacitive Touch Panel (I2C) - **LCD Controller:** Sitronix ST7703 (MIPI DSI) - **RAM:** 2GB or 3GB LPDDR3 SDRAM - **Internal Storage:** 16GB or 32GB eMMC, extendable up to 2TB via microSD @@ -25,7 +26,9 @@ Features - 2.4 GHz Wireless: Realtek RTL8723CS - **WLAN:** WiFi 802.11 b/g/n, single-band, hotspot - **Bluetooth:** 4.0, A2DP -- **Sensors:** Accelerometer, Gyroscope, Proximity, Ambient Light, Compass +- **Magnetometer:** STMicroelectronics LIS3MDL +- **Ambient Light / Proximity:** SensorTek STK3335 +- **Accelerometer / Gyroscope:** InvenSense MPU-6050 (I2C) - **Privacy Switches:** Modem, WiFi & Bluetooth, Microphone, Cameras, Headphone - **Battery:** Lithium-ion, rated capacity 2800mAh (10.64Wh), typical capacity 3000mAh (11.40Wh) - **I/O:** USB Type-C, USB Host, DisplayPort Alternate Mode output, 15W 5V 3A Quick Charge, follows USB PD specification @@ -74,7 +77,7 @@ Configure the NuttX project and build the project: .. code:: console $ cd nuttx - $ tools/configure.sh pinephone:lcd + $ tools/configure.sh pinephone:lvgl $ make $ cp nuttx.bin Image $ rm -f Image.gz @@ -114,6 +117,12 @@ To see the available commands in NuttShell: $ help +To run the LVGL Touchscreen Demo: + +.. code:: console + + $ lvgldemo widgets + LEDs ==== @@ -139,6 +148,13 @@ Power Management Integrated Circuit (AXP803) and Reduced Serial Bus (RSB). Serial Console is enabled on UART0 at 115.2 kbps. +lvgl +____ + +Supports all the features in ``lcd``, +plus LVGL Graphics Library and Touch Panel (GT917S). +Serial Console is enabled on UART0 at 115.2 kbps. + nsh --- @@ -147,14 +163,23 @@ This configuration is focused on low level, command-line driver testing. Built-in applications are supported, but none are enabled. Serial Console is enabled on UART0 at 115.2 kbps. +sensor +------ + +Supports Accelerometer / Gyroscope (MPU-6050), +Power Management Integrated Circuit (AXP803) and +Reduced Serial Bus (RSB). +Serial Console is enabled on UART0 at 115.2 kbps. + Peripheral Support ================== NuttX for PinePhone supports these peripherals: -======================= ======= ===== -Peripheral Support NOTES -======================= ======= ===== +======================== ======= ===== +Peripheral Support NOTES +======================== ======= ===== +Accelerometer (MPU-6050) Yes Backlight Yes Display Engine Yes Frame Buffer Yes @@ -166,6 +191,7 @@ PIO Yes PMIC (AXP803) Yes RSB Yes TCON0 Yes -TWI Yes -UART Yes Only UART0 is supported -======================= ======= ===== +TWI / I2C Yes +Touch Panel (GT917S) Yes +UART Yes Only UART0 is supported +======================== ======= ===== diff --git a/boards/arm64/a64/pinephone/configs/lvgl/defconfig b/boards/arm64/a64/pinephone/configs/lvgl/defconfig new file mode 100644 index 00000000000..925489f8cae --- /dev/null +++ b/boards/arm64/a64/pinephone/configs/lvgl/defconfig @@ -0,0 +1,87 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_A64_TWI0=y +CONFIG_A64_UART=y +CONFIG_ARCH="arm64" +CONFIG_ARCH_ARM64=y +CONFIG_ARCH_BOARD="pinephone" +CONFIG_ARCH_BOARD_PINEPHONE=y +CONFIG_ARCH_CHIP="a64" +CONFIG_ARCH_CHIP_A64=y +CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=116524 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_SCHED=y +CONFIG_DEBUG_SCHED_ERROR=y +CONFIG_DEBUG_SCHED_WARN=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_WARN=y +CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_DEV_ZERO=y +CONFIG_EXAMPLES_FB=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_LEDS=y +CONFIG_EXAMPLES_LVGLDEMO=y +CONFIG_EXAMPLES_TOUCHSCREEN=y +CONFIG_EXPERIMENTAL=y +CONFIG_FS_PROCFS=y +CONFIG_FS_ROMFS=y +CONFIG_GRAPHICS_LVGL=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_HOST_MACOS=y +CONFIG_I2C=y +CONFIG_IDLETHREAD_STACKSIZE=8192 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INPUT_GT9XX=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LV_COLOR_DEPTH_32=y +CONFIG_LV_DPI_DEF=267 +CONFIG_LV_FONT_DEFAULT_MONTSERRAT_20=y +CONFIG_LV_MEM_SIZE_KILOBYTES=64 +CONFIG_LV_PORT_USE_FBDEV=y +CONFIG_LV_PORT_USE_TOUCHPAD=y +CONFIG_LV_TICK_CUSTOM=y +CONFIG_LV_TICK_CUSTOM_INCLUDE="port/lv_port_tick.h" +CONFIG_LV_USE_DEMO_WIDGETS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_PINEPHONE_LCD=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PTHREAD_STACK_MIN=8192 +CONFIG_RAMLOG=y +CONFIG_RAM_SIZE=134217728 +CONFIG_RAM_START=0x40000000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SPINLOCK=y +CONFIG_STACK_COLORATION=y +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2022 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SYSTEM=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART1_SERIAL_CONSOLE=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_USERLED=y +CONFIG_USERLED_LOWER=y diff --git a/boards/arm64/a64/pinephone/src/Makefile b/boards/arm64/a64/pinephone/src/Makefile index 4b3911798d3..353d3ae6344 100644 --- a/boards/arm64/a64/pinephone/src/Makefile +++ b/boards/arm64/a64/pinephone/src/Makefile @@ -41,4 +41,8 @@ ifeq ($(CONFIG_VIDEO_FB),y) CSRCS += pinephone_display.c pinephone_lcd.c endif +ifeq ($(CONFIG_INPUT_GT9XX),y) +CSRCS += pinephone_touch.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm64/a64/pinephone/src/pinephone_bringup.c b/boards/arm64/a64/pinephone/src/pinephone_bringup.c index 4694343db77..3ea296a35b2 100644 --- a/boards/arm64/a64/pinephone/src/pinephone_bringup.c +++ b/boards/arm64/a64/pinephone/src/pinephone_bringup.c @@ -23,15 +23,16 @@ ****************************************************************************/ #include +#include #include #include +#include "a64_twi.h" +#include "pinephone.h" +#include "pinephone_pmic.h" + #ifdef CONFIG_I2C # include #endif -#include -#ifdef CONFIG_MPU60X0_I2C -# include -#endif #ifdef CONFIG_FS_PROCFS # include @@ -46,9 +47,13 @@ # include "pinephone_display.h" #endif -#include "a64_twi.h" -#include "pinephone.h" -#include "pinephone_pmic.h" +#ifdef CONFIG_INPUT_GT9XX +# include "pinephone_touch.h" +#endif + +#ifdef CONFIG_MPU60X0_I2C +# include +#endif /**************************************************************************** * Public Functions @@ -64,13 +69,20 @@ int pinephone_bringup(void) { - int ret; -#ifdef CONFIG_I2C - int i2c_bus; - struct i2c_master_s *i2c; -#ifdef CONFIG_MPU60X0_I2C - struct mpu_config_s *mpu_config; + int ret = OK; + +#if defined(CONFIG_I2C) && defined(CONFIG_A64_TWI0) + const int i2c0_bus = 0; + struct i2c_master_s *i2c0 = NULL; #endif + +#if defined(CONFIG_I2C) && defined(CONFIG_A64_TWI1) + const int i2c1_bus = 1; + struct i2c_master_s *i2c1 = NULL; +#endif + +#if defined(CONFIG_MPU60X0_I2C) && defined(CONFIG_A64_TWI1) + struct mpu_config_s *mpu_config = NULL; #endif #ifdef CONFIG_USERLED @@ -107,25 +119,62 @@ int pinephone_bringup(void) pinephone_display_test_pattern(); #endif -#if defined(CONFIG_I2C) && defined(CONFIG_A64_TWI1) - i2c_bus = 1; - i2c = a64_i2cbus_initialize(i2c_bus); - if (i2c == NULL) +#if defined(CONFIG_I2C) && defined(CONFIG_A64_TWI0) + /* Initialize TWI0 as I2C Bus 0 */ + + i2c0 = a64_i2cbus_initialize(i2c0_bus); + if (i2c0 == NULL) { - syslog(LOG_ERR, "ERROR: Failed to get I2C%d interface\n", i2c_bus); + syslog(LOG_ERR, "ERROR: Failed to get I2C%d interface\n", i2c0_bus); } - else +#endif + +#if defined(CONFIG_I2C) && defined(CONFIG_A64_TWI1) + /* Initialize TWI1 as I2C Bus 1 */ + + i2c1 = a64_i2cbus_initialize(i2c1_bus); + if (i2c1 == NULL) { -#if defined(CONFIG_SYSTEM_I2CTOOL) - ret = i2c_register(i2c, i2c_bus); + syslog(LOG_ERR, "ERROR: Failed to get I2C%d interface\n", i2c1_bus); + } +#endif + +#if defined(CONFIG_SYSTEM_I2CTOOL) && defined(CONFIG_A64_TWI1) + /* Register I2C Driver for I2C Bus 1 at TWI1 */ + + if (i2c1 != NULL) + { + ret = i2c_register(i2c1, i2c1_bus); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to register I2C%d driver: %d\n", - i2c_bus, ret); + i2c1_bus, ret); } + } #endif -#ifdef CONFIG_MPU60X0_I2C +#if defined(CONFIG_INPUT_GT9XX) && defined(CONFIG_A64_TWI0) + /* Register Touch Input Driver for GT9XX Touch Panel at TWI0 */ + + if (i2c0 != NULL) + { + /* Register Touch Input Driver at /dev/input0 */ + + ret = pinephone_touch_panel_register("/dev/input0", i2c0); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to register Touch Input GT9xx: %d\n", + ret); + } + } +#endif + +#if defined(CONFIG_MPU60X0_I2C) && defined(CONFIG_A64_TWI1) + /* Register IMU Driver for MPU-60X0 Accelerometer at TWI1 */ + + if (i2c1 != NULL) + { /* Init PMIC */ ret = pinephone_pmic_init(); @@ -139,6 +188,8 @@ int pinephone_bringup(void) up_mdelay(15); + /* Register IMU Driver at /dev/imu0 */ + mpu_config = kmm_zalloc(sizeof(struct mpu_config_s)); if (mpu_config == NULL) { @@ -146,11 +197,10 @@ int pinephone_bringup(void) } else { - mpu_config->i2c = i2c; + mpu_config->i2c = i2c1; mpu_config->addr = 0x68; mpu60x0_register("/dev/imu0", mpu_config); } -#endif } #endif diff --git a/boards/arm64/a64/pinephone/src/pinephone_touch.c b/boards/arm64/a64/pinephone/src/pinephone_touch.c new file mode 100644 index 00000000000..c3ff169f31a --- /dev/null +++ b/boards/arm64/a64/pinephone/src/pinephone_touch.c @@ -0,0 +1,245 @@ +/**************************************************************************** + * boards/arm64/a64/pinephone/src/pinephone_touch.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Reference: + * "NuttX RTOS for PinePhone: Touch Panel" + * https://lupyuen.github.io/articles/touch2 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include "arm64_arch.h" +#include "arm64_gic.h" +#include "a64_pio.h" +#include "pinephone_touch.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Goodix GT917S Touch Panel Interrupt at PH4 */ + +#define CTP_INT (PIO_EINT | PIO_PORT_PIOH | PIO_PIN4) + +/* I2C Address for Touch Panel */ + +#define CTP_I2C_ADDR 0x5d + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int pinephone_gt9xx_irq_attach(const struct gt9xx_board_s *state, + xcpt_t isr, + FAR void *arg); +static void pinephone_gt9xx_irq_enable(const struct gt9xx_board_s *state, + bool enable); +static int pinephone_gt9xx_set_power(const struct gt9xx_board_s *state, + bool on); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Callback for Board-Specific Operations */ + +static const struct gt9xx_board_s g_pinephone_gt9xx = +{ + .irq_attach = pinephone_gt9xx_irq_attach, + .irq_enable = pinephone_gt9xx_irq_enable, + .set_power = pinephone_gt9xx_set_power +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pinephone_gt9xx_irq_attach + * + * Description: + * Attach the Interrupt Handler for Touch Panel. + * + * Input Parameters: + * state - Callback for Board-Specific Operations + * isr - Interrupt Handler + * arg - Argument for Interrupt Handler + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ****************************************************************************/ + +static int pinephone_gt9xx_irq_attach(const struct gt9xx_board_s *state, + xcpt_t isr, + FAR void *arg) +{ + int ret; + + iinfo("\n"); + DEBUGASSERT(state != NULL && isr != NULL && arg != NULL); + + /* Attach the Interrupt Handler to Port PH */ + + ret = irq_attach(A64_IRQ_PH_EINT, isr, arg); + if (ret < 0) + { + ierr("Attach Interrupt Handler failed: %d\n", ret); + return ret; + } + + /* Set Interrupt Priority in Generic Interrupt Controller v2 */ + + arm64_gic_irq_set_priority(A64_IRQ_PH_EINT, 0, IRQ_TYPE_EDGE); + + /* Enable Interrupts for Port PH */ + + up_enable_irq(A64_IRQ_PH_EINT); + + return OK; +} + +/**************************************************************************** + * Name: pinephone_gt9xx_irq_enable + * + * Description: + * Enable or disable Interrupts for the Touch Panel. + * + * Input Parameters: + * state - Callback for Board-Specific Operations + * enable - True to enable interrupts; False to disable interrupts + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ****************************************************************************/ + +static void pinephone_gt9xx_irq_enable(const struct gt9xx_board_s *state, + bool enable) +{ + int ret; + + iinfo("enable=%d\n", enable); + DEBUGASSERT(state != NULL); + + if (enable) + { + /* Configure the Touch Panel Interrupt */ + + ret = a64_pio_config(CTP_INT); + if (ret < 0) + { + ierr("Configure Touch Panel Interrupt failed: %d\n", ret); + return; + } + + /* Enable the Touch Panel Interrupt */ + + ret = a64_pio_irqenable(CTP_INT); + if (ret < 0) + { + ierr("Enable Touch Panel Interrupt failed: %d\n", ret); + return; + } + } + else + { + /* Disable the Touch Panel Interrupt */ + + ret = a64_pio_irqdisable(CTP_INT); + if (ret < 0) + { + ierr("Disable Touch Panel Interrupt failed: %d\n", ret); + return; + } + } +} + +/**************************************************************************** + * Name: pinephone_gt9xx_set_power + * + * Description: + * Power on or off the Touch Panel. + * + * Input Parameters: + * state - Callback for Board-Specific Operations + * on - True to power on; False to power off + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ****************************************************************************/ + +static int pinephone_gt9xx_set_power(const struct gt9xx_board_s *state, + bool on) +{ + /* Assume that Touch Panel is already powered on by pinephone_pmic_init() */ + + iinfo("on=%d\n", on); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pinephone_touch_panel_register + * + * Description: + * Register the driver for Goodix GT9XX Touch Panel. Attach the + * Interrupt Handler for the Touch Panel and disable Touch Interrupts. + * + * Input Parameters: + * devpath - Device Path (e.g. "/dev/input0") + * i2c - I2C Bus + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ****************************************************************************/ + +int pinephone_touch_panel_register(const char *devpath, + struct i2c_master_s *i2c) +{ + int ret; + + iinfo("devpath=%s\n", devpath); + DEBUGASSERT(devpath != NULL && i2c != NULL); + + ret = gt9xx_register(devpath, i2c, CTP_I2C_ADDR, &g_pinephone_gt9xx); + if (ret < 0) + { + ierr("Register Touch Input GT9xx failed: %d\n", ret); + return ret; + } + + return OK; +} diff --git a/boards/arm64/a64/pinephone/src/pinephone_touch.h b/boards/arm64/a64/pinephone/src/pinephone_touch.h new file mode 100644 index 00000000000..2f777d3dab0 --- /dev/null +++ b/boards/arm64/a64/pinephone/src/pinephone_touch.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * boards/arm64/a64/pinephone/src/pinephone_touch.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_TOUCH_H +#define __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_TOUCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: pinephone_touch_panel_register + * + * Description: + * Register the driver for Goodix GT9XX Touch Panel. Attach the + * Interrupt Handler for the Touch Panel and disable Touch Interrupts. + * + * Input Parameters: + * devpath - Device Path (e.g. "/dev/input0") + * i2c - I2C Bus + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ****************************************************************************/ + +int pinephone_touch_panel_register(const char *devpath, + struct i2c_master_s *i2c); + +#endif /* __BOARDS_ARM64_A64_PINEPHONE_SRC_PINEPHONE_TOUCH_H */ diff --git a/include/nuttx/input/gt9xx.h b/include/nuttx/input/gt9xx.h index fe105e7eb49..ccb49ac8ee1 100644 --- a/include/nuttx/input/gt9xx.h +++ b/include/nuttx/input/gt9xx.h @@ -43,9 +43,7 @@ struct gt9xx_board_s xcpt_t isr, FAR void *arg); - /* Enable or disable Interrupts for the Touch Panel. Will be called by - * Interrupt Handler. - */ + /* Enable or disable Interrupts for the Touch Panel */ void (*irq_enable) (const struct gt9xx_board_s *state, bool enable);