mirror of https://github.com/joan2937/pigpio
This commit is contained in:
parent
56b5f62885
commit
3e7e75ea29
36
Makefile
36
Makefile
|
@ -5,7 +5,9 @@ SIZE = size
|
||||||
|
|
||||||
CFLAGS = -O3 -Wall
|
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
|
checklib: checklib.o libpigpio.a
|
||||||
$(CC) -o checklib checklib.c -L. -lpigpio -lpthread -lrt
|
$(CC) -o checklib checklib.c -L. -lpigpio -lpthread -lrt
|
||||||
|
@ -19,31 +21,29 @@ pig2vcd: pig2vcd.o
|
||||||
pigpiod: pigpiod.o libpigpio.a
|
pigpiod: pigpiod.o libpigpio.a
|
||||||
$(CC) -o pigpiod pigpiod.c -L. -lpigpio -lpthread -lrt
|
$(CC) -o pigpiod pigpiod.c -L. -lpigpio -lpthread -lrt
|
||||||
|
|
||||||
pigs: pigs.o command.o
|
pigs: command.o
|
||||||
$(CC) -o pigs pigs.c command.c
|
$(CC) -o pigs pigs.c command.c
|
||||||
|
|
||||||
.c.o:
|
|
||||||
$(CC) -c $(CFLAGS) $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.i *.s *~ libpigpio.a checklib demolib pigpiod pigs pig2vcd
|
rm -f *.o *.i *.s *~ $(ALL)
|
||||||
|
|
||||||
install: $(LIB)
|
install: $(LIB)
|
||||||
sudo install -m 0755 -d /usr/local/bin
|
|
||||||
sudo install -m 0755 -d /usr/local/include
|
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 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 pig2vcd /usr/local/bin
|
||||||
sudo install -m 0755 pigpiod /usr/local/bin
|
sudo install -m 0755 pigpiod /usr/local/bin
|
||||||
sudo install -m 0755 pigs /usr/local/bin
|
sudo install -m 0755 pigs /usr/local/bin
|
||||||
sudo install -m 0644 pigpio.h /usr/local/include
|
sudo python setup.py install
|
||||||
sudo install -m 0644 libpigpio.a /usr/local/lib
|
|
||||||
|
|
||||||
uninstall:
|
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/pig2vcd
|
||||||
sudo rm -f /usr/local/bin/pigpiod
|
sudo rm -f /usr/local/bin/pigpiod
|
||||||
sudo rm -f /usr/local/bin/pigs
|
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
|
LIB = libpigpio.a
|
||||||
OBJ = pigpio.o command.o
|
OBJ = pigpio.o command.o
|
||||||
|
@ -53,11 +53,13 @@ $(LIB): $(OBJ)
|
||||||
$(RANLIB) $(LIB)
|
$(RANLIB) $(LIB)
|
||||||
$(SIZE) $(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
28
README
|
@ -15,6 +15,7 @@ This will install:
|
||||||
the daemon (pigpiod) in /usr/local/bin
|
the daemon (pigpiod) in /usr/local/bin
|
||||||
the socket interface (pigs) in /usr/local/bin
|
the socket interface (pigs) in /usr/local/bin
|
||||||
the utility pig2vcd in /usr/local/bin
|
the utility pig2vcd in /usr/local/bin
|
||||||
|
the Python module pigpio.py
|
||||||
|
|
||||||
TEST
|
TEST
|
||||||
|
|
||||||
|
@ -22,8 +23,8 @@ To test the library do
|
||||||
|
|
||||||
sudo ./checklib
|
sudo ./checklib
|
||||||
|
|
||||||
checklib.c, demolib.c, pig2vcd.c, pigpiod.c, and pigs.c show examples
|
checklib.c, demolib.c, pig2vcd.c, pigpiod.c, pigs.c, and pigpio.py
|
||||||
of interfacing with the library.
|
show examples of interfacing with the library.
|
||||||
|
|
||||||
DAEMON
|
DAEMON
|
||||||
|
|
||||||
|
@ -59,9 +60,30 @@ cat /dev/pigerr &
|
||||||
|
|
||||||
echo "help" >/dev/pigpio
|
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
|
STOP DAEMON
|
||||||
|
|
||||||
To stop the daemon
|
To stop the pigpiod daemon
|
||||||
|
|
||||||
sudo killall pigpiod
|
sudo killall pigpiod
|
||||||
|
|
||||||
|
|
|
@ -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>
|
#include <stdio.h>
|
||||||
|
@ -141,7 +141,7 @@ static errInfo_t errInfo[]=
|
||||||
{PI_BAD_CLK_SOURCE , "clock source not 0-1"},
|
{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_CLK_MICROS , "clock micros not 1, 2, 4, 5, 8, or 10"},
|
||||||
{PI_BAD_BUF_MILLIS , "buf millis not 100-10000"},
|
{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_SIGNUM , "signum not 0-63"},
|
||||||
{PI_BAD_PATHNAME , "can't open pathname"},
|
{PI_BAD_PATHNAME , "can't open pathname"},
|
||||||
{PI_NO_HANDLE , "no handle available"},
|
{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_PULSES , "waveform has too many pulses"},
|
||||||
{PI_TOO_MANY_CHARS , "waveform has too many chars"},
|
{PI_TOO_MANY_CHARS , "waveform has too many chars"},
|
||||||
{PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"},
|
{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";
|
static char * fmtMdeStr="RW540123";
|
||||||
|
@ -289,4 +290,3 @@ char * cmdErrStr(int error)
|
||||||
}
|
}
|
||||||
return "unknown error";
|
return "unknown error";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
command.h
10
command.h
|
@ -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
|
#ifndef COMMAND_H
|
||||||
|
@ -39,10 +39,10 @@ This version is for pigpio version 3+
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int cmd;
|
int cmd; /* command number */
|
||||||
char * name;
|
char * name; /* command name */
|
||||||
int vt;
|
int vt; /* command verification type */
|
||||||
int rv;
|
int rv; /* command return value type */
|
||||||
} cmdInfo_t;
|
} cmdInfo_t;
|
||||||
|
|
||||||
extern cmdInfo_t cmdInfo[];
|
extern cmdInfo_t cmdInfo[];
|
||||||
|
|
251
pigpio.c
251
pigpio.c
|
@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||||
For more information, please refer to <http://unlicense.org/>
|
For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* pigpio version 6 */
|
/* pigpio version 7 */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -229,6 +229,13 @@ bit 0 READ_LAST_NOT_SET_ERROR
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
|
#define PERM_ERROR(format, arg...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
fprintf(stderr, "%s " format "\n", myTimeStamp(), ## arg); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
#define TIMER_ADD(a, b, result) \
|
#define TIMER_ADD(a, b, result) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
|
@ -519,8 +526,6 @@ bit 0 READ_LAST_NOT_SET_ERROR
|
||||||
#define PI_WFRX_SERIAL 1
|
#define PI_WFRX_SERIAL 1
|
||||||
#define PI_WF_MICROS 2
|
#define PI_WF_MICROS 2
|
||||||
|
|
||||||
#define PI_WAVE_MAX_PULSES 3000
|
|
||||||
|
|
||||||
#define DATUMS 2000
|
#define DATUMS 2000
|
||||||
|
|
||||||
#define DEFAULT_PWM_IDX 5
|
#define DEFAULT_PWM_IDX 5
|
||||||
|
@ -704,12 +709,16 @@ static volatile gpioCfg_t gpioCfg =
|
||||||
|
|
||||||
static volatile gpioStats_t gpioStats;
|
static volatile gpioStats_t gpioStats;
|
||||||
|
|
||||||
|
static int gpioMaskSet = 0;
|
||||||
|
|
||||||
/* initialise every gpioInitialise */
|
/* initialise every gpioInitialise */
|
||||||
|
|
||||||
static struct timespec libStarted;
|
static struct timespec libStarted;
|
||||||
|
|
||||||
/* initialse if not libInitialised */
|
/* initialse if not libInitialised */
|
||||||
|
|
||||||
|
static uint64_t gpioMask;
|
||||||
|
|
||||||
static gpioPulse_t wf[3][PI_WAVE_MAX_PULSES];
|
static gpioPulse_t wf[3][PI_WAVE_MAX_PULSES];
|
||||||
|
|
||||||
static int wfc[3]={0, 0, 0};
|
static int wfc[3]={0, 0, 0};
|
||||||
|
@ -732,7 +741,6 @@ static volatile uint32_t notifyBits = 0;
|
||||||
static volatile int DMAstarted = 0;
|
static volatile int DMAstarted = 0;
|
||||||
|
|
||||||
static int libInitialised = 0;
|
static int libInitialised = 0;
|
||||||
static unsigned hardwareRevision = 0;
|
|
||||||
|
|
||||||
static int pthAlertRunning = 0;
|
static int pthAlertRunning = 0;
|
||||||
static int pthFifoRunning = 0;
|
static int pthFifoRunning = 0;
|
||||||
|
@ -947,6 +955,7 @@ static uint32_t myGetTick(int pos)
|
||||||
static void myDoCommand(cmdCmd_t * cmd)
|
static void myDoCommand(cmdCmd_t * cmd)
|
||||||
{
|
{
|
||||||
int p1, p2, res;
|
int p1, p2, res;
|
||||||
|
uint32_t mask;
|
||||||
|
|
||||||
p1 = cmd->p1;
|
p1 = cmd->p1;
|
||||||
p2 = cmd->p2;
|
p2 = cmd->p2;
|
||||||
|
@ -956,7 +965,12 @@ static void myDoCommand(cmdCmd_t * cmd)
|
||||||
switch (cmd->cmd)
|
switch (cmd->cmd)
|
||||||
{
|
{
|
||||||
case PI_CMD_MODES:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_MODEG:
|
case PI_CMD_MODEG:
|
||||||
|
@ -964,7 +978,12 @@ static void myDoCommand(cmdCmd_t * cmd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PI_CMD_PUD:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_READ:
|
case PI_CMD_READ:
|
||||||
|
@ -972,23 +991,48 @@ static void myDoCommand(cmdCmd_t * cmd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PI_CMD_WRITE:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_PWM:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_PRS:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_PFS:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_SERVO:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_WDOG:
|
case PI_CMD_WDOG:
|
||||||
|
@ -1004,19 +1048,55 @@ static void myDoCommand(cmdCmd_t * cmd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PI_CMD_BC1:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_BC2:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_BS1:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_BS2:
|
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;
|
break;
|
||||||
|
|
||||||
case PI_CMD_TICK:
|
case PI_CMD_TICK:
|
||||||
|
@ -1274,7 +1354,7 @@ static void waveCbOPrint(int pos)
|
||||||
|
|
||||||
p = waveCbVOadr(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);
|
p->info, p->src, p->dst, p->length, p->stride, p->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1669,7 +1749,7 @@ static void dmaCbPrint(int pos)
|
||||||
|
|
||||||
p = dmaCB2adr(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);
|
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);
|
DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel);
|
||||||
}
|
}
|
||||||
|
else if (signum == SIGPIPE)
|
||||||
|
{
|
||||||
|
DBG(DBG_USER, "SIGPIPE received");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* close library safely and exit */
|
/* exit */
|
||||||
|
|
||||||
DBG(DBG_USER, "Unhandled signal %d, terminating\n", signum);
|
DBG(DBG_MIN_LEVEL, "Unhandled signal %d, terminating\n", signum);
|
||||||
|
|
||||||
gpioTerminate();
|
|
||||||
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -1976,11 +2058,9 @@ static void sigHandler(int signum)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* close library safely and exit */
|
/* exit */
|
||||||
|
|
||||||
DBG(DBG_USER, "Unhandled signal %d, terminating\n", signum);
|
DBG(DBG_MIN_LEVEL, "Unhandled signal %d, terminating\n", signum);
|
||||||
|
|
||||||
gpioTerminate();
|
|
||||||
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -2424,7 +2504,6 @@ static void * pthTimerTick(void *x)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -2465,6 +2544,7 @@ static void * pthFifoThread(void *x)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
fprintf(outFifo, "%d\n", cmd.res);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -2860,7 +2940,7 @@ static int initDMAcbs(void)
|
||||||
/* allocate memory for pointers to virtual and physical pages */
|
/* allocate memory for pointers to virtual and physical pages */
|
||||||
|
|
||||||
dmaBloc = mmap(
|
dmaBloc = mmap(
|
||||||
0, (bufferBlocks+1)*sizeof(dmaPage_t *),
|
0, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
|
||||||
PROT_READ|PROT_WRITE,
|
PROT_READ|PROT_WRITE,
|
||||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
|
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
@ -2869,7 +2949,7 @@ static int initDMAcbs(void)
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
|
SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
|
||||||
|
|
||||||
dmaVirt = mmap(
|
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,
|
PROT_READ|PROT_WRITE,
|
||||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
|
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
@ -2878,7 +2958,7 @@ static int initDMAcbs(void)
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
|
SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
|
||||||
|
|
||||||
dmaPhys = mmap(
|
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,
|
PROT_READ|PROT_WRITE,
|
||||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
|
MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
@ -2901,7 +2981,7 @@ static int initDMAcbs(void)
|
||||||
if (pagemapFd < 0)
|
if (pagemapFd < 0)
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "open pagemap failed(%m)");
|
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);
|
close(pagemapFd);
|
||||||
|
|
||||||
|
@ -2918,7 +2998,10 @@ static int initDMAcbs(void)
|
||||||
dmaInitCbs();
|
dmaInitCbs();
|
||||||
|
|
||||||
if (gpioCfg.dbgLevel >= DBG_DMACBS)
|
if (gpioCfg.dbgLevel >= DBG_DMACBS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** INPUT DMA CONTROL BLOCKS ***\n");
|
||||||
for (i=0; i<NUM_CBS; i++) dmaCbPrint(i);
|
for (i=0; i<NUM_CBS; i++) dmaCbPrint(i);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3132,7 +3215,6 @@ static void initClearGlobals(void)
|
||||||
|
|
||||||
libInitialised = 0;
|
libInitialised = 0;
|
||||||
DMAstarted = 0;
|
DMAstarted = 0;
|
||||||
hardwareRevision = 0;
|
|
||||||
|
|
||||||
pthAlertRunning = 0;
|
pthAlertRunning = 0;
|
||||||
pthFifoRunning = 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)
|
static void initReleaseResources(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -3299,7 +3350,7 @@ static void initReleaseResources(void)
|
||||||
/* release mmap'd memory */
|
/* release mmap'd memory */
|
||||||
|
|
||||||
if (clkReg != MAP_FAILED) munmap((void *)clkReg, CLK_LEN);
|
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 (gpioReg != MAP_FAILED) munmap((void *)gpioReg, GPIO_LEN);
|
||||||
if (pcmReg != MAP_FAILED) munmap((void *)pcmReg, PCM_LEN);
|
if (pcmReg != MAP_FAILED) munmap((void *)pcmReg, PCM_LEN);
|
||||||
if (pwmReg != MAP_FAILED) munmap((void *)pwmReg, PWM_LEN);
|
if (pwmReg != MAP_FAILED) munmap((void *)pwmReg, PWM_LEN);
|
||||||
|
@ -3314,36 +3365,36 @@ static void initReleaseResources(void)
|
||||||
|
|
||||||
if (dmaVirt != MAP_FAILED)
|
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[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;
|
dmaVirt = MAP_FAILED;
|
||||||
|
|
||||||
if (dmaPhys != 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[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;
|
dmaPhys = MAP_FAILED;
|
||||||
|
|
||||||
if (dmaBloc != 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[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;
|
dmaBloc = MAP_FAILED;
|
||||||
|
@ -3403,6 +3454,17 @@ int gpioInitialise(void)
|
||||||
if (fdLock < 0)
|
if (fdLock < 0)
|
||||||
SOFT_ERROR(PI_INIT_FAILED, "Can't lock %s", PI_LOCKFILE);
|
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();
|
sigSetHandler();
|
||||||
|
|
||||||
if (initPeripherals() < 0) return PI_INIT_FAILED;
|
if (initPeripherals() < 0) return PI_INIT_FAILED;
|
||||||
|
@ -3450,8 +3512,6 @@ int gpioInitialise(void)
|
||||||
pthSocketRunning = 1;
|
pthSocketRunning = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hardwareRevision = initHardwareRevision();
|
|
||||||
|
|
||||||
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
|
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
|
||||||
|
|
||||||
return PIGPIO_VERSION;
|
return PIGPIO_VERSION;
|
||||||
|
@ -3465,6 +3525,7 @@ void gpioTerminate(void)
|
||||||
|
|
||||||
DBG(DBG_USER, "");
|
DBG(DBG_USER, "");
|
||||||
|
|
||||||
|
gpioMaskSet = 0;
|
||||||
|
|
||||||
if (libInitialised)
|
if (libInitialised)
|
||||||
{
|
{
|
||||||
|
@ -3716,7 +3777,7 @@ int gpioSetPWMrange(unsigned gpio, unsigned range)
|
||||||
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
|
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
|
||||||
|
|
||||||
if ((range < PI_MIN_DUTYCYCLE_RANGE) || (range > PI_MAX_DUTYCYCLE_RANGE))
|
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;
|
oldWidth = gpioInfo[gpio].width;
|
||||||
|
|
||||||
|
@ -4247,7 +4308,10 @@ int gpioWaveTxStart(unsigned mode)
|
||||||
cb = wave2Cbs(mode);
|
cb = wave2Cbs(mode);
|
||||||
|
|
||||||
if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
|
if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
|
||||||
for (i=0; i<cb; i++) waveCbOPrint(i);
|
for (i=0; i<cb; i++) waveCbOPrint(i);
|
||||||
|
}
|
||||||
|
|
||||||
initDMAgo((uint32_t *)dmaOut, (uint32_t)dmaOPhys[0]);
|
initDMAgo((uint32_t *)dmaOut, (uint32_t)dmaOPhys[0]);
|
||||||
|
|
||||||
|
@ -4899,11 +4963,34 @@ uint32_t gpioTick(void)
|
||||||
|
|
||||||
unsigned gpioHardwareRevision(void)
|
unsigned gpioHardwareRevision(void)
|
||||||
{
|
{
|
||||||
|
static unsigned rev = 0;
|
||||||
|
|
||||||
|
FILE * filp;
|
||||||
|
char buf[512];
|
||||||
|
char term;
|
||||||
|
|
||||||
DBG(DBG_USER, "");
|
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)
|
int gpioCfgInterfaces(unsigned ifFlags)
|
||||||
|
|
44
pigpio.h
44
pigpio.h
|
@ -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
|
#ifndef PIGPIO_H
|
||||||
|
@ -82,7 +82,7 @@ This version is for pigpio version 6
|
||||||
|
|
||||||
#include <stdint.h>
|
#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.
|
gpioCfgBufferSize Configure the gpio sample buffer size.
|
||||||
gpioCfgClock Configure the gpio sample rate.
|
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.
|
gpioCfgInterfaces Configure user interfaces.
|
||||||
gpioCfgSocketPort Configure socket port.
|
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).
|
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,
|
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:
|
EXAMPLE:
|
||||||
...
|
...
|
||||||
|
@ -892,9 +894,12 @@ int gpioWaveAddSerial(unsigned user_gpio,
|
||||||
the same waveform.
|
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_MIN_BAUD 100
|
||||||
#define PI_WAVE_MAX_BAUD 250000
|
#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.
|
/* Configures pigpio to use the specified DMA channel.
|
||||||
|
|
||||||
|
@ -1622,7 +1627,7 @@ int gpioCfgDMAchannels(unsigned primaryChannel,
|
||||||
/* Configures pigpio to use the specified DMA channels.
|
/* Configures pigpio to use the specified DMA channels.
|
||||||
|
|
||||||
The default setting is to use channel 14 for the primary channel and
|
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
|
#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);
|
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_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_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_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_SIGNUM -22 /* signum not 0-63 */
|
||||||
#define PI_BAD_PATHNAME -23 /* can't open pathname */
|
#define PI_BAD_PATHNAME -23 /* can't open pathname */
|
||||||
#define PI_NO_HANDLE -24 /* no handle available */
|
#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_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_STRUC -39 /* bad null serial structure parameter */
|
||||||
#define PI_BAD_SERIAL_BUF -40 /* bad null serial buf 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_IF_FLAGS 0
|
||||||
#define PI_DEFAULT_DMA_CHANNEL 14
|
#define PI_DEFAULT_DMA_CHANNEL 14
|
||||||
#define PI_DEFAULT_DMA_PRIMARY_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 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
|
#endif
|
||||||
|
|
||||||
|
|
37
pigpiod.c
37
pigpiod.c
|
@ -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>
|
#include <sys/types.h>
|
||||||
|
@ -54,8 +54,10 @@ static unsigned clockMicros = PI_DEFAULT_CLK_MICROS;
|
||||||
static unsigned clockPeripheral = PI_DEFAULT_CLK_PERIPHERAL;
|
static unsigned clockPeripheral = PI_DEFAULT_CLK_PERIPHERAL;
|
||||||
static unsigned clockSource = PI_DEFAULT_CLK_SOURCE;
|
static unsigned clockSource = PI_DEFAULT_CLK_SOURCE;
|
||||||
static unsigned ifFlags = PI_DEFAULT_IF_FLAGS;
|
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 unsigned socketPort = PI_DEFAULT_SOCKET_PORT;
|
||||||
|
static uint64_t updateMask = -1;
|
||||||
|
|
||||||
static FILE * errFifo;
|
static FILE * errFifo;
|
||||||
|
|
||||||
|
@ -64,13 +66,15 @@ void usage()
|
||||||
fprintf(stderr, "\n" \
|
fprintf(stderr, "\n" \
|
||||||
"Usage: sudo pigpiod [OPTION] ...\n" \
|
"Usage: sudo pigpiod [OPTION] ...\n" \
|
||||||
" -b value, gpio sample buffer in milliseconds, default 120\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" \
|
" -f, disable fifo interface, default enabled\n" \
|
||||||
" -k, disable socket interface, default enabled\n" \
|
" -k, disable socket interface, default enabled\n" \
|
||||||
" -p value, socket port, 1024-32000, default 8888\n" \
|
" -p value, socket port, 1024-32000, default 8888\n" \
|
||||||
" -s value, sample rate, 1, 2, 4, 5, 8, or 10, default 5\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" \
|
" -t value, clock peripheral, 0=PWM 1=PCM, default PCM\n" \
|
||||||
" -u value, clock source, 0=OSC 1=PLLD, default PLLD\n" \
|
" -u value, clock source, 0=OSC 1=PLLD, default PLLD\n" \
|
||||||
|
" -x mask, gpios which may be updated, default 0xFFFFFFFF\n" \
|
||||||
"EXAMPLE\n" \
|
"EXAMPLE\n" \
|
||||||
"sudo pigpiod -s 2 -b 200 -f\n" \
|
"sudo pigpiod -s 2 -b 200 -f\n" \
|
||||||
" Set a sample rate of 2 microseconds with a 200 millisecond\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[])
|
static void initOpts(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, opt;
|
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;
|
i = -1;
|
||||||
|
|
||||||
|
@ -97,11 +103,18 @@ static void initOpts(int argc, char *argv[])
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
i = atoi(optarg);
|
i = atoi(optarg);
|
||||||
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_DMA_CHANNEL))
|
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_PRIMARY_CHANNEL))
|
||||||
DMAchannelChannel = i;
|
DMAprimaryChannel = i;
|
||||||
else cmdFatal("invalid -d option (%d)", i);
|
else cmdFatal("invalid -d option (%d)", i);
|
||||||
break;
|
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':
|
case 'f':
|
||||||
ifFlags |= PI_DISABLE_FIFO_IF;
|
ifFlags |= PI_DISABLE_FIFO_IF;
|
||||||
break;
|
break;
|
||||||
|
@ -151,6 +164,13 @@ static void initOpts(int argc, char *argv[])
|
||||||
else cmdFatal("invalid -u option (%d)", i);
|
else cmdFatal("invalid -u option (%d)", i);
|
||||||
break;
|
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: /* '?' */
|
default: /* '?' */
|
||||||
usage();
|
usage();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
@ -224,10 +244,12 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
gpioCfgInterfaces(ifFlags);
|
gpioCfgInterfaces(ifFlags);
|
||||||
|
|
||||||
gpioCfgDMAchannel(DMAchannelChannel);
|
gpioCfgDMAchannels(DMAprimaryChannel, DMAsecondaryChannel);
|
||||||
|
|
||||||
gpioCfgSocketPort(socketPort);
|
gpioCfgSocketPort(socketPort);
|
||||||
|
|
||||||
|
if (updateMask != -1) gpioCfgPermissions(updateMask);
|
||||||
|
|
||||||
/* start library */
|
/* start library */
|
||||||
|
|
||||||
if (gpioInitialise()< 0) cmdFatal("Can't initialise pigpio library");
|
if (gpioInitialise()< 0) cmdFatal("Can't initialise pigpio library");
|
||||||
|
@ -275,4 +297,3 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
187
pigs.c
187
pigs.c
|
@ -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>
|
#include <stdio.h>
|
||||||
|
@ -34,6 +34,8 @@ This version is for pigpio version 3+
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "pigpio.h"
|
#include "pigpio.h"
|
||||||
|
@ -44,100 +46,123 @@ This program provides a socket interface
|
||||||
to the commands available from pigpio.
|
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 main(int argc , char *argv[])
|
||||||
{
|
{
|
||||||
int sock, r, idx, port;
|
int sock, r, idx;
|
||||||
struct sockaddr_in server;
|
|
||||||
cmdCmd_t cmd;
|
cmdCmd_t cmd;
|
||||||
char * portStr, * addrStr;
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
sock = openSocket();
|
||||||
|
|
||||||
if (sock != -1)
|
if (sock != -1)
|
||||||
{
|
{
|
||||||
portStr = getenv(PI_ENVPORT);
|
switch(argc)
|
||||||
|
|
||||||
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)
|
case 1:
|
||||||
{
|
exit(0);
|
||||||
case 1:
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
sprintf(buf, "%10s", argv[1]);
|
sprintf(buf, "%10s", argv[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
sprintf(buf, "%10s %10s", argv[1], argv[2]);
|
sprintf(buf, "%10s %10s", argv[1], argv[2]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
sprintf(buf, "%10s %10s %10s", argv[1], argv[2], argv[3]);
|
sprintf(buf, "%10s %10s %10s", argv[1], argv[2], argv[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cmdFatal("what?");
|
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?");
|
|
||||||
}
|
}
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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']
|
||||||
|
)
|
Loading…
Reference in New Issue