diff --git a/src/Makefile b/src/Makefile index b743510..8a30cc3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,8 +18,8 @@ CC = gcc 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) -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 + $(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 amdmasync.h amdmasync.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 amdmasync.o v2rpitx: librpitx.h librpitx.a diff --git a/src/amdmasync.cpp b/src/amdmasync.cpp new file mode 100644 index 0000000..24a4029 --- /dev/null +++ b/src/amdmasync.cpp @@ -0,0 +1,123 @@ + +#include "stdio.h" +#include "amdmasync.h" +#include + + +amdmasync::amdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint32_t FifoSize):bufferdma(Channel,FifoSize,3,2) +{ + + + tunefreq=TuneFrequency; + clkgpio::SetAdvancedPllMode(true); + clkgpio::SetCenterFrequency(TuneFrequency,SampleRate); + clkgpio::SetFrequency(0); + clkgpio::enableclk(4); // GPIO 4 CLK by default + syncwithpwm=false; + + if(syncwithpwm) + { + pwmgpio::SetPllNumber(clk_plld,1); + pwmgpio::SetFrequency(SampleRate); + } + else + { + pcmgpio::SetPllNumber(clk_plld,1); + pcmgpio::SetFrequency(SampleRate); + } + + padgpio pad; + Originfsel=pad.gpioreg[PADS_GPIO_0]; + + SetDmaAlgo(); + + +} + +amdmasync::~amdmasync() +{ + clkgpio::disableclk(4); + padgpio pad; + pad.gpioreg[PADS_GPIO_0]=Originfsel; +} + + + +void amdmasync::SetDmaAlgo() +{ + dma_cb_t *cbp = cbarray; + for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++) + { + + //@0 + //Set Amplitude by writing to PADS + cbp->info = 0;//BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]); + cbp->dst = 0x7E000000+(PADS_GPIO_0<<2)+PADS_GPIO; + cbp->length = 4; + cbp->stride = 0; + cbp->next = mem_virt_to_phys(cbp + 1); + cbp++; + + //@1 + //Set Amplitude to FSEL for amplitude=0 + cbp->info = 0;//BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample+1]); + cbp->dst = 0x7E000000 + (GPFSEL0<<2)+GENERAL_BASE; + cbp->length = 4; + cbp->stride = 0; + cbp->next = mem_virt_to_phys(cbp + 1); + cbp++; + + + // Delay + if(syncwithpwm) + cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM); + else + 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 + if(syncwithpwm) + cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ; + else + 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 amdmasync::SetAmSample(uint32_t Index,float Amplitude) //-1;1 +{ + Index=Index%buffersize; + + int IntAmplitude=round(abs(Amplitude)*8.0)-1; + + int IntAmplitudePAD=IntAmplitude; + if(IntAmplitudePAD>7) IntAmplitudePAD=7; + if(IntAmplitudePAD<0) IntAmplitudePAD=0; + + //fprintf(stderr,"Amplitude=%f PAD %d\n",Amplitude,IntAmplitudePAD); + sampletab[Index*registerbysample]=(0x5A<<24) + (IntAmplitudePAD&0x7) + (1<<4) + (0<<3); // Amplitude PAD + + //sampletab[Index*registerbysample+2]=(Originfsel & ~(7 << 12)) | (4 << 12); //Alternate is CLK + if(IntAmplitude==-1) + { + sampletab[Index*registerbysample+1]=(Originfsel & ~(7 << 12)) | (0 << 12); //Pin is in -> Amplitude 0 + } + else + { + sampletab[Index*registerbysample+1]=(Originfsel & ~(7 << 12)) | (4 << 12); //Alternate is CLK + } + + + PushSample(Index); +} + + diff --git a/src/amdmasync.h b/src/amdmasync.h new file mode 100644 index 0000000..29d9f92 --- /dev/null +++ b/src/amdmasync.h @@ -0,0 +1,22 @@ +#ifndef DEF_AMDMASYNC +#define DEF_AMDMASYNC + +#include "stdint.h" +#include "dma.h" +#include "gpio.h" + +class amdmasync:public bufferdma,public clkgpio,public pwmgpio,public pcmgpio +{ + protected: + uint64_t tunefreq; + bool syncwithpwm; + uint32_t Originfsel; + public: + amdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint32_t FifoSize); + ~amdmasync(); + void SetDmaAlgo(); + + void SetAmSample(uint32_t Index,float Amplitude); +}; + +#endif diff --git a/src/amdmasync.h.gch b/src/amdmasync.h.gch new file mode 100644 index 0000000..3493a56 Binary files /dev/null and b/src/amdmasync.h.gch differ diff --git a/src/gpio.cpp b/src/gpio.cpp index bcecd29..5a5deae 100644 --- a/src/gpio.cpp +++ b/src/gpio.cpp @@ -176,7 +176,7 @@ int clkgpio::ComputeBestLO(uint64_t Frequency,int Bandwidth) for( divider=1;divider<4096;divider++) { if( Frequency*divider < 600e6 ) continue; // widest accepted frequency range - if( Frequency*divider > 1500e6 ) break; + if( Frequency*divider > 1800e6 ) break; max_int_multiplier=((int)((double)(Frequency+Bandwidth)*divider*xtal_freq_recip)); min_int_multiplier=((int)((double)(Frequency-Bandwidth)*divider*xtal_freq_recip)); @@ -194,7 +194,8 @@ 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( (frac_multiplier>0.2) && (frac_multiplier<0.8) ) fom+=2; // prefer mulipliers away from integer boundaries + if((int_multiplier%2)==0) fom++; + 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 @@ -267,6 +268,22 @@ 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); + + uint32_t ana[4]; + for(int i=3;i>=0;i--) + { + ana[i]=gpioreg[(0x1010/4)+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]; + } + + usleep(100); gpioreg[PLLA_PER]=0x5A000002; // Div ? usleep(100); @@ -289,6 +306,11 @@ void clkgpio::print_clock_tree(void) printf("PLLC_DIG2R=%08x\n",gpioreg[(0x1828/4)]); printf("PLLC_DIG3R=%08x\n",gpioreg[(0x182c/4)]); + printf("PLLA_ANA0=%08x\n",gpioreg[(0x1010/4)]); + printf("PLLA_ANA1=%08x prediv=%d\n",gpioreg[(0x1014/4)],(gpioreg[(0x1014/4)]>>14)&1); + printf("PLLA_ANA2=%08x\n",gpioreg[(0x1018/4)]); + printf("PLLA_ANA3=%08x\n",gpioreg[(0x101c/4)]); + printf("GNRIC CTL=%08x DIV=%8x ",gpioreg[ 0],gpioreg[ 1]); printf("VPU CTL=%08x DIV=%8x\n",gpioreg[ 2],gpioreg[ 3]); printf("SYS CTL=%08x DIV=%8x ",gpioreg[ 4],gpioreg[ 5]); @@ -304,7 +326,7 @@ void clkgpio::print_clock_tree(void) printf("DSI0E CTL=%08x DIV=%8x\n",gpioreg[22],gpioreg[23]); printf("DSI0P CTL=%08x DIV=%8x ",gpioreg[24],gpioreg[25]); printf("DPI CTL=%08x DIV=%8x\n",gpioreg[26],gpioreg[27]); - printf("GP0 CTL=%08x DIV=%8x ",gpioreg[28],gpioreg[29]); + printf("GP0 CTL=%08x DIV=%8x ",gpioreg[0x70/4],gpioreg[0x74/4]); printf("GP1 CTL=%08x DIV=%8x\n",gpioreg[30],gpioreg[31]); printf("GP2 CTL=%08x DIV=%8x ",gpioreg[32],gpioreg[33]); diff --git a/src/librpitx.h b/src/librpitx.h index 58f5ba8..80c61ea 100644 --- a/src/librpitx.h +++ b/src/librpitx.h @@ -3,7 +3,7 @@ #include "fmdmasync.h" #include "ngfmdmasync.h" #include "iqdmasync.h" -#include "bpsk.h" #include "serialdmasync.h" #include "phasedmasync.h" +#include "amdmasync.h" #include "dsp.h" diff --git a/src/v2rpitx.cpp b/src/v2rpitx.cpp index 12ec200..fd77559 100644 --- a/src/v2rpitx.cpp +++ b/src/v2rpitx.cpp @@ -8,16 +8,31 @@ bool running=true; 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[GPPUDCLK0]=(1<<4); //GPIO CLK is GPIO 4 + usleep(100); + //genpio.gpioreg[GPPUDCLK0]=(0); //GPIO CLK is GPIO 4 clkgpio clk; clk.print_clock_tree(); //clk.SetPllNumber(clk_plla,0); clk.SetAdvancedPllMode(true); clk.SetCenterFrequency(Freq,100000); + int Deviation=0; clk.SetFrequency(000); clk.enableclk(4); - sleep(60); + while(running) + { + sleep(5); + //Deviation+=1; + clk.SetFrequency(Deviation); + } /*for(int i=0;i<100000;i+=1) { clk.SetFrequency(i); @@ -163,7 +178,7 @@ void SimpleTestbpsk(uint64_t Freq) clkgpio clk; clk.print_clock_tree(); - int SR=1000; + int SR=100000; int FifoSize=1024; int NumberofPhase=2; phasedmasync biphase(Freq,SR,NumberofPhase,14,FifoSize); @@ -177,12 +192,12 @@ void SimpleTestbpsk(uint64_t Freq) { int Index=biphase.GetUserMemIndex(); - /* + for(int i=0;i256) + { + int Index=amtest.GetUserMemIndex(); + int nbread=fread(AudioBuffer,sizeof(short),128*2,audiofile); + if(nbread>0) + { + + for(int i=0;i256) + { + int Index=amtest.GetUserMemIndex(); + for(int i=0;i2) x=0; else x=1; + //x+=(1.0/(float)SR*10.0); + x+=0.0001; + if(x>1.0) x=0; + + amtest.SetAmSample(Index+i,x); + count++; + } + } + } + amtest.stop(); +} + static void terminate(int num) { @@ -259,10 +362,12 @@ int main(int argc, char* argv[]) sigaction(i, &sa, NULL); } - //SimpleTest(Freq); + SimpleTest(Freq); //SimpleTestbpsk(Freq); //SimpleTestFileIQ(Freq); - SimpleTestDMA(Freq); + //SimpleTestDMA(Freq); + //SimpleTestAm(Freq); + //SimpleTestOOK(Freq); }