summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-03-18 11:39:28 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-03-18 11:39:28 +0000
commit8ffeab5fc93d095c1fd21ebfa53488f7a2e5d939 (patch)
treeb0efd9ae67be851a82d014a7bb9b2bf4b3763993
parent07218e54019a862deeff7e70a9dcee2eefa30348 (diff)
downloadrockbox-8ffeab5fc93d095c1fd21ebfa53488f7a2e5d939.tar.gz
rockbox-8ffeab5fc93d095c1fd21ebfa53488f7a2e5d939.zip
PCM playback for iRiver
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6210 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES8
-rw-r--r--firmware/export/pcm_playback.h27
-rw-r--r--firmware/pcm_playback.c132
3 files changed, 167 insertions, 0 deletions
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
70tuner_philips.c 70tuner_philips.c
71#endif 71#endif
72#endif 72#endif
73#if CONFIG_I2C == I2C_H100
74drivers/i2c-h100.c
75#else
73drivers/i2c.c 76drivers/i2c.c
77#endif
74#if CONFIG_HWCODEC != MASNONE 78#if CONFIG_HWCODEC != MASNONE
75drivers/mas.c 79drivers/mas.c
76#endif 80#endif
@@ -107,3 +111,7 @@ bitswap.S
107descramble.S 111descramble.S
108#endif 112#endif
109drivers/lcd.S 113drivers/lcd.S
114#if defined(IRIVER_H100) && !defined(SIMULATOR)
115drivers/uda1380.c
116pcm_playback.c
117#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef PCM_PLAYBACK_H
20#define PCM_PLAYBACK_H
21
22void pcm_play_data(const unsigned char* start, int size,
23 void (*get_more)(unsigned char** start, long* size));
24void pcm_play_stop(void);
25bool pcm_is_playing(void);
26
27#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdbool.h>
20#include "config.h"
21#include "debug.h"
22#include "panic.h"
23#include <kernel.h>
24#include "pcm_playback.h"
25#ifndef SIMULATOR
26#include "cpu.h"
27#include "i2c.h"
28#include "uda1380.h"
29#include "system.h"
30#endif
31
32#include <stdio.h>
33#include <string.h>
34#include <stdarg.h>
35#include "lcd.h"
36#include "button.h"
37#include "file.h"
38#include "buffer.h"
39
40bool pcm_playing;
41
42/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
43static void dma_start(const void *addr, long size)
44{
45 pcm_playing = 1;
46
47 BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */
48
49 /* Set up DMA transfer */
50 DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
51 SAR0 = (unsigned long)addr; /* Source address */
52 DAR0 = (unsigned long)&PDOR3; /* Destination address */
53 BCR0 = size; /* Bytes to transfer */
54 DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1;
55 DMACONFIG = 1; /* Enable DMA0Req => set DMAROUTE |= DMA0_REQ_AUDIO_1 */
56
57 /* Start transfer when requested */
58 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_SINC;
59
60 /* Enable interrupt at level 7, priority 0 */
61 ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00;
62 IMR &= ~(1<<14); /* bit 14 is DMA0 */
63
64 IIS2CONFIG = 0x4300; /* CLOCKSEL = AudioClk/8 (44.1kHz),
65 data source = PDOR3 */
66
67 PDOR3 = 0; /* These are needed to generate FIFO empty request to DMA.. */
68 PDOR3 = 0;
69 PDOR3 = 0;
70 PDOR3 = 0;
71 PDOR3 = 0;
72}
73
74/* Stops the DMA transfer and interrupt */
75static void dma_stop(void)
76{
77 pcm_playing = 0;
78 DCR0 = 0;
79
80 /* Disable DMA0 interrupt */
81 IMR |= (1<<14);
82 ICR4 &= 0xffff00ff;
83}
84
85/* the registered callback function to ask for more mp3 data */
86static void (*callback_for_more)(unsigned char**, long*) = NULL;
87
88void pcm_play_data(const unsigned char* start, int size,
89 void (*get_more)(unsigned char** start, long* size))
90{
91 callback_for_more = get_more;
92
93 dma_start(start, size);
94}
95
96void pcm_play_stop(void)
97{
98 dma_stop();
99}
100
101bool pcm_is_playing(void)
102{
103 return pcm_playing;
104}
105
106/* DMA0 Interrupt is called when the DMA has finished transfering a chunk */
107void DMA0(void) __attribute__ ((interrupt_handler, section(".icode")));
108void DMA0(void)
109{
110 unsigned char* start;
111 long size = 0;
112
113 DSR0 = 1; /* Clear interrupt */
114
115 if (callback_for_more)
116 {
117 callback_for_more(&start, &size);
118 }
119
120 if(size)
121 {
122 SAR0 = (unsigned long)start; /* Source address */
123 BCR0 = size; /* Bytes to transfer */
124 }
125 else
126 {
127 /* Finished playing */
128 dma_stop();
129 }
130
131 IPR |= (1<<14); /* Clear pending interrupt request */
132}