diff options
| author | Michael Sevakis <jethead71@rockbox.org> | 2012-02-23 08:14:46 -0500 |
|---|---|---|
| committer | Michael Sevakis <jethead71@rockbox.org> | 2012-03-03 07:23:38 +0100 |
| commit | 286a4c5caa1945c8d1cb365a3d90fb09d5700cb2 (patch) | |
| tree | 4835f46d16ec78d035ec9f49333079fe618384c1 /firmware/export | |
| parent | 3f82f3aca14eb954e55f761721ffdd2684f0e812 (diff) | |
| download | rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.zip rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.tar.gz rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.tar.bz2 rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.tar.xz | |
Revise the PCM callback system after adding multichannel audio.
Additional status callback is added to pcm_play/rec_data instead of
using a special function to set it. Status includes DMA error
reporting to the status callback. Playback and recording callback
become more alike except playback uses "const void **addr" (because
the data should not be altered) and recording uses "void **addr".
"const" is put in place throughout where appropriate.
Most changes are fairly trivial. One that should be checked in
particular because it isn't so much is telechips, if anyone cares to
bother. PP5002 is not so trivial either but that tested as working.
Change-Id: I4928d69b3b3be7fb93e259f81635232df9bd1df2
Reviewed-on: http://gerrit.rockbox.org/166
Reviewed-by: Michael Sevakis <jethead71@rockbox.org>
Tested-by: Michael Sevakis <jethead71@rockbox.org>
Diffstat (limited to 'firmware/export')
| -rw-r--r-- | firmware/export/pcm-internal.h | 51 | ||||
| -rw-r--r-- | firmware/export/pcm.h | 31 | ||||
| -rw-r--r-- | firmware/export/pcm_mixer.h | 4 | ||||
| -rw-r--r-- | firmware/export/pp5002.h | 2 |
4 files changed, 59 insertions, 29 deletions
diff --git a/firmware/export/pcm-internal.h b/firmware/export/pcm-internal.h index 89d895f..abe3fe0 100644 --- a/firmware/export/pcm-internal.h +++ b/firmware/export/pcm-internal.h @@ -41,24 +41,28 @@ void pcm_do_peak_calculation(struct pcm_peaks *peaks, bool active, /** The following are for internal use between pcm.c and target- specific portion **/ +static FORCE_INLINE enum pcm_dma_status pcm_call_status_cb( + pcm_status_callback_type callback, enum pcm_dma_status status) +{ + if (!callback) + return status; -/* Called by the bottom layer ISR when more data is needed. Returns non- - * zero size if more data is to be played. Setting start to NULL - * forces stop. */ -void pcm_play_get_more_callback(void **start, size_t *size); + return callback(status); +} -/* Called by the bottom layer ISR after next transfer has begun in order - to fill more data for next "get more" callback to implement double-buffered - callbacks - except for a couple ASM handlers, help drivers to implement - this functionality with minimal overhead */ -static FORCE_INLINE void pcm_play_dma_started_callback(void) +static FORCE_INLINE enum pcm_dma_status +pcm_play_dma_status_callback(enum pcm_dma_status status) { - extern void (* pcm_play_dma_started)(void); - void (* callback)(void) = pcm_play_dma_started; - if (callback) - callback(); + extern enum pcm_dma_status + (* volatile pcm_play_status_callback)(enum pcm_dma_status); + return pcm_call_status_cb(pcm_play_status_callback, status); } +/* Called by the bottom layer ISR when more data is needed. Returns true + * if a new buffer is available, false otherwise. */ +bool pcm_play_dma_complete_callback(enum pcm_dma_status status, + const void **addr, size_t *size); + extern unsigned long pcm_curr_sampr; extern unsigned long pcm_sampr; extern int pcm_fsel; @@ -90,10 +94,29 @@ extern volatile bool pcm_recording; void pcm_rec_dma_init(void); void pcm_rec_dma_close(void); void pcm_rec_dma_start(void *addr, size_t size); -void pcm_rec_dma_record_more(void *start, size_t size); void pcm_rec_dma_stop(void); const void * pcm_rec_dma_get_peak_buffer(void); +static FORCE_INLINE enum pcm_dma_status +pcm_rec_dma_status_callback(enum pcm_dma_status status) +{ + extern enum pcm_dma_status + (* volatile pcm_rec_status_callback)(enum pcm_dma_status); + return pcm_call_status_cb(pcm_rec_status_callback, status); +} + + +/* Called by the bottom layer ISR when more data is needed. Returns true + * if a new buffer is available, false otherwise. */ +bool pcm_rec_dma_complete_callback(enum pcm_dma_status status, + void **addr, size_t *size); + +#ifdef HAVE_PCM_REC_DMA_ADDRESS +#define pcm_rec_dma_addr(addr) pcm_dma_addr(addr) +#else +#define pcm_rec_dma_addr(addr) addr +#endif + #endif /* HAVE_RECORDING */ #endif /* PCM_INTERNAL_H */ diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index 4a7a5b3..df82c60 100644 --- a/firmware/export/pcm.h +++ b/firmware/export/pcm.h @@ -24,17 +24,23 @@ #include <string.h> /* size_t */ #include "config.h" -#define DMA_REC_ERROR_DMA (-1) +enum pcm_dma_status +{ #ifdef HAVE_SPDIF_REC -#define DMA_REC_ERROR_SPDIF (-2) + PCM_DMAST_ERR_SPDIF = -2, #endif + PCM_DMAST_ERR_DMA = -1, + PCM_DMAST_OK = 0, + PCM_DMAST_STARTED = 1, +}; /** RAW PCM routines used with playback and recording **/ -/* Typedef for registered callbacks */ -typedef void (*pcm_play_callback_type)(unsigned char **start, - size_t *size); -typedef void (*pcm_rec_callback_type)(int status, void **start, size_t *size); +/* Typedef for registered data callback */ +typedef void (*pcm_play_callback_type)(const void **start, size_t *size); + +/* Typedef for registered status callback */ +typedef enum pcm_dma_status (*pcm_status_callback_type)(enum pcm_dma_status status); /* set the pcm frequency - use values in hw_sampr_list * when CONFIG_SAMPR_TYPES is #defined, or-in SAMPR_TYPE_* fields with @@ -62,7 +68,8 @@ bool pcm_is_initialized(void); /* This is for playing "raw" PCM data */ void pcm_play_data(pcm_play_callback_type get_more, - unsigned char* start, size_t size); + pcm_status_callback_type status_cb, + const void *start, size_t size); void pcm_calculate_peaks(int *left, int *right); const void* pcm_get_peak_buffer(int* count); @@ -73,12 +80,13 @@ void pcm_play_pause(bool play); bool pcm_is_paused(void); bool pcm_is_playing(void); -void pcm_play_set_dma_started_callback(void (* callback)(void)); - #ifdef HAVE_RECORDING /** RAW PCM recording routines **/ +/* Typedef for registered data callback */ +typedef void (*pcm_rec_callback_type)(void **start, size_t *size); + /* Reenterable locks for locking and unlocking the recording interrupt */ void pcm_rec_lock(void); void pcm_rec_unlock(void); @@ -90,6 +98,7 @@ void pcm_close_recording(void); /* Start recording "raw" PCM data */ void pcm_record_data(pcm_rec_callback_type more_ready, + pcm_status_callback_type status_cb, void *start, size_t size); /* Stop tranferring data into supplied buffer */ @@ -98,10 +107,6 @@ void pcm_stop_recording(void); /* Is pcm currently recording? */ bool pcm_is_recording(void); -/* Called by bottom layer ISR when transfer is complete. Returns non-zero - * size if successful. Setting start to NULL forces stop. */ -void pcm_rec_more_ready_callback(int status, void **start, size_t *size); - void pcm_calculate_rec_peaks(int *left, int *right); #endif /* HAVE_RECORDING */ diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h index ea26060..6e1632d 100644 --- a/firmware/export/pcm_mixer.h +++ b/firmware/export/pcm_mixer.h @@ -86,7 +86,7 @@ enum channel_status /* Start playback on a channel */ void mixer_channel_play_data(enum pcm_mixer_channel channel, pcm_play_callback_type get_more, - unsigned char *start, size_t size); + const void *start, size_t size); /* Pause or resume a channel (when started) */ void mixer_channel_play_pause(enum pcm_mixer_channel channel, bool play); @@ -105,7 +105,7 @@ enum channel_status mixer_channel_status(enum pcm_mixer_channel channel); size_t mixer_channel_get_bytes_waiting(enum pcm_mixer_channel channel); /* Return pointer to channel's playing audio data and the size remaining */ -void * mixer_channel_get_buffer(enum pcm_mixer_channel channel, int *count); +const void * mixer_channel_get_buffer(enum pcm_mixer_channel channel, int *count); /* Calculate peak values for channel */ void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel, diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h index 95cc8d5..5966f10 100644 --- a/firmware/export/pp5002.h +++ b/firmware/export/pp5002.h @@ -43,7 +43,9 @@ #define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) #define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c)) #define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540)) +#define IISFIFO_WRH (*(volatile unsigned short *)(0xc0002540)) #define IISFIFO_RD (*(volatile unsigned long *)(0xc0002580)) +#define IISFIFO_RDH (*(volatile unsigned short *)(0xc0002540)) /** * IISCONFIG bits: |