kopia lustrzana https://github.com/F5OEO/rpitx
librpitx with PWM added
rodzic
3a571e0e54
commit
40f2f7e3dd
15
src/Makefile
15
src/Makefile
|
@ -1,5 +1,5 @@
|
|||
#all: ../rpitx ../pissb ../pisstv ../pifsq ../pifm ../piam ../pidcf77 ../piopera
|
||||
all: v2rpitx ../rpitx ../pissb ../pisstv ../pifsq ../pifm ../piam ../pidcf77 ../piopera
|
||||
all: librpitx v2rpitx ../rpitx ../pissb ../pisstv ../pifsq ../pifm ../piam ../pidcf77 ../piopera
|
||||
|
||||
#CFLAGS = -Wall -g -O2 -D DIGITHIN
|
||||
CFLAGS = -Wall -g -O2 -Wno-unused-variable
|
||||
|
@ -15,10 +15,15 @@ LDFLAGS = -lm -lrt -lpthread -lliquid
|
|||
CCP = g++
|
||||
CC = gcc
|
||||
|
||||
v2rpitx: librpitx.h gpio.h gpio.cpp dma.h dma.cpp mailbox.c raspberry_pi_revision.c v2rpitx.cpp fmdmasync.h fmdmasync.cpp ngfmdmasync.h ngfmdmasync.cpp dsp.h dsp.cpp iqdmasync.h iqdmasync.cpp
|
||||
librpitx: librpitx.h gpio.h gpio.cpp dma.h dma.cpp mailbox.c raspberry_pi_revision.c fmdmasync.h fmdmasync.cpp ngfmdmasync.h ngfmdmasync.cpp dsp.h dsp.cpp iqdmasync.h iqdmasync.cpp serialdmasync.h serialdmasync.cpp phasedmasync.h phasedmasync.cpp
|
||||
$(CC) $(CFLAGS) -c -o mailbox.o mailbox.c
|
||||
$(CC) $(CFLAGS) -c -o raspberry_pi_revision.o raspberry_pi_revision.c
|
||||
$(CCP) $(CFLAGS) -o v2rpitx dsp.cpp iqdmasync.cpp ngfmdmasync.cpp fmdmasync.cpp dma.cpp gpio.cpp mailbox.o raspberry_pi_revision.o v2rpitx.cpp $(LDFLAGS)
|
||||
$(CCP) $(CFLAGS) -c dsp.cpp iqdmasync.cpp ngfmdmasync.cpp fmdmasync.cpp dma.cpp gpio.cpp mailbox.o raspberry_pi_revision.o v2rpitx.cpp serialdmasync.cpp phasedmasync.cpp
|
||||
$(AR) rc librpitx.a dsp.o iqdmasync.o ngfmdmasync.o fmdmasync.o dma.o gpio.o mailbox.o raspberry_pi_revision.o serialdmasync.o phasedmasync.o
|
||||
|
||||
v2rpitx: librpitx.h librpitx.a
|
||||
|
||||
$(CCP) $(CFLAGS) -o v2rpitx v2rpitx.cpp librpitx.a $(LDFLAGS)
|
||||
|
||||
|
||||
|
||||
|
@ -30,8 +35,8 @@ LDFLAGS_Pissb = -lm -lrt -lpthread -lsndfile
|
|||
|
||||
CFLAGS_Pisstv = -Wall -g -O2 -Wno-unused-variable
|
||||
LDFLAGS_Pisstv = -lm -lrt -lpthread
|
||||
../pisstv : ../sstv/pisstv.c
|
||||
$(CC) $(CFLAGS_Pisstv) -o ../pisstv ../sstv/pisstv.c $(LDFLAGS_Pisstv)
|
||||
../pisstv : ../sstv/v2pisstv.cpp
|
||||
$(CCP) $(CFLAGS_Pisstv) -o ../pisstv ../sstv/v2pisstv.cpp ../src/librpitx.a $(LDFLAGS_Pisstv)
|
||||
|
||||
CFLAGS_Pifsq = -Wall -g -O2 -Wno-unused-variable
|
||||
LDFLAGS_Pifsq = -lm -lrt -lpthread
|
||||
|
|
217
src/gpio.cpp
217
src/gpio.cpp
|
@ -14,17 +14,6 @@ gpio::gpio(uint32_t base, uint32_t len)
|
|||
|
||||
}
|
||||
|
||||
int gpio::setmode(uint32_t gpio, uint32_t mode)
|
||||
{
|
||||
int reg, shift;
|
||||
|
||||
reg = gpio/10;
|
||||
shift = (gpio%10) * 3;
|
||||
|
||||
gpioreg[reg] = (gpioreg[reg] & ~(7<<shift)) | (mode<<shift);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t gpio::GetPeripheralBase()
|
||||
{
|
||||
|
@ -55,11 +44,14 @@ dmagpio::dmagpio():gpio(GetPeripheralBase()+DMA_BASE,DMA_LEN)
|
|||
// ***************** CLK Registers *****************************************
|
||||
clkgpio::clkgpio():gpio(GetPeripheralBase()+CLK_BASE,CLK_LEN)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
clkgpio::~clkgpio()
|
||||
{
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(0 << 4) ; //4 is START CLK
|
||||
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
int clkgpio::SetPllNumber(int PllNo,int MashType)
|
||||
|
@ -74,7 +66,7 @@ int clkgpio::SetPllNumber(int PllNo,int MashType)
|
|||
Mash=MashType;
|
||||
else
|
||||
Mash=0;
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(1 << 4) ; //4 is START CLK
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber/*|(1 << 5)*/ ; //5 is Reset CLK
|
||||
usleep(100);
|
||||
Pllfrequency=GetPllFrequency(pllnumber);
|
||||
return 0;
|
||||
|
@ -102,7 +94,8 @@ int clkgpio::SetClkDivFrac(uint32_t Div,uint32_t Frac)
|
|||
{
|
||||
|
||||
gpioreg[GPCLK_DIV] = 0x5A000000 | ((Div)<<12) | Frac;
|
||||
usleep(10);
|
||||
usleep(100);
|
||||
fprintf(stderr,"Clk Number %d div %d frac %d\n",pllnumber,Div,Frac);
|
||||
//gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber |(1<<4) ; //4 is START CLK
|
||||
// usleep(10);
|
||||
return 0;
|
||||
|
@ -112,8 +105,9 @@ int clkgpio::SetClkDivFrac(uint32_t Div,uint32_t Frac)
|
|||
int clkgpio::SetMasterMultFrac(uint32_t Mult,uint32_t Frac)
|
||||
{
|
||||
|
||||
fprintf(stderr,"Master Mult %d Frac %d\n",Mult,Frac);
|
||||
gpioreg[PLLA_CTRL] = (0x5a<<24) | (0x21<<12) | Mult;
|
||||
|
||||
usleep(100);
|
||||
gpioreg[PLLA_FRAC]= 0x5A000000 | Frac ;
|
||||
|
||||
return 0;
|
||||
|
@ -129,7 +123,9 @@ int clkgpio::SetFrequency(int Frequency)
|
|||
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
|
||||
SetMasterMultFrac(IntMultiply,FracMultiply);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -137,7 +133,7 @@ int clkgpio::SetFrequency(int Frequency)
|
|||
uint32_t FreqDivider=(uint32_t)Freqresult;
|
||||
uint32_t FreqFractionnal=(uint32_t) (4096*(Freqresult-(double)FreqDivider));
|
||||
if((FreqDivider>4096)||(FreqDivider<2)) fprintf(stderr,"Frequency out of range\n");
|
||||
//printf("DIV/FRAC %u/%u \n",FreqDivider,FreqFractionnal);
|
||||
printf("DIV/FRAC %u/%u \n",FreqDivider,FreqFractionnal);
|
||||
|
||||
SetClkDivFrac(FreqDivider,FreqFractionnal);
|
||||
}
|
||||
|
@ -162,28 +158,97 @@ uint32_t clkgpio::GetMasterFrac(int Frequency)
|
|||
|
||||
}
|
||||
|
||||
int clkgpio::ComputeBestLO(uint64_t Frequency)
|
||||
int clkgpio::ComputeBestLO(uint64_t Frequency,int Bandwidth)
|
||||
{
|
||||
for(int i=1;i<4096;i++)
|
||||
{
|
||||
|
||||
}
|
||||
return 0;
|
||||
// Algorithm adapted from https://github.com/SaucySoliton/PiFmRds/blob/master/src/pi_fm_rds.c
|
||||
// Choose an integer divider for GPCLK0
|
||||
//
|
||||
// There may be improvements possible to this algorithm.
|
||||
double xtal_freq_recip=1.0/19.2e6; // todo PPM correction
|
||||
int best_divider=0;
|
||||
|
||||
|
||||
int solution_count=0;
|
||||
//printf("carrier:%3.2f ",carrier_freq/1e6);
|
||||
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++)
|
||||
{
|
||||
if( Frequency*divider < 600e6 ) continue; // widest accepted frequency range
|
||||
if( Frequency*divider > 1500e6 ) break;
|
||||
|
||||
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
|
||||
|
||||
solution_count++; // if we make it here the solution is acceptable,
|
||||
fom=0; // but we want a good solution
|
||||
|
||||
if( Frequency*divider > 900e6 ) fom++; // prefer freqs closer to 1000
|
||||
if( Frequency*divider < 1100e6 ) fom++;
|
||||
if( Frequency*divider > 800e6 ) fom++; // accepted frequency range
|
||||
if( Frequency*divider < 1200e6 ) fom++;
|
||||
|
||||
|
||||
frac_multiplier=((double)(Frequency)*divider*xtal_freq_recip);
|
||||
int_multiplier = (int) frac_multiplier;
|
||||
frac_multiplier = frac_multiplier - int_multiplier;
|
||||
if( (frac_multiplier>0.2) && (frac_multiplier<0.8) ) 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(" multiplier:%f divider:%d VCO: %4.1fMHz\n",carrier_freq*divider*xtal_freq_recip,divider,(double)carrier_freq*divider/1e6);
|
||||
if( fom > best_fom )
|
||||
{
|
||||
best_fom=fom;
|
||||
best_divider=divider;
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Central frequency not available !!!!!!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int clkgpio::SetCenterFrequency(uint64_t Frequency)
|
||||
int clkgpio::SetCenterFrequency(uint64_t Frequency,int Bandwidth)
|
||||
{
|
||||
CentralFrequency=Frequency;
|
||||
if(ModulateFromMasterPLL)
|
||||
{
|
||||
//Choose best PLLDiv and Div
|
||||
ComputeBestLO(Frequency);
|
||||
ComputeBestLO(Frequency,Bandwidth); //FixeDivider update
|
||||
|
||||
SetFrequency(0);
|
||||
usleep(1000);
|
||||
if((gpioreg[CM_LOCK]&CM_LOCK_FLOCKA)>0)
|
||||
fprintf(stderr,"Master PLLA Locked\n");
|
||||
else
|
||||
fprintf(stderr,"Warning ! Master PLLA NOT Locked !!!!\n");
|
||||
SetClkDivFrac(PllFixDivider,0); // NO MASH !!!!
|
||||
SetFrequency(Frequency);
|
||||
usleep(100);
|
||||
|
||||
usleep(100);
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(1 << 4) ; //4 is START CLK
|
||||
usleep(100);
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(1 << 4) ; //4 is START CLK
|
||||
usleep(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPllFrequency(pllnumber);// Be sure to get the master PLL frequency
|
||||
gpioreg[GPCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(1 << 4) ; //4 is START CLK
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -305,6 +370,24 @@ void clkgpio::print_clock_tree(void)
|
|||
|
||||
}
|
||||
|
||||
void clkgpio::enableclk(int gpio)
|
||||
{
|
||||
switch(gpio)
|
||||
{
|
||||
case 4: gengpio.setmode(gpio,fsel_alt0);break;
|
||||
case 20:gengpio.setmode(gpio,fsel_alt5);break;
|
||||
case 32:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
case 34:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
default: fprintf(stderr,"gpio %d has no clk - available(4,20,32,34)\n",gpio);break;
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
void clkgpio::disableclk(int gpio)
|
||||
{
|
||||
gengpio.setmode(gpio,fsel_input);
|
||||
|
||||
}
|
||||
|
||||
// ************************************** GENERAL GPIO *****************************************************
|
||||
|
||||
|
@ -314,23 +397,27 @@ generalgpio::generalgpio():gpio(GetPeripheralBase()+GENERAL_BASE,GENERAL_LEN)
|
|||
|
||||
generalgpio::~generalgpio()
|
||||
{
|
||||
disableclk();
|
||||
|
||||
}
|
||||
|
||||
void generalgpio::enableclk()
|
||||
int generalgpio::setmode(uint32_t gpio, uint32_t mode)
|
||||
{
|
||||
gpioreg[GPFSEL0] = (gpioreg[GPFSEL0] & ~(7 << 12)) | (4 << 12);
|
||||
int reg, shift;
|
||||
|
||||
reg = gpio/10;
|
||||
shift = (gpio%10) * 3;
|
||||
|
||||
gpioreg[reg] = (gpioreg[reg] & ~(7<<shift)) | (mode<<shift);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void generalgpio::disableclk()
|
||||
{
|
||||
gpioreg[GPFSEL0] = (gpioreg[GPFSEL0] & ~(7 << 12)) | (0 << 12);
|
||||
}
|
||||
|
||||
// ********************************** PWM GPIO **********************************
|
||||
|
||||
pwmgpio::pwmgpio():gpio(GetPeripheralBase()+PWM_BASE,PWM_LEN)
|
||||
{
|
||||
|
||||
gpioreg[PWM_CTL] = 0;
|
||||
}
|
||||
|
||||
|
@ -341,6 +428,39 @@ pwmgpio::~pwmgpio()
|
|||
gpioreg[PWM_DMAC] = 0;
|
||||
}
|
||||
|
||||
void pwmgpio::enablepwm(int gpio,int PwmNumber)
|
||||
{
|
||||
if(PwmNumber==0)
|
||||
{
|
||||
switch(gpio)
|
||||
{
|
||||
case 12:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
case 18:gengpio.setmode(gpio,fsel_alt5);break;
|
||||
case 40:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
|
||||
default: fprintf(stderr,"gpio %d has no pwm - available(12,18,40)\n",gpio);break;
|
||||
}
|
||||
}
|
||||
if(PwmNumber==1)
|
||||
{
|
||||
switch(gpio)
|
||||
{
|
||||
case 13:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
case 19:gengpio.setmode(gpio,fsel_alt5);break;
|
||||
case 41:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
case 45:gengpio.setmode(gpio,fsel_alt0);break;
|
||||
default: fprintf(stderr,"gpio %d has no pwm - available(13,19,41,45)\n",gpio);break;
|
||||
}
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
void pwmgpio::disablepwm(int gpio)
|
||||
{
|
||||
gengpio.setmode(gpio,fsel_input);
|
||||
|
||||
}
|
||||
|
||||
int pwmgpio::SetPllNumber(int PllNo,int MashType)
|
||||
{
|
||||
if(PllNo<8)
|
||||
|
@ -378,11 +498,17 @@ int pwmgpio::SetFrequency(uint64_t Frequency)
|
|||
usleep(100);
|
||||
|
||||
|
||||
SetPrediv(Prediv);
|
||||
SetPrediv(Prediv); //SetMode should be called before
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void pwmgpio::SetMode(int Mode)
|
||||
{
|
||||
if((Mode>=pwm1pin)&&(Mode<=pwm1pinrepeat))
|
||||
ModePwm=Mode;
|
||||
}
|
||||
|
||||
int pwmgpio::SetPrediv(int predivisor) //Mode should be only for SYNC or a Data serializer : Todo
|
||||
{
|
||||
Prediv=predivisor;
|
||||
|
@ -402,8 +528,14 @@ int pwmgpio::SetPrediv(int predivisor) //Mode should be only for SYNC or a Data
|
|||
usleep(100);
|
||||
gpioreg[PWM_CTL] = PWMCTL_CLRF;
|
||||
usleep(100);
|
||||
//gpioreg[PWM_CTL] = PWMCTL_USEF1 | PWMCTL_PWEN1;
|
||||
gpioreg[PWM_CTL] = PWMCTL_USEF1| PWMCTL_MODE1| PWMCTL_PWEN1|PWMCTL_MSEN1;
|
||||
|
||||
//gpioreg[PWM_CTL] = PWMCTL_USEF1| PWMCTL_MODE1| PWMCTL_PWEN1|PWMCTL_MSEN1;
|
||||
switch(ModePwm)
|
||||
{
|
||||
case pwm1pin:gpioreg[PWM_CTL] = PWMCTL_USEF1| PWMCTL_MODE1| PWMCTL_PWEN1|PWMCTL_MSEN1;break; // All serial go to 1 pin
|
||||
case pwm2pin:gpioreg[PWM_CTL] = PWMCTL_USEF2|PWMCTL_PWEN2|PWMCTL_MODE2|PWMCTL_USEF1| PWMCTL_MODE1| PWMCTL_PWEN1;break;// Alternate bit to pin 1 and 2
|
||||
case pwm1pinrepeat:gpioreg[PWM_CTL] = PWMCTL_USEF1| PWMCTL_MODE1| PWMCTL_PWEN1|PWMCTL_RPTL1;break; // All serial go to 1 pin, repeat if empty : RF mode with PWM
|
||||
}
|
||||
usleep(100);
|
||||
|
||||
return 0;
|
||||
|
@ -443,9 +575,24 @@ uint64_t pcmgpio::GetPllFrequency(int PllNo)
|
|||
|
||||
}
|
||||
|
||||
int pcmgpio::ComputePrediv(uint64_t Frequency)
|
||||
{
|
||||
int prediv=5;
|
||||
for(prediv=10;prediv<1000;prediv++)
|
||||
{
|
||||
double Freqresult=(double)Pllfrequency/(double)(Frequency*prediv);
|
||||
if((Freqresult<4096.0)&&(Freqresult>2.0))
|
||||
{
|
||||
fprintf(stderr,"PCM prediv = %d\n",prediv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return prediv;
|
||||
}
|
||||
|
||||
int pcmgpio::SetFrequency(uint64_t Frequency)
|
||||
{
|
||||
Prediv=10;
|
||||
Prediv=ComputePrediv(Frequency);
|
||||
double Freqresult=(double)Pllfrequency/(double)(Frequency*Prediv);
|
||||
uint32_t FreqDivider=(uint32_t)Freqresult;
|
||||
uint32_t FreqFractionnal=(uint32_t) (4096*(Freqresult-(double)FreqDivider));
|
||||
|
|
74
src/gpio.h
74
src/gpio.h
|
@ -2,13 +2,16 @@
|
|||
#define DEF_GPIO
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class gpio
|
||||
{
|
||||
|
||||
public:
|
||||
volatile uint32_t *gpioreg;
|
||||
gpio(uint32_t base, uint32_t len);
|
||||
int setmode(uint32_t gpio, uint32_t mode);
|
||||
|
||||
uint32_t GetPeripheralBase();
|
||||
};
|
||||
|
||||
|
@ -52,6 +55,28 @@ class dmagpio:public gpio
|
|||
|
||||
};
|
||||
|
||||
//************************************ GENERAL GPIO ***************************************
|
||||
|
||||
#define GENERAL_BASE (0x00200000)
|
||||
#define GENERAL_LEN 0xB4
|
||||
|
||||
#define GPFSEL0 (0x00/4)
|
||||
#define GPFSEL1 (0x04/4)
|
||||
#define GPFSEL2 (0x08/4)
|
||||
#define GPPUD (0x94/4)
|
||||
#define GPPUDCLK0 (0x9C/4)
|
||||
|
||||
enum {fsel_input,fsel_output,fsel_alt5,fsel_alt4,fsel_alt0,fsel_alt1,fsel_alt2,fsel_alt3};
|
||||
|
||||
class generalgpio:public gpio
|
||||
{
|
||||
|
||||
public:
|
||||
generalgpio();
|
||||
int setmode(uint32_t gpio, uint32_t mode);
|
||||
~generalgpio();
|
||||
|
||||
};
|
||||
|
||||
// Add for PLL frequency CTRL wihout divider
|
||||
// https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/clk/bcm/clk-bcm2835.c
|
||||
|
@ -67,6 +92,12 @@ class dmagpio:public gpio
|
|||
#define EMMCCLK_CNTL (0x1C0/4)
|
||||
#define EMMCCLK_DIV (0x1C4/4)
|
||||
|
||||
#define CM_LOCK (0x114/4)
|
||||
# define CM_LOCK_FLOCKH (1<<12)
|
||||
# define CM_LOCK_FLOCKD (1<<11)
|
||||
# define CM_LOCK_FLOCKC (1<<10)
|
||||
# define CM_LOCK_FLOCKB (1<<9)
|
||||
# define CM_LOCK_FLOCKA (1<<8)
|
||||
|
||||
#define PLLA_CTRL (0x1100/4)
|
||||
#define PLLA_FRAC (0x1200/4)
|
||||
|
@ -115,10 +146,11 @@ class clkgpio:public gpio
|
|||
int Mash;
|
||||
uint64_t Pllfrequency;
|
||||
bool ModulateFromMasterPLL=false;
|
||||
|
||||
uint64_t CentralFrequency=0;
|
||||
int PllFixDivider=1; //Fix divider from the master clock in advanced mode
|
||||
uint64_t CentralFrequency=0;
|
||||
generalgpio gengpio;
|
||||
public:
|
||||
int PllFixDivider=8; //Fix divider from the master clock in advanced mode
|
||||
|
||||
clkgpio();
|
||||
~clkgpio();
|
||||
int SetPllNumber(int PllNo,int MashType);
|
||||
|
@ -128,34 +160,17 @@ class clkgpio:public gpio
|
|||
int SetClkDivFrac(uint32_t Div,uint32_t Frac);
|
||||
void SetPhase(bool inversed);
|
||||
void SetAdvancedPllMode(bool Advanced);
|
||||
int SetCenterFrequency(uint64_t Frequency);
|
||||
int ComputeBestLO(uint64_t Frequency);
|
||||
int SetCenterFrequency(uint64_t Frequency,int Bandwidth);
|
||||
int ComputeBestLO(uint64_t Frequency,int Bandwidth);
|
||||
int SetMasterMultFrac(uint32_t Mult,uint32_t Frac);
|
||||
uint32_t GetMasterFrac(int Frequency);
|
||||
void enableclk(int gpio);
|
||||
void disableclk(int gpio);
|
||||
|
||||
};
|
||||
|
||||
|
||||
//************************************ GENERAL GPIO ***************************************
|
||||
|
||||
#define GENERAL_BASE (0x00200000)
|
||||
#define GENERAL_LEN 0xB4
|
||||
|
||||
#define GPFSEL0 (0x00/4)
|
||||
#define GPFSEL1 (0x04/4)
|
||||
#define GPFSEL2 (0x08/4)
|
||||
#define GPPUD (0x94/4)
|
||||
#define GPPUDCLK0 (0x9C/4)
|
||||
|
||||
class generalgpio:public gpio
|
||||
{
|
||||
|
||||
public:
|
||||
generalgpio();
|
||||
~generalgpio();
|
||||
void enableclk();
|
||||
void disableclk();
|
||||
};
|
||||
|
||||
//************************************ PWM GPIO ***************************************
|
||||
|
||||
|
@ -187,6 +202,7 @@ class generalgpio:public gpio
|
|||
#define PWMCTL_PWEN1 (1<<0)
|
||||
#define PWMDMAC_ENAB (1<<31)
|
||||
#define PWMDMAC_THRSHLD ((15<<8)|(15<<0))
|
||||
enum pwmmode{pwm1pin,pwm2pin,pwm1pinrepeat};
|
||||
|
||||
class pwmgpio:public gpio
|
||||
{
|
||||
|
@ -196,6 +212,9 @@ class pwmgpio:public gpio
|
|||
int Mash;
|
||||
int Prediv; //Range of PWM
|
||||
uint64_t Pllfrequency;
|
||||
bool ModulateFromMasterPLL=false;
|
||||
int ModePwm=pwm1pin;
|
||||
generalgpio gengpio;
|
||||
public:
|
||||
pwmgpio();
|
||||
~pwmgpio();
|
||||
|
@ -203,6 +222,9 @@ class pwmgpio:public gpio
|
|||
uint64_t GetPllFrequency(int PllNo);
|
||||
int SetFrequency(uint64_t Frequency);
|
||||
int SetPrediv(int predivisor);
|
||||
void SetMode(int Mode);
|
||||
void enablepwm(int gpio,int PwmNumber);
|
||||
void disablepwm(int gpio);
|
||||
};
|
||||
|
||||
//******************************* PCM GPIO (I2S) ***********************************
|
||||
|
@ -229,6 +251,7 @@ class pcmgpio:public gpio
|
|||
int pllnumber;
|
||||
int Mash;
|
||||
int Prediv; //Range of PCM
|
||||
|
||||
uint64_t Pllfrequency;
|
||||
int SetPrediv(int predivisor);
|
||||
|
||||
|
@ -238,6 +261,7 @@ class pcmgpio:public gpio
|
|||
int SetPllNumber(int PllNo,int MashType);
|
||||
uint64_t GetPllFrequency(int PllNo);
|
||||
int SetFrequency(uint64_t Frequency);
|
||||
int ComputePrediv(uint64_t Frequency);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -14,8 +14,9 @@ iqdmasync::iqdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint
|
|||
|
||||
tunefreq=TuneFrequency;
|
||||
clkgpio::SetAdvancedPllMode(true);
|
||||
clkgpio::SetCenterFrequency(TuneFrequency); // Write Mult Int and Frac : FixMe carrier is already there
|
||||
clkgpio::SetCenterFrequency(TuneFrequency,SampleRate); // Write Mult Int and Frac : FixMe carrier is already there
|
||||
clkgpio::SetFrequency(0);
|
||||
clkgpio::enableclk(4);
|
||||
syncwithpwm=false;
|
||||
|
||||
if(syncwithpwm)
|
||||
|
@ -45,6 +46,9 @@ iqdmasync::iqdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint
|
|||
|
||||
iqdmasync::~iqdmasync()
|
||||
{
|
||||
padgpio pad;
|
||||
pad.gpioreg[PADS_GPIO_0]=Originfsel;
|
||||
clkgpio::disableclk(4);
|
||||
}
|
||||
|
||||
void iqdmasync::SetPhase(bool inversed)
|
||||
|
|
|
@ -3,4 +3,7 @@
|
|||
#include "fmdmasync.h"
|
||||
#include "ngfmdmasync.h"
|
||||
#include "iqdmasync.h"
|
||||
#include "bpsk.h"
|
||||
#include "serialdmasync.h"
|
||||
#include "phasedmasync.h"
|
||||
#include "dsp.h"
|
||||
|
|
|
@ -11,8 +11,9 @@ ngfmdmasync::ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,
|
|||
|
||||
tunefreq=TuneFrequency;
|
||||
clkgpio::SetAdvancedPllMode(true);
|
||||
clkgpio::SetCenterFrequency(TuneFrequency); // Write Mult Int and Frac : FixMe carrier is already there
|
||||
clkgpio::SetCenterFrequency(TuneFrequency,SampleRate); // Write Mult Int and Frac : FixMe carrier is already there
|
||||
clkgpio::SetFrequency(0);
|
||||
clkgpio::enableclk(4); // GPIO 4 CLK by default
|
||||
syncwithpwm=false;
|
||||
|
||||
if(syncwithpwm)
|
||||
|
@ -39,6 +40,7 @@ ngfmdmasync::ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,
|
|||
|
||||
ngfmdmasync::~ngfmdmasync()
|
||||
{
|
||||
clkgpio::disableclk(4);
|
||||
}
|
||||
|
||||
void ngfmdmasync::SetPhase(bool inversed)
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
|
||||
|
||||
#include "stdio.h"
|
||||
#include "phasedmasync.h"
|
||||
#include <unistd.h>
|
||||
|
||||
phasedmasync::phasedmasync(uint64_t TuneFrequency,uint32_t SampleRate,int NumberOfPhase,int Channel,uint32_t FifoSize):bufferdma(Channel,FifoSize,2,1) // Number of phase between 2 and 16
|
||||
{
|
||||
|
||||
SetMode(pwm1pinrepeat);
|
||||
pwmgpio::SetPllNumber(clk_plla,0);
|
||||
|
||||
tunefreq=TuneFrequency*NumberOfPhase;
|
||||
|
||||
if((NumberOfPhase==2)||(NumberOfPhase==4)||(NumberOfPhase==8)||(NumberOfPhase==16)||(NumberOfPhase==32))
|
||||
NumbPhase=NumberOfPhase;
|
||||
else
|
||||
fprintf(stderr,"PWM critical error: %d is not a legal number of phase\n",NumberOfPhase);
|
||||
clkgpio::SetAdvancedPllMode(true);
|
||||
|
||||
clkgpio::ComputeBestLO(tunefreq,0); // compute PWM divider according to MasterPLL clkgpio::PllFixDivider
|
||||
double FloatMult=((double)(tunefreq)*clkgpio::PllFixDivider)/(double)(XOSC_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;
|
||||
clkgpio::SetMasterMultFrac(IntMultiply,FracMultiply);
|
||||
fprintf(stderr,"PWM Mult %d Frac %d Div %d\n",IntMultiply,FracMultiply,clkgpio::PllFixDivider);
|
||||
|
||||
|
||||
pwmgpio::clk.gpioreg[PWMCLK_DIV] = 0x5A000000 | ((clkgpio::PllFixDivider)<<12); // PWM clock input divider
|
||||
usleep(100);
|
||||
pwmgpio::clk.gpioreg[PWMCLK_CNTL]= 0x5A000000 | (pwmgpio::Mash << 9) | pwmgpio::pllnumber|(1 << 4) ; //4 is START CLK
|
||||
usleep(100);
|
||||
pwmgpio::SetPrediv(32); //SetMode should be called before
|
||||
|
||||
|
||||
|
||||
enablepwm(12,0); // By default PWM on GPIO 12/pin 32
|
||||
|
||||
|
||||
pcmgpio::SetPllNumber(clk_plld,1);// Clk for Samplerate by PCM
|
||||
pcmgpio::SetFrequency(SampleRate);
|
||||
|
||||
|
||||
|
||||
SetDmaAlgo();
|
||||
|
||||
uint32_t ZeroPhase=0;
|
||||
switch(NumbPhase)
|
||||
{
|
||||
case 2:ZeroPhase=0xAAAAAAAA;break;//1,0,1,0 1,0,1,0
|
||||
case 4:ZeroPhase=0xCCCCCCCC;break;//1,1,0,0 //4
|
||||
case 8:ZeroPhase=0xF0F0F0F0;break;//1,1,1,1,0,0,0,0 //8
|
||||
case 16:ZeroPhase=0xFF00FF00;break;//1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 //16
|
||||
case 32:ZeroPhase=0xFFFF0000;break;//1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //32
|
||||
default:fprintf(stderr,"Zero phase not initialized\n");break;
|
||||
}
|
||||
|
||||
for(int i=0;i<NumbPhase;i++)
|
||||
{
|
||||
TabPhase[i]=ZeroPhase;
|
||||
fprintf(stderr,"Phase[%d]=%x\n",i,TabPhase[i]);
|
||||
ZeroPhase=(ZeroPhase<<1)|(ZeroPhase>>31);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
phasedmasync::~phasedmasync()
|
||||
{
|
||||
disablepwm(12);
|
||||
}
|
||||
|
||||
|
||||
void phasedmasync::SetDmaAlgo()
|
||||
{
|
||||
dma_cb_t *cbp = cbarray;
|
||||
for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++)
|
||||
{
|
||||
|
||||
|
||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
||||
cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ;
|
||||
cbp->length = 4;
|
||||
cbp->stride = 0;
|
||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
||||
cbp++;
|
||||
|
||||
|
||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PCM_TX);
|
||||
cbp->src = mem_virt_to_phys(cbarray); // Data is not important as we use it only to feed the PWM
|
||||
cbp->dst = 0x7E000000 + (PCM_FIFO_A<<2) + PCM_BASE ;
|
||||
cbp->length = 4;
|
||||
cbp->stride = 0;
|
||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
||||
cbp++;
|
||||
}
|
||||
|
||||
cbp--;
|
||||
cbp->next = mem_virt_to_phys(cbarray); // We loop to the first CB
|
||||
//fprintf(stderr,"Last cbp : src %x dest %x next %x\n",cbp->src,cbp->dst,cbp->next);
|
||||
}
|
||||
|
||||
void phasedmasync::SetPhase(uint32_t Index,int Phase)
|
||||
{
|
||||
Index=Index%buffersize;
|
||||
Phase=Phase%NumbPhase;
|
||||
sampletab[Index]=TabPhase[Phase];
|
||||
PushSample(Index);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef DEF_PHASEDMASYNC
|
||||
#define DEF_PHASEDMASYNC
|
||||
|
||||
#include "stdint.h"
|
||||
#include "dma.h"
|
||||
#include "gpio.h"
|
||||
|
||||
class phasedmasync:public bufferdma,public clkgpio,public pwmgpio,public pcmgpio,public generalgpio
|
||||
{
|
||||
protected:
|
||||
uint64_t tunefreq;
|
||||
int NumbPhase=2;
|
||||
|
||||
uint32_t TabPhase[32];//32 is Max Phase
|
||||
public:
|
||||
phasedmasync(uint64_t TuneFrequency,uint32_t SampleRate,int NumberOfPhase,int Channel,uint32_t FifoSize);
|
||||
~phasedmasync();
|
||||
void SetDmaAlgo();
|
||||
void SetPhase(uint32_t Index,int Phase);
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
|
||||
#include "stdio.h"
|
||||
#include "serialdmasync.h"
|
||||
|
||||
|
||||
serialdmasync::serialdmasync(uint32_t SampleRate,int Channel,uint32_t FifoSize,bool dualoutput):bufferdma(Channel,FifoSize,1,1)
|
||||
{
|
||||
if(dualoutput) //Fixme if 2pin we want maybe 2*SRATE as it is distributed over 2 pin
|
||||
{
|
||||
pwmgpio::SetMode(pwm2pin);
|
||||
SampleRate*=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pwmgpio::SetMode(pwm1pin);
|
||||
}
|
||||
|
||||
if(SampleRate>250000)
|
||||
{
|
||||
pwmgpio::SetPllNumber(clk_plld,1);
|
||||
pwmgpio::SetFrequency(SampleRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
pwmgpio::SetPllNumber(clk_osc,1);
|
||||
pwmgpio::SetFrequency(SampleRate);
|
||||
}
|
||||
|
||||
enablepwm(12,0); // By default PWM on GPIO 12/pin 32
|
||||
enablepwm(13,0); // By default PWM on GPIO 13/pin 33
|
||||
|
||||
SetDmaAlgo();
|
||||
|
||||
|
||||
// Note : Spurious are at +/-(19.2MHZ/2^20)*Div*N : (N=1,2,3...) So we need to have a big div to spurious away BUT
|
||||
// Spurious are ALSO at +/-(19.2MHZ/2^20)*(2^20-Div)*N
|
||||
// Max spurious avoid is to be in the center ! Theory shoud be that spurious are set away at 19.2/2= 9.6Mhz ! But need to get account of div of PLLClock
|
||||
|
||||
}
|
||||
|
||||
serialdmasync::~serialdmasync()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void serialdmasync::SetDmaAlgo()
|
||||
{
|
||||
dma_cb_t *cbp = cbarray;
|
||||
for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++)
|
||||
{
|
||||
|
||||
|
||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);
|
||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
||||
cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ;
|
||||
cbp->length = 4;
|
||||
cbp->stride = 0;
|
||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
||||
cbp++;
|
||||
|
||||
}
|
||||
|
||||
cbp--;
|
||||
cbp->next = mem_virt_to_phys(cbarray); // We loop to the first CB
|
||||
//fprintf(stderr,"Last cbp : src %x dest %x next %x\n",cbp->src,cbp->dst,cbp->next);
|
||||
}
|
||||
|
||||
void serialdmasync::SetSample(uint32_t Index,int Sample)
|
||||
{
|
||||
Index=Index%buffersize;
|
||||
sampletab[Index]=Sample;
|
||||
|
||||
PushSample(Index);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef DEF_SERIALDMASYNC
|
||||
#define DEF_SERIALDMASYNC
|
||||
|
||||
#include "stdint.h"
|
||||
#include "dma.h"
|
||||
#include "gpio.h"
|
||||
|
||||
class serialdmasync:public bufferdma,public clkgpio,public pwmgpio
|
||||
{
|
||||
protected:
|
||||
uint64_t tunefreq;
|
||||
bool syncwithpwm;
|
||||
public:
|
||||
serialdmasync(uint32_t SampleRate,int Channel,uint32_t FifoSize,bool dualoutput);
|
||||
~serialdmasync();
|
||||
void SetDmaAlgo();
|
||||
|
||||
void SetSample(uint32_t Index,int Sample);
|
||||
};
|
||||
#endif
|
165
src/v2rpitx.cpp
165
src/v2rpitx.cpp
|
@ -2,36 +2,40 @@
|
|||
#include "librpitx.h"
|
||||
#include <unistd.h>
|
||||
#include "stdio.h"
|
||||
#include <cstring>
|
||||
#include <signal.h>
|
||||
|
||||
void SimpleTest()
|
||||
bool running=true;
|
||||
void SimpleTest(uint64_t Freq)
|
||||
{
|
||||
generalgpio generalio;
|
||||
generalio.enableclk();
|
||||
|
||||
|
||||
|
||||
clkgpio clk;
|
||||
clk.SetPllNumber(clk_plld,1);
|
||||
clk.print_clock_tree();
|
||||
//clk.SetPllNumber(clk_plla,0);
|
||||
clk.SetAdvancedPllMode(true);
|
||||
clk.SetCenterFrequency(144100000);
|
||||
for(int i=0;i<1000000;i+=1)
|
||||
clk.SetCenterFrequency(Freq,100000);
|
||||
clk.SetFrequency(000);
|
||||
clk.enableclk(4);
|
||||
sleep(60);
|
||||
/*for(int i=0;i<100000;i+=1)
|
||||
{
|
||||
clk.SetFrequency(i);
|
||||
//usleep(1);
|
||||
}
|
||||
|
||||
usleep(1000);
|
||||
}*/
|
||||
clk.disableclk(4);
|
||||
|
||||
}
|
||||
|
||||
void SimpleTestDMA()
|
||||
void SimpleTestDMA(uint64_t Freq)
|
||||
{
|
||||
generalgpio generalio;
|
||||
generalio.enableclk();
|
||||
|
||||
|
||||
int SR=200000;
|
||||
int FifoSize=4096;
|
||||
ngfmdmasync ngfmtest(1244200000,SR,14,FifoSize);
|
||||
|
||||
for(int i=0;i<SR;)
|
||||
//ngfmdmasync ngfmtest(1244200000,SR,14,FifoSize);
|
||||
ngfmdmasync ngfmtest(Freq,SR,14,FifoSize);
|
||||
for(int i=0;running;)
|
||||
{
|
||||
//usleep(10);
|
||||
usleep(FifoSize*1000000.0*3.0/(4.0*SR));
|
||||
|
@ -42,7 +46,7 @@ void SimpleTestDMA()
|
|||
//printf("GetIndex=%d\n",Index);
|
||||
for(int j=0;j<Available;j++)
|
||||
{
|
||||
ngfmtest.SetFrequencySample(Index,((i%10000)>5000)?1000:0);
|
||||
//ngfmtest.SetFrequencySample(Index,((i%10000)>5000)?1000:0);
|
||||
ngfmtest.SetFrequencySample(Index+j,(i%SR));
|
||||
i++;
|
||||
|
||||
|
@ -59,8 +63,7 @@ void SimpleTestDMA()
|
|||
using std::complex;
|
||||
void SimpleTestLiquid()
|
||||
{
|
||||
generalgpio generalio;
|
||||
generalio.enableclk();
|
||||
|
||||
|
||||
int SR=200000;
|
||||
int FifoSize=4096;
|
||||
|
@ -71,7 +74,7 @@ void SimpleTestLiquid()
|
|||
nco_crcf_set_frequency(q, -0.2f);
|
||||
|
||||
//ngfmtest.print_clock_tree();
|
||||
for(int i=0;i<SR;)
|
||||
for(int i=0;(i<SR)&&running;)
|
||||
{
|
||||
//usleep(10);
|
||||
usleep(FifoSize*1000000.0*3.0/(4.0*SR));
|
||||
|
@ -106,22 +109,23 @@ void SimpleTestLiquid()
|
|||
ngfmtest.stop();
|
||||
}
|
||||
|
||||
void SimpleTestFileIQ()
|
||||
void SimpleTestFileIQ(uint64_t Freq)
|
||||
{
|
||||
FILE *iqfile=NULL;
|
||||
iqfile=fopen("ssb.iq","rb");
|
||||
iqfile=fopen("../ssbtest.iq","rb");
|
||||
if (iqfile==NULL) printf("input file issue\n");
|
||||
|
||||
generalgpio generalio;
|
||||
generalio.enableclk();
|
||||
|
||||
bool stereo=true;
|
||||
int SR=48000;
|
||||
int FifoSize=512;
|
||||
iqdmasync iqtest(1242300000,SR,14,FifoSize);
|
||||
|
||||
//iqdmasync iqtest(1245000000,SR,14,FifoSize);
|
||||
//iqdmasync iqtest(50100000,SR,14,FifoSize);
|
||||
iqdmasync iqtest(Freq,SR,14,FifoSize);
|
||||
//iqdmasync iqtest(14100000,SR,14,FifoSize);
|
||||
short IQBuffer[128*2];
|
||||
printf("Sizeof = %d\n",sizeof(liquid_float_complex));
|
||||
while(1)
|
||||
|
||||
while(running)
|
||||
{
|
||||
//usleep(FifoSize*1000000.0*1.0/(8.0*SR));
|
||||
usleep(100);
|
||||
|
@ -152,10 +156,113 @@ void SimpleTestFileIQ()
|
|||
iqtest.stop();
|
||||
}
|
||||
|
||||
|
||||
void SimpleTestbpsk(uint64_t Freq)
|
||||
{
|
||||
|
||||
|
||||
clkgpio clk;
|
||||
clk.print_clock_tree();
|
||||
int SR=1000;
|
||||
int FifoSize=1024;
|
||||
int NumberofPhase=2;
|
||||
phasedmasync biphase(Freq,SR,NumberofPhase,14,FifoSize);
|
||||
int lastphase=0;
|
||||
while(running)
|
||||
{
|
||||
//usleep(FifoSize*1000000.0*1.0/(8.0*SR));
|
||||
usleep(10);
|
||||
int Available=biphase.GetBufferAvailable();
|
||||
if(Available>256)
|
||||
{
|
||||
int Index=biphase.GetUserMemIndex();
|
||||
|
||||
/*
|
||||
for(int i=0;i<Available;i++)
|
||||
{
|
||||
int phase=(rand()%NumberofPhase);
|
||||
biphase.SetPhase(Index+i,phase);
|
||||
}*/
|
||||
/*
|
||||
for(int i=0;i<Available/2;i++)
|
||||
{
|
||||
int phase=2*(rand()%NumberofPhase/2);
|
||||
biphase.SetPhase(Index+i*2,(phase+lastphase)/2);
|
||||
biphase.SetPhase(Index+i*2+1,phase);
|
||||
lastphase=phase;
|
||||
}*/
|
||||
for(int i=0;i<Available;i++)
|
||||
{
|
||||
lastphase=(lastphase+1)%NumberofPhase;
|
||||
biphase.SetPhase(Index+i,lastphase);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
biphase.stop();
|
||||
}
|
||||
|
||||
|
||||
void SimpleTestSerial()
|
||||
{
|
||||
|
||||
bool stereo=true;
|
||||
int SR=10000;
|
||||
int FifoSize=1024;
|
||||
bool dualoutput=true;
|
||||
serialdmasync testserial(SR,14,FifoSize,dualoutput);
|
||||
|
||||
while(running)
|
||||
{
|
||||
|
||||
usleep(10);
|
||||
int Available=testserial.GetBufferAvailable();
|
||||
if(Available>256)
|
||||
{
|
||||
int Index=testserial.GetUserMemIndex();
|
||||
|
||||
|
||||
for(int i=0;i<Available;i++)
|
||||
{
|
||||
|
||||
|
||||
testserial.SetSample(Index+i,i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
testserial.stop();
|
||||
}
|
||||
|
||||
static void
|
||||
terminate(int num)
|
||||
{
|
||||
running=false;
|
||||
fprintf(stderr,"Caught signal - Terminating\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SimpleTestFileIQ();
|
||||
|
||||
uint64_t Freq=144200000;
|
||||
if(argc>1)
|
||||
Freq=atol(argv[1]);
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
struct sigaction sa;
|
||||
|
||||
std::memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = terminate;
|
||||
sigaction(i, &sa, NULL);
|
||||
}
|
||||
|
||||
//SimpleTest(Freq);
|
||||
//SimpleTestbpsk(Freq);
|
||||
//SimpleTestFileIQ(Freq);
|
||||
SimpleTestDMA(Freq);
|
||||
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue