diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2005-03-31 06:49:10 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2005-03-31 06:49:10 +0000 |
commit | 928beee0d1b05e0c403288d9cd6a4122c4640223 (patch) | |
tree | 63db67be1faaf8ad67df3b94cbca1e824ac9145c | |
parent | 1e77c70b32e488bd0459a6bcd8e7a2f8677ec659 (diff) | |
download | rockbox-928beee0d1b05e0c403288d9cd6a4122c4640223.tar.gz rockbox-928beee0d1b05e0c403288d9cd6a4122c4640223.zip |
iRiver: Major PCM DMA code cleanup, added pcm_init() and pcm_play_pause()
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6234 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/export/pcm_playback.h | 2 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 133 |
2 files changed, 80 insertions, 55 deletions
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h index 6010293bbd..f6612095e0 100644 --- a/firmware/export/pcm_playback.h +++ b/firmware/export/pcm_playback.h | |||
@@ -19,10 +19,12 @@ | |||
19 | #ifndef PCM_PLAYBACK_H | 19 | #ifndef PCM_PLAYBACK_H |
20 | #define PCM_PLAYBACK_H | 20 | #define PCM_PLAYBACK_H |
21 | 21 | ||
22 | void pcm_init(void); | ||
22 | void pcm_set_frequency(unsigned int frequency); | 23 | void pcm_set_frequency(unsigned int frequency); |
23 | void pcm_play_data(const unsigned char* start, int size, | 24 | void pcm_play_data(const unsigned char* start, int size, |
24 | void (*get_more)(unsigned char** start, long* size)); | 25 | void (*get_more)(unsigned char** start, long* size)); |
25 | void pcm_play_stop(void); | 26 | void pcm_play_stop(void); |
27 | void pcm_play_pause(bool play); | ||
26 | bool pcm_is_playing(void); | 28 | bool pcm_is_playing(void); |
27 | void pcm_set_volume(int volume); | 29 | void pcm_set_volume(int volume); |
28 | 30 | ||
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index bc2218be69..e1afea949d 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c | |||
@@ -42,57 +42,37 @@ | |||
42 | #include <string.h> | 42 | #include <string.h> |
43 | 43 | ||
44 | static bool pcm_playing; | 44 | static bool pcm_playing; |
45 | static int pcm_freq = 0x6; // 44.1 in default | 45 | static bool pcm_paused; |
46 | static int pcm_freq = 0x6; /* 44.1 is default */ | ||
46 | 47 | ||
47 | /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ | 48 | /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ |
48 | static void dma_start(const void *addr_r, long size) | 49 | static void dma_start(const void *addr, long size) |
49 | { | 50 | { |
50 | pcm_playing = 1; | 51 | pcm_playing = true; |
51 | int i; | ||
52 | |||
53 | int align; | ||
54 | align = 4; | ||
55 | |||
56 | void* addr = (void*)((((unsigned int)addr_r) >> 2) << 2); // always align data, never pass unaligned data | ||
57 | size = (size >> 2) << 2; // size shoudl also be always multiple of 4 | ||
58 | 52 | ||
59 | BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */ | 53 | addr = (void *)((unsigned long)addr & ~3); /* Align data */ |
54 | size &= ~3; /* Size must be multiple of 4 */ | ||
60 | 55 | ||
56 | /* Reset the audio FIFO */ | ||
57 | IIS2CONFIG = 0x800; | ||
58 | |||
61 | /* Set up DMA transfer */ | 59 | /* Set up DMA transfer */ |
62 | DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ | 60 | SAR0 = ((unsigned long)addr); /* Source address */ |
63 | SAR0 = ((unsigned long)addr) + align*4; /* Source address */ | 61 | DAR0 = (unsigned long)&PDOR3; /* Destination address */ |
64 | DAR0 = (unsigned long)&PDOR3; /* Destination address */ | 62 | BCR0 = size; /* Bytes to transfer */ |
65 | BCR0 = size-(align*4); /* Bytes to transfer */ | ||
66 | DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1; | ||
67 | DMACONFIG = 1; /* Enable DMA0Req => set DMAROUTE |= DMA0_REQ_AUDIO_1 */ | ||
68 | |||
69 | /* Start transfer when requested */ | ||
70 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_SINC; | ||
71 | |||
72 | /* Enable interrupt at level 7, priority 0 */ | ||
73 | ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00; | ||
74 | IMR &= ~(1<<14); /* bit 14 is DMA0 */ | ||
75 | 63 | ||
76 | IIS2CONFIG = (pcm_freq << 12) | 0x300; /* CLOCKSEL for right frequency + data source = PDOR3 */ | 64 | /* Enable the FIFO and force one write to it */ |
77 | 65 | IIS2CONFIG = (pcm_freq << 12) | 0x300; | |
78 | for(i = 0; i < align; i++) | 66 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_SINC | DMA_START; |
79 | PDOR3 = ((unsigned int*)(addr))[i]; /* These are needed to generate FIFO empty request to DMA.. */ | ||
80 | } | 67 | } |
81 | 68 | ||
82 | /* Stops the DMA transfer and interrupt */ | 69 | /* Stops the DMA transfer and interrupt */ |
83 | static void dma_stop(void) | 70 | static void dma_stop(void) |
84 | { | 71 | { |
85 | pcm_playing = 0; | 72 | pcm_playing = false; |
86 | DCR0 = 0; | ||
87 | |||
88 | /* DMAROUTE &= 0xffffff00; | ||
89 | DMACONFIG = 0;*/ | ||
90 | 73 | ||
74 | /* Reset the FIFO */ | ||
91 | IIS2CONFIG = 0x800; | 75 | IIS2CONFIG = 0x800; |
92 | |||
93 | /* Disable DMA0 interrupt */ | ||
94 | IMR |= (1<<14); | ||
95 | ICR4 &= 0xffff00ff; | ||
96 | } | 76 | } |
97 | 77 | ||
98 | 78 | ||
@@ -113,8 +93,8 @@ void pcm_set_volume(int volume) | |||
113 | /* sets frequency of input to DAC */ | 93 | /* sets frequency of input to DAC */ |
114 | void pcm_set_frequency(unsigned int frequency) | 94 | void pcm_set_frequency(unsigned int frequency) |
115 | { | 95 | { |
116 | switch(frequency) | 96 | switch(frequency) |
117 | { | 97 | { |
118 | case 11025: | 98 | case 11025: |
119 | pcm_freq = 0x2; | 99 | pcm_freq = 0x2; |
120 | break; | 100 | break; |
@@ -126,7 +106,8 @@ void pcm_set_frequency(unsigned int frequency) | |||
126 | break; | 106 | break; |
127 | default: | 107 | default: |
128 | pcm_freq = 0x6; | 108 | pcm_freq = 0x6; |
129 | } | 109 | break; |
110 | } | ||
130 | } | 111 | } |
131 | 112 | ||
132 | /* the registered callback function to ask for more mp3 data */ | 113 | /* the registered callback function to ask for more mp3 data */ |
@@ -145,6 +126,23 @@ void pcm_play_stop(void) | |||
145 | dma_stop(); | 126 | dma_stop(); |
146 | } | 127 | } |
147 | 128 | ||
129 | void pcm_play_pause(bool play) | ||
130 | { | ||
131 | if(pcm_paused && play) | ||
132 | { | ||
133 | /* Enable the FIFO and force one write to it */ | ||
134 | IIS2CONFIG = (pcm_freq << 12) | 0x300; | ||
135 | DCR0 |= DMA_START; | ||
136 | |||
137 | pcm_paused = false; | ||
138 | } | ||
139 | else if(!pcm_paused && !play) | ||
140 | { | ||
141 | IIS2CONFIG = 0x800; | ||
142 | pcm_paused = true; | ||
143 | } | ||
144 | } | ||
145 | |||
148 | bool pcm_is_playing(void) | 146 | bool pcm_is_playing(void) |
149 | { | 147 | { |
150 | return pcm_playing; | 148 | return pcm_playing; |
@@ -161,26 +159,51 @@ void DMA0(void) | |||
161 | 159 | ||
162 | DSR0 = 1; /* Clear interrupt */ | 160 | DSR0 = 1; /* Clear interrupt */ |
163 | 161 | ||
164 | if(res == 0x41) | 162 | /* Stop on error */ |
163 | if(res & 0x70) | ||
165 | { | 164 | { |
166 | dma_stop(); | 165 | dma_stop(); |
167 | } | 166 | } |
168 | |||
169 | if (callback_for_more) | ||
170 | { | ||
171 | callback_for_more(&start, &size); | ||
172 | } | ||
173 | |||
174 | if(size) | ||
175 | { | ||
176 | SAR0 = (unsigned long)start; /* Source address */ | ||
177 | BCR0 = size; /* Bytes to transfer */ | ||
178 | } | ||
179 | else | 167 | else |
180 | { | 168 | { |
181 | /* Finished playing */ | 169 | if (callback_for_more) |
182 | dma_stop(); | 170 | { |
171 | callback_for_more(&start, &size); | ||
172 | } | ||
173 | |||
174 | if(size) | ||
175 | { | ||
176 | SAR0 = (unsigned long)start; /* Source address */ | ||
177 | BCR0 = size; /* Bytes to transfer */ | ||
178 | } | ||
179 | else | ||
180 | { | ||
181 | /* Finished playing */ | ||
182 | dma_stop(); | ||
183 | } | ||
183 | } | 184 | } |
184 | 185 | ||
185 | IPR |= (1<<14); /* Clear pending interrupt request */ | 186 | IPR |= (1<<14); /* Clear pending interrupt request */ |
186 | } | 187 | } |
188 | |||
189 | void pcm_init(void) | ||
190 | { | ||
191 | pcm_playing = false; | ||
192 | pcm_paused = false; | ||
193 | |||
194 | uda1380_init(); | ||
195 | |||
196 | BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */ | ||
197 | DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ | ||
198 | DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1; | ||
199 | DMACONFIG = 1; /* DMA0Req = PDOR3 */ | ||
200 | |||
201 | /* Reset the audio FIFO */ | ||
202 | IIS2CONFIG = 0x800; | ||
203 | |||
204 | /* Enable interrupt at level 7, priority 0 */ | ||
205 | ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00; | ||
206 | IMR &= ~(1<<14); /* bit 14 is DMA0 */ | ||
207 | |||
208 | pcm_set_frequency(44100); | ||
209 | } | ||