Work on spurious - still investigate

This commit is contained in:
F5OEO 2018-06-14 13:49:20 +00:00
parent 9e757ea566
commit 8d0ff49fa7
7 changed files with 194 additions and 25 deletions

View file

@ -6,23 +6,52 @@
#include <signal.h>
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<<count));
//uint32_t N=(1<<18);
uint32_t N=(1<<13)*count;
//clk.SetMasterMultFrac(34,N);
printf("count =%d gcd%d spurious%f N=%x %f\n",count,lcm(N,1<<20),(double)gcd(1<<20,N)*19.2e6/(double)(1<<20),N,N/(float)(1<<20));
count=(count+1)%128;
//usleep(10000000);
int a=getc(stdin);
static int Ki=4,Kp=0,Ka=0;
Kp=Kp+1;
if(Kp>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)

View file

@ -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()

View file

@ -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<<A2W_PLL_KI_SHIFT)|(Kp<<A2W_PLL_KP_SHIFT)|(Ka<<A2W_PLL_KA_SHIFT);
fprintf(stderr,"Loop parameter =%x\n",ana[1]);
for (int i = 3; i >= 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<<gpio;
usleep(150);
gpioreg[GPPUDCLK0]=0;
return 0;
}
// ********************************** PWM GPIO **********************************
pwmgpio::pwmgpio() : gpio(GetPeripheralBase() + PWM_BASE, PWM_LEN)
@ -762,3 +805,9 @@ padgpio::padgpio() : gpio(GetPeripheralBase() + PADS_GPIO, PADS_GPIO_LEN)
padgpio::~padgpio()
{
}
int padgpio::setlevel(int level)
{
gpioreg[PADS_GPIO_0]=0x5a000000 + (level&0x7) + (0<<4) + (0<<3);
return 0;
}

View file

@ -64,7 +64,8 @@ class dmagpio:public gpio
#define GPFSEL1 (0x04/4)
#define GPFSEL2 (0x08/4)
#define GPPUD (0x94/4)
#define GPPUDCLK0 (0x9C/4)
#define GPPUDCLK0 (0x98/4)
#define GPPUDCLK1 (0x9C/4)
enum {fsel_input,fsel_output,fsel_alt5,fsel_alt4,fsel_alt0,fsel_alt1,fsel_alt2,fsel_alt3};
@ -75,12 +76,13 @@ class generalgpio:public gpio
generalgpio();
int setmode(uint32_t gpio, uint32_t mode);
~generalgpio();
int setpulloff(uint32_t gpio);
};
// Add for PLL frequency CTRL wihout divider
// https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/clk/bcm/clk-bcm2835.c
// See interesting patch for jitter https://github.com/raspberrypi/linux/commit/76527b4e6a5dbe55e0b2d8ab533c2388b36c86be
#define GENMASK(h, l) (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l))
#define CLK_BASE (0x00101000)
#define CLK_LEN 0x1300
@ -99,6 +101,34 @@ class generalgpio:public gpio
# define CM_LOCK_FLOCKB (1<<9)
# define CM_LOCK_FLOCKA (1<<8)
#define CM_PLLA (0x104/4)
/*
# define CM_PLL_ANARST BIT(8)
# define CM_PLLA_HOLDPER BIT(7)
# define CM_PLLA_LOADPER BIT(6)
# define CM_PLLA_HOLDCORE BIT(5)
# define CM_PLLA_LOADCORE BIT(4)
# define CM_PLLA_HOLDCCP2 BIT(3)
# define CM_PLLA_LOADCCP2 BIT(2)
# define CM_PLLA_HOLDDSI0 BIT(1)
# define CM_PLLA_LOADDSI0 BIT(0)
*/
#define CM_PLLC (0x108/4)
#define CM_PLLD (0x10c/4)
#define CM_PLLH (0x110/4)
#define CM_PLLB (0x170/4)
#define A2W_PLLA_ANA0 (0x1010/4)
#define A2W_PLLC_ANA0 (0x1030/4)
#define A2W_PLLD_ANA0 (0x1050/4)
#define A2W_PLLH_ANA0 (0x1070/4)
#define A2W_PLLB_ANA0 (0x10f0/4)
#define A2W_PLL_KA_SHIFT 7
#define A2W_PLL_KI_SHIFT 19
#define A2W_PLL_KP_SHIFT 15
#define PLLA_CTRL (0x1100/4)
#define PLLA_FRAC (0x1200/4)
#define PLLA_DSI0 (0x1300/4)
@ -171,6 +201,7 @@ class clkgpio:public gpio
void disableclk(int gpio);
void Setppm(double ppm);
void SetppmFromNTP();
void SetPLLMasterLoop(int Ki,int Kp,int Ka);
};
@ -284,6 +315,7 @@ class padgpio:public gpio
public:
padgpio();
~padgpio();
int setlevel(int level);
};
#endif

View file

@ -25,3 +25,4 @@ This program is free software: you can redistribute it and/or modify
#include "amdmasync.h"
#include "fskburst.h"
#include "dsp.h"

View file

@ -246,6 +246,28 @@ unsigned execute_qpu(int file_desc, unsigned num_qpus, unsigned control, unsigne
return p[5];
}
unsigned get_clocks(int file_desc ) //FixMe !!!!!!
{
int i=0;
unsigned p[256];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x00010007; // (the tag id)
p[i++] = 0; // (size of the buffer)
p[i++] = 128; // (size of the data)
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
mbox_property(file_desc, p);
fprintf(stderr,"Clock size = %d\n",p[4]&0xFFF);
for(i=0;i<128/4;i++) fprintf(stderr,"%x ",p[i]);
fprintf(stderr,"\n");
return p[5];
}
int mbox_open() {
int file_desc;

View file

@ -53,4 +53,5 @@ void *unmapmem(void *addr, unsigned size);
unsigned execute_code(int file_desc, unsigned code, unsigned r0, unsigned r1, unsigned r2, unsigned r3, unsigned r4, unsigned r5);
unsigned execute_qpu(int file_desc, unsigned num_qpus, unsigned control, unsigned noflush, unsigned timeout);
unsigned qpu_enable(int file_desc, unsigned enable);
unsigned get_clocks(int file_desc );
#endif