1+
2+ #include <stdio.h>
3+ #include <string.h>
4+ #include <strings.h>
5+
6+ #include "hardware/gpio.h"
7+ #include "hardware/sync.h"
8+ #include "pico/stdlib.h"
9+ #include "pico/time.h"
10+ #include "pico/bootrom.h"
11+ #include "pico/types.h"
12+ #include "pio_usb.h"
13+ #include "pio_usb_configuration.h"
14+ #include "pio_usb_ll.h"
15+ #include "usb_definitions.h"
16+ #include "usb_rx.pio.h"
17+
18+ pio_usb_configuration_t pio_usb_config = PIO_USB_DEFAULT_CONFIG ;
19+
20+ static bool do_test (pio_port_t * pp );
21+
22+ int main () {
23+ // default 125MHz is not appropreate. Sysclock should be multiple of 12MHz.
24+ set_sys_clock_khz (120000 , true);
25+
26+ stdio_init_all ();
27+
28+ sleep_ms (1000 );
29+
30+ printf ("start\n" );
31+
32+ pio_usb_config .alarm_pool = NULL ;
33+ pio_usb_config .skip_alarm_pool = true;
34+ pio_usb_config .pin_dp = 0 ;
35+ pio_usb_host_init (& pio_usb_config );
36+ if (pio_usb_host_add_port (4 , PIO_USB_PINOUT_DMDP ) != 0 ) {
37+ printf ("Failed to add root port\n" );
38+ }
39+ pio_port_t * pp = PIO_USB_PIO_PORT (0 );
40+
41+ while (1 ) {
42+ printf ("\n[b]: Jump to bootloader, [others]: Execute tests\n" );
43+ char c = 0 ;
44+ scanf ("%c" , & c );
45+
46+ if (c == 'b' ) {
47+ reset_usb_boot (1 << PICO_DEFAULT_LED_PIN , 0 );
48+ }
49+
50+ {
51+ printf ("\nTest1: FS, 1\n" );
52+
53+ root_port_t * root = PIO_USB_ROOT_PORT (0 );
54+ gpio_pull_up (root -> pin_dp );
55+ gpio_pull_down (root -> pin_dm );
56+ root -> is_fullspeed = true;
57+ root -> initialized = true;
58+ root -> connected = true;
59+ root -> suspended = false;
60+
61+ uint32_t irq = save_and_disable_interrupts ();
62+ pio_usb_host_frame ();
63+ restore_interrupts (irq );
64+
65+ printf ("%s\n" , do_test (pp ) ? "[OK]" : "[NG]" );
66+
67+ root -> connected = false;
68+ }
69+
70+ {
71+ printf ("\nTest2: FS, 2\n" );
72+
73+ root_port_t * root = PIO_USB_ROOT_PORT (1 );
74+ gpio_pull_up (root -> pin_dp );
75+ gpio_pull_down (root -> pin_dm );
76+ root -> is_fullspeed = true;
77+ root -> initialized = true;
78+ root -> connected = true;
79+ root -> suspended = false;
80+
81+ uint32_t irq = save_and_disable_interrupts ();
82+ pio_usb_host_frame ();
83+ restore_interrupts (irq );
84+
85+ printf ("%s\n" , do_test (pp ) ? "[OK]" : "[NG]" );
86+
87+ root -> connected = false;
88+ }
89+
90+ {
91+ printf ("\nTest3: LS, 1\n" );
92+
93+ root_port_t * root = PIO_USB_ROOT_PORT (0 );
94+ gpio_pull_down (root -> pin_dp );
95+ gpio_pull_up (root -> pin_dm );
96+ root -> is_fullspeed = false;
97+ root -> initialized = true;
98+ root -> connected = true;
99+ root -> suspended = false;
100+
101+ uint32_t irq = save_and_disable_interrupts ();
102+ pio_usb_host_frame ();
103+ restore_interrupts (irq );
104+
105+ printf ("%s\n" , do_test (pp ) ? "[OK]" : "[NG]" );
106+
107+ root -> connected = false;
108+ }
109+
110+ {
111+ printf ("\nTest4: LS, 2\n" );
112+
113+ root_port_t * root = PIO_USB_ROOT_PORT (1 );
114+ gpio_pull_down (root -> pin_dp );
115+ gpio_pull_up (root -> pin_dm );
116+ root -> is_fullspeed = false;
117+ root -> initialized = true;
118+ root -> connected = true;
119+ root -> suspended = false;
120+
121+ uint32_t irq = save_and_disable_interrupts ();
122+ pio_usb_host_frame ();
123+ restore_interrupts (irq );
124+
125+ printf ("%s\n" , do_test (pp ) ? "[OK]" : "[NG]" );
126+
127+ root -> connected = false;
128+ }
129+
130+ {
131+ printf ("\nTest 5: Software Encode Speed\n" );
132+ uint8_t buffer [64 ];
133+ uint8_t encoded_data [64 * 2 * 7 / 6 + 2 ];
134+ for (size_t i = 0 ; i < sizeof (buffer ); i ++ ) {
135+ buffer [i ] = i ;
136+ }
137+
138+ absolute_time_t start = get_absolute_time ();
139+ for (int i = 0 ; i < 1000 ; i ++ ) {
140+ pio_usb_ll_encode_tx_data (buffer , sizeof (buffer ), encoded_data );
141+ }
142+ absolute_time_t end = get_absolute_time ();
143+ int64_t diff = absolute_time_diff_us (start , end );
144+ printf ("%f us (64bytes packet)" , diff / 1000.0f );
145+ }
146+ }
147+ }
148+
149+ static bool do_test (pio_port_t * pp ) {
150+ bool success = true;
151+
152+ // Prepare transfer data
153+ uint8_t test_data [] = {0x80 , 0xff , 0x00 , 0x83 };
154+ endpoint_t * ep = PIO_USB_ENDPOINT (0 );
155+ ep -> has_transfer = false;
156+ ep -> is_tx = true;
157+ ep -> size = 32 ;
158+ pio_usb_ll_transfer_start (ep , test_data , sizeof (test_data ));
159+
160+ // Start receiver
161+ pio_usb_bus_prepare_receive (pp );
162+ pio_usb_bus_start_receive (pp );
163+
164+ uint32_t irq = save_and_disable_interrupts ();
165+ // Start transmitter
166+ pio_usb_bus_usb_transfer (pp , ep -> buffer , ep -> encoded_data_len );
167+ restore_interrupts (irq );
168+
169+ // Check received data
170+ uint8_t received [sizeof (test_data ) + 4 ];
171+ memset (received , 0 , sizeof (received ));
172+ uint8_t received_cnt = 0 ;
173+
174+ while (pio_sm_get_rx_fifo_level (pp -> pio_usb_rx , pp -> sm_rx )) {
175+ if (received_cnt >= sizeof (received )) {
176+ printf ("\t[NG] Invalid size\n" );
177+ success = false;
178+ break ;
179+ }
180+ received [received_cnt ++ ] = pio_sm_get (pp -> pio_usb_rx , pp -> sm_rx ) >> 24 ;
181+ }
182+
183+ for (size_t i = 0 ; i < sizeof (received ); i ++ ) {
184+ printf ("%02x " , received [i ]);
185+ }
186+ printf ("\n" );
187+
188+ for (size_t i = 0 ; i < sizeof (test_data ); i ++ ) {
189+ if (test_data [i ] != received [i + 2 ]) {
190+ printf ("\t[NG] Invalid data at %d. Expect: %02x, Received: %02x\n" , i ,
191+ test_data [i ], received [i + 2 ]);
192+ success = false;
193+ }
194+ }
195+
196+ ep -> has_transfer = false;
197+
198+ return success ;
199+ }
0 commit comments