1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
37 unsigned char *out_buf
;
40 void (*out_done
)(int, unsigned char *, int);
41 unsigned char out_in_progress
;
43 unsigned char *in_buf
;
47 void (*in_done
)(int, unsigned char *, int);
50 unsigned char halt
[2];
51 unsigned char enabled
[2];
52 short max_pkt_size
[2];
56 static unsigned char setup_pkt_buf
[8];
57 static struct usb_endpoint endpoints
[NUM_ENDPOINTS
];
59 static bool high_speed_mode
= false;
61 static inline void or_int_value(volatile unsigned short *a
, volatile unsigned short *b
, unsigned long r
, unsigned long value
)
63 set_int_value(*a
, *b
, (r
| value
));
65 static inline void bc_int_value(volatile unsigned short *a
, volatile unsigned short *b
, unsigned long r
, unsigned long value
)
67 set_int_value(*a
, *b
, (r
& ~value
));
70 static inline void nop_f(void)
75 #define NOP asm volatile("nop\n");
77 static inline int ep_index(int n
, bool dir
)
79 return (n
<< 1) | dir
;
82 static inline bool epidx_dir(int idx
)
87 static inline int epidx_n(int idx
)
92 static inline void usb_select_endpoint(int idx
)
94 /* Select the endpoint */
95 ISP1583_DFLOW_EPINDEX
= idx
;
96 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
97 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
102 static inline void usb_select_setup_endpoint(void)
104 /* Select the endpoint */
105 ISP1583_DFLOW_EPINDEX
= DFLOW_EPINDEX_EP0SETUP
;
106 /* The delay time from the Write Endpoint Index register to the Read Data Port register must be at least 190 ns.
107 * The delay time from the Write Endpoint Index register to the Write Data Port register must be at least 100 ns.
112 static void usb_setup_endpoint(int idx
, int max_pkt_size
, int type
)
116 usb_select_endpoint(idx
);
117 ISP1583_DFLOW_MAXPKSZ
= max_pkt_size
& 0x7FF;
118 ISP1583_DFLOW_EPTYPE
= (DFLOW_EPTYPE_NOEMPKT
| DFLOW_EPTYPE_DBLBUF
| (type
& 0x3));
120 /* clear buffer ... */
121 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
122 /* ... twice because of double buffering */
123 usb_select_endpoint(idx
);
124 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
127 struct usb_endpoint
*ep
;
128 ep
= &(endpoints
[epidx_n(idx
)]);
129 ep
->halt
[epidx_dir(idx
)] = 0;
130 ep
->enabled
[epidx_dir(idx
)] = 0;
131 ep
->out_in_progress
= 0;
135 ep
->max_pkt_size
[epidx_dir(idx
)] = max_pkt_size
;
138 static void usb_enable_endpoint(int idx
)
142 usb_select_endpoint(idx
);
143 /* Enable interrupt */
144 or_int_value(&ISP1583_INIT_INTEN_A
, &ISP1583_INIT_INTEN_B
, ISP1583_INIT_INTEN_READ
, 1 << (10 + idx
));
145 /* Enable endpoint */
146 ISP1583_DFLOW_EPTYPE
|= DFLOW_EPTYPE_ENABLE
;
149 endpoints
[epidx_n(idx
)].enabled
[epidx_dir(idx
)] = 1;
152 static void usb_disable_endpoint(int idx, bool set_struct)
154 usb_select_endpoint(idx);
155 ISP1583_DFLOW_EPTYPE &= ~DFLOW_EPTYPE_ENABLE;
156 bc_int_value(&ISP1583_INIT_INTEN_A, &ISP1583_INIT_INTEN_B, ISP1583_INIT_INTEN_READ, 1 << (10 + idx));
159 endpoints[epidx_n(idx)].enabled[epidx_dir(idx)] = 0;
162 static int usb_get_packet(unsigned char *buf
, int max_len
)
165 len
= ISP1583_DFLOW_BUFLEN
;
167 if (max_len
< 0 || max_len
> len
)
173 unsigned short d
= ISP1583_DFLOW_DATA
;
178 buf
[i
] = (d
>> 8) & 0xff;
184 static int usb_receive(int n
)
186 logf("usb_receive(%d)", n
);
189 if (endpoints
[n
].halt
[DIR_RX
]
190 || !endpoints
[n
].enabled
[DIR_RX
]
191 || endpoints
[n
].in_min_len
< 0
192 || !endpoints
[n
].in_ack
)
195 endpoints
[n
].in_ack
= 0;
197 usb_select_endpoint(ep_index(n
, DIR_RX
));
199 len
= usb_get_packet(endpoints
[n
].in_buf
+ endpoints
[n
].in_ptr
,
200 endpoints
[n
].in_max_len
- endpoints
[n
].in_ptr
);
201 endpoints
[n
].in_ptr
+= len
;
202 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
);
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 */
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
;
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!");
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!");
246 if (usb_out_buffer_full(n
))
248 logf("BUFFER FULL!");
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
)
258 if(len
< max_pkt_size
)
259 ISP1583_DFLOW_BUFLEN
= len
;
261 p
= endpoints
[n
].out_buf
+ endpoints
[n
].out_ptr
;
263 while (len
- i
>= 2) {
264 ISP1583_DFLOW_DATA
= p
[i
] | (p
[i
+ 1] << 8);
268 ISP1583_DFLOW_DATA
= p
[i
];
270 endpoints
[n
].out_ptr
+= len
;
273 if (endpoints[n].out_ptr == endpoints[n].out_len
274 && len < max_pkt_size)
276 if (endpoints
[n
].out_ptr
== endpoints
[n
].out_len
)
277 endpoints
[n
].out_ptr
= -1;
283 static void usb_stall_endpoint(int idx
)
285 usb_select_endpoint(idx
);
286 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STALL
;
287 endpoints
[epidx_n(idx
)].halt
[epidx_dir(idx
)] = 1;
290 static void usb_unstall_endpoint(int idx
)
292 usb_select_endpoint(idx
);
293 ISP1583_DFLOW_CTRLFUN
&= ~DFLOW_CTRLFUN_STALL
;
294 ISP1583_DFLOW_EPTYPE
&= ~DFLOW_EPTYPE_ENABLE
;
295 ISP1583_DFLOW_EPTYPE
|= DFLOW_EPTYPE_ENABLE
;
296 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_CLBUF
;
297 if (epidx_dir(idx
) == DIR_TX
)
298 endpoints
[epidx_n(idx
)].out_in_progress
= 0;
301 endpoints
[epidx_n(idx
)].in_min_len
= -1;
302 endpoints
[epidx_n(idx
)].in_ack
= 0;
304 endpoints
[epidx_n(idx
)].halt
[epidx_dir(idx
)] = 0;
307 static void usb_status_ack(int ep
, int dir
)
309 logf("usb_status_ack(%d)", dir
);
310 usb_select_endpoint(ep_index(ep
, dir
));
311 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_STATUS
;
314 static void usb_data_stage_enable(int ep
, int dir
)
316 logf("usb_data_stage_enable(%d)", dir
);
317 usb_select_endpoint(ep_index(ep
, dir
));
318 ISP1583_DFLOW_CTRLFUN
|= DFLOW_CTRLFUN_DSEN
;
321 static void usb_handle_setup_rx(void)
324 usb_select_setup_endpoint();
325 len
= usb_get_packet(setup_pkt_buf
, 8);
328 usb_core_control_request((struct usb_ctrlrequest
*)setup_pkt_buf
);
331 usb_drv_stall(0, true, false);
332 usb_drv_stall(0, true, true);
333 logf("usb_handle_setup_rx() failed");
337 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]);
340 static void usb_handle_data_int(int ep
, int dir
)
347 len
= usb_receive(ep
);
348 endpoints
[ep
].in_ack
= 1;
350 logf("usb_handle_data_int(%d, %d) finished", ep
, dir
);
353 bool usb_drv_powered(void)
356 return (ISP1583_INIT_OTG
& INIT_OTG_BSESS_VALID
) ? true : false;
358 return (ISP1583_INIT_MODE
& INIT_MODE_VBUSSTAT
) ? true : false;
362 static void setup_endpoints(void)
364 usb_setup_endpoint(ep_index(0, DIR_RX
), 64, 0);
365 usb_setup_endpoint(ep_index(0, DIR_TX
), 64, 0);
368 for(i
= 1; i
< NUM_ENDPOINTS
-1; i
++)
370 usb_setup_endpoint(ep_index(i
, DIR_RX
), (high_speed_mode
? 512 : 64), 2); /* 2 = TYPE_BULK */
371 usb_setup_endpoint(ep_index(i
, DIR_TX
), (high_speed_mode
? 512 : 64), 2);
374 usb_enable_endpoint(ep_index(0, DIR_RX
));
375 usb_enable_endpoint(ep_index(0, DIR_TX
));
377 for (i
= 1; i
< NUM_ENDPOINTS
-1; i
++)
379 usb_enable_endpoint(ep_index(i
, DIR_RX
));
380 usb_enable_endpoint(ep_index(i
, DIR_TX
));
386 void usb_helper(void)
388 if(ISP1583_GEN_INT_READ
& ISP1583_INIT_INTEN_READ
)
391 logf("Helper detected interrupt... [%d]", current_tick
);
398 void usb_drv_init(void)
400 /* Disable interrupt at CPU level */
403 /* Unlock the device's registers */
404 ISP1583_GEN_UNLCKDEV
= ISP1583_UNLOCK_CODE
;
406 /* Soft reset the device */
407 ISP1583_INIT_MODE
= INIT_MODE_SFRESET
;
409 /* Enable CLKAON & GLINTENA */
410 ISP1583_INIT_MODE
= STANDARD_INIT_MODE
;
412 /* Disable all OTG functions */
413 ISP1583_INIT_OTG
= 0;
416 #ifdef USE_HIGH_SPEED
417 /* Force device to high speed */
418 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_FORCEHS
;
419 high_speed_mode
= true;
424 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
));
425 logf("Chip ID: 0x%x", ISP1583_GEN_CHIPID
);
426 //logf("INV0: 0x% IRQEDGE: 0x%x IRQPORT: 0x%x", IO_GIO_INV0, IO_GIO_IRQEDGE, IO_GIO_IRQPORT);
429 /*Set interrupt generation to target-specific mode +
430 * Set the control pipe to ACK only interrupt +
431 * Set the IN pipe to ACK only interrupt +
432 * Set OUT pipe to ACK and NYET interrupt
435 ISP1583_INIT_INTCONF
= 0x54 | INT_CONF_TARGET
;
436 /* Clear all interrupts */
437 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, 0xFFFFFFFF);
438 /* Enable USB interrupts */
439 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, STANDARD_INTEN
);
443 /* Enable interrupt at CPU level */
448 /* Clear device address and disable it */
449 ISP1583_INIT_ADDRESS
= 0;
451 /* Turn SoftConnect on */
452 ISP1583_INIT_MODE
|= INIT_MODE_SOFTCT
;
456 tick_add_task(usb_helper
);
458 logf("usb_init_device() finished");
461 int usb_drv_port_speed(void)
463 return (int)high_speed_mode
;
466 void usb_drv_exit(void)
468 logf("usb_drv_exit()");
471 ISP1583_INIT_MODE
&= ~INIT_MODE_SOFTCT
;
472 ISP1583_INIT_ADDRESS
= 0;
474 /* Disable interrupts */
475 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, 0);
476 /* and the CPU's one... */
480 /* Send usb controller to suspend mode */
481 ISP1583_INIT_MODE
= INIT_MODE_GOSUSP
;
482 ISP1583_INIT_MODE
= 0;
484 tick_remove_task(usb_helper
);
489 void usb_drv_stall(int endpoint
, bool stall
, bool in
)
491 logf("%sstall EP%d %s", (stall
? "" : "un"), endpoint
, (in
? "RX" : "TX" ));
493 usb_stall_endpoint(ep_index(endpoint
, (int)in
));
495 usb_unstall_endpoint(ep_index(endpoint
, (int)in
));
498 bool usb_drv_stalled(int endpoint
, bool in
)
500 return (endpoints
[endpoint
].halt
[(int)in
] == 1);
503 static void out_callback(int ep
, unsigned char *buf
, int len
)
506 logf("out_callback(%d, 0x%x, %d)", ep
, &buf
, len
);
507 usb_status_ack(ep
, DIR_RX
);
508 usb_core_transfer_complete(ep
, true, 0, len
); /* 0=>status succeeded, haven't worked out status failed yet... */
511 static void in_callback(int ep
, unsigned char *buf
, int len
)
514 logf("in_callback(%d, 0x%x, %d)", ep
, &buf
, len
);
515 usb_status_ack(ep
, DIR_TX
);
516 usb_core_transfer_complete(ep
, false, 0, len
);
519 int usb_drv_recv(int ep
, void* ptr
, int length
)
521 logf("usb_drv_recv(%d, 0x%x, %d)", ep
, &ptr
, length
);
522 if(ep
== 0 && length
== 0 && ptr
== NULL
)
524 usb_status_ack(ep
, DIR_TX
);
527 endpoints
[ep
].in_done
= in_callback
;
528 endpoints
[ep
].in_buf
= ptr
;
529 endpoints
[ep
].in_max_len
= length
;
530 endpoints
[ep
].in_min_len
= length
;
531 endpoints
[ep
].in_ptr
= 0;
534 usb_data_stage_enable(ep
, DIR_RX
);
535 return usb_receive(ep
);
538 return usb_receive(ep
);
541 int usb_drv_send_nonblocking(int ep
, void* ptr
, int length
)
543 /* First implement DMA... */
544 return usb_drv_send(ep
, ptr
, length
);
547 int usb_drv_send(int ep
, void* ptr
, int length
)
549 logf("usb_drv_send_nb(%d, 0x%x, %d)", ep
, &ptr
, length
);
550 if(ep
== 0 && length
== 0 && ptr
== NULL
)
552 usb_status_ack(ep
, DIR_RX
);
555 if(endpoints
[ep
].out_in_progress
== 1)
557 endpoints
[ep
].out_done
= out_callback
;
558 endpoints
[ep
].out_buf
= ptr
;
559 endpoints
[ep
].out_len
= length
;
560 endpoints
[ep
].out_ptr
= 0;
561 endpoints
[ep
].out_in_progress
= 1;
564 int rc
= usb_send(ep
);
565 usb_data_stage_enable(ep
, DIR_TX
);
566 usb_drv_wait(ep
, DIR_TX
);
573 void usb_drv_reset_endpoint(int ep
, bool send
)
575 logf("reset endpoint(%d, %d)", ep
, send
);
576 usb_setup_endpoint(ep_index(ep
, (int)send
), endpoints
[ep
].max_pkt_size
[(int)send
], endpoints
[ep
].type
);
577 usb_enable_endpoint(ep_index(ep
, (int)send
));
580 void usb_drv_wait(int ep
, bool send
)
582 logf("usb_drv_wait(%d, %d)", ep
, send
);
585 while (endpoints
[ep
].out_in_progress
)
590 while (endpoints
[ep
].in_ack
)
595 void usb_drv_cancel_all_transfers(void)
597 logf("usb_drv_cancel_all_tranfers()");
600 for(i
=0;i
<NUM_ENDPOINTS
-1;i
++)
601 endpoints
[i
].halt
[0] = endpoints
[i
].halt
[1] = 1;
604 static void bus_reset(void)
606 /* Enable CLKAON & GLINTENA */
607 ISP1583_INIT_MODE
= STANDARD_INIT_MODE
;
608 /* Enable USB interrupts */
609 ISP1583_INIT_INTCONF
= 0x54 | INT_CONF_TARGET
;
610 set_int_value(ISP1583_INIT_INTEN_A
, ISP1583_INIT_INTEN_B
, STANDARD_INTEN
);
612 /* Disable all OTG functions */
613 ISP1583_INIT_OTG
= 0;
615 /* Clear device address and enable it */
616 ISP1583_INIT_ADDRESS
= INIT_ADDRESS_DEVEN
;
620 /* Reset endpoints to default */
623 logf("bus reset->done");
626 /* Method for handling interrupts, must be called from usb-<target>.c */
627 void IRAM_ATTR
usb_drv_int(void)
630 ints
= ISP1583_GEN_INT_READ
& ISP1583_INIT_INTEN_READ
;
635 /* Unlock the device's registers */
636 ISP1583_GEN_UNLCKDEV
= ISP1583_UNLOCK_CODE
;
639 logf(" handling int [0x%x & 0x%x = 0x%x]", ISP1583_GEN_INT_READ
, ISP1583_INIT_INTEN_READ
, ints
);
642 if(ints
& INT_IEBRST
) /* Bus reset */
645 high_speed_mode
= false;
647 usb_core_bus_reset();
648 /* Mask bus reset interrupt */
649 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, INT_IEBRST
);
652 if(ints
& INT_IEP0SETUP
) /* EP0SETUP interrupt */
655 usb_handle_setup_rx();
657 if(ints
& INT_IEHS_STA
) /* change from full-speed to high-speed mode -> endpoints need to get reconfigured!! */
660 high_speed_mode
= true;
663 if(ints
& INT_EP_MASK
) /* Endpoints interrupt */
665 unsigned long ep_event
;
666 unsigned short i
= 10;
667 ep_event
= ints
& INT_EP_MASK
;
673 if(ep_event
& (1 << i
))
675 logf("EP%d %s interrupt", (i
- 10) / 2, i
% 2 ? "RX" : "TX");
676 usb_handle_data_int((i
- 10) / 2, i
% 2);
677 ep_event
&= ~(1 << i
);
682 if(ints
& INT_IERESM
&& !(ints
& INT_IESUSP
)) /* Resume status: status change from suspend to resume (active) */
686 if(ints
& INT_IESUSP
&& !(ints
& INT_IERESM
)) /* Suspend status: status change from active to suspend */
690 if(ints
& INT_IEDMA
) /* change in the DMA Interrupt Reason register */
694 if(ints
& INT_IEVBUS
) /* transition from LOW to HIGH on VBUS */
698 /* Mask all (enabled) interrupts */
699 set_int_value(ISP1583_GEN_INT_A
, ISP1583_GEN_INT_B
, ints
);
704 void usb_drv_set_address(int address
)
706 logf("usb_drv_set_address(0x%x)", address
);
707 ISP1583_INIT_ADDRESS
= (address
& 0x7F) | INIT_ADDRESS_DEVEN
;
711 usb_status_ack(0, DIR_TX
);
714 int dbg_usb_num_items(void)
716 return 2+NUM_ENDPOINTS
*2;
719 char* dbg_usb_item(int selected_item
, void *data
, char *buffer
, size_t buffer_len
)
721 if(selected_item
< 2)
723 switch(selected_item
)
726 snprintf(buffer
, buffer_len
, "USB connected: %s", (usb_drv_connected() ? "Yes" : "No"));
729 snprintf(buffer
, buffer_len
, "HS mode: %s", (high_speed_mode
? "Yes" : "No"));
735 int n
= ep_index((selected_item
- 2) / 2, (selected_item
- 2) % 2);
736 if(endpoints
[n
].enabled
== false)
737 snprintf(buffer
, buffer_len
, "EP%d[%s]: DISABLED", epidx_n(n
), (epidx_dir(n
) ? "TX" : "RX"));
742 if(endpoints
[n
].out_in_progress
)
743 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
);
745 snprintf(buffer
, buffer_len
, "EP%d[TX]: STANDBY", epidx_n(n
));
749 if(endpoints
[n
].in_buf
&& !endpoints
[n
].in_ack
)
750 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
);
752 snprintf(buffer
, buffer_len
, "EP%d[RX]: STANDBY", epidx_n(n
));
761 void usb_drv_set_test_mode(int mode
)
763 logf("usb_drv_set_test_mode(%d)", mode
);
766 ISP1583_GEN_TSTMOD
= 0;
770 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_JSTATE
;
773 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_KSTATE
;
776 ISP1583_GEN_TSTMOD
= GEN_TSTMOD_SE0_NAK
;
779 //REG_PORTSC1 |= PORTSCX_PTC_PACKET;
782 //REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;