Compare commits

..

No commits in common. "master" and "falbala" have entirely different histories.

58 changed files with 2098 additions and 25554 deletions

7
.gitignore vendored
View file

@ -24,10 +24,3 @@ gerber/thhor_crs-*.png
*.map
pdfs/
sensor/*.pdf
*.vvp
vcd
*.log
sallen-key-pulse.hex
*~.pcb
*.backup

3
.gitmodules vendored
View file

@ -1,6 +1,3 @@
[submodule "src/bch4369"]
path = src/bch4369
url = git@codeberg.org:SiB64/bch4369
[submodule "fpga/solo"]
path = fpga/solo
url = ../solo_altera

View file

@ -1,582 +0,0 @@
v 20220529 2
C 43400 49800 1 0 0 capacitor-1.sym
{
T 43500 50100 5 10 1 1 0 0 1
refdes=C1
T 44000 50100 5 10 1 1 0 0 1
value=10nF 200V
T 43600 49600 5 10 1 1 0 0 1
footprint=C1206
}
C 45700 45100 1 0 0 capacitor-1.sym
{
T 45800 45400 5 10 1 1 0 0 1
refdes=C2
T 46300 45400 5 10 1 1 0 0 1
value=$CF
T 45900 44900 5 10 1 1 0 0 1
footprint=C0603
T 45900 46000 5 10 0 0 0 0 1
symversion=0.1
}
N 53800 51600 53800 53200 4
N 53800 47800 53800 50800 4
C 45700 45900 1 0 0 resistor-1.sym
{
T 45900 46200 5 10 1 1 0 0 1
refdes=R2
T 46300 46200 5 10 1 1 0 0 1
value=$RF
T 45900 45700 5 10 1 1 0 0 1
footprint=C0805
}
N 44300 50000 45300 50000 4
N 45900 50400 45900 51600 4
{
T 45800 50800 5 10 1 1 90 0 1
netname=q1out
}
N 47500 51400 51000 51400 4
{
T 47700 51500 5 10 1 1 0 0 1
netname=q2_out
}
N 51000 45300 51000 51400 4
N 51000 46000 46600 46000 4
N 45700 46000 45200 46000 4
N 45200 45300 45200 50000 4
{
T 45100 49000 5 10 1 1 90 0 1
netname=fet_gate
}
N 46600 45300 51000 45300 4
N 45700 45300 45200 45300 4
C 45200 53200 1 90 0 capacitor-1.sym
{
T 44900 53800 5 10 1 1 90 0 1
refdes=C31
T 45200 53100 5 10 1 1 90 0 1
value=100nF
T 44900 53000 5 10 1 1 90 0 1
footprint=C0603
}
C 44900 52800 1 0 0 gnd-1.sym
N 45000 53100 45000 53200 4
N 45900 54100 45000 54100 4
N 54300 51200 55400 51200 4
C 45300 49600 1 0 0 jfet-1.sym
{
T 45100 50800 5 10 1 1 0 0 1
refdes=Q1
T 45100 50400 5 10 1 1 0 0 1
footprint=SOT23_3
T 45100 50600 5 10 1 1 0 0 1
value=BF862
}
C 46000 51600 1 90 0 resistor-1.sym
{
T 46200 52100 5 10 1 1 90 0 1
refdes=R3
T 46200 51600 5 10 1 1 90 0 1
value=470Ω
T 45700 51800 5 10 1 1 90 0 1
footprint=C0603
}
C 54700 47000 1 90 0 capacitor-1.sym
{
T 54600 47600 5 10 1 1 0 0 1
refdes=C12
T 54700 46900 5 10 1 1 90 0 1
value=100nF
T 54400 46900 5 10 0 1 90 0 1
footprint=C0603
}
C 54900 53300 1 90 0 capacitor-1.sym
{
T 54600 53900 5 10 1 1 90 0 1
refdes=C13
T 54900 53200 5 10 1 1 90 0 1
value=100nF
T 54600 53100 5 10 0 1 90 0 1
footprint=C0603
}
C 54400 46600 1 0 0 gnd-1.sym
N 54500 48100 53800 48100 4
{
T 53900 47900 5 7 1 1 0 0 1
netname=vss_u1
}
N 54700 53100 53800 53100 4
{
T 54200 53200 5 7 1 1 0 0 1
netname=vcc_u1
}
C 54800 54500 1 180 0 gnd-1.sym
N 42100 50000 43400 50000 4
C 42700 53500 1 180 0 gnd-1.sym
C 43400 50300 1 90 0 resistor-1.sym
{
T 43100 50500 5 10 1 1 90 0 1
refdes=R1
T 43100 50900 5 10 1 1 90 0 1
value=15MΩ
T 43600 50500 5 10 1 1 90 0 1
footprint=C0805
}
N 43300 50300 43300 50000 4
N 45900 54100 45900 54500 4
C 42400 53200 1 270 0 capacitor-1.sym
{
T 42800 52900 5 10 1 1 90 0 1
refdes=C51
T 42300 52100 5 10 1 1 90 0 1
value=10nF 200V
T 42500 52100 5 10 1 1 90 0 1
footprint=C1206
}
C 43400 52100 1 90 0 resistor-1.sym
{
T 43100 52300 5 10 1 1 90 0 1
refdes=R51
T 43100 52700 5 10 1 1 90 0 1
value=15MΩ
T 43600 52300 5 10 1 1 90 0 1
footprint=C0805
}
N 43300 51200 43300 52100 4
{
T 42100 51600 5 10 1 1 0 0 1
netname=vbias_filtered
}
N 42100 51800 43300 51800 4
N 43300 53000 43300 53500 4
{
T 43500 53200 5 10 1 1 90 0 1
netname=vbias
}
C 53100 50800 1 0 0 AD8005-1.sym
{
T 53150 51650 5 8 1 1 0 0 1
device=AD8005
T 53900 51600 5 10 1 1 0 0 1
refdes=U1
T 54300 50900 5 10 1 1 0 0 1
footprint=SOT23_5
T 53800 51200 5 10 1 1 0 4 1
model-name=CFA
T 53100 50800 5 10 0 0 0 0 1
value=AD8005
}
C 53900 53200 1 90 0 resistor-1.sym
{
T 54100 53300 5 10 1 1 90 0 1
refdes=R13
T 54100 53800 5 10 1 1 90 0 1
value=75Ω
T 53600 53300 5 10 0 1 90 0 1
footprint=C0603
}
C 53900 46900 1 90 0 resistor-1.sym
{
T 53650 47200 5 10 1 1 90 0 1
refdes=R12
T 54100 47200 5 10 1 1 90 0 1
value=75Ω
T 53700 46800 5 10 0 1 90 0 1
footprint=C0603
}
N 53800 46400 53800 46900 4
N 54500 48100 54500 47900 4
N 54500 46900 54500 47000 4
C 46000 53200 1 90 0 resistor-1.sym
{
T 46200 53700 5 10 1 1 90 0 1
refdes=R31
T 46200 53200 5 10 1 1 90 0 1
value=470Ω
T 45700 53400 5 10 1 1 90 0 1
footprint=C0603
}
C 45200 51800 1 90 0 capacitor-1.sym
{
T 44900 52400 5 10 1 1 90 0 1
refdes=C3
T 45200 51700 5 10 1 1 90 0 1
value=100nF
T 44900 51600 5 10 1 1 90 0 1
footprint=C0603
}
C 44900 51400 1 0 0 gnd-1.sym
N 45000 51700 45000 51800 4
N 45000 52700 45900 52700 4
N 45900 52500 45900 53200 4
{
T 45800 52900 5 10 1 1 180 0 1
netname=vfet_q1
}
C 40800 43800 0 0 0 title-A3.sym
{
T 41000 44000 5 10 1 1 0 0 1
title=Common base stage with current source type Charge Sensitive Amplifier
T 50300 44500 5 10 1 1 0 0 1
Date=$Date: 2025-06-13 15:47:50 +0200 (Fr, 13 Jun 2025) $
T 50300 44200 5 10 1 1 0 0 1
Filename=CSA-Beau-2.sch
T 54400 44200 5 10 1 1 0 0 1
revision=$Revision: 9346 $
T 54400 43900 5 10 1 1 0 0 1
author=$Author: stephan $
T 49900 44900 5 10 1 1 0 0 1
id=$Id: CSA-Beau-sk.sch 9346 2025-06-13 13:47:50Z stephan $
}
C 55400 51100 1 0 0 out-1.sym
{
T 55400 51400 5 10 0 0 0 0 1
device=OUTPUT
T 56100 51200 5 10 1 1 0 0 1
refdes=out
}
C 41500 49900 1 0 0 in-1.sym
{
T 41500 50200 5 10 0 0 0 0 1
device=INPUT
T 41500 50000 5 10 1 1 0 7 1
refdes=in
}
C 53700 54900 1 270 0 in-1.sym
{
T 54000 54900 5 10 0 0 270 0 1
device=INPUT
T 53700 55000 5 10 1 1 0 0 1
refdes=Vcc
}
C 45800 55100 1 270 0 in-1.sym
{
T 46100 55100 5 10 0 0 270 0 1
device=INPUT
T 45700 55200 5 10 1 1 0 0 1
refdes=Vfet
}
C 53900 45800 1 90 0 in-1.sym
{
T 53600 45800 5 10 0 0 90 0 1
device=INPUT
T 53800 45600 5 10 1 1 0 0 1
refdes=Vss
}
C 43200 54100 1 270 0 in-1.sym
{
T 43500 54100 5 10 0 0 270 0 1
device=INPUT
T 43100 54200 5 10 1 1 0 0 1
refdes=Vbias
}
C 42200 48300 1 0 0 gnd-1.sym
C 41500 48600 1 0 0 in-1.sym
{
T 41500 48900 5 10 0 0 0 0 1
device=INPUT
T 41500 48700 5 10 1 1 0 7 1
refdes=GND
}
C 55100 50900 1 270 0 resistor-1.sym
{
T 55500 50400 5 10 1 1 180 4 1
refdes=R22
T 55500 50600 5 10 0 1 0 4 1
value=$R22
T 55500 50000 5 10 0 1 90 0 1
footprint=C0603
}
N 45900 51400 46500 51400 4
N 54700 53100 54700 53300 4
C 47200 49700 1 90 0 capacitor-1.sym
{
T 47100 50300 5 10 1 1 0 0 1
refdes=C7
T 47200 49600 5 10 1 1 90 0 1
value=100nF
T 46900 49500 5 10 1 1 90 0 1
footprint=C0603
}
C 46900 49300 1 0 0 gnd-1.sym
N 47000 50800 47000 50600 4
N 47000 49600 47000 49700 4
C 49000 48800 1 270 0 resistor-1.sym
{
T 48900 48100 5 10 1 1 90 0 1
refdes=R8
T 48900 48400 5 10 1 1 90 0 1
value=33kΩ
T 49400 48100 5 10 1 1 90 0 1
footprint=C0603
}
C 49700 50600 1 270 0 resistor-1.sym
{
T 49600 49800 5 10 1 1 90 0 1
refdes=R7
T 49600 50100 5 10 1 1 90 0 1
value=120kΩ
T 50100 49900 5 10 1 1 90 0 1
footprint=C0603
}
C 49700 52400 1 270 0 resistor-1.sym
{
T 49600 51600 5 10 1 1 90 0 1
refdes=R6
T 49600 52000 5 10 1 1 90 0 1
value=68kΩ
T 50000 52200 5 10 1 1 270 0 1
footprint=C0603
}
N 49800 51500 49800 50600 4
N 47000 50700 49800 50700 4
{
T 48400 50800 5 10 1 1 0 0 1
netname=q2bias
}
N 49800 48900 49800 49700 4
C 48200 48800 1 270 0 resistor-1.sym
{
T 48100 48100 5 10 1 1 90 0 1
refdes=R4
T 48100 48400 5 10 1 1 90 0 1
value=1.5kΩ
T 48500 48600 5 10 1 1 270 0 1
footprint=C0603
}
N 48300 47900 49800 47900 4
{
T 48700 47600 5 10 1 1 0 0 1
netname=vdd_f1
}
N 48900 49500 49800 49500 4
{
T 48800 49600 5 10 1 1 0 0 1
netname=q3bias
}
N 48300 50000 48300 51400 4
C 50000 48000 1 90 0 capacitor-1.sym
{
T 50000 48600 5 10 1 1 90 0 1
refdes=C8
T 50000 48900 5 10 1 1 90 0 1
value=100nF
T 49700 48600 5 10 1 1 90 0 1
footprint=C0603
}
C 48200 46600 1 0 0 gnd-1.sym
N 49800 47700 49800 48000 4
N 55200 50900 55200 51200 4
N 55200 50000 55200 49600 4
C 49100 53000 1 90 0 capacitor-1.sym
{
T 49100 53600 5 10 1 1 90 0 1
refdes=C61
T 49100 52900 5 10 1 1 90 0 1
value=100nF
T 48800 52800 5 10 1 1 90 0 1
footprint=C0603
}
C 49000 54200 1 180 0 gnd-1.sym
N 49800 52600 48900 52600 4
{
T 49000 52400 5 10 1 1 0 0 1
netname=vcc_f1
}
N 48900 52600 48900 53000 4
C 48500 46900 1 90 0 capacitor-1.sym
{
T 48200 47500 5 10 1 1 90 0 1
refdes=C62
T 48500 46800 5 10 1 1 90 0 1
value=100nF
T 48200 46700 5 10 1 1 90 0 1
footprint=C0603
}
C 49700 47700 1 270 0 resistor-1.sym
{
T 49600 46800 5 10 1 1 90 0 1
refdes=R62
T 49600 47300 5 10 1 1 90 0 1
value=75Ω
T 50100 46900 5 10 1 1 90 0 1
footprint=C0603
}
N 42600 51800 42600 52300 4
N 49800 52700 49800 52400 4
C 49700 53600 1 270 0 resistor-1.sym
{
T 49600 52900 5 10 1 1 90 0 1
refdes=R61
T 49600 53400 5 10 1 1 90 0 1
value=1kΩ
T 50000 53400 5 10 1 1 270 0 1
footprint=C0603
}
N 49800 53600 49800 54500 4
N 53800 54300 53800 54100 4
N 49800 46800 49800 46400 4
N 49800 46400 53800 46400 4
N 49800 54500 45900 54500 4
N 42300 48600 42300 48700 4
N 42100 48700 42300 48700 4
C 46500 50800 1 270 1 pnp-sot23.sym
{
T 47000 51700 5 10 0 0 90 2 1
device=PNP_TRANSISTOR
T 46900 51500 5 10 1 1 0 2 1
refdes=Q2
T 46900 51700 5 10 1 1 0 2 1
footprint=SOT23_3
T 46900 51800 5 10 1 1 0 0 1
device=MMBTH81
T 46900 52000 5 10 0 1 0 0 1
value=MMBTH81
}
C 48900 49000 1 0 1 npn-sot23.sym
{
T 48000 49500 5 10 0 0 0 6 1
device=NPN_TRANSISTOR
T 48400 49500 5 10 1 1 0 6 1
refdes=Q3
T 49000 50100 5 10 1 1 0 6 1
footprint=SOT23_3
T 48400 49900 5 10 1 1 0 0 1
device=MMBTH10
T 48400 50300 5 10 0 1 0 0 1
value=MMBTH10
}
C 45800 49100 1 0 0 gnd-1.sym
N 45900 49600 45900 49400 4
N 49100 48800 49100 49500 4
N 48300 48800 48300 49000 4
{
T 48500 48800 5 10 1 1 90 0 1
netname=q3e
}
N 48300 47800 48300 47900 4
C 43900 54500 1 180 0 gnd-1.sym
C 44000 53300 1 90 0 capacitor-1.sym
{
T 43900 53600 5 10 1 1 270 0 1
refdes=C52
T 44100 54200 5 10 1 1 270 0 1
value=10nF 200V
T 43900 54300 5 10 1 1 270 0 1
footprint=C1206
}
N 43800 53300 43300 53300 4
C 41500 47300 1 0 0 in-1.sym
{
T 41500 47600 5 10 0 0 0 0 1
device=INPUT
T 41500 47400 5 10 1 1 0 7 1
refdes=test
}
N 44300 47400 45200 47400 4
C 55100 49600 1 270 0 resistor-1.sym
{
T 55600 49000 5 10 1 1 180 4 1
refdes=R23
T 55600 49200 5 10 0 1 180 4 1
value=$R23
T 55500 48700 5 10 0 1 90 0 1
footprint=C0603
}
C 55100 48400 1 0 0 gnd-1.sym
N 53300 51000 53300 49800 4
{
T 53250 50900 5 7 1 1 90 6 1
netname=u1inv
}
N 53300 49800 55200 49800 4
C 51900 51500 1 180 0 resistor-1.sym
{
T 51400 51200 5 10 1 1 0 4 1
refdes=R20
T 51400 51000 5 10 0 1 0 4 1
value=$R20
T 51000 51100 5 10 0 1 0 0 1
footprint=C0603
}
C 52800 51500 1 180 0 resistor-1.sym
{
T 52400 51200 5 10 1 1 0 4 1
refdes=R21
T 52400 51000 5 10 0 1 0 4 1
value=$R21
T 51900 51100 5 10 0 1 0 0 1
footprint=C0603
}
N 52800 51400 53300 51400 4
{
T 52800 51450 5 7 1 1 0 0 1
netname=u1ninv
}
C 52200 52000 1 0 0 capacitor-1.sym
{
T 52600 52600 5 10 1 1 0 4 1
refdes=C20
T 52600 52800 5 10 0 1 0 4 1
value=$C20
T 52400 51800 5 10 0 1 0 0 1
footprint=C0603
T 52400 52900 5 10 0 0 0 0 1
symversion=0.1
}
N 54900 51200 54900 52200 4
N 54900 52200 53100 52200 4
N 52200 52200 51900 52200 4
N 51900 52200 51900 51400 4
{
T 51850 52100 5 7 1 1 90 6 1
netname=u1sk
}
C 53200 49600 1 90 0 capacitor-1.sym
{
T 52700 50300 5 10 1 1 180 4 1
refdes=C21
T 52700 50500 5 10 0 1 0 4 1
value=$C21
T 53400 49800 5 10 0 1 90 0 1
footprint=C0603
T 52300 49800 5 10 0 0 90 0 1
symversion=0.1
}
C 52900 49300 1 0 0 gnd-1.sym
N 53000 50500 53000 51400 4
T 51200 55000 9 10 1 0 0 2 8
b=0.46, a=1.47
τ = 1µs / 1.5µs / 2.2µs
R20 = 22kΩ
R21 = 33kΩ
C20 = 47pF / 68pF/ 100pF
C21 = 33pF / 47pF / 68pF
R22 = 1kΩ
R23 = 2.2kΩ
T 55400 54900 9 10 1 0 0 2 6
b=0.46, a=1.47
τ = 2.7µs
R20 = 27kΩ
R21 = 39kΩ
C20 = 100pF
C21 = 68pF
T 51500 48700 9 10 1 0 0 0 1
b = R22/R23
T 51500 49000 9 10 1 0 0 0 1
a = C20/C21
T 51500 48400 9 10 1 0 0 0 1
a = b+1 → τ = R20×C20 = R21×C21
N 42100 47400 43400 47400 4
C 43400 47200 1 0 0 capacitor-1.sym
{
T 43500 47500 5 10 1 1 0 0 1
refdes=C11
T 44000 47500 5 10 1 1 0 0 1
value=1pF 5%
T 43600 47000 5 10 1 1 0 0 1
footprint=C0603
T 43600 48100 5 10 0 0 0 0 1
symversion=0.1
}

View file

@ -277,17 +277,3 @@ N 45800 42500 45400 42500 4
N 45400 42500 45400 42600 4
N 45800 42500 45800 42600 4
N 46200 42200 46200 42600 4
T 48100 45700 9 10 1 0 0 0 13
Spaping time τ=2.7µs
Pole-Zero comp τr=100µs
Gain 15
R₁ = 270Ω C₁ = 10nF = τ/R₁
R₃ = 12kΩ₃ = 45R₁, C₃ = 220pF = τ/R₃
R₀ = 10kΩ = τr/C₁
Gain 1
R₁ = 2.7kΩ C₁ = 1nF = τ/R₁
R₃ = 8.2kΩ₃ = 3R₁, C₃ = 330pF = τ/R₃
R₀ = 100kΩ = τr/C₁

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

View file

@ -8,30 +8,12 @@ CHAOS Jr: HET BGO and 2× HETB.
## Electronics
- single 5…20V power supply
- 37 pin Omnetics Bilobe connector to the preamps board, A28200-037
- detector bias voltage, positive or negative
- 12 channel DORN readout, dual gain (with six preamps)
- with Beau-SK type preamps
- 6 preamps
- 12 channel DORN readout, dual gain
- 10LC25 FPGA
- ATtiny824-XF
- AT45B161E for FPGA bitfile and data
- 3.3V UART (optional RS485 half duplex) ifc to OBC
- RS485 half duplex ifc to OBC
- optional HSS serial ifc/spacewire.
- optional MS5534 pressure sensor for balloon missions
![Layout](thhor_crs-topbot.png)
### Transformer
- 4 turns, thick, Vcore, 1.25V, directly regulated.
- 12 turns, thick, primary.
- 12 turns, medium, SEPIC, 4.5V digital, LDO regulators Vpll=2.5V, Vio=3.3V, Vadc=3.3V.
- 19 turns, medium, +7.5V, LDO regulators +5V shaper, preamps, fets.
- 19 turns, medium, -7.5V, LDO regulators -5V shaper, preamps.
- 19 turns, thin, Vbias cascade.
![Transformer](IMG_20260324_100529_131-1200.jpg)
## Charge Sensitive Amplifier
![Layout](thhor_csa-topbot.png)
![Layout](thhor_crs-top.png)
![Layout](thhor_crs-bot.png)

View file

@ -1,17 +0,0 @@
Element["" "" "J?" "" 2340.00mil 1400.00mil -22.50mil -112.50mil 0 100 ""]
(
Pad[0.0000 -90.00mil 0.0000 -70.00mil 1.2000mm 20.00mil 1.4032mm "1" "1" "square"]
Pad[0.0000 0.0000 0.0000 100.00mil 1.2000mm 20.00mil 1.7588mm "2" "2" "square,edge2"]
# Pin[0.0000 100.00mil 0.9000mm 0.5000mm 38.00mil 0.4000mm "2" "2" ""]
# Pin[0.0000 50.00mil 0.9000mm 0.5000mm 38.00mil 0.4000mm "2" "2" ""]
# Pin[0.0000 0.0000 0.9000mm 0.5000mm 38.00mil 0.4000mm "2" "2" ""]
ElementLine [15.00mil 117.50mil 15.00mil 82.50mil 0.1500mm]
ElementLine [-15.00mil 117.50mil -15.00mil 82.50mil 0.1500mm]
ElementLine [-10.00mil 117.50mil -10.00mil -12.50mil 0.1500mm]
ElementLine [10.00mil 117.50mil 10.00mil -12.50mil 0.1500mm]
ElementLine [-5.00mil 25.00mil -5.00mil -40.00mil 0.1500mm]
ElementLine [5.00mil 25.00mil 5.00mil -40.00mil 0.1500mm]
ElementLine [0.0000 0.0000 0.0000 -87.50mil 0.1500mm]
)

View file

@ -1,47 +1,45 @@
Element["" "" "CONN?" "" 103.50mil 365.50mil 26.50mil 78.00mil 1 100 ""]
Element["" "" "CONN?" "" 2230.00mil 5995.00mil -30.00mil 70.00mil 1 100 ""]
(
Pin[0.0000 310.00mil 2.0000mm 20.00mil 2.1270mm 1.5500mm "" "0" "square"]
Pin[0.0000 -310.00mil 2.0000mm 20.00mil 2.1270mm 1.5500mm "" "0" "square"]
Pad[-6.50mil -311.50mil 15.50mil -311.50mil 102.00mil 20.00mil 110.00mil "" "0" "square"]
Pad[-6.50mil 311.50mil 15.50mil 311.50mil 102.00mil 20.00mil 110.00mil "" "0" "square"]
Pad[25.00mil 212.50mil 95.00mil 212.50mil 17.00mil 20.00mil 22.00mil "" "37" "square,edge2"]
Pad[25.00mil 187.50mil 95.00mil 187.50mil 17.00mil 20.00mil 22.00mil "" "36" "square,edge2"]
Pad[25.00mil 162.50mil 95.00mil 162.50mil 17.00mil 20.00mil 22.00mil "" "35" "square,edge2"]
Pad[25.00mil 137.50mil 95.00mil 137.50mil 17.00mil 20.00mil 22.00mil "" "34" "square,edge2"]
Pad[25.00mil 112.50mil 95.00mil 112.50mil 17.00mil 20.00mil 22.00mil "" "33" "square,edge2"]
Pad[25.00mil 87.50mil 95.00mil 87.50mil 17.00mil 20.00mil 22.00mil "" "32" "square,edge2"]
Pad[25.00mil 62.50mil 95.00mil 62.50mil 17.00mil 20.00mil 22.00mil "" "31" "square,edge2"]
Pad[25.00mil 37.50mil 95.00mil 37.50mil 17.00mil 20.00mil 22.00mil "" "30" "square,edge2"]
Pad[25.00mil 12.50mil 95.00mil 12.50mil 17.00mil 20.00mil 22.00mil "" "29" "square,edge2"]
Pad[25.00mil -12.50mil 95.00mil -12.50mil 17.00mil 20.00mil 22.00mil "" "28" "square,edge2"]
Pad[25.00mil -37.50mil 95.00mil -37.50mil 17.00mil 20.00mil 22.00mil "" "27" "square,edge2"]
Pad[25.00mil -62.50mil 95.00mil -62.50mil 17.00mil 20.00mil 22.00mil "" "26" "square,edge2"]
Pad[25.00mil -87.50mil 95.00mil -87.50mil 17.00mil 20.00mil 22.00mil "" "25" "square,edge2"]
Pad[25.00mil -112.50mil 95.00mil -112.50mil 17.00mil 20.00mil 22.00mil "" "24" "square,edge2"]
Pad[25.00mil -137.50mil 95.00mil -137.50mil 17.00mil 20.00mil 22.00mil "" "23" "square,edge2"]
Pad[25.00mil -162.50mil 95.00mil -162.50mil 17.00mil 20.00mil 22.00mil "" "22" "square,edge2"]
Pad[25.00mil -187.50mil 95.00mil -187.50mil 17.00mil 20.00mil 22.00mil "" "21" "square,edge2"]
Pad[25.00mil -212.50mil 95.00mil -212.50mil 17.00mil 20.00mil 22.00mil "" "20" "square,edge2"]
Pad[-85.00mil 225.00mil -25.00mil 225.00mil 17.00mil 20.00mil 22.00mil "" "19" "square"]
Pad[-85.00mil 200.00mil -25.00mil 200.00mil 17.00mil 20.00mil 22.00mil "" "18" "square"]
Pad[-85.00mil 175.00mil -25.00mil 175.00mil 17.00mil 20.00mil 22.00mil "" "17" "square"]
Pad[-85.00mil 150.00mil -25.00mil 150.00mil 17.00mil 20.00mil 22.00mil "" "16" "square"]
Pad[-85.00mil 125.00mil -25.00mil 125.00mil 17.00mil 20.00mil 22.00mil "" "15" "square"]
Pad[-85.00mil 100.00mil -25.00mil 100.00mil 17.00mil 20.00mil 22.00mil "" "14" "square"]
Pad[-85.00mil 75.00mil -25.00mil 75.00mil 17.00mil 20.00mil 22.00mil "" "13" "square"]
Pad[-85.00mil 50.00mil -25.00mil 50.00mil 17.00mil 20.00mil 22.00mil "" "12" "square"]
Pad[-85.00mil 25.00mil -25.00mil 25.00mil 17.00mil 20.00mil 22.00mil "" "11" "square"]
Pad[-85.00mil 0.0000 -25.00mil 0.0000 17.00mil 20.00mil 22.00mil "" "10" "square"]
Pad[-85.00mil -25.00mil -25.00mil -25.00mil 17.00mil 20.00mil 22.00mil "" "9" "square"]
Pad[-85.00mil -50.00mil -25.00mil -50.00mil 17.00mil 20.00mil 22.00mil "" "8" "square"]
Pad[-85.00mil -75.00mil -25.00mil -75.00mil 17.00mil 20.00mil 22.00mil "" "7" "square"]
Pad[-85.00mil -100.00mil -25.00mil -100.00mil 17.00mil 20.00mil 22.00mil "" "6" "square"]
Pad[-85.00mil -125.00mil -25.00mil -125.00mil 17.00mil 20.00mil 22.00mil "" "5" "square"]
Pad[-85.00mil -150.00mil -25.00mil -150.00mil 17.00mil 20.00mil 22.00mil "" "4" "square"]
Pad[-85.00mil -175.00mil -25.00mil -175.00mil 17.00mil 20.00mil 22.00mil "" "3" "square"]
Pad[-85.00mil -200.00mil -25.00mil -200.00mil 17.00mil 20.00mil 22.00mil "" "2" "square"]
Pad[-85.00mil -225.00mil -25.00mil -225.00mil 17.00mil 20.00mil 22.00mil "" "1" "square"]
Pin[0.0000 310.00mil 65.00mil 20.00mil 70.00mil 43.00mil "" "0" ""]
Pin[0.0000 -310.00mil 65.00mil 20.00mil 70.00mil 43.00mil "" "0" ""]
Pad[25.00mil 212.50mil 95.00mil 212.50mil 17.00mil 20.00mil 37.00mil "" "37" "square,edge2"]
Pad[25.00mil 187.50mil 95.00mil 187.50mil 17.00mil 20.00mil 37.00mil "" "36" "square,edge2"]
Pad[25.00mil 162.50mil 95.00mil 162.50mil 17.00mil 20.00mil 37.00mil "" "35" "square,edge2"]
Pad[25.00mil 137.50mil 95.00mil 137.50mil 17.00mil 20.00mil 37.00mil "" "34" "square,edge2"]
Pad[25.00mil 112.50mil 95.00mil 112.50mil 17.00mil 20.00mil 37.00mil "" "33" "square,edge2"]
Pad[25.00mil 87.50mil 95.00mil 87.50mil 17.00mil 20.00mil 37.00mil "" "32" "square,edge2"]
Pad[25.00mil 62.50mil 95.00mil 62.50mil 17.00mil 20.00mil 37.00mil "" "31" "square,edge2"]
Pad[25.00mil 37.50mil 95.00mil 37.50mil 17.00mil 20.00mil 37.00mil "" "30" "square,edge2"]
Pad[25.00mil 12.50mil 95.00mil 12.50mil 17.00mil 20.00mil 37.00mil "" "29" "square,edge2"]
Pad[25.00mil -12.50mil 95.00mil -12.50mil 17.00mil 20.00mil 37.00mil "" "28" "square,edge2"]
Pad[25.00mil -37.50mil 95.00mil -37.50mil 17.00mil 20.00mil 37.00mil "" "27" "square,edge2"]
Pad[25.00mil -62.50mil 95.00mil -62.50mil 17.00mil 20.00mil 37.00mil "" "26" "square,edge2"]
Pad[25.00mil -87.50mil 95.00mil -87.50mil 17.00mil 20.00mil 37.00mil "" "25" "square,edge2"]
Pad[25.00mil -112.50mil 95.00mil -112.50mil 17.00mil 20.00mil 37.00mil "" "24" "square,edge2"]
Pad[25.00mil -137.50mil 95.00mil -137.50mil 17.00mil 20.00mil 37.00mil "" "23" "square,edge2"]
Pad[25.00mil -162.50mil 95.00mil -162.50mil 17.00mil 20.00mil 37.00mil "" "22" "square,edge2"]
Pad[25.00mil -187.50mil 95.00mil -187.50mil 17.00mil 20.00mil 37.00mil "" "21" "square,edge2"]
Pad[25.00mil -212.50mil 95.00mil -212.50mil 17.00mil 20.00mil 37.00mil "" "20" "square,edge2"]
Pad[-85.00mil 225.00mil -25.00mil 225.00mil 17.00mil 20.00mil 37.00mil "" "19" "square"]
Pad[-85.00mil 200.00mil -25.00mil 200.00mil 17.00mil 20.00mil 37.00mil "" "18" "square"]
Pad[-85.00mil 175.00mil -25.00mil 175.00mil 17.00mil 20.00mil 37.00mil "" "17" "square"]
Pad[-85.00mil 150.00mil -25.00mil 150.00mil 17.00mil 20.00mil 37.00mil "" "16" "square"]
Pad[-85.00mil 125.00mil -25.00mil 125.00mil 17.00mil 20.00mil 37.00mil "" "15" "square"]
Pad[-85.00mil 100.00mil -25.00mil 100.00mil 17.00mil 20.00mil 37.00mil "" "14" "square"]
Pad[-85.00mil 75.00mil -25.00mil 75.00mil 17.00mil 20.00mil 37.00mil "" "13" "square"]
Pad[-85.00mil 50.00mil -25.00mil 50.00mil 17.00mil 20.00mil 37.00mil "" "12" "square"]
Pad[-85.00mil 25.00mil -25.00mil 25.00mil 17.00mil 20.00mil 37.00mil "" "11" "square"]
Pad[-85.00mil 0.0000 -25.00mil 0.0000 17.00mil 20.00mil 37.00mil "" "10" "square"]
Pad[-85.00mil -25.00mil -25.00mil -25.00mil 17.00mil 20.00mil 37.00mil "" "9" "square"]
Pad[-85.00mil -50.00mil -25.00mil -50.00mil 17.00mil 20.00mil 37.00mil "" "8" "square"]
Pad[-85.00mil -75.00mil -25.00mil -75.00mil 17.00mil 20.00mil 37.00mil "" "7" "square"]
Pad[-85.00mil -100.00mil -25.00mil -100.00mil 17.00mil 20.00mil 37.00mil "" "6" "square"]
Pad[-85.00mil -125.00mil -25.00mil -125.00mil 17.00mil 20.00mil 37.00mil "" "5" "square"]
Pad[-85.00mil -150.00mil -25.00mil -150.00mil 17.00mil 20.00mil 37.00mil "" "4" "square"]
Pad[-85.00mil -175.00mil -25.00mil -175.00mil 17.00mil 20.00mil 37.00mil "" "3" "square"]
Pad[-85.00mil -200.00mil -25.00mil -200.00mil 17.00mil 20.00mil 37.00mil "" "2" "square"]
Pad[-85.00mil -225.00mil -25.00mil -225.00mil 17.00mil 20.00mil 37.00mil "" "1" "square"]
ElementLine [-57.50mil -362.50mil -57.50mil -260.00mil 6.00mil]
ElementLine [-57.50mil -260.00mil 67.50mil -260.00mil 6.00mil]
ElementLine [67.50mil -362.50mil 67.50mil -260.00mil 6.00mil]

View file

@ -1,54 +0,0 @@
Element["" "" "CONN?" "" 103.50mil 365.50mil 26.50mil 78.00mil 1 100 ""]
(
Pin[0.0000 310.00mil 2.0000mm 20.00mil 2.1270mm 1.5500mm "" "0" "square"]
Pin[0.0000 -310.00mil 2.0000mm 20.00mil 2.1270mm 1.5500mm "" "0" "square"]
Pad[-6.50mil -311.50mil 15.50mil -311.50mil 102.00mil 20.00mil 110.00mil "" "0" "square"]
Pad[-6.50mil 311.50mil 15.50mil 311.50mil 102.00mil 20.00mil 110.00mil "" "0" "square"]
Pad[25.00mil 212.50mil 95.00mil 212.50mil 17.00mil 20.00mil 22.00mil "" "20" "square,edge2"]
Pad[25.00mil 187.50mil 95.00mil 187.50mil 17.00mil 20.00mil 22.00mil "" "21" "square,edge2"]
Pad[25.00mil 162.50mil 95.00mil 162.50mil 17.00mil 20.00mil 22.00mil "" "22" "square,edge2"]
Pad[25.00mil 137.50mil 95.00mil 137.50mil 17.00mil 20.00mil 22.00mil "" "23" "square,edge2"]
Pad[25.00mil 112.50mil 95.00mil 112.50mil 17.00mil 20.00mil 22.00mil "" "24" "square,edge2"]
Pad[25.00mil 87.50mil 95.00mil 87.50mil 17.00mil 20.00mil 22.00mil "" "25" "square,edge2"]
Pad[25.00mil 62.50mil 95.00mil 62.50mil 17.00mil 20.00mil 22.00mil "" "26" "square,edge2"]
Pad[25.00mil 37.50mil 95.00mil 37.50mil 17.00mil 20.00mil 22.00mil "" "27" "square,edge2"]
Pad[25.00mil 12.50mil 95.00mil 12.50mil 17.00mil 20.00mil 22.00mil "" "28" "square,edge2"]
Pad[25.00mil -12.50mil 95.00mil -12.50mil 17.00mil 20.00mil 22.00mil "" "29" "square,edge2"]
Pad[25.00mil -37.50mil 95.00mil -37.50mil 17.00mil 20.00mil 22.00mil "" "30" "square,edge2"]
Pad[25.00mil -62.50mil 95.00mil -62.50mil 17.00mil 20.00mil 22.00mil "" "31" "square,edge2"]
Pad[25.00mil -87.50mil 95.00mil -87.50mil 17.00mil 20.00mil 22.00mil "" "32" "square,edge2"]
Pad[25.00mil -112.50mil 95.00mil -112.50mil 17.00mil 20.00mil 22.00mil "" "33" "square,edge2"]
Pad[25.00mil -137.50mil 95.00mil -137.50mil 17.00mil 20.00mil 22.00mil "" "34" "square,edge2"]
Pad[25.00mil -162.50mil 95.00mil -162.50mil 17.00mil 20.00mil 22.00mil "" "35" "square,edge2"]
Pad[25.00mil -187.50mil 95.00mil -187.50mil 17.00mil 20.00mil 22.00mil "" "36" "square,edge2"]
Pad[25.00mil -212.50mil 95.00mil -212.50mil 17.00mil 20.00mil 22.00mil "" "37" "square,edge2"]
Pad[-85.00mil 225.00mil -25.00mil 225.00mil 17.00mil 20.00mil 22.00mil "" "1" "square"]
Pad[-85.00mil 200.00mil -25.00mil 200.00mil 17.00mil 20.00mil 22.00mil "" "2" "square"]
Pad[-85.00mil 175.00mil -25.00mil 175.00mil 17.00mil 20.00mil 22.00mil "" "3" "square"]
Pad[-85.00mil 150.00mil -25.00mil 150.00mil 17.00mil 20.00mil 22.00mil "" "4" "square"]
Pad[-85.00mil 125.00mil -25.00mil 125.00mil 17.00mil 20.00mil 22.00mil "" "5" "square"]
Pad[-85.00mil 100.00mil -25.00mil 100.00mil 17.00mil 20.00mil 22.00mil "" "6" "square"]
Pad[-85.00mil 75.00mil -25.00mil 75.00mil 17.00mil 20.00mil 22.00mil "" "7" "square"]
Pad[-85.00mil 50.00mil -25.00mil 50.00mil 17.00mil 20.00mil 22.00mil "" "8" "square"]
Pad[-85.00mil 25.00mil -25.00mil 25.00mil 17.00mil 20.00mil 22.00mil "" "9" "square"]
Pad[-85.00mil 0.0000 -25.00mil 0.0000 17.00mil 20.00mil 22.00mil "" "10" "square"]
Pad[-85.00mil -25.00mil -25.00mil -25.00mil 17.00mil 20.00mil 22.00mil "" "11" "square"]
Pad[-85.00mil -50.00mil -25.00mil -50.00mil 17.00mil 20.00mil 22.00mil "" "12" "square"]
Pad[-85.00mil -75.00mil -25.00mil -75.00mil 17.00mil 20.00mil 22.00mil "" "13" "square"]
Pad[-85.00mil -100.00mil -25.00mil -100.00mil 17.00mil 20.00mil 22.00mil "" "14" "square"]
Pad[-85.00mil -125.00mil -25.00mil -125.00mil 17.00mil 20.00mil 22.00mil "" "15" "square"]
Pad[-85.00mil -150.00mil -25.00mil -150.00mil 17.00mil 20.00mil 22.00mil "" "16" "square"]
Pad[-85.00mil -175.00mil -25.00mil -175.00mil 17.00mil 20.00mil 22.00mil "" "17" "square"]
Pad[-85.00mil -200.00mil -25.00mil -200.00mil 17.00mil 20.00mil 22.00mil "" "18" "square"]
Pad[-85.00mil -225.00mil -25.00mil -225.00mil 17.00mil 20.00mil 22.00mil "" "19" "square"]
ElementLine [-57.50mil -362.50mil -57.50mil -260.00mil 6.00mil]
ElementLine [-57.50mil -260.00mil 67.50mil -260.00mil 6.00mil]
ElementLine [67.50mil -362.50mil 67.50mil -260.00mil 6.00mil]
ElementLine [-57.50mil -362.50mil 67.50mil -362.50mil 6.00mil]
ElementLine [-57.50mil 260.00mil -57.50mil 362.50mil 6.00mil]
ElementLine [-57.50mil 260.00mil 67.50mil 260.00mil 6.00mil]
ElementLine [67.50mil 260.00mil 67.50mil 362.50mil 6.00mil]
ElementLine [-57.50mil 362.50mil 67.50mil 362.50mil 6.00mil]
)

View file

@ -1,5 +1,5 @@
VERILOG=iverilog -gno-strict-parameter-declaration -Wno-declaration-after-use
VERILOG=/usr/bin/iverilog
VERILOGFLAGS = -v -DSIMULATION $($*_FLAGS)
%.vvp:
@ -10,26 +10,10 @@ vcd/%.fst: %.vvp
.PRECIOUS: vcd/%.fst
VPATH = solo/altera : solo/irena/altera: solo/irena/altera/adc128: \
solo/dorn/altera : solo/nm64/altera
FRONTEND_FILES = frontend_test.v spi_slave.v frontend.v packetfifo.v conf_reg.v spififo_sim.v \
countbits.v serializer.v secondcyclone.v
DORN_FILES = thhor_core.v stis_ana_core.v dorn.v multiply.v divider.v nmcounter.v dmem.v
IRENA_FILES = frontend_test.v mem.v itof.v ms5540c.v adc128s102.v pulser.v
THHOR_CRS_SRC = thhor_crs.v $(FRONTEND_FILES) $(DORN_FILES) $(IRENA_FILES)
THHOR_CRS_SRC = thhor_crs.v pll.v
thhor_crs.vvp: $(THHOR_CRS_SRC)
vcd/thhor_crs.fst: sallen-key-pulse.hex
sallen-key-pulse.hex:
ln -f solo/dorn/altera/$@
DORN_FLAGS = -DWITH_FULL_L1_CONF -DWITH_FULL_L2_CONF -DWITH_FULL_L3_CONF \
-DANA_WITHOUT_SERIALIZER -DSPARSE_TRIG_EN -DL2_AHEPAM
ARCH_FLAGS = -DSTIS_ANA_JIG -DINFERRED_SRAM -DSER_FIFO_ALTERA -DWITH_SPI_SSEL
thhor_crs_FLAGS = -sthhor_crs_test -DTHHOR -DTHHOR_CRS_TEST -DAX_PORT \
$(DORN_FLAGS) $(ARCH_FLAGS)
thhor_crs_FLAGS = -sthhor_crs_test -DTHHOR_CRS -DTHHOR_CRS_TEST
CYCLONE=10

@ -1 +0,0 @@
Subproject commit 9bbfeb3316098af16370c10355c94ed7ec06f5ee

File diff suppressed because it is too large Load diff

View file

@ -198,37 +198,9 @@ set_location_assignment PIN_144 -to P25[18]
########## Sources
set_global_assignment -name VERILOG_FILE thhor_crs.v
set_global_assignment -name VERILOG_FILE solo/altera/spi_slave.v
set_global_assignment -name VERILOG_FILE solo/altera/frontend.v
set_global_assignment -name VERILOG_FILE solo/altera/packetfifo.v
set_global_assignment -name VERILOG_FILE solo/altera/mega/spififo.v
set_global_assignment -name VERILOG_FILE solo/altera/conf_reg.v
set_global_assignment -name VERILOG_FILE solo/altera/countbits.v
set_global_assignment -name VERILOG_FILE solo/altera/serializer.v
set_global_assignment -name VERILOG_FILE solo/altera/secondcyclone.v
set_global_assignment -name VERILOG_FILE solo/dorn/altera/thhor_core.v
set_global_assignment -name VERILOG_FILE solo/dorn/altera/stis_ana_core.v
set_global_assignment -name VERILOG_FILE solo/dorn/altera/dorn.v
set_global_assignment -name VERILOG_FILE solo/dorn/altera/multiply.v
set_global_assignment -name VERILOG_FILE solo/dorn/altera/divider.v
set_global_assignment -name VERILOG_FILE solo/nm64/altera/nmcounter.v
set_global_assignment -name VERILOG_FILE solo/dorn/altera/dmem.v
set_global_assignment -name VERILOG_FILE solo/altera/mem.v
set_global_assignment -name VERILOG_FILE solo/altera/itof.v
set_global_assignment -name VERILOG_FILE solo/irena/altera/ms5540c.v
set_global_assignment -name VERILOG_FILE solo/altera/adc128s102.v
set_global_assignment -name VERILOG_FILE pll.v
set_global_assignment -name VERILOG_MACRO "TARGET_ALTERA=1"
set_global_assignment -name VERILOG_MACRO "TARGET_10C25=1"
set_global_assignment -name VERILOG_MACRO "THHOR=1"
set_global_assignment -name VERILOG_MACRO "INFERRED_SRAM=1"
set_global_assignment -name VERILOG_MACRO "WITH_FULL_L1_CONF=1"
set_global_assignment -name VERILOG_MACRO "WITH_FULL_L2_CONF=1"
set_global_assignment -name VERILOG_MACRO "WITH_FULL_L3_CONF=1"
set_global_assignment -name VERILOG_MACRO "ANA_WITHOUT_SERIALIZER=1"
set_global_assignment -name VERILOG_MACRO "SPARSE_TRIG_EN=1"
set_global_assignment -name VERILOG_MACRO "L2_AHEPAM=1"
set_global_assignment -name VERILOG_MACRO "WITH_SPI_SSEL=1"
set_global_assignment -name VERILOG_MACRO "AX_PORT=1"
set_global_assignment -name VERILOG_MACRO "SER_FIFO_ALTERA=1"
set_global_assignment -name VERILOG_MACRO "SPI_TIMEOUT_1024=1"

View file

@ -1,8 +1,7 @@
create_clock -name xclk -period 31.25 xclk
create_clock -name spi_sck -period 200 spi_sck
create_clock -name ARxC -period 10 S_IN
create_clock -name xclk -period 83.333 xclk
derive_pll_clocks
derive_clock_uncertainty
set_false_path -from spi_sck -to xclk
set_false_path -from xclk -to spi_sck
set_false_path -from ARxC -to xclk
set_false_path -from xclk -to ARxC
set_false_path -from spi_sck -to {pll|altpll_component|auto_generated|pll1|clk[3]}
set_false_path -from {pll|altpll_component|auto_generated|pll1|clk[3]} -to spi_sck

View file

@ -22,214 +22,17 @@ module thhor_crs
inout [7:0] P33
);
// no pll, the quarz is 32 MHz, as required.
wire mclk = xclk;
parameter ND=4;
///FIFO definitions
parameter NFIFO = 6;
wire [NFIFO:1] fifo_push, fifo_full;
wire [15:0] fifo[1:NFIFO], fsiz[1:NFIFO], fhma[1:NFIFO], fhva[1:NFIFO];
wire [3:1] fifo_halffull;
wire pll_locked;
wire mclk;
pll192 pll(.inclk0(xclk),
.c3(mclk),
.locked(pll_locked)
);
// packets that are generated on request only.
parameter FIFO_MUX = 1;
parameter FIFO_CNTR = 4;
parameter FIFO_BATE = 5;
parameter FIFO_HK = 6;
wire we, wp, re;
wire [13:0] wa;
wire [15:0] wd, rd, resets, confs;
wire stick;
wire [14:0] states, strobes;
wire [31:0] clock;
reg [15:0] fifo_mux, fsiz_mux, fhma_mux, fhva_mux;
reg fifo_mux_push;
assign fifo_push[FIFO_MUX] = fifo_mux_push;
assign fifo[FIFO_MUX] = fifo_mux;
assign fsiz[FIFO_MUX] = fsiz_mux;
assign fhma[FIFO_MUX] = fhma_mux;
assign fhva[FIFO_MUX] = fhva_mux;
assign fifo_full[NFIFO:4] = {(NFIFO-3){fifo_full[FIFO_MUX]}};
integer ii;
reg r;
assign spi_miso = r;
always @(posedge mclk)
begin
if (resets[4+FIFO_MUX])
fsiz_mux <= 0;
for (ii=4; ii<=NFIFO; ii=ii+1)
if (fifo_push[ii])
begin
fifo_mux <= fifo[ii];
fsiz_mux <= fsiz[ii];
fhma_mux <= fhma[ii];
fhva_mux <= fhva[ii];
end
fifo_mux_push <= |fifo_push[NFIFO:4];
end
frontend front
(.mclk(mclk),
.spi_ssel(~spi_ssel), .spi_sck(spi_sck), .spi_mosi(spi_mosi), .spi_miso(spi_miso),
.sclk(mclk), .ARxC(S_IN), .ARxD(D_IN), .ATxC(S_OUT), .ATxD(D_OUT),
.states(states), .strobes(strobes),
.we(we), .wp(wp), .wa(wa), .wd(wd), .re(re), .rd(rd),
.errors(), .stats(), .resets(resets), .confs(confs), .clock(),
.conf3(),
.fifo_push(fifo_push[3:1]), .fifo_full(fifo_full[3:1]),
.fifo_halffull(fifo_halffull),
.fifo1(fifo[1]), .fifo2(fifo[2]), .fifo3(fifo[3]),
.fsiz1(fsiz[1]), .fsiz2(fsiz[2]), .fsiz3(fsiz[3]),
.fhma1(fhma[1]), .fhma2(fhma[2]), .fhma3(fhma[3]),
.fhva1(fhva[1]), .fhva2(fhva[2]), .fhva3(fhva[3]),
.fsma1(64'b0), .fsma2(64'b0), .fsma3(64'b0),
.tick(stick) );
parameter NHIT = 3*ND + 1;
wire [NHIT-1:0] counter_hit;
parameter CNTR_ADDR = 'h 240;
wire read_counters = we & wa[13:4]==CNTR_ADDR[13:4];
assign fhma[FIFO_CNTR] = 16'h ffff;
nm_counters #(.N(NHIT)) counters
( .clk(mclk),
.clear(resets[1] | read_counters & wa[2] & (~fifo_full[FIFO_CNTR] | ~wa[3])),
.read(~fifo_full[FIFO_CNTR] & read_counters & wa[3]),
.read_size(wa[1:0]),
.clock(clock),
.hit(counter_hit),
.fifo_push(fifo_push[FIFO_CNTR]),
.fifo(fifo[FIFO_CNTR]),
.fifo_size(fsiz[FIFO_CNTR]),
.fifo_head(fhva[FIFO_CNTR]) );
parameter BATE_ADDR = 'h 0300; // 'h 037f
wire we_bate = we & (wa[13:7] == BATE_ADDR[13:7]);
assign fhma[FIFO_BATE] = 'h ffff;
pressure #(.CLK96(32_000_000)) bate
( .clk96(mclk),
.MCLK(pt_MCLK),
.SCLK(pt_SCLK),
.Din(pt_Din),
.Dout(pt_Dout),
.we(we_bate),
.wa({1'b0, wa[6:0]}),
.fifos(fsiz[FIFO_BATE]),
.fifoh(fhva[FIFO_BATE]),
.fifoe(fifo_push[FIFO_BATE]),
.fifof(fifo_full[FIFO_BATE]),
.fifo(fifo[FIFO_BATE]) );
parameter HK_MAGIC = 16'h 5710;
parameter SA_MAGIC = 16'h 5714;
parameter EV_MAGIC = 16'h 5718;
assign fhva[FIFO_HK] = HK_MAGIC;
assign fhva[2] = EV_MAGIC;
assign fhva[3] = SA_MAGIC;
assign fhma[FIFO_HK] = 16'h ffff;
assign fhma[2] = 16'h ffff;
assign fhma[3] = 16'h ffff;
assign fsiz[FIFO_HK] = 8*ND;
assign fsiz[3] = 3*ND + 2;
thhor_core core
( .mclk(mclk),
.we(we), .wp(wp), .wa(wa), .wd(wd), .re(re), .rd(rd),
.confs(confs), .resets(resets),
.ax_states(states), .ax_strobes(strobes),
.fifo_e({fifo_push[3:2], fifo_push[FIFO_HK]}),
.fifo1(fifo[FIFO_HK]), .fifo2(fifo[2]), .fifo3(fifo[3]),
.afull({fifo_full[3:2], fifo_full[FIFO_HK]}),
.ev_psize(fsiz[2]),
.counter_hit(counter_hit), .stick(stick), .clock(clock),
.SCLK(ADC_SCK), .nCS(ADC_nCS), .DIN(ADC_DIN), .DOUT(ADC_DOUT) );
if (spi_ssel)
r <= spi_mosi;
endmodule // thhor_crs
`ifdef SIMULATION
`timescale 1ns/1ps
`ifdef THHOR_CRS_TEST
module thhor_crs_test;
wire sclk, mosi, miso;
ssp_test spi(.sclk(sclk), .mosi(mosi), .miso(miso));
wire xclk;
wire [3:0] SCLK, nCS, DIN, DOUT;
stis_ana_jig #(.SLICES(1), .ND(4)) jig
( .xclk(xclk), .SCLK(SCLK[0]), .nCS(nCS[0]), .DIN(DIN[0]), .DOUT(DOUT));
always @(jig.send_command)
begin
if (jig.awp)
spi.cmdp(jig.awa, jig.awd);
else
spi.cmd(jig.awa);
-> jig.end_command;
end
wire pt_MCLK, pt_SCLK, pt_Din, pt_Dout;
ms5540c_sim bate(pt_MCLK, pt_SCLK, pt_Din, pt_Dout);
thhor_crs dut
(
.xclk(xclk),
.S_IN(1'b0),
.spi_ssel(1'b1), .spi_sck(sclk), .spi_mosi(mosi), .spi_miso(miso),
.pt_MCLK(pt_MCLK), .pt_SCLK(pt_SCLK), .pt_Din(pt_Din), .pt_Dout(pt_Dout),
.ADC_SCK(SCLK), .ADC_nCS(nCS), .ADC_DIN(DIN), .ADC_DOUT(DOUT)
);
initial
begin
$dumpfile("vcd/thhor_crs.fst");
$dumpvars(0);
#100 spi.verbose <= 2;
#100 spi.frame(0);
#4_000; // force a frame timeout
#100 spi.frame(0);
spi.rx_idle = 16'h 0000;
spi.cmdp(dut.front.SPIDE_ADDR, spi.rx_idle);
spi.cmdp(dut.front.HKSZ_ADDR, 0);
spi.cmd(dut.front.MRSTS_ADDR);
spi.cmdp(dut.front.MCONF_ADDR+3, 16'b 0000_1000_1111_1000);
spi.cmdp(dut.core.MISC_ADDR+11, 16'b 0000_0001_0000_1000);
spi.cmdp(dut.front.MRSTS_ADDR, 16'b 0000_0001_1111_1100);
jig.l1_conf;
jig.l2_conf;
jig.l3_conf;
spi.cmdp(dut.core.DORN_ADDR+'h8, 16'h 0e0e);
spi.cmdp(dut.core.DORN_ADDR+'h9, 16'h 000e);
spi.cmdp(dut.core.DORN_ADDR+'ha, 16'h 0000);
spi.cmdp(dut.core.DORN_ADDR+'hb, {8'b 01, 8'd 16});
spi.cmdp(dut.front. MCONF_ADDR+2, 16'b 0000_0000_0000_0001);
#30000;
jig.pulse(0,0,1);
jig.pulse(0, 'b 00_01, 0);
#20000 jig.pulse(0, 'b 01_11, 0);
#4000 jig.pulse(0, 'b 10_10, 0);
#50000 jig.pulse(0, 'b 00_01, 3);
#1000 jig.pulse(0, 'b 01_11, 1);
#20000 jig.pulse(0, 'b 10_10, 1);
repeat(100) spi.cmd(0);
spi.cmd(dut.CNTR_ADDR + 'b 1111);
repeat(100) spi.cmd(0);
spi.cmd(dut.BATE_ADDR + 'b 0111_1111);
repeat(1000) spi.cmd(0);
spi.cmdp(dut.core.MISC_ADDR+11, 16'b 0000_0000_0001_0000);
repeat(2000) spi.cmd(0);
#10000 $finish();
end
endmodule
`endif
`endif

View file

@ -1,10 +1,10 @@
quartus/thhor_crs.asm.rpt:Warning (18236): Number of processors has not been specified which may cause overloading on shared machines. Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
quartus/thhor_crs.asm.rpt:Info: Quartus Prime Assembler was successful. 0 errors, 1 warning
quartus/thhor_crs.fit.rpt: 19. I/O Assignment Warnings
quartus/thhor_crs.fit.rpt: 21. I/O Assignment Warnings
quartus/thhor_crs.fit.rpt:; Force Fitter to Avoid Periphery Placement Warnings ; Off ; Off ;
quartus/thhor_crs.fit.rpt:; I/O Assignment Warnings ;
quartus/thhor_crs.fit.rpt:Warning (18236): Number of processors has not been specified which may cause overloading on shared machines. Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
quartus/thhor_crs.fit.rpt:Warning (18550): Found RAM instances implemented as ROM because the write logic is disabled. One instance is listed below as an example.
quartus/thhor_crs.fit.rpt:Warning (15564): Compensate clock of PLL "pll192:pll|altpll:altpll_component|pll192_altpll:auto_generated|pll1" has been set to clock3
quartus/thhor_crs.fit.rpt:Warning (292013): Feature LogicLock is only available with a valid subscription license. You can purchase a software subscription to gain full access to this feature.
quartus/thhor_crs.fit.rpt:Warning (15714): Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details
quartus/thhor_crs.fit.rpt:Warning (176674): Following 4 pins are differential I/O pins but do not have their complement pins. Hence, the Fitter automatically created the complement pins.
@ -13,102 +13,27 @@ quartus/thhor_crs.fit.rpt: Warning (176118): Pin "D_OUT" is a differential I/
quartus/thhor_crs.fit.rpt: Warning (176118): Pin "S_IN" is a differential I/O pin but does not have its complement pin. Hence, fitter automatically created the complement pin "S_IN(n)"
quartus/thhor_crs.fit.rpt: Warning (176118): Pin "D_IN" is a differential I/O pin but does not have its complement pin. Hence, fitter automatically created the complement pin "D_IN(n)"
quartus/thhor_crs.fit.rpt:Critical Warning (169085): No exact pin location assignment(s) for 1 pins of 56 total pins. For the list of pins please refer to the I/O Assignment Warnings table in the fitter report.
quartus/thhor_crs.fit.rpt:Warning (176225): Can't pack node r to I/O pin
quartus/thhor_crs.fit.rpt:Warning (176250): Ignoring invalid fast I/O register assignments. See the Ignored Assignments panel in the Fitter Compilation Report for more information.
quartus/thhor_crs.fit.rpt:Warning (171167): Found invalid Fitter assignments. See the Ignored Assignments panel in the Fitter Compilation Report for more information.
quartus/thhor_crs.fit.rpt:Warning (169177): 15 pins must meet Intel FPGA requirements for 3.3-, 3.0-, and 2.5-V interfaces. For more information, refer to AN 447: Interfacing Cyclone 10 LP Devices with 3.3/3.0/2.5-V LVTTL/LVCMOS I/O Systems.
quartus/thhor_crs.fit.rpt:Warning (169203): PCI-clamp diode is not supported in this mode. The following 1 pins must meet the Intel FPGA requirements for 3.3V, 3.0V, and 2.5V interfaces if they are connected to devices other than the supported configuration devices. In these cases, Intel recommends termination method as specified in the Application Note 447.
quartus/thhor_crs.fit.rpt:Warning (169064): Following 27 pins have no output enable or a GND or VCC output enable - later changes to this connectivity may change fitting results
quartus/thhor_crs.fit.rpt:Info: Quartus Prime Fitter was successful. 0 errors, 15 warnings
quartus/thhor_crs.map.rpt:; ctick ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; fifo_e ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; fifo ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; afull ; Input ; Warning ; Declared by entity but not connected by instance. If a default value exists, it will be used. Otherwise, the port will be connected to GND. ;
quartus/thhor_crs.map.rpt:; fifo_nonblock ; Input ; Warning ; Declared by entity but not connected by instance. If a default value exists, it will be used. Otherwise, the port will be connected to GND. ;
quartus/thhor_crs.map.rpt:; rbo ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; ff_full ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; ff_half ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; ff_empty ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; ff_packet ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; trigger ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; RXn ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; fempty ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; fifo_empty ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; attn ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.fit.rpt:Info: Quartus Prime Fitter was successful. 0 errors, 16 warnings
quartus/thhor_crs.map.rpt:; c0 ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; c1 ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; c2 ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:; c4 ; Output ; Warning ; Declared by entity but not connected by instance. Logic that only feeds a dangling port will be removed. ;
quartus/thhor_crs.map.rpt:Warning (18236): Number of processors has not been specified which may cause overloading on shared machines. Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
quartus/thhor_crs.map.rpt:Warning (10335): Unrecognized synthesis attribute "synthesis" at solo/altera/serializer.v(…)
quartus/thhor_crs.map.rpt:Warning (10335): Unrecognized synthesis attribute "synthesis" at solo/altera/adc128s102.v(…)
quartus/thhor_crs.map.rpt:Warning (10335): Unrecognized synthesis attribute "synthesis" at solo/altera/adc128s102.v(…)
quartus/thhor_crs.map.rpt:Warning (10335): Unrecognized synthesis attribute "synthesis" at solo/altera/adc128s102.v(…)
quartus/thhor_crs.map.rpt:Warning (10335): Unrecognized synthesis attribute "synthesis" at solo/altera/adc128s102.v(…)
quartus/thhor_crs.map.rpt:Warning (10335): Unrecognized synthesis attribute "synthesis" at solo/altera/adc128s102.v(…)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at itof.v(…): truncated value with size 30 to match size of target (12)
quartus/thhor_crs.map.rpt:Warning (10036): Verilog HDL or VHDL warning at dorn.v(…): object "dtrig_en" assigned a value but never read
quartus/thhor_crs.map.rpt:Warning (10036): Verilog HDL or VHDL warning at dorn.v(…): object "atrig_en" assigned a value but never read
quartus/thhor_crs.map.rpt:Warning (10036): Verilog HDL or VHDL warning at dorn.v(…): object "sa_triggers" assigned a value but never read
quartus/thhor_crs.map.rpt:Warning (10036): Verilog HDL or VHDL warning at dorn.v(…): object "adc_valid" assigned a value but never read
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 4 to match size of target (3)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 5 to match size of target (4)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 6 to match size of target (5)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 13 to match size of target (12)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 24 to match size of target (12)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 48 to match size of target (12)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 96 to match size of target (12)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at dorn.v(…): truncated value with size 192 to match size of target (12)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at divider.v(…): truncated value with size 40 to match size of target (39)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at divider.v(…): truncated value with size 40 to match size of target (39)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at divider.v(…): truncated value with size 40 to match size of target (39)
quartus/thhor_crs.map.rpt:Warning (10230): Verilog HDL assignment warning at divider.v(…): truncated value with size 17 to match size of target (16)
quartus/thhor_crs.map.rpt:Warning (14284): Synthesized away the following node(s):
quartus/thhor_crs.map.rpt: Warning (14285): Synthesized away the following RAM node(s):
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[0]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[1]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[2]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[3]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[4]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[5]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[6]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[7]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[8]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[9]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[10]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[11]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[12]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[13]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[14]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fsa|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[15]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[0]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[1]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[2]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[3]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[4]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[5]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[6]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[7]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[8]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[9]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[10]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[11]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[12]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[13]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[14]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fev|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[15]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[0]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[1]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[2]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[3]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[4]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[5]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[6]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[7]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[8]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[9]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[10]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[11]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[12]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[13]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[14]"
quartus/thhor_crs.map.rpt: Warning (14320): Synthesized away node "thhor_core:core|stis_slice:stis|packetfifo:fhk|spififo:fifo|scfifo:scfifo_component|scfifo_r1c1:auto_generated|a_dpfifo_5l61:dpfifo|altsyncram_hfj1:FIFOram|q_b[15]"
quartus/thhor_crs.map.rpt:Warning (12241): 4 hierarchies have connectivity warnings - see the Connectivity Checks report folder
quartus/thhor_crs.map.rpt:Warning (10034): Output port "ADC_nCS" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "ADC_SCK" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "ADC_DIN" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "pt_MCLK" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "pt_SCLK" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "pt_Din" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "S_OUT" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (10034): Output port "D_OUT" at thhor_crs.v(…) has no driver
quartus/thhor_crs.map.rpt:Warning (12241): 1 hierarchies have connectivity warnings - see the Connectivity Checks report folder
quartus/thhor_crs.map.rpt:Warning (13039): The following bidirectional pins have no drivers
quartus/thhor_crs.map.rpt: Warning (13040): bidirectional pin "P25[0]" has no driver
quartus/thhor_crs.map.rpt: Warning (13040): bidirectional pin "P25[1]" has no driver
@ -137,6 +62,35 @@ quartus/thhor_crs.map.rpt: Warning (13040): bidirectional pin "P33[4]" has no
quartus/thhor_crs.map.rpt: Warning (13040): bidirectional pin "P33[5]" has no driver
quartus/thhor_crs.map.rpt: Warning (13040): bidirectional pin "P33[6]" has no driver
quartus/thhor_crs.map.rpt: Warning (13040): bidirectional pin "P33[7]" has no driver
quartus/thhor_crs.map.rpt:Info: Quartus Prime Analysis & Synthesis was successful. 0 errors, 238 warnings
quartus/thhor_crs.map.rpt:Warning (13024): Output pins are stuck at VCC or GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "pt_MCLK" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "pt_SCLK" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "pt_Din" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_nCS[0]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_nCS[1]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_nCS[2]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_nCS[3]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_SCK[0]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_SCK[1]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_SCK[2]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_SCK[3]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_DIN[0]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_DIN[1]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_DIN[2]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "ADC_DIN[3]" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "S_OUT" is stuck at GND
quartus/thhor_crs.map.rpt: Warning (13410): Pin "D_OUT" is stuck at GND
quartus/thhor_crs.map.rpt:Warning (15897): PLL "pll192:pll|altpll:altpll_component|pll192_altpll:auto_generated|pll1" has parameter compensate_clock set to clock0 but port CLK[0] is not connected
quartus/thhor_crs.map.rpt:Warning (15899): PLL "pll192:pll|altpll:altpll_component|pll192_altpll:auto_generated|pll1" has parameters clk0_multiply_by and clk0_divide_by specified but port CLK[0] is not connected
quartus/thhor_crs.map.rpt:Warning (21074): Design contains 8 input pin(s) that do not drive logic
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "spi_sck"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "pt_Dout"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "ADC_DOUT[0]"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "ADC_DOUT[1]"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "ADC_DOUT[2]"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "ADC_DOUT[3]"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "S_IN"
quartus/thhor_crs.map.rpt: Warning (15610): No output dependent on input pin "D_IN"
quartus/thhor_crs.map.rpt:Info: Quartus Prime Analysis & Synthesis was successful. 0 errors, 67 warnings
quartus/thhor_crs.sta.rpt:Warning (18236): Number of processors has not been specified which may cause overloading on shared machines. Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
quartus/thhor_crs.sta.rpt:Info: Quartus Prime Timing Analyzer was successful. 0 errors, 1 warning

File diff suppressed because it is too large Load diff

2
src/.gitignore vendored
View file

@ -1,3 +1 @@
thhor.userrow
*.s
revision.h

View file

@ -1,27 +1,34 @@
PROJ=thhor
_R := $(shell ./update_revision.sh)
PATH:=/usr/local/bin:$(PATH)
VPATH=.:bch4369
default: all
all: $(PROJ).hex $(PROJ)_all
thhor_all: thhor.eeprom thhor.userrow
thhor_all: thhor.eeprom
CFLAGS_thhor = -Ibch4369 -DHAVE_FPGA -DSEND_HEX -DTHHOR
MCU_thhor = attiny3224
SN_thhor = 1
# Link order defines ADC packet composition
# main() is first, with .bss.magic
# config.c includes .eeprom `port_config`, that should go second
# .bss: rtc, adc, flash, uart, spi, pipe
C_FILES_thhor = config.c rtc.c adc.c flash.c uart.c cmd.c base85.c pwm.c spi.c bch4369.c pipe.c fpga.c
S_FILES_thhor = uart_tx.S base85a.S spi_poll.S
C_FILES_thhor = config.c uart.c cmd.c base85.c rtc.c adc.c pwm.c spi.c flash.c bch4369.c
S_FILES_thhor = uart_tx.S base85a.S
dose_all: dose.eeprom dose.userrow
SN_dose = 1
MCU_dose = $(MCU_$(VAR))
MCU_nFETs = attiny424
MCU_FPGA = attiny3224
VAR=nFETs
C_FILES_nFETs =
C_FILES_FPGA = fpga.c
CFLAGS_dose = -DHAVE_$(VAR)
C_FILES_dose = config.c rtc.c adc.c pwm.c $(C_FILES_$(VAR)) uart.c cmd.c pipe.c base85.c bch4369.c spi.c flash.c
S_FILES_dose = uart_tx.S base85a.S
MCU = $(MCU_$(PROJ))
OPT = -Os -fverbose-asm
OPT = -Os
CC=avr-gcc -Wall -Wno-parentheses -MMD -std=c99 $(OPT) \
-mmcu=$(MCU) \
@ -75,24 +82,23 @@ pMCU-attiny824 = t824
pMCU-attiny3224 = t3224
# WDT
fuse0_thhor= 0x00
fuse0_dose= 0x00
# BOD
fuse1_thhor= 0x00
fuse1_dose= 0x00
# OSC, 20 MHz
fuse2_thhor= 0x7e
# Reserved
fuse3_thhor= 0xff
# Reserved
fuse4_thhor= 0xff
fuse2_dose= 0x7e
# ???
fuse4_dose= 0xff
# SYS0 (default 0xf6) RESET, EEPROM erase
fuse5_thhor= 0xf7
fuse5_dose= 0xf7
# SYS1 startup time (64ms)
fuse6_thhor= 0xff
fuse6_dose= 0xff
# APPEND
fuse7_thhor= 0x00
fuse7_dose= 0x00
# BOOTEND
fuse8_thhor= 0x00
fuses_thhor =$(patsubst %, 0x%, 00 00 7e ff ff f7 ff 00 00)
fuse8_dose= 0x00
fuses_dose =$(patsubst %, 0x%, 00 00 7e ff ff f7 ff 00 00)
fuses_thhor = $(fuses_dose)
AVRDUDEPROG = avrdude
AVRDUDE = $(AVRDUDEPROG)
@ -101,6 +107,8 @@ AVRDUDE_PORT = /dev/ttyUSB0
AD = $(AVRDUDE) -p $(pMCU-$(MCU)) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
sig_dose = 0x1e 0x92 0x2c
sig_thhor = 0x1e 0x95 0x28

View file

@ -1,162 +1,194 @@
# THHOR Cosmic Ray Sensor
# Turbo Weather
## ATtiny3224 resources
## ATtiny424SS resources
- `TCA0`: ADC trigger clock
- `SPI0-PA1…3, 7`: communication with flash and FPGA
- `USART0-RxD/TxD-PB0,2…3`: transmission of data, receive commands
- `TCA0-WO0-PB0`: generate the 32768kHz clock for the MS5534C
- `SPI0-PA1…3`: communication with the MS5534C
- `USART0-RxD/TxD-PB2…3`: transmission of data, receive commands
- `PORTB-PB1`: enable the RF power regulator
- `ADC`: internal sources.
- `PORTA-PA5`: light up the LED
- `ADC0-PA4,6,7`: read Batterie, NTC, and RF power voltage, and internal sources.
- `PIT`: generate clock tick, to wake the µC once per second from deep sleep.
- `RTC`: clock
- `USERROW`: store persistent configuration
- `EEPROM`: io configuration, `ADC` readings configuration
- `RAM`: 32 byte TX buffer, 32 bytes RX buffer, 80 bytes
`flash_buffer`, here called _block buffer_.
- `EEPROM`: store `ADC` readings configuration, store sensor test data records.
- `RAM`: 256 byte TX buffer, 16 bytes RX buffer, ~128 bytes stack.
- `FLASH`: pretty full. With lots of assembly, -O2 fits with -DDEBUG.
## Source files
- `thhor.c`: main program,
- `config.c`: io configuration, userrow config,
- `adc.c`: configure and run the ADC,
- `rtc.c`: configure the _periodic interrupt timer_ `PIT`,
- `spi.c`: configure the `SPI0` and run a 16-bit frame,
- `uart.c`: configure the `USART0`, provide Tx and Rx buffers for IO,
- `uart_tx.S`: assembly implemention for uart,
- `base85.c`: Base85 encode/decode 16-bytes `cmd_buffer` on UART,
- `base85a.S` assembly implemention for bch4369,
- `cmd.c`: parse and run commands received from the UART,
- `flash.c`: talk to the flash via SPI,
- `bch4369.c`: EDAC on flash pages,
- `flga.c`: talk to the FPGA via SPI,
- `pipe.c`: move data streams.
- `bate.c`: main program, interface to the MS5534C
- `calib.c`: calculate the calibrated the pressure sensor readings.
- `adc.c`: configure and run the ADC, calculate calibrated results
- `mul.c`: handcraft 16-bit multiplication and decimal printing.
- `rtc.c`: configure the _periodic interrupt timer_ `PIT`.
- `spi.c`: configure the `SPI0` and run a 16-bit frame.
- `uart.c`: configure the USART0, provide Tx and Rx buffers for IO.
- `cmd.c`: parse and run simple commands received from the UART.
## UART protocol
## Output records
The host sends commands consisting of
- a capital letter,
- flags, ASCII between ' ' and 'A',
- optionally one space and 16 base85 encoded `data` bytes, and
- a newline.
The programm issues several types of output lines. Each type is
prefixed with a unique capital letter.
When the first flag is a digit `0``4`, it selects a section of the
block buffer. When no section is selected, the command operates on
the `data` buffer directly, where applicable.
- `V`: sent at boot, a greeting and version.
- `B`: sent at boot, a single byte `RSTCTRL.RSTFR`, the reset reason.
- `S`: config record (`SEND_CONFIG`): hex dump of the `SIGROW`.
- `F`: config record (`SEND_CONFIG`): hex dump of the `FUSES`.
- `U`: config record (`SEND_CONFIG`): hex dump of the `USERROW`.
- `C`: config record (`SEND_CONFIG`): hex dump of the `config` structure in `RAM`.
- `E`: config record (`SEND_CONFIG`): hex dump of the ADC configuration in `EEPROM`.
- `W`: calibration record (`SEND_BATEW`): sensor calibration data (hex) read from the sensor.
- `D`: sensor record (`SEND_BATED`): sensor reading data (hex) acquired from the sensor.
- `P`: pressure record (`SEND_CALIB`): sensor readings in natural units.
- `A`: ADC readings (`SEND_ADC_HEX`): hex words, 16-bit range.
- `V`: ADC readings (`SEND_ADC_VOLT`): calibrated, natural units.
- `X`: Debug (`SEND_DEBUG`): hex dump of the `debug_data` structure.
- `R`: command reception.
When the last flag is a half-mesh `=` and there is no `data`, and the
previous command was the same letter, then the `data` of the previous
command is used again, possibly modified by the previous command
execution.
Config records are sent at boot, with test data, and when enabled via
`SEND_CONFIG` with a subset of sensor readings. The config byte `confp`
is the number of readings sent in between without sending config records.
The µC answers with
- a mesh `#`,
- the command letter and used flags,
- optionally one space and 16 base85 encoded `data` bytes,
- a newline.
Debug data is only available when not disabled during compilation. Do
`make DEBUG=-DNODEBUG` to disable all debugging code and data.
In case of any error the answer is terminated with a what `?` and a newline,
without encoded data bytes.
The `SEND` flags are stored in byte[3] of the `config` structure to
enable the respective output records, with the bit positions
### Commands
- `SEND_CONFIG = 0x01`
- `SEND_BATED = 0x02`
- `SEND_BATEW = 0x04`
- `SEND_CLOCK = 0x08`
- `SEND_CALIB = 0x10`
- `SEND_ADC_HEX = 0x20`
- `SEND_ADC_VOLT = 0x40`
- `SEND_DEBUG = 0x80`
- `A`: ADC
## Configuration
All variants return number of completed channels.
There are two configued channels, T and Vcc.
* `A`: Return status.
* `A!`: Start conversions.
* `A<`: Return ADC readings.
At boot, the configuration is copied from the `USERROW` to the
`config` structure in `RAM`, if the first byte in the `USERROW` is
the magic `0xba`, and the second byte matches the version of the
`config` structure, currently `0x08`. Else, the defaults are used.
- `B`: Block buffer ops, return valid sections.
The config structure is
- `[0]`: `magic = 0xba`.
- `[1]`: `version = 0x08`.
- `[2]`: `triggers`: trigger enables.
- `[3]`: `send`: output data configuration.
- `[4]`: `power`: power management.
- `[5]`: `calib_test`: number of test records to send after a reset.
- `[6]`: `spi_div`: `SPI0.CTRLA.SPI_PRESC` \[÷64\]
- `[7]`: `mclk_delay`: number of `MCLK` ticks to wait before a reading.
- `[8]`: `period`: number of seconds-1 between readings.
- `[9]`: `confp`: number of readings without config records.
- `[10]`: `cpu_clk`: `CLKCTRL.MCLKCTRLB` \[÷2\]
- `[11]`: `mclk_period`: `TCA0.SINGLE.CMP0` \[÷76\]
- `[12]`: `baud_div`: two bytes little endian \[÷16667\]
- `[14]`: `uart_mode`: `USART0.CTRLB`
- `[15]`: `pit_period`: `RTC.CLKSEL` \[÷1024\]
- `[16]`: `immediate`: number of immediate readings at boot.
The block buffer is 80 bytes, in five sections.
One flash page is 8 blocks of 64 bytes, plus one section 4 for EDAC in the last block.
When no section is selected, the `data` is used in the cmd buffer.
* `B0``B4`: Select section.
* `B@`: Mark all sections invalid.
* `B0 data`: Fill the invalid selected section with the data and mark it valid..
* `B0! data`: Fill the selected section with the data even if it is valid.
* `B…%@`: Reset the BCH4369 parity.
* `B…%`: Add the selected section/data to the parity.
* `B…%!`: Complete the parity and copy to section 4 in the block buffer.
* `B…<`: Return valid data from the selected section and mark it invalid.
* `B…<!`: Return data from the selected section, evcen when invalid, and do not mark is invalid.
### Triggers
The operations _write_, _parity_, and _read_ can be combined in
that order, as indicated by `…`.
The `triggers` byte\[2\] enables various reasons to do a sensor reading.
- 'C': FPGA command
* `C@`: reset the FPGA to unconfigured state.
* `C data`: send a command to the FPGA, up to 14 bytes that came back.
The command format is defined by `struct fpga_cmd`
- `TRIGGER_ONCE = 0x01`: one reading at boot.
- `TRIGGER_CONT = 0x02`: continuously read the sensor.
- `TRIGGER_UART = 0x04`: read the sensor when the UART Rx input toggles.
- `TRIGGER_CLOCK = 0x08`: read periodically, every `period`+1 _seconds_.
- `TRIGGER_BREAK = 0x10`: read continuously while the UART Rx input is low.
- `TRIGGER_IMMED = 0x20`: do any requested immediate readings.
- `D`: Find the first free page in the flash telemetry area.
_Seconds_ are define by the `PIT`. Those can be up to 8 real seconds
long, or much shorter. _Immediate_ readings can be requested at boot
or via the command `T`.
- `F`: Command to the flash chip via SPI.
* `F`: Return SPI status.
* `F data`: Submit command.
* `F!`: Poll SPI.
* `F<`: Return the answer.
### Power
- `M` peek/poke.
* `M data`: Execute a peek of poke.
* `M=`: Continue the just emitted peak/poke.
The bits in the power byte\[4\] are
`data` is a `struct peek_poke`. Up to 12 bytes can be transfered by each call.
Writing to EEPROM requires a key for the CCP.
- `POWER_DOWN = 0x01`: Enter `POWER_DOWN` sleep between readings.
- `POWER_DOWN_CLI = 0x02`: Disable interrupts before `POWER_DOWN`.
- `STOP_MCLK = 0x04`: Stop the `MCLK` after the reading.
- `POWER_LED = 0x08`: Turn on the LED during a reading.
- `POWER_STDBY = 0x10`: Enter `STANDBY` sleep between readings.
- `POWER_RX = 0x20`: Do not `POWER_DOWN` when the `UART` Rx is active
- `POWER_RF = 0x40`: Turn on the RF transmitter power.
- `POWER_LINE = 0x80`: Send a preamble after rfen()
- `O`: Power/configure the FPGA, return FPGA status.
* `O0`: Turn power off.
* `O1`: Turn power on.
* `O2`: Configure from flash, if powered and unconfigured.
* `O3`: Power off, if unconfigured.
* `O4`: Configure from flash, unconditionally.
`POWER_STDBY` is sufficient to reduce the power to a minimum.
`POWER_RX` does not seem to work. From `POWER_DOWN_CLI` we shall
never wake up, unless the `WDT` is enabled in the fuses. When the
`MCLK` is stopped after a reading, it will be truned on and
`mclk_delay` ticks must pass before communication with the sensor
resumes. That delay is probably not necessary. `POWER_RF` is
necessary to bias the NTC measured by ADC readings. The `POWER_LINE`
preamble charges the AC-coupled output of the RF receiver to
properly receive subsequent characters.
- `P`: Pipe stream ops.
* `P@`: Stop current stream (clear all destinations).
* `P data`: confiure ans start a stream.
* `P.`: Poll the flash stream.
* `P,`: Poll the flash stream with ACK.
* `P!`: Poll the pipe.
## Commands
The poll options are usefull for debugging, when mainloop polling is on hold.
Do `poke("magic+2", 0x01, s=1)` to set the pipe polling on hold.
Commandlines received via the UART must be in the format
- `«C» {[«space»]+ «hex»}+ [«space»]+ «linefeed»`
## Pipe
A command letter, uppercase, and up to seven (optionally space
separated) hex bytes, optionally followed by more space characters and
a linefeed. A hex character is one or two hex digits, letters `a``f`
_must_ be lowercase. Obviously, a single hex digit must be separated
with space characters from any following byte. No spaces are required
at all when all bytes are written with two digits. The Rx buffer can
accomodate commandlines up to 15 bytes long, including the newline
char.
Data is moved in three levels of granularity:
- Page: 512(528) bytes, the native page size of the external flash.
- Block: 64(80) bytes of µC RAM.
- Cmd: 16 Bytes of cmd `data` payload.
The parser echos the received line, preceeded with the string `R>`.
When the command is valid, the answer bytes are sent prefixed with
`R!`. Invalid commands are answered with `R?`.
The excess 16 Bytes of a flash page are used for parity. The BCH4369
code allows to correct up to 8 bit errors in a page. The required math
cannot be implemented on the µC. But generatring parity and comparing
to stored parity for error detection is implemented. It is not fast.
The python code can run the error correction on the ground.
Most commands require a specific number of hex bytes as arguments. As
currently implemented, all commands echo all their arguments and one
additional byte.
The pipe can check parity read from flash, it can generate parity on
the way to the flash, when CMD does not sent parity.
### List of commands:
The pipe data sources are:
- CMD, data received via `Bn data`.
- ADC/HK, all named `.bss` segments.
- Flash
- FPGA
- `R «ccp»`: Reboot the µC. The argument byte must be `d8`, the
`CCP[IOREG]` key, to validate the reset.
The pipe data destinations are
- CMD, data pulled via `Bn<`.
- Flash
- FPGA config
- FPGA
- `C «key» «bytes»…`: write to the `config` structure in `RAM`
- `U «key» «bytes»…`: write to persistent config in the `USERROW`
- `E «key» «bytes»…`: write to `EEPROM`
Streaming to multiple destinations is possible, as long as only one
requires the SPI. That leaves CMD and one of the others.
Up to six «bytes» are written. The «key» must be `9d`, the
`CCP[SPM]` key, for the persistent stores, and `ba` for the `RAM`.
These commands return the old value of the first byte that was
written.
- `T «n»`: trigger «n» more immediate sensor readings.
- `M «aaaa»`: reads any memory address «aaaa» (two bytes, big endian)
and prints the byte.
- `W «aaaa» «bb»`: write a byte «bb» into any address «aaaa», return
the old value of that memory location.
- `K «bb» «bb» «bb» «bb»`: set the clock. The 32-bit time value must
be sent little endian.
- `D «n»`: process and send calibrated readings for «n» test data
records. The `EEPROM` has space for up to five data records.
## Toolchain
The ATtiny3224 µC requires an up-to-date toolchain
The ATtiny424 µC requires an up-to-date toolchain
- binutits: `./configure --target=avr --program-prefix=avr-`
- gcc: `../gcc/configure --program-prefix=avr- --with-avrlibc --target=avr --enable-languages=c --disable-nls`
- avr-libc: `./configure --host=avr`
## TODO (all done)
- √ Use the SPI hardware to talk to the sensor.
- √ Send results via UART hardware.
- × Setup the watchdog. √ Use PIT instead
- √ Control power to the RF transmitter
- √ Light the LED.
- √ Readout the ADCs, thermistors.
- √ Readout the internal temperature sensor.

@ -1 +1 @@
Subproject commit 55612f3934f089d966fc4f5b000b8c41259d4375
Subproject commit eebd4bb43039a2ecf63aa7c2fdbe1c4edf469393

View file

@ -204,13 +204,13 @@ void parse_command(const uint8_t *s, uint8_t n)
case 'B':
if (cmd_flag('@'))
pipe.valid = 0;
r = pipe.valid | flash_current_block() << 5;
r = pipe.valid;
if (have_b) {
if (bflg && cmd_flag('!') || ~r & bflg) {
if (cmd_flag('!') || ~r & bflg) {
memcpy(bptr, cmd_buffer, 16);
pipe.valid = r |= bflg;
r = pipe.valid |= bflg;
}
else if (bflg)
else
goto error;
}
if (cmd_flag('%')) {
@ -220,14 +220,14 @@ void parse_command(const uint8_t *s, uint8_t n)
if (cmd_flag('!')) {
bch4369_fini();
memcpy(flash_buffer+64, bch_parity, 16);
pipe.valid = r |= 0x10;
r = pipe.valid |= 0x10;
}
}
if (cmd_flag('<')) {
if (cmd_flag('!')) goto send_buffer;
if (~r & bflg)
goto error;
pipe.valid = r &=~ bflg;
pipe.valid &=~ bflg;
goto send_buffer;
}
break;
@ -240,51 +240,28 @@ void parse_command(const uint8_t *s, uint8_t n)
r = flash_submit_command(cmd_buffer);
else
r = spi_busy_p();
if (cmd_flag('!'))
spi_poll();
if (cmd_flag('<'))
goto send_buffer;
break;
case 'P':
if (cmd_flag('@'))
pipe.dest = 0;
if (have_b)
pipe_config((void*)cmd_buffer, (void*)bptr);
if (cmd_flag('.'))
flash_poll(0);
else if (cmd_flag(','))
flash_poll(1);
if (cmd_flag('!'))
pipe_poll();
r = pipe.status | flash_current_block();
break;
#ifdef HAVE_FPGA
case 'O':
r = fpga_status();
if (bflg & 1)
// "O1" power off
fpga_power_off();
if (bflg >= 2) {
// "O2" power on
fpga_power_on();
if (!r) {
fpga_reset();
break;
}
}
if (bflg <= 2)
break;
if (bflg <= 8 && r==as_configured)
// "O2": configure if unconfigured
break;
if (bflg & 8) {
// "O3": power of if unconfigured
fpga_power_off();
break;
}
// "O4" configure unconditionally
fpga_config(config.fpga_config_page, config.fpga_config_count);
r = !!(PEN_VPORT.IN & (1<<PEN_PIN));
if (bflg == 1)
PEN_VPORT.OUT &=~ (1<<PEN_PIN);
else if (bflg == 2)
PEN_VPORT.OUT |= (1<<PEN_PIN);
break;
#endif
#ifndef THHOR
case 'P':
if (have_b)
pipe_config((void*)cmd_buffer);
else
r = pipe_poll();
break;
goto send_buffer;
break;
#ifdef HAVE_FPGA
case 'C':
if (cmd_flag('@')) {
fpga_reset();
@ -295,6 +272,7 @@ void parse_command(const uint8_t *s, uint8_t n)
fpga_cmd((void*)cmd_buffer);
goto send_buffer;
#endif
#endif // THHOR
case 'M':
if (!have_b)
goto error;

View file

@ -21,18 +21,12 @@ const struct config config = {
[0] = 0xd1 | FM_READ, // Buffer 1 Read (Low-Frequency)
[1] = 0xd3 | FM_READ, // Buffer 2 Read (Low-Frequency)
},
.page_start = 0x0400,
.page_start = 0x0800,
.page_end = 0x1000,
#ifdef HAVE_nFETs
.pwm_min = 0x0000,
.pwm_max = 0xffff,
#endif
#ifdef HAVE_FPGA
.fpga_config_page = 0x100,
.fpga_config_count = 3955,
.dorn_config_page = 8,
.dorn_config_count = 1,
#endif
};
////////////////////////////////////////////////////////////////////////////////

View file

@ -23,12 +23,6 @@ struct config {
uint16_t pwm_min;
uint16_t pwm_max;
#endif
#ifdef HAVE_FPGA
uint16_t fpga_config_page;
uint16_t fpga_config_count;
uint16_t dorn_config_page;
uint16_t dorn_config_count;
#endif
};
enum magic_flags {
@ -38,9 +32,8 @@ enum magic_flags {
#endif
#ifdef HAVE_FPGA
MAGIC = 0xC5,
VERSION = 0x00,
VERSION = 0x01,
#endif
hold_pipe = 0x01,
};
extern const struct config config;
@ -72,7 +65,7 @@ extern struct io_config ee9_start[], ee9_end[];
#define UART_VPORT VPORTB
#define UART_PORT PORTB
#define TxE_PIN 0
#define TxE_PIN 1
#define TxD_PIN 2
#define RxD_PIN 3
#define RxD_PINCTRL UART_PORT.PIN3CTRL
@ -161,14 +154,11 @@ void apply_config()
extern struct magic {
uint8_t magic;
uint8_t reset_source;
uint8_t flags;
} magic;
#if 0
#define _memcopy memcpy
#define _memcopyyz memcpy
#define _memcopyzy memcpy
#define _memcmpyz memcmp
#else
// avoid the avr-libc memcpy.
// ¡ n must not be zero !
@ -202,43 +192,6 @@ void _memcopyyz(uint8_t *d, uint8_t *s, uint8_t n)
:: "r0", "memory");
}
static inline
void _memcopyzy(uint8_t *d, uint8_t *s, uint8_t n)
{
__asm__ volatile ("\n"
"1:" "\n\t"
"ld r0, Y+" "\n\t"
"st Z+, r0" "\n\t"
"dec %[N]" "\n\t"
"brne 1b" "\n"
: [D] "+z" (d),
[S] "+y" (s),
[N] "+r" (n)
:: "r0", "memory");
}
static inline
uint8_t _memcmpyz(uint8_t *d, uint8_t *s, uint8_t n)
{
uint8_t r;
__asm__ volatile (
"\n"
"1:" "\n\t"
"ld %[R], Y+" "\n\t"
"ld r0, Z+" "\n\t"
"sub %[R], r0" "\n\t"
"breq 1f" "\n\t"
"dec %[N]" "\n\t"
"brne 1b" "\n"
"1:" "\n"
: [D] "+x" (d),
[S] "+y" (s),
[N] "+r" (n),
[R] "=r" (r)
:
: "r0", "memory");
return r;
}
#endif

View file

@ -1,696 +0,0 @@
import math, time, sys
def _connect(ifc):
global _ifc, acmd, rfifo, menable
_ifc = ifc
acmd = ifc.acmd
rfifo = ifc.rfifo
menable = ifc.menable
def degCβ(a, R1=10e3, R25=10e3, B25=3940, res=0x1000):
if not a:
a = 1
R = R1 * a / (res - (a & (res-1)))
T = B25/(math.log(R/R25) + B25/298) - 273
return T
def degC(a, idx=0):
return degCβ(a, **CONFIG.NTC[idx])
def HK_fmt(s, i, n, d):
return f"{i}. {n}: {repr(d)}\n"
def HK3_fmt(s, i, n, d):
return f"""{i}. {n}
T = {d[5]:6.2f} °C, GND = {d[0]:6.3f} V,
Vff = {d[1]:6.3f} V, Vnn = {d[2]:6.3f} V, Vpp = {d[3]:6.3f} V, Vdig = {d[4]:6.3f} V,
Vcc = {d[6]:6.3f} V, Vss = {d[7]:6.3f} V.
"""
def HK4_AHBGO_fmt(s, i, n, d):
return f"""{i}. {n}
Tbgo = {d[0]:6.2f} °C, {d[1]:6.2f} °C, {d[3]:6.2f} °C,
Vbias = {d[2]:6.3f} V, Ibias = {d[4]:6.1f} nA, {d[5]:6.1f} nA,
Vcc = {d[7]:6.3f} V, Vss = {d[6]:6.3f} V.
"""
def HK4_SETH_fmt(s, i, n, d):
return f"""{i}. {n}
Tpa = {d[4]:6.2f} °C, Tbgo = {d[3]:6.2f} °C, {d[5]:6.2f} °C,
Vbias = {d[2]:6.3f} V, Ibias = {d[1]:6.1f} nA, {d[0]:6.1f} nA,
Vcc = {d[7]:6.3f} V, Vss = {d[6]:6.3f} V.
"""
def HK7_SETH_fmt(s, i, n, d):
if s==0:
return f"""{i}. {n}
na = {repr(d[:4])}
Tpwr = {d[6]:.1f} °C,
Vprim = {d[5]:.1f} V, Iprim = {d[4]:.1f} mA,
Ibias = {d[7]:.1f} nA.
"""
return f"""{i}. {n}
na = {repr(d[:4])}
Text = {d[6]:.1f} °C,
Ibias = {d[4]:.1f} nA,
Ibias = {d[7]:.1f} nA, Vbias = {d[5]:.1f} V.
"""
def HK3_LEIA_fmt(s, i, n, d):
return f"""{i}. {n}
Tadc = {d[0]:6.2f} °C,
Vadc = {d[1]:6.3f} V,
VbiasD = {d[7]:6.2f} V,
Vbias2 = {d[6]:6.1f} V,
Vpp = {d[3]:6.3f} V, Vnn = {d[2]:6.3f} V,
Vcc = {d[5]:6.3f} V, Vss = {d[4]:6.3f} V.
"""
def HK4_LEIA_fmt(s, i, n, d):
return f"""{i}. {n}
Ibias1 = {d[3]:.1f} nA, Ibias2 = {d[2]:.1f} nA, IbiasD = {d[0]:.1f} nA,
VbiasG = {d[1]:.1f} V, Vbias1 = {d[4]:.1f} V,
Tpa0 = {d[5]:6.2f} °C, Tpa1= {d[6]:6.2f} °C, Tpa2 = {d[7]:6.2f} °C.
"""
def HK3_THHOR_fmt(s, i, n, d):
return f"""{i}. {n}
VssP = {d[0]:6.3f} V,
Vcore = {d[1]:6.3f} V,
Vcc = {d[2]:6.3f} V,
Vprim = {d[3]:6.2f} V,
"""
def HK4_THHOR_fmt(s, i, n, d):
return f"""{i}. {n}
VccP = {d[0]:6.3f} V,
VssS = {d[1]:6.3f} V,
VccS = {d[2]:6.3f} V,
Vpll = {d[3]:6.3f} V,
"""
def HK5_THHOR_fmt(s, i, n, d):
return f"""{i}. {n}
Ibias = {d[0]:6.1f} nA,
Vbias = {d[1]:6.1f} V,
Vdig = {d[2]:6.3f} V,
Vss = {d[3]:6.3f} V,
"""
def HK7_THHOR_fmt(s, i, n, d):
return f"""{i}. {n}
Tpa1 = {d[0]:6.2f} °C,
Tpa2 = {d[1]:6.2f} °C,
Tpa3 = {d[2]:6.2f} °C,
Tfpga = {d[3]:6.2f} °C,
"""
class DORN_CONFIG:
# stis_ana_core 2×24 ch
dorn_addr = 0x2000
verbose = True
slices = (0,1)
n_channels = 24
l2 = ( # set6
(0, -1203, 0),
(1, -1203, 0),
(2, -1203, 0),
(3, -1186, 0),
(4, -39, 2000),
(5, 1709, 970),
(6, 2000, -1082),
(7, 1125, -1888),
)
HK3 = [[
("GND",),
("Vff", 2.0),
("Vnn", 2.5, ("Vpp", -1.5)),
("Vpp", 2.0),
("Vdig", 2.0),
("Tadc", (degC, {})),
("Vcc", 2.0),
("Vss", 2.5, ("Vcc", -1.5)),
]]
HK = [
("INP₀", None, HK_fmt),
("INP₁", None, HK_fmt),
("INP₂", None, HK_fmt),
("HK ADC", HK3, HK3_fmt),
("HK PA", None, HK_fmt),
("VrefL", None, HK_fmt),
("VrefH", None, HK_fmt),
("HK_PWR", None, HK_fmt),
]
def n_adc(self):
return self.n_channels//3
def Vref(self, slice=None):
try:
return self.VREF[slice]
except:
pass
return 3.3
def n_trigs(self):
if self.n_channels > 16:
return self.n_adc()
return self.n_channels
def m_trigs(self):
return (1 << self.n_trigs()) - 1
NTC = [dict(R1=10e3, R25=10e3, B25=3940, res=0x1000),
dict(R1=22e3, R25=10e3, B25=3940, res=0x1000), ]
HK4_SETH = [
[
("Ibias₂", 10470/470 * 51/1051 * 100, -97),
("Ibias₁", 10470/470 * 51/1051 * 100, -135),
("Vbias", -1/0.047),
("Tbgo₁", (degC, {})),
("Tpa", (degC, {})),
("Tbgo₂", (degC, {})),
("Vss", 2.5, ("Vcc", -1.5)),
("Vcc", 2.0),
],
[
("Ibias₂", 10470/470 * 51/1051 * 100, -98),
("Ibias₁", 10470/470 * 51/1051 * 100, -112),
("Vbias", -1/0.047, 2.0),
("Tbgo₁", (degC, {})),
("Tpa", (degC, {})),
("Tbgo₂", (degC, {})),
("Vss", 2.5, ("Vcc", -1.5)),
("Vcc", 2.0),
],
]
HK7_SETH = [
[
("na₁",), ("na₂",), ("na₃",), ("na₄",),
("Iprim", 2000.0),
("Vprim", 16.3),
("Tpwr", (degC, {})),
("Ibias⁺", 100.0),
],
[
("na₁",), ("na₂",), ("na₃",), ("na₄",),
("Ibias", 100.0),
("Vbias⁺", 100.0),
("Text", (degC, {})),
("Ibias⁺", 100.0),
],
]
def seth(self):
# ! change the class attribute .HK
self.HK[4] = ("HK PA", self.HK4_SETH, HK4_SETH_fmt)
self.HK[7] = ("HK_PWR", self.HK7_SETH, HK7_SETH_fmt)
self.BGO = [(0,3), (0,12), (0,20), (1,3), (1,12), (1,20)]
HK4_AHBGO = [[
("Tbgo₁", (degC, {})),
("Tbgo₂", (degC, {})),
("Vbias1", -1/0.047),
("Tbgo₃", (degC, {})),
("Ibias₁", 10470/470 * 51/1051 * 100),
("Ibias₂", 10470/470 * 51/1051 * 100),
("Vss", 2.5, ("Vcc", -1.5)),
("Vcc", 2.0),
]]
def ahbgo(self):
# ! change the class attribute .HK
self.HK[4] = ("HK PA", self.HK4_AHBGO, HK4_AHBGO_fmt)
# calib 2025-11-25
Fluke_cal = 1/0.862
# SN2 dac, 14*HK3H, VbiasD
VbiasD_SN2 = [
[ 64, 0.51, 0.5 * Fluke_cal ],
[ 960, 1.85, 1.6 * Fluke_cal ],
[ 1984, 3.36, 2.9 * Fluke_cal ],
[ 4992, 7.85, 6.7 * Fluke_cal ],
[ 9984, 15.27, 13.1 * Fluke_cal ],
[ 14976, 22.56, 19.3 * Fluke_cal ],
[ 19968, 29.91, 25.6 * Fluke_cal ],
[ 20992, 31.42, 26.9 * Fluke_cal ],
[ 21440, 32.06, 27.5 * Fluke_cal ],
[ 21952, 32.83, 28.0 * Fluke_cal ],
[ 24960, 37.36, 28.6 * Fluke_cal ],
]
VbiasD_a = 0.033
VbiasD_b = 0.9918
HK3_LEIA = [[
("Tadc", (degC, {})),
("Vadc", 2.0),
("Vnn", 2.5, ("Vpp", -1.5)),
("Vpp", 2.0),
("Vss", 2.5, ("Vcc", -1.5)),
("Vcc", 2.0),
("Vbias2", -1/0.022 * 66.6/75.2),
("VbiasD", -14 * VbiasD_b - VbiasD_a),
]]
HK4_LEIA = [[
("IbiasD", 100., -1.4),
("VbiasG", 46.3, ("Vref", -45.3)),
("Ibias2", 10470/470 * 51/1051 * 100, -71.0),
("Ibias1", 10470/470 * 51/1051 * 100, -52.0),
("Vbias1", -1/0.047 * 44.7/48.5),
("Tpa0", (degC, {})),
("Tpa1", (degC, {})),
("Tpa2", (degC, {})),
]]
def leia(self):
self.VREF = (3.342,)
self.slices=(0,)
self.HK[3] = ("HK_AD", self.HK3_LEIA, HK3_LEIA_fmt)
self.HK[4] = ("HK_PA", self.HK4_LEIA, HK4_LEIA_fmt)
NTC_THHOR = (degC, dict(idx=1))
HK_THHOR = [
("V₃",
[[
("VssP", 2.5, ("VccP", -1.5)),
("Vcore", 1),
("Vcc", 2.505),
("Vprim", 11),
]],
HK3_THHOR_fmt),
("V₄",
[[
("VccP", 2),
("VssS", 2.5, ("VccS", -1.5)),
("VccS", 2),
("Vpll", 1.0012),
]],
HK4_THHOR_fmt),
("V₅,Ibias",
[[
("Ibias", 10470/470 * 51/1051 * 100, -7),
("Vbias", -8850/220, ("Vss", -8850/470)),
("Vdig", 2),
("Vss", 2.5034, ("Vcc", -1.505)),
]],
HK5_THHOR_fmt),
("Vref", None, HK_fmt),
("NTC",
[[
("Tpa0", NTC_THHOR),
("Tpa1", NTC_THHOR),
("Tpa2", NTC_THHOR),
("Tfpga", NTC_THHOR),
]],
HK7_THHOR_fmt),
]
def thhor(self):
self.slices=(0,)
self.n_channels = 12
self.VREF = [3.359] # ADC supply voltage
self.HK[3:] = self.HK_THHOR
CONFIG = DORN_CONFIG()
def hk(sl=0, what="print", data=None):
if not data:
menable()
fifo_enable(en=True, sl=sl, hk=True)
fifo_reset(sl=sl, hk=True)
strobe(sl=sl, hk=True)
time.sleep(0.1)
fifo_read(sl=sl, hk=True)
data=rfifo()
if data[0] != 0x5710 + sl:
raise ValueError("Read HK packet error", data)
if isinstance(data, str):
# HDORN … data line
if "x" in data:
return sl, None
data = data.split()
if data[0] != "HDORN":
return sl, None
data = list(map(int, data[1:]))
if sl is None:
sl = data[0] & 3;
if data[0] & 3 != sl:
return sl, None
if what=="data":
return sl, data
ND = CONFIG.n_adc()
NV = ND
data = [d & 0xfff for d in data]
data = [data[ND*i+1:ND*i+1+NV] for i in range(8)]
if what=="raw":
return sl, data
Vref = CONFIG.Vref(sl)/4096
ddata = []
VV = {"Vref": CONFIG.Vref(sl)}
deferred = []
for a in range(8):
V = {}
ddata.append(V)
HK = CONFIG.HK[a][1]
# cookbook:
# None
# (name, factor, offset)
# (name, factor, (offset_name, factor))
# (name, (func, {args}))
if not HK:
V.update({c:data[a][c] for c in range(ND)})
continue
HK = HK[sl % len(HK)]
for c in range(ND):
H = HK[c]
if len(H) > 1:
if isinstance(H[1], tuple):
data[a][c] = H[1][0](data[a][c], **H[1][1])
else:
data[a][c] *= Vref*H[1]
if len(H) > 2 and not isinstance(H[2], tuple):
data[a][c] += H[2]
if len(H) <= 2 or not isinstance(H[2], tuple):
V[H[0]] = data[a][c]
ddata[a][H[0]] = data[a][c]
else:
deferred.append((a,c,H))
VV.update(V)
while deferred:
ndef = []
nn = len(deferred)
for a,c,H in deferred:
if H[2][0] in VV:
data[a][c] += VV[H[2][0]] * H[2][1]
VV[H[0]] = data[a][c]
ddata[a][H[0]] = data[a][c]
else:
ndef.append((a,c,H))
deferred = ndef
if len(deferred) >= nn:
print("Unresolved offsets", repr(deferred), VV, file=sys.stderr)
break
if what=="cooked":
return sl, data
if what=="dict":
return sl, ddata
r = []
for a in range(8):
H=CONFIG.HK[a]
# (name, [cookbooks], fmt_function)
r.append(H[2](sl, a, H[0], data[a]))
if what=="print":
sys.stderr.write("".join(r))
return sl, r
def dorn_config(a, v=None, mes=None, slice=0):
verb = CONFIG.verbose
a |= CONFIG.dorn_addr | (slice<<11)
if v is None:
if not mes:
mes = f"dorn[0x{a:03x}]"
return acmd(a, task=mes, verb=verb)
if not mes:
mes = f"dorn[0x{a:03x}] = 0x{v:04x}"
if v is False:
acmd(a, task=mes, verb=verb)
else:
acmd(a, v, task=mes, verb=verb)
def thres(sl, ch, v):
dorn_config(0x040 | ch, v, slice=sl)
def write_l2(sl, ch, i, a, b):
dorn_config(0x400 | (ch<<4) | (i<<1) | 0, a & 0xffff, slice=sl)
dorn_config(0x400 | (ch<<4) | (i<<1) | 1, b & 0xffff, slice=sl)
def calib_l2(cal, coeff):
if cal is None:
return coeff
from numpy import array, floor, add, any
c = array(coeff)[:,1:] * cal
i = floor(c+0.5)
e = add.reduce(i)
v = e>0
w = e<0
while any(v) or any(w):
d = i - c
vv = d.argmax(axis=0)
ww = d.argmin(axis=0)
for x,f in enumerate(v):
if f:
i[vv[x],x] -= 1
for x,f in enumerate(w):
if f:
i[ww[x],x] += 1
e = add.reduce(i)
v = e>0
w = e<0
return [(x, int(ii[0]), int(ii[1])) for x, ii in enumerate(i)]
def l2filter(coeff=None, cal=None):
if coeff==None:
coeff = CONFIG.l2
for sl in CONFIG.slices:
for ch in range(CONFIG.n_channels):
c = coeff
if cal and cal[sl] and cal[sl][ch]:
c = calib_l2(cal[sl][ch], c)
for cc in c:
write_l2(sl, ch, *cc)
def write_l3(sl, ch, *p):
scales = (14, 14, 15, 15)
for i,pp in enumerate(p):
if isinstance(pp, float):
pp = int(pp * 2**scales[i])
dorn_config(0x100 | (ch<<2) | i, pp & 0xffff, slice=sl)
def l3banana(
# 2025-02-20-seth-pa1-4
p0 = -3839,
p2 = 13891,
p3 = 3579,
p4 = 22853 ):
for sl in CONFIG.slices:
for ch in range(CONFIG.n_channels):
write_l3(sl, ch, p0, p2, p3, p4)
def c16log2(A):
return int(math.ceil(16*math.log(1024*A)/math.log(2)))
def enable_trigger(sl, triggers, det=False, sa=False):
i = 2 if sa else 0 if det else 1
dorn_config(0x008 | i, triggers, slice=sl)
def nsamples(sl, n=None, m=None):
if n is None:
return dorn_config(0x00b, slice=sl)
if m is None:
m = 0xffff if n else 0
enable_trigger(sl, m, sa=True)
dorn_config(0x00b, n, slice=sl)
def triggers(sl, atrig=0xffff, dtrig=0, sam=0, nsa=10):
enable_trigger(sl, dtrig, det=True)
enable_trigger(sl, atrig)
nsamples(sl, nsa, sam)
def atriggers(sl, atrig=0, gtrig=0, csa=False, gsa=False, nsa=10):
dorn_config(0x008, slice=sl, v=atrig & 0xffff, mes="atrig[15:0]")
dorn_config(0x009, slice=sl, v=(atrig>>16)|((gtrig&0xff)<<8), mes="gtrig[7:0],atrig[23:8]")
dorn_config(0x00a, slice=sl, v=gtrig>>8, mes="gtrig[23:8]")
dorn_config(0x00b, slice=sl, v=(gsa<<9)|(csa<<8)|nsa, mes="nsamples")
def hist_bins(sl, bin0=4.0, res=1, cwin=6, xtalk=6):
"""configure dorn_l4 histogramming
bin0: float: A-value of bin 0, int: 16LOG2(A)
res: bin = 16×log₂(A) >> res
cwin: anti-coincidence window [µs]
xtalk: x-talk ratio cut: reject if S > (S>>xtalk)
"""
if isinstance(bin0, float):
bin0=c16log2(bin0)
dorn_config(0x00c, (xtalk<<8) | cwin, slice=sl)
dorn_config(0x00d, (res<<9) | bin0, slice=sl)
def base_address(hists=None, counters=None, hmask=None, cmask=None):
if hists is not None:
if counters is None:
counters = hists
r = dorn_config(0x088, (counters<<3) | hists)
else:
if hmask is not None:
r = dorn_config(0x088, 0x4000 | hmask)
if cmask is not None:
r = dorn_config(0x088, 0x8000 | cmask)
if cmask is None and hmask is None:
r = dorn_config(0x088, 0x8000)
return r & 7, r >> 3
def fifo_status(i=None):
e = dorn_config(0x084)
p = dorn_config(0x085)
f = dorn_config(0x086)
if i is None:
return e,p,f
return (e>>i)&1, (p>>i)&1, (f>>i)&1
def fifo_select(hi=False, sl=None, hk=False, ev=False, sa=False, i=None):
if i is not None:
f = 1<<i
else:
f = (sa<<2) | (ev<<1) | hk
if sl is not None:
f <<= 3*sl+1
else:
f *= 0b0010010010010
f |= hi
return f
def fifo_enable(en=True, rfifo=True, men=True, sl=None, **aa):
f = fifo_select(sl=sl, **aa)
if sl is None and en is True:
en = 0xf
elif sl is not None:
en <<= sl
dorn_config(0x087, (f<<6) | (rfifo<<5) | (men<<4) | en)
STROBES = {
"read_fifos": 0,
"incr": 1,
"resync": 2,
"clock_reset": 3,
"hk": 4,
"dorn_reset": 8,
"mem_reset": 12,
"rb_reset": 13,
"fifo_reset": 14,
}
def strobe(sl=None, **aa):
s = 0
for k in aa:
if not k in STROBES:
raise KeyError(f"No STROBE: {k}")
if aa[k]:
b = 1
if k=="hk":
if sl is None:
b = 15;
else:
b <<= sl
s |= b << STROBES[k]
dorn_config(0x08b, s)
def fifo_reset(**aa):
f = fifo_select(**aa)
if not f:
strobe(fifo_reset=True)
else:
dorn_config(0x084, f)
def fifo_read(**aa):
f = fifo_select(**aa)
if not f:
acmd(0x8800, verb=_verbose)
else:
dorn_config(0x085, f)
def default_config(thr=0x7ff):
for sl in CONFIG.slices:
for ch in range(CONFIG.n_channels):
thres(sl, ch, thr)
l2filter()
l3banana()
for sl in CONFIG.slices:
atriggers(sl)
def print_trigger_config():
tri = [[dorn_config(0x008 + i, slice=sl)
for i in range(4)]
for sl in CONFIG.slices]
ff = [dorn_config(0x084+i) for i in range(4)]
tri.append(ff)
e = ff[3]
df = [acmd(0x11+i) for i in range(3)]
df.append(acmd(5))
tri.append(df)
ct0 = tri[0][0] | (tri[0][1]<<16) & 0xff0000
ct1 = tri[1][0] | (tri[1][1]<<16) & 0xff0000
gt0 = (tri[0][2]<<8) | (tri[0][1]>>8)
gt1 = (tri[1][2]<<8) | (tri[1][1]>>8)
ns0 = tri[0][3] & 0xff
ns1 = tri[1][3] & 0xff
se0 = tri[0][3] >> 8
se1 = tri[1][3] >> 8
print(f"""narena trigger config:
trigger detector masks:
ctriggers: 0x{ct0:06x} 0x{ct1:06x}
gtriggers: 0x{gt0:06x} 0x{gt1:06x}
nsamples: {ns0:-6d} {ns1}
samples enable: {se0:-6d} {se1}
enable: {e&1:-6d} {(e>>1)&1}
fifos enable SA/EV/HK HI {(e>>7)&7:03b} {(e>>10)&7:03b} {(e>>6)&1}
empty {(ff[0]>>1)&7:03b} {(ff[0]>>4)&7:03b} {ff[0]&1} {(df[3]>>9)&7:03b}
packet {(ff[1]>>1)&7:03b} {(ff[1]>>4)&7:03b} {ff[1]&1} {(df[3]>>13)&7:03b}
full {(ff[2]>>1)&7:03b} {(ff[2]>>4)&7:03b} {ff[2]&1} {(df[3]>>5)&7:03b}
dig fifo status {df[2]&0x3ff} {df[1]&0x3ff} {df[0]&0x3ff}
""", file=sys.stderr)
return tri
def read_event(sl=None, ev=None):
if ev is None:
fifo_read(sl=sl, ev=True)
ev = rfifo(2)
if (ev[0] & 0xfffc) != 0x5718:
raise ValueError(f"EV packet magic mismatch {ev[0]:04x}")
Ba = ev[5]
Ph = ev[6]
A = ev[7]<<8 | ev[9]>>8
B = ev[8]<<8 | ev[9]&0xff
E = ev[10] | ev[11]<<16
if Ba & 0x8000:
Ba -= 0x10000
if Ph & 0x8000:
Ph -= 0x10000
if A & 0x800000:
A -= 0x1000000
if B & 0x800000:
B -= 0x1000000
if E & 0x80000000:
E -= 0x100000000
print(f"""PHA Event slice {ev[0]&3} ch {ev[4]&15}
time: {ev[1] | ev[2]<<16}
Δtime: {ev[3]}
lost: {ev[4]>>4}
A: {A/1024:.2f}
B: {B/1024:.2f}
banana: {Ba/0x4000:.4f}
φ: {Ph/0x4000:.4f}
E: {E/0x20000:.2f}
""", file=sys.stderr)
return ev
def read_samples(sl=0, n=None, sa=None):
if not sa:
if not n:
n = nsamples(sl)
sa = []
while n:
ff = dorn_config(0x085)
if not (ff & (8 << (3*sl))):
break;
fifo_read(sl=sl, sa=True)
sa.append(rfifo(3))
n -= 1
for s in sa:
if (s[0] & 0xfffc) != 0x5714:
raise ValueError(f"SA magic mismatch {s[0]:04x}")
t = s[1] | s[2]<<16
print(f"{t} ", " ".join([f"{ss&0xfff:5d}" for ss in s[3:]]), file=sys.stderr)
return sa

View file

@ -1,6 +1,6 @@
#! /usr/bin/ipython3 --profile=thhor
#! /usr/bin/ipython3 --profile=turbo_dose
import sys, os, time, getopt, fileinput, struct
import sys, time, getopt, fileinput, struct
import uart
from base85 import base85_encode, base85_decode
from map import memmap
@ -66,16 +66,6 @@ mmap = memmap(map_fn)
class dose_cmd(uart.uart):
def parse_line(self, l):
self.responses.append(l)
v = self._verbose
if v>=4 or v and (l[:1]!=b'#' or b'?' in l.split()[0]):
try:
s = l.decode()
print(f"{self.portname}<- {s}", file=sys.stderr)
except:
print(f"{self.portname}<- {repr(l)}", file=sys.stderr)
def cmd(self, c, d=None, timeout=0.2):
if not isinstance(c, bytes):
c = c.encode()
@ -93,7 +83,7 @@ class dose_cmd(uart.uart):
e = int(r[-1], 16)
if len(r)==3:
d = base85_decode(r[1])
if self._verbose >= 3:
if self._verbose:
print(f"{r[0]}[{r[2]}] {"".join([f"{b:02x}" for b in d])}", file=sys.stderr)
self.last_cmd = c[0:1]
return r[0], e, d
@ -101,32 +91,26 @@ class dose_cmd(uart.uart):
def poke(self, a, d, s=None, ccp=0):
return self.peek(a, s=s, d=d, ccp=ccp)
def peek(self, a=None, s=None, d=None, ccp=0, o=0):
def peek(self, a=None, s=None, d=None, ccp=0):
name = None
if a in SFR:
name = a
a, ss = SFR[a]
if s is None:
s = ss
if a in mmap:
a, ss = mmap[a]
if ss and s is None:
s = ss
if isinstance(a, str):
aa = a.split('+',1)
if aa[1:]:
o += int(aa[1], 0)
aa = aa[0]
if aa in SFR:
name = aa
a, ss = SFR[aa]
if s is None:
s = ss
elif aa in mmap:
a, ss = mmap[aa]
if ss and s is None:
s = ss
else:
print(f"PEEK: unknown addr {a}", file=sys.stderr)
for k in mmap.keys():
if a in k:
print(f"PEEK: in RAM we have {k}", file=sys.stderr)
for k in SFR.keys():
if a in k:
print(f"PEEK: IO SFR we have {k}", file=sys.stderr)
raise ValueError(a)
a += o
print(f"PEEK: unknown addr {a}", file=sys.stderr)
for k in mmap.keys():
if a in k:
print(f"PEEK: in RAM we have {k}", file=sys.stderr)
for k in SFR.keys():
if a in k:
print(f"PEEK: IO SFR we have {k}", file=sys.stderr)
raise ValueError(a)
FF = {1: "B", 2: "H", 4:"I"}
if a is None:
cc, nn, dd = self.cmd(b"M=")
@ -144,7 +128,7 @@ class dose_cmd(uart.uart):
d = bytes(d)
if s is None:
s = len(d)
d = struct.pack("<HBB", a,s,ccp) + d + bytes(12)
d = struct.pack("<HBB", a,s,ccp) + d + b'\0\0\0\0\0\0\0\0\0\0\0\0'
cc, nn, dd = self.cmd(c, d[:16])
if dd and nn:
aa,ss,cc = struct.unpack("<HBB", dd[:4])
@ -155,9 +139,6 @@ class dose_cmd(uart.uart):
return name, d
return cc, nn, dd
def peek_byte(self, a):
return self.peek(a)[-1][0]
def more(self, flags=b''):
return self.cmd(self.last_cmd + b'=' + flags)
@ -169,11 +150,6 @@ class dose_cmd(uart.uart):
r += dd[4:4+nn]
return r
def read_version(self, a="version_str", s=None):
r = read_mem(a, s)
print(r.decode())
return r
_adc_conf = None
_sigrow = None
@ -241,18 +217,15 @@ class dose_cmd(uart.uart):
r.append((dc, self.adc()))
return r
def flash(self, op=None, resp=False, poll=False, **aa):
c = "F"
if poll:
if poll in ".,!":
c = "F"+poll
else:
c = "F!"
if resp:
c += "<"
def flash(self, op=None, abort=False, buf=False, **aa):
if op is None:
c = "F"
if abort:
c = "F!"
if buf:
c += "<"
return self.cmd(c)
r = self.cmd(c, flash_cmd.cmd_buffer(op, **aa))
r = self.cmd("F", flash_cmd.cmd_buffer(op, **aa))
if r[1]:
raise flash_cmd.Flash_Error(op)
return r
@ -278,7 +251,6 @@ class dose_cmd(uart.uart):
self.wait_for_spi()
def wait_for_spi(self):
return
while True:
r = self.cmd("F")[1]
if not r:
@ -302,8 +274,10 @@ class dose_cmd(uart.uart):
if min(d) == 255:
print(f"FLASH: page is erased")
elif bch.check_page(d):
d = self.fix_page(d)
return d
if not bch.galois:
raise bch.BCHError("galois module not loaded for Parity Error correction")
d = bch.fix_page(d)
return d[:512]
def read_flash(self, page):
print(f"FLASH: reading from {page=}")
@ -321,7 +295,10 @@ class dose_cmd(uart.uart):
def flash_status(self, blocking=False):
r = (0,0,bytes(2))
while not r[2][0] & 0x80:
r = self.flash("Status", resp=True, what="cmdbuf")
self.flash("Status", what="cmdbuf")
r = self.cmd("F<")
while r[1]:
r = self.cmd("F<")
if not blocking:
break
return tuple(r[2][:2])
@ -332,10 +309,10 @@ class dose_cmd(uart.uart):
self.flash("Program2", page=page)
self.flash_status(True)
def write_file2flash(self, page, fn, pages):
def write_file2flash(self, page, fn):
n = 0
with open(fn, "rb") as f:
while not pages or n < pages:
while True:
b =f.read(512)
if not b:
break
@ -359,24 +336,16 @@ class dose_cmd(uart.uart):
self.flash(op, page=page)
self.flash_status(True)
def erased_map(self, page=0, npages=4096):
if page + npages > 0x1000:
npages = 0x1000 - page
# assume the last page is erased
self.flash("Transfer2", page=0xfff)
self.flash_status(True)
r = []
for p in range(page, page+npages):
self.flash("Compare2", page=p)
r.append(self.flash_status(True))
return r
def flash_power(self, on=True):
op = "PowerUp" if on else "PowerDown"
self.flash(op)
def flash_Id(self):
r = self.flash("Id", resp=True, what="cmdbuf")
self.flash("Id", what="cmdbuf")
while True:
r = self.cmd("F<")
if not r[1]:
break
i = r[2][:5]
print(f"FLASH chip {b2hex(i)}", file=sys.stderr)
return i
@ -389,509 +358,23 @@ class dose_cmd(uart.uart):
self.flash(op, size=s, what=what, byte=i)
self.wait_for_spi()
def make_parity(self, page):
for i in range(32):
if i==0:
c = "B4!%@"
elif i!=31:
c = "B4!%"
else:
c = "B4!%!"
self.cmd(c, page[16*i:16*(i+1)])
return self.cmd("B4<!")
FPGA_STAT = {
"POWER": 1,
"nCONFIG": 0x40,
"nSTATUS": 0x10,
"CRCERR": 0x20,
}
def power(self, on=None):
if on is None:
if on==True:
c = 'O1'
elif on==False:
c = 'O0'
elif on is None:
c = 'O'
else:
c = f'O{on:d}'
raise ValueError(f".power expects True or False, got {on!r}")
r = self.cmd(c)
print(f"Power was {("off", "ON")[r[1]&1]}", file=sys.stderr)
return int2flags(self.FPGA_STAT, r[1])
def fpga_reset(self):
return self.cmd("C@")
FPGA_FLGS = {
"DEAD": 0x10,
"BUSY": 0x20,
"SUBMITTED": 0x40,
"CONFIG": 0x80,
"NOOP": 0x8000,
}
def fpga_cmd(self, c, read=0, wait=0, flags=()):
n = len(c) & 0xe
if n != len(c):
raise ValueError(f"FPGA command must be even 2…14 bytes {c!r}")
n |= flags2int(self.FPGA_FLGS, flags)
z = read << 1
if wait:
if wait > 7 or z > 14:
raise ValueError("FPGA cannot wait-read more than 14 bytes")
z |= wait << 4
z |= 1
z |= n >> 8
n &= 0xff
c = bytes((n, z)) + c + bytes(14)
r, e, d = self.cmd("C", c[:16])
s = int2flags(self.FPGA_FLGS, d[0])
if self._verbose >= 2:
print(f"FPGA cmd status {s!r}", file=sys.stderr)
return d
def fpga_config_c(self, filename="../fpga/quartus/thhor_crs.rbf"):
self.fpga_reset()
n = 0
nn = 0
with open(filename, "rb") as f:
c = f.read(14)
while c:
if len(c) & 1:
c += b'\0'
d = fpga_cmd(c, flags="CONFIG")
if d[0] & self.FPGA_FLGS["SUBMITTED"]:
n += len(c)
c = f.read(14)
if n > nn + 1024:
if ~self.peek_byte("VPORTA_IN") & 0x10:
raise FPGA_Error("nSTATUS went low during config")
print(f"{n} bytes sent", file=sys.stderr)
nn += 1024
return n
AADDR = {
"RFIFO": 0x0000,
"RNOOP": 0x0001,
"SPIDE": 0x0002,
"MSTAT": 0x0005,
"MERRC": 0x0006,
"MRSTS": 0x0007,
"MCONF": 0x0008,
"MCONF_SET": 0x000a,
"MCONF_CLR": 0x0009,
"MCONF_WR": 0x000b,
"MCLCK": 0x000c,
"MCLCKL": 0x000c,
"MCLCKH": 0x000f,
"WHK": 0x0010,
"RHKS": 0x0010,
"RF1S": 0x0011,
"RF2S": 0x0012,
"RF3S": 0x0013,
"RHK": 0x0014,
"RF1": 0x0015,
"RF2": 0x0016,
"RF3": 0x0017,
"HKSZ": 0x0018,
"HKMA": 0x0019,
"HKHV": 0x001a,
"BATE": 0x037f,
}
def icmd(self, c, p=None, r=2, flgs=0, mes=None):
if c in self.AADDR:
c = self.AADDR[c]+flgs
w = [c | 0x8000]
if p is not None:
w[0] |= 0x4000
w.append(p)
if r:
w.extend([0x8001]*(r-1))
w.append(0)
d = struct.pack(f">{len(w)}H", *w)
if self._verbose >= 2:
if mes:
mes = f"[{mes}]"
else:
mes = ""
print(f"icmd{mes}{[f"{ww:04x}" for ww in w]}")
d = self.fpga_cmd(d)
r = struct.unpack(f">{len(w)+1}H", d[:2*len(w)+2])
if self._verbose >= 2:
print(f" {mes}{[f"{rr:04x}" for rr in r]}", file=sys.stderr)
print(f"Power was {("off", "ON")[r[1]]}", file=sys.stderr)
return r
def acmd(self, c, v=None, task=None, verb=True):
_v = self._verbose
self._verbose = verb+1
r = self.icmd(c, v, mes=task)[-1]
self._verbose = _v
return r
def rfifo(self, fifo=1, n=None):
s = self.icmd(0x10+fifo)[-1]
if not s & 0x1000:
return None
if not n:
n = s & 0x3ff
r = []
z = 1
d = b''
nnn = n
while nnn>0:
nn = nnn if nnn<=7 else 7
dd = self.fpga_cmd(struct.pack(">H", 0x8014+fifo),
read=nn+z, flags=self.FPGA_FLGS["NOOP"])
if dd[0] & self.FPGA_FLGS["SUBMITTED"]:
z = -1
nnn -= nn
d += dd[2:]
r = struct.unpack(f">{len(d)//2}H", d)[:n]
if self._verbose >= 2:
print(f"FIFO[{fifo}] ← {[f"{rr:04x}" for rr in r]}", file=sys.stderr)
return r
def pressure(self, data=None, cmd="BATE", fifo=1):
if data is None:
self.icmd(cmd, mes="bate")
time.sleep(0.2)
data = self.rfifo(fifo)
import pressure
T,p = pressure.calibrate(data[1:])
T /= 10
p /= 10
print(f"bate reading {p=:.2f} mbar, {T=:.2f} °C", file=sys.stderr)
return p, T, data
def menable(self, on=True, what=0x0001):
if on:
self.icmd("MCONF_SET", what)
else:
self.icmd("MCONF_CLR", what)
PIPE = {
"CMD" : 1,
"ADC" : 2,
"FLASH" : 4,
"FPGA" : 8,
"CONFIG" : 0x208,
"FPGA_CMD" : 0x408,
"ERASE" : 0x10000,
}
PSTAT = {
"BLK" : 0x0f,
"OUT" : 0x80,
"ERR" : 0x40,
"BCH" : 0x20,
"P528" : 0x10,
}
FSS = {
"Ready": 1, # ready for the next buffer
"Busy" : 2, # processing …
"Error": 3, # Aborted
"Read" : 4, # array read
"Write": 8, # buffer write and burn
"Erase": 12, # Erase
"Ack" : 32, # Next buffer is provided, continue …
"StBsy": 64, # Waiting to Flash status register
"P528" : 128, # do 528 byte pages.
}
def pipe(self, source=None, dest=None,
fpga_cmd=4, psize=0, n=0,
page=0, npages=0,
poll=None, parity=None):
valid = 0
flags = flags2int(self.PIPE, dest)
flags |= flags2int(self.PIPE, source)
astatus = (flags >> 8) & 0xff
dest = flags2int(self.PIPE, dest) & 0xff
source = flags2int(self.PIPE, source) & 0xff
flash = 0
status = 0x80 # PS_OUT
c = 'P'
if astatus & self.PIPE["FPGA_CMD"]:
if not isinstance(fpga_cmd, int):
self.cmd("B4!", fpga_cmd)
fpga_cmd = 4
c = f'P{fpga_cmd}'
if poll:
c += poll
if n and not psize:
if dest & self.PIPE["FPGA"]:
psize = (n % 64) & 0xfe
n //= 64
else:
psize = 64
if n and not npages:
if dest & self.PIPE["FPGA"]:
npages = (n*64 + psize + 511)//512
else:
npages = (n*psize + 511)//512
if not npages:
npages = 1
if parity == "pipe":
status |= 0x30 # PS_BCH
if source & self.PIPE["FLASH"]:
flash = flags2int(self.FSS, ["Read", "Ready", "P528"])
source = self.PIPE["FLASH"]
status |= 0x10 # PS_528
dest &=~ self.PIPE["FLASH"]
if dest & self.PIPE["FPGA"] and not n:
n = 512//64 * npages
if dest & self.PIPE["FLASH"]:
flash = flags2int(self.FSS, ["Write", "Ready", "P528"])
status |= 0x10 # PS_528
if source == self.PIPE["FPGA"] and not n:
n = (512*npages + psize - 1) // psize
if flags & self.PIPE["ERASE"]:
flash = flags2int(self.FSS, ["Erase", "Busy", "P528"])
status &= 0x7f # ~PS_OUT
if not source:
valid = 0x1f
d = struct.pack("<6BH3B2HB",
source, dest, status, valid, 0,
astatus, n, psize//2, 0, 0,
page, npages-1, flash)
if self._verbose >= 2:
print(f"PIPE {n=} {b2hex(d)}", file=sys.stderr)
return self.cmd(c, d)
def erase_flash(self, page, npages=1):
cc, nn, dd = self.pipe("ERASE", "FLASH", page, npages)
while nn & self.PSTAT["OUT"]:
print(f"flash erase p={int2flags(self.PSTAT, nn)!r}", file=sys.stderr)
self.peek("fs")
self.peek("pipe")
cc, nn, dd = self.cmd("P,!")
Sync = False
def read_pipe(self, n=0, file=None, timeout=2, parity=False):
if isinstance(file, str):
f = open(file, "ab")
else:
f = file
result = []
i = 0
page = []
t = time.time()
s = 1/256
while i < n:
cc, nn, dd = self.cmd("B")
if not parity or len(page) < 7:
bflg = 0x0f
else:
bflg = 0x1f
tt = time.time()
if ~nn & bflg:
if tt > t+timeout:
if self._verbose:
print("read_pipe timeout", file=sys.stderr)
break
time.sleep(s)
s *= 2
if s > 1:
s = 1
continue
t = tt
s = 1/256
if len(result) >= n:
break
if nn & 0x10:
p = self.cmd("B4<")[2]
else:
p = None
data = [self.cmd(f"B{i}<")[2] for i in range(4)]
data = b''.join(data)
page.append(data)
if len(page)==8:
if p:
page.append(p)
page = b''.join(page)
i += 1
if parity:
if bch.check_page(page):
print(f"parity error on page {i}", file=sys.stderr)
if parity == "fix":
page = self.fix_page(page)
if f and parity == "fix":
file.write(page[:512])
if not f:
result.append(page)
page = []
if f and parity != "fix":
f.write(data)
if len(page) and parity == "save":
f.write(p)
if f and self.Sync:
f.flush()
if isinstance(file, str):
f.close()
return result
def write_pipe(self, data=[], timeout=2, n=None, parity=None, bfill=b'\0', pfill=b'\xff'):
if isinstance(data, str):
f = open(data, "rb")
data = []
else:
f = None
if not isinstance(data, list):
data = [data]
i = 0
t = time.time()
s = 1/256
# parity="cmd":
# calculate the parity with the 'B%' command
# parity="data":
# calculate the parity with python, or take it from array `data[]`
# parity="pipe":
# calculate the parity in `pipe_poll()`
# !parity:
# Do not care about parity (same as "pipe")
while True:
if f:
page = f.read(512)
elif data:
page = data[0]
data[0:1] = []
else:
page = None
if not page:
break
if len(page) < 512:
j = len(page) % 64
if self._verbose:
print(f"short page {len(page)} bytes", file=sys.stderr)
if j and bfill:
page += (64-j)*bfill
if pfill:
page = (page + 512*pfill)[:512]
if len(page)==512 and parity == "data":
page += bch.page_parity(page)
page = [page[j:j+64] for j in range(0,len(page),64)]
for b in range(8):
while True:
cc, nn, dd = self.cmd("B")
tt = time.time()
bb = nn>>5
nn &= 0xf
if not nn:
t = tt
s = 1/256
break
if tt > t+timeout:
if self._verbose:
print(f"write_pipe timeout {i=} {b=}", file=sys.stderr)
break
time.sleep(s)
s *= 2
if s > 1:
s = 1
if nn:
break
if parity and bb != b:
raise ValueError(f"block number mismatch {b=} != {bb=}")
if b >= len(page):
break
if parity == "data" and b==7:
self.cmd("B4@", page[8])
for j in range(4):
B = f"B{j}"
if parity == "cmd":
B += "%"
if not b and not j:
B += "@"
if b==7 and j==3:
B += "!"
ccc,nnn,ddd = self.cmd(B, page[b][16*j:16*(j+1)])
if self._verbose >= 3:
print(f"write_pipe {i=} {b=} {j=} {B=} {nn=}, {ccc=}, {nnn=:#02x}", file=sys.stderr)
if self._verbose >= 2:
self.peek("pipe", 11)
i += 1
if n and i >= n:
break
if n and i >= n:
break
if nn:
break
if f:
f.close()
return i
def fpga_config_p(self, filename="../fpga/quartus/thhor_crs.rbf"):
self.fpga_reset()
n = (os.stat(filename).st_size + 63) // 64
self.pipe("CMD", "CONFIG", n=n*64)
self.write_pipe(filename, n=n)
def fpga_config_f(self, filename="../fpga/quartus/thhor_crs.rbf"):
self.fpga_reset()
n = os.stat(filename).st_size
self.pipe("FLASH", "CONFIG", page=0x100, n=n)
def fix_page(self, page):
if self.load_galois():
page = bch.fix_page(page)
def load_galois(self):
if not bch.galois:
raise bch.BCHError("galois module not loaded for Parity Error correction")
return True
def write_file2flash(self, filename, page, npages=None, parity="pipe"):
if npages is None:
npages = (os.stat(filename).st_size + 511) // 512
self.pipe("CMD", "FLASH", page=page, npages=npages, parity=parity)
return self.write_pipe(filename, parity=parity)
def flags2int(FLAGS, flags):
r = 0
if flags is None:
return r
if isinstance(flags, int):
return flags
if isinstance(flags, str):
return FLAGS[flags]
for f in flags:
if isinstance(f, int):
r |= f
else:
r |= FLAGS[f]
return r
def int2flags(FLAGS, flags):
r = []
for f in FLAGS:
if flags & FLAGS[f]:
r.append(f)
return r
if tty:
tty = dose_cmd(tty, baud)
tty._export(globals())
tty._verbose = True
import dorn
from dorn import *
dorn._connect(tty)
dorn.CONFIG.thhor()
tty._verbose = False
uart.set_prompt("GRETEL")

View file

@ -4,14 +4,14 @@
*/
MEMORY
{
eemap (rw!x) : ORIGIN = 0x801400, LENGTH = 0x100
eedef (rw!x) : ORIGIN = 0x810000, LENGTH = 0x100
uumap (rw!x) : ORIGIN = 0x801300, LENGTH = 0x020
uudef (rw!x) : ORIGIN = 0x850000, LENGTH = 0x020
eemap : ORIGIN = 0x1400, LENGTH = 0x100
eedef : ORIGIN = 0x810000, LENGTH = 0x100
uumap : ORIGIN = 0x1300, LENGTH = 0x20
uudef : ORIGIN = 0x850000, LENGTH = 0x20
}
SECTIONS
{
.eemap 0x801400:
.eemap 0x1400:
{
ee1_start = .;
*(.eeprom1)
@ -22,7 +22,7 @@ SECTIONS
ee9_end = .;
ee9_size = ee9_end - ee9_start;
} >eemap AT >eedef
.uumap 0x801300:
.uumap 0x1300:
{
*(.userrow)
} >uumap AT >uudef

View file

@ -1,7 +1,5 @@
/******************************************************
AT45DB161E spi flash chip
- opcode (hex)
- address
- pb page and byte address
@ -152,7 +150,7 @@ uint8_t flash_cmd(uint16_t mode, uint16_t what, uint16_t page, uint16_t byte)
spi_start_read(csize, flash_cmd_buffer, size, b);
break;
case FM_WAIT:
spi.mask = spi.wait = 0x80;
spi.mask = 0x80;
spi_start_read(csize, flash_cmd_buffer, 2, b);
break;
}
@ -175,13 +173,12 @@ uint8_t flash_stream_submit(uint16_t mode, uint8_t size)
{
uint8_t b = fs.block;
uint16_t p = fs.page;
uint8_t r = fs.status;
uint8_t r = fs.status & ~FS_Ready;
mode |= (uint16_t)config.flash_page_size << 8;
if (size) {
if (b & 8) {
b = 0;
fs.page = ++p;
// reached only when npages > 0
fs.npages--;
}
else if (b==7 && r & FS_528)
@ -196,8 +193,21 @@ uint8_t flash_stream_submit(uint16_t mode, uint8_t size)
uint8_t e = flash_cmd(mode, size, p, (uint16_t)(b&7) << 6);
if (e)
fs.status = r |= FS_Error;
return r;
r |= FS_Ready; // FS_Error
r |= FS_Busy;
fs.status = r;
return e;
}
__attribute__ ((noinline, noclone))
uint8_t flash_stream_done()
{
uint8_t r = fs.status & FS_Error;
if (!r || r == FS_Error)
return 1;
if (fs.npages || !(fs.block & 8))
return 0;
return 1;
}
static inline
@ -221,8 +231,6 @@ static inline
uint8_t flash_erase_next_page()
{
uint16_t mode = 0x81; // Page Erase
if (~fs.block & 8)
fs.npages++;
uint8_t n = 0;
if (fs.page && !(fs.page & 0xff) && fs.npages & 0xff00) {
mode = 0x7c; // Sector 1…15 Erase
@ -245,62 +253,55 @@ uint8_t flash_burn_page()
uint8_t flash_poll(uint8_t rr)
{
uint8_t r = fs.status;
if (rr)
fs.status = r |= FS_Ack;
if (spi_busy_p())
return r;
if (flash_stream_done())
if ((r & FS_Error) == FS_Error)
return r;
if (r & FS_Ready)
goto ready;
if (r & FS_StBsy && flash_status_bytes[0] & 0x80) {
// flash is done burning
fs.block &= ~7;
r &= ~FS_StBsy;
goto idle;
}
if (r & FS_Write && fs.block == 9) {
// Write or Erase
r |= FS_StBsy;
flash_status_bytes[0] = 0;
flash_cmd_na(0xd7 | FM_READ, 0xf002);
goto done;
}
if ((r & FS_Dir) == FS_Write && fs.block == 8) {
// Write
r = flash_burn_page();
goto done;
}
idle:
if (!fs.npages && fs.block & 8)
if (r & FS_StBsy) {
// status bytes arrived
if (~flash_status_bytes[0] & 0x80)
// flash is still busy burning
goto rd_status;
// not busy any more, move Bsy → Rdy
if (r & FS_Busy)
r |= FS_Ready;
goto ready;
if ((r & FS_Dir) == FS_Erase) {
r = flash_erase_next_page();
goto done;
}
if (!(r & FS_Busy))
goto ready;
if (rr) {
r |= FS_Error;
fs.status = r;
return r;
}
if (r & FS_Write) {
if (fs.block == 9) {
rd_status:
// request status bytes for pending Write or Error
r |= FS_StBsy;
fs.status = r;
flash_cmd_na(0xd7 | FM_READ, 0xf002);
return r;
}
}
ready:
r &= ~FS_Error;
if (~r & FS_Ack) {
r |= FS_Ready;
goto done;
}
r &=~ FS_Ack;
if (!fs.npages && fs.block & 8)
goto done;
fs.status = r |= FS_Busy;
if ((r & FS_Dir) == FS_Read)
r = flash_read_next_block();
else if ((r & FS_Dir) == FS_Write)
r = flash_write_next_block();
done:
r &= ~(FS_Busy | FS_StBsy);
if (rr)
r |= FS_Ack;
fs.status = r;
return r;
if (r & FS_Dir == FS_Write && fs.block == 8)
flash_burn_page();
else if (!flash_stream_done()) {
if (r & (FS_Dir|FS_Ack) == (FS_Read|FS_Ack))
flash_read_next_block();
else if (r & (FS_Dir|FS_Ack) == (FS_Write|FS_Ack))
flash_write_next_block();
else if (r & FS_Dir == FS_Erase)
flash_erase_next_page();
fs.status &=~ FS_Ack;
}
return fs.status;
}
uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags)
@ -308,12 +309,15 @@ uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags)
uint8_t r = flash_poll(0);
if ((r & FS_Error) == FS_Busy)
return FS_Error;
r = flags | FS_Ready;
if (config.flash_page_size != FM_528)
r &=~ FS_528;
fs.page = page;
fs.npages = npages;
flash_status_bytes[0] = 0;
fs.block = 0;
fs.status = r = flags;
return r;
fs.npages = npages;
fs.status = r;
flash_status_bytes[0] = 0xff;
return flash_poll(0);
}
static inline

View file

@ -53,8 +53,4 @@ enum {
FS_528 = 128, // do 528 byte pages.
};
static inline uint8_t flash_current_block() { return fs.block; }
static inline uint8_t flash_stream_done()
{ return !(fs.status & FS_Error) || !(~fs.status & FS_Error); }
#endif

Binary file not shown.

View file

@ -2,65 +2,39 @@
#include "pipe.h"
#include "fpga.h"
#include "spi.h"
#include <string.h>
uint8_t fpga_reset_poll()
{
// nSTATUS may stay low for up to 230µs after nCONFIG high
uint8_t r = !(nSTATUS_VPORT.IN & (1 << nSTATUS_PIN));
if (r)
nCONFIG_VPORT.OUT |= 1 << nCONFIG_PIN;
return r;
}
uint8_t fpga_status()
{
uint8_t r = fpga_power();
// all three altera pins must be on the same PORT
if (r)
r |= CRCERR_VPORT.IN &
( 1<<nCONFIG_PIN
| 1<<nSTATUS_PIN
| 1<<CRCERR_PIN );
return r;
}
void fpga_reset()
{
nCONFIG_VPORT.OUT &=~ (1<<nCONFIG_PIN);
uint8_t n = 10;
// nSTATUS will go low within 500ns
while (!fpga_reset_poll() && --n);
}
void fpga_cmd(struct fpga_cmd *c)
{
uint8_t n = c->n;
uint8_t z = c->z;
if (fpga_status() != as_configured) {
n |= fpga_dead;
if (~n & fpga_configure) {
c->n = n;
return;
}
}
c->n = n & ~fpga_busy | fpga_submitted;
if (n & fpga_submitted)
if (fpga_reset_poll()) {
c->n |= 0x20; // busy flag
return;
spi_select(n & fpga_configure ? SPI_CONFIG : 0);
spi.csize = n &= fpga_size;
spi.zero = z & 0x80; // send 0x0000 or 0x8080
}
if (c->n & 1 && spi_abort()) {
c->n |= 0x10; // aborted flag
return;
}
else if (spi_busy_p()) {
c->n |= 0x20; // busy flag
return;
}
c->n &=~ 0x10; // not busy
if (c->n & 0x40)
return;
c->n |= 0x40; // submitted flag
uint8_t n = c->n & 0x0e; // send up to seven cmd words
uint8_t z = c->z & 0x7e; // and up to 63 zeros
spi_select(0);
spi.zero = c->n & 0x80; // send nop: 0x8080 (please), or zeros
spi.csize = n;
spi.cmd = c->d;
spi.rdata = c->d;
if (z & fpga_wait_nonzero) {
spi.isize = n + (z>>3 & fpga_size); // ignore cmd ± (z[6:4])
spi.zsize = spi.rsize = z & fpga_size; // read x[3:1] words
// start reading at the first byte with MSB set after cmd
spi.mask = spi.wait = 0x80;
if (c->z & 0x80) {
spi.isize = n + z>>3 & 0x0e; // ignore cmd ± (z[6:4])
spi.zsize = spi.rsize = z & 0x0e; // read x[3:1] words
spi.mask = 0xff; // start reading at the first nonzero byte after cmd
}
else {
spi.zsize = z &= 0x7e; // send z zeros/nop after cmd
spi.zsize = z; // send z zeros/nop after cmd
spi.rsize = 14; // save the last 7 words returned
if (n + z > 14)
spi.isize = n + z - 14;
@ -70,114 +44,25 @@ void fpga_cmd(struct fpga_cmd *c)
spi_start();
}
struct pipe_fpga_cmd pipe_fpga_cmd;
uint8_t fpga_start_write()
void fpga_start(uint8_t write)
{
uint8_t s = fpga_status();
uint8_t mode = pipe.fpga.status & SPI_CONFIG;
if (!mode && s != as_configured)
return 0;
if (~s & as_rconfig)
return 0;
uint8_t mode = 0;
if (pipe.fpga.zero == SPI_CONFIG)
mode = SPI_CONFIG;
spi_select(mode);
_memcopy(&spi.csize, &pipe.fpga.csize, 6);
spi.cmd = pipe.fpga.cmd;
spi.wdata = flash_buffer;
uint8_t n = 32;
if (pipe.fpga.count)
pipe.fpga.count--;
else {
uint8_t nn = pipe.fpga.size;
if (nn < n)
n = nn;
pipe.fpga.size -= n;
}
spi.wsize = n<<1;
if (n)
spi_start();
return n;
}
uint8_t fpga_start_read()
{
/************************************************************
* Send `counts` commands to the FPGA.
* Read `size` Words from each command.
* Fill the `flash_buffer` with 32 Words.
* AS_CONT:
* Continue reading Words after the buffer was used.
* User resets spi.fpga.val when done.
* Return the number of Words to be read now.
***********************************************************/
if (spi_select(0))
return 0;
if (fpga_status() != as_configured)
return 0;
if (!pipe.fpga.val)
memset(flash_buffer, 0, 64);
uint8_t n = 64 - pipe.fpga.val;
spi.rdata = flash_buffer;
uint8_t n = 64;
if (n > pipe.fpga.size)
n = pipe.fpga.size;
pipe.fpga.size -= n;
if (!n)
return n;
n >>= 1;
if (~pipe.fpga.status & AS_CONT) {
if (!pipe.fpga.count)
return 0;
pipe.fpga.count--;
spi.cmd = pipe_fpga_cmd.cmd;
_memcopy((void*)&spi.csize, (void*)&pipe_fpga_cmd, 6);
pipe.fpga.pos = 0;
pipe.fpga.status |= AS_CONT;
}
uint8_t nn = pipe.fpga.size - pipe.fpga.pos;
if (nn && nn < n)
n = nn;
pipe.fpga.pos += n;
if (pipe.fpga.pos == pipe.fpga.size)
pipe.fpga.status &=~ AS_CONT;
spi.rdata = flash_buffer + pipe.fpga.val;
spi.rsize = n << 1;
spi.zsize += spi.rsize;
pipe.fpga.val += spi.rsize;
spi_start();
return n;
}
uint8_t fpga_pipe_ready()
{
/************************************************************
* Return the number of valid Words read in to the buffer,
* when
* - the FPGA is alive, and
* - the buffer is full, or
* - there is nothing more to read.
* Reset pipe.fpga.val, when returning nonzero,
* assuming those Words will be used now.
***********************************************************/
uint8_t r = pipe.fpga.val;
if (fpga_status() != as_configured)
return 0;
if (r >= 64 || !pipe.fpga.count && ~pipe.fpga.status & AS_CONT)
pipe.fpga.val = 0;
return;
if (write)
spi.wsize = n;
else
r = 0;
return r;
}
const struct pipe pipe_config_fpga_config = {
.source = pipe_flash,
.dest = pipe_fpga,
.status = PS_BCH | PS_528 | PS_OUT,
.fpga = {
.status = AS_CONFIG,
},
};
void fpga_config(uint16_t page, uint16_t count)
{
fpga_reset();
pipe = pipe_config_fpga_config;
pipe.fpga.count = count;
flash_start_stream(page, count >> 3, FS_Read|FS_528|FS_Ready);
spi.rsize = n;
spi_start();
}

