usb_dc_kinetis.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbd_core.h"
  7. #include "usb_kinetis_reg.h"
  8. #undef CONFIG_USBDEV_EP_NUM
  9. #define CONFIG_USBDEV_EP_NUM 16
  10. #define USB_OTG_DEV ((KINETIS_TypeDef *)g_usbdev_bus[busid].reg_base)
  11. /* Endpoint state */
  12. struct kinetis_ep_state {
  13. uint16_t ep_mps; /* Endpoint max packet size */
  14. uint8_t ep_type; /* Endpoint type */
  15. uint8_t ep_stalled; /* Endpoint stall flag */
  16. uint8_t ep_enable; /* Endpoint enable */
  17. bool ep_odd; /* Endpoint odd */
  18. uint8_t *xfer_buf;
  19. uint32_t xfer_len;
  20. uint32_t actual_xfer_len;
  21. };
  22. /* Driver state */
  23. struct kinetis_udc {
  24. uint8_t dev_addr;
  25. struct kinetis_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
  26. struct kinetis_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
  27. } g_kinetis_udc[CONFIG_USBDEV_MAX_BUS];
  28. USB_NOCACHE_RAM_SECTION __attribute__((aligned(512))) kinetis_bd_table_t g_kinetis_bdt[CONFIG_USBDEV_MAX_BUS];
  29. USB_NOCACHE_RAM_SECTION __attribute__((aligned(32))) uint8_t setup_packet[CONFIG_USBDEV_MAX_BUS][8];
  30. static int kinetis_start_transfer(uint8_t busid, uint8_t ep, uint8_t *buffer, uint16_t buflen)
  31. {
  32. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  33. uint8_t dir;
  34. uint8_t odd;
  35. uint16_t ep_mps;
  36. kinetis_bd_t *bd;
  37. kinetis_bd_t *next;
  38. if (USB_EP_DIR_IS_OUT(ep)) {
  39. dir = 0;
  40. odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd;
  41. ep_mps = g_kinetis_udc[busid].out_ep[ep_idx].ep_mps;
  42. } else {
  43. dir = 1;
  44. odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd;
  45. ep_mps = g_kinetis_udc[busid].in_ep[ep_idx].ep_mps;
  46. }
  47. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd];
  48. if (bd->own) {
  49. USB_LOG_INFO("ep%02x is busy\r\n", ep);
  50. return -1;
  51. }
  52. bd->bc = buflen >= ep_mps ? ep_mps : buflen;
  53. bd->addr = (uint32_t)buffer;
  54. bd->own = 1;
  55. return 0;
  56. }
  57. static void kinetis_read_setup(uint8_t busid)
  58. {
  59. uint8_t out_odd = g_kinetis_udc[busid].out_ep[0].ep_odd;
  60. uint8_t in_odd = g_kinetis_udc[busid].in_ep[0].ep_odd;
  61. if (g_kinetis_bdt[busid].table[0][0][out_odd].own) {
  62. USB_LOG_INFO("ep0 is busy\r\n");
  63. return;
  64. }
  65. g_kinetis_bdt[busid].table[0][0][out_odd].data = 0;
  66. g_kinetis_bdt[busid].table[0][0][out_odd ^ 1].data = 1;
  67. g_kinetis_bdt[busid].table[0][1][in_odd].data = 1;
  68. g_kinetis_bdt[busid].table[0][1][in_odd ^ 1].data = 0;
  69. kinetis_start_transfer(busid, USB_CONTROL_OUT_EP0, setup_packet[busid], 8);
  70. }
  71. __WEAK void usb_dc_low_level_init(uint8_t busid)
  72. {
  73. }
  74. __WEAK void usb_dc_low_level_deinit(uint8_t busid)
  75. {
  76. }
  77. int usb_dc_init(uint8_t busid)
  78. {
  79. usb_dc_low_level_init(busid);
  80. memset(&g_kinetis_udc[busid], 0, sizeof(g_kinetis_udc[busid]));
  81. USB_OTG_DEV->BDTPAGE1 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 8);
  82. USB_OTG_DEV->BDTPAGE2 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 16);
  83. USB_OTG_DEV->BDTPAGE3 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 24);
  84. USB_OTG_DEV->INTEN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK |
  85. USB_INTEN_SLEEPEN_MASK | USB_INTEN_RESUMEEN_MASK |
  86. USB_INTEN_ERROREN_MASK;
  87. #ifdef CONFIG_USBDEV_SOF_ENABLE
  88. USB_OTG_DEV->INTEN |= USB_INTEN_SOFTOKEN_MASK;
  89. #endif
  90. USB_OTG_DEV->CTL |= USB_CTL_USBENSOFEN_MASK;
  91. return 0;
  92. }
  93. int usb_dc_deinit(uint8_t busid)
  94. {
  95. USB_OTG_DEV->INTEN = 0;
  96. USB_OTG_DEV->CTL &= ~USB_CTL_USBENSOFEN_MASK;
  97. memset(&g_kinetis_udc[busid], 0, sizeof(g_kinetis_udc[busid]));
  98. USB_OTG_DEV->BDTPAGE1 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 8);
  99. USB_OTG_DEV->BDTPAGE2 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 16);
  100. USB_OTG_DEV->BDTPAGE3 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 24);
  101. usb_dc_low_level_deinit(busid);
  102. return 0;
  103. }
  104. int usbd_set_address(uint8_t busid, const uint8_t addr)
  105. {
  106. g_kinetis_udc[busid].dev_addr = addr;
  107. if (addr == 0) {
  108. USB_OTG_DEV->ADDR = 0;
  109. }
  110. return 0;
  111. }
  112. int usbd_set_remote_wakeup(uint8_t busid)
  113. {
  114. USB_OTG_DEV->CTL |= USB_CTL_RESUME_MASK;
  115. usbd_kinetis_delay_ms(10);
  116. USB_OTG_DEV->CTL &= ~USB_CTL_RESUME_MASK;
  117. return 0;
  118. }
  119. uint8_t usbd_get_port_speed(uint8_t busid)
  120. {
  121. return USB_SPEED_FULL;
  122. }
  123. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  124. {
  125. uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
  126. uint8_t odd;
  127. uint8_t dir;
  128. kinetis_bd_t *bd;
  129. uint8_t regval;
  130. /* Must not exceed max endpoint number */
  131. USB_ASSERT_MSG(ep_idx < CONFIG_USBDEV_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
  132. if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
  133. g_kinetis_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  134. g_kinetis_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  135. g_kinetis_udc[busid].out_ep[ep_idx].ep_enable = true;
  136. dir = 0;
  137. odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd;
  138. } else {
  139. g_kinetis_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  140. g_kinetis_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  141. g_kinetis_udc[busid].in_ep[ep_idx].ep_enable = true;
  142. dir = 1;
  143. odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd;
  144. }
  145. if (ep_idx != 0) {
  146. regval = USB_ENDPT_EPCTLDIS_MASK;
  147. regval |= (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK : 0;
  148. regval |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
  149. USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT |= regval;
  150. if (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  151. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd];
  152. bd->dts = 1;
  153. bd->data = 0;
  154. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd ^ 1];
  155. bd->dts = 1;
  156. bd->data = 1;
  157. }
  158. }
  159. return 0;
  160. }
  161. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  162. {
  163. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  164. uint8_t dir;
  165. kinetis_bd_t *bd;
  166. if (USB_EP_DIR_IS_OUT(ep)) {
  167. g_kinetis_udc[busid].out_ep[ep_idx].ep_enable = false;
  168. dir = 0;
  169. } else {
  170. g_kinetis_udc[busid].in_ep[ep_idx].ep_enable = false;
  171. dir = 1;
  172. }
  173. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][0];
  174. bd->head = 0;
  175. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][1];
  176. bd->head = 0;
  177. USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT &= ~(dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK);
  178. return 0;
  179. }
  180. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  181. {
  182. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  183. kinetis_bd_t *bd;
  184. uint8_t odd;
  185. uint8_t dir;
  186. if (0 == ep_idx) {
  187. USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPSTALL_MASK;
  188. if (ep_idx == 0) {
  189. kinetis_read_setup(busid);
  190. }
  191. } else {
  192. if (USB_EP_DIR_IS_OUT(ep)) {
  193. dir = 0;
  194. odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd;
  195. } else {
  196. dir = 1;
  197. odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd;
  198. }
  199. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd];
  200. bd->bdt_stall = 1;
  201. bd->own = 1;
  202. }
  203. return 0;
  204. }
  205. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  206. {
  207. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  208. kinetis_bd_t *bd;
  209. uint8_t odd;
  210. uint8_t dir;
  211. if (USB_EP_DIR_IS_OUT(ep)) {
  212. dir = 0;
  213. odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd;
  214. } else {
  215. dir = 1;
  216. odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd;
  217. }
  218. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd];
  219. bd->own = 0;
  220. bd->bdt_stall = 0;
  221. bd->data = 0;
  222. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd ^ 1];
  223. bd->data = 1;
  224. uint8_t regval = USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT;
  225. if (regval & USB_ENDPT_EPSTALL_MASK) {
  226. USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT = regval & ~USB_ENDPT_EPSTALL_MASK;
  227. }
  228. return 0;
  229. }
  230. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  231. {
  232. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  233. uint8_t regval = USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT;
  234. if (regval & USB_ENDPT_EPSTALL_MASK) {
  235. *stalled = 1;
  236. } else {
  237. *stalled = 0;
  238. }
  239. return 0;
  240. }
  241. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data,
  242. uint32_t data_len)
  243. {
  244. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  245. if (!data && data_len) {
  246. return -1;
  247. }
  248. if (!g_kinetis_udc[busid].in_ep[ep_idx].ep_enable) {
  249. return -2;
  250. }
  251. g_kinetis_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
  252. g_kinetis_udc[busid].in_ep[ep_idx].xfer_len = data_len;
  253. g_kinetis_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
  254. return kinetis_start_transfer(busid, ep, (uint8_t *)data, MIN(data_len, g_kinetis_udc[busid].in_ep[ep_idx].ep_mps));
  255. }
  256. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data,
  257. uint32_t data_len)
  258. {
  259. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  260. if (!data && data_len) {
  261. return -1;
  262. }
  263. if (!g_kinetis_udc[busid].out_ep[ep_idx].ep_enable) {
  264. return -2;
  265. }
  266. g_kinetis_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
  267. g_kinetis_udc[busid].out_ep[ep_idx].xfer_len = data_len;
  268. g_kinetis_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
  269. return kinetis_start_transfer(busid, ep, (uint8_t *)data, MIN(data_len, g_kinetis_udc[busid].out_ep[ep_idx].ep_mps));
  270. }
  271. void USBD_IRQHandler(uint8_t busid)
  272. {
  273. uint8_t s;
  274. uint8_t pid;
  275. uint8_t ep_idx;
  276. uint8_t dir;
  277. uint8_t odd;
  278. uint16_t bc;
  279. uint8_t is = USB_OTG_DEV->ISTAT;
  280. uint8_t mask = USB_OTG_DEV->INTEN;
  281. kinetis_bd_t *bd;
  282. USB_OTG_DEV->ISTAT = is & ~mask;
  283. is &= mask;
  284. if (is & USB_ISTAT_ERROR_MASK) {
  285. uint32_t es = USB_OTG_DEV->ERRSTAT;
  286. USB_OTG_DEV->ERRSTAT = es;
  287. USB_OTG_DEV->ISTAT = is;
  288. }
  289. if (is & USB_ISTAT_USBRST_MASK) {
  290. USB_OTG_DEV->ISTAT = is;
  291. USB_OTG_DEV->CTL |= USB_CTL_ODDRST_MASK;
  292. USB_OTG_DEV->ADDR = 0;
  293. USB_OTG_DEV->ENDPOINT[0].ENDPT = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK;
  294. for (uint8_t i = 1; i < 16; i++) {
  295. USB_OTG_DEV->ENDPOINT[i].ENDPT = 0;
  296. }
  297. memset(&g_kinetis_bdt[busid], 0, sizeof(g_kinetis_bdt[busid]));
  298. memset(g_kinetis_udc[busid].in_ep, 0, sizeof(struct kinetis_ep_state) * CONFIG_USBDEV_EP_NUM);
  299. memset(g_kinetis_udc[busid].out_ep, 0, sizeof(struct kinetis_ep_state) * CONFIG_USBDEV_EP_NUM);
  300. usbd_event_reset_handler(busid);
  301. kinetis_read_setup(busid);
  302. USB_OTG_DEV->CTL &= ~USB_CTL_ODDRST_MASK;
  303. }
  304. if (is & USB_ISTAT_SLEEP_MASK) {
  305. USB_OTG_DEV->ISTAT = USB_ISTAT_SLEEP_MASK;
  306. }
  307. if (is & USB_ISTAT_RESUME_MASK) {
  308. USB_OTG_DEV->ISTAT = USB_ISTAT_RESUME_MASK;
  309. }
  310. #ifdef CONFIG_USBDEV_SOF_ENABLE
  311. if (is & USB_ISTAT_SOFTOK_MASK) {
  312. USB_OTG_DEV->ISTAT = USB_ISTAT_SOFTOK_MASK;
  313. usbd_event_sof_handler(busid);
  314. }
  315. #endif
  316. if (is & USB_ISTAT_STALL_MASK) {
  317. USB_OTG_DEV->ISTAT = USB_ISTAT_STALL_MASK;
  318. }
  319. if (is & USB_ISTAT_TOKDNE_MASK) {
  320. s = USB_OTG_DEV->STAT;
  321. USB_OTG_DEV->ISTAT = USB_ISTAT_TOKDNE_MASK; /* must be cleared after get STAT */
  322. ep_idx = (s & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT;
  323. dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT;
  324. odd = (s & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
  325. bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd];
  326. pid = bd->tok_pid;
  327. bc = bd->bc;
  328. bd->bdt_stall = 0;
  329. bd->dts = 1;
  330. bd->ninc = 0;
  331. bd->keep = 0;
  332. if (dir) {
  333. g_kinetis_udc[busid].in_ep[ep_idx].ep_odd = odd ^ 1;
  334. } else {
  335. g_kinetis_udc[busid].out_ep[ep_idx].ep_odd = odd ^ 1;
  336. }
  337. if (pid == USB_TOKEN_PID_SETUP) {
  338. USB_OTG_DEV->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
  339. usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)bd->addr);
  340. return;
  341. }
  342. if (dir) {
  343. g_kinetis_udc[busid].in_ep[ep_idx].xfer_buf += bc;
  344. g_kinetis_udc[busid].in_ep[ep_idx].xfer_len -= bc;
  345. g_kinetis_udc[busid].in_ep[ep_idx].actual_xfer_len += bc;
  346. if (g_kinetis_udc[busid].in_ep[ep_idx].xfer_len == 0) {
  347. usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_kinetis_udc[busid].in_ep[ep_idx].actual_xfer_len);
  348. } else {
  349. kinetis_start_transfer(busid, ep_idx | 0x80, g_kinetis_udc[busid].in_ep[ep_idx].xfer_buf,
  350. MIN(g_kinetis_udc[busid].in_ep[ep_idx].xfer_len, g_kinetis_udc[busid].in_ep[ep_idx].ep_mps));
  351. }
  352. } else {
  353. g_kinetis_udc[busid].out_ep[ep_idx].xfer_buf += bc;
  354. g_kinetis_udc[busid].out_ep[ep_idx].xfer_len -= bc;
  355. g_kinetis_udc[busid].out_ep[ep_idx].actual_xfer_len += bc;
  356. if ((bc < g_kinetis_udc[busid].out_ep[ep_idx].ep_mps) || (g_kinetis_udc[busid].out_ep[ep_idx].xfer_len == 0)) {
  357. usbd_event_ep_out_complete_handler(busid, ep_idx, g_kinetis_udc[busid].out_ep[ep_idx].actual_xfer_len);
  358. } else {
  359. kinetis_start_transfer(busid, ep_idx, g_kinetis_udc[busid].out_ep[ep_idx].xfer_buf,
  360. MIN(g_kinetis_udc[busid].out_ep[ep_idx].xfer_len, g_kinetis_udc[busid].out_ep[ep_idx].ep_mps));
  361. }
  362. }
  363. if ((bc == 0) && (ep_idx == 0)) {
  364. if ((g_kinetis_udc[busid].dev_addr > 0) && dir) {
  365. USB_OTG_DEV->ADDR = g_kinetis_udc[busid].dev_addr;
  366. g_kinetis_udc[busid].dev_addr = 0;
  367. }
  368. kinetis_read_setup(busid);
  369. }
  370. }
  371. }