Contiki 3.x
usb-arch.c
1 /*
2 Copyright (c) 2012, Philippe Retornaz
3 Copyright (c) 2012, EPFL STI IMT LSRO1 -- Mobots group
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 1. Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in the
13  documentation and/or other materials provided with the distribution.
14 3. The name of the author may not be used to endorse or promote
15  products derived from this software without specific prior
16  written permission.
17 
18 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 #include "contiki.h"
32 #include "usb-arch.h"
33 #include "port2.h"
34 
35 #include "cc253x.h"
36 #include "sfr-bits.h"
37 #include "port.h"
38 
39 #include "dma.h"
40 
41 // P1_0
42 #define USB_PULLUP_PORT 1
43 #define USB_PULLUP_PIN 0
44 
45 #define USBCTRL_USB_EN (1 << 0)
46 #define USBCTRL_PLL_EN (1 << 1)
47 #define USBCTRL_PLL_LOCKED (1 << 7)
48 
49 #define USBIIE_EP0IE (1 << 0)
50 #define USBIIE_INEPxIE(x) (1 << x)
51 
52 #define USBOIE_OUEPxIE(x) (1 << x)
53 
54 #define USBCSxH_ISO (1 << 6)
55 
56 #define USBCS0_CLR_SETUP_END (1 << 7)
57 #define USBCS0_CLR_OUTPKT_RDY (1 << 6)
58 #define USBCS0_SEND_STALL (1 << 5)
59 #define USBCS0_SETUP_END (1 << 4)
60 #define USBCS0_DATA_END (1 << 3)
61 #define USBCS0_SENT_STALL (1 << 2)
62 #define USBCS0_INPKT_RDY (1 << 1)
63 #define USBCS0_OUTPKT_RDY (1 << 0)
64 
65 #define USBCSIL_SENT_STALL (1 << 5)
66 #define USBCSIL_SEND_STALL (1 << 4)
67 #define USBCSIL_FLUSH_PACKET (1 << 3)
68 #define USBCSIL_UNDERRUN (1 << 2)
69 #define USBCSIL_PKT_PRESENT (1 << 1)
70 #define USBCSIL_INPKT_RDY (1 << 0)
71 
72 #define USBCSOL_SENT_STALL (1 << 6)
73 #define USBCSOL_SEND_STALL (1 << 5)
74 #define USBCSOL_OVERRUN (1 << 2)
75 #define USBCSOL_OUTPKT_RDY (1 << 0)
76 
77 // Double buffering not used
78 // We assume only the IN or the OUT of
79 // each endpoint is enabled and not both.
80 #if CTRL_EP_SIZE > 32
81 #error Control endpoint size too big
82 #endif
83 
84 #if USB_EP1_SIZE > 32
85 #error Endpoint 1 size too big
86 #endif
87 
88 #if USB_EP2_SIZE > 64
89 #error Endpoint 2 size too big
90 #endif
91 
92 #if USB_EP3_SIZE > 128
93 #error Endpoint 3 size too big
94 #endif
95 
96 #if USB_EP4_SIZE > 256
97 #error Endpoint 4 size too big
98 #endif
99 
100 #if USB_EP5_SIZE > 512
101 #error Endpoint 5 size too big
102 #endif
103 
104 
105 static const uint16_t ep_xfer_size[] = {
106  CTRL_EP_SIZE,
107  USB_EP1_SIZE,
108  USB_EP2_SIZE,
109  USB_EP3_SIZE,
110  USB_EP4_SIZE,
111  USB_EP5_SIZE,
112 };
113 
114 
115 #define EP_IDLE 0
116 #define EP_RX 1
117 #define EP_TX 2
118 static uint8_t ep0status;
119 
120 typedef struct _USBEndpoint USBEndpoint;
121 struct _USBEndpoint {
122  uint8_t halted;
123  uint8_t addr;
124  uint8_t flags;
125  USBBuffer *buffer; /* NULL if no current buffer */
126  struct process *event_process;
127  unsigned int events;
128  uint16_t xfer_size;
129 };
130 
131 #define USB_EP_FLAGS_TYPE_MASK 0x03
132 #define USB_EP_FLAGS_TYPE_BULK 0x00
133 #define USB_EP_FLAGS_TYPE_CONTROL 0x01
134 #define USB_EP_FLAGS_TYPE_ISO 0x02
135 #define USB_EP_FLAGS_TYPE_INTERRUPT 0x03
136 
137 #define USB_EP_FLAGS_ENABLED 0x04
138 
139 #define EP_TYPE(ep) ((ep)->flags & USB_EP_FLAGS_TYPE_MASK)
140 #define IS_EP_TYPE(ep, type) (EP_TYPE(ep) == (type))
141 #define IS_CONTROL_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_CONTROL)
142 #define IS_BULK_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_BULK)
143 #define IS_INTERRUPT_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_INTERRUPT)
144 #define IS_ISO_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_ISO)
145 
146 
147 #define USB_WRITE_BLOCK 0x01
148 #define USB_READ_BLOCK 0x01 /* The currently submitted buffers
149  can't hold the received data, wait
150  for more buffers. No data was read
151  from the hardware buffer */
152 #define USB_WRITE_NOTIFY 0x02
153 #define USB_READ_NOTIFY 0x02 /* Some buffers that had the
154  USB_BUFFER_NOTIFY flags set were
155  released */
156 #define USB_READ_FAIL 0x4
157 
158 
159 /* Index in endpoint array */
160 #define EP_INDEX(addr) ((addr) & 0x7f)
161 
162 /* Get address of endpoint struct */
163 #define EP_STRUCT(addr) &usb_endpoints[EP_INDEX(addr)];
164 
165 /* Number of hardware endpoint */
166 #define EP_HW_NUM(addr) ((addr) & 0x7f)
167 
168 #define usb_irq_disable(flag) cc253x_p2_irq_disable(flag)
169 #define usb_irq_enable(flag) cc253x_p2_irq_enable(flag)
170 
171 static uint8_t usb_irq(void);
172 static void usb_arch_epin_irq(uint8_t ep_hw);
173 static void usb_arch_epout_irq(uint8_t ep_hw);
174 static void usb_arch_ep0_irq(void);
175 
176 static struct cc253x_p2_handler usb_irq_handler = { NULL, usb_irq };
177 
178 static USBEndpoint usb_endpoints[USB_MAX_ENDPOINTS];
179 struct process *event_process = 0;
180 volatile static unsigned int events = 0;
181 
182 static uint8_t ep0_tx(void);
183 static uint8_t ep_tx(uint8_t ep_hw);
184 
185 static void
186 notify_process(unsigned int e)
187 {
188  events |= e;
189  if(event_process) {
190  process_poll(event_process);
191  }
192 }
193 
194 static void
195 notify_ep_process(USBEndpoint * ep, unsigned int e)
196 {
197  ep->events |= e;
198  if(ep->event_process) {
199  process_poll(ep->event_process);
200  }
201 }
202 
203 
204 void
205 usb_set_ep_event_process(unsigned char addr, struct process *p)
206 {
207  USBEndpoint *ep = EP_STRUCT(addr);
208 
209  ep->event_process = p;
210 }
211 
212 
213 void
214 usb_arch_set_global_event_process(struct process *p)
215 {
216  event_process = p;
217 }
218 
219 unsigned int
220 usb_arch_get_global_events(void)
221 {
222  uint8_t flag;
223  volatile unsigned int e;
224 
225  usb_irq_disable(flag);
226  e = events;
227  events = 0;
228  usb_irq_enable(flag);
229 
230  return e;
231 }
232 
233 unsigned int
234 usb_get_ep_events(uint8_t addr)
235 {
236  volatile unsigned int e;
237  uint8_t flag;
238  USBEndpoint *ep = EP_STRUCT(addr);
239 
240  usb_irq_disable(flag);
241  e = ep->events;
242  ep->events = 0;
243  usb_irq_enable(flag);
244 
245  return e;
246 }
247 #if DMA_ON
248 #ifndef DMA_USB_CHANNEL
249 #error You must set DMA_USB_CHANNEL to a valid dma channel.
250 #endif
251 static void
252 read_hw_buffer_dma(uint8_t tl, uint8_t th, uint8_t __xdata * xptr,
253  unsigned int len)
254 {
255  dma_conf[DMA_USB_CHANNEL].src_h = ((uint16_t) xptr) >> 8;
256  dma_conf[DMA_USB_CHANNEL].src_l = ((uint16_t) xptr) & 0xFF;
257  dma_conf[DMA_USB_CHANNEL].dst_h = th;
258  dma_conf[DMA_USB_CHANNEL].dst_l = tl;
259 
260  // Maximum USB len transfert is 512bytes, maximum DMA len: 4096, we are safe.
261  dma_conf[DMA_USB_CHANNEL].len_h = len >> 8;
262  dma_conf[DMA_USB_CHANNEL].len_l = len & 0xFF;
263  dma_conf[DMA_USB_CHANNEL].wtt = DMA_T_NONE | DMA_BLOCK;
264  // Maximum prio, we will be polling until the transfert is done.
265  dma_conf[DMA_USB_CHANNEL].inc_prio =
266  DMA_SRC_INC_NO | DMA_DST_INC_1 | DMA_PRIO_HIGH;
267 
268  DMA_ARM(DMA_USB_CHANNEL);
269  // Wait until the channel is armed
270  while(!(DMAARM & (1 << DMA_USB_CHANNEL)));
271 
272  DMA_TRIGGER(DMA_USB_CHANNEL);
273  // Wait until the transfert is done.
274  // For some unknown reason, the DMA channel do not set the IRQ flag
275  // sometimes, so use the DMAARM bit to check if transfert is done
276  while(DMAARM & (1 << DMA_USB_CHANNEL));
277  // Clear interrupt flag
278  DMAIRQ = ~(1 << DMA_USB_CHANNEL);
279 }
280 static void
281 write_hw_buffer_dma(uint8_t __xdata * xptr, uint8_t fl, uint8_t fh,
282  unsigned int len)
283 {
284  dma_conf[DMA_USB_CHANNEL].src_h = fh;
285  dma_conf[DMA_USB_CHANNEL].src_l = fl;
286  dma_conf[DMA_USB_CHANNEL].dst_h = ((uint16_t) xptr) >> 8;
287  dma_conf[DMA_USB_CHANNEL].dst_l = ((uint16_t) xptr) & 0xFF;
288 
289  // Maximum USB len transfert is 512bytes, maximum DMA len: 4096, we are safe.
290  dma_conf[DMA_USB_CHANNEL].len_h = len >> 8;
291  dma_conf[DMA_USB_CHANNEL].len_l = len & 0xFF;
292  dma_conf[DMA_USB_CHANNEL].wtt = DMA_T_NONE | DMA_BLOCK;
293  // Maximum prio, we will be polling until the transfert is done.
294  dma_conf[DMA_USB_CHANNEL].inc_prio =
295  DMA_SRC_INC_1 | DMA_DST_INC_NO | DMA_PRIO_HIGH;
296 
297  DMA_ARM(DMA_USB_CHANNEL);
298  // Wait until the channel is armed
299  while(!(DMAARM & (1 << DMA_USB_CHANNEL)));
300 
301  DMA_TRIGGER(DMA_USB_CHANNEL);
302  // Wait until the transfert is done.
303  while(DMAARM & (1 << DMA_USB_CHANNEL));
304 
305  // Clear interrupt flag
306  DMAIRQ = ~(1 << DMA_USB_CHANNEL);
307 }
308 
309 #endif
310 static void
311 read_hw_buffer(uint8_t * to, uint8_t hw_ep, unsigned int len)
312 {
313  __xdata uint8_t *from = &USBF0 + (hw_ep << 1);
314 
315 #if DMA_ON
316  // For small transfers we use PIO
317  // This check is specific to SDCC and large/huge memory model
318  if(len > 8 && ((uint8_t *) & to)[2] == 0x0 /* x data pointer */ ) {
319  read_hw_buffer_dma(((uint8_t *) & to)[0], ((uint8_t *) & to)[1], from,
320  len);
321  return;
322  }
323 #endif
324  while(len--) {
325  *to++ = *from;
326  }
327 }
328 
329 static void
330 write_hw_buffer(uint8_t hw_ep, uint8_t * from, unsigned int len)
331 {
332  __xdata uint8_t *to = &USBF0 + (hw_ep << 1);
333 
334 #if DMA_ON
335  // For small transfers we use PIO
336  if(len > 8 && ((uint8_t *) & from)[2] == 0x0 /* x data pointer */ ) {
337  write_hw_buffer_dma(to, ((uint8_t *) & from)[0], ((uint8_t *) & from)[1],
338  len);
339  return;
340  }
341 #endif
342  while(len--) {
343  *to = *from++;
344  }
345 }
346 
347 static void
348 usb_arch_reset(void)
349 {
350  uint8_t e;
351 
352  for(e = 0; e < USB_MAX_ENDPOINTS; e++) {
353  if(usb_endpoints[e].flags & USB_EP_FLAGS_ENABLED) {
354  USBBuffer *buffer = usb_endpoints[e].buffer;
355 
356  usb_endpoints[e].flags = 0;
357  usb_disable_endpoint(e);
358  while(buffer) {
359  buffer->flags &= ~USB_BUFFER_SUBMITTED;
360  buffer = buffer->next;
361  }
362  }
363  }
364  usb_arch_setup_control_endpoint(0);
365 }
366 
367 /* Init USB */
368 void
369 usb_arch_setup(void)
370 {
371  uint8_t i;
372 
373  /* Switch on USB PLL & USB module */
374  USBCTRL = USBCTRL_USB_EN | USBCTRL_PLL_EN;
375 
376  /* Wait until USB PLL is stable */
377  while(!(USBCTRL & USBCTRL_PLL_LOCKED));
378 
379  /* Enable pull-up on usb port */
380  PORT_SET(USB_PULLUP_PORT, USB_PULLUP_PIN);
381  PORT_DIR_OUTPUT(USB_PULLUP_PORT, USB_PULLUP_PIN);
382 
383  for(i = 0; i < USB_MAX_ENDPOINTS; i++) {
384  usb_endpoints[i].flags = 0;
385  usb_endpoints[i].event_process = 0;
386  }
387 
388  usb_arch_reset();
389 
390  // Disable all endpoints interrupts
391  // Enpoint 0 interrupt will be enabled later
392  USBIIE = 0;
393  USBOIE = 0;
394 
395  cc253x_p2_register_handler(&usb_irq_handler);
396  // We have to force IRQ enable as we might be the first user
397  cc253x_p2_irq_force_enable();
398 }
399 
400 void
401 usb_submit_recv_buffer(uint8_t addr, USBBuffer * buffer)
402 {
403  USBBuffer **tailp;
404  uint8_t flag;
405  USBEndpoint *ep = EP_STRUCT(addr);
406 
407  if(!(ep->flags & USB_EP_FLAGS_ENABLED)) {
408  return;
409  }
410 
411  if(buffer->data == NULL && EP_HW_NUM(addr) == 0) {
412  // the usb-core is trying to get the STATUS packet (ZLP in this case)
413  // but the USB hardware is catching them, thus ignore this.
414  // FIXME: Use the interrupt to release this buffer when the packet is sent
415  // at least the timing would be better ...
416  if(buffer->flags & USB_BUFFER_NOTIFY) {
417  notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
418  }
419  return;
420  }
421 
422  usb_irq_disable(flag);
423 
424  tailp = &ep->buffer;
425  while(*tailp) {
426  tailp = &(*tailp)->next;
427  }
428  *tailp = buffer;
429  while(buffer) {
430  buffer->flags |= USB_BUFFER_SUBMITTED;
431  buffer = buffer->next;
432  }
433 
434  USBINDEX = EP_HW_NUM(addr);
435  if(!EP_HW_NUM(ep->addr)) {
436  if(USBCS0 & USBCS0_OUTPKT_RDY) {
437  usb_arch_ep0_irq();
438  }
439  } else {
440  if(USBCSOL & USBCSOL_OUTPKT_RDY) {
441  usb_arch_epout_irq(EP_HW_NUM(ep->addr));
442  }
443  }
444  usb_irq_enable(flag);
445 }
446 
447 void
448 usb_submit_xmit_buffer(uint8_t addr, USBBuffer * buffer)
449 {
450  USBBuffer **tailp;
451  uint8_t flag;
452  uint8_t res;
453  USBEndpoint *ep = EP_STRUCT(addr);
454 
455  if(!(ep->flags & USB_EP_FLAGS_ENABLED)) {
456  return;
457  }
458 
459  usb_irq_disable(flag);
460 
461 
462  if(EP_HW_NUM(addr) == 0) {
463  if(buffer->data == NULL) {
464  // We are asked to send a STATUS packet.
465  // But the USB hardware is doing this automatically
466  // as soon as we release hw FIFO.
467  USBINDEX = 0;
468  USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
469  notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
470  usb_irq_enable(flag);
471  return;
472  } else {
473  // Release the hw FIFO ...
474  USBINDEX = 0;
475  USBCS0 = USBCS0_CLR_OUTPKT_RDY;
476  }
477  }
478 
479  tailp = &ep->buffer;
480  while(*tailp) {
481  tailp = &(*tailp)->next;
482  }
483  *tailp = buffer;
484  while(buffer) {
485  buffer->flags |= USB_BUFFER_SUBMITTED | USB_BUFFER_IN;
486  buffer = buffer->next;
487  }
488 
489  USBINDEX = EP_HW_NUM(ep->addr);
490  if(EP_HW_NUM(ep->addr)) {
491  res = ep_tx(EP_HW_NUM(ep->addr));
492  } else {
493  res = ep0_tx();
494  }
495 
496  usb_irq_enable(flag);
497 
498  if(res & USB_WRITE_NOTIFY) {
499  notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
500  }
501 
502 }
503 
504 
505 static void
506 usb_arch_setup_endpoint0(void)
507 {
508  USBIIE |= USBIIE_EP0IE;
509 }
510 
511 static void
512 usb_arch_setup_in_endpoint(uint8_t addr)
513 {
514  uint8_t ei = EP_HW_NUM(addr);
515  USBEndpoint *ep = EP_STRUCT(addr);
516 
517  // Enable interrupt
518  USBIIE |= USBIIE_INEPxIE(ei);
519 
520  // Set internal FIFO size
521  USBMAXI = ep->xfer_size / 8;
522 
523  if(IS_ISO_EP(ep)) {
524  USBCSIH |= USBCSxH_ISO;
525  } else {
526  USBCSIH &= ~USBCSxH_ISO;
527  }
528 }
529 
530 static void
531 usb_arch_setup_out_endpoint(uint8_t addr)
532 {
533  uint8_t ei = EP_HW_NUM(addr);
534  USBEndpoint *ep = EP_STRUCT(addr);
535 
536  // Enable interrupt
537  USBOIE |= USBOIE_OUEPxIE(ei);
538 
539  // Set internal FIFO size
540  USBMAXO = ep->xfer_size / 8;
541 
542  if(IS_ISO_EP(ep)) {
543  USBCSOH |= USBCSxH_ISO;
544  } else {
545  USBCSOH &= ~USBCSxH_ISO;
546  }
547 }
548 
549 static void
550 usb_arch_setup_endpoint(uint8_t addr)
551 {
552  uint8_t ei = EP_HW_NUM(addr);
553  uint8_t flag;
554  USBEndpoint *ep = EP_STRUCT(addr);
555 
556  ep->halted = 0;
557  ep->flags |= USB_EP_FLAGS_ENABLED;
558  ep->buffer = 0;
559  ep->addr = addr;
560  ep->events = 0;
561  ep->xfer_size = ep_xfer_size[ei];
562 
563  usb_irq_disable(flag);
564  // Select endpoint banked register
565  USBINDEX = ei;
566 
567  // special case for ep 0
568  if(ei == 0) {
569  usb_arch_setup_endpoint0();
570  } else {
571  if(addr & 0x80) {
572  usb_arch_setup_in_endpoint(addr);
573  } else {
574  usb_arch_setup_out_endpoint(addr);
575  }
576  }
577  usb_irq_enable(flag);
578 }
579 
580 void
581 usb_arch_setup_iso_endpoint(uint8_t addr)
582 {
583  USBEndpoint *ep = EP_STRUCT(addr);
584 
585  ep->flags = USB_EP_FLAGS_TYPE_ISO;
586 
587  usb_arch_setup_endpoint(addr);
588 }
589 
590 void
591 usb_arch_setup_control_endpoint(uint8_t addr)
592 {
593  USBEndpoint *ep = EP_STRUCT(addr);
594 
595  ep->flags = USB_EP_FLAGS_TYPE_CONTROL;
596 
597  usb_arch_setup_endpoint(addr);
598 }
599 
600 void
601 usb_arch_setup_bulk_endpoint(uint8_t addr)
602 {
603  USBEndpoint *ep = EP_STRUCT(addr);
604 
605  ep->flags = USB_EP_FLAGS_TYPE_BULK;
606 
607  usb_arch_setup_endpoint(addr);
608 }
609 
610 void
611 usb_arch_setup_interrupt_endpoint(uint8_t addr)
612 {
613  USBEndpoint *ep = EP_STRUCT(addr);
614 
615  ep->flags = USB_EP_FLAGS_TYPE_INTERRUPT;
616 
617  usb_arch_setup_endpoint(addr);
618 }
619 
620 static void
621 usb_arch_disable_ep0(void)
622 {
623  USBIIE &= ~USBIIE_EP0IE;
624  USBCS0 = 0xC0; // Clear any pending status flags
625 }
626 
627 static void
628 usb_arch_disable_in_endpoint(uint8_t addr)
629 {
630  USBMAXI = 0;
631  USBIIE &= ~USBIIE_INEPxIE(EP_HW_NUM(addr));
632 
633  // Flush any pending packets
634  USBCSIL = 0x08; // Double-buffering not used. Flush only once
635 }
636 
637 static void
638 usb_arch_disable_out_endpoint(uint8_t addr)
639 {
640  USBMAXO = 0;
641  USBOIE &= ~USBOIE_OUEPxIE(EP_HW_NUM(addr));
642 
643  // Flush any pending packets
644  USBCSOL = 0x08; // Double buffering not used, flush only once
645 }
646 
647 
648 void
649 usb_arch_disable_endpoint(uint8_t addr)
650 {
651  uint8_t ei = EP_HW_NUM(addr);
652  uint8_t flag;
653  USBEndpoint *ep = EP_STRUCT(addr);
654 
655  ep->flags &= ~USB_EP_FLAGS_ENABLED;
656 
657  usb_irq_disable(flag);
658  USBINDEX = ei;
659  if(ei == 0) {
660  usb_arch_disable_ep0();
661  } else {
662  if(addr & 0x80) {
663  usb_arch_disable_in_endpoint(addr);
664  } else {
665  usb_arch_disable_out_endpoint(addr);
666  }
667  }
668  usb_irq_enable(flag);
669 }
670 
671 void
672 usb_arch_discard_all_buffers(uint8_t addr)
673 {
674  USBBuffer *buffer;
675  uint8_t flag;
676  volatile USBEndpoint *ep = EP_STRUCT(addr);
677 
678  usb_irq_disable(flag);
679  buffer = ep->buffer;
680  ep->buffer = NULL;
681  usb_irq_enable(flag);
682 
683  while(buffer) {
684  buffer->flags &= ~USB_BUFFER_SUBMITTED;
685  buffer = buffer->next;
686  }
687 }
688 
689 static void
690 set_stall(uint8_t addr, uint8_t stall)
691 {
692  uint8_t ei = EP_HW_NUM(addr);
693 
694  USBINDEX = ei;
695  if(ei == 0) {
696  // Stall is automatically deasserted on EP0
697  if(stall) {
698  ep0status = EP_IDLE;
699  USBCS0 |= USBCS0_SEND_STALL | USBCS0_OUTPKT_RDY;
700  }
701  } else {
702  if(addr & 0x80) {
703  if(stall) {
704  USBCSIL |= USBCSIL_SEND_STALL;
705  } else {
706  USBCSIL &= ~USBCSIL_SEND_STALL;
707  }
708  } else {
709  if(stall) {
710  USBCSOL |= USBCSOL_SEND_STALL;
711  } else {
712  USBCSOL &= ~USBCSOL_SEND_STALL;
713  }
714  }
715  }
716 }
717 
718 void
719 usb_arch_control_stall(uint8_t addr)
720 {
721  uint8_t ei = EP_HW_NUM(addr);
722  uint8_t flag;
723 
724  if(ei > USB_MAX_ENDPOINTS) {
725  return;
726  }
727 
728  usb_irq_disable(flag);
729 
730  set_stall(addr, 1);
731 
732  usb_irq_enable(flag);
733 }
734 
735 void
736 usb_arch_halt_endpoint(uint8_t addr, int halt)
737 {
738  uint8_t ei = EP_HW_NUM(addr);
739  uint8_t flag;
740  USBEndpoint *ep = EP_STRUCT(addr);
741 
742 
743  if(ei > USB_MAX_ENDPOINTS) {
744  return;
745  }
746 
747  if(!(ep->flags & USB_EP_FLAGS_ENABLED)) {
748  return;
749  }
750 
751  usb_irq_disable(flag);
752 
753  if(halt) {
754  ep->halted = 0x1;
755  set_stall(addr, 1);
756  } else {
757  ep->halted = 0;
758  set_stall(addr, 0);
759 
760  if(ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
761  ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
762  if(ep->buffer->flags & USB_BUFFER_NOTIFY) {
763  notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
764  }
765  ep->buffer = ep->buffer->next;
766  }
767  if(ei) {
768  usb_arch_epout_irq(EP_HW_NUM(addr));
769  }
770  }
771 
772  usb_irq_enable(flag);
773 }
774 
775 void
776 usb_arch_set_configuration(uint8_t usb_configuration_value)
777 {
778  // Nothing to do ?
779 }
780 
781 uint16_t
782 usb_arch_get_ep_status(uint8_t addr)
783 {
784  uint8_t ei = EP_INDEX(addr);
785  USBEndpoint *ep = EP_STRUCT(addr);
786 
787  if(ei > USB_MAX_ENDPOINTS) {
788  return 0;
789  }
790 
791  return ep->halted;
792 }
793 
794 void
795 usb_arch_set_address(uint8_t addr)
796 {
797  USBADDR = addr;
798 }
799 
800 int
801 usb_arch_send_pending(uint8_t addr)
802 {
803  uint8_t flag;
804  uint8_t ret;
805  uint8_t ei = EP_INDEX(addr);
806 
807  usb_irq_disable(flag);
808  USBINDEX = ei;
809  if(ei == 0) {
810  ret = USBCS0 & USBCS0_INPKT_RDY;
811  } else {
812  ret = USBCSIL & USBCSIL_INPKT_RDY;
813  }
814  usb_irq_enable(flag);
815 
816  return ret;
817 }
818 
819 static unsigned int
820 get_receive_capacity(USBBuffer * buffer)
821 {
822  unsigned int capacity = 0;
823 
824  while(buffer &&
825  !(buffer->flags & (USB_BUFFER_IN | USB_BUFFER_SETUP | USB_BUFFER_HALT))) {
826  capacity += buffer->left;
827  buffer = buffer->next;
828  }
829  return capacity;
830 }
831 
832 static USBBuffer *
833 skip_buffers_until(USBBuffer * buffer, unsigned int mask, unsigned int flags,
834  uint8_t * resp)
835 {
836  while(buffer && !((buffer->flags & mask) == flags)) {
837  buffer->flags &= ~USB_BUFFER_SUBMITTED;
838  buffer->flags |= USB_BUFFER_FAILED;
839  if(buffer->flags & USB_BUFFER_NOTIFY) {
840  *resp |= USB_READ_NOTIFY;
841  }
842  buffer = buffer->next;
843  }
844  return buffer;
845 }
846 
847 static uint8_t
848 fill_buffers(USBBuffer * buffer, uint8_t hw_ep, unsigned int len,
849  uint8_t short_packet)
850 {
851  unsigned int t;
852  uint8_t res = 0;
853 
854  do {
855  if(buffer->left < len) {
856  t = buffer->left;
857  } else {
858  t = len;
859  }
860  len -= t;
861  buffer->left -= t;
862 
863  read_hw_buffer(buffer->data, hw_ep, t);
864 
865  buffer->data += t;
866 
867  if(len == 0) {
868  break;
869  }
870 
871  buffer->flags &= ~(USB_BUFFER_SUBMITTED | USB_BUFFER_SHORT_PACKET);
872  if(buffer->flags & USB_BUFFER_NOTIFY) {
873  res |= USB_READ_NOTIFY;
874  }
875  buffer = buffer->next;
876  } while(1);
877 
878  if(short_packet) {
879  buffer->flags |= USB_BUFFER_SHORT_PACKET;
880  }
881 
882  if((buffer->left == 0) || (buffer->flags & USB_BUFFER_PACKET_END)) {
883  buffer->flags &= ~USB_BUFFER_SUBMITTED;
884  if(buffer->flags & USB_BUFFER_NOTIFY) {
885  res |= USB_READ_NOTIFY;
886  }
887  buffer = buffer->next;
888  } else {
889  if(short_packet) {
890  if(buffer->left && !(buffer->flags & USB_BUFFER_SHORT_END)) {
891  buffer->flags |= USB_BUFFER_FAILED;
892  res |= USB_READ_FAIL;
893  }
894  buffer->flags &= ~USB_BUFFER_SUBMITTED;
895  if(buffer->flags & USB_BUFFER_NOTIFY) {
896  res |= USB_READ_NOTIFY;
897  }
898  buffer = buffer->next;
899  }
900  }
901 
902  usb_endpoints[hw_ep].buffer = buffer;
903 
904  return res;
905 }
906 
907 
908 static uint8_t
909 ep0_get_setup_pkt(void)
910 {
911  // The USB controller check that the packet size is == 8
912  // First get a valid setup buffer
913  uint8_t res;
914  USBBuffer *buffer =
915  skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP,
916  USB_BUFFER_SETUP, &res);
917 
918  usb_endpoints[0].buffer = buffer;
919 
920  if(!buffer || buffer->left < 8) {
921  return USB_READ_BLOCK;
922  }
923 
924  read_hw_buffer(buffer->data, 0, 8);
925  buffer->left -= 8;
926 
927  buffer->flags &= ~USB_BUFFER_SUBMITTED;
928  if(buffer->flags & USB_BUFFER_NOTIFY) {
929  res |= USB_READ_NOTIFY;
930  }
931 
932  if(buffer->data[6] || buffer->data[7]) {
933  // DATA stage ...
934  USBCS0 |= USBCS0_CLR_OUTPKT_RDY;
935  ep0status = buffer->data[0] & 0x80 ? EP_TX : EP_RX;
936  } else {
937  // The usb-core will submit an empty data packet
938  // This will trigger the clr (see the buffer submission routine)
939 // USBCS0 |= USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
940  }
941 
942  buffer->data += 8;
943 
944  usb_endpoints[0].buffer = buffer->next;
945 
946  return res;
947 }
948 
949 static uint8_t
950 ep0_get_data_pkt(void)
951 {
952  uint8_t res = 0;
953  uint8_t short_packet = 0;
954  USBBuffer *buffer = usb_endpoints[0].buffer;
955  uint8_t len = USBCNT0;
956 
957  if(!buffer) {
958  return USB_READ_BLOCK;
959  }
960 
961  if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) {
962  uint8_t temp;
963 
964  buffer->flags |= USB_BUFFER_FAILED;
965  buffer->flags &= ~USB_BUFFER_SUBMITTED;
966  if(buffer->flags & USB_BUFFER_NOTIFY) {
967  res |= USB_READ_NOTIFY;
968  }
969  // Flush the fifo
970  while(len--) {
971  temp = USBF0;
972  }
973  usb_endpoints[0].buffer = buffer->next;
974  // Force an end to the data stage
975  USBCS0 |= USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
976 
977  ep0status = EP_IDLE;
978  return res;
979  }
980 
981  if(get_receive_capacity(buffer) < len) {
982  // Wait until we queue more buffers.
983  return USB_READ_BLOCK;
984  }
985 
986  if(len < usb_endpoints[0].xfer_size) {
987  short_packet = 1;
988  }
989 
990  res = fill_buffers(buffer, 0, len, short_packet);
991 
992  if(short_packet) {
993  /* The usb-core will send a status packet, we will release the fifo at this stage */
994  ep0status = EP_IDLE;
995  } else {
996  // More data to come
997  USBCS0 |= USBCS0_CLR_OUTPKT_RDY;
998  }
999  return res;
1000 }
1001 
1002 static uint8_t
1003 ep0_tx(void)
1004 {
1005  USBBuffer *buffer = usb_endpoints[0].buffer;
1006  unsigned int len = usb_endpoints[0].xfer_size;
1007  uint8_t data_end = 0;
1008  uint8_t res = 0;
1009 
1010  // If TX Fifo still busy or ep0 not in TX data stage don't do anything
1011  if((USBCS0 & USBCS0_INPKT_RDY) || (ep0status != EP_TX)) {
1012  return 0;
1013  }
1014 
1015  if(!buffer) {
1016  return 0;
1017  }
1018 
1019  if(!(buffer->flags & USB_BUFFER_IN)) {
1020  return 0; // Huh .. problem ... we should TX but queued buffer is in RX ...
1021  }
1022 
1023  while(buffer) {
1024  unsigned int copy;
1025 
1026  if(buffer->left < len) {
1027  copy = buffer->left;
1028  } else {
1029  copy = len;
1030  }
1031 
1032  len -= copy;
1033  buffer->left -= copy;
1034  write_hw_buffer(0, buffer->data, copy);
1035  buffer->data += copy;
1036  if(buffer->left == 0) {
1037  if(buffer->flags & USB_BUFFER_SHORT_END) {
1038  if(len == 0) {
1039  break; // We keep the buffer in queue so we will send a ZLP next time.
1040  } else {
1041  data_end = 1;
1042  len = 0; // Stop looking for more data to send
1043  }
1044  }
1045  buffer->flags &= ~USB_BUFFER_SUBMITTED;
1046  if(buffer->flags & USB_BUFFER_NOTIFY) {
1047  res |= USB_WRITE_NOTIFY;
1048  }
1049  buffer = buffer->next;
1050  }
1051  if(len == 0) {
1052  break; // FIFO is full, send packet.
1053  }
1054  }
1055  if(len) {
1056  // Short packet will be sent.
1057  data_end = 1;
1058  }
1059  usb_endpoints[0].buffer = buffer;
1060 
1061  // Workaround the fact that the usb controller do not like to have DATA_END set after INPKT_RDY
1062  // for the last packet. Thus if no more is in the queue set DATA_END.
1063  if(data_end || !buffer) {
1064  ep0status = EP_IDLE;
1065  USBCS0 |= USBCS0_INPKT_RDY | USBCS0_DATA_END;
1066  } else {
1067  USBCS0 |= USBCS0_INPKT_RDY;
1068  }
1069 
1070  return res;
1071 }
1072 
1073 static void
1074 usb_arch_ep0_irq(void)
1075 {
1076  uint8_t cs0;
1077  uint8_t res;
1078 
1079  USBINDEX = 0;
1080  cs0 = USBCS0;
1081  if(cs0 & USBCS0_SENT_STALL) {
1082  // Ack the stall
1083  USBCS0 = 0;
1084  ep0status = EP_IDLE;
1085  }
1086  if(cs0 & USBCS0_SETUP_END) {
1087  // Clear it
1088  USBCS0 = USBCS0_CLR_SETUP_END;
1089  ep0status = EP_IDLE;
1090  }
1091 
1092  if(cs0 & USBCS0_OUTPKT_RDY) {
1093  if(ep0status == EP_IDLE) {
1094  res = ep0_get_setup_pkt();
1095  } else {
1096  res = ep0_get_data_pkt();
1097  }
1098 
1099  if(res & USB_READ_NOTIFY) {
1100  notify_ep_process(&usb_endpoints[0], USB_EP_EVENT_NOTIFICATION);
1101  }
1102  if(res & USB_READ_BLOCK) {
1103  return;
1104  }
1105  }
1106  // Trigger the TX path
1107  res = ep0_tx();
1108 
1109  if(res & USB_WRITE_NOTIFY) {
1110  notify_ep_process(&usb_endpoints[0], USB_EP_EVENT_NOTIFICATION);
1111  }
1112 }
1113 
1114 
1115 static uint8_t
1116 ep_tx(uint8_t ep_hw)
1117 {
1118  unsigned int len;
1119  uint8_t res = 0;
1120  USBEndpoint *ep = EP_STRUCT(ep_hw);
1121 
1122  len = ep->xfer_size;
1123 
1124  if(ep->halted) {
1125  return 0;
1126  }
1127 
1128  if(!ep->buffer || !(ep->buffer->flags & USB_BUFFER_IN)) {
1129  return 0;
1130  }
1131 
1132  while(ep->buffer) {
1133  unsigned int copy;
1134 
1135  if(ep->buffer->left < len) {
1136  copy = ep->buffer->left;
1137  } else {
1138  copy = len;
1139  }
1140 
1141  len -= copy;
1142  ep->buffer->left -= copy;
1143  write_hw_buffer(EP_INDEX(ep_hw), ep->buffer->data, copy);
1144  ep->buffer->data += copy;
1145 
1146  if(ep->buffer->left == 0) {
1147  if(ep->buffer->flags & USB_BUFFER_SHORT_END) {
1148  if(len == 0) {
1149  break; // We keep the buffer in queue so we will send a ZLP next time.
1150  } else {
1151  len = 0; // Stop looking for more data to send
1152  }
1153  }
1154  ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
1155  if(ep->buffer->flags & USB_BUFFER_NOTIFY) {
1156  res |= USB_WRITE_NOTIFY;
1157  }
1158  ep->buffer = ep->buffer->next;
1159  }
1160  if(len == 0)
1161  break; // FIFO is full, send packet.
1162  }
1163 
1164  USBCSIL |= USBCSIL_INPKT_RDY;
1165 
1166  return res;
1167 
1168 }
1169 
1170 static uint8_t
1171 ep_get_data_pkt(uint8_t ep_hw)
1172 {
1173  uint16_t pkt_len;
1174  uint8_t res;
1175  uint8_t short_packet = 0;
1176  USBEndpoint *ep = EP_STRUCT(ep_hw);
1177 
1178  if(!ep->buffer) {
1179  return USB_READ_BLOCK;
1180  }
1181 
1182  if(ep->buffer->flags & USB_BUFFER_HALT) {
1183  ep->halted = 1;
1184  if(!(USBCSOL & USBCSOL_SEND_STALL)) {
1185  USBCSOL |= USBCSOL_SEND_STALL;
1186  }
1187  return 0;
1188  }
1189 
1190  pkt_len = USBCNTL | (USBCNTH << 8);
1191  if(get_receive_capacity(ep->buffer) < pkt_len) {
1192  return USB_READ_BLOCK;
1193  }
1194 
1195  if(pkt_len < ep->xfer_size) {
1196  short_packet = 1;
1197  }
1198 
1199  res = fill_buffers(ep->buffer, ep_hw, pkt_len, short_packet);
1200 
1201  USBCSOL &= ~USBCSOL_OUTPKT_RDY;
1202 
1203  return res;
1204 }
1205 
1206 static void
1207 usb_arch_epout_irq(uint8_t ep_hw)
1208 {
1209  // RX interrupt
1210  uint8_t csl;
1211  uint8_t res;
1212  USBEndpoint *ep = EP_STRUCT(ep_hw);
1213 
1214 
1215  USBINDEX = ep_hw;
1216  csl = USBCSOL;
1217 
1218  if(csl & USBCSOL_SENT_STALL) {
1219  USBCSOL &= ~USBCSOL_SENT_STALL;
1220  }
1221 
1222  if(csl & USBCSOL_OVERRUN) {
1223  // We lost one isochronous packet ...
1224  USBCSOL &= ~USBCSOL_OVERRUN;
1225  }
1226 
1227  if(csl & USBCSOL_OUTPKT_RDY) {
1228  res = ep_get_data_pkt(ep_hw);
1229 
1230  if(res & USB_READ_NOTIFY) {
1231  notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
1232  }
1233  }
1234 }
1235 
1236 static void
1237 usb_arch_epin_irq(uint8_t ep_hw)
1238 {
1239  uint8_t csl;
1240  uint8_t res;
1241  USBEndpoint *ep = EP_STRUCT(ep_hw);
1242 
1243  // TX interrupt
1244 
1245  USBINDEX = ep_hw;
1246  csl = USBCSIL;
1247 
1248  if(csl & USBCSIL_SENT_STALL) {
1249  USBCSIL &= ~USBCSIL_SENT_STALL;
1250  }
1251 
1252  if(csl & USBCSIL_UNDERRUN) {
1253  USBCSIL &= ~USBCSIL_UNDERRUN;
1254  }
1255 
1256  if(!(csl & USBCSIL_INPKT_RDY)) {
1257  res = ep_tx(ep_hw);
1258  if(res & USB_WRITE_NOTIFY) {
1259  notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
1260  }
1261  }
1262 }
1263 
1264 #define EPxIF(x) (1 << x)
1265 #define RSTIF (1 << 2)
1266 #define RESUMEIF (1 << 1)
1267 #define SUSPENDIF (1 << 0)
1268 
1269 uint8_t
1270 usb_irq(void)
1271 {
1272  uint8_t ep_in_if = USBIIF & USBIIE;
1273  uint8_t ep_out_if = USBOIF & USBOIE;
1274  uint8_t common_if = USBCIF & USBCIE;
1275  uint8_t i;
1276 
1277  if(ep_in_if) {
1278  /* EP0 is routed on IN irq flags */
1279  if(ep_in_if & 0x1) {
1280  usb_arch_ep0_irq();
1281  }
1282  for(i = 1; i < 6; i++) {
1283  if(ep_in_if & EPxIF(i)) {
1284  usb_arch_epin_irq(i);
1285  }
1286  }
1287  }
1288  if(ep_out_if) {
1289  for(i = 1; i < 6; i++) {
1290  if(ep_out_if & EPxIF(i)) {
1291  usb_arch_epout_irq(i);
1292  }
1293  }
1294  }
1295  if(common_if & RSTIF) {
1296  usb_arch_reset();
1297  notify_process(USB_EVENT_RESET);
1298  }
1299  if(common_if & RESUMEIF) {
1300  notify_process(USB_EVENT_RESUME);
1301  }
1302  if(common_if & SUSPENDIF) {
1303  notify_process(USB_EVENT_SUSPEND);
1304  }
1305 
1306  return ep_in_if || ep_out_if || common_if ? CC253x_P2_ACK : CC253x_P2_NACK;
1307 }
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
#define NULL
The null pointer.
Definitions for TI/Chipcon cc2530, cc2531 and cc2533 SFR registers.
Header file with definitions of bit masks for some cc2530 SFRs