页次: 1
齐活了,将R45 R47加大为220r,最大音量下底噪也几乎完全消失,或许阻值再小点也可以,现在最大音量变小了些,跟手机最大音量差不多了。
耳机的音量旋钮本质上就是个电位器串联分压,调整直至观察到底噪消失时,用万用表测量耳机单声道的特性阻抗,测出耳机的特性阻抗增量大概200r,于是我将插座末端47r改为220r,起到了相同的效果。
asound.state改了一点,第一项Headphone拉满,第七项DAC拉到87(dB gain: -3.48),基本就是把之前设置的音量调大了一些
state.Loopback {
control.1 {
iface PCM
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.2 {
iface PCM
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.3 {
iface PCM
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.4 {
iface PCM
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.5 {
iface PCM
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.6 {
iface PCM
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.7 {
iface PCM
subdevice 1
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.8 {
iface PCM
subdevice 1
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.9 {
iface PCM
subdevice 1
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.10 {
iface PCM
subdevice 1
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.11 {
iface PCM
subdevice 1
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.12 {
iface PCM
subdevice 1
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.13 {
iface PCM
subdevice 2
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.14 {
iface PCM
subdevice 2
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.15 {
iface PCM
subdevice 2
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.16 {
iface PCM
subdevice 2
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.17 {
iface PCM
subdevice 2
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.18 {
iface PCM
subdevice 2
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.19 {
iface PCM
subdevice 3
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.20 {
iface PCM
subdevice 3
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.21 {
iface PCM
subdevice 3
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.22 {
iface PCM
subdevice 3
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.23 {
iface PCM
subdevice 3
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.24 {
iface PCM
subdevice 3
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.25 {
iface PCM
subdevice 4
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.26 {
iface PCM
subdevice 4
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.27 {
iface PCM
subdevice 4
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.28 {
iface PCM
subdevice 4
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.29 {
iface PCM
subdevice 4
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.30 {
iface PCM
subdevice 4
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.31 {
iface PCM
subdevice 5
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.32 {
iface PCM
subdevice 5
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.33 {
iface PCM
subdevice 5
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.34 {
iface PCM
subdevice 5
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.35 {
iface PCM
subdevice 5
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.36 {
iface PCM
subdevice 5
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.37 {
iface PCM
subdevice 6
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.38 {
iface PCM
subdevice 6
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.39 {
iface PCM
subdevice 6
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.40 {
iface PCM
subdevice 6
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.41 {
iface PCM
subdevice 6
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.42 {
iface PCM
subdevice 6
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.43 {
iface PCM
subdevice 7
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.44 {
iface PCM
subdevice 7
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.45 {
iface PCM
subdevice 7
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.46 {
iface PCM
subdevice 7
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.47 {
iface PCM
subdevice 7
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.48 {
iface PCM
subdevice 7
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.49 {
iface PCM
device 1
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.50 {
iface PCM
device 1
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.51 {
iface PCM
device 1
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.52 {
iface PCM
device 1
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.53 {
iface PCM
device 1
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.54 {
iface PCM
device 1
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.55 {
iface PCM
device 1
subdevice 1
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.56 {
iface PCM
device 1
subdevice 1
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.57 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.58 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.59 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.60 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.61 {
iface PCM
device 1
subdevice 2
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.62 {
iface PCM
device 1
subdevice 2
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.63 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.64 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.65 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.66 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.67 {
iface PCM
device 1
subdevice 3
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.68 {
iface PCM
device 1
subdevice 3
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.69 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.70 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.71 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.72 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.73 {
iface PCM
device 1
subdevice 4
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.74 {
iface PCM
device 1
subdevice 4
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.75 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.76 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.77 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.78 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.79 {
iface PCM
device 1
subdevice 5
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.80 {
iface PCM
device 1
subdevice 5
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.81 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.82 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.83 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.84 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.85 {
iface PCM
device 1
subdevice 6
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.86 {
iface PCM
device 1
subdevice 6
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.87 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.88 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.89 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.90 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.91 {
iface PCM
device 1
subdevice 7
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.92 {
iface PCM
device 1
subdevice 7
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.93 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.94 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.95 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.96 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
}
state.Codec {
control.1 {
iface MIXER
name 'DAC Playback Volume'
value 60
comment {
access 'read write'
type INTEGER
count 1
range '0 - 63'
dbmin -7308
dbmax 0
dbvalue.0 -348
}
}
control.2 {
iface MIXER
name 'Headphone Playback Volume'
value 63
comment {
access 'read write'
type INTEGER
count 1
range '0 - 63'
dbmin -9999999
dbmax 0
dbvalue.0 0
}
}
control.3 {
iface MIXER
name 'Headphone Playback Switch'
value.0 true
value.1 true
comment {
access 'read write'
type BOOLEAN
count 2
}
}
control.4 {
iface MIXER
name 'Line In Playback Volume'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 -450
}
}
control.5 {
iface MIXER
name 'FM In Playback Volume'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 -450
}
}
control.6 {
iface MIXER
name 'Mic In Playback Volume'
value 7
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 600
}
}
control.7 {
iface MIXER
name 'Mic Boost Volume'
value 7
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin 0
dbmax 4200
dbvalue.0 4200
}
}
control.8 {
iface MIXER
name 'ADC Capture Volume'
value 7
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 600
}
}
control.9 {
iface MIXER
name 'ADC Mixer Right Out Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.10 {
iface MIXER
name 'ADC Mixer Left Out Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.11 {
iface MIXER
name 'ADC Mixer Line In Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.12 {
iface MIXER
name 'ADC Mixer Right FM In Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.13 {
iface MIXER
name 'ADC Mixer Left FM In Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.14 {
iface MIXER
name 'ADC Mixer Mic Capture Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.15 {
iface MIXER
name 'Left Mixer Right DAC Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.16 {
iface MIXER
name 'Left Mixer Left DAC Playback Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.17 {
iface MIXER
name 'Left Mixer FM In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.18 {
iface MIXER
name 'Left Mixer Line In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.19 {
iface MIXER
name 'Left Mixer Mic In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.20 {
iface MIXER
name 'Right Mixer Left DAC Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.21 {
iface MIXER
name 'Right Mixer Right DAC Playback Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.22 {
iface MIXER
name 'Right Mixer FM In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.23 {
iface MIXER
name 'Right Mixer Line In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.24 {
iface MIXER
name 'Right Mixer Mic In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.25 {
iface MIXER
name 'Headphone Source Playback Route'
value.0 Mixer
value.1 Mixer
comment {
access 'read write'
type ENUMERATED
count 2
item.0 DAC
item.1 Mixer
}
}
}
很完整了,不过还是喜欢跑debian,然后通过pc联网这样想装啥apt就搞定了。f1c的声卡驱动是怎么配置的
声卡配置和电路和上面10楼是一样的。刚刚说的有点不对,由于声卡输出音量非常大,现在是手动把耳机上的旋钮调小了,调小状态是没有底噪的,而且音量依旧蛮大的。耳机上的旋钮我猜就是个电位器(我耳机的声卡是外置的usb声卡,所以整个耳机都是模拟音频),也就是说提高输出阻抗,底噪可以减小到一个令人满意的水平,过会我再去改改音频电路。
网卡我这里倒是调通了,能把150m带宽跑满,但蓝牙始终不好使,偶尔能搜到设备,但配对连不上。。这个usb接口的8723bu的资料少得可怜,github上写这个驱动的没几个人,重点也都是在wifi上,所以最后干脆我就给拆掉了,留个usb-a接键盘。
大学入学以后有时间用手头的f133重制一次这个项目,用sdio的8723bs。
以及:
基本所有的外设驱动都调好了
spi1上挂的ds1302 xpt2046 st7789v内核里都有驱动,但是由于ds1302是三线spi所以我用了个自己写的模拟spi驱动,导致总线上其他的设备也都不敢直接用内核驱动,同时st7789v也只是用spi总线初始化为rgb总线模式,所以就都自己写了
lradc由于电路画的有问题,所以我把内核的驱动魔改成了轮询模式,并且魔改成了能够同时按多个键。
顺便吐槽lradc写着检测电压是0-2.5v,结果工作的逻辑却是从3v下落到2.5v来触发中断。。而我的按键电路是0v上升到某电压值。。
电源管理方面,在uboot的broad_init里拉高控制mos管的gpio,实现了按开机键大概2s开机
然后kernel里poweroff指令会调用halt指令,最后会进一个函数,在这个函数里拉低gpio,从而实现程序关机
然而reboot指令执行完,芯片硬件重启后,gpio的dr寄存器会被初始化成0,然后就掉电了。。所以reboot不能实现了
然后是裁减了buildroot,和别的一起放入了32MB的nor flash
由于rtl8723bu的蓝牙始终调不通,而且f1c的usb只能挂一个设备,我就干脆吧网卡拆下来了,所以内核和根文件系统的所有网络功能都关掉了。
编译的组件有高度裁剪的ffmpeg(由于f1c的视频解码能力太鸡肋,所以裁剪了大部分视频格式),alsa,tslib(buildroot里那个不知道为什么一直调不通,用的是自己移植的)
最后裁剪完的空间分配是
uboot 0x0 - 0x48000 288k 实际使用244k
dtb 0x48000 - 0x50000 32k 实际使用12k
linux 0x50000 - 0x400000 3776k 实际使用2992k
rootfs 0x400000 - 0x2000000 28672k 实际使用16M,然而已经卡的要死了
启动时间从上电到命令行大概在10s左右(kernel大概需要7s),而用tf卡做rootfs从上电到进入命令行只需要6s左右,主要是spi nor的性能太差,挂载rootfs前kernel只需要2s不到,挂载rootfs要卡好几秒,而且设备树里调高spi0频率会导致读写错误,但我看w25q256jv手册写最高读写是133M,而且全志的spi最高也是100M,按理来说是没问题的,可能是因为我板子的spi不等长吧。
最后用指令测试了没有mpv播放器情况下的ffmpeg是否正常工作
ffmpeg -i xxx.mp3 -f alsa hw
ffmpeg -i xxx.flac -f s16le - | aplay -f S16_le -r 192000 -c 2 192kHz的flac受限于ddr频率,通过上面的方法播放会很卡,然而通过管道传给aplay线程播放就一点问题没有,不知道什么原理
话说f1c的音频dac和外围电路调教好了音质居然意外的还不错,现在我调的一点底噪都没有,感觉和我电脑的主板声卡放音没什么两样,而且声音可以非常巨大。。
@f_Endman
感谢分享,学到了。更进一步的想到__image_file_start的地址在不同介质都是一样的吗?spi flash,nand flash,sd卡,如果应用是在其他两种介质,代码拷贝程序需要做相应移植吧。
除了要写相应介质的读写函数,全志的brom是从sd卡第8k字节开始读的,对于nand,brom更是会只读每块的前1k字节,这些需要程序来区分相应操作。
我这里可以直接使用__image_file_start是因为sram阶段的代码是位置无关码,是从0地址开始链接的,则此处__image_file_start的大小就是sram阶段代码的大小
@f_Endman
和实验不符呀,改成0x80000000,似乎没有进入ddr启动应用。是不是可以用ida pro分析二进制程序,找到__image_start 的实际地址
我试了一下,在main.c中
extern unsigned int __image_start;
……
puts("__image_start: ");
PrintHex(&__image_start);
可输出__image_start: 0x80000000
而如果直接
extern unsigned int __image_start;
……
puts("__image_start: ");
PrintHex(__image_start);
输出则是__image_start: 0xEA00009D,这应该是一条机器码,对应的大概是start.s中的那句b main
可得出结论:链接脚本中定义__image_start=.对应的是定义一个__image_start“指针变量”,指向定位器符号“.”,在这里是0x80000000(实质就是定义了一个汇编标号,指向0x80000000)
进一步验证的话,我把boot0.s中第58行改成
/* 跳转到DDR */
/* b __image_start */
b 0x80000000
codeloder.c中Boot_Load_Code函数改成
/* 加载程序 */
void Boot_Load_Code(void)
{
Boot_SPI0_Init();
Boot_SPI_Flash_Read((unsigned int)&__image_file_start, (unsigned int*)0x80000000/*&__image_start*/, &__image_end - &__image_start);
Boot_SPI0_Exit();
}
程序正常启动并运行
链接脚本的逻辑过于贴近底层,设计上就是为了汇编服务的,内部定义的“变量”直接就是汇编里的标号,可以直接作为b指令的地址参数。
又经过一系列实验,发现在链接脚本里定义标号似乎只能通过
.=0x80000000;
__image_start=.;
直接__image_start=0x80000000则是直接定义了一个指向0x00000000的标号
听到些许质疑声,想了想我还是说下我的历程吧
我小学初中基本每年都有小半个学期不去,就算去学校也是三天打鱼两天晒网。
六年级被玩游戏网上认识的一个朋友带着自己焊板子,一开始是功放,就是这时候我学会了用记号笔在覆铜板上画电路或热转印加化学蚀刻和手工做uv固化绿油等一系列手艺。后来他提到单片机,然后他去玩了树莓派,还用那玩意挖矿(现在想想他还挺超前的?)。。
我一开始自己焊51的板子,最早甚至用的都是跟功放ic顺便买来的51加上从不知道哪里拆下来的频率诡异的晶振在洞洞板上焊的,我就用这玩意完成了第一次点灯,然后买了郭天祥那本书,用洞洞板正经焊了个最小系统板,一边看一边在keil上一点一点写东西,还用洞洞板做了很多模块。
再后来又发现淘宝店卖stm32的最小系统板,比51nb多了,于是开始玩stm32,跟着网上搜的教学视频用st的库文件写程序,点了lcd,点了摄像头,然后又用ad学着画起了pcb,自己做了块f103zet6的带lcd 摄像头 sram的开发板(那时候没钱,抠门的要死,救世主jlc也没出现,打板加上各种ic购置是下了挺大决心才弄下来的),这时候差不多是我初中快毕业了。。
在这之前,由于我爸是搞机械的,他或许是看我在家精神状态不好,找了一个挺简单的声音检测分拣的工业项目带我出去大老远去干,估计一开始也没想让我搞成,最后我用低成本51加声强检测模块然后驱动步进电机分拣弄出来了,但最后由于那个机器太过嘈杂,改成我爸重新设计机器了,后来是他用的专业的控制器自己弄的了,我就不清楚了。
之后高一疫情那会自己在家用木头(现在想想都觉得离谱)和网上买来的乱七八糟的零件搭了一台3d打印机,然后最搞的是我那时候自命不凡,完全没用开源的库,硬是自己堆出来了一个不完全的g代码解释器,还有三轨步进电机的同步加速算法(现在想想有很多问题),然后跑在了我那个stm32的开发板上,自己搭起了一个四通道的步进电机驱动板,和一个mos管的加热驱动电路,然后再用pid控温。。但由于用的木头实在是太垃圾了,精度低不说,有的时候直接卡住,后来螺杆都弯了,再加上拧各种螺丝,锯各种木头,那段时间手每天都在疼,直接给我干了个精神创伤,一气之下给拆了。
然后我好像就没再怎么继续玩stm32了,最后的印象就是在上面移植lvgl。。
后来看到稚晖君发的小电脑的视频,顺着了解到荔枝派,发现这才是我一直想找的东西,然后买了个荔枝派到手,,结果发现这东西简直对新手太不友好了,于是我又买了某原子的imx开发板跟着视频学,他那个视频一开始写的裸机,还教了怎么写BootLoader,于是后来我找到这个论坛后第一个贴就是写的f1c100s的裸机BootLoader。
最后就到了这个板子。这是我7年断断续续的浅薄的经验积淀下来的。
但要说我花了多少心思在这上面,其实也没有。从小经常辍学,和父母对着干,后来都搞的抑郁了,但好在课没落下,这才考了个最差的公立高中。。从小到大由于小半的时间都没去学校,我在各种游戏、乐器、绘画上也都有接触,但最让我感兴趣的还是写程序,积淀下来最多也是这个。高中还用C#写过一个"特殊用途"的手机APP,和(给一个沙雕同学写的)fps图像识别锁轮廓的游戏外挂,鼠标运动算法用的pid,被他称赞为他见过非暴力锁的最准的挂(是不是前后都连上了),当然他发誓从没开挂打pvp(拿亲m发誓的那种)。哦,说来我面向对象和.NET C#还是在一个可以内置编程的太空沙盒游戏里跟着大佬零零星星的教学自学的(是不是又连上了)
最后要说背后有谁提点过的话,大概是一开始那个网友、郭天祥老师、某原子哥,和我辍学在家也没把我赶出去还给我支持的爸妈,剩下的就靠我从几乎小与生俱来的可谓莫名其妙的兴趣
闲着没事干(指还有一个多月高考),花了半天把NES模拟器移植上来了,用的这个arm-NES-linux,但这个是直接写fb的方式,背后的控制台还在不停刷新,很烦人。。于是我就浅改了一下,搞成drm的了,可以单独显示了。不过声音非常抽象,延迟有几秒,而且模拟器速度快了一点,不过总之是别人在别的平台上移植的,我也没改,效果还算差强人意。视频里没插耳机,太辣耳朵了
现在WiFi是调通了,TCP双向45Mbps,但是蓝牙始终不行。蓝牙能够扫描到手机,尝试连接无报错但也无反应。。有没有人用过rtl8723bu这个模块调通蓝牙的朋友,分享一下怎么弄得。
我用的这个驱动https://github.com/SonelSA/rtl8723bu_realtek,而不是内核里的驱动,内核驱动WiFi能通,但是芯片发热很严重,并且速度缓慢,蓝牙也还是不行。问题相关现象我在上面git仓库里发了一个issue。
顺便f1c200s的USB只能挂载3个节点是我没想到的,我整一个hub芯片直接白费了。。还有usb-a和5v升压也白搞了。。
音频codec电路已经调到比较理想状态了,声卡驱动参考https://whycan.com/t_2041.html,我的alsa设置(主要是Codec的control1和2影响比较大):
state.Loopback {
control.1 {
iface PCM
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.2 {
iface PCM
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.3 {
iface PCM
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.4 {
iface PCM
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.5 {
iface PCM
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.6 {
iface PCM
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.7 {
iface PCM
subdevice 1
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.8 {
iface PCM
subdevice 1
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.9 {
iface PCM
subdevice 1
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.10 {
iface PCM
subdevice 1
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.11 {
iface PCM
subdevice 1
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.12 {
iface PCM
subdevice 1
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.13 {
iface PCM
subdevice 2
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.14 {
iface PCM
subdevice 2
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.15 {
iface PCM
subdevice 2
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.16 {
iface PCM
subdevice 2
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.17 {
iface PCM
subdevice 2
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.18 {
iface PCM
subdevice 2
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.19 {
iface PCM
subdevice 3
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.20 {
iface PCM
subdevice 3
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.21 {
iface PCM
subdevice 3
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.22 {
iface PCM
subdevice 3
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.23 {
iface PCM
subdevice 3
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.24 {
iface PCM
subdevice 3
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.25 {
iface PCM
subdevice 4
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.26 {
iface PCM
subdevice 4
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.27 {
iface PCM
subdevice 4
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.28 {
iface PCM
subdevice 4
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.29 {
iface PCM
subdevice 4
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.30 {
iface PCM
subdevice 4
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.31 {
iface PCM
subdevice 5
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.32 {
iface PCM
subdevice 5
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.33 {
iface PCM
subdevice 5
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.34 {
iface PCM
subdevice 5
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.35 {
iface PCM
subdevice 5
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.36 {
iface PCM
subdevice 5
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.37 {
iface PCM
subdevice 6
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.38 {
iface PCM
subdevice 6
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.39 {
iface PCM
subdevice 6
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.40 {
iface PCM
subdevice 6
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.41 {
iface PCM
subdevice 6
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.42 {
iface PCM
subdevice 6
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.43 {
iface PCM
subdevice 7
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.44 {
iface PCM
subdevice 7
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.45 {
iface PCM
subdevice 7
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.46 {
iface PCM
subdevice 7
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.47 {
iface PCM
subdevice 7
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.48 {
iface PCM
subdevice 7
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.49 {
iface PCM
device 1
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.50 {
iface PCM
device 1
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.51 {
iface PCM
device 1
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.52 {
iface PCM
device 1
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.53 {
iface PCM
device 1
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.54 {
iface PCM
device 1
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.55 {
iface PCM
device 1
subdevice 1
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.56 {
iface PCM
device 1
subdevice 1
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.57 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.58 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.59 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.60 {
iface PCM
device 1
subdevice 1
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.61 {
iface PCM
device 1
subdevice 2
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.62 {
iface PCM
device 1
subdevice 2
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.63 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.64 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.65 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.66 {
iface PCM
device 1
subdevice 2
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.67 {
iface PCM
device 1
subdevice 3
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.68 {
iface PCM
device 1
subdevice 3
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.69 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.70 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.71 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.72 {
iface PCM
device 1
subdevice 3
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.73 {
iface PCM
device 1
subdevice 4
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.74 {
iface PCM
device 1
subdevice 4
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.75 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.76 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.77 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.78 {
iface PCM
device 1
subdevice 4
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.79 {
iface PCM
device 1
subdevice 5
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.80 {
iface PCM
device 1
subdevice 5
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.81 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.82 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.83 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.84 {
iface PCM
device 1
subdevice 5
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.85 {
iface PCM
device 1
subdevice 6
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.86 {
iface PCM
device 1
subdevice 6
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.87 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.88 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.89 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.90 {
iface PCM
device 1
subdevice 6
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
control.91 {
iface PCM
device 1
subdevice 7
name 'PCM Rate Shift 100000'
value 100000
comment {
access 'read write'
type INTEGER
count 1
range '80000 - 120000 (step 1)'
}
}
control.92 {
iface PCM
device 1
subdevice 7
name 'PCM Notify'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.93 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Active'
value false
comment {
access read
type BOOLEAN
count 1
}
}
control.94 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Format'
value 2
comment {
access read
type INTEGER
count 1
range '0 - 52 (step 1)'
}
}
control.95 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Rate'
value 48000
comment {
access read
type INTEGER
count 1
range '0 - 192000 (step 1)'
}
}
control.96 {
iface PCM
device 1
subdevice 7
name 'PCM Slave Channels'
value 2
comment {
access read
type INTEGER
count 1
range '1 - 1024 (step 1)'
}
}
}
state.Codec {
control.1 {
iface MIXER
name 'DAC Playback Volume'
value 57
comment {
access 'read write'
type INTEGER
count 1
range '0 - 63'
dbmin -7308
dbmax 0
dbvalue.0 -696
}
}
control.2 {
iface MIXER
name 'Headphone Playback Volume'
value 55
comment {
access 'read write'
type INTEGER
count 1
range '0 - 63'
dbmin -9999999
dbmax 0
dbvalue.0 -800
}
}
control.3 {
iface MIXER
name 'Headphone Playback Switch'
value.0 true
value.1 true
comment {
access 'read write'
type BOOLEAN
count 2
}
}
control.4 {
iface MIXER
name 'Line In Playback Volume'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 -450
}
}
control.5 {
iface MIXER
name 'FM In Playback Volume'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 -450
}
}
control.6 {
iface MIXER
name 'Mic In Playback Volume'
value 7
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 600
}
}
control.7 {
iface MIXER
name 'Mic Boost Volume'
value 7
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin 0
dbmax 4200
dbvalue.0 4200
}
}
control.8 {
iface MIXER
name 'ADC Capture Volume'
value 7
comment {
access 'read write'
type INTEGER
count 1
range '0 - 7'
dbmin -450
dbmax 600
dbvalue.0 600
}
}
control.9 {
iface MIXER
name 'ADC Mixer Right Out Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.10 {
iface MIXER
name 'ADC Mixer Left Out Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.11 {
iface MIXER
name 'ADC Mixer Line In Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.12 {
iface MIXER
name 'ADC Mixer Right FM In Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.13 {
iface MIXER
name 'ADC Mixer Left FM In Capture Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.14 {
iface MIXER
name 'ADC Mixer Mic Capture Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.15 {
iface MIXER
name 'Left Mixer Right DAC Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.16 {
iface MIXER
name 'Left Mixer Left DAC Playback Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.17 {
iface MIXER
name 'Left Mixer FM In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.18 {
iface MIXER
name 'Left Mixer Line In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.19 {
iface MIXER
name 'Left Mixer Mic In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.20 {
iface MIXER
name 'Right Mixer Left DAC Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.21 {
iface MIXER
name 'Right Mixer Right DAC Playback Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.22 {
iface MIXER
name 'Right Mixer FM In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.23 {
iface MIXER
name 'Right Mixer Line In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.24 {
iface MIXER
name 'Right Mixer Mic In Playback Switch'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.25 {
iface MIXER
name 'Headphone Source Playback Route'
value.0 Mixer
value.1 Mixer
comment {
access 'read write'
type ENUMERATED
count 2
item.0 DAC
item.1 Mixer
}
}
}
电路有些问题,参考了https://whycan.com/t_5779.html将声道的串联电容改成了串联47欧电阻
有一个我不知道什么原理的问题,就是用我原本的电路拖头戴耳机,播放结束关闭dac的时候芯片直接彻底死机(硬复位都没用的那种),但是将hpcom对地改成43r+1uf后就没再出现问题。改之前我用示波器看到hpcom上有0.3v左右的高频振荡,改后震荡消失,底噪也有了很大改善。但无论如何都会出现于上述帖子一样的掉电pop声,不过也无伤大雅了,音质还算可以,底噪也在一个能接受的范围。
这几个周末抽空把屏幕调通了,ST7789v屏幕的初始化最终选择分别写了模拟spi的驱动和st7789v初始化的驱动,没有使用硬件spi的原因是我突然意识到我板子上那个ds1302是双线spi的。。而且时钟频率不能太高,然而刚好我测试st7789v的时钟频率不能太低,所以最后只能使用了模拟spi控制总线上的三个设备。。
还有我在mpv播放器上踩了不少坑,最后发现最简单的方式是用Linux的DRM在Framebuffer上播放
要开启buildroot和Kernel里的DRM,然后buildroot重新编译mpv
mpv --vo=drm --no-audio --profile=sw-fast /media/BadApple.mp4
https://whycan.com/files/members/4444/20220217093815.png
想问下,原理图部分电源开关的开关在哪里?
开关是用飞线加在了D3那个Debug二极管的一端和VBAT之间
正常上电我想的是按下Key_Power手动上电,然后在芯片UBoot阶段BootDelay倒计时结束后把PowerOn引脚拉高,来实现类似手机的一个上电过程
其实是几个月前搞的了。。马上giao考了,没时间搞软件了。。
这板子旨在用比较紧凑的空间,使用二层板,堆出最全的功能。板子大小只有5*7(主要是我那个屏也是这么大)。
功能大致包括:电池充电、电源开关管理(2个mos管堆出来的)、调试串口、USB Device、USB主从状态监测(可软件切换实现OTC)、板载USB Hub芯片、一个USB2.0 Host接口(配有5v升压电路)、USB WiFi+BT、蓝牙音频(PCM)、模拟音频、麦克风、KeyADC、RTC芯片、触摸ADC芯片(附带电池电压检测)、SD卡、SPI Nor Flash、以及一个接口十分反人类的LCD(不是标准40pin,而且线还跟一般的屏是反着的)。。
虽然功能这么多,但实际焊接调好的没几个。。关键的功能比如USBHub WIFi蓝牙音频以及液晶屏(不过这屏我在另一帖里调出来过)啥的都还没来得及调。。时间比较少,我只移植到Uboot就没再搞了Orz,所以软件部分没啥参考性了。硬件至少目前调通的还凑合没问题,有个主要问题是串口的保护二极管没弄,我有个USB-TTL板似乎被搞坏了。
其实本来我是想搞个类似MP5的功能,能一定程度上连接网络,能听歌,而且能连蓝牙。但仔细想想我Linux没啥经验,外壳3D设计更是还一窍不通。。再加上我还高三了,然后我就摆了,准备先高中毕业再继续调这玩意。
最后是AD工程,这F1C200s还是我手画的,包括3D封装啥的。。。
项目就叫 个人数字终端 测试板:PersonalTerminalTest.7z
PDF:PersonalTerminalTest.pdf
再贴点图
最后这有个上电软启动VBAT的图,不知道是不是电容太多的缘故,有个很大的波动。。但总之没影响启动
https://whycan.com/t_5652.html
我之前搞过个类似的屏,我的spi直接强行复用了rgb的数据引脚。你可以设置成rgb666然后只接rgb565,把多余的几个引脚接地就行了,或者刚好复用成软件spi。
https://whycan.com/t_5060.html
可以参考我这个bootloader里那个AddCheckSum工具,那个就是我写的生成魔术头的程序,对头部数据的注释以及与其配合的boot0里的汇编程序都有相应注释,应该在./Tool目录里,对代码大小是否超过sram大小那里写的有点问题,可以对照我的新帖子里的tool看。下载到SD卡8kb偏移的地方就行,我只测试过spiflash
顺便我这个bootloader是可以直接引导裸机程序到ddr运行的,你也可以参考一下
事情还要从我上淘宝捡便宜买了一块ST7789主控的LCD开始说起(不是广告),然后折腾半天才发现这玩意需要用SPI进行初始化QAQ。。(以下省略N字)
在翻F1C100s手册的时候偶然间看到TCON的数据源中写到了“DMA565”,然后再一次在偶然间翻DMA的手册时发现F1C100有个叫DDMA的东西可以用DRQ的形式向TCON发送数据,来实现类似于Framebuffer的功能,于是我开始尝试调试这个玩意。这个DMA方式的Framebuffer是我自己几乎从零开始慢慢摸索,断断续续整了几个月弄出来的(其实绝大部分时间都花在了TCON的调试上)。
DMA方式的特点在于代码小,避开了图像引擎那资料极少、难以理解、操作还极其繁琐的初始化过程,这样一来增强了可移植性,而且顺便避开了图像引擎工作带来的工作耗电量。而且我还发现使用图像引擎方式屏幕上的像素点会有一定抖动,但DMA方式则完全不会抖动。要说缺点的话,其一是只能使用RGB565,其二是不能使用图像引擎的硬件混色和图层叠加啥的,其三是会一定程度上占用AHB总线。但这些在大部分情况下影响都不大,毕竟代码量只有5KB这个大优势是一直都在的。
裸机BootLoader使用了我前段时间在论坛里开源过的BootLoader,并修复了一些小Bug(代码大小的判断出错)。目前试了三种交叉编译链都能正常编译运行。
软件部分秉承我的一贯风格,使用了我自己写的外设寄存器结构体(这段时间摸索出来了一种极其方便的利用Excel处理手册的方法)。程序里存进去了一张数组形式的图片用于测试。开发环境用的是VSCode,但其它环境应该也没问题。
硬件部分是荔枝派NANO+官方4.3寸屏或者通过转接板连接我上面蓝字那款ST7789的屏(这坑人玩意还涨价了)。其中转接板我用了一种极其鬼畜的方式复用了LCD的引脚来进行软件模拟SPI通讯,居然成功了,AD工程附在文件里。
正所谓前人种树后人乘凉,希望我开源这个东西可以帮到以后入坑的同好。这个DMA-TCON方式实在是有太多坑了,我在程序里基本都详细地一一注释了,有些手册写的不清楚的地方我也根据自己的推断写了注释。
就比如F1C100s手册里TCON外设的寄存器列表:
Register Name Offset Description
TCON_CTRL_REG 0x000 TCON Control Register
TCON_INT_REG0 0x004 TCON Interrupt Register 0
TCON_INT_REG1 0x008 TCON Interrupt Register 1
TCON_FRM_CTRL_REG 0x010 TCON FRM Control Register
……………………
要将其转化为:
typedef struct
{
vuint32_t TCON_CTRL_REG; //TCON Control Register
vuint32_t TCON_INT_REG0; //TCON Interrupt Register 0
vuint32_t TCON_INT_REG1; //TCON Interrupt Register 1
vuint32_t rsv1;
vuint32_t TCON_FRM_CTRL_REG; //TCON FRM Control Register
……………………
}TCON_Type;
可以参考我画的这张流程图:
具体风格和格式还由自己来定,我这个只是一个思路。
顺便一说,不同的Office软件PDF复制出来的格式可能有所不同,我全程使用的都是WPS,经测试这个已经算是效果最好最方便的了
演示文件、可以复制的F1C200s的PDF手册,还有我目前已经以自己风格编写的寄存器结构体头文件,都打包好发在这了
Manual-Excel-Code.zip
刚入门F1C没多久,自己写了个BootLoader玩,一定程度上参考了达克罗德大神的minimal。
我把代码尽量优化了,最终Boot0总共不到3KB,这里面大部分都是设置DDR控制器的代码,但由于DDR控制器的资料太少了,我没有头绪怎么去编写和优化,就只好照搬了达神的代码。
这个BootLoader有一个比较大的特点就是Boot0部分链接到了SRAM里,而其他程序链接到DDR里,在加载程序到DDR时只加载用户代码,这样应该使用绝对地址码也不会出错。实现这一点的链接脚本下文会提到。
在时钟的初始化中,我把ARM内核频率和DDR频率都设置为了408MHz,受DDR1限制再高就说不准会出问题了。
仿照达神的信息头,我写了一个简化版的,只有加载长度和校验和两个变量,校验和由我写的一个工具在编译时生成,加载长度通过链接脚本可以得知,在编译时进行字节对齐即可。
与BootLoader有关的代码都在Boot0里,还有一个引用的头文件是我自己编写的寄存器结构体(写这个老费劲了XD)文件,如果一定要移到别的工程里只需要移植这几个文件即可,需要注意的是链接脚本的修改,可以参考下文。代码整体实现了较高的内聚度和较低的耦合度。在用户代码中可以完全当BootLoader不存在,值得注意的是跳转到DDR时直接跳转到链接首地址,此后BootLoader就永久留在了SRAM里。
目前Boot0部分关闭了中断,如果需要使用中断可以在用户程序里把中断向量表啥的设置好,然后CPSR里把bit[7:6]都置零以开启中断。
在编写过程中遇到过的几个比较大的坑:
SRAM的地址和BROM是重合的,都是0x0开始,这与手册不一致,但影响不大,即使不知道也可以用位置无关码避免
手动设置SP指针时尽量不要指向DDR以外的区域比如SRAM,因为某些玄学因素我设置SP指针在SRAM里后入栈出栈就会出问题,这时使用上电自动设置好的SP指针即可(上电后SP指针指向0x9FE4)
硬件SPI的FIFO如果设置成字节读写,那就必须使用BYTE大小的指针读写,这其实是个比较低级的错误,但我查了好久。。Orz
链接脚本中如果把两段代码链接到不同的内存区域,这两个内存区域之间没用的部分也会被写入生成的文件,导致编译完的文件有好几个G大。。解决办法也很简单,只需要指定SRAM段后第一个DDR段在生成文件中的相对地址即可,这需要用AT()关键字实现,下面是链接脚本的一部分:
MEMORY
{
sram : ORIGIN = 0x00000000, LENGTH = 24K
ddr : ORIGIN = 0x80000000, LENGTH = 32M
}
SECTIONS
{
.boot0 :
{
Obj/Boot0.o (.text)
Obj/ClockInit.o (.text)
Obj/DDRInit.o (.text)
Obj/SPIFlashInit.o (.text)
Obj/CodeLoader.o (.text)
} > sram
__boot0_size = SIZEOF(.boot0);
__image_file_start = .;
.text : AT(__image_file_start) //就是这里,表示代码链接到DDR内,但编译时存放在文件的__image_file_start处
{
PROVIDE(__image_start = .);
Obj/start.o (.text)
Obj/main.o (.text)
*(.text)
*(.note.gnu.build-id)
} > ddr
……………………
}
这个文件里我的用户程序初始化了串口,打印测试了Data段、RoData段和BSS段的读写,然后就一直闪灯,需要注意的是我用的是一个外接的LED接到了PA0上灌电流驱动,大家如果需要测试可以修改或是直接删掉。
编译只需要make就行。
伪目标recompile用来重新编译工程。
伪目标write用来写入SPI Flash,这会调用sunxi-fel,这个工具所需要的运行库似乎在Ubuntu18下apt-get不到,我重装了Ubuntu16才能使用
伪目标maketool用来编译那个加载信息头的程序,一般应该用不到
伪目标clean用来清理工程,不用多说
目前只支持SPI Flash启动,大家可以自己添加SDIO的驱动来从SD卡加载程序
我写这段代码使用的是VSCode,这里面有些关于VSCode的文件忽略掉就行。
代码中对寄存器的每一位操作都有非常详细的注释,觉得看手册晕的可以瞄一眼0v0
其实这段代码要说实用性多高估计也谈不上,发出来主要是跟大家共同学习一下,以后有新人入坑也能多一个参考,少踩点坑
工程下载:BootLoader.zip
刚到手荔枝派没几天,已经跑起来裸机了,但是遇到很多诡异的现象,比如函数跳转异常之类的,甚至有的时候for循环都会出问题。
然后我就试着把pc指针通过串口打印出来了,发现pc指针居然在0x00000000范围,也就是手册上写的BROM区域。。
越来越懵了
串口发送十六进制是我自己写的(移植printf函数失败了),测试都是没问题的。因为选通DDR时钟的时候程序会莫名卡死,所以我现在没在DDR上运行,所以才遇到的不少问题。
__asm__ __volatile__("mov %0, pc" : "=r"(num));
//因为for循环和while都出问题了只能这么写了Orz。。。。
putc('0');
putc('x');
str = num / 0x10000000 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x1000000 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x100000 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x10000 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x1000 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x100 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x10 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
str = num / 0x1 % 0x10;
str += ((str < 10) ? 0x30 : 0x37);
putc(str);
putc('\r');
putc('\n');
为什么BROM要把代码拷到BROM区域上执行?这样不会覆盖掉BROM自己吗?我之前一直以为引导程序先会在SRAM区域0x10000上开始运行,链接脚本都是这么写的。。话说BROM不是ROM吗。。怎么当成RAM用了都。。全志这个芯片好魔性啊>A<
页次: 1