PageRenderTime 55ms CodeModel.GetById 25ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 0ms

/cpu/arm/at91sam7s/usb-arch.c

https://bitbucket.org/homadeus/contiki
C | 878 lines | 699 code | 108 blank | 71 comment | 114 complexity | 73bf9da120581f166268a305bb3dea6e MD5 | raw file
  1#include <usb-arch.h>
  2#include <usb-interrupt.h>
  3#include <AT91SAM7S64.h>
  4#include <stdio.h>
  5#include <debug-uart.h>
  6
  7
  8/* #define DEBUG   */
  9#ifdef DEBUG
 10#define PRINTF(...) printf(__VA_ARGS__)
 11#else
 12#define PRINTF(...)
 13#endif
 14
 15#define USB_PULLUP_PIN AT91C_PIO_PA16
 16
 17#ifndef AT91C_UDP_STALLSENT
 18#define AT91C_UDP_STALLSENT AT91C_UDP_ISOERROR
 19#endif
 20
 21/* Bits that won't effect the state if they're written at a specific level.
 22 */
 23/* Bits that should be written as 1 */
 24#define NO_EFFECT_BITS (AT91C_UDP_TXCOMP | AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RXSETUP \
 25			| AT91C_UDP_ISOERROR | AT91C_UDP_RX_DATA_BK1)
 26/* Also includes bits that should be written as 0 */
 27#define NO_EFFECT_MASK (NO_EFFECT_BITS | AT91C_UDP_TXPKTRDY)
 28
 29#define RXBYTECNT(s) (((s)>>16)&0x7ff)
 30
 31
 32static inline void
 33udp_set_ep_ctrl_flags(AT91_REG *reg, unsigned int flags,
 34		      unsigned int write_mask, unsigned int check_mask)
 35{
 36  while ( (*reg & check_mask) != (flags & check_mask)) {
 37    *reg = (*reg & ~write_mask) | flags; 
 38  }
 39}
 40
 41#define UDP_SET_EP_CTRL_FLAGS(reg, flags, mask) \
 42udp_set_ep_ctrl_flags((reg), \
 43  (NO_EFFECT_BITS & ~(mask)) | ((flags) & (mask)), (mask) | NO_EFFECT_MASK,\
 44  (mask))
 45
 46
 47#define USB_DISABLE_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_UDP)
 48#define USB_ENABLE_INT *AT91C_AIC_IECR = (1 << AT91C_ID_UDP)
 49
 50#define USB_DISABLE_EP_INT(hw_ep) *AT91C_UDP_IDR = (1 << (hw_ep))
 51#define USB_ENABLE_EP_INT(hw_ep) *AT91C_UDP_IER = (1 << (hw_ep))
 52
 53#if CTRL_EP_SIZE > 8
 54#error Control endpoint size too big
 55#endif
 56
 57#if USB_EP1_SIZE > 64
 58#error Endpoint 1 size too big
 59#endif
 60
 61#if USB_EP2_SIZE > 64
 62#error Endpoint 2 size too big
 63#endif
 64
 65#if USB_EP3_SIZE > 64
 66#error Endpoint 3 size too big
 67#endif
 68
 69static const uint16_t ep_xfer_size[8] =
 70  {
 71    CTRL_EP_SIZE,
 72    USB_EP1_SIZE,
 73    USB_EP2_SIZE,
 74    USB_EP3_SIZE
 75  };
 76
 77#define USB_EP_XFER_SIZE(ep) ep_xfer_size[ep]
 78
 79typedef struct _USBEndpoint USBEndpoint;
 80struct _USBEndpoint
 81{
 82  uint16_t status;
 83  uint8_t addr;
 84  uint8_t flags;
 85  USBBuffer *buffer;	/* NULL if no current buffer */
 86  struct process *event_process;
 87  unsigned int events;
 88  uint16_t xfer_size;
 89};
 90
 91#define USB_EP_FLAGS_TYPE_MASK 0x03
 92#define USB_EP_FLAGS_TYPE_BULK 0x00
 93#define USB_EP_FLAGS_TYPE_CONTROL 0x01
 94#define USB_EP_FLAGS_TYPE_ISO 0x02
 95#define USB_EP_FLAGS_TYPE_INTERRUPT 0x03
 96
 97#define EP_TYPE(ep) ((ep)->flags & USB_EP_FLAGS_TYPE_MASK)
 98#define IS_EP_TYPE(ep, type) (EP_TYPE(ep) == (type))
 99#define IS_CONTROL_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_CONTROL)
