Skip to content

Commit 78d34d5

Browse files
committed
reduce code size, use state to replace active + pending
1 parent 9ac343a commit 78d34d5

File tree

8 files changed

+266
-122
lines changed

8 files changed

+266
-122
lines changed

.claude/commands/build-doc.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# build-doc
2+
3+
Scan all example READMEs and build the Sphinx documentation.
4+
5+
## Instructions
6+
7+
1. Install docs dependencies:
8+
```bash
9+
pip install -r docs/requirements.txt
10+
```
11+
12+
2. Build the docs from the repo root:
13+
```bash
14+
sphinx-build -b html docs docs/_build
15+
```
16+
`conf.py` automatically scans all `examples/{device,host,dual}/*/README.md`, copies them into `docs/examples/`, and regenerates `examples.rst` with the toctree.
17+
18+
3. Use a timeout of at least 60 seconds.
19+
20+
4. After the build completes:
21+
- Show the build output to the user.
22+
- Report total warnings and errors.
23+
- List which example READMEs were discovered and included.
24+
- If there are errors, suggest fixes.

.claude/commands/hil.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# hil
2+
3+
Run Hardware-in-the-Loop (HIL) tests on physical boards.
4+
5+
## Arguments
6+
- $ARGUMENTS: Optional flags (e.g. board name, extra args). If empty, runs all boards with default config.
7+
8+
## Instructions
9+
10+
1. Determine the HIL config file:
11+
```bash
12+
HIL_CONFIG=$( (systemctl list-units --type=service --state=running 2>/dev/null; systemctl --user list-units --type=service --state=running 2>/dev/null) | grep -q 'actions\.runner' && echo tinyusb.json || echo local.json )
13+
```
14+
Default is `local.json` for local development.
15+
16+
2. Parse $ARGUMENTS:
17+
- If $ARGUMENTS contains `-b BOARD_NAME`, run for that specific board only.
18+
- If $ARGUMENTS is empty or has no `-b`, run for all boards in the config.
19+
- Pass through any other flags (e.g. `-v` for verbose) directly to the command.
20+
21+
3. Run the HIL test from the repo root directory:
22+
- Specific board: `python test/hil/hil_test.py -b BOARD_NAME -B examples $HIL_CONFIG $EXTRA_ARGS`
23+
- All boards: `python test/hil/hil_test.py -B examples $HIL_CONFIG $EXTRA_ARGS`
24+
25+
4. Use a timeout of at least 20 minutes (600000ms). HIL tests take 2-5 minutes. NEVER cancel early.
26+
27+
5. After the test completes:
28+
- Show the test output to the user.
29+
- Summarize pass/fail results per board.
30+
- If there are failures, suggest re-running with `-v` flag for verbose output to help debug.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# MSC File Explorer
2+
3+
This host example implements an interactive command-line file browser for USB Mass Storage devices.
4+
When a USB flash drive is connected, the device is automatically mounted using FatFS and a shell-like
5+
CLI is presented over the board's serial console.
6+
7+
## Features
8+
9+
- Automatic mount/unmount of USB storage devices
10+
- FAT12/16/32 filesystem support via FatFS
11+
- Interactive CLI with command history
12+
- Read speed benchmarking with `dd`
13+
- Support for up to 4 simultaneous USB storage devices (via hub)
14+
15+
## Supported Commands
16+
17+
| Command | Usage | Description |
18+
|---------|--------------------|------------------------------------------------------|
19+
| help | `help` | Print list of available commands |
20+
| cat | `cat <file>` | Print file contents to the console |
21+
| cd | `cd <dir>` | Change current working directory |
22+
| cp | `cp <src> <dest>` | Copy a file |
23+
| dd | `dd [count]` | Read sectors and report speed (default 1024 sectors) |
24+
| ls | `ls [dir]` | List directory contents |
25+
| pwd | `pwd` | Print current working directory |
26+
| mkdir | `mkdir <dir>` | Create a directory |
27+
| mv | `mv <src> <dest>` | Rename/move a file or directory |
28+
| rm | `rm <file>` | Remove a file |
29+
30+
## Build
31+
32+
Build for a specific board using CMake (see [Getting Started](https://docs.tinyusb.org/en/latest/getting_started.html)):
33+
34+
```bash
35+
# Example: build for Raspberry Pi Pico
36+
cmake -B build -DBOARD=raspberry_pi_pico -DFAMILY=rp2040 examples/host/msc_file_explorer
37+
cmake --build build
38+
```
39+
40+
## Usage
41+
42+
1. Flash the firmware to your board.
43+
2. Open a serial terminal (e.g. `minicom`, `screen`, `PuTTY`) at 115200 baud.
44+
3. Plug a USB flash drive into the board's USB host port.
45+
4. The device is auto-mounted and the prompt appears:
46+
47+
```
48+
TinyUSB MSC File Explorer Example
49+
50+
Device connected
51+
Vendor : Kingston
52+
Product : DataTraveler 2.0
53+
Rev : 1.0
54+
Capacity: 1.9 GB
55+
56+
0:/> _
57+
```
58+
59+
### Browsing Files
60+
61+
```
62+
0:/> ls
63+
----a 1234 readme.txt
64+
d---- 0 photos
65+
d---- 0 docs
66+
67+
0:/> cd photos
68+
0:/photos> ls
69+
----a 520432 vacation.jpg
70+
----a 312088 family.png
71+
72+
0:/> cat readme.txt
73+
Hello from USB drive!
74+
```
75+
76+
### Copying and Moving Files
77+
78+
```
79+
0:/> cp readme.txt backup.txt
80+
0:/> mv backup.txt docs/backup.txt
81+
```
82+
83+
### Measuring Read Speed
84+
85+
```
86+
0:/> dd
87+
Reading 1024 sectors...
88+
Data speed: 823 KB/s
89+
```
90+
91+
### Multiple Devices
92+
93+
When using a USB hub, multiple drives are mounted as `0:`, `1:`, etc. Use the drive prefix to
94+
navigate between them:
95+
96+
```
97+
0:/> cd 1:
98+
1:/> ls
99+
```
100+
101+
## Testing
102+
103+
This example is part of the TinyUSB HIL (Hardware-in-the-Loop) test suite. The HIL test
104+
automatically flashes, runs the example, and verifies MSC enumeration and file operations
105+
against a known USB drive.

src/portable/raspberrypi/rp2040/dcd_rp2040.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ static void hw_endpoint_open(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t
111111
// double buffered Bulk endpoint
112112
if (transfer_type == TUSB_XFER_BULK) {
113113
size *= 2u;
114-
115114
#if CFG_TUSB_RP2_ERRATA_E15
116115
if (dir == TUSB_DIR_IN) {
117116
ep->e15_bulk_in = true;
@@ -195,7 +194,7 @@ TU_ATTR_ALWAYS_INLINE static inline void reset_ep0(void) {
195194
for (uint8_t dir = 0; dir < 2; dir++) {
196195
struct hw_endpoint *ep = hw_endpoint_get(0, dir);
197196
ep->next_pid = 1u;
198-
if (ep->active) {
197+
if (ep->state == EPSTATE_ACTIVE) {
199198
hw_endpoint_abort_xfer(ep); // Abort any pending transfer per USB specs
200199
}
201200
}
@@ -254,12 +253,12 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) {
254253
struct hw_endpoint *ep = hw_endpoint_get(i, TUSB_DIR_IN);
255254

256255
// Active Bulk IN endpoint requires SOF
257-
if (ep->e15_bulk_in && ep->active) {
256+
if (ep->e15_bulk_in && ep->state == EPSTATE_ACTIVE) {
258257
keep_sof_alive = true;
259258
hw_endpoint_lock_update(ep, 1);
260259

261-
if (ep->pending) {
262-
ep->pending = 0;
260+
if (ep->state == EPSTATE_PENDING) {
261+
ep->state = EPSTATE_ACTIVE;
263262

264263
io_rw_32 *buf_reg32 = get_buf_ctrl(i, TUSB_DIR_IN);
265264
io_rw_16 *buf_reg16 = (io_rw_16 *)buf_reg32;
@@ -276,7 +275,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) {
276275
if (buf0_idle && buf1_idle) {
277276
// both are idle, start fresh
278277
io_rw_32 *ep_reg = get_ep_ctrl(i, TUSB_DIR_IN);
279-
rp2usb_buffer_start(ep, ep_reg, buf_reg32, false, false);
278+
rp2usb_buffer_start(ep, ep_reg, buf_reg32, false);
280279
} else if (buf0_idle) {
281280
uint16_t buf0 = bufctrl_prepare16(ep, ep->dpram_buf, false);
282281
bufctrl_write16(buf_reg16, buf0);
@@ -501,7 +500,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc)
501500
struct hw_endpoint *ep = hw_endpoint_get(epnum, dir);
502501
TU_ASSERT(ep->dpram_buf != NULL); // must be inited and allocated previously
503502

504-
if (ep->active) {
503+
if (ep->state == EPSTATE_ACTIVE) {
505504
hw_endpoint_abort_xfer(ep); // abort any pending transfer
506505
}
507506
ep->max_packet_size = ep_desc->wMaxPacketSize;

0 commit comments

Comments
 (0)