diff options
Diffstat (limited to 'firmware/pcm_record.c')
-rw-r--r-- | firmware/pcm_record.c | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c index 2d9c65a7e4..fee2bbd35b 100644 --- a/firmware/pcm_record.c +++ b/firmware/pcm_record.c | |||
@@ -31,7 +31,12 @@ | |||
31 | #include "cpu.h" | 31 | #include "cpu.h" |
32 | #include "i2c.h" | 32 | #include "i2c.h" |
33 | #include "power.h" | 33 | #include "power.h" |
34 | #ifdef HAVE_UDA1380 | ||
34 | #include "uda1380.h" | 35 | #include "uda1380.h" |
36 | #endif | ||
37 | #ifdef HAVE_TLV320 | ||
38 | #include "tlv320.h" | ||
39 | #endif | ||
35 | #include "system.h" | 40 | #include "system.h" |
36 | #include "usb.h" | 41 | #include "usb.h" |
37 | 42 | ||
@@ -51,14 +56,14 @@ extern int boost_counter; /* used for boost check */ | |||
51 | 56 | ||
52 | /***************************************************************************/ | 57 | /***************************************************************************/ |
53 | 58 | ||
54 | static volatile bool is_recording; /* We are recording */ | 59 | static bool is_recording; /* We are recording */ |
55 | static volatile bool is_stopping; /* Are we going to stop */ | 60 | static bool is_stopping; /* Are we going to stop */ |
56 | static volatile bool is_paused; /* We have paused */ | 61 | static bool is_paused; /* We have paused */ |
57 | static volatile bool is_error; /* An error has occured */ | 62 | static bool is_error; /* An error has occured */ |
58 | 63 | ||
59 | static volatile unsigned long num_rec_bytes; /* Num bytes recorded */ | 64 | static unsigned long num_rec_bytes; /* Num bytes recorded */ |
60 | static volatile unsigned long num_file_bytes; /* Num bytes written to current file */ | 65 | static unsigned long num_file_bytes; /* Num bytes written to current file */ |
61 | static volatile int error_count; /* Number of DMA errors */ | 66 | static int error_count; /* Number of DMA errors */ |
62 | 67 | ||
63 | static long record_start_time; /* Value of current_tick when recording was started */ | 68 | static long record_start_time; /* Value of current_tick when recording was started */ |
64 | static long pause_start_time; /* Value of current_tick when pause was started */ | 69 | static long pause_start_time; /* Value of current_tick when pause was started */ |
@@ -69,7 +74,7 @@ static int rec_source; /* Current recording source */ | |||
69 | static int wav_file; | 74 | static int wav_file; |
70 | static char recording_filename[MAX_PATH]; | 75 | static char recording_filename[MAX_PATH]; |
71 | 76 | ||
72 | static volatile bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done; | 77 | static bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done; |
73 | 78 | ||
74 | static short peak_left, peak_right; | 79 | static short peak_left, peak_right; |
75 | 80 | ||
@@ -90,16 +95,23 @@ static unsigned int rec_buffer_offset; | |||
90 | static unsigned char *rec_buffer; /* Circular recording buffer */ | 95 | static unsigned char *rec_buffer; /* Circular recording buffer */ |
91 | static int num_chunks; /* Number of chunks available in rec_buffer */ | 96 | static int num_chunks; /* Number of chunks available in rec_buffer */ |
92 | 97 | ||
93 | 98 | #ifdef IAUDIO_X5 | |
99 | #define SET_IIS_PLAY(x) IIS1CONFIG = (x); | ||
100 | #define SET_IIS_REC(x) IIS1CONFIG = (x); | ||
101 | #else | ||
102 | #define SET_IIS_PLAY(x) IIS2CONFIG = (x); | ||
103 | #define SET_IIS_REC(x) IIS1CONFIG = (x); | ||
104 | #endif | ||
105 | |||
94 | /* | 106 | /* |
95 | Overrun occures when DMA needs to write a new chunk and write_index == read_index | 107 | Overrun occures when DMA needs to write a new chunk and write_index == read_index |
96 | Solution to this is to optimize pcmrec_callback, use cpu_boost or save to disk | 108 | Solution to this is to optimize pcmrec_callback, use cpu_boost or save to disk |
97 | more often. | 109 | more often. |
98 | */ | 110 | */ |
99 | 111 | ||
100 | static volatile int write_index; /* Current chunk the DMA is writing to */ | 112 | static int write_index; /* Current chunk the DMA is writing to */ |
101 | static volatile int read_index; /* Oldest chunk that is not written to disk */ | 113 | static int read_index; /* Oldest chunk that is not written to disk */ |
102 | static volatile int read2_index; /* Latest chunk that has not been converted to little endian */ | 114 | static int read2_index; /* Latest chunk that has not been converted to little endian */ |
103 | static long pre_record_ticks; /* pre-record time expressed in ticks */ | 115 | static long pre_record_ticks; /* pre-record time expressed in ticks */ |
104 | static int pre_record_chunks; /* pre-record time expressed in chunks */ | 116 | static int pre_record_chunks; /* pre-record time expressed in chunks */ |
105 | 117 | ||
@@ -137,7 +149,7 @@ void pcm_rec_init(void) | |||
137 | 149 | ||
138 | 150 | ||
139 | /* Initializes recording: | 151 | /* Initializes recording: |
140 | * - Set up the UDA1380 for recording | 152 | * - Set up the UDA1380/TLV320 for recording |
141 | * - Prepare for DMA transfers | 153 | * - Prepare for DMA transfers |
142 | */ | 154 | */ |
143 | 155 | ||
@@ -292,14 +304,26 @@ void audio_set_recording_options(int frequency, int quality, | |||
292 | case 0: | 304 | case 0: |
293 | /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */ | 305 | /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */ |
294 | DATAINCONTROL = 0xc020; | 306 | DATAINCONTROL = 0xc020; |
307 | |||
308 | #ifdef HAVE_UDA1380 | ||
295 | uda1380_enable_recording(true); | 309 | uda1380_enable_recording(true); |
310 | #endif | ||
311 | #ifdef HAVE_TLV320 | ||
312 | tlv320_enable_recording(true); | ||
313 | #endif | ||
296 | break; | 314 | break; |
297 | 315 | ||
298 | /* line-in */ | 316 | /* line-in */ |
299 | case 1: | 317 | case 1: |
300 | /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */ | 318 | /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */ |
301 | DATAINCONTROL = 0xc020; | 319 | DATAINCONTROL = 0xc020; |
320 | |||
321 | #ifdef HAVE_UDA1380 | ||
302 | uda1380_enable_recording(false); | 322 | uda1380_enable_recording(false); |
323 | #endif | ||
324 | #ifdef HAVE_TLV320 | ||
325 | tlv320_enable_recording(false); | ||
326 | #endif | ||
303 | break; | 327 | break; |
304 | #ifdef HAVE_SPDIF_IN | 328 | #ifdef HAVE_SPDIF_IN |
305 | /* SPDIF */ | 329 | /* SPDIF */ |
@@ -322,7 +346,8 @@ void audio_set_recording_options(int frequency, int quality, | |||
322 | 346 | ||
323 | /* Monitoring: route the signals through the coldfire audio interface. */ | 347 | /* Monitoring: route the signals through the coldfire audio interface. */ |
324 | 348 | ||
325 | IIS2CONFIG = 0x800; /* Reset before reprogram */ | 349 | SET_IIS_PLAY(0x800); /* Reset before reprogram */ |
350 | |||
326 | #ifdef HAVE_SPDIF_IN | 351 | #ifdef HAVE_SPDIF_IN |
327 | if (source == 2) { | 352 | if (source == 2) { |
328 | /* SCLK2 = Audioclk/4 (can't use EBUin clock), TXSRC = EBU1rcv, 64 bclk/wclk */ | 353 | /* SCLK2 = Audioclk/4 (can't use EBUin clock), TXSRC = EBU1rcv, 64 bclk/wclk */ |
@@ -340,21 +365,27 @@ void audio_set_recording_options(int frequency, int quality, | |||
340 | } | 365 | } |
341 | #else | 366 | #else |
342 | /* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */ | 367 | /* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */ |
343 | IIS2CONFIG = (8 << 12) | (4 << 8) | (4 << 2); | 368 | SET_IIS_PLAY( (8 << 12) | (4 << 8) | (4 << 2) ); |
344 | #endif | 369 | #endif |
345 | } | 370 | } |
346 | 371 | ||
347 | 372 | ||
348 | /** | 373 | /** |
349 | * Note that microphone is mono, only left value is used | 374 | * Note that microphone is mono, only left value is used |
350 | * See uda1380_set_recvol() for exact ranges. | 375 | * See {uda1380,tlv320}_set_recvol() for exact ranges. |
351 | * | 376 | * |
352 | * @param type 0=line-in (radio), 1=mic | 377 | * @param type 0=line-in (radio), 1=mic |
353 | * | 378 | * |
354 | */ | 379 | */ |
355 | void audio_set_recording_gain(int left, int right, int type) | 380 | void audio_set_recording_gain(int left, int right, int type) |
356 | { | 381 | { |
382 | //logf("rcmrec: t=%d l=%d r=%d", type, left, right); | ||
383 | #ifdef HAVE_UDA1380 | ||
357 | uda1380_set_recvol(left, right, type); | 384 | uda1380_set_recvol(left, right, type); |
385 | #endif | ||
386 | #ifdef HAVE_TLV320 | ||
387 | tlv320_set_recvol(left, right, type); | ||
388 | #endif | ||
358 | } | 389 | } |
359 | 390 | ||
360 | 391 | ||
@@ -987,7 +1018,7 @@ static void pcmrec_init(void) | |||
987 | 1018 | ||
988 | logf("num_chunks: %d", num_chunks); | 1019 | logf("num_chunks: %d", num_chunks); |
989 | 1020 | ||
990 | IIS1CONFIG = 0x800; /* Stop any playback */ | 1021 | SET_IIS_PLAY(0x800); /* Stop any playback */ |
991 | AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */ | 1022 | AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */ |
992 | DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */ | 1023 | DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */ |
993 | 1024 | ||
@@ -1007,7 +1038,12 @@ static void pcmrec_init(void) | |||
1007 | 1038 | ||
1008 | static void pcmrec_close(void) | 1039 | static void pcmrec_close(void) |
1009 | { | 1040 | { |
1041 | #ifdef HAVE_UDA1380 | ||
1010 | uda1380_disable_recording(); | 1042 | uda1380_disable_recording(); |
1043 | #endif | ||
1044 | #ifdef HAVE_TLV320 | ||
1045 | tlv320_disable_recording(); | ||
1046 | #endif | ||
1011 | 1047 | ||
1012 | #ifdef HAVE_SPDIF_POWER | 1048 | #ifdef HAVE_SPDIF_POWER |
1013 | spdif_power_enable(spdif_power_setting); | 1049 | spdif_power_enable(spdif_power_setting); |
@@ -1091,7 +1127,7 @@ void pcm_rec_mux(int source) | |||
1091 | 1127 | ||
1092 | or_l(0x40000000, &GPIO_ENABLE); | 1128 | or_l(0x40000000, &GPIO_ENABLE); |
1093 | or_l(0x40000000, &GPIO_FUNCTION); | 1129 | or_l(0x40000000, &GPIO_FUNCTION); |
1094 | #else | 1130 | #elif defined(IRIVER_H100_SERIES) |
1095 | if(source == 0) | 1131 | if(source == 0) |
1096 | and_l(~0x00800000, &GPIO_OUT); /* Line In */ | 1132 | and_l(~0x00800000, &GPIO_OUT); /* Line In */ |
1097 | else | 1133 | else |
@@ -1099,5 +1135,16 @@ void pcm_rec_mux(int source) | |||
1099 | 1135 | ||
1100 | or_l(0x00800000, &GPIO_ENABLE); | 1136 | or_l(0x00800000, &GPIO_ENABLE); |
1101 | or_l(0x00800000, &GPIO_FUNCTION); | 1137 | or_l(0x00800000, &GPIO_FUNCTION); |
1138 | |||
1139 | #elif defined(IAUDIO_X5) | ||
1140 | if(source == 0) | ||
1141 | or_l((1<<29), &GPIO_OUT); /* Line In */ | ||
1142 | else | ||
1143 | and_l(~(1<<29), &GPIO_OUT); /* FM radio */ | ||
1144 | |||
1145 | or_l((1<<29), &GPIO_ENABLE); | ||
1146 | or_l((1<<29), &GPIO_FUNCTION); | ||
1147 | |||
1148 | /* iAudio x5 */ | ||
1102 | #endif | 1149 | #endif |
1103 | } | 1150 | } |