|
| 1 | +# UART Command Handling System Documentation |
| 2 | + |
| 3 | +This document describes the UART command/packet handling system used by the firmware. It is intended to help future developers understand how commands are framed, parsed, dispatched, and responded to. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## High-Level Overview |
| 8 | + |
| 9 | +The firmware communicates over UART using a framed packet protocol. Each packet represents a **command**, **response**, **data transfer**, or **error condition**. Incoming packets are parsed into a `UartPacket` structure and passed into the command handler (`process_if_command`). The handler inspects the packet type and command code, executes the requested operation, and populates a response packet. |
| 10 | + |
| 11 | +At a high level: |
| 12 | + |
| 13 | +1. Bytes are received over UART |
| 14 | +2. A packet parser validates framing and CRC |
| 15 | +3. The parsed packet is represented as a `UartPacket` |
| 16 | +4. `process_if_command()` dispatches based on packet type and command |
| 17 | +5. A response packet is constructed and transmitted |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## Packet Format |
| 22 | + |
| 23 | +All UART traffic uses the following packet structure: |
| 24 | + |
| 25 | +``` |
| 26 | +| Start | ID | Type | Command | Addr | Reserved | Length | Payload | CRC16 | End | |
| 27 | +``` |
| 28 | + |
| 29 | +### Field Definitions |
| 30 | + |
| 31 | +| Field | Size | Description | |
| 32 | +| -------- | ------- | --------------------------------------------------------------- | |
| 33 | +| Start | 1 byte | Start-of-packet marker (`0xAA`) | |
| 34 | +| ID | 2 bytes | Transaction identifier used to correlate requests and responses | |
| 35 | +| Type | 1 byte | Packet type (command, response, data, error, etc.) | |
| 36 | +| Command | 1 byte | Command opcode | |
| 37 | +| Addr | 1 byte | Address or sub-target (device, channel, register, etc.) | |
| 38 | +| Reserved | 1 byte | Reserved for future use (must be zero) | |
| 39 | +| Length | 2 bytes | Length of payload in bytes | |
| 40 | +| Payload | N bytes | Command-specific data (0–2048 bytes) | |
| 41 | +| CRC16 | 2 bytes | CRC16 of header + payload | |
| 42 | +| End | 1 byte | End-of-packet marker (`0xDD`) | |
| 43 | + |
| 44 | +Maximum payload size is defined by `COMMAND_MAX_SIZE` (2048 bytes). |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +## Core Data Structures |
| 49 | + |
| 50 | +### `UartPacket` |
| 51 | + |
| 52 | +All parsed packets are represented using the `UartPacket` structure: |
| 53 | + |
| 54 | +* `id`: Transaction ID |
| 55 | +* `packet_type`: One of `OWPacketTypes` |
| 56 | +* `command`: Command opcode |
| 57 | +* `addr`: Address or selector byte |
| 58 | +* `reserved`: Reserved, should be zero |
| 59 | +* `data_len`: Payload length |
| 60 | +* `data`: Pointer to payload buffer |
| 61 | +* `crc`: CRC16 value from the packet |
| 62 | + |
| 63 | +This structure is used for both incoming commands and outgoing responses. |
| 64 | + |
| 65 | +--- |
| 66 | + |
| 67 | +## Packet Types (`OWPacketTypes`) |
| 68 | + |
| 69 | +Packet types define *how* a packet should be interpreted: |
| 70 | + |
| 71 | +| Type | Meaning | |
| 72 | +| ----------------- | ---------------------------------- | |
| 73 | +| `OW_CMD` | Incoming command from host | |
| 74 | +| `OW_RESP` | Command response | |
| 75 | +| `OW_DATA` | Raw binary data transfer | |
| 76 | +| `OW_JSON` | JSON-encoded data | |
| 77 | +| `OW_ACK` | Acknowledgement (success) | |
| 78 | +| `OW_NAK` | Negative acknowledgement | |
| 79 | +| `OW_BAD_PARSE` | Packet framing or format error | |
| 80 | +| `OW_BAD_CRC` | CRC mismatch | |
| 81 | +| `OW_UNKNOWN` | Unknown command or type | |
| 82 | +| `OW_ERROR` | General error response | |
| 83 | +| `OW_I2C_PASSTHRU` | I2C passthrough operation | |
| 84 | +| `OW_CONTROLLER` | Motion/controller-specific command | |
| 85 | + |
| 86 | +The `packet_type` is always evaluated first in the command handler. |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +## Command Namespaces |
| 91 | + |
| 92 | +Commands are grouped into logical namespaces based on the packet type and command value. |
| 93 | + |
| 94 | +### Global Commands (`OWGlobalCommands`) |
| 95 | + |
| 96 | +These commands apply to the device as a whole and are typically sent using `OW_CMD`: |
| 97 | + |
| 98 | +| Command | Description | |
| 99 | +| ------------------- | --------------------------- | |
| 100 | +| `OW_CMD_PING` | Connectivity check | |
| 101 | +| `OW_CMD_PONG` | Ping response | |
| 102 | +| `OW_CMD_VERSION` | Firmware version query | |
| 103 | +| `OW_CMD_ECHO` | Echo payload back to sender | |
| 104 | +| `OW_CMD_TOGGLE_LED` | Toggle status LED | |
| 105 | +| `OW_CMD_HWID` | Hardware ID query | |
| 106 | +| `OW_CMD_DFU` | Enter DFU/bootloader mode | |
| 107 | +| `OW_CMD_NOP` | No operation | |
| 108 | +| `OW_CMD_RESET` | Software reset | |
| 109 | + |
| 110 | +These commands usually generate an `OW_RESP` or `OW_ACK` packet. |
| 111 | + |
| 112 | +--- |
| 113 | + |
| 114 | +### Motion / Controller Commands (`MotionControllerCommands`) |
| 115 | + |
| 116 | +These commands are used when `packet_type == OW_CONTROLLER` and target the motion controller or peripherals: |
| 117 | + |
| 118 | +Examples include: |
| 119 | + |
| 120 | +| Command | Description | |
| 121 | +| -------------------- | --------------------------------------- | |
| 122 | +| `OW_CTRL_I2C_SCAN` | Scan I2C bus for connected devices | |
| 123 | +| `OW_CTRL_SET_IND` | Set indicator (LED) state | |
| 124 | +| `OW_CTRL_GET_IND` | Get indicator (LED) state | |
| 125 | +| `OW_CTRL_SET_TRIG` | Configure trigger parameters | |
| 126 | +| `OW_CTRL_GET_TRIG` | Read current trigger configuration | |
| 127 | +| `OW_CTRL_START_TRIG` | Start/arm trigger operation | |
| 128 | +| `OW_CTRL_STOP_TRIG` | Stop/disarm trigger operation | |
| 129 | +| `OW_CTRL_SET_FAN` | Set fan speed or enable state | |
| 130 | +| `OW_CTRL_GET_FAN` | Get fan speed and status | |
| 131 | +| `OW_CTRL_I2C_RD` | Perform I2C read transaction | |
| 132 | +| `OW_CTRL_I2C_WR` | Perform I2C write transaction | |
| 133 | +| `OW_CTRL_GET_FSYNC` | Read frame sync (FSYNC) status | |
| 134 | +| `OW_CTRL_GET_LSYNC` | Read line sync (LSYNC) status | |
| 135 | +| `OW_CTRL_TEC_DAC` | Set TEC control DAC output | |
| 136 | +| `OW_CTRL_READ_ADC` | Read ADC channel value | |
| 137 | +| `OW_CTRL_READ_GPIO` | Read GPIO pin state | |
| 138 | +| `OW_CTRL_GET_TEMPS` | Read temperature sensor values | |
| 139 | +| `OW_CTRL_TECADC` | Read TEC-related ADC measurements | |
| 140 | +| `OW_CTRL_TEC_STATUS` | Read TEC controller status and faults | |
| 141 | +| `OW_CTRL_BOARDID` | Read board identification information | |
| 142 | +| `OW_CTRL_PDUMON` | Read power distribution monitoring data | |
| 143 | + |
| 144 | +Each command defines its own payload format and response payload. |
| 145 | + |
| 146 | +--- |
| 147 | + |
| 148 | +## Error Codes (`OWErrorCodes`) |
| 149 | + |
| 150 | +Error codes are returned in response payloads or error packets: |
| 151 | + |
| 152 | +| Code | Meaning | |
| 153 | +| --------------------- | -------------------------------- | |
| 154 | +| `OW_CODE_SUCCESS` | Operation completed successfully | |
| 155 | +| `OW_CODE_IDENT_ERROR` | Invalid ID or addressing | |
| 156 | +| `OW_CODE_DATA_ERROR` | Invalid or malformed payload | |
| 157 | +| `OW_CODE_ERROR` | General failure | |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +## Command Handling Flow |
| 162 | + |
| 163 | +The central entry point for command processing is: |
| 164 | + |
| 165 | +``` |
| 166 | +_Bool process_if_command(UartPacket *uartResp, UartPacket *cmd); |
| 167 | +``` |
| 168 | + |
| 169 | +### Responsibilities |
| 170 | + |
| 171 | +* Validate the incoming packet type |
| 172 | +* Dispatch based on `packet_type` and `command` |
| 173 | +* Execute the requested operation |
| 174 | +* Populate `uartResp` with: |
| 175 | + |
| 176 | + * Matching transaction ID |
| 177 | + * Appropriate response packet type |
| 178 | + * Response payload and length |
| 179 | + * Error codes if applicable |
| 180 | + |
| 181 | +The function returns: |
| 182 | + |
| 183 | +* `true` if the command was recognized and handled |
| 184 | +* `false` if the command was unsupported or invalid |
| 185 | + |
| 186 | +--- |
| 187 | + |
| 188 | +## Typical Command Lifecycle |
| 189 | + |
| 190 | +1. **Receive**: Host sends `OW_CMD` or `OW_CONTROLLER` packet |
| 191 | +2. **Parse**: Firmware validates framing and CRC |
| 192 | +3. **Dispatch**: `process_if_command()` routes the command |
| 193 | +4. **Execute**: Hardware or firmware operation is performed |
| 194 | +5. **Respond**: Firmware sends `OW_RESP`, `OW_ACK`, `OW_DATA`, or `OW_ERROR` |
| 195 | + |
| 196 | +The response packet: |
| 197 | + |
| 198 | +* Reuses the incoming `id` |
| 199 | +* Indicates success or failure via packet type and payload |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +## Adding a New Command |
| 204 | + |
| 205 | +To add a new command: |
| 206 | + |
| 207 | +1. Add a new enum value in the appropriate command enum |
| 208 | +2. Define the payload format (document it!) |
| 209 | +3. Add a case in `process_if_command()` |
| 210 | +4. Validate `data_len` and payload contents |
| 211 | +5. Populate the response packet |
| 212 | +6. Return `true` on success |
| 213 | + |
| 214 | +Always: |
| 215 | + |
| 216 | +* Check payload length |
| 217 | +* Avoid blocking operations |
| 218 | +* Return meaningful error codes |
| 219 | + |
| 220 | +--- |
| 221 | + |
| 222 | +## Design Notes & Best Practices |
| 223 | + |
| 224 | +* **Transaction IDs** must be preserved across responses |
| 225 | +* **CRC failures** should generate `OW_BAD_CRC` |
| 226 | +* **Unknown commands** should generate `OW_UNKNOWN` |
| 227 | +* Reserved fields must remain zero for forward compatibility |
| 228 | +* Payloads should be endian-safe when possible |
| 229 | + |
| 230 | +--- |
| 231 | + |
| 232 | +## Summary |
| 233 | + |
| 234 | +This command handling system provides a structured, extensible UART protocol with: |
| 235 | + |
| 236 | +* Clear packet framing |
| 237 | +* Strong error detection |
| 238 | +* Namespaced command sets |
| 239 | +* Transaction-safe request/response handling |
| 240 | + |
| 241 | +Understanding this flow is essential before modifying or extending the firmware command interface. |
0 commit comments