summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/pp5020.h14
-rw-r--r--firmware/target/arm/i2s-pp.c7
-rw-r--r--firmware/target/arm/pcm-pp.c51
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 @@
311#define IISCONFIG (*(volatile unsigned long*)(0x70002800)) 311#define IISCONFIG (*(volatile unsigned long*)(0x70002800))
312#define IISFIFO_CFG (*(volatile unsigned long*)(0x7000280c)) 312#define IISFIFO_CFG (*(volatile unsigned long*)(0x7000280c))
313#define IISFIFO_WR (*(volatile unsigned long*)(0x70002840)) 313#define IISFIFO_WR (*(volatile unsigned long*)(0x70002840))
314#define IISFIFO_WRH (*(volatile unsigned short*)(0x70002840))
314#define IISFIFO_RD (*(volatile unsigned long*)(0x70002880)) 315#define IISFIFO_RD (*(volatile unsigned long*)(0x70002880))
316#define IISFIFO_RDH (*(volatile unsigned short*)(0x70002880))
315 317
316/** 318/**
317 * IISCONFIG bits: 319 * IISCONFIG bits:
@@ -350,16 +352,16 @@
350/* Other sizes not yet known */ 352/* Other sizes not yet known */
351 353
352/* Data size/format on IIS FIFO */ 354/* Data size/format on IIS FIFO */
353#define IIS_FIFO_FORMAT_MASK (0x7 << 4) 355#define IIS_FIFO_FORMAT_MASK (0x7 << 4)
354#define IIS_FIFO_FORMAT_0 (0x0 << 4) 356#define IIS_FIFO_FORMAT_LE_HALFWORD (0x0 << 4)
355/* Big-endian formats - data sent to the FIFO must be big endian. 357/* Big-endian formats - data sent to the FIFO must be big endian.
356 * I forgot which is which size but did test them. */ 358 * I forgot which is which size but did test them. */
357#define IIS_FIFO_FORMAT_1 (0x1 << 4) 359#define IIS_FIFO_FORMAT_1 (0x1 << 4)
358#define IIS_FIFO_FORMAT_2 (0x2 << 4) 360#define IIS_FIFO_FORMAT_2 (0x2 << 4)
359 /* 32bit-MSB-little endian */ 361 /* 32bit-MSB-little endian */
360#define IIS_FIFO_FORMAT_LE32 (0x3 << 4) 362#define IIS_FIFO_FORMAT_LE32 (0x3 << 4)
361 /* 16bit-MSB-little endian */ 363 /* 16bit-MSB-little endian */
362#define IIS_FIFO_FORMAT_LE16 (0x4 << 4) 364#define IIS_FIFO_FORMAT_LE16 (0x4 << 4)
363 365
364/* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */ 366/* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */
365 367
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)
57 IISCONFIG &= ~IIS_RESET; 57 IISCONFIG &= ~IIS_RESET;
58 58
59 /* BIT.FORMAT */ 59 /* BIT.FORMAT */
60 IISCONFIG = ((IISCONFIG & ~IIS_FORMAT_MASK) | IIS_FORMAT_IIS);
61
62 /* BIT.SIZE */
63 IISCONFIG = ((IISCONFIG & ~IIS_SIZE_MASK) | IIS_SIZE_16BIT); 60 IISCONFIG = ((IISCONFIG & ~IIS_SIZE_MASK) | IIS_SIZE_16BIT);
61 /* BIT.SIZE */
62 IISCONFIG = ((IISCONFIG & ~IIS_FORMAT_MASK) | IIS_FORMAT_IIS);
64 63
65 /* FIFO.FORMAT */ 64 /* FIFO.FORMAT */
66 /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */ 65 /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */
@@ -71,6 +70,8 @@ void i2s_reset(void)
71 outl((inl(0x70002808) & ~(0x1ff)) | 33, 0x70002808); 70 outl((inl(0x70002808) & ~(0x1ff)) | 33, 0x70002808);
72 outl(7, 0x60006080); 71 outl(7, 0x60006080);
73 IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE16); 72 IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE16);
73#elif defined (IRIVER_H10) || defined (IRIVER_H10_5GB)
74 IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE_HALFWORD);
74#else 75#else
75 IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE32); 76 IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE32);
76#endif 77#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 @@
25 25
26/** DMA **/ 26/** DMA **/
27 27
28#if defined(HAVE_AS3514) 28/* List of transfer settings. Defined by player in order to have an inventory
29/* E200 uses 16bit FIFO - all others should be able to as well - 29 of working settings. DMA-compatible settings should be found for here, i2s,
30 i2s-pp.c has to set the right size as well */ 30 and codec setup using "arithmetic" the hardware supports like halfword
31#define SAMPLE_SIZE 16 31 swapping. Try to use 32-bit packed in IIS modes if possible. */
32#if defined(SANSA_C200) || defined(SANSA_E200)
33/* 16-bit, L-R packed into 32 bits with left in the least significant halfword */
34#define SAMPLE_SIZE 16
35#define TRANSFER_SIZE 32
36#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
37/* 16-bit, one left 16-bit sample followed by one right 16-bit sample */
38#define SAMPLE_SIZE 16
39#define TRANSFER_SIZE 16
32#else 40#else
33#define SAMPLE_SIZE 32 41/* 32-bit, one left 32-bit sample followed by one right 32-bit sample */
42#define SAMPLE_SIZE 32
43#define TRANSFER_SIZE 32
34#endif 44#endif
35 45
36struct dma_data 46struct dma_data
@@ -38,7 +48,11 @@ struct dma_data
38/* NOTE: The order of size and p is important if you use assembler 48/* NOTE: The order of size and p is important if you use assembler
39 optimised fiq handler, so don't change it. */ 49 optimised fiq handler, so don't change it. */
40#if SAMPLE_SIZE == 16 50#if SAMPLE_SIZE == 16
51#if TRANSFER_SIZE == 16
52 uint16_t *p;
53#elif TRANSFER_SIZE == 32
41 uint32_t *p; 54 uint32_t *p;
55#endif
42#elif SAMPLE_SIZE == 32 56#elif SAMPLE_SIZE == 32
43 uint16_t *p; 57 uint16_t *p;
44#endif 58#endif
@@ -122,10 +136,18 @@ void fiq_playback(void)
122 "ldr r12, [r10, %[cfg]] \n" /* read IISFIFO_CFG to check FIFO status */ 136 "ldr r12, [r10, %[cfg]] \n" /* read IISFIFO_CFG to check FIFO status */
123 "ands r12, r12, %[mask] \n" 137 "ands r12, r12, %[mask] \n"
124 "beq .exit \n" /* FIFO full, exit */ 138 "beq .exit \n" /* FIFO full, exit */
125 "ldr r12, [r8], #4 \n" /* load two samples */
126#if SAMPLE_SIZE == 16 139#if SAMPLE_SIZE == 16
140#if TRANSFER_SIZE == 16
141 "ldrh r12, [r8], #2 \n" /* Load left channel */
142 "strh r12, [r10, %[wr]] \n" /* Store it */
143 "ldrh r12, [r8], #2 \n" /* Load right channel */
144 "strh r12, [r10, %[wr]] \n" /* Store it */
145#elif TRANSFER_SIZE == 32
146 "ldr r12, [r8], #4 \n" /* load two samples */
127 "str r12, [r10, %[wr]] \n" /* write them */ 147 "str r12, [r10, %[wr]] \n" /* write them */
148#endif
128#elif SAMPLE_SIZE == 32 149#elif SAMPLE_SIZE == 32
150 "ldr r12, [r8], #4 \n" /* load two samples */
129 "mov r12, r12, ror #16 \n" /* put left sample at the top bits */ 151 "mov r12, r12, ror #16 \n" /* put left sample at the top bits */
130 "str r12, [r10, %[wr]] \n" /* write top sample, lower sample ignored */ 152 "str r12, [r10, %[wr]] \n" /* write top sample, lower sample ignored */
131 "mov r12, r12, lsl #16 \n" /* shift lower sample up */ 153 "mov r12, r12, lsl #16 \n" /* shift lower sample up */
@@ -181,7 +203,12 @@ void fiq_playback(void)
181 return; 203 return;
182 } 204 }
183#if SAMPLE_SIZE == 16 205#if SAMPLE_SIZE == 16
184 IISFIFO_WR = *dma_play_data.p++; 206#if TRANSFER_SIZE == 16
207 IISFIFO_WRH = *dma_play_data.p++;
208 IISFIFO_WRH = *dma_play_data.p++;
209#elif TRANSFER_SIZE == 32
210 IISFIFO_WR = *dma_play_data.p++;
211#endif
185#elif SAMPLE_SIZE == 32 212#elif SAMPLE_SIZE == 32
186 IISFIFO_WR = *dma_play_data.p++ << 16; 213 IISFIFO_WR = *dma_play_data.p++ << 16;
187 IISFIFO_WR = *dma_play_data.p++ << 16; 214 IISFIFO_WR = *dma_play_data.p++ << 16;
@@ -244,7 +271,12 @@ static void play_start_pcm(void)
244 } 271 }
245 272
246#if SAMPLE_SIZE == 16 273#if SAMPLE_SIZE == 16
274#if TRANSFER_SIZE == 16
275 IISFIFO_WRH = *dma_play_data.p++;
276 IISFIFO_WRH = *dma_play_data.p++;
277#elif TRANSFER_SIZE == 32
247 IISFIFO_WR = *dma_play_data.p++; 278 IISFIFO_WR = *dma_play_data.p++;
279#endif
248#elif SAMPLE_SIZE == 32 280#elif SAMPLE_SIZE == 32
249 IISFIFO_WR = *dma_play_data.p++ << 16; 281 IISFIFO_WR = *dma_play_data.p++ << 16;
250 IISFIFO_WR = *dma_play_data.p++ << 16; 282 IISFIFO_WR = *dma_play_data.p++ << 16;
@@ -461,7 +493,12 @@ void fiq_record(void)
461 } 493 }
462 494
463#if SAMPLE_SIZE == 16 495#if SAMPLE_SIZE == 16
496#if TRANSFER_SIZE == 16
497 *dma_rec_data.p++ = IISFIFO_RDH;
498 *dma_rec_data.p++ = IISFIFO_RDH;
499#elif TRANSFER_SIZE == 32
464 *dma_rec_data.p++ = IISFIFO_RD; 500 *dma_rec_data.p++ = IISFIFO_RD;
501#endif
465#elif SAMPLE_SIZE == 32 502#elif SAMPLE_SIZE == 32
466 *dma_rec_data.p++ = IISFIFO_RD >> 16; 503 *dma_rec_data.p++ = IISFIFO_RD >> 16;
467 *dma_rec_data.p++ = IISFIFO_RD >> 16; 504 *dma_rec_data.p++ = IISFIFO_RD >> 16;