diff options
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r-- | firmware/mpeg.c | 110 |
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 | ||
503 | static void mas_poll_start(int interval_in_ms) | 504 | static 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 |
536 | static void dbg_timer_start(void) | 538 | static void dbg_timer_start(void) |
@@ -618,11 +620,10 @@ static void stop_dma(void) | |||
618 | long current_dma_tick = 0; | 620 | long current_dma_tick = 0; |
619 | long timing_info_index = 0; | 621 | long timing_info_index = 0; |
620 | long timing_info[1024]; | 622 | long timing_info[1024]; |
623 | bool inverted_pr; | ||
621 | 624 | ||
622 | static void dma_tick(void) | 625 | static 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 |
722 | void IRQ6(void) | ||
723 | { | ||
724 | stop_dma(); | ||
725 | } | ||
726 | |||
727 | #pragma interrupt | ||
728 | void DEI3(void) | 706 | void 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 |
815 | void IMIA1(void) | 794 | void 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 | ||
802 | static 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 | ||
816 | void 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 | ||
828 | void 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 | ||
821 | static int add_track_to_tag_list(char *filename) | 837 | static int add_track_to_tag_list(char *filename) |
822 | { | 838 | { |
@@ -908,6 +924,9 @@ static int new_file(int steps) | |||
908 | static void stop_playing(void) | 924 | static 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); |