summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2004-01-10 15:39:56 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2004-01-10 15:39:56 +0000
commitec5d44627fb8a409c445741264cc4f2995a17721 (patch)
tree757a89bd1a7bff52f302df77c5db22bb63759c34 /firmware/mpeg.c
parent1e32b94441afd344a250efec1450c86a83c297d1 (diff)
downloadrockbox-ec5d44627fb8a409c445741264cc4f2995a17721.tar.gz
rockbox-ec5d44627fb8a409c445741264cc4f2995a17721.zip
next round of playback function split: everything in place, working and used; except for the playtime
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4218 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c276
1 files changed, 93 insertions, 183 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 29836dd14e..12d71a1dbd 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -74,7 +74,7 @@ static int get_unswapped_space(void);
74#define MPEG_STOP_DONE 103 74#define MPEG_STOP_DONE 103
75 75
76#ifdef HAVE_MAS3587F 76#ifdef HAVE_MAS3587F
77static enum 77extern enum /* from mp3_playback.c */
78{ 78{
79 MPEG_DECODER, 79 MPEG_DECODER,
80 MPEG_ENCODER 80 MPEG_ENCODER
@@ -371,33 +371,6 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
371 dbgdata->lowest_watermark_level = lowest_watermark_level; 371 dbgdata->lowest_watermark_level = lowest_watermark_level;
372} 372}
373 373
374#ifndef HAVE_MAS3507D
375static void postpone_dma_tick(void)
376{
377 unsigned int count;
378
379 count = FREQ / 1000 / 8;
380
381 /* We are using timer 1 */
382
383 TSTR &= ~0x02; /* Stop the timer */
384 TSNC &= ~0x02; /* No synchronization */
385 TMDR &= ~0x02; /* Operate normally */
386
387 TCNT1 = 0; /* Start counting at 0 */
388 GRA1 = count;
389 TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
390
391 /* Enable interrupt on level 5 */
392 IPRC = (IPRC & ~0x000f) | 0x0005;
393
394 TSR1 &= ~0x02;
395 TIER1 = 0xf9; /* Enable GRA match interrupt */
396
397 TSTR |= 0x02; /* Start timer 1 */
398}
399#endif /* #ifndef HAVE_MAS3507D */
400
401#ifdef DEBUG 374#ifdef DEBUG
402static void dbg_timer_start(void) 375static void dbg_timer_start(void)
403{ 376{
@@ -524,134 +497,122 @@ static void drain_dma_buffer(void)
524 497
525#endif /* #ifdef HAVE_MAS3587F */ 498#endif /* #ifdef HAVE_MAS3587F */
526 499
527static void dma_tick (void) __attribute__ ((section (".icode"))); 500void rec_tick (void) __attribute__ ((section (".icode")));
528static void dma_tick(void) 501void rec_tick(void)
529{ 502{
530#ifdef HAVE_MAS3587F 503#ifdef HAVE_MAS3587F
531 if(mpeg_mode == MPEG_DECODER) 504 int i;
532 { 505 int num_bytes;
533#endif /* #ifdef HAVE_MAS3587F */ 506 if(is_recording && (PBDR & 0x4000))
534 if(playing && !paused)
535 {
536 /* Start DMA if it is disabled and the DEMAND pin is high */
537 if(!(SCR0 & 0x80) && (PBDR & 0x4000))
538 {
539 mp3_play_pause(true);
540 }
541 id3tags[tag_read_idx]->id3.elapsed +=
542 (current_tick - last_dma_tick) * 1000 / HZ;
543 last_dma_tick = current_tick;
544 }
545#ifdef HAVE_MAS3587F
546 }
547 else /* MPEG_ENCODER */
548 { 507 {
549 int i;
550 int num_bytes;
551 if(is_recording && (PBDR & 0x4000))
552 {
553#ifdef DEBUG 508#ifdef DEBUG
554 timing_info[timing_info_index++] = current_tick; 509 timing_info[timing_info_index++] = current_tick;
555 TCNT2 = 0; 510 TCNT2 = 0;
556#endif /* #ifdef DEBUG */ 511#endif /* #ifdef DEBUG */
557 /* We read as long as EOD is high, but max 30 bytes. 512 /* We read as long as EOD is high, but max 30 bytes.
558 This code is optimized, and should probably be 513 This code is optimized, and should probably be
559 written in assembler instead. */ 514 written in assembler instead. */
560 if(inverted_pr) 515 if(inverted_pr)
516 {
517 i = 0;
518 while((*((volatile unsigned char *)PBDR_ADDR) & 0x40)
519 && i < 30)
561 { 520 {
562 i = 0; 521 or_b(0x08, &PADRH);
563 while((*((volatile unsigned char *)PBDR_ADDR) & 0x40)
564 && i < 30)
565 {
566 or_b(0x08, &PADRH);
567 522
568 while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); 523 while(*((volatile unsigned char *)PBDR_ADDR) & 0x80);
569 524
570 /* It must take at least 5 cycles before 525 /* It must take at least 5 cycles before
571 the data is read */ 526 the data is read */
572 asm(" nop\n nop\n nop\n"); 527 asm(" nop\n nop\n nop\n");
573 mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000; 528 mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000;
574 529
575 if(mp3buf_write >= mp3buflen) 530 if(mp3buf_write >= mp3buflen)
576 mp3buf_write = 0; 531 mp3buf_write = 0;
577 532
578 i++; 533 i++;
579 534
580 and_b(~0x08, &PADRH); 535 and_b(~0x08, &PADRH);
581 536
582 /* No wait for /RTW, cause it's not necessary */ 537 /* No wait for /RTW, cause it's not necessary */
583 }
584 } 538 }
585 else /* !inverted_pr */ 539 }
540 else /* !inverted_pr */
541 {
542 i = 0;
543 while((*((volatile unsigned char *)PBDR_ADDR) & 0x40)
544 && i < 30)
586 { 545 {
587 i = 0; 546 and_b(~0x08, &PADRH);
588 while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) 547
589 && i < 30) 548 while(*((volatile unsigned char *)PBDR_ADDR) & 0x80);
590 { 549
591 and_b(~0x08, &PADRH); 550 /* It must take at least 5 cycles before
592 551 the data is read */
593 while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); 552 asm(" nop\n nop\n nop\n");
594 553 mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000;
595 /* It must take at least 5 cycles before 554
596 the data is read */ 555 if(mp3buf_write >= mp3buflen)
597 asm(" nop\n nop\n nop\n"); 556 mp3buf_write = 0;
598 mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000;
599
600 if(mp3buf_write >= mp3buflen)
601 mp3buf_write = 0;
602 557
603 i++; 558 i++;
604 559
605 or_b(0x08, &PADRH); 560 or_b(0x08, &PADRH);
606 561
607 /* No wait for /RTW, cause it's not necessary */ 562 /* No wait for /RTW, cause it's not necessary */
608 }
609 } 563 }
564 }
610#ifdef DEBUG 565#ifdef DEBUG
611 timing_info[timing_info_index++] = TCNT2 + (i << 16); 566 timing_info[timing_info_index++] = TCNT2 + (i << 16);
612 timing_info_index &= 0x3ff; 567 timing_info_index &= 0x3ff;
613#endif /* #ifdef DEBUG */ 568#endif /* #ifdef DEBUG */
614 569
615 num_rec_bytes += i; 570 num_rec_bytes += i;
616 571
617 if(is_prerecording) 572 if(is_prerecording)
573 {
574 if(TIME_AFTER(current_tick, prerecord_timeout))
618 { 575 {
619 if(TIME_AFTER(current_tick, prerecord_timeout)) 576 prerecord_timeout = current_tick + HZ;
620 {
621 prerecord_timeout = current_tick + HZ;
622 577
623 /* Store the write pointer every second */ 578 /* Store the write pointer every second */
624 prerecord_buffer[prerecord_index++] = mp3buf_write; 579 prerecord_buffer[prerecord_index++] = mp3buf_write;
625 580
626 /* Wrap if necessary */ 581 /* Wrap if necessary */
627 if(prerecord_index == prerecording_max_seconds) 582 if(prerecord_index == prerecording_max_seconds)
628 prerecord_index = 0; 583 prerecord_index = 0;
629 584
630 /* Update the number of seconds recorded */ 585 /* Update the number of seconds recorded */
631 if(prerecord_count < prerecording_max_seconds) 586 if(prerecord_count < prerecording_max_seconds)
632 prerecord_count++; 587 prerecord_count++;
633 }
634 } 588 }
635 else 589 }
590 else
591 {
592 /* Signal to save the data if we are running out of buffer
593 space */
594 num_bytes = mp3buf_write - mp3buf_read;
595 if(num_bytes < 0)
596 num_bytes += mp3buflen;
597
598 if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving)
636 { 599 {
637 /* Signal to save the data if we are running out of buffer 600 saving = true;
638 space */ 601 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
639 num_bytes = mp3buf_write - mp3buf_read; 602 wake_up_thread();
640 if(num_bytes < 0)
641 num_bytes += mp3buflen;
642
643 if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving)
644 {
645 saving = true;
646 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
647 wake_up_thread();
648 }
649 } 603 }
650 } 604 }
651 } 605 }
652#endif /* #ifdef HAVE_MAS3587F */ 606#endif /* #ifdef HAVE_MAS3587F */
653} 607}
654 608
609void playback_tick(void)
610{
611 id3tags[tag_read_idx]->id3.elapsed +=
612 (current_tick - last_dma_tick) * 1000 / HZ;
613 last_dma_tick = current_tick;
614}
615
655static void reset_mp3_buffer(void) 616static void reset_mp3_buffer(void)
656{ 617{
657 mp3buf_read = 0; 618 mp3buf_read = 0;
@@ -751,48 +712,6 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
751 wake_up_thread(); 712 wake_up_thread();
752} 713}
753 714
754#ifdef HAVE_MAS3587F
755static void demand_irq_enable(bool on)
756{
757 int oldlevel = set_irq_level(15);
758
759 if(on)
760 {
761 IPRA = (IPRA & 0xfff0) | 0x000b;
762 ICR &= ~0x0010; /* IRQ3 level sensitive */
763 }
764 else
765 IPRA &= 0xfff0;
766
767 set_irq_level(oldlevel);
768}
769#endif /* #ifdef HAVE_MAS3587F */
770
771#pragma interrupt
772void IMIA1(void) /* Timer 1 interrupt */
773{
774 dma_tick();
775 TSR1 &= ~0x01;
776#ifdef HAVE_MAS3587F
777 /* Disable interrupt */
778 IPRC &= ~0x000f;
779#endif /* #ifdef HAVE_MAS3587F */
780}
781
782#ifdef HAVE_MAS3587F
783#pragma interrupt
784void IRQ3(void) /* PA15: MAS demand IRQ */
785{
786 /* Begin with setting the IRQ to edge sensitive */
787 ICR |= 0x0010;
788
789 if(mpeg_mode == MPEG_ENCODER)
790 dma_tick();
791 else
792 postpone_dma_tick();
793}
794#endif /* #ifdef HAVE_MAS3587F */
795
796static int add_track_to_tag_list(char *filename) 715static int add_track_to_tag_list(char *filename)
797{ 716{
798 struct id3tag *t = NULL; 717 struct id3tag *t = NULL;
@@ -892,15 +811,12 @@ static int new_file(int steps)
892static void stop_playing(void) 811static void stop_playing(void)
893{ 812{
894 /* Stop the current stream */ 813 /* Stop the current stream */
895#ifdef HAVE_MAS3587F 814 mp3_play_stop();
896 demand_irq_enable(false);
897#endif /* #ifdef HAVE_MAS3587F */
898 playing = false; 815 playing = false;
899 filling = false; 816 filling = false;
900 if(mpeg_file >= 0) 817 if(mpeg_file >= 0)
901 close(mpeg_file); 818 close(mpeg_file);
902 mpeg_file = -1; 819 mpeg_file = -1;
903 mp3_play_pause(false);
904 remove_all_tags(); 820 remove_all_tags();
905} 821}
906 822
@@ -967,17 +883,14 @@ static void start_playback_if_ready(void)
967 play_pending = false; 883 play_pending = false;
968 playing = true; 884 playing = true;
969 885
970 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
971 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
972 dma_underrun = false;
973
974 if (!paused) 886 if (!paused)
975 { 887 {
888 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
889 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
890 dma_underrun = false;
891
976 last_dma_tick = current_tick; 892 last_dma_tick = current_tick;
977 mp3_play_pause(true); 893 mp3_play_pause(true);
978#ifdef HAVE_MAS3587F
979 demand_irq_enable(true);
980#endif /* #ifdef HAVE_MAS3587F */
981 } 894 }
982 895
983 /* Tell ourselves that we need more data */ 896 /* Tell ourselves that we need more data */
@@ -2002,10 +1915,7 @@ static void mpeg_thread(void)
2002 case MPEG_INIT_PLAYBACK: 1915 case MPEG_INIT_PLAYBACK:
2003 /* Stop the prerecording */ 1916 /* Stop the prerecording */
2004 stop_recording(); 1917 stop_recording();
2005
2006 mp3_play_init(); 1918 mp3_play_init();
2007 mpeg_mode = MPEG_DECODER;
2008
2009 init_playback_done = true; 1919 init_playback_done = true;
2010 break; 1920 break;
2011 1921