/ src / pio_usb_device.c
pio_usb_device.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 "pio_usb.h"
 15  #include "pio_usb_ll.h"
 16  #include "usb_crc.h"
 17  
 18  #include "usb_rx.pio.h"
 19  #include "usb_tx.pio.h"
 20  
 21  #include "hardware/dma.h"
 22  #include "hardware/irq.h"
 23  #include "hardware/gpio.h"
 24  #include "hardware/pio.h"
 25  
 26  static uint8_t new_devaddr = 0;
 27  static uint8_t ep0_crc5_lut[16];
 28  static __unused usb_descriptor_buffers_t descriptor_buffers;
 29  
 30  static uint8_t nak_encoded[5];
 31  static uint8_t stall_encoded[5];
 32  
 33  static void __no_inline_not_in_flash_func(update_ep0_crc5_lut)(uint8_t addr) {
 34    uint16_t dat;
 35    uint8_t crc;
 36  
 37    for (int epnum = 0; epnum < 16; epnum++) {
 38      dat = (addr) | (epnum << 7);
 39      crc = calc_usb_crc5(dat);
 40      ep0_crc5_lut[epnum] = (crc << 3) | ((epnum >> 1) & 0x07);
 41    }
 42  }
 43  
 44  static __always_inline void restart_usb_receiver(pio_port_t *pp) {
 45    pio_sm_exec(pp->pio_usb_rx, pp->sm_rx, pp->rx_reset_instr2);
 46    pio_sm_restart(pp->pio_usb_rx, pp->sm_rx);
 47    pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
 48  }
 49  
 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) {
 74    pio_port_t *pp = PIO_USB_PIO_PORT(0);
 75    uint8_t idx = 0;
 76    uint8_t addr;
 77    uint8_t ep;
 78    uint8_t ep_num = 0;
 79    uint8_t buffer[3];
 80    bool match = false;
 81  
 82    static uint8_t eplut[2][8] = {{0, 2, 4, 6, 8, 10, 12, 14},
 83                                  {1, 3, 5, 7, 9, 11, 13, 15}};
 84    uint8_t *current_lut;
 85  
 86    if ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
 87      while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) {
 88        if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) {
 89          buffer[idx++] = pio_sm_get(pp->pio_usb_rx, pp->sm_rx) >> 24;
 90          if ((idx == 1) && (token != USB_PID_SOF)) {
 91            addr = buffer[0] & 0x7f;
 92            current_lut = &eplut[buffer[0] >> 7][0];
 93            match = dev_addr == addr ? true : false;
 94          } else if (idx == 2) {
 95            ep_num = buffer[1];
 96            break;
 97          }
 98        }
 99      }
