Rework DMA for ATV

This commit is contained in:
F5OEO 2019-01-01 21:45:37 +00:00
parent 5419622f6b
commit b356479493
3 changed files with 108 additions and 161 deletions

View file

@ -511,7 +511,6 @@ void AlectoOOK(uint64_t Freq)
} }
} }
void RfSwitchOOK(uint64_t Freq) void RfSwitchOOK(uint64_t Freq)
{ {
/* /*
@ -532,7 +531,7 @@ void RfSwitchOOK(uint64_t Freq)
* Every message is repeated four times. * Every message is repeated four times.
* */ * */
ookbursttiming ooksender(Freq, 1200000); ookbursttiming ooksender(Freq, 1200000);
ookbursttiming::SampleOOKTiming Message[50 * 6 * 2]; ookbursttiming::SampleOOKTiming Message[50 * 6 * 2];
ookbursttiming::SampleOOKTiming pulse; ookbursttiming::SampleOOKTiming pulse;
pulse.value = 1; pulse.value = 1;
@ -554,28 +553,29 @@ void RfSwitchOOK(uint64_t Freq)
preamble.value = 0; preamble.value = 0;
preamble.duration = 2600; preamble.duration = 2600;
unsigned int ID=32288767; unsigned int ID = 32288767;
ID = ID << 6;
ID=ID<<6;
unsigned char MessageTx[4]; unsigned char MessageTx[4];
int group=1; int group = 1;
int Channel=3; int Channel = 3;
int unit=2; int unit = 2;
int power=1; int power = 1;
ookbursttiming::SampleOOKTiming MessageOOK[200]; ookbursttiming::SampleOOKTiming MessageOOK[200];
for (int times = 0; times < 20; times++) for (int times = 0; times < 20; times++)
{ {
power=times%2; power = times % 2;
for(int i=0;i<4;i++) MessageTx[i]=ID>>(8*(3-i)); for (int i = 0; i < 4; i++)
MessageTx[3]|=(group&0x1)<<5; MessageTx[i] = ID >> (8 * (3 - i));
MessageTx[3]|=(~power&0x1)<<4; MessageTx[3] |= (group & 0x1) << 5;
MessageTx[3]|=(Channel&0x3)<<2; MessageTx[3] |= (~power & 0x1) << 4;
MessageTx[3]|=(unit&0x3); MessageTx[3] |= (Channel & 0x3) << 2;
MessageTx[3] |= (unit & 0x3);
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
int n = 0; int n = 0;
@ -583,7 +583,7 @@ void RfSwitchOOK(uint64_t Freq)
MessageOOK[n++] = preamble; MessageOOK[n++] = preamble;
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
{ {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
{ {
if (((MessageTx[j] >> (7 - k)) & 1) == 0) if (((MessageTx[j] >> (7 - k)) & 1) == 0)
@ -592,7 +592,6 @@ void RfSwitchOOK(uint64_t Freq)
MessageOOK[n++] = Zero; MessageOOK[n++] = Zero;
MessageOOK[n++] = pulse; MessageOOK[n++] = pulse;
MessageOOK[n++] = One; MessageOOK[n++] = One;
} }
else else
{ {
@ -600,13 +599,10 @@ void RfSwitchOOK(uint64_t Freq)
MessageOOK[n++] = One; MessageOOK[n++] = One;
MessageOOK[n++] = pulse; MessageOOK[n++] = pulse;
MessageOOK[n++] = Zero; MessageOOK[n++] = Zero;
} }
} }
} }
MessageOOK[n++] = pulse; MessageOOK[n++] = pulse;
MessageOOK[n++] = Sync; MessageOOK[n++] = Sync;
@ -614,11 +610,8 @@ void RfSwitchOOK(uint64_t Freq)
} }
usleep(100000); usleep(100000);
} }
} }
void SimpleTestBurstFsk(uint64_t Freq) void SimpleTestBurstFsk(uint64_t Freq)
{ {
@ -642,48 +635,39 @@ void SimpleTestAtv(uint64_t Freq)
{ {
int SR = 1000000; int SR = 1000000;
int FifoSize = 625*52; int FifoSize = 625 * 52;
float samples[FifoSize]; unsigned char 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;
}
}
atv atvtest(Freq, SR, 14, 625); atv atvtest(Freq, SR, 14, 625);
int Available = atvtest.GetBufferAvailable(); //Frame 0
int Index = atvtest.GetUserMemIndex(); for (int j = 0; j < 312; j++)
fprintf(stderr,"Available %d Index %d\n",Available,Index); {
atvtest.SetTvSamples(samples,FifoSize); if (j < 160)
while(running) {
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); //atvtest.SetTvSamples(samples,FifoSize/4);
usleep(40000); usleep(400000);
} }
} }

View file

