00001 #include <usb-arch.h>
00002 #include <usb-interrupt.h>
00003 #include <AT91SAM7S64.h>
00004 #include <stdio.h>
00005 #include <debug-uart.h>
00006
00007
00008
00009 #ifdef DEBUG
00010 #define PRINTF(...) printf(__VA_ARGS__)
00011 #else
00012 #define PRINTF(...)
00013 #endif
00014
00015 #define USB_PULLUP_PIN AT91C_PIO_PA16
00016
00017 #ifndef AT91C_UDP_STALLSENT
00018 #define AT91C_UDP_STALLSENT AT91C_UDP_ISOERROR
00019 #endif
00020
00021
00022
00023
00024 #define NO_EFFECT_BITS (AT91C_UDP_TXCOMP | AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RXSETUP \
00025 | AT91C_UDP_ISOERROR | AT91C_UDP_RX_DATA_BK1)
00026
00027 #define NO_EFFECT_MASK (NO_EFFECT_BITS | AT91C_UDP_TXPKTRDY)
00028
00029 #define RXBYTECNT(s) (((s)>>16)&0x7ff)
00030
00031
00032 static inline void
00033 udp_set_ep_ctrl_flags(AT91_REG *reg, unsigned int flags,
00034 unsigned int write_mask, unsigned int check_mask)
00035 {
00036 while ( (*reg & check_mask) != (flags & check_mask)) {
00037 *reg = (*reg & ~write_mask) | flags;
00038 }
00039 }
00040
00041 #define UDP_SET_EP_CTRL_FLAGS(reg, flags, mask) \
00042 udp_set_ep_ctrl_flags((reg), \
00043 (NO_EFFECT_BITS & ~(mask)) | ((flags) & (mask)), (mask) | NO_EFFECT_MASK,\
00044 (mask))
00045
00046
00047 #define USB_DISABLE_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_UDP)
00048 #define USB_ENABLE_INT *AT91C_AIC_IECR = (1 << AT91C_ID_UDP)
00049
00050 #define USB_DISABLE_EP_INT(hw_ep) *AT91C_UDP_IDR = (1 << (hw_ep))
00051 #define USB_ENABLE_EP_INT(hw_ep) *AT91C_UDP_IER = (1 << (hw_ep))
00052
00053 #if CTRL_EP_SIZE > 8
00054 #error Control endpoint size too big
00055 #endif
00056
00057 #if USB_EP1_SIZE > 64
00058 #error Endpoint 1 size too big
00059 #endif
00060
00061 #if USB_EP2_SIZE > 64
00062 #error Endpoint 2 size too big
00063 #endif
00064
00065 #if USB_EP3_SIZE > 64
00066 #error Endpoint 3 size too big
00067 #endif
00068
00069 static const uint16_t ep_xfer_size[8] =
00070 {
00071 CTRL_EP_SIZE,
00072 USB_EP1_SIZE,
00073 USB_EP2_SIZE,
00074 USB_EP3_SIZE
00075 };
00076
00077 #define USB_EP_XFER_SIZE(ep) ep_xfer_size[ep]
00078
00079 typedef struct _USBEndpoint USBEndpoint;
00080 struct _USBEndpoint
00081 {
00082 uint16_t status;
00083 uint8_t addr;
00084 uint8_t flags;
00085 USBBuffer *buffer;
00086 struct process *event_process;
00087 unsigned int events;
00088 uint16_t xfer_size;
00089 };
00090
00091 #define USB_EP_FLAGS_TYPE_MASK 0x03
00092 #define USB_EP_FLAGS_TYPE_BULK 0x00
00093 #define USB_EP_FLAGS_TYPE_CONTROL 0x01
00094 #define USB_EP_FLAGS_TYPE_ISO 0x02
00095 #define USB_EP_FLAGS_TYPE_INTERRUPT 0x03
00096
00097 #define EP_TYPE(ep) ((ep)->flags & USB_EP_FLAGS_TYPE_MASK)
00098 #define IS_EP_TYPE(ep, type) (EP_TYPE(ep) == (type))
00099 #define IS_CONTROL_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_CONTROL)
00100 #define IS_BULK_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_BULK)
00101
00102 #define USB_EP_FLAGS_ENABLED 0x04
00103
00104
00105 #define USB_EP_FLAGS_RECV_PENDING 0x08
00106
00107 #define USB_EP_FLAGS_SETUP_PENDING 0x10
00108
00109
00110 #define USB_EP_FLAGS_TRANSMITTING 0x20
00111
00112
00113 #define USB_EP_FLAGS_RECEIVING 0x40
00114
00115
00116
00117 #define USB_EP_FLAGS_DOUBLE 0x80
00118
00119
00120 #define USB_EP_FLAGS_BANK_1_RECV_NEXT 0x10
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 #define EP_INDEX(addr) ((addr) & 0x7f)
00142
00143
00144 #define EP_STRUCT(addr) &usb_endpoints[EP_INDEX(addr)];
00145
00146
00147 #define EP_HW_NUM(addr) ((addr) & 0x7f)
00148
00149
00150 static USBEndpoint usb_endpoints[USB_MAX_ENDPOINTS];
00151 struct process *event_process = 0;
00152 volatile unsigned int events = 0;
00153
00154 static void
00155 notify_process(unsigned int e)
00156 {
00157 events |= e;
00158 if (event_process) {
00159 process_poll(event_process);
00160 }
00161 }
00162
00163 static void
00164 notify_ep_process(USBEndpoint *ep, unsigned int e)
00165 {
00166 ep->events |= e;
00167 if (ep->event_process) {
00168 process_poll(ep->event_process);
00169 }
00170 }
00171
00172
00173 static void
00174 usb_arch_reset(void)
00175 {
00176 unsigned int e;
00177 for (e = 0; e < USB_MAX_ENDPOINTS; e++) {
00178 if (usb_endpoints[e].flags &USB_EP_FLAGS_ENABLED) {
00179 USBBuffer *buffer = usb_endpoints[e].buffer;
00180 usb_endpoints[e].flags = 0;
00181 usb_disable_endpoint(e);
00182 while(buffer) {
00183 buffer->flags &= ~USB_BUFFER_SUBMITTED;
00184 buffer = buffer->next;
00185 }
00186 }
00187 }
00188 usb_arch_setup_control_endpoint(0);
00189
00190 }
00191
00192 void
00193 usb_arch_setup(void)
00194 {
00195 unsigned int i;
00196
00197 *AT91C_CKGR_PLLR = ((*AT91C_CKGR_PLLR & ~AT91C_CKGR_USBDIV)
00198 | AT91C_CKGR_USBDIV_1);
00199
00200 *AT91C_PMC_SCER = AT91C_PMC_UDP;
00201
00202 *AT91C_PMC_PCER = (1 << AT91C_ID_UDP);
00203
00204
00205 *AT91C_PIOA_PER = USB_PULLUP_PIN;
00206 *AT91C_PIOA_OER = USB_PULLUP_PIN;
00207 *AT91C_PIOA_CODR = USB_PULLUP_PIN;
00208
00209 for(i = 0; i < USB_MAX_ENDPOINTS; i++) {
00210 usb_endpoints[i].flags = 0;
00211 usb_endpoints[i].event_process = 0;
00212 }
00213
00214 usb_arch_reset();
00215
00216 AT91C_AIC_SMR[AT91C_ID_UDP] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 4;
00217 AT91C_AIC_SVR[AT91C_ID_UDP] = (unsigned long) usb_int;
00218 *AT91C_AIC_IECR = (1 << AT91C_ID_UDP);
00219 }
00220
00221
00222 static void
00223 usb_arch_setup_endpoint(unsigned char addr, unsigned int hw_type)
00224 {
00225 unsigned int ei = EP_HW_NUM(addr);
00226 USBEndpoint *ep = EP_STRUCT(addr);
00227 ep->status = 0;
00228 ep->flags = USB_EP_FLAGS_ENABLED;
00229 ep->buffer = 0;
00230 ep->addr = addr;
00231 ep->events = 0;
00232 ep->xfer_size = 0;
00233
00234 *AT91C_UDP_IDR = 1<<ei;
00235
00236 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ei], hw_type | AT91C_UDP_EPEDS,
00237 AT91C_UDP_EPTYPE | AT91C_UDP_EPEDS);
00238
00239 *AT91C_UDP_IER = 1<<ei;
00240 };
00241
00242 void
00243 usb_arch_setup_control_endpoint(unsigned char addr)
00244 {
00245 unsigned int ei = EP_HW_NUM(addr);
00246 USBEndpoint *ep = EP_STRUCT(addr);
00247 usb_arch_setup_endpoint(addr, AT91C_UDP_EPTYPE_CTRL);
00248 ep->flags |= USB_EP_FLAGS_TYPE_CONTROL;
00249 ep->xfer_size = ep_xfer_size[ei];
00250
00251 }
00252
00253 void
00254 usb_arch_setup_bulk_endpoint(unsigned char addr)
00255 {
00256 unsigned int ei = EP_HW_NUM(addr);
00257 USBEndpoint *ep = EP_STRUCT(addr);
00258 usb_arch_setup_endpoint(addr, ((addr & 0x80)
00259 ? AT91C_UDP_EPTYPE_BULK_IN
00260 : AT91C_UDP_EPTYPE_BULK_OUT));
00261 ep->flags |= USB_EP_FLAGS_TYPE_BULK;
00262 ep->xfer_size = ep_xfer_size[ei];
00263 }
00264
00265 void
00266 usb_arch_setup_interrupt_endpoint(unsigned char addr)
00267 {
00268 unsigned int ei = EP_HW_NUM(addr);
00269 USBEndpoint *ep = EP_STRUCT(addr);
00270 usb_arch_setup_endpoint(addr, ((addr & 0x80)
00271 ? AT91C_UDP_EPTYPE_INT_IN
00272 : AT91C_UDP_EPTYPE_INT_OUT));
00273 ep->flags |= USB_EP_FLAGS_TYPE_BULK;
00274 ep->xfer_size = ep_xfer_size[ei];
00275 }
00276
00277 void
00278 usb_arch_disable_endpoint(uint8_t addr)
00279 {
00280 USBEndpoint *ep = EP_STRUCT(addr);
00281 ep->flags &= ~USB_EP_FLAGS_ENABLED;
00282
00283 *AT91C_UDP_IDR = 1<<EP_HW_NUM(addr);
00284 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(addr)], 0, AT91C_UDP_EPEDS);
00285 }
00286
00287
00288 #define USB_READ_BLOCK 0x01
00289
00290
00291
00292 #define USB_READ_NOTIFY 0x02
00293
00294
00295 #define USB_READ_FAIL 0x04
00296
00297
00298
00299
00300 static USBBuffer *
00301 skip_buffers_until(USBBuffer *buffer, unsigned int mask, unsigned int flags,
00302 unsigned int *resp)
00303 {
00304 while(buffer && !((buffer->flags & mask) == flags)) {
00305 USBBuffer *next = buffer->next;
00306 buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00307 buffer->flags |= USB_BUFFER_FAILED;
00308 if (buffer->flags & USB_BUFFER_NOTIFY) *resp |= USB_READ_NOTIFY;
00309 buffer = next;
00310 }
00311 return buffer;
00312 }
00313
00314 static void
00315 read_hw_buffer(uint8_t *data, unsigned int hw_ep, unsigned int len)
00316 {
00317 AT91_REG *fdr;
00318 fdr = &AT91C_UDP_FDR[hw_ep];
00319 while(len-- > 0) {
00320 *data++ = *fdr;
00321 }
00322 }
00323
00324
00325 #define USB_WRITE_BLOCK 0x01
00326 #define USB_WRITE_NOTIFY 0x02
00327
00328 void
00329 write_hw_buffer(const uint8_t *data, unsigned int hw_ep, unsigned int len)
00330 {
00331 AT91_REG *fdr;
00332 fdr = &AT91C_UDP_FDR[hw_ep];
00333
00334 while(len-- > 0) {
00335 *fdr = *data++;
00336 }
00337 }
00338
00339 static unsigned int
00340 get_receive_capacity(USBBuffer *buffer)
00341 {
00342 unsigned int capacity = 0;
00343 while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP|USB_BUFFER_HALT))) {
00344 capacity += buffer->left;
00345 buffer = buffer->next;
00346 }
00347 return capacity;
00348 }
00349
00350 static int
00351 handle_pending_receive(USBEndpoint *ep)
00352 {
00353 int short_packet;
00354 unsigned int len;
00355 unsigned int copy;
00356 unsigned int res = 0;
00357 unsigned int hw_ep = EP_HW_NUM(ep->addr);
00358 USBBuffer *buffer = ep->buffer;
00359 uint8_t *setup_data = NULL;
00360 unsigned int flags = ep->flags;
00361 if (!(flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_READ_BLOCK;
00362 len = RXBYTECNT(AT91C_UDP_CSR[hw_ep]);
00363 PRINTF("handle_pending_receive: %d\n", len);
00364 switch(flags & USB_EP_FLAGS_TYPE_MASK) {
00365 case USB_EP_FLAGS_TYPE_CONTROL:
00366 if (flags & USB_EP_FLAGS_SETUP_PENDING) {
00367
00368 buffer =
00369 skip_buffers_until(buffer, USB_BUFFER_SETUP, USB_BUFFER_SETUP, &res);
00370 ep->buffer = buffer;
00371 if (!buffer || buffer->left < len) {
00372 res |= USB_READ_BLOCK;
00373 return res;
00374 }
00375
00376 if (buffer->left < len) {
00377 buffer->flags |= USB_BUFFER_FAILED;
00378 buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00379 if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00380 ep->buffer = buffer->next;
00381 res |= USB_READ_FAIL;
00382 return res;
00383 }
00384 setup_data = buffer->data;
00385 } else {
00386 if (buffer->flags & (USB_BUFFER_SETUP|USB_BUFFER_IN)) {
00387 buffer->flags |= USB_BUFFER_FAILED;
00388
00389 buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00390 if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00391 ep->buffer = buffer->next;
00392 res |= USB_READ_FAIL;
00393 return res;
00394 }
00395
00396 if (len == 0) {
00397
00398 if (buffer->left > 0) {
00399 buffer->flags |= USB_BUFFER_FAILED;
00400 res |= USB_READ_FAIL;
00401 }
00402 buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00403 if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00404 ep->buffer = buffer->next;
00405 return res;
00406 }
00407 if (get_receive_capacity(buffer) < len) return USB_READ_BLOCK;
00408 }
00409 break;
00410 case USB_EP_FLAGS_TYPE_INTERRUPT:
00411 case USB_EP_FLAGS_TYPE_BULK:
00412 case USB_EP_FLAGS_TYPE_ISO:
00413 if (get_receive_capacity(buffer) < len) {
00414 return USB_READ_BLOCK;
00415 }
00416 break;
00417 }
00418
00419 short_packet = len < ep->xfer_size;
00420
00421 do {
00422 if (buffer->left < len) {
00423 copy = buffer->left;
00424 } else {
00425 copy = len;
00426 }
00427 len -= copy;
00428 buffer->left -= copy;
00429 read_hw_buffer(buffer->data, hw_ep, copy);
00430 buffer->data += copy;
00431
00432 if (len == 0) break;
00433
00434
00435 buffer->flags &= ~(USB_BUFFER_SUBMITTED | USB_BUFFER_SHORT_PACKET);
00436 if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00437
00438 buffer = buffer->next;
00439 } while(1);
00440
00441 if (short_packet) {
00442 buffer->flags |= USB_BUFFER_SHORT_PACKET;
00443 }
00444
00445 if ((buffer->left == 0)
00446 || (buffer->flags & USB_BUFFER_PACKET_END)
00447 || (short_packet && (buffer->flags & USB_BUFFER_SHORT_END))) {
00448
00449 buffer->flags &= ~USB_BUFFER_SUBMITTED;
00450 if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00451
00452 buffer = buffer->next;
00453 }
00454
00455 ep->buffer = buffer;
00456 if (setup_data) {
00457
00458 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],
00459 ((setup_data[0] & 0x80)
00460 ? AT91C_UDP_DIR : 0), AT91C_UDP_DIR);
00461 }
00462 return res;
00463 }
00464
00465
00466 static void
00467 start_receive(USBEndpoint *ep)
00468 {
00469 ep->flags |= USB_EP_FLAGS_RECEIVING;
00470 }
00471
00472 #if 0
00473 static unsigned int
00474 get_transmit_length(USBBuffer *buffer)
00475 {
00476 unsigned int length = 0;
00477 while(buffer && (buffer->flags & USB_BUFFER_IN)) {
00478 length += buffer->left;
00479 buffer = buffer->next;
00480 }
00481 return length;
00482 }
00483 #endif
00484
00485 static int
00486 start_transmit(USBEndpoint *ep)
00487 {
00488 unsigned int res = 0;
00489 USBBuffer *buffer = ep->buffer;
00490 unsigned int len;
00491 unsigned int hw_ep = EP_HW_NUM(ep->addr);
00492 unsigned int ep_flags = ep->flags;
00493 len = ep->xfer_size;
00494 if (!(ep_flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_WRITE_BLOCK;
00495 switch(ep_flags & USB_EP_FLAGS_TYPE_MASK) {
00496 case USB_EP_FLAGS_TYPE_BULK:
00497 if (buffer->flags & USB_BUFFER_HALT) {
00498 if (ep->status & 0x01) return USB_WRITE_BLOCK;
00499 ep->status |= 0x01;
00500 if (!(ep->flags & USB_EP_FLAGS_TRANSMITTING)) {
00501 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],
00502 AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
00503 PRINTF("HALT IN\n");
00504 }
00505 return USB_WRITE_BLOCK;
00506 }
00507 case USB_EP_FLAGS_TYPE_ISO:
00508 if (!(ep->flags & USB_EP_FLAGS_TRANSMITTING)) {
00509 if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_TXPKTRDY) return USB_WRITE_BLOCK;
00510 }
00511 break;
00512 default:
00513 if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_TXPKTRDY) return USB_WRITE_BLOCK;
00514 }
00515
00516
00517 while (buffer) {
00518 unsigned int copy;
00519 if (buffer->left < len) {
00520 copy = buffer->left;
00521 } else {
00522 copy = len;
00523 }
00524 len -= copy;
00525 buffer->left -= copy;
00526 write_hw_buffer(buffer->data, hw_ep, copy);
00527 buffer->data += copy;
00528 if (buffer->left == 0) {
00529 if (buffer->flags & USB_BUFFER_SHORT_END) {
00530 if (len == 0) {
00531
00532 break;
00533 } else {
00534 len = 0;
00535 }
00536 }
00537
00538 buffer->flags &= ~USB_BUFFER_SUBMITTED;
00539 if (buffer->flags & USB_BUFFER_NOTIFY) res = USB_WRITE_NOTIFY;
00540
00541 buffer = buffer->next;
00542 }
00543 if (len == 0) break;
00544 }
00545 ep->buffer = buffer;
00546 if (ep->flags & USB_EP_FLAGS_TRANSMITTING) {
00547 ep->flags |= USB_EP_FLAGS_DOUBLE;
00548 } else {
00549 ep->flags |= USB_EP_FLAGS_TRANSMITTING;
00550 }
00551
00552 PRINTF("start_transmit: sent %08x\n",AT91C_UDP_CSR[hw_ep]);
00553
00554 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],
00555 AT91C_UDP_TXPKTRDY, AT91C_UDP_TXPKTRDY);
00556
00557 return res;
00558 }
00559
00560 static void
00561 start_transfer(USBEndpoint *ep)
00562 {
00563 unsigned int hw_ep = EP_HW_NUM(ep->addr);
00564 int res;
00565 while (1) {
00566 if (!(ep->addr & 0x80)) {
00567 if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
00568 if (ep->status & 0x01) return ;
00569 ep->status |= 0x01;
00570 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep->addr)],
00571 AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
00572 PRINTF("HALT OUT\n");
00573 *AT91C_UDP_IDR = 1<<hw_ep;
00574 return;
00575 }
00576 }
00577 if (!(ep->flags & USB_EP_FLAGS_RECV_PENDING)) break;
00578 res = handle_pending_receive(ep);
00579 if (res & USB_READ_NOTIFY) {
00580 notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
00581 }
00582 PRINTF("received res = %d\n", res);
00583 if (res & USB_READ_BLOCK) {
00584 *AT91C_UDP_IDR = 1<<hw_ep;
00585 return;
00586 }
00587 if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_RXSETUP) {
00588
00589 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0, AT91C_UDP_RXSETUP);
00590 } else if (AT91C_UDP_CSR[hw_ep] & (AT91C_UDP_RX_DATA_BK1)) {
00591
00592 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0,
00593 (ep->flags & USB_EP_FLAGS_BANK_1_RECV_NEXT)
00594 ? AT91C_UDP_RX_DATA_BK1
00595 : AT91C_UDP_RX_DATA_BK0);
00596 ep->flags ^= USB_EP_FLAGS_BANK_1_RECV_NEXT;
00597 } else {
00598
00599 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0,
00600 AT91C_UDP_RX_DATA_BK0);
00601 ep->flags |= USB_EP_FLAGS_BANK_1_RECV_NEXT;
00602 }
00603
00604 if (ep->flags & USB_EP_FLAGS_DOUBLE) {
00605 ep->flags &= ~USB_EP_FLAGS_DOUBLE;
00606 } else if IS_CONTROL_EP(ep) {
00607 ep->flags &= ~(USB_EP_FLAGS_RECV_PENDING|USB_EP_FLAGS_SETUP_PENDING);
00608 } else {
00609 ep->flags &= ~USB_EP_FLAGS_RECV_PENDING;
00610 }
00611 if (res & USB_READ_FAIL) {
00612
00613 usb_arch_control_stall(ep->addr);
00614 return;
00615 }
00616 *AT91C_UDP_IER = 1<<hw_ep;
00617 }
00618 if (ep->flags & (USB_EP_FLAGS_TRANSMITTING | USB_EP_FLAGS_RECEIVING)) {
00619 #if 0
00620 if (!IS_BULK_EP(ep) || (ep->flags & USB_EP_FLAGS_DOUBLE)) {
00621 #else
00622 if(1) {
00623 #endif
00624 PRINTF("Busy\n");
00625 return;
00626 }
00627 }
00628 if (ep->status & 0x01) return;
00629 if (ep->buffer) {
00630 if (ep->buffer->flags & USB_BUFFER_IN) {
00631 res = start_transmit(ep);
00632 if (res & USB_WRITE_NOTIFY) {
00633 notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
00634 }
00635 } else {
00636 start_receive(ep);
00637 }
00638 }
00639 }
00640
00641
00642 void
00643 usb_arch_transfer_complete(unsigned int hw_ep)
00644 {
00645 unsigned int status = AT91C_UDP_CSR[hw_ep];
00646 USBEndpoint *ep = &usb_endpoints[hw_ep];
00647 PRINTF("transfer_complete: %d\n", hw_ep);
00648 if (status & AT91C_UDP_STALLSENT) {
00649
00650 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0, AT91C_UDP_STALLSENT);
00651 }
00652 if (status & (AT91C_UDP_RXSETUP
00653 | AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_RX_DATA_BK0)) {
00654 if (status & AT91C_UDP_RXSETUP) {
00655 PRINTF("SETUP\n");
00656 ep->flags |= USB_EP_FLAGS_SETUP_PENDING;
00657 }
00658 if (ep->flags & USB_EP_FLAGS_DOUBLE) {
00659 ep->flags &= ~USB_EP_FLAGS_DOUBLE;
00660 } else {
00661 ep->flags &= ~USB_EP_FLAGS_RECEIVING;
00662 }
00663 if ( ep->flags & USB_EP_FLAGS_RECV_PENDING) {
00664 ep->flags |= USB_EP_FLAGS_DOUBLE;
00665 } else {
00666 ep->flags |= USB_EP_FLAGS_RECV_PENDING;
00667 }
00668 start_transfer(ep);
00669 }
00670 if (status & AT91C_UDP_TXCOMP) {
00671 PRINTF("Sent packet\n");
00672 if (ep->flags & USB_EP_FLAGS_DOUBLE) {
00673 ep->flags &= ~USB_EP_FLAGS_DOUBLE;
00674 } else {
00675 ep->flags &= ~USB_EP_FLAGS_TRANSMITTING;
00676 }
00677 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0, AT91C_UDP_TXCOMP);
00678 if (ep->status & 0x01) {
00679 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],
00680 AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
00681 PRINTF("HALT IN\n");
00682 } else {
00683 start_transfer(ep);
00684 }
00685 }
00686
00687 }
00688
00689
00690 void
00691 usb_set_ep_event_process(unsigned char addr, struct process *p)
00692 {
00693 USBEndpoint *ep = &usb_endpoints[EP_INDEX(addr)];
00694 ep->event_process = p;
00695 }
00696
00697
00698 void
00699 usb_arch_set_global_event_process(struct process *p)
00700 {
00701 event_process = p;
00702 }
00703
00704 unsigned int
00705 usb_arch_get_global_events(void)
00706 {
00707 unsigned int e;
00708 USB_DISABLE_INT;
00709 e = events;
00710 events = 0;
00711 USB_ENABLE_INT;
00712 return e;
00713 }
00714
00715 unsigned int
00716 usb_get_ep_events(unsigned char addr)
00717 {
00718 unsigned int e;
00719 unsigned int ei = EP_HW_NUM(addr);
00720 USB_DISABLE_INT;
00721 e = usb_endpoints[ei].events;
00722 usb_endpoints[ei].events = 0;
00723 USB_ENABLE_INT;
00724 return e;
00725 }
00726
00727
00728 void
00729 usb_submit_recv_buffer(unsigned char ep_addr, USBBuffer *buffer)
00730 {
00731 USBBuffer **tailp;
00732 USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
00733 if (!(ep->flags & USB_EP_FLAGS_ENABLED)) return;
00734
00735
00736 USB_DISABLE_INT;
00737 tailp = (USBBuffer**)&ep->buffer;
00738 while(*tailp) {
00739 tailp = &(*tailp)->next;
00740 }
00741 *tailp = buffer;
00742 while(buffer) {
00743 buffer->flags |= USB_BUFFER_SUBMITTED;
00744 buffer = buffer->next;
00745 }
00746 start_transfer(ep);
00747
00748 USB_ENABLE_INT;
00749 }
00750
00751 void
00752 usb_submit_xmit_buffer(unsigned char ep_addr, USBBuffer *buffer)
00753 {
00754 USBBuffer **tailp;
00755 USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
00756 if (!(ep->flags & USB_EP_FLAGS_ENABLED)) return;
00757
00758 USB_DISABLE_INT;
00759 tailp = (USBBuffer**)&ep->buffer;
00760 while(*tailp) {
00761 tailp = &(*tailp)->next;
00762 }
00763 *tailp = buffer;
00764 while(buffer) {
00765 buffer->flags |= USB_BUFFER_SUBMITTED | USB_BUFFER_IN;
00766 buffer = buffer->next;
00767 }
00768 start_transfer(ep);
00769 USB_ENABLE_INT;
00770 }
00771
00772 void
00773 usb_arch_discard_all_buffers(unsigned char ep_addr)
00774 {
00775 USBBuffer *buffer;
00776 volatile USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
00777 USB_DISABLE_EP_INT(EP_HW_NUM(ep_addr));
00778 buffer = ep->buffer;
00779 ep->buffer = NULL;
00780
00781 USB_ENABLE_EP_INT(EP_HW_NUM(ep_addr));
00782 while(buffer) {
00783 buffer->flags &= ~USB_BUFFER_SUBMITTED;
00784 buffer = buffer->next;
00785 }
00786 }
00787
00788 uint16_t
00789 usb_arch_get_ep_status(uint8_t addr)
00790 {
00791 if (EP_INDEX(addr) > USB_MAX_ENDPOINTS) return 0;
00792 return usb_endpoints[EP_INDEX(addr)].status;
00793 }
00794
00795 void
00796 usb_arch_set_configuration(uint8_t usb_configuration_value)
00797 {
00798
00799 }
00800
00801 void
00802 usb_arch_control_stall(unsigned char addr)
00803 {
00804 if (EP_INDEX(addr) > USB_MAX_ENDPOINTS) return;
00805 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(addr)],
00806 AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
00807 }
00808
00809
00810 void
00811 usb_arch_halt_endpoint(unsigned char ep_addr, int halt)
00812 {
00813 if (EP_INDEX(ep_addr) > USB_MAX_ENDPOINTS) return;
00814 if (!usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_ENABLED) return;
00815 *AT91C_UDP_IDR = 1<<EP_HW_NUM(ep_addr);
00816 if (halt) {
00817 usb_endpoints[EP_INDEX(ep_addr)].status |= 0x01;
00818
00819 if (!(usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_TRANSMITTING)){
00820 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep_addr)],
00821 AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
00822 }
00823 } else {
00824 USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
00825 ep->status &= ~0x01;
00826 *AT91C_UDP_IDR = 1<<EP_HW_NUM(ep_addr);
00827 UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep_addr)],
00828 0, AT91C_UDP_FORCESTALL);
00829 *AT91C_UDP_RSTEP = 1<<EP_HW_NUM(ep_addr);
00830 *AT91C_UDP_RSTEP = 0;
00831
00832
00833 if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
00834 ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
00835 if (ep->buffer->flags & USB_BUFFER_NOTIFY) {
00836 notify_ep_process(ep,USB_EP_EVENT_NOTIFICATION);
00837 }
00838 ep->buffer = ep->buffer->next;
00839 }
00840
00841
00842 start_transfer(&usb_endpoints[EP_INDEX(ep_addr)]);
00843 }
00844 *AT91C_UDP_IER = 1<<EP_HW_NUM(ep_addr);
00845 }
00846
00847 int
00848 usb_arch_send_pending(uint8_t ep_addr)
00849 {
00850 return usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_TRANSMITTING;
00851 }
00852
00853 void
00854 usb_arch_set_address(unsigned char addr)
00855 {
00856 *AT91C_UDP_FADDR = AT91C_UDP_FEN | addr;
00857 *AT91C_UDP_GLBSTATE |= AT91C_UDP_FADDEN;
00858 }
00859
00860 void
00861 usb_arch_reset_int()
00862 {
00863 usb_arch_reset();
00864 notify_process(USB_EVENT_RESET);
00865 }
00866
00867 void
00868 usb_arch_suspend_int()
00869 {
00870 notify_process(USB_EVENT_SUSPEND);
00871 }
00872
00873 void
00874 usb_arch_resume_int()
00875 {
00876 notify_process(USB_EVENT_RESUME);
00877 }
00878