summaryrefslogtreecommitdiff
path: root/firmware/mp3_playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/mp3_playback.c')
-rw-r--r--firmware/mp3_playback.c103
1 files changed, 58 insertions, 45 deletions
diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c
index fae8377c4b..4f1d16f9d3 100644
--- a/firmware/mp3_playback.c
+++ b/firmware/mp3_playback.c
@@ -41,11 +41,12 @@ enum
41 MPEG_DECODER, 41 MPEG_DECODER,
42 MPEG_ENCODER 42 MPEG_ENCODER
43} mpeg_mode; 43} mpeg_mode;
44
45extern unsigned long shadow_7f1;
46
47#endif /* #ifdef MAS3587F */ 44#endif /* #ifdef MAS3587F */
48 45
46#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
47extern unsigned long shadow_io_control_main;
48#endif
49
49/**** globals ****/ 50/**** globals ****/
50 51
51/* own version, independent of mpeg.c */ 52/* own version, independent of mpeg.c */
@@ -124,7 +125,7 @@ static const int steps[] =
124static const int minval[] = 125static const int minval[] =
125{ 126{
126 0, /* Volume */ 127 0, /* Volume */
127#if CONFIG_HWCODEC == MAS3587F 128#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
128 -12, /* Bass */ 129 -12, /* Bass */
129 -12, /* Treble */ 130 -12, /* Treble */
130#else 131#else
@@ -149,7 +150,7 @@ static const int minval[] =
149static const int maxval[] = 150static const int maxval[] =
150{ 151{
151 100, /* Volume */ 152 100, /* Volume */
152#if CONFIG_HWCODEC == MAS3587F 153#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
153 12, /* Bass */ 154 12, /* Bass */
154 12, /* Treble */ 155 12, /* Treble */
155#else 156#else
@@ -174,7 +175,7 @@ static const int maxval[] =
174static const int defaultval[] = 175static const int defaultval[] =
175{ 176{
176 70, /* Volume */ 177 70, /* Volume */
177#if CONFIG_HWCODEC == MAS3587F 178#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
178 6, /* Bass */ 179 6, /* Bass */
179 6, /* Treble */ 180 6, /* Treble */
180#else 181#else
@@ -393,7 +394,7 @@ static void postpone_dma_tick(void)
393#endif 394#endif
394 395
395 396
396#if CONFIG_HWCODEC == MAS3587F 397#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
397void demand_irq_enable(bool on) 398void demand_irq_enable(bool on)
398{ 399{
399 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 400 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
@@ -408,7 +409,7 @@ void demand_irq_enable(bool on)
408 409
409 set_irq_level(oldlevel); 410 set_irq_level(oldlevel);
410} 411}
411#endif /* #if CONFIG_HWCODEC == MAS3587F */ 412#endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
412 413
413 414
414void play_tick(void) 415void play_tick(void)
@@ -455,10 +456,10 @@ void IMIA1(void) /* Timer 1 interrupt */
455 if(playing) 456 if(playing)
456 play_tick(); 457 play_tick();
457 TSR1 &= ~0x01; 458 TSR1 &= ~0x01;
458#if CONFIG_HWCODEC == MAS3587F 459#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
459 /* Disable interrupt */ 460 /* Disable interrupt */
460 IPRC &= ~0x000f; 461 IPRC &= ~0x000f;
461#endif /* #if CONFIG_HWCODEC == MAS3587F */ 462#endif
462} 463}
463 464
464#pragma interrupt 465#pragma interrupt
@@ -467,19 +468,21 @@ void IRQ6(void) /* PB14: MAS stop demand IRQ */
467 SCR0 &= ~0x80; 468 SCR0 &= ~0x80;
468} 469}
469 470
470#if CONFIG_HWCODEC == MAS3587F 471#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
471#pragma interrupt 472#pragma interrupt
472void IRQ3(void) /* PA15: MAS demand IRQ */ 473void IRQ3(void) /* PA15: MAS demand IRQ */
473{ 474{
474 /* Begin with setting the IRQ to edge sensitive */ 475 /* Begin with setting the IRQ to edge sensitive */
475 ICR |= 0x0010; 476 ICR |= 0x0010;
476 477
478#if CONFIG_HWCODEC == MAS3587F
477 if(mpeg_mode == MPEG_ENCODER) 479 if(mpeg_mode == MPEG_ENCODER)
478 rec_tick(); 480 rec_tick();
479 else 481 else
482#endif
480 postpone_dma_tick(); 483 postpone_dma_tick();
481} 484}
482#endif /* #if CONFIG_HWCODEC == MAS3587F */ 485#endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
483 486
484static void setup_sci0(void) 487static void setup_sci0(void)
485{ 488{
@@ -519,7 +522,7 @@ static void setup_sci0(void)
519} 522}
520#endif /* SIMULATOR */ 523#endif /* SIMULATOR */
521 524
522#if CONFIG_HWCODEC == MAS3587F 525#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
523static void init_playback(void) 526static void init_playback(void)
524{ 527{
525 unsigned long val; 528 unsigned long val;
@@ -536,10 +539,10 @@ static void init_playback(void)
536 539
537 /* Stop the current application */ 540 /* Stop the current application */
538 val = 0; 541 val = 0;
539 mas_writemem(MAS_BANK_D0,0x7f6,&val,1); 542 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
540 do 543 do
541 { 544 {
542 mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1); 545 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
543 } while(val); 546 } while(val);
544 547
545 /* Enable the D/A Converter */ 548 /* Enable the D/A Converter */
@@ -551,23 +554,25 @@ static void init_playback(void)
551 554
552 /* Disable SDO and SDI */ 555 /* Disable SDO and SDI */
553 val = 0x0d; 556 val = 0x0d;
554 mas_writemem(MAS_BANK_D0,0x7f2,&val,1); 557 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
555 558
556 /* Set Demand mode and validate all settings */ 559 /* Set Demand mode and validate all settings */
557 shadow_7f1 = 0x25; 560 shadow_io_control_main = 0x25;
558 mas_writemem(MAS_BANK_D0,0x7f1,&shadow_7f1,1); 561 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
559 562
560 /* Start the Layer2/3 decoder applications */ 563 /* Start the Layer2/3 decoder applications */
561 val = 0x0c; 564 val = 0x0c;
562 mas_writemem(MAS_BANK_D0,0x7f6,&val,1); 565 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
563 do 566 do
564 { 567 {
565 mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1); 568 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
566 } while((val & 0x0c) != 0x0c); 569 } while((val & 0x0c) != 0x0c);
567 570
568 mpeg_sound_channel_config(MPEG_SOUND_STEREO); 571 mpeg_sound_channel_config(MPEG_SOUND_STEREO);
569 572
573#if CONFIG_HWCODEC == MAS3587F
570 mpeg_mode = MPEG_DECODER; 574 mpeg_mode = MPEG_DECODER;
575#endif
571 576
572 /* set IRQ6 to edge detect */ 577 /* set IRQ6 to edge detect */
573 ICR |= 0x02; 578 ICR |= 0x02;
@@ -577,7 +582,7 @@ static void init_playback(void)
577 582
578 DEBUGF("MAS Decoding application started\n"); 583 DEBUGF("MAS Decoding application started\n");
579} 584}
580#endif /* #if CONFIG_HWCODEC == MAS3587F */ 585#endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
581 586
582#ifndef SIMULATOR 587#ifndef SIMULATOR
583#if CONFIG_HWCODEC == MAS3507D 588#if CONFIG_HWCODEC == MAS3507D
@@ -616,7 +621,7 @@ void set_prescaled_volume(void)
616#endif /* MAS3507D */ 621#endif /* MAS3507D */
617#endif /* !SIMULATOR */ 622#endif /* !SIMULATOR */
618 623
619#if CONFIG_HWCODEC == MAS3587F 624#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
620unsigned long mdb_shape_shadow = 0; 625unsigned long mdb_shape_shadow = 0;
621unsigned long loudness_shadow = 0; 626unsigned long loudness_shadow = 0;
622#endif 627#endif
@@ -638,7 +643,7 @@ void mpeg_sound_set(int setting, int value)
638 switch(setting) 643 switch(setting)
639 { 644 {
640 case SOUND_VOLUME: 645 case SOUND_VOLUME:
641#if CONFIG_HWCODEC == MAS3587F 646#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
642 tmp = 0x7f00 * value / 100; 647 tmp = 0x7f00 * value / 100;
643 mas_codec_writereg(0x10, tmp & 0xff00); 648 mas_codec_writereg(0x10, tmp & 0xff00);
644#else 649#else
@@ -671,7 +676,7 @@ void mpeg_sound_set(int setting, int value)
671 break; 676 break;
672 677
673 case SOUND_BALANCE: 678 case SOUND_BALANCE:
674#if CONFIG_HWCODEC == MAS3587F 679#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
675 tmp = ((value * 127 / 100) & 0xff) << 8; 680 tmp = ((value * 127 / 100) & 0xff) << 8;
676 mas_codec_writereg(0x11, tmp & 0xff00); 681 mas_codec_writereg(0x11, tmp & 0xff00);
677#else 682#else
@@ -680,7 +685,7 @@ void mpeg_sound_set(int setting, int value)
680 break; 685 break;
681 686
682 case SOUND_BASS: 687 case SOUND_BASS:
683#if CONFIG_HWCODEC == MAS3587F 688#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
684 tmp = ((value * 8) & 0xff) << 8; 689 tmp = ((value * 8) & 0xff) << 8;
685 mas_codec_writereg(0x14, tmp & 0xff00); 690 mas_codec_writereg(0x14, tmp & 0xff00);
686#else 691#else
@@ -691,7 +696,7 @@ void mpeg_sound_set(int setting, int value)
691 break; 696 break;
692 697
693 case SOUND_TREBLE: 698 case SOUND_TREBLE:
694#if CONFIG_HWCODEC == MAS3587F 699#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
695 tmp = ((value * 8) & 0xff) << 8; 700 tmp = ((value * 8) & 0xff) << 8;
696 mas_codec_writereg(0x15, tmp & 0xff00); 701 mas_codec_writereg(0x15, tmp & 0xff00);
697#else 702#else
@@ -701,7 +706,7 @@ void mpeg_sound_set(int setting, int value)
701#endif 706#endif
702 break; 707 break;
703 708
704#if CONFIG_HWCODEC == MAS3587F 709#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
705 case SOUND_LOUDNESS: 710 case SOUND_LOUDNESS:
706 loudness_shadow = (loudness_shadow & 0x04) | 711 loudness_shadow = (loudness_shadow & 0x04) |
707 (MAX(MIN(value * 4, 0x44), 0) << 8); 712 (MAX(MIN(value * 4, 0x44), 0) << 8);
@@ -771,7 +776,7 @@ void mpeg_sound_set(int setting, int value)
771 776
772int mpeg_val2phys(int setting, int value) 777int mpeg_val2phys(int setting, int value)
773{ 778{
774#if CONFIG_HWCODEC == MAS3587F 779#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
775 int result = 0; 780 int result = 0;
776 781
777 switch(setting) 782 switch(setting)
@@ -858,11 +863,11 @@ void mpeg_sound_channel_config(int configuration)
858 break; 863 break;
859 } 864 }
860 865
861#if CONFIG_HWCODEC == MAS3587F 866#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
862 mas_writemem(MAS_BANK_D0, 0x7fc, &val_ll, 1); /* LL */ 867 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
863 mas_writemem(MAS_BANK_D0, 0x7fd, &val_lr, 1); /* LR */ 868 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
864 mas_writemem(MAS_BANK_D0, 0x7fe, &val_rl, 1); /* RL */ 869 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
865 mas_writemem(MAS_BANK_D0, 0x7ff, &val_rr, 1); /* RR */ 870 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
866#else 871#else
867 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ 872 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
868 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ 873 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
@@ -872,7 +877,7 @@ void mpeg_sound_channel_config(int configuration)
872#endif 877#endif
873} 878}
874 879
875#if CONFIG_HWCODEC == MAS3587F 880#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
876/* This function works by telling the decoder that we have another 881/* This function works by telling the decoder that we have another
877 crystal frequency than we actually have. It will adjust its internal 882 crystal frequency than we actually have. It will adjust its internal
878 parameters and the result is that the audio is played at another pitch. 883 parameters and the result is that the audio is played at another pitch.
@@ -889,11 +894,11 @@ void mpeg_set_pitch(int pitch)
889 /* Calculate the new (bogus) frequency */ 894 /* Calculate the new (bogus) frequency */
890 val = 18432*pitch/1000; 895 val = 18432*pitch/1000;
891 896
892 mas_writemem(MAS_BANK_D0,0x7f3,&val,1); 897 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
893 898
894 /* We must tell the MAS that the frequency has changed. 899 /* We must tell the MAS that the frequency has changed.
895 This will unfortunately cause a short silence. */ 900 This will unfortunately cause a short silence. */
896 mas_writemem(MAS_BANK_D0,0x7f1,&shadow_7f1,1); 901 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
897} 902}
898#endif 903#endif
899 904
@@ -940,6 +945,14 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness,
940 DEBUGF("MAS3587 derivate %d, version %c%d\n", 945 DEBUGF("MAS3587 derivate %d, version %c%d\n",
941 (mas_version_code & 0xf000) >> 12, 946 (mas_version_code & 0xf000) >> 12,
942 'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff); 947 'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff);
948#elif CONFIG_HW_CODEC == MAS3539F
949 or_b(0x08, &PAIORH); /* output for /PR */
950 init_playback();
951
952 mas_version_code = mas_readver();
953 DEBUGF("MAS3539 derivate %d, version %c%d\n",
954 (mas_version_code & 0xf000) >> 12,
955 'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff);
943#endif 956#endif
944 957
945#ifdef HAVE_DAC3550A 958#ifdef HAVE_DAC3550A
@@ -1001,20 +1014,20 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness,
1001 mpeg_sound_channel_config(channel_config); 1014 mpeg_sound_channel_config(channel_config);
1002#endif 1015#endif
1003 1016
1004#if CONFIG_HWCODEC == MAS3587F 1017#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1005 ICR &= ~0x0010; /* IRQ3 level sensitive */ 1018 ICR &= ~0x0010; /* IRQ3 level sensitive */
1006 PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ 1019 PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */
1007#endif 1020#endif
1008 1021
1009 /* Must be done before calling mpeg_sound_set() */ 1022 /* Must be done before calling mpeg_sound_set() */
1010 mpeg_is_initialized = true; 1023 mpeg_is_initialized = true;
1011 1024
1012 mpeg_sound_set(SOUND_BASS, bass); 1025 mpeg_sound_set(SOUND_BASS, bass);
1013 mpeg_sound_set(SOUND_TREBLE, treble); 1026 mpeg_sound_set(SOUND_TREBLE, treble);
1014 mpeg_sound_set(SOUND_BALANCE, balance); 1027 mpeg_sound_set(SOUND_BALANCE, balance);
1015 mpeg_sound_set(SOUND_VOLUME, volume); 1028 mpeg_sound_set(SOUND_VOLUME, volume);
1016 1029
1017#if CONFIG_HWCODEC == MAS3587F 1030#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1018 mpeg_sound_channel_config(channel_config); 1031 mpeg_sound_channel_config(channel_config);
1019 mpeg_sound_set(SOUND_LOUDNESS, loudness); 1032 mpeg_sound_set(SOUND_LOUDNESS, loudness);
1020 mpeg_sound_set(SOUND_AVC, avc); 1033 mpeg_sound_set(SOUND_AVC, avc);
@@ -1034,9 +1047,9 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness,
1034void mp3_shutdown(void) 1047void mp3_shutdown(void)
1035{ 1048{
1036#ifndef SIMULATOR 1049#ifndef SIMULATOR
1037#if CONFIG_HWCODEC == MAS3587F 1050#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1038 unsigned long val = 1; 1051 unsigned long val = 1;
1039 mas_writemem(MAS_BANK_D0, 0x7f9, &val, 1); /* Mute */ 1052 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &val, 1); /* Mute */
1040#endif 1053#endif
1041 1054
1042#if CONFIG_HWCODEC == MAS3507D 1055#if CONFIG_HWCODEC == MAS3507D
@@ -1052,7 +1065,7 @@ void mp3_shutdown(void)
1052 1065
1053void mp3_play_init(void) 1066void mp3_play_init(void)
1054{ 1067{
1055#if CONFIG_HWCODEC == MAS3587F 1068#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1056 init_playback(); 1069 init_playback();
1057#endif 1070#endif
1058 playing = false; 1071 playing = false;
@@ -1081,7 +1094,7 @@ void mp3_play_data(const unsigned char* start, int size,
1081 1094
1082 CHCR3 |= 0x0001; /* Enable DMA IRQ */ 1095 CHCR3 |= 0x0001; /* Enable DMA IRQ */
1083 1096
1084#if CONFIG_HWCODEC == MAS3587F 1097#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1085 demand_irq_enable(true); 1098 demand_irq_enable(true);
1086#endif 1099#endif
1087} 1100}
@@ -1107,7 +1120,7 @@ void mp3_play_stop(void)
1107 playing = false; 1120 playing = false;
1108 mp3_play_pause(false); 1121 mp3_play_pause(false);
1109 CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ 1122 CHCR3 &= ~0x0001; /* Disable the DMA interrupt */
1110#if CONFIG_HWCODEC == MAS3587F 1123#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1111 demand_irq_enable(false); 1124 demand_irq_enable(false);
1112#endif 1125#endif
1113} 1126}