1 /***************************************************************************
5 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
7 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
9 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
11 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
19 * Copyright (C) 2002 by Linus Nielsen Feltzing
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version 2
27 * of the License, or (at your option) any later version.
31 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
33 * KIND, either express or implied.
37 ****************************************************************************/
79 #define MIN(a, b) (((a)<(b))?(a):(b))
93 #define MPEG_NEED_DATA 100
97 #define MP3_LOW_WATER 0x30000
99 #define MP3_CHUNK_SIZE 0x20000
103 unsigned int bass_table
[] =
143 unsigned int treble_table
[] =
183 unsigned char fliptable
[] =
187 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
189 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
191 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
193 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
195 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
197 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
199 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
201 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
203 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
205 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
207 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
209 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
211 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
213 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
215 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
217 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
219 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
221 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
223 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
225 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
227 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
229 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
231 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
233 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
235 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
237 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
239 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
241 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
243 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
245 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
247 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
249 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
255 extern unsigned int stack
[];
257 /* Place the MP3 data right after the stack */
261 #define MP3BUF_LEN 0x100000 /* 1 Mbyte */
265 unsigned char *mp3buf
= (unsigned char *)stack
;
279 int last_dma_chunk_size
;
283 bool dma_on
; /* The DMA is active */
285 bool playing
; /* We are playing an MP3 stream */
287 bool filling
; /* We are filling the buffer with data from disk */
291 struct event_queue mpeg_queue
;
295 static void mas_poll_start(unsigned int interval_in_ms
);
297 void mpeg_thread(void);
301 void reset_mp3_buffer(void)
313 void setup_sci0(void)
317 /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0 */
319 PBCR1
= (PBCR1
& 0x0cff) | 0x1200;
323 /* Set PB12 to output */
329 /* Disable serial port */
335 /* Synchronous, no prescale */
341 /* Set baudrate 1Mbit/s */
347 /* use SCK as serial clock output */
353 /* Clear FER and PER */
359 /* Set interrupt ITU2 and SCI0 priority to 0 */
365 /* set IRQ6 and IRQ7 to edge detect */
371 /* set PB15 and PB14 to inputs */
379 /* set IRQ6 prio 8 and IRQ7 prio 0 */
381 IPRB
= ( IPRB
& 0xff00 ) | 0x0080;
385 /* Enable End of DMA interrupt at prio 8 */
387 IPRC
= (IPRC
& 0xf0ff) | 0x0800;
391 /* Enable Tx (only!) */
405 SAR3
= (unsigned int) mp3buf
+ mp3buf_read
;
409 CHCR3
&= ~0x0002; /* Clear interrupt */
411 CHCR3
= 0x1504; /* Single address destination, TXI0, IE=1 */
413 last_dma_chunk_size
= MIN(65536, mp3buf_write
- mp3buf_read
);
415 DTCR3
= last_dma_chunk_size
& 0xffff;
417 DMAOR
= 0x0001; /* Enable DMA */
419 CHCR3
|= 0x0001; /* Enable DMA IRQ */
453 /* Start DMA if it isn't running */
455 if(playing
&& !dma_on
)
475 void bitswap(unsigned char *data
, int length
)
481 for(i
= 0;i
< length
;i
++)
485 data
[i
] = fliptable
[data
[i
]];
509 int volume
, bass
, treble
;
511 unsigned short frame_count
;
517 SSR1
&= ~(SCI_RDRF
| SCI_ORER
| SCI_PER
| SCI_FER
);
521 /* This enables the serial Rx interrupt, to be able to exit into the
523 debugger when you hit CTRL-C */
531 IPRE
|= 0xf000; /* Highest priority */
555 i
=mas_readmem(MAS_BANK_D1
,0xff6,(unsigned long*)buf
,2);
559 debugf("Error - mas_readmem() returned %d\n", i
);
567 i
= buf
[0] | buf
[1] << 8;
569 debugf("MAS version: %x\n", i
);
571 i
= buf
[4] | buf
[5] << 8;
573 debugf("MAS revision: %x\n", i
);
577 i
=mas_readmem(MAS_BANK_D1
,0xff9,(unsigned long*)buf
,7);
581 debugf("Error - mas_readmem() returned %d\n", i
);
593 str
[i
*2+1] = buf
[i
*4];
595 str
[i
*2] = buf
[i
*4+1];
601 debugf("Description: %s\n", str
);
605 i
=mas_writereg(0x3b, 0x20);
609 debugf("Error - mas_writereg() returned %d\n", i
);
621 debugf("Error - mas_run() returned %d\n", i
);
631 debugf("ata_init() returned %d\n", i
);
637 debugf("disk_init() returned %d\n", i
);
641 debugf("part[0] starts at sector %d\n", part
[0].start
);
645 i
= fat_mount(IF_MV2(0,) IF_MV2(0,) part
[0].start
);
647 debugf("fat_mount() returned %d\n", i
);
653 if((d
= opendir("/")))
657 while((dent
= readdir(d
)))
661 debugf("%s\n", dent
->d_name
);
663 i
= strlen(dent
->d_name
);
665 tmp
= dent
->d_name
+ i
- 4;
669 if(!stricmp(tmp
, ".mp3"))
679 debugf("Adding track %s\n", dent
->d_name
);
681 snprintf(tmp
, i
+1, "/%s", dent
->d_name
);
683 tracks
[num_tracks
++] = tmp
;
691 panicf("Out of memory\n");
705 debugf("Number of tracks: %d\n");
709 queue_init(&mpeg_queue
);
713 create_thread(mpeg_thread
, stack
- 0x2000, 0x4000, 0);
721 debugf("let's play...\n");
725 queue_post(&mpeg_queue
, MPEG_PLAY
, 0);
733 if(dac_config(0x04) < 0)
735 debugf("DAC write failed\n");
739 if(dac_volume(volume
) < 0)
741 debugf("DAC write failed\n");
751 mas_writereg(MAS_REG_KPRESCALE
, 0xe9400);
753 mas_writereg(MAS_REG_KBASS
, bass_table
[bass
]);
755 mas_writereg(MAS_REG_KTREBLE
, treble_table
[treble
]);
771 void IRQ6(void) __attribute__((interrupt_handler
));
783 void DEI3(void) __attribute__((interrupt_handler
));
789 int unplayed_space_left
;
791 int space_until_end_of_buffer
;
799 mp3buf_read
+= last_dma_chunk_size
;
801 if(mp3buf_read
>= MP3BUF_LEN
)
807 unplayed_space_left
= mp3buf_write
- mp3buf_read
;
809 if(unplayed_space_left
< 0)
811 unplayed_space_left
= MP3BUF_LEN
+ unplayed_space_left
;
815 space_until_end_of_buffer
= MP3BUF_LEN
- mp3buf_read
;
819 if(!filling
&& unplayed_space_left
< MP3_LOW_WATER
)
823 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
829 if(unplayed_space_left
)
833 last_dma_chunk_size
= MIN(65536, unplayed_space_left
);
835 last_dma_chunk_size
= MIN(last_dma_chunk_size
, space_until_end_of_buffer
);
837 DTCR3
= last_dma_chunk_size
& 0xffff;
839 SAR3
= (unsigned int)mp3buf
+ mp3buf_read
;
847 debugf("No more MP3 data. Stopping.\n");
849 CHCR3
= 0; /* Stop DMA interrupt */
857 CHCR3
&= ~0x0002; /* Clear DMA interrupt */
863 static void mas_poll_start(unsigned int interval_in_ms
)
871 count
= FREQ
/ 1000 / 8 * interval_in_ms
;
879 panicf("Error! The MAS poll interval is too long (%d ms)\n",
889 /* We are using timer 1 */
893 TSTR
&= ~0x02; /* Stop the timer */
895 TSNC
&= ~0x02; /* No synchronization */
897 TMDR
&= ~0x02; /* Operate normally */
901 TCNT1
= 0; /* Start counting at 0 */
905 TCR1
= 0x23; /* Clear at GRA match, sysclock/8 */
909 /* Enable interrupt on level 2 */
911 IPRC
= (IPRC
& ~0x000f) | 0x0002;
917 TIER1
= 0xf9; /* Enable GRA match interrupt */
921 TSTR
|= 0x02; /* Start timer 2 */
927 void IMIA1(void) __attribute__((interrupt_handler
));
943 char *peek_next_track(int index
)
947 if(track_index
< num_tracks
)
949 return tracks
[track_index
+index
];
959 void next_track(void)
981 trackname
= peek_next_track(0);
985 debugf("playing %s\n", trackname
);
987 mpeg_file
= open(trackname
, O_RDONLY
);
993 debugf("Couldn't open file\n");
1005 void mpeg_thread(void)
1009 struct queue_event ev
;
1013 int free_space_left
;
1021 play_pending
= false;
1033 queue_wait(&mpeg_queue
, &ev
);
1041 /* Stop the current stream */
1043 play_pending
= false;
1059 /* Make it read more data */
1063 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1067 /* Tell the file loading code that we want to start playing
1069 as soon as we have some data */
1071 play_pending
= true;
1079 /* Stop the current stream */
1091 /* Stop the current stream */
1103 /* Stop the current stream */
1113 case MPEG_NEED_DATA
:
1115 free_space_left
= mp3buf_read
- mp3buf_write
;
1119 /* We interpret 0 as "empty buffer" */
1121 if(free_space_left
<= 0)
1123 free_space_left
= MP3BUF_LEN
+ free_space_left
;
1127 if(free_space_left
<= MP3_CHUNK_SIZE
)
1143 amount_to_read
= MIN(MP3_CHUNK_SIZE
, free_space_left
);
1145 amount_to_read
= MIN(MP3BUF_LEN
- mp3buf_write
, amount_to_read
);
1149 /* Read in a few seconds worth of MP3 data. We don't want to
1151 read too large chunks because the bitswapping will take
1153 too much time. We must keep the DMA happy and also give
1155 the other threads a chance to run. */
1159 len
= read(mpeg_file
, mp3buf
+mp3buf_write
, amount_to_read
);
1167 bitswap(mp3buf
+ mp3buf_write
, len
);
1171 mp3buf_write
+= len
;
1173 if(mp3buf_write
>= MP3BUF_LEN
)
1185 /* Tell ourselves that we want more data */
1187 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1191 /* And while we're at it, see if we have startet playing
1193 yet. If not, do it. */
1199 play_pending
= false;
1221 /* Make sure that the write pointer is at a word
1225 mp3buf_write
&= 0xfffffffe;
1235 /* No more data to play */
1237 debugf("Finished playing\n");
1251 /* Tell ourselves that we want more data */
1253 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1269 /* Newlib trap honeypot */
1275 debugf("newlib trap34\n");