diff options
-rw-r--r-- | firmware/export/pp5020.h | 14 | ||||
-rw-r--r-- | firmware/target/arm/i2s-pp.c | 7 | ||||
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 51 |
3 files changed, 56 insertions, 16 deletions
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index 981ab318c5..2f49c50bad 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h @@ -311,7 +311,9 @@ #define IISCONFIG (*(volatile unsigned long*)(0x70002800)) #define IISFIFO_CFG (*(volatile unsigned long*)(0x7000280c)) #define IISFIFO_WR (*(volatile unsigned long*)(0x70002840)) +#define IISFIFO_WRH (*(volatile unsigned short*)(0x70002840)) #define IISFIFO_RD (*(volatile unsigned long*)(0x70002880)) +#define IISFIFO_RDH (*(volatile unsigned short*)(0x70002880)) /** * IISCONFIG bits: @@ -350,16 +352,16 @@ /* 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) +#define IIS_FIFO_FORMAT_MASK (0x7 << 4) +#define IIS_FIFO_FORMAT_LE_HALFWORD (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) +#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) +#define IIS_FIFO_FORMAT_LE32 (0x3 << 4) /* 16bit-MSB-little endian */ -#define IIS_FIFO_FORMAT_LE16 (0x4 << 4) +#define IIS_FIFO_FORMAT_LE16 (0x4 << 4) /* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */ diff --git a/firmware/target/arm/i2s-pp.c b/firmware/target/arm/i2s-pp.c index 24d901a4c1..09170c818b 100644 --- a/firmware/target/arm/i2s-pp.c +++ b/firmware/target/arm/i2s-pp.c @@ -57,10 +57,9 @@ void i2s_reset(void) IISCONFIG &= ~IIS_RESET; /* BIT.FORMAT */ - IISCONFIG = ((IISCONFIG & ~IIS_FORMAT_MASK) | IIS_FORMAT_IIS); - - /* BIT.SIZE */ IISCONFIG = ((IISCONFIG & ~IIS_SIZE_MASK) | IIS_SIZE_16BIT); + /* BIT.SIZE */ + IISCONFIG = ((IISCONFIG & ~IIS_FORMAT_MASK) | IIS_FORMAT_IIS); /* FIFO.FORMAT */ /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */ @@ -71,6 +70,8 @@ void i2s_reset(void) outl((inl(0x70002808) & ~(0x1ff)) | 33, 0x70002808); outl(7, 0x60006080); IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE16); +#elif defined (IRIVER_H10) || defined (IRIVER_H10_5GB) + IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE_HALFWORD); #else IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE32); #endif diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index 50e5b272aa..119c54d71b 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c @@ -25,12 +25,22 @@ /** DMA **/ -#if defined(HAVE_AS3514) -/* E200 uses 16bit FIFO - all others should be able to as well - - i2s-pp.c has to set the right size as well */ -#define SAMPLE_SIZE 16 +/* List of transfer settings. Defined by player in order to have an inventory + of working settings. DMA-compatible settings should be found for here, i2s, + and codec setup using "arithmetic" the hardware supports like halfword + swapping. Try to use 32-bit packed in IIS modes if possible. */ +#if defined(SANSA_C200) || defined(SANSA_E200) +/* 16-bit, L-R packed into 32 bits with left in the least significant halfword */ +#define SAMPLE_SIZE 16 +#define TRANSFER_SIZE 32 +#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) +/* 16-bit, one left 16-bit sample followed by one right 16-bit sample */ +#define SAMPLE_SIZE 16 +#define TRANSFER_SIZE 16 #else -#define SAMPLE_SIZE 32 +/* 32-bit, one left 32-bit sample followed by one right 32-bit sample */ +#define SAMPLE_SIZE 32 +#define TRANSFER_SIZE 32 #endif struct dma_data @@ -38,7 +48,11 @@ struct dma_data /* NOTE: The order of size and p is important if you use assembler optimised fiq handler, so don't change it. */ #if SAMPLE_SIZE == 16 +#if TRANSFER_SIZE == 16 + uint16_t *p; +#elif TRANSFER_SIZE == 32 uint32_t *p; +#endif #elif SAMPLE_SIZE == 32 uint16_t *p; #endif @@ -122,10 +136,18 @@ void fiq_playback(void) "ldr r12, [r10, %[cfg]] \n" /* read IISFIFO_CFG to check FIFO status */ "ands r12, r12, %[mask] \n" "beq .exit \n" /* FIFO full, exit */ - "ldr r12, [r8], #4 \n" /* load two samples */ #if SAMPLE_SIZE == 16 +#if TRANSFER_SIZE == 16 + "ldrh r12, [r8], #2 \n" /* Load left channel */ + "strh r12, [r10, %[wr]] \n" /* Store it */ + "ldrh r12, [r8], #2 \n" /* Load right channel */ + "strh r12, [r10, %[wr]] \n" /* Store it */ +#elif TRANSFER_SIZE == 32 + "ldr r12, [r8], #4 \n" /* load two samples */ "str r12, [r10, %[wr]] \n" /* write them */ +#endif #elif SAMPLE_SIZE == 32 + "ldr r12, [r8], #4 \n" /* load two samples */ "mov r12, r12, ror #16 \n" /* put left sample at the top bits */ "str r12, [r10, %[wr]] \n" /* write top sample, lower sample ignored */ "mov r12, r12, lsl #16 \n" /* shift lower sample up */ @@ -181,7 +203,12 @@ void fiq_playback(void) return; } #if SAMPLE_SIZE == 16 - IISFIFO_WR = *dma_play_data.p++; +#if TRANSFER_SIZE == 16 + IISFIFO_WRH = *dma_play_data.p++; + IISFIFO_WRH = *dma_play_data.p++; +#elif TRANSFER_SIZE == 32 + IISFIFO_WR = *dma_play_data.p++; +#endif #elif SAMPLE_SIZE == 32 IISFIFO_WR = *dma_play_data.p++ << 16; IISFIFO_WR = *dma_play_data.p++ << 16; @@ -244,7 +271,12 @@ static void play_start_pcm(void) } #if SAMPLE_SIZE == 16 +#if TRANSFER_SIZE == 16 + IISFIFO_WRH = *dma_play_data.p++; + IISFIFO_WRH = *dma_play_data.p++; +#elif TRANSFER_SIZE == 32 IISFIFO_WR = *dma_play_data.p++; +#endif #elif SAMPLE_SIZE == 32 IISFIFO_WR = *dma_play_data.p++ << 16; IISFIFO_WR = *dma_play_data.p++ << 16; @@ -461,7 +493,12 @@ void fiq_record(void) } #if SAMPLE_SIZE == 16 +#if TRANSFER_SIZE == 16 + *dma_rec_data.p++ = IISFIFO_RDH; + *dma_rec_data.p++ = IISFIFO_RDH; +#elif TRANSFER_SIZE == 32 *dma_rec_data.p++ = IISFIFO_RD; +#endif #elif SAMPLE_SIZE == 32 *dma_rec_data.p++ = IISFIFO_RD >> 16; *dma_rec_data.p++ = IISFIFO_RD >> 16; |