diff --git a/app/testrpitx.cpp b/app/testrpitx.cpp
index 3366c25..15242c6 100644
--- a/app/testrpitx.cpp
+++ b/app/testrpitx.cpp
@@ -637,6 +637,26 @@ void SimpleTestBurstFsk(uint64_t Freq)
}
fsktest.stop();
}
+
+void SimpleTestAtv(uint64_t Freq)
+{
+
+ int SR = 1000000;
+ int FifoSize = 625*52;
+ float samples[FifoSize];
+ for(int j=0;j<625;j++)
+ {
+ for(int i=0;i<52;i++) samples[i+j*52]=i/52.0;
+ }
+ atv atvtest(Freq, SR, 14, 625);
+ atvtest.SetTvSamples(samples,FifoSize);
+ while(running)
+ {
+ usleep(100000);
+
+ }
+}
+
static void
terminate(int num)
{
@@ -669,5 +689,6 @@ int main(int argc, char *argv[])
//SimpleTestBurstFsk(Freq);
//SimpleTestOOKTiming(Freq);
//AlectoOOK(Freq);
- RfSwitchOOK(Freq);
+ //RfSwitchOOK(Freq);
+ SimpleTestAtv(Freq);
}
diff --git a/src/Makefile b/src/Makefile
index c6113bf..e894812 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,11 +4,11 @@ LDFLAGS = -lm -lrt -lpthread
CCP = c++
CC = cc
-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 fskburst.h fskburst.cpp ookburst.cpp ookburst.h
+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 fskburst.h fskburst.cpp ookburst.cpp ookburst.h atv.h atv.cpp
$(CC) $(CFLAGS) -c -o mailbox.o mailbox.c
$(CC) $(CFLAGS) -c -o raspberry_pi_revision.o raspberry_pi_revision.c
- $(CCP) $(CXXFLAGS) -c dsp.cpp iqdmasync.cpp ngfmdmasync.cpp fmdmasync.cpp dma.cpp gpio.cpp serialdmasync.cpp phasedmasync.cpp amdmasync.h amdmasync.cpp fskburst.cpp ookburst.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 fskburst.o ookburst.o
+ $(CCP) $(CXXFLAGS) -c dsp.cpp iqdmasync.cpp ngfmdmasync.cpp fmdmasync.cpp dma.cpp gpio.cpp serialdmasync.cpp phasedmasync.cpp amdmasync.h amdmasync.cpp fskburst.cpp ookburst.cpp atv.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 fskburst.o ookburst.o atv.o
install: librpitx
diff --git a/src/atv.cpp b/src/atv.cpp
new file mode 100644
index 0000000..73b3f46
--- /dev/null
+++ b/src/atv.cpp
@@ -0,0 +1,399 @@
+/*
+Copyright (C) 2018 Evariste COURJAUD F5OEO
+
+This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "stdio.h"
+#include "atv.h"
+#include "gpio.h"
+#include
+#include
+#include
+#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)
+// Need 2 more bytes for 0 and 1
+// Need 6 CB more for sync, if so as 2CBby sample : 3
+{
+
+ SampleRate = SR;
+ tunefreq = TuneFrequency;
+ clkgpio::SetAdvancedPllMode(true);
+ clkgpio::SetCenterFrequency(TuneFrequency, SampleRate);
+ clkgpio::SetFrequency(0);
+ clkgpio::enableclk(4); // GPIO 4 CLK by default
+ syncwithpwm = true;
+
+ 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];
+
+ 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
+
+ SetDmaAlgo();
+}
+
+atv::~atv()
+{
+ clkgpio::disableclk(4);
+ padgpio pad;
+ pad.gpioreg[PADS_GPIO_0] = Originfsel;
+}
+
+void atv::SetDmaAlgo()
+{
+ dma_cb_t *cbp = cbarray;
+ int LineResolution = 625;
+
+ for (int frame = 0; frame < 2; frame++)
+ {
+ //32us*5 or 6
+ for (int i = 0; i < 5+frame; i++)
+ {
+ //2us 0,30us 1
+ //@0
+ //SYNC preegalisation 2us
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 1)]); //Amp 0
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 2; //2us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+
+ //SYNC preegalisation 30us
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); //Amp 1
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 30; //30us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+ }
+ //SYNC top trame
+ for (int i = 0; i < 5; i++)
+ {
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 1)]); //Amp 0 27us
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 27; //27us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); //Amp 1 5us
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 5; //5us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+ }
+ //postegalisation ; copy paste from preegalisation
+ for (int i = 0; i < 5; i++)
+ {
+ //2us 0,30us 1
+ //@0
+ //SYNC preegalisation 2us
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 1)]); //Amp 0
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 2; //2us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+
+ //SYNC preegalisation 30us
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); //Amp 1
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 30; //30us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+ }
+
+ for (int line = 0; line < 305; line++)
+ {
+
+ //@0
+ //SYNC 0/ 5us
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 1)]); //Amp 0
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 4; //5us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+
+ //@0
+ //SYNC 1/ 5us
+ cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
+ cbp->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); //Amp 1
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 6; //5us;
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ cbp++;
+
+ for (uint32_t samplecnt = 0; samplecnt < 52; samplecnt++) //52 us
+ {
+ 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 ;
+ cbp->src = mem_virt_to_phys(&usermem[samplecnt * registerbysample]); //Amp 1
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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; //1us
+ cbp->stride = 0;
+ 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->src = mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); //Amp 1
+ cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
+ 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 * 2; //2us
+ cbp->stride = 0;
+ cbp->next = mem_virt_to_phys(cbp + 1);
+ 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 atv::SetTvSample(uint32_t Index, float Amplitude) //-1;1
+{
+ 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)
+ {
+ 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++)
+ {
+ SetTvSample(Index + i, sample[NbWritten++]);
+ }
+ }
+}
diff --git a/src/atv.h b/src/atv.h
new file mode 100644
index 0000000..1fd3852
--- /dev/null
+++ b/src/atv.h
@@ -0,0 +1,25 @@
+#ifndef DEF_ATV
+#define DEF_ATV
+
+#include "stdint.h"
+#include "stdio.h"
+#include "dma.h"
+#include "gpio.h"
+
+class atv:public bufferdma,public clkgpio,public pwmgpio,public pcmgpio
+{
+ protected:
+ uint64_t tunefreq;
+ bool syncwithpwm;
+ uint32_t Originfsel;
+ uint32_t SampleRate;
+ public:
+ 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);
+};
+
+#endif
diff --git a/src/librpitx.h b/src/librpitx.h
index 5aaebb3..6d6554c 100644
--- a/src/librpitx.h
+++ b/src/librpitx.h
@@ -25,4 +25,5 @@ This program is free software: you can redistribute it and/or modify
#include "amdmasync.h"
#include "fskburst.h"
#include "dsp.h"
-#include "ookburst.h"
\ No newline at end of file
+#include "ookburst.h"
+#include "atv.h"
\ No newline at end of file