v2beta
F5OEO 2018-03-06 12:08:00 +00:00
rodzic d0d2fd9aff
commit a2dc4f509c
7 zmienionych plików z 94 dodań i 65 usunięć

Wyświetl plik

@ -43,7 +43,7 @@ dma::dma(int Channel,uint32_t CBSize,uint32_t UserMemSize) // Fixme! Need to che
usermem= (unsigned int *)(virtbase+CBSize*sizeof(dma_cb_t)); // user memory is placed after
//fprintf(stderr,"usermem %p\n", usermem);
dma_reg.gpioreg[DMA_CS+channel*0x40] = BCM2708_DMA_RESET;
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
}
@ -138,6 +138,12 @@ bool dma::isrunning()
return ((dma_reg.gpioreg[DMA_CS+channel*0x40]&DMA_CS_ACTIVE)>0);
}
bool dma::isunderflow()
{
//if((dma_reg.gpioreg[DMA_CS+channel*0x40]&DMA_CS_INT)>0) fprintf(stderr,"Status:%x\n",dma_reg.gpioreg[DMA_CS+channel*0x40]);
return ((dma_reg.gpioreg[DMA_CS+channel*0x40]&DMA_CS_INT)>0);
}
//**************************************** BUFFER DMA ********************************************************
bufferdma::bufferdma(int Channel,uint32_t tbuffersize,uint32_t tcbbysample,uint32_t tregisterbysample):dma(Channel,tbuffersize*tcbbysample,tbuffersize*tregisterbysample)
{
@ -173,24 +179,29 @@ int bufferdma::GetBufferAvailable()
}
else
{
fprintf(stderr,"DMA Stopped\n");
fprintf(stderr,"DMA WEIRD STATE\n");
current_sample=0;
}
//fprintf(stderr,"CurrentCB=%d\n",current_sample);
diffsample=current_sample-last_sample;
if(diffsample<=0) diffsample+=buffersize;
if(diffsample<0) diffsample+=buffersize;
fprintf(stderr,"cur %d last %d diff%d\n",current_sample,last_sample,diffsample);
//fprintf(stderr,"cur %d last %d diff%d\n",current_sample,last_sample,diffsample);
}
else
{
last_sample=buffersize-1;
//last_sample=buffersize-1;
diffsample=buffersize;
current_sample=0;
fprintf(stderr,"Warning DMA stopped \n");
fprintf(stderr,"cur %d last %d diff%d\n",current_sample,last_sample,diffsample);
//fprintf(stderr,"Warning DMA stopped \n");
//fprintf(stderr,"S:cur %d last %d diff%d\n",current_sample,last_sample,diffsample);
}
if(isunderflow())
{
fprintf(stderr,"cur %d last %d \n",current_sample,last_sample);
fprintf(stderr,"Underflow\n");
}
return diffsample;
}
@ -203,7 +214,7 @@ int bufferdma::GetUserMemIndex()
if(GetBufferAvailable()>0)
{
IndexAvailable=last_sample+1;
if(IndexAvailable>=(int)buffersize-1) IndexAvailable=0;
if(IndexAvailable>=(int)buffersize) IndexAvailable=0;
}
return IndexAvailable;
}
@ -214,16 +225,30 @@ int bufferdma::PushSample(int Index)
/*dma_cb_t *cbp;
cbp=&cbarray[last_sample*cbbysample+cbbysample-1];
cbp->next=mem_virt_to_phys(&cbarray[Index]);
*/
cbp->next=mem_virt_to_phys(&cbarray[Index]);*/
dma_cb_t *cbp;
cbp=&cbarray[last_sample*cbbysample+cbbysample-1];
//fprintf(stderr,"Info=%x\n",cbp->info);
cbp->info=cbp->info&(~BCM2708_DMA_SET_INT);
//fprintf(stderr,"Info2=%x\n",cbp->info);
last_sample=Index;
/*
cbp=&cbarray[Index*cbbysample+cbbysample-1];
cbp->next=0;
*/
//fprintf(stderr,"Info=%x\n",cbp->info);
cbp->info=cbp->info|(BCM2708_DMA_SET_INT);
//fprintf(stderr,"Info2=%x\n",cbp->info);
/*if(isunderflow())
{
fprintf(stderr,"cur %d last %d \n",current_sample,last_sample);
fprintf(stderr,"Underflow\n");
}*/
if(isrunning()==false)
{
start();
if(last_sample>buffersize/4) start(); // 1/4 Fill buffer before starting DMA
}
return 0;

Wyświetl plik

@ -89,6 +89,7 @@ class dma
int stop();
int getcbposition();
bool isrunning();
bool isunderflow();
};

