void pcm_play_dma_start(const void *addr, size_t size) { /* Stop any DMA in progress */ pcm_play_dma_stop(); /* kick in DMA transfer */ hdma_i2s_transfer(addr, size); }
void DSPHINT(void) { register pcm_more_callback_type get_more; /* No stack for this */ unsigned int i; IO_INTC_FIQ0 = 1 << 11; switch (dsp_message.msg) { case MSG_DEBUGF: /* DSP stores one character per word. */ for (i = 0; i < sizeof(buffer); i++) { buffer[i] = dsp_message.payload.debugf.buffer[i]; } DEBUGF("DSP: %s", buffer); break; case MSG_REFILL: /* Buffer empty. Try to get more. */ get_more = pcm_callback_for_more; size = 0; if (get_more == NULL || (get_more(&start, &size), size == 0)) { /* Callback missing or no more DMA to do */ pcm_play_dma_stop(); pcm_play_dma_stopped_callback(); } { unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START; /* Flush any pending cache writes */ clean_dcache_range(start, size); /* set the new DMA values */ DSP_(_sdem_addrl) = sdem_addr & 0xffff; DSP_(_sdem_addrh) = sdem_addr >> 16; DSP_(_sdem_dsp_size) = size; DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx", (unsigned long)start, (unsigned long)sdem_addr); } break; default: DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg); break; } /* Re-Activate the channel */ dsp_wake(); DEBUGF("DSP: %s", buffer); }
/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ void pcm_play_dma_start(const void *addr, size_t size) { /* Stop any DMA in progress */ pcm_play_dma_stop(); /* Set up DMA transfer */ SAR0 = (unsigned long)addr; /* Source address */ DAR0 = (unsigned long)&PDOR3; /* Destination address */ BCR0 = (unsigned long)size; /* Bytes to transfer */ DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; dma_play_lock.state = (0 << 14); } /* pcm_play_dma_start */
void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len) { udata->stream = stream; /* Write what we have in the PCM buffer */ if (pcm_data_size > 0) goto start; /* Audio card wants more? Get some more then. */ while (len > 0) { if ((ssize_t)pcm_data_size <= 0) { pcm_data_size = 0; if (pcm_callback_for_more) pcm_callback_for_more(&pcm_data, &pcm_data_size); } if (pcm_data_size > 0) { start: udata->num_in = pcm_data_size / pcm_sample_bytes; udata->num_out = len / pcm_sample_bytes; write_to_soundcard(udata); udata->num_in *= pcm_sample_bytes; udata->num_out *= pcm_sample_bytes; pcm_data += udata->num_in; pcm_data_size -= udata->num_in; udata->stream += udata->num_out; len -= udata->num_out; } else { DEBUGF("sdl_audio_callback: No Data.\n"); pcm_play_dma_stop(); pcm_play_dma_stopped_callback(); break; } } }
static inline void pcm_play_dma_stop_int(void) { pcm_play_dma_stop(); }