Wavebubble 2010 Firmware
|
00001 00007 #include <avr/io.h> 00008 #include <avr/pgmspace.h> 00009 #include "pll.h" 00010 #include "main.h" 00011 #include "serial.h" 00012 00019 void pll_init(void) { 00020 uint32_t out; 00021 00022 ADCSRA = _BV(ADSC) | _BV(ADEN) | _BV(ADPS1) | _BV(ADPS2); 00023 00024 PLLCLK_DDR |= _BV(PLLCLK); 00025 PLLDATA_DDR |= _BV(PLLDATA); 00026 PLLLE_DDR |= _BV(PLLLE); 00027 PLL_IFIN_DDR &= ~_BV(PLL_IFIN); 00028 PLL_RFIN_DDR &= ~_BV(PLL_RFIN); 00029 PLL_IFIN_PORT &= ~_BV(PLL_IFIN); 00030 PLL_RFIN_PORT &= ~_BV(PLL_RFIN); 00031 00032 pll_tx(0x0, 0x2); // dont use general purpose pins, no fastlock 00033 pll_tx(0x0, 0x5); // dont use general purpose pins, no fastlock 00034 00035 // setup 1MHz reference clock 00036 out = 3; out <<= 19; out |= (10&0x7FFF); 00037 pll_tx(out, 0x3); // no otherbits set: defaults 00038 out = 3; out <<= 19; out |= (10&0x7FFF); 00039 pll_tx(out, 0x0); // no otherbits set: defaults 00040 } 00041 00049 void pll_tx(uint32_t data, uint8_t addr) { 00050 uint8_t i; 00051 00052 if (addr > 5) return; 00053 00054 data <<= 3; 00055 data |= (addr & 0x7); 00056 data <<= 8; 00057 00058 PLLLE_PORT &= ~_BV(PLLLE); 00059 PLLDATA_PORT &= ~_BV(PLLDATA); 00060 PLLCLK_PORT &= ~_BV(PLLCLK); 00061 00062 for (i=0; i<24; i++) { 00063 PLLCLK_PORT &= ~_BV(PLLCLK); 00064 if (data & 0x80000000) { 00065 PLLDATA_PORT |= _BV(PLLDATA); 00066 } else { 00067 PLLDATA_PORT &= ~_BV(PLLDATA); 00068 } 00069 asm volatile ("nop"); 00070 asm volatile ("nop"); 00071 asm volatile ("nop"); 00072 PLLCLK_PORT |= _BV(PLLCLK); 00073 asm volatile ("nop"); 00074 asm volatile ("nop"); 00075 asm volatile ("nop"); 00076 data <<= 1; 00077 } 00078 PLLLE_PORT |= _BV(PLLLE); 00079 asm volatile ("nop"); 00080 asm volatile ("nop"); 00081 asm volatile ("nop"); 00082 PLLLE_PORT &= ~_BV(PLLLE); 00083 PLLDATA_PORT &= ~_BV(PLLDATA); 00084 PLLCLK_PORT &= ~_BV(PLLCLK); 00085 } 00086 00087 00094 void pll_set_rcounter(uint16_t rcounter) { 00095 pll_tx((rcounter&0x7FFF), 0x0); // no otherbits set: defaults 00096 pll_tx((rcounter&0x7FFF), 0x3); // no otherbits set: defaults 00097 } 00098 00099 00100 void pll_set_freq(uint16_t rf_freq, uint8_t prescaler, uint8_t reg) { 00101 uint16_t N; 00102 uint16_t B, A; 00103 uint32_t out=0; 00104 00105 if ((prescaler != 8) && (prescaler != 16)) 00106 prescaler = 8; 00107 00108 // Fin = N*fcomp 00109 N = rf_freq; // fcomp = 1MHz 00110 // N = (P*B) + A 00111 if (prescaler == 8) { 00112 B = N / 8; 00113 A = N % 8; 00114 } else { 00115 B = N / 16; 00116 A = N % 16; 00117 } 00118 00119 pc_puts_P(PSTR("PLL for RF freq ")); putnum_ud(N); 00120 pc_puts_P(PSTR("MHz & prescaler ")); putnum_ud(prescaler); 00121 pc_puts_P(PSTR(": B=")); putnum_ud(B); 00122 pc_puts_P(PSTR(" A=")); putnum_ud(A); 00123 pc_putc('\n'); 00124 00125 if (prescaler == 16) 00126 out = 1; // 16 prescale 00127 out <<= 15; 00128 out |= B; out<<= 4; 00129 out |= A&0xF; 00130 pll_tx(out, reg); 00131 } 00132 00142 uint8_t tune_rf(uint16_t freq) { 00143 uint16_t i=0, low, high; 00144 00145 pll_set_rf(freq, 8); 00146 00147 set_resistor(BANDWADJ1_RES, 0); 00148 POWERCTL1_PORT |= _BV(POWERCTL1); // turn on vco 00149 00150 OCR1A = 0; 00151 delay_ms(500); 00152 00153 if (PLL_RFIN_PIN & _BV(PLL_RFIN)) { // we cant tune any lower...??? 00154 pc_puts_P(PSTR("RF VCO range is too high!\n")); 00155 return 0; 00156 } 00157 OCR1A = 4095; 00158 delay_ms(500); 00159 00160 if (! (PLL_RFIN_PIN & _BV(PLL_RFIN))) { // we cant tune any higher...??? 00161 pc_puts_P(PSTR("RF VCO range is too low!\n")); 00162 return 0; 00163 } 00164 00165 pc_puts_P(PSTR("midpoint @ ")); 00166 low = 0; 00167 high = 4095; 00168 while ((low + 2) <= high) { 00169 //putnum_ud(low); uart_putchar('/'); putnum_ud(high); uart_putchar('\t'); 00170 i = ((uint16_t)low+(uint16_t)high)/2; 00171 OCR1A = i; 00172 //putnum_ud(OCR1A); pc_puts(", "); 00173 delay_ms(500); 00174 if (PLL_RFIN_PIN & _BV(PLL_RFIN)) { 00175 delay_ms(1); 00176 if (PLL_RFIN_PIN & _BV(PLL_RFIN)) { 00177 high = i; 00178 } 00179 } else { 00180 low = i; 00181 } 00182 } 00183 putnum_ud(i); pc_putc('\n'); 00184 return i; 00185 } 00186 00196 uint8_t tune_if(uint16_t freq) { 00197 uint16_t i=0, low, high; 00198 00199 pll_set_if(freq, 8); 00200 00201 set_resistor(BANDWADJ2_RES, 0); 00202 POWERCTL2_PORT |= _BV(POWERCTL2); // turn on vco 00203 00204 OCR1B = 0; 00205 delay_ms(500); 00206 00207 if (PLL_IFIN_PIN & _BV(PLL_IFIN)) { // we cant tune any lower...??? 00208 pc_puts_P(PSTR("IF VCO range is too high!\n")); 00209 return 0; 00210 } 00211 00212 OCR1B = 4095; 00213 delay_ms(500); 00214 00215 if (! (PLL_IFIN_PIN & _BV(PLL_IFIN))) { // we cant tune any higher...??? 00216 pc_puts_P(PSTR("IF VCO range is too low!\n")); 00217 return 0; 00218 } 00219 00220 pc_puts_P(PSTR("midpoint @ ")); 00221 low = 0; 00222 high = 4095; 00223 while ((low + 2) <= high) { 00224 i = ((uint16_t)low+(uint16_t)high)/2; 00225 OCR1B = i; 00226 //putnum_ud(OCR1B); pc_puts(", "); 00227 delay_ms(500); 00228 if (PLL_IFIN_PIN & _BV(PLL_IFIN)) { 00229 delay_ms(1); 00230 if (PLL_IFIN_PIN & _BV(PLL_IFIN)) { 00231 high = i; 00232 } 00233 } else { 00234 low = i; 00235 } 00236 } 00237 putnum_ud(i); pc_putc('\n'); 00238 return i; 00239 } 00240 00250 uint8_t tune_rf_band(uint16_t min, uint16_t max, uint8_t vco_num) { 00251 uint16_t threshhold, midpt; 00252 uint32_t avg; 00253 uint8_t i=0, j, low, high; 00254 00255 // Check and correct possible frequency mismatch 00256 if (min > max) { 00257 midpt = max; 00258 max = min; 00259 min = midpt; 00260 } 00261 00262 // Check for single frequency 00263 if( min == max) 00264 midpt = min; 00265 else 00266 midpt = (min+max)/2; 00267 00268 if (vco_num == 0) 00269 midpt = tune_rf(midpt); 00270 else 00271 midpt = tune_if(midpt); 00272 00273 if ((midpt == 0) || (min == max)) // start in the middle 00274 return 0; 00275 00276 pc_puts_P(PSTR("\nbandwidth tuning...\n")); 00277 00278 if (vco_num==0) 00279 pll_set_rf(min, 8) 00280 else 00281 pll_set_if(min, 8); 00282 00283 set_sawtooth_low(); 00284 00285 // get high vals? 00286 if (vco_num == 0) { 00287 set_resistor(BANDWADJ1_RES, 0); 00288 ADMUX = 0; 00289 } else { 00290 set_resistor(BANDWADJ2_RES, 0); 00291 ADMUX = 5; 00292 } 00293 delay_ms(100); 00294 avg = 0; 00295 for (j = 0; j < 127; j++) { 00296 ADCSRA |= _BV(ADSC); 00297 while (ADCSRA & _BV(ADSC)); // wait for conversion to finish; 00298 avg += ADC; 00299 //putnum_ud(t); pc_putc(' '); 00300 } 00301 avg /= 128; 00302 threshhold = avg; 00303 //pc_puts("thres = "); putnum_ud(threshhold); pc_putc('\n'); 00304 00305 low = 0; 00306 high = 255; 00307 while ((low + 2) <= high) { 00308 i = ((uint16_t)low+(uint16_t)high)/2; 00309 // set the bandwidth 00310 if (vco_num == 0) 00311 set_resistor(BANDWADJ1_RES, i); 00312 else 00313 set_resistor(BANDWADJ2_RES, i); 00314 //putnum_ud(i); pc_puts(", "); 00315 delay_ms(500); 00316 00317 // read ADC 00318 00319 if (vco_num == 0) 00320 ADMUX = 0; 00321 else 00322 ADMUX = 5; 00323 00324 avg = 0; 00325 for (j = 0; j < 127; j++) { 00326 ADCSRA |= _BV(ADSC); 00327 while (ADCSRA & _BV(ADSC)); // wait for conversion to finish; 00328 avg += ADC; 00329 //putnum_ud(t); uart_putchar(' '); 00330 } 00331 avg /= 128; 00332 //putnum_ud(avg); pc_putc('\n'); 00333 if (avg < (threshhold-10)) { 00334 high = i; 00335 } else { 00336 low = i; 00337 } 00338 } 00339 putnum_ud(i); 00340 pc_puts_P(PSTR(" done!\n")); 00341 set_sawtooth_high(); 00342 return i; 00343 }