Work on spurious - still investigate
This commit is contained in:
parent
9e757ea566
commit
8d0ff49fa7
7 changed files with 194 additions and 25 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
77
src/gpio.cpp
77
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<<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;
|
||||
}
|
||||
|
|
36
src/gpio.h
36
src/gpio.h
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue