forked from len0rd/rockbox
iAudio: First unfinished attempt for tlv320 driver and rockbox integration
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7286 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
095854b989
commit
14e80671af
8 changed files with 441 additions and 142 deletions
|
@ -48,10 +48,14 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
#include "uda1380.h"
|
#include "uda1380.h"
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
#include "tlv320.h"
|
||||||
|
#endif
|
||||||
#include "pcm_record.h"
|
#include "pcm_record.h"
|
||||||
|
|
||||||
#ifdef HAVE_UDA1380
|
#if defined(HAVE_UDA1380) || defined(HAVE_TLV320)
|
||||||
|
|
||||||
bool pcm_rec_screen(void)
|
bool pcm_rec_screen(void)
|
||||||
{
|
{
|
||||||
|
@ -64,36 +68,45 @@ bool pcm_rec_screen(void)
|
||||||
int rec_time;
|
int rec_time;
|
||||||
int done, button;
|
int done, button;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
lcd_setfont(FONT_SYSFIXED);
|
lcd_setfont(FONT_SYSFIXED);
|
||||||
lcd_getstringsize("M", &w, &h);
|
lcd_getstringsize("M", &w, &h);
|
||||||
lcd_setmargins(global_settings.invert_cursor ? 0 : w, 8);
|
lcd_setmargins(global_settings.invert_cursor ? 0 : w, 8);
|
||||||
|
|
||||||
play_vol = 120;
|
play_vol = 120;
|
||||||
|
|
||||||
//cpu_boost(true);
|
//cpu_boost(true);
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_enable_output(true);
|
uda1380_enable_output(true);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_enable_output(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_set_master_vol(play_vol, play_vol);
|
uda1380_set_master_vol(play_vol, play_vol);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_set_headphone_vol(play_vol, play_vol);
|
||||||
|
#endif
|
||||||
|
|
||||||
rec_monitor = 0; // No record feedback
|
rec_monitor = 0; // No record feedback
|
||||||
rec_source = 1; // Mic
|
rec_source = 1; // Mic
|
||||||
rec_gain = 0; // 0-15
|
rec_gain = 0; // 0-15
|
||||||
rec_vol = 0; // 0-255
|
rec_vol = 0; // 0-255
|
||||||
rec_count = 0;
|
rec_count = 0;
|
||||||
rec_waveform = 0;
|
rec_waveform = 0;
|
||||||
|
|
||||||
pcm_open_recording();
|
pcm_open_recording();
|
||||||
pcm_set_recording_options(rec_source, rec_waveform);
|
pcm_set_recording_options(rec_source, rec_waveform);
|
||||||
pcm_set_recording_gain(rec_gain, rec_vol);
|
pcm_set_recording_gain(rec_gain, rec_vol);
|
||||||
|
|
||||||
//rec_create_directory();
|
//rec_create_directory();
|
||||||
|
|
||||||
done = 0;
|
done = 0;
|
||||||
while(!done)
|
while(!done)
|
||||||
{
|
{
|
||||||
line = 0;
|
line = 0;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "PlayVolume: %3d", play_vol);
|
snprintf(buf, sizeof(buf), "PlayVolume: %3d", play_vol);
|
||||||
lcd_puts(0,line++, buf);
|
lcd_puts(0,line++, buf);
|
||||||
snprintf(buf, sizeof(buf), "Gain : %2d Volume : %2d", rec_gain, rec_vol);
|
snprintf(buf, sizeof(buf), "Gain : %2d Volume : %2d", rec_gain, rec_vol);
|
||||||
|
@ -112,10 +125,10 @@ bool pcm_rec_screen(void)
|
||||||
snprintf(buf, sizeof(buf), "File : %s", filename);
|
snprintf(buf, sizeof(buf), "File : %s", filename);
|
||||||
lcd_puts(0,line++, buf);
|
lcd_puts(0,line++, buf);
|
||||||
snprintf(buf, sizeof(buf), "Time : %02d:%02d.%02d", rec_time/HZ/60, (rec_time/HZ)%60, rec_time%HZ);
|
snprintf(buf, sizeof(buf), "Time : %02d:%02d.%02d", rec_time/HZ/60, (rec_time/HZ)%60, rec_time%HZ);
|
||||||
lcd_puts(0,line++, buf);
|
lcd_puts(0,line++, buf);
|
||||||
|
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "MODE : Select source");
|
snprintf(buf, sizeof(buf), "MODE : Select source");
|
||||||
lcd_puts(0,line++, buf);
|
lcd_puts(0,line++, buf);
|
||||||
snprintf(buf, sizeof(buf), "UP/DOWN : Record volume");
|
snprintf(buf, sizeof(buf), "UP/DOWN : Record volume");
|
||||||
|
@ -127,10 +140,10 @@ bool pcm_rec_screen(void)
|
||||||
snprintf(buf, sizeof(buf), "RMT PLAY: Toggle waveform");
|
snprintf(buf, sizeof(buf), "RMT PLAY: Toggle waveform");
|
||||||
lcd_puts(0,line++, buf);
|
lcd_puts(0,line++, buf);
|
||||||
|
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
|
|
||||||
|
|
||||||
button = button_get_w_tmo(HZ/8);
|
button = button_get_w_tmo(HZ/8);
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
|
@ -142,14 +155,14 @@ bool pcm_rec_screen(void)
|
||||||
if (pcm_status() & AUDIO_STATUS_RECORD)
|
if (pcm_status() & AUDIO_STATUS_RECORD)
|
||||||
{
|
{
|
||||||
pcm_stop_recording();
|
pcm_stop_recording();
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
snprintf(filename, MAX_PATH, "/record-%0d.wav", rec_count++);
|
snprintf(filename, MAX_PATH, "/record-%0d.wav", rec_count++);
|
||||||
pcm_record(filename);
|
pcm_record(filename);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_ON:
|
case BUTTON_ON:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -162,7 +175,7 @@ bool pcm_rec_screen(void)
|
||||||
case BUTTON_RIGHT | BUTTON_REPEAT:
|
case BUTTON_RIGHT | BUTTON_REPEAT:
|
||||||
if (rec_gain < 15)
|
if (rec_gain < 15)
|
||||||
rec_gain++;
|
rec_gain++;
|
||||||
|
|
||||||
pcm_set_recording_gain(rec_gain, rec_vol);
|
pcm_set_recording_gain(rec_gain, rec_vol);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -170,20 +183,22 @@ bool pcm_rec_screen(void)
|
||||||
case BUTTON_LEFT | BUTTON_REPEAT:
|
case BUTTON_LEFT | BUTTON_REPEAT:
|
||||||
if (rec_gain > 0)
|
if (rec_gain > 0)
|
||||||
rec_gain--;
|
rec_gain--;
|
||||||
|
|
||||||
pcm_set_recording_gain(rec_gain, rec_vol);
|
pcm_set_recording_gain(rec_gain, rec_vol);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_RC_MENU:
|
case BUTTON_RC_MENU:
|
||||||
rec_monitor = 1 - rec_monitor;
|
rec_monitor = 1 - rec_monitor;
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_set_monitor(rec_monitor);
|
uda1380_set_monitor(rec_monitor);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_RC_ON:
|
case BUTTON_RC_ON:
|
||||||
rec_waveform = 1 - rec_waveform;
|
rec_waveform = 1 - rec_waveform;
|
||||||
pcm_set_recording_options(rec_source, rec_waveform);
|
pcm_set_recording_options(rec_source, rec_waveform);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_UP:
|
case BUTTON_UP:
|
||||||
case BUTTON_UP | BUTTON_REPEAT:
|
case BUTTON_UP | BUTTON_REPEAT:
|
||||||
if (rec_vol<255)
|
if (rec_vol<255)
|
||||||
|
@ -205,23 +220,29 @@ bool pcm_rec_screen(void)
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
pcm_stop_recording();
|
pcm_stop_recording();
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_enable_output(false);
|
uda1380_enable_output(false);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_enable_output(false);
|
||||||
|
#endif
|
||||||
default_event_handler(SYS_USB_CONNECTED);
|
default_event_handler(SYS_USB_CONNECTED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcm_stop_recording();
|
pcm_stop_recording();
|
||||||
pcm_close_recording();
|
pcm_close_recording();
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_enable_output(false);
|
uda1380_enable_output(false);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_enable_output(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,8 @@ drivers/lcd-h100-remote.c
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_UDA1380) && !defined(SIMULATOR)
|
#if defined(HAVE_UDA1380) && !defined(SIMULATOR)
|
||||||
drivers/uda1380.c
|
drivers/uda1380.c
|
||||||
|
#elif defined(HAVE_TLV320) && !defined(SIMULATOR)
|
||||||
|
drivers/tlv320.c
|
||||||
#endif
|
#endif
|
||||||
#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR)
|
#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR)
|
||||||
pcm_playback.c
|
pcm_playback.c
|
||||||
|
@ -133,7 +135,7 @@ pcm_playback.c
|
||||||
#if CONFIG_HWCODEC == MASNONE
|
#if CONFIG_HWCODEC == MASNONE
|
||||||
replaygain.c
|
replaygain.c
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_UDA1380) && !defined(SIMULATOR)
|
#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
|
||||||
pcm_record.c
|
pcm_record.c
|
||||||
#endif
|
#endif
|
||||||
sound.c
|
sound.c
|
||||||
|
|
223
firmware/drivers/tlv320.c
Normal file
223
firmware/drivers/tlv320.c
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 by Christian Gmeiner
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#include "lcd.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "power.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "sprintf.h"
|
||||||
|
#include "button.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "file.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#include "i2c-coldfire.h"
|
||||||
|
#include "tlv320.h"
|
||||||
|
|
||||||
|
/* local functions and definations */
|
||||||
|
#define TLV320_ADDR 0x34
|
||||||
|
|
||||||
|
struct tlv320_info
|
||||||
|
{
|
||||||
|
int vol_l;
|
||||||
|
int vol_r;
|
||||||
|
} tlv320;
|
||||||
|
|
||||||
|
/* Definition of a playback configuration to start with */
|
||||||
|
#define NUM_DEFAULT_REGS 10
|
||||||
|
unsigned tlv320_defaults[2*NUM_DEFAULT_REGS] =
|
||||||
|
{
|
||||||
|
REG_PC, PC_ON | PC_OSC | PC_CLK | PC_DAC | ~PC_OUT, /* do we need to enable osciliator and clock? */
|
||||||
|
REG_LLIV, LLIV_LIM, /* mute adc input */
|
||||||
|
REG_RLIV, RLIV_RIM, /* mute adc input */
|
||||||
|
REG_LHV, LHV_LHV(HEADPHONE_MUTE), /* mute headphone */
|
||||||
|
REG_RHV, RHV_RHV(HEADPHONE_MUTE), /* mute headphone */
|
||||||
|
REG_AAP, AAP_MICM, /* mute microphone */
|
||||||
|
REG_DAP, DAP_DEEMP_DIS, /* de-emphasis control: disabled */
|
||||||
|
REG_DAIF, DAIF_FOR_I2S | DAIF_IWL_24 | ~DAIF_MS, /* i2s with 24 bit data len and slave mode */
|
||||||
|
REG_SRC, 0, /* ToDo */
|
||||||
|
REG_DIA, DIA_ACT, /* activate digital interface */
|
||||||
|
};
|
||||||
|
unsigned tlv320_regs[0xf];
|
||||||
|
|
||||||
|
void tlv320_write_reg(unsigned reg, unsigned value)
|
||||||
|
{
|
||||||
|
unsigned data[3];
|
||||||
|
|
||||||
|
data[0] = TLV320_ADDR;
|
||||||
|
data[1] = reg << 1;
|
||||||
|
data[2] = value & 0xff;
|
||||||
|
|
||||||
|
if (i2c_write(1, data, 3) != 3)
|
||||||
|
{
|
||||||
|
DEBUGF("tlv320 error reg=0x%x", reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tlv320_regs[reg] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 0 if successful or -1 if some register failed */
|
||||||
|
void tlv320_set_regs()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
memset(tlv320_regs, 0, sizeof(tlv320_regs));
|
||||||
|
|
||||||
|
/* Initialize all registers */
|
||||||
|
for (i=0; i<NUM_DEFAULT_REGS; i++)
|
||||||
|
{
|
||||||
|
unsigned reg = tlv320_defaults[i*2+0];
|
||||||
|
unsigned value = tlv320_defaults[i*2+1];
|
||||||
|
|
||||||
|
tlv320_write_reg(reg, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* public functions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init our tlv with default values
|
||||||
|
*/
|
||||||
|
void tlv320_init()
|
||||||
|
{
|
||||||
|
tlv320_reset();
|
||||||
|
tlv320_set_regs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets tlv320 to default values
|
||||||
|
*/
|
||||||
|
void tlv320_reset()
|
||||||
|
{
|
||||||
|
tlv320_write_reg(REG_RR, RR_RESET):
|
||||||
|
}
|
||||||
|
|
||||||
|
void tlv320_enable_output(bool enable)
|
||||||
|
{
|
||||||
|
unsigned value = tlv320regs[REG_PC];
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
value |= PC_OUT;
|
||||||
|
else
|
||||||
|
value &= ~PC_OUT;
|
||||||
|
|
||||||
|
tlv320_write_reg(REG_PC, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets left and right headphone volume (127(max) to 48(muted))
|
||||||
|
*/
|
||||||
|
void tlv320_set_headphone_vol(int vol_l, int vol_r)
|
||||||
|
{
|
||||||
|
unsigned value_l = tlv320_regs[REG_LHV];
|
||||||
|
unsigned value_r = tlv320_regs[REG_RHV];
|
||||||
|
|
||||||
|
/* keep track of current setting */
|
||||||
|
tlv320.vol_l = vol_l;
|
||||||
|
tlv320.vol_r = vol_r;
|
||||||
|
|
||||||
|
/* set new values in local register holders */
|
||||||
|
value_l |= LHV_LHV(vol_l);
|
||||||
|
value_r |= LHV_LHV(vol_r);
|
||||||
|
|
||||||
|
/* update */
|
||||||
|
tlv320_write_reg(REG_LHV, value_l);
|
||||||
|
tlv320_write_reg(REG_RHV, value_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets left and right linein volume (31(max) to 0(muted))
|
||||||
|
*/
|
||||||
|
void tlv320_set_linein_vol(int vol_l, int vol_r)
|
||||||
|
{
|
||||||
|
unsigned value_l = tlv320regs[REG_LLIV];
|
||||||
|
unsigned value_r = tlv320regs[REG_RLIV];
|
||||||
|
|
||||||
|
value_l |= LLIV_LHV(vol_l);
|
||||||
|
value_r |= RLIV_RHV(vol_r);
|
||||||
|
|
||||||
|
tlv320_write_reg(REG_LLIV, value_l);
|
||||||
|
tlv320_write_reg(REG_RLIV, value_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mute (mute=true) or enable sound (mute=false)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void tlv320_mute(bool mute)
|
||||||
|
{
|
||||||
|
unsigned value_l = tlv320regs[REG_LHV];
|
||||||
|
unsigned value_r = tlv320regs[REG_RHV];
|
||||||
|
|
||||||
|
if (mute)
|
||||||
|
{
|
||||||
|
value_l |= LHV_LHV(HEADPHONE_MUTE);
|
||||||
|
value_r |= RHV_RHV(HEADPHONE_MUTE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value_l |= LHV_LHV(tlv320.vol_l);
|
||||||
|
value_r |= RHV_RHV(tlv320.vol_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
tlv320_write_reg(REG_LHV, value_r);
|
||||||
|
tlv320_write_reg(REG_RHV, value_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tlv320_close()
|
||||||
|
{
|
||||||
|
/* todo */
|
||||||
|
}
|
||||||
|
|
||||||
|
void tlv320_enable_recording(bool source_mic)
|
||||||
|
{
|
||||||
|
unsigned value_pc = tlv320regs[REG_PC];
|
||||||
|
unsigned value_aap = tlv320regs[REG_AAP];
|
||||||
|
|
||||||
|
/* select source*/
|
||||||
|
if (source_mic)
|
||||||
|
{
|
||||||
|
value_aap &= ~AAP_INSEL;
|
||||||
|
value_pc |= PC_MIC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value_aap |= AAP_INSEL;
|
||||||
|
value_pc |= PC_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* poweron adc */
|
||||||
|
value_pc |= PC_ADC;
|
||||||
|
|
||||||
|
tlv320_write_reg(REG_AAP, value_aap);
|
||||||
|
tlv320_write_reg(REG_PC, value_pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tlv320_disable_recording()
|
||||||
|
{
|
||||||
|
unsigned value = tlv320regs[REG_PC];
|
||||||
|
|
||||||
|
/* powerdown mic, linein and adc */
|
||||||
|
value &= ~(PC_MIC | PC_LINE | PC_ADC);
|
||||||
|
|
||||||
|
/* powerdown mic, linein and adc */
|
||||||
|
tlv320_write_reg(REG_PC, value);
|
||||||
|
}
|
|
@ -22,10 +22,15 @@
|
||||||
|
|
||||||
/*** definitions ***/
|
/*** definitions ***/
|
||||||
|
|
||||||
extern void tlv320_reset(void);
|
extern void tlv320_init();
|
||||||
extern int tlv320_init(void);
|
extern void tlv320_reset();
|
||||||
extern int tlv320_set_headphone_vol(int vol_l, int vol_r);
|
extern void tlv320_enable_output(bool enable);
|
||||||
extern int tlv320_mute(bool mute);
|
extern void tlv320_set_headphone_vol(int vol_l, int vol_r);
|
||||||
|
extern void tlv320_set_linein_vol(int vol_l, int vol_r);
|
||||||
|
extern void tlv320_mute(bool mute);
|
||||||
|
extern void tlv320_close();
|
||||||
|
extern void tlv320_enable_recording(bool source_mic);
|
||||||
|
extern void tlv320_disable_recording();
|
||||||
|
|
||||||
#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */
|
#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */
|
||||||
|
|
||||||
|
@ -35,8 +40,8 @@ extern int tlv320_mute(bool mute);
|
||||||
/* REG_LLIV: Left line input channel volume control */
|
/* REG_LLIV: Left line input channel volume control */
|
||||||
#define REG_LLIV 0x0
|
#define REG_LLIV 0x0
|
||||||
#define LLIV_LRS (0 << 8) /* simultaneous volume/mute update */
|
#define LLIV_LRS (0 << 8) /* simultaneous volume/mute update */
|
||||||
#define LIM (1 << 7) /* Left line input mute */
|
#define LLIV_LIM (1 << 7) /* Left line input mute */
|
||||||
#define LIV ((x) & 0x1f)/* Left line input volume control */
|
#define LLIV_LIV ((x) & 0x1f)/* Left line input volume control */
|
||||||
|
|
||||||
/* REG_RLIV: Right line input channel volume control */
|
/* REG_RLIV: Right line input channel volume control */
|
||||||
#define REG_RLIV 0x1
|
#define REG_RLIV 0x1
|
||||||
|
@ -75,7 +80,7 @@ extern int tlv320_mute(bool mute);
|
||||||
|
|
||||||
/* REG_PC: Power Down Control */
|
/* REG_PC: Power Down Control */
|
||||||
#define REG_PC 0x6
|
#define REG_PC 0x6
|
||||||
#define PC_OFF (0 << 7) /* Device power */
|
#define PC_ON (0 << 7) /* Device power */
|
||||||
#define PC_CLK (0 << 6) /* Clock */
|
#define PC_CLK (0 << 6) /* Clock */
|
||||||
#define PC_OSC (0 << 5) /* Oscillator */
|
#define PC_OSC (0 << 5) /* Oscillator */
|
||||||
#define PC_OUT (0 << 4) /* Outputs */
|
#define PC_OUT (0 << 4) /* Outputs */
|
||||||
|
|
|
@ -24,7 +24,11 @@
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
#include "uda1380.h"
|
#include "uda1380.h"
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
#include "tlv320.h"
|
||||||
|
#endif
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#endif
|
#endif
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
|
@ -181,13 +185,18 @@ void pcm_play_data(void (*get_more)(unsigned char** start, long* size))
|
||||||
{
|
{
|
||||||
unsigned char *start;
|
unsigned char *start;
|
||||||
long size;
|
long size;
|
||||||
|
|
||||||
callback_for_more = get_more;
|
callback_for_more = get_more;
|
||||||
|
|
||||||
get_more((unsigned char **)&start, (long *)&size);
|
get_more((unsigned char **)&start, (long *)&size);
|
||||||
get_more(&next_start, &next_size);
|
get_more(&next_start, &next_size);
|
||||||
dma_start(start, size);
|
dma_start(start, size);
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_mute(false);
|
uda1380_mute(false);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_mute(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
long pcm_get_bytes_waiting(void)
|
long pcm_get_bytes_waiting(void)
|
||||||
|
@ -198,7 +207,12 @@ long pcm_get_bytes_waiting(void)
|
||||||
void pcm_play_stop(void)
|
void pcm_play_stop(void)
|
||||||
{
|
{
|
||||||
if (pcm_playing) {
|
if (pcm_playing) {
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_mute(true);
|
uda1380_mute(true);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_mute(true);
|
||||||
|
#endif
|
||||||
dma_stop();
|
dma_stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,14 +230,23 @@ void pcm_play_pause(bool play)
|
||||||
IIS2CONFIG = (pcm_freq << 12) | 0x300 | 4 << 2;
|
IIS2CONFIG = (pcm_freq << 12) | 0x300 | 4 << 2;
|
||||||
EBU1CONFIG = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2);
|
EBU1CONFIG = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2);
|
||||||
DCR0 |= DMA_EEXT | DMA_START;
|
DCR0 |= DMA_EEXT | DMA_START;
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_mute(false);
|
uda1380_mute(false);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_mute(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if(!pcm_paused && !play)
|
else if(!pcm_paused && !play)
|
||||||
{
|
{
|
||||||
logf("pause");
|
logf("pause");
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_mute(true);
|
uda1380_mute(true);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_mute(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Disable DMA peripheral request. */
|
/* Disable DMA peripheral request. */
|
||||||
DCR0 &= ~DMA_EEXT;
|
DCR0 &= ~DMA_EEXT;
|
||||||
IIS2CONFIG = 0x800;
|
IIS2CONFIG = 0x800;
|
||||||
|
@ -250,7 +273,7 @@ void DMA0(void)
|
||||||
|
|
||||||
DSR0 = 1; /* Clear interrupt */
|
DSR0 = 1; /* Clear interrupt */
|
||||||
DCR0 &= ~DMA_EEXT;
|
DCR0 &= ~DMA_EEXT;
|
||||||
|
|
||||||
/* Stop on error */
|
/* Stop on error */
|
||||||
if(res & 0x70)
|
if(res & 0x70)
|
||||||
{
|
{
|
||||||
|
@ -274,7 +297,7 @@ void DMA0(void)
|
||||||
logf("DMA No Data:0x%04x", res);
|
logf("DMA No Data:0x%04x", res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPR |= (1<<14); /* Clear pending interrupt request */
|
IPR |= (1<<14); /* Clear pending interrupt request */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,8 +305,12 @@ void pcm_init(void)
|
||||||
{
|
{
|
||||||
pcm_playing = false;
|
pcm_playing = false;
|
||||||
pcm_paused = false;
|
pcm_paused = false;
|
||||||
|
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_init();
|
uda1380_init();
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */
|
BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */
|
||||||
DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
|
DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
|
||||||
|
@ -292,18 +319,25 @@ void pcm_init(void)
|
||||||
|
|
||||||
/* Reset the audio FIFO */
|
/* Reset the audio FIFO */
|
||||||
IIS2CONFIG = 0x800;
|
IIS2CONFIG = 0x800;
|
||||||
|
|
||||||
/* Enable interrupt at level 7, priority 0 */
|
/* Enable interrupt at level 7, priority 0 */
|
||||||
ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00;
|
ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00;
|
||||||
IMR &= ~(1<<14); /* bit 14 is DMA0 */
|
IMR &= ~(1<<14); /* bit 14 is DMA0 */
|
||||||
|
|
||||||
pcm_set_frequency(44100);
|
pcm_set_frequency(44100);
|
||||||
|
|
||||||
/* Turn on headphone power with audio output muted. */
|
/* Turn on headphone power with audio output muted. */
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_mute(true);
|
uda1380_mute(true);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_mute(true);
|
||||||
|
#endif
|
||||||
sleep(HZ/4);
|
sleep(HZ/4);
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_enable_output(true);
|
uda1380_enable_output(true);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_enable_output(true);
|
||||||
|
#endif
|
||||||
/* Call dma_stop to initialize everything. */
|
/* Call dma_stop to initialize everything. */
|
||||||
dma_stop();
|
dma_stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
#include "uda1380.h"
|
#include "uda1380.h"
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
#include "tlv320.h"
|
||||||
|
#endif
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
|
@ -61,7 +65,7 @@ static unsigned long record_start_time; /* Value of current_tick when re
|
||||||
static unsigned long pause_start_time; /* Value of current_tick when pause was started */
|
static unsigned long pause_start_time; /* Value of current_tick when pause was started */
|
||||||
|
|
||||||
static int rec_gain, rec_volume;
|
static int rec_gain, rec_volume;
|
||||||
static bool show_waveform;
|
static bool show_waveform;
|
||||||
static int init_done = 0;
|
static int init_done = 0;
|
||||||
static int wav_file;
|
static int wav_file;
|
||||||
static char recording_filename[MAX_PATH];
|
static char recording_filename[MAX_PATH];
|
||||||
|
@ -72,12 +76,12 @@ static char recording_filename[MAX_PATH];
|
||||||
Some estimates:
|
Some estimates:
|
||||||
44100 HZ * 4 = 176400 bytes/s
|
44100 HZ * 4 = 176400 bytes/s
|
||||||
Refresh LCD 10 HZ = 176400 / 10 = 17640 bytes ~=~ 1024*16 bytes
|
Refresh LCD 10 HZ = 176400 / 10 = 17640 bytes ~=~ 1024*16 bytes
|
||||||
|
|
||||||
If NUM_BUFFERS is 80 we can hold ~8 sec of data in memory
|
If NUM_BUFFERS is 80 we can hold ~8 sec of data in memory
|
||||||
ALL_BUFFER_SIZE will be 1024*16 * 80 = 1310720 bytes
|
ALL_BUFFER_SIZE will be 1024*16 * 80 = 1310720 bytes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NUM_BUFFERS 80
|
#define NUM_BUFFERS 80
|
||||||
#define EACH_BUFFER_SIZE (1024*16) /* Multiple of 4. Use small value to get responsive waveform */
|
#define EACH_BUFFER_SIZE (1024*16) /* Multiple of 4. Use small value to get responsive waveform */
|
||||||
#define ALL_BUFFERS_SIZE (NUM_BUFFERS * EACH_BUFFER_SIZE)
|
#define ALL_BUFFERS_SIZE (NUM_BUFFERS * EACH_BUFFER_SIZE)
|
||||||
|
|
||||||
|
@ -130,7 +134,7 @@ void pcm_init_recording(void)
|
||||||
wav_file = -1;
|
wav_file = -1;
|
||||||
read_index = 0;
|
read_index = 0;
|
||||||
write_index = 0;
|
write_index = 0;
|
||||||
|
|
||||||
queue_init(&pcmrec_queue);
|
queue_init(&pcmrec_queue);
|
||||||
create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), pcmrec_thread_name);
|
create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), pcmrec_thread_name);
|
||||||
}
|
}
|
||||||
|
@ -138,16 +142,16 @@ void pcm_init_recording(void)
|
||||||
void pcm_open_recording(void)
|
void pcm_open_recording(void)
|
||||||
{
|
{
|
||||||
init_done = 0;
|
init_done = 0;
|
||||||
|
|
||||||
logf("pcm_open_rec");
|
logf("pcm_open_rec");
|
||||||
|
|
||||||
queue_post(&pcmrec_queue, PCMREC_OPEN, 0);
|
queue_post(&pcmrec_queue, PCMREC_OPEN, 0);
|
||||||
|
|
||||||
while (init_done)
|
while (init_done)
|
||||||
{
|
{
|
||||||
sleep(HZ >> 8);
|
sleep(HZ >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
logf("pcm_open_rec done");
|
logf("pcm_open_rec done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +166,10 @@ void pcm_close_recording(void)
|
||||||
unsigned long pcm_status(void)
|
unsigned long pcm_status(void)
|
||||||
{
|
{
|
||||||
unsigned long ret = 0;
|
unsigned long ret = 0;
|
||||||
|
|
||||||
if (is_recording)
|
if (is_recording)
|
||||||
ret |= AUDIO_STATUS_RECORD;
|
ret |= AUDIO_STATUS_RECORD;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +197,7 @@ unsigned long pcm_recorded_time(void)
|
||||||
|
|
||||||
unsigned long pcm_num_recorded_bytes(void)
|
unsigned long pcm_num_recorded_bytes(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (is_recording)
|
if (is_recording)
|
||||||
{
|
{
|
||||||
return num_rec_bytes;
|
return num_rec_bytes;
|
||||||
|
@ -222,10 +226,12 @@ void pcm_resume_recording(void)
|
||||||
*/
|
*/
|
||||||
void pcm_set_recording_options(int source, bool enable_waveform)
|
void pcm_set_recording_options(int source, bool enable_waveform)
|
||||||
{
|
{
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_enable_recording(source);
|
uda1380_enable_recording(source);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_enable_recording(source);
|
||||||
|
#endif
|
||||||
show_waveform = enable_waveform;
|
show_waveform = enable_waveform;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,21 +244,20 @@ void pcm_set_recording_gain(int gain, int volume)
|
||||||
{
|
{
|
||||||
rec_gain = gain;
|
rec_gain = gain;
|
||||||
rec_volume = volume;
|
rec_volume = volume;
|
||||||
|
|
||||||
queue_post(&pcmrec_queue, PCMREC_SET_GAIN, 0);
|
queue_post(&pcmrec_queue, PCMREC_SET_GAIN, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start recording
|
* Start recording
|
||||||
*
|
*
|
||||||
* Use pcm_set_recording_options before calling record
|
* Use pcm_set_recording_options before calling record
|
||||||
*/
|
*/
|
||||||
void pcm_record(const char *filename)
|
void pcm_record(const char *filename)
|
||||||
{
|
{
|
||||||
strncpy(recording_filename, filename, MAX_PATH - 1);
|
strncpy(recording_filename, filename, MAX_PATH - 1);
|
||||||
recording_filename[MAX_PATH - 1] = 0;
|
recording_filename[MAX_PATH - 1] = 0;
|
||||||
|
|
||||||
queue_post(&pcmrec_queue, PCMREC_START, 0);
|
queue_post(&pcmrec_queue, PCMREC_START, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,19 +268,17 @@ void pcm_stop_recording(void)
|
||||||
{
|
{
|
||||||
if (is_recording)
|
if (is_recording)
|
||||||
is_stopping = 1;
|
is_stopping = 1;
|
||||||
|
|
||||||
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
|
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
|
||||||
|
|
||||||
logf("pcm_stop_recording");
|
logf("pcm_stop_recording");
|
||||||
|
|
||||||
while (is_stopping)
|
while (is_stopping)
|
||||||
{
|
{
|
||||||
sleep(HZ >> 4);
|
sleep(HZ >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
logf("pcm_stop_recording done");
|
logf("pcm_stop_recording done");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,40 +306,40 @@ void pcmrec_callback(bool flush)
|
||||||
num_ready += NUM_BUFFERS;
|
num_ready += NUM_BUFFERS;
|
||||||
|
|
||||||
/* we can consume up to num_ready buffers */
|
/* we can consume up to num_ready buffers */
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_LCD
|
#ifdef HAVE_REMOTE_LCD
|
||||||
/* Draw waveform on remote LCD */
|
/* Draw waveform on remote LCD */
|
||||||
if (show_waveform && num_ready>0)
|
if (show_waveform && num_ready>0)
|
||||||
{
|
{
|
||||||
short *buf;
|
short *buf;
|
||||||
long x,y,offset;
|
long x,y,offset;
|
||||||
int show_index;
|
int show_index;
|
||||||
|
|
||||||
/* Just display the last buffer (most recent one) */
|
/* Just display the last buffer (most recent one) */
|
||||||
show_index = read_index + num_ready - 1;
|
show_index = read_index + num_ready - 1;
|
||||||
buf = (short*)rec_buffers[show_index];
|
buf = (short*)rec_buffers[show_index];
|
||||||
|
|
||||||
lcd_remote_clear_display();
|
lcd_remote_clear_display();
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for (x=0; x<LCD_REMOTE_WIDTH-1; x++)
|
for (x=0; x<LCD_REMOTE_WIDTH-1; x++)
|
||||||
{
|
{
|
||||||
y = buf[offset] * (LCD_REMOTE_HEIGHT / 2) *5; /* The 5 is just 'zooming' */
|
y = buf[offset] * (LCD_REMOTE_HEIGHT / 2) *5; /* The 5 is just 'zooming' */
|
||||||
y = y >> 15; /* Divide with SHRT_MAX */
|
y = y >> 15; /* Divide with SHRT_MAX */
|
||||||
y += LCD_REMOTE_HEIGHT/2;
|
y += LCD_REMOTE_HEIGHT/2;
|
||||||
|
|
||||||
if (y < 2) y=2;
|
if (y < 2) y=2;
|
||||||
if (y >= LCD_REMOTE_HEIGHT-2) y = LCD_REMOTE_HEIGHT-2;
|
if (y >= LCD_REMOTE_HEIGHT-2) y = LCD_REMOTE_HEIGHT-2;
|
||||||
|
|
||||||
lcd_remote_drawpixel(x,y);
|
lcd_remote_drawpixel(x,y);
|
||||||
|
|
||||||
offset += (EACH_BUFFER_SIZE/2) / LCD_REMOTE_WIDTH;
|
offset += (EACH_BUFFER_SIZE/2) / LCD_REMOTE_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_remote_update();
|
lcd_remote_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Note: This might be a good place to call the 'codec' later */
|
/* Note: This might be a good place to call the 'codec' later */
|
||||||
|
|
||||||
|
@ -348,43 +351,41 @@ void pcmrec_callback(bool flush)
|
||||||
{
|
{
|
||||||
unsigned long *ptr = (unsigned long*)rec_buffers[read_index];
|
unsigned long *ptr = (unsigned long*)rec_buffers[read_index];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<EACH_BUFFER_SIZE * num_ready / 4; i++)
|
for (i=0; i<EACH_BUFFER_SIZE * num_ready / 4; i++)
|
||||||
{
|
{
|
||||||
*ptr = SWAB32(*ptr);
|
*ptr = SWAB32(*ptr);
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
write(wav_file, rec_buffers[read_index], EACH_BUFFER_SIZE * num_ready);
|
write(wav_file, rec_buffers[read_index], EACH_BUFFER_SIZE * num_ready);
|
||||||
|
|
||||||
read_index+=num_ready;
|
read_index+=num_ready;
|
||||||
if (read_index >= NUM_BUFFERS)
|
if (read_index >= NUM_BUFFERS)
|
||||||
read_index -= NUM_BUFFERS;
|
read_index -= NUM_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
/* In this case we must consume the buffers otherwise we will */
|
/* In this case we must consume the buffers otherwise we will */
|
||||||
/* get 'dma1 overrun' pretty fast */
|
/* get 'dma1 overrun' pretty fast */
|
||||||
|
|
||||||
read_index+=num_ready;
|
read_index+=num_ready;
|
||||||
if (read_index >= NUM_BUFFERS)
|
if (read_index >= NUM_BUFFERS)
|
||||||
read_index -= NUM_BUFFERS;
|
read_index -= NUM_BUFFERS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void pcmrec_dma_start(void)
|
void pcmrec_dma_start(void)
|
||||||
{
|
{
|
||||||
DAR1 = (unsigned long)rec_buffers[write_index++]; /* Destination address */
|
DAR1 = (unsigned long)rec_buffers[write_index++]; /* Destination address */
|
||||||
SAR1 = (unsigned long)&PDIR2; /* Source address */
|
SAR1 = (unsigned long)&PDIR2; /* Source address */
|
||||||
BCR1 = EACH_BUFFER_SIZE; /* Bytes to transfer */
|
BCR1 = EACH_BUFFER_SIZE; /* Bytes to transfer */
|
||||||
|
|
||||||
/* Start the DMA transfer.. */
|
/* Start the DMA transfer.. */
|
||||||
DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
|
DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
|
||||||
|
|
||||||
logf("dma1 started");
|
logf("dma1 started");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +397,7 @@ void DMA1(void)
|
||||||
int res = DSR1;
|
int res = DSR1;
|
||||||
|
|
||||||
DSR1 = 1; /* Clear interrupt */
|
DSR1 = 1; /* Clear interrupt */
|
||||||
|
|
||||||
int_count++;
|
int_count++;
|
||||||
|
|
||||||
if (res & 0x70)
|
if (res & 0x70)
|
||||||
|
@ -404,41 +405,41 @@ void DMA1(void)
|
||||||
DCR1 = 0; /* Stop DMA transfer */
|
DCR1 = 0; /* Stop DMA transfer */
|
||||||
error_count++;
|
error_count++;
|
||||||
is_recording = 0;
|
is_recording = 0;
|
||||||
|
|
||||||
logf("dma1 err 0x%x", res);
|
logf("dma1 err 0x%x", res);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
num_rec_bytes += EACH_BUFFER_SIZE;
|
num_rec_bytes += EACH_BUFFER_SIZE;
|
||||||
|
|
||||||
write_index++;
|
write_index++;
|
||||||
if (write_index >= NUM_BUFFERS)
|
if (write_index >= NUM_BUFFERS)
|
||||||
write_index = 0;
|
write_index = 0;
|
||||||
|
|
||||||
if (is_stopping || !is_recording)
|
if (is_stopping || !is_recording)
|
||||||
{
|
{
|
||||||
DCR1 = 0; /* Stop DMA transfer */
|
DCR1 = 0; /* Stop DMA transfer */
|
||||||
is_recording = 0;
|
is_recording = 0;
|
||||||
|
|
||||||
logf("dma1 stopping");
|
logf("dma1 stopping");
|
||||||
|
|
||||||
} else if (write_index == read_index)
|
} else if (write_index == read_index)
|
||||||
{
|
{
|
||||||
DCR1 = 0; /* Stop DMA transfer */
|
DCR1 = 0; /* Stop DMA transfer */
|
||||||
is_recording = 0;
|
is_recording = 0;
|
||||||
|
|
||||||
logf("dma1 overrun");
|
logf("dma1 overrun");
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
DAR1 = (unsigned long)rec_buffers[write_index]; /* Destination address */
|
DAR1 = (unsigned long)rec_buffers[write_index]; /* Destination address */
|
||||||
BCR1 = EACH_BUFFER_SIZE;
|
BCR1 = EACH_BUFFER_SIZE;
|
||||||
|
|
||||||
queue_post(&pcmrec_queue, PCMREC_GOT_DATA, NULL);
|
queue_post(&pcmrec_queue, PCMREC_GOT_DATA, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPR |= (1<<15); /* Clear pending interrupt request */
|
IPR |= (1<<15); /* Clear pending interrupt request */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +451,7 @@ static int start_wave(void)
|
||||||
0x10,0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,
|
0x10,0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,
|
||||||
4,0,0x10,0,'d','a','t','a',0,0,0,0
|
4,0,0x10,0,'d','a','t','a',0,0,0,0
|
||||||
};
|
};
|
||||||
|
|
||||||
wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
|
wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
|
||||||
if (wav_file < 0)
|
if (wav_file < 0)
|
||||||
{
|
{
|
||||||
|
@ -458,7 +459,7 @@ static int start_wave(void)
|
||||||
logf("create failed: %d", wav_file);
|
logf("create failed: %d", wav_file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeof(header) != write(wav_file, header, sizeof(header)))
|
if (sizeof(header) != write(wav_file, header, sizeof(header)))
|
||||||
{
|
{
|
||||||
close(wav_file);
|
close(wav_file);
|
||||||
|
@ -466,7 +467,7 @@ static int start_wave(void)
|
||||||
logf("write failed");
|
logf("write failed");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,15 +475,15 @@ static int start_wave(void)
|
||||||
static void close_wave(void)
|
static void close_wave(void)
|
||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
l = SWAB32(num_rec_bytes + 36);
|
l = SWAB32(num_rec_bytes + 36);
|
||||||
lseek(wav_file, 4, SEEK_SET);
|
lseek(wav_file, 4, SEEK_SET);
|
||||||
write(wav_file, &l, 4);
|
write(wav_file, &l, 4);
|
||||||
|
|
||||||
l = SWAB32(num_rec_bytes);
|
l = SWAB32(num_rec_bytes);
|
||||||
lseek(wav_file, 40, SEEK_SET);
|
lseek(wav_file, 40, SEEK_SET);
|
||||||
write(wav_file, &l, 4);
|
write(wav_file, &l, 4);
|
||||||
|
|
||||||
close(wav_file);
|
close(wav_file);
|
||||||
wav_file = -1;
|
wav_file = -1;
|
||||||
}
|
}
|
||||||
|
@ -490,19 +491,19 @@ static void close_wave(void)
|
||||||
static void pcmrec_start(void)
|
static void pcmrec_start(void)
|
||||||
{
|
{
|
||||||
logf("pcmrec_start");
|
logf("pcmrec_start");
|
||||||
|
|
||||||
if (is_recording)
|
if (is_recording)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wav_file != -1)
|
if (wav_file != -1)
|
||||||
close(wav_file);
|
close(wav_file);
|
||||||
|
|
||||||
logf("rec: %s", recording_filename);
|
logf("rec: %s", recording_filename);
|
||||||
|
|
||||||
start_wave(); /* todo: send signal to pcm_record if we have failed */
|
start_wave(); /* todo: send signal to pcm_record if we have failed */
|
||||||
|
|
||||||
num_rec_bytes = 0;
|
num_rec_bytes = 0;
|
||||||
|
|
||||||
/* Store the current time */
|
/* Store the current time */
|
||||||
record_start_time = current_tick;
|
record_start_time = current_tick;
|
||||||
|
|
||||||
|
@ -514,29 +515,29 @@ static void pcmrec_start(void)
|
||||||
is_recording = 1;
|
is_recording = 1;
|
||||||
|
|
||||||
pcmrec_dma_start();
|
pcmrec_dma_start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmrec_stop(void)
|
static void pcmrec_stop(void)
|
||||||
{
|
{
|
||||||
/* wait for recording to finish */
|
/* wait for recording to finish */
|
||||||
|
|
||||||
/* todo: Abort current DMA transfer using DCR1.. */
|
/* todo: Abort current DMA transfer using DCR1.. */
|
||||||
|
|
||||||
logf("pcmrec_stop");
|
logf("pcmrec_stop");
|
||||||
|
|
||||||
while (is_recording)
|
while (is_recording)
|
||||||
{
|
{
|
||||||
sleep(HZ >> 4);
|
sleep(HZ >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
logf("pcmrec_stop done");
|
logf("pcmrec_stop done");
|
||||||
|
|
||||||
/* Write unfinished buffers to file */
|
/* Write unfinished buffers to file */
|
||||||
pcmrec_callback(true);
|
pcmrec_callback(true);
|
||||||
|
|
||||||
close_wave();
|
close_wave();
|
||||||
|
|
||||||
is_stopping = 0;
|
is_stopping = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +545,7 @@ static void pcmrec_open(void)
|
||||||
{
|
{
|
||||||
unsigned long buffer_start;
|
unsigned long buffer_start;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
show_waveform = 0;
|
show_waveform = 0;
|
||||||
is_recording = 0;
|
is_recording = 0;
|
||||||
is_stopping = 0;
|
is_stopping = 0;
|
||||||
|
@ -555,7 +556,7 @@ static void pcmrec_open(void)
|
||||||
|
|
||||||
buffer_start = (unsigned long)(&audiobuf[(audiobufend - audiobuf) - (ALL_BUFFERS_SIZE + 16)]);
|
buffer_start = (unsigned long)(&audiobuf[(audiobufend - audiobuf) - (ALL_BUFFERS_SIZE + 16)]);
|
||||||
buffer_start &= ~3;
|
buffer_start &= ~3;
|
||||||
|
|
||||||
for (i=0; i<NUM_BUFFERS; i++)
|
for (i=0; i<NUM_BUFFERS; i++)
|
||||||
{
|
{
|
||||||
rec_buffers[i] = (unsigned char*)(buffer_start + EACH_BUFFER_SIZE * i);
|
rec_buffers[i] = (unsigned char*)(buffer_start + EACH_BUFFER_SIZE * i);
|
||||||
|
@ -572,61 +573,69 @@ static void pcmrec_open(void)
|
||||||
ICR4 = (ICR4 & 0xffffff00) | 0x0000001c; /* Enable interrupt at level 7, priority 0 */
|
ICR4 = (ICR4 & 0xffffff00) | 0x0000001c; /* Enable interrupt at level 7, priority 0 */
|
||||||
IMR &= ~(1<<15); /* bit 15 is DMA1 */
|
IMR &= ~(1<<15); /* bit 15 is DMA1 */
|
||||||
|
|
||||||
init_done = 1;
|
init_done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmrec_close(void)
|
static void pcmrec_close(void)
|
||||||
{
|
{
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_disable_recording();
|
uda1380_disable_recording();
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
tlv320_disable_recording();
|
||||||
|
#endif
|
||||||
|
|
||||||
DMAROUTE = (DMAROUTE & 0xffff00ff);
|
DMAROUTE = (DMAROUTE & 0xffff00ff);
|
||||||
ICR4 = (ICR4 & 0xffffff00); /* Disable interrupt */
|
ICR4 = (ICR4 & 0xffffff00); /* Disable interrupt */
|
||||||
IMR |= (1<<15); /* bit 15 is DMA1 */
|
IMR |= (1<<15); /* bit 15 is DMA1 */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmrec_thread(void)
|
static void pcmrec_thread(void)
|
||||||
{
|
{
|
||||||
struct event ev;
|
struct event ev;
|
||||||
|
|
||||||
logf("thread pcmrec start");
|
logf("thread pcmrec start");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
queue_wait(&pcmrec_queue, &ev);
|
queue_wait(&pcmrec_queue, &ev);
|
||||||
|
|
||||||
switch (ev.id)
|
switch (ev.id)
|
||||||
{
|
{
|
||||||
case PCMREC_OPEN:
|
case PCMREC_OPEN:
|
||||||
pcmrec_open();
|
pcmrec_open();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_CLOSE:
|
case PCMREC_CLOSE:
|
||||||
pcmrec_close();
|
pcmrec_close();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_START:
|
case PCMREC_START:
|
||||||
pcmrec_start();
|
pcmrec_start();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_STOP:
|
case PCMREC_STOP:
|
||||||
pcmrec_stop();
|
pcmrec_stop();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_PAUSE:
|
case PCMREC_PAUSE:
|
||||||
/* todo */
|
/* todo */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_RESUME:
|
case PCMREC_RESUME:
|
||||||
/* todo */
|
/* todo */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_NEW_FILE:
|
case PCMREC_NEW_FILE:
|
||||||
/* todo */
|
/* todo */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_SET_GAIN:
|
case PCMREC_SET_GAIN:
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
uda1380_set_recvol(rec_gain, rec_gain, rec_volume);
|
uda1380_set_recvol(rec_gain, rec_gain, rec_volume);
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
/* ToDo */
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCMREC_GOT_DATA:
|
case PCMREC_GOT_DATA:
|
||||||
|
@ -637,13 +646,12 @@ static void pcmrec_thread(void)
|
||||||
if (!is_recording && !is_stopping)
|
if (!is_recording && !is_stopping)
|
||||||
{
|
{
|
||||||
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
||||||
usb_wait_for_disconnect(&pcmrec_queue);
|
usb_wait_for_disconnect(&pcmrec_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logf("thread pcmrec done");
|
logf("thread pcmrec done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_UDA1380
|
#ifdef HAVE_UDA1380
|
||||||
#include "uda1380.h"
|
#include "uda1380.h"
|
||||||
|
#eilf HAVE_TLV320
|
||||||
|
#include "tlv320.h"
|
||||||
#endif
|
#endif
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
|
|
||||||
|
@ -377,7 +379,7 @@ static void handle_auto_poweroff(void)
|
||||||
last_event_tick = current_tick;
|
last_event_tick = current_tick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(timeout &&
|
if(timeout &&
|
||||||
#ifdef CONFIG_TUNER
|
#ifdef CONFIG_TUNER
|
||||||
(radio_get_status() != FMRADIO_PLAYING) &&
|
(radio_get_status() != FMRADIO_PLAYING) &&
|
||||||
|
@ -903,6 +905,8 @@ void shutdown_hw(void)
|
||||||
mp3_shutdown();
|
mp3_shutdown();
|
||||||
#ifdef HAVE_UDA1380
|
#ifdef HAVE_UDA1380
|
||||||
uda1380_close();
|
uda1380_close();
|
||||||
|
#eilf HAVE_TLV320
|
||||||
|
tlv320_close();
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_KEYPAD == ONDIO_PAD
|
#if CONFIG_KEYPAD == ONDIO_PAD
|
||||||
backlight_off();
|
backlight_off();
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "mas.h"
|
#include "mas.h"
|
||||||
#ifdef HAVE_UDA1380
|
#ifdef HAVE_UDA1380
|
||||||
#include "uda1380.h"
|
#include "uda1380.h"
|
||||||
|
#elif HAVE_TLV320
|
||||||
|
#include "tlv320.h"
|
||||||
#endif
|
#endif
|
||||||
#include "dac.h"
|
#include "dac.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue