Skip to content

Commit 535dfc2

Browse files
committed
More robust handling of the capture start. Should eliminate a lot of bad captures.
1 parent 14835bf commit 535dfc2

File tree

6 files changed

+135
-29
lines changed

6 files changed

+135
-29
lines changed

README.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ USB D+ and D- signals can be directly connected to the MCU pins. The default
2525
pin assignments are shown in the following table:
2626

2727
| RP2040 Pin | Function | USB Cable Color |
28-
|:-------:|:-------:|:-----:|
29-
| GND | Ground | Black |
30-
| GPIO 10 | D+ | Green |
31-
| GPIO 11 | D- | White |
32-
| GPIO 18 | Trigger | N/A |
28+
|:-------:|:----------------:|:-----:|
29+
| GND | Ground | Black |
30+
| GPIO 10 | D+ | Green |
31+
| GPIO 11 | D- | White |
32+
| GPIO 12 | Start (internal) | N/A |
33+
| GPIO 18 | Trigger | N/A |
34+
| GPIO 25 | Status LED | N/A |
35+
| GPIO 26 | Error LED | N/A |
3336

3437
The easiest way to connect the signals to the Raspberry Pi Pico board is to splice
3538
the USB cable. It does not have to be pretty. Below is a picture of a cable that

bin/UsbSnifferLite.uf2

512 Bytes
Binary file not shown.

firmware/capture.c

+70-12
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
// DP and DM can be any pins, but they must be consequitive and in that order
2020
#define DP_INDEX 10
2121
#define DM_INDEX 11
22+
#define START_INDEX 12
2223

2324
HAL_GPIO_PIN(DP, 0, 10, pio0_10)
2425
HAL_GPIO_PIN(DM, 0, 11, pio0_11)
26+
HAL_GPIO_PIN(START, 0, 12, pio1_12) // Internal trigger from PIO1 to PIO0
2527
HAL_GPIO_PIN(TRIGGER, 0, 18, sio_18)
2628

