From 8d0ff49fa7d7dc5f98c83a9876000254ae9edbaf Mon Sep 17 00:00:00 2001 From: F5OEO Date: Thu, 14 Jun 2018 13:49:20 +0000 Subject: [PATCH] Work on spurious - still investigate --- app/testrpitx.cpp | 80 +++++++++++++++++++++++++++++++++++++++++------ src/dma.cpp | 2 ++ src/gpio.cpp | 77 ++++++++++++++++++++++++++++++++++++--------- src/gpio.h | 36 +++++++++++++++++++-- src/librpitx.h | 1 + src/mailbox.c | 22 +++++++++++++ src/mailbox.h | 1 + 7 files changed, 194 insertions(+), 25 deletions(-) diff --git a/app/testrpitx.cpp b/app/testrpitx.cpp index c3e3354..d601846 100644 --- a/app/testrpitx.cpp +++ b/app/testrpitx.cpp @@ -6,23 +6,52 @@ #include bool running=true; +/*int +gcd ( int a, int b ) +{ + int c; + while ( a != 0 ) { + c = a; a = b%a; b = c; + } + return b; +}*/ + +uint64_t gcd(uint64_t x,uint64_t y) +{ + return y == 0 ? x : gcd(y, x % y); +} + +uint64_t lcm(uint64_t x, uint64_t y) +{ + return x * y / gcd(x, y); +} + void SimpleTest(uint64_t Freq) { generalgpio genpio; fprintf(stderr,"GPIOPULL =%x\n",genpio.gpioreg[GPPUDCLK0]); + #define PULL_OFF 0 #define PULL_DOWN 1 #define PULL_UP 2 - genpio.gpioreg[GPPUD]=PULL_DOWN; - usleep(100); + genpio.gpioreg[GPPUD]=1;//PULL_DOWN; + usleep(150); genpio.gpioreg[GPPUDCLK0]=(1<<4); //GPIO CLK is GPIO 4 - usleep(100); - //genpio.gpioreg[GPPUDCLK0]=(0); //GPIO CLK is GPIO 4 + usleep(150); + genpio.gpioreg[GPPUDCLK0]=(0); //GPIO CLK is GPIO 4 + + //genpio.setpulloff(4); + + padgpio pad; + pad.setlevel(7); + clkgpio clk; clk.print_clock_tree(); - clk.SetPllNumber(clk_plld,1); - clk.SetAdvancedPllMode(true); + clk.SetPllNumber(clk_plla,0); + + //clk.SetAdvancedPllMode(true); + //clk.SetPLLMasterLoop(0,4,0); //clk.Setppm(+7.7); clk.SetCenterFrequency(Freq,1000); double freqresolution=clk.GetFrequencyResolution(); @@ -30,14 +59,47 @@ void SimpleTest(uint64_t Freq) fprintf(stderr,"Frequency resolution=%f Error freq=%f\n",freqresolution,RealFreq); int Deviation=0; clk.SetFrequency(000); - clk.enableclk(4); + clk.enableclk(4); + usleep(100); + //clk.SetClkDivFrac(100,0); // If mash!=0 update doesnt seem to work + int count=0; while(running) { - clk.SetFrequency(000); + //clk.SetMasterMultFrac(44,(1<15) + { Kp=0; + Ki=Ki+1; + } + //Ki=Ki+1; + if(Ki>11) + { + Ki=4; + Ka++; + } + Ki=Kp; + + clk.SetClkDivFrac(count,count); + + //clk.SetPLLMasterLoop(Ki,4,Ka); + //clk.SetPLLMasterLoop(2,4,0); + //clk.SetPLLMasterLoop(3,4,0); //best one + + //printf("Ki=%d :Kp %d Ka %d\n ",Ki,Kp,Ka); + /*clk.SetFrequency(000); sleep(5); clk.SetFrequency(freqresolution); - sleep(5); + sleep(5);*/ } /* for(int i=0;i<100000;i+=1) diff --git a/src/dma.cpp b/src/dma.cpp index 6a0b9c1..eec0467 100644 --- a/src/dma.cpp +++ b/src/dma.cpp @@ -64,6 +64,8 @@ dma::dma(int Channel,uint32_t CBSize,uint32_t UserMemSize) // Fixme! Need to che dma_reg.gpioreg[DMA_CS+channel*0x40] = BCM2708_DMA_RESET|DMA_CS_INT; // Remove int flag usleep(100); dma_reg.gpioreg[DMA_CONBLK_AD+channel*0x40]=mem_virt_to_phys((void*)cbarray ); // reset to beginning + + //get_clocks(mbox.handle); } void dma::GetRpiInfo() diff --git a/src/gpio.cpp b/src/gpio.cpp index 4acc606..a6bbe34 100644 --- a/src/gpio.cpp +++ b/src/gpio.cpp @@ -29,6 +29,11 @@ gpio::gpio(uint32_t base, uint32_t len) { gpioreg = (uint32_t *)mapmem(base, len); + + /*int mhandle=mbox_open(); + get_clocks(mhandle); + mbox_close(mhandle); + */ } uint32_t gpio::GetPeripheralBase() @@ -144,8 +149,10 @@ int clkgpio::SetFrequency(double Frequency) uint32_t freqctl = FloatMult * ((double)(1 << 20)); int IntMultiply = freqctl >> 20; // Need to be calculated to have a center frequency freqctl &= 0xFFFFF; // Fractionnal is 20bits + uint32_t FracMultiply = freqctl & 0xFFFFF; - //gpioreg[PLLA_FRAC]= 0x5A000000 | FracMultiply ; // Only Frac is Sent + //uint32_t FracMultiply = 0.75*(1<<20); + SetMasterMultFrac(IntMultiply, FracMultiply); } else @@ -192,7 +199,7 @@ int clkgpio::ComputeBestLO(uint64_t Frequency, int Bandwidth) int divider, min_int_multiplier, max_int_multiplier, fom, int_multiplier, best_fom = 0; double frac_multiplier; best_divider = 0; - for (divider = 1; divider < 4096; divider++)//1 is allowed only for MASH=0 + for (divider = 2; divider < 4096; divider++)//1 is allowed only for MASH=0 { if (Frequency * divider < 600e6) continue; // widest accepted frequency range @@ -202,7 +209,11 @@ int clkgpio::ComputeBestLO(uint64_t Frequency, int Bandwidth) max_int_multiplier = ((int)((double)(Frequency + Bandwidth) * divider * xtal_freq_recip)); min_int_multiplier = ((int)((double)(Frequency - Bandwidth) * divider * xtal_freq_recip)); if (min_int_multiplier != max_int_multiplier) - continue; // don't cross integer boundary + { + //fprintf(stderr,"Warning : cross boundary frequency\n"); + continue; // don't cross integer boundary + } + // continue; // don't cross integer boundary solution_count++; // if we make it here the solution is acceptable, fom = 0; // but we want a good solution @@ -219,16 +230,18 @@ int clkgpio::ComputeBestLO(uint64_t Frequency, int Bandwidth) frac_multiplier = ((double)(Frequency)*divider * xtal_freq_recip); int_multiplier = (int)frac_multiplier; frac_multiplier = frac_multiplier - int_multiplier; - if ((int_multiplier % 2) == 0) - fom++; - if ((frac_multiplier > 0.4) && (frac_multiplier < 0.6)) + //if ((int_multiplier % 2) == 0) + // fom++; + //if (((frac_multiplier > 0.7) && (frac_multiplier < 1.0))||((frac_multiplier > 0.0) && (frac_multiplier < 0.3))) + if (((frac_multiplier > 0.2) && (frac_multiplier < 0.3))||((frac_multiplier > 0.7) && (frac_multiplier < 0.8))) + //if (((frac_multiplier > 0.4) && (frac_multiplier < 0.6))) fom += 2; // prefer mulipliers away from integer boundaries //if( divider%2 == 1 ) fom+=2; // prefer odd dividers // Even and odd dividers could have different harmonic content, // but the latest measurements have shown no significant difference. - printf("Try multiplier:%f divider:%d VCO: %4.1fMHz\n",Frequency*divider*xtal_freq_recip,divider,(double)Frequency*divider/1e6); + //printf("Try multiplier:%f divider:%d VCO: %4.1fMHz Spurious %f\n",Frequency*divider*xtal_freq_recip,divider,(double)Frequency*divider/1e6,frac_multiplier*19.2e6/(double)divider); if (fom > best_fom) { best_fom = fom; @@ -238,7 +251,7 @@ int clkgpio::ComputeBestLO(uint64_t Frequency, int Bandwidth) if (solution_count > 0) { PllFixDivider = best_divider; - fprintf(stderr, " multiplier:%f divider:%d VCO: %4.1fMHz\n", Frequency * best_divider * xtal_freq_recip, best_divider, (double)Frequency * best_divider / 1e6); + //fprintf(stderr, " multiplier:%f divider:%d VCO: %4.1fMHz Spurious %f \n", Frequency * best_divider * xtal_freq_recip, best_divider, (double)Frequency * best_divider / 1e6,frac_multiplier*xtal_freq_recip/(double)divider); return 0; } else @@ -289,7 +302,7 @@ int clkgpio::SetCenterFrequency(uint64_t Frequency, int Bandwidth) fprintf(stderr, "Master PLLA Locked\n"); else fprintf(stderr, "Warning ! Master PLLA NOT Locked !!!!\n"); - SetClkDivFrac(PllFixDivider, 0); // NO MASH !!!! + SetClkDivFrac(PllFixDivider, 0x0); // NO MASH !!!! usleep(100); usleep(100); @@ -319,29 +332,48 @@ void clkgpio::SetAdvancedPllMode(bool Advanced) if (ModulateFromMasterPLL) { SetPllNumber(clk_plla, 0); // Use PPL_A , Do not USE MASH which generates spurious - gpioreg[0x104 / 4] = 0x5A00022A; // Enable Plla_PER + gpioreg[CM_PLLA] = 0x5A00022A; // Enable Plla_PER usleep(100); uint32_t ana[4]; for (int i = 3; i >= 0; i--) { - ana[i] = gpioreg[(0x1010 / 4) + i]; + ana[i] = gpioreg[(A2W_PLLA_ANA0 ) + i]; } ana[1]&=~(1<<14); // No use prediv means Frequency //ana[1] |= (1 << 14); // use prediv means Frequency*2 for (int i = 3; i >= 0; i--) { - gpioreg[(0x1010 / 4) + i] = (0x5A << 24) | ana[i]; + gpioreg[(A2W_PLLA_ANA0 ) + i] = (0x5A << 24) | ana[i]; } usleep(100); - gpioreg[PLLA_CORE] = 0x5A000001; // Div ? - gpioreg[PLLA_PER] = 0x5A000001; // Div ? + gpioreg[PLLA_CORE] = 0x5A000000|(1<<8);//Disable + gpioreg[PLLA_PER] = 0x5A000001; // Divisor usleep(100); } } +void clkgpio::SetPLLMasterLoop(int Ki,int Kp,int Ka) +{ + uint32_t ana[4]; + for (int i = 3; i >= 0; i--) + { + ana[i] = gpioreg[(A2W_PLLA_ANA0 ) + i]; + } + + ana[1]=(Ki<= 0; i--) + { + gpioreg[(A2W_PLLA_ANA0 ) + i] = (0x5A << 24) | ana[i]; + } + usleep(100) ; + //Only PLLA for now + +} + void clkgpio::print_clock_tree(void) { @@ -519,6 +551,17 @@ int generalgpio::setmode(uint32_t gpio, uint32_t mode) return 0; } +int generalgpio::setpulloff(uint32_t gpio) +{ + gpioreg[GPPUD]=0; + usleep(150); + gpioreg[GPPUDCLK0]=1<