This commit is contained in:
joan 2015-11-10 14:57:12 +00:00
parent b140e1aa74
commit 92bd13d857
18 changed files with 11244 additions and 164 deletions

View File

@ -4,43 +4,56 @@ SIZE = size
SHLIB = gcc -shared
STRIPLIB = strip --strip-unneeded
CFLAGS += -O3 -Wall
CFLAGS += -O3 -Wall -pthread
ALL = libpigpiod_if.so pigs
ALL = libpigpiod_if.so libpigpiod_if2.so pigs x_pigpiod_if x_pigpiod_if2
all: $(ALL) pigpio.py setup.py
pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
$(CC) $(CFLAGS) -fpic -c -o pigpiod_if.o pigpiod_if.c
pigpiod_if2.o: pigpiod_if2.c pigpio.h command.h pigpiod_if2.h
$(CC) $(CFLAGS) -fpic -c -o pigpiod_if2.o pigpiod_if2.c
command.o: command.c pigpio.h command.h
$(CC) $(CFLAGS) -fpic -c -o command.o command.c
pigs: command.o pigs.o
$(CC) $(CFLAGS) -fpic -o pigs pigs.c command.c
x_pigpiod_if: x_pigpiod_if.o $(LIB1)
$(CC) -o x_pigpiod_if x_pigpiod_if.o $(LL1)
x_pigpiod_if2: x_pigpiod_if2.o $(LIB2)
$(CC) -o x_pigpiod_if2 x_pigpiod_if2.o $(LL2)
clean:
rm -f *.o *.i *.s *~ $(ALL)
install: $(LIB)
install -m 0755 -d /usr/local/include
install -m 0644 pigpio.h /usr/local/include
install -m 0644 pigpiod_if.h /usr/local/include
install -m 0755 -d /usr/local/lib
install -m 0644 libpigpiod_if.so /usr/local/lib
install -m 0755 -d /usr/local/bin
install -m 0755 pigs /usr/local/bin
install: $(LIB1) $(LIB2)
install -m 0755 -d /usr/local/include
install -m 0644 pigpio.h /usr/local/include
install -m 0644 pigpiod_if.h /usr/local/include
install -m 0644 pigpiod_if2.h /usr/local/include
install -m 0755 -d /usr/local/lib
install -m 0644 libpigpiod_if.so /usr/local/lib
install -m 0644 libpigpiod_if2.so /usr/local/lib
install -m 0755 -d /usr/local/bin
install -m 0755 pigs /usr/local/bin
python2 setup.py install
python3 setup.py install
install -m 0755 -d /usr/local/man/man1
install -m 0644 *.1 /usr/local/man/man1
install -m 0755 -d /usr/local/man/man3
install -m 0644 *.3 /usr/local/man/man3
install -m 0755 -d /usr/local/man/man1
install -m 0644 *.1 /usr/local/man/man1
install -m 0755 -d /usr/local/man/man3
install -m 0644 *.3 /usr/local/man/man3
uninstall:
rm -f /usr/local/include/pigpio.h
rm -f /usr/local/include/pigpiod_if.h
rm -f /usr/local/include/pigpiod_if2.h
rm -f /usr/local/lib/libpigpiod_if.so
rm -f /usr/local/lib/libpigpiod_if2.so
echo removing python2 files
python2 setup.py install --record /tmp/pigpio >/dev/null
xargs rm -f < /tmp/pigpio >/dev/null
@ -51,18 +64,30 @@ uninstall:
rm -f /usr/local/man/man1/pig*.1
rm -f /usr/local/man/man3/pig*.3
LIB = libpigpiod_if.so
OBJ = pigpiod_if.o command.o
LL1 = -L. -lpigpiod_if -pthread -lrt
LL2 = -L. -lpigpiod_if2 -pthread -lrt
$(LIB): $(OBJ)
$(SHLIB) -o $(LIB) $(OBJ)
$(STRIPLIB) $(LIB)
$(SIZE) $(LIB)
LIB1 = libpigpiod_if.so
OBJ1 = pigpiod_if.o command.o
LIB2 = libpigpiod_if2.so
OBJ2 = pigpiod_if2.o command.o
$(LIB1): $(OBJ1)
$(SHLIB) -o $(LIB1) $(OBJ1)
$(STRIPLIB) $(LIB1)
$(SIZE) $(LIB1)
$(LIB2): $(OBJ2)
$(SHLIB) -o $(LIB2) $(OBJ2)
$(STRIPLIB) $(LIB2)
$(SIZE) $(LIB2)
# generated using gcc -MM *.c
command.o: command.c pigpio.h command.h
pigpiod.o: pigpiod.c pigpio.h
pigpiod_if.o: pigpiod_if.c pigpio.h pigpiod_if.h command.h
pigpiod_if2.o: pigpiod_if2.c pigpio.h pigpiod_if2.h command.h
pigs.o: pigs.c pigpio.h command.h

View File

@ -6,7 +6,7 @@ SIZE = size
SHLIB = gcc -shared
STRIPLIB = strip --strip-unneeded
CFLAGS += -O3 -Wall
CFLAGS += -O3 -Wall -pthread
LIB1 = libpigpio.so
OBJ1 = pigpio.o command.o
@ -14,13 +14,18 @@ OBJ1 = pigpio.o command.o
LIB2 = libpigpiod_if.so
OBJ2 = pigpiod_if.o command.o
LIB = $(LIB1) $(LIB2)
LIB3 = libpigpiod_if2.so
OBJ3 = pigpiod_if2.o command.o
ALL = $(LIB) x_pigpio x_pigpiod_if pig2vcd pigpiod pigs
LIB = $(LIB1) $(LIB2) $(LIB3)
LL1 = -L. -lpigpio -lpthread -lrt
ALL = $(LIB) x_pigpio x_pigpiod_if x_pigpiod_if2 pig2vcd pigpiod pigs
LL2 = -L. -lpigpiod_if -lpthread -lrt
LL1 = -L. -lpigpio -pthread -lrt
LL2 = -L. -lpigpiod_if -pthread -lrt
LL3 = -L. -lpigpiod_if2 -pthread -lrt
all: $(ALL)
@ -30,6 +35,9 @@ pigpio.o: pigpio.c pigpio.h command.h custom.cext
pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
$(CC) $(CFLAGS) -fpic -c -o pigpiod_if.o pigpiod_if.c
pigpiod_if2.o: pigpiod_if2.c pigpio.h command.h pigpiod_if2.h
$(CC) $(CFLAGS) -fpic -c -o pigpiod_if2.o pigpiod_if2.c
command.o: command.c pigpio.h command.h
$(CC) $(CFLAGS) -fpic -c -o command.o command.c
@ -39,6 +47,9 @@ x_pigpio: x_pigpio.o $(LIB1)
x_pigpiod_if: x_pigpiod_if.o $(LIB2)
$(CC) -o x_pigpiod_if x_pigpiod_if.o $(LL2)
x_pigpiod_if2: x_pigpiod_if2.o $(LIB3)
$(CC) -o x_pigpiod_if2 x_pigpiod_if2.o $(LL3)
pigpiod: pigpiod.o $(LIB1)
$(CC) -o pigpiod pigpiod.o $(LL1)
@ -52,30 +63,34 @@ clean:
rm -f *.o *.i *.s *~ $(ALL)
install: $(ALL)
install -m 0755 -d /opt/pigpio/cgi
install -m 0755 -d /usr/local/include
install -m 0644 pigpio.h /usr/local/include
install -m 0644 pigpiod_if.h /usr/local/include
install -m 0755 -d /usr/local/lib
install -m 0755 libpigpio.so /usr/local/lib
install -m 0755 libpigpiod_if.so /usr/local/lib
install -m 0755 -d /usr/local/bin
install -m 0755 -s pig2vcd /usr/local/bin
install -m 0755 -s pigpiod /usr/local/bin
install -m 0755 -s pigs /usr/local/bin
install -m 0755 -d /opt/pigpio/cgi
install -m 0755 -d /usr/local/include
install -m 0644 pigpio.h /usr/local/include
install -m 0644 pigpiod_if.h /usr/local/include
install -m 0644 pigpiod_if2.h /usr/local/include
install -m 0755 -d /usr/local/lib
install -m 0755 libpigpio.so /usr/local/lib
install -m 0755 libpigpiod_if.so /usr/local/lib
install -m 0755 libpigpiod_if2.so /usr/local/lib
install -m 0755 -d /usr/local/bin
install -m 0755 -s pig2vcd /usr/local/bin
install -m 0755 -s pigpiod /usr/local/bin
install -m 0755 -s pigs /usr/local/bin
if which python2; then python2 setup.py install; fi
if which python3; then python3 setup.py install; fi
install -m 0755 -d /usr/local/man/man1
install -m 0644 *.1 /usr/local/man/man1
install -m 0755 -d /usr/local/man/man3
install -m 0644 *.3 /usr/local/man/man3
install -m 0755 -d /usr/local/man/man1
install -m 0644 *.1 /usr/local/man/man1
install -m 0755 -d /usr/local/man/man3
install -m 0644 *.3 /usr/local/man/man3
ldconfig
uninstall:
rm -f /usr/local/include/pigpio.h
rm -f /usr/local/include/pigpiod_if.h
rm -f /usr/local/include/pigpiod_if2.h
rm -f /usr/local/lib/libpigpio.so
rm -f /usr/local/lib/libpigpiod_if.so
rm -f /usr/local/lib/libpigpiod_if2.so
rm -f /usr/local/bin/pig2vcd
rm -f /usr/local/bin/pigpiod
rm -f /usr/local/bin/pigs
@ -95,6 +110,11 @@ $(LIB2): $(OBJ2)
$(STRIPLIB) $(LIB2)
$(SIZE) $(LIB2)
$(LIB3): $(OBJ3)
$(SHLIB) -o $(LIB3) $(OBJ3)
$(STRIPLIB) $(LIB3)
$(SIZE) $(LIB3)
# generated using gcc -MM *.c
pig2vcd.o: pig2vcd.c pigpio.h
@ -102,3 +122,4 @@ pigpiod.o: pigpiod.c pigpio.h
pigs.o: pigs.c pigpio.h command.h
x_pigpio.o: x_pigpio.c pigpio.h
x_pigpiod_if.o: x_pigpiod_if.c pigpiod_if.h pigpio.h
x_pigpiod_if2.o: x_pigpiod_if2.c pigpiod_if2.h pigpio.h

