You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

USBHAL_KL25Z.cpp 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. /* Copyright (c) 2010-2011 mbed.org, MIT License
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  4. * and associated documentation files (the "Software"), to deal in the Software without
  5. * restriction, including without limitation the rights to use, copy, modify, merge, publish,
  6. * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
  7. * Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or
  10. * substantial portions of the Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
  13. * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  14. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  15. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. */
  18. #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F)
  19. #include "USBHAL.h"
  20. USBHAL * USBHAL::instance;
  21. static volatile int epComplete = 0;
  22. // Convert physical endpoint number to register bit
  23. #define EP(endpoint) (1<<(endpoint))
  24. // Convert physical to logical
  25. #define PHY_TO_LOG(endpoint) ((endpoint)>>1)
  26. // Get endpoint direction
  27. #define IN_EP(endpoint) ((endpoint) & 1U ? true : false)
  28. #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true)
  29. #define BD_OWN_MASK (1<<7)
  30. #define BD_DATA01_MASK (1<<6)
  31. #define BD_KEEP_MASK (1<<5)
  32. #define BD_NINC_MASK (1<<4)
  33. #define BD_DTS_MASK (1<<3)
  34. #define BD_STALL_MASK (1<<2)
  35. #define TX 1
  36. #define RX 0
  37. #define ODD 0
  38. #define EVEN 1
  39. // this macro waits a physical endpoint number
  40. #define EP_BDT_IDX(ep, dir, odd) (((ep * 4) + (2 * dir) + (1 * odd)))
  41. #define SETUP_TOKEN 0x0D
  42. #define IN_TOKEN 0x09
  43. #define OUT_TOKEN 0x01
  44. #define TOK_PID(idx) ((bdt[idx].info >> 2) & 0x0F)
  45. // for each endpt: 8 bytes
  46. typedef struct BDT {
  47. uint8_t info; // BD[0:7]
  48. uint8_t dummy; // RSVD: BD[8:15]
  49. uint16_t byte_count; // BD[16:32]
  50. uint32_t address; // Addr
  51. } BDT;
  52. // there are:
  53. // * 16 bidirectionnal endpt -> 32 physical endpt
  54. // * as there are ODD and EVEN buffer -> 32*2 bdt
  55. __attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];
  56. uint8_t * endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2];
  57. uint8_t * endpoint_buffer_iso[2*2];
  58. static uint8_t set_addr = 0;
  59. static uint8_t addr = 0;
  60. static uint32_t Data1 = 0x55555555;
  61. static uint32_t frameNumber() {
  62. return((USB0->FRMNUML | (USB0->FRMNUMH << 8)) & 0x07FF);
  63. }
  64. uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
  65. return 0;
  66. }
  67. USBHAL::USBHAL(void) {
  68. // Disable IRQ
  69. NVIC_DisableIRQ(USB0_IRQn);
  70. #if defined(TARGET_K64F)
  71. MPU->CESR=0;
  72. #endif
  73. // fill in callback array
  74. epCallback[0] = &USBHAL::EP1_OUT_callback;
  75. epCallback[1] = &USBHAL::EP1_IN_callback;
  76. epCallback[2] = &USBHAL::EP2_OUT_callback;
  77. epCallback[3] = &USBHAL::EP2_IN_callback;
  78. epCallback[4] = &USBHAL::EP3_OUT_callback;
  79. epCallback[5] = &USBHAL::EP3_IN_callback;
  80. epCallback[6] = &USBHAL::EP4_OUT_callback;
  81. epCallback[7] = &USBHAL::EP4_IN_callback;
  82. epCallback[8] = &USBHAL::EP5_OUT_callback;
  83. epCallback[9] = &USBHAL::EP5_IN_callback;
  84. epCallback[10] = &USBHAL::EP6_OUT_callback;
  85. epCallback[11] = &USBHAL::EP6_IN_callback;
  86. epCallback[12] = &USBHAL::EP7_OUT_callback;
  87. epCallback[13] = &USBHAL::EP7_IN_callback;
  88. epCallback[14] = &USBHAL::EP8_OUT_callback;
  89. epCallback[15] = &USBHAL::EP8_IN_callback;
  90. epCallback[16] = &USBHAL::EP9_OUT_callback;
  91. epCallback[17] = &USBHAL::EP9_IN_callback;
  92. epCallback[18] = &USBHAL::EP10_OUT_callback;
  93. epCallback[19] = &USBHAL::EP10_IN_callback;
  94. epCallback[20] = &USBHAL::EP11_OUT_callback;
  95. epCallback[21] = &USBHAL::EP11_IN_callback;
  96. epCallback[22] = &USBHAL::EP12_OUT_callback;
  97. epCallback[23] = &USBHAL::EP12_IN_callback;
  98. epCallback[24] = &USBHAL::EP13_OUT_callback;
  99. epCallback[25] = &USBHAL::EP13_IN_callback;
  100. epCallback[26] = &USBHAL::EP14_OUT_callback;
  101. epCallback[27] = &USBHAL::EP14_IN_callback;
  102. epCallback[28] = &USBHAL::EP15_OUT_callback;
  103. epCallback[29] = &USBHAL::EP15_IN_callback;
  104. #if defined(TARGET_KL43Z)
  105. // enable USBFS clock
  106. SIM->SCGC4 |= SIM_SCGC4_USBFS_MASK;
  107. // enable the IRC48M clock
  108. USB0->CLK_RECOVER_IRC_EN |= USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK;
  109. // enable the USB clock recovery tuning
  110. USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
  111. // choose usb src clock
  112. SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK;
  113. #elif defined(TARGET_INFINITY)
  114. // USB clock source: FLL
  115. SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK;
  116. // enable OTG clock
  117. SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
  118. #else
  119. // choose usb src as PLL
  120. SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
  121. SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | (1 << SIM_SOPT2_PLLFLLSEL_SHIFT));
  122. // enable OTG clock
  123. SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
  124. #endif
  125. // Attach IRQ
  126. instance = this;
  127. NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr);
  128. NVIC_EnableIRQ(USB0_IRQn);
  129. // USB Module Configuration
  130. // Reset USB Module
  131. USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
  132. while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
  133. // Set BDT Base Register
  134. USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8);
  135. USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16);
  136. USB0->BDTPAGE3 = (uint8_t)((uint32_t)bdt>>24);
  137. // Clear interrupt flag
  138. USB0->ISTAT = 0xff;
  139. // USB Interrupt Enablers
  140. USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK |
  141. USB_INTEN_SOFTOKEN_MASK |
  142. USB_INTEN_ERROREN_MASK |
  143. USB_INTEN_USBRSTEN_MASK;
  144. // Disable weak pull downs
  145. USB0->USBCTRL &= ~(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK);
  146. USB0->USBTRC0 |= 0x40;
  147. }
  148. USBHAL::~USBHAL(void) { }
  149. void USBHAL::connect(void) {
  150. // enable USB
  151. USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
  152. // Pull up enable
  153. USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
  154. }
  155. void USBHAL::disconnect(void) {
  156. // disable USB
  157. USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK;
  158. // Pull up disable
  159. USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
  160. //Free buffers if required:
  161. for (int i = 0; i<(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2; i++) {
  162. free(endpoint_buffer[i]);
  163. endpoint_buffer[i] = NULL;
  164. }
  165. free(endpoint_buffer_iso[2]);
  166. endpoint_buffer_iso[2] = NULL;
  167. free(endpoint_buffer_iso[0]);
  168. endpoint_buffer_iso[0] = NULL;
  169. }
  170. void USBHAL::configureDevice(void) {
  171. // not needed
  172. }
  173. void USBHAL::unconfigureDevice(void) {
  174. // not needed
  175. }
  176. void USBHAL::setAddress(uint8_t address) {
  177. // we don't set the address now otherwise the usb controller does not ack
  178. // we set a flag instead
  179. // see usbisr when an IN token is received
  180. set_addr = 1;
  181. addr = address;
  182. }
  183. bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
  184. uint32_t handshake_flag = 0;
  185. uint8_t * buf;
  186. if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
  187. return false;
  188. }
  189. uint32_t log_endpoint = PHY_TO_LOG(endpoint);
  190. if ((flags & ISOCHRONOUS) == 0) {
  191. handshake_flag = USB_ENDPT_EPHSHK_MASK;
  192. if (IN_EP(endpoint)) {
  193. if (endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] == NULL)
  194. endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] = (uint8_t *) malloc (64*2);
  195. buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0];
  196. } else {
  197. if (endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] == NULL)
  198. endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] = (uint8_t *) malloc (64*2);
  199. buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0];
  200. }
  201. } else {
  202. if (IN_EP(endpoint)) {
  203. if (endpoint_buffer_iso[2] == NULL)
  204. endpoint_buffer_iso[2] = (uint8_t *) malloc (1023*2);
  205. buf = &endpoint_buffer_iso[2][0];
  206. } else {
  207. if (endpoint_buffer_iso[0] == NULL)
  208. endpoint_buffer_iso[0] = (uint8_t *) malloc (1023*2);
  209. buf = &endpoint_buffer_iso[0][0];
  210. }
  211. }
  212. // IN endpt -> device to host (TX)
  213. if (IN_EP(endpoint)) {
  214. USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint)
  215. USB_ENDPT_EPTXEN_MASK; // en TX (IN) tran
  216. bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = (uint32_t) buf;
  217. bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = 0;
  218. }
  219. // OUT endpt -> host to device (RX)
  220. else {
  221. USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint)
  222. USB_ENDPT_EPRXEN_MASK; // en RX (OUT) tran.
  223. bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].byte_count = maxPacket;
  224. bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = (uint32_t) buf;
  225. bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info = BD_OWN_MASK | BD_DTS_MASK;
  226. bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info = 0;
  227. }
  228. Data1 |= (1 << endpoint);
  229. return true;
  230. }
  231. // read setup packet
  232. void USBHAL::EP0setup(uint8_t *buffer) {
  233. uint32_t sz;
  234. endpointReadResult(EP0OUT, buffer, &sz);
  235. }
  236. void USBHAL::EP0readStage(void) {
  237. Data1 &= ~1UL; // set DATA0
  238. bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK);
  239. }
  240. void USBHAL::EP0read(void) {
  241. uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0);
  242. bdt[idx].byte_count = MAX_PACKET_SIZE_EP0;
  243. }
  244. uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
  245. uint32_t sz;
  246. endpointReadResult(EP0OUT, buffer, &sz);
  247. return sz;
  248. }
  249. void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
  250. endpointWrite(EP0IN, buffer, size);
  251. }
  252. void USBHAL::EP0getWriteResult(void) {
  253. }
  254. void USBHAL::EP0stall(void) {
  255. stallEndpoint(EP0OUT);
  256. }
  257. EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
  258. endpoint = PHY_TO_LOG(endpoint);
  259. uint32_t idx = EP_BDT_IDX(endpoint, RX, 0);
  260. bdt[idx].byte_count = maximumSize;
  261. return EP_PENDING;
  262. }
  263. EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
  264. uint32_t n, sz, idx, setup = 0;
  265. uint8_t not_iso;
  266. uint8_t * ep_buf;
  267. uint32_t log_endpoint = PHY_TO_LOG(endpoint);
  268. if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
  269. return EP_INVALID;
  270. }
  271. // if read on a IN endpoint -> error
  272. if (IN_EP(endpoint)) {
  273. return EP_INVALID;
  274. }
  275. idx = EP_BDT_IDX(log_endpoint, RX, 0);
  276. sz = bdt[idx].byte_count;
  277. not_iso = USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK;
  278. //for isochronous endpoint, we don't wait an interrupt
  279. if ((log_endpoint != 0) && not_iso && !(epComplete & EP(endpoint))) {
  280. return EP_PENDING;
  281. }
  282. if ((log_endpoint == 0) && (TOK_PID(idx) == SETUP_TOKEN)) {
  283. setup = 1;
  284. }
  285. // non iso endpoint
  286. if (not_iso) {
  287. ep_buf = endpoint_buffer[idx];
  288. } else {
  289. ep_buf = endpoint_buffer_iso[0];
  290. }
  291. for (n = 0; n < sz; n++) {
  292. buffer[n] = ep_buf[n];
  293. }
  294. if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) {
  295. if (setup && (buffer[6] == 0)) // if no setup data stage,
  296. Data1 &= ~1UL; // set DATA0
  297. else
  298. Data1 ^= (1 << endpoint);
  299. }
  300. if (((Data1 >> endpoint) & 1)) {
  301. bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK;
  302. }
  303. else {
  304. bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK;
  305. }
  306. USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
  307. *bytesRead = sz;
  308. epComplete &= ~EP(endpoint);
  309. return EP_COMPLETED;
  310. }
  311. EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
  312. uint32_t idx, n;
  313. uint8_t * ep_buf;
  314. if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
  315. return EP_INVALID;
  316. }
  317. // if write on a OUT endpoint -> error
  318. if (OUT_EP(endpoint)) {
  319. return EP_INVALID;
  320. }
  321. idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0);
  322. bdt[idx].byte_count = size;
  323. // non iso endpoint
  324. if (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPHSHK_MASK) {
  325. ep_buf = endpoint_buffer[idx];
  326. } else {
  327. ep_buf = endpoint_buffer_iso[2];
  328. }
  329. for (n = 0; n < size; n++) {
  330. ep_buf[n] = data[n];
  331. }
  332. if ((Data1 >> endpoint) & 1) {
  333. bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK;
  334. } else {
  335. bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK;
  336. }
  337. Data1 ^= (1 << endpoint);
  338. return EP_PENDING;
  339. }
  340. EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
  341. if (epComplete & EP(endpoint)) {
  342. epComplete &= ~EP(endpoint);
  343. return EP_COMPLETED;
  344. }
  345. return EP_PENDING;
  346. }
  347. void USBHAL::stallEndpoint(uint8_t endpoint) {
  348. USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK;
  349. }
  350. void USBHAL::unstallEndpoint(uint8_t endpoint) {
  351. USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
  352. }
  353. bool USBHAL::getEndpointStallState(uint8_t endpoint) {
  354. uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK);
  355. return (stall) ? true : false;
  356. }
  357. void USBHAL::remoteWakeup(void) {
  358. // [TODO]
  359. }
  360. void USBHAL::_usbisr(void) {
  361. instance->usbisr();
  362. }
  363. void USBHAL::usbisr(void) {
  364. uint8_t i;
  365. uint8_t istat = USB0->ISTAT;
  366. // reset interrupt
  367. if (istat & USB_ISTAT_USBRST_MASK) {
  368. // disable all endpt
  369. for(i = 0; i < 16; i++) {
  370. USB0->ENDPOINT[i].ENDPT = 0x00;
  371. }
  372. // enable control endpoint
  373. realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
  374. realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
  375. Data1 = 0x55555555;
  376. USB0->CTL |= USB_CTL_ODDRST_MASK;
  377. USB0->ISTAT = 0xFF; // clear all interrupt status flags
  378. USB0->ERRSTAT = 0xFF; // clear all error flags
  379. USB0->ERREN = 0xFF; // enable error interrupt sources
  380. USB0->ADDR = 0x00; // set default address
  381. return;
  382. }
  383. // resume interrupt
  384. if (istat & USB_ISTAT_RESUME_MASK) {
  385. USB0->ISTAT = USB_ISTAT_RESUME_MASK;
  386. }
  387. // SOF interrupt
  388. if (istat & USB_ISTAT_SOFTOK_MASK) {
  389. USB0->ISTAT = USB_ISTAT_SOFTOK_MASK;
  390. // SOF event, read frame number
  391. SOF(frameNumber());
  392. }
  393. // stall interrupt
  394. if (istat & 1<<7) {
  395. if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK)
  396. USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
  397. USB0->ISTAT |= USB_ISTAT_STALL_MASK;
  398. }
  399. // token interrupt
  400. if (istat & 1<<3) {
  401. uint32_t num = (USB0->STAT >> 4) & 0x0F;
  402. uint32_t dir = (USB0->STAT >> 3) & 0x01;
  403. uint32_t ev_odd = (USB0->STAT >> 2) & 0x01;
  404. // setup packet
  405. if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) {
  406. Data1 &= ~0x02;
  407. bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK;
  408. bdt[EP_BDT_IDX(0, TX, ODD)].info &= ~BD_OWN_MASK;
  409. // EP0 SETUP event (SETUP data received)
  410. EP0setupCallback();
  411. } else {
  412. // OUT packet
  413. if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) {
  414. if (num == 0)
  415. EP0out();
  416. else {
  417. epComplete |= (1 << EP(num));
  418. if ((instance->*(epCallback[EP(num) - 2]))()) {
  419. epComplete &= ~(1 << EP(num));
  420. }
  421. }
  422. }
  423. // IN packet
  424. if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) {
  425. if (num == 0) {
  426. EP0in();
  427. if (set_addr == 1) {
  428. USB0->ADDR = addr & 0x7F;
  429. set_addr = 0;
  430. }
  431. }
  432. else {
  433. epComplete |= (1 << (EP(num) + 1));
  434. if ((instance->*(epCallback[EP(num) + 1 - 2]))()) {
  435. epComplete &= ~(1 << (EP(num) + 1));
  436. }
  437. }
  438. }
  439. }
  440. USB0->ISTAT = USB_ISTAT_TOKDNE_MASK;
  441. }
  442. // sleep interrupt
  443. if (istat & 1<<4) {
  444. USB0->ISTAT |= USB_ISTAT_SLEEP_MASK;
  445. }
  446. // error interrupt
  447. if (istat & USB_ISTAT_ERROR_MASK) {
  448. USB0->ERRSTAT = 0xFF;
  449. USB0->ISTAT |= USB_ISTAT_ERROR_MASK;
  450. }
  451. }
  452. #endif