changeset 134:09a32ca96255

Fixed and improved I2c_codec. Copied from the scope-refactoring branch
author Giulio Moro <giuliomoro@yahoo.it>
date Thu, 27 Aug 2015 03:39:11 +0100
parents 836052c86e1e
children d064234468cd
files core/I2c_Codec.cpp include/I2c_Codec.h
diffstat 2 files changed, 49 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/core/I2c_Codec.cpp	Tue Aug 18 00:13:04 2015 +0100
+++ b/core/I2c_Codec.cpp	Thu Aug 27 03:39:11 2015 +0100
@@ -44,11 +44,15 @@
 		return 1;
 	if(writeRegister(0x03, 0x91))	// PLL register A: enable
 		return 1;
-	if(writeRegister(0x04, 0x1C))	// PLL register B
+//	if(writeRegister(0x04, 0x1C))	// PLL register B
+//		return 1;
+//	if(writeRegister(0x05, 0x52))	// PLL register C
+//		return 1;
+//	if(writeRegister(0x06, 0x40))	// PLL register D
+//		return 1;
+	if(setPllD(5264)) //7.5264 gives 44.1kHz nominal value with a 12MHz master clock
 		return 1;
-	if(writeRegister(0x05, 0x52))	// PLL register C
-		return 1;
-	if(writeRegister(0x06, 0x40))	// PLL register D
+	if(setPllJ(7))
 		return 1;
 	if(dual_rate) {
 		if(writeRegister(0x07, 0xEA))	// Codec datapath register: 44.1kHz; dual rate; standard datapath
@@ -120,7 +124,7 @@
 //set the numerator multiplier for the PLL
 int I2c_Codec::setPllK(float k){
 	short unsigned int j=(int)k;
-	unsigned int d=(k-j+0.5)*10000; //fractionary part, between 0 and 9999
+	unsigned int d=(int)(0.5+(k-j)*10000); //fractional part, between 0 and 9999
 	if(setPllJ(j)>0)
 		return 1;
 	if(setPllD(d)>0)
@@ -138,6 +142,7 @@
 		printf("I2C error while writing PLL j: %d", j);
 		return 1;
 	}
+	pllJ=j;
 	return 0;
 }
 
@@ -153,8 +158,40 @@
 		printf("I2C error while writing PLL d part 2 : %d", d);
 		return 1;
 	}
+	pllD=d;
 	return 0;
 }
+
+int I2c_Codec::setAudioSamplingRate(float newSamplingRate){
+	int pllP=1; //TODO: create get/set for pllP and pllR
+	int pllR=1;
+	long int PLLCLK_IN=12000000;
+	//	f_{S(ref)} = (PLLCLK_IN × K × R)/(2048 × P)
+	float k = ((double)(newSamplingRate * pllP * 2048.0f/(float)pllR)) / PLLCLK_IN ;
+	return (setPllK(k));
+}
+
+short unsigned int I2c_Codec::getPllJ(){
+	return pllJ;
+}
+unsigned int I2c_Codec::getPllD(){
+	return pllD;
+}
+float I2c_Codec::getPllK(){
+	float j=getPllJ();
+	float d=getPllD();
+	float k=j+d/10000.0f;
+	return k;
+}
+
+float I2c_Codec::getAudioSamplingRate(){
+	int pllP=1; //TODO: create get/set for pllP and pllR
+	int pllR=1;
+	long int PLLCLK_IN=12000000;
+	//	f_{S(ref)} = (PLLCLK_IN × K × R)/(2048 × P)
+	float fs = (PLLCLK_IN/2048.0f) * getPllK()*pllR/(float)pllP;
+	return fs;
+}
 // Set the volume of the DAC output
 int I2c_Codec::setDACVolume(int halfDbSteps)
 {
--- a/include/I2c_Codec.h	Tue Aug 18 00:13:04 2015 +0100
+++ b/include/I2c_Codec.h	Thu Aug 27 03:39:11 2015 +0100
@@ -21,6 +21,8 @@
 
 class I2c_Codec : public I2c
 {
+	short unsigned int pllJ;
+	short unsigned int pllD;
 public:
 	int writeRegister(unsigned int reg, unsigned int value);
 
@@ -31,6 +33,11 @@
 	int setPllJ(short unsigned int j);
 	int setPllD(unsigned int d);
 	int setPllK(float k);
+	int setAudioSamplingRate(float newSamplingRate);
+	short unsigned int getPllJ();
+	unsigned int getPllD();
+	float getPllK();
+	float getAudioSamplingRate();
 	int setDACVolume(int halfDbSteps);
 	int writeDACVolumeRegisters(bool mute);
 	int setADCVolume(int halfDbSteps);