32
README
View File

@ -13,18 +13,20 @@ IN THAT DIRECTORY
Enter the following two commands (in this order)
make
make install
sudo make install
This will install
o the library (libpigpio.so) in /usr/local/lib
o the library (libpigpiod_if.so) in /usr/local/lib
o the library (libpigpiod_if2.so) in /usr/local/lib
o the header file (pigpio.h) in /usr/local/include
o the header file (pigpiod_if.h) in /usr/local/include
o the header file (pigpiod_if2.h) in /usr/local/include
o the daemon (pigpiod) in /usr/local/bin
o the socket interface (pigs) in /usr/local/bin
o the utility pig2vcd in /usr/local/bin
o man pages in /usr/local/man/man1 and man3
o man pages in /usr/local/man/man1 and /usr/local/man/man3
o the Python module pigpio.py for Python 2 and 3
TEST (optional)
@ -48,19 +50,21 @@ To test the pigpio daemon do
sudo pigpiod
./x_pigpiod_if # test the C I/F to the pigpio daemon
./x_pigpio.py # test the Python I/F to the pigpio daemon
./x_pigs # test the socket I/F to the pigpio daemon
./x_pipe # test the pipe I/F to the pigpio daemon
./x_pigpiod_if # test the C I/F to the pigpio daemon
./x_pigpiod_if2 # test the C I/F to the pigpio daemon
./x_pigpio.py # test the Python I/F to the pigpio daemon
./x_pigs # test the socket I/F to the pigpio daemon
./x_pipe # test the pipe I/F to the pigpio daemon
EXAMPLE CODE
x_pigpio.c, pig2vcd.c, and pigpiod.c show examples of interfacing
with the pigpio library.
pigs.c, pigpio.py, x_pigpiod_if.c, x_pigpio.py, x_pigs, and x_pipe
show examples of interfacing with the pigpio daemon. x_pipe uses
the pipe interface, the others use the socket interface.
pigs.c, pigpio.py, x_pigpiod_if, x_pigpiod_if2.c, x_pigpio.py,
x_pigs, and x_pipe show examples of interfacing with the pigpio
daemon. x_pipe uses the pipe interface, the others use the
socket interface.
DAEMON
@ -123,6 +127,7 @@ In particular this allows you to use the following on non-Pi's.
o pigs
o the pigpio Python module
o the C socket I/F using libpigpiod_if (header file pigpiod_if.h)
o the C socket I/F using libpigpiod_if2 (header file pigpiod_if2.h)
On a Linux machine
@ -133,10 +138,12 @@ make -f MakeRemote install
This will install
o the library (libpigpiod_if.so) in /usr/local/lib
o the library (libpigpiod_if2.so) in /usr/local/lib
o the header file (pigpio.h) in /usr/local/include
o the header file (pigpiod_if.h) in /usr/local/include
o the header file (pigpiod_if2.h) in /usr/local/include
o the socket interface (pigs) in /usr/local/bin
o man pages in /usr/local/man/man1 and man3
o man pages in /usr/local/man/man1 and /usr/local/man/man3
o the Python module pigpio.py
On Windows machines (and possibly Macs)
@ -145,8 +152,8 @@ The Python module should install with
python setup.py install
pigs and pigpiod_if.c will need minor mods to reflect the
Window's/Mac's socket interface.
pigs, pigpiod_if, and pigpiod_if2 will need minor mods to
reflect the Windows/Mac socket interface.
DOCUMENTATION
@ -160,6 +167,7 @@ man pig2vcd
man pigpio
man pigpiod_if
man pigpiod_if2
pydoc pigpio

View File