2729
/*- Constants ---------------------------------------------------------------*/
@@ -171,7 +173,10 @@ static uint8_t crc5_usb(uint8_t *data, int size)
171173
static void handle_folding(int pid, uint32_t error)
172174
{
173175
if (error)
176+
{
174177
g_buffer_info.errors++;
178+
set_error(true);
179+
}
175180

176181
if (pid == Pid_Sof)
177182
{
@@ -424,21 +429,23 @@ static bool wait_for_trigger(void)
424429
//-----------------------------------------------------------------------------
425430
static void capture_buffer(void)
426431
{
427-
volatile uint32_t *instr = (volatile uint32_t *)&PIO0->INSTR_MEM0;
432+
volatile uint32_t *PIO0_INSTR_MEM = (volatile uint32_t *)&PIO0->INSTR_MEM0;
433+
volatile uint32_t *PIO1_INSTR_MEM = (volatile uint32_t *)&PIO1->INSTR_MEM0;
428434
int index, packet;
429435

430436
HAL_GPIO_DP_init();
431437
HAL_GPIO_DM_init();
438+
HAL_GPIO_START_init();
432439

433-
RESETS_SET->RESET = RESETS_RESET_pio0_Msk;
434-
RESETS_CLR->RESET = RESETS_RESET_pio0_Msk;
435-
while (0 == RESETS->RESET_DONE_b.pio0);
440+
RESETS_SET->RESET = RESETS_RESET_pio0_Msk | RESETS_RESET_pio1_Msk;
441+
RESETS_CLR->RESET = RESETS_RESET_pio0_Msk | RESETS_RESET_pio1_Msk;
442+
while (0 == RESETS->RESET_DONE_b.pio0 && 0 == RESETS->RESET_DONE_b.pio1);
436443

437444
g_buffer_info.fs = (g_capture_speed == CaptureSpeed_Full);
438445
g_buffer_info.trigger = (g_capture_trigger == CaptureTrigger_Enabled);
439446
g_buffer_info.limit = capture_limit_value();
440447

441-
static const uint16_t ops[] =
448+
static const uint16_t pio0_ops[] =
442449
{
443450
// idle:
444451
/* 0 */ OP_MOV | MOV_DST_X | MOV_SRC_NULL | MOV_OP_INVERT, // Reset the bit counter
@@ -484,32 +491,82 @@ static void capture_buffer(void)
484491
/* 28 */ OP_JMP | JMP_COND_X_NZ_PD | JMP_ADDR(25/*poll_loop*/),
485492
/* 29 */ OP_MOV | MOV_DST_ISR | MOV_SRC_NULL | MOV_OP_INVERT,
486493
/* 30 */ OP_PUSH,
487-
/* 31 */ OP_JMP | JMP_ADDR(0/*idle*/),
494+
// Wrap to 0 from here
495+
496+
// Entry point, wait for a START signal from the PIO1
497+
/* 31 */ OP_WAIT | WAIT_POL_1 | WAIT_SRC_PIN | WAIT_INDEX(2),
498+
};
499+
500+
static const uint16_t pio1_ops[] =
501+
{
502+
/* 0 */ OP_NOP | OP_DELAY(31), // Wait for the PIO0 to start
503+
/* 1 */ OP_NOP | OP_DELAY(31),
504+
/* 2 */ OP_NOP | OP_DELAY(31),
505+
/* 3 */ OP_NOP | OP_DELAY(31),
506+
507+
// wait_se0:
508+
/* 4 */ OP_MOV | MOV_DST_OSR | MOV_SRC_PINS | MOV_OP_BIT_REV,
509+
/* 5 */ OP_OUT | OUT_DST_Y | OUT_CNT(2),
510+
/* 6 */ OP_JMP | JMP_COND_Y_NZ_PD | JMP_ADDR(4/*wait_se0*/),
511+
512+
/* 7 */ OP_MOV | MOV_DST_OSR | MOV_SRC_PINS | MOV_OP_BIT_REV,
513+
/* 8 */ OP_OUT | OUT_DST_Y | OUT_CNT(2),
514+
/* 9 */ OP_JMP | JMP_COND_Y_NZ_PD | JMP_ADDR(4/*wait_se0*/),
515+
516+
/* 10 */ OP_MOV | MOV_DST_OSR | MOV_SRC_PINS | MOV_OP_BIT_REV,
517+
/* 11 */ OP_OUT | OUT_DST_Y | OUT_CNT(2),
518+
/* 12 */ OP_JMP | JMP_COND_Y_NZ_PD | JMP_ADDR(4/*wait_se0*/),
519+
520+
/* 13 */ OP_MOV | MOV_DST_OSR | MOV_SRC_PINS | MOV_OP_BIT_REV,
521+
/* 14 */ OP_OUT | OUT_DST_Y | OUT_CNT(2),
522+
/* 15 */ OP_JMP | JMP_COND_Y_NZ_PD | JMP_ADDR(4/*wait_se0*/),
523+
524+
/* 16 */ OP_SET | SET_DST_PINS | SET_DATA(1), // Set the START output
525+
/* 17 */ OP_JMP | JMP_ADDR(17/*self*/), // Infinite loop
488526
};
489527

528+
// PIO0 init
490529
PIO0->SM0_CLKDIV = ((g_buffer_info.fs ? 1 : 8) << PIO0_SM0_CLKDIV_INT_Pos);
491530

492-
for (int i = 0; i < (int)(sizeof(ops)/sizeof(uint16_t)); i++)
493-
instr[i] = ops[i];
531+
for (int i = 0; i < (int)(sizeof(pio0_ops)/sizeof(uint16_t)); i++)
532+
PIO0_INSTR_MEM[i] = pio0_ops[i];
494533

495534
if (!g_buffer_info.fs)
496535
{
497-
instr[1] = OP_WAIT | WAIT_POL_1 | WAIT_SRC_PIN | WAIT_INDEX(1);
498-
instr[2] = OP_WAIT | WAIT_POL_0 | WAIT_SRC_PIN | WAIT_INDEX(1);
536+
PIO0_INSTR_MEM[1] = OP_WAIT | WAIT_POL_1 | WAIT_SRC_PIN | WAIT_INDEX(1);
537+
PIO0_INSTR_MEM[2] = OP_WAIT | WAIT_POL_0 | WAIT_SRC_PIN | WAIT_INDEX(1);
499538
}
500539

501-
PIO0->SM0_EXECCTRL = ((g_buffer_info.fs ? DM_INDEX : DP_INDEX) << PIO0_SM0_EXECCTRL_JMP_PIN_Pos) | (31 << PIO0_SM0_EXECCTRL_WRAP_TOP_Pos) |
502-
(0 << PIO0_SM0_EXECCTRL_WRAP_BOTTOM_Pos);
540+
PIO0->SM0_EXECCTRL = ((g_buffer_info.fs ? DM_INDEX : DP_INDEX) << PIO0_SM0_EXECCTRL_JMP_PIN_Pos) |
541+
(30 << PIO0_SM0_EXECCTRL_WRAP_TOP_Pos) | (0 << PIO0_SM0_EXECCTRL_WRAP_BOTTOM_Pos);
503542

504543
PIO0->SM0_SHIFTCTRL = PIO0_SM0_SHIFTCTRL_FJOIN_RX_Msk | PIO0_SM0_SHIFTCTRL_AUTOPUSH_Msk |
505544
(31 << PIO0_SM0_SHIFTCTRL_PUSH_THRESH_Pos);
506545

507546
PIO0->SM0_PINCTRL = (DP_INDEX << PIO0_SM0_PINCTRL_IN_BASE_Pos);
508547

548+
PIO0->SM0_INSTR = OP_JMP | JMP_ADDR(31);
549+
550+
// PIO1 init
551+
PIO1->SM0_CLKDIV = ((g_buffer_info.fs ? 1 : 8) << PIO0_SM0_CLKDIV_INT_Pos);
552+
553+
for (int i = 0; i < (int)(sizeof(pio1_ops)/sizeof(uint16_t)); i++)
554+
PIO1_INSTR_MEM[i] = pio1_ops[i];
555+
556+
PIO1->SM0_EXECCTRL = (31 << PIO0_SM0_EXECCTRL_WRAP_TOP_Pos) | (0 << PIO0_SM0_EXECCTRL_WRAP_BOTTOM_Pos);
557+
PIO1->SM0_SHIFTCTRL = 0;
558+
PIO1->SM0_PINCTRL = (DP_INDEX << PIO0_SM0_PINCTRL_IN_BASE_Pos) |
559+
(START_INDEX << PIO0_SM0_PINCTRL_SET_BASE_Pos) | (1 << PIO0_SM0_PINCTRL_SET_COUNT_Pos);
560+
561+
PIO1->SM0_INSTR = OP_SET | SET_DST_PINDIRS | SET_DATA(1); // Clear the START output
562+
PIO1->SM0_INSTR = OP_SET | SET_DST_PINS | SET_DATA(0);
563+
509564
index = 2;
510565
packet = 0;
511566
g_buffer_info.count = 0;
512567

568+
set_error(false);
569+
513570
if (!wait_for_trigger())
514571
{
515572
display_puts("Capture stopped\r\n");
@@ -518,6 +575,7 @@ static void capture_buffer(void)
518575

519576
display_puts("Capture started\r\n");
520577

578+
PIO1_SET->CTRL = (1 << (PIO0_CTRL_SM_ENABLE_Pos + 0));
521579
PIO0_SET->CTRL = (1 << (PIO0_CTRL_SM_ENABLE_Pos + 0));
522580

523581
while (1)

firmware/display.c

+42-8
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@
1313
#include "utils.h"
1414

1515
/*- Definitions -------------------------------------------------------------*/
16+
#define ERROR_DATA_SIZE_LIMIT 16
17+
#define MAX_PACKET_DELTA 10000 // us
1618

1719
/*- Variables ---------------------------------------------------------------*/
1820
static uint32_t g_ref_time;
21+
static uint32_t g_prev_time;
22+
static bool g_check_delta;
1923
static bool g_folding;
2024
static int g_fold_count;
2125
static int g_display_ptr;
@@ -100,13 +104,24 @@ static void print_errors(uint32_t flags, uint8_t *data, int size)
100104

101105
if (size > 2)
102106
{
107+
bool limited = false;
108+
103109
display_puts("DATA: ");
104110

111+
if (size > ERROR_DATA_SIZE_LIMIT)
112+
{
113+
size = ERROR_DATA_SIZE_LIMIT;
114+
limited = true;
115+
}
116+
105117
for (int i = 2; i < size; i++)
106118
{
107119
display_puthex(data[i], 2);
108120
display_putc(' ');
109121
}
122+
123+
if (limited)
124+
display_puts("...");
110125
}
111126

112127
display_puts("\r\n");
@@ -252,17 +267,27 @@ static void print_time(int time)
252267
}
253268

254269
//-----------------------------------------------------------------------------
255-
static void print_packet(void)
270+
static bool print_packet(void)
256271
{
257272
int flags = g_buffer[g_display_ptr];
258273
int time = g_buffer[g_display_ptr+1];
259274
int ftime = time - g_ref_time;
275+
int delta = time - g_prev_time;
260276
int size = flags & CAPTURE_SIZE_MASK;
261277
uint8_t *payload = (uint8_t *)&g_buffer[g_display_ptr+2];
262278
int pid = payload[1] & 0x0f;
263279

280+
if (g_check_delta && delta > MAX_PACKET_DELTA)
281+
{
282+
display_puts("Time delta between packets is too large, possible buffer corruption.\r\n");
283+
return false;
284+
}
285+
264286
g_display_ptr += (((size+3)/4) + 2);
265287

288+
g_prev_time = time;
289+
g_check_delta = true;
290+
266291
if (flags & CAPTURE_LS_SOF)
267292
pid = Pid_Sof;
268293

@@ -272,12 +297,12 @@ static void print_packet(void)
272297
if (g_folding)
273298
{
274299
if (pid != Pid_Sof)
275-
return;
300+
return true;
276301

277302
if (flags & CAPTURE_MAY_FOLD)
278303
{
279304
g_fold_count++;
280-
return;
305+
return true;
281306
}
282307

283308
print_g_fold_count(g_fold_count);
@@ -288,7 +313,7 @@ static void print_packet(void)
288313
{
289314
g_folding = true;
290315
g_fold_count = 1;
291-
return;
316+
return true;
292317
}
293318

294319
print_time(ftime);
@@ -300,19 +325,21 @@ static void print_packet(void)
300325
if (g_display_time == DisplayTime_Reset)
301326
g_ref_time = time;
302327

303-
return;
328+
g_check_delta = false;
329+
330+
return true;
304331
}
305332

306333
if (flags & CAPTURE_LS_SOF)
307334
{
308335
print_ls_sof();
309-
return;
336+
return true;
310337
}
311338

312339
if (flags & CAPTURE_ERROR_MASK)
313340
{
314341
print_errors(flags, payload, size);
315-
return;
342+
return true;
316343
}
317344

318345
if (pid == Pid_Sof)
@@ -350,6 +377,8 @@ static void print_packet(void)
350377
print_split(payload);
351378
else if (pid == Pid_Reserved)
352379
print_simple("RESERVED");
380+
381+
return true;
353382
}
354383

355384
//-----------------------------------------------------------------------------
@@ -375,12 +404,17 @@ void display_buffer(void)
375404
display_puts("\r\nCapture buffer:\r\n");
376405

377406
g_ref_time = g_buffer[1];
407+
g_prev_time = g_buffer[1];
378408
g_folding = false;
409+
g_check_delta = true;
379410
g_fold_count = 0;
380411
g_display_ptr = 0;
381412

382413
for (int i = 0; i < g_buffer_info.count; i++)
383-
print_packet();
414+
{
415+
if (!print_packet())
416+
break;
417+
}
384418

385419
if (g_folding && g_fold_count)
386420
print_g_fold_count(g_fold_count);

firmware/globals.h

+1
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,6 @@ extern int g_display_data;
9898
extern int g_display_fold;
9999

100100
/*- Prototypes --------------------------------------------------------------*/
101+
void set_error(bool error);
101102

102103
#endif // _GLOBALS_H_

firmware/main.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
#define VCP_TIMEOUT 10000 // us
2525
#define STATUS_TIMEOUT 500000 // us
2626

27-
HAL_GPIO_PIN(LED, 0, 25, sio_25)
27+
HAL_GPIO_PIN(LED_O, 0, 25, sio_25)
28+
HAL_GPIO_PIN(LED_R, 0, 26, sio_26)
2829

2930
/*- Variables ---------------------------------------------------------------*/
3031
static uint8_t app_recv_buffer[USB_BUFFER_SIZE];
@@ -130,7 +131,7 @@ static void status_timer_task(void)
130131
{
131132
TIMER->INTR = TIMER_INTR_ALARM_0_Msk;
132133
TIMER->ALARM0 = TIMER->TIMELR + STATUS_TIMEOUT;
133-
HAL_GPIO_LED_toggle();
134+
HAL_GPIO_LED_O_toggle();
134135
}
135136
}
136137

@@ -267,6 +268,12 @@ void usb_configuration_callback(int config)
267268
(void)config;
268269
}
269270

271+
//-----------------------------------------------------------------------------
272+
void set_error(bool error)
273+
{
274+
HAL_GPIO_LED_R_write(error);
275+
}
276+
270277
//-----------------------------------------------------------------------------
271278
int main(void)
272279
{
@@ -277,8 +284,11 @@ int main(void)
277284
serial_number_init();
278285
capture_init();
279286

280-
HAL_GPIO_LED_out();
281-
HAL_GPIO_LED_clr();
287+
HAL_GPIO_LED_O_out();
288+
HAL_GPIO_LED_O_clr();
289+
290+
HAL_GPIO_LED_R_out();
291+
HAL_GPIO_LED_R_clr();
282292

283293
while (1)
284294
{

0 commit comments

Comments
 (0)