Sansa clip+: do not set GPIO B7 in the display driver, it's already used for FM radio I2C
[kugel-rb.git] / firmware / drivers / isp1583.c
blobf45ff6eb5e918af83c371af924abb7b7298cce7f
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 struct usb_endpoint
34 unsigned char *out_buf;
35 short out_len;
36 short out_ptr;
37 void (*out_done)(int, unsigned char *, int);
38 unsigned char out_in_progress;
40 unsigned char *in_buf;
41 short in_min_len;
42 short in_max_len;
43 short in_ptr;
44 void (*in_done)(int, unsigned char *, int);
45 unsigned char in_ack;
47 unsigned char halt[2];
48 unsigned char enabled[2];
49 short max_pkt_size[2];
50 short type;
51 char allocation;
54 static unsigned char setup_pkt_buf[8];
55 static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS];
57 static bool high_speed_mode = false;
59 static inline void or_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
61 set_int_value(*a, *b, (r | value));
63 static inline void bc_int_value(volatile unsigned short *a, volatile unsigned short *b, unsigned long r, unsigned long value)
65 set_int_value(*a, *b, (r & ~value));
68 static inline void nop_f(void)
70 yield();
73 #define NOP asm volatile("nop\n");
75 static inline int ep_index(int n, bool dir)
77 return (n << 1) | dir;
80 static inline bool epidx_dir(int idx)
82 return idx & 1;
85 static inline int epidx_n(int idx)
87 return idx >> 1;
90 static inline void usb_select_endpoint(int idx)
92 /* Select the endpoint */
93 ISP1583_DFLOW_EPINDEX = idx;
94 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
95 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
97 NOP;
100 static inline void usb_select_setup_endpoint(void)
102 /* Select the endpoint */
103 ISP1583_DFLOW_EPINDEX = DFLOW_EPINDEX_EP0SETUP;
104 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
105 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
107 NOP;
110 static void usb_setup_endpoint(int idx, int max_pkt_size, int type)
112 if(epidx_n(idx)!=EP_CONTROL)
114 usb_select_endpoint(idx);
115 ISP1583_DFLOW_MAXPKSZ = max_pkt_size & 0x7FF;
116 ISP1583_DFLOW_EPTYPE = (DFLOW_EPTYPE_NOEMPKT | DFLOW_EPTYPE_DBLBUF | (type & 0x3));
118 /* clear buffer ... */
119 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
120 /* ... twice because of double buffering */
121 usb_select_endpoint(idx);
122 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
125 struct usb_endpoint *ep;
126 ep = &(endpoints[epidx_n(idx)]);
127 ep->halt[epidx_dir(idx)] = 0;
128 ep->enabled[epidx_dir(idx)] = 0;
129 ep->out_in_progress = 0;
130 ep->in_min_len = -1;
131 ep->in_ack = 0;
132 ep->type = type;
133 ep->max_pkt_size[epidx_dir(idx)] = max_pkt_size;
136 static void usb_enable_endpoint(int idx)
138 if(epidx_n(idx)!=EP_CONTROL)
140 usb_select_endpoint(idx);
141 /* Enable interrupt */
142 or_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
143 /* Enable endpoint */
144 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
147 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 1;
150 static void usb_disable_endpoint(int idx, bool set_struct)
152 usb_select_endpoint(idx);
153 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
154 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
156 if(set_struct)
157 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
160 static int usb_get_packet(unsigned char *buf, int max_len)
162 int len, i;
163 len = ISP1583_DFLOW_BUFLEN;
165 if (max_len < 0 || max_len > len)
166 max_len = len;
168 i = 0;
169 while (i < len)
171 unsigned short d = ISP1583_DFLOW_DATA;
172 if (i < max_len)
173 buf[i] = d & 0xff;
174 i++;
175 if (i < max_len)
176 buf[i] = (d >> 8) & 0xff;
177 i++;
179 return max_len;
182 static int usb_receive(int n)
184 logf("usb_receive(%d)", n);
185 int len;
187 if (endpoints[n].halt[DIR_RX]
188 || !endpoints[n].enabled[DIR_RX]
189 || endpoints[n].in_min_len < 0
190 || !endpoints[n].in_ack)
191 return -1;
193 endpoints[n].in_ack = 0;
195 usb_select_endpoint(ep_index(n, DIR_RX));
197 len = usb_get_packet(endpoints[n].in_buf + endpoints[n].in_ptr,
198 endpoints[n].in_max_len - endpoints[n].in_ptr);
199 endpoints[n].in_ptr += len;
201 if (endpoints[n].in_ptr >= endpoints[n].in_min_len)
203 endpoints[n].in_min_len = -1;
204 if (endpoints[n].in_done)
205 (*(endpoints[n].in_done))(n, endpoints[n].in_buf,
206 endpoints[n].in_ptr);
208 logf("receive_end");
209 return 0;
212 static bool usb_out_buffer_full(int ep)
214 usb_select_endpoint(ep_index(ep, DIR_TX));
215 if (ISP1583_DFLOW_EPTYPE & 4) /* Check if type=bulk and double buffering is set */
216 return (ISP1583_DFLOW_BUFSTAT & 3) == 3; /* Return true if both buffers are filled */
217 else
218 return (ISP1583_DFLOW_BUFSTAT & 3) != 0; /* Return true if one of the buffers are filled */
221 static int usb_send(int n)
223 logf("usb_send(%d)", n);
224 int max_pkt_size, len;
225 int i;
226 unsigned char *p;
228 if (endpoints[n].halt[DIR_TX]
229 || !endpoints[n].enabled[DIR_TX]
230 || !endpoints[n].out_in_progress)
232 logf("NOT SEND TO EP!");
233 return -1;
236 if (endpoints[n].out_ptr < 0)
238 endpoints[n].out_in_progress = 0;
239 if (endpoints[n].out_done)
240 (*(endpoints[n].out_done))(n, endpoints[n].out_buf,
241 endpoints[n].out_len);
242 logf("ALREADY SENT TO EP!");
243 return -1;
246 if (usb_out_buffer_full(n))
248 logf("BUFFER FULL!");
249 return -1;
252 usb_select_endpoint(ep_index(n, DIR_TX));
253 max_pkt_size = endpoints[n].max_pkt_size[DIR_TX];
254 len = endpoints[n].out_len - endpoints[n].out_ptr;
255 if (len > max_pkt_size)
256 len = max_pkt_size;
258 if(len < max_pkt_size)
259 ISP1583_DFLOW_BUFLEN = len;
261 p = endpoints[n].out_buf + endpoints[n].out_ptr;
262 i = 0;
263 while (len - i >= 2)
265 ISP1583_DFLOW_DATA = p[i] | (p[i + 1] << 8);
266 i += 2;
268 if (i < len)
269 ISP1583_DFLOW_DATA = p[i];
271 endpoints[n].out_ptr += len;
274 if (endpoints[n].out_ptr == endpoints[n].out_len
275 && len < max_pkt_size)
277 if (endpoints[n].out_ptr == endpoints[n].out_len)
278 endpoints[n].out_ptr = -1;
280 logf("send_end");
281 return 0;
284 static void usb_stall_endpoint(int idx)
286 usb_select_endpoint(idx);
287 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STALL;
288 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 1;
291 static void usb_unstall_endpoint(int idx)
293 usb_select_endpoint(idx);
294 ISP1583_DFLOW_CTRLFUN &= ~DFLOW_CTRLFUN_STALL;
295 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
296 ISP1583_DFLOW_EPTYPE |= DFLOW_EPTYPE_ENABLE;
297 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_CLBUF;
298 if (epidx_dir(idx) == DIR_TX)
299 endpoints[epidx_n(idx)].out_in_progress = 0;
300 else
302 endpoints[epidx_n(idx)].in_min_len = -1;
303 endpoints[epidx_n(idx)].in_ack = 0;
305 endpoints[epidx_n(idx)].halt[epidx_dir(idx)] = 0;
308 static void usb_status_ack(int ep, int dir)
310 logf("usb_status_ack(%d)", dir);
311 if(ep == EP_CONTROL)
312 usb_select_setup_endpoint();
313 else
314 usb_select_endpoint(ep_index(ep, dir));
316 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS;
319 static void usb_data_stage_enable(int ep, int dir)
321 logf("usb_data_stage_enable(%d)", dir);
322 usb_select_endpoint(ep_index(ep, dir));
323 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_DSEN;
326 static void usb_handle_setup_rx(void)
328 int len;
329 usb_select_setup_endpoint();
330 len = usb_get_packet(setup_pkt_buf, 8);
332 if (len == 8)
334 ISP1583_DFLOW_CTRLFUN |= DFLOW_CTRLFUN_STATUS; /* Acknowledge packet */
335 usb_core_control_request((struct usb_ctrlrequest*)setup_pkt_buf);
337 else
339 usb_drv_stall(EP_CONTROL, true, false);
340 usb_drv_stall(EP_CONTROL, true, true);
341 logf("usb_handle_setup_rx() failed");
342 return;
345 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]);
348 static void usb_handle_data_int(int ep, int dir)
350 int len;
351 if (dir == DIR_TX)
352 len = usb_send(ep);
353 else
355 len = usb_receive(ep);
356 endpoints[ep].in_ack = 1;
358 logf("usb_handle_data_int(%d, %d) finished", ep, dir);
361 bool usb_drv_powered(void)
363 #if 0
364 return (ISP1583_INIT_OTG & INIT_OTG_BSESS_VALID) ? true : false;
365 #else
366 return (ISP1583_INIT_MODE & INIT_MODE_VBUSSTAT) ? true : false;
367 #endif
370 static void setup_endpoints(void)
372 int i;
373 int max_pkt_size = (high_speed_mode ? 512 : 64);
375 usb_setup_endpoint(ep_index(EP_CONTROL, DIR_RX), 64,
376 USB_ENDPOINT_XFER_CONTROL);
377 usb_setup_endpoint(ep_index(EP_CONTROL, DIR_TX), 64,
378 USB_ENDPOINT_XFER_CONTROL);
380 for(i = 1; i < USB_NUM_ENDPOINTS-1; i++)
382 usb_setup_endpoint(ep_index(i, DIR_RX), max_pkt_size,
383 USB_ENDPOINT_XFER_BULK);
384 usb_setup_endpoint(ep_index(i, DIR_TX), max_pkt_size,
385 USB_ENDPOINT_XFER_BULK);
388 usb_enable_endpoint(ep_index(EP_CONTROL, DIR_RX));
389 usb_enable_endpoint(ep_index(EP_CONTROL, DIR_TX));
391 for (i = 1; i < USB_NUM_ENDPOINTS-1; i++)
393 usb_enable_endpoint(ep_index(i, DIR_RX));
394 usb_enable_endpoint(ep_index(i, DIR_TX));
397 ZVM_SPECIFIC;
400 #if 0 /* currently unused */
401 static void usb_helper(void)
403 if(ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ)
405 logf("Helper detected interrupt... [%d]", (int)current_tick);
406 usb_drv_int();
409 #endif
411 void usb_drv_init(void)
413 /* Disable interrupt at CPU level */
414 DIS_INT_CPU_TARGET;
416 /* Unlock the device's registers */
417 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
419 /* Soft reset the device */
420 ISP1583_INIT_MODE = INIT_MODE_SFRESET;
421 sleep(10);
422 /* Enable CLKAON & GLINTENA */
423 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
425 /* Disable all OTG functions */
426 ISP1583_INIT_OTG = 0;
428 #ifdef DEBUG
429 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));
430 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID);
431 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
432 #endif
434 /*Set interrupt generation to target-specific mode +
435 * Set the control pipe to ACK only interrupt +
436 * Set the IN pipe to ACK only interrupt +
437 * Set OUT pipe to ACK and NYET interrupt
440 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
441 /* Clear all interrupts */
442 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, 0xFFFFFFFF);
443 /* Enable USB interrupts */
444 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
446 ZVM_SPECIFIC;
448 /* Enable interrupt at CPU level */
449 EN_INT_CPU_TARGET;
451 setup_endpoints();
453 /* Clear device address and disable it */
454 ISP1583_INIT_ADDRESS = 0;
456 /* Turn SoftConnect on */
457 ISP1583_INIT_MODE |= INIT_MODE_SOFTCT;
459 ZVM_SPECIFIC;
461 //tick_add_task(usb_helper);
463 logf("usb_init_device() finished");
466 int usb_drv_port_speed(void)
468 return (int)high_speed_mode;
471 void usb_drv_exit(void)
473 logf("usb_drv_exit()");
475 /* Disable device */
476 ISP1583_INIT_MODE &= ~INIT_MODE_SOFTCT;
477 ISP1583_INIT_ADDRESS = 0;
479 /* Disable interrupts */
480 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, 0);
481 /* and the CPU's one... */
482 DIS_INT_CPU_TARGET;
485 /* Send usb controller to suspend mode */
486 ISP1583_INIT_MODE = INIT_MODE_GOSUSP;
487 ISP1583_INIT_MODE = 0;
489 //tick_remove_task(usb_helper);
491 ZVM_SPECIFIC;
494 void usb_drv_stall(int endpoint, bool stall, bool in)
496 logf("%sstall EP%d %s", (stall ? "" : "un"), endpoint, (in ? "RX" : "TX" ));
497 if (stall)
498 usb_stall_endpoint(ep_index(endpoint, (int)in));
499 else
500 usb_unstall_endpoint(ep_index(endpoint, (int)in));
503 bool usb_drv_stalled(int endpoint, bool in)
505 return (endpoints[endpoint].halt[(int)in] == 1);
508 static void out_callback(int ep, unsigned char *buf, int len)
510 (void)buf;
511 logf("out_callback(%d, 0x%x, %d)", ep, (int)buf, len);
512 usb_status_ack(ep, DIR_RX);
513 usb_core_transfer_complete(ep, true, 0, len); /* 0=>status succeeded, haven't worked out status failed yet... */
516 static void in_callback(int ep, unsigned char *buf, int len)
518 (void)buf;
519 logf("in_callback(%d, 0x%x, %d)", ep, (int)buf, len);
520 usb_status_ack(ep, DIR_TX);
521 usb_core_transfer_complete(ep, false, 0, len);
524 int usb_drv_recv(int ep, void* ptr, int length)
526 logf("usb_drv_recv(%d, 0x%x, %d)", ep, (int)ptr, length);
527 if(ep == EP_CONTROL && length == 0 && ptr == NULL)
529 usb_status_ack(ep, DIR_TX);
530 return 0;
532 endpoints[ep].in_done = in_callback;
533 endpoints[ep].in_buf = ptr;
534 endpoints[ep].in_max_len = length;
535 endpoints[ep].in_min_len = length;
536 endpoints[ep].in_ptr = 0;
537 if(ep == EP_CONTROL)
539 usb_data_stage_enable(ep, DIR_RX);
540 return usb_receive(ep);
542 else
543 return usb_receive(ep);
546 int usb_drv_send_nonblocking(int ep, void* ptr, int length)
548 /* First implement DMA... */
549 return usb_drv_send(ep, ptr, length);
552 static void usb_drv_wait(int ep, bool send)
554 logf("usb_drv_wait(%d, %d)", ep, send);
555 if(send)
557 while (endpoints[ep].out_in_progress)
558 nop_f();
560 else
562 while (endpoints[ep].in_ack)
563 nop_f();
567 int usb_drv_send(int ep, void* ptr, int length)
569 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep, (int)ptr, length);
570 if(ep == EP_CONTROL && length == 0 && ptr == NULL)
572 usb_status_ack(ep, DIR_RX);
573 return 0;
575 if(endpoints[ep].out_in_progress == 1)
576 return -1;
577 endpoints[ep].out_done = out_callback;
578 endpoints[ep].out_buf = ptr;
579 endpoints[ep].out_len = length;
580 endpoints[ep].out_ptr = 0;
581 endpoints[ep].out_in_progress = 1;
582 if(ep == EP_CONTROL)
584 int rc = usb_send(ep);
585 usb_data_stage_enable(ep, DIR_TX);
586 usb_drv_wait(ep, DIR_TX);
587 return rc;
589 else
590 return usb_send(ep);
593 void usb_drv_reset_endpoint(int ep, bool send)
595 logf("reset endpoint(%d, %d)", ep, send);
596 usb_setup_endpoint(ep_index(ep, (int)send), endpoints[ep].max_pkt_size[(int)send], endpoints[ep].type);
597 usb_enable_endpoint(ep_index(ep, (int)send));
600 void usb_drv_cancel_all_transfers(void)
602 logf("usb_drv_cancel_all_tranfers()");
603 int i;
605 for(i=0;i<USB_NUM_ENDPOINTS-1;i++)
606 endpoints[i].halt[0] = endpoints[i].halt[1] = 1;
609 int usb_drv_request_endpoint(int type, int dir)
611 int i, bit;
613 if (type != USB_ENDPOINT_XFER_BULK)
614 return -1;
616 bit=(dir & USB_DIR_IN)? 2:1;
618 for (i=1; i < USB_NUM_ENDPOINTS; i++) {
619 if((endpoints[i].allocation & bit)!=0)
620 continue;
621 endpoints[i].allocation |= bit;
622 return i | dir;
625 return -1;
628 void usb_drv_release_endpoint(int ep)
630 int mask = (ep & USB_DIR_IN)? ~2:~1;
631 endpoints[ep & 0x7f].allocation &= mask;
634 static void bus_reset(void)
636 /* Enable CLKAON & GLINTENA */
637 ISP1583_INIT_MODE = STANDARD_INIT_MODE;
638 /* Enable USB interrupts */
639 ISP1583_INIT_INTCONF = 0x54 | INT_CONF_TARGET;
640 set_int_value(ISP1583_INIT_INTEN_A, ISP1583_INIT_INTEN_B, STANDARD_INTEN);
642 /* Disable all OTG functions */
643 ISP1583_INIT_OTG = 0;
645 /* Clear device address and enable it */
646 ISP1583_INIT_ADDRESS = INIT_ADDRESS_DEVEN;
648 ZVM_SPECIFIC;
650 /* Reset endpoints to default */
651 setup_endpoints();
653 logf("bus reset->done");
656 /* Method for handling interrupts, must be called from usb-<target>.c */
657 void IRAM_ATTR usb_drv_int(void)
659 unsigned long ints;
660 ints = ISP1583_GEN_INT_READ & ISP1583_INIT_INTEN_READ;
662 if(!ints)
663 return;
665 /* Unlock the device's registers */
666 ISP1583_GEN_UNLCKDEV = ISP1583_UNLOCK_CODE;
668 //logf(" handling int [0x%lx & 0x%lx = 0x%x]", ISP1583_GEN_INT_READ, ISP1583_INIT_INTEN_READ, (int)ints);
670 if(ints & INT_IEBRST) /* Bus reset */
672 logf("BRESET");
673 high_speed_mode = false;
674 bus_reset();
675 usb_core_bus_reset();
676 /* Mask bus reset interrupt */
677 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, INT_IEBRST);
678 return;
680 if(ints & INT_IEP0SETUP) /* EP0SETUP interrupt */
682 logf("EP0SETUP");
683 usb_handle_setup_rx();
685 if(ints & INT_IEHS_STA) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
687 logf("HS_STA");
688 high_speed_mode = true;
689 setup_endpoints();
691 if(ints & INT_EP_MASK) /* Endpoints interrupt */
693 unsigned long ep_event;
694 unsigned short i = 10;
695 ep_event = ints & INT_EP_MASK;
696 while(ep_event)
698 if(i>25)
699 break;
701 if(ep_event & (1 << i))
703 logf("EP%d %s interrupt", (i - 10) / 2, i % 2 ? "RX" : "TX");
704 usb_handle_data_int((i - 10) / 2, i % 2);
705 ep_event &= ~(1 << i);
707 i++;
710 if(ints & INT_IERESM && !(ints & INT_IESUSP)) /* Resume status: status change from suspend to resume (active) */
712 logf("RESM");
714 if(ints & INT_IESUSP && !(ints & INT_IERESM)) /* Suspend status: status change from active to suspend */
716 logf("SUSP");
718 if(ints & INT_IEDMA) /* change in the DMA Interrupt Reason register */
720 logf("DMA");
722 if(ints & INT_IEVBUS) /* transition from LOW to HIGH on VBUS */
724 logf("VBUS");
726 /* Mask all (enabled) interrupts */
727 set_int_value(ISP1583_GEN_INT_A, ISP1583_GEN_INT_B, ints);
729 ZVM_SPECIFIC;
732 void usb_drv_set_address(int address)
734 logf("usb_drv_set_address(0x%x)", address);
735 ISP1583_INIT_ADDRESS = (address & 0x7F) | INIT_ADDRESS_DEVEN;
737 ZVM_SPECIFIC;
740 void usb_drv_set_test_mode(int mode)
742 logf("usb_drv_set_test_mode(%d)", mode);
743 switch(mode){
744 case 0:
745 ISP1583_GEN_TSTMOD = 0;
746 /* Power cycle... */
747 break;
748 case 1:
749 ISP1583_GEN_TSTMOD = GEN_TSTMOD_JSTATE;
750 break;
751 case 2:
752 ISP1583_GEN_TSTMOD = GEN_TSTMOD_KSTATE;
753 break;
754 case 3:
755 ISP1583_GEN_TSTMOD = GEN_TSTMOD_SE0_NAK;
756 break;
757 case 4:
758 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
759 break;
760 case 5:
761 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
762 break;
766 #ifndef BOOTLOADER
767 int dbg_usb_num_items(void)
769 return 2+USB_NUM_ENDPOINTS*2;
772 const char* dbg_usb_item(int selected_item, void *data,
773 char *buffer, size_t buffer_len)
775 if(selected_item < 2)
777 switch(selected_item)
779 case 0:
780 snprintf(buffer, buffer_len, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
781 return buffer;
782 case 1:
783 snprintf(buffer, buffer_len, "HS mode: %s", (high_speed_mode ? "Yes" : "No"));
784 return buffer;
787 else
789 int n = ep_index((selected_item - 2) / 2, (selected_item - 2) % 2);
790 if(endpoints[n].enabled == false)
791 snprintf(buffer, buffer_len, "EP%d[%s]: DISABLED", epidx_n(n), (epidx_dir(n) ? "TX" : "RX"));
792 else
794 if(epidx_dir(n))
796 if(endpoints[n].out_in_progress)
797 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);
798 else
799 snprintf(buffer, buffer_len, "EP%d[TX]: STANDBY", epidx_n(n));
801 else
803 if(endpoints[n].in_buf && !endpoints[n].in_ack)
804 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);
805 else
806 snprintf(buffer, buffer_len, "EP%d[RX]: STANDBY", epidx_n(n));
809 return buffer;
811 return NULL;
812 (void)data;
814 #endif