summaryrefslogtreecommitdiff
path: root/firmware/export
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-02-23 08:14:46 -0500
committerMichael Sevakis <jethead71@rockbox.org>2012-03-03 07:23:38 +0100
commit286a4c5caa1945c8d1cb365a3d90fb09d5700cb2 (patch)
tree4835f46d16ec78d035ec9f49333079fe618384c1 /firmware/export
parent3f82f3aca14eb954e55f761721ffdd2684f0e812 (diff)
downloadrockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.tar.gz
rockbox-286a4c5caa1945c8d1cb365a3d90fb09d5700cb2.zip
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.h51
-rw-r--r--firmware/export/pcm.h31
-rw-r--r--firmware/export/pcm_mixer.h4
-rw-r--r--firmware/export/pp5002.h2
4 files changed, 59 insertions, 29 deletions
diff --git a/firmware/export/pcm-internal.h b/firmware/export/pcm-internal.h
index 89d895fe4b..abe3fe08dc 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,
41 41
42/** The following are for internal use between pcm.c and target- 42/** The following are for internal use between pcm.c and target-
43 specific portion **/ 43 specific portion **/
44static FORCE_INLINE enum pcm_dma_status pcm_call_status_cb(
45 pcm_status_callback_type callback, enum pcm_dma_status status)
46{
47 if (!callback)
48 return status;
44 49
45/* Called by the bottom layer ISR when more data is needed. Returns non- 50 return callback(status);
46 * zero size if more data is to be played. Setting start to NULL 51}
47 * forces stop. */
48void pcm_play_get_more_callback(void **start, size_t *size);
49 52
50/* Called by the bottom layer ISR after next transfer has begun in order 53static FORCE_INLINE enum pcm_dma_status
51 to fill more data for next "get more" callback to implement double-buffered 54pcm_play_dma_status_callback(enum pcm_dma_status status)
52 callbacks - except for a couple ASM handlers, help drivers to implement
53 this functionality with minimal overhead */
54static FORCE_INLINE void pcm_play_dma_started_callback(void)
55{ 55{
56 extern void (* pcm_play_dma_started)(void); 56 extern enum pcm_dma_status
57 void (* callback)(void) = pcm_play_dma_started; 57 (* volatile pcm_play_status_callback)(enum pcm_dma_status);
58 if (callback) 58 return pcm_call_status_cb(pcm_play_status_callback, status);
59 callback();
60} 59}
61 60
61/* Called by the bottom layer ISR when more data is needed. Returns true
62 * if a new buffer is available, false otherwise. */
63bool pcm_play_dma_complete_callback(enum pcm_dma_status status,
64 const void **addr, size_t *size);
65
62extern unsigned long pcm_curr_sampr; 66extern unsigned long pcm_curr_sampr;
63extern unsigned long pcm_sampr; 67extern unsigned long pcm_sampr;
64extern int pcm_fsel; 68extern int pcm_fsel;
@@ -90,10 +94,29 @@ extern volatile bool pcm_recording;
90void pcm_rec_dma_init(void); 94void pcm_rec_dma_init(void);
91void pcm_rec_dma_close(void); 95void pcm_rec_dma_close(void);
92void pcm_rec_dma_start(void *addr, size_t size); 96void pcm_rec_dma_start(void *addr, size_t size);
93void pcm_rec_dma_record_more(void *start, size_t size);
94void pcm_rec_dma_stop(void); 97void pcm_rec_dma_stop(void);
95const void * pcm_rec_dma_get_peak_buffer(void); 98const void * pcm_rec_dma_get_peak_buffer(void);
96 99
100static FORCE_INLINE enum pcm_dma_status
101pcm_rec_dma_status_callback(enum pcm_dma_status status)
102{
103 extern enum pcm_dma_status
104 (* volatile pcm_rec_status_callback)(enum pcm_dma_status);
105 return pcm_call_status_cb(pcm_rec_status_callback, status);
106}
107
108
109/* Called by the bottom layer ISR when more data is needed. Returns true
110 * if a new buffer is available, false otherwise. */
111bool pcm_rec_dma_complete_callback(enum pcm_dma_status status,
112 void **addr, size_t *size);
113
114#ifdef HAVE_PCM_REC_DMA_ADDRESS
115#define pcm_rec_dma_addr(addr) pcm_dma_addr(addr)
116#else
117#define pcm_rec_dma_addr(addr) addr
118#endif
119
97#endif /* HAVE_RECORDING */ 120#endif /* HAVE_RECORDING */
98 121
99#endif /* PCM_INTERNAL_H */ 122#endif /* PCM_INTERNAL_H */
diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h
index 4a7a5b3193..df82c6092d 100644
--- a/firmware/export/pcm.h
+++ b/firmware/export/pcm.h
@@ -24,17 +24,23 @@
24#include <string.h> /* size_t */ 24#include <string.h> /* size_t */
25#include "config.h" 25#include "config.h"
26 26
27#define DMA_REC_ERROR_DMA (-1) 27enum pcm_dma_status
28{
28#ifdef HAVE_SPDIF_REC 29#ifdef HAVE_SPDIF_REC
29#define DMA_REC_ERROR_SPDIF (-2) 30 PCM_DMAST_ERR_SPDIF = -2,
30#endif 31#endif
32 PCM_DMAST_ERR_DMA = -1,
33 PCM_DMAST_OK = 0,
34 PCM_DMAST_STARTED = 1,
35};
31 36
32/** RAW PCM routines used with playback and recording **/ 37/** RAW PCM routines used with playback and recording **/
33 38
34/* Typedef for registered callbacks */ 39/* Typedef for registered data callback */
35typedef void (*pcm_play_callback_type)(unsigned char **start, 40typedef void (*pcm_play_callback_type)(const void **start, size_t *size);
36 size_t *size); 41
37typedef void (*pcm_rec_callback_type)(int status, void **start, size_t *size); 42/* Typedef for registered status callback */
43typedef enum pcm_dma_status (*pcm_status_callback_type)(enum pcm_dma_status status);
38 44
39/* set the pcm frequency - use values in hw_sampr_list 45/* set the pcm frequency - use values in hw_sampr_list
40 * when CONFIG_SAMPR_TYPES is #defined, or-in SAMPR_TYPE_* fields with 46 * when CONFIG_SAMPR_TYPES is #defined, or-in SAMPR_TYPE_* fields with
@@ -62,7 +68,8 @@ bool pcm_is_initialized(void);
62 68
63/* This is for playing "raw" PCM data */ 69/* This is for playing "raw" PCM data */
64void pcm_play_data(pcm_play_callback_type get_more, 70void pcm_play_data(pcm_play_callback_type get_more,
65 unsigned char* start, size_t size); 71 pcm_status_callback_type status_cb,
72 const void *start, size_t size);
66 73
67void pcm_calculate_peaks(int *left, int *right); 74void pcm_calculate_peaks(int *left, int *right);
68const void* pcm_get_peak_buffer(int* count); 75const void* pcm_get_peak_buffer(int* count);
@@ -73,12 +80,13 @@ void pcm_play_pause(bool play);
73bool pcm_is_paused(void); 80bool pcm_is_paused(void);
74bool pcm_is_playing(void); 81bool pcm_is_playing(void);
75 82
76void pcm_play_set_dma_started_callback(void (* callback)(void));
77
78#ifdef HAVE_RECORDING 83#ifdef HAVE_RECORDING
79 84
80/** RAW PCM recording routines **/ 85/** RAW PCM recording routines **/
81 86
87/* Typedef for registered data callback */
88typedef void (*pcm_rec_callback_type)(void **start, size_t *size);
89
82/* Reenterable locks for locking and unlocking the recording interrupt */ 90/* Reenterable locks for locking and unlocking the recording interrupt */
83void pcm_rec_lock(void); 91void pcm_rec_lock(void);
84void pcm_rec_unlock(void); 92void pcm_rec_unlock(void);
@@ -90,6 +98,7 @@ void pcm_close_recording(void);
90 98
91/* Start recording "raw" PCM data */ 99/* Start recording "raw" PCM data */
92void pcm_record_data(pcm_rec_callback_type more_ready, 100void pcm_record_data(pcm_rec_callback_type more_ready,
101 pcm_status_callback_type status_cb,
93 void *start, size_t size); 102 void *start, size_t size);
94 103
95/* Stop tranferring data into supplied buffer */ 104/* Stop tranferring data into supplied buffer */
@@ -98,10 +107,6 @@ void pcm_stop_recording(void);
98/* Is pcm currently recording? */ 107/* Is pcm currently recording? */
99bool pcm_is_recording(void); 108bool pcm_is_recording(void);
100 109
101/* Called by bottom layer ISR when transfer is complete. Returns non-zero
102 * size if successful. Setting start to NULL forces stop. */
103void pcm_rec_more_ready_callback(int status, void **start, size_t *size);
104
105void pcm_calculate_rec_peaks(int *left, int *right); 110void pcm_calculate_rec_peaks(int *left, int *right);
106 111
107#endif /* HAVE_RECORDING */ 112#endif /* HAVE_RECORDING */
diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h
index ea26060452..6e1632d5ae 100644
--- a/firmware/export/pcm_mixer.h
+++ b/firmware/export/pcm_mixer.h
@@ -86,7 +86,7 @@ enum channel_status
86/* Start playback on a channel */ 86/* Start playback on a channel */
87void mixer_channel_play_data(enum pcm_mixer_channel channel, 87void mixer_channel_play_data(enum pcm_mixer_channel channel,
88 pcm_play_callback_type get_more, 88 pcm_play_callback_type get_more,
89 unsigned char *start, size_t size); 89 const void *start, size_t size);
90 90
91/* Pause or resume a channel (when started) */ 91/* Pause or resume a channel (when started) */
92void mixer_channel_play_pause(enum pcm_mixer_channel channel, bool play); 92void 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);
105size_t mixer_channel_get_bytes_waiting(enum pcm_mixer_channel channel); 105size_t mixer_channel_get_bytes_waiting(enum pcm_mixer_channel channel);
106 106
107/* Return pointer to channel's playing audio data and the size remaining */ 107/* Return pointer to channel's playing audio data and the size remaining */
108void * mixer_channel_get_buffer(enum pcm_mixer_channel channel, int *count); 108const void * mixer_channel_get_buffer(enum pcm_mixer_channel channel, int *count);
109 109
110/* Calculate peak values for channel */ 110/* Calculate peak values for channel */
111void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel, 111void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel,
diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h
index 95cc8d5058..5966f10d08 100644
--- a/firmware/export/pp5002.h
+++ b/firmware/export/pp5002.h
@@ -43,7 +43,9 @@
43#define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) 43#define IISCONFIG (*(volatile unsigned long *)(0xc0002500))
44#define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c)) 44#define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c))
45#define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540)) 45#define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540))
46#define IISFIFO_WRH (*(volatile unsigned short *)(0xc0002540))
46#define IISFIFO_RD (*(volatile unsigned long *)(0xc0002580)) 47#define IISFIFO_RD (*(volatile unsigned long *)(0xc0002580))
48#define IISFIFO_RDH (*(volatile unsigned short *)(0xc0002540))
47 49
48/** 50/**
49 * IISCONFIG bits: 51 * IISCONFIG bits: