AW平台的DRAM控制器支持地址线REMAP,可以通过REMAP简化外部不同种类的DRAM的连接。
这个REAMP是固定在芯片里的不能自己修改,在电路原理图可以看到REMAP的引脚。
如图,如果需要挂DDR3内存,需要接DDR3的REAMP,如果需要接DDR2,可以接默认的REMAP
举个其他平台的例子:
这里接的是 LPDDR4,使用LPDDR4的REMAP
这里接的是DDR4,使用DDR4的REMAP
AW平台的DRAM控制器支持地址线REMAP,可以通过REMAP简化外部不同种类的DRAM的连接。
这个REAMP是固定在芯片里的不能自己修改,在电路原理图可以看到REMAP的引脚。
如图,如果需要挂DDR3内存,需要接DDR3的REAMP,如果需要接DDR2,可以接默认的REMAP
举个其他平台的例子:
这里接的是 LPDDR4,使用LPDDR4的REMAP
这里接的是DDR4,使用DDR4的REMAP
@abc16883
下载工具:
AllwinnertechPhoeniSuitRelease20230905.zip
下载驱动:
全志USB烧录驱动20201229
Out of memory 没有内存了,camerademo走的拍摄路径是v4l2不是mpp的vipp路径,需要的内存较大,可以尝试拍摄小分辨率的图片测试
[CAMERA] Resolution size : 1920 * 1088
@huerli 在 T113输出日志,是不是片子坏了啊 中说:
BUG: Bad page map in process S10mdev pte:40cdf59f pmd:41bb1835
主线驱动缺陷导致mdev申请出现NULL pointer。可以尝试使用新内核
[sdc0]
card_ctrl = 0
card_high_speed = 0
card_line = 4
sdc_d1 = port:PA27<2><1><3><default>
sdc_d0 = port:PA26<2><1><3><default>
sdc_clk = port:PA29<2><1><3><default>
sdc_cmd = port:PA25<2><1><3><default>
sdc_d3 = port:PA24<2><1><3><default>
sdc_d2 = port:PA28<2><1><3><default>
[sdc0det_para]
sdc0_det = port:PA23<0><1><3><1>
适配 EVT 的测试镜像:
be810818-4bc0-447f-8705-d5d70abd8813-rtos_freertos_r128s2_evt_uart0_16Mnor.img
jlt35031c是比较少见的小端屏,但是大部分的SPI屏都是大端屏,所以用jlt35031c时,需要修改sys_config.fex里面的配置项lcd_rgb_order为9.
unsigned char color[4] = {0xff,0x0,0xff,0x0};
这个数组决定颜色,颜色顺序是R(红) G(绿) B(蓝) A(亮度)。
所以红色 + 蓝色,应该是紫色
但是这里由于使用的是SPI接口驱动这个屏幕,并不支持lcd_rgb_order的参数配置。所以在屏幕初始化的时候通过写寄存器配置为对应的接口以支持LVGL的正确显示输出。但是测试命令可能会出现反色的情况。
屏参改一下
lcd_driver_name = "default_lcd"
lcd_backlight = 150
lcd_if = 0
lcd_x = 1024
lcd_y = 600
lcd_width = 150
lcd_height = 94
lcd_rb_swap = 0
lcd_dclk_freq = 48
lcd_pwm_used = 1
lcd_pwm_ch = 7
lcd_pwm_freq = 500000
lcd_pwm_pol = 1
lcd_hbp = 160
lcd_ht = 1344
lcd_hspw = 20
lcd_vbp = 20
lcd_vt = 635
lcd_vspw = 3
lcd_lvds_if = 0
lcd_lvds_colordepth = 1
lcd_lvds_mode = 0
lcd_frm = 0
lcd_io_phase = 0x0000
lcd_gamma_en = 0
lcd_bright_curve_en = 0
lcd_cmap_en = 0
感觉是环境配置有问题
试试:
由于屏幕较大首先精简系统内存,关闭DSP核心,并将 RV 核心移到 HSPSRAM 上提高带宽。配置 LV_COLOR_DEPTH 16 提高帧率降低内存占用
patch 如下,增加了新方案r128-devkit-rgb:161ca91b-f759-4108-8bfc-85114394da0c-r128-devkit-rgb.tar.gz
编译打包即可
700ms启动 LVGL:
@casdfxx 这个代码是u-boot提供的,具体问题可以访问 https://lists.denx.de/listinfo/u-boot 寻求帮助。
裸机工程:https://github.com/xboot/xboot/tree/master/src/arch/arm32/mach-v3s
disp init configuration
disp_mode (0:screen0<screen0,fb0>)
screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;5:vdpo)
screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50)
(5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60)
screenx_output_format (for hdmi, 0:RGB 1:yuv444 2:yuv422 3:yuv420)
screenx_output_bits (for hdmi, 0:8bit 1:10bit 2:12bit 2:16bit)
screenx_output_eotf (for hdmi, 0:reserve 4:SDR 16:HDR10 18:HLG)
screenx_output_cs (for hdmi, 0:undefined 257:BT709 260:BT601 263:BT2020)
screenx_output_dvi_hdmi (for hdmi, 0:undefined 1:dvi mode 2:hdmi mode)
screen0_output_range (for hdmi, 0:default 1:full 2:limited)
screen0_output_scan (for hdmi, 0:no data 1:overscan 2:underscan)
screen0_output_aspect_ratio (for hdmi, 8-same as original picture 9-4:3 10-16:9 11-14:9)
fbx format (4:RGB655 5:RGB565 6:RGB556 7:ARGB1555 8:RGBA5551 9:RGB888 10:ARGB8888 12:ARGB4444)
fbx pixel sequence (0:ARGB 1:BGRA 2:ABGR 3:RGBA)
fb0_scaler_mode_enable(scaler mode enable, used FE)
fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0)
lcdx_backlight (lcd init backlight,the range:[0,256],default:197
lcdx_yy (lcd init screen bright/contrast/saturation/hue, value:0~100, default:50/50/57/50)
lcd0_contrast (LCD contrast, 0~100)
lcd0_saturation (LCD saturation, 0~100)
lcd0_hue (LCD hue, 0~100)
framebuffer software rotation setting:
disp_rotation_used: (0:disable; 1:enable,you must set fbX_width to lcd_y,
set fbX_height to lcd_x)
degreeX: (X:screen index; 0:0 degree; 1:90 degree; 3:270 degree)
degreeX_Y: (X:screen index; Y:layer index 0~15; 0:0 degree; 1:90 degree; 3:270 degree)
devX_output_type : config output type in bootGUI framework in UBOOT-2018.
(0:none; 1:lcd; 2:tv; 4:hdmi;)
devX_output_mode : config output resolution(see include/video/sunxi_display2.h) of bootGUI framework in UBOOT-2018
devX_screen_id : config display index of bootGUI framework in UBOOT-2018
devX_do_hpd : whether do hpd detectation or not in UBOOT-2018
chn_cfg_mode : Hardware DE channel allocation config. 0:single display with 6
channel, 1:dual display with 4 channel in main display and 2 channel in second
display, 2:dual display with 3 channel in main display and 3 channel in second
in display.
@xjy_5 tc358743有现成的驱动,可以试一下
sensor0:sensor@0 {
device_type = "sensor0";
compatible = "allwinner,sunxi-sensor";
sensor0_mname = "tc358743_mipi";
sensor0_twi_cci_id = <2>;
sensor0_twi_addr = <0x1f>;
sensor0_mclk_id = <0>;
sensor0_pos = "rear";
sensor0_isp_used = <0>;
sensor0_fmt = <0>;
sensor0_stby_mode = <0>;
sensor0_vflip = <0>;
sensor0_hflip = <0>;
sensor0_cameravdd-supply = <>;
sensor0_cameravdd_vol = <2800000>;
sensor0_iovdd-supply = <®_cldo4>;
sensor0_iovdd_vol = <1800000>;
sensor0_avdd-supply = <>;
sensor0_avdd_vol = <>;
sensor0_dvdd-supply = <>;
sensor0_dvdd_vol = <>;
sensor0_power_en = <>;
sensor0_reset = <&pio PI 8 1 0 1 0>;
sensor0_pwdn = <>;
sensor0_sm_vs = <>;
flash_handle = <&flash0>;
act_handle = <&actuator0>;
device_id = <0>;
status = "okay";
};
sensor0_isp_used 配置了不使用 ISP
sensor0_isp_used = <0>;
@rookie 但是没有unix编译环境,另外cygwin如果之前没有用过坑比linux下还大
创建模型
vip_create_network(&network1);
vip_prepare_network(network1);
vip_create_network(&network2);
vip_prepare_network(network2);
设置模型输入输出
// set network input/output buffer
创建执行组
vip_create_group(max, &group); // max = 2
vip_add_network(group, network1);
vip_add_network(group, network2);
执行
vip_run_group(group, max);
获取输出结果
销毁
vip_finish_network(network1);
vip_finish_network(network2);
vip_destroy_buffer // 销毁input/output
vip_destroy_group(group);
adb 可用时可以直接读取 /dev/by-name/rootfs 将rootfs导出来
adb pull /dev/by-name/rootfs rootfs.img
也可以push到tmp文件夹然后dd写入
adb push rootfs.img /tmp
dd if=/tmp/rootfs.img of=/dev/by-name/rootfs
@uccccc 在 为什么添加Gstreamer后会报这个错误 中说:
@awwwwa 麻烦问一下这个应该怎麼添加,有没有相关的资料亚
内核配置去掉宏:CONFIG_STACKPROTECTOR和CONFIG_STACKPROTECTOR_STRONG。
24993+0 records in
24993+0 records out
6398208 bytes (6.4 MB) copied, 0.0271082 s, 236 MB/s
ERROR: dl file rtos_riscv.fex size too large
ERROR: filename = rtos_riscv.fex
ERROR: dl_file_size = 1579 sector
ERROR: part_size = 1000 sector
ERROR: update mbr file fail
ERROR: update_mbr failed
这是因为 rootfs.fex
太大了,分区容量设置过小。
运行打包命令,找到打包使用发分区表。例如这里使用的是 sys_partition_xip.fex
使用 cconfigs
命令进入目录,找到打包使用的分区表,编辑修改
找到上面报错的行,修改 size
选项,单位是扇区。对于 NOR 方案请对齐。这里我们修改到 7000
重新打包,正常通过
@vincent1 需要修改ffmpeg从vipp获取数据,或者使用mpp推流不使用ffmpeg
mipi摄像头需要走vipp通路,video0只有一个很基础的v4l2设备,上层需要更多的处理,例如isp,3a等,usb走uvc直接对接v4l2提供全部功能
@kkkcxf 在 R329 tina 启动卡死问题 中说:
Waiting for root device /dev/mmcblk0p4...
rootfs配置问题,不是卡死了而是等待挂载ROOTFS
@yofa2008 img不是磁盘镜像文件,是专有的压缩格式,不带分区表。可以用OpenixCard转换为dd可以写入的带分区表的镜像
@mysteryli 可以到 out/v853/xxxx/openwrt/build_dir/target/camerademo/ipkg-install/usr
@xjy_5 在 抓图报错[VIN_ERR]isp0 width error,求给个排查思路 中说:
首先,isp配置错误
[VIN_ERR]isp0 configuration error
isp fifo为空
[VIN_ERR]isp0 internal fifo full
isp 帧错误
[VIN_ERR]isp0 frame lost!
如果不需要使用isp,可以修改sample的源码删除isp处理部分,并且修改设备树禁用isp
@gaowei15537316965 SPI驱动参考 Linux 编写spidev驱动即可
F1C100s 与 STM32 通讯是需要通过外设接口,例如UART,SPI,IIC,SDIO来通讯,你看到的这个 DMA 控制器驱动是给STM32MP用的,不是给F1C100s用的
为什么F1C100s的DMA控制器驱动需要使用 st,stm32-dma 而不是 allwinner,sunxi-dma
@sofia USB 2.0 的速率,大约为 34MByte/s
不正常,进行了如下实验:
刷写时间,5分17秒:
刷写 LOG 如下:
[858]fes begin commit:fccdad5de4-dirty
[861]set pll start
[867]periph0 has been enabled
[870]set pll end
[872][pmu]: bus read error
[874]board init ok
[876]beign to init dram
[878]ZQ value = 0x30
[880]get_pmu_exist() = -1
[883]ddr_efuse_type: 0xa
[885]trefi:7.8ms
[888][AUTO DEBUG] single rank and full DQ!
[892]ddr_efuse_type: 0xa
[894]trefi:7.8ms
[896][AUTO DEBUG] rank 0 row = 13
[899][AUTO DEBUG] rank 0 bank = 8
[903][AUTO DEBUG] rank 0 page size = 2 KB
[907]DRAM BOOT DRIVE INFO: V0.34
[910]DRAM CLK = 792 MHz
[912]DRAM Type = 3 (2:DDR2,3:DDR3)
[915]DRAMC read ODT off.
[918]DRAM ODT value: 0x42.
[920]ddr_efuse_type: 0xa
[923]DRAM SIZE = 128 MB
[927]DRAM simple test OK.
[929]rtc standby flag is 0x0, super standby flag is 0x0
[935]init dram ok
U-Boot 2018.07-00006-g65ea3f1459 (Aug 31 2023 - 08:08:04 +0000) Allwinner Technology
[03.646]CPU: Allwinner Family
[03.649]Model: sun8iw20
[03.651]DRAM: 0 Bytes
[03.654]Relocation Offset is: 04eaf000
[03.683]secure enable bit: 0
[03.690]CPU=1008 MHz,PLL6=600 Mhz,AHB=200 Mhz, APB1=100Mhz MBus=300Mhz
[03.697]gic: normal mode
[03.700]sunxi flash map init
SPI ALL: ready
[03.745]line:703 init_clocks
[03.765]init_clocks:finish
[03.767]flash init start
[03.769]workmode = 16,storage type = 0
try card 2
set card number 2
get card number 2
[03.777][mmc]: mmc driver ver uboot2018:2023-07-4 16:18:00
[03.823][mmc]: Is not Boot mode!
[03.826][mmc]: SUNXI SDMMC Controller Version:0x50310
[03.838][mmc]: ************Try SD card 2************
[03.843][mmc]: mmc 2 cmd timeout 100 status 100
[03.847][mmc]: smc 2 err, cmd 8, RTO
[03.851][mmc]: mmc 2 close bus gating and reset
[03.856][mmc]: mmc 2 cmd timeout 100 status 100
[03.860][mmc]: smc 2 err, cmd 55, RTO
[03.863][mmc]: mmc 2 close bus gating and reset
[03.868][mmc]: ************Try MMC card 2************
[03.890][mmc]: mmc 2 cmd timeout 100 status 100
[03.894][mmc]: smc 2 err, cmd 8, RTO
[03.898][mmc]: mmc 2 close bus gating and reset
[03.903][mmc]: mmc 2 cmd timeout 100 status 100
[03.907][mmc]: smc 2 err, cmd 55, RTO
[03.910][mmc]: mmc 2 close bus gating and reset
[03.927][mmc]: gen_tuning_blk_bus8: total blk 10
[03.933][mmc]: gen_tuning_blk_bus4: total blk 6
[03.938][mmc]: Using 4 bit tuning now
[03.941][mmc]: write_tuning_try_freq: write ok
[03.947][mmc]: Pattern compare ok
[03.950][mmc]: Write tuning pattern ok
[03.954][mmc]: ================== HSSDR52_SDR25...
[03.958][mmc]: skip freq 400000
[03.961][mmc]: skip freq 25000000
[03.964][mmc]: freq: 2-50000000-64-4
[05.493][mmc]: [0-63|64]
[05.495][mmc]: ================== HSDDR52_DDR50...
[05.499][mmc]: skip freq 400000
[05.502][mmc]: freq: 1-25000000-64-4
[06.658][mmc]: freq: 2-50000000-64-4
[07.766][mmc]: [0-48|49]
[07.768][mmc]: [0-48|49]
[07.771][mmc]: DS26/SDR12: 0xffffffff 0xffffffff
[07.775][mmc]: HSSDR52/SDR25: 0xff20ffff 0xffffffff
[07.780][mmc]: HSDDR52/DDR50: 0xff1818ff 0xffffffff
[07.784][mmc]: HS200/SDR104: 0xffffffff 0xffffffff
[07.789][mmc]: HS400: 0xffffffff 0xffffffff
[07.793][mmc]: HS400: 0xffffffff 0xffffffff
[07.797][mmc]: Best spd md: 2-HSDDR52/DDR50, freq: 2-50000000, Bus width: 4
[07.810]Loading Environment from SUNXI_FLASH... OK
[07.821]try to burn key
[07.826]out of usb burn from boot: not boot mode
Hit any key to stop autoboot: 0
sunxi work mode=0x10
run usb efex
delay time 2500
weak:otg_phy_config
usb init ok
set address 0xf
set address 0xf ok
SUNXI_EFEX_ERASE_TAG
erase_flag = 0x12
origin_erase_flag = 0x1
FEX_CMD_fes_verify_status
FEX_CMD_fes_verify last err=0
the 0 mbr table is ok
the 1 mbr table is ok
the 2 mbr table is ok
the 3 mbr table is ok
*************MBR DUMP***************
total mbr part 8
part[0] name :boot-resource
part[0] classname :DISK
part[0] addrlo :0x1f8
part[0] lenlo :0x1f8
part[0] user_type :32768
part[0] keydata :0
part[0] ro :0
part[1] name :env
part[1] classname :DISK
part[1] addrlo :0x3f0
part[1] lenlo :0x1f8
part[1] user_type :32768
part[1] keydata :0
part[1] ro :0
part[2] name :env-redund
part[2] classname :DISK
part[2] addrlo :0x5e8
part[2] lenlo :0x1f8
part[2] user_type :32768
part[2] keydata :0
part[2] ro :0
part[3] name :boot
part[3] classname :DISK
part[3] addrlo :0x7e0
part[3] lenlo :0x4ec0
part[3] user_type :32768
part[3] keydata :0
part[3] ro :0
part[4] name :rootfs
part[4] classname :DISK
part[4] addrlo :0x56a0
part[4] lenlo :0x2329a0
part[4] user_type :32768
part[4] keydata :0
part[4] ro :0
part[5] name :private
part[5] classname :DISK
part[5] addrlo :0x238040
part[5] lenlo :0x2760
part[5] user_type :32768
part[5] keydata :0
part[5] ro :0
part[6] name :recovery
part[6] classname :DISK
part[6] addrlo :0x23a7a0
part[6] lenlo :0x5a90
part[6] user_type :32768
part[6] keydata :0
part[6] ro :0
part[7] name :UDISK
part[7] classname :DISK
part[7] addrlo :0x240230
part[7] lenlo :0x0
part[7] user_type :0
part[7] keydata :0
part[7] ro :0
total part: 9
mbr 0, 1f8, 8000
boot-resource 1, 1f8, 8000
env 2, 1f8, 8000
env-redund 3, 1f8, 8000
boot 4, 4ec0, 8000
rootfs 5, 2329a0, 8000
private 6, 2760, 8000
recovery 7, 5a90, 8000
UDISK 8, 0, 0
[10.886]erase all part start
need erase flash: 18
[10.893][mmc]: erase from: 0, to: 15269887, cnt: 15269888, erase_group: 1024
[10.971][mmc]: sunxi_mmc_do_send_cmd_common: cmd 38 wait rsp busy 0x46 ms
[10.977]read item0 copy0
[11.016]Item0 (Map) magic is bad
[11.019]the secure storage item0 copy0 magic is bad
[11.060]Item0 (Map) magic is bad
[11.063]the secure storage item0 copy1 magic is bad
[11.068]Item0 (Map) magic is bad
[11.071]the secure storage map is empty
[11.147]erase secure storage: 0 ok
SUNXI_EFEX_MBR_TAG
mbr size = 0x10000
write primary GPT success
write Backup GPT success
[11.163]update partition map
FEX_CMD_fes_verify_status
FEX_CMD_fes_verify last err=0
******Has init
FEX_CMD_fes_verify_value, start 0x1f8, size high 0x0:low 0x14000
FEX_CMD_fes_verify_value 0xe6f75b5c
FEX_CMD_fes_verify_value, start 0x3f0, size high 0x0:low 0x20000
FEX_CMD_fes_verify_value 0xa367d787
FEX_CMD_fes_verify_value, start 0x5e8, size high 0x0:low 0x20000
FEX_CMD_fes_verify_value 0xa367d787
FEX_CMD_fes_verify_value, start 0x7e0, size high 0x0:low 0x429800
FEX_CMD_fes_verify_value 0x97662167
FEX_CMD_fes_verify_value, start 0x56a0, size high 0x0:low 0x43460000
FEX_CMD_fes_verify_value 0x3fee63cb
bootfile_mode=4
SUNXI_EFEX_BOOT1_TAG
boot1 size = 0x15c000, max size = 0x200000
uboot size = 0x15c000
storage type = 2
FEX_CMD_fes_verify_status
FEX_CMD_fes_verify last err=0
bootfile_mode=4
SUNXI_EFEX_BOOT0_TAG
boot0 size = 0xa000
[327.990][mmc]: write mmc 2 info ok
dram para[0] = 318
dram para[1] = 3
dram para[2] = 7b7bfb
dram para[3] = 0
dram para[4] = 10d2
dram para[5] = 800000
dram para[6] = 1c70
dram para[7] = 42
dram para[8] = 18
dram para[9] = 0
dram para[10] = 4a2195
dram para[11] = 2423190
dram para[12] = 8b061
dram para[13] = b4787896
dram para[14] = 0
dram para[15] = 48484848
dram para[16] = 48
dram para[17] = 1620121e
dram para[18] = 0
dram para[19] = 0
dram para[20] = 0
dram para[21] = 340000
dram para[22] = 46
dram para[23] = b4006103
dram para[24] = 0
dram para[25] = 0
dram para[26] = 0
dram para[27] = 0
dram para[28] = 0
dram para[29] = 0
dram para[30] = 0
dram para[31] = 0
storage type = 2
FEX_CMD_fes_verify_status
FEX_CMD_fes_verify last err=0
sunxi_efex_next_action=2
exit usb
next work 2
[28]HELLO! BOOT0 is starting!
[30]BOOT0 commit : fccdad5de4-dirty
[34]set pll start
[40]periph0 has been enabled
[43]set pll end
[44][pmu]: bus read error
[47]board init ok
[49]enable_jtag
[50]ZQ value = 0x2f
[52]get_pmu_exist() = -1
[54]DRAM BOOT DRIVE INFO: V0.34
[57]DRAM CLK = 792 MHz
[60]DRAM Type = 3 (2:DDR2,3:DDR3)
[63]DRAMC read ODT off.
[65]DRAM ODT value: 0x42.
[68]ddr_efuse_type: 0xa
[71]DRAM SIZE = 128 MB
[77]DRAM simple test OK.
[79]rtc standby flag is 0x0, super standby flag is 0x0
[85]dram size =128
[87]card no is 2
[89]sdcard 2 line count 4
[91][mmc]: mmc driver ver 2021-05-21 14:47
[100][mmc]: Wrong media type 0x0, but host sdc2, try mmc first
[106][mmc]: ***Try MMC card 2***
[130][mmc]: RMCA OK!
[132][mmc]: mmc 2 bias 0
[136][mmc]: MMC 5.1
[138][mmc]: HSSDR52/SDR25 4 bit
[141][mmc]: 50000000 Hz
[143][mmc]: 7456 MB
[145][mmc]: ***SD/MMC 2 init OK!!!***
[243]Loading boot-pkg Succeed(index=0).
[247]Entry_name = u-boot
[254]Entry_name = optee
[258]Entry_name = dtb
[261]tunning data addr:0x430003e8
[264]Jump to second Boot.
M/TC: OP-TEE version: 8b49ce62-dirty (gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05)) #1 Fri Aug 12 08:24:15 UTC 2022 arm
U-Boot 2018.07-00006-g65ea3f1459 (Aug 31 2023 - 08:08:04 +0000) Allwinner Technology
[00.316]CPU: Allwinner Family
[00.319]Model: sun8iw20
[00.321]DRAM: 128 MiB
[00.325]Relocation Offset is: ffeaf000
[00.354]secure enable bit: 0
E/TC:0 fdt_getprop_u32:343 prop trace_level not found
[00.367]CPU=1008 MHz,PLL6=600 Mhz,AHB=200 Mhz, APB1=100Mhz MBus=300Mhz
[00.374]gic: sec monitor mode
SPI ALL: ready
[00.379]line:703 init_clocks
[00.382]flash init start
[00.384]workmode = 0,storage type = 2
[00.387][mmc]: mmc driver ver uboot2018:2023-07-4 16:18:00
[00.394][mmc]: SUNXI SDMMC Controller Version:0x50310
[00.418][mmc]: Best spd md: 2-HSDDR52/DDR50, freq: 2-50000000, Bus width: 4
[00.424]sunxi flash init ok
[00.427]drv_disp_init
partno erro : can't find partition bootloader
** Unable to read file lcd_compatible_index.txt **
[00.447]disp_fat_load for lcd config failed
[00.474]boot_hdmi20: [info] hdmi_init start
[00.479]boot_hdmi20: [info] hdmi use aw phy!
[00.483]boot_hdmi20: [info] hdmi_init finish
[00.487]drv_disp_init finish
[00.492]Loading Environment from SUNXI_FLASH... OK
[00.505]boot_gui_init:start
partno erro : can't find partition Reserve0
bad fb1_cfg[w=0,h=0,bpp=32,format=0]
[00.520]boot_gui_init:finish
partno erro : can't find partition bootloader
[00.527]bmp_name=bootlogo.bmp size 38454
[00.536]Item0 (Map) magic is bad
[00.539]the secure storage item0 copy0 magic is bad
[00.547]Item0 (Map) magic is bad
[00.549]the secure storage item0 copy1 magic is bad
[00.554]Item0 (Map) magic is bad
[00.557]usb burn from boot
delay time 0
weak:otg_phy_config
[00.568]usb prepare ok
[00.698]LCD open finish
[00.775]usb sof ok
[00.776]usb probe ok
[00.778]usb setup ok
set address 0x10
set address 0x10 ok
try to update
[01.183]do_burn_from_boot usb : have no handshake
List file under ULI/factory
** Unrecognized filesystem type **
root_partition is rootfs
set root to /dev/mmcblk0p5
[01.199]update part info
[01.202]update bootcmd
[01.205]change working_fdt 0x40e6ee68 to 0x40e4ee68
[01.210][mmc]: can't find node "sunxi-mmc2" try "mmc"
[01.215][mmc]: no mmc-hs400-1_8v!
[01.218][mmc]: delete mmc-hs200-1_8v from dtb
[01.222][mmc]: get max-frequency ok 50000000 Hz
[01.227][mmc]: get sunxi-mmc2 string failed
[01.231]The storage not support sample function
partno erro : can't find partition bootloader
** Unable to read file lcd_compatible_index.txt **
[01.257]disp_fat_load for lcd config failed
partno erro : can't find partition bootloader
writing lcd_compatible_index.txt
16 bytes written
save lcd compatible disp0 index 0 to flash
partno erro : can't find partition bootloader
[01.281]update dts
Hit any key to stop autoboot: 0
input addr exceed dram scope
[01.385]no vendor_boot partition is found
Android's image name: sun8i_arm
[01.480]Starting kernel ...
[01.483][mmc]: mmc exit start
[01.500][mmc]: mmc 2 exit ok
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.4.61 (kunyao@AwExdroid89) (arm-linux-gnueabi-gcc (Linaro GCC 5.3-2016.05) 5.3.1 20160412, GNU ld (Linaro_Binutils-2016.05) 2.25.0 Linaro 2016_02) #1 SMP PREEMPT Wed Sep 6 10:23:35 CST 2023
[ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
[ 0.000000] CPU: div instructions available: patching division code
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] OF: fdt: Machine model: sun8iw20
[ 0.000000] Memory policy: Data cache writealloc
[ 0.000000] Reserved memory: created DMA memory pool at 0x42200000, size 0 MiB
[ 0.000000] OF: reserved mem: initialized node vdev0buffer@42200000, compatible id shared-dma-pool
[ 0.000000] Reserved memory: created DMA memory pool at 0x42244000, size 0 MiB
[ 0.000000] OF: reserved mem: initialized node dsp0_rpbuf@42244000, compatible id shared-dma-pool
[ 0.000000] cma: Reserved 4 MiB at 0x47c00000
[ 0.000000] On node 0 totalpages: 32420
[ 0.000000] Normal zone: 256 pages used for memmap
[ 0.000000] Normal zone: 0 pages reserved
[ 0.000000] Normal zone: 32420 pages, LIFO batch:7
[ 0.000000] psci: probing for conduit method from DT.
[ 0.000000] psci: PSCIv1.0 detected in firmware.
[ 0.000000] psci: Using standard PSCI v0.2 function IDs
[ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
[ 0.000000] psci: SMC Calling Convention v1.0
[ 0.000000] percpu: Embedded 15 pages/cpu s30784 r8192 d22464 u61440
[ 0.000000] pcpu-alloc: s30784 r8192 d22464 u61440 alloc=15*4096
[ 0.000000] pcpu-alloc: [0] 0 [0] 1
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 32164
[ 0.000000] Kernel command line: earlyprintk=sunxi-uart,0x02500000 clk_ignore_unused initcall_debug=0 console=ttyS0,115200 loglevel=8 root=/dev/mmcblk0p5 init=/init rdinit=/rdinit partitions=boot-resource@mmcblk0p1:env@mmcblk0p2:env-redund@mmcblk0p3:boot@mmcblk0p4:rootfs@mmcblk0p5:private@mmcblk0p6:recovery@mmcblk0p7:UDISK@mmcblk0p8 cma=4M snum= mac_addr= wifi_mac= bt_mac= specialstr= gpt=1 androidboot.mode=normal androidboot.hardware=sun8iw20p1 boot_type=2 androidboot.boot_type=2 gpt=1 uboot_message=2018.07-00006-g65ea3f1459(08/31/2023-08:08:04) mbr_offset=1032192 disp_reserve=1536000,0x40efb000 androidboot.dramfreq=792 androidboot.dramsize=128 mtdparts=<NULL>
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 103624K/129680K available (6144K kernel code, 303K rwdata, 2200K rodata, 1024K init, 1166K bss, 21960K reserved, 4096K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[ 0.000000] rcu: Preemptible hierarchical RCU implementation.
[ 0.000000] Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[ 0.000000] random: get_random_bytes called from start_kernel+0x25c/0x3dc with crng_init=0
[ 0.000000] arch_timer: cp15 timer(s) running at 24.00MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns
[ 0.000006] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns
[ 0.000017] Switching to timer-based delay loop, resolution 41ns
[ 0.000190] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[ 0.000836] Console: colour dummy device 80x30
[ 0.000875] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
[ 0.000887] pid_max: default: 32768 minimum: 301
[ 0.001015] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.001027] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[ 0.001620] CPU: Testing write buffer coherency: ok
[ 0.001944] /cpus/cpu@0 missing clock-frequency property
[ 0.001963] /cpus/cpu@1 missing clock-frequency property
[ 0.001974] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[ 0.002490] Setting up static identity map for 0x40100000 - 0x40100060
[ 0.002593] rcu: Hierarchical SRCU implementation.
[ 0.003017] smp: Bringing up secondary CPUs ...
[ 0.004175] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[ 0.004303] smp: Brought up 1 node, 2 CPUs
[ 0.004317] SMP: Total of 2 processors activated (96.00 BogoMIPS).
[ 0.004323] CPU: All CPU(s) started in SVC mode.
[ 0.004775] devtmpfs: initialized
[ 0.016429] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
[ 0.017002] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.017028] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
[ 0.017372] pinctrl core: initialized pinctrl subsystem
[ 0.018649] NET: Registered protocol family 16
[ 0.020217] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.058181] rtc_ccu: sunxi ccu init OK
[ 0.060672] ccu: sunxi ccu init OK
[ 0.061209] r_ccu: sunxi ccu init OK
[ 0.092454] sun6i-dma 3002000.dma-controller: sunxi dma probed
[ 0.097123] iommu: Default domain type: Translated
[ 0.097336] sunxi iommu: irq = 24
[ 0.098409] SCSI subsystem initialized
[ 0.098800] usbcore: registered new interface driver usbfs
[ 0.098879] usbcore: registered new interface driver hub
[ 0.098996] usbcore: registered new device driver usb
[ 0.099231] videodev: Linux video capture interface: v2.00
[ 0.101776] Advanced Linux Sound Architecture Driver Initialized.
[ 0.102463] Bluetooth: Core ver 2.22
[ 0.102547] NET: Registered protocol family 31
[ 0.102556] Bluetooth: HCI device and connection manager initialized
下略
考虑可能的问题:
@sofia 我记得需要在小机运行一个uvc的程序,因为vin框架和isp通路与nxp的不一样,nxp是软件isp这个是硬件isp,可能有些地方需要适配
这个UVC需要本地运行一个UVC的服务端调用摄像头通路才可建立,否则不会上报为UVC设备而是复合设备
/*
*usb_port_type: usb mode. 0-device, 1-host, 2-otg.
*usb_detect_type: usb hotplug detect mode. 0-none, 1-vbus/id detect, 2-id/dpdm detect.
*usb_detect_mode: 0-thread scan, 1-id gpio interrupt.
*usb_id_gpio: gpio for id detect.
*usb_det_vbus_gpio: gpio for id detect. gpio or "axp_ctrl";
*usb_wakeup_suspend:0-SUPER_STANDBY, 1-USB_STANDBY.
*/
usb_port_type改成1就可以
参照opencv的编写使用cmake的makefile
include $(TOPDIR)/rules.mk
PKG_NAME:=opencv
PKG_VERSION:=4.1.1
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/opencv/opencv
PKG_SOURCE_VERSION:=$(PKG_VERSION)
PKG_MIRROR_HASH:=c8587820421d2f22acdafe4712d068ae490897dc445bdb4aa128ecaa8e65d3a1
PKG_MAINTAINER:=
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
CMAKE_INSTALL:=1
CMAKE_BINARY_SUBDIR:=build
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/opencv/Default/description
OpenCV (Open Source Computer Vision Library) is an open source computer
vision and machine learning software library. OpenCV was built to provide
a common infrastructure for computer vision applications and to accelerate
the use of machine perception in the commercial products. Being a
BSD-licensed product, OpenCV makes it easy for businesses to utilize
and modify the code.
endef
define Package/opencv
SECTION:=libs
CATEGORY:=Libraries
TITLE:=OpenCV
URL:=https://opencv.org/
DEPENDS:=+libpthread +librt +libatomic +libstdcpp +zlib +libjpeg +python3 +python3-numpy
endef
CMAKE_OPTIONS += \
-DBUILD_opencv_gpu:BOOL=OFF \
-DWITH_1394:BOOL=OFF -DBUILD_opencv_stitching:BOOL=OFF \
-DBUILD_opencv_superres:BOOL=OFF -DBUILD_opencv_ts:BOOL=OFF \
-DBUILD_opencv_highgui:BOOL=ON \
-DBUILD_opencv_videostab:BOOL=OFF \
-DWITH_FFMPEG:BOOL=OFF \
-DWITH_GSTREAMER:BOOL=OFF \
-DWITH_LIBV4L:BOOL=ON \
-DWITH_PNG:BOOL=OFF \
-DWITH_GTK:BOOL=OFF \
-DWITH_TIFF:BOOL=OFF \
-DCMAKE_VERBOSE:BOOL=OFF \
-DENABLE_PRECOMPILED_HEADERS=OFF \
-DPYTHON3_INCLUDE_PATH=$(STAGING_DIR)/usr/include/python3.9 \
-DPYTHON3_LIBRARIES=$(STAGING_DIR)/usr/lib/libpython3.9.so \
-DPYTHON3_NUMPY_INCLUDE_DIRS=$(TARGET_ROOTFS_DIR)/pypi/numpy-1.20.1/ipkg-install/usr/lib/python3.9/site-packages/numpy/core/include \
-DBUILD_OPENCV_PYTHON3:BOOL=ON
TARGET_LDFLAGS += -latomic
define Package/opencv/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,opencv))
tina SDK可以编译buildroot吗?
这里需要修改配置fstab和勾选对应格式化包,不过我感觉你这应该不是tina,没有包括扩展分区
设备树的disp节点
fbx format (4:RGB655 5:RGB565 6:RGB556 7:ARGB1555 8:RGBA5551 9:RGB888 10:ARGB8888 12:ARGB4444)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <ctype.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include <tplayer.h>
//#include <power_manager_client.h>
#define TOTAL_VIDEO_AUDIO_NUM 100
#define MAX_FILE_NAME_LEN 256
#define FILE_TYPE_NUM 29
#define FILE_TYPE_LEN 10
#define VIDEO_TYPE_NUM 11
#define VIDEO_TYPE_LEN 10
#define USE_REPEAT_RESET_MODE 1
#define HOLD_LAST_PICTURE 1
#define LOOP_PLAY_FLAG 1
typedef struct DemoPlayerContext
{
TPlayer* mTPlayer;
int mSeekable;
int mError;
int mVideoFrameNum;
bool mPreparedFlag;
bool mLoopFlag;
bool mSetLoop;
bool mComplete;
char mUrl[512];
MediaInfo* mMediaInfo;
char mVideoAudioList[TOTAL_VIDEO_AUDIO_NUM][MAX_FILE_NAME_LEN];
int mCurPlayIndex;
int mRealFileNum;
sem_t mPreparedSem;
}DemoPlayerContext;
//* define commands for user control.
typedef struct Command
{
const char* strCommand;
int nCommandId;
const char* strHelpMsg;
}Command;
#define COMMAND_HELP 0x1 //* show help message.
#define COMMAND_QUIT 0x2 //* quit this program.
#define COMMAND_SET_SOURCE 0x101 //* set url of media file.
#define COMMAND_PREPARE 0x102 //* prepare the media file.
#define COMMAND_PLAY 0x103 //* start playback.
#define COMMAND_PAUSE 0x104 //* pause the playback.
#define COMMAND_STOP 0x105 //* stop the playback.
#define COMMAND_SEEKTO 0x106 //* seek to posion, in unit of second.
#define COMMAND_RESET 0x107 //* reset the player
#define COMMAND_SHOW_MEDIAINFO 0x108 //* show media information.
#define COMMAND_SHOW_DURATION 0x109 //* show media duration, in unit of second.
#define COMMAND_SHOW_POSITION 0x110 //* show current play position, in unit of second.
#define COMMAND_SWITCH_AUDIO 0x111 //* switch autio track.
#define COMMAND_PLAY_URL 0x112 //set url and prepare and play
#define COMMAND_SET_VOLUME 0x113 //set the software volume
#define COMMAND_GET_VOLUME 0x114 //get the software volume
#define COMMAND_SET_LOOP 0x115 //set loop play flag,1 means loop play,0 means not loop play
#define COMMAND_SET_SCALEDOWN 0x116 //set video scale down ratio,valid value is:2,4,8 . 2 means 1/2 scaledown,4 means 1/4 scaledown,8 means 1/8 scaledown
#define COMMAND_FAST_FORWARD 0x117 //fast forward,valid value is:2,4,8,16, 2 means 2 times fast forward,4 means 4 times fast forward,8 means 8 times fast forward,16 means 16 times fast forward
#define COMMAND_FAST_BACKWARD 0x118 //fast backward,valid value is:2,4,8,16,2 means 2 times fast backward,4 means 4 times fast backward,8 means 8 times fast backward,16 means 16 times fast backward
#define COMMAND_SET_SRC_RECT 0x119 //set display source crop rect
#define COMMAND_SET_OUTPUT_RECT 0x120 //set display output display rect
#define COMMAND_GET_DISP_FRAMERATE 0x121 //* show the real display framerate
#define CEDARX_UNUSE(param) (void)param
static const Command commands[] =
{
{"help", COMMAND_HELP, "show this help message."},
{"quit", COMMAND_QUIT, "quit this program."},
{"set url", COMMAND_SET_SOURCE, "set url of the media, for example, set url: ~/testfile.mkv."},
{"prepare", COMMAND_PREPARE, "prepare the media."},
{"play", COMMAND_PLAY, "start playback."},
{"pause", COMMAND_PAUSE, "pause the playback."},
{"stop", COMMAND_STOP, "stop the playback."},
{"seek to", COMMAND_SEEKTO, "seek to specific position to play, position is in unit of second, for example, seek to: 100."},
{"reset", COMMAND_RESET, "reset the player."},
{"show media info", COMMAND_SHOW_MEDIAINFO, "show media information of the media file."},
{"show duration", COMMAND_SHOW_DURATION, "show duration of the media file."},
{"show position", COMMAND_SHOW_POSITION, "show current play position, position is in unit of second."},
{"switch audio", COMMAND_SWITCH_AUDIO, "switch audio to a specific track, for example, switch audio: 2, track is start counting from 0."},
{"play url", COMMAND_PLAY_URL, "set url and prepare and play url,for example:play url:/mnt/UDISK/test.mp3"},
{"set volume", COMMAND_SET_VOLUME, "set the software volume,the range is 0-40,for example:set volume:30"},
{"get volume", COMMAND_GET_VOLUME, "get the software volume"},
{"set loop", COMMAND_SET_LOOP, "set the loop play flag,1 means loop play,0 means not loop play"},
{"set scaledown", COMMAND_SET_SCALEDOWN, "set video scale down ratio,valid value is:2,4,8 . 2 means 1/2 scaledown,4 means 1/4 scaledown,8 means 1/8 scaledown"},
{"fast forward", COMMAND_FAST_FORWARD, "fast forward,valid value is:2,4,8,16, 2 means 2 times fast forward,4 means 4 times fast forward,8 means 8 times fast forward,16 means 16 times fast forward"},
{"fast backward", COMMAND_FAST_BACKWARD, "fast backward,valid value is:2,4,8,16,2 means 2 times fast backward,4 means 4 times fast backward,8 means 8 times fast backward,16 means 16 times fast backward"},
{"set src_rect", COMMAND_SET_SRC_RECT, "set display source crop rect"},
{"set dst_rect", COMMAND_SET_OUTPUT_RECT, "set display output rect"},
{"get display framerate", COMMAND_GET_DISP_FRAMERATE, "show the real display framerate."},
{NULL, 0, NULL}
};
DemoPlayerContext demoPlayer;
DemoPlayerContext gDemoPlayers[5];
int isDir = 0;
int gScreenWidth = 0;
int gScreenHeight = 0;
int gPlayerNum = 0;
/* Signal handler */
static void terminate(int sig_no)
{
printf("Got signal %d, exiting ...\n", sig_no);
if(demoPlayer.mTPlayer != NULL)
{
TPlayerDestroy(demoPlayer.mTPlayer);
demoPlayer.mTPlayer = NULL;
printf("TPlayerDestroy() successfully\n");
}
sem_destroy(&demoPlayer.mPreparedSem);
int i=0;
for(i = gPlayerNum-1;i >= 0;i--){
if(gDemoPlayers[i].mTPlayer != NULL)
{
TPlayerDestroy(gDemoPlayers[i].mTPlayer);
gDemoPlayers[i].mTPlayer = NULL;
printf("TPlayerDestroy(%d) successfully\n",i);
}
}
printf("destroy tplayer \n");
printf("tplaydemo exit\n");
exit(1);
}
static void install_sig_handler(void)
{
signal(SIGBUS, terminate);
signal(SIGFPE, terminate);
signal(SIGHUP, terminate);
signal(SIGILL, terminate);
signal(SIGINT, terminate);
signal(SIGIOT, terminate);
signal(SIGPIPE, terminate);
signal(SIGQUIT, terminate);
signal(SIGSEGV, terminate);
signal(SIGSYS, terminate);
signal(SIGTERM, terminate);
signal(SIGTRAP, terminate);
signal(SIGUSR1, terminate);
signal(SIGUSR2, terminate);
}
static void showHelp(void)
{
int i;
printf("\n");
printf("******************************************************************************************\n");
printf("* This is a simple media player, when it is started, you can input commands to tell\n");
printf("* what you want it to do.\n");
printf("* Usage: \n");
printf("* # ./tplayerdemo\n");
printf("* # set url:/mnt/UDISK/test.mp3\n");
printf("* # prepare\n");
printf("* # show media info\n");
printf("* # play\n");
printf("* # pause\n");
printf("* # stop\n");
printf("* # reset\n");
printf("* # seek to:100\n");
printf("* # play url:/mnt/UDISK/test.mp3\n");
printf("* # set volume:30\n");
printf("* # get volume\n");
printf("* # set loop:1 \n");
printf("* # set scaledown:2 \n");
printf("* # fast forward:2 \n");
printf("* # fast backward:2 \n");
printf("* # switch audio:1 \n");
printf("* #get display framerate \n");
printf("*\n");
printf("* Command and it's param is seperated by a colon, param is optional, as below:\n");
printf("* Command[: Param]\n");
printf("* #notice:we can play a list use the following command,for example the video or audio file puts in /mnt/UDISK/ directory \n");
printf("* #tplayerdemo /mnt/UDISK/ \n");
printf("* #notice:we can play one file use the following command,for example the video or audio file puts in /mnt/UDISK/ directory \n");
printf("* #tplayerdemo /mnt/UDISK/test.mp4 \n");
printf("* #notice:we can play two file use the following command,for example the video or audio file puts in /mnt/UDISK/ directory \n");
printf("* #tplayerdemo /mnt/UDISK/test1.mp4 /mnt/UDISK/test2.mp4\n");
printf("*\n");
printf("* here are the commands supported:\n");
for(i=0; ; i++)
{
if(commands[i].strCommand == NULL)
break;
printf("* %s:\n", commands[i].strCommand);
printf("*\t\t%s\n", commands[i].strHelpMsg);
}
printf("*\n");
printf("******************************************************************************************\n");
}
static int readCommand(char* strCommandLine, int nMaxLineSize)
{
int nMaxFds;
fd_set readFdSet;
int result;
char* p;
unsigned int nReadBytes;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
fflush(stdout);
nMaxFds = 0;
FD_ZERO(&readFdSet);
FD_SET(STDIN_FILENO, &readFdSet);
result = select(nMaxFds+1, &readFdSet, NULL, NULL, &tv);
if(result > 0)
{
printf("\ntplayerdemo# ");
if(FD_ISSET(STDIN_FILENO, &readFdSet))
{
nReadBytes = read(STDIN_FILENO, &strCommandLine[0], nMaxLineSize);
if(nReadBytes > 0)
{
p = strCommandLine;
while(*p != 0)
{
if(*p == 0xa)
{
*p = 0;
break;
}
p++;
}
}
return 0;
}
}
return -1;
}
static void formatString(char* strIn)
{
char* ptrIn;
char* ptrOut;
int len;
int i;
if(strIn == NULL || (len=strlen(strIn)) == 0)
return;
ptrIn = strIn;
ptrOut = strIn;
i = 0;
while(*ptrIn != '\0')
{
//* skip the beginning space or multiple space between words.
if(*ptrIn != ' ' || (i!=0 && *(ptrOut-1)!=' '))
{
*ptrOut++ = *ptrIn++;
i++;
}
else
ptrIn++;
}
//* skip the space at the tail.
if(i==0 || *(ptrOut-1) != ' ')
*ptrOut = '\0';
else
*(ptrOut-1) = '\0';
return;
}
//* return command id,
static int parseCommandLine(char* strCommandLine, unsigned long* pParam)
{
char* strCommand;
char* strParam;
int i;
int nCommandId;
char colon = ':';
if(strCommandLine == NULL || strlen(strCommandLine) == 0)
{
return -1;
}
strCommand = strCommandLine;
strParam = strchr(strCommandLine, colon);
if(strParam != NULL)
{
*strParam = '\0';
strParam++;
}
formatString(strCommand);
formatString(strParam);
nCommandId = -1;
for(i=0; commands[i].strCommand != NULL; i++)
{
if(strcmp(commands[i].strCommand, strCommand) == 0)
{
nCommandId = commands[i].nCommandId;
break;
}
}
if(commands[i].strCommand == NULL)
return -1;
switch(nCommandId)
{
case COMMAND_SET_SOURCE:
if(strParam != NULL && strlen(strParam) > 0)
*pParam = (uintptr_t)strParam; //* pointer to the url.
else
{
printf("no url specified.\n");
nCommandId = -1;
}
break;
case COMMAND_SEEKTO:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10); //* seek time in unit of second.
if(errno == EINVAL || errno == ERANGE)
{
printf("seek time is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("no seek time is specified.\n");
nCommandId = -1;
}
break;
case COMMAND_SWITCH_AUDIO:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10); //* audio stream index start counting from 0.
if(errno == EINVAL || errno == ERANGE)
{
printf("audio stream index is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("no audio stream index is specified.\n");
nCommandId = -1;
}
break;
case COMMAND_PLAY_URL:
if(strParam != NULL && strlen(strParam) > 0)
*pParam = (uintptr_t)strParam; //* pointer to the url.
else
{
printf("no url to play.\n");
nCommandId = -1;
}
break;
case COMMAND_SET_VOLUME:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10); //* seek time in unit of second.
if(errno == EINVAL || errno == ERANGE)
{
printf("volume value is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("the volume value is not specified.\n");
nCommandId = -1;
}
break;
case COMMAND_SET_LOOP:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10);
if(errno == EINVAL || errno == ERANGE)
{
printf("loop value is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("the loop value is not specified.\n");
nCommandId = -1;
}
break;
case COMMAND_SET_SCALEDOWN:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10);
if(errno == EINVAL || errno == ERANGE)
{
printf("scaledown value is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("the scaledown value is not specified.\n");
nCommandId = -1;
}
break;
case COMMAND_FAST_FORWARD:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10);
if(errno == EINVAL || errno == ERANGE)
{
printf("play fast value is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("play fast value is not specified.\n");
nCommandId = -1;
}
break;
case COMMAND_FAST_BACKWARD:
if(strParam != NULL)
{
*pParam = (int)strtol(strParam, (char**)NULL, 10);
if(errno == EINVAL || errno == ERANGE)
{
printf("play slow value is not valid.\n");
nCommandId = -1;
}
}
else
{
printf("play slow value is not specified.\n");
nCommandId = -1;
}
break;
default:
break;
}
return nCommandId;
}
static int semTimedWait(sem_t* sem, int64_t time_ms)
{
int err;
if(time_ms == -1)
{
err = sem_wait(sem);
}
else
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_nsec += time_ms % 1000 * 1000 * 1000;
ts.tv_sec += time_ms / 1000 + ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec = ts.tv_nsec % (1000*1000*1000);
err = sem_timedwait(sem, &ts);
}
return err;
}
//* a callback for tplayer.
int CallbackForTPlayer(void* pUserData, int msg, int param0, void* param1)
{
DemoPlayerContext* pDemoPlayer = (DemoPlayerContext*)pUserData;
CEDARX_UNUSE(param1);
switch(msg)
{
case TPLAYER_NOTIFY_PREPARED:
{
printf("TPLAYER_NOTIFY_PREPARED,has prepared.\n");
sem_post(&pDemoPlayer->mPreparedSem);
pDemoPlayer->mPreparedFlag = 1;
break;
}
case TPLAYER_NOTIFY_PLAYBACK_COMPLETE:
{
printf("TPLAYER_NOTIFY_PLAYBACK_COMPLETE\n");
pDemoPlayer->mComplete = 1;
if(pDemoPlayer->mSetLoop == 1){
pDemoPlayer->mLoopFlag = 1;
}else{
pDemoPlayer->mLoopFlag = 0;
}
//PowerManagerReleaseWakeLock("tplayerdemo");
break;
}
case TPLAYER_NOTIFY_SEEK_COMPLETE:
{
printf("TPLAYER_NOTIFY_SEEK_COMPLETE>>>>info: seek ok.\n");
break;
}
case TPLAYER_NOTIFY_MEDIA_ERROR:
{
switch (param0)
{
case TPLAYER_MEDIA_ERROR_UNKNOWN:
{
printf("erro type:TPLAYER_MEDIA_ERROR_UNKNOWN\n");
break;
}
case TPLAYER_MEDIA_ERROR_UNSUPPORTED:
{
printf("erro type:TPLAYER_MEDIA_ERROR_UNSUPPORTED\n");
break;
}
case TPLAYER_MEDIA_ERROR_IO:
{
printf("erro type:TPLAYER_MEDIA_ERROR_IO\n");
break;
}
}
printf("TPLAYER_NOTIFY_MEDIA_ERROR\n");
pDemoPlayer->mError = 1;
if(pDemoPlayer->mPreparedFlag == 0){
printf("recive err when preparing\n");
sem_post(&pDemoPlayer->mPreparedSem);
}
if(pDemoPlayer->mSetLoop == 1){
pDemoPlayer->mLoopFlag = 1;
}else{
pDemoPlayer->mLoopFlag = 0;
}
printf("error: open media source fail.\n");
break;
}
case TPLAYER_NOTIFY_NOT_SEEKABLE:
{
pDemoPlayer->mSeekable = 0;
printf("info: media source is unseekable.\n");
break;
}
case TPLAYER_NOTIFY_BUFFER_START:
{
printf("have no enough data to play\n");
break;
}
case TPLAYER_NOTIFY_BUFFER_END:
{
printf("have enough data to play again\n");
break;
}
case TPLAYER_NOTIFY_VIDEO_FRAME:
{
//printf("get the decoded video frame\n");
break;
}
case TPLAYER_NOTIFY_AUDIO_FRAME:
{
//printf("get the decoded audio frame\n");
break;
}
case TPLAYER_NOTIFY_SUBTITLE_FRAME:
{
//printf("get the decoded subtitle frame\n");
break;
}
case TPLAYER_NOTYFY_DECODED_VIDEO_SIZE:
{
int w, h;
w = ((int*)param1)[0]; //real decoded video width
h = ((int*)param1)[1]; //real decoded video height
printf("*****tplayerdemo:video decoded width = %d,height = %d",w,h);
//int divider = 1;
//if(w>400){
// divider = w/400+1;
//}
//w = w/divider;
//h = h/divider;
printf("real set to display rect:w = %d,h = %d\n",w,h);
//TPlayerSetSrcRect(pDemoPlayer->mTPlayer, 0, 0, w, h);
}
default:
{
printf("warning: unknown callback from Tinaplayer.\n");
break;
}
}
return 0;
}
static int playVideo(DemoPlayerContext* playerContext, char* url,int x,int y,int width,int height)
{
printf("before TPlayerSetDataSource,%d:%s\n",playerContext,url);
playerContext->mSeekable = 1;
if(TPlayerSetDataSource(playerContext->mTPlayer,url,NULL)!= 0)
{
printf("TPlayerSetDataSource return fail.\n");
return -1;
}else{
printf("setDataSource end\n");
}
if(TPlayerPrepare(playerContext->mTPlayer)!= 0)
{
printf("TPlayerPrepare return fail.\n");
return -1;
}else{
printf("TPlayerPrepare end\n");
}
playerContext->mComplete = 0;
playerContext->mError = 0;
TPlayerSetDisplayRect(playerContext->mTPlayer, x, y, width, height);
#if LOOP_PLAY_FLAG
#if !USE_REPEAT_RESET_MODE
TPlayerSetLooping(playerContext->mTPlayer,1);
#endif
#endif
#if HOLD_LAST_PICTURE
printf("TPlayerSetHoldLastPicture()\n");
TPlayerSetHoldLastPicture(playerContext->mTPlayer,1);
#else
TPlayerSetHoldLastPicture(playerContext->mTPlayer,0);
#endif
#ifndef ONLY_DISABLE_AUDIO
TPlayerSetAudioEQType(playerContext->mTPlayer, AUD_EQ_TYPE_NORMAL);
#endif
if(TPlayerStart(playerContext->mTPlayer) != 0)
{
printf("TPlayerStart() return fail.\n");
return -1;
}else{
printf("started.\n");
}
return 0;
}
static int createPlayersAndPlayVideos(int argc, char** argv)
{
char fileType[FILE_TYPE_NUM][FILE_TYPE_LEN] = {".avi",".mkv",".flv",".ts",".mp4",".ts",".webm",".asf",".mpg",".mpeg",".mov",".vob",".3gp",".wmv",".pmp",".f4v",
".mp1",".mp2",".mp3",".ogg",".flac",".ape",".wav",".m4a",".amr",".aac",".omg",".oma",".aa3"};
char* lastStrPos;
int ret = 0;
for(int i = 0;i < argc-1;i++)
{
if((lastStrPos = strrchr(argv[i+1],'.')) != NULL)
{
gPlayerNum = argc -1;
if(ret == -1)
{
printf("has error,break\n");
break;
}
printf("may be is one file:cut down suffix is:%s\n",lastStrPos);
int j = 0;
int findMatchFileFlag = 0;
for(j = 0;j < FILE_TYPE_NUM;j++)
{
if(!strncasecmp(lastStrPos,&(fileType[j]),strlen(&(fileType[j]))))
{
printf("find the matched type:%s\n",&(fileType[j]));
findMatchFileFlag = 1;
break;
}
}
if(findMatchFileFlag == 0)
{
printf("%d:can not play this file:%s\n",i,argv[i]);
return -1;
}
printf("create player:%d\n",i);
//* create a player.
memset(&gDemoPlayers[i], 0, sizeof(DemoPlayerContext));
gDemoPlayers[i].mTPlayer= TPlayerCreate(CEDARX_PLAYER);
if(gDemoPlayers[i].mTPlayer == NULL)
{
printf("can not create tplayer, quit.\n");
int count = 0;
for(count=i-1;count >= 0;count--)
{
TPlayerDestroy(gDemoPlayers[count].mTPlayer);
gDemoPlayers[count].mTPlayer = NULL;
}
return -1;
}
else
{
printf("create player[%d]:%p\n",i,gDemoPlayers[i].mTPlayer);
}
//* set callback to player.
TPlayerSetNotifyCallback(gDemoPlayers[i].mTPlayer,CallbackForTPlayer, (void*)&gDemoPlayers[i]);
#ifndef ONLY_ENABLE_AUDIO
if((gScreenWidth == 0 || gScreenHeight == 0) && gDemoPlayers[i].mTPlayer->mLayerCtrl)
{
VoutRect tmpRect;
TPlayerGetDisplayRect(gDemoPlayers[i].mTPlayer,&tmpRect);
gScreenWidth = tmpRect.width;
gScreenHeight = tmpRect.height;
printf("screen width:%d,screen height:%d\n",gScreenWidth,gScreenHeight);
}
#endif
switch (argc)
{
case 2:/*one player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
break;
}
case 3:/*two player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(i%2 == 0)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth/2, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
else
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, 0, gScreenWidth/2, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
break;
}
case 4:/*three player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(i%3 == 0)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth/2, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
else if(i%3 == 1)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, 0, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
else
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, gScreenHeight/2, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
break;
}
case 5:/*four player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(i%4 == 0)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
else if(i%4 == 1)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, gScreenHeight/2, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
else if(i%4 == 2)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, 0, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
else
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, gScreenHeight/2, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
ret = -1;
}
}
break;
}
default:
{
printf("do not support play %d videos\n",argc-1);
break;
}
}
}
else
{ /*play all audio and video in one folder*/
char fileType[FILE_TYPE_NUM][FILE_TYPE_LEN] = {".avi",".mkv",".flv",".ts",".mp4",".ts",".webm",".asf",".mpg",".mpeg",".mov",".vob",".3gp",".wmv",".pmp",".f4v",
".mp1",".mp2",".mp3",".ogg",".flac",".ape",".wav",".m4a",".amr",".aac",".omg",".oma",".aa3"};
char* lastStrPos;
DIR *dir = opendir(argv[1]);
if (dir == NULL)
{
printf("opendir %s fail\n",argv[1]);
return -1;
}
isDir = 1;
struct dirent *entry;
int count= 0;
while ((entry = readdir(dir)) != NULL)
{
printf("file record length = %d,type = %d, name = %s\n",entry->d_reclen,entry->d_type,entry->d_name);
if(entry->d_type == 8)
{
char* strpos;
if((strpos = strrchr(entry->d_name,'.')) != NULL)
{
int i = 0;
printf("cut down suffix is:%s\n",strpos);
for(i = 0;i < FILE_TYPE_NUM;i++)
{
if(!strncasecmp(strpos,&(fileType[i]),strlen(&(fileType[i]))))
{
printf("find the matched type:%s\n",&(fileType[i]));
break;
}
}
if(i < FILE_TYPE_NUM)
{
if(count < TOTAL_VIDEO_AUDIO_NUM)
{
strncpy(&demoPlayer.mVideoAudioList[count],entry->d_name,strlen(entry->d_name));
printf("video file name = %s\n",&demoPlayer.mVideoAudioList[count]);
count++;
}
else
{
count++;
printf("warning:the video file in /mnt/UDISK/ is %d,which is larger than %d,we only support %d\n",count,TOTAL_VIDEO_AUDIO_NUM,TOTAL_VIDEO_AUDIO_NUM);
}
}
}
}
}
closedir(dir);
demoPlayer.mLoopFlag = 1;
demoPlayer.mSetLoop = 1;
if(count > TOTAL_VIDEO_AUDIO_NUM)
{
demoPlayer.mRealFileNum = TOTAL_VIDEO_AUDIO_NUM;
}
else
{
demoPlayer.mRealFileNum = count;
}
if(demoPlayer.mRealFileNum == 0)
{
printf("there are no video or audio files in %s,exit(-1)\n",argv[1]);
exit(-1);
}
//* create a player.
demoPlayer.mTPlayer= TPlayerCreate(CEDARX_PLAYER);
if(demoPlayer.mTPlayer == NULL)
{
printf("can not create tplayer, quit.\n");
exit(-1);
}
//* set callback to player.
TPlayerSetNotifyCallback(demoPlayer.mTPlayer,CallbackForTPlayer, (void*)&demoPlayer);
#ifndef ONLY_ENABLE_AUDIO
if((gScreenWidth == 0 || gScreenHeight == 0) && demoPlayer.mTPlayer->mLayerCtrl)
{
VoutRect tmpRect;
TPlayerGetDisplayRect(demoPlayer.mTPlayer,&tmpRect);
gScreenWidth = tmpRect.width;
gScreenHeight = tmpRect.height;
printf("screen width:%d,screen height:%d\n",gScreenWidth,gScreenHeight);
}
#endif
sem_init(&demoPlayer.mPreparedSem, 0, 0);
}
}
return ret;
}
//* the main method.
int main(int argc, char** argv)
{
install_sig_handler();
int nCommandId;
unsigned long nCommandParam;
int bQuit = 0;
char strCommandLine[1024];
CEDARX_UNUSE(argc);
CEDARX_UNUSE(argv);
int waitErr = 0;
int ret = 0;
printf("\n");
printf("******************************************************************************************\n");
printf("* This program implements a simple player, you can type commands to control the player.\n");
printf("* To show what commands supported, type 'help'.\n");
printf("******************************************************************************************\n");
if(((access("/dev/zero",F_OK)) < 0)||((access("/dev/fb0",F_OK)) < 0)){
printf("/dev/zero OR /dev/fb0 is not exit\n");
}else{
system("dd if=/dev/zero of=/dev/fb0");//clean the framebuffer
}
if(argc > 1 && argc < 6) /* can play 1-4 video*/
{
printf("argc = %d\n",argc);
int argc_count=0;
for(argc_count=0;argc_count < argc;argc_count++)
{
printf("argv[%d] = %s\n",argc_count,argv[argc_count]);
}
ret = createPlayersAndPlayVideos(argc, argv);
if(ret == -1)
goto QUIT;
while(!bQuit)
{
if(isDir)
{
if(demoPlayer.mLoopFlag)
{
demoPlayer.mLoopFlag = 0;
printf("TPlayerReset begin\n");
if(TPlayerReset(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerReset return fail.\n");
}
else
{
printf("reset the player ok.\n");
if(demoPlayer.mError == 1)
{
demoPlayer.mError = 0;
}
//PowerManagerReleaseWakeLock("tplayerdemo");
}
demoPlayer.mSeekable = 1; //* if the media source is not seekable, this flag will be
//* clear at the TINA_NOTIFY_NOT_SEEKABLE callback.
if(demoPlayer.mCurPlayIndex == demoPlayer.mRealFileNum)
{
demoPlayer.mCurPlayIndex = 0;
}
strcpy(demoPlayer.mUrl,argv[1]);
strcat(demoPlayer.mUrl,&demoPlayer.mVideoAudioList[demoPlayer.mCurPlayIndex]);
printf("demoPlayer.mUrl = %s\n",demoPlayer.mUrl);
demoPlayer.mCurPlayIndex++;
//* set url to the tinaplayer.
if(TPlayerSetDataSource(demoPlayer.mTPlayer,(const char*)demoPlayer.mUrl,NULL) != 0)
{
printf("TPlayerSetDataSource() return fail.\n");
}
else
{
printf("TPlayerSetDataSource() end\n");
}
demoPlayer.mPreparedFlag = 0;
if(TPlayerPrepareAsync(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerPrepareAsync() return fail.\n");
}
else
{
printf("preparing...\n");
}
waitErr = semTimedWait(&demoPlayer.mPreparedSem,300*1000);
if(waitErr == -1)
{
printf("prepare fail,has wait 300s\n");
break;
}
else if(demoPlayer.mError == 1)
{
printf("prepare fail\n");
break;
}
printf("prepare ok\n");
#if HOLD_LAST_PICTURE
printf("TPlayerSetHoldLastPicture()\n");
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,1);
#else
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,0);
#endif
printf("start play\n");
//TPlayerSetLooping(demoPlayer.mTPlayer,1);//let the player into looping mode
//* start the playback
if(TPlayerStart(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerStart() return fail.\n");
}
else
{
printf("started.\n");
//PowerManagerAcquireWakeLock("tplayerdemo");
}
}
}
else
{
#if LOOP_PLAY_FLAG
for(int i = 0;i < argc-1;i++)
{
if(gDemoPlayers[i].mComplete == 1)
{
printf("TPlayerReset begin\n");
if(TPlayerReset(gDemoPlayers[i].mTPlayer) != 0)
{
printf("TPlayerReset return fail.\n");
}
else
{
printf("reset the player ok.\n");
}
switch (argc)
{
case 2:/*one player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
break;
}
case 3:/*two player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(i%2 == 0)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth/2, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
else
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, 0, gScreenWidth/2, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
break;
}
case 4:/*three player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(i%3 == 0)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth/2, gScreenHeight) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
else if(i%3 == 1)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, 0, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
else
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, gScreenHeight/2, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
break;
}
case 5:/*four player*/
{
printf("%d:playVideo:%d\n",argc-1,i);
if(i%4 == 0)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, 0, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
else if(i%4 == 1)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], 0, gScreenHeight/2, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
else if(i%4 == 2)
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, 0, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
else
{
if(playVideo(&gDemoPlayers[i], argv[i+1], gScreenWidth/2, gScreenHeight/2, gScreenWidth/2, gScreenHeight/2) != 0)
{
printf("%d:playVideo fail%d\n",argc-1,i);
goto QUIT;
}
}
break;
}
default:
{
printf("do not support play %d videos\n",argc-1);
break;
}
}
}
}
#endif
}
//* read command from stdin.
if(readCommand(strCommandLine, sizeof(strCommandLine)) == 0)
{
//* parse command.
nCommandParam = 0;
nCommandId = parseCommandLine(strCommandLine, &nCommandParam);
//* process command.
switch(nCommandId)
{
case COMMAND_HELP:
{
showHelp();
break;
}
case COMMAND_QUIT:
{
printf("COMMAND_QUIT\n");
bQuit = 1;
break;
}
}
}
}
QUIT:
if(isDir)
{
if(demoPlayer.mTPlayer != NULL)
{
TPlayerDestroy(demoPlayer.mTPlayer);
demoPlayer.mTPlayer = NULL;
printf("TPlayerDestroy() successfully\n");
}
printf("destroy tplayer \n");
sem_destroy(&demoPlayer.mPreparedSem);
}
else
{
int i=0;
for(i = (argc-1)-1;i >= 0;i--)
{
if(gDemoPlayers[i].mTPlayer != NULL)
{
TPlayerDestroy(gDemoPlayers[i].mTPlayer);
gDemoPlayers[i].mTPlayer = NULL;
printf("TPlayerDestroy(%d) successfully\n",i);
}
}
printf("destroy all tplayer\n");
}
//PowerManagerReleaseWakeLock("tplayerdemo");
printf("\n");
printf("******************************************************************************************\n");
printf("* Quit the program, goodbye!\n");
printf("******************************************************************************************\n");
printf("\n");
return 0;
}
if(argc == 1)
{/*use command to control one player*/
memset(&demoPlayer, 0, sizeof(DemoPlayerContext));
demoPlayer.mError = 0;
demoPlayer.mSeekable = 1;
demoPlayer.mPreparedFlag = 0;
demoPlayer.mLoopFlag = 0;
demoPlayer.mSetLoop = 0;
demoPlayer.mMediaInfo = NULL;
//* create a player.
demoPlayer.mTPlayer= TPlayerCreate(CEDARX_PLAYER);
if(demoPlayer.mTPlayer == NULL)
{
printf("can not create tplayer, quit.\n");
exit(-1);
}
//* set callback to player.
TPlayerSetNotifyCallback(demoPlayer.mTPlayer,CallbackForTPlayer, (void*)&demoPlayer);
#ifndef ONLY_ENABLE_AUDIO
if((gScreenWidth == 0 || gScreenHeight == 0) && demoPlayer.mTPlayer->mLayerCtrl)
{
VoutRect tmpRect;
TPlayerGetDisplayRect(demoPlayer.mTPlayer,&tmpRect);
gScreenWidth = tmpRect.width;
gScreenHeight = tmpRect.height;
printf("screen width:%d,screen height:%d\n",gScreenWidth,gScreenHeight);
}
#endif
sem_init(&demoPlayer.mPreparedSem, 0, 0);
//* read, parse and process command from user.
bQuit = 0;
while(!bQuit)
{
//for test loop play which use reset for each play
//printf("demoPlayer.mLoopFlag = %d",demoPlayer.mLoopFlag);
if(demoPlayer.mLoopFlag)
{
demoPlayer.mLoopFlag = 0;
printf("TPlayerReset begin\n");
if(TPlayerReset(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerReset return fail.\n");
}
else
{
printf("reset the player ok.\n");
if(demoPlayer.mError == 1)
{
demoPlayer.mError = 0;
}
//PowerManagerReleaseWakeLock("tplayerdemo");
}
demoPlayer.mSeekable = 1; //* if the media source is not seekable, this flag will be
//* clear at the TINA_NOTIFY_NOT_SEEKABLE callback.
//* set url to the tplayer.
if(TPlayerSetDataSource(demoPlayer.mTPlayer,(const char*)demoPlayer.mUrl,NULL) != 0)
{
printf("TPlayerSetDataSource() return fail.\n");
}
else
{
printf("TPlayerSetDataSource() end\n");
}
demoPlayer.mPreparedFlag = 0;
if(TPlayerPrepareAsync(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerPrepareAsync() return fail.\n");
}
else
{
printf("preparing...\n");
}
waitErr = semTimedWait(&demoPlayer.mPreparedSem,300*1000);
if(waitErr == -1)
{
printf("prepare fail,has wait 300s\n");
break;
}
else if(demoPlayer.mError == 1)
{
printf("prepare fail\n");
break;
}
printf("prepare ok\n");
#if HOLD_LAST_PICTURE
printf("TPlayerSetHoldLastPicture()\n");
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,1);
#else
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,0);
#endif
printf("start play\n");
//TPlayerSetLooping(demoPlayer.mTPlayer,1);//let the player into looping mode
//* start the playback
if(TPlayerStart(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerStart() return fail.\n");
}
else
{
printf("started.\n");
//PowerManagerAcquireWakeLock("tplayerdemo");
}
}
//* read command from stdin.
if(readCommand(strCommandLine, sizeof(strCommandLine)) == 0)
{
//* parse command.
nCommandParam = 0;
nCommandId = parseCommandLine(strCommandLine, &nCommandParam);
//* process command.
switch(nCommandId)
{
case COMMAND_HELP:
{
showHelp();
break;
}
case COMMAND_QUIT:
{
printf("COMMAND_QUIT\n");
bQuit = 1;
break;
}
case COMMAND_SET_SOURCE : //* set url of media file.
{
char* pUrl;
pUrl = (char*)(uintptr_t)nCommandParam;
memset(demoPlayer.mUrl,0,512);
strcpy(demoPlayer.mUrl,pUrl);
printf("demoPlayer.mUrl = %s\n",demoPlayer.mUrl);
if(demoPlayer.mError == 1) //pre status is error,reset the player first
{
printf("pre status is error,reset the tina player first.\n");
TPlayerReset(demoPlayer.mTPlayer);
demoPlayer.mError = 0;
}
demoPlayer.mSeekable = 1; //* if the media source is not seekable, this flag will be
//* clear at the TINA_NOTIFY_NOT_SEEKABLE callback.
//* set url to the tinaplayer.
if(TPlayerSetDataSource(demoPlayer.mTPlayer,(const char*)demoPlayer.mUrl,NULL) != 0)
{
printf("TPlayerSetDataSource() return fail.\n");
break;
}
else
{
printf("setDataSource end\n");
}
break;
}
case COMMAND_PREPARE:
{
demoPlayer.mPreparedFlag = 0;
if(TPlayerPrepareAsync(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerPrepareAsync() return fail.\n");
}
else
{
printf("prepare\n");
}
waitErr = semTimedWait(&demoPlayer.mPreparedSem,300*1000);
if(waitErr == -1)
{
printf("prepare fail,has wait 300s\n");
break;
}
else if(demoPlayer.mError == 1)
{
printf("prepare fail\n");
break;
}
printf("prepared ok\n");
break;
}
case COMMAND_PLAY: //* start playback.
{
#if HOLD_LAST_PICTURE
printf("TPlayerSetHoldLastPicture()\n");
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,1);
#else
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,0);
#endif
if(TPlayerStart(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerStart() return fail.\n");
break;
}
else
{
printf("started.\n");
//PowerManagerAcquireWakeLock("tplayerdemo");
}
break;
}
case COMMAND_PAUSE: //* pause the playback.
{
if(TPlayerPause(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerPause() return fail.\n");
break;
}
else
{
printf("paused.\n");
//PowerManagerReleaseWakeLock("tplayerdemo");
}
break;
}
case COMMAND_STOP: //* stop the playback.
{
if(TPlayerStop(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerStop() return fail.\n");
break;
}
else
{
//PowerManagerReleaseWakeLock("tplayerdemo");
}
break;
}
case COMMAND_SEEKTO: //* seek to posion, in unit of second.
{
int nSeekTimeMs;
int nDuration;
nSeekTimeMs = nCommandParam*1000;
int ret = TPlayerGetDuration(demoPlayer.mTPlayer,&nDuration);
printf("nSeekTimeMs = %d , nDuration = %d\n",nSeekTimeMs,nDuration);
if(ret != 0)
{
printf("getDuration fail, unable to seek!\n");
break;
}
if(nSeekTimeMs > nDuration)
{
printf("seek time out of range, media duration = %d seconds.\n", nDuration/1000);
break;
}
if(demoPlayer.mSeekable == 0)
{
printf("media source is unseekable.\n");
break;
}
if(TPlayerSeekTo(demoPlayer.mTPlayer,nSeekTimeMs) != 0)
{
printf("TPlayerSeekTo() return fail,nSeekTimeMs= %d\n",nSeekTimeMs);
break;
}
else
{
printf("is seeking.\n");
}
break;
}
case COMMAND_RESET: //* reset the player
{
if(TPlayerReset(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerReset() return fail.\n");
break;
}
else
{
printf("reset the player ok.\n");
//PowerManagerReleaseWakeLock("tinaplayerdemo");
}
break;
}
case COMMAND_SHOW_MEDIAINFO: //* show media information.
{
printf("show media information:\n");
MediaInfo* mi = NULL;
demoPlayer.mMediaInfo = TPlayerGetMediaInfo(demoPlayer.mTPlayer);
if(demoPlayer.mMediaInfo != NULL)
{
mi = demoPlayer.mMediaInfo;
printf("file size = %lld KB\n",mi->nFileSize/1024);
printf("duration = %lld ms\n",mi->nDurationMs);
printf("bitrate = %d Kbps\n",mi->nBitrate/1024);
printf("container type = %d\n",mi->eContainerType);
#ifndef ONLY_ENABLE_AUDIO
printf("video stream num = %d\n",mi->nVideoStreamNum);
#endif
printf("audio stream num = %d\n",mi->nAudioStreamNum);
#ifndef ONLY_ENABLE_AUDIO
printf("subtitle stream num = %d\n",mi->nSubtitleStreamNum);
if(mi->pVideoStreamInfo != NULL)
{
printf("video codec tpye = %d\n",mi->pVideoStreamInfo->eCodecFormat);
printf("video width = %d\n",mi->pVideoStreamInfo->nWidth);
printf("video height = %d\n",mi->pVideoStreamInfo->nHeight);
printf("video framerate = %d\n",mi->pVideoStreamInfo->nFrameRate);
printf("video frameduration = %d\n",mi->pVideoStreamInfo->nFrameDuration);
}
#endif
if(mi->pAudioStreamInfo != NULL)
{
printf("audio codec tpye = %d\n",mi->pAudioStreamInfo->eCodecFormat);
printf("audio channel num = %d\n",mi->pAudioStreamInfo->nChannelNum);
printf("audio BitsPerSample = %d\n",mi->pAudioStreamInfo->nBitsPerSample);
printf("audio sample rate = %d\n",mi->pAudioStreamInfo->nSampleRate);
printf("audio bitrate = %d Kbps\n",mi->pAudioStreamInfo->nAvgBitrate/1024);
}
}
break;
}
case COMMAND_SHOW_DURATION: //* show media duration, in unit of second.
{
int nDuration = 0;
if(TPlayerGetDuration(demoPlayer.mTPlayer,&nDuration) == 0)
printf("media duration = %d seconds.\n", nDuration/1000);
else
printf("fail to get media duration.\n");
break;
}
case COMMAND_SHOW_POSITION: //* show current play position, in unit of second.
{
int nPosition = 0;
if(TPlayerGetCurrentPosition(demoPlayer.mTPlayer,&nPosition) == 0)
printf("current position = %d seconds.\n", nPosition/1000);
else
printf("fail to get pisition.\n");
break;
}
case COMMAND_GET_DISP_FRAMERATE: //* get video real disp framerate
{
float realDispFramerate = 0.0;
int getFramerateRet = TPlayerGetVideoDispFramerate(demoPlayer.mTPlayer,&realDispFramerate);
if(getFramerateRet == -1)
printf("err:we should get the real display framerate after play\n");
else
printf("real display framerate : %f\n",realDispFramerate);
break;
}
case COMMAND_SWITCH_AUDIO: //* switch autio track.
{
int audioStreamIndex;
audioStreamIndex = (int)nCommandParam;
printf("switch audio to the %dth track.\n", audioStreamIndex);
int ret = TPlayerSwitchAudio(demoPlayer.mTPlayer,audioStreamIndex);
if(ret != 0){
printf("switch audio err\n");
}
break;
}
case COMMAND_PLAY_URL: //* set url of media file.
{
char* pUrl;
pUrl = (char*)(uintptr_t)nCommandParam;
memset(demoPlayer.mUrl,0,512);
strcpy(demoPlayer.mUrl,pUrl);
printf("demoPlayer.mUrl = %s",demoPlayer.mUrl);
if(TPlayerReset(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerReset() return fail.\n");
break;
}
else
{
printf("reset the player ok.\n");
if(demoPlayer.mError == 1)
{
demoPlayer.mError = 0;
}
//PowerManagerReleaseWakeLock("tplayerdemo");
}
demoPlayer.mSeekable = 1; //* if the media source is not seekable, this flag will be
//* clear at the TINA_NOTIFY_NOT_SEEKABLE callback.
//* set url to the tinaplayer.
if(TPlayerSetDataSource(demoPlayer.mTPlayer,(const char*)demoPlayer.mUrl,NULL)!= 0)
{
printf("TPlayerSetDataSource return fail.\n");
break;
}
else
{
printf("setDataSource end\n");
}
demoPlayer.mPreparedFlag = 0;
if(TPlayerPrepareAsync(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerPrepareAsync() return fail.\n");
}
else
{
printf("preparing...\n");
}
waitErr = semTimedWait(&demoPlayer.mPreparedSem,300*1000);
if(waitErr == -1)
{
printf("prepare fail,has wait 300s\n");
break;
}
else if(demoPlayer.mError == 1)
{
printf("prepare fail\n");
break;
}
printf("prepared ok\n");
#if HOLD_LAST_PICTURE
printf("TPlayerSetHoldLastPicture()\n");
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,1);
#else
TPlayerSetHoldLastPicture(demoPlayer.mTPlayer,0);
#endif
printf("start play \n");
//TPlayerSetLooping(demoPlayer.mTPlayer,1);//let the player into looping mode
//* start the playback
if(TPlayerStart(demoPlayer.mTPlayer) != 0)
{
printf("TPlayerStart() return fail.\n");
break;
}
else
{
printf("started.\n");
//PowerManagerAcquireWakeLock("tplayerdemo");
}
break;
}
case COMMAND_SET_VOLUME: //* seek to posion, in unit of second.
{
int volume = (int)nCommandParam;
printf("tplayerdemo setVolume:volume = %d\n",volume);
int ret = TPlayerSetVolume(demoPlayer.mTPlayer,volume);
if(ret == -1)
{
printf("tplayerdemo set volume err\n");
}
else
{
printf("tplayerdemo set volume ok\n");
}
break;
}
case COMMAND_GET_VOLUME: //* seek to posion, in unit of second.
{
int curVolume = TPlayerGetVolume(demoPlayer.mTPlayer);
printf("cur volume = %d\n",curVolume);
break;
}
case COMMAND_SET_LOOP: //* set loop flag
{
printf("tplayerdemo set loop flag:flag = %d\n",(int)nCommandParam);
if(nCommandParam == 1)
{
demoPlayer.mSetLoop = 1;
}
else if(nCommandParam == 0)
{
demoPlayer.mSetLoop = 0;
}
else
{
printf("the set loop value is wrong\n");
}
break;
}
case COMMAND_SET_SCALEDOWN: //set video scaledown
{
int scaleDown = (int)nCommandParam;
printf("tplayerdemo set scaledown value = %d\n",scaleDown);
switch (scaleDown)
{
case 2:
{
printf("scale down 1/2\n");
int ret = TPlayerSetScaleDownRatio(demoPlayer.mTPlayer,TPLAYER_VIDEO_SCALE_DOWN_2,TPLAYER_VIDEO_SCALE_DOWN_2);
if(ret != 0){
printf("set scale down err\n");
}
break;
}
case 4:
{
printf("scale down 1/4\n");
int ret = TPlayerSetScaleDownRatio(demoPlayer.mTPlayer,TPLAYER_VIDEO_SCALE_DOWN_4,TPLAYER_VIDEO_SCALE_DOWN_4);
if(ret != 0){
printf("set scale down err\n");
}
break;
}
case 8:
{
printf("scale down 1/8\n");
int ret = TPlayerSetScaleDownRatio(demoPlayer.mTPlayer,TPLAYER_VIDEO_SCALE_DOWN_8,TPLAYER_VIDEO_SCALE_DOWN_8);
if(ret != 0){
printf("set scale down err\n");
}
break;
}
default:
{
printf("scaledown value is wrong\n");
break;
}
}
break;
}
case COMMAND_FAST_FORWARD: //fast forward
{
int fastForwardTimes = (int)nCommandParam;
printf("tplayerdemo fast forward times = %d\n",fastForwardTimes);
switch (fastForwardTimes)
{
case 2:
{
printf("fast forward 2 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_FORWARD_2);
if(ret != 0){
printf("fast forward err\n");
}
break;
}
case 4:
{
printf("fast forward 4 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_FORWARD_4);
if(ret != 0){
printf("fast forward err\n");
}
break;
}
case 8:
{
printf("fast forward 8 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_FORWARD_8);
if(ret != 0){
printf("fast forward err\n");
}
break;
}
case 16:
{
printf("fast forward 16 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_FORWARD_16);
if(ret != 0){
printf("fast forward err\n");
}
break;
}
default:
{
printf("the value of fast forward times is wrong,can not fast forward. value = %d\n",fastForwardTimes);
printf("we set it to normal play\n");
TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_1);
break;
}
}
break;
}
case COMMAND_FAST_BACKWARD: //fast backward
{
int fastBackwardTimes = (int)nCommandParam;
printf("tplayerdemo fast backward times = %d\n",fastBackwardTimes);
switch (fastBackwardTimes)
{
case 2:
{
printf("fast backward 2 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_BACKWARD_2);
if(ret != 0){
printf("fast backward err\n");
}
break;
}
case 4:
{
printf("fast backward 4 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_BACKWARD_4);
if(ret != 0){
printf("fast backward err\n");
}
break;
}
case 8:
{
printf("fast backward 8 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_BACKWARD_8);
if(ret != 0){
printf("fast backward err\n");
}
break;
}
case 16:
{
printf("fast backward 16 times\n");
int ret = TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_FAST_BACKWARD_16);
if(ret != 0){
printf("fast backward err\n");
}
break;
}
default:
{
printf("the value of fast backward times is wrong,can not fast backward. value = %d\n",fastBackwardTimes);
printf("we set it to normal play\n");
TPlayerSetSpeed(demoPlayer.mTPlayer,PLAY_SPEED_1);
break;
}
}
break;
}
case COMMAND_SET_SRC_RECT:
{
TPlayerSetSrcRect(demoPlayer.mTPlayer, 0, 0, 720, 480);
break;
}
case COMMAND_SET_OUTPUT_RECT:
{
TPlayerSetDisplayRect(demoPlayer.mTPlayer, 0, 0, 400, 400);
break;
}
}
}
}
if(demoPlayer.mTPlayer != NULL)
{
TPlayerDestroy(demoPlayer.mTPlayer);
demoPlayer.mTPlayer = NULL;
printf("TPlayerDestroy() successfully\n");
}
printf("destroy tplayer \n");
sem_destroy(&demoPlayer.mPreparedSem);
//PowerManagerReleaseWakeLock("tplayerdemo");
printf("\n");
printf("******************************************************************************************\n");
printf("* Quit the program, goodbye!\n");
printf("******************************************************************************************\n");
printf("\n");
return 0;
}
}
@awwwwa 在 D1s i80 接 ST7789V uboot有显示进入 Linux 没显示黑屏了 中说:
lcd_gpio_0 = <&pio PD 0 GPIO_ACTIVE_LOW>;
配置成 lcd_gpio_0 = <&pio PD 0 GPIO_ACTIVE_HIGH>; 解决,Uboot 初始化后又拉低了rst脚
D1s i80 接 ST7789V uboot有显示进入 Linux 没显示黑屏了
设备树这样配置的
&disp {
disp_init_enable = <1>;
disp_mode = <0>;
screen0_output_type = <1>;
screen0_output_mode = <4>;
screen1_output_type = <3>;
screen1_output_mode = <4>;
screen1_output_format = <0>;
screen1_output_bits = <0>;
screen1_output_eotf = <4>;
screen1_output_cs = <257>;
screen1_output_dvi_hdmi = <2>;
screen1_output_range = <2>;
screen1_output_scan = <0>;
screen1_output_aspect_ratio = <8>;
dev0_output_type = <1>;
dev0_output_mode = <4>;
dev0_screen_id = <0>;
dev0_do_hpd = <0>;
dev1_output_type = <4>;
dev1_output_mode = <10>;
dev1_screen_id = <1>;
dev1_do_hpd = <1>;
def_output_dev = <0>;
hdmi_mode_check = <1>;
disp_rotation_used = <1>;
degree0 = <0>;
fb0_format = <0>;
fb0_buffer_num = <1>;
/*fb0_width = <800>;*/
/*fb0_height = <480>;*/ /*read from lcd*/
fb1_format = <0>;
fb1_width = <0>;
fb1_height = <0>;
chn_cfg_mode = <1>;
disp_para_zone = <1>;
/*VCC-LCD*/
/* dc1sw-supply = <®_dc1sw>;*/
/*VCC-DSI*/
/* eldo3-supply = <®_eldo3>;*/
/*VCC-PD*/
/* dcdc1-supply = <®_dcdc1>;*/
};
&lcd0 {
lcd_used = <1>;
lcd_driver_name = "st7789v_cpu2";
/* part 2 */
lcd_if = <1>;
lcd_cpu_if = <8>;
/* part 3 */
lcd_width = <23>;
lcd_height = <43>;
lcd_x = <320>;
lcd_y = <240>;
lcd_dclk_freq = <6>;
lcd_hbp = <34>;
lcd_ht = <384>;
lcd_hspw = <10>;
lcd_vbp = <14>;
lcd_vt = <260>;
lcd_vspw = <4>;
/* part 4 */
lcd_backlight = <50>;
lcd_pwm_used = <1>;
lcd_pwm_ch = <7>;
lcd_pwm_freq = <20000>;
lcd_pwm_pol = <1>;
lcd_bright_curve_en = <1>;
/* part 5 */
lcd_cpu_mode= <1>;
lcd_cpu_te= <0>;
lcd_frm = <1>;
lcd_gamma_en = <0>;
lcd_cmap_en = <0>;
/* part 6 */
lcd_gpio_0 = <&pio PD 0 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&cpu16_pins_a>;
pinctrl-1 = <&cpu16_pins_b>;
};
驱动
/*
* Copyright (c) 2021 Allwinnertech Co., Ltd.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "st7789v_cpu2.h"
static void lcd_power_on(u32 sel);
static void lcd_power_off(u32 sel);
static void lcd_bl_open(u32 sel);
static void lcd_bl_close(u32 sel);
static void lcd_panel_init(u32 sel);
static void lcd_panel_exit(u32 sel);
#define panel_reset(sel, val) sunxi_lcd_gpio_set_value(sel, 0, val)
static void lcd_cfg_panel_info(struct panel_extend_para *info)
{
u32 i = 0, j = 0;
u32 items;
u8 lcd_gamma_tbl[][2] = {
{0, 0},
{15, 15},
{30, 30},
{45, 45},
{60, 60},
{75, 75},
{90, 90},
{105, 105},
{120, 120},
{135, 135},
{150, 150},
{165, 165},
{180, 180},
{195, 195},
{210, 210},
{225, 225},
{240, 240},
{255, 255},
};
u32 lcd_cmap_tbl[2][3][4] = {
{
{LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
{LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
{LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
},
{
{LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
{LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
{LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
},
};
items = sizeof(lcd_gamma_tbl) / 2;
for (i = 0; i < items - 1; i++) {
u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
for (j = 0; j < num; j++) {
u32 value = 0;
value = lcd_gamma_tbl[i][1] +
((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1])
* j) / num;
info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
(value << 16)
+ (value << 8) + value;
}
}
info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
(lcd_gamma_tbl[items - 1][1] << 8)
+ lcd_gamma_tbl[items - 1][1];
memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
}
static s32 lcd_open_flow(u32 sel)
{
LCD_OPEN_FUNC(sel, lcd_power_on, 10);
LCD_OPEN_FUNC(sel, lcd_panel_init, 10);
LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 50);
LCD_OPEN_FUNC(sel, lcd_bl_open, 0);
return 0;
}
static s32 lcd_close_flow(u32 sel)
{
LCD_CLOSE_FUNC(sel, lcd_bl_close, 0);
LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 0);
LCD_CLOSE_FUNC(sel, lcd_panel_exit, 200);
LCD_CLOSE_FUNC(sel, lcd_power_off, 500);
return 0;
}
static void lcd_power_on(u32 sel)
{
panel_reset(sel, 1);
sunxi_lcd_delay_ms(100);
panel_reset(sel, 0);
sunxi_lcd_delay_ms(20);
panel_reset(sel, 1);
sunxi_lcd_delay_ms(100);
sunxi_lcd_pin_cfg(sel, 1);
}
static void lcd_power_off(u32 sel)
{
sunxi_lcd_pin_cfg(sel, 0);
sunxi_lcd_delay_ms(20);
panel_reset(sel, 0);
sunxi_lcd_delay_ms(5);
}
static void lcd_bl_open(u32 sel)
{
sunxi_lcd_pwm_enable(sel);
}
static void lcd_bl_close(u32 sel)
{
sunxi_lcd_pwm_disable(sel);
}
static void lcd_panel_init(u32 sel)
{
sunxi_lcd_cpu_write_index(sel, 0xbb);
sunxi_lcd_cpu_write_data(sel, 0x1e);
sunxi_lcd_cpu_write_index(sel, 0xc0);
sunxi_lcd_cpu_write_data(sel, 0x2c);
sunxi_lcd_cpu_write_index(sel, 0xc2);
sunxi_lcd_cpu_write_data(sel, 0x01);
sunxi_lcd_cpu_write_index(sel, 0xc3);
sunxi_lcd_cpu_write_data(sel, 0x0b);
sunxi_lcd_cpu_write_index(sel, 0xc4);
sunxi_lcd_cpu_write_data(sel, 0x20);
//sunxi_lcd_cpu_write_index(sel, 0xc6);// frame rate control
//sunxi_lcd_cpu_write_data(sel, 0x04);
sunxi_lcd_cpu_write_index(sel, 0xd0);
sunxi_lcd_cpu_write_data(sel, 0xa4);
sunxi_lcd_cpu_write_data(sel, 0xa1);
sunxi_lcd_cpu_write_index(sel, 0xd6);
sunxi_lcd_cpu_write_data(sel, 0xa1);
sunxi_lcd_cpu_write_index(sel, 0xbb);
sunxi_lcd_cpu_write_data(sel, 0x1a);
#endif
/*ST7789V gamma setting */
sunxi_lcd_cpu_write_index(sel, 0xe0);
sunxi_lcd_cpu_write_data(sel, 0xd0);
sunxi_lcd_cpu_write_data(sel, 0x06);
sunxi_lcd_cpu_write_data(sel, 0x0b);
sunxi_lcd_cpu_write_data(sel, 0x07);
sunxi_lcd_cpu_write_data(sel, 0x07);
sunxi_lcd_cpu_write_data(sel, 0x24);
sunxi_lcd_cpu_write_data(sel, 0x2e);
sunxi_lcd_cpu_write_data(sel, 0x32);
sunxi_lcd_cpu_write_data(sel, 0x46);
sunxi_lcd_cpu_write_data(sel, 0x37);
sunxi_lcd_cpu_write_data(sel, 0x13);
sunxi_lcd_cpu_write_data(sel, 0x13);
sunxi_lcd_cpu_write_data(sel, 0x2d);
sunxi_lcd_cpu_write_data(sel, 0x33);
sunxi_lcd_cpu_write_index(sel, 0xe1);
sunxi_lcd_cpu_write_data(sel, 0xd0);
sunxi_lcd_cpu_write_data(sel, 0x02);
sunxi_lcd_cpu_write_data(sel, 0x06);
sunxi_lcd_cpu_write_data(sel, 0x09);
sunxi_lcd_cpu_write_data(sel, 0x08);
sunxi_lcd_cpu_write_data(sel, 0x05);
sunxi_lcd_cpu_write_data(sel, 0x29);
sunxi_lcd_cpu_write_data(sel, 0x44);
sunxi_lcd_cpu_write_data(sel, 0x42);
sunxi_lcd_cpu_write_data(sel, 0x38);
sunxi_lcd_cpu_write_data(sel, 0x14);
sunxi_lcd_cpu_write_data(sel, 0x14);
sunxi_lcd_cpu_write_data(sel, 0x2a);
sunxi_lcd_cpu_write_data(sel, 0x30);
sunxi_lcd_cpu_write_index(sel, 0x21);
sunxi_lcd_cpu_write_index(sel, 0x11);//sleep out
sunxi_lcd_delay_ms(120);
sunxi_lcd_cpu_write_index(sel, 0x36);//data access control
sunxi_lcd_cpu_write_data(sel, 0xb0);
sunxi_lcd_cpu_write_index(sel, 0x2a);// column address set
sunxi_lcd_cpu_write_data(sel, 0x00);
sunxi_lcd_cpu_write_data(sel, 0x00);
sunxi_lcd_cpu_write_data(sel, 0x01);
sunxi_lcd_cpu_write_data(sel, 0x3f);
sunxi_lcd_cpu_write_index(sel, 0x2b);// row address set
sunxi_lcd_cpu_write_data(sel, 0x00);
sunxi_lcd_cpu_write_data(sel, 0x00);
sunxi_lcd_cpu_write_data(sel, 0x00);
sunxi_lcd_cpu_write_data(sel, 0xef);
sunxi_lcd_cpu_write_index(sel, 0x3a);// cpu mode
sunxi_lcd_cpu_write_data(sel, 0x55);
sunxi_lcd_cpu_write_index(sel, 0x29);//display on
sunxi_lcd_cpu_write_index(sel, 0x2c);//memory write
printk(KERN_ERR "st7789v3 init over!");
}
static void lcd_panel_exit(u32 sel)
{
//sunxi_lcd_dsi_dcs_write_0para(sel, 0x10);
sunxi_lcd_delay_ms(80);
//sunxi_lcd_dsi_dcs_write_0para(sel, 0x28);
sunxi_lcd_delay_ms(50);
}
/*sel: 0:lcd0; 1:lcd1*/
static s32 lcd_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
{
return 0;
}
struct __lcd_panel st7789v_cpu2_panel = {
/* panel driver name, must mach the name of
* lcd_drv_name in sys_config.fex
*/
.name = "st7789v_cpu2",
.func = {
.cfg_panel_info = lcd_cfg_panel_info,
.cfg_open_flow = lcd_open_flow,
.cfg_close_flow = lcd_close_flow,
.lcd_user_defined_func = lcd_user_defined_func,
},
};