mirror of https://github.com/joan2937/pigpio
V29
This commit is contained in:
parent
19f0245957
commit
9aeb30d0dc
210
pigpio.c
210
pigpio.c
|
@ -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,
|
||||||
|
|
2
pigpio.h
2
pigpio.h
|
@ -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
4
x_pigs
|
@ -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 ]]
|
||||||
|
|
Loading…
Reference in New Issue