summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/pcm-coldfire.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-06-17 03:09:47 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-06-17 03:09:47 +0000
commitd4800fa3851d2d89c1be03ec99af81f277892579 (patch)
tree60c2beebe08192b2ba6a9c2db31e4409aa940b4e /firmware/target/coldfire/pcm-coldfire.c
parent7b605f04168400f3b1b2024600886045f0103c3a (diff)
downloadrockbox-d4800fa3851d2d89c1be03ec99af81f277892579.tar.gz
rockbox-d4800fa3851d2d89c1be03ec99af81f277892579.zip
Coldfire: Fix the modification of IMR. Interrupts must be masked at the core level at at least the level of the interrupt being masked. Not following the datasheet and relying strictly on and/or_l causes unhandled 'Levelx' exceptions (showing itself quite often in PCM mixer work which more greatly stresses PCM lockout).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30009 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire/pcm-coldfire.c')
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index fa320dff3f..a06542c31f 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -219,19 +219,19 @@ void pcm_postinit(void)
219static struct dma_lock dma_play_lock = 219static struct dma_lock dma_play_lock =
220{ 220{
221 .locked = 0, 221 .locked = 0,
222 .state = (0 << 14) /* bit 14 is DMA0 */ 222 .state = (1 << 14) /* bit 14 is DMA0 */
223}; 223};
224 224
225void pcm_play_lock(void) 225void pcm_play_lock(void)
226{ 226{
227 if (++dma_play_lock.locked == 1) 227 if (++dma_play_lock.locked == 1)
228 or_l((1 << 14), &IMR); 228 coldfire_imr_mod(1 << 14, 1 << 14);
229} 229}
230 230
231void pcm_play_unlock(void) 231void pcm_play_unlock(void)
232{ 232{
233 if (--dma_play_lock.locked == 0) 233 if (--dma_play_lock.locked == 0)
234 and_l(~dma_play_lock.state, &IMR); 234 coldfire_imr_mod(dma_play_lock.state, 1 << 14);
235} 235}
236 236
237/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ 237/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
@@ -248,7 +248,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
248 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_SINC | 248 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_SINC |
249 DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; 249 DMA_SSIZE(DMA_SIZE_LINE) | DMA_START;
250 250
251 dma_play_lock.state = (1 << 14); 251 dma_play_lock.state = (0 << 14);
252} /* pcm_play_dma_start */ 252} /* pcm_play_dma_start */
253 253
254/* Stops the DMA transfer and interrupt */ 254/* Stops the DMA transfer and interrupt */
@@ -260,7 +260,7 @@ void pcm_play_dma_stop(void)
260 260
261 iis_play_reset_if_playback(true); 261 iis_play_reset_if_playback(true);
262 262
263 dma_play_lock.state = (0 << 14); 263 dma_play_lock.state = (1 << 14);
264} /* pcm_play_dma_stop */ 264} /* pcm_play_dma_stop */
265 265
266void pcm_play_dma_pause(bool pause) 266void pcm_play_dma_pause(bool pause)
@@ -271,14 +271,14 @@ void pcm_play_dma_pause(bool pause)
271 and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */ 271 and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */
272 DSR0 = 1; /* stop channel */ 272 DSR0 = 1; /* stop channel */
273 iis_play_reset_if_playback(true); 273 iis_play_reset_if_playback(true);
274 dma_play_lock.state = (0 << 14); 274 dma_play_lock.state = (1 << 14);
275 } 275 }
276 else 276 else
277 { 277 {
278 /* restart playback on current buffer */ 278 /* restart playback on current buffer */
279 iis_play_reset_if_playback(true); 279 iis_play_reset_if_playback(true);
280 or_l(DMA_INT | DMA_EEXT | DMA_START, &DCR0); /* everything ON */ 280 or_l(DMA_INT | DMA_EEXT | DMA_START, &DCR0); /* everything ON */
281 dma_play_lock.state = (1 << 14); 281 dma_play_lock.state = (0 << 14);
282 } 282 }
283} /* pcm_play_dma_pause */ 283} /* pcm_play_dma_pause */
284 284
@@ -344,7 +344,7 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
344static struct dma_lock dma_rec_lock = 344static struct dma_lock dma_rec_lock =
345{ 345{
346 .locked = 0, 346 .locked = 0,
347 .state = (0 << 15) /* bit 15 is DMA1 */ 347 .state = (1 << 15) /* bit 15 is DMA1 */
348}; 348};
349 349
350/* For the locks, DMA interrupt must be disabled when manipulating the lock 350/* For the locks, DMA interrupt must be disabled when manipulating the lock
@@ -353,13 +353,13 @@ static struct dma_lock dma_rec_lock =
353void pcm_rec_lock(void) 353void pcm_rec_lock(void)
354{ 354{
355 if (++dma_rec_lock.locked == 1) 355 if (++dma_rec_lock.locked == 1)
356 or_l((1 << 15), &IMR); 356 coldfire_imr_mod(1 << 15, 1 << 15);
357} 357}
358 358
359void pcm_rec_unlock(void) 359void pcm_rec_unlock(void)
360{ 360{
361 if (--dma_rec_lock.locked == 0) 361 if (--dma_rec_lock.locked == 0)
362 and_l(~dma_rec_lock.state, &IMR); 362 coldfire_imr_mod(dma_rec_lock.state, 1 << 15);
363} 363}
364 364
365void pcm_rec_dma_start(void *addr, size_t size) 365void pcm_rec_dma_start(void *addr, size_t size)
@@ -382,7 +382,7 @@ void pcm_rec_dma_start(void *addr, size_t size)
382 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC | 382 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC |
383 DMA_DSIZE(DMA_SIZE_LINE) | DMA_START; 383 DMA_DSIZE(DMA_SIZE_LINE) | DMA_START;
384 384
385 dma_rec_lock.state = (1 << 15); 385 dma_rec_lock.state = (0 << 15);
386} /* pcm_rec_dma_start */ 386} /* pcm_rec_dma_start */
387 387
388void pcm_rec_dma_stop(void) 388void pcm_rec_dma_stop(void)
@@ -395,7 +395,7 @@ void pcm_rec_dma_stop(void)
395 395
396 iis_play_reset_if_playback(false); 396 iis_play_reset_if_playback(false);
397 397
398 dma_rec_lock.state = (0 << 15); 398 dma_rec_lock.state = (1 << 15);
399} /* pcm_rec_dma_stop */ 399} /* pcm_rec_dma_stop */
400 400
401void pcm_rec_dma_init(void) 401void pcm_rec_dma_init(void)