diff --git a/ReleaseNote.md b/ReleaseNote.md index 058515b60..2952a7ca8 100644 --- a/ReleaseNote.md +++ b/ReleaseNote.md @@ -1,3 +1,48 @@ +# V1.3.0 # + +## 新增 ## +- USB: + - 支持MTP功能 + - 支持指定EP地址 +- MPP:支持AAC raw data的解码 +- Display:支持AiPQ工具的接口自动识别功能 +- PBP:支持预定义IO的状态 +- SPI:支持用户态动态调整SPI的clock频率 +- LVGL: + - 新增控件:lyrics_effect(歌词特效)、aic_canvas、aic_player +- 增加aishoot_demo +- RTP:支持作为普通ADC使用 +- WiFi:aic8800增加monitor功能 +- 增加歌词特效的功能,支持以视频播放作为背景 +- 新增方案:双系统双显、aishoot +- 新增示例:test_battery、http-wificonfig +- 新增器件: +- NAND:PY25Q128HA、XCSP1AAPK-IT +- 屏幕:nv3051、gh8555bc + +## 优化 ## +- LVGL V9: + - 优化软件绘图的stride处理 + - 优化FreeType的多线程访问 +- MPP:优化视频播放的文件切换流程 +- SPL: + - 使用硬件Gzip解压Kernel + - 优化Boot logo的兼容处理 +- Boot:优化SPI的delay参数配置流程 +- Display:优化Vsync的处理流程 +- SPI:完善工作模式的容错处理 +- NAND: + - 优化OOB layout的处理流程 + - 优化ECC的获取接口 + - 完善Boot中的BBT处理流程 +- winbond:兼容3Byte ID的型号 +- NOR:优化擦写的容错处理 + +## 修改 ## +- SPL:demo88_nor配置默认打开Falcon模式 + + + # V1.2.9 # ## 新增 ## diff --git a/dl/.commit b/dl/.commit index 03df2293a..36d1af4b3 100644 --- a/dl/.commit +++ b/dl/.commit @@ -1 +1 @@ -51249f6af42675458ef777ac49830c844c4266dc +52b44675ba49987bdf12cb3e81239d515b908877 diff --git a/dl/aic8800_fw/aic8800_fw-1.0.tar.gz b/dl/aic8800_fw/aic8800_fw-1.0.tar.gz deleted file mode 100644 index d33f0a6d1..000000000 Binary files a/dl/aic8800_fw/aic8800_fw-1.0.tar.gz and /dev/null differ diff --git a/dl/aic8800_fw/aic8800_fw-2.0.tar.gz b/dl/aic8800_fw/aic8800_fw-2.0.tar.gz new file mode 100644 index 000000000..e171f621c Binary files /dev/null and b/dl/aic8800_fw/aic8800_fw-2.0.tar.gz differ diff --git a/dl/libfuse/fuse-2.9.9.tar.gz b/dl/libfuse/fuse-2.9.9.tar.gz new file mode 100644 index 000000000..ae84512e9 Binary files /dev/null and b/dl/libfuse/fuse-2.9.9.tar.gz differ diff --git a/dl/libiconv/libiconv-1.18.tar.gz b/dl/libiconv/libiconv-1.18.tar.gz new file mode 100644 index 000000000..8d9151e9d Binary files /dev/null and b/dl/libiconv/libiconv-1.18.tar.gz differ diff --git a/dl/libmtp/libmtp-1.1.22.tar.gz b/dl/libmtp/libmtp-1.1.22.tar.gz new file mode 100644 index 000000000..d78648b9e Binary files /dev/null and b/dl/libmtp/libmtp-1.1.22.tar.gz differ diff --git a/dl/libusb/libusb-1.0.23.tar.bz2 b/dl/libusb/libusb-1.0.23.tar.bz2 new file mode 100644 index 000000000..661efd8a7 Binary files /dev/null and b/dl/libusb/libusb-1.0.23.tar.bz2 differ diff --git a/dl/mtpfs/mtpfs-1.0.tar.gz b/dl/mtpfs/mtpfs-1.0.tar.gz new file mode 100644 index 000000000..943004a4f Binary files /dev/null and b/dl/mtpfs/mtpfs-1.0.tar.gz differ diff --git a/dl/umtprd/umtprd-1.6.8.tar.gz b/dl/umtprd/umtprd-1.6.8.tar.gz new file mode 100644 index 000000000..8a356914a Binary files /dev/null and b/dl/umtprd/umtprd-1.6.8.tar.gz differ diff --git a/package/.commit b/package/.commit index 6efdf1d31..ab32c2a83 100644 --- a/package/.commit +++ b/package/.commit @@ -1 +1 @@ -22f3e30f76abdbaa773d16010976a269ff49b5ec +7150ec57051b1b395bba363863bb0869d7db4b97 diff --git a/package/artinchip/Config.in b/package/artinchip/Config.in index 1cdd5f3b0..39bf11e2b 100644 --- a/package/artinchip/Config.in +++ b/package/artinchip/Config.in @@ -12,6 +12,7 @@ source package/artinchip/aicp-dec/Config.in source package/artinchip/aic-mem/Config.in source package/artinchip/wifimanager/Config.in source package/artinchip/p2p_auto/Config.in +source package/artinchip/http-wificonfig/Config.in menu "Sample code" source package/artinchip/test-mtop/Config.in @@ -25,6 +26,7 @@ menu "Sample code" source package/artinchip/test-libmad/Config.in source package/artinchip/test-clock/Config.in source package/artinchip/test-keyadc/Config.in + source package/artinchip/test-battery/Config.in source package/artinchip/reg-dump/Config.in source package/artinchip/test-gpio/Config.in source package/artinchip/test-can/Config.in diff --git a/package/artinchip/http-wificonfig/Config.in b/package/artinchip/http-wificonfig/Config.in new file mode 100644 index 000000000..702191d2b --- /dev/null +++ b/package/artinchip/http-wificonfig/Config.in @@ -0,0 +1,4 @@ +config BR2_PACKAGE_HTTP_WIFICONFIG + bool "Enable artinchip http-wificonfig" + default n + diff --git a/package/artinchip/http-wificonfig/http-wificonfig.mk b/package/artinchip/http-wificonfig/http-wificonfig.mk new file mode 100644 index 000000000..3076814a3 --- /dev/null +++ b/package/artinchip/http-wificonfig/http-wificonfig.mk @@ -0,0 +1,9 @@ +HTTP_WIFICONFIG_VERSION = +HTTP_WIFICONFIG_ENABLE_TARBALL = NO +HTTP_WIFICONFIG_ENABLE_PATCH = NO +HTTP_WIFICONFIG_INSTALL_STAGING = YES +HTTP_WIFICONFIG_CONF_OPTS += -DCMAKE_INSTALL_PREFIX=/usr/local +HTTP_WIFICONFIG_DEPENDENCIES += wifimanager + +$(eval $(cmake-package)) + diff --git a/package/artinchip/lvgl-ui/lvgl-ui.mk b/package/artinchip/lvgl-ui/lvgl-ui.mk index ede1f6799..93c96754f 100644 --- a/package/artinchip/lvgl-ui/lvgl-ui.mk +++ b/package/artinchip/lvgl-ui/lvgl-ui.mk @@ -84,6 +84,8 @@ else LVGL_UI_CONF_OPTS += -DUSE_FREETYPE=no endif +LVGL_UI_CONF_OPTS += -DBUILD_DIR=$(BUILD_DIR) + ifeq ($(BR2_PACKAGE_AIC_MEM),y) LVGL_UI_DEPENDENCIES += aic-mem LVGL_UI_CONF_OPTS += -DUSE_AIC_MEM=yes diff --git a/package/artinchip/test-battery/Config.in b/package/artinchip/test-battery/Config.in new file mode 100644 index 000000000..5b411bfa7 --- /dev/null +++ b/package/artinchip/test-battery/Config.in @@ -0,0 +1,9 @@ +menuconfig BR2_PACKAGE_TEST_BATTERY + bool "test-battery" + default n + +if BR2_PACKAGE_TEST_BATTERY +config BR2_PACKAGE_TEST_BATTERY_USE_PREBUILT + bool "use prebuilt binary instead of building from source" + default n +endif diff --git a/package/artinchip/test-battery/test-battery.mk b/package/artinchip/test-battery/test-battery.mk new file mode 100644 index 000000000..075bffd9f --- /dev/null +++ b/package/artinchip/test-battery/test-battery.mk @@ -0,0 +1,8 @@ +TEST_BATTERY_VERSION = +TEST_BATTERY_ENABLE_TARBALL = NO +TEST_BATTERY_ENABLE_PATCH = NO + +TEST_BATTERY_DEPENDENCIES += test-common + +TEST_BATTERY_CONF_OPTS += -DCMAKE_INSTALL_PREFIX=/usr/local +$(eval $(cmake-package)) diff --git a/package/fs/userfs/Config.in.userfs1 b/package/fs/userfs/Config.in.userfs1 index 982b5be0f..1f499aa43 100644 --- a/package/fs/userfs/Config.in.userfs1 +++ b/package/fs/userfs/Config.in.userfs1 @@ -67,7 +67,95 @@ endif # BR2_TARGET_USERFS1_TYPE_EXT4 if BR2_TARGET_USERFS1_TYPE_UBIFS -if BR2_UBI_PARAM_USER_CUSTOM +config BR2_TARGET_USERFS1_UBI_DEVICE_SPI_NAND_2K_128K + bool + +config BR2_TARGET_USERFS1_UBI_DEVICE_SPI_NAND_4K_256K + bool + +choice + prompt "ubi parameter select" + default BR2_TARGET_USERFS1_UBI_PARAM_ALL_SPI_NAND + +config BR2_TARGET_USERFS1_UBI_PARAM_ALL_SPI_NAND + bool "spi-nand all type support" + select BR2_TARGET_USERFS1_UBI_DEVICE_SPI_NAND_2K_128K + select BR2_TARGET_USERFS1_UBI_DEVICE_SPI_NAND_4K_256K + +config BR2_TARGET_USERFS1_UBI_PARAM_SPI_NAND_2K_128K + bool "spi-nand page:2k block:128k" + select BR2_TARGET_USERFS1_UBI_DEVICE_SPI_NAND_2K_128K + +config BR2_TARGET_USERFS1_UBI_PARAM_SPI_NAND_4K_256K + bool "spi-nand page:4k block:256k" + select BR2_TARGET_USERFS1_UBI_DEVICE_SPI_NAND_4K_256K + +config BR2_TARGET_USERFS1_UBI_PARAM_USER_CUSTOM + bool "user custom" + +endchoice + +config BR2_TARGET_USERFS1_TYPE_UBI + bool "ubi image containing an ubifs userfs1 filesystem" + default y + help + Build an ubi image from the ubifs one (with ubinize). + +if BR2_TARGET_USERFS1_TYPE_UBI + +if BR2_TARGET_USERFS1_UBI_PARAM_USER_CUSTOM +config BR2_TARGET_USERFS1_UBI_PEBSIZE + hex "physical eraseblock size" + default 0x20000 + help + Tells ubinize the physical eraseblock (PEB) size of the + flash chip the ubi image is created for. The value provided + here is passed to the -p/--peb-size option of ubinize. + +config BR2_TARGET_USERFS1_UBI_SUBSIZE + int "sub-page size" + default 512 + help + Tells ubinize that the flash supports sub-pages and the + sub-page size. Use 0 if sub-pages are not supported on flash + chip. + The value provided here is passed to the -s/--sub-page-size + option of ubinize. +endif + +config BR2_TARGET_USERFS1_UBI_USE_CUSTOM_CONFIG + bool "Use custom config file" + help + Select this option to use a custom ubinize configuration file, + rather than the default configuration used by Buildroot (which + defines a single dynamic volume marked as auto-resize). + Passing a custom ubinize configuration file allows you to + create several volumes, specify volume types, etc. + + As a convenience, buildroot replaces the string + "BR2_USERFS1_UBIFS_PATH" with the path to the built ubifs file. + So the volume defined for the root filesystem can specify the + image path as: image=BR2_USERFS1_UBIFS_PATH + + Buildroot also replaces the string "BINARIES_DIR" with the + value of $(BINARIES_DIR), so that it is possible to reference + other build artefacts (e.g. to include the kernel in a UBI + volume). + +config BR2_TARGET_USERFS1_UBI_CUSTOM_CONFIG_FILE + string "Configuration file path" + depends on BR2_TARGET_USERFS1_UBI_USE_CUSTOM_CONFIG + help + Path to the ubinize configuration file. + +config BR2_TARGET_USERFS1_UBI_OPTS + string "Additional ubinize options" + help + Any additional ubinize options you may want to include. + +endif # BR2_TARGET_USERFS1_TYPE_UBI + +if BR2_TARGET_USERFS1_UBI_PARAM_USER_CUSTOM config BR2_TARGET_USERFS1_UBIFS_LEBSIZE hex "logical eraseblock size" default 0x1f800 @@ -90,7 +178,7 @@ config BR2_TARGET_USERFS1_UBIFS_MAXLEBCNT here is passed to the -c/--max-leb-cnt option of mkfs.ubifs. endif -if !BR2_UBI_PARAM_USER_CUSTOM +if !BR2_TARGET_USERFS1_UBI_PARAM_USER_CUSTOM config BR2_TARGET_USERFS1_UBIFS_MAX_SIZE hex "ubifs size(Should be aligned to MB)" default 0x1000000 diff --git a/package/fs/userfs/Config.in.userfs2 b/package/fs/userfs/Config.in.userfs2 index b4b78517f..84e2e359d 100644 --- a/package/fs/userfs/Config.in.userfs2 +++ b/package/fs/userfs/Config.in.userfs2 @@ -67,7 +67,95 @@ endif # BR2_TARGET_USERFS2_TYPE_EXT4 if BR2_TARGET_USERFS2_TYPE_UBIFS -if BR2_UBI_PARAM_USER_CUSTOM +config BR2_TARGET_USERFS2_UBI_DEVICE_SPI_NAND_2K_128K + bool + +config BR2_TARGET_USERFS2_UBI_DEVICE_SPI_NAND_4K_256K + bool + +choice + prompt "ubi parameter select" + default BR2_TARGET_USERFS2_UBI_PARAM_ALL_SPI_NAND + +config BR2_TARGET_USERFS2_UBI_PARAM_ALL_SPI_NAND + bool "spi-nand all type support" + select BR2_TARGET_USERFS2_UBI_DEVICE_SPI_NAND_2K_128K + select BR2_TARGET_USERFS2_UBI_DEVICE_SPI_NAND_4K_256K + +config BR2_TARGET_USERFS2_UBI_PARAM_SPI_NAND_2K_128K + bool "spi-nand page:2k block:128k" + select BR2_TARGET_USERFS2_UBI_DEVICE_SPI_NAND_2K_128K + +config BR2_TARGET_USERFS2_UBI_PARAM_SPI_NAND_4K_256K + bool "spi-nand page:4k block:256k" + select BR2_TARGET_USERFS2_UBI_DEVICE_SPI_NAND_4K_256K + +config BR2_TARGET_USERFS2_UBI_PARAM_USER_CUSTOM + bool "user custom" + +endchoice + +config BR2_TARGET_USERFS2_TYPE_UBI + bool "ubi image containing an ubifs userfs2 filesystem" + default y + help + Build an ubi image from the ubifs one (with ubinize). + +if BR2_TARGET_USERFS2_TYPE_UBI + +if BR2_TARGET_USERFS2_UBI_PARAM_USER_CUSTOM +config BR2_TARGET_USERFS2_UBI_PEBSIZE + hex "physical eraseblock size" + default 0x20000 + help + Tells ubinize the physical eraseblock (PEB) size of the + flash chip the ubi image is created for. The value provided + here is passed to the -p/--peb-size option of ubinize. + +config BR2_TARGET_USERFS2_UBI_SUBSIZE + int "sub-page size" + default 512 + help + Tells ubinize that the flash supports sub-pages and the + sub-page size. Use 0 if sub-pages are not supported on flash + chip. + The value provided here is passed to the -s/--sub-page-size + option of ubinize. +endif + +config BR2_TARGET_USERFS2_UBI_USE_CUSTOM_CONFIG + bool "Use custom config file" + help + Select this option to use a custom ubinize configuration file, + rather than the default configuration used by Buildroot (which + defines a single dynamic volume marked as auto-resize). + Passing a custom ubinize configuration file allows you to + create several volumes, specify volume types, etc. + + As a convenience, buildroot replaces the string + "BR2_USERFS2_UBIFS_PATH" with the path to the built ubifs file. + So the volume defined for the root filesystem can specify the + image path as: image=BR2_USERFS2_UBIFS_PATH + + Buildroot also replaces the string "BINARIES_DIR" with the + value of $(BINARIES_DIR), so that it is possible to reference + other build artefacts (e.g. to include the kernel in a UBI + volume). + +config BR2_TARGET_USERFS2_UBI_CUSTOM_CONFIG_FILE + string "Configuration file path" + depends on BR2_TARGET_USERFS2_UBI_USE_CUSTOM_CONFIG + help + Path to the ubinize configuration file. + +config BR2_TARGET_USERFS2_UBI_OPTS + string "Additional ubinize options" + help + Any additional ubinize options you may want to include. + +endif # BR2_TARGET_USERFS2_TYPE_UBI + +if BR2_TARGET_USERFS2_UBI_PARAM_USER_CUSTOM config BR2_TARGET_USERFS2_UBIFS_LEBSIZE hex "logical eraseblock size" default 0x1f800 @@ -90,7 +178,7 @@ config BR2_TARGET_USERFS2_UBIFS_MAXLEBCNT here is passed to the -c/--max-leb-cnt option of mkfs.ubifs. endif -if !BR2_UBI_PARAM_USER_CUSTOM +if !BR2_TARGET_USERFS2_UBI_PARAM_USER_CUSTOM config BR2_TARGET_USERFS2_UBIFS_MAX_SIZE hex "ubifs size(Should be aligned to MB)" default 0x1000000 diff --git a/package/fs/userfs/Config.in.userfs3 b/package/fs/userfs/Config.in.userfs3 index 283c82813..2d78b455c 100644 --- a/package/fs/userfs/Config.in.userfs3 +++ b/package/fs/userfs/Config.in.userfs3 @@ -67,7 +67,95 @@ endif # BR2_TARGET_USERFS3_TYPE_EXT4 if BR2_TARGET_USERFS3_TYPE_UBIFS -if BR2_UBI_PARAM_USER_CUSTOM +config BR2_TARGET_USERFS3_UBI_DEVICE_SPI_NAND_2K_128K + bool + +config BR2_TARGET_USERFS3_UBI_DEVICE_SPI_NAND_4K_256K + bool + +choice + prompt "ubi parameter select" + default BR2_TARGET_USERFS3_UBI_PARAM_ALL_SPI_NAND + +config BR2_TARGET_USERFS3_UBI_PARAM_ALL_SPI_NAND + bool "spi-nand all type support" + select BR2_TARGET_USERFS3_UBI_DEVICE_SPI_NAND_2K_128K + select BR2_TARGET_USERFS3_UBI_DEVICE_SPI_NAND_4K_256K + +config BR2_TARGET_USERFS3_UBI_PARAM_SPI_NAND_2K_128K + bool "spi-nand page:2k block:128k" + select BR2_TARGET_USERFS3_UBI_DEVICE_SPI_NAND_2K_128K + +config BR2_TARGET_USERFS3_UBI_PARAM_SPI_NAND_4K_256K + bool "spi-nand page:4k block:256k" + select BR2_TARGET_USERFS3_UBI_DEVICE_SPI_NAND_4K_256K + +config BR2_TARGET_USERFS3_UBI_PARAM_USER_CUSTOM + bool "user custom" + +endchoice + +config BR2_TARGET_USERFS3_TYPE_UBI + bool "ubi image containing an ubifs userfs3 filesystem" + default y + help + Build an ubi image from the ubifs one (with ubinize). + +if BR2_TARGET_USERFS3_TYPE_UBI + +if BR2_TARGET_USERFS3_UBI_PARAM_USER_CUSTOM +config BR2_TARGET_USERFS3_UBI_PEBSIZE + hex "physical eraseblock size" + default 0x20000 + help + Tells ubinize the physical eraseblock (PEB) size of the + flash chip the ubi image is created for. The value provided + here is passed to the -p/--peb-size option of ubinize. + +config BR2_TARGET_USERFS3_UBI_SUBSIZE + int "sub-page size" + default 512 + help + Tells ubinize that the flash supports sub-pages and the + sub-page size. Use 0 if sub-pages are not supported on flash + chip. + The value provided here is passed to the -s/--sub-page-size + option of ubinize. +endif + +config BR2_TARGET_USERFS3_UBI_USE_CUSTOM_CONFIG + bool "Use custom config file" + help + Select this option to use a custom ubinize configuration file, + rather than the default configuration used by Buildroot (which + defines a single dynamic volume marked as auto-resize). + Passing a custom ubinize configuration file allows you to + create several volumes, specify volume types, etc. + + As a convenience, buildroot replaces the string + "BR2_USERFS3_UBIFS_PATH" with the path to the built ubifs file. + So the volume defined for the root filesystem can specify the + image path as: image=BR2_USERFS3_UBIFS_PATH + + Buildroot also replaces the string "BINARIES_DIR" with the + value of $(BINARIES_DIR), so that it is possible to reference + other build artefacts (e.g. to include the kernel in a UBI + volume). + +config BR2_TARGET_USERFS3_UBI_CUSTOM_CONFIG_FILE + string "Configuration file path" + depends on BR2_TARGET_USERFS3_UBI_USE_CUSTOM_CONFIG + help + Path to the ubinize configuration file. + +config BR2_TARGET_USERFS3_UBI_OPTS + string "Additional ubinize options" + help + Any additional ubinize options you may want to include. + +endif # BR2_TARGET_USERFS3_TYPE_UBI + +if BR2_TARGET_USERFS3_UBI_PARAM_USER_CUSTOM config BR2_TARGET_USERFS3_UBIFS_LEBSIZE hex "logical eraseblock size" default 0x1f800 @@ -90,7 +178,7 @@ config BR2_TARGET_USERFS3_UBIFS_MAXLEBCNT here is passed to the -c/--max-leb-cnt option of mkfs.ubifs. endif -if !BR2_UBI_PARAM_USER_CUSTOM +if !BR2_TARGET_USERFS3_UBI_PARAM_USER_CUSTOM config BR2_TARGET_USERFS3_UBIFS_MAX_SIZE hex "ubifs size(Should be aligned to MB)" default 0x1000000 diff --git a/package/fs/userfs/ubinize.cfg.userfs1 b/package/fs/userfs/ubinize.cfg.userfs1 new file mode 100644 index 000000000..706790a3b --- /dev/null +++ b/package/fs/userfs/ubinize.cfg.userfs1 @@ -0,0 +1,8 @@ +[ubifs] +mode=ubi +vol_id=0 +vol_type=dynamic +vol_name=userfs1 +vol_alignment=1 +vol_flags=autoresize +image=BR2_USERFS1_UBIFS_PATH diff --git a/package/fs/userfs/ubinize.cfg.userfs2 b/package/fs/userfs/ubinize.cfg.userfs2 new file mode 100644 index 000000000..001ba57fe --- /dev/null +++ b/package/fs/userfs/ubinize.cfg.userfs2 @@ -0,0 +1,8 @@ +[ubifs] +mode=ubi +vol_id=0 +vol_type=dynamic +vol_name=userfs2 +vol_alignment=1 +vol_flags=autoresize +image=BR2_USERFS2_UBIFS_PATH diff --git a/package/fs/userfs/ubinize.cfg.userfs3 b/package/fs/userfs/ubinize.cfg.userfs3 new file mode 100644 index 000000000..4404d2e54 --- /dev/null +++ b/package/fs/userfs/ubinize.cfg.userfs3 @@ -0,0 +1,8 @@ +[ubifs] +mode=ubi +vol_id=0 +vol_type=dynamic +vol_name=userfs3 +vol_alignment=1 +vol_flags=autoresize +image=BR2_USERFS3_UBIFS_PATH diff --git a/package/fs/userfs/userfs.mk b/package/fs/userfs/userfs.mk index 7f84600cb..2425e0049 100644 --- a/package/fs/userfs/userfs.mk +++ b/package/fs/userfs/userfs.mk @@ -175,6 +175,62 @@ endif USERFS_$(1)_UBIFS_CMD = $$(foreach MKCMD, $$(MK_UBIFS_$(1)_CMD), $$(call $$(MKCMD))$$(sep)) +######## UBI commands ######## + +ifeq ($$(BR2_TARGET_USERFS$(1)_UBI_PARAM_USER_CUSTOM),y) +USERFS_$(1)_UBI_UBINIZE_OPTS_CUSTOM = -m $$(BR2_TARGET_USERFS$(1)_UBIFS_MINIOSIZE) +USERFS_$(1)_UBI_UBINIZE_OPTS_CUSTOM += -p $$(BR2_TARGET_USERFS$(1)_UBI_PEBSIZE) +ifneq ($$(BR2_TARGET_USERFS$(1)_UBI_SUBSIZE),0) +USERFS_$(1)_UBI_UBINIZE_OPTS_CUSTOM += -s $$(BR2_TARGET_USERFS$(1)_UBI_SUBSIZE) +endif +USERFS_$(1)_UBI_UBINIZE_OPTS_CUSTOM += $$(call qstrip, $$(BR2_TARGET_USERFS$(1)_UBI_OPTS)) + +MK_USERFS_$(1)_UBI_HOOK += MK_USERFS_$(1)_UBI_CMD_CUSTOM +endif + +ifeq ($$(BR2_TARGET_USERFS$(1)_UBI_DEVICE_SPI_NAND_2K_128K),y) +USERFS_$(1)_UBI_UBINIZE_OPTS_2K_128K = -m 0x800 -p 0x20000 +USERFS_$(1)_UBI_UBINIZE_OPTS_2K_128K += $$(call qstrip, $$(BR2_TARGET_USERFS$(1)_UBI_OPTS)) +MK_USERFS_$(1)_UBI_HOOK += MK_USERFS_$(1)_UBI_CMD_2K_128K +endif + +ifeq ($$(BR2_TARGET_USERFS$(1)_UBI_DEVICE_SPI_NAND_4K_256K),y) +USERFS_$(1)_UBI_UBINIZE_OPTS_4K_256K = -m 0x1000 -p 0x40000 +USERFS_$(1)_UBI_UBINIZE_OPTS_4K_256K += $$(call qstrip, $$(BR2_TARGET_USERFS$(1)_UBI_OPTS)) +MK_USERFS_$(1)_UBI_HOOK += MK_USERFS_$(1)_UBI_CMD_4K_256K +endif + +USERFS_$(1)_UBI_DEPENDENCIES = userfs$(1)-ubifs + +ifeq ($$(BR2_TARGET_USERFS$(1)_UBI_USE_CUSTOM_CONFIG),y) +USERFS_$(1)_UBI_UBINIZE_CONFIG_FILE_PATH = $$(call qstrip,$$(BR2_TARGET_USERFS$(1)_UBI_CUSTOM_CONFIG_FILE)) +else +USERFS_$(1)_UBI_UBINIZE_CONFIG_FILE_PATH = package/fs/userfs/ubinize.cfg.userfs$(1) +endif + +MK_USERFS_$(1)_UBI_CMD_CUSTOM = \ + sed 's;userfs$(1);$$(call qstrip,$$(BR2_TARGET_USERFS$(1)_NAME));;s;BR2_USERFS$(1)_UBIFS_PATH;$@fs;;s;BINARIES_DIR;$(BINARIES_DIR);' \ + $$(USERFS_$(1)_UBI_UBINIZE_CONFIG_FILE_PATH) > $(BUILD_DIR)/ubinize.custom.cfg \ + rm $(BUILD_DIR)/ubinize.custom.cfg + +MK_USERFS_$(1)_UBI_CMD_2K_128K = \ + sed 's;userfs$(1);$$(call qstrip,$$(BR2_TARGET_USERFS$(1)_NAME));;s;BR2_USERFS$(1)_UBIFS_PATH;$$(BINARIES_DIR)/$$(call qstrip,$$(BR2_TARGET_USERFS$(1)_NAME))_page_2k_block_128k.ubifs;;s;BINARIES_DIR;$(BINARIES_DIR);' \ + $$(USERFS_$(1)_UBI_UBINIZE_CONFIG_FILE_PATH) > $(BUILD_DIR)/ubinize.2k_128k.cfg; \ + $(HOST_DIR)/sbin/ubinize \ + -o $$(BINARIES_DIR)/$$(call qstrip,$$(BR2_TARGET_USERFS$(1)_NAME))_page_2k_block_128k.ubi \ + $$(USERFS_$(1)_UBI_UBINIZE_OPTS_2K_128K) \ + $(BUILD_DIR)/ubinize.2k_128k.cfg + +MK_USERFS_$(1)_UBI_CMD_4K_256K = \ + sed 's;userfs$(1);$$(call qstrip,$$(BR2_TARGET_USERFS$(1)_NAME));;s;BR2_USERFS$(1)_UBIFS_PATH;$$(BINARIES_DIR)/$$(call qstrip,$$(BR2_TARGET_USERFS$(1)_NAME))_page_4k_block_256k.ubifs;;s;BINARIES_DIR;$(BINARIES_DIR);' \ + $$(USERFS_$(1)_UBI_UBINIZE_CONFIG_FILE_PATH) > $(BUILD_DIR)/ubinize.4k_256k.cfg; \ + $(HOST_DIR)/sbin/ubinize \ + -o $$(BINARIES_DIR)/$$(call qstrip,$$(BR2_TARGET _USERFS$(1)_NAME))_page_4k_block_256k.ubi \ + $$(USERFS_$(1)_UBI_UBINIZE_OPTS_4K_256K) \ + $(BUILD_DIR)/ubinize.4k_256k.cfg + +USERFS_$(1)_UBI_CMD = $$(foreach MKCMD, $$(MK_USERFS_$(1)_UBI_HOOK), $$(call $$(MKCMD))$$(sep)) + ######## JFFS2 commands ######## USERFS_$(1)_JFFS2_OPTS = -e $$(BR2_TARGET_USERFS$(1)_JFFS2_EBSIZE) --with-xattr USERFS_$(1)_JFFS2_SUMTOOL_OPTS = -e $$(BR2_TARGET_USERFS$(1)_JFFS2_EBSIZE) @@ -291,6 +347,10 @@ ifeq ($$(BR2_TARGET_USERFS$(1)_TYPE_UBIFS),y) $$(call PRINTF,$$(USERFS_$(1)_UBIFS_CMD)) >> $$(FAKEROOT_SCRIPT) endif +ifeq ($$(BR2_TARGET_USERFS$(1)_TYPE_UBI),y) + $$(call PRINTF,$$(USERFS_$(1)_UBI_CMD)) >> $$(FAKEROOT_SCRIPT) +endif + ifeq ($$(BR2_TARGET_USERFS$(1)_TYPE_JFFS2),y) $$(call PRINTF,$$(USERFS_$(1)_JFFS2_CMD)) >> $$(FAKEROOT_SCRIPT) endif diff --git a/package/third-party/Config.in b/package/third-party/Config.in index 0a5563bb2..9295919e2 100644 --- a/package/third-party/Config.in +++ b/package/third-party/Config.in @@ -144,5 +144,12 @@ menu "Third-party packages" source package/third-party/live555/Config.in source package/third-party/rtl8733bs_bt_fw/Config.in source package/third-party/rtl8733bu_bt_fw/Config.in + comment "************************ MTP Tools *************************" + source package/third-party/libfuse/Config.in + source package/third-party/libiconv/Config.in + source package/third-party/libusb/Config.in + source package/third-party/mtpfs/Config.in + source package/third-party/umtprd/Config.in + source package/third-party/libmtp/Config.in endmenu diff --git a/package/third-party/aic8800_fw/aic8800_fw.mk b/package/third-party/aic8800_fw/aic8800_fw.mk index f4738c197..59e7d81c6 100644 --- a/package/third-party/aic8800_fw/aic8800_fw.mk +++ b/package/third-party/aic8800_fw/aic8800_fw.mk @@ -1,4 +1,4 @@ -AIC8800_FW_VERSION = 1.0 +AIC8800_FW_VERSION = 2.0 AIC8800_FW_SOURCE = aic8800_fw-$(AIC8800_FW_VERSION).tar.gz AIC8800_FW_SITE = aic8800_fw AIC8800_FW_ENABLE_TARBALL = YES diff --git a/package/third-party/gdb/Config.in b/package/third-party/gdb/Config.in index a3a76144a..8a68469fa 100644 --- a/package/third-party/gdb/Config.in +++ b/package/third-party/gdb/Config.in @@ -17,6 +17,7 @@ comment "gdb/gdbserver >= 8.x needs a toolchain w/ C++, gcc >= 4.8" menuconfig BR2_PACKAGE_GDB bool "gdb" + select BR2_PACKAGE_HOST_GDB depends on BR2_TOOLCHAIN_HAS_THREADS && BR2_TOOLCHAIN_HAS_THREADS_DEBUG depends on BR2_PACKAGE_GDB_ARCH_SUPPORTS depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_8 @@ -60,6 +61,7 @@ config BR2_PACKAGE_GDB_SERVER config BR2_PACKAGE_GDB_DEBUGGER bool "full debugger" + default y depends on BR2_USE_WCHAR depends on !BR2_sh select BR2_PACKAGE_GMP diff --git a/package/third-party/gdb/Config.in.host b/package/third-party/gdb/Config.in.host index 37781d682..f877b1166 100644 --- a/package/third-party/gdb/Config.in.host +++ b/package/third-party/gdb/Config.in.host @@ -45,7 +45,7 @@ config BR2_PACKAGE_HOST_GDB_SIM choice prompt "GDB debugger Version" - default BR2_GDB_VERSION_15 + default BR2_GDB_VERSION_14 depends on !BR2_arc help Select the version of gdb you wish to use. diff --git a/package/third-party/libfuse/0001-fix-aarch64-build.patch b/package/third-party/libfuse/0001-fix-aarch64-build.patch new file mode 100644 index 000000000..3b88687f6 --- /dev/null +++ b/package/third-party/libfuse/0001-fix-aarch64-build.patch @@ -0,0 +1,22 @@ +Fix build on the AArch64 platform + +Upstream-Status: Submitted + +Signed-off-by: Riku Voipio + +--- a/include/fuse_kernel.h ++++ b/include/fuse_kernel.h +@@ -88,12 +88,7 @@ + #ifndef _LINUX_FUSE_H + #define _LINUX_FUSE_H + +-#include +-#define __u64 uint64_t +-#define __s64 int64_t +-#define __u32 uint32_t +-#define __s32 int32_t +-#define __u16 uint16_t ++#include + + /* + * Version negotiation: diff --git a/package/third-party/libfuse/0002-util-ulockmgr_server-c-conditionally-define-closefrom-fix-glibc-2-34.patch b/package/third-party/libfuse/0002-util-ulockmgr_server-c-conditionally-define-closefrom-fix-glibc-2-34.patch new file mode 100644 index 000000000..7c3346e47 --- /dev/null +++ b/package/third-party/libfuse/0002-util-ulockmgr_server-c-conditionally-define-closefrom-fix-glibc-2-34.patch @@ -0,0 +1,64 @@ +From 5a43d0f724c56f8836f3f92411e0de1b5f82db32 Mon Sep 17 00:00:00 2001 +From: Sam James +Date: Sat, 24 Jul 2021 22:02:45 +0100 +Subject: [PATCH] util/ulockmgr_server.c: conditionally define closefrom (fix + glibc-2.34+) + +closefrom(3) has joined us in glibc-land from *BSD and Solaris. Since +it's available in glibc 2.34+, we want to detect it and only define our +fallback if the libc doesn't provide it. + +Bug: https://bugs.gentoo.org/803923 +Signed-off-by: Sam James + +[Retrieved from: +https://github.com/libfuse/libfuse/commit/5a43d0f724c56f8836f3f92411e0de1b5f82db32] +Signed-off-by: Fabrice Fontaine +--- + configure.ac | 1 + + util/ulockmgr_server.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 9946a0efa..a2d481aa9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -55,6 +55,7 @@ fi + + AC_CHECK_FUNCS([fork setxattr fdatasync splice vmsplice utimensat]) + AC_CHECK_FUNCS([posix_fallocate]) ++AC_CHECK_FUNCS([closefrom]) + AC_CHECK_MEMBERS([struct stat.st_atim]) + AC_CHECK_MEMBERS([struct stat.st_atimespec]) + +diff --git a/util/ulockmgr_server.c b/util/ulockmgr_server.c +index 273c7d923..a04dac5c6 100644 +--- a/util/ulockmgr_server.c ++++ b/util/ulockmgr_server.c +@@ -22,6 +22,10 @@ + #include + #include + ++#ifdef HAVE_CONFIG_H ++ #include "config.h" ++#endif ++ + struct message { + unsigned intr : 1; + unsigned nofd : 1; +@@ -124,6 +128,7 @@ static int receive_message(int sock, void *buf, size_t buflen, int *fdp, + return res; + } + ++#if !defined(HAVE_CLOSEFROM) + static int closefrom(int minfd) + { + DIR *dir = opendir("/proc/self/fd"); +@@ -141,6 +146,7 @@ static int closefrom(int minfd) + } + return 0; + } ++#endif + + static void send_reply(int cfd, struct message *msg) + { diff --git a/package/third-party/libfuse/Config.in b/package/third-party/libfuse/Config.in new file mode 100644 index 000000000..2b0e31a99 --- /dev/null +++ b/package/third-party/libfuse/Config.in @@ -0,0 +1,14 @@ +config BR2_PACKAGE_LIBFUSE + bool "libfuse" + # Really doesn't like static, see fuse/lib/fuse.c + depends on !BR2_STATIC_LIBS + depends on BR2_TOOLCHAIN_HAS_THREADS + depends on BR2_USE_MMU # fork() + help + FUSE (Filesystem in UserSpacE) + + https://github.com/libfuse/libfuse + +comment "libfuse needs a toolchain w/ threads, dynamic library" + depends on BR2_USE_MMU + depends on !BR2_TOOLCHAIN_HAS_THREADS || BR2_STATIC_LIBS diff --git a/package/third-party/libfuse/libfuse.hash b/package/third-party/libfuse/libfuse.hash new file mode 100644 index 000000000..3ab322489 --- /dev/null +++ b/package/third-party/libfuse/libfuse.hash @@ -0,0 +1,6 @@ +# Locally calculated after checking pgp signature +sha256 d0e69d5d608cc22ff4843791ad097f554dd32540ddc9bed7638cc6fea7c1b4b5 fuse-2.9.9.tar.gz + +# Hash for license files: +sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING +sha256 dc626520dcd53a22f727af3ee42c770e56c97a64fe3adb063799d8ab032fe551 COPYING.LIB diff --git a/package/third-party/libfuse/libfuse.mk b/package/third-party/libfuse/libfuse.mk new file mode 100644 index 000000000..147b38b2e --- /dev/null +++ b/package/third-party/libfuse/libfuse.mk @@ -0,0 +1,48 @@ +################################################################################ +# +# libfuse +# +################################################################################ + +LIBFUSE_VERSION = 2.9.9 +LIBFUSE_SOURCE = fuse-$(LIBFUSE_VERSION).tar.gz +LIBFUSE_SITE = https://github.com/libfuse/libfuse/releases/download/fuse-$(LIBFUSE_VERSION) +LIBFUSE_LICENSE = GPL-2.0, LGPL-2.1 +LIBFUSE_LICENSE_FILES = COPYING COPYING.LIB +LIBFUSE_CPE_ID_VALID = YES +LIBFUSE_INSTALL_STAGING = YES +# We're patching configure.ac +LIBFUSE_AUTORECONF = YES +# add host-gettext for AM_ICONV macro +LIBFUSE_DEPENDENCIES = \ + host-gettext \ + $(if $(BR2_PACKAGE_LIBICONV),libiconv) +LIBFUSE_CONF_OPTS = \ + --disable-example \ + --enable-lib \ + --enable-util \ + UDEV_RULES_PATH=/lib/udev/rules.d + +ifeq ($(BR2_PACKAGE_HAS_UDEV),y) +define LIBFUSE_INSTALL_UDEV + mkdir -p $(TARGET_DIR)/lib/udev/rules.d + cp $(STAGING_DIR)/lib/udev/rules.d/*-fuse.rules $(TARGET_DIR)/lib/udev/rules.d +endef + +LIBFUSE_POST_INSTALL_TARGET_HOOKS += LIBFUSE_INSTALL_UDEV +endif + +define LIBFUSE_INSTALL_TARGET_CMDS + cp -dpf $(STAGING_DIR)/usr/bin/fusermount $(TARGET_DIR)/usr/bin/ + cp -dpf $(STAGING_DIR)/usr/lib/libfuse.so* $(TARGET_DIR)/usr/lib/ +endef + +define LIBFUSE_DEVICES + /dev/fuse c 666 0 0 10 229 0 0 - +endef + +define LIBFUSE_PERMISSIONS + /usr/bin/fusermount f 4755 0 0 - - - - - +endef + +$(eval $(autotools-package)) diff --git a/package/third-party/libiconv/Config.in b/package/third-party/libiconv/Config.in new file mode 100644 index 000000000..c08a844b0 --- /dev/null +++ b/package/third-party/libiconv/Config.in @@ -0,0 +1,29 @@ +config BR2_PACKAGE_LIBICONV + bool "libiconv" + depends on !BR2_ENABLE_LOCALE + help + unicode conversion library + + http://ftp.gnu.org/pub/gnu/libiconv + +if BR2_PACKAGE_LIBICONV + +config BR2_PACKAGE_LIBICONV_EXTRA_ENCODINGS + bool "extra encodings" + help + Provide support for a few extra encodings: + + European languages + CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125} + Semitic languages + CP864 + Japanese + EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3 + Chinese + BIG5-2003 (experimental) + Turkmen + TDS565 + Platform specifics + ATARIST, RISCOS-LATIN1 + +endif diff --git a/package/third-party/libiconv/libiconv.hash b/package/third-party/libiconv/libiconv.hash new file mode 100644 index 000000000..1f19c24f7 --- /dev/null +++ b/package/third-party/libiconv/libiconv.hash @@ -0,0 +1,6 @@ +# Locally calculated after checking pgp signature +3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8 libiconv-1.18.tar.gz + +# Hash for license files: +sha256 8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903 COPYING +sha256 56bdea73b6145ef6ac5259b3da390b981d840c24cb03b8e1cbc678de7ecfa18d COPYING.LIB diff --git a/package/third-party/libiconv/libiconv.mk b/package/third-party/libiconv/libiconv.mk new file mode 100644 index 000000000..ae072b017 --- /dev/null +++ b/package/third-party/libiconv/libiconv.mk @@ -0,0 +1,33 @@ +################################################################################ +# +# libiconv +# +################################################################################ + +LIBICONV_VERSION = 1.18 +LIBICONV_SOURCE = libiconv-$(LIBICONV_VERSION).tar.gz +LIBICONV_SITE = $(BR2_GNU_MIRROR)/libiconv +LIBICONV_INSTALL_STAGING = YES +LIBICONV_LICENSE = GPL-3.0+ (iconv program), LGPL-2.0+ (library) +LIBICONV_LICENSE_FILES = COPYING COPYING.LIB + +ifeq ($(BR2_PACKAGE_LIBICONV_EXTRA_ENCODINGS),y) +LIBICONV_CONF_OPTS += --enable-extra-encodings +endif + +# Don't build the preloadable library, as we don't need it (it's only +# for LD_PRELOAD to replace glibc's iconv, but we never build libiconv +# when glibc is used). And it causes problems for static only builds. +# define LIBICONV_DISABLE_PRELOAD +# $(SED) '/preload/d' $(@D)/Makefile.in +# endef +# LIBICONV_PRE_CONFIGURE_HOOKS += LIBICONV_DISABLE_PRELOAD + +$(eval $(autotools-package)) + +# Configurations where the toolchain supports locales and the libiconv +# package is enabled are incorrect, because the toolchain already +# provides libiconv functionality, and having both confuses packages. +ifeq ($(BR2_PACKAGE_LIBICONV)$(BR2_ENABLE_LOCALE),yy) +$(error Libiconv should never be enabled when the toolchain supports locales. Report this failure to Buildroot developers) +endif diff --git a/package/third-party/libmtp/Config.in b/package/third-party/libmtp/Config.in new file mode 100644 index 000000000..44e9c33b4 --- /dev/null +++ b/package/third-party/libmtp/Config.in @@ -0,0 +1,4 @@ +config BR2_PACKAGE_LIBMTP + bool "libmtp" + default n + diff --git a/package/third-party/libmtp/libmtp.mk b/package/third-party/libmtp/libmtp.mk new file mode 100644 index 000000000..05b63e68f --- /dev/null +++ b/package/third-party/libmtp/libmtp.mk @@ -0,0 +1,18 @@ +################################################################################ +# +# libmtp +# +################################################################################ + +LIBMTP_VERSION = 1.1.22 +LIBMTP_SOURCE = libmtp-$(LIBMTP_VERSION).tar.gz +LIBMTP_SITE = https://sourceforge.net/projects/libmtp/files/libmtp/$(LIBMTP_VERSION) +LIBMTP_SHA256 = c3fcf411aea9cb9643590cbc9df99fa5fe30adcac695024442973d76fa5f87bc +LIBMTP_LICENSE = LGPL-2.1+ +LIBMTP_LICENSE_FILES = COPYING +LIBMTP_INSTALL_STAGING = YES +LIBMTP_DEPENDENCIES = host-pkgconf libusb + +LIBMTP_PRE_CONFIGURE_HOOKS += LIBMTP_REMOVE_HOTPLUG_INSTALL_HOOK + +$(eval $(autotools-package)) \ No newline at end of file diff --git a/package/third-party/libusb/Config.in b/package/third-party/libusb/Config.in new file mode 100644 index 000000000..5a04ac128 --- /dev/null +++ b/package/third-party/libusb/Config.in @@ -0,0 +1,19 @@ +config BR2_PACKAGE_LIBUSB + bool "libusb" + depends on BR2_TOOLCHAIN_HAS_THREADS + depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 # _Thread_local + help + Userspace library for accessing USB devices + + http://libusb.info/ + +if BR2_PACKAGE_LIBUSB + +config BR2_PACKAGE_LIBUSB_EXAMPLES + bool "build libusb examples" + +endif + +comment "libusb needs a toolchain w/ threads, gcc >= 4.9" + depends on !BR2_TOOLCHAIN_HAS_THREADS || \ + !BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 diff --git a/package/third-party/libusb/libusb.hash b/package/third-party/libusb/libusb.hash new file mode 100644 index 000000000..2b9c1cc55 --- /dev/null +++ b/package/third-party/libusb/libusb.hash @@ -0,0 +1,3 @@ +# Locally computed: +sha256 db11c06e958a82dac52cf3c65cb4dd2c3f339c8a988665110e0d24d19312ad8d libusb-1.0.23.tar.bz2 +sha256 5df07007198989c622f5d41de8d703e7bef3d0e79d62e24332ee739a452af62a COPYING diff --git a/package/third-party/libusb/libusb.mk b/package/third-party/libusb/libusb.mk new file mode 100644 index 000000000..72310942d --- /dev/null +++ b/package/third-party/libusb/libusb.mk @@ -0,0 +1,38 @@ +################################################################################ +# +# libusb +# +################################################################################ + +LIBUSB_VERSION_MAJOR = 1.0 +LIBUSB_VERSION = $(LIBUSB_VERSION_MAJOR).23 +LIBUSB_SOURCE = libusb-$(LIBUSB_VERSION).tar.bz2 +LIBUSB_SITE = https://github.com/libusb/libusb/releases/download/v$(LIBUSB_VERSION) +LIBUSB_LICENSE = LGPL-2.1+ +LIBUSB_LICENSE_FILES = COPYING +LIBUSB_CPE_ID_VENDOR = libusb +LIBUSB_DEPENDENCIES = host-pkgconf +LIBUSB_INSTALL_STAGING = YES + +# Avoid the discovery of udev for the host variant +HOST_LIBUSB_CONF_OPTS = --disable-udev +HOST_LIBUSB_DEPENDENCIES = host-pkgconf + +ifeq ($(BR2_PACKAGE_HAS_UDEV),y) +LIBUSB_DEPENDENCIES += udev +else +LIBUSB_CONF_OPTS += --disable-udev +endif + +ifeq ($(BR2_PACKAGE_LIBUSB_EXAMPLES),y) +LIBUSB_CONF_OPTS += --enable-examples-build +define LIBUSB_INSTALL_TARGET_EXAMPLES + $(foreach example,listdevs xusb fxload hotplugtest testlibusb dpfp dpfp_threaded sam3u_benchmark, + $(INSTALL) -D -m0755 $(@D)/examples/$(example) $(TARGET_DIR)/usr/bin/$(example) + ) +endef +LIBUSB_POST_INSTALL_TARGET_HOOKS += LIBUSB_INSTALL_TARGET_EXAMPLES +endif + +$(eval $(autotools-package)) +$(eval $(host-autotools-package)) diff --git a/package/third-party/mtpfs/Config.in b/package/third-party/mtpfs/Config.in new file mode 100644 index 000000000..52d7914dd --- /dev/null +++ b/package/third-party/mtpfs/Config.in @@ -0,0 +1,3 @@ +config BR2_PACKAGE_MTPFS + bool "mtpfs" + default n \ No newline at end of file diff --git a/package/third-party/mtpfs/mtpfs.hash b/package/third-party/mtpfs/mtpfs.hash new file mode 100644 index 000000000..c4e69c49f --- /dev/null +++ b/package/third-party/mtpfs/mtpfs.hash @@ -0,0 +1 @@ +sha256 5f3854644bfeaa3f0391cc13251c60d19a4cdf8dab09415450a5881e3cd7891b mtpfs-1.0.tar.gz \ No newline at end of file diff --git a/package/third-party/mtpfs/mtpfs.mk b/package/third-party/mtpfs/mtpfs.mk new file mode 100644 index 000000000..052018efc --- /dev/null +++ b/package/third-party/mtpfs/mtpfs.mk @@ -0,0 +1,47 @@ +################################################################################ +# +# mtpfs +# +################################################################################ + +MTPFS_VERSION = 1.0 +MTPFS_SOURCE = mtpfs-$(MTPFS_VERSION).tar.gz +MTPFS_SITE = https://github.com/cjd/mtpfs/archive/refs/tags/v$(MTPFS_VERSION).tar.gz +MTPFS_LICENSE = LGPL-2.1+ +MTPFS_LICENSE_FILES = COPYING +MTPFS_DEPENDENCIES = host-automake host-autoconf host-libtool libmtp libfuse +MTPFS_SUBDIR = mtpfs-$(MTPFS_VERSION) + +define MTPFS_CONFIGURE_CMDS + cd $(@D) && \ + chmod +x autogen.sh && \ + ./autogen.sh && \ + ./configure \ + --prefix=/usr \ + --host=$(GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --disable-static \ + --enable-shared \ + --disable-dependency-tracking \ + --disable-mad \ + --disable-id3tag \ + $(DISABLE_NLS) \ + $(TARGET_CONFIGURE_OPTS) +endef + +define MTPFS_BUILD_CMDS + $(MAKE) -C $(@D) \ + $(TARGET_CONFIGURE_OPTS) +endef + +define MTPFS_INSTALL_STAGING_CMDS + $(MAKE) -C $(@D) install \ + DESTDIR=$(STAGING_DIR) +endef + +define MTPFS_INSTALL_TARGET_CMDS + $(MAKE) -C $(@D) install \ + DESTDIR=$(TARGET_DIR) +endef + +$(eval $(generic-package)) \ No newline at end of file diff --git a/package/third-party/rtl8733bs_bt_fw/rtl8733bs_bt_fw.mk b/package/third-party/rtl8733bs_bt_fw/rtl8733bs_bt_fw.mk index 91a3dc005..e9001dc9f 100644 --- a/package/third-party/rtl8733bs_bt_fw/rtl8733bs_bt_fw.mk +++ b/package/third-party/rtl8733bs_bt_fw/rtl8733bs_bt_fw.mk @@ -6,7 +6,7 @@ RTL8733BS_BT_FW_ENABLE_PATCH = NO RTL8733BS_BT_FW_INSTALL_STAGING = YES RTL8733BS_BT_FW_DEPENDENCIES = linux -RTL8733BS_BT_FW_CONF_OPTS += -DCMAKE_INSTALL_PREFIX=/lib/firmware +RTL8733BS_BT_FW_CONF_OPTS += -DCMAKE_INSTALL_PREFIX=/lib/firmware/rtlbt $(eval $(cmake-package)) diff --git a/package/third-party/skeleton-init-sysv/skeleton/usr/bin/list_module b/package/third-party/skeleton-init-sysv/skeleton/usr/bin/list_module index 56a1f6294..5a93f78df 100755 --- a/package/third-party/skeleton-init-sysv/skeleton/usr/bin/list_module +++ b/package/third-party/skeleton-init-sysv/skeleton/usr/bin/list_module @@ -15,6 +15,8 @@ else MOD_INFO_FILE="/etc/config/.module.csv" fi +CMU_VER=V1 + RUN_TIME=`date +%Y-%m-%d_%H-%M` COLOR_BEGIN="\033[" @@ -104,6 +106,30 @@ lm_exit() cd / > /dev/null } +# $1 - the current CLK status +parse_clk_status() +{ + CLK_STATUS=$1 + + if [ "$CMU_VER" == "V1" ]; then + if [ "${CLK_STATUS:6:1}" == "3" ] \ + || [ "${CLK_STATUS:6:1}" == "1" ] \ + || [ "${CLK_STATUS:7:1}" == "1" ]; then + return 1 + else + return 0 + fi + else + if [ "${CLK_STATUS:5:1}" == "3" ] \ + || [ "${CLK_STATUS:5:1}" == "1" ] \ + || [ "${CLK_STATUS:3:1}" == "1" ]; then + return 1 + else + return 0 + fi + fi +} + clk_is_enable() { CLK_STATUS="-" @@ -118,9 +144,8 @@ clk_is_enable() CLK_STATUS="0x0" return 0 else - if [ "${CLK_STATUS:6:1}" == "3" ] \ - || [ "${CLK_STATUS:6:1}" == "1" ] \ - || [ "${CLK_STATUS:7:1}" == "1" ]; then + parse_clk_status $CLK_STATUS + if [ $? -eq 1 ]; then MOD_ENABLE="Yes" ENABLE_CNT=$(expr $ENABLE_CNT + 1) return 1 @@ -157,6 +182,24 @@ disable_mod_clk() fi } +# $1 - CMU base address +# $2 - version offset +check_cmu_ver() +{ + hex_add $1 $2 + readl $SUM + CUR_IP_VER=$(echo ${REG_VAL:7:1}) + if [ "$CUR_IP_VER" = "1" ] || [ "$CUR_IP_VER" = "2" ]; then + CMU_VER=V1 + else + CMU_VER=V2 + fi + + if [ "x$AIC_VERBOSE" = "xon" ]; then + printf "CMU Version: %s [%s]\n" $CMU_VER $REG_VAL + fi +} + show_mod_version() { VER_INFO="-" @@ -226,10 +269,6 @@ check_one_module() INFO_STR=$2 MOD_NAME=$(echo $INFO_STR | awk -F ',' '{printf $1}') - if [ "x$AIC_VERBOSE" = "xon" ]; then - printf "%-3s %-15s ...\n" $NUM ${MOD_NAME} - fi - if [ "${MOD_NAME:0:1}" == "#" ]; then # The module is commented out printf "%-3s %-15s can not access!\n" $NUM ${MOD_NAME:1} @@ -242,10 +281,18 @@ check_one_module() TEST_REG_OFFSET=$(echo $INFO_STR | awk -F ',' '{printf $5}') EXPECT_VAL=$(echo $INFO_STR | awk -F ',' '{printf $6}' | tr -d '\r') + if [ "$MOD_NAME" = "CMU" ]; then + check_cmu_ver $MOD_BASE $VER_REG + fi + MOD_ENABLE="-" clk_is_enable show_mod_version + if [ "x$AIC_VERBOSE" = "xon" ]; then + printf "%-3s %-15s, Enable: %s\n" "$NUM" "$MOD_NAME" "$MOD_ENABLE" + fi + if [ ! "x$PROBE_TEST" == "xprobe" ]; then if [ "$MOD_ENABLE" == "Yes" ]; then printf "%-3s %-15s %-11s %-10s %-11s\n" \ @@ -303,7 +350,10 @@ while read line; do INDEX=$(expr $INDEX + 1) continue fi - # echo $line + if [ "x$AIC_VERBOSE" = "xon" ]; then + echo $line + fi + TOTAL_CNT=$(expr $TOTAL_CNT + 1) check_one_module $INDEX "$line" diff --git a/package/third-party/umtprd/Config.in b/package/third-party/umtprd/Config.in new file mode 100644 index 000000000..24bf11954 --- /dev/null +++ b/package/third-party/umtprd/Config.in @@ -0,0 +1,11 @@ +config BR2_PACKAGE_UMTPRD + bool "umtprd" + depends on BR2_TOOLCHAIN_HAS_THREADS + depends on BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_15 + help + Lightweight USB MTP responder daemon for GNU/Linux + + https://github.com/viveris/uMTP-Responder + +comment "umtprd needs a toolchain w/ threads, headers >= 3.15" + depends on !BR2_TOOLCHAIN_HAS_THREADS || !BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_15 diff --git a/package/third-party/umtprd/umtprd.hash b/package/third-party/umtprd/umtprd.hash new file mode 100644 index 000000000..47dd77693 --- /dev/null +++ b/package/third-party/umtprd/umtprd.hash @@ -0,0 +1,3 @@ +# Locally computed +sha256 51af5453987a2c63dc6a4e6d1505ceba83c23484d6c2db6c3caaed96ffbde295 uMTP-1.6.8.tar.gz +sha256 8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903 LICENSE diff --git a/package/third-party/umtprd/umtprd.mk b/package/third-party/umtprd/umtprd.mk new file mode 100644 index 000000000..aa8a1a033 --- /dev/null +++ b/package/third-party/umtprd/umtprd.mk @@ -0,0 +1,25 @@ +################################################################################ +# +# umtprd +# +################################################################################ + +UMTPRD_VERSION = 1.6.8 +UMTPRD_SITE = https://github.com/viveris/uMTP-Responder/archive +UMTPRD_LICENSE = GPL-3.0+ +UMTPRD_LICENSE_FILES = LICENSE + +define UMTPRD_BUILD_CMDS + $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D) +endef + +define UMTPRD_INSTALL_TARGET_CMDS + rm -f $(TARGET_DIR)/etc/init.d/S90adbd + + $(INSTALL) -d -m 0777 $(TARGET_DIR)/etc/umtprd + $(INSTALL) -m 0777 $(@D)/$(MTP_UMTP_SUBDIR)/conf/umtprd.conf $(TARGET_DIR)/etc/umtprd/ + $(INSTALL) -m 0777 $(@D)/$(MTP_UMTP_SUBDIR)/conf/umtprd-ffs.sh $(TARGET_DIR)/usr/sbin/umtprd-ffs.sh + $(INSTALL) -D -m 0755 $(@D)/umtprd $(TARGET_DIR)/usr/sbin/umtprd +endef + +$(eval $(generic-package)) diff --git a/package/third-party/v4l-utils/0001-media-ctl-Export-mediactl-lib-for-test-vin.patch b/package/third-party/v4l-utils/0001-media-ctl-Export-mediactl-lib-for-test-vin.patch new file mode 100644 index 000000000..e5b868cef --- /dev/null +++ b/package/third-party/v4l-utils/0001-media-ctl-Export-mediactl-lib-for-test-vin.patch @@ -0,0 +1,57 @@ +From 913667571f4c1810e0d20a999440bda612448ee6 Mon Sep 17 00:00:00 2001 +From: matteo +Date: Wed, 9 Jul 2025 10:10:44 +0800 +Subject: [PATCH] media-ctl: Export mediactl lib for test-vin + +Signed-off-by: matteo +--- + utils/media-ctl/meson.build | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/utils/media-ctl/meson.build b/utils/media-ctl/meson.build +index 3a7b0c9..06cacf1 100644 +--- a/utils/media-ctl/meson.build ++++ b/utils/media-ctl/meson.build +@@ -3,6 +3,10 @@ libmediactl_sources = files( + 'mediactl-priv.h', + ) + ++libmediactl_api = files( ++ 'mediactl.h', ++) ++ + libmediactl_deps = [ + dep_libudev, + ] +@@ -10,18 +14,28 @@ libmediactl_deps = [ + libmediactl = static_library('mediactl', + libmediactl_sources, + dependencies : libmediactl_deps, ++ install : true, + include_directories : v4l2_utils_incdir) + ++install_headers(libmediactl_api) ++ + dep_libmediactl = declare_dependency(link_with : libmediactl) + + libv4l2subdev_sources = files('libv4l2subdev.c') + libv4l2subdev_sources += media_bus_format_names_h + libv4l2subdev_sources += media_bus_format_codes_h + ++libv4l2subdev_api = files( ++ 'v4l2subdev.h', ++) ++ + libv4l2subdev = static_library('v4l2subdev', + libv4l2subdev_sources, ++ install : true, + include_directories : v4l2_utils_incdir) + ++install_headers(libv4l2subdev_api) ++ + dep_libv4l2subdev = declare_dependency(link_with : libv4l2subdev) + + media_ctl_sources = files( +-- +2.25.1 + diff --git a/package/third-party/v4l-utils/v4l-utils.mk b/package/third-party/v4l-utils/v4l-utils.mk index c11079dcd..15a4d6d30 100644 --- a/package/third-party/v4l-utils/v4l-utils.mk +++ b/package/third-party/v4l-utils/v4l-utils.mk @@ -4,7 +4,7 @@ # ################################################################################ V4L_UTILS_VERSION = 1.28.1 -V4L_UTILS_SOURCE = v4l-tuils-$(V4L_UTILS_VERSION).tar.xz +V4L_UTILS_SOURCE = v4l-utils-$(V4L_UTILS_VERSION).tar.xz V4L_UTILS_SITE = http://git.linuxtv.org/v4l-utils.git V4L_UTILS_LICENSE = LGPL-2.0+ V4L_UTILS_LICENSE_FILES = COPYING COPYING.libdvbv5 COPYING.libv4l diff --git a/prebuilt/.commit b/prebuilt/.commit index 3de8abbc3..47be2be3c 100644 --- a/prebuilt/.commit +++ b/prebuilt/.commit @@ -1 +1 @@ -cf7de4a44043abb6f09877fc51d08d2f2dfdf951 +30d7903266f387ed5aa2aaca418d67a60314e851 diff --git a/prebuilt/riscv64-linux-gnu/libmtp-master.tar.gz b/prebuilt/riscv64-linux-gnu/libmtp-master.tar.gz new file mode 100644 index 000000000..b2a5a6ef7 Binary files /dev/null and b/prebuilt/riscv64-linux-gnu/libmtp-master.tar.gz differ diff --git a/prebuilt/riscv64-linux-gnu/mtpfs-master.tar.gz b/prebuilt/riscv64-linux-gnu/mtpfs-master.tar.gz new file mode 100644 index 000000000..943004a4f Binary files /dev/null and b/prebuilt/riscv64-linux-gnu/mtpfs-master.tar.gz differ diff --git a/prebuilt/riscv64-linux-gnu/uMTP-Responder-master.tar.gz b/prebuilt/riscv64-linux-gnu/uMTP-Responder-master.tar.gz new file mode 100644 index 000000000..8a356914a Binary files /dev/null and b/prebuilt/riscv64-linux-gnu/uMTP-Responder-master.tar.gz differ diff --git a/prebuilt/riscv64-linux-gnu/v4l-utils-1.28.1.tar.gz b/prebuilt/riscv64-linux-gnu/v4l-utils-1.28.1.tar.gz index 6c5cf708c..d53a01ab2 100644 Binary files a/prebuilt/riscv64-linux-gnu/v4l-utils-1.28.1.tar.gz and b/prebuilt/riscv64-linux-gnu/v4l-utils-1.28.1.tar.gz differ diff --git a/source/artinchip/.commit b/source/artinchip/.commit index 6caff764e..86d1bc306 100644 --- a/source/artinchip/.commit +++ b/source/artinchip/.commit @@ -1 +1 @@ -a9c6b2ffe35593c619b6b0a7081c639e7b56fdef +273153a27c1814593a63b668b3dadae031d05311 diff --git a/source/artinchip/aic-mpp/middle_media/audio_decoder/decoder/aac/aac_decoder.c b/source/artinchip/aic-mpp/middle_media/audio_decoder/decoder/aac/aac_decoder.c index 95ffa66ee..e2d943400 100644 --- a/source/artinchip/aic-mpp/middle_media/audio_decoder/decoder/aac/aac_decoder.c +++ b/source/artinchip/aic-mpp/middle_media/audio_decoder/decoder/aac/aac_decoder.c @@ -1,12 +1,11 @@ /* - * Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * - * author: - * Desc: aac_decoder + * Author: + * Desc: aac_decoder */ - #include #include #include @@ -20,6 +19,10 @@ #include "audio_decoder.h" #include "faad.h" +#define ADTS_AAC (0) +#define LATM_AAC (1) +#define AAC (2) + struct aac_audio_decoder { struct aic_audio_decoder decoder; @@ -32,6 +35,7 @@ struct aac_audio_decoder int bits_per_sample; int frame_id; int frame_count; + int aac_type; }; int __aac_decode_init(struct aic_audio_decoder *decoder, struct aic_audio_decode_config *config) @@ -43,7 +47,7 @@ int __aac_decode_init(struct aic_audio_decoder *decoder, struct aic_audio_decode aac_decoder->aac_handle = NeAACDecOpen(); aac_cfg = NeAACDecGetCurrentConfiguration(aac_decoder->aac_handle); - logd("defObjectType:%d,defSampleRate:%lu,"\ + logi("defObjectType:%d,defSampleRate:%lu,"\ "dontUpSampleImplicitSBR:%d,downMatrix:%d,"\ "outputFormat:%d,useOldADTSFormat:%d\n" ,aac_cfg->defObjectType,aac_cfg->defSampleRate @@ -67,6 +71,17 @@ int __aac_decode_destroy(struct aic_audio_decoder *decoder) return 0; } +static int check_aac_type(unsigned char* buf, int len) +{ + if (buf[0]==0xff && (buf[1]&0xf0)==0xf0) + return ADTS_AAC; + + if ((buf[0]&0xff) == 0x56 && (buf[1]&0xe0) == 0xe0) + return LATM_AAC; + + return AAC; +} + int __aac_decode_frame(struct aic_audio_decoder *decoder) { s32 ret = 0; @@ -88,23 +103,39 @@ int __aac_decode_frame(struct aic_audio_decoder *decoder) if (aac_decoder->aac_handle_init_flag == 0) { aac_decoder->curr_packet = audio_pm_dequeue_ready_packet(aac_decoder->decoder.pm); - ret = NeAACDecInit2(aac_decoder->aac_handle, aac_decoder->curr_packet->data, aac_decoder->curr_packet->size, &samplerate, &channels); - if (ret < 0) { + + aac_decoder->aac_type = check_aac_type(aac_decoder->curr_packet->data, aac_decoder->curr_packet->size); + if (aac_decoder->aac_type == AAC) { + ret = NeAACDecInit2(aac_decoder->aac_handle, aac_decoder->curr_packet->data, + aac_decoder->curr_packet->size, &samplerate, &channels); audio_pm_enqueue_empty_packet(aac_decoder->decoder.pm, aac_decoder->curr_packet); + } else { + ret = NeAACDecInit(aac_decoder->aac_handle, aac_decoder->curr_packet->data, + aac_decoder->curr_packet->size, &samplerate, &channels); + // we should decode raw data for this packet + audio_pm_reclaim_ready_packet(aac_decoder->decoder.pm, aac_decoder->curr_packet); + } + + if (ret < 0) { loge("NeAACDecInit error\n"); return DEC_ERR_NOT_SUPPORT; } + aac_decoder->aac_handle_init_flag = 1; - audio_pm_enqueue_empty_packet(aac_decoder->decoder.pm, aac_decoder->curr_packet); + return DEC_OK; } aac_decoder->curr_packet = audio_pm_dequeue_ready_packet(aac_decoder->decoder.pm); memset(&frame_info, 0x00, sizeof(NeAACDecFrameInfo)); - pcm_data = NeAACDecDecode(aac_decoder->aac_handle, &frame_info, aac_decoder->curr_packet->data, aac_decoder->curr_packet->size); + u8* buf = aac_decoder->curr_packet->data; + int size = aac_decoder->curr_packet->size; + + pcm_data = NeAACDecDecode(aac_decoder->aac_handle, &frame_info, buf, size); if (frame_info.error && !aac_decoder->decoder.fm) { - loge("decoder fail !!!\n"); + loge("decoder fail, frame_info.error: %d\n", frame_info.error); + audio_pm_enqueue_empty_packet(aac_decoder->decoder.pm, aac_decoder->curr_packet); return DEC_ERR_NULL_PTR; } @@ -114,7 +145,7 @@ int __aac_decode_frame(struct aic_audio_decoder *decoder) return DEC_OK; } - logd("channels:%d,error:%d,header_type:%d,"\ + logi("channels:%d,error:%d,header_type:%d,"\ "num_back_channels:%d,num_front_channels:%d,num_lfe_channels:%d,num_side_channels:%d,"\ "object_type:%d,ps:%d,samplerate:%lu,samples:%lu,sbr:%d,"\ "bytesconsumed:%lu,packet_size:%d,channel_position[0]:%d,channel_position[1]:%d\n" @@ -165,6 +196,7 @@ int __aac_decode_frame(struct aic_audio_decoder *decoder) frame->pts = aac_decoder->curr_packet->pts; frame->bits_per_sample = aac_decoder->bits_per_sample; frame->id = aac_decoder->frame_id++; + if (frame_info.error == 0) { memcpy(frame->data, pcm_data, pcm_data_size); } else { @@ -183,7 +215,7 @@ int __aac_decode_frame(struct aic_audio_decoder *decoder) ,frame->pts,frame->sample_rate,frame->id,frame->size); if (audio_fm_decoder_put_frame(aac_decoder->decoder.fm, frame) != 0) { - loge("plese check code,why!!!\n"); + loge("please check code, why!!!\n"); return DEC_ERR_NULL_PTR; } return DEC_OK; @@ -193,6 +225,7 @@ int __aac_decode_control(struct aic_audio_decoder *decoder, int cmd, void *param { return 0; } + int __aac_decode_reset(struct aic_audio_decoder *decoder) { struct aac_audio_decoder *aac_decoder = (struct aac_audio_decoder *)decoder; diff --git a/source/artinchip/aic-mpp/middle_media/base/CMakeLists.txt b/source/artinchip/aic-mpp/middle_media/base/CMakeLists.txt index 590adc98c..45e13dae3 100644 --- a/source/artinchip/aic-mpp/middle_media/base/CMakeLists.txt +++ b/source/artinchip/aic-mpp/middle_media/base/CMakeLists.txt @@ -91,7 +91,7 @@ add_library(mm_base SHARED ${BASE_AUDIO_RENDER} ) -target_link_libraries(mm_base mpp_base asound) +target_link_libraries(mm_base mpp_base mpp_ge asound) if (RTSP_DEMUXER) target_link_libraries(mm_base BasicUsageEnvironment groupsock liveMedia UsageEnvironment) diff --git a/source/artinchip/aic-mpp/middle_media/base/include/aic_render.h b/source/artinchip/aic-mpp/middle_media/base/include/aic_render.h index 07d99ba3c..a919c0db2 100644 --- a/source/artinchip/aic-mpp/middle_media/base/include/aic_render.h +++ b/source/artinchip/aic-mpp/middle_media/base/include/aic_render.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -13,7 +13,7 @@ #include "mpp_dec_type.h" #ifdef __cplusplus -extern "C"{ +extern "C" { #endif /* __cplusplus */ struct aic_video_render { @@ -25,6 +25,7 @@ struct aic_video_render { s32 (*get_dis_rect)(struct aic_video_render *render,struct mpp_rect *rect); s32 (*set_on_off)(struct aic_video_render *render,s32 on_off); s32 (*get_on_off)(struct aic_video_render *render,s32 *on_off); + s32 (*rend_last_frame)(struct aic_video_render *render, s32 enable); }; @@ -58,6 +59,10 @@ struct aic_video_render { on_off) \ ((struct aic_video_render*)render)->get_on_off(render,on_off) +#define aic_video_render_rend_last_frame( \ + render, \ + enable) \ + ((struct aic_video_render *)render)->rend_last_frame(render, enable) s32 aic_video_render_create(struct aic_video_render **render); #ifdef __cplusplus diff --git a/source/artinchip/aic-mpp/middle_media/base/render/aic_video_render.c b/source/artinchip/aic-mpp/middle_media/base/render/aic_video_render.c index 8ca38c6d3..85e29d869 100644 --- a/source/artinchip/aic-mpp/middle_media/base/render/aic_video_render.c +++ b/source/artinchip/aic-mpp/middle_media/base/render/aic_video_render.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -19,6 +19,8 @@ #include "mpp_log.h" #include "mpp_list.h" #include "aic_render.h" +#include "dma_allocator.h" +#include "mpp_ge.h" #define DEV_FB "/dev/fb0" @@ -41,6 +43,15 @@ struct aic_fb_video_render { struct mpp_list dma_list; }; +struct aic_fb_video_render_last_frame { + struct aicfb_layer_data layer; + struct mpp_frame frame; + s32 enable; + s32 dma_fd; +}; + +static struct aic_fb_video_render_last_frame g_last_frame = {0}; + static s32 fb_video_render_init(struct aic_video_render *render,s32 layer,s32 dev_id) { struct aic_fb_video_render *fb_render = (struct aic_fb_video_render*)render; @@ -52,8 +63,10 @@ static s32 fb_video_render_init(struct aic_video_render *render,s32 layer,s32 de fb_render->layer.layer_id = layer; ioctl(fb_render->fd, AICFB_GET_LAYER_CONFIG, &fb_render->layer); - fb_render->layer.enable = 0; - ioctl(fb_render->fd, AICFB_UPDATE_LAYER_CONFIG, &fb_render->layer); + if (!g_last_frame.enable) { + fb_render->layer.enable = 0; + ioctl(fb_render->fd, AICFB_UPDATE_LAYER_CONFIG, &fb_render->layer); + } return 0; } @@ -64,9 +77,11 @@ static s32 fb_video_render_destroy(struct aic_video_render *render) struct dma_buf_info dmabuf_fd[3]; int i = 0; - fb_render->layer.enable = 0; - if (ioctl(fb_render->fd, AICFB_UPDATE_LAYER_CONFIG, &fb_render->layer) < 0) - loge("fb ioctl() AICFB_UPDATE_LAYER_CONFIG failed!"); + if (!g_last_frame.enable) { + fb_render->layer.enable = 0; + if (ioctl(fb_render->fd, AICFB_UPDATE_LAYER_CONFIG, &fb_render->layer) < 0) + loge("fb ioctl() AICFB_UPDATE_LAYER_CONFIG failed!"); + } if (!mpp_list_empty(&fb_render->dma_list)) { struct frame_dma_buf_info_list *dma_buf_node = NULL,*dma_buf_node1 = NULL; @@ -94,26 +109,26 @@ static s32 fb_video_render_destroy(struct aic_video_render *render) static s32 get_component_num(enum mpp_pixel_format format) { int component_num = 0; - if (format == MPP_FMT_ARGB_8888) { - component_num = 1; - } else if (format == MPP_FMT_RGBA_8888) { - component_num = 1; - } else if (format == MPP_FMT_RGB_888) { - component_num = 1; - } else if (format == MPP_FMT_YUV420P) { - component_num = 3; - } else if (format == MPP_FMT_NV12 || format == MPP_FMT_NV21) { - component_num = 2; - } else if (format == MPP_FMT_YUV444P) { - component_num = 3; - } else if (format == MPP_FMT_YUV422P) { - component_num = 3; - } else if (format == MPP_FMT_YUV400) { - component_num = 1; - } else { - loge("no support picture foramt %d, default argb8888", format); - } - return component_num; + if (format == MPP_FMT_ARGB_8888) { + component_num = 1; + } else if (format == MPP_FMT_RGBA_8888) { + component_num = 1; + } else if (format == MPP_FMT_RGB_888) { + component_num = 1; + } else if (format == MPP_FMT_YUV420P) { + component_num = 3; + } else if (format == MPP_FMT_NV12 || format == MPP_FMT_NV21) { + component_num = 2; + } else if (format == MPP_FMT_YUV444P) { + component_num = 3; + } else if (format == MPP_FMT_YUV422P) { + component_num = 3; + } else if (format == MPP_FMT_YUV400) { + component_num = 1; + } else { + loge("no support picture foramt %d, default argb8888", format); + } + return component_num; } static s32 fb_video_render_rend(struct aic_video_render *render,struct mpp_frame *frame_info) @@ -250,6 +265,161 @@ static s32 fb_video_render_get_on_off(struct aic_video_render *render,s32 *enabl return 0; } +static int fb_video_render_last_frame_alloc(struct mpp_frame *frame) +{ + int dma_fd = -1; + if (frame == NULL) { + loge("frame is null\n"); + return -1; + } + + dma_fd = dmabuf_device_open(); + if (dma_fd < 0) { + loge("dmabuf_device_open error dma_fd:%d \n", dma_fd); + return -1; + } + + if (mpp_buf_alloc(dma_fd, &frame->buf) < 0) { + loge("mpp_buf_alloc frame buf error dma_fd.\n"); + dmabuf_device_close(dma_fd); + return -1; + } + + return dma_fd; +} + + + +static s32 fb_video_render_last_frame_free(struct mpp_frame* frame, int dma_fd) +{ + if (frame == NULL || dma_fd <= 0) { + loge("frame free error frame:%p, dma_fd:%d.\n", frame, dma_fd); + return -1; + } + + mpp_buf_free(&frame->buf); + + dmabuf_device_close(dma_fd); + return 0; +} + + +static s32 fb_video_render_last_frame_copy(struct mpp_buf *src_buf, struct mpp_frame *dest_frame) +{ + s32 ret = 0; + struct mpp_ge *ge = NULL; + struct ge_bitblt blt; + int i = 0; + int comp_num = 0; + + ge = mpp_ge_open(); + if (!ge) { + printf("open ge device error\n"); + return -1; + } + + comp_num = get_component_num(src_buf->format); + memset(&blt, 0, sizeof(struct ge_bitblt)); + memcpy(&blt.src_buf, src_buf, sizeof(struct mpp_buf)); + memcpy(&blt.dst_buf, &dest_frame->buf, sizeof(struct mpp_buf)); + + for (i = 0; i < comp_num; i++) { + mpp_ge_add_dmabuf(ge, src_buf->fd[i]); + mpp_ge_add_dmabuf(ge, dest_frame->buf.fd[i]); + } + + ret = mpp_ge_bitblt(ge, &blt); + if (ret < 0) { + printf("ge bitblt fail\n"); + goto exit; + } + + ret = mpp_ge_emit(ge); + if (ret < 0) { + printf("ge emit fail\n"); + goto exit; + } + + ret = mpp_ge_sync(ge); + if (ret < 0) { + printf("ge sync fail\n"); + } + +exit: + for (i = 0; i < comp_num; i++) { + mpp_ge_rm_dmabuf(ge, src_buf->fd[i]); + mpp_ge_rm_dmabuf(ge, dest_frame->buf.fd[i]); + } + + if (ge) + mpp_ge_close(ge); + + return ret; +} + +static s32 fb_video_render_rend_last_frame(struct aic_video_render *render, s32 enable) +{ + s32 ret = 0; + struct mpp_frame cur_frame; + struct aic_fb_video_render *fb_render = (struct aic_fb_video_render *)render; + + if (fb_render == NULL) { + loge("fb_render is not initialization!"); + return -1; + } + + if (enable) { + /*step1: malloc empty for last frame*/ + memcpy(&cur_frame.buf, &fb_render->layer.buf, sizeof(struct mpp_buf)); + + /*the first frame need malloc buf for last frame*/ + if (!g_last_frame.enable) { + logi("%s:alloc last frame firsttime, enable:%d.\n", __func__, enable); + memset(&g_last_frame.frame, 0, sizeof(struct mpp_frame)); + g_last_frame.dma_fd = fb_video_render_last_frame_alloc(&cur_frame); + if (g_last_frame.dma_fd < 0) { + loge("fb_video_render_last_frame_alloc failed.\n"); + return -1; + } + memcpy(&g_last_frame.frame, &cur_frame, sizeof(struct mpp_frame)); + } else { + /*the frame resolution changed need realloc buf for last frame*/ + if ((g_last_frame.frame.buf.size.height != cur_frame.buf.size.height) || + (g_last_frame.frame.buf.size.width != cur_frame.buf.size.width)) { + logi("free last frame and alloc next frame.\n"); + fb_video_render_last_frame_free(&g_last_frame.frame, g_last_frame.dma_fd); + + g_last_frame.dma_fd = fb_video_render_last_frame_alloc(&cur_frame); + if (g_last_frame.dma_fd < 0) { + loge("fb_video_render_last_frame_alloc failed.\n"); + return -1; + } + memcpy(&g_last_frame.frame, &cur_frame, sizeof(struct mpp_frame)); + } + } + logi("fb_video_render_last_frame_copy.\n"); + /*step2: copy frame data to last frame*/ + fb_video_render_last_frame_copy(&fb_render->layer.buf, &g_last_frame.frame); + + /*step3: display last frame*/ + fb_video_render_rend(render, &g_last_frame.frame); + } else { + if (g_last_frame.enable) { + logi("%s:reclaim the final last frame, enable:%d.\n", __func__, enable); + /*reclaim the end last frame*/ + ret = fb_video_render_last_frame_free(&g_last_frame.frame, g_last_frame.dma_fd); + if (ret) { + loge("fb_video_render_last_frame_free error %d.", ret); + return ret; + } + memset(&g_last_frame.frame, 0, sizeof(struct mpp_frame)); + } + } + + g_last_frame.enable = enable; + return ret; +} + s32 aic_video_render_create(struct aic_video_render **render) { struct aic_fb_video_render * fb_render; @@ -270,6 +440,7 @@ s32 aic_video_render_create(struct aic_video_render **render) fb_render->base.set_on_off = fb_video_render_set_on_off; fb_render->base.get_on_off = fb_video_render_get_on_off; fb_render->base.get_screen_size = get_screen_size; + fb_render->base.rend_last_frame = fb_video_render_rend_last_frame; *render = &fb_render->base; return 0; diff --git a/source/artinchip/aic-mpp/middle_media/component/include/mm_index.h b/source/artinchip/aic-mpp/middle_media/component/include/mm_index.h index 0c2a1b7bf..221d53589 100644 --- a/source/artinchip/aic-mpp/middle_media/component/include/mm_index.h +++ b/source/artinchip/aic-mpp/middle_media/component/include/mm_index.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -59,6 +59,7 @@ typedef enum MM_INDEX_TYPE { MM_INDEX_VENDOR_AUDIO_RENDER_VOLUME, MM_INDEX_VENDOR_DEMUXER_SKIP_TRACK, MM_INDEX_VENDOR_VIDEO_RENDER_CAPTURE, + MM_INDEX_VENDOR_VIDEO_RENDER_KEEP_LAST_FRAME, MM_INDEX_VENDOR_MUXER_RECORD_FILE_INFO, } MM_INDEX_TYPE; diff --git a/source/artinchip/aic-mpp/middle_media/component/src/mm_video_render_component.c b/source/artinchip/aic-mpp/middle_media/component/src/mm_video_render_component.c index 03121948e..5afb65376 100644 --- a/source/artinchip/aic-mpp/middle_media/component/src/mm_video_render_component.c +++ b/source/artinchip/aic-mpp/middle_media/component/src/mm_video_render_component.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -125,11 +125,11 @@ static int mm_video_render_free_dma_buffer(struct mpp_frame* p_frame,int dma_fd) if (p_frame->buf.fd[0] > 0) { dmabuf_free(p_frame->buf.fd[0]); } - if (p_frame->buf.fd[0] > 0) { - dmabuf_free(p_frame->buf.fd[0]); + if (p_frame->buf.fd[1] > 0) { + dmabuf_free(p_frame->buf.fd[1]); } - if (p_frame->buf.fd[0] > 0) { - dmabuf_free(p_frame->buf.fd[0]); + if (p_frame->buf.fd[2] > 0) { + dmabuf_free(p_frame->buf.fd[2]); } dmabuf_device_close(dma_fd); return 0; @@ -1211,6 +1211,17 @@ static s32 mm_video_render_set_parameter(mm_handle h_component, ((mm_config_rect *)p_param)->height; p_video_render_data->dis_rect_change = MM_TRUE; break; + case MM_INDEX_VENDOR_VIDEO_RENDER_KEEP_LAST_FRAME: + if (!p_video_render_data->render) { + loge("video render is not initialization!!!\n"); + return MM_ERROR_INSUFFICIENT_RESOURCES; + } + error = aic_video_render_rend_last_frame(p_video_render_data->render, + (s32)(((mm_param_u32 *)p_param)->u32)); + if (error != 0) + loge("aic_video_render_rend_last_frame error %d!!!\n", error); + + break; default: break; diff --git a/source/artinchip/aic-mpp/middle_media/player/aic_player.c b/source/artinchip/aic-mpp/middle_media/player/aic_player.c index 1a0bcedf7..57c3ab69d 100644 --- a/source/artinchip/aic-mpp/middle_media/player/aic_player.c +++ b/source/artinchip/aic-mpp/middle_media/player/aic_player.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -68,6 +68,7 @@ struct aic_player { s32 rotation_angle; s8 mute; s8 seeking; + s8 video_render_keep_last_frame; }; @@ -940,6 +941,13 @@ s32 aic_player_stop(struct aic_player *player) if (player->media_info.has_video) { if (player->video_render_handle) { + mm_param_u32 params; + params.u32 = (u32)player->video_render_keep_last_frame; + if (MM_ERROR_NONE != mm_set_parameter(player->video_render_handle, + MM_INDEX_VENDOR_VIDEO_RENDER_KEEP_LAST_FRAME, + ¶ms)) { + loge("set video render keep last frame failed.\n"); + } mm_free_handle(player->video_render_handle); player->video_render_handle = NULL; } @@ -1200,3 +1208,22 @@ s32 aic_player_get_rotation(struct aic_player *player) return rotation.rotation; } +s32 aic_player_control(struct aic_player *player, enum aic_player_command cmd, void *data) +{ + s32 ret = 0; + switch (cmd) { + case AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME: { + if (!data) { + loge("video render set last frame data is null\n"); + return -1; + } + player->video_render_keep_last_frame = *(s8 *)data; + break; + } + + default: + return -1; + } + + return ret; +} diff --git a/source/artinchip/aic-mpp/middle_media/player/include/aic_player.h b/source/artinchip/aic-mpp/middle_media/player/include/aic_player.h index c035aeca2..9847bb0d4 100644 --- a/source/artinchip/aic-mpp/middle_media/player/include/aic_player.h +++ b/source/artinchip/aic-mpp/middle_media/player/include/aic_player.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -30,6 +30,9 @@ enum aic_player_event { AIC_PLAYER_EVENT_DEMUXER_FORMAT_NOT_DETECTED }; +enum aic_player_command { + AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME, +}; // now do not support setting nWidth and nHeight,just only support setting pFilePath struct aic_capture_info { s8 *file_path; @@ -108,6 +111,8 @@ s32 aic_player_set_rotation(struct aic_player *player, int rotation_angle); s32 aic_player_get_rotation(struct aic_player *player); +s32 aic_player_control(struct aic_player *player, enum aic_player_command cmd, void *data); + #ifdef __cplusplus #if __cplusplus } diff --git a/source/artinchip/aic-mpp/middle_media/player/player_demo.c b/source/artinchip/aic-mpp/middle_media/player/player_demo.c index fdba89259..799e6590e 100644 --- a/source/artinchip/aic-mpp/middle_media/player/player_demo.c +++ b/source/artinchip/aic-mpp/middle_media/player/player_demo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd + * Copyright (C) 2020-2025 ArtInChip Technology Co. Ltd * * SPDX-License-Identifier: Apache-2.0 * @@ -392,6 +392,34 @@ static int process_command(struct video_player_ctx *player_ctx,char cmd) return ret; } + +static int player_demo_prepare_stop(struct video_player_ctx *ctx, int force_stop, + int loop_time, int file_num) +{ + int enable = 0; + + /*force stop need set render delay disable*/ + if (force_stop && (ctx->loop_time > 1 || ctx->files.file_num > 1)) { + enable = 0; + aic_player_control(ctx->player, AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME, &enable); + return 0; + } + + /*check the final play file then set render delay disable*/ + if ((ctx->loop_time > 1) && (ctx->files.file_num > 1)) { + if ((loop_time == ctx->loop_time - 1) && (file_num == ctx->files.file_num -1)) { + enable = 0; + aic_player_control(ctx->player, AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME, &enable); + } + } else if ((ctx->loop_time > 1) && (loop_time == ctx->loop_time - 1)) { + enable = 0; + aic_player_control(ctx->player, AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME, &enable); + } else if ((ctx->files.file_num > 1) && (file_num == ctx->files.file_num - 1)) { + enable = 0; + aic_player_control(ctx->player, AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME, &enable); + } + return 0; +} int main(int argc,char*argv[]) { int ret = 0; @@ -400,6 +428,7 @@ int main(int argc,char*argv[]) char buffer[BUFFER_LEN]; int flag; static int fd_dev; + int enable = 0; struct aicfb_alpha_config alpha_bak = {0}; struct aicfb_alpha_config alpha = {0}; struct video_player_ctx *ctx = NULL; @@ -441,6 +470,10 @@ int main(int argc,char*argv[]) flag = fcntl(STDIN_FILENO,F_GETFL); flag |= O_NONBLOCK; fcntl(STDIN_FILENO,F_SETFL,flag); + if (ctx->loop_time > 1 || ctx->files.file_num > 1) { + enable = 1; + aic_player_control(ctx->player, AIC_PLAYER_CMD_SET_VIDEO_RENDER_KEEP_LAST_FRAME, &enable); + } for(i = 0;i < ctx->loop_time; i++) { for(j = 0; j < ctx->files.file_num; j++) { @@ -448,11 +481,13 @@ int main(int argc,char*argv[]) ctx->player_end = 0; if (aic_player_set_uri(ctx->player,ctx->files.file_path[j])) { loge("aic_player_prepare error!!!!\n"); + player_demo_prepare_stop(ctx, 0, i, j); aic_player_stop(ctx->player); continue; } if (aic_player_prepare_sync(ctx->player)) { + player_demo_prepare_stop(ctx, 0, i, j); loge("aic_player_prepare error!!!!\n"); aic_player_stop(ctx->player); continue; @@ -460,6 +495,7 @@ int main(int argc,char*argv[]) if (start_play(ctx) != 0) { loge("start_play error!!!!\n"); + player_demo_prepare_stop(ctx, 0, i, j); aic_player_stop(ctx->player); continue; } @@ -467,6 +503,7 @@ int main(int argc,char*argv[]) while(1) { if (ctx->player_end == 1) { logd("play file:%s end!!!!\n",ctx->files.file_path[j]); + player_demo_prepare_stop(ctx, 0, i, j); ret = aic_player_stop(ctx->player); ctx->player_end = 0; break; @@ -478,9 +515,11 @@ int main(int argc,char*argv[]) aic_player_stop(ctx->player); break; } else if (buffer[0] == 'd') {// down + player_demo_prepare_stop(ctx, 0, i, j); aic_player_stop(ctx->player); break; } else if (buffer[0] == 'e') {// end + player_demo_prepare_stop(ctx, 1, i, j); aic_player_stop(ctx->player); goto _EXIT_; } diff --git a/source/artinchip/http-wificonfig/CMakeLists.txt b/source/artinchip/http-wificonfig/CMakeLists.txt new file mode 100644 index 000000000..142ef4c81 --- /dev/null +++ b/source/artinchip/http-wificonfig/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) + +# include_directories(include) + +# Install +# install directories +add_executable(http_wificonfig http.c) +target_link_libraries(http_wificonfig wifimanager wpa_client) +if(NOT CMAKE_INSTALL_PREFIX) + message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.") +endif() +include(GNUInstallDirs) + +install(TARGETS http_wificonfig DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(DIRECTORY html DESTINATION ${TARGET_DIR}/var/http_wificonfig) + +install(FILES config/hostapd.conf DESTINATION ${TARGET_DIR}/etc/http_wificonfig) +install(FILES config/udhcpd.conf DESTINATION ${TARGET_DIR}/etc/http_wificonfig) \ No newline at end of file diff --git a/source/artinchip/http-wificonfig/config/hostapd.conf b/source/artinchip/http-wificonfig/config/hostapd.conf new file mode 100644 index 000000000..343e1f0e4 --- /dev/null +++ b/source/artinchip/http-wificonfig/config/hostapd.conf @@ -0,0 +1,1541 @@ +##### hostapd configuration file ############################################## +# Empty lines and lines starting with # are ignored + +# AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for +# management frames); ath0 for madwifi +interface=wlan1 +ssid=ArtInChip-WiFI +wpa=2 +wpa_passphrase=88888888 +wpa_key_mgmt=WPA-PSK +channel=1 +rsn_pairwise=CCMP +# In case of madwifi, atheros, and nl80211 driver interfaces, an additional +# configuration parameter, bridge, may be used to notify hostapd if the +# interface is included in a bridge. This parameter is not used with Host AP +# driver. If the bridge parameter is not set, the drivers will automatically +# figure out the bridge interface (assuming sysfs is enabled and mounted to +# /sys) and this parameter may not be needed. +# +# For nl80211, this parameter can be used to request the AP interface to be +# added to the bridge automatically (brctl may refuse to do this before hostapd +# has been started to change the interface mode). If needed, the bridge +# interface is also created. +#bridge=br0 + +# Driver interface type (hostap/wired/madwifi/test/none/nl80211/bsd); +# default: hostap). nl80211 is used with all Linux mac80211 drivers. +# Use driver=none if building hostapd as a standalone RADIUS server that does +# not control any wireless/wired driver. +driver=nl80211 + +# hostapd event logger configuration +# +# Two output method: syslog and stdout (only usable if not forking to +# background). +# +# Module bitfield (ORed bitfield of modules that will be logged; -1 = all +# modules): +# bit 0 (1) = IEEE 802.11 +# bit 1 (2) = IEEE 802.1X +# bit 2 (4) = RADIUS +# bit 3 (8) = WPA +# bit 4 (16) = driver interface +# bit 5 (32) = IAPP +# bit 6 (64) = MLME +# +# Levels (minimum value for logged events): +# 0 = verbose debugging +# 1 = debugging +# 2 = informational messages +# 3 = notification +# 4 = warning +# +logger_syslog=-1 +logger_syslog_level=2 +logger_stdout=-1 +logger_stdout_level=2 + +# Dump file for state information (on SIGUSR1) +dump_file=/tmp/hostapd.dump + +# Interface for separate control program. If this is specified, hostapd +# will create this directory and a UNIX domain socket for listening to requests +# from external programs (CLI/GUI, etc.) for status information and +# configuration. The socket file will be named based on the interface name, so +# multiple hostapd processes/interfaces can be run at the same time if more +# than one interface is used. +# /var/run/hostapd is the recommended directory for sockets and by default, +# hostapd_cli will use it when trying to connect with hostapd. +ctrl_interface=/var/run/hostapd + +# Access control for the control interface can be configured by setting the +# directory to allow only members of a group to use sockets. This way, it is +# possible to run hostapd as root (since it needs to change network +# configuration and open raw sockets) and still allow GUI/CLI components to be +# run as non-root users. However, since the control interface can be used to +# change the network configuration, this access needs to be protected in many +# cases. By default, hostapd is configured to use gid 0 (root). If you +# want to allow non-root users to use the contron interface, add a new group +# and change this value to match with that group. Add users that should have +# control interface access to this group. +# +# This variable can be a group name or gid. +#ctrl_interface_group=wheel +ctrl_interface_group=0 + + +##### IEEE 802.11 related configuration ####################################### + +# SSID to be used in IEEE 802.11 management frames +#ssid=SSVQATestAP +# Alternative formats for configuring SSID +# (double quoted string, hexdump, printf-escaped string) +#ssid2="test" +#ssid2=74657374 +#ssid2=P"hello\nthere" + +# UTF-8 SSID: Whether the SSID is to be interpreted using UTF-8 encoding +#utf8_ssid=1 + +# Country code (ISO/IEC 3166-1). Used to set regulatory domain. +# Set as needed to indicate country in which device is operating. +# This can limit available channels and transmit power. +#country_code=US + +# Enable IEEE 802.11d. This advertises the country_code and the set of allowed +# channels and transmit power levels based on the regulatory limits. The +# country_code setting must be configured with the correct country for +# IEEE 802.11d functions. +# (default: 0 = disabled) +#ieee80211d=1 + +# Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g, +# ad = IEEE 802.11ad (60 GHz); a/g options are used with IEEE 802.11n, too, to +# specify band) +# Default: IEEE 802.11b +hw_mode=g + +# Channel number (IEEE 802.11) +# (default: 0, i.e., not set) +# Please note that some drivers do not use this value from hostapd and the +# channel will need to be configured separately with iwconfig. +#channel=6 + +# Beacon interval in kus (1.024 ms) (default: 100; range 15..65535) +beacon_int=100 + +# DTIM (delivery traffic information message) period (range 1..255): +# number of beacons between DTIMs (1 = every beacon includes DTIM element) +# (default: 2) +dtim_period=2 + +# Maximum number of stations allowed in station table. New stations will be +# rejected after the station table is full. IEEE 802.11 has a limit of 2007 +# different association IDs, so this number should not be larger than that. +# (default: 2007) +max_num_sta=9 + +# RTS/CTS threshold; 2347 = disabled (default); range 0..2347 +# If this field is not included in hostapd.conf, hostapd will not control +# RTS threshold and 'iwconfig wlan# rts ' can be used to set it. +rts_threshold=2347 + +# Fragmentation threshold; 2346 = disabled (default); range 256..2346 +# If this field is not included in hostapd.conf, hostapd will not control +# fragmentation threshold and 'iwconfig wlan# frag ' can be used to set +# it. +fragm_threshold=2346 + +# Rate configuration +# Default is to enable all rates supported by the hardware. This configuration +# item allows this list be filtered so that only the listed rates will be left +# in the list. If the list is empty, all rates are used. This list can have +# entries that are not in the list of rates the hardware supports (such entries +# are ignored). The entries in this list are in 100 kbps, i.e., 11 Mbps = 110. +# If this item is present, at least one rate have to be matching with the rates +# hardware supports. +# default: use the most common supported rate setting for the selected +# hw_mode (i.e., this line can be removed from configuration file in most +# cases) +#supported_rates=10 20 55 110 60 90 120 180 240 360 480 540 + +# Basic rate set configuration +# List of rates (in 100 kbps) that are included in the basic rate set. +# If this item is not included, usually reasonable default set is used. +#basic_rates=10 20 +#basic_rates=10 20 55 110 +#basic_rates=60 120 240 + +# Short Preamble +# This parameter can be used to enable optional use of short preamble for +# frames sent at 2 Mbps, 5.5 Mbps, and 11 Mbps to improve network performance. +# This applies only to IEEE 802.11b-compatible networks and this should only be +# enabled if the local hardware supports use of short preamble. If any of the +# associated STAs do not support short preamble, use of short preamble will be +# disabled (and enabled when such STAs disassociate) dynamically. +# 0 = do not allow use of short preamble (default) +# 1 = allow use of short preamble +#preamble=1 + +# Station MAC address -based authentication +# Please note that this kind of access control requires a driver that uses +# hostapd to take care of management frame processing and as such, this can be +# used with driver=hostap or driver=nl80211, but not with driver=madwifi. +# 0 = accept unless in deny list +# 1 = deny unless in accept list +# 2 = use external RADIUS server (accept/deny lists are searched first) +macaddr_acl=0 + +# Accept/deny lists are read from separate files (containing list of +# MAC addresses, one per line). Use absolute path name to make sure that the +# files can be read on SIGHUP configuration reloads. +#accept_mac_file=/etc/hostapd.accept +#deny_mac_file=/etc/hostapd.deny + +# IEEE 802.11 specifies two authentication algorithms. hostapd can be +# configured to allow both of these or only one. Open system authentication +# should be used with IEEE 802.1X. +# Bit fields of allowed authentication algorithms: +# bit 0 = Open System Authentication +# bit 1 = Shared Key Authentication (requires WEP) +auth_algs=3 + +# Send empty SSID in beacons and ignore probe request frames that do not +# specify full SSID, i.e., require stations to know SSID. +# default: disabled (0) +# 1 = send empty (length=0) SSID in beacon and ignore probe request for +# broadcast SSID +# 2 = clear SSID (ASCII 0), but keep the original length (this may be required +# with some clients that do not support empty SSID) and ignore probe +# requests for broadcast SSID +ignore_broadcast_ssid=0 + +# Additional vendor specfic elements for Beacon and Probe Response frames +# This parameter can be used to add additional vendor specific element(s) into +# the end of the Beacon and Probe Response frames. The format for these +# element(s) is a hexdump of the raw information elements (id+len+payload for +# one or more elements) +#vendor_elements=dd0411223301 + +# TX queue parameters (EDCF / bursting) +# tx_queue__ +# queues: data0, data1, data2, data3, after_beacon, beacon +# (data0 is the highest priority queue) +# parameters: +# aifs: AIFS (default 2) +# cwmin: cwMin (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023) +# cwmax: cwMax (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023); cwMax >= cwMin +# burst: maximum length (in milliseconds with precision of up to 0.1 ms) for +# bursting +# +# Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e): +# These parameters are used by the access point when transmitting frames +# to the clients. +# +# Low priority / AC_BK = background +#tx_queue_data3_aifs=7 +#tx_queue_data3_cwmin=15 +#tx_queue_data3_cwmax=1023 +#tx_queue_data3_burst=0 +# Note: for IEEE 802.11b mode: cWmin=31 cWmax=1023 burst=0 +# +# Normal priority / AC_BE = best effort +#tx_queue_data2_aifs=3 +#tx_queue_data2_cwmin=15 +#tx_queue_data2_cwmax=63 +#tx_queue_data2_burst=0 +# Note: for IEEE 802.11b mode: cWmin=31 cWmax=127 burst=0 +# +# High priority / AC_VI = video +#tx_queue_data1_aifs=1 +#tx_queue_data1_cwmin=7 +#tx_queue_data1_cwmax=15 +#tx_queue_data1_burst=3.0 +# Note: for IEEE 802.11b mode: cWmin=15 cWmax=31 burst=6.0 +# +# Highest priority / AC_VO = voice +#tx_queue_data0_aifs=1 +#tx_queue_data0_cwmin=3 +#tx_queue_data0_cwmax=7 +#tx_queue_data0_burst=1.5 +# Note: for IEEE 802.11b mode: cWmin=7 cWmax=15 burst=3.3 + +# 802.1D Tag (= UP) to AC mappings +# WMM specifies following mapping of data frames to different ACs. This mapping +# can be configured using Linux QoS/tc and sch_pktpri.o module. +# 802.1D Tag 802.1D Designation Access Category WMM Designation +# 1 BK AC_BK Background +# 2 - AC_BK Background +# 0 BE AC_BE Best Effort +# 3 EE AC_BE Best Effort +# 4 CL AC_VI Video +# 5 VI AC_VI Video +# 6 VO AC_VO Voice +# 7 NC AC_VO Voice +# Data frames with no priority information: AC_BE +# Management frames: AC_VO +# PS-Poll frames: AC_BE + +# Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e): +# for 802.11a or 802.11g networks +# These parameters are sent to WMM clients when they associate. +# The parameters will be used by WMM clients for frames transmitted to the +# access point. +# +# note - txop_limit is in units of 32microseconds +# note - acm is admission control mandatory flag. 0 = admission control not +# required, 1 = mandatory +# note - here cwMin and cmMax are in exponent form. the actual cw value used +# will be (2^n)-1 where n is the value given here +# +wmm_enabled=1 +# +# WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD] +# Enable this flag if U-APSD supported outside hostapd (eg., Firmware/driver) +#uapsd_advertisement_enabled=1 +# +# Low priority / AC_BK = background +wmm_ac_bk_cwmin=4 +wmm_ac_bk_cwmax=10 +wmm_ac_bk_aifs=7 +wmm_ac_bk_txop_limit=0 +wmm_ac_bk_acm=0 +# Note: for IEEE 802.11b mode: cWmin=5 cWmax=10 +# +# Normal priority / AC_BE = best effort +wmm_ac_be_aifs=3 +wmm_ac_be_cwmin=4 +wmm_ac_be_cwmax=10 +wmm_ac_be_txop_limit=0 +wmm_ac_be_acm=0 +# Note: for IEEE 802.11b mode: cWmin=5 cWmax=7 +# +# High priority / AC_VI = video +wmm_ac_vi_aifs=2 +wmm_ac_vi_cwmin=3 +wmm_ac_vi_cwmax=4 +wmm_ac_vi_txop_limit=94 +wmm_ac_vi_acm=0 +# Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188 +# +# Highest priority / AC_VO = voice +wmm_ac_vo_aifs=2 +wmm_ac_vo_cwmin=2 +wmm_ac_vo_cwmax=3 +wmm_ac_vo_txop_limit=47 +wmm_ac_vo_acm=0 +# Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102 + +# Static WEP key configuration +# +# The key number to use when transmitting. +# It must be between 0 and 3, and the corresponding key must be set. +# default: not set +#wep_default_key=0 +# The WEP keys to use. +# A key may be a quoted string or unquoted hexadecimal digits. +# The key length should be 5, 13, or 16 characters, or 10, 26, or 32 +# digits, depending on whether 40-bit (64-bit), 104-bit (128-bit), or +# 128-bit (152-bit) WEP is used. +# Only the default key must be supplied; the others are optional. +# default: not set +#wep_key0=123456789a +#wep_key1="vwxyz" +#wep_key2=0102030405060708090a0b0c0d +#wep_key3=".2.4.6.8.0.23" + +# Station inactivity limit +# +# If a station does not send anything in ap_max_inactivity seconds, an +# empty data frame is sent to it in order to verify whether it is +# still in range. If this frame is not ACKed, the station will be +# disassociated and then deauthenticated. This feature is used to +# clear station table of old entries when the STAs move out of the +# range. +# +# The station can associate again with the AP if it is still in range; +# this inactivity poll is just used as a nicer way of verifying +# inactivity; i.e., client will not report broken connection because +# disassociation frame is not sent immediately without first polling +# the STA with a data frame. +# default: 300 (i.e., 5 minutes) +#ap_max_inactivity=300 +# +# The inactivity polling can be disabled to disconnect stations based on +# inactivity timeout so that idle stations are more likely to be disconnected +# even if they are still in range of the AP. This can be done by setting +# skip_inactivity_poll to 1 (default 0). +#skip_inactivity_poll=0 + +# Disassociate stations based on excessive transmission failures or other +# indications of connection loss. This depends on the driver capabilities and +# may not be available with all drivers. +#disassoc_low_ack=1 + +# Maximum allowed Listen Interval (how many Beacon periods STAs are allowed to +# remain asleep). Default: 65535 (no limit apart from field size) +#max_listen_interval=100 + +# WDS (4-address frame) mode with per-station virtual interfaces +# (only supported with driver=nl80211) +# This mode allows associated stations to use 4-address frames to allow layer 2 +# bridging to be used. +#wds_sta=1 + +# If bridge parameter is set, the WDS STA interface will be added to the same +# bridge by default. This can be overridden with the wds_bridge parameter to +# use a separate bridge. +#wds_bridge=wds-br0 + +# Client isolation can be used to prevent low-level bridging of frames between +# associated stations in the BSS. By default, this bridging is allowed. +#ap_isolate=1 + +##### IEEE 802.11n related configuration ###################################### + +# ieee80211n: Whether IEEE 802.11n (HT) is enabled +# 0 = disabled (default) +# 1 = enabled +# Note: You will also need to enable WMM for full HT functionality. +ieee80211n=1 + +# ht_capab: HT capabilities (list of flags) +# LDPC coding capability: [LDPC] = supported +# Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary +# channel below the primary channel; [HT40+] = both 20 MHz and 40 MHz +# with secondary channel below the primary channel +# (20 MHz only if neither is set) +# Note: There are limits on which channels can be used with HT40- and +# HT40+. Following table shows the channels that may be available for +# HT40- and HT40+ use per IEEE 802.11n Annex J: +# freq HT40- HT40+ +# 2.4 GHz 5-13 1-7 (1-9 in Europe/Japan) +# 5 GHz 40,48,56,64 36,44,52,60 +# (depending on the location, not all of these channels may be available +# for use) +# Please note that 40 MHz channels may switch their primary and secondary +# channels if needed or creation of 40 MHz channel maybe rejected based +# on overlapping BSSes. These changes are done automatically when hostapd +# is setting up the 40 MHz channel. +# Spatial Multiplexing (SM) Power Save: [SMPS-STATIC] or [SMPS-DYNAMIC] +# (SMPS disabled if neither is set) +# HT-greenfield: [GF] (disabled if not set) +# Short GI for 20 MHz: [SHORT-GI-20] (disabled if not set) +# Short GI for 40 MHz: [SHORT-GI-40] (disabled if not set) +# Tx STBC: [TX-STBC] (disabled if not set) +# Rx STBC: [RX-STBC1] (one spatial stream), [RX-STBC12] (one or two spatial +# streams), or [RX-STBC123] (one, two, or three spatial streams); Rx STBC +# disabled if none of these set +# HT-delayed Block Ack: [DELAYED-BA] (disabled if not set) +# Maximum A-MSDU length: [MAX-AMSDU-7935] for 7935 octets (3839 octets if not +# set) +# DSSS/CCK Mode in 40 MHz: [DSSS_CCK-40] = allowed (not allowed if not set) +# PSMP support: [PSMP] (disabled if not set) +# L-SIG TXOP protection support: [LSIG-TXOP-PROT] (disabled if not set) +#ht_capab=[SHORT-GI-20] + +# Require stations to support HT PHY (reject association if they do not) +#require_ht=1 + +##### IEEE 802.11ac related configuration ##################################### + +# ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled +# 0 = disabled (default) +# 1 = enabled +# Note: You will also need to enable WMM for full VHT functionality. +#ieee80211ac=1 + +# vht_capab: VHT capabilities (list of flags) +# +# vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454] +# Indicates maximum MPDU length +# 0 = 3895 octets (default) +# 1 = 7991 octets +# 2 = 11454 octets +# 3 = reserved +# +# supported_chan_width: [VHT160] [VHT160-80PLUS80] +# Indicates supported Channel widths +# 0 = 160 MHz & 80+80 channel widths are not supported (default) +# 1 = 160 MHz channel width is supported +# 2 = 160 MHz & 80+80 channel widths are supported +# 3 = reserved +# +# Rx LDPC coding capability: [RXLDPC] +# Indicates support for receiving LDPC coded pkts +# 0 = Not supported (default) +# 1 = Supported +# +# Short GI for 80 MHz: [SHORT-GI-80] +# Indicates short GI support for reception of packets transmitted with TXVECTOR +# params format equal to VHT and CBW = 80Mhz +# 0 = Not supported (default) +# 1 = Supported +# +# Short GI for 160 MHz: [SHORT-GI-160] +# Indicates short GI support for reception of packets transmitted with TXVECTOR +# params format equal to VHT and CBW = 160Mhz +# 0 = Not supported (default) +# 1 = Supported +# +# Tx STBC: [TX-STBC-2BY1] +# Indicates support for the transmission of at least 2x1 STBC +# 0 = Not supported (default) +# 1 = Supported +# +# Rx STBC: [RX-STBC-1] [RX-STBC-12] [RX-STBC-123] [RX-STBC-1234] +# Indicates support for the reception of PPDUs using STBC +# 0 = Not supported (default) +# 1 = support of one spatial stream +# 2 = support of one and two spatial streams +# 3 = support of one, two and three spatial streams +# 4 = support of one, two, three and four spatial streams +# 5,6,7 = reserved +# +# SU Beamformer Capable: [SU-BEAMFORMER] +# Indicates support for operation as a single user beamformer +# 0 = Not supported (default) +# 1 = Supported +# +# SU Beamformee Capable: [SU-BEAMFORMEE] +# Indicates support for operation as a single user beamformee +# 0 = Not supported (default) +# 1 = Supported +# +# Compressed Steering Number of Beamformer Antennas Supported: [BF-ANTENNA-2] +# Beamformee's capability indicating the maximum number of beamformer +# antennas the beamformee can support when sending compressed beamforming +# feedback +# If SU beamformer capable, set to maximum value minus 1 +# else reserved (default) +# +# Number of Sounding Dimensions: [SOUNDING-DIMENSION-2] +# Beamformer's capability indicating the maximum value of the NUM_STS parameter +# in the TXVECTOR of a VHT NDP +# If SU beamformer capable, set to maximum value minus 1 +# else reserved (default) +# +# MU Beamformer Capable: [MU-BEAMFORMER] +# Indicates support for operation as an MU beamformer +# 0 = Not supported or sent by Non-AP STA (default) +# 1 = Supported +# +# MU Beamformee Capable: [MU-BEAMFORMEE] +# Indicates support for operation as an MU beamformee +# 0 = Not supported or sent by AP (default) +# 1 = Supported +# +# VHT TXOP PS: [VHT-TXOP-PS] +# Indicates whether or not the AP supports VHT TXOP Power Save Mode +# or whether or not the STA is in VHT TXOP Power Save mode +# 0 = VHT AP doesnt support VHT TXOP PS mode (OR) VHT Sta not in VHT TXOP PS +# mode +# 1 = VHT AP supports VHT TXOP PS mode (OR) VHT Sta is in VHT TXOP power save +# mode +# +# +HTC-VHT Capable: [HTC-VHT] +# Indicates whether or not the STA supports receiving a VHT variant HT Control +# field. +# 0 = Not supported (default) +# 1 = supported +# +# Maximum A-MPDU Length Exponent: [MAX-A-MPDU-LEN-EXP0]..[MAX-A-MPDU-LEN-EXP7] +# Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv +# This field is an integer in the range of 0 to 7. +# The length defined by this field is equal to +# 2 pow(13 + Maximum A-MPDU Length Exponent) -1 octets +# +# VHT Link Adaptation Capable: [VHT-LINK-ADAPT2] [VHT-LINK-ADAPT3] +# Indicates whether or not the STA supports link adaptation using VHT variant +# HT Control field +# If +HTC-VHTcapable is 1 +# 0 = (no feedback) if the STA does not provide VHT MFB (default) +# 1 = reserved +# 2 = (Unsolicited) if the STA provides only unsolicited VHT MFB +# 3 = (Both) if the STA can provide VHT MFB in response to VHT MRQ and if the +# STA provides unsolicited VHT MFB +# Reserved if +HTC-VHTcapable is 0 +# +# Rx Antenna Pattern Consistency: [RX-ANTENNA-PATTERN] +# Indicates the possibility of Rx antenna pattern change +# 0 = Rx antenna pattern might change during the lifetime of an association +# 1 = Rx antenna pattern does not change during the lifetime of an association +# +# Tx Antenna Pattern Consistency: [TX-ANTENNA-PATTERN] +# Indicates the possibility of Tx antenna pattern change +# 0 = Tx antenna pattern might change during the lifetime of an association +# 1 = Tx antenna pattern does not change during the lifetime of an association +#vht_capab=[SHORT-GI-80][HTC-VHT] +# +# Require stations to support VHT PHY (reject association if they do not) +#require_vht=1 + +# 0 = 20 or 40 MHz operating Channel width +# 1 = 80 MHz channel width +# 2 = 160 MHz channel width +# 3 = 80+80 MHz channel width +#vht_oper_chwidth=1 +# +# center freq = 5 GHz + (5 * index) +# So index 42 gives center freq 5.210 GHz +# which is channel 42 in 5G band +# +#vht_oper_centr_freq_seg0_idx=42 +# +# center freq = 5 GHz + (5 * index) +# So index 159 gives center freq 5.795 GHz +# which is channel 159 in 5G band +# +#vht_oper_centr_freq_seg1_idx=159 + +##### IEEE 802.1X-2004 related configuration ################################## + +# Require IEEE 802.1X authorization +#ieee8021x=1 + +# IEEE 802.1X/EAPOL version +# hostapd is implemented based on IEEE Std 802.1X-2004 which defines EAPOL +# version 2. However, there are many client implementations that do not handle +# the new version number correctly (they seem to drop the frames completely). +# In order to make hostapd interoperate with these clients, the version number +# can be set to the older version (1) with this configuration value. +#eapol_version=2 + +# Optional displayable message sent with EAP Request-Identity. The first \0 +# in this string will be converted to ASCII-0 (nul). This can be used to +# separate network info (comma separated list of attribute=value pairs); see, +# e.g., RFC 4284. +#eap_message=hello +#eap_message=hello\0networkid=netw,nasid=foo,portid=0,NAIRealms=example.com + +# WEP rekeying (disabled if key lengths are not set or are set to 0) +# Key lengths for default/broadcast and individual/unicast keys: +# 5 = 40-bit WEP (also known as 64-bit WEP with 40 secret bits) +# 13 = 104-bit WEP (also known as 128-bit WEP with 104 secret bits) +#wep_key_len_broadcast=5 +#wep_key_len_unicast=5 +# Rekeying period in seconds. 0 = do not rekey (i.e., set keys only once) +#wep_rekey_period=300 + +# EAPOL-Key index workaround (set bit7) for WinXP Supplicant (needed only if +# only broadcast keys are used) +eapol_key_index_workaround=0 + +# EAP reauthentication period in seconds (default: 3600 seconds; 0 = disable +# reauthentication). +#eap_reauth_period=3600 + +# Use PAE group address (01:80:c2:00:00:03) instead of individual target +# address when sending EAPOL frames with driver=wired. This is the most common +# mechanism used in wired authentication, but it also requires that the port +# is only used by one station. +#use_pae_group_addr=1 + +##### Integrated EAP server ################################################### + +# Optionally, hostapd can be configured to use an integrated EAP server +# to process EAP authentication locally without need for an external RADIUS +# server. This functionality can be used both as a local authentication server +# for IEEE 802.1X/EAPOL and as a RADIUS server for other devices. + +# Use integrated EAP server instead of external RADIUS authentication +# server. This is also needed if hostapd is configured to act as a RADIUS +# authentication server. +#eap_server=0 + +# Path for EAP server user database +# If SQLite support is included, this can be set to "sqlite:/path/to/sqlite.db" +# to use SQLite database instead of a text file. +#eap_user_file=/etc/hostapd.eap_user + +# CA certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS +#ca_cert=/etc/hostapd.ca.pem + +# Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS +#server_cert=/etc/hostapd.server.pem + +# Private key matching with the server certificate for EAP-TLS/PEAP/TTLS +# This may point to the same file as server_cert if both certificate and key +# are included in a single file. PKCS#12 (PFX) file (.p12/.pfx) can also be +# used by commenting out server_cert and specifying the PFX file as the +# private_key. +#private_key=/etc/hostapd.server.prv + +# Passphrase for private key +#private_key_passwd=secret passphrase + +# Enable CRL verification. +# Note: hostapd does not yet support CRL downloading based on CDP. Thus, a +# valid CRL signed by the CA is required to be included in the ca_cert file. +# This can be done by using PEM format for CA certificate and CRL and +# concatenating these into one file. Whenever CRL changes, hostapd needs to be +# restarted to take the new CRL into use. +# 0 = do not verify CRLs (default) +# 1 = check the CRL of the user certificate +# 2 = check all CRLs in the certificate path +#check_crl=1 + +# dh_file: File path to DH/DSA parameters file (in PEM format) +# This is an optional configuration file for setting parameters for an +# ephemeral DH key exchange. In most cases, the default RSA authentication does +# not use this configuration. However, it is possible setup RSA to use +# ephemeral DH key exchange. In addition, ciphers with DSA keys always use +# ephemeral DH keys. This can be used to achieve forward secrecy. If the file +# is in DSA parameters format, it will be automatically converted into DH +# params. This parameter is required if anonymous EAP-FAST is used. +# You can generate DH parameters file with OpenSSL, e.g., +# "openssl dhparam -out /etc/hostapd.dh.pem 1024" +#dh_file=/etc/hostapd.dh.pem + +# Fragment size for EAP methods +#fragment_size=1400 + +# Finite cyclic group for EAP-pwd. Number maps to group of domain parameters +# using the IANA repository for IKE (RFC 2409). +#pwd_group=19 + +# Configuration data for EAP-SIM database/authentication gateway interface. +# This is a text string in implementation specific format. The example +# implementation in eap_sim_db.c uses this as the UNIX domain socket name for +# the HLR/AuC gateway (e.g., hlr_auc_gw). In this case, the path uses "unix:" +# prefix. If hostapd is built with SQLite support (CONFIG_SQLITE=y in .config), +# database file can be described with an optional db= parameter. +#eap_sim_db=unix:/tmp/hlr_auc_gw.sock +#eap_sim_db=unix:/tmp/hlr_auc_gw.sock db=/tmp/hostapd.db + +# Encryption key for EAP-FAST PAC-Opaque values. This key must be a secret, +# random value. It is configured as a 16-octet value in hex format. It can be +# generated, e.g., with the following command: +# od -tx1 -v -N16 /dev/random | colrm 1 8 | tr -d ' ' +#pac_opaque_encr_key=000102030405060708090a0b0c0d0e0f + +# EAP-FAST authority identity (A-ID) +# A-ID indicates the identity of the authority that issues PACs. The A-ID +# should be unique across all issuing servers. In theory, this is a variable +# length field, but due to some existing implementations requiring A-ID to be +# 16 octets in length, it is strongly recommended to use that length for the +# field to provid interoperability with deployed peer implementations. This +# field is configured in hex format. +#eap_fast_a_id=101112131415161718191a1b1c1d1e1f + +# EAP-FAST authority identifier information (A-ID-Info) +# This is a user-friendly name for the A-ID. For example, the enterprise name +# and server name in a human-readable format. This field is encoded as UTF-8. +#eap_fast_a_id_info=test server + +# Enable/disable different EAP-FAST provisioning modes: +#0 = provisioning disabled +#1 = only anonymous provisioning allowed +#2 = only authenticated provisioning allowed +#3 = both provisioning modes allowed (default) +#eap_fast_prov=3 + +# EAP-FAST PAC-Key lifetime in seconds (hard limit) +#pac_key_lifetime=604800 + +# EAP-FAST PAC-Key refresh time in seconds (soft limit on remaining hard +# limit). The server will generate a new PAC-Key when this number of seconds +# (or fewer) of the lifetime remains. +#pac_key_refresh_time=86400 + +# EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND +# (default: 0 = disabled). +#eap_sim_aka_result_ind=1 + +# Trusted Network Connect (TNC) +# If enabled, TNC validation will be required before the peer is allowed to +# connect. Note: This is only used with EAP-TTLS and EAP-FAST. If any other +# EAP method is enabled, the peer will be allowed to connect without TNC. +#tnc=1 + + +##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) ####################### + +# Interface to be used for IAPP broadcast packets +#iapp_interface=eth0 + + +##### RADIUS client configuration ############################################# +# for IEEE 802.1X with external Authentication Server, IEEE 802.11 +# authentication with external ACL for MAC addresses, and accounting + +# The own IP address of the access point (used as NAS-IP-Address) +own_ip_addr=127.0.0.1 + +# Optional NAS-Identifier string for RADIUS messages. When used, this should be +# a unique to the NAS within the scope of the RADIUS server. For example, a +# fully qualified domain name can be used here. +# When using IEEE 802.11r, nas_identifier must be set and must be between 1 and +# 48 octets long. +#nas_identifier=ap.example.com + +# RADIUS authentication server +#auth_server_addr=127.0.0.1 +#auth_server_port=1812 +#auth_server_shared_secret=secret + +# RADIUS accounting server +#acct_server_addr=127.0.0.1 +#acct_server_port=1813 +#acct_server_shared_secret=secret + +# Secondary RADIUS servers; to be used if primary one does not reply to +# RADIUS packets. These are optional and there can be more than one secondary +# server listed. +#auth_server_addr=127.0.0.2 +#auth_server_port=1812 +#auth_server_shared_secret=secret2 +# +#acct_server_addr=127.0.0.2 +#acct_server_port=1813 +#acct_server_shared_secret=secret2 + +# Retry interval for trying to return to the primary RADIUS server (in +# seconds). RADIUS client code will automatically try to use the next server +# when the current server is not replying to requests. If this interval is set, +# primary server will be retried after configured amount of time even if the +# currently used secondary server is still working. +#radius_retry_primary_interval=600 + + +# Interim accounting update interval +# If this is set (larger than 0) and acct_server is configured, hostapd will +# send interim accounting updates every N seconds. Note: if set, this overrides +# possible Acct-Interim-Interval attribute in Access-Accept message. Thus, this +# value should not be configured in hostapd.conf, if RADIUS server is used to +# control the interim interval. +# This value should not be less 600 (10 minutes) and must not be less than +# 60 (1 minute). +#radius_acct_interim_interval=600 + +# Request Chargeable-User-Identity (RFC 4372) +# This parameter can be used to configure hostapd to request CUI from the +# RADIUS server by including Chargeable-User-Identity attribute into +# Access-Request packets. +#radius_request_cui=1 + +# Dynamic VLAN mode; allow RADIUS authentication server to decide which VLAN +# is used for the stations. This information is parsed from following RADIUS +# attributes based on RFC 3580 and RFC 2868: Tunnel-Type (value 13 = VLAN), +# Tunnel-Medium-Type (value 6 = IEEE 802), Tunnel-Private-Group-ID (value +# VLANID as a string). vlan_file option below must be configured if dynamic +# VLANs are used. Optionally, the local MAC ACL list (accept_mac_file) can be +# used to set static client MAC address to VLAN ID mapping. +# 0 = disabled (default) +# 1 = option; use default interface if RADIUS server does not include VLAN ID +# 2 = required; reject authentication if RADIUS server does not include VLAN ID +#dynamic_vlan=0 + +# VLAN interface list for dynamic VLAN mode is read from a separate text file. +# This list is used to map VLAN ID from the RADIUS server to a network +# interface. Each station is bound to one interface in the same way as with +# multiple BSSIDs or SSIDs. Each line in this text file is defining a new +# interface and the line must include VLAN ID and interface name separated by +# white space (space or tab). +#vlan_file=/etc/hostapd.vlan + +# Interface where 802.1q tagged packets should appear when a RADIUS server is +# used to determine which VLAN a station is on. hostapd creates a bridge for +# each VLAN. Then hostapd adds a VLAN interface (associated with the interface +# indicated by 'vlan_tagged_interface') and the appropriate wireless interface +# to the bridge. +#vlan_tagged_interface=eth0 + +# When hostapd creates a VLAN interface on vlan_tagged_interfaces, it needs +# to know how to name it. +# 0 = vlan, e.g., vlan1 +# 1 = ., e.g. eth0.1 +#vlan_naming=0 + +# Arbitrary RADIUS attributes can be added into Access-Request and +# Accounting-Request packets by specifying the contents of the attributes with +# the following configuration parameters. There can be multiple of these to +# add multiple attributes. These parameters can also be used to override some +# of the attributes added automatically by hostapd. +# Format: [:] +# attr_id: RADIUS attribute type (e.g., 26 = Vendor-Specific) +# syntax: s = string (UTF-8), d = integer, x = octet string +# value: attribute value in format indicated by the syntax +# If syntax and value parts are omitted, a null value (single 0x00 octet) is +# used. +# +# Additional Access-Request attributes +# radius_auth_req_attr=[:] +# Examples: +# Operator-Name = "Operator" +#radius_auth_req_attr=126:s:Operator +# Service-Type = Framed (2) +#radius_auth_req_attr=6:d:2 +# Connect-Info = "testing" (this overrides the automatically generated value) +#radius_auth_req_attr=77:s:testing +# Same Connect-Info value set as a hexdump +#radius_auth_req_attr=77:x:74657374696e67 + +# +# Additional Accounting-Request attributes +# radius_acct_req_attr=[:] +# Examples: +# Operator-Name = "Operator" +#radius_acct_req_attr=126:s:Operator + +# Dynamic Authorization Extensions (RFC 5176) +# This mechanism can be used to allow dynamic changes to user session based on +# commands from a RADIUS server (or some other disconnect client that has the +# needed session information). For example, Disconnect message can be used to +# request an associated station to be disconnected. +# +# This is disabled by default. Set radius_das_port to non-zero UDP port +# number to enable. +#radius_das_port=3799 +# +# DAS client (the host that can send Disconnect/CoA requests) and shared secret +#radius_das_client=192.168.1.123 shared secret here +# +# DAS Event-Timestamp time window in seconds +#radius_das_time_window=300 +# +# DAS require Event-Timestamp +#radius_das_require_event_timestamp=1 + +##### RADIUS authentication server configuration ############################## + +# hostapd can be used as a RADIUS authentication server for other hosts. This +# requires that the integrated EAP server is also enabled and both +# authentication services are sharing the same configuration. + +# File name of the RADIUS clients configuration for the RADIUS server. If this +# commented out, RADIUS server is disabled. +#radius_server_clients=/etc/hostapd.radius_clients + +# The UDP port number for the RADIUS authentication server +#radius_server_auth_port=1812 + +# Use IPv6 with RADIUS server (IPv4 will also be supported using IPv6 API) +#radius_server_ipv6=1 + + +##### WPA/IEEE 802.11i configuration ########################################## + +# Enable WPA. Setting this variable configures the AP to require WPA (either +# WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either +# wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK. +# Instead of wpa_psk / wpa_passphrase, wpa_psk_radius might suffice. +# For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys), +# RADIUS authentication server must be configured, and WPA-EAP must be included +# in wpa_key_mgmt. +# This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0) +# and/or WPA2 (full IEEE 802.11i/RSN): +# bit0 = WPA +# bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled) +#wpa=1 + +# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit +# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase +# (8..63 characters) that will be converted to PSK. This conversion uses SSID +# so the PSK changes when ASCII passphrase is used and the SSID is changed. +# wpa_psk (dot11RSNAConfigPSKValue) +# wpa_passphrase (dot11RSNAConfigPSKPassPhrase) +#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef +#wpa_passphrase=secret passphrase + +# Optionally, WPA PSKs can be read from a separate text file (containing list +# of (PSK,MAC address) pairs. This allows more than one PSK to be configured. +# Use absolute path name to make sure that the files can be read on SIGHUP +# configuration reloads. +#wpa_psk_file=/etc/hostapd.wpa_psk + +# Optionally, WPA passphrase can be received from RADIUS authentication server +# This requires macaddr_acl to be set to 2 (RADIUS) +# 0 = disabled (default) +# 1 = optional; use default passphrase/psk if RADIUS server does not include +# Tunnel-Password +# 2 = required; reject authentication if RADIUS server does not include +# Tunnel-Password +#wpa_psk_radius=0 + +# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The +# entries are separated with a space. WPA-PSK-SHA256 and WPA-EAP-SHA256 can be +# added to enable SHA256-based stronger algorithms. +# (dot11RSNAConfigAuthenticationSuitesTable) +#wpa_key_mgmt=WPA-PSK WPA-EAP + +# Set of accepted cipher suites (encryption algorithms) for pairwise keys +# (unicast packets). This is a space separated list of algorithms: +# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] +# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] +# Group cipher suite (encryption algorithm for broadcast and multicast frames) +# is automatically selected based on this configuration. If only CCMP is +# allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise, +# TKIP will be used as the group cipher. +# (dot11RSNAConfigPairwiseCiphersTable) +# Pairwise cipher for WPA (v1) (default: TKIP) +#wpa_pairwise=TKIP CCMP +# Pairwise cipher for RSN/WPA2 (default: use wpa_pairwise value) +#rsn_pairwise=CCMP + +# Time interval for rekeying GTK (broadcast/multicast encryption keys) in +# seconds. (dot11RSNAConfigGroupRekeyTime) +#wpa_group_rekey=600 + +# Rekey GTK when any STA that possesses the current GTK is leaving the BSS. +# (dot11RSNAConfigGroupRekeyStrict) +#wpa_strict_rekey=1 + +# Time interval for rekeying GMK (master key used internally to generate GTKs +# (in seconds). +#wpa_gmk_rekey=86400 + +# Maximum lifetime for PTK in seconds. This can be used to enforce rekeying of +# PTK to mitigate some attacks against TKIP deficiencies. +#wpa_ptk_rekey=600 + +# Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up +# roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN +# authentication and key handshake before actually associating with a new AP. +# (dot11RSNAPreauthenticationEnabled) +#rsn_preauth=1 +# +# Space separated list of interfaces from which pre-authentication frames are +# accepted (e.g., 'eth0' or 'eth0 wlan0wds0'. This list should include all +# interface that are used for connections to other APs. This could include +# wired interfaces and WDS links. The normal wireless data interface towards +# associated stations (e.g., wlan0) should not be added, since +# pre-authentication is only used with APs other than the currently associated +# one. +#rsn_preauth_interfaces=eth0 + +# peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e) is +# allowed. This is only used with RSN/WPA2. +# 0 = disabled (default) +# 1 = enabled +#peerkey=1 + +# ieee80211w: Whether management frame protection (MFP) is enabled +# 0 = disabled (default) +# 1 = optional +# 2 = required +#ieee80211w=0 + +# Association SA Query maximum timeout (in TU = 1.024 ms; for MFP) +# (maximum time to wait for a SA Query response) +# dot11AssociationSAQueryMaximumTimeout, 1...4294967295 +#assoc_sa_query_max_timeout=1000 + +# Association SA Query retry timeout (in TU = 1.024 ms; for MFP) +# (time between two subsequent SA Query requests) +# dot11AssociationSAQueryRetryTimeout, 1...4294967295 +#assoc_sa_query_retry_timeout=201 + +# disable_pmksa_caching: Disable PMKSA caching +# This parameter can be used to disable caching of PMKSA created through EAP +# authentication. RSN preauthentication may still end up using PMKSA caching if +# it is enabled (rsn_preauth=1). +# 0 = PMKSA caching enabled (default) +# 1 = PMKSA caching disabled +#disable_pmksa_caching=0 + +# okc: Opportunistic Key Caching (aka Proactive Key Caching) +# Allow PMK cache to be shared opportunistically among configured interfaces +# and BSSes (i.e., all configurations within a single hostapd process). +# 0 = disabled (default) +# 1 = enabled +#okc=1 + + +##### IEEE 802.11r configuration ############################################## + +# Mobility Domain identifier (dot11FTMobilityDomainID, MDID) +# MDID is used to indicate a group of APs (within an ESS, i.e., sharing the +# same SSID) between which a STA can use Fast BSS Transition. +# 2-octet identifier as a hex string. +#mobility_domain=a1b2 + +# PMK-R0 Key Holder identifier (dot11FTR0KeyHolderID) +# 1 to 48 octet identifier. +# This is configured with nas_identifier (see RADIUS client section above). + +# Default lifetime of the PMK-RO in minutes; range 1..65535 +# (dot11FTR0KeyLifetime) +#r0_key_lifetime=10000 + +# PMK-R1 Key Holder identifier (dot11FTR1KeyHolderID) +# 6-octet identifier as a hex string. +#r1_key_holder=000102030405 + +# Reassociation deadline in time units (TUs / 1.024 ms; range 1000..65535) +# (dot11FTReassociationDeadline) +#reassociation_deadline=1000 + +# List of R0KHs in the same Mobility Domain +# format: <128-bit key as hex string> +# This list is used to map R0KH-ID (NAS Identifier) to a destination MAC +# address when requesting PMK-R1 key from the R0KH that the STA used during the +# Initial Mobility Domain Association. +#r0kh=02:01:02:03:04:05 r0kh-1.example.com 000102030405060708090a0b0c0d0e0f +#r0kh=02:01:02:03:04:06 r0kh-2.example.com 00112233445566778899aabbccddeeff +# And so on.. One line per R0KH. + +# List of R1KHs in the same Mobility Domain +# format: <128-bit key as hex string> +# This list is used to map R1KH-ID to a destination MAC address when sending +# PMK-R1 key from the R0KH. This is also the list of authorized R1KHs in the MD +# that can request PMK-R1 keys. +#r1kh=02:01:02:03:04:05 02:11:22:33:44:55 000102030405060708090a0b0c0d0e0f +#r1kh=02:01:02:03:04:06 02:11:22:33:44:66 00112233445566778899aabbccddeeff +# And so on.. One line per R1KH. + +# Whether PMK-R1 push is enabled at R0KH +# 0 = do not push PMK-R1 to all configured R1KHs (default) +# 1 = push PMK-R1 to all configured R1KHs whenever a new PMK-R0 is derived +#pmk_r1_push=1 + +##### Neighbor table ########################################################## +# Maximum number of entries kept in AP table (either for neigbor table or for +# detecting Overlapping Legacy BSS Condition). The oldest entry will be +# removed when adding a new entry that would make the list grow over this +# limit. Note! WFA certification for IEEE 802.11g requires that OLBC is +# enabled, so this field should not be set to 0 when using IEEE 802.11g. +# default: 255 +#ap_table_max_size=255 + +# Number of seconds of no frames received after which entries may be deleted +# from the AP table. Since passive scanning is not usually performed frequently +# this should not be set to very small value. In addition, there is no +# guarantee that every scan cycle will receive beacon frames from the +# neighboring APs. +# default: 60 +#ap_table_expiration_time=3600 + + +##### Wi-Fi Protected Setup (WPS) ############################################# + +# WPS state +# 0 = WPS disabled (default) +# 1 = WPS enabled, not configured +# 2 = WPS enabled, configured +#wps_state=2 + +# AP can be configured into a locked state where new WPS Registrar are not +# accepted, but previously authorized Registrars (including the internal one) +# can continue to add new Enrollees. +#ap_setup_locked=1 + +# Universally Unique IDentifier (UUID; see RFC 4122) of the device +# This value is used as the UUID for the internal WPS Registrar. If the AP +# is also using UPnP, this value should be set to the device's UPnP UUID. +# If not configured, UUID will be generated based on the local MAC address. +#uuid=12345678-9abc-def0-1234-56789abcdef0 + +# Note: If wpa_psk_file is set, WPS is used to generate random, per-device PSKs +# that will be appended to the wpa_psk_file. If wpa_psk_file is not set, the +# default PSK (wpa_psk/wpa_passphrase) will be delivered to Enrollees. Use of +# per-device PSKs is recommended as the more secure option (i.e., make sure to +# set wpa_psk_file when using WPS with WPA-PSK). + +# When an Enrollee requests access to the network with PIN method, the Enrollee +# PIN will need to be entered for the Registrar. PIN request notifications are +# sent to hostapd ctrl_iface monitor. In addition, they can be written to a +# text file that could be used, e.g., to populate the AP administration UI with +# pending PIN requests. If the following variable is set, the PIN requests will +# be written to the configured file. +#wps_pin_requests=/var/run/hostapd_wps_pin_requests + +# Device Name +# User-friendly description of device; up to 32 octets encoded in UTF-8 +#device_name=Wireless AP + +# Manufacturer +# The manufacturer of the device (up to 64 ASCII characters) +#manufacturer=Company + +# Model Name +# Model of the device (up to 32 ASCII characters) +#model_name=WAP + +# Model Number +# Additional device description (up to 32 ASCII characters) +#model_number=123 + +# Serial Number +# Serial number of the device (up to 32 characters) +#serial_number=12345 + +# Primary Device Type +# Used format: -- +# categ = Category as an integer value +# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for +# default WPS OUI +# subcateg = OUI-specific Sub Category as an integer value +# Examples: +# 1-0050F204-1 (Computer / PC) +# 1-0050F204-2 (Computer / Server) +# 5-0050F204-1 (Storage / NAS) +# 6-0050F204-1 (Network Infrastructure / AP) +#device_type=6-0050F204-1 + +# OS Version +# 4-octet operating system version number (hex string) +#os_version=01020300 + +# Config Methods +# List of the supported configuration methods +# Available methods: usba ethernet label display ext_nfc_token int_nfc_token +# nfc_interface push_button keypad virtual_display physical_display +# virtual_push_button physical_push_button +#config_methods=label virtual_display virtual_push_button keypad + +# WPS capability discovery workaround for PBC with Windows 7 +# Windows 7 uses incorrect way of figuring out AP's WPS capabilities by acting +# as a Registrar and using M1 from the AP. The config methods attribute in that +# message is supposed to indicate only the configuration method supported by +# the AP in Enrollee role, i.e., to add an external Registrar. For that case, +# PBC shall not be used and as such, the PushButton config method is removed +# from M1 by default. If pbc_in_m1=1 is included in the configuration file, +# the PushButton config method is left in M1 (if included in config_methods +# parameter) to allow Windows 7 to use PBC instead of PIN (e.g., from a label +# in the AP). +#pbc_in_m1=1 + +# Static access point PIN for initial configuration and adding Registrars +# If not set, hostapd will not allow external WPS Registrars to control the +# access point. The AP PIN can also be set at runtime with hostapd_cli +# wps_ap_pin command. Use of temporary (enabled by user action) and random +# AP PIN is much more secure than configuring a static AP PIN here. As such, +# use of the ap_pin parameter is not recommended if the AP device has means for +# displaying a random PIN. +#ap_pin=12345670 + +# Skip building of automatic WPS credential +# This can be used to allow the automatically generated Credential attribute to +# be replaced with pre-configured Credential(s). +#skip_cred_build=1 + +# Additional Credential attribute(s) +# This option can be used to add pre-configured Credential attributes into M8 +# message when acting as a Registrar. If skip_cred_build=1, this data will also +# be able to override the Credential attribute that would have otherwise been +# automatically generated based on network configuration. This configuration +# option points to an external file that much contain the WPS Credential +# attribute(s) as binary data. +#extra_cred=hostapd.cred + +# Credential processing +# 0 = process received credentials internally (default) +# 1 = do not process received credentials; just pass them over ctrl_iface to +# external program(s) +# 2 = process received credentials internally and pass them over ctrl_iface +# to external program(s) +# Note: With wps_cred_processing=1, skip_cred_build should be set to 1 and +# extra_cred be used to provide the Credential data for Enrollees. +# +# wps_cred_processing=1 will disabled automatic updates of hostapd.conf file +# both for Credential processing and for marking AP Setup Locked based on +# validation failures of AP PIN. An external program is responsible on updating +# the configuration appropriately in this case. +#wps_cred_processing=0 + +# AP Settings Attributes for M7 +# By default, hostapd generates the AP Settings Attributes for M7 based on the +# current configuration. It is possible to override this by providing a file +# with pre-configured attributes. This is similar to extra_cred file format, +# but the AP Settings attributes are not encapsulated in a Credential +# attribute. +#ap_settings=hostapd.ap_settings + +# WPS UPnP interface +# If set, support for external Registrars is enabled. +#upnp_iface=br0 + +# Friendly Name (required for UPnP) +# Short description for end use. Should be less than 64 characters. +#friendly_name=WPS Access Point + +# Manufacturer URL (optional for UPnP) +#manufacturer_url=http://www.example.com/ + +# Model Description (recommended for UPnP) +# Long description for end user. Should be less than 128 characters. +#model_description=Wireless Access Point + +# Model URL (optional for UPnP) +#model_url=http://www.example.com/model/ + +# Universal Product Code (optional for UPnP) +# 12-digit, all-numeric code that identifies the consumer package. +#upc=123456789012 + +# WPS RF Bands (a = 5G, b = 2.4G, g = 2.4G, ag = dual band) +# This value should be set according to RF band(s) supported by the AP if +# hw_mode is not set. For dual band dual concurrent devices, this needs to be +# set to ag to allow both RF bands to be advertized. +#wps_rf_bands=ag + +# NFC password token for WPS +# These parameters can be used to configure a fixed NFC password token for the +# AP. This can be generated, e.g., with nfc_pw_token from wpa_supplicant. When +# these parameters are used, the AP is assumed to be deployed with a NFC tag +# that includes the matching NFC password token (e.g., written based on the +# NDEF record from nfc_pw_token). +# +#wps_nfc_dev_pw_id: Device Password ID (16..65535) +#wps_nfc_dh_pubkey: Hexdump of DH Public Key +#wps_nfc_dh_privkey: Hexdump of DH Private Key +#wps_nfc_dev_pw: Hexdump of Device Password + +##### Wi-Fi Direct (P2P) ###################################################### + +# Enable P2P Device management +#manage_p2p=1 + +# Allow cross connection +#allow_cross_connection=1 + +#### TDLS (IEEE 802.11z-2010) ################################################# + +# Prohibit use of TDLS in this BSS +#tdls_prohibit=1 + +# Prohibit use of TDLS Channel Switching in this BSS +#tdls_prohibit_chan_switch=1 + +##### IEEE 802.11v-2011 ####################################################### + +# Time advertisement +# 0 = disabled (default) +# 2 = UTC time at which the TSF timer is 0 +#time_advertisement=2 + +# Local time zone as specified in 8.3 of IEEE Std 1003.1-2004: +# stdoffset[dst[offset][,start[/time],end[/time]]] +#time_zone=EST5 + +# WNM-Sleep Mode (extended sleep mode for stations) +# 0 = disabled (default) +# 1 = enabled (allow stations to use WNM-Sleep Mode) +#wnm_sleep_mode=1 + +# BSS Transition Management +# 0 = disabled (default) +# 1 = enabled +#bss_transition=1 + +##### IEEE 802.11u-2011 ####################################################### + +# Enable Interworking service +#interworking=1 + +# Access Network Type +# 0 = Private network +# 1 = Private network with guest access +# 2 = Chargeable public network +# 3 = Free public network +# 4 = Personal device network +# 5 = Emergency services only network +# 14 = Test or experimental +# 15 = Wildcard +#access_network_type=0 + +# Whether the network provides connectivity to the Internet +# 0 = Unspecified +# 1 = Network provides connectivity to the Internet +#internet=1 + +# Additional Step Required for Access +# Note: This is only used with open network, i.e., ASRA shall ne set to 0 if +# RSN is used. +#asra=0 + +# Emergency services reachable +#esr=0 + +# Unauthenticated emergency service accessible +#uesa=0 + +# Venue Info (optional) +# The available values are defined in IEEE Std 802.11u-2011, 7.3.1.34. +# Example values (group,type): +# 0,0 = Unspecified +# 1,7 = Convention Center +# 1,13 = Coffee Shop +# 2,0 = Unspecified Business +# 7,1 Private Residence +#venue_group=7 +#venue_type=1 + +# Homogeneous ESS identifier (optional; dot11HESSID) +# If set, this shall be identifical to one of the BSSIDs in the homogeneous +# ESS and this shall be set to the same value across all BSSs in homogeneous +# ESS. +#hessid=02:03:04:05:06:07 + +# Roaming Consortium List +# Arbitrary number of Roaming Consortium OIs can be configured with each line +# adding a new OI to the list. The first three entries are available through +# Beacon and Probe Response frames. Any additional entry will be available only +# through ANQP queries. Each OI is between 3 and 15 octets and is configured as +# a hexstring. +#roaming_consortium=021122 +#roaming_consortium=2233445566 + +# Venue Name information +# This parameter can be used to configure one or more Venue Name Duples for +# Venue Name ANQP information. Each entry has a two or three character language +# code (ISO-639) separated by colon from the venue name string. +# Note that venue_group and venue_type have to be set for Venue Name +# information to be complete. +#venue_name=eng:Example venue +#venue_name=fin:Esimerkkipaikka + +# Network Authentication Type +# This parameter indicates what type of network authentication is used in the +# network. +# format: [redirect URL] +# Network Authentication Type Indicator values: +# 00 = Acceptance of terms and conditions +# 01 = On-line enrollment supported +# 02 = http/https redirection +# 03 = DNS redirection +#network_auth_type=00 +#network_auth_type=02http://www.example.com/redirect/me/here/ + +# IP Address Type Availability +# format: <1-octet encoded value as hex str> +# (ipv4_type & 0x3f) << 2 | (ipv6_type & 0x3) +# ipv4_type: +# 0 = Address type not available +# 1 = Public IPv4 address available +# 2 = Port-restricted IPv4 address available +# 3 = Single NATed private IPv4 address available +# 4 = Double NATed private IPv4 address available +# 5 = Port-restricted IPv4 address and single NATed IPv4 address available +# 6 = Port-restricted IPv4 address and double NATed IPv4 address available +# 7 = Availability of the address type is not known +# ipv6_type: +# 0 = Address type not available +# 1 = Address type available +# 2 = Availability of the address type not known +#ipaddr_type_availability=14 + +# Domain Name +# format: [,] +#domain_name=example.com,another.example.com,yet-another.example.com + +# 3GPP Cellular Network information +# format: [;][;...] +#anqp_3gpp_cell_net=244,91;310,026;234,56 + +# NAI Realm information +# One or more realm can be advertised. Each nai_realm line adds a new realm to +# the set. These parameters provide information for stations using Interworking +# network selection to allow automatic connection to a network based on +# credentials. +# format: ,[,][,][,...] +# encoding: +# 0 = Realm formatted in accordance with IETF RFC 4282 +# 1 = UTF-8 formatted character string that is not formatted in +# accordance with IETF RFC 4282 +# NAI Realm(s): Semi-colon delimited NAI Realm(s) +# EAP Method: [:<[AuthParam1:Val1]>][<[AuthParam2:Val2]>][...] +# AuthParam (Table 8-188 in IEEE Std 802.11-2012): +# ID 2 = Non-EAP Inner Authentication Type +# 1 = PAP, 2 = CHAP, 3 = MSCHAP, 4 = MSCHAPV2 +# ID 3 = Inner authentication EAP Method Type +# ID 5 = Credential Type +# 1 = SIM, 2 = USIM, 3 = NFC Secure Element, 4 = Hardware Token, +# 5 = Softoken, 6 = Certificate, 7 = username/password, 9 = Anonymous, +# 10 = Vendor Specific +#nai_realm=0,example.com;example.net +# EAP methods EAP-TLS with certificate and EAP-TTLS/MSCHAPv2 with +# username/password +#nai_realm=0,example.org,13[5:6],21[2:4][5:7] + +##### Hotspot 2.0 ############################################################# + +# Enable Hotspot 2.0 support +#hs20=1 + +# Disable Downstream Group-Addressed Forwarding (DGAF) +# This can be used to configure a network where no group-addressed frames are +# allowed. The AP will not forward any group-address frames to the stations and +# random GTKs are issued for each station to prevent associated stations from +# forging such frames to other stations in the BSS. +#disable_dgaf=1 + +# Operator Friendly Name +# This parameter can be used to configure one or more Operator Friendly Name +# Duples. Each entry has a two or three character language code (ISO-639) +# separated by colon from the operator friendly name string. +#hs20_oper_friendly_name=eng:Example operator +#hs20_oper_friendly_name=fin:Esimerkkioperaattori + +# Connection Capability +# This can be used to advertise what type of IP traffic can be sent through the +# hotspot (e.g., due to firewall allowing/blocking protocols/ports). +# format: :: +# IP Protocol: 1 = ICMP, 6 = TCP, 17 = UDP +# Port Number: 0..65535 +# Status: 0 = Closed, 1 = Open, 2 = Unknown +# Each hs20_conn_capab line is added to the list of advertised tuples. +#hs20_conn_capab=1:0:2 +#hs20_conn_capab=6:22:1 +#hs20_conn_capab=17:5060:0 + +# WAN Metrics +# format: :
:
    :
    :
      : +# WAN Info: B0-B1: Link Status, B2: Symmetric Link, B3: At Capabity +# (encoded as two hex digits) +# Link Status: 1 = Link up, 2 = Link down, 3 = Link in test state +# Downlink Speed: Estimate of WAN backhaul link current downlink speed in kbps; +# 1..4294967295; 0 = unknown +# Uplink Speed: Estimate of WAN backhaul link current uplink speed in kbps +# 1..4294967295; 0 = unknown +# Downlink Load: Current load of downlink WAN connection (scaled to 255 = 100%) +# Uplink Load: Current load of uplink WAN connection (scaled to 255 = 100%) +# Load Measurement Duration: Duration for measuring downlink/uplink load in +# tenths of a second (1..65535); 0 if load cannot be determined +#hs20_wan_metrics=01:8000:1000:80:240:3000 + +# Operating Class Indication +# List of operating classes the BSSes in this ESS use. The Global operating +# classes in Table E-4 of IEEE Std 802.11-2012 Annex E define the values that +# can be used in this. +# format: hexdump of operating class octets +# for example, operating classes 81 (2.4 GHz channels 1-13) and 115 (5 GHz +# channels 36-48): +#hs20_operating_class=5173 + +##### Multiple BSSID support ################################################## +# +# Above configuration is using the default interface (wlan#, or multi-SSID VLAN +# interfaces). Other BSSIDs can be added by using separator 'bss' with +# default interface name to be allocated for the data packets of the new BSS. +# +# hostapd will generate BSSID mask based on the BSSIDs that are +# configured. hostapd will verify that dev_addr & MASK == dev_addr. If this is +# not the case, the MAC address of the radio must be changed before starting +# hostapd (ifconfig wlan0 hw ether ). If a BSSID is configured for +# every secondary BSS, this limitation is not applied at hostapd and other +# masks may be used if the driver supports them (e.g., swap the locally +# administered bit) +# +# BSSIDs are assigned in order to each BSS, unless an explicit BSSID is +# specified using the 'bssid' parameter. +# If an explicit BSSID is specified, it must be chosen such that it: +# - results in a valid MASK that covers it and the dev_addr +# - is not the same as the MAC address of the radio +# - is not the same as any other explicitly specified BSSID +# +# Please note that hostapd uses some of the values configured for the first BSS +# as the defaults for the following BSSes. However, it is recommended that all +# BSSes include explicit configuration of all relevant configuration items. +# +#bss=wlan0_0 +#ssid=test2 +# most of the above items can be used here (apart from radio interface specific +# items, like channel) + +#bss=wlan0_1 +#bssid=00:13:10:95:fe:0b +# ... + diff --git a/source/artinchip/http-wificonfig/config/udhcpd.conf b/source/artinchip/http-wificonfig/config/udhcpd.conf new file mode 100644 index 000000000..6040060b1 --- /dev/null +++ b/source/artinchip/http-wificonfig/config/udhcpd.conf @@ -0,0 +1,4 @@ +start 192.168.1.2 +end 169.168.1.254 + +interface wlan1 diff --git a/source/artinchip/http-wificonfig/html/Aicast.jpg b/source/artinchip/http-wificonfig/html/Aicast.jpg new file mode 100644 index 000000000..759902362 Binary files /dev/null and b/source/artinchip/http-wificonfig/html/Aicast.jpg differ diff --git a/source/artinchip/http-wificonfig/html/fail_result.html b/source/artinchip/http-wificonfig/html/fail_result.html new file mode 100644 index 000000000..db55948e1 --- /dev/null +++ b/source/artinchip/http-wificonfig/html/fail_result.html @@ -0,0 +1,35 @@ + + + + config fail + + + + + + \ No newline at end of file diff --git a/source/artinchip/http-wificonfig/html/index.html b/source/artinchip/http-wificonfig/html/index.html new file mode 100644 index 000000000..eac93eea1 --- /dev/null +++ b/source/artinchip/http-wificonfig/html/index.html @@ -0,0 +1,105 @@ + + + + http-wificonfig + + + + + + + + diff --git a/source/artinchip/http-wificonfig/html/success_result.html b/source/artinchip/http-wificonfig/html/success_result.html new file mode 100644 index 000000000..f9190182d --- /dev/null +++ b/source/artinchip/http-wificonfig/html/success_result.html @@ -0,0 +1,82 @@ + + + + + WiFi sucess + + + + +
      +
      WiFi Configure Sucess!
      +
      Will be closed after 10 Second
      +
      + + + + diff --git a/source/artinchip/http-wificonfig/http.c b/source/artinchip/http-wificonfig/http.c new file mode 100644 index 000000000..9634d1c2a --- /dev/null +++ b/source/artinchip/http-wificonfig/http.c @@ -0,0 +1,660 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + * Copyright (C) 2025 Artinchip Technology Co., Ltd. + * Authors: wulv + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wifimanager.h" + +#define SERVER_STRING "Server: artinchiphttpd/0.1.0\r\n" +#define SERVER_PORT 80 +#define HTML_DEFAULT "/var/http_wificonfig/html/" +#define WIFI_CONNECT_TIMEOUT_S 15 + +struct stat st; + +static int get_line(int sock, char *buff, int size); +static void handle_get(int sock, char *url); +static int handle_post(int sock, char *url); +int do_http(int sock); +void not_found(int sock); +void responce_headers(int sock, FILE *file); +void responce_bodys(int sock, FILE *file); +void unimplement(int sock); +void do_responce(int sock, const char *path); + +enum +{ + HTTP_WIFICONFIG_ERROR = 0, + HTTP_WIFICONFIG_WARNING, + HTTP_WIFICONFIG_INFO, + HTTP_WIFICONFIG_DEBUG, +}; +static int debug_level = HTTP_WIFICONFIG_INFO; + +void http_wificonfig_debug(int level, const char *fmt, ...) +{ + va_list args; + + if (level > debug_level) + return; + + va_start(args, fmt); + + printf("[http_wificonfig]: "); + + vprintf(fmt, args); + + va_end(args); +} + +static int get_line(int sock, char *buff, int size) +{ + int count = 0; + char ch = '\0'; + int len = 0; + + while (count < size - 1 && ch != '\n') + { + len = read(sock, &ch, 1); + if (len == 1) + { + if (ch == '\r') + { + continue; + } + else if (ch == '\n') + { + break; + } + + buff[count] = ch; + count++; + } + else if (len == -1) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "read error\n"); + count = -1; + break; + } + else + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "client error\n"); + count = -1; + break; + } + } + if (count >= 0) + buff[count] = '\0'; + + return count; +} + +static void handle_get(int sock, char *url) +{ + int len = 0; + char buff[512]; + char path[128]; + + snprintf(path, 127, HTML_DEFAULT "%s", url); + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "method: GET \n "); + + do + { + len = get_line(sock, buff, sizeof(buff)); + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "%s\n", buff); + } while (len > 0); + + if (stat(path, &st) == -1) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "The file: %s is not exist!\n", path); + not_found(sock); + } + else + { + do_responce(sock, path); + } +} + +static void bad_request(int client) +{ + char buf[128]; + + snprintf(buf, 127, "HTTP/1.0 400 BAD REQUEST\r\n"); + send(client, buf, sizeof(buf), 0); + snprintf(buf, 127, "Content-type: text/html\r\n"); + send(client, buf, sizeof(buf), 0); + snprintf(buf, 127, "\r\n"); + send(client, buf, sizeof(buf), 0); + snprintf(buf, 127, "

      Your browser sent a bad request, "); + send(client, buf, sizeof(buf), 0); + snprintf(buf, 127, "such as a POST without a Content-Length.\r\n"); + send(client, buf, sizeof(buf), 0); +} + +static int hex_to_char(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return -1; +} + +static char *url_decode(const char *str) +{ + if (str == NULL) + return NULL; + + size_t len = strlen(str); + + char *decoded = (char *)malloc(len + 1); + if (decoded == NULL) + return NULL; + + size_t i = 0, j = 0; + while (str[i] != '\0') + { + if (str[i] == '%' && str[i + 1] != '\0' && str[i + 2] != '\0') + { + int high = hex_to_char(str[i + 1]); + int low = hex_to_char(str[i + 2]); + if (high != -1 && low != -1) + { + decoded[j++] = (char)((high << 4) | low); + i += 3; + continue; + } + else + { + decoded[j++] = str[i++]; + } + } + else + { + decoded[j++] = str[i++]; + } + } + decoded[j] = '\0'; + return decoded; +} + +static int parse_wificonfig_info(char *buff, char *ssid, char *password) +{ + char *ptr = NULL; + int i; + char *decode = NULL; + + decode = url_decode(buff); + if (!decode) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "decode error\n"); + return -1; + } + + ptr = strstr(decode, "ssid="); + if (ptr == NULL) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "Can't get ssid info\n"); + free(decode); + return -1; + } + ptr += 5; + + for (i = 0; *ptr != '&' && i < 64; i++) + { + ssid[i] = *ptr; + ptr++; + } + ssid[i] = '\0'; + + ptr = strstr(ptr, "password="); + if (ptr == NULL) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "Can't get password info\n"); + free(decode); + return -1; + } + ptr += 9; + for (i = 0; *ptr != '\0' && i < 64; i++) + { + password[i] = *ptr; + ptr++; + } + password[i] = '\0'; + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "ssid = %s\n password = %s\n", ssid, password); + + free(decode); + return 0; +} + +static int handle_post(int sock, char *url) +{ + int len = 0; + char buff[128]; + char *ptr = NULL; + char ssid[32]; + char password[64]; + int content_length = -1; + int ret = 0; + + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "method: POST \n "); + + do + { + len = get_line(sock, buff, sizeof(buff)); + if (len < 0) + return 0; + + if (len == 0 && content_length != -1) + { + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "content_length == %d\n", content_length); + len = recv(sock, buff, content_length, 0); + if (len <= 0) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "recv post request body filed\n"); + content_length = -1; + } + else + { + buff[content_length] = '\0'; + } + + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "POST:body: %s\n", buff); + break; + } + + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "%s\n", buff); + + ptr = strstr(buff, "Content-Length:"); + if (ptr != NULL) + { + content_length = atoi(&(ptr[16])); + } + + } while (len > 0); + + if (content_length == -1) + { + bad_request(sock); + return 0; + } + + ret = parse_wificonfig_info(buff, ssid, password); + if (ret != 0) + { + bad_request(sock); + return 0; + } + + wifi_status_t status; + + memset(&status, 0, sizeof(wifi_status_t)); + + int timeout = WIFI_CONNECT_TIMEOUT_S; + char new_path[64]; + wifimanager_connect(ssid, password); + do + { + sleep(1); + wifimanager_get_status(&status); + if (status.state == WIFI_STATE_GOT_IP || status.state == WIFI_STATE_CONNECTED) + break; + } while (timeout-- > 0); + + if (timeout > 0) + snprintf(new_path, 63, HTML_DEFAULT "success_%s", url); + else + snprintf(new_path, 63, HTML_DEFAULT "fail_%s", url); + + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "path:%s\n", new_path); + + if (stat(new_path, &st) == -1) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "The file: %s is not exist!\n", new_path); + not_found(sock); + } + + do_responce(sock, new_path); + + if (timeout > 0) + { + sleep(10); + system("killall hostapd"); + system("killall udhcpd"); + + return 1; + } + + return 0; +} + +int do_http(int sock) +{ + int len = 0; + char buff[512]; + char url[256]; + char method[64]; + char path[256]; + + len = get_line(sock, buff, sizeof(buff)); + int i = 0, j = 0; + if (len > 0) + { + while (!isspace(buff[j]) && i < sizeof(method) - 1) + { + method[i] = buff[j]; + i++; + j++; + } + method[i] = '\0'; + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "request method:%s\n", method); + } + + while (isspace(buff[j++])) {} + i = 0; + + while (!isspace(buff[j]) && i < sizeof(url) - 1) + { + url[i] = buff[j]; + i++; + j++; + } + url[i] = '\0'; + + char *p = strchr(url, '?'); + if (p) + *p = '\0'; + if (url[0] == '\0' || url[0] == '/') + strcat(url, "index.html"); + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "actual url:%s\n", url); + + if (strncasecmp(method, "GET", i) == 0) + { + handle_get(sock, url); + } + else if (strncasecmp(method, "POST", i) == 0) + { + return handle_post(sock, url); + } + else + { + fprintf(stderr, "warning! other request:%s\n !", method); + do + { + len = get_line(sock, buff, sizeof(buff)); + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "read:%s\n", buff); + } while (len > 0); + unimplement(sock); + } + return 0; +} + +/**********************************************************************/ +/* Give a client a 404 not found status message. */ +/**********************************************************************/ +void not_found(int sock) +{ + char buf[128]; + + snprintf(buf, 127, "HTTP/1.0 404 NOT FOUND\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, SERVER_STRING); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "Content-Type: text/html\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "Not Found\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "

      The server could not fulfill\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "your request because the resource specified\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "is unavailable or nonexistent.\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "\r\n"); + send(sock, buf, strlen(buf), 0); +} + +void responce_headers(int sock, FILE *file) +{ + struct stat st1; + char buff[1024] = {0}; + char temp[64]; + const char *head = "HTTP/1.0 200 OK\r\nServer:ArtInChip Private Server\r\nContent-Type: text/html\r\nConnection: Close\r\n"; + + strcpy(buff, head); + + int fd = fileno(file); + fstat(fd, &st1); + + int size = st1.st_size; + snprintf(temp, 63, "Content-Length:%d\r\n\r\n", size); + + strcat(buff, temp); + + write(sock, buff, strlen(buff)); + http_wificonfig_debug(HTTP_WIFICONFIG_DEBUG, "%s\n", buff); +} + +void responce_bodys(int sock, FILE *file) +{ + fseek(file, 0, SEEK_END); + long fileSize = ftell(file); + + rewind(file); + + char *buffer = (char *)malloc(fileSize); + if (buffer == NULL) + { + perror("Failed to allocate memory"); + return; + } + + fread(buffer, 1, fileSize, file); + write(sock, buffer, fileSize); + free(buffer); +} + +void unimplement(int sock) +{ + char buf[128]; + + snprintf(buf, 127, "HTTP/1.0 501 Method Not Implemented\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, SERVER_STRING); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "Content-Type: text/html\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "Method Not Implemented\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "

      HTTP request method not supported.\r\n"); + send(sock, buf, strlen(buf), 0); + snprintf(buf, 127, "\r\n"); + send(sock, buf, strlen(buf), 0); +} + +void do_responce(int sock, const char *path) +{ + FILE *resource = NULL; + + resource = fopen(path, "r"); + if (resource == NULL) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "open file %s\n error!\n", path); + not_found(sock); + return; + } + + responce_headers(sock, resource); + + responce_bodys(sock, resource); + + fclose(resource); +} + +static const char *wifistate2string(wifistate_t state) +{ + switch (state) + { + case WIFI_STATE_GOT_IP: + return "WIFI_STATE_GOT_IP"; + case WIFI_STATE_CONNECTING: + return "WIFI_STATE_CONNECTING"; + case WIFI_STATE_DHCPC_REQUEST: + return "WIFI_STATE_DHCPC_REQUEST"; + case WIFI_STATE_DISCONNECTED: + return "WIFI_STATE_DISCONNECTED"; + case WIFI_STATE_CONNECTED: + return "WIFI_STATE_CONNECTED"; + default: + return "WIFI_STATE_ERROR"; + } +} + +static const char *disconn_reason2string(wifimanager_disconn_reason_t reason) +{ + switch (reason) + { + case AUTO_DISCONNECT: + return "wpa auto disconnect"; + case ACTIVE_DISCONNECT: + return "active disconnect"; + case KEYMT_NO_SUPPORT: + return "keymt is not supported"; + case CMD_OR_PARAMS_ERROR: + return "wpas command error"; + case IS_CONNECTTING: + return "wifi is still connecting"; + case CONNECT_TIMEOUT: + return "connect timeout"; + case REQUEST_IP_TIMEOUT: + return "request ip address timeout"; + case WPA_TERMINATING: + return "wpa_supplicant is closed"; + case AP_ASSOC_REJECT: + return "AP assoc reject"; + case NETWORK_NOT_FOUND: + return "can't search such ssid"; + case PASSWORD_INCORRECT: + return "incorrect password"; + default: + return "other reason"; + } +} + +static void print_scan_result(char *result) +{ + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "%s\n", result); +} + +static void print_stat_change(wifistate_t stat, wifimanager_disconn_reason_t reason) +{ + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "%s\n", wifistate2string(stat)); + if (stat == WIFI_STATE_DISCONNECTED) + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "disconnect reason: %s\n", disconn_reason2string(reason)); +} + +int main(int argc, char *argv[]) +{ + int server_sock = -1; + struct sockaddr_in server_addr; + int ret; + int on = 1; + wifimanager_cb_t cb = { + .scan_result_cb = print_scan_result, + .stat_change_cb = print_stat_change, + }; + + bzero(&server_addr, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + server_addr.sin_port = htons(SERVER_PORT); + + server_sock = socket(AF_INET, SOCK_STREAM, 0); + if (server_sock < 0) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "socket failed\n"); + return -1; + } + + if ((setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &on, sizeof(on))) < 0) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "setsockopt failed\n"); + close(server_sock); + return -1; + } + if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "bind failed\n"); + close(server_sock); + return -1; + } + if (listen(server_sock, 5) < 0) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "listen failed\n"); + close(server_sock); + return -1; + } + + wifimanager_init(&cb); + + system("hostapd -d /etc/http_wificonfig/hostapd.conf -B"); + // sleep(1); + system("ifconfig wlan1 192.168.1.1"); + system("udhcpd /etc/http_wificonfig/udhcpd.conf"); + + while (1) + { + struct sockaddr_in client_addr; + int client_sock; + char buff[64]; + int client_length = sizeof(client_addr); + + client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_length); + if (client_sock == -1) + { + http_wificonfig_debug(HTTP_WIFICONFIG_ERROR, "accept error\n"); + close(server_sock); + return -1; + } + + http_wificonfig_debug(HTTP_WIFICONFIG_INFO, "client ip:%s\t port:%d\n ", + inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, buff, sizeof(buff)), + ntohs(client_addr.sin_port)); + ret = do_http(client_sock); + close(client_sock); + + /* wifi configration success, exit! */ + if (ret) + { + close(server_sock); + break; + } + } + + return 0; +} diff --git a/source/artinchip/lvgl-ui/CMakeLists.txt b/source/artinchip/lvgl-ui/CMakeLists.txt index 32cdd43eb..abd923293 100644 --- a/source/artinchip/lvgl-ui/CMakeLists.txt +++ b/source/artinchip/lvgl-ui/CMakeLists.txt @@ -11,6 +11,7 @@ if(DEFINED LVGL_FBDEV) if(${LVGL_FBDEV} STREQUAL "yes") set(APP_FOLDER ${DEMO_FOLDER}/base_demo) #set(APP_FOLDER ${DEMO_FOLDER}/hub_demo) + #set(APP_FOLDER ${DEMO_FOLDER}/lyrics_demo) endif() endif() @@ -47,6 +48,10 @@ add_compile_options(-Wall) add_definitions(-DLV_USE_CONF_CUSTOM) +if(DEFINED BUILD_DIR) + message(NOTICE ${BUILD_DIR}) +endif() + # set custom config path, used by lvgl library set(LV_CONF_CUSTOM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${APP_FOLDER}) @@ -59,6 +64,12 @@ include(GNUInstallDirs) ### build lvgl library add_subdirectory(${LVGL_LIB_PATH}/lvgl) +option(BUILD_LYRICS_LIBS "Build lyrics_effect library" OFF) +option(BUILD_RELEASE_LIBS "Release lyrics_effect library" OFF) + +### build aic widget library +add_subdirectory(aic_widgets) + # lvgl HAL source set(LVGL_DRIVER_PATH fbdev) @@ -105,6 +116,16 @@ add_executable(${APP_OUT_NAME} ${APP_SOURCE_FILES}) target_link_libraries(${APP_OUT_NAME} lvgl) target_link_libraries(${APP_OUT_NAME} lvgl_examples) target_link_libraries(${APP_OUT_NAME} lvgl_demos) +target_link_libraries(${APP_OUT_NAME} aic_widgets) + +if(DEFINED LVGL_V_9) + if(${LVGL_V_9} STREQUAL "yes" AND BUILD_LYRICS_LIBS) + if(BUILD_RELEASE_LIBS) + link_directories(${CMAKE_CURRENT_SOURCE_DIR}/aic_widgets/lyrics_effect) + endif() + target_link_libraries(${APP_OUT_NAME} lyrics_effect) + endif() +endif() if(DEFINED LVGL_FBDEV) if(${LVGL_FBDEV} STREQUAL "yes") diff --git a/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/aic_player_demo.c b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/aic_player_demo.c new file mode 100644 index 000000000..09d9f08ee --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/aic_player_demo.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Zequan Liang + */ + +#include "aic_ui.h" +#include "lvgl.h" +#include "lv_aic_player.h" + +#define CHECK_CONDITION_RETURN_VOID(confition, ...) \ + if (confition) { __VA_ARGS__; return; } + +static bool g_del_player = false; +static bool g_playing = false; + +static void print_del(void) +{ + printf("lv_aic_player have been deleted\n"); +} + +static void scale_player_cb(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player = lv_event_get_user_data(e); + lv_obj_t * slider = lv_event_get_current_target(e); + + if (code == LV_EVENT_VALUE_CHANGED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + int32_t value = lv_slider_get_value(slider); + lv_aic_player_set_scale(player, value); + } +} + +static void rotate_player_cb(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player = lv_event_get_user_data(e); + lv_obj_t * slider = lv_event_get_current_target(e); + + if (code == LV_EVENT_VALUE_CHANGED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + int32_t value = lv_slider_get_value(slider); + lv_aic_player_set_rotation(player, value); + } +} + +static void start_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player = lv_event_get_user_data(e); + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + lv_aic_player_set_cmd(player, LV_AIC_PLAYER_CMD_START, NULL); + g_playing = true; + } +} + +static void pause_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player= lv_event_get_user_data(e); + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + lv_aic_player_set_cmd(player, LV_AIC_PLAYER_CMD_PAUSE, NULL); + g_playing = false; + } +} + +static void resume_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player= lv_event_get_user_data(e); + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + lv_aic_player_set_cmd(player, LV_AIC_PLAYER_CMD_RESUME, NULL); + } +} + +static void seek_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player= lv_event_get_user_data(e); + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + u64 seek = 0; + lv_aic_player_set_cmd(player, LV_AIC_PLAYER_CMD_SET_PLAY_TIME, &seek); + } +} + +static void auto_restart_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player = lv_event_get_user_data(e); + lv_obj_t * btn = lv_event_get_current_target(e); + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + lv_aic_player_set_auto_restart(player, true); + lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_style_bg_color(btn, lv_color_black(), 0); + } +} + +static void del_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player= lv_event_get_user_data(e); + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + lv_obj_del(player); + g_del_player = true; + } +} + +static void next_button_handler(lv_event_t *e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * player= lv_event_get_user_data(e); + static int cur_video = 0; + + if (code == LV_EVENT_CLICKED) { + CHECK_CONDITION_RETURN_VOID(g_del_player, print_del()); + if (cur_video == 0) + lv_aic_player_set_src(player, LVGL_PATH(cartoon_mjpeg.mp4)); + else + lv_aic_player_set_src(player, LVGL_PATH(elevator_mjpeg.mp4)); + if (g_playing) + lv_aic_player_set_cmd(player, LV_AIC_PLAYER_CMD_START, NULL); + cur_video = cur_video == 0 ? 1 :0; + } +} + +static void move_player_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t *obj = lv_event_get_target(e); + + /* LV_OBJ_FLAG_USER_4 flag is used to record whether there is movement and the click event will not be triggered if there is movement */ + if (LV_EVENT_PRESSED == code) + lv_obj_clear_flag(obj, LV_OBJ_FLAG_USER_4); + + if (code == LV_EVENT_PRESSING) { + if (lv_obj_has_flag(obj, LV_OBJ_FLAG_USER_4) == false) lv_obj_set_style_opa(obj, LV_OPA_100, 0); + lv_indev_t *indev = lv_indev_get_act(); + if (indev == NULL) return; + + lv_indev_type_t indev_type = lv_indev_get_type(indev); + if (indev_type != LV_INDEV_TYPE_POINTER) return; + + lv_point_t vect; + lv_indev_get_vect(indev, &vect); + lv_coord_t x = lv_obj_get_x_aligned(obj) + vect.x; + lv_coord_t y = lv_obj_get_y_aligned(obj) + vect.y; + + /* after moving it will not trigger click */ + lv_obj_add_flag(obj, LV_OBJ_FLAG_USER_4); + + lv_obj_set_pos(obj, x, y); + } +} + +static lv_obj_t *common_btn(lv_obj_t *parent, char *desc, lv_event_cb_t event_cb, void *event_user_data) +{ + lv_obj_t *btn = lv_btn_create(parent); + lv_obj_t *label = lv_label_create(btn); + lv_label_set_text(label, desc); + lv_obj_center(label); + lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, event_user_data); + return btn; +} + +void ui_init(void) +{ + lv_obj_t *player = lv_aic_player_create(lv_scr_act()); + lv_aic_player_set_src(player, LVGL_PATH(elevator_mjpeg.mp4)); + lv_obj_center(player); + lv_obj_set_pos(player, 0, 0); + + lv_obj_set_style_bg_color(player, lv_color_hex(0x0), 0); + lv_obj_add_flag(player, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(player, move_player_cb, LV_EVENT_ALL, NULL); + + lv_obj_t *scale_slider = lv_slider_create(lv_scr_act()); + lv_slider_set_range(scale_slider, 64, 512); + lv_slider_set_value(scale_slider, 256, LV_ANIM_OFF); + lv_obj_set_size(scale_slider, LV_HOR_RES * 0.03, LV_VER_RES * 0.8); + lv_obj_align(scale_slider, LV_ALIGN_RIGHT_MID, -LV_HOR_RES * 0.02, 0); + lv_obj_add_event_cb(scale_slider, scale_player_cb, LV_EVENT_ALL, player); + + lv_obj_t *rotate_slider = lv_slider_create(lv_scr_act()); + lv_slider_set_range(rotate_slider, 0, 3600); + lv_slider_set_value(rotate_slider, 0, LV_ANIM_OFF); + lv_obj_set_size(rotate_slider, LV_HOR_RES * 0.03, LV_VER_RES * 0.8); + lv_obj_align(rotate_slider, LV_ALIGN_LEFT_MID, LV_HOR_RES * 0.02, 0); + lv_obj_add_event_cb(rotate_slider, rotate_player_cb, LV_EVENT_ALL, player); + + lv_obj_t *btn_container = lv_obj_create(lv_scr_act()); + lv_obj_set_style_bg_opa(btn_container, LV_OPA_0, 0); + lv_obj_set_style_border_opa(btn_container, LV_OPA_0, 0); + lv_obj_set_scroll_dir(btn_container, LV_SCROLLBAR_MODE_OFF); + lv_obj_set_scroll_snap_x(btn_container, LV_SCROLL_SNAP_START); + lv_obj_set_size(btn_container, LV_HOR_RES * 0.8, LV_VER_RES * 0.4); + lv_obj_set_align(btn_container, LV_ALIGN_TOP_MID); + lv_obj_set_flex_flow(btn_container, LV_FLEX_FLOW_ROW_WRAP); + lv_obj_set_flex_align(btn_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + common_btn(btn_container, "Start", start_button_handler, player); + common_btn(btn_container, "Pause", pause_button_handler, player); + common_btn(btn_container, "Resume", resume_button_handler, player); + common_btn(btn_container, "Seek", seek_button_handler, player); + common_btn(btn_container, "Auto Restart", auto_restart_button_handler, player); + common_btn(btn_container, "del", del_button_handler, player); + common_btn(btn_container, "next", next_button_handler, player); + + lv_obj_t *label = lv_label_create(lv_scr_act()); + lv_label_set_text(label, "Video Test"); + lv_obj_align(label, LV_ALIGN_BOTTOM_MID, -LV_VER_RES * 0.1, 0); +} diff --git a/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/assets/cartoon_mjpeg.mp4 b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/assets/cartoon_mjpeg.mp4 new file mode 100644 index 000000000..90500e11c Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/assets/cartoon_mjpeg.mp4 differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/assets/elevator_mjpeg.mp4 b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/assets/elevator_mjpeg.mp4 new file mode 100644 index 000000000..0d7dca30e Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/assets/elevator_mjpeg.mp4 differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/lv_conf_custom.h b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/lv_conf_custom.h new file mode 100644 index 000000000..a50e6a72f --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aic_player_demo/lv_conf_custom.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * lv_conf_custom.h for custom lv_conf.h file + * example : + * #undef LV_USE_LOG + * #define LV_USE_LOG 1 + */ + +#ifndef LV_CONF_CUSTOM_H +#define LV_CONF_CUSTOM_H + +/* code begin */ + +/* code end */ + +#endif /* LV_CONF_CUSTOM_H */ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_1.png b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_1.png new file mode 100644 index 000000000..78a136f66 Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_1.png differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_2.png b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_2.png new file mode 100644 index 000000000..a87f3636b Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_2.png differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_3.png b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_3.png new file mode 100644 index 000000000..78f3ee71e Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_3.png differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_4.png b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_4.png new file mode 100644 index 000000000..b22e77984 Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/battery_4.png differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/description.png b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/description.png new file mode 100644 index 000000000..8ee7e7c18 Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/assets/image/description.png differ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/battery.c b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/battery.c new file mode 100644 index 000000000..f0c4cdb0f --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/battery.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#include +#include +#include +#include +#include +#include +#include +#include "artinchip/sample_base.h" +#include +#include +#include + +#include "battery.h" + +bool file_exists(const char *path) +{ + struct stat st; + return (path && stat(path, &st) == 0); +} + +bool change_working_dir(const char *dir) +{ + char path[MAX_PATH_LEN] = {0}; + + if (chdir(dir) != 0) + return false; + + return (getcwd(path, sizeof(path)) != NULL); +} + +int read_int_from_file(const char *filename) +{ + FILE *f = fopen(filename, "r"); + if (!f) { + ERR("Failed to open %s: %s\n", filename, strerror(errno)); + return -1; + } + + char buf[GPAI_CHAN_NUM] = {0}; + int ret = fread(buf, 1, sizeof(buf) - 1, f); + fclose(f); + + if (ret <= 0) { + ERR("fread() returned %d: %s\n", ret, strerror(errno)); + return -1; + } + + return atoi(buf); +} + +static int calculate_battery_level(int adc_val) +{ + for (size_t i = 0; i < sizeof(battery_levels)/sizeof(battery_levels[0]); i++) { + if (adc_val >= battery_levels[i].adc_val) { + printf("Current ADC value: %d, battery level: %d%%\n", + adc_val, battery_levels[i].level); + return battery_levels[i].level; + } + } + return 0; +} + +int check_battery_level() +{ + char path[MAX_PATH_LEN] = {0}; + + if (!file_exists("/tmp/gpai")) { + system("ln -sf /sys/devices/platform/soc/*.gpai/iio:device0 /tmp/gpai"); + } + + if (!change_working_dir("/tmp/gpai")) { + ERR("Failed to change to /tmp/gpai directory\n"); + return -1; + } + + snprintf(path, sizeof(path), "in_voltage%d_raw", ADC_CHAN); + int adc_val = read_int_from_file(path); + + if (adc_val < 0) { + return -1; + } + + return calculate_battery_level(adc_val); +} + diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/battery.h b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/battery.h new file mode 100644 index 000000000..9fef15c4e --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/battery.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#include "artinchip/sample_base.h" + +#define GPAI_CHAN_NUM 8 +#define MAX_PATH_LEN 128 +#define ADC_CHAN 7 + +static const struct battery_level { + int adc_val; + int level; +} battery_levels[] = { + {2330, 100}, + {2291, 75}, + {2234, 50}, + {2177, 25}, + {0, 0} +}; + +int check_battery_level(); + diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/custom.c b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/custom.c new file mode 100644 index 000000000..b8d39983e --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/custom.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#include "custom.h" +#include "battery.h" + +screen_t *scr; + +static void timer_battery_callback(lv_timer_t *tmr) +{ + int level = check_battery_level(); + switch (level) { + case 0: + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_1.png)); + break; + case 25: + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_1.png)); + break; + case 50: + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_2.png)); + break; + case 75: + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_3.png)); + break; + case 100: + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_4.png)); + break; + default: + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_1.png)); + } + + return; +} + +void custom_init(ui_manager_t *ui) +{ + /* Add your codes here */ + scr = screen_get(ui); + lv_timer_create(timer_battery_callback, 5000, 0); +} + diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/custom.h b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/custom.h new file mode 100644 index 000000000..7904533c5 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/custom/custom.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#ifndef CUSTOM_CODE +#define CUSTOM_CODE +#ifdef __cplusplus +extern "C" { +#endif + +#include "ui_objects.h" +#include "aic_ui.h" +#include "ui_util.h" + +void custom_init(ui_manager_t *ui); + +#ifdef __cplusplus +} +#endif +#endif /* CUSTOM_CODE */ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/lv_conf_custom.h b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/lv_conf_custom.h new file mode 100644 index 000000000..3cc9f87bb --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/lv_conf_custom.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +/* lv_conf_custom.h for custom lv_conf.h file + * example : + * #undef LV_USE_LOG + * #define LV_USE_LOG 1 + */ + +#ifndef LV_CONF_CUSTOM_H +#define LV_CONF_CUSTOM_H + +/* code begin */ + +#undef LV_USE_FREETYPE +#define LV_USE_FREETYPE 1 + +#undef LV_COLOR_DEPTH +#define LV_COLOR_DEPTH 32 + +/* code end */ + +#endif /* LV_CONF_CUSTOM_H */ diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/screen.c b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/screen.c new file mode 100644 index 000000000..1a095fe04 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/screen.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#include "ui_objects.h" +#include "aic_ui.h" +#include "ui_util.h" + + +void screen_create(ui_manager_t *ui) +{ + screen_t *scr = screen_get(ui); + + if (!ui->auto_del && scr->obj) + return; + + // Init scr->obj + scr->obj = lv_obj_create(NULL); + lv_obj_set_scrollbar_mode(scr->obj, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->obj + lv_obj_set_style_bg_color(scr->obj, lv_color_hex(0xfcfcfc), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->image_descrip + scr->image_descrip = lv_img_create(scr->obj); + lv_img_set_src(scr->image_descrip, LVGL_IMAGE_PATH(description.png)); + lv_img_set_pivot(scr->image_descrip, 50, 50); + lv_img_set_angle(scr->image_descrip, 0); + lv_obj_set_style_img_opa(scr->image_descrip, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->image_descrip, 0, 0); + + // Init scr->image_battery + scr->image_battery = lv_img_create(scr->obj); + lv_img_set_src(scr->image_battery, LVGL_IMAGE_PATH(battery_3.png)); + lv_img_set_pivot(scr->image_battery, 50, 50); + lv_img_set_angle(scr->image_battery, 0); + lv_obj_set_style_img_opa(scr->image_battery, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->image_battery, 545, 8); + + +} diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_init.c b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_init.c new file mode 100644 index 000000000..2f75adbca --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_init.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#include "ui_init.h" +#include "ui_util.h" +#include "aic_ui.h" +#include "custom/custom.h" + +ui_manager_t ui_manager; + + +void ui_init(void) +{ + + // auto delete screen + ui_manager_init(&ui_manager, true); + + screen_create(&ui_manager); + lv_scr_load(screen_get(&ui_manager)->obj); + + // custom code + custom_init(&ui_manager); +} diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_init.h b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_init.h new file mode 100644 index 000000000..65ee78454 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_init.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#ifndef _UI_INIT_H +#define _UI_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "ui_objects.h" + +void ui_init(void); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif // _UI_INIT_H diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_objects.h b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_objects.h new file mode 100644 index 000000000..c37c776c5 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_objects.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#ifndef _UI_OBJECTS +#define _UI_OBJECTS + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" +#include "lv_conf_custom.h" + +typedef struct { + lv_obj_t *obj; + lv_obj_t *image_descrip; + lv_obj_t *image_battery; +} screen_t; + + +typedef struct { + bool auto_del; + screen_t screen; + +} ui_manager_t; + +static inline void ui_manager_init(ui_manager_t *ui, bool auto_del) +{ + memset(ui, 0 , sizeof(ui_manager_t)); + ui->auto_del = auto_del; +} + +static inline screen_t *screen_get(ui_manager_t *ui) +{ + return &ui->screen; +} + + +void screen_create(ui_manager_t *ui); + + + +extern ui_manager_t ui_manager; + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif // _UI_OBJECTS diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_util.c b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_util.c new file mode 100644 index 000000000..379d287b1 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_util.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#include +#include "ui_util.h" + +bool screen_is_loading(lv_obj_t *scr) +{ +#if LVGL_VERSION_MAJOR == 8 + lv_obj_t *act_scr = lv_scr_act(); + lv_disp_t *d = lv_obj_get_disp(scr); + if (d->prev_scr == NULL && (d->scr_to_load == NULL || d->scr_to_load == act_scr)) + return false; + else + return true; +#else + return false; +#endif +} + +void ui_style_init(lv_style_t *style) +{ + if (style->prop_cnt >= 1) + lv_style_reset(style); + else + lv_style_init(style); +} + +lv_font_t *ui_font_init(char *path, int size) { +#if LVGL_VERSION_MAJOR == 8 + static lv_ft_info_t info; + info.name = path; + info.weight = size; + info.style = FT_FONT_STYLE_NORMAL; + info.mem = NULL; + if (!lv_ft_font_init(&info)) + return NULL; + return info.font; +#else + lv_font_t *font = lv_freetype_font_create(path, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, + size, + LV_FREETYPE_FONT_STYLE_NORMAL); + return font; +#endif //LVGL_VERSION_MAJOR +} diff --git a/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_util.h b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_util.h new file mode 100644 index 000000000..a119f0a5f --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/aishoot_demo/ui_util.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: haidong.pan + */ + +#ifndef _UI_UTIL_H +#define _UI_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" + +bool screen_is_loading(lv_obj_t *scr); + +void ui_style_init(lv_style_t * style); + +lv_font_t *ui_font_init(char *path, int size); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif // _UI_UTIL_H diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/font/SourceHanSansSC-Bold-crop.otf b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/font/SourceHanSansSC-Bold-crop.otf new file mode 100644 index 000000000..605d60715 Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/font/SourceHanSansSC-Bold-crop.otf differ diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/font/readme.txt b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/font/readme.txt new file mode 100644 index 000000000..a8997b1eb --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/font/readme.txt @@ -0,0 +1 @@ +仅包含常用3700个汉字 \ No newline at end of file diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/image/diamond_red_1.png b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/image/diamond_red_1.png new file mode 100644 index 000000000..3b6c71098 Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/image/diamond_red_1.png differ diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/video/board1_1_scale.mp4 b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/video/board1_1_scale.mp4 new file mode 100644 index 000000000..eaf7bc7fe Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/video/board1_1_scale.mp4 differ diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/video/board2_1_scale.mp4 b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/video/board2_1_scale.mp4 new file mode 100644 index 000000000..ae32bb23e Binary files /dev/null and b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/assets/video/board2_1_scale.mp4 differ diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/lv_conf_custom.h b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/lv_conf_custom.h new file mode 100644 index 000000000..e40e3d15d --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/lv_conf_custom.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * lv_conf_custom.h for custom lv_conf.h file + * example : + * #undef LV_USE_LOG + * #define LV_USE_LOG 1 + */ + +#ifndef LV_CONF_CUSTOM_H +#define LV_CONF_CUSTOM_H + +/* code begin */ + +#undef LV_USE_FREETYPEo +#define LV_USE_FREETYPE 1 + +#define MTP_MOUNT_DIR "/usr/local/share/lvgl_data/font" + +#define USE_HOST_DEMO 1 +#define USE_DEVICE_DEMO 0 +#define USE_TRY_MTP_MOUNTED 0 +#define USE_DOUBLE_SDL_DISP 0 // PC simulator + +/* code end */ + +#endif /* LV_CONF_CUSTOM_H */ diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/module/check_load_assets.c b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/module/check_load_assets.c new file mode 100644 index 000000000..eb14cf3f1 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/module/check_load_assets.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Zequan Liang + */ + +#include "ui_objects.h" +#include "ui_util.h" + +static uint32_t g_start_time; + +#if USE_TRY_MTP_MOUNTED +#include +#include +#define MTP_MOUNT_PATH "/usr/local/share/lvgl_data" + +int is_mtp_mounted(const char *mount_path) +{ + DIR *dir = opendir(mount_path); + if (!dir) { + return -1; + } + closedir(dir); + return 0; +} +#endif +static void check_load_assets_cb(lv_timer_t *timer) +{ + ui_manager_t *ui = (ui_manager_t *)timer->user_data; + uint32_t elapsed = lv_tick_elaps(g_start_time); +#if USE_TRY_MTP_MOUNTED + if (is_mtp_mounted(MTP_MOUNT_PATH) == 0) { + progress_screen_set_finish(ui); + lv_timer_delete(timer); + } +#endif + if (elapsed > 20 * 1000) { +#if USE_DOUBLE_SDL_DISP + progress_screen_set_finish(ui); +#endif + LV_LOG_ERROR("try get assets timeout"); + lv_timer_delete(timer); + } +} + +void check_load_assets_create(ui_manager_t *ui) +{ + g_start_time = lv_tick_get(); + lv_timer_create(check_load_assets_cb, 50, ui); +} \ No newline at end of file diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/loading.c b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/loading.c new file mode 100644 index 000000000..3a5500265 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/loading.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Zequan Liang + */ + +#include "ui_objects.h" +#include "ui_util.h" + +#define ESTIMATED_LOAD_TIME_MS 8000 // Estimated loading time 8s +#define PROGRESS_UPDATE_MS 50 // Progress update interval 50ms + +// Non-linear progress calculation (0~99%) +static uint8_t calculate_progress(uint32_t elapsed_ms) +{ + if (elapsed_ms >= ESTIMATED_LOAD_TIME_MS) + return 99; // Stay at 99% after reaching estimated time + + // Easing function: slow start → fast middle → slow end + float t = (float)elapsed_ms / ESTIMATED_LOAD_TIME_MS; + if (t < 0.5f) + t = 2 * t * t; + else + t = -1 + (4 - 2 * t) * t; + + return (uint8_t)(t * 99); +} + +// Timer callback: update progress +static void update_progress(lv_timer_t *timer) +{ + ui_manager_t *ui = (ui_manager_t *)timer->user_data; + progress_screen_t *scr = progress_screen_get(ui); + uint32_t elapsed = lv_tick_elaps(scr->start_time); + + if (scr->is_loading_complete) + { + lv_label_set_text(scr->progress_label, "100%"); + lv_bar_set_value(scr->progress_bar, 100, LV_ANIM_OFF); + lv_timer_pause(scr->timer); // Stop timer + // Page transition can be added here +#if USE_DOUBLE_SDL_DISP + lv_disp_set_default(lv_display_get_next(NULL)); +#endif + lv_screen_load_anim(price_tags_screen_2_get(ui)->obj, LV_SCR_LOAD_ANIM_NONE, 0, 500, 0); + return; + } + + if (elapsed > ESTIMATED_LOAD_TIME_MS * 2) + { + lv_label_set_text(scr->progress_label, "Load failed"); + lv_spinner_set_anim_params(scr->spinner, 0, 0); + + // lv_obj_set_style_bg_color(scr->container, lv_palette_lighten(LV_PALETTE_RED, 1), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->progress_label, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(scr->progress_bar, lv_palette_main(LV_PALETTE_RED), LV_PART_INDICATOR | LV_STATE_DEFAULT); + lv_timer_pause(scr->timer); + return; + } + + uint8_t progress = calculate_progress(elapsed); + lv_label_set_text_fmt(scr->progress_label, "Loading assets: %d%%", progress); + lv_bar_set_value(scr->progress_bar, progress, LV_ANIM_OFF); +} + +static void progress_screen_cb(lv_event_t *e) +{ + lv_event_code_t code = (lv_event_code_t)lv_event_get_code(e); + ui_manager_t *ui = (ui_manager_t *)lv_event_get_user_data(e); + progress_screen_t *scr = progress_screen_get(ui); + + if (code == LV_EVENT_SCREEN_UNLOAD_START) { + lv_timer_delete(scr->timer); + } + if (code == LV_EVENT_DELETE) {;} + if (code == LV_EVENT_SCREEN_LOADED) { + scr->start_time = lv_tick_get(); + scr->is_loading_complete = false; + lv_timer_resume(scr->timer); + } +} + +void progress_screen_create(ui_manager_t *ui) +{ + progress_screen_t *scr = progress_screen_get(ui); + + if (!ui->auto_del && scr->obj) + return; + + scr->obj = lv_obj_create(NULL); + lv_obj_set_scrollbar_mode(scr->obj, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->obj + lv_obj_set_style_bg_color(scr->obj, lv_color_hex(0xfcfcfc), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->container + scr->container = lv_obj_create(scr->obj); + lv_obj_center(scr->container); + lv_obj_set_size(scr->container, 700, 173); + lv_obj_set_scrollbar_mode(scr->container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->container + lv_obj_set_style_bg_color(scr->container, lv_color_hex(0xe7f7ff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->container, 20, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->title_label + scr->title_label = lv_label_create(scr->container); + lv_label_set_text(scr->title_label, "Digital menu board"); + lv_label_set_long_mode(scr->title_label, LV_LABEL_LONG_WRAP); + lv_obj_align(scr->title_label, LV_ALIGN_TOP_MID, 0, 10); + lv_obj_set_size(scr->title_label, 160, 16); + + // Init scr->progress_bar + scr->progress_bar = lv_bar_create(scr->container); + lv_obj_set_style_anim_time(scr->progress_bar, 0, 0); + lv_bar_set_value(scr->progress_bar, 50, LV_ANIM_OFF); + lv_obj_align(scr->progress_bar, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_size(scr->progress_bar, 657, 20); + + // Init scr->progress_label + scr->progress_label = lv_label_create(scr->container); + lv_label_set_text(scr->progress_label, "Loading assets: 0%"); + lv_label_set_long_mode(scr->progress_label, LV_LABEL_LONG_WRAP); + lv_obj_align(scr->progress_label, LV_ALIGN_LEFT_MID, 60, -28); + lv_obj_set_size(scr->progress_label, 188, 20); + + // Init scr->spinner +#if LVGL_VERSION_MAJOR == 8 + scr->spinner = lv_spinner_create(scr->container, 1000, 60); +#else + scr->spinner = lv_spinner_create(scr->container); + lv_spinner_set_anim_params(scr->spinner, 1000, 60); +#endif + lv_obj_align(scr->spinner, LV_ALIGN_LEFT_MID, 25, -30); + lv_obj_set_size(scr->spinner, 26, 25); + + // Set style of scr->spinner + lv_obj_set_style_arc_width(scr->spinner, 4, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_arc_width(scr->spinner, 4, LV_PART_INDICATOR | LV_STATE_DEFAULT); + + scr->timer = lv_timer_create(update_progress, PROGRESS_UPDATE_MS, ui); + lv_timer_pause(scr->timer); + + lv_obj_add_event_cb(scr->obj, progress_screen_cb, LV_EVENT_ALL, ui); +} + +void progress_screen_set_finish(ui_manager_t *ui) +{ + progress_screen_t *scr = progress_screen_get(ui); + scr->is_loading_complete = true; +} diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/price_tags_1.c b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/price_tags_1.c new file mode 100644 index 000000000..6339d748d --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/price_tags_1.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#include "ui_objects.h" +#include "aic_ui.h" +#include "ui_util.h" +#include "lv_aic_player.h" + +void price_tags_screen_1_create(ui_manager_t *ui) +{ + price_tags_screen_t *scr = price_tags_screen_1_get(ui); + + if (!ui->auto_del && scr->obj) + return; + + // Init scr->obj + scr->obj = lv_obj_create(NULL); + lv_obj_set_scrollbar_mode(scr->obj, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->obj + lv_obj_set_style_bg_color(scr->obj, lv_color_hex(0xfcfcfc), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->background + scr->background = lv_aic_player_create(scr->obj); + lv_aic_player_set_src(scr->background, LVGL_VIDEO_PATH(board1_1_scale.mp4)); + lv_aic_player_set_auto_restart(scr->background, true); + lv_aic_player_set_cmd(scr->background, LV_AIC_PLAYER_CMD_START, NULL); + lv_obj_set_pos(scr->background, 0, 0); + lv_obj_set_size(scr->background, 800, 1280); + + // Init scr->info_container + scr->info_container = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->info_container, 0, 1157); + lv_obj_set_size(scr->info_container, 800, 123); + lv_obj_set_scrollbar_mode(scr->info_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->info_container + lv_obj_set_style_bg_color(scr->info_container, lv_color_hex(0x452000), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->qrcode +#if LVGL_VERSION_MAJOR == 8 + scr->qrcode = lv_qrcode_create(scr->info_container, 100, lv_color_hex(0x000000), lv_color_hex(0xffffff)); +#else + scr->qrcode = lv_qrcode_create(scr->info_container); + lv_qrcode_set_size(scr->qrcode, 100); + lv_qrcode_set_dark_color(scr->qrcode, lv_color_hex(0x000000)); + lv_qrcode_set_light_color(scr->qrcode, lv_color_hex(0xffffff)); +#endif + lv_qrcode_update(scr->qrcode, "www.artinchip.com", 17); + lv_obj_set_pos(scr->qrcode, 18, 11); + + // Init scr->act_time_container + scr->act_time_container = lv_obj_create(scr->info_container); + lv_obj_set_pos(scr->act_time_container, 137, 12); + lv_obj_set_size(scr->act_time_container, 30, 100); + lv_obj_set_scrollbar_mode(scr->act_time_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->act_time_container + lv_obj_set_style_bg_color(scr->act_time_container, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_color(scr->act_time_container, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->act_time_container, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->act_time_label + scr->act_time_label = lv_label_create(scr->act_time_container); + lv_label_set_text(scr->act_time_label, "活\n动\n时\n间"); + lv_label_set_long_mode(scr->act_time_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->act_time_label, 5, 3); + lv_obj_set_size(scr->act_time_label, 21, 88); + + // Set style of scr->act_time_label + lv_obj_set_style_text_font(scr->act_time_label, fs_sourcehansanssc_bold_16, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->act_time_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->start_time_label + scr->start_time_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->start_time_label, "10.01"); + lv_label_set_long_mode(scr->start_time_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->start_time_label, 187, 1); + lv_obj_set_size(scr->start_time_label, 115, 61); + + // Set style of scr->start_time_label + lv_obj_set_style_text_font(scr->start_time_label, fs_sourcehansanssc_bold_40, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->start_time_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->end_timer_label + scr->end_timer_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->end_timer_label, "10.07"); + lv_label_set_long_mode(scr->end_timer_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->end_timer_label, 186, 61); + lv_obj_set_size(scr->end_timer_label, 115, 61); + + // Set style of scr->end_timer_label + lv_obj_set_style_text_font(scr->end_timer_label, fs_sourcehansanssc_bold_40, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->end_timer_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->line + scr->line = lv_obj_create(scr->info_container); + lv_obj_set_pos(scr->line, 192, 63); + lv_obj_set_size(scr->line, 100, 3); + lv_obj_set_scrollbar_mode(scr->line, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->line + lv_obj_set_style_bg_color(scr->line, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->contact_info_container + scr->contact_info_container = lv_obj_create(scr->info_container); + lv_obj_set_pos(scr->contact_info_container, 311, 13); + lv_obj_set_size(scr->contact_info_container, 30, 100); + lv_obj_set_scrollbar_mode(scr->contact_info_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->contact_info_container + lv_obj_set_style_bg_color(scr->contact_info_container, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_color(scr->contact_info_container, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->contact_info_container, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->contact_info_label + scr->contact_info_label = lv_label_create(scr->contact_info_container); + lv_label_set_text(scr->contact_info_label, "联\n系\n方\n式"); + lv_label_set_long_mode(scr->contact_info_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->contact_info_label, 5, 3); + lv_obj_set_size(scr->contact_info_label, 21, 86); + + // Set style of scr->contact_info_label + lv_obj_set_style_text_font(scr->contact_info_label, fs_sourcehansanssc_bold_16, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->contact_info_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->phone_label + scr->phone_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->phone_label, "订购电话:"); + lv_label_set_long_mode(scr->phone_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->phone_label, 359, 21); + lv_obj_set_size(scr->phone_label, 140, 32); + + // Set style of scr->phone_label + lv_obj_set_style_text_font(scr->phone_label, fs_sourcehansanssc_bold_28, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->phone_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->phone_num_label + scr->phone_num_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->phone_num_label, "400-9527-952X"); + lv_label_set_long_mode(scr->phone_num_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->phone_num_label, 509, 12); + lv_obj_set_size(scr->phone_num_label, 282, 61); + + // Set style of scr->phone_num_label + lv_obj_set_style_text_font(scr->phone_num_label, fs_sourcehansanssc_bold_38, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->phone_num_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->addr_label + scr->addr_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->addr_label, "火星熔石区泰拉瑞亚文化中路XX号"); + lv_label_set_long_mode(scr->addr_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->addr_label, 356, 70); + lv_obj_set_size(scr->addr_label, 431, 35); + + // Set style of scr->addr_label + lv_obj_set_style_text_font(scr->addr_label, fs_sourcehansanssc_bold_28, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->addr_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->container_3 + scr->container_3 = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->container_3, 510, 886); + lv_obj_set_size(scr->container_3, 305, 286); + lv_obj_set_scrollbar_mode(scr->container_3, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->container_3 + lv_obj_set_style_bg_color(scr->container_3, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_opa(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->container_3, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->money_label + scr->money_label = lv_label_create(scr->container_3); + lv_label_set_text(scr->money_label, "¥"); + lv_label_set_long_mode(scr->money_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->money_label, 24, 84); + lv_obj_set_size(scr->money_label, 83, 107); + + // Set style of scr->money_label + lv_obj_set_style_text_font(scr->money_label, fs_sourcehansanssc_bold_82, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->money_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->ex_price_container + scr->ex_price_container = lv_obj_create(scr->container_3); + lv_obj_set_pos(scr->ex_price_container, 19, 201); + lv_obj_set_size(scr->ex_price_container, 91, 57); + lv_obj_set_scrollbar_mode(scr->ex_price_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->ex_price_container + lv_obj_set_style_bg_color(scr->ex_price_container, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->ex_price_container, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->ex_price_label + scr->ex_price_label = lv_label_create(scr->ex_price_container); + lv_label_set_text(scr->ex_price_label, "特惠"); + lv_label_set_long_mode(scr->ex_price_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->ex_price_label, 10, 2); + lv_obj_set_size(scr->ex_price_label, 76, 47); + + // Set style of scr->ex_price_label + lv_obj_set_style_text_font(scr->ex_price_label, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->ex_price_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->price_label + scr->price_label = lv_label_create(scr->container_3); + lv_label_set_text(scr->price_label, "68"); + lv_label_set_long_mode(scr->price_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->price_label, 116, 15); + lv_obj_set_size(scr->price_label, 176, 197); + + // Set style of scr->price_label + lv_obj_set_style_text_font(scr->price_label, fs_sourcehansanssc_bold_144, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->price_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_18 + scr->label_18 = lv_label_create(scr->container_3); + lv_label_set_text(scr->label_18, "{两人份}"); + lv_label_set_long_mode(scr->label_18, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_18, 129, 204); + lv_obj_set_size(scr->label_18, 154, 47); + + // Set style of scr->label_18 + lv_obj_set_style_text_font(scr->label_18, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_18, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_container + scr->discount_container = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->discount_container, 154, 75); + lv_obj_set_size(scr->discount_container, 257, 320); + lv_obj_set_scrollbar_mode(scr->discount_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_container + lv_obj_set_style_bg_color(scr->discount_container, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_opa(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_container, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_detail_container_2 + scr->discount_detail_container_2 = lv_obj_create(scr->discount_container); + lv_obj_set_pos(scr->discount_detail_container_2, 117, 34); + lv_obj_set_size(scr->discount_detail_container_2, 70, 269); + lv_obj_set_scrollbar_mode(scr->discount_detail_container_2, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_detail_container_2 + lv_obj_set_style_bg_color(scr->discount_detail_container_2, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_label_2 + scr->discount_label_2 = lv_label_create(scr->discount_detail_container_2); + lv_label_set_text(scr->discount_label_2, "优\n惠\n多\n多"); + lv_label_set_long_mode(scr->discount_label_2, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->discount_label_2, 17, 55); + lv_obj_set_size(scr->discount_label_2, 39, 217); + + // Set style of scr->discount_label_2 + lv_obj_set_style_text_font(scr->discount_label_2, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->discount_label_2, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_image_2 + scr->discount_image_2 = lv_img_create(scr->discount_detail_container_2); + lv_img_set_src(scr->discount_image_2, LVGL_IMAGE_PATH(diamond_red_1.png)); + lv_img_set_pivot(scr->discount_image_2, 50, 50); + lv_img_set_angle(scr->discount_image_2, 0); + lv_obj_set_style_img_opa(scr->discount_image_2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->discount_image_2, 13, 10); + + // Init scr->discount_detail_container_3 + scr->discount_detail_container_3 = lv_obj_create(scr->discount_container); + lv_obj_set_pos(scr->discount_detail_container_3, 183, 34); + lv_obj_set_size(scr->discount_detail_container_3, 70, 269); + lv_obj_set_scrollbar_mode(scr->discount_detail_container_3, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_detail_container_3 + lv_obj_set_style_bg_color(scr->discount_detail_container_3, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_label_3 + scr->discount_label_3 = lv_label_create(scr->discount_detail_container_3); + lv_label_set_text(scr->discount_label_3, "低\n至\n五\n折"); + lv_label_set_long_mode(scr->discount_label_3, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->discount_label_3, 17, 55); + lv_obj_set_size(scr->discount_label_3, 39, 217); + + // Set style of scr->discount_label_3 + lv_obj_set_style_text_font(scr->discount_label_3, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->discount_label_3, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_image_3 + scr->discount_image_3 = lv_img_create(scr->discount_detail_container_3); + lv_img_set_src(scr->discount_image_3, LVGL_IMAGE_PATH(diamond_red_1.png)); + lv_img_set_pivot(scr->discount_image_3, 50, 50); + lv_img_set_angle(scr->discount_image_3, 0); + lv_obj_set_style_img_opa(scr->discount_image_3, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->discount_image_3, 13, 10); + + // Init scr->discount_detail_container_1 + scr->discount_detail_container_1 = lv_obj_create(scr->discount_container); + lv_obj_set_pos(scr->discount_detail_container_1, 48, 34); + lv_obj_set_size(scr->discount_detail_container_1, 70, 269); + lv_obj_set_scrollbar_mode(scr->discount_detail_container_1, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_detail_container_1 + lv_obj_set_style_bg_color(scr->discount_detail_container_1, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_label_1 + scr->discount_label_1 = lv_label_create(scr->discount_detail_container_1); + lv_label_set_text(scr->discount_label_1, "活\n动\n期\n间"); + lv_label_set_long_mode(scr->discount_label_1, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->discount_label_1, 17, 55); + lv_obj_set_size(scr->discount_label_1, 39, 217); + + // Set style of scr->discount_label_1 + lv_obj_set_style_text_font(scr->discount_label_1, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->discount_label_1, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_image_1 + scr->discount_image_1 = lv_img_create(scr->discount_detail_container_1); + lv_img_set_src(scr->discount_image_1, LVGL_IMAGE_PATH(diamond_red_1.png)); + lv_img_set_pivot(scr->discount_image_1, 50, 50); + lv_img_set_angle(scr->discount_image_1, 0); + lv_obj_set_style_img_opa(scr->discount_image_1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->discount_image_1, 13, 10); + + // Init scr->title_contianer + scr->title_contianer = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->title_contianer, 401, 21); + lv_obj_set_size(scr->title_contianer, 398, 380); + lv_obj_set_scrollbar_mode(scr->title_contianer, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->title_contianer + lv_obj_set_style_bg_color(scr->title_contianer, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->name_contianer + scr->name_contianer = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->name_contianer, 42, 36); + lv_obj_set_size(scr->name_contianer, 312, 313); + lv_obj_set_scrollbar_mode(scr->name_contianer, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->name_contianer + lv_obj_set_style_bg_color(scr->name_contianer, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_color(scr->name_contianer, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->name_contianer, 7, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_3 + scr->label_3 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_3, "海"); + lv_label_set_long_mode(scr->label_3, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_3, 8, 127); + lv_obj_set_size(scr->label_3, 125, 153); + + // Set style of scr->label_3 + lv_obj_set_style_text_font(scr->label_3, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_3, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_4 + scr->label_4 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_4, "鲜"); + lv_label_set_long_mode(scr->label_4, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_4, 158, 128); + lv_obj_set_size(scr->label_4, 106, 144); + + // Set style of scr->label_4 + lv_obj_set_style_text_font(scr->label_4, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_4, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_1 + scr->label_1 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_1, "家"); + lv_label_set_long_mode(scr->label_1, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_1, 157, -20); + lv_obj_set_size(scr->label_1, 125, 151); + + // Set style of scr->label_1 + lv_obj_set_style_text_font(scr->label_1, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_1, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_2 + scr->label_2 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_2, "有"); + lv_label_set_long_mode(scr->label_2, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_2, 18, -25); + lv_obj_set_size(scr->label_2, 106, 144); + + // Set style of scr->label_2 + lv_obj_set_style_text_font(scr->label_2, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_2, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_1 + scr->point_1 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->point_1, 19, 160); + lv_obj_set_size(scr->point_1, 54, 54); + lv_obj_set_scrollbar_mode(scr->point_1, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->point_1 + lv_obj_set_style_bg_color(scr->point_1, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->point_1, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_label_1 + scr->point_label_1 = lv_label_create(scr->point_1); + lv_label_set_text(scr->point_label_1, "正"); + lv_label_set_long_mode(scr->point_label_1, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->point_label_1, 11, 1); + lv_obj_set_size(scr->point_label_1, 31, 42); + + // Set style of scr->point_label_1 + lv_obj_set_style_text_font(scr->point_label_1, fs_sourcehansanssc_bold_31, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->point_label_1, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_2 + scr->point_2 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->point_2, 324, 160); + lv_obj_set_size(scr->point_2, 54, 54); + lv_obj_set_scrollbar_mode(scr->point_2, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->point_2 + lv_obj_set_style_bg_color(scr->point_2, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->point_2, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_label_2 + scr->point_label_2 = lv_label_create(scr->point_2); + lv_label_set_text(scr->point_label_2, "宗"); + lv_label_set_long_mode(scr->point_label_2, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->point_label_2, 12, 2); + lv_obj_set_size(scr->point_label_2, 31, 42); + + // Set style of scr->point_label_2 + lv_obj_set_style_text_font(scr->point_label_2, fs_sourcehansanssc_bold_31, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->point_label_2, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->small_point_1 + scr->small_point_1 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->small_point_1, 32, 27); + lv_obj_set_size(scr->small_point_1, 25, 25); + lv_obj_set_scrollbar_mode(scr->small_point_1, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->small_point_1 + lv_obj_set_style_bg_color(scr->small_point_1, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->small_point_1, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->small_point_2 + scr->small_point_2 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->small_point_2, 339, 26); + lv_obj_set_size(scr->small_point_2, 25, 25); + lv_obj_set_scrollbar_mode(scr->small_point_2, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->small_point_2 + lv_obj_set_style_bg_color(scr->small_point_2, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->small_point_2, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->small_point_4 + scr->small_point_4 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->small_point_4, 340, 332); + lv_obj_set_size(scr->small_point_4, 25, 25); + lv_obj_set_scrollbar_mode(scr->small_point_4, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->small_point_4 + lv_obj_set_style_bg_color(scr->small_point_4, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->small_point_4, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->container_12 + scr->container_12 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->container_12, 32, 333); + lv_obj_set_size(scr->container_12, 25, 25); + lv_obj_set_scrollbar_mode(scr->container_12, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->container_12 + lv_obj_set_style_bg_color(scr->container_12, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->container_12, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); +} diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/price_tags_2.c b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/price_tags_2.c new file mode 100644 index 000000000..9d8103974 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/screen/price_tags_2.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#include "ui_objects.h" +#include "aic_ui.h" +#include "ui_util.h" +#include "lv_aic_player.h" + +void price_tags_screen_2_create(ui_manager_t *ui) +{ + price_tags_screen_t *scr = price_tags_screen_2_get(ui); + + if (!ui->auto_del && scr->obj) + return; + + // Init scr->obj + scr->obj = lv_obj_create(NULL); + lv_obj_set_scrollbar_mode(scr->obj, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->obj + lv_obj_set_style_bg_color(scr->obj, lv_color_hex(0xfcfcfc), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->background + scr->background = lv_aic_player_create(scr->obj); + lv_aic_player_set_src(scr->background, LVGL_VIDEO_PATH(board2_1_scale.mp4)); + lv_aic_player_set_auto_restart(scr->background, true); + lv_aic_player_set_cmd(scr->background, LV_AIC_PLAYER_CMD_START, NULL); + lv_obj_set_pos(scr->background, 0, 0); + lv_obj_set_size(scr->background, 800, 1280); + + // Init scr->info_container + scr->info_container = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->info_container, 0, 1157); + lv_obj_set_size(scr->info_container, 800, 123); + lv_obj_set_scrollbar_mode(scr->info_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->info_container + lv_obj_set_style_bg_color(scr->info_container, lv_color_hex(0x452000), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->qrcode +#if LVGL_VERSION_MAJOR == 8 + scr->qrcode = lv_qrcode_create(scr->info_container, 100, lv_color_hex(0x000000), lv_color_hex(0xffffff)); +#else + scr->qrcode = lv_qrcode_create(scr->info_container); + lv_qrcode_set_size(scr->qrcode, 100); + lv_qrcode_set_dark_color(scr->qrcode, lv_color_hex(0x000000)); + lv_qrcode_set_light_color(scr->qrcode, lv_color_hex(0xffffff)); +#endif + lv_qrcode_update(scr->qrcode, "www.artinchip.com", 17); + lv_obj_set_pos(scr->qrcode, 18, 11); + + // Init scr->act_time_container + scr->act_time_container = lv_obj_create(scr->info_container); + lv_obj_set_pos(scr->act_time_container, 137, 12); + lv_obj_set_size(scr->act_time_container, 30, 100); + lv_obj_set_scrollbar_mode(scr->act_time_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->act_time_container + lv_obj_set_style_bg_color(scr->act_time_container, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_color(scr->act_time_container, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->act_time_container, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->act_time_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->act_time_label + scr->act_time_label = lv_label_create(scr->act_time_container); + lv_label_set_text(scr->act_time_label, "活\n动\n时\n间"); + lv_label_set_long_mode(scr->act_time_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->act_time_label, 5, 3); + lv_obj_set_size(scr->act_time_label, 21, 88); + + // Set style of scr->act_time_label + lv_obj_set_style_text_font(scr->act_time_label, fs_sourcehansanssc_bold_16, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->act_time_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->start_time_label + scr->start_time_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->start_time_label, "11.01"); + lv_label_set_long_mode(scr->start_time_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->start_time_label, 187, 1); + lv_obj_set_size(scr->start_time_label, 115, 61); + + // Set style of scr->start_time_label + lv_obj_set_style_text_font(scr->start_time_label, fs_sourcehansanssc_bold_40, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->start_time_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->end_timer_label + scr->end_timer_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->end_timer_label, "11.07"); + lv_label_set_long_mode(scr->end_timer_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->end_timer_label, 186, 61); + lv_obj_set_size(scr->end_timer_label, 115, 61); + + // Set style of scr->end_timer_label + lv_obj_set_style_text_font(scr->end_timer_label, fs_sourcehansanssc_bold_40, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->end_timer_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->line + scr->line = lv_obj_create(scr->info_container); + lv_obj_set_pos(scr->line, 192, 63); + lv_obj_set_size(scr->line, 100, 3); + lv_obj_set_scrollbar_mode(scr->line, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->line + lv_obj_set_style_bg_color(scr->line, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->line, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->contact_info_container + scr->contact_info_container = lv_obj_create(scr->info_container); + lv_obj_set_pos(scr->contact_info_container, 311, 13); + lv_obj_set_size(scr->contact_info_container, 30, 100); + lv_obj_set_scrollbar_mode(scr->contact_info_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->contact_info_container + lv_obj_set_style_bg_color(scr->contact_info_container, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_color(scr->contact_info_container, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->contact_info_container, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->contact_info_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->contact_info_label + scr->contact_info_label = lv_label_create(scr->contact_info_container); + lv_label_set_text(scr->contact_info_label, "联\n系\n方\n式"); + lv_label_set_long_mode(scr->contact_info_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->contact_info_label, 5, 3); + lv_obj_set_size(scr->contact_info_label, 21, 86); + + // Set style of scr->contact_info_label + lv_obj_set_style_text_font(scr->contact_info_label, fs_sourcehansanssc_bold_16, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->contact_info_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->phone_label + scr->phone_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->phone_label, "订购电话:"); + lv_label_set_long_mode(scr->phone_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->phone_label, 359, 21); + lv_obj_set_size(scr->phone_label, 140, 32); + + // Set style of scr->phone_label + lv_obj_set_style_text_font(scr->phone_label, fs_sourcehansanssc_bold_28, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->phone_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->phone_num_label + scr->phone_num_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->phone_num_label, "400-9527-952X"); + lv_label_set_long_mode(scr->phone_num_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->phone_num_label, 509, 12); + lv_obj_set_size(scr->phone_num_label, 282, 61); + + // Set style of scr->phone_num_label + lv_obj_set_style_text_font(scr->phone_num_label, fs_sourcehansanssc_bold_38, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->phone_num_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->addr_label + scr->addr_label = lv_label_create(scr->info_container); + lv_label_set_text(scr->addr_label, "水星深海区泰拉瑞亚文化水路XY号"); + lv_label_set_long_mode(scr->addr_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->addr_label, 356, 70); + lv_obj_set_size(scr->addr_label, 431, 35); + + // Set style of scr->addr_label + lv_obj_set_style_text_font(scr->addr_label, fs_sourcehansanssc_bold_28, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->addr_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->container_3 + scr->container_3 = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->container_3, 510, 886); + lv_obj_set_size(scr->container_3, 305, 286); + lv_obj_set_scrollbar_mode(scr->container_3, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->container_3 + lv_obj_set_style_bg_color(scr->container_3, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_opa(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->container_3, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->money_label + scr->money_label = lv_label_create(scr->container_3); + lv_label_set_text(scr->money_label, "¥"); + lv_label_set_long_mode(scr->money_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->money_label, 24, 84); + lv_obj_set_size(scr->money_label, 83, 107); + + // Set style of scr->money_label + lv_obj_set_style_text_font(scr->money_label, fs_sourcehansanssc_bold_82, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->money_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->ex_price_container + scr->ex_price_container = lv_obj_create(scr->container_3); + lv_obj_set_pos(scr->ex_price_container, 19, 201); + lv_obj_set_size(scr->ex_price_container, 91, 57); + lv_obj_set_scrollbar_mode(scr->ex_price_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->ex_price_container + lv_obj_set_style_bg_color(scr->ex_price_container, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->ex_price_container, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->ex_price_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->ex_price_label + scr->ex_price_label = lv_label_create(scr->ex_price_container); + lv_label_set_text(scr->ex_price_label, "优惠"); + lv_label_set_long_mode(scr->ex_price_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->ex_price_label, 10, 2); + lv_obj_set_size(scr->ex_price_label, 76, 47); + + // Set style of scr->ex_price_label + lv_obj_set_style_text_font(scr->ex_price_label, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->ex_price_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->price_label + scr->price_label = lv_label_create(scr->container_3); + lv_label_set_text(scr->price_label, "88"); + lv_label_set_long_mode(scr->price_label, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->price_label, 116, 15); + lv_obj_set_size(scr->price_label, 176, 197); + + // Set style of scr->price_label + lv_obj_set_style_text_font(scr->price_label, fs_sourcehansanssc_bold_144, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->price_label, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_18 + scr->label_18 = lv_label_create(scr->container_3); + lv_label_set_text(scr->label_18, "{单人份}"); + lv_label_set_long_mode(scr->label_18, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_18, 129, 204); + lv_obj_set_size(scr->label_18, 154, 47); + + // Set style of scr->label_18 + lv_obj_set_style_text_font(scr->label_18, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_18, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_container + scr->discount_container = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->discount_container, 154, 75); + lv_obj_set_size(scr->discount_container, 257, 320); + lv_obj_set_scrollbar_mode(scr->discount_container, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_container + lv_obj_set_style_bg_color(scr->discount_container, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_opa(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_container, 2, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_container, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_detail_container_2 + scr->discount_detail_container_2 = lv_obj_create(scr->discount_container); + lv_obj_set_pos(scr->discount_detail_container_2, 117, 34); + lv_obj_set_size(scr->discount_detail_container_2, 70, 269); + lv_obj_set_scrollbar_mode(scr->discount_detail_container_2, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_detail_container_2 + lv_obj_set_style_bg_color(scr->discount_detail_container_2, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_detail_container_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_label_2 + scr->discount_label_2 = lv_label_create(scr->discount_detail_container_2); + lv_label_set_text(scr->discount_label_2, "优\n惠\n多\n多"); + lv_label_set_long_mode(scr->discount_label_2, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->discount_label_2, 17, 55); + lv_obj_set_size(scr->discount_label_2, 39, 217); + + // Set style of scr->discount_label_2 + lv_obj_set_style_text_font(scr->discount_label_2, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->discount_label_2, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_image_2 + scr->discount_image_2 = lv_img_create(scr->discount_detail_container_2); + lv_img_set_src(scr->discount_image_2, LVGL_IMAGE_PATH(diamond_red_1.png)); + lv_img_set_pivot(scr->discount_image_2, 50, 50); + lv_img_set_angle(scr->discount_image_2, 0); + lv_obj_set_style_img_opa(scr->discount_image_2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->discount_image_2, 13, 10); + + // Init scr->discount_detail_container_3 + scr->discount_detail_container_3 = lv_obj_create(scr->discount_container); + lv_obj_set_pos(scr->discount_detail_container_3, 183, 34); + lv_obj_set_size(scr->discount_detail_container_3, 70, 269); + lv_obj_set_scrollbar_mode(scr->discount_detail_container_3, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_detail_container_3 + lv_obj_set_style_bg_color(scr->discount_detail_container_3, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_detail_container_3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_label_3 + scr->discount_label_3 = lv_label_create(scr->discount_detail_container_3); + lv_label_set_text(scr->discount_label_3, "低\n至\n八\n折"); + lv_label_set_long_mode(scr->discount_label_3, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->discount_label_3, 17, 55); + lv_obj_set_size(scr->discount_label_3, 39, 217); + + // Set style of scr->discount_label_3 + lv_obj_set_style_text_font(scr->discount_label_3, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->discount_label_3, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_image_3 + scr->discount_image_3 = lv_img_create(scr->discount_detail_container_3); + lv_img_set_src(scr->discount_image_3, LVGL_IMAGE_PATH(diamond_red_1.png)); + lv_img_set_pivot(scr->discount_image_3, 50, 50); + lv_img_set_angle(scr->discount_image_3, 0); + lv_obj_set_style_img_opa(scr->discount_image_3, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->discount_image_3, 13, 10); + + // Init scr->discount_detail_container_1 + scr->discount_detail_container_1 = lv_obj_create(scr->discount_container); + lv_obj_set_pos(scr->discount_detail_container_1, 48, 34); + lv_obj_set_size(scr->discount_detail_container_1, 70, 269); + lv_obj_set_scrollbar_mode(scr->discount_detail_container_1, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->discount_detail_container_1 + lv_obj_set_style_bg_color(scr->discount_detail_container_1, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->discount_detail_container_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_label_1 + scr->discount_label_1 = lv_label_create(scr->discount_detail_container_1); + lv_label_set_text(scr->discount_label_1, "活\n动\n期\n间"); + lv_label_set_long_mode(scr->discount_label_1, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->discount_label_1, 17, 55); + lv_obj_set_size(scr->discount_label_1, 39, 217); + + // Set style of scr->discount_label_1 + lv_obj_set_style_text_font(scr->discount_label_1, fs_sourcehansanssc_bold_36, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->discount_label_1, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->discount_image_1 + scr->discount_image_1 = lv_img_create(scr->discount_detail_container_1); + lv_img_set_src(scr->discount_image_1, LVGL_IMAGE_PATH(diamond_red_1.png)); + lv_img_set_pivot(scr->discount_image_1, 50, 50); + lv_img_set_angle(scr->discount_image_1, 0); + lv_obj_set_style_img_opa(scr->discount_image_1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_pos(scr->discount_image_1, 13, 10); + + // Init scr->title_contianer + scr->title_contianer = lv_obj_create(scr->obj); + lv_obj_set_pos(scr->title_contianer, 401, 21); + lv_obj_set_size(scr->title_contianer, 398, 380); + lv_obj_set_scrollbar_mode(scr->title_contianer, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->title_contianer + lv_obj_set_style_bg_color(scr->title_contianer, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->title_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->name_contianer + scr->name_contianer = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->name_contianer, 42, 36); + lv_obj_set_size(scr->name_contianer, 312, 313); + lv_obj_set_scrollbar_mode(scr->name_contianer, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->name_contianer + lv_obj_set_style_bg_color(scr->name_contianer, lv_color_hex(0xeff8f5), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_color(scr->name_contianer, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->name_contianer, 7, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->name_contianer, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_3 + scr->label_3 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_3, "日"); + lv_label_set_long_mode(scr->label_3, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_3, 8, 127); + lv_obj_set_size(scr->label_3, 125, 153); + + // Set style of scr->label_3 + lv_obj_set_style_text_font(scr->label_3, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_3, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_4 + scr->label_4 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_4, "料"); + lv_label_set_long_mode(scr->label_4, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_4, 158, 128); + lv_obj_set_size(scr->label_4, 106, 144); + + // Set style of scr->label_4 + lv_obj_set_style_text_font(scr->label_4, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_4, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_1 + scr->label_1 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_1, "家"); + lv_label_set_long_mode(scr->label_1, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_1, 157, -20); + lv_obj_set_size(scr->label_1, 125, 151); + + // Set style of scr->label_1 + lv_obj_set_style_text_font(scr->label_1, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_1, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->label_2 + scr->label_2 = lv_label_create(scr->name_contianer); + lv_label_set_text(scr->label_2, "有"); + lv_label_set_long_mode(scr->label_2, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->label_2, 18, -25); + lv_obj_set_size(scr->label_2, 106, 144); + + // Set style of scr->label_2 + lv_obj_set_style_text_font(scr->label_2, fs_sourcehansanssc_bold_126, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->label_2, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_1 + scr->point_1 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->point_1, 19, 160); + lv_obj_set_size(scr->point_1, 54, 54); + lv_obj_set_scrollbar_mode(scr->point_1, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->point_1 + lv_obj_set_style_bg_color(scr->point_1, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->point_1, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_label_1 + scr->point_label_1 = lv_label_create(scr->point_1); + lv_label_set_text(scr->point_label_1, "正"); + lv_label_set_long_mode(scr->point_label_1, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->point_label_1, 11, 1); + lv_obj_set_size(scr->point_label_1, 31, 42); + + // Set style of scr->point_label_1 + lv_obj_set_style_text_font(scr->point_label_1, fs_sourcehansanssc_bold_31, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->point_label_1, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_2 + scr->point_2 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->point_2, 324, 160); + lv_obj_set_size(scr->point_2, 54, 54); + lv_obj_set_scrollbar_mode(scr->point_2, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->point_2 + lv_obj_set_style_bg_color(scr->point_2, lv_color_hex(0xaf1402), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->point_2, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->point_label_2 + scr->point_label_2 = lv_label_create(scr->point_2); + lv_label_set_text(scr->point_label_2, "宗"); + lv_label_set_long_mode(scr->point_label_2, LV_LABEL_LONG_WRAP); + lv_obj_set_pos(scr->point_label_2, 12, 2); + lv_obj_set_size(scr->point_label_2, 31, 42); + + // Set style of scr->point_label_2 + lv_obj_set_style_text_font(scr->point_label_2, fs_sourcehansanssc_bold_31, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_color(scr->point_label_2, lv_color_hex(0xffffff), LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->small_point_1 + scr->small_point_1 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->small_point_1, 32, 27); + lv_obj_set_size(scr->small_point_1, 25, 25); + lv_obj_set_scrollbar_mode(scr->small_point_1, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->small_point_1 + lv_obj_set_style_bg_color(scr->small_point_1, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->small_point_1, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->small_point_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->small_point_2 + scr->small_point_2 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->small_point_2, 339, 26); + lv_obj_set_size(scr->small_point_2, 25, 25); + lv_obj_set_scrollbar_mode(scr->small_point_2, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->small_point_2 + lv_obj_set_style_bg_color(scr->small_point_2, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->small_point_2, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->small_point_2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->small_point_4 + scr->small_point_4 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->small_point_4, 340, 332); + lv_obj_set_size(scr->small_point_4, 25, 25); + lv_obj_set_scrollbar_mode(scr->small_point_4, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->small_point_4 + lv_obj_set_style_bg_color(scr->small_point_4, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->small_point_4, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->small_point_4, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + // Init scr->container_12 + scr->container_12 = lv_obj_create(scr->title_contianer); + lv_obj_set_pos(scr->container_12, 32, 333); + lv_obj_set_size(scr->container_12, 25, 25); + lv_obj_set_scrollbar_mode(scr->container_12, LV_SCROLLBAR_MODE_OFF); + + // Set style of scr->container_12 + lv_obj_set_style_bg_color(scr->container_12, lv_color_hex(0xc9813a), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(scr->container_12, 360, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(scr->container_12, 0, LV_PART_MAIN | LV_STATE_DEFAULT); +} diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_init.c b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_init.c new file mode 100644 index 000000000..269756d26 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_init.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#include "ui_init.h" +#include "ui_util.h" +#include "aic_ui.h" + +ui_manager_t ui_manager; + +lv_font_t *fs_sourcehansanssc_bold_16; +lv_font_t *fs_sourcehansanssc_bold_40; +lv_font_t *fs_sourcehansanssc_bold_144; +lv_font_t *fs_sourcehansanssc_bold_126; +lv_font_t *fs_sourcehansanssc_bold_28; +lv_font_t *fs_sourcehansanssc_bold_31; +lv_font_t *fs_sourcehansanssc_bold_36; +lv_font_t *fs_sourcehansanssc_bold_82; +lv_font_t *fs_sourcehansanssc_bold_38; + +void ui_init(void) +{ + fs_sourcehansanssc_bold_16 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 16); + fs_sourcehansanssc_bold_40 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 40); + fs_sourcehansanssc_bold_144 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 144); + fs_sourcehansanssc_bold_126 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 126); + fs_sourcehansanssc_bold_28 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 28); + fs_sourcehansanssc_bold_31 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 31); + fs_sourcehansanssc_bold_36 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 36); + fs_sourcehansanssc_bold_82 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 82); + fs_sourcehansanssc_bold_38 = ui_font_init(LVGL_FONT_PATH(SourceHanSansSC-Bold-crop.otf), 38); + if (!fs_sourcehansanssc_bold_16) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_16"); + return; + } + if (!fs_sourcehansanssc_bold_40) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_40"); + return; + } + if (!fs_sourcehansanssc_bold_144) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_144"); + return; + } + if (!fs_sourcehansanssc_bold_126) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_126"); + return; + } + if (!fs_sourcehansanssc_bold_28) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_28"); + return; + } + if (!fs_sourcehansanssc_bold_31) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_31"); + return; + } + if (!fs_sourcehansanssc_bold_36) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_36"); + return; + } + if (!fs_sourcehansanssc_bold_82) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_82"); + return; + } + if (!fs_sourcehansanssc_bold_38) { + LV_LOG_ERROR("Failed to init fs_sourcehansanssc_bold_38"); + return; + } + + // auto delete screen + ui_manager_init(&ui_manager, false); + +#if USE_DOUBLE_SDL_DISP + extern void lv_sdl_window_create_test(); + lv_sdl_window_create_test(); + + lv_disp_t *disp_0 = lv_display_get_next(NULL); + lv_disp_t *disp_1 = lv_display_get_next(disp_0); +#endif + +#if USE_HOST_DEMO +#if USE_DOUBLE_SDL_DISP + lv_disp_set_default(disp_0); +#endif + price_tags_screen_1_create(&ui_manager); +#endif + +#if USE_DEVICE_DEMO +#if USE_DOUBLE_SDL_DISP + lv_disp_set_default(disp_1); +#endif + price_tags_screen_2_create(&ui_manager); + progress_screen_create(&ui_manager); + + extern void check_load_assets_create(ui_manager_t *ui); + check_load_assets_create(&ui_manager); +#endif + +#if USE_HOST_DEMO +#if USE_DOUBLE_SDL_DISP + lv_disp_set_default(disp_0); +#endif + lv_scr_load(price_tags_screen_1_get(&ui_manager)->obj); +#endif + +#if USE_DEVICE_DEMO +#if USE_DOUBLE_SDL_DISP + lv_disp_set_default(disp_1); +#endif + lv_scr_load(progress_screen_get(&ui_manager)->obj); +#endif +} diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_init.h b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_init.h new file mode 100644 index 000000000..7b4b811fa --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_init.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#ifndef _UI_INIT_H +#define _UI_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "ui_objects.h" + +void ui_init(void); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif // _UI_INIT_H diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_objects.h b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_objects.h new file mode 100644 index 000000000..0eeead43f --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_objects.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#ifndef _UI_OBJECTS +#define _UI_OBJECTS + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" +#include "lv_conf_custom.h" + +typedef struct { + lv_obj_t *obj; + lv_obj_t *background; + lv_obj_t *info_container; + lv_obj_t *qrcode; + lv_obj_t *act_time_container; + lv_obj_t *act_time_label; + lv_obj_t *start_time_label; + lv_obj_t *end_timer_label; + lv_obj_t *line; + lv_obj_t *contact_info_container; + lv_obj_t *contact_info_label; + lv_obj_t *phone_label; + lv_obj_t *phone_num_label; + lv_obj_t *addr_label; + lv_obj_t *container_3; + lv_obj_t *money_label; + lv_obj_t *ex_price_container; + lv_obj_t *ex_price_label; + lv_obj_t *price_label; + lv_obj_t *label_18; + lv_obj_t *discount_container; + lv_obj_t *discount_detail_container_2; + lv_obj_t *discount_label_2; + lv_obj_t *discount_image_2; + lv_obj_t *discount_detail_container_3; + lv_obj_t *discount_label_3; + lv_obj_t *discount_image_3; + lv_obj_t *discount_detail_container_1; + lv_obj_t *discount_label_1; + lv_obj_t *discount_image_1; + lv_obj_t *title_contianer; + lv_obj_t *name_contianer; + lv_obj_t *label_3; + lv_obj_t *label_4; + lv_obj_t *label_1; + lv_obj_t *label_2; + lv_obj_t *point_1; + lv_obj_t *point_label_1; + lv_obj_t *point_2; + lv_obj_t *point_label_2; + lv_obj_t *small_point_1; + lv_obj_t *small_point_2; + lv_obj_t *small_point_4; + lv_obj_t *container_12; +} price_tags_screen_t; + + +typedef struct { + lv_obj_t *obj; + lv_obj_t *container; + lv_obj_t *title_label; + lv_obj_t *progress_label; + lv_obj_t *progress_bar; + lv_obj_t *spinner; + + lv_timer_t * timer; // Progress update timer + uint32_t start_time; // Start time + bool is_loading_complete; // Whether loading is complete +} progress_screen_t; + +typedef struct { + bool auto_del; + price_tags_screen_t price_tags_screen_1; + price_tags_screen_t price_tags_screen_2; + progress_screen_t progress_screen; +} ui_manager_t; + +static inline void ui_manager_init(ui_manager_t *ui, bool auto_del) +{ + memset(ui, 0 , sizeof(ui_manager_t)); + ui->auto_del = auto_del; +} + +static inline price_tags_screen_t *price_tags_screen_1_get(ui_manager_t *ui) +{ + return &ui->price_tags_screen_1; +} + +static inline price_tags_screen_t *price_tags_screen_2_get(ui_manager_t *ui) +{ + return &ui->price_tags_screen_2; +} + +static inline progress_screen_t *progress_screen_get(ui_manager_t *ui) +{ + return &ui->progress_screen; +} + +void price_tags_screen_1_create(ui_manager_t *ui); +void price_tags_screen_2_create(ui_manager_t *ui); +void progress_screen_create(ui_manager_t *ui); + +void progress_screen_set_finish(ui_manager_t *ui); + +extern lv_font_t *fs_sourcehansanssc_bold_16; +extern lv_font_t *fs_sourcehansanssc_bold_40; +extern lv_font_t *fs_sourcehansanssc_bold_144; +extern lv_font_t *fs_sourcehansanssc_bold_126; +extern lv_font_t *fs_sourcehansanssc_bold_28; +extern lv_font_t *fs_sourcehansanssc_bold_31; +extern lv_font_t *fs_sourcehansanssc_bold_36; +extern lv_font_t *fs_sourcehansanssc_bold_82; +extern lv_font_t *fs_sourcehansanssc_bold_38; + + +extern ui_manager_t ui_manager; + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif // _UI_OBJECTS diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_util.c b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_util.c new file mode 100644 index 000000000..032ad5814 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_util.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#include +#include "ui_util.h" + +bool screen_is_loading(lv_obj_t *scr) +{ +#if LVGL_VERSION_MAJOR == 8 + lv_obj_t *act_scr = lv_scr_act(); + lv_disp_t *d = lv_obj_get_disp(scr); + if (d->prev_scr == NULL && (d->scr_to_load == NULL || d->scr_to_load == act_scr)) + return false; + else + return true; +#else + return false; +#endif +} + +void ui_style_init(lv_style_t *style) +{ + if (style->prop_cnt >= 1) + lv_style_reset(style); + else + lv_style_init(style); +} + +lv_font_t *ui_font_init(char *path, int size) { +#if LVGL_VERSION_MAJOR == 8 + static lv_ft_info_t info; + info.name = path; + info.weight = size; + info.style = FT_FONT_STYLE_NORMAL; + info.mem = NULL; + if (!lv_ft_font_init(&info)) + return NULL; + return info.font; +#else + lv_font_t *font = lv_freetype_font_create(path, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, + size, + LV_FREETYPE_FONT_STYLE_NORMAL); + return font; +#endif //LVGL_VERSION_MAJOR +} diff --git a/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_util.h b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_util.h new file mode 100644 index 000000000..28e5d36b4 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_demo/digital_menu_demo/ui_util.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 ArtInChip Technology Co., Ltd. + * + * This file was generated by AiUIBuilder + * AiUIBuilder version: v1.2.0 + */ + +#ifndef _UI_UTIL_H +#define _UI_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" + +bool screen_is_loading(lv_obj_t *scr); + +void ui_style_init(lv_style_t * style); + +lv_font_t *ui_font_init(char *path, int size); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif // _UI_UTIL_H diff --git a/source/artinchip/lvgl-ui/aic_ui.h b/source/artinchip/lvgl-ui/aic_ui.h index f5dc0189f..a21ea999f 100644 --- a/source/artinchip/lvgl-ui/aic_ui.h +++ b/source/artinchip/lvgl-ui/aic_ui.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 ArtInChip Technology Co., Ltd. + * Copyright (C) 2022-2025 ArtInChip Technology Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 * @@ -14,23 +14,48 @@ extern "C" { #endif #include +#include +#include #define LVGL_PATH_ORI "/usr/local/share/lvgl_data/" #define CONN(x, y) x#y #define LVGL_PATH(y) CONN(LVGL_DIR, y) #define LVGL_FONT_PATH(y) CONN(LVGL_PATH_ORI"font/", y) #define LVGL_IMAGE_PATH(y) CONN(LVGL_DIR"image/", y) +#define LVGL_VIDEO_PATH(y) CONN(LVGL_DIR"video/", y) #define FILE_LIST_PATH "/usr/local/share/lvgl_data/" #define LVGL_FILE_LIST_PATH(y) CONN(FILE_LIST_PATH, y) +#define LV_USE_AIC_SIMULATOR 0 + /* use fake image to fill color */ -#define FAKE_IMAGE_DECLARE(name) char fake_##name[128]; +#define FAKE_IMAGE_DECLARE(name) char fake_##name[256]; #define FAKE_IMAGE_INIT(name, w, h, blend, color) \ - snprintf(fake_##name, 128, "L:/%dx%d_%d_%08x.fake",\ + snprintf(fake_##name, 255, "L:/%dx%d_%d_%08x.fake",\ w, h, blend, color); #define FAKE_IMAGE_NAME(name) (fake_##name) -#define FAKE_IMAGE_PARSE(fake_name, ret, width, height, blend, color) \ - ret = sscanf(fake_name + 3, "%dx%d_%d_%08x", &width, &height, &blend, &color); + +#define FAKE_IMAGE_PARSE(fake_name, pwidth, pheight, pblend, pcolor) \ + fake_image_parse(fake_name, pwidth, pheight, pblend, pcolor) + +static inline void fake_image_parse(char *fake_name, int *width, + int *height, int *blend, + unsigned int *color) +{ + char *cur_ptr; + char *pos_ptr; + cur_ptr = fake_name + 3; + *width = strtol(cur_ptr, &pos_ptr, 10); + cur_ptr = pos_ptr + 1; + *height = strtol(cur_ptr, &pos_ptr, 10); + cur_ptr = pos_ptr + 1; + *blend = strtol(cur_ptr, &pos_ptr, 10); + cur_ptr = pos_ptr + 1; + *color = strtoul(cur_ptr, NULL, 16); + return; +} + +#define ui_snprintf(fmt, arg...) snprintf(fmt, 255, ##arg) uint32_t custom_tick_get(void); diff --git a/source/artinchip/lvgl-ui/aic_widgets/CMakeLists.txt b/source/artinchip/lvgl-ui/aic_widgets/CMakeLists.txt new file mode 100644 index 000000000..0c0eb69b4 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_widgets/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) + +project(aic_widgets LANGUAGES C) + +# Suppress cmake unused warning +set(ignore ${BUILD_DOC} ${BUILD_DOCS} ${BUILD_EXAMPLE} ${BUILD_EXAMPLES} + ${BUILD_SHARED_LIBS}${BUILD_TEST}${BUILD_TESTING}${BUILD_TESTS}) + +add_compile_options(-Wall -Werror) + +# set include path +set(INCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../${APP_FOLDER} +) + +# Set source file +file(GLOB WIDGETS_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c) + +file(GLOB AIC_CANVAS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/aic_canvas/*.c) + +if(DEFINED LVGL_V_9) + if(${LVGL_V_9} STREQUAL "yes") + file(GLOB AIC_CANVAS_FILES_V9 ${CMAKE_CURRENT_SOURCE_DIR}/aic_canvas/v9/*.c) + file(GLOB AIC_PLAYER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/aic_player/v9/*.c) + list(APPEND AIC_CANVAS_FILES ${AIC_CANVAS_FILES_V9}) + list(APPEND INCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/aic_canvas/v9 + ${CMAKE_CURRENT_SOURCE_DIR}/../lvgl_v9 + ${CMAKE_CURRENT_SOURCE_DIR}/../lvgl_v9/lvgl + ${CMAKE_CURRENT_SOURCE_DIR}/../lvgl_v9/lv_drivers/fbdev/lv_mpp_dec + ) + list(APPEND PUBLIC_INCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/aic_canvas/v9 + ${CMAKE_CURRENT_SOURCE_DIR}/aic_player/v9 + ) + if(BUILD_LYRICS_LIBS) + ### build lyrics_effect library + add_subdirectory(lyrics_effect) + endif() + else() + list(APPEND INCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/../lvgl_v8 + ${CMAKE_CURRENT_SOURCE_DIR}/../lvgl_v8/lvgl + ) + endif() +endif() + +set(WIDGETS_SOURCE_FILES ${WIDGETS_SOURCE_FILES} ${AIC_CANVAS_FILES} ${AIC_PLAYER_FILES}) +add_library(aic_widgets STATIC ${WIDGETS_SOURCE_FILES}) + +# add include path +target_include_directories(aic_widgets PRIVATE ${INCLUDE_PATH}) +target_include_directories(aic_widgets PUBLIC ${PUBLIC_INCLUDE_PATH}) + +# Install +if(NOT CMAKE_INSTALL_PREFIX) + message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.") +endif() +include(GNUInstallDirs) diff --git a/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/canvas_image.c b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/canvas_image.c new file mode 100644 index 000000000..3c7fb9823 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/canvas_image.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Ning Fang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lvgl.h" +#include "aic_ui.h" +#include "mpp_ge.h" +#include "canvas_image.h" +#include "dma_allocator.h" +#include "frame_allocator.h" + +#define ALIGN_8B(x) (((x) + (7)) & ~7) + +#if LVGL_VERSION_MAJOR == 9 +static struct mpp_ge *g_ge = NULL; + +void lv_mpp_image_free(mpp_decoder_data_t *image) +{ + if (image) { + if (image->data[0]) + dmabuf_munmap((unsigned char*)image->data[0], image->size[0]); + + if (image->dec_buf.fd[0] > 0) { + dmabuf_free(image->dec_buf.fd[0]); + } + + free(image); + } + + return; +} + +mpp_decoder_data_t *lv_mpp_image_alloc(int width, int height, enum mpp_pixel_format fmt) +{ + mpp_decoder_data_t *image = NULL; + int dma_fd = -1; + int size = 0; + + image = (mpp_decoder_data_t *)malloc(sizeof(mpp_decoder_data_t)); + if (!image) { + LV_LOG_ERROR("malloc failed"); + goto alloc_error; + } + + memset(image, 0, sizeof(mpp_decoder_data_t)); + + dma_fd = dmabuf_device_open(); + if (dma_fd < 0) { + LV_LOG_ERROR("dmabuf_device_open failed"); + goto alloc_error; + } + + if (fmt == MPP_FMT_ARGB_8888) { + image->dec_buf.stride[0] = ALIGN_8B(width * 4); + } else if (fmt == MPP_FMT_RGB_565) { + image->dec_buf.stride[0] = ALIGN_8B(width * 2); + } else { + LV_LOG_ERROR("unsupport fmt:%d", fmt); + goto alloc_error; + } + + size = image->dec_buf.stride[0] * height; + image->size[0] = size; + image->dec_buf.buf_type = MPP_DMA_BUF_FD; + image->dec_buf.size.width = width; + image->dec_buf.size.height = height; + image->dec_buf.format = fmt; + image->dec_buf.fd[0] = dmabuf_alloc(dma_fd, size); + + if (image->dec_buf.fd[0] < 0) { + LV_LOG_ERROR("dmabuf_alloc failed"); + goto alloc_error; + } else { + image->data[0] = dmabuf_mmap(image->dec_buf.fd[0], size); + if (image->data[0] == MAP_FAILED) { + image->data[0] = NULL; + LV_LOG_ERROR("dmabuf_mmap failed"); + goto alloc_error; + } + } + + dmabuf_device_close(dma_fd); + return image; + +alloc_error: + lv_mpp_image_free(image); + + if (dma_fd > 0) + dmabuf_device_close(dma_fd); + + return NULL; +} + +int lv_ge_fill(struct mpp_buf *buf, enum ge_fillrect_type type, + unsigned int start_color, unsigned int end_color, int blend) +{ + int ret; + struct ge_fillrect fill = { 0 }; + + if (!g_ge) + g_ge = mpp_ge_open(); + + /* fill info */ + fill.type = type; + fill.start_color = start_color; + fill.end_color = end_color; + + /* dst buf */ + memcpy(&fill.dst_buf, buf, sizeof(struct mpp_buf)); + + /* ctrl */ + fill.ctrl.flags = 0; + fill.ctrl.alpha_en = blend; + + ret = mpp_ge_fillrect(g_ge, &fill); + if (ret < 0) { + LV_LOG_WARN("fillrect1 fail\n"); + return LV_RES_INV; + } + + ret = mpp_ge_emit(g_ge); + if (ret < 0) { + LV_LOG_WARN("emit fail\n"); + return LV_RES_INV; + } + + ret = mpp_ge_sync(g_ge); + if (ret < 0) { + LV_LOG_WARN("sync fail\n"); + return LV_RES_INV; + } + + return LV_RES_OK; +} + +#else + +//TODO: support V8 +void *lv_mpp_image_alloc(int width, int height, enum mpp_pixel_format fmt) +{ + return NULL; +} + +#endif diff --git a/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/canvas_image.h b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/canvas_image.h new file mode 100644 index 000000000..b9a1b6cf6 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/canvas_image.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Ning Fang + */ + +#ifndef CANVAS_IMAGE_H +#define CANVAS_IMAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if LVGL_VERSION_MAJOR == 9 + +#include "lvgl.h" +#include "aic_ui.h" +#include "mpp_ge.h" +#include "lv_mpp_dec.h" + +mpp_decoder_data_t *lv_mpp_image_alloc(int width, int height, enum mpp_pixel_format fmt); + +void lv_mpp_image_flush_cache(mpp_decoder_data_t *image); + +void lv_mpp_image_free(mpp_decoder_data_t *image); + +int lv_ge_fill(struct mpp_buf *buf, enum ge_fillrect_type type, + unsigned int start_color, unsigned int end_color, int blend); + +#endif + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif //CANVAS_IMAGE_H diff --git a/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/v9/lv_aic_canvas.c b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/v9/lv_aic_canvas.c new file mode 100644 index 000000000..a88b51842 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/v9/lv_aic_canvas.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Ning Fang + */ + +#include "lv_aic_canvas.h" + +#include "src/core/lv_refr.h" +#include "src/display/lv_display.h" +#include "src/stdlib/lv_string.h" + +void lv_aic_canvas_init_layer(lv_obj_t *obj, lv_layer_t *layer); + +void lv_aic_canvas_finish_layer(lv_obj_t *canvas, lv_layer_t *layer); + +#define MY_CLASS (&lv_aic_canvas_class) + +static void lv_aic_canvas_constructor(const lv_obj_class_t *class_p, lv_obj_t *obj); +static void lv_aic_canvas_destructor(const lv_obj_class_t *class_p, lv_obj_t *obj); + +const lv_obj_class_t lv_aic_canvas_class = { + .constructor_cb = lv_aic_canvas_constructor, + .destructor_cb = lv_aic_canvas_destructor, + .instance_size = sizeof(lv_aic_canvas_t), + .base_class = &lv_image_class, + .name = "aic_canvas", +}; + +lv_obj_t * lv_aic_canvas_create(lv_obj_t *parent) +{ + LV_LOG_INFO("begin"); + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + return obj; +} + +lv_res_t lv_aic_canvas_alloc_buffer(lv_obj_t *obj, lv_coord_t w, lv_coord_t h) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_color_format_t cf = LV_COLOR_FORMAT_ARGB8888; + enum mpp_pixel_format fmt = MPP_FMT_ARGB_8888; + lv_aic_canvas_t *canvas = (lv_aic_canvas_t *)obj; + + canvas->img_buf= lv_mpp_image_alloc(w, h, fmt); + if (!canvas->img_buf) { + LV_LOG_ERROR("lv_mpp_image_alloc failed"); + return LV_RES_INV; + } + + uint32_t stride = canvas->img_buf->dec_buf.stride[0]; + void *data = (void *)canvas->img_buf->data[0]; + lv_draw_buf_init(&canvas->img_buf->decoded, w, h, cf, stride, data, stride * h); + canvas->draw_buf = &canvas->img_buf->decoded; + + // means aic mpp buffer + canvas->draw_buf->header.flags |= LV_IMAGE_FLAGS_USER8; + + const void *src = lv_image_get_src(obj); + if (src) { + lv_image_cache_drop(src); + } + + lv_image_set_src(obj, canvas->draw_buf); + lv_image_cache_drop(canvas->draw_buf); + + return LV_RES_OK; +} + +void lv_aic_canvas_init_layer(lv_obj_t *obj, lv_layer_t *layer) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_NULL(layer); + lv_aic_canvas_t * canvas = (lv_aic_canvas_t *)obj; + if(canvas->draw_buf == NULL) return; + + lv_image_header_t * header = &canvas->draw_buf->header; + lv_area_t canvas_area = {0, 0, header->w - 1, header->h - 1}; + lv_memzero(layer, sizeof(*layer)); + + layer->draw_buf = canvas->draw_buf; + layer->color_format = header->cf; + layer->buf_area = canvas_area; + layer->_clip_area = canvas_area; +} + +void lv_aic_canvas_finish_layer(lv_obj_t *canvas, lv_layer_t *layer) +{ + while(layer->draw_task_head) { + lv_draw_dispatch_wait_for_request(); + lv_draw_dispatch_layer(lv_obj_get_display(canvas), layer); + } +} + +void lv_aic_canvas_draw_text(lv_obj_t *obj, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, + lv_draw_label_dsc_t *draw_dsc, const char *txt) +{ + lv_aic_canvas_t *canvas = (lv_aic_canvas_t *)obj; + lv_layer_t layer; + lv_aic_canvas_init_layer(obj, &layer); + + lv_area_t coords; + coords.x1 = x; + coords.y1 = y; + coords.x2 = x + max_w - 1; + coords.y2 = canvas->draw_buf->header.h - 1; + + draw_dsc->text = txt; + lv_draw_label(&layer, draw_dsc, &coords); + lv_aic_canvas_finish_layer(obj, &layer); +} + +void lv_aic_canvas_draw_text_to_center(lv_obj_t *obj, lv_draw_label_dsc_t *label_dsc, const char *txt) +{ + lv_aic_canvas_t *canvas = (lv_aic_canvas_t *)obj; + + if (canvas->img_buf) { + lv_ge_fill(&canvas->img_buf->dec_buf, GE_NO_GRADIENT, 0x00000000, 0x00000000, 0); + + lv_point_t txt_size; + lv_txt_get_size(&txt_size, txt, label_dsc->font, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_coord_t x = (canvas->draw_buf->header.w - txt_size.x) / 2; + lv_coord_t y = (canvas->draw_buf->header.h - txt_size.y) / 2; + + lv_aic_canvas_draw_text(obj, x, y, canvas->draw_buf->header.w, label_dsc, txt); + lv_obj_invalidate(obj); + } +} + +static void lv_aic_canvas_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_UNUSED(obj); +} + +static void lv_aic_canvas_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_TRACE_OBJ_CREATE("begin"); + + lv_aic_canvas_t *canvas = (lv_aic_canvas_t *)obj; + if(canvas->draw_buf == NULL) return; + + lv_image_cache_drop(&canvas->draw_buf); + if (canvas->img_buf) + lv_mpp_image_free(canvas->img_buf); +} diff --git a/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/v9/lv_aic_canvas.h b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/v9/lv_aic_canvas.h new file mode 100644 index 000000000..caac81889 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_widgets/aic_canvas/v9/lv_aic_canvas.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Ning Fang + */ + +#ifndef LV_AIC_CANVAS_H +#define LV_AIC_CANVAS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" +#include "../canvas_image.h" + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_aic_canvas_class; + +typedef struct { + lv_image_t img; + lv_draw_buf_t *draw_buf; + mpp_decoder_data_t *img_buf; +} lv_aic_canvas_t; + +lv_obj_t * lv_aic_canvas_create(lv_obj_t *parent); + + +lv_res_t lv_aic_canvas_alloc_buffer(lv_obj_t *obj, lv_coord_t w, lv_coord_t h); + + +void lv_aic_canvas_draw_text(lv_obj_t *obj, lv_coord_t x, lv_coord_t y, lv_coord_t max_w, + lv_draw_label_dsc_t *draw_dsc, const char *txt); + +void lv_aic_canvas_draw_text_to_center(lv_obj_t *obj, lv_draw_label_dsc_t *label_dsc, const char *txt); + + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_AIC_CANVAS_H*/ diff --git a/source/artinchip/lvgl-ui/aic_widgets/aic_player/v9/lv_aic_player.c b/source/artinchip/lvgl-ui/aic_widgets/aic_player/v9/lv_aic_player.c new file mode 100644 index 000000000..24e536167 --- /dev/null +++ b/source/artinchip/lvgl-ui/aic_widgets/aic_player/v9/lv_aic_player.c @@ -0,0 +1,1320 @@ +/* + * Copyright (c) 2023-2025, ArtInChip Technology Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + * + * Authors: Zequan Liang + */ + +#include "lv_aic_player.h" +#include "aic_ui.h" + +#if LV_USE_AIC_SIMULATOR == 0 && LVGL_VERSION_MAJOR == 9 +#include +#include +#include +#include + +#if __RTOS__ +#include "mpp_ge.h" +#include "mpp_fb.h" +#include "mpp_mem.h" +#include "mpp_list.h" +#include "frame_allocator.h" +#else +#include +#include +#include