Mercurial > hg > beaglert
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; |