a bit of code cleanup.. use a single function to get the statusbar height (or lack...
[Rockbox.git] / firmware / drivers / isp1583.c
blob7e78f87468fe3854b9974cd66e3779b24c1fc69f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include "config.h"
22 #include "usb-target.h"
23 #include "usb_ch9.h"
24 #include "usb_drv.h"
25 #include "usb_core.h"
26 #include "isp1583.h"
27 #include "thread.h"
28 #include "logf.h"
29 #include <stdio.h>
31 #define DIR_RX 0
32 #define DIR_TX 1
34 #define DIR_OUT 0
35 #define DIR_IN 1
37 struct usb_endpoint
39 unsigned char *out_buf;
40 short out_len;
41 short out_ptr;
42 void (*out_done)(int, unsigned char *, int);
43 unsigned char out_in_progress;
45 unsigned char *in_buf;
46 short in_min_len;
47 short in_max_len;
48 short in_ptr;
49 void (*in_done)(int, unsigned char *, int);
50 unsigned char in_ack;
52 unsigned char halt[2];
53 unsigned char enabled[2];
54 short max_pkt_size[2];
55 short type;
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)
74 yield();
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)
86 return idx & 1;
89 static inline int epidx_n(int idx)
91 return idx >> 1;
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.
101 NOP;
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.
111 NOP;
114 static void usb_setup_endpoint(int idx, int max_pkt_size, int type)
116 if(epidx_n(idx)!=0)
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;
134 ep->in_min_len = -1;
135 ep->in_ack = 0;
136 ep->type = type;
137 ep->max_pkt_size[epidx_dir(idx)] = max_pkt_size;
140 static void usb_enable_endpoint(int idx)
142 if(epidx_n(idx)!=0)
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));
160 if(set_struct)
161 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
164 static int usb_get_packet(unsigned char *buf, int max_len)
166 int len, i;
167 len = ISP1583_DFLOW_BUFLEN;
169 if (max_len < 0 || max_len > len)
170 max_len = len;
172 i = 0;
173 while (i < len)
175 unsigned short d = ISP1583_DFLOW_DATA;
176 if (i < max_len)
177 buf[i] = d & 0xff;
178 i++;
179 if (i < max_len)
180 buf[i] = (d >> 8) & 0xff;
181 i++;
183 return max_len;
186 static int usb_receive(int n)
188 logf("usb_receive(%d)", n);
189 int len;
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)
195 return -1;
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);
210 logf("receive_end");
211 return 0;
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 */
219 else
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;
227 int i;
228 unsigned char *p;
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!");
235 return -1;
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!");
245 return -1;
248 if (usb_out_buffer_full(n))
250 logf("BUFFER FULL!");
251 return -1;
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)
258 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;
264 i = 0;
265 while (len - i >= 2) {
266 ISP1583_DFLOW_DATA = p[i] | (p[i + 1] << 8);
267 i += 2;
269 if (i < len)
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;
281 logf("send_end");
282 return 0;
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;
301 else
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)
325 int len;
326 usb_select_setup_endpoint();
327 len = usb_get_packet(setup_pkt_buf, 8);
329 if (len == 8)
330 usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf);
331 else
333 usb_drv_stall(0, true, false);
334 usb_drv_stall(0, true, true);
335 logf("usb_handle_setup_rx() failed");
336 return;
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)
344 int len;
345 if (dir == DIR_TX)
346 len = usb_send(ep);
347 else
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)
357 #if 0
358 return (ISP1583_INIT_OTG & INIT_OTG_BSESS_VALID) ? true : false;
359 #else
360 return (ISP1583_INIT_MODE & INIT_MODE_VBUSSTAT) ? true : false;
361 #endif
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);
369 int i;
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));
385 ZVM_SPECIFIC;
388 void usb_helper(void)
390 if(ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ)
392 #ifdef DEBUG
393 logf("Helper detected interrupt... [%d]", current_tick);
394 #endif
395 usb_drv_int();
397 return;
400 void usb_drv_init(void)
402 /* Disable interrupt at CPU level */
403 DIS_INT_CPU_TARGET;
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;
410 sleep(10);
411 /* Enable CLKAON & GLINTENA */
412 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
414 /* Disable all OTG functions */
415 ISP1583_INIT_OTG = 0;
417 #if 0
418 #ifdef USE_HIGH_SPEED
419 /* Force device to high speed */
420 ISP1583_GEN_TSTMOD = GEN_TSTMOD_FORCEHS;
421 high_speed_mode = true;
422 #endif
423 #endif
425 #ifdef DEBUG
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);
429 #endif
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);
443 ZVM_SPECIFIC;
445 /* Enable interrupt at CPU level */
446 EN_INT_CPU_TARGET;
448 setup_endpoints();
450 /* Clear device address and disable it */
451 ISP1583_INIT_ADDRESS = 0;
453 /* Turn SoftConnect on */
454 ISP1583_INIT_MODE |= INIT_MODE_SOFTCT;
456 ZVM_SPECIFIC;
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()");
472 /* Disable device */
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... */
479 DIS_INT_CPU_TARGET;
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);
488 ZVM_SPECIFIC;
491 void usb_drv_stall(int endpoint, bool stall, bool in)
493 logf("%sstall EP%d %s", (stall ? "" : "un"), endpoint, (in ? "RX" : "TX" ));
494 if (stall)
495 usb_stall_endpoint(ep_index(endpoint, (int)in));
496 else
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)
507 (void)buf;
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)
515 (void)buf;
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);
527 return 0;
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;
534 if(ep == 0)
536 usb_data_stage_enable(ep, DIR_RX);
537 return usb_receive(ep);
539 else
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);
555 return 0;
557 if(endpoints[ep].out_in_progress == 1)
558 return -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;
564 if(ep == 0)
566 int rc = usb_send(ep);
567 usb_data_stage_enable(ep, DIR_TX);
568 usb_drv_wait(ep, DIR_TX);
569 return rc;
571 else
572 return usb_send(ep);
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);
585 if(send)
587 while (endpoints[ep].out_in_progress)
588 nop_f();
590 else
592 while (endpoints[ep].in_ack)
593 nop_f();
597 void usb_drv_cancel_all_transfers(void)
599 logf("usb_drv_cancel_all_tranfers()");
600 int i;
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;
620 ZVM_SPECIFIC;
622 /* Reset endpoints to default */
623 setup_endpoints();
625 logf("bus reset->done");
628 /* Method for handling interrupts, must be called from usb-<target>.c */
629 void usb_drv_int(void)
631 unsigned long ints;
632 ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ;
634 if(!ints)
635 return;
637 /* Unlock the device's registers */
638 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
640 #if 0
641 logf(" handling int [0x%x & 0x%x = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, ints);
642 #endif
644 if(ints & INT_IEBRST) /* Bus reset */
646 logf("BRESET");
647 high_speed_mode = false;
648 bus_reset();
649 usb_core_bus_reset();
650 /* Mask bus reset interrupt */
651 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, INT_IEBRST);
652 return;
654 if(ints & INT_IEP0SETUP) /* EP0SETUP interrupt */
656 logf("EP0SETUP");
657 usb_handle_setup_rx();
659 if(ints & INT_IEHS_STA) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
661 logf("HS_STA");
662 high_speed_mode = true;
663 setup_endpoints();
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;
670 while(ep_event)
672 if(i>25)
673 break;
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);
681 i++;
684 if(ints & INT_IERESM && !(ints & INT_IESUSP)) /* Resume status: status change from suspend to resume (active) */
686 logf("RESM");
688 if(ints & INT_IESUSP && !(ints & INT_IERESM)) /* Suspend status: status change from active to suspend */
690 logf("SUSP");
692 if(ints & INT_IEDMA) /* change in the DMA Interrupt Reason register */
694 logf("DMA");
696 if(ints & INT_IEVBUS) /* transition from LOW to HIGH on VBUS */
698 logf("VBUS");
700 /* Mask all (enabled) interrupts */
701 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints);
703 ZVM_SPECIFIC;
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;
711 ZVM_SPECIFIC;
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)
727 case 0:
728 snprintf(buffer, buffer_len, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
729 return buffer;
730 case 1:
731 snprintf(buffer, buffer_len, "HS mode: %s", (high_speed_mode ? "Yes" : "No"));
732 return buffer;
735 else
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"));
740 else
742 if(epidx_dir(n))
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);
746 else
747 snprintf(buffer, buffer_len, "EP%d[TX]: STANDBY", epidx_n(n));
749 else
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);
753 else
754 snprintf(buffer, buffer_len, "EP%d[RX]: STANDBY", epidx_n(n));
757 return buffer;
759 return NULL;
760 (void)data;
763 void usb_drv_set_test_mode(int mode)
765 logf("usb_drv_set_test_mode(%d)", mode);
766 switch(mode){
767 case 0:
768 ISP1583_GEN_TSTMOD = 0;
769 /* Power cycle... */
770 break;
771 case 1:
772 ISP1583_GEN_TSTMOD = GEN_TSTMOD_JSTATE;
773 break;
774 case 2:
775 ISP1583_GEN_TSTMOD = GEN_TSTMOD_KSTATE;
776 break;
777 case 3:
778 ISP1583_GEN_TSTMOD = GEN_TSTMOD_SE0_NAK;
779 break;
780 case 4:
781 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
782 break;
783 case 5:
784 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
785 break;