Skip to content

Commit ef9d780

Browse files
Update pio_usb_device
1 parent 30283a9 commit ef9d780

File tree

5 files changed

+110
-40
lines changed

5 files changed

+110
-40
lines changed

src/pio_usb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ uint8_t __no_inline_not_in_flash_func(pio_usb_bus_wait_handshake)(pio_port_t* pp
163163
}
164164
}
165165

166-
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
166+
// pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, true);
167167

168168
return pp->usb_rx_buffer[1];
169169
}

src/pio_usb_device.c

Lines changed: 103 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include "hardware/dma.h"
2222
#include "hardware/irq.h"
23+
#include "hardware/gpio.h"
24+
#include "hardware/pio.h"
2325

2426
static uint8_t new_devaddr = 0;
2527
static uint8_t ep0_crc5_lut[16];
@@ -39,19 +41,42 @@ static void __no_inline_not_in_flash_func(update_ep0_crc5_lut)(uint8_t addr) {
3941
}
4042
}
4143

42-
static __always_inline void restart_usb_reveiver(pio_port_t *pp) {
43-
pio_sm_exec(pp->pio_usb_rx, pp->sm_rx, pp->rx_reset_instr);
44+
static __always_inline void restart_usb_receiver(pio_port_t *pp) {
4445
pio_sm_exec(pp->pio_usb_rx, pp->sm_rx, pp->rx_reset_instr2);
4546
pio_sm_restart(pp->pio_usb_rx, pp->sm_rx);
4647
pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
4748
}
4849

49-
static __always_inline int8_t device_receive_token(uint8_t *buffer,
50-
uint8_t dev_addr) {
50+
static __always_inline uint8_t device_receive_token(void) {
51+
pio_port_t *pp = PIO_USB_PIO_PORT(0);
52+
uint8_t idx = 0;
53+
uint8_t buffer[2];
54+
55+
if ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
56+
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
57+
if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) {
58+
buffer[idx++] = pio_sm_get(pp->pio_usb_rx, pp->sm_rx) >> 24;
59+
if (idx == 2) {
60+
return buffer[1];
61+
}
62+
}
63+
}
64+
} else {
65+
// host is probably timeout. Ignore this packets.
66+
pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
67+
}
68+
69+
return 0;
70+
}
71+
72+
static __always_inline int8_t device_receive_ep_address(uint8_t token,
73+
uint8_t dev_addr) {
5174
pio_port_t *pp = PIO_USB_PIO_PORT(0);
5275
uint8_t idx = 0;
5376
uint8_t addr;
5477
uint8_t ep;
78+
uint8_t ep_num = 0;
79+
uint8_t buffer[3];
5580
bool match = false;
5681

5782
static uint8_t eplut[2][8] = {{0, 2, 4, 6, 8, 10, 12, 14},
@@ -62,10 +87,13 @@ static __always_inline int8_t device_receive_token(uint8_t *buffer,
6287
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
6388
if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) {
6489
buffer[idx++] = pio_sm_get(pp->pio_usb_rx, pp->sm_rx) >> 24;
65-
if ((idx == 3) && (buffer[1] != USB_PID_SOF)) {
66-
addr = buffer[2] & 0x7f;
67-
current_lut = &eplut[buffer[2] >> 7][0];
90+
if ((idx == 1) && (token != USB_PID_SOF)) {
91+
addr = buffer[0] & 0x7f;
92+
current_lut = &eplut[buffer[0] >> 7][0];
6893
match = dev_addr == addr ? true : false;
94+
} else if (idx == 2) {
95+
ep_num = buffer[1];
96+
break;
6997
}
7098
}
7199
}
@@ -74,11 +102,9 @@ static __always_inline int8_t device_receive_token(uint8_t *buffer,
74102
pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
75103
}
76104

77-
restart_usb_reveiver(pp);
78-
79105
if (match) {
80-
ep = current_lut[buffer[3] & 0x07];
81-
if (ep0_crc5_lut[ep] == buffer[3]) {
106+
ep = current_lut[ep_num & 0x07];
107+
if (ep0_crc5_lut[ep] == ep_num) {
82108
return ep;
83109
} else {
84110
return -1;
@@ -88,34 +114,42 @@ static __always_inline int8_t device_receive_token(uint8_t *buffer,
88114
return -1;
89115
}
90116

117+
static __always_inline void wait_receive_complete(pio_port_t *pp) {
118+
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
119+
continue;
120+
}
121+
pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
122+
}
123+
91124
static void __no_inline_not_in_flash_func(usb_device_packet_handler)(void) {
92-
static uint8_t token_buf[64];
93125
pio_port_t *pp = PIO_USB_PIO_PORT(0);
94126
root_port_t *rport = PIO_USB_ROOT_PORT(0);
95127

128+
gpio_clr_mask(1<<3);
96129
//
97130
// time critical start
98131
//
99-
int8_t ep_num = device_receive_token(token_buf, rport->dev_addr);
132+
uint8_t addr = rport->dev_addr;
133+
uint8_t token = device_receive_token();
100134

101-
if (token_buf[1] == USB_PID_IN) {
135+
if (token == USB_PID_IN) {
136+
int8_t ep_num = device_receive_ep_address(token, addr);
102137
if (ep_num < 0) {
138+
gpio_set_mask(1 << 3);
103139
return;
104140
}
105141

106142
endpoint_t *ep = PIO_USB_ENDPOINT((ep_num << 1) | 0x01);
107-
uint16_t const xact_len = pio_usb_ll_get_transaction_len(ep);
108143

109-
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
110144
pio_sm_exec(pp->pio_usb_tx, pp->sm_tx, pp->tx_start_instr);
111145
volatile bool has_transfer = ep->has_transfer;
112146

113147
if (has_transfer) {
114148
dma_channel_transfer_from_buffer_now(pp->tx_ch, ep->buffer, ep->encoded_data_len);
115149
} else if (ep->stalled) {
116-
dma_channel_transfer_from_buffer_now(pp->tx_ch, stall_encoded, 5);
150+
dma_channel_transfer_from_buffer_now(pp->tx_ch, stall_encoded, sizeof(stall_encoded));
117151
} else {
118-
dma_channel_transfer_from_buffer_now(pp->tx_ch, nak_encoded, 5);
152+
dma_channel_transfer_from_buffer_now(pp->tx_ch, nak_encoded, sizeof(nak_encoded));
119153
}
120154

121155
pp->pio_usb_tx->irq = IRQ_TX_ALL_MASK; // clear complete flag
@@ -144,28 +178,35 @@ static void __no_inline_not_in_flash_func(usb_device_packet_handler)(void) {
144178
update_ep0_crc5_lut(rport->dev_addr);
145179
}
146180

147-
pio_usb_ll_transfer_continue(ep, xact_len);
181+
rport->ints |= PIO_USB_INTS_ENDPOINT_CONTINUE_BITS;
182+
rport->ep_continue |= (1 << ep_num);
148183
} else {
149184
pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
150185
irq_clear(pp->device_rx_irq_num);
186+
restart_usb_receiver(pp);
151187
pio_usb_bus_start_receive(pp);
152188

153189
//
154190
// time critical end
155191
//
156192
}
157-
} else if (token_buf[1] == USB_PID_OUT) {
193+
} else if (token == USB_PID_OUT) {
194+
int8_t ep_num = device_receive_ep_address(token, addr);
195+
wait_receive_complete(pp);
196+
restart_usb_receiver(pp);
158197
if (ep_num < 0) {
159198
return;
160199
}
161200
endpoint_t *ep = PIO_USB_ENDPOINT(ep_num << 1);
162201

202+
gpio_clr_mask(1<<4);
163203
uint8_t hanshake = ep->stalled
164204
? USB_PID_STALL
165205
: (ep->has_transfer ? USB_PID_ACK : USB_PID_NAK);
166206
int res = pio_usb_bus_receive_packet_and_handshake(pp, hanshake);
167207
pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
168-
restart_usb_reveiver(pp);
208+
restart_usb_receiver(pp);
209+
pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
169210
irq_clear(pp->device_rx_irq_num);
170211

171212
if (ep->has_transfer) {
@@ -174,13 +215,16 @@ static void __no_inline_not_in_flash_func(usb_device_packet_handler)(void) {
174215
pio_usb_ll_transfer_continue(ep, res);
175216
}
176217
}
177-
} else if (token_buf[1] == USB_PID_SETUP) {
218+
} else if (token == USB_PID_SETUP) {
219+
int8_t ep_num = device_receive_ep_address(token, addr);
220+
restart_usb_receiver(pp);
178221
if (ep_num < 0) {
179222
return;
180223
}
181224
int res = pio_usb_bus_receive_packet_and_handshake(pp, USB_PID_ACK);
182225
pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
183-
restart_usb_reveiver(pp);
226+
restart_usb_receiver(pp);
227+
pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
184228
irq_clear(pp->device_rx_irq_num);
185229

186230
if (res >= 0) {
@@ -192,16 +236,15 @@ static void __no_inline_not_in_flash_func(usb_device_packet_handler)(void) {
192236
PIO_USB_ENDPOINT(0)->data_id = PIO_USB_ENDPOINT(1)->data_id = 1;
193237
PIO_USB_ENDPOINT(0)->stalled = PIO_USB_ENDPOINT(1)->stalled = false;
194238
}
195-
} else if (token_buf[1] == USB_PID_SOF) {
239+
} else if (token == USB_PID_SOF) {
196240
// SOF interrupt
197-
}
198-
199-
200-
token_buf[0] = 0; // clear received token
201-
token_buf[1] = 0;
202-
203-
if (rport->ints) {
204-
pio_usb_device_irq_handler(0);
241+
device_receive_ep_address(token, addr);
242+
wait_receive_complete(pp);
243+
restart_usb_receiver(pp);
244+
} else {
245+
device_receive_ep_address(token, addr);
246+
wait_receive_complete(pp);
247+
restart_usb_receiver(pp);
205248
}
206249
}
207250

@@ -212,6 +255,7 @@ usb_device_t *pio_usb_device_init(const pio_usb_configuration_t *c,
212255
usb_device_t *dev = &pio_usb_device[0];
213256

214257
pio_usb_bus_init(pp, c, rport);
258+
gpio_disable_pulls(rport->pin_dp); // needs external pull-up
215259
rport->mode = PIO_USB_MODE_DEVICE;
216260

217261
memset(dev, 0, sizeof(*dev));
@@ -231,18 +275,18 @@ usb_device_t *pio_usb_device_init(const pio_usb_configuration_t *c,
231275
&pp->clk_div_fs_rx.div_frac);
232276

233277
pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_rx, rport->pin_dp);
278+
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
234279
SM_SET_CLKDIV_MAXSPEED(pp->pio_usb_rx, pp->sm_rx);
280+
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, true);
235281

236282
pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_eop, rport->pin_dm);
237283
pio_sm_set_in_pins(pp->pio_usb_rx, pp->sm_eop, rport->pin_dp);
284+
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_eop, false);
238285
SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_fs_rx);
239286

240287
descriptor_buffers = *buffers;
241288

242-
pio_sm_set_enabled(pp->pio_usb_tx, pp->sm_tx, true);
243289
pio_usb_bus_prepare_receive(pp);
244-
pp->pio_usb_rx->ctrl |= (1 << pp->sm_rx);
245-
pp->pio_usb_rx->irq |= IRQ_RX_ALL_MASK;
246290

247291
// configure PIOx_IRQ_0 to detect packet receive start
248292
pio_set_irqn_source_enabled(pp->pio_usb_rx, 0, pis_interrupt0 + IRQ_RX_START,
@@ -323,6 +367,12 @@ static void __no_inline_not_in_flash_func(prepare_ep0_rx)(uint8_t *data,
323367
}
324368

325369
void pio_usb_device_task(void) {
370+
root_port_t *rport = PIO_USB_ROOT_PORT(0);
371+
pio_port_t *pp = PIO_USB_PIO_PORT(0);
372+
if (rport->ints) {
373+
pio_usb_device_irq_handler(0);
374+
}
375+
326376
switch (ep0_desc_request_type) {
327377
case DESC_TYPE_CONFIG: {
328378
uint16_t req_len = ep0_desc_request_len;
@@ -348,8 +398,8 @@ void pio_usb_device_task(void) {
348398
break;
349399
}
350400

351-
root_port_t *rport = PIO_USB_ROOT_PORT(0);
352401
uint32_t se0_time_us =0;
402+
bool reset = false;
353403
while (pio_usb_bus_get_line_state(rport) == PORT_PIN_SE0) {
354404
busy_wait_us_32(1);
355405
se0_time_us++;
@@ -371,11 +421,14 @@ void pio_usb_device_task(void) {
371421
// TODO should be reset end, this is reset start only
372422
rport->ep_complete = rport->ep_stalled = rport->ep_error = 0;
373423
rport->ints |= PIO_USB_INTS_RESET_END_BITS;
374-
375-
pio_port_t *pp = PIO_USB_PIO_PORT(0);
376-
restart_usb_reveiver(pp);
424+
reset = true;
377425
}
378426
}
427+
if (reset) {
428+
restart_usb_receiver(pp);
429+
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_eop, true);
430+
pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
431+
}
379432
}
380433

381434
static void __no_inline_not_in_flash_func(configure_all_endpoints)(uint8_t const *desc) {
@@ -496,6 +549,17 @@ static void __no_inline_not_in_flash_func(__pio_usb_device_irq_handler)(uint8_t
496549
root->ep_complete &= ~ep_all;
497550
}
498551

552+
if (ints & PIO_USB_INTS_ENDPOINT_CONTINUE_BITS) {
553+
for (int b = 0; b < 16; b++) {
554+
if (root->ep_continue & (1 << b)) {
555+
endpoint_t *ep = PIO_USB_ENDPOINT((b << 1) | 0x01);
556+
uint16_t const xact_len = pio_usb_ll_get_transaction_len(ep);
557+
pio_usb_ll_transfer_continue(ep, xact_len);
558+
root->ep_continue &= ~(1 << b);
559+
}
560+
}
561+
}
562+
499563
// clear all
500564
root->ints &= ~ints;
501565
}

src/pio_usb_host.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ static int __no_inline_not_in_flash_func(usb_out_transaction)(pio_port_t *pp,
558558
pio_usb_bus_start_receive(pp);
559559

560560
pio_usb_bus_wait_handshake(pp);
561+
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
561562

562563
uint8_t const receive_token = pp->usb_rx_buffer[1];
563564

@@ -595,6 +596,7 @@ static int __no_inline_not_in_flash_func(usb_setup_transaction)(
595596
// Handshake
596597
pio_usb_bus_start_receive(pp);
597598
pio_usb_bus_wait_handshake(pp);
599+
pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
598600

599601
ep->actual_len = 8;
600602

src/pio_usb_ll.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum {
2020
PIO_USB_INTS_ENDPOINT_COMPLETE_POS,
2121
PIO_USB_INTS_ENDPOINT_ERROR_POS,
2222
PIO_USB_INTS_ENDPOINT_STALLED_POS,
23+
PIO_USB_INTS_ENDPOINT_CONTINUE_POS,
2324
};
2425

2526
#define PIO_USB_INTS_CONNECT_BITS (1u << PIO_USB_INTS_CONNECT_POS)
@@ -34,6 +35,8 @@ enum {
3435
#define PIO_USB_INTS_ENDPOINT_ERROR_BITS (1u << PIO_USB_INTS_ENDPOINT_ERROR_POS)
3536
#define PIO_USB_INTS_ENDPOINT_STALLED_BITS \
3637
(1u << PIO_USB_INTS_ENDPOINT_STALLED_POS)
38+
#define PIO_USB_INTS_ENDPOINT_CONTINUE_BITS \
39+
(1u << PIO_USB_INTS_ENDPOINT_CONTINUE_POS)
3740

3841
typedef enum {
3942
PORT_PIN_SE0 = 0b00,

src/usb_definitions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ typedef struct struct_root_port_t {
107107
volatile uint32_t ep_complete;
108108
volatile uint32_t ep_error;
109109
volatile uint32_t ep_stalled;
110+
volatile uint32_t ep_continue;
110111

111112
// device only
112113
uint8_t dev_addr;

0 commit comments

Comments
 (0)