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.c156
1 files changed, 151 insertions, 5 deletions
diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c
index 9930f10824..fe16676624 100644
--- a/firmware/mp3_playback.c
+++ b/firmware/mp3_playback.c
@@ -34,6 +34,30 @@
34#include "hwcompat.h" 34#include "hwcompat.h"
35#endif 35#endif
36 36
37/* hacking into mpeg.c, recording is still there */
38#ifdef HAVE_MAS3587F
39enum
40{
41 MPEG_DECODER,
42 MPEG_ENCODER
43} mpeg_mode;
44#endif /* #ifdef HAVE_MAS3587F */
45
46/**** globals ****/
47
48/* own version, independent of mpeg.c */
49static bool paused; /* playback is paused */
50static bool playing; /* We are playing an MP3 stream */
51
52#ifndef SIMULATOR
53/* for measuring the play time */
54static long playstart_tick;
55static long cumulative_ticks;
56
57/* the registered callback function to ask for more mp3 data */
58static void (*callback_for_more)(unsigned char**, int*);
59#endif /* #ifndef SIMULATOR */
60
37static char *units[] = 61static char *units[] =
38{ 62{
39 "%", /* Volume */ 63 "%", /* Volume */
@@ -283,10 +307,65 @@ static void mas_poll_start(int interval_in_ms)
283 307
284 TSTR |= 0x02; /* Start timer 1 */ 308 TSTR |= 0x02; /* Start timer 1 */
285} 309}
310#else
311static void postpone_dma_tick(void)
312{
313 unsigned int count;
314
315 count = FREQ / 1000 / 8;
316
317 /* We are using timer 1 */
318
319 TSTR &= ~0x02; /* Stop the timer */
320 TSNC &= ~0x02; /* No synchronization */
321 TMDR &= ~0x02; /* Operate normally */
322
323 TCNT1 = 0; /* Start counting at 0 */
324 GRA1 = count;
325 TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
326
327 /* Enable interrupt on level 5 */
328 IPRC = (IPRC & ~0x000f) | 0x0005;
329
330 TSR1 &= ~0x02;
331 TIER1 = 0xf9; /* Enable GRA match interrupt */
332
333 TSTR |= 0x02; /* Start timer 1 */
334}
286#endif 335#endif
287 336
288/* the registered callback function ta ask for more mp3 data */ 337
289static void (*callback_for_more)(unsigned char**, int*); 338#ifdef HAVE_MAS3587F
339void demand_irq_enable(bool on)
340{
341 int oldlevel = set_irq_level(15);
342
343 if(on)
344 {
345 IPRA = (IPRA & 0xfff0) | 0x000b;
346 ICR &= ~0x0010; /* IRQ3 level sensitive */
347 }
348 else
349 IPRA &= 0xfff0;
350
351 set_irq_level(oldlevel);
352}
353#endif /* #ifdef HAVE_MAS3587F */
354
355
356void play_tick(void)
357{
358 if(playing && !paused)
359 {
360 /* Start DMA if it is disabled and the DEMAND pin is high */
361 if(!(SCR0 & 0x80) && (PBDR & 0x4000))
362 {
363 SCR0 |= 0x80;
364 }
365
366 playback_tick(); /* dirty call to mpeg.c */
367 }
368}
290 369
291#pragma interrupt 370#pragma interrupt
292void DEI3(void) 371void DEI3(void)
@@ -313,10 +392,36 @@ void DEI3(void)
313} 392}
314 393
315#pragma interrupt 394#pragma interrupt
395void IMIA1(void) /* Timer 1 interrupt */
396{
397 if(playing)
398 play_tick();
399 TSR1 &= ~0x01;
400#ifdef HAVE_MAS3587F
401 /* Disable interrupt */
402 IPRC &= ~0x000f;
403#endif /* #ifdef HAVE_MAS3587F */
404}
405
406#pragma interrupt
316void IRQ6(void) /* PB14: MAS stop demand IRQ */ 407void IRQ6(void) /* PB14: MAS stop demand IRQ */
317{ 408{
318 mp3_play_pause(false); 409 SCR0 &= ~0x80;
410}
411
412#ifdef HAVE_MAS3587F
413#pragma interrupt
414void IRQ3(void) /* PA15: MAS demand IRQ */
415{
416 /* Begin with setting the IRQ to edge sensitive */
417 ICR |= 0x0010;
418
419 if(mpeg_mode == MPEG_ENCODER)
420 rec_tick();
421 else
422 postpone_dma_tick();
319} 423}
424#endif /* #ifdef HAVE_MAS3587F */
320 425
321static void setup_sci0(void) 426static void setup_sci0(void)
322{ 427{
@@ -404,6 +509,8 @@ static void init_playback(void)
404 509
405 mpeg_sound_channel_config(MPEG_SOUND_STEREO); 510 mpeg_sound_channel_config(MPEG_SOUND_STEREO);
406 511
512 mpeg_mode = MPEG_DECODER;
513
407 /* set IRQ6 to edge detect */ 514 /* set IRQ6 to edge detect */
408 ICR |= 0x02; 515 ICR |= 0x02;
409 516
@@ -893,6 +1000,9 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness,
893 mpeg_sound_set(SOUND_AVC, avc); 1000 mpeg_sound_set(SOUND_AVC, avc);
894#endif 1001#endif
895#endif /* !SIMULATOR */ 1002#endif /* !SIMULATOR */
1003
1004 playing = false;
1005 paused = true;
896} 1006}
897 1007
898 1008
@@ -905,7 +1015,10 @@ void mp3_play_init(void)
905#ifdef HAVE_MAS3587F 1015#ifdef HAVE_MAS3587F
906 init_playback(); 1016 init_playback();
907#endif 1017#endif
1018 playing = false;
1019 paused = true;
908 callback_for_more = NULL; 1020 callback_for_more = NULL;
1021 mp3_reset_playtime();
909} 1022}
910 1023
911void mp3_play_data(unsigned char* start, int size, 1024void mp3_play_data(unsigned char* start, int size,
@@ -923,21 +1036,54 @@ void mp3_play_data(unsigned char* start, int size,
923 SAR3 = (unsigned int)start; 1036 SAR3 = (unsigned int)start;
924 DTCR3 = size & 0xffff; 1037 DTCR3 = size & 0xffff;
925 1038
1039 playing = true;
1040 paused = true;
1041
926 CHCR3 |= 0x0001; /* Enable DMA IRQ */ 1042 CHCR3 |= 0x0001; /* Enable DMA IRQ */
1043
1044#ifdef HAVE_MAS3587F
1045 demand_irq_enable(true);
1046#endif
927} 1047}
928 1048
929void mp3_play_pause(bool play) 1049void mp3_play_pause(bool play)
930{ 1050{
931 if (play) 1051 if (paused && play)
1052 { /* resume playback */
932 SCR0 |= 0x80; 1053 SCR0 |= 0x80;
933 else 1054 paused = false;
1055 playstart_tick = current_tick;
1056 }
1057 else if (!paused && !play)
1058 { /* stop playback */
934 SCR0 &= 0x7f; 1059 SCR0 &= 0x7f;
1060 paused = true;
1061 cumulative_ticks += current_tick - playstart_tick;
1062 }
935} 1063}
936 1064
937void mp3_play_stop(void) 1065void mp3_play_stop(void)
938{ 1066{
1067 playing = false;
939 mp3_play_pause(false); 1068 mp3_play_pause(false);
940 CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ 1069 CHCR3 &= ~0x0001; /* Disable the DMA interrupt */
1070#ifdef HAVE_MAS3587F
1071 demand_irq_enable(false);
1072#endif
1073}
1074
1075long mp3_get_playtime(void)
1076{
1077 if (paused)
1078 return cumulative_ticks;
1079 else
1080 return cumulative_ticks + current_tick - playstart_tick;
1081}
1082
1083void mp3_reset_playtime(void)
1084{
1085 cumulative_ticks = 0;
1086 playstart_tick = current_tick;
941} 1087}
942 1088
943#endif /* #ifndef SIMULATOR */ 1089#endif /* #ifndef SIMULATOR */