1
0
Fork 0
forked from len0rd/rockbox

Sansa AMS: allow use of PLL B for more accurate audio sample rate (0.04% instead 0.15% error)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24211 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Bertrik Sikken 2010-01-10 14:24:45 +00:00
parent 25972b63e6
commit ba9040a82b
3 changed files with 34 additions and 11 deletions

View file

@ -52,7 +52,7 @@
/* Clock Sources */ /* Clock Sources */
#define AS3525_CLK_MAIN 0 #define AS3525_CLK_MAIN 0
#define AS3525_CLK_PLLA 1 #define AS3525_CLK_PLLA 1
//#define AS3525_CLK_PLLB 2 #define AS3525_CLK_PLLB 2
#define AS3525_CLK_FCLK 3 /* Available as PCLK input only */ #define AS3525_CLK_FCLK 3 /* Available as PCLK input only */
/** ************ Change these to reconfigure clocking scheme *******************/ /** ************ Change these to reconfigure clocking scheme *******************/
@ -70,6 +70,10 @@
/* *5/8 = 155MHz 77.5, 51.67, 38.75 */ /* *5/8 = 155MHz 77.5, 51.67, 38.75 */
#define AS3525_PLLA_SETTING 0x261F #define AS3525_PLLA_SETTING 0x261F
/* PLLB frequencies and settings (audio and USB) */
#define AS3525_PLLB_FREQ 384000000 /* allows 44.1kHz with 0.04% error*/
#define AS3525_PLLB_SETTING 0x2630
#endif /* SANSA_CLIPV2 */ #endif /* SANSA_CLIPV2 */
//#define AS3525_PLLA_FREQ 384000000 /*192,128,96,76.8,64,54.9,48,42.7,38.4*/ //#define AS3525_PLLA_FREQ 384000000 /*192,128,96,76.8,64,54.9,48,42.7,38.4*/
@ -107,6 +111,16 @@
#define AS3525_FCLK_SEL AS3525_CLK_PLLA #define AS3525_FCLK_SEL AS3525_CLK_PLLA
#define AS3525_FCLK_POSTDIV (CLK_DIV((AS3525_PLLA_FREQ*(8-AS3525_FCLK_PREDIV)/8), AS3525_FCLK_FREQ) - 1) /*div=1/(n+1)*/ #define AS3525_FCLK_POSTDIV (CLK_DIV((AS3525_PLLA_FREQ*(8-AS3525_FCLK_PREDIV)/8), AS3525_FCLK_FREQ) - 1) /*div=1/(n+1)*/
/* MCLK */
#define AS3525_MCLK_SEL AS3525_CLK_PLLA
#if (AS3525_MCLK_SEL==AS3525_CLK_PLLA)
#define AS3525_MCLK_FREQ AS3525_PLLA_FREQ
#elif (AS3525_MCLK_SEL==AS3525_CLK_PLLB)
#define AS3525_MCLK_FREQ AS3525_PLLB_FREQ
#else
#error Choose either PLLA or PLLB for MCLK!
#endif
/* PCLK */ /* PCLK */
#ifdef ASYNCHRONOUS_BUS #ifdef ASYNCHRONOUS_BUS
#define AS3525_PCLK_SEL AS3525_CLK_PLLA /* PLLA input for asynchronous */ #define AS3525_PCLK_SEL AS3525_CLK_PLLA /* PLLA input for asynchronous */
@ -169,12 +183,12 @@
/* I2SIN / I2SOUT frequencies */ /* I2SIN / I2SOUT frequencies */
/* low samplerate */ /* low samplerate */
#if ((AS3525_PLLA_FREQ/(128*8000))) > 512 /* 8kHz = lowest frequency */ #if ((AS3525_MCLK_FREQ/(128*8000))) > 512 /* 8kHz = lowest frequency */
#error PLLA frequency is too low for 8kHz samplerate ! #error AS3525_MCLK_FREQ is too high for 8kHz samplerate !
#endif #endif
/* high samplerate */ /* high samplerate */
#if ((AS3525_PLLA_FREQ/(128*96000))) < 1 /* 96kHz = highest frequency */ #if ((AS3525_MCLK_FREQ/(128*96000))) < 1 /* 96kHz = highest frequency */
#error PLLA frequency is too high for 96kHz samplerate ! #error AS3525_MCLK_FREQ is too low for 96kHz samplerate !
#endif #endif
#endif /* CLOCK_TARGET_H */ #endif /* CLOCK_TARGET_H */

