This commit is contained in:
joan 2015-02-14 21:34:20 +00:00
parent 19f0245957
commit 9aeb30d0dc
4 changed files with 76 additions and 142 deletions

210
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* pigpio version 28 */ /* pigpio version 29 */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -285,8 +285,6 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define PI_PERI_PHYS 0x7E000000 #define PI_PERI_PHYS 0x7E000000
static void *dummy = MAP_FAILED;
static volatile uint32_t piModel = 1; static volatile uint32_t piModel = 1;
static volatile uint32_t PI_PERI_BASE = 0x20000000; static volatile uint32_t PI_PERI_BASE = 0x20000000;
@ -742,6 +740,8 @@ static volatile uint32_t DMA_BUS_CACHE = 0x00000000;
#define PI_MASH_MAX_FREQ 23800000 #define PI_MASH_MAX_FREQ 23800000
#define FLUSH_PAGES 1024
/* --------------------------------------------------------------- */ /* --------------------------------------------------------------- */
typedef void (*callbk_t) (); typedef void (*callbk_t) ();
@ -901,7 +901,6 @@ typedef struct
uint32_t maxSamples; uint32_t maxSamples;
uint32_t numSamples; uint32_t numSamples;
uint32_t DMARestarts; uint32_t DMARestarts;
uint32_t DMAInits;
uint32_t dmaInitCbsCount; uint32_t dmaInitCbsCount;
} gpioStats_t; } gpioStats_t;
@ -1209,7 +1208,6 @@ static int gpioNotifyOpenInBand(int fd);
static void initHWClk static void initHWClk
(int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH); (int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH);
static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr); static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr);
static void flushDMA(void);
/* ======================================================================= */ /* ======================================================================= */
@ -1392,6 +1390,41 @@ static int myPermit(unsigned gpio)
return 0; return 0;
} }
static void flushMemory(void)
{
static int val = 0;
void *dummy;
dummy = mmap(
0, (FLUSH_PAGES*PAGE_SIZE),
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_LOCKED,
-1, 0);
if (dummy == MAP_FAILED)
{
DBG(DBG_STARTUP, "mmap dummy failed (%m)");
}
else
{
memset(dummy, val++, (FLUSH_PAGES*PAGE_SIZE));
memset(dummy, val++, (FLUSH_PAGES*PAGE_SIZE));
munmap(dummy, FLUSH_PAGES*PAGE_SIZE);
}
}
/* ----------------------------------------------------------------------- */
static void waitForDMAstarted(void)
{
while (!DMAstarted)
{
if (piModel == 1) myGpioDelay(1000);
else flushMemory();
}
}
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
@ -4408,9 +4441,7 @@ static void * pthAlertThread(void *x)
/* don't start until DMA started */ /* don't start until DMA started */
while (!DMAstarted) myGpioDelay(1000); waitForDMAstarted();
myGpioDelay(20000); /* let DMA run for a while */
reportedLevel = gpioReg[GPLEV0]; reportedLevel = gpioReg[GPLEV0];
@ -4432,7 +4463,7 @@ static void * pthAlertThread(void *x)
{ {
if (stopped) if (stopped)
{ {
DBG(1, "****** GOING ******"); DBG(DBG_STARTUP, "****** GOING ******");
stopped = 0; stopped = 0;
} }
} }
@ -4440,16 +4471,21 @@ static void * pthAlertThread(void *x)
{ {
if (!stopped) if (!stopped)
{ {
DBG(1, "****** STOPPED ******"); DBG(DBG_STARTUP, "****** STOPPED ******");
stopped = 1; stopped = 1;
} }
dmaInitCbs();
flushDMA(); myGpioDelay(5000);
myGpioDelay(5000); /* let DMA run for a while */
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]); if (DMAstarted)
myGpioDelay(5000); /* let DMA run for a while */ {
oldSlot = 0; dmaInitCbs();
gpioStats.DMARestarts++; flushMemory();
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
myGpioDelay(5000); /* let DMA run for a while */
oldSlot = dmaCurrentSlot(dmaNowAtICB());
gpioStats.DMARestarts++;
}
} }
gpioStats.alertTicks++; gpioStats.alertTicks++;
@ -5206,10 +5242,7 @@ static void * pthFifoThread(void *x)
/* don't start until DMA started */ /* don't start until DMA started */
while (!DMAstarted) myGpioDelay(1000); waitForDMAstarted();
myGpioDelay(20000); /* let DMA run for a while */
while (1) while (1)
{ {
@ -5434,9 +5467,7 @@ static void * pthSocketThread(void *x)
/* don't start until DMA started */ /* don't start until DMA started */
while (!DMAstarted) myGpioDelay(1000); waitForDMAstarted();
myGpioDelay(20000); /* let DMA run for a while */
while ((fdC = while ((fdC =
accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c))) accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c)))
@ -5672,6 +5703,10 @@ static int initDMAblock(int pagemapFd, int block)
memset((void *)dmaBloc[block], 0, (PAGES_PER_BLOCK*PAGE_SIZE)); memset((void *)dmaBloc[block], 0, (PAGES_PER_BLOCK*PAGE_SIZE));
memset((void *)dmaBloc[block], 0xFF, (PAGES_PER_BLOCK*PAGE_SIZE));
memset((void *)dmaBloc[block], 0, (PAGES_PER_BLOCK*PAGE_SIZE));
pageNum = block * PAGES_PER_BLOCK; pageNum = block * PAGES_PER_BLOCK;
dmaVirt[pageNum] = mmap( dmaVirt[pageNum] = mmap(
@ -5705,32 +5740,6 @@ static int initDMAblock(int pagemapFd, int block)
return 0; return 0;
} }
#define FLUSH_PAGES 1000
static void flushDMA(void)
{
static int val = 0;
if (dummy != MAP_FAILED) munmap(dummy, FLUSH_PAGES*PAGE_SIZE);
dummy = MAP_FAILED;
dummy = mmap(
0, (FLUSH_PAGES*PAGE_SIZE),
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_LOCKED,
-1, 0);
if (dummy == MAP_FAILED)
{
DBG(0, "mmap dummy failed (%m)");
}
else
{
memset(dummy, val++, (FLUSH_PAGES*PAGE_SIZE));
}
}
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static int initDMAcbs(void) static int initDMAcbs(void)
@ -5985,7 +5994,6 @@ static void initClock(int mainClock)
clkSrc = CLK_CTL_SRC_PLLD; clkSrc = CLK_CTL_SRC_PLLD;
clkDivI = 50 * micros; /* 10 MHz - 1 MHz */ clkDivI = 50 * micros; /* 10 MHz - 1 MHz */
//if (!mainClock) clkDivI = 40 * micros;
clkBits = BITS; /* 10/BITS MHz - 1/BITS MHz */ clkBits = BITS; /* 10/BITS MHz - 1/BITS MHz */
clkDivF = 0; clkDivF = 0;
clkMash = 0; clkMash = 0;
@ -6467,81 +6475,6 @@ void rawDumpScript(unsigned script_id)
/* ======================================================================= */ /* ======================================================================= */
void startPi1DMA(void)
{
dmaInitCbs();
flushDMA();
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
gpioStats.DMAInits++;
}
void startPi2DMA(void)
{
int i, running, looped, firstCB, passedFirst;
for (i=0; i<150; i++)
{
dmaInitCbs();
flushDMA();
}
running = 0;
while (!running)
{
dmaInitCbs();
flushDMA();
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
gpioStats.DMAInits++;
myGpioDelay(20000);
i = dmaNowAtICB();
if (i)
{
firstCB = i;
passedFirst = 0;
looped = 0;
while (looped < 10)
{
dmaInitCbs();
flushDMA();
myGpioDelay(1000);
i = dmaNowAtICB();
if (i < firstCB)
{
if (i)
{
if (passedFirst)
{
looped++;
running = 1;
passedFirst = 0;
}
}
else
{
running = 0;
looped = 1000;
}
}
else passedFirst = 1;
}
}
}
}
int gpioInitialise(void) int gpioInitialise(void)
{ {
int i; int i;
@ -6647,10 +6580,15 @@ int gpioInitialise(void)
pthSocketRunning = 1; pthSocketRunning = 1;
} }
if (piModel == 1) myGpioDelay(10000);
startPi1DMA();
else dmaInitCbs();
startPi2DMA();
flushMemory();
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
myGpioDelay(20000);
DMAstarted = 1; DMAstarted = 1;
@ -6672,23 +6610,19 @@ void gpioTerminate(void)
{ {
/* reset DMA */ /* reset DMA */
DMAstarted = 0;
dmaIn[DMA_CS] = DMA_CHANNEL_RESET; dmaIn[DMA_CS] = DMA_CHANNEL_RESET;
dmaOut[DMA_CS] = DMA_CHANNEL_RESET; dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
/* reset PWM */
pwmReg[PWM_CTL] = 0;
libInitialised = 0; libInitialised = 0;
DMAstarted = 0;
if (gpioCfg.showStats) if (gpioCfg.showStats)
{ {
fprintf(stderr, fprintf(stderr,
"micros=%d dmaInitCbs=%d DMA inits=%d DMA restarts=%d\n", "micros=%d dmaInitCbs=%d DMA restarts=%d\n",
gpioCfg.clockMicros, gpioStats.dmaInitCbsCount, gpioCfg.clockMicros, gpioStats.dmaInitCbsCount,
gpioStats.DMAInits, gpioStats.DMARestarts); gpioStats.DMARestarts);
fprintf(stderr, "samples %u maxSamples %u maxEmit %u emitFrags %u\n", fprintf(stderr, "samples %u maxSamples %u maxEmit %u emitFrags %u\n",
gpioStats.numSamples, gpioStats.maxSamples, gpioStats.numSamples, gpioStats.maxSamples,

View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#define PIGPIO_VERSION 28 #define PIGPIO_VERSION 29
/*TEXT /*TEXT

4
x_pigs
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION=28 VERSION=29
GPIO=4 GPIO=4
@ -197,7 +197,7 @@ s=$(pigs m $GPIO w)
if [[ $s = "" ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi if [[ $s = "" ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi
s=$(pigs wvgo) s=$(pigs wvgo)
if [[ $s = 191 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi if [[ $s = 191 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi
sleep 0.1 sleep 0.2
s=$(pigs slr $GPIO 100) s=$(pigs slr $GPIO 100)
e="15 109 121 32 110 97 109 101 32 105 115 32 106 111 97 110" e="15 109 121 32 110 97 109 101 32 105 115 32 106 111 97 110"
if [[ $s = $e ]] if [[ $s = $e ]]

2
x_pipe
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION=28 VERSION=29
GPIO=4 GPIO=4