Skip to content

Commit f1f7c7c

Browse files
Add mixed-bus Linux and Arduino validation examples (including read-ex/write-ex flows), fix Linux parser issues, and update core example docs for pre-release sensor-integration testing
1 parent c1bc991 commit f1f7c7c

9 files changed

Lines changed: 660 additions & 4 deletions

File tree

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ if(CRUMBS_BUILD_EXAMPLES AND CRUMBS_ENABLE_LINUX_HAL)
8282
)
8383
target_link_libraries(crumbs_simple_linux_controller PRIVATE crumbs)
8484

85+
add_executable(crumbs_mixed_bus_controller
86+
examples/core_usage/linux/mixed_bus_controller/main.c
87+
)
88+
target_link_libraries(crumbs_mixed_bus_controller PRIVATE crumbs)
89+
8590
add_executable(crumbs_mock_controller
8691
examples/handlers_usage/linux/mock_controller/mock_controller.c
8792
)

docs/examples.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ CRUMBS examples are organized into a **three-tier learning path** from basics to
1616
| | [basic_peripheral](../examples/core_usage/arduino/basic_peripheral/) — multi-command with state |
1717
| | [basic_controller](../examples/core_usage/arduino/basic_controller/) — key command interface |
1818
| | [advanced_controller](../examples/core_usage/arduino/advanced_controller/) — production patterns |
19+
| | [mixed_bus_controller](../examples/core_usage/arduino/mixed_bus_controller/) — CRUMBS + raw sensor validation |
1920
| | [basic_peripheral_noncrumbs](../examples/core_usage/arduino/basic_peripheral_noncrumbs/) — non-CRUMBS device |
2021
| PlatformIO | [simple_peripheral](../examples/core_usage/platformio/simple_peripheral/) |
2122
| | [simple_controller](../examples/core_usage/platformio/simple_controller/) |
2223
| Linux | [simple_controller](../examples/core_usage/linux/simple_controller/) |
24+
| | [mixed_bus_controller](../examples/core_usage/linux/mixed_bus_controller/) |
2325

2426
**Start here:** Learn message structure, encoding/decoding, basic request-reply patterns.
2527

@@ -86,9 +88,9 @@ See [families_usage/README.md](../examples/families_usage/README.md) for overvie
8688

8789
| Platform | Peripheral Examples | Controller Examples |
8890
| ---------- | ----------------------------- | ----------------------------- |
89-
| Arduino | 3 Core | 2 Core |
91+
| Arduino | 3 Core | 4 Core |
9092
| PlatformIO | 1 Core + 1 Handler + 3 Family | 1 Core + 1 Handler |
91-
| Linux || 1 Core + 1 Handler + 2 Family |
93+
| Linux || 2 Core + 1 Handler + 2 Family |
9294

9395
---
9496