View file

@ -139,11 +139,13 @@ void pcm_dma_apply_settings(void)
unsigned long frequency = pcm_sampr; unsigned long frequency = pcm_sampr;
/* TODO : use a table ? */ /* TODO : use a table ? */
const int divider = (((AS3525_PLLA_FREQ/128) + (frequency/2)) / frequency) - 1; const int divider = ((AS3525_MCLK_FREQ/128) + (frequency/2)) / frequency;
int cgu_audio = CGU_AUDIO; /* read register */ int cgu_audio = CGU_AUDIO; /* read register */
cgu_audio &= ~(3 << 0); /* clear i2sout MCLK_SEL */
cgu_audio |= (AS3525_MCLK_SEL << 0); /* set i2sout MCLK_SEL */
cgu_audio &= ~(511 << 2); /* clear i2sout divider */ cgu_audio &= ~(511 << 2); /* clear i2sout divider */
cgu_audio |= divider << 2; /* set new i2sout divider */ cgu_audio |= (divider - 1) << 2; /* set new i2sout divider */
CGU_AUDIO = cgu_audio; /* write back register */ CGU_AUDIO = cgu_audio; /* write back register */
} }
@ -318,13 +320,13 @@ void pcm_rec_dma_init(void)
unsigned long frequency = pcm_sampr; unsigned long frequency = pcm_sampr;
/* TODO : use a table ? */ /* TODO : use a table ? */
const int divider = (((AS3525_PLLA_FREQ/128) + (frequency/2)) / frequency) - 1; const int divider = ((AS3525_MCLK_FREQ/128) + (frequency/2)) / frequency;
int cgu_audio = CGU_AUDIO; /* read register */ int cgu_audio = CGU_AUDIO; /* read register */
cgu_audio &= ~(3 << 12); /* clear i2sin clocksource */ cgu_audio &= ~(3 << 12); /* clear i2sin MCLK_SEL */
cgu_audio |= (1 << 12); /* set to PLLA */ cgu_audio |= (AS3525_MCLK_SEL << 12); /* set i2sin MCLK_SEL */
cgu_audio &= ~(511 << 14); /* clear i2sin divider */ cgu_audio &= ~(511 << 14); /* clear i2sin divider */
cgu_audio |= divider << 14; /* set new i2sin divider */ cgu_audio |= (divider - 1) << 14; /* set new i2sin divider */
CGU_AUDIO = cgu_audio; /* write back register */ CGU_AUDIO = cgu_audio; /* write back register */
} }

View file

@ -285,8 +285,15 @@ void system_init(void)
CGU_PROC = 0; /* fclk 24 MHz */ CGU_PROC = 0; /* fclk 24 MHz */
CGU_PERI &= ~0x7f; /* pclk 24 MHz */ CGU_PERI &= ~0x7f; /* pclk 24 MHz */
CGU_PLLASUP = 0; /* enable PLLA */
CGU_PLLA = AS3525_PLLA_SETTING; CGU_PLLA = AS3525_PLLA_SETTING;
while(!(CGU_INTCTRL & (1<<0))); /* wait until PLLA is locked */ while(!(CGU_INTCTRL & (1<<0))); /* wait until PLLA is locked */
#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB)
CGU_PLLBSUP = 0; /* enable PLLB */
CGU_PLLB = AS3525_PLLB_SETTING;
while(!(CGU_INTCTRL & (1<<1))); /* wait until PLLB is locked */
#endif
/* Set FCLK frequency */ /* Set FCLK frequency */
CGU_PROC = ((AS3525_FCLK_POSTDIV << 4) | CGU_PROC = ((AS3525_FCLK_POSTDIV << 4) |