summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-11-19 09:50:19 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-11-19 09:50:19 +0000
commit0dcd47eb848d159efd03577cc638a69074b0fb9b (patch)
tree8030d398f0b79abb377ceee57afac8250f80718f /firmware
parent0a488fb155a9728fa09e72cd65ed7632feecaf3b (diff)
downloadrockbox-0dcd47eb848d159efd03577cc638a69074b0fb9b.tar.gz
rockbox-0dcd47eb848d159efd03577cc638a69074b0fb9b.zip
Now uses IRQ for DEMAND instead of polling. This should improve the playback performance a lot, for all bitrates
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2855 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/mpeg.c110
1 files changed, 74 insertions, 36 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 83f9a38246..92f79b1977 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -500,6 +500,7 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
500 dbgdata->lowest_watermark_level = lowest_watermark_level; 500 dbgdata->lowest_watermark_level = lowest_watermark_level;
501} 501}
502 502
503#ifdef HAVE_MAS3507D
503static void mas_poll_start(int interval_in_ms) 504static void mas_poll_start(int interval_in_ms)
504{ 505{
505 unsigned int count; 506 unsigned int count;
@@ -531,6 +532,7 @@ static void mas_poll_start(int interval_in_ms)
531 532
532 TSTR |= 0x02; /* Start timer 1 */ 533 TSTR |= 0x02; /* Start timer 1 */
533} 534}
535#endif
534 536
535#ifdef DEBUG 537#ifdef DEBUG
536static void dbg_timer_start(void) 538static void dbg_timer_start(void)
@@ -618,11 +620,10 @@ static void stop_dma(void)
618long current_dma_tick = 0; 620long current_dma_tick = 0;
619long timing_info_index = 0; 621long timing_info_index = 0;
620long timing_info[1024]; 622long timing_info[1024];
623bool inverted_pr;
621 624
622static void dma_tick(void) 625static void dma_tick(void)
623{ 626{
624 current_dma_tick++;
625
626#ifdef HAVE_MAS3587F 627#ifdef HAVE_MAS3587F
627 if(mpeg_mode == MPEG_DECODER) 628 if(mpeg_mode == MPEG_DECODER)
628 { 629 {
@@ -644,58 +645,41 @@ static void dma_tick(void)
644 else 645 else
645 { 646 {
646 int i; 647 int i;
647 int x;
648 int num_bytes = 0; 648 int num_bytes = 0;
649 if(recording && (PBDR & 0x4000)) 649 if(recording && (PBDR & 0x4000))
650 { 650 {
651 timing_info[timing_info_index++] = current_dma_tick; 651#ifdef DEBUG
652 timing_info[timing_info_index++] = current_tick;
652 TCNT2 = 0; 653 TCNT2 = 0;
654#endif
653 for(i = 0;i < 30 && (PBDR & 0x4000);i++) 655 for(i = 0;i < 30 && (PBDR & 0x4000);i++)
654 { 656 {
655 if(read_hw_mask() & PR_ACTIVE_HIGH) 657 if(inverted_pr)
656 PADR |= 0x800; 658 PADR |= 0x800;
657 else 659 else
658 PADR &= ~0x800; 660 PADR &= ~0x800;
659 661
660 for(x = 2000;PBDR & 0x8000 && x;x--) {}; 662 /* It must take at least 5 cycles before the data is read */
661 663
662 if(x == 0)
663 {
664 queue_post(&mpeg_queue, MPEG_REC_TIMEOUT, (void *)0);
665 if(read_hw_mask() & PR_ACTIVE_HIGH)
666 PADR &= ~0x800;
667 else
668 PADR |= 0x800;
669 break;
670 }
671
672 mp3buf[mp3buf_write] = *(unsigned char *)0x4000000; 664 mp3buf[mp3buf_write] = *(unsigned char *)0x4000000;
673 665
674 if(read_hw_mask() & PR_ACTIVE_HIGH) 666 if(inverted_pr)
675 PADR &= ~0x800; 667 PADR &= ~0x800;
676 else 668 else
677 PADR |= 0x800; 669 PADR |= 0x800;
678 670
671 /* It must take at least 4 cycles before the next loop */
672
679 mp3buf_write++; 673 mp3buf_write++;
680 if(mp3buf_write >= mp3buflen) 674 if(mp3buf_write >= mp3buflen)
681 mp3buf_write = 0; 675 mp3buf_write = 0;
682 676
683 num_bytes++; 677 num_bytes++;
684
685 for(x = 2000;!(PBDR & 0x8000) && x;x--) {};
686 if(x == 0)
687 {
688 queue_post(&mpeg_queue, MPEG_REC_TIMEOUT, (void *)1);
689 if(read_hw_mask() & PR_ACTIVE_HIGH)
690 PADR &= ~0x800;
691 else
692 PADR |= 0x800;
693 break;
694 }
695 } 678 }
679#ifdef DEBUG
696 timing_info[timing_info_index++] = TCNT2 + (num_bytes << 16); 680 timing_info[timing_info_index++] = TCNT2 + (num_bytes << 16);
697
698 timing_info_index &= 0x3ff; 681 timing_info_index &= 0x3ff;
682#endif
699 683
700 /* Signal to save the data if we are running out of buffer 684 /* Signal to save the data if we are running out of buffer
701 space */ 685 space */
@@ -719,12 +703,6 @@ static void reset_mp3_buffer(void)
719} 703}
720 704
721#pragma interrupt 705#pragma interrupt
722void IRQ6(void)
723{
724 stop_dma();
725}
726
727#pragma interrupt
728void DEI3(void) 706void DEI3(void)
729{ 707{
730 if(playing && !paused) 708 if(playing && !paused)
@@ -811,12 +789,50 @@ void DEI3(void)
811 CHCR3 &= ~0x0002; /* Clear DMA interrupt */ 789 CHCR3 &= ~0x0002; /* Clear DMA interrupt */
812} 790}
813 791
792#ifdef HAVE_MAS3507D
814#pragma interrupt 793#pragma interrupt
815void IMIA1(void) 794void IMIA1(void)
816{ 795{
817 dma_tick(); 796 dma_tick();
818 TSR1 &= ~0x01; 797 TSR1 &= ~0x01;
819} 798}
799#endif
800
801#ifdef HAVE_MAS3587F
802static void demand_irq_enable(bool on)
803{
804 int oldlevel = set_irq_level(15);
805
806 if(on)
807 IPRA = (IPRA & 0xfff0) | 0x000b;
808 else
809 IPRA &= 0xfff0;
810
811 set_irq_level(oldlevel);
812}
813#endif
814
815#pragma interrupt
816void IRQ6(void)
817{
818 stop_dma();
819
820#ifdef HAVE_MAS3587F
821 /* Enable IRQ to trap the next DEMAND */
822 demand_irq_enable(true);
823#endif
824}
825
826#ifdef HAVE_MAS3587F
827#pragma interrupt
828void IRQ3(void)
829{
830 dma_tick();
831
832 /* Disable IRQ until DEMAND goes low again */
833 demand_irq_enable(false);
834}
835#endif
820 836
821static int add_track_to_tag_list(char *filename) 837static int add_track_to_tag_list(char *filename)
822{ 838{
@@ -908,6 +924,9 @@ static int new_file(int steps)
908static void stop_playing(void) 924static void stop_playing(void)
909{ 925{
910 /* Stop the current stream */ 926 /* Stop the current stream */
927#ifdef HAVE_MAS3587F
928 demand_irq_enable(false);
929#endif
911 playing = false; 930 playing = false;
912 filling = false; 931 filling = false;
913 if(mpeg_file >= 0) 932 if(mpeg_file >= 0)
@@ -980,6 +999,9 @@ static void start_playback_if_ready(void)
980 { 999 {
981 last_dma_tick = current_tick; 1000 last_dma_tick = current_tick;
982 start_dma(); 1001 start_dma();
1002#ifdef HAVE_MAS3587F
1003 demand_irq_enable(true);
1004#endif
983 } 1005 }
984 1006
985 /* Tell ourselves that we need more data */ 1007 /* Tell ourselves that we need more data */
@@ -1583,6 +1605,7 @@ static void mpeg_thread(void)
1583 panicf("recfile: %d", mpeg_file); 1605 panicf("recfile: %d", mpeg_file);
1584 reset_mp3_buffer(); 1606 reset_mp3_buffer();
1585 start_recording(); 1607 start_recording();
1608 demand_irq_enable(true);
1586 break; 1609 break;
1587 1610
1588 case MPEG_STOP: 1611 case MPEG_STOP:
@@ -1596,6 +1619,7 @@ static void mpeg_thread(void)
1596 break; 1619 break;
1597 1620
1598 case MPEG_REC_TIMEOUT: 1621 case MPEG_REC_TIMEOUT:
1622 demand_irq_enable(false);
1599 if(mpeg_file >= 0) 1623 if(mpeg_file >= 0)
1600 close(mpeg_file); 1624 close(mpeg_file);
1601 panicf("Timeout: %d", (int)ev.data); 1625 panicf("Timeout: %d", (int)ev.data);
@@ -1604,6 +1628,7 @@ static void mpeg_thread(void)
1604 case MPEG_STOP_DONE: 1628 case MPEG_STOP_DONE:
1605 DEBUGF("MPEG_STOP_DONE\n"); 1629 DEBUGF("MPEG_STOP_DONE\n");
1606 1630
1631 demand_irq_enable(false);
1607 if(mpeg_file >= 0) 1632 if(mpeg_file >= 0)
1608 close(mpeg_file); 1633 close(mpeg_file);
1609 1634
@@ -2509,7 +2534,15 @@ void mpeg_init(int volume, int bass, int treble, int balance, int loudness, int
2509 queue_init(&mpeg_queue); 2534 queue_init(&mpeg_queue);
2510 create_thread(mpeg_thread, mpeg_stack, 2535 create_thread(mpeg_thread, mpeg_stack,
2511 sizeof(mpeg_stack), mpeg_thread_name); 2536 sizeof(mpeg_stack), mpeg_thread_name);
2537
2538#ifdef HAVE_MAS3507D
2512 mas_poll_start(1); 2539 mas_poll_start(1);
2540#endif
2541
2542#ifdef HAVE_MAS3587F
2543 ICR &= ~0x0010; /* IRQ3 level sensitive */
2544 PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */
2545#endif
2513 2546
2514#ifdef HAVE_MAS3507D 2547#ifdef HAVE_MAS3507D
2515 mas_writereg(MAS_REG_KPRESCALE, 0xe9400); 2548 mas_writereg(MAS_REG_KPRESCALE, 0xe9400);
@@ -2537,6 +2570,11 @@ void mpeg_init(int volume, int bass, int treble, int balance, int loudness, int
2537 memset(id3tags, sizeof(id3tags), 0); 2570 memset(id3tags, sizeof(id3tags), 0);
2538 memset(_id3tags, sizeof(id3tags), 0); 2571 memset(_id3tags, sizeof(id3tags), 0);
2539 2572
2573 if(read_hw_mask() & PR_ACTIVE_HIGH)
2574 inverted_pr = true;
2575 else
2576 inverted_pr = false;
2577
2540#ifdef DEBUG 2578#ifdef DEBUG
2541 dbg_timer_start(); 2579 dbg_timer_start();
2542 dbg_cnt2us(0); 2580 dbg_cnt2us(0);