diff --git a/README b/README
index d04da3c..a9993b5 100644
--- a/README
+++ b/README
@@ -22,11 +22,18 @@ o the Python module pigpio.py
TEST (optional)
+*** WARNING ************************************************
+* *
+* All the tests make extensive use of gpio 4 (pin P1-7). *
+* Ensure that either nothing or just a LED is connected to *
+* gpio 4 before running any of the tests. *
+************************************************************
+
To test the library do
sudo ./x_pigpio
-To text the pigpio daemon do
+To test the pigpio daemon do
sudo pigpiod
@@ -41,7 +48,7 @@ x_pigpio.c, pig2vcd.c, and pigpiod.c show examples of interfacing
with the pigpio library.
pigs.c, pigpio.py, x_pigpiod_if.c, x_pigpio.py, x_pigs, and x_pipe
-show examples of interfacing with the pigpiod daemon.
+show examples of interfacing with the pigpio daemon.
DAEMON
diff --git a/command.c b/command.c
index 9bf8f9b..683b587 100644
--- a/command.c
+++ b/command.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 13+
+This version is for pigpio version 14+
*/
#include
@@ -38,170 +38,137 @@ This version is for pigpio version 13+
#include "pigpio.h"
#include "command.h"
-/* retv
- pigs pipe
-0 "" <0 ERR %d
-1 "" <0 ERR %d
-2 %d <0 ERR %d
-3 %08X %08X
-4 %u %u
-5 HELP HELP
-6 %s <0 ERR
-*/
-
-/* vfyt
- 1 cmd
- 2 cmd %d
- 3 cmd %d %d
- 4 cmd %d %x
- 6 HELP
- 7 cmd %x
- 8 MODES %d %c
- 9 PUD %d %c
-10 PROC %s
-11 WVAS %d %d %d %s
-12 PROCR %d [%d]*10
-13 WVAG %d %d %d [%d %d %d]*160
-
-
-20 cmd m(0-150)
-21 cmd v
-22 cmd L
-23 cmd
-24 cmd m1(0-150) m2(0-150)
-25 cmd p(0-9)
-*/
-
cmdInfo_t cmdInfo[]=
{
/* num str vfyt retv */
- {PI_CMD_BC1, "BC1", 7, 1},
- {PI_CMD_BC2, "BC2", 7, 1},
- {PI_CMD_BR1, "BR1", 1, 3},
- {PI_CMD_BR2, "BR2", 1, 3},
- {PI_CMD_BS1, "BS1", 7, 1},
- {PI_CMD_BS2, "BS2", 7, 1},
- {PI_CMD_HELP, "H", 6, 5},
- {PI_CMD_HELP, "HELP", 6, 5},
- {PI_CMD_HWVER, "HWVER", 1, 4},
- {PI_CMD_MICRO, "MICRO", 21, 0},
- {PI_CMD_MILLI, "MILLI", 21, 0},
- {PI_CMD_MODEG, "MG" , 2, 2},
- {PI_CMD_MODEG, "MODEG", 2, 2},
- {PI_CMD_MODES, "M", 8, 0},
- {PI_CMD_MODES, "MODES", 8, 0},
- {PI_CMD_NB, "NB", 4, 0},
- {PI_CMD_NC, "NC", 2, 0},
- {PI_CMD_NO, "NO", 1, 2},
- {PI_CMD_NP, "NP", 2, 0},
- {PI_CMD_PFG, "PFG", 2, 2},
- {PI_CMD_PFS, "PFS", 3, 2},
- {PI_CMD_PIGPV, "PIGPV", 1, 4},
- {PI_CMD_PRG, "PRG", 2, 2},
- {PI_CMD_PROC, "PROC", 10, 2},
- {PI_CMD_PROCD, "PROCD", 2, 2},
- {PI_CMD_PROCP, "PROCP", 2, 7},
- {PI_CMD_PROCR, "PROCR",12, 2},
- {PI_CMD_PROCS, "PROCS", 2, 2},
- {PI_CMD_PRRG, "PRRG", 2, 2},
- {PI_CMD_PRS, "PRS", 3, 2},
- {PI_CMD_PUD, "PUD", 9, 0},
- {PI_CMD_PWM, "P", 3, 0},
- {PI_CMD_PWM, "PWM", 3, 0},
- {PI_CMD_READ, "R", 2, 2},
- {PI_CMD_READ, "READ", 2, 2},
- {PI_CMD_SERVO, "S", 3, 0},
- {PI_CMD_SERVO, "SERVO", 3, 0},
- {PI_CMD_SLR, "SLR", 3, 6},
- {PI_CMD_SLRC, "SLRC", 2, 2},
- {PI_CMD_SLRO, "SLRO", 3, 2},
- {PI_CMD_TICK, "T", 1, 4},
- {PI_CMD_TICK, "TICK", 1, 4},
- {PI_CMD_TRIG, "TRIG", 5, 0},
- {PI_CMD_WDOG, "WDOG", 3, 0},
- {PI_CMD_WRITE, "W", 3, 0},
- {PI_CMD_WRITE, "WRITE", 3, 0},
- {PI_CMD_WVAG, "WVAG", 13, 2},
- {PI_CMD_WVAS, "WVAS", 11, 2},
- {PI_CMD_WVBSY, "WVBSY", 1, 2},
- {PI_CMD_WVCLR, "WVCLR", 1, 2},
- {PI_CMD_WVGO, "WVGO" , 1, 2},
- {PI_CMD_WVGOR, "WVGOR", 1, 2},
- {PI_CMD_WVHLT, "WVHLT", 1, 2},
- {PI_CMD_WVSC, "WVSC", 2, 2},
- {PI_CMD_WVSM, "WVSM", 2, 2},
- {PI_CMD_WVSP, "WVSP", 2, 2},
+ {PI_CMD_BC1, "BC1", 111, 1},
+ {PI_CMD_BC2, "BC2", 111, 1},
+ {PI_CMD_BR1, "BR1", 101, 3},
+ {PI_CMD_BR2, "BR2", 101, 3},
+ {PI_CMD_BS1, "BS1", 111, 1},
+ {PI_CMD_BS2, "BS2", 111, 1},
+ {PI_CMD_HELP, "H", 101, 5},
+ {PI_CMD_HELP, "HELP", 101, 5},
+ {PI_CMD_HWVER, "HWVER", 101, 4},
+ {PI_CMD_MICS, "MICS", 112, 0},
+ {PI_CMD_MILS, "MILS", 112, 0},
+ {PI_CMD_MODEG, "MG" , 112, 2},
+ {PI_CMD_MODEG, "MODEG", 112, 2},
+ {PI_CMD_MODES, "M", 125, 0},
+ {PI_CMD_MODES, "MODES", 125, 0},
+ {PI_CMD_NB, "NB", 122, 0},
+ {PI_CMD_NC, "NC", 112, 0},
+ {PI_CMD_NO, "NO", 101, 2},
+ {PI_CMD_NP, "NP", 112, 0},
+ {PI_CMD_PARSE, "PARSE", 115, 2},
+ {PI_CMD_PFG, "PFG", 112, 2},
+ {PI_CMD_PFS, "PFS", 121, 2},
+ {PI_CMD_PIGPV, "PIGPV", 101, 4},
+ {PI_CMD_PRG, "PRG", 112, 2},
+ {PI_CMD_PROC, "PROC", 115, 2},
+ {PI_CMD_PROCD, "PROCD", 112, 2},
+ {PI_CMD_PROCP, "PROCP", 112, 7},
+ {PI_CMD_PROCR, "PROCR", 191, 2},
+ {PI_CMD_PROCS, "PROCS", 112, 2},
+ {PI_CMD_PRRG, "PRRG", 112, 2},
+ {PI_CMD_PRS, "PRS", 121, 2},
+ {PI_CMD_PUD, "PUD", 126, 0},
+ {PI_CMD_PWM, "P", 121, 0},
+ {PI_CMD_PWM, "PWM", 121, 0},
+ {PI_CMD_READ, "R", 112, 2},
+ {PI_CMD_READ, "READ", 112, 2},
+ {PI_CMD_SERVO, "S", 121, 0},
+ {PI_CMD_SERVO, "SERVO", 121, 0},
+ {PI_CMD_SLR, "SLR", 121, 6},
+ {PI_CMD_SLRC, "SLRC", 112, 2},
+ {PI_CMD_SLRO, "SLRO", 121, 2},
+ {PI_CMD_TICK, "T", 101, 4},
+ {PI_CMD_TICK, "TICK", 101, 4},
+ {PI_CMD_TRIG, "TRIG", 131, 0},
+ {PI_CMD_WDOG, "WDOG", 121, 0},
+ {PI_CMD_WRITE, "W", 121, 0},
+ {PI_CMD_WRITE, "WRITE", 121, 0},
+ {PI_CMD_WVAG, "WVAG", 192, 2},
+ {PI_CMD_WVAS, "WVAS", 141, 2},
+ {PI_CMD_WVBSY, "WVBSY", 101, 2},
+ {PI_CMD_WVCLR, "WVCLR", 101, 2},
+ {PI_CMD_WVCRE, "WVCRE", 101, 2},
+ {PI_CMD_WVDEL, "WVDEL", 112, 2},
+ {PI_CMD_WVGO, "WVGO" , 101, 2},
+ {PI_CMD_WVGOR, "WVGOR", 101, 2},
+ {PI_CMD_WVHLT, "WVHLT", 101, 2},
+ {PI_CMD_WVNEW, "WVNEW", 101, 2},
+ {PI_CMD_WVSC, "WVSC", 112, 2},
+ {PI_CMD_WVSM, "WVSM", 112, 2},
+ {PI_CMD_WVSP, "WVSP", 112, 2},
+ {PI_CMD_WVTX, "WVTX", 112, 2},
+ {PI_CMD_WVTXR, "WVTXR", 112, 2},
- {PI_CMD_ADDI , "ADDI" , 21, 0},
- {PI_CMD_ADDV , "ADDV" , 20, 0},
- {PI_CMD_ANDI , "ANDI" , 21, 0},
- {PI_CMD_ANDV , "ANDV" , 20, 0},
- {PI_CMD_CALL , "CALL" , 22, 0},
- {PI_CMD_CMPI , "CMPI" , 21, 0},
- {PI_CMD_CMPV , "CMPV" , 20, 0},
- {PI_CMD_DCRA , "DCRA" , 23, 0},
- {PI_CMD_DCRV , "DCRV" , 20, 0},
- {PI_CMD_HALT , "HALT" , 23, 0},
- {PI_CMD_INRA , "INRA" , 23, 0},
- {PI_CMD_INRV , "INRV" , 20, 0},
- {PI_CMD_JM , "JM" , 22, 0},
- {PI_CMD_JMP , "JMP" , 22, 0},
- {PI_CMD_JNZ , "JNZ" , 22, 0},
- {PI_CMD_JP , "JP" , 22, 0},
- {PI_CMD_JZ , "JZ" , 22, 0},
- {PI_CMD_LABEL, "LABEL", 22, 0},
- {PI_CMD_LDAI , "LDAI" , 21, 0},
- {PI_CMD_LDAP , "LDAP" , 25, 0},
- {PI_CMD_LDAV , "LDAV" , 20, 0},
- {PI_CMD_LDPA , "LDPA" , 25, 0},
- {PI_CMD_LDVA , "LDVA" , 20, 0},
- {PI_CMD_LDVI , "LDVI" , 28, 0},
- {PI_CMD_LDVV , "LDVV" , 24, 0},
- {PI_CMD_ORI , "ORI" , 21, 0},
- {PI_CMD_ORV , "ORV" , 20, 0},
- {PI_CMD_POPA , "POPA" , 23, 0},
- {PI_CMD_POPV , "POPV" , 20, 0},
- {PI_CMD_PUSHA, "PUSHA", 23, 0},
- {PI_CMD_PUSHV, "PUSHV", 20, 0},
- {PI_CMD_RET , "RET" , 23, 0},
- {PI_CMD_RAL , "RAL" , 21, 0},
- {PI_CMD_RAR , "RAR" , 21, 0},
- {PI_CMD_SUBI , "SUBI" , 21, 0},
- {PI_CMD_SUBV , "SUBV" , 20, 0},
- {PI_CMD_SWAPA, "SWAPA", 20, 0},
- {PI_CMD_SWAPV, "SWAPV", 24, 0},
- {PI_CMD_SYS , "SYS" , 27, 0},
- {PI_CMD_WAITI, "WAITI", 21, 0},
- {PI_CMD_WAITV, "WAITV", 20, 0},
- {PI_CMD_XORI , "XORI" , 21, 0},
- {PI_CMD_XORV , "XORV" , 20, 0},
+ {PI_CMD_ADD , "ADD" , 111, 0},
+ {PI_CMD_AND , "AND" , 111, 0},
+ {PI_CMD_CALL , "CALL" , 114, 0},
+ {PI_CMD_CMP , "CMP" , 111, 0},
+ {PI_CMD_DCR , "DCR" , 113, 0},
+ {PI_CMD_DCRA , "DCRA" , 101, 0},
+ {PI_CMD_DIV , "DIV" , 111, 0},
+ {PI_CMD_HALT , "HALT" , 101, 0},
+ {PI_CMD_INR , "INR" , 113, 0},
+ {PI_CMD_INRA , "INRA" , 101, 0},
+ {PI_CMD_JM , "JM" , 114, 0},
+ {PI_CMD_JMP , "JMP" , 114, 0},
+ {PI_CMD_JNZ , "JNZ" , 114, 0},
+ {PI_CMD_JP , "JP" , 114, 0},
+ {PI_CMD_JZ , "JZ" , 114, 0},
+ {PI_CMD_LD , "LD" , 123, 0},
+ {PI_CMD_LDA , "LDA" , 111, 0},
+ {PI_CMD_MLT , "MLT" , 111, 0},
+ {PI_CMD_MOD , "MOD" , 111, 0},
+ {PI_CMD_OR , "OR" , 111, 0},
+ {PI_CMD_POP , "POP" , 113, 0},
+ {PI_CMD_POPA , "POPA" , 101, 0},
+ {PI_CMD_PUSH , "PUSH" , 113, 0},
+ {PI_CMD_PUSHA, "PUSHA", 101, 0},
+ {PI_CMD_RET , "RET" , 101, 0},
+ {PI_CMD_RL , "RL" , 123, 0},
+ {PI_CMD_RLA , "RLA" , 111, 0},
+ {PI_CMD_RR , "RR" , 123, 0},
+ {PI_CMD_RRA , "RRA" , 111, 0},
+ {PI_CMD_STA , "STA" , 113, 0},
+ {PI_CMD_SUB , "SUB" , 111, 0},
+ {PI_CMD_SYS , "SYS" , 116, 0},
+ {PI_CMD_TAG , "TAG" , 114, 0},
+ {PI_CMD_WAIT , "WAIT" , 111, 0},
+ {PI_CMD_X , "X" , 124, 0},
+ {PI_CMD_XA , "XA" , 113, 0},
+ {PI_CMD_XOR , "XOR" , 111, 0},
};
char * cmdUsage = "\
-BC1 v Clear gpios defined by mask v in bank 1.\n\
-BC2 v Clear gpios defined by mask v in bank 2.\n\
+BC1 v Clear gpios specified by mask v in bank 1.\n\
+BC2 v Clear gpios specified by mask v in bank 2.\n\
BR1 Read gpios bank 1.\n\
BR2 Read gpios bank 2.\n\
-BS1 v Set gpios defined by mask v in bank 1.\n\
-BS2 v Set gpios defined by mask v in bank 2.\n\
+BS1 v Set gpios specified by mask v in bank 1.\n\
+BS2 v Set gpios specified by mask v in bank 2.\n\
H Displays command help.\n\
HELP Displays command help.\n\
HWVER Return hardware version.\n\
M g m Set gpio g to mode m.\n\
MG g Get gpio g mode.\n\
-MICRO v Delay for v microseconds.\n\
-MILLI v Delay for v milliseconds.\n\
+MICS v Delay for v microseconds.\n\
+MILS v Delay for v milliseconds.\n\
MODEG g Get gpio g mode.\n\
MODES g m Set gpio g to mode m.\n\
-NB h v Start notifications on handle h for gpios defined by mask v.\n\
+NB h v Start notifications on handle h for gpios specified by mask v.\n\
NC h Close notification handle h.\n\
NO Request notification handle.\n\
NP h Pause notifications on handle h.\n\
-P u v Set PWM value for user gpio u to d.\n\
+P u v Set PWM value for user gpio u to v.\n\
+PARSE t Validate script text t without storing.\n\
PFG u Get PWM frequency for user gpio u.\n\
-PFS u v Set PWM frequency for user gpio u to d.\n\
+PFS u v Set PWM frequency for user gpio u to v.\n\
PIGPV Return pigpio version.\n\
PRG u Get PWM range for user gpio u.\n\
PROC t Store text t of script.\n\
@@ -210,13 +177,13 @@ PROCP s Get current status and parameter values for script s.\n\
PROCR s pars Run script s with up to 10 optional parameters.\n\
PROCS s Stop script s.\n\
PRRG u Get PWM real range for user gpio u.\n\
-PRS u v Set PWM range for user gpio u to d.\n\
+PRS u v Set PWM range for user gpio u to v.\n\
PUD g p Set gpio pull up/down for gpio g to p.\n\
-PWM u v Set PWM value for user gpio u to d.\n\
+PWM u v Set PWM value for user gpio u to v.\n\
R g Read gpio g.\n\
READ g Read gpio g.\n\
-S u v Set servo value for user gpio u to d microseconds.\n\
-SERVO u v Set servo value for user gpio u to d microseconds.\n\
+S u v Set servo value for user gpio u to v microseconds.\n\
+SERVO u v Set servo value for user gpio u to v microseconds.\n\
SLR u v Read up to d bytes of serial data from user gpio u.\n\
SLRC u Close user gpio u for serial data.\n\
SLRO u b Open user gpio u for serial data at b baud.\n\
@@ -224,34 +191,40 @@ T Return current tick.\n\
TICK Return current tick.\n\
TRIG u pl L Trigger level L for pl micros on user gpio u.\n\
W g L Write level L to gpio g.\n\
-WDOG u v Set watchdog of d milliseconds on user gpio u.\n\
+WDOG u v Set watchdog of v milliseconds on user gpio u.\n\
WRITE g L Write level L to gpio g.\n\
WVAG pulses Wave add generic pulses.\n\
WVAS u b o t Wave add serial data t to user gpio u at b baud.\n\
WVBSY Check if wave busy.\n\
WVCLR Wave clear.\n\
-WVGO Wave transmit.\n\
-WVGOR Wave transmit repeatedly.\n\
+WVCRE Create wave from added pulses.\n\
+WVDEL w Delete waves w and higher.\n\
+WVGO Wave transmit (DEPRECATED).\n\
+WVGOR Wave transmit repeatedly (DEPRECATED).\n\
WVHLT Wave stop.\n\
+WVNEW Start a new empty wave.\n\
WVSC ws Wave get DMA control block stats.\n\
WVSM ws Wave get micros stats.\n\
WVSP ws Wave get pulses stats.\n\
+WVTX w Transmit wave w as one-shot.\n\
+WVTXR w Transmit wave w repeatedly.\n\
\n\
b = baud rate.\n\
g = any gpio (0-53).\n\
-h = handle (0-31).\n\
+h = handle (>=0).\n\
L = level (0-1).\n\
m = mode (RW540123).\n\
mask = a bit mask where (1<=0).\n\
p = pud (ODU).\n\
pars = 0 to 10 parameters for script.\n\
-pl = pulse length (0-100).\n\
+pl = pulse length (1-50).\n\
pulses = 1 or more triplets of gpios on, gpios off, delay.\n\
-s = script id (0-31).\n\
+s = script id (>=0).\n\
t = text.\n\
u = user gpio (0-31).\n\
v = value.\n\
+w = wave id (>=0).\n\
ws = 0=now, 1=high, 2=max.\n\
\n\
Numbers may be entered as hex (prefix 0x), octal (prefix 0),\n\
@@ -311,15 +284,15 @@ static errInfo_t errInfo[]=
{PI_BAD_WVSC_COMMND , "bad WVSC subcommand"},
{PI_BAD_WVSM_COMMND , "bad WVSM subcommand"},
{PI_BAD_WVSP_COMMND , "bad WVSP subcommand"},
- {PI_BAD_PULSELEN , "trigger pulse > 100 microseconds"},
+ {PI_BAD_PULSELEN , "trigger pulse > 50 microseconds"},
{PI_BAD_SCRIPT , "invalid script"},
{PI_BAD_SCRIPT_ID , "unknown script id"},
{PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
{PI_GPIO_IN_USE , "gpio already in use"},
{PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"},
{PI_BAD_PARAM_NUM , "script parameter must be 0-9"},
- {PI_DUP_LABEL , "script has duplicate label"},
- {PI_TOO_MANY_LABELS , "script has too many labels"},
+ {PI_DUP_TAG , "script has duplicate tag"},
+ {PI_TOO_MANY_TAGS , "script has too many tags"},
{PI_BAD_SCRIPT_CMD , "illegal script command"},
{PI_BAD_VAR_NUM , "script variable must be 0-149"},
{PI_NO_SCRIPT_ROOM , "no more room for scripts"},
@@ -328,6 +301,14 @@ static errInfo_t errInfo[]=
{PI_SOCK_WRIT_FAILED , "socket write failed"},
{PI_TOO_MANY_PARAM , "too many script parameters > 10"},
{PI_NOT_HALTED , "script already running or failed"},
+ {PI_BAD_TAG , "script has unresolved tag"},
+ {PI_BAD_MICS_DELAY , "bad MICS delay (too large)"},
+ {PI_BAD_MILS_DELAY , "bad MILS delay (too large)"},
+ {PI_BAD_WAVE_ID , "non existent wave id"},
+ {PI_TOO_MANY_CBS , "No more CBs for waveform"},
+ {PI_TOO_MANY_OOL , "No more OOL for waveform"},
+ {PI_EMPTY_WAVEFORM , "attempt to create an empty waveform"},
+ {PI_NO_WAVEFORM_ID , "no more waveform ids"},
};
@@ -342,12 +323,13 @@ static int cmdMatch(char *str)
{
if (strcasecmp(str, cmdInfo[i].name) == 0) return i;
}
- return -1;
+ return CMD_UNKNOWN_CMD;
}
-static int getNum(char *str, unsigned *val, uint8_t *opt, int flags)
+static int getNum(char *str, unsigned *val, int8_t *opt)
{
- int f, n, v;
+ int f, n;
+ unsigned v;
*opt = 0;
@@ -360,28 +342,24 @@ static int getNum(char *str, unsigned *val, uint8_t *opt, int flags)
return n;
}
- if (flags & PARSE_FLAGS_PARAMS)
- {
- f = sscanf(str, " p%i %n", &v, &n);
+ f = sscanf(str, " v%i %n", &v, &n);
- if (f == 1)
- {
- *val = v;
- *opt = CMD_PARAM;
- return n;
- }
+ if (f == 1)
+ {
+ *val = v;
+ if (v < PI_MAX_SCRIPT_VARS) *opt = CMD_VAR;
+ else *opt = -CMD_VAR;
+ return n;
}
- if (flags & PARSE_FLAGS_VARS)
- {
- f = sscanf(str, " v%i %n", &v, &n);
+ f = sscanf(str, " p%i %n", &v, &n);
- if (f == 1)
- {
- *val = v;
- *opt = CMD_VAR;
- return n;
- }
+ if (f == 1)
+ {
+ *val = v;
+ if (v < PI_MAX_SCRIPT_PARAMS) *opt = CMD_PAR;
+ else *opt = -CMD_PAR;
+ return n;
}
return 0;
@@ -394,16 +372,18 @@ char *cmdStr(void)
return intCmdStr;
}
-int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctl)
+int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
{
int f, valid, idx, val, pp, pars, n, n2, i;
char *ptr;
char c;
- int param[MAX_PARAM];
+ int32_t param[MAX_PARAM];
bzero(&ctl->opt, sizeof(ctl->opt));
- sscanf(buf+ctl->eaten, " %31s", intCmdStr);
+ sscanf(buf+ctl->eaten, " %31s %n", intCmdStr, &pp);
+
+ ctl->eaten += pp;
p[0] = -1;
@@ -411,10 +391,6 @@ int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctl)
if (idx < 0) return idx;
- sscanf(buf+ctl->eaten, " %*31s %n", &pp);
-
- ctl->eaten += pp;
-
valid = 0;
p[0] = cmdInfo[idx].cmd;
@@ -423,218 +399,74 @@ int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctl)
switch (cmdInfo[idx].vt)
{
- case 1: /* BR1 BR2 HWVER NO PIGPV TICK WVBSY WVCLR WVGO
- WVGOR WVHLT
- */
+ case 101: /* BR1 BR2 DCRA H HALT HELP HWVER INRA NO
+ PIGPV POPA PUSHA RET T TICK WVBSY WVCLR
+ WVCRE WVGO WVGOR WVHLT WVNEW
+
+ No parameters, always valid.
+ */
valid = 1;
+
break;
- case 2: /* MODEG NC NP PFG PRG PROCD PROCS PRRG
- SLRC READ WVSC WVSM WVSP
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- if (ctl->opt[0]) valid = 1;
+ case 111: /* ADD AND BC1 BC2 BS1 BS2 CMP DIV LDA MLT
+ MOD OR RLA RRA SUB WAIT XOR
+
+ One parameter, any value.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+
+ if (ctl->opt[0] > 0) valid = 1;
+
break;
- case 3: /* PFS PRS PWM SERVO SLR SLRO WDOG WRITE
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
- if (ctl->opt[0] && ctl->opt[1]) valid = 1;
+ case 112: /* MG MICS MILS MODEG NC NP PFG PRG
+ PROCD PROCP PROCS PRRG R READ SLRC
+ WVDEL WVSC WVSM WVSP WVTX WVTXR
+
+ One positive parameter.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+
+ if ((ctl->opt[0] > 0) && ((int)p[1] >= 0)) valid = 1;
+
break;
- case 4: /* NB
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
- if (ctl->opt[0] && ctl->opt[1]) valid = 1;
+ case 113: /* DCR INR POP PUSH STA XA
+
+ One register parameter.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+
+ if ((ctl->opt[0] > 0) && (p[1] < PI_MAX_SCRIPT_VARS)) valid = 1;
+
break;
- case 5: /* TRIG
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
- ctl->eaten += getNum(buf+ctl->eaten, &p[3], &ctl->opt[2], ctl->flags);
- if (ctl->opt[0] && ctl->opt[1] && ctl->opt[2]) valid = 1;
+ case 114: /* CALL JM JMP JNZ JP JZ TAG
+
+ One numeric parameter, any value.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ if (ctl->opt[0] == CMD_NUMERIC) valid = 1;
+
break;
- case 6: /* HELP
- */
- valid = 1;
- break;
+ case 115: /* PARSE PROC
- case 7: /* BC1 BC2 BS1 BS2
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- if (ctl->opt[0]) valid = 1;
- break;
-
- case 8: /* MODES
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
- if (ctl->opt[0] && (f >= 1))
- {
- ctl->eaten += n;
- val = toupper(c);
- ptr = strchr(fmtMdeStr, val);
- if (ptr != NULL)
- {
- val = ptr - fmtMdeStr;
- p[2] = val;
- valid = 1;
- }
- }
- break;
-
- case 9: /* PUD
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
- if (ctl->opt[0] && (f >= 1))
- {
- ctl->eaten += n;
- val = toupper(c);
- ptr = strchr(fmtPudStr, val);
- if (ptr != NULL)
- {
- val = ptr - fmtPudStr;
- p[2] = val;
- valid = 1;
- }
- }
- break;
-
- case 10: /* PROC
- */
+ One parameter, string (rest of input).
+ */
p[1] = strlen(buf+ctl->eaten);
v[1] = buf+ctl->eaten;
ctl->eaten += p[1];
+
valid = 1;
+
break;
- case 11: /* WVAS
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], ctl->flags);
- ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], ctl->flags);
- ctl->eaten += getNum(buf+ctl->eaten, &p[3], &ctl->opt[2], ctl->flags);
+ case 116: /* SYS
- if (ctl->opt[0] && ctl->opt[1] && ctl->opt[2])
- {
- p[4] = strlen(buf+ctl->eaten);
- v[1] = buf+ctl->eaten;
- ctl->eaten += p[4];
- valid = 1;
- }
- break;
-
- case 12: /* PROCR
- */
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], 0);
-
- pars = 0;
-
- while (pars < 10)
- {
- ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1], 0);
- if (ctl->opt[1]) param[pars++] = p[2];
- else break;
- }
-
- p[2] = pars;
-
- v[1] = param;
-
- if (ctl->opt[0]) valid = 1;
- break;
-
- case 13: /* WVAG
- */
- pars = 0;
-
- while (pars < MAX_PARAM)
- {
- ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0], 0);
- if (ctl->opt[0]) param[pars++] = p[1];
- else break;
- }
-
- p[1] = pars/3;
-
- v[1] = param;
-
- if (pars && ((pars%3)==0)) valid = 1;
- break;
-
- case 20: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
- if ((f >= 1) && (p[1] >= 0) && (p[1] < MAX_SCRIPT_VARS))
- {
- ctl->eaten += n;
- valid = 1;
- }
- break;
-
- case 21: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
- if (f == 1)
- {
- ctl->eaten += n;
- valid = 1;
- }
- break;
-
- case 22: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
- if (f == 1)
- {
- ctl->eaten += n;
- valid = 1;
- }
- break;
-
- case 23: /*
- */
- valid = 1;
- break;
-
- case 24: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %d %n", &p[1], &p[2], &n);
- if ((f >= 2) &&
- (p[1] >= 0) && (p[1] < MAX_SCRIPT_VARS) &&
- (p[2] >= 0) && (p[2] < MAX_SCRIPT_VARS))
- {
- ctl->eaten += n;
- valid = 1;
- }
- break;
-
- case 25: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
- if ((f >= 1) && (p[1] >= 0) && (p[1] < MAX_SCRIPT_PARAMS))
- {
- ctl->eaten += n;
- valid = 1;
- }
- break;
-
- case 26: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %n", &p[1], &n);
- if (f >= 1)
- {
- ctl->eaten += n;
- valid = 1;
- }
- break;
-
- case 27: /*
- */
+ One parameter, a string of letters, digits, '-' and '_'.
+ */
f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
if ((f >= 0) && n)
{
@@ -659,20 +491,194 @@ int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctl)
ctl->eaten += n2;
}
}
+
break;
- case 28: /*
- */
- f = sscanf(buf+ctl->eaten, " %d %d %n", &p[1], &p[2], &n);
- if ((f >= 2) && (p[1] >= 0) && (p[1] < MAX_SCRIPT_VARS))
+ case 121: /* P PFS PRS PWM S SERVO SLR SLRO W WDOG WRITE
+
+ Two positive parameters.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+
+ if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) &&
+ (ctl->opt[1] > 0) && ((int)p[2] >= 0)) valid = 1;
+
+ break;
+
+ case 122: /* NB
+
+ Two parameters, first positive, second any value.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+
+ if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) &&
+ (ctl->opt[1] > 0)) valid = 1;
+
+ break;
+
+ case 123: /* LD RL RR
+
+ Two parameters, first register, second any value.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+
+ if ((ctl->opt[0] > 0) &&
+ (p[1] < PI_MAX_SCRIPT_VARS) &&
+ (ctl->opt[1] > 0)) valid = 1;
+
+ break;
+
+ case 124: /* X
+
+ Two register parameters.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+
+ if ((ctl->opt[0] > 0) && (p[1] < PI_MAX_SCRIPT_VARS) &&
+ (ctl->opt[1] > 0) && (p[2] < PI_MAX_SCRIPT_VARS)) valid = 1;
+
+ break;
+
+ case 125: /* M MODES
+
+ Two parameters, first positive, second in 'RW540123'.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+
+ f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
+
+ if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) && (f >= 1))
{
ctl->eaten += n;
+ val = toupper(c);
+ ptr = strchr(fmtMdeStr, val);
+
+ if (ptr != NULL)
+ {
+ val = ptr - fmtMdeStr;
+ p[2] = val;
+ valid = 1;
+ }
+ }
+
+ break;
+
+ case 126: /* PUD
+
+ Two parameters, first positive, second in 'ODU'.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+
+ f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
+
+ if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) && (f >= 1))
+ {
+ ctl->eaten += n;
+ val = toupper(c);
+ ptr = strchr(fmtPudStr, val);
+ if (ptr != NULL)
+ {
+ val = ptr - fmtPudStr;
+ p[2] = val;
+ valid = 1;
+ }
+ }
+
+ break;
+
+ case 131: /* TRIG
+
+ Three positive parameters.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[3], &ctl->opt[2]);
+
+ if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) &&
+ (ctl->opt[1] > 0) && ((int)p[2] >= 0) &&
+ (ctl->opt[2] == CMD_NUMERIC) && ((int)p[3] >= 0))
+ valid = 1;
+
+ break;
+
+ case 141: /* WVAS
+
+ Four parameters, first two positive, third any value,
+ last string (rest of input).
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+ ctl->eaten += getNum(buf+ctl->eaten, &p[3], &ctl->opt[2]);
+
+ if ((ctl->opt[0] == CMD_NUMERIC) && ((int)p[1] >= 0) &&
+ (ctl->opt[1] == CMD_NUMERIC) && ((int)p[2] >= 0) &&
+ (ctl->opt[2] == CMD_NUMERIC))
+ {
+ p[4] = strlen(buf+ctl->eaten);
+ v[1] = buf+ctl->eaten;
+ ctl->eaten += p[4];
valid = 1;
}
+
break;
+
+ case 191: /* PROCR
+
+ One to 11 parameters, first positive,
+ optional remainder, any value.
+ */
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+
+ if ((ctl->opt[0] == CMD_NUMERIC) && ((int)p[1] >= 0))
+ {
+ pars = 0;
+
+ while (pars < PI_MAX_SCRIPT_PARAMS)
+ {
+ ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[1]);
+ if (ctl->opt[1] == CMD_NUMERIC) param[pars++] = p[2];
+ else break;
+ }
+
+ p[2] = pars;
+
+ v[1] = param;
+
+ valid = 1;
+ }
+
+ break;
+
+ case 192: /* WVAG
+
+ One or more triplets (gpios on, gpios off, delay),
+ any value.
+ */
+ pars = 0;
+
+ while (pars < MAX_PARAM)
+ {
+ ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
+ if (ctl->opt[0] == CMD_NUMERIC) param[pars++] = p[1];
+ else break;
+ }
+
+ p[1] = pars / 3;
+
+ v[1] = param;
+
+ if (pars && ((pars % 3) == 0)) valid = 1;
+
+ break;
+
+
}
- if (valid) return idx; else return -1;
+ if (valid) return idx; else return CMD_BAD_PARAMETER;
}
char * cmdErrStr(int error)
@@ -686,3 +692,180 @@ char * cmdErrStr(int error)
return "unknown error";
}
+int cmdParseScript(char *script, cmdScript_t *s, int diags)
+{
+ int idx, len, b, i, j, tags, resolved;
+ int status;
+ uint32_t p[10];
+ void *v[10];
+ cmdInstr_t instr;
+ cmdCtlParse_t ctl;
+
+ ctl.eaten = 0;
+
+ status = 0;
+
+ cmdTagStep_t tag_step[PI_MAX_SCRIPT_TAGS];
+
+ len = strlen(script);
+
+ /* calloc space for PARAMS, VARS, CMDS, and STRINGS */
+
+ b = (sizeof(int) * (PI_MAX_SCRIPT_PARAMS + PI_MAX_SCRIPT_VARS)) +
+ (sizeof(cmdInstr_t) * (len + 2) / 2) + len;
+
+ s->par = calloc(b, 1);
+
+ if (s->par == NULL) return -1;
+
+ s->var = s->par + PI_MAX_SCRIPT_PARAMS;
+
+ s->instr = (cmdInstr_t *)(s->var + PI_MAX_SCRIPT_VARS);
+
+ s->str_area = (char *)(s->instr + ((len + 2) / 2));
+
+ s->str_area_len = len;
+ s->str_area_pos = 0;
+
+ s->instrs = 0;
+
+ tags = 0;
+
+ idx = 0;
+
+ while (ctl.eaten= 0)
+ {
+ switch (instr.p[0])
+ {
+ case PI_CMD_HELP:
+ case PI_CMD_PARSE:
+ case PI_CMD_PROC:
+ case PI_CMD_PROCD:
+ case PI_CMD_PROCP:
+ case PI_CMD_PROCR:
+ case PI_CMD_PROCS:
+ case PI_CMD_SLR:
+ case PI_CMD_SLRC:
+ case PI_CMD_SLRO:
+ case PI_CMD_WVAG:
+ case PI_CMD_WVAS:
+
+ if (diags)
+ {
+ fprintf(stderr, "Illegal command: %s\n", cmdStr());
+ }
+
+ if (!status) status = PI_BAD_SCRIPT_CMD;
+ idx = -1;
+
+ break;
+
+ case PI_CMD_TAG:
+
+ if (tags < PI_MAX_SCRIPT_TAGS)
+ {
+ /* check tag not already used */
+ for (j=0; jinstrs;
+ tags++;
+ }
+ else
+ {
+ if (diags)
+ {
+ fprintf(stderr, "Too many tags: %d\n", instr.p[1]);
+ }
+ if (!status) status = PI_TOO_MANY_TAGS;
+ idx = -1;
+ }
+
+ break;
+
+ case PI_CMD_SYS:
+
+ strncpy(s->str_area+s->str_area_pos, v[1], p[1]);
+ s->str_area[s->str_area_pos+p[1]] = 0;
+ instr.p[1] = (intptr_t) s->str_area+s->str_area_pos;
+ s->str_area_pos += (p[1] + 1);
+
+ break;
+
+ }
+ }
+ else
+ {
+ if (diags)
+ {
+ if (idx == CMD_UNKNOWN_CMD)
+ fprintf(stderr, "Unknown command: %s\n", cmdStr());
+ else
+ fprintf(stderr, "Bad parameter to %s\n", cmdStr());
+ }
+ if (!status) status = PI_BAD_SCRIPT_CMD;
+ }
+
+ if (idx >= 0)
+ {
+ if (instr.p[0] != PI_CMD_TAG)
+ {
+ memcpy(instr.opt, &ctl.opt, sizeof(instr.opt));
+ s->instr[s->instrs++] = instr;
+ }
+ }
+ }
+
+ for (i=0; iinstrs; i++)
+ {
+ instr = s->instr[i];
+
+ /* resolve jumps */
+
+ if ((instr.p[0] == PI_CMD_JMP) || (instr.p[0] == PI_CMD_CALL) ||
+ (instr.p[0] == PI_CMD_JZ) || (instr.p[0] == PI_CMD_JNZ) ||
+ (instr.p[0] == PI_CMD_JM) || (instr.p[0] == PI_CMD_JP))
+ {
+ resolved = 0;
+
+ for (j=0; jinstr[i].p[1] = tag_step[j].step;
+ resolved = 1;
+ break;
+ }
+ }
+
+ if (!resolved)
+ {
+ if (diags)
+ {
+ fprintf(stderr, "Can't resolve tag %d\n", instr.p[1]);
+ }
+ if (!status) status = PI_BAD_TAG;
+ }
+ }
+ }
+ return status;
+}
+
diff --git a/command.h b/command.h
index 7e62405..06d0fef 100644
--- a/command.h
+++ b/command.h
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 13+
+This version is for pigpio version 14+
*/
#ifndef COMMAND_H
@@ -39,19 +39,18 @@ This version is for pigpio version 13+
#define MAX_PARAM 512
-#define PARSE_FLAGS_PARAMS 1
-#define PARSE_FLAGS_VARS 2
+#define CMD_UNKNOWN_CMD -1
+#define CMD_BAD_PARAMETER -2
#define CMD_NUMERIC 1
-#define CMD_PARAM 2
-#define CMD_VAR 3
+#define CMD_VAR 2
+#define CMD_PAR 3
typedef struct
{
- int flags;
- int eaten;
- uint8_t opt[8];
-} gpioCtlParse_t;
+ int eaten;
+ int8_t opt[4];
+} cmdCtlParse_t;
typedef struct
{
@@ -61,11 +60,41 @@ typedef struct
int rv; /* command return value type */
} cmdInfo_t;
+typedef struct
+{
+ uint32_t tag;
+ int step;
+} cmdTagStep_t;
+
+typedef struct
+{
+ uint32_t p[7];
+ int8_t opt[4];
+} cmdInstr_t;
+
+typedef struct
+{
+ /*
+ +-----------+---------+---------+----------------+
+ | PARAMS... | VARS... | CMDS... | STRING AREA... |
+ +-----------+---------+---------+----------------+
+ */
+ int *par;
+ int *var;
+ cmdInstr_t *instr;
+ int instrs;
+ char *str_area;
+ int str_area_len;
+ int str_area_pos;
+} cmdScript_t;
+
extern cmdInfo_t cmdInfo[];
extern char *cmdUsage;
-int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctlParse);
+int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl);
+
+int cmdParseScript(char *script, cmdScript_t *s, int diags);
char *cmdErrStr(int error);
diff --git a/pigpio.c b/pigpio.c
index b9cdb29..0c540d2 100644
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* pigpio version 13 */
+/* pigpio version 14 */
#include
#include
@@ -533,7 +533,8 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define DMAO_PAGES (PAGES_PER_BLOCK * PI_WAVE_BLOCKS)
-#define NUM_OOL (DMAO_PAGES * OOL_PER_OPAGE)
+#define NUM_WAVE_OOL (DMAO_PAGES * OOL_PER_OPAGE)
+#define NUM_WAVE_CBS (DMAO_PAGES * CBS_PER_OPAGE)
#define TICKSLOTS 50
@@ -556,28 +557,20 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define SRX_BUF_SIZE 8192
#define CMD_BUF_SIZE 4096
+#define MAX_DELAY 50
+
/* --------------------------------------------------------------- */
typedef void (*callbk_t) ();
-typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */
- unsigned long info;
- unsigned long src;
- unsigned long dst;
- unsigned long length;
- unsigned long stride;
- unsigned long next;
- unsigned long pad[2];
-} dmaCbs_t;
-
typedef struct
{
- dmaCbs_t cb [128];
+ rawCbs_t cb [128];
} dmaPage_t;
typedef struct
{
- dmaCbs_t cb [CBS_PER_IPAGE];
+ rawCbs_t cb [CBS_PER_IPAGE];
uint32_t level [LVS_PER_IPAGE];
uint32_t gpioOff [OFF_PER_IPAGE];
uint32_t tick [TCK_PER_IPAGE];
@@ -588,7 +581,7 @@ typedef struct
typedef struct
{
- dmaCbs_t cb [CBS_PER_OPAGE];
+ rawCbs_t cb [CBS_PER_OPAGE];
uint32_t OOL [OOL_PER_OPAGE];
uint32_t periphData;
} dmaOPage_t;
@@ -626,12 +619,6 @@ typedef struct
uint32_t bits;
} gpioGetSamples_t;
-typedef struct
-{
- uint32_t label;
- int step;
-} gpioLabelStep_t;
-
typedef struct
{
callbk_t func;
@@ -653,16 +640,8 @@ typedef struct
#define PI_SCRIPT_RUN 1
#define PI_SCRIPT_DELETE 2
-#define PI_SCRIPT_SLOTS 32
-
#define PI_SCRIPT_STACK_SIZE 256
-typedef struct
-{
- uint32_t p[6];
- uint8_t opt[8];
-} gpioInstr_t;
-
typedef struct
{
unsigned id;
@@ -674,18 +653,7 @@ typedef struct
pthread_t *pthIdp;
pthread_mutex_t pthMutex;
pthread_cond_t pthCond;
-/*
- +-----------+---------+---------+----------------+
- | PARAMS... | VARS... | CMDS... | STRING AREA... |
- +-----------+---------+---------+----------------+
-*/
- int *param;
- int *var;
- gpioInstr_t *instr;
- int instrs;
- char *str_area;
- int str_area_len;
- int str_area_pos;
+ cmdScript_t script;
} gpioScript_t;
@@ -768,6 +736,13 @@ typedef struct
int mode;
} wfRx_t;
+typedef struct
+{
+ int botCB; /* first CB used by wave */
+ int topCB; /* last CB used by wave */
+ int botOOL;
+ int topOOL;
+} waveInfo_t;
/* --------------------------------------------------------------- */
@@ -812,8 +787,16 @@ static wfStats_t wfStats=
0, 0, (DMAO_PAGES * CBS_PER_OPAGE)
};
+static waveInfo_t waveInfo[PI_MAX_WAVES];
+
static volatile wfRx_t wfRx[PI_MAX_USER_GPIO+1];
+static int waveOutBotCB = 0;
+static int waveOutTopCB = NUM_WAVE_CBS;
+static int waveOutBotOOL = 0;
+static int waveOutTopOOL = NUM_WAVE_OOL;
+static int waveOutCount = 0;
+
static volatile uint32_t alertBits = 0;
static volatile uint32_t monitorBits = 0;
static volatile uint32_t notifyBits = 0;
@@ -835,7 +818,7 @@ static gpioInfo_t gpioInfo [PI_MAX_USER_GPIO+1];
static gpioNotify_t gpioNotify [PI_NOTIFY_SLOTS];
-static gpioScript_t gpioScript [PI_SCRIPT_SLOTS];
+static gpioScript_t gpioScript [PI_MAX_SCRIPTS];
static gpioSignal_t gpioSignal [PI_MAX_SIGNUM+1];
@@ -945,7 +928,7 @@ static uint32_t myGpioDelay(uint32_t micros)
start = systReg[SYST_CLO];
- if (micros < 101) while ((systReg[SYST_CLO] - start) <= micros) ;
+ if (micros <= MAX_DELAY) while ((systReg[SYST_CLO] - start) <= micros) ;
else myGpioSleep(micros/MILLION, micros%MILLION);
@@ -1041,153 +1024,9 @@ static uint32_t myGetTick(int pos)
return tick;
}
-/* ----------------------------------------------------------------------- */
-
-static int myParseScript(char *script, gpioScript_t *s)
+static int myPermit(unsigned gpio)
{
- int idx, len, b, i, j, labels, resolved, pos;
- int status;
- uint32_t p[10];
- void *v[10];
- gpioInstr_t instr;
- gpioCtlParse_t ctl;
-
- ctl.flags = PARSE_FLAGS_PARAMS | PARSE_FLAGS_VARS;
- ctl.eaten = 0;
-
- status = 0;
-
- gpioLabelStep_t label_step[MAX_SCRIPT_LABELS];
-
- len = strlen(script);
-
- /* calloc space for PARAMS, VARS, CMDS, and STRINGS */
-
- b = (sizeof(int) * (MAX_SCRIPT_PARAMS + MAX_SCRIPT_VARS)) +
- (sizeof(gpioInstr_t) * (len + 2) / 2) + len;
-
- s->param = calloc(b, 1);
-
- if (s->param == NULL) return -1;
-
- s->var = s->param + MAX_SCRIPT_PARAMS;
-
- s->instr = (gpioInstr_t *)(s->var + MAX_SCRIPT_VARS);
-
- s->str_area = (char *)(s->instr + ((len + 2) / 2));
-
- s->str_area_len = len;
- s->str_area_pos = 0;
-
- s->instrs = 0;
-
- labels = 0;
-
- idx = 0;
-
- while (!status && ((ctl.eaten)= 0))
- {
- pos = ctl.eaten;
-
- idx = cmdParse(script, p, v, &ctl);
-
- memcpy(&instr.p, p, sizeof(instr.p));
-
- if (idx >= 0)
- {
- switch (instr.p[0])
- {
- case PI_CMD_LABEL:
-
- if (labels < MAX_SCRIPT_LABELS)
- {
- /* check label not already used */
- for (j=0; jinstrs;
- labels++;
- }
- else
- {
- DBG(DBG_USER, "too many labels: %s", script+pos);
- status = PI_TOO_MANY_LABELS;
- idx = -1;
- }
-
- break;
-
- case PI_CMD_SYS:
-
- strncpy(s->str_area+s->str_area_pos, v[1], p[1]);
- s->str_area[s->str_area_pos+p[1]] = 0;
- instr.p[1] = (int) s->str_area+s->str_area_pos;
- s->str_area_pos += (p[1] + 1);
-
- break;
-
- case PI_CMD_TRIG:
- break;
-
- }
- }
- else
- {
- DBG(DBG_USER, "invalid command: %s", script+pos);
- status = PI_BAD_SCRIPT_CMD;
- }
-
- if (idx >= 0)
- {
- if (instr.p[0] != PI_CMD_LABEL)
- {
- memcpy(instr.opt, &ctl.opt, sizeof(instr.opt));
- s->instr[s->instrs++] = instr;
- }
- }
- }
-
- DBG(DBG_SCRIPT, "status=%d eaten=%d len=%d idx=%d",
- status, ctl.eaten, len, idx);
-
- for (i=0; iinstrs; i++)
- {
- instr = s->instr[i];
-
- /* resolve jumps */
-
- if ((instr.p[0] == PI_CMD_JMP) || (instr.p[0] == PI_CMD_CALL) ||
- (instr.p[0] == PI_CMD_JZ) || (instr.p[0] == PI_CMD_JNZ) ||
- (instr.p[0] == PI_CMD_JM) || (instr.p[0] == PI_CMD_JP))
- {
- resolved = 0;
-
- for (j=0; jinstr[i].p[1] = label_step[j].step;
- resolved = 1;
- break;
- }
- }
-
- if (!resolved)
- {
- DBG(DBG_USER, "can't resolve label %d\n", instr.p[1]);
- status = PI_BAD_SCRIPT;
- }
- }
- }
- return status;
+ if (gpioMask & ((uint64_t)(1)<cb[slot];
}
@@ -1708,9 +1565,9 @@ static uint32_t waveOOLPOadr(int pos)
static void waveCbOPrint(int pos)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
- p = waveCbVOadr(pos);
+ p = rawWaveCBAdr(pos);
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);
@@ -1756,15 +1613,26 @@ static void waveBitDelay(unsigned baud, unsigned * bitDelay)
bitDelay[9] = (e-s)/100;
}
+static int errCBsOOL(int cb, int botOOL, int topOOL)
+{
+ if (cb >= waveOutTopCB) return PI_TOO_MANY_CBS;
+
+ if (botOOL >= topOOL) return PI_TOO_MANY_OOL;
+
+ return 0;
+}
+
/* ----------------------------------------------------------------------- */
static int wave2Cbs(unsigned mode)
{
- int cb=0, onoff=0, level=NUM_OOL;
+ int botCB=waveOutBotCB, botOOL=waveOutBotOOL, topOOL=waveOutTopOOL;
- dmaCbs_t *p=NULL;
+ int status;
- unsigned i, half, repeatCb;
+ rawCbs_t *p=NULL;
+
+ unsigned i, half, repeatCB;
unsigned numWaves;
@@ -1775,9 +1643,11 @@ static int wave2Cbs(unsigned mode)
half = PI_WF_MICROS/2;
+ if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status;
+
/* add delay cb at start of DMA */
- p = waveCbVOadr(cb++);
+ p = rawWaveCBAdr(botCB++);
/* use the secondary clock */
@@ -1786,7 +1656,6 @@ static int wave2Cbs(unsigned mode)
p->info = NORMAL_DMA |
DMA_DEST_DREQ |
DMA_PERIPHERAL_MAPPING(2);
-
p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
}
else
@@ -1794,69 +1663,78 @@ static int wave2Cbs(unsigned mode)
p->info = NORMAL_DMA |
DMA_DEST_DREQ |
DMA_PERIPHERAL_MAPPING(5);
-
p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
}
p->src = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR;
- p->length = 4 * 50 / PI_WF_MICROS; /* 50 micros delay */
- p->next = waveCbPOadr(cb) | DMA_BUS_ADR;
+ p->length = 4 * 20 / PI_WF_MICROS; /* 20 micros delay */
+ p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
- repeatCb = cb;
+ repeatCB = botCB;
for (i=0; iinfo = NORMAL_DMA;
- p->src = waveOOLPOadr(onoff++) | DMA_BUS_ADR;
+ p->src = waveOOLPOadr(botOOL++) | DMA_BUS_ADR;
p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | 0x7e000000;
p->length = 4;
- p->next = waveCbPOadr(cb) | DMA_BUS_ADR;
+ p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
if (waves[i].gpioOff)
{
- waveSetOOL(onoff, waves[i].gpioOff);
+ if ((status = errCBsOOL(botCB+1, botOOL+1, topOOL))) return status;
- p = waveCbVOadr(cb++);
+ waveSetOOL(botOOL, waves[i].gpioOff);
+
+ p = rawWaveCBAdr(botCB++);
p->info = NORMAL_DMA;
- p->src = waveOOLPOadr(onoff++) | DMA_BUS_ADR;
+ p->src = waveOOLPOadr(botOOL++) | DMA_BUS_ADR;
p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | 0x7e000000;
p->length = 4;
- p->next = waveCbPOadr(cb) | DMA_BUS_ADR;
+ p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
if (waves[i].flags & WAVE_FLAG_READ)
{
- p = waveCbVOadr(cb++);
+ if ((status = errCBsOOL(botCB+1, botOOL, topOOL-1))) return status;
+
+ p = rawWaveCBAdr(botCB++);
p->info = NORMAL_DMA;
p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | 0x7e000000;
- p->dst = waveOOLPOadr(--level) | DMA_BUS_ADR;
+ p->dst = waveOOLPOadr(--topOOL) | DMA_BUS_ADR;
p->length = 4;
- p->next = waveCbPOadr(cb) | DMA_BUS_ADR;
+ p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
if (waves[i].flags & WAVE_FLAG_TICK)
{
- p = waveCbVOadr(cb++);
+ if ((status = errCBsOOL(botCB+1, botOOL, topOOL-1))) return status;
+
+ p = rawWaveCBAdr(botCB++);
p->info = NORMAL_DMA;
p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | 0x7e000000;
- p->dst = waveOOLPOadr(--level) | DMA_BUS_ADR;
+ p->dst = waveOOLPOadr(--topOOL) | DMA_BUS_ADR;
p->length = 4;
- p->next = waveCbPOadr(cb) | DMA_BUS_ADR;
+ p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
if (waves[i].usDelay)
{
- p = waveCbVOadr(cb++);
+ if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status;
+
+ p = rawWaveCBAdr(botCB++);
/* use the secondary clock */
@@ -1879,7 +1757,7 @@ static int wave2Cbs(unsigned mode)
p->src = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR;
p->length = 4 * ((waves[i].usDelay+half)/PI_WF_MICROS);
- p->next = waveCbPOadr(cb) | DMA_BUS_ADR;
+ p->next = waveCbPOadr(botCB) | DMA_BUS_ADR;
}
}
@@ -1887,10 +1765,16 @@ static int wave2Cbs(unsigned mode)
{
if (mode == PI_WAVE_MODE_ONE_SHOT)
p->next = 0;
- else p->next = waveCbPOadr(repeatCb) | DMA_BUS_ADR;
+ else p->next = waveCbPOadr(repeatCB) | DMA_BUS_ADR;
}
- return cb;
+ status = botCB - waveOutBotCB;
+
+ waveOutBotCB = botCB;
+ waveOutBotOOL = botOOL;
+ waveOutTopOOL = topOOL;
+
+ return status;
}
@@ -1980,7 +1864,7 @@ static void waveRxBit(int gpio, int level, uint32_t tick)
static int waveMerge(unsigned numIn1, gpioWave_t *in1)
{
- unsigned inPos1=0, inPos2=0, outPos=0, level = NUM_OOL;
+ unsigned inPos1=0, inPos2=0, outPos=0, level = NUM_WAVE_OOL;
unsigned cbs=0;
@@ -2111,7 +1995,7 @@ static int waveMerge(unsigned numIn1, gpioWave_t *in1)
/* ======================================================================= */
-static dmaCbs_t * dmaCB2adr(int pos)
+static rawCbs_t * dmaCB2adr(int pos)
{
int page, slot;
@@ -2125,7 +2009,7 @@ static dmaCbs_t * dmaCB2adr(int pos)
static void dmaCbPrint(int pos)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
p = dmaCB2adr(pos);
@@ -2180,7 +2064,7 @@ static unsigned dmaNowAtICB(void)
/* ----------------------------------------------------------------------- */
-unsigned dmaNowAtOCB(void)
+unsigned rawWaveCB(void)
{
unsigned cb;
static unsigned lastPage=0;
@@ -2296,7 +2180,7 @@ static uint32_t dmaCbAdr(int pos)
static void dmaGpioOnCb(int b, int pos)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
p = dmaCB2adr(b);
@@ -2311,7 +2195,7 @@ static void dmaGpioOnCb(int b, int pos)
static void dmaTickCb(int b, int pos)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
p = dmaCB2adr(b);
@@ -2326,7 +2210,7 @@ static void dmaTickCb(int b, int pos)
static void dmaGpioOffCb(int b, int pos)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
p = dmaCB2adr(b);
@@ -2341,7 +2225,7 @@ static void dmaGpioOffCb(int b, int pos)
static void dmaReadLevelsCb(int b, int pos)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
p = dmaCB2adr(b);
@@ -2356,7 +2240,7 @@ static void dmaReadLevelsCb(int b, int pos)
static void dmaDelayCb(int b)
{
- dmaCbs_t * p;
+ rawCbs_t * p;
p = dmaCB2adr(b);
@@ -2382,7 +2266,7 @@ static void dmaInitCbs(void)
{
int b, pulse, level, cycle;
- dmaCbs_t * p;
+ rawCbs_t * p;
/* set up the DMA control blocks */
@@ -2816,16 +2700,22 @@ static void * pthAlertThread(void *x)
if (err != (MAX_EMITS*sizeof(gpioReport_t)))
{
- DBG(0, "fd=%d err=%d errno=%d",
- gpioNotify[n].fd, err, errno);
- if (err < 0) DBG(0, "%s", strerror(errno));
- if ((err != EAGAIN) && (err != EWOULDBLOCK))
+ if (err < 0)
{
- /* serious error, no point continuing */
- gpioNotify[n].bits = 0;
- gpioNotify[n].state = PI_NOTIFY_CLOSING;
- intNotifyBits();
- break;
+ if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
+ {
+ /* serious error, no point continuing */
+
+ DBG(0, "fd=%d err=%d errno=%d",
+ gpioNotify[n].fd, err, errno);
+
+ DBG(0, "%s", strerror(errno));
+
+ gpioNotify[n].bits = 0;
+ gpioNotify[n].state = PI_NOTIFY_CLOSING;
+ intNotifyBits();
+ break;
+ }
}
}
@@ -2840,16 +2730,21 @@ static void * pthAlertThread(void *x)
if (err != (emit*sizeof(gpioReport_t)))
{
- DBG(0, "fd=%d err=%d errno=%d",
- gpioNotify[n].fd, err, errno);
- if (err < 0) DBG(0, "%s", strerror(errno));
- if ((err != EAGAIN) && (err != EWOULDBLOCK))
+ if (err < 0)
{
- /* serious error, no point continuing */
- gpioNotify[n].bits = 0;
- gpioNotify[n].state = PI_NOTIFY_CLOSING;
- intNotifyBits();
- break;
+ if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
+ {
+ DBG(0, "fd=%d err=%d errno=%d",
+ gpioNotify[n].fd, err, errno);
+
+ DBG(0, "%s", strerror(errno));
+
+ /* serious error, no point continuing */
+ gpioNotify[n].bits = 0;
+ gpioNotify[n].state = PI_NOTIFY_CLOSING;
+ intNotifyBits();
+ break;
+ }
}
}
@@ -2865,7 +2760,7 @@ static void * pthAlertThread(void *x)
if (changedBits & scriptBits)
{
- for (n=0; nrequest == PI_SCRIPT_RUN ) &&
(s->run_state == PI_SCRIPT_RUNNING))
{
- instr = s->instr[PC];
+ instr = s->script.instr[PC];
- p1 = instr.p[1];
- p2 = instr.p[2];
+ p1o = instr.p[1];
+ p2o = instr.p[2];
+
+ if (instr.opt[0] == CMD_VAR) instr.p[1] = s->script.var[p1o];
+ else if (instr.opt[0] == CMD_PAR) instr.p[1] = s->script.par[p1o];
+
+ if (instr.opt[1] == CMD_VAR) instr.p[2] = s->script.var[p2o];
+ else if (instr.opt[1] == CMD_PAR) instr.p[2] = s->script.par[p2o];
if (instr.p[0] < 100)
{
oExt[0].ptr = buf;
oExt[0].size = CMD_BUF_SIZE-1;
- if (instr.opt[0] == CMD_PARAM)
- {
- instr.p[1] = s->param[p1];
- }
- else if (instr.opt[0] == CMD_VAR)
- {
- instr.p[1] = s->var[p1];
- }
-
- if (instr.opt[1] == CMD_PARAM)
- {
- instr.p[2] = s->param[p2];
- }
- else if (instr.opt[1] == CMD_VAR)
- {
- instr.p[2] = s->var[p2];
- }
-
A = myDoCommand(instr.p, oExt);
F = A;
@@ -3050,98 +2933,146 @@ static void *pthScript(void *x)
}
else
{
+ p1 = instr.p[1];
+ p2 = instr.p[2];
+
switch (instr.p[0])
{
- case PI_CMD_ADDI: A+=p1; F=A; PC++; break;
+ case PI_CMD_ADD: A+=p1; F=A; PC++; break;
- case PI_CMD_ADDV: A+=s->var[p1]; F=A; PC++; break;
+ case PI_CMD_AND: A&=p1; F=A; PC++; break;
- case PI_CMD_ANDI: A&=p1; F=A; PC++; break;
+ case PI_CMD_CALL: scrPush(s, &SP, S, PC+1); PC = p1; break;
- case PI_CMD_ANDV: A&=s->var[p1]; F=A; PC++; break;
+ case PI_CMD_CMP: F=A-p1; PC++; break;
- case PI_CMD_CALL: scrPush(s, S, &SP, PC+1); PC = p1; break;
+ case PI_CMD_DCR:
+ if (instr.opt[0] == CMD_PAR)
+ {--s->script.par[p1o]; F=s->script.par[p1o];}
+ else
+ {--s->script.var[p1o]; F=s->script.var[p1o];}
+ PC++;
+ break;
- case PI_CMD_CMPI: F=A-p1; PC++; break;
+ case PI_CMD_DCRA: --A; F=A; PC++; break;
- case PI_CMD_CMPV: F=A-s->var[p1]; PC++; break;
+ case PI_CMD_DIV: A/=p1; F=A; PC++; break;
- case PI_CMD_DCRA: --A; F=A; PC++; break;
+ case PI_CMD_HALT: s->run_state = PI_SCRIPT_HALTED; break;
- case PI_CMD_DCRV: --s->var[p1]; F=s->var[p1]; PC++; break;
+ case PI_CMD_INR:
+ if (instr.opt[0] == CMD_PAR)
+ {++s->script.par[p1o]; F=s->script.par[p1o];}
+ else
+ {++s->script.var[p1o]; F=s->script.var[p1o];}
+ PC++;
+ break;
- case PI_CMD_HALT: s->run_state = PI_SCRIPT_HALTED; break;
+ case PI_CMD_INRA: ++A; F=A; PC++; break;
- case PI_CMD_INRA: ++A; F=A; PC++; break;
+ case PI_CMD_JM: if (F<0) PC=p1; else PC++; break;
- case PI_CMD_INRV: ++s->var[p1]; F=s->var[p1]; PC++; break;
+ case PI_CMD_JMP: PC=p1; break;
- case PI_CMD_JM: if (F<0) PC=p1; else PC++; break;
+ case PI_CMD_JNZ: if (F) PC=p1; else PC++; break;
- case PI_CMD_JMP: PC=p1; break;
+ case PI_CMD_JP: if (F>=0) PC=p1; else PC++; break;
- case PI_CMD_JNZ: if (F) PC=p1; else PC++; break;
+ case PI_CMD_JZ: if (!F) PC=p1; else PC++; break;
- case PI_CMD_JP: if (F>=0) PC=p1; else PC++; break;
+ case PI_CMD_LD:
+ if (instr.opt[0] == CMD_PAR) s->script.par[p1o]=p2;
+ else s->script.var[p1o]=p2;
+ PC++;
+ break;
- case PI_CMD_JZ: if (!F) PC=p1; else PC++; break;
+ case PI_CMD_LDA: A=p1; PC++; break;
- case PI_CMD_LABEL: PC++; break;
+ case PI_CMD_MLT: A*=p1; F=A; PC++; break;
- case PI_CMD_LDAI: A=p1; PC++; break;
+ case PI_CMD_MOD: A%=p1; F=A; PC++; break;
- case PI_CMD_LDAP: A=s->param[p1]; PC++; break;
+ case PI_CMD_OR: A|=p1; F=A; PC++; break;
- case PI_CMD_LDAV: A=s->var[p1]; PC++; break;
+ case PI_CMD_POP:
+ if (instr.opt[0] == CMD_PAR)
+ s->script.par[p1o]=scrPop(s, &SP, S);
+ else
+ s->script.var[p1o]=scrPop(s, &SP, S);
+ PC++;
+ break;
- case PI_CMD_LDPA: s->param[p1]=A; PC++; break;
+ case PI_CMD_POPA: A=scrPop(s, &SP, S); PC++; break;
- case PI_CMD_LDVA: s->var[p1]=A; PC++; break;
+ case PI_CMD_PUSH:
+ if (instr.opt[0] == CMD_PAR)
+ scrPush(s, &SP, S, s->script.par[p1o]);
+ else
+ scrPush(s, &SP, S, s->script.var[p1o]);
+ PC++;
+ break;
- case PI_CMD_LDVI: s->var[p1] = p2; PC++; break;
+ case PI_CMD_PUSHA: scrPush(s, &SP, S, A); PC++; break;
- case PI_CMD_LDVV: s->var[p1]=s->var[p2]; PC++; break;
+ case PI_CMD_RET: PC=scrPop(s, &SP, S); break;
- case PI_CMD_ORI: A|=p1; F=A; PC++; break;
+ case PI_CMD_RL:
+ if (instr.opt[0] == CMD_PAR)
+ {s->script.par[p1o]<<=p2; F=s->script.par[p1o];}
+ else
+ {s->script.var[p1o]<<=p2; F=s->script.var[p1o];}
+ PC++;
+ break;
- case PI_CMD_ORV: A|=s->var[p1]; F=A; PC++; break;
+ case PI_CMD_RLA: A<<=p1; F=A; PC++; break;
- case PI_CMD_POPA: A=scrPop(s, S, &SP); PC++; break;
+ case PI_CMD_RR:
+ if (instr.opt[0] == CMD_PAR)
+ {s->script.par[p1o]>>=p2; F=s->script.par[p1o];}
+ else
+ {s->script.var[p1o]>>=p2; F=s->script.var[p1o];}
+ PC++;
+ break;
- case PI_CMD_POPV: s->var[p1]=scrPop(s, S, &SP); PC++; break;
+ case PI_CMD_RRA: A>>=p1; F=A; PC++; break;
- case PI_CMD_PUSHA: scrPush(s, S, &SP, A); PC++; break;
+ case PI_CMD_STA:
+ if (instr.opt[0] == CMD_PAR) s->script.par[p1o]=A;
+ else s->script.var[p1o]=A;
+ PC++;
+ break;
- case PI_CMD_PUSHV: scrPush(s, S, &SP, s->var[p1]); PC++; break;
+ case PI_CMD_SUB: A-=p1; F=A; PC++; break;
- case PI_CMD_RET: PC=scrPop(s, S, &SP); break;
+ case PI_CMD_X:
+ if (instr.opt[0] == CMD_PAR) t1 = &s->script.par[p1o];
+ else t1 = &s->script.var[p1o];
- case PI_CMD_RAL: A<<=p1; F=A; PC++; break;
+ if (instr.opt[1] == CMD_PAR) t2 = &s->script.par[p2o];
+ else t2 = &s->script.var[p2o];
- case PI_CMD_RAR: A>>=p1; F=A; PC++; break;
+ scrSwap(t1, t2);
+ PC++;
+ break;
- case PI_CMD_SUBI: A-=p1; F=A; PC++; break;
+ case PI_CMD_XA:
+ if (instr.opt[0] == CMD_PAR)
+ scrSwap(&s->script.par[p1o], &A);
+ else
+ scrSwap(&s->script.var[p1o], &A);
+ PC++;
+ break;
- case PI_CMD_SUBV: A-=s->var[p1]; F=A; PC++; break;
+ case PI_CMD_SYS: A=scrSys((char*)p1, A); F=A; PC++; break;
- case PI_CMD_SWAPA: scrSwap(&s->var[p1], &A); PC++; break;
+ case PI_CMD_WAIT: A=scrWait(s, p1); F=A; PC++; break;
- case PI_CMD_SWAPV: scrSwap(&s->var[p1], &s->var[p2]);PC++; break;
-
- case PI_CMD_SYS: A=scrSys((char*)p1, A); F=A; PC++; break;
-
- case PI_CMD_WAITI: A=scrWait(s, p1); F=A; PC++; break;
-
- case PI_CMD_WAITV: A=scrWait(s, s->var[p1]); F=A; PC++; break;
-
- case PI_CMD_XORI: A^=p1; F=A; PC++; break;
-
- case PI_CMD_XORV: A^=s->var[p1]; F=A; PC++; break;
+ case PI_CMD_XOR: A^=p1; F=A; PC++; break;
}
}
- if (PC >= s->instrs) s->run_state = PI_SCRIPT_HALTED;
+ if (PC >= s->script.instrs) s->run_state = PI_SCRIPT_HALTED;
}
@@ -3214,12 +3145,10 @@ static void * pthFifoThread(void *x)
uint32_t p[10];
void *v[10];
gpioExtent_t oExt[3];
- gpioCtlParse_t ctl;
+ cmdCtlParse_t ctl;
char *pp;
uint32_t *param;
- ctl.flags = 0;
-
myCreatePipe(PI_INPFIFO, 0662);
if ((inpFifo = fopen(PI_INPFIFO, "r+")) == NULL)
@@ -3310,7 +3239,7 @@ static void * pthFifoThread(void *x)
{
fprintf(outFifo, "%d", res);
param = oExt[0].ptr;
- for (i=0; i= 0)
{
- write(sock, oExt[0].ptr, sizeof(uint32_t)*MAX_SCRIPT_PARAMS);
+ write(sock, oExt[0].ptr, sizeof(uint32_t)*PI_MAX_SCRIPT_PARAMS);
}
break;
@@ -4390,11 +4319,11 @@ void putBitInBytes(int bitPos, uint8_t *buf, int val)
/* ----------------------------------------------------------------------- */
-uint32_t waveGetRawOut(int pos)
+uint32_t rawWaveGetOut(int pos)
{
int page, slot;
- if ((pos >= 0) && (pos < NUM_OOL))
+ if ((pos >= 0) && (pos < NUM_WAVE_OOL))
{
waveOOLPageSlot(pos, &page, &slot);
return (dmaOVirt[page]->OOL[slot]);
@@ -4409,7 +4338,7 @@ void waveSetRawOut(int pos, uint32_t value)
{
int page, slot;
- if ((pos >= 0) && (pos < NUM_OOL))
+ if ((pos >= 0) && (pos < NUM_WAVE_OOL))
{
waveOOLPageSlot(pos, &page, &slot);
dmaOVirt[page]->OOL[slot] = value;
@@ -4419,13 +4348,13 @@ void waveSetRawOut(int pos, uint32_t value)
/* ----------------------------------------------------------------------- */
-uint32_t waveGetRawIn(int pos)
+uint32_t rawWaveGetIn(int pos)
{
int page, slot;
- if ((pos >= 0) && (pos < NUM_OOL))
+ if ((pos >= 0) && (pos < NUM_WAVE_OOL))
{
- waveOOLPageSlot((NUM_OOL-1)-pos, &page, &slot);
+ waveOOLPageSlot((NUM_WAVE_OOL-1)-pos, &page, &slot);
return (dmaOVirt[page]->OOL[slot]);
}
@@ -4434,13 +4363,13 @@ uint32_t waveGetRawIn(int pos)
/* ----------------------------------------------------------------------- */
-void waveSetRawIn(int pos, uint32_t value)
+void rawWaveSetIn(int pos, uint32_t value)
{
int page, slot;
- if ((pos >= 0) && (pos < NUM_OOL))
+ if ((pos >= 0) && (pos < NUM_WAVE_OOL))
{
- waveOOLPageSlot((NUM_OOL-1)-pos, &page, &slot);
+ waveOOLPageSlot((NUM_WAVE_OOL-1)-pos, &page, &slot);
dmaOVirt[page]->OOL[slot] = value;
}
}
@@ -4481,7 +4410,7 @@ void time_sleep(double seconds)
/* ----------------------------------------------------------------------- */
-void gpioDumpWave(void)
+void rawDumpWave(void)
{
int i;
@@ -4505,30 +4434,30 @@ void gpioDumpWave(void)
/* ----------------------------------------------------------------------- */
-void gpioDumpScript(int s)
+void rawDumpScript(int s)
{
int i;
- for (i=0; i= waveOutCount)
+ SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
+
+ waveOutBotCB = waveInfo[wave_id].botCB;
+ waveOutBotOOL = waveInfo[wave_id].botOOL;
+ waveOutTopOOL = waveInfo[wave_id].topOOL;
+
+ waveOutCount = wave_id;
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveTxStart(unsigned mode)
+{
+ /* This function is deprecated and will be removed. */
+
+ static int secondaryClockInited = 0;
+
+ int cb, i;
+
+ DBG(DBG_USER, "mode=%d", mode);
+
+ CHECK_INITED;
+
+ if (mode > PI_WAVE_MODE_REPEAT)
+ SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", mode);
+
+ if (wfc[wfcur] == 0) return 0;
+
+ if (!secondaryClockInited)
+ {
+ initClock(0); /* initialise secondary clock */
+ secondaryClockInited = 1;
+ }
+
+ dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+
+ dmaOut[DMA_CONBLK_AD] = 0;
+
+ waveOutBotCB = 0;
+ waveOutTopCB = NUM_WAVE_CBS;
+ waveOutBotOOL = 0;
+ waveOutTopOOL = NUM_WAVE_OOL;
+
+ waveOutCount = 0;
+
+ cb = wave2Cbs(mode);
+
+ if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
+ {
+ fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
+ for (i=0; i= waveOutCount)
+ SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
+
+ if (mode > PI_WAVE_MODE_REPEAT)
+ SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", mode);
+
+ if (!secondaryClockInited)
+ {
+ initClock(0); /* initialise secondary clock */
+ secondaryClockInited = 1;
+ }
+
+ p = rawWaveCBAdr(waveInfo[wave_id].topCB);
+
+ if (mode == PI_WAVE_MODE_ONE_SHOT) p->next = 0;
+ else p->next = waveCbPOadr(waveInfo[wave_id].botCB+1) | DMA_BUS_ADR;
+
+ dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+
+ dmaOut[DMA_CONBLK_AD] = 0;
+
+ initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
+
+ /* for compatability with the deprecated gpioWaveTxStart return the
+ number of cbs
+ */
+ return (waveInfo[wave_id].topCB - waveInfo[wave_id].botCB) + 1;
+}
+
+/*-------------------------------------------------------------------------*/
+
+int gpioWaveTxBusy(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ if (dmaOut[DMA_CONBLK_AD])
+ return 1;
+ else
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveTxStop(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+
+ dmaOut[DMA_CONBLK_AD] = 0;
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetMicros(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.micros;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetHighMicros(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.highMicros;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetMaxMicros(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.maxMicros;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetPulses(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.pulses;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetHighPulses(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.highPulses;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetMaxPulses(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.maxPulses;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetCbs(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.cbs;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetHighCbs(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.highCbs;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int gpioWaveGetMaxCbs(void)
+{
+ DBG(DBG_USER, "");
+
+ CHECK_INITED;
+
+ return wfStats.maxCbs;
+}
+
/*-------------------------------------------------------------------------*/
int gpioSerialReadOpen(unsigned gpio, unsigned baud)
@@ -5540,7 +5656,7 @@ int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize)
if (bytes > bufSize) bytes = bufSize;
- memcpy(buf, p->buf+p->readPos, bytes);
+ if (buf) memcpy(buf, p->buf+p->readPos, bytes);
p->readPos += bytes;
@@ -5586,78 +5702,6 @@ int gpioSerialReadClose(unsigned gpio)
}
-/*-------------------------------------------------------------------------*/
-
-int gpioWaveTxBusy(void)
-{
- DBG(DBG_USER, "");
-
- CHECK_INITED;
-
- if (dmaOut[DMA_CONBLK_AD])
- return 1;
- else
- return 0;
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-int gpioWaveTxStart(unsigned mode)
-{
- static int secondaryClockInited = 0;
-
- int cb, i;
-
- DBG(DBG_USER, "mode=%d", mode);
-
- CHECK_INITED;
-
- if (mode > PI_WAVE_MODE_REPEAT)
- SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", mode);
-
- if (wfc[wfcur] == 0) return 0;
-
- if (!secondaryClockInited)
- {
- initClock(0); /* initialise secondary clock */
- secondaryClockInited = 1;
- }
-
- dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
-
- dmaOut[DMA_CONBLK_AD] = 0;
-
- cb = wave2Cbs(mode);
-
- if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
- {
- fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
- for (i=0; i PI_NOTIFY_SLOTS)
+ if (handle >= PI_NOTIFY_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
@@ -5879,7 +5923,7 @@ int gpioNotifyPause (unsigned handle)
CHECK_INITED;
- if (handle > PI_NOTIFY_SLOTS)
+ if (handle >= PI_NOTIFY_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
@@ -5903,7 +5947,7 @@ int gpioNotifyClose(unsigned handle)
CHECK_INITED;
- if (handle > PI_NOTIFY_SLOTS)
+ if (handle >= PI_NOTIFY_SLOTS)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
@@ -6171,7 +6215,7 @@ int gpioStoreScript(char *script)
slot = -1;
- for (i=0; iscript, 0);
if (status == 0)
{
@@ -6207,8 +6251,8 @@ int gpioStoreScript(char *script)
}
else
{
- if (s->param) free(s->param);
- s->param = NULL;
+ if (s->script.par) free(s->script.par);
+ s->script.par = NULL;
gpioScript[slot].state = PI_SCRIPT_FREE;
}
@@ -6218,7 +6262,7 @@ int gpioStoreScript(char *script)
/* ----------------------------------------------------------------------- */
-int gpioRunScript(int script_id, unsigned numParam, uint32_t *param)
+int gpioRunScript(unsigned script_id, unsigned numParam, uint32_t *param)
{
int status = 0;
@@ -6227,7 +6271,10 @@ int gpioRunScript(int script_id, unsigned numParam, uint32_t *param)
CHECK_INITED;
- if (numParam > MAX_SCRIPT_PARAMS)
+ if (script_id >= PI_MAX_SCRIPTS)
+ SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
+
+ if (numParam > PI_MAX_SCRIPT_PARAMS)
SOFT_ERROR(PI_TOO_MANY_PARAM, "bad number of parameters(%d)", numParam);
if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
@@ -6238,7 +6285,7 @@ int gpioRunScript(int script_id, unsigned numParam, uint32_t *param)
{
if ((numParam > 0) && (param != 0))
{
- memcpy(gpioScript[script_id].param, param,
+ memcpy(gpioScript[script_id].script.par, param,
sizeof(uint32_t) * numParam);
}
@@ -6255,24 +6302,30 @@ int gpioRunScript(int script_id, unsigned numParam, uint32_t *param)
return status;
}
- else return PI_BAD_SCRIPT_ID;
+ else
+ {
+ return PI_BAD_SCRIPT_ID;
+ }
}
/* ----------------------------------------------------------------------- */
-int gpioScriptStatus(int script_id, uint32_t *param)
+int gpioScriptStatus(unsigned script_id, uint32_t *param)
{
DBG(DBG_USER, "script_id=%d param=%08X", script_id, (uint32_t)param);
CHECK_INITED;
+ if (script_id >= PI_MAX_SCRIPTS)
+ SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
+
if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
{
if (param != 0)
{
- memcpy(param, gpioScript[script_id].param,
- sizeof(uint32_t) * MAX_SCRIPT_PARAMS);
+ memcpy(param, gpioScript[script_id].script.par,
+ sizeof(uint32_t) * PI_MAX_SCRIPT_PARAMS);
}
return gpioScript[script_id].run_state;
@@ -6283,12 +6336,15 @@ int gpioScriptStatus(int script_id, uint32_t *param)
/* ----------------------------------------------------------------------- */
-int gpioStopScript(int script_id)
+int gpioStopScript(unsigned script_id)
{
DBG(DBG_USER, "script_id=%d", script_id);
CHECK_INITED;
+ if (script_id >= PI_MAX_SCRIPTS)
+ SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
+
if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
{
pthread_mutex_lock(&gpioScript[script_id].pthMutex);
@@ -6309,12 +6365,15 @@ int gpioStopScript(int script_id)
/* ----------------------------------------------------------------------- */
-int gpioDeleteScript(int script_id)
+int gpioDeleteScript(unsigned script_id)
{
DBG(DBG_USER, "script_id=%d", script_id);
CHECK_INITED;
+ if (script_id >= PI_MAX_SCRIPTS)
+ SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
+
if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
{
gpioScript[script_id].state = PI_SCRIPT_DYING;
@@ -6337,9 +6396,9 @@ int gpioDeleteScript(int script_id)
gpioStopThread(gpioScript[script_id].pthIdp);
- if (gpioScript[script_id].param) free(gpioScript[script_id].param);
+ if (gpioScript[script_id].script.par) free(gpioScript[script_id].script.par);
- gpioScript[script_id].param = NULL;
+ gpioScript[script_id].script.par = NULL;
gpioScript[script_id].state = PI_SCRIPT_FREE;
@@ -6559,7 +6618,7 @@ uint32_t gpioDelay(uint32_t micros)
start = systReg[SYST_CLO];
- if (micros < 101) while ((systReg[SYST_CLO] - start) <= micros) ;
+ if (micros <= MAX_DELAY) while ((systReg[SYST_CLO] - start) <= micros) ;
else gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION));
diff --git a/pigpio.h b/pigpio.h
index 0ddac32..6b163dd 100644
--- a/pigpio.h
+++ b/pigpio.h
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 13
+This version is for pigpio version 14
*/
#ifndef PIGPIO_H
@@ -86,7 +86,7 @@ This version is for pigpio version 13
#include
#include
-#define PIGPIO_VERSION 13
+#define PIGPIO_VERSION 14
/*-------------------------------------------------------------------------*/
@@ -125,18 +125,21 @@ gpioNotifyBegin Begin a gpio(s) changed notification.
gpioNotifyPause Pause a gpio(s) changed notification.
gpioNotifyClose Close a gpio(s) changed notification.
-gpioWaveClear Initialises a new waveform.
+gpioWaveClear Deletes all waveforms.
+
+gpioWaveAddNew Starts a new waveform.
gpioWaveAddGeneric Adds a series of pulses to the waveform.
gpioWaveAddSerial Adds serial data to the waveform.
-gpioWaveTxStart Transmits the waveform.
+gpioWaveCreate Creates a waveform from added data.
+gpioWaveDelete Deletes one or more waveforms.
+
+gpioWaveTxStart Creates/transmits a waveform (DEPRECATED).
+
+gpioWaveTxSend Transmits a waveform.
gpioWaveTxBusy Checks to see if the waveform has ended.
gpioWaveTxStop Aborts the current waveform.
-gpioSerialReadOpen Opens a gpio for reading serial data.
-gpioSerialRead Reads serial data from a gpio.
-gpioSerialReadClose Closes a gpio for reading serial data.
-
gpioWaveGetMicros Length in microseconds of the current waveform.
gpioWaveGetHighMicros Length of longest waveform so far.
gpioWaveGetMaxMicros Absolute maximum allowed micros.
@@ -149,6 +152,10 @@ gpioWaveGetCbs Length in cbs of the current waveform.
gpioWaveGetHighCbs Length of longest waveform so far.
gpioWaveGetMaxCbs Absolute maximum allowed cbs.
+gpioSerialReadOpen Opens a gpio for reading serial data.
+gpioSerialRead Reads serial data from a gpio.
+gpioSerialReadClose Closes a gpio for reading serial data.
+
gpioTrigger Send a trigger pulse to a gpio.
gpioSetWatchdog Set a watchdog on a gpio.
@@ -281,7 +288,17 @@ typedef struct
int clk_pol; /* clock off state */
int clk_pha; /* clock phase */
int clk_us; /* clock micros */
-} gpioSPI_t;
+} rawSPI_t;
+
+typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */
+ unsigned long info;
+ unsigned long src;
+ unsigned long dst;
+ unsigned long length;
+ unsigned long stride;
+ unsigned long next;
+ unsigned long pad[2];
+} rawCbs_t;
typedef void (*gpioAlertFunc_t) (int gpio,
int level,
@@ -873,34 +890,26 @@ int gpioNotifyClose(unsigned handle);
/*-------------------------------------------------------------------------*/
int gpioWaveClear(void);
/*-------------------------------------------------------------------------*/
-/* This function initialises a new waveform.
+/* This function clears all waveforms and any data added by calls to the
+ gpioWaveAdd* functions.
Returns 0 if OK.
-
- A waveform comprises one of more pulses. Each pulse consists of a
- gpioPulse_t structure.
-
- typedef struct
- {
- uint32_t gpioOn;
- uint32_t gpioOff;
- uint32_t usDelay;
- } gpioPulse_t;
-
- The fields specify
-
- 1) the gpios to be switched on at the start of the pulse.
- 2) the gpios to be switched off at the start of the pulse.
- 3) the delay in microseconds before the next pulse.
-
- Any or all the fields can be zero. It doesn't make any sense to
- set all the fields to zero (the pulse will be ignored).
-
- When a waveform is started each pulse is executed in order with the
- specified delay between the pulse and the next.
*/
+
+/*-------------------------------------------------------------------------*/
+int gpioWaveAddNew(void);
+/*-------------------------------------------------------------------------*/
+/* This function starts a new empty waveform. You wouldn't normally need
+ to call this function as it is automatically called after a waveform is
+ created with the gpioWaveCreate function.
+
+ Returns 0 if OK.
+*/
+
+
+
/*-------------------------------------------------------------------------*/
int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
/*-------------------------------------------------------------------------*/
@@ -911,7 +920,7 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
NOTES:
- The pulses are interleaved in time order within the existing waveform
+ The pulses are interleaved in time order within the existing waveform
(if any).
Merging allows the waveform to be built in parts, that is the settings
@@ -956,16 +965,97 @@ int gpioWaveAddSerial(unsigned user_gpio,
#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
+#define PI_MAX_WAVES 100
+
+
+
/*-------------------------------------------------------------------------*/
-int gpioWaveTxStart(unsigned mode);
+int gpioWaveCreate(void);
/*-------------------------------------------------------------------------*/
-/* This function transmits the current waveform. The mode determines
- whether the waveform is sent once or cycles endlessly.
+/* This function creates a waveform from the data provided by the prior
+ calls to the gpioWaveAdd* functions. Upon success a positive wave id
+ is returned.
+
+ The data provided by the gpioWaveAdd* functions is consumed by this
+ function.
+
+ As many waveforms may be created as there is space available. The
+ wave id is passed to gpioWaveTxSend to specify the waveform to transmit.
+
+ Normal usage would be
+
+ Step 1. gpioWaveClear to clear all waveforms and added data.
+
+ Step 2. gpioWaveAdd* calls to supply the waveform data.
+
+ Step 3. gpioWaveCreate to create the waveform and get a unique id
+
+ Repeat steps 2 and 3 as needed.
+
+ Step 4. gpioWaveTxSend with the id of the waveform to transmit.
+
+ A waveform comprises one of more pulses. Each pulse consists of a
+ gpioPulse_t structure.
+
+ typedef struct
+ {
+ uint32_t gpioOn;
+ uint32_t gpioOff;
+ uint32_t usDelay;
+ } gpioPulse_t;
+
+ The fields specify
+
+ 1) the gpios to be switched on at the start of the pulse.
+ 2) the gpios to be switched off at the start of the pulse.
+ 3) the delay in microseconds before the next pulse.
+
+ Any or all the fields can be zero. It doesn't make any sense to
+ set all the fields to zero (the pulse will be ignored).
+
+ When a waveform is started each pulse is executed in order with the
+ specified delay between the pulse and the next.
+
+ Returns the new waveform id if OK, otherwise PI_EMPTY_WAVEFORM,
+ PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
+*/
+
+
+/*-------------------------------------------------------------------------*/
+int gpioWaveDelete(unsigned wave_id);
+/*-------------------------------------------------------------------------*/
+/* This function deletes all created waveforms with ids greater than or
+ equal to wave_id.
+
+ Wave ids are allocated in order, 0, 1, 2, etc.
+
+ Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
+*/
+
+
+/*-------------------------------------------------------------------------*/
+int gpioWaveTxStart(unsigned mode); /* DEPRECATED */
+/*-------------------------------------------------------------------------*/
+/* This function creates and then transmits a waveform. The mode
+ determines whether the waveform is sent once or cycles endlessly.
+
+ This function is deprecated and should no longer be used. Use
+ gpioWaveCreate/gpioWaveTxSend instead.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
+/*-------------------------------------------------------------------------*/
+int gpioWaveTxSend(unsigned wave_id, unsigned mode);
+/*-------------------------------------------------------------------------*/
+/* This function transmits the waveform with id wave_id. The mode
+ determines whether the waveform is sent once or cycles endlessly.
+
+ Returns the number of DMA control blocks in the waveform if OK,
+ otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
+*/
+
#define PI_WAVE_MODE_ONE_SHOT 0
#define PI_WAVE_MODE_REPEAT 1
@@ -991,46 +1081,7 @@ int gpioWaveTxStop(void);
NOTES:
- This function is intended to stop a waveform started with the repeat mode.
-*/
-
-
-
-/*-------------------------------------------------------------------------*/
-int gpioSerialReadOpen(unsigned user_gpio, unsigned baud);
-/*-------------------------------------------------------------------------*/
-/* This function opens a gpio for reading serial data.
-
- Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
- or PI_GPIO_IN_USE.
-
- The serial data is returned in a cyclic buffer and is read using
- gpioSerialRead().
-
- It is the caller's responsibility to read data from the cyclic buffer
- in a timely fashion.
-*/
-
-
-
-/*-------------------------------------------------------------------------*/
-int gpioSerialRead(unsigned user_gpio, void *buf, size_t bufSize);
-/*-------------------------------------------------------------------------*/
-/* This function copies up to bufSize bytes of data read from the
- serial cyclic buffer to the buffer starting at buf.
-
- Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
- or PI_NOT_SERIAL_GPIO.
-*/
-
-
-
-/*-------------------------------------------------------------------------*/
-int gpioSerialReadClose(unsigned user_gpio);
-/*-------------------------------------------------------------------------*/
-/* This function closes a gpio for reading serial data.
-
- Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
+ This function is intended to stop a waveform started in repeat mode.
*/
@@ -1114,6 +1165,45 @@ int gpioWaveGetMaxCbs(void);
+/*-------------------------------------------------------------------------*/
+int gpioSerialReadOpen(unsigned user_gpio, unsigned baud);
+/*-------------------------------------------------------------------------*/
+/* This function opens a gpio for reading serial data.
+
+ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
+ or PI_GPIO_IN_USE.
+
+ The serial data is returned in a cyclic buffer and is read using
+ gpioSerialRead().
+
+ It is the caller's responsibility to read data from the cyclic buffer
+ in a timely fashion.
+*/
+
+
+
+/*-------------------------------------------------------------------------*/
+int gpioSerialRead(unsigned user_gpio, void *buf, size_t bufSize);
+/*-------------------------------------------------------------------------*/
+/* This function copies up to bufSize bytes of data read from the
+ serial cyclic buffer to the buffer starting at buf.
+
+ Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
+ or PI_NOT_SERIAL_GPIO.
+*/
+
+
+
+/*-------------------------------------------------------------------------*/
+int gpioSerialReadClose(unsigned user_gpio);
+/*-------------------------------------------------------------------------*/
+/* This function closes a gpio for reading serial data.
+
+ Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
+*/
+
+
+
/*-------------------------------------------------------------------------*/
int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
/*-------------------------------------------------------------------------*/
@@ -1124,7 +1214,7 @@ int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
or PI_BAD_PULSELEN.
*/
-#define PI_MAX_PULSELEN 100
+#define PI_MAX_PULSELEN 50
/*-------------------------------------------------------------------------*/
@@ -1351,13 +1441,15 @@ int gpioStoreScript(char *script);
otherwise PI_BAD_SCRIPT.
*/
-#define MAX_SCRIPT_LABELS 50
-#define MAX_SCRIPT_VARS 150
-#define MAX_SCRIPT_PARAMS 10
+#define PI_MAX_SCRIPTS 32
+
+#define PI_MAX_SCRIPT_TAGS 50
+#define PI_MAX_SCRIPT_VARS 150
+#define PI_MAX_SCRIPT_PARAMS 10
/* ----------------------------------------------------------------------- */
-int gpioRunScript(int script_id, unsigned numParam, uint32_t *param);
+int gpioRunScript(unsigned script_id, unsigned numParam, uint32_t *param);
/* ----------------------------------------------------------------------- */
/* This function runs a stored script.
@@ -1371,7 +1463,7 @@ int gpioRunScript(int script_id, unsigned numParam, uint32_t *param);
/* ----------------------------------------------------------------------- */
-int gpioScriptStatus(int script_id, uint32_t *param);
+int gpioScriptStatus(unsigned script_id, uint32_t *param);
/* ----------------------------------------------------------------------- */
/* This function returns the run status of a stored script as well as
the current values of parameters 0 to 9.
@@ -1399,7 +1491,7 @@ int gpioScriptStatus(int script_id, uint32_t *param);
/* ----------------------------------------------------------------------- */
-int gpioStopScript(int script_id);
+int gpioStopScript(unsigned script_id);
/* ----------------------------------------------------------------------- */
/* This function stops a running script.
@@ -1409,7 +1501,7 @@ int gpioStopScript(int script_id);
/* ----------------------------------------------------------------------- */
-int gpioDeleteScript(int script_id);
+int gpioDeleteScript(unsigned script_id);
/* ----------------------------------------------------------------------- */
/* This function deletes a stored script.
@@ -1615,7 +1707,8 @@ uint32_t gpioDelay(uint32_t micros);
Returns the actual length of the delay in microseconds.
*/
-
+#define PI_MAX_MICS_DELAY 1000000 /* 1 second */
+#define PI_MAX_MILS_DELAY 60000 /* 60 seconds */
/*-------------------------------------------------------------------------*/
uint32_t gpioTick(void);
@@ -1860,12 +1953,13 @@ int gpioCfgInternals(unsigned what,
int value);
/*-------------------------------------------------------------------------*/
/* Used to tune internal settings.
+
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
-int gpioWaveAddSPI(
- gpioSPI_t *spi,
+int rawWaveAddSPI(
+ rawSPI_t *spi,
unsigned offset,
unsigned ss,
uint8_t *tx_bits,
@@ -1883,36 +1977,59 @@ int gpioWaveAddSPI(
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_BAD_USER_GPIO, PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
+
+ Not intended for general use.
*/
+/* ----------------------------------------------------------------------- */
+unsigned rawWaveCB(void);
+/* ----------------------------------------------------------------------- */
+/*
+ Returns the number of the cb being currently output.
+
+ Not intended for general use.
+*/
/* ----------------------------------------------------------------------- */
-uint32_t waveGetRawOut(int pos);
+rawCbs_t * rawWaveCBAdr(int n);
+/* ----------------------------------------------------------------------- */
+/*
+ Return the Linux address of contol block n.
+
+ Not intended for general use.
+*/
+
+/* ----------------------------------------------------------------------- */
+uint32_t rawWaveGetOut(int pos);
/* ----------------------------------------------------------------------- */
/* Gets the wave output parameter stored at pos.
+
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
-void waveSetRawOut(int pos, uint32_t value);
+void rawWaveSetOut(int pos, uint32_t value);
/* ----------------------------------------------------------------------- */
/* Sets the wave output parameter stored at pos to value.
+
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
-uint32_t waveGetRawIn(int pos);
+uint32_t rawWaveGetIn(int pos);
/* ----------------------------------------------------------------------- */
/* Gets the wave input value parameter stored at pos.
+
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
-void waveSetRawIn(int pos, uint32_t value);
+void rawWaveSetIn(int pos, uint32_t value);
/* ----------------------------------------------------------------------- */
/* Sets the wave input value stored at pos to value.
+
Not intended for general use.
*/
@@ -1944,17 +2061,19 @@ void time_sleep(double seconds);
/*-------------------------------------------------------------------------*/
-void gpioDumpWave(void);
+void rawDumpWave(void);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of the current waveform to stderr.
+
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
-void gpioDumpScript(int s);
+void rawDumpScript(int s);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of a script to stderr.
+
Not intended for general use.
*/
@@ -2011,8 +2130,14 @@ void gpioDumpScript(int s);
#define PI_CMD_SLR 43
#define PI_CMD_SLRC 44
#define PI_CMD_PROCP 45
-#define PI_CMD_MICRO 46
-#define PI_CMD_MILLI 47
+#define PI_CMD_MICS 46
+#define PI_CMD_MILS 47
+#define PI_CMD_PARSE 48
+#define PI_CMD_WVCRE 49
+#define PI_CMD_WVDEL 50
+#define PI_CMD_WVTX 51
+#define PI_CMD_WVTXR 52
+#define PI_CMD_WVNEW 53
/*
@@ -2031,49 +2156,43 @@ after this command is issued.
#define PI_CMD_SCRIPT 800
-#define PI_CMD_ADDI 800
-#define PI_CMD_ADDV 801
-#define PI_CMD_ANDI 802
-#define PI_CMD_ANDV 803
-#define PI_CMD_CALL 804
-#define PI_CMD_CMPI 805
-#define PI_CMD_CMPV 806
-#define PI_CMD_DCRA 807
-#define PI_CMD_DCRV 808
-#define PI_CMD_HALT 809
-#define PI_CMD_INRA 810
-#define PI_CMD_INRV 811
-#define PI_CMD_JM 812
-#define PI_CMD_JMP 813
-#define PI_CMD_JNZ 814
-#define PI_CMD_JP 815
-#define PI_CMD_JZ 816
-#define PI_CMD_LABEL 817
-#define PI_CMD_LDAI 818
-#define PI_CMD_LDAP 819
-#define PI_CMD_LDAV 820
-#define PI_CMD_LDPA 821
-#define PI_CMD_LDVA 822
-#define PI_CMD_LDVI 823
-#define PI_CMD_LDVV 824
-#define PI_CMD_ORI 827
-#define PI_CMD_ORV 828
-#define PI_CMD_POPA 829
-#define PI_CMD_POPV 830
-#define PI_CMD_PUSHA 831
-#define PI_CMD_PUSHV 832
-#define PI_CMD_RET 833
-#define PI_CMD_RAL 834
-#define PI_CMD_RAR 835
-#define PI_CMD_SUBI 836
-#define PI_CMD_SUBV 837
-#define PI_CMD_SWAPA 838
-#define PI_CMD_SWAPV 839
-#define PI_CMD_SYS 840
-#define PI_CMD_WAITI 841
-#define PI_CMD_WAITV 842
-#define PI_CMD_XORI 843
-#define PI_CMD_XORV 844
+#define PI_CMD_ADD 800
+#define PI_CMD_AND 801
+#define PI_CMD_CALL 802
+#define PI_CMD_CMP 803
+#define PI_CMD_DCR 804
+#define PI_CMD_DCRA 805
+#define PI_CMD_DIV 806
+#define PI_CMD_HALT 807
+#define PI_CMD_INR 808
+#define PI_CMD_INRA 809
+#define PI_CMD_JM 810
+#define PI_CMD_JMP 811
+#define PI_CMD_JNZ 812
+#define PI_CMD_JP 813
+#define PI_CMD_JZ 814
+#define PI_CMD_TAG 815
+#define PI_CMD_LD 816
+#define PI_CMD_LDA 817
+#define PI_CMD_MLT 818
+#define PI_CMD_MOD 819
+#define PI_CMD_OR 820
+#define PI_CMD_POP 821
+#define PI_CMD_POPA 822
+#define PI_CMD_PUSH 823
+#define PI_CMD_PUSHA 824
+#define PI_CMD_RET 825
+#define PI_CMD_RL 826
+#define PI_CMD_RLA 827
+#define PI_CMD_RR 828
+#define PI_CMD_RRA 829
+#define PI_CMD_STA 830
+#define PI_CMD_SUB 831
+#define PI_CMD_SYS 832
+#define PI_CMD_WAIT 833
+#define PI_CMD_X 834
+#define PI_CMD_XA 835
+#define PI_CMD_XOR 836
/*-------------------------------------------------------------------------*/
@@ -2126,15 +2245,15 @@ after this command is issued.
#define PI_BAD_WVSC_COMMND -43 /* bad WVSC subcommand */
#define PI_BAD_WVSM_COMMND -44 /* bad WVSM subcommand */
#define PI_BAD_WVSP_COMMND -45 /* bad WVSP subcommand */
-#define PI_BAD_PULSELEN -46 /* trigger pulse length > 100 */
+#define PI_BAD_PULSELEN -46 /* trigger pulse length > 50 */
#define PI_BAD_SCRIPT -47 /* invalid script */
#define PI_BAD_SCRIPT_ID -48 /* unknown script id */
#define PI_BAD_SER_OFFSET -49 /* add serial data offset > 30 minutes */
#define PI_GPIO_IN_USE -50 /* gpio already in use */
#define PI_BAD_SERIAL_COUNT -51 /* must read at least a byte at a time */
#define PI_BAD_PARAM_NUM -52 /* script parameter must be 0-9 */
-#define PI_DUP_LABEL -53 /* script has duplicate label */
-#define PI_TOO_MANY_LABELS -54 /* script has too many labels */
+#define PI_DUP_TAG -53 /* script has duplicate tag */
+#define PI_TOO_MANY_TAGS -54 /* script has too many tags */
#define PI_BAD_SCRIPT_CMD -55 /* illegal script command */
#define PI_BAD_VAR_NUM -56 /* script variable must be 0-149 */
#define PI_NO_SCRIPT_ROOM -57 /* no more room for scripts */
@@ -2143,6 +2262,14 @@ after this command is issued.
#define PI_SOCK_WRIT_FAILED -60 /* socket write failed */
#define PI_TOO_MANY_PARAM -61 /* too many script parameters > 10 */
#define PI_NOT_HALTED -62 /* script already running or failed */
+#define PI_BAD_TAG -63 /* script has unresolved tag */
+#define PI_BAD_MICS_DELAY -64 /* bad MICS delay (too large) */
+#define PI_BAD_MILS_DELAY -65 /* bad MILS delay (too large) */
+#define PI_BAD_WAVE_ID -66 /* non existent wave id */
+#define PI_TOO_MANY_CBS -67 /* No more CBs for waveform */
+#define PI_TOO_MANY_OOL -68 /* No more OOL for waveform */
+#define PI_EMPTY_WAVEFORM -69 /* attempt to create an empty waveform */
+#define PI_NO_WAVEFORM_ID -70 /* no more waveforms */
/*-------------------------------------------------------------------------*/
diff --git a/pigpio.py b/pigpio.py
index f5591ca..3124ecd 100644
--- a/pigpio.py
+++ b/pigpio.py
@@ -26,7 +26,8 @@ The pigpio module's main features are:
- provision of servo pulses on any number of gpios 0-31 simultaneously.
-- callbacks when any of gpios 0-31 change state.
+- callbacks when any of gpios 0-31 change state (callbacks receive the
+ time of the event accurate to a few microseconds).
- reading/writing gpios and setting their modes (typically input
or output).
@@ -34,6 +35,11 @@ The pigpio module's main features are:
- reading/writing all of the gpios in a bank (0-31, 32-53) as a single
operation.
+- creating and transmitting precisely timed waveforms (accurate
+ to a few microseconds).
+
+- creating and running scripts on the pigpio daemon.
+
Notes
ALL gpios are identified by their Broadcom number.
@@ -76,7 +82,7 @@ import threading
import os
import atexit
-VERSION = "1.4"
+VERSION = "1.5"
# gpio levels
@@ -168,11 +174,16 @@ _PI_CMD_SLRO= 42
_PI_CMD_SLR= 43
_PI_CMD_SLRC= 44
_PI_CMD_PROCP=45
-
+_PI_CMD_MICRO=46
+_PI_CMD_MILLI=47
+_PI_CMD_PARSE=48
+_PI_CMD_WVCRE=49
+_PI_CMD_WVDEL=50
+_PI_CMD_WVTX =51
+_PI_CMD_WVTXR=52
_PI_CMD_NOIB= 99
-
# pigpio error numbers
_PI_INIT_FAILED =-1
@@ -228,8 +239,8 @@ PI_BAD_SER_OFFSET =-49
PI_GPIO_IN_USE =-50
PI_BAD_SERIAL_COUNT =-51
PI_BAD_PARAM_NUM =-52
-PI_DUP_LABEL =-53
-PI_TOO_MANY_LABELS =-54
+PI_DUP_TAG =-53
+PI_TOO_MANY_TAGS =-54
PI_BAD_SCRIPT_CMD =-55
PI_BAD_VAR_NUM =-56
PI_NO_SCRIPT_ROOM =-57
@@ -238,6 +249,14 @@ PI_SOCK_READ_FAILED =-59
PI_SOCK_WRIT_FAILED =-60
PI_TOO_MANY_PARAM =-61
PI_NOT_HALTED =-62
+PI_BAD_TAG =-63
+PI_BAD_MICS_DELAY =-64
+PI_BAD_MILS_DELAY =-65
+PI_BAD_WAVE_ID =-66
+PI_TOO_MANY_CBS =-67
+PI_TOO_MANY_OOL =-68
+PI_EMPTY_WAVEFORM =-69
+PI_NO_WAVEFORM_ID =-70
# pigpio error text
@@ -285,15 +304,15 @@ _errors=[
[PI_BAD_WVSC_COMMND , "bad WVSC subcommand"],
[PI_BAD_WVSM_COMMND , "bad WVSM subcommand"],
[PI_BAD_WVSP_COMMND , "bad WVSP subcommand"],
- [PI_BAD_PULSELEN , "trigger pulse length > 100"],
+ [PI_BAD_PULSELEN , "trigger pulse length > 50"],
[PI_BAD_SCRIPT , "invalid script"],
[PI_BAD_SCRIPT_ID , "unknown script id"],
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
[PI_GPIO_IN_USE , "gpio already in use"],
[PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"],
[PI_BAD_PARAM_NUM , "script parameter must be 0-9"],
- [PI_DUP_LABEL , "script has duplicate label"],
- [PI_TOO_MANY_LABELS , "script has too many labels"],
+ [PI_DUP_TAG , "script has duplicate tag"],
+ [PI_TOO_MANY_TAGS , "script has too many tags"],
[PI_BAD_SCRIPT_CMD , "illegal script command"],
[PI_BAD_VAR_NUM , "script variable must be 0-149"],
[PI_NO_SCRIPT_ROOM , "no more room for scripts"],
@@ -302,6 +321,14 @@ _errors=[
[PI_SOCK_WRIT_FAILED , "socket write failed"],
[PI_TOO_MANY_PARAM , "too many script parameters (> 10)"],
[PI_NOT_HALTED , "script already running or failed"],
+ [PI_BAD_TAG , "script has unresolved tag"],
+ [PI_BAD_MICS_DELAY , "bad MICS delay (too large)"],
+ [PI_BAD_MILS_DELAY , "bad MILS delay (too large)"],
+ [PI_BAD_WAVE_ID , "non existent wave id"],
+ [PI_TOO_MANY_CBS , "No more CBs for waveform"],
+ [PI_TOO_MANY_OOL , "No more OOL for waveform"],
+ [PI_EMPTY_WAVEFORM , "attempt to create an empty waveform"],
+ [PI_NO_WAVEFORM_ID , "No more waveform ids"],
]
@@ -402,11 +429,9 @@ def _pigpio_command_ext(sock, cmd, p1, p2, extents):
extents: additional data blocks
"""
if sock is not None:
- sock.send(struct.pack('IIII', cmd, p1, p2, 0))
-
- for ext in extents:
- sock.sendall(ext)
-
+ msg = struct.pack('IIII', cmd, p1, p2, 0)
+ for ext in extents: msg += ext
+ sock.sendall(msg)
x, y, z, res = struct.unpack('IIII', sock.recv(16))
return res
else:
@@ -523,7 +548,7 @@ class _wait_for_edge:
_notify.append(self.callb)
self.start = time.time()
while (self.trigger == False) and ((time.time()-self.start) < timeout):
- time.sleep(0.1)
+ time.sleep(0.05)
_notify.remove(self.callb)
def func(self, gpio, level, tick):
@@ -916,7 +941,7 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
Example 1: standard 50 Hz hobby servo updates
- #!/usr/bin/python
+ #!/usr/bin/env python
import pigpio
import time
@@ -943,7 +968,7 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
Example 2: 400 Hz ESC type servo updates
- #!/usr/bin/python
+ #!/usr/bin/env python
import pigpio
import time
@@ -1102,7 +1127,7 @@ def set_watchdog(user_gpio, timeout):
Example
- #!/usr/bin/python
+ #!/usr/bin/env python
import pigpio
import time
@@ -1189,7 +1214,7 @@ def clear_bank_1(levels):
Example
- #!/usr/bin/python
+ #!/usr/bin/env python
import pigpio
@@ -1255,7 +1280,7 @@ def set_bank_1(levels):
Example
- #!/usr/bin/python
+ #!/usr/bin/env python
import pigpio
@@ -1317,7 +1342,7 @@ def get_current_tick():
Example
- #!/usr/bin/python
+ #!/usr/bin/env python
import pigpio
import time
@@ -1406,26 +1431,19 @@ class pulse:
def wave_clear():
"""
- Initialises a new waveform.
-
- Returns 0 if OK.
-
- A waveform comprises one of more pulses.
-
- A pulse specifies
-
- 1) the gpios to be switched on at the start of the pulse.
- 2) the gpios to be switched off at the start of the pulse.
- 3) the delay in microseconds before the next pulse.
-
- Any or all the fields can be zero. It doesn't make any sense
- to set all the fields to zero (the pulse will be ignored).
-
- When a waveform is started each pulse is executed in order with
- the specified delay between the pulse and the next.
+ Clears all waveforms and any data added by calls to the
+ wave_add_* functions.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVCLR, 0, 0))
+def wave_add_new():
+ """
+ Starts a new empty waveform. You wouldn't normally need
+ to call this function as it is automatically called after a
+ waveform is created with the wave_create function.
+ """
+ return _u2i(_pigpio_command(_control, _PI_CMD_WVNEW, 0, 0))
+
def wave_add_generic(pulses):
"""
Adds a list of pulses to the current waveform.
@@ -1447,62 +1465,54 @@ def wave_add_generic(pulses):
Example
- #!/usr/bin/env python
-
import time
+
import pigpio
- class stepper:
-
- def __init__(self, g1, g2, g3, g4):
- self.g1 = g1
- self.g2 = g2
- self.g3 = g3
- self.g4 = g4
- self.all = (1<
*/
/*
-This version is for pigpio version 11+
+This version is for pigpio version 14+
*/
#include
@@ -59,6 +59,8 @@ static unsigned DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CHANNEL;
static unsigned socketPort = PI_DEFAULT_SOCKET_PORT;
static uint64_t updateMask = -1;
+static int updateMaskSet = 0;
+
static FILE * errFifo;
void fatal(char *fmt, ...)
@@ -183,7 +185,11 @@ static void initOpts(int argc, char *argv[])
case 'x':
mask = strtoll(optarg, &endptr, 0);
printf("mask=%llx\n", mask);
- if (!*endptr) updateMask = mask;
+ if (!*endptr)
+ {
+ updateMask = mask;
+ updateMaskSet = 1;
+ }
else fatal("invalid -x option (%s)", optarg);
break;
@@ -264,7 +270,7 @@ int main(int argc, char **argv)
gpioCfgSocketPort(socketPort);
- if (updateMask != -1) gpioCfgPermissions(updateMask);
+ if (updateMaskSet) gpioCfgPermissions(updateMask);
/* start library */
diff --git a/pigpiod_if.c b/pigpiod_if.c
index 2fab6d0..b5cc3e7 100644
--- a/pigpiod_if.c
+++ b/pigpiod_if.c
@@ -606,6 +606,9 @@ uint32_t get_pigpio_version(void)
int wave_clear(void)
{return pigpio_command(gPigCommand, PI_CMD_WVCLR, 0, 0);}
+int wave_add_new(void)
+ {return pigpio_command(gPigCommand, PI_CMD_WVNEW, 0, 0);}
+
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
{
gpioExtent_t ext[1];
@@ -617,6 +620,8 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
gpioPulse_t[] pulses
*/
+ if (!numPulses) return 0;
+
ext[0].size = numPulses * sizeof(gpioPulse_t);
ext[0].ptr = pulses;
@@ -637,6 +642,8 @@ int wave_add_serial(
char[] str
*/
+ if (!numChar) return 0;
+
ext[0].size = sizeof(unsigned);
ext[0].ptr = &baud;
@@ -649,18 +656,30 @@ int wave_add_serial(
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext);
}
+int wave_create(void)
+ {return pigpio_command(gPigCommand, PI_CMD_WVCRE, 0, 0);}
+
+int wave_delete(unsigned wave_id)
+ {return pigpio_command(gPigCommand, PI_CMD_WVDEL, wave_id, 0);}
+
+int wave_tx_start(void) /* DEPRECATED */
+ {return pigpio_command(gPigCommand, PI_CMD_WVGO, 0, 0);}
+
+int wave_tx_repeat(void) /* DEPRECATED */
+ {return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0);}
+
+int wave_send_once(unsigned wave_id)
+ {return pigpio_command(gPigCommand, PI_CMD_WVTX, 0, 0);}
+
+int wave_send_repeat(unsigned wave_id)
+ {return pigpio_command(gPigCommand, PI_CMD_WVTXR, 0, 0);}
+
int wave_tx_busy(void)
{return pigpio_command(gPigCommand, PI_CMD_WVBSY, 0, 0);}
int wave_tx_stop(void)
{return pigpio_command(gPigCommand, PI_CMD_WVHLT, 0, 0);}
-int wave_tx_start(void)
- {return pigpio_command(gPigCommand, PI_CMD_WVGO, 0, 0);}
-
-int wave_tx_repeat(void)
- {return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0);}
-
int wave_get_micros(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 0, 0);}
@@ -743,10 +762,10 @@ int run_script(unsigned script_id, unsigned numPar, uint32_t *param)
(gPigCommand, PI_CMD_PROCR, script_id, numPar, 1, ext);
}
-int script_status(int script_id, uint32_t *param)
+int script_status(unsigned script_id, uint32_t *param)
{
int status;
- uint32_t p[MAX_SCRIPT_PARAMS];
+ uint32_t p[PI_MAX_SCRIPT_PARAMS];
status = pigpio_command(gPigCommand, PI_CMD_PROCP, script_id, 0);
diff --git a/pigpiod_if.h b/pigpiod_if.h
index 809800c..ef01ca8 100644
--- a/pigpiod_if.h
+++ b/pigpiod_if.h
@@ -30,7 +30,7 @@ For more information, please refer to
#include "pigpio.h"
-#define PIGPIOD_IF_VERSION 4
+#define PIGPIOD_IF_VERSION 5
typedef enum
{
@@ -514,62 +514,18 @@ uint32_t get_pigpio_version(void);
int wave_clear(void);
-/* This function initialises a new waveform.
+/* This function clears all waveforms and any data added by calls to the
+ wave_add_* functions.
Returns 0 if OK.
-
- A waveform comprises one of more pulses. Each pulse consists of a
- gpioPulse_t structure.
-
- typedef struct
- {
- uint32_t gpioOn;
- uint32_t gpioOff;
- uint32_t usDelay;
- } gpioPulse_t;
-
- The fields specify
-
- 1) the gpios to be switched on at the start of the pulse.
- 2) the gpios to be switched off at the start of the pulse.
- 3) the delay in microseconds before the next pulse.
-
- Any or all the fields can be zero. It doesn't make any sense to
- set all the fields to zero (the pulse will be ignored).
-
- When a waveform is started each pulse is executed in order with the
- specified delay between the pulse and the next.
*/
-int wave_tx_busy(void);
-/* This function checks to see if a waveform is currently being
- transmitted.
-
- Returns 1 if a waveform is currently being transmitted, otherwise 0.
-*/
-
-int wave_tx_stop(void);
-/* This function stops the transmission of the current waveform.
+int wave_add_new(void);
+/* This function starts a new empty waveform. You wouldn't normally need
+ to call this function as it is automatically called after a waveform is
+ created with the wave_create function.
Returns 0 if OK.
-
- This function is intended to stop a waveform started with the repeat mode.
-*/
-
-int wave_tx_start(void);
-/* This function transmits the current waveform. The waveform is
- sent once.
-
- Returns the number of DMA control blocks in the waveform if OK,
- otherwise PI_BAD_WAVE_MODE.
-*/
-
-int wave_tx_repeat(void);
-/* This function transmits the current waveform. The waveform repeats
- endlessly until wave_tx_stop is called.
-
- Returns the number of DMA control blocks in the waveform if OK,
- otherwise PI_BAD_WAVE_MODE.
*/
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses);
@@ -578,7 +534,7 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses);
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_TOO_MANY_PULSES.
- The pulses are interleaved in time order within the existing waveform
+ The pulses are interleaved in time order within the existing waveform
(if any).
Merging allows the waveform to be built in parts, that is the settings
@@ -607,6 +563,108 @@ int wave_add_serial
the same waveform.
*/
+int wave_create(void);
+/* This function creates a waveform from the data provided by the prior
+ calls to the wave_add_* functions. Upon success a positive wave id
+ is returned.
+
+ The data provided by the wave_add_* functions is consumed by this
+ function.
+
+ As many waveforms may be created as there is space available. The
+ wave id is passed to wave_send_* to specify the waveform to transmit.
+
+ Normal usage would be
+
+ Step 1. wave_clear to clear all waveforms and added data.
+
+ Step 2. wave_add_* calls to supply the waveform data.
+
+ Step 3. wave_create to create the waveform and get a unique id
+
+ Repeat steps 2 and 3 as needed.
+
+ Step 4. wave_send_* with the id of the waveform to transmit.
+
+ A waveform comprises one or more pulses. Each pulse consists of a
+ gpioPulse_t structure.
+
+ typedef struct
+ {
+ uint32_t gpioOn;
+ uint32_t gpioOff;
+ uint32_t usDelay;
+ } gpioPulse_t;
+
+ The fields specify
+
+ 1) the gpios to be switched on at the start of the pulse.
+ 2) the gpios to be switched off at the start of the pulse.
+ 3) the delay in microseconds before the next pulse.
+
+ Any or all the fields can be zero. It doesn't make any sense to
+ set all the fields to zero (the pulse will be ignored).
+
+ When a waveform is started each pulse is executed in order with the
+ specified delay between the pulse and the next.
+
+ Returns the new waveform id if OK, otherwise PI_EMPTY_WAVEFORM,
+ PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
+*/
+
+
+int wave_delete(unsigned wave_id);
+/* This function deletes all created waveforms with ids greater than or
+ equal to wave_id.
+
+ Wave ids are allocated in order, 0, 1, 2, etc.
+
+ Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
+*/
+
+int wave_tx_start(void);
+/* This function is deprecated and should no longer be used. Use
+ wave_create/wave_send_* instead.
+*/
+
+int wave_tx_repeat(void);
+/* This function is deprecated and should no longer be used. Use
+ wave_create/wave_send_* instead.
+*/
+
+int wave_send_once(unsigned wave_id);
+/* This function transmits the waveform with id wave_id. The waveform
+ is sent once.
+
+ Returns the number of DMA control blocks in the waveform if OK,
+ otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
+*/
+
+int wave_send_repeat(unsigned wave_id);
+/* This function transmits the waveform with id wave_id. The waveform
+ cycles until cancelled (either by the sending of a new waveform or
+ by wave_tx_stop).
+
+ Returns the number of DMA control blocks in the waveform if OK,
+ otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
+*/
+
+
+int wave_tx_busy(void);
+/* This function checks to see if a waveform is currently being
+ transmitted.
+
+ Returns 1 if a waveform is currently being transmitted, otherwise 0.
+*/
+
+int wave_tx_stop(void);
+/* This function stops the transmission of the current waveform.
+
+ Returns 0 if OK.
+
+ This function is intended to stop a waveform started with the repeat mode.
+*/
+
int wave_get_micros(void);
/* This function returns the length in microseconds of the current
waveform.
@@ -675,7 +733,7 @@ int run_script(unsigned script_id, unsigned numPar, uint32_t *param);
the script as param 0 to param 9..
*/
-int script_status(int script_id, uint32_t *param);
+int script_status(unsigned script_id, uint32_t *param);
/* This function returns the run status of a stored script as well
as the current values of parameters 0 to 9.
diff --git a/pigs.c b/pigs.c
index 35c47e4..3cce611 100644
--- a/pigs.c
+++ b/pigs.c
@@ -26,7 +26,7 @@ For more information, please refer to
*/
/*
-This version is for pigpio version 13+
+This version is for pigpio version 14+
*/
#include
@@ -50,6 +50,8 @@ the commands available from pigpio.
char command_buf[8192];
char response_buf[8192];
+#define SOCKET_OPEN_FAILED -1
+
void fatal(char *fmt, ...)
{
char buf[128];
@@ -88,7 +90,7 @@ static int openSocket(void)
err = getaddrinfo(addrStr, portStr, &hints, &res);
- if (err) return -1;
+ if (err) return SOCKET_OPEN_FAILED;
for (rp=res; rp!=NULL; rp=rp->ai_next)
{
@@ -101,7 +103,7 @@ static int openSocket(void)
freeaddrinfo(res);
- if (rp == NULL) return -1;
+ if (rp == NULL) return SOCKET_OPEN_FAILED;
return sock;
}
@@ -156,7 +158,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd)
p = (uint32_t *)response_buf;
- for (i=0; i= 0) && (ctl.eaten < len))
+ {
+ if ((idx=cmdParse(command_buf, p, v, &ctl)) >= 0)
{
- l += (strlen(argv[i]) + 1);
- if (l < sizeof(command_buf))
- {sprintf(command_buf+pp, "%s ", argv[i]); pp=l;}
- }
+ command = p[0];
- if (pp) {command_buf[--pp] = 0;}
-
- ctl.flags = 0;
- ctl.eaten = 0;
-
- len = strlen(command_buf);
- idx = 0;
-
- while ((idx >= 0) && (ctl.eaten < len))
- {
- if ((idx=cmdParse(command_buf, p, v, &ctl)) >= 0)
+ if (command < PI_CMD_SCRIPT)
{
- command = p[0];
-
- if (command < PI_CMD_SCRIPT)
+ if (command == PI_CMD_HELP)
+ {
+ printf(cmdUsage);
+ }
+ else if (command == PI_CMD_PARSE)
+ {
+ cmdParseScript(v[1], &s, 1);
+ if (s.par) free (s.par);
+ }
+ else
{
cmd.cmd = command;
cmd.p1 = p[1];
@@ -300,36 +311,46 @@ int main(int argc , char *argv[])
{
case PI_CMD_WVAS:
cmd.p2 = p[4];
- break;
+ break;
case PI_CMD_PROC:
cmd.p2 = 0;
break;
}
- if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
+ if (sock != SOCKET_OPEN_FAILED)
{
- put_extensions(sock, command, p, v);
-
- if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
+ if (send(sock, &cmd, sizeof(cmdCmd_t), 0) ==
sizeof(cmdCmd_t))
{
- get_extensions(sock, command, cmd.res);
+ put_extensions(sock, command, p, v);
- print_result(sock, cmdInfo[idx].rv, cmd);
+ if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
+ sizeof(cmdCmd_t))
+ {
+ get_extensions(sock, command, cmd.res);
+
+ print_result(sock, cmdInfo[idx].rv, cmd);
+ }
+ else fatal("recv failed, %m");
}
- else fatal("recv failed, %m");
+ else fatal("send failed, %m");
}
- else fatal("send failed, %m");
+ else fatal("connect failed");
}
- else fatal("%s only allowed within a script", cmdInfo[idx].name);
}
- else fatal("%s? pigs h for help", cmdStr());
+ else fatal("%s only allowed within a script", cmdInfo[idx].name);
+ }
+ else
+ {
+ if (idx == CMD_UNKNOWN_CMD)
+ fatal("%s? unknown command, pigs h for help", cmdStr());
+ else
+ fatal("%s: bad parameter, pigs h for help", cmdStr());
}
}
- else fatal("connect failed, %m");
- close(sock);
+ if (sock >= 0) close(sock);
return 0;
}
diff --git a/setup.py b/setup.py
index dc6e304..14465f1 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='pigpio',
- version='1.4',
+ version='1.5',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',
diff --git a/tarball b/tarball
new file mode 100755
index 0000000..aab4ff7
--- /dev/null
+++ b/tarball
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+rm -rf PIGPIO
+mkdir PIGPIO
+#
+cp command.c PIGPIO
+cp command.h PIGPIO
+cp Makefile PIGPIO
+cp MakeRemote PIGPIO
+cp pig2vcd.c PIGPIO
+cp pigpio.c PIGPIO
+cp pigpio.h PIGPIO
+cp pigpiod.c PIGPIO
+cp pigpiod_if.c PIGPIO
+cp pigpiod_if.h PIGPIO
+cp pigpio.py PIGPIO
+cp pigs.c PIGPIO
+cp README PIGPIO
+cp setup.py PIGPIO
+cp UNLICENCE PIGPIO
+cp x_pigpio.c PIGPIO
+cp x_pigpio.py PIGPIO
+cp x_pigpiod_if.c PIGPIO
+cp x_pigs PIGPIO
+cp x_pipe PIGPIO
+#
+zip -r pigpio-$1.zip PIGPIO
+tar cvf pigpio-$1.tar PIGPIO
+
diff --git a/x_pigpio.c b/x_pigpio.c
index d884f4d..c827a7b 100644
--- a/x_pigpio.c
+++ b/x_pigpio.c
@@ -1,6 +1,13 @@
/*
gcc -o x_pigpio x_pigpio.c -lpigpio -lrt -lpthread
sudo ./x_pigpio
+
+*** WARNING ************************************************
+* *
+* All the tests make extensive use of gpio 4 (pin P1-7). *
+* Ensure that either nothing or just a LED is connected to *
+* gpio 4 before running any of the tests. *
+************************************************************
*/
#include
@@ -448,17 +455,17 @@ void t6()
gpioSetAlertFunc(GPIO, t6cbf);
- for (t=0; t<10; t++)
+ for (t=0; t<5; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
- gpioTrigger(4, p, 1);
+ gpioTrigger(GPIO, p, 1);
}
time_sleep(0.2);
- CHECK(6, 1, t6_count, 10, 0, "gpio trigger count");
+ CHECK(6, 1, t6_count, 5, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
}
@@ -553,16 +560,16 @@ void t9()
p1 GPIO
*/
char *script="\
- ldap 0\
- ldva 0\
- label 0\
+ lda p0\
+ sta v0\
+ tag 0\
w p1 1\
- milli 5\
+ mils 5\
w p1 0\
- milli 5\
- dcrv 0\
- ldav 0\
- ldpa 9\
+ mils 5\
+ dcr v0\
+ lda v0\
+ sta p9\
jp 0";
printf("Script store/run/status/stop/delete tests.\n");
diff --git a/x_pigpio.py b/x_pigpio.py
index 7b09908..55a63e3 100755
--- a/x_pigpio.py
+++ b/x_pigpio.py
@@ -1,5 +1,12 @@
#!/usr/bin/env python
+#*** WARNING ************************************************
+#* *
+#* All the tests make extensive use of gpio 4 (pin P1-7). *
+#* Ensure that either nothing or just a LED is connected to *
+#* gpio 4 before running any of the tests. *
+#************************************************************
+
import time
import struct
@@ -364,6 +371,50 @@ To the lascivious pleasing of a lute.
c = pigpio.wave_get_max_cbs()
CHECK(5, 21, c, 25016, 0, "wave get max cbs")
+ e = pigpio.wave_clear()
+ CHECK(5, 22, e, 0, 0, "wave clear")
+
+ e = pigpio.wave_add_generic(wf)
+ CHECK(5, 23, e, 4, 0, "pulse, wave add generic")
+
+ w1 = pigpio.wave_create()
+ CHECK(5, 24, w1, 0, 0, "wave create")
+
+ e = pigpio.wave_send_repeat(w1)
+ CHECK(5, 25, e, 9, 0, "wave send repeat")
+
+ oc = t5_count
+ time.sleep(5)
+ c = t5_count - oc
+ CHECK(5, 26, c, 50, 1, "callback")
+
+ e = pigpio.wave_tx_stop()
+ CHECK(5, 27, e, 0, 0, "wave tx stop")
+
+ e = pigpio.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
+ CHECK(5, 28, e, 3405, 0, "wave add serial")
+
+ w2 = pigpio.wave_create()
+ CHECK(5, 29, w2, 1, 0, "wave create")
+
+ e = pigpio.wave_send_once(w2)
+ CHECK(5, 30, e, 6811, 0, "wave send once")
+
+ oc = t5_count
+ time.sleep(3)
+ c = t5_count - oc
+ CHECK(5, 31, c, 0, 0, "callback")
+
+ oc = t5_count
+ while pigpio.wave_tx_busy():
+ time.sleep(0.1)
+ time.sleep(0.1)
+ c = t5_count - oc
+ CHECK(5, 32, c, 1702, 0, "wave tx busy, callback")
+
+ e = pigpio.wave_delete(0)
+ CHECK(5, 33, e, 0, 0, "wave delete")
+
t6_count=0
t6_on=0
t6_on_tick=None
@@ -388,15 +439,15 @@ def t6():
t6cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t6cbf)
- for t in range(10):
+ for t in range(5):
time.sleep(0.1)
p = 10 + (t*10)
tp += p;
- pigpio.gpio_trigger(4, p, 1)
+ pigpio.gpio_trigger(GPIO, p, 1)
time.sleep(0.5)
- CHECK(6, 1, t6_count, 10, 0, "gpio trigger count")
+ CHECK(6, 1, t6_count, 5, 0, "gpio trigger count")
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length")
@@ -480,16 +531,16 @@ def t9():
# p0 number of loops
# p1 GPIO
script="""
- ldap 0
- ldva 0
- label 0
+ lda p0
+ sta v0
+ tag 0
w p1 1
- milli 5
+ mils 5
w p1 0
- milli 5
- dcrv 0
- ldav 0
- ldpa 9
+ mils 5
+ dcr v0
+ lda v0
+ sta p9
jp 0"""
t9cb = pigpio.callback(GPIO)
diff --git a/x_pigpiod_if.c b/x_pigpiod_if.c
index 9ae3229..787c6d4 100644
--- a/x_pigpiod_if.c
+++ b/x_pigpiod_if.c
@@ -1,6 +1,13 @@
/*
gcc -o x_pigpiod_if x_pigpiod_if.c -lpigpiod_if -lrt -lpthread
sudo ./x_pigpiod_if
+
+*** WARNING ************************************************
+* *
+* All the tests make extensive use of gpio 4 (pin P1-7). *
+* Ensure that either nothing or just a LED is connected to *
+* gpio 4 before running any of the tests. *
+************************************************************
*/
#include
@@ -429,17 +436,17 @@ void t6()
time_sleep(0.2);
- for (t=0; t<10; t++)
+ for (t=0; t<5; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
- gpio_trigger(4, p, 1);
+ gpio_trigger(GPIO, p, 1);
}
time_sleep(0.5);
- CHECK(6, 1, t6_count, 10, 0, "gpio trigger count");
+ CHECK(6, 1, t6_count, 5, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
}
@@ -540,16 +547,16 @@ void t9()
p1 GPIO
*/
char *script="\
- ldap 0\
- ldva 0\
- label 0\
+ lda p0\
+ sta v0\
+ tag 0\
w p1 1\
- milli 5\
+ mils 5\
w p1 0\
- milli 5\
- dcrv 0\
- ldav 0\
- ldpa 9\
+ mils 5\
+ dcr v0\
+ lda v0\
+ sta p9\
jp 0";
callback(GPIO, RISING_EDGE, t9cbf);
diff --git a/x_pigs b/x_pigs
index 82d9124..9b1bc56 100755
--- a/x_pigs
+++ b/x_pigs
@@ -40,16 +40,16 @@ s=$(pigs bs2 0)
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h)
-if [[ ${#s} = 2999 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
+if [[ ${#s} = 3315 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
s=$(pigs hwver)
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
-s=$(pigs micro 1000)
-if [[ $s = "" ]]; then echo "MICRO ok"; else echo "MICRO fail ($s)"; fi
+s=$(pigs mics 1000)
+if [[ $s = "" ]]; then echo "MICS ok"; else echo "MICS fail ($s)"; fi
-s=$(pigs milli 10)
-if [[ $s = "" ]]; then echo "MILLI ok"; else echo "MILLI fail ($s)"; fi
+s=$(pigs mils 10)
+if [[ $s = "" ]]; then echo "MILS ok"; else echo "MILS fail ($s)"; fi
s=$(pigs modes $GPIO 0)
s=$(pigs modeg $GPIO)
@@ -86,14 +86,14 @@ s=$(pigs pfs $GPIO 800)
if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
s=$(pigs pigpv)
-if [[ $s = 13 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
+if [[ $s = 14 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
s=$(pigs prs $GPIO 255)
if [[ $s = 250 ]]; then echo "PRG-a ok"; else echo "PRG-a fail ($s)"; fi
s=$(pigs prg $GPIO)
if [[ $s = 255 ]]; then echo "PRG-b ok"; else echo "PRG-b fail ($s)"; fi
-p=$(pigs proc ldap 0 ldpa 1 ldai 1234 ldpa 0 label 999 milli 1000 jmp 999)
+p=$(pigs proc ld p1 p0 ld p0 1234 tag 999 mils 1000 jmp 999)
if [[ $p -ge 0 && $p -le 31 ]]
then echo "PROC($p) ok"
else echo "PROC($p) fail ($s)"
@@ -186,10 +186,10 @@ fi
s=$(pigs slrc $GPIO)
if [[ $s = 0 ]]; then echo "SLR-g ok"; else echo "SLR-g fail ($s)"; fi
-t1=$(pigs t)
-t2=$(pigs tick)
-s=$(($t2-$t1))
-if [[ $s -gt 0 && $s -lt 20000 ]]
+t=$(pigs t tick)
+v=(${t// / })
+s=$((v[1]-v[0]))
+if [[ $s -gt 0 && $s -lt 2000 ]]
then echo "TICK ok"
else echo "TICK fail($s)"
fi
diff --git a/x_pipe b/x_pipe
index 16eb209..0dfb534 100755
--- a/x_pipe
+++ b/x_pipe
@@ -46,14 +46,14 @@ if [[ $s = 0 ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
echo "h" >/dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s /dev/pigpio
+echo "mics 1000" >/dev/pigpio
read -t 1 s /dev/pigpio
+echo "mils 10" >/dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s /dev/pigpio
read -t 1 s /dev/pigpio
+echo "proc ld p1 p0 ld p0 29 tag 9 mils 1000 jmp 9" >/dev/pigpio
read -t 1 p