summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c144
1 files changed, 105 insertions, 39 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 5bf4fe0fd8..52525cf4d1 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -29,7 +29,6 @@
29#include "file.h" 29#include "file.h"
30 30
31#define MPEG_STACK_SIZE 0x2000 31#define MPEG_STACK_SIZE 0x2000
32#define MPEG_BUFSIZE 0x100000
33#define MPEG_CHUNKSIZE 0x20000 32#define MPEG_CHUNKSIZE 0x20000
34#define MPEG_LOW_WATER 0x30000 33#define MPEG_LOW_WATER 0x30000
35 34
@@ -118,7 +117,11 @@ static unsigned char fliptable[] =
118static struct event_queue mpeg_queue; 117static struct event_queue mpeg_queue;
119static int mpeg_stack[MPEG_STACK_SIZE/sizeof(int)]; 118static int mpeg_stack[MPEG_STACK_SIZE/sizeof(int)];
120 119
121static unsigned char mp3buf[ MPEG_BUFSIZE ]; 120/* defined in linker script */
121extern unsigned char mp3buf[];
122extern unsigned char mp3end[];
123
124static int mp3buflen;
122static int mp3buf_write; 125static int mp3buf_write;
123static int mp3buf_read; 126static int mp3buf_read;
124 127
@@ -215,6 +218,52 @@ static void reset_mp3_buffer(void)
215} 218}
216 219
217#pragma interrupt 220#pragma interrupt
221void IRQ6(void)
222{
223 stop_dma();
224}
225
226#pragma interrupt
227void DEI3(void)
228{
229 int unplayed_space_left;
230 int space_until_end_of_buffer;
231
232 if(playing)
233 {
234 mp3buf_read += last_dma_chunk_size;
235 if(mp3buf_read >= mp3buflen)
236 mp3buf_read = 0;
237
238 unplayed_space_left = mp3buf_write - mp3buf_read;
239 if(unplayed_space_left < 0)
240 unplayed_space_left = mp3buflen + unplayed_space_left;
241
242 space_until_end_of_buffer = mp3buflen - mp3buf_read;
243
244 if(!filling && unplayed_space_left < MPEG_LOW_WATER)
245 {
246 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
247 }
248
249 if(unplayed_space_left)
250 {
251 last_dma_chunk_size = MIN(65536, unplayed_space_left);
252 last_dma_chunk_size = MIN(last_dma_chunk_size, space_until_end_of_buffer);
253 DTCR3 = last_dma_chunk_size & 0xffff;
254 SAR3 = (unsigned int)mp3buf + mp3buf_read;
255 }
256 else
257 {
258 DEBUGF("No more MP3 data. Stopping.\n");
259 CHCR3 = 0; /* Stop DMA interrupt */
260 }
261 }
262
263 CHCR3 &= ~0x0002; /* Clear DMA interrupt */
264}
265
266#pragma interrupt
218void IMIA1(void) 267void IMIA1(void)
219{ 268{
220 dma_tick(); 269 dma_tick();
@@ -239,6 +288,7 @@ static void mpeg_thread(void)
239 switch(ev.id) 288 switch(ev.id)
240 { 289 {
241 case MPEG_PLAY: 290 case MPEG_PLAY:
291 DEBUGF("MPEG_PLAY %s\n",ev.data);
242 /* Stop the current stream */ 292 /* Stop the current stream */
243 play_pending = false; 293 play_pending = false;
244 playing = false; 294 playing = false;
@@ -263,18 +313,21 @@ static void mpeg_thread(void)
263 break; 313 break;
264 314
265 case MPEG_STOP: 315 case MPEG_STOP:
316 DEBUGF("MPEG_STOP\n");
266 /* Stop the current stream */ 317 /* Stop the current stream */
267 playing = false; 318 playing = false;
268 stop_dma(); 319 stop_dma();
269 break; 320 break;
270 321
271 case MPEG_PAUSE: 322 case MPEG_PAUSE:
323 DEBUGF("MPEG_PAUSE\n");
272 /* Stop the current stream */ 324 /* Stop the current stream */
273 playing = false; 325 playing = false;
274 stop_dma(); 326 stop_dma();
275 break; 327 break;
276 328
277 case MPEG_RESUME: 329 case MPEG_RESUME:
330 DEBUGF("MPEG_RESUME\n");
278 /* Stop the current stream */ 331 /* Stop the current stream */
279 playing = true; 332 playing = true;
280 start_dma(); 333 start_dma();
@@ -285,7 +338,7 @@ static void mpeg_thread(void)
285 338
286 /* We interpret 0 as "empty buffer" */ 339 /* We interpret 0 as "empty buffer" */
287 if(free_space_left <= 0) 340 if(free_space_left <= 0)
288 free_space_left = MPEG_BUFSIZE + free_space_left; 341 free_space_left = mp3buflen + free_space_left;
289 342
290 if(free_space_left <= MPEG_CHUNKSIZE) 343 if(free_space_left <= MPEG_CHUNKSIZE)
291 { 344 {
@@ -295,7 +348,7 @@ static void mpeg_thread(void)
295 } 348 }
296 349
297 amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left); 350 amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
298 amount_to_read = MIN(MPEG_BUFSIZE - mp3buf_write, amount_to_read); 351 amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
299 352
300 /* Read in a few seconds worth of MP3 data. We don't want to 353 /* Read in a few seconds worth of MP3 data. We don't want to
301 read too large chunks because the bitswapping will take 354 read too large chunks because the bitswapping will take
@@ -309,7 +362,7 @@ static void mpeg_thread(void)
309 bitswap(mp3buf + mp3buf_write, len); 362 bitswap(mp3buf + mp3buf_write, len);
310 363
311 mp3buf_write += len; 364 mp3buf_write += len;
312 if(mp3buf_write >= MPEG_BUFSIZE) 365 if(mp3buf_write >= mp3buflen)
313 { 366 {
314 mp3buf_write = 0; 367 mp3buf_write = 0;
315 DEBUGF("W\n"); 368 DEBUGF("W\n");
@@ -406,11 +459,51 @@ static void setup_sci0(void)
406 SCR0 |= 0x20; 459 SCR0 |= 0x20;
407} 460}
408 461
462
463void mpeg_play(char* trackname)
464{
465 queue_post(&mpeg_queue, MPEG_PLAY, trackname);
466}
467
468void mpeg_stop(void)
469{
470 queue_post(&mpeg_queue, MPEG_STOP, NULL);
471}
472
473void mpeg_pause(void)
474{
475 queue_post(&mpeg_queue, MPEG_PAUSE, NULL);
476}
477
478void mpeg_resume(void)
479{
480 queue_post(&mpeg_queue, MPEG_RESUME, NULL);
481}
482
483void mpeg_volume(int percent)
484{
485 int volume = 0x2c * percent / 100;
486 dac_volume(volume);
487}
488
489void mpeg_bass(int percent)
490{
491 int bass = 15 * percent / 100;
492 mas_writereg(MAS_REG_KBASS, bass_table[bass]);
493}
494
495void mpeg_treble(int percent)
496{
497 int treble = 15 * percent / 100;
498 mas_writereg(MAS_REG_KTREBLE, treble_table[treble]);
499}
500
409void mpeg_init(void) 501void mpeg_init(void)
410{ 502{
411 int rc; 503 int rc;
412 504
413 setup_sci0(); 505 setup_sci0();
506 i2c_init();
414 507
415#ifdef DEBUG 508#ifdef DEBUG
416 { 509 {
@@ -453,42 +546,15 @@ void mpeg_init(void)
453 mas_poll_start(2); 546 mas_poll_start(2);
454 547
455 mas_writereg(MAS_REG_KPRESCALE, 0xe9400); 548 mas_writereg(MAS_REG_KPRESCALE, 0xe9400);
456}
457
458void mpeg_play(char* trackname)
459{
460 queue_post(&mpeg_queue, MPEG_PLAY, trackname);
461}
462 549
463void mpeg_stop(void) 550 mp3buflen = mp3end - mp3buf;
464{
465 queue_post(&mpeg_queue, MPEG_STOP, NULL);
466}
467 551
468void mpeg_pause(void) 552 if(dac_config(0x04) < 0) {
469{ 553 DEBUGF("dac_config() failed\n");
470 queue_post(&mpeg_queue, MPEG_PAUSE, NULL); 554 }
471}
472
473void mpeg_resume(void)
474{
475 queue_post(&mpeg_queue, MPEG_RESUME, NULL);
476}
477
478void mpeg_volume(int percent)
479{
480 int volume = 0x2c * percent / 100;
481 dac_volume(volume);
482}
483 555
484void mpeg_bass(int percent) 556 mpeg_volume(70);
485{ 557 mpeg_bass(50);
486 int bass = 15 * percent / 100; 558 mpeg_treble(50);
487 mas_writereg(MAS_REG_KBASS, bass_table[bass]);
488}
489 559
490void mpeg_treble(int percent)
491{
492 int treble = 15 * percent / 100;
493 mas_writereg(MAS_REG_KTREBLE, treble_table[treble]);
494} 560}