From b356479493c03155b6fb3aedf20d8cebb275dfbc Mon Sep 17 00:00:00 2001 From: F5OEO Date: Tue, 1 Jan 2019 21:45:37 +0000 Subject: [PATCH] Rework DMA for ATV --- app/testrpitx.cpp | 118 +++++++++++++++++--------------------- src/atv.cpp | 142 +++++++++++++++++----------------------------- src/atv.h | 9 +-- 3 files changed, 108 insertions(+), 161 deletions(-) diff --git a/app/testrpitx.cpp b/app/testrpitx.cpp index eddf1af..35bb4ad 100644 --- a/app/testrpitx.cpp +++ b/app/testrpitx.cpp @@ -511,7 +511,6 @@ void AlectoOOK(uint64_t Freq) } } - void RfSwitchOOK(uint64_t Freq) { /* @@ -532,7 +531,7 @@ void RfSwitchOOK(uint64_t Freq) * Every message is repeated four times. * */ ookbursttiming ooksender(Freq, 1200000); - ookbursttiming::SampleOOKTiming Message[50 * 6 * 2]; + ookbursttiming::SampleOOKTiming Message[50 * 6 * 2]; ookbursttiming::SampleOOKTiming pulse; pulse.value = 1; @@ -554,28 +553,29 @@ void RfSwitchOOK(uint64_t Freq) preamble.value = 0; preamble.duration = 2600; - unsigned int ID=32288767; + unsigned int ID = 32288767; + + ID = ID << 6; - ID=ID<<6; - unsigned char MessageTx[4]; - - int group=1; - int Channel=3; - int unit=2; - int power=1; + + int group = 1; + int Channel = 3; + int unit = 2; + int power = 1; ookbursttiming::SampleOOKTiming MessageOOK[200]; - + for (int times = 0; times < 20; times++) { - power=times%2; - for(int i=0;i<4;i++) MessageTx[i]=ID>>(8*(3-i)); - MessageTx[3]|=(group&0x1)<<5; - MessageTx[3]|=(~power&0x1)<<4; - MessageTx[3]|=(Channel&0x3)<<2; - MessageTx[3]|=(unit&0x3); - + power = times % 2; + for (int i = 0; i < 4; i++) + MessageTx[i] = ID >> (8 * (3 - i)); + MessageTx[3] |= (group & 0x1) << 5; + MessageTx[3] |= (~power & 0x1) << 4; + MessageTx[3] |= (Channel & 0x3) << 2; + MessageTx[3] |= (unit & 0x3); + for (int i = 0; i < 2; i++) { int n = 0; @@ -583,7 +583,7 @@ void RfSwitchOOK(uint64_t Freq) MessageOOK[n++] = preamble; for (int j = 0; j < 4; j++) { - + for (int k = 0; k < 8; k++) { if (((MessageTx[j] >> (7 - k)) & 1) == 0) @@ -592,7 +592,6 @@ void RfSwitchOOK(uint64_t Freq) MessageOOK[n++] = Zero; MessageOOK[n++] = pulse; MessageOOK[n++] = One; - } else { @@ -600,13 +599,10 @@ void RfSwitchOOK(uint64_t Freq) MessageOOK[n++] = One; MessageOOK[n++] = pulse; MessageOOK[n++] = Zero; - } - } - } - + MessageOOK[n++] = pulse; MessageOOK[n++] = Sync; @@ -614,11 +610,8 @@ void RfSwitchOOK(uint64_t Freq) } usleep(100000); } - } - - void SimpleTestBurstFsk(uint64_t Freq) { @@ -642,48 +635,39 @@ void SimpleTestAtv(uint64_t Freq) { int SR = 1000000; - int FifoSize = 625*52; - float samples[FifoSize]; - //Frame 0 - for(int j=0;j<312;j++) - { - if(j<160) - { - for(int i=0;i<52;i++) samples[i+j*52]=i/52.0; - - } - else - { - for(int i=0;i<52;i++) samples[i+j*52]=0; - - } - - } - //Frame 1 - for(int j=0;j<312;j++) - { - if(j<160) - { - for(int i=0;i<52;i++) samples[i+(j+312)*52]=i/52.0; - - } - else - { - for(int i=0;i<52;i++) samples[i+(j+312)*52]=0; - - } - - } + int FifoSize = 625 * 52; + unsigned char samples[FifoSize]; + + atv atvtest(Freq, SR, 14, 625); - int Available = atvtest.GetBufferAvailable(); - int Index = atvtest.GetUserMemIndex(); - fprintf(stderr,"Available %d Index %d\n",Available,Index); - atvtest.SetTvSamples(samples,FifoSize); - while(running) + //Frame 0 + for (int j = 0; j < 312; j++) + { + if (j < 160) + { + + for (int i = 0; i < 52; i++) + { + + samples[i + j * 52] = 255*(1-i/52.0);//Frame 0 + samples[i + j*52+312*52] =255*(1-i/52.0); //Frame 1 + } + } + else + { + for (int i = 0; i < 52; i++) + { + samples[i + j * 52] = 255*(1-i/52.0); + samples[i + j*52+312*52] =255*(1-i/52.0); + } + } + } + //atvtest.SetFrame(samples,625); + atvtest.start(); + while (running) { - //atvtest.SetTvSamples(samples,FifoSize); - usleep(40000); - + //atvtest.SetTvSamples(samples,FifoSize/4); + usleep(400000); } } diff --git a/src/atv.cpp b/src/atv.cpp index 3a52a48..e125389 100644 --- a/src/atv.cpp +++ b/src/atv.cpp @@ -24,7 +24,10 @@ This program is free software: you can redistribute it and/or modify #include #include -atv::atv(uint64_t TuneFrequency, uint32_t SR, int Channel, uint32_t Lines) : bufferdma(Channel, 20 + /*(fixme)*/ 2 + Lines * (6 + (52 * 2)), 2, 1) +//#define CB_ATV (6 * 4 + 5 * 4 + 5 * 4 + (304 + 305) * (4 + 52 * 2)) +#define CB_ATV 68000 + +atv::atv(uint64_t TuneFrequency, uint32_t SR, int Channel, uint32_t Lines) : dma(Channel, CB_ATV, Lines * 52 + 3) // Need 2 more bytes for 0 and 1 // Need 6 CB more for sync, if so as 2CBby sample : 3 { @@ -51,9 +54,9 @@ atv::atv(uint64_t TuneFrequency, uint32_t SR, int Channel, uint32_t Lines) : buf padgpio pad; Originfsel = pad.gpioreg[PADS_GPIO_0]; - sampletab[(buffersize * registerbysample - 2)] = (0x5A << 24) + (1 & 0x7) + (1 << 4) + (0 << 3); // Amp 1 - sampletab[(buffersize * registerbysample - 1)] = (0x5A << 24) + (0 & 0x7) + (1 << 4) + (0 << 3); // Amp 0 - sampletab[(buffersize * registerbysample - 3)] = (0x5A << 24) + (4 & 0x7) + (1 << 4) + (0 << 3); // Amp 1 + usermem[(usermemsize - 2)] = (0x5A << 24) + (1 & 0x7) + (1 << 4) + (0 << 3); // Amp 1 + usermem[(usermemsize - 1)] = (0x5A << 24) + (0 & 0x7) + (1 << 4) + (0 << 3); // Amp 0 + usermem[(usermemsize - 3)] = (0x5A << 24) + (4 & 0x7) + (1 << 4) + (0 << 3); // Amp 4 SetDmaAlgo(); } @@ -70,30 +73,30 @@ void atv::SetDmaAlgo() dma_cb_t *cbp = cbarray; int LineResolution = 625; - uint32_t level0= mem_virt_to_phys(&usermem[(buffersize * registerbysample - 1)]); - uint32_t level1= mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); - uint32_t level4= mem_virt_to_phys(&usermem[(buffersize * registerbysample - 3)]); - - int shortsync_0=2; - int shortsync_1=30; + uint32_t level0 = mem_virt_to_phys(&usermem[(usermemsize - 1)]); + uint32_t level1 = mem_virt_to_phys(&usermem[(usermemsize - 2)]); + uint32_t level4 = mem_virt_to_phys(&usermem[(usermemsize - 3)]); - int longsync_0=30; - int longsync_1=2; + int shortsync_0 = 2; + int shortsync_1 = 30; - int normalsync_0=4; - int normalsync_1=6; + int longsync_0 = 30; + int longsync_1 = 2; - int frontsync_1=2; + int normalsync_0 = 4; + int normalsync_1 = 6; + + int frontsync_1 = 2; for (int frame = 0; frame < 2; frame++) { - //Preegalisation - for (int i = 0; i < 6/*-frame*/; i++) + //Preegalisation //6*4CB + for (int i = 0; i < 6 /*-frame*/; i++) { //2us 0,30us 1 //@0 //SYNC preegalisation 2us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level0; //Amp 0 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -117,7 +120,7 @@ void atv::SetDmaAlgo() cbp++; //SYNC preegalisation 30us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level1; //Amp 1 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -140,10 +143,10 @@ void atv::SetDmaAlgo() cbp->next = mem_virt_to_phys(cbp + 1); cbp++; } - //SYNC top trame + //SYNC top trame 5*4CB for (int i = 0; i < 5; i++) { - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level0; //Amp 0 27us cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -166,7 +169,7 @@ void atv::SetDmaAlgo() cbp->next = mem_virt_to_phys(cbp + 1); cbp++; - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level1; //Amp 1 5us cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -190,12 +193,13 @@ void atv::SetDmaAlgo() cbp++; } //postegalisation ; copy paste from preegalisation - for (int i = 0; i < 5/*-i*/; i++) + //5*4CB + for (int i = 0; i < 5 /*-i*/; i++) { //2us 0,30us 1 //@0 //SYNC preegalisation 2us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level0; //Amp 0 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -219,7 +223,7 @@ void atv::SetDmaAlgo() cbp++; //SYNC preegalisation 30us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level1; //Amp 1 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -242,13 +246,13 @@ void atv::SetDmaAlgo() cbp->next = mem_virt_to_phys(cbp + 1); cbp++; } - - for (int line = 0; line < /*305*/304+frame; line++) + //(304+305)*(4+52*2)CB + for (int line = 0; line < /*305*/ 304 + frame; line++) { - + //@0 //SYNC 0/ 5us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level0; //Amp 0 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -273,7 +277,7 @@ void atv::SetDmaAlgo() //@0 //SYNC 1/ 5us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level1; //Amp 1 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -298,14 +302,14 @@ void atv::SetDmaAlgo() for (uint32_t samplecnt = 0; samplecnt < 52; samplecnt++) //52 us { - sampletab[samplecnt * registerbysample] = (0x5A << 24) + (3 & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD - //@0 + //sampletab[samplecnt * registerbysample] = (0x5A << 24) + (3 & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD + //@0 //DATA IN / 1us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; - if(line<20) cbp->src=level1; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + //if(line<20) cbp->src=level1; //if((line>=20)&&(line<40)) cbp->src=level4; - if(line>=20) - cbp->src = mem_virt_to_phys(&usermem[samplecnt * registerbysample+frame*312*registerbysample]); //Amp 1 + //if(line>=20) + cbp->src = mem_virt_to_phys(&usermem[samplecnt + line * 52 + frame * 312 * 52]); cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -328,10 +332,10 @@ void atv::SetDmaAlgo() cbp->next = mem_virt_to_phys(cbp + 1); cbp++; } - + //FRONT PORSH //SYNC 2us - cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; + cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->src = level1; //Amp 1 cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->length = 4; @@ -357,64 +361,22 @@ void atv::SetDmaAlgo() } 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); + fprintf(stderr,"Last cbp : %d \n",((unsigned int)(cbp)-(unsigned int)(cbarray))/sizeof(dma_cb_t)); } -void atv::SetTvSample(uint32_t Index, float Amplitude) //-1;1 +void atv::SetFrame(unsigned char *Luminance, size_t Lines) { - Index = Index % buffersize; - - int IntAmplitude = round(abs(Amplitude) * 6.0) + 1; //1 to 7 - - 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 - - PushSample(Index); // ?? -} - -void atv::SetTvSamples(float *sample, size_t Size) -{ - size_t NbWritten = 0; - int OSGranularity = 100; - - long int start_time; - long time_difference = 0; - struct timespec gettime_now; - - while (NbWritten < Size) + for (size_t i = 0; i < Lines; i++) { - clock_gettime(CLOCK_REALTIME, &gettime_now); - start_time = gettime_now.tv_nsec; - int Available = GetBufferAvailable(); - int TimeToSleep = 1e6 * ((int)buffersize * 3 / 4 - Available) / SampleRate - OSGranularity; // Sleep for theorically fill 3/4 of Fifo - if (TimeToSleep > 0) - { - //fprintf(stderr,"buffer size %d Available %d SampleRate %d Sleep %d\n",buffersize,Available,SampleRate,TimeToSleep); - usleep(TimeToSleep); - } - else - { - //fprintf(stderr,"No Sleep %d\n",TimeToSleep); - sched_yield(); - } - clock_gettime(CLOCK_REALTIME, &gettime_now); - time_difference = gettime_now.tv_nsec - start_time; - if (time_difference < 0) - time_difference += 1E9; - //fprintf(stderr,"Measure samplerate=%d\n",(int)((GetBufferAvailable()-Available)*1e9/time_difference)); - Available = GetBufferAvailable(); - int Index = GetUserMemIndex(); - int ToWrite = ((int)Size - (int)NbWritten) < Available ? Size - NbWritten : Available; - for (int i = 0; i < ToWrite; i++) + for (size_t x = 0; x < 52; x++) { - SetTvSample(Index + i, sample[NbWritten++]); + int AmplitudePAD = Luminance[i * 52 + x] * 6 + 1; //1 to 7 + + if (i % 2 == 0) // First field + usermem[i * 52 / 2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD + else //second field + usermem[i * 52 / 2 + Lines / 2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD } } } diff --git a/src/atv.h b/src/atv.h index 1fd3852..422650a 100644 --- a/src/atv.h +++ b/src/atv.h @@ -6,7 +6,7 @@ #include "dma.h" #include "gpio.h" -class atv:public bufferdma,public clkgpio,public pwmgpio,public pcmgpio +class atv:public dma,public clkgpio,public pwmgpio,public pcmgpio { protected: uint64_t tunefreq; @@ -17,9 +17,10 @@ class atv:public bufferdma,public clkgpio,public pwmgpio,public pcmgpio atv(uint64_t TuneFrequency,uint32_t SR,int Channel,uint32_t FifoSize); ~atv(); void SetDmaAlgo(); - - void SetTvSample(uint32_t Index,float Amplitude); - void SetTvSamples(float *sample,size_t Size); + + void SetFrame(unsigned char *Luminance,size_t Lines); + //void SetTvSample(uint32_t Index,float Amplitude); + //void SetTvSamples(float *sample,size_t Size); }; #endif