From 2c0b72f103e5d924da78f089cea778363e8d4bed Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Mon, 25 Nov 2002 00:02:54 +0000 Subject: Saves battery when monitoring, no longer trashes the first frame, corrected DMA timing git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2885 a1c6a512-1295-4272-9138-f99709370657 --- firmware/mpeg.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 5 deletions(-) (limited to 'firmware') diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 10316b93fb..b5d82897f0 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c @@ -42,6 +42,7 @@ extern void bitswap(unsigned char *data, int length); static void init_recording(void); static void init_playback(void); static void start_recording(void); +static void stop_recording(void); #endif #ifndef SIMULATOR @@ -629,6 +630,45 @@ long timing_info_index = 0; long timing_info[1024]; bool inverted_pr; unsigned long num_rec_bytes; + +void drain_dma_buffer(void) +{ + if(inverted_pr) + { + while((*((volatile unsigned char *)PBDR_ADDR) & 0x40)) + { + PADR |= 0x800; + + while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); + + /* It must take at least 5 cycles before + the data is read */ + asm(" nop\n nop\n nop\n"); + asm(" nop\n nop\n nop\n"); + PADR &= ~0x800; + + while(!(*((volatile unsigned char *)PBDR_ADDR) & 0x80)); + } + } + else + { + while((*((volatile unsigned char *)PBDR_ADDR) & 0x40)) + { + PADR &= ~0x800; + + while(*((volatile unsigned char *)PBDR_ADDR) & 0x80); + + /* It must take at least 5 cycles before + the data is read */ + asm(" nop\n nop\n nop\n"); + asm(" nop\n nop\n nop\n"); + + PADR |= 0x800; + + while(!(*((volatile unsigned char *)PBDR_ADDR) & 0x80)); + } + } +} #endif static void dma_tick (void) __attribute__ ((section (".icode"))); @@ -702,6 +742,7 @@ static void dma_tick(void) /* It must take at least 5 cycles before the data is read */ + asm(" nop\n nop\n nop\n"); mp3buf[mp3buf_write++] = *(unsigned char *)0x4000000; if(mp3buf_write >= mp3buflen) @@ -1656,7 +1697,7 @@ static void mpeg_thread(void) case MPEG_STOP: DEBUGF("MPEG_STOP\n"); demand_irq_enable(false); - is_recording = false; + stop_recording(); /* Save the remaining data in the buffer */ stop_pending = true; @@ -1970,9 +2011,6 @@ static void init_playback(void) void mpeg_record(char *filename) { - /* Read the current frame */ - mas_readmem(MAS_BANK_D0, 0xfd0, &record_start_frame, 1); - num_rec_bytes = 0; is_recording = true; queue_post(&mpeg_queue, MPEG_RECORD, (void*)filename); @@ -1980,10 +2018,35 @@ void mpeg_record(char *filename) static void start_recording(void) { + unsigned long val; + + /* Stop monitoring and record for real */ + mas_readmem(MAS_BANK_D0, 0x7f1, &val, 1); + val &= ~(1 << 10); + val |= 1; + mas_writemem(MAS_BANK_D0, 0x7f1, &val, 1); + + /* Read the current frame */ + mas_readmem(MAS_BANK_D0, 0xfd0, &record_start_frame, 1); + stop_pending = false; saving = false; } +static void stop_recording(void) +{ + unsigned long val; + + is_recording = false; + + /* Start monitoring */ + mas_readmem(MAS_BANK_D0, 0x7f1, &val, 1); + val |= (1 << 10) | 1; + mas_writemem(MAS_BANK_D0, 0x7f1, &val, 1); + + drain_dma_buffer(); +} + unsigned long mpeg_num_recorded_frames(void) { unsigned long val; @@ -2554,7 +2617,8 @@ void mpeg_set_recording_options(int frequency, int quality, DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f0, %x)\n", val); - val = (((source < 2)?1:2) << 8) | /* Input select */ + val = ((1 << 10) | /* Monitoring on */ + ((source < 2)?1:2) << 8) | /* Input select */ (1 << 5) | /* SDO strobe invert */ ((is_mpeg1?0:1) << 3) | (1 << 2) | /* Inverted SIBC clock signal */ @@ -2563,6 +2627,8 @@ void mpeg_set_recording_options(int frequency, int quality, DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f1, %x)\n", val); + drain_dma_buffer(); + if(source == 0) /* Mic */ { /* Copy left channel to right (mono mode) */ -- cgit v1.2.3