Zimin Wang / Mbed 2 deprecated DDRO_Farrari

Dependencies:   mbed-rtos mbed

Fork of DDRO_Farrari by Liangzhen Lai

Committer:
liangzhen
Date:
Mon Oct 21 22:36:51 2013 +0000
Revision:
1:6a820a0ca03b
Parent:
0:84a8bcfbdec9
Child:
10:95e9932f7990
mbed code for Farrari board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
liangzhen 0:84a8bcfbdec9 1 #include "pll.h"
liangzhen 0:84a8bcfbdec9 2
liangzhen 0:84a8bcfbdec9 3 unsigned long long calc_pll_freqs(unsigned int prediv, unsigned int multint_upper, unsigned int multint,
liangzhen 0:84a8bcfbdec9 4 unsigned int range_upper, unsigned int rangea, unsigned int rangeb){
liangzhen 0:84a8bcfbdec9 5
liangzhen 0:84a8bcfbdec9 6 if(prediv < 1 || prediv > 32){
liangzhen 0:84a8bcfbdec9 7 pc.printf("Prediv out of 1-32 range\r\n");
liangzhen 0:84a8bcfbdec9 8 }
liangzhen 0:84a8bcfbdec9 9 if(multint_upper < 1 || multint_upper > 4){
liangzhen 0:84a8bcfbdec9 10 pc.printf("Multint_upper out of 1-4 range\r\n");
liangzhen 0:84a8bcfbdec9 11 }
liangzhen 0:84a8bcfbdec9 12 if(multint < 1 || multint > 255){
liangzhen 0:84a8bcfbdec9 13 pc.printf("Multint out of 1-255 range\r\n");
liangzhen 0:84a8bcfbdec9 14 }
liangzhen 0:84a8bcfbdec9 15 if(multint_upper * multint > 255){
liangzhen 0:84a8bcfbdec9 16 pc.printf("Multint_upper * Multint out of 1-255 range\r\n");
liangzhen 0:84a8bcfbdec9 17 }
liangzhen 0:84a8bcfbdec9 18 if(!(range_upper == 1 || range_upper == 2 || range_upper == 4)){
liangzhen 0:84a8bcfbdec9 19 pc.printf("Range_upper out of 1,2,4 range\r\n");
liangzhen 0:84a8bcfbdec9 20 }
liangzhen 0:84a8bcfbdec9 21 if(rangea < 1 || rangea > 32){
liangzhen 0:84a8bcfbdec9 22 pc.printf("RangeA out of 1-32 range\r\n");
liangzhen 0:84a8bcfbdec9 23 }
liangzhen 0:84a8bcfbdec9 24 if(rangeb < 1 || rangeb > 32){
liangzhen 0:84a8bcfbdec9 25 pc.printf("RangeB out of 1-32 range\r\n");
liangzhen 0:84a8bcfbdec9 26 }
liangzhen 0:84a8bcfbdec9 27
liangzhen 1:6a820a0ca03b 28 int dco = (PLL_REF / prediv) * multint_upper * multint;
liangzhen 1:6a820a0ca03b 29 if(dco < 2500000 || dco > 5000000){
liangzhen 1:6a820a0ca03b 30 pc.printf("Dco=%d out of 2.5G-5G range\r\n",dco);
liangzhen 0:84a8bcfbdec9 31 }
liangzhen 1:6a820a0ca03b 32 int internal = dco / multint_upper;
liangzhen 1:6a820a0ca03b 33 if(internal < 9800 || internal > 3200000){
liangzhen 1:6a820a0ca03b 34 pc.printf("internal=%d out of 9.8M-3.2G range\r\n",internal);
liangzhen 0:84a8bcfbdec9 35 }
liangzhen 1:6a820a0ca03b 36 int prescale_dco = dco / range_upper;
liangzhen 1:6a820a0ca03b 37 if(prescale_dco > 3200000){
liangzhen 1:6a820a0ca03b 38 pc.printf("Prescale DCO out of 0-3.2G range\r\n");
liangzhen 0:84a8bcfbdec9 39 }
liangzhen 1:6a820a0ca03b 40 int out_a = prescale_dco / rangea;
liangzhen 1:6a820a0ca03b 41 if(out_a < 20000 || out_a > 3000000){
liangzhen 0:84a8bcfbdec9 42 pc.printf("Out A out of 20M-3.0G range\r\n");
liangzhen 0:84a8bcfbdec9 43 }
liangzhen 1:6a820a0ca03b 44 int out_b = prescale_dco / rangeb;
liangzhen 1:6a820a0ca03b 45 if(out_b < 20000 || out_b > 3000000){
liangzhen 0:84a8bcfbdec9 46 pc.printf("Out B out of 20M-3.0G range\r\n");
liangzhen 0:84a8bcfbdec9 47 }
liangzhen 0:84a8bcfbdec9 48
liangzhen 0:84a8bcfbdec9 49 return out_a;
liangzhen 0:84a8bcfbdec9 50 }
liangzhen 0:84a8bcfbdec9 51
liangzhen 0:84a8bcfbdec9 52 int get_binline_by_num(char* filename, int linenum){
liangzhen 0:84a8bcfbdec9 53 char value[30];
liangzhen 0:84a8bcfbdec9 54
liangzhen 0:84a8bcfbdec9 55 //pc.printf("Opening %s File\r\n", filename);
liangzhen 0:84a8bcfbdec9 56 FILE *fp = fopen(filename, "r");
liangzhen 0:84a8bcfbdec9 57 if(!fp){
liangzhen 0:84a8bcfbdec9 58 pc.printf("ERROR: %s not found\r\n", filename);
liangzhen 0:84a8bcfbdec9 59 }
liangzhen 0:84a8bcfbdec9 60 //pc.printf("%s Open\r\n", filename);
liangzhen 0:84a8bcfbdec9 61
liangzhen 0:84a8bcfbdec9 62 int i=1;
liangzhen 0:84a8bcfbdec9 63 char lineval[255];
liangzhen 0:84a8bcfbdec9 64 while (!feof(fp)) {
liangzhen 0:84a8bcfbdec9 65 fscanf(fp, "%s", lineval);
liangzhen 0:84a8bcfbdec9 66 if(i == linenum){
liangzhen 0:84a8bcfbdec9 67 strcpy(value, lineval);
liangzhen 0:84a8bcfbdec9 68 break;
liangzhen 0:84a8bcfbdec9 69 }
liangzhen 0:84a8bcfbdec9 70 i++;
liangzhen 0:84a8bcfbdec9 71 }
liangzhen 0:84a8bcfbdec9 72
liangzhen 0:84a8bcfbdec9 73 //pc.printf("Closing %s File\r\n", filename);
liangzhen 0:84a8bcfbdec9 74 fclose(fp);
liangzhen 0:84a8bcfbdec9 75 //pc.printf("File %s Closed\r\n", filename);
liangzhen 0:84a8bcfbdec9 76
liangzhen 0:84a8bcfbdec9 77 return strtol(value, NULL, 2);
liangzhen 0:84a8bcfbdec9 78 }
liangzhen 0:84a8bcfbdec9 79
liangzhen 0:84a8bcfbdec9 80 void scan_pll(unsigned int prediv, unsigned int multint_upper, unsigned int multint,
liangzhen 0:84a8bcfbdec9 81 unsigned int range_upper, unsigned int rangea, unsigned int rangeb){
liangzhen 0:84a8bcfbdec9 82
liangzhen 0:84a8bcfbdec9 83 prediv = get_binline_by_num("/local/Pprediv.txt", prediv);
liangzhen 0:84a8bcfbdec9 84 multint_upper = get_binline_by_num("/local/Pmultup.txt", multint_upper);
liangzhen 0:84a8bcfbdec9 85 multint = get_binline_by_num("/local/Pmultint.txt", multint);
liangzhen 0:84a8bcfbdec9 86 range_upper = get_binline_by_num("/local/Prangeup.txt", range_upper);
liangzhen 0:84a8bcfbdec9 87 rangea = get_binline_by_num("/local/Prange.txt", rangea);
liangzhen 0:84a8bcfbdec9 88 rangeb = get_binline_by_num("/local/Prange.txt", rangeb);
liangzhen 0:84a8bcfbdec9 89
liangzhen 0:84a8bcfbdec9 90 set_scan_bits("PLL_CE1CCB", 1);
liangzhen 0:84a8bcfbdec9 91 set_scan_bits("PLL_CE1MPGC1", 1);
liangzhen 0:84a8bcfbdec9 92 set_scan_bits("PLL_FFTUNE", fftune(0));
liangzhen 0:84a8bcfbdec9 93 set_scan_bits("PLL_LFTUNE", lftune()); // @@@ Fix this. Scan doesn't support more than 32 bits
liangzhen 0:84a8bcfbdec9 94 set_scan_bits("PLL_INTFBK", 1);
liangzhen 0:84a8bcfbdec9 95 set_scan_bits("PLL_PREDIV", prediv);
liangzhen 0:84a8bcfbdec9 96 set_scan_bits("PLL_MULTINT", multint_upper << 8 | multint);
liangzhen 0:84a8bcfbdec9 97 set_scan_bits("PLL_RANGEA", range_upper << 5 | rangea);
liangzhen 0:84a8bcfbdec9 98 set_scan_bits("PLL_RANGEB", range_upper << 5 | rangeb);
liangzhen 0:84a8bcfbdec9 99 }
liangzhen 0:84a8bcfbdec9 100
liangzhen 0:84a8bcfbdec9 101 void jtag_pll(JTAG &jtag, unsigned int prediv, unsigned int multint_upper, unsigned int multint,
liangzhen 0:84a8bcfbdec9 102 unsigned int range_upper, unsigned int rangea, unsigned int rangeb){
liangzhen 0:84a8bcfbdec9 103
liangzhen 0:84a8bcfbdec9 104 prediv = get_binline_by_num("/local/Pprediv.txt", prediv);
liangzhen 0:84a8bcfbdec9 105 multint_upper = get_binline_by_num("/local/Pmultup.txt", multint_upper);
liangzhen 0:84a8bcfbdec9 106 multint = get_binline_by_num("/local/Pmultint.txt", multint);
liangzhen 0:84a8bcfbdec9 107 range_upper = get_binline_by_num("/local/Prangeup.txt", range_upper);
liangzhen 0:84a8bcfbdec9 108 rangea = get_binline_by_num("/local/Prange.txt", rangea);
liangzhen 0:84a8bcfbdec9 109 rangeb = get_binline_by_num("/local/Prange.txt", rangeb);
liangzhen 0:84a8bcfbdec9 110 jtag.writeMemory(PLL_CE1CCB, 1);
liangzhen 0:84a8bcfbdec9 111 jtag.writeMemory(PLL_CE1MPGC1, 1);
liangzhen 0:84a8bcfbdec9 112 jtag.writeMemory(PLL_FFTUNE, fftune(0));
liangzhen 0:84a8bcfbdec9 113 jtag.writeMemory(PLL_LFTUNE_32_0, lftune_lo());
liangzhen 0:84a8bcfbdec9 114 jtag.writeMemory(PLL_LFTUNE_40_32, lftune_hi());
liangzhen 0:84a8bcfbdec9 115 jtag.writeMemory(PLL_INTFBK, 1);
liangzhen 0:84a8bcfbdec9 116 jtag.writeMemory(PLL_PREDIV, prediv);
liangzhen 0:84a8bcfbdec9 117 jtag.writeMemory(PLL_RANGEA, range_upper << 5 | rangea);
liangzhen 0:84a8bcfbdec9 118 jtag.writeMemory(PLL_RANGEB, range_upper << 5 | rangeb);
liangzhen 1:6a820a0ca03b 119 jtag.writeMemory(PLL_MULTINT, multint_upper << 8 | multint);
liangzhen 0:84a8bcfbdec9 120 }
liangzhen 0:84a8bcfbdec9 121
liangzhen 0:84a8bcfbdec9 122
liangzhen 0:84a8bcfbdec9 123 unsigned int fftune(bool change_rangeab){
liangzhen 0:84a8bcfbdec9 124 if(change_rangeab){
liangzhen 0:84a8bcfbdec9 125 return 0x0120;
liangzhen 0:84a8bcfbdec9 126 }else{
liangzhen 0:84a8bcfbdec9 127 return 0x0100;
liangzhen 0:84a8bcfbdec9 128 }
liangzhen 0:84a8bcfbdec9 129 }
liangzhen 0:84a8bcfbdec9 130
liangzhen 0:84a8bcfbdec9 131 unsigned int lftune_hi(){
liangzhen 0:84a8bcfbdec9 132 return 0x00000050;
liangzhen 0:84a8bcfbdec9 133 }
liangzhen 0:84a8bcfbdec9 134
liangzhen 0:84a8bcfbdec9 135 unsigned int lftune_lo(){
liangzhen 0:84a8bcfbdec9 136 return 0x40100000;
liangzhen 0:84a8bcfbdec9 137 }
liangzhen 0:84a8bcfbdec9 138
liangzhen 0:84a8bcfbdec9 139 unsigned long long lftune(){
liangzhen 0:84a8bcfbdec9 140 // 41 bits
liangzhen 0:84a8bcfbdec9 141 return 0x05040100000L;
liangzhen 1:6a820a0ca03b 142 }
liangzhen 1:6a820a0ca03b 143
liangzhen 1:6a820a0ca03b 144 /*
liangzhen 1:6a820a0ca03b 145 unsigned long long calc_pll_freqs(unsigned int prediv, unsigned int multint_upper, unsigned int multint,
liangzhen 1:6a820a0ca03b 146 unsigned int range_upper, unsigned int rangea, unsigned int rangeb)
liangzhen 1:6a820a0ca03b 147 dco = (PLL_REF / prediv) * multint_upper * multint;
liangzhen 1:6a820a0ca03b 148 prescale_dco = dco / range_upper;
liangzhen 1:6a820a0ca03b 149 out_a = prescale_dco / rangea;
liangzhen 1:6a820a0ca03b 150 */
liangzhen 1:6a820a0ca03b 151 int set_pll_frequency (int fMHz, JTAG &jtag) {
liangzhen 1:6a820a0ca03b 152 jtag.writeMemory(intclk_source, 0);
liangzhen 1:6a820a0ca03b 153 int counter = fMHz / 5;
liangzhen 1:6a820a0ca03b 154 int frequency = counter * 5;
liangzhen 1:6a820a0ca03b 155 if (frequency >= 625) {
liangzhen 1:6a820a0ca03b 156 pc.printf("Frequency > 625 MHz out of range!\r\nClock source changed to HCLK_EXT\r\n");
liangzhen 1:6a820a0ca03b 157 return 1;
liangzhen 1:6a820a0ca03b 158 } /*
liangzhen 1:6a820a0ca03b 159 else if (frequency >= 625) {
liangzhen 1:6a820a0ca03b 160 //counter between 125 and 200
liangzhen 1:6a820a0ca03b 161 // 20*125/4=625
liangzhen 1:6a820a0ca03b 162 // 20*200/4=1G
liangzhen 1:6a820a0ca03b 163 jtag_pll(jtag, 1, 1, counter, 1, 4, 4);
liangzhen 1:6a820a0ca03b 164 calculated_f = calc_pll_freqs(1, 1, counter, 1, 4, 4)/1000;
liangzhen 1:6a820a0ca03b 165 if (calculated_f != frequency) {
liangzhen 1:6a820a0ca03b 166 pc.printf("PLL frequency not match!\r\n");
liangzhen 1:6a820a0ca03b 167 }
liangzhen 1:6a820a0ca03b 168 } */
liangzhen 1:6a820a0ca03b 169 else if (frequency >= 325) {
liangzhen 1:6a820a0ca03b 170 //counter between 65 and 125
liangzhen 1:6a820a0ca03b 171 // 20*2*65/8=325
liangzhen 1:6a820a0ca03b 172 // 20*2*125/8=625
liangzhen 1:6a820a0ca03b 173 jtag_pll(jtag, 1, 2, counter, 1, 8, 8);
liangzhen 1:6a820a0ca03b 174 } else if (frequency >= 210) {
liangzhen 1:6a820a0ca03b 175 //counter between 42 and 65
liangzhen 1:6a820a0ca03b 176 // 20*3*42/12=210
liangzhen 1:6a820a0ca03b 177 // 20*3*65/12=325
liangzhen 1:6a820a0ca03b 178 jtag_pll(jtag, 1, 3, counter, 1, 12, 12);
liangzhen 1:6a820a0ca03b 179 } else if (frequency >= 105) {
liangzhen 1:6a820a0ca03b 180 //counter between 21 and 42
liangzhen 1:6a820a0ca03b 181 // 20*6*21/24=125
liangzhen 1:6a820a0ca03b 182 // 20*6*42/24=210
liangzhen 1:6a820a0ca03b 183 jtag_pll(jtag, 1, 3, 2*counter, 1, 24, 24);
liangzhen 1:6a820a0ca03b 184 } else {
liangzhen 1:6a820a0ca03b 185 pc.printf("Frequency < 105M out of range!\r\nClock source changed to HCLK_EXT\r\n");
liangzhen 1:6a820a0ca03b 186 return 1;
liangzhen 1:6a820a0ca03b 187 }
liangzhen 1:6a820a0ca03b 188 jtag.writeMemory(PLL_RESET, 1);
liangzhen 1:6a820a0ca03b 189 wait_us(10);
liangzhen 1:6a820a0ca03b 190 jtag.writeMemory(PLL_RESET, 0);
liangzhen 1:6a820a0ca03b 191 wait_us(10);
liangzhen 1:6a820a0ca03b 192 if(jtag.readMemory(PLL_PLLLOCK)==0) {
liangzhen 1:6a820a0ca03b 193 pc.printf("PLL lock failed!\r\nClock source changed to HCLK_EXT\r\n");
liangzhen 1:6a820a0ca03b 194 return 1;
liangzhen 1:6a820a0ca03b 195 } else {
liangzhen 1:6a820a0ca03b 196 jtag.writeMemory(intclk_source, 2);
liangzhen 1:6a820a0ca03b 197 return 0;
liangzhen 1:6a820a0ca03b 198 }
liangzhen 0:84a8bcfbdec9 199 }