Make the reference to the 'Default codepage' setting introduced in r18581 actually...
[kugel-rb.git] / firmware / drivers / isp1583.c
blobf37374158620a6b8630dab4f91720c4bad87e9c1
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 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
23 #include "config.h"
24 #include "usb_ch9.h"
25 #include "usb_drv.h"
26 #include "usb_core.h"
27 #include "isp1583.h"
28 #include "thread.h"
29 #include "logf.h"
30 #include "stdio.h"
32 #define DIR_RX 0
33 #define DIR_TX 1
35 struct usb_endpoint
37 unsigned char *out_buf;
38 short out_len;
39 short out_ptr;
40 void (*out_done)(int, unsigned char *, int);
41 unsigned char out_in_progress;
43 unsigned char *in_buf;
44 short in_min_len;
45 short in_max_len;
46 short in_ptr;
47 void (*in_done)(int, unsigned char *, int);
48 unsigned char in_ack;
50 unsigned char halt[2];
51 unsigned char enabled[2];
52 short max_pkt_size[2];
53 short type;
54 char allocation;
57 static unsigned char setup_pkt_buf[8];
58 static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS];
60 static bool high_speed_mode = false;
62 static inline void or_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
64 set_int_value(*a, *b, (r | value));
66 static inline void bc_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
68 set_int_value(*a, *b, (r & ~value));
71 static inline void nop_f(void)
73 yield();
76 #define NOP asm volatile("nop\n");
78 static inline int ep_index(int n, bool dir)
80 return (n << 1) | dir;
83 static inline bool epidx_dir(int idx)
85 return idx & 1;
88 static inline int epidx_n(int idx)
90 return idx >> 1;
93 static inline void usb_select_endpoint(int idx)
95 /* Select the endpoint */
96 ISP1583_DFLOW_EPINDEX = idx;
97 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
98 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
100 NOP;
103 static inline void usb_select_setup_endpoint(void)
105 /* Select the endpoint */
106 ISP1583_DFLOW_EPINDEX = DFLOW_EPINDEX_EP0SETUP;
107 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
108 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
110 NOP;
113 static void usb_setup_endpoint(int idx, int max_pkt_size, int type)
115 if(epidx_n(idx)!=0)
117 usb_select_endpoint(idx);
118 ISP1583_DFLOW_MAXPKSZ = max_pkt_size & 0x7FF;
119 ISP1583_DFLOW_EPTYPE = (DFLOW_EPTYPE_NOEMPKT | DFLOW_EPTYPE_DBLBUF | (type & 0x3));
121 /* clear buffer ... */
122 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
123 /* ... twice because of double buffering */
124 usb_select_endpoint(idx);
125 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
128 struct usb_endpoint *ep;
129 ep = &(endpoints[epidx_n(idx)]);
130 ep->halt[epidx_dir(idx)] = 0;
131 ep->enabled[epidx_dir(idx)] = 0;
132 ep->out_in_progress = 0;
133 ep->in_min_len = -1;
134 ep->in_ack = 0;
135 ep->type = type;
136 ep->max_pkt_size[epidx_dir(idx)] = max_pkt_size;
139 static void usb_enable_endpoint(int idx)
141 if(epidx_n(idx)!=0)
143 usb_select_endpoint(idx);
144 /* Enable interrupt */
145 or_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
146 /* Enable endpoint */
147 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
150 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 1;
153 static void usb_disable_endpoint(int idx, bool set_struct)
155 usb_select_endpoint(idx);
156 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
157 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
159 if(set_struct)
160 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
163 static int usb_get_packet(unsigned char *buf, int max_len)
165 int len, i;
166 len = ISP1583_DFLOW_BUFLEN;
168 if (max_len < 0 || max_len > len)
169 max_len = len;
171 i = 0;
172 while (i < len)
174 unsigned short d = ISP1583_DFLOW_DATA;
175 if (i < max_len)
176 buf[i] = d & 0xff;
177 i++;
178 if (i < max_len)
179 buf[i] = (d >> 8) & 0xff;
180 i++;
182 return max_len;
185 static int usb_receive(int n)
187 logf("usb_receive(%d)", n);
188 int len;
190 if (endpoints[n].halt[DIR_RX]
191 || !endpoints[n].enabled[DIR_RX]
192 || endpoints[n].in_min_len < 0
193 || !endpoints[n].in_ack)
194 return -1;
196 endpoints[n].in_ack = 0;
198 usb_select_endpoint(ep_index(n, DIR_RX));
200 len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr,
201 endpoints[n].in_max_len - endpoints[n].in_ptr);
202 endpoints[n].in_ptr += len;
204 if (endpoints[n].in_ptr >= endpoints[n].in_min_len)
206 endpoints[n].in_min_len = -1;
207 if (endpoints[n].in_done)
208 (*(endpoints[n].in_done))(n, endpoints[n].in_buf,
209 endpoints[n].in_ptr);
211 logf("receive_end");
212 return 0;
215 static bool usb_out_buffer_full(int ep)
217 usb_select_endpoint(ep_index(ep, DIR_TX));
218 if (ISP1583_DFLOW_EPTYPE & 4) /* Check if type=bulk and double buffering is set */
219 return (ISP1583_DFLOW_BUFSTAT & 3) == 3; /* Return true if both buffers are filled */
220 else
221 return (ISP1583_DFLOW_BUFSTAT & 3) != 0; /* Return true if one of the buffers are filled */
224 static int usb_send(int n)
226 logf("usb_send(%d)", n);
227 int max_pkt_size, len;
228 int i;
229 unsigned char *p;
231 if (endpoints[n].halt[DIR_TX]
232 || !endpoints[n].enabled[DIR_TX]
233 || !endpoints[n].out_in_progress)
235 logf("NOT SEND TO EP!");
236 return -1;
239 if (endpoints[n].out_ptr < 0)
241 endpoints[n].out_in_progress = 0;
242 if (endpoints[n].out_done)
243 (*(endpoints[n].out_done))(n, endpoints[n].out_buf,
244 endpoints[n].out_len);
245 logf("ALREADY SENT TO EP!");
246 return -1;
249 if (usb_out_buffer_full(n))
251 logf("BUFFER FULL!");
252 return -1;
255 usb_select_endpoint(ep_index(n, DIR_TX));
256 max_pkt_size = endpoints[n].max_pkt_size[DIR_TX];
257 len = endpoints[n].out_len - endpoints[n].out_ptr;
258 if (len > max_pkt_size)
259 len = max_pkt_size;
261 if(len < max_pkt_size)
262 ISP1583_DFLOW_BUFLEN = len;
264 p = endpoints[n].out_buf + endpoints[n].out_ptr;
265 i = 0;
266 while (len - i >= 2)
268 ISP1583_DFLOW_DATA = p[i] | (p[i + 1] << 8);
269 i += 2;
271 if (i < len)
272 ISP1583_DFLOW_DATA = p[i];
274 endpoints[n].out_ptr += len;
277 if (endpoints[n].out_ptr == endpoints[n].out_len
278 && len < max_pkt_size)
280 if (endpoints[n].out_ptr == endpoints[n].out_len)
281 endpoints[n].out_ptr = -1;
283 logf("send_end");
284 return 0;
287 static void usb_stall_endpoint(int idx)
289 usb_select_endpoint(idx);
290 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STALL;
291 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 1;
294 static void usb_unstall_endpoint(int idx)
296 usb_select_endpoint(idx);
297 ISP1583_DFLOW_CTRLFUN &= ~DFLOW_CTRLFUN_STALL;
298 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
299 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
300 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
301 if (epidx_dir(idx) == DIR_TX)
302 endpoints[epidx_n(idx)].out_in_progress = 0;
303 else
305 endpoints[epidx_n(idx)].in_min_len = -1;
306 endpoints[epidx_n(idx)].in_ack = 0;
308 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 0;
311 static void usb_status_ack(int ep, int dir)
313 logf("usb_status_ack(%d)", dir);
314 if(ep == EP_CONTROL)
315 usb_select_setup_endpoint();
316 else
317 usb_select_endpoint(ep_index(ep, dir));
319 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS;
322 static void usb_data_stage_enable(int ep, int dir)
324 logf("usb_data_stage_enable(%d)", dir);
325 usb_select_endpoint(ep_index(ep, dir));
326 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_DSEN;
329 static void usb_handle_setup_rx(void)
331 int len;
332 usb_select_setup_endpoint();
333 len = usb_get_packet(setup_pkt_buf, 8);
335 if (len == 8)
337 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS; /* Acknowledge packet */
338 usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf);
340 else
342 usb_drv_stall(0, true, false);
343 usb_drv_stall(0, true, true);
344 logf("usb_handle_setup_rx() failed");
345 return;
348 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]);
351 static void usb_handle_data_int(int ep, int dir)
353 int len;
354 if (dir == DIR_TX)
355 len = usb_send(ep);
356 else
358 len = usb_receive(ep);
359 endpoints[ep].in_ack = 1;
361 logf("usb_handle_data_int(%d, %d) finished", ep, dir);
364 bool usb_drv_powered(void)
366 #if 0
367 return (ISP1583_INIT_OTG & INIT_OTG_BSESS_VALID) ? true : false;
368 #else
369 return (ISP1583_INIT_MODE & INIT_MODE_VBUSSTAT) ? true : false;
370 #endif
373 static void setup_endpoints(void)
375 usb_setup_endpoint(ep_index(0, DIR_RX), 64, 0);
376 usb_setup_endpoint(ep_index(0, DIR_TX), 64, 0);
378 int i;
379 for(i = 1; i < USB_NUM_ENDPOINTS-1; i++)
381 usb_setup_endpoint(ep_index(i, DIR_RX), (high_speed_mode ? 512 : 64), 2); /* 2 = TYPE_BULK */
382 usb_setup_endpoint(ep_index(i, DIR_TX), (high_speed_mode ? 512 : 64), 2);
385 usb_enable_endpoint(ep_index(0, DIR_RX));
386 usb_enable_endpoint(ep_index(0, DIR_TX));
388 for (i = 1; i < USB_NUM_ENDPOINTS-1; i++)
390 usb_enable_endpoint(ep_index(i, DIR_RX));
391 usb_enable_endpoint(ep_index(i, DIR_TX));
394 ZVM_SPECIFIC;
397 void usb_helper(void)
399 if(ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ)
401 logf("Helper detected interrupt... [%d]", (int)current_tick);
402 usb_drv_int();
404 return;
407 void usb_drv_init(void)
409 /* Disable interrupt at CPU level */
410 DIS_INT_CPU_TARGET;
412 /* Unlock the device's registers */
413 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
415 /* Soft reset the device */
416 ISP1583_INIT_MODE = INIT_MODE_SFRESET;
417 sleep(10);
418 /* Enable CLKAON & GLINTENA */
419 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
421 /* Disable all OTG functions */
422 ISP1583_INIT_OTG = 0;
424 #ifdef DEBUG
425 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));
426 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID);
427 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
428 #endif
430 /*Set interrupt generation to target-specific mode +
431 * Set the control pipe to ACK only interrupt +
432 * Set the IN pipe to ACK only interrupt +
433 * Set OUT pipe to ACK and NYET interrupt
436 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
437 /* Clear all interrupts */
438 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, 0xFFFFFFFF);
439 /* Enable USB interrupts */
440 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
442 ZVM_SPECIFIC;
444 /* Enable interrupt at CPU level */
445 EN_INT_CPU_TARGET;
447 setup_endpoints();
449 /* Clear device address and disable it */
450 ISP1583_INIT_ADDRESS = 0;
452 /* Turn SoftConnect on */
453 ISP1583_INIT_MODE |= INIT_MODE_SOFTCT;
455 ZVM_SPECIFIC;
457 //tick_add_task(usb_helper);
459 logf("usb_init_device() finished");
462 int usb_drv_port_speed(void)
464 return (int)high_speed_mode;
467 void usb_drv_exit(void)
469 logf("usb_drv_exit()");
471 /* Disable device */
472 ISP1583_INIT_MODE &= ~INIT_MODE_SOFTCT;
473 ISP1583_INIT_ADDRESS = 0;
475 /* Disable interrupts */
476 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, 0);
477 /* and the CPU's one... */
478 DIS_INT_CPU_TARGET;
481 /* Send usb controller to suspend mode */
482 ISP1583_INIT_MODE = INIT_MODE_GOSUSP;
483 ISP1583_INIT_MODE = 0;
485 //tick_remove_task(usb_helper);
487 ZVM_SPECIFIC;
490 void usb_drv_stall(int endpoint, bool stall, bool in)
492 logf("%sstall EP%d %s", (stall ? "" : "un"), endpoint, (in ? "RX" : "TX" ));
493 if (stall)
494 usb_stall_endpoint(ep_index(endpoint, (int)in));
495 else
496 usb_unstall_endpoint(ep_index(endpoint, (int)in));
499 bool usb_drv_stalled(int endpoint, bool in)
501 return (endpoints[endpoint].halt[(int)in] == 1);
504 static void out_callback(int ep, unsigned char *buf, int len)
506 (void)buf;
507 logf("out_callback(%d, 0x%x, %d)", ep, (int)buf, len);
508 usb_status_ack(ep, DIR_RX);
509 usb_core_transfer_complete(ep, true, 0, len); /* 0=>status succeeded, haven't worked out status failed yet... */
512 static void in_callback(int ep, unsigned char *buf, int len)
514 (void)buf;
515 logf("in_callback(%d, 0x%x, %d)", ep, (int)buf, len);
516 usb_status_ack(ep, DIR_TX);
517 usb_core_transfer_complete(ep, false, 0, len);
520 int usb_drv_recv(int ep, void* ptr, int length)
522 logf("usb_drv_recv(%d, 0x%x, %d)", ep, (int)ptr, length);
523 if(ep == 0 && length == 0 && ptr == NULL)
525 usb_status_ack(ep, DIR_TX);
526 return 0;
528 endpoints[ep].in_done = in_callback;
529 endpoints[ep].in_buf = ptr;
530 endpoints[ep].in_max_len = length;
531 endpoints[ep].in_min_len = length;
532 endpoints[ep].in_ptr = 0;
533 if(ep == 0)
535 usb_data_stage_enable(ep, DIR_RX);
536 return usb_receive(ep);
538 else
539 return usb_receive(ep);
542 int usb_drv_send_nonblocking(int ep, void* ptr, int length)
544 /* First implement DMA... */
545 return usb_drv_send(ep, ptr, length);
548 static void usb_drv_wait(int ep, bool send)
550 logf("usb_drv_wait(%d, %d)", ep, send);
551 if(send)
553 while (endpoints[ep].out_in_progress)
554 nop_f();
556 else
558 while (endpoints[ep].in_ack)
559 nop_f();
563 int usb_drv_send(int ep, void* ptr, int length)
565 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep, (int)ptr, length);
566 if(ep == 0 && length == 0 && ptr == NULL)
568 usb_status_ack(ep, DIR_RX);
569 return 0;
571 if(endpoints[ep].out_in_progress == 1)
572 return -1;
573 endpoints[ep].out_done = out_callback;
574 endpoints[ep].out_buf = ptr;
575 endpoints[ep].out_len = length;
576 endpoints[ep].out_ptr = 0;
577 endpoints[ep].out_in_progress = 1;
578 if(ep == 0)
580 int rc = usb_send(ep);
581 usb_data_stage_enable(ep, DIR_TX);
582 usb_drv_wait(ep, DIR_TX);
583 return rc;
585 else
586 return usb_send(ep);
589 void usb_drv_reset_endpoint(int ep, bool send)
591 logf("reset endpoint(%d, %d)", ep, send);
592 usb_setup_endpoint(ep_index(ep, (int)send), endpoints[ep].max_pkt_size[(int)send], endpoints[ep].type);
593 usb_enable_endpoint(ep_index(ep, (int)send));
596 void usb_drv_cancel_all_transfers(void)
598 logf("usb_drv_cancel_all_tranfers()");
599 int i;
601 for(i=0;i<USB_NUM_ENDPOINTS-1;i++)
602 endpoints[i].halt[0] = endpoints[i].halt[1] = 1;
605 int usb_drv_request_endpoint(int dir)
607 int i, bit;
609 bit=(dir & USB_DIR_IN)? 2:1;
611 for (i=1; i < USB_NUM_ENDPOINTS; i++) {
612 if((endpoints[i].allocation & bit)!=0)
613 continue;
614 endpoints[i].allocation |= bit;
615 return i | dir;
618 return -1;
621 void usb_drv_release_endpoint(int ep)
623 int mask = (ep & USB_DIR_IN)? ~2:~1;
624 endpoints[ep & 0x7f].allocation &= mask;
627 static void bus_reset(void)
629 /* Enable CLKAON & GLINTENA */
630 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
631 /* Enable USB interrupts */
632 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
633 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
635 /* Disable all OTG functions */
636 ISP1583_INIT_OTG = 0;
638 /* Clear device address and enable it */
639 ISP1583_INIT_ADDRESS = INIT_ADDRESS_DEVEN;
641 ZVM_SPECIFIC;
643 /* Reset endpoints to default */
644 setup_endpoints();
646 logf("bus reset->done");
649 /* Method for handling interrupts, must be called from usb-<target>.c */
650 void IRAM_ATTR usb_drv_int(void)
652 unsigned long ints;
653 ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ;
655 if(!ints)
656 return;
658 /* Unlock the device's registers */
659 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
661 //logf(" handling int [0x%lx & 0x%lx = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, (int)ints);
663 if(ints & INT_IEBRST) /* Bus reset */
665 logf("BRESET");
666 high_speed_mode = false;
667 bus_reset();
668 usb_core_bus_reset();
669 /* Mask bus reset interrupt */
670 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, INT_IEBRST);
671 return;
673 if(ints & INT_IEP0SETUP) /* EP0SETUP interrupt */
675 logf("EP0SETUP");
676 usb_handle_setup_rx();
678 if(ints & INT_IEHS_STA) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
680 logf("HS_STA");
681 high_speed_mode = true;
682 setup_endpoints();
684 if(ints & INT_EP_MASK) /* Endpoints interrupt */
686 unsigned long ep_event;
687 unsigned short i = 10;
688 ep_event = ints & INT_EP_MASK;
689 while(ep_event)
691 if(i>25)
692 break;
694 if(ep_event & (1 << i))
696 logf("EP%d %s interrupt", (i - 10) / 2, i % 2 ? "RX" : "TX");
697 usb_handle_data_int((i - 10) / 2, i % 2);
698 ep_event &= ~(1 << i);
700 i++;
703 if(ints & INT_IERESM && !(ints & INT_IESUSP)) /* Resume status: status change from suspend to resume (active) */
705 logf("RESM");
707 if(ints & INT_IESUSP && !(ints & INT_IERESM)) /* Suspend status: status change from active to suspend */
709 logf("SUSP");
711 if(ints & INT_IEDMA) /* change in the DMA Interrupt Reason register */
713 logf("DMA");
715 if(ints & INT_IEVBUS) /* transition from LOW to HIGH on VBUS */
717 logf("VBUS");
719 /* Mask all (enabled) interrupts */
720 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints);
722 ZVM_SPECIFIC;
725 void usb_drv_set_address(int address)
727 logf("usb_drv_set_address(0x%x)", address);
728 ISP1583_INIT_ADDRESS = (address & 0x7F) | INIT_ADDRESS_DEVEN;
730 ZVM_SPECIFIC;
733 void usb_drv_set_test_mode(int mode)
735 logf("usb_drv_set_test_mode(%d)", mode);
736 switch(mode){
737 case 0:
738 ISP1583_GEN_TSTMOD = 0;
739 /* Power cycle... */
740 break;
741 case 1:
742 ISP1583_GEN_TSTMOD = GEN_TSTMOD_JSTATE;
743 break;
744 case 2:
745 ISP1583_GEN_TSTMOD = GEN_TSTMOD_KSTATE;
746 break;
747 case 3:
748 ISP1583_GEN_TSTMOD = GEN_TSTMOD_SE0_NAK;
749 break;
750 case 4:
751 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
752 break;
753 case 5:
754 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
755 break;
759 #ifndef BOOTLOADER
760 int dbg_usb_num_items(void)
762 return 2+USB_NUM_ENDPOINTS*2;
765 char* dbg_usb_item(int selected_item, void *data, char *buffer, size_t buffer_len)
767 if(selected_item < 2)
769 switch(selected_item)
771 case 0:
772 snprintf(buffer, buffer_len, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
773 return buffer;
774 case 1:
775 snprintf(buffer, buffer_len, "HS mode: %s", (high_speed_mode ? "Yes" : "No"));
776 return buffer;
779 else
781 int n = ep_index((selected_item - 2) / 2, (selected_item - 2) % 2);
782 if(endpoints[n].enabled == false)
783 snprintf(buffer, buffer_len, "EP%d[%s]: DISABLED", epidx_n(n), (epidx_dir(n) ? "TX" : "RX"));
784 else
786 if(epidx_dir(n))
788 if(endpoints[n].out_in_progress)
789 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);
790 else
791 snprintf(buffer, buffer_len, "EP%d[TX]: STANDBY", epidx_n(n));
793 else
795 if(endpoints[n].in_buf && !endpoints[n].in_ack)
796 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);
797 else
798 snprintf(buffer, buffer_len, "EP%d[RX]: STANDBY", epidx_n(n));
801 return buffer;
803 return NULL;
804 (void)data;
806 #endif