diff --git a/bsp/k230/.config b/bsp/k230/.config index 47d11534483..d6ef859ac50 100644 --- a/bsp/k230/.config +++ b/bsp/k230/.config @@ -116,7 +116,7 @@ CONFIG_RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS=4 # end of rt_strnlen options # end of klibc options -CONFIG_RT_NAME_MAX=16 +CONFIG_RT_NAME_MAX=32 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_NANO is not set CONFIG_RT_USING_SMART=y @@ -141,6 +141,7 @@ CONFIG_RT_TIMER_THREAD_PRIO=4 CONFIG_RT_TIMER_THREAD_STACK_SIZE=8192 # CONFIG_RT_USING_TIMER_ALL_SOFT is not set CONFIG_RT_USING_CPU_USAGE_TRACER=y +CONFIG_RT_CPU_USAGE_CALC_INTERVAL_MS=200 # # kservice options @@ -191,7 +192,8 @@ CONFIG_RT_USING_DEVICE_OPS=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" -CONFIG_RT_VER_NUM=0x50201 +CONFIG_RT_USING_CONSOLE_OUTPUT_CTL=y +CONFIG_RT_VER_NUM=0x50300 CONFIG_RT_USING_STDC_ATOMIC=y CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 # end of RT-Thread Kernel @@ -202,12 +204,10 @@ CONFIG_ARCH_MM_MMU=y CONFIG_KERNEL_VADDR_START=0xffffffc000000000 CONFIG_ARCH_RISCV=y CONFIG_ARCH_RISCV_FPU=y -CONFIG_ARCH_RISCV_VECTOR=y -CONFIG_ARCH_VECTOR_VLEN_128=y -# CONFIG_ARCH_VECTOR_VLEN_256 is not set -CONFIG_ARCH_RISCV_FPU_D=y CONFIG_ARCH_RISCV64=y +CONFIG_ARCH_RISCV_XUANTIE=y CONFIG_ARCH_USING_NEW_CTX_SWITCH=y +CONFIG_CONFIG_XUANTIE_SVPBMT=1 CONFIG_ARCH_REMAP_KERNEL=y # @@ -275,7 +275,7 @@ CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_ROMFS is not set CONFIG_RT_USING_DFS_PTYFS=y # CONFIG_RT_USING_DFS_PROCFS is not set -CONFIG_RT_USING_DFS_CROMFS=y +# CONFIG_RT_USING_DFS_CROMFS is not set CONFIG_RT_USING_DFS_TMPFS=y # CONFIG_RT_USING_DFS_MQUEUE is not set CONFIG_RT_USING_PAGECACHE=y @@ -311,9 +311,8 @@ CONFIG_RT_SERIAL_USING_DMA=y CONFIG_RT_SERIAL_RB_BUFSZ=64 CONFIG_RT_USING_SERIAL_BYPASS=y # CONFIG_RT_USING_CAN is not set -CONFIG_RT_USING_CPUTIME=y -CONFIG_RT_USING_CPUTIME_RISCV=y -CONFIG_CPUTIME_TIMER_FREQ=25000000 +CONFIG_RT_USING_CLOCK_TIME=y +CONFIG_CLOCK_TIMER_FREQ=250000 # CONFIG_RT_USING_I2C is not set # CONFIG_RT_USING_PHY is not set # CONFIG_RT_USING_PHY_V2 is not set @@ -330,7 +329,7 @@ CONFIG_RT_USING_RANDOM=y # CONFIG_RT_USING_PM is not set CONFIG_RT_USING_RTC=y # CONFIG_RT_USING_ALARM is not set -# CONFIG_RT_USING_SOFT_RTC is not set +CONFIG_RT_USING_SOFT_RTC=y CONFIG_RT_USING_SDIO=y CONFIG_RT_SDIO_STACK_SIZE=8192 CONFIG_RT_SDIO_THREAD_PRIORITY=15 @@ -356,10 +355,10 @@ CONFIG_RT_BLK_PARTITION_DFS=y CONFIG_RT_BLK_PARTITION_EFI=y # end of Partition Types +# CONFIG_RT_USING_REGULATOR is not set +# CONFIG_RT_USING_POWER_SUPPLY is not set # CONFIG_RT_USING_VIRTIO is not set CONFIG_RT_USING_PIN=y -CONFIG_RT_USING_KTIME=y -# CONFIG_RT_USING_HWTIMER is not set # CONFIG_RT_USING_CHERRYUSB is not set # end of Device Drivers @@ -408,7 +407,8 @@ CONFIG_RT_USING_POSIX_TIMER=y # # Interprocess Communication (IPC) # -# CONFIG_RT_USING_POSIX_PIPE is not set +CONFIG_RT_USING_POSIX_PIPE=y +CONFIG_RT_USING_POSIX_PIPE_SIZE=2048 # CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set # CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set @@ -537,6 +537,7 @@ CONFIG_RT_USING_ADT_REF=y # # Memory management # +# CONFIG_RT_PAGE_MPR_SIZE_DYNAMIC is not set CONFIG_RT_PAGE_AFFINITY_BLOCK_SIZE=0x1000 CONFIG_RT_PAGE_MAX_ORDER=11 # CONFIG_RT_USING_MEMBLOCK is not set @@ -574,6 +575,7 @@ CONFIG_RT_USING_VDSO=y # end of Using USB legacy version # CONFIG_RT_USING_FDT is not set +# CONFIG_RT_USING_RUST is not set # end of RT-Thread Components # @@ -775,6 +777,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_U8G2 is not set # end of u8g2: a monochrome graphic library +# CONFIG_PKG_USING_NES_SIMULATOR is not set # CONFIG_PKG_USING_OPENMV is not set # CONFIG_PKG_USING_MUPDF is not set # CONFIG_PKG_USING_STEMWIN is not set @@ -799,6 +802,9 @@ CONFIG_RT_USING_VDSO=y # # tools packages # +# CONFIG_PKG_USING_VECTOR is not set +# CONFIG_PKG_USING_SORCH is not set +# CONFIG_PKG_USING_DICT is not set # CONFIG_PKG_USING_CMBACKTRACE is not set # CONFIG_PKG_USING_MCOREDUMP is not set # CONFIG_PKG_USING_EASYFLASH is not set @@ -847,6 +853,9 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_RVBACKTRACE is not set # CONFIG_PKG_USING_HPATCHLITE is not set # CONFIG_PKG_USING_THREAD_METRIC is not set +# CONFIG_PKG_USING_UORB is not set +# CONFIG_PKG_USING_RT_TUNNEL is not set +# CONFIG_PKG_USING_VIRTUAL_TERMINAL is not set # end of tools packages # @@ -907,7 +916,13 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_LITTLEFS is not set # CONFIG_PKG_USING_DFS_JFFS2 is not set # CONFIG_PKG_USING_DFS_UFFS is not set -# CONFIG_PKG_USING_LWEXT4 is not set +CONFIG_PKG_USING_LWEXT4=y +CONFIG_PKG_LWEXT4_PATH="/packages/system/lwext4" +CONFIG_RT_USING_DFS_LWEXT4=y +# CONFIG_PKG_USING_LWEXT4_V200 is not set +CONFIG_PKG_USING_LWEXT4_LATEST_VERSION=y +# CONFIG_PKG_USING_LWEXT4_V110 is not set +CONFIG_PKG_LWEXT4_VER="latest" # CONFIG_PKG_USING_THREAD_POOL is not set # CONFIG_PKG_USING_ROBOTS is not set # CONFIG_PKG_USING_EV is not set @@ -941,6 +956,9 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_R_RHEALSTONE is not set # CONFIG_PKG_USING_HEARTBEAT is not set # CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set +# CONFIG_PKG_USING_CHERRYECAT is not set +# CONFIG_PKG_USING_EVENT_LOOP is not set +# CONFIG_PKG_USING_THREAD_MANAGER is not set # end of system packages # @@ -1097,7 +1115,24 @@ CONFIG_RT_USING_VDSO=y # # CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set # CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set +# CONFIG_PKG_USING_GD32_RISCV_SERIES_DRIVER is not set +# CONFIG_PKG_USING_GD32VW55X_WIFI is not set # end of GD32 Drivers + +# +# HPMicro SDK +# +# CONFIG_PKG_USING_HPM_SDK is not set +# end of HPMicro SDK + +# +# FT32 HAL & SDK Drivers +# +# CONFIG_PKG_USING_FT32F0_STD_DRIVER is not set +# CONFIG_PKG_USING_FT32F0_CMSIS_DRIVER is not set +# CONFIG_PKG_USING_FT32F4_STD_DRIVER is not set +# CONFIG_PKG_USING_FT32F4_CMSIS_DRIVER is not set +# end of FT32 HAL & SDK Drivers # end of HAL & SDK Drivers # @@ -1143,9 +1178,11 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_RT3020 is not set # CONFIG_PKG_USING_MLX90632 is not set # CONFIG_PKG_USING_MLX90382 is not set +# CONFIG_PKG_USING_MLX90384 is not set # CONFIG_PKG_USING_MLX90393 is not set # CONFIG_PKG_USING_MLX90392 is not set # CONFIG_PKG_USING_MLX90394 is not set +# CONFIG_PKG_USING_MLX90396 is not set # CONFIG_PKG_USING_MLX90397 is not set # CONFIG_PKG_USING_MS5611 is not set # CONFIG_PKG_USING_MAX31865 is not set @@ -1174,6 +1211,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_P3T1755 is not set # CONFIG_PKG_USING_QMI8658 is not set # CONFIG_PKG_USING_ICM20948 is not set +# CONFIG_PKG_USING_SCD4X is not set # end of sensors drivers # @@ -1191,6 +1229,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_CST812T is not set # end of touch drivers +# CONFIG_PKG_USING_LCD_SPI_DRIVER is not set # CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_BUTTON is not set # CONFIG_PKG_USING_PCF8574 is not set @@ -1270,6 +1309,13 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_IC74HC165 is not set # CONFIG_PKG_USING_IST8310 is not set # CONFIG_PKG_USING_ST7789_SPI is not set +# CONFIG_PKG_USING_CAN_UDS is not set +# CONFIG_PKG_USING_ISOTP_C is not set +# CONFIG_PKG_USING_IKUNLED is not set +# CONFIG_PKG_USING_INS5T8025 is not set +# CONFIG_PKG_USING_IRUART is not set +# CONFIG_PKG_USING_ST7305 is not set +# CONFIG_PKG_USING_TM1668 is not set # CONFIG_PKG_USING_SPI_TOOLS is not set # end of peripheral libraries and drivers @@ -1344,13 +1390,7 @@ CONFIG_RT_USING_VDSO=y # CONFIG_PKG_USING_MULTIBUTTON is not set # CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set # CONFIG_PKG_USING_CANFESTIVAL is not set -CONFIG_PKG_USING_ZLIB=y -CONFIG_PKG_ZLIB_PATH="/packages/misc/zlib" -# CONFIG_ZLIB_USING_SAMPLE is not set -# CONFIG_PKG_USING_ZLIB_V100 is not set -# CONFIG_PKG_USING_ZLIB_V123 is not set -CONFIG_PKG_USING_ZLIB_LATEST_VERSION=y -CONFIG_PKG_ZLIB_VER="latest" +# CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_MINIZIP is not set # CONFIG_PKG_USING_HEATSHRINK is not set # CONFIG_PKG_USING_DSTR is not set @@ -1618,6 +1658,8 @@ CONFIG_PKG_ZLIB_VER="latest" # Drivers Configuration # # CONFIG_BSP_USING_GNNE is not set +CONFIG_BSP_USING_GPIO=y +CONFIG_BSP_USING_DISPLAY=y # CONFIG_BSP_USING_SPI is not set # CONFIG_BSP_USING_I2C is not set # CONFIG_BSP_USING_RTC is not set @@ -1637,16 +1679,18 @@ CONFIG_BSP_USING_SDIO0=y # CONFIG_BSP_SDIO0_EMMC is not set # CONFIG_BSP_SDIO0_1V8 is not set # CONFIG_BSP_USING_SDIO1 is not set -CONFIG_BSP_SD_MNT_DEVNAME="sd0p1" +CONFIG_BSP_SD_MNT_DEVNAME="sd0p0" # CONFIG_BSP_USING_TIMERS is not set # CONFIG_BSP_USING_WDT is not set # CONFIG_BSP_USING_PDMA is not set # CONFIG_BSP_UTEST_DRIVERS is not set # end of Drivers Configuration +# CONFIG_SOC_K230 is not set +CONFIG_SOC_K230D=y CONFIG_BOARD_C908=y CONFIG___STACKSIZE__=65536 CONFIG_BSP_ROOTFS_TYPE_ELMFAT=y # CONFIG_BSP_ROOTFS_TYPE_CROMFS is not set -# CONFIG_BSP_RISCV_FPU_SOFT is not set -CONFIG_BSP_RISCV_FPU_D=y +CONFIG_BSP_RISCV_FPU_SOFT=y +# CONFIG_BSP_RISCV_FPU_D is not set diff --git a/bsp/k230/Kconfig b/bsp/k230/Kconfig index 3ddee1c468c..e6791a7b6b1 100644 --- a/bsp/k230/Kconfig +++ b/bsp/k230/Kconfig @@ -10,15 +10,35 @@ source "$RTT_DIR/Kconfig" source "$PKGS_DIR/Kconfig" rsource "board/Kconfig" -config BOARD_C908 - bool +choice + prompt "SoC variant" + default SOC_K230 + +config SOC_K230 + bool "K230" + select ARCH_RISCV64 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + select RT_USING_CACHE + select ARCH_MM_MMU + select ARCH_RISCV_FPU + select ARCH_RISCV_XUANTIE + select ARCH_REMAP_KERNEL if RT_USING_SMART + +config SOC_K230D + bool "K230D (128MB DDR)" select ARCH_RISCV64 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN select RT_USING_CACHE - select ARCH_MM_MMU + select ARCH_MM_MMU select ARCH_RISCV_FPU + select ARCH_RISCV_XUANTIE select ARCH_REMAP_KERNEL if RT_USING_SMART +endchoice + +config BOARD_C908 + bool default y config __STACKSIZE__ diff --git a/bsp/k230/applications/SConscript b/bsp/k230/applications/SConscript index 9ffdfd6d3ac..86c67462cab 100644 --- a/bsp/k230/applications/SConscript +++ b/bsp/k230/applications/SConscript @@ -6,4 +6,9 @@ CPPPATH = [cwd] group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) +list = os.listdir(cwd) +for item in list: + if os.path.isfile(os.path.join(cwd, item, 'SConscript')): + group = group + SConscript(os.path.join(item, 'SConscript')) + Return('group') diff --git a/bsp/k230/applications/display_demo/SConscript b/bsp/k230/applications/display_demo/SConscript new file mode 100644 index 00000000000..f639133b473 --- /dev/null +++ b/bsp/k230/applications/display_demo/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('DisplayDemo', src, depend=['BSP_USING_DISPLAY'], CPPPATH=CPPPATH) + +Return('group') diff --git a/bsp/k230/applications/display_demo/display_demo.c b/bsp/k230/applications/display_demo/display_demo.c new file mode 100644 index 00000000000..9a81a7c90ca --- /dev/null +++ b/bsp/k230/applications/display_demo/display_demo.c @@ -0,0 +1,74 @@ +/* Display demo: draw an RGB565 test pattern through the fb0 device. */ + +#include +#include +#include + +static rt_uint16_t rgb565(rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) +{ + return (rt_uint16_t)(((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3)); +} + +static void display_demo(int argc, char** argv) +{ + rt_device_t fb; + struct rt_device_graphic_info info; + rt_uint16_t *fbmem; + rt_uint16_t colors[] = { + rgb565(255, 0, 0), + rgb565(0, 255, 0), + rgb565(0, 0, 255), + rgb565(255, 255, 255), + rgb565(0, 0, 0), + }; + rt_size_t color_count = sizeof(colors) / sizeof(colors[0]); + + (void)argc; + (void)argv; + + fb = rt_device_find("fb0"); + if (!fb) { + rt_kprintf("display_demo: fb0 device not found\n"); + return; + } + + if (rt_device_open(fb, RT_DEVICE_FLAG_RDWR) != RT_EOK) { + rt_kprintf("display_demo: open fb0 failed\n"); + return; + } + + rt_memset(&info, 0, sizeof(info)); + if (rt_device_control(fb, RTGRAPHIC_CTRL_GET_INFO, &info) != RT_EOK || + info.pixel_format != RTGRAPHIC_PIXEL_FORMAT_RGB565) { + rt_kprintf("display_demo: unsupported framebuffer\n"); + rt_device_close(fb); + return; + } + + fbmem = (rt_uint16_t *)info.framebuffer; + if (!fbmem || info.pitch < info.width * sizeof(rt_uint16_t)) { + rt_kprintf("display_demo: invalid framebuffer\n"); + rt_device_close(fb); + return; + } + + for (rt_uint16_t y = 0; y < info.height; y++) { + rt_uint16_t *line = (rt_uint16_t *)((rt_uint8_t *)fbmem + y * info.pitch); + + for (rt_uint16_t x = 0; x < info.width; x++) { + rt_uint16_t band = (x * color_count) / info.width; + rt_uint16_t shade = (y * 31) / info.height; + + line[x] = colors[band]; + if (band == color_count - 1) + line[x] = (shade << 11) | (shade << 6) | shade; + } + } + + rt_device_control(fb, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL); + rt_device_close(fb); + + rt_kprintf("display_demo: wrote %ux%u RGB565 test pattern\n", info.width, info.height); +} + +MSH_CMD_EXPORT(display_demo, draw RGB565 test pattern to fb0); diff --git a/bsp/k230/applications/mnt.c b/bsp/k230/applications/mnt.c index 3e86c2db035..9c2c97b52a1 100644 --- a/bsp/k230/applications/mnt.c +++ b/bsp/k230/applications/mnt.c @@ -38,7 +38,7 @@ int mnt_init(void) rt_thread_mdelay(100); // Yield to the scheduler } - if (dfs_mount(BSP_SD_MNT_DEVNAME, "/", "elm", 0, 0) != 0) + if (dfs_mount(BSP_SD_MNT_DEVNAME, "/", "ext", 0, 0) != 0) { rt_kprintf("%s mounted on / failed!\n", BSP_SD_MNT_DEVNAME); } diff --git a/bsp/k230/board/Kconfig b/bsp/k230/board/Kconfig index 11d7e6aae0b..22f64302633 100644 --- a/bsp/k230/board/Kconfig +++ b/bsp/k230/board/Kconfig @@ -4,6 +4,23 @@ menu "Drivers Configuration" bool "Enable KPU and AI2D" default n + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default n + + menuconfig BSP_USING_DISPLAY + bool "Enable MIPI DSI Display (ST7701)" + select RT_USING_DEVICE + select RT_USING_DEVICE_OPS + select RT_USING_PIN + select BSP_USING_GPIO + default n + help + Enable MIPI DSI display support for the atk_k230d board. + This registers lcd and fb0 graphic devices for the + 480x640 ST7701 panel over 2-lane MIPI DSI. + menuconfig BSP_USING_SPI bool "Enable SPI" select RT_USING_SPI diff --git a/bsp/k230/board/board.c b/bsp/k230/board/board.c index 8e4eb675d58..26259a305e0 100644 --- a/bsp/k230/board/board.c +++ b/bsp/k230/board/board.c @@ -12,6 +12,10 @@ #include #include +#define DBG_TAG "board" +#define DBG_LVL DBG_INFO +#include + #include "board.h" #include "tick.h" @@ -39,7 +43,6 @@ extern unsigned int __bss_end; #define RT_HW_PAGE_END ((void *)(RAM_END)) #ifdef RT_USING_SMART - rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END}; extern size_t MMUTable[]; @@ -47,9 +50,7 @@ extern size_t MMUTable[]; struct mem_desc platform_mem_desc[] = { {KERNEL_VADDR_START, (rt_size_t)(KERNEL_VADDR_START + CONFIG_MEM_MMZ_BASE + CONFIG_MEM_MMZ_SIZE - 1), (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM}, }; - #define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0])) - #endif /* RT_USING_SMART */ #ifndef ARCH_REMAP_KERNEL @@ -76,34 +77,42 @@ static void __rt_assert_handler(const char *ex_string, const char *func, rt_size asm volatile("ebreak":::"memory"); } -//BSP的C入口 +/* C entry point, this gets called on primary CPU after stack setup. */ void primary_cpu_entry(void) { - //关中断 + LOG_I("primary_cpu_entry"); + rt_hw_interrupt_disable(); + +#ifdef RT_DEBUGING_ASSERT rt_assert_set_hook(__rt_assert_handler); - //启动RT-Thread Smart内核 +#endif + entry(); } #define IOREMAP_SIZE (1ul << 30) -//这个初始化程序由内核主动调用,此时调度器还未启动,因此在此不能使用依赖线程上下文的函数 +/* + * This function is called by the kernel during initialization. At this point, + * the scheduler has not started, so functions that depend on thread context + * cannot be used. + */ void rt_hw_board_init(void) { + LOG_D("board init: heap %p-%p, page %p-%p", + RT_HW_HEAP_BEGIN, RT_HW_HEAP_END, + RT_HW_PAGE_START, RT_HW_PAGE_END); + #ifdef RT_USING_SMART - /* init data structure */ rt_hw_mmu_map_init(&rt_kernel_space, (void *)(IOREMAP_VEND - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, PV_OFFSET); - - /* init page allocator */ rt_page_init(init_page_region); - /* setup region, and enable MMU */ + LOG_D("mmu setup: %d regions", NUM_MEM_DESC); rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, NUM_MEM_DESC); #endif #ifdef RT_USING_HEAP - /* initialize memory system */ rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); #endif /* initalize interrupt */ diff --git a/bsp/k230/board/board.h b/bsp/k230/board/board.h index 5b06bda30fb..47eafaee370 100644 --- a/bsp/k230/board/board.h +++ b/bsp/k230/board/board.h @@ -20,9 +20,6 @@ * * See K230 Technical Reference Manual, chapter 1.5 Address Space mapping */ -#define SRAM_BASE_ADDR (0x80200000UL) -#define SRAM_IO_SIZE (0x00200000UL) - #define KPU_BASE_ADDR (0x80400000UL) #define KPU_IO_SIZE (0x00000800UL) @@ -32,43 +29,15 @@ #define AI2D_BASE_ADDR (0x80400C00UL) #define AI2D_IO_SIZE (0x00000400UL) -#define GSDMA_BASE_ADDR (0x80800000UL) -#define GSDMA_IO_SIZE (0x00004000UL) - #define DMA_BASE_ADDR (0x80804000UL) #define DMA_IO_SIZE (0x00004000UL) -#define DECOMP_BASE_ADDR (0x80808000UL) -#define DECOMP_IO_SIZE (0x00004000UL) - -#define NON_AI2D_BASE_ADDR (0x8080C000UL) -#define NON_AI2D_IO_SIZE (0x00004000UL) - -#define ISP_BASE_ADDR (0x90000000UL) -#define ISP_IO_SIZE (0x00008000UL) - -#define DEWARP_BASE_ADDR (0x90008000UL) -#define DEWARP_IO_SIZE (0x00001000UL) - -#define CSI_BASE_ADDR (0x90009000UL) -#define CSI_IO_SIZE (0x00002000UL) - -#define VPU_BASE_ADDR (0x90400000UL) -#define VPU_IO_SIZE (0x00010000UL) - -/*2.5D*/ -#define TAAH_GPU_BASE_ADDR (0x90800000UL) -#define TAAH_GPU_IO_SIZE (0x00040000UL) - #define VO_BASE_ADDR (0x90840000UL) #define VO_IO_SIZE (0x00010000UL) #define DSI_BASE_ADDR (0x90850000UL) #define DSI_IO_SIZE (0x00001000UL) -#define GPU_ENGINE_BASE_ADDR (0x90A00000UL) -#define GPU_ENGINE_IO_SIZE (0x00000800UL) - #define PMU_BASE_ADDR (0x91000000UL) #define PMU_IO_SIZE (0x00000C00UL) @@ -105,18 +74,9 @@ #define TS_BASE_ADDR (0x91107000UL) #define TS_IO_SIZE (0x00000800UL) -#define HDI_BASE_ADDR (0x91107800UL) -#define HDI_IO_SIZE (0x00000800UL) - #define STC_BASE_ADDR (0x91108000UL) #define STC_IO_SIZE (0x00001000UL) -#define BOOTROM_BASE_ADDR (0x91200000UL) -#define BOOTROM_IO_SIZE (0x00010000UL) - -#define SECURITY_BASE_ADDR (0x91210000UL) -#define SECURITY_IO_SIZE (0x00008000UL) - #define UART0_BASE_ADDR (0x91400000UL) #define UART0_IO_SIZE (0x00001000UL) @@ -159,35 +119,10 @@ #define ADC_BASE_ADDR (0x9140D000UL) #define ADC_IO_SIZE (0x00001000UL) -#define CODEC_BASE_ADDR (0x9140E000UL) -#define CODEC_IO_SIZE (0x00001000UL) - -#define AUDIO_BASE_ADDR (0x9140F000UL) -#define AUDIO_IO_SIZE (0x00001000UL) - -#define USB2_BASE_ADDR (0x91500000UL) -#define USB2_IO_SIZE (0x00080000UL) - -#define SD_HC_BASE_ADDR (0x91580000UL) -#define SD_HC_IO_SIZE (0x00002000UL) - #define SPI_QOPI_BASE_ADDR (0x91582000UL) #define SPI_QOPI_IO_SIZE (0x00002000UL) #define SPI_OPI_BASE_ADDR (0x91584000UL) #define SPI_OPI_IO_SIZE (0x00001000UL) -#define HI_SYS_CONFIG_BASE_ADDR (0x91585000UL) -#define HI_SYS_CONFIG_IO_SIZE (0x00000400UL) - -#define DDRC_CONF_BASE_ADDR (0x98000000UL) -#define DDRC_CONF_IO_SIZE (0x02000000UL) - -#define SPI_XIP_FLASH_BASE_ADDR (0xC0000000UL) -#define SPI_XIP_FLASH_IO_SIZE (0x08000000UL) - -#define IO_SPACE_BASE_ADDR (KPU_BASE_ADDR) - -#define TIMER_CLK_FREQ (27000000) - #endif // BOARD_H__ diff --git a/bsp/k230/board/mem_layout.h b/bsp/k230/board/mem_layout.h index cca1e0f7d99..19ba60ed0b0 100644 --- a/bsp/k230/board/mem_layout.h +++ b/bsp/k230/board/mem_layout.h @@ -26,7 +26,7 @@ * | ...... | maybe zero * +---------+ <- CONFIG_MEM_RTSMART_SIZE * | guard | MEM_GUARD_SIZE - * +---------+ <- End of Kerenl + * +---------+ <- End of Kernel * | | * | | * +---------+ @@ -47,30 +47,76 @@ * the SDK configuration. * * If CONFIG_XXX is defined, it means that the value comes from the SDK - * configuration, otherwise the default configuration of bsp/k230 in RT-Thead - * is used. The default configuration of bsp/k230 is for the 01Studio CanMV - * development board that supports 512MB of memory. + * configuration, otherwise the default configuration defined in this file + * is used. + */ + +#if defined(SOC_K230D) +/* + * ATK-DNK230D: 128MB DDR + * + * +---------+ <- 0x8000000 (128MB) + * | MMZ | CONFIG_MEM_MMZ_SIZE = 0x4600000 (70MB) + * +---------+ <- CONFIG_MEM_MMZ_BASE = 0x3A00000 (58MB) + * | heap | CONFIG_MEM_RTSMART_HEAP_SIZE = 0x800000 (8MB) + * +---------+ + * | kernel | CONFIG_MEM_RTSMART_SIZE - MEM_OPENSBI_SIZE - MEM_GUARD_SIZE - heap + * +---------+ <- CONFIG_MEM_RTSMART_BASE + MEM_OPENSBI_SIZE (128KB) + * | opensbi | MEM_OPENSBI_SIZE = 0x20000 (128KB) + * +---------+ <- 0x0 */ #ifndef CONFIG_MEM_TOTAL_SIZE -#define CONFIG_MEM_TOTAL_SIZE 0x20000000 // 512M +#define CONFIG_MEM_TOTAL_SIZE 0x8000000 // 128M #endif #ifndef CONFIG_MEM_RTSMART_SIZE -#define CONFIG_MEM_RTSMART_SIZE 0x10000000 // 256M +#define CONFIG_MEM_RTSMART_SIZE 0x3A00000 // 58M #endif #ifndef CONFIG_MEM_RTSMART_HEAP_SIZE -#define CONFIG_MEM_RTSMART_HEAP_SIZE 0x2000000 // 32M +#define CONFIG_MEM_RTSMART_HEAP_SIZE 0x800000 // 8M #endif #ifndef CONFIG_MEM_MMZ_BASE -#define CONFIG_MEM_MMZ_BASE 0x10000000 // 512M +#define CONFIG_MEM_MMZ_BASE 0x3A00000 // 58M #endif #ifndef CONFIG_MEM_MMZ_SIZE -#define CONFIG_MEM_MMZ_SIZE 0x10000000 // 256M +#define CONFIG_MEM_MMZ_SIZE 0x4600000 // 70M +#endif + +#elif defined(SOC_K230) +/* + * K230: default memory configuration + * + * The K230 chip supports different DDR sizes (256MB, 512MB, 1GB, 2GB). + * Override the CONFIG_MEM_XXX values in rtconfig.h or SDK configuration + * to match your board's actual DDR size. + */ +#ifndef CONFIG_MEM_TOTAL_SIZE +#define CONFIG_MEM_TOTAL_SIZE 0x8000000 // 128M +#endif + +#ifndef CONFIG_MEM_RTSMART_SIZE +#define CONFIG_MEM_RTSMART_SIZE 0x3A00000 // 58M +#endif + +#ifndef CONFIG_MEM_RTSMART_HEAP_SIZE +#define CONFIG_MEM_RTSMART_HEAP_SIZE 0x800000 // 8M +#endif + +#ifndef CONFIG_MEM_MMZ_BASE +#define CONFIG_MEM_MMZ_BASE 0x3A00000 // 58M +#endif + +#ifndef CONFIG_MEM_MMZ_SIZE +#define CONFIG_MEM_MMZ_SIZE 0x4600000 // 70M +#endif + +#else +#error "Either SOC_K230 or SOC_K230D must be defined" #endif #define MEM_KERNEL_SIZE (CONFIG_MEM_RTSMART_SIZE - MEM_OPENSBI_SIZE - MEM_GUARD_SIZE) -#endif // MEMORY_LAYOUT_H__ \ No newline at end of file +#endif // MEMORY_LAYOUT_H__ diff --git a/bsp/k230/drivers/display/README.md b/bsp/k230/drivers/display/README.md new file mode 100644 index 00000000000..1e9028bcd09 --- /dev/null +++ b/bsp/k230/drivers/display/README.md @@ -0,0 +1,103 @@ +# K230 Display Driver + +This driver enables the ATK K230D ST7701 MIPI-DSI panel without linking the +hard-float `libvo.a`. The implementation is intentionally small: + +- `drv_display.c` registers RT-Thread graphic devices `lcd` and `fb0`. +- `panel_common.c`, `bus_dsi.c`, and `panels/` describe the panel, GPIO reset, + backlight, MIPI-DSI bus, and timing. +- `vo/` contains the lightweight VO/DSI register code that replaces the old + `libvo.a` dependency. + +## Configuration + +Enable: + +```text +BSP_USING_DISPLAY=y +``` + +The Kconfig option selects the RT-Thread device, device-ops, and pin APIs used +by this driver. The build is handled by `drivers/display/SConscript`; it builds +the local VO/DSI source files and does not link `libvo.a`. + +## Device Interface + +The driver registers: + +- `lcd`: compatible RT-Thread graphic device name. +- `fb0`: framebuffer-style graphic device intended for device-file access. + +Both devices share one RGB565 framebuffer. `RTGRAPHIC_CTRL_GET_INFO` returns +`struct rt_device_graphic_info`: + +- `pixel_format`: `RTGRAPHIC_PIXEL_FORMAT_RGB565` +- `bits_per_pixel`: `16` +- `pitch`: bytes per line +- `width`, `height`: panel active size +- `framebuffer`, `smem_len`: kernel framebuffer address and size + +Supported controls: + +- `RTGRAPHIC_CTRL_GET_INFO` +- `RTGRAPHIC_CTRL_RECT_UPDATE` +- `RTGRAPHIC_CTRL_POWERON` +- `RTGRAPHIC_CTRL_POWEROFF` +- `RTGRAPHIC_CTRL_SET_BRIGHTNESS` +- `RTGRAPHIC_CTRL_GET_BRIGHTNESS` +- `RTGRAPHIC_CTRL_WAIT_VSYNC` + +`read()` and `write()` operate on byte offsets in the RGB565 framebuffer. Writes +flush the CPU data cache for the updated range. + +## Kernel Shell Example + +```text +list_device +list_display +display_demo +``` + +`display_demo` opens `fb0`, queries `RTGRAPHIC_CTRL_GET_INFO`, writes an RGB565 +test pattern, then calls `RTGRAPHIC_CTRL_RECT_UPDATE`. + +## User-Space Example + +```c +#include +#include +#include + +int main(void) +{ + int fd = open("/dev/fb0", O_RDWR); + uint16_t line[480]; + + if (fd < 0) + return -1; + + for (int x = 0; x < 480; x++) + line[x] = 0xf800; /* red in RGB565 */ + + for (int y = 0; y < 640; y++) + write(fd, line, sizeof(line)); + + close(fd); + return 0; +} +``` + +Use RGB565 pixels. For partial updates, seek to `y * pitch + x * 2` before +writing if the user-space C library exposes `lseek()` for device files. + +## Notes + +This driver does not implement hardware acceleration. It only provides a CPU +framebuffer and the minimum panel/DSI/VO setup needed for display bring-up. + +The current local VO source covers reset, timing, mixer, background, DSI, and +register remap. The original hard-float `libvo.a` also contains lower-level +video/OSD layer address, stride, and format functions. Those functions must be +implemented from verified register definitions before claiming full framebuffer +scanout on hardware. Until then, `fb0` device-file drawing is present and cache +coherent, while actual panel scanout requires board validation. diff --git a/bsp/k230/drivers/display/SConscript b/bsp/k230/drivers/display/SConscript new file mode 100644 index 00000000000..d0fb772fab1 --- /dev/null +++ b/bsp/k230/drivers/display/SConscript @@ -0,0 +1,26 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('lib/*.c') +src += [ + 'vo/vo_remap.c', + 'vo/kd_vo_reg.c', + 'vo/kd_dsi_reg.c', +] +CPPPATH = [ + cwd, + cwd + '/include', + cwd + '/vo', + cwd + '/../interdrv/sysctl/sysctl_power', + cwd + '/../interdrv/sysctl/sysctl_reset', +] + +group = DefineGroup('Display', src, depend=['BSP_USING_DISPLAY'], + CPPPATH=CPPPATH) + +list = os.listdir(cwd) +for item in list: + if os.path.isfile(os.path.join(cwd, item, 'SConscript')): + group = group + SConscript(os.path.join(item, 'SConscript')) + +Return('group') diff --git a/bsp/k230/drivers/display/bus_dsi.c b/bsp/k230/drivers/display/bus_dsi.c new file mode 100644 index 00000000000..e4599de7475 --- /dev/null +++ b/bsp/k230/drivers/display/bus_dsi.c @@ -0,0 +1,345 @@ +/* Adapted from atk_k230d connector_bus_dsi.c for RT-Thread BSP */ + +#include +#include + +#include "connector_panel.h" +#include "connector_bus_dsi.h" + +#define DSI_PHY_REF_CLK 24000000 +#define DSI_DPI_BITS_PER_PIXEL 16U + +typedef struct { + k_u64 min_freq; + k_u64 max_freq; + k_u8 hsfreqrange; +} dsi_phy_hsfreq_range_t; + +static const dsi_phy_hsfreq_range_t hsfreq_ranges[] = { + { 2363125000ULL, 2500000000ULL, 0x49 }, { 2315625000ULL, 2500000000ULL, 0x48 }, { 2268125000ULL, 2500000000ULL, 0x47 }, + { 2220625000ULL, 2480625000ULL, 0x46 }, { 2173125000ULL, 2428125000ULL, 0x45 }, { 2125625000ULL, 2375625000ULL, 0x44 }, + { 2078125000ULL, 2323125000ULL, 0x43 }, { 2030625000ULL, 2270625000ULL, 0x42 }, { 1983125000ULL, 2218125000ULL, 0x41 }, + { 1935625000ULL, 2165625000ULL, 0x40 }, { 1888125000ULL, 2113125000ULL, 0x0F }, { 1840625000ULL, 2060625000ULL, 0x3F }, + { 1793125000ULL, 2008125000ULL, 0x2F }, { 1745625000ULL, 1955625000ULL, 0x1E }, { 1698125000ULL, 1903125000ULL, 0x0E }, + { 1650625000ULL, 1850625000ULL, 0x3E }, { 1603125000ULL, 1798125000ULL, 0x2E }, { 1555625000ULL, 1745625000ULL, 0x1D }, + { 1508125000ULL, 1693125000ULL, 0x0D }, { 1460625000ULL, 1640625000ULL, 0x3D }, { 1413125000ULL, 1588125000ULL, 0x2C }, + { 1365625000ULL, 1535625000ULL, 0x1C }, { 1318125000ULL, 1483125000ULL, 0x0C }, { 1270625000ULL, 1430625000ULL, 0x3C }, + { 1223125000ULL, 1378125000ULL, 0x2B }, { 1175625000ULL, 1325625000ULL, 0x1B }, { 1128125000ULL, 1273125000ULL, 0x0B }, + { 1080625000ULL, 1220625000ULL, 0x3B }, { 1033125000ULL, 1168125000ULL, 0x2A }, { 985625000ULL, 1115625000ULL, 0x1A }, + { 938125000ULL, 1063125000ULL, 0x0A }, { 890625000ULL, 1010625000ULL, 0x3A }, { 843125000ULL, 958125000ULL, 0x29 }, + { 795625000ULL, 905625000ULL, 0x19 }, { 748125000ULL, 853125000ULL, 0x09 }, { 700625000ULL, 800625000ULL, 0x39 }, + { 653125000ULL, 748125000ULL, 0x28 }, { 605625000ULL, 695625000ULL, 0x18 }, { 558125000ULL, 643125000ULL, 0x07 }, + { 510625000ULL, 590625000ULL, 0x37 }, { 463125000ULL, 538125000ULL, 0x26 }, { 415625000ULL, 485625000ULL, 0x16 }, + { 368125000ULL, 433125000ULL, 0x05 }, { 320625000ULL, 380625000ULL, 0x35 }, { 296875000ULL, 354375000ULL, 0x25 }, + { 273125000ULL, 328125000ULL, 0x14 }, { 249375000ULL, 301875000ULL, 0x04 }, { 225625000ULL, 275625000ULL, 0x33 }, + { 211375000ULL, 259875000ULL, 0x23 }, { 197125000ULL, 244125000ULL, 0x13 }, { 182875000ULL, 228375000ULL, 0x03 }, + { 168625000ULL, 212625000ULL, 0x32 }, { 159125000ULL, 202125000ULL, 0x22 }, { 149625000ULL, 191625000ULL, 0x12 }, + { 140125000ULL, 181125000ULL, 0x02 }, { 130625000ULL, 170625000ULL, 0x31 }, { 121125000ULL, 160125000ULL, 0x21 }, + { 111625000ULL, 149625000ULL, 0x11 }, { 102125000ULL, 139125000ULL, 0x01 }, { 92625000ULL, 128625000ULL, 0x30 }, + { 83125000ULL, 118125000ULL, 0x20 }, { 80000000ULL, 107625000ULL, 0x10 }, { 80000000ULL, 97125000ULL, 0x00 }, +}; + +static k_u32 dsi_lane_count(k_vo_dsi_lane_num lanes) +{ + switch (lanes) { + case K_DSI_1LAN: + return 1; + case K_DSI_2LAN: + return 2; + case K_DSI_4LAN: + return 4; + default: + return 0; + } +} + +static inline k_u32 dsi_bus_calc_lane_clk(const k_vo_timing* res, k_vo_dsi_lane_num lanes) +{ + k_u32 lane_count = dsi_lane_count(lanes); + + if (!res || res->pclk_khz == 0 || lane_count == 0) + return 0; + + return ((res->pclk_khz * DSI_DPI_BITS_PER_PIXEL * 1000) / + (lane_count * 2)); +} + +static k_u32 dsi_phy_calc_hsfreqrange(k_u64 bitrate_hz) +{ + int num_ranges = sizeof(hsfreq_ranges) / sizeof(hsfreq_ranges[0]); + + for (int i = 0; i < num_ranges; i++) { + if (bitrate_hz >= hsfreq_ranges[i].min_freq && bitrate_hz <= hsfreq_ranges[i].max_freq) { + return hsfreq_ranges[i].hsfreqrange; + } + } + + rt_kprintf("dsi_phy: unsupported bitrate %llu Hz\n", bitrate_hz); + return 0; +} + +static k_u32 dsi_phy_calc_vco(k_u32 fout_hz) +{ + if (fout_hz >= 1100000000 && fout_hz <= 1250000000) return 0x01; + if (fout_hz >= 630000000 && fout_hz <= 1149000000) return 0x03; + if (fout_hz >= 420000000 && fout_hz <= 660000000) return 0x07; + if (fout_hz >= 320000000 && fout_hz <= 440000000) return 0x0F; + if (fout_hz >= 210000000 && fout_hz <= 330000000) return 0x17; + if (fout_hz >= 160000000 && fout_hz <= 220000000) return 0x1F; + if (fout_hz >= 105000000 && fout_hz <= 165000000) return 0x27; + if (fout_hz >= 80000000 && fout_hz <= 110000000) return 0x2F; + if (fout_hz >= 52500000 && fout_hz <= 82500000) return 0x37; + if (fout_hz >= 40000000 && fout_hz <= 55000000) return 0x3F; + + rt_kprintf("dsi_phy: unsupported VCO frequency %u Hz\n", fout_hz); + return 0x17; +} + +static int dsi_phy_calc_m_and_n_impl(k_u32 fout, k_u32 mut, k_u32 clkin, k_u32* om, k_u32* on) +{ + for (int n = 1; n <= 16; n++) { + uint64_t numerator = (uint64_t)fout * mut * (n + 1); + if (numerator % clkin == 0) { + uint32_t mp2 = numerator / clkin; + if (mp2 >= 42 && mp2 <= 627) { + *om = mp2 - 2; + *on = n; + return 0; + } + } + } + + rt_kprintf("dsi_phy: can't generate phy attr with configuration\n"); + rt_kprintf("dsi_phy: try to increase or decrease pclk\n"); + return -1; +} + +static int dsi_phy_calc_m_and_n(k_u32 fout, k_u32* m, k_u32* n) +{ + k_u32 mut = 1; + + if (fout >= 320000000 && fout <= 1250000000) + mut = 1; + else if (fout >= 160000000 && fout <= 320000000) + mut = 2; + else if (fout >= 80000000 && fout <= 160000000) + mut = 4; + else if (fout >= 40000000 && fout <= 80000000) + mut = 8; + else + rt_kprintf("dsi_phy: unsupported MIPI Phy Clock: %u\n", fout); + + return dsi_phy_calc_m_and_n_impl(fout, mut, DSI_PHY_REF_CLK, m, n); +} + +static int dsi_bus_check_lane_clk(k_u32 lane_clk_hz) +{ + k_u32 mut = 1; + + if (lane_clk_hz == 0) + return -1; + + if (lane_clk_hz >= 320000000 && lane_clk_hz <= 1250000000) + mut = 1; + else if (lane_clk_hz >= 160000000 && lane_clk_hz <= 320000000) + mut = 2; + else if (lane_clk_hz >= 80000000 && lane_clk_hz <= 160000000) + mut = 4; + else if (lane_clk_hz >= 40000000 && lane_clk_hz <= 80000000) + mut = 8; + else + return -1; + + for (int n = 1; n <= 16; n++) { + uint64_t numerator = (uint64_t)lane_clk_hz * mut * (n + 1); + if (numerator % DSI_PHY_REF_CLK == 0) { + uint32_t mp2 = numerator / DSI_PHY_REF_CLK; + if (mp2 >= 42 && mp2 <= 627) + return 0; + } + } + + return -1; +} + +k_u32 dsi_correct_pclk(k_u32 pclk_hz, k_vo_dsi_lane_num lanes) +{ + k_u32 ratio, candidate_pclk, lane_clk, lane_count; + int delta; + + lane_count = dsi_lane_count(lanes); + if (pclk_hz == 0 || lane_count == 0) + return 0; + + ratio = (VO_PIXEL_CLOCK_HZ + pclk_hz / 2) / pclk_hz; + if (ratio == 0) + ratio = 1; + + for (delta = 0; delta <= 10; delta++) { + if (ratio + delta > 0) { + candidate_pclk = VO_PIXEL_CLOCK_HZ / (ratio + delta); + lane_clk = (candidate_pclk / 1000 * DSI_DPI_BITS_PER_PIXEL * 1000) / + (lane_count * 2); + if (dsi_bus_check_lane_clk(lane_clk) == 0) + return candidate_pclk; + } + if (delta > 0 && ratio > (k_u32)delta) { + candidate_pclk = VO_PIXEL_CLOCK_HZ / (ratio - delta); + lane_clk = (candidate_pclk / 1000 * DSI_DPI_BITS_PER_PIXEL * 1000) / + (lane_count * 2); + if (dsi_bus_check_lane_clk(lane_clk) == 0) + return candidate_pclk; + } + } + + return 0; +} + +static int dsi_bus_calculate_phy_attr(k_u32 lane_clk_hz, k_u32* n, k_u32* m, k_u32* voc, k_u32* hs_freq) +{ + k_u32 m_val, n_val; + + if (!n || !m || !voc || !hs_freq || lane_clk_hz == 0) + return -1; + + if (dsi_phy_calc_m_and_n(lane_clk_hz, &m_val, &n_val) != 0) + return -1; + + *m = m_val; + *n = n_val; + *voc = dsi_phy_calc_vco(lane_clk_hz); + *hs_freq = 0x80 | dsi_phy_calc_hsfreqrange(lane_clk_hz * 2); + + return 0; +} + +static int dsi_bus_init(const struct panel_desc* desc) +{ + k_u32 lane_clk; + k_u32 m, n, voc, hs_freq; + k_vo_dsi_config cfg; + + if (!desc) + return -1; + + lane_clk = dsi_bus_calc_lane_clk(&desc->timing, desc->bus.dsi.lanes); + if (lane_clk == 0) { + rt_kprintf("dsi_bus_init: failed to calculate lane_clk\n"); + return -2; + } + + if (dsi_bus_calculate_phy_attr(lane_clk, &n, &m, &voc, &hs_freq) != 0) { + rt_kprintf("dsi_bus_init: failed to calculate phy attr\n"); + return -3; + } + + cfg.phy.datarate = lane_clk * 2; + cfg.phy.m = m; + cfg.phy.n = n; + cfg.phy.voc = voc; + cfg.phy.hs_freq = hs_freq; + + cfg.timing = &desc->timing; + cfg.lanes = desc->bus.dsi.lanes; + cfg.cmd_mode = desc->bus.dsi.cmd_mode; + cfg.video_mode = desc->bus.dsi.video_mode; + cfg.vc_id = desc->bus.dsi.vc_id; + cfg.lp_speed_mhz = desc->bus.dsi.lp_cmd_speed_mhz; + + dwc_dsi_init(&cfg); + + return 0; +} + +static int dsi_bus_enable(const struct panel_desc* desc) +{ + if (!desc) + return -1; + + dwc_dsi_enable(); + return 0; +} + +k_s32 dsi_send_cmd_sequence(const struct panel_desc* desc, const k_u8* cmd_seq, size_t cmd_size, k_bool dump) +{ + uint32_t cmd_remain; + const uint8_t * pcmd, *pcmd_end; + k_connector_cmd_slice* cmd; + + if (!cmd_seq || !desc) { + rt_kprintf("no init sequence set.\n"); + return -1; + } + + pcmd = cmd_seq; + pcmd_end = pcmd + cmd_size; + + do { + cmd = (k_connector_cmd_slice*)pcmd; + cmd_remain = pcmd_end - pcmd; + + if (cmd->cmd_size > (cmd_remain - sizeof(k_connector_cmd_slice))) { + rt_kprintf("error cmd sequence. %d > %d\n", cmd->cmd_size, + cmd_remain - (int)sizeof(k_connector_cmd_slice)); + break; + } + + if (cmd->cmd_size) { + if ((DSI_DCS_SHORT_WRITE == cmd->cmd_type) || (DSI_DCS_SHORT_WRITE_PARAM == cmd->cmd_type) + || (DSI_DCS_LONG_WRITE == cmd->cmd_type)) { + + if (dwc_dsi_dcs_write(cmd->cmd_data, cmd->cmd_size, desc->bus.dsi.vc_id) != 0) { + rt_kprintf("dsi send cmd failed, but we treat it as non-fatal\n"); + return 0; + } + } else if ((DSI_GENERIC_SHORT_WRITE_0_PARAM == cmd->cmd_type) || (DSI_GENERIC_SHORT_WRITE_1_PARAM == cmd->cmd_type) + || (DSI_GENERIC_SHORT_WRITE_2_PARAM == cmd->cmd_type) || (DSI_GENERIC_LONG_WRITE == cmd->cmd_type)) { + + if (dwc_dsi_generic_write(cmd->cmd_data, cmd->cmd_size, desc->bus.dsi.vc_id) != 0) { + rt_kprintf("dsi send cmd failed, but we treat it as non-fatal\n"); + return 0; + } + } else { + rt_kprintf("unsupport cmd type 0x%02X\n", cmd->cmd_type); + return -2; + } + + if (dump) { + rt_kprintf("cmd[0x%02x] -> delay %u, data:", cmd->cmd_type, cmd->cmd_delay); + for (int i = 0; i < cmd->cmd_size; i++) + rt_kprintf("%02X ", cmd->cmd_data[i]); + rt_kprintf("\n"); + } + + if (cmd->cmd_delay) + rt_hw_us_delay((uint64_t)(cmd->cmd_delay) * 1000); + } + + pcmd += sizeof(k_connector_cmd_slice) + cmd->cmd_size; + } while (pcmd < pcmd_end); + + return 0; +} + +k_u32 dsi_read_chip_id(const struct panel_desc* desc) +{ + if (!desc) + return 0xDEADBEEF; + + k_u8 vc = desc->bus.dsi.vc_id; + k_u8 id[3] = { 0x03, 0x00, 0x00 }; + + if (dwc_dsi_send_packet(0x37, vc, id, 1, 1) != 0) + return 0xDEADBEEF; + + if (dwc_dsi_dcs_read(0x04, &id[0], 3, vc) != 3) + return 0xDEADBEEF; + + return (k_u32)((id[0] << 16) | (id[1] << 8) | id[2]); +} + +const struct panel_bus_ops dsi_bus_ops = { + .init = dsi_bus_init, + .enable = dsi_bus_enable, + .disable = NULL, +}; diff --git a/bsp/k230/drivers/display/connector_bus.h b/bsp/k230/drivers/display/connector_bus.h new file mode 100644 index 00000000000..0390e2cb813 --- /dev/null +++ b/bsp/k230/drivers/display/connector_bus.h @@ -0,0 +1,36 @@ +#ifndef _CONNECTOR_BUS_H_ +#define _CONNECTOR_BUS_H_ + +#include "connector_bus_dsi.h" +#include "k_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct panel_desc; + +enum panel_bus_type { + PANEL_BUS_DSI, + PANEL_BUS_SPI, + PANEL_BUS_I8080_SPI, + PANEL_BUS_QSPI, + PANEL_BUS_NONE, +}; + +struct panel_bus_ops { + int (*init)(const struct panel_desc* desc); + int (*enable)(const struct panel_desc* desc); + int (*disable)(const struct panel_desc* desc); + int (*send_cmd)(const struct panel_desc* desc, k_u8 cmd, + const k_u8* data, k_u32 len); + int (*send_frame)(const struct panel_desc* desc, void* data, k_u32 size); +}; + +extern const struct panel_bus_ops dsi_bus_ops; + +#ifdef __cplusplus +} +#endif + +#endif /* _CONNECTOR_BUS_H_ */ diff --git a/bsp/k230/drivers/display/connector_bus_dsi.h b/bsp/k230/drivers/display/connector_bus_dsi.h new file mode 100644 index 00000000000..d5a5498d57d --- /dev/null +++ b/bsp/k230/drivers/display/connector_bus_dsi.h @@ -0,0 +1,48 @@ +#ifndef _CONNECTOR_BUS_DSI_H_ +#define _CONNECTOR_BUS_DSI_H_ + +#include +#include + +#include "k_vo_comm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct panel_desc; + +/* MIPI DSI DCS Command Types */ +#define DSI_DCS_SHORT_WRITE 0x05 +#define DSI_DCS_SHORT_WRITE_PARAM 0x15 +#define DSI_DCS_LONG_WRITE 0x39 + +/* MIPI DSI Generic Command Types */ +#define DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03 +#define DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13 +#define DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23 +#define DSI_GENERIC_LONG_WRITE 0x29 + +k_s32 dsi_send_cmd_sequence(const struct panel_desc* desc, const k_u8* cmd_seq, + size_t cmd_size, k_bool dump); +k_u32 dsi_read_chip_id(const struct panel_desc* desc); +k_u32 dsi_correct_pclk(k_u32 pclk_hz, k_vo_dsi_lane_num lanes); + +/* DWC DSI controller HAL implemented by display/vo. */ +void dwc_dsi_init(k_vo_dsi_config* cfg); +int dwc_dsi_enable(void); +int dwc_dsi_disable(void); +int dwc_dsi_send_packet(uint8_t type, uint8_t vc, const void* data, + uint32_t len, uint8_t req_ack); +int dwc_dsi_dcs_write(const void* data, uint32_t len, uint8_t vc); +int dwc_dsi_dcs_read(uint8_t addr, void* buf, uint32_t len, uint8_t vc); +int dwc_dsi_generic_write(const void* data, uint32_t len, uint8_t vc); +int dwc_dsi_generic_read(const void* cmd, uint32_t cmd_len, + void* buf, uint32_t len, uint8_t vc); +void dwc_dsi_dump_reg_val(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONNECTOR_BUS_DSI_H_ */ diff --git a/bsp/k230/drivers/display/connector_panel.h b/bsp/k230/drivers/display/connector_panel.h new file mode 100644 index 00000000000..3763bb75479 --- /dev/null +++ b/bsp/k230/drivers/display/connector_panel.h @@ -0,0 +1,78 @@ +#ifndef _CONNECTOR_PANEL_H_ +#define _CONNECTOR_PANEL_H_ + +#include "k_connector_comm.h" +#include "k_vo_comm.h" + +#include "connector_bus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define VO_PIXEL_CLOCK_HZ 594000000UL +#define PANEL_BG_COLOR_BLACK 0x00000000 +#define PANEL_BG_COLOR_WHITE 0x00FFFFFF + +struct panel_desc; + +struct panel_drv { + const char* connector_name; + const struct panel_desc** panel_variants; + const struct panel_desc* active_panel; +}; + +struct panel_gpio_config { + k_s32 reset_pin; + k_u32 reset_delay_ms; + k_u32 backlight_delay_ms; + k_s32 backlight_pin; + k_bool reset_active_low; + k_bool backlight_active_low; +}; + +struct panel_dsi_config { + k_vo_dsi_lane_num lanes; + k_u32 cmd_mode; + k_vo_dsi_video_mode video_mode; + k_u8 vc_id; + k_u8 lp_cmd_speed_mhz; +}; + +struct panel_ops { + int (*reset)(const struct panel_desc* desc); + int (*init)(const struct panel_desc* desc); + int (*power_off)(const struct panel_desc* desc); + k_u32 (*read_chip_id)(const struct panel_desc* desc); +}; + +struct panel_desc { + const char* name; + k_u32 connector_type; + enum panel_bus_type bus_type; + + k_vo_timing timing; + k_u32 bg_color; + + struct panel_gpio_config gpio; + + union { + struct panel_dsi_config dsi; + } bus; + + const struct panel_bus_ops* bus_ops; + const struct panel_ops* ops; +}; + +k_u32 panel_correct_pclk(k_u32 pclk); +int panel_calculate_fps(const k_vo_timing* timing); +int panel_generic_reset(const struct panel_desc* desc); +int panel_generic_backlight(const struct panel_desc* desc, k_u32 mode, k_u32 duty); +k_s32 panel_generic_power_on(struct panel_desc* desc); +k_s32 panel_generic_power_off(const struct panel_desc* desc); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONNECTOR_PANEL_H_ */ diff --git a/bsp/k230/drivers/display/drv_display.c b/bsp/k230/drivers/display/drv_display.c new file mode 100644 index 00000000000..c5fb6238844 --- /dev/null +++ b/bsp/k230/drivers/display/drv_display.c @@ -0,0 +1,1510 @@ +/* RT-Thread display driver for K230D */ + +#include +#include +#include +#include +#include + +#ifdef RT_USING_SMART +#include +#include +#ifdef RT_USING_DFS +#include +#endif +#endif + +#include "connector_panel.h" +#include "drv_display.h" +#include "vo_display_remap.h" +#include "kd_vo_reg.h" +#include "kd_dsi_reg.h" +#include "sysctl_pwr.h" +#include "sysctl_rst.h" + +extern struct panel_drv mipi_st7701_drv; +extern void dwc_dsi_debug_dump(void); +extern volatile sysctl_pwr_s *sysctl_pwr; +extern volatile sysctl_rst_t *sysctl_rst; + +static struct { + struct rt_device lcd; + struct rt_device fb; + struct rt_device_graphic_info info; + struct panel_desc* panel; + struct rt_mutex lock; + rt_uint8_t* framebuffer; + void* framebuffer_pa; + rt_size_t framebuffer_size; + rt_uint8_t brightness; + rt_bool_t initialized; + rt_err_t last_error; + const char* last_stage; +} g_display; + +static struct panel_drv* display_drv_list[] = { + &mipi_st7701_drv, + RT_NULL, +}; + +static void display_flush_range(rt_uint8_t *addr, rt_size_t size); + +static rt_bool_t display_power_domains_ready(void) +{ + if (!sysctl_pwr) + return RT_FALSE; + + return ((sysctl_pwr->disp_lpi_state & 0x2U) != 0) && + ((sysctl_pwr->dpu_pwr_lpi_state & 0x2U) != 0); +} + +static rt_bool_t display_wait_power_domains(void) +{ + for (int i = 0; i < 20; i++) { + if (display_power_domains_ready()) + return RT_TRUE; + rt_thread_mdelay(1); + } + + return RT_FALSE; +} + +static rt_err_t display_hw_enable(void) +{ + bool disp_ok; + bool dpu_ok; + + disp_ok = sysctl_pwr_up(SYSCTL_PD_DISP); + dpu_ok = sysctl_pwr_up(SYSCTL_PD_DPU); + if (!display_wait_power_domains()) { + rt_kprintf("display: power domain enable failed, ret disp=%d dpu=%d state disp=0x%08x dpu=0x%08x\n", + disp_ok, dpu_ok, + sysctl_pwr ? sysctl_pwr->disp_lpi_state : 0, + sysctl_pwr ? sysctl_pwr->dpu_pwr_lpi_state : 0); + return -RT_ERROR; + } + if (!disp_ok || !dpu_ok) + rt_kprintf("display: power domain enable warning, ret disp=%d dpu=%d state disp=0x%08x dpu=0x%08x\n", + disp_ok, dpu_ok, sysctl_pwr->disp_lpi_state, + sysctl_pwr->dpu_pwr_lpi_state); + + disp_ok = sysctl_pwr_set_lpi(SYSCTL_PD_DISP, true); + dpu_ok = sysctl_pwr_set_lpi(SYSCTL_PD_DPU, true); + if (!disp_ok || !dpu_ok) + rt_kprintf("display: lpi exit warning, disp=%d dpu=%d\n", disp_ok, dpu_ok); + + (void)sysctl_set_reset_time(SYSCTL_RESET_TIME_DISP_SYS, 0xf, 0xf, 0xf); + (void)sysctl_set_reset_time(SYSCTL_RESET_TIME_DPU, 0, 0xf, 0xf); + + disp_ok = sysctl_reset(SYSCTL_RESET_DISP); + dpu_ok = sysctl_reset(SYSCTL_RESET_DPU); + if (!disp_ok || !dpu_ok) + rt_kprintf("display: reset warning, ret disp=%d dpu=%d ctl disp=0x%08x dpu=0x%08x\n", + disp_ok, dpu_ok, + sysctl_rst ? sysctl_rst->disp_rst_ctl : 0, + sysctl_rst ? sysctl_rst->dpu_rst_ctl : 0); + rt_thread_mdelay(1); + + return RT_EOK; +} + +static rt_err_t display_fail(const char *stage, rt_err_t error) +{ + g_display.last_stage = stage; + g_display.last_error = error; + return error; +} + +static void display_fb_release(void) +{ + if (g_display.framebuffer) + rt_free_align(g_display.framebuffer); + + g_display.framebuffer = RT_NULL; + g_display.framebuffer_pa = RT_NULL; + g_display.framebuffer_size = 0; + rt_memset(&g_display.info, 0, sizeof(g_display.info)); +} + +static const struct panel_desc* find_panel_by_name(const char* name) +{ + for (int i = 0; display_drv_list[i] != RT_NULL; i++) { + struct panel_drv* drv = display_drv_list[i]; + + if (drv->panel_variants) { + for (int j = 0; drv->panel_variants[j] != RT_NULL; j++) { + if (rt_strcmp(drv->panel_variants[j]->name, name) == 0) + return drv->panel_variants[j]; + } + } + if (drv->active_panel && rt_strcmp(drv->active_panel->name, name) == 0) + return drv->active_panel; + } + return RT_NULL; +} + +static void display_flush_range(rt_uint8_t *addr, rt_size_t size) +{ + if (addr && size) + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, addr, size); +} + +static void display_commit_framebuffer(void) +{ + if (!g_display.framebuffer || !g_display.framebuffer_size) + return; + + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, g_display.framebuffer, + g_display.framebuffer_size); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, g_display.framebuffer, + g_display.framebuffer_size); + if (g_display.initialized) + kd_vo_commit(); +} + +static void display_bind_default_osd(void) +{ + if (!g_display.initialized || !g_display.framebuffer_pa) + return; + + kd_vo_set_osd_rgb565_framebuffer(2, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + g_display.info.width, + g_display.info.height, + g_display.info.pitch); + kd_vo_select_osd(2); +} + +static rt_uint32_t display_fb_crc32(void) +{ + const rt_uint8_t *data = g_display.framebuffer; + rt_uint32_t crc = 0xffffffffU; + + if (!data || !g_display.framebuffer_size) + return 0; + + for (rt_size_t i = 0; i < g_display.framebuffer_size; i++) { + crc ^= data[i]; + for (int bit = 0; bit < 8; bit++) { + if (crc & 1U) + crc = (crc >> 1) ^ 0xedb88320U; + else + crc >>= 1; + } + } + + return ~crc; +} + +static rt_uint16_t display_fb_pixel(rt_uint16_t x, rt_uint16_t y) +{ + rt_uint16_t *line; + + if (!g_display.framebuffer || x >= g_display.info.width || y >= g_display.info.height) + return 0; + + line = (rt_uint16_t *)(g_display.framebuffer + y * g_display.info.pitch); + return line[x]; +} + +static void display_fb_probe_print(const char *tag) +{ + rt_uint16_t x0; + rt_uint16_t x1; + rt_uint16_t x2; + rt_uint16_t y0; + rt_uint16_t y1; + rt_uint16_t y2; + + if (!g_display.framebuffer) { + rt_kprintf("FB_PROBE %s not-ready\n", tag); + return; + } + + x0 = 0; + y0 = 0; + x1 = g_display.info.width / 2U; + y1 = g_display.info.height / 2U; + x2 = g_display.info.width ? (g_display.info.width - 1U) : 0; + y2 = g_display.info.height ? (g_display.info.height - 1U) : 0; + + rt_kprintf("FB_PROBE %s va=%p pa=%p size=0x%lx pitch=%u align_pa=0x%lx crc=0x%08x\n", + tag, g_display.framebuffer, g_display.framebuffer_pa, + (unsigned long)g_display.framebuffer_size, g_display.info.pitch, + ((unsigned long)(rt_ubase_t)g_display.framebuffer_pa) & 0xfffUL, + display_fb_crc32()); + rt_kprintf("FB_PROBE %s p00=0x%04x p_mid=0x%04x p_last=0x%04x p120_80=0x%04x p240_80=0x%04x p360_80=0x%04x p120_240=0x%04x p360_480=0x%04x\n", + tag, + display_fb_pixel(x0, y0), + display_fb_pixel(x1, y1), + display_fb_pixel(x2, y2), + display_fb_pixel(120, 80), + display_fb_pixel(240, 80), + display_fb_pixel(360, 80), + display_fb_pixel(120, 240), + display_fb_pixel(360, 480)); +} + +static void display_flush_rect(const struct rt_device_rect_info *rect) +{ + rt_uint16_t x; + rt_uint16_t y; + rt_uint16_t width; + rt_uint16_t height; + rt_uint8_t bytes_per_pixel = g_display.info.bits_per_pixel / 8; + rt_size_t line_bytes; + + if (!g_display.framebuffer) + return; + + if (!rect) { + display_bind_default_osd(); + display_commit_framebuffer(); + return; + } + + if (rect->x >= g_display.info.width || rect->y >= g_display.info.height) + return; + + x = rect->x; + y = rect->y; + width = rect->width; + height = rect->height; + + if (x + width > g_display.info.width) + width = g_display.info.width - x; + if (y + height > g_display.info.height) + height = g_display.info.height - y; + if (width == 0 || height == 0) + return; + + line_bytes = width * bytes_per_pixel; + if (x == 0 && width == g_display.info.width) { + display_flush_range(g_display.framebuffer + y * g_display.info.pitch, + height * g_display.info.pitch); + display_bind_default_osd(); + if (g_display.initialized) + kd_vo_commit(); + return; + } + + for (rt_uint16_t row = 0; row < height; row++) { + display_flush_range(g_display.framebuffer + (y + row) * g_display.info.pitch + + x * bytes_per_pixel, + line_bytes); + } + display_bind_default_osd(); + if (g_display.initialized) + kd_vo_commit(); +} + +static rt_err_t display_init(rt_device_t dev) +{ + rt_size_t fb_size; + + (void)dev; + + if (g_display.initialized) + return RT_EOK; + + if (!g_display.panel) { + rt_kprintf("display: no panel selected\n"); + return display_fail("select-panel", -RT_ERROR); + } + + rt_kprintf("display: init start, panel=%s\n", g_display.panel->name); + + if (display_hw_enable() != RT_EOK) + return display_fail("hw-enable", -RT_ERROR); + + if (vo_display_remap_init() != 0) { + rt_kprintf("display: register remap failed\n"); + return display_fail("remap", -RT_ERROR); + } + + fb_size = g_display.panel->timing.hactive * g_display.panel->timing.vactive * 2; + g_display.framebuffer = rt_malloc_align(fb_size, K230_DISPLAY_FB_ALIGN); + if (!g_display.framebuffer) { + rt_kprintf("display: framebuffer allocation failed\n"); + return display_fail("fb-alloc", -RT_ENOMEM); + } + + rt_memset(g_display.framebuffer, 0, fb_size); + g_display.framebuffer_pa = rt_kmem_v2p(g_display.framebuffer); + if (!g_display.framebuffer_pa || g_display.framebuffer_pa == ARCH_MAP_FAILED) { + rt_kprintf("display: framebuffer physical address failed\n"); + display_fb_release(); + return display_fail("fb-phys", -RT_ERROR); + } + + g_display.framebuffer_size = fb_size; + g_display.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; + g_display.info.bits_per_pixel = 16; + g_display.info.pitch = g_display.panel->timing.hactive * 2; + g_display.info.width = g_display.panel->timing.hactive; + g_display.info.height = g_display.panel->timing.vactive; + g_display.info.framebuffer = g_display.framebuffer; + g_display.info.smem_len = fb_size; + display_flush_range(g_display.framebuffer, fb_size); + + if (panel_generic_power_on(g_display.panel) != 0) { + rt_kprintf("display: power_on failed\n"); + display_fb_release(); + return display_fail("panel-power-on", -RT_ERROR); + } + + g_display.initialized = RT_TRUE; + g_display.brightness = 255; + g_display.last_stage = "ready"; + g_display.last_error = RT_EOK; + + kd_vo_disable_osd_all(); + + panel_generic_backlight(g_display.panel, 1, g_display.brightness); + + rt_kprintf("display: init done, fb va=%p pa=%p size=0x%lx\n", + g_display.framebuffer, g_display.framebuffer_pa, + (unsigned long)g_display.framebuffer_size); + return RT_EOK; +} + +static rt_err_t display_open(rt_device_t dev, rt_uint16_t oflag) +{ + (void)oflag; + return display_init(dev); +} + +static rt_err_t display_close(rt_device_t dev) +{ + (void)dev; + return RT_EOK; +} + +static rt_ssize_t display_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + rt_size_t count; + + (void)dev; + + if (!buffer || !g_display.framebuffer || pos < 0) + return 0; + if ((rt_size_t)pos >= g_display.framebuffer_size) + return 0; + + count = g_display.framebuffer_size - (rt_size_t)pos; + if (count > size) + count = size; + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + rt_memcpy(buffer, g_display.framebuffer + pos, count); + rt_mutex_release(&g_display.lock); + + return count; +} + +static rt_ssize_t display_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + rt_size_t count; + + (void)dev; + + if (!buffer || !g_display.framebuffer || pos < 0) + return 0; + if ((rt_size_t)pos >= g_display.framebuffer_size) + return 0; + + count = g_display.framebuffer_size - (rt_size_t)pos; + if (count > size) + count = size; + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + rt_memcpy(g_display.framebuffer + pos, buffer, count); + display_bind_default_osd(); + display_commit_framebuffer(); + rt_mutex_release(&g_display.lock); + + return count; +} + +static rt_err_t display_control(rt_device_t dev, int cmd, void* args) +{ + (void)dev; + + switch (cmd) { + case RTGRAPHIC_CTRL_GET_INFO: + if (!args) + return -RT_EINVAL; + rt_memcpy(args, &g_display.info, sizeof(g_display.info)); + break; + case RTGRAPHIC_CTRL_RECT_UPDATE: + display_flush_rect((const struct rt_device_rect_info *)args); + break; + case RTGRAPHIC_CTRL_POWERON: + case LCD_CTRL_BACKLIGHT_ON: + panel_generic_backlight(g_display.panel, 1, g_display.brightness); + break; + case RTGRAPHIC_CTRL_POWEROFF: + case LCD_CTRL_BACKLIGHT_OFF: + panel_generic_backlight(g_display.panel, 0, 0); + break; + case RTGRAPHIC_CTRL_SET_BRIGHTNESS: + g_display.brightness = args ? *(rt_uint8_t *)args : 0; + panel_generic_backlight(g_display.panel, g_display.brightness ? 1 : 0, + g_display.brightness); + break; + case RTGRAPHIC_CTRL_GET_BRIGHTNESS: + if (!args) + return -RT_EINVAL; + *(rt_uint8_t *)args = g_display.brightness; + break; + case RTGRAPHIC_CTRL_WAIT_VSYNC: + rt_thread_mdelay(1000 / 60); + break; + case LCD_CTRL_SET_BG_COLOR: + if (args) + kd_vo_set_background(*(k_u32*)args); + break; +#ifdef RT_FIOMMAP2 + case RT_FIOMMAP2: + { + struct dfs_mmap2_args *mmap2 = (struct dfs_mmap2_args *)args; + + if (!mmap2 || !g_display.framebuffer_pa) + return -RT_EINVAL; + if (mmap2->length > g_display.framebuffer_size) + return -RT_ENOMEM; + + mmap2->ret = lwp_map_user_phy(lwp_self(), RT_NULL, g_display.framebuffer_pa, + mmap2->length, 1); + break; + } +#endif + default: + return -RT_ERROR; + } + return RT_EOK; +} + +static void display_set_pixel(const char *pixel, int x, int y) +{ + rt_uint8_t *dst; + rt_uint8_t bytes_per_pixel = g_display.info.bits_per_pixel / 8; + + if (!pixel || !g_display.framebuffer || x < 0 || y < 0 || + x >= g_display.info.width || y >= g_display.info.height) + return; + + dst = g_display.framebuffer + y * g_display.info.pitch + x * bytes_per_pixel; + rt_memcpy(dst, pixel, bytes_per_pixel); + display_flush_range(dst, bytes_per_pixel); + display_bind_default_osd(); + if (g_display.initialized) + kd_vo_commit(); +} + +static void display_get_pixel(char *pixel, int x, int y) +{ + rt_uint8_t *src; + rt_uint8_t bytes_per_pixel = g_display.info.bits_per_pixel / 8; + + if (!pixel || !g_display.framebuffer || x < 0 || y < 0 || + x >= g_display.info.width || y >= g_display.info.height) + return; + + src = g_display.framebuffer + y * g_display.info.pitch + x * bytes_per_pixel; + rt_memcpy(pixel, src, bytes_per_pixel); +} + +static void display_draw_hline(const char *pixel, int x1, int x2, int y) +{ + rt_uint8_t bytes_per_pixel = g_display.info.bits_per_pixel / 8; + rt_uint8_t *dst; + + if (!pixel || !g_display.framebuffer || y < 0 || y >= g_display.info.height) + return; + + if (x1 > x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + + if (x2 < 0 || x1 >= g_display.info.width) + return; + if (x1 < 0) + x1 = 0; + if (x2 >= g_display.info.width) + x2 = g_display.info.width - 1; + + dst = g_display.framebuffer + y * g_display.info.pitch + x1 * bytes_per_pixel; + for (int x = x1; x <= x2; x++) { + rt_memcpy(dst, pixel, bytes_per_pixel); + dst += bytes_per_pixel; + } + display_flush_range(g_display.framebuffer + y * g_display.info.pitch + x1 * bytes_per_pixel, + (x2 - x1 + 1) * bytes_per_pixel); + display_bind_default_osd(); + if (g_display.initialized) + kd_vo_commit(); +} + +static void display_draw_vline(const char *pixel, int x, int y1, int y2) +{ + if (!pixel || !g_display.framebuffer || x < 0 || x >= g_display.info.width) + return; + + if (y1 > y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + if (y2 < 0 || y1 >= g_display.info.height) + return; + if (y1 < 0) + y1 = 0; + if (y2 >= g_display.info.height) + y2 = g_display.info.height - 1; + + for (int y = y1; y <= y2; y++) + display_set_pixel(pixel, x, y); +} + +static void display_blit_line(const char *pixel, int x, int y, rt_size_t size) +{ + rt_uint8_t bytes_per_pixel = g_display.info.bits_per_pixel / 8; + rt_uint8_t *dst; + rt_size_t max_size; + + if (!pixel || !g_display.framebuffer || x < 0 || y < 0 || + x >= g_display.info.width || y >= g_display.info.height) + return; + + max_size = (g_display.info.width - x) * bytes_per_pixel; + if (size > max_size) + size = max_size; + + dst = g_display.framebuffer + y * g_display.info.pitch + x * bytes_per_pixel; + rt_memcpy(dst, pixel, size); + display_flush_range(dst, size); + display_bind_default_osd(); + if (g_display.initialized) + kd_vo_commit(); +} + +static struct rt_device_graphic_ops display_graphic_ops = { + .set_pixel = display_set_pixel, + .get_pixel = display_get_pixel, + .draw_hline = display_draw_hline, + .draw_vline = display_draw_vline, + .blit_line = display_blit_line, +}; + +static void list_display(int argc, char** argv) +{ + (void)argc; + (void)argv; + + rt_kprintf("Display Panels:\n"); + rt_kprintf("%-24s %-12s %-7s\n", "NAME", "RESOLUTION", "FPS"); + rt_kprintf("%-24s %-12s %-7s\n", "------------------------", "------------", "-------"); + + int shown = 0; + for (int i = 0; display_drv_list[i] != RT_NULL; i++) { + struct panel_drv* drv = display_drv_list[i]; + + if (drv->panel_variants) { + for (int j = 0; drv->panel_variants[j] != RT_NULL; j++) { + const struct panel_desc* panel = drv->panel_variants[j]; + int fps = panel_calculate_fps(&panel->timing); + rt_kprintf("%-24s %4ux%-4u %3d fps\n", + panel->name, panel->timing.hactive, + panel->timing.vactive, fps); + shown++; + } + } else if (drv->active_panel) { + const struct panel_desc* panel = drv->active_panel; + int fps = panel_calculate_fps(&panel->timing); + rt_kprintf("%-24s %4ux%-4u %3d fps\n", + panel->name, panel->timing.hactive, panel->timing.vactive, fps); + shown++; + } + } + + if (shown == 0) + rt_kprintf("No panels registered.\n"); +} + +MSH_CMD_EXPORT(list_display, list display panels); + +static void display_dump(int argc, char** argv) +{ + (void)argc; + (void)argv; + + rt_kprintf("display initialized=%d panel=%s\n", + g_display.initialized, + g_display.panel ? g_display.panel->name : ""); + rt_kprintf("display last_stage=%s last_error=%d\n", + g_display.last_stage ? g_display.last_stage : "", + g_display.last_error); + rt_kprintf("fb va=%p pa=%p size=0x%lx width=%u height=%u pitch=%u bpp=%u brightness=%u\n", + g_display.framebuffer, g_display.framebuffer_pa, + (unsigned long)g_display.framebuffer_size, + g_display.info.width, g_display.info.height, + g_display.info.pitch, g_display.info.bits_per_pixel, + g_display.brightness); + + if (g_display.panel) { + const k_vo_timing *t = &g_display.panel->timing; + + rt_kprintf("timing pclk=%u h=%u/%u/%u/%u v=%u/%u/%u/%u bg=0x%08x\n", + t->pclk_khz, + t->hactive, t->hsync_len, t->hback_porch, t->hfront_porch, + t->vactive, t->vsync_len, t->vback_porch, t->vfront_porch, + g_display.panel->bg_color); + } + + if (sysctl_pwr) { + rt_kprintf("PWR base=%p disp_ctl=0x%08x disp_state=0x%08x dpu_ctl=0x%08x dpu_state=0x%08x repair=0x%08x\n", + sysctl_pwr, + sysctl_pwr->disp_lpi_ctl, sysctl_pwr->disp_lpi_state, + sysctl_pwr->dpu_pwr_lpi_ctl, sysctl_pwr->dpu_pwr_lpi_state, + sysctl_pwr->repair_status); + } else { + rt_kprintf("PWR base=\n"); + } + + if (sysctl_rst) { + rt_kprintf("RMU base=%p dpu_rst_tim=0x%08x dpu_rst_ctl=0x%08x disp_rst_tim=0x%08x disp_rst_ctl=0x%08x\n", + sysctl_rst, + sysctl_rst->dpu_rst_tim, sysctl_rst->dpu_rst_ctl, + sysctl_rst->disp_sys_rst_tim, sysctl_rst->disp_rst_ctl); + } else { + rt_kprintf("RMU base=\n"); + } + + kd_vo_debug_dump(); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_dump, dump K230 display registers); + +static void display_bind_osd(int argc, char** argv) +{ + int osd; + + if (argc != 2) { + rt_kprintf("usage: display_bind_osd <0-3>\n"); + return; + } + + if (!g_display.framebuffer_pa) { + rt_kprintf("display: framebuffer is not ready\n"); + return; + } + + osd = atoi(argv[1]); + if (osd < 0 || osd > 3) { + rt_kprintf("display: invalid osd %d\n", osd); + return; + } + + kd_vo_set_osd_rgb565_framebuffer((k_u32)osd, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + g_display.info.width, g_display.info.height, + g_display.info.pitch); + kd_vo_select_osd((k_u32)osd); + display_commit_framebuffer(); + rt_kprintf("display: bound fb0 to OSD%d\n", osd); +} +MSH_CMD_EXPORT(display_bind_osd, bind fb0 to K230 VO OSD plane); + +static void display_peek(int argc, char** argv) +{ + volatile rt_uint32_t *base = RT_NULL; + unsigned long offset; + unsigned long count = 1; + + if (argc < 3 || argc > 4) { + rt_kprintf("usage: display_peek [count]\n"); + return; + } + + if (vo_display_remap_init() != 0) { + rt_kprintf("display: register remap failed\n"); + return; + } + + if (rt_strcmp(argv[1], "vo") == 0) { + base = (volatile rt_uint32_t *)display_remap->vo_base; + } else if (rt_strcmp(argv[1], "dsi") == 0) { + base = (volatile rt_uint32_t *)display_remap->dsi_base; + } else if (rt_strcmp(argv[1], "phy") == 0) { + base = (volatile rt_uint32_t *)display_remap->phy_base; + } else if (rt_strcmp(argv[1], "pwr") == 0) { + base = (volatile rt_uint32_t *)sysctl_pwr; + } else if (rt_strcmp(argv[1], "rmu") == 0) { + base = (volatile rt_uint32_t *)sysctl_rst; + } else if (rt_strcmp(argv[1], "cmu") == 0) { + base = (volatile rt_uint32_t *)display_remap->clock_base; + } else if (rt_strcmp(argv[1], "stc") == 0) { + base = (volatile rt_uint32_t *)display_remap->timestamp_base; + } else { + rt_kprintf("display: unknown region %s\n", argv[1]); + return; + } + + if (base == RT_NULL) { + rt_kprintf("display: region %s is not mapped\n", argv[1]); + return; + } + + offset = strtoul(argv[2], RT_NULL, 0); + if ((offset & 0x3UL) != 0) { + rt_kprintf("display: offset must be 4-byte aligned\n"); + return; + } + + if (argc == 4) + count = strtoul(argv[3], RT_NULL, 0); + if (count == 0) + count = 1; + if (count > 64) + count = 64; + + for (unsigned long i = 0; i < count; i++) { + volatile rt_uint32_t *reg = (volatile rt_uint32_t *)((rt_uint8_t *)base + offset + i * 4); + + rt_kprintf("%s[0x%04lx] = 0x%08x\n", + argv[1], offset + i * 4, *reg); + } +} +MSH_CMD_EXPORT(display_peek, read K230 display/sysctl registers); + +static void display_poke(int argc, char** argv) +{ + unsigned long offset; + unsigned long value; + + if (argc != 3) { + rt_kprintf("usage: display_poke \n"); + return; + } + + offset = strtoul(argv[1], RT_NULL, 0); + value = strtoul(argv[2], RT_NULL, 0); + if ((offset & 0x3UL) != 0) { + rt_kprintf("display: offset must be 4-byte aligned\n"); + return; + } + + kd_vo_poke((k_u32)offset, (k_u32)value); + rt_kprintf("vo[0x%04lx] <- 0x%08lx\n", offset, value); +} +MSH_CMD_EXPORT(display_poke, write a K230 VO register); + +static void display_osd_tune(int argc, char** argv) +{ + int osd; + unsigned long stride; + unsigned long dma_ctrl; + unsigned long addr_sel; + + if (argc != 5) { + rt_kprintf("usage: display_osd_tune \n"); + rt_kprintf("example: display_osd_tune 2 0x00000078 0x7f 0x100\n"); + return; + } + + if (!g_display.framebuffer_pa) { + rt_kprintf("display: framebuffer is not ready\n"); + return; + } + + osd = atoi(argv[1]); + if (osd < 0 || osd > 3) { + rt_kprintf("display: invalid osd %d\n", osd); + return; + } + + stride = strtoul(argv[2], RT_NULL, 0); + dma_ctrl = strtoul(argv[3], RT_NULL, 0); + addr_sel = strtoul(argv[4], RT_NULL, 0); + + kd_vo_set_osd_rgb565_framebuffer_raw((k_u32)osd, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + g_display.info.width, + g_display.info.height, + (k_u32)stride, + (k_u32)dma_ctrl, + (k_u32)addr_sel); + kd_vo_select_osd((k_u32)osd); + display_commit_framebuffer(); + rt_kprintf("display: osd%d stride=0x%08lx dma=0x%08lx sel=0x%08lx addr=0x%08lx\n", + osd, stride, dma_ctrl, addr_sel, + (unsigned long)(rt_ubase_t)g_display.framebuffer_pa); +} +MSH_CMD_EXPORT(display_osd_tune, tune K230 VO OSD framebuffer registers); + +static void display_phy(int argc, char** argv) +{ + unsigned long m; + unsigned long n; + unsigned long voc; + unsigned long hs_freq; + + if (argc != 5) { + rt_kprintf("usage: display_phy \n"); + return; + } + + if (vo_display_remap_init() != 0) { + rt_kprintf("display: register remap failed\n"); + return; + } + + m = strtoul(argv[1], RT_NULL, 0); + n = strtoul(argv[2], RT_NULL, 0); + voc = strtoul(argv[3], RT_NULL, 0); + hs_freq = strtoul(argv[4], RT_NULL, 0); + + k230_dsi_phy_config(K_DSI_2LAN, (k_u32)m, (k_u32)n, (k_u8)voc, (k_u8)hs_freq); + rt_thread_mdelay(1); + rt_kprintf("display: phy set m=%lu n=%lu voc=0x%02lx hs_freq=0x%02lx\n", + m, n, voc, hs_freq); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_phy, configure K230 DSI PHY clock parameters); + +static void display_hw_on(int argc, char** argv) +{ + (void)argc; + (void)argv; + + if (display_hw_enable() == RT_EOK) + rt_kprintf("display: DISP/DPU power and reset sequence done\n"); +} +MSH_CMD_EXPORT(display_hw_on, enable K230 display power domains and reset blocks); + +static void display_init_now(int argc, char** argv) +{ + rt_err_t ret; + + (void)argc; + (void)argv; + + ret = display_init(&g_display.lcd); + rt_kprintf("display_init_now: ret=%d initialized=%d stage=%s\n", + ret, g_display.initialized, + g_display.last_stage ? g_display.last_stage : ""); +} +MSH_CMD_EXPORT(display_init_now, initialize K230 display immediately); + +static void display_panel_on(int argc, char** argv) +{ + k_u8 vc; + k_u8 sleep_out[] = { 0x11 }; + k_u8 pixel_format[] = { 0x3A, 0x50 }; + k_u8 display_on[] = { 0x29 }; + int ret_sleep; + int ret_format; + int ret_on; + + (void)argc; + (void)argv; + + if (!g_display.panel) { + rt_kprintf("display: no panel selected\n"); + return; + } + + vc = g_display.panel->bus.dsi.vc_id; + ret_sleep = dwc_dsi_dcs_write(sleep_out, sizeof(sleep_out), vc); + rt_thread_mdelay(200); + ret_format = dwc_dsi_dcs_write(pixel_format, sizeof(pixel_format), vc); + ret_on = dwc_dsi_dcs_write(display_on, sizeof(display_on), vc); + rt_thread_mdelay(50); + + rt_kprintf("display_panel_on: sleep=%d format=%d display=%d\n", + ret_sleep, ret_format, ret_on); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_panel_on, send ST7701 sleep-out pixel-format display-on); + +static int display_panel_set_colmod(k_u8 value) +{ + k_u8 vc; + k_u8 pixel_format[2]; + + if (!g_display.panel) + return -RT_ERROR; + + vc = g_display.panel->bus.dsi.vc_id; + pixel_format[0] = 0x3A; + pixel_format[1] = value; + return dwc_dsi_dcs_write(pixel_format, sizeof(pixel_format), vc); +} + +static void display_colmod(int argc, char** argv) +{ + unsigned long value; + int ret; + + if (argc != 2) { + rt_kprintf("usage: display_colmod <0x50|0x55|0x66>\n"); + return; + } + + value = strtoul(argv[1], RT_NULL, 0); + ret = display_panel_set_colmod((k_u8)value); + rt_kprintf("display: panel COLMOD=0x%02lx ret=%d\n", value & 0xffUL, ret); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_colmod, set panel DCS 0x3A pixel format); + +static void display_panel_status_read(k_u8 cmd, const char *name) +{ + k_u8 vc = g_display.panel->bus.dsi.vc_id; + k_u8 max_return[2] = { 1, 0 }; + k_u8 data[4] = { 0 }; + int ret; + + ret = dwc_dsi_send_packet(0x37, vc, max_return, sizeof(max_return), 0); + if (ret != 0) { + rt_kprintf("%s(0x%02x): set-max-return failed ret=%d\n", + name, cmd, ret); + return; + } + + ret = dwc_dsi_dcs_read(cmd, data, 1, vc); + if (ret < 0) { + rt_kprintf("%s(0x%02x): read failed ret=%d\n", name, cmd, ret); + return; + } + + rt_kprintf("%s(0x%02x): ret=%d data=0x%02x\n", + name, cmd, ret, data[0]); +} + +static void display_panel_status(int argc, char** argv) +{ + (void)argc; + (void)argv; + + if (!g_display.panel) { + rt_kprintf("display: no panel selected\n"); + return; + } + + display_panel_status_read(0x0A, "power-mode"); + display_panel_status_read(0x0B, "address-mode"); + display_panel_status_read(0x0C, "pixel-format"); + display_panel_status_read(0x0D, "display-mode"); + display_panel_status_read(0x0E, "signal-mode"); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_panel_status, read basic panel DCS status registers); + +static void display_bg(int argc, char** argv) +{ + unsigned long color; + + if (argc != 2) { + rt_kprintf("usage: display_bg \n"); + return; + } + + color = strtoul(argv[1], RT_NULL, 0); + kd_vo_set_background((k_u32)color); + rt_kprintf("display: background rgb888=0x%06lx\n", color & 0xffffffUL); +} +MSH_CMD_EXPORT(display_bg, set VO background color from RGB888); + +static void display_bg_yuv(int argc, char** argv) +{ + unsigned long color; + + if (argc != 2) { + rt_kprintf("usage: display_bg_yuv \n"); + return; + } + + color = strtoul(argv[1], RT_NULL, 0); + kd_vo_set_background_yuv((k_u32)color); + rt_kprintf("display: background yuv=0x%06lx\n", color & 0xffffffUL); +} +MSH_CMD_EXPORT(display_bg_yuv, set VO background color from packed YUV); + +static rt_uint16_t display_rgb565(rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) +{ + return (rt_uint16_t)(((r & 0xf8U) << 8) | ((g & 0xfcU) << 3) | (b >> 3)); +} + +static void display_fill(int argc, char** argv) +{ + unsigned long rgb; + rt_uint8_t r; + rt_uint8_t g; + rt_uint8_t b; + rt_uint16_t color; + rt_uint16_t *fb; + rt_size_t pixels; + + if (argc != 2) { + rt_kprintf("usage: display_fill \n"); + return; + } + + if (!g_display.framebuffer) { + rt_kprintf("display: framebuffer is not ready\n"); + return; + } + + rgb = strtoul(argv[1], RT_NULL, 0); + r = (rt_uint8_t)((rgb >> 16) & 0xffU); + g = (rt_uint8_t)((rgb >> 8) & 0xffU); + b = (rt_uint8_t)(rgb & 0xffU); + color = display_rgb565(r, g, b); + fb = (rt_uint16_t *)g_display.framebuffer; + pixels = (g_display.info.pitch / 2U) * g_display.info.height; + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + for (rt_size_t i = 0; i < pixels; i++) + fb[i] = color; + display_bind_default_osd(); + display_commit_framebuffer(); + rt_mutex_release(&g_display.lock); + + rt_kprintf("display: filled fb0 rgb888=0x%06lx rgb565=0x%04x\n", + rgb & 0xffffffUL, color); +} +MSH_CMD_EXPORT(display_fill, fill fb0 with one RGB565 color); + +static void display_draw_rect_rgb565(rt_int32_t x, rt_int32_t y, + rt_int32_t w, rt_int32_t h, + rt_uint16_t color) +{ + rt_int32_t x0; + rt_int32_t y0; + rt_int32_t x1; + rt_int32_t y1; + rt_uint16_t *line; + + if (!g_display.framebuffer || w <= 0 || h <= 0) + return; + + x0 = x; + y0 = y; + x1 = x + w; + y1 = y + h; + + if (x0 < 0) + x0 = 0; + if (y0 < 0) + y0 = 0; + if (x1 > (rt_int32_t)g_display.info.width) + x1 = g_display.info.width; + if (y1 > (rt_int32_t)g_display.info.height) + y1 = g_display.info.height; + if (x0 >= x1 || y0 >= y1) + return; + + for (rt_int32_t row = y0; row < y1; row++) { + line = (rt_uint16_t *)(g_display.framebuffer + + row * g_display.info.pitch + + x0 * sizeof(rt_uint16_t)); + for (rt_int32_t col = x0; col < x1; col++) + *line++ = color; + } +} + +static void display_rect(int argc, char** argv) +{ + rt_int32_t x; + rt_int32_t y; + rt_int32_t w; + rt_int32_t h; + unsigned long rgb; + rt_uint16_t color; + + if (argc != 6) { + rt_kprintf("usage: display_rect \n"); + return; + } + + if (!g_display.framebuffer) { + rt_kprintf("display: framebuffer is not ready\n"); + return; + } + + x = (rt_int32_t)strtol(argv[1], RT_NULL, 0); + y = (rt_int32_t)strtol(argv[2], RT_NULL, 0); + w = (rt_int32_t)strtol(argv[3], RT_NULL, 0); + h = (rt_int32_t)strtol(argv[4], RT_NULL, 0); + rgb = strtoul(argv[5], RT_NULL, 0); + color = display_rgb565((rt_uint8_t)((rgb >> 16) & 0xffU), + (rt_uint8_t)((rgb >> 8) & 0xffU), + (rt_uint8_t)(rgb & 0xffU)); + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + display_draw_rect_rgb565(x, y, w, h, color); + display_bind_default_osd(); + display_commit_framebuffer(); + rt_mutex_release(&g_display.lock); + + rt_kprintf("display: rect x=%d y=%d w=%d h=%d rgb888=0x%06lx rgb565=0x%04x\n", + x, y, w, h, rgb & 0xffffffUL, color); +} +MSH_CMD_EXPORT(display_rect, draw an RGB565 rectangle into fb0); + +static void display_blocks(int argc, char** argv) +{ + (void)argc; + (void)argv; + + if (!g_display.framebuffer) { + rt_kprintf("display: framebuffer is not ready\n"); + return; + } + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + display_draw_rect_rgb565(0, 0, 120, 160, display_rgb565(255, 0, 0)); + display_draw_rect_rgb565(120, 0, 120, 160, display_rgb565(0, 255, 0)); + display_draw_rect_rgb565(240, 0, 120, 160, display_rgb565(0, 0, 255)); + display_draw_rect_rgb565(360, 0, 120, 160, display_rgb565(255, 255, 255)); + display_draw_rect_rgb565(0, 160, 240, 160, display_rgb565(255, 255, 0)); + display_draw_rect_rgb565(240, 160, 240, 160, display_rgb565(0, 255, 255)); + display_draw_rect_rgb565(0, 320, 240, 320, display_rgb565(255, 0, 255)); + display_draw_rect_rgb565(240, 320, 240, 320, display_rgb565(32, 32, 32)); + display_bind_default_osd(); + display_commit_framebuffer(); + rt_mutex_release(&g_display.lock); + + rt_kprintf("display: drew RGB565 block pattern\n"); +} +MSH_CMD_EXPORT(display_blocks, draw fixed RGB565 rectangles into fb0); + +static void display_fb_probe(int argc, char** argv) +{ + (void)argc; + (void)argv; + + display_commit_framebuffer(); + display_fb_probe_print("manual"); + kd_vo_debug_summary(); +} +MSH_CMD_EXPORT(display_fb_probe, print framebuffer checksum and key pixels); + +static void display_diag_write_blocks(void) +{ + display_draw_rect_rgb565(0, 0, 120, 160, display_rgb565(255, 0, 0)); + display_draw_rect_rgb565(120, 0, 120, 160, display_rgb565(0, 255, 0)); + display_draw_rect_rgb565(240, 0, 120, 160, display_rgb565(0, 0, 255)); + display_draw_rect_rgb565(360, 0, 120, 160, display_rgb565(255, 255, 255)); + display_draw_rect_rgb565(0, 160, 240, 160, display_rgb565(255, 255, 0)); + display_draw_rect_rgb565(240, 160, 240, 160, display_rgb565(0, 255, 255)); + display_draw_rect_rgb565(0, 320, 240, 320, display_rgb565(255, 0, 255)); + display_draw_rect_rgb565(240, 320, 240, 320, display_rgb565(32, 32, 32)); +} + +static void display_diag_fill_rgb565(rt_uint16_t color) +{ + rt_uint16_t *fb = (rt_uint16_t *)g_display.framebuffer; + rt_size_t pixels = (g_display.info.pitch / 2U) * g_display.info.height; + + for (rt_size_t i = 0; i < pixels; i++) + fb[i] = color; +} + +static void display_diag_case_format(const char *name, int osd, k_u32 stride, + k_u32 info, k_u32 dma_ctrl, k_u32 addr_sel, + rt_bool_t blocks, rt_uint16_t fill); + +static void display_diag_case(const char *name, int osd, k_u32 stride, + k_u32 dma_ctrl, k_u32 addr_sel, rt_bool_t blocks, + rt_uint16_t fill) +{ + display_diag_case_format(name, osd, stride, 0x00000002U, dma_ctrl, addr_sel, + blocks, fill); +} + +static void display_diag_case_format(const char *name, int osd, k_u32 stride, + k_u32 info, k_u32 dma_ctrl, k_u32 addr_sel, + rt_bool_t blocks, rt_uint16_t fill) +{ + rt_kprintf("DIAG_CASE begin %s osd=%d stride=0x%08x info=0x%08x dma=0x%08x sel=0x%08x pattern=%s\n", + name, osd, stride, info, dma_ctrl, addr_sel, blocks ? "blocks" : "fill"); + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + if (blocks) + display_diag_write_blocks(); + else + display_diag_fill_rgb565(fill); + display_commit_framebuffer(); + kd_vo_set_osd_rgb565_framebuffer_format_raw((k_u32)osd, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + g_display.info.width, + g_display.info.height, + stride, + info, + dma_ctrl, + addr_sel); + kd_vo_select_osd((k_u32)osd); + rt_mutex_release(&g_display.lock); + + kd_vo_debug_summary(); + display_fb_probe_print(name); + rt_kprintf("DIAG_CASE end %s observe-screen-now\n", name); + rt_thread_mdelay(800); +} + +static void display_diag_bg_case(const char *name, k_u32 yuv) +{ + rt_kprintf("DIAG_CASE begin %s bg_yuv=0x%06x\n", name, yuv & 0xffffffU); + kd_vo_disable_osd_all(); + kd_vo_set_background_yuv(yuv); + kd_vo_debug_summary(); + display_fb_probe_print(name); + rt_kprintf("DIAG_CASE end %s observe-screen-now\n", name); + rt_thread_mdelay(500); +} + +static void display_bg_only(int argc, char** argv) +{ + unsigned long yuv = 0x4c551dUL; + + if (argc > 2) { + rt_kprintf("usage: display_bg_only [yuv]\n"); + return; + } + if (!g_display.initialized) { + rt_kprintf("display_bg_only: display is not initialized, run display_init_now first\n"); + return; + } + if (argc == 2) + yuv = strtoul(argv[1], RT_NULL, 0); + + kd_vo_disable_osd_all(); + kd_vo_set_background_yuv((k_u32)yuv); + rt_kprintf("display: background only yuv=0x%06lx\n", yuv & 0xffffffUL); + kd_vo_debug_summary(); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_bg_only, disable OSD planes and show VO background color); + +static void display_diag(int argc, char** argv) +{ + k_u32 stride_sdk; + k_u32 stride_packed16; + k_u32 stride_legacy_low; + + (void)argc; + (void)argv; + + if (!g_display.initialized) { + rt_kprintf("display_diag: display is not initialized, run display_init_now first\n"); + return; + } + if (!g_display.framebuffer || !g_display.framebuffer_pa) { + rt_kprintf("display_diag: framebuffer is not ready\n"); + return; + } + + stride_sdk = g_display.info.pitch / 8U; + stride_packed16 = (g_display.info.pitch / 32U) | ((g_display.info.pitch / 32U) << 16); + stride_legacy_low = g_display.info.pitch / 32U; + + rt_kprintf("DIAG_START fb_va=%p fb_pa=%p size=0x%lx w=%u h=%u pitch=%u stride_sdk64=0x%08x stride_packed16=0x%08x stride_legacy_low=0x%08x\n", + g_display.framebuffer, g_display.framebuffer_pa, + (unsigned long)g_display.framebuffer_size, + g_display.info.width, g_display.info.height, g_display.info.pitch, + stride_sdk, stride_packed16, stride_legacy_low); + + display_commit_framebuffer(); + display_fb_probe_print("start"); + kd_vo_debug_summary(); + dwc_dsi_debug_dump(); + + display_diag_bg_case("bg-red-yuv", 0x4c551d); + display_diag_bg_case("bg-green-yuv", 0x952b15); + display_diag_bg_case("bg-blue-yuv", 0x1d6bff); + + display_diag_case_format("osd2-blocks-sdk-rgb565", 2, stride_sdk, 0x00000002U, 0x0000007fU, 0x00000100U, RT_TRUE, 0); + display_diag_case_format("osd2-fill-red-sdk-rgb565", 2, stride_sdk, 0x00000002U, 0x0000007fU, 0x00000100U, RT_FALSE, display_rgb565(255, 0, 0)); + display_diag_case_format("osd0-blocks-sdk-rgb565", 0, stride_sdk, 0x00000002U, 0x0000007fU, 0x00000100U, RT_TRUE, 0); + display_diag_case_format("osd1-blocks-sdk-rgb565", 1, stride_sdk, 0x00000002U, 0x0000007fU, 0x00000100U, RT_TRUE, 0); + display_diag_case_format("osd3-blocks-sdk-rgb565", 3, stride_sdk, 0x00000002U, 0x0000007fU, 0x00000100U, RT_TRUE, 0); + + display_diag_case_format("osd2-blocks-prev-dma0f", 2, stride_sdk, 0x00000002U, 0x0000000fU, 0x00000100U, RT_TRUE, 0); + display_diag_case_format("osd2-blocks-prev-dma4f", 2, stride_sdk, 0x00000002U, 0x0000004fU, 0x00000100U, RT_TRUE, 0); + display_diag_case_format("osd2-blocks-info2-dma3f", 2, stride_sdk, 0x00000002U, 0x0000003fU, 0x00000100U, RT_TRUE, 0); + display_diag_case_format("osd2-blocks-info2-dma5f", 2, stride_sdk, 0x00000002U, 0x0000005fU, 0x00000100U, RT_TRUE, 0); + display_diag_case("osd2-blocks-packed16", 2, stride_packed16, 0x0000007fU, 0x00000100U, RT_TRUE, 0); + display_diag_case("osd2-blocks-legacy-low", 2, stride_legacy_low, 0x0000007fU, 0x00000100U, RT_TRUE, 0); + display_diag_case("osd2-blocks-sel0", 2, stride_sdk, 0x0000007fU, 0x00000000U, RT_TRUE, 0); + + rt_kprintf("DIAG_DONE\n"); +} +MSH_CMD_EXPORT(display_diag, run concentrated display scanout diagnostics); + +static void display_dsi_video(int argc, char** argv) +{ + unsigned long dpi_color; + unsigned long pkt; + unsigned long hsa; + unsigned long hbp; + unsigned long hline; + unsigned long mode; + + if (argc != 7) { + rt_kprintf("usage: display_dsi_video \n"); + return; + } + + dpi_color = strtoul(argv[1], RT_NULL, 0); + pkt = strtoul(argv[2], RT_NULL, 0); + hsa = strtoul(argv[3], RT_NULL, 0); + hbp = strtoul(argv[4], RT_NULL, 0); + hline = strtoul(argv[5], RT_NULL, 0); + mode = strtoul(argv[6], RT_NULL, 0); + + dwc_dsi_set_video_scan((k_u32)dpi_color, (k_u32)pkt, + (k_u32)hsa, (k_u32)hbp, + (k_u32)hline, (k_u32)mode); + rt_kprintf("display: dsi video dpi=0x%lx pkt=%lu hsa=%lu hbp=%lu hline=%lu mode=%lu\n", + dpi_color & 0x7UL, pkt, hsa, hbp, hline, mode); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_dsi_video, set DSI DPI video scan registers); + +static void display_dsi_diag_case(const char *name, k_u8 colmod, + k_u32 dpi_color, k_u32 pkt, + k_u32 hsa, k_u32 hbp, + k_u32 hline, k_u32 mode) +{ + int ret; + k_u32 stride_sdk; + + stride_sdk = g_display.info.pitch / 8U; + + rt_kprintf("DSI_DIAG_CASE begin %s colmod=0x%02x dpi=0x%08x pkt=%u hsa=%u hbp=%u hline=%u mode=%u\n", + name, colmod, dpi_color, pkt, hsa, hbp, hline, mode); + + ret = display_panel_set_colmod(colmod); + rt_kprintf("DSI_DIAG_CASE %s colmod_ret=%d\n", name, ret); + dwc_dsi_set_video_scan(dpi_color, pkt, hsa, hbp, hline, mode); + + rt_mutex_take(&g_display.lock, RT_WAITING_FOREVER); + display_diag_write_blocks(); + display_commit_framebuffer(); + kd_vo_set_osd_rgb565_framebuffer_raw(2, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + (k_u64)(rt_ubase_t)g_display.framebuffer_pa, + g_display.info.width, + g_display.info.height, + stride_sdk, + 0x0000007fU, + 0x00000100U); + kd_vo_select_osd(2); + rt_mutex_release(&g_display.lock); + + kd_vo_debug_summary(); + dwc_dsi_debug_dump(); + display_fb_probe_print(name); + rt_kprintf("DSI_DIAG_CASE end %s observe-screen-now\n", name); + rt_thread_mdelay(1000); +} + +static void display_dsi_diag(int argc, char** argv) +{ + (void)argc; + (void)argv; + + if (!g_display.initialized) { + rt_kprintf("display_dsi_diag: display is not initialized, run display_init_now first\n"); + return; + } + if (!g_display.framebuffer || !g_display.framebuffer_pa) { + rt_kprintf("display_dsi_diag: framebuffer is not ready\n"); + return; + } + + rt_kprintf("DSI_DIAG_START w=%u h=%u pitch=%u fb_pa=%p\n", + g_display.info.width, g_display.info.height, + g_display.info.pitch, g_display.framebuffer_pa); + kd_vo_debug_summary(); + dwc_dsi_debug_dump(); + + display_dsi_diag_case("col70-dpi5-p480-h840-burst", 0x70, 5, 480, 30, 30, 840, K_BURST_MODE); + display_dsi_diag_case("col70-dpi5-p480-h840-sync-event", 0x70, 5, 480, 30, 30, 840, K_NON_BURST_MODE_WITH_SYNC_EVENT); + display_dsi_diag_case("col70-dpi5-p480-h840-pulses", 0x70, 5, 480, 30, 30, 840, K_NON_BURST_MODE_WITH_PULSES); + display_dsi_diag_case("col50-dpi0-p480-h560-burst", 0x50, 0, 480, 20, 20, 560, K_BURST_MODE); + display_dsi_diag_case("col50-dpi1-p480-h560-burst", 0x50, 1, 480, 20, 20, 560, K_BURST_MODE); + display_dsi_diag_case("col50-dpi2-p480-h560-burst", 0x50, 2, 480, 20, 20, 560, K_BURST_MODE); + display_dsi_diag_case("col55-dpi5-p480-h840-burst", 0x55, 5, 480, 30, 30, 840, K_BURST_MODE); + display_dsi_diag_case("col55-dpi5-p480-h560-burst", 0x55, 5, 480, 20, 20, 560, K_BURST_MODE); + display_dsi_diag_case("col66-dpi5-p480-h840-burst", 0x66, 5, 480, 30, 30, 840, K_BURST_MODE); + + (void)display_panel_set_colmod(0x50); + dwc_dsi_set_video_scan(1, 480, 20, 20, 560, K_BURST_MODE); + rt_kprintf("DSI_DIAG_DONE restored colmod=0x50 dpi=1 pkt=480 hline=560 burst\n"); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_dsi_diag, scan DSI video color and timing combinations); + +static void display_dpi_color(int argc, char** argv) +{ + unsigned long coding; + + if (argc != 2) { + rt_kprintf("usage: display_dpi_color <0|1|2|5>\n"); + return; + } + + coding = strtoul(argv[1], RT_NULL, 0); + dwc_dsi_set_dpi_color_coding((k_u32)coding); + rt_kprintf("display: DSI DPI color coding=0x%lx\n", coding & 0x7UL); + dwc_dsi_debug_dump(); +} +MSH_CMD_EXPORT(display_dpi_color, set DSI DPI color coding register); + +static const struct rt_device_ops display_ops = { + .init = display_init, + .open = display_open, + .close = display_close, + .read = display_read, + .write = display_write, + .control = display_control, +}; + +int k230_display_init(void) +{ + rt_memset(&g_display, 0, sizeof(g_display)); + + g_display.panel = (struct panel_desc*)find_panel_by_name("st7701_480x640_atk"); + if (!g_display.panel) { + rt_kprintf("display: st7701_480x640_atk panel not found\n"); + return -1; + } + + rt_mutex_init(&g_display.lock, "display", RT_IPC_FLAG_PRIO); + + g_display.lcd.type = RT_Device_Class_Graphic; + g_display.lcd.ops = &display_ops; + g_display.lcd.user_data = &display_graphic_ops; + + g_display.fb.type = RT_Device_Class_Graphic; + g_display.fb.ops = &display_ops; + g_display.fb.user_data = &display_graphic_ops; + + rt_device_register(&g_display.lcd, "lcd", RT_DEVICE_FLAG_RDWR); + rt_device_register(&g_display.fb, "fb0", RT_DEVICE_FLAG_RDWR); + g_display.last_stage = "registered"; + g_display.last_error = RT_EOK; + + rt_kprintf("display: lcd/fb0 device registered\n"); + return 0; +} +INIT_DEVICE_EXPORT(k230_display_init); diff --git a/bsp/k230/drivers/display/drv_display.h b/bsp/k230/drivers/display/drv_display.h new file mode 100644 index 00000000000..440a940e860 --- /dev/null +++ b/bsp/k230/drivers/display/drv_display.h @@ -0,0 +1,18 @@ +#ifndef _DRV_DISPLAY_H_ +#define _DRV_DISPLAY_H_ + +#include + +/* K230D board pins */ +#define K230D_LCD_RESET_PIN 3 +#define K230D_LCD_BACKLIGHT_PIN 5 + +#define K230_DISPLAY_FB_ALIGN 4096 + +#define LCD_CTRL_BACKLIGHT_OFF 0 +#define LCD_CTRL_BACKLIGHT_ON 1 +#define LCD_CTRL_SET_BG_COLOR 2 + +int k230_display_init(void); + +#endif /* _DRV_DISPLAY_H_ */ diff --git a/bsp/k230/drivers/display/include/k_connector_comm.h b/bsp/k230/drivers/display/include/k_connector_comm.h new file mode 100644 index 00000000000..02191bff1f5 --- /dev/null +++ b/bsp/k230/drivers/display/include/k_connector_comm.h @@ -0,0 +1,117 @@ +#ifndef __K_CONNECTOR_COMM_H__ +#define __K_CONNECTOR_COMM_H__ + +#include "k_type.h" +#include "k_vo_comm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Connector chip identifier */ +typedef enum { + K_CHIP_VIRTUAL = 0, + K_CHIP_HX8399 = 1, + K_CHIP_ILI9806 = 2, + K_CHIP_ILI9881 = 3, + K_CHIP_NT35516 = 4, + K_CHIP_NT35532 = 5, + K_CHIP_GC9503 = 6, + K_CHIP_ST7102 = 7, + K_CHIP_AML020T = 8, + K_CHIP_ST7701 = 9, + K_CHIP_JD9852 = 10, + K_CHIP_LT9611 = 11, + K_CHIP_ST7789 = 12, + K_CHIP_NV3030B = 13, +} k_connector_chip; + +/** Connector bus type */ +typedef enum { + K_BUS_DSI = 0, + K_BUS_HDMI = 1, + K_BUS_SPI = 2, +} k_connector_bus; + +/* + * k_connector_type encoding (32-bit): + * [31:26] chip (6 bits) + * [25:24] bus (2 bits) + * [23:20] version (4 bits) + * [19:10] width (10 bits) — h >> 1 + * [9:0] height (10 bits) — v >> 1 + */ +#define _CONN_CHIP_BITS 6 +#define _CONN_BUS_BITS 2 +#define _CONN_VER_BITS 4 +#define _CONN_W_BITS 10 +#define _CONN_H_BITS 10 + +#define _CONN_H_SHIFT 0 +#define _CONN_W_SHIFT 10 +#define _CONN_VER_SHIFT 20 +#define _CONN_BUS_SHIFT 24 +#define _CONN_CHIP_SHIFT 26 + +#define _CONN_MASK(bits) ((1U << (bits)) - 1) + +#define K_CONN_TYPE(chip, bus, w, h, ver) \ + ((k_u32) \ + ((((k_u32)(chip) & _CONN_MASK(_CONN_CHIP_BITS)) << _CONN_CHIP_SHIFT) | \ + (((k_u32)(bus) & _CONN_MASK(_CONN_BUS_BITS)) << _CONN_BUS_SHIFT) | \ + (((k_u32)(ver) & _CONN_MASK(_CONN_VER_BITS)) << _CONN_VER_SHIFT) | \ + (((k_u32)((w) >> 1) & _CONN_MASK(_CONN_W_BITS)) << _CONN_W_SHIFT) | \ + (((k_u32)((h) >> 1) & _CONN_MASK(_CONN_H_BITS)) << _CONN_H_SHIFT))) + +#define K_CONN_CHIP(type) ((k_connector_chip)(((type) >> _CONN_CHIP_SHIFT) & _CONN_MASK(_CONN_CHIP_BITS))) +#define K_CONN_BUS(type) ((k_connector_bus)(((type) >> _CONN_BUS_SHIFT) & _CONN_MASK(_CONN_BUS_BITS))) +#define K_CONN_VER(type) (((type) >> _CONN_VER_SHIFT) & _CONN_MASK(_CONN_VER_BITS)) +#define K_CONN_WIDTH(type) ((((type) >> _CONN_W_SHIFT) & _CONN_MASK(_CONN_W_BITS)) << 1) +#define K_CONN_HEIGHT(type) ((((type) >> _CONN_H_SHIFT) & _CONN_MASK(_CONN_H_BITS)) << 1) + +typedef k_u32 k_connector_type; + +/* ST7701 variants */ +#define ST7701_480_800_DSI_V1 K_CONN_TYPE(K_CHIP_ST7701, K_BUS_DSI, 480, 800, 1) +#define ST7701_480_854_DSI_V1 K_CONN_TYPE(K_CHIP_ST7701, K_BUS_DSI, 480, 854, 1) +#define ST7701_480_640_DSI_V1 K_CONN_TYPE(K_CHIP_ST7701, K_BUS_DSI, 480, 640, 1) +#define ST7701_368_544_DSI_V1 K_CONN_TYPE(K_CHIP_ST7701, K_BUS_DSI, 368, 544, 1) + +#define CONNECTOR_BUTT ((k_u32)0xFFFFFFFF) + +typedef enum { + K_CONNECTOR_BL_MODE_OFF = 0, + K_CONNECTOR_BL_MODE_ON = 1, + K_CONNECTOR_BL_MODE_PWM = 2, +} k_connector_backlight_mode; + +typedef struct { + k_connector_backlight_mode mode; + k_u32 duty; +} k_connector_backlight_attr; + +typedef struct { + char connector_name[32]; + k_connector_type type; + union { + k_vo_timing timing; + k_vo_timing resolution; + }; + k_u32 bg_color; +} k_connector_info; + +typedef struct { + k_u8 cmd_type; + k_u8 cmd_delay; + k_u8 cmd_size; + k_u8 cmd_data[0]; +} k_connector_cmd_slice; + +#define CONNECTOR_CMD_SEQUENCE(type, delay, ...) \ + (type), (delay), sizeof((k_u8[]) { __VA_ARGS__ }) / sizeof(k_u8), __VA_ARGS__ + +#ifdef __cplusplus +} +#endif + +#endif /* __K_CONNECTOR_COMM_H__ */ diff --git a/bsp/k230/drivers/display/include/k_type.h b/bsp/k230/drivers/display/include/k_type.h new file mode 100644 index 00000000000..8e7e7a4726d --- /dev/null +++ b/bsp/k230/drivers/display/include/k_type.h @@ -0,0 +1,36 @@ +#ifndef __K_TYPE_H__ +#define __K_TYPE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char k_u8; +typedef unsigned short k_u16; +typedef unsigned int k_u32; + +typedef signed char k_s8; +typedef short k_s16; +typedef int k_s32; + +typedef unsigned long k_u64; +typedef signed long k_s64; + +typedef char k_char; + +typedef enum +{ + K_FALSE = 0, + K_TRUE = 1, +} k_bool; + +typedef k_u32 k_handle; + +#define K_SUCCESS (0) +#define K_FAILED (-1) + +#ifdef __cplusplus +} +#endif + +#endif /* __K_TYPE_H__ */ diff --git a/bsp/k230/drivers/display/include/k_vo_comm.h b/bsp/k230/drivers/display/include/k_vo_comm.h new file mode 100644 index 00000000000..4852a37e119 --- /dev/null +++ b/bsp/k230/drivers/display/include/k_vo_comm.h @@ -0,0 +1,98 @@ +#ifndef __K_VO_COMM_H__ +#define __K_VO_COMM_H__ + +#include "k_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Display device / channel constants */ +#define K_VO_MAX_DEV_NUMS (1) +#define K_VO_MAX_CHN_NUMS (8) +#define K_VO_DISPLAY_DEV_ID (0) + +#define K_VO_DEFAULT_MIX_ORDER (0x0000000076543210) + +typedef struct { + k_u32 x; + k_u32 y; +} k_vo_position; + +typedef struct { + k_u32 width; + k_u32 height; +} k_vo_size; + +struct vo_disp_layer_mix_priority_t { + union { + struct { + k_u64 layer0_sel : 4; + k_u64 layer1_sel : 4; + k_u64 layer2_sel : 4; + k_u64 layer3_sel : 4; + k_u64 layer4_sel : 4; + k_u64 layer5_sel : 4; + k_u64 layer6_sel : 4; + k_u64 layer7_sel : 4; + k_u64 layer8_sel : 4; + k_u64 layer9_sel : 4; + k_u64 layer10_sel : 4; + k_u64 layer11_sel : 4; + k_u64 recv : 16; + } bits; + k_u64 reg; + }; +}; + +/* Display timing parameters */ +typedef struct { + k_u32 pclk_khz; + k_u32 hactive; + k_u32 hsync_len; + k_u32 hback_porch; + k_u32 hfront_porch; + k_u32 vactive; + k_u32 vsync_len; + k_u32 vback_porch; + k_u32 vfront_porch; +} k_vo_timing; + +/* DSI lane config */ +typedef enum { + K_DSI_1LAN = 0, + K_DSI_2LAN = 1, + K_DSI_4LAN = 3, +} k_vo_dsi_lane_num; + +typedef enum { + K_VO_LP_MODE = 0, + K_VO_HS_MODE, +} k_vo_dsi_cmd_mode; + +typedef enum { + K_BURST_MODE = 0, + K_NON_BURST_MODE_WITH_SYNC_EVENT = 1, + K_NON_BURST_MODE_WITH_PULSES = 2, +} k_vo_dsi_video_mode; + +typedef struct { + struct { + k_u32 datarate; + k_u32 m, n, voc, hs_freq; + } phy; + + const k_vo_timing* timing; + + k_vo_dsi_lane_num lanes; + k_vo_dsi_cmd_mode cmd_mode; + k_vo_dsi_video_mode video_mode; + k_u8 vc_id; + k_u8 lp_speed_mhz; +} k_vo_dsi_config; + +#ifdef __cplusplus +} +#endif + +#endif /* __K_VO_COMM_H__ */ diff --git a/bsp/k230/drivers/display/lib/vo_stubs.c b/bsp/k230/drivers/display/lib/vo_stubs.c new file mode 100644 index 00000000000..d3bf2f91eb7 --- /dev/null +++ b/bsp/k230/drivers/display/lib/vo_stubs.c @@ -0,0 +1,27 @@ +/* Small compatibility helpers used by the source VO/DSI implementation. */ + +#include +#include + +#ifndef VO_LOG_LEVEL +#define VO_LOG_LEVEL 3 +#endif + +void cpu_ticks_delay_us(uint64_t us) +{ + rt_hw_us_delay(us); +} + +void K_LOG(int level, int module, const char* fmt, ...) +{ + char buf[256]; + va_list args; + + if (level > VO_LOG_LEVEL) + return; + + va_start(args, fmt); + rt_vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + rt_kprintf("[vo:%d:%d] %s", module, level, buf); +} diff --git a/bsp/k230/drivers/display/panel_common.c b/bsp/k230/drivers/display/panel_common.c new file mode 100644 index 00000000000..5bc60436536 --- /dev/null +++ b/bsp/k230/drivers/display/panel_common.c @@ -0,0 +1,252 @@ +/* Adapted from atk_k230d connector_panel_common.c for RT-Thread BSP */ + +#include +#include + +#include "connector_bus_dsi.h" +#include "connector_panel.h" + +extern void kd_vo_reset(void); +extern void kd_vo_wrap_init(void); +extern void kd_vo_set_config_mix(void); +extern void kd_vo_set_frame_intr(k_bool status); +extern void kd_vo_set_timing(const k_vo_timing* timing); +extern void kd_vo_set_pixclk(k_u32 div); +extern void kd_vo_set_background(k_u32 rgb888); +extern void kd_vo_enable(void); + +static inline k_u32 panel_calc_pixclk_div(k_u32 pclk_khz) +{ + return (pclk_khz == 0) ? 0 : (VO_PIXEL_CLOCK_HZ / (pclk_khz * 1000)) - 1; +} + +static k_s32 panel_vo_init(const struct panel_desc* desc) +{ + kd_vo_wrap_init(); + kd_vo_set_config_mix(); + kd_vo_set_frame_intr(K_TRUE); + kd_vo_set_timing(&desc->timing); + kd_vo_set_background(desc->bg_color); + kd_vo_enable(); + return 0; +} + +k_u32 panel_correct_pclk(k_u32 pclk_hz) +{ + k_u32 ratio; + + if (pclk_hz == 0) + return 0; + + ratio = (VO_PIXEL_CLOCK_HZ + pclk_hz / 2) / pclk_hz; + if (ratio == 0) + ratio = 1; + + return VO_PIXEL_CLOCK_HZ / ratio; +} + +int panel_calculate_fps(const k_vo_timing* timing) +{ + k_u32 htotal, vtotal; + + if (!timing) + return 0; + + htotal = timing->hactive + timing->hsync_len + timing->hback_porch + timing->hfront_porch; + vtotal = timing->vactive + timing->vsync_len + timing->vback_porch + timing->vfront_porch; + + if (htotal == 0 || vtotal == 0) + return 0; + + return (timing->pclk_khz * 1000) / htotal / vtotal; +} + +int panel_generic_reset(const struct panel_desc* desc) +{ + k_s32 reset_pin; + k_u32 reset_delay_ms; + k_bool reset_active_low; + int inactive_level, active_level; + + if (!desc) + return -1; + + reset_pin = desc->gpio.reset_pin; + if (reset_pin < 0) + return 0; + + reset_delay_ms = desc->gpio.reset_delay_ms; + reset_active_low = desc->gpio.reset_active_low; + + if (reset_active_low) { + active_level = PIN_LOW; + inactive_level = PIN_HIGH; + } else { + active_level = PIN_HIGH; + inactive_level = PIN_LOW; + } + + rt_pin_mode(reset_pin, PIN_MODE_OUTPUT); + + rt_pin_write(reset_pin, inactive_level); + rt_thread_mdelay(3); + + rt_pin_write(reset_pin, active_level); + rt_thread_mdelay(7); + + rt_pin_write(reset_pin, inactive_level); + rt_thread_mdelay(reset_delay_ms); + + return 0; +} + +static int panel_generic_backlight_over_gpio(const struct panel_desc* desc, k_u32 mode, k_u32 duty) +{ + k_s32 backlight_pin; + k_u32 backlight_delay_ms; + k_bool backlight_active_low; + int target_level; + int on; + + if (!desc) + return -1; + + backlight_pin = desc->gpio.backlight_pin; + if (backlight_pin < 0) + return -1; + + if (mode == 0) + on = 0; + else if (mode == 1) + on = 1; + else + on = duty / 128; + + backlight_delay_ms = desc->gpio.backlight_delay_ms; + backlight_active_low = desc->gpio.backlight_active_low; + + if (backlight_active_low) + target_level = on ? PIN_LOW : PIN_HIGH; + else + target_level = on ? PIN_HIGH : PIN_LOW; + + rt_pin_mode(backlight_pin, PIN_MODE_OUTPUT); + rt_pin_write(backlight_pin, target_level); + + if (backlight_delay_ms > 0) + rt_thread_mdelay(backlight_delay_ms); + + return 0; +} + +int panel_generic_backlight(const struct panel_desc* desc, k_u32 mode, k_u32 duty) +{ + if (!desc) + return -1; + + return panel_generic_backlight_over_gpio(desc, mode, duty); +} + +k_s32 panel_generic_power_on(struct panel_desc* desc) +{ + k_s32 ret; + k_u32 pixclk_div; + int fps; + + if (!desc) + return -1; + + kd_vo_reset(); + + if (!desc->bus_ops) { + rt_kprintf("panel_generic_power_on: missing bus_ops\n"); + return -1; + } + + if (desc->ops && desc->ops->reset) { + ret = desc->ops->reset(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_on: ops->reset failed: %d\n", ret); + return ret; + } + } + + if (desc->bus_type == PANEL_BUS_DSI) { + desc->timing.pclk_khz = dsi_correct_pclk(desc->timing.pclk_khz * 1000, desc->bus.dsi.lanes) / 1000; + } else { + desc->timing.pclk_khz = panel_correct_pclk(desc->timing.pclk_khz * 1000) / 1000; + } + + fps = panel_calculate_fps(&desc->timing); + rt_kprintf("panel %s, pixelclock %u khz, resolution %dx%d@%d\n", + desc->name, desc->timing.pclk_khz, desc->timing.hactive, desc->timing.vactive, fps); + + pixclk_div = panel_calc_pixclk_div(desc->timing.pclk_khz); + if (pixclk_div != 0) + kd_vo_set_pixclk(pixclk_div); + + if (desc->bus_ops->init) { + ret = desc->bus_ops->init(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_on: bus_ops->init failed: %d\n", ret); + return ret; + } + } + + if (!desc->ops || !desc->ops->init) { + rt_kprintf("panel_generic_power_on: panel missing mandatory ops->init\n"); + return -1; + } + + ret = desc->ops->init(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_on: ops->init failed: %d\n", ret); + return ret; + } + + if (desc->bus_ops->enable) { + ret = desc->bus_ops->enable(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_on: bus_ops->enable failed: %d\n", ret); + return ret; + } + } + + ret = panel_vo_init(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_on: panel_vo_init failed: %d\n", ret); + return ret; + } + + return 0; +} + +k_s32 panel_generic_power_off(const struct panel_desc* desc) +{ + k_s32 first_err = 0; + k_s32 ret; + + if (!desc) + return -1; + + panel_generic_backlight(desc, 0, 0); + + if (desc->ops && desc->ops->power_off) { + ret = desc->ops->power_off(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_off: ops->power_off failed: %d\n", ret); + first_err = ret; + } + } + + if (desc->bus_ops && desc->bus_ops->disable) { + ret = desc->bus_ops->disable(desc); + if (ret != 0) { + rt_kprintf("panel_generic_power_off: bus_ops->disable failed: %d\n", ret); + if (!first_err) + first_err = ret; + } + } + + return first_err; +} diff --git a/bsp/k230/drivers/display/panels/SConscript b/bsp/k230/drivers/display/panels/SConscript new file mode 100644 index 00000000000..17399e96708 --- /dev/null +++ b/bsp/k230/drivers/display/panels/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('DisplayPanels', src, depend=['BSP_USING_DISPLAY'], CPPPATH=CPPPATH) + +Return('group') diff --git a/bsp/k230/drivers/display/panels/mipi_st7701.c b/bsp/k230/drivers/display/panels/mipi_st7701.c new file mode 100644 index 00000000000..ea2cd8c5233 --- /dev/null +++ b/bsp/k230/drivers/display/panels/mipi_st7701.c @@ -0,0 +1,126 @@ +/* Adapted from atk_k230d mipi_st7701.c — K230D ATK variant only */ + +#include + +#include "connector_panel.h" +#include "connector_bus_dsi.h" + +#include "drv_display.h" + +static int st7701_480x640_atk_init(const struct panel_desc* desc) +{ + /* clang-format off */ + const k_u8 init_sequence[] = { + // cmd type, delay, data length, data0 ... dataN + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x13, + 0x15, 0, 2, 0xEF, 0x08, + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x10, + 0x39, 0, 3, 0xC0, 0x4F, 0x00, + 0x39, 0, 3, 0xC1, 0x10, 0x0C, + 0x39, 0, 3, 0xC2, 0x01, 0x14, + 0x15, 0, 2, 0xCC, 0x10, + 0x39, 0,17, 0xB0, 0x00, 0x0B, 0x13, 0x0D, 0x10, 0x07, 0x02, 0x08, 0x07, 0x1F, 0x04, 0x11, 0x0F, 0x28, 0x2F, 0x1F, + 0x39, 0,17, 0xB1, 0x00, 0x0C, 0x13, 0x0C, 0x10, 0x05, 0x02, 0x08, 0x08, 0x1E, 0x05, 0x13, 0x11, 0x27, 0x30, 0x1F, + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x11, + 0x15, 0, 2, 0xB0, 0x4D, + 0x15, 0, 2, 0xB1, 0x4D, + 0x15, 0, 2, 0xB2, 0x87, + 0x15, 0, 2, 0xB3, 0x80, + 0x15, 0, 2, 0xB5, 0x45, + 0x15, 0, 2, 0xB7, 0x85, + 0x15, 0, 2, 0xB8, 0x20, + 0x15, 0, 2, 0xC0, 0x09, + 0x15, 0, 2, 0xC1, 0x78, + 0x15, 0, 2, 0xC2, 0x78, + 0x15,10, 2, 0xD0, 0x88, + 0x39, 0, 4, 0xE0, 0x00, 0x00, 0x02, + 0x39, 0,12, 0xE1, 0x04, 0xB0, 0x06, 0xB0, 0x05, 0xB0, 0x07, 0xB0, 0x00, 0x44, 0x44, + 0x39, 0,13, 0xE2, 0x20, 0x20, 0x44, 0x44, 0x96, 0xA0, 0x00, 0x00, 0x96, 0xA0, 0x00, 0x00, + 0x39, 0, 5, 0xE3, 0x00, 0x00, 0x22, 0x22, + 0x39, 0, 3, 0xE4, 0x44, 0x44, + 0x39, 0,17, 0xE5, 0x0C, 0x90, 0xB0, 0xA0, 0x0E, 0x92, 0xB0, 0xA0, 0x08, 0x8C, 0xB0, 0xA0, 0x0A, 0x8E, 0xB0, 0xA0, + 0x39, 0, 5, 0xE6, 0x00, 0x00, 0x22, 0x22, + 0x39, 0, 3, 0xE7, 0x44, 0x44, + 0x39, 0,17, 0xE8, 0x0D, 0x91, 0xB0, 0xA0, 0x0F, 0x93, 0xB0, 0xA0, 0x09, 0x8D, 0xB0, 0xA0, 0x0B, 0x8F, 0xB0, 0xA0, + 0x39, 0, 3, 0xE9, 0x36, 0x00, + 0x39, 0, 8, 0xEB, 0x00, 0x00, 0xE4, 0xE4, 0x44, 0x88, 0x40, + 0x39, 0,17, 0xED, 0xC1, 0xA2, 0xBF, 0x0F, 0x67, 0x45, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x76, 0xF0, 0xFB, 0x2A, 0x1C, + 0x39, 0, 7, 0xEF, 0x10, 0x0D, 0x04, 0x08, 0x3F, 0x1F, + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x13, + 0x39, 0, 3, 0xE8, 0x00, 0x0E, + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x00, + 0x05,200, 1, 0x11, + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x13, + 0x39,10, 3, 0xE8, 0x00, 0x0C, + 0x39, 0, 3, 0xE8, 0x00, 0x00, + 0x39, 0, 6, 0xFF, 0x77, 0x01, 0x00, 0x00, 0x00, + 0x15, 0, 2, 0x3A, 0x50, + 0x05,50, 1, 0x29, + }; + /* clang-format on */ + + return dsi_send_cmd_sequence(desc, init_sequence, sizeof(init_sequence), 0); +} + +static int st7701_power_off(const struct panel_desc* desc) +{ + (void)desc; + return 0; +} + +static const struct panel_ops st7701_480x640_atk_ops = { + .reset = panel_generic_reset, + .init = st7701_480x640_atk_init, + .power_off = st7701_power_off, + .read_chip_id = dsi_read_chip_id, +}; + +static struct panel_desc st7701_480x640_atk_panel_desc = { + .name = "st7701_480x640_atk", + .connector_type = ST7701_480_640_DSI_V1, + .bus_type = PANEL_BUS_DSI, + + .timing = { + .pclk_khz = 24864, + .hactive = 480, + .hsync_len = 20, + .hback_porch = 20, + .hfront_porch = 40, + .vactive = 640, + .vsync_len = 20, + .vback_porch = 20, + .vfront_porch = 40, + }, + + .bg_color = PANEL_BG_COLOR_BLACK, + + .gpio = { + .reset_pin = K230D_LCD_RESET_PIN, + .backlight_pin = K230D_LCD_BACKLIGHT_PIN, + .reset_delay_ms = 10, + .backlight_delay_ms = 0, + .reset_active_low = K_TRUE, + .backlight_active_low = K_FALSE, + }, + + .bus.dsi = { + .lanes = K_DSI_2LAN, + .cmd_mode = K_VO_LP_MODE, + .video_mode = K_BURST_MODE, + .vc_id = 0, + }, + + .bus_ops = &dsi_bus_ops, + .ops = &st7701_480x640_atk_ops, +}; + +static const struct panel_desc* st7701_panel_variants[] = { + &st7701_480x640_atk_panel_desc, + NULL, +}; + +struct panel_drv mipi_st7701_drv = { + .connector_name = "st7701", + .panel_variants = st7701_panel_variants, + .active_panel = &st7701_480x640_atk_panel_desc, +}; diff --git a/bsp/k230/drivers/display/vo/kd_dsi_reg.c b/bsp/k230/drivers/display/vo/kd_dsi_reg.c new file mode 100644 index 00000000000..94b87f68a58 --- /dev/null +++ b/bsp/k230/drivers/display/vo/kd_dsi_reg.c @@ -0,0 +1,1089 @@ +#include "kd_dsi_reg.h" +#include "vo_display_remap.h" + +#include + +#include +#include + +#define KD_DSI_MODULE_ID 11 + +#define DSI_REG_PWR_UP 0x004 +#define DSI_REG_CLKMGR_CFG 0x008 +#define DSI_REG_DPI_VCID 0x00c +#define DSI_REG_DPI_COLOR_CODING 0x010 +#define DSI_REG_DPI_CFG_POL 0x014 +#define DSI_REG_DPI_LP_CMD_TIM 0x018 +#define DSI_REG_PCKHDL_CFG 0x02c +#define DSI_REG_GEN_VCID 0x030 +#define DSI_REG_VID_MODE_CFG 0x038 +#define DSI_REG_VID_PKT_SIZE 0x03c +#define DSI_REG_VID_NUM_CHUNKS 0x040 +#define DSI_REG_VID_NULL_SIZE 0x044 +#define DSI_REG_VID_HSA_TIME 0x048 +#define DSI_REG_VID_HBP_TIME 0x04c +#define DSI_REG_VID_HLINE_TIME 0x050 +#define DSI_REG_VID_VSA_LINES 0x054 +#define DSI_REG_VID_VBP_LINES 0x058 +#define DSI_REG_VID_VFP_LINES 0x05c +#define DSI_REG_VID_VACTIVE_LINES 0x060 +#define DSI_REG_CMD_MODE_CFG 0x068 +#define DSI_REG_GEN_HDR 0x06c +#define DSI_REG_GEN_PLD_DATA 0x070 +#define DSI_REG_CMD_PKT_STATUS 0x074 +#define DSI_REG_TO_CNT_CFG 0x078 +#define DSI_REG_HS_RD_TO_CNT 0x080 +#define DSI_REG_BTA_TO_CNT 0x08c +#define DSI_REG_LPCLK_CTRL 0x094 +#define DSI_REG_PHY_TMR_LPCLK_CFG 0x098 +#define DSI_REG_PHY_TMR_CFG 0x09c +#define DSI_REG_PHY_TMR_RD_CFG 0x0f4 +#define DSI_REG_PHY_IF_CFG 0x0a4 +#define DSI_REG_PHY_RSTZ 0x0a0 +#define DSI_REG_PHY_STATUS 0x0b0 +#define DSI_REG_PHY_TST_CTRL0 0x0b4 +#define DSI_REG_PHY_TST_CTRL1 0x0b8 +#define DSI_REG_INT_ST0 0x0bc +#define DSI_REG_INT_ST1 0x0c0 +#define DSI_REG_INT_MSK0 0x0c4 +#define DSI_REG_INT_MSK1 0x0c8 +#define DSI_REG_MODE_CFG 0x034 + +#define DSI_CMD_MODE_ALL_LP 0x010f7f00U +#define DSI_DPI_COLOR_RGB565 0x1U +#define DSI_DPI_BYTES_PER_PIXEL 2U + +#define DSI_PACKET_DCS_SHORT_WRITE0 0x05 +#define DSI_PACKET_DCS_SHORT_WRITE1 0x15 +#define DSI_PACKET_DCS_LONG_WRITE 0x39 +#define DSI_PACKET_DCS_READ 0x06 +#define DSI_PACKET_GEN_SHORT_WRITE0 0x03 +#define DSI_PACKET_GEN_SHORT_WRITE1 0x13 +#define DSI_PACKET_GEN_SHORT_WRITE2 0x23 +#define DSI_PACKET_GEN_LONG_WRITE 0x29 +#define DSI_PACKET_GEN_READ0 0x04 +#define DSI_PACKET_GEN_READ1 0x14 +#define DSI_PACKET_GEN_READ2 0x24 + +#define DSI_WAIT_US 10 +#define DSI_WAIT_RETRY 20000U + +#if defined(__riscv) +#define DSI_FENCE_WO() __asm__ volatile("fence w,o" ::: "memory") +#define DSI_FENCE_IR() __asm__ volatile("fence i,r" ::: "memory") +#else +#define DSI_FENCE_WO() __asm__ volatile("" ::: "memory") +#define DSI_FENCE_IR() __asm__ volatile("" ::: "memory") +#endif + +struct kd_dsi_resolution { + k_u32 pclk; + k_u32 phyclk; + k_u32 htotal; + k_u32 hdisplay; + k_u32 hsync_len; + k_u32 hback_porch; + k_u32 hfront_porch; + k_u32 vtotal; + k_u32 vdisplay; + k_u32 vsync_len; + k_u32 vback_porch; + k_u32 vfront_porch; +}; + +struct kd_dsi_config { + k_u32 pclk; + k_u32 phyclk; + k_u32 n; + k_u32 m; + k_u32 voc; + k_u32 lane_num; + k_u32 hs_freq; + k_u32 cmd_mode; + k_u32 work_mode; + k_u32 video_mode; + struct kd_dsi_resolution *resolution; + uint8_t color_coding; + uint8_t lp_div; +}; + +struct dsi_dphy_timing { + k_u32 lane_mbps; + k_u16 clk_lp2hs; + k_u16 clk_hs2lp; + k_u16 data_lp2hs; + k_u16 data_hs2lp; +}; + +static const k_u32 minimum_lbccs[] = {10U, 5U, 4U, 3U}; + +static const struct dsi_dphy_timing dphy_timings[] = { + { 80U, 21U, 17U, 15U, 10U}, + { 90U, 23U, 17U, 16U, 10U}, + { 100U, 22U, 17U, 16U, 10U}, + { 110U, 25U, 18U, 17U, 11U}, + { 120U, 26U, 20U, 18U, 11U}, + { 130U, 27U, 19U, 19U, 11U}, + { 140U, 27U, 19U, 19U, 11U}, + { 150U, 28U, 20U, 20U, 12U}, + { 160U, 30U, 21U, 22U, 13U}, + { 170U, 30U, 21U, 23U, 13U}, + { 180U, 31U, 21U, 23U, 13U}, + { 190U, 32U, 22U, 24U, 13U}, + { 205U, 35U, 22U, 25U, 13U}, + { 220U, 37U, 26U, 27U, 15U}, + { 235U, 38U, 28U, 27U, 16U}, + { 250U, 41U, 29U, 30U, 17U}, + { 275U, 43U, 29U, 32U, 18U}, + { 300U, 45U, 32U, 35U, 19U}, + { 325U, 48U, 33U, 36U, 18U}, + { 350U, 51U, 35U, 40U, 20U}, + { 400U, 59U, 37U, 44U, 21U}, + { 450U, 65U, 40U, 49U, 23U}, + { 500U, 71U, 41U, 54U, 24U}, + { 550U, 77U, 44U, 57U, 26U}, + { 600U, 82U, 46U, 64U, 27U}, + { 650U, 87U, 48U, 67U, 28U}, + { 700U, 94U, 52U, 71U, 29U}, + { 750U, 99U, 52U, 75U, 31U}, + { 800U, 105U, 55U, 82U, 32U}, + { 850U, 110U, 58U, 85U, 32U}, + { 900U, 115U, 58U, 88U, 35U}, + { 950U, 120U, 62U, 93U, 36U}, + {1000U, 128U, 63U, 99U, 38U}, + {1050U, 132U, 65U, 102U, 38U}, + {1100U, 138U, 67U, 106U, 39U}, + {1150U, 146U, 69U, 112U, 42U}, + {1200U, 151U, 71U, 117U, 43U}, + {1250U, 153U, 74U, 120U, 45U}, + {1300U, 160U, 73U, 124U, 46U}, + {1350U, 165U, 76U, 130U, 47U}, + {1400U, 172U, 78U, 134U, 49U}, + {1450U, 177U, 80U, 138U, 49U}, + {1500U, 183U, 81U, 143U, 52U}, + {1550U, 191U, 84U, 147U, 52U}, + {1600U, 194U, 85U, 152U, 52U}, + {1650U, 201U, 86U, 155U, 53U}, + {1700U, 208U, 88U, 161U, 53U}, + {1750U, 212U, 89U, 165U, 53U}, + {1800U, 220U, 90U, 171U, 54U}, + {1850U, 223U, 92U, 175U, 54U}, + {1900U, 231U, 91U, 180U, 55U}, + {1950U, 236U, 95U, 185U, 56U}, + {2000U, 243U, 97U, 190U, 56U}, + {2050U, 248U, 99U, 194U, 58U}, + {2100U, 252U, 100U, 199U, 59U}, + {2150U, 259U, 102U, 204U, 61U}, + {2200U, 266U, 105U, 210U, 62U}, + {2250U, 269U, 109U, 213U, 63U}, + {2300U, 272U, 109U, 217U, 65U}, + {2350U, 281U, 112U, 225U, 66U}, + {2400U, 283U, 115U, 226U, 66U}, + {2450U, 282U, 115U, 226U, 67U}, + {2500U, 281U, 118U, 227U, 67U}, +}; + +extern void K_LOG(int level, int module, const char *fmt, ...); +extern void *memcpy(void *dst, const void *src, unsigned long count); + +static k_u32 curren_video_mode; + +static void dsi_video_mode_config(k_u32 mode); + +static k_u32 dsi_lane_count(k_vo_dsi_lane_num lanes) +{ + switch (lanes) { + case K_DSI_1LAN: + return 1; + case K_DSI_2LAN: + return 2; + case K_DSI_4LAN: + return 4; + default: + return 0; + } +} + +static inline void raw_writel(k_u32 value, volatile void *addr) +{ + *(volatile k_u32 *)addr = value; +} + +static inline k_u32 raw_readl(const volatile void *addr) +{ + return *(const volatile k_u32 *)addr; +} + +static uintptr_t dsi_base_addr(void) +{ + if (display_remap == NULL || display_remap->dsi_base == NULL) { + (void)vo_display_remap_init(); + } + if (display_remap == NULL || display_remap->dsi_base == NULL) { + return 0; + } + return (uintptr_t)display_remap->dsi_base; +} + +static uintptr_t phy_base_addr(void) +{ + if (display_remap == NULL || display_remap->phy_base == NULL) { + (void)vo_display_remap_init(); + } + if (display_remap == NULL || display_remap->phy_base == NULL) { + return 0; + } + return (uintptr_t)display_remap->phy_base; +} + +static void dsi_write(k_u32 value, k_u32 offset) +{ + uintptr_t base = dsi_base_addr(); + + K_LOG(7, KD_DSI_MODULE_ID, + "[Func]:%s [Line]:%d [Info]:DSI write: offset 0x%x, val 0x%x\n", + __func__, 160, offset, value); + + if (base == 0U) { + return; + } + + DSI_FENCE_WO(); + raw_writel(value, (void *)(base + offset)); +} + +static k_u32 dsi_read(k_u32 offset) +{ + uintptr_t base = dsi_base_addr(); + k_u32 value = 0; + + if (base != 0U) { + value = raw_readl((void *)(base + offset)); + DSI_FENCE_IR(); + } + + K_LOG(7, KD_DSI_MODULE_ID, + "[Func]:%s [Line]:%d [Info]:DSI read: offset 0x%x, val 0x%x\n", + __func__, 179, offset, value); + return value; +} + +static k_u32 dsi_phy_read(k_u32 offset) +{ + uintptr_t base = phy_base_addr(); + k_u32 value = 0; + + if (base != 0U) { + value = raw_readl((void *)(base + offset)); + DSI_FENCE_IR(); + } + + return value; +} + +void dwc_dsi_debug_dump(void) +{ + rt_kprintf("DSI base=%p phy=%p mode=%u\n", + display_remap ? display_remap->dsi_base : RT_NULL, + display_remap ? display_remap->phy_base : RT_NULL, + curren_video_mode); + rt_kprintf("DSI pwr=0x%08x clk=0x%08x mode=0x%08x vid_mode=0x%08x cmd_mode=0x%08x lpclk=0x%08x dpi_lp=0x%08x dpi_color=0x%08x\n", + dsi_read(DSI_REG_PWR_UP), dsi_read(DSI_REG_CLKMGR_CFG), + dsi_read(DSI_REG_MODE_CFG), dsi_read(DSI_REG_VID_MODE_CFG), + dsi_read(DSI_REG_CMD_MODE_CFG), dsi_read(DSI_REG_LPCLK_CTRL), + dsi_read(DSI_REG_DPI_LP_CMD_TIM), + dsi_read(DSI_REG_DPI_COLOR_CODING)); + rt_kprintf("DSI phy_if=0x%08x phy_rstz=0x%08x phy_status=0x%08x hs_rd_to=0x%08x phy_tmr_rd=0x%08x\n", + dsi_read(DSI_REG_PHY_IF_CFG), dsi_read(DSI_REG_PHY_RSTZ), + dsi_read(DSI_REG_PHY_STATUS), dsi_read(DSI_REG_HS_RD_TO_CNT), + dsi_read(DSI_REG_PHY_TMR_RD_CFG)); + rt_kprintf("DSI pkt=%u chunks=%u null=%u hsa=%u hbp=%u hline=%u vsa=%u vbp=%u vfp=%u vact=%u\n", + dsi_read(DSI_REG_VID_PKT_SIZE), dsi_read(DSI_REG_VID_NUM_CHUNKS), + dsi_read(DSI_REG_VID_NULL_SIZE), dsi_read(DSI_REG_VID_HSA_TIME), + dsi_read(DSI_REG_VID_HBP_TIME), dsi_read(DSI_REG_VID_HLINE_TIME), + dsi_read(DSI_REG_VID_VSA_LINES), dsi_read(DSI_REG_VID_VBP_LINES), + dsi_read(DSI_REG_VID_VFP_LINES), dsi_read(DSI_REG_VID_VACTIVE_LINES)); + rt_kprintf("DSI status=0x%08x msk0=0x%08x msk1=0x%08x\n", + dsi_read(DSI_REG_CMD_PKT_STATUS), + dsi_read(DSI_REG_INT_MSK0), dsi_read(DSI_REG_INT_MSK1)); + rt_kprintf("DSI_PHY 0x00=0x%08x 0x04=0x%08x 0x08=0x%08x 0x0c=0x%08x 0x10=0x%08x 0x14=0x%08x 0x18=0x%08x\n", + dsi_phy_read(0x00), dsi_phy_read(0x04), dsi_phy_read(0x08), + dsi_phy_read(0x0c), dsi_phy_read(0x10), dsi_phy_read(0x14), + dsi_phy_read(0x18)); +} + +void dwc_dsi_set_dpi_color_coding(k_u32 coding) +{ + dsi_write(coding & 0x7U, DSI_REG_DPI_COLOR_CODING); +} + +void dwc_dsi_set_video_scan(k_u32 dpi_color, k_u32 pkt_size, + k_u32 hsa, k_u32 hbp, k_u32 hline, + k_u32 video_mode) +{ + dsi_write(0, DSI_REG_PWR_UP); + dsi_write(dpi_color & 0x7U, DSI_REG_DPI_COLOR_CODING); + dsi_write(pkt_size & 0x3fffU, DSI_REG_VID_PKT_SIZE); + dsi_write(hsa, DSI_REG_VID_HSA_TIME); + dsi_write(hbp, DSI_REG_VID_HBP_TIME); + dsi_write(hline, DSI_REG_VID_HLINE_TIME); + curren_video_mode = video_mode; + dsi_write(0, DSI_REG_MODE_CFG); + dsi_video_mode_config(video_mode); + dsi_write(1, DSI_REG_LPCLK_CTRL); + dsi_write(1, DSI_REG_PWR_UP); +} + +static void phy_update_bits(k_u32 offset, k_u32 mask, k_u32 value) +{ + uintptr_t base = phy_base_addr(); + k_u32 reg; + + if (base == 0U) { + return; + } + + reg = raw_readl((void *)(base + offset)); + DSI_FENCE_IR(); + reg &= ~mask; + reg |= value & mask; + DSI_FENCE_WO(); + raw_writel(reg, (void *)(base + offset)); +} + +static int packet_format_is_long(uint8_t type) +{ + return type == DSI_PACKET_DCS_LONG_WRITE || + type == DSI_PACKET_GEN_LONG_WRITE; +} + +static uint8_t dcs_packet_type(uint32_t len) +{ + if (len == 1U) { + return DSI_PACKET_DCS_SHORT_WRITE0; + } + if (len == 2U) { + return DSI_PACKET_DCS_SHORT_WRITE1; + } + return DSI_PACKET_DCS_LONG_WRITE; +} + +static int wait_status_clear(k_u32 mask) +{ + unsigned int retry; + + for (retry = 0; retry < DSI_WAIT_RETRY; ++retry) { + if ((dsi_read(DSI_REG_CMD_PKT_STATUS) & mask) == 0U) { + return 0; + } + rt_hw_us_delay(DSI_WAIT_US); + } + + return -1; +} + +static int wait_status_set(k_u32 mask) +{ + unsigned int retry; + + for (retry = 0; retry < DSI_WAIT_RETRY; ++retry) { + if ((dsi_read(DSI_REG_CMD_PKT_STATUS) & mask) == mask) { + return 0; + } + rt_hw_us_delay(DSI_WAIT_US); + } + + return -1; +} + +static void dsi_dump_packet_error(k_u8 type, k_u32 header, k_u32 status) +{ + K_LOG(3, KD_DSI_MODULE_ID, + "%s: packet 0x%x timeout, header 0x%x status 0x%x\n", + __func__, type, header, status); + rt_kprintf("DSI packet error: type=0x%02x header=0x%08x status=0x%08x\n", + type, header, status); + rt_kprintf("DSI packet regs: pwr=0x%08x mode=0x%08x cmd=0x%08x vid=0x%08x lpclk=0x%08x dpi_lp=0x%08x phy_rstz=0x%08x phy_status=0x%08x\n", + dsi_read(DSI_REG_PWR_UP), dsi_read(DSI_REG_MODE_CFG), + dsi_read(DSI_REG_CMD_MODE_CFG), dsi_read(DSI_REG_VID_MODE_CFG), + dsi_read(DSI_REG_LPCLK_CTRL), dsi_read(DSI_REG_DPI_LP_CMD_TIM), + dsi_read(DSI_REG_PHY_RSTZ), dsi_read(DSI_REG_PHY_STATUS)); + rt_kprintf("DSI packet ints: int0=0x%08x int1=0x%08x msk0=0x%08x msk1=0x%08x\n", + dsi_read(DSI_REG_INT_ST0), dsi_read(DSI_REG_INT_ST1), + dsi_read(DSI_REG_INT_MSK0), dsi_read(DSI_REG_INT_MSK1)); +} + +static int write_payload(const uint8_t *payload, uint32_t len) +{ + uint32_t offset = 0; + + while (offset < len) { + uint32_t word = 0; + uint32_t chunk = len - offset; + uint32_t i; + + if (wait_status_clear(0x8U) != 0) { + return -1; + } + + if (chunk > 4U) { + chunk = 4U; + } + + for (i = 0; i < chunk; ++i) { + word |= (k_u32)payload[offset + i] << (i * 8U); + } + + dsi_write(word, DSI_REG_GEN_PLD_DATA); + offset += chunk; + } + + return 0; +} + +static int read_payload(uint8_t *data, uint32_t len) +{ + uint32_t offset = 0; + + while (offset < len) { + k_u32 word; + uint32_t chunk = len - offset; + + if (wait_status_clear(0x10U) != 0) { + return offset == 0U ? -1 : (int)offset; + } + + if (chunk > 4U) { + chunk = 4U; + } + + word = dsi_read(DSI_REG_GEN_PLD_DATA); + memcpy(data + offset, &word, chunk); + offset += chunk; + + if ((dsi_read(DSI_REG_CMD_PKT_STATUS) & 0x10U) != 0U) { + break; + } + } + + return (int)offset; +} + +static void dsi_message_config(uint8_t channel, uint8_t lp, uint8_t ack) +{ + k_u32 value = 0; + k_u32 video_mode; + + (void)channel; + + dsi_write(0x00100004U, DSI_REG_DPI_LP_CMD_TIM); + + if (ack != 0U) { + value |= 0x2U; + } + if (lp != 0U) { + value |= DSI_CMD_MODE_ALL_LP; + } + + dsi_write(value, DSI_REG_CMD_MODE_CFG); + + video_mode = dsi_read(DSI_REG_VID_MODE_CFG); + if (lp != 0U) { + video_mode |= 0x00008000U; + } else { + video_mode &= ~0x00008000U; + } + dsi_write(video_mode, DSI_REG_VID_MODE_CFG); +} + +static void dsi_video_mode_config(k_u32 mode) +{ + k_u32 value = 0xbf00U; + + if (mode == 1U) { + value |= 0x1U; + } else if (mode != 2U) { + value |= 0x2U; + } + + dsi_write(value, DSI_REG_VID_MODE_CFG); +} + +static void dsi_set_mode(uint8_t enable, k_u32 video_mode) +{ + dsi_write(0, DSI_REG_PWR_UP); + if (enable == 0U) { + dsi_write(1, DSI_REG_MODE_CFG); + dsi_write(DSI_CMD_MODE_ALL_LP, DSI_REG_CMD_MODE_CFG); + dsi_write(0, DSI_REG_VID_MODE_CFG); + } else { + dsi_write(0, DSI_REG_MODE_CFG); + dsi_video_mode_config(video_mode); + } + dsi_write(1, DSI_REG_LPCLK_CTRL); + dsi_write(1, DSI_REG_PWR_UP); +} + +static void wait_for_two_frames(const struct kd_dsi_resolution *res) +{ + k_u32 htotal; + k_u32 vtotal; + k_u32 frame_ms; + + if (res == NULL || res->pclk == 0U) { + rt_thread_mdelay(34); + return; + } + + htotal = res->hdisplay + res->hsync_len + res->hback_porch + res->hfront_porch; + vtotal = res->vdisplay + res->vsync_len + res->vback_porch + res->vfront_porch; + frame_ms = (k_u32)(((uint64_t)htotal * (uint64_t)vtotal) / (uint64_t)res->pclk); + rt_thread_mdelay((int)((frame_ms + 1U) * 2U)); +} + +void k230_dsi_write_phy_reg(uint8_t addr, uint8_t value) +{ + dsi_write(0x10000U | addr, DSI_REG_PHY_TST_CTRL1); + dsi_write(2, DSI_REG_PHY_TST_CTRL0); + dsi_write(0, DSI_REG_PHY_TST_CTRL0); + dsi_write(value, DSI_REG_PHY_TST_CTRL1); + dsi_write(2, DSI_REG_PHY_TST_CTRL0); + dsi_write(0, DSI_REG_PHY_TST_CTRL0); +} + +void k230_dsi_phy_pll_config(uint32_t m, uint32_t n, uint8_t voc) +{ + phy_update_bits(0x10, 0x00000200U, 0x00000200U); + phy_update_bits(0x10, 0x00000200U, 0); + phy_update_bits(0x10, 0x00000003U, 0x00000001U); + phy_update_bits(0x08, 0x07fe0000U, (n & 0x3ffU) << 17); + phy_update_bits(0x08, 0x78000000U, (m & 0x0fU) << 27); + phy_update_bits(0x10, 0x0001f800U, ((k_u32)voc & 0x3fU) << 11); + phy_update_bits(0x08, 0x0000007fU, 0x00000010U); + phy_update_bits(0x08, 0x00000300U, 0); + phy_update_bits(0x08, 0x0001f800U, 0); + phy_update_bits(0x10, 0x000001f8U, 0x00000040U); + + k230_dsi_write_phy_reg(0x14, 0x02); + k230_dsi_write_phy_reg(0x15, 0x60); + k230_dsi_write_phy_reg(0x16, 0x03); + k230_dsi_write_phy_reg(0x1d, 0x01); + + phy_update_bits(0x10, 0x00000400U, 0x00000400U); + rt_thread_mdelay(1); + phy_update_bits(0x10, 0x00000400U, 0); +} + +void k230_dsi_phy0_config(uint32_t m, uint32_t n, uint8_t voc, uint8_t hs_freq) +{ + uintptr_t base = phy_base_addr(); + + if (base != 0U) { + DSI_FENCE_WO(); + raw_writel(0, (void *)(base + 0x04)); + } + + dsi_write(0x0c, DSI_REG_PHY_RSTZ); + dsi_write(1, DSI_REG_PHY_TST_CTRL0); + dsi_write(0, DSI_REG_PHY_TST_CTRL0); + + k230_dsi_write_phy_reg(0x0c, 0x03); + k230_dsi_write_phy_reg(0x44, hs_freq); + k230_dsi_write_phy_reg(0xa0, 0x40); + k230_dsi_write_phy_reg(0xa4, 0x11); + k230_dsi_write_phy_reg(0xa4, 0x85); + k230_dsi_write_phy_reg(0xa3, 0x01); + k230_dsi_write_phy_reg(0x1f, 0x01); + k230_dsi_write_phy_reg(0x4a, 0x40); + + phy_update_bits(0x00, 0x00003f3cU, 0x000028a0U); + k230_dsi_phy_pll_config(m, n, voc); + + if (base != 0U) { + DSI_FENCE_WO(); + raw_writel(0x28a0U, (void *)base); + } + + dsi_write(0x0c, DSI_REG_PHY_RSTZ); +} + +void k230_dsi_phy1_config(uint8_t hs_freq) +{ + uintptr_t base = phy_base_addr(); + int retry = 10; + + if (base != 0U) { + DSI_FENCE_WO(); + raw_writel(0x00400000U, (void *)(base + 0x04)); + } + + dsi_write(1, DSI_REG_PHY_TST_CTRL0); + rt_thread_mdelay(1); + dsi_write(0, DSI_REG_PHY_TST_CTRL0); + k230_dsi_write_phy_reg(0x0c, 0); + k230_dsi_write_phy_reg(0x44, hs_freq); + k230_dsi_write_phy_reg(0x30, 0xff); + k230_dsi_write_phy_reg(0xa0, 0x40); + k230_dsi_write_phy_reg(0xa4, 0x11); + k230_dsi_write_phy_reg(0xa4, 0x85); + k230_dsi_write_phy_reg(0xa3, 0x01); + k230_dsi_write_phy_reg(0x1f, 0x01); + k230_dsi_write_phy_reg(0x4a, 0x40); + + if (base != 0U) { + k_u32 value = raw_readl((void *)base); + + DSI_FENCE_IR(); + value &= ~0x000000fcU; + value |= 0x000000a0U; + value &= ~0x00003f00U; + value |= 0x00002800U; + DSI_FENCE_WO(); + raw_writel(value, (void *)base); + } + + dsi_write(4, DSI_REG_PHY_RSTZ); + dsi_write(0x0d, DSI_REG_PHY_RSTZ); + dsi_write(0x0f, DSI_REG_PHY_RSTZ); + k230_dsi_write_phy_reg(0x03, 0x80); + + do { + if (dsi_read(DSI_REG_PHY_TST_CTRL1) == 0x580U) { + return; + } + k230_dsi_write_phy_reg(0x03, 0x80); + rt_thread_mdelay(1); + } while (--retry > 0); + + K_LOG(7, KD_DSI_MODULE_ID, "%s: test interface ready status 0x%x\n", + __func__, dsi_read(DSI_REG_PHY_TST_CTRL1)); +} + +static k_u32 dsi_phy_stopstate_mask(k_u32 lane_num) +{ + k_u32 mask = 0x0dU; + + for (k_u32 i = 0; i < lane_num; i++) { + if (i == 0U) { + mask |= 0x30U; + } else if (i == 1U) { + mask |= 0x180U; + } else if (i == 2U) { + mask |= 0x600U; + } else if (i == 3U) { + mask |= 0x1800U; + } + } + + return mask; +} + +static void dsi_wait_phy_status(k_u32 mask, const char *stage) +{ + k_u32 status = 0; + + for (k_u32 timeout = 50000U; timeout != 0U; timeout -= DSI_WAIT_US) { + status = dsi_read(DSI_REG_PHY_STATUS); + if ((status & mask) == mask) { + return; + } + rt_hw_us_delay(DSI_WAIT_US); + } + + K_LOG(3, KD_DSI_MODULE_ID, "%s: %s timeout, status 0x%x mask 0x%x\n", + __func__, stage, status, mask); +} + +void k230_dsi_phy_config(k_u32 lane_sel, k_u32 m, k_u32 n, k_u8 voc, + k_u8 hs_freq) +{ + uintptr_t base = phy_base_addr(); + k_u32 mask = dsi_phy_stopstate_mask(lane_sel); + + k230_dsi_phy0_config(m, n, voc, hs_freq); + k230_dsi_phy1_config(hs_freq); + + if (base != 0U) { + DSI_FENCE_WO(); + raw_writel(0, (void *)(base + 0x04)); + } + + dsi_write(0x0d, DSI_REG_PHY_RSTZ); + dsi_write(0x0f, DSI_REG_PHY_RSTZ); + dsi_wait_phy_status(mask, "stop-state"); + rt_thread_mdelay(1); + + if (base != 0U) { + DSI_FENCE_WO(); + raw_writel(0x00400000U, (void *)(base + 0x04)); + } + + dsi_wait_phy_status(mask, "external stop-state"); +} + +int dwc_dsi_send_packet(k_u8 type, k_u8 channel, const void *payload, + uint32_t payload_len, uint8_t read) +{ + const uint8_t *bytes = (const uint8_t *)payload; + k_u32 header; + + if (payload_len != 0U && bytes == NULL) { + return -1; + } + + dsi_message_config(channel, 1, read); + if (wait_status_clear(0x2U) != 0) { + return -1; + } + + if (packet_format_is_long(type)) { + if (write_payload(bytes, payload_len) != 0) { + return -1; + } + header = ((k_u32)type | (((k_u32)channel & 0x3U) << 6)) | + (payload_len << 8); + } else { + k_u32 data0 = payload_len > 0U ? bytes[0] : 0U; + k_u32 data1 = payload_len > 1U ? bytes[1] : 0U; + + header = ((k_u32)type | (((k_u32)channel & 0x3U) << 6)) | + (data0 << 8) | (data1 << 16); + } + + dsi_write(header, DSI_REG_GEN_HDR); + + if (wait_status_set(0x5U) != 0) { + dsi_dump_packet_error(type, header, dsi_read(DSI_REG_CMD_PKT_STATUS)); + return -1; + } + + return 0; +} + +int dwc_dsi_dcs_write(const void *data, uint32_t len, uint8_t channel) +{ + return dwc_dsi_send_packet(dcs_packet_type(len), channel, data, len, 0); +} + +int dwc_dsi_dcs_read(uint8_t cmd, void *data, uint32_t len, uint8_t channel) +{ + int ret; + + if (len != 0U && data == NULL) { + return -1; + } + + ret = dwc_dsi_send_packet(DSI_PACKET_DCS_READ, channel, &cmd, 1, 1); + if (ret != 0) { + return ret; + } + if (wait_status_clear(0x20U) != 0) { + return -1; + } + + return read_payload((uint8_t *)data, len); +} + +int dwc_dsi_generic_write(const void *data, uint32_t len, uint8_t channel) +{ + uint8_t type; + + if (len == 0U) { + type = DSI_PACKET_GEN_SHORT_WRITE0; + } else if (len == 1U) { + type = DSI_PACKET_GEN_SHORT_WRITE1; + } else if (len == 2U) { + type = DSI_PACKET_GEN_SHORT_WRITE2; + } else { + type = DSI_PACKET_GEN_LONG_WRITE; + } + + return dwc_dsi_send_packet(type, channel, data, len, 0); +} + +int dwc_dsi_generic_read(const void *params, uint32_t params_len, void *data, + uint32_t len, uint8_t channel) +{ + uint8_t type; + int ret; + + if ((params_len != 0U && params == NULL) || (len != 0U && data == NULL)) { + return -1; + } + + if (params_len == 0U) { + type = DSI_PACKET_GEN_READ0; + } else if (params_len == 1U) { + type = DSI_PACKET_GEN_READ1; + } else { + type = DSI_PACKET_GEN_READ2; + } + + ret = dwc_dsi_send_packet(type, channel, params, params_len, 1); + if (ret != 0) { + return ret; + } + if (wait_status_clear(0x20U) != 0) { + return -1; + } + + return read_payload((uint8_t *)data, len); +} + +void dwc_dsi_dump_config(const k_vo_dsi_config *config) +{ + if (config == NULL) { + rt_kprintf("dwc dsi config is null\n"); + return; + } + + rt_kprintf("dwc dsi config:\n"); + rt_kprintf(" lane_num %u\n", config->lanes); + rt_kprintf(" cmd_mode %u\n", config->cmd_mode); + rt_kprintf(" video_mode %u\n", config->video_mode); + rt_kprintf(" pclk %u phyclk %u n %u m %u voc %u hs_freq %u\n", + config->timing->pclk_khz * 1000, config->phy.datarate / 2, + config->phy.n, config->phy.m, config->phy.voc, + config->phy.hs_freq); +} + +static k_u32 dsi_get_minimum_lbcc(k_u32 lane_count) +{ + if (lane_count == 0U || lane_count > 4U) { + return minimum_lbccs[0]; + } + + return minimum_lbccs[lane_count - 1U]; +} + +static k_u32 dsi_get_hcomponent_lbcc(const k_vo_dsi_config *config, + k_u32 component) +{ + uint64_t lbcc; + uint64_t rem; + k_u32 lane_count = dsi_lane_count(config->lanes); + k_u32 minimum; + + if (config->video_mode == K_BURST_MODE) { + lbcc = ((uint64_t)component * (uint64_t)(config->phy.datarate / 1000U)) >> 3; + } else { + lbcc = ((uint64_t)component * (uint64_t)config->timing->pclk_khz * + DSI_DPI_BYTES_PER_PIXEL) / + (uint64_t)(lane_count * 8U); + } + + rem = lbcc % (uint64_t)config->timing->pclk_khz; + lbcc = lbcc / (uint64_t)config->timing->pclk_khz; + if (rem != 0U) { + lbcc++; + } + + minimum = dsi_get_minimum_lbcc(lane_count); + if (lbcc < minimum) { + lbcc = minimum; + } + + return (k_u32)lbcc; +} + +static int dsi_get_phy_timings(k_u32 lane_mbps, struct dsi_dphy_timing *timing) +{ + k_u32 best_delta = 0xffffffffU; + int best = -1; + + for (k_u32 i = 0; i < sizeof(dphy_timings) / sizeof(dphy_timings[0]); i++) { + k_u32 table_mbps = dphy_timings[i].lane_mbps; + k_u32 delta = table_mbps > lane_mbps ? table_mbps - lane_mbps : + lane_mbps - table_mbps; + + if (delta < best_delta) { + best_delta = delta; + best = (int)i; + } + } + + if (best < 0) { + return -1; + } + + *timing = dphy_timings[best]; + return 0; +} + +static void dsi_wait_phy_bit(k_u32 bit, const char *stage) +{ + k_u32 status = 0; + + for (k_u32 timeout = 10000U; timeout != 0U; timeout -= DSI_WAIT_US) { + status = dsi_read(DSI_REG_PHY_STATUS); + if ((status & bit) != 0U) { + return; + } + rt_hw_us_delay(DSI_WAIT_US); + } + + K_LOG(3, KD_DSI_MODULE_ID, "%s: %s timeout, status 0x%x\n", + __func__, stage, status); +} + +void dwc_dsi_init(k_vo_dsi_config *config) +{ + struct kd_dsi_resolution res; + struct dsi_dphy_timing phy_timing; + k_u32 lane_num; + k_u32 lane_mbps; + k_u32 byte_clk; + k_u32 lane_byte_mbps; + k_u32 tx_escape_clk_division; + k_u32 timeout_clock_division; + k_u32 hline_pixels; + k_u32 hsa_lbcc; + k_u32 hbp_lbcc; + k_u32 hline_lbcc; + k_u32 phy_tmr_cfg; + k_u32 phy_tmr_lpclk_cfg; + + if (config == NULL || config->timing == NULL) { + K_LOG(3, KD_DSI_MODULE_ID, "%s: invalid dsi config\n", __func__); + return; + } + + rt_memset(&res, 0, sizeof(res)); + res.pclk = config->timing->pclk_khz * 1000; + res.phyclk = config->phy.datarate / 2; + res.hdisplay = config->timing->hactive; + res.hsync_len = config->timing->hsync_len; + res.hback_porch = config->timing->hback_porch; + res.hfront_porch = config->timing->hfront_porch; + res.htotal = res.hdisplay + res.hsync_len + res.hback_porch + res.hfront_porch; + res.vdisplay = config->timing->vactive; + res.vsync_len = config->timing->vsync_len; + res.vback_porch = config->timing->vback_porch; + res.vfront_porch = config->timing->vfront_porch; + res.vtotal = res.vdisplay + res.vsync_len + res.vback_porch + res.vfront_porch; + + lane_num = dsi_lane_count(config->lanes); + if (lane_num == 0U) { + K_LOG(3, KD_DSI_MODULE_ID, "%s: invalid lane config %u\n", + __func__, config->lanes); + return; + } + + lane_mbps = config->phy.datarate / 1000000U; + lane_byte_mbps = lane_mbps / 8U; + byte_clk = lane_byte_mbps; + if (byte_clk == 0U) { + byte_clk = 1U; + } + + tx_escape_clk_division = (lane_byte_mbps + (config->lp_speed_mhz == 0U ? 20U : config->lp_speed_mhz) - 1U) / + (config->lp_speed_mhz == 0U ? 20U : config->lp_speed_mhz); + if (tx_escape_clk_division == 0U) { + tx_escape_clk_division = 1U; + } + if (tx_escape_clk_division > 255U) { + tx_escape_clk_division = 255U; + } + + timeout_clock_division = (lane_byte_mbps + 1U - 1U) / 1U; + if (timeout_clock_division == 0U) { + timeout_clock_division = 1U; + } + if (timeout_clock_division > 255U) { + timeout_clock_division = 255U; + } + + if (tx_escape_clk_division < 1U || tx_escape_clk_division > 20U) { + K_LOG(4, KD_DSI_MODULE_ID, + "%s: unusual escape clock divider %u for lane_mbps=%u\n", + __func__, tx_escape_clk_division, lane_mbps); + } + + if (dsi_get_phy_timings(lane_mbps, &phy_timing) != 0) { + phy_timing.clk_lp2hs = 0x73U; + phy_timing.clk_hs2lp = 0x3aU; + phy_timing.data_lp2hs = 0xceU; + phy_timing.data_hs2lp = 0x23U; + K_LOG(4, KD_DSI_MODULE_ID, + "%s: using default dphy timings for lane_mbps=%u\n", + __func__, lane_mbps); + } + phy_timing.data_lp2hs += phy_timing.clk_lp2hs; + phy_tmr_cfg = (((k_u32)phy_timing.data_hs2lp & 0x3ffU) << 16) | + ((k_u32)phy_timing.data_lp2hs & 0x3ffU); + phy_tmr_lpclk_cfg = (((k_u32)phy_timing.clk_hs2lp & 0x3ffU) << 16) | + ((k_u32)phy_timing.clk_lp2hs & 0x3ffU); + + hline_pixels = res.hdisplay + res.hsync_len + res.hback_porch + res.hfront_porch; + hsa_lbcc = dsi_get_hcomponent_lbcc(config, res.hsync_len); + hbp_lbcc = dsi_get_hcomponent_lbcc(config, res.hback_porch); + hline_lbcc = dsi_get_hcomponent_lbcc(config, hline_pixels); + + curren_video_mode = config->video_mode; + + dsi_write(0, DSI_REG_PWR_UP); + dsi_write(((timeout_clock_division & 0xffU) << 8) | + (tx_escape_clk_division & 0xffU), + DSI_REG_CLKMGR_CFG); + dsi_write(config->vc_id & 0x3U, DSI_REG_DPI_VCID); + dsi_write((config->vc_id & 0x3U) | ((config->vc_id & 0x3U) << 8), + DSI_REG_GEN_VCID); + dsi_write(DSI_DPI_COLOR_RGB565, DSI_REG_DPI_COLOR_CODING); + dsi_write(0, DSI_REG_DPI_CFG_POL); + dsi_write(0x1cU, DSI_REG_PCKHDL_CFG); + dsi_video_mode_config(config->video_mode); + + dsi_write(res.hdisplay & 0x3fffU, DSI_REG_VID_PKT_SIZE); + dsi_write(0, DSI_REG_VID_NUM_CHUNKS); + dsi_write(0, DSI_REG_VID_NULL_SIZE); + + dsi_write(0x1388U, DSI_REG_TO_CNT_CFG); + dsi_write(0x0d00U, DSI_REG_BTA_TO_CNT); + dsi_write(0x1388U, DSI_REG_HS_RD_TO_CNT); + dsi_write(1, DSI_REG_MODE_CFG); + dsi_write(hsa_lbcc, DSI_REG_VID_HSA_TIME); + dsi_write(hbp_lbcc, DSI_REG_VID_HBP_TIME); + dsi_write(hline_lbcc, DSI_REG_VID_HLINE_TIME); + dsi_write(res.vsync_len, DSI_REG_VID_VSA_LINES); + dsi_write(res.vback_porch, DSI_REG_VID_VBP_LINES); + dsi_write(res.vfront_porch, DSI_REG_VID_VFP_LINES); + dsi_write(res.vdisplay, DSI_REG_VID_VACTIVE_LINES); + dsi_write(0, DSI_REG_PHY_RSTZ); + dsi_write(0, DSI_REG_PHY_TST_CTRL0); + dsi_write(1, DSI_REG_PHY_TST_CTRL0); + dsi_write(0, DSI_REG_PHY_TST_CTRL0); + dsi_write(phy_tmr_cfg, DSI_REG_PHY_TMR_CFG); + dsi_write(0x2710U, DSI_REG_PHY_TMR_RD_CFG); + dsi_write(phy_tmr_lpclk_cfg, DSI_REG_PHY_TMR_LPCLK_CFG); + dsi_write(0x2800U | ((lane_num - 1U) & 0x3U), DSI_REG_PHY_IF_CFG); + dsi_read(DSI_REG_INT_ST0); + dsi_read(DSI_REG_INT_ST1); + dsi_write(0xffffffffU, DSI_REG_INT_MSK0); + dsi_write(0xffffffffU, DSI_REG_INT_MSK1); + + k230_dsi_phy_config((k_u32)config->lanes, config->phy.m, config->phy.n, + (uint8_t)config->phy.voc, + (uint8_t)config->phy.hs_freq); + + dsi_write(0x0f, DSI_REG_PHY_RSTZ); + + dsi_wait_phy_bit(0x1U, "phy lock"); + dsi_wait_phy_bit(0x4U, "clk lane stop-state"); + + wait_for_two_frames(&res); + dsi_set_mode(0, 0); +} + +int dwc_dsi_enable(void) +{ + dsi_set_mode(1, curren_video_mode); + return 0; +} + +int dwc_dsi_disable(void) +{ + dsi_set_mode(0, 0); + dsi_write(0, DSI_REG_PWR_UP); + dsi_write(0, DSI_REG_PHY_RSTZ); + return 0; +} diff --git a/bsp/k230/drivers/display/vo/kd_dsi_reg.h b/bsp/k230/drivers/display/vo/kd_dsi_reg.h new file mode 100644 index 00000000000..485de2f2944 --- /dev/null +++ b/bsp/k230/drivers/display/vo/kd_dsi_reg.h @@ -0,0 +1,39 @@ +#ifndef VO_KD_DSI_REG_H +#define VO_KD_DSI_REG_H + +#include "k_vo_comm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void k230_dsi_write_phy_reg(k_u8 addr, k_u8 value); +void k230_dsi_phy_pll_config(k_u32 m, k_u32 n, k_u8 voc); +void k230_dsi_phy0_config(k_u32 m, k_u32 n, k_u8 voc, k_u8 hs_freq); +void k230_dsi_phy1_config(k_u8 hs_freq); +void k230_dsi_phy_config(k_u32 lane_num, k_u32 m, k_u32 n, k_u8 voc, + k_u8 hs_freq); + +int dwc_dsi_send_packet(k_u8 type, k_u8 channel, const void *payload, + k_u32 payload_len, k_u8 read); +int dwc_dsi_dcs_write(const void *data, k_u32 len, k_u8 channel); +int dwc_dsi_dcs_read(k_u8 cmd, void *data, k_u32 len, k_u8 channel); +int dwc_dsi_generic_write(const void *data, k_u32 len, k_u8 channel); +int dwc_dsi_generic_read(const void *params, k_u32 params_len, void *data, + k_u32 len, k_u8 channel); + +void dwc_dsi_init(k_vo_dsi_config *config); +int dwc_dsi_enable(void); +int dwc_dsi_disable(void); +void dwc_dsi_dump_config(const k_vo_dsi_config *config); +void dwc_dsi_debug_dump(void); +void dwc_dsi_set_dpi_color_coding(k_u32 coding); +void dwc_dsi_set_video_scan(k_u32 dpi_color, k_u32 pkt_size, + k_u32 hsa, k_u32 hbp, k_u32 hline, + k_u32 video_mode); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/k230/drivers/display/vo/kd_vo_reg.c b/bsp/k230/drivers/display/vo/kd_vo_reg.c new file mode 100644 index 00000000000..f571b988b9b --- /dev/null +++ b/bsp/k230/drivers/display/vo/kd_vo_reg.c @@ -0,0 +1,601 @@ +#include "kd_vo_reg.h" +#include "vo_display_remap.h" + +#include + +#include +#include + +#define KD_VO_MODULE_ID 11 + +#define VO_REG_RESET 0x004 +#define VO_REG_ENABLE 0x004 +#define VO_REG_WRAP_CTRL0 0x008 +#define VO_REG_WRAP_CTRL1 0x00c +#define VO_REG_WRAP_CTRL2 0x010 +#define VO_REG_MIX_ORDER0 0x034 +#define VO_REG_MIX_ORDER1 0x038 +#define VO_REG_MIX_ORDER2 0x03c +#define VO_REG_MIX_ORDER3 0x040 +#define VO_REG_MIX_ORDER4 0x044 +#define VO_REG_MIX_ORDER5 0x048 +#define VO_REG_MIX_ORDER6 0x04c +#define VO_REG_MIX_ORDER7 0x050 +#define VO_REG_HSYNC 0x100 +#define VO_REG_HSYNC1 0x104 +#define VO_REG_VSYNC1 0x108 +#define VO_REG_HSYNC2 0x10c +#define VO_REG_VSYNC2 0x110 +#define VO_REG_LAYER_CFG_EXTRA 0x118 +#define VO_REG_ACTIVE_H 0x0c0 +#define VO_REG_ACTIVE_V 0x0c4 +#define VO_REG_TOTAL_SIZE 0x11c +#define VO_REG_BG_COLOR 0x3d0 +#define VO_REG_MIX_ENABLE 0x3c0 +#define VO_REG_MIX_ALPHA0 0x3c4 +#define VO_REG_MIX_ALPHA1 0x3c8 +#define VO_REG_MIX_PRIORITY0 0x3cc +#define VO_REG_MIX_PRIORITY1 0x950 +#define VO_REG_LAYER_ENABLE 0x380 +#define VO_REG_LOAD_CTL 0x004 +#define VO_REG_INTR_FRAME 0x3e0 +#define VO_REG_INTR_VTTH 0x3e4 +#define VO_REG_INTR_CLEAR0 0x3d4 +#define VO_REG_INTR_CLEAR1 0x3d8 +#define VO_REG_INTR_MASK0 0x3e8 +#define VO_REG_USER_SYNC 0x780 + +#define VO_MIX_ENABLE_SDK 0x000000ffU + +#define VO_OSD_COUNT 4U +#define VO_OSD_INFO 0x00 +#define VO_OSD_SIZE 0x04 +#define VO_OSD_VLU_ADDR0 0x08 +#define VO_OSD_ALP_ADDR0 0x0c +#define VO_OSD_VLU_ADDR1 0x10 +#define VO_OSD_ALP_ADDR1 0x14 +#define VO_OSD_DMA_CTRL 0x18 +#define VO_OSD_STRIDE 0x1c +#define VO_OSD_ADDR_SEL_MODE 0x20 + +#define VO_OSD_FORMAT_RGB565 0x02 + +struct vo_osd_plane { + k_u32 offset; + k_u32 enable_bit; + k_u32 xctl; + k_u32 yctl; +}; + +static const struct vo_osd_plane vo_osd_planes[VO_OSD_COUNT] = { + {0x280, 4, 0x0e8, 0x0ec}, + {0x2c0, 5, 0x0f0, 0x0f4}, + {0x300, 6, 0x0f8, 0x0fc}, + {0x850, 7, 0x820, 0x824}, +}; + +#define VO_SYS_RESET_OFFSET 0x090 +#define VO_PIXCLK_REG_OFFSET 0x078 +#define VO_TIMESTAMP_CTRL_OFFSET 0x000 +#define VO_TIMESTAMP_TIME_HI 0x070 +#define VO_TIMESTAMP_TIME_LO 0x074 +#define VO_TIMESTAMP_PTP_HI 0x078 +#define VO_TIMESTAMP_PTP_LO 0x07c + +#if defined(__riscv) +#define VO_FENCE_WO() __asm__ volatile("fence w,o" ::: "memory") +#define VO_FENCE_IR() __asm__ volatile("fence i,r" ::: "memory") +#else +#define VO_FENCE_WO() __asm__ volatile("" ::: "memory") +#define VO_FENCE_IR() __asm__ volatile("" ::: "memory") +#endif + +extern void K_LOG(int level, int module, const char *fmt, ...); +extern void dwc_dsi_disable(void); + +static inline void __raw_writel(k_u32 value, volatile void *addr) +{ + *(volatile k_u32 *)addr = value; +} + +static inline k_u32 __raw_readl(const volatile void *addr) +{ + return *(const volatile k_u32 *)addr; +} + +static inline uintptr_t vo_base_addr(void) +{ + if (display_remap == RT_NULL || display_remap->vo_base == RT_NULL) + { + (void)vo_display_remap_init(); + } + return (uintptr_t)display_remap->vo_base; +} + +static inline uintptr_t clock_base_addr(void) +{ + if (display_remap == RT_NULL || display_remap->clock_base == RT_NULL) + { + (void)vo_display_remap_init(); + } + return (uintptr_t)display_remap->clock_base; +} + +static inline uintptr_t sysctl_base_addr(void) +{ + if (display_remap == RT_NULL || display_remap->sysctl_base == RT_NULL) + { + (void)vo_display_remap_init(); + } + return (uintptr_t)display_remap->sysctl_base; +} + +static inline uintptr_t timestamp_base_addr(void) +{ + if (display_remap == RT_NULL || display_remap->timestamp_base == RT_NULL) + { + (void)vo_display_remap_init(); + } + return (uintptr_t)display_remap->timestamp_base; +} + +static void vo_write(k_u32 value, k_u32 offset) +{ + K_LOG(7, KD_VO_MODULE_ID, + "[Func]:%s [Line]:%d [Info]:VO write: offset 0x%x, val 0x%x\n", + __func__, 61, offset, value); + VO_FENCE_WO(); + __raw_writel(value, (void *)(vo_base_addr() + offset)); +} + +static k_u32 vo_read(k_u32 offset) +{ + k_u32 value; + + value = __raw_readl((void *)(vo_base_addr() + offset)); + VO_FENCE_IR(); + + return value; +} + +void kd_vo_set_pixclk(k_u32 div) +{ + uintptr_t addr = clock_base_addr() + VO_PIXCLK_REG_OFFSET; + k_u32 val; + + val = __raw_readl((void *)addr); + VO_FENCE_IR(); + val &= ~0x7f8U; + val |= div << 3; + val |= 0x80000000U; + VO_FENCE_WO(); + __raw_writel(val, (void *)addr); +} + +void kd_vo_wrap_init(void) +{ + unsigned int i; + + vo_write(0x00000011U, VO_REG_WRAP_CTRL0); + vo_write(0x00000088U, VO_REG_WRAP_CTRL1); + vo_write(0x00000000U, VO_REG_WRAP_CTRL2); + + for (i = 0; i <= 7; ++i) { + vo_write(0x01010101U, (i + 5U) * 4U); + } + + vo_write(0x76543210U, VO_REG_MIX_ORDER0); + vo_write(0x76543210U, VO_REG_MIX_ORDER2); + vo_write(0x76543210U, VO_REG_MIX_ORDER4); + vo_write(0x76543210U, VO_REG_MIX_ORDER6); + vo_write(0xfedcba98U, VO_REG_MIX_ORDER1); + vo_write(0xfedcba98U, VO_REG_MIX_ORDER3); + vo_write(0xfedcba98U, VO_REG_MIX_ORDER5); + vo_write(0xfedcba98U, VO_REG_MIX_ORDER7); + + for (i = 0; i <= 9; ++i) { + vo_write(0x00000701U, (i + 32U) * 4U); + } + + vo_write(0x00000701U, 0x800U); + vo_write(0x00000701U, 0x804U); + vo_write(0x00000701U, 0x808U); + vo_write(0x00000701U, 0x80cU); + vo_write(0x00000701U, 0x810U); + vo_write(0x00000000U, VO_REG_LAYER_CFG_EXTRA); +} + +static void kd_vo_software_reset(void) +{ + vo_write(0x0000000fU, VO_REG_RESET); + vo_write(0x00000000U, VO_REG_WRAP_CTRL0); + vo_write(0x00000000U, VO_REG_ENABLE); +} + +void kd_vo_reset(void) +{ + uintptr_t reset_addr; + + (void)vo_display_remap_init(); + reset_addr = sysctl_base_addr() + VO_SYS_RESET_OFFSET; + + VO_FENCE_WO(); + __raw_writel(0, (void *)reset_addr); + rt_thread_mdelay(1); + + VO_FENCE_WO(); + __raw_writel(0xffffffffU, (void *)reset_addr); + rt_thread_mdelay(1); + + dwc_dsi_disable(); + kd_vo_software_reset(); + rt_thread_mdelay(3); +} + +void kd_vo_timestamp_enable(void) +{ + uintptr_t addr = timestamp_base_addr() + VO_TIMESTAMP_CTRL_OFFSET; + k_u32 val; + + val = __raw_readl((void *)addr); + VO_FENCE_IR(); + + if ((val & 0x1U) == 0) { + val &= ~0x18U; + val |= 0x8U; + val |= 0x1U; + VO_FENCE_WO(); + __raw_writel(val, (void *)addr); + } +} + +void k230_get_timestamp(k_u32 *ptp_time, k_u32 *time) +{ + uintptr_t base = timestamp_base_addr(); + k_u32 val; + + val = __raw_readl((void *)(base + VO_TIMESTAMP_TIME_HI)); + VO_FENCE_IR(); + time[1] = val; + + val = __raw_readl((void *)(base + VO_TIMESTAMP_TIME_LO)); + VO_FENCE_IR(); + time[0] = val; + + val = __raw_readl((void *)(base + VO_TIMESTAMP_PTP_HI)); + VO_FENCE_IR(); + ptp_time[1] = val; + + val = __raw_readl((void *)(base + VO_TIMESTAMP_PTP_LO)); + VO_FENCE_IR(); + ptp_time[0] = val; +} + +void kd_vo_enable(void) +{ + vo_write(0x00000011U, VO_REG_ENABLE); + kd_vo_timestamp_enable(); +} + +void kd_vo_set_config_mix(void) +{ + vo_write(0x0000007fU, VO_REG_MIX_ENABLE); + vo_write(0xffffffffU, VO_REG_MIX_ALPHA0); + vo_write(0xffffffffU, VO_REG_MIX_ALPHA1); + vo_write(0xffffffffU, 0x940U); + vo_write(0x00003210U, VO_REG_MIX_PRIORITY0); + vo_write(0xba987654U, VO_REG_MIX_PRIORITY1); + vo_write(0x00000001U, VO_REG_LAYER_ENABLE); + vo_write(0x00000000U, VO_REG_INTR_CLEAR1); + vo_write(0x00000001U, VO_REG_INTR_CLEAR0); + vo_write(0x11111111U, 0x340U); + vo_write(0x000000ffU, VO_REG_MIX_ENABLE); + vo_write(0x00000000U, VO_REG_INTR_FRAME); + vo_write(0x00000000U, VO_REG_INTR_VTTH); + vo_write(0x00000000U, VO_REG_INTR_MASK0); +} + +static void kd_vo_set_sync_pair(k_u32 low, k_u32 high, k_u32 offset) +{ + k_u32 val = (low & 0xffffU) | (high << 16); + + vo_write(val, offset); +} + +static void kd_vo_set_hsync(k_u32 low, k_u32 high) +{ + kd_vo_set_sync_pair(low, high, VO_REG_HSYNC); +} + +static void kd_vo_set_hsync1(k_u32 low, k_u32 high) +{ + kd_vo_set_sync_pair(low, high, VO_REG_HSYNC1); +} + +static void kd_vo_set_hsync2(k_u32 low, k_u32 high) +{ + kd_vo_set_sync_pair(low, high, VO_REG_HSYNC2); +} + +static void kd_vo_set_vsync1(k_u32 low, k_u32 high) +{ + kd_vo_set_sync_pair(low, high, VO_REG_VSYNC1); +} + +static void kd_vo_set_vsync2(k_u32 low, k_u32 high) +{ + kd_vo_set_sync_pair(low, high, VO_REG_VSYNC2); +} + +void kd_vo_set_background(k_u32 rgb888) +{ + k_u32 r = (rgb888 >> 16) & 0xffU; + k_u32 g = (rgb888 >> 8) & 0xffU; + k_u32 b = rgb888 & 0xffU; + k_u32 y; + k_u32 cb; + k_u32 cr; + k_u32 yuv; + + y = (66U * r + 129U * g + 25U * b + 128U) >> 8; + y += 16U; + cb = ((-38 * (int)r - 74 * (int)g + 112 * (int)b + 128) >> 8) + 128; + cr = ((112 * (int)r - 94 * (int)g - 18 * (int)b + 128) >> 8) + 128; + + yuv = ((cr & 0xffU) << 16) | ((cb & 0xffU) << 8) | (y & 0xffU); + vo_write(yuv, VO_REG_BG_COLOR); + vo_write(0x00000011U, VO_REG_LOAD_CTL); +} + +void kd_vo_set_background_yuv(k_u32 yuv) +{ + vo_write(yuv, VO_REG_BG_COLOR); + vo_write(0x00000011U, VO_REG_LOAD_CTL); +} + +void kd_vo_set_osd_rgb565_framebuffer(k_u32 osd, k_u64 paddr, k_u32 width, k_u32 height, k_u32 pitch) +{ + kd_vo_set_osd_rgb565_framebuffer_ex(osd, paddr, paddr, width, height, pitch, + 0x0000007fU, 0x00000100U); +} + +void kd_vo_set_osd_rgb565_framebuffer_ex(k_u32 osd, k_u64 paddr, k_u64 alpha_paddr, + k_u32 width, k_u32 height, k_u32 pitch, + k_u32 dma_ctrl, k_u32 addr_sel) +{ + k_u32 stride; + + if (pitch == 0) + return; + + /* + * The K230 SDK passes OSD stride in 64-bit words. For RGB565 this is + * width * 2 / 8, which is equivalent to pitch / 8. + */ + stride = pitch / 8U; + kd_vo_set_osd_rgb565_framebuffer_raw(osd, paddr, alpha_paddr, width, height, + stride, dma_ctrl, addr_sel); +} + +void kd_vo_set_osd_rgb565_framebuffer_raw(k_u32 osd, k_u64 paddr, k_u64 alpha_paddr, + k_u32 width, k_u32 height, k_u32 stride_reg, + k_u32 dma_ctrl, k_u32 addr_sel) +{ + kd_vo_set_osd_rgb565_framebuffer_format_raw(osd, paddr, alpha_paddr, + width, height, stride_reg, + VO_OSD_FORMAT_RGB565, + dma_ctrl, addr_sel); +} + +void kd_vo_set_osd_rgb565_framebuffer_format_raw(k_u32 osd, k_u64 paddr, k_u64 alpha_paddr, + k_u32 width, k_u32 height, k_u32 stride_reg, + k_u32 info, k_u32 dma_ctrl, k_u32 addr_sel) +{ + k_u32 base; + const struct vo_osd_plane *plane; + k_u32 start_x; + k_u32 start_y; + k_u32 value; + + if (osd >= VO_OSD_COUNT || paddr == 0 || width == 0 || height == 0) + return; + + plane = &vo_osd_planes[osd]; + base = (k_u32)paddr; + (void)alpha_paddr; + + vo_write(info, plane->offset + VO_OSD_INFO); + vo_write(width | (height << 16), plane->offset + VO_OSD_SIZE); + + start_x = vo_read(VO_REG_ACTIVE_H) & 0x1fffU; + start_y = vo_read(VO_REG_ACTIVE_V) & 0x1fffU; + vo_write(((start_x + width - 1U) << 16) | start_x, plane->xctl); + vo_write(((start_y + height - 1U) << 16) | start_y, plane->yctl); + + vo_write(base, plane->offset + VO_OSD_VLU_ADDR0); + vo_write(base, plane->offset + VO_OSD_VLU_ADDR1); + vo_write(base, plane->offset + VO_OSD_ALP_ADDR0); + vo_write(base, plane->offset + VO_OSD_ALP_ADDR1); + vo_write(stride_reg, plane->offset + VO_OSD_STRIDE); + vo_write(dma_ctrl, plane->offset + VO_OSD_DMA_CTRL); + vo_write(addr_sel, plane->offset + VO_OSD_ADDR_SEL_MODE); + + value = vo_read(VO_REG_LAYER_CFG_EXTRA); + value |= 1U << plane->enable_bit; + vo_write(value, VO_REG_LAYER_CFG_EXTRA); + + value = vo_read(VO_REG_MIX_ENABLE); + value |= 1U << plane->enable_bit; + vo_write(value, VO_REG_MIX_ENABLE); + + vo_write(0x00000011U, VO_REG_LOAD_CTL); +} + +void kd_vo_disable_osd_all(void) +{ + k_u32 layer_enable; + + layer_enable = vo_read(VO_REG_LAYER_CFG_EXTRA); + + for (k_u32 i = 0; i < VO_OSD_COUNT; i++) { + layer_enable &= ~(1U << vo_osd_planes[i].enable_bit); + } + + vo_write(layer_enable, VO_REG_LAYER_CFG_EXTRA); + vo_write(0x00000000U, VO_REG_MIX_ENABLE); + vo_write(0x00000011U, VO_REG_LOAD_CTL); +} + +void kd_vo_select_osd(k_u32 osd) +{ + k_u32 layer_enable; + k_u32 mix_enable; + + if (osd >= VO_OSD_COUNT) + return; + + layer_enable = vo_read(VO_REG_LAYER_CFG_EXTRA); + mix_enable = vo_read(VO_REG_MIX_ENABLE); + + for (k_u32 i = 0; i < VO_OSD_COUNT; i++) { + layer_enable &= ~(1U << vo_osd_planes[i].enable_bit); + } + + layer_enable |= 1U << vo_osd_planes[osd].enable_bit; + mix_enable |= VO_MIX_ENABLE_SDK; + + vo_write(layer_enable, VO_REG_LAYER_CFG_EXTRA); + vo_write(mix_enable, VO_REG_MIX_ENABLE); + vo_write(0x00000011U, VO_REG_LOAD_CTL); +} + +void kd_vo_commit(void) +{ + vo_write(0x00000011U, VO_REG_LOAD_CTL); +} + +void kd_vo_poke(k_u32 offset, k_u32 value) +{ + vo_write(value, offset); +} + +void kd_vo_debug_dump(void) +{ + (void)vo_display_remap_init(); + + rt_kprintf("VO base=%p\n", display_remap ? display_remap->vo_base : RT_NULL); + rt_kprintf("VO load/enable=0x%08x dma_sw=0x%08x active_h=0x%08x active_v=0x%08x total=0x%08x\n", + vo_read(VO_REG_LOAD_CTL), vo_read(VO_REG_WRAP_CTRL0), + vo_read(VO_REG_ACTIVE_H), vo_read(VO_REG_ACTIVE_V), vo_read(VO_REG_TOTAL_SIZE)); + rt_kprintf("VO layer_en=0x%08x mix_en=0x%08x mix_alpha0=0x%08x mix_alpha1=0x%08x bg=0x%08x\n", + vo_read(VO_REG_LAYER_CFG_EXTRA), vo_read(VO_REG_MIX_ENABLE), + vo_read(VO_REG_MIX_ALPHA0), vo_read(VO_REG_MIX_ALPHA1), vo_read(VO_REG_BG_COLOR)); + rt_kprintf("VO pri0=0x%08x pri1=0x%08x intr_frame=0x%08x intr_vtth=0x%08x intr_mask=0x%08x\n", + vo_read(VO_REG_MIX_PRIORITY0), vo_read(VO_REG_MIX_PRIORITY1), + vo_read(VO_REG_INTR_FRAME), vo_read(VO_REG_INTR_VTTH), vo_read(VO_REG_INTR_MASK0)); + + for (k_u32 i = 0; i < VO_OSD_COUNT; i++) { + const struct vo_osd_plane *plane = &vo_osd_planes[i]; + + rt_kprintf("OSD%u off=0x%03x bit=%u info=0x%08x size=0x%08x x=0x%08x y=0x%08x\n", + i, plane->offset, plane->enable_bit, + vo_read(plane->offset + VO_OSD_INFO), + vo_read(plane->offset + VO_OSD_SIZE), + vo_read(plane->xctl), vo_read(plane->yctl)); + rt_kprintf("OSD%u addr0=0x%08x alp0=0x%08x addr1=0x%08x alp1=0x%08x dma=0x%08x stride=0x%08x sel=0x%08x\n", + i, + vo_read(plane->offset + VO_OSD_VLU_ADDR0), + vo_read(plane->offset + VO_OSD_ALP_ADDR0), + vo_read(plane->offset + VO_OSD_VLU_ADDR1), + vo_read(plane->offset + VO_OSD_ALP_ADDR1), + vo_read(plane->offset + VO_OSD_DMA_CTRL), + vo_read(plane->offset + VO_OSD_STRIDE), + vo_read(plane->offset + VO_OSD_ADDR_SEL_MODE)); + } +} + +void kd_vo_debug_summary(void) +{ + (void)vo_display_remap_init(); + + rt_kprintf("VO_SUM load=0x%08x dma_sw=0x%08x layer_en=0x%08x mix_en=0x%08x alpha0=0x%08x alpha1=0x%08x bg=0x%08x\n", + vo_read(VO_REG_LOAD_CTL), vo_read(VO_REG_WRAP_CTRL0), + vo_read(VO_REG_LAYER_CFG_EXTRA), vo_read(VO_REG_MIX_ENABLE), + vo_read(VO_REG_MIX_ALPHA0), vo_read(VO_REG_MIX_ALPHA1), + vo_read(VO_REG_BG_COLOR)); + rt_kprintf("VO_SUM active_h=0x%08x active_v=0x%08x total=0x%08x pri0=0x%08x pri1=0x%08x intr=0x%08x\n", + vo_read(VO_REG_ACTIVE_H), vo_read(VO_REG_ACTIVE_V), + vo_read(VO_REG_TOTAL_SIZE), vo_read(VO_REG_MIX_PRIORITY0), + vo_read(VO_REG_MIX_PRIORITY1), vo_read(VO_REG_INTR_FRAME)); + + for (k_u32 i = 0; i < VO_OSD_COUNT; i++) { + const struct vo_osd_plane *plane = &vo_osd_planes[i]; + k_u32 info = vo_read(plane->offset + VO_OSD_INFO); + k_u32 size = vo_read(plane->offset + VO_OSD_SIZE); + k_u32 addr = vo_read(plane->offset + VO_OSD_VLU_ADDR0); + k_u32 stride = vo_read(plane->offset + VO_OSD_STRIDE); + k_u32 dma = vo_read(plane->offset + VO_OSD_DMA_CTRL); + k_u32 sel = vo_read(plane->offset + VO_OSD_ADDR_SEL_MODE); + + if (info || size || addr || (vo_read(VO_REG_LAYER_CFG_EXTRA) & (1U << plane->enable_bit))) { + rt_kprintf("VO_SUM OSD%u bit=%u off=0x%03x info=0x%08x size=0x%08x addr=0x%08x alp=0x%08x stride=0x%08x dma=0x%08x sel=0x%08x x=0x%08x y=0x%08x\n", + i, plane->enable_bit, plane->offset, info, size, addr, + vo_read(plane->offset + VO_OSD_ALP_ADDR0), stride, dma, + sel, vo_read(plane->xctl), vo_read(plane->yctl)); + } + } +} + +void kd_vo_set_timing(const k_vo_timing *timing) +{ + k_u32 hactive; + k_u32 hback_porch; + k_u32 htotal; + k_u32 vactive; + k_u32 vback_porch; + k_u32 vtotal; + k_u32 val; + + hback_porch = timing->hback_porch; + hactive = timing->hactive; + htotal = hactive + hback_porch + timing->hsync_len + timing->hfront_porch; + + vback_porch = timing->vback_porch; + vactive = timing->vactive; + vtotal = vactive + vback_porch + timing->vsync_len + timing->vfront_porch; + + kd_vo_set_hsync(2, 5); + kd_vo_set_hsync1(2, 5); + kd_vo_set_hsync2(2, 5); + kd_vo_set_vsync1(0, 0); + kd_vo_set_vsync2(0, 0); + + val = ((hactive + hback_porch - 1U) << 16) | hback_porch; + vo_write(val, VO_REG_ACTIVE_H); + + val = ((vactive + vback_porch - 1U) << 16) | vback_porch; + vo_write(val, VO_REG_ACTIVE_V); + + val = (vtotal << 16) | htotal; + vo_write(val, VO_REG_TOTAL_SIZE); + + val = ((vactive - 1U) << 16) | hactive; + val += 0x7fffU; + vo_write(val, VO_REG_USER_SYNC); + +} + +void kd_vo_set_vtth_intr(k_u32 status, k_u32 line) +{ + (void)status; + (void)line; + vo_write(0x00000000U, VO_REG_INTR_VTTH); +} + +void kd_vo_set_frame_intr(k_bool status) +{ + k_u32 val = ((k_u32)status) << 20; + + vo_write(val, VO_REG_INTR_FRAME); + kd_vo_set_vtth_intr(0, 0); +} diff --git a/bsp/k230/drivers/display/vo/kd_vo_reg.h b/bsp/k230/drivers/display/vo/kd_vo_reg.h new file mode 100644 index 00000000000..0cbfbd7f680 --- /dev/null +++ b/bsp/k230/drivers/display/vo/kd_vo_reg.h @@ -0,0 +1,43 @@ +#ifndef VO_KD_VO_REG_H +#define VO_KD_VO_REG_H + +#include "k_vo_comm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void kd_vo_reset(void); +void kd_vo_wrap_init(void); +void kd_vo_set_config_mix(void); +void kd_vo_set_frame_intr(k_bool status); +void kd_vo_set_vtth_intr(k_u32 status, k_u32 line); +void kd_vo_set_pixclk(k_u32 div); +void kd_vo_set_timing(const k_vo_timing *timing); +void kd_vo_set_background(k_u32 rgb888); +void kd_vo_set_background_yuv(k_u32 yuv); +void kd_vo_set_osd_rgb565_framebuffer(k_u32 osd, k_u64 paddr, k_u32 width, k_u32 height, k_u32 pitch); +void kd_vo_set_osd_rgb565_framebuffer_ex(k_u32 osd, k_u64 paddr, k_u64 alpha_paddr, + k_u32 width, k_u32 height, k_u32 pitch, + k_u32 dma_ctrl, k_u32 addr_sel); +void kd_vo_set_osd_rgb565_framebuffer_raw(k_u32 osd, k_u64 paddr, k_u64 alpha_paddr, + k_u32 width, k_u32 height, k_u32 stride_reg, + k_u32 dma_ctrl, k_u32 addr_sel); +void kd_vo_set_osd_rgb565_framebuffer_format_raw(k_u32 osd, k_u64 paddr, k_u64 alpha_paddr, + k_u32 width, k_u32 height, k_u32 stride_reg, + k_u32 info, k_u32 dma_ctrl, k_u32 addr_sel); +void kd_vo_select_osd(k_u32 osd); +void kd_vo_disable_osd_all(void); +void kd_vo_commit(void); +void kd_vo_poke(k_u32 offset, k_u32 value); +void kd_vo_enable(void); +void kd_vo_timestamp_enable(void); +void k230_get_timestamp(k_u32 *ptp_time, k_u32 *time); +void kd_vo_debug_dump(void); +void kd_vo_debug_summary(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/k230/drivers/display/vo/vo_display_remap.h b/bsp/k230/drivers/display/vo/vo_display_remap.h new file mode 100644 index 00000000000..a3e06495e58 --- /dev/null +++ b/bsp/k230/drivers/display/vo/vo_display_remap.h @@ -0,0 +1,26 @@ +#ifndef VO_DISPLAY_REMAP_H +#define VO_DISPLAY_REMAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct vo_display_remap { + void *vo_base; + void *dsi_base; + void *sysctl_base; + void *phy_base; + void *clock_base; + void *timestamp_base; +}; + +extern struct vo_display_remap *display_remap; + +int vo_display_remap_init(void); +void vo_display_remap_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/k230/drivers/display/vo/vo_remap.c b/bsp/k230/drivers/display/vo/vo_remap.c new file mode 100644 index 00000000000..4bc5cb74d3f --- /dev/null +++ b/bsp/k230/drivers/display/vo/vo_remap.c @@ -0,0 +1,77 @@ +#include "vo_display_remap.h" + +#include + +#include "board.h" +#include "ioremap.h" + +#include + +#define DSI_PHY_REG_BASE_PHYS (DSI_BASE_ADDR + 0x400UL) +#define DSI_PHY_REG_SIZE (DSI_IO_SIZE - 0x400UL) + +struct vo_display_remap *display_remap; + +static struct vo_display_remap g_display_remap; +static int g_remap_ready; + +static void unmap_if_present(void **addr) +{ + if (addr != RT_NULL && *addr != RT_NULL) + { + rt_iounmap(*addr); + *addr = RT_NULL; + } +} + +void vo_display_remap_deinit(void) +{ + if (!g_remap_ready) + { + return; + } + + unmap_if_present(&g_display_remap.timestamp_base); + unmap_if_present(&g_display_remap.clock_base); + unmap_if_present(&g_display_remap.phy_base); + unmap_if_present(&g_display_remap.sysctl_base); + unmap_if_present(&g_display_remap.dsi_base); + unmap_if_present(&g_display_remap.vo_base); + + memset(&g_display_remap, 0, sizeof(g_display_remap)); + display_remap = RT_NULL; + g_remap_ready = 0; +} + +int vo_display_remap_init(void) +{ + if (g_remap_ready) + { + return 0; + } + + memset(&g_display_remap, 0, sizeof(g_display_remap)); + + g_display_remap.vo_base = rt_ioremap_nocache((void *)VO_BASE_ADDR, VO_IO_SIZE); + g_display_remap.dsi_base = rt_ioremap_nocache((void *)DSI_BASE_ADDR, DSI_IO_SIZE); + g_display_remap.sysctl_base = rt_ioremap((void *)RMU_BASE_ADDR, RMU_IO_SIZE); + g_display_remap.phy_base = rt_ioremap_nocache((void *)DSI_PHY_REG_BASE_PHYS, DSI_PHY_REG_SIZE); + g_display_remap.clock_base = rt_ioremap((void *)CMU_BASE_ADDR, CMU_IO_SIZE); + g_display_remap.timestamp_base = rt_ioremap((void *)STC_BASE_ADDR, STC_IO_SIZE); + + if (g_display_remap.vo_base == RT_NULL || + g_display_remap.dsi_base == RT_NULL || + g_display_remap.sysctl_base == RT_NULL || + g_display_remap.phy_base == RT_NULL || + g_display_remap.clock_base == RT_NULL || + g_display_remap.timestamp_base == RT_NULL) + { + rt_kprintf("vo_remap: failed to map display registers\n"); + vo_display_remap_deinit(); + return -1; + } + + display_remap = &g_display_remap; + g_remap_ready = 1; + return 0; +} diff --git a/bsp/k230/drivers/interdrv/gpio/drv_gpio.c b/bsp/k230/drivers/interdrv/gpio/drv_gpio.c index 2185418aea0..9d0f0aeee77 100644 --- a/bsp/k230/drivers/interdrv/gpio/drv_gpio.c +++ b/bsp/k230/drivers/interdrv/gpio/drv_gpio.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include "ioremap.h" @@ -52,7 +53,6 @@ #define DBG_COLOR struct kd_gpio_device { - struct rt_device dev; void* base[2]; int hardlock; }; @@ -92,7 +92,7 @@ static rt_uint32_t kd_gpio_reg_readl(void* reg, rt_size_t offset) static int check_pin_valid(rt_base_t pin) { - if ((rt_uint16_t)pin < 0 || (rt_uint16_t)pin > GPIO_MAX_NUM) + if (pin < 0 || pin >= GPIO_MAX_NUM) { LOG_E("pin %d is not valid\n", pin); return -RT_EINVAL; @@ -379,6 +379,75 @@ rt_err_t kd_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled) return RT_EOK; } +static void k230_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) +{ + (void)device; + + switch (mode) + { + case PIN_MODE_OUTPUT: + case PIN_MODE_OUTPUT_OD: + (void)kd_pin_mode(pin, GPIO_DM_OUTPUT); + break; + case PIN_MODE_INPUT: + case PIN_MODE_INPUT_PULLUP: + case PIN_MODE_INPUT_PULLDOWN: + (void)kd_pin_mode(pin, GPIO_DM_INPUT); + break; + default: + LOG_E("pin mode %u is not supported", mode); + break; + } +} + +static void k230_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value) +{ + (void)device; + + (void)kd_pin_write(pin, value ? GPIO_PV_HIGH : GPIO_PV_LOW); +} + +static rt_ssize_t k230_pin_read(struct rt_device *device, rt_base_t pin) +{ + (void)device; + + return kd_pin_read(pin); +} + +static rt_err_t k230_pin_attach_irq(struct rt_device *device, rt_base_t pin, + rt_uint8_t mode, void (*hdr)(void *args), + void *args) +{ + (void)device; + + return kd_pin_attach_irq(pin, mode, hdr, args); +} + +static rt_err_t k230_pin_detach_irq(struct rt_device *device, rt_base_t pin) +{ + (void)device; + + return kd_pin_detach_irq(pin); +} + +static rt_err_t k230_pin_irq_enable(struct rt_device *device, rt_base_t pin, + rt_uint8_t enabled) +{ + (void)device; + + return kd_pin_irq_enable(pin, enabled); +} + +static const struct rt_pin_ops k230_pin_ops = +{ + .pin_mode = k230_pin_mode, + .pin_write = k230_pin_write, + .pin_read = k230_pin_read, + .pin_attach_irq = k230_pin_attach_irq, + .pin_detach_irq = k230_pin_detach_irq, + .pin_irq_enable = k230_pin_irq_enable, +}; + int rt_hw_gpio_init(void) { rt_err_t ret; @@ -393,8 +462,8 @@ int rt_hw_gpio_init(void) } gpio_dev.hardlock = HARDLOCK_GPIO; - ret = rt_device_register(&gpio_dev.dev, "gpio", RT_DEVICE_FLAG_RDWR); + ret = rt_device_pin_register("gpio", &k230_pin_ops, RT_NULL); return ret; } -INIT_BOARD_EXPORT(rt_hw_gpio_init); \ No newline at end of file +INIT_BOARD_EXPORT(rt_hw_gpio_init); diff --git a/bsp/k230/drivers/interdrv/rtc/drv_rtc.c b/bsp/k230/drivers/interdrv/rtc/drv_rtc.c index b4820dc79a1..17a941b4229 100644 --- a/bsp/k230/drivers/interdrv/rtc/drv_rtc.c +++ b/bsp/k230/drivers/interdrv/rtc/drv_rtc.c @@ -477,7 +477,7 @@ static int rt_hw_rtc_init(void) ret = rt_device_register(&rtc_dev.device, "rtc", RT_DEVICE_FLAG_RDWR); RT_ASSERT(ret == RT_EOK); - LOG_I("rtc driver register OK\n"); + LOG_D("rtc driver register OK"); rtc_alarm_stop(&rtc_dev); rtc_tick_stop(&rtc_dev); diff --git a/bsp/k230/rtconfig.h b/bsp/k230/rtconfig.h index e0a4e114508..7e979a0d755 100644 --- a/bsp/k230/rtconfig.h +++ b/bsp/k230/rtconfig.h @@ -72,7 +72,7 @@ /* end of rt_strnlen options */ /* end of klibc options */ -#define RT_NAME_MAX 16 +#define RT_NAME_MAX 32 #define RT_USING_SMART #define RT_CPUS_NR 1 #define RT_ALIGN_SIZE 8 @@ -90,6 +90,7 @@ #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 8192 #define RT_USING_CPU_USAGE_TRACER +#define RT_CPU_USAGE_CALC_INTERVAL_MS 200 /* kservice options */ @@ -120,7 +121,8 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 256 #define RT_CONSOLE_DEVICE_NAME "uart0" -#define RT_VER_NUM 0x50201 +#define RT_USING_CONSOLE_OUTPUT_CTL +#define RT_VER_NUM 0x50300 #define RT_USING_STDC_ATOMIC #define RT_BACKTRACE_LEVEL_MAX_NR 32 /* end of RT-Thread Kernel */ @@ -130,11 +132,10 @@ #define KERNEL_VADDR_START 0xffffffc000000000 #define ARCH_RISCV #define ARCH_RISCV_FPU -#define ARCH_RISCV_VECTOR -#define ARCH_VECTOR_VLEN_128 -#define ARCH_RISCV_FPU_D #define ARCH_RISCV64 +#define ARCH_RISCV_XUANTIE #define ARCH_USING_NEW_CTX_SWITCH +#define CONFIG_XUANTIE_SVPBMT 1 #define ARCH_REMAP_KERNEL /* RT-Thread Components */ @@ -183,7 +184,6 @@ /* end of elm-chan's FatFs, Generic FAT Filesystem Module */ #define RT_USING_DFS_DEVFS #define RT_USING_DFS_PTYFS -#define RT_USING_DFS_CROMFS #define RT_USING_DFS_TMPFS #define RT_USING_PAGECACHE @@ -210,13 +210,13 @@ #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_SERIAL_BYPASS -#define RT_USING_CPUTIME -#define RT_USING_CPUTIME_RISCV -#define CPUTIME_TIMER_FREQ 25000000 +#define RT_USING_CLOCK_TIME +#define CLOCK_TIMER_FREQ 250000 #define RT_USING_NULL #define RT_USING_ZERO #define RT_USING_RANDOM #define RT_USING_RTC +#define RT_USING_SOFT_RTC #define RT_USING_SDIO #define RT_SDIO_STACK_SIZE 8192 #define RT_SDIO_THREAD_PRIORITY 15 @@ -231,7 +231,6 @@ #define RT_BLK_PARTITION_EFI /* end of Partition Types */ #define RT_USING_PIN -#define RT_USING_KTIME /* end of Device Drivers */ /* C/C++ and POSIX layer */ @@ -265,6 +264,8 @@ /* Interprocess Communication (IPC) */ +#define RT_USING_POSIX_PIPE +#define RT_USING_POSIX_PIPE_SIZE 2048 /* Socket is in the 'Network' category */ @@ -462,6 +463,9 @@ /* Micrium: Micrium software products porting for RT-Thread */ /* end of Micrium: Micrium software products porting for RT-Thread */ +#define PKG_USING_LWEXT4 +#define RT_USING_DFS_LWEXT4 +#define PKG_USING_LWEXT4_LATEST_VERSION /* end of system packages */ /* peripheral libraries and drivers */ @@ -503,6 +507,14 @@ /* GD32 Drivers */ /* end of GD32 Drivers */ + +/* HPMicro SDK */ + +/* end of HPMicro SDK */ + +/* FT32 HAL & SDK Drivers */ + +/* end of FT32 HAL & SDK Drivers */ /* end of HAL & SDK Drivers */ /* sensors drivers */ @@ -535,8 +547,6 @@ /* entertainment: terminal games and other interesting software packages */ /* end of entertainment: terminal games and other interesting software packages */ -#define PKG_USING_ZLIB -#define PKG_USING_ZLIB_LATEST_VERSION /* end of miscellaneous packages */ /* Arduino libraries */ @@ -587,17 +597,20 @@ /* Drivers Configuration */ +#define BSP_USING_GPIO +#define BSP_USING_DISPLAY #define BSP_USING_UART #define BSP_UART_USING_DMA #define BSP_USING_UART0 #define BSP_USING_HARDLOCK #define BSP_USING_SDIO #define BSP_USING_SDIO0 -#define BSP_SD_MNT_DEVNAME "sd0p1" +#define BSP_SD_MNT_DEVNAME "sd0p0" /* end of Drivers Configuration */ +#define SOC_K230D #define BOARD_C908 #define __STACKSIZE__ 65536 #define BSP_ROOTFS_TYPE_ELMFAT -#define BSP_RISCV_FPU_D +#define BSP_RISCV_FPU_SOFT #endif diff --git a/bsp/k230/rtconfig.py b/bsp/k230/rtconfig.py index 10987fa320b..7f390e8765b 100644 --- a/bsp/k230/rtconfig.py +++ b/bsp/k230/rtconfig.py @@ -30,7 +30,7 @@ if PLATFORM == 'gcc': # toolchains #PREFIX = 'riscv64-unknown-elf-' - PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-linux-musl-' + PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-linux-musleabi-' CC = PREFIX + 'gcc' CXX = PREFIX + 'g++' AS = PREFIX + 'gcc' diff --git a/bsp/qemu-virt64-riscv/.config b/bsp/qemu-virt64-riscv/.config index 2bca112cf86..09c479f430a 100644 --- a/bsp/qemu-virt64-riscv/.config +++ b/bsp/qemu-virt64-riscv/.config @@ -116,10 +116,10 @@ CONFIG_RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS=4 # end of rt_strnlen options # end of klibc options -CONFIG_RT_NAME_MAX=24 +CONFIG_RT_NAME_MAX=32 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_NANO is not set -# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMART=y # CONFIG_RT_USING_AMP is not set # CONFIG_RT_USING_SMP is not set CONFIG_RT_CPUS_NR=1 @@ -141,6 +141,7 @@ CONFIG_RT_TIMER_THREAD_PRIO=4 CONFIG_RT_TIMER_THREAD_STACK_SIZE=16384 # CONFIG_RT_USING_TIMER_ALL_SOFT is not set CONFIG_RT_USING_CPU_USAGE_TRACER=y +CONFIG_RT_CPU_USAGE_CALC_INTERVAL_MS=200 # # kservice options @@ -191,7 +192,8 @@ CONFIG_RT_USING_DEVICE_OPS=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" -CONFIG_RT_VER_NUM=0x50201 +CONFIG_RT_USING_CONSOLE_OUTPUT_CTL=y +CONFIG_RT_VER_NUM=0x50300 CONFIG_RT_USING_STDC_ATOMIC=y CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 # end of RT-Thread Kernel @@ -199,6 +201,7 @@ CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 CONFIG_ARCH_CPU_64BIT=y CONFIG_RT_USING_CACHE=y CONFIG_ARCH_MM_MMU=y +CONFIG_KERNEL_VADDR_START=0xffffffc000000000 CONFIG_ARCH_RISCV=y CONFIG_ARCH_RISCV_FPU=y CONFIG_ARCH_RISCV64=y @@ -240,7 +243,6 @@ CONFIG_RT_USING_DFS=y CONFIG_DFS_USING_POSIX=y CONFIG_DFS_USING_WORKDIR=y CONFIG_DFS_FD_MAX=32 -# CONFIG_RT_USING_DFS_V1 is not set CONFIG_RT_USING_DFS_V2=y CONFIG_RT_USING_DFS_ELMFAT=y @@ -270,9 +272,23 @@ CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 CONFIG_RT_USING_DFS_DEVFS=y CONFIG_RT_USING_DFS_ROMFS=y +CONFIG_RT_USING_DFS_PTYFS=y +# CONFIG_RT_USING_DFS_PROCFS is not set # CONFIG_RT_USING_DFS_CROMFS is not set # CONFIG_RT_USING_DFS_TMPFS is not set # CONFIG_RT_USING_DFS_MQUEUE is not set +CONFIG_RT_USING_PAGECACHE=y + +# +# page cache config +# +CONFIG_RT_PAGECACHE_COUNT=4096 +CONFIG_RT_PAGECACHE_ASPACE_COUNT=1024 +CONFIG_RT_PAGECACHE_PRELOAD=4 +CONFIG_RT_PAGECACHE_HASH_NR=1024 +CONFIG_RT_PAGECACHE_GC_WORK_LEVEL=90 +CONFIG_RT_PAGECACHE_GC_STOP_LEVEL=70 +# end of page cache config # end of DFS: device virtual file system # CONFIG_RT_USING_FAL is not set @@ -280,8 +296,8 @@ CONFIG_RT_USING_DFS_ROMFS=y # # Device Drivers # -# CONFIG_RT_USING_DM is not set -# CONFIG_RT_USING_DEV_BUS is not set +CONFIG_RT_USING_DM=y +CONFIG_RT_USING_DEV_BUS=y CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_UNAMED_PIPE_NUMBER=64 CONFIG_RT_USING_SYSTEM_WORKQUEUE=y @@ -292,11 +308,13 @@ CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_USING_SERIAL_V2 is not set CONFIG_RT_SERIAL_USING_DMA=y CONFIG_RT_SERIAL_RB_BUFSZ=64 -# CONFIG_RT_USING_SERIAL_BYPASS is not set +CONFIG_RT_USING_SERIAL_BYPASS=y +# CONFIG_RT_SERIAL_EARLY_HVC is not set +# CONFIG_RT_SERIAL_PL011 is not set +# CONFIG_RT_SERIAL_8250 is not set # CONFIG_RT_USING_CAN is not set -CONFIG_RT_USING_CPUTIME=y -CONFIG_RT_USING_CPUTIME_RISCV=y -CONFIG_CPUTIME_TIMER_FREQ=10000000 +CONFIG_RT_USING_CLOCK_TIME=y +CONFIG_CLOCK_TIMER_FREQ=0 # CONFIG_RT_USING_I2C is not set # CONFIG_RT_USING_PHY is not set # CONFIG_RT_USING_PHY_V2 is not set @@ -314,16 +332,37 @@ CONFIG_RT_USING_RANDOM=y CONFIG_RT_USING_RTC=y # CONFIG_RT_USING_ALARM is not set CONFIG_RT_USING_SOFT_RTC=y +# CONFIG_RT_RTC_GOLDFISH is not set +# CONFIG_RT_RTC_PL031 is not set # CONFIG_RT_USING_SDIO is not set # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set # CONFIG_RT_USING_TOUCH is not set -# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_GRAPHIC is not set # CONFIG_RT_USING_HWCRYPTO is not set # CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_LED is not set +# CONFIG_RT_USING_INPUT is not set +# CONFIG_RT_USING_MBOX is not set +# CONFIG_RT_USING_HWSPINLOCK is not set +# CONFIG_RT_USING_PHYE is not set # CONFIG_RT_USING_BLK is not set +# CONFIG_RT_USING_SCSI is not set +# CONFIG_RT_USING_FIRMWARE is not set +# CONFIG_RT_USING_HWCACHE is not set +# CONFIG_RT_USING_REGULATOR is not set +# CONFIG_RT_USING_RESET is not set + +# +# Power Management (PM) Domains device drivers +# +# end of Power Management (PM) Domains device drivers + +# CONFIG_RT_USING_POWER_RESET is not set +# CONFIG_RT_USING_POWER_SUPPLY is not set +# CONFIG_RT_USING_THERMAL is not set CONFIG_RT_USING_VIRTIO=y CONFIG_RT_USING_VIRTIO10=y # CONFIG_RT_USING_VIRTIO_MMIO_ALIGN is not set @@ -333,10 +372,23 @@ CONFIG_RT_USING_VIRTIO_CONSOLE=y CONFIG_RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR=4 CONFIG_RT_USING_VIRTIO_GPU=y CONFIG_RT_USING_VIRTIO_INPUT=y +# CONFIG_RT_USING_NVMEM is not set +# CONFIG_RT_USING_DMA is not set +# CONFIG_RT_USING_MFD is not set +CONFIG_RT_USING_OFW=y +# CONFIG_RT_USING_BUILTIN_FDT is not set +CONFIG_RT_FDT_EARLYCON_MSG_SIZE=128 +CONFIG_RT_USING_OFW_BUS_RANGES_NUMBER=8 +# CONFIG_RT_USING_PIC is not set CONFIG_RT_USING_PIN=y -CONFIG_RT_USING_KTIME=y -# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_PIN_PL061 is not set +# CONFIG_RT_USING_PINCTRL is not set +CONFIG_RT_USING_CLK=y # CONFIG_RT_USING_CHERRYUSB is not set + +# +# SoC (System on Chip) Drivers +# # end of Device Drivers # @@ -367,6 +419,9 @@ CONFIG_RT_USING_POSIX_STDIO=y CONFIG_RT_USING_POSIX_POLL=y CONFIG_RT_USING_POSIX_SELECT=y # CONFIG_RT_USING_POSIX_EVENTFD is not set +CONFIG_RT_USING_POSIX_EPOLL=y +CONFIG_RT_USING_POSIX_SIGNALFD=y +CONFIG_RT_SIGNALFD_MAX_NUM=10 # CONFIG_RT_USING_POSIX_TIMERFD is not set # CONFIG_RT_USING_POSIX_SOCKET is not set CONFIG_RT_USING_POSIX_TERMIOS=y @@ -497,7 +552,11 @@ CONFIG_RT_LWIP_USING_PING=y # # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set -# CONFIG_RT_USING_UTEST is not set +CONFIG_RT_USING_UTEST=y +CONFIG_UTEST_THR_STACK_SIZE=4096 +CONFIG_UTEST_THR_PRIORITY=20 +# CONFIG_RT_UTEST_USING_AUTO_RUN is not set +CONFIG_RT_UTEST_MAX_OPTIONS=64 # CONFIG_RT_USING_VAR_EXPORT is not set CONFIG_RT_USING_RESOURCE_ID=y CONFIG_RT_USING_ADT=y @@ -508,14 +567,14 @@ CONFIG_RT_USING_ADT_REF=y # CONFIG_RT_USING_RT_LINK is not set # end of Utilities -# CONFIG_RT_USING_VBUS is not set - # # Memory management # +# CONFIG_RT_PAGE_MPR_SIZE_DYNAMIC is not set CONFIG_RT_PAGE_AFFINITY_BLOCK_SIZE=0x1000 CONFIG_RT_PAGE_MAX_ORDER=11 -# CONFIG_RT_USING_MEMBLOCK is not set +CONFIG_RT_USING_MEMBLOCK=y +CONFIG_RT_INIT_MEMORY_REGIONS=128 # # Debugging @@ -526,6 +585,21 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # end of Debugging # end of Memory management +CONFIG_RT_USING_LWP=y +# CONFIG_LWP_DEBUG is not set +CONFIG_LWP_USING_RUNTIME=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_TID_MAX_NR=64 +CONFIG_RT_LWP_SHM_MAX_NR=64 +CONFIG_RT_USING_LDSO=y +# CONFIG_ELF_DEBUG_ENABLE is not set +# CONFIG_ELF_LOAD_RANDOMIZE is not set +CONFIG_LWP_USING_TERMINAL=y +CONFIG_LWP_PTY_MAX_PARIS_LIMIT=64 +# CONFIG_RT_USING_VDSO is not set + # # Using USB legacy version # @@ -534,6 +608,7 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # end of Using USB legacy version # CONFIG_RT_USING_FDT is not set +# CONFIG_RT_USING_RUST is not set # end of RT-Thread Components # @@ -542,1031 +617,10 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # CONFIG_RT_USING_UTESTCASES is not set # end of RT-Thread Utestcases -# -# RT-Thread online packages -# - -# -# IoT - internet of things -# -# CONFIG_PKG_USING_LORAWAN_DRIVER is not set -# CONFIG_PKG_USING_PAHOMQTT is not set -# CONFIG_PKG_USING_UMQTT is not set -# CONFIG_PKG_USING_WEBCLIENT is not set -# CONFIG_PKG_USING_WEBNET is not set -# CONFIG_PKG_USING_MONGOOSE is not set -# CONFIG_PKG_USING_MYMQTT is not set -# CONFIG_PKG_USING_KAWAII_MQTT is not set -# CONFIG_PKG_USING_BC28_MQTT is not set -# CONFIG_PKG_USING_WEBTERMINAL is not set -# CONFIG_PKG_USING_FREEMODBUS is not set -# CONFIG_PKG_USING_NANOPB is not set -# CONFIG_PKG_USING_WIFI_HOST_DRIVER is not set -# CONFIG_PKG_USING_ESP_HOSTED is not set - -# -# Wi-Fi -# - -# -# Marvell WiFi -# -# CONFIG_PKG_USING_WLANMARVELL is not set -# end of Marvell WiFi - -# -# Wiced WiFi -# -# CONFIG_PKG_USING_WLAN_WICED is not set -# end of Wiced WiFi - -# CONFIG_PKG_USING_RW007 is not set - -# -# CYW43012 WiFi -# -# CONFIG_PKG_USING_WLAN_CYW43012 is not set -# end of CYW43012 WiFi - -# -# BL808 WiFi -# -# CONFIG_PKG_USING_WLAN_BL808 is not set -# end of BL808 WiFi - -# -# CYW43439 WiFi -# -# CONFIG_PKG_USING_WLAN_CYW43439 is not set -# end of CYW43439 WiFi -# end of Wi-Fi - -# CONFIG_PKG_USING_COAP is not set -# CONFIG_PKG_USING_NOPOLL is not set -# CONFIG_PKG_USING_NETUTILS is not set -# CONFIG_PKG_USING_CMUX is not set -# CONFIG_PKG_USING_PPP_DEVICE is not set -# CONFIG_PKG_USING_AT_DEVICE is not set -# CONFIG_PKG_USING_ATSRV_SOCKET is not set -# CONFIG_PKG_USING_WIZNET is not set -# CONFIG_PKG_USING_ZB_COORDINATOR is not set - -# -# IoT Cloud -# -# CONFIG_PKG_USING_ONENET is not set -# CONFIG_PKG_USING_GAGENT_CLOUD is not set -# CONFIG_PKG_USING_ALI_IOTKIT is not set -# CONFIG_PKG_USING_AZURE is not set -# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set -# CONFIG_PKG_USING_JIOT-C-SDK is not set -# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set -# CONFIG_PKG_USING_JOYLINK is not set -# CONFIG_PKG_USING_IOTSHARP_SDK is not set -# end of IoT Cloud - -# CONFIG_PKG_USING_NIMBLE is not set -# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set -# CONFIG_PKG_USING_OTA_DOWNLOADER is not set -# CONFIG_PKG_USING_IPMSG is not set -# CONFIG_PKG_USING_LSSDP is not set -# CONFIG_PKG_USING_AIRKISS_OPEN is not set -# CONFIG_PKG_USING_LIBRWS is not set -# CONFIG_PKG_USING_TCPSERVER is not set -# CONFIG_PKG_USING_PROTOBUF_C is not set -# CONFIG_PKG_USING_DLT645 is not set -# CONFIG_PKG_USING_QXWZ is not set -# CONFIG_PKG_USING_SMTP_CLIENT is not set -# CONFIG_PKG_USING_ABUP_FOTA is not set -# CONFIG_PKG_USING_LIBCURL2RTT is not set -# CONFIG_PKG_USING_CAPNP is not set -# CONFIG_PKG_USING_AGILE_TELNET is not set -# CONFIG_PKG_USING_NMEALIB is not set -# CONFIG_PKG_USING_PDULIB is not set -# CONFIG_PKG_USING_BTSTACK is not set -# CONFIG_PKG_USING_BT_CYW43012 is not set -# CONFIG_PKG_USING_CYW43XX is not set -# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set -# CONFIG_PKG_USING_WAYZ_IOTKIT is not set -# CONFIG_PKG_USING_MAVLINK is not set -# CONFIG_PKG_USING_BSAL is not set -# CONFIG_PKG_USING_AGILE_MODBUS is not set -# CONFIG_PKG_USING_AGILE_FTP is not set -# CONFIG_PKG_USING_EMBEDDEDPROTO is not set -# CONFIG_PKG_USING_RT_LINK_HW is not set -# CONFIG_PKG_USING_RYANMQTT is not set -# CONFIG_PKG_USING_RYANW5500 is not set -# CONFIG_PKG_USING_LORA_PKT_FWD is not set -# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set -# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set -# CONFIG_PKG_USING_HM is not set -# CONFIG_PKG_USING_SMALL_MODBUS is not set -# CONFIG_PKG_USING_NET_SERVER is not set -# CONFIG_PKG_USING_ZFTP is not set -# CONFIG_PKG_USING_WOL is not set -# CONFIG_PKG_USING_ZEPHYR_POLLING is not set -# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set -# CONFIG_PKG_USING_LHC_MODBUS is not set -# CONFIG_PKG_USING_QMODBUS is not set -# CONFIG_PKG_USING_PNET is not set -# CONFIG_PKG_USING_OPENER is not set -# CONFIG_PKG_USING_FREEMQTT is not set -# end of IoT - internet of things - -# -# security packages -# -# CONFIG_PKG_USING_MBEDTLS is not set -# CONFIG_PKG_USING_LIBSODIUM is not set -# CONFIG_PKG_USING_LIBHYDROGEN is not set -# CONFIG_PKG_USING_TINYCRYPT is not set -# CONFIG_PKG_USING_TFM is not set -# CONFIG_PKG_USING_YD_CRYPTO is not set -# end of security packages - -# -# language packages -# - -# -# JSON: JavaScript Object Notation, a lightweight data-interchange format -# -# CONFIG_PKG_USING_CJSON is not set -# CONFIG_PKG_USING_LJSON is not set -# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set -# CONFIG_PKG_USING_RAPIDJSON is not set -# CONFIG_PKG_USING_JSMN is not set -# CONFIG_PKG_USING_AGILE_JSMN is not set -# CONFIG_PKG_USING_PARSON is not set -# CONFIG_PKG_USING_RYAN_JSON is not set -# end of JSON: JavaScript Object Notation, a lightweight data-interchange format - -# -# XML: Extensible Markup Language -# -# CONFIG_PKG_USING_SIMPLE_XML is not set -# CONFIG_PKG_USING_EZXML is not set -# end of XML: Extensible Markup Language - -# CONFIG_PKG_USING_LUATOS_SOC is not set -# CONFIG_PKG_USING_LUA is not set -# CONFIG_PKG_USING_JERRYSCRIPT is not set -# CONFIG_PKG_USING_MICROPYTHON is not set -# CONFIG_PKG_USING_PIKASCRIPT is not set -# CONFIG_PKG_USING_RTT_RUST is not set -# end of language packages - -# -# multimedia packages -# - -# -# LVGL: powerful and easy-to-use embedded GUI library -# -# CONFIG_PKG_USING_LVGL is not set -# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set -# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set -# end of LVGL: powerful and easy-to-use embedded GUI library - -# -# u8g2: a monochrome graphic library -# -# CONFIG_PKG_USING_U8G2_OFFICIAL is not set -# CONFIG_PKG_USING_U8G2 is not set -# end of u8g2: a monochrome graphic library - -# CONFIG_PKG_USING_OPENMV is not set -# CONFIG_PKG_USING_MUPDF is not set -# CONFIG_PKG_USING_STEMWIN is not set -# CONFIG_PKG_USING_WAVPLAYER is not set -# CONFIG_PKG_USING_TJPGD is not set -# CONFIG_PKG_USING_PDFGEN is not set -# CONFIG_PKG_USING_HELIX is not set -# CONFIG_PKG_USING_AZUREGUIX is not set -# CONFIG_PKG_USING_TOUCHGFX2RTT is not set -# CONFIG_PKG_USING_NUEMWIN is not set -# CONFIG_PKG_USING_MP3PLAYER is not set -# CONFIG_PKG_USING_TINYJPEG is not set -# CONFIG_PKG_USING_UGUI is not set -# CONFIG_PKG_USING_MCURSES is not set -# CONFIG_PKG_USING_TERMBOX is not set -# CONFIG_PKG_USING_VT100 is not set -# CONFIG_PKG_USING_QRCODE is not set -# CONFIG_PKG_USING_GUIENGINE is not set -# CONFIG_PKG_USING_3GPP_AMRNB is not set -# end of multimedia packages - -# -# tools packages -# -# CONFIG_PKG_USING_CMBACKTRACE is not set -# CONFIG_PKG_USING_MCOREDUMP is not set -# CONFIG_PKG_USING_EASYFLASH is not set -# CONFIG_PKG_USING_EASYLOGGER is not set -# CONFIG_PKG_USING_SYSTEMVIEW is not set -# CONFIG_PKG_USING_SEGGER_RTT is not set -# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set -# CONFIG_PKG_USING_RDB is not set -# CONFIG_PKG_USING_ULOG_EASYFLASH is not set -# CONFIG_PKG_USING_LOGMGR is not set -# CONFIG_PKG_USING_ADBD is not set -# CONFIG_PKG_USING_COREMARK is not set -# CONFIG_PKG_USING_DHRYSTONE is not set -# CONFIG_PKG_USING_MEMORYPERF is not set -# CONFIG_PKG_USING_NR_MICRO_SHELL is not set -# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set -# CONFIG_PKG_USING_LUNAR_CALENDAR is not set -# CONFIG_PKG_USING_BS8116A is not set -# CONFIG_PKG_USING_GPS_RMC is not set -# CONFIG_PKG_USING_URLENCODE is not set -# CONFIG_PKG_USING_UMCN is not set -# CONFIG_PKG_USING_LWRB2RTT is not set -# CONFIG_PKG_USING_CPU_USAGE is not set -# CONFIG_PKG_USING_GBK2UTF8 is not set -# CONFIG_PKG_USING_VCONSOLE is not set -# CONFIG_PKG_USING_KDB is not set -# CONFIG_PKG_USING_WAMR is not set -# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set -# CONFIG_PKG_USING_LWLOG is not set -# CONFIG_PKG_USING_ANV_TRACE is not set -# CONFIG_PKG_USING_ANV_MEMLEAK is not set -# CONFIG_PKG_USING_ANV_TESTSUIT is not set -# CONFIG_PKG_USING_ANV_BENCH is not set -# CONFIG_PKG_USING_DEVMEM is not set -# CONFIG_PKG_USING_REGEX is not set -# CONFIG_PKG_USING_MEM_SANDBOX is not set -# CONFIG_PKG_USING_SOLAR_TERMS is not set -# CONFIG_PKG_USING_GAN_ZHI is not set -# CONFIG_PKG_USING_FDT is not set -# CONFIG_PKG_USING_CBOX is not set -# CONFIG_PKG_USING_SNOWFLAKE is not set -# CONFIG_PKG_USING_HASH_MATCH is not set -# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set -# CONFIG_PKG_USING_VOFA_PLUS is not set -# CONFIG_PKG_USING_ZDEBUG is not set -# CONFIG_PKG_USING_RVBACKTRACE is not set -# CONFIG_PKG_USING_HPATCHLITE is not set -# CONFIG_PKG_USING_THREAD_METRIC is not set -# end of tools packages - -# -# system packages -# - -# -# enhanced kernel services -# -# CONFIG_PKG_USING_RT_MEMCPY_CM is not set -# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set -# end of enhanced kernel services - -# CONFIG_PKG_USING_AUNITY is not set - -# -# acceleration: Assembly language or algorithmic acceleration packages -# -# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set -# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set -# CONFIG_PKG_USING_QFPLIB_M3 is not set -# end of acceleration: Assembly language or algorithmic acceleration packages - -# -# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard -# -# CONFIG_PKG_USING_CMSIS_5 is not set -# CONFIG_PKG_USING_CMSIS_CORE is not set -# CONFIG_PKG_USING_CMSIS_NN is not set -# CONFIG_PKG_USING_CMSIS_RTOS1 is not set -# CONFIG_PKG_USING_CMSIS_RTOS2 is not set -# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard - -# -# Micrium: Micrium software products porting for RT-Thread -# -# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set -# CONFIG_PKG_USING_UCOSII_WRAPPER is not set -# CONFIG_PKG_USING_UC_CRC is not set -# CONFIG_PKG_USING_UC_CLK is not set -# CONFIG_PKG_USING_UC_COMMON is not set -# CONFIG_PKG_USING_UC_MODBUS is not set -# end of Micrium: Micrium software products porting for RT-Thread - -# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set -# CONFIG_PKG_USING_LITEOS_SDK is not set -# CONFIG_PKG_USING_TZ_DATABASE is not set -# CONFIG_PKG_USING_CAIRO is not set -# CONFIG_PKG_USING_PIXMAN is not set -# CONFIG_PKG_USING_PARTITION is not set -# CONFIG_PKG_USING_PERF_COUNTER is not set -# CONFIG_PKG_USING_FILEX is not set -# CONFIG_PKG_USING_LEVELX is not set -# CONFIG_PKG_USING_FLASHDB is not set -# CONFIG_PKG_USING_SQLITE is not set -# CONFIG_PKG_USING_RTI is not set -# CONFIG_PKG_USING_DFS_YAFFS is not set -# CONFIG_PKG_USING_LITTLEFS is not set -# CONFIG_PKG_USING_DFS_JFFS2 is not set -# CONFIG_PKG_USING_DFS_UFFS is not set -# CONFIG_PKG_USING_LWEXT4 is not set -# CONFIG_PKG_USING_THREAD_POOL is not set -# CONFIG_PKG_USING_ROBOTS is not set -# CONFIG_PKG_USING_EV is not set -# CONFIG_PKG_USING_SYSWATCH is not set -# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set -# CONFIG_PKG_USING_PLCCORE is not set -# CONFIG_PKG_USING_RAMDISK is not set -# CONFIG_PKG_USING_MININI is not set -# CONFIG_PKG_USING_QBOOT is not set -# CONFIG_PKG_USING_PPOOL is not set -# CONFIG_PKG_USING_OPENAMP is not set -# CONFIG_PKG_USING_RPMSG_LITE is not set -# CONFIG_PKG_USING_LPM is not set -# CONFIG_PKG_USING_TLSF is not set -# CONFIG_PKG_USING_EVENT_RECORDER is not set -# CONFIG_PKG_USING_ARM_2D is not set -# CONFIG_PKG_USING_MCUBOOT is not set -# CONFIG_PKG_USING_TINYUSB is not set -# CONFIG_PKG_USING_KMULTI_RTIMER is not set -# CONFIG_PKG_USING_TFDB is not set -# CONFIG_PKG_USING_QPC is not set -# CONFIG_PKG_USING_AGILE_UPGRADE is not set -# CONFIG_PKG_USING_FLASH_BLOB is not set -# CONFIG_PKG_USING_MLIBC is not set -# CONFIG_PKG_USING_TASK_MSG_BUS is not set -# CONFIG_PKG_USING_UART_FRAMEWORK is not set -# CONFIG_PKG_USING_SFDB is not set -# CONFIG_PKG_USING_RTP is not set -# CONFIG_PKG_USING_REB is not set -# CONFIG_PKG_USING_RMP is not set -# CONFIG_PKG_USING_R_RHEALSTONE is not set -# CONFIG_PKG_USING_HEARTBEAT is not set -# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set -# end of system packages - -# -# peripheral libraries and drivers -# - -# -# HAL & SDK Drivers -# - -# -# STM32 HAL & SDK Drivers -# -# CONFIG_PKG_USING_STM32F0_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32F0_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32F1_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32F1_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32F2_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32F2_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32F3_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32F3_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32F7_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32F7_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32G0_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32G0_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32G4_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32G4_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32H5_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32H5_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32H7_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32H7_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32H7RS_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32H7RS_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32L0_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32L0_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32L5_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32L5_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32U5_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32U5_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32WB55_SDK is not set -# CONFIG_PKG_USING_STM32_SDIO is not set -# CONFIG_PKG_USING_STM32WL_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32WL_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32WB_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32WB_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_STM32MP1_M4_HAL_DRIVER is not set -# CONFIG_PKG_USING_STM32MP1_M4_CMSIS_DRIVER is not set -# end of STM32 HAL & SDK Drivers - -# -# Infineon HAL Packages -# -# CONFIG_PKG_USING_INFINEON_CAT1CM0P is not set -# CONFIG_PKG_USING_INFINEON_CMSIS is not set -# CONFIG_PKG_USING_INFINEON_CORE_LIB is not set -# CONFIG_PKG_USING_INFINEON_MTB_HAL_CAT1 is not set -# CONFIG_PKG_USING_INFINEON_MTB_PDL_CAT1 is not set -# CONFIG_PKG_USING_INFINEON_RETARGET_IO is not set -# CONFIG_PKG_USING_INFINEON_CAPSENSE is not set -# CONFIG_PKG_USING_INFINEON_CSDIDAC is not set -# CONFIG_PKG_USING_INFINEON_SERIAL_FLASH is not set -# CONFIG_PKG_USING_INFINEON_USBDEV is not set -# end of Infineon HAL Packages - -# CONFIG_PKG_USING_BLUETRUM_SDK is not set -# CONFIG_PKG_USING_EMBARC_BSP is not set -# CONFIG_PKG_USING_ESP_IDF is not set - -# -# Kendryte SDK -# -# CONFIG_PKG_USING_K210_SDK is not set -# CONFIG_PKG_USING_KENDRYTE_SDK is not set -# end of Kendryte SDK - -# CONFIG_PKG_USING_NRF5X_SDK is not set -# CONFIG_PKG_USING_NRFX is not set -# CONFIG_PKG_USING_NUCLEI_SDK is not set -# CONFIG_PKG_USING_RASPBERRYPI_PICO_RP2350_SDK is not set -# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set -# CONFIG_PKG_USING_MM32 is not set - -# -# WCH HAL & SDK Drivers -# -# CONFIG_PKG_USING_CH32V20x_SDK is not set -# CONFIG_PKG_USING_CH32V307_SDK is not set -# end of WCH HAL & SDK Drivers - -# -# AT32 HAL & SDK Drivers -# -# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set -# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set -# end of AT32 HAL & SDK Drivers - -# -# HC32 DDL Drivers -# -# CONFIG_PKG_USING_HC32F3_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_HC32F3_SERIES_DRIVER is not set -# CONFIG_PKG_USING_HC32F4_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_HC32F4_SERIES_DRIVER is not set -# end of HC32 DDL Drivers - -# -# NXP HAL & SDK Drivers -# -# CONFIG_PKG_USING_NXP_MCX_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_NXP_MCX_SERIES_DRIVER is not set -# CONFIG_PKG_USING_NXP_LPC_DRIVER is not set -# CONFIG_PKG_USING_NXP_LPC55S_DRIVER is not set -# CONFIG_PKG_USING_NXP_IMX6SX_DRIVER is not set -# CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set -# CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set -# end of NXP HAL & SDK Drivers - -# -# NUVOTON Drivers -# -# CONFIG_PKG_USING_NUVOTON_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_NUVOTON_SERIES_DRIVER is not set -# CONFIG_PKG_USING_NUVOTON_ARM926_LIB is not set -# end of NUVOTON Drivers - -# -# GD32 Drivers -# -# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set -# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set -# end of GD32 Drivers -# end of HAL & SDK Drivers - -# -# sensors drivers -# -# CONFIG_PKG_USING_LSM6DSM is not set -# CONFIG_PKG_USING_LSM6DSL is not set -# CONFIG_PKG_USING_LPS22HB is not set -# CONFIG_PKG_USING_HTS221 is not set -# CONFIG_PKG_USING_LSM303AGR is not set -# CONFIG_PKG_USING_BME280 is not set -# CONFIG_PKG_USING_BME680 is not set -# CONFIG_PKG_USING_BMA400 is not set -# CONFIG_PKG_USING_BMI160_BMX160 is not set -# CONFIG_PKG_USING_SPL0601 is not set -# CONFIG_PKG_USING_MS5805 is not set -# CONFIG_PKG_USING_DA270 is not set -# CONFIG_PKG_USING_DF220 is not set -# CONFIG_PKG_USING_HSHCAL001 is not set -# CONFIG_PKG_USING_BH1750 is not set -# CONFIG_PKG_USING_MPU6XXX is not set -# CONFIG_PKG_USING_AHT10 is not set -# CONFIG_PKG_USING_AP3216C is not set -# CONFIG_PKG_USING_TSL4531 is not set -# CONFIG_PKG_USING_DS18B20 is not set -# CONFIG_PKG_USING_DHT11 is not set -# CONFIG_PKG_USING_DHTXX is not set -# CONFIG_PKG_USING_GY271 is not set -# CONFIG_PKG_USING_GP2Y10 is not set -# CONFIG_PKG_USING_SGP30 is not set -# CONFIG_PKG_USING_HDC1000 is not set -# CONFIG_PKG_USING_BMP180 is not set -# CONFIG_PKG_USING_BMP280 is not set -# CONFIG_PKG_USING_SHTC1 is not set -# CONFIG_PKG_USING_BMI088 is not set -# CONFIG_PKG_USING_HMC5883 is not set -# CONFIG_PKG_USING_MAX6675 is not set -# CONFIG_PKG_USING_MAX31855 is not set -# CONFIG_PKG_USING_TMP1075 is not set -# CONFIG_PKG_USING_SR04 is not set -# CONFIG_PKG_USING_CCS811 is not set -# CONFIG_PKG_USING_PMSXX is not set -# CONFIG_PKG_USING_RT3020 is not set -# CONFIG_PKG_USING_MLX90632 is not set -# CONFIG_PKG_USING_MLX90382 is not set -# CONFIG_PKG_USING_MLX90393 is not set -# CONFIG_PKG_USING_MLX90392 is not set -# CONFIG_PKG_USING_MLX90394 is not set -# CONFIG_PKG_USING_MLX90397 is not set -# CONFIG_PKG_USING_MS5611 is not set -# CONFIG_PKG_USING_MAX31865 is not set -# CONFIG_PKG_USING_VL53L0X is not set -# CONFIG_PKG_USING_INA260 is not set -# CONFIG_PKG_USING_MAX30102 is not set -# CONFIG_PKG_USING_INA226 is not set -# CONFIG_PKG_USING_LIS2DH12 is not set -# CONFIG_PKG_USING_HS300X is not set -# CONFIG_PKG_USING_ZMOD4410 is not set -# CONFIG_PKG_USING_ISL29035 is not set -# CONFIG_PKG_USING_MMC3680KJ is not set -# CONFIG_PKG_USING_QMP6989 is not set -# CONFIG_PKG_USING_BALANCE is not set -# CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_SHT3X is not set -# CONFIG_PKG_USING_SHT4X is not set -# CONFIG_PKG_USING_AD7746 is not set -# CONFIG_PKG_USING_ADT74XX is not set -# CONFIG_PKG_USING_MAX17048 is not set -# CONFIG_PKG_USING_AS7341 is not set -# CONFIG_PKG_USING_CW2015 is not set -# CONFIG_PKG_USING_ICM20608 is not set -# CONFIG_PKG_USING_PAJ7620 is not set -# CONFIG_PKG_USING_STHS34PF80 is not set -# CONFIG_PKG_USING_P3T1755 is not set -# CONFIG_PKG_USING_QMI8658 is not set -# CONFIG_PKG_USING_ICM20948 is not set -# end of sensors drivers - -# -# touch drivers -# -# CONFIG_PKG_USING_GT9147 is not set -# CONFIG_PKG_USING_GT1151 is not set -# CONFIG_PKG_USING_GT917S is not set -# CONFIG_PKG_USING_GT911 is not set -# CONFIG_PKG_USING_FT6206 is not set -# CONFIG_PKG_USING_FT5426 is not set -# CONFIG_PKG_USING_FT6236 is not set -# CONFIG_PKG_USING_XPT2046_TOUCH is not set -# CONFIG_PKG_USING_CST816X is not set -# CONFIG_PKG_USING_CST812T is not set -# end of touch drivers - -# CONFIG_PKG_USING_REALTEK_AMEBA is not set -# CONFIG_PKG_USING_BUTTON is not set -# CONFIG_PKG_USING_PCF8574 is not set -# CONFIG_PKG_USING_SX12XX is not set -# CONFIG_PKG_USING_SIGNAL_LED is not set -# CONFIG_PKG_USING_LEDBLINK is not set -# CONFIG_PKG_USING_LITTLED is not set -# CONFIG_PKG_USING_LKDGUI is not set -# CONFIG_PKG_USING_INFRARED is not set -# CONFIG_PKG_USING_MULTI_INFRARED is not set -# CONFIG_PKG_USING_AGILE_BUTTON is not set -# CONFIG_PKG_USING_AGILE_LED is not set -# CONFIG_PKG_USING_AT24CXX is not set -# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set -# CONFIG_PKG_USING_PCA9685 is not set -# CONFIG_PKG_USING_ILI9341 is not set -# CONFIG_PKG_USING_I2C_TOOLS is not set -# CONFIG_PKG_USING_NRF24L01 is not set -# CONFIG_PKG_USING_RPLIDAR is not set -# CONFIG_PKG_USING_AS608 is not set -# CONFIG_PKG_USING_RC522 is not set -# CONFIG_PKG_USING_WS2812B is not set -# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set -# CONFIG_PKG_USING_MULTI_RTIMER is not set -# CONFIG_PKG_USING_MAX7219 is not set -# CONFIG_PKG_USING_BEEP is not set -# CONFIG_PKG_USING_EASYBLINK is not set -# CONFIG_PKG_USING_PMS_SERIES is not set -# CONFIG_PKG_USING_CAN_YMODEM is not set -# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set -# CONFIG_PKG_USING_QLED is not set -# CONFIG_PKG_USING_AGILE_CONSOLE is not set -# CONFIG_PKG_USING_LD3320 is not set -# CONFIG_PKG_USING_WK2124 is not set -# CONFIG_PKG_USING_LY68L6400 is not set -# CONFIG_PKG_USING_DM9051 is not set -# CONFIG_PKG_USING_SSD1306 is not set -# CONFIG_PKG_USING_QKEY is not set -# CONFIG_PKG_USING_RS485 is not set -# CONFIG_PKG_USING_RS232 is not set -# CONFIG_PKG_USING_NES is not set -# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set -# CONFIG_PKG_USING_VDEVICE is not set -# CONFIG_PKG_USING_SGM706 is not set -# CONFIG_PKG_USING_RDA58XX is not set -# CONFIG_PKG_USING_LIBNFC is not set -# CONFIG_PKG_USING_MFOC is not set -# CONFIG_PKG_USING_TMC51XX is not set -# CONFIG_PKG_USING_TCA9534 is not set -# CONFIG_PKG_USING_KOBUKI is not set -# CONFIG_PKG_USING_ROSSERIAL is not set -# CONFIG_PKG_USING_MICRO_ROS is not set -# CONFIG_PKG_USING_MCP23008 is not set -# CONFIG_PKG_USING_MISAKA_AT24CXX is not set -# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set -# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set -# CONFIG_PKG_USING_SOFT_SERIAL is not set -# CONFIG_PKG_USING_MB85RS16 is not set -# CONFIG_PKG_USING_RFM300 is not set -# CONFIG_PKG_USING_IO_INPUT_FILTER is not set -# CONFIG_PKG_USING_LRF_NV7LIDAR is not set -# CONFIG_PKG_USING_AIP650 is not set -# CONFIG_PKG_USING_FINGERPRINT is not set -# CONFIG_PKG_USING_BT_ECB02C is not set -# CONFIG_PKG_USING_UAT is not set -# CONFIG_PKG_USING_ST7789 is not set -# CONFIG_PKG_USING_VS1003 is not set -# CONFIG_PKG_USING_X9555 is not set -# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set -# CONFIG_PKG_USING_BT_MX01 is not set -# CONFIG_PKG_USING_RGPOWER is not set -# CONFIG_PKG_USING_BT_MX02 is not set -# CONFIG_PKG_USING_GC9A01 is not set -# CONFIG_PKG_USING_IK485 is not set -# CONFIG_PKG_USING_SERVO is not set -# CONFIG_PKG_USING_SEAN_WS2812B is not set -# CONFIG_PKG_USING_IC74HC165 is not set -# CONFIG_PKG_USING_IST8310 is not set -# CONFIG_PKG_USING_ST7789_SPI is not set -# CONFIG_PKG_USING_SPI_TOOLS is not set -# end of peripheral libraries and drivers - -# -# AI packages -# -# CONFIG_PKG_USING_LIBANN is not set -# CONFIG_PKG_USING_NNOM is not set -# CONFIG_PKG_USING_ONNX_BACKEND is not set -# CONFIG_PKG_USING_ONNX_PARSER is not set -# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set -# CONFIG_PKG_USING_ELAPACK is not set -# CONFIG_PKG_USING_ULAPACK is not set -# CONFIG_PKG_USING_QUEST is not set -# CONFIG_PKG_USING_NAXOS is not set -# CONFIG_PKG_USING_R_TINYMAIX is not set -# CONFIG_PKG_USING_LLMCHAT is not set -# end of AI packages - -# -# Signal Processing and Control Algorithm Packages -# -# CONFIG_PKG_USING_APID is not set -# CONFIG_PKG_USING_FIRE_PID_CURVE is not set -# CONFIG_PKG_USING_QPID is not set -# CONFIG_PKG_USING_UKAL is not set -# CONFIG_PKG_USING_DIGITALCTRL is not set -# CONFIG_PKG_USING_KISSFFT is not set -# end of Signal Processing and Control Algorithm Packages - -# -# miscellaneous packages -# - -# -# project laboratory -# -# end of project laboratory - -# -# samples: kernel and components samples -# -# CONFIG_PKG_USING_KERNEL_SAMPLES is not set -# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set -# CONFIG_PKG_USING_NETWORK_SAMPLES is not set -# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set -# end of samples: kernel and components samples - -# -# entertainment: terminal games and other interesting software packages -# -# CONFIG_PKG_USING_CMATRIX is not set -# CONFIG_PKG_USING_SL is not set -# CONFIG_PKG_USING_CAL is not set -# CONFIG_PKG_USING_ACLOCK is not set -# CONFIG_PKG_USING_THREES is not set -# CONFIG_PKG_USING_2048 is not set -# CONFIG_PKG_USING_SNAKE is not set -# CONFIG_PKG_USING_TETRIS is not set -# CONFIG_PKG_USING_DONUT is not set -# CONFIG_PKG_USING_COWSAY is not set -# CONFIG_PKG_USING_MORSE is not set -# end of entertainment: terminal games and other interesting software packages - -# CONFIG_PKG_USING_LIBCSV is not set -# CONFIG_PKG_USING_OPTPARSE is not set -# CONFIG_PKG_USING_FASTLZ is not set -# CONFIG_PKG_USING_MINILZO is not set -# CONFIG_PKG_USING_QUICKLZ is not set -# CONFIG_PKG_USING_LZMA is not set -# CONFIG_PKG_USING_RALARAM is not set -# CONFIG_PKG_USING_MULTIBUTTON is not set -# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set -# CONFIG_PKG_USING_CANFESTIVAL is not set -# CONFIG_PKG_USING_ZLIB is not set -# CONFIG_PKG_USING_MINIZIP is not set -# CONFIG_PKG_USING_HEATSHRINK is not set -# CONFIG_PKG_USING_DSTR is not set -# CONFIG_PKG_USING_TINYFRAME is not set -# CONFIG_PKG_USING_KENDRYTE_DEMO is not set -# CONFIG_PKG_USING_UPACKER is not set -# CONFIG_PKG_USING_UPARAM is not set -# CONFIG_PKG_USING_HELLO is not set -# CONFIG_PKG_USING_VI is not set -# CONFIG_PKG_USING_KI is not set -# CONFIG_PKG_USING_ARMv7M_DWT is not set -# CONFIG_PKG_USING_CRCLIB is not set -# CONFIG_PKG_USING_LIBCRC is not set -# CONFIG_PKG_USING_LWGPS is not set -# CONFIG_PKG_USING_STATE_MACHINE is not set -# CONFIG_PKG_USING_DESIGN_PATTERN is not set -# CONFIG_PKG_USING_CONTROLLER is not set -# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set -# CONFIG_PKG_USING_MFBD is not set -# CONFIG_PKG_USING_SLCAN2RTT is not set -# CONFIG_PKG_USING_SOEM is not set -# CONFIG_PKG_USING_QPARAM is not set -# CONFIG_PKG_USING_CorevMCU_CLI is not set -# CONFIG_PKG_USING_DRMP is not set -# end of miscellaneous packages - -# -# Arduino libraries -# -# CONFIG_PKG_USING_RTDUINO is not set - -# -# Projects and Demos -# -# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set -# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set -# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set -# CONFIG_PKG_USING_ARDUINO_RTDUINO_SENSORFUSION_SHIELD is not set -# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set -# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set -# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set -# end of Projects and Demos - -# -# Sensors -# -# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31855 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MSA301 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_ITG3200 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_MP503 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set -# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set -# CONFIG_PKG_USING_ARDUINO_JARZEBSKI_MPU6050 is not set -# end of Sensors - -# -# Display -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set -# CONFIG_PKG_USING_ARDUINO_U8G2 is not set -# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set -# CONFIG_PKG_USING_SEEED_TM1637 is not set -# end of Display - -# -# Timing -# -# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set -# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set -# CONFIG_PKG_USING_ARDUINO_TICKER is not set -# CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set -# end of Timing - -# -# Data Processing -# -# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set -# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set -# CONFIG_PKG_USING_ARDUINO_TENSORFLOW_LITE_MICRO is not set -# CONFIG_PKG_USING_ARDUINO_RUNNINGMEDIAN is not set -# end of Data Processing - -# -# Data Storage -# - -# -# Communication -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set -# end of Communication - -# -# Device Control -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set -# end of Device Control - -# -# Other -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set -# end of Other - -# -# Signal IO -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set -# end of Signal IO - -# -# Uncategorized -# -# end of Arduino libraries -# end of RT-Thread online packages +CONFIG_PKG_USING_LVGL=y +CONFIG_PKG_LVGL_THREAD_STACK_SIZE=8192 +CONFIG_PKG_LVGL_THREAD_PRIO=10 +CONFIG_PKG_LVGL_DISP_REFR_PERIOD=33 # # RISC-V QEMU virt64 configs diff --git a/bsp/qemu-virt64-riscv/Kconfig b/bsp/qemu-virt64-riscv/Kconfig index 544753502b2..5347d59be6c 100644 --- a/bsp/qemu-virt64-riscv/Kconfig +++ b/bsp/qemu-virt64-riscv/Kconfig @@ -7,7 +7,7 @@ RTT_DIR := ../../ PKGS_DIR := packages source "$(RTT_DIR)/Kconfig" -osource "$PKGS_DIR/Kconfig" +osource "$(PKGS_DIR)/Kconfig" rsource "driver/Kconfig" config BOARD_QEMU_VIRT_RV64 diff --git a/bsp/qemu-virt64-riscv/applications/lvgl/SConscript b/bsp/qemu-virt64-riscv/applications/lvgl/SConscript new file mode 100644 index 00000000000..1b7f21a5377 --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/lvgl/SConscript @@ -0,0 +1,16 @@ +from building import * +import os + +cwd = GetCurrentDir() + +src = Glob('*.c') +inc = [cwd] + +lvgl_root = cwd + '/../../packages/lvgl-latest' +inc += [lvgl_root] +inc += [lvgl_root + '/src'] +inc += [lvgl_root + '/env_support/rt-thread'] + +group = DefineGroup('LVGL-app', src, depend = ['PKG_USING_LVGL'], CPPPATH = inc) + +Return('group') diff --git a/bsp/qemu-virt64-riscv/applications/lvgl/lv_conf.h b/bsp/qemu-virt64-riscv/applications/lvgl/lv_conf.h new file mode 100644 index 00000000000..c425b0b76e8 --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/lvgl/lv_conf.h @@ -0,0 +1,19 @@ +#ifndef LV_CONF_H +#define LV_CONF_H + +#ifdef __RTTHREAD__ +#include +#endif + +#define LV_COLOR_DEPTH 32 + +#define LV_HOR_RES_MAX 800 +#define LV_VER_RES_MAX 600 + +#define LV_USE_PERF_MONITOR 1 + +#define LV_FONT_MONTSERRAT_14 1 +#define LV_FONT_MONTSERRAT_16 1 +#define LV_FONT_MONTSERRAT_24 1 + +#endif diff --git a/bsp/qemu-virt64-riscv/applications/lvgl/lv_port_disp.c b/bsp/qemu-virt64-riscv/applications/lvgl/lv_port_disp.c new file mode 100644 index 00000000000..634fcc9534d --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/lvgl/lv_port_disp.c @@ -0,0 +1,81 @@ +#include +#include +#include + +#define DBG_TAG "lv_port_disp" +#define DBG_LVL DBG_INFO +#include + +static lv_disp_draw_buf_t disp_buf; +static lv_disp_drv_t disp_drv; +static rt_device_t gpu_device = 0; +static struct rt_device_graphic_info info; + +static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +{ + lv_color32_t *fbp32 = (lv_color32_t *)info.framebuffer; + int32_t x, y; + + for (y = area->y1; y <= area->y2; y++) + { + for (x = area->x1; x <= area->x2; x++) + { + fbp32[y * info.width + x].full = color_p->full; + color_p++; + } + } + + lv_disp_flush_ready(disp_drv); +} + +void lv_port_disp_init(void) +{ + rt_err_t result; + + gpu_device = rt_device_find("virtio-gpu0"); + if (gpu_device == RT_NULL) + { + LOG_E("virtio-gpu0 device not found"); + return; + } + + result = rt_device_open(gpu_device, RT_DEVICE_OFLAG_RDWR); + if (result != RT_EOK) + { + LOG_E("failed to open virtio-gpu0: %d", result); + return; + } + + result = rt_device_control(gpu_device, RTGRAPHIC_CTRL_GET_INFO, &info); + if (result != RT_EOK) + { + LOG_E("failed to get graphic info: %d", result); + return; + } + + LOG_I("framebuffer: %p, %dx%d, bpp=%d, format=%d", + info.framebuffer, info.width, info.height, + info.bits_per_pixel, info.pixel_format); + + lv_color_t *fbuf1 = rt_malloc(info.width * info.height * sizeof(lv_color_t)); + lv_color_t *fbuf2 = rt_malloc(info.width * info.height * sizeof(lv_color_t)); + if (fbuf1 == RT_NULL || fbuf2 == RT_NULL) + { + LOG_E("failed to allocate LVGL draw buffers"); + if (fbuf1) rt_free(fbuf1); + if (fbuf2) rt_free(fbuf2); + return; + } + + lv_disp_draw_buf_init(&disp_buf, fbuf1, fbuf2, info.width * info.height); + + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = info.width; + disp_drv.ver_res = info.height; + disp_drv.draw_buf = &disp_buf; + disp_drv.flush_cb = disp_flush; + + lv_disp_drv_register(&disp_drv); + + LOG_I("LVGL display port initialized"); +} diff --git a/bsp/qemu-virt64-riscv/applications/lvgl/lv_port_indev.c b/bsp/qemu-virt64-riscv/applications/lvgl/lv_port_indev.c new file mode 100644 index 00000000000..d5e40e69118 --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/lvgl/lv_port_indev.c @@ -0,0 +1,7 @@ +#include +#include + +void lv_port_indev_init(void) +{ + /* no input devices yet */ +} diff --git a/bsp/qemu-virt64-riscv/applications/lvgl/lvgl_demo.c b/bsp/qemu-virt64-riscv/applications/lvgl/lvgl_demo.c new file mode 100644 index 00000000000..d6a979eb105 --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/lvgl/lvgl_demo.c @@ -0,0 +1,49 @@ +#include +#include + +static void btn_event_cb(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_CLICKED) + { + rt_kprintf("LVGL button clicked!\n"); + } +} + +static lv_obj_t *label; + +static void slider_event_cb(lv_event_t *e) +{ + lv_obj_t *slider = lv_event_get_target(e); + lv_label_set_text_fmt(label, "%d%%", (int)lv_slider_get_value(slider)); + lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -10); +} + +void lv_user_gui_init(void) +{ + lv_obj_t *scr = lv_scr_act(); + + lv_obj_t *title = lv_label_create(scr); + lv_label_set_text(title, "Hello RT-Thread + LVGL!"); + lv_obj_set_style_text_color(title, lv_color_white(), 0); + lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 20); + + lv_obj_t *btn = lv_btn_create(scr); + lv_obj_set_size(btn, 120, 50); + lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t *btn_label = lv_label_create(btn); + lv_label_set_text(btn_label, "Click Me!"); + + lv_obj_t *slider = lv_slider_create(scr); + lv_obj_set_width(slider, 200); + lv_obj_align(slider, LV_ALIGN_BOTTOM_MID, 0, -40); + lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + + label = lv_label_create(scr); + lv_label_set_text(label, "0%"); + lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -10); + + rt_kprintf("LVGL user GUI initialized\n"); +} diff --git a/bsp/qemu-virt64-riscv/driver/board.c b/bsp/qemu-virt64-riscv/driver/board.c index 7250159e300..7bf6581b5d9 100644 --- a/bsp/qemu-virt64-riscv/driver/board.c +++ b/bsp/qemu-virt64-riscv/driver/board.c @@ -28,6 +28,14 @@ #include "interrupt.h" #endif /* RT_USING_SMP */ +#ifdef RT_USING_OFW +#include +#endif + +#ifdef RT_USING_DM +#include +#endif + #ifdef RT_USING_SMART #include "riscv_mmu.h" #include "mmu.h" @@ -46,6 +54,84 @@ struct mem_desc platform_mem_desc[] = { #endif +#ifdef RT_USING_OFW +#define QEMU_RISCV_FDT_MAX_SIZE (256 * 1024) + +extern rt_ubase_t boot_fdt_addr; + +static rt_align(8) rt_uint8_t qemu_riscv_fdt[QEMU_RISCV_FDT_MAX_SIZE]; +static void *qemu_riscv_fdt_ptr; + +static void qemu_riscv_fdt_copy_early(void) +{ + void *fdt; + rt_size_t fdt_size; + + if (!boot_fdt_addr) + { + rt_kprintf("OFW: boot FDT address is empty\n"); + return; + } + +#ifdef RT_USING_SMART + fdt = (void *)(boot_fdt_addr - PV_OFFSET); +#else + fdt = (void *)boot_fdt_addr; +#endif + + if (fdt_check_header(fdt)) + { + rt_kprintf("OFW: invalid boot FDT at %p\n", (void *)boot_fdt_addr); + return; + } + + fdt_size = fdt_totalsize(fdt); + if (fdt_size > sizeof(qemu_riscv_fdt)) + { + rt_kprintf("OFW: boot FDT is too large: %u > %u\n", + (unsigned int)fdt_size, (unsigned int)sizeof(qemu_riscv_fdt)); + return; + } + + rt_memcpy(qemu_riscv_fdt, fdt, fdt_size); + qemu_riscv_fdt_ptr = qemu_riscv_fdt; +} + +static void qemu_riscv_ofw_init(void) +{ + rt_err_t err; + + if (!qemu_riscv_fdt_ptr) + { + return; + } + + err = rt_fdt_prefetch(qemu_riscv_fdt_ptr); + if (err) + { + rt_kprintf("OFW: FDT prefetch failed: %d\n", err); + return; + } + + rt_fdt_scan_chosen_stdout(); + rt_fdt_scan_memory(); + + err = rt_fdt_unflatten(); + if (err) + { + rt_kprintf("OFW: FDT unflatten failed: %d\n", err); + } +} +#endif + +static void qemu_riscv_machine_shutdown(void) +{ + sbi_shutdown(); + + while (1) + ; +} + rt_uint64_t rt_hw_get_clock_timer_freq(void) { return 10000000ULL; @@ -73,6 +159,10 @@ void rt_hw_board_init(void) /* init data structure */ rt_hw_mmu_map_init(&rt_kernel_space, (void *)(IOREMAP_VEND - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, PV_OFFSET); +#ifdef RT_USING_OFW + qemu_riscv_fdt_copy_early(); +#endif + /* init page allocator */ rt_page_init(init_page_region); @@ -85,6 +175,15 @@ void rt_hw_board_init(void) rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); #endif +#ifdef RT_USING_OFW + qemu_riscv_ofw_init(); +#endif + +#ifdef RT_USING_DM + rt_dm_machine_shutdown = qemu_riscv_machine_shutdown; + rt_dm_machine_reset = qemu_riscv_machine_shutdown; +#endif + plic_init(); rt_hw_interrupt_init(); @@ -112,11 +211,10 @@ void rt_hw_board_init(void) #endif /* RT_USING_HEAP */ } +#ifndef RT_USING_DM void rt_hw_cpu_reset(void) { - sbi_shutdown(); - - while (1) - ; + qemu_riscv_machine_shutdown(); } MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine); +#endif diff --git a/bsp/qemu-virt64-riscv/driver/drv_libc_stubs.c b/bsp/qemu-virt64-riscv/driver/drv_libc_stubs.c new file mode 100644 index 00000000000..973d67ec1f1 --- /dev/null +++ b/bsp/qemu-virt64-riscv/driver/drv_libc_stubs.c @@ -0,0 +1,33 @@ +/* libc stubs for qemu-virt64-riscv — override toolchain libc with non-vector implementations */ + +#include + +void *memcpy(void *dest, const void *src, size_t n) +{ + const char *s = (const char *)src; + char *d = (char *)dest; + size_t i; + for (i = 0; i < n; i++) + d[i] = s[i]; + return dest; +} + +void *memset(void *s, int c, size_t n) +{ + char *p = (char *)s; + size_t i; + for (i = 0; i < n; i++) + p[i] = (char)c; + return s; +} + +int memcmp(const void *s1, const void *s2, size_t n) +{ + const unsigned char *a = (const unsigned char *)s1; + const unsigned char *b = (const unsigned char *)s2; + size_t i; + for (i = 0; i < n; i++) + if (a[i] != b[i]) + return (int)a[i] - (int)b[i]; + return 0; +} diff --git a/bsp/qemu-virt64-riscv/link_cpus.lds b/bsp/qemu-virt64-riscv/link_cpus.lds index 2659b2befb4..e4cd5b88712 100644 --- a/bsp/qemu-virt64-riscv/link_cpus.lds +++ b/bsp/qemu-virt64-riscv/link_cpus.lds @@ -1 +1 @@ -RT_CPUS_NR = 8; +RT_CPUS_NR = 1; diff --git a/bsp/qemu-virt64-riscv/packages/Kconfig b/bsp/qemu-virt64-riscv/packages/Kconfig new file mode 100644 index 00000000000..bbb26eeef3c --- /dev/null +++ b/bsp/qemu-virt64-riscv/packages/Kconfig @@ -0,0 +1,21 @@ +config PKG_USING_LVGL + bool "LVGL: powerful and easy-to-use embedded GUI library" + default n + help + LVGL is a free and open-source embedded graphic library. + +if PKG_USING_LVGL + +config PKG_LVGL_THREAD_STACK_SIZE + int "LVGL thread stack size" + default 8192 + +config PKG_LVGL_THREAD_PRIO + int "LVGL thread priority" + default 10 + +config PKG_LVGL_DISP_REFR_PERIOD + int "LVGL display refresh period (ms)" + default 33 + +endif diff --git a/bsp/qemu-virt64-riscv/rtconfig.h b/bsp/qemu-virt64-riscv/rtconfig.h index 430730ff68c..e5d6f721dd1 100644 --- a/bsp/qemu-virt64-riscv/rtconfig.h +++ b/bsp/qemu-virt64-riscv/rtconfig.h @@ -72,7 +72,8 @@ /* end of rt_strnlen options */ /* end of klibc options */ -#define RT_NAME_MAX 24 +#define RT_NAME_MAX 32 +#define RT_USING_SMART #define RT_CPUS_NR 1 #define RT_ALIGN_SIZE 8 #define RT_THREAD_PRIORITY_32 @@ -88,6 +89,7 @@ #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 16384 #define RT_USING_CPU_USAGE_TRACER +#define RT_CPU_USAGE_CALC_INTERVAL_MS 200 /* kservice options */ @@ -120,13 +122,15 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 256 #define RT_CONSOLE_DEVICE_NAME "uart0" -#define RT_VER_NUM 0x50201 +#define RT_USING_CONSOLE_OUTPUT_CTL +#define RT_VER_NUM 0x50300 #define RT_USING_STDC_ATOMIC #define RT_BACKTRACE_LEVEL_MAX_NR 32 /* end of RT-Thread Kernel */ #define ARCH_CPU_64BIT #define RT_USING_CACHE #define ARCH_MM_MMU +#define KERNEL_VADDR_START 0xffffffc000000000 #define ARCH_RISCV #define ARCH_RISCV_FPU #define ARCH_RISCV64 @@ -180,10 +184,24 @@ /* end of elm-chan's FatFs, Generic FAT Filesystem Module */ #define RT_USING_DFS_DEVFS #define RT_USING_DFS_ROMFS +#define RT_USING_DFS_PTYFS +#define RT_USING_PAGECACHE + +/* page cache config */ + +#define RT_PAGECACHE_COUNT 4096 +#define RT_PAGECACHE_ASPACE_COUNT 1024 +#define RT_PAGECACHE_PRELOAD 4 +#define RT_PAGECACHE_HASH_NR 1024 +#define RT_PAGECACHE_GC_WORK_LEVEL 90 +#define RT_PAGECACHE_GC_STOP_LEVEL 70 +/* end of page cache config */ /* end of DFS: device virtual file system */ /* Device Drivers */ +#define RT_USING_DM +#define RT_USING_DEV_BUS #define RT_USING_DEVICE_IPC #define RT_UNAMED_PIPE_NUMBER 64 #define RT_USING_SYSTEM_WORKQUEUE @@ -193,14 +211,18 @@ #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_CPUTIME -#define RT_USING_CPUTIME_RISCV -#define CPUTIME_TIMER_FREQ 10000000 +#define RT_USING_SERIAL_BYPASS +#define RT_USING_CLOCK_TIME +#define CLOCK_TIMER_FREQ 0 #define RT_USING_NULL #define RT_USING_ZERO #define RT_USING_RANDOM #define RT_USING_RTC #define RT_USING_SOFT_RTC + +/* Power Management (PM) Domains device drivers */ + +/* end of Power Management (PM) Domains device drivers */ #define RT_USING_VIRTIO #define RT_USING_VIRTIO10 #define RT_USING_VIRTIO_BLK @@ -209,8 +231,14 @@ #define RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR 4 #define RT_USING_VIRTIO_GPU #define RT_USING_VIRTIO_INPUT +#define RT_USING_OFW +#define RT_FDT_EARLYCON_MSG_SIZE 128 +#define RT_USING_OFW_BUS_RANGES_NUMBER 8 #define RT_USING_PIN -#define RT_USING_KTIME +#define RT_USING_CLK + +/* SoC (System on Chip) Drivers */ + /* end of Device Drivers */ /* C/C++ and POSIX layer */ @@ -233,6 +261,9 @@ #define RT_USING_POSIX_STDIO #define RT_USING_POSIX_POLL #define RT_USING_POSIX_SELECT +#define RT_USING_POSIX_EPOLL +#define RT_USING_POSIX_SIGNALFD +#define RT_SIGNALFD_MAX_NUM 10 #define RT_USING_POSIX_TERMIOS #define RT_USING_POSIX_AIO #define RT_USING_POSIX_DELAY @@ -320,6 +351,10 @@ /* Utilities */ +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 4096 +#define UTEST_THR_PRIORITY 20 +#define RT_UTEST_MAX_OPTIONS 64 #define RT_USING_RESOURCE_ID #define RT_USING_ADT #define RT_USING_ADT_AVL @@ -332,11 +367,23 @@ #define RT_PAGE_AFFINITY_BLOCK_SIZE 0x1000 #define RT_PAGE_MAX_ORDER 11 +#define RT_USING_MEMBLOCK +#define RT_INIT_MEMORY_REGIONS 128 /* Debugging */ /* end of Debugging */ /* end of Memory management */ +#define RT_USING_LWP +#define LWP_USING_RUNTIME +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_TID_MAX_NR 64 +#define RT_LWP_SHM_MAX_NR 64 +#define RT_USING_LDSO +#define LWP_USING_TERMINAL +#define LWP_PTY_MAX_PARIS_LIMIT 64 /* Using USB legacy version */ @@ -346,207 +393,10 @@ /* RT-Thread Utestcases */ /* end of RT-Thread Utestcases */ - -/* RT-Thread online packages */ - -/* IoT - internet of things */ - - -/* Wi-Fi */ - -/* Marvell WiFi */ - -/* end of Marvell WiFi */ - -/* Wiced WiFi */ - -/* end of Wiced WiFi */ - -/* CYW43012 WiFi */ - -/* end of CYW43012 WiFi */ - -/* BL808 WiFi */ - -/* end of BL808 WiFi */ - -/* CYW43439 WiFi */ - -/* end of CYW43439 WiFi */ -/* end of Wi-Fi */ - -/* IoT Cloud */ - -/* end of IoT Cloud */ -/* end of IoT - internet of things */ - -/* security packages */ - -/* end of security packages */ - -/* language packages */ - -/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ - -/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */ - -/* XML: Extensible Markup Language */ - -/* end of XML: Extensible Markup Language */ -/* end of language packages */ - -/* multimedia packages */ - -/* LVGL: powerful and easy-to-use embedded GUI library */ - -/* end of LVGL: powerful and easy-to-use embedded GUI library */ - -/* u8g2: a monochrome graphic library */ - -/* end of u8g2: a monochrome graphic library */ -/* end of multimedia packages */ - -/* tools packages */ - -/* end of tools packages */ - -/* system packages */ - -/* enhanced kernel services */ - -/* end of enhanced kernel services */ - -/* acceleration: Assembly language or algorithmic acceleration packages */ - -/* end of acceleration: Assembly language or algorithmic acceleration packages */ - -/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ - -/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ - -/* Micrium: Micrium software products porting for RT-Thread */ - -/* end of Micrium: Micrium software products porting for RT-Thread */ -/* end of system packages */ - -/* peripheral libraries and drivers */ - -/* HAL & SDK Drivers */ - -/* STM32 HAL & SDK Drivers */ - -/* end of STM32 HAL & SDK Drivers */ - -/* Infineon HAL Packages */ - -/* end of Infineon HAL Packages */ - -/* Kendryte SDK */ - -/* end of Kendryte SDK */ - -/* WCH HAL & SDK Drivers */ - -/* end of WCH HAL & SDK Drivers */ - -/* AT32 HAL & SDK Drivers */ - -/* end of AT32 HAL & SDK Drivers */ - -/* HC32 DDL Drivers */ - -/* end of HC32 DDL Drivers */ - -/* NXP HAL & SDK Drivers */ - -/* end of NXP HAL & SDK Drivers */ - -/* NUVOTON Drivers */ - -/* end of NUVOTON Drivers */ - -/* GD32 Drivers */ - -/* end of GD32 Drivers */ -/* end of HAL & SDK Drivers */ - -/* sensors drivers */ - -/* end of sensors drivers */ - -/* touch drivers */ - -/* end of touch drivers */ -/* end of peripheral libraries and drivers */ - -/* AI packages */ - -/* end of AI packages */ - -/* Signal Processing and Control Algorithm Packages */ - -/* end of Signal Processing and Control Algorithm Packages */ - -/* miscellaneous packages */ - -/* project laboratory */ - -/* end of project laboratory */ - -/* samples: kernel and components samples */ - -/* end of samples: kernel and components samples */ - -/* entertainment: terminal games and other interesting software packages */ - -/* end of entertainment: terminal games and other interesting software packages */ -/* end of miscellaneous packages */ - -/* Arduino libraries */ - - -/* Projects and Demos */ - -/* end of Projects and Demos */ - -/* Sensors */ - -/* end of Sensors */ - -/* Display */ - -/* end of Display */ - -/* Timing */ - -/* end of Timing */ - -/* Data Processing */ - -/* end of Data Processing */ - -/* Data Storage */ - -/* Communication */ - -/* end of Communication */ - -/* Device Control */ - -/* end of Device Control */ - -/* Other */ - -/* end of Other */ - -/* Signal IO */ - -/* end of Signal IO */ - -/* Uncategorized */ - -/* end of Arduino libraries */ -/* end of RT-Thread online packages */ +#define PKG_USING_LVGL +#define PKG_LVGL_THREAD_STACK_SIZE 8192 +#define PKG_LVGL_THREAD_PRIO 10 +#define PKG_LVGL_DISP_REFR_PERIOD 33 /* RISC-V QEMU virt64 configs */ @@ -561,4 +411,6 @@ #define ENABLE_FPU #define __STACKSIZE__ 16384 +#define PKG_USING_LWEXT4 +#define RT_USING_DFS_LWEXT4 #endif diff --git a/bsp/qemu-virt64-riscv/rtconfig.py b/bsp/qemu-virt64-riscv/rtconfig.py index 09d530af4a1..ab43271b222 100644 --- a/bsp/qemu-virt64-riscv/rtconfig.py +++ b/bsp/qemu-virt64-riscv/rtconfig.py @@ -21,7 +21,7 @@ if PLATFORM == 'gcc': # toolchains - PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-elf-' + PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-linux-musleabi-' CC = PREFIX + 'gcc' CXX = PREFIX + 'g++' AS = PREFIX + 'gcc' @@ -32,10 +32,10 @@ OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64 ' - CFLAGS = DEVICE + '-ffreestanding -flax-vector-conversions -Wno-cpp -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fdiagnostics-color=always' + DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64d ' + CFLAGS = DEVICE + '-ffreestanding -fno-builtin -flax-vector-conversions -Wno-cpp -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fdiagnostics-color=always' AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ ' - LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static' + LFLAGS = DEVICE + ' -nostartfiles -nostdlib -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static' CPATH = '' LPATH = '' diff --git a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c index 90b87a178b4..1f15adad7c7 100644 --- a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c @@ -444,7 +444,7 @@ int dfs_elm_open(struct dfs_file *file) } file->vnode->data = dir; - rt_mutex_init(&file->vnode->lock, file->dentry->pathname, RT_IPC_FLAG_PRIO); + rt_mutex_init(&file->vnode->lock, "elm_vn", RT_IPC_FLAG_PRIO); return RT_EOK; } else @@ -485,7 +485,7 @@ int dfs_elm_open(struct dfs_file *file) file->vnode->size = f_size(fd); file->vnode->type = FT_REGULAR; file->vnode->data = fd; - rt_mutex_init(&file->vnode->lock, file->dentry->pathname, RT_IPC_FLAG_PRIO); + rt_mutex_init(&file->vnode->lock, "elm_vn", RT_IPC_FLAG_PRIO); if (file->flags & O_APPEND) { diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c index 1dc1fd54f9e..79039b8acbf 100644 --- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c +++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c @@ -455,7 +455,7 @@ static int dfs_tmpfs_open(struct dfs_file *file) RT_ASSERT(file->vnode->ref_count > 0); if(file->vnode->ref_count == 1) { - rt_mutex_init(&file->vnode->lock, file->dentry->pathname, RT_IPC_FLAG_PRIO); + rt_mutex_init(&file->vnode->lock, "tmp_vn", RT_IPC_FLAG_PRIO); } return 0; diff --git a/components/drivers/sdio/dev_block.c b/components/drivers/sdio/dev_block.c index d4f8f62885d..ed4c4c3cad5 100644 --- a/components/drivers/sdio/dev_block.c +++ b/components/drivers/sdio/dev_block.c @@ -375,7 +375,6 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) host->max_dma_segs * host->max_seg_size, host->max_blk_count * host->max_blk_size) >> 9; blk_dev->geometry.bytes_per_sector = 1 << 9; - blk_dev->geometry.block_size = card->card_blksize; blk_dev->geometry.sector_count = card->card_capacity * (1024 / 512); /* Set blk size before partitions probe, Why? */ @@ -383,6 +382,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) { goto _fail; } + blk_dev->geometry.block_size = blk_dev->geometry.bytes_per_sector; rt_thread_mdelay(1); #ifdef RT_USING_DM diff --git a/components/lwp/lwp_elf.c b/components/lwp/lwp_elf.c index c6809f8cae2..3ec49bd227e 100644 --- a/components/lwp/lwp_elf.c +++ b/components/lwp/lwp_elf.c @@ -616,6 +616,15 @@ static int elf_zero_bss(struct rt_lwp *lwp, int fd, const Elf_Phdr *phdr, rt_uba * @return -RT_ERROR if memory mapping fails. * @return -ENOMEM if memory allocation fails. */ +static size_t elf_prot_from_pflags(uint32_t p_flags) +{ + size_t prot = PROT_NONE; + if (p_flags & PF_R) prot |= PROT_READ; + if (p_flags & PF_W) prot |= PROT_WRITE; + if (p_flags & PF_X) prot |= PROT_EXEC; + return prot; +} + static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ubase_t *elfload_addr, rt_uint32_t map_size, rt_ubase_t *load_base) { @@ -626,7 +635,6 @@ static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ub const Elf_Phdr *tmp_phdr = phdr; /* Current program header */ int fd = elf_info->fd; /* File descriptor for ELF file */ rt_ubase_t load_addr; /* Calculated load address */ - size_t prot = PROT_READ | PROT_WRITE; /* Memory protection flags */ size_t flags = MAP_FIXED | MAP_PRIVATE; /* Memory mapping flags */ /* Iterate through all program headers */ @@ -659,8 +667,8 @@ static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ub flags &= ~MAP_FIXED; } - /* Map the segment into memory */ - map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, prot, flags, map_size); + /* Map the segment into memory with correct permissions */ + map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, elf_prot_from_pflags(tmp_phdr->p_flags), flags, map_size); if (!map_va) { LOG_E("%s : elf_map failed", __func__); diff --git a/components/mm/mm_fault.c b/components/mm/mm_fault.c index 01e32fed95c..f659cb8456b 100644 --- a/components/mm/mm_fault.c +++ b/components/mm/mm_fault.c @@ -33,6 +33,9 @@ static int _fetch_page(rt_varea_t varea, struct rt_aspace_fault_msg *msg) err = rt_varea_map_with_msg(varea, msg); err = (err == RT_EOK ? MM_FAULT_FIXABLE_TRUE : MM_FAULT_FIXABLE_FALSE); } + else + { + } return err; } @@ -101,6 +104,10 @@ static int _exec_fault(rt_varea_t varea, void *pa, struct rt_aspace_fault_msg *m RT_ASSERT(!(varea->flag & MMF_PREFETCH)); err = _fetch_page(varea, msg); } + else + { + /* signal a fault to user? */ + } return err; } diff --git a/libcpu/Kconfig b/libcpu/Kconfig index 1185c495214..d1046f1ac19 100644 --- a/libcpu/Kconfig +++ b/libcpu/Kconfig @@ -288,6 +288,10 @@ config ARCH_RISCV64 select ARCH_CPU_64BIT bool +config ARCH_RISCV_XUANTIE + select ARCH_RISCV + bool + if ARCH_RISCV64 config ARCH_USING_NEW_CTX_SWITCH bool @@ -300,6 +304,14 @@ if ARCH_RISCV64 select ARCH_USING_NEW_CTX_SWITCH help Using the common64 implementation under ./libcpu/risc-v + +if RT_USING_SMART + config CONFIG_XUANTIE_SVPBMT + int + depends on ARCH_RISCV_XUANTIE + default 1 +endif + endif config ARCH_REMAP_KERNEL diff --git a/libcpu/risc-v/common64/mmu.c b/libcpu/risc-v/common64/mmu.c index d88982d5136..60ca9f423a0 100644 --- a/libcpu/risc-v/common64/mmu.c +++ b/libcpu/risc-v/common64/mmu.c @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -84,6 +85,20 @@ void rt_hw_aspace_switch(rt_aspace_t aspace) uint32_t hartid = rt_cpu_get_id(); uintptr_t ptr = (uintptr_t)aspace->page_table + (uintptr_t)(hartid * ARCH_PAGE_SIZE); uintptr_t page_table = (uintptr_t)rt_kmem_v2p((void *)ptr); + + if (page_table == (uintptr_t)ARCH_MAP_FAILED) + { + /* + * During early K230 bring-up the kernel still runs with low physical + * pointers after relocation, including MMUTable. The formal kernel + * aspace does not translate that low pointer yet, but SATP needs the + * physical page-table address, so use the low address directly. + */ + if (ptr < KERNEL_VADDR_START) + { + page_table = ptr; + } + } #ifndef RT_USING_SMP current_mmu_table = aspace->page_table; #else @@ -561,14 +576,14 @@ static inline void _init_region(void *vaddr, size_t size) { rt_ioremap_start = vaddr; rt_ioremap_size = size; - rt_mpr_start = rt_ioremap_start - rt_mpr_size; + rt_mpr_start = (void *)((rt_ubase_t)rt_ioremap_start - rt_mpr_size); LOG_D("rt_ioremap_start: %p, rt_mpr_start: %p", rt_ioremap_start, rt_mpr_start); } #else static inline void _init_region(void *vaddr, size_t size) { - rt_mpr_start = vaddr - rt_mpr_size; + rt_mpr_start = (void *)((rt_ubase_t)vaddr - rt_mpr_size); } #endif @@ -955,6 +970,9 @@ void rt_hw_mem_setup_early(void *pgtbl, rt_uint64_t hartid) vs += L2_PAGE_SIZE; } #endif + /* flush page table entries from data cache before enabling MMU */ + rt_hw_cpu_dcache_clean(early_pgtbl, ARCH_PAGE_SIZE); + /* apply new mapping */ asm volatile("sfence.vma x0, x0"); write_csr(satp, SATP_BASE | ((size_t)early_pgtbl >> PAGE_OFFSET_BIT)); @@ -982,6 +1000,19 @@ void *rt_hw_mmu_pgtbl_create(void) return RT_NULL; } rt_memcpy(mmu_table, rt_kernel_space.page_table, ARCH_PAGE_SIZE); + +#ifdef RT_USING_SMART + { + int i; + int start_idx = USER_VADDR_START >> VPN2_SHIFT; + int end_idx = USER_VADDR_TOP >> VPN2_SHIFT; + for (i = start_idx; i <= end_idx; i++) + { + mmu_table[i] = 0; + } + } +#endif + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE); return mmu_table; diff --git a/libcpu/risc-v/common64/startup_gcc.S b/libcpu/risc-v/common64/startup_gcc.S index dde3c092408..63b0ff49b5b 100644 --- a/libcpu/risc-v/common64/startup_gcc.S +++ b/libcpu/risc-v/common64/startup_gcc.S @@ -18,6 +18,10 @@ .global boot_hartid /* global varible rt_boot_hartid in .data section */ boot_hartid: .word 0xdeadbeef + .align 3 + .global boot_fdt_addr +boot_fdt_addr: + .dword 0 .global _start .section ".start", "ax" @@ -41,6 +45,8 @@ _start: #endif mv t1, a0 /* get hartid in S-mode frome a0 register */ sw t1, (t0) /* store t1 register low 4 bits in memory address which is stored in t0 */ + la t0, boot_fdt_addr /* QEMU/OpenSBI passes FDT address in a1 */ + sd a1, (t0) #ifdef RT_USING_SMP system_init: @@ -236,4 +242,4 @@ _start_link_addr: .space RT_CPUS_NR * 5 * page_size #endif -#endif /* ARCH_MM_MMU */ \ No newline at end of file +#endif /* ARCH_MM_MMU */