Unplugged-cable behavior fixed end to end: heat grid rolls on the slot boundary (view computes the newest slot from the draw clock; history sampled every frame so slots color within a frame; noise phase displayed as commanded straight from the shared clock — radiating and the per-slot vote deleted), SNR ghost panic disambiguated via the PMA 1.1 latch (link dropped mid-read discards the batch, ghost on a proven-up link still dies), measure skips the 25s relink wait when the ECD verdict says faulted and the header says MEASURING instead of GOOD while a diag runs, RollBall mailbox deadline resized to 10s from bench measurement (<25ms linked, ~220ms no-link, >3s during a live plug's training; docs/modules/wiitek updated)
This commit is contained in:
@@ -65,6 +65,16 @@ type noisePort struct {
|
||||
frame []byte
|
||||
}
|
||||
|
||||
// The cycle is a pure function of the shared slot clock: even slots up — ports
|
||||
// admin-up and the wire loud, training or frames — odd slots down. Everything
|
||||
// that shows the phase computes it from the clock through here rather than
|
||||
// sampling the actuator, whose ioctls lag the boundary.
|
||||
func slotUp(seq int64) bool { return seq%2 == 0 }
|
||||
|
||||
func noiseUp(now time.Time) bool {
|
||||
return slotUp(int64(now.Sub(rateEpochStart) / histSlotSpan))
|
||||
}
|
||||
|
||||
type noiser struct {
|
||||
eps [2]endpoint
|
||||
ports [2]noisePort
|
||||
@@ -73,8 +83,6 @@ type noiser struct {
|
||||
// phase. Latched across the down phase, where the missing carrier is our
|
||||
// own doing and says nothing about the cable.
|
||||
connected atomic.Bool
|
||||
// The cycle's up phase: ports admin-up and the wire loud, training or frames.
|
||||
radiating atomic.Bool
|
||||
}
|
||||
|
||||
func newNoiser() (*noiser, error) {
|
||||
@@ -124,9 +132,9 @@ type noiseView struct {
|
||||
|
||||
// missing is zero while the cable was there at the last verdict, one while it
|
||||
// was not: the shape the error cells already colour by, so absence paints as
|
||||
// the fault it is. on is the cycle's phase, presence granted.
|
||||
// the fault it is. on is the commanded phase, straight from the clock.
|
||||
func (n *noiser) view() noiseView {
|
||||
v := noiseView{on: n.radiating.Load()}
|
||||
v := noiseView{on: noiseUp(time.Now())}
|
||||
if !n.connected.Load() {
|
||||
v.missing = 1
|
||||
}
|
||||
@@ -188,7 +196,7 @@ func (n *noiser) run(done *atomic.Bool) {
|
||||
applied, wasUp, linked := false, false, false
|
||||
for !done.Load() {
|
||||
<-tick.C
|
||||
up := (time.Since(rateEpochStart)/histSlotSpan)%2 == 0
|
||||
up := noiseUp(time.Now())
|
||||
if !applied || up != wasUp {
|
||||
// A whole up phase with no link is many times the ~1s the wire
|
||||
// needs to train, so at its end the silence is the cable's answer.
|
||||
@@ -196,7 +204,6 @@ func (n *noiser) run(done *atomic.Bool) {
|
||||
n.connected.Store(linked)
|
||||
}
|
||||
n.setLinks(fd, up)
|
||||
n.radiating.Store(up)
|
||||
applied, wasUp, linked = true, up, false
|
||||
}
|
||||
if !up || !n.bothUp() {
|
||||
|
||||
Reference in New Issue
Block a user