refactor(motor-control): single source of truth for the MCP command numbers - #766
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
The change is a low-risk refactor that centralizes command constants without altering computed indices/values, and the dependency/include updates appear consistent.
Pull request overview
This PR refactors the MCP236/266 motor-control stack to make the Basicmicro/MCP command-number mapping a single source of truth, shared across the packet-serial (basicmicro) and CANopen (mcp266) transports via the motor_controller component.
Changes:
- Introduces a shared
espp::detail::BasicmicroCommandenum inmotor_controllerand updates both transport cores to include it. - Updates
mcp266to derive manufacturer object indices from named commands (command_object(BasicmicroCommand::...)) instead of hardcoded magic numbers. - Updates docs and host-test build instructions to reflect the shared header location.
File summaries
| File | Description |
|---|---|
| doc/en/motor_control/motor_controller.rst | Documents the shared BasicmicroCommand table and why mcp266 derives object indices from it. |
| doc/Doxyfile | Adds the new shared header to Doxygen INPUT so it appears in generated docs. |
| components/motor_controller/include/basicmicro_commands.hpp | New shared command-number enum (BasicmicroCommand) serving as the single source of truth. |
| components/mcp266/test/mcp266_host_test.cpp | Updates host-build instructions to include the motor_controller include path. |
| components/mcp266/include/detail/mcp266_core.hpp | Switches manufacturer-object constants to use BasicmicroCommand and adds an overload command_object(BasicmicroCommand). |
| components/basicmicro/test/basicmicro_host_test.cpp | Updates host-build instructions to include the motor_controller include path. |
| components/basicmicro/include/detail/basicmicro_core.hpp | Removes the local BasicmicroCommand definition in favor of the shared header. |
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…umbers The mcp266 CANopen driver mirrors the Basicmicro packet-serial command set into its manufacturer object dictionary at 0x2000 + command number, but it hardcoded those command numbers (24, 82, 200, 61-64, 32/33/35/36) as magic values that had to be kept in lockstep with basicmicro's BasicmicroCommand enum by hand. Move the BasicmicroCommand table into the shared motor_controller component (basicmicro_commands.hpp) -- which both drivers already depend on, so neither sibling depends on the other -- and derive the manufacturer object indices from the named enum values via a command_object(BasicmicroCommand) overload. The numbers now live in exactly one place and cannot drift. No value changes: both host cores test-verify the same concrete addresses (e.g. ReadMainBatteryVoltage -> 0x2018). basicmicro_core keeps its packet codecs / CRC / BasicmicroStatus (transport-specific, not shared). Verified: basicmicro + mcp266 host tests pass; both examples build on IDF v6.0.1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
aa92cba to
a15bf74
Compare
|
✅Static analysis result - no issues found! ✅ |
There was a problem hiding this comment.
🟡 Changes recommended
The component README must document the newly shared command table.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Balanced
| The component also holds :cpp:enum:`espp::detail::BasicmicroCommand` | ||
| (``basicmicro_commands.hpp``) — the packet-serial command-number table. Both |
Single source of truth for the MCP236/266 command numbers
Stacked on #764 (needs the
motor_controllercomponent). Rebases ontomainonce #764 merges.Follow-up to the design discussion on whether
basicmicro(packet serial) andmcp266(CANopen) could be unified: the right answer is the
MotorControllerconcept for theAPI, not a merged component — but the one thing genuinely worth de-duplicating is the
command-number table, and this PR does that.
The drift risk
The MCP266's CANopen firmware mirrors the Basicmicro packet-serial command set into its
manufacturer object dictionary at
0x2000 + command. So "read main battery voltage" iscommand
24on serial and object0x2018on CAN — the same24. Butmcp266_core.hpphardcoded those numbers as magic values (
command_object(24),(82),(200),(61/62/63/64),(32/33/35/36)) that had to be hand-kept in lockstep withbasicmicro'sBasicmicroCommandenum. Nothing stopped them drifting.The change
BasicmicroCommandtable into the sharedmotor_controllercomponent(
basicmicro_commands.hpp). Both drivers already depend on that component, so this addsno dependency between the two sibling drivers and no new component.
basicmicro_core.hppincludes it (keeps its packet codecs / CRC /BasicmicroStatus—those are transport-specific and not shared).
mcp266_core.hppderives every manufacturer object from the named enum via a newcommand_object(BasicmicroCommand)overload, e.g.command_object(BasicmicroCommand::ReadMainBatteryVoltage)instead ofcommand_object(24).The numbers now live in exactly one place.
No behavior change
Pure relocation + indirection — no object address or command byte changes. Both
host-buildable cores test-verify the same concrete values (the mcp266 test still asserts
0x2018etc.).Verified
basicmicro+mcp266host tests pass (rebuilt with the added-I../../motor_controller/includefor the shared header; their build instructions areupdated accordingly — these are dev tests, not CI-gated).
Note: this is the DRY win, not a merge. The transports stay separate components (different
wire protocols, byte order, and control models — CiA 402 state machine vs direct commands);
they share the interface (
MotorController) and now the command-number table, which isall they genuinely have in common.
🤖 Generated with Claude Code