linux3.4 bsp linux 摄像头NV12格式原始视频格式数据采集源码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#define BUF_NUM 4
#define FRAMESINBUF 1
struct CJ_Buffer {
void *memory;
int length;
};
struct CJ_Buffer *gpV4l2Buf;
int gMemMapLen;
int file_fd;
char *dev_name = "/dev/video0";
int fd;
int getFullSize(int * full_w, int * full_h)
{
struct v4l2_frmsizeenum size_enum;
size_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
size_enum.pixel_format = V4L2_PIX_FMT_NV12;
size_enum.index = 0;
if (-1 == ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &size_enum))
{
perror("VIDIOC_ENUM_FRAMESIZES failed");
return 0;
}
*full_w = size_enum.discrete.width;
*full_h = size_enum.discrete.height;
printf("getFullSize: %dx%d\n", *full_w, *full_h);
return 1;
}
int tryFmtSize(int *width, int *height)
{
int ret = -1;
struct v4l2_format fmt;
printf("%dx%d", *width, *height);
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = *width;
fmt.fmt.pix.height = *height;
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
fmt.fmt.pix.field = V4L2_FIELD_NONE;
ret = ioctl(fd, VIDIOC_TRY_FMT, &fmt);
if (ret < 0)
{
perror("VIDIOC_TRY_FMT failed");
return ret;
}
// driver surpport this size
*width = fmt.fmt.pix.width;
*height = fmt.fmt.pix.height;
return 0;
}
int setContrastValue(int value)
{
int ret = -1;
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_CONTRAST;
ctrl.value = value;
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0) {
perror("VIDIOC_S_CTRL failed");
} else {
printf("setContrastValue ok\n");
}
return ret;
}
int setBrightnessValue(int value)
{
struct v4l2_control ctrl;
int ret = -1;
ctrl.id = V4L2_CID_BRIGHTNESS;
ctrl.value = value;
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0) {
perror("VIDIOC_S_CTRL failed");
} else {
printf("setBrightnessValue ok\n");
}
return ret;
}
int setSaturationValue(int value)
{
struct v4l2_control ctrl;
int ret = -1;
ctrl.id = V4L2_CID_SATURATION;
ctrl.value = value;
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0) {
perror("VIDIOC_S_CTRL failed");
} else {
printf("setSaturationValue ok\n");
}
return ret;
}
int setSharpnessValue(int value)
{
struct v4l2_control ctrl;
int ret = -1;
ctrl.id = V4L2_CID_SHARPNESS;
ctrl.value = value;
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0) {
perror("VIDIOC_S_CTRL failed");
} else {
printf("setSharpnessValue ok\n");
}
return ret;
}
int setHueValue(int value)
{
struct v4l2_control ctrl;
int ret = -1;
ctrl.id = V4L2_CID_HUE;
ctrl.value = value;
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0) {
perror("VIDIOC_S_CTRL failed");
} else {
printf("setHueValue ok\n");
}
return ret;
}
int setHflip(int value)
{
struct v4l2_control ctrl;
int ret = -1;
ctrl.id = V4L2_CID_HFLIP_THUMB;
ctrl.value = value;
printf("V4L2CameraDevice::setHflip value=%d\n", value);
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0)
{
//setSharpnessValue failed
perror("setHflip thumb failed\n");
}
ctrl.id = V4L2_CID_HFLIP;
ctrl.value = value;
printf("V4L2CameraDevice::setHflip value=%d\n", value);
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0)
{
//setSharpnessValue failed
perror("setHflip failed\n");
}
return ret;
}
int setVflip(int value)
{
struct v4l2_control ctrl;
int ret = -1;
ctrl.id = V4L2_CID_VFLIP_THUMB;
ctrl.value = value;
printf("V4L2CameraDevice::setVflip value=%d\n", value);
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0)
{
//setSharpnessValue failed
perror("setVflip thumb failed111\n");
}
ctrl.id = V4L2_CID_VFLIP;
ctrl.value = value;
printf("V4L2CameraDevice::setVflip value=%d\n", value);
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0)
{
//setSharpnessValue failed
perror("setVflip failed111\n");
}
return ret;
}
int v4l2setCaptureParams(int framerate)
{
printf("framerate=%d", framerate);
int ret = -1;
struct v4l2_streamparm params;
params.parm.capture.timeperframe.numerator = 1;
params.parm.capture.timeperframe.denominator = framerate;
params.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
params.parm.capture.capturemode = V4L2_MODE_VIDEO;
printf("VIDIOC_S_PARM mFrameRate: %d, capture mode: %d\n", framerate, params.parm.capture.capturemode);
ret = ioctl(fd, VIDIOC_S_PARM, ¶ms);
if (ret < 0) {
perror("VIDIOC_S_PARM failed");
} else {
printf("v4l2setCaptureParams ok\n");
}
return ret;
}
void v4l2SetVideoParams(int width, int height, int sub_w, int sub_h, unsigned int pix_fmt)
{
struct v4l2_format format;
printf("main:%dx%d, sub:%dx%d, pfmt: 0x%x\n", width, height, sub_w, sub_h, pix_fmt);
memset(&format, 0, sizeof(format));
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = width;
format.fmt.pix.height = height;
//format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
//format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
//format.fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
format.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
format.fmt.pix.field = V4L2_FIELD_NONE;
if ((sub_w > 0 && sub_w < width) && (sub_h > 0 && sub_h < height)) {
struct v4l2_pix_format sub_fmt;
memset(&sub_fmt, 0, sizeof(sub_fmt));
format.fmt.pix.subchannel = &sub_fmt;
format.fmt.pix.subchannel->width = sub_w;
format.fmt.pix.subchannel->height = sub_h;
format.fmt.pix.subchannel->pixelformat = pix_fmt;
format.fmt.pix.subchannel->field = V4L2_FIELD_NONE;
format.fmt.pix.subchannel->rot_angle = 0;
printf("sub_w=%d, sub_h=%d\n", sub_w, sub_h);
}
if (ioctl(fd, VIDIOC_S_FMT, &format) < 0)
{
perror("VIDIOC_S_FMT failed");
return;
}
return;
}
void initV4l2Buffer()
{
gpV4l2Buf = (struct CJ_Buffer *)malloc(sizeof(struct CJ_Buffer) * BUF_NUM);
if (gpV4l2Buf == NULL) {
perror("alloc V4l2Buffer_tag error!!");
return;
}
memset(gpV4l2Buf, 0, sizeof(struct CJ_Buffer) * BUF_NUM);
}
void setFramesInV4L2BufNum()
{
unsigned int nFramesInBuf = FRAMESINBUF;
printf("mFramesInV4l2buf=%u\n", FRAMESINBUF);
if (ioctl (fd, VIDIOC_SET_NFRAME_BUF, &nFramesInBuf) < 0) {
perror("VIDIOC_SET_NFRAME_BUF failed");
}
}
int v4l2ReqBufs(int * buf_cnt)
{
int ret = 0;
struct v4l2_requestbuffers rb;
printf("TO VIDIOC_REQBUFS count: %d\n", *buf_cnt);
memset(&rb, 0, sizeof(rb));
rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
rb.memory = V4L2_MEMORY_MMAP;
rb.count = *buf_cnt;
ret = ioctl(fd, VIDIOC_REQBUFS, &rb);
if (ret < 0)
{
perror("VIDIOC_REQBUFS failed");
return ret;
}
*buf_cnt = rb.count;
printf("VIDIOC_REQBUFS count: %d\n", *buf_cnt);
return 1;
}
int v4l2QueryBuf()
{
int i;
int ret = 0;
struct v4l2_buffer buf;
for (i = 0; i < BUF_NUM; i++)
{
memset (&buf, 0, sizeof (struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
ret = ioctl (fd, VIDIOC_QUERYBUF, &buf);
if (ret < 0)
{
perror("VIDIOC_QUERYBUF failed");
return ret;
}
gpV4l2Buf[i].memory = mmap(0, buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
buf.m.offset);
gMemMapLen = buf.length;
printf("index: %d, mem: %x, len: %d, offset: %x\n", i, (int)gpV4l2Buf[i].memory, buf.length, buf.m.offset);
if (gpV4l2Buf[i].memory == MAP_FAILED)
{
perror("mmap failed");
return -1;
}
}
for (i = 0; i < BUF_NUM; i++)
{
memset (&buf, 0, sizeof (struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
// start with all buffers in queue
ret = ioctl(fd, VIDIOC_QBUF, &buf);
if (ret < 0)
{
perror("VIDIOC_QBUF failed");
return ret;
}
}
return 1;
}
int v4l2StartStreaming()
{
int ret = 0;
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl (fd, VIDIOC_STREAMON, &type);
if (ret < 0)
{
perror("VIDIOC_STREAMON failed");
return ret;
}
return 1;
}
int v4l2StopStreaming()
{
int ret = 0;
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl (fd, VIDIOC_STREAMOFF, &type);
if (ret < 0)
{
perror("VIDIOC_STREAMOFF failed");
return ret;
}
printf("V4L2Camera::v4l2StopStreaming ok\n");
return 1;
}
int v4l2UnmapBuf()
{
int i;
int ret = 0;
for (i = 0; i < BUF_NUM; i++)
{
ret = munmap(gpV4l2Buf[i].memory, gMemMapLen);
if (ret < 0)
{
perror("munmap failed");
return ret;
}
gpV4l2Buf[i].memory = NULL;
}
return 1;
}
int main (int argc,char ** argv)
{
struct v4l2_capability cap;
struct v4l2_format fmt;
struct v4l2_pix_format sub_fmt;
struct v4l2_requestbuffers req;
struct v4l2_buffer buf;
struct v4l2_input inp;
unsigned int i;
enum v4l2_buf_type type;
int width, height;
fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
ioctl (fd, VIDIOC_QUERYCAP, &cap);
printf("Driver Name:%s\n Card Name:%s\n Bus info:%s\n\n", cap.driver, cap.card, cap.bus_info);
printf("capabilities:%d\n", cap.capabilities);
if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0 &&
(cap.capabilities & V4L2_CAP_STREAMING) == 0)
{
perror("cap capabilities format fail");
return -2 ;
}
inp.index = 0;
if (-1 == ioctl(fd, VIDIOC_S_INPUT, &inp))
{
perror("VIDIOC_S_INPUT error!");
return -2 ;
}
getFullSize(&width, &height);
width = 640; height = 480;
/*tryFmtSize(&width, &height);
setContrastValue(50);
setBrightnessValue(50);
setSaturationValue(0);
setSharpnessValue(10);
setHueValue(30);
setHflip(0);
setVflip(0);*/
v4l2setCaptureParams(30);
v4l2SetVideoParams(640, 480, 320, 240, V4L2_PIX_FMT_NV12);
initV4l2Buffer();
setFramesInV4L2BufNum();
int buf_cnt = BUF_NUM;
v4l2ReqBufs(&buf_cnt);
v4l2QueryBuf();
v4l2StartStreaming();
//for (i = 0; i < 10; i++)
// sleep(1);
//struct v4l2_control ctrl;
// ctrl.id = V4L2_CID_TAKE_PICTURE;
//if (ioctl(fd, VIDIOC_S_CTRL, &ctrl) < 0) {
// perror("VIDIOC_S_CTRL failed");
// } else {
// perror("setTakePictureCtrl ok\n");
// }
FILE* fp = fopen("test2.nv12", "w");
if(fp == NULL)
{
printf("open file error.\n");
goto end;
}
for (i = 0; i < 200; i++)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
select(fd + 1, &fds, NULL, NULL, NULL);
memset(&buf, 0, sizeof(struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ioctl(fd, VIDIOC_DQBUF, &buf);
void *pMem = gpV4l2Buf[buf.index].memory;
printf("frame addr = %x, length=%d, %d\n", (unsigned int)pMem, gpV4l2Buf[buf.index].length, buf.length);
fwrite(pMem, 640 * 480 * 3 / 2, 1, fp);
#if 0
if (i == 199)
{
file_fd = open("test.jpg", O_RDWR | O_CREAT, 0777);
write(file_fd, pMem, 640 * 480 * 3 / 2);
close (file_fd);
printf("frame index = %d, size = %d.\n", buf.index, buf.length);
}
#endif
ioctl(fd, VIDIOC_QBUF, &buf);
}
end:
fclose(fp);
v4l2StopStreaming();
v4l2UnmapBuf();
close (fd);
printf("Camera Done.\n");
return 0;
}
NV12录像文件下载: nv12_data.7z
想请问下晕哥,以前只有STM32基础。如何切换到这个F1C100S跑LINUX的学习上来?论坛有没有入门级的资料供我这种初学者学习?
这个教程不错: https://whycan.cn/t_3138.html
收藏本帖,目前正在新增使用spi nand flash,启动引导主线Linux 4.19,各种学习中。。。
这个帖子更有参考价值: https://whycan.cn/t_3123.html
配置sunxi-fel工具出现了如下问题:
fel.c:32:18: fatal error: zlib.h: 没有那个文件或目录
compilation terminated.
fel_lib.c:26:20: fatal error: libusb.h: 没有那个文件或目录
这个怎么破
从网上搜索的资料看,应该是 MySQL Server不支持4字节unicode码引起
https://blog.51cto.com/suifu/1853864
https://stackoverflow.com/questions/36894731/mysqli-not-setting-charset-to-utf8mb4
vc++6.0文件失效了吗?
一楼的下载链接已修复: VC6绿色版下载: vc++6.0_green.7z
已换,感谢大佬提醒。
$ find . |grep SerialPort |grep \\.so
./output/build/qt5serialport-5.12.4/lib/libQt5SerialPort.so.5.12.4
./output/build/qt5serialport-5.12.4/lib/libQt5SerialPort.so.5.12
./output/build/qt5serialport-5.12.4/lib/libQt5SerialPort.so.5
./output/build/qt5serialport-5.12.4/lib/libQt5SerialPort.so
./output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libQt5SerialPort.so.5.12.4
./output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libQt5SerialPort.so.5.12
./output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libQt5SerialPort.so.5
./output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libQt5SerialPort.so
./output/target/usr/lib/libQt5SerialPort.so.5.12.4
./output/target/usr/lib/libQt5SerialPort.so.5.12
./output/target/usr/lib/libQt5SerialPort.so.5
用 find 命令搜索 SerialPort 相关文件是否存在。
先检查自己操作的问题吧: https://whycan.cn/t_3426.html#p30402
电脑版购买链接:
https://2.taobao.com/item.htm?id=615375166331
淘宝手机app购买:
我在闲鱼发布了【闲鱼被禁言中 4元一个全新720P互联网网关监控摄像头 摄像】椱ァ製这段描述后,打开闲鱼€hbXu1kChb0O€后打开闲鱼
关于运费:
10元*数量+运费,运费首重通通通按10计,每4个超重加5元
第一套友情价,15包邮(记得留言:whycan)
------------------------
仅发布信息,不承担任何质量等其他问题.
仅发布信息,不承担任何质量等其他问题.
仅发布信息,不承担任何质量等其他问题.
https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
compatible = "gpio-leds";
drivers/leds/Makefile:obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
这个 CONFIG_LEDS_GPIO 驱动有没有勾选?
backlight {
compatible = "pwm-backlight";
pwms = <&pwm 0 5000000>;brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;power-supply = <&vdd_bl_reg>;
enable-gpios = <&gpio 58 0>;
post-pwm-on-delay-ms = <10>;
pwm-off-delay-ms = <10>;
};
凭感觉 /sys/class/backlight/pwm-backlight/bl_power 应该对应是 enable-gpios
https://whycan.cn/t_2376.html#p18090
用同一公司同一版本的 gcc 编译器就行,也就是说文件系统的gcc和windows编译app的gcc版本要一致。
否则你的app只能静态链接。
还有帖子链接吗,我没搜到
@达克罗德 大神的: https://whycan.cn/t_3380.html
可能这组TF卡引脚和他的复用功能冲突, 详细情况查看你的dts: https://whycan.cn/t_636.html#p13068
u-boot, linux代码什么都不用改, make menuconfig 配置好就行,
如果你用 sunxi-fel 的 spi nor flash 版本要改下切换bank的代码:
mkdir ~/A33/
cd ~/A33
git clone https://gitee.com/mirrors/linux
gitee的linux挂了
用清华的吧: git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux.git
mv /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gnueabihf-g++ /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gnueabihf-g++.bak
mv /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gnueabihf-gcc /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gnueabihf-gcc.bak
cp /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-g++ /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gnueabihf-g++
cp /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gcc /home/zhang/buildroot-2018.08.2/output/host/bin/arm-linux-gnueabihf-gcc
老铁们,关于democracy和virus的问题有点敏感, 可以移步Quroa或者Zhihu讨论:
这价格也是666666
https://whycan.cn/t_1158.html
https://blog.csdn.net/wavemcu/article/details/7202908
记起来了, 当时听xboot说和 busybox 有关, 你可以深入研究一下。
如果以前你按这个帖子: 【视频分享】制作荔枝派Zero开发板(全志V3s) TF/SD卡启动盘,
那么现在就可以把这个 GParted 扔掉了。
--------------------------------------------
以下由 @哇酷小管家 2021-12-16 添加:
用 buildroot 更方便,参考这两个链接
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
https://whycan.com/t_5221.html
(V3s/V3x/S3/S3L/R11通吃)小智V3x开发板smallwitpi lite u-boot/linux/buildroot测试
https://whycan.com/t_7248.html#p69178
完毕
--------------------------------------------
pack.sh
#!/bin/bash
_UBOOT_SIZE=1
###第一个分区(FAT)大小,单位MiB##
_P1_SIZE=16
###TF卡镜像文件名称###
_IMG_FILE='f1c100s_tfcard_img.bin'
###TF卡镜像文件大小, 单位MiB###
_IMG_SIZE=120
temp_root_dir=$PWD
_UBOOT_FILE="${temp_root_dir}/data/u-boot-sunxi-with-spl.bin"
_SPLASH_BMP_FILE="${temp_root_dir}/data/splash.bmp"
_BOOT_SCR_FILE="${temp_root_dir}/data/boot.scr"
_KERNEL_IMAGE_FILE="${temp_root_dir}/data/zImage"
_DTB_FILE="${temp_root_dir}/data/dtb.bin"
_ROOTFS_TGZ_FILE="${temp_root_dir}/data/rootfs.tgz"
###初始化镜像文件###
dd if=/dev/zero of=$_IMG_FILE bs=1M count=$_IMG_SIZE
###判断镜像文件是否初始化成功###
if [ $? -ne 0 ]
then
echo "getting error in creating dd img!"
exit
fi
###获取一个循环设备###
_LOOP_DEV=$(sudo losetup -f)
#echo ${_LOOP_DEV}
##再次判断此设备是否存在###
if [ -z $_LOOP_DEV ]
then
echo "can not find a loop device!"
exit
fi
###把镜像文件和循环设备关联###
sudo losetup $_LOOP_DEV $_IMG_FILE
if [ $? -ne 0 ]
then
echo "dd img --> $_LOOP_DEV error!"
sudo losetup -d $_LOOP_DEV >/dev/null 2>&1 && exit
fi
echo "--->creating partitions for tf image ..."
#blockdev --rereadpt $_LOOP_DEV >/dev/null 2>&1
# size only can be integer
###分区###
cat <<EOT |sudo sfdisk ${_IMG_FILE}
${_UBOOT_SIZE}M,${_P1_SIZE}M,c
,,L
EOT
###格式化###
sleep 2
sudo partx -u $_LOOP_DEV
sudo mkfs.vfat ${_LOOP_DEV}p1 ||exit
sudo mkfs.ext4 ${_LOOP_DEV}p2 ||exit
if [ $? -ne 0 ]
then
echo "error in creating partitions"
sudo losetup -d $_LOOP_DEV >/dev/null 2>&1 && exit
#sudo partprobe $_LOOP_DEV >/dev/null 2>&1 && exit
fi
###u-boot写到TF卡8K偏移处###
#pack uboot
echo "--->writing u-boot-sunxi-with-spl to $_LOOP_DEV"
# sudo dd if=/dev/zero of=$_LOOP_DEV bs=1K seek=1 count=1023 # clear except mbr
sudo dd if=$_UBOOT_FILE of=$_LOOP_DEV bs=1024 seek=8
if [ $? -ne 0 ]
then
echo "writing u-boot error!"
sudo losetup -d $_LOOP_DEV >/dev/null 2>&1 && exit
#sudo partprobe $_LOOP_DEV >/dev/null 2>&1 && exit
fi
###新建 p1,p2 目录,并挂载TF卡两个分区###
sudo sync
mkdir -p ${temp_root_dir}/output/p1 >/dev/null 2>&1
mkdir -p ${temp_root_dir}/output/p2 > /dev/null 2>&1
sudo mount ${_LOOP_DEV}p1 ${temp_root_dir}/output/p1
sudo mount ${_LOOP_DEV}p2 ${temp_root_dir}/output/p2
echo "--->copy boot and rootfs files..."
sudo rm -rf ${temp_root_dir}/output/p1/* && sudo rm -rf ${temp_root_dir}/output/p2/*
###复制zImage, dtb, boot.scr, splash.bmp 等文件到第一分区 ###
sudo cp ${_KERNEL_IMAGE_FILE} ${temp_root_dir}/output/p1/zImage &&\
sudo cp ${_DTB_FILE} ${temp_root_dir}/output/p1/ &&\
sudo cp ${_BOOT_SCR_FILE} ${temp_root_dir}/output/p1/ &&\
sudo cp ${_SPLASH_BMP_FILE} ${temp_root_dir}/output/p1/ &&\
echo "--->p1 done~"
###解压 rootfs.tgz 到第二分区###
sudo tar xvf ${_ROOTFS_TGZ_FILE} -C ${temp_root_dir}/output/p2/ &&\
echo "--->p2 done~"
###同步, 等待, 卸载, 退出###
sudo sync
sleep 2
sudo umount ${temp_root_dir}/output/p1 ${temp_root_dir}/output/p2 && sudo losetup -d $_LOOP_DEV
if [ $? -ne 0 ]
then
echo "umount or losetup -d error!!"
exit
fi
目录结构:
.
..
pack.sh
data/
u-boot-sunxi-with-spl.bin
boot.scr
dtb.bin
rootfs.tgz
splash.bmp
zImage
以上脚本参考本站 @xiaohui 的打包脚本, 我加了部分注释, 把其他非打包脚本剥离开了。
电阻触摸接口有验证吗,好像不对呀。屏接线与荔枝派是反的,一个是RGB,一个是BGR.
这里有RGB/BGR的切换补丁:
https://gitee.com/jiang_xing/f1c100s_buildroot/blob/master/board/f1c100s/patch/linux_kernel.patch
--- a/arch/arm/boot/dts/suniv-f1c100s.dtsi 2019-08-29 14:30:28.000000000 +0800
+++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi 2020-01-21 19:26:46.466638364 +0800
@@ -4,6 +4,10 @@
* Copyright 2018 Mesih Kilinc <mesihkilinc@gmail.com>
*/
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
+#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
+
/ {
#address-cells = <1>;
#size-cells = <1>;
@@ -31,6 +35,12 @@
device_type = "cpu";
};
};
+
+ de: display-engine {
+ compatible = "allwinner,suniv-f1c100s-display-engine";
+ allwinner,pipelines = <&fe0>;
+ status = "disabled";
+ };
soc {
compatible = "simple-bus";
@@ -62,6 +72,68 @@
};
};
+ spi0: spi@1c05000 {
+ compatible = "allwinner,suniv-spi",
+ "allwinner,sun8i-h3-spi";
+ reg = <0x01c05000 0x1000>;
+ interrupts = <10>;
+ clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;
+ clock-names = "ahb", "mod";
+ resets = <&ccu RST_BUS_SPI0>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi1: spi@1c06000 {
+ compatible = "allwinner,suniv-spi",
+ "allwinner,sun8i-h3-spi";
+ reg = <0x01c06000 0x1000>;
+ interrupts = <11>;
+ clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_BUS_SPI1>;
+ clock-names = "ahb", "mod";
+ resets = <&ccu RST_BUS_SPI1>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ tcon0: lcd-controller@1c0c000 {
+ compatible = "allwinner,suniv-f1c100s-tcon";
+ reg = <0x01c0c000 0x1000>;
+ interrupts = <29>;
+ clocks = <&ccu CLK_BUS_LCD>,
+ <&ccu CLK_TCON>;
+ clock-names = "ahb",
+ "tcon-ch0";
+ clock-output-names = "tcon-pixel-clock";
+ resets = <&ccu RST_BUS_LCD>;
+ reset-names = "lcd";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tcon0_in: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ tcon0_in_be0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&be0_out_tcon0>;
+ };
+ };
+
+ tcon0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+ };
+ };
+
ccu: clock@1c20000 {
compatible = "allwinner,suniv-f1c100s-ccu";
reg = <0x01c20000 0x400>;
@@ -71,6 +143,19 @@
#reset-cells = <1>;
};
+ i2c0: i2c@1C27000 {
+ compatible = "allwinner,sun6i-a31-i2c";
+ reg = <0x01C27000 0x400>;
+ interrupts = <7>;
+ clocks = <&ccu CLK_BUS_I2C0>;
+ resets = <&ccu RST_BUS_I2C0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
intc: interrupt-controller@1c20400 {
compatible = "allwinner,suniv-f1c100s-ic";
reg = <0x01c20400 0x400>;
@@ -82,17 +167,41 @@
compatible = "allwinner,suniv-f1c100s-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <38>, <39>, <40>;
- clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
+ clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
#gpio-cells = <3>;
+ i2c0_pins: i2c0 {
+ pins = "PE11", "PE12";
+ function = "i2c0";
+ };
+
uart0_pe_pins: uart0-pe-pins {
pins = "PE0", "PE1";
function = "uart0";
};
+
+ lcd_rgb666_pins: lcd-rgb666-pins {
+ pins = "PD0", "PD1", "PD2", "PD3", "PD4",
+ "PD5", "PD6", "PD7", "PD8", "PD9",
+ "PD10", "PD11", "PD12", "PD13", "PD14",
+ "PD15", "PD16", "PD17", "PD18", "PD19",
+ "PD20", "PD21";
+ function = "lcd";
+ };
+
+ mmc0_pins: mmc0-pins {
+ pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
+ function = "mmc0";
+ };
+
+ spi0_pins_a: spi0-pins-pc {
+ pins = "PC0", "PC1", "PC2", "PC3";
+ function = "spi0";
+ };
};
timer@1c20c00 {
@@ -102,20 +211,49 @@
clocks = <&osc24M>;
};
+ mmc0: mmc@1c0f000 {
+ compatible = "allwinner,suniv-f1c100s-mmc",
+ "allwinner,sun7i-a20-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ccu CLK_BUS_MMC0>,
+ <&ccu CLK_MMC0>,
+ <&ccu CLK_MMC0_OUTPUT>,
+ <&ccu CLK_MMC0_SAMPLE>;
+ clock-names = "ahb",
+ "mmc",
+ "output",
+ "sample";
+ resets = <&ccu RST_BUS_MMC0>;
+ reset-names = "ahb";
+ interrupts = <23>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
wdt: watchdog@1c20ca0 {
compatible = "allwinner,suniv-f1c100s-wdt",
"allwinner,sun4i-a10-wdt";
reg = <0x01c20ca0 0x20>;
};
+ lradc: lradc@1C23400 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01C23400 0x400>;
+ interrupts = <22>;
+ status = "disabled";
+ };
+
uart0: serial@1c25000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c25000 0x400>;
interrupts = <1>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&ccu 38>;
- resets = <&ccu 24>;
+ clocks = <&ccu CLK_BUS_UART0>;
+ resets = <&ccu RST_BUS_UART0>;
status = "disabled";
};
@@ -125,8 +263,8 @@
interrupts = <2>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&ccu 39>;
- resets = <&ccu 25>;
+ clocks = <&ccu CLK_BUS_UART1>;
+ resets = <&ccu RST_BUS_UART1>;
status = "disabled";
};
@@ -136,9 +274,107 @@
interrupts = <3>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&ccu 40>;
- resets = <&ccu 26>;
+ clocks = <&ccu CLK_BUS_UART2>;
+ resets = <&ccu RST_BUS_UART2>;
+ status = "disabled";
+ };
+
+ usb_otg: usb@1c13000 {
+ compatible = "allwinner,suniv-musb";
+ reg = <0x01c13000 0x0400>;
+ clocks = <&ccu CLK_BUS_OTG>;
+ resets = <&ccu RST_BUS_OTG>;
+ interrupts = <26>;
+ interrupt-names = "mc";
+ phys = <&usbphy 0>;
+ phy-names = "usb";
+ extcon = <&usbphy 0>;
+ allwinner,sram = <&otg_sram 1>;
+ status = "disabled";
+ };
+
+ usbphy: phy@1c13400 {
+ compatible = "allwinner,suniv-usb-phy";
+ reg = <0x01c13400 0x10>;
+ reg-names = "phy_ctrl";
+ clocks = <&ccu CLK_USB_PHY0>;
+ clock-names = "usb0_phy";
+ resets = <&ccu RST_USB_PHY0>;
+ reset-names = "usb0_reset";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ fe0: display-frontend@1e00000 {
+ compatible = "allwinner,suniv-f1c100s-display-frontend";
+ reg = <0x01e00000 0x20000>;
+ interrupts = <30>;
+ clocks = <&ccu CLK_BUS_DE_FE>, <&ccu CLK_DE_FE>,
+ <&ccu CLK_DRAM_DE_FE>;
+ clock-names = "ahb", "mod",
+ "ram";
+ resets = <&ccu RST_BUS_DE_FE>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ fe0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ fe0_out_be0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&be0_in_fe0>;
+ };
+ };
+ };
+ };
+
+ be0: display-backend@1e60000 {
+ compatible = "allwinner,suniv-f1c100s-display-backend";
+ reg = <0x01e60000 0x10000>;
+ reg-names = "be";
+ interrupts = <31>;
+ clocks = <&ccu CLK_BUS_DE_BE>, <&ccu CLK_DE_BE>,
+ <&ccu CLK_DRAM_DE_BE>;
+ clock-names = "ahb", "mod",
+ "ram";
+ resets = <&ccu RST_BUS_DE_BE>;
+ reset-names = "be";
+ assigned-clocks = <&ccu CLK_DE_BE>;
+ assigned-clock-rates = <300000000>;
+ rgb-channel-swap = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ be0_in: port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ be0_in_fe0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&fe0_out_be0>;
+ };
+ };
+
+ be0_out: port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ be0_out_tcon0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&tcon0_in_be0>;
+ };
+ };
+ };
};
};
};
+
--- a/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts 2019-08-29 14:30:28.000000000 +0800
+++ b/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts 2020-01-21 19:26:46.470638361 +0800
@@ -1,10 +1,14 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR X11)
/*
* Copyright 2018 Icenowy Zheng <icenowy@aosc.io>
*/
/dts-v1/;
+
#include "suniv-f1c100s.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "sunxi-common-regulators.dtsi"
/ {
model = "Lichee Pi Nano";
@@ -12,11 +16,142 @@
aliases {
serial0 = &uart0;
+ spi0 = &spi0;
};
chosen {
stdout-path = "serial0:115200n8";
};
+
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ panel: panel {
+ compatible = "ampire,am-480272h3tmqw-t01h";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>;
+ power-supply = <®_vcc3v3>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel_input: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&tcon0_out_lcd>;
+ };
+ };
+ };
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpio = <&pio 4 2 GPIO_ACTIVE_HIGH>; /* PE2 */
+ status = "okay";
+};
+
+&pio {
+ vcc-pc-supply = <®_vcc3v3>;
+ vcc-pd-supply = <®_vcc3v3>;
+ vcc-pe-supply = <®_vcc3v3>;
+ vcc-pf-supply = <®_vcc3v3>;
+};
+
+&be0 {
+ status = "okay";
+};
+
+&de {
+ status = "okay";
+};
+
+&tcon0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_rgb666_pins>;
+ status = "okay";
+};
+
+&tcon0_out {
+ tcon0_out_lcd: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&panel_input>;
+ };
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&mmc0 {
+ vmmc-supply = <®_vcc3v3>;
+ bus-width = <4>;
+ broken-cd;
+ status = "okay";
+};
+
+&pio {
+ ts_reset_pin: ts_reset_pin@0 {
+ pins = "PE9";
+ function = "gpio_out";
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+
+ flash: w25q128@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "winbond,w25q128", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "dtb";
+ reg = <0x100000 0x10000>;
+ read-only;
+ };
+
+ partition@110000 {
+ label = "kernel";
+ reg = <0x110000 0x400000>;
+ read-only;
+ };
+
+ partition@520000 {
+ label = "rootfs";
+ reg = <0x510000 0xAF0000>;
+ };
+ };
+ };
};
&uart0 {
--- a/drivers/mtd/spi-nor/spi-nor.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/mtd/spi-nor/spi-nor.c 2020-01-21 19:26:46.470638361 +0800
@@ -2118,7 +2118,7 @@
},
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
- { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, 0) },
{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) },
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c 2020-01-21 19:26:46.470638361 +0800
@@ -1419,6 +1419,15 @@
return 0;
}
+static const struct sun4i_tcon_quirks suniv_f1c100s_quirks = {
+ /*
+ * The F1C100s SoC has a second channel in TCON, but the clock input of
+ * it is not documented.
+ */
+ .has_channel_0 = true,
+ /* .has_channel_1 = true, */
+};
+
static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
.has_channel_0 = true,
.has_channel_1 = true,
@@ -1487,6 +1496,7 @@
/* sun4i_drv uses this list to check if a device node is a TCON */
const struct of_device_id sun4i_tcon_of_table[] = {
+ { .compatible = "allwinner,suniv-f1c100s-tcon", .data = &suniv_f1c100s_quirks },
{ .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
{ .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
{ .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c 2020-01-21 19:26:46.470638361 +0800
@@ -164,7 +164,8 @@
static bool sun4i_drv_node_is_frontend(struct device_node *node)
{
- return of_device_is_compatible(node, "allwinner,sun4i-a10-display-frontend") ||
+ return of_device_is_compatible(node, "allwinner,suniv-f1c100s-display-frontend") ||
+ of_device_is_compatible(node, "allwinner,sun4i-a10-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") ||
of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") ||
@@ -404,6 +405,7 @@
}
static const struct of_device_id sun4i_drv_of_table[] = {
+ { .compatible = "allwinner,suniv-f1c100s-display-engine" },
{ .compatible = "allwinner,sun4i-a10-display-engine" },
{ .compatible = "allwinner,sun5i-a10s-display-engine" },
{ .compatible = "allwinner,sun5i-a13-display-engine" },
--- a/drivers/gpu/drm/sun4i/sunxi_engine.h 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h 2020-01-21 19:26:46.470638361 +0800
@@ -124,6 +124,7 @@
struct regmap *regs;
int id;
+ int rgb_swap;
/* Engine list management */
struct list_head list;
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h 2020-01-21 19:30:43.086543111 +0800
@@ -92,6 +92,7 @@
#define SUN4I_BACKEND_LAY_FBFMT_RGB888 (11 << 8)
#define SUN4I_BACKEND_LAY_FBFMT_ARGB4444 (12 << 8)
#define SUN4I_BACKEND_LAY_FBFMT_RGBA4444 (13 << 8)
+#define SUN4I_BACKEND_LAY_RGB_SWAP (1 << 2)
#define SUN4I_BACKEND_DLCDPCTL_REG 0x8b0
#define SUN4I_BACKEND_DLCDPFRMBUF_ADDRCTL_REG 0x8b4
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c 2020-01-21 19:26:46.542638322 +0800
@@ -293,9 +293,16 @@
return ret;
}
- regmap_update_bits(backend->engine.regs,
- SUN4I_BACKEND_ATTCTL_REG1(layer),
- SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);
+ if (backend->engine.rgb_swap) {
+ regmap_update_bits(backend->engine.regs,
+ SUN4I_BACKEND_ATTCTL_REG1(layer),
+ SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT | SUN4I_BACKEND_LAY_RGB_SWAP,
+ val | SUN4I_BACKEND_LAY_RGB_SWAP);
+ } else {
+ regmap_update_bits(backend->engine.regs,
+ SUN4I_BACKEND_ATTCTL_REG1(layer),
+ SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);
+ }
return 0;
}
@@ -316,10 +323,17 @@
SUN4I_BACKEND_ATTCTL_REG0(layer),
SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN,
SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN);
-
- regmap_update_bits(backend->engine.regs,
- SUN4I_BACKEND_ATTCTL_REG1(layer),
- SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);
+
+ if (backend->engine.rgb_swap) {
+ regmap_update_bits(backend->engine.regs,
+ SUN4I_BACKEND_ATTCTL_REG1(layer),
+ SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT | SUN4I_BACKEND_LAY_RGB_SWAP,
+ val | SUN4I_BACKEND_LAY_RGB_SWAP);
+ } else {
+ regmap_update_bits(backend->engine.regs,
+ SUN4I_BACKEND_ATTCTL_REG1(layer),
+ SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);
+ }
return 0;
}
@@ -818,6 +832,12 @@
backend->engine.id = sun4i_backend_of_get_id(dev->of_node);
if (backend->engine.id < 0)
return backend->engine.id;
+
+ backend->engine.rgb_swap = 0;
+ if (of_find_property(dev->of_node, "rgb-channel-swap", NULL)) {
+ of_property_read_u32(dev->of_node, "rgb-channel-swap", &backend->engine.rgb_swap);
+ dev_warn(dev, "backend rgb channel swap(%d)\n", backend->engine.rgb_swap);
+ }
backend->frontend = sun4i_backend_find_frontend(drv, dev->of_node);
if (IS_ERR(backend->frontend))
@@ -972,6 +992,9 @@
return 0;
}
+static const struct sun4i_backend_quirks suniv_backend_quirks = {
+};
+
static const struct sun4i_backend_quirks sun4i_backend_quirks = {
.needs_output_muxing = true,
};
@@ -996,6 +1019,10 @@
static const struct of_device_id sun4i_backend_of_table[] = {
{
+ .compatible = "allwinner,suniv-f1c100s-display-backend",
+ .data = &suniv_backend_quirks,
+ },
+ {
.compatible = "allwinner,sun4i-a10-display-backend",
.data = &sun4i_backend_quirks,
},
--- a/drivers/phy/allwinner/phy-sun4i-usb.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c 2020-01-21 19:26:46.542638322 +0800
@@ -98,6 +98,7 @@
#define POLL_TIME msecs_to_jiffies(250)
enum sun4i_usb_phy_type {
+ suniv_phy,
sun4i_a10_phy,
sun6i_a31_phy,
sun8i_a33_phy,
@@ -859,6 +860,14 @@
return 0;
}
+static const struct sun4i_usb_phy_cfg suniv_cfg = {
+ .num_phys = 1,
+ .type = suniv_phy,
+ .disc_thresh = 3,
+ .phyctl_offset = REG_PHYCTL_A10,
+ .dedicated_clocks = true,
+};
+
static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
.num_phys = 3,
.type = sun4i_a10_phy,
@@ -973,6 +982,7 @@
};
static const struct of_device_id sun4i_usb_phy_of_match[] = {
+ { .compatible = "allwinner,suniv-usb-phy", .data = &suniv_cfg },
{ .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
{ .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
{ .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg },
--- a/drivers/usb/musb/sunxi.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/usb/musb/sunxi.c 2020-01-21 19:26:46.542638322 +0800
@@ -714,14 +714,16 @@
INIT_WORK(&glue->work, sunxi_musb_work);
glue->host_nb.notifier_call = sunxi_musb_host_notifier;
- if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb"))
+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb") ||
+ of_device_is_compatible(np, "allwinner,suniv-musb"))
set_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags);
if (of_device_is_compatible(np, "allwinner,sun6i-a31-musb"))
set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb") ||
- of_device_is_compatible(np, "allwinner,sun8i-h3-musb")) {
+ of_device_is_compatible(np, "allwinner,sun8i-h3-musb") ||
+ of_device_is_compatible(np, "allwinner,suniv-musb")) {
set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
set_bit(SUNXI_MUSB_FL_NO_CONFIGDATA, &glue->flags);
}
@@ -812,6 +814,7 @@
}
static const struct of_device_id sunxi_musb_match[] = {
+ { .compatible = "allwinner,suniv-musb", },
{ .compatible = "allwinner,sun4i-a10-musb", },
{ .compatible = "allwinner,sun6i-a31-musb", },
{ .compatible = "allwinner,sun8i-a33-musb", },
--- a/drivers/video/fbdev/core/fbcon.c 2019-08-29 14:30:28.000000000 +0800
+++ b/drivers/video/fbdev/core/fbcon.c 2020-01-21 19:26:46.542638322 +0800
@@ -368,6 +368,7 @@
static void fb_flashcursor(struct work_struct *work)
{
+#if 0
struct fb_info *info = container_of(work, struct fb_info, queue);
struct fbcon_ops *ops = info->fbcon_par;
struct vc_data *vc = NULL;
@@ -398,6 +399,7 @@
ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
console_unlock();
+#endif
}
static void cursor_timer_handler(struct timer_list *t)
感谢楼主分享!
找到原因了, 发现这个文件视频用hevc编码, 音频aac,
我查了一下, hevc 是微软扩展的h.265格式(难道又要分裂h.265???),
所以大部分浏览器无法直接播放视频, 只能听到声音,
而用微软最新的 edge 浏览器是可以播放一楼的视频。
win/linux 可用 ffmpeg 重新转一下格式
windows 可执行的 ffmpeg.exe 在这里下载:
http://www.ffmpeg.org/download.html
可以用这个命令:
ffmpeg.exe -i 1585463237885.mp4 -vcodec libx264 -acodec copy 1585463237885.mp4
或这个命令转码:
ffmpeg.exe -i 1585463237885.mp4 -vcodec libx264 -acodec copy 1585463237885.mp4
参考这个: https://whycan.cn/t_3781.html#p36600
试一试,第三步,只删除Qt的那个配置文件
@路漫漫 大神的固件试一试: https://whycan.cn/t_3400.html
在一个QQ群里面,发了下拼团的分享链接,结果:
https://whycan.cn/files/members/1569/TIM截图20200329120132.png
清库存基本不可能,谁会贴本清库存嘛,明显是为了推广新产品。
按着楼主的步骤一步一步走,发现编译出来的buildroot 达到98MB,不知道有没有类似问题。
root@eedccd40ec5a:~/buildroot/buildroot-2017.08/output/images# ll
-rw-r--r-- 1 root root 98119680 Mar 26 19:13 rootfs.tar
a) 打开 ~/buildroot/buildroot-2017.08/.config 文件, 把里面的 QT/MPLAYER 等相关行删掉,
b) make menuconfig 里面把 Qt/mplayer 相关软件包删除
上面两步操作等效。
然后按这个操作重新做一次即可: https://whycan.cn/t_3781.html#p36600
一楼更新了楼主的视频: https://whycan.cn/t_3914.html#p36184
用widora这个可以加速: https://g.widora.cn/
晕哥,你好。请问固件支持spi nand吗?还有个问题,v3s只有64M,运行qt5稳定吗?之前在qt官方,看到建议256M运行内存。谢谢
主线linux支持spi nand很麻烦,但是仍然是可以的: https://whycan.cn/t_3123.html
全志官方sdk也支持 spi nand
逻辑分析仪,PulseView:https://sigrok.org/wiki/PulseView
这个确实不错
感谢楼主 @Iron 分享宝贵经验, 为了方便给位老友搜索, 特加入本站精华帖
111. 关于 lichee-pi zero V3s 以太网硬件严重发热问题和解决办法 by @Iron
晕哥,在spi-flash上用主线uboot+主线linux是没问题的,我现在用的是spi-nand,所以只能用这个改版的uboot,内核就起不来了。
那你参考这个V3s openwrt @spi nand帖子: https://whycan.cn/t_3123.html
代码在这里: https://github.com/bhorn/openwrt/tree/dolphinpi-spinand
感谢楼主的支持, 我列个索引方便大家查看:
[正点原子i.MX6UL开发板] 开箱与固件烧录 by Jmhh247
[正点原子i.MX6UL开发板] 编译uboot、linux、buildroot-rootfs by Jmhh247
[正点原子i.MX6UL开发板] v4l2+framebuffer预览USB摄像头(一):采集拍照 by Jmhh247
[正点原子i.MX6UL开发板] v4l2+framebuffer预览USB摄像头(二):显示照片 by Jmhh247
@staunchheart 感谢分享, 为了方便给位老友搜索, 特加入本站精华帖
110. F1C100S下LittleVgl+RTT触摸、GT911、看门狗踩坑记录 by @staunchheart
感谢楼主分享, TF卡镜像文件已经传给我了, 晚点我分享到百度云.
更新:
------------------
链接: https://pan.baidu.com/s/1FVu9c3m7peLN3iCnQPlrcA
密码:5him
128脚DEMO版资料能不能发给我一下。谢谢!xidaole@163.com
应该是说这个吧: https://whycan.cn/t_3844.html
@JinC 感谢分享, 为了方便给位老友搜索, 特加入本站精华帖
100. 荔枝派zero/小智极客S3/V3s使用sunxi-fel 借 u-boot 启动 Linux系统, 无需 spi flash / TF 卡 by@JinC
感谢分享!
其他关于 F1C100s 软重启的讨论:
1. F1C100S linux-4.15 无法软件重启的问题原因 @by 阿黄
2. f1c100s使用linux4.19可以正常reboot,但是otg该怎么配置才正确啊?
3. 全志F1C100S LicheePi Nano 4.14版 kernel 无法reboot
https://blog.csdn.net/mike8825/article/details/51171055
https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/errno-base.h
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_GENERIC_ERRNO_BASE_H
#define _ASM_GENERIC_ERRNO_BASE_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#endif
看起来是目录或文件不存在: No such file or directory
谢谢楼主的分享,很详细。但是我在编译make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4的时候出现了
binman: Node '/binman/u-boot-img': Entry contents size is 0xa6fa9 (683945) but entry size is 0x7e000 (516096)
Makefile:1148: recipe for target 'u-boot-sunxi-with-spl.bin' failed
make: *** [u-boot-sunxi-with-spl.bin] Error 1
这个错误。我也不知道是什么原因,是之前配置可视化出错了吗?
参考: https://whycan.cn/t_3631.html#p33896
可能是: 编译出来的uboot体积太大了,使用空间和env环境的地址冲突了,将env环境的地址调大一点