diff --git a/src/dma.h b/src/dma.h index b9f57ca..92aa2bb 100644 --- a/src/dma.h +++ b/src/dma.h @@ -71,6 +71,8 @@ class dma uint32_t mem_flag; //Cache or not depending on Rpi1 or 2/3 uint32_t dram_phys_base; + + public: dma_cb_t *cbarray; uint32_t cbsize; @@ -86,6 +88,6 @@ class dma int start(); int stop(); uint32_t getcbposition(); - + }; #endif diff --git a/src/ngfmdmasync.cpp b/src/ngfmdmasync.cpp index f3d8826..5bb7e6b 100644 --- a/src/ngfmdmasync.cpp +++ b/src/ngfmdmasync.cpp @@ -1,8 +1,11 @@ +// Inspired by https://github.com/SaucySoliton/PiFmRds/blob/master/src/pi_fm_rds.c + + #include "stdio.h" #include "ngfmdmasync.h" -ngfmdmasync::ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint32_t FifoSize):dma(Channel,FifoSize*2,FifoSize) +ngfmdmasync::ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel,uint32_t FifoSize):dma(Channel,FifoSize*3,FifoSize*2) { tunefreq=TuneFrequency; clkgpio::SetPllNumber(clk_plla,0); // Use PPL_A , Do not USE MASH which generates spurious @@ -23,10 +26,15 @@ ngfmdmasync::ngfmdmasync(uint64_t TuneFrequency,uint32_t SampleRate,int Channel, pwmgpio::SetPllNumber(clk_osc,1); pwmgpio::SetFrequency(SampleRate); pwmgpio::SetMode(0); - + fprintf(stderr,"PLLA Div %d Frac %d\n",IntMultiply,FracMultiply); //clkgpio::print_clock_tree(); SetDmaAlgo(); - FillMemory(FracMultiply); + FillMemory(IntMultiply,FracMultiply); + + // 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 + } ngfmdmasync::~ngfmdmasync() @@ -36,13 +44,24 @@ ngfmdmasync::~ngfmdmasync() void ngfmdmasync::SetDmaAlgo() { dma_cb_t *cbp = cbarray; - for (uint32_t samplecnt = 0; samplecnt < cbsize/2; samplecnt++) { //cbsize/2 because we have 2 CB by sample + for (uint32_t samplecnt = 0; samplecnt < usermemsize/2; samplecnt++) + { - // Write a frequency sample cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; - cbp->src = mem_virt_to_phys(&usermem[samplecnt]); + cbp->src = mem_virt_to_phys(&usermem[samplecnt*2]); + cbp->dst = 0x7E000000 + (PLLA_CTRL<<2) + CLK_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++; + + // Write a frequency sample + + cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->src = mem_virt_to_phys(&usermem[samplecnt*2+1]); cbp->dst = 0x7E000000 + (PLLA_FRAC<<2) + CLK_BASE ; cbp->length = 4; cbp->stride = 0; @@ -68,14 +87,24 @@ void ngfmdmasync::SetDmaAlgo() //fprintf(stderr,"Last cbp : src %x dest %x next %x\n",cbp->src,cbp->dst,cbp->next); } -void ngfmdmasync::FillMemory(uint32_t FirstFrac) +void ngfmdmasync::FillMemory(uint32_t MultInt,uint32_t FirstFrac) { - if(FirstFrac