Zimin Wang / Mbed 2 deprecated DDRO_Farrari

Dependencies:   mbed-rtos mbed

Fork of DDRO_Farrari by Liangzhen Lai

pll.cpp

Committer:
liangzhen
Date:
2013-10-07
Revision:
0:84a8bcfbdec9
Child:
1:6a820a0ca03b

File content as of revision 0:84a8bcfbdec9:

#include "pll.h"

unsigned long long calc_pll_freqs(unsigned int prediv, unsigned int multint_upper, unsigned int multint, 
                            unsigned int range_upper, unsigned int rangea, unsigned int rangeb){

    if(prediv < 1 || prediv > 32){
        pc.printf("Prediv out of 1-32 range\r\n");
    }
    if(multint_upper < 1 || multint_upper > 4){
        pc.printf("Multint_upper out of 1-4 range\r\n");
    }
    if(multint < 1 || multint > 255){
        pc.printf("Multint out of 1-255 range\r\n");
    }
    if(multint_upper * multint > 255){
        pc.printf("Multint_upper * Multint out of 1-255 range\r\n");
    }
    if(!(range_upper == 1 || range_upper == 2 || range_upper == 4)){
        pc.printf("Range_upper out of 1,2,4 range\r\n");
    }
    if(rangea < 1 || rangea > 32){
        pc.printf("RangeA out of 1-32 range\r\n");
    }
    if(rangeb < 1 || rangeb > 32){
        pc.printf("RangeB out of 1-32 range\r\n");
    }
    
    unsigned long long dco = PLL_REF / prediv * multint_upper * multint;
    if(dco < 2500000000 || dco > 5000000000){
        pc.printf("Dco out of 2.5G-5G range\r\n");
    }
    unsigned long long internal = dco / multint_upper;
    if(internal < 9800000 || internal > 3200000000){
       //\ pc.printf("Dco out of 9.8M-3.2G range\r\n");
    }
    unsigned long long prescale_dco = dco / range_upper;
    if(prescale_dco > 3200000000){
       // pc.printf("Prescale DCO out of 0-3.2G range\r\n");
    }
    unsigned long long out_a = prescale_dco / rangea;
    if(out_a < 20000000 || out_a > 3000000000){
        pc.printf("Out A out of 20M-3.0G range\r\n");
    }
    unsigned long long out_b = prescale_dco / rangeb;
    if(out_b < 20000000 || out_b > 3000000000){
        pc.printf("Out B out of 20M-3.0G range\r\n");
    }
    
    return out_a;
}

int get_binline_by_num(char* filename, int linenum){
    char value[30];
    
    //pc.printf("Opening %s File\r\n", filename);
    FILE *fp = fopen(filename, "r");
    if(!fp){
        pc.printf("ERROR: %s not found\r\n", filename);
    }
    //pc.printf("%s Open\r\n", filename);
        
    int i=1;
    char lineval[255];
    while (!feof(fp)) {
        fscanf(fp, "%s", lineval);
        if(i == linenum){
            strcpy(value, lineval);
            break;
        }
        i++;
    }
            
    //pc.printf("Closing %s File\r\n", filename);
    fclose(fp);
    //pc.printf("File %s Closed\r\n", filename);
    
    return strtol(value, NULL, 2);
}

void scan_pll(unsigned int prediv, unsigned int multint_upper, unsigned int multint, 
              unsigned int range_upper, unsigned int rangea, unsigned int rangeb){
    
    prediv        = get_binline_by_num("/local/Pprediv.txt",  prediv);
    multint_upper = get_binline_by_num("/local/Pmultup.txt",  multint_upper);
    multint       = get_binline_by_num("/local/Pmultint.txt", multint);
    range_upper   = get_binline_by_num("/local/Prangeup.txt", range_upper);
    rangea        = get_binline_by_num("/local/Prange.txt",   rangea);
    rangeb        = get_binline_by_num("/local/Prange.txt",   rangeb);
    
    set_scan_bits("PLL_CE1CCB",   1);
    set_scan_bits("PLL_CE1MPGC1", 1);
    set_scan_bits("PLL_FFTUNE",   fftune(0));
    set_scan_bits("PLL_LFTUNE",   lftune()); // @@@ Fix this. Scan doesn't support more than 32 bits
    set_scan_bits("PLL_INTFBK",   1);
    set_scan_bits("PLL_PREDIV",   prediv);
    set_scan_bits("PLL_MULTINT",  multint_upper << 8 | multint);
    set_scan_bits("PLL_RANGEA",   range_upper << 5 | rangea);
    set_scan_bits("PLL_RANGEB",   range_upper << 5 | rangeb);
}

void jtag_pll(JTAG &jtag, unsigned int prediv, unsigned int multint_upper, unsigned int multint, 
              unsigned int range_upper, unsigned int rangea, unsigned int rangeb){
    
    prediv        = get_binline_by_num("/local/Pprediv.txt",  prediv);
    multint_upper = get_binline_by_num("/local/Pmultup.txt",  multint_upper);
    multint       = get_binline_by_num("/local/Pmultint.txt", multint);
    range_upper   = get_binline_by_num("/local/Prangeup.txt", range_upper);
    rangea        = get_binline_by_num("/local/Prange.txt",   rangea);
    rangeb        = get_binline_by_num("/local/Prange.txt",   rangeb);
    
    jtag.writeMemory(PLL_CE1CCB,   1);
    jtag.writeMemory(PLL_CE1MPGC1, 1);
    jtag.writeMemory(PLL_FFTUNE,   fftune(0));
    jtag.writeMemory(PLL_LFTUNE_32_0,   lftune_lo());
    jtag.writeMemory(PLL_LFTUNE_40_32,   lftune_hi());
    jtag.writeMemory(PLL_INTFBK,   1);
    jtag.writeMemory(PLL_PREDIV,   prediv);
    jtag.writeMemory(PLL_MULTINT,  multint_upper << 8 | multint);
    jtag.writeMemory(PLL_RANGEA,   range_upper << 5 | rangea);
    jtag.writeMemory(PLL_RANGEB,   range_upper << 5 | rangeb);
}


unsigned int fftune(bool change_rangeab){
    if(change_rangeab){
        return 0x0120;
    }else{
        return 0x0100;
    }
}

unsigned int lftune_hi(){
    return 0x00000050;
}

unsigned int lftune_lo(){
    return 0x40100000;
}

unsigned long long lftune(){
    // 41 bits
    return 0x05040100000L;
}