100    } else {
101      // host is probably timeout. Ignore this packets.
102      pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
103    }
104  
105    if (match) {
106      ep = current_lut[ep_num & 0x07];
107      if (ep0_crc5_lut[ep] == ep_num) {
108        return ep;
109      } else {
110        return -1;
111      }
112    }
113  
114    return -1;
115  }
116  
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  
124  static void __no_inline_not_in_flash_func(usb_device_packet_handler)(void) {
125    pio_port_t *pp = PIO_USB_PIO_PORT(0);
126    root_port_t *rport = PIO_USB_ROOT_PORT(0);
127  
128    gpio_clr_mask(1<<3);
129    //
130    // time critical start
131    //
132    uint8_t addr = rport->dev_addr;
133    uint8_t token = device_receive_token();
134  
135    if (token == USB_PID_IN) {
136      int8_t ep_num = device_receive_ep_address(token, addr);
137      if (ep_num < 0) {
138        gpio_set_mask(1 << 3);
139        return;
140      }
141  
142      endpoint_t *ep = PIO_USB_ENDPOINT((ep_num << 1) | 0x01);
143  
144      pio_sm_exec(pp->pio_usb_tx, pp->sm_tx, pp->tx_start_instr);
145      volatile bool has_transfer = ep->has_transfer;
146  
147      if (has_transfer) {
148        dma_channel_transfer_from_buffer_now(pp->tx_ch, ep->buffer, ep->encoded_data_len);
149      } else if (ep->stalled) {
150        dma_channel_transfer_from_buffer_now(pp->tx_ch, stall_encoded, sizeof(stall_encoded));
151      } else {
152        dma_channel_transfer_from_buffer_now(pp->tx_ch, nak_encoded, sizeof(nak_encoded));
153      }
154  
155      pp->pio_usb_tx->irq = IRQ_TX_ALL_MASK; // clear complete flag
156      while ((pp->pio_usb_tx->irq & IRQ_TX_ALL_MASK) == 0) {
157        continue;
158      }
159  
160      if (has_transfer) {
161        pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
162        irq_clear(pp->device_rx_irq_num);
163        pio_usb_bus_start_receive(pp);
164  
165        // wait for ack
166        pio_usb_bus_wait_handshake(pp);
167  
168        pio_usb_bus_start_receive(pp);
169        irq_clear(pp->device_rx_irq_num);
170  
171        //
172        // time critical end
173        //
174  
175        if (ep->ep_num == 0x80 && new_devaddr > 0) {
176          rport->dev_addr = new_devaddr;
177          new_devaddr = 0;
178          update_ep0_crc5_lut(rport->dev_addr);
179        }
180  
181        rport->ints |= PIO_USB_INTS_ENDPOINT_CONTINUE_BITS;
182        rport->ep_continue |= (1 << ep_num);
183      } else {
184        pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
185        irq_clear(pp->device_rx_irq_num);
186        restart_usb_receiver(pp);
187        pio_usb_bus_start_receive(pp);
188  
189        //
190        // time critical end
191        //
192      }
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);
197      if (ep_num < 0) {
198        return;
199      }
200      endpoint_t *ep = PIO_USB_ENDPOINT(ep_num << 1);
201  
202    gpio_clr_mask(1<<4);
203      uint8_t hanshake = ep->stalled
204                             ? USB_PID_STALL
205                             : (ep->has_transfer ? USB_PID_ACK : USB_PID_NAK);
206      int res = pio_usb_bus_receive_packet_and_handshake(pp, hanshake);
207      pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
208      restart_usb_receiver(pp);
209      pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
210      irq_clear(pp->device_rx_irq_num);
211  
212      if (ep->has_transfer) {
213        if (res >= 0) {
214          memcpy(ep->app_buf, pp->usb_rx_buffer + 2, res);
215          pio_usb_ll_transfer_continue(ep, res);
216        }
217      }
218    } else if (token == USB_PID_SETUP) {
219      int8_t ep_num = device_receive_ep_address(token, addr);
220      restart_usb_receiver(pp);
221      if (ep_num < 0) {
222        return;
223      }
224      int res = pio_usb_bus_receive_packet_and_handshake(pp, USB_PID_ACK);
225      pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
226      restart_usb_receiver(pp);
227      pp->pio_usb_rx->irq = IRQ_RX_ALL_MASK;
228      irq_clear(pp->device_rx_irq_num);
229  
230      if (res >= 0) {
231        rport->setup_packet = pp->usb_rx_buffer + 2;
232        rport->ints |= PIO_USB_INTS_SETUP_REQ_BITS;
233  
234        // DATA1 for both data and status stage
235        PIO_USB_ENDPOINT(0)->has_transfer = PIO_USB_ENDPOINT(1)->has_transfer = false;
236        PIO_USB_ENDPOINT(0)->data_id = PIO_USB_ENDPOINT(1)->data_id = 1;
237        PIO_USB_ENDPOINT(0)->stalled = PIO_USB_ENDPOINT(1)->stalled = false;
238      }
239    } else if (token == USB_PID_SOF) {
240      // SOF interrupt
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);
248    }
249  }
250  
251  usb_device_t *pio_usb_device_init(const pio_usb_configuration_t *c,
252                                    const usb_descriptor_buffers_t *buffers) {
253    pio_port_t *pp = PIO_USB_PIO_PORT(0);
254    root_port_t *rport = PIO_USB_ROOT_PORT(0);
255    usb_device_t *dev = &pio_usb_device[0];
256  
257    pio_usb_bus_init(pp, c, rport);
258    gpio_disable_pulls(rport->pin_dp); // needs external pull-up 
259    rport->mode = PIO_USB_MODE_DEVICE;
260  
261    memset(dev, 0, sizeof(*dev));
262    for (int i = 0; i < PIO_USB_DEV_EP_CNT; i++) {
263      dev->endpoint_id[i] = 2 * (i + 1); // only index IN endpoint
264    }
265  
266    update_ep0_crc5_lut(rport->dev_addr);
267  
268    float const cpu_freq = (float)clock_get_hz(clk_sys);
269  
270    pio_calculate_clkdiv_from_float(cpu_freq / 48000000,
271                                    &pp->clk_div_fs_tx.div_int,
272                                    &pp->clk_div_fs_tx.div_frac);
273    pio_calculate_clkdiv_from_float(cpu_freq / 96000000,
274                                    &pp->clk_div_fs_rx.div_int,
275                                    &pp->clk_div_fs_rx.div_frac);
276  
277    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);
279    SM_SET_CLKDIV_MAXSPEED(pp->pio_usb_rx, pp->sm_rx);
280    pio_sm_set_enabled(pp->pio_usb_rx, pp->sm_rx, true);
281  
282    pio_sm_set_jmp_pin(pp->pio_usb_rx, pp->sm_eop, rport->pin_dm);
283    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);
285    SM_SET_CLKDIV(pp->pio_usb_rx, pp->sm_eop, pp->clk_div_fs_rx);
286  
287    descriptor_buffers = *buffers;
288  
289    pio_usb_bus_prepare_receive(pp);
290  
291    // configure PIOx_IRQ_0 to detect packet receive start
292    pio_set_irqn_source_enabled(pp->pio_usb_rx, 0, pis_interrupt0 + IRQ_RX_START,
293                                true);
294    pp->device_rx_irq_num = PIO_IRQ_NUM(pp->pio_usb_rx, 0);
295    irq_set_exclusive_handler(pp->device_rx_irq_num, usb_device_packet_handler);
296    irq_set_enabled(pp->device_rx_irq_num, true);
297  
298  
299    // pre-encode handshake packets
300    uint8_t raw_packet[] = {USB_SYNC, USB_PID_NAK};
301    pio_usb_ll_encode_tx_data(raw_packet, 2, nak_encoded);
302    raw_packet[1] = USB_PID_STALL;
303    pio_usb_ll_encode_tx_data(raw_packet, 2, stall_encoded);
304  
305    return dev;
306  }
307  
308  //--------------------------------------------------------------------+
309  // Device Controller functions
310  //--------------------------------------------------------------------+
311  
312  void pio_usb_device_set_address(uint8_t dev_addr) {
313    new_devaddr = dev_addr;
314  }
315  
316  bool __no_inline_not_in_flash_func(pio_usb_device_endpoint_open)(
317      uint8_t const *desc_endpoint) {
318    const endpoint_descriptor_t *d = (const endpoint_descriptor_t *)desc_endpoint;
319    endpoint_t *ep = pio_usb_device_get_endpoint_by_address(d->epaddr);
320  
321    pio_usb_ll_configure_endpoint(ep, desc_endpoint);
322    ep->root_idx = 0;
323    ep->dev_addr = 0; // not used
324    ep->need_pre = 0;
325    ep->is_tx = (d->epaddr & 0x80) ? true : false; // device: endpoint in is tx
326  
327    return true;
328  }
329  
330  bool pio_usb_device_transfer(uint8_t ep_address, uint8_t *buffer,
331                               uint16_t buflen) {
332    endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_address);
333    return pio_usb_ll_transfer_start(ep, buffer, buflen);
334  }
335  
336  //--------------------------------------------------------------------+
337  // USB Device Stack
338  //--------------------------------------------------------------------+
339  static int8_t ep0_desc_request_type = -1;
340  static uint16_t ep0_desc_request_len;
341  static uint8_t ep0_desc_request_idx;
342  
343  static void __no_inline_not_in_flash_func(prepare_ep0_data)(uint8_t *data,
344                                                              uint8_t len) {
345    // 0: control out (rx), 1 : control in (tx)
346    endpoint_t *ep = &pio_usb_ep_pool[1];
347  
348    pio_usb_ll_transfer_start(ep, data, len);
349  
350    if (len) {
351      // there is data, prepare for status as well
352      pio_usb_ll_transfer_start(&pio_usb_ep_pool[0], NULL, 0);
353    }
354  }
355  
356  static void __no_inline_not_in_flash_func(prepare_ep0_rx)(uint8_t *data,
357                                                            uint8_t len) {
358    // 0: control out (rx), 1 : control in (tx)
359    endpoint_t *ep = &pio_usb_ep_pool[0];
360  
361    pio_usb_ll_transfer_start(ep, data, len);
362  
363    if (len) {
364      // there is data, prepare for status as well
365      pio_usb_ll_transfer_start(&pio_usb_ep_pool[1], NULL, 0);
366    }
367  }
368  
369  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  
376    switch (ep0_desc_request_type) {
377      case DESC_TYPE_CONFIG: {
378        uint16_t req_len = ep0_desc_request_len;
379        uint16_t desc_len =
380            descriptor_buffers.config[2] | (descriptor_buffers.config[3] << 8);
381        req_len = req_len > desc_len ? desc_len : req_len;
382        prepare_ep0_data((uint8_t *)descriptor_buffers.config, req_len);
383        ep0_desc_request_type = -1;
384      } break;
385      case DESC_TYPE_STRING: {
386        const uint16_t *str =
387            (uint16_t *)&descriptor_buffers.string[ep0_desc_request_idx];
388        prepare_ep0_data((uint8_t *)str, str[0] & 0xff);
389        ep0_desc_request_type = -1;
390      } break;
391      case DESC_TYPE_HID_REPORT:{
392        prepare_ep0_data(
393            (uint8_t *)descriptor_buffers.hid_report[ep0_desc_request_idx],
394            ep0_desc_request_len);
395        ep0_desc_request_type = -1;
396      }
397      default:
398        break;
399    }
400  
401    uint32_t se0_time_us =0;
402    bool reset = false;
403    while (pio_usb_bus_get_line_state(rport) == PORT_PIN_SE0) {
404      busy_wait_us_32(1);
405      se0_time_us++;
406  
407      if (se0_time_us == 1000) {
408        memset(pio_usb_ep_pool, 0, sizeof(pio_usb_ep_pool));
409        rport->dev_addr = 0;
410        update_ep0_crc5_lut(rport->dev_addr);
411  
412        // init endpoint control in/out
413        PIO_USB_ENDPOINT(0)->size = 64;
414        PIO_USB_ENDPOINT(0)->ep_num = 0;
415        PIO_USB_ENDPOINT(0)->is_tx = false;
416  
417        PIO_USB_ENDPOINT(1)->size = 64;
418        PIO_USB_ENDPOINT(1)->ep_num = 0x80;
419        PIO_USB_ENDPOINT(1)->is_tx = true;
420  
421        // TODO should be reset end, this is reset start only
422        rport->ep_complete = rport->ep_stalled = rport->ep_error = 0;
423        rport->ints |= PIO_USB_INTS_RESET_END_BITS;
424        reset = true;
425      }
426    }
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    }
432  }
433  
434  static void __no_inline_not_in_flash_func(configure_all_endpoints)(uint8_t const *desc) {
435    uint8_t const *desc_end = desc + (descriptor_buffers.config[2] |
436                                      (descriptor_buffers.config[3] << 8));
437    while (desc < desc_end) {
438      if (desc[1] == DESC_TYPE_ENDPOINT) {
439        pio_usb_device_endpoint_open(desc);
440      }
441      desc += desc[0];
442    }
443  }
444  
445  static int __no_inline_not_in_flash_func(process_device_setup_stage)(uint8_t *buffer) {
446    int res = -1;
447    const usb_setup_packet_t *packet = (usb_setup_packet_t *)buffer;
448  
449    if (packet->request_type == USB_REQ_DIR_IN) {
450      if (packet->request == 0x06) {
451        if (packet->value_msb == DESC_TYPE_DEVICE) {
452          prepare_ep0_data((uint8_t *)descriptor_buffers.device, 18);
453          res = 0;
454        } else if (packet->value_msb == DESC_TYPE_CONFIG) {
455          ep0_desc_request_len = (packet->length_lsb | (packet->length_msb << 8));
456          ep0_desc_request_type = DESC_TYPE_CONFIG;
457          res = 0;
458        } else if (packet->value_msb == DESC_TYPE_STRING) {
459          if (descriptor_buffers.string != NULL) {
460            ep0_desc_request_idx = packet->value_lsb;
461            ep0_desc_request_type = DESC_TYPE_STRING;
462            res = 0;
463          }
464        }
465      }
466    } else if (packet->request_type == USB_REQ_DIR_OUT) {
467      if (packet->request == 0x05) {
468        // set address
469        new_devaddr = packet->value_lsb;
470        prepare_ep0_data(NULL, 0);
471        res = 0;
472      } else if (packet->request == 0x09) {
473        // set configuration
474        configure_all_endpoints(descriptor_buffers.config);
475        prepare_ep0_data(NULL, 0);
476        res = 0;
477      }
478    } else if (packet->request_type == (USB_REQ_DIR_IN | USB_REQ_REC_IFACE)) {
479      if (packet->request == 0x06 && packet->value_msb == DESC_TYPE_HID_REPORT) {
480        // get hid report desc
481        ep0_desc_request_len = (packet->length_lsb | (packet->length_msb << 8));
482        ep0_desc_request_idx = packet->index_lsb;
483        ep0_desc_request_type = DESC_TYPE_HID_REPORT;
484        res = 0;
485      }
486    } else if (packet->request_type == (USB_REQ_TYP_CLASS | USB_REQ_REC_IFACE)) {
487      if (packet->request == 0x09) {
488        // set hid report
489        static __unused uint8_t received_hid_report[8]; // not used
490        prepare_ep0_rx(received_hid_report, 8);
491        res = 0;
492      } else if (packet->request == 0x0A) {
493        // set hid idle request
494        prepare_ep0_data(NULL, 0);
495        res = 0;
496      } else if (packet->request == 0x0B) {
497        // set hid protocol request
498        prepare_ep0_data(NULL, 0);
499        res = 0;
500      }
501    } else if (packet->request_type == (USB_REQ_REC_EP)) {
502        prepare_ep0_data(NULL, 0);
503        res = 0;
504    }
505  
506    return res;
507  }
508  
509  // IRQ Handler
510  static void __no_inline_not_in_flash_func(__pio_usb_device_irq_handler)(uint8_t root_idx) {
511    root_port_t *root = PIO_USB_ROOT_PORT(root_idx);
512    usb_device_t *dev = &pio_usb_device[0];
513  
514    uint32_t const ints = root->ints;
515  
516    if (ints & PIO_USB_INTS_RESET_END_BITS) {
517      memset(dev, 0, sizeof(*dev));
518      for (int i = 0; i < PIO_USB_DEV_EP_CNT; i++) {
519        dev->endpoint_id[i] = 2 * (i + 1); // only index IN endpoint
520      }
521    }
522  
523    if (ints & PIO_USB_INTS_SETUP_REQ_BITS) {
524      process_device_setup_stage(root->setup_packet);
525      dev->control_pipe.stage = STAGE_DATA;
526    }
527  
528    if (ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS) {
529      const uint32_t ep_all = root->ep_complete;
530  
531      // control out
532      if (ep_all & 0x01) {
533        if (dev->control_pipe.stage == STAGE_STATUS) {
534          dev->control_pipe.stage = STAGE_COMPLETE;
535        } else if (dev->control_pipe.stage == STAGE_DATA) {
536          dev->control_pipe.stage = STAGE_STATUS;
537          prepare_ep0_data(NULL, 0);
538        }
539      }
540  
541      // control in
542      if (ep_all & 0x02) {
543        if (dev->control_pipe.stage == STAGE_STATUS) {
544          dev->control_pipe.stage = STAGE_COMPLETE;
545        }
546      }
547  
548      // clear all
549      root->ep_complete &= ~ep_all;
550    }
551  
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  
563    // clear all
564    root->ints &= ~ints;
565  }
566  
567  // weak alias to __pio_usb_device_irq_handler
568  void pio_usb_device_irq_handler(uint8_t root_id) __attribute__ ((weak, alias("__pio_usb_device_irq_handler")));
569  
570  #pragma GCC pop_options