Skip to content

Commit 4b21ec6

Browse files
committed
Document inter-module CAN protocol
1 parent 18f3fd1 commit 4b21ec6

4 files changed

Lines changed: 193 additions & 2 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ This output is included in the Next.js static export so that the website and the
8686
| [`docs/source/build/safety.md`](./docs/source/build/safety.md) | Safety notes |
8787
| [`docs/source/hardware/index.md`](./docs/source/hardware/index.md) | Hardware and module overview |
8888
| [`docs/source/hardware/pcbs.md`](./docs/source/hardware/pcbs.md) | PCB documentation |
89-
| [`docs/source/software/index.md`](./docs/source/software/index.md) | Software, GUI, and data workflow notes |
89+
| [`docs/source/software/index.md`](./docs/source/software/index.md) | Software and firmware documentation |
90+
| [`docs/source/software/firmware/index.md`](./docs/source/software/firmware/index.md) | Firmware documentation index |
91+
| [`docs/source/software/firmware/can-intermodule-protocol.md`](./docs/source/software/firmware/can-intermodule-protocol.md) | Inter-module CAN bus protocol |
9092
| [`docs/source/protocols/index.md`](./docs/source/protocols/index.md) | Protocol templates and validation status |
9193
| [`docs/source/contributing.md`](./docs/source/contributing.md) | Contribution guidelines |
9294

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# BEATBox inter-module CAN protocol
2+
3+
This document is the firmware reference for the BEATBox CAN protocol exchanged between the main controller and peripheral modules.
4+
5+
```{warning}
6+
This protocol is under active development and may change as the firmware evolves. Check the revision history before updating or integrating firmware.
7+
```
8+
9+
## 1) Identifier layout (11-bit standard CAN)
10+
11+
BEATBox uses standard 11-bit CAN IDs.
12+
13+
### 1.1 Field ordering (MSB -> LSB)
14+
15+
| Bits | Size | Field | Meaning |
16+
|-------|------|--------|---------|
17+
| 10..8 | 3 | PRIO | Arbitration priority class (`0` highest) |
18+
| 7..4 | 4 | MODULE | Target module for request, source module for response |
19+
| 3..2 | 2 | TYPE | Message class and direction |
20+
| 1..0 | 2 | CMD | Command index inside the selected TYPE namespace |
21+
22+
Once a module is selected by `MODULE`, the message meaning is described by 3 protocol fields: `PRIO`, `TYPE`, `CMD` (plus payload).
23+
24+
Payload is 0..8 bytes. RTR is not used.
25+
26+
### 1.2 Encoding formula
27+
28+
`CAN_ID = (PRIO << 8) | (MODULE << 4) | (TYPE << 2) | CMD`
29+
30+
## 2) Global dictionaries
31+
32+
### 2.1 Priority classes (`PRIO`)
33+
34+
| PRIO | Class | Typical usage |
35+
|------|---------------|---------------|
36+
| 000 | P0 highest | Critical errors, safety urgent |
37+
| 001 | P1 high | Control commands (start/stop/reset/reward) |
38+
| 010 | P2 medium | Real-time events (nosepoke, touch, barrier edge) |
39+
| 011 | P3 normal | Status and ACK traffic |
40+
| 100 | P4 background | Telemetry / periodic reporting |
41+
| 101..111 | Reserved | Future use |
42+
43+
### 2.2 Type classes (`TYPE`)
44+
45+
| TYPE | Meaning |
46+
|------|---------|
47+
| 00 | Common request |
48+
| 01 | Common response |
49+
| 10 | Module-specific request |
50+
| 11 | Module-specific response |
51+
52+
### 2.3 Module IDs (`MODULE`)
53+
54+
| Module | Value |
55+
|-------------------|-------|
56+
| MAIN | 0x1 |
57+
| FEEDER | 0x2 |
58+
| NOSEPOKE | 0x3 |
59+
| SCREEN_LEFT | 0x4 |
60+
| SCREEN_RIGHT | 0x5 |
61+
| LIGHTING | 0x6 |
62+
| IR_BARRIER | 0x7 |
63+
| BROADCAST target | 0xF |
64+
65+
No response may use `MODULE=0xF`.
66+
67+
## 3) Common namespace (`TYPE=00` / `TYPE=01`)
68+
69+
`CMD` values are global in this namespace.
70+
71+
| TYPE | CMD | Name | Direction | Default PRIO | Payload |
72+
|------|-----|------------|-----------|--------------|---------|
73+
| 00 | 00 | SCAN | Request | P3 | none |
74+
| 01 | 00 | SCAN_REPLY | Response | P3 | `status_code:uint8` |
75+
| 00 | 01 | GET_STATUS | Request | P3 | none |
76+
| 01 | 01 | STATUS | Response | P3 | `status_code:uint8` |
77+
| 01 | 10 | ERROR | Response | P0 | `error_code:uint8` |
78+
| 00 | 11 | RESET | Request | P1 | `delay_ms:uint16` big-endian |
79+
80+
Status values:
81+
- `0`: INIT
82+
- `1`: IDLE
83+
- `2`: ACTIVE
84+
- `3`: ERROR
85+
86+
## 4) Module-specific namespace (`TYPE=10` / `TYPE=11`)
87+
88+
`CMD` is module-local in this namespace.
89+
90+
### 4.1 Feeder (`MODULE=0x2`)
91+
92+
| TYPE | CMD | Name | Direction | Default PRIO | Payload |
93+
|------|-----|------------------|-----------|--------------|---------|
94+
| 10 | 01 | REQUEST_REWARD | Request | P1 | none |
95+
| 11 | 01 | REWARD_DELIVERED | Response | P3 | none |
96+
97+
### 4.2 Nosepoke (`MODULE=0x3`)
98+
99+
| TYPE | CMD | Name | Direction | Default PRIO | Payload |
100+
|------|-----|-----------------|-----------|--------------|---------|
101+
| 10 | 00 | GET_BEAM_STATUS | Request | P3 | none |
102+
| 11 | 00 | BEAM_STATUS | Response | P3 | `beam:uint8` (`0` clear, `1` broken) |
103+
| 11 | 01 | BEAM_EVENT | Response | P2 | `beam:uint8` (`1` when poke event detected) |
104+
105+
### 4.3 Screen left/right (`MODULE=0x4` / `0x5`)
106+
107+
Screen side is encoded by module ID, so payload has no side field.
108+
109+
| TYPE | CMD | Name | Direction | Default PRIO | Payload |
110+
|------|-----|---------------------|-----------|--------------|---------|
111+
| 10 | 00 | DISPLAY_PATTERN | Request | P1 | `pattern_id:uint8` |
112+
| 11 | 00 | DISPLAY_PATTERN_ACK | Response | P3 | `pattern_id:uint8` |
113+
| 11 | 01 | TOUCH_EVENT | Response | P2 | `touch:uint8` (`1` touched) |
114+
115+
### 4.4 Lighting (`MODULE=0x6`)
116+
117+
| TYPE | CMD | Name | Direction | Default PRIO | Payload |
118+
|------|-----|----------------|-----------|--------------|---------|
119+
| 10 | 00 | SET_DUTY | Request | P1 | `white:uint8, red:uint8, ir:uint8` |
120+
| 11 | 00 | SET_DUTY_ACK | Response | P3 | `white:uint8, red:uint8, ir:uint8` |
121+
| 10 | 01 | GET_DUTY | Request | P3 | none |
122+
| 11 | 01 | DUTY_STATUS | Response | P3 | `white:uint8, red:uint8, ir:uint8` |
123+
| 10 | 10 | TURN_ON_GROUP | Request | P1 | `group:uint8` (`0` IR, `1` RED, `2` WHITE) |
124+
| 10 | 11 | TURN_OFF | Request | P1 | optional `group:uint8` (empty = all) |
125+
126+
### 4.5 IR barrier (`MODULE=0x7`)
127+
128+
| TYPE | CMD | Name | Direction | Default PRIO | Payload |
129+
|------|-----|--------------------|-----------|--------------|---------|
130+
| 10 | 00 | GET_BARRIER_STATUS | Request | P3 | none |
131+
| 11 | 00 | BARRIER_STATUS | Response | P3 | `barrier:uint8` (`0` clear, `1` blocked) |
132+
| 11 | 01 | BARRIER_EVENT | Response | P2 | `barrier:uint8` (`1` on edge event) |
133+
134+
## 5) Arbitration behavior
135+
136+
With `PRIO` in the top bits, arbitration follows functional urgency before module identity:
137+
138+
1. lower `PRIO` wins first,
139+
2. then lower `MODULE`,
140+
3. then lower `TYPE`,
141+
4. then lower `CMD`.
142+
143+
This avoids permanent dominance by low module IDs and matches the target policy: `error > control > event > status/telemetry`.
144+
145+
## 6) Worked examples
146+
147+
- Broadcast scan request (`P3`, `BROADCAST`, common request, `SCAN`):
148+
- bits: `011 1111 00 00`
149+
- Nosepoke event (`P2`, `NOSEPOKE`, module response, `BEAM_EVENT`):
150+
- bits: `010 0011 11 01`
151+
- Lighting set duty (`P1`, `LIGHTING`, module request, `SET_DUTY`):
152+
- bits: `001 0110 10 00`
153+
154+
## 7) Capacity note
155+
156+
This layout provides `2` command bits (`CMD=0..3`) per TYPE namespace.
157+
If a module later needs more than 4 module-specific operations, use either:
158+
159+
- one `CMD` value as a payload sub-opcode container, or
160+
- a protocol v2 based on 29-bit IDs.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Firmware
2+
3+
This section documents the embedded firmware interfaces used by BEATBox controllers and peripheral modules.
4+
5+
```{toctree}
6+
:maxdepth: 2
7+
8+
can-intermodule-protocol
9+
```
10+
11+
## Reference documentation
12+
13+
- {doc}`can-intermodule-protocol`: CAN identifiers, message classes, module IDs, commands, payloads, and arbitration behavior.
14+
15+
## Firmware resources
16+
17+
[Browse firmware and embedded-control resources](https://github.com/Open-BeatBox/Open-BeatBox.github.io/tree/main/resources/firmware)

‎docs/source/software/index.md‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
This section will document the BEATBox software and firmware stack.
44

5+
```{toctree}
6+
:maxdepth: 2
7+
8+
firmware/index
9+
```
10+
11+
## Available documentation
12+
13+
- {doc}`firmware/index`: embedded firmware documentation.
14+
- {doc}`firmware/can-intermodule-protocol`: CAN bus protocol used between the main controller and peripheral modules.
15+
516
## Planned content
617

718
- Raspberry Pi setup.
@@ -14,4 +25,5 @@ This section will document the BEATBox software and firmware stack.
1425

1526
## Current resources
1627

17-
[Software resources](https://github.com/Open-BeatBox/Open-BeatBox.github.io/tree/main/resources/software)
28+
- [Firmware resources](https://github.com/Open-BeatBox/Open-BeatBox.github.io/tree/main/resources/firmware)
29+
- [Software resources](https://github.com/Open-BeatBox/Open-BeatBox.github.io/tree/main/resources/software)

0 commit comments

Comments
 (0)