mbed code for Farrari board
Dependencies: DDRO_Farrari mbed
Fork of DDRO_Farrari by
pll.cpp
00001 #include "pll.h" 00002 00003 unsigned long long calc_pll_freqs(unsigned int prediv, unsigned int multint_upper, unsigned int multint, 00004 unsigned int range_upper, unsigned int rangea, unsigned int rangeb){ 00005 00006 if(prediv < 1 || prediv > 32){ 00007 pc.printf("Prediv out of 1-32 range\r\n"); 00008 } 00009 if(multint_upper < 1 || multint_upper > 4){ 00010 pc.printf("Multint_upper out of 1-4 range\r\n"); 00011 } 00012 if(multint < 1 || multint > 255){ 00013 pc.printf("Multint out of 1-255 range\r\n"); 00014 } 00015 if(multint_upper * multint > 255){ 00016 pc.printf("Multint_upper * Multint out of 1-255 range\r\n"); 00017 } 00018 if(!(range_upper == 1 || range_upper == 2 || range_upper == 4)){ 00019 pc.printf("Range_upper out of 1,2,4 range\r\n"); 00020 } 00021 if(rangea < 1 || rangea > 32){ 00022 pc.printf("RangeA out of 1-32 range\r\n"); 00023 } 00024 if(rangeb < 1 || rangeb > 32){ 00025 pc.printf("RangeB out of 1-32 range\r\n"); 00026 } 00027 00028 int dco = (PLL_REF / prediv) * multint_upper * multint; 00029 if(dco < 2500000 || dco > 5000000){ 00030 pc.printf("Dco=%d out of 2.5G-5G range\r\n",dco); 00031 } 00032 int internal = dco / multint_upper; 00033 if(internal < 9800 || internal > 3200000){ 00034 pc.printf("internal=%d out of 9.8M-3.2G range\r\n",internal); 00035 } 00036 int prescale_dco = dco / range_upper; 00037 if(prescale_dco > 3200000){ 00038 pc.printf("Prescale DCO out of 0-3.2G range\r\n"); 00039 } 00040 int out_a = prescale_dco / rangea; 00041 if(out_a < 20000 || out_a > 3000000){ 00042 pc.printf("Out A out of 20M-3.0G range\r\n"); 00043 } 00044 int out_b = prescale_dco / rangeb; 00045 if(out_b < 20000 || out_b > 3000000){ 00046 pc.printf("Out B out of 20M-3.0G range\r\n"); 00047 } 00048 00049 return out_a; 00050 } 00051 00052 int get_binline_by_num(char* filename, int linenum){ 00053 char value[30]; 00054 00055 //pc.printf("Opening %s File\r\n", filename); 00056 FILE *fp = fopen(filename, "r"); 00057 if(!fp){ 00058 pc.printf("ERROR: %s not found\r\n", filename); 00059 } 00060 //pc.printf("%s Open\r\n", filename); 00061 00062 int i=1; 00063 char lineval[255]; 00064 while (!feof(fp)) { 00065 fscanf(fp, "%s", lineval); 00066 if(i == linenum){ 00067 strcpy(value, lineval); 00068 break; 00069 } 00070 i++; 00071 } 00072 00073 //pc.printf("Closing %s File\r\n", filename); 00074 fclose(fp); 00075 //pc.printf("File %s Closed\r\n", filename); 00076 00077 return strtol(value, NULL, 2); 00078 } 00079 00080 void scan_pll(unsigned int prediv, unsigned int multint_upper, unsigned int multint, 00081 unsigned int range_upper, unsigned int rangea, unsigned int rangeb){ 00082 00083 prediv = get_binline_by_num("/local/Pprediv.txt", prediv); 00084 multint_upper = get_binline_by_num("/local/Pmultup.txt", multint_upper); 00085 multint = get_binline_by_num("/local/Pmultint.txt", multint); 00086 range_upper = get_binline_by_num("/local/Prangeup.txt", range_upper); 00087 rangea = get_binline_by_num("/local/Prange.txt", rangea); 00088 rangeb = get_binline_by_num("/local/Prange.txt", rangeb); 00089 00090 set_scan_bits("PLL_CE1CCB", 1); 00091 set_scan_bits("PLL_CE1MPGC1", 1); 00092 set_scan_bits("PLL_FFTUNE", fftune(0)); 00093 set_scan_bits("PLL_LFTUNE", lftune()); // @@@ Fix this. Scan doesn't support more than 32 bits 00094 set_scan_bits("PLL_INTFBK", 1); 00095 set_scan_bits("PLL_PREDIV", prediv); 00096 set_scan_bits("PLL_MULTINT", multint_upper << 8 | multint); 00097 set_scan_bits("PLL_RANGEA", range_upper << 5 | rangea); 00098 set_scan_bits("PLL_RANGEB", range_upper << 5 | rangeb); 00099 } 00100 00101 void jtag_pll(JTAG &jtag, unsigned int prediv, unsigned int multint_upper, unsigned int multint, 00102 unsigned int range_upper, unsigned int rangea, unsigned int rangeb){ 00103 00104 prediv = get_binline_by_num("/local/Pprediv.txt", prediv); 00105 multint_upper = get_binline_by_num("/local/Pmultup.txt", multint_upper); 00106 multint = get_binline_by_num("/local/Pmultint.txt", multint); 00107 range_upper = get_binline_by_num("/local/Prangeup.txt", range_upper); 00108 rangea = get_binline_by_num("/local/Prange.txt", rangea); 00109 rangeb = get_binline_by_num("/local/Prange.txt", rangeb); 00110 jtag.writeMemory(PLL_CE1CCB, 1); 00111 jtag.writeMemory(PLL_CE1MPGC1, 1); 00112 jtag.writeMemory(PLL_FFTUNE, fftune(0)); 00113 jtag.writeMemory(PLL_LFTUNE_32_0, lftune_lo()); 00114 jtag.writeMemory(PLL_LFTUNE_40_32, lftune_hi()); 00115 jtag.writeMemory(PLL_INTFBK, 1); 00116 jtag.writeMemory(PLL_PREDIV, prediv); 00117 jtag.writeMemory(PLL_RANGEA, range_upper << 5 | rangea); 00118 jtag.writeMemory(PLL_RANGEB, range_upper << 5 | rangeb); 00119 jtag.writeMemory(PLL_MULTINT, multint_upper << 8 | multint); 00120 } 00121 00122 00123 unsigned int fftune(bool change_rangeab){ 00124 if(change_rangeab){ 00125 return 0x0120; 00126 }else{ 00127 return 0x0100; 00128 } 00129 } 00130 00131 unsigned int lftune_hi(){ 00132 return 0x00000050; 00133 } 00134 00135 unsigned int lftune_lo(){ 00136 return 0x40100000; 00137 } 00138 00139 unsigned long long lftune(){ 00140 // 41 bits 00141 return 0x05040100000L; 00142 } 00143 00144 /* 00145 unsigned long long calc_pll_freqs(unsigned int prediv, unsigned int multint_upper, unsigned int multint, 00146 unsigned int range_upper, unsigned int rangea, unsigned int rangeb) 00147 dco = (PLL_REF / prediv) * multint_upper * multint; 00148 prescale_dco = dco / range_upper; 00149 out_a = prescale_dco / rangea; 00150 */ 00151 int set_pll_frequency (int fMHz, JTAG &jtag) { 00152 jtag.writeMemory(intclk_source, 0); 00153 int counter = fMHz / 5; 00154 int frequency = counter * 5; 00155 if (frequency >= 625) { 00156 pc.printf("Frequency > 625 MHz out of range!\r\nClock source changed to HCLK_EXT\r\n"); 00157 return 1; 00158 } /* 00159 else if (frequency >= 625) { 00160 //counter between 125 and 200 00161 // 20*125/4=625 00162 // 20*200/4=1G 00163 jtag_pll(jtag, 1, 1, counter, 1, 4, 4); 00164 calculated_f = calc_pll_freqs(1, 1, counter, 1, 4, 4)/1000; 00165 if (calculated_f != frequency) { 00166 pc.printf("PLL frequency not match!\r\n"); 00167 } 00168 } */ 00169 else if (frequency >= 325) { 00170 //counter between 65 and 125 00171 // 20*2*65/8=325 00172 // 20*2*125/8=625 00173 jtag_pll(jtag, 1, 2, counter, 1, 8, 8); 00174 } else if (frequency >= 210) { 00175 //counter between 42 and 65 00176 // 20*3*42/12=210 00177 // 20*3*65/12=325 00178 jtag_pll(jtag, 1, 3, counter, 1, 12, 12); 00179 } else if (frequency >= 105) { 00180 //counter between 21 and 42 00181 // 20*6*21/24=125 00182 // 20*6*42/24=210 00183 jtag_pll(jtag, 1, 3, 2*counter, 1, 24, 24); 00184 } else { 00185 pc.printf("Frequency < 105M out of range!\r\nClock source changed to HCLK_EXT\r\n"); 00186 return 1; 00187 } 00188 jtag.writeMemory(PLL_RESET, 1); 00189 wait_us(10); 00190 jtag.writeMemory(PLL_RESET, 0); 00191 wait_us(10); 00192 if(jtag.readMemory(PLL_PLLLOCK)==0) { 00193 pc.printf("PLL lock failed!\r\nClock source changed to HCLK_EXT\r\n"); 00194 return 1; 00195 } else { 00196 jtag.writeMemory(intclk_source, 2); 00197 return 0; 00198 } 00199 }
Generated on Wed Jul 27 2022 00:15:18 by
1.7.2
