This commit is contained in:
joan 2013-12-12 10:32:49 +00:00
parent 56b5f62885
commit 3e7e75ea29
10 changed files with 2002 additions and 202 deletions

View File

@ -5,7 +5,9 @@ SIZE = size
CFLAGS = -O3 -Wall
all: libpigpio.a checklib demolib pig2vcd pigpiod pigs
ALL = libpigpio.a checklib demolib pig2vcd pigpiod pigs
all: $(ALL)
checklib: checklib.o libpigpio.a
$(CC) -o checklib checklib.c -L. -lpigpio -lpthread -lrt
@ -19,31 +21,29 @@ pig2vcd: pig2vcd.o
pigpiod: pigpiod.o libpigpio.a
$(CC) -o pigpiod pigpiod.c -L. -lpigpio -lpthread -lrt
pigs: pigs.o command.o
pigs: command.o
$(CC) -o pigs pigs.c command.c
.c.o:
$(CC) -c $(CFLAGS) $<
clean:
rm -f *.o *.i *.s *~ libpigpio.a checklib demolib pigpiod pigs pig2vcd
rm -f *.o *.i *.s *~ $(ALL)
install: $(LIB)
sudo install -m 0755 -d /usr/local/bin
sudo install -m 0755 -d /usr/local/include
sudo install -m 0644 pigpio.h /usr/local/include
sudo install -m 0755 -d /usr/local/lib
sudo install -m 0644 libpigpio.a /usr/local/lib
sudo install -m 0755 -d /usr/local/bin
sudo install -m 0755 pig2vcd /usr/local/bin
sudo install -m 0755 pigpiod /usr/local/bin
sudo install -m 0755 pigs /usr/local/bin
sudo install -m 0644 pigpio.h /usr/local/include
sudo install -m 0644 libpigpio.a /usr/local/lib
sudo python setup.py install
uninstall:
sudo rm -f /usr/local/include/pigpio.h
sudo rm -f /usr/local/lib/libpigpio.a
sudo rm -f /usr/local/bin/pig2vcd
sudo rm -f /usr/local/bin/pigpiod
sudo rm -f /usr/local/bin/pigs
sudo rm -f /usr/local/include/pigpio.h
sudo rm -f /usr/local/lib/libpigpio.a
LIB = libpigpio.a
OBJ = pigpio.o command.o
@ -53,11 +53,13 @@ $(LIB): $(OBJ)
$(RANLIB) $(LIB)
$(SIZE) $(LIB)
# generated using gcc -M *.c
# DO NOT DELETE
checklib.o: checklib.c pigpio.h
command.o: command.c pigpio.h command.h
demolib.o: demolib.c pigpio.h
pig2vcd.o: pig2vcd.c pigpio.h
pigpio.o: pigpio.c pigpio.h command.h
pigpiod.o: pigpiod.c pigpio.h command.h
pigs.o: pigs.c pigpio.h command.h
checklib.o: checklib.c pigpio.h
demolib.o: demolib.c pigpio.h
pig2vcd: pigpio.h
pigpiod: pigpiod.c pigpio.h
pigs: pigs.c command.c pigpio.h command.h

28
README
View File

