Add NTP ppm calibration

This commit is contained in:
F5OEO 2018-03-30 08:23:20 +00:00
parent 58adc4a97e
commit e608ff8936
3 changed files with 48 additions and 9 deletions

View file

@ -23,6 +23,7 @@ void SimpleTest(uint64_t Freq)
clk.print_clock_tree(); clk.print_clock_tree();
clk.SetPllNumber(clk_plld,1); clk.SetPllNumber(clk_plld,1);
clk.SetAdvancedPllMode(true); clk.SetAdvancedPllMode(true);
//clk.Setppm(+7.7);
clk.SetCenterFrequency(Freq,1000); clk.SetCenterFrequency(Freq,1000);
double freqresolution=clk.GetFrequencyResolution(); double freqresolution=clk.GetFrequencyResolution();
double RealFreq=clk.GetRealFrequency(0); double RealFreq=clk.GetRealFrequency(0);
@ -30,6 +31,7 @@ void SimpleTest(uint64_t Freq)
int Deviation=0; int Deviation=0;
clk.SetFrequency(000); clk.SetFrequency(000);
clk.enableclk(4); clk.enableclk(4);
while(running) while(running)
{ {
clk.SetFrequency(000); clk.SetFrequency(000);
@ -37,9 +39,10 @@ void SimpleTest(uint64_t Freq)
clk.SetFrequency(freqresolution); clk.SetFrequency(freqresolution);
sleep(5); sleep(5);
} }
/*for(int i=0;i<100000;i+=1) /*
for(int i=0;i<100000;i+=1)
{ {
clk.SetFrequency(i); clk.SetFrequency(0);
usleep(1000); usleep(1000);
}*/ }*/
clk.disableclk(4); clk.disableclk(4);
@ -342,13 +345,13 @@ int main(int argc, char* argv[])
sigaction(i, &sa, NULL); sigaction(i, &sa, NULL);
} }
//SimpleTest(Freq); SimpleTest(Freq);
//SimpleTestbpsk(Freq); //SimpleTestbpsk(Freq);
//SimpleTestFileIQ(Freq); //SimpleTestFileIQ(Freq);
//SimpleTestDMA(Freq); //SimpleTestDMA(Freq);
//SimpleTestAm(Freq); //SimpleTestAm(Freq);
//SimpleTestOOK(Freq); //SimpleTestOOK(Freq);
SimpleTestBurstFsk(Freq); //SimpleTestBurstFsk(Freq);
} }

View file

