Add runtime BMA456 tap config with NVS persistence and goTool UI.

Expose multitap parameters over UART/ESP-NOW (like deadzone), store per node in NVS, and allow get/set from CLI, REST, and the dashboard without poll-overwrite while editing.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
simon
2026-09-26 13:07:13 +02:00
co-authored by Cursor
parent f006f8b912
commit d7441cb85f
32 changed files with 1859 additions and 150 deletions
+52
View File
@@ -225,6 +225,27 @@ func (m *managedSerial) AccelDeadzonePoll(req *pb.AccelDeadzoneRequest) (*pb.Acc
return m.accelDeadzoneVia(m.withPortPoll, req)
}
func (m *managedSerial) TapConfig(req *pb.TapConfigRequest) (*pb.TapConfigResponse, error) {
return m.tapConfigVia(m.withPort, req)
}
func (m *managedSerial) TapConfigPoll(req *pb.TapConfigRequest) (*pb.TapConfigResponse, error) {
return m.tapConfigVia(m.withPortPoll, req)
}
func (m *managedSerial) tapConfigVia(
portFn func(func(*serialPort) error) error,
req *pb.TapConfigRequest,
) (*pb.TapConfigResponse, error) {
var resp *pb.TapConfigResponse
err := portFn(func(sp *serialPort) error {
var e error
resp, e = sp.TapConfig(req)
return e
})
return resp, err
}
func (m *managedSerial) accelDeadzoneVia(
portFn func(func(*serialPort) error) error,
req *pb.AccelDeadzoneRequest,
@@ -383,6 +404,33 @@ func (s *serialPort) accelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadz
return r, nil
}
func (s *serialPort) tapConfig(req *pb.TapConfigRequest) (*pb.TapConfigResponse, error) {
msg := &pb.UartMessage{
Type: pb.MessageType_TAP_CONFIG,
Payload: &pb.UartMessage_TapConfigRequest{
TapConfigRequest: req,
},
}
body, err := proto.Marshal(msg)
if err != nil {
return nil, fmt.Errorf("encode: %w", err)
}
payload := append([]byte{byte(pb.MessageType_TAP_CONFIG)}, body...)
respPayload, err := s.exchangePayload(payload, "TAP_CONFIG")
if err != nil {
return nil, err
}
var respMsg pb.UartMessage
if err := proto.Unmarshal(respPayload[1:], &respMsg); err != nil {
return nil, fmt.Errorf("decode: %w", err)
}
r := respMsg.GetTapConfigResponse()
if r == nil {
return nil, fmt.Errorf("missing tap_config_response")
}
return r, nil
}
func (s *serialPort) espnowUnicastTest(clientID, seq uint32) (*pb.EspNowUnicastTestResponse, error) {
req := &pb.EspNowUnicastTestRequest{ClientId: clientID, Seq: seq}
msg := &pb.UartMessage{
@@ -557,6 +605,10 @@ func (s *serialPort) AccelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadz
return s.accelDeadzone(req)
}
func (s *serialPort) TapConfig(req *pb.TapConfigRequest) (*pb.TapConfigResponse, error) {
return s.tapConfig(req)
}
func (s *serialPort) EspnowUnicastTest(clientID, seq uint32) (*pb.EspNowUnicastTestResponse, error) {
return s.espnowUnicastTest(clientID, seq)
}