simplify dma writting
This commit is contained in:
parent
d23e1fd8fc
commit
326d51cbbc
12 changed files with 469 additions and 740 deletions
|
@ -4,7 +4,7 @@ LDFLAGS = -lm -lrt -lpthread
|
||||||
CCP = c++
|
CCP = c++
|
||||||
CC = cc
|
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 atv.h atv.cpp
|
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 util.h
|
||||||
$(CC) $(CFLAGS) -c -o mailbox.o mailbox.c
|
$(CC) $(CFLAGS) -c -o mailbox.o mailbox.c
|
||||||
$(CC) $(CFLAGS) -c -o raspberry_pi_revision.o raspberry_pi_revision.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 atv.cpp
|
$(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
|
||||||
|
|
|
@ -72,39 +72,17 @@ void amdmasync::SetDmaAlgo()
|
||||||
|
|
||||||
//@0
|
//@0
|
||||||
//Set Amplitude by writing to PADS
|
//Set Amplitude by writing to PADS
|
||||||
cbp->info = 0;//BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp,samplecnt*registerbysample,dma_pad,1);
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
|
||||||
cbp->dst = 0x7E000000+(PADS_GPIO_0<<2)+PADS_GPIO;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
//@1
|
//@1
|
||||||
//Set Amplitude to FSEL for amplitude=0
|
//Set Amplitude to FSEL for amplitude=0
|
||||||
cbp->info = 0;//BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp,samplecnt*registerbysample+1,dma_fsel,1);
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample+1]);
|
|
||||||
cbp->dst = 0x7E000000 + (GPFSEL0<<2)+GENERAL_BASE;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
|
|
||||||
// Delay
|
// Delay
|
||||||
if(syncwithpwm)
|
SetEasyCB(cbp,samplecnt*registerbysample,syncwithpwm?dma_pwm:dma_pcm,1);
|
||||||
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;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
276
src/atv.cpp
276
src/atv.cpp
|
@ -77,6 +77,10 @@ void atv::SetDmaAlgo()
|
||||||
uint32_t level1 = mem_virt_to_phys(&usermem[(usermemsize - 2)]);
|
uint32_t level1 = mem_virt_to_phys(&usermem[(usermemsize - 2)]);
|
||||||
uint32_t level4 = mem_virt_to_phys(&usermem[(usermemsize - 3)]);
|
uint32_t level4 = mem_virt_to_phys(&usermem[(usermemsize - 3)]);
|
||||||
|
|
||||||
|
uint32_t index_level0 = usermemsize - 1;
|
||||||
|
uint32_t index_level1 = usermemsize - 2;
|
||||||
|
uint32_t index_level4 = usermemsize - 3;
|
||||||
|
|
||||||
int shortsync_0 = 2;
|
int shortsync_0 = 2;
|
||||||
int shortsync_1 = 30;
|
int shortsync_1 = 30;
|
||||||
|
|
||||||
|
@ -96,272 +100,65 @@ void atv::SetDmaAlgo()
|
||||||
//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 ;
|
SetEasyCB(cbp++, index_level0, dma_pad, 1);
|
||||||
cbp->src = level0; //Amp 0
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_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 * shortsync_0; //2us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
|
|
||||||
//SYNC preegalisation 30us
|
//SYNC preegalisation 30us
|
||||||
cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp++, index_level1, dma_pad, 1);
|
||||||
cbp->src = level1; //Amp 1
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_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 * shortsync_1; //30us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
}
|
}
|
||||||
//SYNC top trame 5*4*2frameCB
|
//SYNC top trame 5*4*2frameCB
|
||||||
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 ;
|
SetEasyCB(cbp++, index_level0, dma_pad, 1);
|
||||||
cbp->src = level0; //Amp 0 27us
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, longsync_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
|
SetEasyCB(cbp++, index_level1, dma_pad, 1);
|
||||||
if (syncwithpwm)
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, longsync_1);
|
||||||
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 * longsync_0; //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 = level1; //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 * longsync_1; //5us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
}
|
}
|
||||||
//postegalisation ; copy paste from preegalisation
|
//postegalisation ; copy paste from preegalisation
|
||||||
//5*4*2CB
|
//5*4*2CB
|
||||||
for (int i = 0; i < 5 /*-i*/; i++)
|
for (int i = 0; i < 5 + 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 ;
|
SetEasyCB(cbp++, index_level0, dma_pad, 1);
|
||||||
cbp->src = level0; //Amp 0
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_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 * shortsync_0; //2us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
|
|
||||||
//SYNC preegalisation 30us
|
//SYNC preegalisation 30us
|
||||||
cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp++, index_level1, dma_pad, 1);
|
||||||
cbp->src = level1; //Amp 1
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, shortsync_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 * shortsync_1; //30us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//(304+305)*(4+52*2+2)CB
|
//(304+305)*(4+52*2+2)CB
|
||||||
for (int line = 0; line < 305/* 317 + frame*/; line++)
|
for (int line = 0; line < 305 /* 317 + frame*/; line++)
|
||||||
{
|
{
|
||||||
|
|
||||||
//@0
|
//@0
|
||||||
//SYNC 0/ 5us
|
//SYNC 0/ 5us
|
||||||
cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp++, index_level0, dma_pad, 1);
|
||||||
cbp->src = level0; //Amp 0
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, normalsync_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 * normalsync_0; //4us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
|
|
||||||
//@0
|
|
||||||
//SYNC 1/ 5us
|
//SYNC 1/ 5us
|
||||||
cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp++, index_level1, dma_pad, 1);
|
||||||
cbp->src = level1; //Amp 1
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, normalsync_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 * normalsync_1; //5us;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
|
|
||||||
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
|
SetEasyCB(cbp++, samplecnt + line * 52 + frame * 312 * 52, dma_pad, 1);
|
||||||
//@0
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, 1);
|
||||||
//DATA IN / 1us
|
|
||||||
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 + line * 52 + frame * 312 * 52]);
|
|
||||||
|
|
||||||
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
|
//FRONT PORSH
|
||||||
//SYNC 2us
|
//SYNC 2us
|
||||||
cbp->info = 0; //BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp++, index_level1, dma_pad, 1);
|
||||||
cbp->src = level1; //Amp 1
|
SetEasyCB(cbp++, 0, syncwithpwm ? dma_pwm : dma_pcm, frontsync_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 * frontsync_1; //2us
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 : %d \n",((unsigned int)(cbp)-(unsigned int)(cbarray))/sizeof(dma_cb_t));
|
fprintf(stderr, "Last cbp : %d \n", ((unsigned int)(cbp) - (unsigned int)(cbarray)) / sizeof(dma_cb_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void atv::SetFrame(unsigned char *Luminance, size_t Lines)
|
void atv::SetFrame(unsigned char *Luminance, size_t Lines)
|
||||||
|
@ -370,23 +167,12 @@ void atv::SetFrame(unsigned char *Luminance, size_t Lines)
|
||||||
{
|
{
|
||||||
for (size_t x = 0; x < 52; x++)
|
for (size_t x = 0; x < 52; x++)
|
||||||
{
|
{
|
||||||
int AmplitudePAD = (Luminance[i * 52 + x]/255.0) * 6.0 + 1; //1 to 7
|
int AmplitudePAD = (Luminance[i * 52 + x] / 255.0) * 6.0 + 1; //1 to 7
|
||||||
// usermem[i* 52 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
|
||||||
if (i % 2 == 0) // First field
|
|
||||||
usermem[i* 52 /2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
|
||||||
else
|
|
||||||
usermem[(i-1)* 52/2 + x+52*312] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
|
||||||
|
|
||||||
}
|
|
||||||
/*for (size_t x = 0; x < 52; x++)
|
|
||||||
{
|
|
||||||
int AmplitudePAD = (Luminance[i * 52 + x]/255.0) * 6 + 1; //1 to 7
|
|
||||||
|
|
||||||
if (i % 2 == 0) // First field
|
if (i % 2 == 0) // First field
|
||||||
usermem[i * 52 / 2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
usermem[i * 52 / 2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
||||||
else //second field
|
else
|
||||||
usermem[i * 52 / 2 + Lines / 2 + x] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
usermem[(i - 1) * 52 / 2 + x + 52 * 312] = (0x5A << 24) + (AmplitudePAD & 0x7) + (1 << 4) + (0 << 3); // Amplitude PAD
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
src/dma.cpp
28
src/dma.cpp
|
@ -18,6 +18,7 @@ This program is free software: you can redistribute it and/or modify
|
||||||
|
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
@ -166,6 +167,33 @@ bool dma::isunderflow()
|
||||||
return ((dma_reg.gpioreg[DMA_CS+channel*0x40]&DMA_CS_INT)>0);
|
return ((dma_reg.gpioreg[DMA_CS+channel*0x40]&DMA_CS_INT)>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dma::SetCB(dma_cb_t *cbp,uint32_t dma_flag,uint32_t src,uint32_t dst,uint32_t repeat)
|
||||||
|
{
|
||||||
|
cbp->info = dma_flag;
|
||||||
|
cbp->src = src;
|
||||||
|
cbp->dst = dst;
|
||||||
|
cbp->length = 4*repeat;
|
||||||
|
cbp->stride = 0;
|
||||||
|
cbp->next = mem_virt_to_phys(cbp + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dma::SetEasyCB(dma_cb_t *cbp,uint32_t index,dma_common_reg dst,uint32_t repeat)
|
||||||
|
{
|
||||||
|
uint32_t flag=BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP;
|
||||||
|
uint32_t src=mem_virt_to_phys(&usermem[index]);
|
||||||
|
switch(dst)
|
||||||
|
{
|
||||||
|
case dma_pllc_frac :break;
|
||||||
|
case dma_fsel:break;
|
||||||
|
case dma_pad:break;
|
||||||
|
case dma_pwm : flag|=BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);break;
|
||||||
|
case dma_pcm : flag|=BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PCM_TX);break;
|
||||||
|
}
|
||||||
|
SetCB(cbp,flag,src,dst,repeat);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//**************************************** BUFFER DMA ********************************************************
|
//**************************************** BUFFER DMA ********************************************************
|
||||||
bufferdma::bufferdma(int Channel,uint32_t tbuffersize,uint32_t tcbbysample,uint32_t tregisterbysample):dma(Channel,tbuffersize*tcbbysample,tbuffersize*tregisterbysample)
|
bufferdma::bufferdma(int Channel,uint32_t tbuffersize,uint32_t tcbbysample,uint32_t tregisterbysample):dma(Channel,tbuffersize*tcbbysample,tbuffersize*tregisterbysample)
|
||||||
{
|
{
|
||||||
|
|
63
src/dma.h
63
src/dma.h
|
@ -1,8 +1,9 @@
|
||||||
#ifndef DEF_DMA
|
#ifndef DEF_DMA
|
||||||
#define DEF_DMA
|
#define DEF_DMA
|
||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
#include "util.h"
|
||||||
// ---- Memory allocating defines
|
// ---- Memory allocating defines
|
||||||
// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
|
// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
|
||||||
#define MEM_FLAG_DISCARDABLE (1 << 0) /* can be resized to 0 at any time. Use for cached data */
|
#define MEM_FLAG_DISCARDABLE (1 << 0) /* can be resized to 0 at any time. Use for cached data */
|
||||||
|
@ -10,26 +11,25 @@
|
||||||
#define MEM_FLAG_DIRECT (1 << 2) /* 0xC alias uncached */
|
#define MEM_FLAG_DIRECT (1 << 2) /* 0xC alias uncached */
|
||||||
#define MEM_FLAG_COHERENT (2 << 2) /* 0x8 alias. Non-allocating in L2 but coherent */
|
#define MEM_FLAG_COHERENT (2 << 2) /* 0x8 alias. Non-allocating in L2 but coherent */
|
||||||
#define MEM_FLAG_L1_NONALLOCATING (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT) /* Allocating in L2 */
|
#define MEM_FLAG_L1_NONALLOCATING (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT) /* Allocating in L2 */
|
||||||
#define MEM_FLAG_ZERO ( 1 << 4) /* initialise buffer to all zeros */
|
#define MEM_FLAG_ZERO (1 << 4) /* initialise buffer to all zeros */
|
||||||
#define MEM_FLAG_NO_INIT ( 1 << 5) /* don't initialise (default is initialise to all ones */
|
#define MEM_FLAG_NO_INIT (1 << 5) /* don't initialise (default is initialise to all ones */
|
||||||
#define MEM_FLAG_HINT_PERMALOCK (1 << 6) /* Likely to be locked for long periods of time. */
|
#define MEM_FLAG_HINT_PERMALOCK (1 << 6) /* Likely to be locked for long periods of time. */
|
||||||
|
|
||||||
#define BCM2708_DMA_SRC_IGNOR (1<<11)
|
#define BCM2708_DMA_SRC_IGNOR (1 << 11)
|
||||||
#define BCM2708_DMA_SRC_INC (1<<8)
|
#define BCM2708_DMA_SRC_INC (1 << 8)
|
||||||
#define BCM2708_DMA_DST_IGNOR (1<<7)
|
#define BCM2708_DMA_DST_IGNOR (1 << 7)
|
||||||
#define BCM2708_DMA_NO_WIDE_BURSTS (1<<26)
|
#define BCM2708_DMA_NO_WIDE_BURSTS (1 << 26)
|
||||||
#define BCM2708_DMA_WAIT_RESP (1<<3)
|
#define BCM2708_DMA_WAIT_RESP (1 << 3)
|
||||||
|
|
||||||
|
#define BCM2708_DMA_D_DREQ (1 << 6)
|
||||||
|
#define BCM2708_DMA_PER_MAP(x) ((x) << 16)
|
||||||
|
#define BCM2708_DMA_END (1 << 1)
|
||||||
|
#define BCM2708_DMA_RESET (1 << 31)
|
||||||
|
#define BCM2708_DMA_INT (1 << 2)
|
||||||
|
|
||||||
#define BCM2708_DMA_D_DREQ (1<<6)
|
#define DMA_CS (0x00 / 4)
|
||||||
#define BCM2708_DMA_PER_MAP(x) ((x)<<16)
|
#define DMA_CONBLK_AD (0x04 / 4)
|
||||||
#define BCM2708_DMA_END (1<<1)
|
#define DMA_DEBUG (0x20 / 4)
|
||||||
#define BCM2708_DMA_RESET (1<<31)
|
|
||||||
#define BCM2708_DMA_INT (1<<2)
|
|
||||||
|
|
||||||
#define DMA_CS (0x00/4)
|
|
||||||
#define DMA_CONBLK_AD (0x04/4)
|
|
||||||
#define DMA_DEBUG (0x20/4)
|
|
||||||
|
|
||||||
//Page 61
|
//Page 61
|
||||||
#define DREQ_PCM_TX 2
|
#define DREQ_PCM_TX 2
|
||||||
|
@ -41,23 +41,25 @@
|
||||||
#define DREQ_SPI_SLAVE_TX 8
|
#define DREQ_SPI_SLAVE_TX 8
|
||||||
#define DREQ_SPI_SLAVE_RX 9
|
#define DREQ_SPI_SLAVE_RX 9
|
||||||
|
|
||||||
|
|
||||||
class dma
|
class dma
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
int handle; /* From mbox_open() */
|
int handle; /* From mbox_open() */
|
||||||
unsigned mem_ref; /* From mem_alloc() */
|
unsigned mem_ref; /* From mem_alloc() */
|
||||||
unsigned bus_addr; /* From mem_lock() */
|
unsigned bus_addr; /* From mem_lock() */
|
||||||
uint8_t *virt_addr; /* From mapmem() */
|
uint8_t *virt_addr; /* From mapmem() */
|
||||||
} mbox;
|
} mbox;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
uint32_t info, src, dst, length,
|
uint32_t info, src, dst, length,
|
||||||
stride, next, pad[2];
|
stride, next, pad[2];
|
||||||
} dma_cb_t; //8*4=32 bytes
|
} dma_cb_t; //8*4=32 bytes
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
uint8_t *virtaddr;
|
uint8_t *virtaddr;
|
||||||
uint32_t physaddr;
|
uint32_t physaddr;
|
||||||
} page_map_t;
|
} page_map_t;
|
||||||
|
@ -65,22 +67,21 @@ class dma
|
||||||
page_map_t *page_map;
|
page_map_t *page_map;
|
||||||
|
|
||||||
uint8_t *virtbase;
|
uint8_t *virtbase;
|
||||||
int NumPages=0;
|
int NumPages = 0;
|
||||||
int channel; //DMA Channel
|
int channel; //DMA Channel
|
||||||
dmagpio dma_reg;
|
dmagpio dma_reg;
|
||||||
|
|
||||||
uint32_t mem_flag; //Cache or not depending on Rpi1 or 2/3
|
uint32_t mem_flag; //Cache or not depending on Rpi1 or 2/3
|
||||||
uint32_t dram_phys_base;
|
uint32_t dram_phys_base;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dma_cb_t *cbarray;
|
dma_cb_t *cbarray;
|
||||||
uint32_t cbsize;
|
uint32_t cbsize;
|
||||||
uint32_t *usermem;
|
uint32_t *usermem;
|
||||||
uint32_t usermemsize;
|
uint32_t usermemsize;
|
||||||
bool Started=false;
|
bool Started = false;
|
||||||
|
|
||||||
dma(int Channel,uint32_t CBSize,uint32_t UserMemSize);
|
dma(int Channel, uint32_t CBSize, uint32_t UserMemSize);
|
||||||
~dma();
|
~dma();
|
||||||
uint32_t mem_virt_to_phys(volatile void *virt);
|
uint32_t mem_virt_to_phys(volatile void *virt);
|
||||||
uint32_t mem_phys_to_virt(volatile uint32_t phys);
|
uint32_t mem_phys_to_virt(volatile uint32_t phys);
|
||||||
|
@ -90,16 +91,13 @@ class dma
|
||||||
int getcbposition();
|
int getcbposition();
|
||||||
bool isrunning();
|
bool isrunning();
|
||||||
bool isunderflow();
|
bool isunderflow();
|
||||||
|
bool SetCB(dma_cb_t *cbp, uint32_t dma_flag, uint32_t src, uint32_t dst, uint32_t repeat);
|
||||||
|
bool SetEasyCB(dma_cb_t *cbp, uint32_t index, dma_common_reg dst, uint32_t repeat);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PHYSICAL_BUS 0x7E000000
|
class bufferdma : public dma
|
||||||
|
|
||||||
class bufferdma:public dma
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
uint32_t current_sample;
|
uint32_t current_sample;
|
||||||
uint32_t last_sample;
|
uint32_t last_sample;
|
||||||
uint32_t sample_available;
|
uint32_t sample_available;
|
||||||
|
@ -111,11 +109,10 @@ class bufferdma:public dma
|
||||||
uint32_t *sampletab;
|
uint32_t *sampletab;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bufferdma(int Channel,uint32_t tbuffersize,uint32_t tcbbysample,uint32_t tregisterbysample);
|
bufferdma(int Channel, uint32_t tbuffersize, uint32_t tcbbysample, uint32_t tregisterbysample);
|
||||||
void SetDmaAlgo();
|
void SetDmaAlgo();
|
||||||
int GetBufferAvailable();
|
int GetBufferAvailable();
|
||||||
int GetUserMemIndex();
|
int GetUserMemIndex();
|
||||||
int PushSample(int Index);
|
int PushSample(int Index);
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
334
src/gpio.h
334
src/gpio.h
|
@ -3,58 +3,55 @@
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#define PHYSICAL_BUS 0x7E000000
|
||||||
|
|
||||||
class gpio
|
class gpio
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
volatile uint32_t *gpioreg=NULL;
|
volatile uint32_t *gpioreg = NULL;
|
||||||
uint32_t gpiolen;
|
uint32_t gpiolen;
|
||||||
gpio(uint32_t base, uint32_t len);
|
gpio(uint32_t base, uint32_t len);
|
||||||
~gpio();
|
~gpio();
|
||||||
uint32_t GetPeripheralBase();
|
uint32_t GetPeripheralBase();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DMA_BASE (0x00007000)
|
||||||
#define DMA_BASE (0x00007000 )
|
|
||||||
#define DMA_LEN 0xF00
|
#define DMA_LEN 0xF00
|
||||||
|
|
||||||
#define BCM2708_DMA_SRC_IGNOR (1<<11)
|
#define BCM2708_DMA_SRC_IGNOR (1 << 11)
|
||||||
#define BCM2708_DMA_SRC_INC (1<<8)
|
#define BCM2708_DMA_SRC_INC (1 << 8)
|
||||||
#define BCM2708_DMA_DST_IGNOR (1<<7)
|
#define BCM2708_DMA_DST_IGNOR (1 << 7)
|
||||||
#define BCM2708_DMA_NO_WIDE_BURSTS (1<<26)
|
#define BCM2708_DMA_NO_WIDE_BURSTS (1 << 26)
|
||||||
#define BCM2708_DMA_WAIT_RESP (1<<3)
|
#define BCM2708_DMA_WAIT_RESP (1 << 3)
|
||||||
#define BCM2708_DMA_SET_INT (1<<0)
|
#define BCM2708_DMA_SET_INT (1 << 0)
|
||||||
|
|
||||||
#define BCM2708_DMA_D_DREQ (1<<6)
|
#define BCM2708_DMA_D_DREQ (1 << 6)
|
||||||
#define BCM2708_DMA_PER_MAP(x) ((x)<<16)
|
#define BCM2708_DMA_PER_MAP(x) ((x) << 16)
|
||||||
#define BCM2708_DMA_END (1<<1)
|
#define BCM2708_DMA_END (1 << 1)
|
||||||
#define BCM2708_DMA_RESET (1<<31)
|
#define BCM2708_DMA_RESET (1 << 31)
|
||||||
#define BCM2708_DMA_ABORT (1<<30)
|
#define BCM2708_DMA_ABORT (1 << 30)
|
||||||
#define BCM2708_DMA_INT (1<<2)
|
#define BCM2708_DMA_INT (1 << 2)
|
||||||
|
|
||||||
#define DMA_CS (0x00/4)
|
#define DMA_CS (0x00 / 4)
|
||||||
#define DMA_CONBLK_AD (0x04/4)
|
#define DMA_CONBLK_AD (0x04 / 4)
|
||||||
#define DMA_DEBUG (0x20/4)
|
#define DMA_DEBUG (0x20 / 4)
|
||||||
|
|
||||||
#define DMA_CS_RESET (1<<31)
|
#define DMA_CS_RESET (1 << 31)
|
||||||
#define DMA_CS_ABORT (1<<30)
|
#define DMA_CS_ABORT (1 << 30)
|
||||||
#define DMA_CS_DISDEBUG (1<<29)
|
#define DMA_CS_DISDEBUG (1 << 29)
|
||||||
#define DMA_CS_WAIT_FOR_OUTSTANDING_WRITES (1<<28)
|
#define DMA_CS_WAIT_FOR_OUTSTANDING_WRITES (1 << 28)
|
||||||
#define DMA_CS_INT (1<<2)
|
#define DMA_CS_INT (1 << 2)
|
||||||
#define DMA_CS_END (1<<1)
|
#define DMA_CS_END (1 << 1)
|
||||||
#define DMA_CS_ACTIVE (1<<0)
|
#define DMA_CS_ACTIVE (1 << 0)
|
||||||
#define DMA_CS_PRIORITY(x) ((x)&0xf << 16)
|
#define DMA_CS_PRIORITY(x) ((x)&0xf << 16)
|
||||||
#define DMA_CS_PANIC_PRIORITY(x) ((x)&0xf << 20)
|
#define DMA_CS_PANIC_PRIORITY(x) ((x)&0xf << 20)
|
||||||
|
|
||||||
class dmagpio:public gpio
|
class dmagpio : public gpio
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dmagpio();
|
dmagpio();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//************************************ GENERAL GPIO ***************************************
|
//************************************ GENERAL GPIO ***************************************
|
||||||
|
@ -62,16 +59,26 @@ class dmagpio:public gpio
|
||||||
#define GENERAL_BASE (0x00200000)
|
#define GENERAL_BASE (0x00200000)
|
||||||
#define GENERAL_LEN 0xB4
|
#define GENERAL_LEN 0xB4
|
||||||
|
|
||||||
#define GPFSEL0 (0x00/4)
|
#define GPFSEL0 (0x00 / 4)
|
||||||
#define GPFSEL1 (0x04/4)
|
#define GPFSEL1 (0x04 / 4)
|
||||||
#define GPFSEL2 (0x08/4)
|
#define GPFSEL2 (0x08 / 4)
|
||||||
#define GPPUD (0x94/4)
|
#define GPPUD (0x94 / 4)
|
||||||
#define GPPUDCLK0 (0x98/4)
|
#define GPPUDCLK0 (0x98 / 4)
|
||||||
#define GPPUDCLK1 (0x9C/4)
|
#define GPPUDCLK1 (0x9C / 4)
|
||||||
|
|
||||||
enum {fsel_input,fsel_output,fsel_alt5,fsel_alt4,fsel_alt0,fsel_alt1,fsel_alt2,fsel_alt3};
|
enum
|
||||||
|
{
|
||||||
|
fsel_input,
|
||||||
|
fsel_output,
|
||||||
|
fsel_alt5,
|
||||||
|
fsel_alt4,
|
||||||
|
fsel_alt0,
|
||||||
|
fsel_alt1,
|
||||||
|
fsel_alt2,
|
||||||
|
fsel_alt3
|
||||||
|
};
|
||||||
|
|
||||||
class generalgpio:public gpio
|
class generalgpio : public gpio
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -89,14 +96,14 @@ class generalgpio:public gpio
|
||||||
#define CLK_BASE (0x00101000)
|
#define CLK_BASE (0x00101000)
|
||||||
#define CLK_LEN 0x1660
|
#define CLK_LEN 0x1660
|
||||||
|
|
||||||
#define CORECLK_CNTL (0x08/4)
|
#define CORECLK_CNTL (0x08 / 4)
|
||||||
#define CORECLK_DIV (0x0c/4)
|
#define CORECLK_DIV (0x0c / 4)
|
||||||
#define GPCLK_CNTL (0x70/4)
|
#define GPCLK_CNTL (0x70 / 4)
|
||||||
#define GPCLK_DIV (0x74/4)
|
#define GPCLK_DIV (0x74 / 4)
|
||||||
#define GPCLK_CNTL_2 (0x80/4)
|
#define GPCLK_CNTL_2 (0x80 / 4)
|
||||||
#define GPCLK_DIV_2 (0x84/4)
|
#define GPCLK_DIV_2 (0x84 / 4)
|
||||||
#define EMMCCLK_CNTL (0x1C0/4)
|
#define EMMCCLK_CNTL (0x1C0 / 4)
|
||||||
#define EMMCCLK_DIV (0x1C4/4)
|
#define EMMCCLK_DIV (0x1C4 / 4)
|
||||||
|
|
||||||
#define CM_VPUCTL 0x008
|
#define CM_VPUCTL 0x008
|
||||||
#define CM_VPUDIV 0x00c
|
#define CM_VPUDIV 0x00c
|
||||||
|
@ -144,7 +151,7 @@ class generalgpio:public gpio
|
||||||
#define CM_SMIDIV 0x0b4
|
#define CM_SMIDIV 0x0b4
|
||||||
/* no definition for 0x0b8 and 0x0bc */
|
/* no definition for 0x0b8 and 0x0bc */
|
||||||
#define CM_TCNTCTL 0x0c0
|
#define CM_TCNTCTL 0x0c0
|
||||||
# define CM_TCNT_SRC1_SHIFT 12
|
#define CM_TCNT_SRC1_SHIFT 12
|
||||||
#define CM_TCNTCNT 0x0c4
|
#define CM_TCNTCNT 0x0c4
|
||||||
#define CM_TECCTL 0x0c8
|
#define CM_TECCTL 0x0c8
|
||||||
#define CM_TECDIV 0x0cc
|
#define CM_TECDIV 0x0cc
|
||||||
|
@ -170,15 +177,14 @@ class generalgpio:public gpio
|
||||||
#define CM_EMMCCTL 0x1c0
|
#define CM_EMMCCTL 0x1c0
|
||||||
#define CM_EMMCDIV 0x1c4
|
#define CM_EMMCDIV 0x1c4
|
||||||
|
|
||||||
|
#define CM_LOCK (0x114 / 4)
|
||||||
|
#define CM_LOCK_FLOCKH (1 << 12)
|
||||||
|
#define CM_LOCK_FLOCKD (1 << 11)
|
||||||
|
#define CM_LOCK_FLOCKC (1 << 10)
|
||||||
|
#define CM_LOCK_FLOCKB (1 << 9)
|
||||||
|
#define CM_LOCK_FLOCKA (1 << 8)
|
||||||
|
|
||||||
#define CM_LOCK (0x114/4)
|
#define CM_PLLA (0x104 / 4)
|
||||||
# define CM_LOCK_FLOCKH (1<<12)
|
|
||||||
# define CM_LOCK_FLOCKD (1<<11)
|
|
||||||
# define CM_LOCK_FLOCKC (1<<10)
|
|
||||||
# define CM_LOCK_FLOCKB (1<<9)
|
|
||||||
# define CM_LOCK_FLOCKA (1<<8)
|
|
||||||
|
|
||||||
#define CM_PLLA (0x104/4)
|
|
||||||
/*
|
/*
|
||||||
# define CM_PLL_ANARST BIT(8)
|
# define CM_PLL_ANARST BIT(8)
|
||||||
# define CM_PLLA_HOLDPER BIT(7)
|
# define CM_PLLA_HOLDPER BIT(7)
|
||||||
|
@ -190,135 +196,144 @@ class generalgpio:public gpio
|
||||||
# define CM_PLLA_HOLDDSI0 BIT(1)
|
# define CM_PLLA_HOLDDSI0 BIT(1)
|
||||||
# define CM_PLLA_LOADDSI0 BIT(0)
|
# define CM_PLLA_LOADDSI0 BIT(0)
|
||||||
*/
|
*/
|
||||||
#define CM_PLLC (0x108/4)
|
#define CM_PLLC (0x108 / 4)
|
||||||
#define CM_PLLD (0x10c/4)
|
#define CM_PLLD (0x10c / 4)
|
||||||
#define CM_PLLH (0x110/4)
|
#define CM_PLLH (0x110 / 4)
|
||||||
#define CM_PLLB (0x170/4)
|
#define CM_PLLB (0x170 / 4)
|
||||||
|
|
||||||
|
#define A2W_PLLA_ANA0 (0x1010 / 4)
|
||||||
|
#define A2W_PLLC_ANA0 (0x1030 / 4)
|
||||||
#define A2W_PLLA_ANA0 (0x1010/4)
|
#define A2W_PLLD_ANA0 (0x1050 / 4)
|
||||||
#define A2W_PLLC_ANA0 (0x1030/4)
|
#define A2W_PLLH_ANA0 (0x1070 / 4)
|
||||||
#define A2W_PLLD_ANA0 (0x1050/4)
|
#define A2W_PLLB_ANA0 (0x10f0 / 4)
|
||||||
#define A2W_PLLH_ANA0 (0x1070/4)
|
|
||||||
#define A2W_PLLB_ANA0 (0x10f0/4)
|
|
||||||
#define A2W_PLL_KA_SHIFT 7
|
#define A2W_PLL_KA_SHIFT 7
|
||||||
#define A2W_PLL_KI_SHIFT 19
|
#define A2W_PLL_KI_SHIFT 19
|
||||||
#define A2W_PLL_KP_SHIFT 15
|
#define A2W_PLL_KP_SHIFT 15
|
||||||
|
|
||||||
#define PLLA_CTRL (0x1100/4)
|
#define PLLA_CTRL (0x1100 / 4)
|
||||||
#define PLLA_FRAC (0x1200/4)
|
#define PLLA_FRAC (0x1200 / 4)
|
||||||
#define PLLA_DSI0 (0x1300/4)
|
#define PLLA_DSI0 (0x1300 / 4)
|
||||||
#define PLLA_CORE (0x1400/4)
|
#define PLLA_CORE (0x1400 / 4)
|
||||||
#define PLLA_PER (0x1500/4)
|
#define PLLA_PER (0x1500 / 4)
|
||||||
#define PLLA_CCP2 (0x1600/4)
|
#define PLLA_CCP2 (0x1600 / 4)
|
||||||
|
|
||||||
#define PLLB_CTRL (0x11e0/4)
|
#define PLLB_CTRL (0x11e0 / 4)
|
||||||
#define PLLB_FRAC (0x12e0/4)
|
#define PLLB_FRAC (0x12e0 / 4)
|
||||||
#define PLLB_ARM (0x13e0/4)
|
#define PLLB_ARM (0x13e0 / 4)
|
||||||
#define PLLB_SP0 (0x14e0/4)
|
#define PLLB_SP0 (0x14e0 / 4)
|
||||||
#define PLLB_SP1 (0x15e0/4)
|
#define PLLB_SP1 (0x15e0 / 4)
|
||||||
#define PLLB_SP2 (0x16e0/4)
|
#define PLLB_SP2 (0x16e0 / 4)
|
||||||
|
|
||||||
#define PLLC_CTRL (0x1120/4)
|
#define PLLC_CTRL (0x1120 / 4)
|
||||||
#define PLLC_FRAC (0x1220/4)
|
#define PLLC_FRAC (0x1220 / 4)
|
||||||
#define PLLC_CORE2 (0x1320/4)
|
#define PLLC_CORE2 (0x1320 / 4)
|
||||||
#define PLLC_CORE1 (0x1420/4)
|
#define PLLC_CORE1 (0x1420 / 4)
|
||||||
#define PLLC_PER (0x1520/4)
|
#define PLLC_PER (0x1520 / 4)
|
||||||
#define PLLC_CORE0 (0x1620/4)
|
#define PLLC_CORE0 (0x1620 / 4)
|
||||||
|
|
||||||
#define PLLD_CTRL (0x1140/4)
|
#define PLLD_CTRL (0x1140 / 4)
|
||||||
#define PLLD_FRAC (0x1240/4)
|
#define PLLD_FRAC (0x1240 / 4)
|
||||||
#define PLLD_DSI0 (0x1340/4)
|
#define PLLD_DSI0 (0x1340 / 4)
|
||||||
#define PLLD_CORE (0x1440/4)
|
#define PLLD_CORE (0x1440 / 4)
|
||||||
#define PLLD_PER (0x1540/4)
|
#define PLLD_PER (0x1540 / 4)
|
||||||
#define PLLD_DSI1 (0x1640/4)
|
#define PLLD_DSI1 (0x1640 / 4)
|
||||||
|
|
||||||
#define PLLH_CTRL (0x1160/4)
|
#define PLLH_CTRL (0x1160 / 4)
|
||||||
#define PLLH_FRAC (0x1260/4)
|
#define PLLH_FRAC (0x1260 / 4)
|
||||||
#define PLLH_AUX (0x1360/4)
|
#define PLLH_AUX (0x1360 / 4)
|
||||||
#define PLLH_RCAL (0x1460/4)
|
#define PLLH_RCAL (0x1460 / 4)
|
||||||
#define PLLH_PIX (0x1560/4)
|
#define PLLH_PIX (0x1560 / 4)
|
||||||
#define PLLH_STS (0x1660/4)
|
#define PLLH_STS (0x1660 / 4)
|
||||||
|
|
||||||
#define XOSC_CTRL (0x1190/4)
|
#define XOSC_CTRL (0x1190 / 4)
|
||||||
#define XOSC_FREQUENCY 19200000
|
#define XOSC_FREQUENCY 19200000
|
||||||
|
|
||||||
//Parent PLL
|
//Parent PLL
|
||||||
enum {clk_gnd,clk_osc,clk_debug0,clk_debug1,clk_plla,clk_pllc,clk_plld,clk_hdmi};
|
enum
|
||||||
|
{
|
||||||
|
clk_gnd,
|
||||||
|
clk_osc,
|
||||||
|
clk_debug0,
|
||||||
|
clk_debug1,
|
||||||
|
clk_plla,
|
||||||
|
clk_pllc,
|
||||||
|
clk_plld,
|
||||||
|
clk_hdmi
|
||||||
|
};
|
||||||
|
|
||||||
class clkgpio:public gpio
|
class clkgpio : public gpio
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int pllnumber;
|
int pllnumber;
|
||||||
int Mash;
|
int Mash;
|
||||||
uint64_t Pllfrequency;
|
uint64_t Pllfrequency;
|
||||||
bool ModulateFromMasterPLL=false;
|
bool ModulateFromMasterPLL = false;
|
||||||
uint64_t CentralFrequency=0;
|
uint64_t CentralFrequency = 0;
|
||||||
generalgpio gengpio;
|
generalgpio gengpio;
|
||||||
double clk_ppm=0;
|
double clk_ppm = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int PllFixDivider=8; //Fix divider from the master clock in advanced mode
|
int PllFixDivider = 8; //Fix divider from the master clock in advanced mode
|
||||||
|
|
||||||
clkgpio();
|
clkgpio();
|
||||||
~clkgpio();
|
~clkgpio();
|
||||||
int SetPllNumber(int PllNo,int MashType);
|
int SetPllNumber(int PllNo, int MashType);
|
||||||
uint64_t GetPllFrequency(int PllNo);
|
uint64_t GetPllFrequency(int PllNo);
|
||||||
void print_clock_tree(void);
|
void print_clock_tree(void);
|
||||||
int SetFrequency(double Frequency);
|
int SetFrequency(double Frequency);
|
||||||
int SetClkDivFrac(uint32_t Div,uint32_t Frac);
|
int SetClkDivFrac(uint32_t Div, uint32_t Frac);
|
||||||
void SetPhase(bool inversed);
|
void SetPhase(bool inversed);
|
||||||
void SetAdvancedPllMode(bool Advanced);
|
void SetAdvancedPllMode(bool Advanced);
|
||||||
int SetCenterFrequency(uint64_t Frequency,int Bandwidth);
|
int SetCenterFrequency(uint64_t Frequency, int Bandwidth);
|
||||||
double GetFrequencyResolution();
|
double GetFrequencyResolution();
|
||||||
double GetRealFrequency(double Frequency);
|
double GetRealFrequency(double Frequency);
|
||||||
int ComputeBestLO(uint64_t Frequency,int Bandwidth);
|
int ComputeBestLO(uint64_t Frequency, int Bandwidth);
|
||||||
int SetMasterMultFrac(uint32_t Mult,uint32_t Frac);
|
int SetMasterMultFrac(uint32_t Mult, uint32_t Frac);
|
||||||
uint32_t GetMasterFrac(double Frequency);
|
uint32_t GetMasterFrac(double Frequency);
|
||||||
void enableclk(int gpio);
|
void enableclk(int gpio);
|
||||||
void disableclk(int gpio);
|
void disableclk(int gpio);
|
||||||
void Setppm(double ppm);
|
void Setppm(double ppm);
|
||||||
void SetppmFromNTP();
|
void SetppmFromNTP();
|
||||||
void SetPLLMasterLoop(int Ki,int Kp,int Ka);
|
void SetPLLMasterLoop(int Ki, int Kp, int Ka);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//************************************ PWM GPIO ***************************************
|
//************************************ PWM GPIO ***************************************
|
||||||
|
|
||||||
#define PWM_BASE (0x0020C000)
|
#define PWM_BASE (0x0020C000)
|
||||||
#define PWM_LEN 0x28
|
#define PWM_LEN 0x28
|
||||||
|
|
||||||
#define PWM_CTL (0x00/4)
|
#define PWM_CTL (0x00 / 4)
|
||||||
#define PWM_DMAC (0x08/4)
|
#define PWM_DMAC (0x08 / 4)
|
||||||
#define PWM_RNG1 (0x10/4)
|
#define PWM_RNG1 (0x10 / 4)
|
||||||
#define PWM_RNG2 (0x20/4)
|
#define PWM_RNG2 (0x20 / 4)
|
||||||
#define PWM_FIFO (0x18/4)
|
#define PWM_FIFO (0x18 / 4)
|
||||||
|
|
||||||
#define PWMCLK_CNTL (40) // Clk register
|
#define PWMCLK_CNTL (40) // Clk register
|
||||||
#define PWMCLK_DIV (41) // Clk register
|
#define PWMCLK_DIV (41) // Clk register
|
||||||
|
|
||||||
|
#define PWMCTL_MSEN2 (1 << 15)
|
||||||
|
#define PWMCTL_USEF2 (1 << 13)
|
||||||
|
#define PWMCTL_RPTL2 (1 << 10)
|
||||||
|
#define PWMCTL_MODE2 (1 << 9)
|
||||||
|
#define PWMCTL_PWEN2 (1 << 8)
|
||||||
|
|
||||||
#define PWMCTL_MSEN2 (1<<15)
|
#define PWMCTL_MSEN1 (1 << 7)
|
||||||
#define PWMCTL_USEF2 (1<<13)
|
#define PWMCTL_CLRF (1 << 6)
|
||||||
#define PWMCTL_RPTL2 (1<<10)
|
#define PWMCTL_USEF1 (1 << 5)
|
||||||
#define PWMCTL_MODE2 (1<<9)
|
#define PWMCTL_POLA1 (1 << 4)
|
||||||
#define PWMCTL_PWEN2 (1<<8)
|
#define PWMCTL_RPTL1 (1 << 2)
|
||||||
|
#define PWMCTL_MODE1 (1 << 1)
|
||||||
|
#define PWMCTL_PWEN1 (1 << 0)
|
||||||
|
#define PWMDMAC_ENAB (1 << 31)
|
||||||
|
#define PWMDMAC_THRSHLD ((15 << 8) | (15 << 0))
|
||||||
|
enum pwmmode
|
||||||
|
{
|
||||||
|
pwm1pin,
|
||||||
|
pwm2pin,
|
||||||
|
pwm1pinrepeat
|
||||||
|
};
|
||||||
|
|
||||||
#define PWMCTL_MSEN1 (1<<7)
|
class pwmgpio : public gpio
|
||||||
#define PWMCTL_CLRF (1<<6)
|
|
||||||
#define PWMCTL_USEF1 (1<<5)
|
|
||||||
#define PWMCTL_POLA1 (1<<4)
|
|
||||||
#define PWMCTL_RPTL1 (1<<2)
|
|
||||||
#define PWMCTL_MODE1 (1<<1)
|
|
||||||
#define PWMCTL_PWEN1 (1<<0)
|
|
||||||
#define PWMDMAC_ENAB (1<<31)
|
|
||||||
#define PWMDMAC_THRSHLD ((15<<8)|(15<<0))
|
|
||||||
enum pwmmode{pwm1pin,pwm2pin,pwm1pinrepeat};
|
|
||||||
|
|
||||||
class pwmgpio:public gpio
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
clkgpio clk;
|
clkgpio clk;
|
||||||
|
@ -326,18 +341,19 @@ class pwmgpio:public gpio
|
||||||
int Mash;
|
int Mash;
|
||||||
int Prediv; //Range of PWM
|
int Prediv; //Range of PWM
|
||||||
uint64_t Pllfrequency;
|
uint64_t Pllfrequency;
|
||||||
bool ModulateFromMasterPLL=false;
|
bool ModulateFromMasterPLL = false;
|
||||||
int ModePwm=pwm1pin;
|
int ModePwm = pwm1pin;
|
||||||
generalgpio gengpio;
|
generalgpio gengpio;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pwmgpio();
|
pwmgpio();
|
||||||
~pwmgpio();
|
~pwmgpio();
|
||||||
int SetPllNumber(int PllNo,int MashType);
|
int SetPllNumber(int PllNo, int MashType);
|
||||||
uint64_t GetPllFrequency(int PllNo);
|
uint64_t GetPllFrequency(int PllNo);
|
||||||
int SetFrequency(uint64_t Frequency);
|
int SetFrequency(uint64_t Frequency);
|
||||||
int SetPrediv(int predivisor);
|
int SetPrediv(int predivisor);
|
||||||
void SetMode(int Mode);
|
void SetMode(int Mode);
|
||||||
void enablepwm(int gpio,int PwmNumber);
|
void enablepwm(int gpio, int PwmNumber);
|
||||||
void disablepwm(int gpio);
|
void disablepwm(int gpio);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -345,20 +361,20 @@ class pwmgpio:public gpio
|
||||||
#define PCM_BASE (0x00203000)
|
#define PCM_BASE (0x00203000)
|
||||||
#define PCM_LEN 0x24
|
#define PCM_LEN 0x24
|
||||||
|
|
||||||
#define PCM_CS_A (0x00/4)
|
#define PCM_CS_A (0x00 / 4)
|
||||||
#define PCM_FIFO_A (0x04/4)
|
#define PCM_FIFO_A (0x04 / 4)
|
||||||
#define PCM_MODE_A (0x08/4)
|
#define PCM_MODE_A (0x08 / 4)
|
||||||
#define PCM_RXC_A (0x0c/4)
|
#define PCM_RXC_A (0x0c / 4)
|
||||||
#define PCM_TXC_A (0x10/4)
|
#define PCM_TXC_A (0x10 / 4)
|
||||||
#define PCM_DREQ_A (0x14/4)
|
#define PCM_DREQ_A (0x14 / 4)
|
||||||
#define PCM_INTEN_A (0x18/4)
|
#define PCM_INTEN_A (0x18 / 4)
|
||||||
#define PCM_INT_STC_A (0x1c/4)
|
#define PCM_INT_STC_A (0x1c / 4)
|
||||||
#define PCM_GRAY (0x20/4)
|
#define PCM_GRAY (0x20 / 4)
|
||||||
|
|
||||||
#define PCMCLK_CNTL (38) // Clk register
|
#define PCMCLK_CNTL (38) // Clk register
|
||||||
#define PCMCLK_DIV (39) // Clk register
|
#define PCMCLK_DIV (39) // Clk register
|
||||||
|
|
||||||
class pcmgpio:public gpio
|
class pcmgpio : public gpio
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
clkgpio clk;
|
clkgpio clk;
|
||||||
|
@ -372,22 +388,21 @@ class pcmgpio:public gpio
|
||||||
public:
|
public:
|
||||||
pcmgpio();
|
pcmgpio();
|
||||||
~pcmgpio();
|
~pcmgpio();
|
||||||
int SetPllNumber(int PllNo,int MashType);
|
int SetPllNumber(int PllNo, int MashType);
|
||||||
uint64_t GetPllFrequency(int PllNo);
|
uint64_t GetPllFrequency(int PllNo);
|
||||||
int SetFrequency(uint64_t Frequency);
|
int SetFrequency(uint64_t Frequency);
|
||||||
int ComputePrediv(uint64_t Frequency);
|
int ComputePrediv(uint64_t Frequency);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//******************************* PAD GPIO (Amplitude) ***********************************
|
//******************************* PAD GPIO (Amplitude) ***********************************
|
||||||
#define PADS_GPIO (0x00100000)
|
#define PADS_GPIO (0x00100000)
|
||||||
#define PADS_GPIO_LEN (0x40/4)
|
#define PADS_GPIO_LEN (0x40 / 4)
|
||||||
|
|
||||||
#define PADS_GPIO_0 (0x2C/4)
|
#define PADS_GPIO_0 (0x2C / 4)
|
||||||
#define PADS_GPIO_1 (0x30/4)
|
#define PADS_GPIO_1 (0x30 / 4)
|
||||||
#define PADS_GPIO_2 (0x34/4)
|
#define PADS_GPIO_2 (0x34 / 4)
|
||||||
|
|
||||||
class padgpio:public gpio
|
class padgpio : public gpio
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -396,4 +411,13 @@ class padgpio:public gpio
|
||||||
int setlevel(int level);
|
int setlevel(int level);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum dma_common_reg
|
||||||
|
{
|
||||||
|
dma_pllc_frac = 0x7E000000 + (PLLC_FRAC << 2) + CLK_BASE,
|
||||||
|
dma_pwm = 0x7E000000 + (PWM_FIFO << 2) + PWM_BASE,
|
||||||
|
dma_pcm = 0x7E000000 + (PCM_FIFO_A << 2) + PCM_BASE,
|
||||||
|
dma_fsel = 0x7E000000 + (GPFSEL0 << 2) + GENERAL_BASE,
|
||||||
|
dma_pad = 0x7E000000 + (PADS_GPIO_0 << 2) + PADS_GPIO
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -81,55 +81,20 @@ void iqdmasync::SetDmaAlgo()
|
||||||
for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++)
|
for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
SetEasyCB(cbp,samplecnt*registerbysample+1,dma_pad,1);
|
||||||
|
|
||||||
//@0
|
|
||||||
//Set Amplitude by writing to PADS
|
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample+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++;
|
cbp++;
|
||||||
|
|
||||||
//@2 Write a frequency sample : Order of DMA CS influence maximum rate : here 0,2,1 is the best : why !!!!!!
|
//@2 Write a frequency sample : Order of DMA CS influence maximum rate : here 0,2,1 is the best : why !!!!!!
|
||||||
|
SetEasyCB(cbp,samplecnt*registerbysample,dma_pllc_frac,1);
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
|
||||||
cbp->dst = 0x7E000000 + (PLLC_FRAC<<2) + CLK_BASE ;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
//@1
|
//@1
|
||||||
//Set Amplitude to FSEL for amplitude=0
|
//Set Amplitude to FSEL for amplitude=0
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp,samplecnt*registerbysample+2,dma_fsel,1);
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample+2]);
|
|
||||||
cbp->dst = 0x7E000000 + (GPFSEL0<<2)+GENERAL_BASE;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//@3 Delay
|
//@3 Delay
|
||||||
if(syncwithpwm)
|
SetEasyCB(cbp,samplecnt*registerbysample,syncwithpwm?dma_pwm:dma_pcm,1);
|
||||||
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(&usermem[(samplecnt+1)*registerbysample]);//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;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
|
|
|
@ -74,31 +74,12 @@ void ngfmdmasync::SetDmaAlgo()
|
||||||
|
|
||||||
|
|
||||||
// Write a frequency sample
|
// Write a frequency sample
|
||||||
|
SetEasyCB(cbp,samplecnt*registerbysample,dma_pllc_frac,1);
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
|
||||||
cbp->dst = 0x7E000000 + (PLLC_FRAC<<2) + CLK_BASE ;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
|
|
||||||
// Delay
|
// Delay
|
||||||
if(syncwithpwm)
|
SetEasyCB(cbp,samplecnt*registerbysample,syncwithpwm?dma_pwm:dma_pcm,1);
|
||||||
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;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -119,7 +100,7 @@ void ngfmdmasync::SetFrequencySample(uint32_t Index,float Frequency)
|
||||||
void ngfmdmasync::SetFrequencySamples(float *sample,size_t Size)
|
void ngfmdmasync::SetFrequencySamples(float *sample,size_t Size)
|
||||||
{
|
{
|
||||||
size_t NbWritten=0;
|
size_t NbWritten=0;
|
||||||
int OSGranularity=100;
|
int OSGranularity=200;
|
||||||
|
|
||||||
long int start_time;
|
long int start_time;
|
||||||
long time_difference=0;
|
long time_difference=0;
|
||||||
|
@ -133,19 +114,20 @@ void ngfmdmasync::SetFrequencySamples(float *sample,size_t Size)
|
||||||
int TimeToSleep=1e6*((int)buffersize*3/4-Available)/SampleRate-OSGranularity; // Sleep for theorically fill 3/4 of Fifo
|
int TimeToSleep=1e6*((int)buffersize*3/4-Available)/SampleRate-OSGranularity; // Sleep for theorically fill 3/4 of Fifo
|
||||||
if(TimeToSleep>0)
|
if(TimeToSleep>0)
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"buffer size %d Available %d SampleRate %d Sleep %d\n",buffersize,Available,SampleRate,TimeToSleep);
|
fprintf(stderr,"buffer size %d Available %d SampleRate %d Sleep %d\n",buffersize,Available,SampleRate,TimeToSleep);
|
||||||
usleep(TimeToSleep);
|
usleep(TimeToSleep);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"No Sleep %d\n",TimeToSleep);
|
fprintf(stderr,"No Sleep %d\n",TimeToSleep);
|
||||||
sched_yield();
|
sched_yield();
|
||||||
}
|
}
|
||||||
clock_gettime(CLOCK_REALTIME, &gettime_now);
|
clock_gettime(CLOCK_REALTIME, &gettime_now);
|
||||||
time_difference = gettime_now.tv_nsec - start_time;
|
time_difference = gettime_now.tv_nsec - start_time;
|
||||||
if(time_difference<0) time_difference+=1E9;
|
if(time_difference<0) time_difference+=1E9;
|
||||||
//fprintf(stderr,"Measure samplerate=%d\n",(int)((GetBufferAvailable()-Available)*1e9/time_difference));
|
int NewAvailable=GetBufferAvailable();
|
||||||
Available=GetBufferAvailable();
|
fprintf(stderr,"Newavailable %d Measure samplerate=%d\n",NewAvailable,(int)((GetBufferAvailable()-Available)*1e9/time_difference));
|
||||||
|
Available=NewAvailable;
|
||||||
int Index=GetUserMemIndex();
|
int Index=GetUserMemIndex();
|
||||||
int ToWrite=((int)Size-(int)NbWritten)<Available?Size-NbWritten:Available;
|
int ToWrite=((int)Size-(int)NbWritten)<Available?Size-NbWritten:Available;
|
||||||
|
|
||||||
|
|
|
@ -61,69 +61,31 @@ This program is free software: you can redistribute it and/or modify
|
||||||
// PCM FIFO = 64
|
// PCM FIFO = 64
|
||||||
if(syncwithpwm)
|
if(syncwithpwm)
|
||||||
{
|
{
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);
|
SetEasyCB(cbp++,0,dma_pwm,16+1);
|
||||||
cbp->src = mem_virt_to_phys(cbarray); // Data is not important as we use it only to feed the PWM
|
|
||||||
cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ;
|
|
||||||
cbp->length = 4*(16+1);
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PCM_TX);
|
SetEasyCB(cbp++,0,dma_pcm,64+1);
|
||||||
cbp->src = mem_virt_to_phys(cbarray); // Data is not important as we use it only to feed PCM
|
|
||||||
cbp->dst = 0x7E000000 + (PCM_FIFO_A<<2) + PCM_BASE ;
|
|
||||||
cbp->length = 4*(64+1);
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t samplecnt = 0; samplecnt < buffersize-2; samplecnt++)
|
for (uint32_t samplecnt = 0; samplecnt < buffersize-2; samplecnt++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
//Set Amplitude to FSEL for amplitude=0
|
//Set Amplitude to FSEL for amplitude=0
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp++,samplecnt*registerbysample,dma_fsel,1);
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
|
||||||
cbp->dst = 0x7E000000 + (GPFSEL0<<2)+GENERAL_BASE;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
cbp++;
|
|
||||||
|
|
||||||
|
|
||||||
// Delay
|
// Delay
|
||||||
if(syncwithpwm)
|
SetEasyCB(cbp++,samplecnt*registerbysample,syncwithpwm?dma_pwm:dma_pcm,1);
|
||||||
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;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %d pointer %p src %x dest %x next %x\n",samplecnt,cbp,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
lastcbp=cbp;
|
lastcbp=cbp;
|
||||||
|
|
||||||
// Last CBP before stopping : disable output
|
// Last CBP before stopping : disable output
|
||||||
sampletab[buffersize*registerbysample-1]=(Originfsel & ~(7 << 12)) | (0 << 12); //Disable Clk
|
sampletab[buffersize*registerbysample-1]=(Originfsel & ~(7 << 12)) | (0 << 12); //Disable Clk
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
|
SetEasyCB(cbp,buffersize*registerbysample-1,dma_fsel,1);
|
||||||
cbp->src = mem_virt_to_phys(&usermem[(buffersize*registerbysample-1)]);
|
|
||||||
cbp->dst = 0x7E000000 + (GPFSEL0<<2)+GENERAL_BASE;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = 0; // Stop DMA
|
cbp->next = 0; // Stop DMA
|
||||||
|
|
||||||
//fprintf(stderr,"Last cbp %p: src %x dest %x next %x\n",cbp,cbp->src,cbp->dst,cbp->next);
|
|
||||||
}
|
}
|
||||||
void ookburst::SetSymbols(unsigned char *Symbols,uint32_t Size)
|
void ookburst::SetSymbols(unsigned char *Symbols,uint32_t Size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,14 +62,7 @@ void serialdmasync::SetDmaAlgo()
|
||||||
for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++)
|
for (uint32_t samplecnt = 0; samplecnt < buffersize; samplecnt++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
SetEasyCB(cbp,samplecnt*registerbysample,dma_pwm,1);
|
||||||
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);
|
|
||||||
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
|
|
||||||
cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ;
|
|
||||||
cbp->length = 4;
|
|
||||||
cbp->stride = 0;
|
|
||||||
cbp->next = mem_virt_to_phys(cbp + 1);
|
|
||||||
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
|
|
||||||
cbp++;
|
cbp++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
14
src/util.h
Normal file
14
src/util.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef DEF_UTIL
|
||||||
|
#define DEF_UTIL
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void dbg_printf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in a new issue