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)
{
/*
@ -554,27 +553,28 @@ 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++)
{
@ -592,7 +592,6 @@ void RfSwitchOOK(uint64_t Freq)
MessageOOK[n++] = Zero;
MessageOOK[n++] = pulse;
MessageOOK[n++] = One;
}
else
{
@ -600,11 +599,8 @@ void RfSwitchOOK(uint64_t Freq)
MessageOOK[n++] = One;
MessageOOK[n++] = pulse;
MessageOOK[n++] = Zero;
}
}
}
MessageOOK[n++] = pulse;
@ -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;
int FifoSize = 625 * 52;
unsigned char samples[FifoSize];
}
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);
int Available = atvtest.GetBufferAvailable();
int Index = atvtest.GetUserMemIndex();
fprintf(stderr,"Available %d Index %d\n",Available,Index);
atvtest.SetTvSamples(samples,FifoSize);
while(running)
{
//atvtest.SetTvSamples(samples,FifoSize);
usleep(40000);
//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/4);
usleep(400000);
}
}

View file

@ -24,7 +24,10 @@ This program is free software: you can redistribute it and/or modify
#include <sched.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 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)]);
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 shortsync_0=2;
int shortsync_1=30;
int shortsync_0 = 2;
int shortsync_1 = 30;
int longsync_0=30;
int longsync_1=2;
int longsync_0 = 30;
int longsync_1 = 2;
int normalsync_0=4;
int normalsync_1=6;
int normalsync_0 = 4;
int normalsync_1 = 6;
int frontsync_1=2;
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;
@ -331,7 +335,7 @@ void atv::SetDmaAlgo()
//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
}
}
}

View file

@ -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;
@ -18,8 +18,9 @@ class atv:public bufferdma,public clkgpio,public pwmgpio,public pcmgpio
~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