examples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ Examples organized by complexity. **Test I²C bus with [scanner](https://playgro
4545

4646
| Platform | Tier 1 | Tier 2 | Tier 3 |
4747
| ---------- | -------------- | -------------- | ----------------------------------- |
48-
| Arduino |5 examples |||
48+
| Arduino |7 examples |||
4949
| PlatformIO | ✓ 2 examples | ✓ 2 examples | ✓ 4 peripherals (LHWIT family) |
50-
| Linux |1 controller | ✓ 1 controller | ✓ 2 controllers (discovery, manual) |
50+
| Linux |2 controllers | ✓ 1 controller | ✓ 2 controllers (discovery, manual) |
5151

5252
---
5353

examples/core_usage/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
| [basic_peripheral/](arduino/basic_peripheral/) | Basic peripheral with multiple commands |
2222
| [basic_controller/](arduino/basic_controller/) | Basic controller with key commands |
2323
| [advanced_controller/](arduino/advanced_controller/) | Advanced controller with CSV parsing and scanning |
24+
| [mixed_bus_controller/](arduino/mixed_bus_controller/) | CRUMBS + raw sensor access on one bus |
2425
| [basic_peripheral_noncrumbs/](arduino/basic_peripheral_noncrumbs/) | Raw I²C peripheral (no CRUMBS) for comparison |
2526

2627
**Quick Start:** Upload [hello_peripheral](arduino/hello_peripheral/) and [hello_controller](arduino/hello_controller/) to see CRUMBS working in 15 minutes.
@@ -60,17 +61,58 @@ pio run --target upload
6061
| Example | Description |
6162
| ---------------------------------------------- | ----------------------------------------- |
6263
| [simple_controller/](linux/simple_controller/) | Linux controller using linux-wire library |
64+
| [mixed_bus_controller/](linux/mixed_bus_controller/) | Mixed-bus validator for CRUMBS + sensor |
6365

6466
### Getting Started (Linux)
6567

6668
```bash
6769
cd examples/core_usage/linux/simple_controller
6870
make
6971
./simple_controller /dev/i2c-1
72+
73+
cd ../mixed_bus_controller
74+
cmake -S . -B build -DCRUMBS_BUILD_IN_TREE=ON
75+
cmake --build build
76+
./build/crumbs_mixed_bus_controller /dev/i2c-1 scan 0x20,0x21 strict
7077
```
7178

7279
**Note:** Requires [linux-wire](https://github.com/AnotherDaniel/linux-wire) library installed.
7380

81+
### Mixed-Bus Validation Path (Pre-Release)
82+
83+
Use this sequence to validate the new raw-I2C helper APIs end-to-end before release:
84+
85+
1. `scan` known CRUMBS addresses only:
86+
87+
```bash
88+
./build/crumbs_mixed_bus_controller /dev/i2c-1 scan 0x20,0x21,0x30 strict
89+
```
90+
91+
2. read sensor register with repeated-start:
92+
93+
```bash
94+
./build/crumbs_mixed_bus_controller /dev/i2c-1 read-u8 0x76 0xD0 1 repeat
95+
```
96+
97+
3. read u16-addressed register device:
98+
99+
```bash
100+
./build/crumbs_mixed_bus_controller /dev/i2c-1 read-u16 0x40 0x0100 6 repeat
101+
```
102+
103+
4. optional generic preamble read/write using `-ex` APIs:
104+
105+
```bash
106+
./build/crumbs_mixed_bus_controller /dev/i2c-1 read-ex 0x1E 0x20,0x08 6 repeat
107+
./build/crumbs_mixed_bus_controller /dev/i2c-1 write-ex 0x1E 0x20,0x09 0x10,0x00
108+
```
109+
110+
5. optional sensor register write:
111+
112+
```bash
113+
./build/crumbs_mixed_bus_controller /dev/i2c-1 write-u8 0x76 0xF4 0x27
114+
```
115+
74116
---
75117

76118
## Quick Start Path
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Mixed Bus Controller (Arduino)
2+
3+
Arduino controller example for mixed-bus validation:
4+
5+
- CRUMBS candidate-address scanning
6+
- raw register read from an off-the-shelf I2C sensor
7+
- repeated-start path through `crumbs_arduino_write_then_read`
8+
9+
## What It Does
10+
11+
Each loop:
12+
13+
1. scans only configured CRUMBS candidate addresses,
14+
2. reads one sensor register (`SENSOR_WHOAMI_REG`) using raw helper APIs,
15+
3. prints results to Serial.
16+
17+
## Setup
18+
19+
Edit these constants in `mixed_bus_controller.ino`:
20+
21+
- `SENSOR_ADDR`
22+
- `SENSOR_WHOAMI_REG`
23+
- `kCrumbsCandidates[]`
24+
25+
## Expected Output
26+
27+
Serial should show:
28+
29+
- discovered CRUMBS addresses/types,
30+
- `Sensor read rc=0 WHOAMI=0x..` for successful sensor reads.
31+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include <crumbs.h>
2+
#include <crumbs_arduino.h>
3+
4+
// Configure for your hardware setup.
5+
#define SENSOR_ADDR 0x76
6+
#define SENSOR_WHOAMI_REG 0xD0
7+
8+
// Only probe known CRUMBS addresses on mixed buses.
9+
static const uint8_t kCrumbsCandidates[] = {0x20, 0x21, 0x30};
10+
11+
static crumbs_context_t g_ctx;
12+
static crumbs_device_t g_sensor = {
13+
&g_ctx,
14+
SENSOR_ADDR,
15+
crumbs_arduino_wire_write,
16+
crumbs_arduino_read,
17+
crumbs_arduino_delay_us,
18+
NULL};
19+
20+
static void print_hex_u8(uint8_t v)
21+
{
22+
if (v < 0x10)
23+
Serial.print('0');
24+
Serial.print(v, HEX);
25+
}
26+
27+
void setup()
28+
{
29+
Serial.begin(115200);
30+
while (!Serial)
31+
{
32+
}
33+
34+
crumbs_arduino_init_controller(&g_ctx);
35+
Serial.println("CRUMBS mixed-bus controller example");
36+
}
37+
38+
void loop()
39+
{
40+
uint8_t found[8];
41+
uint8_t types[8];
42+
43+
int n = crumbs_controller_scan_for_crumbs_candidates(
44+
&g_ctx,
45+
kCrumbsCandidates,
46+
sizeof(kCrumbsCandidates),
47+
1, /* strict */
48+
crumbs_arduino_wire_write,
49+
crumbs_arduino_read,
50+
NULL,
51+
found,
52+
types,
53+
8,
54+
10000);
55+
56+
Serial.print("CRUMBS scan result: ");
57+
Serial.println(n);
58+
for (int i = 0; i < n && i < 8; ++i)
59+
{
60+
Serial.print(" addr=0x");
61+
print_hex_u8(found[i]);
62+
Serial.print(" type=0x");
63+
print_hex_u8(types[i]);
64+
Serial.println();
65+
}
66+
67+
uint8_t whoami = 0;
68+
int rc = crumbs_i2c_dev_read_reg_u8(
69+
&g_sensor,
70+
SENSOR_WHOAMI_REG,
71+
&whoami,
72+
1,
73+
10000,
74+
1, /* require repeated-start */
75+
crumbs_arduino_write_then_read);
76+
77+
Serial.print("Sensor read rc=");
78+
Serial.print(rc);
79+
if (rc == CRUMBS_I2C_DEV_OK)
80+
{
81+
Serial.print(" WHOAMI=0x");
82+
print_hex_u8(whoami);
83+
}
84+
Serial.println();
85+
86+
delay(2000);
87+
}
88+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
project(crumbs_mixed_bus_controller C)
3+
4+
option(CRUMBS_BUILD_IN_TREE "Add CRUMBS as a subdirectory and link the in-repo crumbs target" ON)
5+
if(NOT DEFINED CRUMBS_PATH)
6+
set(CRUMBS_PATH ${CMAKE_SOURCE_DIR}/../../../..)
7+
endif()
8+
9+
if(CRUMBS_BUILD_IN_TREE)
10+
set(CRUMBS_ENABLE_LINUX_HAL ON CACHE BOOL "" FORCE)
11+
add_subdirectory(${CRUMBS_PATH} ${CMAKE_BINARY_DIR}/crumbs_subbuild)
12+
13+
add_executable(crumbs_mixed_bus_controller main.c)
14+
target_link_libraries(crumbs_mixed_bus_controller PRIVATE crumbs)
15+
target_include_directories(crumbs_mixed_bus_controller PRIVATE ${CRUMBS_PATH}/src)
16+
else()
17+
find_package(crumbs CONFIG REQUIRED)
18+
add_executable(crumbs_mixed_bus_controller main.c)
19+
target_link_libraries(crumbs_mixed_bus_controller PRIVATE crumbs::crumbs)
20+
endif()
21+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Mixed Bus Controller (Linux)
2+
3+
Linux controller example for validating the new mixed-bus APIs:
4+
5+
- `crumbs_controller_scan_for_crumbs_candidates(...)`
6+
- `crumbs_i2c_dev_read_reg_u8/u16be(...)`
7+
- `crumbs_i2c_dev_write_reg_u8/u16be(...)`
8+
- `crumbs_linux_write_then_read(...)`
9+
10+
This example is intended for **pre-release validation** on a real bus with:
11+
12+
1. one or more CRUMBS devices,
13+
2. one off-the-shelf I2C sensor.
14+
15+
## Build
16+
17+
```bash
18+
cmake -S . -B build -DCRUMBS_BUILD_IN_TREE=ON
19+
cmake --build build
20+
```
21+
22+
## Usage
23+
24+
```bash
25+
./build/crumbs_mixed_bus_controller <i2c-dev> scan <candidate_csv> [strict|non-strict]
26+
./build/crumbs_mixed_bus_controller <i2c-dev> read-u8 <sensor_addr> <reg_u8> <len> [repeat|norepeat]
27+
./build/crumbs_mixed_bus_controller <i2c-dev> read-u16 <sensor_addr> <reg_u16> <len> [repeat|norepeat]
28+
./build/crumbs_mixed_bus_controller <i2c-dev> read-ex <sensor_addr> <reg_csv> <len> [repeat|norepeat]
29+
./build/crumbs_mixed_bus_controller <i2c-dev> write-u8 <sensor_addr> <reg_u8> <data_csv>
30+
./build/crumbs_mixed_bus_controller <i2c-dev> write-u16 <sensor_addr> <reg_u16> <data_csv>
31+
./build/crumbs_mixed_bus_controller <i2c-dev> write-ex <sensor_addr> <reg_csv> <data_csv>
32+
```
33+
34+
## Examples
35+
36+
```bash
37+
# Scan only known CRUMBS addresses
38+
./build/crumbs_mixed_bus_controller /dev/i2c-1 scan 0x20,0x21,0x30 strict
39+
40+
# Read sensor WHOAMI register (u8 register address)
41+
./build/crumbs_mixed_bus_controller /dev/i2c-1 read-u8 0x76 0xD0 1 repeat
42+
43+
# Read 6 bytes using u16 register address
44+
./build/crumbs_mixed_bus_controller /dev/i2c-1 read-u16 0x40 0x0100 6 repeat
45+
46+
# Read 6 bytes from a 2-byte register preamble using generic -ex API
47+
./build/crumbs_mixed_bus_controller /dev/i2c-1 read-ex 0x1E 0x20,0x08 6 repeat
48+
49+
# Write one config byte
50+
./build/crumbs_mixed_bus_controller /dev/i2c-1 write-u8 0x76 0xF4 0x27
51+
52+
# Generic write with multi-byte register preamble
53+
./build/crumbs_mixed_bus_controller /dev/i2c-1 write-ex 0x1E 0x20,0x09 0x10,0x00
54+
```
55+
56+
## Validation Checklist
57+
58+
- `scan` only touches candidate addresses you pass in.
59+
- CRUMBS devices are discovered with address + type.
60+
- sensor read/write works for both u8 and u16 register-address forms.
61+
- generic `read-ex`/`write-ex` works for sensors with custom register preambles.
62+
- repeated-start mode works for sensors that require it.

0 commit comments

Comments
 (0)