summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/drivers/m66591.c847
-rw-r--r--firmware/export/config-mrobe500.h16
-rw-r--r--firmware/export/config.h3
-rw-r--r--firmware/export/m66591.h102
-rw-r--r--firmware/target/arm/tms320dm320/boot.lds11
-rwxr-xr-xfirmware/target/arm/tms320dm320/crt0.S22
-rwxr-xr-xfirmware/target/arm/tms320dm320/mrobe-500/powermgmt-mr500.c8
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/usb-mr500.c74
-rw-r--r--firmware/target/arm/tms320dm320/system-dm320.c12
-rwxr-xr-xfirmware/target/arm/tms320dm320/system-target.h2
-rw-r--r--firmware/usb.c3
12 files changed, 1048 insertions, 56 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 3ee805eedd..f4705d9694 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -271,7 +271,9 @@ usbstack/usb_charging_only.c
271#ifdef USB_ENABLE_HID 271#ifdef USB_ENABLE_HID
272usbstack/usb_hid.c 272usbstack/usb_hid.c
273#endif 273#endif
274#if CONFIG_USBOTG == USBOTG_ARC 274#if CONFIG_USBOTG == USBOTG_M66591
275drivers/m66591.c
276#elif CONFIG_USBOTG == USBOTG_ARC
275target/arm/usb-drv-arc.c 277target/arm/usb-drv-arc.c
276#elif CONFIG_USBOTG == USBOTG_ISP1583 278#elif CONFIG_USBOTG == USBOTG_ISP1583
277drivers/isp1583.c 279drivers/isp1583.c
diff --git a/firmware/drivers/m66591.c b/firmware/drivers/m66591.c
new file mode 100644
index 0000000000..9a93985580
--- /dev/null
+++ b/firmware/drivers/m66591.c
@@ -0,0 +1,847 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: usb-mr500.c 18487 2008-09-10 20:14:22Z bertrik $
9 *
10 * Copyright (C) 2009 by Karl Kurbjun
11 * Portions Copyright (C) 2007 by Catalin Patulea
12 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#define LOGF_ENABLE
23
24#include "system.h"
25#include "config.h"
26#include "string.h"
27#include "usb_ch9.h"
28#include "usb_core.h"
29#include "kernel.h"
30#include "panic.h"
31#include "usb_drv.h"
32#include "logf.h"
33
34#include "config.h"
35#include "cpu.h"
36#include "ata.h"
37#include "usb.h"
38#include "usb-target.h"
39#include "m66591.h"
40
41/*******************************************************************************
42 * These are the driver specific defines.
43 ******************************************************************************/
44#define HISPEED
45
46/* Right now sending blocks till the full transfer has completed, this needs to
47 * be fixed so that it does not require a block. (USB_TRAN_LOCK ideally would
48 * not be set).
49 */
50#define USB_TRAN_BLOCK
51
52/*******************************************************************************
53 * The following functions are all helpers which should not be called directly
54 * from the USB stack. They should only be called by eachother, or the USB
55 * stack visible functions.
56 ******************************************************************************/
57
58static volatile unsigned short * pipe_ctrl_addr(int pipe);
59static void pipe_handshake(int pipe, int handshake);
60static void pipe_c_select (int pipe, bool dir);
61#if !defined(USB_TRAN_BLOCK)
62static int pipe_buffer_size (int pipe);
63#endif
64static int pipe_maxpack_size (int pipe);
65static void control_received(void);
66static void transfer_complete(int endpoint);
67static int mxx_transmit_receive(int endpoint);
68static int mxx_queue(int endpoint, void * ptr, int length, bool send);
69
70struct M66591_epstat {
71 unsigned char dir; /* endpoint direction */
72 char *buf; /* user buffer to store data */
73 int length; /* how match data will fit */
74 volatile int count; /* actual data count */
75 bool waiting; /* is there data to transfer? */
76 bool busy; /* has the pipe been requested for use? */
77} ;
78
79static struct M66591_epstat M66591_eps[USB_NUM_ENDPOINTS];
80
81/* This function is used to return the control address for each pipe */
82static volatile unsigned short * pipe_ctrl_addr(int pipe) {
83 if(pipe==0) {
84 return &M66591_DCPCTRL;
85 } else {
86 return &M66591_PIPECTRL1 + (pipe-1);
87 }
88}
89
90/* This function sets the pipe/endpoint handshake */
91static void pipe_handshake(int pipe, int handshake) {
92 handshake&=0x03;
93
94 if(handshake == PIPE_SHAKE_STALL) {
95 if( *(pipe_ctrl_addr(pipe)) & 0x03 ) {
96 *(pipe_ctrl_addr(pipe)) = 0x03;
97 } else {
98 *(pipe_ctrl_addr(pipe)) = 0x02;
99 }
100 } else {
101 *(pipe_ctrl_addr(pipe)) = handshake;
102 }
103}
104
105/* This function chooses the pipe desired and waits the required time before
106 * warites/reads are valid */
107static void pipe_c_select (int pipe, bool dir) {
108 M66591_CPORT_CTRL0 = pipe | (1<<10) | (dir<<5);
109
110 // Wait for the Pipe to be valid;
111 udelay(2);
112}
113
114#if !defined(USB_TRAN_BLOCK)
115/* This returns the maximum buffer size of each pipe. On this device the size
116 * is fixed.
117 */
118static int pipe_buffer_size (int pipe) {
119 switch(pipe) {
120 case 0:
121 return 256;
122 case 1:
123 case 2:
124 return 1024;
125 case 3:
126 case 4:
127 return 512;
128 case 5:
129 case 6:
130 return 64;
131 default:
132 return 0;
133 }
134}
135#endif
136
137/* This function returns the maximum packet size for each endpoint/pipe. It is
138 * Currently only setup to support Highspeed mode.
139 */
140static int pipe_maxpack_size (int pipe) {
141 switch(pipe) {
142 case 0:
143 /* DCP max packet size is configurable */
144 return M66591_DCP_MXPKSZ;
145 case 1:
146 case 2:
147 case 3:
148 case 4:
149 return 512;
150 case 5:
151 case 6:
152 return 64;
153 default:
154 return 0;
155 }
156}
157
158/* This is a helper function that is only called from the interupt handler. It
159 * copies the control packet information from the PHY and notifies the stack.
160 */
161static void control_received(void) {
162 /* copy setup data from packet */
163 static struct usb_ctrlrequest temp;
164
165 memcpy(&temp, (unsigned char*)&M66591_USB_REQ0, 8);
166
167 logf("mxx: bReqType=0x%02x bReq=0x%02x wVal=0x%04x"
168 " wIdx=0x%04x wLen=0x%04x",
169 temp.bRequestType, temp.bRequest, temp.wValue,
170 temp.wIndex, temp.wLength);
171
172 /* acknowledge packet recieved (clear valid) */
173 M66591_INTSTAT_MAIN &= ~(1<<3);
174
175 usb_core_control_request(&temp);
176}
177
178/* This is a helper function, it is used to notife the stack that a transfer is
179 * done.
180 */
181static void transfer_complete(int endpoint) {
182 M66591_INTCFG_EMP &= ~(1 << endpoint);
183 logf("mxx: ep %d transfer complete", endpoint);
184 int temp=M66591_eps[endpoint].dir ? USB_DIR_IN : USB_DIR_OUT;
185 usb_core_transfer_complete(endpoint, temp, 0,
186 M66591_eps[endpoint].length);
187}
188
189/* This is the main transmit routine that is typically called from the interrupt
190 * handler (the queue function calls it in some situations)
191 */
192static int mxx_transmit_receive(int endpoint) {
193 logf("mxx: do start");
194
195 /* Only the lower 15 bits of the endpoint correlate to the pipe number.
196 * For example pipe 2 will corelate to endpoint 0x82, so the upper bits
197 * need to be masked out.
198 */
199 endpoint &= 0x7F;
200
201 int i; /* Used as a loop counter */
202 int length; /* Used in transfers to determine the amount to send/receive */
203
204 bool send=M66591_eps[endpoint].dir;
205
206 /* This is used as the internal buffer pointer */
207 unsigned short *ptrs;
208
209 /* Choose the pipe that data is being transfered on */
210 pipe_c_select(endpoint, send);
211
212 /* Check to see if the endpoint is ready and give it some time to become
213 * ready. If it runs out of time exit out as an error.
214 */
215 i = 0;
216 while (!(M66591_CPORT_CTRL1&(1<<13))) {
217 if (i++ > 100000) {
218 logf("mxx: FIFO %d not ready", endpoint);
219 return -1;
220 }
221 }
222
223 /* Write to FIFO */
224 if(send) {
225 int maxpack=pipe_maxpack_size(endpoint);
226#if defined(USB_TRAN_BLOCK)
227 length = M66591_eps[endpoint].length;
228#else
229 int bufsize=pipe_buffer_size(endpoint);
230 length=MIN(M66591_eps[endpoint].length, bufsize);
231#endif
232
233 /* Calculate the position in the buffer, all transfers should be 2-byte
234 * aligned till the last packet or short packet.
235 */
236 ptrs = (unsigned short *)(M66591_eps[endpoint].buf
237 + M66591_eps[endpoint].count);
238
239 /* Start sending data in 16-bit words */
240 for (i = 0; i < (length>>1); i++) {
241 /* This wait is dangerous in the event htat something happens to
242 * the PHY pipe where it never becomes ready again, should probably
243 * add a timeout, and ideally completely remove.
244 */
245 while(!(M66591_CPORT_CTRL1&(1<<13))){};
246
247 M66591_CPORT = *ptrs++;
248 M66591_eps[endpoint].count+=2;
249 }
250
251 /* If the length is odd, send the last byte after setting the byte width
252 * of the FIFO.
253 */
254 if(length & 0x01) {
255 /* Unset MBW (8-bit transfer) */
256 M66591_CPORT_CTRL0 &= ~(1<<10);
257 M66591_CPORT = *((unsigned char *)ptrs - 1);
258 M66591_eps[endpoint].count++;
259 }
260
261 /* Set BVAL if length is not a multiple of the maximum packet size */
262 if( (length == 0) || (length % maxpack != 0) ) {
263 logf("mxx: do set BVAL");
264 M66591_CPORT_CTRL1 |= (1<<15);
265 }
266
267 /* If the transfer is complete set up interrupts to notify when FIFO is
268 * EMPTY, disable READY and let the handler know that there is nothing
269 * left to transfer on this pipe.
270 */
271 if(M66591_eps[endpoint].count == M66591_eps[endpoint].length) {
272 /* Enable Empty flag */
273 M66591_INTCFG_EMP |= 1 << endpoint;
274 /* Disable ready flag */
275 M66591_INTCFG_RDY &= ~(1 << endpoint);
276 /* Nothing left to transfer */
277 M66591_eps[endpoint].waiting=false;
278 } else {
279 /* There is still data to transfer, make sure READY is enabled */
280 M66591_INTCFG_RDY |= 1 << endpoint;
281 }
282 } else {
283 /* Read data from FIFO */
284
285 /* Read the number of bytes that the PHY received */
286 int receive_length=M66591_CPORT_CTRL1 & 0x03FF;
287
288 /* The number of bytes to actually read is either what's left of the
289 * amount requested, or the amount that the PHY received. Choose the
290 * smaller of the two.
291 */
292 length = MIN(M66591_eps[endpoint].length - M66591_eps[endpoint].count,
293 receive_length);
294
295 /* If the length is zero, just clear the buffer as specified in the
296 * datasheet. Otherwise read in the data (in 16-bit pieces */
297 if(length==0) {
298 /* Set the BCLR bit */
299 M66591_CPORT_CTRL1 |= 1<<14;
300 } else {
301 /* Set the position in the buffer */
302 ptrs = (unsigned short *)(M66591_eps[endpoint].buf
303 + M66591_eps[endpoint].count);
304
305 /* Read in the data (buffer size should be even). The PHY cannot
306 * switch from 16-bit mode to 8-bit mode on an OUT buffer.
307 */
308 for (i = 0; i < ((length+1)>>1); i++) {
309 *ptrs++ = M66591_CPORT;
310 M66591_eps[endpoint].count+=2;
311 }
312 }
313
314 /* If the length was odd subtract 1 from the count */
315 M66591_eps[endpoint].count -= (length&0x01);
316
317 /* If the requested size of data was received, or the data received was
318 * less than the maximum packet size end the transfer.
319 */
320 if( (M66591_eps[endpoint].count == M66591_eps[endpoint].length)
321 || (length % pipe_maxpack_size(endpoint)) ) {
322
323 /* If the host tries to send anything else the FIFO is not ready/
324 * enabled yet (NAK).
325 */
326 pipe_handshake(endpoint, PIPE_SHAKE_NAK);
327 /* Tell the interrupt handler that transfer is complete. */
328 M66591_eps[endpoint].waiting=false;
329 /* Disable ready */
330 M66591_INTCFG_RDY &= ~(1 << endpoint);
331
332 /* Let the stack know that the transfer is complete */
333 if(endpoint!=0)
334 transfer_complete(endpoint);
335 }
336 }
337
338 logf("mxx: do done ep %d %s len: %d cnt: %d", endpoint,
339 send ? "out" : "in", length, M66591_eps[endpoint].count);
340
341 return 0;
342}
343
344/* This function is used to start transfers. It is a helper function for the
345 * usb_drv_send_nonblocking, usb_drv_send, and usb_drv_receive functions.
346 */
347static int mxx_queue(int endpoint, void * ptr, int length, bool send) {
348 /* Disable IRQs */
349 int flags = disable_irq_save();
350
351 /* Only the lower 15 bits of the endpoint correlate to the pipe number.
352 * For example pipe 2 will corelate to endpoint 0x82, so the upper bits
353 * need to be masked out.
354 */
355 endpoint &= 0x7F;
356
357 /* Initialize the enpoint status registers used for the transfer */
358 M66591_eps[endpoint].buf=ptr;
359 M66591_eps[endpoint].length=length;
360 M66591_eps[endpoint].count=0;
361 M66591_eps[endpoint].dir=send;
362 M66591_eps[endpoint].waiting=true;
363
364 logf("mxx: queue ep %d %s, len: %d", endpoint, send ? "out" : "in", length);
365
366 /* Pick the pipe that communications are happening on */
367 pipe_c_select(endpoint, send);
368
369 /* All transfers start with a BUF handshake */
370 pipe_handshake(endpoint, PIPE_SHAKE_BUF);
371
372 /* This USB PHY takes care of control completion packets by setting the
373 * CCPL bit in EP0 (endpoint 0, or DCP). If the control state is "write no
374 * data tranfer" then we just need to set the CCPL bit (hopefully)
375 * regardless of what the stack said to send.
376 */
377 int control_state = (M66591_INTSTAT_MAIN & 0x07);
378 if(endpoint==0 && control_state==CTRL_WTND) {
379 logf("mxx: queue ep 0 ctls: 5, set ccpl");
380
381 /* Set CCPL */
382 M66591_DCPCTRL |= 1<<2;
383 } else {
384 /* This is the standard case for transmitting data */
385 if(send) {
386 /* If the pipe is not ready don't try and send right away; instead
387 * just set the READY interrupt so that the handler can initiate
388 * the transfer.
389 */
390 if((M66591_CPORT_CTRL1&(1<<13))) {
391 mxx_transmit_receive(endpoint);
392 } else {
393 M66591_INTCFG_RDY |= 1 << endpoint;
394 }
395
396 if(length==0) {
397 transfer_complete(endpoint);
398 }
399 } else {
400 /* When receiving data, just enable the ready interrupt, the PHY
401 * will trigger it and then the reads can start.
402 */
403 M66591_INTCFG_RDY |= 1 << endpoint;
404 }
405 }
406
407 /* Re-enable IRQs */
408 restore_irq(flags);
409 return 0;
410}
411
412/*******************************************************************************
413 * This is the interrupt handler for this driver. It should be called from the
414 * target interrupt handler routine (eg. GPIO3 on M:Robe 500).
415 ******************************************************************************/
416void USB_DEVICE(void) {
417 int pipe_restore=M66591_CPORT_CTRL0;
418 logf("mxx: INT BEGIN tick: %d\n", (int) current_tick);
419
420 logf("mxx: sMAIN0: 0x%04x, sRDY: 0x%04x",
421 M66591_INTSTAT_MAIN, M66591_INTSTAT_RDY);
422 logf("mxx: sNRDY: 0x%04x, sEMP: 0x%04x",
423 M66591_INTSTAT_NRDY, M66591_INTSTAT_EMP);
424
425 /* VBUS (connected) interrupt */
426 while ( M66591_INTSTAT_MAIN & (1<<15) ) {
427 M66591_INTSTAT_MAIN &= ~(1<<15);
428
429 /* If device is not clocked, interrupt flag must be set manually */
430 if ( !(M66591_TRN_CTRL & (1<<10)) ) {
431 M66591_INTSTAT_MAIN |= (1<<15);
432 }
433 }
434
435 /* Resume interrupt: This is not used. Extra logic needs to be added similar
436 * to the VBUS interrupt incase the PHY clock is not running.
437 */
438 if(M66591_INTSTAT_MAIN & (1<<14)) {
439 M66591_INTSTAT_MAIN &= ~(1<<14);
440 logf("mxx: RESUME");
441 }
442
443 /* Device state transition interrupt: Not used, but useful for debugging */
444 if(M66591_INTSTAT_MAIN & (1<<12)) {
445 M66591_INTSTAT_MAIN &= ~(1<<12);
446 logf("mxx: DEV state CHANGE=%d",
447 ((M66591_INTSTAT_MAIN & (0x07<<4)) >> 4) );
448 }
449
450 /* Control transfer stage interrupt */
451 if(M66591_INTSTAT_MAIN & (1<<11)) {
452 M66591_INTSTAT_MAIN &= ~(1<<11);
453 int control_state = (M66591_INTSTAT_MAIN & 0x07);
454
455 logf("mxx: CTRT with CTSQ=%d", control_state);
456
457 switch ( control_state ) {
458 case CTRL_IDLE:
459 transfer_complete(0);
460 break;
461 case CTRL_RTDS:
462 case CTRL_WTDS:
463 case CTRL_WTND:
464 // If data is not valid stop
465 if(!(M66591_INTSTAT_MAIN & (1<<3)) ) {
466 logf("mxx: CTRT interrupt but VALID is false");
467 break;
468 }
469 control_received();
470 break;
471 case CTRL_RTSS:
472 case CTRL_WTSS:
473 pipe_handshake(0, PIPE_SHAKE_BUF);
474 M66591_DCPCTRL |= 1<<2; // Set CCPL
475 break;
476 default:
477 logf("mxx: CTRT with unknown CTSQ");
478 break;
479 }
480 }
481
482 /* FIFO EMPTY interrupt: when this happens the transfer should be complete.
483 * When the interrupt occurs notify the stack.
484 */
485 if(M66591_INTSTAT_MAIN & (1<<10)) {
486 int i;
487 logf("mxx: INT EMPTY: 0x%04x", M66591_INTSTAT_EMP);
488
489 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
490 if(M66591_INTSTAT_EMP&(1<<i)) {
491 /* Clear the empty flag */
492 M66591_INTSTAT_EMP=~(1<<i);
493 /* Notify the stack */
494 transfer_complete(i);
495 }
496 }
497 }
498
499 /* FIFO NOT READY interrupt: This is not used, but included incase the
500 * interrupt is endabled.
501 */
502 if(M66591_INTSTAT_MAIN & (1<<9)) {
503 logf("mxx: INT NOT READY: 0x%04x", M66591_INTSTAT_NRDY);
504 M66591_INTSTAT_NRDY = 0;
505 }
506
507 /* FIFO READY interrupt: This just initiates transfers if they are needed */
508 if(M66591_INTSTAT_MAIN & (1<<8)) {
509 int i;
510 logf("mxx: INT READY: 0x%04x", M66591_INTSTAT_RDY);
511
512 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
513 /* Was this endpoint ready and waiting */
514 if(M66591_INTSTAT_RDY&(1<<i) && M66591_eps[i].waiting) {
515 /* Clear the ready flag */
516 M66591_INTSTAT_RDY=~(1<<i);
517 /* It was ready and waiting so start a transfer */
518 mxx_transmit_receive(i);
519 }
520 }
521 }
522
523 /* Make sure that the INTStatus register is completely cleared. */
524 M66591_INTSTAT_MAIN = 0;
525
526 /* Restore the pipe state before the interrupt occured */
527 M66591_CPORT_CTRL0=pipe_restore;
528 logf("\nmxx: INT END");
529}
530
531/*******************************************************************************
532 * The following functions are all called by and visible to the USB stack.
533 ******************************************************************************/
534
535/* The M55691 handles this automatically, nothing to do */
536void usb_drv_set_address(int address) {
537 (void) address;
538}
539
540/* This function sets the standard test modes, it is not required, but might as
541 * well implement it since the hardware supports it
542 */
543void usb_drv_set_test_mode(int mode) {
544 /* This sets the test bits and assumes that mode is from 0 to 0x04 */
545 M66591_TESTMODE &= 0x0007;
546 M66591_TESTMODE |= mode;
547}
548
549/* Request an unused endpoint, support for interrupt endpoints needs addition */
550int usb_drv_request_endpoint(int type, int dir) {
551 int ep;
552 int pipecfg = 0;
553
554 if (type != USB_ENDPOINT_XFER_BULK)
555 return -1;
556
557 /* The endpoint/pipes are hard coded: This could be more flexible */
558 if (dir == USB_DIR_IN) {
559 pipecfg |= (1<<4);
560 ep = 2;
561 } else {
562 ep = 1;
563 }
564
565 if (!M66591_eps[ep].busy) {
566 M66591_eps[ep].busy = true;
567 M66591_eps[ep].dir = dir;
568 } else {
569 logf("mxx: ep %d busy", ep);
570 return -1;
571 }
572
573 M66591_PIPE_CFGSEL=ep;
574
575 pipecfg |= 1<<15 | 1<<9 | 1<<8;
576
577 pipe_handshake(ep, PIPE_SHAKE_NAK);
578
579 // Setup the flags
580 M66591_PIPE_CFGWND=pipecfg;
581
582 logf("mxx: ep req ep#: %d config: 0x%04x", ep, M66591_PIPE_CFGWND);
583
584 return ep | dir;
585}
586
587/* Used by stack to tell the helper functions that the pipe is not in use */
588void usb_drv_release_endpoint(int ep) {
589 int flags;
590 ep &= 0x7f;
591
592 if (ep < 1 || ep > USB_NUM_ENDPOINTS || M66591_eps[ep].busy == false)
593 return ;
594
595 flags = disable_irq_save();
596
597 logf("mxx: ep %d release", ep);
598
599 M66591_eps[ep].busy = false;
600 M66591_eps[ep].dir = -1;
601
602 restore_irq(flags);
603}
604
605/* Periodically called to check if a cable was plugged into the device */
606inline int usb_detect(void)
607{
608 if(M66591_INTSTAT_MAIN&(1<<7))
609 return USB_INSERTED;
610 else
611 return USB_EXTRACTED;
612}
613
614void usb_enable(bool on) {
615 logf("mxx: %s: %s", __FUNCTION__, on ? "true" : "false");
616 if (on)
617 usb_core_init();
618 else
619 usb_core_exit();
620}
621
622/* This is where the driver stuff starts */
623void usb_drv_init(void) {
624 logf("mxx: Device Init");
625
626 /* State left behind by m:robe 500i original firmware */
627 M66591_TRN_CTRL = 0x8001; /* External 48 MHz clock */
628 M66591_TRN_LNSTAT = 0x0040; /* "Reserved. Set it to '1'." */
629
630 M66591_PIN_CFG0 = 0x0000;
631 M66591_PIN_CFG1 = 0x8000; /* Drive Current: 3.3V setting */
632 M66591_PIN_CFG2 = 0x0000;
633
634 M66591_INTCFG_MAIN = 0x0000; /* All Interrupts Disable for now */
635 M66591_INTCFG_OUT = 0x0000; /* Sense is edge, polarity is low */
636 M66591_INTCFG_RDY = 0x0000;
637 M66591_INTCFG_NRDY = 0x0000;
638 M66591_INTCFG_EMP = 0x0000;
639
640 M66591_INTSTAT_MAIN = 0;
641 M66591_INTSTAT_RDY = 0;
642 M66591_INTSTAT_NRDY = 0;
643 M66591_INTSTAT_EMP = 0;
644}
645
646/* fully enable driver */
647void usb_attach(void) {
648 int i;
649
650 /* Reset Endpoint states */
651 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
652 M66591_eps[i].dir = -1;
653 M66591_eps[i].buf = (char *) 0;
654 M66591_eps[i].length = 0;
655 M66591_eps[i].count = 0;
656 M66591_eps[i].waiting = false;
657 M66591_eps[i].busy = false;
658 }
659
660 /* Issue a h/w reset */
661 usb_init_device();
662 usb_drv_init();
663
664 /* USB Attach Process: This follows the flow diagram in the M66591GP
665 * Reference Manual Rev 1.00, p. 77 */
666
667#if defined(HISPEED)
668 /* Run Hi-Speed */
669 M66591_TRN_CTRL |= 1<<7;
670#else
671 /* Run Full-Speed */
672 M66591_TRN_CTRL &= ~(1<<7);
673#endif
674
675 /* Enable oscillation buffer */
676 M66591_TRN_CTRL |= (1<<13);
677
678 udelay(1500);
679
680 /* Enable reference clock, PLL */
681 M66591_TRN_CTRL |= (3<<11);
682
683 udelay(9);
684
685 /* Enable internal clock supply */
686 M66591_TRN_CTRL |= (1<<10);
687
688 /* Disable PIPE ready interrupts */
689 M66591_INTCFG_RDY = 0;
690
691 /* Disable PIPE not-ready interrupts */
692 M66591_INTCFG_NRDY = 0;
693
694 /* Disable PIPE empyt/size error interrupts */
695 M66591_INTCFG_EMP = 0;
696
697 /* Enable all interrupts except NOT READY, RESUME, and VBUS */
698 M66591_INTCFG_MAIN = 0x1DFF;
699
700 pipe_c_select(0, false);
701
702 /* Enable continuous transfer mode on the DCP */
703 M66591_DCP_CNTMD |= (1<<8);
704
705 /* Set the threshold that the PHY will automatically transmit from EP0 */
706 M66591_DCP_CTRLEN = 128;
707
708 pipe_handshake(0, PIPE_SHAKE_NAK);
709
710 /* Set the Max packet size to 64 */
711 M66591_DCP_MXPKSZ = 64;
712
713 /* Attach notification to PC (D+ pull-up) */
714 M66591_TRN_CTRL |= (1<<4);
715
716 logf("mxx: attached");
717}
718
719void usb_drv_exit(void) {
720 /* USB Detach Process: This follows the flow diagram in the M66591GP
721 * Reference Manual Rev 1.00, p. 78.
722 */
723
724 /* Detach notification to PC (disable D+ pull-up) */
725 M66591_TRN_CTRL &= ~(1<<4);
726
727 /* Software reset */
728 M66591_TRN_CTRL &= ~0x01;
729
730 /* Disable internal clock supply */
731 M66591_TRN_CTRL &= ~(1<<10);
732 udelay(3);
733
734 /* Disable PLL */
735 M66591_TRN_CTRL &= ~(1<<11);
736 udelay(3);
737
738 /* Disable internal reference clock */
739 M66591_TRN_CTRL &= ~(1<<12);
740 udelay(3);
741
742 /* Disable oscillation buffer, reenable USB operation */
743 M66591_TRN_CTRL &= ~(1<<13);
744
745 M66591_TRN_CTRL |= 0x01;
746
747 logf("mxx: detached");
748}
749
750/* This function begins a transmit (on an IN endpoint), it should not block
751 * so the actual transmit is done in the interrupt handler.
752 */
753int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
754{
755 /* The last arguement for queue specifies the dir of data (true==send) */
756 return mxx_queue(endpoint, ptr, length, true);
757}
758
759/* This function begins a transmit (on an IN endpoint), it does not block
760 * so the actual transmit is done in the interrupt handler.
761 */
762int usb_drv_send(int endpoint, void* ptr, int length)
763{
764 /* The last arguement for queue specifies the dir of data (true==send) */
765 return mxx_queue(endpoint, ptr, length, true);
766}
767
768/* This function begins a receive (on an OUT endpoint), it should not block
769 * so the actual receive is done in the interrupt handler.
770 */
771int usb_drv_recv(int endpoint, void* ptr, int length)
772{
773 /* Last arguement for queue specifies the dir of data (false==receive) */
774 return mxx_queue(endpoint, ptr, length, false);
775}
776
777/* This function checks the reset handshake speed status
778 * (Fullspeed or Highspeed)
779 */
780int usb_drv_port_speed(void)
781{
782 int handshake = (M66591_HSFS & 0xFF);
783
784 if( handshake == 0x02) {
785 return 0; /* Handshook at Full-Speed */
786 } else if( handshake == 0x03) {
787 return 1; /* Handshook at Hi-Speed */
788 } else {
789 return -1; /* Error, handshake may not be complete */
790 }
791}
792
793/* This function checks if the endpoint is stalled (error). I am not sure what
794 * the "in" variable is intended for.
795 */
796bool usb_drv_stalled(int endpoint,bool in)
797{
798 (void) in;
799
800 bool stalled = (*(pipe_ctrl_addr(endpoint)) & (0x02)) ? true : false;
801
802 logf("mxx: stall?: %s ep: %d", stalled ? "true" : "false", endpoint);
803
804 if(stalled) {
805 return true;
806 } else {
807 return false;
808 }
809}
810
811/* This function stalls/unstalls the endpoint. Stalls only happen on error so
812 * if the endpoint is functioning properly this should not be called. I am
813 * not sure what the "in" variable is intended for.
814 */
815void usb_drv_stall(int endpoint, bool stall,bool in)
816{
817 (void) in;
818
819 logf("mxx: stall - ep: %d", endpoint);
820
821 if(stall) {
822 /* Stall the pipe (host needs to intervene/error) */
823 pipe_handshake(endpoint, PIPE_SHAKE_STALL);
824 } else {
825 /* Setting this to a NAK, not sure if it is appropriate */
826 pipe_handshake(endpoint, PIPE_SHAKE_NAK);
827 }
828}
829
830/* !!!!!!!!!!This function is likely incomplete!!!!!!!!!!!!!! */
831void usb_drv_cancel_all_transfers(void)
832{
833 int endpoint;
834 int flags;
835
836 logf("mxx: %s", __func__);
837
838 flags = disable_irq_save();
839 for (endpoint = 0; endpoint < USB_NUM_ENDPOINTS; endpoint++) {
840 if (M66591_eps[endpoint].buf) {
841 M66591_eps[endpoint].buf = NULL;
842 }
843 }
844
845 restore_irq(flags);
846}
847
diff --git a/firmware/export/config-mrobe500.h b/firmware/export/config-mrobe500.h
index f9e8d9ebf6..619e3fe8e7 100644
--- a/firmware/export/config-mrobe500.h
+++ b/firmware/export/config-mrobe500.h
@@ -35,6 +35,9 @@
35/* define this if you use an ATA controller */ 35/* define this if you use an ATA controller */
36#define CONFIG_STORAGE STORAGE_ATA 36#define CONFIG_STORAGE STORAGE_ATA
37 37
38/* Define this to add support for ATA DMA */
39//#define HAVE_ATA_DMA
40
38/* define this if you have a bitmap LCD display */ 41/* define this if you have a bitmap LCD display */
39#define HAVE_LCD_BITMAP 42#define HAVE_LCD_BITMAP
40 43
@@ -114,6 +117,19 @@
114#define HAVE_TOUCHSCREEN 117#define HAVE_TOUCHSCREEN
115#define HAVE_BUTTON_DATA 118#define HAVE_BUTTON_DATA
116 119
120/* M66591 register base */
121#define M66591_BASE 0x60000000
122
123/* enable these for the usb stack */
124#define CONFIG_USBOTG USBOTG_M66591
125#define USE_ROCKBOX_USB
126#define HAVE_USBSTACK
127#define USB_STORAGE
128/* usb stack and driver settings */
129#define USB_NUM_ENDPOINTS 7
130#define USB_VENDOR_ID 0x07b4
131#define USB_PRODUCT_ID 0x0281
132
117/* define this if the target has volume keys which can be used in the lists */ 133/* define this if the target has volume keys which can be used in the lists */
118#define HAVE_VOLUME_IN_LIST 134#define HAVE_VOLUME_IN_LIST
119 135
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 5cdf46dcfd..696c923bb6 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -250,6 +250,7 @@ Lyre prototype 1*/
250#define RTC_JZ47XX 16 /* Ingenic Jz47XX */ 250#define RTC_JZ47XX 16 /* Ingenic Jz47XX */
251 251
252/* USB On-the-go */ 252/* USB On-the-go */
253#define USBOTG_M66591 6591 /* M:Robe 500 */
253#define USBOTG_ISP1362 1362 /* iriver H300 */ 254#define USBOTG_ISP1362 1362 /* iriver H300 */
254#define USBOTG_ISP1583 1583 /* Creative Zen Vision:M */ 255#define USBOTG_ISP1583 1583 /* Creative Zen Vision:M */
255#define USBOTG_M5636 5636 /* iAudio X5 */ 256#define USBOTG_M5636 5636 /* iAudio X5 */
@@ -775,7 +776,7 @@ Lyre prototype 1*/
775#elif CONFIG_USBOTG == USBOTG_JZ4740 776#elif CONFIG_USBOTG == USBOTG_JZ4740
776#define USB_HAS_BULK 777#define USB_HAS_BULK
777#define USB_HAS_INTERRUPT 778#define USB_HAS_INTERRUPT
778#elif defined(CPU_TCC780X) || defined(CPU_TCC77X) 779#elif defined(CPU_TCC780X) || defined(CPU_TCC77X) || defined(MROBE_500)
779#define USB_HAS_BULK 780#define USB_HAS_BULK
780#endif /* CONFIG_USBOTG */ 781#endif /* CONFIG_USBOTG */
781 782
diff --git a/firmware/export/m66591.h b/firmware/export/m66591.h
new file mode 100644
index 0000000000..db7776e45f
--- /dev/null
+++ b/firmware/export/m66591.h
@@ -0,0 +1,102 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2009 by Karl Kurbjun
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23
24#define M66591_REG(addr) (*(volatile unsigned short *) \
25 ((unsigned char *) M66591_BASE + (addr)) )
26
27/* Interrupt handler routine, visible for target handler */
28void USB_DEVICE(void);
29
30/* Register offsets */
31#define M66591_TRN_CTRL M66591_REG(0x00) /* pg 14 */
32#define M66591_TRN_LNSTAT M66591_REG(0x02) /* pg 16 */
33
34#define M66591_HSFS M66591_REG(0x04) /* pg 17 */
35#define M66591_TESTMODE M66591_REG(0x06) /* pg 18 */
36
37#define M66591_PIN_CFG0 M66591_REG(0x08) /* pg 19 */
38#define M66591_PIN_CFG1 M66591_REG(0x0A) /* pg 20 */
39#define M66591_PIN_CFG2 M66591_REG(0x0C) /* pg 21 */
40
41#define M66591_CPORT M66591_REG(0x14) /* pg 23 */
42#define M66591_DPORT M66591_REG(0x18) /* pg 24 */
43
44#define M66591_DCP_CTRLEN M66591_REG(0x26) /* pg 25 */
45
46#define M66591_CPORT_CTRL0 M66591_REG(0x28) /* pg 26 */
47#define M66591_CPORT_CTRL1 M66591_REG(0x2C) /* pg 28 */
48#define M66591_CPORT_CTRL2 M66591_REG(0x2E) /* pg 30 */
49
50#define M66591_DPORT_CTRL0 M66591_REG(0x30) /* pg 31 */
51#define M66591_DPORT_CTRL1 M66591_REG(0x34) /* pg 34 */
52#define M66591_DPORT_CTRL2 M66591_REG(0x36) /* pg 36 */
53
54#define M66591_INTCFG_MAIN M66591_REG(0x40) /* pg 37 */
55#define M66591_INTCFG_OUT M66591_REG(0x42) /* pg 40 */
56#define M66591_INTCFG_RDY M66591_REG(0x44) /* pg 41 */
57#define M66591_INTCFG_NRDY M66591_REG(0x48) /* pg 42 */
58#define M66591_INTCFG_EMP M66591_REG(0x4C) /* pg 43 */
59
60#define M66591_INTSTAT_MAIN M66591_REG(0x60) /* pg 44 */
61#define M66591_INTSTAT_RDY M66591_REG(0x64) /* pg 48 */
62#define M66591_INTSTAT_NRDY M66591_REG(0x68) /* pg 50 */
63#define M66591_INTSTAT_EMP M66591_REG(0x6C) /* pg 53 */
64
65#define M66591_USB_ADDRESS M66591_REG(0x74) /* pg 56 */
66
67#define M66591_USB_REQ0 M66591_REG(0x78) /* pg 57 */
68#define M66591_USB_REQ1 M66591_REG(0x7A) /* pg 58 */
69#define M66591_USB_REQ2 M66591_REG(0x7C) /* pg 59 */
70#define M66591_USB_REQ3 M66591_REG(0x7E) /* pg 60 */
71
72#define M66591_DCP_CNTMD M66591_REG(0x82) /* pg 61 */
73#define M66591_DCP_MXPKSZ M66591_REG(0x84) /* pg 62 */
74#define M66591_DCPCTRL M66591_REG(0x88) /* pg 63 */
75
76#define M66591_PIPE_CFGSEL M66591_REG(0x8C) /* pg 65 */
77#define M66591_PIPE_CFGWND M66591_REG(0x90) /* pg 66 */
78
79#define M66591_PIPECTRL1 M66591_REG(0xA0) /* pg 69 */
80#define M66591_PIPECTRL2 M66591_REG(0xA2) /* pg 69 */
81#define M66591_PIPECTRL3 M66591_REG(0xA4) /* pg 69 */
82#define M66591_PIPECTRL4 M66591_REG(0xA6) /* pg 69 */
83#define M66591_PIPECTRL5 M66591_REG(0xA8) /* pg 71 */
84#define M66591_PIPECTRL6 M66591_REG(0xAA) /* pg 71 */
85
86/* These defines are used for CTRL register handshake setup
87 * They are used on the following registers:
88 * DCPCTRL and PIPECTRL(1-6)
89 */
90#define PIPE_SHAKE_NAK 0x00
91#define PIPE_SHAKE_BUF 0x01
92#define PIPE_SHAKE_STALL 0x02
93
94/* These defines are used for the control transfer stage status */
95#define CTRL_IDLE 0x00 /* Idle Stage */
96#define CTRL_RTDS 0x01 /* Read transfer data stage */
97#define CTRL_RTSS 0x02 /* Read transfer status stage */
98#define CTRL_WTDS 0x03 /* Write transfer data stage */
99#define CTRL_WTSS 0x04 /* Write transfer status stage */
100#define CTRL_WTND 0x05 /* Write transfer no data stage */
101#define CTRL_TRER 0x06 /* Transmit error stage */
102
diff --git a/firmware/target/arm/tms320dm320/boot.lds b/firmware/target/arm/tms320dm320/boot.lds
index ff8203ccd8..0ee6c202a4 100644
--- a/firmware/target/arm/tms320dm320/boot.lds
+++ b/firmware/target/arm/tms320dm320/boot.lds
@@ -138,9 +138,20 @@ SECTIONS
138 . += TTB_SIZE; 138 . += TTB_SIZE;
139 } > DRAM 139 } > DRAM
140 140
141 /* The LCD buffer should be at the end of memory to protect against
142 * overflowing something else when the YUV blitter is fudging the screen
143 * size.
144 */
145
141 .lcdbuffer (NOLOAD) : 146 .lcdbuffer (NOLOAD) :
142 { 147 {
143 _lcdbuf = .; 148 _lcdbuf = .;
144 . += LCD_BUFFER_SIZE; 149 . += LCD_BUFFER_SIZE;
145 } > DRAM 150 } > DRAM
151
152 .lcdbuffer2 (NOLOAD) :
153 {
154 _lcdbuf2 = .;
155 . += LCD_BUFFER_SIZE;
156 } > DRAM
146} 157}
diff --git a/firmware/target/arm/tms320dm320/crt0.S b/firmware/target/arm/tms320dm320/crt0.S
index 0243c13971..7c0c27eb74 100755
--- a/firmware/target/arm/tms320dm320/crt0.S
+++ b/firmware/target/arm/tms320dm320/crt0.S
@@ -75,7 +75,7 @@ start:
75 strhi r5, [r3], #4 75 strhi r5, [r3], #4
76 bhi 1b 76 bhi 1b
77#endif 77#endif
78#endif /* !BOOTLOADER,!STUB */ 78#endif /* !STUB */
79 79
80 80
81 /* Initialise bss section to zero */ 81 /* Initialise bss section to zero */
@@ -113,26 +113,6 @@ stackmunge:
113 /* Switch to supervisor mode (no IRQ) */ 113 /* Switch to supervisor mode (no IRQ) */
114 msr cpsr_c, #0xd3 114 msr cpsr_c, #0xd3
115 ldr sp, =stackend 115 ldr sp, =stackend
116
117#if defined(BOOTLOADER) && !defined(CREATIVE_ZVx)
118 /* get the high part of our execute address */
119 ldr r2, =0xffffff00
120 and r4, pc, r2
121
122 /* Copy bootloader to safe area - 0x01900000 */
123 mov r5, #0x01900000
124 ldr r6, = _dataend
125 sub r0, r6, r5 /* length of loader */
126 add r0, r4, r0 /* r0 points to start of loader */
1271:
128 cmp r5, r6
129 ldrcc r2, [r4], #4
130 strcc r2, [r5], #4
131 bcc 1b
132
133 ldr pc, =start_loc /* jump to the relocated start_loc: */
134
135#endif
136 116
137start_loc: 117start_loc:
138 bl main 118 bl main
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/powermgmt-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/powermgmt-mr500.c
index b81c34ac3b..6e361aac15 100755
--- a/firmware/target/arm/tms320dm320/mrobe-500/powermgmt-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/powermgmt-mr500.c
@@ -25,9 +25,9 @@
25#include "tsc2100.h" 25#include "tsc2100.h"
26#include "kernel.h" 26#include "kernel.h"
27 27
28unsigned short current_bat2 = 3910; 28unsigned short current_bat2 = 4200;
29unsigned short current_aux = 3910; 29unsigned short current_aux = 4200;
30static unsigned short current_voltage = 3910; 30static unsigned short current_voltage = 4200;
31const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = 31const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
32{ 32{
33 3450 33 3450
@@ -69,7 +69,7 @@ unsigned int battery_adc_voltage(void)
69 current_aux=((short)((int)(aux<<10)/4096*6*2.5)); 69 current_aux=((short)((int)(aux<<10)/4096*6*2.5));
70 } 70 }
71 71
72 if (TIME_BEFORE(last_tick+2*HZ, current_tick)) 72 if (TIME_BEFORE(last_tick+2*HZ, current_tick) || last_tick==0)
73 { 73 {
74 tsadc=tsc2100_readreg(TSADC_PAGE, TSADC_ADDRESS); 74 tsadc=tsc2100_readreg(TSADC_PAGE, TSADC_ADDRESS);
75 75
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/usb-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/usb-mr500.c
index 41211c2b47..2e3518868b 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/usb-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/usb-mr500.c
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2007 by Karl Kurbjun 10 * Copyright (C) 2007, 2009 by Karl Kurbjun
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -18,42 +18,60 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#define LOGF_ENABLE
21 22
22#include "config.h" 23#include "config.h"
24#include "logf.h"
23#include "cpu.h" 25#include "cpu.h"
24#include "system.h" 26#include "system.h"
25#include "kernel.h"
26#include "ata.h"
27#include "usb.h"
28#include "usb-target.h"
29 27
30#define USB_RST_ASSERT 28#include "m66591.h"
31#define USB_RST_DEASSERT
32 29
33#define USB_VPLUS_PWR_ASSERT 30void usb_init_device(void) {
34#define USB_VPLUS_PWR_DEASSERT 31 logf("mxx: SOC Init");
35 32
36#define USB_UNIT_IS_PRESENT USB_EXTRACTED 33 /* The EMIF timing that is currently used may not be apropriate when the
34 * device is boosted. The following values were used with sucess too:
35 * IO_EMIF_CS4CTRL1 = 0x66AB;
36 * IO_EMIF_CS4CTRL2 = 0x4220;
37 */
38 IO_EMIF_CS4CTRL1 = 0x2245;
39 IO_EMIF_CS4CTRL2 = 0x4110;
37 40
38/* The usb detect is one pin to the cpu active low */ 41 IO_GIO_DIR0 &= ~(1<<2);
39inline int usb_detect(void) 42 IO_GIO_INV0 &= ~(1<<2);
40{ 43 IO_GIO_FSEL0 &= ~(0x03);
41 return USB_UNIT_IS_PRESENT; 44
42} 45 /* Drive the reset pin low */
46 IO_GIO_BITCLR0 = 1<<2;
47
48 /* Wait a bit */
49 udelay(3);
43 50
44void usb_init_device(void) 51 /* Release the reset (drive it high) */
45{ 52 IO_GIO_BITSET0 = 1<<2;
46// ata_enable(true); 53
54 udelay(300);
55
56 IO_GIO_DIR0 |= 1<<3;
57 IO_GIO_INV0 &= ~(1<<3);
58 IO_GIO_IRQPORT |= 1<<3;
59
60 /* Enable the MXX interrupt */
61 IO_INTC_EINT1 |= (1<<8); /* IRQ_GIO3 */
47} 62}
48 63
49void usb_enable(bool on) 64/* This is the initial interupt handler routine for the USB controller */
50{ 65void GIO3 (void) {
51 if (on) 66 /* Clear the interrupt, this is critical to do before running the full
52 { 67 * handler otherwise you might miss an interrupt and everything will stop
53 USB_VPLUS_PWR_ASSERT; 68 * working.
54 } 69 *
55 else 70 * The M66591 interrupt line is attached to GPIO3.
56 { 71 */
57 USB_VPLUS_PWR_DEASSERT; 72 IO_INTC_IRQ1 = (1<<8);
58 } 73
74 /* Start the full handler which is located in the driver */
75 USB_DEVICE();
59} 76}
77
diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c
index b8c9eee87f..8742f59691 100644
--- a/firmware/target/arm/tms320dm320/system-dm320.c
+++ b/firmware/target/arm/tms320dm320/system-dm320.c
@@ -28,6 +28,7 @@
28#include "spi.h" 28#include "spi.h"
29#ifdef CREATIVE_ZVx 29#ifdef CREATIVE_ZVx
30#include "dma-target.h" 30#include "dma-target.h"
31#include "usb-mr500.h"
31#endif 32#endif
32 33
33#define default_interrupt(name) \ 34#define default_interrupt(name) \
@@ -308,3 +309,14 @@ void set_cpu_frequency(long frequency)
308} 309}
309#endif 310#endif
310 311
312/* This function is pretty crude. It is not acurate to a usec, but errors on
313 * longer.
314 */
315void udelay(int usec) {
316 volatile int temp=usec*(175000/200);
317
318 while(temp) {
319 temp--;
320 }
321}
322
diff --git a/firmware/target/arm/tms320dm320/system-target.h b/firmware/target/arm/tms320dm320/system-target.h
index 63d314f572..285dd0275f 100755
--- a/firmware/target/arm/tms320dm320/system-target.h
+++ b/firmware/target/arm/tms320dm320/system-target.h
@@ -28,4 +28,6 @@
28#define CPUFREQ_NORMAL 87500000 28#define CPUFREQ_NORMAL 87500000
29#define CPUFREQ_MAX 175000000 29#define CPUFREQ_MAX 175000000
30 30
31void udelay(int usec);
32
31#endif /* SYSTEM_TARGET_H */ 33#endif /* SYSTEM_TARGET_H */
diff --git a/firmware/usb.c b/firmware/usb.c
index f918f19bc4..07683ce7b1 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -48,7 +48,8 @@
48/* Conditions under which we want the entire driver */ 48/* Conditions under which we want the entire driver */
49#if !defined(BOOTLOADER) || (CONFIG_CPU == SH7034) || \ 49#if !defined(BOOTLOADER) || (CONFIG_CPU == SH7034) || \
50 (defined(TOSHIBA_GIGABEAT_S) && defined(USE_ROCKBOX_USB) && defined(USB_ENABLE_STORAGE)) || \ 50 (defined(TOSHIBA_GIGABEAT_S) && defined(USE_ROCKBOX_USB) && defined(USB_ENABLE_STORAGE)) || \
51 (defined(HAVE_USBSTACK) && (defined(CREATIVE_ZVx) || \ 51 (defined(HAVE_USBSTACK) && (defined(CREATIVE_ZVx)) || \
52 (defined(HAVE_USBSTACK) && (defined(OLYMPUS_MROBE_500)) || \
52 defined(CPU_TCC77X) || defined(CPU_TCC780X))) || \ 53 defined(CPU_TCC77X) || defined(CPU_TCC780X))) || \
53 (CONFIG_USBOTG == USBOTG_JZ4740) 54 (CONFIG_USBOTG == USBOTG_JZ4740)
54#define USB_FULL_INIT 55#define USB_FULL_INIT