View file

@ -7,39 +7,21 @@ struct fpga_cmd {
uint8_t d[14];
};
enum fpga_flags {
fpga_size = 0x0e,
fpga_dead = 0x10,
fpga_busy = 0x20,
fpga_submitted = 0x40,
fpga_configure = 0x80,
fpga_wait_nonzero = 0x01,
};
void fpga_reset();
uint8_t fpga_reset_poll();
void fpga_cmd(struct fpga_cmd *c);
uint8_t fpga_start_read();
uint8_t fpga_start_write();
uint8_t fpga_pipe_ready();
void fpga_config(uint16_t page, uint16_t count);
static inline uint8_t fpga_power() { return !!(PEN_VPORT.IN & (1<<PEN_PIN)); }
static inline void fpga_power_on() { PEN_VPORT.OUT |= 1<<PEN_PIN; }
static inline void fpga_power_off()
static inline
void fpga_reset()
{
nCONFIG_VPORT.OUT &=~ (1<<nCONFIG_PIN);
PEN_VPORT.OUT &=~ (1<<PEN_PIN);
nCONFIG_VPORT.OUT |= (1<<nCONFIG_PIN);
}
enum fpga_status_values {
as_off = 0,
as_on = 1,
as_reset = as_on | 1<<CRCERR_PIN,
as_configured = as_on | 1<<nCONFIG_PIN | 1<<nSTATUS_PIN,
as_crcerror = as_configured | 1<<CRCERR_PIN,
as_rconfig = as_on | 1<<nCONFIG_PIN | 1<<nSTATUS_PIN,
};
static inline
uint8_t fpga_reset_poll()
{
uint8_t r = !(nSTATUS_VPORT.IN & (1 << nSTATUS_PIN));
if (r)
nCONFIG_VPORT.OUT |= 1 << nCONFIG_PIN;
return r;
}
uint8_t fpga_status();
void fpga_cmd(struct fpga_cmd *c);
void fpga_start(uint8_t write);

