2004-01-05 20:42:51 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Code that has been in mpeg.c before, now creating an encapsulated play
|
|
|
|
* data module, to be used by other sources than file playback as well.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004 by Linus Nielsen Feltzing
|
|
|
|
*
|
|
|
|
* 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 <stdbool.h>
|
|
|
|
#include "config.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "panic.h"
|
|
|
|
#include <kernel.h>
|
|
|
|
#include "mpeg.h" /* ToDo: remove crosslinks */
|
|
|
|
#include "mp3_playback.h"
|
|
|
|
#ifndef SIMULATOR
|
|
|
|
#include "i2c.h"
|
|
|
|
#include "mas.h"
|
|
|
|
#include "dac.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "hwcompat.h"
|
|
|
|
#endif
|
|
|
|
|
2004-01-10 15:39:56 +00:00
|
|
|
/* hacking into mpeg.c, recording is still there */
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3587F
|
2004-01-10 15:39:56 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
MPEG_DECODER,
|
|
|
|
MPEG_ENCODER
|
|
|
|
} mpeg_mode;
|
2004-09-28 22:13:26 +00:00
|
|
|
#endif /* #ifdef MAS3587F */
|
2004-01-10 15:39:56 +00:00
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
|
|
|
extern unsigned long shadow_io_control_main;
|
2005-01-09 00:58:59 +00:00
|
|
|
extern unsigned shadow_codec_reg0;
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif
|
|
|
|
|
2004-01-10 15:39:56 +00:00
|
|
|
/**** globals ****/
|
|
|
|
|
|
|
|
/* own version, independent of mpeg.c */
|
|
|
|
static bool paused; /* playback is paused */
|
|
|
|
static bool playing; /* We are playing an MP3 stream */
|
|
|
|
|
|
|
|
#ifndef SIMULATOR
|
|
|
|
/* for measuring the play time */
|
|
|
|
static long playstart_tick;
|
|
|
|
static long cumulative_ticks;
|
|
|
|
|
|
|
|
/* the registered callback function to ask for more mp3 data */
|
|
|
|
static void (*callback_for_more)(unsigned char**, int*);
|
|
|
|
#endif /* #ifndef SIMULATOR */
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
static const char* const units[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
"%", /* Volume */
|
|
|
|
"dB", /* Bass */
|
|
|
|
"dB", /* Treble */
|
|
|
|
"%", /* Balance */
|
|
|
|
"dB", /* Loudness */
|
|
|
|
"", /* AVC */
|
|
|
|
"", /* Channels */
|
2005-01-12 00:24:15 +00:00
|
|
|
"%", /* Stereo width */
|
2004-01-05 20:42:51 +00:00
|
|
|
"dB", /* Left gain */
|
|
|
|
"dB", /* Right gain */
|
|
|
|
"dB", /* Mic gain */
|
2004-07-06 12:17:14 +00:00
|
|
|
"dB", /* MDB Strength */
|
|
|
|
"%", /* MDB Harmonics */
|
|
|
|
"Hz", /* MDB Center */
|
|
|
|
"Hz", /* MDB Shape */
|
|
|
|
"", /* MDB Enable */
|
|
|
|
"", /* Super bass */
|
2004-01-05 20:42:51 +00:00
|
|
|
};
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
static const int numdecimals[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
0, /* Volume */
|
|
|
|
0, /* Bass */
|
|
|
|
0, /* Treble */
|
|
|
|
0, /* Balance */
|
|
|
|
0, /* Loudness */
|
|
|
|
0, /* AVC */
|
|
|
|
0, /* Channels */
|
2005-01-12 00:24:15 +00:00
|
|
|
0, /* Stereo width */
|
2004-01-05 20:42:51 +00:00
|
|
|
1, /* Left gain */
|
|
|
|
1, /* Right gain */
|
|
|
|
1, /* Mic gain */
|
2004-07-06 12:17:14 +00:00
|
|
|
0, /* MDB Strength */
|
|
|
|
0, /* MDB Harmonics */
|
|
|
|
0, /* MDB Center */
|
|
|
|
0, /* MDB Shape */
|
|
|
|
0, /* MDB Enable */
|
|
|
|
0, /* Super bass */
|
|
|
|
};
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
static const int steps[] =
|
2004-07-06 12:17:14 +00:00
|
|
|
{
|
|
|
|
1, /* Volume */
|
|
|
|
1, /* Bass */
|
|
|
|
1, /* Treble */
|
2004-07-27 22:27:59 +00:00
|
|
|
1, /* Balance */
|
2004-07-06 12:17:14 +00:00
|
|
|
1, /* Loudness */
|
|
|
|
1, /* AVC */
|
|
|
|
1, /* Channels */
|
2005-01-12 00:24:15 +00:00
|
|
|
1, /* Stereo width */
|
2004-07-06 12:17:14 +00:00
|
|
|
1, /* Left gain */
|
|
|
|
1, /* Right gain */
|
|
|
|
1, /* Mic gain */
|
|
|
|
1, /* MDB Strength */
|
|
|
|
1, /* MDB Harmonics */
|
|
|
|
10, /* MDB Center */
|
|
|
|
10, /* MDB Shape */
|
|
|
|
1, /* MDB Enable */
|
|
|
|
1, /* Super bass */
|
2004-01-05 20:42:51 +00:00
|
|
|
};
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
static const int minval[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
0, /* Volume */
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-06-21 13:42:37 +00:00
|
|
|
-12, /* Bass */
|
|
|
|
-12, /* Treble */
|
|
|
|
#else
|
|
|
|
-15, /* Bass */
|
|
|
|
-15, /* Treble */
|
|
|
|
#endif
|
|
|
|
-100, /* Balance */
|
2004-01-05 20:42:51 +00:00
|
|
|
0, /* Loudness */
|
|
|
|
-1, /* AVC */
|
|
|
|
0, /* Channels */
|
2005-01-12 00:24:15 +00:00
|
|
|
0, /* Stereo width */
|
2004-01-05 20:42:51 +00:00
|
|
|
0, /* Left gain */
|
|
|
|
0, /* Right gain */
|
|
|
|
0, /* Mic gain */
|
2004-07-06 12:17:14 +00:00
|
|
|
0, /* MDB Strength */
|
|
|
|
0, /* MDB Harmonics */
|
|
|
|
20, /* MDB Center */
|
|
|
|
50, /* MDB Shape */
|
|
|
|
0, /* MDB Enable */
|
|
|
|
0, /* Super bass */
|
2004-01-05 20:42:51 +00:00
|
|
|
};
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
static const int maxval[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
100, /* Volume */
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-06-21 13:42:37 +00:00
|
|
|
12, /* Bass */
|
|
|
|
12, /* Treble */
|
2004-01-05 20:42:51 +00:00
|
|
|
#else
|
2004-06-21 13:42:37 +00:00
|
|
|
15, /* Bass */
|
|
|
|
15, /* Treble */
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
2004-06-21 13:42:37 +00:00
|
|
|
100, /* Balance */
|
2004-01-05 20:42:51 +00:00
|
|
|
17, /* Loudness */
|
2004-06-22 12:37:42 +00:00
|
|
|
4, /* AVC */
|
2005-01-12 00:24:15 +00:00
|
|
|
5, /* Channels */
|
|
|
|
255, /* Stereo width */
|
2004-01-05 20:42:51 +00:00
|
|
|
15, /* Left gain */
|
|
|
|
15, /* Right gain */
|
|
|
|
15, /* Mic gain */
|
2004-07-06 12:17:14 +00:00
|
|
|
127, /* MDB Strength */
|
|
|
|
100, /* MDB Harmonics */
|
|
|
|
300, /* MDB Center */
|
|
|
|
300, /* MDB Shape */
|
|
|
|
1, /* MDB Enable */
|
|
|
|
1, /* Super bass */
|
2004-01-05 20:42:51 +00:00
|
|
|
};
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
static const int defaultval[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
70, /* Volume */
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-06-21 13:42:37 +00:00
|
|
|
6, /* Bass */
|
|
|
|
6, /* Treble */
|
2004-01-05 20:42:51 +00:00
|
|
|
#else
|
2004-06-21 13:42:37 +00:00
|
|
|
7, /* Bass */
|
|
|
|
7, /* Treble */
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
|
|
|
0, /* Balance */
|
|
|
|
0, /* Loudness */
|
|
|
|
0, /* AVC */
|
|
|
|
0, /* Channels */
|
2005-01-12 00:24:15 +00:00
|
|
|
100, /* Stereo width */
|
2004-01-05 20:42:51 +00:00
|
|
|
8, /* Left gain */
|
|
|
|
8, /* Right gain */
|
|
|
|
2, /* Mic gain */
|
2004-07-06 12:17:14 +00:00
|
|
|
50, /* MDB Strength */
|
|
|
|
48, /* MDB Harmonics */
|
|
|
|
60, /* MDB Center */
|
|
|
|
90, /* MDB Shape */
|
|
|
|
0, /* MDB Enable */
|
|
|
|
0, /* Super bass */
|
2004-01-05 20:42:51 +00:00
|
|
|
};
|
|
|
|
|
2004-07-20 22:13:24 +00:00
|
|
|
const char *mpeg_sound_unit(int setting)
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
return units[setting];
|
|
|
|
}
|
|
|
|
|
|
|
|
int mpeg_sound_numdecimals(int setting)
|
|
|
|
{
|
|
|
|
return numdecimals[setting];
|
|
|
|
}
|
|
|
|
|
2004-07-06 12:17:14 +00:00
|
|
|
int mpeg_sound_steps(int setting)
|
|
|
|
{
|
|
|
|
return steps[setting];
|
|
|
|
}
|
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
int mpeg_sound_min(int setting)
|
|
|
|
{
|
|
|
|
return minval[setting];
|
|
|
|
}
|
|
|
|
|
|
|
|
int mpeg_sound_max(int setting)
|
|
|
|
{
|
|
|
|
return maxval[setting];
|
|
|
|
}
|
|
|
|
|
|
|
|
int mpeg_sound_default(int setting)
|
|
|
|
{
|
|
|
|
return defaultval[setting];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* list of tracks in memory */
|
|
|
|
#define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
|
|
|
|
#define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
|
|
|
|
|
|
|
|
#ifndef SIMULATOR
|
|
|
|
static bool mpeg_is_initialized = false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef SIMULATOR
|
|
|
|
|
|
|
|
unsigned long mas_version_code;
|
|
|
|
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-01-05 20:42:51 +00:00
|
|
|
|
2004-08-03 19:22:56 +00:00
|
|
|
static const unsigned int bass_table[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
0x9e400, /* -15dB */
|
|
|
|
0xa2800, /* -14dB */
|
|
|
|
0xa7400, /* -13dB */
|
|
|
|
0xac400, /* -12dB */
|
|
|
|
0xb1800, /* -11dB */
|
|
|
|
0xb7400, /* -10dB */
|
|
|
|
0xbd400, /* -9dB */
|
|
|
|
0xc3c00, /* -8dB */
|
|
|
|
0xca400, /* -7dB */
|
|
|
|
0xd1800, /* -6dB */
|
|
|
|
0xd8c00, /* -5dB */
|
|
|
|
0xe0400, /* -4dB */
|
|
|
|
0xe8000, /* -3dB */
|
|
|
|
0xefc00, /* -2dB */
|
|
|
|
0xf7c00, /* -1dB */
|
|
|
|
0,
|
|
|
|
0x800, /* 1dB */
|
|
|
|
0x10000, /* 2dB */
|
|
|
|
0x17c00, /* 3dB */
|
|
|
|
0x1f800, /* 4dB */
|
|
|
|
0x27000, /* 5dB */
|
|
|
|
0x2e400, /* 6dB */
|
|
|
|
0x35800, /* 7dB */
|
|
|
|
0x3c000, /* 8dB */
|
|
|
|
0x42800, /* 9dB */
|
|
|
|
0x48800, /* 10dB */
|
|
|
|
0x4e400, /* 11dB */
|
|
|
|
0x53800, /* 12dB */
|
|
|
|
0x58800, /* 13dB */
|
|
|
|
0x5d400, /* 14dB */
|
|
|
|
0x61800 /* 15dB */
|
|
|
|
};
|
|
|
|
|
2004-08-03 19:22:56 +00:00
|
|
|
static const unsigned int treble_table[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
0xb2c00, /* -15dB */
|
|
|
|
0xbb400, /* -14dB */
|
|
|
|
0xc1800, /* -13dB */
|
|
|
|
0xc6c00, /* -12dB */
|
|
|
|
0xcbc00, /* -11dB */
|
|
|
|
0xd0400, /* -10dB */
|
|
|
|
0xd5000, /* -9dB */
|
|
|
|
0xd9800, /* -8dB */
|
|
|
|
0xde000, /* -7dB */
|
|
|
|
0xe2800, /* -6dB */
|
|
|
|
0xe7e00, /* -5dB */
|
|
|
|
0xec000, /* -4dB */
|
|
|
|
0xf0c00, /* -3dB */
|
|
|
|
0xf5c00, /* -2dB */
|
|
|
|
0xfac00, /* -1dB */
|
|
|
|
0,
|
|
|
|
0x5400, /* 1dB */
|
|
|
|
0xac00, /* 2dB */
|
|
|
|
0x10400, /* 3dB */
|
|
|
|
0x16000, /* 4dB */
|
|
|
|
0x1c000, /* 5dB */
|
|
|
|
0x22400, /* 6dB */
|
|
|
|
0x28400, /* 7dB */
|
|
|
|
0x2ec00, /* 8dB */
|
|
|
|
0x35400, /* 9dB */
|
|
|
|
0x3c000, /* 10dB */
|
|
|
|
0x42c00, /* 11dB */
|
|
|
|
0x49c00, /* 12dB */
|
|
|
|
0x51800, /* 13dB */
|
|
|
|
0x58400, /* 14dB */
|
|
|
|
0x5f800 /* 15dB */
|
|
|
|
};
|
|
|
|
|
2004-08-03 19:22:56 +00:00
|
|
|
static const unsigned int prescale_table[] =
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
0x80000, /* 0db */
|
|
|
|
0x8e000, /* 1dB */
|
|
|
|
0x9a400, /* 2dB */
|
|
|
|
0xa5800, /* 3dB */
|
|
|
|
0xaf400, /* 4dB */
|
|
|
|
0xb8000, /* 5dB */
|
|
|
|
0xbfc00, /* 6dB */
|
|
|
|
0xc6c00, /* 7dB */
|
|
|
|
0xcd000, /* 8dB */
|
|
|
|
0xd25c0, /* 9dB */
|
|
|
|
0xd7800, /* 10dB */
|
|
|
|
0xdc000, /* 11dB */
|
|
|
|
0xdfc00, /* 12dB */
|
|
|
|
0xe3400, /* 13dB */
|
|
|
|
0xe6800, /* 14dB */
|
|
|
|
0xe9400 /* 15dB */
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool dma_on; /* The DMA is active */
|
|
|
|
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-11-07 08:09:08 +00:00
|
|
|
static void mas_poll_start(void)
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
unsigned int count;
|
|
|
|
|
2004-11-07 08:09:08 +00:00
|
|
|
count = 9 * FREQ / 10000 / 8; /* 0.9 ms */
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* We are using timer 1 */
|
|
|
|
|
|
|
|
TSTR &= ~0x02; /* Stop the timer */
|
|
|
|
TSNC &= ~0x02; /* No synchronization */
|
|
|
|
TMDR &= ~0x02; /* Operate normally */
|
|
|
|
|
|
|
|
TCNT1 = 0; /* Start counting at 0 */
|
|
|
|
GRA1 = count;
|
|
|
|
TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
|
|
|
|
|
|
|
|
/* Enable interrupt on level 5 */
|
|
|
|
IPRC = (IPRC & ~0x000f) | 0x0005;
|
|
|
|
|
|
|
|
TSR1 &= ~0x02;
|
|
|
|
TIER1 = 0xf9; /* Enable GRA match interrupt */
|
|
|
|
|
|
|
|
TSTR |= 0x02; /* Start timer 1 */
|
|
|
|
}
|
2004-01-10 15:39:56 +00:00
|
|
|
#else
|
|
|
|
static void postpone_dma_tick(void)
|
|
|
|
{
|
|
|
|
unsigned int count;
|
|
|
|
|
2004-11-07 08:09:08 +00:00
|
|
|
count = 8 * FREQ / 10000 / 8; /* 0.8 ms */
|
2004-01-10 15:39:56 +00:00
|
|
|
|
|
|
|
/* We are using timer 1 */
|
|
|
|
|
|
|
|
TSTR &= ~0x02; /* Stop the timer */
|
|
|
|
TSNC &= ~0x02; /* No synchronization */
|
|
|
|
TMDR &= ~0x02; /* Operate normally */
|
|
|
|
|
|
|
|
TCNT1 = 0; /* Start counting at 0 */
|
|
|
|
GRA1 = count;
|
|
|
|
TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
|
|
|
|
|
|
|
|
/* Enable interrupt on level 5 */
|
|
|
|
IPRC = (IPRC & ~0x000f) | 0x0005;
|
|
|
|
|
|
|
|
TSR1 &= ~0x02;
|
|
|
|
TIER1 = 0xf9; /* Enable GRA match interrupt */
|
|
|
|
|
|
|
|
TSTR |= 0x02; /* Start timer 1 */
|
|
|
|
}
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
|
|
|
|
2004-01-10 15:39:56 +00:00
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-10 15:39:56 +00:00
|
|
|
void demand_irq_enable(bool on)
|
|
|
|
{
|
2004-03-02 11:32:59 +00:00
|
|
|
int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
|
2004-01-10 15:39:56 +00:00
|
|
|
|
|
|
|
if(on)
|
|
|
|
{
|
|
|
|
IPRA = (IPRA & 0xfff0) | 0x000b;
|
|
|
|
ICR &= ~0x0010; /* IRQ3 level sensitive */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
IPRA &= 0xfff0;
|
|
|
|
|
|
|
|
set_irq_level(oldlevel);
|
|
|
|
}
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
|
2004-01-10 15:39:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
void play_tick(void)
|
|
|
|
{
|
|
|
|
if(playing && !paused)
|
|
|
|
{
|
|
|
|
/* Start DMA if it is disabled and the DEMAND pin is high */
|
|
|
|
if(!(SCR0 & 0x80) && (PBDR & 0x4000))
|
|
|
|
{
|
|
|
|
SCR0 |= 0x80;
|
|
|
|
}
|
|
|
|
|
|
|
|
playback_tick(); /* dirty call to mpeg.c */
|
|
|
|
}
|
|
|
|
}
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
#pragma interrupt
|
|
|
|
void DEI3(void)
|
|
|
|
{
|
|
|
|
unsigned char* start;
|
|
|
|
int size = 0;
|
|
|
|
|
|
|
|
if (callback_for_more != NULL)
|
|
|
|
{
|
|
|
|
callback_for_more(&start, &size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (size > 0)
|
|
|
|
{
|
|
|
|
DTCR3 = size & 0xffff;
|
|
|
|
SAR3 = (unsigned int) start;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CHCR3 &= ~0x0001; /* Disable the DMA interrupt */
|
|
|
|
}
|
|
|
|
|
|
|
|
CHCR3 &= ~0x0002; /* Clear DMA interrupt */
|
|
|
|
}
|
|
|
|
|
2004-01-10 15:39:56 +00:00
|
|
|
#pragma interrupt
|
|
|
|
void IMIA1(void) /* Timer 1 interrupt */
|
|
|
|
{
|
|
|
|
if(playing)
|
|
|
|
play_tick();
|
|
|
|
TSR1 &= ~0x01;
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-10 15:39:56 +00:00
|
|
|
/* Disable interrupt */
|
|
|
|
IPRC &= ~0x000f;
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif
|
2004-01-10 15:39:56 +00:00
|
|
|
}
|
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
#pragma interrupt
|
|
|
|
void IRQ6(void) /* PB14: MAS stop demand IRQ */
|
|
|
|
{
|
2004-01-10 15:39:56 +00:00
|
|
|
SCR0 &= ~0x80;
|
|
|
|
}
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-10 15:39:56 +00:00
|
|
|
#pragma interrupt
|
|
|
|
void IRQ3(void) /* PA15: MAS demand IRQ */
|
|
|
|
{
|
|
|
|
/* Begin with setting the IRQ to edge sensitive */
|
|
|
|
ICR |= 0x0010;
|
2004-09-29 19:51:41 +00:00
|
|
|
|
|
|
|
#if CONFIG_HWCODEC == MAS3587F
|
2004-01-10 15:39:56 +00:00
|
|
|
if(mpeg_mode == MPEG_ENCODER)
|
|
|
|
rec_tick();
|
|
|
|
else
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif
|
2004-01-10 15:39:56 +00:00
|
|
|
postpone_dma_tick();
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
static void setup_sci0(void)
|
|
|
|
{
|
|
|
|
/* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */
|
|
|
|
PBCR1 = (PBCR1 & 0x0cff) | 0x1208;
|
|
|
|
|
|
|
|
/* Set PB12 to output */
|
|
|
|
or_b(0x10, &PBIORH);
|
|
|
|
|
|
|
|
/* Disable serial port */
|
|
|
|
SCR0 = 0x00;
|
|
|
|
|
|
|
|
/* Synchronous, no prescale */
|
|
|
|
SMR0 = 0x80;
|
|
|
|
|
|
|
|
/* Set baudrate 1Mbit/s */
|
2004-11-06 00:54:56 +00:00
|
|
|
BRR0 = 0x02;
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* use SCK as serial clock output */
|
|
|
|
SCR0 = 0x01;
|
|
|
|
|
|
|
|
/* Clear FER and PER */
|
|
|
|
SSR0 &= 0xe7;
|
|
|
|
|
|
|
|
/* Set interrupt ITU2 and SCI0 priority to 0 */
|
|
|
|
IPRD &= 0x0ff0;
|
|
|
|
|
|
|
|
/* set PB15 and PB14 to inputs */
|
|
|
|
and_b(~0x80, &PBIORH);
|
|
|
|
and_b(~0x40, &PBIORH);
|
|
|
|
|
|
|
|
/* Enable End of DMA interrupt at prio 8 */
|
|
|
|
IPRC = (IPRC & 0xf0ff) | 0x0800;
|
|
|
|
|
|
|
|
/* Enable Tx (only!) */
|
|
|
|
SCR0 |= 0x20;
|
|
|
|
}
|
|
|
|
#endif /* SIMULATOR */
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
static void init_playback(void)
|
|
|
|
{
|
|
|
|
unsigned long val;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
mp3_play_pause(false);
|
|
|
|
|
|
|
|
mas_reset();
|
2004-10-01 18:47:19 +00:00
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
/* Enable the audio CODEC and the DSP core, max analog voltage range */
|
|
|
|
rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
|
|
|
|
if(rc < 0)
|
|
|
|
panicf("mas_ctrl_w: %d", rc);
|
|
|
|
|
|
|
|
/* Stop the current application */
|
|
|
|
val = 0;
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
do
|
|
|
|
{
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
} while(val);
|
|
|
|
|
|
|
|
/* Enable the D/A Converter */
|
2005-01-09 00:58:59 +00:00
|
|
|
shadow_codec_reg0 = 0x0001;
|
|
|
|
mas_codec_writereg(0x0, shadow_codec_reg0);
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* ADC scale 0%, DSP scale 100% */
|
|
|
|
mas_codec_writereg(6, 0x0000);
|
|
|
|
mas_codec_writereg(7, 0x4000);
|
|
|
|
|
2004-10-11 22:53:49 +00:00
|
|
|
#ifdef HAVE_SPDIF_OUT
|
|
|
|
val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
|
|
|
|
#else
|
|
|
|
val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
|
|
|
|
#endif
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* Set Demand mode and validate all settings */
|
2004-09-29 19:51:41 +00:00
|
|
|
shadow_io_control_main = 0x25;
|
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* Start the Layer2/3 decoder applications */
|
|
|
|
val = 0x0c;
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
do
|
|
|
|
{
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
} while((val & 0x0c) != 0x0c);
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3587F
|
2004-01-10 15:39:56 +00:00
|
|
|
mpeg_mode = MPEG_DECODER;
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif
|
2004-01-10 15:39:56 +00:00
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
/* set IRQ6 to edge detect */
|
|
|
|
ICR |= 0x02;
|
|
|
|
|
|
|
|
/* set IRQ6 prio 8 */
|
|
|
|
IPRB = ( IPRB & 0xff0f ) | 0x0080;
|
|
|
|
|
|
|
|
DEBUGF("MAS Decoding application started\n");
|
|
|
|
}
|
2004-09-29 19:51:41 +00:00
|
|
|
#endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
#ifndef SIMULATOR
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-01-05 20:42:51 +00:00
|
|
|
int current_left_volume = 0; /* all values in tenth of dB */
|
|
|
|
int current_right_volume = 0; /* all values in tenth of dB */
|
|
|
|
int current_treble = 0;
|
|
|
|
int current_bass = 0;
|
|
|
|
int current_balance = 0;
|
|
|
|
|
|
|
|
/* convert tenth of dB volume to register value */
|
|
|
|
static int tenthdb2reg(int db) {
|
|
|
|
if (db < -540)
|
|
|
|
return (db + 780) / 30;
|
|
|
|
else
|
|
|
|
return (db + 660) / 15;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_prescaled_volume(void)
|
|
|
|
{
|
|
|
|
int prescale;
|
|
|
|
int l, r;
|
|
|
|
|
|
|
|
prescale = MAX(current_bass, current_treble);
|
|
|
|
if (prescale < 0)
|
|
|
|
prescale = 0; /* no need to prescale if we don't boost
|
|
|
|
bass or treble */
|
|
|
|
|
|
|
|
mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
|
|
|
|
|
|
|
|
/* gain up the analog volume to compensate the prescale reduction gain */
|
|
|
|
l = current_left_volume + prescale;
|
|
|
|
r = current_right_volume + prescale;
|
|
|
|
|
|
|
|
dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
|
|
|
|
}
|
2004-09-28 22:13:26 +00:00
|
|
|
#endif /* MAS3507D */
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif /* !SIMULATOR */
|
|
|
|
|
2005-01-12 00:24:15 +00:00
|
|
|
int channel_configuration = MPEG_SOUND_STEREO;
|
|
|
|
int stereo_width = 100;
|
|
|
|
|
|
|
|
#ifndef SIMULATOR
|
|
|
|
static void set_channel_config(void)
|
|
|
|
{
|
|
|
|
/* default values: stereo */
|
|
|
|
unsigned long val_ll = 0x80000;
|
|
|
|
unsigned long val_lr = 0;
|
|
|
|
unsigned long val_rl = 0;
|
|
|
|
unsigned long val_rr = 0x80000;
|
|
|
|
|
|
|
|
switch(channel_configuration)
|
|
|
|
{
|
|
|
|
/* case MPEG_SOUND_STEREO unnecessary */
|
|
|
|
|
|
|
|
case MPEG_SOUND_MONO:
|
|
|
|
val_ll = 0xc0000;
|
|
|
|
val_lr = 0xc0000;
|
|
|
|
val_rl = 0xc0000;
|
|
|
|
val_rr = 0xc0000;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MPEG_SOUND_CUSTOM:
|
|
|
|
{
|
|
|
|
/* fixed point variables (matching MAS internal format)
|
|
|
|
integer part: upper 13 bits (inlcuding sign)
|
|
|
|
fractional part: lower 19 bits */
|
|
|
|
long fp_width, fp_straight, fp_cross;
|
|
|
|
|
|
|
|
fp_width = (stereo_width << 19) / 100;
|
|
|
|
if (stereo_width <= 100)
|
|
|
|
{
|
|
|
|
fp_straight = - ((1<<19) + fp_width) / 2;
|
|
|
|
fp_cross = fp_straight + fp_width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fp_straight = - (1<<19);
|
|
|
|
fp_cross = ((2 * fp_width / (((1<<19) + fp_width) >> 10))
|
|
|
|
<< 9) - (1<<19);
|
|
|
|
}
|
|
|
|
val_ll = val_rr = fp_straight & 0xFFFFF;
|
|
|
|
val_lr = val_rl = fp_cross & 0xFFFFF;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MPEG_SOUND_MONO_LEFT:
|
|
|
|
val_ll = 0x80000;
|
|
|
|
val_lr = 0x80000;
|
|
|
|
val_rl = 0;
|
|
|
|
val_rr = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MPEG_SOUND_MONO_RIGHT:
|
|
|
|
val_ll = 0;
|
|
|
|
val_lr = 0;
|
|
|
|
val_rl = 0x80000;
|
|
|
|
val_rr = 0x80000;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MPEG_SOUND_KARAOKE:
|
|
|
|
val_ll = 0x80001;
|
|
|
|
val_lr = 0x7ffff;
|
|
|
|
val_rl = 0x7ffff;
|
|
|
|
val_rr = 0x80001;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
|
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
|
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
|
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
|
|
|
|
#elif CONFIG_HWCODEC == MAS3507D
|
|
|
|
mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
|
|
|
|
mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
|
|
|
|
mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
|
|
|
|
mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif /* !SIMULATOR */
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-07-06 12:17:14 +00:00
|
|
|
unsigned long mdb_shape_shadow = 0;
|
|
|
|
unsigned long loudness_shadow = 0;
|
|
|
|
#endif
|
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
void mpeg_sound_set(int setting, int value)
|
|
|
|
{
|
|
|
|
#ifdef SIMULATOR
|
|
|
|
setting = value;
|
|
|
|
#else
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-01-05 20:42:51 +00:00
|
|
|
int l, r;
|
|
|
|
#else
|
|
|
|
int tmp;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(!mpeg_is_initialized)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch(setting)
|
|
|
|
{
|
|
|
|
case SOUND_VOLUME:
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
tmp = 0x7f00 * value / 100;
|
|
|
|
mas_codec_writereg(0x10, tmp & 0xff00);
|
|
|
|
#else
|
|
|
|
l = value;
|
|
|
|
r = value;
|
|
|
|
|
|
|
|
if(current_balance > 0)
|
|
|
|
{
|
|
|
|
l -= current_balance;
|
|
|
|
if(l < 0)
|
|
|
|
l = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(current_balance < 0)
|
|
|
|
{
|
|
|
|
r += current_balance;
|
|
|
|
if(r < 0)
|
|
|
|
r = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
l = 0x38 * l / 100;
|
|
|
|
r = 0x38 * r / 100;
|
|
|
|
|
|
|
|
/* store volume in tenth of dB */
|
|
|
|
current_left_volume = ( l < 0x08 ? l*30 - 780 : l*15 - 660 );
|
|
|
|
current_right_volume = ( r < 0x08 ? r*30 - 780 : r*15 - 660 );
|
|
|
|
|
|
|
|
set_prescaled_volume();
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_BALANCE:
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
tmp = ((value * 127 / 100) & 0xff) << 8;
|
|
|
|
mas_codec_writereg(0x11, tmp & 0xff00);
|
2004-09-13 08:12:15 +00:00
|
|
|
#else
|
|
|
|
current_balance = value;
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_BASS:
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-06-21 13:42:37 +00:00
|
|
|
tmp = ((value * 8) & 0xff) << 8;
|
2004-01-05 20:42:51 +00:00
|
|
|
mas_codec_writereg(0x14, tmp & 0xff00);
|
|
|
|
#else
|
2004-06-21 13:42:37 +00:00
|
|
|
mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
|
|
|
|
current_bass = (value) * 10;
|
2004-01-05 20:42:51 +00:00
|
|
|
set_prescaled_volume();
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_TREBLE:
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-06-21 13:42:37 +00:00
|
|
|
tmp = ((value * 8) & 0xff) << 8;
|
2004-01-05 20:42:51 +00:00
|
|
|
mas_codec_writereg(0x15, tmp & 0xff00);
|
|
|
|
#else
|
2004-06-21 13:42:37 +00:00
|
|
|
mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
|
|
|
|
current_treble = (value) * 10;
|
2004-01-05 20:42:51 +00:00
|
|
|
set_prescaled_volume();
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
case SOUND_LOUDNESS:
|
2004-07-06 12:17:14 +00:00
|
|
|
loudness_shadow = (loudness_shadow & 0x04) |
|
|
|
|
(MAX(MIN(value * 4, 0x44), 0) << 8);
|
|
|
|
mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
|
2004-01-05 20:42:51 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_AVC:
|
|
|
|
switch (value) {
|
2004-06-22 12:37:42 +00:00
|
|
|
case 1: /* 20ms */
|
|
|
|
tmp = (0x1 << 8) | (0x8 << 12);
|
|
|
|
break;
|
|
|
|
case 2: /* 2s */
|
2004-01-05 20:42:51 +00:00
|
|
|
tmp = (0x2 << 8) | (0x8 << 12);
|
|
|
|
break;
|
2004-06-22 12:37:42 +00:00
|
|
|
case 3: /* 4s */
|
2004-01-05 20:42:51 +00:00
|
|
|
tmp = (0x4 << 8) | (0x8 << 12);
|
|
|
|
break;
|
2004-06-22 12:37:42 +00:00
|
|
|
case 4: /* 8s */
|
2004-01-05 20:42:51 +00:00
|
|
|
tmp = (0x8 << 8) | (0x8 << 12);
|
|
|
|
break;
|
|
|
|
case -1: /* turn off and then turn on again to decay quickly */
|
|
|
|
tmp = mas_codec_readreg(MAS_REG_KAVC);
|
|
|
|
mas_codec_writereg(MAS_REG_KAVC, 0);
|
|
|
|
break;
|
|
|
|
default: /* off */
|
|
|
|
tmp = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mas_codec_writereg(MAS_REG_KAVC, tmp);
|
|
|
|
break;
|
2004-07-06 12:17:14 +00:00
|
|
|
|
|
|
|
case SOUND_MDB_STRENGTH:
|
|
|
|
mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_MDB_HARMONICS:
|
|
|
|
tmp = value * 127 / 100;
|
|
|
|
mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_MDB_CENTER:
|
|
|
|
mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_MDB_SHAPE:
|
|
|
|
mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
|
|
|
|
mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_MDB_ENABLE:
|
|
|
|
mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
|
|
|
|
mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_SUPERBASS:
|
|
|
|
loudness_shadow = (loudness_shadow & ~0x04) |
|
|
|
|
(value?4:0);
|
|
|
|
mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
|
|
|
|
break;
|
|
|
|
#endif
|
2004-01-05 20:42:51 +00:00
|
|
|
case SOUND_CHANNELS:
|
2005-01-12 00:24:15 +00:00
|
|
|
channel_configuration = value;
|
|
|
|
set_channel_config();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_STEREO_WIDTH:
|
|
|
|
stereo_width = value;
|
|
|
|
if (channel_configuration == MPEG_SOUND_CUSTOM)
|
|
|
|
set_channel_config();
|
2004-01-05 20:42:51 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif /* SIMULATOR */
|
|
|
|
}
|
|
|
|
|
|
|
|
int mpeg_val2phys(int setting, int value)
|
|
|
|
{
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
switch(setting)
|
|
|
|
{
|
|
|
|
case SOUND_LEFT_GAIN:
|
|
|
|
case SOUND_RIGHT_GAIN:
|
|
|
|
result = (value - 2) * 15;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOUND_MIC_GAIN:
|
|
|
|
result = value * 15 + 210;
|
|
|
|
break;
|
|
|
|
|
2004-06-21 13:42:37 +00:00
|
|
|
default:
|
2004-01-05 20:42:51 +00:00
|
|
|
result = value;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
2004-06-21 13:42:37 +00:00
|
|
|
#else
|
|
|
|
(void)setting;
|
|
|
|
return value;
|
|
|
|
#endif
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
/* This function works by telling the decoder that we have another
|
|
|
|
crystal frequency than we actually have. It will adjust its internal
|
|
|
|
parameters and the result is that the audio is played at another pitch.
|
|
|
|
|
|
|
|
The pitch value is in tenths of percent.
|
|
|
|
*/
|
|
|
|
void mpeg_set_pitch(int pitch)
|
|
|
|
{
|
|
|
|
unsigned long val;
|
|
|
|
|
|
|
|
/* invert pitch value */
|
|
|
|
pitch = 1000000/pitch;
|
|
|
|
|
|
|
|
/* Calculate the new (bogus) frequency */
|
|
|
|
val = 18432*pitch/1000;
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* We must tell the MAS that the frequency has changed.
|
|
|
|
This will unfortunately cause a short silence. */
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-10-01 18:47:19 +00:00
|
|
|
void mp3_init(int volume, int bass, int treble, int balance, int loudness,
|
2005-01-12 00:24:15 +00:00
|
|
|
int avc, int channel_config, int stereo_width,
|
2004-07-06 12:17:14 +00:00
|
|
|
int mdb_strength, int mdb_harmonics,
|
|
|
|
int mdb_center, int mdb_shape, bool mdb_enable,
|
|
|
|
bool superbass)
|
2004-01-05 20:42:51 +00:00
|
|
|
{
|
|
|
|
#ifdef SIMULATOR
|
2004-07-06 12:17:14 +00:00
|
|
|
(void)volume;
|
|
|
|
(void)bass;
|
|
|
|
(void)treble;
|
|
|
|
(void)balance;
|
|
|
|
(void)loudness;
|
|
|
|
(void)avc;
|
|
|
|
(void)channel_config;
|
2005-01-12 00:24:15 +00:00
|
|
|
(void)stereo_width;
|
2004-07-06 12:17:14 +00:00
|
|
|
(void)mdb_strength;
|
|
|
|
(void)mdb_harmonics;
|
|
|
|
(void)mdb_center;
|
|
|
|
(void)mdb_shape;
|
|
|
|
(void)mdb_enable;
|
|
|
|
(void)superbass;
|
2004-01-05 20:42:51 +00:00
|
|
|
#else
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-01-05 20:42:51 +00:00
|
|
|
unsigned long val;
|
2004-07-06 12:17:14 +00:00
|
|
|
(void)loudness;
|
|
|
|
(void)avc;
|
|
|
|
(void)mdb_strength;
|
|
|
|
(void)mdb_harmonics;
|
|
|
|
(void)mdb_center;
|
|
|
|
(void)mdb_shape;
|
|
|
|
(void)mdb_enable;
|
|
|
|
(void)superbass;
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
setup_sci0();
|
|
|
|
|
2004-10-01 07:36:25 +00:00
|
|
|
#ifdef HAVE_MAS_SIBI_CONTROL
|
|
|
|
and_b(~0x01, &PBDRH); /* drive SIBI low */
|
2004-10-02 21:53:21 +00:00
|
|
|
or_b(0x01, &PBIORH); /* output for PB8 */
|
2004-10-01 07:36:25 +00:00
|
|
|
#endif
|
|
|
|
|
2004-11-22 01:54:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
|
|
|
mas_reset();
|
|
|
|
#elif CONFIG_HWCODEC == MAS3587F
|
2004-01-05 20:42:51 +00:00
|
|
|
or_b(0x08, &PAIORH); /* output for /PR */
|
|
|
|
init_playback();
|
|
|
|
|
|
|
|
mas_version_code = mas_readver();
|
2004-08-05 17:06:31 +00:00
|
|
|
DEBUGF("MAS3587 derivate %d, version %c%d\n",
|
|
|
|
(mas_version_code & 0xf000) >> 12,
|
|
|
|
'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff);
|
2004-10-01 18:47:19 +00:00
|
|
|
#elif CONFIG_HWCODEC == MAS3539F
|
2004-09-29 19:51:41 +00:00
|
|
|
or_b(0x08, &PAIORH); /* output for /PR */
|
|
|
|
init_playback();
|
|
|
|
|
|
|
|
mas_version_code = mas_readver();
|
|
|
|
DEBUGF("MAS3539 derivate %d, version %c%d\n",
|
|
|
|
(mas_version_code & 0xf000) >> 12,
|
|
|
|
'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff);
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_DAC3550A
|
|
|
|
dac_init();
|
|
|
|
#endif
|
|
|
|
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-01-05 20:42:51 +00:00
|
|
|
and_b(~0x20, &PBDRL);
|
|
|
|
sleep(HZ/5);
|
|
|
|
or_b(0x20, &PBDRL);
|
|
|
|
sleep(HZ/5);
|
|
|
|
|
|
|
|
/* set IRQ6 to edge detect */
|
|
|
|
ICR |= 0x02;
|
|
|
|
|
|
|
|
/* set IRQ6 prio 8 */
|
|
|
|
IPRB = ( IPRB & 0xff0f ) | 0x0080;
|
|
|
|
|
|
|
|
mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1);
|
|
|
|
|
|
|
|
mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */
|
|
|
|
mas_run(1);
|
|
|
|
sleep(HZ);
|
|
|
|
|
|
|
|
/* Clear the upper 12 bits of the 32-bit samples */
|
|
|
|
mas_writereg(0xc5, 0);
|
|
|
|
mas_writereg(0xc6, 0);
|
|
|
|
|
2004-11-06 00:54:56 +00:00
|
|
|
/* We need to set the PLL for a 14.31818MHz crystal */
|
2004-01-05 20:42:51 +00:00
|
|
|
if(mas_version_code == 0x0601) /* Version F10? */
|
|
|
|
{
|
|
|
|
val = 0x5d9d0;
|
|
|
|
mas_writemem(MAS_BANK_D0, 0x32d, &val, 1);
|
|
|
|
val = 0xfffceceb;
|
|
|
|
mas_writemem(MAS_BANK_D0, 0x32e, &val, 1);
|
|
|
|
val = 0x0;
|
|
|
|
mas_writemem(MAS_BANK_D0, 0x32f, &val, 1);
|
|
|
|
mas_run(0x475);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
val = 0x5d9d0;
|
|
|
|
mas_writemem(MAS_BANK_D0, 0x36d, &val, 1);
|
|
|
|
val = 0xfffceceb;
|
|
|
|
mas_writemem(MAS_BANK_D0, 0x36e, &val, 1);
|
|
|
|
val = 0x0;
|
|
|
|
mas_writemem(MAS_BANK_D0, 0x36f, &val, 1);
|
|
|
|
mas_run(0xfcb);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-11-07 08:09:08 +00:00
|
|
|
mas_poll_start();
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
mas_writereg(MAS_REG_KPRESCALE, 0xe9400);
|
|
|
|
dac_enable(true);
|
|
|
|
#endif
|
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
ICR &= ~0x0010; /* IRQ3 level sensitive */
|
|
|
|
PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Must be done before calling mpeg_sound_set() */
|
|
|
|
mpeg_is_initialized = true;
|
2004-09-29 19:51:41 +00:00
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
mpeg_sound_set(SOUND_BASS, bass);
|
|
|
|
mpeg_sound_set(SOUND_TREBLE, treble);
|
|
|
|
mpeg_sound_set(SOUND_BALANCE, balance);
|
|
|
|
mpeg_sound_set(SOUND_VOLUME, volume);
|
2005-01-12 00:24:15 +00:00
|
|
|
mpeg_sound_set(SOUND_CHANNELS, channel_config);
|
|
|
|
mpeg_sound_set(SOUND_STEREO_WIDTH, stereo_width);
|
2004-01-05 20:42:51 +00:00
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
mpeg_sound_set(SOUND_LOUDNESS, loudness);
|
|
|
|
mpeg_sound_set(SOUND_AVC, avc);
|
2004-07-06 12:17:14 +00:00
|
|
|
mpeg_sound_set(SOUND_MDB_STRENGTH, mdb_strength);
|
|
|
|
mpeg_sound_set(SOUND_MDB_HARMONICS, mdb_harmonics);
|
|
|
|
mpeg_sound_set(SOUND_MDB_CENTER, mdb_center);
|
|
|
|
mpeg_sound_set(SOUND_MDB_SHAPE, mdb_shape);
|
|
|
|
mpeg_sound_set(SOUND_MDB_ENABLE, mdb_enable);
|
|
|
|
mpeg_sound_set(SOUND_SUPERBASS, superbass);
|
2004-01-05 20:42:51 +00:00
|
|
|
#endif
|
|
|
|
#endif /* !SIMULATOR */
|
2004-01-10 15:39:56 +00:00
|
|
|
|
|
|
|
playing = false;
|
|
|
|
paused = true;
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
|
|
|
|
2004-07-24 21:26:41 +00:00
|
|
|
void mp3_shutdown(void)
|
|
|
|
{
|
|
|
|
#ifndef SIMULATOR
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-07-24 21:26:41 +00:00
|
|
|
unsigned long val = 1;
|
2004-09-29 19:51:41 +00:00
|
|
|
mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &val, 1); /* Mute */
|
2004-07-24 21:26:41 +00:00
|
|
|
#endif
|
|
|
|
|
2004-09-28 22:13:26 +00:00
|
|
|
#if CONFIG_HWCODEC == MAS3507D
|
2004-07-24 21:26:41 +00:00
|
|
|
dac_volume(0, 0, false);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
2004-01-05 20:42:51 +00:00
|
|
|
|
|
|
|
/* new functions, to be exported to plugin API */
|
|
|
|
|
2004-01-05 23:42:56 +00:00
|
|
|
#ifndef SIMULATOR
|
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
void mp3_play_init(void)
|
|
|
|
{
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-05 20:42:51 +00:00
|
|
|
init_playback();
|
|
|
|
#endif
|
2004-01-10 15:39:56 +00:00
|
|
|
playing = false;
|
|
|
|
paused = true;
|
2004-01-05 20:42:51 +00:00
|
|
|
callback_for_more = NULL;
|
2004-01-10 15:39:56 +00:00
|
|
|
mp3_reset_playtime();
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
|
|
|
|
2004-08-16 23:37:23 +00:00
|
|
|
void mp3_play_data(const unsigned char* start, int size,
|
2004-01-05 20:42:51 +00:00
|
|
|
void (*get_more)(unsigned char** start, int* size) /* callback fn */
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* init DMA */
|
|
|
|
DAR3 = 0x5FFFEC3;
|
|
|
|
CHCR3 &= ~0x0002; /* Clear interrupt */
|
|
|
|
CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */
|
|
|
|
DMAOR = 0x0001; /* Enable DMA */
|
|
|
|
|
|
|
|
callback_for_more = get_more;
|
|
|
|
|
|
|
|
SAR3 = (unsigned int)start;
|
|
|
|
DTCR3 = size & 0xffff;
|
|
|
|
|
2004-01-10 15:39:56 +00:00
|
|
|
playing = true;
|
|
|
|
paused = true;
|
|
|
|
|
2004-01-05 20:42:51 +00:00
|
|
|
CHCR3 |= 0x0001; /* Enable DMA IRQ */
|
2004-01-10 15:39:56 +00:00
|
|
|
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-10 15:39:56 +00:00
|
|
|
demand_irq_enable(true);
|
|
|
|
#endif
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mp3_play_pause(bool play)
|
|
|
|
{
|
2004-01-10 15:39:56 +00:00
|
|
|
if (paused && play)
|
|
|
|
{ /* resume playback */
|
2004-01-05 20:42:51 +00:00
|
|
|
SCR0 |= 0x80;
|
2004-01-10 15:39:56 +00:00
|
|
|
paused = false;
|
|
|
|
playstart_tick = current_tick;
|
|
|
|
}
|
|
|
|
else if (!paused && !play)
|
|
|
|
{ /* stop playback */
|
2004-01-05 20:42:51 +00:00
|
|
|
SCR0 &= 0x7f;
|
2004-01-10 15:39:56 +00:00
|
|
|
paused = true;
|
|
|
|
cumulative_ticks += current_tick - playstart_tick;
|
|
|
|
}
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mp3_play_stop(void)
|
|
|
|
{
|
2004-01-10 15:39:56 +00:00
|
|
|
playing = false;
|
2004-01-05 20:42:51 +00:00
|
|
|
mp3_play_pause(false);
|
|
|
|
CHCR3 &= ~0x0001; /* Disable the DMA interrupt */
|
2004-09-29 19:51:41 +00:00
|
|
|
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
|
2004-01-10 15:39:56 +00:00
|
|
|
demand_irq_enable(false);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
long mp3_get_playtime(void)
|
|
|
|
{
|
|
|
|
if (paused)
|
|
|
|
return cumulative_ticks;
|
|
|
|
else
|
|
|
|
return cumulative_ticks + current_tick - playstart_tick;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mp3_reset_playtime(void)
|
|
|
|
{
|
|
|
|
cumulative_ticks = 0;
|
|
|
|
playstart_tick = current_tick;
|
2004-01-05 20:42:51 +00:00
|
|
|
}
|
2004-01-05 23:42:56 +00:00
|
|
|
|
2004-01-30 22:30:40 +00:00
|
|
|
|
|
|
|
bool mp3_is_playing(void)
|
|
|
|
{
|
|
|
|
return playing;
|
|
|
|
}
|
|
|
|
|
2004-03-21 17:45:45 +00:00
|
|
|
|
|
|
|
/* returns the next byte position which would be transferred */
|
|
|
|
unsigned char* mp3_get_pos(void)
|
|
|
|
{
|
|
|
|
return (unsigned char*)SAR3;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-08 09:53:53 +00:00
|
|
|
#endif /* #ifndef SIMULATOR */
|