This commit is contained in:
joan 2015-02-11 23:01:56 +00:00
parent 9160f42474
commit b14e0a0572
7 changed files with 402 additions and 70 deletions

109
pigpio.3
View File

@ -2659,8 +2659,8 @@ handle: >=0, as returned by a call to \fBspiOpen\fP
.br
.br
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
PI_SPI_XFER_FAILED.
Returns the number of bytes transferred if OK, otherwise
PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
.IP "\fBint spiWrite(unsigned handle, char *buf, unsigned count)\fP"
.IP "" 4
@ -2684,8 +2684,8 @@ handle: >=0, as returned by a call to \fBspiOpen\fP
.br
.br
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
PI_SPI_XFER_FAILED.
Returns the number of bytes transferred if OK, otherwise
PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
.IP "\fBint spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)\fP"
.IP "" 4
@ -2712,8 +2712,8 @@ handle: >=0, as returned by a call to \fBspiOpen\fP
.br
.br
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
PI_SPI_XFER_FAILED.
Returns the number of bytes transferred if OK, otherwise
PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
.IP "\fBint serOpen(char *sertty, unsigned serBaud, unsigned serFlags)\fP"
.IP "" 4
@ -4309,6 +4309,75 @@ The default setting (0) is that both interfaces are enabled.
Or in PI_DISABLE_FIFO_IF to disable the pipe interface.
Or in PI_DISABLE_SOCK_IF to disable the socket interface.
.IP "\fBint gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count)\fP"
.IP "" 4
This function is available for user customisation.
.br
.br
It returns a single integer value.
.br
.br
.EX
arg1: >=0
.br
arg2: >=0
.br
argx: extra (byte) arguments
.br
count: number of extra arguments
.br
.EE
.br
.br
Returns >= 0 if OK, less than 0 indicates a user defined error.
.IP "\fBint gpioCustom2(unsigned arg1, char *argx, unsigned count, char *retBuf, unsigned retMax)\fP"
.IP "" 4
This function is available for user customisation.
.br
.br
It differs from gpioCustom1 in that it returns an array of bytes
rather than just an integer.
.br
.br
The returned value is an integer indicating the number of returned bytes.
.EX
arg1: >=0
.br
argx: extra (byte) arguments
.br
count: number of extra arguments
.br
retBuf: buffer for returned bytes
.br
retMax: maximum number of bytes to return
.br
.EE
.br
.br
Returns >= 0 if OK, less than 0 indicates a user defined error.
.br
.br
The number of returned bytes must be retMax or less.
.IP "\fBint gpioCfgInternals(unsigned cfgWhat, int cfgVal)\fP"
.IP "" 4
Used to tune internal settings.
@ -5643,7 +5712,7 @@ The hardware PWM dutycycle.
.br
.EX
#define PI_HW_PWM_RANGE 1000
#define PI_HW_PWM_RANGE 5000
.br
.EE
@ -5662,7 +5731,7 @@ The hardware PWM frequency.
.EX
#define PI_HW_PWM_MIN_FREQ 5
.br
#define PI_HW_PWM_MAX_FREQ 250000
#define PI_HW_PWM_MAX_FREQ 50000
.br
.EE
@ -6411,6 +6480,12 @@ A 16-bit word value.
#define PI_CMD_HP 86
.br
.br
#define PI_CMD_CF1 87
.br
#define PI_CMD_CF2 88
.br
.br
#define PI_CMD_NOIB 99
.br
@ -6617,9 +6692,9 @@ A 16-bit word value.
.br
#define PI_NOT_HPWM_GPIO -95 // gpio has no hardware PWM
.br
#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 5-250K
#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 5-50K
.br
#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-1000
#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-5000
.br
#define PI_BAD_HCLK_FREQ -98 // hardware clock frequency not 4689-25M
.br
@ -6631,6 +6706,20 @@ A 16-bit word value.
.br
#define PI_BAD_STOPBITS -102 // serial (half) stop bits not 2-8
.br
#define PI_MSG_TOOBIG -103 // socket/pipe message too big
.br
.br
#define PI_PIGIF_ERR_0 -2000
.br
#define PI_PIGIF_ERR_99 -2099
.br
.br
#define PI_CUSTOM_ERR_0 -3000
.br
#define PI_CUSTOM_ERR_999 -3999
.br
.br

