usb-arch.c

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 /* #define DEBUG   */
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 /* Bits that won't effect the state if they're written at a specific level.
00022  */
00023 /* Bits that should be written as 1 */
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 /* Also includes bits that should be written as 0 */
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;    /* NULL if no current 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 /* A packet has been received but the data is still in hardware buffer */
00105 #define USB_EP_FLAGS_RECV_PENDING 0x08
00106 /* The pending packet is a SETUP packet */
00107 #define USB_EP_FLAGS_SETUP_PENDING 0x10
00108 
00109 /* The data in the hardware buffer is being transmitted */
00110 #define USB_EP_FLAGS_TRANSMITTING 0x20
00111 
00112 /* The  receiver is waiting for a packet */
00113 #define USB_EP_FLAGS_RECEIVING 0x40
00114 
00115 /* For bulk endpoints. Both buffers are busy are in use, either by
00116    hardware or software. */
00117 #define USB_EP_FLAGS_DOUBLE 0x80
00118 
00119 /* The next packet received should be read from bank 1 if possible */
00120 #define USB_EP_FLAGS_BANK_1_RECV_NEXT 0x10
00121 
00122 /* States for double buffered reception:
00123 
00124 Packets being received  0       1       2       1       0       0
00125 Packets pending         0       0       0       1       2       1
00126 
00127 RECVING                 0       1       1       1       0       0
00128 RECV_PENDING            0       0       0       1       1       1
00129 DOUBLE                  0       0       1       0       1       0
00130 */
00131 
00132 /* States for double buffered transmission:
00133    
00134 Packets being transmitted       0       1       2
00135 
00136 TRANSMITTING                    0       1       1
00137 DOUBLE                          0       0       1
00138 */
00139 
00140 /* Index in endpoint array */
00141 #define EP_INDEX(addr) ((addr) & 0x7f)
00142 
00143 /* Get address of endpoint struct */
00144 #define EP_STRUCT(addr) &usb_endpoints[EP_INDEX(addr)];
00145 
00146 /* Number of hardware endpoint */
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   /* Assume 96MHz PLL frequency */
00197   *AT91C_CKGR_PLLR = ((*AT91C_CKGR_PLLR & ~AT91C_CKGR_USBDIV)
00198                           | AT91C_CKGR_USBDIV_1);
00199   /* Enable 48MHz USB clock */
00200   *AT91C_PMC_SCER = AT91C_PMC_UDP;
00201   /* Enable USB main clock */
00202   *AT91C_PMC_PCER = (1 << AT91C_ID_UDP);
00203   
00204   /* Enable pullup */
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   /* Enable usb_interrupt */
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     /* The currently submitted buffers
00289                                    can't hold the received data, wait
00290                                    for more buffers. No data was read
00291                                    from the hardware buffer */
00292 #define USB_READ_NOTIFY 0x02    /* Some buffers that had the
00293                                    USB_BUFFER_NOTIFY flags set were
00294                                    released */
00295 #define USB_READ_FAIL 0x04      /* The received data doesn't match the
00296                                    submitted buffers. The hardware
00297                                    buffer is discarded. */
00298 
00299 /* Skip buffers until mask and flags matches*/
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   /* PRINTF("Write %d\n", len); */
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       /* Discard buffers until we find a SETUP buffer */
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       /* SETUP packet must fit in a single buffer */
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         /* Status OUT */
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     /* Release buffer */
00435     buffer->flags &= ~(USB_BUFFER_SUBMITTED | USB_BUFFER_SHORT_PACKET);
00436     if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00437     /* Use next buffer. */
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     /* Release buffer */
00449     buffer->flags &= ~USB_BUFFER_SUBMITTED;
00450     if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00451     /* Use next buffer. */
00452     buffer = buffer->next;
00453   }
00454   
00455   ep->buffer = buffer;
00456   if (setup_data) {
00457     /* Set direction according to request */
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           /* Send zero length packet. */
00532           break;
00533         } else {
00534           len = 0;
00535         }
00536       }
00537       /* Release buffer */
00538       buffer->flags &= ~USB_BUFFER_SUBMITTED;
00539       if (buffer->flags & USB_BUFFER_NOTIFY) res = USB_WRITE_NOTIFY;
00540            /* Use next buffer. */
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   /* Start transmission */
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       /* Acknowledge SETUP */
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        /* Ping-pong */
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       /* Ping-pong or single buffer */
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       /* Only fails for control endpoints */
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; /* Don't start transfer if halted */
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     /* Acknowledge */
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 /* Select what process should be polled when a global event occurs */
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   /* PRINTF("buffer: %p\n", ep->buffer); */
00735   /* dbg_drain(); */
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   /* PRINTF("usb_submit_xmit_buffer %d\n", buffer->left); */
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   /* Nothing needs to be done */
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 /* Not for control endpoints */
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     /* Delay stall if a transmission is i progress */
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     /* Release HALT buffer */
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     /* Restart transmission */
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 

Generated on Mon Apr 11 14:23:35 2011 for Contiki 2.5 by  doxygen 1.6.1