summaryrefslogtreecommitdiff
path: root/firmware/pcm_record.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/pcm_record.c')
-rw-r--r--firmware/pcm_record.c83
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
54static volatile bool is_recording; /* We are recording */ 59static bool is_recording; /* We are recording */
55static volatile bool is_stopping; /* Are we going to stop */ 60static bool is_stopping; /* Are we going to stop */
56static volatile bool is_paused; /* We have paused */ 61static bool is_paused; /* We have paused */
57static volatile bool is_error; /* An error has occured */ 62static bool is_error; /* An error has occured */
58 63
59static volatile unsigned long num_rec_bytes; /* Num bytes recorded */ 64static unsigned long num_rec_bytes; /* Num bytes recorded */
60static volatile unsigned long num_file_bytes; /* Num bytes written to current file */ 65static unsigned long num_file_bytes; /* Num bytes written to current file */
61static volatile int error_count; /* Number of DMA errors */ 66static int error_count; /* Number of DMA errors */
62 67
63static long record_start_time; /* Value of current_tick when recording was started */ 68static long record_start_time; /* Value of current_tick when recording was started */
64static long pause_start_time; /* Value of current_tick when pause was started */ 69static long pause_start_time; /* Value of current_tick when pause was started */
@@ -69,7 +74,7 @@ static int rec_source; /* Current recording source */
69static int wav_file; 74static int wav_file;
70static char recording_filename[MAX_PATH]; 75static char recording_filename[MAX_PATH];
71 76
72static volatile bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done; 77static bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done;
73 78
74static short peak_left, peak_right; 79static short peak_left, peak_right;
75 80
@@ -90,16 +95,23 @@ static unsigned int rec_buffer_offset;
90static unsigned char *rec_buffer; /* Circular recording buffer */ 95static unsigned char *rec_buffer; /* Circular recording buffer */
91static int num_chunks; /* Number of chunks available in rec_buffer */ 96static 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
100static volatile int write_index; /* Current chunk the DMA is writing to */ 112static int write_index; /* Current chunk the DMA is writing to */
101static volatile int read_index; /* Oldest chunk that is not written to disk */ 113static int read_index; /* Oldest chunk that is not written to disk */
102static volatile int read2_index; /* Latest chunk that has not been converted to little endian */ 114static int read2_index; /* Latest chunk that has not been converted to little endian */
103static long pre_record_ticks; /* pre-record time expressed in ticks */ 115static long pre_record_ticks; /* pre-record time expressed in ticks */
104static int pre_record_chunks; /* pre-record time expressed in chunks */ 116static 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 */
355void audio_set_recording_gain(int left, int right, int type) 380void 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
1008static void pcmrec_close(void) 1039static 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}