usb.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * usb.c
  3. *
  4. * Copyright (C) 2019 Sylvain Munaut
  5. * All rights reserved.
  6. *
  7. * LGPL v3+, see LICENSE.lgpl3
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 3 of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this program; if not, write to the Free Software Foundation,
  21. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. */
  23. #include <stdint.h>
  24. #include <stdbool.h>
  25. #include <string.h>
  26. #include "console.h"
  27. #include "usb_priv.h"
  28. /* Main stack state */
  29. struct usb_stack g_usb;
  30. /* Helpers for data access */
  31. void
  32. usb_data_write(int dst_ofs, const void *src, int len)
  33. {
  34. const uint32_t *src_u32 = src;
  35. volatile uint32_t *dst_u32 = (volatile uint32_t *)((USB_DATA_BASE) + (dst_ofs << 2));
  36. len = (len + 3) >> 2;
  37. while (len--)
  38. *dst_u32++ = *src_u32++;
  39. }
  40. void
  41. usb_data_read (void *dst, int src_ofs, int len)
  42. {
  43. volatile uint32_t *src_u32 = (volatile uint32_t *)((USB_DATA_BASE) + (src_ofs << 2));
  44. uint32_t *dst_u32 = dst;
  45. int i = len >> 2;
  46. while (i--)
  47. *dst_u32++ = *src_u32++;
  48. if ((len &= 3) != 0) {
  49. uint32_t x = *src_u32;
  50. uint8_t *dst_u8 = (uint8_t *)dst_u32;
  51. while (len--) {
  52. *dst_u8++ = x & 0xff;
  53. x >>= 8;
  54. }
  55. }
  56. }
  57. /* Debug */
  58. static const char *_hex = "0123456789abcdef";
  59. static void
  60. _fast_print_04x(uint32_t v)
  61. {
  62. int i;
  63. char str[5];
  64. for (i=3; i>=0; i--) {
  65. str[i] = _hex[v & 0xf];
  66. v >>= 4;
  67. }
  68. str[4] = 0;
  69. puts(str);
  70. }
  71. static void
  72. _fast_print_hex(uint32_t v)
  73. {
  74. char str[12], *p = str;
  75. int i;
  76. for (i=0; i<4; i++) {
  77. *p++ = _hex[(v & 0xf0) >> 4];
  78. *p++ = _hex[ v & 0x0f ];
  79. *p++ = ' ';
  80. v >>= 8;
  81. }
  82. str[11] = 0;
  83. puts(str);
  84. }
  85. void
  86. usb_debug_print_ep(int ep, int dir)
  87. {
  88. volatile struct usb_ep *ep_regs = dir ? &usb_ep_regs[ep].in : &usb_ep_regs[ep].out;
  89. printf("EP%d %s", ep, dir ? "IN" : "OUT");
  90. puts("\n\tS "); _fast_print_04x(ep_regs->status);
  91. puts("\n\tBD0.0 "); _fast_print_04x(ep_regs->bd[0].csr);
  92. puts("\n\tBD0.1 "); _fast_print_04x(ep_regs->bd[0].ptr);
  93. puts("\n\tBD1.0 "); _fast_print_04x(ep_regs->bd[1].csr);
  94. puts("\n\tBD1.1 "); _fast_print_04x(ep_regs->bd[1].ptr);
  95. puts("\n\n");
  96. }
  97. void
  98. usb_debug_print_data(int ofs, int len)
  99. {
  100. volatile uint32_t *data = (volatile uint32_t *)((USB_DATA_BASE) + (ofs << 2));
  101. int i;
  102. for (i=0; i<len; i++) {
  103. _fast_print_hex(*data++);
  104. putchar((((i & 3) == 3) | (i == (len-1))) ? '\n' : ' ');
  105. }
  106. puts("\n");
  107. }
  108. void
  109. usb_debug_print(void)
  110. {
  111. puts("\nCSR:");
  112. puts("\n\tSR: "); _fast_print_04x(usb_regs->csr);
  113. puts("\n\n");
  114. usb_debug_print_ep(0, 0);
  115. usb_debug_print_ep(0, 1);
  116. usb_debug_print_ep(1, 0);
  117. usb_debug_print_ep(1, 1);
  118. puts("\nData:\n");
  119. usb_debug_print_data(0, 4);
  120. }
  121. /* Exposed API */
  122. void
  123. usb_init(void)
  124. {
  125. /* Main state init */
  126. memset(&g_usb, 0x00, sizeof(g_usb));
  127. g_usb.ctrl.state = IDLE;
  128. /* Initialize EP0 */
  129. usb_ep0_init();
  130. /* Enable the core */
  131. usb_regs->csr = USB_CSR_PU_ENA | USB_CSR_CEL_ENA;
  132. }
  133. void
  134. usb_poll(void)
  135. {
  136. uint32_t evt;
  137. /* Check for activity */
  138. evt = usb_regs->evt;
  139. if (!(evt & 0xf000))
  140. return;
  141. /* Run EP0 (control) */
  142. usb_ep0_run();
  143. }