summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2004-01-05 20:42:51 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2004-01-05 20:42:51 +0000
commitf993365447d8dc5bb28c76a003cecd045c3abaf7 (patch)
tree19d4a2cfebd7e0f43c85559c2e88114fd4ba3223 /firmware/mpeg.c
parent974c2f0d43c1ebc786854f48f15ccaea7803d8f0 (diff)
downloadrockbox-f993365447d8dc5bb28c76a003cecd045c3abaf7.tar.gz
rockbox-f993365447d8dc5bb28c76a003cecd045c3abaf7.zip
Moved the low-level playback functionality into a new, separate module "mp3_playback". This e.g. allows to export a memory playback API to the plugins, opens the door to games with sound, UI sounds, etc.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4192 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c922
1 files changed, 43 insertions, 879 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 43da221800..1dd489a290 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -29,6 +29,7 @@
29#include "errno.h" 29#include "errno.h"
30#include "mp3data.h" 30#include "mp3data.h"
31#include "buffer.h" 31#include "buffer.h"
32#include "mp3_playback.h"
32#ifndef SIMULATOR 33#ifndef SIMULATOR
33#include "i2c.h" 34#include "i2c.h"
34#include "mas.h" 35#include "mas.h"
@@ -43,7 +44,6 @@ extern void bitswap(unsigned char *data, int length);
43 44
44#ifdef HAVE_MAS3587F 45#ifdef HAVE_MAS3587F
45static void init_recording(void); 46static void init_recording(void);
46static void init_playback(void);
47static void start_prerecording(void); 47static void start_prerecording(void);
48static void start_recording(void); 48static void start_recording(void);
49static void stop_recording(void); 49static void stop_recording(void);
@@ -87,116 +87,6 @@ extern int playlist_next(int steps);
87extern int playlist_amount(void); 87extern int playlist_amount(void);
88extern void update_file_pos( int id, int pos ); 88extern void update_file_pos( int id, int pos );
89 89
90static char *units[] =
91{
92 "%", /* Volume */
93 "dB", /* Bass */
94 "dB", /* Treble */
95 "%", /* Balance */
96 "dB", /* Loudness */
97 "%", /* Bass boost */
98 "", /* AVC */
99 "", /* Channels */
100 "dB", /* Left gain */
101 "dB", /* Right gain */
102 "dB", /* Mic gain */
103};
104
105static int numdecimals[] =
106{
107 0, /* Volume */
108 0, /* Bass */
109 0, /* Treble */
110 0, /* Balance */
111 0, /* Loudness */
112 0, /* Bass boost */
113 0, /* AVC */
114 0, /* Channels */
115 1, /* Left gain */
116 1, /* Right gain */
117 1, /* Mic gain */
118};
119
120static int minval[] =
121{
122 0, /* Volume */
123 0, /* Bass */
124 0, /* Treble */
125 -50, /* Balance */
126 0, /* Loudness */
127 0, /* Bass boost */
128 -1, /* AVC */
129 0, /* Channels */
130 0, /* Left gain */
131 0, /* Right gain */
132 0, /* Mic gain */
133};
134
135static int maxval[] =
136{
137 100, /* Volume */
138#ifdef HAVE_MAS3587F
139 24, /* Bass */
140 24, /* Treble */
141#else
142 30, /* Bass */
143 30, /* Treble */
144#endif
145 50, /* Balance */
146 17, /* Loudness */
147 10, /* Bass boost */
148 3, /* AVC */
149 6, /* Channels */
150 15, /* Left gain */
151 15, /* Right gain */
152 15, /* Mic gain */
153};
154
155static int defaultval[] =
156{
157 70, /* Volume */
158#ifdef HAVE_MAS3587F
159 12+6, /* Bass */
160 12+6, /* Treble */
161#else
162 15+7, /* Bass */
163 15+7, /* Treble */
164#endif
165 0, /* Balance */
166 0, /* Loudness */
167 0, /* Bass boost */
168 0, /* AVC */
169 0, /* Channels */
170 8, /* Left gain */
171 8, /* Right gain */
172 2, /* Mic gain */
173};
174
175char *mpeg_sound_unit(int setting)
176{
177 return units[setting];
178}
179
180int mpeg_sound_numdecimals(int setting)
181{
182 return numdecimals[setting];
183}
184
185int mpeg_sound_min(int setting)
186{
187 return minval[setting];
188}
189
190int mpeg_sound_max(int setting)
191{
192 return maxval[setting];
193}
194
195int mpeg_sound_default(int setting)
196{
197 return defaultval[setting];
198}
199
200/* list of tracks in memory */ 90/* list of tracks in memory */
201#define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ 91#define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
202#define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) 92#define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
@@ -216,8 +106,6 @@ static unsigned int last_track_counter = 0;
216 106
217#ifndef SIMULATOR 107#ifndef SIMULATOR
218 108
219static bool mpeg_is_initialized = false;
220
221static int tag_read_idx = 0; 109static int tag_read_idx = 0;
222static int tag_write_idx = 0; 110static int tag_write_idx = 0;
223 111
@@ -371,100 +259,7 @@ static bool playing = false;
371#else 259#else
372static int last_dma_tick = 0; 260static int last_dma_tick = 0;
373 261
374static unsigned long mas_version_code; 262extern unsigned long mas_version_code;
375
376#ifdef HAVE_MAS3507D
377
378static unsigned int bass_table[] =
379{
380 0x9e400, /* -15dB */
381 0xa2800, /* -14dB */
382 0xa7400, /* -13dB */
383 0xac400, /* -12dB */
384 0xb1800, /* -11dB */
385 0xb7400, /* -10dB */
386 0xbd400, /* -9dB */
387 0xc3c00, /* -8dB */
388 0xca400, /* -7dB */
389 0xd1800, /* -6dB */
390 0xd8c00, /* -5dB */
391 0xe0400, /* -4dB */
392 0xe8000, /* -3dB */
393 0xefc00, /* -2dB */
394 0xf7c00, /* -1dB */
395 0,
396 0x800, /* 1dB */
397 0x10000, /* 2dB */
398 0x17c00, /* 3dB */
399 0x1f800, /* 4dB */
400 0x27000, /* 5dB */
401 0x2e400, /* 6dB */
402 0x35800, /* 7dB */
403 0x3c000, /* 8dB */
404 0x42800, /* 9dB */
405 0x48800, /* 10dB */
406 0x4e400, /* 11dB */
407 0x53800, /* 12dB */
408 0x58800, /* 13dB */
409 0x5d400, /* 14dB */
410 0x61800 /* 15dB */
411};
412
413static unsigned int treble_table[] =
414{
415 0xb2c00, /* -15dB */
416 0xbb400, /* -14dB */
417 0xc1800, /* -13dB */
418 0xc6c00, /* -12dB */
419 0xcbc00, /* -11dB */
420 0xd0400, /* -10dB */
421 0xd5000, /* -9dB */
422 0xd9800, /* -8dB */
423 0xde000, /* -7dB */
424 0xe2800, /* -6dB */
425 0xe7e00, /* -5dB */
426 0xec000, /* -4dB */
427 0xf0c00, /* -3dB */
428 0xf5c00, /* -2dB */
429 0xfac00, /* -1dB */
430 0,
431 0x5400, /* 1dB */
432 0xac00, /* 2dB */
433 0x10400, /* 3dB */
434 0x16000, /* 4dB */
435 0x1c000, /* 5dB */
436 0x22400, /* 6dB */
437 0x28400, /* 7dB */
438 0x2ec00, /* 8dB */
439 0x35400, /* 9dB */
440 0x3c000, /* 10dB */
441 0x42c00, /* 11dB */
442 0x49c00, /* 12dB */
443 0x51800, /* 13dB */
444 0x58400, /* 14dB */
445 0x5f800 /* 15dB */
446};
447
448static unsigned int prescale_table[] =
449{
450 0x80000, /* 0db */
451 0x8e000, /* 1dB */
452 0x9a400, /* 2dB */
453 0xa5800, /* 3dB */
454 0xaf400, /* 4dB */
455 0xb8000, /* 5dB */
456 0xbfc00, /* 6dB */
457 0xc6c00, /* 7dB */
458 0xcd000, /* 8dB */
459 0xd25c0, /* 9dB */
460 0xd7800, /* 10dB */
461 0xdc000, /* 11dB */
462 0xdfc00, /* 12dB */
463 0xe3400, /* 13dB */
464 0xe6800, /* 14dB */
465 0xe9400 /* 15dB */
466};
467#endif
468 263
469static struct event_queue mpeg_queue; 264static struct event_queue mpeg_queue;
470static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000]; 265static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000];
@@ -477,7 +272,6 @@ static int mp3buf_read;
477 272
478static int last_dma_chunk_size; 273static int last_dma_chunk_size;
479 274
480static bool dma_on; /* The DMA is active */
481static bool playing; /* We are playing an MP3 stream */ 275static bool playing; /* We are playing an MP3 stream */
482static bool play_pending; /* We are about to start playing */ 276static bool play_pending; /* We are about to start playing */
483static bool is_playing; /* We are (attempting to) playing MP3 files */ 277static bool is_playing; /* We are (attempting to) playing MP3 files */
@@ -562,7 +356,7 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
562 356
563 dbgdata->last_dma_chunk_size = last_dma_chunk_size; 357 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
564 358
565 dbgdata->dma_on = dma_on; 359 dbgdata->dma_on = (SCR0 & 0x80) != 0;
566 dbgdata->playing = playing; 360 dbgdata->playing = playing;
567 dbgdata->play_pending = play_pending; 361 dbgdata->play_pending = play_pending;
568 dbgdata->is_playing = is_playing; 362 dbgdata->is_playing = is_playing;
@@ -577,39 +371,7 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
577 dbgdata->lowest_watermark_level = lowest_watermark_level; 371 dbgdata->lowest_watermark_level = lowest_watermark_level;
578} 372}
579 373
580#ifdef HAVE_MAS3507D 374#ifndef HAVE_MAS3507D
581static void mas_poll_start(int interval_in_ms)
582{
583 unsigned int count;
584
585 count = (FREQ * interval_in_ms) / 1000 / 8;
586
587 if(count > 0xffff)
588 {
589 panicf("Error! The MAS poll interval is too long (%d ms)\n",
590 interval_in_ms);
591 return;
592 }
593
594 /* We are using timer 1 */
595
596 TSTR &= ~0x02; /* Stop the timer */
597 TSNC &= ~0x02; /* No synchronization */
598 TMDR &= ~0x02; /* Operate normally */
599
600 TCNT1 = 0; /* Start counting at 0 */
601 GRA1 = count;
602 TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
603
604 /* Enable interrupt on level 5 */
605 IPRC = (IPRC & ~0x000f) | 0x0005;
606
607 TSR1 &= ~0x02;
608 TIER1 = 0xf9; /* Enable GRA match interrupt */
609
610 TSTR |= 0x02; /* Start timer 1 */
611}
612#else
613static void postpone_dma_tick(void) 375static void postpone_dma_tick(void)
614{ 376{
615 unsigned int count; 377 unsigned int count;
@@ -712,31 +474,6 @@ static int get_unsaved_space(void)
712} 474}
713#endif 475#endif
714 476
715static void init_dma(void)
716{
717 SAR3 = (unsigned int) mp3buf + mp3buf_read;
718 DAR3 = 0x5FFFEC3;
719 CHCR3 &= ~0x0002; /* Clear interrupt */
720 CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */
721 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
722 DTCR3 = last_dma_chunk_size & 0xffff;
723 DMAOR = 0x0001; /* Enable DMA */
724 CHCR3 |= 0x0001; /* Enable DMA IRQ */
725 dma_underrun = false;
726}
727
728static void start_dma(void)
729{
730 SCR0 |= 0x80;
731 dma_on = true;
732}
733
734static void stop_dma(void)
735{
736 SCR0 &= 0x7f;
737 dma_on = false;
738}
739
740#ifdef HAVE_MAS3587F 477#ifdef HAVE_MAS3587F
741#ifdef DEBUG 478#ifdef DEBUG
742static long timing_info_index = 0; 479static long timing_info_index = 0;
@@ -746,7 +483,7 @@ static bool inverted_pr;
746static unsigned long num_rec_bytes; 483static unsigned long num_rec_bytes;
747static unsigned long num_recorded_frames; 484static unsigned long num_recorded_frames;
748 485
749void drain_dma_buffer(void) 486static void drain_dma_buffer(void)
750{ 487{
751 if(inverted_pr) 488 if(inverted_pr)
752 { 489 {
@@ -784,7 +521,8 @@ void drain_dma_buffer(void)
784 } 521 }
785 } 522 }
786} 523}
787#endif 524
525#endif /* #ifdef HAVE_MAS3587F */
788 526
789static void dma_tick (void) __attribute__ ((section (".icode"))); 527static void dma_tick (void) __attribute__ ((section (".icode")));
790static void dma_tick(void) 528static void dma_tick(void)
@@ -796,10 +534,9 @@ static void dma_tick(void)
796 if(playing && !paused) 534 if(playing && !paused)
797 { 535 {
798 /* Start DMA if it is disabled and the DEMAND pin is high */ 536 /* Start DMA if it is disabled and the DEMAND pin is high */
799 if(!dma_on && (PBDR & 0x4000)) 537 if(!(SCR0 & 0x80) && (PBDR & 0x4000))
800 { 538 {
801 if(!(SCR0 & 0x80)) 539 mp3_play_pause(true);
802 start_dma();
803 } 540 }
804 id3tags[tag_read_idx]->id3.elapsed += 541 id3tags[tag_read_idx]->id3.elapsed +=
805 (current_tick - last_dma_tick) * 1000 / HZ; 542 (current_tick - last_dma_tick) * 1000 / HZ;
@@ -807,7 +544,7 @@ static void dma_tick(void)
807 } 544 }
808#ifdef HAVE_MAS3587F 545#ifdef HAVE_MAS3587F
809 } 546 }
810 else 547 else /* MPEG_ENCODER */
811 { 548 {
812 int i; 549 int i;
813 int num_bytes; 550 int num_bytes;
@@ -845,7 +582,7 @@ static void dma_tick(void)
845 /* No wait for /RTW, cause it's not necessary */ 582 /* No wait for /RTW, cause it's not necessary */
846 } 583 }
847 } 584 }
848 else 585 else /* !inverted_pr */
849 { 586 {
850 i = 0; 587 i = 0;
851 while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) 588 while((*((volatile unsigned char *)PBDR_ADDR) & 0x40)
@@ -923,8 +660,8 @@ static void reset_mp3_buffer(void)
923 lowest_watermark_level = mp3buflen; 660 lowest_watermark_level = mp3buflen;
924} 661}
925 662
926#pragma interrupt 663 /* DMA transfer end interrupt callback */
927void DEI3(void) 664static void transfer_end(unsigned char** ppbuf, int* psize)
928{ 665{
929 if(playing && !paused) 666 if(playing && !paused)
930 { 667 {
@@ -976,8 +713,8 @@ void DEI3(void)
976 } 713 }
977 } 714 }
978 715
979 DTCR3 = last_dma_chunk_size & 0xffff; 716 *psize = last_dma_chunk_size & 0xffff;
980 SAR3 = (unsigned int)mp3buf + mp3buf_read; 717 *ppbuf = mp3buf + mp3buf_read;
981 id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size; 718 id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size;
982 719
983 /* Update the watermark debug level */ 720 /* Update the watermark debug level */
@@ -1007,11 +744,10 @@ void DEI3(void)
1007 playing = false; 744 playing = false;
1008 is_playing = false; 745 is_playing = false;
1009 } 746 }
1010 CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ 747 *psize = 0; /* no more transfer */
1011 } 748 }
1012 } 749 }
1013 750
1014 CHCR3 &= ~0x0002; /* Clear DMA interrupt */
1015 wake_up_thread(); 751 wake_up_thread();
1016} 752}
1017 753
@@ -1033,7 +769,7 @@ static void demand_irq_enable(bool on)
1033#endif 769#endif
1034 770
1035#pragma interrupt 771#pragma interrupt
1036void IMIA1(void) 772void IMIA1(void) /* Timer 1 interrupt */
1037{ 773{
1038 dma_tick(); 774 dma_tick();
1039 TSR1 &= ~0x01; 775 TSR1 &= ~0x01;
@@ -1043,15 +779,9 @@ void IMIA1(void)
1043#endif 779#endif
1044} 780}
1045 781
1046#pragma interrupt
1047void IRQ6(void)
1048{
1049 stop_dma();
1050}
1051
1052#ifdef HAVE_MAS3587F 782#ifdef HAVE_MAS3587F
1053#pragma interrupt 783#pragma interrupt
1054void IRQ3(void) 784void IRQ3(void) /* PA15: MAS demand IRQ */
1055{ 785{
1056 /* Begin with setting the IRQ to edge sensitive */ 786 /* Begin with setting the IRQ to edge sensitive */
1057 ICR |= 0x0010; 787 ICR |= 0x0010;
@@ -1170,7 +900,7 @@ static void stop_playing(void)
1170 if(mpeg_file >= 0) 900 if(mpeg_file >= 0)
1171 close(mpeg_file); 901 close(mpeg_file);
1172 mpeg_file = -1; 902 mpeg_file = -1;
1173 stop_dma(); 903 mp3_play_pause(false);
1174 remove_all_tags(); 904 remove_all_tags();
1175} 905}
1176 906
@@ -1237,11 +967,14 @@ static void start_playback_if_ready(void)
1237 play_pending = false; 967 play_pending = false;
1238 playing = true; 968 playing = true;
1239 969
1240 init_dma(); 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
1241 if (!paused) 974 if (!paused)
1242 { 975 {
1243 last_dma_tick = current_tick; 976 last_dma_tick = current_tick;
1244 start_dma(); 977 mp3_play_pause(true);
1245#ifdef HAVE_MAS3587F 978#ifdef HAVE_MAS3587F
1246 demand_irq_enable(true); 979 demand_irq_enable(true);
1247#endif 980#endif
@@ -1376,7 +1109,7 @@ static void mpeg_thread(void)
1376 play_pending = false; 1109 play_pending = false;
1377 playing = false; 1110 playing = false;
1378 paused = false; 1111 paused = false;
1379 stop_dma(); 1112 mp3_play_pause(false);
1380 1113
1381 reset_mp3_buffer(); 1114 reset_mp3_buffer();
1382 remove_all_tags(); 1115 remove_all_tags();
@@ -1435,7 +1168,7 @@ static void mpeg_thread(void)
1435 playing = false; 1168 playing = false;
1436 pause_tick = current_tick; 1169 pause_tick = current_tick;
1437 pause_track = current_track_counter; 1170 pause_track = current_track_counter;
1438 stop_dma(); 1171 mp3_play_pause(false);
1439 break; 1172 break;
1440 1173
1441 case MPEG_RESUME: 1174 case MPEG_RESUME:
@@ -1450,7 +1183,7 @@ static void mpeg_thread(void)
1450 else 1183 else
1451 last_dma_tick = current_tick; 1184 last_dma_tick = current_tick;
1452 pause_tick = 0; 1185 pause_tick = 0;
1453 start_dma(); 1186 mp3_play_pause(true);
1454 } 1187 }
1455 break; 1188 break;
1456 1189
@@ -1463,11 +1196,13 @@ static void mpeg_thread(void)
1463 /* stop the current stream */ 1196 /* stop the current stream */
1464 play_pending = false; 1197 play_pending = false;
1465 playing = false; 1198 playing = false;
1466 stop_dma(); 1199 mp3_play_pause(false);
1467 1200
1468 track_change(); 1201 track_change();
1469 mp3buf_read = id3tags[tag_read_idx]->mempos; 1202 mp3buf_read = id3tags[tag_read_idx]->mempos;
1470 init_dma(); 1203 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1204 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
1205 dma_underrun = false;
1471 last_dma_tick = current_tick; 1206 last_dma_tick = current_tick;
1472 1207
1473 unplayed_space_left = get_unplayed_space(); 1208 unplayed_space_left = get_unplayed_space();
@@ -1486,7 +1221,7 @@ static void mpeg_thread(void)
1486 } else { 1221 } else {
1487 playing = true; 1222 playing = true;
1488 if (!paused) 1223 if (!paused)
1489 start_dma(); 1224 mp3_play_pause(true);
1490 } 1225 }
1491 } 1226 }
1492 else { 1227 else {
@@ -1496,7 +1231,7 @@ static void mpeg_thread(void)
1496 /* stop the current stream */ 1231 /* stop the current stream */
1497 play_pending = false; 1232 play_pending = false;
1498 playing = false; 1233 playing = false;
1499 stop_dma(); 1234 mp3_play_pause(false);
1500 1235
1501 reset_mp3_buffer(); 1236 reset_mp3_buffer();
1502 remove_all_tags(); 1237 remove_all_tags();
@@ -1532,7 +1267,7 @@ static void mpeg_thread(void)
1532 /* stop the current stream */ 1267 /* stop the current stream */
1533 play_pending = false; 1268 play_pending = false;
1534 playing = false; 1269 playing = false;
1535 stop_dma(); 1270 mp3_play_pause(false);
1536 1271
1537 reset_mp3_buffer(); 1272 reset_mp3_buffer();
1538 remove_all_tags(); 1273 remove_all_tags();
@@ -1685,7 +1420,11 @@ static void mpeg_thread(void)
1685 else 1420 else
1686 { 1421 {
1687 /* resume will start at new position */ 1422 /* resume will start at new position */
1688 init_dma(); 1423 last_dma_chunk_size =
1424 MIN(0x2000, get_unplayed_space_current_song());
1425 mp3_play_data(mp3buf + mp3buf_read,
1426 last_dma_chunk_size, transfer_end);
1427 dma_underrun = false;
1689 } 1428 }
1690 } 1429 }
1691 else 1430 else
@@ -2261,7 +2000,9 @@ static void mpeg_thread(void)
2261 break; 2000 break;
2262 2001
2263 case MPEG_INIT_PLAYBACK: 2002 case MPEG_INIT_PLAYBACK:
2264 init_playback(); 2003 mp3_play_init();
2004 mpeg_mode = MPEG_DECODER;
2005
2265 init_playback_done = true; 2006 init_playback_done = true;
2266 break; 2007 break;
2267 2008
@@ -2288,43 +2029,6 @@ static void mpeg_thread(void)
2288#endif 2029#endif
2289 } 2030 }
2290} 2031}
2291
2292static void setup_sci0(void)
2293{
2294 /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */
2295 PBCR1 = (PBCR1 & 0x0cff) | 0x1208;
2296
2297 /* Set PB12 to output */
2298 or_b(0x10, &PBIORH);
2299
2300 /* Disable serial port */
2301 SCR0 = 0x00;
2302
2303 /* Synchronous, no prescale */
2304 SMR0 = 0x80;
2305
2306 /* Set baudrate 1Mbit/s */
2307 BRR0 = 0x03;
2308
2309 /* use SCK as serial clock output */
2310 SCR0 = 0x01;
2311
2312 /* Clear FER and PER */
2313 SSR0 &= 0xe7;
2314
2315 /* Set interrupt ITU2 and SCI0 priority to 0 */
2316 IPRD &= 0x0ff0;
2317
2318 /* set PB15 and PB14 to inputs */
2319 and_b(~0x80, &PBIORH);
2320 and_b(~0x40, &PBIORH);
2321
2322 /* Enable End of DMA interrupt at prio 8 */
2323 IPRC = (IPRC & 0xf0ff) | 0x0800;
2324
2325 /* Enable Tx (only!) */
2326 SCR0 |= 0x20;
2327}
2328#endif /* SIMULATOR */ 2032#endif /* SIMULATOR */
2329 2033
2330#ifdef SIMULATOR 2034#ifdef SIMULATOR
@@ -2364,66 +2068,6 @@ void mpeg_init_playback(void)
2364 wake_up_thread(); 2068 wake_up_thread();
2365} 2069}
2366 2070
2367static void init_playback(void)
2368{
2369 unsigned long val;
2370 int rc;
2371
2372 if(mpeg_mode == MPEG_ENCODER)
2373 stop_recording();
2374
2375 stop_dma();
2376
2377 mas_reset();
2378
2379 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2380 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2381 if(rc < 0)
2382 panicf("mas_ctrl_w: %d", rc);
2383
2384 /* Stop the current application */
2385 val = 0;
2386 mas_writemem(MAS_BANK_D0,0x7f6,&val,1);
2387 do
2388 {
2389 mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1);
2390 } while(val);
2391
2392 /* Enable the D/A Converter */
2393 mas_codec_writereg(0x0, 0x0001);
2394
2395 /* ADC scale 0%, DSP scale 100% */
2396 mas_codec_writereg(6, 0x0000);
2397 mas_codec_writereg(7, 0x4000);
2398
2399 /* Disable SDO and SDI */
2400 val = 0x0d;
2401 mas_writemem(MAS_BANK_D0,0x7f2,&val,1);
2402
2403 /* Set Demand mode and validate all settings */
2404 val = 0x25;
2405 mas_writemem(MAS_BANK_D0,0x7f1,&val,1);
2406
2407 /* Start the Layer2/3 decoder applications */
2408 val = 0x0c;
2409 mas_writemem(MAS_BANK_D0,0x7f6,&val,1);
2410 do
2411 {
2412 mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1);
2413 } while((val & 0x0c) != 0x0c);
2414
2415 mpeg_sound_channel_config(MPEG_SOUND_STEREO);
2416
2417 mpeg_mode = MPEG_DECODER;
2418
2419 /* set IRQ6 to edge detect */
2420 ICR |= 0x02;
2421
2422 /* set IRQ6 prio 8 */
2423 IPRB = ( IPRB & 0xff0f ) | 0x0080;
2424
2425 DEBUGF("MAS Decoding application started\n");
2426}
2427 2071
2428/**************************************************************************** 2072/****************************************************************************
2429 ** 2073 **
@@ -2965,383 +2609,6 @@ void mpeg_error_clear(void)
2965 mpeg_errno = 0; 2609 mpeg_errno = 0;
2966} 2610}
2967 2611
2968#ifndef SIMULATOR
2969#ifdef HAVE_MAS3507D
2970int current_left_volume = 0; /* all values in tenth of dB */
2971int current_right_volume = 0; /* all values in tenth of dB */
2972int current_treble = 0;
2973int current_bass = 0;
2974int current_balance = 0;
2975
2976/* convert tenth of dB volume to register value */
2977static int tenthdb2reg(int db) {
2978 if (db < -540)
2979 return (db + 780) / 30;
2980 else
2981 return (db + 660) / 15;
2982}
2983
2984void set_prescaled_volume(void)
2985{
2986 int prescale;
2987 int l, r;
2988
2989 prescale = MAX(current_bass, current_treble);
2990 if (prescale < 0)
2991 prescale = 0; /* no need to prescale if we don't boost
2992 bass or treble */
2993
2994 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
2995
2996 /* gain up the analog volume to compensate the prescale reduction gain */
2997 l = current_left_volume + prescale;
2998 r = current_right_volume + prescale;
2999
3000 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
3001}
3002#endif /* HAVE_MAS3507D */
3003#endif /* !SIMULATOR */
3004
3005void mpeg_sound_set(int setting, int value)
3006{
3007#ifdef SIMULATOR
3008 setting = value;
3009#else
3010#ifdef HAVE_MAS3507D
3011 int l, r;
3012#else
3013 int tmp;
3014#endif
3015
3016 if(!mpeg_is_initialized)
3017 return;
3018
3019 switch(setting)
3020 {
3021 case SOUND_VOLUME:
3022#ifdef HAVE_MAS3587F
3023 tmp = 0x7f00 * value / 100;
3024 mas_codec_writereg(0x10, tmp & 0xff00);
3025#else
3026 l = value;
3027 r = value;
3028
3029 if(current_balance > 0)
3030 {
3031 l -= current_balance;
3032 if(l < 0)
3033 l = 0;
3034 }
3035
3036 if(current_balance < 0)
3037 {
3038 r += current_balance;
3039 if(r < 0)
3040 r = 0;
3041 }
3042
3043 l = 0x38 * l / 100;
3044 r = 0x38 * r / 100;
3045
3046 /* store volume in tenth of dB */
3047 current_left_volume = ( l < 0x08 ? l*30 - 780 : l*15 - 660 );
3048 current_right_volume = ( r < 0x08 ? r*30 - 780 : r*15 - 660 );
3049
3050 set_prescaled_volume();
3051#endif
3052 break;
3053
3054 case SOUND_BALANCE:
3055#ifdef HAVE_MAS3587F
3056 tmp = ((value * 127 / 100) & 0xff) << 8;
3057 mas_codec_writereg(0x11, tmp & 0xff00);
3058#else
3059 /* Convert to percent */
3060 current_balance = value * 2;
3061#endif
3062 break;
3063
3064 case SOUND_BASS:
3065#ifdef HAVE_MAS3587F
3066 tmp = (((value-12) * 8) & 0xff) << 8;
3067 mas_codec_writereg(0x14, tmp & 0xff00);
3068#else
3069 mas_writereg(MAS_REG_KBASS, bass_table[value]);
3070 current_bass = (value-15) * 10;
3071 set_prescaled_volume();
3072#endif
3073 break;
3074
3075 case SOUND_TREBLE:
3076#ifdef HAVE_MAS3587F
3077 tmp = (((value-12) * 8) & 0xff) << 8;
3078 mas_codec_writereg(0x15, tmp & 0xff00);
3079#else
3080 mas_writereg(MAS_REG_KTREBLE, treble_table[value]);
3081 current_treble = (value-15) * 10;
3082 set_prescaled_volume();
3083#endif
3084 break;
3085
3086#ifdef HAVE_MAS3587F
3087 case SOUND_SUPERBASS:
3088 if (value) {
3089 tmp = MAX(MIN(value * 12, 0x7f), 0);
3090 mas_codec_writereg(MAS_REG_KMDB_STR, (tmp & 0xff) << 8);
3091 tmp = 0x30; /* MDB_HAR: Space for experiment here */
3092 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0xff) << 8);
3093 tmp = 60 / 10; /* calculate MDB_FC, 60hz - experiment here,
3094 this would depend on the earphones...
3095 perhaps make it tunable? */
3096 mas_codec_writereg(MAS_REG_KMDB_FC, (tmp & 0xff) << 8);
3097 tmp = (3 * tmp) / 2; /* calculate MDB_SHAPE */
3098 mas_codec_writereg(MAS_REG_KMDB_SWITCH,
3099 ((tmp & 0xff) << 8) /* MDB_SHAPE */
3100 | 2); /* MDB_SWITCH enable */
3101 } else {
3102 mas_codec_writereg(MAS_REG_KMDB_STR, 0);
3103 mas_codec_writereg(MAS_REG_KMDB_HAR, 0);
3104 mas_codec_writereg(MAS_REG_KMDB_SWITCH, 0); /* MDB_SWITCH disable */
3105 }
3106 break;
3107
3108 case SOUND_LOUDNESS:
3109 tmp = MAX(MIN(value * 4, 0x44), 0);
3110 mas_codec_writereg(MAS_REG_KLOUDNESS, (tmp & 0xff) << 8);
3111 break;
3112
3113 case SOUND_AVC:
3114 switch (value) {
3115 case 1: /* 2s */
3116 tmp = (0x2 << 8) | (0x8 << 12);
3117 break;
3118 case 2: /* 4s */
3119 tmp = (0x4 << 8) | (0x8 << 12);
3120 break;
3121 case 3: /* 8s */
3122 tmp = (0x8 << 8) | (0x8 << 12);
3123 break;
3124 case -1: /* turn off and then turn on again to decay quickly */
3125 tmp = mas_codec_readreg(MAS_REG_KAVC);
3126 mas_codec_writereg(MAS_REG_KAVC, 0);
3127 break;
3128 default: /* off */
3129 tmp = 0;
3130 break;
3131 }
3132 mas_codec_writereg(MAS_REG_KAVC, tmp);
3133 break;
3134#endif
3135 case SOUND_CHANNELS:
3136 mpeg_sound_channel_config(value);
3137 break;
3138 }
3139#endif /* SIMULATOR */
3140}
3141
3142int mpeg_val2phys(int setting, int value)
3143{
3144 int result = 0;
3145
3146 switch(setting)
3147 {
3148 case SOUND_VOLUME:
3149 result = value;
3150 break;
3151
3152 case SOUND_BALANCE:
3153 result = value * 2;
3154 break;
3155
3156 case SOUND_BASS:
3157#ifdef HAVE_MAS3587F
3158 result = value - 12;
3159#else
3160 result = value - 15;
3161#endif
3162 break;
3163
3164 case SOUND_TREBLE:
3165#ifdef HAVE_MAS3587F
3166 result = value - 12;
3167#else
3168 result = value - 15;
3169#endif
3170 break;
3171
3172#ifdef HAVE_MAS3587F
3173 case SOUND_LOUDNESS:
3174 result = value;
3175 break;
3176
3177 case SOUND_SUPERBASS:
3178 result = value * 10;
3179 break;
3180
3181 case SOUND_LEFT_GAIN:
3182 case SOUND_RIGHT_GAIN:
3183 result = (value - 2) * 15;
3184 break;
3185
3186 case SOUND_MIC_GAIN:
3187 result = value * 15 + 210;
3188 break;
3189#endif
3190 }
3191 return result;
3192}
3193
3194int mpeg_phys2val(int setting, int value)
3195{
3196 int result = 0;
3197
3198 switch(setting)
3199 {
3200 case SOUND_VOLUME:
3201 result = value;
3202 break;
3203
3204 case SOUND_BALANCE:
3205 result = value / 2;
3206 break;
3207
3208 case SOUND_BASS:
3209#ifdef HAVE_MAS3587F
3210 result = value + 12;
3211#else
3212 result = value + 15;
3213#endif
3214 break;
3215
3216 case SOUND_TREBLE:
3217#ifdef HAVE_MAS3587F
3218 result = value + 12;
3219#else
3220 result = value + 15;
3221#endif
3222 break;
3223
3224#ifdef HAVE_MAS3587F
3225 case SOUND_SUPERBASS:
3226 result = value / 10;
3227 break;
3228
3229 case SOUND_LOUDNESS:
3230 case SOUND_AVC:
3231 case SOUND_LEFT_GAIN:
3232 case SOUND_RIGHT_GAIN:
3233 case SOUND_MIC_GAIN:
3234 result = value;
3235 break;
3236#endif
3237 }
3238
3239 return result;
3240}
3241
3242
3243void mpeg_sound_channel_config(int configuration)
3244{
3245#ifdef SIMULATOR
3246 (void)configuration;
3247#else
3248 unsigned long val_ll = 0x80000;
3249 unsigned long val_lr = 0;
3250 unsigned long val_rl = 0;
3251 unsigned long val_rr = 0x80000;
3252
3253 switch(configuration)
3254 {
3255 case MPEG_SOUND_STEREO:
3256 val_ll = 0x80000;
3257 val_lr = 0;
3258 val_rl = 0;
3259 val_rr = 0x80000;
3260 break;
3261
3262 case MPEG_SOUND_MONO:
3263 val_ll = 0xc0000;
3264 val_lr = 0xc0000;
3265 val_rl = 0xc0000;
3266 val_rr = 0xc0000;
3267 break;
3268
3269 case MPEG_SOUND_MONO_LEFT:
3270 val_ll = 0x80000;
3271 val_lr = 0x80000;
3272 val_rl = 0;
3273 val_rr = 0;
3274 break;
3275
3276 case MPEG_SOUND_MONO_RIGHT:
3277 val_ll = 0;
3278 val_lr = 0;
3279 val_rl = 0x80000;
3280 val_rr = 0x80000;
3281 break;
3282
3283 case MPEG_SOUND_STEREO_NARROW:
3284 val_ll = 0xa0000;
3285 val_lr = 0xe0000;
3286 val_rl = 0xe0000;
3287 val_rr = 0xa0000;
3288 break;
3289
3290 case MPEG_SOUND_STEREO_WIDE:
3291 val_ll = 0x80000;
3292 val_lr = 0x40000;
3293 val_rl = 0x40000;
3294 val_rr = 0x80000;
3295 break;
3296
3297 case MPEG_SOUND_KARAOKE:
3298 val_ll = 0x80001;
3299 val_lr = 0x7ffff;
3300 val_rl = 0x7ffff;
3301 val_rr = 0x80001;
3302 break;
3303 }
3304
3305#ifdef HAVE_MAS3587F
3306 mas_writemem(MAS_BANK_D0, 0x7fc, &val_ll, 1); /* LL */
3307 mas_writemem(MAS_BANK_D0, 0x7fd, &val_lr, 1); /* LR */
3308 mas_writemem(MAS_BANK_D0, 0x7fe, &val_rl, 1); /* RL */
3309 mas_writemem(MAS_BANK_D0, 0x7ff, &val_rr, 1); /* RR */
3310#else
3311 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
3312 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
3313 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
3314 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
3315#endif
3316#endif
3317}
3318
3319#ifdef HAVE_MAS3587F
3320/* This function works by telling the decoder that we have another
3321 crystal frequency than we actually have. It will adjust its internal
3322 parameters and the result is that the audio is played at another pitch.
3323
3324 The pitch value is in tenths of percent.
3325*/
3326void mpeg_set_pitch(int pitch)
3327{
3328 unsigned long val;
3329
3330 /* invert pitch value */
3331 pitch = 1000000/pitch;
3332
3333 /* Calculate the new (bogus) frequency */
3334 val = 18432*pitch/1000;
3335
3336 mas_writemem(MAS_BANK_D0,0x7f3,&val,1);
3337
3338 /* We must tell the MAS that the frequency has changed.
3339 This will unfortunately cause a short silence. */
3340 val = 0x25;
3341 mas_writemem(MAS_BANK_D0,0x7f1,&val,1);
3342}
3343#endif
3344
3345#ifdef SIMULATOR 2612#ifdef SIMULATOR
3346static char mpeg_stack[DEFAULT_STACK_SIZE]; 2613static char mpeg_stack[DEFAULT_STACK_SIZE];
3347static char mpeg_thread_name[] = "mpeg"; 2614static char mpeg_thread_name[] = "mpeg";
@@ -3364,82 +2631,9 @@ static void mpeg_thread(void)
3364} 2631}
3365#endif 2632#endif
3366 2633
3367void mpeg_init(int volume, int bass, int treble, int balance, int loudness, 2634void mpeg_init(void)
3368 int bass_boost, int avc, int channel_config)
3369{ 2635{
3370 mpeg_errno = 0; 2636 mpeg_errno = 0;
3371
3372#ifdef SIMULATOR
3373 volume = bass = treble = balance = loudness
3374 = bass_boost = avc = channel_config;
3375 create_thread(mpeg_thread, mpeg_stack,
3376 sizeof(mpeg_stack), mpeg_thread_name);
3377#else
3378#ifdef HAVE_MAS3507D
3379 unsigned long val;
3380 loudness = bass_boost = avc;
3381#endif
3382
3383 setup_sci0();
3384
3385#ifdef HAVE_MAS3587F
3386 or_b(0x08, &PAIORH); /* output for /PR */
3387 init_playback();
3388
3389 mas_version_code = mas_readver();
3390 DEBUGF("MAS3587 derivate %d, version B%d\n",
3391 (mas_version_code & 0xff00) >> 8, mas_version_code & 0xff);
3392#endif
3393
3394#ifdef HAVE_DAC3550A
3395 dac_init();
3396#endif
3397
3398#ifdef HAVE_MAS3507D
3399 and_b(~0x20, &PBDRL);
3400 sleep(HZ/5);
3401 or_b(0x20, &PBDRL);
3402 sleep(HZ/5);
3403
3404 /* set IRQ6 to edge detect */
3405 ICR |= 0x02;
3406
3407 /* set IRQ6 prio 8 */
3408 IPRB = ( IPRB & 0xff0f ) | 0x0080;
3409
3410 mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1);
3411
3412 mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */
3413 mas_run(1);
3414 sleep(HZ);
3415
3416 /* Clear the upper 12 bits of the 32-bit samples */
3417 mas_writereg(0xc5, 0);
3418 mas_writereg(0xc6, 0);
3419
3420 /* We need to set the PLL for a 14.1318MHz crystal */
3421 if(mas_version_code == 0x0601) /* Version F10? */
3422 {
3423 val = 0x5d9d0;
3424 mas_writemem(MAS_BANK_D0, 0x32d, &val, 1);
3425 val = 0xfffceceb;
3426 mas_writemem(MAS_BANK_D0, 0x32e, &val, 1);
3427 val = 0x0;
3428 mas_writemem(MAS_BANK_D0, 0x32f, &val, 1);
3429 mas_run(0x475);
3430 }
3431 else
3432 {
3433 val = 0x5d9d0;
3434 mas_writemem(MAS_BANK_D0, 0x36d, &val, 1);
3435 val = 0xfffceceb;
3436 mas_writemem(MAS_BANK_D0, 0x36e, &val, 1);
3437 val = 0x0;
3438 mas_writemem(MAS_BANK_D0, 0x36f, &val, 1);
3439 mas_run(0xfcb);
3440 }
3441
3442#endif
3443 2637
3444 mp3buflen = mp3end - mp3buf; 2638 mp3buflen = mp3end - mp3buf;
3445 2639
@@ -3447,36 +2641,6 @@ void mpeg_init(int volume, int bass, int treble, int balance, int loudness,
3447 create_thread(mpeg_thread, mpeg_stack, 2641 create_thread(mpeg_thread, mpeg_stack,
3448 sizeof(mpeg_stack), mpeg_thread_name); 2642 sizeof(mpeg_stack), mpeg_thread_name);
3449 2643
3450#ifdef HAVE_MAS3507D
3451 mas_poll_start(1);
3452
3453 mas_writereg(MAS_REG_KPRESCALE, 0xe9400);
3454 dac_enable(true);
3455
3456 mpeg_sound_channel_config(channel_config);
3457#endif
3458
3459#ifdef HAVE_MAS3587F
3460 ICR &= ~0x0010; /* IRQ3 level sensitive */
3461 PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */
3462#endif
3463
3464 /* Must be done before calling mpeg_sound_set() */
3465 mpeg_is_initialized = true;
3466
3467 mpeg_sound_set(SOUND_BASS, bass);
3468 mpeg_sound_set(SOUND_TREBLE, treble);
3469 mpeg_sound_set(SOUND_BALANCE, balance);
3470 mpeg_sound_set(SOUND_VOLUME, volume);
3471
3472#ifdef HAVE_MAS3587F
3473 mpeg_sound_channel_config(channel_config);
3474 mpeg_sound_set(SOUND_LOUDNESS, loudness);
3475 mpeg_sound_set(SOUND_SUPERBASS, bass_boost);
3476 mpeg_sound_set(SOUND_AVC, avc);
3477#endif
3478#endif /* !SIMULATOR */
3479
3480 memset(id3tags, sizeof(id3tags), 0); 2644 memset(id3tags, sizeof(id3tags), 0);
3481 memset(_id3tags, sizeof(id3tags), 0); 2645 memset(_id3tags, sizeof(id3tags), 0);
3482 2646