mirror of https://github.com/joan2937/pigpio
V38
This commit is contained in:
parent
294eac0916
commit
f5912f84b4
12
Makefile
12
Makefile
|
@ -63,8 +63,8 @@ install: $(ALL)
|
||||||
install -m 0755 -s pig2vcd /usr/local/bin
|
install -m 0755 -s pig2vcd /usr/local/bin
|
||||||
install -m 0755 -s pigpiod /usr/local/bin
|
install -m 0755 -s pigpiod /usr/local/bin
|
||||||
install -m 0755 -s pigs /usr/local/bin
|
install -m 0755 -s pigs /usr/local/bin
|
||||||
python2 setup.py install
|
if which python2; then python2 setup.py install; fi
|
||||||
python3 setup.py install
|
if which python3; then python3 setup.py install; fi
|
||||||
install -m 0755 -d /usr/local/man/man1
|
install -m 0755 -d /usr/local/man/man1
|
||||||
install -m 0644 *.1 /usr/local/man/man1
|
install -m 0644 *.1 /usr/local/man/man1
|
||||||
install -m 0755 -d /usr/local/man/man3
|
install -m 0755 -d /usr/local/man/man3
|
||||||
|
@ -79,12 +79,8 @@ uninstall:
|
||||||
rm -f /usr/local/bin/pig2vcd
|
rm -f /usr/local/bin/pig2vcd
|
||||||
rm -f /usr/local/bin/pigpiod
|
rm -f /usr/local/bin/pigpiod
|
||||||
rm -f /usr/local/bin/pigs
|
rm -f /usr/local/bin/pigs
|
||||||
echo removing python2 files
|
if which python2; then python2 setup.py install --record /tmp/pigpio >/dev/null; xargs rm -f < /tmp/pigpio >/dev/null; fi
|
||||||
python2 setup.py install --record /tmp/pigpio >/dev/null
|
if which python3; then python3 setup.py install --record /tmp/pigpio >/dev/null; xargs rm -f < /tmp/pigpio >/dev/null; fi
|
||||||
xargs rm -f < /tmp/pigpio >/dev/null
|
|
||||||
echo removing python3 files
|
|
||||||
python3 setup.py install --record /tmp/pigpio >/dev/null
|
|
||||||
xargs rm -f < /tmp/pigpio >/dev/null
|
|
||||||
rm -f /usr/local/man/man1/pig*.1
|
rm -f /usr/local/man/man1/pig*.1
|
||||||
rm -f /usr/local/man/man3/pig*.3
|
rm -f /usr/local/man/man3/pig*.3
|
||||||
ldconfig
|
ldconfig
|
||||||
|
|
18
command.c
18
command.c
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This version is for pigpio version 37+
|
This version is for pigpio version 38+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -58,6 +58,9 @@ cmdInfo_t cmdInfo[]=
|
||||||
{PI_CMD_CF1, "CF1", 195, 2}, // gpioCustom1
|
{PI_CMD_CF1, "CF1", 195, 2}, // gpioCustom1
|
||||||
{PI_CMD_CF2, "CF2", 195, 6}, // gpioCustom2
|
{PI_CMD_CF2, "CF2", 195, 6}, // gpioCustom2
|
||||||
|
|
||||||
|
{PI_CMD_CGI, "CGI", 101, 4}, // gpioCfgGetInternals
|
||||||
|
{PI_CMD_CSI, "CSI", 111, 1}, // gpioCfgSetInternals
|
||||||
|
|
||||||
{PI_CMD_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle
|
{PI_CMD_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle
|
||||||
{PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth
|
{PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth
|
||||||
|
|
||||||
|
@ -241,6 +244,9 @@ BS2 bits Set gpios in bank 2\n\
|
||||||
CF1 ... Custom function 1\n\
|
CF1 ... Custom function 1\n\
|
||||||
CF2 ... Custom function 2\n\
|
CF2 ... Custom function 2\n\
|
||||||
\n\
|
\n\
|
||||||
|
CGI Configuration get internals\n\
|
||||||
|
CSI v Configuration set internals\n\
|
||||||
|
\n\
|
||||||
GDC g Get PWM dutycycle for gpio\n\
|
GDC g Get PWM dutycycle for gpio\n\
|
||||||
GPW g Get servo pulsewidth for gpio\n\
|
GPW g Get servo pulsewidth for gpio\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -450,6 +456,7 @@ static errInfo_t errInfo[]=
|
||||||
{PI_BAD_HCLK_PASS , "need password to use hardware clock 1"},
|
{PI_BAD_HCLK_PASS , "need password to use hardware clock 1"},
|
||||||
{PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"},
|
{PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"},
|
||||||
{PI_BAD_DATABITS , "serial data bits not 1-32"},
|
{PI_BAD_DATABITS , "serial data bits not 1-32"},
|
||||||
|
{PI_BAD_STOPBITS , "serial (half) stop bits not 2-8"},
|
||||||
{PI_MSG_TOOBIG , "socket/pipe message too big"},
|
{PI_MSG_TOOBIG , "socket/pipe message too big"},
|
||||||
{PI_BAD_MALLOC_MODE , "bad memory allocation mode"},
|
{PI_BAD_MALLOC_MODE , "bad memory allocation mode"},
|
||||||
{PI_TOO_MANY_SEGS , "too many I2C transaction segments"},
|
{PI_TOO_MANY_SEGS , "too many I2C transaction segments"},
|
||||||
|
@ -469,6 +476,9 @@ static errInfo_t errInfo[]=
|
||||||
{PI_CHAIN_TOO_BIG , "chain is too long"},
|
{PI_CHAIN_TOO_BIG , "chain is too long"},
|
||||||
{PI_DEPRECATED , "deprecated function removed"},
|
{PI_DEPRECATED , "deprecated function removed"},
|
||||||
{PI_BAD_SER_INVERT , "bit bang serial invert not 0 or 1"},
|
{PI_BAD_SER_INVERT , "bit bang serial invert not 0 or 1"},
|
||||||
|
{PI_BAD_EDGE , "bad ISR edge, not 1, 1, or 2"},
|
||||||
|
{PI_BAD_ISR_INIT , "bad ISR initialisation"},
|
||||||
|
{PI_BAD_FOREVER , "loop forever must be last chain command"},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -567,7 +577,7 @@ int cmdParse(
|
||||||
|
|
||||||
switch (cmdInfo[idx].vt)
|
switch (cmdInfo[idx].vt)
|
||||||
{
|
{
|
||||||
case 101: /* BR1 BR2 H HELP HWVER
|
case 101: /* BR1 BR2 CGI H HELP HWVER
|
||||||
DCRA HALT INRA NO
|
DCRA HALT INRA NO
|
||||||
PIGPV POPA PUSHA RET T TICK WVBSY WVCLR
|
PIGPV POPA PUSHA RET T TICK WVBSY WVCLR
|
||||||
WVCRE WVGO WVGOR WVHLT WVNEW
|
WVCRE WVGO WVGOR WVHLT WVNEW
|
||||||
|
@ -578,8 +588,8 @@ int cmdParse(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 111: /* BC1 BC2 BS1 BS2
|
case 111: /* ADD AND BC1 BC2 BS1 BS2
|
||||||
ADD AND CMP DIV LDA LDAB MLT
|
CMP CSI DIV LDA LDAB MLT
|
||||||
MOD OR RLA RRA STAB SUB WAIT XOR
|
MOD OR RLA RRA STAB SUB WAIT XOR
|
||||||
|
|
||||||
One parameter, any value.
|
One parameter, any value.
|
||||||
|
|
15
pig2vcd.1
15
pig2vcd.1
|
@ -53,29 +53,22 @@ typedef struct
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
seqno starts at 0 each time the handle is opened and then increments
|
seqno: starts at 0 each time the handle is opened and then increments by one for each report.
|
||||||
by one for each report.
|
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
flags, if bit 5 is set then bits 0-4 of the flags indicate a gpio which
|
flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. If bit 5 is set (PI_NTFY_FLAGS_WDOG) then bits 0-4 of the flags indicate a gpio which has had a watchdog timeout; if bit 6 is set (PI_NTFY_FLAGS_ALIVE) this indicates a keep alive signal on the pipe/socket and is sent once a minute in the absence of other notification activity.
|
||||||
has had a watchdog timeout.
|
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
tick is the number of microseconds since system boot.
|
tick: the number of microseconds since system boot. It wraps around after 1h12m.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
level indicates the level of each gpio.
|
level: indicates the level of each gpio. If bit 1<<x is set then gpio x is high. pig2vcd takes these notifications and outputs a text format VCD.
|
||||||
|
|
||||||
.br
|
|
||||||
|
|
||||||
.br
|
|
||||||
pig2vcd takes these notifications and outputs a text format VCD.
|
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
|
265
pigpio.3
265
pigpio.3
|
@ -1104,7 +1104,7 @@ void aFunction(int gpio, int level, uint32_t tick)
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
gpioSetAlertFunc(4, aFunction);
|
gpioSetAlertFunc(4F, aFunction);
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
@ -1155,6 +1155,135 @@ registered per gpio.
|
||||||
.br
|
.br
|
||||||
See \fBgpioSetAlertFunc\fP for further details.
|
See \fBgpioSetAlertFunc\fP for further details.
|
||||||
|
|
||||||
|
.IP "\fBint gpioSetISRFunc(unsigned user_gpio, unsigned edge, int timeout, gpioISRFunc_t f)\fP"
|
||||||
|
.IP "" 4
|
||||||
|
Registers a function to be called (a callback) whenever the specified
|
||||||
|
gpio interrupt occurs.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EX
|
||||||
|
user_gpio: 0-31
|
||||||
|
.br
|
||||||
|
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
|
||||||
|
.br
|
||||||
|
timeout: interrupt timeout in milliseconds (<=0 to cancel)
|
||||||
|
.br
|
||||||
|
f: the callback function
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
|
||||||
|
or PI_BAD_ISR_INIT.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
One function may be registered per gpio.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The function is passed the gpio, the current level, and the
|
||||||
|
current tick. The level will be PI_TIMEOUT if the optional
|
||||||
|
interrupt timeout expires.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The underlying Linux sysfs gpio interface is used to provide
|
||||||
|
the interrupt services.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The first time the function is called, with a non-NULL f, the
|
||||||
|
gpio is exported, set to be an input, and set to interrupt
|
||||||
|
on the given edge and timeout.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
Subsequent calls, with a non-NULL f, can vary one or more of the
|
||||||
|
edge, timeout, or function.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The ISR may be cancelled by passing a NULL f, in which case the
|
||||||
|
gpio is unexported.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The tick is that read at the time the process was informed of
|
||||||
|
the interrupt. This will be a variable number of microseconds
|
||||||
|
after the interrupt occurred. Typically the latency will be of
|
||||||
|
the order of 50 microseconds. The latency is not guaranteed
|
||||||
|
and will vary with system load.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The level is that read at the time the process was informed of
|
||||||
|
the interrupt, or PI_TIMEOUT if the optional interrupt timeout
|
||||||
|
expired. It may not be the same as the expected edge as
|
||||||
|
interrupts happening in rapid succession may be missed by the
|
||||||
|
kernel (i.e. this mechanism can not be used to capture several
|
||||||
|
interrupts only a few microseconds apart).
|
||||||
|
|
||||||
|
.IP "\fBint gpioSetISRFuncEx(unsigned user_gpio, unsigned edge, int timeout, gpioISRFuncEx_t f, void *userdata)\fP"
|
||||||
|
.IP "" 4
|
||||||
|
Registers a function to be called (a callback) whenever the specified
|
||||||
|
gpio interrupt occurs.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EX
|
||||||
|
user_gpio: 0-31
|
||||||
|
.br
|
||||||
|
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
|
||||||
|
.br
|
||||||
|
timeout: interrupt timeout in milliseconds (<=0 to cancel)
|
||||||
|
.br
|
||||||
|
f: the callback function
|
||||||
|
.br
|
||||||
|
userdata: pointer to arbitrary user data
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
|
||||||
|
or PI_BAD_ISR_INIT.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The function is passed the gpio, the current level, the
|
||||||
|
current tick, and the userdata pointer.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
Only one of \fBgpioSetISRFunc\fP or \fBgpioSetISRFuncEx\fP can be
|
||||||
|
registered per gpio.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
See \fBgpioSetISRFunc\fP for further details.
|
||||||
|
|
||||||
.IP "\fBint gpioNotifyOpen(void)\fP"
|
.IP "\fBint gpioNotifyOpen(void)\fP"
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
This function requests a free notification handle.
|
This function requests a free notification handle.
|
||||||
|
@ -1917,6 +2046,14 @@ Loop Repeat 255 1 x y loop x + y*256 times
|
||||||
Delay 255 2 x y delay x + y*256 microseconds
|
Delay 255 2 x y delay x + y*256 microseconds
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
Loop Forever 255 3 loop forever
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
If present Loop Forever must be the last entry in the chain.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
@ -5064,7 +5201,7 @@ method uses the mailbox property interface to allocate bus memory.
|
||||||
Auto will use the mailbox method unless a larger than default buffer
|
Auto will use the mailbox method unless a larger than default buffer
|
||||||
size is requested with \fBgpioCfgBufferSize\fP.
|
size is requested with \fBgpioCfgBufferSize\fP.
|
||||||
|
|
||||||
.IP "\fBint gpioCfgInternals(unsigned cfgWhat, int cfgVal)\fP"
|
.IP "\fBint gpioCfgInternals(unsigned cfgWhat, unsigned cfgVal)\fP"
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
Used to tune internal settings.
|
Used to tune internal settings.
|
||||||
|
|
||||||
|
@ -5080,6 +5217,26 @@ cfgWhat: see source code
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
|
||||||
|
.IP "\fBuint32_t gpioCfgGetInternals(void)\fP"
|
||||||
|
.IP "" 4
|
||||||
|
This function returns the current library internal configuration
|
||||||
|
settings.
|
||||||
|
|
||||||
|
.IP "\fBint gpioCfgSetInternals(uint32_t cfgVal)\fP"
|
||||||
|
.IP "" 4
|
||||||
|
This function sets the current library internal configuration
|
||||||
|
settings.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EX
|
||||||
|
cfgVal: see source code
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
.IP "\fBint gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned argc)\fP"
|
.IP "\fBint gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned argc)\fP"
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
This function is available for user customisation.
|
This function is available for user customisation.
|
||||||
|
@ -5698,9 +5855,9 @@ The hardware clock frequency.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
#define PI_HW_CLK_MIN_FREQ 4689
|
PI_HW_CLK_MIN_FREQ 4689
|
||||||
.br
|
.br
|
||||||
#define PI_HW_CLK_MAX_FREQ 250000000
|
PI_HW_CLK_MAX_FREQ 250000000
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
@ -5734,9 +5891,9 @@ waveform.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
#define PI_MIN_WAVE_DATABITS 1
|
PI_MIN_WAVE_DATABITS 1
|
||||||
.br
|
.br
|
||||||
#define PI_MAX_WAVE_DATABITS 32
|
PI_MAX_WAVE_DATABITS 32
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
@ -5787,6 +5944,28 @@ The number may vary between 0 and range (default 255) where
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.IP "\fBedge\fP: 0-2" 0
|
||||||
|
The type of gpio edge to generate an intrrupt. See\fBgpioSetISRFunc\fP,
|
||||||
|
and \fBgpioSetISRFuncEx\fP.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EX
|
||||||
|
RISING_EDGE 0
|
||||||
|
.br
|
||||||
|
FALLING_EDGE 1
|
||||||
|
.br
|
||||||
|
EITHER_EDGE 2
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
.IP "\fBf\fP" 0
|
.IP "\fBf\fP" 0
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
@ -5964,6 +6143,34 @@ typedef void (*gpioGetSamplesFuncEx_t)
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.IP "\fBgpioISRFunc_t\fP" 0
|
||||||
|
|
||||||
|
.EX
|
||||||
|
typedef void (*gpioISRFunc_t)
|
||||||
|
.br
|
||||||
|
(int gpio, int level, uint32_t tick);
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.IP "\fBgpioISRFuncEx_t\fP" 0
|
||||||
|
|
||||||
|
.EX
|
||||||
|
typedef void (*gpioISRFuncEx_t)
|
||||||
|
.br
|
||||||
|
(int gpio, int level, uint32_t tick, void *userdata);
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
.IP "\fBgpioPulse_t\fP" 0
|
.IP "\fBgpioPulse_t\fP" 0
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
|
@ -6551,7 +6758,7 @@ The hardware PWM dutycycle.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
#define PI_HW_PWM_RANGE 1000000
|
PI_HW_PWM_RANGE 1000000
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
@ -6568,9 +6775,9 @@ The hardware PWM frequency.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
#define PI_HW_PWM_MIN_FREQ 1
|
PI_HW_PWM_MIN_FREQ 1
|
||||||
.br
|
.br
|
||||||
#define PI_HW_PWM_MAX_FREQ 125000000
|
PI_HW_PWM_MAX_FREQ 125000000
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
@ -6940,9 +7147,9 @@ to a waveform.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
#define PI_MIN_WAVE_HALFSTOPBITS 2
|
PI_MIN_WAVE_HALFSTOPBITS 2
|
||||||
.br
|
.br
|
||||||
#define PI_MAX_WAVE_HALFSTOPBITS 8
|
PI_MAX_WAVE_HALFSTOPBITS 8
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
@ -6959,7 +7166,12 @@ An array of characters.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.IP "\fBtimeout\fP" 0
|
.IP "\fBtimeout\fP" 0
|
||||||
A gpio watchdog timeout in milliseconds.
|
A gpio level change timeout in milliseconds.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
\fBgpioSetWatchdog\fP
|
||||||
|
|
||||||
.EX
|
.EX
|
||||||
PI_MIN_WDOG_TIMEOUT 0
|
PI_MIN_WDOG_TIMEOUT 0
|
||||||
|
@ -6971,6 +7183,19 @@ PI_MAX_WDOG_TIMEOUT 60000
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
\fBgpioSetISRFunc\fP and \fBgpioSetISRFuncEx\fP
|
||||||
|
|
||||||
|
.EX
|
||||||
|
<=0 cancel timeout
|
||||||
|
.br
|
||||||
|
>0 timeout after specified milliseconds
|
||||||
|
.br
|
||||||
|
|
||||||
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.IP "\fBtimer\fP" 0
|
.IP "\fBtimer\fP" 0
|
||||||
|
@ -7360,6 +7585,12 @@ A 16-bit word value.
|
||||||
#define PI_CMD_SLRI 94
|
#define PI_CMD_SLRI 94
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
#define PI_CMD_CGI 95
|
||||||
|
.br
|
||||||
|
#define PI_CMD_CSI 96
|
||||||
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
#define PI_CMD_NOIB 99
|
#define PI_CMD_NOIB 99
|
||||||
.br
|
.br
|
||||||
|
@ -7618,6 +7849,12 @@ A 16-bit word value.
|
||||||
.br
|
.br
|
||||||
#define PI_BAD_SER_INVERT -121 // bit bang serial invert not 0 or 1
|
#define PI_BAD_SER_INVERT -121 // bit bang serial invert not 0 or 1
|
||||||
.br
|
.br
|
||||||
|
#define PI_BAD_EDGE -122 // bad ISR edge value, not 0-2
|
||||||
|
.br
|
||||||
|
#define PI_BAD_ISR_INIT -123 // bad ISR initialisation
|
||||||
|
.br
|
||||||
|
#define PI_BAD_FOREVER -124 // loop forever must be last chain command
|
||||||
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
#define PI_PIGIF_ERR_0 -2000
|
#define PI_PIGIF_ERR_0 -2000
|
||||||
|
@ -7672,6 +7909,10 @@ A 16-bit word value.
|
||||||
#define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO
|
#define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
#define PI_DEFAULT_CFG_INTERNALS 0
|
||||||
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
|
579
pigpio.c
579
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 37 */
|
/* pigpio version 38 */
|
||||||
|
|
||||||
/* include ------------------------------------------------------- */
|
/* include ------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -872,6 +872,18 @@ typedef struct
|
||||||
uint32_t tick;
|
uint32_t tick;
|
||||||
} gpioAlert_t;
|
} gpioAlert_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned gpio;
|
||||||
|
pthread_t *pth;
|
||||||
|
callbk_t func;
|
||||||
|
unsigned edge;
|
||||||
|
int timeout;
|
||||||
|
unsigned ex;
|
||||||
|
void *userdata;
|
||||||
|
int inited;
|
||||||
|
} gpioISR_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
callbk_t func;
|
callbk_t func;
|
||||||
|
@ -928,6 +940,7 @@ typedef struct
|
||||||
uint32_t lastReportTick;
|
uint32_t lastReportTick;
|
||||||
int fd;
|
int fd;
|
||||||
int pipe;
|
int pipe;
|
||||||
|
int max_emits;
|
||||||
} gpioNotify_t;
|
} gpioNotify_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -955,8 +968,9 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t startTick;
|
|
||||||
uint32_t alertTicks;
|
uint32_t alertTicks;
|
||||||
|
uint32_t lateTicks;
|
||||||
|
uint32_t moreToDo;
|
||||||
uint32_t diffTick[TICKSLOTS];
|
uint32_t diffTick[TICKSLOTS];
|
||||||
uint32_t cbTicks;
|
uint32_t cbTicks;
|
||||||
uint32_t cbCalls;
|
uint32_t cbCalls;
|
||||||
|
@ -966,6 +980,9 @@ typedef struct
|
||||||
uint32_t numSamples;
|
uint32_t numSamples;
|
||||||
uint32_t DMARestarts;
|
uint32_t DMARestarts;
|
||||||
uint32_t dmaInitCbsCount;
|
uint32_t dmaInitCbsCount;
|
||||||
|
uint32_t goodPipeWrite;
|
||||||
|
uint32_t shortPipeWrite;
|
||||||
|
uint32_t wouldBlockPipeWrite;
|
||||||
} gpioStats_t;
|
} gpioStats_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -977,9 +994,14 @@ typedef struct
|
||||||
unsigned DMAsecondaryChannel;
|
unsigned DMAsecondaryChannel;
|
||||||
unsigned socketPort;
|
unsigned socketPort;
|
||||||
unsigned ifFlags;
|
unsigned ifFlags;
|
||||||
int dbgLevel;
|
|
||||||
unsigned showStats;
|
|
||||||
unsigned memAllocMode;
|
unsigned memAllocMode;
|
||||||
|
unsigned dbgLevel;
|
||||||
|
unsigned alertFreq;
|
||||||
|
uint32_t internals;
|
||||||
|
/*
|
||||||
|
0-3: dbgLevel
|
||||||
|
4-7: alertFreq
|
||||||
|
*/
|
||||||
} gpioCfg_t;
|
} gpioCfg_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -1131,6 +1153,8 @@ static int pthSocketRunning = 0;
|
||||||
|
|
||||||
static gpioAlert_t gpioAlert [PI_MAX_USER_GPIO+1];
|
static gpioAlert_t gpioAlert [PI_MAX_USER_GPIO+1];
|
||||||
|
|
||||||
|
static gpioISR_t gpioISR [PI_MAX_USER_GPIO+1];
|
||||||
|
|
||||||
static gpioGetSamples_t gpioGetSamples;
|
static gpioGetSamples_t gpioGetSamples;
|
||||||
|
|
||||||
static gpioInfo_t gpioInfo [PI_MAX_GPIO+1];
|
static gpioInfo_t gpioInfo [PI_MAX_GPIO+1];
|
||||||
|
@ -1199,9 +1223,10 @@ static volatile gpioCfg_t gpioCfg =
|
||||||
PI_DEFAULT_DMA_SECONDARY_CHANNEL,
|
PI_DEFAULT_DMA_SECONDARY_CHANNEL,
|
||||||
PI_DEFAULT_SOCKET_PORT,
|
PI_DEFAULT_SOCKET_PORT,
|
||||||
PI_DEFAULT_IF_FLAGS,
|
PI_DEFAULT_IF_FLAGS,
|
||||||
DBG_MIN_LEVEL,
|
|
||||||
0,
|
|
||||||
PI_DEFAULT_MEM_ALLOC_MODE,
|
PI_DEFAULT_MEM_ALLOC_MODE,
|
||||||
|
0, /* dbgLevel */
|
||||||
|
0, /* alertFreq */
|
||||||
|
0, /* internals */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* no initialisation required */
|
/* no initialisation required */
|
||||||
|
@ -1413,6 +1438,14 @@ static void myGpioSetMode(unsigned gpio, unsigned mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int myGpioRead(unsigned gpio)
|
||||||
|
{
|
||||||
|
if ((*(gpioReg + GPLEV0 + BANK) & BIT) != 0) return PI_ON;
|
||||||
|
else return PI_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -1552,11 +1585,12 @@ static uint32_t myGetTick(int pos)
|
||||||
|
|
||||||
static int myPermit(unsigned gpio)
|
static int myPermit(unsigned gpio)
|
||||||
{
|
{
|
||||||
if ((gpio <= PI_MAX_GPIO) &&
|
if (gpio <= PI_MAX_GPIO)
|
||||||
(gpioMask & ((uint64_t)(1)<<gpio)))
|
{
|
||||||
return 1;
|
if (gpioMask & ((uint64_t)(1)<<gpio)) return 1;
|
||||||
else
|
else return 0;
|
||||||
return 0;
|
}
|
||||||
|
return 1; /* will fail for bad gpio number */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flushMemory(void)
|
static void flushMemory(void)
|
||||||
|
@ -1689,7 +1723,6 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
|
||||||
res = gpioCustom1(p[1], p[2], buf, p[3]);
|
res = gpioCustom1(p[1], p[2], buf, p[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case PI_CMD_CF2:
|
case PI_CMD_CF2:
|
||||||
/* a couple of extra precautions for untrusted code */
|
/* a couple of extra precautions for untrusted code */
|
||||||
if (p[2] > bufSize) p[2] = bufSize;
|
if (p[2] > bufSize) p[2] = bufSize;
|
||||||
|
@ -1697,6 +1730,10 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
|
||||||
if (res > p[2]) res = p[2];
|
if (res > p[2]) res = p[2];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PI_CMD_CGI: res = gpioCfgGetInternals(); break;
|
||||||
|
|
||||||
|
case PI_CMD_CSI: res = gpioCfgSetInternals(p[1]); break;
|
||||||
|
|
||||||
case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break;
|
case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break;
|
||||||
|
|
||||||
case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break;
|
case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break;
|
||||||
|
@ -2226,14 +2263,11 @@ static void myGpioSetPwm(unsigned gpio, int oldVal, int newVal)
|
||||||
|
|
||||||
static void myGpioSetServo(unsigned gpio, int oldVal, int newVal)
|
static void myGpioSetServo(unsigned gpio, int oldVal, int newVal)
|
||||||
{
|
{
|
||||||
int switchGpioOff;
|
|
||||||
int newOff, oldOff, realRange, cycles, i;
|
int newOff, oldOff, realRange, cycles, i;
|
||||||
|
|
||||||
DBG(DBG_INTERNAL,
|
DBG(DBG_INTERNAL,
|
||||||
"myGpioSetServo %d from %d to %d", gpio, oldVal, newVal);
|
"myGpioSetServo %d from %d to %d", gpio, oldVal, newVal);
|
||||||
|
|
||||||
switchGpioOff = 0;
|
|
||||||
|
|
||||||
realRange = pwmRealRange[clkCfg[gpioCfg.clockMicros].servoIdx];
|
realRange = pwmRealRange[clkCfg[gpioCfg.clockMicros].servoIdx];
|
||||||
cycles = pwmCycles [clkCfg[gpioCfg.clockMicros].servoIdx];
|
cycles = pwmCycles [clkCfg[gpioCfg.clockMicros].servoIdx];
|
||||||
|
|
||||||
|
@ -2267,16 +2301,14 @@ static void myGpioSetServo(unsigned gpio, int oldVal, int newVal)
|
||||||
for (i=0; i<SUPERCYCLE; i+=cycles)
|
for (i=0; i<SUPERCYCLE; i+=cycles)
|
||||||
myClearGpioOn(gpio, i);
|
myClearGpioOn(gpio, i);
|
||||||
|
|
||||||
|
/* if in pulse then delay for the last cycle to complete */
|
||||||
|
|
||||||
|
if (myGpioRead(gpio)) myGpioDelay(PI_MAX_SERVO_PULSEWIDTH);
|
||||||
|
|
||||||
|
/* deschedule gpio off */
|
||||||
|
|
||||||
for (i=0; i<SUPERLEVEL; i+=realRange)
|
for (i=0; i<SUPERLEVEL; i+=realRange)
|
||||||
myClearGpioOff(gpio, i+oldOff);
|
myClearGpioOff(gpio, i+oldOff);
|
||||||
|
|
||||||
switchGpioOff = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switchGpioOff)
|
|
||||||
{
|
|
||||||
*(gpioReg + GPCLR0) = (1<<gpio);
|
|
||||||
*(gpioReg + GPCLR0) = (1<<gpio);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4920,11 +4952,14 @@ static void sigHandler(int signum)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGPIPE:
|
case SIGPIPE:
|
||||||
case SIGCHLD:
|
|
||||||
case SIGWINCH:
|
case SIGWINCH:
|
||||||
DBG(DBG_USER, "signal %d ignored", signum);
|
DBG(DBG_USER, "signal %d ignored", signum);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SIGCHLD:
|
||||||
|
/* Used to notify threads of events */
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum);
|
DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum);
|
||||||
gpioTerminate();
|
gpioTerminate();
|
||||||
|
@ -4959,6 +4994,12 @@ static void sigSetHandler(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned alert_delays[]={
|
||||||
|
1000, 1068, 1145, 1235,
|
||||||
|
1339, 1463, 1613, 1796,
|
||||||
|
2027, 2326, 2727, 3297,
|
||||||
|
4167, 5660, 8823, 20000};
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
static void * pthAlertThread(void *x)
|
static void * pthAlertThread(void *x)
|
||||||
|
@ -4966,7 +5007,7 @@ static void * pthAlertThread(void *x)
|
||||||
struct timespec req, rem;
|
struct timespec req, rem;
|
||||||
uint32_t oldLevel, newLevel, level, reportedLevel;
|
uint32_t oldLevel, newLevel, level, reportedLevel;
|
||||||
uint32_t oldSlot, newSlot;
|
uint32_t oldSlot, newSlot;
|
||||||
uint32_t tick, expected;
|
uint32_t tick, expected, nowTick;
|
||||||
int32_t diff;
|
int32_t diff;
|
||||||
int cycle, pulse;
|
int cycle, pulse;
|
||||||
int emit, seqno, emitted;
|
int emit, seqno, emitted;
|
||||||
|
@ -4975,6 +5016,10 @@ static void * pthAlertThread(void *x)
|
||||||
int b, n, v;
|
int b, n, v;
|
||||||
int err;
|
int err;
|
||||||
int stopped;
|
int stopped;
|
||||||
|
int delayTicks;
|
||||||
|
uint32_t nextWakeTick;
|
||||||
|
int moreToDo;
|
||||||
|
int max_emits;
|
||||||
char fifo[32];
|
char fifo[32];
|
||||||
|
|
||||||
req.tv_sec = 0;
|
req.tv_sec = 0;
|
||||||
|
@ -4985,10 +5030,6 @@ static void * pthAlertThread(void *x)
|
||||||
|
|
||||||
reportedLevel = gpioReg[GPLEV0];
|
reportedLevel = gpioReg[GPLEV0];
|
||||||
|
|
||||||
tick = systReg[SYST_CLO];
|
|
||||||
|
|
||||||
gpioStats.startTick = tick;
|
|
||||||
|
|
||||||
oldSlot = dmaCurrentSlot(dmaNowAtICB());
|
oldSlot = dmaCurrentSlot(dmaNowAtICB());
|
||||||
|
|
||||||
cycle = (oldSlot/PULSE_PER_CYCLE);
|
cycle = (oldSlot/PULSE_PER_CYCLE);
|
||||||
|
@ -4996,48 +5037,15 @@ static void * pthAlertThread(void *x)
|
||||||
|
|
||||||
stopped = 0;
|
stopped = 0;
|
||||||
|
|
||||||
|
moreToDo = 0;
|
||||||
|
|
||||||
|
tick = systReg[SYST_CLO];
|
||||||
|
|
||||||
|
nextWakeTick =
|
||||||
|
tick + alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (dmaIn[DMA_CONBLK_AD])
|
|
||||||
{
|
|
||||||
if (stopped)
|
|
||||||
{
|
|
||||||
DBG(DBG_STARTUP, "****** GOING ******");
|
|
||||||
stopped = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stopped = 1;
|
|
||||||
|
|
||||||
myGpioDelay(5000);
|
|
||||||
|
|
||||||
if (runState == PI_RUNNING)
|
|
||||||
{
|
|
||||||
/* should never be executed, leave code just in case */
|
|
||||||
|
|
||||||
gpioCfg.showStats = 1;
|
|
||||||
|
|
||||||
dmaInitCbs();
|
|
||||||
flushMemory();
|
|
||||||
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
|
|
||||||
myGpioDelay(5000); /* let DMA run for a while */
|
|
||||||
oldSlot = dmaCurrentSlot(dmaNowAtICB());
|
|
||||||
gpioStats.DMARestarts++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gpioStats.alertTicks++;
|
|
||||||
|
|
||||||
req.tv_nsec = 850000;
|
|
||||||
|
|
||||||
while (nanosleep(&req, &rem))
|
|
||||||
{
|
|
||||||
req.tv_sec = rem.tv_sec;
|
|
||||||
req.tv_nsec = rem.tv_nsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
newSlot = dmaCurrentSlot(dmaNowAtICB());
|
newSlot = dmaCurrentSlot(dmaNowAtICB());
|
||||||
|
|
||||||
numSamples = 0;
|
numSamples = 0;
|
||||||
|
@ -5086,19 +5094,11 @@ static void * pthAlertThread(void *x)
|
||||||
|
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
{
|
{
|
||||||
/* shouldn't happen */
|
|
||||||
|
|
||||||
//gpioCfg.showStats = 1;
|
|
||||||
|
|
||||||
gpioStats.diffTick[0]++;
|
gpioStats.diffTick[0]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (diff >= TICKSLOTS)
|
else if (diff >= TICKSLOTS)
|
||||||
{
|
{
|
||||||
/* shouldn't happen */
|
|
||||||
|
|
||||||
//gpioCfg.showStats = 1;
|
|
||||||
|
|
||||||
gpioStats.diffTick[TICKSLOTS-1]++;
|
gpioStats.diffTick[TICKSLOTS-1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5106,6 +5106,8 @@ static void * pthAlertThread(void *x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldSlot == newSlot) moreToDo = 0; else moreToDo = 1;
|
||||||
|
|
||||||
/* should gpioGetSamples be called */
|
/* should gpioGetSamples be called */
|
||||||
|
|
||||||
if (changedBits)
|
if (changedBits)
|
||||||
|
@ -5318,6 +5320,7 @@ static void * pthAlertThread(void *x)
|
||||||
if (emit)
|
if (emit)
|
||||||
{
|
{
|
||||||
gpioNotify[n].lastReportTick = tick;
|
gpioNotify[n].lastReportTick = tick;
|
||||||
|
max_emits = gpioNotify[n].max_emits;
|
||||||
|
|
||||||
if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit;
|
if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit;
|
||||||
|
|
||||||
|
@ -5325,15 +5328,15 @@ static void * pthAlertThread(void *x)
|
||||||
|
|
||||||
while (emit > 0)
|
while (emit > 0)
|
||||||
{
|
{
|
||||||
if (emit > MAX_EMITS)
|
if (emit > max_emits)
|
||||||
{
|
{
|
||||||
gpioStats.emitFrags++;
|
gpioStats.emitFrags++;
|
||||||
|
|
||||||
err = write(gpioNotify[n].fd,
|
err = write(gpioNotify[n].fd,
|
||||||
gpioReport+emitted,
|
gpioReport+emitted,
|
||||||
MAX_EMITS*sizeof(gpioReport_t));
|
max_emits*sizeof(gpioReport_t));
|
||||||
|
|
||||||
if (err != (MAX_EMITS*sizeof(gpioReport_t)))
|
if (err != (max_emits*sizeof(gpioReport_t)))
|
||||||
{
|
{
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
|
@ -5351,11 +5354,20 @@ static void * pthAlertThread(void *x)
|
||||||
intNotifyBits();
|
intNotifyBits();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else gpioStats.wouldBlockPipeWrite++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpioCfg.internals |= PI_CFG_STATS;
|
||||||
|
gpioStats.shortPipeWrite++;
|
||||||
|
DBG(DBG_ALWAYS, "emitted %d, asked for %d",
|
||||||
|
err/sizeof(gpioReport_t), max_emits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else gpioStats.goodPipeWrite++;
|
||||||
|
|
||||||
emitted += MAX_EMITS;
|
emitted += max_emits;
|
||||||
emit -= MAX_EMITS;
|
emit -= max_emits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5380,8 +5392,17 @@ static void * pthAlertThread(void *x)
|
||||||
intNotifyBits();
|
intNotifyBits();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else gpioStats.wouldBlockPipeWrite++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpioCfg.internals |= PI_CFG_STATS;
|
||||||
|
gpioStats.shortPipeWrite++;
|
||||||
|
DBG(DBG_ALWAYS, "emitted %d, asked for %d",
|
||||||
|
err/sizeof(gpioReport_t), emit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else gpioStats.goodPipeWrite++;
|
||||||
|
|
||||||
emitted += emit;
|
emitted += emit;
|
||||||
emit = 0;
|
emit = 0;
|
||||||
|
@ -5423,6 +5444,91 @@ static void * pthAlertThread(void *x)
|
||||||
gpioStats.maxSamples = numSamples;
|
gpioStats.maxSamples = numSamples;
|
||||||
|
|
||||||
gpioStats.numSamples += numSamples;
|
gpioStats.numSamples += numSamples;
|
||||||
|
|
||||||
|
/* Check that DMA is running okay */
|
||||||
|
|
||||||
|
if (dmaIn[DMA_CONBLK_AD])
|
||||||
|
{
|
||||||
|
if (stopped)
|
||||||
|
{
|
||||||
|
DBG(DBG_STARTUP, "****** GOING ******");
|
||||||
|
stopped = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stopped = 1;
|
||||||
|
|
||||||
|
myGpioDelay(5000);
|
||||||
|
|
||||||
|
if (runState == PI_RUNNING)
|
||||||
|
{
|
||||||
|
/* should never be executed, leave code just in case */
|
||||||
|
|
||||||
|
gpioCfg.internals |= PI_CFG_STATS;
|
||||||
|
|
||||||
|
dmaInitCbs();
|
||||||
|
flushMemory();
|
||||||
|
initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
|
||||||
|
myGpioDelay(5000); /* let DMA run for a while */
|
||||||
|
oldSlot = dmaCurrentSlot(dmaNowAtICB());
|
||||||
|
gpioStats.DMARestarts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nowTick = systReg[SYST_CLO];
|
||||||
|
|
||||||
|
if (moreToDo)
|
||||||
|
{
|
||||||
|
gpioStats.moreToDo++;
|
||||||
|
|
||||||
|
/* rebase wake up time */
|
||||||
|
|
||||||
|
nextWakeTick = nowTick +
|
||||||
|
alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
|
||||||
|
|
||||||
|
req.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delayTicks = nextWakeTick - nowTick;
|
||||||
|
|
||||||
|
if (delayTicks < 0)
|
||||||
|
{
|
||||||
|
gpioStats.lateTicks++;
|
||||||
|
|
||||||
|
/* rebase wake up time */
|
||||||
|
|
||||||
|
nextWakeTick = nowTick +
|
||||||
|
alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
|
||||||
|
|
||||||
|
req.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpioStats.alertTicks++;
|
||||||
|
|
||||||
|
nextWakeTick +=
|
||||||
|
alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
|
||||||
|
|
||||||
|
req.tv_nsec = (delayTicks * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.tv_nsec)
|
||||||
|
{
|
||||||
|
req.tv_sec = 0;
|
||||||
|
|
||||||
|
while (nanosleep(&req, &rem))
|
||||||
|
{
|
||||||
|
req.tv_sec = rem.tv_sec;
|
||||||
|
req.tv_nsec = rem.tv_nsec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextWakeTick +=
|
||||||
|
alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -5960,12 +6066,14 @@ static void *pthSocketThreadHandler(void *fdC)
|
||||||
switch (p[0])
|
switch (p[0])
|
||||||
{
|
{
|
||||||
case PI_CMD_NOIB:
|
case PI_CMD_NOIB:
|
||||||
|
|
||||||
p[3] = gpioNotifyOpenInBand(sock);
|
p[3] = gpioNotifyOpenInBand(sock);
|
||||||
|
|
||||||
/* Enable the Nagle algorithm. */
|
/* Enable the Nagle algorithm. */
|
||||||
opt = 0;
|
opt = 0;
|
||||||
setsockopt(
|
setsockopt(
|
||||||
sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
|
sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PI_CMD_PROCP:
|
case PI_CMD_PROCP:
|
||||||
|
@ -7041,6 +7149,7 @@ int initInitialise(void)
|
||||||
|
|
||||||
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
||||||
|
|
||||||
|
if (gpioCfg.internals & PI_CFG_RT_PRIORITY)
|
||||||
sched_setscheduler(0, SCHED_FIFO, ¶m);
|
sched_setscheduler(0, SCHED_FIFO, ¶m);
|
||||||
|
|
||||||
initClock(1); /* initialise main clock */
|
initClock(1); /* initialise main clock */
|
||||||
|
@ -7350,12 +7459,17 @@ void gpioTerminate(void)
|
||||||
if (dmaReg != MAP_FAILED) dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
|
if (dmaReg != MAP_FAILED) dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
|
||||||
|
|
||||||
#ifndef EMBEDDED_IN_VM
|
#ifndef EMBEDDED_IN_VM
|
||||||
if (gpioCfg.showStats)
|
if (gpioCfg.internals & PI_CFG_STATS)
|
||||||
{
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n#####################################################\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"If you didn't request stats please cut & paste the\n"
|
"If you didn't request stats please cut & paste the\n"
|
||||||
"following and e-mail to pigpio@abyz.co.uk\n");
|
"following and e-mail to pigpio@abyz.co.uk\n");
|
||||||
|
|
||||||
|
fprintf(stderr, "pigpio version=%d internals=%X\n",
|
||||||
|
PIGPIO_VERSION, gpioCfg.internals);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n",
|
"micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n",
|
||||||
gpioCfg.clockMicros, gpioCfg.memAllocMode,
|
gpioCfg.clockMicros, gpioCfg.memAllocMode,
|
||||||
|
@ -7366,18 +7480,21 @@ void gpioTerminate(void)
|
||||||
gpioStats.numSamples, gpioStats.maxSamples,
|
gpioStats.numSamples, gpioStats.maxSamples,
|
||||||
gpioStats.maxEmit, gpioStats.emitFrags);
|
gpioStats.maxEmit, gpioStats.emitFrags);
|
||||||
|
|
||||||
fprintf(stderr, "cbTicks %d, cbCalls %u alertTicks %u\n",
|
fprintf(stderr, "cbTicks %d, cbCalls %u\n",
|
||||||
gpioStats.cbTicks, gpioStats.cbCalls, gpioStats.alertTicks);
|
gpioStats.cbTicks, gpioStats.cbCalls);
|
||||||
|
|
||||||
|
fprintf(stderr, "pipe: good %u, short %u, would block %u\n",
|
||||||
|
gpioStats.goodPipeWrite, gpioStats.shortPipeWrite,
|
||||||
|
gpioStats.wouldBlockPipeWrite);
|
||||||
|
|
||||||
|
fprintf(stderr, "alertTicks %u, lateTicks %u, moreToDo %u\n",
|
||||||
|
gpioStats.alertTicks, gpioStats.lateTicks, gpioStats.moreToDo);
|
||||||
|
|
||||||
for (i=0; i< TICKSLOTS; i++)
|
for (i=0; i< TICKSLOTS; i++)
|
||||||
fprintf(stderr, "%9u ", gpioStats.diffTick[i]);
|
fprintf(stderr, "%9u ", gpioStats.diffTick[i]);
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"#####################################################\n");
|
"\n#####################################################\n\n\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -8637,6 +8754,7 @@ int gpioWaveChain(char *buf, unsigned bufSize)
|
||||||
"chain counters nested too deep (at %d)", i);
|
"chain counters nested too deep (at %d)", i);
|
||||||
|
|
||||||
stk_pos[stk_lev++] = cb;
|
stk_pos[stk_lev++] = cb;
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
else if (cmd == 1) /* loop end */
|
else if (cmd == 1) /* loop end */
|
||||||
|
@ -8708,7 +8826,6 @@ int gpioWaveChain(char *buf, unsigned bufSize)
|
||||||
|
|
||||||
counters++;
|
counters++;
|
||||||
}
|
}
|
||||||
loop = -1;
|
|
||||||
}
|
}
|
||||||
else if (cmd == 2) /* delay us */
|
else if (cmd == 2) /* delay us */
|
||||||
{
|
{
|
||||||
|
@ -8751,6 +8868,34 @@ int gpioWaveChain(char *buf, unsigned bufSize)
|
||||||
p->next = waveCbPOadr(chainGetCB(cb));
|
p->next = waveCbPOadr(chainGetCB(cb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cmd == 3) /* repeat loop forever */
|
||||||
|
{
|
||||||
|
i += 2;
|
||||||
|
|
||||||
|
loop = 0;
|
||||||
|
if (--stk_lev >= 0) loop = stk_pos[stk_lev];
|
||||||
|
|
||||||
|
if ((loop < 1) || (loop == cb))
|
||||||
|
SOFT_ERROR(PI_BAD_CHAIN_LOOP,
|
||||||
|
"empty chain loop (at %d)", i);
|
||||||
|
|
||||||
|
chaincb = chainGetCB(cb++);
|
||||||
|
if (chaincb < 0)
|
||||||
|
SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
|
||||||
|
|
||||||
|
if (i < bufSize)
|
||||||
|
SOFT_ERROR(PI_BAD_FOREVER,
|
||||||
|
"loop forever must be last command");
|
||||||
|
|
||||||
|
p = rawWaveCBAdr(chaincb);
|
||||||
|
|
||||||
|
/* dummy src and dest */
|
||||||
|
p->info = NORMAL_DMA;
|
||||||
|
p->src = (uint32_t) (&dmaOBus[0]->periphData);
|
||||||
|
p->dst = (uint32_t) (&dmaOBus[0]->periphData);
|
||||||
|
p->length = 4;
|
||||||
|
p->next = waveCbPOadr(chainGetCB(loop));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
SOFT_ERROR(PI_BAD_CHAIN_CMD,
|
SOFT_ERROR(PI_BAD_CHAIN_CMD,
|
||||||
"unknown chain command (255 %d)", cmd);
|
"unknown chain command (255 %d)", cmd);
|
||||||
|
@ -9495,6 +9640,212 @@ int gpioSetAlertFuncEx(unsigned gpio, gpioAlertFuncEx_t f, void *userdata)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *pthISRThread(void *x)
|
||||||
|
{
|
||||||
|
gpioISR_t *isr = x;
|
||||||
|
int fd;
|
||||||
|
int retval;
|
||||||
|
uint32_t tick;
|
||||||
|
int level;
|
||||||
|
uint32_t levels;
|
||||||
|
struct pollfd pfd;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
DBG(DBG_USER, "gpio=%d edge=%d timeout=%d f=%x u=%d data=%x",
|
||||||
|
isr->gpio, isr->edge, isr->timeout, (uint32_t)isr->func,
|
||||||
|
isr->ex, (uint32_t)isr->userdata);
|
||||||
|
|
||||||
|
sprintf(buf, "/sys/class/gpio/gpio%d/value", isr->gpio);
|
||||||
|
|
||||||
|
if ((fd = open(buf, O_RDONLY)) < 0)
|
||||||
|
{
|
||||||
|
DBG(DBG_ALWAYS, "gpio %d not exported", isr->gpio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfd.fd = fd;
|
||||||
|
|
||||||
|
pfd.events = POLLPRI;
|
||||||
|
|
||||||
|
lseek(fd, 0, SEEK_SET); /* consume any prior interrupt */
|
||||||
|
read(fd, buf, sizeof buf);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
retval = poll(&pfd, 1, isr->timeout); /* wait for interrupt */
|
||||||
|
|
||||||
|
tick = systReg[SYST_CLO];
|
||||||
|
|
||||||
|
levels = *(gpioReg + GPLEV0);
|
||||||
|
|
||||||
|
if (retval >= 0)
|
||||||
|
{
|
||||||
|
lseek(fd, 0, SEEK_SET); /* consume interrupt */
|
||||||
|
read(fd, buf, sizeof buf);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
if (levels & (1<<isr->gpio)) level = PI_ON; else level = PI_OFF;
|
||||||
|
}
|
||||||
|
else level = PI_TIMEOUT;
|
||||||
|
|
||||||
|
if (isr->ex) (isr->func)(isr->gpio, level, tick, isr->userdata);
|
||||||
|
else (isr->func)(isr->gpio, level, tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int intGpioSetISRFunc(
|
||||||
|
unsigned gpio,
|
||||||
|
unsigned edge,
|
||||||
|
int timeout,
|
||||||
|
void *f,
|
||||||
|
int user,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
char *edge_str[]={"rising\n", "falling\n", "both\n"};
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
DBG(DBG_INTERNAL,
|
||||||
|
"gpio=%d edge=%d timeout=%d function=%08X user=%d userdata=%08X",
|
||||||
|
gpio, edge, timeout, (uint32_t)f, user, (uint32_t)userdata);
|
||||||
|
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
if (!gpioISR[gpio].inited) /* export gpio if unexported */
|
||||||
|
{
|
||||||
|
fd = open("/sys/class/gpio/export", O_WRONLY);
|
||||||
|
if (fd < 0) return PI_BAD_ISR_INIT;
|
||||||
|
|
||||||
|
/* ignore write fail if already exported */
|
||||||
|
sprintf(buf, "%d\n", gpio);
|
||||||
|
err = write(fd, buf, strlen(buf));
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
|
||||||
|
fd = open(buf, O_WRONLY);
|
||||||
|
if (fd < 0) return PI_BAD_ISR_INIT;
|
||||||
|
|
||||||
|
err = write(fd, "in\n", 3);
|
||||||
|
close(fd);
|
||||||
|
if (err != 3) return PI_BAD_ISR_INIT;
|
||||||
|
|
||||||
|
gpioISR[gpio].gpio = gpio;
|
||||||
|
gpioISR[gpio].edge = -1;
|
||||||
|
gpioISR[gpio].timeout = -1;
|
||||||
|
|
||||||
|
gpioISR[gpio].inited = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpioISR[gpio].edge != edge)
|
||||||
|
{
|
||||||
|
sprintf(buf, "/sys/class/gpio/gpio%d/edge", gpio);
|
||||||
|
fd = open(buf, O_WRONLY);
|
||||||
|
if (fd < 0) return PI_BAD_ISR_INIT;
|
||||||
|
|
||||||
|
err = write(fd, edge_str[edge], strlen(edge_str[edge]));
|
||||||
|
close(fd);
|
||||||
|
if (err != strlen(edge_str[edge])) return PI_BAD_ISR_INIT;
|
||||||
|
|
||||||
|
gpioISR[gpio].edge = edge;
|
||||||
|
|
||||||
|
if (gpioISR[gpio].pth != NULL)
|
||||||
|
pthread_kill(*gpioISR[gpio].pth, SIGCHLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout <= 0) timeout = -1;
|
||||||
|
if (gpioISR[gpio].timeout != timeout)
|
||||||
|
{
|
||||||
|
gpioISR[gpio].timeout = timeout;
|
||||||
|
|
||||||
|
if (gpioISR[gpio].pth != NULL)
|
||||||
|
pthread_kill(*gpioISR[gpio].pth, SIGCHLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioISR[gpio].func = f;
|
||||||
|
gpioISR[gpio].ex = user;
|
||||||
|
gpioISR[gpio].userdata = userdata;
|
||||||
|
|
||||||
|
if (gpioISR[gpio].pth == NULL)
|
||||||
|
gpioISR[gpio].pth = gpioStartThread(pthISRThread, &gpioISR[gpio]);
|
||||||
|
}
|
||||||
|
else /* null function, delete ISR, unexport gpio */
|
||||||
|
{
|
||||||
|
if (gpioISR[gpio].pth) /* delete any existing ISR */
|
||||||
|
{
|
||||||
|
gpioStopThread(gpioISR[gpio].pth);
|
||||||
|
gpioISR[gpio].func = NULL;
|
||||||
|
gpioISR[gpio].pth = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpioISR[gpio].inited) /* unexport any gpio */
|
||||||
|
{
|
||||||
|
fd = open("/sys/class/gpio/unexport", O_WRONLY);
|
||||||
|
if (fd < 0) return PI_BAD_ISR_INIT;
|
||||||
|
sprintf(buf, "%d\n", gpio);
|
||||||
|
err = write(fd, buf, strlen(buf));
|
||||||
|
close(fd);
|
||||||
|
if (err != sizeof(buf)) return PI_BAD_ISR_INIT;
|
||||||
|
gpioISR[gpio].inited = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int gpioSetISRFunc(
|
||||||
|
unsigned gpio,
|
||||||
|
unsigned edge,
|
||||||
|
int timeout,
|
||||||
|
gpioISRFunc_t f)
|
||||||
|
{
|
||||||
|
DBG(DBG_USER, "gpio=%d edge=%d timeout=%d function=%08X",
|
||||||
|
gpio, edge, timeout, (uint32_t)f);
|
||||||
|
|
||||||
|
CHECK_INITED;
|
||||||
|
|
||||||
|
if (gpio > PI_MAX_USER_GPIO)
|
||||||
|
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
|
||||||
|
|
||||||
|
if (edge > EITHER_EDGE)
|
||||||
|
SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
|
||||||
|
|
||||||
|
return intGpioSetISRFunc(gpio, edge, timeout, f, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int gpioSetISRFuncEx(
|
||||||
|
unsigned gpio,
|
||||||
|
unsigned edge,
|
||||||
|
int timeout,
|
||||||
|
gpioAlertFuncEx_t f,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
DBG(DBG_USER, "gpio=%d edge=%d timeout=%d function=%08X userdata=%08X",
|
||||||
|
gpio, edge, timeout, (uint32_t)f, (uint32_t)userdata);
|
||||||
|
|
||||||
|
CHECK_INITED;
|
||||||
|
|
||||||
|
if (gpio > PI_MAX_USER_GPIO)
|
||||||
|
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
|
||||||
|
|
||||||
|
if (edge > EITHER_EDGE)
|
||||||
|
SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
|
||||||
|
|
||||||
|
return intGpioSetISRFunc(gpio, edge, timeout, f, 1, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -9538,6 +9889,7 @@ int gpioNotifyOpen(void)
|
||||||
gpioNotify[slot].bits = 0;
|
gpioNotify[slot].bits = 0;
|
||||||
gpioNotify[slot].fd = fd;
|
gpioNotify[slot].fd = fd;
|
||||||
gpioNotify[slot].pipe = 1;
|
gpioNotify[slot].pipe = 1;
|
||||||
|
gpioNotify[slot].max_emits = MAX_EMITS;
|
||||||
gpioNotify[slot].lastReportTick = gpioTick();
|
gpioNotify[slot].lastReportTick = gpioTick();
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
|
@ -9572,6 +9924,7 @@ static int gpioNotifyOpenInBand(int fd)
|
||||||
gpioNotify[slot].bits = 0;
|
gpioNotify[slot].bits = 0;
|
||||||
gpioNotify[slot].fd = fd;
|
gpioNotify[slot].fd = fd;
|
||||||
gpioNotify[slot].pipe = 0;
|
gpioNotify[slot].pipe = 0;
|
||||||
|
gpioNotify[slot].max_emits = MAX_EMITS;
|
||||||
gpioNotify[slot].lastReportTick = gpioTick();
|
gpioNotify[slot].lastReportTick = gpioTick();
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
|
@ -9940,6 +10293,7 @@ void gpioStopThread(pthread_t *pth)
|
||||||
{
|
{
|
||||||
pthread_cancel(*pth);
|
pthread_cancel(*pth);
|
||||||
pthread_join(*pth, NULL);
|
pthread_join(*pth, NULL);
|
||||||
|
free(pth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10793,34 +11147,33 @@ int gpioCfgMemAlloc(unsigned memAllocMode)
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
int gpioCfgInternals(unsigned cfgWhat, int cfgVal)
|
uint32_t gpioCfgGetInternals(void)
|
||||||
|
{
|
||||||
|
return gpioCfg.internals;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpioCfgSetInternals(uint32_t cfgVal)
|
||||||
|
{
|
||||||
|
gpioCfg.internals = cfgVal;
|
||||||
|
gpioCfg.dbgLevel = cfgVal & 0xF;
|
||||||
|
gpioCfg.alertFreq = (cfgVal>>4) & 0xF;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gpioCfgInternals(unsigned cfgWhat, unsigned cfgVal)
|
||||||
{
|
{
|
||||||
int retVal = PI_BAD_CFG_INTERNAL;
|
int retVal = PI_BAD_CFG_INTERNAL;
|
||||||
|
|
||||||
DBG(DBG_USER, "cfgWhat=%u, cfgVal=%d", cfgWhat, cfgVal);
|
DBG(DBG_USER, "cfgWhat=%u, cfgVal=%d", cfgWhat, cfgVal);
|
||||||
|
|
||||||
/*
|
|
||||||
133084774
|
|
||||||
207081315
|
|
||||||
293640712
|
|
||||||
394342930
|
|
||||||
472769257
|
|
||||||
430873902
|
|
||||||
635370313
|
|
||||||
684442696
|
|
||||||
786301093
|
|
||||||
816051706
|
|
||||||
858202631
|
|
||||||
997413601
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch(cfgWhat)
|
switch(cfgWhat)
|
||||||
{
|
{
|
||||||
case 562484977:
|
case 562484977:
|
||||||
|
|
||||||
gpioCfg.showStats = cfgVal;
|
if (cfgVal) gpioCfg.internals |= PI_CFG_STATS;
|
||||||
|
else gpioCfg.internals &= (~PI_CFG_STATS);
|
||||||
|
|
||||||
DBG(DBG_ALWAYS, "showStats is %u", cfgVal);
|
DBG(DBG_ALWAYS, "show stats is %u", cfgVal);
|
||||||
|
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
|
|
||||||
|
@ -10828,15 +11181,16 @@ int gpioCfgInternals(unsigned cfgWhat, int cfgVal)
|
||||||
|
|
||||||
case 984762879:
|
case 984762879:
|
||||||
|
|
||||||
if (cfgVal < DBG_ALWAYS) cfgVal = DBG_ALWAYS;
|
if ((cfgVal >= DBG_ALWAYS) && (cfgVal <= DBG_MAX_LEVEL))
|
||||||
|
{
|
||||||
if (cfgVal > DBG_MAX_LEVEL) cfgVal = DBG_MAX_LEVEL;
|
|
||||||
|
|
||||||
gpioCfg.dbgLevel = cfgVal;
|
gpioCfg.dbgLevel = cfgVal;
|
||||||
|
gpioCfg.internals = (gpioCfg.internals & (~0xF)) | cfgVal;
|
||||||
|
|
||||||
DBG(DBG_ALWAYS, "Debug level is %u", cfgVal);
|
DBG(DBG_ALWAYS, "Debug level is %u", cfgVal);
|
||||||
|
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10844,6 +11198,7 @@ int gpioCfgInternals(unsigned cfgWhat, int cfgVal)
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* include any user customisations */
|
/* include any user customisations */
|
||||||
|
|
||||||
#include "custom.cext"
|
#include "custom.cext"
|
||||||
|
|
203
pigpio.h
203
pigpio.h
|
@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define PIGPIO_VERSION 37
|
#define PIGPIO_VERSION 38
|
||||||
|
|
||||||
/*TEXT
|
/*TEXT
|
||||||
|
|
||||||
|
@ -160,6 +160,9 @@ gpioGetPWMrealRange Get underlying PWM range for a gpio
|
||||||
|
|
||||||
gpioSetAlertFuncEx Request a gpio change callback, extended
|
gpioSetAlertFuncEx Request a gpio change callback, extended
|
||||||
|
|
||||||
|
gpioSetISRFunc Request a gpio interrupt callback
|
||||||
|
gpioSetISRFuncEx Request a gpio interrupt callback, extended
|
||||||
|
|
||||||
gpioSetSignalFunc Request a signal callback
|
gpioSetSignalFunc Request a signal callback
|
||||||
gpioSetSignalFuncEx Request a signal callback, extended
|
gpioSetSignalFuncEx Request a signal callback, extended
|
||||||
|
|
||||||
|
@ -281,10 +284,14 @@ gpioCfgDMAchannel Configure the DMA channel (DEPRECATED)
|
||||||
gpioCfgDMAchannels Configure the DMA channels
|
gpioCfgDMAchannels Configure the DMA channels
|
||||||
gpioCfgPermissions Configure the gpio access permissions
|
gpioCfgPermissions Configure the gpio access permissions
|
||||||
gpioCfgInterfaces Configure user interfaces
|
gpioCfgInterfaces Configure user interfaces
|
||||||
gpioCfgInternals Configure miscellaneous internals
|
|
||||||
gpioCfgSocketPort Configure socket port
|
gpioCfgSocketPort Configure socket port
|
||||||
gpioCfgMemAlloc Configure DMA memory allocation mode
|
gpioCfgMemAlloc Configure DMA memory allocation mode
|
||||||
|
|
||||||
|
gpioCfgInternals Configure miscellaneous internals (DEPRECATED)
|
||||||
|
|
||||||
|
gpioCfgGetInternals Get internal configuration settings
|
||||||
|
gpioCfgSetInternals Set internal configuration settings
|
||||||
|
|
||||||
CUSTOM
|
CUSTOM
|
||||||
|
|
||||||
gpioCustom1 User custom function 1
|
gpioCustom1 User custom function 1
|
||||||
|
@ -448,6 +455,15 @@ typedef void (*gpioAlertFuncEx_t) (int gpio,
|
||||||
uint32_t tick,
|
uint32_t tick,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
|
typedef void (*gpioISRFunc_t) (int gpio,
|
||||||
|
int level,
|
||||||
|
uint32_t tick);
|
||||||
|
|
||||||
|
typedef void (*gpioISRFuncEx_t) (int gpio,
|
||||||
|
int level,
|
||||||
|
uint32_t tick,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
typedef void (*gpioTimerFunc_t) (void);
|
typedef void (*gpioTimerFunc_t) (void);
|
||||||
|
|
||||||
typedef void (*gpioTimerFuncEx_t) (void *userdata);
|
typedef void (*gpioTimerFuncEx_t) (void *userdata);
|
||||||
|
@ -720,6 +736,22 @@ typedef void *(gpioThreadFunc_t) (void *);
|
||||||
#define PI_MEM_ALLOC_PAGEMAP 1
|
#define PI_MEM_ALLOC_PAGEMAP 1
|
||||||
#define PI_MEM_ALLOC_MAILBOX 2
|
#define PI_MEM_ALLOC_MAILBOX 2
|
||||||
|
|
||||||
|
/* gpioCfgInternals */
|
||||||
|
|
||||||
|
#define PI_CFG_DBG_LEVEL 0 /* bits 0-3 */
|
||||||
|
#define PI_CFG_ALERT_FREQ 4 /* bits 4-7 */
|
||||||
|
#define PI_CFG_RT_PRIORITY (1<<8)
|
||||||
|
#define PI_CFG_STATS (1<<9)
|
||||||
|
|
||||||
|
#define PI_CFG_ILLEGAL_VAL (1<<10)
|
||||||
|
|
||||||
|
/* gpioISR */
|
||||||
|
|
||||||
|
#define RISING_EDGE 0
|
||||||
|
#define FALLING_EDGE 1
|
||||||
|
#define EITHER_EDGE 2
|
||||||
|
|
||||||
|
|
||||||
/*F*/
|
/*F*/
|
||||||
int gpioInitialise(void);
|
int gpioInitialise(void);
|
||||||
/*D
|
/*D
|
||||||
|
@ -1212,7 +1244,7 @@ void aFunction(int gpio, int level, uint32_t tick)
|
||||||
|
|
||||||
// call aFunction whenever gpio 4 changes state
|
// call aFunction whenever gpio 4 changes state
|
||||||
|
|
||||||
gpioSetAlertFunc(4, aFunction);
|
gpioSetAlertFunc(4F, aFunction);
|
||||||
...
|
...
|
||||||
D*/
|
D*/
|
||||||
|
|
||||||
|
@ -1244,6 +1276,89 @@ See [*gpioSetAlertFunc*] for further details.
|
||||||
D*/
|
D*/
|
||||||
|
|
||||||
|
|
||||||
|
/*F*/
|
||||||
|
int gpioSetISRFunc(
|
||||||
|
unsigned user_gpio, unsigned edge, int timeout, gpioISRFunc_t f);
|
||||||
|
/*D
|
||||||
|
Registers a function to be called (a callback) whenever the specified
|
||||||
|
gpio interrupt occurs.
|
||||||
|
|
||||||
|
. .
|
||||||
|
user_gpio: 0-31
|
||||||
|
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
|
||||||
|
timeout: interrupt timeout in milliseconds (<=0 to cancel)
|
||||||
|
f: the callback function
|
||||||
|
. .
|
||||||
|
|
||||||
|
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
|
||||||
|
or PI_BAD_ISR_INIT.
|
||||||
|
|
||||||
|
One function may be registered per gpio.
|
||||||
|
|
||||||
|
The function is passed the gpio, the current level, and the
|
||||||
|
current tick. The level will be PI_TIMEOUT if the optional
|
||||||
|
interrupt timeout expires.
|
||||||
|
|
||||||
|
The underlying Linux sysfs gpio interface is used to provide
|
||||||
|
the interrupt services.
|
||||||
|
|
||||||
|
The first time the function is called, with a non-NULL f, the
|
||||||
|
gpio is exported, set to be an input, and set to interrupt
|
||||||
|
on the given edge and timeout.
|
||||||
|
|
||||||
|
Subsequent calls, with a non-NULL f, can vary one or more of the
|
||||||
|
edge, timeout, or function.
|
||||||
|
|
||||||
|
The ISR may be cancelled by passing a NULL f, in which case the
|
||||||
|
gpio is unexported.
|
||||||
|
|
||||||
|
The tick is that read at the time the process was informed of
|
||||||
|
the interrupt. This will be a variable number of microseconds
|
||||||
|
after the interrupt occurred. Typically the latency will be of
|
||||||
|
the order of 50 microseconds. The latency is not guaranteed
|
||||||
|
and will vary with system load.
|
||||||
|
|
||||||
|
The level is that read at the time the process was informed of
|
||||||
|
the interrupt, or PI_TIMEOUT if the optional interrupt timeout
|
||||||
|
expired. It may not be the same as the expected edge as
|
||||||
|
interrupts happening in rapid succession may be missed by the
|
||||||
|
kernel (i.e. this mechanism can not be used to capture several
|
||||||
|
interrupts only a few microseconds apart).
|
||||||
|
D*/
|
||||||
|
|
||||||
|
|
||||||
|
/*F*/
|
||||||
|
int gpioSetISRFuncEx(
|
||||||
|
unsigned user_gpio,
|
||||||
|
unsigned edge,
|
||||||
|
int timeout,
|
||||||
|
gpioISRFuncEx_t f,
|
||||||
|
void *userdata);
|
||||||
|
/*D
|
||||||
|
Registers a function to be called (a callback) whenever the specified
|
||||||
|
gpio interrupt occurs.
|
||||||
|
|
||||||
|
. .
|
||||||
|
user_gpio: 0-31
|
||||||
|
edge: RISING_EDGE, FALLING_EDGE, or EITHER_EDGE
|
||||||
|
timeout: interrupt timeout in milliseconds (<=0 to cancel)
|
||||||
|
f: the callback function
|
||||||
|
userdata: pointer to arbitrary user data
|
||||||
|
. .
|
||||||
|
|
||||||
|
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_EDGE,
|
||||||
|
or PI_BAD_ISR_INIT.
|
||||||
|
|
||||||
|
The function is passed the gpio, the current level, the
|
||||||
|
current tick, and the userdata pointer.
|
||||||
|
|
||||||
|
Only one of [*gpioSetISRFunc*] or [*gpioSetISRFuncEx*] can be
|
||||||
|
registered per gpio.
|
||||||
|
|
||||||
|
See [*gpioSetISRFunc*] for further details.
|
||||||
|
D*/
|
||||||
|
|
||||||
|
|
||||||
/*F*/
|
/*F*/
|
||||||
int gpioNotifyOpen(void);
|
int gpioNotifyOpen(void);
|
||||||
/*D
|
/*D
|
||||||
|
@ -1658,6 +1773,9 @@ Name @ Cmd & Data @ Meaning
|
||||||
Loop Start @ 255 0 @ Identify start of a wave block
|
Loop Start @ 255 0 @ Identify start of a wave block
|
||||||
Loop Repeat @ 255 1 x y @ loop x + y*256 times
|
Loop Repeat @ 255 1 x y @ loop x + y*256 times
|
||||||
Delay @ 255 2 x y @ delay x + y*256 microseconds
|
Delay @ 255 2 x y @ delay x + y*256 microseconds
|
||||||
|
Loop Forever @ 255 3 @ loop forever
|
||||||
|
|
||||||
|
If present Loop Forever must be the last entry in the chain.
|
||||||
|
|
||||||
The code is currently dimensioned to support a chain with roughly
|
The code is currently dimensioned to support a chain with roughly
|
||||||
600 entries and 20 loop counters.
|
600 entries and 20 loop counters.
|
||||||
|
@ -3540,7 +3658,7 @@ size is requested with [*gpioCfgBufferSize*].
|
||||||
D*/
|
D*/
|
||||||
|
|
||||||
/*F*/
|
/*F*/
|
||||||
int gpioCfgInternals(unsigned cfgWhat, int cfgVal);
|
int gpioCfgInternals(unsigned cfgWhat, unsigned cfgVal);
|
||||||
/*D
|
/*D
|
||||||
Used to tune internal settings.
|
Used to tune internal settings.
|
||||||
|
|
||||||
|
@ -3550,6 +3668,25 @@ cfgWhat: see source code
|
||||||
. .
|
. .
|
||||||
D*/
|
D*/
|
||||||
|
|
||||||
|
/*F*/
|
||||||
|
uint32_t gpioCfgGetInternals(void);
|
||||||
|
/*D
|
||||||
|
This function returns the current library internal configuration
|
||||||
|
settings.
|
||||||
|
D*/
|
||||||
|
|
||||||
|
/*F*/
|
||||||
|
int gpioCfgSetInternals(uint32_t cfgVal);
|
||||||
|
/*D
|
||||||
|
This function sets the current library internal configuration
|
||||||
|
settings.
|
||||||
|
|
||||||
|
. .
|
||||||
|
cfgVal: see source code
|
||||||
|
. .
|
||||||
|
D*/
|
||||||
|
|
||||||
|
|
||||||
/*F*/
|
/*F*/
|
||||||
int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned argc);
|
int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned argc);
|
||||||
/*D
|
/*D
|
||||||
|
@ -3904,8 +4041,8 @@ clkfreq::4689-250M
|
||||||
The hardware clock frequency.
|
The hardware clock frequency.
|
||||||
|
|
||||||
. .
|
. .
|
||||||
#define PI_HW_CLK_MIN_FREQ 4689
|
PI_HW_CLK_MIN_FREQ 4689
|
||||||
#define PI_HW_CLK_MAX_FREQ 250000000
|
PI_HW_CLK_MAX_FREQ 250000000
|
||||||
. .
|
. .
|
||||||
|
|
||||||
count::
|
count::
|
||||||
|
@ -3919,8 +4056,8 @@ The number of data bits to be used when adding serial data to a
|
||||||
waveform.
|
waveform.
|
||||||
|
|
||||||
. .
|
. .
|
||||||
#define PI_MIN_WAVE_DATABITS 1
|
PI_MIN_WAVE_DATABITS 1
|
||||||
#define PI_MAX_WAVE_DATABITS 32
|
PI_MAX_WAVE_DATABITS 32
|
||||||
. .
|
. .
|
||||||
|
|
||||||
DMAchannel::0-14
|
DMAchannel::0-14
|
||||||
|
@ -3940,6 +4077,16 @@ A number representing the ratio of on time to off time for PWM.
|
||||||
The number may vary between 0 and range (default 255) where
|
The number may vary between 0 and range (default 255) where
|
||||||
0 is off and range is fully on.
|
0 is off and range is fully on.
|
||||||
|
|
||||||
|
edge::0-2
|
||||||
|
The type of gpio edge to generate an intrrupt. See[*gpioSetISRFunc*],
|
||||||
|
and [*gpioSetISRFuncEx*].
|
||||||
|
|
||||||
|
. .
|
||||||
|
RISING_EDGE 0
|
||||||
|
FALLING_EDGE 1
|
||||||
|
EITHER_EDGE 2
|
||||||
|
. .
|
||||||
|
|
||||||
f::
|
f::
|
||||||
|
|
||||||
A function.
|
A function.
|
||||||
|
@ -4018,6 +4165,18 @@ typedef void (*gpioGetSamplesFuncEx_t)
|
||||||
(const gpioSample_t *samples, int numSamples, void *userdata);
|
(const gpioSample_t *samples, int numSamples, void *userdata);
|
||||||
. .
|
. .
|
||||||
|
|
||||||
|
gpioISRFunc_t::
|
||||||
|
. .
|
||||||
|
typedef void (*gpioISRFunc_t)
|
||||||
|
(int gpio, int level, uint32_t tick);
|
||||||
|
. .
|
||||||
|
|
||||||
|
gpioISRFuncEx_t::
|
||||||
|
. .
|
||||||
|
typedef void (*gpioISRFuncEx_t)
|
||||||
|
(int gpio, int level, uint32_t tick, void *userdata);
|
||||||
|
. .
|
||||||
|
|
||||||
gpioPulse_t::
|
gpioPulse_t::
|
||||||
. .
|
. .
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -4264,15 +4423,15 @@ PWMduty::0-1000000 (1M)
|
||||||
The hardware PWM dutycycle.
|
The hardware PWM dutycycle.
|
||||||
|
|
||||||
. .
|
. .
|
||||||
#define PI_HW_PWM_RANGE 1000000
|
PI_HW_PWM_RANGE 1000000
|
||||||
. .
|
. .
|
||||||
|
|
||||||
PWMfreq::5-250K
|
PWMfreq::5-250K
|
||||||
The hardware PWM frequency.
|
The hardware PWM frequency.
|
||||||
|
|
||||||
. .
|
. .
|
||||||
#define PI_HW_PWM_MIN_FREQ 1
|
PI_HW_PWM_MIN_FREQ 1
|
||||||
#define PI_HW_PWM_MAX_FREQ 125000000
|
PI_HW_PWM_MAX_FREQ 125000000
|
||||||
. .
|
. .
|
||||||
|
|
||||||
range::25-40000
|
range::25-40000
|
||||||
|
@ -4426,20 +4585,28 @@ The number of (half) stop bits to be used when adding serial data
|
||||||
to a waveform.
|
to a waveform.
|
||||||
|
|
||||||
. .
|
. .
|
||||||
#define PI_MIN_WAVE_HALFSTOPBITS 2
|
PI_MIN_WAVE_HALFSTOPBITS 2
|
||||||
#define PI_MAX_WAVE_HALFSTOPBITS 8
|
PI_MAX_WAVE_HALFSTOPBITS 8
|
||||||
. .
|
. .
|
||||||
|
|
||||||
*str::
|
*str::
|
||||||
An array of characters.
|
An array of characters.
|
||||||
|
|
||||||
timeout::
|
timeout::
|
||||||
A gpio watchdog timeout in milliseconds.
|
A gpio level change timeout in milliseconds.
|
||||||
|
|
||||||
|
[*gpioSetWatchdog*]
|
||||||
. .
|
. .
|
||||||
PI_MIN_WDOG_TIMEOUT 0
|
PI_MIN_WDOG_TIMEOUT 0
|
||||||
PI_MAX_WDOG_TIMEOUT 60000
|
PI_MAX_WDOG_TIMEOUT 60000
|
||||||
. .
|
. .
|
||||||
|
|
||||||
|
[*gpioSetISRFunc*] and [*gpioSetISRFuncEx*]
|
||||||
|
. .
|
||||||
|
<=0 cancel timeout
|
||||||
|
>0 timeout after specified milliseconds
|
||||||
|
. .
|
||||||
|
|
||||||
timer::
|
timer::
|
||||||
. .
|
. .
|
||||||
PI_MIN_TIMER 0
|
PI_MIN_TIMER 0
|
||||||
|
@ -4616,6 +4783,9 @@ PARAMS*/
|
||||||
|
|
||||||
#define PI_CMD_SLRI 94
|
#define PI_CMD_SLRI 94
|
||||||
|
|
||||||
|
#define PI_CMD_CGI 95
|
||||||
|
#define PI_CMD_CSI 96
|
||||||
|
|
||||||
#define PI_CMD_NOIB 99
|
#define PI_CMD_NOIB 99
|
||||||
|
|
||||||
/*DEF_E*/
|
/*DEF_E*/
|
||||||
|
@ -4802,6 +4972,9 @@ after this command is issued.
|
||||||
#define PI_CHAIN_TOO_BIG -119 // chain is too long
|
#define PI_CHAIN_TOO_BIG -119 // chain is too long
|
||||||
#define PI_DEPRECATED -120 // deprecated function removed
|
#define PI_DEPRECATED -120 // deprecated function removed
|
||||||
#define PI_BAD_SER_INVERT -121 // bit bang serial invert not 0 or 1
|
#define PI_BAD_SER_INVERT -121 // bit bang serial invert not 0 or 1
|
||||||
|
#define PI_BAD_EDGE -122 // bad ISR edge value, not 0-2
|
||||||
|
#define PI_BAD_ISR_INIT -123 // bad ISR initialisation
|
||||||
|
#define PI_BAD_FOREVER -124 // loop forever must be last chain command
|
||||||
|
|
||||||
#define PI_PIGIF_ERR_0 -2000
|
#define PI_PIGIF_ERR_0 -2000
|
||||||
#define PI_PIGIF_ERR_99 -2099
|
#define PI_PIGIF_ERR_99 -2099
|
||||||
|
@ -4830,6 +5003,8 @@ after this command is issued.
|
||||||
#define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL
|
#define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL
|
||||||
#define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO
|
#define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO
|
||||||
|
|
||||||
|
#define PI_DEFAULT_CFG_INTERNALS 0
|
||||||
|
|
||||||
/*DEF_E*/
|
/*DEF_E*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -264,7 +264,7 @@ import threading
|
||||||
import os
|
import os
|
||||||
import atexit
|
import atexit
|
||||||
|
|
||||||
VERSION = "1.21"
|
VERSION = "1.22"
|
||||||
|
|
||||||
exceptions = True
|
exceptions = True
|
||||||
|
|
||||||
|
@ -899,7 +899,7 @@ class _callback_thread(threading.Thread):
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Runs the notification thread."""
|
"""Runs the notification thread."""
|
||||||
|
|
||||||
lastLevel = 0
|
lastLevel = _pigpio_command(self.control, _PI_CMD_BR1, 0, 0)
|
||||||
|
|
||||||
MSG_SIZ = 12
|
MSG_SIZ = 12
|
||||||
|
|
||||||
|
@ -2018,6 +2018,9 @@ class pi():
|
||||||
Loop Start @ 255 0 @ Identify start of a wave block
|
Loop Start @ 255 0 @ Identify start of a wave block
|
||||||
Loop Repeat @ 255 1 x y @ loop x + y*256 times
|
Loop Repeat @ 255 1 x y @ loop x + y*256 times
|
||||||
Delay @ 255 2 x y @ delay x + y*256 microseconds
|
Delay @ 255 2 x y @ delay x + y*256 microseconds
|
||||||
|
Loop Forever @ 255 3 @ loop forever
|
||||||
|
|
||||||
|
If present Loop Forever must be the last entry in the chain.
|
||||||
|
|
||||||
The code is currently dimensioned to support a chain with
|
The code is currently dimensioned to support a chain with
|
||||||
roughly 600 entries and 20 loop counters.
|
roughly 600 entries and 20 loop counters.
|
||||||
|
|
16
pigpiod.1
16
pigpiod.1
|
@ -39,6 +39,11 @@ gpio sample buffer in milliseconds
|
||||||
100-10000
|
100-10000
|
||||||
default 120
|
default 120
|
||||||
|
|
||||||
|
.IP "\fB-c value\fP"
|
||||||
|
library internal settings
|
||||||
|
|
||||||
|
default 0
|
||||||
|
|
||||||
.IP "\fB-d value\fP"
|
.IP "\fB-d value\fP"
|
||||||
primary DMA channel
|
primary DMA channel
|
||||||
0-14
|
0-14
|
||||||
|
@ -158,13 +163,18 @@ affect updateable gpios.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
There are two special cases.
|
There are several special cases.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
The activity LED may be written (gpio 16 for type 1 and 2
|
The activity LED (green) may be written (gpio 16 for type 1 and 2
|
||||||
boards, gpio 47 for type 3 boards).
|
boards, gpio 47 for type 3 boards)
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
The power LED (red) may be written on type 3 boards (gpio 35).
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
|
52
pigpiod.c
52
pigpiod.c
|
@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This version is for pigpio version 30+
|
This version is for pigpio version 38+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -59,6 +59,8 @@ static unsigned socketPort = PI_DEFAULT_SOCKET_PORT;
|
||||||
static unsigned memAllocMode = PI_DEFAULT_MEM_ALLOC_MODE;
|
static unsigned memAllocMode = PI_DEFAULT_MEM_ALLOC_MODE;
|
||||||
static uint64_t updateMask = -1;
|
static uint64_t updateMask = -1;
|
||||||
|
|
||||||
|
static uint32_t cfgInternals = PI_DEFAULT_CFG_INTERNALS;
|
||||||
|
|
||||||
static int updateMaskSet = 0;
|
static int updateMaskSet = 0;
|
||||||
|
|
||||||
static FILE * errFifo;
|
static FILE * errFifo;
|
||||||
|
@ -85,6 +87,7 @@ void usage()
|
||||||
"Usage: sudo pigpiod [OPTION] ...\n" \
|
"Usage: sudo pigpiod [OPTION] ...\n" \
|
||||||
" -a value, DMA mode, 0=AUTO, 1=PMAP, 2=MBOX, default AUTO\n" \
|
" -a value, DMA mode, 0=AUTO, 1=PMAP, 2=MBOX, default AUTO\n" \
|
||||||
" -b value, gpio sample buffer in milliseconds, default 120\n" \
|
" -b value, gpio sample buffer in milliseconds, default 120\n" \
|
||||||
|
" -c value, library internal settings, default 0\n" \
|
||||||
" -d value, primary 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" \
|
" -e value, secondary DMA channel, 0-6, default 5\n" \
|
||||||
" -f, disable fifo interface, default enabled\n" \
|
" -f, disable fifo interface, default enabled\n" \
|
||||||
|
@ -100,41 +103,56 @@ void usage()
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initOpts(int argc, char *argv[])
|
static uint64_t getNum(char *str, int *err)
|
||||||
{
|
{
|
||||||
int i, opt;
|
uint64_t val;
|
||||||
uint64_t mask;
|
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "a:b:d:e:fkp:s:t:x:")) != -1)
|
*err = 0;
|
||||||
{
|
val = strtoll(str, &endptr, 0);
|
||||||
i = -1;
|
if (*endptr) {*err = 1; val = -1;}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initOpts(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int opt, err, i;
|
||||||
|
int64_t mask;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "a:b:c:d:e:fkp:s:t:x:")) != -1)
|
||||||
|
{
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
if ((i >= PI_MEM_ALLOC_AUTO) && (i <= PI_MEM_ALLOC_MAILBOX))
|
if ((i >= PI_MEM_ALLOC_AUTO) && (i <= PI_MEM_ALLOC_MAILBOX))
|
||||||
memAllocMode = i;
|
memAllocMode = i;
|
||||||
else fatal("invalid -a option (%d)", i);
|
else fatal("invalid -a option (%d)", i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX))
|
if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX))
|
||||||
bufferSizeMilliseconds = i;
|
bufferSizeMilliseconds = i;
|
||||||
else fatal("invalid -b option (%d)", i);
|
else fatal("invalid -b option (%d)", i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
i = getNum(optarg, &err);
|
||||||
|
if ((i >= 0) && (i < PI_CFG_ILLEGAL_VAL))
|
||||||
|
cfgInternals = i;
|
||||||
|
else fatal("invalid -c option (%x)", i);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_PRIMARY_CHANNEL))
|
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_PRIMARY_CHANNEL))
|
||||||
DMAprimaryChannel = i;
|
DMAprimaryChannel = i;
|
||||||
else fatal("invalid -d option (%d)", i);
|
else fatal("invalid -d option (%d)", i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_SECONDARY_CHANNEL))
|
if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_SECONDARY_CHANNEL))
|
||||||
DMAsecondaryChannel = i;
|
DMAsecondaryChannel = i;
|
||||||
else fatal("invalid -e option (%d)", i);
|
else fatal("invalid -e option (%d)", i);
|
||||||
|
@ -149,14 +167,14 @@ static void initOpts(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
if ((i >= PI_MIN_SOCKET_PORT) && (i <= PI_MAX_SOCKET_PORT))
|
if ((i >= PI_MIN_SOCKET_PORT) && (i <= PI_MAX_SOCKET_PORT))
|
||||||
socketPort = i;
|
socketPort = i;
|
||||||
else fatal("invalid -p option (%d)", i);
|
else fatal("invalid -p option (%d)", i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
|
|
||||||
switch(i)
|
switch(i)
|
||||||
{
|
{
|
||||||
|
@ -176,15 +194,15 @@ static void initOpts(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
i = atoi(optarg);
|
i = getNum(optarg, &err);
|
||||||
if ((i >= PI_CLOCK_PWM) && (i <= PI_CLOCK_PCM))
|
if ((i >= PI_CLOCK_PWM) && (i <= PI_CLOCK_PCM))
|
||||||
clockPeripheral = i;
|
clockPeripheral = i;
|
||||||
else fatal("invalid -t option (%d)", i);
|
else fatal("invalid -t option (%d)", i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
mask = strtoll(optarg, &endptr, 0);
|
mask = getNum(optarg, &err);
|
||||||
if (!*endptr)
|
if (!err)
|
||||||
{
|
{
|
||||||
updateMask = mask;
|
updateMask = mask;
|
||||||
updateMaskSet = 1;
|
updateMaskSet = 1;
|
||||||
|
@ -273,6 +291,8 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (updateMaskSet) gpioCfgPermissions(updateMask);
|
if (updateMaskSet) gpioCfgPermissions(updateMask);
|
||||||
|
|
||||||
|
gpioCfgSetInternals(cfgInternals);
|
||||||
|
|
||||||
/* start library */
|
/* start library */
|
||||||
|
|
||||||
if (gpioInitialise()< 0) fatal("Can't initialise pigpio library");
|
if (gpioInitialise()< 0) fatal("Can't initialise pigpio library");
|
||||||
|
|
|
@ -1747,6 +1747,14 @@ Loop Repeat 255 1 x y loop x + y*256 times
|
||||||
Delay 255 2 x y delay x + y*256 microseconds
|
Delay 255 2 x y delay x + y*256 microseconds
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
Loop Forever 255 3 loop forever
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.br
|
||||||
|
If present Loop Forever must be the last entry in the chain.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
|
13
pigpiod_if.c
13
pigpiod_if.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/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* PIGPIOD_IF_VERSION 18 */
|
/* PIGPIOD_IF_VERSION 19 */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -80,6 +80,7 @@ static int gPigHandle = -1;
|
||||||
static int gPigNotify = -1;
|
static int gPigNotify = -1;
|
||||||
|
|
||||||
static uint32_t gNotifyBits;
|
static uint32_t gNotifyBits;
|
||||||
|
static uint32_t gLastLevel;
|
||||||
|
|
||||||
callback_t *gCallBackFirst = 0;
|
callback_t *gCallBackFirst = 0;
|
||||||
callback_t *gCallBackLast = 0;
|
callback_t *gCallBackLast = 0;
|
||||||
|
@ -220,8 +221,6 @@ static int pigpioOpenSocket(char *addr, char *port)
|
||||||
|
|
||||||
static void dispatch_notification(gpioReport_t *r)
|
static void dispatch_notification(gpioReport_t *r)
|
||||||
{
|
{
|
||||||
static uint32_t lastLevel = 0;
|
|
||||||
|
|
||||||
callback_t *p;
|
callback_t *p;
|
||||||
uint32_t changed;
|
uint32_t changed;
|
||||||
int l, g;
|
int l, g;
|
||||||
|
@ -233,9 +232,9 @@ static void dispatch_notification(gpioReport_t *r)
|
||||||
|
|
||||||
if (r->flags == 0)
|
if (r->flags == 0)
|
||||||
{
|
{
|
||||||
changed = (r->level ^ lastLevel) & gNotifyBits;
|
changed = (r->level ^ gLastLevel) & gNotifyBits;
|
||||||
|
|
||||||
lastLevel = r->level;
|
gLastLevel = r->level;
|
||||||
|
|
||||||
p = gCallBackFirst;
|
p = gCallBackFirst;
|
||||||
|
|
||||||
|
@ -487,6 +486,7 @@ void stop_thread(pthread_t *pth)
|
||||||
{
|
{
|
||||||
pthread_cancel(*pth);
|
pthread_cancel(*pth);
|
||||||
pthread_join(*pth, NULL);
|
pthread_join(*pth, NULL);
|
||||||
|
free(pth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,6 +507,8 @@ int pigpio_start(char *addrStr, char *portStr)
|
||||||
if (gPigHandle < 0) return pigif_bad_noib;
|
if (gPigHandle < 0) return pigif_bad_noib;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gLastLevel = read_bank_1();
|
||||||
|
|
||||||
pthNotify = start_thread(pthNotifyThread, 0);
|
pthNotify = start_thread(pthNotifyThread, 0);
|
||||||
if (pthNotify)
|
if (pthNotify)
|
||||||
{
|
{
|
||||||
|
@ -1540,3 +1542,4 @@ int wait_for_edge(unsigned user_gpio, unsigned edge, double timeout)
|
||||||
return triggered;
|
return triggered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
|
||||||
|
|
||||||
#include "pigpio.h"
|
#include "pigpio.h"
|
||||||
|
|
||||||
#define PIGPIOD_IF_VERSION 18
|
#define PIGPIOD_IF_VERSION 20
|
||||||
|
|
||||||
/*TEXT
|
/*TEXT
|
||||||
|
|
||||||
|
@ -283,10 +283,6 @@ typedef void (*CBFuncEx_t)
|
||||||
|
|
||||||
typedef struct callback_s callback_t;
|
typedef struct callback_s callback_t;
|
||||||
|
|
||||||
#define RISING_EDGE 0
|
|
||||||
#define FALLING_EDGE 1
|
|
||||||
#define EITHER_EDGE 2
|
|
||||||
|
|
||||||
/*F*/
|
/*F*/
|
||||||
double time_time(void);
|
double time_time(void);
|
||||||
/*D
|
/*D
|
||||||
|
@ -1211,6 +1207,9 @@ Name @ Cmd & Data @ Meaning
|
||||||
Loop Start @ 255 0 @ Identify start of a wave block
|
Loop Start @ 255 0 @ Identify start of a wave block
|
||||||
Loop Repeat @ 255 1 x y @ loop x + y*256 times
|
Loop Repeat @ 255 1 x y @ loop x + y*256 times
|
||||||
Delay @ 255 2 x y @ delay x + y*256 microseconds
|
Delay @ 255 2 x y @ delay x + y*256 microseconds
|
||||||
|
Loop Forever @ 255 3 @ loop forever
|
||||||
|
|
||||||
|
If present Loop Forever must be the last entry in the chain.
|
||||||
|
|
||||||
The code is currently dimensioned to support a chain with roughly
|
The code is currently dimensioned to support a chain with roughly
|
||||||
600 entries and 20 loop counters.
|
600 entries and 20 loop counters.
|
||||||
|
|
20
pigs.1
20
pigs.1
|
@ -500,6 +500,20 @@ customiser.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.IP "\fBCGI \fP - Configuration get internals"
|
||||||
|
.IP "" 4
|
||||||
|
This command returns the value of the internal library
|
||||||
|
configuration settings.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
|
.IP "\fBCSI v\fP - Configuration set internals"
|
||||||
|
.IP "" 4
|
||||||
|
This command sets the value of the internal library
|
||||||
|
configuration settings to \fBv\fP.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
.IP "\fBGDC u\fP - Get gpio PWM dutycycle"
|
.IP "\fBGDC u\fP - Get gpio PWM dutycycle"
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
|
|
||||||
|
@ -2584,6 +2598,8 @@ will be returned.
|
||||||
.br
|
.br
|
||||||
The invert parameter \fBv\fP is 1 for inverted signal, 0 for normal.
|
The invert parameter \fBv\fP is 1 for inverted signal, 0 for normal.
|
||||||
|
|
||||||
|
.br
|
||||||
|
|
||||||
\fBExample\fP
|
\fBExample\fP
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
@ -3174,9 +3190,13 @@ Name Cmd & Data Meaning
|
||||||
Loop Start 255 0 Identify start of a wave block
|
Loop Start 255 0 Identify start of a wave block
|
||||||
Loop Repeat 255 1 x y loop x + y*256 times
|
Loop Repeat 255 1 x y loop x + y*256 times
|
||||||
Delay 255 2 x y delay x + y*256 microseconds
|
Delay 255 2 x y delay x + y*256 microseconds
|
||||||
|
Loop Forever 255 3 loop forever
|
||||||
|
|
||||||
.EE
|
.EE
|
||||||
|
|
||||||
|
.br
|
||||||
|
If present Loop Forever must be the last entry in the chain.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
The code is currently dimensioned to support a chain with roughly
|
The code is currently dimensioned to support a chain with roughly
|
||||||
600 entries and 20 loop counters.
|
600 entries and 20 loop counters.
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -3,7 +3,7 @@
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
|
|
||||||
setup(name='pigpio',
|
setup(name='pigpio',
|
||||||
version='1.21',
|
version='1.22',
|
||||||
author='joan',
|
author='joan',
|
||||||
author_email='joan@abyz.co.uk',
|
author_email='joan@abyz.co.uk',
|
||||||
maintainer='joan',
|
maintainer='joan',
|
||||||
|
|
23
x_pigpio.py
23
x_pigpio.py
|
@ -592,18 +592,27 @@ def t9():
|
||||||
|
|
||||||
t9cb = pi.callback(GPIO)
|
t9cb = pi.callback(GPIO)
|
||||||
|
|
||||||
|
old_exceptions = pigpio.exceptions
|
||||||
|
|
||||||
|
pigpio.exceptions = False
|
||||||
|
|
||||||
s = pi.store_script(script)
|
s = pi.store_script(script)
|
||||||
|
|
||||||
# Ensure the script has finished initing.
|
# Ensure the script has finished initing.
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.1)
|
|
||||||
e, p = pi.script_status(s)
|
e, p = pi.script_status(s)
|
||||||
if e != pigpio.PI_SCRIPT_INITING:
|
if e != pigpio.PI_SCRIPT_INITING:
|
||||||
break
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
oc = t9cb.tally()
|
oc = t9cb.tally()
|
||||||
pi.run_script(s, [99, GPIO])
|
pi.run_script(s, [99, GPIO])
|
||||||
time.sleep(2)
|
while True:
|
||||||
|
e, p = pi.script_status(s)
|
||||||
|
if e != pigpio.PI_SCRIPT_RUNNING:
|
||||||
|
break
|
||||||
|
time.sleep(0.1)
|
||||||
|
time.sleep(0.3)
|
||||||
c = t9cb.tally() - oc
|
c = t9cb.tally() - oc
|
||||||
CHECK(9, 1, c, 100, 0, "store/run script")
|
CHECK(9, 1, c, 100, 0, "store/run script")
|
||||||
|
|
||||||
|
@ -613,9 +622,9 @@ def t9():
|
||||||
e, p = pi.script_status(s)
|
e, p = pi.script_status(s)
|
||||||
if e != pigpio.PI_SCRIPT_RUNNING:
|
if e != pigpio.PI_SCRIPT_RUNNING:
|
||||||
break
|
break
|
||||||
time.sleep(0.5)
|
|
||||||
c = t9cb.tally() - oc
|
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
time.sleep(0.3)
|
||||||
|
c = t9cb.tally() - oc
|
||||||
CHECK(9, 2, c, 201, 0, "run script/script status")
|
CHECK(9, 2, c, 201, 0, "run script/script status")
|
||||||
|
|
||||||
oc = t9cb.tally()
|
oc = t9cb.tally()
|
||||||
|
@ -627,13 +636,15 @@ def t9():
|
||||||
if p[9] < 1900:
|
if p[9] < 1900:
|
||||||
pi.stop_script(s)
|
pi.stop_script(s)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
time.sleep(0.3)
|
||||||
c = t9cb.tally() - oc
|
c = t9cb.tally() - oc
|
||||||
time.sleep(0.1)
|
CHECK(9, 3, c, 110, 20, "run/stop script/script status")
|
||||||
CHECK(9, 3, c, 110, 10, "run/stop script/script status")
|
|
||||||
|
|
||||||
e = pi.delete_script(s)
|
e = pi.delete_script(s)
|
||||||
CHECK(9, 4, e, 0, 0, "delete script")
|
CHECK(9, 4, e, 0, 0, "delete script")
|
||||||
|
|
||||||
|
pigpio.exceptions = old_exceptions
|
||||||
|
|
||||||
def ta():
|
def ta():
|
||||||
print("Serial link tests.")
|
print("Serial link tests.")
|
||||||
|
|
||||||
|
|
|
@ -362,7 +362,7 @@ To the lascivious pleasing of a lute.\n\
|
||||||
oc = t5_count;
|
oc = t5_count;
|
||||||
time_sleep(5.05);
|
time_sleep(5.05);
|
||||||
c = t5_count - oc;
|
c = t5_count - oc;
|
||||||
CHECK(5, 4, c, 50, 1, "callback");
|
CHECK(5, 4, c, 50, 2, "callback");
|
||||||
|
|
||||||
e = wave_tx_stop();
|
e = wave_tx_stop();
|
||||||
CHECK(5, 5, e, 0, 0, "wave tx stop");
|
CHECK(5, 5, e, 0, 0, "wave tx stop");
|
||||||
|
|
2
x_pigs
2
x_pigs
|
@ -49,7 +49,7 @@ s=$(pigs bs2 0)
|
||||||
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
|
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
|
||||||
|
|
||||||
s=$(pigs h)
|
s=$(pigs h)
|
||||||
if [[ ${#s} = 4321 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
|
if [[ ${#s} = 4412 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
|
||||||
|
|
||||||
s=$(pigs hwver)
|
s=$(pigs hwver)
|
||||||
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
|
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
|
||||||
|
|
Loading…
Reference in New Issue