@ -15,6 +15,7 @@ This will install:
the daemon (pigpiod) in /usr/local/bin
the socket interface (pigs) in /usr/local/bin
the utility pig2vcd in /usr/local/bin
the Python module pigpio.py
TEST
@ -22,8 +23,8 @@ To test the library do
sudo ./checklib
checklib.c, demolib.c, pig2vcd.c, pigpiod.c, and pigs.c show examples
of interfacing with the library.
checklib.c, demolib.c, pig2vcd.c, pigpiod.c, pigs.c, and pigpio.py
show examples of interfacing with the library.
DAEMON
@ -59,9 +60,30 @@ cat /dev/pigerr &
echo "help" >/dev/pigpio
PYTHON INTERFACE
If the pigpiod daemon is running you can test the Python
interface by entering the following commands.
python
import pigpio
pigpio.start()
print(pigpio.get_current_tick())
print(hex(pigpio.read_bank_1()))
pigpio.stop()
help(pigpio)
quit()
STOP DAEMON
To stop the daemon
To stop the pigpiod daemon
sudo killall pigpiod

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 4+
This version is for pigpio version 7+
*/
#include <stdio.h>
@ -141,7 +141,7 @@ static errInfo_t errInfo[]=
{PI_BAD_CLK_SOURCE , "clock source not 0-1"},
{PI_BAD_CLK_MICROS , "clock micros not 1, 2, 4, 5, 8, or 10"},
{PI_BAD_BUF_MILLIS , "buf millis not 100-10000"},
{PI_BAD_DUTY_RANGE , "dutycycle range not 25-40000"},
{PI_BAD_DUTYRANGE , "dutycycle range not 25-40000"},
{PI_BAD_SIGNUM , "signum not 0-63"},
{PI_BAD_PATHNAME , "can't open pathname"},
{PI_NO_HANDLE , "no handle available"},
@ -159,7 +159,8 @@ static errInfo_t errInfo[]=
{PI_TOO_MANY_PULSES , "waveform has too many pulses"},
{PI_TOO_MANY_CHARS , "waveform has too many chars"},
{PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"},
{PI_NOT_PERMITTED , "no permission to update gpio"},
{PI_SOME_PERMITTED , "no permission to update one or more gpios"},
};
static char * fmtMdeStr="RW540123";
@ -289,4 +290,3 @@ char * cmdErrStr(int error)
}
return "unknown error";
}

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 3+
This version is for pigpio version 7+
*/
#ifndef COMMAND_H
@ -39,10 +39,10 @@ This version is for pigpio version 3+
typedef struct
{
int cmd;
char * name;
int vt;
int rv;
int cmd; /* command number */
char * name; /* command name */
int vt; /* command verification type */
int rv; /* command return value type */
} cmdInfo_t;
extern cmdInfo_t cmdInfo[];

