Lot of rework on circular buffers

pull/53/merge
F5OEO 2016-12-08 15:18:35 +00:00
rodzic 34f193f74b
commit 6c4cc12fc7
1 zmienionych plików z 151 dodań i 62 usunięć

Wyświetl plik

@ -52,6 +52,7 @@
#include <sys/prctl.h>
#include <sys/timex.h>
#include <sys/ioctl.h>
extern void dvbsenco_init (void) ;
extern uchar* dvbsenco (uchar*) ;
@ -63,7 +64,7 @@ extern uchar* interleave (uchar* packetin) ;
#define PROGRAM_VERSION "2.0.0"
//Minimum Time in us to sleep
#define KERNEL_GRANULARITY 20000
#define KERNEL_GRANULARITY 10000
#define SCHED_PRIORITY 30 //Linux scheduler priority. Higher = more realtime
@ -129,29 +130,32 @@ terminate(int dummy)
gpio_reg[0x28/4]=1<<21; // Set PTT OFF
if (dma_reg) {
if (dma_reg)
{
dma_reg[DMA_CS+DMA_CHANNEL*0x40] = BCM2708_DMA_INT | BCM2708_DMA_END;
udelay(100);
dma_reg[DMA_CS+DMA_CHANNEL*0x40] = BCM2708_DMA_RESET;
udelay(100);
//printf("Reset DMA Done\n");
clk_reg[GPCLK_CNTL] = 0x5A << 24 | 0 << 9 | 1 << 4 | 6; //NO MASH !!!
udelay(500);
printf("Reset DMA Done\n");
//clk_reg[GPCLK_CNTL] = 0x5A << 24 | 0 << 9 | 1 << 4 | 6; //NO MASH !!!
//udelay(500);
gpio_reg[GPFSEL0] = (gpio_reg[GPFSEL0] & ~(7 << 12)) | (0 << 12); //DISABLE CLOCK - In case used by digilite
clk_reg[PWMCLK_CNTL] = 0x5A000006 | (0 << 9) ;
//clk_reg[PWMCLK_CNTL] = 0x5A000006 | (0 << 9) ;
clk_reg[PWMCLK_CNTL] = 0x5A000000|PLL_PWM;
udelay(500);
clk_reg[PCMCLK_CNTL] = 0x5A000006;
clk_reg[PCMCLK_CNTL] = 0x5A000000|PLL_PWM;
udelay(500);
//printf("Resetpcm Done\n");
pwm_reg[PWM_DMAC] = 0;
udelay(100);
pwm_reg[PWM_CTL] = PWMCTL_CLRF;
udelay(100);
pwm_reg[PWM_FIFO]=0L;
//printf("Reset pwm Done\n");
}
if (mbox.virt_addr != NULL) {
unmapmem(mbox.virt_addr, NUM_PAGES * PAGE_SIZE);
//printf("Unmapmem Done\n");
printf("Unmapmem Done\n");
mem_unlock(mbox.handle, mbox.mem_ref);
//printf("Unmaplock Done\n");
mem_free(mbox.handle, mbox.mem_ref);
@ -399,14 +403,14 @@ int InitIQ(int DigithinMode)
//SymbolRate = PLLFREQ/(SRClockPCM*1000);
uint32_t DigiThin_ClockBySymbol=0;
// CLK_DIGITHIN 500MHZ(PLLD)/4MHZ = 125
int CLK_DIGITHIN=PLLFREQ_PCM/4E6;
//#define CLK_4MHZ 125
if(DigithinMode==1)
{
uint32_t DigiThin_ClockBySymbol;
// GPIO4 needs to be ALT FUNC 0 to otuput the clock
gpio_reg[GPFSEL0] = (gpio_reg[GPFSEL0] & ~(7 << 12)) | (4 << 12); //ENABLE CLOCK - In case used by digilite
@ -417,7 +421,7 @@ int InitIQ(int DigithinMode)
usleep(100);
DigiThin_ClockBySymbol=( PLLFREQ_PCM/(CLK_DIGITHIN));
//SRClock=DigiThin_ClockBySymbol*CLK_4MHZ;
printf("Digithin Clock at 4MHZ:%ld clock by Symbol (SR=%d)\n",(long int)DigiThin_ClockBySymbol,4000000/(SymbolRate*1000L));
printf("Digithin Clock at 4MHZ:%d clock by Symbol (SR=%ld)\n",DigiThin_ClockBySymbol,4000000/(SymbolRate*1000L));
udelay(500);
clk_reg[GPCLK_CNTL] = 0x5A << 24 | 0 << 9 | 1 << 4 | PLL_PCM; //NO MASH !!!
udelay(500);
@ -551,7 +555,7 @@ int InitIQ(int DigithinMode)
uint32_t phys_pwm_fifo_addr = 0x7e20c000 + 0x18;//PWM
int samplecnt;
NUM_SAMPLES = NUM_SAMPLES_MAX/4; // Minize the buffer in IQ Mode
NUM_SAMPLES = NUM_SAMPLES_MAX/2; // Minize the buffer in IQ Mode
for (samplecnt = 0; samplecnt < NUM_SAMPLES; samplecnt++) {
// Write a PWM sample
@ -697,8 +701,8 @@ int InitDTX1()
}
#define BIG_BUFFER_SIZE (18800*4)
#define BURST_MEM_SIZE 188
#define BIG_BUFFER_SIZE ((int)((NUM_SAMPLES*4*1.5)/188)*188)
#define BURST_MEM_SIZE (188)
typedef struct circular_buffer
{
unsigned char *buffer;
@ -734,13 +738,17 @@ void store_in_buffer(unsigned char data)
void store_in_buffer_1880(unsigned char *data)
{
//while(((unsigned int)(my_circular_buffer.head + 18800) % BIG_BUFFER_SIZE)==my_circular_buffer.tail)
// usleep(50000);
while(((unsigned int)(my_circular_buffer.head + BURST_MEM_SIZE) % BIG_BUFFER_SIZE)==my_circular_buffer.tail)
{
//printf("Bigbuffer plein\n");
usleep(50000);
}
pthread_mutex_lock(&my_circular_buffer.lock);
memcpy(my_circular_buffer.buffer+my_circular_buffer.head,data,BURST_MEM_SIZE);
unsigned int next = (unsigned long)(my_circular_buffer.head + BURST_MEM_SIZE) % BIG_BUFFER_SIZE;
my_circular_buffer.head = next;
pthread_mutex_unlock(&my_circular_buffer.lock);
}
@ -763,11 +771,11 @@ char read_from_buffer()
void read_from_buffer_188(unsigned char *Dest)
{
while(BufferAvailable()<188) usleep(0);
//pthread_mutex_lock(&my_circular_buffer.lock);
while(BufferAvailable()<188) {usleep(5000);printf("B");} // Carefull of deadlock ! BE sure to have available
pthread_mutex_lock(&my_circular_buffer.lock);
memcpy(Dest,my_circular_buffer.buffer+my_circular_buffer.tail,188);
my_circular_buffer.tail = (unsigned int)(my_circular_buffer.tail + 188) % BIG_BUFFER_SIZE;
//pthread_mutex_unlock(&my_circular_buffer.lock);
pthread_mutex_unlock(&my_circular_buffer.lock);
}
void *FillBigBuffer (void * arg)
@ -784,14 +792,29 @@ void *FillBigBuffer (void * arg)
prctl(PR_SET_NAME, name, 0, 0, 0);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
struct stat bufstat;
int ret;
ret=fstat(fdts,&bufstat);
if(S_ISFIFO(bufstat.st_mode))
printf("Using a Pipe\n");
else
printf("Using a File %d %d\n",ret,bufstat.st_mode);
while(EndOfApp==0)
{
TotalByteRead=0;
//usleep(200);
do
{
int n;
if(S_ISFIFO(bufstat.st_mode))
{
do
{
ioctl(fdts, FIONREAD, &n);
if(n<(BURST_MEM_SIZE)) {usleep(10000);}
}
while(n<(BURST_MEM_SIZE));
}
ByteRead=read(fdts,buff188+TotalByteRead,BURST_MEM_SIZE-TotalByteRead);
if(ByteRead<=0)
@ -813,6 +836,11 @@ void *FillBigBuffer (void * arg)
}
else
{
if(ByteRead!=(BURST_MEM_SIZE-TotalByteRead))
{
//usleep(25000);
}
TotalByteRead+=ByteRead;
//usleep(2000);
@ -821,17 +849,25 @@ void *FillBigBuffer (void * arg)
}
while (TotalByteRead<BURST_MEM_SIZE); // Read should be around 20us
while(((BIG_BUFFER_SIZE-BufferAvailable())<=BURST_MEM_SIZE))
{
usleep(1000);
if(((BIG_BUFFER_SIZE-BufferAvailable())<=BIG_BUFFER_SIZE/8))
{
unsigned char Dummy[188];
if(S_ISFIFO(bufstat.st_mode))
{
printf("PIdatv ov=%d/%d\n",BufferAvailable(),BIG_BUFFER_SIZE);
while(BufferAvailable()>BIG_BUFFER_SIZE/8)
read_from_buffer_188(Dummy);
}
//usleep(1000);
}
//printf("Lock BigBuffer\n");
pthread_mutex_lock(&my_circular_buffer.lock);
store_in_buffer_1880(buff188);
//printf("#");
/*
for(NbWrite=0;NbWrite<1880;NbWrite++)
@ -839,7 +875,8 @@ void *FillBigBuffer (void * arg)
store_in_buffer(buff188[NbWrite]);
}
*/
pthread_mutex_unlock(&my_circular_buffer.lock);
// printf("UNLock BigBuffer\n");
}
@ -952,7 +989,7 @@ main(int argc, char **argv)
if(strcmp("3/4",optarg)==0) FEC=3;
if(strcmp("5/6",optarg)==0) FEC=5;
if(strcmp("7/8",optarg)==0) FEC=7;
if(strcmp("carrier",optarg)==0) FEC=0;//CARRIER MODE
if(strcmp("carrier",optarg)==0) {printf("Rpidatv:Carrier mode\n");FEC=0;}//CARRIER MODE
if(strcmp("test",optarg)==0) FEC=-1;//TEST MODE
break;
case 'h': // help
@ -1017,7 +1054,7 @@ main(int argc, char **argv)
//data=malloc(DATA_FILE_SIZE);
CalibrateSystem();
//CalibrateSystem();
dvbsenco_init() ;
@ -1059,7 +1096,7 @@ main(int argc, char **argv)
dma_reg[DMA_CS+DMA_CHANNEL*0x40] = BCM2708_DMA_RESET;
udelay(1000);
dma_reg[DMA_CS+DMA_CHANNEL*0x40] = BCM2708_DMA_INT | BCM2708_DMA_END;
udelay(100);
udelay(1000);
@ -1140,10 +1177,14 @@ else
#endif
//uchar PacketNULL[188];
//PacketNULL[0]=0x47;
//PacketNULL[1]=0x00;
//for(i=2;i<188;i++) PacketNULL[i]=0xFF;
uchar PacketNULL[BURST_MEM_SIZE];
int k;
for(k=0;k<BURST_MEM_SIZE/188;k++)
{
PacketNULL[0+k*188]=0x47;
PacketNULL[1+k*188]=0x00;
for(i=2;i<188;i++) PacketNULL[i+k*188]=0xFF;
}
if(ModeIQ==0) //UGLY
@ -1202,11 +1243,11 @@ if(ModeIQ==2)
pthread_attr_destroy (&attr);
while(BufferAvailable()<(TSRate/10)&&(BufferAvailable()<(BIG_BUFFER_SIZE*8/10))) // 1/10 SECOND BUFFERING DEPEND ON SYMBOLRATE OR 80% BUFFERSIZE
while(BufferAvailable()<(BIG_BUFFER_SIZE*5/10)) // 1/10 SECOND BUFFERING DEPEND ON SYMBOLRATE OR 80% BUFFERSIZE
{
//printf("Init Filling Memory buffer %d\n",BufferAvailable());
//printf(".");
usleep(500);
usleep(10000);
}
/*
int NbByteInitRead=0;
@ -1352,7 +1393,7 @@ for (;;)
if(Loop==1)
{
close(fdts);
fdts = open(argv[1], 'r');
fdts = open(FileName, 'r');
}
else
{
@ -1476,7 +1517,7 @@ for (;;)
//********************************* MODE IQ **************************************
if(ModeIQ==1)
{
static int StatusCompteur=0;
cur_cb = mem_phys_to_virt(dma_reg[DMA_CONBLK_AD+DMA_CHANNEL*0x40]);
this_sample = (cur_cb - (uint32_t)virtbase) / (sizeof(dma_cb_t) );
last_sample = (last_cb - (uint32_t)virtbase) / (sizeof(dma_cb_t) );
@ -1489,16 +1530,23 @@ for (;;)
//printf("FreeSlots = %d Time to sleep=%d\n",free_slots,TimeToSleep);
clock_gettime(CLOCK_REALTIME, &gettime_now);
start_time = gettime_now.tv_nsec;
if(TimeToSleep>=(2000+KERNEL_GRANULARITY)){
if(TimeToSleep>=150000) TimeToSleep=150000; //Digithin should be every 250ms
udelay(TimeToSleep-(2000+KERNEL_GRANULARITY));
}
else
{
//usleep(0);//20 ms mini !!
if(free_slots>(NUM_SAMPLES*9/10))
printf("Buffer nearly empty...%d/%d\n",free_slots,NUM_SAMPLES);
start_time = gettime_now.tv_nsec;
if(Init==0)
{
if(TimeToSleep>=(2000+KERNEL_GRANULARITY)){
if(TimeToSleep>=20000) TimeToSleep=20000; //Digithin should be every 250ms
udelay(TimeToSleep-(2000+KERNEL_GRANULARITY));
}
else
{
printf("!");
usleep(1000);//20 ms mini !!
if(free_slots>(NUM_SAMPLES*9/10))
{
//printf("Buffer nearly empty...%d/%d\n",free_slots,NUM_SAMPLES);
//printf("$");
}
}
}
//printf("FreeSlots = %d Time to sleep=%d\n",free_slots,TimeToSleep);
@ -1543,12 +1591,21 @@ for (;;)
clock_gettime(CLOCK_REALTIME, &gettime_now);
time_difference = gettime_now.tv_nsec - start_time;
if(time_difference<0) time_difference+=1E9;
if(StatusCompteur%100==0)
{
//SetUglyFrequency(TuneFrequency);
//TuneFrequency+=5000.0;
printf("Memavailable %d/%d FreeSlot=%d/%d Bitrate : %f\n",BufferAvailable(),BIG_BUFFER_SIZE,free_slots_now,NUM_SAMPLES,(1000000.0*(free_slots_now-free_slots))/(float)time_difference);
}
StatusCompteur++;
//printf("DiffTime = %ld FreeSlot=%ld Bitrate : %f\n",time_difference,free_slots_now-free_slots,(1000000.0*(free_slots_now-free_slots)*16.0)/(float)time_difference);
free_slots=free_slots_now;
if((Init==1)&&(free_slots <= (204*8*2)/*NUM_SAMPLES/8*/))
if((Init==1)&&(free_slots <= (204*8*2)))
{
printf("%ld:%ld : End of Fulling buffer \n",gettime_now.tv_sec,gettime_now.tv_nsec);
dma_reg[DMA_CS+DMA_CHANNEL*0x40] = 0x10880001; // go, mid priority, wait for outstanding writes :7 Seems Max Priority
@ -1567,7 +1624,32 @@ for (;;)
clock_gettime(CLOCK_REALTIME, &gettime_now);
start_time = gettime_now.tv_nsec;
while ((free_slots > (204*8*2))&&(BufferAvailable()>188*8)) //204Bytes*2(IQ)/32
#ifdef WITH_MEMORY_BUFFER
if((Init==0)&&(free_slots > (NUM_SAMPLES*9/10))&&(BufferAvailable()<=188*8))
{
int k;
store_in_buffer_1880(PacketNULL);
/*while(BufferAvailable()<188*8)
{
//printf("!");
sleep(1000);
}
*/
/*
pthread_mutex_lock(&my_circular_buffer.lock);
for(k=0;k<8*2;k++)
store_in_buffer_1880(PacketNULL);
pthread_mutex_unlock(&my_circular_buffer.lock);
*/
printf("Underflow\n");
}
#endif
#ifdef WITH_MEMORY_BUFFER
while ((free_slots > (204*8*2))&&((BufferAvailable()>=188*8)||(FEC==0))) //204Bytes*2(IQ)/32
#else
while ((free_slots > (204*8*2))||(FEC==0)) //204Bytes*2(IQ)/32
#endif
{
//static uint32_t BuffAligned[256];
@ -1595,31 +1677,36 @@ for (;;)
if(FEC>0)
{
/*
static int ByteRead=0;
#ifndef WITH_MEMORY_BUFFER
/*static*/ int ByteRead=0;
if ((ByteRead=read(fdts,buff,188))!=188) // Read should be around 20us
{
printf("END OF FILE OR packet is not 188 long %d\n",data_len);
printf("END OF FILE OR packet is not 188 long %d\n",ByteRead);
if(Loop==1)
{
close(fdts);
fdts = open(argv[1], 'r');
fdts = open(FileName, 'r');
ByteRead=read(fdts,buff,188);
}
else
{
while(ByteRead!=188)
{
ByteRead+=read(fdts,buff+ByteRead,188-ByteRead);
//printf("End of processing file\n");
usleep(1000);
}
printf("ok 188\n");
//terminate(0);
}
}
*/
#else
int ii;
pthread_mutex_lock(&my_circular_buffer.lock);
for(ii=0;ii<188;ii++) buff[ii]=read_from_buffer();
pthread_mutex_unlock(&my_circular_buffer.lock);
read_from_buffer_188(buff);
#endif
}
else
{
@ -1650,6 +1737,7 @@ for (;;)
}
else
{
//printf("408\n");
NbIQOutput=408;
}
@ -1686,10 +1774,11 @@ for (;;)
if(FEC==0) //CARRIER MODE : OVERWRITE IQ previously calculated
{
//I32=TabIQTestI[NbSymbol%4];
//Q32=TabIQTestQ[NbSymbol%4];
I32=0xFFFFFFFF;
Q32=0;
I32=0x55555555;
Q32=0x55555555;
}
/*
if(FEC<0)