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 @@ | |||
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 | ||
36 | struct dma_data | 46 | struct 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; |