Capability 005: Forward Motor State¶
Status: Accepted
Context¶
Each Motor Controller Board reports its state over UART: persistent conditions such as a motor error or a battery alert, and events such as power-on or an imminent shutdown. It sends the state whenever it changes and in reply to a Status Query (capability 001). The Bridge forwards it on the CAN bus, per Motor, as it forwards the Motor Status (capability 003, Decision 1).
References¶
- CAN messages:
drive.dbc - UART protocol, frame
Serial_Feedback_State: hoverboard-firmware v1.0.0,command_api.md - CAN identifiers: ADR-001
Mapping¶
| Board frame | CAN messages |
|---|---|
| Board 1 state | Motor 1 state from the left bits, motor 2 state from the right bits |
| Board 2 state | Motor 3 state from the left bits; the right bits are dropped |
Each Motor State keeps the 32-bit layout of the board state (state_lo in bits 0–15, state_hi in bits 16–31):
- Bit 0 (motor error) and bit 7 (motor enabled) belong to the Motor itself. For the left output they are taken as they are; for the right output from bits 1 and 8.
- Bits 1 and 8 are reserved and sent as zero.
- All other bits concern the whole board and are passed on unchanged.
Functional Requirements¶
- The Bridge recognizes a state frame by its start marker and a valid checksum.
- It translates each state frame into the Motor State messages as mapped.
- It forwards every state frame, so each event of a board reaches the CAN bus once per Motor.
- It passes the board-wide bits on unchanged, including reserved ones.
Non-Functional Requirements¶
- At most 10 ms from the complete reception of a state frame to the start of the CAN transmission.
- Load: state frames arrive on changes and in reply to a Status Query only, a few per second at most.
Error Handling¶
As for the Motor Status (capability 003, Error Handling); a full transmit queue discards the new Motor State.
Solution Constraints¶
As for the Motor Status (capability 003, Solution Constraints).
Out of Scope¶
- Interpreting the state, for example stopping the Drive on an error: the Superordinate Controller decides
- Querying the state on its own initiative: only the Superordinate Controller sends a Status Query
- The right output of board 2: no Motor is connected to it
Acceptance Criteria¶
- Board 1 state (right motor error, left motor enabled, temperature warning): Motor State of motor 1 with motor enabled and temperature warning, of motor 2 with motor error and temperature warning.
- Board 2 state (left motor error, both outputs enabled, power-on event): Motor State of motor 3 with motor error, motor enabled, and power-on; the right output is dropped.
- State frame with an invalid checksum: no CAN message; the discarded frame is reported over USB serial.
- Under the load of NFR 2: at most 10 ms delay.
Test vectors for criteria 1 and 2, in hexadecimal bytes as they appear on the wire:
| Criterion | Board (UART) | CAN (identifier: payload) |
|---|---|---|
| 1 | 1: c0 ab 92 00 00 00 52 ab |
04210005: 90 00 00 00, 04220005: 11 00 00 00 |
| 2 | 2: c0 ab 81 01 01 00 40 aa |
04230005: 81 00 01 00 |
Decisions¶
- One Motor State per Motor, as for the Motor Status (capability 003, Decision 1). The left and right bits of a board are therefore split across its Motors; the board-wide bits appear in each.
- The Motor State keeps the bit layout of the board state instead of a layout of its own,
because the translation then stays a copy plus one shift, and the board documentation explains every bit.
Consequence: bits 1 and 8 stay unused in
drive.dbc. Passing the board state on unchanged would be simpler still, but the Superordinate Controller would then have to know which output of which board drives a Motor. - Motor State is event-driven, without cycle time or receive timeout: priority class 1 (event-driven state changes), subsystem 1, instance = Motor, message number 5.
- A full transmit queue discards the new message, as for the Motor Status (capability 003, Decision 4). Consequence: an event, for example an imminent shutdown, can be lost while the bus is blocked. The persistent bits can be read again with a Status Query; lost events cannot.