@ -556,7 +556,7 @@ int cmdParse(
char *p8;
int32_t *p32;
char c;
uint32_t tp1, tp2, tp3;
uint32_t tp1=0, tp2=0, tp3=0;
int8_t to1, to2, to3;
int eaten;

View File

@ -2,7 +2,7 @@
." Process this file with
." groff -man -Tascii pig2vcd.1
."
.TH pig2vcd 1 2012-2014 Linux "pigpio archive"
.TH pig2vcd 1 2012-2015 Linux "pigpio archive"
.SH NAME
pig2vd - A utility to convert pigpio notifications to VCD.
@ -236,7 +236,7 @@ The state lines contain the new state followed by the gpio identifier.
.SH SEE ALSO
pigpiod(1), pigs(1), pigpio(3), pigpiod_if(3)
pigpiod(1), pigs(1), pigpio(3), pigpiod_if(3), pigpiod_if2(3)
.SH AUTHOR
joan@abyz.co.uk

138
pigpio.3
View File

@ -2,13 +2,16 @@
." Process this file with
." groff -man -Tascii pigpio.3
."
.TH pigpio 3 2012-2014 Linux "pigpio archive"
.TH pigpio 3 2012-2015 Linux "pigpio archive"
.SH NAME
pigpio - A C library to manipulate the Pi's gpios.
.SH SYNOPSIS
gcc -o prog prog.c -lpigpio -lrt -lpthread
#include <pigpio.h>
gcc -Wall -pthread -o prog prog.c -lpigpio -lrt
sudo ./prog
.SH DESCRIPTION
@ -130,7 +133,7 @@ run the executable.
.br
.EX
gcc -o prog prog.c -lpigpio -lpthread -lrt
gcc -Wall -pthread -o prog prog.c -lpigpio -lrt
.br
sudo ./prog
.br
@ -2411,23 +2414,23 @@ of the function description. The following abbreviations are used.
.br
.EX
S (1 bit) : Start bit
S (1 bit) : Start bit
.br
P (1 bit) : Stop bit
P (1 bit) : Stop bit
.br
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
.br
A, NA (1 bit) : Accept and not accept bit.
A, NA (1 bit) : Accept and not accept bit.
.br
.br
.br
Addr (7 bits): I2C 7 bit address.
Addr (7 bits): I2C 7 bit address.
.br
Comm (8 bits): Command byte, a data byte which often selects a register.
i2cReg (8 bits): Command byte, a byte which often selects a register.
.br
Data (8 bits): A data byte.
Data (8 bits): A data byte.
.br
Count (8 bits): A data byte containing the length of a block operation.
Count (8 bits): A byte defining the length of a block operation.
.br
.br
@ -2484,7 +2487,7 @@ PI_I2C_WRITE_FAILED.
Quick command. SMBus 2.0 5.5.1
.EX
S Addr Rd/Wr [A] P
S Addr bit [A] P
.br
.EE
@ -2517,7 +2520,7 @@ PI_I2C_WRITE_FAILED.
Send byte. SMBus 2.0 5.5.2
.EX
S Addr Wr [A] Data [A] P
S Addr Wr [A] bVal [A] P
.br
.EE
@ -2584,7 +2587,7 @@ PI_I2C_WRITE_FAILED.
Write byte. SMBus 2.0 5.5.4
.EX
S Addr Wr [A] Comm [A] Data [A] P
S Addr Wr [A] i2cReg [A] bVal [A] P
.br
.EE
@ -2620,7 +2623,7 @@ PI_I2C_WRITE_FAILED.
Write word. SMBus 2.0 5.5.4
.EX
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
S Addr Wr [A] i2cReg [A] wValLow [A] wValHigh [A] P
.br
.EE
@ -2654,7 +2657,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Read byte. SMBus 2.0 5.5.5
.EX
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
S Addr Wr [A] i2cReg [A] S Addr Rd [A] [Data] NA P
.br
.EE
@ -2688,7 +2691,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Read word. SMBus 2.0 5.5.5
.EX
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
S Addr Wr [A] i2cReg [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
.br
.EE
@ -2724,7 +2727,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Process call. SMBus 2.0 5.5.6
.EX
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
S Addr Wr [A] i2cReg [A] wValLow [A] wValHigh [A]
.br
S Addr Rd [A] [DataLow] A [DataHigh] NA P
.br
@ -2764,7 +2767,9 @@ PI_I2C_WRITE_FAILED.
Block write. SMBus 2.0 5.5.7
.EX
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
S Addr Wr [A] i2cReg [A] count [A]
.br
buf0 [A] buf1 [A] ... [A] bufn [A] P
.br
.EE
@ -2805,9 +2810,9 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Block read. SMBus 2.0 5.5.7
.EX
S Addr Wr [A] Comm [A]
S Addr Wr [A] i2cReg [A]
.br
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
S Addr Rd [A] [Count] A [buf0] A [buf1] A ... A [bufn] NA P
.br
.EE
@ -2853,9 +2858,9 @@ bytes sent/received must be 32 or less.
Block write-block read. SMBus 2.0 5.5.8
.EX
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
S Addr Wr [A] i2cReg [A] count [A] buf0 [A] ... bufn [A]
.br
S Addr Rd [A] [Count] A [Data] ... A P
S Addr Rd [A] [Count] A [buf0] A ... [bufn] A P
.br
.EE
@ -2892,9 +2897,9 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.EX
S Addr Wr [A] Comm [A]
S Addr Wr [A] i2cReg [A]
.br
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
S Addr Rd [A] [buf0] A [buf1] A ... A [bufn] NA P
.br
.EE
@ -2931,7 +2936,7 @@ PI_I2C_WRITE_FAILED.
.br
.EX
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
S Addr Wr [A] i2cReg [A] buf0 [A] buf1 [A] ... [A] bufn [A] P
.br
.EE
@ -2960,6 +2965,16 @@ handle: >=0, as returned by a call to \fBi2cOpen\fP
Returns count (>0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_READ_FAILED.
.br
.br
.EX
S Addr Rd [A] [buf0] A [buf1] A ... A [bufn] NA P
.br
.EE
.IP "\fBint i2cWriteDevice(unsigned handle, char *buf, unsigned count)\fP"
.IP "" 4
This writes count bytes from buf to the raw device.
@ -2984,6 +2999,16 @@ handle: >=0, as returned by a call to \fBi2cOpen\fP
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
.br
.br
.EX
S Addr Wr [A] buf0 [A] buf1 [A] ... [A] bufn [A] P
.br
.EE
.IP "\fBvoid i2cSwitchCombined(int setting)\fP"
.IP "" 4
This sets the I2C (i2c-bcm2708) module "use combined transactions"
@ -4130,7 +4155,7 @@ registered per timer.
.br
See \fBgpioSetTimerFunc\fP for further details.
.IP "\fBpthread_t *gpioStartThread(gpioThreadFunc_t f, void *arg)\fP"
.IP "\fBpthread_t *gpioStartThread(gpioThreadFunc_t f, void *userdata)\fP"
.IP "" 4
Starts a new thread of execution with f as the main routine.
@ -4139,9 +4164,9 @@ Starts a new thread of execution with f as the main routine.
.br
.EX
f: the main function for the new thread
f: the main function for the new thread
.br
arg: a pointer to arbitrary user data
userdata: a pointer to arbitrary user data
.br
.EE
@ -5706,17 +5731,6 @@ a stable level).
.br
.IP "\fB*arg\fP" 0
.br
.br
A pointer to a void object passed to a thread started by gpioStartThread.
.br
.br
.IP "\fBarg1\fP" 0
.br
@ -7410,6 +7424,48 @@ A pointer to arbitrary user data. This may be used to identify the instance.
.br
.br
You must ensure that the pointer is in scope at the time it is processed. If
it is a pointer to a global this is automatic. Do not pass the address of a
local variable. If you want to pass a transient object then use the
following technique.
.br
.br
In the calling function:
.br
.br
user_type *userdata;
.br
user_type my_userdata;
.br
.br
userdata = malloc(sizeof(user_type));
.br
*userdata = my_userdata;
.br
.br
In the receiving function:
.br
.br
user_type my_userdata = *(user_type*)userdata;
.br
.br
free(userdata);
.br
.br
.IP "\fBvoid\fP" 0
@ -8026,7 +8082,7 @@ A 16-bit word value.
.SH SEE ALSO
pigpiod(1), pig2vcd(1), pigs(1), pigpiod_if(3)
pigpiod(1), pig2vcd(1), pigs(1), pigpiod_if(3), pigpiod_if2(3)
.SH AUTHOR
joan@abyz.co.uk

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 39 */
/* pigpio version 40 */
/* include ------------------------------------------------------- */
@ -1375,6 +1375,8 @@ static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr);
int gpioWaveTxStart(unsigned wave_mode); /* deprecated */
static void closeOrphanedNotifications(int slot, int fd);
/* ======================================================================= */
@ -5394,6 +5396,7 @@ static void * pthAlertThread(void *x)
{
if (gpioNotify[n].pipe)
{
DBG(DBG_INTERNAL, "close notify pipe %d", gpioNotify[n].fd);
close(gpioNotify[n].fd);
sprintf(fifo, "/dev/pigpio%d", n);
@ -5499,6 +5502,8 @@ static void * pthAlertThread(void *x)
if (emit)
{
DBG(DBG_FAST_TICK, "notification %d (%d reports, %x-%x)",
n, emit, gpioReport[0].seqno, gpioReport[emit-1].seqno);
gpioNotify[n].lastReportTick = stick;
max_emits = gpioNotify[n].max_emits;
@ -6221,7 +6226,10 @@ static void *pthSocketThreadHandler(void *fdC)
if (recv(sock, buf, p[3], MSG_WAITALL) != p[3])
{
/* Serious error. No point continuing. */
DBG(DBG_ALWAYS, "recv failed for %d bytes", p[3]);
DBG(DBG_ALWAYS,
"recv failed for %d bytes, sock=%d", p[3], sock);
closeOrphanedNotifications(-1, sock);
close(sock);
@ -6231,7 +6239,10 @@ static void *pthSocketThreadHandler(void *fdC)
else
{
/* Serious error. No point continuing. */
DBG(DBG_ALWAYS, "ext too large %d(%d)", p[3], sizeof(buf));
DBG(DBG_ALWAYS,
"ext too large %d(%d), sock=%d", p[3], sizeof(buf), sock);
closeOrphanedNotifications(-1, sock);
close(sock);
@ -6299,6 +6310,8 @@ static void *pthSocketThreadHandler(void *fdC)
}
}
closeOrphanedNotifications(-1, sock);
close(sock);
return 0;
@ -6340,6 +6353,8 @@ static void * pthSocketThread(void *x)
{
pthread_t thr;
closeOrphanedNotifications(-1, fdC);
sock = malloc(sizeof(int));
*sock = fdC;
@ -7123,6 +7138,16 @@ static void initReleaseResources(void)
/* shut down running threads */
for (i=0; i<=PI_MAX_USER_GPIO; i++)
{
if (gpioISR[i].pth)
{
/* destroy thread, unexport GPIO */
gpioSetISRFunc(i, 0, 0, NULL);
}
}
for (i=0; i<=PI_MAX_TIMER; i++)
{
if (gpioTimer[i].running)
@ -10026,6 +10051,24 @@ int gpioSetISRFuncEx(
return intGpioSetISRFunc(gpio, edge, timeout, f, 1, userdata);
}
static void closeOrphanedNotifications(int slot, int fd)
{
int i;
/* Check for and close any orphaned notifications. */
for (i=0; i<PI_NOTIFY_SLOTS; i++)
{
if ((i != slot) &&
(gpioNotify[i].state != PI_NOTIFY_CLOSED) &&
(gpioNotify[i].fd == fd))
{
DBG(DBG_USER, "closed orphaned fd=%d (handle=%d)", fd, i);
gpioNotify[i].state = PI_NOTIFY_CLOSED;
intNotifyBits();
}
}
}
/* ----------------------------------------------------------------------- */
@ -10072,6 +10115,8 @@ int gpioNotifyOpen(void)
gpioNotify[slot].max_emits = MAX_EMITS;
gpioNotify[slot].lastReportTick = gpioTick();
closeOrphanedNotifications(slot, fd);
return slot;
}
@ -10082,7 +10127,7 @@ static int gpioNotifyOpenInBand(int fd)
{
int i, slot;
DBG(DBG_USER, "");
DBG(DBG_USER, "fd=%d", fd);
CHECK_INITED;
@ -10107,6 +10152,8 @@ static int gpioNotifyOpenInBand(int fd)
gpioNotify[slot].max_emits = MAX_EMITS;
gpioNotify[slot].lastReportTick = gpioTick();
closeOrphanedNotifications(slot, fd);
return slot;
}
@ -10491,12 +10538,12 @@ int gpioSetTimerFuncEx(unsigned id, unsigned millis, gpioTimerFuncEx_t f,
/* ----------------------------------------------------------------------- */
pthread_t *gpioStartThread(gpioThreadFunc_t f, void *arg)
pthread_t *gpioStartThread(gpioThreadFunc_t f, void *userdata)
{
pthread_t *pth;
pthread_attr_t pthAttr;
DBG(DBG_USER, "f=%08X, arg=%08X", (uint32_t)f, (uint32_t)arg);
DBG(DBG_USER, "f=%08X, userdata=%08X", (uint32_t)f, (uint32_t)userdata);
CHECK_INITED_RET_NULL_PTR;
@ -10516,7 +10563,7 @@ pthread_t *gpioStartThread(gpioThreadFunc_t f, void *arg)
SOFT_ERROR(NULL, "pthread_attr_setstacksize failed");
}
if (pthread_create(pth, &pthAttr, f, arg))
if (pthread_create(pth, &pthAttr, f, userdata))
{
free(pth);
SOFT_ERROR(NULL, "pthread_create failed");

View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h>
#include <pthread.h>
#define PIGPIO_VERSION 39
#define PIGPIO_VERSION 40
/*TEXT
@ -83,7 +83,7 @@ Assuming your source is in prog.c use the following command to build and
run the executable.
. .
gcc -o prog prog.c -lpigpio -lpthread -lrt
gcc -Wall -pthread -o prog prog.c -lpigpio -lrt
sudo ./prog
. .
@ -2034,14 +2034,14 @@ For the SMBus commands the low level transactions are shown at the end
of the function description. The following abbreviations are used.
. .
S (1 bit) : Start bit
P (1 bit) : Stop bit
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A, NA (1 bit) : Accept and not accept bit.
Addr (7 bits): I2C 7 bit address.
Comm (8 bits): Command byte, a data byte which often selects a register.
Data (8 bits): A data byte.
Count (8 bits): A data byte containing the length of a block operation.
S (1 bit) : Start bit
P (1 bit) : Stop bit
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A, NA (1 bit) : Accept and not accept bit.
Addr (7 bits): I2C 7 bit address.
i2cReg (8 bits): Command byte, a byte which often selects a register.
Data (8 bits): A data byte.
Count (8 bits): A byte defining the length of a block operation.
[..]: Data sent by the device.
. .
@ -2077,7 +2077,7 @@ PI_I2C_WRITE_FAILED.
Quick command. SMBus 2.0 5.5.1
. .
S Addr Rd/Wr [A] P
S Addr bit [A] P
. .
D*/
@ -2097,7 +2097,7 @@ PI_I2C_WRITE_FAILED.
Send byte. SMBus 2.0 5.5.2
. .
S Addr Wr [A] Data [A] P
S Addr Wr [A] bVal [A] P
. .
D*/
@ -2138,7 +2138,7 @@ PI_I2C_WRITE_FAILED.
Write byte. SMBus 2.0 5.5.4
. .
S Addr Wr [A] Comm [A] Data [A] P
S Addr Wr [A] i2cReg [A] bVal [A] P
. .
D*/
@ -2160,7 +2160,7 @@ PI_I2C_WRITE_FAILED.
Write word. SMBus 2.0 5.5.4
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
S Addr Wr [A] i2cReg [A] wValLow [A] wValHigh [A] P
. .
D*/
@ -2181,7 +2181,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Read byte. SMBus 2.0 5.5.5
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
S Addr Wr [A] i2cReg [A] S Addr Rd [A] [Data] NA P
. .
D*/
@ -2202,7 +2202,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Read word. SMBus 2.0 5.5.5
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
S Addr Wr [A] i2cReg [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
D*/
@ -2224,7 +2224,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Process call. SMBus 2.0 5.5.6
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
S Addr Wr [A] i2cReg [A] wValLow [A] wValHigh [A]
S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
D*/
@ -2249,7 +2249,8 @@ PI_I2C_WRITE_FAILED.
Block write. SMBus 2.0 5.5.7
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
S Addr Wr [A] i2cReg [A] count [A]
buf0 [A] buf1 [A] ... [A] bufn [A] P
. .
D*/
@ -2273,8 +2274,8 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
Block read. SMBus 2.0 5.5.7
. .
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
S Addr Wr [A] i2cReg [A]
S Addr Rd [A] [Count] A [buf0] A [buf1] A ... A [bufn] NA P
. .
D*/
@ -2303,8 +2304,8 @@ bytes sent/received must be 32 or less.
Block write-block read. SMBus 2.0 5.5.8
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
S Addr Rd [A] [Count] A [Data] ... A P
S Addr Wr [A] i2cReg [A] count [A] buf0 [A] ... bufn [A]
S Addr Rd [A] [Count] A [buf0] A ... [bufn] A P
. .
D*/
@ -2327,8 +2328,8 @@ Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
. .
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
S Addr Wr [A] i2cReg [A]
S Addr Rd [A] [buf0] A [buf1] A ... A [bufn] NA P
. .
D*/
@ -2351,7 +2352,7 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
. .
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
S Addr Wr [A] i2cReg [A] buf0 [A] buf1 [A] ... [A] bufn [A] P
. .
D*/
@ -2368,6 +2369,10 @@ handle: >=0, as returned by a call to [*i2cOpen*]
Returns count (>0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_READ_FAILED.
. .
S Addr Rd [A] [buf0] A [buf1] A ... A [bufn] NA P
. .
D*/
@ -2384,6 +2389,10 @@ handle: >=0, as returned by a call to [*i2cOpen*]
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
. .
S Addr Wr [A] buf0 [A] buf1 [A] ... [A] bufn [A] P
. .
D*/
/*F*/
@ -3046,13 +3055,13 @@ D*/
/*F*/
pthread_t *gpioStartThread(gpioThreadFunc_t f, void *arg);
pthread_t *gpioStartThread(gpioThreadFunc_t f, void *userdata);
/*D
Starts a new thread of execution with f as the main routine.
. .
f: the main function for the new thread
arg: a pointer to arbitrary user data
f: the main function for the new thread
userdata: a pointer to arbitrary user data
. .
Returns a pointer to pthread_t if OK, otherwise NULL.
@ -4005,10 +4014,6 @@ The number of microseconds level changes are reported for once
a noise filter has been triggered (by [*steady*] microseconds of
a stable level).
*arg::
A pointer to a void object passed to a thread started by gpioStartThread.
arg1::
An unsigned argument passed to a user customised function. Its
@ -4717,6 +4722,25 @@ See [*gpio*].
A pointer to arbitrary user data. This may be used to identify the instance.
You must ensure that the pointer is in scope at the time it is processed. If
it is a pointer to a global this is automatic. Do not pass the address of a
local variable. If you want to pass a transient object then use the
following technique.
In the calling function:
user_type *userdata;
user_type my_userdata;
userdata = malloc(sizeof(user_type));
*userdata = my_userdata;
In the receiving function:
user_type my_userdata = *(user_type*)userdata;
free(userdata);
void::
Denoting no parameter is required

View File

@ -269,7 +269,7 @@ import threading
import os
import atexit
VERSION = "1.23"
VERSION = "1.24"
exceptions = True
@ -2190,9 +2190,9 @@ class pi():
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A, NA (1 bit) : Accept and not accept bit.
Addr (7 bits): I2C 7 bit address.
Comm (8 bits): Command byte, which often selects a register.
reg (8 bits): Command byte, which often selects a register.
Data (8 bits): A data byte.
Count (8 bits): A byte containing the length of a block operation.
Count (8 bits): A byte defining the length of a block operation.
[..]: Data sent by the device.
. .
@ -2231,7 +2231,7 @@ class pi():
SMBus 2.0 5.5.1 - Quick command.
. .
S Addr Rd/Wr [A] P
S Addr bit [A] P
. .
...
@ -2250,7 +2250,7 @@ class pi():
SMBus 2.0 5.5.2 - Send byte.
. .
S Addr Wr [A] Data [A] P
S Addr Wr [A] byte_val [A] P
. .
...
@ -2289,7 +2289,7 @@ class pi():
SMBus 2.0 5.5.4 - Write byte.
. .
S Addr Wr [A] Comm [A] Data [A] P
S Addr Wr [A] reg [A] byte_val [A] P
. .
...
@ -2320,7 +2320,7 @@ class pi():
SMBus 2.0 5.5.4 - Write word.
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
S Addr Wr [A] reg [A] word_val_Low [A] word_val_High [A] P
. .
...
@ -2350,7 +2350,7 @@ class pi():
SMBus 2.0 5.5.5 - Read byte.
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
S Addr Wr [A] reg [A] S Addr Rd [A] [Data] NA P
. .
...
@ -2373,7 +2373,7 @@ class pi():
SMBus 2.0 5.5.5 - Read word.
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
S Addr Wr [A] reg [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
...
@ -2397,7 +2397,7 @@ class pi():
SMBus 2.0 5.5.6 - Process call.
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
S Addr Wr [A] reg [A] word_val_Low [A] word_val_High [A]
S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
@ -2426,8 +2426,8 @@ class pi():
SMBus 2.0 5.5.7 - Block write.
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A]
Data [A] P
S Addr Wr [A] reg [A] len(data) [A] data0 [A] data1 [A] ... [A]
datan [A] P
. .
...
@ -2461,7 +2461,7 @@ class pi():
SMBus 2.0 5.5.7 - Block read.
. .
S Addr Wr [A] Comm [A]
S Addr Wr [A] reg [A]
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
. .
@ -2505,7 +2505,7 @@ class pi():
SMBus 2.0 5.5.8 - Block write-block read.
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
S Addr Wr [A] reg [A] len(data) [A] data0 [A] ... datan [A]
S Addr Rd [A] [Count] A [Data] ... A P
. .
@ -2550,8 +2550,7 @@ class pi():
data:= the bytes to write.
. .
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
S Addr Wr [A] reg [A] data0 [A] data1 [A] ... [A] datan [NA] P
. .
...
@ -2585,7 +2584,8 @@ class pi():
count:= >0, the number of bytes to read.
. .
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
S Addr Wr [A] reg [A]
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
. .
The returned value is a tuple of the number of bytes read and a
@ -2626,6 +2626,10 @@ class pi():
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
count:= >0, the number of bytes to read.
. .
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
. .
The returned value is a tuple of the number of bytes read and a
bytearray containing the bytes. If there was an error the
number of bytes read will be less than zero (and will contain
@ -2652,6 +2656,10 @@ class pi():
handle:= >=0 (as returned by a prior call to [*i2c_open*]).
data:= the bytes to write.
. .
S Addr Wr [A] data0 [A] data1 [A] ... [A] datan [A] P
. .
...
pi.i2c_write_device(h, b"\\x12\\x34\\xA8")
@ -3902,7 +3910,9 @@ def xref():
PI_CHAIN_NESTING = -118
PI_CHAIN_TOO_BIG = -119
PI_DEPRECATED = -120
PI_BAD_SER_INVERT = -121
PI_BAD_SER_INVERT = -121
PI_BAD_FOREVER = -124
PI_BAD_FILTER = -125
. .
frequency: 0-40000

View File

@ -2,7 +2,7 @@
." Process this file with
." groff -man -Tascii pigpiod.1
."
.TH pigpiod 1 2012-2014 Linux "pigpio archive"
.TH pigpiod 1 2012-2015 Linux "pigpio archive"
.SH NAME
pigpiod - A utility to start the pigpio library as a daemon.
@ -183,7 +183,7 @@ The high USB power mode gpio may be written (gpio 38 for type 3 boards).
.SH SEE ALSO
pig2vcd(1), pigs(1), pigpio(3), pigpiod_if(3)
pig2vcd(1), pigs(1), pigpio(3), pigpiod_if(3), pigpiod_if2(3)
.SH AUTHOR
joan@abyz.co.uk

View File

@ -2,18 +2,27 @@
." Process this file with
." groff -man -Tascii pigpiod_if.3
."
.TH pigpiod_if 3 2012-2014 Linux "pigpio archive"
.TH pigpiod_if 3 2012-2015 Linux "pigpio archive"
.SH NAME
pigpiod_if - A C library to interface to the pigpio daemon.
.SH SYNOPSIS
gcc -o prog prog.c -lpigpiod_if
#include <pigpiod_if.h>
gcc -Wall -pthread -o prog prog.c -lpigpiod_if -lrt
./prog
.SH DESCRIPTION
.br
.br
THIS LIBRARY IS DEPRECATED. NEW CODE SHOULD BE WRITTEN TO
USE THE MORE VERSATILE pigpiod_if2 LIBRARY.
.br
.br
@ -122,7 +131,7 @@ Assuming your source is in prog.c use the following command to build
.br
.EX
gcc -o prog prog.c -lpigpiod_if
gcc -Wall -pthread -o prog prog.c -lpigpiod_if -lrt
.br
.EE
@ -4770,7 +4779,7 @@ typedef enum
.SH SEE ALSO
pigpiod(1), pig2vcd(1), pigs(1), pigpio(3)
pigpiod(1), pig2vcd(1), pigs(1), pigpio(3), pigpiod_if2(3)
.SH AUTHOR
joan@abyz.co.uk

View File

@ -34,6 +34,9 @@ For more information, please refer to <http://unlicense.org/>
/*TEXT
THIS LIBRARY IS DEPRECATED. NEW CODE SHOULD BE WRITTEN TO
USE THE MORE VERSATILE pigpiod_if2 LIBRARY.
pigpiod_if is a C library for the Raspberry which allows control
of the gpios via the socket interface to the pigpio daemon.
@ -78,7 +81,7 @@ Include <pigpiod_if.h> in your source files.
Assuming your source is in prog.c use the following command to build
. .
gcc -o prog prog.c -lpigpiod_if
gcc -Wall -pthread -o prog prog.c -lpigpiod_if -lrt
. .
to run make sure the pigpio daemon is running

5240
pigpiod_if2.3 Normal file

File diff suppressed because it is too large Load Diff

1659
pigpiod_if2.c Normal file

File diff suppressed because it is too large Load Diff

3094
pigpiod_if2.h Normal file

File diff suppressed because it is too large Load Diff

4
pigs.1
View File

@ -2,7 +2,7 @@
." Process this file with
." groff -man -Tascii foo.1
."
.TH pigs 1 2012-2014 Linux "pigpio archive"
.TH pigs 1 2012-2015 Linux "pigpio archive"
.SH NAME
pigs - command line socket access to the pigpio daemon.
@ -4339,7 +4339,7 @@ the current gpio levels.
.SH SEE ALSO
pigpiod(1), pig2vcd(1), pigpio(3), pigpiod_if(3)
pigpiod(1), pig2vcd(1), pigpio(3), pigpiod_if(3), pigpiod_if2(3)
.SH AUTHOR
joan@abyz.co.uk

View File

@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='pigpio',
version='1.23',
version='1.24',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',

884
x_pigpiod_if2.c Normal file
View File

@ -0,0 +1,884 @@
/*
gcc -o x_pigpiod_if2 x_pigpiod_if2.c -lpigpiod_if2 -lpthread
./x_pigpiod_if2
*** WARNING ************************************************
* *
* All the tests make extensive use of gpio 4 (pin P1-7). *
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
* *
* Some tests are statistical in nature and so may on *
* occasion fail. Repeated failures on the same test or *
* many failures in a group of tests indicate a problem. *
************************************************************
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "pigpiod_if2.h"
#define GPIO 4
void CHECK(int t, int st, int got, int expect, int pc, char *desc)
{
if ((got >= (((1E2-pc)*expect)/1E2)) && (got <= (((1E2+pc)*expect)/1E2)))
{
printf("TEST %2d.%-2d PASS (%s: %d)\n", t, st, desc, expect);
}
else
{
fprintf(stderr,
"TEST %2d.%-2d FAILED got %d (%s: %d)\n",
t, st, got, desc, expect);
}
}
void t0(int pi)
{
printf("Version.\n");
printf("pigpio version %d.\n", get_pigpio_version(pi));
printf("Hardware revision %d.\n", get_hardware_revision(pi));
}
void t1(int pi)
{
int v;
printf("Mode/PUD/read/write tests.\n");
set_mode(pi, GPIO, PI_INPUT);
v = get_mode(pi, GPIO);
CHECK(1, 1, v, 0, 0, "set mode, get mode");
set_pull_up_down(pi, GPIO, PI_PUD_UP);
v = gpio_read(pi, GPIO);
CHECK(1, 2, v, 1, 0, "set pull up down, read");
set_pull_up_down(pi, GPIO, PI_PUD_DOWN);
v = gpio_read(pi, GPIO);
CHECK(1, 3, v, 0, 0, "set pull up down, read");
gpio_write(pi, GPIO, PI_LOW);
v = get_mode(pi, GPIO);
CHECK(1, 4, v, 1, 0, "write, get mode");
v = gpio_read(pi, GPIO);
CHECK(1, 5, v, 0, 0, "read");
gpio_write(pi, GPIO, PI_HIGH);
v = gpio_read(pi, GPIO);
CHECK(1, 6, v, 1, 0, "write, read");
}
int t2_count=0;
void t2cb(int pi, unsigned gpio, unsigned level, uint32_t tick)
{
t2_count++;
}
void t2(int pi)
{
int dc, f, r, rr, oc, id;
printf("PWM dutycycle/range/frequency tests.\n");
set_PWM_range(pi, GPIO, 255);
set_PWM_frequency(pi, GPIO, 0);
f = get_PWM_frequency(pi, GPIO);
CHECK(2, 1, f, 10, 0, "set PWM range, set/get PWM frequency");
id = callback(pi, GPIO, EITHER_EDGE, t2cb);
set_PWM_dutycycle(pi, GPIO, 0);
dc = get_PWM_dutycycle(pi, GPIO);
CHECK(2, 2, dc, 0, 0, "get PWM dutycycle");
time_sleep(0.5); /* allow old notifications to flush */
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 3, f, 0, 0, "set PWM dutycycle, callback");
set_PWM_dutycycle(pi, GPIO, 128);
dc = get_PWM_dutycycle(pi, GPIO);
CHECK(2, 4, dc, 128, 0, "get PWM dutycycle");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 5, f, 40, 5, "set PWM dutycycle, callback");
set_PWM_frequency(pi, GPIO, 100);
f = get_PWM_frequency(pi, GPIO);
CHECK(2, 6, f, 100, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 7, f, 400, 1, "callback");
set_PWM_frequency(pi, GPIO, 1000);
f = get_PWM_frequency(pi, GPIO);
CHECK(2, 8, f, 1000, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 9, f, 4000, 1, "callback");
r = get_PWM_range(pi, GPIO);
CHECK(2, 10, r, 255, 0, "get PWM range");
rr = get_PWM_real_range(pi, GPIO);
CHECK(2, 11, rr, 200, 0, "get PWM real range");
set_PWM_range(pi, GPIO, 2000);
r = get_PWM_range(pi, GPIO);
CHECK(2, 12, r, 2000, 0, "set/get PWM range");
rr = get_PWM_real_range(pi, GPIO);
CHECK(2, 13, rr, 200, 0, "get PWM real range");
set_PWM_dutycycle(pi, GPIO, 0);
callback_cancel(id);
}
int t3_reset=1;
int t3_count=0;
uint32_t t3_tick=0;
float t3_on=0.0;
float t3_off=0.0;
void t3cbf(int pi, unsigned gpio, unsigned level, uint32_t tick)
{
uint32_t td;
// printf("pi=%d g=%d l=%d t=%u\n", pi, gpio, level, tick);
if (t3_reset)
{
t3_count = 0;
t3_on = 0.0;
t3_off = 0.0;
t3_reset = 0;
}
else
{
td = tick - t3_tick;
if (level == 0) t3_on += td;
else t3_off += td;
}
t3_count ++;
t3_tick = tick;
}
void t3(int pi)
{
int pw[3]={500, 1500, 2500};
int dc[4]={20, 40, 60, 80};
int f, rr, v;
float on, off;
int t, id;
printf("PWM/Servo pulse accuracy tests.\n");
id = callback(pi, GPIO, EITHER_EDGE, t3cbf);
for (t=0; t<3; t++)
{
set_servo_pulsewidth(pi, GPIO, pw[t]);
v = get_servo_pulsewidth(pi, GPIO);
CHECK(3, t+t+1, v, pw[t], 0, "get servo pulsewidth");
time_sleep(1);
t3_reset = 1;
time_sleep(4);
on = t3_on;
off = t3_off;
CHECK(3, t+t+2, (1000.0*(on+off))/on, 20000000.0/pw[t], 1,
"set servo pulsewidth");
}
set_servo_pulsewidth(pi, GPIO, 0);
set_PWM_frequency(pi, GPIO, 1000);
f = get_PWM_frequency(pi, GPIO);
CHECK(3, 7, f, 1000, 0, "set/get PWM frequency");
rr = set_PWM_range(pi, GPIO, 100);
CHECK(3, 8, rr, 200, 0, "set PWM range");
for (t=0; t<4; t++)
{
set_PWM_dutycycle(pi, GPIO, dc[t]);
v = get_PWM_dutycycle(pi, GPIO);
CHECK(3, t+t+9, v, dc[t], 0, "get PWM dutycycle");
time_sleep(1);
t3_reset = 1;
time_sleep(2);
on = t3_on;
off = t3_off;
CHECK(3, t+t+10, (1000.0*on)/(on+off), 10.0*dc[t], 1,
"set PWM dutycycle");
}
set_PWM_dutycycle(pi, GPIO, 0);
callback_cancel(id);
}
void t4(int pi)
{
int h, e, f, n, s, b, l, seq_ok, toggle_ok;
gpioReport_t r;
char p[32];
printf("Pipe notification tests.\n");
set_PWM_frequency(pi, GPIO, 0);
set_PWM_dutycycle(pi, GPIO, 0);
set_PWM_range(pi, GPIO, 100);
h = notify_open(pi);
e = notify_begin(pi, h, (1<<4));
CHECK(4, 1, e, 0, 0, "notify open/begin");
time_sleep(1);
sprintf(p, "/dev/pigpio%d", h);
f = open(p, O_RDONLY);
set_PWM_dutycycle(pi, GPIO, 50);
time_sleep(4);
set_PWM_dutycycle(pi, GPIO, 0);
e = notify_pause(pi, h);
CHECK(4, 2, e, 0, 0, "notify pause");
e = notify_close(pi, h);
CHECK(4, 3, e, 0, 0, "notify close");
n = 0;
s = 0;
l = 0;
seq_ok = 1;
toggle_ok = 1;
while (1)
{
b = read(f, &r, 12);
if (b == 12)
{
if (s != r.seqno) seq_ok = 0;
if (n) if (l != (r.level&(1<<4))) toggle_ok = 0;
if (r.level&(1<<4)) l = 0;
else l = (1<<4);
s++;
n++;
// printf("%d %d %d %X\n", r.seqno, r.flags, r.tick, r.level);
}
else break;
}
close(f);
CHECK(4, 4, seq_ok, 1, 0, "sequence numbers ok");
CHECK(4, 5, toggle_ok, 1, 0, "gpio toggled ok");
CHECK(4, 6, n, 80, 10, "number of notifications");
}
int t5_count = 0;
void t5cbf(int pi, unsigned gpio, unsigned level, uint32_t tick)
{
t5_count++;
}
void t5(int pi)
{
int BAUD=4800;
char *TEXT=
"\n\
Now is the winter of our discontent\n\
Made glorious summer by this sun of York;\n\
And all the clouds that lour'd upon our house\n\
In the deep bosom of the ocean buried.\n\
Now are our brows bound with victorious wreaths;\n\
Our bruised arms hung up for monuments;\n\
Our stern alarums changed to merry meetings,\n\
Our dreadful marches to delightful measures.\n\
Grim-visaged war hath smooth'd his wrinkled front;\n\
And now, instead of mounting barded steeds\n\
To fright the souls of fearful adversaries,\n\
He capers nimbly in a lady's chamber\n\
To the lascivious pleasing of a lute.\n\
";
gpioPulse_t wf[] =
{
{1<<GPIO, 0, 10000},
{0, 1<<GPIO, 30000},
{1<<GPIO, 0, 60000},
{0, 1<<GPIO, 100000},
};
int e, oc, c, wid, id;
char text[2048];
printf("Waveforms & serial read/write tests.\n");
id = callback(pi, GPIO, FALLING_EDGE, t5cbf);
set_mode(pi, GPIO, PI_OUTPUT);
e = wave_clear(pi);
CHECK(5, 1, e, 0, 0, "callback, set mode, wave clear");
e = wave_add_generic(pi, 4, wf);
CHECK(5, 2, e, 4, 0, "pulse, wave add generic");
wid = wave_create(pi);
e = wave_send_repeat(pi, wid);
CHECK(5, 3, e, 9, 0, "wave tx repeat");
oc = t5_count;
time_sleep(5.05);
c = t5_count - oc;
CHECK(5, 4, c, 50, 2, "callback");
e = wave_tx_stop(pi);
CHECK(5, 5, e, 0, 0, "wave tx stop");
e = bb_serial_read_open(pi, GPIO, BAUD, 8);
CHECK(5, 6, e, 0, 0, "serial read open");
wave_clear(pi);
e = wave_add_serial(pi, GPIO, BAUD, 8, 2, 5000000, strlen(TEXT), TEXT);
CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial");
wid = wave_create(pi);
e = wave_send_once(pi, wid);
CHECK(5, 8, e, 6811, 0, "wave tx start");
oc = t5_count;
time_sleep(3);
c = t5_count - oc;
CHECK(5, 9, c, 0, 0, "callback");
oc = t5_count;
while (wave_tx_busy(pi)) time_sleep(0.1);
time_sleep(0.1);
c = t5_count - oc;
CHECK(5, 10, c, 1702, 0, "wave tx busy, callback");
c = bb_serial_read(pi, GPIO, text, sizeof(text)-1);
if (c > 0) text[c] = 0; /* null terminate string */
CHECK(5, 11, strcmp(TEXT, text), 0, 0, "wave tx busy, serial read");
e = bb_serial_read_close(pi, GPIO);
CHECK(5, 12, e, 0, 0, "serial read close");
c = wave_get_micros(pi);
CHECK(5, 13, c, 6158148, 0, "wave get micros");
c = wave_get_high_micros(pi);
if (c > 6158148) c = 6158148;
CHECK(5, 14, c, 6158148, 0, "wave get high micros");
c = wave_get_max_micros(pi);
CHECK(5, 15, c, 1800000000, 0, "wave get max micros");
c = wave_get_pulses(pi);
CHECK(5, 16, c, 3405, 0, "wave get pulses");
c = wave_get_high_pulses(pi);
CHECK(5, 17, c, 3405, 0, "wave get high pulses");
c = wave_get_max_pulses(pi);
CHECK(5, 18, c, 12000, 0, "wave get max pulses");
c = wave_get_cbs(pi);
CHECK(5, 19, c, 6810, 0, "wave get cbs");
c = wave_get_high_cbs(pi);
CHECK(5, 20, c, 6810, 0, "wave get high cbs");
c = wave_get_max_cbs(pi);
CHECK(5, 21, c, 25016, 0, "wave get max cbs");
callback_cancel(id);
}
int t6_count=0;
int t6_on=0;
uint32_t t6_on_tick=0;
void t6cbf(int pi, unsigned gpio, unsigned level, uint32_t tick)
{
if (level == 1)
{
t6_on_tick = tick;
t6_count++;
}
else
{
if (t6_on_tick) t6_on += (tick - t6_on_tick);
}
}
void t6(int pi)
{
int tp, t, p, id;
printf("Trigger tests.\n");
gpio_write(pi, GPIO, PI_LOW);
tp = 0;
id = callback(pi, GPIO, EITHER_EDGE, t6cbf);
time_sleep(0.2);
for (t=0; t<5; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
gpio_trigger(pi, GPIO, p, 1);
}
time_sleep(0.5);
CHECK(6, 1, t6_count, 5, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
callback_cancel(id);
}
int t7_count=0;
void t7cbf(int pi, unsigned gpio, unsigned level, uint32_t tick)
{
if (level == PI_TIMEOUT) t7_count++;
}
void t7(int pi)
{
int c, oc, id;
printf("Watchdog tests.\n");
/* type of edge shouldn't matter for watchdogs */
id = callback(pi, GPIO, FALLING_EDGE, t7cbf);
set_watchdog(pi, GPIO, 10); /* 10 ms, 100 per second */
time_sleep(0.5);
oc = t7_count;
time_sleep(2);
c = t7_count - oc;
CHECK(7, 1, c, 200, 1, "set watchdog on count");
set_watchdog(pi, GPIO, 0); /* 0 switches watchdog off */
time_sleep(0.5);
oc = t7_count;
time_sleep(2);
c = t7_count - oc;
CHECK(7, 2, c, 0, 1, "set watchdog off count");
callback_cancel(id);
}
void t8(int pi)
{
int v, t, i;
printf("Bank read/write tests.\n");
gpio_write(pi, GPIO, 0);
v = read_bank_1(pi) & (1<<GPIO);
CHECK(8, 1, v, 0, 0, "read bank 1");
gpio_write(pi, GPIO, 1);
v = read_bank_1(pi) & (1<<GPIO);
CHECK(8, 2, v, (1<<GPIO), 0, "read bank 1");
clear_bank_1(pi, 1<<GPIO);
v = gpio_read(pi, GPIO);
CHECK(8, 3, v, 0, 0, "clear bank 1");
set_bank_1(pi, 1<<GPIO);
v = gpio_read(pi, GPIO);
CHECK(8, 4, v, 1, 0, "set bank 1");
t = 0;
v = (1<<16);
for (i=0; i<100; i++)
{
if (read_bank_2(pi) & v) t++;
};
CHECK(8, 5, t, 60, 75, "read bank 2");
v = clear_bank_2(pi, 0);
CHECK(8, 6, v, 0, 0, "clear bank 2");
v = clear_bank_2(pi, 0xffffff);
CHECK(8, 7, v, PI_SOME_PERMITTED, 0, "clear bank 2");
v = set_bank_2(pi, 0);
CHECK(8, 8, v, 0, 0, "set bank 2");
v = set_bank_2(pi, 0xffffff);
CHECK(8, 9, v, PI_SOME_PERMITTED, 0, "set bank 2");
}
int t9_count = 0;
void t9cbf(int pi, unsigned gpio, unsigned level, uint32_t tick)
{
t9_count++;
}
void t9(int pi)
{
int s, oc, c, e, id;
uint32_t p[10];
printf("Script store/run/status/stop/delete tests.\n");
gpio_write(pi, GPIO, 0); /* need known state */
/*
100 loops per second
p0 number of loops
p1 GPIO
*/
char *script="\
ld p9 p0\
tag 0\
w p1 1\
mils 5\
w p1 0\
mils 5\
dcr p9\
jp 0";
id = callback(pi, GPIO, RISING_EDGE, t9cbf);
s = store_script(pi, script);
/* Wait for script to finish initing. */
while (1)
{
time_sleep(0.1);
e = script_status(pi, s, p);
if (e != PI_SCRIPT_INITING) break;
}
oc = t9_count;
p[0] = 99;
p[1] = GPIO;
run_script(pi, s, 2, p);
time_sleep(2);
c = t9_count - oc;
CHECK(9, 1, c, 100, 0, "store/run script");
oc = t9_count;
p[0] = 200;
p[1] = GPIO;
run_script(pi, s, 2, p);
while (1)
{
time_sleep(0.1);
e = script_status(pi, s, p);
if (e != PI_SCRIPT_RUNNING) break;
}
c = t9_count - oc;
time_sleep(0.1);
CHECK(9, 2, c, 201, 0, "run script/script status");
oc = t9_count;
p[0] = 2000;
p[1] = GPIO;
run_script(pi, s, 2, p);
while (1)
{
time_sleep(0.1);
e = script_status(pi, s, p);
if (e != PI_SCRIPT_RUNNING) break;
if (p[9] < 1600) stop_script(pi, s);
}
c = t9_count - oc;
time_sleep(0.1);
CHECK(9, 3, c, 410, 10, "run/stop script/script status");
e = delete_script(pi, s);
CHECK(9, 4, e, 0, 0, "delete script");
callback_cancel(id);
}
void ta(int pi)
{
int h, b, e;
char *TEXT;
char text[2048];
printf("Serial link tests.\n");
/* this test needs RXD and TXD to be connected */
h = serial_open(pi, "/dev/ttyAMA0", 57600, 0);
CHECK(10, 1, h, 0, 0, "serial open");
time_sleep(0.1); /* allow time for transmission */
b = serial_read(pi, h, text, sizeof(text)); /* flush buffer */
b = serial_data_available(pi, h);
CHECK(10, 2, b, 0, 0, "serial data available");
TEXT = "\
To be, or not to be, that is the question-\
Whether 'tis Nobler in the mind to suffer\
The Slings and Arrows of outrageous Fortune,\
Or to take Arms against a Sea of troubles,\
";
e = serial_write(pi, h, TEXT, strlen(TEXT));
CHECK(10, 3, e, 0, 0, "serial write");
e = serial_write_byte(pi, h, 0xAA);
e = serial_write_byte(pi, h, 0x55);
e = serial_write_byte(pi, h, 0x00);
e = serial_write_byte(pi, h, 0xFF);
CHECK(10, 4, e, 0, 0, "serial write byte");
time_sleep(0.1); /* allow time for transmission */
b = serial_data_available(pi, h);
CHECK(10, 5, b, strlen(TEXT)+4, 0, "serial data available");
b = serial_read(pi, h, text, strlen(TEXT));
CHECK(10, 6, b, strlen(TEXT), 0, "serial read");
if (b >= 0) text[b] = 0;
CHECK(10, 7, strcmp(TEXT, text), 0, 0, "serial read");
b = serial_read_byte(pi, h);
CHECK(10, 8, b, 0xAA, 0, "serial read byte");
b = serial_read_byte(pi, h);
CHECK(10, 9, b, 0x55, 0, "serial read byte");
b = serial_read_byte(pi, h);
CHECK(10, 10, b, 0x00, 0, "serial read byte");
b = serial_read_byte(pi, h);
CHECK(10, 11, b, 0xFF, 0, "serial read byte");
b = serial_data_available(pi, h);
CHECK(10, 12, b, 0, 0, "serial data availabe");
e = serial_close(pi, h);
CHECK(10, 13, e, 0, 0, "serial close");
}
void tb(int pi)
{
int h, e, b, len;
char *exp;
char buf[128];
printf("SMBus / I2C tests.");
/* this test requires an ADXL345 on I2C bus 1 addr 0x53 */
h = i2c_open(pi, 1, 0x53, 0);
CHECK(11, 1, h, 0, 0, "i2c open");
e = i2c_write_device(pi, h, "\x00", 1); /* move to known register */
CHECK(11, 2, e, 0, 0, "i2c write device");
b = i2c_read_device(pi, h, buf, 1);
CHECK(11, 3, b, 1, 0, "i2c read device");
CHECK(11, 4, buf[0], 0xE5, 0, "i2c read device");
b = i2c_read_byte(pi, h);
CHECK(11, 5, b, 0xE5, 0, "i2c read byte");
b = i2c_read_byte_data(pi, h, 0);
CHECK(11, 6, b, 0xE5, 0, "i2c read byte data");
b = i2c_read_byte_data(pi, h, 48);
CHECK(11, 7, b, 2, 0, "i2c read byte data");
exp = "\x1D[aBcDeFgHjKM]";
len = strlen(exp);
e = i2c_write_device(pi, h, exp, len);
CHECK(11, 8, e, 0, 0, "i2c write device");
e = i2c_write_device(pi, h, "\x1D", 1);
b = i2c_read_device(pi, h, buf, len-1);
CHECK(11, 9, b, len-1, 0, "i2c read device");
CHECK(11, 10, strncmp(buf, exp+1, len-1), 0, 0, "i2c read device");
if (strncmp(buf, exp+1, len-1))
printf("got [%.*s] expected [%.*s]\n", len-1, buf, len-1, exp+1);
e = i2c_write_byte_data(pi, h, 0x1d, 0xAA);
CHECK(11, 11, e, 0, 0, "i2c write byte data");
b = i2c_read_byte_data(pi, h, 0x1d);
CHECK(11, 12, b, 0xAA, 0, "i2c read byte data");
e = i2c_write_byte_data(pi, h, 0x1d, 0x55);
CHECK(11, 13, e, 0, 0, "i2c write byte data");
b = i2c_read_byte_data(pi, h, 0x1d);
CHECK(11, 14, b, 0x55, 0, "i2c read byte data");
exp = "[1234567890#]";
len = strlen(exp);
e = i2c_write_block_data(pi, h, 0x1C, exp, len);
CHECK(11, 15, e, 0, 0, "i2c write block data");
e = i2c_write_device(pi, h, "\x1D", 1);
b = i2c_read_device(pi, h, buf, len);
CHECK(11, 16, b, len, 0, "i2c read device");
CHECK(11, 17, strncmp(buf, exp, len), 0, 0, "i2c read device");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
b = i2c_read_i2c_block_data(pi, h, 0x1D, buf, len);
CHECK(11, 18, b, len, 0, "i2c read i2c block data");
CHECK(11, 19, strncmp(buf, exp, len), 0, 0, "i2c read i2c block data");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
exp = "(-+=;:,<>!%)";
len = strlen(exp);
e = i2c_write_i2c_block_data(pi, h, 0x1D, exp, len);
CHECK(11, 20, e, 0, 0, "i2c write i2c block data");
b = i2c_read_i2c_block_data(pi, h, 0x1D, buf, len);
CHECK(11, 21, b, len, 0, "i2c read i2c block data");
CHECK(11, 22, strncmp(buf, exp, len), 0, 0, "i2c read i2c block data");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
e = i2c_close(pi, h);
CHECK(11, 23, e, 0, 0, "i2c close");
}
void tc(int pi)
{
int h, x, b, e;
char buf[128];
printf("SPI tests.");
/* this test requires a MCP3202 on SPI channel 1 */
h = spi_open(pi, 1, 50000, 0);
CHECK(12, 1, h, 0, 0, "spi open");
for (x=0; x<5; x++)
{
sprintf(buf, "\x01\x80");
b = spi_xfer(pi, h, buf, buf, 3);
CHECK(12, 2, b, 3, 0, "spi xfer");
if (b == 3)
{
time_sleep(1.0);
printf("%d ", ((buf[1]&0x0F)*256)|buf[2]);
}
}
e = spi_close(pi, h);
CHECK(12, 99, e, 0, 0, "spi close");
}
int main(int argc, char *argv[])
{
int i, t, c, pi;
char test[64];
if (argc > 1)
{
t = 0;
for (i=0; i<strlen(argv[1]); i++)
{
c = tolower(argv[1][i]);
if (!strchr(test, c))
{
test[t++] = c;
test[t] = 0;
}
}
}
else strcat(test, "0123456789");
pi = pigpio_start(0, 0);
if (pi < 0)
{
fprintf(stderr, "pigpio initialisation failed (%d).\n", pi);
return 1;
}
printf("Connected to pigpio daemon (%d).\n", pi);
if (strchr(test, '0')) t0(pi);
if (strchr(test, '1')) t1(pi);
if (strchr(test, '2')) t2(pi);
if (strchr(test, '3')) t3(pi);
if (strchr(test, '4')) t4(pi);
if (strchr(test, '5')) t5(pi);
if (strchr(test, '6')) t6(pi);
if (strchr(test, '7')) t7(pi);
if (strchr(test, '8')) t8(pi);
if (strchr(test, '9')) t9(pi);
if (strchr(test, 'a')) ta(pi);
if (strchr(test, 'b')) tb(pi);
if (strchr(test, 'c')) tc(pi);
pigpio_stop(pi);
return 0;
}