From 6077e5b7c85c0d6f5963e4aadb215faf2c4d10d2 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 6 Oct 2007 22:27:27 +0000 Subject: Unify PCM interface just above the hardware driver level for all targets including the sims. Perform lockout of audio callback when changing states. Weird new playback or recording trouble? Check before and after this revision first though things seem quite sound. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15006 a1c6a512-1295-4272-9138-f99709370657 --- firmware/export/audio.h | 2 +- firmware/export/pcm.h | 122 +++++++++++++++++++++++++++++++++++++++++ firmware/export/pcm_playback.h | 65 ---------------------- firmware/export/pcm_record.h | 34 ------------ firmware/export/pp5002.h | 20 ++++++- firmware/export/pp5020.h | 90 +++++++++++++++++++++++++++++- 6 files changed, 229 insertions(+), 104 deletions(-) create mode 100644 firmware/export/pcm.h delete mode 100644 firmware/export/pcm_playback.h (limited to 'firmware/export') diff --git a/firmware/export/audio.h b/firmware/export/audio.h index b55c46a573..84275cca2a 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h @@ -26,7 +26,7 @@ many files. */ #if CONFIG_CODEC == SWCODEC #include "pcm_sampr.h" -#include "pcm_playback.h" +#include "pcm.h" #ifdef HAVE_RECORDING #include "pcm_record.h" #include "id3.h" diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h new file mode 100644 index 0000000000..a875479a2d --- /dev/null +++ b/firmware/export/pcm.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef PCM_PLAYBACK_H +#define PCM_PLAYBACK_H + +#include + +/** RAW PCM routines used with playback and recording **/ + +/* Typedef for registered callback */ +typedef void (*pcm_more_callback_type)(unsigned char **start, + size_t *size); +typedef int (*pcm_more_callback_type2)(int status); + +/* set the pcm frequency - use values in hw_sampr_list + * use -1 for the default frequency + */ +void pcm_set_frequency(unsigned int frequency); +/* apply settings to hardware immediately */ +void pcm_apply_settings(void); + +/** RAW PCM playback routines **/ + +/* Reenterable locks for locking and unlocking the playback interrupt */ +void pcm_play_lock(void); +void pcm_play_unlock(void); + +void pcm_init(void); +void pcm_postinit(void); + +/* This is for playing "raw" PCM data */ +void pcm_play_data(pcm_more_callback_type get_more, + unsigned char* start, size_t size); + +void pcm_calculate_peaks(int *left, int *right); +size_t pcm_get_bytes_waiting(void); + +void pcm_play_stop(void); +void pcm_mute(bool mute); +void pcm_play_pause(bool play); +bool pcm_is_paused(void); +bool pcm_is_playing(void); + +/** The following are for internal use between pcm.c and target- + specific portion **/ + +extern unsigned long pcm_curr_sampr; + +/* 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_paused; + +void pcm_play_dma_lock(void); +void pcm_play_dma_unlock(void); +void pcm_play_dma_init(void); +void pcm_play_dma_start(const void *addr, size_t size); +void pcm_play_dma_stop(void); +void pcm_play_dma_pause(bool pause); +void pcm_play_dma_stopped_callback(void); +const void * pcm_play_dma_get_peak_buffer(int *count); + +#ifdef HAVE_RECORDING + +/** RAW PCM recording routines **/ + +/* Reenterable locks for locking and unlocking the recording interrupt */ +void pcm_rec_lock(void); +void pcm_rec_unlock(void); + +/* Initialize pcm recording interface */ +void pcm_init_recording(void); +/* Uninitialze pcm recording interface */ +void pcm_close_recording(void); + +/* Start recording "raw" PCM data */ +void pcm_record_data(pcm_more_callback_type2 more_ready, + void *start, size_t size); + +/* Stop tranferring data into supplied buffer */ +void pcm_stop_recording(void); + +/* Continue transferring data in - call during interrupt handler */ +void pcm_record_more(void *start, size_t size); + +void pcm_calculate_rec_peaks(int *left, int *right); + +/** The following are for internal use between pcm.c and target- + specific portion **/ +extern volatile const void *pcm_rec_peak_addr; +/* 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 */ +extern volatile bool pcm_recording; + +/* APIs implemented in the target-specific portion */ +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_stop(void); +void pcm_rec_dma_stopped_callback(void); +const void * pcm_rec_dma_get_peak_buffer(int *count); + +#endif /* HAVE_RECORDING */ + +#endif /* PCM_PLAYBACK_H */ diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h deleted file mode 100644 index 351b1fa23f..0000000000 --- a/firmware/export/pcm_playback.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2005 by Linus Nielsen Feltzing - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef PCM_PLAYBACK_H -#define PCM_PLAYBACK_H - -#include - -/* Typedef for registered callback (play and record) */ -typedef void (*pcm_more_callback_type)(unsigned char **start, - size_t *size); -typedef int (*pcm_more_callback_type2)(int status); - -void pcm_init(void); -void pcm_postinit(void); - -/* set the pcm frequency - use values in hw_sampr_list - * use -1 for the default frequency - */ -void pcm_set_frequency(unsigned int frequency); -/* apply settings to hardware immediately */ -void pcm_apply_settings(void); - -/* This is for playing "raw" PCM data */ -void pcm_play_data(pcm_more_callback_type get_more, - unsigned char* start, size_t size); - -void pcm_calculate_peaks(int *left, int *right); -size_t pcm_get_bytes_waiting(void); - -void pcm_play_stop(void); -void pcm_mute(bool mute); -void pcm_play_pause(bool play); -bool pcm_is_paused(void); -bool pcm_is_playing(void); - -/** The following are for internal use between pcm_playback.c and target- - specific portion **/ - -/* 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_paused; - -extern void pcm_play_dma_start(const void *addr, size_t size); -extern void pcm_play_dma_stop(void); -extern void pcm_play_pause_pause(void); -extern void pcm_play_pause_unpause(void); - -#endif /* PCM_PLAYBACK_H */ diff --git a/firmware/export/pcm_record.h b/firmware/export/pcm_record.h index 19c10cb228..814eb73b3a 100644 --- a/firmware/export/pcm_record.h +++ b/firmware/export/pcm_record.h @@ -44,28 +44,6 @@ #define PCMREC_E_CHUNK_OVF 0x80010000 #endif /* DEBUG */ -/** - * RAW pcm data recording - * These calls are nescessary only when using the raw pcm apis directly. - */ - -/* Initialize pcm recording interface */ -void pcm_init_recording(void); -/* Uninitialze pcm recording interface */ -void pcm_close_recording(void); - -/* Start recording "raw" PCM data */ -void pcm_record_data(pcm_more_callback_type2 more_ready, - void *start, size_t size); - -/* Stop tranferring data into supplied buffer */ -void pcm_stop_recording(void); - -/* Continue transferring data in - call during interrupt handler */ -void pcm_record_more(void *start, size_t size); - -void pcm_calculate_rec_peaks(int *left, int *right); - /** General functions for high level codec recording **/ /* pcm_rec_error_clear is deprecated for general use. audio_error_clear should be used */ @@ -83,16 +61,4 @@ int pcm_get_num_unprocessed(void); /* audio.h contains audio_* recording functions */ - -/** The following are for internal use between pcm_record.c and target- - 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 */ -extern volatile bool pcm_recording; - -/* APIs implemented in the target-specific portion */ -extern void pcm_rec_dma_start(void *addr, size_t size); -extern void pcm_rec_dma_stop(void); - #endif /* PCM_RECORD_H */ diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h index f566b5cd04..730e42b66d 100644 --- a/firmware/export/pp5002.h +++ b/firmware/export/pp5002.h @@ -26,12 +26,28 @@ #define IPOD_LCD_BASE 0xc0001000 -#define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) +/* Processor ID */ +#define PROCESSOR_ID (*(volatile unsigned long *)(0xc4000000)) +#define PROC_ID_CPU 0x55 +#define PROC_ID_COP 0xaa + +#define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) #define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c)) #define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540)) #define IISFIFO_RD (*(volatile unsigned long *)(0xc0002580)) +/* IISCONFIG bits: */ +#define IIS_TXFIFOEN (1 << 2) +#define IIS_TX_FREE_MASK (0xf << 23) +#define IIS_TX_FREE_COUNT ((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 23) + +/* IISFIFO_CFG bits: */ +#define IIS_IRQTX_REG IISFIFO_CFG +#define IIS_IRQTX (1 << 9) + +#define I2C_BASE 0xc0008000 + #define IDE_BASE 0xc0003000 #define IDE_CFG_STATUS (*(volatile unsigned long *)(0xc0003024)) @@ -103,6 +119,8 @@ #define DMA_OUT_MASK (1 << DMA_OUT_IRQ) #define DMA_IN_MASK (1 << DMA_IN_IRQ) +/* Yes, there is I2S_MASK but this cleans up the pcm code */ +#define IIS_MASK DMA_OUT_MASK #define TIMER1_CFG (*(volatile unsigned long *)(0xcf001100)) #define TIMER1_VAL (*(volatile unsigned long *)(0xcf001104)) diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index af78101583..981ab318c5 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h @@ -84,7 +84,7 @@ #define TIMER1_IRQ 0 #define TIMER2_IRQ 1 #define MAILBOX_IRQ 4 -#define I2S_IRQ 10 +#define IIS_IRQ 10 #define IDE_IRQ 23 #define USB_IRQ 24 #define FIREWIRE_IRQ 25 @@ -97,7 +97,7 @@ #define TIMER1_MASK (1 << TIMER1_IRQ) #define TIMER2_MASK (1 << TIMER2_IRQ) #define MAILBOX_MASK (1 << MAILBOX_IRQ) -#define I2S_MASK (1 << I2S_IRQ) +#define IIS_MASK (1 << IIS_IRQ) #define IDE_MASK (1 << IDE_IRQ) #define USB_MASK (1 << USB_IRQ) #define FIREWIRE_MASK (1 << FIREWIRE_IRQ) @@ -307,12 +307,96 @@ #define INIT_USB 0x80000000 -/* I2S */ +/* IIS */ #define IISCONFIG (*(volatile unsigned long*)(0x70002800)) #define IISFIFO_CFG (*(volatile unsigned long*)(0x7000280c)) #define IISFIFO_WR (*(volatile unsigned long*)(0x70002840)) #define IISFIFO_RD (*(volatile unsigned long*)(0x70002880)) +/** + * IISCONFIG bits: + * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | + * | RESET | |TXFIFOEN|RXFIFOEN| | ???? | MS | ???? | + * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | + * | | | | | | | | | + * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | + * | | | | | Bus Format[1:0] | Size[1:0] | + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * | | Size Format[2:0] | ???? | ???? | IRQTX | IRQRX | + */ + +/* All IIS formats send MSB first */ +#define IIS_RESET (1 << 31) +#define IIS_TXFIFOEN (1 << 29) +#define IIS_RXFIFOEN (1 << 28) +#define IIS_MASTER (1 << 25) +#define IIS_IRQTX (1 << 1) +#define IIS_IRQRX (1 << 0) + +#define IIS_IRQTX_REG IISCONFIG +#define IIS_IRQRX_REG IISCONFIG + +/* Data format on the IIS bus */ +#define IIS_FORMAT_MASK (0x3 << 10) +#define IIS_FORMAT_IIS (0x0 << 10) /* Standard IIS - leading dummy bit */ +#define IIS_FORMAT_1 (0x1 << 10) +#define IIS_FORMAT_LJUST (0x2 << 10) /* Left justified - no dummy bit */ +#define IIS_FORMAT_3 (0x3 << 10) +/* Other formats not yet known */ + +/* Data size on IIS bus */ +#define IIS_SIZE_MASK (0x3 << 8) +#define IIS_SIZE_16BIT (0x0 << 8) +/* Other sizes not yet known */ + +/* Data size/format on IIS FIFO */ +#define IIS_FIFO_FORMAT_MASK (0x7 << 4) +#define IIS_FIFO_FORMAT_0 (0x0 << 4) +/* Big-endian formats - data sent to the FIFO must be big endian. + * I forgot which is which size but did test them. */ +#define IIS_FIFO_FORMAT_1 (0x1 << 4) +#define IIS_FIFO_FORMAT_2 (0x2 << 4) + /* 32bit-MSB-little endian */ +#define IIS_FIFO_FORMAT_LE32 (0x3 << 4) + /* 16bit-MSB-little endian */ +#define IIS_FIFO_FORMAT_LE16 (0x4 << 4) + +/* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */ + +/** + * IISFIFO_CFG bits: + * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | + * | | | RXFull[5:0] | + * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | + * | | | TXFree[5:0] | + * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | + * | | | | RXCLR | | | | TXCLR | + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * | | | RX_FULL_LVL | | | TX_EMPTY_LVL | + */ + +/* handy macros to extract the FIFO counts */ +#define IIS_RX_FULL_MASK (0x3f << 24) +#define IIS_RX_FULL_COUNT \ + ((IISFIFO_CFG & IIS_RX_FULL_MASK) >> 24) + +#define IIS_TX_FREE_MASK (0x3f << 16) +#define IIS_TX_FREE_COUNT \ + ((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 16) + +#define IIS_RXCLR (1 << 12) +#define IIS_TXCLR (1 << 8) +/* Number of slots */ +#define IIS_RX_FULL_LVL_4 (0x1 << 4) +#define IIS_RX_FULL_LVL_8 (0x2 << 4) +#define IIS_RX_FULL_LVL_12 (0x3 << 4) + +#define IIS_TX_EMPTY_LVL_4 (0x1 << 0) +#define IIS_TX_EMPTY_LVL_8 (0x2 << 0) +#define IIS_TX_EMPTY_LVL_12 (0x3 << 0) + +/* Note: didn't bother to see of levels 0 and 16 actually work */ + /* Serial Controller */ #define SERIAL0 (*(volatile unsigned long*)(0x70006000)) #define SERIAL1 (*(volatile unsigned long*)(0x70006040)) -- cgit v1.2.3