Wyświetl plik

@ -64,6 +64,7 @@ clkgpio::~clkgpio()
int clkgpio::SetPllNumber(int PllNo,int MashType)
{
//print_clock_tree();
if(PllNo<8)
pllnumber=PllNo;
else
@ -112,9 +113,9 @@ int clkgpio::SetMasterMultFrac(uint32_t Mult,uint32_t Frac)
{
gpioreg[PLLA_CTRL] = (0x5a<<24) | (0x21<<12) | Mult;
//usleep(10);
gpioreg[PLLA_FRAC]= 0x5A000000 | Frac ; //4 is START CLK
// usleep(10);
usleep(10);
gpioreg[PLLA_FRAC]= 0x5A000000 | Frac ;
usleep(10);
return 0;
}
@ -178,6 +179,7 @@ int clkgpio::SetCenterFrequency(uint64_t Frequency)
//Choose best PLLDiv and Div
ComputeBestLO(Frequency);
SetClkDivFrac(PllFixDivider,0); // NO MASH !!!!
SetFrequency(Frequency);
}
else
{
@ -200,7 +202,9 @@ void clkgpio::SetAdvancedPllMode(bool Advanced)
{
SetPllNumber(clk_plla,0); // Use PPL_A , Do not USE MASH which generates spurious
gpioreg[0x104/4]=0x5A00020A; // Enable Plla_PER
usleep(100);
gpioreg[PLLA_PER]=0x5A000002; // Div ?
usleep(100);
}
}
@ -361,32 +365,45 @@ uint64_t pwmgpio::GetPllFrequency(int PllNo)
int pwmgpio::SetFrequency(uint64_t Frequency)
{
double Freqresult=(double)Pllfrequency/(double)Frequency;
Prediv=2; // Fixe for now , need investigation if not 32 !!!! FixMe !
double Freqresult=(double)Pllfrequency/(double)(Frequency*Prediv);
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");
fprintf(stderr,"PWM clk=%d / %d\n",FreqDivider,FreqFractionnal);
clk.gpioreg[PWMCLK_DIV] = 0x5A000000 | ((FreqDivider)<<12) | FreqFractionnal;
usleep(100);
clk.gpioreg[PWMCLK_CNTL]= 0x5A000000 | (Mash << 9) | pllnumber|(1 << 4) ; //4 is STAR CLK
usleep(100);
usleep(100);
fprintf(stderr,"PWM Reg %x\n",clk.gpioreg[PWMCLK_CNTL]);
SetPrediv(Prediv);
return 0;
}
int pwmgpio::SetMode(int Mode) //Mode should be only for SYNC or a Data serializer : Todo
int pwmgpio::SetPrediv(int predivisor) //Mode should be only for SYNC or a Data serializer : Todo
{
gpioreg[PWM_RNG1] = 32;// 250 -> 8KHZ
Prediv=predivisor;
if(Prediv>32)
{
fprintf(stderr,"PWM Prediv is max 32\n");
Prediv=2;
}
fprintf(stderr,"PWM Prediv %d\n",Prediv);
gpioreg[PWM_RNG1] = Prediv;// 250 -> 8KHZ
usleep(100);
gpioreg[PWM_RNG2] = 32;// 32 Mandatory for Serial Mode without gap
gpioreg[PWM_RNG2] = Prediv;// 32 Mandatory for Serial Mode without gap
gpioreg[PWM_FIFO]=0xAAAAAAAA;
//gpioreg[PWM_FIFO]=0xAAAAAAAA;
gpioreg[PWM_DMAC] = PWMDMAC_ENAB | PWMDMAC_THRSHLD;
usleep(100);
//gpioreg[PWM_CTL] = PWMCTL_CLRF;
gpioreg[PWM_CTL] = PWMCTL_USEF1 | PWMCTL_PWEN1; //PWM0 in Repeat mode
gpioreg[PWM_CTL] = PWMCTL_CLRF;
usleep(100);
gpioreg[PWM_CTL] = PWMCTL_USEF1 | PWMCTL_PWEN1;
usleep(100);
return 0;

Wyświetl plik

@ -21,6 +21,7 @@ class gpio
#define BCM2708_DMA_DST_IGNOR (1<<7)
#define BCM2708_DMA_NO_WIDE_BURSTS (1<<26)
#define BCM2708_DMA_WAIT_RESP (1<<3)
#define BCM2708_DMA_SET_INT (1<<0)
#define BCM2708_DMA_D_DREQ (1<<6)
#define BCM2708_DMA_PER_MAP(x) ((x)<<16)
@ -36,6 +37,7 @@ class gpio
#define DMA_CS_RESET (1<<31)
#define DMA_CS_ABORT (1<<30)
#define DMA_CS_DISDEBUG (1<<28)
#define DMA_CS_INT (1<<2)
#define DMA_CS_END (1<<1)
#define DMA_CS_ACTIVE (1<<0)
#define DMA_CS_PRIORITY(x) ((x)&0xf << 16)
@ -192,6 +194,7 @@ class pwmgpio:public gpio
clkgpio clk;
int pllnumber;
int Mash;
int Prediv; //Range of PWM
uint64_t Pllfrequency;
public:
pwmgpio();
@ -199,7 +202,7 @@ class pwmgpio:public gpio
int SetPllNumber(int PllNo,int MashType);
uint64_t GetPllFrequency(int PllNo);
int SetFrequency(uint64_t Frequency);
int SetMode(int Mode);
int SetPrediv(int predivisor);
};
//******************************* PCM GPIO (I2S) ***********************************

