1
0

usb_dc_musb.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. /*
  2. * Copyright (c) 2022, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbd_core.h"
  7. #include "usb_musb_reg.h"
  8. #define HWREG(x) \
  9. (*((volatile uint32_t *)(x)))
  10. #define HWREGH(x) \
  11. (*((volatile uint16_t *)(x)))
  12. #define HWREGB(x) \
  13. (*((volatile uint8_t *)(x)))
  14. #define USB_BASE (g_usbdev_bus[0].reg_base)
  15. #if defined(CONFIG_USB_MUSB_SUNXI)
  16. #define MUSB_FADDR_OFFSET 0x98
  17. #define MUSB_POWER_OFFSET 0x40
  18. #define MUSB_TXIS_OFFSET 0x44
  19. #define MUSB_RXIS_OFFSET 0x46
  20. #define MUSB_TXIE_OFFSET 0x48
  21. #define MUSB_RXIE_OFFSET 0x4A
  22. #define MUSB_IS_OFFSET 0x4C
  23. #define MUSB_IE_OFFSET 0x50
  24. #define MUSB_EPIDX_OFFSET 0x42
  25. #define MUSB_IND_TXMAP_OFFSET 0x80
  26. #define MUSB_IND_TXCSRL_OFFSET 0x82
  27. #define MUSB_IND_TXCSRH_OFFSET 0x83
  28. #define MUSB_IND_RXMAP_OFFSET 0x84
  29. #define MUSB_IND_RXCSRL_OFFSET 0x86
  30. #define MUSB_IND_RXCSRH_OFFSET 0x87
  31. #define MUSB_IND_RXCOUNT_OFFSET 0x88
  32. #define MUSB_IND_TXTYPE_OFFSET 0x8C
  33. #define MUSB_IND_TXINTERVAL_OFFSET 0x8D
  34. #define MUSB_IND_RXTYPE_OFFSET 0x8E
  35. #define MUSB_IND_RXINTERVAL_OFFSET 0x8F
  36. #define MUSB_FIFO_OFFSET 0x00
  37. #define MUSB_DEVCTL_OFFSET 0x41
  38. #define MUSB_TXFIFOSZ_OFFSET 0x90
  39. #define MUSB_RXFIFOSZ_OFFSET 0x94
  40. #define MUSB_TXFIFOADD_OFFSET 0x92
  41. #define MUSB_RXFIFOADD_OFFSET 0x96
  42. #define MUSB_TXFUNCADDR0_OFFSET 0x98
  43. #define MUSB_TXHUBADDR0_OFFSET 0x9A
  44. #define MUSB_TXHUBPORT0_OFFSET 0x9B
  45. #define MUSB_TXFUNCADDRx_OFFSET 0x98
  46. #define MUSB_TXHUBADDRx_OFFSET 0x9A
  47. #define MUSB_TXHUBPORTx_OFFSET 0x9B
  48. #define MUSB_RXFUNCADDRx_OFFSET 0x9C
  49. #define MUSB_RXHUBADDRx_OFFSET 0x9E
  50. #define MUSB_RXHUBPORTx_OFFSET 0x9F
  51. #define USB_TXMAP_BASE(ep_idx) (USB_BASE + MUSB_IND_TXMAP_OFFSET)
  52. #define USB_TXCSRL_BASE(ep_idx) (USB_BASE + MUSB_IND_TXCSRL_OFFSET)
  53. #define USB_TXCSRH_BASE(ep_idx) (USB_BASE + MUSB_IND_TXCSRH_OFFSET)
  54. #define USB_RXMAP_BASE(ep_idx) (USB_BASE + MUSB_IND_RXMAP_OFFSET)
  55. #define USB_RXCSRL_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCSRL_OFFSET)
  56. #define USB_RXCSRH_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCSRH_OFFSET)
  57. #define USB_RXCOUNT_BASE(ep_idx) (USB_BASE + MUSB_IND_RXCOUNT_OFFSET)
  58. #define USB_TXTYPE_BASE(ep_idx) (USB_BASE + MUSB_IND_TXTYPE_OFFSET)
  59. #define USB_TXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_IND_TXINTERVAL_OFFSET)
  60. #define USB_RXTYPE_BASE(ep_idx) (USB_BASE + MUSB_IND_RXTYPE_OFFSET)
  61. #define USB_RXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_IND_RXINTERVAL_OFFSET)
  62. #define USB_TXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDRx_OFFSET)
  63. #define USB_TXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXHUBADDRx_OFFSET)
  64. #define USB_TXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXHUBPORTx_OFFSET)
  65. #define USB_RXADDR_BASE(ep_idx) (USB_BASE + MUSB_RXFUNCADDRx_OFFSET)
  66. #define USB_RXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_RXHUBADDRx_OFFSET)
  67. #define USB_RXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_RXHUBPORTx_OFFSET)
  68. #elif defined(CONFIG_USB_MUSB_CUSTOM)
  69. #include "musb_custom.h"
  70. #else
  71. #define MUSB_FADDR_OFFSET 0x00
  72. #define MUSB_POWER_OFFSET 0x01
  73. #define MUSB_TXIS_OFFSET 0x02
  74. #define MUSB_RXIS_OFFSET 0x04
  75. #define MUSB_TXIE_OFFSET 0x06
  76. #define MUSB_RXIE_OFFSET 0x08
  77. #define MUSB_IS_OFFSET 0x0A
  78. #define MUSB_IE_OFFSET 0x0B
  79. #define MUSB_EPIDX_OFFSET 0x0E
  80. #define MUSB_IND_TXMAP_OFFSET 0x10
  81. #define MUSB_IND_TXCSRL_OFFSET 0x12
  82. #define MUSB_IND_TXCSRH_OFFSET 0x13
  83. #define MUSB_IND_RXMAP_OFFSET 0x14
  84. #define MUSB_IND_RXCSRL_OFFSET 0x16
  85. #define MUSB_IND_RXCSRH_OFFSET 0x17
  86. #define MUSB_IND_RXCOUNT_OFFSET 0x18
  87. #define MUSB_IND_TXTYPE_OFFSET 0x1A
  88. #define MUSB_IND_TXINTERVAL_OFFSET 0x1B
  89. #define MUSB_IND_RXTYPE_OFFSET 0x1C
  90. #define MUSB_IND_RXINTERVAL_OFFSET 0x1D
  91. #define MUSB_FIFO_OFFSET 0x20
  92. #define MUSB_DEVCTL_OFFSET 0x60
  93. #define MUSB_TXFIFOSZ_OFFSET 0x62
  94. #define MUSB_RXFIFOSZ_OFFSET 0x63
  95. #define MUSB_TXFIFOADD_OFFSET 0x64
  96. #define MUSB_RXFIFOADD_OFFSET 0x66
  97. #define MUSB_TXFUNCADDR0_OFFSET 0x80
  98. #define MUSB_TXHUBADDR0_OFFSET 0x82
  99. #define MUSB_TXHUBPORT0_OFFSET 0x83
  100. #define MUSB_TXFUNCADDRx_OFFSET 0x88
  101. #define MUSB_TXHUBADDRx_OFFSET 0x8A
  102. #define MUSB_TXHUBPORTx_OFFSET 0x8B
  103. #define MUSB_RXFUNCADDRx_OFFSET 0x8C
  104. #define MUSB_RXHUBADDRx_OFFSET 0x8E
  105. #define MUSB_RXHUBPORTx_OFFSET 0x8F
  106. #define MUSB_TXMAP0_OFFSET 0x100
  107. // do not use EPIDX
  108. #define USB_TXMAP_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx)
  109. #define USB_TXCSRL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 2)
  110. #define USB_TXCSRH_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 3)
  111. #define USB_RXMAP_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 4)
  112. #define USB_RXCSRL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 6)
  113. #define USB_RXCSRH_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 7)
  114. #define USB_RXCOUNT_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 8)
  115. #define USB_TXTYPE_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0A)
  116. #define USB_TXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0B)
  117. #define USB_RXTYPE_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0C)
  118. #define USB_RXINTERVAL_BASE(ep_idx) (USB_BASE + MUSB_TXMAP0_OFFSET + 0x10 * ep_idx + 0x0D)
  119. #define USB_TXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx)
  120. #define USB_TXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 2)
  121. #define USB_TXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 3)
  122. #define USB_RXADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 4)
  123. #define USB_RXHUBADDR_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 6)
  124. #define USB_RXHUBPORT_BASE(ep_idx) (USB_BASE + MUSB_TXFUNCADDR0_OFFSET + 0x8 * ep_idx + 7)
  125. #endif
  126. #define USB_FIFO_BASE(ep_idx) (USB_BASE + MUSB_FIFO_OFFSET + 0x4 * ep_idx)
  127. typedef enum {
  128. USB_EP0_STATE_SETUP = 0x0, /**< SETUP DATA */
  129. USB_EP0_STATE_IN_DATA = 0x1, /**< IN DATA */
  130. USB_EP0_STATE_OUT_DATA = 0x3, /**< OUT DATA */
  131. USB_EP0_STATE_IN_STATUS = 0x4, /**< IN status */
  132. USB_EP0_STATE_OUT_STATUS = 0x5, /**< OUT status */
  133. USB_EP0_STATE_IN_ZLP = 0x6, /**< OUT status */
  134. USB_EP0_STATE_STALL = 0x7, /**< STALL status */
  135. } ep0_state_t;
  136. /* Endpoint state */
  137. struct musb_ep_state {
  138. uint16_t ep_mps; /* Endpoint max packet size */
  139. uint8_t ep_type; /* Endpoint type */
  140. uint8_t ep_stalled; /* Endpoint stall flag */
  141. uint8_t ep_enable; /* Endpoint enable */
  142. uint8_t *xfer_buf;
  143. uint32_t xfer_len;
  144. uint32_t actual_xfer_len;
  145. };
  146. /* Driver state */
  147. struct musb_udc {
  148. volatile uint8_t dev_addr;
  149. __attribute__((aligned(32))) struct usb_setup_packet setup;
  150. struct musb_ep_state in_ep[CONFIG_USB_MUSB_EP_NUM]; /*!< IN endpoint parameters*/
  151. struct musb_ep_state out_ep[CONFIG_USB_MUSB_EP_NUM]; /*!< OUT endpoint parameters */
  152. } g_musb_udc;
  153. static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
  154. /* get current active ep */
  155. static uint8_t musb_get_active_ep(void)
  156. {
  157. return HWREGB(USB_BASE + MUSB_EPIDX_OFFSET);
  158. }
  159. /* set the active ep */
  160. static void musb_set_active_ep(uint8_t ep_index)
  161. {
  162. HWREGB(USB_BASE + MUSB_EPIDX_OFFSET) = ep_index;
  163. }
  164. static void musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
  165. {
  166. uint32_t *buf32;
  167. uint8_t *buf8;
  168. uint32_t count32;
  169. uint32_t count8;
  170. int i;
  171. if ((uint32_t)buffer & 0x03) {
  172. buf8 = buffer;
  173. for (i = 0; i < len; i++) {
  174. HWREGB(USB_FIFO_BASE(ep_idx)) = *buf8++;
  175. }
  176. } else {
  177. count32 = len >> 2;
  178. count8 = len & 0x03;
  179. buf32 = (uint32_t *)buffer;
  180. while (count32--) {
  181. HWREG(USB_FIFO_BASE(ep_idx)) = *buf32++;
  182. }
  183. buf8 = (uint8_t *)buf32;
  184. while (count8--) {
  185. HWREGB(USB_FIFO_BASE(ep_idx)) = *buf8++;
  186. }
  187. }
  188. }
  189. static void musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
  190. {
  191. uint32_t *buf32;
  192. uint8_t *buf8;
  193. uint32_t count32;
  194. uint32_t count8;
  195. int i;
  196. if ((uint32_t)buffer & 0x03) {
  197. buf8 = buffer;
  198. for (i = 0; i < len; i++) {
  199. *buf8++ = HWREGB(USB_FIFO_BASE(ep_idx));
  200. }
  201. } else {
  202. count32 = len >> 2;
  203. count8 = len & 0x03;
  204. buf32 = (uint32_t *)buffer;
  205. while (count32--) {
  206. *buf32++ = HWREG(USB_FIFO_BASE(ep_idx));
  207. }
  208. buf8 = (uint8_t *)buf32;
  209. while (count8--) {
  210. *buf8++ = HWREGB(USB_FIFO_BASE(ep_idx));
  211. }
  212. }
  213. }
  214. static uint32_t musb_get_fifo_size(uint16_t mps, uint16_t *used)
  215. {
  216. uint32_t size;
  217. for (uint8_t i = USB_TXFIFOSZ_SIZE_8; i <= USB_TXFIFOSZ_SIZE_2048; i++) {
  218. size = (8 << i);
  219. if (mps <= size) {
  220. *used = size;
  221. return i;
  222. }
  223. }
  224. *used = 0;
  225. return USB_TXFIFOSZ_SIZE_8;
  226. }
  227. static uint32_t usbd_musb_fifo_config(struct musb_fifo_cfg *cfg, uint32_t offset)
  228. {
  229. uint16_t fifo_used;
  230. uint8_t c_size;
  231. uint16_t c_off;
  232. c_off = offset >> 3;
  233. c_size = musb_get_fifo_size(cfg->maxpacket, &fifo_used);
  234. musb_set_active_ep(cfg->ep_num);
  235. switch (cfg->style) {
  236. case FIFO_TX:
  237. HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = c_size & 0x0f;
  238. HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = c_off;
  239. break;
  240. case FIFO_RX:
  241. HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = c_size & 0x0f;
  242. HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = c_off;
  243. break;
  244. case FIFO_TXRX:
  245. HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = c_size & 0x0f;
  246. HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = c_off;
  247. HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = c_size & 0x0f;
  248. HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = c_off;
  249. break;
  250. default:
  251. break;
  252. }
  253. return (offset + fifo_used);
  254. }
  255. __WEAK void usb_dc_low_level_init(void)
  256. {
  257. }
  258. __WEAK void usb_dc_low_level_deinit(void)
  259. {
  260. }
  261. int usb_dc_init(uint8_t busid)
  262. {
  263. uint16_t offset = 0;
  264. uint8_t cfg_num;
  265. struct musb_fifo_cfg *cfg;
  266. usb_dc_low_level_init();
  267. #ifdef CONFIG_USB_HS
  268. HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_HSENAB;
  269. #else
  270. HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_HSENAB;
  271. #endif
  272. musb_set_active_ep(0);
  273. HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = 0;
  274. HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) |= USB_DEVCTL_SESSION;
  275. cfg_num = usbd_get_musb_fifo_cfg(&cfg);
  276. for (uint8_t i = 0; i < cfg_num; i++) {
  277. offset = usbd_musb_fifo_config(&cfg[i], offset);
  278. }
  279. USB_ASSERT_MSG(offset <= usb_get_musb_ram_size(), "Your fifo config is overflow, please check");
  280. /* Enable USB interrupts */
  281. HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET | USB_IE_SUSPND | USB_IE_RESUME;
  282. HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0;
  283. HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
  284. #ifdef CONFIG_USBDEV_SOF_ENABLE
  285. HWREGB(USB_BASE + MUSB_IE_OFFSET) |= USB_IE_SOF;
  286. #endif
  287. HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_SOFTCONN;
  288. return 0;
  289. }
  290. int usb_dc_deinit(uint8_t busid)
  291. {
  292. HWREGB(USB_BASE + MUSB_IE_OFFSET) = 0;
  293. HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = 0;
  294. HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
  295. HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_SOFTCONN;
  296. usb_dc_low_level_deinit();
  297. return 0;
  298. }
  299. int usbd_set_address(uint8_t busid, const uint8_t addr)
  300. {
  301. if (addr == 0) {
  302. HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = 0;
  303. }
  304. g_musb_udc.dev_addr = addr;
  305. return 0;
  306. }
  307. int usbd_set_remote_wakeup(uint8_t busid)
  308. {
  309. HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESUME;
  310. usbd_musb_delay_ms(10);
  311. HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_RESUME;
  312. return 0;
  313. }
  314. uint8_t usbd_get_port_speed(uint8_t busid)
  315. {
  316. uint8_t speed = USB_SPEED_UNKNOWN;
  317. if (HWREGB(USB_BASE + MUSB_POWER_OFFSET) & USB_POWER_HSMODE)
  318. speed = USB_SPEED_HIGH;
  319. else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_FSDEV)
  320. speed = USB_SPEED_FULL;
  321. else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_LSDEV)
  322. speed = USB_SPEED_LOW;
  323. return speed;
  324. }
  325. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  326. {
  327. uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
  328. uint8_t old_ep_idx;
  329. uint32_t ui32Flags = 0;
  330. uint16_t ui32Register = 0;
  331. if (ep_idx == 0) {
  332. g_musb_udc.out_ep[0].ep_mps = USB_CTRL_EP_MPS;
  333. g_musb_udc.out_ep[0].ep_type = 0x00;
  334. g_musb_udc.out_ep[0].ep_enable = true;
  335. g_musb_udc.in_ep[0].ep_mps = USB_CTRL_EP_MPS;
  336. g_musb_udc.in_ep[0].ep_type = 0x00;
  337. g_musb_udc.in_ep[0].ep_enable = true;
  338. return 0;
  339. }
  340. USB_ASSERT_MSG(ep_idx < CONFIG_USB_MUSB_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
  341. old_ep_idx = musb_get_active_ep();
  342. musb_set_active_ep(ep_idx);
  343. if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
  344. g_musb_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  345. g_musb_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  346. g_musb_udc.out_ep[ep_idx].ep_enable = true;
  347. #ifndef CONFIG_USB_MUSB_SIFLI
  348. USB_ASSERT_MSG((8 << HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET)) >= g_musb_udc.out_ep[ep_idx].ep_mps,
  349. "Ep %02x fifo is overflow", ep->bEndpointAddress);
  350. #endif
  351. HWREGH(USB_RXMAP_BASE(ep_idx)) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  352. //
  353. // Allow auto clearing of RxPktRdy when packet of size max packet
  354. // has been unloaded from the FIFO.
  355. //
  356. if (ui32Flags & USB_EP_AUTO_CLEAR) {
  357. ui32Register = USB_RXCSRH1_AUTOCL;
  358. }
  359. //
  360. // Configure the DMA mode.
  361. //
  362. if (ui32Flags & USB_EP_DMA_MODE_1) {
  363. ui32Register |= USB_RXCSRH1_DMAEN | USB_RXCSRH1_DMAMOD;
  364. } else if (ui32Flags & USB_EP_DMA_MODE_0) {
  365. ui32Register |= USB_RXCSRH1_DMAEN;
  366. }
  367. //
  368. // If requested, disable NYET responses for high-speed bulk and
  369. // interrupt endpoints.
  370. //
  371. if (ui32Flags & USB_EP_DIS_NYET) {
  372. ui32Register |= USB_RXCSRH1_DISNYET;
  373. }
  374. //
  375. // Enable isochronous mode if requested.
  376. //
  377. if (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == 0x01) {
  378. ui32Register |= USB_RXCSRH1_ISO;
  379. }
  380. HWREGB(USB_RXCSRH_BASE(ep_idx)) = ui32Register;
  381. // Reset the Data toggle to zero.
  382. if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_RXRDY)
  383. HWREGB(USB_RXCSRL_BASE(ep_idx)) = (USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH);
  384. else
  385. HWREGB(USB_RXCSRL_BASE(ep_idx)) = USB_RXCSRL1_CLRDT;
  386. HWREGB(USB_TXCSRH_BASE(ep_idx)) &= ~USB_TXCSRH1_MODE;
  387. } else {
  388. g_musb_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  389. g_musb_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  390. g_musb_udc.in_ep[ep_idx].ep_enable = true;
  391. #ifndef CONFIG_USB_MUSB_SIFLI
  392. USB_ASSERT_MSG((8 << HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET)) >= g_musb_udc.in_ep[ep_idx].ep_mps,
  393. "Ep %02x fifo is overflow", ep->bEndpointAddress);
  394. #endif
  395. HWREGH(USB_TXMAP_BASE(ep_idx)) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  396. //
  397. // Allow auto setting of TxPktRdy when max packet size has been loaded
  398. // into the FIFO.
  399. //
  400. if (ui32Flags & USB_EP_AUTO_SET) {
  401. ui32Register |= USB_TXCSRH1_AUTOSET;
  402. }
  403. //
  404. // Configure the DMA mode.
  405. //
  406. if (ui32Flags & USB_EP_DMA_MODE_1) {
  407. ui32Register |= USB_TXCSRH1_DMAEN | USB_TXCSRH1_DMAMOD;
  408. } else if (ui32Flags & USB_EP_DMA_MODE_0) {
  409. ui32Register |= USB_TXCSRH1_DMAEN;
  410. }
  411. //
  412. // Enable isochronous mode if requested.
  413. //
  414. if (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == 0x01) {
  415. ui32Register |= USB_TXCSRH1_ISO;
  416. }
  417. HWREGB(USB_TXCSRH_BASE(ep_idx)) = ui32Register | USB_TXCSRH1_MODE;
  418. // Reset the Data toggle to zero.
  419. if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_TXRDY)
  420. HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH);
  421. else
  422. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_CLRDT;
  423. }
  424. musb_set_active_ep(old_ep_idx);
  425. return 0;
  426. }
  427. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  428. {
  429. return 0;
  430. }
  431. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  432. {
  433. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  434. uint8_t old_ep_idx;
  435. old_ep_idx = musb_get_active_ep();
  436. musb_set_active_ep(ep_idx);
  437. if (USB_EP_DIR_IS_OUT(ep)) {
  438. if (ep_idx == 0x00) {
  439. usb_ep0_state = USB_EP0_STATE_STALL;
  440. HWREGB(USB_TXCSRL_BASE(ep_idx)) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
  441. } else {
  442. HWREGB(USB_RXCSRL_BASE(ep_idx)) |= USB_RXCSRL1_STALL;
  443. }
  444. } else {
  445. if (ep_idx == 0x00) {
  446. usb_ep0_state = USB_EP0_STATE_STALL;
  447. HWREGB(USB_TXCSRL_BASE(ep_idx)) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
  448. } else {
  449. HWREGB(USB_TXCSRL_BASE(ep_idx)) |= USB_TXCSRL1_STALL;
  450. }
  451. }
  452. musb_set_active_ep(old_ep_idx);
  453. return 0;
  454. }
  455. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  456. {
  457. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  458. uint8_t old_ep_idx;
  459. old_ep_idx = musb_get_active_ep();
  460. musb_set_active_ep(ep_idx);
  461. if (USB_EP_DIR_IS_OUT(ep)) {
  462. if (ep_idx == 0x00) {
  463. HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
  464. } else {
  465. // Clear the stall on an OUT endpoint.
  466. HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~(USB_RXCSRL1_STALL | USB_RXCSRL1_STALLED);
  467. // Reset the data toggle.
  468. HWREGB(USB_RXCSRL_BASE(ep_idx)) |= USB_RXCSRL1_CLRDT;
  469. }
  470. } else {
  471. if (ep_idx == 0x00) {
  472. HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
  473. } else {
  474. // Clear the stall on an IN endpoint.
  475. HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~(USB_TXCSRL1_STALL | USB_TXCSRL1_STALLED);
  476. // Reset the data toggle.
  477. HWREGB(USB_TXCSRL_BASE(ep_idx)) |= USB_TXCSRL1_CLRDT;
  478. }
  479. }
  480. musb_set_active_ep(old_ep_idx);
  481. return 0;
  482. }
  483. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  484. {
  485. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  486. uint8_t old_ep_idx;
  487. old_ep_idx = musb_get_active_ep();
  488. musb_set_active_ep(ep_idx);
  489. if (USB_EP_DIR_IS_OUT(ep)) {
  490. if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_STALL) {
  491. *stalled = 1;
  492. } else {
  493. *stalled = 0;
  494. }
  495. } else {
  496. if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_STALL) {
  497. *stalled = 1;
  498. } else {
  499. *stalled = 0;
  500. }
  501. }
  502. musb_set_active_ep(old_ep_idx);
  503. return 0;
  504. }
  505. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
  506. {
  507. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  508. uint8_t old_ep_idx;
  509. if (!data && data_len) {
  510. return -1;
  511. }
  512. if (!g_musb_udc.in_ep[ep_idx].ep_enable) {
  513. return -2;
  514. }
  515. old_ep_idx = musb_get_active_ep();
  516. musb_set_active_ep(ep_idx);
  517. if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_TXRDY) {
  518. musb_set_active_ep(old_ep_idx);
  519. return -3;
  520. }
  521. g_musb_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
  522. g_musb_udc.in_ep[ep_idx].xfer_len = data_len;
  523. g_musb_udc.in_ep[ep_idx].actual_xfer_len = 0;
  524. if (data_len == 0) {
  525. if (ep_idx == 0x00) {
  526. if (g_musb_udc.setup.wLength == 0) {
  527. usb_ep0_state = USB_EP0_STATE_IN_STATUS;
  528. } else {
  529. usb_ep0_state = USB_EP0_STATE_IN_ZLP;
  530. }
  531. HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
  532. } else {
  533. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
  534. HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
  535. }
  536. musb_set_active_ep(old_ep_idx);
  537. return 0;
  538. }
  539. data_len = MIN(data_len, g_musb_udc.in_ep[ep_idx].ep_mps);
  540. musb_write_packet(ep_idx, (uint8_t *)data, data_len);
  541. HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
  542. if (ep_idx == 0x00) {
  543. usb_ep0_state = USB_EP0_STATE_IN_DATA;
  544. if (data_len < g_musb_udc.in_ep[ep_idx].ep_mps) {
  545. HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
  546. } else {
  547. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_TXRDY;
  548. }
  549. } else {
  550. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
  551. }
  552. musb_set_active_ep(old_ep_idx);
  553. return 0;
  554. }
  555. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
  556. {
  557. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  558. uint8_t old_ep_idx;
  559. if (!data && data_len) {
  560. return -1;
  561. }
  562. if (!g_musb_udc.out_ep[ep_idx].ep_enable) {
  563. return -2;
  564. }
  565. old_ep_idx = musb_get_active_ep();
  566. musb_set_active_ep(ep_idx);
  567. g_musb_udc.out_ep[ep_idx].xfer_buf = data;
  568. g_musb_udc.out_ep[ep_idx].xfer_len = data_len;
  569. g_musb_udc.out_ep[ep_idx].actual_xfer_len = 0;
  570. if (data_len == 0) {
  571. if (ep_idx == 0) {
  572. usb_ep0_state = USB_EP0_STATE_SETUP;
  573. }
  574. musb_set_active_ep(old_ep_idx);
  575. return 0;
  576. }
  577. if (ep_idx == 0) {
  578. usb_ep0_state = USB_EP0_STATE_OUT_DATA;
  579. } else {
  580. HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << ep_idx);
  581. }
  582. musb_set_active_ep(old_ep_idx);
  583. return 0;
  584. }
  585. static void handle_ep0(void)
  586. {
  587. uint8_t ep_idx = 0; // EP0 index is always 0
  588. uint8_t ep0_status = HWREGB(USB_TXCSRL_BASE(ep_idx));
  589. uint16_t read_count;
  590. if (ep0_status & USB_CSRL0_STALLED) {
  591. HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_CSRL0_STALLED;
  592. usb_ep0_state = USB_EP0_STATE_SETUP;
  593. return;
  594. }
  595. if (ep0_status & USB_CSRL0_SETEND) {
  596. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_SETENDC;
  597. }
  598. if (g_musb_udc.dev_addr > 0) {
  599. HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = g_musb_udc.dev_addr;
  600. g_musb_udc.dev_addr = 0;
  601. }
  602. switch (usb_ep0_state) {
  603. case USB_EP0_STATE_SETUP:
  604. if (ep0_status & USB_CSRL0_RXRDY) {
  605. read_count = HWREGH(USB_RXCOUNT_BASE(ep_idx));
  606. if (read_count != 8) {
  607. return;
  608. }
  609. musb_read_packet(0, (uint8_t *)&g_musb_udc.setup, 8);
  610. if (g_musb_udc.setup.wLength) {
  611. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_RXRDYC;
  612. } else {
  613. HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
  614. }
  615. usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_musb_udc.setup);
  616. }
  617. break;
  618. case USB_EP0_STATE_IN_DATA:
  619. if (g_musb_udc.in_ep[0].xfer_len > g_musb_udc.in_ep[0].ep_mps) {
  620. g_musb_udc.in_ep[0].actual_xfer_len += g_musb_udc.in_ep[0].ep_mps;
  621. g_musb_udc.in_ep[0].xfer_len -= g_musb_udc.in_ep[0].ep_mps;
  622. } else {
  623. g_musb_udc.in_ep[0].actual_xfer_len += g_musb_udc.in_ep[0].xfer_len;
  624. g_musb_udc.in_ep[0].xfer_len = 0;
  625. }
  626. usbd_event_ep_in_complete_handler(0, 0x80, g_musb_udc.in_ep[0].actual_xfer_len);
  627. break;
  628. case USB_EP0_STATE_OUT_DATA:
  629. if (ep0_status & USB_CSRL0_RXRDY) {
  630. read_count = HWREGH(USB_RXCOUNT_BASE(ep_idx));
  631. musb_read_packet(0, g_musb_udc.out_ep[0].xfer_buf, read_count);
  632. g_musb_udc.out_ep[0].xfer_buf += read_count;
  633. g_musb_udc.out_ep[0].actual_xfer_len += read_count;
  634. if (read_count < g_musb_udc.out_ep[0].ep_mps) {
  635. usbd_event_ep_out_complete_handler(0, 0x00, g_musb_udc.out_ep[0].actual_xfer_len);
  636. HWREGB(USB_TXCSRL_BASE(ep_idx)) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
  637. usb_ep0_state = USB_EP0_STATE_IN_STATUS;
  638. } else {
  639. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_CSRL0_RXRDYC;
  640. }
  641. }
  642. break;
  643. case USB_EP0_STATE_IN_STATUS:
  644. case USB_EP0_STATE_IN_ZLP:
  645. usb_ep0_state = USB_EP0_STATE_SETUP;
  646. usbd_event_ep_in_complete_handler(0, 0x80, 0);
  647. break;
  648. }
  649. }
  650. void USBD_IRQHandler(uint8_t busid)
  651. {
  652. uint32_t is;
  653. uint32_t txis;
  654. uint32_t rxis;
  655. uint8_t old_ep_idx;
  656. uint8_t ep_idx;
  657. uint16_t write_count, read_count;
  658. if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_HOST) {
  659. return;
  660. }
  661. is = HWREGB(USB_BASE + MUSB_IS_OFFSET);
  662. txis = HWREGH(USB_BASE + MUSB_TXIS_OFFSET);
  663. rxis = HWREGH(USB_BASE + MUSB_RXIS_OFFSET);
  664. HWREGB(USB_BASE + MUSB_IS_OFFSET) = is;
  665. old_ep_idx = musb_get_active_ep();
  666. /* Receive a reset signal from the USB bus */
  667. if (is & USB_IS_RESET) {
  668. memset(&g_musb_udc, 0, sizeof(struct musb_udc));
  669. usbd_event_reset_handler(0);
  670. HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0;
  671. HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
  672. usb_ep0_state = USB_EP0_STATE_SETUP;
  673. }
  674. #ifdef CONFIG_USBDEV_SOF_ENABLE
  675. if (is & USB_IS_SOF) {
  676. usbd_event_sof_handler(0);
  677. }
  678. #endif
  679. if (is & USB_IS_RESUME) {
  680. usbd_event_resume_handler(0);
  681. }
  682. if (is & USB_IS_SUSPEND) {
  683. usbd_event_suspend_handler(0);
  684. }
  685. txis &= HWREGH(USB_BASE + MUSB_TXIE_OFFSET);
  686. /* Handle EP0 interrupt */
  687. if (txis & USB_TXIE_EP0) {
  688. HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = USB_TXIE_EP0;
  689. musb_set_active_ep(0);
  690. handle_ep0();
  691. txis &= ~USB_TXIE_EP0;
  692. }
  693. ep_idx = 1;
  694. while (txis) {
  695. if (txis & (1 << ep_idx)) {
  696. musb_set_active_ep(ep_idx);
  697. HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
  698. if (HWREGB(USB_TXCSRL_BASE(ep_idx)) & USB_TXCSRL1_UNDRN) {
  699. HWREGB(USB_TXCSRL_BASE(ep_idx)) &= ~USB_TXCSRL1_UNDRN;
  700. }
  701. if (g_musb_udc.in_ep[ep_idx].xfer_len > g_musb_udc.in_ep[ep_idx].ep_mps) {
  702. g_musb_udc.in_ep[ep_idx].xfer_buf += g_musb_udc.in_ep[ep_idx].ep_mps;
  703. g_musb_udc.in_ep[ep_idx].actual_xfer_len += g_musb_udc.in_ep[ep_idx].ep_mps;
  704. g_musb_udc.in_ep[ep_idx].xfer_len -= g_musb_udc.in_ep[ep_idx].ep_mps;
  705. } else {
  706. g_musb_udc.in_ep[ep_idx].xfer_buf += g_musb_udc.in_ep[ep_idx].xfer_len;
  707. g_musb_udc.in_ep[ep_idx].actual_xfer_len += g_musb_udc.in_ep[ep_idx].xfer_len;
  708. g_musb_udc.in_ep[ep_idx].xfer_len = 0;
  709. }
  710. if (g_musb_udc.in_ep[ep_idx].xfer_len == 0) {
  711. HWREGH(USB_BASE + MUSB_TXIE_OFFSET) &= ~(1 << ep_idx);
  712. usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_musb_udc.in_ep[ep_idx].actual_xfer_len);
  713. } else {
  714. write_count = MIN(g_musb_udc.in_ep[ep_idx].xfer_len, g_musb_udc.in_ep[ep_idx].ep_mps);
  715. musb_write_packet(ep_idx, g_musb_udc.in_ep[ep_idx].xfer_buf, write_count);
  716. HWREGB(USB_TXCSRL_BASE(ep_idx)) = USB_TXCSRL1_TXRDY;
  717. }
  718. txis &= ~(1 << ep_idx);
  719. }
  720. ep_idx++;
  721. }
  722. rxis &= HWREGH(USB_BASE + MUSB_RXIE_OFFSET);
  723. ep_idx = 1;
  724. while (rxis) {
  725. if (rxis & (1 << ep_idx)) {
  726. musb_set_active_ep(ep_idx);
  727. HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx);
  728. if (HWREGB(USB_RXCSRL_BASE(ep_idx)) & USB_RXCSRL1_RXRDY) {
  729. read_count = HWREGH(USB_RXCOUNT_BASE(ep_idx));
  730. musb_read_packet(ep_idx, g_musb_udc.out_ep[ep_idx].xfer_buf, read_count);
  731. HWREGB(USB_RXCSRL_BASE(ep_idx)) &= ~(USB_RXCSRL1_RXRDY);
  732. g_musb_udc.out_ep[ep_idx].xfer_buf += read_count;
  733. g_musb_udc.out_ep[ep_idx].actual_xfer_len += read_count;
  734. g_musb_udc.out_ep[ep_idx].xfer_len -= read_count;
  735. if ((read_count < g_musb_udc.out_ep[ep_idx].ep_mps) || (g_musb_udc.out_ep[ep_idx].xfer_len == 0)) {
  736. HWREGH(USB_BASE + MUSB_RXIE_OFFSET) &= ~(1 << ep_idx);
  737. usbd_event_ep_out_complete_handler(0, ep_idx, g_musb_udc.out_ep[ep_idx].actual_xfer_len);
  738. } else {
  739. }
  740. }
  741. rxis &= ~(1 << ep_idx);
  742. }
  743. ep_idx++;
  744. }
  745. musb_set_active_ep(old_ep_idx);
  746. }