/ src / pio_usb_host.c
pio_usb_host.c
  1  /**
  2   * Copyright (c) 2021 sekigon-gonnoc
  3   *                    Ha Thach (thach@tinyusb.org)
  4   */
  5  
  6  #pragma GCC push_options
  7  #pragma GCC optimize("-O3")
  8  
  9  #include <stdbool.h>
 10  #include <stdint.h>
 11  #include <stdio.h>
 12  #include <string.h>
 13  
 14  #include "hardware/sync.h"
 15  #include "hardware/pio.h"
 16  #include "hardware/gpio.h"
 17  
 18  #include "pio_usb.h"
 19  #include "pio_usb_ll.h"
 20  #include "usb_crc.h"
 21  #include "usb_rx.pio.h"
 22  #include "usb_tx.pio.h"
 23  
 24  static alarm_pool_t *_alarm_pool = NULL;
 25  static repeating_timer_t sof_rt;
 26  // The sof_count may be incremented and then read on different cores.
 27  static volatile uint32_t sof_count = 0;
 28  static bool timer_active;
 29  
 30  static volatile bool cancel_timer_flag;
 31  static volatile bool start_timer_flag;
 32  static __unused uint32_t int_stat;
 33  static uint8_t sof_packet[4] = {USB_SYNC, USB_PID_SOF, 0x00, 0x10};
 34  static uint8_t sof_packet_encoded[4 * 2 * 7 / 6 + 2];
 35  static uint8_t sof_packet_encoded_len;
 36  
 37  static bool sof_timer(repeating_timer_t *_rt);
 38  
 39  //--------------------------------------------------------------------+
 40  // Application API
 41  //--------------------------------------------------------------------+
 42  
 43  static void start_timer(alarm_pool_t *alarm_pool) {
 44    if (timer_active) {
 45      return;
 46    }
 47  
 48    if (alarm_pool != NULL) {
 49      alarm_pool_add_repeating_timer_us(alarm_pool, -1000, sof_timer, NULL,
 50                                        &sof_rt);
 51    }
 52  
 53    timer_active = true;
 54  }
 55  
 56  static __unused void stop_timer(void) {
 57    cancel_repeating_timer(&sof_rt);
 58    timer_active = false;
 59  }
 60  
 61  usb_device_t *pio_usb_host_init(const pio_usb_configuration_t *c) {
 62    pio_port_t *pp = PIO_USB_PIO_PORT(0);
 63    root_port_t *root = PIO_USB_ROOT_PORT(0);
 64  
 65    pio_usb_bus_init(pp, c, root);
 66    root->mode = PIO_USB_MODE_HOST;
 67  
 68    float const cpu_freq = (float)clock_get_hz(clk_sys);
 69    pio_calculate_clkdiv_from_float(cpu_freq / 48000000,
 70                                    &pp->clk_div_fs_tx.div_int,
 71                                    &pp->clk_div_fs_tx.div_frac);
 72    pio_calculate_clkdiv_from_float(cpu_freq / 6000000,
 73                                    &pp->clk_div_ls_tx.div_int,
 74                                    &pp->clk_div_ls_tx.div_frac);
 75  
 76    pio_calculate_clkdiv_from_float(cpu_freq / 96000000,
 77                                    &pp->clk_div_fs_rx.div_int,
 78                                    &pp->clk_div_fs_rx.div_frac);
 79    pio_calculate_clkdiv_from_float(cpu_freq / 12000000,
 80                                    &pp->clk_div_ls_rx.div_int,
 81                                    &pp->clk_div_ls_rx.div_frac);
 82  
 83    sof_packet_encoded_len =
 84        pio_usb_ll_encode_tx_data(sof_packet, sizeof(sof_packet), sof_packet_encoded);
 85  
 86    if (!c->skip_alarm_pool) {
 87      _alarm_pool = c->alarm_pool;
 88      if (!_alarm_pool) {
 89        _alarm_pool = alarm_pool_create(2, 1);
 90      }
 91    }
 92    start_timer(_alarm_pool);
 93  
 94    return &pio_usb_device[0];
 95  }
 96  
 97  void pio_usb_host_stop(void) {
 98    cancel_timer_flag = true;
 99    while (cancel_timer_flag) {
100      continue;
101    }
102  }
103  
104  void pio_usb_host_restart(void) {
105    start_timer_flag = true;
106    while (start_timer_flag) {
107      continue;
108    }
109  }
110  
111  //--------------------------------------------------------------------+
112  // Bus functions
113  //--------------------------------------------------------------------+
114  
115  static void __no_inline_not_in_flash_func(override_pio_program)(PIO pio, const pio_program_t* program, uint offset) {
116      for (uint i = 0; i < program->length; ++i) {
117        uint16_t instr = program->instructions[i];
118        pio->instr_mem[offset + i] =
119            pio_instr_bits_jmp != _pio_major_instr_bits(instr) ? instr
120                                                               : instr + offset;
121      }
122  }
123  
124  static __always_inline void override_pio_rx_program(PIO pio,
125                                               const pio_program_t *program,
126                                               const pio_program_t *debug_program,
127                                               uint offset, int debug_pin) {
128    if (debug_pin < 0) {
129      override_pio_program(pio, program, offset);
130    } else {
131      override_pio_program(pio, debug_program, offset);
132    }
133  }
134  
135  static void
136  __no_inline_not_in_flash_func(configure_tx_program)(pio_port_t *pp,
137                                                      root_port_t *port) {
138    if (port->pinout == PIO_USB_PINOUT_DPDM) {
139      pp->fs_tx_program = &usb_tx_dpdm_program;
140      pp->fs_tx_pre_program = &usb_tx_pre_dpdm_program;
141      pp->ls_tx_program = &usb_tx_dmdp_program;
142    } else {
143      pp->fs_tx_program = &usb_tx_dmdp_program;
144      pp->fs_tx_pre_program = &usb_tx_pre_dmdp_program;
145      pp->ls_tx_program = &usb_tx_dpdm_program;
146    }
147  }
148  
149  static void __no_inline_not_in_flash_func(configure_fullspeed_host)(
150      pio_port_t *pp, root_port_t *port) {
151    configure_tx_program(pp, port);
152    pio_sm_clear_fifos(pp->pio_usb_tx, pp->sm_tx);
153    override_pio_program(pp->pio_usb_tx, pp->fs_tx_program, pp->offset_tx);
154    SM_SET_CLKDIV(pp->pio_usb_tx, pp->sm_tx, pp->clk_div_fs_tx);
155    usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp, port->pin_dm);
156    pio_sm_exec(pp->pio_usb_tx, pp->sm_tx, pp->tx_reset_instr);
157  
158    pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_rx, port->pin_dp);
159    SM_SET_CLKDIV_MAXSPEED(pp->pio_usb_rx, pp->sm_rx);
160  
161    pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_eop, port->pin_dm);
162    pio_sm_set_in_pins(pp->pio_usb_rx, pp->sm_eop, port->pin_dp);
163    SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_fs_rx);
164  }
165  
166  static void __no_inline_not_in_flash_func(configure_lowspeed_host)(
167      pio_port_t *pp, root_port_t *port) {
168    configure_tx_program(pp, port);
169    pio_sm_clear_fifos(pp->pio_usb_tx, pp->sm_tx);
170    override_pio_program(pp->pio_usb_tx, pp->ls_tx_program, pp->offset_tx);
171    SM_SET_CLKDIV(pp->pio_usb_tx, pp->sm_tx, pp->clk_div_ls_tx);
172    usb_tx_configure_pins(pp->pio_usb_tx, pp->sm_tx, port->pin_dp, port->pin_dm);
173    pio_sm_exec(pp->pio_usb_tx, pp->sm_tx, pp->tx_reset_instr);
174  
175    pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_rx, port->pin_dm);
176    SM_SET_CLKDIV_MAXSPEED(pp->pio_usb_rx, pp->sm_rx);
177  
178    pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_eop, port->pin_dp);
179    pio_sm_set_in_pins(pp->pio_usb_rx, pp->sm_eop, port->pin_dm);
180    SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_ls_rx);
181  }
182  
183  static void __no_inline_not_in_flash_func(configure_root_port)(
184      pio_port_t *pp, root_port_t *root) {
185    if (root->is_fullspeed) {
186      configure_fullspeed_host(pp, root);
187    } else {
188      configure_lowspeed_host(pp, root);
189    }
190  }
191  
192  static void __no_inline_not_in_flash_func(restore_fs_bus)(const pio_port_t *pp) {
193    // change bus speed to full-speed
194    pio_sm_set_enabled(pp->pio_usb_tx, pp->sm_tx, false);
195    SM_SET_CLKDIV(pp->pio_usb_tx, pp->sm_tx, pp->clk_div_fs_tx);
196    pio_sm_set_enabled(pp->pio_usb_tx, pp->sm_tx, true);
197  
198    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
199    SM_SET_CLKDIV_MAXSPEED(pp->pio_usb_rx, pp->sm_rx);
200    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, true);
201  
202    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_eop, false);
203    SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_fs_rx);
204    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_eop, true);
205  }
206  
207  // Time about 1us ourselves so it lives in RAM.
208  static void __not_in_flash_func(busy_wait_1_us)(void) {
209    uint32_t start = timer_hw->timerawl;
210    while (timer_hw->timerawl == start) {
211        tight_loop_contents();
212    }
213  }
214  
215  static bool __no_inline_not_in_flash_func(connection_check)(root_port_t *port) {
216    if (pio_usb_bus_get_line_state(port) == PORT_PIN_SE0) {
217      busy_wait_1_us();
218  
219      if (pio_usb_bus_get_line_state(port) == PORT_PIN_SE0) {
220        busy_wait_1_us();
221        // device disconnect
222        port->connected = false;
223        port->suspended = true;
224        port->ints |= PIO_USB_INTS_DISCONNECT_BITS;
225  
226        // failed/retired all queuing transfer in this root
227        uint8_t root_idx = port - PIO_USB_ROOT_PORT(0);
228        for (int ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) {
229          endpoint_t *ep = PIO_USB_ENDPOINT(ep_idx);
230          if ((ep->root_idx == root_idx) && ep->size && ep->has_transfer) {
231            pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_ERROR_BITS);
232          }
233        }
234  
235        return false;
236      }
237    }
238  
239    return true;
240  }
241  
242  //--------------------------------------------------------------------+
243  // SOF
244  //--------------------------------------------------------------------+
245  static int usb_setup_transaction(pio_port_t *pp, endpoint_t *ep);
246  static int usb_in_transaction(pio_port_t *pp, endpoint_t *ep);
247  static int usb_out_transaction(pio_port_t *pp, endpoint_t *ep);
248  
249  void __not_in_flash_func(pio_usb_host_frame)(void) {
250    if (!timer_active) {
251      return;
252    }
253  
254    pio_port_t *pp = PIO_USB_PIO_PORT(0);
255  
256    // Send SOF
257    for (int root_idx = 0; root_idx < PIO_USB_ROOT_PORT_CNT; root_idx++) {
258      root_port_t *root = PIO_USB_ROOT_PORT(root_idx);
259      if (!(root->initialized && root->connected && !root->suspended &&
260            connection_check(root))) {
261        continue;
262      }
263      configure_root_port(pp, root);
264      pio_usb_bus_usb_transfer(pp, sof_packet_encoded, sof_packet_encoded_len);
265    }
266  
267    // Carry out all queued endpoint transaction
268    for (int root_idx = 0; root_idx < PIO_USB_ROOT_PORT_CNT; root_idx++) {
269      root_port_t *root = PIO_USB_ROOT_PORT(root_idx);
270      if (!(root->initialized && root->connected && !root->suspended)) {
271        continue;
272      }
273  
274      configure_root_port(pp, root);
275  
276      for (int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT;
277           ep_pool_idx++) {
278        endpoint_t *ep = PIO_USB_ENDPOINT(ep_pool_idx);
279        if ((ep->root_idx == root_idx) && ep->size) {
280          bool const is_periodic = ((ep->attr & 0x03) == EP_ATTR_INTERRUPT);
281  
282          if (is_periodic && (ep->interval_counter > 0)) {
283            ep->interval_counter--;
284            continue;
285          }
286  
287          if (ep->has_transfer && !ep->transfer_aborted) {
288            ep->transfer_started = true;
289  
290            if (ep->need_pre) {
291              pp->need_pre = true;
292            }
293  
294            if (ep->ep_num == 0 && ep->data_id == USB_PID_SETUP) {
295              usb_setup_transaction(pp, ep);
296            } else {
297              if (ep->ep_num & EP_IN) {
298                usb_in_transaction(pp, ep);
299              } else {
300                usb_out_transaction(pp, ep);
301              }
302  
303              if (is_periodic) {
304                ep->interval_counter = ep->interval - 1;
305              }
306            }
307  
308            if (ep->need_pre) {
309              pp->need_pre = false;
310              restore_fs_bus(pp);
311            }
312  
313            ep->transfer_started = false;
314          }
315        }
316      }
317    }
318  
319    // check for new connection to root hub
320    for (int root_idx = 0; root_idx < PIO_USB_ROOT_PORT_CNT; root_idx++) {
321      root_port_t *root = PIO_USB_ROOT_PORT(root_idx);
322      if (root->initialized && !root->connected) {
323        port_pin_status_t const line_state = pio_usb_bus_get_line_state(root);
324        if (line_state == PORT_PIN_FS_IDLE || line_state == PORT_PIN_LS_IDLE) {
325          root->is_fullspeed = (line_state == PORT_PIN_FS_IDLE);
326          root->connected = true;
327          root->suspended = true; // need a bus reset before operating
328          root->ints |= PIO_USB_INTS_CONNECT_BITS;
329        }
330      }
331    }
332  
333    // Invoke IRQHandler if interrupt status is set
334    for (uint8_t root_idx = 0; root_idx < PIO_USB_ROOT_PORT_CNT; root_idx++) {
335      if (PIO_USB_ROOT_PORT(root_idx)->ints) {
336        pio_usb_host_irq_handler(root_idx);
337      }
338    }
339  
340    sof_count++;
341  
342    // SOF counter is 11-bit
343    uint16_t const sof_count_11b = sof_count & 0x7ff;
344    sof_packet[2] = sof_count_11b & 0xff;
345    sof_packet[3] = (calc_usb_crc5(sof_count_11b) << 3) | (sof_count_11b >> 8);
346    sof_packet_encoded_len =
347        pio_usb_ll_encode_tx_data(sof_packet, sizeof(sof_packet), sof_packet_encoded);
348  }
349  
350  static bool __no_inline_not_in_flash_func(sof_timer)(repeating_timer_t *_rt) {
351    (void)_rt;
352  
353    pio_usb_host_frame();
354  
355    return true;
356  }
357  
358  //--------------------------------------------------------------------+
359  // Host Controller functions
360  //--------------------------------------------------------------------+
361  
362  uint32_t pio_usb_host_get_frame_number(void) {
363    return sof_count;
364  }
365  
366  void pio_usb_host_port_reset_start(uint8_t root_idx) {
367    root_port_t *root = PIO_USB_ROOT_PORT(root_idx);
368  
369    // bus is not operating while in reset
370    root->suspended = true;
371  
372    // Force line state to SE0
373    gpio_set_outover(root->pin_dp,  GPIO_OVERRIDE_LOW);
374    gpio_set_outover(root->pin_dm,  GPIO_OVERRIDE_LOW);
375    gpio_set_oeover(root->pin_dp,  GPIO_OVERRIDE_HIGH);
376    gpio_set_oeover(root->pin_dm,  GPIO_OVERRIDE_HIGH);
377  }
378  
379  void pio_usb_host_port_reset_end(uint8_t root_idx) {
380    root_port_t *root = PIO_USB_ROOT_PORT(root_idx);
381  
382    // line state to input
383    gpio_set_oeover(root->pin_dp,  GPIO_OVERRIDE_NORMAL);
384    gpio_set_oeover(root->pin_dm,  GPIO_OVERRIDE_NORMAL);
385    gpio_set_outover(root->pin_dp,  GPIO_OVERRIDE_NORMAL);
386    gpio_set_outover(root->pin_dm,  GPIO_OVERRIDE_NORMAL);
387    busy_wait_us(100); // TODO check if this is neccessary
388  
389    // bus back to operating
390    root->suspended = false;
391  }
392  
393  void pio_usb_host_close_device(uint8_t root_idx, uint8_t device_address) {
394    for (int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; ep_pool_idx++) {
395      endpoint_t *ep = PIO_USB_ENDPOINT(ep_pool_idx);
396      if ((ep->root_idx == root_idx) && (ep->dev_addr == device_address) &&
397          ep->size) {
398        ep->size = 0;
399        ep->has_transfer = false;
400      }
401    }
402  }
403  
404  static inline __force_inline endpoint_t * _find_ep(uint8_t root_idx, 
405                                                     uint8_t device_address, uint8_t ep_address) {
406    for (int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; ep_pool_idx++) {
407      endpoint_t *ep = PIO_USB_ENDPOINT(ep_pool_idx);
408      // note 0x00 and 0x80 are matched as control endpoint of opposite direction
409      if ((ep->root_idx == root_idx) && (ep->dev_addr == device_address) &&
410          ep->size &&
411          ((ep->ep_num == ep_address) ||
412           (((ep_address & 0x7f) == 0) && ((ep->ep_num & 0x7f) == 0)))) {
413        return ep;
414      }
415    }
416  
417    return NULL;
418  }
419  
420  bool pio_usb_host_endpoint_open(uint8_t root_idx, uint8_t device_address,
421                                  uint8_t const *desc_endpoint, bool need_pre) {
422    const endpoint_descriptor_t *d = (const endpoint_descriptor_t *)desc_endpoint;
423    for (int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; ep_pool_idx++) {
424      endpoint_t *ep = PIO_USB_ENDPOINT(ep_pool_idx);
425      // ep size is used as valid indicator
426      if (ep->size == 0) {
427        pio_usb_ll_configure_endpoint(ep, desc_endpoint);
428        ep->root_idx = root_idx;
429        ep->dev_addr = device_address;
430        ep->need_pre = need_pre;
431        ep->is_tx = (d->epaddr & 0x80) ? false : true; // host endpoint out is tx
432        return true;
433      }
434    }
435  
436    return false;
437  }
438  
439  bool pio_usb_host_send_setup(uint8_t root_idx, uint8_t device_address,
440                               uint8_t const setup_packet[8]) {
441    endpoint_t *ep = _find_ep(root_idx, device_address, 0);
442    if (!ep) {
443      printf("cannot find ep 0x00\r\n");
444      return false;
445    }
446  
447    ep->ep_num = 0; // setup is is OUT
448    ep->data_id = USB_PID_SETUP;
449    ep->is_tx = true;
450  
451    return pio_usb_ll_transfer_start(ep, (uint8_t *)setup_packet, 8);
452  }
453  
454  bool pio_usb_host_endpoint_transfer(uint8_t root_idx, uint8_t device_address,
455                                      uint8_t ep_address, uint8_t *buffer,
456                                      uint16_t buflen) {
457    endpoint_t *ep = _find_ep(root_idx, device_address, ep_address);
458    if (!ep) {
459      printf("no endpoint 0x%02X\r\n", ep_address);
460      return false;
461    }
462  
463    // Control endpoint, address may switch between 0x00 <-> 0x80
464    // therefore we need to update ep_num and is_tx
465    if ((ep_address & 0x7f) == 0) {
466      ep->ep_num = ep_address;
467      ep->is_tx = ep_address == 0;
468      ep->data_id = 1; // data and status always start with DATA1
469    }
470  
471    return pio_usb_ll_transfer_start(ep, buffer, buflen);
472  }
473  
474  bool pio_usb_host_endpoint_abort_transfer(uint8_t root_idx, uint8_t device_address,
475                                            uint8_t ep_address) {
476    endpoint_t *ep = _find_ep(root_idx, device_address, ep_address);
477    if (!ep) {
478      printf("no endpoint 0x%02X\r\n", ep_address);
479      return false;
480    }
481  
482    if (!ep->has_transfer) {
483      return false; // no transfer to abort
484    }
485  
486    // mark transfer as aborted
487    ep->transfer_aborted = true;
488  
489    // Race potential: SOF timer can be called before transfer_aborted is actually set
490    // and started the transfer. Wait 1 usb frame for transaction to complete.
491    // On the next SOF timer, transfer_aborted will be checked and skipped
492    while (ep->has_transfer && ep->transfer_started) {
493      busy_wait_ms(1);
494    }
495  
496    // check if transfer is still active (could be completed)
497    bool const still_active = ep->has_transfer;
498    if (still_active) {
499      ep->has_transfer = false;
500    }
501    ep->transfer_aborted = false;
502  
503    return still_active; // still active means transfer is successfully aborted
504  }
505  
506  //--------------------------------------------------------------------+
507  // Transaction helper
508  //--------------------------------------------------------------------+
509  
510  static int __no_inline_not_in_flash_func(usb_in_transaction)(pio_port_t *pp,
511                                                               endpoint_t *ep) {
512    int res = 0;
513    uint8_t expect_pid = (ep->data_id == 1) ? USB_PID_DATA1 : USB_PID_DATA0;
514  
515    pio_usb_bus_prepare_receive(pp);
516    pio_usb_bus_send_token(pp, USB_PID_IN, ep->dev_addr, ep->ep_num);
517    pio_usb_bus_start_receive(pp);
518  
519    int receive_len = pio_usb_bus_receive_packet_and_handshake(pp, USB_PID_ACK);
520    uint8_t const receive_pid = pp->usb_rx_buffer[1];
521  
522    if (receive_len >= 0) {
523      if (receive_pid == expect_pid) {
524        memcpy(ep->app_buf, &pp->usb_rx_buffer[2], receive_len);
525        pio_usb_ll_transfer_continue(ep, receive_len);
526      } else {
527        // DATA0/1 mismatched, 0 for re-try next frame
528      }
529    } else if (receive_pid == USB_PID_NAK) {
530      // NAK try again next frame
531    } else if (receive_pid == USB_PID_STALL) {
532      pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_STALLED_BITS);
533    } else {
534      res = -1;
535      if ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
536        res = -2;
537      }
538      pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_ERROR_BITS);
539    }
540  
541    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
542    pp->usb_rx_buffer[0] = 0;
543    pp->usb_rx_buffer[1] = 0;
544  
545    return res;
546  }
547  
548  static int __no_inline_not_in_flash_func(usb_out_transaction)(pio_port_t *pp,
549                                                                endpoint_t *ep) {
550    int res = 0;
551  
552    uint16_t const xact_len = pio_usb_ll_get_transaction_len(ep);
553  
554    pio_usb_bus_prepare_receive(pp);
555    pio_usb_bus_send_token(pp, USB_PID_OUT, ep->dev_addr, ep->ep_num);
556  
557    pio_usb_bus_usb_transfer(pp, ep->buffer, ep->encoded_data_len);
558    pio_usb_bus_start_receive(pp);
559  
560    pio_usb_bus_wait_handshake(pp);
561    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
562  
563    uint8_t const receive_token = pp->usb_rx_buffer[1];
564  
565    if (receive_token == USB_PID_ACK) {
566      pio_usb_ll_transfer_continue(ep, xact_len);
567    } else if (receive_token == USB_PID_NAK) {
568      // NAK try again next frame
569    } else if (receive_token == USB_PID_STALL) {
570      pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_STALLED_BITS);
571    } else {
572      pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_ERROR_BITS);
573    }
574  
575    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
576    pp->usb_rx_buffer[0] = 0;
577    pp->usb_rx_buffer[1] = 0;
578  
579    return res;
580  }
581  
582  static int __no_inline_not_in_flash_func(usb_setup_transaction)(
583      pio_port_t *pp,  endpoint_t *ep) {
584  
585    int res = 0;
586  
587    // Setup token
588    pio_usb_bus_prepare_receive(pp);
589  
590    pio_usb_bus_send_token(pp, USB_PID_SETUP, ep->dev_addr, 0);
591  
592    // Data
593    ep->data_id = 0; // set to DATA0
594    pio_usb_bus_usb_transfer(pp, ep->buffer, ep->encoded_data_len);
595  
596    // Handshake
597    pio_usb_bus_start_receive(pp);
598    pio_usb_bus_wait_handshake(pp);
599    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, false);
600  
601    ep->actual_len = 8;
602  
603    if (pp->usb_rx_buffer[0] == USB_SYNC && pp->usb_rx_buffer[1] == USB_PID_ACK) {
604      pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS);
605    } else {
606      res = -1;
607      pio_usb_ll_transfer_complete(ep, PIO_USB_INTS_ENDPOINT_ERROR_BITS);
608    }
609  
610    pp->usb_rx_buffer[1] = 0; // reset buffer
611  
612    return res;
613  }
614  
615  
616  static void __no_inline_not_in_flash_func(handle_endpoint_irq)(
617      root_port_t *root, uint32_t flag, volatile uint32_t *ep_reg) {
618    (void)root;
619    const uint32_t ep_all = *ep_reg;
620  
621    for (uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++) {
622      if (ep_all & (1u << ep_idx)) {
623        endpoint_t *ep = PIO_USB_ENDPOINT(ep_idx);
624        usb_device_t *device = NULL;
625  
626        // find device this endpoint belongs to
627        for (int idx = 0; idx < PIO_USB_DEVICE_CNT; idx++) {
628          usb_device_t *dev = &pio_usb_device[idx];
629          if (dev->connected && (ep->dev_addr == dev->address)) {
630            device = dev;
631            break;
632          }
633        }
634  
635        if (device) {
636          // control endpoint is either 0x00 or 0x80
637          if ((ep->ep_num & 0x7f) == 0) {
638            control_pipe_t *pipe = &device->control_pipe;
639  
640            if (flag != PIO_USB_INTS_ENDPOINT_COMPLETE_BITS) {
641              pipe->stage = STAGE_SETUP;
642              pipe->operation = CONTROL_ERROR;
643            } else {
644              ep->data_id = 1; // both data and status have DATA1
645              if (pipe->stage == STAGE_SETUP) {
646                if (pipe->operation == CONTROL_IN) {
647                  pipe->stage = STAGE_IN;
648                  ep->ep_num = 0x80;
649                  ep->is_tx = false;
650                  pio_usb_ll_transfer_start(ep,
651                                            (uint8_t *)(uintptr_t)pipe->rx_buffer,
652                                            pipe->request_length);
653                } else if (pipe->operation == CONTROL_OUT) {
654                  if (pipe->out_data_packet.tx_address != NULL) {
655                    pipe->stage = STAGE_OUT;
656                    ep->ep_num = 0x00;
657                    ep->is_tx = true;
658                    pio_usb_ll_transfer_start(ep,
659                                              pipe->out_data_packet.tx_address,
660                                              pipe->out_data_packet.tx_length);
661                  } else {
662                    pipe->stage = STAGE_STATUS;
663                    ep->ep_num = 0x80;
664                    ep->is_tx = false;
665                    pio_usb_ll_transfer_start(ep, NULL, 0);
666                  }
667                }
668              } else if (pipe->stage == STAGE_IN) {
669                pipe->stage = STAGE_STATUS;
670                ep->ep_num = 0x00;
671                ep->is_tx = true;
672                pio_usb_ll_transfer_start(ep, NULL, 0);
673              } else if (pipe->stage == STAGE_OUT) {
674                pipe->stage = STAGE_STATUS;
675                ep->ep_num = 0x80;
676                ep->is_tx = false;
677                pio_usb_ll_transfer_start(ep, NULL, 0);
678              } else if (pipe->stage == STAGE_STATUS) {
679                pipe->stage = STAGE_SETUP;
680                pipe->operation = CONTROL_COMPLETE;
681              }
682            }
683          } else if (device->device_class == CLASS_HUB && (ep->ep_num & EP_IN)) {
684            // hub interrupt endpoint
685            device->event = EVENT_HUB_PORT_CHANGE;
686          }
687        }
688      }
689    }
690  
691    // clear all
692    (*ep_reg) &= ~ep_all;
693  }
694  
695  // IRQ Handler
696  static void __no_inline_not_in_flash_func(__pio_usb_host_irq_handler)(uint8_t root_id) {
697    root_port_t *root = PIO_USB_ROOT_PORT(root_id);
698    uint32_t const ints = root->ints;
699  
700    if (ints & PIO_USB_INTS_CONNECT_BITS) {
701      root->event = EVENT_CONNECT;
702    }
703  
704    if (ints & PIO_USB_INTS_DISCONNECT_BITS) {
705      root->event = EVENT_DISCONNECT;
706    }
707  
708    if (ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS) {
709      handle_endpoint_irq(root, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS,
710                          &root->ep_complete);
711    }
712  
713    if (ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS) {
714      handle_endpoint_irq(root, PIO_USB_INTS_ENDPOINT_STALLED_BITS,
715                          &root->ep_stalled);
716    }
717  
718    if (ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS) {
719      handle_endpoint_irq(root, PIO_USB_INTS_ENDPOINT_ERROR_BITS,
720                          &root->ep_error);
721    }
722  
723    // clear all
724    root->ints &= ~ints;
725  }
726  
727  // weak alias to __pio_usb_host_irq_handler
728  void pio_usb_host_irq_handler(uint8_t root_id) __attribute__ ((weak, alias("__pio_usb_host_irq_handler")));
729  
730  #pragma GCC pop_options