From 8ffeab5fc93d095c1fd21ebfa53488f7a2e5d939 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Fri, 18 Mar 2005 11:39:28 +0000 Subject: PCM playback for iRiver git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6210 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 8 +++ firmware/export/pcm_playback.h | 27 +++++++++ firmware/pcm_playback.c | 132 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 firmware/export/pcm_playback.h create mode 100644 firmware/pcm_playback.c diff --git a/firmware/SOURCES b/firmware/SOURCES index 94274b398e..870026f835 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -70,7 +70,11 @@ drivers/fmradio_i2c.c tuner_philips.c #endif #endif +#if CONFIG_I2C == I2C_H100 +drivers/i2c-h100.c +#else drivers/i2c.c +#endif #if CONFIG_HWCODEC != MASNONE drivers/mas.c #endif @@ -107,3 +111,7 @@ bitswap.S descramble.S #endif drivers/lcd.S +#if defined(IRIVER_H100) && !defined(SIMULATOR) +drivers/uda1380.c +pcm_playback.c +#endif diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h new file mode 100644 index 0000000000..c44fb283ec --- /dev/null +++ b/firmware/export/pcm_playback.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef PCM_PLAYBACK_H +#define PCM_PLAYBACK_H + +void pcm_play_data(const unsigned char* start, int size, + void (*get_more)(unsigned char** start, long* size)); +void pcm_play_stop(void); +bool pcm_is_playing(void); + +#endif diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c new file mode 100644 index 0000000000..fba85f083b --- /dev/null +++ b/firmware/pcm_playback.c @@ -0,0 +1,132 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "config.h" +#include "debug.h" +#include "panic.h" +#include +#include "pcm_playback.h" +#ifndef SIMULATOR +#include "cpu.h" +#include "i2c.h" +#include "uda1380.h" +#include "system.h" +#endif + +#include +#include +#include +#include "lcd.h" +#include "button.h" +#include "file.h" +#include "buffer.h" + +bool pcm_playing; + +/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ +static void dma_start(const void *addr, long size) +{ + pcm_playing = 1; + + BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */ + + /* Set up DMA transfer */ + DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ + SAR0 = (unsigned long)addr; /* Source address */ + DAR0 = (unsigned long)&PDOR3; /* Destination address */ + BCR0 = size; /* Bytes to transfer */ + DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1; + DMACONFIG = 1; /* Enable DMA0Req => set DMAROUTE |= DMA0_REQ_AUDIO_1 */ + + /* Start transfer when requested */ + DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_SINC; + + /* Enable interrupt at level 7, priority 0 */ + ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00; + IMR &= ~(1<<14); /* bit 14 is DMA0 */ + + IIS2CONFIG = 0x4300; /* CLOCKSEL = AudioClk/8 (44.1kHz), + data source = PDOR3 */ + + PDOR3 = 0; /* These are needed to generate FIFO empty request to DMA.. */ + PDOR3 = 0; + PDOR3 = 0; + PDOR3 = 0; + PDOR3 = 0; +} + +/* Stops the DMA transfer and interrupt */ +static void dma_stop(void) +{ + pcm_playing = 0; + DCR0 = 0; + + /* Disable DMA0 interrupt */ + IMR |= (1<<14); + ICR4 &= 0xffff00ff; +} + +/* the registered callback function to ask for more mp3 data */ +static void (*callback_for_more)(unsigned char**, long*) = NULL; + +void pcm_play_data(const unsigned char* start, int size, + void (*get_more)(unsigned char** start, long* size)) +{ + callback_for_more = get_more; + + dma_start(start, size); +} + +void pcm_play_stop(void) +{ + dma_stop(); +} + +bool pcm_is_playing(void) +{ + return pcm_playing; +} + +/* DMA0 Interrupt is called when the DMA has finished transfering a chunk */ +void DMA0(void) __attribute__ ((interrupt_handler, section(".icode"))); +void DMA0(void) +{ + unsigned char* start; + long size = 0; + + DSR0 = 1; /* Clear interrupt */ + + if (callback_for_more) + { + callback_for_more(&start, &size); + } + + if(size) + { + SAR0 = (unsigned long)start; /* Source address */ + BCR0 = size; /* Bytes to transfer */ + } + else + { + /* Finished playing */ + dma_stop(); + } + + IPR |= (1<<14); /* Clear pending interrupt request */ +} -- cgit v1.2.3