1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 and 2009 by Karl Kurbjun
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
28 #include "dsp-target.h"
32 /* These are global to save some latency when pcm_play_dma_get_peak_buffer is
35 static unsigned char *start
;
38 void pcm_postinit(void)
43 /* Return the current location in the SDRAM to SARAM transfer along with the
44 * number of bytes read in the current buffer (count). There is latency with
45 * this method equivalent to ~ the size of the SARAM buffer since there is
46 * another buffer between your ears and this calculation, but this works for
47 * key clicks and an approximate peak meter.
49 const void * pcm_play_dma_get_peak_buffer(int *count
)
51 int cnt
= DSP_(_sdem_level
);
53 unsigned long addr
= (unsigned long) start
+cnt
;
55 *count
= (cnt
& 0xFFFFF) >> 1;
56 return (void *)((addr
+ 2) & ~3);
59 void pcm_play_dma_init(void)
61 IO_INTC_IRQ0
= 1 << 11;
62 IO_INTC_EINT0
|= 1 << 11;
64 IO_DSPC_HPIB_CONTROL
= 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
71 void pcm_dma_apply_settings(void)
73 audiohw_set_frequency(pcm_fsel
);
76 /* Note that size is actually limited to the size of a short right now due to
77 * the implementation on the DSP side (and the way that we access it)
79 void pcm_play_dma_start(const void *addr
, size_t size
)
81 unsigned long sdem_addr
=(unsigned long)addr
- CONFIG_SDRAM_START
;
82 /* Initialize codec. */
83 DSP_(_sdem_addrl
) = sdem_addr
& 0xffff;
84 DSP_(_sdem_addrh
) = sdem_addr
>> 16;
85 DSP_(_sdem_dsp_size
) = size
;
86 DSP_(_dma0_stopped
)=0;
91 void pcm_play_dma_stop(void)
93 DSP_(_dma0_stopped
)=1;
96 void pcm_play_lock(void)
101 void pcm_play_unlock(void)
106 void pcm_play_dma_pause(bool pause
)
110 DSP_(_dma0_stopped
)=2;
114 DSP_(_dma0_stopped
)=0;
119 size_t pcm_get_bytes_waiting(void)
121 return DSP_(_sdem_dsp_size
)-DSP_(_sdem_level
);
126 register pcm_more_callback_type get_more
; /* No stack for this */
131 IO_INTC_IRQ0
= 1 << 11;
133 switch (dsp_message
.msg
)
136 /* DSP stores one character per word. */
137 for (i
= 0; i
< sizeof(buffer
); i
++)
139 buffer
[i
] = dsp_message
.payload
.debugf
.buffer
[i
];
142 DEBUGF("DSP: %s", buffer
);
146 /* Buffer empty. Try to get more. */
147 get_more
= pcm_callback_for_more
;
150 if (get_more
== NULL
|| (get_more(&start
, &size
), size
== 0))
152 /* Callback missing or no more DMA to do */
154 pcm_play_dma_stopped_callback();
158 unsigned long sdem_addr
=(unsigned long)start
- CONFIG_SDRAM_START
;
159 /* Flush any pending cache writes */
160 clean_dcache_range(start
, size
);
162 /* set the new DMA values */
163 DSP_(_sdem_addrl
) = sdem_addr
& 0xffff;
164 DSP_(_sdem_addrh
) = sdem_addr
>> 16;
165 DSP_(_sdem_dsp_size
) = size
;
167 DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
168 (unsigned long)start
, (unsigned long)sdem_addr
);
173 DEBUGF("DSP: unknown msg 0x%04x", dsp_message
.msg
);
177 /* Re-Activate the channel */
180 DEBUGF("DSP: %s", buffer
);