aboutsummaryrefslogtreecommitdiffstats
path: root/sw/cal/table.go
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2025-11-08 19:44:36 -0500
committerSam Anthony <sam@samanthony.xyz>2025-11-08 19:44:36 -0500
commit4d4024312dad007a72844cc82d5fa550b12f050b (patch)
tree319169bda4564d33fd37414f832a8620a7cac499 /sw/cal/table.go
parentc6573ad10a8d96d744324937195cd50bb1442c26 (diff)
downloadcan-gauge-interface-4d4024312dad007a72844cc82d5fa550b12f050b.zip
cal: verify table after writing
Diffstat (limited to 'sw/cal/table.go')
-rw-r--r--sw/cal/table.go93
1 files changed, 80 insertions, 13 deletions
diff --git a/sw/cal/table.go b/sw/cal/table.go
index 610448a..7d63d8d 100644
--- a/sw/cal/table.go
+++ b/sw/cal/table.go
@@ -6,7 +6,6 @@ import (
bin "encoding/binary"
"fmt"
"slices"
- "time"
"go.einride.tech/can"
@@ -14,8 +13,10 @@ import (
)
const (
- tblCtrlId uint32 = 0x1272000
- maxTabRows = 32
+ tblCtrlId uint32 = 0x1272000
+ tblCtrlMask uint32 = 0x1FFFF00
+
+ maxTabRows = 32
)
type Table struct {
@@ -54,7 +55,6 @@ func (tbl Table) Send(bus canbus.Bus) error {
if err := sendRow(tbl.sigIndex, uint8(i), tbl.rows[i], bus); err != nil {
return err
}
- time.Sleep(eepromWriteDelay)
}
// Fill rest of table with last row
@@ -63,7 +63,6 @@ func (tbl Table) Send(bus canbus.Bus) error {
if err := sendRow(tbl.sigIndex, uint8(i), lastRow, bus); err != nil {
return err
}
- time.Sleep(eepromWriteDelay)
}
return nil
@@ -71,22 +70,90 @@ func (tbl Table) Send(bus canbus.Bus) error {
// Transmit a Table Control frame containing one row of a table.
func sendRow(sigIndex, rowIndex uint8, row Row, bus canbus.Bus) error {
- // Serialize DATA FIELD
+ frame, err := marshalTblCtrlFrame(sigIndex, rowIndex, row)
+ if err != nil {
+ return err
+ }
+
+ var retry int
+ for retry = 0; retry < maxRetries; retry++ {
+ // Write to EEPROM
+ ctx, _ := context.WithTimeout(context.Background(), timeout)
+ if err := bus.Send(ctx, frame); err != nil {
+ return err
+ }
+
+ // Read back
+ request := tblCtrlRequest(sigIndex, rowIndex)
+ ctx, _ = context.WithTimeout(context.Background(), timeout)
+ if err := bus.Send(ctx, request); err != nil {
+ return err
+ }
+ ctx, _ = context.WithTimeout(context.Background(), timeout)
+ reply, err := bus.Receive(ctx)
+ if err != nil {
+ return err
+ }
+ rRow, rSigIndex, rRowIndex, err := unmarshalTblCtrlFrame(reply)
+ if err == errWrongId || rSigIndex != sigIndex || rRowIndex != rowIndex {
+ continue
+ } else if err != nil {
+ return err
+ }
+
+ // Verify
+ if rRow == row {
+ fmt.Printf("Table %d row %d OK\n", sigIndex, rowIndex)
+ return nil // success
+ } else {
+ weprintf("Warning: table %d row %d verification failed; rewriting...\n", sigIndex, rowIndex)
+ continue
+ }
+ }
+ // Max retries exceeded
+ return fmt.Errorf("table %d row %d verification failed", sigIndex, rowIndex)
+}
+
+func marshalTblCtrlFrame(sigIndex, rowIndex uint8, row Row) (can.Frame, error) {
var data [8]byte
if _, err := bin.Encode(data[0:4], bin.BigEndian, row.key); err != nil {
- return err
+ return can.Frame{}, err
}
if _, err := bin.Encode(data[4:6], bin.BigEndian, row.val); err != nil {
- return err
+ return can.Frame{}, err
}
-
- // Construct ID and send frame
- frame := can.Frame{
+ return can.Frame{
ID: uint32(tblCtrlId) | uint32((sigIndex<<5)&0xE0) | uint32(rowIndex&0x1F),
Length: 6,
Data: data,
IsExtended: true,
+ }, nil
+}
+
+func unmarshalTblCtrlFrame(frame can.Frame) (row Row, sigIndex, rowIndex uint8, err error) {
+ if !frame.IsExtended || frame.ID&tblCtrlMask != tblCtrlId {
+ err = errWrongId
+ return
+ }
+ if frame.Length != 6 {
+ err = fmt.Errorf("Table Control frame has wrong DLC: %d", frame.Length)
+ return
+ }
+ sigIndex = uint8((frame.ID & 0xE0) >> 5)
+ rowIndex = uint8(frame.ID & 0x1F)
+ _, err = bin.Decode(frame.Data[0:4], bin.BigEndian, &row.key)
+ if err != nil {
+ return
+ }
+ _, err = bin.Decode(frame.Data[4:6], bin.BigEndian, &row.val)
+ return
+}
+
+// Construct a Table Control REMOTE REQUEST frame.
+func tblCtrlRequest(sigIndex, rowIndex uint8) can.Frame {
+ return can.Frame{
+ ID: tblCtrlId | uint32((sigIndex<<5)&0xE0) | uint32(rowIndex&0x1F),
+ IsRemote: true,
+ IsExtended: true,
}
- ctx, _ := context.WithTimeout(context.Background(), timeout)
- return bus.Send(ctx, frame)
}