比较了以下 ddr3 和 ddr2 初始化:
https://github.com/u-boot/u-boot/blob/master/arch/arm/mach-sunxi/dram_timings/ddr3_1333.c
#include <common.h>
#include <asm/arch/dram.h>
#include <asm/arch/cpu.h>
void mctl_set_timing_params(uint16_t socid, struct dram_para *para)
{
struct sunxi_mctl_ctl_reg * const mctl_ctl =
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
u8 tccd = 2;
u8 tfaw = ns_to_t(50);
u8 trrd = max(ns_to_t(10), 4);
u8 trcd = ns_to_t(15);
u8 trc = ns_to_t(53);
u8 txp = max(ns_to_t(8), 3);
u8 twtr = max(ns_to_t(8), 4);
u8 trtp = max(ns_to_t(8), 4);
u8 twr = max(ns_to_t(15), 3);
u8 trp = ns_to_t(15);
u8 tras = ns_to_t(38);
u16 trefi = ns_to_t(7800) / 32;
u16 trfc = ns_to_t(350);
u8 tmrw = 0;
u8 tmrd = 4;
u8 tmod = 12;
u8 tcke = 3;
u8 tcksrx = 5;
u8 tcksre = 5;
u8 tckesr = 4;
u8 trasmax = 24;
u8 tcl = 6; /* CL 12 */
u8 tcwl = 4; /* CWL 8 */
u8 t_rdata_en = 4;
u8 wr_latency = 2;
u32 tdinit0 = (500 * CONFIG_DRAM_CLK) + 1; /* 500us */
u32 tdinit1 = (360 * CONFIG_DRAM_CLK) / 1000 + 1; /* 360ns */
u32 tdinit2 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */
u32 tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */
u8 twtp = tcwl + 2 + twr; /* WL + BL / 2 + tWR */
u8 twr2rd = tcwl + 2 + twtr; /* WL + BL / 2 + tWTR */
u8 trd2wr = tcl + 2 + 1 - tcwl; /* RL + BL / 2 + 2 - WL */
/* set mode register */
writel(0x1c70, &mctl_ctl->mr[0]); /* CL=11, WR=12 */
writel(0x40, &mctl_ctl->mr[1]);
writel(0x18, &mctl_ctl->mr[2]); /* CWL=8 */
writel(0x0, &mctl_ctl->mr[3]);
if (socid == SOCID_R40)
writel(0x3, &mctl_ctl->lp3mr11); /* odt_en[7:4] */
/* set DRAM timing */
writel(DRAMTMG0_TWTP(twtp) | DRAMTMG0_TFAW(tfaw) |
DRAMTMG0_TRAS_MAX(trasmax) | DRAMTMG0_TRAS(tras),
&mctl_ctl->dramtmg[0]);
writel(DRAMTMG1_TXP(txp) | DRAMTMG1_TRTP(trtp) | DRAMTMG1_TRC(trc),
&mctl_ctl->dramtmg[1]);
writel(DRAMTMG2_TCWL(tcwl) | DRAMTMG2_TCL(tcl) |
DRAMTMG2_TRD2WR(trd2wr) | DRAMTMG2_TWR2RD(twr2rd),
&mctl_ctl->dramtmg[2]);
writel(DRAMTMG3_TMRW(tmrw) | DRAMTMG3_TMRD(tmrd) | DRAMTMG3_TMOD(tmod),
&mctl_ctl->dramtmg[3]);
writel(DRAMTMG4_TRCD(trcd) | DRAMTMG4_TCCD(tccd) | DRAMTMG4_TRRD(trrd) |
DRAMTMG4_TRP(trp), &mctl_ctl->dramtmg[4]);
writel(DRAMTMG5_TCKSRX(tcksrx) | DRAMTMG5_TCKSRE(tcksre) |
DRAMTMG5_TCKESR(tckesr) | DRAMTMG5_TCKE(tcke),
&mctl_ctl->dramtmg[5]);
/* set two rank timing */
clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0),
((socid == SOCID_H5 ? 0x33 : 0x66) << 8) | (0x10 << 0));
/* set PHY interface timing, write latency and read latency configure */
writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) |
(wr_latency << 0), &mctl_ctl->pitmg[0]);
/* set PHY timing, PTR0-2 use default */
writel(PTR3_TDINIT0(tdinit0) | PTR3_TDINIT1(tdinit1), &mctl_ctl->ptr[3]);
writel(PTR4_TDINIT2(tdinit2) | PTR4_TDINIT3(tdinit3), &mctl_ctl->ptr[4]);
/* set refresh timing */
writel(RFSHTMG_TREFI(trefi) | RFSHTMG_TRFC(trfc), &mctl_ctl->rfshtmg);
}
https://github.com/u-boot/u-boot/blob/master/arch/arm/mach-sunxi/dram_timings/ddr2_v3s.c
#include <common.h>
#include <asm/arch/dram.h>
#include <asm/arch/cpu.h>
void mctl_set_timing_params(uint16_t socid, struct dram_para *para)
{
struct sunxi_mctl_ctl_reg * const mctl_ctl =
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
u8 tccd = 1;
u8 tfaw = ns_to_t(50);
u8 trrd = max(ns_to_t(10), 2);
u8 trcd = ns_to_t(20);
u8 trc = ns_to_t(65);
u8 txp = 2;
u8 twtr = max(ns_to_t(8), 2);
u8 trtp = max(ns_to_t(8), 2);
u8 twr = max(ns_to_t(15), 3);
u8 trp = ns_to_t(15);
u8 tras = ns_to_t(45);
u16 trefi = ns_to_t(7800) / 32;
u16 trfc = ns_to_t(328);
u8 tmrw = 0;
u8 tmrd = 2;
u8 tmod = 12;
u8 tcke = 3;
u8 tcksrx = 5;
u8 tcksre = 5;
u8 tckesr = 4;
u8 trasmax = 27;
u8 tcl = 3; /* CL 6 */
u8 tcwl = 3; /* CWL 6 */
u8 t_rdata_en = 1;
u8 wr_latency = 1;
u32 tdinit0 = (400 * CONFIG_DRAM_CLK) + 1; /* 400us */
u32 tdinit1 = (500 * CONFIG_DRAM_CLK) / 1000 + 1; /* 500ns */
u32 tdinit2 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */
u32 tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */
u8 twtp = tcwl + 2 + twr; /* WL + BL / 2 + tWR */
u8 twr2rd = tcwl + 2 + twtr; /* WL + BL / 2 + tWTR */
u8 trd2wr = tcl + 2 + 1 - tcwl; /* RL + BL / 2 + 2 - WL */
/* set mode register */
writel(0x263, &mctl_ctl->mr[0]);
writel(0x4, &mctl_ctl->mr[1]);
writel(0x0, &mctl_ctl->mr[2]);
writel(0x0, &mctl_ctl->mr[3]);
/* set DRAM timing */
writel(DRAMTMG0_TWTP(twtp) | DRAMTMG0_TFAW(tfaw) |
DRAMTMG0_TRAS_MAX(trasmax) | DRAMTMG0_TRAS(tras),
&mctl_ctl->dramtmg[0]);
writel(DRAMTMG1_TXP(txp) | DRAMTMG1_TRTP(trtp) | DRAMTMG1_TRC(trc),
&mctl_ctl->dramtmg[1]);
writel(DRAMTMG2_TCWL(tcwl) | DRAMTMG2_TCL(tcl) |
DRAMTMG2_TRD2WR(trd2wr) | DRAMTMG2_TWR2RD(twr2rd),
&mctl_ctl->dramtmg[2]);
writel(DRAMTMG3_TMRW(tmrw) | DRAMTMG3_TMRD(tmrd) | DRAMTMG3_TMOD(tmod),
&mctl_ctl->dramtmg[3]);
writel(DRAMTMG4_TRCD(trcd) | DRAMTMG4_TCCD(tccd) | DRAMTMG4_TRRD(trrd) |
DRAMTMG4_TRP(trp), &mctl_ctl->dramtmg[4]);
writel(DRAMTMG5_TCKSRX(tcksrx) | DRAMTMG5_TCKSRE(tcksre) |
DRAMTMG5_TCKESR(tckesr) | DRAMTMG5_TCKE(tcke),
&mctl_ctl->dramtmg[5]);
/* set two rank timing */
clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0),
(0x66 << 8) | (0x10 << 0));
/* set PHY interface timing, write latency and read latency configure */
writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) |
(wr_latency << 0), &mctl_ctl->pitmg[0]);
/* set PHY timing, PTR0-2 use default */
writel(PTR3_TDINIT0(tdinit0) | PTR3_TDINIT1(tdinit1), &mctl_ctl->ptr[3]);
writel(PTR4_TDINIT2(tdinit2) | PTR4_TDINIT3(tdinit3), &mctl_ctl->ptr[4]);
/* set refresh timing */
writel(RFSHTMG_TREFI(trefi) | RFSHTMG_TRFC(trfc), &mctl_ctl->rfshtmg);
}
IDE(AHL-STM32MP157-20210221.zip)下载地址: http://sumcu.suda.edu.cn/AHLwSTM32MP157/list.htm
STM32MP157快速指南: AHL-STM32MP157快速指南-20210317.pdf
比如 xboot 这个代码段重定位 https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c100s/start.S
_speedup:
nop
/* Copyself to link address */
adr r0, _start
ldr r1, =_start
cmp r0, r1
beq 1f
bl sys_copyself
第一条语句 adr r0, _start 编译后是 基于PC指针把 _start 的位置读到 r0 寄存器,
在哪个位置运行, r0 值就是多少. 比如程序在 0x800 运行, 那么 _start 就是 0x800
第二条语句 ldr r1, =_start 是取 _start 的链接地址, 也就是重定位地址.
如果 r1 与 r0 寄存器不相等, 他们肯定要进行重定位 (代码段复制)
为了证明这个问题, 我用MDK反汇编看了一下:
https://www.denx.de/wiki/publish/DULG/to-delete/UBootCmdGroupMemory.html
① 都读到内存,用cmp命令比较
② 都读到内存,比较crc值
有道理,感谢版主!
这么多元件不如加个两毛钱的单片机靠谱
因为荔枝派nano的ns2009没有接中断引脚, 所以把下面的轮询驱动:
https://github.com/Lichee-Pi/linux/blob/zero-4.13.y/drivers/input/touchscreen/ns2009.c
https://github.com/Lichee-Pi/linux/blob/zero-4.13.y/drivers/input/touchscreen/Makefile
https://github.com/Lichee-Pi/linux/blob/zero-4.13.y/drivers/input/touchscreen/Kconfig
添加到:
https://github.com/Lichee-Pi/linux/tree/nano-5.2-tf/drivers/input/touchscreen
设备树添加 ns2009:
https://github.com/Lichee-Pi/linux/blob/zero-4.13.y/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
&i2c0 {
status = "okay";
ns2009: ns2009@48 {
compatible = "nsiway,ns2009";
reg = <0x48>;
};
};
本站下载: smallwit_x3_tfcard_20201203155930.tgz
1. 解压缩, 用 win32diskimager 把 smallwit_x3_tfcard_20201203155930.img 烧录到 TF卡
2. 把TF卡插入 小智X3开发板, USB插入OTG线启动, 电脑会出现一个U盘, 不要格式化.
3. 用 win32diskimager 把你的 flash img 烧录到 那个U盘即可。
昨天试了一下小智的X3开发板,确实可以用,一开始很快,后面就很慢了,估计是windows缓冲文件系统,加上flash擦写慢引起。最后自己再手动校验一下。
F1C200s主线gstreamer使用openmax调用cedar硬解码
http://whycan.com/t_5824.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
和这个帖子配合一起看,更有参考意义,感谢楼主!
好奇搜了一下, 还真有这玩意: http://www.trivialfeat.com/home/2016/11/17/media-transfer-protocol-in-a-usb-composite-gadget
/etc/init.d/S99-gadget
#!/bin/sh
CONFIGFS="/sys/kernel/config"
GADGET="$CONFIGFS/usb_gadget"
VID="0x0000"
PID="0x0000"
SERIAL="0123456789"
MANUF="Me"
PRODUCT="Radget"
case "$1" in
start)
echo "Creating the USB gadget"
echo "Loading composite module"
modprobe libcomposite
echo "Mounting ConfigFS"
mount -t configfs none $CONFIGFS
cd $GADGET
if [ $? -ne 0 ]; then
echo "Error setting up configfs"
exit 1;
fi
echo "Creating gadget directory"
mkdir gadget
cd gadget
if [ $? -ne 0 ]; then
echo "Error creating usb gadget in configfs"
exit 1;
fi
echo "Setting Vendor and Product ID's"
echo $VID > idVendor
echo $PID > idProduct
echo "Setting English strings"
mkdir strings/0x409
echo $SERIAL > strings/0x409/serialnumber
echo $MANUF > strings/0x409/manufacturer
echo $PRODUCT > strings/0x409/product
echo "Setting configuration"
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "CDC ACM + MTP + Mass Storage" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
echo "Creating ACM interface"
mkdir functions/acm.GS0
ln -s functions/acm.GS0 configs/c.1
echo "Creating MTP interface"
mkdir functions/mtp.mtp
ln -s functions/mtp.mtp configs/c.1
mkdir /dev/mtp
mount -t functionfs mtp /dev/mtp
echo "Creating Mass Storage interface"
mkdir functions/mass_storage.ms0
echo "/dev/mmcblk0" > functions/mass_storage.ms0/lun.0/file
echo "1" > functions/mass_storage.ms0/lun.0/removable
ln -s functions/mass_storage.ms0 configs/c.1/mass_storage.ms0
echo "Binding USB Device Controller"
echo `ls /sys/class/udc` > UDC
echo "Starting the MTP responder daemon"
mtp-server &
;;
stop)
echo "Stopping the USB gadget"
echo "Killing MTP responder daemon"
killall mtp-server
cd $GADGET/gadget
if [ $? -ne 0 ]; then
echo "Error: no configfs gadget found"
exit 1;
fi
echo "Unbinding USB Device Controller"
echo "" > UDC
echo "Removing Mass Storage interface"
rm configs/c.1/mass_storage.ms0
rmdir functions/mass_storage.ms0
echo "Removing MTP interface"
umount /dev/mtp
rmdir /dev/mtp
rm configs/c.1/mtp.mtp
rmdir functions/mtp.mtp
echo "Removing ACM interface"
rm configs/c.1/acm.GS0
rmdir functions/acm.GS0
echo "Clearing English strings"
rmdir strings/0x409
echo "Cleaning up configuration"
rmdir configs/c.1/strings/0x409
rmdir configs/c.1
echo "Removing gadget directory"
cd $GADGET
rmdir gadget
cd /
echo "Unmounting ConfigFS"
umount $CONFIGFS
;;
esac
请问全志V3s使用荔枝派最新的 linux 4.13-y 分支,如何支持声卡?
http://whycan.com/t_489.html#p1595
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
楼主, 给你关键字和链接: SER_RS485_RTS_AFTER_SEND SER_RS485_ENABLED
https://elixir.bootlin.com/linux/v5.4.77/source/drivers/tty/serial/imx.c#L445
https://elixir.bootlin.com/linux/v5.4.77/source/drivers/tty/serial/omap-serial.c#L310
全志的uart驱动修改这个文件就可以了:
https://elixir.bootlin.com/linux/v5.4.77/source/drivers/tty/serial/8250/8250_port.c#L1488
https://elixir.bootlin.com/linux/v5.4.77/source/include/linux/serial_8250.h#L101
照猫画虎, 在这里面实现控制即可:
serial8250_start_tx( )
serial8250_stop_tx( )
https://www.cnblogs.com/leisure_chn/p/10381616.html
https://cloud.tencent.com/developer/article/1409518
dts配置了吗?
最近做个8X11行列键盘,我测试都很好,但是客户说有漏按键的。各位有什么经验介绍一下?
http://whycan.com/t_645.html#p14763
(出处:哇酷开发者社区【Cortex M0/M3/M4/M7】)
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
http://whycan.com/t_5221.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
http://whycan.com/t_5221.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
发现一个好用的一个正则表达式可视化网站 https://regexper.com/
aodzip的sdk不香吗?
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
http://whycan.com/t_5221.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
关于Ubuntu 18.04下编译 SSD202D(卖家给的SDK)的文件无法通过uboot更新到nand上的问题
http://whycan.com/t_5370.html
(出处:哇酷开发者社区【DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/】)
有网友已经玩起来了
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
http://whycan.com/t_5221.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
用这个,然后勾选Qt就可以生成烧写镜像了。
底部的GND焊了,PCB上特地挖了个大的过孔。
今天坑网似乎有问题,原理图一直没上传成功。
如何在本站发图片, 顺便吐槽功能弱智的phpbb半自动步木仑
http://whycan.com/t_588.html#p16351
(出处:哇酷开发者社区【站务公告/网站建设】)
可能上传成功了,要点插入才行。
分享全志主线u-boot/linux 打包 TF/SD/SDNAND 镜像脚本
http://whycan.com/t_4008.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
分享一个2011年在魅族M9上跑的一个framebuffer plasma 测试程序
http://whycan.com/t_3492.html
(出处:哇酷开发者社区【DIY/综合/Arduino/写字机/3D打印机/智能小车/平衡车/四轴飞行/】)
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
http://whycan.com/t_5221.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
最新的tiny200 sdk已经包含了上面的cedarc
三木同子 说:另外还想请教你一个问题,DB0-DB17怎么知道哪个是分别对应R,G,B?
本站不知道哪个帖子(找不到了)里有份全志A10 LCD的文档,有列出来。
v3s和LCD通过i8080总线模式
http://whycan.com/t_900.html#p3678
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
是这个吗?
我做过驱动MT7688 (widora neo 开发板) 驱动 PCM5102A 声卡的,也是没有I2C控制的, 直接I2S输入输出.
https://whycan.cn/files/members/3/QQ20180407173256.jpg
https://whycan.cn/files/members/3/QQ20180407173253.jpg
https://whycan.cn/files/members/3/QQ20180407173247.jpg
https://whycan.cn/files/members/3/QQ20180407173258.png
原理就是创建一张无需codec的虚拟声卡,然后把MT7688的i2s设置为master(非常重要!!!)
widora的代码驱动WM8960声卡, 声卡处于主模式, 时钟是WM8960提供给MT7688的,
如果用NS4168这种不能作为I2S master的声卡,一定要把mt7688改为master.
这操作够骚,学到了。
仿照aodzip给buildroot打补丁
buildroot-tiny200 (F1C100/200s) 开发包近期更新内容 * 已支持DVP摄像头 *
http://whycan.com/t_5221.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)
收到,感谢大佬分享,我先试一试看疗效。
密钥这样放就可以,没必要放/etc目录:
感谢楼主分享宝贵教程,
说句实在话,PyQt5 真香: https://stackoverflow.com/questions/51828943/pyqt5-and-subprocess-popen
可以直接用串口登录X3就可以编程了,无需再烧录:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Console(QtWidgets.QWidget):
errorSignal = QtCore.pyqtSignal(str)
outputSignal = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.editor = QtWidgets.QPlainTextEdit(self)
self.editor.setReadOnly(True)
self.font = QtGui.QFont()
# self.font.setFamily(editor["editorFont"])
self.font.setPointSize(12)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.editor, 1)
self.setLayout(self.layout)
self.output = None
self.error = None
self.editor.setFont(self.font)
self.process = QtCore.QProcess()
self.process.readyReadStandardError.connect(self.onReadyReadStandardError)
self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)
def onReadyReadStandardError(self):
error = self.process.readAllStandardError().data().decode()
self.editor.appendPlainText(error)
self.errorSignal.emit(error)
def onReadyReadStandardOutput(self):
result = self.process.readAllStandardOutput().data().decode()
self.editor.appendPlainText(result)
self.outputSignal.emit(result)
def run(self, command):
"""Executes a system command."""
# clear previous text
self.editor.clear()
self.process.start(command)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Console()
w.show()
w.errorSignal.connect(lambda error: print(error))
w.outputSignal.connect(lambda output: print(output))
w.run("ping 8.8.8.8 -c 100")
sys.exit(app.exec_())
这是一个随意调用外部命令,输出日志随意显示到Qt5的例程.