diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-05-22 15:34:24 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-05-22 15:34:24 +0000 |
commit | e7075db2a76425051b2ecfdd14f14b07384c7e08 (patch) | |
tree | ea8d3c314b96d33451aa0c67780505076c4845e7 /firmware/target/arm | |
parent | 213e7d847245f9ac61a64497424faeac0e22b4a2 (diff) |
e200: Use 16-16 L-R pairs when writing to the TX FIFO. Kill the channel swapping and clicks. Reduce number of FIQs. Should be adaptable to iPods and other PP targets in a few minutes work, eh?
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13463 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/i2s-pp.c | 60 | ||||
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 23 |
2 files changed, 67 insertions, 16 deletions
diff --git a/firmware/target/arm/i2s-pp.c b/firmware/target/arm/i2s-pp.c index a2a74bf72b..c63287b72b 100644 --- a/firmware/target/arm/i2s-pp.c +++ b/firmware/target/arm/i2s-pp.c @@ -46,20 +46,58 @@ void i2s_reset(void) } #else /* PP502X */ +/* All I2S formats send MSB first */ + /* Data format on the I2S bus */ -#define FORMAT_MASK (0x3 << 10) -#define FORMAT_I2S (0x00 << 10) -/* Other formats not yet known */ +#define FORMAT_MASK (0x3 << 10) +#define FORMAT_I2S (0x0 << 10) /* Standard I2S - leading dummy bit */ +#define FORMAT_1 (0x1 << 10) +#define FORMAT_LJUST (0x2 << 10) /* Left justified - no dummy bit */ +#define FORMAT_3 (0x3 << 10) +/* Other formats not yet known */ /* Data size on I2S bus */ #define SIZE_MASK (0x3 << 8) -#define SIZE_16BIT (0x00 << 10) +#define SIZE_16BIT (0x0 << 8) /* Other sizes not yet known */ /* Data size/format on I2S FIFO */ -#define FIFO_FORMAT_MASK (0x7 << 4) -#define FIFO_FORMAT_32LSB (0x03 << 4) -/* Other formats not yet known */ +#define FIFO_FORMAT_MASK (0x7 << 4) +#define 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 FIFO_FORMAT_1 (0x1 << 4) +#define FIFO_FORMAT_2 (0x2 << 4) + /* 32bit-MSB-little endian */ +#define FIFO_FORMAT_LE32 (0x3 << 4) + /* 16bit-MSB-little endian */ +#define FIFO_FORMAT_LE16 (0x4 << 4) + +/* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */ + +/** + * PP502x + * + * 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 | + * + * IISFIFO_CFG bits: + * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | + * | | Free[6:0] | + * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | + * | | | | | | | | | + * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | + * | | | | RXCLR | | | | TXCLR | + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * | | | RX_ATN_LEVEL | | | TX_ATN_LEVEL | + */ /* Are we I2S Master or slave? */ #define I2S_MASTER (1<<25) @@ -83,12 +121,16 @@ void i2s_reset(void) /* FIFO.FORMAT */ /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */ - IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_32LSB); #ifdef HAVE_AS3514 /* AS3514 can only operate as I2S Slave */ IISCONFIG |= I2S_MASTER; /* Set I2S to 44.1kHz */ - outl((inl(0x70002808) & ~(0x1ff)) | 271, 0x70002808); + outl((inl(0x70002808) & ~(0x1ff)) | 33, 0x70002808); + outl(7, 0x60006080); + + IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_LE16); +#else + IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_LE32); #endif /* RX_ATN_LVL=1 == when 12 slots full */ diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index e483700e88..41bd92bd0d 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c @@ -93,13 +93,7 @@ void fiq(void) "bls .fifo_full \n\t" /* FIFO full, exit */ "ldr r10, [r9], #4 \n\t" /* load two samples */ #ifdef HAVE_AS3514 - /* The AS3514 reads 3 bytes at a time, it seems, ignoring the lowest. - This code seems to work well, but we may have to mask off the extra - bits - at the expense of a few extra cycles in the FIQ */ - "mov r10, r10, ror #2\n\t" /* put left sample at the top bits */ - "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */ - "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */ - "str r10, [r12, #0x40]\n\t" /* then write it */ + "str r10, [r12, #0x40]\n\t" /* write them */ #else "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */ "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */ @@ -184,8 +178,13 @@ void fiq(void) return; } +#ifdef HAVE_AS3514 + IISFIFO_WR = *(int32_t *)p; + p += 2; +#else IISFIFO_WR = (*(p++))<<16; IISFIFO_WR = (*(p++))<<16; +#endif p_size-=4; } @@ -240,8 +239,13 @@ void pcm_play_dma_start(const void *addr, size_t size) return; } +#ifdef HAVE_AS3514 + IISFIFO_WR = *(int32_t *)p; + p += 2; +#else IISFIFO_WR = (*(p++))<<16; IISFIFO_WR = (*(p++))<<16; +#endif p_size-=4; } } @@ -315,8 +319,13 @@ void pcm_play_pause_unpause(void) return; } +#ifdef HAVE_AS3514 + IISFIFO_WR = *(int32_t *)p; + p += 2; +#else IISFIFO_WR = (*(p++))<<16; IISFIFO_WR = (*(p++))<<16; +#endif p_size-=4; } } |