1 /* AT91SAM7 USB interface code for OpenPCD
2 * (C) 2006 by Harald Welte <laforge@gnumonks.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * based on existing AT91SAM7 UDP CDC ACM example code, licensed as followed:
19 *----------------------------------------------------------------------------
20 * ATMEL Microcontroller Software Support - ROUSSET -
21 *----------------------------------------------------------------------------
22 * The software is delivered "AS IS" without warranty or condition of any
23 * kind, either express, implied or statutory. This includes without
24 * limitation any warranty or condition with respect to merchantability or
25 * fitness for any particular purpose, or against the infringements of
26 * intellectual property rights of others.
27 *----------------------------------------------------------------------------
32 #include <sys/types.h>
33 #include <asm/atomic.h>
34 #include <lib_AT91SAM7.h>
37 #include <usb_strings_app.h>
39 #include <os/pcd_enumerate.h>
40 #include <os/req_ctx.h>
42 #include "../openpcd.h"
45 #include "../config.h"
47 //#define DEBUG_UDP_IRQ
48 //#define DEBUG_UDP_IRQ_IN
49 //#define DEBUG_UDP_IRQ_OUT
53 #define DEBUGI(x, args ...) DEBUGP(x, ## args)
55 #define DEBUGI(x, args ...) do { } while (0)
58 #ifdef DEBUG_UDP_IRQ_IN
59 #define DEBUGII(x, args ...) DEBUGP(x, ## args)
61 #define DEBUGII(x, args ...) do { } while (0)
64 #ifdef DEBUG_UDP_IRQ_OUT
65 #define DEBUGIO(x, args ...) DEBUGP(x, ## args)
67 #define DEBUGIO(x, args ...) do { } while (0)
71 #define DEBUGE(x, args ...) DEBUGP(x, ## args)
73 #define DEBUGE(x, args ...) do { } while (0)
79 static const struct dfuapi *dfu = DFU_API_LOCATION;
80 #define udp_init dfu->udp_init
81 //#define udp_ep0_send_data dfu->ep0_send_data
82 #define udp_ep0_send_zlp dfu->ep0_send_zlp
83 #define udp_ep0_send_stall dfu->ep0_send_stall
85 #error non-DFU builds currently not supported (yet) again
89 #include "usb_descriptors_hid.h"
91 #include "usb_descriptors_openpcd.h"
94 static struct udp_pcd upcd;
98 u_int32_t state_pending;
101 static const struct epstate epstate[] = {
102 [0] = { .state_busy = RCTX_STATE_INVALID },
103 [1] = { .state_busy = RCTX_STATE_INVALID },
104 [2] = { .state_busy = RCTX_STATE_UDP_EP2_BUSY,
105 .state_pending = RCTX_STATE_UDP_EP2_PENDING },
106 [3] = { .state_busy = RCTX_STATE_UDP_EP3_BUSY,
107 .state_pending = RCTX_STATE_UDP_EP3_PENDING },
110 /* Send Data through the control endpoint */
111 static void udp_ep0_send_data(const char *pData, u_int32_t length)
113 AT91PS_UDP pUdp = AT91C_BASE_UDP;
117 DEBUGE("send_data: %u bytes ", length);
120 cpt = MIN(length, 8);
123 DEBUGE("fifo_fill ");
125 pUdp->UDP_FDR[0] = *pData++;
127 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
128 DEBUGE("wait_txcomp_clear ");
129 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
130 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ;
133 DEBUGE("set_txpktrdy ");
134 pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
135 DEBUGE("wait_txcomp ");
137 csr = pUdp->UDP_CSR[0];
139 /* Data IN stage has been stopped by a status OUT */
140 if (csr & AT91C_UDP_RX_DATA_BK0) {
141 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
142 DEBUGE("stopped by status out ");
145 } while (!(csr & AT91C_UDP_TXCOMP));
149 DEBUGE("clear_txcomp ");
150 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
151 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
152 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ;
157 static void reset_ep(unsigned int ep)
159 AT91PS_UDP pUDP = upcd.pUdp;
160 struct req_ctx *rctx;
162 //pUDP->UDP_CSR[ep] = AT91C_UDP_EPEDS;
164 atomic_set(&upcd.ep[ep].pkts_in_transit, 0);
166 /* free all currently transmitting contexts */
167 while ((rctx = req_ctx_find_get(0, epstate[ep].state_busy,
168 RCTX_STATE_FREE))) {}
169 /* free all currently pending contexts */
170 while ((rctx = req_ctx_find_get(0, epstate[ep].state_pending,
171 RCTX_STATE_FREE))) {}
173 pUDP->UDP_RSTEP |= (1 << ep);
174 pUDP->UDP_RSTEP &= ~(1 << ep);
176 upcd.ep[ep].incomplete.rctx = NULL;
179 static void udp_ep0_handler(void);
181 void udp_unthrottle(void)
183 AT91PS_UDP pUDP = upcd.pUdp;
184 pUDP->UDP_IER = AT91C_UDP_EPINT1;
187 static int __udp_refill_ep(int ep)
190 AT91PS_UDP pUDP = upcd.pUdp;
191 struct req_ctx *rctx;
192 unsigned int start, end;
194 /* If we're not configured by the host yet, there is no point
195 * in trying to send data to it... */
196 if (!upcd.cur_config) {
200 /* If there are already two packets in transit, the DPR of
201 * the SAM7 UDC doesn't have space for more data */
202 if (atomic_read(&upcd.ep[ep].pkts_in_transit) == 2) {
206 /* If we have an incompletely-transmitted req_ctx (>EP size),
207 * we need to transmit the rest and finish the transaction */
208 if (upcd.ep[ep].incomplete.rctx) {
209 rctx = upcd.ep[ep].incomplete.rctx;
210 start = upcd.ep[ep].incomplete.bytes_sent;
212 /* get pending rctx and start transmitting from zero */
213 rctx = req_ctx_find_get(0, epstate[ep].state_pending,
214 epstate[ep].state_busy);
219 upcd.ep[ep].incomplete.bytes_sent = 0;
222 if (rctx->tot_len - start <= AT91C_EP_IN_SIZE)
225 end = start + AT91C_EP_IN_SIZE;
228 DEBUGII("RCTX_tx(ep=%u,ctx=%u):%u ", ep, req_ctx_num(rctx),
230 for (i = start; i < end; i++)
231 pUDP->UDP_FDR[ep] = rctx->data[i];
233 if (atomic_inc_return(&upcd.ep[ep].pkts_in_transit) == 1) {
234 /* not been transmitting before, start transmit */
235 pUDP->UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
238 if ((end - start < AT91C_EP_OUT_SIZE) ||
239 (((end - start) == 0) && end && (rctx->tot_len % AT91C_EP_OUT_SIZE) == 0)) {
240 /* CASE 1: return context to pool, if
241 * - packet transfer < AT91C_EP_OUT_SIZE
242 * - after ZLP of transfer == AT91C_EP_OUT_SIZE
243 * - after ZLP of transfer % AT91C_EP_OUT_SIZE == 0
244 * - after last packet of transfer % AT91C_EP_OUT_SIZE != 0
246 DEBUGII("RCTX(ep=%u,ctx=%u)_tx_done ", ep, req_ctx_num(rctx));
247 upcd.ep[ep].incomplete.rctx = NULL;
250 /* CASE 2: mark transfer as incomplete, if
251 * - after data of transfer == AT91C_EP_OUT_SIZE
252 * - after data of transfer > AT91C_EP_OUT_SIZE
253 * - after last packet of transfer % AT91C_EP_OUT_SIZE == 0
255 upcd.ep[ep].incomplete.rctx = rctx;
256 upcd.ep[ep].incomplete.bytes_sent += end - start;
257 DEBUGII("RCTX(ep=%u)_tx_cont ", ep);
263 int udp_refill_ep(int ep)
268 local_irq_save(flags);
269 ret = __udp_refill_ep(ep);
270 local_irq_restore(flags);
275 static void udp_irq(void)
278 AT91PS_UDP pUDP = upcd.pUdp;
279 AT91_REG isr = pUDP->UDP_ISR;
281 DEBUGI("udp_irq(imr=0x%04x, isr=0x%04x, state=%d): ",
282 pUDP->UDP_IMR, isr, upcd.state);
284 if (isr & AT91C_UDP_ENDBUSRES) {
285 DEBUGI("ENDBUSRES ");
286 pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
287 pUDP->UDP_IER = AT91C_UDP_EPINT0;
288 /* reset all endpoints */
289 pUDP->UDP_RSTEP = (unsigned int)-1;
291 /* Enable the function */
292 pUDP->UDP_FADDR = AT91C_UDP_FEN;
293 /* Configure endpoint 0 */
294 pUDP->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
296 upcd.state = USB_STATE_DEFAULT;
303 if (*dfu->dfu_state == DFU_STATE_appDETACH) {
304 DEBUGI("DFU_SWITCH ");
305 /* now we need to switch to DFU mode */
312 if (isr & AT91C_UDP_EPINT0) {
313 DEBUGI("EP0INT(Control) ");
316 if (isr & AT91C_UDP_EPINT1) {
317 u_int32_t cur_rcv_bank = upcd.cur_rcv_bank;
318 u_int16_t i, pkt_size;
319 struct req_ctx *rctx;
321 csr = pUDP->UDP_CSR[1];
322 pkt_size = csr >> 16;
324 DEBUGI("EP1INT(Out, CSR=0x%08x) ", csr);
325 if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK1)
326 DEBUGIO("cur_bank=1 ");
327 else if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK0)
328 DEBUGIO("cur_bank=0 ");
330 DEBUGIO("cur_bank INVALID ");
332 if (csr & AT91C_UDP_RX_DATA_BK1)
334 if (csr & AT91C_UDP_RX_DATA_BK0)
337 if (!(csr & cur_rcv_bank))
340 if (upcd.ep[1].incomplete.rctx) {
341 DEBUGIO("continue_incompl_RCTX ");
342 rctx = upcd.ep[1].incomplete.rctx;
344 /* allocate new req_ctx */
345 DEBUGIO("alloc_new_RCTX ");
347 /* whether to get a big or a small req_ctx */
348 if (pkt_size >= AT91C_EP_IN_SIZE)
349 rctx = req_ctx_find_get(1, RCTX_STATE_FREE,
350 RCTX_STATE_UDP_RCV_BUSY);
352 rctx = req_ctx_find_get(0, RCTX_STATE_FREE,
353 RCTX_STATE_UDP_RCV_BUSY);
356 /* disable interrupts for now */
357 pUDP->UDP_IDR = AT91C_UDP_EPINT1;
358 DEBUGP("NO_RCTX_AVAIL! ");
363 DEBUGIO("RCTX=%u ", req_ctx_num(rctx));
365 if (rctx->size - rctx->tot_len < pkt_size) {
366 DEBUGIO("RCTX too small, truncating !!!\n");
367 pkt_size = rctx->size - rctx->tot_len;
370 for (i = 0; i < pkt_size; i++)
371 rctx->data[rctx->tot_len++] = pUDP->UDP_FDR[1];
373 pUDP->UDP_CSR[1] &= ~cur_rcv_bank;
375 /* toggle current receive bank */
376 if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK0)
377 cur_rcv_bank = AT91C_UDP_RX_DATA_BK1;
379 cur_rcv_bank = AT91C_UDP_RX_DATA_BK0;
380 upcd.cur_rcv_bank = cur_rcv_bank;
382 DEBUGIO("rctxdump(%s) ", hexdump(rctx->data, rctx->tot_len));
384 /* if this is the last packet in transfer, hand rctx up the
386 if (pkt_size < AT91C_EP_IN_SIZE) {
387 DEBUGIO("RCTX_rx_done ");
388 req_ctx_set_state(rctx, RCTX_STATE_UDP_RCV_DONE);
389 upcd.ep[1].incomplete.rctx = NULL;
391 DEBUGIO("RCTX_rx_cont ");
392 upcd.ep[1].incomplete.rctx = rctx;
396 if (isr & AT91C_UDP_EPINT2) {
397 csr = pUDP->UDP_CSR[2];
398 DEBUGI("EP2INT(In, CSR=0x%08x) ", csr);
399 if (csr & AT91C_UDP_TXCOMP) {
400 DEBUGII("ACK_TX_COMP ");
401 /* acknowledge TX completion */
402 pUDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
403 while (pUDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) ;
405 /* if we already have another packet in DPR, send it */
406 if (atomic_dec_return(&upcd.ep[2].pkts_in_transit) == 1)
407 pUDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
412 if (isr & AT91C_UDP_EPINT3) {
413 csr = pUDP->UDP_CSR[3];
414 DEBUGII("EP3INT(Interrupt, CSR=0x%08x) ", csr);
415 /* Transmit has completed, re-fill from pending rcts for EP3 */
416 if (csr & AT91C_UDP_TXCOMP) {
417 pUDP->UDP_CSR[3] &= ~AT91C_UDP_TXCOMP;
418 while (pUDP->UDP_CSR[3] & AT91C_UDP_TXCOMP) ;
420 /* if we already have another packet in DPR, send it */
421 if (atomic_dec_return(&upcd.ep[3].pkts_in_transit) == 1)
422 pUDP->UDP_CSR[3] |= AT91C_UDP_TXPKTRDY;
427 if (isr & AT91C_UDP_RXSUSP) {
428 pUDP->UDP_ICR = AT91C_UDP_RXSUSP;
430 #ifdef CONFIG_USB_SUSPEND
431 upcd.state = USB_STATE_SUSPENDED;
432 /* FIXME: implement suspend/resume correctly. This
433 * involves saving the pre-suspend state, and calling back
434 * into the main application program to ask it to power down
435 * all peripherals, switching to slow clock, ... */
438 if (isr & AT91C_UDP_RXRSM) {
439 pUDP->UDP_ICR = AT91C_UDP_RXRSM;
441 #ifdef CONFIG_USB_SUSPEND
442 if (upcd.state == USB_STATE_SUSPENDED)
443 upcd.state = USB_STATE_CONFIGURED;
444 /* FIXME: implement suspend/resume */
447 if (isr & AT91C_UDP_EXTRSM) {
448 pUDP->UDP_ICR = AT91C_UDP_EXTRSM;
450 /* FIXME: implement suspend/resume */
452 if (isr & AT91C_UDP_SOFINT) {
453 pUDP->UDP_ICR = AT91C_UDP_SOFINT;
456 if (isr & AT91C_UDP_WAKEUP) {
457 pUDP->UDP_ICR = AT91C_UDP_WAKEUP;
462 AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_UDP);
465 void udp_pullup_on(void)
468 AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
470 AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUPv4);
473 void udp_pullup_off(void)
476 AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
478 AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUPv4);
481 /* Open USB Device Port */
484 DEBUGPCRF("entering");
486 upcd.pUdp = AT91C_BASE_UDP;
488 upcd.cur_rcv_bank = AT91C_UDP_RX_DATA_BK0;
489 /* This should start with USB_STATE_NOTATTACHED, but we're a pure
490 * bus powered device and thus start with powered */
491 upcd.state = USB_STATE_POWERED;
493 AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_UDP,
494 OPENPCD_IRQ_PRIO_UDP,
495 AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &udp_irq);
496 AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_UDP);
498 /* End-of-Bus-Reset is always enabled */
500 /* Set the Pull up resistor */
509 for (i = 0; i < 0xffff; i++)
514 /* Handle requests on the USB Control Endpoint */
515 static void udp_ep0_handler(void)
517 AT91PS_UDP pUDP = upcd.pUdp;
518 u_int8_t bmRequestType, bRequest;
519 u_int16_t wValue, wIndex, wLength, wStatus;
520 u_int32_t csr = pUDP->UDP_CSR[0];
522 DEBUGE("CSR=0x%04x ", csr);
524 if (csr & AT91C_UDP_STALLSENT) {
525 DEBUGE("ACK_STALLSENT ");
526 pUDP->UDP_CSR[0] = ~AT91C_UDP_STALLSENT;
529 if (csr & AT91C_UDP_RX_DATA_BK0) {
530 DEBUGE("ACK_BANK0 ");
531 pUDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
534 if (!(csr & AT91C_UDP_RXSETUP)) {
535 DEBUGE("no setup packet ");
539 DEBUGE("len=%d ", csr >> 16);
540 if (csr >> 16 == 0) {
541 DEBUGE("empty packet ");
545 bmRequestType = pUDP->UDP_FDR[0];
546 bRequest = pUDP->UDP_FDR[0];
547 wValue = (pUDP->UDP_FDR[0] & 0xFF);
548 wValue |= (pUDP->UDP_FDR[0] << 8);
549 wIndex = (pUDP->UDP_FDR[0] & 0xFF);
550 wIndex |= (pUDP->UDP_FDR[0] << 8);
551 wLength = (pUDP->UDP_FDR[0] & 0xFF);
552 wLength |= (pUDP->UDP_FDR[0] << 8);
554 DEBUGE("bmRequestType=0x%2x ", bmRequestType);
556 if (bmRequestType & 0x80) {
557 DEBUGE("DATA_IN=1 ");
558 pUDP->UDP_CSR[0] |= AT91C_UDP_DIR;
559 while (!(pUDP->UDP_CSR[0] & AT91C_UDP_DIR)) ;
561 pUDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
562 while ((pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)) ;
564 DEBUGE("dfu_state = %u ", *dfu->dfu_state);
565 /* Handle supported standard device request Cf Table 9-3 in USB
566 * speciication Rev 1.1 */
567 switch ((bRequest << 8) | bmRequestType) {
568 u_int8_t desc_type, desc_index;
569 case STD_GET_DESCRIPTOR:
570 DEBUGE("GET_DESCRIPTOR(wValue=0x%04x, wIndex=0x%04x) ",
572 desc_type = wValue >> 8;
573 desc_index = wValue & 0xff;
576 /* Return Device Descriptor */
578 if (*dfu->dfu_state != DFU_STATE_appIDLE)
579 udp_ep0_send_data((const char *)
580 dfu->dfu_dev_descriptor,
581 MIN(dfu->dfu_dev_descriptor->bLength,
585 udp_ep0_send_data((const char *) &dev_descriptor,
586 MIN(sizeof(dev_descriptor), wLength));
589 /* Return Configuration Descriptor */
591 if (*dfu->dfu_state != DFU_STATE_appIDLE)
592 udp_ep0_send_data((const char *)
593 dfu->dfu_cfg_descriptor,
594 MIN(dfu->dfu_cfg_descriptor->ucfg.wTotalLength,
598 udp_ep0_send_data((const char *) &cfg_descriptor,
599 MIN(sizeof(cfg_descriptor), wLength));
602 #ifdef CONFIG_USB_STRING
603 /* Return String descriptor */
604 if (desc_index > ARRAY_SIZE(usb_strings))
606 DEBUGE("bLength=%u, wLength=%u\n",
607 usb_strings[desc_index]->bLength, wLength);
608 udp_ep0_send_data((const char *) usb_strings[desc_index],
609 MIN(usb_strings[desc_index]->bLength,
615 case USB_DT_CS_DEVICE:
616 /* Return Function descriptor */
617 udp_ep0_send_data((const char *) &dfu->dfu_cfg_descriptor->func_dfu,
618 MIN(sizeof(dfu->dfu_cfg_descriptor->func_dfu), wLength));
620 case USB_DT_INTERFACE:
621 /* Return Interface descriptor */
622 if (desc_index > cfg_descriptor.ucfg.bNumInterfaces)
624 switch (desc_index) {
626 udp_ep0_send_data((const char *)
628 MIN(sizeof(cfg_descriptor.uif),
633 udp_ep0_send_data((const char *)
634 &cfg_descriptor.uif_dfu[0],
635 MIN(sizeof(cfg_descriptor.uif_dfu[0]),
639 udp_ep0_send_data((const char *)
640 &cfg_descriptor.uif_dfu[1],
641 MIN(sizeof(cfg_descriptor.uif_dfu[1]),
655 case STD_SET_ADDRESS:
656 DEBUGE("SET_ADDRESS ");
660 switch (upcd.state) {
661 case USB_STATE_DEFAULT:
666 pUDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);
667 pUDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
668 upcd.state = USB_STATE_ADDRESS;
671 case USB_STATE_ADDRESS:
674 upcd.state = USB_STATE_DEFAULT;
676 pUDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);
684 case STD_SET_CONFIGURATION:
685 DEBUGE("SET_CONFIG ");
686 if (upcd.state != USB_STATE_ADDRESS &&
687 upcd.state != USB_STATE_CONFIGURED) {
690 if ((wValue & 0xff) == 0) {
692 upcd.state = USB_STATE_ADDRESS;
693 pUDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
694 pUDP->UDP_CSR[1] = 0;
695 pUDP->UDP_CSR[2] = 0;
696 pUDP->UDP_CSR[3] = 0;
697 } else if ((wValue & 0xff) <=
698 dev_descriptor.bNumConfigurations) {
700 upcd.state = USB_STATE_CONFIGURED;
701 pUDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
702 pUDP->UDP_CSR[1] = AT91C_UDP_EPEDS |
703 AT91C_UDP_EPTYPE_BULK_OUT;
704 pUDP->UDP_CSR[2] = AT91C_UDP_EPEDS |
705 AT91C_UDP_EPTYPE_BULK_IN;
706 pUDP->UDP_CSR[3] = AT91C_UDP_EPEDS |
707 AT91C_UDP_EPTYPE_INT_IN;
709 /* invalid configuration */
713 upcd.cur_config = wValue;
715 pUDP->UDP_IER = (AT91C_UDP_EPINT0 | AT91C_UDP_EPINT1 |
716 AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3);
718 case STD_GET_CONFIGURATION:
719 DEBUGE("GET_CONFIG ");
720 switch (upcd.state) {
721 case USB_STATE_ADDRESS:
722 case USB_STATE_CONFIGURED:
723 udp_ep0_send_data((char *)&(upcd.cur_config),
724 sizeof(upcd.cur_config));
731 case STD_GET_INTERFACE:
732 DEBUGE("GET_INTERFACE ");
733 if (upcd.state != USB_STATE_CONFIGURED)
735 udp_ep0_send_data((char *)&(upcd.cur_altsett),
736 sizeof(upcd.cur_altsett));
738 case STD_GET_STATUS_ZERO:
739 DEBUGE("GET_STATUS_ZERO ");
741 udp_ep0_send_data((char *)&wStatus, sizeof(wStatus));
743 case STD_GET_STATUS_INTERFACE:
744 DEBUGE("GET_STATUS_INTERFACE ");
745 if (upcd.state == USB_STATE_DEFAULT ||
746 (upcd.state == USB_STATE_ADDRESS && wIndex != 0))
749 udp_ep0_send_data((char *)&wStatus, sizeof(wStatus));
751 case STD_GET_STATUS_ENDPOINT:
752 DEBUGE("GET_STATUS_ENDPOINT(EPidx=%u) ", wIndex&0x0f);
753 if (upcd.state == USB_STATE_DEFAULT ||
754 (upcd.state == USB_STATE_ADDRESS && wIndex != 0))
758 if ((pUDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
760 (pUDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
761 udp_ep0_send_data((char *)&wStatus,
763 } else if ((pUDP->UDP_GLBSTATE & AT91C_UDP_FADDEN)
766 (pUDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
767 udp_ep0_send_data((char *)&wStatus,
772 case STD_SET_FEATURE_ZERO:
773 DEBUGE("SET_FEATURE_ZERO ");
774 if (upcd.state == USB_STATE_ADDRESS &&
775 (wIndex & 0xff) != 0)
777 /* FIXME: implement this */
780 case STD_SET_FEATURE_INTERFACE:
781 DEBUGE("SET_FEATURE_INTERFACE ");
782 if (upcd.state == USB_STATE_ADDRESS &&
783 (wIndex & 0xff) != 0)
787 case STD_SET_FEATURE_ENDPOINT:
788 DEBUGE("SET_FEATURE_ENDPOINT ");
789 if (upcd.state == USB_STATE_ADDRESS &&
790 (wIndex & 0xff) != 0)
792 if (wValue != USB_ENDPOINT_HALT)
796 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
797 pUDP->UDP_CSR[wIndex] = 0;
802 case STD_CLEAR_FEATURE_ZERO:
803 DEBUGE("CLEAR_FEATURE_ZERO ");
806 case STD_CLEAR_FEATURE_INTERFACE:
807 DEBUGP("CLEAR_FEATURE_INTERFACE ");
810 case STD_CLEAR_FEATURE_ENDPOINT:
811 DEBUGE("CLEAR_FEATURE_ENDPOINT(EPidx=%u) ", wIndex & 0x0f);
812 if (wValue != USB_ENDPOINT_HALT)
815 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
821 case STD_SET_INTERFACE:
822 DEBUGE("SET INTERFACE ");
823 if (upcd.state != USB_STATE_CONFIGURED)
825 if (wIndex > cfg_descriptor.ucfg.bNumInterfaces)
827 upcd.cur_interface = wIndex;
828 upcd.cur_altsett = wValue;
829 /* USB spec mandates that if we only support one altsetting in
830 * the given interface, we shall respond with STALL in the
832 udp_ep0_send_stall();
835 DEBUGE("DEFAULT(req=0x%02x, type=0x%02x) ",
836 bRequest, bmRequestType);
838 if ((bmRequestType & 0x3f) == USB_TYPE_DFU) {
839 dfu->dfu_ep0_handler(bmRequestType, bRequest, wValue,
849 udp_ep0_send_stall();