265
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 27 */
/* pigpio version 28 */
#include <stdio.h>
#include <string.h>
@ -283,9 +283,15 @@ bit 0 READ_LAST_NOT_SET_ERROR
} \
while (0)
static volatile unsigned int piModel = 1;
static volatile unsigned int PI_PERI_BASE = 0x20000000;
static volatile unsigned int DMA_BUS_ADR = 0x40000000;
#define PI_PERI_PHYS 0x7E000000
static void *dummy = MAP_FAILED;
static volatile uint32_t piModel = 1;
static volatile uint32_t PI_PERI_BASE = 0x20000000;
static volatile uint32_t DMA_BUS_ADR = 0x40000000;
static volatile uint32_t DMA_BUS_CACHE = 0x00000000;
#define AUX_BASE (PI_PERI_BASE + 0x00215000)
#define CLK_BASE (PI_PERI_BASE + 0x00101000)
@ -894,6 +900,9 @@ typedef struct
uint32_t emitFrags;
uint32_t maxSamples;
uint32_t numSamples;
uint32_t DMARestarts;
uint32_t DMAInits;
uint32_t dmaInitCbsCount;
} gpioStats_t;
typedef struct
@ -1199,6 +1208,9 @@ static void intScriptBits(void);
static int gpioNotifyOpenInBand(int fd);
static void initHWClk
(int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH);
static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr);
static void flushDMA(void);
/* ======================================================================= */
@ -1327,6 +1339,8 @@ static void myOffPageSlot(int pos, int * page, int * slot)
static void myLvsPageSlot(int pos, int * page, int * slot)
{
// *page = pos%DMAI_PAGES;
// *slot = pos/DMAI_PAGES;
*page = pos/LVS_PER_IPAGE;
*slot = pos%LVS_PER_IPAGE;
}
@ -1335,6 +1349,8 @@ static void myLvsPageSlot(int pos, int * page, int * slot)
static void myTckPageSlot(int pos, int * page, int * slot)
{
// *page = pos%DMAI_PAGES;
// *slot = pos/DMAI_PAGES;
*page = pos/TCK_PER_IPAGE;
*slot = pos%TCK_PER_IPAGE;
}
@ -2175,14 +2191,14 @@ static int wave2Cbs(unsigned wave_mode)
p->info = NORMAL_DMA |
DMA_DEST_DREQ |
DMA_PERIPHERAL_MAPPING(2);
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
}
else
{
p->info = NORMAL_DMA |
DMA_DEST_DREQ |
DMA_PERIPHERAL_MAPPING(5);
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
}
p->src = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR;
@ -2203,7 +2219,7 @@ static int wave2Cbs(unsigned wave_mode)
p->info = NORMAL_DMA;
p->src = waveOOLPOadr(botOOL++) | DMA_BUS_ADR;
p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | 0x7e000000;
p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->length = 4;
p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
@ -2218,7 +2234,7 @@ static int wave2Cbs(unsigned wave_mode)
p->info = NORMAL_DMA;
p->src = waveOOLPOadr(botOOL++) | DMA_BUS_ADR;
p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | 0x7e000000;
p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->length = 4;
p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
@ -2230,7 +2246,7 @@ static int wave2Cbs(unsigned wave_mode)
p = rawWaveCBAdr(botCB++);
p->info = NORMAL_DMA;
p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | 0x7e000000;
p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->dst = waveOOLPOadr(--topOOL) | DMA_BUS_ADR;
p->length = 4;
p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
@ -2243,7 +2259,7 @@ static int wave2Cbs(unsigned wave_mode)
p = rawWaveCBAdr(botCB++);
p->info = NORMAL_DMA;
p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | 0x7e000000;
p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->dst = waveOOLPOadr(--topOOL) | DMA_BUS_ADR;
p->length = 4;
p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
@ -2330,7 +2346,7 @@ static int wave2Cbs(unsigned wave_mode)
DMA_DEST_DREQ |
DMA_PERIPHERAL_MAPPING(2);
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
}
else
{
@ -2338,7 +2354,7 @@ static int wave2Cbs(unsigned wave_mode)
DMA_DEST_DREQ |
DMA_PERIPHERAL_MAPPING(5);
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
}
p->src = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR;
@ -2607,7 +2623,8 @@ int i2cWriteQuick(unsigned handle, unsigned bit)
if (bit > 1)
SOFT_ERROR(PI_BAD_PARAM, "bad bit (%d)", bit);
err = my_smbus_access(i2cInfo[handle].fd, bit, 0, PI_I2C_SMBUS_QUICK, NULL);
err = my_smbus_access(
i2cInfo[handle].fd, bit, 0, PI_I2C_SMBUS_QUICK, NULL);
if (err < 0) return PI_I2C_WRITE_FAILED;
@ -3117,7 +3134,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
system("/sbin/modprobe i2c_dev");
system("/sbin/modprobe i2c_bcm2708");
usleep(100000);
myGpioDelay(100000);
if ((fd = open(dev, O_RDWR)) < 0)
{
@ -3274,7 +3291,7 @@ static void spiGoA(
auxReg[AUX_SPI0_CNTL0_REG] =
AUXSPI_CNTL0_ENABLE | AUXSPI_CNTL0_CLR_FIFOS;
usleep(10);
myGpioDelay(10);
auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE | spiDefaults;
@ -3438,15 +3455,12 @@ static void spiGo(
char *rxBuf,
unsigned count)
{
DBG(0, "spiGo");
if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
{
DBG(0, "spiGoA");
spiGoA(speed, flags, txBuf, rxBuf, count);
}
else
{
DBG(0, "spiGoS");
spiGoS(speed, flags, txBuf, rxBuf, count);
}
}
@ -4037,8 +4051,7 @@ static unsigned dmaNowAtICB(void)
endTick = systReg[SYST_CLO];
if (endTick != startTick)
gpioStats.cbTicks += (endTick - startTick);
else gpioStats.cbTicks ++;
gpioStats.cbTicks += (endTick - startTick);
gpioStats.cbCalls++;
@ -4179,7 +4192,7 @@ static void dmaGpioOnCb(int b, int pos)
p->info = NORMAL_DMA;
p->src = dmaGpioOnAdr(pos) | DMA_BUS_ADR;
p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | 0x7e000000;
p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->length = 4;
p->next = dmaCbAdr(b+1) | DMA_BUS_ADR;
}
@ -4193,7 +4206,7 @@ static void dmaTickCb(int b, int pos)
p = dmaCB2adr(b);
p->info = NORMAL_DMA;
p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | 0x7e000000;
p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->dst = dmaTickAdr(pos) | DMA_BUS_ADR;
p->length = 4;
p->next = dmaCbAdr(b+1) | DMA_BUS_ADR;
@ -4209,7 +4222,7 @@ static void dmaGpioOffCb(int b, int pos)
p->info = NORMAL_DMA;
p->src = dmaGpioOffAdr(pos) | DMA_BUS_ADR;
p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | 0x7e000000;
p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->length = 4;
p->next = dmaCbAdr(b+1) | DMA_BUS_ADR;
}
@ -4223,7 +4236,7 @@ static void dmaReadLevelsCb(int b, int pos)
p = dmaCB2adr(b);
p->info = NORMAL_DMA;
p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | 0x7e000000;
p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_PHYS;
p->dst = dmaReadLevelsAdr(pos) | DMA_BUS_ADR;
p->length = 4;
p->next = dmaCbAdr(b+1) | DMA_BUS_ADR;
@ -4240,12 +4253,12 @@ static void dmaDelayCb(int b)
if (gpioCfg.clockPeriph == PI_CLOCK_PCM)
{
p->info = NORMAL_DMA | TIMED_DMA(2);
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
}
else
{
p->info = NORMAL_DMA | TIMED_DMA(5);
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
}
p->src = dmaPwmDataAdr(b%DMAI_PAGES) | DMA_BUS_ADR;
@ -4265,6 +4278,8 @@ static void dmaInitCbs(void)
DBG(DBG_STARTUP, "");
gpioStats.dmaInitCbsCount++;
b = -1;
level = 0;
@ -4386,6 +4401,7 @@ static void * pthAlertThread(void *x)
int numSamples, d;
int b, n, v;
int err;
int stopped;
char fifo[32];
req.tv_sec = 0;
@ -4407,8 +4423,35 @@ static void * pthAlertThread(void *x)
cycle = (oldSlot/PULSE_PER_CYCLE);
pulse = (oldSlot%PULSE_PER_CYCLE);
stopped = 0;
while (1)
{
if (dmaIn[DMA_CONBLK_AD])
{
if (stopped)
{
DBG(1, "****** GOING ******");
stopped = 0;
}
}
else
{
if (!stopped)
{
DBG(1, "****** STOPPED ******");
stopped = 1;
}
dmaInitCbs();
flushDMA();
myGpioDelay(5000); /* let DMA run for a while */
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
myGpioDelay(5000); /* let DMA run for a while */
oldSlot = 0;
gpioStats.DMARestarts++;
}
gpioStats.alertTicks++;
req.tv_nsec = 850000;
@ -5161,6 +5204,13 @@ static void * pthFifoThread(void *x)
flags = fcntl(fileno(outFifo), F_GETFL, 0);
fcntl(fileno(outFifo), F_SETFL, flags | O_NONBLOCK);
/* don't start until DMA started */
while (!DMAstarted) myGpioDelay(1000);
myGpioDelay(20000); /* let DMA run for a while */
while (1)
{
if (fgets(buf, sizeof(buf), inpFifo) == NULL)
@ -5382,6 +5432,12 @@ static void * pthSocketThread(void *x)
c = sizeof(struct sockaddr_in);
/* don't start until DMA started */
while (!DMAstarted) myGpioDelay(1000);
myGpioDelay(20000); /* let DMA run for a while */
while ((fdC =
accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c)))
{
@ -5484,7 +5540,7 @@ static int initZaps
PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED|MAP_LOCKED|MAP_NORESERVE,
fdMem,
(uint32_t)dmaP[n] | 0x40000000
(uint32_t)dmaP[n] | DMA_BUS_CACHE
);
pageAdr2 += PAGE_SIZE;
@ -5649,6 +5705,31 @@ static int initDMAblock(int pagemapFd, int block)
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));
}
}
/* ----------------------------------------------------------------------- */
@ -5740,8 +5821,6 @@ static int initDMAcbs(void)
for (i=0; i<DMAI_PAGES; i++)
DBG(DBG_STARTUP, "dmaIPhys[%d]=%08X", i, (uint32_t)dmaIPhys[i]);
dmaInitCbs();
if (gpioCfg.dbgLevel >= DBG_DMACBS)
{
fprintf(stderr, "*** INPUT DMA CONTROL BLOCKS ***\n");
@ -5945,8 +6024,6 @@ static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr)
DMA_PANIC_PRIORITY(8) |
DMA_PRIORITY(8) |
DMA_ACTIVATE;
DMAstarted = 1;
}
/* ----------------------------------------------------------------------- */
@ -6390,6 +6467,81 @@ 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 i;
@ -6495,11 +6647,17 @@ int gpioInitialise(void)
pthSocketRunning = 1;
}
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
if (piModel == 1)
startPi1DMA();
else
startPi2DMA();
DMAstarted = 1;
return PIGPIO_VERSION;
}
/* ----------------------------------------------------------------------- */
void gpioTerminate(void)
@ -6527,7 +6685,10 @@ void gpioTerminate(void)
if (gpioCfg.showStats)
{
fprintf(stderr, "micros=%d\n", gpioCfg.clockMicros);
fprintf(stderr,
"micros=%d dmaInitCbs=%d DMA inits=%d DMA restarts=%d\n",
gpioCfg.clockMicros, gpioStats.dmaInitCbsCount,
gpioStats.DMAInits, gpioStats.DMARestarts);
fprintf(stderr, "samples %u maxSamples %u maxEmit %u emitFrags %u\n",
gpioStats.numSamples, gpioStats.maxSamples,
@ -8914,41 +9075,53 @@ unsigned gpioHardwareRevision(void)
FILE * filp;
char buf[512];
char term;
int chars=4; /* number of chars in revision string */
DBG(DBG_USER, "");
if (rev) return rev;
piModel = 0;
filp = fopen ("/proc/cpuinfo", "r");
if (filp != NULL)
{
while (fgets(buf, sizeof(buf), filp) != NULL)
{
if (!strncmp("model name", buf, 10))
if (piModel == 0)
{
if (strstr (buf, "ARMv6") != NULL)
if (!strncasecmp("model name", buf, 10))
{
piModel = 1;
PI_PERI_BASE = 0x20000000;
DMA_BUS_ADR = 0x40000000;
}
else if (strstr (buf, "ARMv7") != NULL)
{
piModel = 2;
PI_PERI_BASE = 0x3F000000;
DMA_BUS_ADR = 0xC0000000;
if (strstr (buf, "ARMv6") != NULL)
{
piModel = 1;
chars = 4;
PI_PERI_BASE = 0x20000000;
DMA_BUS_ADR = 0x40000000;
DMA_BUS_CACHE = 0x40000000;
}
else if (strstr (buf, "ARMv7") != NULL)
{
piModel = 2;
chars = 6;
PI_PERI_BASE = 0x3F000000;
DMA_BUS_ADR = 0xC0000000;
DMA_BUS_CACHE = 0x00000000;
}
}
}
if (!strncmp("Revision", buf, 8))
if (!strncasecmp("revision", buf, 8))
{
if (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2)
if (sscanf(buf+strlen(buf)-(chars+1),
"%x%c", &rev, &term) == 2)
{
if (term != '\n') rev = 0;
}
}
}
fclose(filp);
}
return rev;

View File

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

View File

@ -1207,9 +1207,9 @@ daemon is started (option -t).
.EX
gpio: see descripton
.br
PWMfreq: 0 (off) or 5-250K
PWMfreq: 0 (off) or 5-50K
.br
PWMduty: 0 (off) to 1000 (fully on).
PWMduty: 0 (off) to 5000 (fully on).
.br
.EE
@ -2671,8 +2671,8 @@ handle: >=0, as returned by a call to \fBspi_open\fP.
.br
.br
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
PI_SPI_XFER_FAILED.
Returns the number of bytes transferred if OK, otherwise
PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
.IP "\fBint spi_write(unsigned handle, char *buf, unsigned count)\fP"
.IP "" 4
@ -2696,8 +2696,8 @@ handle: >=0, as returned by a call to \fBspi_open\fP.
.br
.br
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
PI_SPI_XFER_FAILED.
Returns the number of bytes transferred if OK, otherwise
PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
.IP "\fBint spi_xfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)\fP"
.IP "" 4
@ -2724,8 +2724,8 @@ handle: >=0, as returned by a call to \fBspi_open\fP.
.br
.br
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
PI_SPI_XFER_FAILED.
Returns the number of bytes transferred if OK, otherwise
PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
.IP "\fBint serial_open(char *ser_tty, unsigned ser_baud, unsigned ser_flags)\fP"
.IP "" 4
@ -2887,6 +2887,75 @@ handle: >=0, as returned by a call to \fBserial_open\fP.
Returns the number of bytes of data available (>=0) if OK,
otherwise PI_BAD_HANDLE.
.IP "\fBint custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned count)\fP"
.IP "" 4
This function is available for user customisation.
.br
.br
It returns a single integer value.
.br
.br
.EX
arg1: >=0
.br
arg2: >=0
.br
argx: extra (byte) arguments
.br
count: number of extra arguments
.br
.EE
.br
.br
Returns >= 0 if OK, less than 0 indicates a user defined error.
.IP "\fBint custom_2(unsigned arg1, char *argx, unsigned count, char *retBuf, unsigned retMax)\fP"
.IP "" 4
This function is available for user customisation.
.br
.br
It differs from custom_1 in that it returns an array of bytes
rather than just an integer.
.br
.br
The return value is an integer indicating the number of returned bytes.
.EX
arg1: >=0
.br
argx: extra (byte) arguments
.br
count: number of extra arguments
.br
retBuf: buffer for returned data
.br
retMax: maximum number of bytes to return
.br
.EE
.br
.br
Returns >= 0 if OK, less than 0 indicates a user defined error.
.br
.br
Note, the number of returned bytes will be retMax or less.
.IP "\fBint callback(unsigned user_gpio, unsigned edge, CBFunc_t f)\fP"
.IP "" 4
This function initialises a new callback.

6
pigs.1
View File

@ -534,11 +534,11 @@ will be returned.
.br
.EX
$ pigs hp 18 100 900
$ pigs hp 18 100 4000 # 80% dutycycle
.br
.br
$ pigs hp 19 100 100
$ pigs hp 19 100 1000 # 20% dutycycle
.br
.br
@ -546,7 +546,7 @@ $ pigs hp 19 1 100
.br
-96
.br
ERROR: hardware PWM frequency not 5-250K
ERROR: hardware PWM frequency not 5-50K
.br
.EE

2
x_pigs
View File

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

3
x_pipe
View File

@ -1,6 +1,6 @@
#!/bin/bash
VERSION=27
VERSION=28
GPIO=4
@ -159,6 +159,7 @@ read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PROCS($p) ok"; else echo "PROCS($p) fail ($s)"; fi
echo "procd $p" >/dev/pigpio
sleep 0.1
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PROCD($p) ok"; else echo "PROCD($p) fail ($s)"; fi