ARM7 based quadrocopter
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.

684 lines
19KB

  1. /***************************************************************************
  2. * sam7fc - USB Device Port with logical Serial Port *
  3. * *
  4. * Copyright (C) 01/2008 by Olaf Rempel *
  5. * razzor@kopf-tisch.de *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; version 2 of the License *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with this program; if not, write to the *
  18. * Free Software Foundation, Inc., *
  19. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  20. ***************************************************************************/
  21. #include <stdio.h>
  22. #include "AT91SAM7S256.h"
  23. #include "at91_pio.h"
  24. #include "board.h"
  25. #include "fifo.h"
  26. #include "telemetrie.h"
  27. #include "usb_ch9.h"
  28. #include "usb_cdc.h"
  29. #include "usb_dfu.h"
  30. #define csr_clear_flags(csr, flags) \
  31. while ((csr) & (flags)) \
  32. (csr) &= ~(flags);
  33. #define csr_set_flags(csr, flags) \
  34. while (((csr) & (flags)) != (flags)) \
  35. (csr) |= (flags);
  36. struct ep_transfer {
  37. uint16_t length;
  38. uint16_t curpos;
  39. char *data;
  40. void (*complete_cb)(void);
  41. };
  42. struct ep_ctx {
  43. uint16_t maxpktsize;
  44. uint16_t flags;
  45. union {
  46. struct ep_transfer *transfer;
  47. struct fifo *fifo;
  48. };
  49. };
  50. #define CTX_TRANSFER 0x01 /* ctx use ep_transfer struct */
  51. #define CTX_FIFO 0x02 /* ctx use fifo */
  52. #define CTX_IN 0x04 /* write to the host */
  53. #define CTX_OUT 0x08 /* read from the host */
  54. #define CTX_RXBANK0 0x10
  55. #define CTX_RXBANK1 0x20
  56. static struct ep_transfer ep0_transfer;
  57. static struct ep_ctx ep_ctx[4];
  58. static uint16_t current_address;
  59. static uint16_t current_config;
  60. static uint16_t current_interface;
  61. static struct comm_device usb_comm;
  62. static const struct usb_device_descriptor dev_descriptor = {
  63. .bLength = sizeof(struct usb_device_descriptor),
  64. .bDescriptorType = USB_DT_DEVICE,
  65. .bcdUSB = 0x0110,
  66. .bMaxPacketSize0 = 8,
  67. .idVendor = USB_VENDOR_ID,
  68. .idProduct = USB_PRODUCT_ID +1,
  69. .bcdDevice = 0x0001,
  70. .iProduct = 0x01,
  71. .bNumConfigurations = 1,
  72. };
  73. struct my_config {
  74. struct usb_config_descriptor cfg;
  75. struct usb_interface_descriptor ctrl_iface;
  76. struct usb_cdc_header_desc cdc_header;
  77. struct usb_cdc_call_mgmt_descriptor cdc_call_mgmt;
  78. struct usb_cdc_acm_descriptor cdc_acm;
  79. struct usb_cdc_union_desc cdc_union;
  80. struct usb_endpoint_descriptor notify_ep;
  81. struct usb_interface_descriptor data_iface;
  82. struct usb_endpoint_descriptor dataout_ep;
  83. struct usb_endpoint_descriptor datain_ep;
  84. struct usb_interface_descriptor dfu_iface;
  85. struct usb_dfu_descriptor dfu;
  86. } __attribute__ ((packed));
  87. static const struct my_config cfg_descriptor = {
  88. .cfg = {
  89. .bLength = sizeof(struct usb_config_descriptor),
  90. .bDescriptorType = USB_DT_CONFIG,
  91. .wTotalLength = sizeof(struct my_config),
  92. .bNumInterfaces = 3,
  93. .bConfigurationValue = 1,
  94. .bmAttributes = USB_CONFIG_ATT_SELFPOWER | USB_CONFIG_ATT_WAKEUP,
  95. .bMaxPower = 50,
  96. },
  97. .ctrl_iface = {
  98. .bLength = sizeof(struct usb_interface_descriptor),
  99. .bDescriptorType = USB_DT_INTERFACE,
  100. .bInterfaceNumber = 0,
  101. .bNumEndpoints = 1,
  102. .bInterfaceClass = USB_CLASS_COMM,
  103. .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
  104. .bInterfaceProtocol = 1,
  105. },
  106. .cdc_header = {
  107. .bLength = sizeof(struct usb_cdc_header_desc),
  108. .bDescriptorType = USB_DT_CS_INTERFACE,
  109. .bDescriptorSubType = USB_CDC_HEADER_TYPE,
  110. .bcdCDC = 0x0110,
  111. },
  112. .cdc_call_mgmt = {
  113. .bLength = sizeof(struct usb_cdc_call_mgmt_descriptor),
  114. .bDescriptorType = USB_DT_CS_INTERFACE,
  115. .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
  116. .bmCapabilities = USB_CDC_CALL_MGMT_CAP_CALL_MGMT,
  117. .bDataInterface = 1,
  118. },
  119. .cdc_acm = {
  120. .bLength = sizeof(struct usb_cdc_acm_descriptor),
  121. .bDescriptorType = USB_DT_CS_INTERFACE,
  122. .bDescriptorSubType = USB_CDC_ACM_TYPE,
  123. .bmCapabilities = (USB_CDC_CAP_BRK | USB_CDC_CAP_LINE | USB_CDC_COMM_FEATURE),
  124. },
  125. .cdc_union = {
  126. .bLength = sizeof(struct usb_cdc_union_desc),
  127. .bDescriptorType = USB_DT_CS_INTERFACE,
  128. .bDescriptorSubType = USB_CDC_UNION_TYPE,
  129. .bMasterInterface0 = 0,
  130. .bSlaveInterface0 = 1,
  131. },
  132. .notify_ep = {
  133. .bLength = sizeof(struct usb_endpoint_descriptor),
  134. .bDescriptorType = USB_DT_ENDPOINT,
  135. .bEndpointAddress = USB_DIR_IN | 0x03,
  136. .bmAttributes = USB_ENDPOINT_XFER_INT,
  137. .wMaxPacketSize = 64,
  138. .bInterval = 10,
  139. },
  140. .data_iface = {
  141. .bLength = sizeof(struct usb_interface_descriptor),
  142. .bDescriptorType = USB_DT_INTERFACE,
  143. .bInterfaceNumber = 1,
  144. .bNumEndpoints = 2,
  145. .bInterfaceClass = USB_CLASS_CDC_DATA,
  146. },
  147. .dataout_ep = {
  148. .bLength = sizeof(struct usb_endpoint_descriptor),
  149. .bDescriptorType = USB_DT_ENDPOINT,
  150. .bEndpointAddress = USB_DIR_OUT | 0x01,
  151. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  152. .wMaxPacketSize = 64,
  153. },
  154. .datain_ep = {
  155. .bLength = sizeof(struct usb_endpoint_descriptor),
  156. .bDescriptorType = USB_DT_ENDPOINT,
  157. .bEndpointAddress = USB_DIR_IN | 0x02,
  158. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  159. .wMaxPacketSize = 64,
  160. },
  161. .dfu_iface = {
  162. .bLength = sizeof(struct usb_interface_descriptor),
  163. .bDescriptorType = USB_DT_INTERFACE,
  164. .bInterfaceNumber = 2,
  165. .bInterfaceClass = USB_CLASS_APP_SPEC,
  166. .bInterfaceSubClass = 0x01, /* DFU */
  167. .bInterfaceProtocol = 0x01,
  168. },
  169. .dfu = {
  170. .bLength = sizeof(struct usb_dfu_descriptor),
  171. .bDescriptorType = USB_TYPE_DFU,
  172. .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_MANIFEST_TOL | USB_DFU_WILL_DETACH,
  173. .wDetachTimeOut = 0xff00,
  174. .wTransferSize = AT91C_IFLASH_PAGE_SIZE,
  175. .bcdDFUVersion = 0x0101,
  176. },
  177. };
  178. /* not const! */
  179. static struct usb_cdc_line_coding cdc_line_coding = {
  180. .dwDTERate = 9600,
  181. .bCharFormat = USB_CDC_1_STOP_BITS,
  182. .bParityType = USB_CDC_NO_PARITY,
  183. .bDataBits = 8,
  184. };
  185. /* not const! */
  186. static struct dfu_status dfu_status = {
  187. .bStatus = DFU_STATUS_OK,
  188. .bState = DFU_STATE_appIDLE,
  189. };
  190. static const struct usb_string_descriptor usb_string0 = {
  191. /* String 0 - Language */
  192. .bLength = sizeof(struct usb_string_descriptor) + 1 * sizeof(uint16_t),
  193. .bDescriptorType = USB_DT_STRING,
  194. .wData = { 0x0409 /* English */ },
  195. };
  196. static const struct usb_string_descriptor usb_string1 = {
  197. /* String 1 "sam7fc" */
  198. .bLength = sizeof(struct usb_string_descriptor) + 6 * sizeof(uint16_t),
  199. .bDescriptorType = USB_DT_STRING,
  200. .wData = {
  201. 0x0073, 0x0061, 0x006d, 0x0037, 0x0066, 0x0063,
  202. },
  203. };
  204. static const struct usb_string_descriptor *usb_strings[] = {
  205. &usb_string0, &usb_string1,
  206. };
  207. void ep_transfer_send(uint32_t ep, char *data, uint32_t length,
  208. void (*complete_cb)(void))
  209. {
  210. struct ep_ctx *ctx = &ep_ctx[ep];
  211. // printf("ep_transfer_send(%ld) size=%ld flags=0x%x\n\r", ep, length, ctx->flags);
  212. if (!(ctx->flags & CTX_TRANSFER) || (ctx->flags & (CTX_IN | CTX_OUT)))
  213. return;
  214. /* from buffer to usb */
  215. ctx->flags |= CTX_IN;
  216. struct ep_transfer *transfer = ctx->transfer;
  217. transfer->length = length;
  218. transfer->curpos = 0;
  219. transfer->data = data;
  220. transfer->complete_cb = complete_cb;
  221. uint32_t maxsize = ctx->maxpktsize;
  222. /* get data from transfer */
  223. while (transfer->curpos < transfer->length && maxsize--)
  224. AT91C_UDP_FDR[ep] = transfer->data[transfer->curpos++];
  225. /* trigger tx */
  226. AT91C_UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
  227. }
  228. void ep_transfer_receive(uint32_t ep, char *data, uint32_t length,
  229. void (*complete_cb)(void))
  230. {
  231. struct ep_ctx *ctx = &ep_ctx[ep];
  232. // printf("ep_transfer_receive(%ld) size=%ld flags=0x%x\n\r", ep, length, ctx->flags);
  233. if (!(ctx->flags & CTX_TRANSFER) || (ctx->flags & (CTX_IN | CTX_OUT)))
  234. return;
  235. /* from usb to buffer */
  236. ctx->flags |= CTX_OUT;
  237. struct ep_transfer *transfer = ctx->transfer;
  238. transfer->length = length;
  239. transfer->curpos = 0;
  240. transfer->data = data;
  241. transfer->complete_cb = complete_cb;
  242. }
  243. /* stalls the endpoint */
  244. static void ep_send_stall(uint32_t ep)
  245. {
  246. printf("usb stall\n\r");
  247. AT91C_UDP_CSR[ep] |= AT91C_UDP_FORCESTALL;
  248. }
  249. static void udp_configure_ep(const struct usb_endpoint_descriptor *desc)
  250. {
  251. /* get endpoint address, set Max Packet Size */
  252. uint32_t ep = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
  253. ep_ctx[ep].maxpktsize = desc->wMaxPacketSize;
  254. /* get endpoint type (ctrl, iso, bulb, int) */
  255. uint32_t eptype = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
  256. if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
  257. eptype |= 0x04;
  258. } else {
  259. ep_ctx[ep].flags |= CTX_RXBANK0;
  260. }
  261. /* configure UDP endpoint and enable interrupt */
  262. AT91C_UDP_CSR[ep] = AT91C_UDP_EPEDS | (eptype << 8);
  263. *AT91C_UDP_IER = (1 << ep);
  264. }
  265. static void udp_print_config(void)
  266. {
  267. printf("usb: addr=%d cfg=%d if=%d\n\r",
  268. current_address, current_config, current_interface);
  269. }
  270. /*
  271. * set local address
  272. * (USB_REQ_SET_ADDRESS callback)
  273. */
  274. static void udp_txcb_setaddress(void)
  275. {
  276. *AT91C_UDP_FADDR = (AT91C_UDP_FEN | current_address);
  277. *AT91C_UDP_GLBSTATE = AT91C_UDP_FADDEN;
  278. udp_print_config();
  279. }
  280. /*
  281. * configure endpoints
  282. * (USB_REQ_SET_CONFIGURATION callback)
  283. */
  284. static void udp_txcb_setconfig(void)
  285. {
  286. udp_configure_ep(&cfg_descriptor.notify_ep);
  287. udp_configure_ep(&cfg_descriptor.datain_ep);
  288. udp_configure_ep(&cfg_descriptor.dataout_ep);
  289. ep_ctx[1].fifo = usb_comm.rxfifo;
  290. ep_ctx[1].flags |= CTX_FIFO;
  291. ep_ctx[2].fifo = usb_comm.txfifo;
  292. ep_ctx[2].flags |= CTX_FIFO;
  293. /* set UDP to "configured" */
  294. *AT91C_UDP_GLBSTATE = AT91C_UDP_CONFG;
  295. udp_print_config();
  296. }
  297. static void ep_handle_ctrlrequest(struct usb_ctrlrequest *req)
  298. {
  299. // printf("typ:0x%02x req:0x%02x val:0x%04x idx:0x%04x len:0x%04x\n\r",
  300. // req->bRequestType, req->bRequest, req->wValue, req->wIndex, req->wLength);
  301. switch (req->bRequestType & (USB_TYPE_MASK | USB_RECIP_MASK)) {
  302. case (USB_TYPE_STANDARD | USB_RECIP_DEVICE): /* 0x00/0x80 */
  303. switch (req->bRequest) {
  304. case USB_REQ_SET_ADDRESS: /* 0x05 */
  305. current_address = req->wValue;
  306. ep_transfer_send(0, NULL, 0, udp_txcb_setaddress);
  307. break;
  308. case USB_REQ_GET_DESCRIPTOR: /* 0x06 */
  309. switch (req->wValue >> 8) {
  310. case USB_DT_DEVICE: /* 0x01 */
  311. ep_transfer_send(0, (char *)&dev_descriptor,
  312. MIN(sizeof(dev_descriptor), req->wLength),
  313. NULL);
  314. break;
  315. case USB_DT_CONFIG: /* 0x02 */
  316. ep_transfer_send(0, (char *)&cfg_descriptor,
  317. MIN(sizeof(cfg_descriptor), req->wLength),
  318. NULL);
  319. break;
  320. case USB_DT_STRING: /* 0x03 */
  321. ;
  322. uint8_t index = req->wValue & 0xFF;
  323. if (index < ARRAY_SIZE(usb_strings)) {
  324. ep_transfer_send(0, (char *)usb_strings[index],
  325. MIN(usb_strings[index]->bLength, req->wLength),
  326. NULL);
  327. } else {
  328. ep_send_stall(0);
  329. }
  330. break;
  331. case USB_DT_CS_DEVICE: /* 0x21 */
  332. ep_transfer_send(0, (char *)&cfg_descriptor.dfu,
  333. MIN(sizeof(cfg_descriptor.dfu), req->wLength),
  334. NULL);
  335. break;
  336. default:
  337. ep_send_stall(0);
  338. break;
  339. }
  340. break;
  341. case USB_REQ_SET_CONFIGURATION: /* 0x09 */
  342. current_config = req->wValue;
  343. ep_transfer_send(0, NULL, 0, udp_txcb_setconfig);
  344. break;
  345. default:
  346. ep_send_stall(0);
  347. break;
  348. }
  349. break;
  350. case (USB_TYPE_STANDARD | USB_RECIP_INTERFACE): /* 0x01/0x81 */
  351. switch (req->bRequest) {
  352. case USB_REQ_SET_INTERFACE: /* 0x0b */
  353. current_interface = req->wValue;
  354. ep_transfer_send(0, NULL, 0, udp_print_config);
  355. break;
  356. default:
  357. ep_send_stall(0);
  358. break;
  359. }
  360. break;
  361. case (USB_TYPE_CLASS | USB_RECIP_INTERFACE): /* 0x21/0xA1 */
  362. // TODO: follow current_interface
  363. switch (req->bRequest) {
  364. case USB_REQ_DFU_DETACH: /* 0x00 */
  365. dfu_status.bStatus = DFU_STATE_appDETACH;
  366. ep_transfer_send(0, NULL, 0, NULL);
  367. break;
  368. case USB_REQ_DFU_GETSTATUS: /* 0x03 */
  369. ep_transfer_send(0, (char *)&dfu_status, sizeof(dfu_status), NULL);
  370. break;
  371. case USB_CDC_REQ_SET_LINE_CODING: /* 0x20 */
  372. ep_transfer_receive(0, (char *)&cdc_line_coding, sizeof(cdc_line_coding), NULL);
  373. break;
  374. case USB_CDC_REQ_GET_LINE_CODING: /* 0x21 */
  375. ep_transfer_send(0, (char *)&cdc_line_coding, sizeof(cdc_line_coding), NULL);
  376. break;
  377. case USB_CDC_REQ_SET_CONTROL_LINE_STATE: /* 0x22 */
  378. ep_transfer_send(0, NULL, 0, NULL);
  379. break;
  380. default:
  381. ep_send_stall(0);
  382. break;
  383. }
  384. break;
  385. default:
  386. ep_send_stall(0);
  387. break;
  388. }
  389. }
  390. static void udp_handle_ep(uint32_t ep)
  391. {
  392. /* endpoint enabled? */
  393. AT91_REG *csr = &AT91C_UDP_CSR[ep];
  394. if (!(*csr & AT91C_UDP_EPEDS))
  395. return;
  396. /* clear STALLSENT interrupt */
  397. if (*csr & AT91C_UDP_STALLSENT)
  398. csr_clear_flags(*csr, (AT91C_UDP_STALLSENT | AT91C_UDP_FORCESTALL));
  399. /* ctrl request packet? */
  400. if (*csr & AT91C_UDP_RXSETUP) {
  401. struct usb_ctrlrequest req;
  402. uint8_t *p;
  403. for (p = (uint8_t *)&req; p < (uint8_t *)(&req +1); p++)
  404. *p = AT91C_UDP_FDR[ep];
  405. /* ack bank0 *now */
  406. if (*csr & AT91C_UDP_RX_DATA_BK0)
  407. csr_clear_flags(*csr, AT91C_UDP_RX_DATA_BK0);
  408. /* set data phase transfer direction */
  409. if (req.bRequestType & USB_DIR_IN)
  410. *csr |= AT91C_UDP_DIR;
  411. /* clear interrupt - *MUST* use csr_clear_flags() here */
  412. csr_clear_flags(*csr, AT91C_UDP_RXSETUP);
  413. ep_handle_ctrlrequest(&req);
  414. }
  415. void (* transfer_cb)(void) = NULL;
  416. /* transmit complete? */
  417. if (*csr & AT91C_UDP_TXCOMP) {
  418. struct ep_ctx *ctx = &ep_ctx[ep];
  419. if (ctx->flags & CTX_FIFO) {
  420. /* get data from fifo */
  421. if (fifo_txudp(ctx->fifo, ep, ctx->maxpktsize)) {
  422. AT91C_UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
  423. } else {
  424. ctx->flags &= ~CTX_IN;
  425. }
  426. } else if ((ctx->flags & (CTX_TRANSFER | CTX_IN)) == (CTX_TRANSFER | CTX_IN)) {
  427. /* transfer not complete */
  428. struct ep_transfer *transfer = ctx->transfer;
  429. if (transfer->length != transfer->curpos) {
  430. uint32_t maxsize = ctx->maxpktsize;
  431. /* get data from transfer */
  432. while (transfer->curpos < transfer->length && maxsize--)
  433. AT91C_UDP_FDR[ep] = transfer->data[transfer->curpos++];
  434. /* trigger tx */
  435. AT91C_UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
  436. /* transfer complete, execute callback */
  437. } else {
  438. ctx->flags &= ~CTX_IN;
  439. transfer_cb = transfer->complete_cb;
  440. }
  441. }
  442. /* clear interrupt */
  443. *csr &= ~(AT91C_UDP_TXCOMP);
  444. }
  445. /* data ready to read? */
  446. if (*csr & (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1)) {
  447. struct ep_ctx *ctx = &ep_ctx[ep];
  448. uint16_t len = (*csr & AT91C_UDP_RXBYTECNT) >> 16;
  449. // TODO: only ep0 status OUT?
  450. if (!len && (ctx->flags & CTX_TRANSFER)) {
  451. ctx->flags &= ~(CTX_OUT | CTX_IN);
  452. ctx->transfer->length = 0;
  453. ctx->transfer->curpos = 0;
  454. }
  455. if (ctx->flags & CTX_FIFO) {
  456. fifo_rxudp(ctx->fifo, ep, len);
  457. } else if ((ctx->flags & (CTX_TRANSFER | CTX_OUT)) == (CTX_TRANSFER | CTX_OUT)) {
  458. /* transfer not complete */
  459. struct ep_transfer *transfer = ctx->transfer;
  460. if (transfer->length != transfer->curpos) {
  461. /* get data from transfer */
  462. while (transfer->curpos < transfer->length && len--)
  463. transfer->data[transfer->curpos++] = AT91C_UDP_FDR[ep];
  464. }
  465. /* test again */
  466. if (transfer->length == transfer->curpos) {
  467. ctx->flags &= ~CTX_OUT;
  468. transfer_cb = transfer->complete_cb;
  469. }
  470. }
  471. if (ctx->flags & CTX_RXBANK0) {
  472. if (*csr & AT91C_UDP_RX_DATA_BK0)
  473. csr_clear_flags(*csr, AT91C_UDP_RX_DATA_BK0);
  474. /* all but ep0 have ping pong buffers */
  475. if (ep > 0)
  476. ctx->flags = (ctx->flags & ~CTX_RXBANK0) | CTX_RXBANK1;
  477. } else if (ctx->flags & CTX_RXBANK1) {
  478. if (*csr & AT91C_UDP_RX_DATA_BK1)
  479. csr_clear_flags(*csr, AT91C_UDP_RX_DATA_BK1);
  480. ctx->flags = (ctx->flags & ~CTX_RXBANK1) | CTX_RXBANK0;
  481. }
  482. }
  483. if (transfer_cb)
  484. transfer_cb();
  485. }
  486. static void udp_isr(void)
  487. {
  488. uint32_t isr = *AT91C_UDP_ISR;
  489. if (isr & AT91C_UDP_ENDBUSRES) {
  490. AT91S_UDP *udp = AT91C_BASE_UDP;
  491. /* reset all endpoints */
  492. udp->UDP_RSTEP = (AT91C_UDP_EP0 | AT91C_UDP_EP1 |
  493. AT91C_UDP_EP2 | AT91C_UDP_EP3) ;
  494. udp->UDP_RSTEP = 0;
  495. /* init ep0 */
  496. struct ep_ctx *ctx = &ep_ctx[0];
  497. ctx->maxpktsize = 8;
  498. ctx->flags = CTX_TRANSFER | CTX_RXBANK0;
  499. ctx->transfer = &ep0_transfer;
  500. ctx->transfer->length = 0;
  501. ctx->transfer->curpos = 0;
  502. /* Configure endpoint0 as Control EP */
  503. udp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
  504. /* enable ep0 Interrupt, disable all others */
  505. udp->UDP_IER = AT91C_UDP_EPINT0;
  506. udp->UDP_IDR = AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3 |
  507. AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | AT91C_UDP_SOFINT |
  508. AT91C_UDP_WAKEUP;
  509. if (dfu_status.bStatus == DFU_STATE_appDETACH) {
  510. void (* bootloader)(void) = (void *)0x13c000;
  511. bootloader();
  512. while (1);
  513. }
  514. }
  515. /* Handle Endpoint Interrupts */
  516. uint32_t i;
  517. for (i = 0; i < 4; i++) {
  518. if (isr & *AT91C_UDP_IMR & (1<<i))
  519. udp_handle_ep(i);
  520. }
  521. /* clear all unhandled interrupts */
  522. *AT91C_UDP_ICR = isr & (AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM |
  523. AT91C_UDP_ENDBUSRES | AT91C_UDP_WAKEUP);
  524. }
  525. static void trigger_fifo_tx(void)
  526. {
  527. struct ep_ctx *ctx = &ep_ctx[2];
  528. /* currently transmitting, no need to trigger */
  529. // TODO: racy?
  530. if (ctx->flags & CTX_IN)
  531. return;
  532. if (fifo_txudp(ctx->fifo, 2, ctx->maxpktsize)) {
  533. ctx->flags |= CTX_IN;
  534. AT91C_UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
  535. }
  536. }
  537. void at91_udp_init(void)
  538. {
  539. /* configure & disable Pullup, disable Pullup von VBUS */
  540. AT91PS_PIO pio = AT91C_BASE_PIOA;
  541. pio->PIO_CODR = UDP_PULLUP;
  542. pio->PIO_PER = UDP_PULLUP;
  543. pio->PIO_OER = UDP_PULLUP;
  544. /* UDPCK (48MHz) = PLLCK / 2 */
  545. *AT91C_CKGR_PLLR |= AT91C_CKGR_USBDIV_1;
  546. /* enable UDP clocks */
  547. *AT91C_PMC_SCER = AT91C_PMC_UDP;
  548. *AT91C_PMC_PCER = (1 << AT91C_ID_UDP);
  549. /* enable transmitter */
  550. *AT91C_UDP_TXVC &= ~AT91C_UDP_TXVDIS;
  551. /* clear & disable all UDP interrupts */
  552. *AT91C_UDP_IDR = AT91C_UDP_EPINT0 | AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 |
  553. AT91C_UDP_EPINT3 | AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM |
  554. AT91C_UDP_SOFINT | AT91C_UDP_WAKEUP;
  555. *AT91C_UDP_ICR = AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | AT91C_UDP_SOFINT |
  556. AT91C_UDP_ENDBUSRES | AT91C_UDP_WAKEUP ;
  557. /* level triggered, own vector */
  558. AT91S_AIC *aic = AT91C_BASE_AIC;
  559. aic->AIC_SMR[AT91C_ID_UDP] = IRQPRIO_UDP | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
  560. aic->AIC_SVR[AT91C_ID_UDP] = (uint32_t)udp_isr;
  561. aic->AIC_IECR = (1 << AT91C_ID_UDP);
  562. usb_comm.rxfifo = fifo_alloc(1024);
  563. usb_comm.txfifo = fifo_alloc(1024);
  564. usb_comm.trigger_tx = trigger_fifo_tx;
  565. tdc_register_device(0, &usb_comm);
  566. pio_trigger_isr(UDP_VBUS_MON);
  567. }
  568. static void udp_vbus_monitor(uint32_t status, uint32_t input)
  569. {
  570. if (input & UDP_VBUS_MON)
  571. /* usb connected -> enable pullup */
  572. *AT91C_PIOA_CODR = UDP_PULLUP;
  573. else
  574. /* usb got diconnected -> disable pullup */
  575. *AT91C_PIOA_SODR = UDP_PULLUP;
  576. }
  577. PIO_PINCHANGE_ISR(UDP_VBUS_MON, udp_vbus_monitor);