14 Commits
Author SHA1 Message Date
etwenandClaude Opus 5 1a06367ade docs: Record V1.1.7 in Script A's history, and update CLAUDE / ARCHITECTURE
Script A's Version History gains the reboot-cycle macro, the Script B timeout
fix, the tmp/ rule and the stress knobs.

CLAUDE.md: current status to V1.1.7, a Script 5 paragraph, tmp/ in the folder
list, and two gotchas rewritten - the timeout one now covers both restore
positions, and --runtime is described as the job's overall limit rather than
"a 24 hour ceiling". Dropped the stale "TR518 not scripted yet" line.

ARCHITECTURE.md: Script 5 in the tree and in Key Features, tmp/ in the tree,
constraint 14 extended with "copy the :label along with the goto", and two
known issues added for the parts not yet run on hardware.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-04 22:44:21 +08:00
etwenandClaude Opus 5 1fbdcc23d6 feat(reboot): Add a standalone reboot-cycle macro
5_Blanton_Script_Reboot_Cycle.ttl loops: login -> sudo -i -> date -s -> fan
speed -> wait_init -> Check Pt1..Pt13 -> show uptime -> reboot -> wait for the
next boot. The cycle number is printed in the banner of every round.

Like Script 4 it is standalone: it does not chain to A -> B -> C and does not
use hw-test-session. Every cycle is a fresh boot, so there is nothing to carry
over and nothing to tear down.

The cdc_ncm probe was copied out of Script B without its :skip_ping label, so
'goto skip_ping' had no target. Tera Term does not check labels at load time -
it raises the error only when it actually jumps, i.e. only when the NCM
interface is missing, which is exactly the run where something is already
wrong. The label is now there, and timeout is restored BEFORE the branch so
one line covers both paths: the ping block waits on a 'sleep 10', already two
thirds of the 15 s cap on a loaded DUT.

Dmesg_i2c and PCIE Error Counters both announced themselves as Check Pt12;
the second is now Pt13.

Not verified on hardware yet. Two things to confirm on the bench: that
wait "Booting in blind mode" really appears in this build's boot output (it
has no timeout guard, so a changed string waits forever), and that re-running
bmc-first-enroll every cycle is safe.

Also ignore tmp/ - scripts not yet run on a DUT stage there, so an unverified
script cannot reach the publish bundle where the tester cannot tell it apart
from the rest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-04 22:44:21 +08:00
etwenandClaude Opus 5 0d2faef565 feat(scriptb): Move the stress durations into config.ttl, and restore the timeout sooner
SSD_RUNTIME / SSD_COUNT and USB_RUNTIME / USB_COUNT replace the values that
were hard-coded in Script B, so a site changes them in one place. COUNT is
passed straight through as --passes.

--runtime is the job's OVERALL limit, not a per-pass one: qfx5252-stress-*
stops after RUNTIME seconds whatever --passes says. RUNTIME 600 is a ten
minute stress, not 600 x COUNT. A 24 hour soak needs RUNTIME 86400.

Also restore timeout = 0 on the cdc_ncm success path. It was restored only at
:skip_ping, which the success path reaches several waits later - until then
every wait gave up after 15 s instead of blocking, and a wait that returns
without eating the prompt puts the macro a beat ahead of the DUT.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-04 22:44:05 +08:00
etwenandClaude Opus 5 a9c56ee1d4 feat(multiphase): Add a way back from a margin without a power cycle
blanton_multiphase_margin.sh gains 'normal', which returns all 38 rails
to their nominal set point from tools/Multiphase_Normal.txt. Same rails,
same per-rail reporting, same -u 0|1|all as the margin profiles.

Until now the tool could apply high3/low3/comboA/comboB and commit with
save, but had no way to undo. That left a power cycle as the only exit -
and worse, a save run while still margined would have written the offsets
into NVM, which a power cycle does not undo either.

Emitted commands were diffed against the source file: argv identical.

The nominal labels in the source carry extra text ("0.900V (nominal)",
"0.8V(nominal) , 0.8591V with load line"); the per-rail line prints just
the voltage so the column matches the other profiles. The load-line note
is kept as a comment above the data block, because reading 0.859 V back
from TH6_CORE after 'normal' looks like a failed write and is not one.

Script A -> V1.1.7.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-04 09:23:25 +08:00
etwenandClaude Opus 5 78a8f641c9 fix(scriptc): Capture the BMC USB service log to a file, not the console
journalctl now runs with -o short-iso into log/bmc_usb_net.log and is
copied into the job directory with the other monitor logs. rm -f first so
the file covers this run only, and the ISO timestamps line up with
mgmt_ping.log and nfc_poll.log for cross-referencing.

The cost, recorded rather than glossed over: it is no longer echoed to
the console, so the USB copy is the only copy. That cp return value is
not checked - the same shape as the nfc_polling.log filename bug, which
failed silently and was only noticed back at the desk with a job archive
missing a file.

Folded into V1.1.6 rather than bumping: the tag has not moved on and this
is the same delivery.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-02 21:44:06 +08:00
etwenandClaude Opus 5 25e1ce0068 fix(pdb): Read the bricks on the pages the datasheet actually specifies
Every PDB reading came back NA, and the cause was a base error. The four
ADPM12200 bricks put each measurement on its own PMBus PAGE, written
before the read. The bring-up spreadsheet listed those page numbers in
decimal but with an 0x prefix:

    Vin  PAGE 9  -> it said 0x00   (0x09)
    Iin  PAGE 10 -> it said 0x10   (0x0A)
    Vout PAGE 2  -> it said 0x02    correct by luck
    Iout PAGE 14 -> it said 0x14   (0x0E)
    Temp PAGE 18 -> it said 0x18   (0x12)

Only Vout worked, because 2 reads the same in either base. Hence Iin and
Iout answering 0xFFFF, Temp answering 0x0000, and a Vin scale factor
having to be invented to make 50 V appear out of a page-0 register.

pwr_brick.sh reads all five bricks with the right pages and the
datasheet's DIRECT equation, X = (1/m)(Y x 10^-R - b): voltage Y x 8 mV,
current Y x 0.04 A, temperature Y x 0.01 C. Cross-checked rather than
assumed - READ_VOUT 0x05D4 decodes to 11936 mV, exactly what
'show platform voltage' reports for that rail through a separate sensor
path. The datasheet is committed alongside so the numbers are checkable.

Left flagged: Table 3 does not list READ_VIN or READ_IIN. They borrow the
voltage and current coefficients here, which is consistent with a ~50 V
input but is not something the datasheet states.

Each value is re-read until it passes three checks: not 0xFFFF, not
0x0000, and inside a plausibility window. The window is the one that
matters - this bus corrupts the HIGH BYTE only, which turns 11.98 V into
32.00 V. Positive, plausible in magnitude, and invisible to any all-ones
filter. 0x0000 is rejected for the mirror-image reason: on the
temperature register it decodes to a believable 0 C.

Adds comboA/comboB margin profiles per board. comboB is comboA with every
direction flipped, so the pair covers each rail high and low while its
neighbours sit the other way. NC channels stay nominal in both - there is
nothing to margin on an unused rail.

Script C re-enables the BMC USB journalctl dump, which had been commented
out, so that service log now reaches the master log.

Script A -> V1.1.6.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-02 16:35:45 +08:00
etwenandClaude Opus 5 215fed6e95 fix(stress): Keep the SSD and USB jobs alive for the whole soak
qfx5252-stress-usb was started with --runtime 60. It finished a minute
into an overnight run and the USB path sat idle for the rest of the
night - nothing failed, nothing said so, and the log looked complete.
SSD had the same shape at --runtime 3600. Both are now 86400, and the
BMC DDR memtester drops its loop count so it runs until stopped.

86400 is 24h, not forever. Past that SSD and USB die quietly and the
only clue is the shorter bgctl list Script B already prints each round.
Said so in the version history, the release notes and ARCHITECTURE.

Adds blanton_multiphase_margin.sh: the multiphase controllers on both
switch boards over the native i2c buses (SWB0 on i2c-13/15, SWB1 on
-14/-16), 19 rails each. high3/low3/comboA/comboB set voltages and print
one line per rail; save commits them and prints Multiphase Save All,
because that list has no per-rail mapping to report against.

Two hazards it carries: save is STORE_USER_ALL and permanent, and these
are NOT the LTC2980s margin.sh drives - the two tools reach the same
rails from opposite sides with no interlock between them.

The emitted commands were diffed against tools/Multiphase_*.txt: argv
identical for all five. The rail-to-netname mapping was cross-checked
against the bus numbers rather than trusted by line position - blocks
1..19 are all bus 13/15 and 20..38 all 14/16, matching the SWB0/SWB1
split of Multiphase_Netname.

blanton_traffic_linespeed v0.7.0 appends PatternRandom=yes to every tx
including ce0, and the defaults become tx 200 length=324. A fixed
pattern can sit on a benign bit sequence for a whole run; a changing one
is what exposes a weak lane. -r no forces fixed, -r "" omits the
argument for an SDK that will not take it. Bytes per burst went 51200 ->
64800, so absolute counter totals do not carry across this build - the
pair cross-check that decides PASS/FAIL does.

Script A -> V1.1.5.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-01 11:04:45 +08:00
etwenandClaude Opus 5 db44f72352 feat(thermal): Add a standalone thermal/safety run, and move margin out of the soak loop
4_Blanton_Script_thermal_safety.ttl brings the DUT up the way Script A
does, then loads it - mlucas-avx2 -cpu 0:15 in the background plus
blanton_tr518.sh start - and samples platform data and both switch
boards' rail power every minute. Power per rail under sustained full
load, over hours, is the whole point of it.

It is standalone: nothing starts it, it starts nothing, and it must not
share a DUT with Script B because both take over the cd ports.

It also has no teardown. When you interrupt it the unit is still in
port cd lb=mac / l2 learn off / test mode nr=yes and mlucas is still
running, and show interfaces status does not reveal any of that. Called
out in the version history, the release notes, CLAUDE.md gotchas and the
ARCHITECTURE future-work list, because whoever uses the box next will not
find out on their own.

Script B's per-round loop drops the margin scan. The loop is meant to be
a quick minute-by-minute sample and margin_status_all.sh walks nine
LTC2980s over I2C, which dominated the round. Script C takes it instead,
once, before show uptime. The trade-off is real: margin drift DURING the
soak is no longer visible, only a start and an end reading. Documented
rather than glossed over, with a suggestion (scan every N rounds) if it
needs to come back.

Script C also sends exit and waits for "Script done" before
hw-test-session finish, so finish runs in the login shell rather than
inside the session it is closing.

Adds docs/Blanton_Test_Flow.drawio: all four scripts side by side, with
the config flags that change each step marked, Script B's one real goto
drawn, and the A->B->C handoffs shown as the manual steps they are.

The new script arrived LF-only while every other .ttl is CRLF and
.gitattributes marks *.ttl as -text, so what is committed is exactly what
Tera Term reads. Converted.

Script A -> V1.1.4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-31 22:19:38 +08:00
etwenandClaude Opus 5 9cc41f6fbd fix(margin): Reference VNOM to what the rails run at, and split profiles per CONN
86 of the 144 margin channels moved up +0.8% .. +2.5% to the measured
median for this platform (3.3 -> 3.38, 0.9 -> 0.915, 0.8 -> 0.82, ...).

That is not a display change. VNOM is the denominator of margin_status'
deviation %, and it is also the basis margin_set derives high/low/OV/UV
from - so both the number you read and the voltage you apply move with
it. A rail steady at 0.756 V used to read +0.80% against a nominal 0.75
and now reads 0.00%. Margin logs from before and after cannot be
compared: the reference moved, the hardware did not.

comboA/comboB are replaced by combo_SWB_CONN13..16_{high,low}. The
per-channel percentages are positional, so they follow the rails of one
specific board - applying a CONN13 profile to a CONN16 margins the wrong
rails and nothing detects it. SWB0 and SWB1 share a profile per CONN
because their rails are identical.

Fixes two things the deletion broke:
  - margin_apply_profile_all.sh still named comboA for all nine boards,
    which would now stop at "Profile not found" nine times over. It names
    the matching per-CONN profile instead, with CB on the generic
    combo_high3, and a note that the low pass is _high -> _low.
  - docs/LTC2980_channel_map.csv is generated from settings/*.conf, so
    all 86 changed rails were stale in it. Regenerated.

The eight new profiles also still carried comboA's header comment
("alternating high/low"), which describes neither what they contain nor
what they are for.

Script A -> V1.1.3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-30 22:13:43 +08:00
etwenandClaude Opus 5 bc2b529c3a feat(nfc): Poll the NFC tag through the soak instead of sampling it once
nfc_polling.sh wraps blantons_nfc_validate.py in a background loop and
keeps score: start/stop/status/tail/report/clear/fg. Script A takes a
30s baseline, Script B starts the poll for the soak, Script C stops it
with the other monitors and reports.

report only reads the log, so it can be run mid-soak without disturbing
anything - and it says RUNNING so a snapshot is not read as the final
answer. Each round appends a machine-readable RESULT line, which keeps
the tally independent of the tool's wording.

ERROR is counted apart from FAIL. A round where the tool printed neither
[PASS] nor [FAIL] - crashed, missing, hung past the timeout - measured
nothing, and that is a different fault from a tag that would not read.
Rolling them together hides whichever one you are not looking for.

Two habits from earlier bugs are baked in: tail does not follow (tail -f
never returns and a macro waiting on the prompt hangs there), and the .py
is called through python3 rather than ./ (it arrives mode 100644 and a
USB copy carries no execute bit).

Also fixes Script C copying "nfc_polling.log" to the job dir when the
file is "nfc_poll.log". The cp failed, nothing checked it, and the run
finished looking fine - you would find out at the desk, with a job
archive that had no NFC log in it.

Script A -> V1.1.2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-28 22:41:02 +08:00
etwenandClaude Opus 5 c3b0d49145 fix(session): Clear the last run's jobs and session before starting
After a run that ended badly - Tera Term closed, DUT rebooted mid-soak,
macro stopped by hand - the stress jobs kept running and the test session
stayed open. The next run then started on a box that was already loaded.
Nothing errored; the numbers were just quietly wrong.

Script A now opens with hw-test-session finish, bgctl reset --yes,
bgctl stop --all, then bgctl list. The list is the point of the sequence:
it is the one line in the log that proves the DUT was idle at the start.

Script A -> V1.1.1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-28 22:04:31 +08:00
etwenandClaude Opus 5 59861cf953 feat(ber,power): Add the BER sweep and TR518 load; keep ce0 actually sending
Three new tools and one fix to an old one.

blanton_ber.sh - PRBS BER across every cabled port, init/start/report/
stop/clear, -u 0|1|all. A lane passes only below 1e-6 (equal to the
threshold fails). report ends with a per-unit summary carrying the worst
lane, so an all-PASS run still shows how much margin there was. init
checks every lane locked, because an unlocked lane still reports a BER
and it is a meaningless one. Script C runs it after the traffic report,
following SWB_UNIT0/SWB_UNIT1 like the traffic block does.

blanton_tr518.sh - the built-in packet test, used to load the rails
before measuring power. start settles 120s so the reading afterwards is
loaded rather than mid-ramp. stop sends port cd lb=none and nothing else,
exactly what the bench procedure does - l2 learning and test mode are
left as start set them, and stop says so instead of quietly leaving the
box in a state nobody asked about.

TH6_SWB{0,1}_power_readback.sh - 19 rails, V x I and total. These read
the two sensor tables ONCE. The previous version read them per rail: 38
invocations of a slow CLI at 38 different instants, so the "total" was a
sum of readings seconds apart - and under load the currents move (TH6_CORE
186 A -> 636 A). A rail missing from the table now warns on stderr instead
of silently contributing 0 W.

blanton_traffic_linespeed.sh - ce0 (VLAN 138) joins the test. It has no
loopback partner and a switch never sends a frame back out its ingress
port, so a tx burst was one round trip and then silence. init now sets an
ingress mirror of ce0 back to itself; the mirrored copy is not
egress-filtered, so packets keep lapping until stop turns the mirror off.
stop is what ends it - removing the VLAN membership does not, because the
copy never consulted the VLAN. TL_CE_MODE also drops to 'self': ps ce
shows one ce port per unit and a unit-0-only burst returned on unit 0.
Read as cross-unit, both links dying would still report PASS (0 == 0).

Fixes a parser bug worth remembering: bcmcmd returns CRLF, and the BER is
the last token on its line, so the CR stayed glued to the number. Every
lane read as NA, and printing the CR sent the cursor to column 1 so the
RESULT column overwrote the start of the row. One stray \r, two symptoms.

Not yet verified on hardware, all called out in the release notes: the
ce0 mirror (destport == srcport may be refused), the 120s settle (tr 518
may be time-limited), and 'test mode nr=no' on stop.

Script A -> V1.1.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-28 16:33:40 +08:00
etwenandClaude Opus 5 43314444e9 feat(config): Run the fans at full speed by default
FAN_SPEED 30 -> 100. A soak is a thermal test of everything except the
cooling, so the cooling should not be one of the variables in it. At 30%
a long run can throttle partway through, and throttled results read like
a different fault entirely.

Folded into V1.0.11 rather than bumping the version: the tag has not
moved on and this is the same delivery.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-28 10:32:07 +08:00
etwenandClaude Opus 5 4854da8518 feat(margin): Save every LTC2977 in one command, and stop lying about failures
margin_save discarded the result of every write, so a NACK printed
"Change Saved" exactly like a successful store. For the one permanent
operation in this tool that is the worst place to stay quiet. Each store
is now checked, named on failure, and reflected in the exit code.

STORE_USER_ALL also went out as 0x15 followed by a dummy 0x00 - an SMBus
write-byte where the command is a send-byte. The LTC2977 tolerated it,
but tolerance is not correctness. Now i2cset ... 0x15 c on the native
path and a no-data cb_pmbus_write on the FPGA path.

Two new subcommands:

  margin_save all      - all nine boards in settings/, then re-init
                         whichever board was loaded beforehand so a
                         following margin_status still reports the board
                         you were looking at. Does not stop on the first
                         failure; a half-saved set is harder to reason
                         about than a fully-attempted one.

  margin_save blanton  - this platform exposes the CB FPGA F3 I2C
                         channels as native Linux i2c buses (Ch6->13,
                         Ch7->14, Ch8->15, Ch9->16; CB stays on bus 4),
                         so all 18 LTC2977 can be stored with plain
                         i2cset: no margin_init, no FPGA channel setup,
                         no pcimem. 18 commands instead of 42.

The 18 raw commands were verified on the DUT 2026-08-27; the wrapper was
tested against stubbed hardware only. Release notes say so.

Board list is MARGIN_BLANTON_STORE at the top of margin.sh - comment out
what this DUT does not have rather than letting it talk to absent boards.
Missing bus and unresponsive chip are reported as distinct failures.

MARGIN_STORE_SETTLE (0.5s) sits between stores because nothing here polls
the part's busy bit, and blanton fires 18 in a row.

Script A -> V1.0.11.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-28 08:39:31 +08:00
74 changed files with 9410 additions and 322 deletions
+3
View File
@@ -28,3 +28,6 @@ publish/*
# 客戶板 schematic 原始檔(機密,勿入 repo)
*.DSN
*.dsn
# 尚未上機驗證的腳本暫存區(不入 repo,測過再搬進 src/)
tmp/
+137 -18
View File
@@ -112,7 +112,7 @@ Blanton_TTL_Script/
├── CLAUDE.md # 專案記憶 & 給 Claude 的指令
├── ARCHITECTURE.md # 本架構文件
├── .gitignore # secret/ + For_AI/ + logs + publish 產出
├── .gitignore # secret/ + For_AI/ + tmp/ + logs + publish 產出
├── .gitattributes # 換行符政策:.sh/.conf 釘 LF、.ttl 保持 CRLF
├── docs/ # 規格與狀態文件(客戶提供 / 專案產出)
@@ -120,6 +120,8 @@ Blanton_TTL_Script/
│ ├── Blantons_FPGA_Registers_draft.docx # 同上,客戶原始 docx
│ ├── Blantons_FPGA_Registers_Map_draft.xlsx
│ ├── Blantons_PCIe_AER_and_DDR_EDAC_checks.pdf # AER / EDAC 檢查點依據
│ ├── ADPM12200CMLZxx_DS_Datasheet_*.pdf # PDB brick 手冊(PAGE 與 DIRECT 係數的來源)
│ ├── Blanton_Test_Flow.drawio # A/B/C + 熱安規四支的測試流程圖(draw.io)
│ ├── LTC2980_channel_map.csv # 9 個 settings/*.conf 合併:Board,CONN,Ch,NetName,Vnom144 列)
│ ├── TTL_Script_Blanton_Status_20260814.xlsx
│ └── TTL_Script_Blanton_Status_20260817.xlsx # ⭐ 最新:三支腳本逐項 StatusOK / On-Going + Owner
@@ -132,7 +134,11 @@ Blanton_TTL_Script/
│ │ # ↑ 三份為手動貼上用的原始指令表,
│ │ # blanton_traffic_linespeed.sh 是其 bash 版
│ ├── 100G_PRBS.txt # 100G PRBS 原始指令(port_prbs_monitor.sh 的來源)
│ ├── TR518.txt # 內建封包測試 tr 518Scenario=6 Profile=2)— 尚未腳本化
│ ├── TR518.txt # 內建封包測試 tr 518 → blanton_tr518.sh
│ ├── BER_Test.txt # 全機 PRBS BER 指令 → blanton_ber.sh
│ ├── Multiphase_{high3,low3,comboA,comboB,Save}.txt # → blanton_multiphase_margin.sh
│ ├── Multiphase_Netname # 38 條軌的 net 名稱(區塊順序對應)
│ ├── 100G_Traffic.txt # ce0 VLAN 138 打流 → blanton_traffic_linespeed.sh
│ ├── fan_ctrl.txt # MAX31790 unbind/bind + fan-speed-control.sh 30
│ └── gen_channel_map.sh # settings/*.conf → docs/LTC2980_channel_map.csv(需 gawk
@@ -147,9 +153,14 @@ Blanton_TTL_Script/
│ ├── publish.sh # ✅ committed — 打包工具(版號讀 Script A 檔頭)
│ └── Script_ABC_Blanton_<Ver>/ # 🚫 產出,gitignored-z 另出同名 .zip
├── tmp/ # 🚫 gitignored — 尚未上機驗證的腳本暫存區
│ └── blanton_reboottest.sh # 5_..._Reboot_Cycle.ttl 的 bash 版,測過再搬進 Blanton_Script/
└── src/
└── Script_ABC_Blanton/ # ← Tera Term 的工作目錄(整包給測試員)
├── 4_Blanton_Script_thermal_safety.ttl # 熱 / 安規:獨立跑,不接 A→B→C
├── 5_Blanton_Script_Reboot_Cycle.ttl # 重開機循環:獨立跑,while 1 無止境(未上機驗證)
├── config.ttl # 全域設定:testcase 名、EN_Margin / EN_log、三個 prompt 字串
├── 1_Blanton_Script_A.ttl # Pre-test:登入 → 對時 → source 工具 → 清 AER → 抓基線
├── 2_Blanton_Script_B.ttl # Stress:開壓力程序 → while 1 每輪抓 fan/temp/margin
@@ -185,6 +196,14 @@ Blanton_TTL_Script/
├── mgmt_ping_monitor.sh # 10G/1G 管理網路 ping 監控(iproute2
│ # eth0→TARGET_10G、eth1→TARGET_1G,兩張卡同時持續 ping
├── port_prbs_monitor.sh # 100G uplink PRBS 測試(bcmcmd phy diag
├── blanton_ber.sh # 全機 SerDes BER 掃描(phydiag prbs / prbsstat
├── blanton_multiphase_margin.sh # 多相 VRM margin(原生 i2c38 條軌)
├── pwr_brick.sh # PDB / CPB power brick 讀值(VI2C ch4
├── nfc_polling.sh # NFC tag 背景輪詢 + PASS/FAIL 統計
├── blantons_nfc_validate.py # NFC/NCI 驗證工具(廠商提供,未修改)
├── blanton_tr518.sh # TR518 封包測試,量功耗前的負載來源
├── TH6_SWB0_power_readback.sh # SWB0 19 條軌 V×I + 總功耗
├── TH6_SWB1_power_readback.sh # SWB1 同上
│ # ⚠️ 已納入交付,但 A/B/C 的呼叫仍註解掉(bring-up 中)
├── usb_target.sh # 偵測 USB 裝置節點/掛載點(排除系統碟)
├── bmc_monitor.sh # BMC 監控:free -m + I2C 寫入/讀回圖樣測試
@@ -192,8 +211,12 @@ Blanton_TTL_Script/
│ # ↑ 三支都要 chmod +x 才能跑(見 Key Constraints
└── LTC2980_Margin_Script/ # 電壓 margin 子專案(另有獨立 repo
├── margin.sh # margin_init/status/set/apply_profile/save
# # v2.7.0margin_save all / margin_save blanton
├── settings/*.conf # 一個 .conf = 一顆 LTC2980CB + SWB0/1 × CONN13~16
├── profiles/*.conf # 16-ch 批次組合comboA/B、high3/5、low3/5、normal、off
├── profiles/*.conf # 16-ch 批次組合。SWB 為 per-CONN
# # combo_SWB_CONN13~16_{high,low}(百分比對應該片的軌)
# # comboA/comboB_{CB,SWB_CONN13~16}(互補棋盤配對)
# # 通用:high3/5、low3/5、normal、all_off
├── script/*_all.sh # 跨 9 顆 LTC2980 的批次 status / apply / save
├── Ref/margin_command_trace.md # 指令追蹤參考(SWB 章節已標過期,見文件內警告)
└── logs/ # margin 操作 log
@@ -214,7 +237,7 @@ project_name = "Blanton" ; 專案名,進 log 檔名
strTestcase = "ENV" ; 測項名(ENV/EMC/Margin...),進 log 檔名
EN_Margin = 0 ; 1=跑 margin 掃描, 0=跳過
EN_log = 1 ; 1=logopen 存檔, 0=不存
FAN_SPEED = 30 ; 傳給 fan-speed-control.sh 的風扇轉速 (%)
FAN_SPEED = 100 ; 傳給 fan-speed-control.sh 的風扇轉速 (%),預設全速
SWB_UNIT0 = 1 ; 這台有 switch unit 0(流量與 wait_init 都依此)
SWB_UNIT1 = 1 ; 這台有 switch unit 1
prompt_login = "sonic login:"
@@ -234,11 +257,20 @@ Log 檔名規則:`<mdir>\Logs\<project_name>_<strTestcase>_<YYYYmmdd-HHMMSS>.l
| `CB_I2C_CH` | int | `TRANSPORT="swb"` 時的 FPGA I2C 通道(6/7/8/9 |
| `CHIPS[]` | string[2] | `"bus:addr"`index 0 → CH0~7、index 1 → CH8~15 |
| `CHIP_PRE_CMD[]` / `CHIP_POST_CMD[]` | string[1] | mux 切換等前後置指令,`;` 分隔多筆 |
| `CH<n>_VNOM` | string | 標稱電壓`"-"` = 未使用 / NC |
| `CH<n>_VNOM` | string | 這條軌的**基準電壓**`"-"` = 未使用 / NC |
| `CH<n>_NET` | string | 電路 net name(對照 schematic |
Channel 定址:`ch / 8``CHIPS[]` index`ch % 8` → LTC2977 PMBus PAGE0x00~0x07)。
**`VNOM` 自 2026-08-30 起是「Blanton 實測中位數」,不是規格標稱值。** 144 條軌裡有 86 條
被改上去 +0.8% ~ +2.5%(例:`PVDD3_3V_SYNTH_LDO_*` 3.3 → 3.38、`P0V9_AVDD_*` 0.9 → 0.915、
`PVDD0_8V_T3` 0.8 → 0.82)。這件事影響兩處,**不是只有顯示**:
- `margin_status` 的偏差 % 是對 `VNOM` 算的 —— 以前一條穩定在 0.756 V 的軌顯示 `+0.80%`
現在顯示 `0.00%`。**舊 log 的偏差 % 不能跟新 log 直接比。**
- `margin_set` 的 high / low / OV / UV **全部由 `VNOM` 推算**`VNOM × (1 ± change%)`),
所以整個 margin 視窗跟著平移。同樣下 `+3%`,實際打到的絕對電壓比以前高。
**SWB 通道與位址對應(2026-08-19 上機驗證,`ababb2c`):**
| FPGA I2C 通道 | 板 / 接頭 | LTC2977 位址(lo / hi |
@@ -251,6 +283,21 @@ Channel 定址:`ch / 8` → `CHIPS[]` index`ch % 8` → LTC2977 PMBus PAGE
> 同一顆 LTC2980 的兩個位址**相差 2**7-bit,由規格書 8-bit 配對除以 2 而來),不是 1。
> 兩張板共用一條通道,所以同通道上的位址必須互斥 —— 上表兩組(`0x5C/0x5E` 與 `0x62/0x64`)不重疊。
**同一批 LTC2977 也掛在原生 i2c bus 上**2026-08-27 上機驗證):Blanton 的 SONiC 把 CB FPGA F3
的這四條 I2C 通道同時註冊成 kernel i2c adapter,因此除了 `cb_pmbus_*` → pcimem 這條路,
還可以用 `i2cset -f -y <bus>` 直接打到同一顆晶片:
| FPGA F3 通道 | Linux bus | CB FPGA 路徑 | 原生 i2c 路徑 |
|---|---|---|---|
| Ch6 | 13 | `cb_pmbus_write 6 <addr> …` | `i2cset -f -y 13 <addr> …` |
| Ch7 | 14 | `cb_pmbus_write 7 <addr> …` | `i2cset -f -y 14 <addr> …` |
| Ch8 | 15 | `cb_pmbus_write 8 <addr> …` | `i2cset -f -y 15 <addr> …` |
| Ch9 | 16 | `cb_pmbus_write 9 <addr> …` | `i2cset -f -y 16 <addr> …` |
`margin.sh``margin_save blanton` 走原生路徑(`MARGIN_BLANTON_STORE` 表),
其餘功能仍走 `TRANSPORT="swb"` 的 FPGA 路徑。兩條路到的是同一顆 LTC2977,
**不要同時用**(同一條匯流排上兩個 master 語意的存取)。
**全通道 net / 電壓對照:`docs/LTC2980_channel_map.csv`**9 個 `.conf` × 16ch = 144 列,
欄位 `Board,CONN,Ch,NetName,Vnom`)。查「某個 net 在哪片哪個 channel」比翻 9 個 `.conf` 快。
CSV 是產出物,不是正本 —— 改完 `.conf``./tools/gen_channel_map.sh` 重產,別手改 CSV。
@@ -320,20 +367,29 @@ PROFILE_CHANNELS=( "0:high:8" "1:low:8" ... ) # "channel:operation:change_perc
| 模組 | 進入點 | 功能 |
|------|--------|------|
| **Script APre-test** | `1_Blanton_Script_A.ttl` V1.0.7 | root 登入 → `date -s` 對時 → 清 job log → `hw-test-session start`**設定風扇轉速****等資料面就緒**`wait_init.ttl`)→ DUT 清單(boot/version/fwutil/syseeprom/ssdhealth/TPM/NVMe)→ BMC enroll + version/status → source bash 工具 → 清/讀 7 組 PCIe AER + `ras-mc-ctl --summary``lspci` → margin → PMON → dmesg → **10G/1G 管理網路 ping** → 100G uplink 設定與狀態 → **一輪流量基線**`show uptime` |
| **Script BStress** | `2_Blanton_Script_B.ttl` | `mlucas-avx2 -cpu 0:15` + `bgctl run``memtester` / SSD / USB 壓力 + BMC DDR`bmc-manager run memtester`)→ BMC USB net test(探測 cdc_ncm 介面,`systemd-run` 掛 4 小時 ping)→ 啟動 mgmt ping 監控 → `jobs` / `bgctl list` → traffic(依 `SWB_UNIT`)→ `while 1` 每輪完整 PMON + margin |
| **Script CPost-test** | `3_Blanton_Script_C.ttl` | `kill $(jobs -p)` + `bgctl stop --all` / `reset` + 停 BMC USB unitmgmt ping → PMON + dmesg → 7 組 AER + `ras-mc-ctl` → BMC USB `journalctl``ip -s link show eth0/eth1``cat` mlucas log → traffic `stop` + `report`NVMe 健康 → `show reboot-cause` / `uptime`**job log 複製到 USB(帶時戳)**`hw-test-session finish` |
| **SWB loopback 流量** | `blanton_traffic_linespeed <sub> [-u 0\|1\|all]` | `init`VLAN 30..137,成對 `cdN`/`cdN+32`)→ `clear``start``tx 100 length=512`)→ `stop` `report`per-pair TX/RX 交叉比對 PASS/FAIL);另有 `ps`link/speed)與 `run`(一條龍) |
| **Script APre-test** | `1_Blanton_Script_A.ttl` V1.1.7 | root 登入 → `date -s` 對時 → 清 job log → **收掉前一輪殘留**`hw-test-session finish``bgctl reset --yes``bgctl stop --all``bgctl list` 確認清空)→ `hw-test-session start`**設定風扇轉速****等資料面就緒**`wait_init.ttl`)→ DUT 清單(boot/version/fwutil/syseeprom/ssdhealth/TPM/NVMe)→ BMC enroll + version/status → source bash 工具 → 清/讀 7 組 PCIe AER + `ras-mc-ctl --summary``lspci` → margin → PMON → dmesg → **10G/1G 管理網路 ping** **NFC 基線**start → 30s → stop → report)→ 100G uplink 設定與狀態 → **一輪流量基線**`show uptime` |
| **Script BStress** | `2_Blanton_Script_B.ttl` | `mlucas-avx2 -cpu 0:15` + `bgctl run``memtester` / SSD / USB 壓力v1.1.7 起 SSD/USB 的 `--runtime`/`--passes``config.ttl``SSD_RUNTIME`/`SSD_COUNT``USB_RUNTIME`/`USB_COUNT`BMC memtester 不帶次數 = 跑到被停) + BMC DDR`bmc-manager run memtester`)→ BMC USB net test(探測 cdc_ncm 介面,`systemd-run` 掛 4 小時 ping)→ 啟動 mgmt ping 監控 → **啟動 NFC 輪詢** `jobs` / `bgctl list` → traffic(依 `SWB_UNIT`)→ `while 1` 每輪 PMON + `bgctl list`/`jobs` + `pause 60`**V1.1.4 起 margin 不在迴圈內**|
| **Script CPost-test** | `3_Blanton_Script_C.ttl` | `kill $(jobs -p)` + `bgctl stop --all` / `reset` + 停 BMC USB unitmgmt ping**NFC 輪詢** → PMON + dmesg → 7 組 AER + `ras-mc-ctl` → BMC USB `journalctl` **寫進 `log/bmc_usb_net.log`**(不再印在 console`ip -s link show eth0/eth1``cat` mlucas log → **NFC `report`** traffic `stop` + `report`**BER 掃描**(依 `SWB_UNIT`)→ NVMe 健康 → `show reboot-cause`**margin 掃描**`EN_Margin`V1.1.4 由 Script B 移來)→ `uptime`**job log 複製到 USB(帶時戳)** `exit` + wait『Script done』→ `hw-test-session finish` |
| **Script 4Thermal / Safety** | `4_Blanton_Script_thermal_safety.ttl` | **獨立腳本,不接 A→B→C。** Script A 式的環境建立(登入 / session / 風扇 / `wait_init` / DUT 清單 / BMC / PCIe 清除 / `pcie_bus` / PMON / dmesg)→ **滿載**`mlucas-avx2 -cpu 0:15` 背景 + `blanton_tr518.sh start`)→ `while 1`PMON + `TH6_SWB0/1_power_readback.sh` + `bgctl list` / `jobs``pause 60`。**沒有收尾段** —— 中斷後 DUT 仍在 `port cd lb=mac` / `l2 learn off` / `test mode nr=yes`,要手動 `blanton_tr518.sh stop` |
| **Script 5Reboot Cycle** | `5_Blanton_Script_Reboot_Cycle.ttl` | **獨立腳本,不接 A→B→C。** `while 1`:登入 → `sudo -i` → 對時 → 風扇 → **Check Pt1~Pt13**DUT/BMC info、mgmt ping、NFC、SSD、USB、BMC USB、port status + 15s traffic、BER、NVMe、platform data、dmesg i2c、PCIe error counters)→ `show uptime``reboot``wait "Booting in blind mode"``cnt_cycle` 每輪 +1 印在標頭。**沒有結束條件** —— 要停就關掉 Tera Term 的 macro。**尚未上機驗證** |
| **SWB loopback 流量** | `blanton_traffic_linespeed <sub> [-u 0\|1\|all]` | `init`VLAN 30..137,成對 `cdN`/`cdN+32`)→ `clear``start``tx 200 length=324 PatternRandom=yes`v0.7.0 起)→ `stop``report`per-pair TX/RX 交叉比對 PASS/FAIL);另有 `ps`link/speed)與 `run`(一條龍)。**V0.6.0 起含 100G uplink `ce0`**VLAN 138):它沒有 loopback 對象,靠 **ingress mirror 打回自己**維持循環,`report` 最後一列就是它,底下再接一份跨 unit summary |
| **FPGA 暫存器存取** | `cb_fpga <fn> <addr> [data]``fpga_rescan` | pcimem 打 `resource0` + BAR 相對 offset32-bit wordBDF 於 source 時自動偵測;`pmc/icb/swb0/swb1_fpga` 走 VSPI 窗口 |
| **CB I2C / PMBus** | `cb_i2c_init/scan/read/write``cb_pmbus_read/write/linear16` | FPGA F3 OpenCores master**讀用 Repeated START**SMBus/PMBus 裝置必需) |
| **ICB / PDB 存取** | `vi2c_init/scan/read/write``vi2c_scan_all` | CB F3 VI2C proxy~3.3 ms/reg,取代 VSPI 的 ~18 ms/reg(後者會踩 SMBus 2535 ms timeout |
| **溫度** | `temp_cb` / `temp_icb` / `temp_all` | TMP7512-bit 左靠齊 ×0.0625)、TMP432(含 RANGE bit 的 64 偏移、remote1/2 |
| **電源資料** | `pwr_data` / `pwr_data_pdb` / `pwr_pdb_id` | SWB VRM 全軌 Vin/Vout/Iout/Temp 對齊表;MP29816 解析度**執行期從 `MFR_VOUT_SCALE_LOOP` 讀**,不寫死 |
| **電壓 Margin** | `margin_init/status/set/apply_profile/save` + `*_all.sh` | 9 顆 LTC2980CB CONN13、SWB0/1 CONN13~16)批次 high/low margin 與狀態掃描。v2.6.0 起 SWB 路徑真正接上共用 cb_i2c 後端,並有 `margin_swb_info/probe/scan/reset/sem` 除錯包裝 |
| **電壓 Margin** | `margin_init/status/set/apply_profile/save` + `*_all.sh` | 9 顆 LTC2980CB CONN13、SWB0/1 CONN13~16)批次 high/low margin 與狀態掃描。`VNOM` 為 Blanton 實測中位數(2026-08-30);SWB 的 profile 是 per-CONN,套錯 CONN 會 margin 到錯的軌且不報錯。v2.6.0 起 SWB 路徑真正接上共用 cb_i2c 後端,並有 `margin_swb_info/probe/scan/reset/sem` 除錯包裝 |
| **Multiphase VRM margin** | `blanton_multiphase_margin.sh {high3\|low3\|comboA\|comboB\|save} [-u 0\|1\|all]` | 兩片 SWB 的多相控制器(**不是** `margin.sh` 管的 LTC2980),走原生 i2c busSWB0 = `/dev/i2c-13`+`-15`、SWB1 = `-14`+`-16`。每片 19 條軌、共 38 條,逐條印 `SWB0_0V9_ANLG0 - 0.930V Configure Done``save` 沒有 per-rail 對應,只印 `Multiphase Save All`。⚠️ `save``STORE_USER_ALL`0x15TH6 core 用 0x17**永久寫 NVM**;⚠️ 與 `margin.sh` 從兩側摸同一批軌,**不可同時用** |
| **Margin 寫 NVM** | `margin_save` / `margin_save all` / `margin_save blanton` | ⚠️ 永久寫入。`0x15` 送 PMBus **send-byte**(不帶 data byte)。`all` = 依 `settings/` 走 9 顆、跑完還原原本載入的板子;`blanton` = 本平台捷徑,18 顆全走原生 i2c bus(`MARGIN_BLANTON_STORE` 表),不需 `margin_init`。每筆之間 `MARGIN_STORE_SETTLE`0.5s),工具**不 poll busy bit** |
| **管理網路 ping** | `mgmt_ping_monitor.sh {start\|stop\|status\|fg\|tail\|clear\|summary}` | 一輪 = 10G leg + 1G leg,各自 `ip address/route replace``ping -I <if>` 打自己的對端;兩張卡都保持 up。每 leg 記 `ip -s link show` 與該卡的 TX/RX packet delta,另出一行可 grep 的 `RESULT` |
| **BMC 監控** | `bmc_monitor.sh {start\|stop\|status\|fg\|tail\|clear}` | 由 host 端 `bmc-manager run` 週期取樣 `free -m`,另加一組 **I2C 寫入/讀回圖樣測試**bus 1、addr 0x41、offset 0x00C0,寫 `55AA55AA` 讀回、再寫 `AA55AA55` 讀回)。B 啟動、C 停止並 `cat log/bmc_poll.log` |
| **BMC DDR 壓力** | `bmc_monitor_ddr.sh` | ⚠️ **已停用** —— B/C 內呼叫處已註解,改由 `bgctl run bmc-manager run memtester` 取代。檔案保留未刪 |
| **100G PRBS** | `port_prbs_monitor.sh {start [both\|a\|b]\|stop\|status\|report\|clear}` | 兩個 uplink 各一個 worker,可同時或單獨跑。setup`lpmode off``prbs set``prbsstat STArt`)→ 週期 `prbs get`(判定)+ `prbsstat Ber`(只記錄)→ teardown`STOp` + `prbs clear`)。輸出含 `PRBS OK!` 才算 PASS。**⚠️ A/B/C 的呼叫目前註解掉** |
| **SerDes BER 掃描** | `blanton_ber.sh {init\|clear\|start\|stop\|report} [-u 0\|1\|all]` | 全機每個對接 port 的 PRBS BER`prbs set p=3` + `prbs get`(確認每條 lane 都鎖上)→ `prbsstat STArt Interval=30` →(等一個 interval)→ `prbsstat Ber``STOp``prbs clear``report` 一列一條 lane**BER < 1e-6 才 PASS**,最後跨 unit 的 summary 帶最差 lane。⚠️ PRBS 期間 link 顯示 DOWN、不過流量 |
| **TR518 負載** | `blanton_tr518.sh {start\|stop} [-u 0\|1\|all]` | `port cd lb=mac``l2 learn off``test mode nr=yes``tr 518 ... testphase=1`,然後 settle `TR_SETTLE_SEC`120s)再讓人量功耗。`stop` 只送 `port cd lb=none`(照 `TR518.txt`),L2 學習與 test mode **不會還原**`TR_RESTORE_*=1` 才會 |
| **PDB / CPB brick** | `pwr_brick.sh show [-r]` | 5 顆 brick 的 Vin / Iin / Vout / Iout / TempSWB0 `0x62`/`0x63`、SWB1 `0x60`/`0x61`、CPB `0x26`)。四顆 ADPM12200 **每個量各自一個 PMBus PAGE**Vin 9、Iin 10、Vout 2、Iout 14、Temp 18),讀之前一定要先寫 PAGE —— `blanton_pwr_data.sh` 完全沒寫,所以整張 PDB 表都是 NA。換算用手冊 DIRECT 公式 `X=(1/m)(Y×10⁻ᴿ−b)`。每個值重讀到通過三道檢查為止(非 `0xFFFF`、非 `0x0000`、落在合理範圍)—— 這條匯流排**只壞高位元組**,`11.98 V` 會變成 `32.00 V`,全一過濾擋不住 |
| **SWB 軌功耗** | `TH6_SWB{0,1}_power_readback.sh` | 讀 `show platform voltage/current` **各一次**,19 條軌 V×I 與總功耗。舊版每軌各讀一次(38 次呼叫、每軌不同時刻),總和是不同瞬間的加總 |
| **NFC 讀取輪詢** | `nfc_polling.sh {start\|stop\|status\|tail\|report\|clear\|fg}` | 背景重複跑 `blantons_nfc_validate.py`,每輪追加一行機器可讀的 `RESULT=`(PASS/FAIL 取自工具自己的摘要行,兩者皆無則 **ERROR**,與 FAIL 分開計數)。`start` 會先清空 log`report` **只讀 logpolling 中隨時可跑**,並標示 `RUNNING` 免得快照被當最終結果。`tail` **不 follow** |
| **USB 目標偵測** | `usb_target.sh [-o dev\|mnt\|both\|id] [-n] [-r sec]` | 找出插入的 USB 儲存裝置,排除 `/``/host` 的底層碟(本平台可能從 USB DOM 開機),多顆時拒絕猜;掛載時會驗證真的可寫 |
| **打包交付** | `publish/publish.sh [-v Ver] [-f] [-z] [-n]` | 版號讀 Script A 檔頭,複製成 `publish/Script_ABC_Blanton_<Ver>/`,排除 `*.log`,可另出 zip |
@@ -352,6 +408,7 @@ Script A ── logopen Logs/Blanton_Margin_<ts>.log ──┐ (之後所有畫
├─ 登入 admin → sudo -i → root@sonic:~# │
├─ date -s "<host 時間>" ← 讓 DUT 時戳可對照
├─ rm /host/hw-eval/jobs/* ← 清掉上一輪的 job log
├─ hw-test-session finish / bgctl reset / stop --all / list (收前一輪)
├─ hw-test-session start / log / status
├─ 風扇:max31790 unbind→sleep→bind18-0020 與 25-0020 各一次)
│ → fan-speed-control.sh <FAN_SPEED> → 回答 y 確認 │
@@ -435,6 +492,8 @@ pwr_data
只吃 Sr;只有純暫存器裝置兩種都行。
7. **`margin_save``STORE_USER_ALL`)會永久寫進 NVM**,斷電保留。測試流程中**絕不執行**,
以免覆蓋客戶出廠 config。`margin.sh` 的 auto-enable 只改 RAM`ON_OFF_CONFIG`),斷電復原。
`margin_save all` / `margin_save blanton`v2.7.0)一次對 9 顆 LTC298018 個 LTC2977
下同一道命令,風險同性質但範圍是全機;命令本身是 PMBus send-byte`0x15`,不帶 data byte)。
8. **操作硬體電壓有損壞 DUT 的風險**:套 profile 前先確認該軌 OV/UV limit 與 servo DAC 注入電阻
有 populate(本板部分 margin 電阻標 PROTO,沒 populate 的軌電壓不會動)。
9. **`ARB_LOST` 不等於裝置存在**`vi2c_scan` 只看 `RX_ACK`,仲裁失敗會被誤報成「有裝置」。
@@ -462,8 +521,13 @@ pwr_data
`Permission denied`、Script C 的 `cat` 撲空(BMC 段全空但不會報錯)。
14. **TTL 的 `timeout` 是全域的,設了就要還原**`timeout = N` 之後**每一個** `wait` 都被限制在 N 秒,
逾時的 `wait` 會直接返回而沒吃到 prompt,於是下一個指令在前一個還沒跑完就送出,之後整輪錯開一拍。
`wait_init.ttl` 設 60 後還原 0Script B 的 cdc_ncm 探測設 15`:skip_ping`(兩條路徑的匯流點)還原
加新的 `timeout` 時務必配一個 `timeout = 0`
`wait_init.ttl` 設 60 後還原 0Script B 的 cdc_ncm 探測設 15成功路徑在 `endif` 之後還原
跳過路徑在 `:skip_ping` 還原(兩處各一次)
Script 5 抄了同一段,但它的 ping 區塊要 `wait` 一個 `sleep 10` —— DUT 一忙就逼近 15 s 上限,
所以**還原點提前到 `if` 之前**:分支之前還原,一行就涵蓋兩條路徑,`:skip_ping` 的那行留作備援。
加新的 `timeout` 時務必配一個 `timeout = 0`**抄有 `goto` 的段落時連 `:label` 一起抄** ——
標籤沒定義 Tera Term 不會在載入時報錯,要真的跳進那條分支才會彈錯誤視窗停住整輪
Script 5 原本就漏了 `:skip_ping`,只有抓不到 NCM 介面時才會發作,已補)。
15. **兩張管理網卡同網段時會 ARP flux**`mgmt_ping_monitor.sh` 讓 eth0/eth1 同時 up,若兩者在同一個
/24(本專案預設 `192.168.1.99` / `.101`),對端 ARP 可能由任一張卡回應,回包落在沒送封包的那張,
量到的數字不能歸屬。`ARP_STRICT=1` 會設 `arp_ignore=1` / `arp_announce=2` 擋掉;
@@ -483,7 +547,7 @@ pwr_data
| **客戶機密文件** | `docs/` 內 FPGA 規格(docx/xlsx/md)屬客戶 NDA 範圍;schematic 原始檔(`*.DSN`)一律 gitignore,不進 repo |
| **Remote 限制** | 只推私有 remote`nas``git.et-wen.com:51222`+ `gitea``etgit.et-wen.com`)。**不設 GitHub `origin`** |
| **測試 log** | `logs/*.log` 含 DUT 序號、MAC、韌體版本等可識別資訊 → gitignore,只保留目錄結構(`.gitkeep` |
| **破壞性硬體指令** | `margin_save` / `STORE_USER_ALL` 為永久 NVM 寫入,工具預設不呼叫;批次腳本 `margin_save_all.sh` 在 README 與腳本頂端都有警語 |
| **破壞性硬體指令** | `margin_save` / `margin_save all` / `margin_save blanton` / `STORE_USER_ALL` 為永久 NVM 寫入,工具預設不呼叫;`margin_save all`批次腳本 `margin_save_all.sh` 在 README 與程式頂端都有警語 |
| **root 權限** | 全流程在 `root@sonic:~#` 下執行(pcimem / i2c 需要);腳本不留任何 `chmod 777` 或放寬權限的動作 |
| **For_AI/** | AI 協作素材(截圖、草稿筆記)整個資料夾 gitignore,避免不小心把客戶圖面帶進 repo |
@@ -704,7 +768,7 @@ margin status、全部 VRM 軌的 Vin/Vout/Iout/Temp、CB + ICB 溫感讀值,
- [ ] `CHANGELOG.md`:延續三支腳本頂端的 Version History,集中成一份
- [ ] 三支腳本的 header 版號與 `CHANGELOG.md` 對齊,`config.ttl``script_version` 並寫進 log 開頭
- [ ] `docs/TTL_Script_Blanton_Status_*.xlsx` 更新為全 OK,或把剩餘項目移進 Future Extensions
- [ ] 打 git tag `v1.1.0`push `nas` + `gitea`
- [x] 打 git tagpush `nas` + `gitea`(已至 `V1.1.7``publish/` 依 Script A 檔頭版號打包)
**驗收條件:** 從 zip 解壓到一台乾淨的測試 NB,照 README 操作,不看原始碼就能完成一輪 A→B→C
並產出 summary`publish/` 內容與 git tag 一致。
@@ -746,16 +810,71 @@ margin status、全部 VRM 軌的 Vin/Vout/Iout/Temp、CB + ICB 溫感讀值,
複製到 USB。要確認 `bgctl` 的產出結構,必要時改成 `rm -rf .../jobs/*`
- **100G PRBS 尚未接進 A/B/C**`port_prbs_monitor.sh` 已隨包交付、可手動執行,但三支腳本裡的呼叫
都還註解著(bring-up 中)。要啟用時記得 PRBS 期間 link 會顯示 down`stop` 之後才會回來。
- **Script 5Reboot Cycle)尚未上機驗證**`5_Blanton_Script_Reboot_Cycle.ttl` 隨 V1.1.7 交付,
但還沒在真 DUT 上跑過一輪完整循環。兩個要現場確認的點:`wait "Booting in blind mode"` 是否
真的在每一版開機訊息裡出現(沒出現就會永遠等下去,而且沒有 `timeout` 保護);以及每輪重跑
`bmc-first-enroll` 是否安全。**沒有結束條件**,測夠了要自己關掉 macro。
- **`tmp/blanton_reboottest.sh`(bash 版重開循環)也未上機驗證**:不用 Tera Term、由 systemd 在
每次開機跑一輪並自動 `reboot`,登入下 `stop` 才停。整個 `tmp/` 是 gitignored**不會進交付包** ——
驗證過再搬進 `Blanton_Script/`。未驗證的腳本混進 `Blanton_Script/` 之後,測試員分不出哪支能信。
- **Script C 的 USB 掛載走 `mount` 而非 `usb_target.sh -o mnt`**:目前是 `-o dev` 取節點再自己
`mount <dev> /mnt/usb`,繞過了工具內建的 `mkdir -p`、exfat/ntfs `modprobe` 與可寫性驗證。
掛載點不存在、檔案系統模組沒載、或媒體唯讀時只會失敗一行,job log 就沒帶出來。
- **風扇確認提示是無限等待**`wait "Set all configured fan channels to"` 之後才 `sendln "y"`
若該版 `fan-speed-control.sh` 不再詢問(或字串改了),這個 `wait` 會永遠等下去,Script A 停在那裡
且不報錯。加個 `timeout` + 分支會比較保險(記得還原 `timeout = 0`)。
- **TR518 內建封包測試尚未腳本化**`tools/TR518.txt` 記下了 `tr 518 Scenario=6 Profile=2 Count=260
PktSize=324 PortList=1-259,270-565` 這組指令(含 `port all lb=mac` + `l2 learn off` 前置),
目前只能手貼。它與 `blanton_traffic_linespeed` 是兩條互斥的打流路線(都會動 loopback 與 L2 學習),
要腳本化的話得先決定兩者怎麼共存,不能同時跑。
- **TR518 已腳本化** —— `blanton_tr518.sh` V1.0.12026-08-28)。仍與 `blanton_traffic_linespeed`
互斥(兩者都會動 `port cd` loopback 與 L2 學習),檔頭與 help 都標了。剩下三件事:
`stop` 沒把 `l2 learn` / `test mode` 放回去(照 `TR518.txt` 的定義,旗標可開);
**`sleep 120` 的方向還沒驗證** —— 若 `tr 518` 的流量是有時限的(參數含 `runtime=1`
`CheckDataTime=200`),等 120 秒可能量到已經降下來的值,要上機比對 0s / 30s / 120s 三次;
TTL 尚未呼叫它。
- **`--runtime` 是整個 job 的總時限,不是每個 pass 的**:V1.1.7 起由 `config.ttl` 宣告
`SSD_RUNTIME`/`SSD_COUNT``USB_RUNTIME`/`USB_COUNT`COUNT 直接對應 `--passes`)。
`qfx5252-stress-*` 跑滿 RUNTIME 秒就結束,**`--passes` 不會把它延長**,所以
`RUNTIME=600, COUNT=720` 是 10 分鐘的壓力而不是 120 小時。要跑滿一天就把 RUNTIME 填 `86400`
壓力提早結束時 Script B 每輪的 `bgctl list` 數量會變少,但**沒有任何東西會主動報警**;
要比 24 小時更久則得加一段重啟 job 的邏輯。
- **BMC USB 的 service log 只剩隨身碟一份**Script C 把 `journalctl` 導進
`log/bmc_usb_net.log``cp` 到 job 目錄,**不再印在 master console log**。
那個 `cp` 沒有檢查回傳值(`nfc_polling.log` 檔名打錯那次就是這樣安靜失敗的),
失敗的話這份 log 就完全消失。要嘛在 `cp` 之後補一次 `ls` 驗證,要嘛保留一份
`cat` 到 console。
- **`READ_VIN` / `READ_IIN` 不在 ADPM12200 手冊的 Table 3 裡**`pwr_brick.sh` 讓它們沿用
Voltage / Current 那兩組係數。50 V 輸入算得出來、數量級也對,但**手冊沒有明說**。要定案
得找 ADI 確認,或找一個能獨立比對輸入電壓的量測點(`READ_VOUT` 就是靠 `show platform
voltage``PDB_IBC_*` 對上的)。
- **VI2C 沒有硬體號誌**`vi2c_muxsel` 的 help 自己寫了「VI2C has no SEM_REG」),而平台的
sensor 驅動會週期性讀同一批 PDB 裝置。`pwr_brick.sh` 用「重讀到合理為止」繞過去,但根本
問題沒解:`_vrd` 裡的 `_vwait` 逾時後仍然回傳半成品,呼叫端也沒檢查它的回傳值。修
`blanton_icb_vi2c.sh` 會影響所有走 VI2C 的工具(ICB 溫感、風扇、EEPROM),值得先確認
是不是跟 pmon 競爭再動。
- **`blanton_multiphase_margin.sh``margin.sh` 沒有互斥機制**:兩支從不同側(原生 i2c vs
LTC2980 PMBus)摸同一批軌,各自都假設自己是唯一的寫入者。目前只靠文件與 help 提醒,
沒有任何執行期檢查。
- **Script 4 沒有收尾段**`while 1` 之後就是檔案結尾,中斷時 DUT 停在 `port cd lb=mac` /
`l2 learn off` / `test mode nr=yes`,而且 `mlucas-avx2` 還在背景跑。要手動
`blanton_tr518.sh stop` + `kill`,否則下一輪任何測試都在被污染的狀態上開始
Script A 的 `bgctl reset/stop --all` 收得掉 job,但收不掉 bcm 的 loopback 設定)。
可考慮加一支對應的收尾腳本,或在檔尾用 `messagebox` 提示要下哪些指令。
- **margin 在 soak 期間不再取樣**V1.1.4):只剩 Script A 的起始值與 Script C 的結束值。
漂移發生在中間就看不到了。若要恢復,比較好的做法是在 B 的迴圈內每 N 輪才掃一次,
而不是每輪都掃。
- **`blanton_ber.sh``sleep 30``BER_INTERVAL` 是兩處要同步改的數字**:Script C 寫死
`sendln "sleep 30"`,腳本預設 `BER_INTERVAL=30`。改一邊沒改另一邊,report 會讀到還沒累積完
一個 interval 的數字,而且不會有任何警告。
- **`ce0` 的 ingress mirror 尚未上機驗證**`mirror port ce0 Mode=Ingress DestPort=ce0` 這條路是
推論出來的(鏡像複本不受 egress filter 的 source-port knockout 限制),語法取自 DUT 的
`help mirror`,但**還沒證明硬體真的接受 destport == srcport**。驗證方式是隔 10 秒看兩次
`show c | grep POK.ce0`,數字有沒有繼續長 —— 光看 report 的 PASS 分不出來,因為一次性 burst
也是 TX==RX。不通的話備案是 `tr 518 PortList=268`
- **SWB 的 LTC2977 有兩條路可以到,目前工具兩條都在用**:`cb_pmbus_*`CB FPGA F3 → pcimem
`margin_init` / `margin_status` / `margin_set` 走的路;原生 i2c busCh+7 = bus 13/14/15/16
`margin_save blanton` 走的路。後者短很多 —— 不需要通道初始化、不需要 pcimem,
單一 `i2cset` 就到。若原生 bus 在這平台夠穩,整個 `TRANSPORT="swb"` 層其實可以退成
「bus 號不同的 i2c 路徑」,`_swb_*`、probe、semaphore、prescale 那整套都能拿掉。
要動之前得先確認:讀取(`margin_status` 的 LINEAR16 word read)是否也同樣可靠,
以及 kernel driver 有沒有搶著存取(`margin_save blanton``-f` 就是為了繞過這件事)。
- **`settings/` 裡 SWB0 與 SWB1 是兩份相同的資料**:8 個 `.conf` 中,SWB1 的四個除了 `CHIPS[]`
bus 與 `CB_I2C_CH` 之外,net name 與 `VNOM` 與 SWB0 逐欄相同(見 `docs/LTC2980_channel_map.csv`)。
改一邊忘了改另一邊不會有任何警告。可考慮改成「共用 net 定義 + 各自的 transport 覆寫」兩層檔案。
+124 -5
View File
@@ -9,14 +9,28 @@ DUT 端的取數能力由一組 **bash 工具庫** 提供(CB FPGA `pcimem` →
完整架構見 [ARCHITECTURE.md](ARCHITECTURE.md)。
**目前狀態(2026-08-27**Script A 為 **V1.0.10**A 集中記錄 A/B/C 三支的變更)。涵蓋
**目前狀態(2026-09-04**Script A 為 **V1.1.7**A 集中記錄所有 TTL 的變更)。涵蓋
PCIe AER / DDR EDAC / PMON+TPM / 電壓 margin9 顆 LTC2980/ SWB loopback 線速流量 /
10G+1G 管理網路 ping / BMC DDR 與 USB / NVMe 健康,壓力層走平台的 `bgctl`
switch unit 數量由 `config.ttl``SWB_UNIT0` / `SWB_UNIT1` 宣告,風扇轉速由 `FAN_SPEED` 指定
switch unit 數量由 `config.ttl``SWB_UNIT0` / `SWB_UNIT1` 宣告,風扇轉速由 `FAN_SPEED` 指定
(預設 100 = 全速;soak 是熱測試,散熱不該是變因)。
測試 job log 收在 DUT 的 `/host/hw-eval/jobs/`Script C 結束時掛好 USB 再帶時戳複製到 `/mnt/usb/`
100G PRBS`port_prbs_monitor.sh`)已隨包交付,但 **A/B/C 的呼叫仍註解掉**,還在 bring-up。
Script B 的 soak 迴圈每輪印 `bgctl list` + `jobs`,並 `pause 60`V1.0.10 之前完全沒有 pause)。
最後一次發布是 **V1.0.9**;SWB 的 I2C 通道與位址已於 2026-08-19 上機驗證。
V1.1.0 新增全機 SerDes BER 掃描(`blanton_ber.sh`**Script C 已接**,依 `SWB_UNIT` 分支)、
TR518 負載(`blanton_tr518.sh`**TTL 尚未接**)、SWB 軌功耗(`TH6_SWB{0,1}_power_readback.sh`),
線速流量也納入 100G `ce0`VLAN 138,靠 ingress mirror 維持循環)。
Script A 開頭會先收掉前一輪殘留(`hw-test-session finish` + `bgctl reset/stop --all`),
`bgctl list` 確認沒有 job 留著佔資源。
NFC tag 讀取由 `nfc_polling.sh` 背景輪詢(A 做基線、B 起、C 停並 report)。
另有 **`4_Blanton_Script_thermal_safety.ttl`**(熱 / 安規,**獨立跑不接 A→B→C**,滿載後每分鐘
取 PMON + 兩片 SWB 的軌功耗;**沒有收尾段**,中斷後要手動 `blanton_tr518.sh stop`)。
以及 **`5_Blanton_Script_Reboot_Cycle.ttl`**(重開機循環,**獨立跑不接 A→B→C**:登入 → 風扇 →
Check Pt1~Pt13 → `reboot``wait "Booting in blind mode"``cnt_cycle` 每輪遞增,`while 1` 無止境,
要停就關 Tera Term 的 macro)。**尚未上機驗證**。
流程圖:`docs/Blanton_Test_Flow.drawio`
最後一次發布是 **V1.1.5**;SWB 的 I2C 通道與位址已於 2026-08-19 上機驗證。
margin 的 `VNOM` 已於 2026-08-30 改為 Blanton 實測中位數(144 條軌中 86 條上調 0.8~2.5%)。
交付用 `./publish/publish.sh` 打包。
## 技術棧
@@ -63,6 +77,14 @@ temp_all # CB + ICB 溫感
pwr_data # SWB VRM 全軌
margin_init Blanton_CB_CONN13 && margin_status
# ── 電壓 margin 寫 NVM(⚠️ 永久,測試中絕不執行)─────
margin_save # 只寫當前 margin_init 載入的那顆(2 個 LTC2977
margin_save all # settings/ 全部 9 顆;跑完自動切回原本載入的那顆
margin_save blanton # Blanton SONiC 捷徑:18 顆全走原生 i2c,不用 margin_init
# 0x15 是 send-byte,不帶 data bytei2cset -f -y <bus> <addr> 0x15
# bus = FPGA F3 通道 + 7 → Ch6=13, Ch7=14, Ch8=15, Ch9=16CB 本來就是 bus 4
# ⚠️ 沒裝滿的機器:改 margin.sh 頂端的 MARGIN_BLANTON_STORE,把沒有的板子註解掉
# ── SWB loopback 流量(bcmcmdunit 0/1)─────────────
# 不帶 -u 就是預設 TL_UNITS="0 1",兩塊 switch board 都做(TTL 三支腳本即如此)
blanton_traffic_linespeed ps # 對照線的 link/speed
@@ -98,6 +120,50 @@ bash ~/Blanton_Script/port_prbs_monitor.sh report # PASS/FAIL 統計(沒
bash ~/Blanton_Script/port_prbs_monitor.sh stop # 收尾會跑 prbsstat STOp + prbs clear
# ⚠️ PRBS 打起來時 link 會顯示 down,這是正常的 —— 所以 start 刻意不印 port status
# ── PDB / CPB power brick 讀值 ──────────────────────
./Blanton_Script/pwr_brick.sh show # Vin/Iin/Vout/Iout/Temp × 5 顆
./Blanton_Script/pwr_brick.sh show -r # 多印 raw word
# 四顆 ADPM12200 每個量各一個 PMBus PAGEVin 9 / Iin 10 / Vout 2 / Iout 14 / Temp 18
# CPB.PU37 (0x26) 是不同零件:不寫 PAGE,自己一套換算
# PB_TRIES=1 ... show -r 可看未經重試的原始行為
# ── 多相 VRM margin(原生 i2c,38 條軌)──────────────
./Blanton_Script/blanton_multiphase_margin.sh high3 # 全部 +3%
./Blanton_Script/blanton_multiphase_margin.sh low3 # 全部 -3%
./Blanton_Script/blanton_multiphase_margin.sh comboA # 混合,組合 A
./Blanton_Script/blanton_multiphase_margin.sh comboB # 混合,組合 B
./Blanton_Script/blanton_multiphase_margin.sh save # ⚠️ 永久寫 NVM
# -u 0 / -u 1 單邊(SWB0=i2c-13/15SWB1=i2c-14/16);-n 只印指令
# 逐條印 SWB0_0V9_ANLG0 - 0.930V Configure Donesave 只印 Multiphase Save All
# ⚠️ 這不是 margin.sh 管的 LTC2980,兩支摸同一批軌,不要同時用
# ── 全機 SerDes BERPRBS,期間 link 會顯示 DOWN)────
./Blanton_Script/blanton_ber.sh init # prbs set p=3 + prbs get(檢查每條 lane 鎖定)
./Blanton_Script/blanton_ber.sh start # prbsstat STArt Interval=30
sleep 30 # 至少等一個 interval 再 report
./Blanton_Script/blanton_ber.sh report # 每 lane 一列,BER < 1e-6 才 PASS,最後 summary
./Blanton_Script/blanton_ber.sh stop # prbsstat STOp
./Blanton_Script/blanton_ber.sh clear # prbs clear(會解除 PRBS,要重測得再 init)
# -u 0 / -u 1 單邊;-c 1e-9 換門檻;-F 只列失敗;-f <log> 離線重解
# ⚠️ 不能跟 blanton_traffic_linespeed / blanton_tr518 同時跑(都會接管同一批 port)
# ── TR518 負載 + 量功耗(TTL 尚未接)─────────────────
./Blanton_Script/blanton_tr518.sh start # 兩 unit,跑完 settle 120s
./Blanton_Script/TH6_SWB0_power_readback.sh # 19 條軌 V×I + TOTAL POWER
./Blanton_Script/TH6_SWB1_power_readback.sh
./Blanton_Script/blanton_tr518.sh stop # 只送 port cd lb=none
# ⚠️ stop 不還原 l2 learn / test modeTR_RESTORE_LEARN=1 / _TESTMODE=1 才會)
# ── NFC tag 輪詢 ────────────────────────────────────
~/Blanton_Script/nfc_polling.sh start # 背景,start 會先清空 log
~/Blanton_Script/nfc_polling.sh status # pid、已跑幾輪、最後一筆結果
~/Blanton_Script/nfc_polling.sh report # PASS/FAIL/ERROR 統計,polling 中也能跑
~/Blanton_Script/nfc_polling.sh tail 50 # 最後 50 行(不 follow,不會卡住)
~/Blanton_Script/nfc_polling.sh stop
# log: ~/Blanton_Script/log/nfc_poll.log
# ERROR = 工具沒印出 [PASS]/[FAIL](或逾時),跟「tag 讀不到」分開算
# NFC_INTERVAL_SEC / NFC_TIMEOUT_SEC / NFC_ARGS 可調(要每個子指令都帶)
# ── USB 目標偵測 ────────────────────────────────────
bash ~/Blanton_Script/usb_target.sh -o dev # /dev/sdX1
bash ~/Blanton_Script/usb_target.sh -o mnt # 掛好並回傳掛載點
@@ -176,8 +242,42 @@ Tera Term 連 COM port (115200-8-N-1)
- ⚠️ **ICB/PDB 一律走 VI2C`blanton_icb_vi2c.sh`),不要走 VSPI**VSPI ~18 ms/reg 會讓 I2C
byte 相間隔拉到 ~50 ms,踩中 SMBus 2535 ms timeout,裝置直接 NACK。實測全掃 9.4 s vs 34.0 s。
- ⚠️ **I2C 讀一律 Repeated START**(不是 STOP + START),否則 PMBus/SMBus 裝置(VRM、EFUSE)不理。
- ⚠️ **Script C 的 BMC USB service log 不進 master log**:改成
`journalctl ... > log/bmc_usb_net.log` 再複製到隨身碟,**那是唯一一份**。
收工後翻不到就先確認 job 目錄裡有沒有這個檔
- ⚠️ **VI2C 這條路的壞法是「只壞高位元組」**,不是整包壞掉。`11.98 V` 會變成 `32.00 V`
—— 正的、數量級也不誇張,**擋全一/全零的過濾完全攔不到**。寫任何 VI2C 讀值工具都要有
合理範圍檢查 + 重讀,光靠 `PDB_REJECT_FFFF` 那種是不夠的(`pwr_brick.sh` 的教訓)
- ⚠️ **PMBus 的 PAGE 不是只有 VRM 通道在用**:ADPM12200 把每個量測放在不同 PAGE
Vin 9 / Iin 10 / Vout 2 / Iout 14 / Temp 18),沒寫 PAGE 就讀,回的是 `0xFFFF`
`0x0000``blanton_pwr_data.sh` 的 PDB 表 page 是 `-`,這就是它整張表 NA 的原因
- ⚠️ **`--runtime` 是整個 job 的總時限,不是每個 pass 的**:V1.1.7 起由 `config.ttl`
`SSD_RUNTIME`/`SSD_COUNT``USB_RUNTIME`/`USB_COUNT` 指定(COUNT 就是 `--passes`)。
`qfx5252-stress-*` 跑滿 RUNTIME 秒就停,**`--passes` 不會把它延長** —— `RUNTIME=600` 就是
10 分鐘,不是 600×COUNT。要 24 小時就填 `86400`。壓力提早結束時 `bgctl list` 數量變少是
唯一線索,**不會報警**
- ⚠️ **多相 VRM 與 LTC2980 是同一批軌的兩條路**`blanton_multiphase_margin.sh`(原生 i2c
`margin.sh`LTC2980 PMBus)都假設自己是唯一寫入者,**沒有互斥檢查**,只靠人記得
- ⚠️ **traffic 的計數器基準在 v0.7.0 變了**`tx 100 length=512``tx 200 length=324`
每 burst 的位元組數 +27%。PASS/FAIL 是成對交叉比對不受影響,但**絕對值不能跟舊 log 比**
- ⚠️ **Script 4thermal/safety)沒有收尾**`while 1` 之後就是檔尾。中斷後 DUT 停在
`port cd lb=mac` / `l2 learn off` / `test mode nr=yes``mlucas-avx2` 也還在背景。
下一個測試會在被污染的狀態上開始,而且 **`show interfaces status` 看不出來**。
收尾:`blanton_tr518.sh stop` + `kill $(jobs -p)`
- ⚠️ **Script 4 與 Script B 不能共用同一台 DUT**:兩者都會接管 `port cd` 的 loopback
- ⚠️ **`settings/*.conf``VNOM` 是實測中位數,不是規格值**(2026-08-30 起)。它同時是
`margin_status` 偏差 % 的分母、也是 `margin_set` 推算 high/low/OV/UV 的基準,所以改它會
同時移動「看到的數字」和「實際打出去的電壓」。**跨這個日期的 margin log 不能直接互比。**
- ⚠️ **SWB 的 margin profile 是 per-CONN 的**`combo_SWB_CONN13~16_{high,low}` 各自的百分比
對應該片板子的軌。套到別的 CONN 會 margin 到錯的軌,而且**不會報錯**。CB 沒有專屬 profile
用通用的 `combo_high3` / `combo_low3`
- ⚠️ **`margin_save` / `STORE_USER_ALL` 會永久寫 NVM**,斷電保留 → **測試流程中絕不執行**
以免覆蓋客戶出廠 config。`margin.sh` 的 auto-enable`ON_OFF_CONFIG=0x1a`)只改 RAM,斷電復原。
v2.7.0 新增的 **`margin_save all` / `margin_save blanton` 一次寫 18 個 LTC2977**
同一個警告放大 9 倍;另外 `0x15` 現在送 send-byte,不再帶多餘的 `0x00` data byte。
- ⚠️ **SWB 的 LTC2977 有兩條路可以到**`cb_pmbus_*`CB FPGA F3 Ch6/7/8/9 → pcimem)與
原生 i2c bus`i2cset -f -y 13/14/15/16`Ch+7 = bus)。`margin_save blanton` 走後者,
其餘功能走前者。同一顆晶片,**不要同時用兩條路**。
- ⚠️ **改電壓會弄壞 DUT**:套 profile 前確認該軌 OV/UV limit,且 servo DAC 注入電阻有 populate
(本板部分 margin 電阻標 PROTO,沒 populate 的軌電壓不會動,不是腳本壞掉)。
- ⚠️ **`ARB_LOST` ≠ 有裝置**`vi2c_scan` 只看 `RX_ACK`,仲裁失敗會被誤報成裝置存在。
@@ -202,7 +302,12 @@ Tera Term 連 COM port (115200-8-N-1)
`--renormalize` 只在進 index 的路上轉換)。驗證要看 byte:`grep -rlU $'\r' <dir>`
- ⚠️ **TTL 的 `timeout` 是全域的**`timeout = N` 之後**每一個** `wait` 都被限制在 N 秒。逾時的 `wait`
直接返回而沒吃到 prompt,下一個指令就在前一個還沒跑完時送出,之後整輪錯開一拍。**設了一定要
配一個 `timeout = 0` 還原**`wait_init.ttl` 60→0Script B 的 cdc_ncm 探測 15→0 `:skip_ping`
配一個 `timeout = 0` 還原**`wait_init.ttl` 60→0Script B 的 cdc_ncm 探測 15→0 兩處各還原一次
—— `endif` 之後走成功路徑、`:skip_ping` 走跳過路徑;Script 5 同一段**直接還原在 `if` 之前**
一行涵蓋兩條路徑,因為它的 ping 區塊要 `wait` 一個 `sleep 10`,DUT 一忙就逼近 15 s 上限)
- ⚠️ **`goto` 的標籤沒定義,Tera Term 是執行到才報錯**Script 5 從 Script B 抄 cdc_ncm 探測時
只帶走 `goto skip_ping` 沒帶 `:skip_ping`,平常測不出來 —— 只有真的抓不到 NCM 介面走進那條分支
才會跳錯誤視窗停住整個循環(已補)。抄段落過去時**連標籤一起抄**
- ⚠️ **兩張管理網卡同網段會 ARP flux**`mgmt_ping_monitor.sh` 讓 eth0/eth1 同時 up,同一個 /24 下
對端 ARP 可能由任一張卡回應,回包落在沒送封包的那張。`ARP_STRICT=1` 擋掉;判讀時看 `RESULT` 行的
`nic_tx`/`nic_rx`(該卡自己的 packet delta)—— **ping 成功但 `nic_tx` 接近 0 = 封包從另一張卡出去的**
@@ -221,6 +326,17 @@ Tera Term 連 COM port (115200-8-N-1)
(版本改了、字串換了)就會永遠卡住且不報錯 —— 現場看起來像 Script A 當掉
- ⚠️ **`show_dmesg.ttl` 結尾會 `dmesg -C` 清空 kernel ring buffer**。這是刻意的(讓 Script C 只看到
soak 期間新產生的訊息),但代表事後在 DUT 上 `dmesg` 撈不到舊訊息 —— 內容只存在 master log 裡
- ⚠️ **`bcmcmd` 的輸出是 CRLF**。`show c` 的計數器後面還跟著 delta,所以「砍掉第一個空白之後」
順便把 CR 砍掉了;但 `prbsstat Ber` 的 BER 是**整行最後一個 token**,CR 直接黏在數字上 ——
數字驗證會失敗(全變 NA),而且印出來時 CR 把游標拉回行首,後面的欄位會**覆蓋掉前面的欄位**。
寫新的 awk 解析器時,第一件事就是 `{ gsub(/\r/, "") }``blanton_ber.sh` V1.0.1 的教訓)
- ⚠️ **`bcmcmd` 的 exit code 兩邊都不能信**BCM shell 拒絕指令時它回 **0**
`blanton_traffic_linespeed.sh` V0.3.1),而 `tr 518` 這種跑很久的指令會讓它 poll 逾時而回
**非 0**,但指令其實已經在跑(`polling socket timeout: Success`)。可靠的作法是**找成功的證據**
——例如 `tr 518` 印出 `TR 518 TEST PARAMETERS` 才算收下(`blanton_tr518.sh` V1.0.1
- ⚠️ **交換晶片不會把封包從進來的那個 port 送回去**source-port knockout)。所以單一 port 的
VLAN 打不出持續流量:`tx 100` 就是一趟來回然後結束。`ce0` 靠 **ingress mirror 打回自己**繞過
這個限制(鏡像複本不經過 egress filter),**且不 stop 就不會自己停**
- ⚠️ **DUT 的 awk 對 `%d` 會夾到 INT32**(2147483647)。線速流量的計數器是 ~10¹² 量級,
所以 awk 裡輸出大數一律用 `%.0f`double 域,精確到 2⁵³)。`blanton_traffic_linespeed.sh`
V0.4.1 已修;寫新的 awk 報表時要記得同一件事
@@ -234,7 +350,10 @@ Tera Term 連 COM port (115200-8-N-1)
- `tools/` — Host / 離線端:`bcm_mibpair_report_V1.1.0.py`drivshell log → per-pair 報表)、
`traffic_loopback_*.txt`bcmcmd 原始指令表,`blanton_traffic_linespeed.sh` 是其 bash 版,
**改 loopback 線路時兩邊要同步**)、`100G_PRBS.txt` / `TR518.txt` / `fan_ctrl.txt`
(上機手貼用的原始指令;PRBS 已有 `.sh`TR518 尚未腳本化
(上機手貼用的原始指令;PRBS / TR518 / 100G traffic / multiphase normal 都已有對應 `.sh`
- `publish/``publish.sh`(打包工具,**進 git**+ `Script_ABC_Blanton_<Ver>/` 產出(**gitignored**
- `tmp/` — 🚫 gitignored:**還沒上機驗證**的腳本暫存區(目前 `blanton_reboottest.sh`)。
上機測過才搬進 `src/Script_ABC_Blanton/Blanton_Script/` 並進 git —— 未驗證的東西不該混在
交付包裡,publish 時測試員分不出哪支能信
- `secret/` — 🚫 gitignored(除 `README.md``*.example`):DUT 帳密、per-unit BDF 覆寫、COM 設定
- `For_AI/` — 🚫 gitignored:AI 協作素材(波形截圖、草稿筆記)
Binary file not shown.
+172
View File
@@ -0,0 +1,172 @@
<mxfile host="app.diagrams.net" agent="Blanton_TTL_Script/tools" version="24.7.17">
<diagram id="blanton-test-flow" name="Blanton Test Flow">
<mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1670" pageHeight="1785" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="n11" value="Blanton (Project Helios) — 測試流程" style="text;html=1;align=center;verticalAlign=middle;fontSize=20;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="30" y="20" width="1610" height="34" as="geometry"/></mxCell>
<mxCell id="n12" value="來源:src/Script_ABC_Blanton/{1,2,3}_Blanton_Script_*.ttlScript A V1.1.3 · ⟨…⟩ = 由 config.ttl 的旗標決定" style="text;html=1;align=center;verticalAlign=middle;fontSize=11;fontColor=#666666;" vertex="1" parent="1"><mxGeometry x="30" y="54" width="1610" height="20" as="geometry"/></mxCell>
<mxCell id="n13" value="Script A — Pre-test(基線 / 環境建立)" style="swimlane;html=1;startSize=34;fillColor=#ffffff;strokeColor=#4d4d4d;fontSize=14;fontStyle=1;horizontal=1;" vertex="1" parent="1"><mxGeometry x="30" y="96" width="380" height="1459" as="geometry"/></mxCell>
<mxCell id="n14" value="&lt;b&gt;include config.ttl&lt;/b&gt;&lt;br&gt;project_name, strTestcase, EN_Margin,&lt;br&gt;EN_log, FAN_SPEED, SWB_UNIT0/1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="44" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="n15" value="&lt;b&gt;logopen&lt;/b&gt; Logs/&amp;lt;proj&amp;gt;_&amp;lt;case&amp;gt;_&amp;lt;ts&amp;gt;.log&lt;br&gt;&lt;i&gt;⟨EN_log = 1⟩&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="124" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e16" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n14" target="n15"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n17" value="&lt;b&gt;Root Login&lt;/b&gt;&lt;br&gt;login → sudo -i → root@sonic:~#" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="189" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n15" target="n17"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n19" value="&lt;b&gt;Pre Setting&lt;/b&gt;&lt;br&gt;date -s 對時 · rm /host/hw-eval/jobs/*" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="254" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e20" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n17" target="n19"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n21" value="&lt;b&gt;HW Test Session — 收前一輪&lt;/b&gt;&lt;br&gt;hw-test-session finish · bgctl reset --yes&lt;br&gt;bgctl stop --all · &lt;b&gt;bgctl list 必須空&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="319" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e22" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n19" target="n21"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n23" value="&lt;b&gt;hw-test-session start&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="399" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n21" target="n23"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n25" value="&lt;b&gt;FAN SPEED&lt;/b&gt;&lt;br&gt;max31790 rebind ×2 → fan-speed-control.sh $FAN_SPEED" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="449" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n23" target="n25"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n27" value="&lt;b&gt;Wait DUT Init&lt;/b&gt; utils/wait_init.ttl&lt;br&gt;輪詢 bcmcmd ps,兩 unit link up ≥ 216&lt;br&gt;&lt;i&gt;⟨SWB_UNIT0 / SWB_UNIT1⟩ · 無逾時出口&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="514" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n25" target="n27"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n29" value="&lt;b&gt;DUT Info&lt;/b&gt;&lt;br&gt;show boot/version/platform · fwutil · syseeprom&lt;br&gt;ssdhealth · TPM · NVMe" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="594" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e30" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n27" target="n29"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n31" value="&lt;b&gt;BMC&lt;/b&gt; bmc-first-enroll · version · status" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="674" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e32" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n29" target="n31"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n33" value="&lt;b&gt;Load Shell Script&lt;/b&gt;&lt;br&gt;source blanton_fpga_pcimem / cb_i2c / icb_vi2c /&lt;br&gt;temp_sensor / pwr_data / traffic_linespeed / margin" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="724" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e34" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n31" target="n33"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n35" value="&lt;b&gt;CLEAR PCIe Error&lt;/b&gt; ×7&lt;br&gt;TH6_SWB0 · TH6_SWB1 · FPGA · BMC · DDR · I210 · SSD" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="804" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e36" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n33" target="n35"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n37" value="&lt;b&gt;PCIe tree / link / bandwidth&lt;/b&gt; utils/pcie_bus.ttl" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="869" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e38" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n35" target="n37"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n39" value="&lt;b&gt;Check Margin&lt;/b&gt; margin_status_all.sh9 顆 LTC2980&lt;br&gt;&lt;i&gt;⟨EN_Margin = 1⟩&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="919" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e40" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n37" target="n39"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n41" value="&lt;b&gt;TAKE DATA&lt;/b&gt; setup_pmon.ttl9 項)+ show_dmesg.ttl" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="984" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n39" target="n41"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n43" value="&lt;b&gt;10G/1G MGMT Ping&lt;/b&gt;&lt;br&gt;start → 30s → report → clear" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="1034" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e44" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n41" target="n43"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n45" value="&lt;b&gt;NFC Test&lt;/b&gt;&lt;br&gt;start → status → 30s → stop → report" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="1099" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e46" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n43" target="n45"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n47" value="&lt;b&gt;100G Port Status&lt;/b&gt; Ethernet513 / 514" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="1164" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n45" target="n47"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n49" value="&lt;b&gt;100G PRBS&lt;/b&gt; port_prbs_monitor.sh&lt;br&gt;&lt;i&gt;整段註解 — bring-up 中&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;dashed=1;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;fontColor=#808080;" vertex="1" parent="n13"><mxGeometry x="18" y="1214" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e50" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n47" target="n49"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n51" value="&lt;b&gt;First Traffic Test(基線)&lt;/b&gt;&lt;br&gt;ps → init → clear → 15s → show → start → 15s → report&lt;br&gt;&lt;i&gt;⟨SWB_UNIT⟩ 兩邊 / -u 0 / -u 1 / skip&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="1279" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e52" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n49" target="n51"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n53" value="&lt;b&gt;Show power-on uptime&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n13"><mxGeometry x="18" y="1359" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e54" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n51" target="n53"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n55" value="messagebox 『Script A DONE / Start Script B』" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;align=center;verticalAlign=middle;fontSize=11;fontStyle=1;" vertex="1" parent="n13"><mxGeometry x="18" y="1409" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e56" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n53" target="n55"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n57" value="Script B — Stress(壓力 soak,人為中斷才結束)" style="swimlane;html=1;startSize=34;fillColor=#ffffff;strokeColor=#4d4d4d;fontSize=14;fontStyle=1;horizontal=1;" vertex="1" parent="1"><mxGeometry x="440" y="96" width="380" height="1014" as="geometry"/></mxCell>
<mxCell id="n58" value="&lt;b&gt;include config.ttl&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="44" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="n59" value="&lt;b&gt;CLEAR EVENT&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="94" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e60" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n58" target="n59"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n61" value="&lt;b&gt;AMD CPU Stress&lt;/b&gt; mlucas-avx2 -cpu 0:15" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="144" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e62" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n59" target="n61"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n63" value="&lt;b&gt;BMC DDR Stress&lt;/b&gt; bgctl run bmc-manager memtester" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="194" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e64" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n61" target="n63"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n65" value="&lt;b&gt;BMC Monitor&lt;/b&gt; bmc_monitor.sh start&lt;br&gt;free -m + I2C 寫入/讀回圖樣測試" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="244" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e66" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n63" target="n65"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n67" value="&lt;b&gt;DDR Memory Stress&lt;/b&gt; bgctl run memtester" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="309" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e68" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n65" target="n67"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n69" value="&lt;b&gt;SSD read/write&lt;/b&gt; bgctl run qfx5252-stress-ssd" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="359" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e70" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n67" target="n69"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n71" value="&lt;b&gt;USB read/write&lt;/b&gt; usb_target.sh -o dev → bgctl run&lt;br&gt;qfx5252-stress-usb" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="409" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e72" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n69" target="n71"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n73" value="&lt;b&gt;SHOW Background job&lt;/b&gt; bgctl list" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="474" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e74" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n71" target="n73"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n75" value="&lt;b&gt;BMC USB Test&lt;/b&gt; 偵測 cdc_ncm 介面" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="524" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e76" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n73" target="n75"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n77" value="&lt;b&gt;:skip_ping&lt;/b&gt; &lt;b&gt;timeout = 0&lt;/b&gt;(還原全域逾時)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="574" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e78" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n75" target="n77"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n79" value="&lt;b&gt;10G/1G MGMT Ping&lt;/b&gt; start → status" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="624" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e80" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n77" target="n79"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n81" value="&lt;b&gt;NFC Test&lt;/b&gt; start → status" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="674" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e82" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n79" target="n81"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n83" value="&lt;b&gt;100G Port&lt;/b&gt; lpmode off · config interface startup" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="724" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e84" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n81" target="n83"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n85" value="&lt;b&gt;100G PRBS&lt;/b&gt; &lt;i&gt;整段註解 — bring-up 中&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;dashed=1;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;fontColor=#808080;" vertex="1" parent="n57"><mxGeometry x="18" y="774" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e86" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n83" target="n85"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n87" value="&lt;b&gt;Traffic START&lt;/b&gt;&lt;br&gt;ps → init → clear → 15s → show → start&lt;br&gt;&lt;i&gt;⟨SWB_UNIT⟩ 兩邊 / -u 0 / -u 1 / skip&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="824" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e88" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n85" target="n87"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n89" value="&lt;b&gt;while 1 — soak 監控迴圈&lt;/b&gt;&lt;br&gt;setup_pmon.ttl9 項)&lt;br&gt;bgctl list + jobs&lt;br&gt;&lt;b&gt;pause 60&lt;/b&gt;&lt;br&gt;&lt;i&gt;V1.1.4 起 margin 移到 Script C&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n57"><mxGeometry x="18" y="904" width="344" height="94" as="geometry"/></mxCell>
<mxCell id="e90" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n87" target="n89"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n91" value="Script C — Post-test(收尾 / 判定 / 收 log" style="swimlane;html=1;startSize=34;fillColor=#ffffff;strokeColor=#4d4d4d;fontSize=14;fontStyle=1;horizontal=1;" vertex="1" parent="1"><mxGeometry x="850" y="96" width="380" height="1259" as="geometry"/></mxCell>
<mxCell id="n92" value="&lt;b&gt;include config.ttl&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="44" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="n93" value="&lt;b&gt;Kill Process&lt;/b&gt; utils/kill_all_process.ttl&lt;br&gt;kill $(jobs -p) · bgctl stop --all ×2&lt;br&gt;停 BMC USB service · mgmt_ping stop · &lt;b&gt;nfc stop&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="94" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e94" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n92" target="n93"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n95" value="&lt;b&gt;100G PRBS STOP&lt;/b&gt; &lt;i&gt;整段註解&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;dashed=1;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;fontColor=#808080;" vertex="1" parent="n91"><mxGeometry x="18" y="174" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e96" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n93" target="n95"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n97" value="&lt;b&gt;TAKE DATA&lt;/b&gt; setup_pmon.ttl + show_dmesg.ttl" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="224" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e98" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n95" target="n97"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n99" value="&lt;b&gt;Check PCIe error counters&lt;/b&gt; ×7(同 Script A" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="274" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e100" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n97" target="n99"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n101" value="&lt;b&gt;BMC DDR / BMC Monitor 取值&lt;/b&gt; cat bmc_ddr.log · bmc_poll.log" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="324" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e102" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n99" target="n101"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n103" value="&lt;b&gt;BMC USB Test result&lt;/b&gt; journalctl" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="374" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e104" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n101" target="n103"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n105" value="&lt;b&gt;CHECK Stress results&lt;/b&gt;&lt;br&gt;cat mlucas / memtester / ssd / usb log" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="424" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e106" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n103" target="n105"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n107" value="&lt;b&gt;10G/1G MGMT result&lt;/b&gt; ip -s link show eth0/eth1 · cat log" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="489" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e108" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n105" target="n107"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n109" value="&lt;b&gt;NFC Test result&lt;/b&gt; nfc_polling.sh report" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="539" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e110" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n107" target="n109"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n111" value="&lt;b&gt;100G Port&lt;/b&gt; show interfaces status" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="589" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e112" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n109" target="n111"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n113" value="&lt;b&gt;CHECK Traffic counters&lt;/b&gt;&lt;br&gt;stop → reportper-pair TX/RX + ce0&lt;br&gt;&lt;i&gt;⟨SWB_UNIT⟩ 兩邊 / -u 0 / -u 1 / skip&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="639" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e114" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n111" target="n113"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n115" value="&lt;b&gt;BER 掃描&lt;/b&gt; blanton_ber.sh&lt;br&gt;init → start → &lt;b&gt;sleep 30&lt;/b&gt; → report → stop → clear&lt;br&gt;&lt;i&gt;⟨SWB_UNIT⟩ · sleep 30 要與 BER_INTERVAL 同步&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="719" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e116" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n113" target="n115"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n117" value="&lt;b&gt;NVMe Err Info&lt;/b&gt; nvme smart-log · smartctl -x" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="799" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e118" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n115" target="n117"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n119" value="&lt;b&gt;show reboot-cause&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="849" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e120" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n117" target="n119"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n121" value="&lt;b&gt;Check Margin&lt;/b&gt; margin_status_all.sh9 顆)&lt;br&gt;&lt;i&gt;⟨EN_Margin = 1⟩ · V1.1.4 從 Script B 移來&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="899" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e122" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n119" target="n121"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n123" value="&lt;b&gt;show uptime&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="964" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e124" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n121" target="n123"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n125" value="&lt;b&gt;Copy Stress Log to USB&lt;/b&gt;&lt;br&gt;usb_target.sh → mount → cp 各 log 進 jobs/&lt;br&gt;→ 帶時戳複製到 /mnt/usb/" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="1014" width="344" height="64" as="geometry"/></mxCell>
<mxCell id="e126" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n123" target="n125"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n127" value="&lt;b&gt;exit&lt;/b&gt; → wait 『Script done』&lt;br&gt;離開 hw-test-session 的 shell" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="1094" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e128" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n125" target="n127"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n129" value="&lt;b&gt;hw-test-session finish&lt;/b&gt; · bgctl reset --yes" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n91"><mxGeometry x="18" y="1159" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e130" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n127" target="n129"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n131" value="messagebox 『GOOD JOB! Test Case DONE』" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;align=center;verticalAlign=middle;fontSize=11;fontStyle=1;" vertex="1" parent="n91"><mxGeometry x="18" y="1209" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e132" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n129" target="n131"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n133" value="Script 4 — Thermal &amp;amp; Safety(獨立跑,不接 A/B/C" style="swimlane;html=1;startSize=34;fillColor=#ffffff;strokeColor=#4d4d4d;fontSize=14;fontStyle=1;horizontal=1;" vertex="1" parent="1"><mxGeometry x="1260" y="96" width="380" height="929" as="geometry"/></mxCell>
<mxCell id="n134" value="&lt;b&gt;include config.ttl&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="44" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="n135" value="&lt;b&gt;logopen&lt;/b&gt; &lt;i&gt;⟨EN_log = 1⟩&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="94" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e136" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n134" target="n135"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n137" value="&lt;b&gt;Root Login&lt;/b&gt; → sudo -i" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="144" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e138" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n135" target="n137"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n139" value="&lt;b&gt;Pre Setting&lt;/b&gt; mkdir ./logs · date -s · rm jobs/*" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="194" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e140" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n137" target="n139"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n141" value="&lt;b&gt;HW Test Session&lt;/b&gt; finish → bgctl reset/stop --all → list&lt;br&gt;→ start → log → status" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="244" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e142" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n139" target="n141"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n143" value="&lt;b&gt;FAN SPEED&lt;/b&gt; max31790 rebind ×2 → fan-speed-control.sh" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="309" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e144" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n141" target="n143"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n145" value="&lt;b&gt;Wait DUT Init&lt;/b&gt; utils/wait_init.ttl&lt;br&gt;&lt;i&gt;無逾時出口&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="359" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e146" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n143" target="n145"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n147" value="&lt;b&gt;DUT Info&lt;/b&gt; boot/version/fwutil/system-memory/service&lt;br&gt;syseeprom · ssdhealth · TPM · NVMe" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="424" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e148" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n145" target="n147"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n149" value="&lt;b&gt;BMC&lt;/b&gt; enroll · version · status" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="489" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e150" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n147" target="n149"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n151" value="&lt;b&gt;CLEAR PCIe Error&lt;/b&gt; ×7 + ras-mc-ctl --summary" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="539" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e152" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n149" target="n151"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n153" value="&lt;b&gt;PCIe tree / link / bandwidth&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="589" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e154" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n151" target="n153"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n155" value="&lt;b&gt;TAKE DATA&lt;/b&gt; setup_pmon.ttl + show_dmesg.ttl" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="639" width="344" height="34" as="geometry"/></mxCell>
<mxCell id="e156" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n153" target="n155"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n157" value="&lt;b&gt;Full Load — CPU&lt;/b&gt;&lt;br&gt;chmod +x → mlucas-avx2 -s l -cpu 0:15 &amp;amp;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="689" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e158" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n155" target="n157"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n159" value="&lt;b&gt;Full Load — 資料面&lt;/b&gt;&lt;br&gt;blanton_tr518.sh start(含 120s settle" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="754" width="344" height="49" as="geometry"/></mxCell>
<mxCell id="e160" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n157" target="n159"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n161" value="&lt;b&gt;while 1 — 熱 / 安規監控迴圈&lt;/b&gt;&lt;br&gt;setup_pmon.ttl9 項)&lt;br&gt;TH6_SWB0 / SWB1_power_readback.sh&lt;br&gt;bgctl list + jobs&lt;br&gt;&lt;b&gt;pause 60&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="n133"><mxGeometry x="18" y="819" width="344" height="94" as="geometry"/></mxCell>
<mxCell id="e162" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#4d4d4d;" edge="1" parent="1" source="n159" target="n161"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="e163" value="人工啟動 Script B" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeColor=#d79b00;strokeWidth=2;dashed=1;fontSize=10;fontColor=#d79b00;" edge="1" parent="1" source="n55" target="n58"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="e164" value="soak 結束後人工中斷,啟動 Script C" style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;strokeColor=#d79b00;strokeWidth=2;dashed=1;fontSize=10;fontColor=#d79b00;" edge="1" parent="1" source="n89" target="n92"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="n165" value="圖例" style="text;html=1;align=left;verticalAlign=middle;fontSize=13;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="30" y="1585" width="200" height="24" as="geometry"/></mxCell>
<mxCell id="n166" value="一般步驟" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="1"><mxGeometry x="30" y="1613" width="230" height="32" as="geometry"/></mxCell>
<mxCell id="n167" value="受 config.ttl 旗標影響" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="1"><mxGeometry x="280" y="1613" width="230" height="32" as="geometry"/></mxCell>
<mxCell id="n168" value="迴圈 / 持續執行" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="1"><mxGeometry x="530" y="1613" width="230" height="32" as="geometry"/></mxCell>
<mxCell id="n169" value="目前註解停用" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;dashed=1;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;fontColor=#808080;" vertex="1" parent="1"><mxGeometry x="30" y="1655" width="230" height="32" as="geometry"/></mxCell>
<mxCell id="n170" value="狀態變更 / 需留意" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;align=left;spacingLeft=8;verticalAlign=middle;fontSize=11;" vertex="1" parent="1"><mxGeometry x="280" y="1655" width="230" height="32" as="geometry"/></mxCell>
<mxCell id="n171" value="人工交接點" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;align=center;verticalAlign=middle;fontSize=11;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="530" y="1655" width="230" height="32" as="geometry"/></mxCell>
<mxCell id="n172" value="⚠️ 已知待辦:① 100G PRBS 三支腳本內呼叫仍註解(bring-up 中) ② wait_init.ttl 與風扇確認 wait 沒有逾時出口,起不來會無限等待 ③ Script C 的 sleep 30 需與 blanton_ber.sh 的 BER_INTERVAL 同步 ④ Script 4 沒有收尾段:中斷後 tr518 留下 port cd lb=mac / l2 learn off / test mode nr=yes,需手動 blanton_tr518.sh stop" style="text;html=1;align=left;verticalAlign=top;fontSize=11;fontColor=#b85450;" vertex="1" parent="1"><mxGeometry x="30" y="1703" width="1610" height="46" as="geometry"/></mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
+86 -86
View File
@@ -6,7 +6,7 @@ CB,CONN13,CH3,V1P8_ALW,1.8
CB,CONN13,CH4,PWR_APU_VDDIO_SUS,1.1
CB,CONN13,CH5,PWR_VDD_MISC_RUN,0.75
CB,CONN13,CH6,PWR_APU_VDD_MEM_RUN,0.78
CB,CONN13,CH7,V0P8_PHY2_DVDD,0.8
CB,CONN13,CH7,V0P8_PHY2_DVDD,0.816
CB,CONN13,CH8,V0P8_AVDD,0.8
CB,CONN13,CH9,V0P8_PHY,0.8
CB,CONN13,CH10,V1P8_FPGA,1.8
@@ -14,132 +14,132 @@ CB,CONN13,CH11,V2P5_FPGA,2.5
CB,CONN13,CH12,V1P1_FPGA,1.1
CB,CONN13,CH13,P5V_STBY,5.0
CB,CONN13,CH14,P3V3_STBY,3.3
CB,CONN13,CH15,V0P8_PHY2_AVDD,0.8
CB,CONN13,CH15,V0P8_PHY2_AVDD,0.816
SWB0,CONN13,CH0,P0V75_DVDD_47,0.75
SWB0,CONN13,CH1,P0V75_AVDD_47,0.75
SWB0,CONN13,CH2,P1V5_AVDD_47,1.5
SWB0,CONN13,CH3,P0V9_AVDD_47,0.9
SWB0,CONN13,CH4,P1V8_1,1.8
SWB0,CONN13,CH5,PVDD3_3V_SYNTH_LDO_A3,3.3
SWB0,CONN13,CH6,PVDD3_3V_SYNTH_LDO_B1,3.3
SWB0,CONN13,CH7,P1V8_3,1.8
SWB0,CONN13,CH1,P0V75_AVDD_47,0.756
SWB0,CONN13,CH2,P1V5_AVDD_47,1.524
SWB0,CONN13,CH3,P0V9_AVDD_47,0.915
SWB0,CONN13,CH4,P1V8_1,1.816
SWB0,CONN13,CH5,PVDD3_3V_SYNTH_LDO_A3,3.38
SWB0,CONN13,CH6,PVDD3_3V_SYNTH_LDO_B1,3.38
SWB0,CONN13,CH7,P1V8_3,1.816
SWB0,CONN13,CH8,P1V8_DVDDIO_3,1.8
SWB0,CONN13,CH9,P0V75_DVDD_39,0.75
SWB0,CONN13,CH10,P0V75_AVDD_39,0.75
SWB0,CONN13,CH11,P1V5_AVDD_39,1.5
SWB0,CONN13,CH12,P0V9_AVDD_39,0.9
SWB0,CONN13,CH10,P0V75_AVDD_39,0.756
SWB0,CONN13,CH11,P1V5_AVDD_39,1.524
SWB0,CONN13,CH12,P0V9_AVDD_39,0.915
SWB0,CONN13,CH13,PVDD1V5_2,1.5
SWB0,CONN13,CH14,PVDD1V8_DUT,1.8
SWB0,CONN13,CH15,PVDD_MDIO,1.2
SWB0,CONN14,CH0,P0V75_AVDD_7,0.75
SWB0,CONN14,CH1,P1V5_AVDD_7,1.5
SWB0,CONN14,CH2,P0V9_AVDD_7,0.9
SWB0,CONN14,CH3,P1V8_5,1.8
SWB0,CONN14,CH4,P1V8_2,1.8
SWB0,CONN14,CH5,PVDD3_3V_SYNTH_LDO_B2,3.3
SWB0,CONN14,CH6,PVDD3_3V_SYNTH_LDO_A2,3.3
SWB0,CONN14,CH7,PVDD3_3V_SYNTH_LDO_A1,3.3
SWB0,CONN14,CH8,PVDD1V5_TSC,1.5
SWB0,CONN14,CH9,PVDD1V5_ANLG,1.5
SWB0,CONN14,CH0,P0V75_AVDD_7,0.756
SWB0,CONN14,CH1,P1V5_AVDD_7,1.524
SWB0,CONN14,CH2,P0V9_AVDD_7,0.915
SWB0,CONN14,CH3,P1V8_5,1.816
SWB0,CONN14,CH4,P1V8_2,1.816
SWB0,CONN14,CH5,PVDD3_3V_SYNTH_LDO_B2,3.38
SWB0,CONN14,CH6,PVDD3_3V_SYNTH_LDO_A2,3.38
SWB0,CONN14,CH7,PVDD3_3V_SYNTH_LDO_A1,3.38
SWB0,CONN14,CH8,PVDD1V5_TSC,1.516
SWB0,CONN14,CH9,PVDD1V5_ANLG,1.516
SWB0,CONN14,CH10,NC,-
SWB0,CONN14,CH11,NC,-
SWB0,CONN14,CH12,PVDD1V5_1,1.5
SWB0,CONN14,CH13,NC,-
SWB0,CONN14,CH14,P1V8_DVDDIO_1,1.8
SWB0,CONN14,CH15,P0V75_DVDD_7,0.75
SWB0,CONN15,CH0,P1V5_AVDD_55,1.5
SWB0,CONN15,CH1,P0V9_AVDD_55,0.9
SWB0,CONN15,CH0,P1V5_AVDD_55,1.524
SWB0,CONN15,CH1,P0V9_AVDD_55,0.915
SWB0,CONN15,CH2,P0V75_DVDD_63,0.75
SWB0,CONN15,CH3,P0V75_AVDD_63,0.75
SWB0,CONN15,CH4,P1V5_AVDD_63,1.5
SWB0,CONN15,CH5,P0V9_AVDD_63,0.9
SWB0,CONN15,CH6,PVDD3_3V_SYNTH_LDO_B3,3.3
SWB0,CONN15,CH3,P0V75_AVDD_63,0.756
SWB0,CONN15,CH4,P1V5_AVDD_63,1.524
SWB0,CONN15,CH5,P0V9_AVDD_63,0.915
SWB0,CONN15,CH6,PVDD3_3V_SYNTH_LDO_B3,3.38
SWB0,CONN15,CH7,PVDD1V5_3,1.5
SWB0,CONN15,CH8,P0V85_STBY,0.85
SWB0,CONN15,CH9,P1V8_STBY,1.8
SWB0,CONN15,CH10,NC,-
SWB0,CONN15,CH11,P3V3_STBY,3.3
SWB0,CONN15,CH12,PVDD0V9_2,0.9
SWB0,CONN15,CH12,PVDD0V9_2,0.91
SWB0,CONN15,CH13,P0V75_DVDD_55,0.75
SWB0,CONN15,CH14,P0V75_AVDD_55,0.75
SWB0,CONN15,CH14,P0V75_AVDD_55,0.756
SWB0,CONN15,CH15,P1V8_DVDDIO_4,1.8
SWB0,CONN16,CH0,PVDD1V5_0,1.5
SWB0,CONN16,CH1,P1V8_4,1.8
SWB0,CONN16,CH2,PVDD3_3V_SYNTH_LDO_B5,3.3
SWB0,CONN16,CH3,PVDD3_3V_SYNTH_LDO_A5,3.3
SWB0,CONN16,CH4,PVDD3_3V_SYNTH_LDO_B4,3.3
SWB0,CONN16,CH5,PVDD3_3V_SYNTH_LDO_A4,3.3
SWB0,CONN16,CH6,P3V3,3.3
SWB0,CONN16,CH7,PVDD0_8V_T3,0.8
SWB0,CONN16,CH1,P1V8_4,1.816
SWB0,CONN16,CH2,PVDD3_3V_SYNTH_LDO_B5,3.38
SWB0,CONN16,CH3,PVDD3_3V_SYNTH_LDO_A5,3.38
SWB0,CONN16,CH4,PVDD3_3V_SYNTH_LDO_B4,3.38
SWB0,CONN16,CH5,PVDD3_3V_SYNTH_LDO_A4,3.38
SWB0,CONN16,CH6,P3V3,3.327
SWB0,CONN16,CH7,PVDD0_8V_T3,0.82
SWB0,CONN16,CH8,P0V75_DVDD_1,0.75
SWB0,CONN16,CH9,P0V75_AVDD_1,0.75
SWB0,CONN16,CH10,P1V5_AVDD_1,1.5
SWB0,CONN16,CH11,P0V9_AVDD_1,0.9
SWB0,CONN16,CH12,PVDD0V9_0,0.9
SWB0,CONN16,CH13,PVDD0V9_1,0.9
SWB0,CONN16,CH14,PVDD0V9_3,0.9
SWB0,CONN16,CH15,PVDD1V2_T3,1.2
SWB0,CONN16,CH9,P0V75_AVDD_1,0.756
SWB0,CONN16,CH10,P1V5_AVDD_1,1.524
SWB0,CONN16,CH11,P0V9_AVDD_1,0.915
SWB0,CONN16,CH12,PVDD0V9_0,0.915
SWB0,CONN16,CH13,PVDD0V9_1,0.91
SWB0,CONN16,CH14,PVDD0V9_3,0.915
SWB0,CONN16,CH15,PVDD1V2_T3,1.224
SWB1,CONN13,CH0,P0V75_DVDD_47,0.75
SWB1,CONN13,CH1,P0V75_AVDD_47,0.75
SWB1,CONN13,CH2,P1V5_AVDD_47,1.5
SWB1,CONN13,CH3,P0V9_AVDD_47,0.9
SWB1,CONN13,CH4,P1V8_1,1.8
SWB1,CONN13,CH5,PVDD3_3V_SYNTH_LDO_A3,3.3
SWB1,CONN13,CH6,PVDD3_3V_SYNTH_LDO_B1,3.3
SWB1,CONN13,CH7,P1V8_3,1.8
SWB1,CONN13,CH1,P0V75_AVDD_47,0.756
SWB1,CONN13,CH2,P1V5_AVDD_47,1.524
SWB1,CONN13,CH3,P0V9_AVDD_47,0.915
SWB1,CONN13,CH4,P1V8_1,1.816
SWB1,CONN13,CH5,PVDD3_3V_SYNTH_LDO_A3,3.38
SWB1,CONN13,CH6,PVDD3_3V_SYNTH_LDO_B1,3.38
SWB1,CONN13,CH7,P1V8_3,1.816
SWB1,CONN13,CH8,P1V8_DVDDIO_3,1.8
SWB1,CONN13,CH9,P0V75_DVDD_39,0.75
SWB1,CONN13,CH10,P0V75_AVDD_39,0.75
SWB1,CONN13,CH11,P1V5_AVDD_39,1.5
SWB1,CONN13,CH12,P0V9_AVDD_39,0.9
SWB1,CONN13,CH10,P0V75_AVDD_39,0.756
SWB1,CONN13,CH11,P1V5_AVDD_39,1.524
SWB1,CONN13,CH12,P0V9_AVDD_39,0.915
SWB1,CONN13,CH13,PVDD1V5_2,1.5
SWB1,CONN13,CH14,PVDD1V8_DUT,1.8
SWB1,CONN13,CH15,PVDD_MDIO,1.2
SWB1,CONN14,CH0,P0V75_AVDD_7,0.75
SWB1,CONN14,CH1,P1V5_AVDD_7,1.5
SWB1,CONN14,CH2,P0V9_AVDD_7,0.9
SWB1,CONN14,CH3,P1V8_5,1.8
SWB1,CONN14,CH4,P1V8_2,1.8
SWB1,CONN14,CH5,PVDD3_3V_SYNTH_LDO_B2,3.3
SWB1,CONN14,CH6,PVDD3_3V_SYNTH_LDO_A2,3.3
SWB1,CONN14,CH7,PVDD3_3V_SYNTH_LDO_A1,3.3
SWB1,CONN14,CH8,PVDD1V5_TSC,1.5
SWB1,CONN14,CH9,PVDD1V5_ANLG,1.5
SWB1,CONN14,CH0,P0V75_AVDD_7,0.756
SWB1,CONN14,CH1,P1V5_AVDD_7,1.524
SWB1,CONN14,CH2,P0V9_AVDD_7,0.915
SWB1,CONN14,CH3,P1V8_5,1.816
SWB1,CONN14,CH4,P1V8_2,1.816
SWB1,CONN14,CH5,PVDD3_3V_SYNTH_LDO_B2,3.38
SWB1,CONN14,CH6,PVDD3_3V_SYNTH_LDO_A2,3.38
SWB1,CONN14,CH7,PVDD3_3V_SYNTH_LDO_A1,3.38
SWB1,CONN14,CH8,PVDD1V5_TSC,1.516
SWB1,CONN14,CH9,PVDD1V5_ANLG,1.516
SWB1,CONN14,CH10,NC,-
SWB1,CONN14,CH11,NC,-
SWB1,CONN14,CH12,PVDD1V5_1,1.5
SWB1,CONN14,CH13,NC,-
SWB1,CONN14,CH14,P1V8_DVDDIO_1,1.8
SWB1,CONN14,CH15,P0V75_DVDD_7,0.75
SWB1,CONN15,CH0,P1V5_AVDD_55,1.5
SWB1,CONN15,CH1,P0V9_AVDD_55,0.9
SWB1,CONN15,CH0,P1V5_AVDD_55,1.524
SWB1,CONN15,CH1,P0V9_AVDD_55,0.915
SWB1,CONN15,CH2,P0V75_DVDD_63,0.75
SWB1,CONN15,CH3,P0V75_AVDD_63,0.75
SWB1,CONN15,CH4,P1V5_AVDD_63,1.5
SWB1,CONN15,CH5,P0V9_AVDD_63,0.9
SWB1,CONN15,CH6,PVDD3_3V_SYNTH_LDO_B3,3.3
SWB1,CONN15,CH3,P0V75_AVDD_63,0.756
SWB1,CONN15,CH4,P1V5_AVDD_63,1.524
SWB1,CONN15,CH5,P0V9_AVDD_63,0.915
SWB1,CONN15,CH6,PVDD3_3V_SYNTH_LDO_B3,3.38
SWB1,CONN15,CH7,PVDD1V5_3,1.5
SWB1,CONN15,CH8,P0V85_STBY,0.85
SWB1,CONN15,CH9,P1V8_STBY,1.8
SWB1,CONN15,CH10,NC,-
SWB1,CONN15,CH11,P3V3_STBY,3.3
SWB1,CONN15,CH12,PVDD0V9_2,0.9
SWB1,CONN15,CH12,PVDD0V9_2,0.91
SWB1,CONN15,CH13,P0V75_DVDD_55,0.75
SWB1,CONN15,CH14,P0V75_AVDD_55,0.75
SWB1,CONN15,CH14,P0V75_AVDD_55,0.756
SWB1,CONN15,CH15,P1V8_DVDDIO_4,1.8
SWB1,CONN16,CH0,PVDD1V5_0,1.5
SWB1,CONN16,CH1,P1V8_4,1.8
SWB1,CONN16,CH2,PVDD3_3V_SYNTH_LDO_B5,3.3
SWB1,CONN16,CH3,PVDD3_3V_SYNTH_LDO_A5,3.3
SWB1,CONN16,CH4,PVDD3_3V_SYNTH_LDO_B4,3.3
SWB1,CONN16,CH5,PVDD3_3V_SYNTH_LDO_A4,3.3
SWB1,CONN16,CH6,P3V3,3.3
SWB1,CONN16,CH7,PVDD0_8V_T3,0.8
SWB1,CONN16,CH1,P1V8_4,1.816
SWB1,CONN16,CH2,PVDD3_3V_SYNTH_LDO_B5,3.38
SWB1,CONN16,CH3,PVDD3_3V_SYNTH_LDO_A5,3.38
SWB1,CONN16,CH4,PVDD3_3V_SYNTH_LDO_B4,3.38
SWB1,CONN16,CH5,PVDD3_3V_SYNTH_LDO_A4,3.38
SWB1,CONN16,CH6,P3V3,3.327
SWB1,CONN16,CH7,PVDD0_8V_T3,0.82
SWB1,CONN16,CH8,P0V75_DVDD_1,0.75
SWB1,CONN16,CH9,P0V75_AVDD_1,0.75
SWB1,CONN16,CH10,P1V5_AVDD_1,1.5
SWB1,CONN16,CH11,P0V9_AVDD_1,0.9
SWB1,CONN16,CH12,PVDD0V9_0,0.9
SWB1,CONN16,CH13,PVDD0V9_1,0.9
SWB1,CONN16,CH14,PVDD0V9_3,0.9
SWB1,CONN16,CH15,PVDD1V2_T3,1.2
SWB1,CONN16,CH9,P0V75_AVDD_1,0.756
SWB1,CONN16,CH10,P1V5_AVDD_1,1.524
SWB1,CONN16,CH11,P0V9_AVDD_1,0.915
SWB1,CONN16,CH12,PVDD0V9_0,0.915
SWB1,CONN16,CH13,PVDD0V9_1,0.91
SWB1,CONN16,CH14,PVDD0V9_3,0.915
SWB1,CONN16,CH15,PVDD1V2_T3,1.224
1 Board CONN Ch NetName Vnom
6 CB CONN13 CH4 PWR_APU_VDDIO_SUS 1.1
7 CB CONN13 CH5 PWR_VDD_MISC_RUN 0.75
8 CB CONN13 CH6 PWR_APU_VDD_MEM_RUN 0.78
9 CB CONN13 CH7 V0P8_PHY2_DVDD 0.8 0.816
10 CB CONN13 CH8 V0P8_AVDD 0.8
11 CB CONN13 CH9 V0P8_PHY 0.8
12 CB CONN13 CH10 V1P8_FPGA 1.8
14 CB CONN13 CH12 V1P1_FPGA 1.1
15 CB CONN13 CH13 P5V_STBY 5.0
16 CB CONN13 CH14 P3V3_STBY 3.3
17 CB CONN13 CH15 V0P8_PHY2_AVDD 0.8 0.816
18 SWB0 CONN13 CH0 P0V75_DVDD_47 0.75
19 SWB0 CONN13 CH1 P0V75_AVDD_47 0.75 0.756
20 SWB0 CONN13 CH2 P1V5_AVDD_47 1.5 1.524
21 SWB0 CONN13 CH3 P0V9_AVDD_47 0.9 0.915
22 SWB0 CONN13 CH4 P1V8_1 1.8 1.816
23 SWB0 CONN13 CH5 PVDD3_3V_SYNTH_LDO_A3 3.3 3.38
24 SWB0 CONN13 CH6 PVDD3_3V_SYNTH_LDO_B1 3.3 3.38
25 SWB0 CONN13 CH7 P1V8_3 1.8 1.816
26 SWB0 CONN13 CH8 P1V8_DVDDIO_3 1.8
27 SWB0 CONN13 CH9 P0V75_DVDD_39 0.75
28 SWB0 CONN13 CH10 P0V75_AVDD_39 0.75 0.756
29 SWB0 CONN13 CH11 P1V5_AVDD_39 1.5 1.524
30 SWB0 CONN13 CH12 P0V9_AVDD_39 0.9 0.915
31 SWB0 CONN13 CH13 PVDD1V5_2 1.5
32 SWB0 CONN13 CH14 PVDD1V8_DUT 1.8
33 SWB0 CONN13 CH15 PVDD_MDIO 1.2
34 SWB0 CONN14 CH0 P0V75_AVDD_7 0.75 0.756
35 SWB0 CONN14 CH1 P1V5_AVDD_7 1.5 1.524
36 SWB0 CONN14 CH2 P0V9_AVDD_7 0.9 0.915
37 SWB0 CONN14 CH3 P1V8_5 1.8 1.816
38 SWB0 CONN14 CH4 P1V8_2 1.8 1.816
39 SWB0 CONN14 CH5 PVDD3_3V_SYNTH_LDO_B2 3.3 3.38
40 SWB0 CONN14 CH6 PVDD3_3V_SYNTH_LDO_A2 3.3 3.38
41 SWB0 CONN14 CH7 PVDD3_3V_SYNTH_LDO_A1 3.3 3.38
42 SWB0 CONN14 CH8 PVDD1V5_TSC 1.5 1.516
43 SWB0 CONN14 CH9 PVDD1V5_ANLG 1.5 1.516
44 SWB0 CONN14 CH10 NC -
45 SWB0 CONN14 CH11 NC -
46 SWB0 CONN14 CH12 PVDD1V5_1 1.5
47 SWB0 CONN14 CH13 NC -
48 SWB0 CONN14 CH14 P1V8_DVDDIO_1 1.8
49 SWB0 CONN14 CH15 P0V75_DVDD_7 0.75
50 SWB0 CONN15 CH0 P1V5_AVDD_55 1.5 1.524
51 SWB0 CONN15 CH1 P0V9_AVDD_55 0.9 0.915
52 SWB0 CONN15 CH2 P0V75_DVDD_63 0.75
53 SWB0 CONN15 CH3 P0V75_AVDD_63 0.75 0.756
54 SWB0 CONN15 CH4 P1V5_AVDD_63 1.5 1.524
55 SWB0 CONN15 CH5 P0V9_AVDD_63 0.9 0.915
56 SWB0 CONN15 CH6 PVDD3_3V_SYNTH_LDO_B3 3.3 3.38
57 SWB0 CONN15 CH7 PVDD1V5_3 1.5
58 SWB0 CONN15 CH8 P0V85_STBY 0.85
59 SWB0 CONN15 CH9 P1V8_STBY 1.8
60 SWB0 CONN15 CH10 NC -
61 SWB0 CONN15 CH11 P3V3_STBY 3.3
62 SWB0 CONN15 CH12 PVDD0V9_2 0.9 0.91
63 SWB0 CONN15 CH13 P0V75_DVDD_55 0.75
64 SWB0 CONN15 CH14 P0V75_AVDD_55 0.75 0.756
65 SWB0 CONN15 CH15 P1V8_DVDDIO_4 1.8
66 SWB0 CONN16 CH0 PVDD1V5_0 1.5
67 SWB0 CONN16 CH1 P1V8_4 1.8 1.816
68 SWB0 CONN16 CH2 PVDD3_3V_SYNTH_LDO_B5 3.3 3.38
69 SWB0 CONN16 CH3 PVDD3_3V_SYNTH_LDO_A5 3.3 3.38
70 SWB0 CONN16 CH4 PVDD3_3V_SYNTH_LDO_B4 3.3 3.38
71 SWB0 CONN16 CH5 PVDD3_3V_SYNTH_LDO_A4 3.3 3.38
72 SWB0 CONN16 CH6 P3V3 3.3 3.327
73 SWB0 CONN16 CH7 PVDD0_8V_T3 0.8 0.82
74 SWB0 CONN16 CH8 P0V75_DVDD_1 0.75
75 SWB0 CONN16 CH9 P0V75_AVDD_1 0.75 0.756
76 SWB0 CONN16 CH10 P1V5_AVDD_1 1.5 1.524
77 SWB0 CONN16 CH11 P0V9_AVDD_1 0.9 0.915
78 SWB0 CONN16 CH12 PVDD0V9_0 0.9 0.915
79 SWB0 CONN16 CH13 PVDD0V9_1 0.9 0.91
80 SWB0 CONN16 CH14 PVDD0V9_3 0.9 0.915
81 SWB0 CONN16 CH15 PVDD1V2_T3 1.2 1.224
82 SWB1 CONN13 CH0 P0V75_DVDD_47 0.75
83 SWB1 CONN13 CH1 P0V75_AVDD_47 0.75 0.756
84 SWB1 CONN13 CH2 P1V5_AVDD_47 1.5 1.524
85 SWB1 CONN13 CH3 P0V9_AVDD_47 0.9 0.915
86 SWB1 CONN13 CH4 P1V8_1 1.8 1.816
87 SWB1 CONN13 CH5 PVDD3_3V_SYNTH_LDO_A3 3.3 3.38
88 SWB1 CONN13 CH6 PVDD3_3V_SYNTH_LDO_B1 3.3 3.38
89 SWB1 CONN13 CH7 P1V8_3 1.8 1.816
90 SWB1 CONN13 CH8 P1V8_DVDDIO_3 1.8
91 SWB1 CONN13 CH9 P0V75_DVDD_39 0.75
92 SWB1 CONN13 CH10 P0V75_AVDD_39 0.75 0.756
93 SWB1 CONN13 CH11 P1V5_AVDD_39 1.5 1.524
94 SWB1 CONN13 CH12 P0V9_AVDD_39 0.9 0.915
95 SWB1 CONN13 CH13 PVDD1V5_2 1.5
96 SWB1 CONN13 CH14 PVDD1V8_DUT 1.8
97 SWB1 CONN13 CH15 PVDD_MDIO 1.2
98 SWB1 CONN14 CH0 P0V75_AVDD_7 0.75 0.756
99 SWB1 CONN14 CH1 P1V5_AVDD_7 1.5 1.524
100 SWB1 CONN14 CH2 P0V9_AVDD_7 0.9 0.915
101 SWB1 CONN14 CH3 P1V8_5 1.8 1.816
102 SWB1 CONN14 CH4 P1V8_2 1.8 1.816
103 SWB1 CONN14 CH5 PVDD3_3V_SYNTH_LDO_B2 3.3 3.38
104 SWB1 CONN14 CH6 PVDD3_3V_SYNTH_LDO_A2 3.3 3.38
105 SWB1 CONN14 CH7 PVDD3_3V_SYNTH_LDO_A1 3.3 3.38
106 SWB1 CONN14 CH8 PVDD1V5_TSC 1.5 1.516
107 SWB1 CONN14 CH9 PVDD1V5_ANLG 1.5 1.516
108 SWB1 CONN14 CH10 NC -
109 SWB1 CONN14 CH11 NC -
110 SWB1 CONN14 CH12 PVDD1V5_1 1.5
111 SWB1 CONN14 CH13 NC -
112 SWB1 CONN14 CH14 P1V8_DVDDIO_1 1.8
113 SWB1 CONN14 CH15 P0V75_DVDD_7 0.75
114 SWB1 CONN15 CH0 P1V5_AVDD_55 1.5 1.524
115 SWB1 CONN15 CH1 P0V9_AVDD_55 0.9 0.915
116 SWB1 CONN15 CH2 P0V75_DVDD_63 0.75
117 SWB1 CONN15 CH3 P0V75_AVDD_63 0.75 0.756
118 SWB1 CONN15 CH4 P1V5_AVDD_63 1.5 1.524
119 SWB1 CONN15 CH5 P0V9_AVDD_63 0.9 0.915
120 SWB1 CONN15 CH6 PVDD3_3V_SYNTH_LDO_B3 3.3 3.38
121 SWB1 CONN15 CH7 PVDD1V5_3 1.5
122 SWB1 CONN15 CH8 P0V85_STBY 0.85
123 SWB1 CONN15 CH9 P1V8_STBY 1.8
124 SWB1 CONN15 CH10 NC -
125 SWB1 CONN15 CH11 P3V3_STBY 3.3
126 SWB1 CONN15 CH12 PVDD0V9_2 0.9 0.91
127 SWB1 CONN15 CH13 P0V75_DVDD_55 0.75
128 SWB1 CONN15 CH14 P0V75_AVDD_55 0.75 0.756
129 SWB1 CONN15 CH15 P1V8_DVDDIO_4 1.8
130 SWB1 CONN16 CH0 PVDD1V5_0 1.5
131 SWB1 CONN16 CH1 P1V8_4 1.8 1.816
132 SWB1 CONN16 CH2 PVDD3_3V_SYNTH_LDO_B5 3.3 3.38
133 SWB1 CONN16 CH3 PVDD3_3V_SYNTH_LDO_A5 3.3 3.38
134 SWB1 CONN16 CH4 PVDD3_3V_SYNTH_LDO_B4 3.3 3.38
135 SWB1 CONN16 CH5 PVDD3_3V_SYNTH_LDO_A4 3.3 3.38
136 SWB1 CONN16 CH6 P3V3 3.3 3.327
137 SWB1 CONN16 CH7 PVDD0_8V_T3 0.8 0.82
138 SWB1 CONN16 CH8 P0V75_DVDD_1 0.75
139 SWB1 CONN16 CH9 P0V75_AVDD_1 0.75 0.756
140 SWB1 CONN16 CH10 P1V5_AVDD_1 1.5 1.524
141 SWB1 CONN16 CH11 P0V9_AVDD_1 0.9 0.915
142 SWB1 CONN16 CH12 PVDD0V9_0 0.9 0.915
143 SWB1 CONN16 CH13 PVDD0V9_1 0.9 0.91
144 SWB1 CONN16 CH14 PVDD0V9_3 0.9 0.915
145 SWB1 CONN16 CH15 PVDD1V2_T3 1.2 1.224
+59
View File
@@ -0,0 +1,59 @@
# v1.0.11 — Saving the margin settings to NVM is now one command, and the command is correct
## ✨ New features
**`margin_save blanton` — all 18 LTC2977 in one go**
* On this platform the CB FPGA's I2C channels are also exposed as ordinary Linux i2c buses, so every margin controller on the box — CB and both switch boards — can be reached with plain `i2cset`. `margin_save blanton` walks all 18 of them from one flat list: no `margin_init`, no FPGA channel setup, no `pcimem`.
* The channel-to-bus mapping it relies on (F3 Ch6 → bus 13, Ch7 → 14, Ch8 → 15, Ch9 → 16; CB is bus 4 as before) is now written down in `ARCHITECTURE.md` and the margin README, not just known at the bench.
* **A partly-populated DUT is a normal build.** Comment out the lines you do not have in `MARGIN_BLANTON_STORE` at the top of `margin.sh` rather than letting the tool talk to boards that are not there.
* Missing bus and unresponsive chip are reported as two different failures. `/dev/i2c-16 does not exist` means the FPGA's i2c adapters did not enumerate; `i2cset failed (NACK/busy)` means the board is absent or the address is wrong. Chasing the second when you have the first wastes an afternoon.
**`margin_save all` — every board in `settings/`**
* Runs `margin_init` + `margin_save` across all nine boards, then puts back whichever board you had loaded, so a following `margin_status` still reports the board you were looking at.
* It does not stop at the first failure: a half-saved set is harder to reason about than a fully-attempted one. The summary names the boards that failed.
Both print a per-chip line and a `N saved, M failed` tally, and both return a non-zero exit code when anything failed.
**The fans now default to full speed**
* `FAN_SPEED` in `config.ttl` is 100 instead of 30. A soak is a thermal test of everything *except* the cooling, so the cooling should not be a variable in it — and a DUT that throttles halfway through a run produces results that look like a different fault. Lower it deliberately if quiet operation is what you are measuring.
## 🐛 Bug fixes
**A failed NVM write still reported success**
* `margin_save` discarded the result of every write, so a NACK printed `Change Saved` exactly like a successful store. For the one operation in this tool that is permanent, that is the worst place to stay quiet. Each store is now checked and named if it fails.
**`STORE_USER_ALL` was sent with a data byte it should not have**
* The command went out as `0x15` followed by a dummy `0x00` — an SMBus write-byte, where `STORE_USER_ALL` is a send-byte. The LTC2977 tolerated it, but tolerance is not correctness. It is now `i2cset ... 0x15 c` on the native path and a no-data `cb_pmbus_write` on the FPGA path.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.0.11.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`mgmt_ping_monitor.sh` and `port_prbs_monitor.sh` launch their workers through `bash`, so those two run without the execute bit. `bmc_monitor.sh` and `usb_target.sh` still need it, and neither git (mode 100644) nor a Windows/USB copy carries it. Without the `chmod`, `start` fails with `Permission denied` and the later `cat` finds nothing: **the section ends up empty and nothing reports an error.**
## ⚠️ Before you run
* **`margin_save` in any form writes NVM permanently.** A power cycle does not undo it. `margin_save all` and `margin_save blanton` do it to all 18 controllers at once. Run `margin_status_all.sh` first and never call any of them during a test run — the macros do not, and should not be made to.
* **The 18 raw commands were verified on the DUT; the wrapper was not.** `margin_save blanton` issues exactly the sequence that was run by hand at the bench, and the packaging was tested against stubbed hardware, but the function itself has not been run on a DUT yet. Watch the per-chip lines the first time.
* **Declare the switch population.** `SWB_UNIT0` / `SWB_UNIT1` in `config.ttl` say which switch units this DUT has; traffic and the readiness gate both follow them.
* **`FAN_SPEED` is now 100.** It is applied at the start of every run, so this build runs the fans flat out unless you change `config.ttl`. Expect the noise.
* **Management connectivity is in use, not preserved.** Both management NICs are up and pinging — drive the run from the serial console.
* **PRBS is still not wired into the macros.** Run `port_prbs_monitor.sh` by hand if you want it; the calls in A/B/C remain commented out.
* **Two settings persist to `config_db.json`** and survive a reboot: LLDP is left disabled and the 100G uplinks are left configured. Restore them before the DUT moves on.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
* [LTC2980_Margin_Script/README.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/src/Script_ABC_Blanton/Blanton_Script/LTC2980_Margin_Script/README.md) — the three `margin_save` variants and what each one sends
**Full changelog:** [V1.0.10...V1.0.11](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.0.10...V1.0.11)
+81
View File
@@ -0,0 +1,81 @@
# v1.1.0 — BER, power under load, and a 100G port that actually keeps sending
## ✨ New features
**Whole-switch SerDes BER sweep**
* New `blanton_ber.sh` runs PRBS across every cabled port and reports the bit error rate lane by lane. `init``start` → wait → `report``stop``clear`, with `-u 0` / `-u 1` for a single switch unit.
* **A lane passes only when its BER is below 1e-6.** Equal to the threshold is a FAIL, not a pass. `-c <ber>` sets a different bar.
* `report` ends with a summary across both units, and each unit's row carries its **worst lane** — so a run where everything passes still tells you how much margin there was:
```
Unit LANES PASS FAIL NA WORST BER WORST LANE RESULT
unit 0 432 432 0 0 1.98e-08 203[0] PASS
unit 1 432 432 0 0 6.34e-10 366[1] PASS
```
* `init` also checks that every lane locked. This matters: an unlocked lane still reports a BER later, and it is a meaningless one. Without the check, a dead lane can report a beautiful number and pass.
* A lane whose reading is not a number is `NA` — counted separately from `FAIL`, because "not measured" and "measured and bad" are different problems.
* Script C runs the sweep after the traffic report, following `SWB_UNIT0` / `SWB_UNIT1` the same way the traffic block does.
**TR518 load test, for measuring power under traffic**
* New `blanton_tr518.sh` puts the cd ports in loopback and runs the built-in `tr 518` packet test, then waits `TR_SETTLE_SEC` (120s by default) before handing back — so the power figures you take afterwards are loaded and settled, not caught mid-ramp.
* `-u 0` / `-u 1` for one unit; no flag runs both.
* `stop` sends `port cd lb=none` and nothing else, which is exactly what the bench procedure does. **L2 learning and test mode are left as `start` set them** — the tool says so on every `stop` rather than quietly leaving the box in a state you did not ask about. `TR_RESTORE_LEARN=1` / `TR_RESTORE_TESTMODE=1` if you want a true inverse.
**Per-rail power readback for both switch boards**
* `TH6_SWB0_power_readback.sh` / `TH6_SWB1_power_readback.sh` report V × I and total power for the 19 rails on each board.
## 🐛 Bug fixes
**The power readback measured every rail at a different moment**
* It ran `show platform voltage` and `show platform current` once *per rail* — 38 invocations of a slow CLI, and 38 different instants. Under load the currents move a lot (`TH6_CORE` was seen going from 186 A to 636 A), so the "total" was a sum of readings taken seconds apart. Both tables are now read once, up front. Same output, one moment.
* A rail missing from the sensor table used to contribute a silent `0.000 V / 0.00 W` to the total. It now says so on stderr; the printed report format is unchanged.
**The 100G port stopped sending after one round trip**
* `ce0` has no loopback partner, and a switch never forwards a frame back out the port it arrived on — so a `tx` burst went out, came back, and was dropped. TX 100, RX 100, silence. That measures the link; it does not exercise it.
* `init` now sets an ingress mirror of `ce0` back to itself. The mirrored copy is not egress-filtered, so each packet keeps lapping and the load is set by how much you inject (`-tx`). **`stop` is what ends it** — removing the VLAN membership does not, because the mirrored copy never consulted the VLAN.
**The 100G verdict was being decided the wrong way**
* `ce0` was treated as a cross-unit check. The bench says otherwise: there is one `ce0` per unit and a burst sent on unit 0 alone came back on unit 0. It is now judged within its own unit. The distinction is invisible while everything works and decisive when it does not — read as cross-unit, *both* links dying still leaves `unit0.TX == unit1.RX` (0 == 0) and reports PASS.
**Every BER lane reported `NA`, and the Port column printed `NA` too**
* `bcmcmd` returns CRLF, and the BER is the last token on its line, so the carriage return stayed glued to the number: it failed the numeric check, and printing it sent the cursor back to column 1 so the RESULT column overwrote the start of the row. Both symptoms, one stray `\r`.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.0.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh` is invoked by Script C as `./Blanton_Script/blanton_ber.sh`, so it joins `bmc_monitor.sh` and `usb_target.sh` in needing the execute bit — and neither git nor a Windows/USB copy carries it reliably. Without the `chmod` the BER section fails with `Permission denied` and the log simply has no BER in it.
## ⚠️ Before you run
* **These three tests cannot share the switch.** `blanton_ber.sh`, `blanton_tr518.sh` and `blanton_traffic_linespeed` all take over port loopback and L2 learning. Run one at a time; Script C already orders BER after the traffic report.
* **PRBS takes the links down.** While `blanton_ber.sh` is armed the ports report DOWN and no traffic passes. That is the test working, not a fault. `clear` releases them.
* **`ce0` keeps running until you stop it.** If a run is interrupted between `start` and `stop`, the 100G port stays saturated with nothing in `show interfaces status` to hint at it. `blanton_traffic_linespeed stop` (or `bcmcmd -n <u> -c 'mirror port ce0 Mode=Off'`) ends it.
* **Two numbers must stay in step**: Script C's `sleep 30` and `blanton_ber.sh`'s `BER_INTERVAL`. Change one without the other and `report` reads an interval that has not finished accumulating — with no warning.
* **`FAN_SPEED` is 100.** This build runs the fans flat out unless you change `config.ttl`.
* **Declare the switch population** with `SWB_UNIT0` / `SWB_UNIT1`; traffic, the readiness gate and now the BER sweep all follow it.
* **PRBS on the two 100G uplinks (`port_prbs_monitor.sh`) is still not wired into the macros.** Unchanged from v1.0.9.
## 🔬 Not yet verified on hardware
Three things in this build were reasoned out rather than measured, and each has a one-command check:
* **The `ce0` ingress mirror.** `mirror port ce0 Mode=Ingress DestPort=ce0` should make the port circulate, but the hardware may refuse a mirror destination equal to its source. Check `show c | grep POK.ce0` twice ten seconds apart — the number must climb. The report cannot tell you: a one-shot burst is also `TX == RX` and also says PASS. Fallback is `tr 518 PortList=268`.
* **The 120s settle in `blanton_tr518.sh`.** If `tr 518`'s traffic is time-limited (its parameters include `runtime=1`, `CheckDataTime=200`), waiting 120s could mean measuring after the load has already dropped. Compare a power readback at 0s, 30s and 120s.
* **`test mode nr=no`** in `blanton_tr518.sh` is the derived inverse of the `nr=yes` that `start` sends; it is not part of the bench-verified sequence, and is off by default.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.0.11...V1.1.0](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.0.11...V1.1.0)
+42
View File
@@ -0,0 +1,42 @@
# v1.1.1 — A run no longer inherits the last one's leftovers
## 🐛 Bug fixes
**A previous run's jobs and session survived into the next one**
* Script A now clears the box before it starts: `hw-test-session finish`, `bgctl reset --yes`, `bgctl stop --all`, then `bgctl list` so you can see it came back empty.
* This matters after a run that ended badly — a closed Tera Term window, a DUT reboot mid-soak, a macro stopped by hand. The stress jobs kept running and the session stayed open, so the next run started on a box that was already loaded. Nothing failed; the numbers were just quietly wrong, and the only hint was a `bgctl list` nobody was reading.
* The `bgctl list` at the end is the point of the sequence, not decoration: it is the one line in the log that proves the DUT was idle when the run began.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.1.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh` is invoked by Script C as `./Blanton_Script/blanton_ber.sh`, so it needs the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — and neither git nor a Windows/USB copy carries it reliably. Without the `chmod` the BER section fails with `Permission denied` and the log simply has no BER in it.
## ⚠️ Before you run
* **`hw-test-session finish` at the start will complain if no session is open.** That is expected on a fresh DUT and does not stop the run.
* **These three tests cannot share the switch.** `blanton_ber.sh`, `blanton_tr518.sh` and `blanton_traffic_linespeed` all take over port loopback and L2 learning. Script C already orders BER after the traffic report.
* **PRBS takes the links down** while `blanton_ber.sh` is armed. That is the test working, not a fault.
* **`ce0` keeps running until you stop it.** If a run is interrupted between `start` and `stop`, the 100G port stays saturated with nothing in `show interfaces status` to hint at it.
* **Two numbers must stay in step**: Script C's `sleep 30` and `blanton_ber.sh`'s `BER_INTERVAL`.
* **`FAN_SPEED` is 100** — the fans run flat out unless you change `config.ttl`.
* **Declare the switch population** with `SWB_UNIT0` / `SWB_UNIT1`.
* **PRBS on the two 100G uplinks (`port_prbs_monitor.sh`) is still not wired into the macros.**
* **The three items listed as unverified in v1.1.0 are still unverified**: the `ce0` ingress mirror, the 120s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop. See [v1.1.0](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/releases/tag/V1.1.0) for the one-command check on each.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.1.0...V1.1.1](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.0...V1.1.1)
+63
View File
@@ -0,0 +1,63 @@
# v1.1.2 — NFC tag reads are now watched for the whole soak, not sampled once
## ✨ New features
**Background NFC polling**
* New `nfc_polling.sh` runs `blantons_nfc_validate.py` over and over in the background and keeps score. `start` / `stop` / `status` / `tail` / `report` / `clear` / `fg`.
* **`report` works while the poll is still running.** It only reads the log, so it never disturbs the run — and it labels itself `RUNNING` so a mid-soak snapshot is not mistaken for the final answer:
```
state : RUNNING (pid=2240323) -- this is a snapshot, the count is still moving
rounds : 240
PASS : 238
FAIL : 2
ERROR : 0 (tool did not produce a verdict)
RESULT : FAIL
--- tags seen ---
046F7BD2142290 238
```
* **`ERROR` is counted apart from `FAIL`.** A round where the tool printed neither `[PASS]` nor `[FAIL]` — it crashed, the file was missing, it hung past the timeout — did not measure anything. That is a different problem from a tag that would not read, and rolling the two together hides whichever one you are not looking for.
* `report` also lists which NFCID1s were seen and how often, and the last ten failures with their timestamps and reasons.
* `start` clears the log first, so a report always describes the run you just did rather than everything since the DUT was built.
* Script A takes a 30-second NFC baseline, Script B starts the poll for the soak, Script C stops it with the other monitors and reports.
## 🐛 Bug fixes
**The NFC log never reached the USB stick**
* Script C copied `nfc_polling.log`; the file is `nfc_poll.log`. The `cp` failed, nothing checked it, and the run finished looking fine — you would only notice back at the desk with a job archive that had no NFC log in it.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.2.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh` and `nfc_polling.sh` are invoked by the macros through `./` or `~/`, so they need the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — neither git nor a Windows/USB copy carries it reliably. `blantons_nfc_validate.py` does **not** need it: `nfc_polling.sh` calls it through `python3` precisely so one more `chmod` cannot be forgotten.
## ⚠️ Before you run
* **`nfc_polling.sh start` clears the log.** Script B starts a fresh poll for the soak, which wipes Script A's baseline log — the baseline numbers are already in the master console log by then, but the file is gone.
* **NFC log path is `~/Blanton_Script/log/nfc_poll.log`** and it is copied into the job directory by Script C for the USB archive.
* **These three tests cannot share the switch.** `blanton_ber.sh`, `blanton_tr518.sh` and `blanton_traffic_linespeed` all take over port loopback and L2 learning. Script C already orders BER after the traffic report.
* **PRBS takes the links down** while `blanton_ber.sh` is armed. That is the test working, not a fault.
* **`ce0` keeps running until you stop it.** An interrupted run leaves the 100G port saturated with nothing in `show interfaces status` to hint at it.
* **Two numbers must stay in step**: Script C's `sleep 30` and `blanton_ber.sh`'s `BER_INTERVAL`.
* **`FAN_SPEED` is 100** — the fans run flat out unless you change `config.ttl`.
* **Declare the switch population** with `SWB_UNIT0` / `SWB_UNIT1`.
* **PRBS on the two 100G uplinks (`port_prbs_monitor.sh`) is still not wired into the macros.**
* **The three items listed as unverified in v1.1.0 are still unverified**: the `ce0` ingress mirror, the 120s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop. See [v1.1.0](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/releases/tag/V1.1.0) for the one-command check on each.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.1.1...V1.1.2](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.1...V1.1.2)
+59
View File
@@ -0,0 +1,59 @@
# v1.1.3 — Margin now measures against what this platform actually runs at
## ✨ New features
**Per-CONN margin profiles for the switch boards**
* `combo_SWB_CONN13_high` / `_low` through `combo_SWB_CONN16_high` / `_low` replace the old `comboA` / `comboB` pair. Each file's per-channel percentages follow the rails on *that* board, so a CONN13 profile is no longer a rough fit for CONN16.
* SWB0 and SWB1 share a profile per CONN — the two boards carry identical rails and differ only by I2C bus.
* A high pass and a low pass are now the same run with `_high` swapped for `_low`.
* **A profile applied to the wrong CONN margins the wrong rails and says nothing.** The percentages are positional, so nothing detects the mismatch. `margin_apply_profile_all.sh` now names the right profile per board instead of one name for all nine.
## 🐛 Bug fixes
**`VNOM` was the spec value, not what the rails actually sit at**
* 86 of the 144 channels moved up between +0.8% and +2.5% to the measured median for this platform — `PVDD3_3V_SYNTH_LDO_*` 3.3 → 3.38, `P0V9_AVDD_*` 0.9 → 0.915, `PVDD0_8V_T3` 0.8 → 0.82, and so on.
* **This is not a display change.** `VNOM` is the denominator of `margin_status`'s deviation %, *and* the basis `margin_set` derives high / low / OV / UV from. A rail sitting steady at 0.756 V used to read `+0.80%` against a nominal 0.75 and now reads `0.00%`; and asking for `+3%` now lands on a different absolute voltage than it did last week.
* **Margin logs from before and after this build cannot be compared directly.** The numbers moved because the reference moved, not because the hardware did.
**The batch profile script pointed at files that no longer exist**
* `margin_apply_profile_all.sh` still named `comboA` for all nine boards. With `comboA.conf` removed, every board would have stopped at `Profile not found` — a nine-line wall of errors on a script that is normally left to run.
**The channel map CSV was stale**
* `docs/LTC2980_channel_map.csv` is generated from `settings/*.conf`, so all 86 changed rails were wrong in it. Regenerated with `tools/gen_channel_map.sh`. It is output, not source — regenerate it, never hand-edit it.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.3.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh` and `nfc_polling.sh` are invoked by the macros through `./` or `~/`, so they need the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — neither git nor a Windows/USB copy carries it reliably.
## ⚠️ Before you run
* **Re-baseline your margin expectations.** Any pass/fail limits or golden logs derived from the old `VNOM` values need redoing against this build.
* **`margin_save` in any form writes NVM permanently** and now writes margin windows derived from the new reference. Run `margin_status_all.sh` first and never call it during a test.
* **SWB profiles are per-CONN.** Applying `combo_SWB_CONN13_high` to a CONN16 board is silently wrong.
* **These three tests cannot share the switch**: `blanton_ber.sh`, `blanton_tr518.sh` and `blanton_traffic_linespeed`.
* **PRBS takes the links down** while `blanton_ber.sh` is armed.
* **`ce0` keeps running until you stop it.**
* **Two numbers must stay in step**: Script C's `sleep 30` and `blanton_ber.sh`'s `BER_INTERVAL`.
* **`FAN_SPEED` is 100** — the fans run flat out unless you change `config.ttl`.
* **`nfc_polling.sh start` clears the log**, so Script B wipes Script A's NFC baseline file (the numbers are already in the console log).
* **The NFC tool is written for the customer's tag.** It polls Type A / B / F only and parses Type A strictly; a tag of another technology is never discovered and fails as `no RF interface activation notification received`. Without `--expected-id` it does not check identity, so a different tag of the same type still passes.
* **The three items listed as unverified in v1.1.0 are still unverified**: the `ce0` ingress mirror, the 120s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
* [LTC2980_channel_map.csv](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/docs/LTC2980_channel_map.csv) — all 144 margin channels with the new `VNOM`
**Full changelog:** [V1.1.2...V1.1.3](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.2...V1.1.3)
+61
View File
@@ -0,0 +1,61 @@
# v1.1.4 — A thermal and safety run that loads the box and watches the rails
## ✨ New features
**`4_Blanton_Script_thermal_safety.ttl`**
* A **standalone** script — it is not part of the A → B → C chain and is not started by any of them. Run it on its own when the question is thermal or safety rather than functional.
* Brings the DUT up the same way Script A does (login, session reset, fan speed, `wait_init`, DUT inventory, BMC, PCIe error clear, `pcie_bus`, PMON, dmesg), then loads it: `mlucas-avx2 -cpu 0:15` in the background and `blanton_tr518.sh start` on the data plane.
* Then loops every minute: platform data, **both switch boards' rail power** via `TH6_SWB0/1_power_readback.sh`, and `bgctl list` / `jobs`. That is the point of the script — power per rail under sustained full load, sampled over hours.
* **It has no teardown.** When you interrupt it the DUT is still in `port cd lb=mac`, `l2 learn off` and `test mode nr=yes`, and `mlucas-avx2` is still running. Run `blanton_tr518.sh stop` and `kill $(jobs -p)` before anything else uses the box — nothing in `show interfaces status` reveals the leftover state.
* **It cannot share a DUT with Script B.** Both take over the `cd` ports.
**Test flow diagram**
* `docs/Blanton_Test_Flow.drawio` draws all four scripts side by side, with the config flags that change each step marked, the one real `goto` in Script B drawn, and the manual handoffs between A → B → C shown as such.
## 🐛 Bug fixes
**The soak loop spent most of its minute reading margin**
* Script B's per-round loop is meant to be a quick sample. `margin_status_all.sh` walks nine LTC2980s over I2C and dominated the round. The scan moved to Script C, which takes it once before `show uptime`.
* **The trade-off is real and worth knowing**: margin is now only measured at the start (Script A) and the end (Script C). Drift that happens *during* the soak is no longer visible.
**`hw-test-session finish` ran from inside the session's own shell**
* Script C now sends `exit` and waits for `Script done` first, so `finish` runs in the login shell that opened the session.
**The new script arrived with LF line endings**
* Every other `.ttl` in the repo is CRLF, and `.gitattributes` marks `*.ttl` as `-text` — whatever is committed is exactly what Tera Term gets. Converted to CRLF to match.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.4.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh`, `nfc_polling.sh`, `blanton_tr518.sh` and the two `TH6_SWB*_power_readback.sh` are invoked through `./` or `~/`, so they need the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — neither git nor a Windows/USB copy carries it reliably.
## ⚠️ Before you run
* **Script 4 leaves the switch loaded and looped back.** Always finish with `blanton_tr518.sh stop`. If the next test starts without it, traffic and BER results are meaningless and nothing warns you.
* **Do not run Script 4 and Script B on the same DUT.** Same ports, same L2 settings.
* **Margin is no longer sampled during the soak** — only Script A (start) and Script C (end).
* **Re-baseline your margin limits if you have not already**: `VNOM` became the measured median in v1.1.3, which moved both the deviation % and the margin window.
* **These three cannot share the switch**: `blanton_ber.sh`, `blanton_tr518.sh`, `blanton_traffic_linespeed`.
* **PRBS takes the links down** while `blanton_ber.sh` is armed.
* **`ce0` keeps circulating until you stop it.**
* **Two numbers must stay in step**: Script C's `sleep 30` and `blanton_ber.sh`'s `BER_INTERVAL`.
* **`FAN_SPEED` is 100** — relevant here more than anywhere: a thermal run at full fan is not the same test as one at 30%.
* **The three items listed as unverified in v1.1.0 are still unverified**: the `ce0` ingress mirror, the 120s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop. The settle matters most for this release — Script 4 depends on `tr 518` still driving traffic minutes after it was started.
## 🔗 Links
* [Blanton_Test_Flow.drawio](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/docs/Blanton_Test_Flow.drawio) — the four scripts side by side
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.1.3...V1.1.4](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.3...V1.1.4)
+67
View File
@@ -0,0 +1,67 @@
# v1.1.5 — The stress jobs now last the whole soak
## 🐛 Bug fixes
**USB stress ran for sixty seconds of an overnight soak**
* `qfx5252-stress-usb` was started with `--runtime 60`. It finished a minute in and the USB path sat idle for the rest of the night. Nothing failed, nothing said so, and the run looked complete.
* SSD stress had the same shape at `--runtime 3600` — one hour of a soak that usually runs far longer.
* Both are now `--runtime 86400`, and the BMC DDR memtester lost its loop count (`64M 1``64M`) so it runs until it is stopped rather than finishing one pass.
* **86400 is 24 hours, not "forever".** A soak longer than a day leaves SSD and USB dead for the remainder. Script B prints `bgctl list` every round (since v1.0.10), so the shorter list is visible there — but nothing raises an alarm.
## ✨ New features
**Multiphase VRM margin**
* New `blanton_multiphase_margin.sh` drives the multiphase controllers on both switch boards over the native i2c buses — SWB0 on `/dev/i2c-13` and `-15`, SWB1 on `-14` and `-16`. 19 rails per board, 38 in all.
* `high3` / `low3` / `comboA` / `comboB` set the voltages and report one line per rail:
```
SWB0_0V9_ANLG0 - 0.930V Configure Done
SWB0_0V75_ANLG0 - 0.775V Configure Done
...
[ OK ] high3: 38 rail(s) configured
```
* `save` commits them. It has no per-rail mapping, so it reports as one operation: `Multiphase Save All`.
* `-u 0` / `-u 1` for a single board; rails belonging to the other board are skipped and counted separately, not failed.
* **`save` writes NVM permanently** (PMBus `STORE_USER_ALL`, and `0x17` on the TH6 core rail). A power cycle does not undo it.
* **These are not the LTC2980s that `margin.sh` drives.** The two tools reach the same rails from different sides and each assumes it is the only writer. There is no interlock — do not run both.
**Traffic bursts carry a random pattern**
* `blanton_traffic_linespeed` v0.7.0 appends `PatternRandom=yes` to every `tx`, `ce0` included. A fixed pattern can sit on a benign bit sequence for an entire run; a changing one is what makes a weak lane show itself.
* `-r no` forces the fixed pattern; `-r ""` leaves the argument off entirely, which is the pre-v0.7.0 wire format if a future SDK rejects it.
* Defaults change from `tx 100 length=512` to `tx 200 length=324`.
* **Counter totals are not comparable across this build**: 64800 bytes per burst instead of 51200, about 27% more. The PASS/FAIL cross-check compares a pair against each other and is unaffected — only absolute figures moved.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.5.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh`, `nfc_polling.sh`, `blanton_tr518.sh`, `blanton_multiphase_margin.sh` and the two `TH6_SWB*_power_readback.sh` are invoked through `./` or `~/`, so they need the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — neither git nor a Windows/USB copy carries it reliably.
## ⚠️ Before you run
* **A soak longer than 24 hours needs the runtimes raised.** `--runtime 86400` is a ceiling; past it, SSD and USB are idle and only a shorter `bgctl list` hints at it.
* **`blanton_multiphase_margin.sh save` is permanent.** Read the rails back before committing, and never run it during a test.
* **Do not mix `blanton_multiphase_margin.sh` and `margin.sh`** — same rails, two different access paths, no interlock.
* **Traffic counters changed scale.** Any absolute thresholds taken from earlier logs need redoing.
* **Script 4 (thermal/safety) has no teardown** — finish with `blanton_tr518.sh stop` and `kill $(jobs -p)`.
* **These three cannot share the switch**: `blanton_ber.sh`, `blanton_tr518.sh`, `blanton_traffic_linespeed`.
* **Margin is only sampled at the start and end of a soak** (since v1.1.4), not during it.
* **`FAN_SPEED` is 100** — the fans run flat out unless you change `config.ttl`.
* **The three items listed as unverified in v1.1.0 are still unverified**: the `ce0` ingress mirror, the 120s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop.
## 🔗 Links
* [Blanton_Test_Flow.drawio](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/docs/Blanton_Test_Flow.drawio) — the four scripts side by side
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
**Full changelog:** [V1.1.4...V1.1.5](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.4...V1.1.5)
+74
View File
@@ -0,0 +1,74 @@
# v1.1.6 — The PDB bricks were never being asked the right question
## 🐛 Bug fixes
**Every PDB reading was `NA`, and the cause was a page number written in the wrong base**
* The four ADPM12200 bricks put each measurement on its own PMBus PAGE, and the page has to be written before every read. The bring-up spreadsheet listed those page numbers in decimal but with an `0x` prefix, so four of the five selected the wrong page:
| Reading | Datasheet PAGE | Should send | Spreadsheet said |
|---|---|---|---|
| Vin | 9 | `0x09` | `0x00` |
| Iin | 10 | `0x0A` | `0x10` |
| Vout | 2 | `0x02` | `0x02` ✅ |
| Iout | 14 | `0x0E` | `0x14` |
| Temp | 18 | `0x12` | `0x18` |
* Only Vout worked — because 2 reads the same in either base. That is why Iin and Iout answered `0xFFFF` and the temperature answered `0x0000`, and why a Vin scaling had to be invented to make 50 V appear.
* `blanton_pwr_data.sh` sends no page at all (its PDB table has `page "-"`), which is the reason it reports the whole PDB section as `NA`.
## ✨ New features
**`pwr_brick.sh` — the five power bricks, read properly**
* `show` prints Vin / Iin / Vout / Iout / Temp for all five: `SWB0.PU207` (0x62), `SWB0.PU13` (0x63), `SWB1.PU332` (0x60), `SWB1.PU85` (0x61) and `CPB.PU37` (0x26). `-r` adds the raw words.
* Conversions come from the datasheet's DIRECT equation, `X = (1/m)(Y × 10⁻ᴿ b)`, with Table 3's coefficients: voltage `Y × 8 mV`, current `Y × 0.04 A`, temperature `Y × 0.01 °C`.
* **Cross-checked, not assumed**: `READ_VOUT` returns `0x05D4` → 1492 × 8 = 11936 mV, which is exactly the figure `show platform voltage` reports for that rail from a completely separate sensor path.
* `CPB.PU37` is a different part — no page writes and its own scaling — and is handled separately.
* The datasheet is now in the repo (`docs/ADPM12200CMLZxx_DS_*.pdf`) so the pages and coefficients can be checked without hunting for it.
**Every value is validated before it is printed**
* This bus corrupts the **high byte only**. That turns `11.98 V` into `32.00 V` — positive, plausible in magnitude, and invisible to any "reject 0xFFFF" filter. Each value is re-read (up to `PB_TRIES`, default 8) until it is not `0xFFFF`, not `0x0000`, and lands inside a plausibility window.
* `0x0000` is rejected as a raw word for the same reason: on the temperature register it decodes to a perfectly believable 0 °C.
**Complementary margin profiles per board**
* `comboA` / `comboB` for CB and each SWB CONN. `comboB` is `comboA` with every direction flipped, so running both covers each rail high and low while its neighbours sit the other way.
* NC channels stay at `nominal` in both — there is nothing to margin on an unused rail (CONN14 CH10/11/13, CONN15 CH10).
**The BMC USB service log is captured again — to a file**
* Script C's `journalctl` dump had been commented out, so that service log reached nothing at all. It now runs with `-o short-iso` into `log/bmc_usb_net.log` and is copied into the job directory for the USB archive. The ISO timestamps line up with the other monitor logs, and `rm -f` first keeps the file to one run.
* **It is no longer printed to the console**, so the USB copy is the only copy. If that `cp` fails — and nothing checks it — the service log is gone. Check the job directory before packing up.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.6.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh`, `nfc_polling.sh`, `blanton_tr518.sh`, `blanton_multiphase_margin.sh`, `pwr_brick.sh` and the two `TH6_SWB*_power_readback.sh` are invoked through `./` or `~/`, so they need the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — neither git nor a Windows/USB copy carries it reliably.
## ⚠️ Before you run
* **`READ_VIN` and `READ_IIN` are not in the datasheet's coefficient table.** They are decoded here with the voltage and current coefficients — consistent with a ~50 V input, but not stated by the datasheet. Anything quoting brick Vin should have that confirmed first. `PB_VIN_M` / `PB_IIN_M` are where to change it.
* **The BMC USB service log only exists on the USB stick.** It is not in the master console log any more.
* **`NA` has two meanings**: nothing readable, or read but outside its plausibility window. Use `PB_TRIES=1 ./Blanton_Script/pwr_brick.sh show -r` to see the unretried raw words and tell them apart.
* **Margin profiles are positional.** `comboA_SWB_CONN13` applied to a CONN16 board margins the wrong rails and nothing detects it.
* **`blanton_multiphase_margin.sh save` is permanent**, and it must not be mixed with `margin.sh` — same rails, two access paths, no interlock.
* **A soak longer than 24 hours needs the stress runtimes raised** — `--runtime 86400` is a ceiling.
* **Script 4 (thermal/safety) has no teardown** — finish with `blanton_tr518.sh stop` and `kill $(jobs -p)`.
* **These three cannot share the switch**: `blanton_ber.sh`, `blanton_tr518.sh`, `blanton_traffic_linespeed`.
* **`FAN_SPEED` is 100.**
* **The three items listed as unverified in v1.1.0 are still unverified**: the `ce0` ingress mirror, the 120s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
* [Blanton_Test_Flow.drawio](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/docs/Blanton_Test_Flow.drawio) — the four scripts side by side
**Full changelog:** [V1.1.5...V1.1.6](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.5...V1.1.6)
+73
View File
@@ -0,0 +1,73 @@
# v1.1.7 — A way back from a margin, and a reboot cycle that runs itself
## ✨ New features
**`blanton_multiphase_margin.sh normal` — put the rails back without a power cycle**
* `normal` returns all 38 multiphase rails to their nominal set point, with the same per-rail reporting as the margin profiles (`SWB0_0V9_ANLG0 - 0.930V Configure Done`). `-u 0|1|all` as usual.
* Until now the only way out of a margin was to power-cycle the DUT. That mattered more than it sounds: `save` run while the board was still margined would have written the offsets into NVM, where a power cycle does not help either.
* The commands it sends are in `tools/Multiphase_Normal.txt` for anyone driving the bench by hand.
> ⚠️ `TH6_CORE` is 0.8 V nominal but settles near **0.8591 V** once the load line is active. Reading back 0.859 after `normal` is the load line doing its job, not a failed write.
**`5_Blanton_Script_Reboot_Cycle.ttl` — an unattended reboot-cycle run**
* A standalone macro, like Script 4: it does **not** chain to A → B → C and does not use `hw-test-session`. Every cycle is a fresh boot, so there is nothing to carry over and nothing to tear down.
* Each round: login → `sudo -i` → `date -s` → fan speed → `wait_init` → **Check Pt1 … Pt13** → `show uptime``reboot` → wait for the next boot. The cycle number is printed in the banner of every round.
| | | | |
|---|---|---|---|
| **Pt1** DUT info | **Pt2** BMC info + tools | **Pt3** mgmt ping | **Pt4** NFC poll |
| **Pt5** SSD stress | **Pt6** USB stress | **Pt7** BMC USB net | **Pt8** port status + 15 s traffic |
| **Pt9** BER sweep | **Pt10** NVMe errors | **Pt11** platform data | **Pt12** dmesg i2c |
| **Pt13** PCIe error counters | | | |
* The USB step takes its device node from `usb_target.sh`, not a hard-coded `/dev/sda1`.
**The SSD and USB stress durations are declared in `config.ttl`**
* `SSD_RUNTIME` / `SSD_COUNT` and `USB_RUNTIME` / `USB_COUNT` replace the values that were hard-coded in Script B, so a site changes them in one place. `COUNT` is passed straight through as `--passes`.
## 🐛 Bug fixes
**Script B left the global `timeout` at 15 s for the rest of the cdc_ncm section**
* The NCM probe sets `timeout = 15` and restored it only at `:skip_ping` — which the *success* path reaches several `wait`s later. Until then every `wait` gave up after 15 s instead of blocking, and a `wait` that returns without eating the prompt puts the whole macro a beat ahead of the DUT. It is now restored on the success path too.
**`goto skip_ping` in the reboot-cycle macro had no label to jump to**
* The probe was copied out of Script B without its `:skip_ping` label. Tera Term does not check labels when it loads a macro — it raises the error only when it actually jumps, which here means only when the NCM interface is missing. The failure mode was an error dialog stopping the whole cycle, on the one run where something was already wrong. The label is there now, and the `timeout` is restored **before** the branch so one line covers both paths.
**Two check points both numbered 12**
* `Dmesg_i2c` and `PCIE Error Counters` both announced themselves as `Check Pt12`. The second is now `Pt13`; Pt1 … Pt13 are unique.
## 📦 Downloads
| File | Contents |
|---|---|
| `Script_ABC_Blanton_V1.1.7.zip` | The full Tera Term working directory, including `Blanton_Script/` to copy onto the DUT |
**After copying to the DUT:**
```bash
chmod +x ~/Blanton_Script/*.sh # see below
grep -rlU $'\r' ~/Blanton_Script # expect no output
```
`blanton_ber.sh`, `nfc_polling.sh`, `blanton_tr518.sh`, `blanton_multiphase_margin.sh`, `pwr_brick.sh` and the two `TH6_SWB*_power_readback.sh` are invoked through `./` or `~/`, so they need the execute bit along with `bmc_monitor.sh` and `usb_target.sh` — neither git nor a Windows/USB copy carries it reliably.
## ⚠️ Before you run
* **`--runtime` is the job's overall limit, not a per-pass one.** `qfx5252-stress-*` stops after `RUNTIME` seconds whatever `--passes` says, so `SSD_RUNTIME=600` is a **10 minute** stress, not 600 × `SSD_COUNT`. For a 24 hour soak set `RUNTIME` to `86400`. The shipped defaults are 600.
* **Script 5 has not been run on hardware yet.** Two things to confirm on the bench: that `wait "Booting in blind mode"` really appears in this build's boot output — it has no `timeout` guard, so a changed string waits forever — and that re-running `bmc-first-enroll` every cycle is safe.
* **Script 5 has no exit condition.** `while 1` with a `reboot` at the end of each round; stop it by closing the Tera Term macro.
* **`blanton_multiphase_margin.sh save` is permanent**, and must not be mixed with `margin.sh` — same rails, two access paths, no interlock. Never run it while the board is margined.
* **`READ_VIN` and `READ_IIN` are still not in the ADPM12200 coefficient table** — `pwr_brick.sh` decodes them with the voltage and current coefficients. Confirm before quoting brick Vin.
* **The BMC USB service log only exists on the USB stick.**
* **Script 4 (thermal/safety) has no teardown** — finish with `blanton_tr518.sh stop` and `kill $(jobs -p)`.
* **These three cannot share the switch**: `blanton_ber.sh`, `blanton_tr518.sh`, `blanton_traffic_linespeed`.
* **`FAN_SPEED` is 100.**
* **Still unverified from v1.1.0**: the `ce0` ingress mirror, the 120 s settle in `blanton_tr518.sh`, and `test mode nr=no` on stop.
## 🔗 Links
* [ARCHITECTURE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/ARCHITECTURE.md) — test flow, data models, constraints
* [CLAUDE.md](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/CLAUDE.md) — commands and the bench gotchas
* [Blanton_Test_Flow.drawio](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/src/branch/main/docs/Blanton_Test_Flow.drawio) — the scripts side by side
**Full changelog:** [V1.1.6...V1.1.7](https://etgit.et-wen.com/etwen/Blanton_TTL_Script/compare/V1.1.6...V1.1.7)
+291 -2
View File
@@ -1,7 +1,7 @@
; =============================================================================
; Script A for Blanton
; Version : V1.0.10
; Date : 2026-08-27
; Version : V1.1.7
; Date : 2026-09-04
; Author : ETWen
; =============================================================================
; Version History:
@@ -74,6 +74,273 @@
; tools/100G_PRBS.txt Bench command references, kept for hand-run debug
; tools/TR518.txt TR518 = built-in packet test (swutil / bcmcmd tr 518)
; tools/fan_ctrl.txt MAX31790 rebind + fan-speed-control.sh
; V1.0.11 2026-08-28 LTC2980_Margin_Script/margin.sh v2.7.0 - margin_save fixes + two new subcommands
; STORE_USER_ALL (0x15) is now a PMBus send-byte, not
; 0x15 followed by a dummy 0x00 data byte. The LTC2977
; tolerated the old form, but it was the wrong protocol
; i2c: i2cset .. 0x15 c swb: cb_pmbus_write <ch> <addr> 0x15
; + margin_save all - every board in settings/ (9 boards,
; 18 chips), then re-init the one loaded beforehand
; + margin_save blanton - Blanton SONiC shortcut: all 18
; LTC2977 straight over the native i2c buses - no
; margin_init, no FPGA channel setup, no pcimem
; F3 Ch6->bus 13, Ch7->14, Ch8->15, Ch9->16
; board list = MARGIN_BLANTON_STORE at the top of margin.sh
; The store result is now checked - a NACK used to still
; print "Change Saved"
; MARGIN_STORE_SETTLE (0.5s) between stores; nothing in this
; tool polls the part's busy bit
; LTC2980_Margin_Script/README.md What each margin_save variant sends, and the
; FPGA-channel -> i2c-bus map
; LTC2980_Margin_Script/Ref/*.md 0x15 trace note corrected to send-byte
; LTC2980_Margin_Script/script/margin_save_all.sh Point at margin_save all; keep it for subsets
; config.ttl FAN_SPEED 30 -> 100 (full speed by default)
; V1.1.0 2026-08-28 Blanton_Script/blanton_ber.sh Add whole-switch SerDes BER test (PRBS via phydiag)
; init / start / report / stop / clear, -u 0|1|all
; report: one row per lane, PASS when BER < 1e-6, then
; a summary across units carrying the worst lane
; init also checks every lane locked - an unlocked lane
; still reports a BER, and it is a meaningless one
; !! PRBS takes the SerDes out of normal operation:
; links show DOWN, no traffic passes while it runs
; Blanton_Script/blanton_tr518.sh Add TR518 packet test - loads the switch so the rails
; can be measured under traffic
; start [-u 0|1] then settles 120s (TR_SETTLE_SEC), so
; the power read afterwards is loaded, not ramping
; stop = port cd lb=none, exactly what TR518.txt does;
; l2 learn / test mode are NOT put back - stop says so
; Blanton_Script/TH6_SWB{0,1}_power_readback.sh Read the sensor tables ONCE, not once per rail
; 38 'show platform' calls -> 2. The old loop sampled
; each rail at a different instant, so the total was a
; sum of readings seconds apart. Output format unchanged
; A rail missing from the table now warns on stderr
; instead of silently counting as 0 W
; Blanton_Script/blanton_traffic_linespeed.sh Add the 100G uplink (ce0, VLAN 138) to the test
; ce0 has no loopback partner and a switch will not send
; a frame back out its ingress port, so a tx burst was
; one round trip. An INGRESS MIRROR of ce0 back to ce0
; keeps it circulating until stop turns the mirror off
; !! stop MUST run - the loop does not end on its own
; report: ce0 is the last row; a summary at the bottom
; carries every unit's PASS / FAIL / NA totals
; ScriptC Run the BER sweep, after the traffic report so the
; two do not fight over the same ports
; Follows SWB_UNIT0/SWB_UNIT1 like the traffic block:
; -u 0 / -u 1 / skip, so a single-unit DUT is not asked
; for counters from a board it does not have
; tools/BER_Test.txt Bench command references for the two new scripts
; tools/100G_Traffic.txt
; tools/TR518.txt Corrected on the bench: port cd (not *:port all),
; testphase=1, and an explicit stop
; V1.1.1 2026-08-28 ScriptA Clear a leftover session before starting a new run
; hw-test-session finish -> bgctl reset --yes ->
; bgctl stop --all -> bgctl list (must come back empty)
; A run that ended badly leaves jobs holding CPU and a
; session open; the next run used to inherit both, and
; the stress numbers were quietly wrong because of it
; V1.1.2 2026-08-28 Blanton_Script/nfc_polling.sh Add background NFC tag polling
; start / stop / status / tail / report / clear / fg
; wraps blantons_nfc_validate.py; start clears the log
; first, so a report covers this run only
; report works WHILE polling - it only reads the log,
; and says RUNNING so a snapshot is not read as final
; Each round appends a machine-readable RESULT line, so
; the tally never depends on the tool's wording
; PASS / FAIL come from the tool's own summary; ERROR
; means it produced neither, which is a different fault
; from a tag that would not read - counted separately
; tail does NOT follow (tail -f never returns, and a
; macro waiting on the prompt would hang there)
; Runs the .py through python3, not ./ - the file is
; mode 100644 and a USB copy carries no execute bit
; Blanton_Script/blantons_nfc_validate.py Vendor NFC/NCI validation tool (unmodified)
; ScriptA NFC baseline: start -> status -> 30s -> stop -> report
; ScriptB Start NFC polling for the soak, then status
; ScriptC Stop NFC polling with the other monitors, report it
; next to the mgmt ping log, and copy nfc_poll.log to
; the job dir for the USB archive
; Fix: that cp said nfc_polling.log - the file is
; nfc_poll.log, so the NFC log never reached the USB
; V1.1.3 2026-08-30 LTC2980_Margin_Script/settings/*.conf VNOM is now the measured median, not the spec value
; 86 of 144 rails moved up +0.8% .. +2.5%
; (3.3 -> 3.38, 0.9 -> 0.915, 0.8 -> 0.82, ...)
; This is NOT display-only: VNOM is the denominator of
; margin_status deviation % AND the basis margin_set
; derives high/low/OV/UV from, so the whole margin
; window shifts with it
; !! margin logs from before/after cannot be compared
; LTC2980_Margin_Script/profiles/ Add per-CONN SWB profiles, drop comboA/comboB
; combo_SWB_CONN13..16_{high,low} - the percentages
; follow that board rails, so applying one to a
; different CONN margins the wrong things, silently
; SWB0 and SWB1 share a profile per CONN (same rails)
; LTC2980_Margin_Script/script/*.sh Fix: margin_apply_profile_all.sh still pointed every
; board at comboA, which this change deleted - all 9
; boards would have failed with "Profile not found"
; docs/LTC2980_channel_map.csv Regenerated (tools/gen_channel_map.sh) - it is output
; V1.1.4 2026-08-31 4_Blanton_Script_thermal_safety.ttl Add the thermal / safety run - a STANDALONE script,
; not part of the A -> B -> C chain
; Script A style setup (login, session, fan, wait_init,
; DUT info, BMC, PCIe clear, pcie_bus, pmon, dmesg)
; then FULL LOAD: mlucas-avx2 -cpu 0:15 in the
; background + blanton_tr518.sh start
; then while 1: setup_pmon + TH6_SWB0/SWB1 power
; readback + bgctl list + jobs, pause 60
; !! no teardown section: after you interrupt it the
; unit is still on port cd lb=mac / l2 learn off /
; test mode nr=yes - run blanton_tr518.sh stop
; !! it drives the same ports as traffic and BER, so it
; cannot share a DUT with Script B
; ScriptB Drop the margin scan from the soak loop
; The loop is a fast per-minute sample; margin_status
; walks 9 LTC2980 over I2C and dominated the round
; ScriptC Take the margin scan instead, once, before uptime
; Trade-off: no margin drift DURING the soak any more,
; only a start (Script A) and end (Script C) reading
; ScriptC exit + wait "Script done" before hw-test-session
; finish - leaves the session shell first, so finish
; runs in the login shell that opened it
; docs/Blanton_Test_Flow.drawio Add the A/B/C + thermal flow diagram
; V1.1.5 2026-09-01 ScriptB Stress jobs now last the whole soak
; BMC DDR memtester 64M 1 -> 64M (loop count
; dropped = runs until stopped)
; SSD --runtime 3600 -> 86400
; USB --runtime 60 -> 86400
; The USB one finished after 60 SECONDS, so an
; overnight run had USB idle for all but the first
; minute and nothing said so
; !! 86400 is 24h: a soak longer than that leaves SSD
; and USB dead for the remainder - the per-round
; bgctl list (V1.0.10) is where that shows up
; Blanton_Script/blanton_multiphase_margin.sh Add multiphase VRM margin over the native i2c buses
; high3 / low3 / comboA / comboB / save, -u 0|1|all
; 38 rails (19 per SWB), one line each:
; SWB0_0V9_ANLG0 - 0.930V Configure Done
; save has no per-rail map, prints Multiphase Save All
; !! save is STORE_USER_ALL - permanent, survives a
; power cycle
; !! these are NOT the LTC2980s margin.sh drives; the
; two tools reach the same rails from different
; sides - do not run both
; Blanton_Script/blanton_traffic_linespeed.sh v0.7.0 tx gains PatternRandom, defaults change
; tx 100 length=512 -> tx 200 length=324
; every burst now ends PatternRandom=yes, ce0 included
; A fixed pattern can sit on a benign bit sequence for
; a whole run; random is what exposes a weak lane
; -r no forces the fixed pattern, -r "" omits the
; argument entirely (pre-v0.7.0 wire format)
; !! bytes per burst went 51200 -> 64800 (+27%), so
; counter totals are not comparable across this
; build - the PASS/FAIL cross-check is unaffected
; tools/Multiphase_*.txt Bench command references for the new script
; V1.1.6 2026-09-02 Blanton_Script/pwr_brick.sh Add PDB / CPB power brick readings
; 5 devices, Vin / Iin / Vout / Iout / Temp:
; SWB0.PU207 0x62 SWB0.PU13 0x63
; SWB1.PU332 0x60 SWB1.PU85 0x61
; CPB.PU37 0x26
; The four ADPM12200 put each measurement on its own
; PMBus PAGE, so a PAGE write has to precede every
; read - blanton_pwr_data.sh sends none, which is why
; it reports the whole PDB table as NA
; Vin PAGE 9 Iin PAGE 10 Vout PAGE 2
; Iout PAGE 14 Temp PAGE 18
; !! the bring-up spreadsheet wrote those page numbers
; in decimal but with an 0x prefix (10 -> 0x10,
; 14 -> 0x14, 18 -> 0x18). Only Vout worked,
; because 2 reads the same either way
; Conversions are the datasheet DIRECT equation
; X = (1/m)(Y x 10^-R - b), Table 3: voltage Y x 8mV,
; current Y x 0.04A, temperature Y x 0.01C
; Checked: READ_VOUT 0x05D4 -> 11936 mV, the same
; figure show platform reports for that rail
; !! Table 3 does NOT list READ_VIN / READ_IIN; they
; borrow the voltage / current coefficients here
; Each value is re-read until it passes: not 0xFFFF,
; not 0x0000, and inside a plausibility window. This
; bus corrupts the HIGH BYTE only, which turns 11.98 V
; into 32.00 V - a value no all-ones filter catches
; docs/ADPM12200..._Datasheet_2025_12_19.pdf The brick datasheet the pages and coefficients above
; came from
; ScriptC Re-enable the BMC USB service log, and send it to
; a file instead of the console
; journalctl ... -o short-iso > log/bmc_usb_net.log
; then cp it into the job dir for the USB archive
; rm -f first, so the file is this run only
; -o short-iso gives it timestamps that line up with
; the other monitor logs
; !! it no longer appears in the master console log,
; so the USB copy is now the ONLY copy - if that
; cp fails the service log is gone
; LTC2980_Margin_Script/profiles/ Add comboA / comboB per board (CB + SWB CONN13..16)
; Checkerboard pair: comboB is comboA with every
; direction flipped, so running both covers each rail
; high and low while its neighbours sit the other way
; NC channels stay nominal in both (CONN14 CH10/11/13,
; CONN15 CH10) - nothing to margin on an unused rail
; V1.1.7 2026-09-04 Blanton_Script/blanton_multiphase_margin.sh v1.1.0 Add the 'normal' sub-command
; Puts all 38 rails back to their nominal set point,
; from tools/Multiphase_Normal.txt - same rails and the
; same per-rail reporting as the margin profiles
; Until now the only way back from a margin was a power
; cycle, and 'save' run while margined would have
; committed the offsets to NVM, where a power cycle does
; not help either
; !! TH6_CORE is 0.8 V nominal but settles near 0.8591 V
; once the load line is active - reading back 0.859
; after 'normal' is the load line, not a failed write
; tools/Multiphase_Normal.txt Bench command reference for the above
; 5_Blanton_Script_Reboot_Cycle.ttl Created Reboot-cycle run - a STANDALONE script, not
; chained to A -> B -> C and not using hw-test-session:
; every cycle is a fresh boot, so there is nothing to
; carry over and nothing to tear down
; while 1: login -> sudo -i -> date -s -> fans -> wait_init
; -> Check Pt1..Pt13 -> show uptime -> reboot ->
; wait 'Booting in blind mode'
; cnt_cycle is printed in the banner of every round
; Pt1 DUT info (boot/version/fwutil/syseeprom/ssdhealth/
; TPM/NVMe) Pt2 BMC info + source the bash tools
; Pt3 mgmt ping Pt4 NFC poll (20 s)
; Pt5 SSD stress Pt6 USB stress (node from
; usb_target.sh, not a fixed sda1)
; Pt7 BMC USB net Pt8 100G port status + 15 s traffic
; Pt9 BER sweep Pt10 NVMe error info
; Pt11 platform data Pt12 dmesg i2c
; Pt13 PCIe error counters + ras-mc-ctl
; !! there is NO exit condition - the only way to stop it
; is to close the Tera Term macro
; !! NOT verified on hardware yet
; The cdc_ncm probe sets timeout = 15 and restores it to 0
; BEFORE the if, so both branches are covered in one line -
; the ping block below it waits on a 'sleep 10', which is
; already two thirds of the cap on a loaded DUT
; The probe was copied from Script B without its :skip_ping
; label, so 'goto skip_ping' had no target. Tera Term only
; raises that when it actually jumps, i.e. only when the
; NCM interface is missing - the label is now there
; Renumbered the second 'Check Pt12' (PCIe error counters)
; to Pt13; Pt1..Pt13 are now unique
; ScriptB Restore timeout = 0 on the cdc_ncm success path too
; It was only restored at :skip_ping, which the success
; path reaches several waits later - until then every wait
; was capped at 15 s instead of blocking
; .gitignore Ignore tmp/ - scripts not yet verified on hardware
; blanton_reboottest.sh (the bash port of the reboot cycle,
; for running without Tera Term) lives there until it has
; been run on a DUT. Unverified scripts must not reach the
; publish bundle: the tester cannot tell which ones to
; trust once they are side by side in Blanton_Script/
; config.ttl Add SSD_RUNTIME / SSD_COUNT / USB_RUNTIME / USB_COUNT
; The SSD and USB stress durations were hard-coded in
; ScriptB (--runtime 86400 --passes 5 / 1); they are now
; declared in one place per site
; !! --runtime is the job's OVERALL limit, not per pass:
; qfx5252-stress-* stops at RUNTIME seconds whatever
; --passes says. RUNTIME 600 = a 10 minute stress,
; not 600 x COUNT. For a 24 h soak set RUNTIME 86400
; ScriptB Build the SSD / USB stress commands from those knobs
; sprintf2 cmd_ssd ... SSD_RUNTIME SSD_COUNT, and the same
; for USB; the old hard-coded lines are left commented out
; next to them
; =============================================================================
include "config.ttl"
@@ -113,6 +380,16 @@ wait prompt_sonic_root
sendln "rm /host/hw-eval/jobs/*"
; ========== HW Test Session ==========
; Clear session
wait prompt_sonic_root
sendln "hw-test-session finish"
wait prompt_sonic_root
sendln "bgctl reset --yes"
wait prompt_sonic_root
sendln "bgctl stop --all"
wait prompt_sonic_root
sendln "bgctl list"
wait prompt_sonic_root
sendln "hw-test-session start"
wait prompt_sonic_root
@@ -232,6 +509,18 @@ sendln "cat ~/Blanton_Script/log/mgmt_ping.log"
wait prompt_sonic_root
sendln "~/Blanton_Script/mgmt_ping_monitor.sh clear"
; ========== NFC Test ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh start"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh status"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh stop"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh report"
; ========== 100G Port Status ==========
wait prompt_sonic_root
+14 -7
View File
@@ -26,7 +26,8 @@ sendln "~/hammer/tools/amd/mlucas-avx2 -s l -cpu 0:15 > ~/hammer/tools/amd/mluca
;wait prompt_sonic_root
;sendln "./Blanton_Script/bmc_monitor.sh start"
wait prompt_sonic_root
sendln "bgctl run bmc-manager run '/usr/bin/memtester 64M 1'"
;sendln "bgctl run bmc-manager run '/usr/bin/memtester 64M 1'"
sendln "bgctl run bmc-manager run '/usr/bin/memtester 64M'" ; Continue Execture
; ========== BMC Monitor Test ==========
wait prompt_sonic_root
@@ -39,8 +40,10 @@ wait prompt_sonic_root
sendln "bgctl run /usr/sbin/memtester 1G" ; Continue Execture
; ========== SSD read/write ==========
sprintf2 cmd_ssd "bgctl run qfx5252-stress-ssd 1G --runtime %d --passes %d --write --force --log /host/hw-eval/jobs/qfx5252-stress-ssd.log" SSD_RUNTIME SSD_COUNT
wait prompt_sonic_root
sendln "bgctl run qfx5252-stress-ssd 1G --runtime 3600 --passes 5 --write --force --log /host/hw-eval/jobs/qfx5252-stress-ssd.log"
;sendln "bgctl run qfx5252-stress-ssd 1G --runtime 86400 --passes 5 --write --force --log /host/hw-eval/jobs/qfx5252-stress-ssd.log"
sendln cmd_ssd
; ========== USB read/write ==========
; ---- Get USB partition node -> usb_dev ----
@@ -51,7 +54,8 @@ waitregex '<<DEV=([^>]*)>>'
usb_dev = groupmatchstr1
wait prompt_sonic_root
sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime 60 --passes 1 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev
;sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime 86400 --passes 1 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev
sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime %d --passes %d --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev USB_RUNTIME USB_COUNT
sendln cmd
;wait prompt_sonic_root
@@ -72,6 +76,7 @@ if result = 0 then
messagebox 'cdc_ncm interface not found. Ping test skipped.' 'ERROR'
goto skip_ping
endif
timeout = 0
strlen matchstr
cut_len = result - 6 ; 'NCMIF=' = 6 chars
strcopy matchstr 7 cut_len ncm_if ; -> ncm_if = "eth2" / "eth3"
@@ -100,6 +105,12 @@ wait prompt_sonic_root
pause 3
sendln "./Blanton_Script/mgmt_ping_monitor.sh status"
; ========== NFC Test ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh start"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh status"
; ========== 100G Port ==========
wait prompt_sonic_root
@@ -168,9 +179,5 @@ while 1
sendln "bgctl list"
wait prompt_sonic_root
sendln "jobs"
; ========== Check Margin ==========
if EN_Margin = 1 then
include "utils/show_margin_status.ttl"
endif
pause 60
endwhile
+72 -2
View File
@@ -25,6 +25,8 @@ wait prompt_sonic_root
sendln "~/Blanton_Script/mgmt_ping_monitor.sh status"
wait prompt_sonic_root
sendln "~/Blanton_Script/mgmt_ping_monitor.sh stop"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh stop"
;=============================================================================================================
; 100G PRBS STOP
@@ -76,8 +78,10 @@ wait prompt_sonic_root
sendln "cat ./Blanton_Script/log/bmc_poll.log"
; ========== BMC USB Test result ==========
;wait prompt_sonic_root
;sendln "journalctl -u qfx5252-bmc-usb-net-test.service --no-pager"
wait prompt_sonic_root
sendln "rm -f ~/Blanton_Script/log/bmc_usb_net.log"
wait prompt_sonic_root
sendln "journalctl -u qfx5252-bmc-usb-net-test.service --no-pager -o short-iso > ~/Blanton_Script/log/bmc_usb_net.log"
; ========== CHECK Stress results ==========
@@ -92,6 +96,10 @@ sendln "cat /host/hw-eval/jobs/qfx5252-stress-usb.log"
wait prompt_sonic_root
sendln "cat ~/Blanton_Script/log/mgmt_ping.log"
; ========== NFC Test result ==========
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh report"
; ========== 100G Port ==========
wait prompt_sonic_root
sendln "show interfaces status Ethernet513,Ethernet514"
@@ -120,6 +128,54 @@ else
endif
; ========== BER ==========
; PRBS takes the SerDes out of normal operation, so this runs AFTER the
; traffic report. sleep 30 matches blanton_ber.sh BER_INTERVAL - reporting
; earlier reads an interval that has not finished accumulating.
if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start -u 0"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear -u 0"
elseif SWB_UNIT0 = 0 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start -u 1"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear -u 1"
else
endif
; ========== NVME Err Info ==========
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
@@ -130,6 +186,11 @@ sendln "/usr/sbin/smartctl -x /dev/nvme0"
wait prompt_sonic_root
sendln "show reboot-cause"
; ========== Check Margin ==========
if EN_Margin = 1 then
include "utils/show_margin_status.ttl"
endif
; ========== Show Power on uptime ==========
wait prompt_sonic_root
sendln "show uptime"
@@ -150,9 +211,15 @@ sendln cmd
; ========== Copy Stress Log to USB ==========
wait prompt_sonic_root
sendln "cp ./Blanton_Script/log/bmc_usb_net.log /host/hw-eval/jobs/"
wait prompt_sonic_root
sendln "cp ./Blanton_Script/log/bmc_poll.log /host/hw-eval/jobs/"
wait prompt_sonic_root
sendln "cp ./Blanton_Script/log/mgmt_ping.log /host/hw-eval/jobs/"
wait prompt_sonic_root
sendln "cp ./Blanton_Script/log/nfc_poll.log /host/hw-eval/jobs/"
wait prompt_sonic_root
getdate ts_date "%Y%m%d"
@@ -163,6 +230,9 @@ sendln cmd
; ========== HW Test Session ==========
wait prompt_sonic_root
sendln "exit"
wait "Script done"
wait prompt_sonic_root
sendln "hw-test-session finish"
wait prompt_sonic_root
sendln "bgctl reset --yes"
@@ -0,0 +1,158 @@
include "config.ttl"
flushrecv
;================================================================
; Log File Creation
;================================================================
gettime str_starttime "%Y%m%d-%H%M%S"
getdir mdir
if EN_log = 1 then
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir project_name strTestcase str_starttime
logopen filename 0 1 1 1
endif
; ========== Root Login ==========
wait prompt_login
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd"
wait prompt_sonic
sendln "sudo -i"
; ========== Pre Setting ==========
; Make log directory
wait prompt_sonic_root
sendln "mkdir ./logs"
; Setting System Time
getdate datestr
gettime timestr
sprintf2 cmd 'sudo date -s "%s %s"' datestr timestr
sendln cmd
;Stress log clear
wait prompt_sonic_root
sendln "rm /host/hw-eval/jobs/*"
; ========== HW Test Session ==========
; Clear session
wait prompt_sonic_root
sendln "hw-test-session finish"
wait prompt_sonic_root
sendln "bgctl reset --yes"
wait prompt_sonic_root
sendln "bgctl stop --all"
wait prompt_sonic_root
sendln "bgctl list"
wait prompt_sonic_root
sendln "hw-test-session start"
wait prompt_sonic_root
sendln "hw-test-session log"
wait prompt_sonic_root
sendln "hw-test-session status"
; ========== FAN SPEED ==========
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sprintf2 fan_ctrl_cmd 'fan-speed-control.sh %d' FAN_SPEED
sendln fan_ctrl_cmd
wait "Set all configured fan channels to"
sendln "y"
; ========== Wait DUT Init ==========
include "utils/wait_init.ttl"
; ========== DUT Info ==========
wait prompt_sonic_root
sendln "show boot"
wait prompt_sonic_root
sendln "show version"
wait prompt_sonic_root
sendln "fwutil show status"
wait prompt_sonic_root
sendln "show system-memory"
wait prompt_sonic_root
sendln "show service"
wait prompt_sonic_root
sendln "show platform syseeprom"
wait prompt_sonic_root
sendln "show platform ssdhealth"
wait prompt_sonic_root
sendln "qfx5252-tpm-version"
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
; ========== BMC version ==========
;wait prompt_sonic_root
;sendln "bmc-manager run 'cat /etc/issue'"
wait prompt_sonic_root
sendln "bmc-first-enroll"
wait prompt_sonic_root
sendln "bmc-manager version"
wait prompt_sonic_root
sendln "bmc-manager status"
; ========== CLEAR PCIE Error ==========
include "utils/show_pcie_error_reg_TH6_SWB0.ttl"
include "utils/show_pcie_error_reg_TH6_SWB1.ttl"
include "utils/show_pcie_error_reg_FPGA.ttl"
include "utils/show_pcie_error_reg_BMC.ttl"
include "utils/show_pcie_error_reg_DDR.ttl"
include "utils/show_pcie_error_reg_I210.ttl"
include "utils/show_pcie_error_reg_SSD.ttl"
wait prompt_sonic_root
sendln "/usr/sbin/ras-mc-ctl --summary"
; ========== Check PCIE tree + PCIE link status + GET PCIE bandwidth Test ==========
include "utils/pcie_bus.ttl"
; ========== TAKE DATA ==========
include "utils/setup_pmon.ttl"
include "utils/show_dmesg.ttl"
; ========== Full Load ==========
; AMD CPU STRESS TEST
wait prompt_sonic_root
sendln 'chmod +x ~/hammer/tools/amd/mlucas-avx2'
wait prompt_sonic_root
sendln "~/hammer/tools/amd/mlucas-avx2 -s l -cpu 0:15 > ~/hammer/tools/amd/mlucas_amm_log 2>&1 &"
; TR518 TEST
wait prompt_sonic_root
sendln "~/Blanton_Script/blanton_tr518.sh start"
while 1
; Base info polling
include "utils/setup_pmon.ttl"
; TH6 Power Polling
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh"
wait prompt_sonic_root
sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh"
; Background jobs Check
wait prompt_sonic_root
sendln "bgctl list"
wait prompt_sonic_root
sendln "jobs"
pause 60
endwhile
@@ -0,0 +1,419 @@
include "config.ttl"
flushrecv
;================================================================
; Log File Creation
;================================================================
gettime str_starttime "%Y%m%d-%H%M%S"
getdir mdir
if EN_log = 1 then
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir project_name "Reboot_Cycle" str_starttime
logopen filename 0 1 1 1
endif
cnt_cycle = 0
while 1
cnt_cycle = cnt_cycle + 1
; ========== Root Login ==========
wait prompt_login
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd"
wait prompt_sonic
sendln "sudo -i"
wait prompt_sonic_root
sendln "sleep 10"
wait prompt_sonic_root
sprintf2 strTitle "echo -e '\033[1;32mReboot Cycle : %d \033[0m'" cnt_cycle
sendln strTitle
; ========== Pre Setting ==========
; Make log directory
wait prompt_sonic_root
sendln "mkdir ./logs"
; Setting System Time
getdate datestr
gettime timestr
sprintf2 cmd 'sudo date -s "%s %s"' datestr timestr
sendln cmd
; ========== FAN SPEED ==========
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sprintf2 fan_ctrl_cmd 'fan-speed-control.sh %d' FAN_SPEED
sendln fan_ctrl_cmd
wait "Set all configured fan channels to"
sendln "y"
; ========== Wait DUT Init ==========
include "utils/wait_init.ttl"
; ========== DUT Info ==========
wait prompt_sonic_root
sprintf2 strCKPt1 "echo -e '\033[36mCheck Pt1 : DUT Info\033[0m'"
sendln strCKPt1
wait prompt_sonic_root
sendln "show boot"
wait prompt_sonic_root
sendln "show version"
wait prompt_sonic_root
sendln "fwutil show status"
wait prompt_sonic_root
sendln "show system-memory"
wait prompt_sonic_root
sendln "show service"
wait prompt_sonic_root
sendln "show platform syseeprom"
wait prompt_sonic_root
sendln "show platform ssdhealth"
wait prompt_sonic_root
sendln "qfx5252-tpm-version"
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
; ========== BMC version ==========
wait prompt_sonic_root
sprintf2 strCKPt2 "echo -e '\033[36mCheck Pt2 : BMC Info\033[0m'"
sendln strCKPt2
wait prompt_sonic_root
sendln "bmc-first-enroll"
wait prompt_sonic_root
sendln "bmc-manager version"
wait prompt_sonic_root
sendln "bmc-manager status"
; ========== Load Shell Script ==========
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_fpga_pcimem.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_cb_i2c.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_icb_vi2c.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_pwr_data.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_traffic_linespeed.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh"
; ========== CLEAR PCIE Error ==========
include "utils/show_pcie_error_reg_TH6_SWB0.ttl"
include "utils/show_pcie_error_reg_TH6_SWB1.ttl"
include "utils/show_pcie_error_reg_FPGA.ttl"
include "utils/show_pcie_error_reg_BMC.ttl"
include "utils/show_pcie_error_reg_DDR.ttl"
include "utils/show_pcie_error_reg_I210.ttl"
include "utils/show_pcie_error_reg_SSD.ttl"
wait prompt_sonic_root
sendln "/usr/sbin/ras-mc-ctl --summary"
; ========== Check PCIE tree + PCIE link status + GET PCIE bandwidth Test ==========
include "utils/pcie_bus.ttl"
; ========== TAKE DATA ==========
include "utils/setup_pmon.ttl"
include "utils/show_dmesg.ttl"
; ========== 10G/1G MGMT Ping Test ==========
wait prompt_sonic_root
sprintf2 strCKPt3 "echo -e '\033[36mCheck Pt3 : Mgmt Ping Test\033[0m'"
sendln strCKPt3
wait prompt_sonic_root
sendln "./Blanton_Script/mgmt_ping_monitor.sh start"
wait prompt_sonic_root
pause 30
sendln "~/Blanton_Script/mgmt_ping_monitor.sh stop"
wait prompt_sonic_root
sendln "cat ~/Blanton_Script/log/mgmt_ping.log"
wait prompt_sonic_root
sendln "~/Blanton_Script/mgmt_ping_monitor.sh clear"
; ========== NFC Test ==========
wait prompt_sonic_root
sprintf2 strCKPt4 "echo -e '\033[36mCheck Pt4 : NFC Test\033[0m'"
sendln strCKPt4
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh start"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh status"
wait prompt_sonic_root
sendln "sleep 20"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh stop"
wait prompt_sonic_root
sendln "~/Blanton_Script/nfc_polling.sh report"
; ========== SSD read/write ==========
wait prompt_sonic_root
sprintf2 strCKPt5 "echo -e '\033[36mCheck Pt5 : SSD Test\033[0m'"
sendln strCKPt5
wait prompt_sonic_root
sendln "qfx5252-stress-ssd 1G --runtime 30 --passes 2 --write --force --log /host/hw-eval/jobs/qfx5252-stress-ssd.log"
wait prompt_sonic_root
sendln "cat /host/hw-eval/jobs/qfx5252-stress-ssd.log"
; ========== USB read/write ==========
wait prompt_sonic_root
sprintf2 strCKPt6 "echo -e '\033[36mCheck Pt6 : USB Test\033[0m'"
sendln strCKPt6
; ---- Get USB partition node -> usb_dev ----
usb_dev = ''
wait prompt_sonic_root
sendln 'D=$(bash ~/Blanton_Script/usb_target.sh -o dev 2>/dev/null); echo "<<D""EV=${D:-NONE}>>"'
waitregex '<<DEV=([^>]*)>>'
usb_dev = groupmatchstr1
wait prompt_sonic_root
sprintf2 cmd "qfx5252-stress-usb %s 256M --runtime 30 --passes 2 --write --log /host/hw-eval/jobs/qfx5252-stress-usb.log" usb_dev
sendln cmd
wait prompt_sonic_root
sendln "cat /host/hw-eval/jobs/qfx5252-stress-usb.log"
; ========== BMC USB Test ==========
wait prompt_sonic_root
sprintf2 strCKPt7 "echo -e '\033[36mCheck Pt7 : BMC USB Test\033[0m'"
sendln strCKPt7
wait prompt_sonic_root
sendln 'echo "NCMIF=$(ls -d /sys/bus/usb/drivers/cdc_ncm/*/net/* 2>/dev/null | head -n 1 | xargs -r basename)"'
; timeout is GLOBAL and sticky: left at 15, every 'wait' below gives up after
; 15 s instead of blocking, the macro runs ahead of the DUT and the whole
; cycle desynchronises. Restore it BEFORE the branch so both paths are
; covered - the ping block below waits on 'sleep 10', which is already two
; thirds of the 15 s cap on a loaded DUT.
timeout = 15
waitregex 'NCMIF=[A-Za-z0-9_-]+'
ncm_found = result ; hold it: 'result' is reused below
timeout = 0 ; restore, both paths
if ncm_found = 0 then
messagebox 'cdc_ncm interface not found. Ping test skipped.' 'ERROR'
goto skip_ping
endif
strlen matchstr
cut_len = result - 6 ; 'NCMIF=' = 6 chars
strcopy matchstr 7 cut_len ncm_if ; -> ncm_if = "eth2" / "eth3"
sprintf2 cmd 'ip -br link show %s' ncm_if
wait prompt_sonic_root
sendln cmd
wait prompt_sonic_root
sendln 'systemctl stop qfx5252-bmc-usb-net-test.service 2>/dev/null || true'
wait prompt_sonic_root
sendln 'systemctl reset-failed qfx5252-bmc-usb-net-test.service 2>/dev/null || true'
sprintf2 cmd 'systemd-run --unit=qfx5252-bmc-usb-net-test --property=Type=exec /usr/bin/ping -I %s -i 1 -W 2 -w 14400 192.168.200.200' ncm_if
wait prompt_sonic_root
sendln cmd
wait prompt_sonic_root
sendln "sleep 10"
wait prompt_sonic_root
sendln "systemctl stop qfx5252-bmc-usb-net-test.service"
wait prompt_sonic_root
sendln "journalctl -u qfx5252-bmc-usb-net-test.service --no-pager"
:skip_ping
timeout = 0 ; backstop, same as Script B
; ========== 100G Port Setting ==========
wait prompt_sonic_root
sendln "sudo sfputil lpmode off Ethernet513"
wait prompt_sonic_root
sendln "sudo sfputil lpmode off Ethernet514"
wait prompt_sonic_root
sendln "config interface -n asic0 startup Ethernet513"
wait prompt_sonic_root
sendln "config interface -n asic1 startup Ethernet514"
wait prompt_sonic_root
sendln "config save -y"
; ========== First Traffic Test ==========
; Silent MAC
wait prompt_sonic_root
sendln "config feature state lldp disabled"
wait prompt_sonic_root
sendln "config save -y"
; ========== 100G Port Status ==========
wait prompt_sonic_root
sprintf2 strCKPt8 "echo -e '\033[36mCheck Pt8 : Port Status and 15sec Traffic \033[0m'"
sendln strCKPt8
wait prompt_sonic_root
sendln "show interfaces status Ethernet513,Ethernet514"
; ========== Traffic Test ==========
if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed init"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed clear"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed show"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed start"
wait prompt_sonic_root
pause 15
sendln "blanton_traffic_linespeed stop"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed report"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed init -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed clear -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed show -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed start -u 0"
wait prompt_sonic_root
pause 15
sendln "blanton_traffic_linespeed stop -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed report -u 0"
elseif SWB_UNIT0 = 0 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps -u 1"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed init -u 1"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed clear -u 1"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed show -u 1"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed start -u 1"
wait prompt_sonic_root
pause 15
sendln "blanton_traffic_linespeed stop -u 1"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed report -u 1"
else
endif
; ========== BER ==========
; PRBS takes the SerDes out of normal operation, so this runs AFTER the
; traffic report. sleep 30 matches blanton_ber.sh BER_INTERVAL - reporting
; earlier reads an interval that has not finished accumulating.
wait prompt_sonic_root
sprintf2 strCKPt8 "echo -e '\033[36mCheck Pt9 : BER Test \033[0m'"
sendln strCKPt8
if SWB_UNIT0 = 1 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear"
elseif SWB_UNIT0 = 1 && SWB_UNIT1 = 0 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start -u 0"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop -u 0"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear -u 0"
elseif SWB_UNIT0 = 0 && SWB_UNIT1 = 1 then
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh init -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh start -u 1"
wait prompt_sonic_root
sendln "sleep 30"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh report -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh stop -u 1"
wait prompt_sonic_root
sendln "./Blanton_Script/blanton_ber.sh clear -u 1"
else
endif
; ========== NVME Err Info ==========
wait prompt_sonic_root
sprintf2 strCKPt9 "echo -e '\033[36mCheck Pt10 : NVME Err Info \033[0m'"
sendln strCKPt9
wait prompt_sonic_root
sendln "/usr/sbin/nvme smart-log -H /dev/nvme0"
wait prompt_sonic_root
sendln "/usr/sbin/smartctl -x /dev/nvme0"
; ========== TAKE DATA ==========
wait prompt_sonic_root
sprintf2 strCKPt10 "echo -e '\033[36mCheck Pt11 : Platform Data \033[0m'"
sendln strCKPt10
include "utils/setup_pmon.ttl"
wait prompt_sonic_root
sprintf2 strCKPt12 "echo -e '\033[36mCheck Pt12 : Dmesg_i2c \033[0m'"
sendln strCKPt12
include "utils/show_dmesg.ttl"
; ========== Check PCIE error counters ==========
wait prompt_sonic_root
sprintf2 strCKPt13 "echo -e '\033[36mCheck Pt13 : PCIE Error Counters \033[0m'"
sendln strCKPt13
include "utils/show_pcie_error_reg_TH6_SWB0.ttl"
include "utils/show_pcie_error_reg_TH6_SWB1.ttl"
include "utils/show_pcie_error_reg_FPGA.ttl"
include "utils/show_pcie_error_reg_BMC.ttl"
include "utils/show_pcie_error_reg_DDR.ttl"
include "utils/show_pcie_error_reg_I210.ttl"
include "utils/show_pcie_error_reg_SSD.ttl"
wait prompt_sonic_root
sendln "/usr/sbin/ras-mc-ctl --summary"
; ========== Show Power on uptime ==========
wait prompt_sonic_root
sendln "show uptime"
; ========== Show Power on uptime ==========
wait prompt_sonic_root
sendln "reboot"
wait "Booting in blind mode"
endwhile
@@ -14,6 +14,8 @@
| `margin_operation <ch> <op>` | 只切 OPERATION register |
| `margin_apply_profile <file>` | 批次套用 profile(套用在當前載入的 LTC2980 |
| `margin_save` | 寫入 NVM(當前 LTC2980 的兩個 LTC2977 都寫) |
| `margin_save all` | 對 `settings/` 底下**全部** LTC2980 寫入 NVM,結束後回到原本載入的那顆 |
| `margin_save blanton` | **Blanton SONiC 專用**18 顆 LTC2977 全部走原生 i2c bus 寫入,不需要 `margin_init` |
| `margin_debug [on\|off]` | 開關 debug 模式(不帶參數則 toggle |
| `margin_log [on\|off]` | 開關 log 記錄(不帶參數則 toggle,預設開啟) |
@@ -70,16 +72,18 @@ margin_operation 0 high
margin_operation 0 nominal
# 批次套用 profile(套在當前載入的 LTC2980
margin_apply_profile profiles/comboA.conf
margin_apply_profile profiles/comboB.conf
margin_apply_profile profiles/combo_SWB_CONN13_high.conf
margin_apply_profile profiles/combo_SWB_CONN13_low.conf
margin_apply_profile profiles/all_off.conf
# 切換到另一顆 LTC2980
margin_init Blanton_SWB1_CONN16
margin_apply_profile profiles/comboA.conf
margin_apply_profile profiles/combo_SWB_CONN16_high.conf
# 儲存到 NVM(斷電後保留)
margin_save
margin_save # 只寫當前載入的那顆
margin_save all # settings/ 底下 9 顆全部寫,最後自動切回原本那顆
margin_save blanton # Blanton SONiC 專用捷徑,18 顆一次寫完(見下)
```
## 一次掃所有 LTC2980
@@ -104,7 +108,7 @@ BOARDS=(
## 一次套 profile 到所有 LTC2980
`script/margin_apply_profile_all.sh` 對多顆 LTC2980 依 `BOARDS[i]` 配對
`PROFILES[i]` 套用 profile(預設全部 `comboA`)。
`PROFILES[i]` 套用 profile(預設 SWB 各用自己 CONN 的 `_high`CB 用 `combo_high3`)。
```bash
source script/margin_apply_profile_all.sh
@@ -120,8 +124,8 @@ BOARDS=(
)
PROFILES=(
"comboA" # Blanton_CB_CONN13
"comboB" # Blanton_SWB0_CONN13 ← 改成 comboB
"combo_high3" # Blanton_CB_CONN13
"combo_SWB_CONN13_high" # Blanton_SWB0_CONN13
...
)
```
@@ -129,18 +133,109 @@ PROFILES=(
`PROFILES` 寫名字即可(不含路徑跟 `.conf`),script 會自動展開成
`profiles/<name>.conf`。兩個陣列長度不一致會直接報錯。
## 一次把所有 LTC2980 寫入 NVM
> ⚠️ **SWB 的 profile 是 per-CONN 的**:每個檔的百分比對應該片板子的軌,
> 套到別的 CONN 會 margin 到錯的東西(而且不會報錯)。這裡不能全部填同一個名字。
> HIGH / LOW 兩輪就是把 `_high` 全換成 `_low` 再跑一次。
`script/margin_save_all.sh``BOARDS` 列出的每顆 LTC2980 跑 `margin_save`
## 一次把所有 LTC2980 寫入 NVM
> ⚠️ `margin_save` 會把當前 margin / OV / UV 設定**永久寫入 NVM**
> 斷電後保留。執行前先用 `margin_status_all.sh` 確認狀態正確。
**全部 9 顆**直接用內建的:
```bash
margin_save all
```
`settings/*.conf` 的檔名順序跑,中途某顆失敗**不會停**(半套完成的狀態比全部試完更難查),
最後印出「幾顆成功 / 哪幾顆失敗」的總結,並把 `margin_init` 切回你呼叫前載入的那顆。
**只寫其中幾顆**才需要 `script/margin_save_all.sh`,編 script 頂端的 `BOARDS` 陣列:
```bash
source script/margin_save_all.sh
```
要改寫哪幾顆,編 script 頂端的 `BOARDS` 陣列即可(同前述)。
### 送出去的是什麼
`margin_save` 對每顆 LTC2977 送一次 `STORE_USER_ALL`PMBus command `0x15`),
**不分 page**(這是整顆晶片的命令),也**不帶 data byte** —— 它是 SMBus send-byte
```bash
i2cset -y 4 0x5C 0x15 c # CB CONN13(原生 bus 4
cb_pmbus_write 8 0x5C 0x15 # SWB0 CONN13CB FPGA F3 Ch8
```
> v2.7.0 之前送的是 `0x15 0x00`write-byte)。LTC2977 在 CB 上吃得下去,但那是零件寬容,
> 不是規範。同時 v2.7.0 起會檢查回傳值 —— 以前 NACK 了還是印 `Change Saved`。
每顆之間會 `sleep $MARGIN_STORE_SETTLE`(預設 0.5 秒)。這不是量測值,是保守的保護:
NVM 寫入需要時間,而這支工具**沒有**去 poll 零件的 busy bit。`margin_save all` 連續送 18 次,
這個間隔就是唯一的緩衝。要關掉設成空字串即可。
## `margin_save blanton` — Blanton SONiC 專用
Blanton 這台把 CB FPGA F3 的 I2C 通道**同時掛成了原生 Linux i2c adapter**
所以 SWB 上的 LTC2977 不必走 `cb_pmbus_*` / pcimem,用 `i2cset` 直接打得到:
| FPGA F3 通道 | Linux bus | 板 / 接頭 |
|---|---|---|
| Ch6 | 13 | SWB0 CONN14 / CONN16 |
| Ch8 | 15 | SWB0 CONN13 / CONN15 |
| Ch7 | 14 | SWB1 CONN14 / CONN16 |
| Ch9 | 16 | SWB1 CONN13 / CONN15 |
| —(原生) | 4 | CB CONN13 |
因此 `margin_save blanton` 就是一張平表跑完 18 顆,**不需要 `margin_init`**、
不做 FPGA 通道初始化、不做 probe,也不會動到你當前載入的那顆板子:
```bash
margin_save blanton
```
```
CB CONN13 bus 4 0x5C : saved
SWB0 CONN13 bus 15 0x5C : saved
...
margin_save blanton: 18 saved, 0 failed
```
送出去的就是這 18 行(2026-08-27 上機驗證):
```bash
i2cset -f -y 4 0x5C 0x15 ; i2cset -f -y 4 0x5E 0x15 # CB CONN13
i2cset -f -y 15 0x5C 0x15 ; i2cset -f -y 15 0x5E 0x15 # SWB0 CONN13
i2cset -f -y 13 0x5C 0x15 ; i2cset -f -y 13 0x5E 0x15 # SWB0 CONN14
i2cset -f -y 15 0x62 0x15 ; i2cset -f -y 15 0x64 0x15 # SWB0 CONN15
i2cset -f -y 13 0x62 0x15 ; i2cset -f -y 13 0x64 0x15 # SWB0 CONN16
i2cset -f -y 16 0x5C 0x15 ; i2cset -f -y 16 0x5E 0x15 # SWB1 CONN13
i2cset -f -y 14 0x5C 0x15 ; i2cset -f -y 14 0x5E 0x15 # SWB1 CONN14
i2cset -f -y 16 0x62 0x15 ; i2cset -f -y 16 0x64 0x15 # SWB1 CONN15
i2cset -f -y 14 0x62 0x15 ; i2cset -f -y 14 0x64 0x15 # SWB1 CONN16
```
`-f` 是因為這些 bus 上的 LTC2977 可能已被 kernel driver 認走;上機驗證過的指令帶 `-f`,就照原樣保留。
**這台沒裝滿的話**,把 `margin.sh` 頂端 `MARGIN_BLANTON_STORE` 陣列裡對應的行註解掉即可,
不要讓它去打不存在的板子。bus 節點不存在(`/dev/i2c-N` 沒有)與晶片不回應(NACK
會分別報不同訊息 —— 前者代表 FPGA 的 i2c adapter 根本沒 enumerate,後者才是板子的問題。
## Profile 一覽
| Profile | 適用 | 說明 |
|---|---|---|
| `combo_SWB_CONN13_high` / `_low` | **SWB CONN13 專用** | 每個 channel 依該板的軌給 3% 或 5% |
| `combo_SWB_CONN14_high` / `_low` | **SWB CONN14 專用** | 同上 |
| `combo_SWB_CONN15_high` / `_low` | **SWB CONN15 專用** | 同上 |
| `combo_SWB_CONN16_high` / `_low` | **SWB CONN16 專用** | 同上 |
| `combo_high3` / `combo_low3` | 通用 | 全部 channel ±3% |
| `combo_high5` / `combo_low5` | 通用 | 全部 channel ±5% |
| `combo_normal` | 通用 | 全部回 nominal |
| `all_off` | 通用 | 全部 OPERATION off |
SWB0 和 SWB1 的同號 CONN 共用同一個 profile(兩片板的軌完全相同,
只差 I2C bus)。CB CONN13 沒有專屬 profile,用通用的 `combo_high3` / `combo_low3`
## Operation 對應
@@ -424,8 +424,9 @@ SWB debug 指令(margin.sh v2.6.0 新增,皆為 `blanton_cb_i2c.sh` 的薄包裝
`Blanton_SWB0_CONN14.conf` 的第一顆也是 `0:0x5E`。兩個 CONN 現在同在 Ch6,
位址相撞。對照 SWB1 的規律(CONN13=`0x5C/0x5D`、CONN14=`0x5E/0x5F`),
SWB0_CONN13 第二顆推測應為 `0:0x5D`**尚未修改,待硬體確認**
- `margin_save``0x15` + data byte(`i2cset ... 0x15 0x00 b`)。PMBus 規範
STORE_USER_ALL 是 send-byte;CB 上實測可用故保留原樣,swb 路徑沿用同一寫法。
- `margin_save``0x15` **send-byte**(`i2cset ... 0x15 c` / `cb_pmbus_write <ch> <addr> 0x15`),
不帶 data byte。v2.7.0 之前送的是 `0x15 0x00`(write-byte),CB 上實測可用,
但那是零件寬容而非規範。
---
@@ -5,6 +5,24 @@
# =============================================================================
# Version Control
# -----------------------------------------------------------------------------
# v2.7.0 margin_save fixes and batching:
# * STORE_USER_ALL (0x15) is now issued as an SMBus send-byte instead
# of a write-byte with a dummy 0x00 data byte. The LTC2977 accepted
# the old form on CB, but it was the wrong protocol.
# i2c path: i2cset ... 0x15 c swb path: cb_pmbus_write ch addr 0x15
# * margin_save all -- STORE_USER_ALL on every board in settings/,
# then re-init whichever board was loaded beforehand. Does not stop
# on the first failure; prints a per-board summary at the end.
# * The store result is now checked. It used to be discarded, so a
# NACK still printed "Change Saved".
# * MARGIN_STORE_SETTLE (default 0.5s) between stores - nothing polls
# the part's busy bit, and `all` issues 18 of them in a row.
# * margin_save blanton -- Blanton SONiC shortcut. On this platform the
# CB FPGA F3 I2C channels also appear as native Linux i2c adapters
# (Ch6->bus 13, Ch7->14, Ch8->15, Ch9->16), so all 18 LTC2977 can be
# stored with plain i2cset: no margin_init, no FPGA channel setup,
# no pcimem. Bench-verified on the DUT 2026-08-27. The board list is
# MARGIN_BLANTON_STORE at the top of this file.
# v2.6.0 SWB path actually wired to the shared CB I2C package. blanton_cb_i2c.sh
# and blanton_fpga_pcimem.sh live in the PARENT dir (Blanton_Script/), not
# next to margin.sh, so the backend is now searched in both places.
@@ -115,6 +133,45 @@ ONOFF_ENABLE_VALUE="0x1a" # controlled_on=1, use_pmbus=1, use_control=0, b1=1
# margin_status after all channels are set. Bump this if you want margin_set's own
# read-back to reflect the settled value.
MARGIN_SETTLE="0.3"
# Pause after each STORE_USER_ALL. The LTC2977 is busy committing NVM once the
# command lands and nothing here polls a busy bit, so this is a plain guard
# rather than a measured value - it matters most for `margin_save all`, which
# fires 18 stores back to back. Set to "" to disable.
MARGIN_STORE_SETTLE="${MARGIN_STORE_SETTLE:-0.5}"
# --- `margin_save blanton`: the bench-verified Blanton SONiC store list -------
# On this platform the CB FPGA F3 I2C channels are ALSO exposed as native Linux
# i2c adapters, so every LTC2977 - CB and SWB alike - can be reached with plain
# i2cset. That path needs no FPGA channel setup, no pcimem, and no margin_init:
# one flat list, 18 commands, done. Verified on the DUT 2026-08-27.
#
# FPGA F3 channel -> Linux bus: Ch6->13 Ch7->14 Ch8->15 Ch9->16
#
# Entry format: "bus:addr:label". Comment out the lines for boards this DUT does
# not have rather than letting them fail - a single-SWB unit is a normal build.
MARGIN_BLANTON_STORE=(
"4:0x5C:CB CONN13"
"4:0x5E:CB CONN13"
"15:0x5C:SWB0 CONN13"
"15:0x5E:SWB0 CONN13"
"13:0x5C:SWB0 CONN14"
"13:0x5E:SWB0 CONN14"
"15:0x62:SWB0 CONN15"
"15:0x64:SWB0 CONN15"
"13:0x62:SWB0 CONN16"
"13:0x64:SWB0 CONN16"
"16:0x5C:SWB1 CONN13"
"16:0x5E:SWB1 CONN13"
"14:0x5C:SWB1 CONN14"
"14:0x5E:SWB1 CONN14"
"16:0x62:SWB1 CONN15"
"16:0x64:SWB1 CONN15"
"14:0x62:SWB1 CONN16"
"14:0x64:SWB1 CONN16"
)
# -f because the LTC2977s may be claimed by a kernel driver on these buses; the
# command that was verified on the bench carries it, so it stays.
MARGIN_BLANTON_I2CSET_FLAGS="${MARGIN_BLANTON_I2CSET_FLAGS:--f -y}"
_BUS=""
_ADDR=""
_PRE_SCOPE="" # set while inside a PRE/POST wrapped operation; prevents nested re-entry
@@ -257,6 +314,20 @@ _swb_write() {
return 0
}
# _swb_send <cmd> -> cb_pmbus_write with NO data byte (SMBus send-byte).
# cb_pmbus_write routes a no-data call to _cbi2c_xfer_cmd_only: START, slave+W,
# command byte, STOP. That is what STORE_USER_ALL expects.
_swb_send() {
local reg=$1
[ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] cb_pmbus_write $CB_I2C_CH $_ADDR $reg (send-byte)\033[0m"
if ! _swb_call cb_pmbus_write "$CB_I2C_CH" "$_ADDR" "$reg" >/dev/null 2>&1; then
echo -e "[\033[31mERRO\033[0m] cb_pmbus_write ch=$CB_I2C_CH $_ADDR reg=$reg (send-byte) failed (NACK/timeout)" >&2
_log_detail "ERRO cb_pmbus_write ch=$CB_I2C_CH $_ADDR $reg send-byte"
return 1
fi
return 0
}
# _swb_read_word <reg> -> echoes "0xXXXX" parsed out of cb_pmbus_read's "=> 0xXXXX"
_swb_read_word() {
local reg=$1 out word
@@ -520,6 +591,20 @@ _i2c_write_byte() {
i2cset -y "$_BUS" "$_ADDR" "$1" "$2" b >/dev/null 2>&1
}
# Send a PMBus command with NO data byte (SMBus send-byte).
# STORE_USER_ALL (0x15) and its relatives are send-byte commands: the command
# byte alone triggers them. Appending a dummy 0x00 makes it a write-byte, which
# is a different SMBus protocol - the LTC2977 happened to accept it, but that is
# tolerance, not correctness. i2cset's "c" mode is the send-byte form.
_i2c_send_byte() {
if [ "$TRANSPORT" = "swb" ]; then
_swb_send "$1"
return
fi
[ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] i2cset -y $_BUS $_ADDR $1 c\033[0m"
i2cset -y "$_BUS" "$_ADDR" "$1" c >/dev/null 2>&1
}
# Read a 16-bit word; echoes "0xXXXX". For swb, parse cb_pmbus_read's "=> 0xXXXX".
_i2c_read_word() {
if [ "$TRANSPORT" = "swb" ]; then
@@ -730,20 +815,171 @@ margin_apply_profile() {
}
# --- Save to NVM ---
# margin_save -- STORE_USER_ALL on the currently initialised board
# margin_save all -- ... on every board in settings/, then re-init the one
# that was loaded when you called it
# margin_save blanton -- Blanton SONiC shortcut: all 18 LTC2977 straight over
# the native i2c buses, no margin_init needed
#
# ⚠️ This is the only permanent write in the tool: it commits the current
# margin / OV / UV registers to NVM, and a power cycle will NOT undo it.
# Run margin_status first and never call it during a test run.
margin_save() {
if [ "${1:-}" = "all" ]; then
_margin_save_every_board
return
fi
if [ "${1:-}" = "blanton" ]; then
_margin_save_blanton
return
fi
local _own=0
_pre_enter_own && _own=1
local chip fails=0
for chip in "${CHIPS[@]}"; do
IFS=':' read -r _BUS _ADDR <<< "$chip"
_i2c_write_byte 0x15 0x00
# STORE_USER_ALL is chip-wide (all 8 pages), so no _open_page here.
if _i2c_send_byte 0x15; then
_log_detail "STORE_USER_ALL $PART_NUMBER $_ADDR ok"
else
fails=$(( fails + 1 ))
echo -e "[\033[31mERRO\033[0m] STORE_USER_ALL failed on $_ADDR" >&2
_log_detail "ERRO STORE_USER_ALL $PART_NUMBER $_ADDR"
fi
# The part is busy writing NVM after this; nothing here polls a busy bit,
# so leave a gap before touching it again. See MARGIN_STORE_SETTLE.
[ -n "$MARGIN_STORE_SETTLE" ] && sleep "$MARGIN_STORE_SETTLE"
done
if [ "$fails" -eq 0 ]; then
echo "Change Saved (${#CHIPS[@]} chips)"
_log_label "margin_save $PART_NUMBER (${#CHIPS[@]} chips)"
else
echo -e "[\033[31mERRO\033[0m] $fails of ${#CHIPS[@]} chips did NOT save"
fi
_log_label "margin_save $PART_NUMBER (${#CHIPS[@]} chips, $fails failed)"
[ "$_own" = "1" ] && _pre_exit
return $(( fails > 0 ))
}
# margin_save all -- every .conf in settings/, in filename order.
# Deliberately does NOT stop on the first failure: a half-saved set is worse to
# diagnose than a fully-attempted one, and the summary tells you which boards
# to redo. margin_init is re-run per board because CHIPS / TRANSPORT /
# CB_I2C_CH are global state.
_margin_save_every_board() {
local files=( "$SETTINGS_DIR"/*.conf )
if [ ! -e "${files[0]}" ]; then
echo -e "[\033[31mERRO\033[0m] no .conf found in $SETTINGS_DIR"
return 1
fi
local restore="$PART_NUMBER" # empty if margin_init was never run
local board f ok=0 bad=0 failed=""
echo "-------------"
echo "margin_save all -- ${#files[@]} boards, permanent NVM write"
echo "-------------"
_log_label "margin_save all (${#files[@]} boards)"
for f in "${files[@]}"; do
board=$(basename "$f" .conf)
echo ""
if ! margin_init "$board"; then
bad=$(( bad + 1 )); failed="$failed $board(init)"
continue
fi
if margin_save; then
ok=$(( ok + 1 ))
else
bad=$(( bad + 1 )); failed="$failed $board"
fi
done
echo ""
echo "-------------"
printf "margin_save all: %d saved, %d failed\n" "$ok" "$bad"
[ "$bad" -gt 0 ] && echo -e "[\033[31mERRO\033[0m] failed:$failed"
echo "-------------"
_log_label "margin_save all done: $ok ok, $bad failed$failed"
# Put back whatever board the caller had loaded, so a following
# margin_status does not silently report the last board in the list.
if [ -n "$restore" ] && [ "$restore" != "$board" ]; then
echo ""
echo -e "[\033[34mINFO\033[0m] restoring previous board: $restore"
margin_init "$restore" >/dev/null
fi
return $(( bad > 0 ))
}
# margin_save blanton -- Blanton SONiC only. Walks MARGIN_BLANTON_STORE and
# sends STORE_USER_ALL to each LTC2977 over the native i2c buses.
#
# Deliberately does NOT use margin_init / CHIPS / TRANSPORT: the whole point is
# that on this platform every LTC2977 is reachable with plain i2cset, so the
# FPGA channel setup and the per-board probe are not needed. That also means it
# does not touch the loaded board - PART_NUMBER is the same afterwards.
_margin_save_blanton() {
local n=${#MARGIN_BLANTON_STORE[@]}
if [ "$n" -eq 0 ]; then
echo -e "[\033[31mERRO\033[0m] MARGIN_BLANTON_STORE is empty"
return 1
fi
echo "-------------"
echo "margin_save blanton -- $n LTC2977, permanent NVM write"
echo "-------------"
_log_label "margin_save blanton ($n chips)"
local entry bus addr label ok=0 bad=0 failed=""
for entry in "${MARGIN_BLANTON_STORE[@]}"; do
IFS=':' read -r bus addr label <<< "$entry"
# "no such bus" and "chip did not answer" are different faults: the first
# means the FPGA i2c adapters did not enumerate, the second means the
# board is absent or the address is wrong. Do not blur them into one.
if [ ! -e "/dev/i2c-$bus" ]; then
echo -e "[\033[31mERRO\033[0m] $label bus $bus addr $addr : /dev/i2c-$bus does not exist"
_log_detail "ERRO STORE_USER_ALL $label bus=$bus addr=$addr no-such-bus"
bad=$(( bad + 1 )); failed="$failed [$label $addr]"
continue
fi
[ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] i2cset $MARGIN_BLANTON_I2CSET_FLAGS $bus $addr 0x15\033[0m"
if i2cset $MARGIN_BLANTON_I2CSET_FLAGS "$bus" "$addr" 0x15 >/dev/null 2>&1; then
printf " %-12s bus %-2s %s : saved\n" "$label" "$bus" "$addr"
ok=$(( ok + 1 ))
_log_detail "STORE_USER_ALL $label bus=$bus addr=$addr ok"
else
echo -e "[\033[31mERRO\033[0m] $label bus $bus addr $addr : i2cset failed (NACK/busy)"
_log_detail "ERRO STORE_USER_ALL $label bus=$bus addr=$addr"
bad=$(( bad + 1 )); failed="$failed [$label $addr]"
fi
# No busy-bit poll anywhere in this tool; this gap is the only buffer.
[ -n "$MARGIN_STORE_SETTLE" ] && sleep "$MARGIN_STORE_SETTLE"
done
echo "-------------"
printf "margin_save blanton: %d saved, %d failed\n" "$ok" "$bad"
[ "$bad" -gt 0 ] && echo -e "[\033[31mERRO\033[0m] failed:$failed"
echo "-------------"
_log_label "margin_save blanton done: $ok ok, $bad failed$failed"
return $(( bad > 0 ))
}
# --- Tab completion for margin_save ---
_margin_save_completions() {
[ "$COMP_CWORD" -ne 1 ] && return
COMPREPLY=($(compgen -W "all blanton" -- "${COMP_WORDS[COMP_CWORD]}"))
}
complete -F _margin_save_completions margin_save
if [ -z "$_LOG_FILE" ]; then
_LOG_FILE="$LOGS_DIR/margin_$(date '+%Y%m%d_%H%M%S').log"
_LOG_DETAIL_FILE="${_LOG_FILE%.log}_detail.log"
@@ -1,22 +0,0 @@
# Profile: comboA - alternating high/low (even=high, odd=low)
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:8"
"1:low:8"
"2:high:8"
"3:low:8"
"4:high:8"
"5:low:8"
"6:high:8"
"7:low:8"
"8:high:8"
"9:low:8"
"10:high:8"
"11:low:8"
"12:high:8"
"13:low:8"
"14:high:8"
"15:low:8"
)
@@ -0,0 +1,26 @@
# Profile: comboA_CB - checkerboard, the complement of comboB_CB
# Board: CB only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboA then comboB to cover every rail in both directions while its
# neighbours sit the other way.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:5"
"1:low:5"
"2:high:5"
"3:low:5"
"4:high:5"
"5:high:5"
"6:high:5"
"7:high:5"
"8:low:5"
"9:high:5"
"10:high:5"
"11:high:5"
"12:low:5"
"13:high:5"
"14:high:5"
"15:low:5"
)
@@ -0,0 +1,26 @@
# Profile: comboA_SWB_CONN13 - checkerboard, the complement of comboB_SWB_CONN13
# Board: SWB_CONN13 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboA then comboB to cover every rail in both directions while its
# neighbours sit the other way.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:3"
"2:low:3"
"3:low:3"
"4:high:5"
"5:low:5"
"6:high:5"
"7:high:5"
"8:high:5"
"9:high:3"
"10:high:3"
"11:low:3"
"12:low:3"
"13:high:3"
"14:high:3"
"15:low:5"
)
@@ -0,0 +1,28 @@
# Profile: comboA_SWB_CONN14 - checkerboard, the complement of comboB_SWB_CONN14
# Board: SWB_CONN14 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboA then comboB to cover every rail in both directions while its
# neighbours sit the other way.
# CH 10, 11, 13 stay nominal: they are NC on this board, so there is
# nothing to margin.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:low:3"
"2:low:3"
"3:high:5"
"4:high:5"
"5:high:5"
"6:low:5"
"7:low:5"
"8:low:3"
"9:low:3"
"10:nominal:5"
"11:nominal:5"
"12:high:3"
"13:nominal:5"
"14:high:5"
"15:high:3"
)
@@ -0,0 +1,28 @@
# Profile: comboA_SWB_CONN15 - checkerboard, the complement of comboB_SWB_CONN15
# Board: SWB_CONN15 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboA then comboB to cover every rail in both directions while its
# neighbours sit the other way.
# CH 10 stay nominal: they are NC on this board, so there is
# nothing to margin.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:3"
"2:high:3"
"3:high:3"
"4:low:3"
"5:low:3"
"6:high:5"
"7:high:3"
"8:high:5"
"9:low:5"
"10:nominal:5"
"11:low:5"
"12:low:3"
"13:high:3"
"14:high:3"
"15:high:5"
)
@@ -0,0 +1,26 @@
# Profile: comboA_SWB_CONN16 - checkerboard, the complement of comboB_SWB_CONN16
# Board: SWB_CONN16 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboA then comboB to cover every rail in both directions while its
# neighbours sit the other way.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:5"
"2:high:5"
"3:low:5"
"4:high:5"
"5:low:5"
"6:high:5"
"7:high:3"
"8:high:3"
"9:high:3"
"10:low:3"
"11:low:3"
"12:low:3"
"13:low:3"
"14:low:3"
"15:high:3"
)
@@ -1,22 +0,0 @@
# Profile: comboB - inverse of comboA (even=low, odd=high)
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:8"
"1:high:8"
"2:low:8"
"3:high:8"
"4:low:8"
"5:high:8"
"6:low:8"
"7:high:8"
"8:low:8"
"9:high:8"
"10:low:8"
"11:high:8"
"12:low:8"
"13:high:8"
"14:low:8"
"15:high:8"
)
@@ -0,0 +1,26 @@
# Profile: comboB_CB - checkerboard, the complement of comboA_CB
# Board: CB only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboB then comboA to cover every rail in both directions while its
# neighbours sit the other way.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:5"
"1:high:5"
"2:low:5"
"3:high:5"
"4:low:5"
"5:low:5"
"6:low:5"
"7:low:5"
"8:high:5"
"9:low:5"
"10:low:5"
"11:low:5"
"12:high:5"
"13:low:5"
"14:low:5"
"15:high:5"
)
@@ -0,0 +1,26 @@
# Profile: comboB_SWB_CONN13 - checkerboard, the complement of comboA_SWB_CONN13
# Board: SWB_CONN13 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboB then comboA to cover every rail in both directions while its
# neighbours sit the other way.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:3"
"2:high:3"
"3:high:3"
"4:low:5"
"5:high:5"
"6:low:5"
"7:low:5"
"8:low:5"
"9:low:3"
"10:low:3"
"11:high:3"
"12:high:3"
"13:low:3"
"14:low:3"
"15:high:5"
)
@@ -0,0 +1,28 @@
# Profile: comboB_SWB_CONN14 - checkerboard, the complement of comboA_SWB_CONN14
# Board: SWB_CONN14 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboB then comboA to cover every rail in both directions while its
# neighbours sit the other way.
# CH 10, 11, 13 stay nominal: they are NC on this board, so there is
# nothing to margin.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:high:3"
"2:high:3"
"3:low:5"
"4:low:5"
"5:low:5"
"6:high:5"
"7:high:5"
"8:high:3"
"9:high:3"
"10:nominal:5"
"11:nominal:5"
"12:low:3"
"13:nominal:5"
"14:low:5"
"15:low:3"
)
@@ -0,0 +1,28 @@
# Profile: comboB_SWB_CONN15 - checkerboard, the complement of comboA_SWB_CONN15
# Board: SWB_CONN15 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboB then comboA to cover every rail in both directions while its
# neighbours sit the other way.
# CH 10 stay nominal: they are NC on this board, so there is
# nothing to margin.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:3"
"2:low:3"
"3:low:3"
"4:high:3"
"5:high:3"
"6:low:5"
"7:low:3"
"8:low:5"
"9:high:5"
"10:nominal:5"
"11:high:5"
"12:high:3"
"13:low:3"
"14:low:3"
"15:low:5"
)
@@ -0,0 +1,26 @@
# Profile: comboB_SWB_CONN16 - checkerboard, the complement of comboA_SWB_CONN16
# Board: SWB_CONN16 only. The channel list is positional, so applying this to a
# different board margins the wrong rails and nothing detects it.
# Run comboB then comboA to cover every rail in both directions while its
# neighbours sit the other way.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:5"
"2:low:5"
"3:high:5"
"4:low:5"
"5:high:5"
"6:low:5"
"7:low:3"
"8:low:3"
"9:low:3"
"10:high:3"
"11:high:3"
"12:high:3"
"13:high:3"
"14:high:3"
"15:low:3"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN13_high - every channel margin HIGH, per-channel percentage
# For the SWB CONN13 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:3"
"2:high:3"
"3:high:3"
"4:high:5"
"5:high:5"
"6:high:5"
"7:high:5"
"8:high:5"
"9:high:3"
"10:high:3"
"11:high:3"
"12:high:3"
"13:high:3"
"14:high:3"
"15:high:5"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN13_low - every channel margin LOW, per-channel percentage
# For the SWB CONN13 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:3"
"2:low:3"
"3:low:3"
"4:low:5"
"5:low:5"
"6:low:5"
"7:low:5"
"8:low:5"
"9:low:3"
"10:low:3"
"11:low:3"
"12:low:3"
"13:low:3"
"14:low:3"
"15:low:5"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN14_high - every channel margin HIGH, per-channel percentage
# For the SWB CONN14 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:3"
"2:high:3"
"3:high:5"
"4:high:5"
"5:high:5"
"6:high:5"
"7:high:5"
"8:high:3"
"9:high:3"
"10:nominal:5"
"11:nominal:5"
"12:high:3"
"13:nominal:5"
"14:high:5"
"15:high:3"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN14_low - every channel margin LOW, per-channel percentage
# For the SWB CONN14 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:3"
"2:low:3"
"3:low:5"
"4:low:5"
"5:low:5"
"6:low:5"
"7:low:5"
"8:low:3"
"9:low:3"
"10:nominal:5"
"11:nominal:5"
"12:low:3"
"13:nominal:5"
"14:low:5"
"15:low:3"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN15_high - every channel margin HIGH, per-channel percentage
# For the SWB CONN15 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:3"
"2:high:3"
"3:high:3"
"4:high:3"
"5:high:3"
"6:high:5"
"7:high:3"
"8:high:5"
"9:high:5"
"10:nominal:5"
"11:high:5"
"12:high:3"
"13:high:3"
"14:high:3"
"15:high:5"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN15_low - every channel margin LOW, per-channel percentage
# For the SWB CONN15 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:3"
"2:low:3"
"3:low:3"
"4:low:3"
"5:low:3"
"6:low:5"
"7:low:3"
"8:low:5"
"9:low:5"
"10:nominal:5"
"11:low:5"
"12:low:3"
"13:low:3"
"14:low:3"
"15:low:5"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN16_high - every channel margin HIGH, per-channel percentage
# For the SWB CONN16 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:high:3"
"1:high:5"
"2:high:5"
"3:high:5"
"4:high:5"
"5:high:5"
"6:high:5"
"7:high:3"
"8:high:3"
"9:high:3"
"10:high:3"
"11:high:3"
"12:high:3"
"13:high:3"
"14:high:3"
"15:high:3"
)
@@ -0,0 +1,24 @@
# Profile: combo_SWB_CONN16_low - every channel margin LOW, per-channel percentage
# For the SWB CONN16 board only: the percentages follow that board's
# rails, so applying it to a different CONN margins the wrong things.
# Applied to whichever LTC2980 is currently loaded via margin_init
# Format: "channel:operation:change_percent"
PROFILE_CHANNELS=(
"0:low:3"
"1:low:5"
"2:low:5"
"3:low:5"
"4:low:5"
"5:low:5"
"6:low:5"
"7:low:3"
"8:low:3"
"9:low:3"
"10:low:3"
"11:low:3"
"12:low:3"
"13:low:3"
"14:low:3"
"15:low:3"
)
@@ -17,17 +17,24 @@ BOARDS=(
"Blanton_SWB1_CONN16"
)
# 對應的 profile 名稱(不含路徑與 .conf 副檔名),預設全部 comboA
# 對應的 profile 名稱(不含路徑與 .conf 副檔名)
#
# SWB 的 profile 是 per-CONN 的:百分比對應該片板子的軌,套到別的 CONN 會 margin
# 到錯的東西,所以這裡不能全部填同一個名字。
#
# 這份預設是 HIGH 那一輪;LOW 那一輪把下面的 _high 全換成 _low 再跑一次
# (或 sed -i 's/_high/_low/' 這個檔)。
# CB 沒有 per-CONN profile,沿用通用的 combo_high3 / combo_low3。
PROFILES=(
"comboA" # Blanton_CB_CONN13
"comboA" # Blanton_SWB0_CONN13
"comboA" # Blanton_SWB0_CONN14
"comboA" # Blanton_SWB0_CONN15
"comboA" # Blanton_SWB0_CONN16
"comboA" # Blanton_SWB1_CONN13
"comboA" # Blanton_SWB1_CONN14
"comboA" # Blanton_SWB1_CONN15
"comboA" # Blanton_SWB1_CONN16
"combo_high3" # Blanton_CB_CONN13 (低壓軌多,用通用 +3%)
"combo_SWB_CONN13_high" # Blanton_SWB0_CONN13
"combo_SWB_CONN14_high" # Blanton_SWB0_CONN14
"combo_SWB_CONN15_high" # Blanton_SWB0_CONN15
"combo_SWB_CONN16_high" # Blanton_SWB0_CONN16
"combo_SWB_CONN13_high" # Blanton_SWB1_CONN13
"combo_SWB_CONN14_high" # Blanton_SWB1_CONN14
"combo_SWB_CONN15_high" # Blanton_SWB1_CONN15
"combo_SWB_CONN16_high" # Blanton_SWB1_CONN16
)
# --- Source margin.sh if not already loaded ---
@@ -4,6 +4,10 @@
# ⚠️ margin_save 會把目前的 margin / OV / UV 設定**永久寫入 NVM**
# 斷電後仍保留。執行前請務必先 margin_status 確認各 channel 狀態正確。
#
# 全部 9 顆請直接用 margin.sh v2.7.0 內建的 `margin_save all` —— 它有成功/失敗總結,
# 跑完還會把 margin_init 切回你原本載入的那顆。這支只在「只想寫其中幾顆」時才需要,
# 編下面的 BOARDS 陣列。
#
# Usage:
# source script/margin_save_all.sh
@@ -41,7 +41,7 @@ CH3_VNOM="1.8"; CH3_NET="V1P8_ALW"
CH4_VNOM="1.1"; CH4_NET="PWR_APU_VDDIO_SUS"
CH5_VNOM="0.75"; CH5_NET="PWR_VDD_MISC_RUN"
CH6_VNOM="0.78"; CH6_NET="PWR_APU_VDD_MEM_RUN"
CH7_VNOM="0.8"; CH7_NET="V0P8_PHY2_DVDD"
CH7_VNOM="0.816"; CH7_NET="V0P8_PHY2_DVDD"
CH8_VNOM="0.8"; CH8_NET="V0P8_AVDD"
CH9_VNOM="0.8"; CH9_NET="V0P8_PHY"
CH10_VNOM="1.8"; CH10_NET="V1P8_FPGA"
@@ -49,4 +49,4 @@ CH11_VNOM="2.5"; CH11_NET="V2P5_FPGA"
CH12_VNOM="1.1"; CH12_NET="V1P1_FPGA"
CH13_VNOM="5.0"; CH13_NET="P5V_STBY"
CH14_VNOM="3.3"; CH14_NET="P3V3_STBY"
CH15_VNOM="0.8"; CH15_NET="V0P8_PHY2_AVDD"
CH15_VNOM="0.816"; CH15_NET="V0P8_PHY2_AVDD"
@@ -35,18 +35,18 @@ CHIP_POST_CMD=(
# chip1: SWB0 (CONN13)
# ============================================================
CH0_VNOM="0.75"; CH0_NET="P0V75_DVDD_47"
CH1_VNOM="0.75"; CH1_NET="P0V75_AVDD_47"
CH2_VNOM="1.5"; CH2_NET="P1V5_AVDD_47"
CH3_VNOM="0.9"; CH3_NET="P0V9_AVDD_47"
CH4_VNOM="1.8"; CH4_NET="P1V8_1"
CH5_VNOM="3.3"; CH5_NET="PVDD3_3V_SYNTH_LDO_A3"
CH6_VNOM="3.3"; CH6_NET="PVDD3_3V_SYNTH_LDO_B1"
CH7_VNOM="1.8"; CH7_NET="P1V8_3"
CH1_VNOM="0.756"; CH1_NET="P0V75_AVDD_47"
CH2_VNOM="1.524"; CH2_NET="P1V5_AVDD_47"
CH3_VNOM="0.915"; CH3_NET="P0V9_AVDD_47"
CH4_VNOM="1.816"; CH4_NET="P1V8_1"
CH5_VNOM="3.38"; CH5_NET="PVDD3_3V_SYNTH_LDO_A3"
CH6_VNOM="3.38"; CH6_NET="PVDD3_3V_SYNTH_LDO_B1"
CH7_VNOM="1.816"; CH7_NET="P1V8_3"
CH8_VNOM="1.8"; CH8_NET="P1V8_DVDDIO_3"
CH9_VNOM="0.75"; CH9_NET="P0V75_DVDD_39"
CH10_VNOM="0.75"; CH10_NET="P0V75_AVDD_39"
CH11_VNOM="1.5"; CH11_NET="P1V5_AVDD_39"
CH12_VNOM="0.9"; CH12_NET="P0V9_AVDD_39"
CH10_VNOM="0.756"; CH10_NET="P0V75_AVDD_39"
CH11_VNOM="1.524"; CH11_NET="P1V5_AVDD_39"
CH12_VNOM="0.915"; CH12_NET="P0V9_AVDD_39"
CH13_VNOM="1.5"; CH13_NET="PVDD1V5_2"
CH14_VNOM="1.8"; CH14_NET="PVDD1V8_DUT"
CH15_VNOM="1.2"; CH15_NET="PVDD_MDIO"
@@ -34,16 +34,16 @@ CHIP_POST_CMD=(
# ============================================================
# chip1: SWB0 (CONN14)
# ============================================================
CH0_VNOM="0.75"; CH0_NET="P0V75_AVDD_7"
CH1_VNOM="1.5"; CH1_NET="P1V5_AVDD_7"
CH2_VNOM="0.9"; CH2_NET="P0V9_AVDD_7"
CH3_VNOM="1.8"; CH3_NET="P1V8_5"
CH4_VNOM="1.8"; CH4_NET="P1V8_2"
CH5_VNOM="3.3"; CH5_NET="PVDD3_3V_SYNTH_LDO_B2"
CH6_VNOM="3.3"; CH6_NET="PVDD3_3V_SYNTH_LDO_A2"
CH7_VNOM="3.3"; CH7_NET="PVDD3_3V_SYNTH_LDO_A1"
CH8_VNOM="1.5"; CH8_NET="PVDD1V5_TSC"
CH9_VNOM="1.5"; CH9_NET="PVDD1V5_ANLG"
CH0_VNOM="0.756"; CH0_NET="P0V75_AVDD_7"
CH1_VNOM="1.524"; CH1_NET="P1V5_AVDD_7"
CH2_VNOM="0.915"; CH2_NET="P0V9_AVDD_7"
CH3_VNOM="1.816"; CH3_NET="P1V8_5"
CH4_VNOM="1.816"; CH4_NET="P1V8_2"
CH5_VNOM="3.38"; CH5_NET="PVDD3_3V_SYNTH_LDO_B2"
CH6_VNOM="3.38"; CH6_NET="PVDD3_3V_SYNTH_LDO_A2"
CH7_VNOM="3.38"; CH7_NET="PVDD3_3V_SYNTH_LDO_A1"
CH8_VNOM="1.516"; CH8_NET="PVDD1V5_TSC"
CH9_VNOM="1.516"; CH9_NET="PVDD1V5_ANLG"
CH10_VNOM="-"; CH10_NET="NC"
CH11_VNOM="-"; CH11_NET="NC"
CH12_VNOM="1.5"; CH12_NET="PVDD1V5_1"
@@ -34,19 +34,19 @@ CHIP_POST_CMD=(
# ============================================================
# chip1: SWB0 (CONN15)
# ============================================================
CH0_VNOM="1.5"; CH0_NET="P1V5_AVDD_55"
CH1_VNOM="0.9"; CH1_NET="P0V9_AVDD_55"
CH0_VNOM="1.524"; CH0_NET="P1V5_AVDD_55"
CH1_VNOM="0.915"; CH1_NET="P0V9_AVDD_55"
CH2_VNOM="0.75"; CH2_NET="P0V75_DVDD_63"
CH3_VNOM="0.75"; CH3_NET="P0V75_AVDD_63"
CH4_VNOM="1.5"; CH4_NET="P1V5_AVDD_63"
CH5_VNOM="0.9"; CH5_NET="P0V9_AVDD_63"
CH6_VNOM="3.3"; CH6_NET="PVDD3_3V_SYNTH_LDO_B3"
CH3_VNOM="0.756"; CH3_NET="P0V75_AVDD_63"
CH4_VNOM="1.524"; CH4_NET="P1V5_AVDD_63"
CH5_VNOM="0.915"; CH5_NET="P0V9_AVDD_63"
CH6_VNOM="3.38"; CH6_NET="PVDD3_3V_SYNTH_LDO_B3"
CH7_VNOM="1.5"; CH7_NET="PVDD1V5_3"
CH8_VNOM="0.85"; CH8_NET="P0V85_STBY"
CH9_VNOM="1.8"; CH9_NET="P1V8_STBY"
CH10_VNOM="-"; CH10_NET="NC"
CH11_VNOM="3.3"; CH11_NET="P3V3_STBY"
CH12_VNOM="0.9"; CH12_NET="PVDD0V9_2"
CH12_VNOM="0.91"; CH12_NET="PVDD0V9_2"
CH13_VNOM="0.75"; CH13_NET="P0V75_DVDD_55"
CH14_VNOM="0.75"; CH14_NET="P0V75_AVDD_55"
CH14_VNOM="0.756"; CH14_NET="P0V75_AVDD_55"
CH15_VNOM="1.8"; CH15_NET="P1V8_DVDDIO_4"
@@ -35,18 +35,18 @@ CHIP_POST_CMD=(
# chip1: SWB0 (CONN16)
# ============================================================
CH0_VNOM="1.5"; CH0_NET="PVDD1V5_0"
CH1_VNOM="1.8"; CH1_NET="P1V8_4"
CH2_VNOM="3.3"; CH2_NET="PVDD3_3V_SYNTH_LDO_B5"
CH3_VNOM="3.3"; CH3_NET="PVDD3_3V_SYNTH_LDO_A5"
CH4_VNOM="3.3"; CH4_NET="PVDD3_3V_SYNTH_LDO_B4"
CH5_VNOM="3.3"; CH5_NET="PVDD3_3V_SYNTH_LDO_A4"
CH6_VNOM="3.3"; CH6_NET="P3V3"
CH7_VNOM="0.8"; CH7_NET="PVDD0_8V_T3"
CH1_VNOM="1.816"; CH1_NET="P1V8_4"
CH2_VNOM="3.38"; CH2_NET="PVDD3_3V_SYNTH_LDO_B5"
CH3_VNOM="3.38"; CH3_NET="PVDD3_3V_SYNTH_LDO_A5"
CH4_VNOM="3.38"; CH4_NET="PVDD3_3V_SYNTH_LDO_B4"
CH5_VNOM="3.38"; CH5_NET="PVDD3_3V_SYNTH_LDO_A4"
CH6_VNOM="3.327"; CH6_NET="P3V3"
CH7_VNOM="0.82"; CH7_NET="PVDD0_8V_T3"
CH8_VNOM="0.75"; CH8_NET="P0V75_DVDD_1"
CH9_VNOM="0.75"; CH9_NET="P0V75_AVDD_1"
CH10_VNOM="1.5"; CH10_NET="P1V5_AVDD_1"
CH11_VNOM="0.9"; CH11_NET="P0V9_AVDD_1"
CH12_VNOM="0.9"; CH12_NET="PVDD0V9_0"
CH13_VNOM="0.9"; CH13_NET="PVDD0V9_1"
CH14_VNOM="0.9"; CH14_NET="PVDD0V9_3"
CH15_VNOM="1.2"; CH15_NET="PVDD1V2_T3"
CH9_VNOM="0.756"; CH9_NET="P0V75_AVDD_1"
CH10_VNOM="1.524"; CH10_NET="P1V5_AVDD_1"
CH11_VNOM="0.915"; CH11_NET="P0V9_AVDD_1"
CH12_VNOM="0.915"; CH12_NET="PVDD0V9_0"
CH13_VNOM="0.91"; CH13_NET="PVDD0V9_1"
CH14_VNOM="0.915"; CH14_NET="PVDD0V9_3"
CH15_VNOM="1.224"; CH15_NET="PVDD1V2_T3"
@@ -35,18 +35,18 @@ CHIP_POST_CMD=(
# chip1: SWB1 (CONN13)
# ============================================================
CH0_VNOM="0.75"; CH0_NET="P0V75_DVDD_47"
CH1_VNOM="0.75"; CH1_NET="P0V75_AVDD_47"
CH2_VNOM="1.5"; CH2_NET="P1V5_AVDD_47"
CH3_VNOM="0.9"; CH3_NET="P0V9_AVDD_47"
CH4_VNOM="1.8"; CH4_NET="P1V8_1"
CH5_VNOM="3.3"; CH5_NET="PVDD3_3V_SYNTH_LDO_A3"
CH6_VNOM="3.3"; CH6_NET="PVDD3_3V_SYNTH_LDO_B1"
CH7_VNOM="1.8"; CH7_NET="P1V8_3"
CH1_VNOM="0.756"; CH1_NET="P0V75_AVDD_47"
CH2_VNOM="1.524"; CH2_NET="P1V5_AVDD_47"
CH3_VNOM="0.915"; CH3_NET="P0V9_AVDD_47"
CH4_VNOM="1.816"; CH4_NET="P1V8_1"
CH5_VNOM="3.38"; CH5_NET="PVDD3_3V_SYNTH_LDO_A3"
CH6_VNOM="3.38"; CH6_NET="PVDD3_3V_SYNTH_LDO_B1"
CH7_VNOM="1.816"; CH7_NET="P1V8_3"
CH8_VNOM="1.8"; CH8_NET="P1V8_DVDDIO_3"
CH9_VNOM="0.75"; CH9_NET="P0V75_DVDD_39"
CH10_VNOM="0.75"; CH10_NET="P0V75_AVDD_39"
CH11_VNOM="1.5"; CH11_NET="P1V5_AVDD_39"
CH12_VNOM="0.9"; CH12_NET="P0V9_AVDD_39"
CH10_VNOM="0.756"; CH10_NET="P0V75_AVDD_39"
CH11_VNOM="1.524"; CH11_NET="P1V5_AVDD_39"
CH12_VNOM="0.915"; CH12_NET="P0V9_AVDD_39"
CH13_VNOM="1.5"; CH13_NET="PVDD1V5_2"
CH14_VNOM="1.8"; CH14_NET="PVDD1V8_DUT"
CH15_VNOM="1.2"; CH15_NET="PVDD_MDIO"
@@ -34,16 +34,16 @@ CHIP_POST_CMD=(
# ============================================================
# chip1: SWB1 (CONN14)
# ============================================================
CH0_VNOM="0.75"; CH0_NET="P0V75_AVDD_7"
CH1_VNOM="1.5"; CH1_NET="P1V5_AVDD_7"
CH2_VNOM="0.9"; CH2_NET="P0V9_AVDD_7"
CH3_VNOM="1.8"; CH3_NET="P1V8_5"
CH4_VNOM="1.8"; CH4_NET="P1V8_2"
CH5_VNOM="3.3"; CH5_NET="PVDD3_3V_SYNTH_LDO_B2"
CH6_VNOM="3.3"; CH6_NET="PVDD3_3V_SYNTH_LDO_A2"
CH7_VNOM="3.3"; CH7_NET="PVDD3_3V_SYNTH_LDO_A1"
CH8_VNOM="1.5"; CH8_NET="PVDD1V5_TSC"
CH9_VNOM="1.5"; CH9_NET="PVDD1V5_ANLG"
CH0_VNOM="0.756"; CH0_NET="P0V75_AVDD_7"
CH1_VNOM="1.524"; CH1_NET="P1V5_AVDD_7"
CH2_VNOM="0.915"; CH2_NET="P0V9_AVDD_7"
CH3_VNOM="1.816"; CH3_NET="P1V8_5"
CH4_VNOM="1.816"; CH4_NET="P1V8_2"
CH5_VNOM="3.38"; CH5_NET="PVDD3_3V_SYNTH_LDO_B2"
CH6_VNOM="3.38"; CH6_NET="PVDD3_3V_SYNTH_LDO_A2"
CH7_VNOM="3.38"; CH7_NET="PVDD3_3V_SYNTH_LDO_A1"
CH8_VNOM="1.516"; CH8_NET="PVDD1V5_TSC"
CH9_VNOM="1.516"; CH9_NET="PVDD1V5_ANLG"
CH10_VNOM="-"; CH10_NET="NC"
CH11_VNOM="-"; CH11_NET="NC"
CH12_VNOM="1.5"; CH12_NET="PVDD1V5_1"
@@ -34,19 +34,19 @@ CHIP_POST_CMD=(
# ============================================================
# chip1: SWB1 (CONN15)
# ============================================================
CH0_VNOM="1.5"; CH0_NET="P1V5_AVDD_55"
CH1_VNOM="0.9"; CH1_NET="P0V9_AVDD_55"
CH0_VNOM="1.524"; CH0_NET="P1V5_AVDD_55"
CH1_VNOM="0.915"; CH1_NET="P0V9_AVDD_55"
CH2_VNOM="0.75"; CH2_NET="P0V75_DVDD_63"
CH3_VNOM="0.75"; CH3_NET="P0V75_AVDD_63"
CH4_VNOM="1.5"; CH4_NET="P1V5_AVDD_63"
CH5_VNOM="0.9"; CH5_NET="P0V9_AVDD_63"
CH6_VNOM="3.3"; CH6_NET="PVDD3_3V_SYNTH_LDO_B3"
CH3_VNOM="0.756"; CH3_NET="P0V75_AVDD_63"
CH4_VNOM="1.524"; CH4_NET="P1V5_AVDD_63"
CH5_VNOM="0.915"; CH5_NET="P0V9_AVDD_63"
CH6_VNOM="3.38"; CH6_NET="PVDD3_3V_SYNTH_LDO_B3"
CH7_VNOM="1.5"; CH7_NET="PVDD1V5_3"
CH8_VNOM="0.85"; CH8_NET="P0V85_STBY"
CH9_VNOM="1.8"; CH9_NET="P1V8_STBY"
CH10_VNOM="-"; CH10_NET="NC"
CH11_VNOM="3.3"; CH11_NET="P3V3_STBY"
CH12_VNOM="0.9"; CH12_NET="PVDD0V9_2"
CH12_VNOM="0.91"; CH12_NET="PVDD0V9_2"
CH13_VNOM="0.75"; CH13_NET="P0V75_DVDD_55"
CH14_VNOM="0.75"; CH14_NET="P0V75_AVDD_55"
CH14_VNOM="0.756"; CH14_NET="P0V75_AVDD_55"
CH15_VNOM="1.8"; CH15_NET="P1V8_DVDDIO_4"
@@ -35,18 +35,18 @@ CHIP_POST_CMD=(
# chip1: SWB1 (CONN16)
# ============================================================
CH0_VNOM="1.5"; CH0_NET="PVDD1V5_0"
CH1_VNOM="1.8"; CH1_NET="P1V8_4"
CH2_VNOM="3.3"; CH2_NET="PVDD3_3V_SYNTH_LDO_B5"
CH3_VNOM="3.3"; CH3_NET="PVDD3_3V_SYNTH_LDO_A5"
CH4_VNOM="3.3"; CH4_NET="PVDD3_3V_SYNTH_LDO_B4"
CH5_VNOM="3.3"; CH5_NET="PVDD3_3V_SYNTH_LDO_A4"
CH6_VNOM="3.3"; CH6_NET="P3V3"
CH7_VNOM="0.8"; CH7_NET="PVDD0_8V_T3"
CH1_VNOM="1.816"; CH1_NET="P1V8_4"
CH2_VNOM="3.38"; CH2_NET="PVDD3_3V_SYNTH_LDO_B5"
CH3_VNOM="3.38"; CH3_NET="PVDD3_3V_SYNTH_LDO_A5"
CH4_VNOM="3.38"; CH4_NET="PVDD3_3V_SYNTH_LDO_B4"
CH5_VNOM="3.38"; CH5_NET="PVDD3_3V_SYNTH_LDO_A4"
CH6_VNOM="3.327"; CH6_NET="P3V3"
CH7_VNOM="0.82"; CH7_NET="PVDD0_8V_T3"
CH8_VNOM="0.75"; CH8_NET="P0V75_DVDD_1"
CH9_VNOM="0.75"; CH9_NET="P0V75_AVDD_1"
CH10_VNOM="1.5"; CH10_NET="P1V5_AVDD_1"
CH11_VNOM="0.9"; CH11_NET="P0V9_AVDD_1"
CH12_VNOM="0.9"; CH12_NET="PVDD0V9_0"
CH13_VNOM="0.9"; CH13_NET="PVDD0V9_1"
CH14_VNOM="0.9"; CH14_NET="PVDD0V9_3"
CH15_VNOM="1.2"; CH15_NET="PVDD1V2_T3"
CH9_VNOM="0.756"; CH9_NET="P0V75_AVDD_1"
CH10_VNOM="1.524"; CH10_NET="P1V5_AVDD_1"
CH11_VNOM="0.915"; CH11_NET="P0V9_AVDD_1"
CH12_VNOM="0.915"; CH12_NET="PVDD0V9_0"
CH13_VNOM="0.91"; CH13_NET="PVDD0V9_1"
CH14_VNOM="0.915"; CH14_NET="PVDD0V9_3"
CH15_VNOM="1.224"; CH15_NET="PVDD1V2_T3"
@@ -0,0 +1,95 @@
#!/bin/bash
# =============================================================================
# TH6_SWB0_power_readback.sh -- SWB0 rail power from the platform sensors
# =============================================================================
# Version History:
# V1.1.0 2026-08-28 'show platform voltage' and 'show platform current' are
# now read ONCE each instead of once per rail. The old
# loop ran them 19 times apiece (38 invocations of a slow
# Python CLI) and every sample came from a different
# instant, so the rails were never actually measured
# together. Output format is unchanged.
# Rails missing from the tables are reported on stderr
# instead of silently contributing 0.000 V / 0.00 W.
# V1.0.0 2026-08-28 First version.
# =============================================================================
#
# Reads the two platform sensor tables:
# 'show platform voltage' -> <RAIL> in mV
# 'show platform current' -> <RAIL>_CURRENT in mA
# and reports V x I per rail plus the total.
#
# For a loaded reading, start traffic first: blanton_tr518.sh start
# =============================================================================
# --- Rails to report, in output order (edit this list) ---
rails=(
"SWB0_0V9_ANLG0"
"SWB0_0V9_ANLG1"
"SWB0_0V75_ANLG0"
"SWB0_0V75_ANLG1"
"SWB0_PHYTILE_P0"
"SWB0_PHYTILE_P1"
"SWB0_PHYTILE_P2"
"SWB0_PHYTILE_P3"
"SWB0_PHYTILE_P4"
"SWB0_PHYTILE_P5"
"SWB0_PHYTILE_P6"
"SWB0_PHYTILE_P7"
"SWB0_PVDD1V5_CNDR0"
"SWB0_PVDD1V5_CNDR1"
"SWB0_PVDDA_PHYT0"
"SWB0_PVDDA_PHYT1"
"SWB0_PVDDA_PHYT2"
"SWB0_PVDDA_PHYT3"
"SWB0_TH6_CORE"
)
# --- One snapshot of each table ---------------------------------------------
# Both are taken up front, back to back, so every rail below comes from the same
# moment. Under tr 518 the currents move a lot; re-reading per rail meant the
# total was a sum of readings taken seconds apart.
V_TABLE="$(show platform voltage 2>/dev/null)"
C_TABLE="$(show platform current 2>/dev/null)"
if [ -z "$V_TABLE" ] || [ -z "$C_TABLE" ]; then
echo "ERROR: 'show platform voltage/current' returned nothing" >&2
exit 1
fi
# --- Join and report ---------------------------------------------------------
# Sensor name is field 1 and the value field 2 in both tables; header and rule
# lines drop out because their field 2 is not numeric.
{
printf '%s\n' "$V_TABLE"
echo "@@@SPLIT@@@"
printf '%s\n' "$C_TABLE"
} | awk -v rails="${rails[*]}" '
BEGIN { n = split(rails, R, " "); sec = 1 }
/^@@@SPLIT@@@$/ { sec = 2; next }
{
if (NF < 2) next
name = $1; val = $2
if (val !~ /^[0-9]+(\.[0-9]+)?$/) next # header / ---- / blank
if (sec == 2) CUR[name] = val + 0
else VOLT[name] = val + 0
}
END {
total = 0
for (i = 1; i <= n; i++) {
rail = R[i]; cname = rail "_CURRENT"
haveV = (rail in VOLT); haveC = (cname in CUR)
if (!haveV || !haveC)
printf "WARN: %s missing from the sensor table (%s%s%s) -- counted as 0 W\n", \
rail, (haveV ? "" : "no voltage"), \
((!haveV && !haveC) ? ", " : ""), \
(haveC ? "" : "no current") > "/dev/stderr"
v = haveV ? VOLT[rail] : 0
c = haveC ? CUR[cname] : 0
p = sprintf("%.2f", (v/1000)*(c/1000))
printf "%s: Voltage=%.3f V, Current=%.3f A, Power=%.2f W\n", rail, v/1000, c/1000, p
total = sprintf("%.2f", total + p)
}
print "----------------------------------------"
printf "TOTAL POWER: %.2f W\n", total
}'
@@ -0,0 +1,95 @@
#!/bin/bash
# =============================================================================
# TH6_SWB1_power_readback.sh -- SWB1 rail power from the platform sensors
# =============================================================================
# Version History:
# V1.1.0 2026-08-28 'show platform voltage' and 'show platform current' are
# now read ONCE each instead of once per rail. The old
# loop ran them 19 times apiece (38 invocations of a slow
# Python CLI) and every sample came from a different
# instant, so the rails were never actually measured
# together. Output format is unchanged.
# Rails missing from the tables are reported on stderr
# instead of silently contributing 0.000 V / 0.00 W.
# V1.0.0 2026-08-28 First version.
# =============================================================================
#
# Reads the two platform sensor tables:
# 'show platform voltage' -> <RAIL> in mV
# 'show platform current' -> <RAIL>_CURRENT in mA
# and reports V x I per rail plus the total.
#
# For a loaded reading, start traffic first: blanton_tr518.sh start
# =============================================================================
# --- Rails to report, in output order (edit this list) ---
rails=(
"SWB1_0V9_ANLG0"
"SWB1_0V9_ANLG1"
"SWB1_0V75_ANLG0"
"SWB1_0V75_ANLG1"
"SWB1_PHYTILE_P0"
"SWB1_PHYTILE_P1"
"SWB1_PHYTILE_P2"
"SWB1_PHYTILE_P3"
"SWB1_PHYTILE_P4"
"SWB1_PHYTILE_P5"
"SWB1_PHYTILE_P6"
"SWB1_PHYTILE_P7"
"SWB1_PVDD1V5_CNDR0"
"SWB1_PVDD1V5_CNDR1"
"SWB1_PVDDA_PHYT0"
"SWB1_PVDDA_PHYT1"
"SWB1_PVDDA_PHYT2"
"SWB1_PVDDA_PHYT3"
"SWB1_TH6_CORE"
)
# --- One snapshot of each table ---------------------------------------------
# Both are taken up front, back to back, so every rail below comes from the same
# moment. Under tr 518 the currents move a lot; re-reading per rail meant the
# total was a sum of readings taken seconds apart.
V_TABLE="$(show platform voltage 2>/dev/null)"
C_TABLE="$(show platform current 2>/dev/null)"
if [ -z "$V_TABLE" ] || [ -z "$C_TABLE" ]; then
echo "ERROR: 'show platform voltage/current' returned nothing" >&2
exit 1
fi
# --- Join and report ---------------------------------------------------------
# Sensor name is field 1 and the value field 2 in both tables; header and rule
# lines drop out because their field 2 is not numeric.
{
printf '%s\n' "$V_TABLE"
echo "@@@SPLIT@@@"
printf '%s\n' "$C_TABLE"
} | awk -v rails="${rails[*]}" '
BEGIN { n = split(rails, R, " "); sec = 1 }
/^@@@SPLIT@@@$/ { sec = 2; next }
{
if (NF < 2) next
name = $1; val = $2
if (val !~ /^[0-9]+(\.[0-9]+)?$/) next # header / ---- / blank
if (sec == 2) CUR[name] = val + 0
else VOLT[name] = val + 0
}
END {
total = 0
for (i = 1; i <= n; i++) {
rail = R[i]; cname = rail "_CURRENT"
haveV = (rail in VOLT); haveC = (cname in CUR)
if (!haveV || !haveC)
printf "WARN: %s missing from the sensor table (%s%s%s) -- counted as 0 W\n", \
rail, (haveV ? "" : "no voltage"), \
((!haveV && !haveC) ? ", " : ""), \
(haveC ? "" : "no current") > "/dev/stderr"
v = haveV ? VOLT[rail] : 0
c = haveC ? CUR[cname] : 0
p = sprintf("%.2f", (v/1000)*(c/1000))
printf "%s: Voltage=%.3f V, Current=%.3f A, Power=%.2f W\n", rail, v/1000, c/1000, p
total = sprintf("%.2f", total + p)
}
print "----------------------------------------"
printf "TOTAL POWER: %.2f W\n", total
}'
@@ -0,0 +1,495 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_ber.sh -- SerDes BER test over every cabled port (PRBS via phydiag)
# =============================================================================
# Version History:
# V1.0.1 2026-08-28 Fix: every lane reported NA and the Port column showed
# "NA". bcmcmd returns CRLF, and the BER is the last token
# on its line, so the CR stayed glued to the number: it
# failed the numeric test (-> NA) and printing it sent the
# cursor back to column 1, so the RESULT column overwrote
# the start of the row. The parser now strips CR first.
# (The traffic report never hit this -- there the counter
# is followed by a delta, so the CR was trimmed with it.)
# V1.0.0 2026-08-28 First version. Bash port of tools/BER_Test.txt.
# init/clear/start/stop/report, -u 0|1|all (default both).
# report parses 'prbsstat Ber' into a per-lane table with a
# PASS/FAIL against BER_MAX (default 1e-6) and a summary
# across units at the very bottom.
# =============================================================================
#
# This is the WHOLE-SWITCH BER sweep: every cabled port, both lanes, PRBS-31
# through the SerDes. Not to be confused with port_prbs_monitor.sh, which drives
# the two 100G uplinks only and polls them continuously.
#
# Order of operations (matches tools/BER_Test.txt):
# init phydiag <ports> prbs set p=3 arm PRBS on every lane
# phydiag <ports> prbs get confirm every lane locked
# start phydiag <ports> prbsstat STArt Interval=<n>
# ...wait at least one Interval...
# report phydiag <ports> prbsstat Ber read + judge
# stop phydiag <ports> prbsstat STOp
# clear phydiag <ports> prbs clear disarm, release the lanes
#
# ⚠️ 'clear' disarms PRBS -- run 'init' again before another measurement.
# ⚠️ PRBS takes the SerDes out of normal operation: the links report DOWN and no
# traffic passes while it is armed. Do not run this alongside
# blanton_traffic_linespeed or blanton_tr518.
#
# Usage (run directly):
# ./blanton_ber.sh init # both units
# ./blanton_ber.sh start -u 0 # unit 0 only
# ./blanton_ber.sh report
# ./blanton_ber.sh stop
# ./blanton_ber.sh clear
#
# Usage (sourced, like the other blanton_*.sh tools):
# source blanton_ber.sh
# blanton_ber report -u 1
#
# Options:
# -u|--unit <0|1|all|0,1> bcmcmd unit(s). Default: $BER_UNITS ("0 1")
# -c|--criteria <ber> report: PASS threshold (default $BER_MAX)
# -i|--interval <sec> start: prbsstat Interval (default $BER_INTERVAL)
# -p|--ports <list> override the port list
# -F|--fail-only report: list only the lanes that FAIL
# --tsv report: tab-separated (paste into Excel)
# --raw report: also print the raw 'prbsstat Ber' output
# --color|--no-color report: force / disable colours
# -f|--file <log> report: parse a saved console log, do not touch DUT
# -d|--debug print every bcmcmd before running it
# -n|--dry-run print commands only, do not touch the DUT
# -h|--help help
#
# Environment overrides:
# BCMCMD_CMD=bcmcmd BER_UNITS="0 1" BER_MAX=1e-6 BER_INTERVAL=30
# BER_PORTS="1-24,..." BER_POLY=p=3 BER_LOG_DIR=/tmp DEBUG_MODE=1
# =============================================================================
# === Config ==================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
BER_UNITS="${BER_UNITS:-0 1}" # one DUT = two switch boards (0 and 1)
# The cabled ports, in bcm logical-port numbering. Same list as
# blanton_traffic_linespeed.sh's TL_PS_PORTS -- kept as one string so it can be
# pasted straight from/into a manual phydiag command.
BER_PORTS="${BER_PORTS:-1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565}"
BER_POLY="${BER_POLY:-p=3}" # passed to 'prbs set'
BER_INTERVAL="${BER_INTERVAL:-30}" # passed to 'prbsstat STArt Interval='
# PASS threshold. A lane PASSES when its BER is strictly BELOW this.
# 1e-6 is the acceptance figure for this project; the measured lanes sit around
# 1e-13..1e-8, so anything near the threshold is already a real finding.
BER_MAX="${BER_MAX:-1e-6}"
BER_LOG_DIR="${BER_LOG_DIR:-/tmp}" # where the raw 'prbsstat Ber' capture goes
BER_FAIL_ONLY=${BER_FAIL_ONLY:-0}
BER_TSV=${BER_TSV:-0}
BER_RAW=${BER_RAW:-0}
BER_REPORT_FILE="" # -f <log>: parse this instead of the DUT
BER_COLOR="${BER_COLOR:-auto}" # auto|always|never
DEBUG_MODE=${DEBUG_MODE:-0}
BER_DRY_RUN=${BER_DRY_RUN:-0}
# === Logging =================================================================
_ber_info() { echo -e "[\033[34mINFO\033[0m] $*"; }
_ber_ok() { echo -e "[\033[32m OK \033[0m] $*"; }
_ber_warn() { echo -e "[\033[33mWARN\033[0m] $*" >&2; }
_ber_err() { echo -e "[\033[31mERR \033[0m] $*" >&2; }
_ber_dbg() { [ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] $*\033[0m" >&2; return 0; }
# === bcmcmd wrapper ==========================================================
# stdin closed for the same reason as blanton_traffic_linespeed.sh: bcmcmd
# otherwise inherits the caller's stdin and eats what a surrounding loop reads.
#
# bcmcmd exits 0 even when the BCM shell refused the command, so the output is
# pattern-matched as well. And it exits NON-zero on long-running commands whose
# response poll times out while the command is in fact fine -- that one is
# tolerated (the blanton_tr518.sh lesson).
BER_ERR_PAT="${BER_ERR_PAT:-ERROR|Failed to execute|Invalid|Syntax error|Unavailable|Unknown command}"
BER_BENIGN_PAT="${BER_BENIGN_PAT:-polling socket timeout}"
# _ber_bcm <unit> <phydiag args...> -- wraps in dsh -c 'phydiag <ports> ...'
# echoes the DUT output on stdout, returns 0 ok / 1 failed
_ber_bcm() {
local unit="$1"; shift
local inner="phydiag ${BER_PORTS} $*"
local cmd="dsh -c '${inner}'"
_ber_dbg "$BCMCMD_CMD -n $unit -c \"${cmd}\""
if [ "$BER_DRY_RUN" = "1" ]; then
echo "[DRY ] $BCMCMD_CMD -n $unit -c \" ${cmd} \"" >&2
return 0
fi
local out rc
out=$("$BCMCMD_CMD" -n "$unit" -c "$cmd" </dev/null 2>&1); rc=$?
printf '%s\n' "$out"
if echo "$out" | grep -qiE "$BER_ERR_PAT"; then
_ber_err "unit $unit: the BCM shell rejected 'phydiag ... $*'"
return 1
fi
if [ "$rc" -ne 0 ] && ! echo "$out" | grep -qiE "$BER_BENIGN_PAT"; then
_ber_err "unit $unit: bcmcmd exited $rc on 'phydiag ... $*'"
return 1
fi
return 0
}
_ber_units_check() {
local u ok=""
for u in $BER_UNITS; do
case "$u" in
0|1) ok="$ok $u" ;;
*) _ber_err "invalid unit '$u' (use 0, 1 or all)"; return 1 ;;
esac
done
[ -n "$ok" ] || { _ber_err "no unit selected"; return 1; }
BER_UNITS="${ok# }"
return 0
}
_ber_use_color() {
case "$BER_COLOR" in
always|1|yes) return 0 ;;
never|0|no) return 1 ;;
*) [ -t 1 ] && [ "$BER_TSV" != "1" ] ;;
esac
}
# === init ====================================================================
# prbs set + prbs get. The 'get' is not decoration: a lane that did not lock
# still reports a BER later, and it is a meaningless one.
blanton_ber_init() {
_ber_units_check || return 1
local unit out total ok rc=0
for unit in $BER_UNITS; do
_ber_info "unit $unit: prbs set ${BER_POLY} on ${BER_PORTS}"
_ber_bcm "$unit" "prbs set ${BER_POLY}" >/dev/null || { rc=1; continue; }
out=$(_ber_bcm "$unit" "prbs get") || { rc=1; continue; }
[ "$BER_DRY_RUN" = "1" ] && continue
# lines look like: " 185 : PRBS OK!has been unlocked since last call"
total=$(printf '%s\n' "$out" | grep -cE '^[ \t]*[0-9]+[ \t]*:')
ok=$(printf '%s\n' "$out" | grep -cE '^[ \t]*[0-9]+[ \t]*:.*PRBS OK')
if [ "$total" -eq 0 ]; then
_ber_err "unit $unit: 'prbs get' reported no lanes at all"
rc=1
elif [ "$ok" -eq "$total" ]; then
_ber_ok "unit $unit: $ok/$total ports locked"
else
_ber_warn "unit $unit: only $ok/$total ports locked -- the rest will report a meaningless BER:"
printf '%s\n' "$out" | grep -E '^[ \t]*[0-9]+[ \t]*:' | grep -v 'PRBS OK' >&2
rc=2
fi
done
return $rc
}
# === clear ===================================================================
blanton_ber_clear() {
_ber_units_check || return 1
local unit rc=0
for unit in $BER_UNITS; do
_ber_info "unit $unit: prbs clear"
_ber_bcm "$unit" "prbs clear" >/dev/null || rc=1
done
[ "$rc" -eq 0 ] && _ber_ok "PRBS disarmed on unit(s): $BER_UNITS -- run 'init' before measuring again"
return $rc
}
# === start ===================================================================
blanton_ber_start() {
_ber_units_check || return 1
local unit rc=0
for unit in $BER_UNITS; do
_ber_info "unit $unit: prbsstat STArt Interval=${BER_INTERVAL}"
_ber_bcm "$unit" "prbsstat STArt Interval=${BER_INTERVAL}" >/dev/null || rc=1
done
if [ "$rc" -eq 0 ]; then
_ber_ok "BER accumulation running on unit(s): $BER_UNITS"
_ber_info "wait at least ${BER_INTERVAL}s before 'report' -- a shorter run has not accumulated a full interval"
fi
return $rc
}
# === stop ====================================================================
blanton_ber_stop() {
_ber_units_check || return 1
local unit rc=0
for unit in $BER_UNITS; do
_ber_info "unit $unit: prbsstat STOp"
_ber_bcm "$unit" "prbsstat STOp" >/dev/null || rc=1
done
if [ "$rc" -eq 0 ]; then
_ber_ok "BER accumulation stopped on unit(s): $BER_UNITS"
_ber_info "PRBS is still armed -- 'clear' releases the lanes and restores normal operation"
fi
return $rc
}
# === report ==================================================================
# Parses 'prbsstat Ber' output:
# port BER
# ====
# 1[0] : 3.53e-11
# 1[1] : 4.00e-11
# into <port> <lane> <ber> <verdict>, PASS when ber < BER_MAX.
# _ber_render <logfile> [side_file] -> 0 all PASS, 2 any FAIL/NA, 1 parse error
_ber_render() {
local log="$1" side="${2:-/dev/null}" color=0
_ber_use_color && color=1
awk -v MAXBER="$BER_MAX" \
-v FAILONLY="$BER_FAIL_ONLY" \
-v TSV="$BER_TSV" \
-v COLOR="$color" \
-v SIDE="$side" '
function vc(v) {
if (!COLOR) return v
if (v == "PASS") return "\033[32m" v "\033[0m"
if (v == "FAIL") return "\033[31m" v "\033[0m"
return "\033[33m" v "\033[0m"
}
BEGIN {
LIM = MAXBER + 0
NC = 4
HDR[1] = "Port"; AL[1] = 1
HDR[2] = "Lane"; AL[2] = 1
HDR[3] = "BER"; AL[3] = 1
HDR[4] = "RESULT"; AL[4] = 1
worst = -1; worstlane = "-"
}
# bcmcmd hands back CRLF. On the cd/traffic report the counter is followed by
# a delta, so the CR got trimmed with the rest of the line; here the BER is
# the LAST token, so the CR sticks to the number -- it failed the numeric
# test (every lane NA) and, worse, printing it moved the cursor back to
# column 1 so the RESULT column overwrote the start of the row.
{ gsub(/\r/, "") }
{
# " 203[1] : 5.05e-09" (leading spaces vary, "====" separators ignored)
if ($0 !~ /^[ \t]*[0-9]+\[[0-9]+\][ \t]*:/) next
line = $0
sub(/^[ \t]+/, "", line)
p = index(line, "[")
q = index(line, "]")
c = index(line, ":")
port = substr(line, 1, p - 1)
lane = substr(line, p + 1, q - p - 1)
ber = substr(line, c + 1)
gsub(/^[ \t\r]+|[ \t\r]+$/, "", ber)
sub(/[ \t\r].*$/, "", ber)
seen++
n++
PORT[n] = port; LANE[n] = lane; BERS[n] = ber
# a lane that reported something non-numeric has no usable measurement
if (ber ~ /^[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/) {
v = ber + 0
if (v < LIM) { V[n] = "PASS"; npass++ }
else { V[n] = "FAIL"; nfail++ }
if (v > worst) { worst = v; worstlane = port "[" lane "]"; worststr = ber }
} else {
V[n] = "NA"; nna++
}
}
END {
if (seen == 0) {
print "error: no \"<port>[<lane>] : <ber>\" line found in the log" > "/dev/stderr"
exit 1
}
# column widths over the rows that will actually be printed
for (c2 = 1; c2 <= NC; c2++) w[c2] = length(HDR[c2])
for (i = 1; i <= n; i++) {
if (FAILONLY && V[i] == "PASS") continue
if (length(PORT[i]) > w[1]) w[1] = length(PORT[i])
if (length(LANE[i]) > w[2]) w[2] = length(LANE[i])
if (length(BERS[i]) > w[3]) w[3] = length(BERS[i])
if (length(V[i]) > w[4]) w[4] = length(V[i])
}
for (c2 = 1; c2 <= NC; c2++) w[c2] += 2
if (TSV) {
print HDR[1] "\t" HDR[2] "\t" HDR[3] "\t" HDR[4]
for (i = 1; i <= n; i++) {
if (FAILONLY && V[i] == "PASS") continue
print PORT[i] "\t" LANE[i] "\t" BERS[i] "\t" V[i]
}
} else {
printf "%*s%*s%*s%*s\n", w[1], HDR[1], w[2], HDR[2], w[3], HDR[3], w[4], HDR[4]
for (i = 1; i <= n; i++) {
if (FAILONLY && V[i] == "PASS") continue
printf "%*s%*s%*s", w[1], PORT[i], w[2], LANE[i], w[3], BERS[i]
# pad on the plain text, then colour, so the columns stay aligned
printf "%*s%s\n", w[4] - length(V[i]), "", vc(V[i])
}
if (FAILONLY && nfail == 0 && nna == 0)
print " (no failing lane)"
}
print ""
printf "# lanes measured : %d\n", n
printf "# %s %d %s %d %s %d (criteria BER < %s)\n", \
vc("PASS"), npass + 0, vc("FAIL"), nfail + 0, vc("NA"), nna + 0, MAXBER
if (worst >= 0)
printf "# worst lane : %s %s\n", worstlane, worststr
if (SIDE != "" && SIDE != "/dev/null")
printf "SUM %d %d %d %d %s %s\n", n, npass + 0, nfail + 0, nna + 0, \
(worst >= 0 ? worststr : "-"), worstlane > SIDE
exit (nfail || nna) ? 2 : 0
}' "$log"
}
# _ber_summary <stamp> -- one table for every unit, printed last
_ber_summary() {
local stamp="$1" unit side g r y n worst=0
g=$'\033[32m'; r=$'\033[31m'; y=$'\033[33m'; n=$'\033[0m'
_ber_use_color || { g=""; r=""; y=""; n=""; }
echo ""
echo "===== summary : all units ====="
printf '%-8s %8s %8s %8s %8s %-12s %-10s %s\n' \
"Unit" "LANES" "PASS" "FAIL" "NA" "WORST BER" "WORST LANE" "RESULT"
local tag lanes pass fail na wber wlane v any=0
for unit in $BER_UNITS; do
side="$BER_LOG_DIR/berside_unit${unit}_${stamp}"
[ -r "$side" ] || continue
read -r tag lanes pass fail na wber wlane < "$side" 2>/dev/null
[ "$tag" = "SUM" ] || continue
any=1
if [ "${fail:-0}" -gt 0 ] || [ "${na:-0}" -gt 0 ]; then
v="${r}FAIL${n}"; worst=2
else
v="${g}PASS${n}"
fi
printf '%-8s %8s %8s %8s %8s %-12s %-10s %b\n' \
"unit $unit" "$lanes" "$pass" "$fail" "$na" "$wber" "$wlane" "$v"
done
[ "$any" = "1" ] || echo " (no unit produced a result)"
echo ""
printf 'criteria: BER < %s\n' "$BER_MAX"
echo ""
return "$worst"
}
blanton_ber_report() {
local unit log side rc worst=0 stamp
# -f <log>: offline, no DUT access, no unit loop -> no cross-unit summary
if [ -n "$BER_REPORT_FILE" ]; then
[ -r "$BER_REPORT_FILE" ] || { _ber_err "cannot read log '$BER_REPORT_FILE'"; return 1; }
_ber_info "report from log: $BER_REPORT_FILE (criteria BER < $BER_MAX)" >&2
_ber_render "$BER_REPORT_FILE"; return $?
fi
_ber_units_check || return 1
if [ "$BER_DRY_RUN" = "1" ]; then
for unit in $BER_UNITS; do _ber_bcm "$unit" "prbsstat Ber" >/dev/null; done
return 0
fi
stamp=$(date +%Y%m%d_%H%M%S 2>/dev/null || echo now)
for unit in $BER_UNITS; do
log="$BER_LOG_DIR/prbsber_unit${unit}_${stamp}.log"
side="$BER_LOG_DIR/berside_unit${unit}_${stamp}"
: > "$side"
if ! _ber_bcm "$unit" "prbsstat Ber" > "$log" 2>&1; then
_ber_err "unit $unit: 'prbsstat Ber' failed (see $log)"; worst=1; continue
fi
[ "$BER_RAW" = "1" ] && { echo "----- unit $unit : raw prbsstat Ber -----"; cat "$log"; }
echo "===== unit $unit : PRBS BER report (raw: $log) ====="
_ber_render "$log" "$side"; rc=$?
[ "$rc" -gt "$worst" ] && worst=$rc
case "$rc" in
0) _ber_ok "unit $unit: every lane below $BER_MAX" ;;
2) _ber_warn "unit $unit: at least one lane FAIL/NA" ;;
*) _ber_err "unit $unit: report parse error" ;;
esac
done
_ber_summary "$stamp"; rc=$?
[ "$rc" -gt "$worst" ] && worst=$rc
rm -f "$BER_LOG_DIR"/berside_unit*_"${stamp}"
return "$worst"
}
# === Help ====================================================================
blanton_ber_help() {
echo -e "\033[1mblanton_ber.sh - SerDes BER test over every cabled port (PRBS via phydiag)\033[0m"
echo ""
echo -e " Units : \033[36m$BER_UNITS\033[0m poly: \033[36m$BER_POLY\033[0m interval: \033[36m${BER_INTERVAL}s\033[0m"
echo -e " Criteria : BER < \033[36m$BER_MAX\033[0m"
echo -e " Ports : \033[36m$BER_PORTS\033[0m"
echo ""
echo -e "\033[1mSubcommands\033[0m"
echo -e " \033[33minit\033[0m prbs set $BER_POLY + prbs get (checks every lane locked)"
echo -e " \033[33mstart\033[0m prbsstat STArt Interval=$BER_INTERVAL"
echo -e " \033[33mreport\033[0m prbsstat Ber -> per-lane table + PASS/FAIL + summary"
echo -e " \033[33mstop\033[0m prbsstat STOp"
echo -e " \033[33mclear\033[0m prbs clear (disarms PRBS -- 'init' again before measuring)"
echo -e " \033[33mhelp\033[0m"
echo ""
echo -e "\033[1mOptions\033[0m"
echo -e " \033[33m-u|--unit\033[0m <0|1|all> bcmcmd unit(s); 'all' = 0 1 (default: $BER_UNITS)"
echo -e " \033[33m-c|--criteria\033[0m <ber> PASS threshold (default $BER_MAX)"
echo -e " \033[33m-i|--interval\033[0m <sec> prbsstat Interval (default $BER_INTERVAL)"
echo -e " \033[33m-p|--ports\033[0m <list> override the port list"
echo -e " \033[33m-F|--fail-only\033[0m report: list only failing lanes"
echo -e " \033[33m--tsv\033[0m report: tab-separated"
echo -e " \033[33m--raw\033[0m report: also print the raw output"
echo -e " \033[33m-f|--file\033[0m <log> report: parse a saved log, do not touch the DUT"
echo -e " \033[33m-d|--debug\033[0m print every bcmcmd"
echo -e " \033[33m-n|--dry-run\033[0m print commands only"
echo ""
echo -e "\033[1mTypical run\033[0m"
echo -e " ./blanton_ber.sh init && ./blanton_ber.sh start"
echo -e " sleep $BER_INTERVAL"
echo -e " ./blanton_ber.sh report"
echo -e " ./blanton_ber.sh stop && ./blanton_ber.sh clear"
echo ""
echo -e "\033[33m PRBS takes the SerDes out of normal operation: links show DOWN and no\033[0m"
echo -e "\033[33m traffic passes. Do not run alongside blanton_traffic_linespeed / blanton_tr518.\033[0m"
}
# === Argument parsing ========================================================
blanton_ber() {
local sub="${1:-help}"; shift 2>/dev/null
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
all|ALL) BER_UNITS="0 1" ;;
*) BER_UNITS="$(echo "$2" | tr ',' ' ')" ;;
esac
shift 2 ;;
-c|--criteria) BER_MAX="$2"; shift 2 ;;
-i|--interval) BER_INTERVAL="$2"; shift 2 ;;
-p|--ports) BER_PORTS="$2"; shift 2 ;;
-f|--file) BER_REPORT_FILE="$2"; shift 2 ;;
-F|--fail-only) BER_FAIL_ONLY=1; shift ;;
--tsv) BER_TSV=1; shift ;;
--raw) BER_RAW=1; shift ;;
--color) BER_COLOR=always; shift ;;
--no-color) BER_COLOR=never; shift ;;
-d|--debug) DEBUG_MODE=1; shift ;;
-n|--dry-run) BER_DRY_RUN=1; shift ;;
-h|--help) blanton_ber_help; return 0 ;;
*) _ber_err "unknown option '$1'"; return 1 ;;
esac
done
case "$sub" in
init) blanton_ber_init ;;
clear) blanton_ber_clear ;;
start) blanton_ber_start ;;
stop) blanton_ber_stop ;;
report) blanton_ber_report ;;
help|-h|--help) blanton_ber_help ;;
*) _ber_err "unknown subcommand '$sub'"; blanton_ber_help; return 1 ;;
esac
}
# Run when executed, define-only when sourced (same as the other blanton_*.sh).
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
blanton_ber "$@"
fi
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,326 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_tr518.sh -- TH6 built-in packet test (tr 518) via bcmcmd
# =============================================================================
# Version History:
# V1.0.1 2026-08-28 Fix: start reported ERR on a run that was actually fine.
# bcmcmd exits NON-zero on 'tr 518' because the test
# outlives its response poll ("polling socket timeout:
# Success") -- the command had been accepted and was
# running. The tr 518 step is now judged on a POSITIVE
# marker in the output ("TR 518 TEST PARAMETERS", which
# the shell prints only after it starts the test) instead
# of on bcmcmd's exit status, and "polling socket timeout"
# is tolerated generally. Failures now also say WHICH
# check tripped (shell rejected it / bcmcmd exited N).
# V1.0.0 2026-08-28 First version. Bash port of tools/TR518.txt, command for
# command. start = port cd lb=mac, l2 learn off,
# test mode nr=yes, tr 518 ... testphase=1, then a settle
# wait so a power reading taken afterwards is a loaded and
# stable one rather than a ramping one.
# stop = port cd lb=none (exactly what TR518.txt does).
# -u 0 | -u 1 | -u all (default both).
# =============================================================================
#
# What this is for: tr 518 loads the switch so the power rails can be measured
# under traffic. The usual sequence is
#
# blanton_tr518.sh start # loads both units, waits to settle
# TH6_SWB0_power_readback.sh # now the numbers mean something
# TH6_SWB1_power_readback.sh
# blanton_tr518.sh stop
#
# ⚠️ tr 518 and blanton_traffic_linespeed CANNOT run at the same time. Both take
# over the cd ports and L2 learning; running one while the other is set up
# gives numbers from neither test. Stop one before the other starts.
#
# ⚠️ stop only undoes the loopback -- see TR_RESTORE_* below.
#
# Usage (run directly):
# ./blanton_tr518.sh start # both units
# ./blanton_tr518.sh start -u 0 # unit 0 only
# ./blanton_tr518.sh start -u 1 # unit 1 only
# ./blanton_tr518.sh stop [-u 0|1]
# ./blanton_tr518.sh help
#
# Usage (sourced, like the other blanton_*.sh tools):
# source blanton_tr518.sh
# blanton_tr518 start -u 0
#
# Options:
# -u|--unit <0|1|all|0,1> bcmcmd unit(s). Default: $TR_UNITS ("0 1")
# -w|--wait <sec> start: settle wait after tr 518 (default $TR_SETTLE_SEC)
# --no-wait start: skip the settle wait entirely
# -d|--debug print every bcmcmd and its output
# -n|--dry-run print commands only, do not touch the DUT
# -h|--help help
#
# Environment overrides:
# BCMCMD_CMD=bcmcmd TR_UNITS="0 1" TR_SETTLE_SEC=120 TR_UNIT_GAP_SEC=1
# TR_TEST_ARGS="..." TR_LB_PORTS=cd TR_RESTORE_LEARN=0 TR_RESTORE_TESTMODE=0
# DEBUG_MODE=1
# =============================================================================
# === Config ==================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
TR_UNITS="${TR_UNITS:-0 1}" # one DUT = two switch boards (0 and 1)
# Settle wait after tr 518 is issued. The point is NOT the test itself -- it is
# to stop someone reading power while traffic is still ramping and reporting a
# number that is neither idle nor loaded. Lower it only if you know the rails
# have already settled.
TR_SETTLE_SEC="${TR_SETTLE_SEC:-120}"
# Gap between unit 0 and unit 1 (each unit is set up as a complete block, the
# way TR518.txt does it -- the cd ports are in MAC loopback, so a unit does not
# depend on the other one being ready).
TR_UNIT_GAP_SEC="${TR_UNIT_GAP_SEC:-1}"
# Ports put into MAC loopback. 'cd' = the cd port group, per TR518.txt.
TR_LB_PORTS="${TR_LB_PORTS:-cd}"
# The tr 518 argument string, verbatim from tools/TR518.txt. One editable line
# so it can be pasted straight from / into a manual bcmcmd.
# Printed by the BCM shell only after tr 518 has accepted its arguments and
# started. Used as the success marker, because bcmcmd's own exit status is not
# trustworthy for a command that runs longer than its response poll.
TR_TEST_OK_PAT="${TR_TEST_OK_PAT:-TR 518 TEST PARAMETERS}"
TR_TEST_ARGS="${TR_TEST_ARGS:-Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=1}"
# TR518.txt stops with 'port cd lb=none' and nothing else, so that is the
# default here too. But note what start changed and stop does NOT put back:
# l2 learn off -> the unit keeps learning disabled
# test mode nr=yes -> the unit stays in test mode
# Both persist until something else changes them or the box reboots. Set these
# to 1 if you want stop to be a true inverse; they are off by default because
# they are not in the bench-verified list.
TR_RESTORE_LEARN="${TR_RESTORE_LEARN:-0}"
TR_RESTORE_TESTMODE="${TR_RESTORE_TESTMODE:-0}"
DEBUG_MODE=${DEBUG_MODE:-0}
TR_DRY_RUN=${TR_DRY_RUN:-0}
TR_NO_WAIT=${TR_NO_WAIT:-0}
# === Logging =================================================================
_tr_info() { echo -e "[\033[34mINFO\033[0m] $*"; }
_tr_ok() { echo -e "[\033[32m OK \033[0m] $*"; }
_tr_warn() { echo -e "[\033[33mWARN\033[0m] $*" >&2; }
_tr_err() { echo -e "[\033[31mERR \033[0m] $*" >&2; }
_tr_dbg() { [ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] $*\033[0m" >&2; return 0; }
# === bcmcmd wrapper ==========================================================
# stdin is closed for the same reason as in blanton_traffic_linespeed.sh:
# bcmcmd otherwise inherits the caller's stdin and eats whatever a surrounding
# loop was reading.
#
# bcmcmd exits 0 even when the BCM shell refused the command, so the output is
# pattern-matched as well (the V0.3.1 lesson from blanton_traffic_linespeed.sh).
TR_ERR_PAT="${TR_ERR_PAT:-ERROR|Failed to execute|Invalid|Syntax error|Unavailable|Unknown command}"
# ...and the reverse also happens: bcmcmd exits NON-zero on a command that was
# accepted and is running. 'tr 518' outlives bcmcmd's response poll, so bcmcmd
# gives up with "polling socket timeout: Success" and a non-zero status while
# the test carries on inside the BCM shell. Treating that as a failure is what
# made V1.0.0 report ERR on a run that was actually fine.
TR_BENIGN_PAT="${TR_BENIGN_PAT:-polling socket timeout}"
# _tr_bcm <unit> <cmd> -> 0 ok, 1 failed
# _tr_bcm_ok <unit> <ok_marker> <cmd> -> as above, but if the output contains
# <ok_marker> the command is a success
# regardless of exit status.
#
# The marker is a POSITIVE proof of success ("the shell printed the thing it
# only prints when it accepted this command"), which is far more reliable than
# trying to enumerate every way bcmcmd can look unhappy.
_tr_bcm() { _tr_bcm_ok "$1" "" "${@:2}"; }
_tr_bcm_ok() {
local unit="$1" okpat="$2"; shift 2
local cmd="$*" out rc why=""
_tr_dbg "$BCMCMD_CMD -n $unit -c '$cmd'"
if [ "$TR_DRY_RUN" = "1" ]; then
echo "[DRY ] $BCMCMD_CMD -n $unit -c '$cmd'"
return 0
fi
out=$("$BCMCMD_CMD" -n "$unit" -c "$cmd" </dev/null 2>&1); rc=$?
[ "$DEBUG_MODE" = "1" ] && [ -n "$out" ] && echo "$out"
# 1. positive proof wins over everything else
if [ -n "$okpat" ] && echo "$out" | grep -qF "$okpat"; then
[ "$rc" -ne 0 ] && _tr_dbg "unit $unit: bcmcmd rc=$rc but '$okpat' seen -> accepted"
return 0
fi
# 2. the BCM shell said no
if echo "$out" | grep -qiE "$TR_ERR_PAT"; then
why="the BCM shell rejected it"
# 3. bcmcmd itself was unhappy -- unless it is the known transport artifact
elif [ "$rc" -ne 0 ]; then
if echo "$out" | grep -qiE "$TR_BENIGN_PAT"; then
_tr_dbg "unit $unit: bcmcmd rc=$rc (${TR_BENIGN_PAT}) -> tolerated"
return 0
fi
why="bcmcmd exited $rc"
else
return 0
fi
_tr_err "unit $unit: $why -- '$cmd'"
[ "$DEBUG_MODE" = "1" ] || { [ -n "$out" ] && echo "$out" >&2; }
return 1
}
_tr_units_check() {
local u ok=""
for u in $TR_UNITS; do
case "$u" in
0|1) ok="$ok $u" ;;
*) _tr_err "invalid unit '$u' (use 0, 1 or all)"; return 1 ;;
esac
done
[ -n "$ok" ] || { _tr_err "no unit selected"; return 1; }
TR_UNITS="${ok# }"
return 0
}
_tr_is_uint() { case "$1" in ''|*[!0-9]*) return 1 ;; *) return 0 ;; esac; }
_tr_gap() {
[ "$TR_DRY_RUN" = "1" ] && return 0
[ "$TR_UNIT_GAP_SEC" = "0" ] && return 0
sleep "$TR_UNIT_GAP_SEC"
}
# === start ===================================================================
# One complete block per unit, exactly the order in tools/TR518.txt.
blanton_tr518_start() {
_tr_units_check || return 1
_tr_is_uint "$TR_SETTLE_SEC" || { _tr_err "settle wait '$TR_SETTLE_SEC' is not an integer (-w <sec>)"; return 1; }
local unit fail=0 first=1
_tr_info "TR518 start on unit(s): $TR_UNITS"
for unit in $TR_UNITS; do
[ "$first" = "0" ] && _tr_gap
first=0
_tr_info "unit $unit: port $TR_LB_PORTS lb=mac -> l2 learn off -> test mode nr=yes -> tr 518"
_tr_bcm "$unit" "port $TR_LB_PORTS lb=mac" || fail=$((fail+1))
_tr_bcm "$unit" "l2 learn off" || fail=$((fail+1))
_tr_bcm "$unit" 'dsh -c "test mode nr=yes"' || fail=$((fail+1))
# "TR 518 TEST PARAMETERS" is printed only once the shell has parsed the
# arguments and started the test -- that is the proof we check for.
_tr_bcm_ok "$unit" "$TR_TEST_OK_PAT" "dsh -c \"tr 518 $TR_TEST_ARGS\"" || fail=$((fail+1))
done
if [ "$fail" -ne 0 ]; then
_tr_err "$fail command(s) failed -- traffic may not be running, not waiting"
_tr_warn "the unit(s) may still be in loopback: blanton_tr518.sh stop"
return 1
fi
if [ "$TR_NO_WAIT" = "1" ] || [ "$TR_SETTLE_SEC" = "0" ]; then
_tr_ok "TR518 running on unit(s): $TR_UNITS (settle wait skipped)"
_tr_warn "rails may still be ramping -- a power reading taken now is not a settled one"
return 0
fi
_tr_info "settling ${TR_SETTLE_SEC}s before the rails are worth reading ..."
[ "$TR_DRY_RUN" = "1" ] || sleep "$TR_SETTLE_SEC"
_tr_ok "TR518 running and settled on unit(s): $TR_UNITS"
_tr_info "read power now: TH6_SWB0_power_readback.sh / TH6_SWB1_power_readback.sh"
_tr_info "when finished: blanton_tr518.sh stop"
return 0
}
# === stop ====================================================================
# TR518.txt stops with 'port cd lb=none' only. l2 learning and test mode are
# left as start set them unless TR_RESTORE_* is turned on.
blanton_tr518_stop() {
_tr_units_check || return 1
local unit fail=0 first=1
_tr_info "TR518 stop on unit(s): $TR_UNITS"
for unit in $TR_UNITS; do
[ "$first" = "0" ] && _tr_gap
first=0
_tr_bcm "$unit" "port $TR_LB_PORTS lb=none" || fail=$((fail+1))
[ "$TR_RESTORE_LEARN" = "1" ] && { _tr_bcm "$unit" "l2 learn on" || fail=$((fail+1)); }
[ "$TR_RESTORE_TESTMODE" = "1" ] && { _tr_bcm "$unit" 'dsh -c "test mode nr=no"' || fail=$((fail+1)); }
done
if [ "$fail" -eq 0 ]; then
_tr_ok "unit(s) $TR_UNITS: port $TR_LB_PORTS lb=none"
[ "$TR_RESTORE_LEARN" = "1" ] || \
_tr_info "l2 learning is still off (TR_RESTORE_LEARN=1 to put it back)"
[ "$TR_RESTORE_TESTMODE" = "1" ] || \
_tr_info "test mode is still nr=yes (TR_RESTORE_TESTMODE=1 to put it back)"
else
_tr_warn "$fail command(s) failed -- check the unit is not still in loopback:"
_tr_warn " bcmcmd -n <u> -c 'port $TR_LB_PORTS' | head"
return 1
fi
return 0
}
# === Help ====================================================================
blanton_tr518_help() {
echo -e "\033[1mblanton_tr518.sh - TH6 built-in packet test (tr 518) for power loading\033[0m"
echo ""
echo -e " Units : \033[36m$TR_UNITS\033[0m"
echo -e " Settle wait : \033[36m${TR_SETTLE_SEC}s\033[0m after tr 518 (so power is read loaded, not ramping)"
echo -e " Loopback : \033[36mport $TR_LB_PORTS lb=mac\033[0m"
echo -e " tr 518 args : \033[36m$TR_TEST_ARGS\033[0m"
echo ""
echo -e "\033[1mSubcommands\033[0m"
echo -e " \033[33mstart\033[0m per unit: port $TR_LB_PORTS lb=mac -> l2 learn off -> test mode nr=yes -> tr 518 -> wait"
echo -e " \033[33mstop\033[0m per unit: port $TR_LB_PORTS lb=none"
echo -e " \033[33mhelp\033[0m"
echo ""
echo -e "\033[1mOptions\033[0m"
echo -e " \033[33m-u|--unit\033[0m <0|1|all> bcmcmd unit(s); 'all' = 0 1 (default: $TR_UNITS)"
echo -e " \033[33m-w|--wait\033[0m <sec> start: settle wait (default $TR_SETTLE_SEC)"
echo -e " \033[33m--no-wait\033[0m start: skip the settle wait"
echo -e " \033[33m-d|--debug\033[0m print every bcmcmd and its output"
echo -e " \033[33m-n|--dry-run\033[0m print commands only, do not touch the DUT"
echo ""
echo -e "\033[1mExamples\033[0m"
echo -e " ./blanton_tr518.sh start # both units, then wait ${TR_SETTLE_SEC}s"
echo -e " ./blanton_tr518.sh start -u 0 # unit 0 only"
echo -e " ./blanton_tr518.sh stop -u 1 # release unit 1"
echo -e " ./blanton_tr518.sh start -n # show the bcmcmds, touch nothing"
echo ""
echo -e "\033[33m stop only sends 'port $TR_LB_PORTS lb=none'. l2 learning stays off and test mode\033[0m"
echo -e "\033[33m stays nr=yes -- TR_RESTORE_LEARN=1 / TR_RESTORE_TESTMODE=1 to put them back.\033[0m"
echo -e "\033[33m tr 518 and blanton_traffic_linespeed cannot run together.\033[0m"
}
# === Argument parsing ========================================================
blanton_tr518() {
local sub="${1:-help}"; shift 2>/dev/null
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
all|ALL) TR_UNITS="0 1" ;;
*) TR_UNITS="$(echo "$2" | tr ',' ' ')" ;;
esac
shift 2 ;;
-w|--wait) TR_SETTLE_SEC="$2"; shift 2 ;;
--no-wait) TR_NO_WAIT=1; shift ;;
-d|--debug) DEBUG_MODE=1; shift ;;
-n|--dry-run) TR_DRY_RUN=1; shift ;;
-h|--help) blanton_tr518_help; return 0 ;;
*) _tr_err "unknown option '$1'"; return 1 ;;
esac
done
case "$sub" in
start) blanton_tr518_start ;;
stop) blanton_tr518_stop ;;
help|-h|--help) blanton_tr518_help ;;
*) _tr_err "unknown subcommand '$sub'"; blanton_tr518_help; return 1 ;;
esac
}
# Run when executed, define-only when sourced (same as the other blanton_*.sh).
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
blanton_tr518 "$@"
fi
@@ -6,7 +6,7 @@
# V0.1.0 2026-08-17 First version. Bash port of the three Tera Term macros
# utils/traffic_loopback_vlan_setting.ttl (VLAN 30..137,
# port pair cdN <-> cdN+32), utils/traffic_loopback_start.ttl
# (tx 100 length=512 VLantag=<vid>) and
# (tx <count> length=<len> VLantag=<vid>) and
# utils/traffic_loopback_vlan_remove.ttl.
# One DUT = two switch boards -> bcmcmd unit 0 and 1
# (bcmcmd -n <unit>), default both.
@@ -74,6 +74,54 @@
# Same fix applied to the "# FAIL ..." delta line (%+d ->
# %+.0f), which would otherwise saturate when a dead port
# makes the delta the size of the whole counter.
# V0.5.0 2026-08-28 Add: the 100G uplink (ce0, VLAN 138) joins init / start /
# stop / report, from tools/100G_Traffic.txt.
# ce0 is NOT a loopback pair: there is one per unit and the
# two are cabled to each other, so its verdict is a
# CROSS-UNIT check and cannot be decided from one unit's
# counters. It therefore appears as the LAST row of each
# unit table with the verdict DEFER, and is judged in a new
# summary printed once at the very bottom, after every
# unit -- which also carries the per-unit PASS/FAIL/NA
# totals ("all Results" in one place).
# TL_CE_MODE=cross (default) | self picks the topology;
# it is a plain editable flag, NOT auto-detected, because
# a non-zero RX cannot tell the two cablings apart.
# With only one unit selected the summary reports
# UNDECIDED (exit 3) instead of guessing.
# TL_CE_ENABLE=0 restores the old cd-pairs-only behaviour.
# V0.7.0 2026-09-01 Change: tx bursts carry PatternRandom=yes and the defaults
# become tx 200 length=324 (were 100 / 512).
# Random payload keeps the bit pattern changing instead of
# repeating, which is what makes a marginal lane show up;
# a fixed pattern can sit on a benign sequence all run.
# TL_TX_RANDOM=no forces the fixed pattern, "" leaves the
# argument off entirely (pre-V0.7.0 wire format).
# NOTE: counters scale with count x length, so totals from
# before this build are not comparable - 200x324 moves
# about 27% more bytes per burst than 100x512.
# V0.6.0 2026-08-28 Add: ce0 traffic is now SUSTAINED, not a single burst.
# A cd pair keeps its packets circulating because they
# flood to the partner port; ce0 has no partner and a
# switch will not send a frame back out its ingress port,
# so 'tx 100' was exactly one round trip (TX 100/RX 100)
# and then silence. init now sets an INGRESS MIRROR of ce0
# back to ce0 -- the mirrored copy is not egress-filtered,
# so each packet keeps lapping until stop turns it off.
# init : mirror init; mirror port ce0 Mode=Ingress
# DestPort=ce0; vlan create/add
# stop : mirror port ce0 Mode=Off (FIRST -- this is what
# breaks the loop), then vlan remove
# Bench-verified command set. TL_CE_MIRROR=0 goes back to
# the one-shot burst.
# Change: TL_CE_MODE now defaults to 'self'. 'ps ce' shows
# one ce port per unit and a unit-0-only burst returned on
# unit 0, so the cross-unit reading was wrong.
# V0.5.1 2026-08-28 Add: TL_CE_COUNTER selects which counter judges the ce
# port -- packets (MIB_TPOK/MIB_RPOK, default, same as the
# cd rows) or bytes (MIB_TBYT/MIB_RBYT). The report prints
# which one it used under the table, so a byte figure is
# never mistaken for a packet count next to the cd rows.
# =============================================================================
#
# The VLAN/port table below is copied verbatim from
@@ -104,6 +152,8 @@
# aliases: -tx | --tx
# -l|--length <n> tx packet length (default $TL_TX_LENGTH)
# aliases: -length | --len
# -r|--random <yes|no> tx PatternRandom (default $TL_TX_RANDOM;
# empty string omits the argument)
# -p|--ports <list|all> ps: port list ('all' = plain 'ps', every port)
# -T|--tolerance <n> report: allowed |delta| in packets (default 0;
# -T 1 absorbs the normal snapshot skew)
@@ -123,7 +173,8 @@
# -h|--help help
#
# Environment overrides:
# BCMCMD_CMD=bcmcmd TL_UNITS="0 1" TL_TX_COUNT=100 TL_TX_LENGTH=512
# BCMCMD_CMD=bcmcmd TL_UNITS="0 1" TL_TX_COUNT=200 TL_TX_LENGTH=324
# TL_TX_RANDOM=yes
# TL_PS_PORTS="1-24,40-96,..." TL_TOLERANCE=0 TL_LOG_DIR=/tmp
# DEBUG_MODE=1
#
@@ -135,8 +186,14 @@
# === Config ==================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
TL_UNITS="${TL_UNITS:-0 1}" # one DUT = two switch boards (0 and 1)
TL_TX_COUNT="${TL_TX_COUNT:-100}"
TL_TX_LENGTH="${TL_TX_LENGTH:-512}"
TL_TX_COUNT="${TL_TX_COUNT:-200}"
TL_TX_LENGTH="${TL_TX_LENGTH:-324}"
# PatternRandom=yes|no is appended to every tx burst. Random payload exercises
# the SerDes with changing bit patterns instead of the repeating one a fixed
# pattern produces, which is what makes a marginal lane show up.
# Set to "" to leave the argument off entirely (pre-V0.7.0 behaviour).
TL_TX_RANDOM="${TL_TX_RANDOM:-yes}"
TL_DEFAULT_VLAN="${TL_DEFAULT_VLAN:-1}"
TL_DEFAULT_VLAN_PBM="${TL_DEFAULT_VLAN_PBM:-cd}"
@@ -145,6 +202,56 @@ TL_DEFAULT_VLAN_PBM="${TL_DEFAULT_VLAN_PBM:-cd}"
# pasted straight from/into a manual "bcmcmd -n 0 -c 'ps <list>'".
TL_PS_PORTS="${TL_PS_PORTS:-1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565}"
# --- 100G uplink (ce0) ------------------------------------------------------
# The cd pairs above are loopback pairs WITHIN one switch unit (cdN <-> cdN+32).
# ce0 is not a pair: 'ps ce' shows exactly one ce port per unit, and it is looped
# back on itself. Bench-confirmed 2026-08-28 -- a tx burst on unit 0 alone came
# back on unit 0 (TPOK +100 AND RPOK +100), which only happens on a self loop.
#
# TL_CE_MODE=self ce0 loops back on itself (default, matches bench)
# verdict: TX == RX within the unit, decided in its own table
# TL_CE_MODE=cross unit0.ce0 <-> unit1.ce0 cabled together
# verdict: unit0.TX == unit1.RX and unit0.RX == unit1.TX,
# decided in the summary; needs BOTH units
#
# If the bench cabling changes, edit TL_CE_MODE -- it is not auto-detected,
# because "RX happens to be non-zero" cannot tell the two topologies apart.
# Note the two modes agree whenever both units send the same amount, so a wrong
# setting looks fine until something actually breaks: with a self loop read as
# cross, BOTH links dying still leaves unit0.TX == unit1.RX (0 == 0) -> PASS.
TL_CE_ENABLE=${TL_CE_ENABLE:-1} # 0 = skip ce0 entirely (cd pairs only)
TL_CE_VLAN="${TL_CE_VLAN:-138}" # one past the cd range (30..137)
TL_CE_PORT="${TL_CE_PORT:-ce0}" # bcm port name, same on both units
TL_CE_MODE="${TL_CE_MODE:-self}" # cross | self -- see above
# --- Why ce0 needs an ingress mirror -----------------------------------------
# A cd pair sustains itself: the packet floods to the OTHER member, goes out the
# cable, comes back on the partner, floods to the other member again -- forever.
# ce0 has no partner. A switch never forwards a frame back out the port it
# arrived on (source-port knockout), so with ce0 as the only VLAN member the
# returning packet is dropped and one 'tx' burst is exactly one round trip:
# TX 100, RX 100, done. That measures the link, it does not load it.
#
# An INGRESS MIRROR of ce0 back to ce0 is the way round it: the mirrored copy is
# not subject to the egress filter, so it does leave the port it came in on.
# Each circulating packet makes exactly one copy per lap -- 1:1, not amplifying,
# so the load is set by how many packets 'start' injects, and it runs until
# 'stop' turns the mirror off.
#
# ⚠️ The loop does NOT stop on its own. Unlike the cd pairs, removing the VLAN
# membership is not enough -- 'stop' must set Mode=Off, or the port keeps
# running flat out with nothing in 'show interfaces status' to hint at it.
# ⚠️ 'mirror init' resets the mirror module. Anything else using mirroring on
# this box (ERSPAN, monitoring) is cleared. Set TL_CE_MIRROR=0 to skip it.
TL_CE_MIRROR=${TL_CE_MIRROR:-1} # 0 = no mirror (one-shot burst, as before)
# Which counter the ce port is judged on. Packets by default, the same counter
# as the cd pairs, so every row of the table is in the same unit.
# packets -> MIB_TPOK / MIB_RPOK (default, same as the cd rows)
# bytes -> MIB_TBYT / MIB_RBYT
# Either way the report prints which one it used under the table.
TL_CE_COUNTER="${TL_CE_COUNTER:-packets}"
# --- report (pair cross-check) defaults -------------------------------------
TL_TOLERANCE="${TL_TOLERANCE:-0}" # allowed |delta| in packets before FAIL
TL_LOG_DIR="${TL_LOG_DIR:-/tmp}" # where the raw 'show c' capture is kept
@@ -378,6 +485,21 @@ traffic_linespeed_init() {
_tl_bcm_q "$unit" "vlan add $vid pbm=$pa,$pb" || fail=$((fail+1))
n=$((n+1))
done 3<<< "$TL_PAIRS"
# 100G uplink: one port, its own VLAN, added last so it is easy to skip.
# The mirror goes up BEFORE the VLAN so the loop is armed the moment the
# first packet is injected.
if [ "$TL_CE_ENABLE" = "1" ]; then
if [ "$TL_CE_MIRROR" = "1" ]; then
_tl_bcm_q "$unit" "mirror init" || fail=$((fail+1))
_tl_bcm_q "$unit" "mirror port $TL_CE_PORT Mode=Ingress DestPort=$TL_CE_PORT" \
|| fail=$((fail+1))
fi
_tl_bcm_run "$unit" "$TL_BENIGN_CREATE" "vlan create $TL_CE_VLAN"; rc=$?
[ "$rc" = "1" ] && fail=$((fail+1))
[ "$rc" = "2" ] && exist=$((exist+1))
_tl_bcm_q "$unit" "vlan add $TL_CE_VLAN pbm=$TL_CE_PORT" || fail=$((fail+1))
n=$((n+1))
fi
if [ "$fail" -eq 0 ]; then
_tl_ok "unit $unit: $n VLANs configured$([ "$exist" -gt 0 ] && echo " ($exist already existed)"), port pairs added"
else
@@ -412,17 +534,29 @@ traffic_linespeed_start() {
_tl_units_check || return 1
_tl_is_uint "$TL_TX_COUNT" || { _tl_err "tx count '$TL_TX_COUNT' is not a positive integer (-tx|-c <n>)"; return 1; }
_tl_is_uint "$TL_TX_LENGTH" || { _tl_err "tx length '$TL_TX_LENGTH' is not a positive integer (-length|-l <n>)"; return 1; }
local rnd=""
case "$TL_TX_RANDOM" in
yes|no) rnd=" PatternRandom=$TL_TX_RANDOM" ;;
"") rnd="" ;;
*) _tl_err "PatternRandom '$TL_TX_RANDOM' must be yes, no or empty (-r|--random)"; return 1 ;;
esac
local unit vid pa pb n fail
for unit in $TL_UNITS; do
n=0; fail=0
_tl_info "unit $unit: tx $TL_TX_COUNT length=$TL_TX_LENGTH per VLAN 30..137"
_tl_info "unit $unit: tx $TL_TX_COUNT length=$TL_TX_LENGTH${rnd} per VLAN 30..137"
while read -r vid pa pb <&3; do
[ -z "$vid" ] && continue
_tl_bcm_q "$unit" "tx $TL_TX_COUNT length=$TL_TX_LENGTH VLantag=$vid" || fail=$((fail+1))
_tl_bcm_q "$unit" "tx $TL_TX_COUNT length=$TL_TX_LENGTH VLantag=$vid${rnd}" || fail=$((fail+1))
n=$((n+1))
done 3<<< "$TL_PAIRS"
if [ "$TL_CE_ENABLE" = "1" ]; then
_tl_bcm_q "$unit" "tx $TL_TX_COUNT length=$TL_TX_LENGTH VLantag=$TL_CE_VLAN${rnd}" || fail=$((fail+1))
n=$((n+1))
fi
if [ "$fail" -eq 0 ]; then
_tl_ok "unit $unit: $n bursts sent ($((n * TL_TX_COUNT)) packets, ${TL_TX_LENGTH}B each)"
[ "$TL_CE_ENABLE" = "1" ] && [ "$TL_CE_MIRROR" = "1" ] && \
_tl_info "unit $unit: ${TL_CE_PORT} is now circulating and will keep running until 'stop'"
else
_tl_warn "unit $unit: $n bursts attempted, $fail failed"
fi
@@ -446,6 +580,25 @@ traffic_linespeed_stop() {
fi
n=$((n+1))
done 3<<< "$TL_PAIRS"
if [ "$TL_CE_ENABLE" = "1" ]; then
# Mirror OFF first: that is what actually breaks the loop. Removing
# the VLAN membership does not -- the mirrored copy never consulted
# the VLAN in the first place.
if [ "$TL_CE_MIRROR" = "1" ]; then
_tl_bcm_q "$unit" "mirror port $TL_CE_PORT Mode=Off" || {
fail=$((fail+1))
_tl_err "unit $unit: ${TL_CE_PORT} mirror still ON -- the loop is STILL RUNNING"
_tl_err " stop it by hand: ${BCMCMD_CMD} -n $unit -c 'mirror port $TL_CE_PORT Mode=Off'"
}
fi
_tl_bcm_run "$unit" "$TL_BENIGN_REMOVE" "vlan remove $TL_CE_VLAN pbm=$TL_CE_PORT"
[ "$?" = "1" ] && fail=$((fail+1))
if [ "$TL_DESTROY" = "1" ]; then
_tl_bcm_run "$unit" "$TL_BENIGN_REMOVE" "vlan destroy $TL_CE_VLAN"
[ "$?" = "1" ] && fail=$((fail+1))
fi
n=$((n+1))
fi
if [ "$fail" -eq 0 ]; then
_tl_ok "unit $unit: $n VLANs cleaned$([ "$TL_DESTROY" = "1" ] && echo " and destroyed")"
else
@@ -480,8 +633,11 @@ traffic_linespeed_ps() {
# (a cd port absent from 'show c' means the counter is zero or the
# console scrolled -- cross-check with 'ps' before blaming the port).
# _tl_pair_report <logfile> -> 0 all PASS, 2 any FAIL/NA, 1 parse error
# _tl_pair_report <logfile> [side_file]
# side_file (optional) receives machine-readable lines for the cross-unit
# summary: SUM <npass> <nfail> <nna> CE <tx> <rx> (CE omitted if absent)
_tl_pair_report() {
local log="$1" color=0
local log="$1" side="${2:-/dev/null}" color=0
# PASS green / FAIL red / NA yellow. auto = only when stdout is a terminal,
# so redirecting to a file or piping into grep/diff stays plain text.
case "$TL_COLOR" in
@@ -497,7 +653,11 @@ _tl_pair_report() {
-v WITHPORT="$TL_REPORT_WITHPORT" \
-v QUIET="$TL_REPORT_QUIET" \
-v TSV="$TL_REPORT_TSV" \
-v COLOR="$color" '
-v COLOR="$color" \
-v CEPORT="$([ "$TL_CE_ENABLE" = "1" ] && echo "$TL_CE_PORT")" \
-v CEMODE="$TL_CE_MODE" \
-v CECOUNTER="$TL_CE_COUNTER" \
-v SIDE="$side" '
function grp(v, s,out,l,i) {
s = sprintf("%.0f", v)
if (!GROUPED) return s
@@ -515,6 +675,7 @@ _tl_pair_report() {
if (!COLOR) return v
if (v == "PASS") return "\033[32m" v "\033[0m"
if (v == "FAIL") return "\033[31m" v "\033[0m"
if (v == "DEFER") return "\033[36m" v "\033[0m" # cyan: judged in the summary
return "\033[33m" v "\033[0m"
}
function redl(s) { return COLOR ? "\033[31m" s "\033[0m" : s }
@@ -535,11 +696,12 @@ _tl_pair_report() {
if (idx == 0) next
s = substr($0, idx)
kind = substr(s, 5, 4)
if (kind != "TPOK" && kind != "RPOK") next
# POK = packets (the cd pairs), BYT = bytes (used for the ce port)
if (kind != "TPOK" && kind != "RPOK" && kind != "TBYT" && kind != "RBYT") next
p1 = index(s, "."); p2 = index(s, "("); p3 = index(s, ")"); p4 = index(s, ":")
if (p1 == 0 || p2 == 0 || p3 == 0 || p4 == 0 || p2 < p1 || p4 < p3) next
cd = substr(s, p1 + 1, p2 - p1 - 1)
if (cd !~ /^cd[0-9]+$/) next
if (cd !~ /^(cd|ce)[0-9]+$/) next
lp = substr(s, p2 + 1, p3 - p2 - 1)
val = substr(s, p4 + 1)
sub(/^[ \t]+/, "", val)
@@ -547,7 +709,10 @@ _tl_pair_report() {
sub(/[ \t].*$/, "", val)
gsub(/,/, "", val)
LP[cd] = lp
if (kind == "TPOK") { TX[cd] = val + 0; HTX[cd] = 1 } else { RX[cd] = val + 0; HRX[cd] = 1 }
if (kind == "TPOK") { TX[cd] = val + 0; HTX[cd] = 1 }
else if (kind == "RPOK") { RX[cd] = val + 0; HRX[cd] = 1 }
else if (kind == "TBYT") { TXB[cd] = val + 0; HTXB[cd] = 1 }
else { RXB[cd] = val + 0; HRXB[cd] = 1 }
seen++
}
END {
@@ -580,6 +745,41 @@ _tl_pair_report() {
nrow++; CELL[nrow,1] = pname(b); CELL[nrow,2] = tb; CELL[nrow,3] = rb; CELL[nrow,4] = v
}
# --- 100G uplink, appended LAST so it sits at the bottom of the table ---
# It is a single port, not a pair, so it gets one row. In cross mode the
# verdict needs the OTHER unit counters and is decided in the summary;
# DEFER says "not judged here", which is not the same as NA ("no data").
cev = ""; ceunit = ""
if (CEPORT != "") {
if (CECOUNTER == "packets") {
ceunit = "packets"
haveT = (CEPORT in HTX); haveR = (CEPORT in HRX)
cetv = TX[CEPORT]; cerv = RX[CEPORT]
} else {
ceunit = "bytes"
haveT = (CEPORT in HTXB); haveR = (CEPORT in HRXB)
cetv = TXB[CEPORT]; cerv = RXB[CEPORT]
}
cet = haveT ? grp(cetv) : MISSING
cer = haveR ? grp(cerv) : MISSING
if (!(haveT && haveR)) {
cev = "NA"; nna++
} else if (CEMODE == "self") {
if (absd(cetv - cerv) <= TOL + 0) { cev = "PASS"; npass++ }
else {
cev = "FAIL"; nfail++
FL[++nf] = sprintf("# FAIL %s: TX-RX=%+.0f %s (self loopback)", \
CEPORT, cetv - cerv, ceunit)
}
} else {
cev = "DEFER"
}
nrep++
nrow++; CELL[nrow,1] = pname(CEPORT); CELL[nrow,2] = cet; CELL[nrow,3] = cer; CELL[nrow,4] = cev
if (SIDE != "" && SIDE != "/dev/null" && haveT && haveR)
printf "CE %.0f %.0f\n", cetv, cerv > SIDE
}
if (TSV) {
line = HDR[1]
for (c = 2; c <= NC; c++) line = line "\t" HDR[c]
@@ -616,13 +816,103 @@ _tl_pair_report() {
printf "# pairs reported : %d\n", nrep
printf "# %s %d %s %d %s %d (tolerance %d)\n", \
vc("PASS"), npass, vc("FAIL"), nfail, vc("NA"), nna, TOL + 0
if (CEPORT != "" && ceunit != "")
printf "# %s TX/RX are %s (MIB_%s/MIB_%s); the cd rows are packets\n", \
CEPORT, ceunit, \
(ceunit == "bytes" ? "TBYT" : "TPOK"), \
(ceunit == "bytes" ? "RBYT" : "RPOK")
if (cev == "DEFER")
printf "# %s is judged across units -- see the summary at the end\n", CEPORT
# every NA pair is a visible row -> no long "no counters" list needed
for (i = 1; i <= nf; i++) print redl(FL[i])
}
if (SIDE != "" && SIDE != "/dev/null")
printf "SUM %d %d %d\n", npass, nfail, nna > SIDE
exit (nfail || nna) ? 2 : 0
}' "$log"
}
# _tl_ce_summary -- the cross-unit ce0 verdict + the per-unit totals.
# Printed once, at the very bottom, after every unit's table.
# Args: <stamp> (side files are $TL_LOG_DIR/tlside_unit<N>_<stamp>)
# Returns 0 all PASS, 2 any FAIL/NA, 3 could not be decided.
_tl_ce_summary() {
local stamp="$1" unit side c g y n r
c=$'\033[36m'; g=$'\033[32m'; y=$'\033[33m'; r=$'\033[31m'; n=$'\033[0m'
case "$TL_COLOR" in
never|0|no) c=""; g=""; y=""; r=""; n="" ;;
always|1|yes) ;;
*) [ -t 1 ] || { c=""; g=""; y=""; r=""; n=""; } ;;
esac
local u tx rx pass fail na have=""
local -A CETX CERX UPASS UFAIL UNA
for unit in $TL_UNITS; do
side="$TL_LOG_DIR/tlside_unit${unit}_${stamp}"
[ -r "$side" ] || continue
while read -r tag a b cc; do
case "$tag" in
CE) CETX[$unit]="$a"; CERX[$unit]="$b" ;;
SUM) UPASS[$unit]="$a"; UFAIL[$unit]="$b"; UNA[$unit]="$cc" ;;
esac
done < "$side"
have="$have $unit"
done
echo ""
echo "===== summary : all units ====="
printf '%-8s %8s %8s %8s %s\n' "Unit" "PASS" "FAIL" "NA" "RESULT"
local worst=0 v
for unit in $have; do
pass="${UPASS[$unit]:-0}"; fail="${UFAIL[$unit]:-0}"; na="${UNA[$unit]:-0}"
if [ "$fail" -gt 0 ] || [ "$na" -gt 0 ]; then v="${r}FAIL${n}"; worst=2
else v="${g}PASS${n}"; fi
printf '%-8s %8s %8s %8s %b\n' "unit $unit" "$pass" "$fail" "$na" "$v"
done
[ "$TL_CE_ENABLE" = "1" ] || { echo ""; return "$worst"; }
echo ""
echo "----- ${TL_CE_PORT} (100G uplink, VLAN ${TL_CE_VLAN}, mode=${TL_CE_MODE}, counter=${TL_CE_COUNTER}) -----"
if [ "$TL_CE_MODE" != "cross" ]; then
echo "# mode=self: the verdict is in each unit's table above"
echo ""
return "$worst"
fi
# cross mode needs both units' counters
if [ -z "${CETX[0]}" ] || [ -z "${CETX[1]}" ]; then
printf '%b\n' "${y}UNDECIDED${n} ${TL_CE_PORT} is a cross-unit check and needs unit 0 AND unit 1;"
echo " this run had TL_UNITS=\"$TL_UNITS\" (counters seen for:${have:-none})."
echo " Re-run with -u all, or set TL_CE_MODE=self if the cabling is a self loopback."
echo ""
[ "$worst" -lt 3 ] && worst=3
return "$worst"
fi
local cu="bytes"; [ "$TL_CE_COUNTER" = "packets" ] && cu="packets"
printf '%-22s %18s %18s\n' "Direction" "TX ($cu)" "RX ($cu)"
printf '%-22s %18s %18s\n' "unit0.${TL_CE_PORT}" "${CETX[0]}" "${CERX[0]}"
printf '%-22s %18s %18s\n' "unit1.${TL_CE_PORT}" "${CETX[1]}" "${CERX[1]}"
local d1 d2 v1 v2
d1=$(awk -v a="${CETX[0]}" -v b="${CERX[1]}" 'BEGIN{printf "%.0f", a-b}')
d2=$(awk -v a="${CETX[1]}" -v b="${CERX[0]}" 'BEGIN{printf "%.0f", a-b}')
v1=$(awk -v d="$d1" -v t="$TL_TOLERANCE" 'BEGIN{print (d<0?-d:d)<=t ? "PASS" : "FAIL"}')
v2=$(awk -v d="$d2" -v t="$TL_TOLERANCE" 'BEGIN{print (d<0?-d:d)<=t ? "PASS" : "FAIL"}')
echo ""
printf 'unit0.TX -> unit1.RX delta %+d %b\n' "$d1" "$([ "$v1" = PASS ] && echo "${g}PASS${n}" || echo "${r}FAIL${n}")"
printf 'unit1.TX -> unit0.RX delta %+d %b\n' "$d2" "$([ "$v2" = PASS ] && echo "${g}PASS${n}" || echo "${r}FAIL${n}")"
if [ "$v1" = PASS ] && [ "$v2" = PASS ]; then
printf '%-22s %b\n' "${TL_CE_PORT} RESULT" "${g}PASS${n}"
else
printf '%-22s %b\n' "${TL_CE_PORT} RESULT" "${r}FAIL${n}"
worst=2
fi
echo ""
return "$worst"
}
# traffic_linespeed_report -- 'show c' per unit, keep the raw log, render the table
traffic_linespeed_report() {
local unit log rc worst=0 stamp
@@ -641,14 +931,17 @@ traffic_linespeed_report() {
fi
stamp=$(date +%Y%m%d_%H%M%S 2>/dev/null || echo now)
local side
for unit in $TL_UNITS; do
log="$TL_LOG_DIR/showc_unit${unit}_${stamp}.log"
side="$TL_LOG_DIR/tlside_unit${unit}_${stamp}"
: > "$side"
if ! _tl_bcm "$unit" "show c" > "$log" 2>&1; then
_tl_err "unit $unit: show c failed (see $log)"; return 1
fi
[ "$TL_REPORT_RAW" = "1" ] && { echo "----- unit $unit : raw show c -----"; cat "$log"; }
echo "===== unit $unit : loopback pair counter report (raw: $log) ====="
_tl_pair_report "$log"; rc=$?
_tl_pair_report "$log" "$side"; rc=$?
[ "$rc" -gt "$worst" ] && worst=$rc
case "$rc" in
0) _tl_ok "unit $unit: all pairs PASS" ;;
@@ -656,6 +949,12 @@ traffic_linespeed_report() {
*) _tl_err "unit $unit: report parse error" ;;
esac
done
# Summary last, after every unit's table -- this is where the cross-unit
# ce0 verdict can finally be decided.
_tl_ce_summary "$stamp"; rc=$?
[ "$rc" -gt "$worst" ] && worst=$rc
rm -f "$TL_LOG_DIR"/tlside_unit*_"${stamp}"
return "$worst"
}
@@ -675,17 +974,22 @@ traffic_linespeed_run() {
blanton_traffic_linespeed_help() {
echo -e "\033[1mblanton_traffic_linespeed.sh - SWB loopback line-speed traffic (bcmcmd)\033[0m"
echo ""
echo -e " Units: \033[36m$TL_UNITS\033[0m tx: \033[36m$TL_TX_COUNT pkt x ${TL_TX_LENGTH}B\033[0m"
echo -e " Units: \033[36m$TL_UNITS\033[0m tx: \033[36m$TL_TX_COUNT pkt x ${TL_TX_LENGTH}B\033[0m PatternRandom: \033[36m${TL_TX_RANDOM:-(不加)}\033[0m"
echo -e " VLANs: 30..137 ($(_tl_pair_count) loopback pairs, cdN <-> cdN+32)"
[ "$TL_CE_ENABLE" = "1" ] && \
echo -e " 100G : VLAN \033[36m$TL_CE_VLAN\033[0m port \033[36m$TL_CE_PORT\033[0m mode=\033[36m$TL_CE_MODE\033[0m (cross = unit0.$TL_CE_PORT <-> unit1.$TL_CE_PORT cabled)"
echo ""
echo -e "\033[1mSubcommands\033[0m"
echo -e " \033[33minit\033[0m step 1 vlan remove 1 pbm=cd, vlan create/add each pair"
echo -e " \033[33mclear\033[0m step 2 clear c"
echo -e " \033[33mshow\033[0m step 3/6 show c (run before and after traffic)"
echo -e " \033[33mstart\033[0m step 4 tx <count> length=<len> VLantag=<vid> per VLAN"
echo -e " \033[33mstart\033[0m step 4 tx <count> length=<len> VLantag=<vid> [PatternRandom=<yes|no>] per VLAN"
echo -e " \033[33mstop\033[0m step 5 vlan remove <vid> pbm=<pair> [--destroy also destroys]"
[ "$TL_CE_ENABLE" = "1" ] && [ "$TL_CE_MIRROR" = "1" ] && \
echo -e " \033[33m^ also turns the $TL_CE_PORT mirror off -- without it the 100G loop keeps running\033[0m"
echo -e " \033[33mps\033[0m ps <portlist> port status (link/speed) of the cabled ports"
echo -e " \033[33mreport\033[0m show c -> per-port TX/RX per pair + PASS/FAIL/NA cross-check"
echo -e " ${TL_CE_PORT} is the last row (DEFER), judged in the summary at the bottom"
echo -e " \033[33mrun\033[0m ps -> init -> clear -> start -> report"
echo -e " \033[33mhelp\033[0m"
echo ""
@@ -693,6 +997,7 @@ blanton_traffic_linespeed_help() {
echo -e " \033[33m-u|--unit\033[0m <0|1|all> bcmcmd unit(s); 'all' = 0 1 (default: $TL_UNITS)"
echo -e " \033[33m-c|--count|-tx\033[0m <n> tx packet count (default $TL_TX_COUNT)"
echo -e " \033[33m-l|--length|-length\033[0m <n> tx packet length (default $TL_TX_LENGTH)"
echo -e " \033[33m-r|--random\033[0m <yes|no> tx PatternRandom (default $TL_TX_RANDOM; \"\" 完全不加)"
echo -e " \033[33m-p|--ports\033[0m <list> ps port list, or 'all' for every port"
echo -e " \033[33m-T|--tolerance\033[0m <n> report: allowed |delta| pkts (default $TL_TOLERANCE; -T 1 = snapshot skew)"
echo -e " \033[33m-a|--all\033[0m report: kept for compatibility (all pairs are listed)"
@@ -716,7 +1021,8 @@ blanton_traffic_linespeed_help() {
echo -e " blanton_traffic_linespeed report -u 1 -q | grep -v PASS"
echo -e " blanton_traffic_linespeed report -f /tmp/showc_unit1_*.log -a"
echo -e " blanton_traffic_linespeed show -u 1 | grep -iE 'error|discard|drop'"
echo -e " blanton_traffic_linespeed start -u 0 -tx 100 -length 512"
echo -e " blanton_traffic_linespeed start -u 0 -tx 200 -length 324"
echo -e " blanton_traffic_linespeed start -r no # 固定樣式,不隨機"
echo -e " blanton_traffic_linespeed start -tx 100000 -length 9216 -d"
echo -e " blanton_traffic_linespeed stop --destroy"
echo ""
@@ -740,6 +1046,7 @@ blanton_traffic_linespeed() {
shift 2 ;;
-c|--count|-tx|--tx) TL_TX_COUNT="$2"; shift 2 ;;
-l|-length|--length|--len) TL_TX_LENGTH="$2"; shift 2 ;;
-r|--random|-PatternRandom|--pattern-random) TL_TX_RANDOM="$2"; shift 2 ;;
-p|--ports) TL_PS_PORTS="$2"; shift 2 ;;
-T|--tolerance) TL_TOLERANCE="$2"; shift 2 ;;
-f|--file) TL_REPORT_FILE="$2"; shift 2 ;;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,314 @@
#!/usr/bin/env bash
# =============================================================================
# nfc_polling.sh -- keep reading the NFC tag in the background, and tally it
# =============================================================================
# Version History:
# V1.0.0 2026-08-28 First version. start/stop/status/tail/report/clear/fg,
# wraps blantons_nfc_validate.py. 'report' works while the
# poll is still running.
# =============================================================================
#
# Each round runs blantons_nfc_validate.py once and appends a machine-readable
# verdict line, so 'report' never has to parse the tool's prose:
#
# [2026-08-28 15:04:11] NFC poll #000001 START
# ... the tool's own output ...
# [2026-08-28 15:04:14] NFC poll #000001 RESULT=PASS tag=046F7BD2142290
#
# The verdict comes from the tool's own [PASS] / [FAIL] summary line. If neither
# appears the round is ERROR, not FAIL -- "the tool did not run" and "the tag was
# not read" are different problems and get counted separately.
#
# Usage:
# ./nfc_polling.sh start # background, CLEARS the log first
# ./nfc_polling.sh status # running? pid, rounds so far, log size
# ./nfc_polling.sh tail [n] # last n lines (default 50) -- does NOT follow
# ./nfc_polling.sh report # PASS/FAIL tally; safe to run WHILE polling
# ./nfc_polling.sh stop
# ./nfc_polling.sh clear # delete the log (must be stopped)
# ./nfc_polling.sh fg # run in the foreground, Ctrl-C to stop
#
# Environment overrides:
# NFC_INTERVAL_SEC=10 NFC_TIMEOUT_SEC=60 NFC_MAX_ROUNDS=0 (0 = forever)
# NFC_ARGS="test --debug" NFC_LOG_DIR=<dir> NFC_BIN=<python3>
# =============================================================================
# --- User Configurable Section ----------------------------------------------
NFC_INTERVAL_SEC="${NFC_INTERVAL_SEC:-10}" # gap between rounds
NFC_TIMEOUT_SEC="${NFC_TIMEOUT_SEC:-60}" # kill a round that hangs (0 = never)
NFC_MAX_ROUNDS="${NFC_MAX_ROUNDS:-0}" # 0 = until 'stop'
# Called through python3 on purpose: blantons_nfc_validate.py arrives from git
# (mode 100644) and a Windows/USB copy does not carry the execute bit either, so
# "./blantons_nfc_validate.py" would fail with Permission denied on a fresh DUT.
NFC_PY="${NFC_PY:-python3}"
NFC_SCRIPT_NAME="${NFC_SCRIPT_NAME:-blantons_nfc_validate.py}"
# --debug is kept because that is the output that has been seen on the bench.
# It costs ~1.5 KB per round (~13 MB/day at a 10s interval), which is fine for a
# soak; drop it to "test" if you want a smaller log.
NFC_ARGS="${NFC_ARGS:-test --debug}"
NFC_LOG_DIR="${NFC_LOG_DIR:-}" # empty = <script dir>/log
NFC_LOG_NAME="${NFC_LOG_NAME:-nfc_poll.log}"
# -----------------------------------------------------------------------------
SCRIPT_NAME="$(basename -- "${BASH_SOURCE[0]}")"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_PATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
NFC_SCRIPT="${NFC_SCRIPT:-${SCRIPT_DIR}/${NFC_SCRIPT_NAME}}"
[ -n "${NFC_LOG_DIR}" ] || NFC_LOG_DIR="${SCRIPT_DIR}/log"
LOG_FILE="${NFC_LOG_DIR}/${NFC_LOG_NAME}"
PID_FILE="${NFC_LOG_DIR}/${NFC_LOG_NAME%.log}.pid"
STOP=0
SLEEP_PID=""
ts() { date '+%Y-%m-%d %H:%M:%S'; }
die() { printf '[ERROR] %s\n' "$*" >&2; exit 1; }
on_signal() {
STOP=1
[ -n "${SLEEP_PID}" ] && kill "${SLEEP_PID}" 2>/dev/null
return 0
}
# sleep that a signal can cut short, so 'stop' does not wait out the interval
interruptible_sleep() {
local sec="$1"
[ "${sec}" -le 0 ] 2>/dev/null && return 0
sleep "${sec}" &
SLEEP_PID=$!
wait "${SLEEP_PID}" 2>/dev/null
SLEEP_PID=""
return 0
}
is_running() {
local pid
[ -f "${PID_FILE}" ] || return 1
pid="$(cat "${PID_FILE}" 2>/dev/null)"
[ -n "${pid}" ] || return 1
kill -0 "${pid}" 2>/dev/null || return 1
printf '%s' "${pid}"
return 0
}
# --- one round ---------------------------------------------------------------
# Appends START, the tool output, then a RESULT line. Everything about a round
# lands in the log even when the tool dies, so 'report' can still account for it.
run_one_round() {
local n="$1" out rc verdict tag reason
printf '[%s] NFC poll #%06d START\n' "$(ts)" "${n}"
if [ -n "${NFC_TIMEOUT_SEC}" ] && [ "${NFC_TIMEOUT_SEC}" -gt 0 ] 2>/dev/null \
&& command -v timeout >/dev/null 2>&1; then
out="$(timeout "${NFC_TIMEOUT_SEC}" "${NFC_PY}" "${NFC_SCRIPT}" ${NFC_ARGS} 2>&1)"; rc=$?
else
out="$("${NFC_PY}" "${NFC_SCRIPT}" ${NFC_ARGS} 2>&1)"; rc=$?
fi
printf '%s\n' "${out}"
# The tool's own summary decides. Exit status is only the fallback, because
# a tool that never printed a summary did not measure anything.
if printf '%s\n' "${out}" | grep -q '^\[PASS\]'; then
verdict="PASS"
elif printf '%s\n' "${out}" | grep -q '^\[FAIL\]'; then
verdict="FAIL"
elif [ "${rc}" -eq 124 ]; then
verdict="ERROR"; reason="round exceeded NFC_TIMEOUT_SEC=${NFC_TIMEOUT_SEC}s"
else
verdict="ERROR"; reason="no [PASS]/[FAIL] summary, exit=${rc}"
fi
tag="$(printf '%s\n' "${out}" | sed -n 's/.*NFCID1=\([0-9A-Fa-f]*\).*/\1/p' | tail -1)"
[ -n "${reason}" ] || reason="$(printf '%s\n' "${out}" | grep -m1 '^\[\(PASS\|FAIL\)\]' | cut -c8-)"
printf '[%s] NFC poll #%06d RESULT=%s tag=%s reason=%s\n' \
"$(ts)" "${n}" "${verdict}" "${tag:--}" "${reason:--}"
}
main_loop() {
local n=0
trap on_signal INT TERM
printf '[%s] ===== nfc_polling start : %s %s (interval %ss) =====\n' \
"$(ts)" "${NFC_PY}" "${NFC_SCRIPT}" "${NFC_INTERVAL_SEC}"
while [ "${STOP}" -eq 0 ]; do
n=$(( n + 1 ))
run_one_round "${n}"
if [ "${NFC_MAX_ROUNDS}" -gt 0 ] 2>/dev/null && [ "${n}" -ge "${NFC_MAX_ROUNDS}" ]; then
break
fi
[ "${STOP}" -eq 0 ] && interruptible_sleep "${NFC_INTERVAL_SEC}"
done
printf '[%s] ===== nfc_polling stop : %d round(s) =====\n' "$(ts)" "${n}"
}
# --- sub-commands ------------------------------------------------------------
do_start() {
local pid
pid="$(is_running)" && die "already running (pid=${pid})"
[ -r "${NFC_SCRIPT}" ] || die "cannot read ${NFC_SCRIPT}"
command -v "${NFC_PY}" >/dev/null 2>&1 || die "${NFC_PY} not found"
mkdir -p "${NFC_LOG_DIR}" || die "cannot create ${NFC_LOG_DIR}"
# start always begins a fresh log, so a report is about THIS run only
: > "${LOG_FILE}" || die "cannot write ${LOG_FILE}"
if command -v setsid >/dev/null 2>&1; then
setsid "${SCRIPT_PATH}" __daemon >/dev/null 2>&1 &
else
nohup "${SCRIPT_PATH}" __daemon >/dev/null 2>&1 &
disown 2>/dev/null
fi
sleep 1
pid="$(is_running)" || die "start failed, check ${LOG_FILE}"
printf 'started (pid=%s)\nlog: %s\n' "${pid}" "${LOG_FILE}"
}
do_daemon() {
mkdir -p "${NFC_LOG_DIR}" || die "cannot create ${NFC_LOG_DIR}"
exec >>"${LOG_FILE}" 2>&1
printf '%d\n' "$$" > "${PID_FILE}"
trap 'rm -f "${PID_FILE}"' EXIT
main_loop
}
do_stop() {
local pid i
pid="$(is_running)" || { printf 'not running\n'; rm -f "${PID_FILE}"; return 0; }
kill -TERM -"${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null
for (( i = 0; i < 20; i++ )); do
kill -0 "${pid}" 2>/dev/null || break
sleep 0.5
done
if kill -0 "${pid}" 2>/dev/null; then
printf 'SIGTERM ignored, sending SIGKILL\n'
kill -KILL -"${pid}" 2>/dev/null || kill -KILL "${pid}" 2>/dev/null
fi
rm -f "${PID_FILE}"
printf 'stopped (pid=%s)\n' "${pid}"
}
# counts straight out of the log, so it is the same answer running or stopped
_tally() {
local f="$1"
[ -r "${f}" ] || { printf '0 0 0 0\n'; return; }
awk '
/RESULT=PASS/ { p++ }
/RESULT=FAIL/ { f++ }
/RESULT=ERROR/ { e++ }
/ START$/ { s++ }
END { printf "%d %d %d %d\n", s+0, p+0, f+0, e+0 }
' "${f}"
}
do_status() {
local pid started passed failed errored size
if pid="$(is_running)"; then
printf 'status : running (pid=%s)\n' "${pid}"
else
printf 'status : stopped\n'
fi
printf 'log : %s\n' "${LOG_FILE}"
if [ -r "${LOG_FILE}" ]; then
size="$(du -h "${LOG_FILE}" 2>/dev/null | cut -f1)"
read -r started passed failed errored <<< "$(_tally "${LOG_FILE}")"
printf 'size : %s\n' "${size:-?}"
printf 'rounds : %s started (PASS %s / FAIL %s / ERROR %s)\n' \
"${started}" "${passed}" "${failed}" "${errored}"
printf 'last : %s\n' "$(grep -a 'RESULT=' "${LOG_FILE}" | tail -1)"
else
printf 'size : (no log yet)\n'
fi
}
do_report() {
local pid started passed failed errored inflight verdict first last
[ -r "${LOG_FILE}" ] || die "no log at ${LOG_FILE} -- has it been started?"
read -r started passed failed errored <<< "$(_tally "${LOG_FILE}")"
inflight=$(( started - passed - failed - errored ))
echo "===== NFC polling report ====="
printf 'log : %s\n' "${LOG_FILE}"
if pid="$(is_running)"; then
printf 'state : RUNNING (pid=%s) -- this is a snapshot, the count is still moving\n' "${pid}"
else
printf 'state : stopped\n'
fi
first="$(grep -a -m1 ' START$' "${LOG_FILE}" | sed -n 's/^\[\([^]]*\)\].*/\1/p')"
last="$(grep -a 'RESULT=' "${LOG_FILE}" | tail -1 | sed -n 's/^\[\([^]]*\)\].*/\1/p')"
printf 'window : %s -> %s\n' "${first:-?}" "${last:-?}"
echo ""
printf 'rounds : %d\n' "${started}"
printf 'PASS : %d\n' "${passed}"
printf 'FAIL : %d\n' "${failed}"
printf 'ERROR : %d (tool did not produce a verdict)\n' "${errored}"
[ "${inflight}" -gt 0 ] && printf 'in flight: %d (round started, no result yet)\n' "${inflight}"
if [ "${started}" -eq 0 ]; then
verdict="NO DATA"
elif [ "${failed}" -gt 0 ] || [ "${errored}" -gt 0 ]; then
verdict="FAIL"
else
verdict="PASS"
fi
printf 'RESULT : %s\n' "${verdict}"
echo ""
echo "--- tags seen ---"
grep -a 'RESULT=PASS' "${LOG_FILE}" \
| sed -n 's/.* tag=\([0-9A-Fa-f]*\) .*/\1/p' \
| sort | uniq -c | sort -rn | awk '{printf " %-20s %s\n", $2, $1}'
grep -aq 'RESULT=PASS.* tag=[0-9A-Fa-f]' "${LOG_FILE}" || echo " (none)"
if [ "$(( failed + errored ))" -gt 0 ]; then
echo ""
echo "--- last 10 FAIL / ERROR ---"
grep -aE 'RESULT=(FAIL|ERROR)' "${LOG_FILE}" | tail -10 | sed 's/^/ /'
fi
echo ""
[ "${verdict}" = "FAIL" ] && return 2
return 0
}
usage() {
cat <<USAGE
${SCRIPT_NAME} - background NFC tag polling (wraps ${NFC_SCRIPT_NAME})
start run in the background; CLEARS the log first
stop stop it
status running? pid, rounds so far, last result
tail [n] last n lines of the log (default 50) -- does NOT follow
report PASS/FAIL tally -- safe to run WHILE polling
clear delete the log (must be stopped)
fg run in the foreground, Ctrl-C to stop
interval ${NFC_INTERVAL_SEC}s per-round timeout ${NFC_TIMEOUT_SEC}s rounds ${NFC_MAX_ROUNDS} (0 = forever)
log ${LOG_FILE}
A round is PASS or FAIL from the tool's own summary line; ERROR means it
produced neither, which is a different problem from a tag that would not read.
USAGE
}
case "${1:-}" in
start) do_start ;;
stop) do_stop ;;
status) do_status ;;
report) do_report ;;
# deliberately NOT 'tail -f': that never returns, and a TTL macro waiting on
# the prompt would hang there forever.
tail) [ -r "${LOG_FILE}" ] || die "no log at ${LOG_FILE}"
tail -n "${2:-50}" "${LOG_FILE}" ;;
clear)
is_running >/dev/null && die "still running, stop it first"
rm -f "${LOG_FILE}"
printf 'log cleared\n'
;;
fg) main_loop ;;
__daemon) do_daemon ;;
-h|--help|"") usage ;;
*) printf '[ERROR] unknown sub-command: %s\n\n' "$1" >&2; usage; exit 1 ;;
esac
@@ -0,0 +1,241 @@
#!/usr/bin/env bash
# =============================================================================
# pwr_brick.sh -- PDB / CPB power brick Vin / Iin / Vout / Iout / Temp
# =============================================================================
# Version History:
# V1.1.0 2026-09-02 PAGE values and conversions taken from the ADPM12200
# datasheet instead of the bring-up spreadsheet.
# The spreadsheet wrote every PAGE in decimal but with an
# 0x prefix, so four of the five selected the wrong page:
# Vin PAGE 9 -> it said 0x00 (should be 0x09)
# Iin PAGE 10 -> it said 0x10 (should be 0x0A)
# Vout PAGE 2 -> it said 0x02 correct by luck
# Iout PAGE 14 -> it said 0x14 (should be 0x0E)
# Temp PAGE 18 -> it said 0x18 (should be 0x12)
# Only Vout worked, because 2 reads the same either way.
# That is why Iin/Iout answered 0xFFFF and Temp 0x0000.
# Conversions now use the datasheet DIRECT equation; the
# reverse-engineered BRICK_VIN_LSB is gone.
# V1.0.0 2026-09-02 First version.
# =============================================================================
#
# Path: CB FPGA F3 VI2C ch4 -> TCA954x mux 0x72 ch0 -> the bricks
#
# The four ADPM12200 modules put each measurement on its own PMBus PAGE, so a
# PAGE write has to precede every read. blanton_pwr_data.sh does not send one
# at all (its PDB table has page "-"), which is why it reports them as NA.
#
# READ_VIN 0x88 PAGE 9
# READ_IIN 0x89 PAGE 10
# READ_VOUT 0x8B PAGE 2
# READ_IOUT 0x8C PAGE 14
# READ_TEMPERATURE_1 0x8D PAGE 18
#
# DIRECT format, datasheet Table 3 ("PMBus Command Code Coefficients"):
#
# X = (1/m) x (Y x 10^-R - b) Y = the 2-byte two's complement word
#
# Voltage m=0.125 b=0 R=0 units mV -> X = Y x 8 mV
# Current m=0.25 b=0 R=2 units A -> X = Y x 0.04 A
# Temperature m=1 b=0 R=2 units degC -> X = Y x 0.01 degC
#
# Sanity check: READ_VOUT 0x05D4 = 1492 -> 1492 x 8 = 11936 mV, which is exactly
# what PDB_IBC_SWB1_A_VOUT reports in 'show platform voltage'.
#
# ⚠️ Table 3 does not list READ_VIN or READ_IIN. They are decoded here with the
# Voltage and Current coefficients respectively - reasonable, and consistent
# with a ~50 V input, but not stated by the datasheet. PB_VIN_M / PB_IIN_M
# below are where to change that if the part turns out to differ.
#
# ⚠️ CPB.PU37 (0x26) is a DIFFERENT part: no PAGE writes, and its own scaling
# (Vin 0.25 V, Vout 2^-11 V, Iout 0.5 A per count of the mantissa). Those
# three were confirmed against words this DUT returns.
#
# Usage:
# ./pwr_brick.sh show # the table
# ./pwr_brick.sh show -r # add the raw words
# ./pwr_brick.sh help
# =============================================================================
# --- User Configurable Section ----------------------------------------------
PB_CH="${PB_CH:-4}" # ICB VI2C channel
PB_MUX="${PB_MUX:-0x72}" # TCA954x address
PB_MUX_SEL="${PB_MUX_SEL:-0x01}" # control byte: bit0 = channel 0
PB_TRIES="${PB_TRIES:-8}" # reads per value before giving up
# PMBus PAGE per measurement (ADPM12200). Decimal page numbers written in hex.
PB_PAGE_VIN="${PB_PAGE_VIN:-0x09}" # 9
PB_PAGE_IIN="${PB_PAGE_IIN:-0x0A}" # 10
PB_PAGE_VOUT="${PB_PAGE_VOUT:-0x02}" # 2
PB_PAGE_IOUT="${PB_PAGE_IOUT:-0x0E}" # 14
PB_PAGE_TEMP="${PB_PAGE_TEMP:-0x12}" # 18
# DIRECT coefficients: m, R, and the divisor that takes the datasheet unit to
# the displayed unit (mV -> V is 1000; A and degC are already right).
PB_VOUT_M="${PB_VOUT_M:-0.125}"; PB_VOUT_R="${PB_VOUT_R:-0}"; PB_VOUT_DIV="${PB_VOUT_DIV:-1000}"
PB_VIN_M="${PB_VIN_M:-0.125}"; PB_VIN_R="${PB_VIN_R:-0}"; PB_VIN_DIV="${PB_VIN_DIV:-1000}"
PB_IOUT_M="${PB_IOUT_M:-0.25}"; PB_IOUT_R="${PB_IOUT_R:-2}"; PB_IOUT_DIV="${PB_IOUT_DIV:-1}"
PB_IIN_M="${PB_IIN_M:-0.25}"; PB_IIN_R="${PB_IIN_R:-2}"; PB_IIN_DIV="${PB_IIN_DIV:-1}"
PB_TEMP_M="${PB_TEMP_M:-1}"; PB_TEMP_R="${PB_TEMP_R:-2}"; PB_TEMP_DIV="${PB_TEMP_DIV:-1}"
# CPB.PU37 only (different part, no PAGE, mantissa-based)
CPB_VIN_LSB="${CPB_VIN_LSB:-0.25}" # V per count of the mantissa
CPB_IOUT_LSB="${CPB_IOUT_LSB:-0.5}" # A per count of the mantissa
# Plausibility windows. A decoded value outside its window is discarded and the
# read retried; this is what rejects the corrupted words this bus produces - a
# bad high byte turns 11.98 V into 32.00 V, which "reject 0xFFFF" never catches.
PB_VIN_LO="${PB_VIN_LO:-30}"; PB_VIN_HI="${PB_VIN_HI:-70}"
PB_VOUT_LO="${PB_VOUT_LO:-8}"; PB_VOUT_HI="${PB_VOUT_HI:-14}"
PB_IIN_LO="${PB_IIN_LO:-0}"; PB_IIN_HI="${PB_IIN_HI:-100}"
PB_IOUT_LO="${PB_IOUT_LO:-0}"; PB_IOUT_HI="${PB_IOUT_HI:-300}"
PB_TEMP_LO="${PB_TEMP_LO:-0}"; PB_TEMP_HI="${PB_TEMP_HI:-125}"
# All-ones and all-zeros are the two ways this bus says "nobody answered", and
# both can decode into a value that sits inside its window - 0x0000 on the
# temperature register reads as a perfectly plausible 0 C. Rejected as raw
# words, before any conversion, so no window has to be bent to catch them.
PB_REJECT_FFFF="${PB_REJECT_FFFF:-1}"
PB_REJECT_0000="${PB_REJECT_0000:-1}"
# "location:bricks:slave:netname:kind" kind = adpm (PAGE per read) | cpb
PB_DEVS=(
"SWB0.PU207:BRICKS1:0x62:P12V_SWB0_L:adpm"
"SWB0.PU13:BRICKS2:0x63:P12V_SWB0_L:adpm"
"SWB1.PU332:BRICKS1:0x60:P12V_SWB1_R:adpm"
"SWB1.PU85:BRICKS2:0x61:P12V_SWB1_R:adpm"
"CPB.PU37:BRICK:0x26:P12V_STBY:cpb"
)
# -----------------------------------------------------------------------------
PB_NA="NA"
PB_RAW=0
PB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
_pb_err() { echo -e "[\033[31mERR \033[0m] $*" >&2; }
# --- backend -----------------------------------------------------------------
if ! declare -F vi2c_read >/dev/null 2>&1; then
if [ -r "$PB_DIR/blanton_icb_vi2c.sh" ]; then
# shellcheck source=/dev/null
source "$PB_DIR/blanton_icb_vi2c.sh" >/dev/null 2>&1
else
_pb_err "blanton_icb_vi2c.sh not found next to this script"; exit 1
fi
fi
declare -F vi2c_read >/dev/null 2>&1 || { _pb_err "vi2c_read() still undefined"; exit 1; }
# --- decoders ----------------------------------------------------------------
# DIRECT: X = (1/m) x (Y x 10^-R - b), b = 0. Y is two's complement, so a word
# above 0x7FFF is negative - that matters for temperature, not for the rails.
_pb_direct() {
awk -v w=$(( $1 )) -v m="$2" -v r="$3" -v d="$4" 'BEGIN{
if (w > 32767) w -= 65536
printf "%.3f", ((w * (10 ^ -r)) / m) / d
}'
}
# SLINEAR11 mantissa only (bits[10:0], two's complement) - CPB.PU37 path.
_pb_mant() { awk -v w=$(( $1 )) 'BEGIN{ m = w % 2048; if (m > 1023) m -= 2048; print m }'; }
_pb_mul() { awk -v a="$1" -v b="$2" 'BEGIN{ printf "%.3f", a * b }'; }
_pb_lin11() { awk -v w=$(( $1 )) 'BEGIN{ printf "%.4f", w * (2.0 ^ -11) }'; }
_pb_in() { awk -v x="$1" -v lo="$2" -v hi="$3" 'BEGIN{ exit !(x >= lo && x <= hi) }'; }
# _pb_word <slave> <page|-> <reg> -> "0xWWWW"
_pb_word() {
local slave="$1" page="$2" reg="$3" out
[ "$page" != "-" ] && vi2c_write "$PB_CH" "$slave" 0x00 "$page" >/dev/null 2>&1
out=$(vi2c_read "$PB_CH" "$slave" "$reg" 2 2>/dev/null \
| sed -n 's/.*\[0x\(..\) 0x\(..\)\].*/0x\2\1/p')
[ -n "$out" ] && echo "$out"
}
# _pb_val <slave> <page|-> <reg> <decoder> <a1> <a2> <a3> <lo> <hi>
# Retries until the decoded value lands inside the window; echoes "value raw".
_pb_val() {
local slave="$1" page="$2" reg="$3" dec="$4" a1="$5" a2="$6" a3="$7" lo="$8" hi="$9"
local i w v
for (( i = 0; i < PB_TRIES; i++ )); do
w=$(_pb_word "$slave" "$page" "$reg") || continue
[ -z "$w" ] && continue
[ "$PB_REJECT_FFFF" = "1" ] && [ "$(( w ))" -eq 65535 ] && continue
[ "$PB_REJECT_0000" = "1" ] && [ "$(( w ))" -eq 0 ] && continue
case "$dec" in
direct) v=$(_pb_direct "$w" "$a1" "$a2" "$a3") ;;
mant) v=$(_pb_mul "$(_pb_mant "$w")" "$a1") ;;
lin11) v=$(_pb_lin11 "$w") ;;
esac
_pb_in "$v" "$lo" "$hi" || continue
echo "$v $w"; return 0
done
echo "$PB_NA -"; return 1
}
_pb_mux_open() {
# The mux takes a bare control byte and vi2c_write always sends a register
# first, so passing 0x01 as both makes the part latch 0x01 either way.
vi2c_init "$PB_CH" >/dev/null 2>&1
vi2c_write "$PB_CH" "$PB_MUX" "$PB_MUX_SEL" "$PB_MUX_SEL" >/dev/null 2>&1
return 0
}
# --- show --------------------------------------------------------------------
pwr_brick_show() {
_pb_mux_open
echo "==== PDB / CPB power bricks (VI2C ch${PB_CH} -> mux ${PB_MUX} ch0) ===="
printf '%-3s %-12s %-8s %-7s %-14s %10s %10s %10s %10s %9s\n' \
"No." "Location" "Bricks" "SlaveID" "Netname" \
"Vin(V)" "Iin(A)" "Vout(V)" "Iout(A)" "Temp(C)"
printf '%s\n' "--------------------------------------------------------------------------------------------------------------"
local n=0 entry loc bk slave net kind vi ii vo io tp
for entry in "${PB_DEVS[@]}"; do
IFS=':' read -r loc bk slave net kind <<< "$entry"
n=$(( n + 1 ))
if [ "$kind" = "cpb" ]; then
vi=$(_pb_val "$slave" - 0x88 mant "$CPB_VIN_LSB" "" "" "$PB_VIN_LO" "$PB_VIN_HI")
ii="$PB_NA -" # no input current on this part
vo=$(_pb_val "$slave" - 0x8B lin11 "" "" "" "$PB_VOUT_LO" "$PB_VOUT_HI")
io=$(_pb_val "$slave" - 0x8C mant "$CPB_IOUT_LSB" "" "" "$PB_IOUT_LO" "$PB_IOUT_HI")
tp=$(_pb_val "$slave" - 0x8D direct 1 2 1 "$PB_TEMP_LO" "$PB_TEMP_HI")
else
vi=$(_pb_val "$slave" "$PB_PAGE_VIN" 0x88 direct "$PB_VIN_M" "$PB_VIN_R" "$PB_VIN_DIV" "$PB_VIN_LO" "$PB_VIN_HI")
ii=$(_pb_val "$slave" "$PB_PAGE_IIN" 0x89 direct "$PB_IIN_M" "$PB_IIN_R" "$PB_IIN_DIV" "$PB_IIN_LO" "$PB_IIN_HI")
vo=$(_pb_val "$slave" "$PB_PAGE_VOUT" 0x8B direct "$PB_VOUT_M" "$PB_VOUT_R" "$PB_VOUT_DIV" "$PB_VOUT_LO" "$PB_VOUT_HI")
io=$(_pb_val "$slave" "$PB_PAGE_IOUT" 0x8C direct "$PB_IOUT_M" "$PB_IOUT_R" "$PB_IOUT_DIV" "$PB_IOUT_LO" "$PB_IOUT_HI")
tp=$(_pb_val "$slave" "$PB_PAGE_TEMP" 0x8D direct "$PB_TEMP_M" "$PB_TEMP_R" "$PB_TEMP_DIV" "$PB_TEMP_LO" "$PB_TEMP_HI")
fi
printf '%-3s %-12s %-8s %-7s %-14s %10s %10s %10s %10s %9s\n' \
"$n" "$loc" "$bk" "$slave" "$net" \
"${vi%% *}" "${ii%% *}" "${vo%% *}" "${io%% *}" "${tp%% *}"
[ "$PB_RAW" = "1" ] && printf '%-3s %-12s %-8s %-7s %-14s %10s %10s %10s %10s %9s\n' \
"" "" "" "" "raw" "${vi##* }" "${ii##* }" "${vo##* }" "${io##* }" "${tp##* }"
done
# No trailing notes on stdout: this table gets pasted into reports and
# captured into the master console log, and a caveat printed every run stops
# being read after the second time. The caveats live in the file header -
# the one that still matters is that READ_VIN / READ_IIN are not in the
# datasheet coefficient table and borrow the Voltage / Current sets.
}
pwr_brick_help() {
echo -e "\033[1mpwr_brick.sh - PDB / CPB power brick readings\033[0m"
echo ""
echo -e " \033[33mshow\033[0m [-r] Vin / Iin / Vout / Iout / Temp for all 5 bricks (-r adds raw)"
echo -e " \033[33mhelp\033[0m"
echo ""
echo -e " Path : VI2C ch$PB_CH -> mux $PB_MUX ch0"
echo -e " The four ADPM12200 modules need a PMBus PAGE per measurement:"
echo -e " Vin $PB_PAGE_VIN(9) Iin $PB_PAGE_IIN(10) Vout $PB_PAGE_VOUT(2) Iout $PB_PAGE_IOUT(14) Temp $PB_PAGE_TEMP(18)"
echo -e " DIRECT format, datasheet Table 3: X = (1/m) x (Y x 10^-R - b)"
echo -e " CPB.PU37 (0x26) is a different part - no PAGE, its own scaling."
echo -e " \033[33mREAD_VIN / READ_IIN are not in Table 3; they borrow Voltage / Current.\033[0m"
}
case "${1:-help}" in
show)
shift 2>/dev/null
[ "${1:-}" = "-r" ] && PB_RAW=1
pwr_brick_show ;;
help|-h|--help) pwr_brick_help ;;
*) _pb_err "unknown sub-command: $1"; pwr_brick_help; exit 1 ;;
esac
+9 -1
View File
@@ -10,13 +10,21 @@ EN_log = 1 ; 1: Enable log, 0: Disable log
;================================================================
; FAN_SPEED
;================================================================
FAN_SPEED = 30
FAN_SPEED = 100
;================================================================
; Switch Unit Population
;================================================================
SWB_UNIT0 = 1 ; 1 = this DUT has switch unit 0, wait for it ; 0 = skip
SWB_UNIT1 = 1 ; 1 = this DUT has switch unit 1, wait for it ; 0 = skip
;================================================================
; Stress_Test
;================================================================
SSD_RUNTIME = 600 ; Unit seconds, 600 = 10 minutes
SSD_COUNT = 720 ; Total time = SSD_RUNTIME * SSD_COUNT
USB_RUNTIME = 600 ; Unit seconds, 600 = 10 minutes
USB_COUNT = 720 ; Total time = USB_RUNTIME * USB_COUNT
;================================================================
; Prompt Definitions
;================================================================
+12
View File
@@ -0,0 +1,12 @@
//Init
bcmcmd -n 0 -c 'mirror init'
bcmcmd -n 0 -c 'mirror port ce0 Mode=Ingress DestPort=ce0'
bcmcmd -n 0 -c 'vlan create 138'
bcmcmd -n 0 -c 'vlan add 138 pbm=ce0'
//Start
bcmcmd -n 0 -c 'tx 100 length=512 VLantag=138'
//stop
bcmcmd -n 0 -c 'mirror port ce0 Mode=Off'
bcmcmd -n 0 -c 'vlan remove 138 pbm=ce0'
+900
View File
@@ -0,0 +1,900 @@
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' "
bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' "
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3'
drivshell>
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get'
1 : PRBS OK!has been unlocked since last call
2 : PRBS OK!has been unlocked since last call
3 : PRBS OK!has been unlocked since last call
4 : PRBS OK!has been unlocked since last call
5 : PRBS OK!has been unlocked since last call
6 : PRBS OK!has been unlocked since last call
7 : PRBS OK!has been unlocked since last call
8 : PRBS OK!has been unlocked since last call
18 : PRBS OK!has been unlocked since last call
19 : PRBS OK!has been unlocked since last call
20 : PRBS OK!has been unlocked since last call
21 : PRBS OK!has been unlocked since last call
22 : PRBS OK!has been unlocked since last call
23 : PRBS OK!has been unlocked since last call
24 : PRBS OK!has been unlocked since last call
40 : PRBS OK!has been unlocked since last call
41 : PRBS OK!has been unlocked since last call
42 : PRBS OK!has been unlocked since last call
43 : PRBS OK!has been unlocked since last call
54 : PRBS OK!has been unlocked since last call
55 : PRBS OK!has been unlocked since last call
56 : PRBS OK!has been unlocked since last call
57 : PRBS OK!has been unlocked since last call
58 : PRBS OK!has been unlocked since last call
59 : PRBS OK!has been unlocked since last call
60 : PRBS OK!has been unlocked since last call
61 : PRBS OK!has been unlocked since last call
72 : PRBS OK!has been unlocked since last call
73 : PRBS OK!has been unlocked since last call
74 : PRBS OK!has been unlocked since last call
75 : PRBS OK!has been unlocked since last call
76 : PRBS OK!has been unlocked since last call
77 : PRBS OK!has been unlocked since last call
78 : PRBS OK!has been unlocked since last call
79 : PRBS OK!has been unlocked since last call
90 : PRBS OK!has been unlocked since last call
91 : PRBS OK!has been unlocked since last call
92 : PRBS OK!has been unlocked since last call
93 : PRBS OK!has been unlocked since last call
94 : PRBS OK!has been unlocked since last call
95 : PRBS OK!has been unlocked since last call
96 : PRBS OK!has been unlocked since last call
112 : PRBS OK!has been unlocked since last call
113 : PRBS OK!has been unlocked since last call
114 : PRBS OK!has been unlocked since last call
115 : PRBS OK!has been unlocked since last call
126 : PRBS OK!has been unlocked since last call
127 : PRBS OK!has been unlocked since last call
128 : PRBS OK!has been unlocked since last call
129 : PRBS OK!has been unlocked since last call
130 : PRBS OK!has been unlocked since last call
131 : PRBS OK!has been unlocked since last call
132 : PRBS OK!has been unlocked since last call
133 : PRBS OK!has been unlocked since last call
144 : PRBS OK!has been unlocked since last call
145 : PRBS OK!has been unlocked since last call
146 : PRBS OK!has been unlocked since last call
147 : PRBS OK!has been unlocked since last call
148 : PRBS OK!has been unlocked since last call
149 : PRBS OK!has been unlocked since last call
150 : PRBS OK!has been unlocked since last call
151 : PRBS OK!has been unlocked since last call
162 : PRBS OK!has been unlocked since last call
163 : PRBS OK!has been unlocked since last call
164 : PRBS OK!has been unlocked since last call
165 : PRBS OK!has been unlocked since last call
166 : PRBS OK!has been unlocked since last call
167 : PRBS OK!has been unlocked since last call
168 : PRBS OK!has been unlocked since last call
184 : PRBS OK!has been unlocked since last call
185 : PRBS OK!has been unlocked since last call
186 : PRBS OK!has been unlocked since last call
187 : PRBS OK!has been unlocked since last call
198 : PRBS OK!has been unlocked since last call
199 : PRBS OK!has been unlocked since last call
200 : PRBS OK!has been unlocked since last call
201 : PRBS OK!has been unlocked since last call
202 : PRBS OK!has been unlocked since last call
203 : PRBS OK!has been unlocked since last call
204 : PRBS OK!has been unlocked since last call
205 : PRBS OK!has been unlocked since last call
216 : PRBS OK!has been unlocked since last call
217 : PRBS OK!has been unlocked since last call
218 : PRBS OK!has been unlocked since last call
219 : PRBS OK!has been unlocked since last call
220 : PRBS OK!has been unlocked since last call
221 : PRBS OK!has been unlocked since last call
222 : PRBS OK!has been unlocked since last call
223 : PRBS OK!has been unlocked since last call
234 : PRBS OK!has been unlocked since last call
235 : PRBS OK!has been unlocked since last call
236 : PRBS OK!has been unlocked since last call
237 : PRBS OK!has been unlocked since last call
238 : PRBS OK!has been unlocked since last call
239 : PRBS OK!has been unlocked since last call
240 : PRBS OK!has been unlocked since last call
256 : PRBS OK!has been unlocked since last call
257 : PRBS OK!has been unlocked since last call
258 : PRBS OK!has been unlocked since last call
259 : PRBS OK!has been unlocked since last call
270 : PRBS OK!has been unlocked since last call
271 : PRBS OK!has been unlocked since last call
272 : PRBS OK!has been unlocked since last call
273 : PRBS OK!has been unlocked since last call
274 : PRBS OK!has been unlocked since last call
275 : PRBS OK!has been unlocked since last call
276 : PRBS OK!has been unlocked since last call
277 : PRBS OK!has been unlocked since last call
288 : PRBS OK!has been unlocked since last call
289 : PRBS OK!has been unlocked since last call
290 : PRBS OK!has been unlocked since last call
291 : PRBS OK!has been unlocked since last call
292 : PRBS OK!has been unlocked since last call
293 : PRBS OK!has been unlocked since last call
294 : PRBS OK!has been unlocked since last call
295 : PRBS OK!has been unlocked since last call
306 : PRBS OK!has been unlocked since last call
307 : PRBS OK!has been unlocked since last call
308 : PRBS OK!has been unlocked since last call
310 : PRBS OK!has been unlocked since last call
311 : PRBS OK!has been unlocked since last call
312 : PRBS OK!has been unlocked since last call
313 : PRBS OK!has been unlocked since last call
324 : PRBS OK!has been unlocked since last call
325 : PRBS OK!has been unlocked since last call
326 : PRBS OK!has been unlocked since last call
327 : PRBS OK!has been unlocked since last call
342 : PRBS OK!has been unlocked since last call
343 : PRBS OK!has been unlocked since last call
344 : PRBS OK!has been unlocked since last call
345 : PRBS OK!has been unlocked since last call
346 : PRBS OK!has been unlocked since last call
347 : PRBS OK!has been unlocked since last call
348 : PRBS OK!has been unlocked since last call
349 : PRBS OK!has been unlocked since last call
360 : PRBS OK!has been unlocked since last call
361 : PRBS OK!has been unlocked since last call
362 : PRBS OK!has been unlocked since last call
363 : PRBS OK!has been unlocked since last call
364 : PRBS OK!has been unlocked since last call
365 : PRBS OK!has been unlocked since last call
366 : PRBS OK!has been unlocked since last call
367 : PRBS OK!has been unlocked since last call
378 : PRBS OK!has been unlocked since last call
379 : PRBS OK!has been unlocked since last call
380 : PRBS OK!has been unlocked since last call
382 : PRBS OK!has been unlocked since last call
383 : PRBS OK!has been unlocked since last call
384 : PRBS OK!has been unlocked since last call
385 : PRBS OK!has been unlocked since last call
396 : PRBS OK!has been unlocked since last call
397 : PRBS OK!has been unlocked since last call
398 : PRBS OK!has been unlocked since last call
399 : PRBS OK!has been unlocked since last call
414 : PRBS OK!has been unlocked since last call
415 : PRBS OK!has been unlocked since last call
416 : PRBS OK!has been unlocked since last call
417 : PRBS OK!has been unlocked since last call
418 : PRBS OK!has been unlocked since last call
419 : PRBS OK!has been unlocked since last call
420 : PRBS OK!has been unlocked since last call
421 : PRBS OK!has been unlocked since last call
432 : PRBS OK!has been unlocked since last call
433 : PRBS OK!has been unlocked since last call
434 : PRBS OK!has been unlocked since last call
435 : PRBS OK!has been unlocked since last call
436 : PRBS OK!has been unlocked since last call
437 : PRBS OK!has been unlocked since last call
438 : PRBS OK!has been unlocked since last call
439 : PRBS OK!has been unlocked since last call
450 : PRBS OK!has been unlocked since last call
451 : PRBS OK!has been unlocked since last call
452 : PRBS OK!has been unlocked since last call
454 : PRBS OK!has been unlocked since last call
455 : PRBS OK!has been unlocked since last call
456 : PRBS OK!has been unlocked since last call
457 : PRBS OK!has been unlocked since last call
468 : PRBS OK!has been unlocked since last call
469 : PRBS OK!has been unlocked since last call
470 : PRBS OK!has been unlocked since last call
471 : PRBS OK!has been unlocked since last call
486 : PRBS OK!has been unlocked since last call
487 : PRBS OK!has been unlocked since last call
488 : PRBS OK!has been unlocked since last call
489 : PRBS OK!has been unlocked since last call
490 : PRBS OK!has been unlocked since last call
491 : PRBS OK!has been unlocked since last call
492 : PRBS OK!has been unlocked since last call
493 : PRBS OK!has been unlocked since last call
504 : PRBS OK!has been unlocked since last call
505 : PRBS OK!has been unlocked since last call
506 : PRBS OK!has been unlocked since last call
507 : PRBS OK!has been unlocked since last call
508 : PRBS OK!has been unlocked since last call
509 : PRBS OK!has been unlocked since last call
510 : PRBS OK!has been unlocked since last call
511 : PRBS OK!has been unlocked since last call
522 : PRBS OK!has been unlocked since last call
523 : PRBS OK!has been unlocked since last call
524 : PRBS OK!has been unlocked since last call
526 : PRBS OK!has been unlocked since last call
527 : PRBS OK!has been unlocked since last call
528 : PRBS OK!has been unlocked since last call
529 : PRBS OK!has been unlocked since last call
540 : PRBS OK!has been unlocked since last call
541 : PRBS OK!has been unlocked since last call
542 : PRBS OK!has been unlocked since last call
543 : PRBS OK!has been unlocked since last call
558 : PRBS OK!has been unlocked since last call
559 : PRBS OK!has been unlocked since last call
560 : PRBS OK!has been unlocked since last call
561 : PRBS OK!has been unlocked since last call
562 : PRBS OK!has been unlocked since last call
563 : PRBS OK!has been unlocked since last call
564 : PRBS OK!has been unlocked since last call
565 : PRBS OK!has been unlocked since last call
drivshell>
root@sonic:~#
root@sonic:~#
root@sonic:~#
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbssat STArt Interval=30' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30'
PRBSStat thread started ...
drivshell>
root@sonic:~# sleep 30
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber'
port BER
====
1[0] : 3.53e-11
1[1] : 4.00e-11
====
2[0] : 1.64e-10
2[1] : 8.80e-11
====
3[0] : 6.01e-11
3[1] : 3.45e-12
====
4[0] : 7.69e-11
4[1] : 2.60e-11
====
5[0] : 9.41e-13
5[1] : 6.27e-13
====
6[0] : 3.14e-13
6[1] : 6.27e-13
====
7[0] : 2.98e-12
7[1] : 2.20e-12
====
8[0] : 4.24e-12
8[1] : 9.41e-13
====
18[0] : 7.84e-13
18[1] : 2.04e-12
====
19[0] : 1.57e-13
19[1] : 1.73e-12
====
20[0] : 1.19e-11
20[1] : 1.41e-12
====
21[0] : 5.65e-12
21[1] : 7.69e-12
====
22[0] : 1.54e-11
22[1] : 7.84e-13
====
23[0] : 1.10e-12
23[1] : 2.35e-12
====
24[0] : 2.51e-12
24[1] : 1.41e-12
====
40[0] : 2.23e-11
40[1] : 2.35e-11
====
41[0] : 3.76e-12
41[1] : 4.55e-12
====
42[0] : 7.84e-12
42[1] : 3.76e-12
====
43[0] : 5.02e-12
43[1] : 1.35e-11
====
54[0] : 7.84e-13
54[1] : 6.27e-13
====
55[0] : 1.57e-13
55[1] : 1.57e-13
====
56[0] : 3.14e-13
56[1] : 4.71e-13
====
57[0] : 4.71e-12
57[1] : 6.27e-13
====
58[0] : 5.80e-12
58[1] : 4.24e-11
====
59[0] : 6.90e-12
59[1] : 7.84e-13
====
60[0] : 1.13e-11
60[1] : 1.10e-12
====
61[0] : 2.35e-12
61[1] : 5.49e-12
====
72[0] : 4.39e-11
72[1] : 5.49e-12
====
73[0] : 7.22e-12
73[1] : 8.00e-12
====
74[0] : 3.29e-12
74[1] : 1.25e-12
====
75[0] : 5.96e-12
75[1] : 3.45e-12
====
76[0] : 1.57e-13
76[1] : 1.41e-12
====
77[0] : 2.20e-12
77[1] : 1.57e-13
====
78[0] : 2.67e-12
78[1] : 1.41e-12
====
79[0] : 6.27e-13
79[1] : 3.14e-13
====
90[0] : 3.61e-12
90[1] : 1.91e-11
====
91[0] : 1.88e-12
91[1] : 4.24e-12
====
92[0] : 8.47e-12
92[1] : 4.08e-12
====
93[0] : 3.92e-12
93[1] : 1.82e-11
====
94[0] : 1.57e-13
94[1] : 1.41e-12
====
95[0] : 1.57e-13
95[1] : 1.57e-13
====
96[0] : 1.57e-13
96[1] : 4.71e-13
====
112[0] : 4.08e-12
112[1] : 2.04e-12
====
113[0] : 4.08e-12
113[1] : 3.29e-12
====
114[0] : 7.84e-13
114[1] : 9.41e-13
====
115[0] : 6.27e-13
115[1] : 1.88e-12
====
126[0] : 2.82e-12
126[1] : 1.57e-13
====
127[0] : 1.57e-13
127[1] : 4.71e-13
====
128[0] : 3.45e-12
128[1] : 3.14e-13
====
129[0] : 4.71e-13
129[1] : 6.27e-13
====
130[0] : 2.67e-12
130[1] : 1.57e-12
====
131[0] : 2.35e-12
131[1] : 6.12e-12
====
132[0] : 3.33e-11
132[1] : 5.02e-12
====
133[0] : 9.88e-12
133[1] : 6.90e-12
====
144[0] : 7.84e-13
144[1] : 7.22e-12
====
145[0] : 3.29e-12
145[1] : 6.12e-12
====
146[0] : 1.02e-11
146[1] : 1.57e-12
====
147[0] : 1.57e-12
147[1] : 3.92e-12
====
148[0] : 1.57e-13
148[1] : 1.25e-12
====
149[0] : 1.57e-13
149[1] : 1.57e-13
====
150[0] : 6.27e-13
150[1] : 1.57e-13
====
151[0] : 6.27e-13
151[1] : 3.14e-13
====
162[0] : 1.57e-13
162[1] : 6.27e-13
====
163[0] : 3.14e-13
163[1] : 1.57e-12
====
164[0] : 1.25e-12
164[1] : 2.20e-12
====
165[0] : 4.71e-13
165[1] : 2.67e-12
====
166[0] : 1.57e-13
166[1] : 3.14e-13
====
167[0] : 1.57e-13
167[1] : 1.57e-12
====
168[0] : 4.71e-13
168[1] : 1.57e-13
====
184[0] : 4.11e-10
184[1] : 3.12e-10
====
185[0] : 1.71e-08
185[1] : 3.13e-09
====
186[0] : 2.05e-10
186[1] : 2.27e-09
====
187[0] : 3.94e-11
187[1] : 2.97e-09
====
198[0] : 3.44e-11
198[1] : 3.29e-11
====
199[0] : 7.53e-10
199[1] : 1.66e-10
====
200[0] : 4.38e-11
200[1] : 3.81e-11
====
201[0] : 5.43e-11
201[1] : 1.95e-11
====
202[0] : 1.82e-10
202[1] : 5.74e-09
====
203[0] : 1.98e-08
203[1] : 5.05e-09
====
204[0] : 2.09e-10
204[1] : 5.71e-11
====
205[0] : 6.59e-11
205[1] : 5.21e-11
====
216[0] : 4.71e-13
216[1] : 6.27e-13
====
217[0] : 1.57e-12
217[1] : 6.27e-13
====
218[0] : 3.14e-13
218[1] : 1.57e-13
====
219[0] : 1.41e-12
219[1] : 1.41e-12
====
220[0] : 1.57e-13
220[1] : 1.57e-13
====
221[0] : 1.57e-13
221[1] : 1.57e-13
====
222[0] : 1.57e-13
222[1] : 3.14e-13
====
223[0] : 9.41e-13
223[1] : 1.57e-13
====
234[0] : 1.57e-13
234[1] : 4.71e-13
====
235[0] : 3.14e-13
235[1] : 1.25e-12
====
236[0] : 4.71e-13
236[1] : 1.57e-13
====
237[0] : 3.14e-13
237[1] : 1.57e-13
====
238[0] : 1.57e-13
238[1] : 1.57e-13
====
239[0] : 3.14e-13
239[1] : 3.14e-13
====
240[0] : 2.35e-12
240[1] : 1.57e-13
====
256[0] : 4.24e-12
256[1] : 7.37e-12
====
257[0] : 4.71e-13
257[1] : 7.69e-12
====
258[0] : 1.09e-09
258[1] : 6.25e-09
====
259[0] : 1.66e-11
259[1] : 1.02e-10
====
270[0] : 1.10e-12
270[1] : 9.25e-12
====
271[0] : 5.33e-12
271[1] : 1.62e-11
====
272[0] : 1.37e-10
272[1] : 9.15e-10
====
273[0] : 9.41e-12
273[1] : 1.90e-11
====
274[0] : 1.57e-13
274[1] : 2.04e-12
====
275[0] : 1.73e-12
275[1] : 2.20e-12
====
276[0] : 1.30e-10
276[1] : 1.36e-10
====
277[0] : 1.41e-12
277[1] : 2.04e-12
====
288[0] : 4.71e-13
288[1] : 4.71e-13
====
289[0] : 3.14e-13
289[1] : 2.20e-12
====
290[0] : 3.14e-13
290[1] : 1.57e-13
====
291[0] : 3.29e-11
291[1] : 1.08e-11
====
292[0] : 3.14e-13
292[1] : 6.27e-13
====
293[0] : 1.57e-13
293[1] : 5.80e-12
====
294[0] : 5.96e-12
294[1] : 1.88e-12
====
295[0] : 1.27e-11
295[1] : 1.21e-11
====
306[0] : 4.71e-13
306[1] : 1.10e-12
====
307[0] : 7.84e-13
307[1] : 5.02e-12
====
308[0] : 3.92e-12
308[1] : 2.67e-12
====
310[0] : 3.92e-12
310[1] : 1.25e-12
====
311[0] : 2.51e-12
311[1] : 6.27e-13
====
312[0] : 2.20e-12
312[1] : 6.75e-12
====
313[0] : 5.43e-11
313[1] : 2.18e-10
====
324[0] : 1.46e-11
324[1] : 1.27e-11
====
325[0] : 2.67e-12
325[1] : 7.94e-11
====
326[0] : 5.35e-11
326[1] : 2.35e-12
====
327[0] : 7.15e-11
327[1] : 1.11e-11
====
342[0] : 2.04e-12
342[1] : 1.41e-12
====
343[0] : 3.14e-13
343[1] : 3.61e-12
====
344[0] : 1.41e-12
344[1] : 1.57e-13
====
345[0] : 1.25e-12
345[1] : 1.41e-12
====
346[0] : 3.14e-13
346[1] : 1.57e-13
====
347[0] : 1.57e-13
347[1] : 3.14e-13
====
348[0] : 1.57e-13
348[1] : 3.14e-13
====
349[0] : 1.73e-12
349[1] : 2.21e-11
====
360[0] : 8.78e-12
360[1] : 1.24e-11
====
361[0] : 7.22e-12
361[1] : 1.87e-11
====
362[0] : 1.30e-11
362[1] : 1.74e-11
====
363[0] : 1.51e-10
363[1] : 2.85e-11
====
364[0] : 1.38e-11
364[1] : 1.17e-10
====
365[0] : 3.95e-11
365[1] : 2.67e-12
====
366[0] : 4.24e-12
366[1] : 5.49e-12
====
367[0] : 1.71e-10
367[1] : 1.40e-11
====
378[0] : 1.41e-11
378[1] : 3.50e-11
====
379[0] : 7.67e-11
379[1] : 1.03e-09
====
380[0] : 2.16e-11
380[1] : 1.62e-11
====
382[0] : 4.35e-11
382[1] : 1.81e-10
====
383[0] : 2.28e-10
383[1] : 1.41e-10
====
384[0] : 7.22e-12
384[1] : 5.71e-11
====
385[0] : 3.36e-11
385[1] : 2.16e-11
====
396[0] : 2.82e-12
396[1] : 4.55e-12
====
397[0] : 1.27e-11
397[1] : 1.41e-11
====
398[0] : 2.99e-10
398[1] : 5.80e-11
====
399[0] : 2.51e-11
399[1] : 1.11e-11
====
414[0] : 4.55e-12
414[1] : 8.31e-12
====
415[0] : 1.57e-13
415[1] : 9.41e-13
====
416[0] : 6.27e-12
416[1] : 5.96e-12
====
417[0] : 2.20e-12
417[1] : 1.88e-12
====
418[0] : 6.27e-13
418[1] : 1.25e-12
====
419[0] : 1.57e-13
419[1] : 1.41e-12
====
420[0] : 3.14e-13
420[1] : 2.82e-12
====
421[0] : 4.39e-12
421[1] : 1.16e-11
====
432[0] : 4.71e-13
432[1] : 6.27e-13
====
433[0] : 4.71e-13
433[1] : 1.57e-12
====
434[0] : 4.71e-13
434[1] : 1.57e-13
====
435[0] : 1.25e-12
435[1] : 1.57e-13
====
436[0] : 1.57e-13
436[1] : 1.57e-13
====
437[0] : 1.57e-13
437[1] : 4.71e-13
====
438[0] : 7.84e-13
438[1] : 1.41e-12
====
439[0] : 1.41e-12
439[1] : 1.10e-12
====
450[0] : 6.27e-13
450[1] : 4.71e-13
====
451[0] : 1.57e-13
451[1] : 1.25e-12
====
452[0] : 1.10e-12
452[1] : 7.84e-13
====
454[0] : 1.10e-12
454[1] : 1.88e-12
====
455[0] : 6.27e-13
455[1] : 1.57e-12
====
456[0] : 1.88e-12
456[1] : 9.41e-13
====
457[0] : 7.84e-13
457[1] : 4.71e-13
====
468[0] : 6.27e-13
468[1] : 9.41e-13
====
469[0] : 2.67e-12
469[1] : 4.08e-12
====
470[0] : 3.14e-13
470[1] : 4.71e-13
====
471[0] : 3.14e-13
471[1] : 7.84e-13
====
486[0] : 1.73e-12
486[1] : 1.57e-12
====
487[0] : 1.10e-12
487[1] : 2.82e-12
====
488[0] : 4.71e-13
488[1] : 4.71e-13
====
489[0] : 9.41e-13
489[1] : 3.14e-13
====
490[0] : 1.57e-13
490[1] : 3.14e-13
====
491[0] : 3.14e-13
491[1] : 1.57e-13
====
492[0] : 9.41e-13
492[1] : 1.10e-12
====
493[0] : 7.84e-13
493[1] : 2.98e-12
====
504[0] : 4.71e-13
504[1] : 3.14e-13
====
505[0] : 1.57e-13
505[1] : 7.84e-13
====
506[0] : 4.71e-13
506[1] : 1.57e-13
====
507[0] : 3.14e-13
507[1] : 1.57e-13
====
508[0] : 2.04e-12
508[1] : 1.41e-12
====
509[0] : 9.41e-13
509[1] : 7.84e-13
====
510[0] : 1.57e-13
510[1] : 6.27e-13
====
511[0] : 6.27e-13
511[1] : 4.71e-13
====
522[0] : 2.35e-12
522[1] : 1.57e-13
====
523[0] : 3.14e-13
523[1] : 6.27e-13
====
524[0] : 7.84e-13
524[1] : 1.57e-13
====
526[0] : 7.84e-13
526[1] : 3.14e-13
====
527[0] : 1.41e-12
527[1] : 4.71e-13
====
528[0] : 3.14e-13
528[1] : 9.41e-13
====
529[0] : 4.71e-13
529[1] : 1.57e-13
====
540[0] : 6.27e-13
540[1] : 1.25e-12
====
541[0] : 3.14e-13
541[1] : 1.10e-12
====
542[0] : 2.98e-12
542[1] : 6.27e-13
====
543[0] : 2.98e-12
543[1] : 3.14e-13
====
558[0] : 9.41e-13
558[1] : 1.10e-12
====
559[0] : 3.29e-12
559[1] : 2.04e-12
====
560[0] : 1.57e-13
560[1] : 1.57e-13
====
561[0] : 2.35e-12
561[1] : 4.71e-13
====
562[0] : 1.57e-13
562[1] : 1.57e-13
====
563[0] : 1.57e-13
563[1] : 4.71e-13
====
564[0] : 1.41e-12
564[1] : 7.84e-13
====
565[0] : 4.55e-12
565[1] : 1.57e-13
====
drivshell>
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbssat STOp' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp'
Stopping PRBSStat thread
drivshell>
root@sonic:~# bcmcmd -n 0 -c " dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' "
dsh -c 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear'
drivshell>
root@sonic:~#
+40
View File
@@ -0,0 +1,40 @@
SWB0_0V9_ANLG0
SWB0_0V9_ANLG1
SWB0_0V75_ANLG0
SWB0_0V75_ANLG1
SWB0_PHYTILE_P0
SWB0_PHYTILE_P1
SWB0_PHYTILE_P2
SWB0_PHYTILE_P3
SWB0_PHYTILE_P4
SWB0_PHYTILE_P5
SWB0_PHYTILE_P6
SWB0_PHYTILE_P7
SWB0_PVDD1V5_CNDR0
SWB0_PVDD1V5_CNDR1
SWB0_PVDDA_PHYT0
SWB0_PVDDA_PHYT1
SWB0_PVDDA_PHYT2
SWB0_PVDDA_PHYT3
SWB0_TH6_CORE
SWB1_0V9_ANLG0
SWB1_0V9_ANLG1
SWB1_0V75_ANLG0
SWB1_0V75_ANLG1
SWB1_PHYTILE_P0
SWB1_PHYTILE_P1
SWB1_PHYTILE_P2
SWB1_PHYTILE_P3
SWB1_PHYTILE_P4
SWB1_PHYTILE_P5
SWB1_PHYTILE_P6
SWB1_PHYTILE_P7
SWB1_PVDD1V5_CNDR0
SWB1_PVDD1V5_CNDR1
SWB1_PVDDA_PHYT0
SWB1_PVDDA_PHYT1
SWB1_PVDDA_PHYT2
SWB1_PVDDA_PHYT3
SWB1_TH6_CORE
+188
View File
@@ -0,0 +1,188 @@
//0.900V (nominal)
i2cset -f -y 13 0x25 0x00 0
i2ctransfer -f -y 13 w3@0x25 0x21 0x83 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x0D 0x74 0x10
//0.900V (nominal)
i2cset -f -y 15 0x26 0x00 0
i2ctransfer -f -y 15 w3@0x26 0x21 0x83 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x0D 0x74 0x10
//0.75V (nominal)
i2cset -f -y 13 0x25 0x00 1
i2ctransfer -f -y 13 w3@0x25 0x21 0x65 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 15 0x26 0x00 1
i2ctransfer -f -y 15 w3@0x26 0x21 0x65 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 13 0x21 0x00 0
i2ctransfer -f -y 13 w3@0x21 0x21 0x65 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 13 0x21 0x00 1
i2ctransfer -f -y 13 w3@0x21 0x21 0x65 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 13 0x22 0x00 0
i2ctransfer -f -y 13 w3@0x22 0x21 0x65 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 13 0x22 0x00 1
i2ctransfer -f -y 13 w3@0x22 0x21 0x65 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 15 0x23 0x00 0
i2ctransfer -f -y 15 w3@0x23 0x21 0x65 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 15 0x23 0x00 1
i2ctransfer -f -y 15 w3@0x23 0x21 0x65 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 15 0x24 0x00 0
i2ctransfer -f -y 15 w3@0x24 0x21 0x65 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 15 0x24 0x00 1
i2ctransfer -f -y 15 w3@0x24 0x21 0x65 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x1D 0x5A 0x06
//1.5V (nominal)
i2cset -f -y 13 0x29 0x00 0
i2ctransfer -f -y 13 w3@0x29 0x21 0xFB 0x00
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x0D 0x71 0x1F
//1.5V (nominal)
i2cset -f -y 13 0x29 0x00 1
i2ctransfer -f -y 13 w3@0x29 0x21 0xFB 0x00
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x1D 0xB9 0x0F
//0.720V
i2cset -f -y 13 0x27 0x00 0
i2ctransfer -f -y 13 w3@0x27 0x21 0x5F 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x0D 0xF4 0x0B
//0.720V
i2cset -f -y 13 0x27 0x00 1
i2ctransfer -f -y 13 w3@0x27 0x21 0x5F 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x1D 0xFC 0x05
//0.720V
i2cset -f -y 15 0x28 0x00 0
i2ctransfer -f -y 15 w3@0x28 0x21 0x5F 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x0D 0xF4 0x0B
//0.720V
i2cset -f -y 15 0x28 0x00 1
i2ctransfer -f -y 15 w3@0x28 0x21 0x5F 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x1D 0xFC 0x05
//0.8V(nominal) , 0.8591V with load line
i2cset -f -y 13 0x20 0x00 0
i2ctransfer -f -y 13 w3@0x20 0x21 0x57 0x01
//0.900V (nominal)
i2cset -f -y 14 0x25 0x00 0
i2ctransfer -f -y 14 w3@0x25 0x21 0x83 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x0D 0x74 0x10
//0.900V (nominal)
i2cset -f -y 16 0x26 0x00 0
i2ctransfer -f -y 16 w3@0x26 0x21 0x83 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x0D 0x74 0x10
//0.75V (nominal)
i2cset -f -y 14 0x25 0x00 1
i2ctransfer -f -y 14 w3@0x25 0x21 0x65 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 16 0x26 0x00 1
i2ctransfer -f -y 16 w3@0x26 0x21 0x65 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 14 0x21 0x00 0
i2ctransfer -f -y 14 w3@0x21 0x21 0x65 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 14 0x21 0x00 1
i2ctransfer -f -y 14 w3@0x21 0x21 0x65 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 14 0x22 0x00 0
i2ctransfer -f -y 14 w3@0x22 0x21 0x65 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 14 0x22 0x00 1
i2ctransfer -f -y 14 w3@0x22 0x21 0x65 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 16 0x23 0x00 0
i2ctransfer -f -y 16 w3@0x23 0x21 0x65 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 16 0x23 0x00 1
i2ctransfer -f -y 16 w3@0x23 0x21 0x65 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x1D 0x5A 0x06
//0.75V (nominal)
i2cset -f -y 16 0x24 0x00 0
i2ctransfer -f -y 16 w3@0x24 0x21 0x65 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x0D 0xB2 0x0C
//0.75V (nominal)
i2cset -f -y 16 0x24 0x00 1
i2ctransfer -f -y 16 w3@0x24 0x21 0x65 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x1D 0x5A 0x06
//1.5V (nominal)
i2cset -f -y 14 0x29 0x00 0
i2ctransfer -f -y 14 w3@0x29 0x21 0xFB 0x00
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x0D 0x71 0x1F
//1.5V (nominal)
i2cset -f -y 14 0x29 0x00 1
i2ctransfer -f -y 14 w3@0x29 0x21 0xFB 0x00
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x1D 0xB9 0x0F
//0.720V (nominal)
i2cset -f -y 14 0x27 0x00 0
i2ctransfer -f -y 14 w3@0x27 0x21 0x5F 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x0D 0xF4 0x0B
//0.720V (nominal)
i2cset -f -y 14 0x27 0x00 1
i2ctransfer -f -y 14 w3@0x27 0x21 0x5F 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x1D 0xFC 0x05
//0.720V (nominal)
i2cset -f -y 16 0x28 0x00 0
i2ctransfer -f -y 16 w3@0x28 0x21 0x5F 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x0D 0xF4 0x0B
//0.720V (nominal)
i2cset -f -y 16 0x28 0x00 1
i2ctransfer -f -y 16 w3@0x28 0x21 0x5F 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x1D 0xFC 0x05
//0.8V(nominal) , 0.8591V with load line
i2cset -f -y 14 0x20 0x00 0
i2ctransfer -f -y 14 w3@0x20 0x21 0x57 0x01
+48
View File
@@ -0,0 +1,48 @@
i2cset -f -y 13 0x25 0x00 0
i2cset -f -y 13 0x25 0x15
i2cset -f -y 15 0x26 0x00 0
i2cset -f -y 15 0x26 0x15
i2cset -f -y 13 0x25 0x00 0
i2cset -f -y 13 0x25 0x15
i2cset -f -y 15 0x26 0x00 0
i2cset -f -y 15 0x26 0x15
i2cset -f -y 13 0x21 0x00 0
i2cset -f -y 13 0x21 0x15
i2cset -f -y 13 0x22 0x00 0
i2cset -f -y 13 0x22 0x15
i2cset -f -y 15 0x23 0x00 0
i2cset -f -y 15 0x23 0x15
i2cset -f -y 15 0x24 0x00 0
i2cset -f -y 15 0x24 0x15
i2cset -f -y 13 0x29 0x00 0
i2cset -f -y 13 0x29 0x15
i2cset -f -y 13 0x27 0x00 0
i2cset -f -y 13 0x27 0x15
i2cset -f -y 15 0x28 0x00 0
i2cset -f -y 15 0x28 0x15
i2cset -f -y 13 0x20 0x00 0
i2cset -f -y 13 0x20 0x17
i2cset -f -y 14 0x25 0x00 0
i2cset -f -y 14 0x25 0x15
i2cset -f -y 16 0x26 0x00 0
i2cset -f -y 16 0x26 0x15
i2cset -f -y 14 0x25 0x00 0
i2cset -f -y 14 0x25 0x15
i2cset -f -y 16 0x26 0x00 0
i2cset -f -y 16 0x26 0x15
i2cset -f -y 14 0x21 0x00 0
i2cset -f -y 14 0x21 0x15
i2cset -f -y 14 0x22 0x00 0
i2cset -f -y 14 0x22 0x15
i2cset -f -y 16 0x23 0x00 0
i2cset -f -y 16 0x23 0x15
i2cset -f -y 16 0x24 0x00 0
i2cset -f -y 16 0x24 0x15
i2cset -f -y 14 0x29 0x00 0
i2cset -f -y 14 0x29 0x15
i2cset -f -y 14 0x27 0x00 0
i2cset -f -y 14 0x27 0x15
i2cset -f -y 16 0x28 0x00 0
i2cset -f -y 16 0x28 0x15
i2cset -f -y 14 0x20 0x00 0
i2cset -f -y 14 0x20 0x17
+188
View File
@@ -0,0 +1,188 @@
//0.930V
i2cset -f -y 13 0x25 0x00 0
i2ctransfer -f -y 13 w3@0x25 0x21 0x89 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x0D 0x34 0x11
//0.930V
i2cset -f -y 15 0x26 0x00 0
i2ctransfer -f -y 15 w3@0x26 0x21 0x89 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x0D 0x34 0x11
//0.725V
i2cset -f -y 13 0x25 0x00 1
i2ctransfer -f -y 13 w3@0x25 0x21 0x60 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 15 0x26 0x00 1
i2ctransfer -f -y 15 w3@0x26 0x21 0x60 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 13 0x21 0x00 0
i2ctransfer -f -y 13 w3@0x21 0x21 0x60 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 13 0x21 0x00 1
i2ctransfer -f -y 13 w3@0x21 0x21 0x60 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 13 0x22 0x00 0
i2ctransfer -f -y 13 w3@0x22 0x21 0x60 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 13 0x22 0x00 1
i2ctransfer -f -y 13 w3@0x22 0x21 0x60 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 15 0x23 0x00 0
i2ctransfer -f -y 15 w3@0x23 0x21 0x60 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 15 0x23 0x00 1
i2ctransfer -f -y 15 w3@0x23 0x21 0x60 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 15 0x24 0x00 0
i2ctransfer -f -y 15 w3@0x24 0x21 0x60 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 15 0x24 0x00 1
i2ctransfer -f -y 15 w3@0x24 0x21 0x60 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x1D 0x0A 0x06
//1.545V
i2cset -f -y 13 0x29 0x00 0
i2ctransfer -f -y 13 w3@0x29 0x21 0x04 0x01
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x0D 0x91 0x20
//1.545V
i2cset -f -y 13 0x29 0x00 1
i2ctransfer -f -y 13 w3@0x29 0x21 0x04 0x01
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x1D 0x49 0x10
//0.745V
i2cset -f -y 13 0x27 0x00 0
i2ctransfer -f -y 13 w3@0x27 0x21 0x64 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 13 0x27 0x00 1
i2ctransfer -f -y 13 w3@0x27 0x21 0x64 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x1D 0x4C 0x06
//0.745V
i2cset -f -y 15 0x28 0x00 0
i2ctransfer -f -y 15 w3@0x28 0x21 0x64 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 15 0x28 0x00 1
i2ctransfer -f -y 15 w3@0x28 0x21 0x64 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x1D 0x4C 0x06
//0.885V
i2cset -f -y 13 0x20 0x00 0
i2ctransfer -f -y 13 w3@0x20 0x21 0x62 0x01
//0.930V
i2cset -f -y 14 0x25 0x00 0
i2ctransfer -f -y 14 w3@0x25 0x21 0x89 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x0D 0x34 0x11
//0.930V
i2cset -f -y 16 0x26 0x00 0
i2ctransfer -f -y 16 w3@0x26 0x21 0x89 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x0D 0x34 0x11
//0.725V
i2cset -f -y 14 0x25 0x00 1
i2ctransfer -f -y 14 w3@0x25 0x21 0x60 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 16 0x26 0x00 1
i2ctransfer -f -y 16 w3@0x26 0x21 0x60 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 14 0x21 0x00 0
i2ctransfer -f -y 14 w3@0x21 0x21 0x60 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 14 0x21 0x00 1
i2ctransfer -f -y 14 w3@0x21 0x21 0x60 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 14 0x22 0x00 0
i2ctransfer -f -y 14 w3@0x22 0x21 0x60 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 14 0x22 0x00 1
i2ctransfer -f -y 14 w3@0x22 0x21 0x60 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 16 0x23 0x00 0
i2ctransfer -f -y 16 w3@0x23 0x21 0x60 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 16 0x23 0x00 1
i2ctransfer -f -y 16 w3@0x23 0x21 0x60 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 16 0x24 0x00 0
i2ctransfer -f -y 16 w3@0x24 0x21 0x60 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 16 0x24 0x00 1
i2ctransfer -f -y 16 w3@0x24 0x21 0x60 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x1D 0x0A 0x06
//1.545V
i2cset -f -y 14 0x29 0x00 0
i2ctransfer -f -y 14 w3@0x29 0x21 0x04 0x01
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x0D 0x91 0x20
//1.545V
i2cset -f -y 14 0x29 0x00 1
i2ctransfer -f -y 14 w3@0x29 0x21 0x04 0x01
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x1D 0x49 0x10
//0.745V
i2cset -f -y 14 0x27 0x00 0
i2ctransfer -f -y 14 w3@0x27 0x21 0x64 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 14 0x27 0x00 1
i2ctransfer -f -y 14 w3@0x27 0x21 0x64 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x1D 0x4C 0x06
//0.745V
i2cset -f -y 16 0x28 0x00 0
i2ctransfer -f -y 16 w3@0x28 0x21 0x64 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 16 0x28 0x00 1
i2ctransfer -f -y 16 w3@0x28 0x21 0x64 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x1D 0x4C 0x06
//0.885V
i2cset -f -y 14 0x20 0x00 0
i2ctransfer -f -y 14 w3@0x20 0x21 0x62 0x01
+188
View File
@@ -0,0 +1,188 @@
//0.870V
i2cset -f -y 13 0x25 0x00 0
i2ctransfer -f -y 13 w3@0x25 0x21 0x7D 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x0D 0xB4 0x0F
//0.870V
i2cset -f -y 15 0x26 0x00 0
i2ctransfer -f -y 15 w3@0x26 0x21 0x7D 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x0D 0xB4 0x0F
//0.775V
i2cset -f -y 13 0x25 0x00 1
i2ctransfer -f -y 13 w3@0x25 0x21 0x6A 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 15 0x26 0x00 1
i2ctransfer -f -y 15 w3@0x26 0x21 0x6A 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 13 0x21 0x00 0
i2ctransfer -f -y 13 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 13 0x21 0x00 1
i2ctransfer -f -y 13 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 13 0x22 0x00 0
i2ctransfer -f -y 13 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 13 0x22 0x00 1
i2ctransfer -f -y 13 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 15 0x23 0x00 0
i2ctransfer -f -y 15 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 15 0x23 0x00 1
i2ctransfer -f -y 15 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 15 0x24 0x00 0
i2ctransfer -f -y 15 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 15 0x24 0x00 1
i2ctransfer -f -y 15 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x1D 0xAA 0x06
//1.455V
i2cset -f -y 13 0x29 0x00 0
i2ctransfer -f -y 13 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x0D 0x51 0x1E
//1.455V
i2cset -f -y 13 0x29 0x00 1
i2ctransfer -f -y 13 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x1D 0x29 0x0F
//0.695V
i2cset -f -y 13 0x27 0x00 0
i2ctransfer -f -y 13 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 13 0x27 0x00 1
i2ctransfer -f -y 13 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x1D 0xAC 0x05
//0.695V
i2cset -f -y 15 0x28 0x00 0
i2ctransfer -f -y 15 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 15 0x28 0x00 1
i2ctransfer -f -y 15 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x1D 0xAC 0x05
//0.753V
i2cset -f -y 13 0x20 0x00 0
i2ctransfer -f -y 13 w3@0x20 0x21 0x2D 0x01
//0.870V
i2cset -f -y 14 0x25 0x00 0
i2ctransfer -f -y 14 w3@0x25 0x21 0x7D 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x0D 0xB4 0x0F
//0.870V
i2cset -f -y 16 0x26 0x00 0
i2ctransfer -f -y 16 w3@0x26 0x21 0x7D 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x0D 0xB4 0x0F
//0.775V
i2cset -f -y 14 0x25 0x00 1
i2ctransfer -f -y 14 w3@0x25 0x21 0x6A 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 16 0x26 0x00 1
i2ctransfer -f -y 16 w3@0x26 0x21 0x6A 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 14 0x21 0x00 0
i2ctransfer -f -y 14 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 14 0x21 0x00 1
i2ctransfer -f -y 14 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 14 0x22 0x00 0
i2ctransfer -f -y 14 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 14 0x22 0x00 1
i2ctransfer -f -y 14 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 16 0x23 0x00 0
i2ctransfer -f -y 16 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 16 0x23 0x00 1
i2ctransfer -f -y 16 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 16 0x24 0x00 0
i2ctransfer -f -y 16 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 16 0x24 0x00 1
i2ctransfer -f -y 16 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x1D 0xAA 0x06
//1.455V
i2cset -f -y 14 0x29 0x00 0
i2ctransfer -f -y 14 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x0D 0x51 0x1E
//1.455V
i2cset -f -y 14 0x29 0x00 1
i2ctransfer -f -y 14 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x1D 0x29 0x0F
//0.695V
i2cset -f -y 14 0x27 0x00 0
i2ctransfer -f -y 14 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 14 0x27 0x00 1
i2ctransfer -f -y 14 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x1D 0xAC 0x05
//0.695V
i2cset -f -y 16 0x28 0x00 0
i2ctransfer -f -y 16 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 16 0x28 0x00 1
i2ctransfer -f -y 16 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x1D 0xAC 0x05
//0.753V
i2cset -f -y 14 0x20 0x00 0
i2ctransfer -f -y 14 w3@0x20 0x21 0x2D 0x01
+188
View File
@@ -0,0 +1,188 @@
//0.930V
i2cset -f -y 13 0x25 0x00 0
i2ctransfer -f -y 13 w3@0x25 0x21 0x89 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x0D 0x34 0x11
//0.930V
i2cset -f -y 15 0x26 0x00 0
i2ctransfer -f -y 15 w3@0x26 0x21 0x89 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x0D 0x34 0x11
//0.775V
i2cset -f -y 13 0x25 0x00 1
i2ctransfer -f -y 13 w3@0x25 0x21 0x6A 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 15 0x26 0x00 1
i2ctransfer -f -y 15 w3@0x26 0x21 0x6A 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 13 0x21 0x00 0
i2ctransfer -f -y 13 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 13 0x21 0x00 1
i2ctransfer -f -y 13 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 13 0x22 0x00 0
i2ctransfer -f -y 13 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 13 0x22 0x00 1
i2ctransfer -f -y 13 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 15 0x23 0x00 0
i2ctransfer -f -y 15 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 15 0x23 0x00 1
i2ctransfer -f -y 15 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 15 0x24 0x00 0
i2ctransfer -f -y 15 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 15 0x24 0x00 1
i2ctransfer -f -y 15 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x1D 0xAA 0x06
//1.545V
i2cset -f -y 13 0x29 0x00 0
i2ctransfer -f -y 13 w3@0x29 0x21 0x04 0x01
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x0D 0x91 0x20
//1.545V
i2cset -f -y 13 0x29 0x00 1
i2ctransfer -f -y 13 w3@0x29 0x21 0x04 0x01
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x1D 0x49 0x10
//0.745V
i2cset -f -y 13 0x27 0x00 0
i2ctransfer -f -y 13 w3@0x27 0x21 0x64 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 13 0x27 0x00 1
i2ctransfer -f -y 13 w3@0x27 0x21 0x64 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x1D 0x4C 0x06
//0.745V
i2cset -f -y 15 0x28 0x00 0
i2ctransfer -f -y 15 w3@0x28 0x21 0x64 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 15 0x28 0x00 1
i2ctransfer -f -y 15 w3@0x28 0x21 0x64 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x1D 0x4C 0x06
//0.885V
i2cset -f -y 13 0x20 0x00 0
i2ctransfer -f -y 13 w3@0x20 0x21 0x62 0x01
//0.930V
i2cset -f -y 14 0x25 0x00 0
i2ctransfer -f -y 14 w3@0x25 0x21 0x89 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x0D 0x34 0x11
//0.930V
i2cset -f -y 16 0x26 0x00 0
i2ctransfer -f -y 16 w3@0x26 0x21 0x89 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x0D 0x34 0x11
//0.775V
i2cset -f -y 14 0x25 0x00 1
i2ctransfer -f -y 14 w3@0x25 0x21 0x6A 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 16 0x26 0x00 1
i2ctransfer -f -y 16 w3@0x26 0x21 0x6A 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 14 0x21 0x00 0
i2ctransfer -f -y 14 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 14 0x21 0x00 1
i2ctransfer -f -y 14 w3@0x21 0x21 0x6A 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 14 0x22 0x00 0
i2ctransfer -f -y 14 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 14 0x22 0x00 1
i2ctransfer -f -y 14 w3@0x22 0x21 0x6A 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 16 0x23 0x00 0
i2ctransfer -f -y 16 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 16 0x23 0x00 1
i2ctransfer -f -y 16 w3@0x23 0x21 0x6A 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x1D 0xAA 0x06
//0.775V
i2cset -f -y 16 0x24 0x00 0
i2ctransfer -f -y 16 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x0D 0x52 0x0D
//0.775V
i2cset -f -y 16 0x24 0x00 1
i2ctransfer -f -y 16 w3@0x24 0x21 0x6A 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x1D 0xAA 0x06
//1.545V
i2cset -f -y 14 0x29 0x00 0
i2ctransfer -f -y 14 w3@0x29 0x21 0x04 0x01
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x0D 0x91 0x20
//1.545V
i2cset -f -y 14 0x29 0x00 1
i2ctransfer -f -y 14 w3@0x29 0x21 0x04 0x01
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x1D 0x49 0x10
//0.745V
i2cset -f -y 14 0x27 0x00 0
i2ctransfer -f -y 14 w3@0x27 0x21 0x64 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 14 0x27 0x00 1
i2ctransfer -f -y 14 w3@0x27 0x21 0x64 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x1D 0x4C 0x06
//0.745V
i2cset -f -y 16 0x28 0x00 0
i2ctransfer -f -y 16 w3@0x28 0x21 0x64 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x0D 0x94 0x0C
//0.745V
i2cset -f -y 16 0x28 0x00 1
i2ctransfer -f -y 16 w3@0x28 0x21 0x64 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x1D 0x4C 0x06
//0.885V
i2cset -f -y 14 0x20 0x00 0
i2ctransfer -f -y 14 w3@0x20 0x21 0x62 0x01
+188
View File
@@ -0,0 +1,188 @@
//0.870V
i2cset -f -y 13 0x25 0x00 0
i2ctransfer -f -y 13 w3@0x25 0x21 0x7D 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x0D 0xB4 0x0F
//0.870V
i2cset -f -y 15 0x26 0x00 0
i2ctransfer -f -y 15 w3@0x26 0x21 0x7D 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x0D 0xB4 0x0F
//0.725V
i2cset -f -y 13 0x25 0x00 1
i2ctransfer -f -y 13 w3@0x25 0x21 0x60 0x00
i2cset -f -y 13 0x25 0x00 2
i2ctransfer -f -y 13 w3@0x25 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 15 0x26 0x00 1
i2ctransfer -f -y 15 w3@0x26 0x21 0x60 0x00
i2cset -f -y 15 0x26 0x00 2
i2ctransfer -f -y 15 w3@0x26 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 13 0x21 0x00 0
i2ctransfer -f -y 13 w3@0x21 0x21 0x60 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 13 0x21 0x00 1
i2ctransfer -f -y 13 w3@0x21 0x21 0x60 0x00
i2cset -f -y 13 0x21 0x00 2
i2ctransfer -f -y 13 w3@0x21 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 13 0x22 0x00 0
i2ctransfer -f -y 13 w3@0x22 0x21 0x60 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 13 0x22 0x00 1
i2ctransfer -f -y 13 w3@0x22 0x21 0x60 0x00
i2cset -f -y 13 0x22 0x00 2
i2ctransfer -f -y 13 w3@0x22 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 15 0x23 0x00 0
i2ctransfer -f -y 15 w3@0x23 0x21 0x60 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 15 0x23 0x00 1
i2ctransfer -f -y 15 w3@0x23 0x21 0x60 0x00
i2cset -f -y 15 0x23 0x00 2
i2ctransfer -f -y 15 w3@0x23 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 15 0x24 0x00 0
i2ctransfer -f -y 15 w3@0x24 0x21 0x60 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 15 0x24 0x00 1
i2ctransfer -f -y 15 w3@0x24 0x21 0x60 0x00
i2cset -f -y 15 0x24 0x00 2
i2ctransfer -f -y 15 w3@0x24 0x1D 0x0A 0x06
//1.455V
i2cset -f -y 13 0x29 0x00 0
i2ctransfer -f -y 13 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x0D 0x51 0x1E
//1.455V
i2cset -f -y 13 0x29 0x00 1
i2ctransfer -f -y 13 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 13 0x29 0x00 2
i2ctransfer -f -y 13 w3@0x29 0x1D 0x29 0x0F
//0.695V
i2cset -f -y 13 0x27 0x00 0
i2ctransfer -f -y 13 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 13 0x27 0x00 1
i2ctransfer -f -y 13 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 13 0x27 0x00 2
i2ctransfer -f -y 13 w3@0x27 0x1D 0xAC 0x05
//0.695V
i2cset -f -y 15 0x28 0x00 0
i2ctransfer -f -y 15 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 15 0x28 0x00 1
i2ctransfer -f -y 15 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 15 0x28 0x00 2
i2ctransfer -f -y 15 w3@0x28 0x1D 0xAC 0x05
//0.753V
i2cset -f -y 13 0x20 0x00 0
i2ctransfer -f -y 13 w3@0x20 0x21 0x2D 0x01
//0.870V
i2cset -f -y 14 0x25 0x00 0
i2ctransfer -f -y 14 w3@0x25 0x21 0x7D 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x0D 0xB4 0x0F
//0.870V
i2cset -f -y 16 0x26 0x00 0
i2ctransfer -f -y 16 w3@0x26 0x21 0x7D 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x0D 0xB4 0x0F
//0.725V
i2cset -f -y 14 0x25 0x00 1
i2ctransfer -f -y 14 w3@0x25 0x21 0x60 0x00
i2cset -f -y 14 0x25 0x00 2
i2ctransfer -f -y 14 w3@0x25 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 16 0x26 0x00 1
i2ctransfer -f -y 16 w3@0x26 0x21 0x60 0x00
i2cset -f -y 16 0x26 0x00 2
i2ctransfer -f -y 16 w3@0x26 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 14 0x21 0x00 0
i2ctransfer -f -y 14 w3@0x21 0x21 0x60 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 14 0x21 0x00 1
i2ctransfer -f -y 14 w3@0x21 0x21 0x60 0x00
i2cset -f -y 14 0x21 0x00 2
i2ctransfer -f -y 14 w3@0x21 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 14 0x22 0x00 0
i2ctransfer -f -y 14 w3@0x22 0x21 0x60 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 14 0x22 0x00 1
i2ctransfer -f -y 14 w3@0x22 0x21 0x60 0x00
i2cset -f -y 14 0x22 0x00 2
i2ctransfer -f -y 14 w3@0x22 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 16 0x23 0x00 0
i2ctransfer -f -y 16 w3@0x23 0x21 0x60 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 16 0x23 0x00 1
i2ctransfer -f -y 16 w3@0x23 0x21 0x60 0x00
i2cset -f -y 16 0x23 0x00 2
i2ctransfer -f -y 16 w3@0x23 0x1D 0x0A 0x06
//0.725V
i2cset -f -y 16 0x24 0x00 0
i2ctransfer -f -y 16 w3@0x24 0x21 0x60 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x0D 0x12 0x0C
//0.725V
i2cset -f -y 16 0x24 0x00 1
i2ctransfer -f -y 16 w3@0x24 0x21 0x60 0x00
i2cset -f -y 16 0x24 0x00 2
i2ctransfer -f -y 16 w3@0x24 0x1D 0x0A 0x06
//1.455V
i2cset -f -y 14 0x29 0x00 0
i2ctransfer -f -y 14 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x0D 0x51 0x1E
//1.455V
i2cset -f -y 14 0x29 0x00 1
i2ctransfer -f -y 14 w3@0x29 0x21 0xF2 0x00
i2cset -f -y 14 0x29 0x00 2
i2ctransfer -f -y 14 w3@0x29 0x1D 0x29 0x0F
//0.695V
i2cset -f -y 14 0x27 0x00 0
i2ctransfer -f -y 14 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 14 0x27 0x00 1
i2ctransfer -f -y 14 w3@0x27 0x21 0x5A 0x00
i2cset -f -y 14 0x27 0x00 2
i2ctransfer -f -y 14 w3@0x27 0x1D 0xAC 0x05
//0.695V
i2cset -f -y 16 0x28 0x00 0
i2ctransfer -f -y 16 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x0D 0x54 0x0B
//0.695V
i2cset -f -y 16 0x28 0x00 1
i2ctransfer -f -y 16 w3@0x28 0x21 0x5A 0x00
i2cset -f -y 16 0x28 0x00 2
i2ctransfer -f -y 16 w3@0x28 0x1D 0xAC 0x05
//0.753V
i2cset -f -y 14 0x20 0x00 0
i2ctransfer -f -y 14 w3@0x20 0x21 0x2D 0x01
+14 -29
View File
@@ -1,32 +1,17 @@
bcmcmd -n 0 -c '*:port all lb=mac'
bcmcmd -n 0 -c '*:l2 learn off'
bcmcmd -n 0 -c '*:dsh -c "test mode nr=yes"'
bcmcmd -n 0 -c '*:dsh -c "tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=2"'
//Start Unit0 Tr518
bcmcmd -n 0 -c 'port cd lb=mac'
bcmcmd -n 0 -c 'l2 learn off'
bcmcmd -n 0 -c 'dsh -c "test mode nr=yes"'
bcmcmd -n 0 -c 'dsh -c "tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=1"'
bcmcmd -n 1 -c "*:port all lb=mac"
bcmcmd -n 1 -c "*:l2 learn off"
bcmcmd -n 1 -c "*:dsh -c 'test mode nr=yes'"
bcmcmd -n 1 -c "*:dsh -c 'tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=2'"
//Stop Unit0 Tr518
bcmcmd -n 0 -c 'port cd lb=none'
//Start Unit1 Tr518
bcmcmd -n 1 -c 'port cd lb=mac'
bcmcmd -n 1 -c 'l2 learn off'
bcmcmd -n 1 -c 'dsh -c "test mode nr=yes"'
bcmcmd -n 1 -c 'dsh -c "tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=1"'
bcmcmd -n 0 -c "*:port all lb=mac"
sleep 1
bcmcmd -n 1 -c "*:port all lb=mac"
sleep 1
bcmcmd -n 0 -c "*:l2 learn off"
sleep 1
bcmcmd -n 1 -c "*:l2 learn off"
sleep 1
bcmcmd -n 0 -c "*:dsh -c 'test mode nr=yes'"
sleep 1
bcmcmd -n 1 -c "*:dsh -c 'test mode nr=yes'"
sleep 1
bcmcmd -n 0 -c "*:dsh -c 'tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=2'"
sleep 1
bcmcmd -n 1 -c "*:dsh -c 'tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=2'"
sleep 1
root@(none):/usr/local/bin# swutil *:l2 learn off
root@(none):/usr/local/bin# swutil *:dsh -c \"test mode nr=yes\"
root@(none):/usr/local/bin# swutil *:dsh -c \"tr 518 Scenario=6 Profile=2 Count=260 PktSize=324 PortList=1-259,270-565 rm=ext CheckLinkTime=20 CheckDataTime=200 testphase=2"
//Stop Unit1 Tr518
bcmcmd -n 1 -c 'port cd lb=none'