summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-02-23 16:10:46 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-02-23 16:10:46 +0000
commit9bcb96f4908c480727de5cafa804d476c6819790 (patch)
treee3ae0054731c045594c67f10a07b3bfee5283a5f
parent2e6d604bb60b84426596449e09a99e475ab5d69f (diff)
downloadrockbox-9bcb96f4908c480727de5cafa804d476c6819790.tar.gz
rockbox-9bcb96f4908c480727de5cafa804d476c6819790.zip
Ingenic Jz4740:
* Fix USB issues + add DMA support (doesn't work fully) * Make exception handler a bit more descriptive git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20091 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/jz4740.h20
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c261
3 files changed, 178 insertions, 107 deletions
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h
index 5642dc8464..f029ad606e 100644
--- a/firmware/export/jz4740.h
+++ b/firmware/export/jz4740.h
@@ -2471,11 +2471,11 @@
2471#define USB_CSR0_SVDSETUPEND 0x80 2471#define USB_CSR0_SVDSETUPEND 0x80
2472 2472
2473/* Endpoint CSR register bits */ 2473/* Endpoint CSR register bits */
2474#define USB_INCSRH_AUTOSET 0x8000 2474#define USB_INCSRH_AUTOSET 0x80
2475#define USB_INCSRH_ISO 0x4000 2475#define USB_INCSRH_ISO 0x40
2476#define USB_INCSRH_MODE 0x2000 2476#define USB_INCSRH_MODE 0x20
2477#define USB_INCSRH_DMAREQENAB 0x1000 2477#define USB_INCSRH_DMAREQENAB 0x10
2478#define USB_INCSRH_DMAREQMODE 0x0400 2478#define USB_INCSRH_DMAREQMODE 0x04
2479#define USB_INCSR_CDT 0x40 2479#define USB_INCSR_CDT 0x40
2480#define USB_INCSR_SENTSTALL 0x20 2480#define USB_INCSR_SENTSTALL 0x20
2481#define USB_INCSR_SENDSTALL 0x10 2481#define USB_INCSR_SENDSTALL 0x10
@@ -2483,11 +2483,11 @@
2483#define USB_INCSR_UNDERRUN 0x04 2483#define USB_INCSR_UNDERRUN 0x04
2484#define USB_INCSR_FFNOTEMPT 0x02 2484#define USB_INCSR_FFNOTEMPT 0x02
2485#define USB_INCSR_INPKTRDY 0x01 2485#define USB_INCSR_INPKTRDY 0x01
2486#define USB_OUTCSRH_AUTOCLR 0x8000 2486#define USB_OUTCSRH_AUTOCLR 0x80
2487#define USB_OUTCSRH_ISO 0x4000 2487#define USB_OUTCSRH_ISO 0x40
2488#define USB_OUTCSRH_DMAREQENAB 0x2000 2488#define USB_OUTCSRH_DMAREQENAB 0x20
2489#define USB_OUTCSRH_DNYT 0x1000 2489#define USB_OUTCSRH_DNYT 0x10
2490#define USB_OUTCSRH_DMAREQMODE 0x0800 2490#define USB_OUTCSRH_DMAREQMODE 0x08
2491#define USB_OUTCSR_CDT 0x80 2491#define USB_OUTCSR_CDT 0x80
2492#define USB_OUTCSR_SENTSTALL 0x40 2492#define USB_OUTCSR_SENTSTALL 0x40
2493#define USB_OUTCSR_SENDSTALL 0x20 2493#define USB_OUTCSR_SENDSTALL 0x20
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index c029dd46bb..f78f3592e5 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -238,7 +238,7 @@ static char* parse_exception(unsigned int cause)
238 238
239void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc) 239void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
240{ 240{
241 panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr); 241 panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), read_c0_badvaddr(), epc, (unsigned int)stack_ptr);
242} 242}
243 243
244void tlb_refill_handler(void) 244void tlb_refill_handler(void)
@@ -308,7 +308,7 @@ static void pll_init(void)
308 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 308 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
309 9 309 9
310 }; 310 };
311 int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ 311 int div[5] = {0, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
312 int nf, pllout2; 312 int nf, pllout2;
313 313
314 cfcr = CPM_CPCCR_CLKOEN | 314 cfcr = CPM_CPCCR_CLKOEN |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
index 7bd0ba4ae5..2dd73c01a4 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -127,21 +127,30 @@ static void writeFIFO(struct usb_endpoint *ep, unsigned int size)
127{ 127{
128 logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size); 128 logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size);
129 129
130 register unsigned int *d = (unsigned int *)EP_PTR(ep); 130 register unsigned int *d32 = (unsigned int *)EP_PTR(ep);
131 register unsigned char *c; 131 register unsigned char *d8 = (unsigned char *)EP_PTR(ep);
132 register unsigned int s; 132 register unsigned int s;
133 133
134 if(size > 0) 134 if(size > 0)
135 { 135 {
136 s = size >> 2; 136 if(UNLIKELY((unsigned int)d8 & 3))
137 while (s--) 137 {
138 REG32(ep->fifo_addr) = *d++; 138 s = size;
139 139 while(s--)
140 if( (s = size & 3) ) 140 REG8(ep->fifo_addr) = *d8++;
141 }
142 else
141 { 143 {
142 c = (unsigned char *)d; 144 s = size >> 2;
143 while (s--) 145 while (s--)
144 REG8(ep->fifo_addr) = *c++; 146 REG32(ep->fifo_addr) = *d32++;
147
148 if( (s = size & 3) )
149 {
150 d8 = (unsigned char *)d32;
151 while (s--)
152 REG8(ep->fifo_addr) = *d8++;
153 }
145 } 154 }
146 } 155 }
147} 156}
@@ -158,9 +167,9 @@ static void flushFIFO(struct usb_endpoint *ep)
158 case ep_bulk: 167 case ep_bulk:
159 case ep_interrupt: 168 case ep_interrupt:
160 if(EP_IS_IN(ep)) 169 if(EP_IS_IN(ep))
161 REG_USB_REG_INCSR |= USB_INCSR_FF; 170 REG_USB_REG_INCSR |= (USB_INCSR_FF | USB_INCSR_CDT);
162 else 171 else
163 REG_USB_REG_OUTCSR |= USB_OUTCSR_FF; 172 REG_USB_REG_OUTCSR |= (USB_OUTCSR_FF | USB_OUTCSR_CDT);
164 break; 173 break;
165 } 174 }
166} 175}
@@ -249,7 +258,7 @@ static void EP0_handler(void)
249} 258}
250 259
251static void EPIN_handler(unsigned int endpoint) 260static void EPIN_handler(unsigned int endpoint)
252{ 261{
253 struct usb_endpoint* ep = &endpoints[endpoint*2+1]; 262 struct usb_endpoint* ep = &endpoints[endpoint*2+1];
254 unsigned int length, csr; 263 unsigned int length, csr;
255 264
@@ -266,14 +275,12 @@ static void EPIN_handler(unsigned int endpoint)
266 return; 275 return;
267 } 276 }
268 277
269#if 0 278 if(ep->use_dma)
270 if(ep->use_dma == true)
271 return; 279 return;
272#endif
273 280
274 if(csr & USB_INCSR_FFNOTEMPT) 281 if(csr & USB_INCSR_FFNOTEMPT)
275 { 282 {
276 logf("FIFO is not empty!: 0x%x", csr); 283 logf("FIFO is not empty! 0x%x", csr);
277 return; 284 return;
278 } 285 }
279 286
@@ -306,56 +313,113 @@ static void EPOUT_handler(unsigned int endpoint)
306 struct usb_endpoint* ep = &endpoints[endpoint*2]; 313 struct usb_endpoint* ep = &endpoints[endpoint*2];
307 unsigned int size, csr; 314 unsigned int size, csr;
308 315
309 select_endpoint(endpoint);
310 csr = REG_USB_REG_OUTCSR;
311 logf("EPOUT_handler(%d): 0x%x", endpoint, csr);
312
313 if(!ep->busy) 316 if(!ep->busy)
314 return; 317 return;
315
316 if(csr & USB_OUTCSR_SENTSTALL)
317 {
318 logf("stall sent, flushing fifo..");
319 flushFIFO(ep);
320 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL;
321 return;
322 }
323 318
324 if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ 319 select_endpoint(endpoint);
320 while((csr = REG_USB_REG_OUTCSR) & (USB_OUTCSR_SENTSTALL|USB_OUTCSR_OUTPKTRDY))
325 { 321 {
326 size = REG_USB_REG_OUTCOUNT; 322 logf("EPOUT_handler(%d): 0x%x", endpoint, csr);
323 if(csr & USB_OUTCSR_SENTSTALL)
324 {
325 logf("stall sent, flushing fifo..");
326 flushFIFO(ep);
327 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL;
328 return;
329 }
327 330
328 readFIFO(ep, size); 331 if(ep->use_dma)
329 ep->received += size; 332 return;
333
334 if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */
335 {
336 size = REG_USB_REG_OUTCOUNT;
337
338 readFIFO(ep, size);
339 ep->received += size;
340
341 /*if(csr & USB_OUTCSR_FFFULL)
342 csr &= ~USB_OUTCSR_FFFULL;*/
343
344 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY;
345
346 logf("received: %d max length: %d", ep->received, ep->length);
347
348 if(size < ep->fifo_size || ep->received >= ep->length)
349 {
350 usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received);
351 if(ep->wait)
352 wakeup_signal(&ep_wkup[endpoint*2]);
353 logf("receive transfer_complete");
354 ep->received = 0;
355 ep->length = 0;
356 ep->buf = NULL;
357 ep->busy = false;
358 return;
359 }
360 }
361 }
362}
330 363
331 REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; 364static void EPDMA_handler(int number)
365{
366 int endpoint=-1;
367 unsigned int size=0;
368 if(number == USB_INTR_DMA_BULKIN)
369 endpoint = (REG_USB_REG_CNTL1 >> 4) & 0xF;
370 else if(number == USB_INTR_DMA_BULKOUT)
371 endpoint = (REG_USB_REG_CNTL2 >> 4) & 0xF;
372
373 struct usb_endpoint* ep = &endpoints[endpoint];
374 logf("DMA_BULK%d %d", number, endpoint);
375
376 if(number == USB_INTR_DMA_BULKIN)
377 size = (unsigned int)ep->buf - REG_USB_REG_ADDR1;
378 else if(number == USB_INTR_DMA_BULKOUT)
379 size = (unsigned int)ep->buf - REG_USB_REG_ADDR2;
380
381 if(number == USB_INTR_DMA_BULKOUT)
382 {
383 /* Disable DMA */
384 REG_USB_REG_CNTL2 = 0;
332 385
333 logf("received: %d max length: %d", ep->received, ep->length); 386 __dcache_invalidate_all();
334 387
335 if(size < ep->fifo_size || ep->received >= ep->length) 388 select_endpoint(endpoint);
389 /* Read out last packet manually */
390 unsigned int lpack_size = REG_USB_REG_OUTCOUNT;
391 if(lpack_size > 0)
336 { 392 {
337 usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); 393 ep->buf += ep->length - lpack_size;
338 if(ep->wait) 394 readFIFO(ep, lpack_size);
339 wakeup_signal(&ep_wkup[endpoint*2]); 395 REG_USB_REG_OUTCSR &= ~USB_OUTCSR_OUTPKTRDY;
340 logf("receive transfer_complete");
341 ep->received = 0;
342 ep->length = 0;
343 ep->buf = NULL;
344 ep->busy = false;
345 } 396 }
346 } 397 }
398 else if(number == USB_INTR_DMA_BULKIN && size % ep->fifo_size)
399 /* If the last packet is less than MAXP, set INPKTRDY manually */
400 REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY;
401
402 usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT,
403 0, ep->length);
404
405 ep->busy = false;
406 ep->sent = 0;
407 ep->length = 0;
408 ep->buf = NULL;
409 if(ep->wait)
410 wakeup_signal(&ep_wkup[EP_NUMBER(ep)]);
347} 411}
348 412
349static void setup_endpoint(struct usb_endpoint *ep) 413static void setup_endpoint(struct usb_endpoint *ep)
350{ 414{
351 int csr; 415 int csr, csrh;
352 ep->sent = 0;
353 ep->length = 0;
354 416
355 select_endpoint(EP_NUMBER2(ep)); 417 select_endpoint(EP_NUMBER2(ep));
356 418
357 ep->busy = false; 419 ep->busy = false;
358 ep->wait = false; 420 ep->wait = false;
421 ep->sent = 0;
422 ep->length = 0;
359 423
360 if(ep->type == ep_bulk) 424 if(ep->type == ep_bulk)
361 { 425 {
@@ -367,27 +431,31 @@ static void setup_endpoint(struct usb_endpoint *ep)
367 431
368 if(EP_IS_IN(ep)) 432 if(EP_IS_IN(ep))
369 { 433 {
370 REG_USB_REG_INMAXP = ep->fifo_size; 434 csr = (USB_INCSR_FF | USB_INCSR_CDT);
371 csr = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE); 435 csrh = USB_INCSRH_MODE;
372 if(ep->use_dma) 436 if(ep->use_dma)
373 csr |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET); 437 csrh |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE);
374 438
375 REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); 439 REG_USB_REG_INMAXP = ep->fifo_size;
376 REG_USB_REG_INCSR = csr; 440 REG_USB_REG_INCSR = csr;
441 REG_USB_REG_INCSRH = csrh;
442 REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep));
377 } 443 }
378 else 444 else
379 { 445 {
380 REG_USB_REG_OUTMAXP = ep->fifo_size;
381 csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); 446 csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT);
447 csrh = 0;
382 448
383 if(ep->type == ep_interrupt) 449 if(ep->type == ep_interrupt)
384 csr |= USB_OUTCSRH_DNYT; 450 csrh |= USB_OUTCSRH_DNYT;
385 451
386 if(ep->use_dma) 452 if(ep->use_dma)
387 csr |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); 453 csrh |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE);
388 454
389 REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); 455 REG_USB_REG_OUTMAXP = ep->fifo_size;
390 REG_USB_REG_OUTCSR = csr; 456 REG_USB_REG_OUTCSR = csr;
457 REG_USB_REG_OUTCSRH = csrh;
458 REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep));
391 } 459 }
392} 460}
393 461
@@ -395,13 +463,13 @@ static void udc_reset(void)
395{ 463{
396 /* From the datasheet: 464 /* From the datasheet:
397 465
398 When a reset condition is detected on the USB, the controller performs the following actions: 466 When a reset condition is detected on the USB, the controller performs the following actions:
399 * Sets FAddr to 0. 467 * Sets FAddr to 0.
400 * Sets Index to 0. 468 * Sets Index to 0.
401 * Flushes all endpoint FIFOs. 469 * Flushes all endpoint FIFOs.
402 * Clears all control/status registers. 470 * Clears all control/status registers.
403 * Enables all endpoint interrupts. 471 * Enables all endpoint interrupts.
404 * Generates a Reset interrupt. 472 * Generates a Reset interrupt.
405 */ 473 */
406 474
407 logf("udc_reset()"); 475 logf("udc_reset()");
@@ -430,7 +498,8 @@ static void udc_reset(void)
430 select_endpoint(0); 498 select_endpoint(0);
431 REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); 499 REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND);
432 500
433 for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */ 501 /* Reset other endpoints */
502 for(i=2; i<TOTAL_EP(); i++)
434 setup_endpoint(&endpoints[i]); 503 setup_endpoint(&endpoints[i]);
435 504
436 /* Enable interrupts */ 505 /* Enable interrupts */
@@ -451,6 +520,8 @@ void UDC(void)
451 520
452 if(UNLIKELY(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0)) 521 if(UNLIKELY(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0))
453 return; 522 return;
523
524 logf("%x %x %x %x", intrUSB, intrIn, intrOut, intrDMA);
454 525
455 /* EPIN & EPOUT are all handled in DMA */ 526 /* EPIN & EPOUT are all handled in DMA */
456 if(intrIn & USB_INTR_EP0) 527 if(intrIn & USB_INTR_EP0)
@@ -473,30 +544,10 @@ void UDC(void)
473 { 544 {
474 logf("USB resume"); 545 logf("USB resume");
475 } 546 }
476#if 0
477 if(intrDMA & USB_INTR_DMA_BULKIN) 547 if(intrDMA & USB_INTR_DMA_BULKIN)
478 { 548 EPDMA_handler(USB_INTR_DMA_BULKIN);
479 logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF));
480 unsigned int size = (unsigned int)endpoints[3].buf - REG_USB_REG_ADDR2;
481 if(size < endpoints[3].length)
482 {
483 select_endpoint(1);
484 writeFIFO(endpoints[3], endpoints[3].length - size);
485 REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY;
486 }
487
488 usb_core_transfer_complete(1, USB_DIR_IN, 0, endpoints[3].length);
489 }
490 if(intrDMA & USB_INTR_DMA_BULKOUT) 549 if(intrDMA & USB_INTR_DMA_BULKOUT)
491 { 550 EPDMA_handler(USB_INTR_DMA_BULKOUT);
492 logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF));
493
494 select_endpoint(1);
495 REG_USB_REG_OUTCSR &= ~(USB_OUTCSRH_DMAREQENAB | USB_OUTCSR_OUTPKTRDY);
496
497 usb_core_transfer_complete(1, USB_DIR_OUT, 0, 0);
498 }
499#endif
500} 551}
501 552
502bool usb_drv_stalled(int endpoint, bool in) 553bool usb_drv_stalled(int endpoint, bool in)
@@ -610,6 +661,10 @@ void usb_drv_init(void)
610 /* Enable the USB PHY */ 661 /* Enable the USB PHY */
611 REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; 662 REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
612 663
664 /* Dis- and reconnect from USB */
665 REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN;
666 REG_USB_REG_POWER |= USB_POWER_SOFTCONN;
667
613 udc_reset(); 668 udc_reset();
614} 669}
615 670
@@ -660,8 +715,8 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
660 endpoints[1].length = length; 715 endpoints[1].length = length;
661 ep0state = USB_EP0_TX; 716 ep0state = USB_EP0_TX;
662 EP0_send(); 717 EP0_send();
663
664 restore_irq(flags); 718 restore_irq(flags);
719
665 return 0; 720 return 0;
666 } 721 }
667 else 722 else
@@ -671,15 +726,19 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
671 endpoints[endpoint*2+1].sent = 0; 726 endpoints[endpoint*2+1].sent = 0;
672 endpoints[endpoint*2+1].length = length; 727 endpoints[endpoint*2+1].length = length;
673 endpoints[endpoint*2+1].busy = true; 728 endpoints[endpoint*2+1].busy = true;
674#if 0 729 if(endpoints[endpoint*2+1].use_dma)
675 select_endpoint(endpoint); 730 {
731 //dma_cache_wback_inv((unsigned long)ptr, length);
732 __dcache_writeback_all();
733 REG_USB_REG_ADDR1 = (unsigned long)ptr & 0x7fffffff;
734 REG_USB_REG_COUNT1 = length;
735 REG_USB_REG_CNTL1 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
736 USB_CNTL_DIR_IN | USB_CNTL_ENA |
737 USB_CNTL_EP(endpoint) | USB_CNTL_BURST_16);
738 }
739 else
740 EPIN_handler(endpoint);
676 741
677 REG_USB_REG_ADDR2 = ((unsigned long)ptr) & 0x7fffffff;
678 REG_USB_REG_COUNT2 = length;
679 REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | USB_CNTL_DIR_IN | USB_CNTL_ENA);
680#else
681 EPIN_handler(endpoint);
682#endif
683 restore_irq(flags); 742 restore_irq(flags);
684 return 0; 743 return 0;
685 } 744 }
@@ -717,8 +776,20 @@ int usb_drv_recv(int endpoint, void* ptr, int length)
717 endpoints[endpoint*2].received = 0; 776 endpoints[endpoint*2].received = 0;
718 endpoints[endpoint*2].length = length; 777 endpoints[endpoint*2].length = length;
719 endpoints[endpoint*2].busy = true; 778 endpoints[endpoint*2].busy = true;
720 restore_irq(flags); 779 if(endpoints[endpoint*2].use_dma)
780 {
781 //dma_cache_wback_inv((unsigned long)ptr, length);
782 __dcache_writeback_all();
783 REG_USB_REG_ADDR2 = (unsigned long)ptr & 0x7fffffff;
784 REG_USB_REG_COUNT2 = length;
785 REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
786 USB_CNTL_ENA | USB_CNTL_EP(endpoint) |
787 USB_CNTL_BURST_16);
788 }
789 else
790 EPOUT_handler(endpoint);
721 791
792 restore_irq(flags);
722 return 0; 793 return 0;
723 } 794 }
724} 795}