forked from len0rd/rockbox
Make PCM->driver interface about as simple as it will get. Registered callback, zero data, alignment and stops are handled entirely inside pcm.c; driver merely calls fixed pcm.c callback. Remove pcm_record_more and do it just like playback; the original reason behind it isn't very practical in general. Everything checks out on supported targets. There wer some compat changes I can't check out on many unsupoorted but if there's a problem it will be a minor oops. Plugins become incompatible due to recording tweak-- full update. Sorted API.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26253 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
6688988ec4
commit
d56999890f
19 changed files with 277 additions and 460 deletions
|
|
@ -177,6 +177,9 @@ static const struct plugin_api rockbox_api = {
|
||||||
&button_queue,
|
&button_queue,
|
||||||
#endif
|
#endif
|
||||||
bidi_l2v,
|
bidi_l2v,
|
||||||
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
is_diacritic,
|
||||||
|
#endif
|
||||||
font_get_bits,
|
font_get_bits,
|
||||||
font_load,
|
font_load,
|
||||||
font_get,
|
font_get,
|
||||||
|
|
@ -461,6 +464,9 @@ static const struct plugin_api rockbox_api = {
|
||||||
sound_max,
|
sound_max,
|
||||||
sound_unit,
|
sound_unit,
|
||||||
sound_val2phys,
|
sound_val2phys,
|
||||||
|
#ifdef AUDIOHW_HAVE_EQ
|
||||||
|
sound_enum_hw_eq_band_setting,
|
||||||
|
#endif
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
mp3_play_data,
|
mp3_play_data,
|
||||||
mp3_play_pause,
|
mp3_play_pause,
|
||||||
|
|
@ -491,7 +497,6 @@ static const struct plugin_api rockbox_api = {
|
||||||
pcm_init_recording,
|
pcm_init_recording,
|
||||||
pcm_close_recording,
|
pcm_close_recording,
|
||||||
pcm_record_data,
|
pcm_record_data,
|
||||||
pcm_record_more,
|
|
||||||
pcm_stop_recording,
|
pcm_stop_recording,
|
||||||
pcm_calculate_rec_peaks,
|
pcm_calculate_rec_peaks,
|
||||||
audio_set_recording_gain,
|
audio_set_recording_gain,
|
||||||
|
|
@ -630,7 +635,12 @@ static const struct plugin_api rockbox_api = {
|
||||||
codec_thread_do_callback,
|
codec_thread_do_callback,
|
||||||
codec_load_file,
|
codec_load_file,
|
||||||
get_codec_filename,
|
get_codec_filename,
|
||||||
|
find_array_ptr,
|
||||||
|
remove_array_ptr,
|
||||||
|
#if defined(HAVE_RECORDING) && (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
||||||
|
round_value_to_list32,
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* CONFIG_CODEC == SWCODEC */
|
||||||
get_metadata,
|
get_metadata,
|
||||||
mp3info,
|
mp3info,
|
||||||
count_mp3_frames,
|
count_mp3_frames,
|
||||||
|
|
@ -711,24 +721,6 @@ static const struct plugin_api rockbox_api = {
|
||||||
appsversion,
|
appsversion,
|
||||||
/* new stuff at the end, sort into place next time
|
/* new stuff at the end, sort into place next time
|
||||||
the API gets incompatible */
|
the API gets incompatible */
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
is_diacritic,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && \
|
|
||||||
(defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
|
||||||
round_value_to_list32,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef AUDIOHW_HAVE_EQ
|
|
||||||
sound_enum_hw_eq_band_setting,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
find_array_ptr,
|
|
||||||
remove_array_ptr,
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int plugin_load(const char* plugin, const void* parameter)
|
int plugin_load(const char* plugin, const void* parameter)
|
||||||
|
|
|
||||||
|
|
@ -144,12 +144,12 @@ void* plugin_get_buffer(size_t *buffer_size);
|
||||||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||||
|
|
||||||
/* increase this every time the api struct changes */
|
/* increase this every time the api struct changes */
|
||||||
#define PLUGIN_API_VERSION 186
|
#define PLUGIN_API_VERSION 187
|
||||||
|
|
||||||
/* update this to latest version if a change to the api struct breaks
|
/* update this to latest version if a change to the api struct breaks
|
||||||
backwards compatibility (and please take the opportunity to sort in any
|
backwards compatibility (and please take the opportunity to sort in any
|
||||||
new function which are "waiting" at the end of the function table) */
|
new function which are "waiting" at the end of the function table) */
|
||||||
#define PLUGIN_MIN_API_VERSION 182
|
#define PLUGIN_MIN_API_VERSION 187
|
||||||
|
|
||||||
/* plugin return codes */
|
/* plugin return codes */
|
||||||
enum plugin_status {
|
enum plugin_status {
|
||||||
|
|
@ -259,6 +259,9 @@ struct plugin_api {
|
||||||
struct event_queue *button_queue;
|
struct event_queue *button_queue;
|
||||||
#endif
|
#endif
|
||||||
unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation );
|
unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation );
|
||||||
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl);
|
||||||
|
#endif
|
||||||
const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
|
const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
|
||||||
int (*font_load)(struct font*, const char *path);
|
int (*font_load)(struct font*, const char *path);
|
||||||
struct font* (*font_get)(int font);
|
struct font* (*font_get)(int font);
|
||||||
|
|
@ -577,6 +580,10 @@ struct plugin_api {
|
||||||
int (*sound_max)(int setting);
|
int (*sound_max)(int setting);
|
||||||
const char * (*sound_unit)(int setting);
|
const char * (*sound_unit)(int setting);
|
||||||
int (*sound_val2phys)(int setting, int value);
|
int (*sound_val2phys)(int setting, int value);
|
||||||
|
#ifdef AUDIOHW_HAVE_EQ
|
||||||
|
int (*sound_enum_hw_eq_band_setting)(unsigned int band,
|
||||||
|
unsigned int band_setting);
|
||||||
|
#endif /* AUDIOHW_HAVE_EQ */
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
void (*mp3_play_data)(const unsigned char* start, int size,
|
void (*mp3_play_data)(const unsigned char* start, int size,
|
||||||
void (*get_more)(unsigned char** start, size_t* size));
|
void (*get_more)(unsigned char** start, size_t* size));
|
||||||
|
|
@ -591,7 +598,7 @@ struct plugin_api {
|
||||||
const unsigned long *audio_master_sampr_list;
|
const unsigned long *audio_master_sampr_list;
|
||||||
const unsigned long *hw_freq_sampr;
|
const unsigned long *hw_freq_sampr;
|
||||||
void (*pcm_apply_settings)(void);
|
void (*pcm_apply_settings)(void);
|
||||||
void (*pcm_play_data)(pcm_more_callback_type get_more,
|
void (*pcm_play_data)(pcm_play_callback_type get_more,
|
||||||
unsigned char* start, size_t size);
|
unsigned char* start, size_t size);
|
||||||
void (*pcm_play_stop)(void);
|
void (*pcm_play_stop)(void);
|
||||||
void (*pcm_set_frequency)(unsigned int frequency);
|
void (*pcm_set_frequency)(unsigned int frequency);
|
||||||
|
|
@ -610,9 +617,8 @@ struct plugin_api {
|
||||||
const unsigned long *rec_freq_sampr;
|
const unsigned long *rec_freq_sampr;
|
||||||
void (*pcm_init_recording)(void);
|
void (*pcm_init_recording)(void);
|
||||||
void (*pcm_close_recording)(void);
|
void (*pcm_close_recording)(void);
|
||||||
void (*pcm_record_data)(pcm_more_callback_type2 more_ready,
|
void (*pcm_record_data)(pcm_rec_callback_type more_ready,
|
||||||
void *start, size_t size);
|
void *start, size_t size);
|
||||||
void (*pcm_record_more)(void *start, size_t size);
|
|
||||||
void (*pcm_stop_recording)(void);
|
void (*pcm_stop_recording)(void);
|
||||||
void (*pcm_calculate_rec_peaks)(int *left, int *right);
|
void (*pcm_calculate_rec_peaks)(int *left, int *right);
|
||||||
void (*audio_set_recording_gain)(int left, int right, int type);
|
void (*audio_set_recording_gain)(int left, int right, int type);
|
||||||
|
|
@ -774,7 +780,15 @@ struct plugin_api {
|
||||||
unsigned int *audio_thread_id);
|
unsigned int *audio_thread_id);
|
||||||
int (*codec_load_file)(const char* codec, struct codec_api *api);
|
int (*codec_load_file)(const char* codec, struct codec_api *api);
|
||||||
const char *(*get_codec_filename)(int cod_spec);
|
const char *(*get_codec_filename)(int cod_spec);
|
||||||
|
void ** (*find_array_ptr)(void **arr, void *ptr);
|
||||||
|
int (*remove_array_ptr)(void **arr, void *ptr);
|
||||||
|
#if defined(HAVE_RECORDING) && (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
||||||
|
int (*round_value_to_list32)(unsigned long value,
|
||||||
|
const unsigned long list[],
|
||||||
|
int count,
|
||||||
|
bool signd);
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* CONFIG_CODEC == SWCODEC */
|
||||||
bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname);
|
bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname);
|
||||||
bool (*mp3info)(struct mp3entry *entry, const char *filename);
|
bool (*mp3info)(struct mp3entry *entry, const char *filename);
|
||||||
int (*count_mp3_frames)(int fd, int startpos, int filesize,
|
int (*count_mp3_frames)(int fd, int startpos, int filesize,
|
||||||
|
|
@ -874,28 +888,6 @@ struct plugin_api {
|
||||||
const char *appsversion;
|
const char *appsversion;
|
||||||
/* new stuff at the end, sort into place next time
|
/* new stuff at the end, sort into place next time
|
||||||
the API gets incompatible */
|
the API gets incompatible */
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && \
|
|
||||||
(defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN))
|
|
||||||
int (*round_value_to_list32)(unsigned long value,
|
|
||||||
const unsigned long list[],
|
|
||||||
int count,
|
|
||||||
bool signd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef AUDIOHW_HAVE_EQ
|
|
||||||
int (*sound_enum_hw_eq_band_setting)(unsigned int band,
|
|
||||||
unsigned int band_setting);
|
|
||||||
#endif /* AUDIOHW_HAVE_EQ */
|
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
void ** (*find_array_ptr)(void **arr, void *ptr);
|
|
||||||
int (*remove_array_ptr)(void **arr, void *ptr);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* plugin header */
|
/* plugin header */
|
||||||
|
|
|
||||||
|
|
@ -982,7 +982,7 @@ uint32_t ICODE_ATTR buffer_magnitude(int16_t *input)
|
||||||
|
|
||||||
/* Stop the recording when the buffer is full */
|
/* Stop the recording when the buffer is full */
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
int recording_callback(int status)
|
void recording_callback(int status, void **start, size_t *size)
|
||||||
{
|
{
|
||||||
int tail = audio_tail ^ 1;
|
int tail = audio_tail ^ 1;
|
||||||
|
|
||||||
|
|
@ -991,10 +991,9 @@ int recording_callback(int status)
|
||||||
audio_tail = tail;
|
audio_tail = tail;
|
||||||
|
|
||||||
/* Always record full buffer, even if not required */
|
/* Always record full buffer, even if not required */
|
||||||
rb->pcm_record_more(audio_data[tail],
|
*start = audio_data[tail];
|
||||||
BUFFER_SIZE * sizeof (int16_t));
|
*size = BUFFER_SIZE * sizeof (int16_t);
|
||||||
|
|
||||||
return 0;
|
|
||||||
(void)status;
|
(void)status;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ enum
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
|
|
||||||
/* Callback for when more data is ready - called in interrupt context */
|
/* Callback for when more data is ready - called in interrupt context */
|
||||||
static int pcm_rec_have_more(int status)
|
static void pcm_rec_have_more(int status, void **start, size_t *size)
|
||||||
{
|
{
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -265,9 +265,9 @@ static int pcm_rec_have_more(int status)
|
||||||
{
|
{
|
||||||
/* Flush recorded data to disk and stop recording */
|
/* Flush recorded data to disk and stop recording */
|
||||||
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
|
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
/* else try again next transmission */
|
/* else try again next transmission - frame is invalid */
|
||||||
}
|
}
|
||||||
else if (!dma_lock)
|
else if (!dma_lock)
|
||||||
{
|
{
|
||||||
|
|
@ -282,8 +282,8 @@ static int pcm_rec_have_more(int status)
|
||||||
dma_wr_pos = next_pos;
|
dma_wr_pos = next_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcm_record_more(GET_PCM_CHUNK(dma_wr_pos), PCM_CHUNK_SIZE);
|
*start = GET_PCM_CHUNK(dma_wr_pos);
|
||||||
return 0;
|
*size = PCM_CHUNK_SIZE;
|
||||||
} /* pcm_rec_have_more */
|
} /* pcm_rec_have_more */
|
||||||
|
|
||||||
static void reset_hardware(void)
|
static void reset_hardware(void)
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ enum voice_thread_messages
|
||||||
/* Structure to store clip data callback info */
|
/* Structure to store clip data callback info */
|
||||||
struct voice_info
|
struct voice_info
|
||||||
{
|
{
|
||||||
pcm_more_callback_type get_more; /* Callback to get more clips */
|
pcm_play_callback_type get_more; /* Callback to get more clips */
|
||||||
unsigned char *start; /* Start of clip */
|
unsigned char *start; /* Start of clip */
|
||||||
size_t size; /* Size of clip */
|
size_t size; /* Size of clip */
|
||||||
};
|
};
|
||||||
|
|
@ -117,7 +117,7 @@ static inline bool playback_is_playing(void)
|
||||||
|
|
||||||
/* Stop any current clip and start playing a new one */
|
/* Stop any current clip and start playing a new one */
|
||||||
void mp3_play_data(const unsigned char* start, int size,
|
void mp3_play_data(const unsigned char* start, int size,
|
||||||
pcm_more_callback_type get_more)
|
pcm_play_callback_type get_more)
|
||||||
{
|
{
|
||||||
/* Shared struct to get data to the thread - once it replies, it has
|
/* Shared struct to get data to the thread - once it replies, it has
|
||||||
* safely cached it in its own private data */
|
* safely cached it in its own private data */
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,9 @@
|
||||||
/** RAW PCM routines used with playback and recording **/
|
/** RAW PCM routines used with playback and recording **/
|
||||||
|
|
||||||
/* Typedef for registered callback */
|
/* Typedef for registered callback */
|
||||||
typedef void (*pcm_more_callback_type)(unsigned char **start,
|
typedef void (*pcm_play_callback_type)(unsigned char **start,
|
||||||
size_t *size);
|
size_t *size);
|
||||||
typedef int (*pcm_more_callback_type2)(int status);
|
typedef void (*pcm_rec_callback_type)(int status, void **start, size_t *size);
|
||||||
|
|
||||||
/* set the pcm frequency - use values in hw_sampr_list
|
/* set the pcm frequency - use values in hw_sampr_list
|
||||||
* use -1 for the default frequency
|
* use -1 for the default frequency
|
||||||
|
|
@ -71,7 +71,7 @@ void pcm_init(void);
|
||||||
void pcm_postinit(void);
|
void pcm_postinit(void);
|
||||||
|
|
||||||
/* This is for playing "raw" PCM data */
|
/* This is for playing "raw" PCM data */
|
||||||
void pcm_play_data(pcm_more_callback_type get_more,
|
void pcm_play_data(pcm_play_callback_type get_more,
|
||||||
unsigned char* start, size_t size);
|
unsigned char* start, size_t size);
|
||||||
|
|
||||||
void pcm_calculate_peaks(int *left, int *right);
|
void pcm_calculate_peaks(int *left, int *right);
|
||||||
|
|
@ -86,6 +86,11 @@ bool pcm_is_playing(void);
|
||||||
/** The following are for internal use between pcm.c and target-
|
/** The following are for internal use between pcm.c and target-
|
||||||
specific portion **/
|
specific portion **/
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
extern unsigned long pcm_curr_sampr;
|
extern unsigned long pcm_curr_sampr;
|
||||||
extern unsigned long pcm_sampr;
|
extern unsigned long pcm_sampr;
|
||||||
extern int pcm_fsel;
|
extern int pcm_fsel;
|
||||||
|
|
@ -94,8 +99,6 @@ extern int pcm_fsel;
|
||||||
void * pcm_dma_addr(void *addr);
|
void * pcm_dma_addr(void *addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* the registered callback function to ask for more mp3 data */
|
|
||||||
extern volatile pcm_more_callback_type pcm_callback_for_more;
|
|
||||||
extern volatile bool pcm_playing;
|
extern volatile bool pcm_playing;
|
||||||
extern volatile bool pcm_paused;
|
extern volatile bool pcm_paused;
|
||||||
|
|
||||||
|
|
@ -105,7 +108,6 @@ void pcm_play_dma_init(void);
|
||||||
void pcm_play_dma_start(const void *addr, size_t size);
|
void pcm_play_dma_start(const void *addr, size_t size);
|
||||||
void pcm_play_dma_stop(void);
|
void pcm_play_dma_stop(void);
|
||||||
void pcm_play_dma_pause(bool pause);
|
void pcm_play_dma_pause(bool pause);
|
||||||
void pcm_play_dma_stopped_callback(void);
|
|
||||||
const void * pcm_play_dma_get_peak_buffer(int *count);
|
const void * pcm_play_dma_get_peak_buffer(int *count);
|
||||||
|
|
||||||
void pcm_dma_apply_settings(void);
|
void pcm_dma_apply_settings(void);
|
||||||
|
|
@ -124,7 +126,7 @@ void pcm_init_recording(void);
|
||||||
void pcm_close_recording(void);
|
void pcm_close_recording(void);
|
||||||
|
|
||||||
/* Start recording "raw" PCM data */
|
/* Start recording "raw" PCM data */
|
||||||
void pcm_record_data(pcm_more_callback_type2 more_ready,
|
void pcm_record_data(pcm_rec_callback_type more_ready,
|
||||||
void *start, size_t size);
|
void *start, size_t size);
|
||||||
|
|
||||||
/* Stop tranferring data into supplied buffer */
|
/* Stop tranferring data into supplied buffer */
|
||||||
|
|
@ -133,15 +135,14 @@ void pcm_stop_recording(void);
|
||||||
/* Is pcm currently recording? */
|
/* Is pcm currently recording? */
|
||||||
bool pcm_is_recording(void);
|
bool pcm_is_recording(void);
|
||||||
|
|
||||||
/* Continue transferring data in - call during interrupt handler */
|
/* Called by bottom layer ISR when transfer is complete. Returns non-zero
|
||||||
void pcm_record_more(void *start, size_t size);
|
* 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);
|
void pcm_calculate_rec_peaks(int *left, int *right);
|
||||||
|
|
||||||
/** The following are for internal use between pcm.c and target-
|
/** The following are for internal use between pcm.c and target-
|
||||||
specific portion **/
|
specific portion **/
|
||||||
/* the registered callback function for when more data is available */
|
|
||||||
extern volatile pcm_more_callback_type2 pcm_callback_more_ready;
|
|
||||||
/* DMA transfer in is currently active */
|
/* DMA transfer in is currently active */
|
||||||
extern volatile bool pcm_recording;
|
extern volatile bool pcm_recording;
|
||||||
|
|
||||||
|
|
@ -151,7 +152,6 @@ void pcm_rec_dma_close(void);
|
||||||
void pcm_rec_dma_start(void *addr, size_t size);
|
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_record_more(void *start, size_t size);
|
||||||
void pcm_rec_dma_stop(void);
|
void pcm_rec_dma_stop(void);
|
||||||
void pcm_rec_dma_stopped_callback(void);
|
|
||||||
const void * pcm_rec_dma_get_peak_buffer(void);
|
const void * pcm_rec_dma_get_peak_buffer(void);
|
||||||
|
|
||||||
#endif /* HAVE_RECORDING */
|
#endif /* HAVE_RECORDING */
|
||||||
|
|
|
||||||
148
firmware/pcm.c
148
firmware/pcm.c
|
|
@ -39,6 +39,7 @@
|
||||||
* pcm_play_lock
|
* pcm_play_lock
|
||||||
* pcm_play_unlock
|
* pcm_play_unlock
|
||||||
* Semi-private -
|
* Semi-private -
|
||||||
|
* pcm_play_get_more_callback
|
||||||
* pcm_play_dma_init
|
* pcm_play_dma_init
|
||||||
* pcm_play_dma_start
|
* pcm_play_dma_start
|
||||||
* pcm_play_dma_stop
|
* pcm_play_dma_stop
|
||||||
|
|
@ -48,28 +49,27 @@
|
||||||
* pcm_sampr (R)
|
* pcm_sampr (R)
|
||||||
* pcm_fsel (R)
|
* pcm_fsel (R)
|
||||||
* pcm_curr_sampr (R)
|
* pcm_curr_sampr (R)
|
||||||
* pcm_callback_for_more (R)
|
|
||||||
* pcm_playing (R)
|
* pcm_playing (R)
|
||||||
* pcm_paused (R)
|
* pcm_paused (R)
|
||||||
*
|
*
|
||||||
* ==Playback/Recording==
|
* ==Playback/Recording==
|
||||||
|
* Public -
|
||||||
|
* pcm_dma_addr
|
||||||
* Semi-private -
|
* Semi-private -
|
||||||
* pcm_dma_apply_settings
|
* pcm_dma_apply_settings
|
||||||
* pcm_dma_addr
|
|
||||||
*
|
*
|
||||||
* ==Recording==
|
* ==Recording==
|
||||||
* Public -
|
* Public -
|
||||||
* pcm_rec_lock
|
* pcm_rec_lock
|
||||||
* pcm_rec_unlock
|
* pcm_rec_unlock
|
||||||
* Semi-private -
|
* Semi-private -
|
||||||
|
* pcm_rec_more_ready_callback
|
||||||
* pcm_rec_dma_init
|
* pcm_rec_dma_init
|
||||||
* pcm_rec_dma_close
|
* pcm_rec_dma_close
|
||||||
* pcm_rec_dma_start
|
* pcm_rec_dma_start
|
||||||
* pcm_rec_dma_record_more
|
|
||||||
* pcm_rec_dma_stop
|
* pcm_rec_dma_stop
|
||||||
* pcm_rec_dma_get_peak_buffer
|
* pcm_rec_dma_get_peak_buffer
|
||||||
* Data Read/Written within TSP -
|
* Data Read/Written within TSP -
|
||||||
* pcm_callback_more_ready (R)
|
|
||||||
* pcm_recording (R)
|
* pcm_recording (R)
|
||||||
*
|
*
|
||||||
* States are set _after_ the target's pcm driver is called so that it may
|
* States are set _after_ the target's pcm driver is called so that it may
|
||||||
|
|
@ -78,7 +78,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* the registered callback function to ask for more mp3 data */
|
/* the registered callback function to ask for more mp3 data */
|
||||||
volatile pcm_more_callback_type pcm_callback_for_more
|
static volatile pcm_play_callback_type pcm_callback_for_more
|
||||||
SHAREDBSS_ATTR = NULL;
|
SHAREDBSS_ATTR = NULL;
|
||||||
/* PCM playback state */
|
/* PCM playback state */
|
||||||
volatile bool pcm_playing SHAREDBSS_ATTR = false;
|
volatile bool pcm_playing SHAREDBSS_ATTR = false;
|
||||||
|
|
@ -91,6 +91,14 @@ unsigned long pcm_sampr SHAREDBSS_ATTR = HW_SAMPR_DEFAULT;
|
||||||
/* samplerate frequency selection index */
|
/* samplerate frequency selection index */
|
||||||
int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT;
|
int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT;
|
||||||
|
|
||||||
|
/* Called internally by functions to reset the state */
|
||||||
|
static void pcm_play_stopped(void)
|
||||||
|
{
|
||||||
|
pcm_callback_for_more = NULL;
|
||||||
|
pcm_paused = false;
|
||||||
|
pcm_playing = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform peak calculation on a buffer of packed 16-bit samples.
|
* Perform peak calculation on a buffer of packed 16-bit samples.
|
||||||
*
|
*
|
||||||
|
|
@ -187,6 +195,16 @@ const void* pcm_get_peak_buffer(int * count)
|
||||||
return pcm_play_dma_get_peak_buffer(count);
|
return pcm_play_dma_get_peak_buffer(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pcm_is_playing(void)
|
||||||
|
{
|
||||||
|
return pcm_playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pcm_is_paused(void)
|
||||||
|
{
|
||||||
|
return pcm_paused;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Functions that do not require targeted implementation but only a targeted
|
* Functions that do not require targeted implementation but only a targeted
|
||||||
* interface
|
* interface
|
||||||
|
|
@ -198,7 +216,7 @@ void pcm_init(void)
|
||||||
{
|
{
|
||||||
logf("pcm_init");
|
logf("pcm_init");
|
||||||
|
|
||||||
pcm_play_dma_stopped_callback();
|
pcm_play_stopped();
|
||||||
|
|
||||||
pcm_set_frequency(HW_SAMPR_DEFAULT);
|
pcm_set_frequency(HW_SAMPR_DEFAULT);
|
||||||
|
|
||||||
|
|
@ -214,7 +232,7 @@ static void pcm_play_data_start(unsigned char *start, size_t size)
|
||||||
|
|
||||||
if (!(start && size))
|
if (!(start && size))
|
||||||
{
|
{
|
||||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
pcm_play_callback_type get_more = pcm_callback_for_more;
|
||||||
size = 0;
|
size = 0;
|
||||||
if (get_more)
|
if (get_more)
|
||||||
{
|
{
|
||||||
|
|
@ -239,10 +257,10 @@ static void pcm_play_data_start(unsigned char *start, size_t size)
|
||||||
/* Force a stop */
|
/* Force a stop */
|
||||||
logf(" pcm_play_dma_stop");
|
logf(" pcm_play_dma_stop");
|
||||||
pcm_play_dma_stop();
|
pcm_play_dma_stop();
|
||||||
pcm_play_dma_stopped_callback();
|
pcm_play_stopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_play_data(pcm_more_callback_type get_more,
|
void pcm_play_data(pcm_play_callback_type get_more,
|
||||||
unsigned char *start, size_t size)
|
unsigned char *start, size_t size)
|
||||||
{
|
{
|
||||||
logf("pcm_play_data");
|
logf("pcm_play_data");
|
||||||
|
|
@ -257,6 +275,29 @@ void pcm_play_data(pcm_more_callback_type get_more,
|
||||||
pcm_play_unlock();
|
pcm_play_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pcm_play_get_more_callback(void **start, size_t *size)
|
||||||
|
{
|
||||||
|
pcm_play_callback_type get_more = pcm_callback_for_more;
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
|
if (get_more && start)
|
||||||
|
{
|
||||||
|
/* Call registered callback */
|
||||||
|
get_more((unsigned char **)start, size);
|
||||||
|
|
||||||
|
*start = (void *)(((uintptr_t)*start + 3) & ~3);
|
||||||
|
*size &= ~3;
|
||||||
|
|
||||||
|
if (*start && *size)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error, callback missing or no more DMA to do */
|
||||||
|
pcm_play_dma_stop();
|
||||||
|
pcm_play_stopped();
|
||||||
|
}
|
||||||
|
|
||||||
void pcm_play_pause(bool play)
|
void pcm_play_pause(bool play)
|
||||||
{
|
{
|
||||||
logf("pcm_play_pause: %s", play ? "play" : "pause");
|
logf("pcm_play_pause: %s", play ? "play" : "pause");
|
||||||
|
|
@ -302,7 +343,7 @@ void pcm_play_stop(void)
|
||||||
{
|
{
|
||||||
logf(" pcm_play_dma_stop");
|
logf(" pcm_play_dma_stop");
|
||||||
pcm_play_dma_stop();
|
pcm_play_dma_stop();
|
||||||
pcm_play_dma_stopped_callback();
|
pcm_play_stopped();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -312,13 +353,6 @@ void pcm_play_stop(void)
|
||||||
pcm_play_unlock();
|
pcm_play_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_play_dma_stopped_callback(void)
|
|
||||||
{
|
|
||||||
pcm_callback_for_more = NULL;
|
|
||||||
pcm_paused = false;
|
|
||||||
pcm_playing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
/* set frequency next frequency used by the audio hardware -
|
/* set frequency next frequency used by the audio hardware -
|
||||||
|
|
@ -350,27 +384,24 @@ void pcm_apply_settings(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcm_is_playing(void)
|
|
||||||
{
|
|
||||||
return pcm_playing;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pcm_is_paused(void)
|
|
||||||
{
|
|
||||||
return pcm_paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
/** Low level pcm recording apis **/
|
/** Low level pcm recording apis **/
|
||||||
|
|
||||||
/* Next start for recording peaks */
|
/* Next start for recording peaks */
|
||||||
static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL;
|
static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL;
|
||||||
/* the registered callback function for when more data is available */
|
/* the registered callback function for when more data is available */
|
||||||
volatile pcm_more_callback_type2
|
static volatile pcm_rec_callback_type
|
||||||
pcm_callback_more_ready SHAREDBSS_ATTR = NULL;
|
pcm_callback_more_ready SHAREDBSS_ATTR = NULL;
|
||||||
/* DMA transfer in is currently active */
|
/* DMA transfer in is currently active */
|
||||||
volatile bool pcm_recording SHAREDBSS_ATTR = false;
|
volatile bool pcm_recording SHAREDBSS_ATTR = false;
|
||||||
|
|
||||||
|
/* Called internally by functions to reset the state */
|
||||||
|
static void pcm_recording_stopped(void)
|
||||||
|
{
|
||||||
|
pcm_recording = false;
|
||||||
|
pcm_callback_more_ready = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return recording peaks - From the end of the last peak up to
|
* Return recording peaks - From the end of the last peak up to
|
||||||
* current write position.
|
* current write position.
|
||||||
|
|
@ -410,10 +441,16 @@ void pcm_calculate_rec_peaks(int *left, int *right)
|
||||||
*right = peaks[1];
|
*right = peaks[1];
|
||||||
} /* pcm_calculate_rec_peaks */
|
} /* pcm_calculate_rec_peaks */
|
||||||
|
|
||||||
|
bool pcm_is_recording(void)
|
||||||
|
{
|
||||||
|
return pcm_recording;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Functions that do not require targeted implementation but only a targeted
|
* Functions that do not require targeted implementation but only a targeted
|
||||||
* interface
|
* interface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void pcm_init_recording(void)
|
void pcm_init_recording(void)
|
||||||
{
|
{
|
||||||
logf("pcm_init_recording");
|
logf("pcm_init_recording");
|
||||||
|
|
@ -424,7 +461,7 @@ void pcm_init_recording(void)
|
||||||
pcm_rec_lock();
|
pcm_rec_lock();
|
||||||
|
|
||||||
logf(" pcm_rec_dma_init");
|
logf(" pcm_rec_dma_init");
|
||||||
pcm_rec_dma_stopped_callback();
|
pcm_recording_stopped();
|
||||||
pcm_rec_dma_init();
|
pcm_rec_dma_init();
|
||||||
|
|
||||||
pcm_rec_unlock();
|
pcm_rec_unlock();
|
||||||
|
|
@ -440,7 +477,7 @@ void pcm_close_recording(void)
|
||||||
{
|
{
|
||||||
logf(" pcm_rec_dma_stop");
|
logf(" pcm_rec_dma_stop");
|
||||||
pcm_rec_dma_stop();
|
pcm_rec_dma_stop();
|
||||||
pcm_rec_dma_stopped_callback();
|
pcm_recording_stopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
logf(" pcm_rec_dma_close");
|
logf(" pcm_rec_dma_close");
|
||||||
|
|
@ -449,7 +486,7 @@ void pcm_close_recording(void)
|
||||||
pcm_rec_unlock();
|
pcm_rec_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_record_data(pcm_more_callback_type2 more_ready,
|
void pcm_record_data(pcm_rec_callback_type more_ready,
|
||||||
void *start, size_t size)
|
void *start, size_t size)
|
||||||
{
|
{
|
||||||
logf("pcm_record_data");
|
logf("pcm_record_data");
|
||||||
|
|
@ -493,43 +530,40 @@ void pcm_stop_recording(void)
|
||||||
{
|
{
|
||||||
logf(" pcm_rec_dma_stop");
|
logf(" pcm_rec_dma_stop");
|
||||||
pcm_rec_dma_stop();
|
pcm_rec_dma_stop();
|
||||||
pcm_rec_dma_stopped_callback();
|
pcm_recording_stopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
pcm_rec_unlock();
|
pcm_rec_unlock();
|
||||||
} /* pcm_stop_recording */
|
} /* pcm_stop_recording */
|
||||||
|
|
||||||
void pcm_record_more(void *start, size_t size)
|
void pcm_rec_more_ready_callback(int status, void **start, size_t *size)
|
||||||
{
|
{
|
||||||
start = (void *)(((uintptr_t)start + 3) & ~3);
|
pcm_rec_callback_type have_more = pcm_callback_more_ready;
|
||||||
size = size & ~3;
|
|
||||||
|
|
||||||
if (!size)
|
*size = 0;
|
||||||
|
|
||||||
|
if (have_more && start)
|
||||||
{
|
{
|
||||||
pcm_rec_dma_stop();
|
have_more(status, start, size);
|
||||||
pcm_rec_dma_stopped_callback();
|
*start = (void *)(((uintptr_t)*start + 3) & ~3);
|
||||||
|
*size &= ~3;
|
||||||
|
|
||||||
|
if (*start && *size)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PCM_REC_DMA_ADDRESS
|
||||||
|
/* Need a physical DMA address translation, if not already
|
||||||
|
* physical. */
|
||||||
|
pcm_rec_peak_addr = pcm_dma_addr(*start);
|
||||||
|
#else
|
||||||
|
pcm_rec_peak_addr = *start;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PCM_REC_DMA_ADDRESS
|
/* Error, callback missing or no more DMA to do */
|
||||||
/* Need a physical DMA address translation, if not already physical. */
|
pcm_rec_dma_stop();
|
||||||
pcm_rec_peak_addr = pcm_dma_addr(start);
|
pcm_recording_stopped();
|
||||||
#else
|
|
||||||
pcm_rec_peak_addr = start;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pcm_rec_dma_record_more(start, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pcm_is_recording(void)
|
|
||||||
{
|
|
||||||
return pcm_recording;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcm_rec_dma_stopped_callback(void)
|
|
||||||
{
|
|
||||||
pcm_recording = false;
|
|
||||||
pcm_callback_more_ready = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_RECORDING */
|
#endif /* HAVE_RECORDING */
|
||||||
|
|
|
||||||
|
|
@ -74,17 +74,12 @@ static void dma_callback(void)
|
||||||
{
|
{
|
||||||
if(!dma_size)
|
if(!dma_size)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback(&dma_start_addr, &dma_size);
|
||||||
if(get_more)
|
|
||||||
get_more(&dma_start_addr, &dma_size);
|
if (!dma_size)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!dma_size)
|
|
||||||
{
|
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
play_start_pcm();
|
play_start_pcm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,31 +270,19 @@ static void rec_dma_callback(void)
|
||||||
|
|
||||||
if(!rec_dma_size)
|
if(!rec_dma_size)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type2 more_ready = pcm_callback_more_ready;
|
pcm_rec_more_ready_callback(0, &rec_dma_start_addr, &rec_dma_size);
|
||||||
if (!more_ready || more_ready(0) < 0)
|
|
||||||
|
if(rec_dma_size != 0)
|
||||||
{
|
{
|
||||||
/* Finished recording */
|
dump_dcache_range(rec_dma_start_addr, rec_dma_size);
|
||||||
pcm_rec_dma_stop();
|
|
||||||
pcm_rec_dma_stopped_callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rec_dma_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
dump_dcache_range(start, size);
|
|
||||||
rec_dma_start_addr = start;
|
|
||||||
#if CONFIG_CPU == AS3525
|
#if CONFIG_CPU == AS3525
|
||||||
mono_samples = AS3525_UNCACHED_ADDR(start);
|
mono_samples = AS3525_UNCACHED_ADDR(rec_dma_start_addr);
|
||||||
#endif
|
#endif
|
||||||
rec_dma_size = size;
|
rec_dma_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcm_rec_dma_stop(void)
|
void pcm_rec_dma_stop(void)
|
||||||
{
|
{
|
||||||
dma_disable_channel(1);
|
dma_disable_channel(1);
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,9 @@ static struct dma_data dma_play_data =
|
||||||
|
|
||||||
static void play_dma_callback(void)
|
static void play_dma_callback(void)
|
||||||
{
|
{
|
||||||
unsigned char *start;
|
void *start;
|
||||||
size_t size = 0;
|
size_t size;
|
||||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
bool rror;
|
||||||
|
|
||||||
if (dma_play_data.locked != 0)
|
if (dma_play_data.locked != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -63,14 +63,12 @@ static void play_dma_callback(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dma_play_bd.mode.status & BD_RROR)
|
rror = dma_play_bd.mode.status & BD_RROR;
|
||||||
{
|
|
||||||
/* Stop on error */
|
pcm_play_get_more_callback(rror ? NULL : &start, &size);
|
||||||
}
|
|
||||||
else if (get_more != NULL && (get_more(&start, &size), size != 0))
|
if (size == 0)
|
||||||
{
|
return;
|
||||||
start = (void*)(((unsigned long)start + 3) & ~3);
|
|
||||||
size &= ~3;
|
|
||||||
|
|
||||||
/* Flush any pending cache writes */
|
/* Flush any pending cache writes */
|
||||||
clean_dcache_range(start, size);
|
clean_dcache_range(start, size);
|
||||||
|
|
@ -79,12 +77,6 @@ static void play_dma_callback(void)
|
||||||
dma_play_bd.mode.command = TRANSFER_16BIT;
|
dma_play_bd.mode.command = TRANSFER_16BIT;
|
||||||
dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
||||||
sdma_channel_run(DMA_PLAY_CH_NUM);
|
sdma_channel_run(DMA_PLAY_CH_NUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Error, callback missing or no more DMA to do */
|
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_play_lock(void)
|
void pcm_play_lock(void)
|
||||||
|
|
@ -272,12 +264,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
|
||||||
SSI_STCR2 &= ~SSI_STCR_TFEN0;
|
SSI_STCR2 &= ~SSI_STCR_TFEN0;
|
||||||
SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
|
SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
|
||||||
|
|
||||||
addr = (void *)(((unsigned long)addr + 3) & ~3);
|
|
||||||
size &= ~3;
|
|
||||||
|
|
||||||
if (size <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!sdma_channel_reset(DMA_PLAY_CH_NUM))
|
if (!sdma_channel_reset(DMA_PLAY_CH_NUM))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -383,8 +369,9 @@ static struct dma_data dma_rec_data =
|
||||||
|
|
||||||
static void rec_dma_callback(void)
|
static void rec_dma_callback(void)
|
||||||
{
|
{
|
||||||
pcm_more_callback_type2 more_ready;
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
void *start;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
if (dma_rec_data.locked != 0)
|
if (dma_rec_data.locked != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -395,17 +382,22 @@ static void rec_dma_callback(void)
|
||||||
if (dma_rec_bd.mode.status & BD_RROR)
|
if (dma_rec_bd.mode.status & BD_RROR)
|
||||||
status = DMA_REC_ERROR_DMA;
|
status = DMA_REC_ERROR_DMA;
|
||||||
|
|
||||||
more_ready = pcm_callback_more_ready;
|
pcm_rec_more_ready_callback(status, &start, &size);
|
||||||
|
|
||||||
if (more_ready != NULL && more_ready(status) >= 0)
|
if (size == 0)
|
||||||
{
|
|
||||||
sdma_channel_run(DMA_REC_CH_NUM);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Finished recording */
|
/* Invalidate - buffer must be coherent */
|
||||||
pcm_rec_dma_stop();
|
dump_dcache_range(start, size);
|
||||||
pcm_rec_dma_stopped_callback();
|
|
||||||
|
start = (void *)addr_virt_to_phys((unsigned long)start);
|
||||||
|
|
||||||
|
dma_rec_bd.buf_addr = start;
|
||||||
|
dma_rec_bd.mode.count = size;
|
||||||
|
dma_rec_bd.mode.command = TRANSFER_16BIT;
|
||||||
|
dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
||||||
|
|
||||||
|
sdma_channel_run(DMA_REC_CH_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_rec_lock(void)
|
void pcm_rec_lock(void)
|
||||||
|
|
@ -432,19 +424,6 @@ void pcm_rec_unlock(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
/* Invalidate - buffer must be coherent */
|
|
||||||
dump_dcache_range(start, size);
|
|
||||||
|
|
||||||
start = (void *)addr_virt_to_phys((unsigned long)start);
|
|
||||||
|
|
||||||
dma_rec_bd.buf_addr = start;
|
|
||||||
dma_rec_bd.mode.count = size;
|
|
||||||
dma_rec_bd.mode.command = TRANSFER_16BIT;
|
|
||||||
dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcm_rec_dma_stop(void)
|
void pcm_rec_dma_stop(void)
|
||||||
{
|
{
|
||||||
/* Stop receiving data */
|
/* Stop receiving data */
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,6 @@ void pcm_dma_apply_settings(void)
|
||||||
/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
|
/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
|
||||||
void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type get_more;
|
|
||||||
register size_t size;
|
register size_t size;
|
||||||
|
|
||||||
DMA0_STATUS; /* Clear any pending interrupt */
|
DMA0_STATUS; /* Clear any pending interrupt */
|
||||||
|
|
@ -141,15 +140,12 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buffer empty. Try to get more. */
|
/* Buffer empty. Try to get more. */
|
||||||
get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback((void **)&dma_play_data.addr,
|
||||||
if (get_more) {
|
&dma_play_data.size);
|
||||||
get_more((unsigned char **)&dma_play_data.addr, &dma_play_data.size);
|
|
||||||
dma_play_data.addr = (dma_play_data.addr + 2) & ~3;
|
|
||||||
dma_play_data.size &= ~3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dma_play_data.size == 0) {
|
if (dma_play_data.size == 0) {
|
||||||
break;
|
/* No more data */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dma_play_data.addr < UNCACHED_BASE_ADDR) {
|
if (dma_play_data.addr < UNCACHED_BASE_ADDR) {
|
||||||
|
|
@ -158,10 +154,6 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
|
||||||
cpucache_flush();
|
cpucache_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback missing or no more DMA to do */
|
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by
|
/* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by
|
||||||
|
|
@ -247,28 +239,16 @@ void fiq_playback(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
".more_data: \n"
|
".more_data: \n"
|
||||||
"ldr r2, =pcm_callback_for_more \n"
|
"ldr r2, =pcm_play_get_more_callback \n"
|
||||||
"ldr r2, [r2] \n" /* get callback address */
|
|
||||||
"cmp r2, #0 \n" /* check for null pointer */
|
|
||||||
"beq .stop \n" /* callback removed, stop */
|
|
||||||
"stmia r11, { r8-r9 } \n" /* save internal copies of variables back */
|
|
||||||
"mov r0, r11 \n" /* r0 = &p */
|
"mov r0, r11 \n" /* r0 = &p */
|
||||||
"add r1, r11, #4 \n" /* r1 = &size */
|
"add r1, r11, #4 \n" /* r1 = &size */
|
||||||
"mov lr, pc \n" /* call pcm_callback_for_more */
|
"mov lr, pc \n" /* call pcm_play_get_more_callback */
|
||||||
"bx r2 \n"
|
"bx r2 \n"
|
||||||
"ldmia r11, { r8-r9 } \n" /* reload p and size */
|
"ldmia r11, { r8-r9 } \n" /* load new p and size */
|
||||||
"cmp r9, #0 \n" /* did we actually get more data? */
|
"cmp r9, #0 \n"
|
||||||
"bne .check_fifo \n"
|
"bne .check_fifo \n" /* size != 0? refill */
|
||||||
|
|
||||||
".stop: \n" /* call termination routines */
|
".exit: \n" /* (r9=0 if stopping, look above) */
|
||||||
"ldr r12, =pcm_play_dma_stop \n"
|
|
||||||
"mov lr, pc \n"
|
|
||||||
"bx r12 \n"
|
|
||||||
"ldr r12, =pcm_play_dma_stopped_callback \n"
|
|
||||||
"mov lr, pc \n"
|
|
||||||
"bx r12 \n"
|
|
||||||
|
|
||||||
".exit: \n" /* (r8=0 if stopping, look above) */
|
|
||||||
"stmia r11, { r8-r9 } \n" /* save p and size */
|
"stmia r11, { r8-r9 } \n" /* save p and size */
|
||||||
"ldmfd sp!, { r0-r3, lr } \n"
|
"ldmfd sp!, { r0-r3, lr } \n"
|
||||||
"subs pc, lr, #4 \n" /* FIQ specific return sequence */
|
"subs pc, lr, #4 \n" /* FIQ specific return sequence */
|
||||||
|
|
@ -284,8 +264,6 @@ void fiq_playback(void) __attribute__((interrupt ("FIQ"))) ICODE_ATTR;
|
||||||
/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
|
/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
|
||||||
void fiq_playback(void)
|
void fiq_playback(void)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type get_more;
|
|
||||||
|
|
||||||
#if CONFIG_CPU == PP5002
|
#if CONFIG_CPU == PP5002
|
||||||
inl(0xcf001040);
|
inl(0xcf001040);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -305,16 +283,11 @@ void fiq_playback(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* p is empty, get some more data */
|
/* p is empty, get some more data */
|
||||||
get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback((void **)&dma_play_data.addr,
|
||||||
if (get_more) {
|
|
||||||
get_more((unsigned char**)&dma_play_data.addr,
|
|
||||||
&dma_play_data.size);
|
&dma_play_data.size);
|
||||||
}
|
|
||||||
} while (dma_play_data.size);
|
} while (dma_play_data.size);
|
||||||
|
|
||||||
/* No more data, so disable the FIFO/interrupt */
|
/* No more data */
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
}
|
||||||
#endif /* ASM / C selection */
|
#endif /* ASM / C selection */
|
||||||
#endif /* CPU_PP502x */
|
#endif /* CPU_PP502x */
|
||||||
|
|
@ -589,7 +562,6 @@ void fiq_record(void) ICODE_ATTR __attribute__((interrupt ("FIQ")));
|
||||||
#if defined(SANSA_C200) || defined(SANSA_E200)
|
#if defined(SANSA_C200) || defined(SANSA_E200)
|
||||||
void fiq_record(void)
|
void fiq_record(void)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type2 more_ready;
|
|
||||||
register int32_t value;
|
register int32_t value;
|
||||||
|
|
||||||
if (audio_channels == 2) {
|
if (audio_channels == 2) {
|
||||||
|
|
@ -648,20 +620,13 @@ void fiq_record(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
more_ready = pcm_callback_more_ready;
|
pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr,
|
||||||
|
&dma_rec_data.size);
|
||||||
if (more_ready == NULL || more_ready(0) < 0) {
|
|
||||||
/* Finished recording */
|
|
||||||
pcm_rec_dma_stop();
|
|
||||||
pcm_rec_dma_stopped_callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void fiq_record(void)
|
void fiq_record(void)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type2 more_ready;
|
|
||||||
|
|
||||||
while (dma_rec_data.size > 0) {
|
while (dma_rec_data.size > 0) {
|
||||||
if (IIS_RX_FULL_COUNT < 2) {
|
if (IIS_RX_FULL_COUNT < 2) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -676,24 +641,12 @@ void fiq_record(void)
|
||||||
dma_rec_data.size -= 4;
|
dma_rec_data.size -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
more_ready = pcm_callback_more_ready;
|
pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr,
|
||||||
|
&dma_rec_data.size);
|
||||||
if (more_ready == NULL || more_ready(0) < 0) {
|
|
||||||
/* Finished recording */
|
|
||||||
pcm_rec_dma_stop();
|
|
||||||
pcm_rec_dma_stopped_callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SANSA_E200 */
|
#endif /* SANSA_E200 */
|
||||||
|
|
||||||
/* Continue transferring data in */
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
dma_rec_data.addr = (unsigned long)start; /* Start of RX buffer */
|
|
||||||
dma_rec_data.size = size; /* Bytes to transfer */
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcm_rec_dma_stop(void)
|
void pcm_rec_dma_stop(void)
|
||||||
{
|
{
|
||||||
/* disable interrupt */
|
/* disable interrupt */
|
||||||
|
|
|
||||||
|
|
@ -233,12 +233,6 @@ const void * pcm_rec_dma_get_peak_buffer(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
(void) start;
|
|
||||||
(void) size;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CPU_TCC77X) || defined(CPU_TCC780X)
|
#if defined(CPU_TCC77X) || defined(CPU_TCC780X)
|
||||||
|
|
@ -289,21 +283,14 @@ void fiq_handler(void)
|
||||||
|
|
||||||
".more_data: \n"
|
".more_data: \n"
|
||||||
"stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */
|
"stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */
|
||||||
"ldr r2, =pcm_callback_for_more \n"
|
"ldr r2, =pcm_play_get_more_callback \n"
|
||||||
"ldr r2, [r2] \n" /* get callback address */
|
"mov r0, r11 \n" /* r0 = &p */
|
||||||
"cmp r2, #0 \n" /* check for null pointer */
|
"add r1, r11, #4 \n" /* r1 = &size */
|
||||||
"movne r0, r11 \n" /* r0 = &p */
|
"blx r2 \n" /* call pcm_play_get_more_callback */
|
||||||
"addne r1, r11, #4 \n" /* r1 = &size */
|
"ldmia r11, { r8-r9 } \n" /* load new p and size */
|
||||||
"blxne r2 \n" /* call pcm_callback_for_more */
|
"cmp r9, #0x10 \n" /* did we actually get enough data? */
|
||||||
"ldmia r11, { r8-r9 } \n" /* reload p and size */
|
|
||||||
"cmp r9, #0x10 \n" /* did we actually get more data? */
|
|
||||||
"ldmgefd sp!, { r0-r3, lr } \n"
|
|
||||||
"bge .fill_fifo \n" /* yes: fill the fifo */
|
|
||||||
"ldr r12, =pcm_play_dma_stop \n"
|
|
||||||
"blx r12 \n" /* no: stop playback */
|
|
||||||
"ldr r12, =pcm_play_dma_stopped_callback \n"
|
|
||||||
"blx r12 \n"
|
|
||||||
"ldmfd sp!, { r0-r3, lr } \n"
|
"ldmfd sp!, { r0-r3, lr } \n"
|
||||||
|
"bpl .fill_fifo \n" /* not stop and enough? refill */
|
||||||
"b .exit \n"
|
"b .exit \n"
|
||||||
".ltorg \n"
|
".ltorg \n"
|
||||||
);
|
);
|
||||||
|
|
@ -315,18 +302,12 @@ void fiq_handler(void)
|
||||||
asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
|
asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
|
||||||
"sub sp, sp, #8 \n"); /* Reserve stack */
|
"sub sp, sp, #8 \n"); /* Reserve stack */
|
||||||
|
|
||||||
register pcm_more_callback_type get_more;
|
|
||||||
|
|
||||||
if (dma_play_data.size < 16)
|
if (dma_play_data.size < 16)
|
||||||
{
|
{
|
||||||
/* p is empty, get some more data */
|
/* p is empty, get some more data */
|
||||||
get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback((void**)&dma_play_data.p,
|
||||||
if (get_more)
|
|
||||||
{
|
|
||||||
get_more((unsigned char**)&dma_play_data.p,
|
|
||||||
&dma_play_data.size);
|
&dma_play_data.size);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dma_play_data.size >= 16)
|
if (dma_play_data.size >= 16)
|
||||||
{
|
{
|
||||||
|
|
@ -341,12 +322,6 @@ void fiq_handler(void)
|
||||||
|
|
||||||
dma_play_data.size -= 16;
|
dma_play_data.size -= 16;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No more data, so disable the FIFO/interrupt */
|
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FIQ status */
|
/* Clear FIQ status */
|
||||||
CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK;
|
CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK;
|
||||||
|
|
|
||||||
|
|
@ -104,13 +104,10 @@ static inline void fill_dma_buf(int offset)
|
||||||
p = tmp_p;
|
p = tmp_p;
|
||||||
if (l >= lend)
|
if (l >= lend)
|
||||||
return;
|
return;
|
||||||
else if (pcm_callback_for_more)
|
|
||||||
pcm_callback_for_more((unsigned char**)&p,
|
pcm_play_get_more_callback((void**)&p, &p_size);
|
||||||
&p_size);
|
|
||||||
}
|
}
|
||||||
while (p_size);
|
while (p_size);
|
||||||
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l < lend)
|
if (l < lend)
|
||||||
|
|
|
||||||
|
|
@ -214,25 +214,18 @@ void pcm_play_dma_pause(bool pause)
|
||||||
|
|
||||||
void fiq_handler(void)
|
void fiq_handler(void)
|
||||||
{
|
{
|
||||||
static unsigned char *start;
|
static void *start;
|
||||||
static size_t size;
|
static size_t size;
|
||||||
register pcm_more_callback_type get_more; /* No stack for this */
|
|
||||||
|
|
||||||
/* clear any pending interrupt */
|
/* clear any pending interrupt */
|
||||||
SRCPND = DMA2_MASK;
|
SRCPND = DMA2_MASK;
|
||||||
|
|
||||||
/* Buffer empty. Try to get more. */
|
/* Buffer empty. Try to get more. */
|
||||||
get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback(&start, &size);
|
||||||
size = 0;
|
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Flush any pending cache writes */
|
/* Flush any pending cache writes */
|
||||||
clean_dcache_range(start, size);
|
clean_dcache_range(start, size);
|
||||||
|
|
||||||
|
|
@ -242,7 +235,6 @@ void fiq_handler(void)
|
||||||
|
|
||||||
/* Re-Activate the channel */
|
/* Re-Activate the channel */
|
||||||
DMASKTRIG2 = 0x2;
|
DMASKTRIG2 = 0x2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcm_get_bytes_waiting(void)
|
size_t pcm_get_bytes_waiting(void)
|
||||||
|
|
|
||||||
|
|
@ -254,25 +254,18 @@ void pcm_play_dma_pause(bool pause)
|
||||||
|
|
||||||
void fiq_handler(void)
|
void fiq_handler(void)
|
||||||
{
|
{
|
||||||
static unsigned char *start;
|
static void *start;
|
||||||
static size_t size;
|
static size_t size;
|
||||||
register pcm_more_callback_type get_more; /* No stack for this */
|
|
||||||
|
|
||||||
/* clear any pending interrupt */
|
/* clear any pending interrupt */
|
||||||
SRCPND = DMA2_MASK;
|
SRCPND = DMA2_MASK;
|
||||||
|
|
||||||
/* Buffer empty. Try to get more. */
|
/* Buffer empty. Try to get more. */
|
||||||
get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback(&start, &size);
|
||||||
size = 0;
|
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Flush any pending cache writes */
|
/* Flush any pending cache writes */
|
||||||
clean_dcache_range(start, size);
|
clean_dcache_range(start, size);
|
||||||
|
|
||||||
|
|
@ -282,7 +275,6 @@ void fiq_handler(void)
|
||||||
|
|
||||||
/* Re-Activate the channel */
|
/* Re-Activate the channel */
|
||||||
DMASKTRIG2 = 0x2;
|
DMASKTRIG2 = 0x2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcm_get_bytes_waiting(void)
|
size_t pcm_get_bytes_waiting(void)
|
||||||
|
|
|
||||||
|
|
@ -102,11 +102,11 @@ static const void* dma_callback(void)
|
||||||
{
|
{
|
||||||
if (dmamode)
|
if (dmamode)
|
||||||
{
|
{
|
||||||
unsigned char *dma_start_addr;
|
void *dma_start_addr;
|
||||||
register pcm_more_callback_type get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback(&dma_start_addr, &nextsize);
|
||||||
if (get_more)
|
|
||||||
|
if (nextsize != 0)
|
||||||
{
|
{
|
||||||
get_more(&dma_start_addr, &nextsize);
|
|
||||||
if (nextsize >= 4096)
|
if (nextsize >= 4096)
|
||||||
{
|
{
|
||||||
dblbufsize = (nextsize >> 4) & ~3;
|
dblbufsize = (nextsize >> 4) & ~3;
|
||||||
|
|
@ -148,7 +148,6 @@ void fiq_handler(void)
|
||||||
"mov r10, #0x00000400 \n" /* INT_DMA */
|
"mov r10, #0x00000400 \n" /* INT_DMA */
|
||||||
"str r10, [r11] \n" /* ACK FIQ */
|
"str r10, [r11] \n" /* ACK FIQ */
|
||||||
"stmfd sp!, {r0-r3,lr} \n"
|
"stmfd sp!, {r0-r3,lr} \n"
|
||||||
"ldreq r0, =pcm_play_dma_stopped_callback \n"
|
|
||||||
"ldrne r0, =dma_callback \n"
|
"ldrne r0, =dma_callback \n"
|
||||||
"mov lr, pc \n"
|
"mov lr, pc \n"
|
||||||
"bx r0 \n"
|
"bx r0 \n"
|
||||||
|
|
@ -225,13 +224,6 @@ void pcm_play_dma_start(const void *addr_in, size_t size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* S3: DMA channel 0 on */
|
/* S3: DMA channel 0 on */
|
||||||
if (!size)
|
|
||||||
{
|
|
||||||
register pcm_more_callback_type get_more = pcm_callback_for_more;
|
|
||||||
if (get_more) get_more(&addr, &size);
|
|
||||||
else return; /* Nothing to play!? */
|
|
||||||
}
|
|
||||||
if (!size) return; /* Nothing to play!? */
|
|
||||||
clean_dcache();
|
clean_dcache();
|
||||||
if (size >= 4096)
|
if (size >= 4096)
|
||||||
{
|
{
|
||||||
|
|
@ -367,12 +359,6 @@ void pcm_rec_unlock(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
(void)start;
|
|
||||||
(void)size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcm_rec_dma_stop(void)
|
void pcm_rec_dma_stop(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,8 +132,6 @@ char buffer[80];
|
||||||
void DSPHINT(void) __attribute__ ((section(".icode")));
|
void DSPHINT(void) __attribute__ ((section(".icode")));
|
||||||
void DSPHINT(void)
|
void DSPHINT(void)
|
||||||
{
|
{
|
||||||
register pcm_more_callback_type get_more; /* No stack for this */
|
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
IO_INTC_FIQ0 = 1 << 11;
|
IO_INTC_FIQ0 = 1 << 11;
|
||||||
|
|
@ -152,16 +150,9 @@ void DSPHINT(void)
|
||||||
|
|
||||||
case MSG_REFILL:
|
case MSG_REFILL:
|
||||||
/* Buffer empty. Try to get more. */
|
/* Buffer empty. Try to get more. */
|
||||||
get_more = pcm_callback_for_more;
|
pcm_play_get_more_callback(&start, &size);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (size != 0)
|
||||||
{
|
{
|
||||||
unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
|
unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
|
||||||
/* Flush any pending cache writes */
|
/* Flush any pending cache writes */
|
||||||
|
|
|
||||||
|
|
@ -288,13 +288,14 @@ void DMA0(void) __attribute__ ((interrupt_handler, section(".icode")));
|
||||||
void DMA0(void)
|
void DMA0(void)
|
||||||
{
|
{
|
||||||
unsigned long res = DSR0;
|
unsigned long res = DSR0;
|
||||||
|
void *start;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */
|
and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */
|
||||||
DSR0 = 1; /* Clear interrupt and errors */
|
DSR0 = 1; /* Clear interrupt and errors */
|
||||||
|
|
||||||
if (res & 0x70)
|
if (res & 0x70)
|
||||||
{
|
{
|
||||||
/* Stop on error */
|
|
||||||
logf("DMA0 err: %02x", res);
|
logf("DMA0 err: %02x", res);
|
||||||
#if 0
|
#if 0
|
||||||
logf(" SAR0: %08x", SAR0);
|
logf(" SAR0: %08x", SAR0);
|
||||||
|
|
@ -303,32 +304,17 @@ void DMA0(void)
|
||||||
logf(" DCR0: %08x", DCR0);
|
logf(" DCR0: %08x", DCR0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
|
||||||
unsigned char *start;
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
if (get_more)
|
/* Force stop on error */
|
||||||
get_more(&start, &size);
|
pcm_play_get_more_callback((res & 0x70) ? NULL : &start, &size);
|
||||||
|
|
||||||
start = (unsigned char *)(((long)start + 3) & ~3);
|
if (size != 0)
|
||||||
size &= ~3;
|
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
{
|
{
|
||||||
SAR0 = (unsigned long)start; /* Source address */
|
SAR0 = (unsigned long)start; /* Source address */
|
||||||
BCR0 = size; /* Bytes to transfer */
|
BCR0 = size; /* Bytes to transfer */
|
||||||
or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */
|
or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
/* Finished playing */
|
/* else inished playing */
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop interrupt and futher transfers */
|
|
||||||
pcm_play_dma_stop();
|
|
||||||
/* Inform PCM that we're done */
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
} /* DMA0 */
|
} /* DMA0 */
|
||||||
|
|
||||||
const void * pcm_play_dma_get_peak_buffer(int *count)
|
const void * pcm_play_dma_get_peak_buffer(int *count)
|
||||||
|
|
@ -436,7 +422,8 @@ void DMA1(void)
|
||||||
{
|
{
|
||||||
unsigned long res = DSR1;
|
unsigned long res = DSR1;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
pcm_more_callback_type2 more_ready;
|
void *start;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */
|
and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */
|
||||||
DSR1 = 1; /* Clear interrupt and errors */
|
DSR1 = 1; /* Clear interrupt and errors */
|
||||||
|
|
@ -465,24 +452,16 @@ void DMA1(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
more_ready = pcm_callback_more_ready;
|
/* Inform PCM we have more data (or error) */
|
||||||
|
pcm_rec_more_ready_callback(status, &start, &size);
|
||||||
|
|
||||||
if (more_ready != NULL && more_ready(status) >= 0)
|
if (size != 0)
|
||||||
return;
|
{
|
||||||
|
|
||||||
/* Finished recording */
|
|
||||||
pcm_rec_dma_stop();
|
|
||||||
/* Inform PCM that we're done */
|
|
||||||
pcm_rec_dma_stopped_callback();
|
|
||||||
} /* DMA1 */
|
|
||||||
|
|
||||||
/* Continue transferring data in - call from interrupt callback */
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
DAR1 = (unsigned long)start; /* Destination address */
|
DAR1 = (unsigned long)start; /* Destination address */
|
||||||
BCR1 = (unsigned long)size; /* Bytes to transfer */
|
BCR1 = (unsigned long)size; /* Bytes to transfer */
|
||||||
or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
|
or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
|
||||||
} /* pcm_record_more */
|
}
|
||||||
|
} /* DMA1 */
|
||||||
|
|
||||||
const void * pcm_rec_dma_get_peak_buffer(void)
|
const void * pcm_rec_dma_get_peak_buffer(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -228,15 +228,9 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
|
||||||
|
|
||||||
/* Audio card wants more? Get some more then. */
|
/* Audio card wants more? Get some more then. */
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if ((ssize_t)pcm_data_size <= 0) {
|
pcm_play_get_more_callback(&pcm_data, &pcm_data_size);
|
||||||
pcm_data_size = 0;
|
|
||||||
|
|
||||||
if (pcm_callback_for_more)
|
|
||||||
pcm_callback_for_more(&pcm_data, &pcm_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pcm_data_size > 0) {
|
|
||||||
start:
|
start:
|
||||||
|
if (pcm_data_size != 0) {
|
||||||
udata->num_in = pcm_data_size / pcm_sample_bytes;
|
udata->num_in = pcm_data_size / pcm_sample_bytes;
|
||||||
udata->num_out = len / pcm_sample_bytes;
|
udata->num_out = len / pcm_sample_bytes;
|
||||||
|
|
||||||
|
|
@ -251,8 +245,6 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
|
||||||
len -= udata->num_out;
|
len -= udata->num_out;
|
||||||
} else {
|
} else {
|
||||||
DEBUGF("sdl_audio_callback: No Data.\n");
|
DEBUGF("sdl_audio_callback: No Data.\n");
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -292,12 +284,6 @@ void pcm_rec_dma_stop(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
(void)start;
|
|
||||||
(void)size;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long pcm_rec_status(void)
|
unsigned long pcm_rec_status(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -100,23 +100,16 @@ static inline void set_dma(const void *addr, size_t size)
|
||||||
|
|
||||||
static inline void play_dma_callback(void)
|
static inline void play_dma_callback(void)
|
||||||
{
|
{
|
||||||
unsigned char *start = NULL;
|
unsigned char *start;
|
||||||
size_t size = 0;
|
size_t size;
|
||||||
|
|
||||||
if(pcm_callback_for_more)
|
pcm_play_get_more_callback(&start, &size);
|
||||||
pcm_callback_for_more(&start, &size);
|
|
||||||
|
|
||||||
if(LIKELY(size > 0 && start))
|
if (size != 0)
|
||||||
{
|
{
|
||||||
set_dma(start, size);
|
set_dma(start, size);
|
||||||
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
|
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Error, callback missing or no more DMA to do */
|
|
||||||
pcm_play_dma_stop();
|
|
||||||
pcm_play_dma_stopped_callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) __attribute__ ((section(".icode")));
|
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) __attribute__ ((section(".icode")));
|
||||||
|
|
@ -292,10 +285,4 @@ const void * pcm_rec_dma_get_peak_buffer(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_rec_dma_record_more(void *start, size_t size)
|
|
||||||
{
|
|
||||||
(void) start;
|
|
||||||
(void) size;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue