comparison core/I2c_Codec.cpp @ 142:d064234468cd

Added I2c methods to set R and P values for the PLL
author Giulio Moro <giuliomoro@yahoo.it>
date Mon, 14 Sep 2015 17:31:24 +0100
parents 09a32ca96255
children 8ff5668bbbad
comparison
equal deleted inserted replaced
134:09a32ca96255 142:d064234468cd
38 // See the TLV320AIC3106 datasheet for full details of the registers 38 // See the TLV320AIC3106 datasheet for full details of the registers
39 // The dual_rate flag, when true, runs the codec at 88.2kHz; otherwise 39 // The dual_rate flag, when true, runs the codec at 88.2kHz; otherwise
40 // it runs at 44.1kHz 40 // it runs at 44.1kHz
41 int I2c_Codec::startAudio(int dual_rate) 41 int I2c_Codec::startAudio(int dual_rate)
42 { 42 {
43 // see datasehet for TLV320AIC3104 from page 44
43 if(writeRegister(0x02, 0x00)) // Codec sample rate register: fs_ref / 1 44 if(writeRegister(0x02, 0x00)) // Codec sample rate register: fs_ref / 1
44 return 1; 45 return 1;
45 if(writeRegister(0x03, 0x91)) // PLL register A: enable 46 // if(writeRegister(0x03, 0x91)) // PLL register A: enable
47 // return 1;
48 if(setPllP(1))
46 return 1; 49 return 1;
47 // if(writeRegister(0x04, 0x1C)) // PLL register B 50 // if(writeRegister(0x04, 0x1C)) // PLL register B
48 // return 1; 51 // return 1;
49 // if(writeRegister(0x05, 0x52)) // PLL register C 52 // if(writeRegister(0x05, 0x52)) // PLL register C
50 // return 1; 53 // return 1;
66 return 1; 69 return 1;
67 if(writeRegister(0x09, 0x40)) // Audio serial control register B: DSP mode, word len 16 bits 70 if(writeRegister(0x09, 0x40)) // Audio serial control register B: DSP mode, word len 16 bits
68 return 1; 71 return 1;
69 if(writeRegister(0x0A, 0x00)) // Audio serial control register C: 0 bit offset 72 if(writeRegister(0x0A, 0x00)) // Audio serial control register C: 0 bit offset
70 return 1; 73 return 1;
71 if(writeRegister(0x0B, 0x01)) // Audio codec overflow flag register: PLL R = 1 74 // if(writeRegister(0x0B, 0x01)) // Audio codec overflow flag register: PLL R = 1
75 // return 1;
76 if(setPllR(1))
72 return 1; 77 return 1;
73 if(writeRegister(0x0C, 0x00)) // Digital filter register: disabled 78 if(writeRegister(0x0C, 0x00)) // Digital filter register: disabled
74 return 1; 79 return 1;
75 if(writeRegister(0x0D, 0x00)) // Headset / button press register A: disabled 80 if(writeRegister(0x0D, 0x00)) // Headset / button press register A: disabled
76 return 1; 81 return 1;
94 return 1; 99 return 1;
95 100
96 if(writeHPVolumeRegisters()) // Send DAC to high-power outputs 101 if(writeHPVolumeRegisters()) // Send DAC to high-power outputs
97 return 1; 102 return 1;
98 103
99 if(writeRegister(0x66, 0x02)) // Clock generation control register: use MCLK, PLL N = 2 104 if(writeRegister(0x66, 0x02)) // Clock generation control register: use MCLK, PLL N = 2
100 return 1; 105 return 1;
101 106
102 if(writeRegister(0x33, 0x0D)) // HPLOUT output level control: output level = 0dB, not muted, powered up 107 if(writeRegister(0x33, 0x0D)) // HPLOUT output level control: output level = 0dB, not muted, powered up
103 return 1; 108 return 1;
104 if(writeRegister(0x41, 0x0D)) // HPROUT output level control: output level = 0dB, not muted, powered up 109 if(writeRegister(0x41, 0x0D)) // HPROUT output level control: output level = 0dB, not muted, powered up
160 } 165 }
161 pllD=d; 166 pllD=d;
162 return 0; 167 return 0;
163 } 168 }
164 169
170 //set integer part of the numerator mutliplier of the PLL
171 //
172 int I2c_Codec::setPllP(short unsigned int p){
173 if(p > 8 || p < 1){
174 return 1;
175 }
176 short unsigned int bits = 0;
177 bits |= 1 << 7; //this means PLL enabled
178 bits |= 0b0010 << 3; // this is the reset value for Q, which is anyhow unused when PLL is active
179 if (p == 8) // 8 is a special value: PLL P Value 000: P = 8
180 bits = bits | 0;
181 else
182 bits = bits | p; // other values are written with their binary representation.
183 if(writeRegister(0x03, bits)){ // PLL register B: j<<2
184 printf("I2C error while writing PLL p: %d", p);
185 return 1;
186 }
187 pllP = p;
188 return 0;
189 }
190 int I2c_Codec::setPllR(unsigned int r){
191 if(r > 16){ //value out of range
192 return 1;
193 }
194 unsigned int bits = 0;
195 //bits D7-D4 are for ADC and DAC overflow flags and are read only
196 if(r == 16) // 16 is a special value: PLL R Value 0000: R = 16
197 bits |= 0;
198 else
199 bits |= r; // other values are written with their binary representation.
200 if(writeRegister(0x0B, bits)){ // PLL register B: j<<2
201 printf("I2C error while writing PLL r: %d", r);
202 return 1;
203 }
204 pllR = r;
205 return 0;
206 }
165 int I2c_Codec::setAudioSamplingRate(float newSamplingRate){ 207 int I2c_Codec::setAudioSamplingRate(float newSamplingRate){
166 int pllP=1; //TODO: create get/set for pllP and pllR 208 int pllP=getPllP(); //TODO: create get/set for pllP and pllR
167 int pllR=1; 209 int pllR=1;
168 long int PLLCLK_IN=12000000; 210 long int PLLCLK_IN=12000000;
169 // f_{S(ref)} = (PLLCLK_IN × K × R)/(2048 × P) 211 // f_{S(ref)} = (PLLCLK_IN × K × R)/(2048 × P)
170 float k = ((double)(newSamplingRate * pllP * 2048.0f/(float)pllR)) / PLLCLK_IN ; 212 float k = ((double)(newSamplingRate * pllP * 2048.0f/(float)pllR)) / PLLCLK_IN ;
171 return (setPllK(k)); 213 return (setPllK(k));
174 short unsigned int I2c_Codec::getPllJ(){ 216 short unsigned int I2c_Codec::getPllJ(){
175 return pllJ; 217 return pllJ;
176 } 218 }
177 unsigned int I2c_Codec::getPllD(){ 219 unsigned int I2c_Codec::getPllD(){
178 return pllD; 220 return pllD;
221 }
222 unsigned int I2c_Codec::getPllR(){
223 return pllR;
224 }
225 unsigned int I2c_Codec::getPllP(){
226 return pllP;
179 } 227 }
180 float I2c_Codec::getPllK(){ 228 float I2c_Codec::getPllK(){
181 float j=getPllJ(); 229 float j=getPllJ();
182 float d=getPllD(); 230 float d=getPllD();
183 float k=j+d/10000.0f; 231 float k=j+d/10000.0f;