usb_dc_musb.c 24 KB

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