Wyświetl plik

@ -12,7 +12,7 @@ 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::SetFrequency(0);
/*
double FloatMult=((double)TuneFrequency)/(double)(XOSC_FREQUENCY);
@ -28,9 +28,10 @@ ngfmdmasync::ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,
*/
pwmgpio::SetPllNumber(clk_osc,1);
//pwmgpio::SetPllNumber(clk_plld,1);
pwmgpio::SetFrequency(SampleRate);
pwmgpio::SetMode(0);
SetDmaAlgo();
@ -84,7 +85,7 @@ void ngfmdmasync::SetDmaAlgo()
// Delay
cbp->info = /*BCM2708_DMA_SRC_IGNOR | */BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP | BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);
cbp->info = /*BCM2708_DMA_SRC_IGNOR |*/ 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(cbarray); // Data is not important as we use it only to feed the PWM
cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ;
cbp->length = 4;
@ -106,24 +107,4 @@ void ngfmdmasync::SetFrequencySample(uint32_t Index,int Frequency)
PushSample(Index);
}
void ngfmdmasync::FillMemory(uint32_t MultInt,uint32_t FirstFrac)
{
//if(FirstFrac<usermemsize) FirstFrac=usermemsize;
uint32_t tempmul=MultInt;
for (uint32_t samplecnt = 0; samplecnt < usermemsize/2; samplecnt++)
{
//uint32_t Frac=(FirstFrac+samplecnt*((samplecnt%2==0)?1:-1))&0xFFFFF;
uint32_t Frac=(FirstFrac+samplecnt/10)%(1<<20); //10times less than symbolrate
//fprintf(stderr,"Frac %d\n",Frac);
if(Frac==0)
{
fprintf(stderr,"Cross Int\n");
tempmul=MultInt+1;
}
//usermem[samplecnt*2]=(0x5a<<24) | (0x21<<12) | tempmul;
//usermem[samplecnt*2+1]=0x5A000000 | Frac;
usermem[samplecnt*2]=0x5A000000 | FirstFrac;
}
}

Wyświetl plik

@ -13,7 +13,7 @@ class ngfmdmasync:public bufferdma,public clkgpio,public pwmgpio
ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint32_t FifoSize);
~ngfmdmasync();
void SetDmaAlgo();
void FillMemory(uint32_t MultInt,uint32_t FirstFrac);
void SetPhase(bool inversed);
void SetFrequencySample(uint32_t Index,int Frequency);
};

Wyświetl plik

@ -10,8 +10,8 @@ int main(int argc, char* argv[])
generalgpio generalio;
generalio.enableclk();
/*
clkgpio clk;
/*clkgpio clk;
clk.SetPllNumber(clk_plld,1);
clk.SetAdvancedPllMode(true);
clk.SetCenterFrequency(144100000);
@ -20,28 +20,30 @@ int main(int argc, char* argv[])
clk.SetFrequency(i);
usleep(10);
}
sleep(5);
*/
sleep(5);*/
//dma mydma(14,32,16);
//bufferdma mydma(14,16,2,1);
ngfmdmasync ngfmtest(144100000,5000,14,128);
for(int i=0;i<256;i++)
ngfmdmasync ngfmtest(144100000,200000,14,512);
for(int i=0;i<1000000;)
{
//usleep(10);
int Index=ngfmtest.GetUserMemIndex();
//printf("GetIndex=%d\n",Index);
if(Index>=0)
{
ngfmtest.SetFrequencySample(Index,i*10);
//ngfmtest.SetFrequencySample(Index,((i%10000)>5000)?1000:0);
ngfmtest.SetFrequencySample(Index,i%100000);
i++;
}
else
usleep(10);
}
fprintf(stderr,"End\n");
sleep(10);
ngfmtest.stop();