@ -24,6 +24,8 @@ extern "C"
#include "raspberry_pi_revision.h" #include "raspberry_pi_revision.h"
#include "stdio.h" #include "stdio.h"
#include <unistd.h> #include <unistd.h>
#include <sys/timex.h>
#include <math.h>
gpio::gpio(uint32_t base, uint32_t len) gpio::gpio(uint32_t base, uint32_t len)
{ {
@ -62,7 +64,7 @@ dmagpio::dmagpio():gpio(GetPeripheralBase()+DMA_BASE,DMA_LEN)
// ***************** CLK Registers ***************************************** // ***************** CLK Registers *****************************************
clkgpio::clkgpio():gpio(GetPeripheralBase()+CLK_BASE,CLK_LEN) clkgpio::clkgpio():gpio(GetPeripheralBase()+CLK_BASE,CLK_LEN)
{ {
SetppmFromNTP();
} }
clkgpio::~clkgpio() clkgpio::~clkgpio()
@ -123,7 +125,7 @@ int clkgpio::SetClkDivFrac(uint32_t Div,uint32_t Frac)
int clkgpio::SetMasterMultFrac(uint32_t Mult,uint32_t Frac) int clkgpio::SetMasterMultFrac(uint32_t Mult,uint32_t Frac)
{ {
fprintf(stderr,"Master Mult %d Frac %d\n",Mult,Frac); //fprintf(stderr,"Master Mult %d Frac %d\n",Mult,Frac);
gpioreg[PLLA_CTRL] = (0x5a<<24) | (0x21<<12) | Mult; gpioreg[PLLA_CTRL] = (0x5a<<24) | (0x21<<12) | Mult;
usleep(100); usleep(100);
gpioreg[PLLA_FRAC]= 0x5A000000 | Frac ; gpioreg[PLLA_FRAC]= 0x5A000000 | Frac ;
@ -136,7 +138,7 @@ int clkgpio::SetFrequency(double Frequency)
{ {
if(ModulateFromMasterPLL) if(ModulateFromMasterPLL)
{ {
double FloatMult=((double)(CentralFrequency+Frequency)*PllFixDivider)/(double)(XOSC_FREQUENCY); double FloatMult=((double)(CentralFrequency+Frequency)*PllFixDivider)/((double)(XOSC_FREQUENCY)*(1-clk_ppm*1e-6)); // -ppm : compensate ppm
uint32_t freqctl = FloatMult*((double)(1<<20)) ; uint32_t freqctl = FloatMult*((double)(1<<20)) ;
int IntMultiply= freqctl>>20; // Need to be calculated to have a center frequency int IntMultiply= freqctl>>20; // Need to be calculated to have a center frequency
freqctl&=0xFFFFF; // Fractionnal is 20bits freqctl&=0xFFFFF; // Fractionnal is 20bits
@ -165,7 +167,7 @@ uint32_t clkgpio::GetMasterFrac(double Frequency)
{ {
if(ModulateFromMasterPLL) if(ModulateFromMasterPLL)
{ {
double FloatMult=((double)(CentralFrequency+Frequency)*PllFixDivider)/(double)(XOSC_FREQUENCY); double FloatMult=((double)(CentralFrequency+Frequency)*PllFixDivider)/((double)(XOSC_FREQUENCY)*(1-clk_ppm*1e-6));
uint32_t freqctl = FloatMult*((double)(1<<20)) ; uint32_t freqctl = FloatMult*((double)(1<<20)) ;
int IntMultiply= freqctl>>20; // Need to be calculated to have a center frequency int IntMultiply= freqctl>>20; // Need to be calculated to have a center frequency
freqctl&=0xFFFFF; // Fractionnal is 20bits freqctl&=0xFFFFF; // Fractionnal is 20bits
@ -457,6 +459,37 @@ void clkgpio::disableclk(int gpio)
} }
void clkgpio::Setppm(double ppm)
{
clk_ppm=ppm-2.0; // -2 is empiric : FixMe
}
void clkgpio::SetppmFromNTP()
{
struct timex ntx;
int status;
//Calibrate Clock system (surely depends also on PLL PPM
// =====================================================
ntx.modes = 0; /* only read */
status = ntp_adjtime(&ntx);
double ntp_ppm;
if (status != TIME_OK)
{
fprintf(stderr,"Warning: NTP calibrate failed\n");
}
else
{
ntp_ppm = (double)ntx.freq/(double)(1 << 16);
fprintf(stderr,"Info:NTP find ppm=%f\n",ntp_ppm);
if(fabs(ntp_ppm)<200)
Setppm(ntp_ppm);
}
}
// ************************************** GENERAL GPIO ***************************************************** // ************************************** GENERAL GPIO *****************************************************
generalgpio::generalgpio():gpio(GetPeripheralBase()+GENERAL_BASE,GENERAL_LEN) generalgpio::generalgpio():gpio(GetPeripheralBase()+GENERAL_BASE,GENERAL_LEN)

View file

@ -147,7 +147,8 @@ class clkgpio:public gpio
uint64_t Pllfrequency; uint64_t Pllfrequency;
bool ModulateFromMasterPLL=false; bool ModulateFromMasterPLL=false;
uint64_t CentralFrequency=0; uint64_t CentralFrequency=0;
generalgpio gengpio; generalgpio gengpio;
double clk_ppm=0;
public: public:
int PllFixDivider=8; //Fix divider from the master clock in advanced mode int PllFixDivider=8; //Fix divider from the master clock in advanced mode
@ -168,6 +169,8 @@ class clkgpio:public gpio
uint32_t GetMasterFrac(double Frequency); uint32_t GetMasterFrac(double Frequency);
void enableclk(int gpio); void enableclk(int gpio);
void disableclk(int gpio); void disableclk(int gpio);
void Setppm(double ppm);
void SetppmFromNTP();
}; };