251
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 6 */
/* pigpio version 7 */
#include <stdio.h>
#include <string.h>
@ -229,6 +229,13 @@ bit 0 READ_LAST_NOT_SET_ERROR
} \
while (0)
#define PERM_ERROR(format, arg...) \
do \
{ \
fprintf(stderr, "%s " format "\n", myTimeStamp(), ## arg); \
} \
while (0)
#define TIMER_ADD(a, b, result) \
do \
{ \
@ -519,8 +526,6 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define PI_WFRX_SERIAL 1
#define PI_WF_MICROS 2
#define PI_WAVE_MAX_PULSES 3000
#define DATUMS 2000
#define DEFAULT_PWM_IDX 5
@ -704,12 +709,16 @@ static volatile gpioCfg_t gpioCfg =
static volatile gpioStats_t gpioStats;
static int gpioMaskSet = 0;
/* initialise every gpioInitialise */
static struct timespec libStarted;
/* initialse if not libInitialised */
static uint64_t gpioMask;
static gpioPulse_t wf[3][PI_WAVE_MAX_PULSES];
static int wfc[3]={0, 0, 0};
@ -732,7 +741,6 @@ static volatile uint32_t notifyBits = 0;
static volatile int DMAstarted = 0;
static int libInitialised = 0;
static unsigned hardwareRevision = 0;
static int pthAlertRunning = 0;
static int pthFifoRunning = 0;
@ -947,6 +955,7 @@ static uint32_t myGetTick(int pos)
static void myDoCommand(cmdCmd_t * cmd)
{
int p1, p2, res;
uint32_t mask;
p1 = cmd->p1;
p2 = cmd->p2;
@ -956,7 +965,12 @@ static void myDoCommand(cmdCmd_t * cmd)
switch (cmd->cmd)
{
case PI_CMD_MODES:
res = gpioSetMode(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetMode(p1, p2);
else
{
PERM_ERROR("gpioSetMode: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_MODEG:
@ -964,7 +978,12 @@ static void myDoCommand(cmdCmd_t * cmd)
break;
case PI_CMD_PUD:
res = gpioSetPullUpDown(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPullUpDown(p1, p2);
else
{
PERM_ERROR("gpioSetPullUpDown: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_READ:
@ -972,23 +991,48 @@ static void myDoCommand(cmdCmd_t * cmd)
break;
case PI_CMD_WRITE:
res = gpioWrite(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioWrite(p1, p2);
else
{
PERM_ERROR("gpioWrite: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PWM:
res = gpioPWM(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioPWM(p1, p2);
else
{
PERM_ERROR("gpioPWM: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PRS:
res = gpioSetPWMrange(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMrange(p1, p2);
else
{
PERM_ERROR("gpioSetPWMrange: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_PFS:
res = gpioSetPWMfrequency(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioSetPWMfrequency(p1, p2);
else
{
PERM_ERROR("gpioSetPWMfrequency: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_SERVO:
res = gpioServo(p1, p2);
if (gpioMask & (uint64_t)(1<<p1)) res = gpioServo(p1, p2);
else
{
PERM_ERROR("gpioServo: gpio %d, no permission to update", p1);
res = PI_NOT_PERMITTED;
}
break;
case PI_CMD_WDOG:
@ -1004,19 +1048,55 @@ static void myDoCommand(cmdCmd_t * cmd)
break;
case PI_CMD_BC1:
gpioWrite_Bits_0_31_Clear(p1);
mask = gpioMask;
res = gpioWrite_Bits_0_31_Clear(p1&mask);
if ((mask | p1) != mask)
{
PERM_ERROR("gpioWrite_Bits_0_31_Clear: bad levels %08X (permissions %08X)",
p1, mask);
res = PI_SOME_PERMITTED;
}
break;
case PI_CMD_BC2:
gpioWrite_Bits_32_53_Clear(p1);
mask = gpioMask>>32;
res = gpioWrite_Bits_32_53_Clear(p1&mask);
if ((mask | p1) != mask)
{
PERM_ERROR("gpioWrite_Bits_32_53_Clear: bad levels %08X (permissions %08X)",
p1, mask);
res = PI_SOME_PERMITTED;
}
break;
case PI_CMD_BS1:
gpioWrite_Bits_0_31_Set(p1);
mask = gpioMask;
res = gpioWrite_Bits_0_31_Set(p1&mask);
if ((mask | p1) != mask)
{
PERM_ERROR("gpioWrite_Bits_0_31_Set: bad levels %08X (permissions %08X)",
p1, mask);
res = PI_SOME_PERMITTED;
}
break;
case PI_CMD_BS2:
gpioWrite_Bits_32_53_Set(p1);
mask = gpioMask>>32;
res = gpioWrite_Bits_32_53_Set(p1&mask);
if ((mask | p1) != mask)
{
PERM_ERROR("gpioWrite_Bits_32_53_Set: bad levels %08X (permissions %08X)",
p1, mask);
res = PI_SOME_PERMITTED;
}
break;
case PI_CMD_TICK:
@ -1274,7 +1354,7 @@ static void waveCbOPrint(int pos)
p = waveCbVOadr(pos);
fprintf(stderr, "i=%lx s=%lx d=%lx len=%lx s=%lx nxt=%lx",
fprintf(stderr, "i=%lx s=%lx d=%lx len=%lx s=%lx nxt=%lx\n",
p->info, p->src, p->dst, p->length, p->stride, p->next);
}
@ -1669,7 +1749,7 @@ static void dmaCbPrint(int pos)
p = dmaCB2adr(pos);
fprintf(stderr, "i=%lx s=%lx d=%lx len=%lx s=%lx nxt=%lx",
fprintf(stderr, "i=%lx s=%lx d=%lx len=%lx s=%lx nxt=%lx\n",
p->info, p->src, p->dst, p->length, p->stride, p->next);
}
@ -1962,13 +2042,15 @@ static void sigHandler(int signum)
DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel);
}
else if (signum == SIGPIPE)
{
DBG(DBG_USER, "SIGPIPE received");
}
else
{
/* close library safely and exit */
/* exit */
DBG(DBG_USER, "Unhandled signal %d, terminating\n", signum);
gpioTerminate();
DBG(DBG_MIN_LEVEL, "Unhandled signal %d, terminating\n", signum);
exit(-1);
}
@ -1976,11 +2058,9 @@ static void sigHandler(int signum)
}
else
{
/* close library safely and exit */
/* exit */
DBG(DBG_USER, "Unhandled signal %d, terminating\n", signum);
gpioTerminate();
DBG(DBG_MIN_LEVEL, "Unhandled signal %d, terminating\n", signum);
exit(-1);
}
@ -2424,7 +2504,6 @@ static void * pthTimerTick(void *x)
return 0;
}
/* ----------------------------------------------------------------------- */
@ -2465,6 +2544,7 @@ static void * pthFifoThread(void *x)
break;
case 1:
fprintf(outFifo, "%d\n", cmd.res);
break;
case 2:
@ -2860,7 +2940,7 @@ static int initDMAcbs(void)
/* allocate memory for pointers to virtual and physical pages */
dmaBloc = mmap(
0, (bufferBlocks+1)*sizeof(dmaPage_t *),
0, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
-1, 0);
@ -2869,7 +2949,7 @@ static int initDMAcbs(void)
SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
dmaVirt = mmap(
0, PAGES_PER_BLOCK*(bufferBlocks+1)*sizeof(dmaPage_t *),
0, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
-1, 0);
@ -2878,7 +2958,7 @@ static int initDMAcbs(void)
SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
dmaPhys = mmap(
0, PAGES_PER_BLOCK*(bufferBlocks+1)*sizeof(dmaPage_t *),
0, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
-1, 0);
@ -2901,7 +2981,7 @@ static int initDMAcbs(void)
if (pagemapFd < 0)
SOFT_ERROR(PI_INIT_FAILED, "open pagemap failed(%m)");
for (i=0; i<(bufferBlocks+1); i++) initDMAblock(pagemapFd, i);
for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++) initDMAblock(pagemapFd, i);
close(pagemapFd);
@ -2918,7 +2998,10 @@ static int initDMAcbs(void)
dmaInitCbs();
if (gpioCfg.dbgLevel >= DBG_DMACBS)
{
fprintf(stderr, "*** INPUT DMA CONTROL BLOCKS ***\n");
for (i=0; i<NUM_CBS; i++) dmaCbPrint(i);
}
return 0;
}
@ -3132,7 +3215,6 @@ static void initClearGlobals(void)
libInitialised = 0;
DMAstarted = 0;
hardwareRevision = 0;
pthAlertRunning = 0;
pthFifoRunning = 0;
@ -3224,37 +3306,6 @@ static void initClearGlobals(void)
/* ----------------------------------------------------------------------- */
static unsigned initHardwareRevision(void)
{
FILE * filp;
unsigned rev;
char buf[512];
char term;
rev = 0;
filp = fopen ("/proc/cpuinfo", "r");
if (filp != NULL)
{
while (fgets(buf, sizeof(buf), filp) != NULL)
{
if (!strncasecmp("revision\t", buf, 9))
{
if (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2)
{
if (term == '\n') break;
rev = 0;
}
}
}
fclose(filp);
}
return rev;
}
/* ----------------------------------------------------------------------- */
static void initReleaseResources(void)
{
int i;
@ -3299,7 +3350,7 @@ static void initReleaseResources(void)
/* release mmap'd memory */
if (clkReg != MAP_FAILED) munmap((void *)clkReg, CLK_LEN);
if (dmaReg != MAP_FAILED) munmap((void *)dmaReg, DMA_LEN);
if (dmaReg != MAP_FAILED) munmap((void *)dmaReg, DMA_LEN);
if (gpioReg != MAP_FAILED) munmap((void *)gpioReg, GPIO_LEN);
if (pcmReg != MAP_FAILED) munmap((void *)pcmReg, PCM_LEN);
if (pwmReg != MAP_FAILED) munmap((void *)pwmReg, PWM_LEN);
@ -3314,36 +3365,36 @@ static void initReleaseResources(void)
if (dmaVirt != MAP_FAILED)
{
for (i=0; i<PAGES_PER_BLOCK*(bufferBlocks+1); i++)
for (i=0; i<PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS); i++)
{
munmap(dmaVirt[i], PAGE_SIZE);
}
munmap(dmaVirt, PAGES_PER_BLOCK*(bufferBlocks+1)*sizeof(dmaPage_t *));
munmap(dmaVirt, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
}
dmaVirt = MAP_FAILED;
if (dmaPhys != MAP_FAILED)
{
for (i=0; i<PAGES_PER_BLOCK*(bufferBlocks+1); i++)
for (i=0; i<PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS); i++)
{
munmap(dmaPhys[i], PAGE_SIZE);
}
munmap(dmaPhys, PAGES_PER_BLOCK*(bufferBlocks+1)*sizeof(dmaPage_t *));
munmap(dmaPhys, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
}
dmaPhys = MAP_FAILED;
if (dmaBloc != MAP_FAILED)
{
for (i=0; i<(bufferBlocks+1); i++)
for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++)
{
munmap(dmaBloc[i], PAGES_PER_BLOCK*PAGE_SIZE);
}
munmap(dmaBloc, (bufferBlocks+1)*sizeof(dmaPage_t *));
munmap(dmaBloc, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
}
dmaBloc = MAP_FAILED;
@ -3403,6 +3454,17 @@ int gpioInitialise(void)
if (fdLock < 0)
SOFT_ERROR(PI_INIT_FAILED, "Can't lock %s", PI_LOCKFILE);
if (!gpioMaskSet)
{
i = gpioHardwareRevision();
if (i == 0) gpioMask = PI_DEFAULT_UPDATE_MASK_R0;
else if (i < 4) gpioMask = PI_DEFAULT_UPDATE_MASK_R1;
else gpioMask = PI_DEFAULT_UPDATE_MASK_R2;
gpioMaskSet = 1;
}
sigSetHandler();
if (initPeripherals() < 0) return PI_INIT_FAILED;
@ -3450,8 +3512,6 @@ int gpioInitialise(void)
pthSocketRunning = 1;
}
hardwareRevision = initHardwareRevision();
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
return PIGPIO_VERSION;
@ -3465,6 +3525,7 @@ void gpioTerminate(void)
DBG(DBG_USER, "");
gpioMaskSet = 0;
if (libInitialised)
{
@ -3716,7 +3777,7 @@ int gpioSetPWMrange(unsigned gpio, unsigned range)
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
if ((range < PI_MIN_DUTYCYCLE_RANGE) || (range > PI_MAX_DUTYCYCLE_RANGE))
SOFT_ERROR(PI_BAD_DUTY_RANGE, "gpio %d, bad range (%d)", gpio, range);
SOFT_ERROR(PI_BAD_DUTYRANGE, "gpio %d, bad range (%d)", gpio, range);
oldWidth = gpioInfo[gpio].width;
@ -4247,7 +4308,10 @@ int gpioWaveTxStart(unsigned mode)
cb = wave2Cbs(mode);
if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
{
fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
for (i=0; i<cb; i++) waveCbOPrint(i);
}
initDMAgo((uint32_t *)dmaOut, (uint32_t)dmaOPhys[0]);
@ -4899,11 +4963,34 @@ uint32_t gpioTick(void)
unsigned gpioHardwareRevision(void)
{
static unsigned rev = 0;
FILE * filp;
char buf[512];
char term;
DBG(DBG_USER, "");
CHECK_INITED;
if (rev) return rev;
return hardwareRevision;
filp = fopen ("/proc/cpuinfo", "r");
if (filp != NULL)
{
while (fgets(buf, sizeof(buf), filp) != NULL)
{
if (!strncasecmp("revision\t", buf, 9))
{
if (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2)
{
if (term == '\n') break;
rev = 0;
}
}
}
fclose(filp);
}
return rev;
}
@ -4994,6 +5081,22 @@ int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel)
}
/*-------------------------------------------------------------------------*/
int gpioCfgPermissions(uint64_t updateMask)
{
DBG(DBG_USER, "gpio update mask=%llX", updateMask);
CHECK_NOT_INITED;
gpioMask = updateMask;
gpioMaskSet = 1;
return 0;
}
/* ----------------------------------------------------------------------- */
int gpioCfgInterfaces(unsigned ifFlags)

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 6
This version is for pigpio version 7
*/
#ifndef PIGPIO_H
@ -82,7 +82,7 @@ This version is for pigpio version 6
#include <stdint.h>
#define PIGPIO_VERSION 6
#define PIGPIO_VERSION 7
/*-------------------------------------------------------------------------*/
@ -175,7 +175,9 @@ gpioHardwareRevision Get hardware version.
gpioCfgBufferSize Configure the gpio sample buffer size.
gpioCfgClock Configure the gpio sample rate.
gpioCfgDMAchannel Configure the DMA channel.
gpioCfgDMAchannel Configure the DMA channel (DEPRECATED).
gpioCfgDMAchannels Configure the DMA channels.
gpioCfgPermissions Configure the gpio access permissions.
gpioCfgInterfaces Configure user interfaces.
gpioCfgSocketPort Configure socket port.
@ -482,7 +484,7 @@ int gpioSetPWMrange(unsigned user_gpio,
to gpioPWM will use a dutycycle between 0 (off) and range (fully on).
Returns the real range for the given gpio's frequency if OK,
otherwise PI_BAD_USER_GPIO or PI_BAD_DUTY_RANGE.
otherwise PI_BAD_USER_GPIO or PI_BAD_DUTYRANGE.
EXAMPLE:
...
@ -892,9 +894,12 @@ int gpioWaveAddSerial(unsigned user_gpio,
the same waveform.
*/
#define PI_WAVE_BLOCKS 3
#define PI_WAVE_MAX_PULSES (PI_WAVE_BLOCKS * 3000)
#define PI_WAVE_MAX_CHARS (PI_WAVE_BLOCKS * 256)
#define PI_WAVE_MIN_BAUD 100
#define PI_WAVE_MAX_BAUD 250000
#define PI_WAVE_MAX_CHARS 256
@ -1601,7 +1606,7 @@ int gpioCfgClock(unsigned micros,
/*-------------------------------------------------------------------------*/
int gpioCfgDMAchannel(unsigned channel);
int gpioCfgDMAchannel(unsigned channel); /* DEPRECATED */
/*-------------------------------------------------------------------------*/
/* Configures pigpio to use the specified DMA channel.
@ -1622,7 +1627,7 @@ int gpioCfgDMAchannels(unsigned primaryChannel,
/* Configures pigpio to use the specified DMA channels.
The default setting is to use channel 14 for the primary channel and
channel 6 for the secondary channel.
channel 5 for the secondary channel.
*/
#define PI_MAX_PRIMARY_CHANNEL 14
@ -1630,6 +1635,18 @@ int gpioCfgDMAchannels(unsigned primaryChannel,
/*-------------------------------------------------------------------------*/
int gpioCfgPermissions(uint64_t updateMask);
/*-------------------------------------------------------------------------*/
/* Configures pigpio to only allow updates (writes or mode changes) for the
gpios specified by the mask.
The default setting is to allow updates to gpios 0-31, i.e. an update mask
of 0x00000000FFFFFFFF.
*/
/*-------------------------------------------------------------------------*/
int gpioCfgSocketPort(unsigned port);
/*-------------------------------------------------------------------------*/
@ -1746,7 +1763,8 @@ after this command is issued.
#define PI_BAD_CLK_SOURCE -18 /* clock source not 0-1 */
#define PI_BAD_CLK_MICROS -19 /* clock micros not 1, 2, 4, 5, 8, or 10 */
#define PI_BAD_BUF_MILLIS -20 /* buf millis not 100-10000 */
#define PI_BAD_DUTY_RANGE -21 /* dutycycle range not 25-40000 */
#define PI_BAD_DUTYRANGE -21 /* dutycycle range not 25-40000 */
#define PI_BAD_DUTY_RANGE -21 /* DEPRECATED (use PI_BAD_DUTYRANGE) */
#define PI_BAD_SIGNUM -22 /* signum not 0-63 */
#define PI_BAD_PATHNAME -23 /* can't open pathname */
#define PI_NO_HANDLE -24 /* no handle available */
@ -1767,6 +1785,8 @@ after this command is issued.
#define PI_NOT_SERIAL_GPIO -38 /* no serial read in progress on gpio */
#define PI_BAD_SERIAL_STRUC -39 /* bad null serial structure parameter */
#define PI_BAD_SERIAL_BUF -40 /* bad null serial buf parameter */
#define PI_NOT_PERMITTED -41 /* gpio operation not permitted */
#define PI_SOME_PERMITTED -42 /* one or more gpios not permitted */
/*-------------------------------------------------------------------------*/
@ -1778,8 +1798,12 @@ after this command is issued.
#define PI_DEFAULT_IF_FLAGS 0
#define PI_DEFAULT_DMA_CHANNEL 14
#define PI_DEFAULT_DMA_PRIMARY_CHANNEL 14
#define PI_DEFAULT_DMA_SECONDARY_CHANNEL 6
#define PI_DEFAULT_DMA_SECONDARY_CHANNEL 5
#define PI_DEFAULT_SOCKET_PORT 8888
#define PI_DEFAULT_SOCKET_PORT_STR "8888"
#define PI_DEFAULT_SOCKET_ADDR_STR "127.0.0.1"
#define PI_DEFAULT_UPDATE_MASK_R0 0xFBE6CF9F
#define PI_DEFAULT_UPDATE_MASK_R1 0x03E6CF93
#define PI_DEFAULT_UPDATE_MASK_R2 0xFBC6CF9C
#endif

1591
pigpio.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 4+
This version is for pigpio version 7+
*/
#include <sys/types.h>
@ -54,8 +54,10 @@ static unsigned clockMicros = PI_DEFAULT_CLK_MICROS;
static unsigned clockPeripheral = PI_DEFAULT_CLK_PERIPHERAL;
static unsigned clockSource = PI_DEFAULT_CLK_SOURCE;
static unsigned ifFlags = PI_DEFAULT_IF_FLAGS;
static unsigned DMAchannelChannel = PI_DEFAULT_DMA_CHANNEL;
static unsigned DMAprimaryChannel = PI_DEFAULT_DMA_PRIMARY_CHANNEL;
static unsigned DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CHANNEL;
static unsigned socketPort = PI_DEFAULT_SOCKET_PORT;
static uint64_t updateMask = -1;
static FILE * errFifo;
@ -64,13 +66,15 @@ void usage()
fprintf(stderr, "\n" \
"Usage: sudo pigpiod [OPTION] ...\n" \
" -b value, gpio sample buffer in milliseconds, default 120\n" \
" -d value, DMA channel, 0-14, default 14\n" \
" -d value, primary DMA channel, 0-14, default 14\n" \
" -e value, secondary DMA channel, 0-6, default 5\n" \
" -f, disable fifo interface, default enabled\n" \
" -k, disable socket interface, default enabled\n" \
" -p value, socket port, 1024-32000, default 8888\n" \
" -s value, sample rate, 1, 2, 4, 5, 8, or 10, default 5\n" \
" -t value, clock peripheral, 0=PWM 1=PCM, default PCM\n" \
" -u value, clock source, 0=OSC 1=PLLD, default PLLD\n" \
" -x mask, gpios which may be updated, default 0xFFFFFFFF\n" \
"EXAMPLE\n" \
"sudo pigpiod -s 2 -b 200 -f\n" \
" Set a sample rate of 2 microseconds with a 200 millisecond\n" \
@ -81,8 +85,10 @@ void usage()
static void initOpts(int argc, char *argv[])
{
int i, opt;
uint64_t mask;
char * endptr;
while ((opt = getopt(argc, argv, "b:d:fkp:s:t:u:")) != -1)
while ((opt = getopt(argc, argv, "b:d:e:fkp:s:t:u:x:")) != -1)
{
i = -1;
@ -97,11 +103,18 @@ static void initOpts(int argc, char *argv[])
case 'd':
i = atoi(optarg);
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_DMA_CHANNEL))
DMAchannelChannel = i;
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_PRIMARY_CHANNEL))
DMAprimaryChannel = i;
else cmdFatal("invalid -d option (%d)", i);
break;
case 'e':
i = atoi(optarg);
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_SECONDARY_CHANNEL))
DMAsecondaryChannel = i;
else cmdFatal("invalid -e option (%d)", i);
break;
case 'f':
ifFlags |= PI_DISABLE_FIFO_IF;
break;
@ -151,6 +164,13 @@ static void initOpts(int argc, char *argv[])
else cmdFatal("invalid -u option (%d)", i);
break;
case 'x':
mask = strtoll(optarg, &endptr, 0);
printf("mask=%llx\n", mask);
if (!*endptr) updateMask = mask;
else cmdFatal("invalid -x option (%s)", optarg);
break;
default: /* '?' */
usage();
exit(-1);
@ -224,10 +244,12 @@ int main(int argc, char **argv)
gpioCfgInterfaces(ifFlags);
gpioCfgDMAchannel(DMAchannelChannel);
gpioCfgDMAchannels(DMAprimaryChannel, DMAsecondaryChannel);
gpioCfgSocketPort(socketPort);
if (updateMask != -1) gpioCfgPermissions(updateMask);
/* start library */
if (gpioInitialise()< 0) cmdFatal("Can't initialise pigpio library");
@ -275,4 +297,3 @@ int main(int argc, char **argv)
return 0;
}

183
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 3+
This version is for pigpio version 7+
*/
#include <stdio.h>
@ -34,6 +34,8 @@ This version is for pigpio version 3+
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "pigpio.h"
@ -44,100 +46,123 @@ This program provides a socket interface
to the commands available from pigpio.
*/
static int openSocket(void)
{
int sock, err;
struct addrinfo hints, *res, *rp;
const char *addrStr, *portStr;
portStr = getenv(PI_ENVPORT);
if (!portStr) portStr = PI_DEFAULT_SOCKET_PORT_STR;
addrStr = getenv(PI_ENVADDR);
if (!addrStr) addrStr = PI_DEFAULT_SOCKET_ADDR_STR;
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
err = getaddrinfo(addrStr, portStr, &hints, &res);
if (err) return -1;
for (rp=res; rp!=NULL; rp=rp->ai_next)
{
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sock == -1) continue;
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) break;
}
freeaddrinfo(res);
if (rp == NULL) return -1;
return sock;
}
int main(int argc , char *argv[])
{
int sock, r, idx, port;
struct sockaddr_in server;
int sock, r, idx;
cmdCmd_t cmd;
char * portStr, * addrStr;
char buf[128];
sock = socket(AF_INET, SOCK_STREAM, 0);
sock = openSocket();
if (sock != -1)
{
portStr = getenv(PI_ENVPORT);
if (portStr) port = atoi(portStr);
else port = PI_DEFAULT_SOCKET_PORT;
addrStr = getenv(PI_ENVADDR);
if (!addrStr) addrStr="127.0.0.1";
server.sin_addr.s_addr = inet_addr(addrStr);
server.sin_family = AF_INET;
server.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == 0)
switch(argc)
{
switch(argc)
{
case 1:
exit(0);
case 1:
exit(0);
case 2:
sprintf(buf, "%10s", argv[1]);
break;
case 2:
sprintf(buf, "%10s", argv[1]);
break;
case 3:
sprintf(buf, "%10s %10s", argv[1], argv[2]);
break;
case 3:
sprintf(buf, "%10s %10s", argv[1], argv[2]);
break;
case 4:
sprintf(buf, "%10s %10s %10s", argv[1], argv[2], argv[3]);
break;
case 4:
sprintf(buf, "%10s %10s %10s", argv[1], argv[2], argv[3]);
break;
default:
cmdFatal("what?");
}
if ((idx=cmdParse(buf, &cmd)) >= 0)
{
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
switch (cmdInfo[idx].rv)
{
case 0:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
break;
case 1:
break;
case 2:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
else printf("%d\n", r);
break;
case 3:
printf("%08X\n", cmd.res);
break;
case 4:
printf("%u\n", cmd.res);
break;
case 5:
printf(cmdUsage);
break;
}
}
else cmdFatal("recv failed, %m");
}
else cmdFatal("send failed, %m");
}
else cmdFatal("what?");
default:
cmdFatal("what?");
}
else cmdFatal("connect failed, %m");
close(sock);
if ((idx=cmdParse(buf, &cmd)) >= 0)
{
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
if (recv(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
{
switch (cmdInfo[idx].rv)
{
case 0:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
break;
case 1:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
break;
case 2:
r = cmd.res;
if (r < 0) cmdFatal("ERROR: %s", cmdErrStr(r));
else printf("%d\n", r);
break;
case 3:
printf("%08X\n", cmd.res);
break;
case 4:
printf("%u\n", cmd.res);
break;
case 5:
printf(cmdUsage);
break;
}
}
else cmdFatal("recv failed, %m");
}
else cmdFatal("send failed, %m");
}
else cmdFatal("what?");
}
else cmdFatal("socket failed, %m");
else cmdFatal("connect failed, %m");
close(sock);
return 0;
}

12
setup.py Normal file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env python
from distutils.core import setup
setup(name='pigpio',
version='1.0',
description='Raspberry Pi gpio utility',
author='joan',
author_email='joan@abyz.me.uk',
url='http://abyz.co.uk/rpi/pigpio/python.html/',
py_modules=['pigpio']
)