100#define IS_BULK_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_BULK)
101
102#define USB_EP_FLAGS_ENABLED 0x04
103
104/* A packet has been received but the data is still in hardware buffer */
105#define USB_EP_FLAGS_RECV_PENDING 0x08
106/* The pending packet is a SETUP packet */
107#define USB_EP_FLAGS_SETUP_PENDING 0x10
108
109/* The data in the hardware buffer is being transmitted */
110#define USB_EP_FLAGS_TRANSMITTING 0x20
111
112/* The  receiver is waiting for a packet */
113#define USB_EP_FLAGS_RECEIVING 0x40
114
115/* For bulk endpoints. Both buffers are busy are in use, either by
116   hardware or software. */
117#define USB_EP_FLAGS_DOUBLE 0x80
118
119/* The next packet received should be read from bank 1 if possible */
120#define USB_EP_FLAGS_BANK_1_RECV_NEXT 0x10
121
122/* States for double buffered reception:
123
124Packets being received	0	1	2	1	0	0
125Packets pending		0	0	0	1	2	1
126
127RECVING			0	1	1	1	0	0
128RECV_PENDING		0	0	0	1	1	1
129DOUBLE			0	0	1	0	1	0
130*/
131
132/* States for double buffered transmission:
133   
134Packets being transmitted	0	1	2
135
136TRANSMITTING			0	1	1
137DOUBLE				0	0	1
138*/
139
140/* Index in endpoint array */
141#define EP_INDEX(addr) ((addr) & 0x7f)
142
143/* Get address of endpoint struct */
144#define EP_STRUCT(addr) &usb_endpoints[EP_INDEX(addr)];
145
146/* Number of hardware endpoint */
147#define EP_HW_NUM(addr) ((addr) & 0x7f)
148
149
150static USBEndpoint usb_endpoints[USB_MAX_ENDPOINTS];
151struct process *event_process = 0;
152volatile unsigned int events = 0;
153
154static void
155notify_process(unsigned int e)
156{
157  events |= e;
158  if (event_process) {
159    process_poll(event_process);
160  }
161}
162
163static void
164notify_ep_process(USBEndpoint *ep, unsigned int e)
165{
166  ep->events |= e;
167  if (ep->event_process) {
168    process_poll(ep->event_process);
169  }
170}
171
172
173static void
174usb_arch_reset(void)
175{
176  unsigned int e;
177  for (e = 0; e < USB_MAX_ENDPOINTS; e++) {
178    if (usb_endpoints[e].flags &USB_EP_FLAGS_ENABLED) {
179      USBBuffer *buffer = usb_endpoints[e].buffer;
180      usb_endpoints[e].flags = 0;
181      usb_disable_endpoint(e);
182      while(buffer) {
183	buffer->flags &= ~USB_BUFFER_SUBMITTED;
184	buffer = buffer->next;
185      }
186    }
187  }
188  usb_arch_setup_control_endpoint(0);  
189
190}
191
192void
193usb_arch_setup(void)
194{
195  unsigned int i;
196  /* Assume 96MHz PLL frequency */
197  *AT91C_CKGR_PLLR = ((*AT91C_CKGR_PLLR & ~AT91C_CKGR_USBDIV)
198			  | AT91C_CKGR_USBDIV_1);
199  /* Enable 48MHz USB clock */
200  *AT91C_PMC_SCER = AT91C_PMC_UDP;
201  /* Enable USB main clock */
202  *AT91C_PMC_PCER = (1 << AT91C_ID_UDP);
203  
204  /* Enable pullup */
205  *AT91C_PIOA_PER = USB_PULLUP_PIN;
206  *AT91C_PIOA_OER = USB_PULLUP_PIN;
207  *AT91C_PIOA_CODR = USB_PULLUP_PIN;
208
209  for(i = 0; i < USB_MAX_ENDPOINTS; i++) {
210    usb_endpoints[i].flags = 0;
211    usb_endpoints[i].event_process = 0;
212  }
213  
214  usb_arch_reset();
215  /* Enable usb_interrupt */
216  AT91C_AIC_SMR[AT91C_ID_UDP] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 4;
217  AT91C_AIC_SVR[AT91C_ID_UDP] = (unsigned long) usb_int;
218  *AT91C_AIC_IECR = (1 << AT91C_ID_UDP);
219}
220
221
222static void
223usb_arch_setup_endpoint(unsigned char addr, unsigned int hw_type)
224{
225  unsigned int ei = EP_HW_NUM(addr);
226  USBEndpoint *ep = EP_STRUCT(addr);
227  ep->status = 0;
228  ep->flags = USB_EP_FLAGS_ENABLED;
229  ep->buffer = 0;
230  ep->addr = addr;
231  ep->events = 0;
232  ep->xfer_size = 0;
233
234  *AT91C_UDP_IDR = 1<<ei;
235
236  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[ei], hw_type | AT91C_UDP_EPEDS,
237			AT91C_UDP_EPTYPE | AT91C_UDP_EPEDS);
238    
239  *AT91C_UDP_IER = 1<<ei;
240};
241
242void
243usb_arch_setup_control_endpoint(unsigned char addr)
244{
245  unsigned int ei = EP_HW_NUM(addr);
246  USBEndpoint *ep = EP_STRUCT(addr);
247  usb_arch_setup_endpoint(addr, AT91C_UDP_EPTYPE_CTRL);
248  ep->flags |= USB_EP_FLAGS_TYPE_CONTROL;
249  ep->xfer_size = ep_xfer_size[ei];
250
251}
252
253void
254usb_arch_setup_bulk_endpoint(unsigned char addr)
255{
256  unsigned int ei = EP_HW_NUM(addr);
257  USBEndpoint *ep = EP_STRUCT(addr);
258  usb_arch_setup_endpoint(addr, ((addr & 0x80)
259				 ? AT91C_UDP_EPTYPE_BULK_IN
260				 : AT91C_UDP_EPTYPE_BULK_OUT));
261  ep->flags |= USB_EP_FLAGS_TYPE_BULK;
262  ep->xfer_size = ep_xfer_size[ei];
263}
264
265void
266usb_arch_setup_interrupt_endpoint(unsigned char addr)
267{
268  unsigned int ei = EP_HW_NUM(addr);
269  USBEndpoint *ep = EP_STRUCT(addr);
270  usb_arch_setup_endpoint(addr, ((addr & 0x80)
271				 ? AT91C_UDP_EPTYPE_INT_IN
272				 : AT91C_UDP_EPTYPE_INT_OUT));
273  ep->flags |= USB_EP_FLAGS_TYPE_BULK;
274  ep->xfer_size = ep_xfer_size[ei];
275}
276
277void
278usb_arch_disable_endpoint(uint8_t addr)
279{
280  USBEndpoint *ep = EP_STRUCT(addr);
281  ep->flags &= ~USB_EP_FLAGS_ENABLED;
282  
283  *AT91C_UDP_IDR = 1<<EP_HW_NUM(addr);
284  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(addr)], 0, AT91C_UDP_EPEDS);
285}
286     
287
288#define USB_READ_BLOCK 0x01	/* The currently submitted buffers
289				   can't hold the received data, wait
290				   for more buffers. No data was read
291				   from the hardware buffer */
292#define USB_READ_NOTIFY 0x02	/* Some buffers that had the
293				   USB_BUFFER_NOTIFY flags set were
294				   released */
295#define USB_READ_FAIL 0x04	/* The received data doesn't match the
296				   submitted buffers. The hardware
297				   buffer is discarded. */
298
299/* Skip buffers until mask and flags matches*/
300static USBBuffer *
301skip_buffers_until(USBBuffer *buffer, unsigned int mask, unsigned int flags,
302		   unsigned int *resp)
303{
304  while(buffer && !((buffer->flags & mask) == flags)) {
305    USBBuffer *next = buffer->next;
306    buffer->flags &= ~USB_BUFFER_SUBMITTED ;
307    buffer->flags |= USB_BUFFER_FAILED;
308    if (buffer->flags & USB_BUFFER_NOTIFY) *resp |= USB_READ_NOTIFY;
309    buffer = next;
310  }
311  return buffer;
312}
313
314static void
315read_hw_buffer(uint8_t *data, unsigned int hw_ep, unsigned int len)
316{
317  AT91_REG *fdr;
318  fdr = &AT91C_UDP_FDR[hw_ep];
319  while(len-- > 0) {
320    *data++ = *fdr;
321  }
322}
323
324
325#define USB_WRITE_BLOCK 0x01
326#define USB_WRITE_NOTIFY 0x02
327
328void
329write_hw_buffer(const uint8_t *data, unsigned int hw_ep, unsigned int len)
330{
331  AT91_REG *fdr;
332  fdr = &AT91C_UDP_FDR[hw_ep];
333  /* PRINTF("Write %d\n", len); */
334  while(len-- > 0) {
335    *fdr = *data++;
336  }
337}
338
339static unsigned int
340get_receive_capacity(USBBuffer *buffer)
341{
342  unsigned int capacity = 0;
343  while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP|USB_BUFFER_HALT))) {
344    capacity += buffer->left;
345    buffer = buffer->next;
346  }
347  return capacity;
348}
349
350static int
351handle_pending_receive(USBEndpoint *ep)
352{
353  int short_packet;
354  unsigned int len;
355  unsigned int copy;
356  unsigned int res = 0;
357  unsigned int hw_ep = EP_HW_NUM(ep->addr);
358  USBBuffer *buffer = ep->buffer;
359  uint8_t *setup_data = NULL;
360  unsigned int flags = ep->flags;
361  if (!(flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_READ_BLOCK;
362  len = RXBYTECNT(AT91C_UDP_CSR[hw_ep]);
363  PRINTF("handle_pending_receive: %d\n", len);
364  switch(flags & USB_EP_FLAGS_TYPE_MASK) {
365  case USB_EP_FLAGS_TYPE_CONTROL:
366    if (flags & USB_EP_FLAGS_SETUP_PENDING) {
367      /* Discard buffers until we find a SETUP buffer */
368      buffer =
369	skip_buffers_until(buffer, USB_BUFFER_SETUP, USB_BUFFER_SETUP, &res);
370      ep->buffer = buffer;
371      if (!buffer || buffer->left < len) {
372	res |= USB_READ_BLOCK;
373	return res;
374      }
375      /* SETUP packet must fit in a single buffer */
376      if (buffer->left < len) {
377	buffer->flags |= USB_BUFFER_FAILED;
378	buffer->flags &= ~USB_BUFFER_SUBMITTED ;
379	if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
380	ep->buffer = buffer->next;
381	res |= USB_READ_FAIL;
382	return res;
383      }
384      setup_data = buffer->data;
385    } else {
386      if (buffer->flags & (USB_BUFFER_SETUP|USB_BUFFER_IN)) {
387	buffer->flags |= USB_BUFFER_FAILED;
388	
389	buffer->flags &= ~USB_BUFFER_SUBMITTED ;
390	if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
391	ep->buffer = buffer->next;
392	res |= USB_READ_FAIL;
393	return res;
394      }
395
396      if (len == 0) {
397	/* Status OUT */
398	if (buffer->left > 0) {
399	  buffer->flags |= USB_BUFFER_FAILED;
400	  res |= USB_READ_FAIL;
401	}
402	buffer->flags &= ~USB_BUFFER_SUBMITTED ;
403	if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
404	ep->buffer = buffer->next;
405	return res;
406      }
407      if (get_receive_capacity(buffer) <  len) return USB_READ_BLOCK;
408    }
409    break;
410  case USB_EP_FLAGS_TYPE_INTERRUPT:
411  case USB_EP_FLAGS_TYPE_BULK:
412  case USB_EP_FLAGS_TYPE_ISO:
413    if (get_receive_capacity(buffer) <  len) {
414      return USB_READ_BLOCK;
415    }
416    break;
417  }
418
419  short_packet = len < ep->xfer_size;
420
421  do {
422    if (buffer->left < len) {
423      copy = buffer->left;
424    } else {
425      copy = len;
426    }
427    len -= copy;
428    buffer->left -= copy;
429    read_hw_buffer(buffer->data, hw_ep, copy);
430    buffer->data += copy;
431
432    if (len == 0) break;
433
434    /* Release buffer */
435    buffer->flags &= ~(USB_BUFFER_SUBMITTED | USB_BUFFER_SHORT_PACKET);
436    if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
437    /* Use next buffer. */
438    buffer = buffer->next;
439  } while(1);
440  
441  if (short_packet) {
442    buffer->flags |= USB_BUFFER_SHORT_PACKET;
443  }
444  
445  if ((buffer->left == 0)
446      || (buffer->flags & USB_BUFFER_PACKET_END)
447      || (short_packet && (buffer->flags & USB_BUFFER_SHORT_END))) {
448    /* Release buffer */
449    buffer->flags &= ~USB_BUFFER_SUBMITTED;
450    if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
451    /* Use next buffer. */
452    buffer = buffer->next;
453  }
454  
455  ep->buffer = buffer;
456  if (setup_data) {
457    /* Set direction according to request */
458    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[0],
459			  ((setup_data[0] & 0x80)
460			   ? AT91C_UDP_DIR : 0), AT91C_UDP_DIR);
461  }
462  return res;
463}
464
465
466static void
467start_receive(USBEndpoint *ep)
468{
469  ep->flags |= USB_EP_FLAGS_RECEIVING;
470}
471
472#if 0
473static unsigned int
474get_transmit_length(USBBuffer *buffer)
475{
476  unsigned int length = 0;
477  while(buffer && (buffer->flags & USB_BUFFER_IN)) {
478    length += buffer->left;
479    buffer = buffer->next;
480  }
481  return length;
482}
483#endif
484
485static int
486start_transmit(USBEndpoint *ep)
487{
488  unsigned int res = 0;
489  USBBuffer *buffer = ep->buffer;
490  unsigned int len;
491  unsigned int hw_ep = EP_HW_NUM(ep->addr);
492  unsigned int ep_flags = ep->flags;
493  len = ep->xfer_size;
494  if (!(ep_flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_WRITE_BLOCK;
495  switch(ep_flags & USB_EP_FLAGS_TYPE_MASK) {
496  case USB_EP_FLAGS_TYPE_BULK:
497    if (buffer->flags & USB_BUFFER_HALT) {
498      if (ep->status & 0x01) return USB_WRITE_BLOCK;
499      ep->status |= 0x01;
500      if (!(ep->flags & USB_EP_FLAGS_TRANSMITTING)) {
501	UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],
502			      AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
503	PRINTF("HALT IN\n");
504      }
505      return USB_WRITE_BLOCK;
506    }
507  case USB_EP_FLAGS_TYPE_ISO:
508    if (!(ep->flags & USB_EP_FLAGS_TRANSMITTING)) {
509      if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_TXPKTRDY) return USB_WRITE_BLOCK;
510    }
511    break;
512  default:
513    if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_TXPKTRDY) return USB_WRITE_BLOCK;
514  }
515  
516
517  while (buffer) {
518    unsigned int copy;
519    if (buffer->left < len) {
520      copy = buffer->left;
521    } else {
522      copy = len;
523    }
524    len -= copy;
525    buffer->left -= copy;
526    write_hw_buffer(buffer->data, hw_ep, copy);
527    buffer->data += copy;
528    if (buffer->left == 0) {
529      if (buffer->flags & USB_BUFFER_SHORT_END) {
530	if (len == 0) {
531	  /* Send zero length packet. */
532	  break;
533	} else {
534	  len = 0;
535	}
536      }
537      /* Release buffer */
538      buffer->flags &= ~USB_BUFFER_SUBMITTED;
539      if (buffer->flags & USB_BUFFER_NOTIFY) res = USB_WRITE_NOTIFY;
540	   /* Use next buffer. */
541      buffer = buffer->next;
542    }
543    if (len == 0) break;
544  }
545  ep->buffer = buffer;
546  if (ep->flags & USB_EP_FLAGS_TRANSMITTING) {
547    ep->flags |= USB_EP_FLAGS_DOUBLE;
548  } else {
549    ep->flags |= USB_EP_FLAGS_TRANSMITTING;
550  }
551 
552  PRINTF("start_transmit: sent %08x\n",AT91C_UDP_CSR[hw_ep]);
553  /* Start transmission */
554  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],
555			AT91C_UDP_TXPKTRDY, AT91C_UDP_TXPKTRDY);
556
557  return res;
558}
559
560static void
561start_transfer(USBEndpoint *ep)
562{
563  unsigned int hw_ep = EP_HW_NUM(ep->addr);
564  int res;
565  while (1) {
566    if (!(ep->addr & 0x80)) {
567      if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
568	if (ep->status & 0x01) return ;
569	ep->status |= 0x01;
570	UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep->addr)],
571			      AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
572	PRINTF("HALT OUT\n");
573	*AT91C_UDP_IDR = 1<<hw_ep;
574	return;
575      }
576    }
577    if (!(ep->flags & USB_EP_FLAGS_RECV_PENDING)) break;
578    res = handle_pending_receive(ep);
579    if (res & USB_READ_NOTIFY) {
580      notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
581    }
582    PRINTF("received res = %d\n", res);
583    if (res & USB_READ_BLOCK) {
584      *AT91C_UDP_IDR = 1<<hw_ep;
585      return;
586    }
587    if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_RXSETUP) {
588      /* Acknowledge SETUP */
589      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0, AT91C_UDP_RXSETUP);
590    } else if (AT91C_UDP_CSR[hw_ep] & (AT91C_UDP_RX_DATA_BK1)) {
591       /* Ping-pong */
592      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0,
593			    (ep->flags & USB_EP_FLAGS_BANK_1_RECV_NEXT)
594			    ? AT91C_UDP_RX_DATA_BK1
595			    : AT91C_UDP_RX_DATA_BK0);
596      ep->flags ^= USB_EP_FLAGS_BANK_1_RECV_NEXT;
597    } else {
598      /* Ping-pong or single buffer */
599      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0,
600			    AT91C_UDP_RX_DATA_BK0);
601      ep->flags |= USB_EP_FLAGS_BANK_1_RECV_NEXT;
602    }
603
604    if (ep->flags & USB_EP_FLAGS_DOUBLE) {
605      ep->flags &= ~USB_EP_FLAGS_DOUBLE;
606    } else if IS_CONTROL_EP(ep) {
607      ep->flags &= ~(USB_EP_FLAGS_RECV_PENDING|USB_EP_FLAGS_SETUP_PENDING);
608    } else {
609      ep->flags &= ~USB_EP_FLAGS_RECV_PENDING;
610    }
611    if (res & USB_READ_FAIL) {
612      /* Only fails for control endpoints */
613      usb_arch_control_stall(ep->addr);
614      return;
615    }
616    *AT91C_UDP_IER = 1<<hw_ep;
617  }
618  if (ep->flags & (USB_EP_FLAGS_TRANSMITTING | USB_EP_FLAGS_RECEIVING)) {
619#if 0
620    if (!IS_BULK_EP(ep) || (ep->flags & USB_EP_FLAGS_DOUBLE)) {
621#else
622      if(1) {
623#endif
624      PRINTF("Busy\n");
625      return;
626    }
627  }
628  if (ep->status & 0x01) return; /* Don't start transfer if halted */
629  if (ep->buffer) {
630    if (ep->buffer->flags & USB_BUFFER_IN) {
631      res = start_transmit(ep);
632      if (res & USB_WRITE_NOTIFY) {
633	notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
634      }
635    } else {
636      start_receive(ep);
637    }
638  }
639}
640
641
642void
643usb_arch_transfer_complete(unsigned int hw_ep)
644{
645  unsigned int status = AT91C_UDP_CSR[hw_ep];
646  USBEndpoint *ep = &usb_endpoints[hw_ep];
647  PRINTF("transfer_complete: %d\n", hw_ep);
648  if (status & AT91C_UDP_STALLSENT) {
649    /* Acknowledge */
650    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0, AT91C_UDP_STALLSENT);
651  }
652  if (status & (AT91C_UDP_RXSETUP
653		| AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_RX_DATA_BK0)) {
654    if (status & AT91C_UDP_RXSETUP) {
655      PRINTF("SETUP\n"); 
656      ep->flags |= USB_EP_FLAGS_SETUP_PENDING;
657    }
658    if (ep->flags & USB_EP_FLAGS_DOUBLE) {
659      ep->flags &= ~USB_EP_FLAGS_DOUBLE;
660    } else {
661      ep->flags &= ~USB_EP_FLAGS_RECEIVING;
662    }
663    if ( ep->flags & USB_EP_FLAGS_RECV_PENDING) {
664      ep->flags |= USB_EP_FLAGS_DOUBLE;
665    } else {
666      ep->flags |= USB_EP_FLAGS_RECV_PENDING;
667    }
668    start_transfer(ep);
669  }
670  if (status & AT91C_UDP_TXCOMP) {
671     PRINTF("Sent packet\n");
672    if (ep->flags & USB_EP_FLAGS_DOUBLE) {
673      ep->flags &= ~USB_EP_FLAGS_DOUBLE;
674    } else {
675      ep->flags &= ~USB_EP_FLAGS_TRANSMITTING;
676    }
677    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],0, AT91C_UDP_TXCOMP);
678    if (ep->status & 0x01) {
679      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep],
680			    AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
681      PRINTF("HALT IN\n");
682    } else {
683      start_transfer(ep);
684    }
685  }
686  
687}
688
689
690void
691usb_set_ep_event_process(unsigned char addr, struct process *p)
692{
693  USBEndpoint *ep = &usb_endpoints[EP_INDEX(addr)];
694  ep->event_process = p;
695}
696
697/* Select what process should be polled when a global event occurs */
698void
699usb_arch_set_global_event_process(struct process *p)
700{
701  event_process = p;
702}
703
704unsigned int
705usb_arch_get_global_events(void)
706{
707  unsigned int e;
708  USB_DISABLE_INT;
709  e = events;
710  events = 0;
711  USB_ENABLE_INT;
712  return e;
713}
714
715unsigned int
716usb_get_ep_events(unsigned char addr)
717{
718  unsigned int e;
719  unsigned int ei = EP_HW_NUM(addr);
720  USB_DISABLE_INT;
721  e = usb_endpoints[ei].events;
722  usb_endpoints[ei].events = 0;
723  USB_ENABLE_INT;
724  return e;
725}
726
727
728void
729usb_submit_recv_buffer(unsigned char ep_addr, USBBuffer *buffer)
730{
731  USBBuffer **tailp;
732  USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
733  if (!(ep->flags & USB_EP_FLAGS_ENABLED)) return;
734  /* PRINTF("buffer: %p\n", ep->buffer); */
735  /* dbg_drain(); */
736  USB_DISABLE_INT;
737  tailp = (USBBuffer**)&ep->buffer;
738  while(*tailp) {
739    tailp = &(*tailp)->next;
740  }
741  *tailp = buffer;
742  while(buffer) {
743    buffer->flags |= USB_BUFFER_SUBMITTED;
744    buffer = buffer->next;
745  }
746  start_transfer(ep);
747  
748  USB_ENABLE_INT;
749}
750
751void
752usb_submit_xmit_buffer(unsigned char ep_addr, USBBuffer *buffer)
753{
754  USBBuffer **tailp;
755  USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
756  if (!(ep->flags & USB_EP_FLAGS_ENABLED)) return;
757  /* PRINTF("usb_submit_xmit_buffer %d\n", buffer->left); */
758  USB_DISABLE_INT;
759  tailp = (USBBuffer**)&ep->buffer;
760  while(*tailp) {
761    tailp = &(*tailp)->next;
762  }
763  *tailp = buffer;
764  while(buffer) {
765    buffer->flags |= USB_BUFFER_SUBMITTED | USB_BUFFER_IN;
766    buffer = buffer->next;
767  }
768  start_transfer(ep);
769  USB_ENABLE_INT;
770}
771
772void
773usb_arch_discard_all_buffers(unsigned char ep_addr)
774{
775  USBBuffer *buffer;
776  volatile USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
777  USB_DISABLE_EP_INT(EP_HW_NUM(ep_addr));
778  buffer = ep->buffer;
779  ep->buffer = NULL;
780
781  USB_ENABLE_EP_INT(EP_HW_NUM(ep_addr));
782  while(buffer) {
783    buffer->flags &= ~USB_BUFFER_SUBMITTED;
784    buffer = buffer->next;
785  }
786}
787
788uint16_t
789usb_arch_get_ep_status(uint8_t addr)
790{
791  if (EP_INDEX(addr) > USB_MAX_ENDPOINTS) return 0;
792  return usb_endpoints[EP_INDEX(addr)].status;
793}
794
795void
796usb_arch_set_configuration(uint8_t usb_configuration_value)
797{
798  /* Nothing needs to be done */
799}
800
801void
802usb_arch_control_stall(unsigned char addr)
803{
804  if (EP_INDEX(addr) > USB_MAX_ENDPOINTS) return;
805  UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(addr)],
806			AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
807}
808
809/* Not for control endpoints */
810void
811usb_arch_halt_endpoint(unsigned char ep_addr, int halt)
812{
813  if (EP_INDEX(ep_addr) > USB_MAX_ENDPOINTS) return;
814  if (!usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_ENABLED) return;
815  *AT91C_UDP_IDR = 1<<EP_HW_NUM(ep_addr);
816  if (halt) {
817    usb_endpoints[EP_INDEX(ep_addr)].status |= 0x01;
818    /* Delay stall if a transmission is i progress */
819    if (!(usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_TRANSMITTING)){
820      UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep_addr)],
821			    AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL);
822    }
823  } else {
824    USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
825    ep->status &= ~0x01;
826    *AT91C_UDP_IDR = 1<<EP_HW_NUM(ep_addr);
827    UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep_addr)],
828			  0, AT91C_UDP_FORCESTALL);
829    *AT91C_UDP_RSTEP = 1<<EP_HW_NUM(ep_addr);
830    *AT91C_UDP_RSTEP = 0;
831    
832    /* Release HALT buffer */
833    if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
834      ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
835      if (ep->buffer->flags & USB_BUFFER_NOTIFY) {
836	notify_ep_process(ep,USB_EP_EVENT_NOTIFICATION);
837      }
838      ep->buffer = ep->buffer->next;
839    }
840    
841    /* Restart transmission */
842    start_transfer(&usb_endpoints[EP_INDEX(ep_addr)]);
843  }
844  *AT91C_UDP_IER = 1<<EP_HW_NUM(ep_addr);
845}
846
847int 
848usb_arch_send_pending(uint8_t ep_addr)
849{
850  return usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_TRANSMITTING;
851}
852
853void
854usb_arch_set_address(unsigned char addr)
855{
856  *AT91C_UDP_FADDR = AT91C_UDP_FEN | addr;
857  *AT91C_UDP_GLBSTATE |= AT91C_UDP_FADDEN;
858}
859
860void
861usb_arch_reset_int()
862{
863  usb_arch_reset();
864  notify_process(USB_EVENT_RESET);
865}
866
867void
868usb_arch_suspend_int()
869{
870  notify_process(USB_EVENT_SUSPEND);
871}
872
873void
874usb_arch_resume_int()
875{
876  notify_process(USB_EVENT_RESUME);
877}
878