1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Tomasz Malesinski
11 * Copyright (C) 2008 by Maurus Cuelenaere
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
22 #include "usb-target.h"
39 unsigned char *out_buf
;
42 void (*out_done
)(int, unsigned char *, int);
43 unsigned char out_in_progress
;
45 unsigned char *in_buf
;
49 void (*in_done
)(int, unsigned char *, int);
52 unsigned char halt
[2];
53 unsigned char enabled
[2];
54 short max_pkt_size
[2];
58 static unsigned char setup_pkt_buf
[8];
59 static struct usb_endpoint endpoints
[NUM_ENDPOINTS
];
61 static bool high_speed_mode
= false;
63 static inline void or_int_value(volatile unsigned short *a
, volatile unsigned short *b
, unsigned long r
, unsigned long value
)
65 set_int_value(*a
, *b
, (r
| value
));
67 static inline void bc_int_value(volatile unsigned short *a
, volatile unsigned short *b
, unsigned long r
, unsigned long value
)
69 set_int_value(*a
, *b
, (r
& ~value
));
72 static inline void nop_f(void)
77 #define NOP asm volatile("nop\n");
79 static inline int ep_index(int n
, bool dir
)
81 return (n
<< 1) | dir
;
84 static inline bool epidx_dir(int idx
)
89 static inline int epidx_n(int idx
)
94 static inline void usb_select_endpoint(int idx
)
96 /* Select the endpoint */
97 ISP1583_DFLOW_EPINDEX
= idx
;
98 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
99 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
104 static inline void usb_select_setup_endpoint(void)
106 /* Select the endpoint */
107 ISP1583_DFLOW_EPINDEX
= DFLOW_EPINDEX_EP0SETUP
;
108 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
109 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
114 static void usb_setup_endpoint(int idx
, int max_pkt_size
, int type
)
118 usb_select_endpoint(idx
);
119 ISP1583_DFLOW_MAXPKSZ
= max_pkt_size
& 0x7FF;
120 ISP1583_DFLOW_EPTYPE
= (DFLOW_EPTYPE_NOEMPKT
| DFLOW_EPTYPE_DBLBUF
| (type
& 0x3));
122 /* clear buffer ... */
123 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
124 /* ... twice because of double buffering */
125 usb_select_endpoint(idx
);
126 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
129 struct usb_endpoint
*ep
;
130 ep
= &(endpoints
[epidx_n(idx
)]);
131 ep
->halt
[epidx_dir(idx
)] = 0;
132 ep
->enabled
[epidx_dir(idx
)] = 0;
133 ep
->out_in_progress
= 0;
137 ep
->max_pkt_size
[epidx_dir(idx
)] = max_pkt_size
;
140 static void usb_enable_endpoint(int idx
)
144 usb_select_endpoint(idx
);
145 /* Enable interrupt */
146 or_int_value(&ISP1583_INIT_INTEN_A
, &ISP1583_INIT_INTEN_B
, ISP1583_INIT_INTEN_READ
, 1 << (10 + idx
));
147 /* Enable endpoint */
148 ISP1583_DFLOW_EPTYPE
|= DFLOW_EPTYPE_ENABLE
;
151 endpoints
[epidx_n(idx
)].enabled
[epidx_dir(idx
)] = 1;
154 static void usb_disable_endpoint(int idx, bool set_struct)
156 usb_select_endpoint(idx);
157 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
158 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
161 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
164 static int usb_get_packet(unsigned char *buf
, int max_len
)
167 len
= ISP1583_DFLOW_BUFLEN
;
169 if (max_len
< 0 || max_len
> len
)
175 unsigned short d
= ISP1583_DFLOW_DATA
;
180 buf
[i
] = (d
>> 8) & 0xff;
186 static int usb_receive(int n
)
188 logf("usb_receive(%d)", n
);
191 if (endpoints
[n
].halt
[DIR_RX
]
192 || !endpoints
[n
].enabled
[DIR_RX
]
193 || endpoints
[n
].in_min_len
< 0
194 || !endpoints
[n
].in_ack
)
197 endpoints
[n
].in_ack
= 0;
199 usb_select_endpoint(ep_index(n
, DIR_RX
));
201 len
= usb_get_packet(endpoints
[n
].in_buf
+ endpoints
[n
].in_ptr
,
202 endpoints
[n
].in_max_len
- endpoints
[n
].in_ptr
);
203 endpoints
[n
].in_ptr
+= len
;
204 if (endpoints
[n
].in_ptr
>= endpoints
[n
].in_min_len
) {
205 endpoints
[n
].in_min_len
= -1;
206 if (endpoints
[n
].in_done
)
207 (*(endpoints
[n
].in_done
))(n
, endpoints
[n
].in_buf
,
208 endpoints
[n
].in_ptr
);
214 static bool usb_out_buffer_full(int ep
)
216 usb_select_endpoint(ep_index(ep
, DIR_TX
));
217 if (ISP1583_DFLOW_EPTYPE
& 4) /* Check if type=bulk and double buffering is set */
218 return (ISP1583_DFLOW_BUFSTAT
& 3) == 3; /* Return true if both buffers are filled */
220 return (ISP1583_DFLOW_BUFSTAT
& 3) != 0; /* Return true if one of the buffers are filled */
223 static int usb_send(int n
)
225 logf("usb_send(%d)", n
);
226 int max_pkt_size
, len
;
230 if (endpoints
[n
].halt
[DIR_TX
]
231 || !endpoints
[n
].enabled
[DIR_TX
]
232 || !endpoints
[n
].out_in_progress
)
234 logf("NOT SEND TO EP!");
238 if (endpoints
[n
].out_ptr
< 0)
240 endpoints
[n
].out_in_progress
= 0;
241 if (endpoints
[n
].out_done
)
242 (*(endpoints
[n
].out_done
))(n
, endpoints
[n
].out_buf
,
243 endpoints
[n
].out_len
);
244 logf("ALREADY SENT TO EP!");
248 if (usb_out_buffer_full(n
))
250 logf("BUFFER FULL!");
254 usb_select_endpoint(ep_index(n
, DIR_TX
));
255 max_pkt_size
= endpoints
[n
].max_pkt_size
[DIR_TX
];
256 len
= endpoints
[n
].out_len
- endpoints
[n
].out_ptr
;
257 if (len
> max_pkt_size
)
260 if(len
< max_pkt_size
)
261 ISP1583_DFLOW_BUFLEN
= len
;
263 p
= endpoints
[n
].out_buf
+ endpoints
[n
].out_ptr
;
265 while (len
- i
>= 2) {
266 ISP1583_DFLOW_DATA
= p
[i
] | (p
[i
+ 1] << 8);
270 ISP1583_DFLOW_DATA
= p
[i
];
272 endpoints
[n
].out_ptr
+= len
;
275 if (endpoints[n].out_ptr == endpoints[n].out_len
276 && len < max_pkt_size)
278 if (endpoints
[n
].out_ptr
== endpoints
[n
].out_len
)
279 endpoints
[n
].out_ptr
= -1;
285 static void usb_stall_endpoint(int idx
)
287 usb_select_endpoint(idx
);
288 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STALL
;
289 endpoints
[epidx_n(idx
)].halt
[epidx_dir(idx
)] = 1;
292 static void usb_unstall_endpoint(int idx
)
294 usb_select_endpoint(idx
);
295 ISP1583_DFLOW_CTRLFUN
&= ~DFLOW_CTRLFUN_STALL
;
296 ISP1583_DFLOW_EPTYPE
&= ~DFLOW_EPTYPE_ENABLE
;
297 ISP1583_DFLOW_EPTYPE
|= DFLOW_EPTYPE_ENABLE
;
298 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
299 if (epidx_dir(idx
) == DIR_TX
)
300 endpoints
[epidx_n(idx
)].out_in_progress
= 0;
303 endpoints
[epidx_n(idx
)].in_min_len
= -1;
304 endpoints
[epidx_n(idx
)].in_ack
= 0;
306 endpoints
[epidx_n(idx
)].halt
[epidx_dir(idx
)] = 0;
309 static void usb_status_ack(int ep
, int dir
)
311 logf("usb_status_ack(%d)", dir
);
312 usb_select_endpoint(ep_index(ep
, dir
));
313 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STATUS
;
316 static void usb_data_stage_enable(int ep
, int dir
)
318 logf("usb_data_stage_enable(%d)", dir
);
319 usb_select_endpoint(ep_index(ep
, dir
));
320 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_DSEN
;
323 static void usb_handle_setup_rx(void)
326 usb_select_setup_endpoint();
327 len
= usb_get_packet(setup_pkt_buf
, 8);
330 usb_core_control_request((struct usb_ctrlrequest
*)setup_pkt_buf
);
333 usb_drv_stall(0, true, false);
334 usb_drv_stall(0, true, true);
335 logf("usb_handle_setup_rx() failed");
339 logf("usb_handle_setup_rx(): %02x %02x %02x %02x %02x %02x %02x %02x", setup_pkt_buf
[0], setup_pkt_buf
[1], setup_pkt_buf
[2], setup_pkt_buf
[3], setup_pkt_buf
[4], setup_pkt_buf
[5], setup_pkt_buf
[6], setup_pkt_buf
[7]);
342 static void usb_handle_data_int(int ep
, int dir
)
349 len
= usb_receive(ep
);
350 endpoints
[ep
].in_ack
= 1;
352 logf("usb_handle_data_int(%d, %d) finished", ep
, dir
);
355 bool usb_drv_powered(void)
358 return (ISP1583_INIT_OTG
& INIT_OTG_BSESS_VALID
) ? true : false;
360 return (ISP1583_INIT_MODE
& INIT_MODE_VBUSSTAT
) ? true : false;
364 static void setup_endpoints(void)
366 usb_setup_endpoint(ep_index(0, DIR_RX
), 64, 0);
367 usb_setup_endpoint(ep_index(0, DIR_TX
), 64, 0);
370 for(i
= 1; i
< NUM_ENDPOINTS
-1; i
++)
372 usb_setup_endpoint(ep_index(i
, DIR_RX
), (high_speed_mode
? 512 : 64), 2); /* 2 = TYPE_BULK */
373 usb_setup_endpoint(ep_index(i
, DIR_TX
), (high_speed_mode
? 512 : 64), 2);
376 usb_enable_endpoint(ep_index(0, DIR_RX
));
377 usb_enable_endpoint(ep_index(0, DIR_TX
));
379 for (i
= 1; i
< NUM_ENDPOINTS
-1; i
++)
381 usb_enable_endpoint(ep_index(i
, DIR_RX
));
382 usb_enable_endpoint(ep_index(i
, DIR_TX
));
388 void usb_helper(void)
390 if(ISP1583_GEN_INT_READ
& ISP1583_INIT_INTEN_READ
)
393 logf("Helper detected interrupt... [%d]", current_tick
);
400 void usb_drv_init(void)
402 /* Disable interrupt at CPU level */
405 /* Unlock the device's registers */
406 ISP1583_GEN_UNLCKDEV
= ISP1583_UNLOCK_CODE
;
408 /* Soft reset the device */
409 ISP1583_INIT_MODE
= INIT_MODE_SFRESET
;
411 /* Enable CLKAON & GLINTENA */
412 ISP1583_INIT_MODE
= STANDARD_INIT_MODE
;
414 /* Disable all OTG functions */
415 ISP1583_INIT_OTG
= 0;
418 #ifdef USE_HIGH_SPEED
419 /* Force device to high speed */
420 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_FORCEHS
;
421 high_speed_mode
= true;
426 logf("BUS_CONF/DA0:%d MODE0/DA1: %d MODE1: %d", (bool)(ISP1583_INIT_MODE
& INIT_MODE_TEST0
), (bool)(ISP1583_INIT_MODE
& INIT_MODE_TEST1
), (bool)(ISP1583_INIT_MODE
& INIT_MODE_TEST2
));
427 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID
);
428 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
431 /*Set interrupt generation to target-specific mode +
432 * Set the control pipe to ACK only interrupt +
433 * Set the IN pipe to ACK only interrupt +
434 * Set OUT pipe to ACK and NYET interrupt
437 ISP1583_INIT_INTCONF
= 0x54 | INT_CONF_TARGET
;
438 /* Clear all interrupts */
439 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, 0xFFFFFFFF);
440 /* Enable USB interrupts */
441 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, STANDARD_INTEN
);
445 /* Enable interrupt at CPU level */
450 /* Clear device address and disable it */
451 ISP1583_INIT_ADDRESS
= 0;
453 /* Turn SoftConnect on */
454 ISP1583_INIT_MODE
|= INIT_MODE_SOFTCT
;
458 tick_add_task(usb_helper
);
460 logf("usb_init_device() finished");
463 int usb_drv_port_speed(void)
465 return (int)high_speed_mode
;
468 void usb_drv_exit(void)
470 logf("usb_drv_exit()");
473 ISP1583_INIT_MODE
&= ~INIT_MODE_SOFTCT
;
474 ISP1583_INIT_ADDRESS
= 0;
476 /* Disable interrupts */
477 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, 0);
478 /* and the CPU's one... */
482 /* Send usb controller to suspend mode */
483 ISP1583_INIT_MODE
= INIT_MODE_GOSUSP
;
484 ISP1583_INIT_MODE
= 0;
486 tick_remove_task(usb_helper
);
491 void usb_drv_stall(int endpoint
, bool stall
, bool in
)
493 logf("%sstall EP%d %s", (stall
? "" : "un"), endpoint
, (in
? "RX" : "TX" ));
495 usb_stall_endpoint(ep_index(endpoint
, (int)in
));
497 usb_unstall_endpoint(ep_index(endpoint
, (int)in
));
500 bool usb_drv_stalled(int endpoint
, bool in
)
502 return (endpoints
[endpoint
].halt
[(int)in
] == 1);
505 static void out_callback(int ep
, unsigned char *buf
, int len
)
508 logf("out_callback(%d, 0x%x, %d)", ep
, &buf
, len
);
509 usb_status_ack(ep
, DIR_RX
);
510 usb_core_transfer_complete(ep
, true, 0, len
); /* 0=>status succeeded, haven't worked out status failed yet... */
513 static void in_callback(int ep
, unsigned char *buf
, int len
)
516 logf("in_callback(%d, 0x%x, %d)", ep
, &buf
, len
);
517 usb_status_ack(ep
, DIR_TX
);
518 usb_core_transfer_complete(ep
, false, 0, len
);
521 int usb_drv_recv(int ep
, void* ptr
, int length
)
523 logf("usb_drv_recv(%d, 0x%x, %d)", ep
, &ptr
, length
);
524 if(ep
== 0 && length
== 0 && ptr
== NULL
)
526 usb_status_ack(ep
, DIR_TX
);
529 endpoints
[ep
].in_done
= in_callback
;
530 endpoints
[ep
].in_buf
= ptr
;
531 endpoints
[ep
].in_max_len
= length
;
532 endpoints
[ep
].in_min_len
= length
;
533 endpoints
[ep
].in_ptr
= 0;
536 usb_data_stage_enable(ep
, DIR_RX
);
537 return usb_receive(ep
);
540 return usb_receive(ep
);
543 int usb_drv_send_nonblocking(int ep
, void* ptr
, int length
)
545 /* First implement DMA... */
546 return usb_drv_send(ep
, ptr
, length
);
549 int usb_drv_send(int ep
, void* ptr
, int length
)
551 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep
, &ptr
, length
);
552 if(ep
== 0 && length
== 0 && ptr
== NULL
)
554 usb_status_ack(ep
, DIR_RX
);
557 if(endpoints
[ep
].out_in_progress
== 1)
559 endpoints
[ep
].out_done
= out_callback
;
560 endpoints
[ep
].out_buf
= ptr
;
561 endpoints
[ep
].out_len
= length
;
562 endpoints
[ep
].out_ptr
= 0;
563 endpoints
[ep
].out_in_progress
= 1;
566 int rc
= usb_send(ep
);
567 usb_data_stage_enable(ep
, DIR_TX
);
568 usb_drv_wait(ep
, DIR_TX
);
575 void usb_drv_reset_endpoint(int ep
, bool send
)
577 logf("reset endpoint(%d, %d)", ep
, send
);
578 usb_setup_endpoint(ep_index(ep
, (int)send
), endpoints
[ep
].max_pkt_size
[(int)send
], endpoints
[ep
].type
);
579 usb_enable_endpoint(ep_index(ep
, (int)send
));
582 void usb_drv_wait(int ep
, bool send
)
584 logf("usb_drv_wait(%d, %d)", ep
, send
);
587 while (endpoints
[ep
].out_in_progress
)
592 while (endpoints
[ep
].in_ack
)
597 void usb_drv_cancel_all_transfers(void)
599 logf("usb_drv_cancel_all_tranfers()");
602 for(i
=0;i
<NUM_ENDPOINTS
-1;i
++)
603 endpoints
[i
].halt
[0] = endpoints
[i
].halt
[1] = 1;
606 static void bus_reset(void)
608 /* Enable CLKAON & GLINTENA */
609 ISP1583_INIT_MODE
= STANDARD_INIT_MODE
;
610 /* Enable USB interrupts */
611 ISP1583_INIT_INTCONF
= 0x54 | INT_CONF_TARGET
;
612 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, STANDARD_INTEN
);
614 /* Disable all OTG functions */
615 ISP1583_INIT_OTG
= 0;
617 /* Clear device address and enable it */
618 ISP1583_INIT_ADDRESS
= INIT_ADDRESS_DEVEN
;
622 /* Reset endpoints to default */
625 logf("bus reset->done");
628 /* Method for handling interrupts, must be called from usb-<target>.c */
629 void usb_drv_int(void)
632 ints
= ISP1583_GEN_INT_READ
& ISP1583_INIT_INTEN_READ
;
637 /* Unlock the device's registers */
638 ISP1583_GEN_UNLCKDEV
= ISP1583_UNLOCK_CODE
;
641 logf(" handling int [0x%x & 0x%x = 0x%x]", ISP1583_GEN_INT_READ
, ISP1583_INIT_INTEN_READ
, ints
);
644 if(ints
& INT_IEBRST
) /* Bus reset */
647 high_speed_mode
= false;
649 usb_core_bus_reset();
650 /* Mask bus reset interrupt */
651 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, INT_IEBRST
);
654 if(ints
& INT_IEP0SETUP
) /* EP0SETUP interrupt */
657 usb_handle_setup_rx();
659 if(ints
& INT_IEHS_STA
) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
662 high_speed_mode
= true;
665 if(ints
& INT_EP_MASK
) /* Endpoints interrupt */
667 unsigned long ep_event
;
668 unsigned short i
= 10;
669 ep_event
= ints
& INT_EP_MASK
;
675 if(ep_event
& (1 << i
))
677 logf("EP%d %s interrupt", (i
- 10) / 2, i
% 2 ? "RX" : "TX");
678 usb_handle_data_int((i
- 10) / 2, i
% 2);
679 ep_event
&= ~(1 << i
);
684 if(ints
& INT_IERESM
&& !(ints
& INT_IESUSP
)) /* Resume status: status change from suspend to resume (active) */
688 if(ints
& INT_IESUSP
&& !(ints
& INT_IERESM
)) /* Suspend status: status change from active to suspend */
692 if(ints
& INT_IEDMA
) /* change in the DMA Interrupt Reason register */
696 if(ints
& INT_IEVBUS
) /* transition from LOW to HIGH on VBUS */
700 /* Mask all (enabled) interrupts */
701 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, ints
);
706 void usb_drv_set_address(int address
)
708 logf("usb_drv_set_address(0x%x)", address
);
709 ISP1583_INIT_ADDRESS
= (address
& 0x7F) | INIT_ADDRESS_DEVEN
;
713 usb_status_ack(0, DIR_TX
);
716 int dbg_usb_num_items(void)
718 return 2+NUM_ENDPOINTS
*2;
721 char* dbg_usb_item(int selected_item
, void *data
, char *buffer
, size_t buffer_len
)
723 if(selected_item
< 2)
725 switch(selected_item
)
728 snprintf(buffer
, buffer_len
, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
731 snprintf(buffer
, buffer_len
, "HS mode: %s", (high_speed_mode
? "Yes" : "No"));
737 int n
= ep_index((selected_item
- 2) / 2, (selected_item
- 2) % 2);
738 if(endpoints
[n
].enabled
== false)
739 snprintf(buffer
, buffer_len
, "EP%d[%s]: DISABLED", epidx_n(n
), (epidx_dir(n
) ? "TX" : "RX"));
744 if(endpoints
[n
].out_in_progress
)
745 snprintf(buffer
, buffer_len
, "EP%d[TX]: TRANSFERRING DATA -> %d bytes/%d bytes", epidx_n(n
), (endpoints
[n
].out_len
- endpoints
[n
].out_ptr
), endpoints
[n
].out_len
);
747 snprintf(buffer
, buffer_len
, "EP%d[TX]: STANDBY", epidx_n(n
));
751 if(endpoints
[n
].in_buf
&& !endpoints
[n
].in_ack
)
752 snprintf(buffer
, buffer_len
, "EP%d[RX]: RECEIVING DATA -> %d bytes/%d bytes", epidx_n(n
), endpoints
[n
].in_ptr
, endpoints
[n
].in_max_len
);
754 snprintf(buffer
, buffer_len
, "EP%d[RX]: STANDBY", epidx_n(n
));
763 void usb_drv_set_test_mode(int mode
)
765 logf("usb_drv_set_test_mode(%d)", mode
);
768 ISP1583_GEN_TSTMOD
= 0;
772 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_JSTATE
;
775 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_KSTATE
;
778 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_SE0_NAK
;
781 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
784 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;