View file

@ -11,125 +11,51 @@
section_status(pipe) struct pipe pipe;
__attribute__((noinline))
uint8_t pipe_busy()
{
// Return true if anything is due to irq
// call this with cli() before sei();sleep()
if (spi_busy_p()) return 1;
if (flash_poll(0) & FS_Busy) return 1;
if (adc_busy()) return 1;
return 0;
}
uint8_t pipe_sleep;
uint8_t pipe_poll()
{
/************************************************************
* Drive data in `flash_buffer` from `source` to `dest`
* `pipe_cmd`:
* data comes and goes via cmd("B…")
* `pipe.valid` controls if a buffer was fully transfered
* `pipe_flash`:
* read or write pages from,to flash
* `PS_528`: use all 528 bytes
* `PS_BCH`: compute or check the BCH codes
* `pipe_adc`: (source)
* Fill the buffer with ADC readings and further status
* `pipe_fpga`:
* Configure the FPGA
* Write to the FPGA
* Read from the FPGA, with commands
***********************************************************/
// Return, if
// any hardware is busy,
// an FS_Error occured, or
// the data goes nowhere.
uint8_t r = pipe.status;
uint8_t dest = pipe.dest;
pipe_sleep = 1;
if (pipe_busy() || !dest)
return r;
uint8_t fl = flash_poll(0);
if (spi_busy_p() || fl & FS_Busy || adc_poll(0))
goto done;
#ifdef HAVE_FPGA
// we need to wait at least until the FPGA raises nSTATUS
if (dest & pipe_fpga && fpga_reset_poll())
return r;
if (fpga_reset_poll())
goto done;
#endif
uint8_t valid = pipe.valid;
if (r & PS_OUT) {
// Sending the buffer to `dest`.
// Return if we are not done sending to all destinations.
if (dest & pipe_cmd && valid & 0x1f)
if (pipe.dest & pipe_cmd && pipe.valid & 0x1f)
// cmd did not drain the buffer, yet
goto done;
if (dest & pipe_flash && ~fs.status & FS_Ready) {
// flash did not finish yet, successfully
pipe_sleep = ~fs.status & FS_Busy;
if (pipe.dest & pipe_flash && !(fl & FS_Ready))
// flash did not finish successfully
goto done;
}
// Return if next ADC reading is not yet due.
// Come back here, until is is.
if (pipe.source == pipe_adc && !adc_poll(pipe.adc))
if (pipe.source & pipe_adc && !adc_poll(pipe.adc))
goto done;
// fpga is OUT when the spi is ready.
// We are done with this buffer
r &=~ PS_OUT;
pipe_sleep = 0;
// Continue the flash stream.
valid = 0;
if (pipe.source == pipe_flash)
pipe.valid = 0;
if (pipe.source & pipe_flash)
flash_poll(1);
#ifdef HAVE_FPGA
// Continue the FPGA stream.
else if (pipe.source == pipe_fpga && !fpga_start_read())
pipe.source = 0;
else if (pipe.source & pipe_fpga)
fpga_start(0);
#endif
r &=~ (PS_OUT|4);
r++;
goto done;
}
// Waiting for the buffer to fill
// The current block index in the flash page
uint8_t b = flash_current_block();
if (pipe.source == pipe_flash)
// The valid data is from the previous block
b -= 1;
b &= 7;
uint8_t bflgs = 0x0f;
// For 528 bytes pages, the last buffer must be 80 Bytes,
// i.e., five cmd_buffers á 16 Bytes
if (b==7 && r & PS_528)
if ((r & PS_5) == PS_5)
bflgs = 0x1f;
// Data from the ADC is in named .bss segments. We send
// 16, 32, or 64 Bytes from the .bss segement for each ADC reading.
// The first named .bss segment is `magic`. Observe the link order
// in the Makefile.
//
// Fun with assembly.
// `n` is the number of bytes, [16, 32, 64]
// `o` is the addr in the flash_buffer
// `v` are the currently valid cmd_buffer flags
// `f` are the fresh valid cmd_buffer flags
if (pipe.source == pipe_adc) {
if (pipe.source & pipe_adc) {
uint8_t n = pipe.adc & 0x70;
if (!n)
goto adc_done;
uint8_t f = n-1;
uint8_t o = -16;
uint8_t v = valid;
uint8_t v = pipe.valid;
#if 0
uint8_t c;
do {
@ -158,103 +84,49 @@ uint8_t pipe_poll()
f = 0xff;
n = 64-o;
}
valid |= f>>4;
pipe.valid |= f>>4;
_memcopy(flash_buffer+o, (void*)&magic, n);
}
adc_done:
// When the flash is done, flag the buffer valid,
// including BCH Bytes.
if (pipe.source == pipe_flash && fs.status & FS_Ready)
valid = bflgs;
if (pipe.source & pipe_flash && fl & FS_Ready)
pipe.valid = bflgs;
#ifdef HAVE_FPGA
// The FPGA delivers 64 Bytes.
else if (pipe.source == pipe_fpga && fpga_pipe_ready())
valid = 0x0f;
else if (pipe.source & pipe_fpga)
pipe.valid = 0x0f;
#endif
// The buffer is not here, yet. Nothing we can do now.
if (~valid & 0x0f)
if (~pipe.valid & 0x0f)
goto done;
// The buffer shall include BCH Bytes.
if (r & PS_BCH) {
// First buffer of a page, clear the parity
if (!b)
bch4369_init(config.bch_salt);
// Add the current buffer to the parity
if (!(r&3))
bch4369_init();
uint8_t *bend = bch4369_stri(flash_buffer, 64);
// Last buffer of the page:
if (b==7) {
bch4369_fini();
// When the Flash is not the source,
// and cmd did not provide the parity
// copy the computed parity into the buffer.
if (~valid & 0x10)
_memcopyyz(bend, bch_parity, 16);
// When the page as read from flash has invalid parity,
// stop writing to the FPGA.
else if (_memcmpyz(bch_parity, bend, 16)) {
dest &=~ pipe_fpga;
r |= PS_ERR;
}
valid = 0x1f;
if (!(~r & 3)) {
// reuse Y=bend
_memcopyyz(bend, bch_parity, 16);
pipe.valid = 0x01f;
}
}
// We still do not have all data we need
if (~valid & bflgs)
if (~pipe.valid & bflgs)
goto done;
// The buffer is full, send it.
pipe_sleep = 0;
r |= PS_OUT;
#ifdef HAVE_FPGA
// Resume the FPGA stream
if (dest & pipe_fpga && !fpga_start_write())
dest &=~ pipe_fpga;
else
if (pipe.dest & pipe_fpga)
fpga_start(1);
#endif
// Resume the flash stream
if (dest & pipe_flash) {
flash_poll(1);
if (flash_stream_done())
dest &=~ pipe_flash;
}
r |= PS_OUT;
done:
pipe.dest = dest;
pipe.valid = valid;
pipe.status = r;
return r;
}
void pipe_config(const struct pipe_config *c, const struct pipe_fpga_cmd *a)
void pipe_config(const struct pipe_config *c)
{
/************************************************************
* cmd("B0!", «fpga-cmd») optionally configure an FPGA cmd
* cmd("P0", «pipe-cfg») with `AS_CMD` in `.status`
***********************************************************/
if (c->pipe.dest) {
pipe = c->pipe;
if (c->flash)
flash_start_stream(c->page, c->npages, c->flash);
}
else {
// new source (NOT flash)
pipe.source = c->pipe.source;
pipe.adc = c->pipe.adc;
}
pipe = c->pipe;
if ((pipe.source | pipe.dest) & pipe_flash)
flash_start_stream(c->page, c->npages, c->flash);
if (pipe.source & pipe_adc)
adc_start_stream(pipe.adc);
#ifdef HAVE_FPGA
if (pipe.source & pipe_fpga) {
if (a && pipe.fpga.status & AS_CMD)
_memcopyzy((void*)&pipe_fpga_cmd, (void*)a, sizeof(*a));
else
memset(&pipe_fpga_cmd, 0, sizeof(*a));
pipe.fpga = c->pipe.fpga;
fpga_start_read();
}
#endif
}

View file

@ -8,13 +8,10 @@ enum pipe_ports {
pipe_fpga = 8,
PS_OUT = 0x80,
PS_ERR = 0x40,
PS_BCH = 0x20,
PS_528 = 0x10,
AS_CONT = 1,
AS_CONFIG = SPI_CONFIG, // = 2
AS_CMD = 4,
PS_BCH = 0x10,
PS_528 = 0x08,
PS_BLK = 0x03,
PS_5 = PS_BLK | PS_528, // need 16 bytes more
};
extern
@ -26,17 +23,18 @@ struct pipe {
uint8_t adc;
#ifdef HAVE_FPGA
struct {
uint8_t status; // AS_…
uint16_t count; // number of cmds(read), 64 Bytes(write)
uint8_t size; // Words per cmd (read), extra Words (write), 0==256
uint8_t val; // Valid Bytes in Buffer (read)
uint8_t pos; // Words read from current cmd (read)
uint16_t size;
uint8_t cmd[4];
uint8_t csize;
uint8_t zsize;
uint8_t isize;
uint8_t zero;
uint8_t wait;
uint8_t mask;
} fpga;
#endif
} pipe;
extern uint8_t pipe_sleep;
struct pipe_config {
struct pipe pipe;
uint16_t page;
@ -44,18 +42,6 @@ struct pipe_config {
uint8_t flash;
};
extern
struct pipe_fpga_cmd {
uint8_t csize;
uint8_t zsize;
uint8_t isize;
uint8_t zero;
uint8_t wait;
uint8_t mask;
uint8_t cmd[10];
} pipe_fpga_cmd;
uint8_t pipe_busy();
uint8_t pipe_poll();
void pipe_cron();
void pipe_config(const struct pipe_config *c, const struct pipe_fpga_cmd *a);
void pipe_config(const struct pipe_config *c);

View file

@ -5,10 +5,7 @@ import sys, time
debug = 0
def calibrate(Word, D=None):
if D is None:
D = Word[4:]
def calibrate(Word, D):
C=[0]*7
C[1] = Word[1] >> 1

View file

@ -81,7 +81,7 @@ ISR(RTC_CNT_vect, ISR_NAKED)
"subi r24, -1" "\n\t"
"sts clockh, r24" "\n\t"
"lds r24, clockh+1" "\n\t"
"sbci r24, 0" "\n\t"
"sbci r24, -1" "\n\t"
"sts clockh+1, r24" "\n\t"
"2:" "\n\t"
"pop r24" "\n\t"
@ -109,7 +109,7 @@ ISR(RTC_CNT_vect)
if (flag & RTC_CNT_bm)
RTC.CMP += rtc_config[1].val | rtc_config[2].val << 8;
if (flag & RTC_OVF_bm)
clockh += 1;
clock += 1;
return;
}
#endif

261
src/spi.c
View file

@ -15,243 +15,6 @@ struct_ioconf(spi_config) = {
conf_io(SPI.CTRLA, SPI_MASTER_bm | SPI_ENABLE_bm | SPI_SPEED),
};
#ifndef SPI_USE_IRQ
#ifdef SPI_POLL_C
static
uint8_t spi_poll_delay()
{
uint8_t t = 0xff;
uint8_t ifg;
do {
ifg = SPI.INTFLAGS & SPI_RXCIF_bm;
} while (!ifg && t--);
return ifg;
}
static
void spi_poll_drop_tail()
{
uint8_t ifg;
do {
ifg = SPI.INTFLAGS;
SPI.DATA;
} while (~ifg & SPI_TXCIF_bm);
spi_poll_delay();
SPI.DATA;
}
static
void spi_poll_write_drop(uint8_t n, const uint8_t *c)
{
do {
uint8_t ifg = SPI.INTFLAGS;
if (ifg & SPI_DREIF_bm) {
SPI.DATA = *c++;
SPI.INTFLAGS = SPI_TXCIF_bm;
n--;
}
SPI.DATA;
} while (n);
spi_poll_drop_tail();
}
static
void spi_poll_zero_drop(uint8_t n)
{
uint8_t z = spi.zero;
do {
uint8_t ifg = SPI.INTFLAGS;
if (ifg & SPI_DREIF_bm) {
SPI.DATA = z;
SPI.INTFLAGS = SPI_TXCIF_bm;
n--;
}
SPI.DATA;
} while (n);
spi_poll_drop_tail();
}
static
uint8_t spi_poll_drop(uint8_t n, const uint8_t *c)
{
if (c)
spi_poll_write_drop(n, c);
else
spi_poll_zero_drop(n);
return n;
}
static
void spi_poll_read_tail(uint8_t r, uint8_t *d)
{
uint8_t ifg;
do {
ifg = SPI.INTFLAGS;
if (ifg & SPI_RXCIF_bm) {
*d++ = SPI.DATA;
if (!--r)
goto done;
}
} while (~ifg & SPI_TXCIF_bm);
if (spi_poll_delay()) {
*d = SPI.DATA;
r--;
}
done:
spi.rdata = d;
spi.rsize = r;
}
static
uint8_t spi_poll_write_read(uint8_t n, const uint8_t *c)
{
uint8_t r = spi.rsize;
uint8_t *d = spi.rdata;
uint8_t w = n;
do {
uint8_t ifg = SPI.INTFLAGS;
if (ifg & SPI_DREIF_bm) {
SPI.DATA = *c++;
SPI.INTFLAGS = SPI_TXCIF_bm;
if (!--n) {
spi_poll_read_tail(r, d);
return w;
}
}
if (ifg & SPI_RXCIF_bm) {
*d++ = SPI.DATA;
r--;
}
} while(r);
spi.rdata = d;
spi.rsize = r;
return w-n;
}
static
uint8_t spi_poll_read(uint8_t n, uint8_t r, uint8_t *d)
{
uint8_t z = spi.zero;
uint8_t w = n;
do {
uint8_t ifg = SPI.INTFLAGS;
if (ifg & SPI_DREIF_bm) {
SPI.DATA = z;
SPI.INTFLAGS = SPI_TXCIF_bm;
if (!--n) {
spi_poll_read_tail(r, d);
return w;
}
}
if (ifg & SPI_RXCIF_bm) {
*d++ = SPI.DATA;
r--;
}
} while(r);
spi.rdata = d;
spi.rsize = r;
return w-n;
}
static
uint8_t spi_poll_wait(uint8_t n)
{
uint8_t r = spi.rsize;
uint8_t *d = spi.rdata;
uint8_t z = spi.zero;
uint8_t w = n;
do {
uint8_t ifg = SPI.INTFLAGS;
if (ifg & SPI_DREIF_bm) {
SPI.DATA = z;
SPI.INTFLAGS = SPI_TXCIF_bm;
if (!--n) {
spi_poll_read_tail(r, d);
return w;
}
}
if (ifg & SPI_RXCIF_bm) {
uint8_t b = SPI.DATA;
if ((b & spi.mask) == spi.wait) {
*d++ = SPI.DATA;
r--;
spi.mask = 0;
break;
}
else
n++;
}
} while (1);
if (r)
return w - n + spi_poll_read(n, r, d);
spi.rdata = d;
spi.rsize = r;
return w-n;
}
static
uint8_t spi_poll_write(uint8_t n, const uint8_t *c)
{
uint8_t i = spi.isize;
uint8_t r = spi.rsize;
uint8_t w =0;
while (n) {
if (!r)
i = n;
if (i) {
if (i < n) {
uint8_t ww = spi_poll_drop(i, c);
w += ww;
c += ww;
n -= ww;
spi.isize = i = 0;
continue;
}
spi.isize = i -= n;
uint8_t ww = spi_poll_drop(n, c);
w += ww;
return w;
}
if (c)
w += spi_poll_write_read(n, c);
else if (spi.mask)
w += spi_poll_wait(n);
else
w += spi_poll_read(n, r, spi.rdata);
}
return w;
}
uint8_t spi_poll()
{
uint8_t n;
n = spi_poll_write(spi.csize, spi.cmd);
spi.cmd += n;
spi.csize -= n;
n = spi_poll_write(spi.zsize, 0);
spi.zsize -= n;
n = spi_poll_write(spi.wsize, spi.wdata);
spi.wdata += n;
spi.wsize -= n;
return 0;
}
#endif // SPI_POLL_C
#else // SPI_USE_IRQ
/****************************************************
The SPI is way to fast for this CPU, the job is done
in a single IRQ invocation.
Running the SPI synchronously allows other Interrupts
to happen.
****************************************************/
#if 0
ISR(SPI0_INT_vect)
{
@ -268,11 +31,6 @@ ISR(SPI0_INT_vect)
d = spi.zero;
}
else if (spi.wsize) {
// TODO:
// spi.csize = spi.wsize;
// spi.wsize = 0;
// spi.cmd = spi.wdata;
// goto repeat;
spi.wsize--;
d = *spi.wdata++;
}
@ -387,18 +145,23 @@ ISR(SPI0_INT_vect, ISR_NAKED)
"rjmp 4f" "\n"
"1:" "\n\t"
"lds r26, %[WAIT]" "\n\t"
"eor r26, r25" "\n\t"
"lds r24, %[MASK]" "\n\t"
"and r26, r24" "\n\t"
"breq 2f" "\n\t"
"lds r26, %[MASK]" "\n\t"
"cpi r26, 0" "\n\t"
"breq 1f" "\n\t"
"and r26, r25" "\n\t"
"lds r24, %[WAIT]" "\n\t"
"cp r24, r26" "\n\t"
"brne 2f" "\n\t"
"lds r25, %[ZSZ]" "\n\t"
"subi r25, -1" "\n\t"
"sts %[ZSZ], r25" "\n\t"
"rjmp 4f" "\n"
"2:" "\n\t"
"sts %[MASK], r26" "\n\t"
"clr r26" "\n\t"
"sts %[MASK], r26" "\n"
"1:" "\n\t"
"lds r26, %[RSZ]" "\n\t"
"subi r26, 1" "\n\t"
"brcs 4f" "\n\t"
@ -459,8 +222,6 @@ ISR(SPI0_INT_vect, ISR_NAKED)
}
#endif
#endif // SPI_USE_IRQ
uint8_t spi_select(uint8_t mode)
{
uint8_t s = spi_busy_p();

View file

@ -30,40 +30,9 @@ struct spi_job {
enum spi_mode_bits {
SPI_FLASH = 0x01,
SPI_CONFIG = 0x02,
SPI_NOPOLL = 0x40,
SPI_CONT = 0x80,
};
#ifndef SPI_USE_IRQ
#ifdef SPI_POLL_C
uint8_t spi_poll();
#else
uint8_t _spi_poll();
#define spi_poll _spi_poll
#endif
static inline
uint8_t spi_abort()
{
return 0;
}
static inline
uint8_t spi_busy_p()
{
return 0;
}
static inline
void spi_start()
{
if (~spi.mode & SPI_NOPOLL)
spi_poll();
}
#else // SPI_USE_IRQ
static inline
uint8_t spi_abort()
{
@ -86,8 +55,6 @@ void spi_start()
SPI.INTCTRL = SPI_DREIF_bm | SPI_TXCIF_bm| SPI_RXCIF_bm;
}
#endif // SPI_USE_IRQ
static inline void barrier() { __asm__("":::"memory"); }
void init_spi(uint8_t spi_div);
uint8_t spi_select(uint8_t mode);

View file

@ -1,259 +0,0 @@
#include <avr/io.h>
#define INTFLAGS SPI0_INTFLAGS
#define DATA SPI0_DATA
#define RXC SPI_RXCIF_bp
#define TXC SPI_TXCIF_bp
#define DRE SPI_DREIF_bp
; defined in spi.c
#define SPI_CONT 7
#define SSEL_VPORT VPORTA_OUT
#define SSEL_PIN 7
; Indices in struct spi_job, withn ldd, std
#define mode Y+0
#define csize Y+1
#define zsize Y+2
#define isize Y+3
#define zero Y+4
#define wait Y+5
#define mask Y+6
#define rsize Y+7
#define wsize Y+8
#define cmd Y+9
#define wdata Y+11
#define rdata Y+13
; All STD in this file should be optional, since
; this function will not be called again with the data.
; All LDD of updated status is done at entry.
; At least the "write" sizes should be updated,
; for safety.
;¿ #define std ;
.global _spi_poll
_spi_poll:
push r28
push r29
ldi r28, lo8(spi)
ldi r29, hi8(spi)
ldd r18, mask
; r19, wait, …
ldd r20, isize
ldd r21, zero
ldd r22, rsize
ldi r23, 1<<TXC
; r24, [czw]size
; r25, INTFLAG
; X, [cw]data
ldd r30, rdata
ldd r31, rdata+1
; drain the Rx fifo
lds r0, DATA
lds r0, DATA
lds r0, DATA
; send .cmd[.csize]
ldd r24, csize
tst r24
breq 5f
ldd r26, cmd
ldd r27, cmd+1
rcall _write
std csize, r24
std cmd, r26
std cmd+1, r27
; send .zsize .zero-s
5: ldd r24, zsize
tst r24
breq 6f
; clear X, no data to send
mov r26, r1
mov r27, r1
rcall _write
std zsize, r24
; send .wdata[wsize]
6: ldd r24, wsize
tst r24
breq 7f
ldd r26, wdata
ldd r27, wdata+1
rcall _write
std wsize, r24
std wdata, r26
std wdata+1, r27
; Update the "read" status.
7: std isize, r20
std rsize, r22
std rdata, r30
std rdata+1, r31
8: ldd r24, mode
sbrc r24, SPI_CONT
rjmp 1f
sbi SSEL_VPORT, SSEL_PIN
1: mov r24, r1 ; return 0
pop r29
pop r28
9: ret
_write_read:
; n = r24 != 0
; r = r22 != 0
; Send all `n` Bytes,
; Read up to `r` Bytes
lds r25, INTFLAGS
sbrs r25, DRE
rjmp 1f
ld r0, X+
sts DATA, r0
sts INTFLAGS, r23
subi r24, 1
breq _read_tail ; n==0 → collect data in flight
1: sbrs r25, RXC
rjmp _write_read
lds r0, DATA
st Z+, r0
subi r22, 1
brne _write_read
rjmp _write_drop ; r==0 → continue writing
_read_tail:
; r = r22 != 0
; Read data in flight
call _wait_tail
brcs 9f
st Z+, r0
subi r22, 1
brne _read_tail
9: ret
_w1: mov r20, r24 ; no rsize, i=n
_w2: sub r20, r24 ; isize = i-n
brcc _drop ; → send all n Bytes, drop all response
add r24, r20 ; n = n + (i-n) = i
neg r20 ; next n = n-i
push r20
mov r20, r1 ; i = 0
rcall _drop ; send i Bytes, drop response
pop r24 ; non-zero, the remaining Bytes to send
_write:
; n = r24 != 0
; X = .cmd
; X = 0
; X = .wdata
tst r22
breq _w1 ; → no rsize. Just send and drop everything
tst r20
brne _w2 ; → isize Bytes to drop before Read
sbiw r26,0
brne _write_read ; → send data, read response
_zero_read:
; n = r24 != 0
; r = r22 != 0
; send all `b` .zero-s, read `r` Bytes response
tst r18
brne _zero_wait ; → skip bytes until a byte matches
0: lds r25, INTFLAGS
sbrs r25, DRE
rjmp 1f
sts DATA, r21
sts INTFLAGS, r23
subi r24, 1
breq _read_tail
1: sbrs r25, RXC
rjmp 0b
lds r0, DATA
_zr: st Z+, r0
subi r22, 1
brne 0b
9: ret
_zero_wait:
; n = r24 != 0
; r = r22 != 0
; Send n .zero-s
; Compare response with .wait
; Sent additional .zero-s for any nonmatching response
; Buggy, when n==0, we should keep matching the tail.
; Will not work with small n.
lds r25, INTFLAGS
sbrs r25, DRE
rjmp 1f
sts DATA, r21
sts INTFLAGS, r23
subi r24, 1
breq _read_tail ; n==0 → collect the data in flight, BUG
1: sbrs r25, RXC
rjmp _zero_wait
subi r24, -1 ; send an extra .zero
lds r0, DATA
ldd r19, wait
eor r19, r0
and r19, r18
brne _zero_wait
subi r24, 1 ; drop the last extra .zero
rjmp _zr ; match found, continue with _zero_read
_drop:
; n = r24 != 0
; send Bytes, drop response
sbiw r26, 0
brne _write_drop ; → write .cmd/.wdata
_zero_drop:
; n = r24 != 0
; send .zero-s
lds r25, INTFLAGS
lds r0, DATA
sbrs r25, DRE
rjmp _zero_drop
sts DATA, r21
sts INTFLAGS, r23
subi r24, 1
brne _zero_drop
rjmp _drop_tail ; → drop data in flight
_write_drop:
; n = r24 != 0
; send .cmd/.wdata, drop response
lds r25, INTFLAGS
lds r0, DATA
sbrs r25, DRE
rjmp _write_drop
ld r0, X+
sts DATA, r0
sts INTFLAGS, r23
subi r24, 1
brne _write_drop
_drop_tail:
; n==0 → drop data in flight
call _wait_tail
brcc _drop_tail
ret
_wait_tail:
; Wait for data in flight.
; Restart the timeout with every byte received.
; TXC → shorten timeout.
; Return r25=INTFLAGS.
; RXC -> Return r0=DATA, C clear.
; Return C set on timeout.
ldi r19, 0xff ; wait a few µs for RXC
clc
1: lds r25, INTFLAGS
sbrs r25, RXC
rjmp 2f
lds r0, DATA
ret
2: sbrs r25, TXC
rjmp 3f
sts INTFLAGS, r23
ldi r19, 0x04 ; ¿ how long after TXC can we expect an RXC ?
3: subi r19, 1
brcc 1b
9: ret
_spi_poll_end:

View file

@ -10,18 +10,16 @@
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "revision.h"
#include "config.h"
#include "uart.h"
#include "pipe.h"
#include "adc.h"
////////////////////////////////////////////////////////////////////////////////
//
// main()
section_status(pipe) struct pipe pipe;
section_status(main) struct magic magic;
const char version_str[] = "\nV THHOR CRS V0.1" Revision;
int main()
{
@ -39,24 +37,12 @@ int main()
magic.reset_source = RSTCTRL.RSTFR;
RSTCTRL.RSTFR = magic.reset_source;
send_str(version_str);
send_str("\nV THHOR CRS V0.0");
send_hex_byte_eol(magic.reset_source);
while (1) {
// The irq sources may become idle before we reach sleep.
// Make sure we have nothing pending before we sleep.
// The sleep command will execute even when an irq becomes
// pending after cli(). It will wake us immediately.
cli();
if (!command_pending() && pipe_sleep) {
sei();
sleep_cpu();
}
sei();
sleep_cpu();
command();
if (~magic.flags & hold_pipe)
pipe_poll();
else
pipe_sleep = 1;
}
}

View file

@ -26,10 +26,3 @@ void send_hex_long(uint32_t b)
extern uint8_t uart_rx_err;
extern uint8_t uart_rx_errors;
extern volatile uint8_t uart_rx_mes;
static inline
uint8_t command_pending()
{
return uart_rx_mes;
}

View file

@ -61,7 +61,7 @@ class uart(threading.Thread):
def parse_line(self, l):
self.responses.append(l)
if self._verbose >= 4:
if self._verbose:
try:
s = l.decode()
print(f"{self.portname}<- {s}", file=sys.stderr)
@ -92,7 +92,7 @@ class uart(threading.Thread):
c = c.encode()
if c[-1:] != b'\n':
c = c + b'\n'
if self._verbose >= 4:
if self._verbose:
print(f"{self.portname}-> {c.decode().rstrip()}", file=sys.stderr)
self.write(c)

View file

@ -1,10 +0,0 @@
#! /bin/bash
git log --pretty='#define Revision " %h" Rev_Modified' --abbrev=8 HEAD^! > revision.h+
if git status --porcelain | grep -q '^.\?M'
then
echo '#define Rev_Modified "+"' >> revision.h+
else
echo '#define Rev_Modified ""' >> revision.h+
fi
diff -q revision.h+ revision.h || \mv -v revision.h+ revision.h
rm -f revision.h+

View file

@ -1,114 +0,0 @@
v 20220529 2
L 1000 2700 1000 1100 3 0 0 0 -1 -1
L 1000 1100 2200 1900 3 0 0 0 -1 -1
L 2200 1900 1000 2700 3 0 0 0 -1 -1
P 500 1900 1000 1900 1 0 0
{
T 800 1700 5 10 0 1 0 0 1
pinseq=1
T 700 1700 5 10 0 1 0 0 1
pinnumber=1
T 900 2000 9 10 1 1 0 7 1
pinlabel=in
T 700 1900 5 10 0 0 0 0 1
pintype=in
}
P 2500 1900 2200 1900 1 0 0
{
T 2300 1700 5 10 0 1 0 0 1
pinseq=2
T 2400 1700 5 10 0 1 0 0 1
pinnumber=2
T 2200 2000 9 10 1 1 0 1 1
pinlabel=out
T 2500 1900 5 10 0 0 0 0 1
pintype=out
}
P 1900 3000 1900 2100 1 0 0
{
T 1900 2400 5 10 0 1 0 0 1
pinseq=5
T 1900 2300 5 10 0 1 0 0 1
pinnumber=5
T 1800 2700 9 10 1 1 90 1 1
pinlabel=Vcc
T 1900 2800 5 10 0 0 0 0 1
pintype=pwr
}
P 1900 1000 1900 1700 1 0 0
{
T 1900 1300 5 10 0 1 0 0 1
pinseq=6
T 1900 1200 5 10 0 1 0 0 1
pinnumber=6
T 1800 1300 9 10 1 1 90 7 1
pinlabel=Vss
T 1900 1000 5 10 0 0 0 0 1
pintype=pwr
}
P 1600 3000 1600 2300 1 0 0
{
T 1600 2400 5 10 0 1 0 0 1
pinseq=4
T 1600 2300 5 10 0 1 0 0 1
pinnumber=4
T 1500 2700 9 10 1 1 90 1 1
pinlabel=Vfet
T 1600 2800 5 10 0 0 0 0 1
pintype=pwr
}
P 1600 1000 1600 1500 1 0 0
{
T 1600 1300 5 10 0 1 0 0 1
pinseq=3
T 1600 1200 5 10 0 1 0 0 1
pinnumber=3
T 1500 1400 9 10 1 1 90 7 1
pinlabel=GND
T 1600 1000 5 10 0 0 0 0 1
pintype=pwr
}
T 1800 2100 8 10 0 1 0 0 1
device=CSA
T 1800 2300 8 10 0 1 0 0 1
description=Charge Sensitive Amplifier
T 1100 2200 8 10 1 1 0 1 1
refdes=L?
P 1300 3000 1300 2500 1 0 0
{
T 1300 2600 5 10 0 1 0 0 1
pinseq=7
T 1300 2500 5 10 0 1 0 0 1
pinnumber=7
T 1200 2600 9 10 1 1 90 1 1
pinlabel=Vbias
T 1300 3000 5 10 0 0 0 0 1
pintype=pwr
}
P 500 1500 1000 1500 1 0 0
{
T 800 1300 5 10 0 1 0 0 1
pinseq=8
T 700 1300 5 10 0 1 0 0 1
pinnumber=8
T 900 1600 9 10 1 1 0 7 1
pinlabel=test
T 700 1500 5 10 0 0 0 0 1
pintype=in
}
T 2200 2100 8 10 0 1 0 0 1
revision=$Revision: 5 $
T 3000 3200 8 10 0 1 0 0 1
parameter=R20:27kΩ
T 3000 3000 8 10 0 1 0 0 1
parameter=R21:39kΩ
T 3000 2600 8 10 0 1 0 0 1
parameter=C21:68pF
T 3000 2800 8 10 0 1 0 0 1
parameter=C20:100pF
T 3000 3600 8 10 0 1 0 0 1
parameter=R22:1kΩ
T 3000 3400 8 10 0 1 0 0 1
parameter=R23:2.2kΩ
T 3000 3800 8 10 0 1 0 0 1
parameter=R5:220Ω

View file

@ -20,6 +20,8 @@ description=oscillator
T 325 350 8 5 1 1 0 4 1
footprint=XO53
B 100 -200 500 600 3 10 1 0 -1 -1 0 -1 -1 -1 -1 -1
T -475 250 8 10 0 1 0 0 1
net=GND:1
T -475 50 8 10 0 1 0 0 1
net=GND:2
T 25 -100 8 6 1 1 0 7 1

View file

@ -1,46 +0,0 @@
v 20060123 1
L 400 600 400 200 3 0 0 0 -1 -1
T -100 600 5 10 0 1 0 0 1
device=2S2K3
L 400 500 600 500 3 0 0 0 -1 -1
P 600 500 600 800 1 0 1
{
T 500 700 5 10 1 1 0 4 1
pinnumber=2
T 600 500 5 10 0 1 0 0 1
pinseq=1
T 700 700 5 10 1 1 0 4 1
pinlabel=D
T 600 500 5 10 0 1 0 0 1
pintype=pas
}
L 400 300 600 300 3 0 0 0 -1 -1
P 600 300 600 0 1 0 1
{
T 500 100 5 10 1 1 0 4 1
pinnumber=1
T 600 300 5 10 0 1 0 0 1
pinseq=3
T 700 100 5 10 1 1 0 4 1
pinlabel=S
T 600 100 5 10 0 1 0 0 1
pintype=pas
}
L 300 400 400 400 3 0 0 0 -1 -1
L 350 450 400 400 3 0 0 0 -1 -1
L 400 400 350 350 3 0 0 0 -1 -1
P 300 400 0 400 1 0 1
{
T 200 300 5 10 0 1 0 4 1
pinseq=2
T 200 300 5 10 1 1 0 4 1
pinnumber=3
T 200 500 5 10 1 1 0 4 1
pinlabel=G
T 200 400 5 10 0 1 0 0 1
pintype=pas
}
T 700 500 8 10 1 1 0 0 1
refdes=J?
T 800 300 8 10 0 1 0 0 1
footprint=SOT23

View file

@ -1,50 +0,0 @@
v 20111231 2
P 600 1000 600 800 1 0 0
{
T 500 850 5 6 1 1 0 0 1
pinnumber=3
T 700 850 5 6 0 0 0 0 1
pinseq=1
T 700 1050 5 6 0 0 0 0 1
pinlabel=C
T 700 950 5 6 0 0 0 0 1
pintype=pas
}
P 600 200 600 0 1 0 1
{
T 500 50 5 6 1 1 0 0 1
pinnumber=2
T 700 50 5 6 0 0 0 0 1
pinseq=3
T 700 250 5 6 0 0 0 0 1
pinlabel=E
T 700 150 5 6 0 0 0 0 1
pintype=pas
}
T 900 500 5 10 0 0 0 0 1
device=PNP_TRANSISTOR
L 600 200 400 400 3 0 0 0 -1 -1
L 600 800 400 600 3 0 0 0 -1 -1
L 400 700 400 300 3 0 0 0 -1 -1
P 0 500 184 500 1 0 0
{
T 300 350 5 6 1 1 0 0 1
pinnumber=1
T 0 550 5 6 0 0 0 0 1
pinseq=2
T 0 750 5 6 0 0 0 0 1
pinlabel=B
T 0 650 5 6 0 0 0 0 1
pintype=pas
}
L 400 500 184 500 3 0 0 0 -1 -1
H 3 0 0 0 -1 -1 1 -1 -1 -1 -1 -1 5
M 440,290
L 400,401
L 495,355
L 465,335
z
T 900 500 8 10 1 1 0 0 1
refdes=Q?
T 900 300 8 10 1 1 0 0 1
footprint=SOT23

BIN
thhor_crs-bot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

BIN
thhor_crs-top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

View file

@ -27,7 +27,7 @@ XB/U2out XB/R6-2 XB/R9-1 XB/U2-1
XB/U1inv XB/C3-1 XB/R3-1 XB/R5-2 XB/U1-4
XB/U1out XB/C3-2 XB/R3-2 XB/U1-1 XB/R4-1
XB/U2- XB/R6-1 XB/U2-4 XB/R4-2
VssH C36-2 R38-2 R36-2 U30-2 XB/U2-2 XB/U1-2
VssH C36-2 R38-2 U30-2 XB/U2-2 XB/U1-2
VccH C35-1 R37-1 U30-5 XB/U2-5 XB/U1-5
hka3j XB/R9-2 R39-1 C31-2
VBIASR XB/U1-3 R30-2 C32-1 R32-1
@ -190,8 +190,8 @@ HKA3 R57-1 R65-2 C59-2 A/C3-2 A/U1-7
SA2 CONN1-15 A/C/R1-1
SA1 CONN1-14 A/B/R1-1
DINA R4-6 A/U1-14
Vadc C141-1 C140-1 R66-2 XADC/C3-1 XADC/R1-1 XADC/C2-2 XADC/U1-5 D/R7-1 D/C9-2 D/C8-2 D/U1-13 D/U1-2 C/R7-1 C/C9-2 C/C8-2 C/U1-13 C/U1-2 B/R7-1 B/C9-2 B/C8-2 B/U1-13 B/U1-2 A/R7-1 A/C9-2 A/C8-2 A/U1-13 \
A/U1-2
Vadc C141-1 C140-1 R36-2 R66-2 XADC/C3-1 XADC/R1-1 XADC/C2-2 XADC/U1-5 D/R7-1 D/C9-2 D/C8-2 D/U1-13 D/U1-2 C/R7-1 C/C9-2 C/C8-2 C/U1-13 C/U1-2 B/R7-1 B/C9-2 B/C8-2 B/U1-13 B/U1-2 A/R7-1 A/C9-2 A/C8-2 \
A/U1-13 A/U1-2
SCKA R4-8 A/U1-16
nCSA R4-5 A/U1-1
DOUTA R4-7 A/U1-15
@ -295,7 +295,7 @@ P32 P32-1 U1-32
P31 P31-1 U1-31
P28 P28-1 U1-28
xclk U9-3 U1-22
Vio C138-1 C137-1 C136-1 C135-1 C134-1 C133-1 C132-1 C131-1 C130-1 U9-1 U9-4 XIO/C3-1 XIO/R1-1 XIO/C2-2 XIO/U1-5 U1-62 U1-26 U1-56 U1-47 U1-40 U1-18 U1-17 U1-15
Vio C138-1 C137-1 C136-1 C135-1 C134-1 C133-1 C132-1 C131-1 C130-1 U9-4 XIO/C3-1 XIO/R1-1 XIO/C2-2 XIO/U1-5 U1-62 U1-26 U1-56 U1-47 U1-40 U1-18 U1-17 U1-15
nCONFIG U2-4 U1-14
MOSI U4-1 U2-11 U1-13
DCLK U6-4 U1-12 U1-11
@ -310,7 +310,7 @@ GND U6-3 C39-2 C38-2 C42-1 C37-1 C29-1 C28-1 C27-2 C26-2 C25-2 C20-2 C23-2 BOARD
CONN1-26 CONN1-27 CONN1-28 CONN1-29 CONN1-30 CONN1-31 PG2-1 PG1-1 C138-2 C127-2 C126-2 C137-2 C136-2 C125-2 C124-2 C123-2 C122-2 C171-2 C170-2 C169-2 C168-2 C151-2 C150-2 C167-2 C166-2 C165-2 C164-2 \
C163-2 C162-2 C161-2 C160-2 C159-2 C158-2 C157-2 C156-2 C155-2 C154-2 C153-2 C152-2 C135-2 C134-2 C133-2 C132-2 C131-2 C130-2 C121-2 C120-2 C119-2 C118-2 C117-2 C116-2 C115-2 C114-2 C113-2 C112-2 \
C111-2 C110-2 J1-8 J1-6 C102-2 C101-2 C100-2 C36-1 C35-2 C41-1 C40-1 U5-1 C63-1 R73-1 C62-1 R69-1 C60-1 C61-1 R67-1 C64-1 R61-1 C55-1 C54-1 C53-1 C52-1 C59-1 R64-1 C58-1 C57-1 R62-1 C56-1 U30-3 C34-1 \
C33-2 C51-1 R52-1 C50-1 P1_3-1 XFET/C1-2 XFET/C3-2 XFET/R2-1 XFET/U1-2 XSSP/C1-1 XSSP/U1-1 XSSP/C3-1 XSSP/R2-1 XCCP/C1-2 XCCP/C3-2 XCCP/R2-1 XCCP/U1-2 C24-1 C21-2 C22-2 U9-2 XIO/C1-2 XIO/C3-2 \
C33-2 C51-1 R52-1 C50-1 P1_3-1 XFET/C1-2 XFET/C3-2 XFET/R2-1 XFET/U1-2 XSSP/C1-1 XSSP/U1-1 XSSP/C3-1 XSSP/R2-1 XCCP/C1-2 XCCP/C3-2 XCCP/R2-1 XCCP/U1-2 C24-1 C21-2 C22-2 U9-2 U9-1 XIO/C1-2 XIO/C3-2 \
XIO/R2-1 XIO/U1-2 C31-1 XB/U2-3 XB/R5-1 C32-2 R32-2 C30-1 XSSS/C1-1 XSSS/U1-1 XSSS/C3-1 XSSS/R2-1 XCCS/C1-2 XCCS/C3-2 XCCS/R2-1 XCCS/U1-2 XADC/C1-2 XADC/C3-2 XADC/R2-1 XADC/U1-2 D/C2-2 D/C1-2 \
D/A/C7-2 D/A/C4-2 D/A/C5-2 D/A/U1-3 D/B/C7-2 D/B/C4-2 D/B/C5-2 D/B/U1-3 D/C/C7-2 D/C/C4-2 D/C/C5-2 D/C/U1-3 D/C9-1 D/C8-1 D/C3-1 D/C4-1 D/C5-1 D/C6-1 D/C7-1 D/C0-2 D/U1-3 D/U1-12 C/C2-2 C/C1-2 \
C/A/C7-2 C/A/C4-2 C/A/C5-2 C/A/U1-3 C/B/C7-2 C/B/C4-2 C/B/C5-2 C/B/U1-3 C/C/C7-2 C/C/C4-2 C/C/C5-2 C/C/U1-3 C/C9-1 C/C8-1 C/C3-1 C/C4-1 C/C5-1 C/C6-1 C/C7-1 C/C0-2 C/U1-3 C/U1-12 B/C2-2 B/C1-2 \

View file

@ -9,7 +9,7 @@ Grid[0.1000mm 0.0000 0.0000 1]
PolyArea[200000000.000000]
Thermal[0.500000]
DRC[0.1999mm 0.0100mm 0.1500mm 0.10mil 0.3000mm 0.2000mm]
Flags("nameonpcb,alldirection,clearnew,autoburiedvias")
Flags("rubberband,nameonpcb,alldirection,clearnew,locknames,autoburiedvias")
Groups("1,c:5:4:3:2:6,s:7:8")
Styles["Signal,0.2000mm,0.7000mm,0.3000mm,0.2000mm,0.5000mm:Power,0.6000mm,1.0000mm,0.5000mm,0.2000mm,0.8000mm:Fat,3.0000mm,4.0000mm,2.2000mm,0.2000mm,4.1000mm:Skinny,6.00mil,24.02mil,11.81mil,6.00mil"]
Symbol[' ' 18.00mil]
@ -877,7 +877,7 @@ Via[18.1000mm 37.4000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[22.5000mm 23.3000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(2X,4X)"]
Via[22.5000mm 29.7000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(3X)"]
Via[16.5000mm 39.7000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[26.6000mm 57.4000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(3S)"]
Via[24.2000mm 57.4000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(3S)"]
Via[25.1000mm 60.8000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[22.6000mm 62.0000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(0S,2S)"]
Via[18.2000mm 44.7000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(2S)"]
@ -989,6 +989,7 @@ Via[51.3000mm 62.4000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(3t,4t)"]
Via[51.7000mm 64.4000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" "thermal(3X)"]
Via[51.2000mm 65.8000mm 1.0000mm 0.4000mm 0.8000mm 0.5000mm "" "thermal(4X)"]
Via[54.1000mm 65.8000mm 1.0000mm 0.4000mm 0.8000mm 0.5000mm "" "thermal(2S)"]
Via[44.3000mm 75.4000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[43.3000mm 77.5000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[49.0000mm 76.9000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[48.1000mm 80.7000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
@ -1150,7 +1151,7 @@ Via[28.4000mm 26.9000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[29.3000mm 27.6000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[44.5000mm 31.6000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[58.8000mm 33.2000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[54.0000mm 27.7000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[54.2000mm 27.5000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[32.0000mm 31.3000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[34.4000mm 31.3000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
Via[35.6000mm 31.3000mm 0.7000mm 0.4000mm 0.5000mm 0.3000mm "" ""]
@ -2973,14 +2974,14 @@ Element["hidename,onsolder" "C0603" "C134" "100nF" 26.7000mm 62.7000mm 0.7000mm
)
Element["hidename,onsolder" "C0603" "C133" "100nF" 24.2000mm 56.1000mm -0.7000mm -0.5000mm 0 50 "onsolder"]
Element["hidename,onsolder" "C0603" "C133" "100nF" 21.0000mm 58.4000mm -0.5000mm 0.7000mm 3 50 "onsolder"]
(
Pad[-32.00mil -2.00mil -32.00mil 2.00mil 35.00mil 20.00mil 41.00mil "1" "1" "onsolder,square"]
Pad[32.00mil -2.00mil 32.00mil 2.00mil 35.00mil 20.00mil 41.00mil "2" "2" "onsolder,square"]
ElementLine [-30.00mil -15.00mil -30.00mil 15.00mil 5.00mil]
ElementLine [-30.00mil -15.00mil 30.00mil -15.00mil 5.00mil]
ElementLine [30.00mil -15.00mil 30.00mil 15.00mil 5.00mil]
ElementLine [-30.00mil 15.00mil 30.00mil 15.00mil 5.00mil]
Pad[-2.00mil 32.00mil 2.00mil 32.00mil 35.00mil 20.00mil 41.00mil "1" "1" "onsolder,square"]
Pad[-2.00mil -32.00mil 2.00mil -32.00mil 35.00mil 20.00mil 41.00mil "2" "2" "onsolder,square"]
ElementLine [-15.00mil 30.00mil 15.00mil 30.00mil 5.00mil]
ElementLine [-15.00mil -30.00mil -15.00mil 30.00mil 5.00mil]
ElementLine [-15.00mil -30.00mil 15.00mil -30.00mil 5.00mil]
ElementLine [15.00mil -30.00mil 15.00mil 30.00mil 5.00mil]
)
@ -4315,6 +4316,58 @@ Element["" "TSSOP_4_16" "C/U1" "ADC128S102" 41.9000mm 50.4000mm -0.6000mm 0.8000
)
Element["onsolder" "OmneVSM37" "CONN1" "A29200-037" 56.5000mm 20.2000mm 0.9620mm 70.00mil 3 100 "onsolder"]
(
Pin[0.0000 -310.00mil 65.00mil 20.00mil 70.00mil 43.00mil "" "0" "thermal(1S)"]
Pin[0.0000 310.00mil 65.00mil 20.00mil 70.00mil 43.00mil "" "0" "thermal(1S)"]
Pad[25.00mil -212.50mil 95.00mil -212.50mil 17.00mil 20.00mil 20.00mil "37" "37" "onsolder,square,edge2"]
Pad[25.00mil -187.50mil 95.00mil -187.50mil 17.00mil 20.00mil 20.00mil "36" "36" "onsolder,square,edge2"]
Pad[25.00mil -162.50mil 95.00mil -162.50mil 17.00mil 20.00mil 20.00mil "35" "35" "onsolder,square,edge2"]
Pad[25.00mil -137.50mil 95.00mil -137.50mil 17.00mil 20.00mil 20.00mil "34" "34" "onsolder,square,edge2"]
Pad[25.00mil -112.50mil 95.00mil -112.50mil 17.00mil 20.00mil 20.00mil "33" "33" "onsolder,square,edge2"]
Pad[25.00mil -87.50mil 95.00mil -87.50mil 17.00mil 20.00mil 20.00mil "32" "32" "onsolder,square,edge2"]
Pad[25.00mil -62.50mil 95.00mil -62.50mil 17.00mil 20.00mil 20.00mil "31" "31" "onsolder,square,edge2"]
Pad[25.00mil -37.50mil 95.00mil -37.50mil 17.00mil 20.00mil 20.00mil "30" "30" "onsolder,square,edge2"]
Pad[25.00mil -12.50mil 95.00mil -12.50mil 17.00mil 20.00mil 20.00mil "29" "29" "onsolder,square,edge2"]
Pad[25.00mil 12.50mil 95.00mil 12.50mil 17.00mil 20.00mil 20.00mil "28" "28" "onsolder,square,edge2"]
Pad[25.00mil 37.50mil 95.00mil 37.50mil 17.00mil 20.00mil 20.00mil "27" "27" "onsolder,square,edge2"]
Pad[25.00mil 62.50mil 95.00mil 62.50mil 17.00mil 20.00mil 20.00mil "26" "26" "onsolder,square,edge2"]
Pad[25.00mil 87.50mil 95.00mil 87.50mil 17.00mil 20.00mil 20.00mil "25" "25" "onsolder,square,edge2"]
Pad[25.00mil 112.50mil 95.00mil 112.50mil 17.00mil 20.00mil 20.00mil "24" "24" "onsolder,square,edge2"]
Pad[25.00mil 137.50mil 95.00mil 137.50mil 17.00mil 20.00mil 20.00mil "23" "23" "onsolder,square,edge2"]
Pad[25.00mil 162.50mil 95.00mil 162.50mil 17.00mil 20.00mil 20.00mil "22" "22" "onsolder,square,edge2"]
Pad[25.00mil 187.50mil 95.00mil 187.50mil 17.00mil 20.00mil 20.00mil "21" "21" "onsolder,square,edge2"]
Pad[25.00mil 212.50mil 95.00mil 212.50mil 17.00mil 20.00mil 20.00mil "20" "20" "onsolder,square,edge2"]
Pad[-85.00mil -225.00mil -25.00mil -225.00mil 17.00mil 20.00mil 20.00mil "19" "19" "onsolder,square"]
Pad[-85.00mil -200.00mil -25.00mil -200.00mil 17.00mil 20.00mil 20.00mil "18" "18" "onsolder,square"]
Pad[-85.00mil -175.00mil -25.00mil -175.00mil 17.00mil 20.00mil 20.00mil "17" "17" "onsolder,square"]
Pad[-85.00mil -150.00mil -25.00mil -150.00mil 17.00mil 20.00mil 20.00mil "16" "16" "onsolder,square"]
Pad[-85.00mil -125.00mil -25.00mil -125.00mil 17.00mil 20.00mil 20.00mil "15" "15" "onsolder,square"]
Pad[-85.00mil -100.00mil -25.00mil -100.00mil 17.00mil 20.00mil 20.00mil "14" "14" "onsolder,square"]
Pad[-85.00mil -75.00mil -25.00mil -75.00mil 17.00mil 20.00mil 20.00mil "13" "13" "onsolder,square"]
Pad[-85.00mil -50.00mil -25.00mil -50.00mil 17.00mil 20.00mil 20.00mil "12" "12" "onsolder,square"]
Pad[-85.00mil -25.00mil -25.00mil -25.00mil 17.00mil 20.00mil 20.00mil "11" "11" "onsolder,square"]
Pad[-85.00mil 0.0000 -25.00mil 0.0000 17.00mil 20.00mil 20.00mil "10" "10" "onsolder,square"]
Pad[-85.00mil 25.00mil -25.00mil 25.00mil 17.00mil 20.00mil 20.00mil "9" "9" "onsolder,square"]
Pad[-85.00mil 50.00mil -25.00mil 50.00mil 17.00mil 20.00mil 20.00mil "8" "8" "onsolder,square"]
Pad[-85.00mil 75.00mil -25.00mil 75.00mil 17.00mil 20.00mil 20.00mil "7" "7" "onsolder,square"]
Pad[-85.00mil 100.00mil -25.00mil 100.00mil 17.00mil 20.00mil 20.00mil "6" "6" "onsolder,square"]
Pad[-85.00mil 125.00mil -25.00mil 125.00mil 17.00mil 20.00mil 20.00mil "5" "5" "onsolder,square"]
Pad[-85.00mil 150.00mil -25.00mil 150.00mil 17.00mil 20.00mil 20.00mil "4" "4" "onsolder,square"]
Pad[-85.00mil 175.00mil -25.00mil 175.00mil 17.00mil 20.00mil 20.00mil "3" "3" "onsolder,square"]
Pad[-85.00mil 200.00mil -25.00mil 200.00mil 17.00mil 20.00mil 20.00mil "2" "2" "onsolder,square"]
Pad[-85.00mil 225.00mil -25.00mil 225.00mil 17.00mil 20.00mil 20.00mil "1" "1" "onsolder,square"]
ElementLine [-57.50mil 260.00mil -57.50mil 362.50mil 6.00mil]
ElementLine [-57.50mil 260.00mil 67.50mil 260.00mil 6.00mil]
ElementLine [67.50mil 260.00mil 67.50mil 362.50mil 6.00mil]
ElementLine [-57.50mil 362.50mil 67.50mil 362.50mil 6.00mil]
ElementLine [-57.50mil -362.50mil -57.50mil -260.00mil 6.00mil]
ElementLine [-57.50mil -260.00mil 67.50mil -260.00mil 6.00mil]
ElementLine [67.50mil -362.50mil 67.50mil -260.00mil 6.00mil]
ElementLine [-57.50mil -362.50mil 67.50mil -362.50mil 6.00mil]
)
Element["" "C0805" "D/C0" "10nF_NP0" 46.1000mm 55.5000mm -0.9000mm -0.4000mm 0 55 ""]
(
Pad[-34.50mil -10.00mil -34.50mil 10.00mil 40.00mil 20.00mil 46.00mil "1" "1" "square"]
@ -7214,7 +7267,7 @@ Element["hidename" "C0603" "C51" "100nF" 32.0000mm 29.9000mm -0.3000mm -1.1000mm
)
Element["lock" "qsat60x80" "BOARD" "thhor_crs_v01" 5.0000mm 5.0000mm 0.0000 0.0000 0 55 ""]
Element["lock" "qsat60x80" "BOARD" "thhor_crs_v01" 5.0000mm 5.0000mm 0.0000 0.0000 0 55 "selected"]
(
Pin[2.5000mm 2.5000mm 3.0000mm 0.4000mm 3.1000mm 2.2000mm "pin" "1" "lock,thermal(1S)"]
Pin[58.5000mm 2.5000mm 3.0000mm 0.4000mm 3.1000mm 2.2000mm "pin" "1" "lock,thermal(1S)"]
@ -7460,10 +7513,10 @@ Element["lock" "qsat60x80" "BOARD" "thhor_crs_v01" 5.0000mm 5.0000mm 0.0000 0.00
Pad[58.5000mm 2.5000mm 58.5000mm 78.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "lock"]
Pad[2.5000mm 78.5000mm 58.5000mm 78.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "lock"]
Pad[2.5000mm 2.5000mm 2.5000mm 78.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "lock"]
Pad[2.5000mm 2.5000mm 58.5000mm 2.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "onsolder,lock"]
Pad[2.5000mm 2.5000mm 2.5000mm 78.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "onsolder,lock"]
Pad[2.5000mm 78.5000mm 58.5000mm 78.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "onsolder,lock"]
Pad[58.5000mm 2.5000mm 58.5000mm 78.5000mm 3.0000mm 0.4000mm 4.0000mm "pin" "1" "onsolder,lock"]
Pad[2.5000mm 2.5000mm 58.5000mm 2.5000mm 3.0000mm 0.4000mm 3.4000mm "pin" "1" "onsolder,lock"]
Pad[2.5000mm 2.5000mm 2.5000mm 78.5000mm 3.0000mm 0.4000mm 3.4000mm "pin" "1" "onsolder,lock"]
Pad[2.5000mm 78.5000mm 58.5000mm 78.5000mm 3.0000mm 0.4000mm 3.4000mm "pin" "1" "onsolder,lock"]
Pad[58.5000mm 2.5000mm 58.5000mm 78.5000mm 3.0000mm 0.4000mm 3.4000mm "pin" "1" "onsolder,lock"]
ElementLine [2.5000mm 0.5000mm 58.5000mm 0.5000mm 0.7024mm]
ElementLine [60.5000mm 2.5000mm 60.5000mm 78.5000mm 0.7024mm]
ElementLine [58.5000mm 80.5000mm 2.5000mm 80.5000mm 0.7024mm]
@ -7610,60 +7663,6 @@ Element["" "SC70_5" "U6" "SN74AUP1G08DCK" 29.3500mm 66.1000mm -0.4000mm 0.3500mm
ElementLine [-0.6000mm -0.9750mm -0.6000mm 0.9750mm 5.00mil]
ElementLine [-0.6000mm 0.9750mm 0.6000mm 0.9750mm 5.00mil]
)
Element["onsolder" "OmneVSM37" "CONN1" "A29200-037" 56.5000mm 20.2000mm 26.50mil -78.00mil 1 100 "onsolder"]
(
Pin[0.0000 -310.00mil 2.0000mm 20.00mil 2.1270mm 1.5500mm "" "0" "thermal(1S)"]
Pin[0.0000 310.00mil 2.0000mm 20.00mil 2.1270mm 1.5500mm "" "0" "thermal(1S)"]
Pad[-6.50mil 311.50mil 15.50mil 311.50mil 102.00mil 20.00mil 110.00mil "" "0" "onsolder,square"]
Pad[-6.50mil -311.50mil 15.50mil -311.50mil 102.00mil 20.00mil 110.00mil "" "0" "onsolder,square"]
Pad[25.00mil -212.50mil 95.00mil -212.50mil 17.00mil 20.00mil 22.00mil "37" "37" "onsolder,square,edge2"]
Pad[25.00mil -187.50mil 95.00mil -187.50mil 17.00mil 20.00mil 22.00mil "36" "36" "onsolder,square,edge2"]
Pad[25.00mil -162.50mil 95.00mil -162.50mil 17.00mil 20.00mil 22.00mil "35" "35" "onsolder,square,edge2"]
Pad[25.00mil -137.50mil 95.00mil -137.50mil 17.00mil 20.00mil 22.00mil "34" "34" "onsolder,square,edge2"]
Pad[25.00mil -112.50mil 95.00mil -112.50mil 17.00mil 20.00mil 22.00mil "33" "33" "onsolder,square,edge2"]
Pad[25.00mil -87.50mil 95.00mil -87.50mil 17.00mil 20.00mil 22.00mil "32" "32" "onsolder,square,edge2"]
Pad[25.00mil -62.50mil 95.00mil -62.50mil 17.00mil 20.00mil 22.00mil "31" "31" "onsolder,square,edge2"]
Pad[25.00mil -37.50mil 95.00mil -37.50mil 17.00mil 20.00mil 22.00mil "30" "30" "onsolder,square,edge2"]
Pad[25.00mil -12.50mil 95.00mil -12.50mil 17.00mil 20.00mil 22.00mil "29" "29" "onsolder,square,edge2"]
Pad[25.00mil 12.50mil 95.00mil 12.50mil 17.00mil 20.00mil 22.00mil "28" "28" "onsolder,square,edge2"]
Pad[25.00mil 37.50mil 95.00mil 37.50mil 17.00mil 20.00mil 22.00mil "27" "27" "onsolder,square,edge2"]
Pad[25.00mil 62.50mil 95.00mil 62.50mil 17.00mil 20.00mil 22.00mil "26" "26" "onsolder,square,edge2"]
Pad[25.00mil 87.50mil 95.00mil 87.50mil 17.00mil 20.00mil 22.00mil "25" "25" "onsolder,square,edge2"]
Pad[25.00mil 112.50mil 95.00mil 112.50mil 17.00mil 20.00mil 22.00mil "24" "24" "onsolder,square,edge2"]
Pad[25.00mil 137.50mil 95.00mil 137.50mil 17.00mil 20.00mil 22.00mil "23" "23" "onsolder,square,edge2"]
Pad[25.00mil 162.50mil 95.00mil 162.50mil 17.00mil 20.00mil 22.00mil "22" "22" "onsolder,square,edge2"]
Pad[25.00mil 187.50mil 95.00mil 187.50mil 17.00mil 20.00mil 22.00mil "21" "21" "onsolder,square,edge2"]
Pad[25.00mil 212.50mil 95.00mil 212.50mil 17.00mil 20.00mil 22.00mil "20" "20" "onsolder,square,edge2"]
Pad[-85.00mil -225.00mil -25.00mil -225.00mil 17.00mil 20.00mil 22.00mil "19" "19" "onsolder,square"]
Pad[-85.00mil -200.00mil -25.00mil -200.00mil 17.00mil 20.00mil 22.00mil "18" "18" "onsolder,square"]
Pad[-85.00mil -175.00mil -25.00mil -175.00mil 17.00mil 20.00mil 22.00mil "17" "17" "onsolder,square"]
Pad[-85.00mil -150.00mil -25.00mil -150.00mil 17.00mil 20.00mil 22.00mil "16" "16" "onsolder,square"]
Pad[-85.00mil -125.00mil -25.00mil -125.00mil 17.00mil 20.00mil 22.00mil "15" "15" "onsolder,square"]
Pad[-85.00mil -100.00mil -25.00mil -100.00mil 17.00mil 20.00mil 22.00mil "14" "14" "onsolder,square"]
Pad[-85.00mil -75.00mil -25.00mil -75.00mil 17.00mil 20.00mil 22.00mil "13" "13" "onsolder,square"]
Pad[-85.00mil -50.00mil -25.00mil -50.00mil 17.00mil 20.00mil 22.00mil "12" "12" "onsolder,square"]
Pad[-85.00mil -25.00mil -25.00mil -25.00mil 17.00mil 20.00mil 22.00mil "11" "11" "onsolder,square"]
Pad[-85.00mil 0.0000 -25.00mil 0.0000 17.00mil 20.00mil 22.00mil "10" "10" "onsolder,square"]
Pad[-85.00mil 25.00mil -25.00mil 25.00mil 17.00mil 20.00mil 22.00mil "9" "9" "onsolder,square"]
Pad[-85.00mil 50.00mil -25.00mil 50.00mil 17.00mil 20.00mil 22.00mil "8" "8" "onsolder,square"]
Pad[-85.00mil 75.00mil -25.00mil 75.00mil 17.00mil 20.00mil 22.00mil "7" "7" "onsolder,square"]
Pad[-85.00mil 100.00mil -25.00mil 100.00mil 17.00mil 20.00mil 22.00mil "6" "6" "onsolder,square"]
Pad[-85.00mil 125.00mil -25.00mil 125.00mil 17.00mil 20.00mil 22.00mil "5" "5" "onsolder,square"]
Pad[-85.00mil 150.00mil -25.00mil 150.00mil 17.00mil 20.00mil 22.00mil "4" "4" "onsolder,square"]
Pad[-85.00mil 175.00mil -25.00mil 175.00mil 17.00mil 20.00mil 22.00mil "3" "3" "onsolder,square"]
Pad[-85.00mil 200.00mil -25.00mil 200.00mil 17.00mil 20.00mil 22.00mil "2" "2" "onsolder,square"]
Pad[-85.00mil 225.00mil -25.00mil 225.00mil 17.00mil 20.00mil 22.00mil "1" "1" "onsolder,square"]
ElementLine [-57.50mil 362.50mil -57.50mil 260.00mil 6.00mil]
ElementLine [-57.50mil 260.00mil 67.50mil 260.00mil 6.00mil]
ElementLine [67.50mil 362.50mil 67.50mil 260.00mil 6.00mil]
ElementLine [-57.50mil 362.50mil 67.50mil 362.50mil 6.00mil]
ElementLine [-57.50mil -260.00mil -57.50mil -362.50mil 6.00mil]
ElementLine [-57.50mil -260.00mil 67.50mil -260.00mil 6.00mil]
ElementLine [67.50mil -260.00mil 67.50mil -362.50mil 6.00mil]
ElementLine [-57.50mil -362.50mil 67.50mil -362.50mil 6.00mil]
)
Layer(1 "top" "copper")
(
@ -8334,6 +8333,7 @@ Layer(1 "top" "copper")
Line[38.7000mm 42.0000mm 36.8000mm 42.6000mm 0.2000mm 0.4000mm "clearline"]
Line[51.3000mm 62.4000mm 51.3000mm 63.8000mm 0.2000mm 0.4000mm "clearline"]
Line[53.7000mm 63.8000mm 51.3000mm 63.8000mm 0.2000mm 0.4000mm "clearline"]
Line[40.2000mm 60.9000mm 40.2000mm 62.0000mm 0.2000mm 0.4000mm "clearline"]
Line[42.9000mm 36.1000mm 45.5000mm 36.1000mm 0.2000mm 0.4000mm "clearline"]
Line[45.5000mm 36.1000mm 45.5000mm 35.0000mm 0.2000mm 0.4000mm "clearline"]
Line[45.5000mm 35.0000mm 45.8000mm 34.7000mm 0.2000mm 0.4000mm "clearline"]
@ -8615,8 +8615,8 @@ Layer(1 "top" "copper")
Line[44.4000mm 30.5000mm 45.7000mm 30.5000mm 0.2000mm 0.4000mm "clearline"]
Line[45.7000mm 30.5000mm 46.6000mm 31.3000mm 0.2000mm 0.4000mm "clearline"]
Line[42.3000mm 34.1000mm 42.3000mm 32.9000mm 0.2000mm 0.4000mm "clearline"]
Line[58.8000mm 33.2000mm 54.0000mm 29.3000mm 0.2000mm 0.4000mm "clearline"]
Line[54.0000mm 29.3000mm 54.0000mm 27.7000mm 0.2000mm 0.4000mm "clearline"]
Line[58.8000mm 33.2000mm 54.2000mm 29.5000mm 0.2000mm 0.4000mm "clearline"]
Line[54.2000mm 29.5000mm 54.2000mm 27.5000mm 0.2000mm 0.4000mm "clearline"]
Line[46.1000mm 46.8000mm 47.2000mm 46.8000mm 0.2000mm 0.4000mm "clearline"]
Line[42.7000mm 29.1000mm 32.0000mm 29.1000mm 0.2000mm 0.4000mm "clearline"]
Line[33.2000mm 30.7000mm 34.4000mm 30.7000mm 0.2000mm 0.4000mm "clearline"]
@ -8853,6 +8853,7 @@ Layer(5 "signal" "copper")
Line[41.3000mm 76.7000mm 36.3000mm 69.2000mm 0.2000mm 0.4000mm "clearline"]
Line[36.3000mm 69.2000mm 35.0000mm 65.6000mm 0.2000mm 0.4000mm "clearline"]
Line[34.4000mm 63.7000mm 34.4000mm 62.6000mm 0.2000mm 0.4000mm "clearline"]
Line[44.3000mm 75.4000mm 54.1000mm 65.8000mm 0.2000mm 0.4000mm "clearline"]
Line[49.0000mm 76.9000mm 47.2000mm 76.6000mm 0.2000mm 0.4000mm "clearline"]
Line[48.1000mm 80.7000mm 46.1000mm 77.0000mm 0.2000mm 0.4000mm "clearline"]
Line[49.4000mm 72.1000mm 59.0000mm 72.1000mm 0.2000mm 0.4000mm "clearline"]
@ -8875,7 +8876,7 @@ Layer(5 "signal" "copper")
Line[57.0000mm 26.5000mm 58.8000mm 28.5000mm 0.2000mm 0.4000mm "clearline"]
Line[53.0000mm 20.9000mm 53.8000mm 20.9000mm 0.2000mm 0.4000mm "clearline"]
Line[53.8000mm 20.9000mm 56.5000mm 22.7000mm 0.2000mm 0.4000mm "clearline"]
Line[56.5000mm 22.7000mm 56.5000mm 26.3000mm 0.2000mm 0.4000mm "clearline"]
Line[56.5000mm 22.7000mm 56.5000mm 26.4000mm 0.2000mm 0.4000mm "clearline"]
Line[53.5000mm 21.7000mm 56.0000mm 23.1000mm 0.2000mm 0.4000mm "clearline"]
Line[56.0000mm 23.1000mm 56.0000mm 26.1000mm 0.2000mm 0.4000mm "clearline"]
Line[59.7000mm 22.2000mm 58.4000mm 23.2000mm 0.2000mm 0.4000mm "clearline"]
@ -8891,10 +8892,10 @@ Layer(5 "signal" "copper")
Line[58.8000mm 28.5000mm 58.8000mm 30.7000mm 0.2000mm 0.4000mm "clearline"]
Line[55.0000mm 1000.00mil 53.3000mm 26.7000mm 0.2000mm 0.4000mm "clearline"]
Line[55.5000mm 25.7000mm 53.6000mm 27.1000mm 0.2000mm 0.4000mm "clearline"]
Line[56.0000mm 26.1000mm 54.7000mm 27.0000mm 0.2000mm 0.4000mm "clearline"]
Line[56.5000mm 26.3000mm 55.1000mm 27.3000mm 0.2000mm 0.4000mm "clearline"]
Line[55.1000mm 29.1000mm 55.1000mm 27.3000mm 0.2000mm 0.4000mm "clearline"]
Line[54.7000mm 29.5000mm 54.7000mm 27.0000mm 0.2000mm 0.4000mm "clearline"]
Line[56.0000mm 26.1000mm 54.9000mm 26.9000mm 0.2000mm 0.4000mm "clearline"]
Line[56.5000mm 26.4000mm 55.3000mm 27.3000mm 0.2000mm 0.4000mm "clearline"]
Line[55.3000mm 29.0000mm 55.3000mm 27.3000mm 0.2000mm 0.4000mm "clearline"]
Line[54.9000mm 29.4000mm 54.9000mm 26.9000mm 0.2000mm 0.4000mm "clearline"]
Line[25.5000mm 11.1000mm 29.0000mm 11.1000mm 0.2000mm 0.4000mm ""]
Line[52.9000mm 16.3000mm 46.5000mm 11.1000mm 0.2000mm 0.4000mm ""]
Line[32.5000mm 11.8000mm 30.1000mm 11.8000mm 0.2000mm 0.4000mm ""]
@ -8936,8 +8937,8 @@ Layer(5 "signal" "copper")
Line[19.5000mm 12.2000mm 18.4000mm 12.2000mm 0.2000mm 0.4000mm ""]
Line[18.4000mm 12.2000mm 17.0000mm 11.1000mm 0.2000mm 0.4000mm ""]
Line[17.0000mm 11.1000mm 13.5000mm 11.1000mm 0.2000mm 0.4000mm ""]
Line[55.1000mm 29.1000mm 56.1000mm 29.6000mm 0.2000mm 0.4000mm "clearline"]
Line[54.7000mm 29.5000mm 56.7000mm 30.4000mm 0.2000mm 0.4000mm "clearline"]
Line[55.3000mm 29.0000mm 58.1000mm 30.3000mm 0.2000mm 0.4000mm "clearline"]
Line[54.9000mm 29.4000mm 56.7000mm 30.4000mm 0.2000mm 0.4000mm "clearline"]
Line[58.8000mm 30.7000mm 57.3000mm 32.3000mm 0.2000mm 0.4000mm "clearline"]
Line[57.3000mm 32.3000mm 57.3000mm 34.0000mm 0.2000mm 0.4000mm "clearline"]
Line[59.0000mm 72.1000mm 59.7000mm 71.5000mm 0.2000mm 0.4000mm "clearline"]
@ -9016,7 +9017,7 @@ Layer(5 "signal" "copper")
Line[40.5000mm 33.5000mm 45.0000mm 32.2000mm 0.2000mm 0.4000mm "clearline"]
Line[40.1000mm 33.1000mm 44.1000mm 31.0000mm 0.2000mm 0.4000mm "clearline"]
Line[44.1000mm 31.0000mm 53.3000mm 26.7000mm 0.2000mm 0.4000mm "clearline"]
Line[54.0000mm 27.7000mm 49.3000mm 29.9000mm 0.2000mm 0.4000mm "clearline"]
Line[54.2000mm 27.5000mm 49.3000mm 29.9000mm 0.2000mm 0.4000mm "clearline"]
Line[46.0000mm 32.2000mm 43.6000mm 33.4000mm 0.2000mm 0.4000mm "clearline"]
Line[34.4000mm 62.6000mm 37.8000mm 61.5000mm 0.2000mm 0.4000mm "clearline"]
Line[33.9000mm 62.2000mm 37.7000mm 61.1000mm 0.2000mm 0.4000mm "clearline"]
@ -9111,8 +9112,6 @@ Layer(5 "signal" "copper")
Line[32.3000mm 66.8000mm 32.3000mm 64.0000mm 0.6000mm 0.4000mm "clearline"]
Line[31.2000mm 67.9000mm 32.3000mm 66.8000mm 0.6000mm 0.4000mm "clearline"]
Line[21.1500mm 67.9000mm 18.7000mm 67.6000mm 0.2000mm 0.4000mm "clearline"]
Line[57.2000mm 29.6000mm 58.1000mm 30.3000mm 0.2000mm 0.4000mm "clearline"]
Line[56.1000mm 29.6000mm 57.2000mm 29.6000mm 0.2000mm 0.4000mm "clearline"]
)
Layer(6 "bottom" "copper")
(
@ -9208,7 +9207,7 @@ Layer(6 "bottom" "copper")
Line[48.8000mm 3000.00mil 47.9000mm 77.0000mm 0.2000mm 0.4000mm "clearline"]
Line[47.9000mm 77.0000mm 47.9000mm 77.6000mm 0.2000mm 0.4000mm "clearline"]
Line[49.0000mm 76.9000mm 49.6000mm 76.7000mm 0.2000mm 0.4000mm "clearline"]
Line[46.7000mm 76.7000mm 44.3000mm 76.7000mm 0.2000mm 0.4000mm "clearline"]
Line[46.7000mm 76.7000mm 44.2000mm 76.7000mm 0.2000mm 0.4000mm "clearline"]
Line[45.5000mm 77.5000mm 43.3000mm 77.5000mm 0.2000mm 0.4000mm "clearline"]
Line[40.2000mm 77.1000mm 40.9000mm 77.1000mm 0.6000mm 0.4000mm "clearline"]
Line[40.9000mm 77.1000mm 40.9000mm 75.4000mm 0.6000mm 0.4000mm "clearline"]
@ -9319,7 +9318,7 @@ Layer(6 "bottom" "copper")
Line[14.8000mm 36.3000mm 15.4000mm 36.3000mm 0.2000mm 0.4000mm "clearline"]
Line[14.8000mm 1500.00mil 16.6000mm 1500.00mil 0.2000mm 0.4000mm "clearline"]
Line[14.8000mm 1500.00mil 13.3000mm 36.3000mm 0.2000mm 0.4000mm "clearline"]
Line[25.1000mm 57.4000mm 26.6000mm 57.4000mm 0.2000mm 0.4000mm "clearline"]
Line[1000.00mil 57.4000mm 21.0000mm 57.4000mm 0.2000mm 0.4000mm "clearline"]
Line[22.6000mm 62.0000mm 22.6000mm 60.5000mm 0.2000mm 0.4000mm "clearline"]
Line[18.2000mm 44.7000mm 18.2000mm 43.9000mm 0.2000mm 0.4000mm "clearline"]
Line[15.5000mm 43.3000mm 15.5000mm 42.2000mm 0.2000mm 0.4000mm "clearline"]
@ -9359,6 +9358,7 @@ Layer(6 "bottom" "copper")
Line[15.6000mm 60.4000mm 14.6000mm 61.3000mm 0.2000mm 0.4000mm "clearline"]
Line[20.5000mm 61.8000mm 20.5000mm 63.0000mm 0.2000mm 0.4000mm "clearline"]
Line[22.6000mm 60.5000mm 20.3000mm 60.5000mm 0.2000mm 0.4000mm "clearline"]
Line[21.0000mm 59.5000mm 21.0000mm 60.5000mm 0.2000mm 0.4000mm "clearline"]
Line[15.1000mm 64.4000mm 14.0000mm 64.4000mm 0.2000mm 0.4000mm "clearline"]
Line[14.6000mm 61.9000mm 14.6000mm 61.8000mm 0.2000mm 0.4000mm "clearline"]
Line[14.6000mm 61.9000mm 14.4000mm 61.8000mm 0.2000mm 0.4000mm "clearline"]
@ -9481,7 +9481,7 @@ Layer(6 "bottom" "copper")
Line[50.6000mm 79.5000mm 47.9000mm 79.5000mm 0.2000mm 0.4000mm "clearline"]
Line[51.0000mm 79.2000mm 50.6000mm 79.5000mm 0.2000mm 0.4000mm "clearline"]
Line[48.3000mm 72.8000mm 44.2000mm 72.8000mm 0.2000mm 0.4000mm "clearline"]
Line[44.3000mm 76.7000mm 44.3000mm 74.4000mm 0.2000mm 0.4000mm "clearline"]
Line[44.3000mm 75.4000mm 44.3000mm 74.4000mm 0.2000mm 0.4000mm "clearline"]
Line[43.3000mm 77.5000mm 43.4000mm 78.3000mm 0.2000mm 0.4000mm "clearline"]
Line[50.0000mm 78.8000mm 48.6000mm 78.8000mm 0.2000mm 0.4000mm "clearline"]
Line[43.4000mm 78.3000mm 43.4000mm 80.3000mm 0.2000mm 0.4000mm "clearline"]
@ -9938,15 +9938,11 @@ Layer(6 "bottom" "copper")
Line[1000.00mil 68.9000mm 24.4000mm 69.4000mm 0.2000mm 0.4000mm "clearline"]
Line[25.8000mm 69.2000mm 24.4000mm 70.7000mm 0.2000mm 0.4000mm "clearline"]
Line[24.5000mm 67.3000mm 23.8000mm 66.9000mm 0.2000mm 0.4000mm "clearline"]
Line[25.1000mm 57.4000mm 25.1000mm 56.1000mm 0.2000mm 0.4000mm "clearline"]
Line[23.3000mm 56.1000mm 23.3000mm 57.4000mm 0.2000mm 0.4000mm "clearline"]
Line[23.3000mm 57.4000mm 21.0000mm 57.4000mm 0.2000mm 0.4000mm "clearline"]
Line[21.0000mm 60.5000mm 21.0000mm 57.4000mm 0.2000mm 0.4000mm "clearline"]
Text[53.2000mm 74.2000mm 2 43 "POS" "clearline,onsolder"]
Text[51.9000mm 75.0000mm 3 43 "NEG" "clearline,onsolder"]
Text[31.2000mm 36.9000mm 2 93 "FORGE.BEXUS.ORG" "clearline,onsolder"]
Text[31.3000mm 33.7000mm 2 93 "THHOR CRS V02" "clearline,onsolder"]
Text[31.2000mm 35.3000mm 2 93 "2026-03-26 SiB" "clearline,onsolder"]
Text[31.3000mm 33.7000mm 2 93 "THHOR CRS V01" "clearline,onsolder"]
Text[31.2000mm 35.3000mm 2 93 "2025-12-18 SiB" "clearline,onsolder"]
Polygon("via")
(
[34.8150mm 33.0340mm] [1370.40mil 1302.00mil] [34.8013mm 33.1054mm] [1367.70mil 1316.60mil] [34.7185mm 33.4651mm]
@ -11115,6 +11111,7 @@ NetList()
Connect("U4-7")
Connect("U5-1")
Connect("U6-3")
Connect("U9-1")
Connect("U9-2")
Connect("U30-3")
Connect("XADC/C1-2")
@ -11762,6 +11759,7 @@ NetList()
Connect("D/R7-1")
Connect("D/U1-2")
Connect("D/U1-13")
Connect("R36-2")
Connect("R66-2")
Connect("XADC/C2-2")
Connect("XADC/C3-1")
@ -11955,7 +11953,6 @@ NetList()
Connect("U1-47")
Connect("U1-56")
Connect("U1-62")
Connect("U9-1")
Connect("U9-4")
Connect("XIO/C2-2")
Connect("XIO/C3-1")
@ -12032,7 +12029,6 @@ NetList()
Net("VssH" "(unknown)")
(
Connect("C36-2")
Connect("R36-2")
Connect("R38-2")
Connect("U30-2")
Connect("XB/U1-2")

View file

@ -1769,8 +1769,6 @@ T 26725 43600 5 6 1 1 0 2 1
net=Vio:4
T 26600 43600 5 8 0 1 0 5 1
value=32MHz XO53 025 UITA
T 26625 43700 5 6 0 1 0 7 1
net=Vio:1
}
C 27000 43400 1 270 0 gnd-1.sym
N 27700 43300 27700 43700 4
@ -2044,7 +2042,7 @@ footprint=C0603
T 40000 52750 5 10 1 1 90 4 1
refdes=R50
T 39850 52550 5 10 1 1 90 0 1
value=15
value=10
}
C 40600 51400 1 90 0 capacitor-1.sym
{
@ -3009,6 +3007,13 @@ value=∞Ω
T 34450 51000 5 10 1 1 0 6 1
footprint=C0805
}
C 34800 50700 1 180 0 generic-power.sym
{
T 34600 50450 5 10 0 1 180 3 1
net=Vadc:1
T 34600 50450 3 8 1 1 180 3 1
description=Vadc
}
N 34600 50700 34600 50600 4
C 38100 52400 1 90 0 resistor-2.sym
{
@ -5051,10 +5056,3 @@ device=none
T 22000 43800 5 8 1 1 0 4 1
value=TxE
}
C 34800 50700 1 180 0 generic-power.sym
{
T 34600 50450 5 10 0 1 180 3 1
net=VssH:1
T 34600 50450 3 8 1 1 180 3 1
description=VssH
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

View file

@ -1,245 +0,0 @@
test_in R52-2 R51-1 J51-1
L31/u1sk L31/C20-1 L31/R21-2 L31/R20-1
L31/q3e L31/Q3-2 L31/R4-1
L31/vcc_f1 L31/R61-2 L31/C61-1 L31/R6-1
L31/q3bias L31/Q3-1 L31/C8-2 L31/R7-2 L31/R8-1
L31/vdd_f1 L31/C62-2 L31/R62-1 L31/C8-1 L31/R4-2 L31/R8-2
L31/q2bias L31/Q2-1 L31/R6-2 L31/R7-1 L31/C7-2
L31/u1inv L31/R23-1 L31/R22-2 L31/U1-4
L31/u1ninv L31/C21-2 L31/R21-1 L31/U1-3
L31/vbias_filtered L31/C51-2 L31/R51-1 L31/R1-2
L31/vcc_u1 L31/R13-1 L31/U1-5 L31/C13-1
L31/vss_u1 L31/R12-2 L31/U1-2 L31/C12-2
L31/vfet_q1 L31/C3-2 L31/R31-1 L31/R3-2
L31/q1out L31/Q2-2 L31/R3-1 L31/Q1-2
L31/q2_out L31/R2-2 L31/R20-2 L31/Q2-3 L31/Q3-3 L31/C2-2
L31/fet_gate L31/Q1-3 L31/C11-2 L31/C2-1 L31/R2-1 L31/C1-2
out31 L31/C20-2 L31/R22-1 L31/U1-1 R1-1 R31-1
in31 L31/R1-1 L31/C1-1 J31-1
L33/u1sk L33/C20-1 L33/R21-2 L33/R20-1
L33/q3e L33/Q3-2 L33/R4-1
L33/vcc_f1 L33/R61-2 L33/C61-1 L33/R6-1
L33/q3bias L33/Q3-1 L33/C8-2 L33/R7-2 L33/R8-1
L33/vdd_f1 L33/C62-2 L33/R62-1 L33/C8-1 L33/R4-2 L33/R8-2
L33/q2bias L33/Q2-1 L33/R6-2 L33/R7-1 L33/C7-2
L33/u1inv L33/R23-1 L33/R22-2 L33/U1-4
L33/u1ninv L33/C21-2 L33/R21-1 L33/U1-3
L33/vbias_filtered L33/C51-2 L33/R51-1 L33/R1-2
L33/vcc_u1 L33/R13-1 L33/U1-5 L33/C13-1
L33/vss_u1 L33/R12-2 L33/U1-2 L33/C12-2
L33/vfet_q1 L33/C3-2 L33/R31-1 L33/R3-2
L33/q1out L33/Q2-2 L33/R3-1 L33/Q1-2
L33/q2_out L33/R2-2 L33/R20-2 L33/Q2-3 L33/Q3-3 L33/C2-2
L33/fet_gate L33/Q1-3 L33/C11-2 L33/C2-1 L33/R2-1 L33/C1-2
out33 L33/C20-2 L33/R22-1 L33/U1-1 R2-1 R33-1
in33 L33/R1-1 L33/C1-1 J33-1
L35/u1sk L35/C20-1 L35/R21-2 L35/R20-1
L35/q3e L35/Q3-2 L35/R4-1
L35/vcc_f1 L35/R61-2 L35/C61-1 L35/R6-1
L35/q3bias L35/Q3-1 L35/C8-2 L35/R7-2 L35/R8-1
L35/vdd_f1 L35/C62-2 L35/R62-1 L35/C8-1 L35/R4-2 L35/R8-2
L35/q2bias L35/Q2-1 L35/R6-2 L35/R7-1 L35/C7-2
L35/u1inv L35/R23-1 L35/R22-2 L35/U1-4
L35/u1ninv L35/C21-2 L35/R21-1 L35/U1-3
L35/vbias_filtered L35/C51-2 L35/R51-1 L35/R1-2
L35/vcc_u1 L35/R13-1 L35/U1-5 L35/C13-1
L35/vss_u1 L35/R12-2 L35/U1-2 L35/C12-2
L35/vfet_q1 L35/C3-2 L35/R31-1 L35/R3-2
L35/q1out L35/Q2-2 L35/R3-1 L35/Q1-2
L35/q2_out L35/R2-2 L35/R20-2 L35/Q2-3 L35/Q3-3 L35/C2-2
L35/fet_gate L35/Q1-3 L35/C11-2 L35/C2-1 L35/R2-1 L35/C1-2
out35 L35/C20-2 L35/R22-1 L35/U1-1 R3-1 R35-1
in35 L35/R1-1 L35/C1-1 J35-1
L37/u1sk L37/C20-1 L37/R21-2 L37/R20-1
L37/q3e L37/Q3-2 L37/R4-1
L37/vcc_f1 L37/R61-2 L37/C61-1 L37/R6-1
L37/q3bias L37/Q3-1 L37/C8-2 L37/R7-2 L37/R8-1
L37/vdd_f1 L37/C62-2 L37/R62-1 L37/C8-1 L37/R4-2 L37/R8-2
L37/q2bias L37/Q2-1 L37/R6-2 L37/R7-1 L37/C7-2
L37/u1inv L37/R23-1 L37/R22-2 L37/U1-4
L37/u1ninv L37/C21-2 L37/R21-1 L37/U1-3
L37/vbias_filtered L37/C51-2 L37/R51-1 L37/R1-2
L37/vcc_u1 L37/R13-1 L37/U1-5 L37/C13-1
L37/vss_u1 L37/R12-2 L37/U1-2 L37/C12-2
L37/vfet_q1 L37/C3-2 L37/R31-1 L37/R3-2
L37/q1out L37/Q2-2 L37/R3-1 L37/Q1-2
L37/q2_out L37/R2-2 L37/R20-2 L37/Q2-3 L37/Q3-3 L37/C2-2
L37/fet_gate L37/Q1-3 L37/C11-2 L37/C2-1 L37/R2-1 L37/C1-2
out37 L37/C20-2 L37/R22-1 L37/U1-1 R4-1 R37-1
in37 L37/R1-1 L37/C1-1 J37-1
L39/u1sk L39/C20-1 L39/R21-2 L39/R20-1
L39/q3e L39/Q3-2 L39/R4-1
L39/vcc_f1 L39/R61-2 L39/C61-1 L39/R6-1
L39/q3bias L39/Q3-1 L39/C8-2 L39/R7-2 L39/R8-1
L39/vdd_f1 L39/C62-2 L39/R62-1 L39/C8-1 L39/R4-2 L39/R8-2
L39/q2bias L39/Q2-1 L39/R6-2 L39/R7-1 L39/C7-2
L39/u1inv L39/R23-1 L39/R22-2 L39/U1-4
L39/u1ninv L39/C21-2 L39/R21-1 L39/U1-3
L39/vbias_filtered L39/C51-2 L39/R51-1 L39/R1-2
L39/vcc_u1 L39/R13-1 L39/U1-5 L39/C13-1
L39/vss_u1 L39/R12-2 L39/U1-2 L39/C12-2
L39/vfet_q1 L39/C3-2 L39/R31-1 L39/R3-2
L39/q1out L39/Q2-2 L39/R3-1 L39/Q1-2
L39/q2_out L39/R2-2 L39/R20-2 L39/Q2-3 L39/Q3-3 L39/C2-2
L39/fet_gate L39/Q1-3 L39/C11-2 L39/C2-1 L39/R2-1 L39/C1-2
out39 L39/C20-2 L39/R22-1 L39/U1-1 R5-1 R39-1
in39 L39/R1-1 L39/C1-1 J39-1
L41/u1sk L41/C20-1 L41/R21-2 L41/R20-1
L41/q3e L41/Q3-2 L41/R4-1
L41/vcc_f1 L41/R61-2 L41/C61-1 L41/R6-1
L41/q3bias L41/Q3-1 L41/C8-2 L41/R7-2 L41/R8-1
L41/vdd_f1 L41/C62-2 L41/R62-1 L41/C8-1 L41/R4-2 L41/R8-2
L41/q2bias L41/Q2-1 L41/R6-2 L41/R7-1 L41/C7-2
L41/u1inv L41/R23-1 L41/R22-2 L41/U1-4
L41/u1ninv L41/C21-2 L41/R21-1 L41/U1-3
L41/vbias_filtered L41/C51-2 L41/R51-1 L41/R1-2
L41/vcc_u1 L41/R13-1 L41/U1-5 L41/C13-1
L41/vss_u1 L41/R12-2 L41/U1-2 L41/C12-2
L41/vfet_q1 L41/C3-2 L41/R31-1 L41/R3-2
L41/q1out L41/Q2-2 L41/R3-1 L41/Q1-2
L41/q2_out L41/R2-2 L41/R20-2 L41/Q2-3 L41/Q3-3 L41/C2-2
L41/fet_gate L41/Q1-3 L41/C11-2 L41/C2-1 L41/R2-1 L41/C1-2
out41 L41/C20-2 L41/R22-1 L41/U1-1 R6-1 R41-1
in41 L41/R1-1 L41/C1-1 J41-1
L32/u1sk L32/C20-1 L32/R21-2 L32/R20-1
L32/q3e L32/Q3-2 L32/R4-1
L32/vcc_f1 L32/R61-2 L32/C61-1 L32/R6-1
L32/q3bias L32/Q3-1 L32/C8-2 L32/R7-2 L32/R8-1
L32/vdd_f1 L32/C62-2 L32/R62-1 L32/C8-1 L32/R4-2 L32/R8-2
L32/q2bias L32/Q2-1 L32/R6-2 L32/R7-1 L32/C7-2
L32/u1inv L32/R23-1 L32/R22-2 L32/U1-4
L32/u1ninv L32/C21-2 L32/R21-1 L32/U1-3
L32/vbias_filtered L32/C51-2 L32/R51-1 L32/R1-2
L32/vcc_u1 L32/R13-1 L32/U1-5 L32/C13-1
L32/vss_u1 L32/R12-2 L32/U1-2 L32/C12-2
L32/vfet_q1 L32/C3-2 L32/R31-1 L32/R3-2
L32/q1out L32/Q2-2 L32/R3-1 L32/Q1-2
L32/q2_out L32/R2-2 L32/R20-2 L32/Q2-3 L32/Q3-3 L32/C2-2
L32/fet_gate L32/Q1-3 L32/C11-2 L32/C2-1 L32/R2-1 L32/C1-2
out32 L32/C20-2 L32/R22-1 L32/U1-1 R32-1
in32 L32/R1-1 L32/C1-1 J32-1
L34/u1sk L34/C20-1 L34/R21-2 L34/R20-1
L34/q3e L34/Q3-2 L34/R4-1
L34/vcc_f1 L34/R61-2 L34/C61-1 L34/R6-1
L34/q3bias L34/Q3-1 L34/C8-2 L34/R7-2 L34/R8-1
L34/vdd_f1 L34/C62-2 L34/R62-1 L34/C8-1 L34/R4-2 L34/R8-2
L34/q2bias L34/Q2-1 L34/R6-2 L34/R7-1 L34/C7-2
L34/u1inv L34/R23-1 L34/R22-2 L34/U1-4
L34/u1ninv L34/C21-2 L34/R21-1 L34/U1-3
L34/vbias_filtered L34/C51-2 L34/R51-1 L34/R1-2
L34/vcc_u1 L34/R13-1 L34/U1-5 L34/C13-1
L34/vss_u1 L34/R12-2 L34/U1-2 L34/C12-2
L34/vfet_q1 L34/C3-2 L34/R31-1 L34/R3-2
L34/q1out L34/Q2-2 L34/R3-1 L34/Q1-2
L34/q2_out L34/R2-2 L34/R20-2 L34/Q2-3 L34/Q3-3 L34/C2-2
L34/fet_gate L34/Q1-3 L34/C11-2 L34/C2-1 L34/R2-1 L34/C1-2
out34 L34/C20-2 L34/R22-1 L34/U1-1 R34-1
in34 L34/R1-1 L34/C1-1 J34-1
L36/u1sk L36/C20-1 L36/R21-2 L36/R20-1
L36/q3e L36/Q3-2 L36/R4-1
L36/vcc_f1 L36/R61-2 L36/C61-1 L36/R6-1
L36/q3bias L36/Q3-1 L36/C8-2 L36/R7-2 L36/R8-1
L36/vdd_f1 L36/C62-2 L36/R62-1 L36/C8-1 L36/R4-2 L36/R8-2
L36/q2bias L36/Q2-1 L36/R6-2 L36/R7-1 L36/C7-2
L36/u1inv L36/R23-1 L36/R22-2 L36/U1-4
L36/u1ninv L36/C21-2 L36/R21-1 L36/U1-3
L36/vbias_filtered L36/C51-2 L36/R51-1 L36/R1-2
L36/vcc_u1 L36/R13-1 L36/U1-5 L36/C13-1
L36/vss_u1 L36/R12-2 L36/U1-2 L36/C12-2
L36/vfet_q1 L36/C3-2 L36/R31-1 L36/R3-2
L36/q1out L36/Q2-2 L36/R3-1 L36/Q1-2
L36/q2_out L36/R2-2 L36/R20-2 L36/Q2-3 L36/Q3-3 L36/C2-2
L36/fet_gate L36/Q1-3 L36/C11-2 L36/C2-1 L36/R2-1 L36/C1-2
out36 L36/C20-2 L36/R22-1 L36/U1-1 R36-1
in36 L36/R1-1 L36/C1-1 J36-1
L38/u1sk L38/C20-1 L38/R21-2 L38/R20-1
L38/q3e L38/Q3-2 L38/R4-1
L38/vcc_f1 L38/R61-2 L38/C61-1 L38/R6-1
L38/q3bias L38/Q3-1 L38/C8-2 L38/R7-2 L38/R8-1
L38/vdd_f1 L38/C62-2 L38/R62-1 L38/C8-1 L38/R4-2 L38/R8-2
L38/q2bias L38/Q2-1 L38/R6-2 L38/R7-1 L38/C7-2
L38/u1inv L38/R23-1 L38/R22-2 L38/U1-4
L38/u1ninv L38/C21-2 L38/R21-1 L38/U1-3
L38/vbias_filtered L38/C51-2 L38/R51-1 L38/R1-2
L38/vcc_u1 L38/R13-1 L38/U1-5 L38/C13-1
L38/vss_u1 L38/R12-2 L38/U1-2 L38/C12-2
L38/vfet_q1 L38/C3-2 L38/R31-1 L38/R3-2
L38/q1out L38/Q2-2 L38/R3-1 L38/Q1-2
L38/q2_out L38/R2-2 L38/R20-2 L38/Q2-3 L38/Q3-3 L38/C2-2
L38/fet_gate L38/Q1-3 L38/C11-2 L38/C2-1 L38/R2-1 L38/C1-2
out38 L38/C20-2 L38/R22-1 L38/U1-1 R38-1
in38 L38/R1-1 L38/C1-1 J38-1
L40/u1sk L40/C20-1 L40/R21-2 L40/R20-1
L40/q3e L40/Q3-2 L40/R4-1
L40/vcc_f1 L40/R61-2 L40/C61-1 L40/R6-1
L40/q3bias L40/Q3-1 L40/C8-2 L40/R7-2 L40/R8-1
L40/vdd_f1 L40/C62-2 L40/R62-1 L40/C8-1 L40/R4-2 L40/R8-2
L40/q2bias L40/Q2-1 L40/R6-2 L40/R7-1 L40/C7-2
L40/u1inv L40/R23-1 L40/R22-2 L40/U1-4
L40/u1ninv L40/C21-2 L40/R21-1 L40/U1-3
L40/vbias_filtered L40/C51-2 L40/R51-1 L40/R1-2
L40/vcc_u1 L40/R13-1 L40/U1-5 L40/C13-1
L40/vss_u1 L40/R12-2 L40/U1-2 L40/C12-2
L40/vfet_q1 L40/C3-2 L40/R31-1 L40/R3-2
L40/q1out L40/Q2-2 L40/R3-1 L40/Q1-2
L40/q2_out L40/R2-2 L40/R20-2 L40/Q2-3 L40/Q3-3 L40/C2-2
L40/fet_gate L40/Q1-3 L40/C11-2 L40/C2-1 L40/R2-1 L40/C1-2
out40 L40/C20-2 L40/R22-1 L40/U1-1 R40-1
in40 L40/R1-1 L40/C1-1 J40-1
guard1 J11-1 C11-1 R11-1
guard2 J12-1 C12-1 R12-1
guard3 J13-1 C13-1 R13-1
guard4 J14-1 C14-1 R14-1
guard5 J15-1 C15-1 R15-1
guard6 J16-1 C16-1 R16-1
L42/u1sk L42/C20-1 L42/R21-2 L42/R20-1
L42/q3e L42/Q3-2 L42/R4-1
L42/vcc_f1 L42/R61-2 L42/C61-1 L42/R6-1
L42/q3bias L42/Q3-1 L42/C8-2 L42/R7-2 L42/R8-1
L42/vdd_f1 L42/C62-2 L42/R62-1 L42/C8-1 L42/R4-2 L42/R8-2
L42/q2bias L42/Q2-1 L42/R6-2 L42/R7-1 L42/C7-2
L42/u1inv L42/R23-1 L42/R22-2 L42/U1-4
L42/u1ninv L42/C21-2 L42/R21-1 L42/U1-3
L42/vbias_filtered L42/C51-2 L42/R51-1 L42/R1-2
L42/vcc_u1 L42/R13-1 L42/U1-5 L42/C13-1
L42/vss_u1 L42/R12-2 L42/U1-2 L42/C12-2
L42/vfet_q1 L42/C3-2 L42/R31-1 L42/R3-2
L42/q1out L42/Q2-2 L42/R3-1 L42/Q1-2
L42/q2_out L42/R2-2 L42/R20-2 L42/Q2-3 L42/Q3-3 L42/C2-2
L42/fet_gate L42/Q1-3 L42/C11-2 L42/C2-1 L42/R2-1 L42/C1-2
TEST R51-2 L31/C11-1 L33/C11-1 L35/C11-1 L37/C11-1 L39/C11-1 L41/C11-1 L32/C11-1 L34/C11-1 L36/C11-1 L38/C11-1 L40/C11-1 L42/C11-1
out42 L42/C20-2 L42/R22-1 L42/U1-1 R42-1
in42 L42/R1-1 L42/C1-1 J42-1
SA1 R32-2 R1-2 CONN1-14
SA2 R31-2 CONN1-15
SC0 R42-2 R6-2 CONN1-16
SB2 R41-2 CONN1-17
SB0 R40-2 R5-2 CONN1-18
SB1 R39-2 CONN1-19
Vbias L31/C52-1 L31/R51-2 L33/C52-1 L33/R51-2 L35/C52-1 L35/R51-2 L37/C52-1 L37/R51-2 L39/C52-1 L39/R51-2 L41/C52-1 L41/R51-2 L32/C52-1 L32/R51-2 L34/C52-1 L34/R51-2 L36/C52-1 L36/R51-2 L38/C52-1 L38/R51-2 \
L40/C52-1 L40/R51-2 R11-2 R12-2 R13-2 R14-2 R15-2 R16-2 L42/C52-1 L42/R51-2 CONN1-1
Vfet C21-1 C24-1 C27-1 L31/R61-1 L31/R31-2 L31/C31-2 L33/R61-1 L33/R31-2 L33/C31-2 L35/R61-1 L35/R31-2 L35/C31-2 L37/R61-1 L37/R31-2 L37/C31-2 L39/R61-1 L39/R31-2 L39/C31-2 L41/R61-1 L41/R31-2 L41/C31-2 \
L32/R61-1 L32/R31-2 L32/C31-2 L34/R61-1 L34/R31-2 L34/C31-2 L36/R61-1 L36/R31-2 L36/C31-2 L38/R61-1 L38/R31-2 L38/C31-2 L40/R61-1 L40/R31-2 L40/C31-2 C30-1 C33-1 C36-1 L42/R61-1 L42/R31-2 L42/C31-2 \
CONN1-2 CONN1-3
VccP C22-1 C25-1 C28-1 L31/R13-2 L33/R13-2 L35/R13-2 L37/R13-2 L39/R13-2 L41/R13-2 L32/R13-2 L34/R13-2 L36/R13-2 L38/R13-2 L40/R13-2 C31-1 C34-1 C37-1 L42/R13-2 CONN1-4
VssP C23-2 C26-2 C29-2 L31/R62-2 L31/R12-1 L33/R62-2 L33/R12-1 L35/R62-2 L35/R12-1 L37/R62-2 L37/R12-1 L39/R62-2 L39/R12-1 L41/R62-2 L41/R12-1 L32/R62-2 L32/R12-1 L34/R62-2 L34/R12-1 L36/R62-2 L36/R12-1 \
L38/R62-2 L38/R12-1 L40/R62-2 L40/R12-1 C32-2 C35-2 C38-2 L42/R62-2 L42/R12-1 CONN1-5
HKC7 J19-1 C19-2 CONN1-6
HKA7 J18-1 C18-2 CONN1-25
HKB7 J17-1 C17-2 CONN1-7
SC1 R38-2 R4-2 CONN1-8
SD2 R37-2 CONN1-9
SC2 R36-2 R3-2 CONN1-10
SD1 R35-2 CONN1-11
SD0 R34-2 R2-2 CONN1-12
GND R52-1 J51-2 C22-2 C21-2 C23-1 C25-2 C24-2 C26-1 C28-2 C27-2 C29-1 J19-2 J18-2 J17-2 J16-2 J15-2 J14-2 J13-2 J12-2 J11-2 J42-2 J40-2 J38-2 J36-2 J34-2 J32-2 J41-2 J39-2 J37-2 J35-2 J33-2 J31-2 \
L31/C21-1 L31/R23-2 L31/C52-2 L31/C61-2 L31/C62-1 L31/C7-1 L31/C3-1 L31/C51-1 L31/C13-2 L31/C12-1 L31/Q1-1 L31/C31-1 L33/C21-1 L33/R23-2 L33/C52-2 L33/C61-2 L33/C62-1 L33/C7-1 L33/C3-1 L33/C51-1 \
L33/C13-2 L33/C12-1 L33/Q1-1 L33/C31-1 L35/C21-1 L35/R23-2 L35/C52-2 L35/C61-2 L35/C62-1 L35/C7-1 L35/C3-1 L35/C51-1 L35/C13-2 L35/C12-1 L35/Q1-1 L35/C31-1 L37/C21-1 L37/R23-2 L37/C52-2 L37/C61-2 \
L37/C62-1 L37/C7-1 L37/C3-1 L37/C51-1 L37/C13-2 L37/C12-1 L37/Q1-1 L37/C31-1 L39/C21-1 L39/R23-2 L39/C52-2 L39/C61-2 L39/C62-1 L39/C7-1 L39/C3-1 L39/C51-1 L39/C13-2 L39/C12-1 L39/Q1-1 L39/C31-1 \
L41/C21-1 L41/R23-2 L41/C52-2 L41/C61-2 L41/C62-1 L41/C7-1 L41/C3-1 L41/C51-1 L41/C13-2 L41/C12-1 L41/Q1-1 L41/C31-1 L32/C21-1 L32/R23-2 L32/C52-2 L32/C61-2 L32/C62-1 L32/C7-1 L32/C3-1 L32/C51-1 \
L32/C13-2 L32/C12-1 L32/Q1-1 L32/C31-1 L34/C21-1 L34/R23-2 L34/C52-2 L34/C61-2 L34/C62-1 L34/C7-1 L34/C3-1 L34/C51-1 L34/C13-2 L34/C12-1 L34/Q1-1 L34/C31-1 L36/C21-1 L36/R23-2 L36/C52-2 L36/C61-2 \
L36/C62-1 L36/C7-1 L36/C3-1 L36/C51-1 L36/C13-2 L36/C12-1 L36/Q1-1 L36/C31-1 L38/C21-1 L38/R23-2 L38/C52-2 L38/C61-2 L38/C62-1 L38/C7-1 L38/C3-1 L38/C51-1 L38/C13-2 L38/C12-1 L38/Q1-1 L38/C31-1 \
L40/C21-1 L40/R23-2 L40/C52-2 L40/C61-2 L40/C62-1 L40/C7-1 L40/C3-1 L40/C51-1 L40/C13-2 L40/C12-1 L40/Q1-1 L40/C31-1 C11-2 C12-2 C13-2 C14-2 C15-2 C16-2 C31-2 C30-2 C32-1 C34-2 C33-2 C35-1 C37-2 \
C36-2 C38-1 C17-1 C18-1 C19-1 L42/C21-1 L42/R23-2 L42/C52-2 L42/C61-2 L42/C62-1 L42/C7-1 L42/C3-1 L42/C51-1 L42/C13-2 L42/C12-1 L42/Q1-1 L42/C31-1 BOARD-1 CONN1-0 CONN1-32 CONN1-33 CONN1-34 CONN1-35 \
CONN1-36 CONN1-37 CONN1-20 CONN1-21 CONN1-22 CONN1-23 CONN1-24 CONN1-26 CONN1-27 CONN1-28 CONN1-29 CONN1-30 CONN1-31
SA0 R33-2 CONN1-13

File diff suppressed because it is too large Load diff

View file

@ -1,5 +0,0 @@
schematics thhor_csa.sch
output-name thhor_csa
elements-dir ./fp
use-files
skip-m4

File diff suppressed because it is too large Load diff