@ -24,7 +24,10 @@ This program is free software: you can redistribute it and/or modify
#include <sched.h> #include <sched.h>
#include <stdlib.h> #include <stdlib.h>
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 2 more bytes for 0 and 1
// Need 6 CB more for sync, if so as 2CBby sample : 3 // 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; padgpio pad;
Originfsel = pad.gpioreg[PADS_GPIO_0]; Originfsel = pad.gpioreg[PADS_GPIO_0];
sampletab[(buffersize * registerbysample - 2)] = (0x5A << 24) + (1 & 0x7) + (1 << 4) + (0 << 3); // Amp 1 usermem[(usermemsize - 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 usermem[(usermemsize - 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 - 3)] = (0x5A << 24) + (4 & 0x7) + (1 << 4) + (0 << 3); // Amp 4
SetDmaAlgo(); SetDmaAlgo();
} }
@ -70,30 +73,30 @@ void atv::SetDmaAlgo()
dma_cb_t *cbp = cbarray; dma_cb_t *cbp = cbarray;
int LineResolution = 625; int LineResolution = 625;
uint32_t level0= mem_virt_to_phys(&usermem[(buffersize * registerbysample - 1)]); uint32_t level0 = mem_virt_to_phys(&usermem[(usermemsize - 1)]);
uint32_t level1= mem_virt_to_phys(&usermem[(buffersize * registerbysample - 2)]); uint32_t level1 = mem_virt_to_phys(&usermem[(usermemsize - 2)]);
uint32_t level4= mem_virt_to_phys(&usermem[(buffersize * registerbysample - 3)]); uint32_t level4 = mem_virt_to_phys(&usermem[(usermemsize - 3)]);
int shortsync_0=2;
int shortsync_1=30;
int longsync_0=30; int shortsync_0 = 2;
int longsync_1=2; int shortsync_1 = 30;
int normalsync_0=4; int longsync_0 = 30;
int normalsync_1=6; 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++) for (int frame = 0; frame < 2; frame++)
{ {
//Preegalisation //Preegalisation //6*4CB
for (int i = 0; i < 6/*-frame*/; i++) for (int i = 0; i < 6 /*-frame*/; i++)
{ {
//2us 0,30us 1 //2us 0,30us 1
//@0 //@0
//SYNC preegalisation 2us //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->src = level0; //Amp 0
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -117,7 +120,7 @@ void atv::SetDmaAlgo()
cbp++; cbp++;
//SYNC preegalisation 30us //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->src = level1; //Amp 1
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -140,10 +143,10 @@ void atv::SetDmaAlgo()
cbp->next = mem_virt_to_phys(cbp + 1); cbp->next = mem_virt_to_phys(cbp + 1);
cbp++; cbp++;
} }
//SYNC top trame //SYNC top trame 5*4CB
for (int i = 0; i < 5; i++) 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->src = level0; //Amp 0 27us
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -166,7 +169,7 @@ void atv::SetDmaAlgo()
cbp->next = mem_virt_to_phys(cbp + 1); cbp->next = mem_virt_to_phys(cbp + 1);
cbp++; 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->src = level1; //Amp 1 5us
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -190,12 +193,13 @@ void atv::SetDmaAlgo()
cbp++; cbp++;
} }
//postegalisation ; copy paste from preegalisation //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 //2us 0,30us 1
//@0 //@0
//SYNC preegalisation 2us //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->src = level0; //Amp 0
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -219,7 +223,7 @@ void atv::SetDmaAlgo()
cbp++; cbp++;
//SYNC preegalisation 30us //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->src = level1; //Amp 1
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -242,13 +246,13 @@ void atv::SetDmaAlgo()
cbp->next = mem_virt_to_phys(cbp + 1); cbp->next = mem_virt_to_phys(cbp + 1);
cbp++; cbp++;
} }
//(304+305)*(4+52*2)CB
for (int line = 0; line < /*305*/304+frame; line++) for (int line = 0; line < /*305*/ 304 + frame; line++)
{ {
//@0 //@0
//SYNC 0/ 5us //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->src = level0; //Amp 0
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -273,7 +277,7 @@ void atv::SetDmaAlgo()
//@0 //@0
//SYNC 1/ 5us //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->src = level1; //Amp 1
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -298,14 +302,14 @@ void atv::SetDmaAlgo()
for (uint32_t samplecnt = 0; samplecnt < 52; samplecnt++) //52 us for (uint32_t samplecnt = 0; samplecnt < 52; samplecnt++) //52 us
{ {
sampletab[samplecnt * registerbysample] = (0x5A << 24) + (3 & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD //sampletab[samplecnt * registerbysample] = (0x5A << 24) + (3 & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
//@0 //@0
//DATA IN / 1us //DATA IN / 1us
cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ; cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
if(line<20) cbp->src=level1; //if(line<20) cbp->src=level1;
//if((line>=20)&&(line<40)) cbp->src=level4; //if((line>=20)&&(line<40)) cbp->src=level4;
if(line>=20) //if(line>=20)
cbp->src = mem_virt_to_phys(&usermem[samplecnt * registerbysample+frame*312*registerbysample]); //Amp 1 cbp->src = mem_virt_to_phys(&usermem[samplecnt + line * 52 + frame * 312 * 52]);
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -328,10 +332,10 @@ void atv::SetDmaAlgo()
cbp->next = mem_virt_to_phys(cbp + 1); cbp->next = mem_virt_to_phys(cbp + 1);
cbp++; cbp++;
} }
//FRONT PORSH //FRONT PORSH
//SYNC 2us //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->src = level1; //Amp 1
cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO; cbp->dst = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO;
cbp->length = 4; cbp->length = 4;
@ -357,64 +361,22 @@ void atv::SetDmaAlgo()
} }
cbp--; cbp--;
cbp->next = mem_virt_to_phys(cbarray); // We loop to the first CB 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; for (size_t i = 0; i < Lines; i++)
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++) 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
} }
} }
} }

View file

@ -6,7 +6,7 @@
#include "dma.h" #include "dma.h"
#include "gpio.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: protected:
uint64_t tunefreq; 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(uint64_t TuneFrequency,uint32_t SR,int Channel,uint32_t FifoSize);
~atv(); ~atv();
void SetDmaAlgo(); void SetDmaAlgo();
void SetTvSample(uint32_t Index,float Amplitude); void SetFrame(unsigned char *Luminance,size_t Lines);
void SetTvSamples(float *sample,size_t Size); //void SetTvSample(uint32_t Index,float Amplitude);
//void SetTvSamples(float *sample,size_t Size);
}; };
#endif #endif