This commit is contained in:
joan 2014-06-12 18:31:00 +01:00
parent 590274dc7f
commit a99255ed9a
14 changed files with 7921 additions and 3897 deletions

730
command.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 14+
This version is for pigpio version 16+
*/
#include <stdio.h>
@ -42,72 +42,133 @@ cmdInfo_t cmdInfo[]=
{
/* num str vfyt retv */
{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_BC1, "BC1", 111, 1}, // gpioWrite_Bits_0_31_Clear
{PI_CMD_BC2, "BC2", 111, 1}, // gpioWrite_Bits_32_53_Clear
{PI_CMD_BR1, "BR1", 101, 3}, // gpioRead_Bits_0_31
{PI_CMD_BR2, "BR2", 101, 3}, // gpioRead_Bits_32_53
{PI_CMD_BS1, "BS1", 111, 1}, // gpioWrite_Bits_0_31_Set
{PI_CMD_BS2, "BS2", 111, 1}, // gpioWrite_Bits_32_53_Set
{PI_CMD_HELP, "H", 101, 5}, // cmdUsage
{PI_CMD_HELP, "HELP", 101, 5}, // cmdUsage
{PI_CMD_HWVER, "HWVER", 101, 4}, // gpioHardwareRevision
{PI_CMD_I2CC, "I2CC", 112, 0}, // i2cClose
{PI_CMD_I2CO, "I2CO", 131, 2}, // i2cOpen
{PI_CMD_I2CPC, "I2CPC", 131, 2}, // i2cProcessCall
{PI_CMD_I2CPK, "I2CPK", 194, 6}, // i2cBlockProcessCall
{PI_CMD_I2CRB, "I2CRB", 121, 2}, // i2cReadByteData
{PI_CMD_I2CRD, "I2CRD", 121, 6}, // i2cReadDevice
{PI_CMD_I2CRI, "I2CRI", 131, 6}, // i2cReadI2CBlockData
{PI_CMD_I2CRK, "I2CRK", 121, 6}, // i2cReadBlockData
{PI_CMD_I2CRS, "I2CRS", 112, 2}, // i2cReadByte
{PI_CMD_I2CRW, "I2CRW", 121, 2}, // i2cReadWordData
{PI_CMD_I2CWB, "I2CWB", 131, 0}, // i2cWriteByteData
{PI_CMD_I2CWD, "I2CWD", 193, 0}, // i2cWriteDevice
{PI_CMD_I2CWI, "I2CWI", 194, 0}, // i2cWriteI2CBlockData
{PI_CMD_I2CWK, "I2CWK", 194, 0}, // i2cWriteBlockData
{PI_CMD_I2CWQ, "I2CWQ", 121, 0}, // i2cWriteQuick
{PI_CMD_I2CWS, "I2CWS", 121, 0}, // i2cWriteByte
{PI_CMD_I2CWW, "I2CWW", 131, 0}, // i2cWriteWordData
{PI_CMD_MICS, "MICS", 112, 0}, // gpioDelay
{PI_CMD_MILS, "MILS", 112, 0}, // gpioDelay
{PI_CMD_MODEG, "MG" , 112, 2}, // gpioGetMode
{PI_CMD_MODEG, "MODEG", 112, 2}, // gpioGetMode
{PI_CMD_MODES, "M", 125, 0}, // gpioSetMode
{PI_CMD_MODES, "MODES", 125, 0}, // gpioSetMode
{PI_CMD_NB, "NB", 122, 0}, // gpioNotifyBegin
{PI_CMD_NC, "NC", 112, 0}, // gpioNotifyClose
{PI_CMD_NO, "NO", 101, 2}, // gpioNotifyOpen
{PI_CMD_NP, "NP", 112, 0}, // gpioNotifyPause
{PI_CMD_PARSE, "PARSE", 115, 2}, // cmdParseScript
{PI_CMD_PFG, "PFG", 112, 2}, // gpioGetPWMfrequency
{PI_CMD_PFS, "PFS", 121, 2}, // gpioSetPWMfrequency
{PI_CMD_PIGPV, "PIGPV", 101, 4}, // gpioVersion
{PI_CMD_PRG, "PRG", 112, 2}, // gpioGetPWMrangeg
{PI_CMD_PROC, "PROC", 115, 2}, // gpioStoreScript
{PI_CMD_PROCD, "PROCD", 112, 2}, // gpioDeleteScript
{PI_CMD_PROCP, "PROCP", 112, 7}, // gpioScriptStatus
{PI_CMD_PROCR, "PROCR", 191, 2}, // gpioRunScript
{PI_CMD_PROCS, "PROCS", 112, 2}, // gpioStopScript
{PI_CMD_PRRG, "PRRG", 112, 2}, // gpioGetPWMrealRange
{PI_CMD_PRS, "PRS", 121, 2}, // gpioSetPWMrange
{PI_CMD_PUD, "PUD", 126, 0}, // gpioSetPullUpDown
{PI_CMD_PWM, "P", 121, 0}, // gpioPWM
{PI_CMD_PWM, "PWM", 121, 0}, // gpioPWM
{PI_CMD_READ, "R", 112, 2}, // gpioRead
{PI_CMD_READ, "READ", 112, 2}, // gpioRead
{PI_CMD_SERRB, "SERRB", 112, 2}, // serReadByte
{PI_CMD_SERWB, "SERWB", 121, 0}, // serWriteByte
{PI_CMD_SERC, "SERC", 112, 0}, // serClose
{PI_CMD_SERDA, "SERDA", 112, 2}, // serDataAvailable
{PI_CMD_SERO, "SERO", 132, 2}, // serOpen
{PI_CMD_SERR, "SERR", 121, 6}, // serRead
{PI_CMD_SERW, "SERW", 193, 0}, // serWrite
{PI_CMD_SERVO, "S", 121, 0}, // gpioServo
{PI_CMD_SERVO, "SERVO", 121, 0}, // gpioServo
{PI_CMD_SLR, "SLR", 121, 6}, // gpioSerialRead
{PI_CMD_SLRC, "SLRC", 112, 2}, // gpioSerialReadClose
{PI_CMD_SLRO, "SLRO", 121, 2}, // gpioSerialReadOpen
{PI_CMD_SPIC, "SPIC", 112, 0}, // spiClose
{PI_CMD_SPIO, "SPIO", 131, 2}, // spiOpen
{PI_CMD_SPIR, "SPIR", 121, 6}, // spiRead
{PI_CMD_SPIW, "SPIW", 193, 2}, // spiWrite
{PI_CMD_SPIX, "SPIX", 193, 6}, // spiXfer
{PI_CMD_TICK, "T", 101, 4}, // gpioTick
{PI_CMD_TICK, "TICK", 101, 4}, // gpioTick
{PI_CMD_TRIG, "TRIG", 131, 0}, // gpioTrigger
{PI_CMD_WDOG, "WDOG", 121, 0}, // gpioSetWatchdog
{PI_CMD_WRITE, "W", 121, 0}, // gpioWrite
{PI_CMD_WRITE, "WRITE", 121, 0}, // gpioWrite
{PI_CMD_WVAG, "WVAG", 192, 2}, // gpioWaveAddGeneric
{PI_CMD_WVAS, "WVAS", 196, 2}, // gpioWaveAddSerial
{PI_CMD_WVBSY, "WVBSY", 101, 2}, // gpioWaveTxBusy
{PI_CMD_WVCLR, "WVCLR", 101, 0}, // gpioWaveClear
{PI_CMD_WVCRE, "WVCRE", 101, 2}, // gpioWaveCreate
{PI_CMD_WVDEL, "WVDEL", 112, 2}, // gpioWaveDelete
{PI_CMD_WVGO, "WVGO" , 101, 2}, // gpioWaveTxStart
{PI_CMD_WVGOR, "WVGOR", 101, 2}, // gpioWaveTxStart
{PI_CMD_WVHLT, "WVHLT", 101, 2}, // gpioWaveTxStop
{PI_CMD_WVNEW, "WVNEW", 101, 2}, // gpioWaveAddNew
{PI_CMD_WVSC, "WVSC", 112, 2}, // gpioWaveGet*Cbs
{PI_CMD_WVSM, "WVSM", 112, 2}, // gpioWaveGet*Micros
{PI_CMD_WVSP, "WVSP", 112, 2}, // gpioWaveGet*Pulses
{PI_CMD_WVTX, "WVTX", 112, 2}, // gpioWaveTxSend
{PI_CMD_WVTXR, "WVTXR", 112, 2}, // gpioWaveTxSend
{PI_CMD_ADD , "ADD" , 111, 0},
{PI_CMD_AND , "AND" , 111, 0},
{PI_CMD_CALL , "CALL" , 114, 0},
{PI_CMD_CMDR ,"CMDR" , 111, 0},
{PI_CMD_CMDW , "CMDW" , 111, 0},
{PI_CMD_CMP , "CMP" , 111, 0},
{PI_CMD_DCR , "DCR" , 113, 0},
{PI_CMD_DCRA , "DCRA" , 101, 0},
@ -122,8 +183,10 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_JZ , "JZ" , 114, 0},
{PI_CMD_LD , "LD" , 123, 0},
{PI_CMD_LDA , "LDA" , 111, 0},
{PI_CMD_LDAB , "LDAB" , 111, 0},
{PI_CMD_MLT , "MLT" , 111, 0},
{PI_CMD_MOD , "MOD" , 111, 0},
{PI_CMD_NOP , "NOP" , 101, 0},
{PI_CMD_OR , "OR" , 111, 0},
{PI_CMD_POP , "POP" , 113, 0},
{PI_CMD_POPA , "POPA" , 101, 0},
@ -135,6 +198,7 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_RR , "RR" , 123, 0},
{PI_CMD_RRA , "RRA" , 111, 0},
{PI_CMD_STA , "STA" , 113, 0},
{PI_CMD_STAB , "STAB" , 111, 0},
{PI_CMD_SUB , "SUB" , 111, 0},
{PI_CMD_SYS , "SYS" , 116, 0},
{PI_CMD_TAG , "TAG" , 114, 0},
@ -145,60 +209,110 @@ cmdInfo_t cmdInfo[]=
};
char * cmdUsage = "\
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 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\
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 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 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 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\
PROCD s Delete script s.\n\
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 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 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 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\
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 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\
BC1 bits Clear specified gpios in bank 1.\n\
BC2 bits Clear specified gpios in bank 2.\n\
BR1 Read bank 1 gpios.\n\
BR2 Read bank 2 gpios.\n\
BS1 bits Set specified gpios in bank 2.\n\
BS2 bits Set specified gpios in bank 2.\n\
\n\
H/HELP Display command help.\n\
\n\
HWVER Get hardware version.\n\
\n\
I2CC h Close I2C handle.\n\
I2CO ib id if Open I2C bus and device with flags.\n\
\n\
I2CPC h r wv smb Process Call: exchange register with word.\n\
I2CPK h r bvs smb Block Process Call: exchange data bytes with register.\n\
\n\
I2CRB h r smb Read Byte Data: read byte from register.\n\
I2CRD h num i2c Read bytes.\n\
I2CRI h r num smb Read I2C Block Data: read bytes from register.\n\
I2CRK h r smb Read Block Data: read data from register.\n\
I2CRS h smb Read Byte: read byte.\n\
I2CRW h r smb Read Word Data: read word from register.\n\
\n\
I2CWB h r bv smb Write Byte Data: write byte to register.\n\
I2CWD h bvs i2c Write data.\n\
I2CWI h smb Write I2C Block Data.\n\
I2CWK h r bvs smb Write Block Data: write data to register.\n\
I2CWQ h bit smb Write Quick: write bit.\n\
I2CWS h bv smb Write Byte: write byte.\n\
I2CWW h r wv smb Write Word Data: write word to register.\n\
\n\
M/MODES g m Set gpio mode.\n\
MG/MODEG g Get gpio mode.\n\
\n\
MICS v Delay for microseconds.\n\
MILS v Delay for milliseconds.\n\
\n\
NB h bits Start notification.\n\
NC h Close notification.\n\
NO Request a notification.\n\
NP h Pause notification.\n\
\n\
P/PWM u v Set gpio PWM value.\n\
\n\
PARSE t Validate script.\n\
\n\
PFG u Get gpio PWM frequency.\n\
PFS u v Set gpio PWM frequency.\n\
\n\
PIGPV Get pigpio library version.\n\
\n\
PRG u Get gpio PWM range.\n\
\n\
PROC t Store script.\n\
PROCD sid Delete script.\n\
PROCP sid Get script status and parameters.\n\
PROCR sid pars Run script.\n\
PROCS sid Stop script.\n\
\n\
PRRG u Get gpio PWM real range.\n\
PRS u v Set gpio PWM range.\n\
\n\
PUD g p Set gpio pull up/down.\n\
\n\
R/READ g Read gpio level.\n\
\n\
S/SERVO u v Set gpio servo pulsewidth.\n\
\n\
SERC h Close serial handle.\n\
SERDA h Check for serial data ready to read.\n\
SERO srd srb srf Open serial device at baud with flags.\n\
\n\
SERR h num Read bytes from serial handle.\n\
SERRB Read byte from serial handle.\n\
SERW h bvs Write bytes to serial handle.\n\
SERWB h bv Write byte to serial handle.\n\
\n\
SLR u num Read bit bang serial data from gpio.\n\
SLRC u Close gpio for bit bang serial data.\n\
SLRO u b Open gpio for bit bang serial data.\n\
\n\
SPIC h SPI close handle.\n\
SPIO sc sb sf SPI open channel at baud with flags.\n\
SPIR h num SPI read bytes from handle.\n\
SPIW h bvs SPI write bytes to handle.\n\
SPIX h bvs SPI transfer bytes to handle.\n\
\n\
T/TICK Get current tick.\n\
\n\
TRIG u pl L Trigger level for micros on gpio.\n\
\n\
W/WRITE g L Write level to gpio.\n\
\n\
WDOG u v Set millisecond watchdog on gpio.\n\
\n\
WVAG trips Wave add generic pulses.\n\
WVAS u b o bvs Wave add serial data with offset for gpio at baud.\n\
WVBSY Check if wave busy.\n\
WVCLR Wave clear.\n\
WVCRE Create wave from added pulses.\n\
WVDEL w Delete waves w and higher.\n\
WVDEL wid Delete waves w and higher.\n\
WVGO Wave transmit (DEPRECATED).\n\
WVGOR Wave transmit repeatedly (DEPRECATED).\n\
WVHLT Wave stop.\n\
@ -206,26 +320,39 @@ 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\
WVTX wid Transmit wave as one-shot.\n\
WVTXR wid Transmit wave repeatedly.\n\
\n\
b = baud rate.\n\
bits = a mask where (1<<g) is set for each gpio g of interest.\n\
bv = byte value (0-255).\n\
bvs = one or more byte values (0-255).\n\
g = any gpio (0-53).\n\
h = handle (>=0).\n\
ib = I2C bus (0-1).\n\
id = I2C device (0-127).\n\
if = I2C flags (0).\n\
L = level (0-1).\n\
m = mode (RW540123).\n\
mask = a bit mask where (1<<g) is set for each gpio g of interest.\n\
num = number of bytes to read.\n\
o = offset (>=0).\n\
p = pud (ODU).\n\
pars = 0 to 10 parameters for script.\n\
pl = pulse length (1-50).\n\
pulses = 1 or more triplets of gpios on, gpios off, delay.\n\
s = script id (>=0).\n\
r = register.\n\
sid = script id (>=0).\n\
sb = SPI baud.\n\
sc = SPI channel (0-1).\n\
sf = SPI flags (0-3).\n\
srd = serial device (/dev/tty*).\n\
srb = serial baud rate.\n\
srf = serial flags (0).\n\
t = text.\n\
trips = 1 or more triplets of gpios on, gpios off, delay.\n\
u = user gpio (0-31).\n\
v = value.\n\
w = wave id (>=0).\n\
ws = 0=now, 1=high, 2=max.\n\
wv = word value (0-65535).\n\
\n\
Numbers may be entered as hex (prefix 0x), octal (prefix 0),\n\
otherwise they are assumed to be decimal.\n\
@ -309,6 +436,24 @@ static errInfo_t errInfo[]=
{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"},
{PI_I2C_OPEN_FAILED , "can't open I2C device"},
{PI_SER_OPEN_FAILED , "can't open serial device"},
{PI_SPI_OPEN_FAILED , "can't open SPI device"},
{PI_BAD_I2C_BUS , "bad I2C bus"},
{PI_BAD_I2C_ADDR , "bad I2C address"},
{PI_BAD_SPI_CHANNEL , "bad SPI channel"},
{PI_BAD_FLAGS , "bad i2c/spi/ser open flags"},
{PI_BAD_SPI_SPEED , "bad SPI speed"},
{PI_BAD_SER_DEVICE , "bad serial device name"},
{PI_BAD_SER_SPEED , "bad serial baud rate"},
{PI_BAD_PARAM , "bad i2c/spi/ser parameter"},
{PI_I2C_WRITE_FAILED , "I2C write failed"},
{PI_I2C_READ_FAILED , "I2C read failed"},
{PI_BAD_SPI_COUNT , "bad SPI count"},
{PI_SER_WRITE_FAILED , "ser write failed"},
{PI_SER_READ_FAILED , "ser read failed"},
{PI_SER_READ_NO_DATA , "ser read no data available"},
{PI_UNKNOWN_COMMAND , "unknown command"},
};
@ -372,12 +517,18 @@ char *cmdStr(void)
return intCmdStr;
}
int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
int cmdParse(
char *buf, uint32_t *p, unsigned ext_len, char *ext, cmdCtlParse_t *ctl)
{
int f, valid, idx, val, pp, pars, n, n2, i;
char *ptr;
char *p8;
int32_t *p32;
char c;
int32_t param[MAX_PARAM];
uint32_t tp1;
int8_t to1;
/* Check that ext is big enough for the largest message. */
if (ext_len < (4 * CMD_MAX_PARAM)) return CMD_EXT_TOO_SMALL;
bzero(&ctl->opt, sizeof(ctl->opt));
@ -396,10 +547,12 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
p[0] = cmdInfo[idx].cmd;
p[1] = 0;
p[2] = 0;
p[3] = 0;
switch (cmdInfo[idx].vt)
{
case 101: /* BR1 BR2 DCRA H HALT HELP HWVER INRA NO
case 101: /* BR1 BR2 H HELP HWVER
DCRA HALT INRA NO
PIGPV POPA PUSHA RET T TICK WVBSY WVCLR
WVCRE WVGO WVGOR WVHLT WVNEW
@ -409,26 +562,28 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
break;
case 111: /* ADD AND BC1 BC2 BS1 BS2 CMP DIV LDA MLT
MOD OR RLA RRA SUB WAIT XOR
case 111: /* BC1 BC2 BS1 BS2
ADD AND CMP DIV LDA LDAB MLT
MOD OR RLA RRA STAB SUB WAIT XOR
One parameter, any value.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
if (ctl->opt[0] > 0) valid = 1;
if (ctl->opt[1] > 0) valid = 1;
break;
case 112: /* MG MICS MILS MODEG NC NP PFG PRG
PROCD PROCP PROCS PRRG R READ SLRC
case 112: /* I2CC
I2CRB MG MICS MILS MODEG NC NP PFG PRG
PROCD PROCP PROCS PRRG R READ SLRC SPIC
WVDEL WVSC WVSM WVSP WVTX WVTXR
One positive parameter.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
if ((ctl->opt[0] > 0) && ((int)p[1] >= 0)) valid = 1;
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0)) valid = 1;
break;
@ -436,9 +591,9 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
One register parameter.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
if ((ctl->opt[0] > 0) && (p[1] < PI_MAX_SCRIPT_VARS)) valid = 1;
if ((ctl->opt[1] > 0) && (p[1] < PI_MAX_SCRIPT_VARS)) valid = 1;
break;
@ -446,8 +601,8 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
One numeric parameter, any value.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
if (ctl->opt[0] == CMD_NUMERIC) valid = 1;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
if (ctl->opt[1] == CMD_NUMERIC) valid = 1;
break;
@ -455,10 +610,9 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
One parameter, string (rest of input).
*/
p[1] = strlen(buf+ctl->eaten);
v[1] = buf+ctl->eaten;
ctl->eaten += p[1];
p[3] = strlen(buf+ctl->eaten);
memcpy(ext, buf+ctl->eaten, p[3]);
ctl->eaten += p[3];
valid = 1;
break;
@ -485,24 +639,25 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
if (valid)
{
p[1] = n;
ctl->opt[0] = CMD_NUMERIC;
v[1]=buf+ctl->eaten;
p[3] = n;
ctl->opt[3] = CMD_NUMERIC;
memcpy(ext, buf+ctl->eaten, n);
ctl->eaten += n2;
}
}
break;
case 121: /* P PFS PRS PWM S SERVO SLR SLRO W WDOG WRITE
case 121: /* I2CRD I2CRR I2CRW I2CWB I2CWQ 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]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) &&
(ctl->opt[1] > 0) && ((int)p[2] >= 0)) valid = 1;
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
(ctl->opt[2] > 0) && ((int)p[2] >= 0)) valid = 1;
break;
@ -510,11 +665,11 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
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]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) &&
(ctl->opt[1] > 0)) valid = 1;
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
(ctl->opt[2] > 0)) valid = 1;
break;
@ -522,12 +677,12 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
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]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
if ((ctl->opt[0] > 0) &&
if ((ctl->opt[1] > 0) &&
(p[1] < PI_MAX_SCRIPT_VARS) &&
(ctl->opt[1] > 0)) valid = 1;
(ctl->opt[2] > 0)) valid = 1;
break;
@ -535,11 +690,11 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
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]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
if ((ctl->opt[0] > 0) && (p[1] < PI_MAX_SCRIPT_VARS) &&
(ctl->opt[1] > 0) && (p[2] < PI_MAX_SCRIPT_VARS)) valid = 1;
if ((ctl->opt[1] > 0) && (p[1] < PI_MAX_SCRIPT_VARS) &&
(ctl->opt[2] > 0) && (p[2] < PI_MAX_SCRIPT_VARS)) valid = 1;
break;
@ -547,19 +702,19 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
Two parameters, first positive, second in 'RW540123'.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) && (f >= 1))
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) && (f >= 1))
{
ctl->eaten += n;
val = toupper(c);
ptr = strchr(fmtMdeStr, val);
p8 = strchr(fmtMdeStr, val);
if (ptr != NULL)
if (p8 != NULL)
{
val = ptr - fmtMdeStr;
val = p8 - fmtMdeStr;
p[2] = val;
valid = 1;
}
@ -571,18 +726,18 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
Two parameters, first positive, second in 'ODU'.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
if ((ctl->opt[0] > 0) && ((int)p[1] >= 0) && (f >= 1))
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) && (f >= 1))
{
ctl->eaten += n;
val = toupper(c);
ptr = strchr(fmtPudStr, val);
if (ptr != NULL)
p8 = strchr(fmtPudStr, val);
if (p8 != NULL)
{
val = ptr - fmtPudStr;
val = p8 - fmtPudStr;
p[2] = val;
valid = 1;
}
@ -590,37 +745,42 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
break;
case 131: /* TRIG
case 131: /* I2CO I2CPC I2CRI I2CWB I2CWW SPIO 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]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
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))
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
(ctl->opt[2] > 0) && ((int)p[2] >= 0) &&
(to1 == CMD_NUMERIC) && ((int)tp1 >= 0))
{
p[3] = 4;
memcpy(ext, &tp1, 4);
valid = 1;
}
break;
case 141: /* WVAS
case 132: /* SERO
Four parameters, first two positive, third any value,
last string (rest of input).
Three parameters, first a string, rest >=0
*/
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))
f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
if ((f >= 0) && n)
{
p[4] = strlen(buf+ctl->eaten);
v[1] = buf+ctl->eaten;
ctl->eaten += p[4];
p[3] = n;
ctl->opt[2] = CMD_NUMERIC;
memcpy(ext, buf+ctl->eaten, n);
ctl->eaten += n2;
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
(ctl->opt[2] > 0) && ((int)p[2] >= 0))
valid = 1;
}
@ -631,22 +791,25 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
One to 11 parameters, first positive,
optional remainder, any value.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
if ((ctl->opt[0] == CMD_NUMERIC) && ((int)p[1] >= 0))
if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0))
{
pars = 0;
p32 = (int32_t *)ext;
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];
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
if (to1 == CMD_NUMERIC)
{
pars++;
*p32++ = tp1;
}
else break;
}
p[2] = pars;
v[1] = param;
p[3] = pars * 4;
valid = 1;
}
@ -658,23 +821,133 @@ int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl)
One or more triplets (gpios on, gpios off, delay),
any value.
*/
pars = 0;
while (pars < MAX_PARAM)
pars = 0;
p32 = (int32_t *)ext;
while (pars < CMD_MAX_PARAM)
{
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[0]);
if (ctl->opt[0] == CMD_NUMERIC) param[pars++] = p[1];
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
if (to1 == CMD_NUMERIC)
{
pars++;
*p32++ = tp1;
}
else break;
}
p[1] = pars / 3;
v[1] = param;
p[3] = pars * 4;
if (pars && ((pars % 3) == 0)) valid = 1;
break;
case 193: /* I2CWD SERW
Two or more parameters, first >=0, rest 0-255.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0))
{
pars = 0;
p8 = ext;
while (pars < CMD_MAX_PARAM)
{
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
if ((to1 == CMD_NUMERIC) &&
((int)tp1>=0) && ((int)tp1<=255))
{
pars++;
*p8++ = tp1;
}
else break;
}
p[3] = pars;
if (pars) valid = 1;
}
break;
case 194: /* I2CPK I2CWI I2CWK
Three to 34 parameters, all 0-255.
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
if ((ctl->opt[1] == CMD_NUMERIC) &&
(ctl->opt[2] == CMD_NUMERIC) &&
((int)p[1]>=0) && ((int)p[2]>=0) && ((int)p[2]<=255))
{
pars = 0;
p8 = ext;
while (pars < 32)
{
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
if ((to1 == CMD_NUMERIC) &&
((int)tp1>=0) &&
((int)tp1<=255))
{
pars++;
*p8++ = tp1;
}
else break;
}
p[3] = pars;
if (pars > 0) valid = 1;
}
break;
case 196: /* WVAS
gpio baud offset char...
p1 gpio
p2 baud
p3 len + 4
---------
uint32_t offset
uint8_t[len]
*/
ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0) &&
(ctl->opt[2] == CMD_NUMERIC) && ((int)p[2] > 0) &&
(to1 == CMD_NUMERIC))
{
pars = 0;
memcpy(ext, &tp1, 4);
p8 = ext + 4;
while (pars < CMD_MAX_PARAM)
{
ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
if ((to1 == CMD_NUMERIC) &&
((int)tp1>=0) && ((int)tp1<=255))
{
*p8++ = tp1;
pars++;
}
else break;
}
p[3] = pars + 4;
if (pars > 0) valid = 1;
}
break;
}
@ -697,9 +970,9 @@ 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;
char v[CMD_MAX_EXTENSION];
ctl.eaten = 0;
@ -714,7 +987,7 @@ int cmdParseScript(char *script, cmdScript_t *s, int diags)
b = (sizeof(int) * (PI_MAX_SCRIPT_PARAMS + PI_MAX_SCRIPT_VARS)) +
(sizeof(cmdInstr_t) * (len + 2) / 2) + len;
s->par = calloc(b, 1);
s->par = calloc(1, b);
if (s->par == NULL) return -1;
@ -735,39 +1008,22 @@ int cmdParseScript(char *script, cmdScript_t *s, int diags)
while (ctl.eaten<len)
{
idx = cmdParse(script, p, v, &ctl);
memcpy(&instr.p, p, sizeof(instr.p));
idx = cmdParse(script, p, CMD_MAX_EXTENSION, v, &ctl);
if (idx >= 0)
{
switch (instr.p[0])
if (p[3])
{
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());
memcpy(s->str_area + s->str_area_pos, v, p[3]);
s->str_area[s->str_area_pos + p[3]] = 0;
p[4] = (intptr_t) s->str_area + s->str_area_pos;
s->str_area_pos += (p[3] + 1);
}
if (!status) status = PI_BAD_SCRIPT_CMD;
idx = -1;
break;
case PI_CMD_TAG:
memcpy(&instr.p, p, sizeof(instr.p));
if (instr.p[0] == PI_CMD_TAG)
{
if (tags < PI_MAX_SCRIPT_TAGS)
{
/* check tag not already used */
@ -798,18 +1054,6 @@ int cmdParseScript(char *script, cmdScript_t *s, int diags)
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

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 14+
This version is for pigpio version 16+
*/
#ifndef COMMAND_H
@ -37,15 +37,33 @@ This version is for pigpio version 14+
#include "pigpio.h"
#define MAX_PARAM 512
#define CMD_MAX_PARAM 512
#define CMD_MAX_EXTENSION 8192
#define CMD_UNKNOWN_CMD -1
#define CMD_BAD_PARAMETER -2
#define CMD_EXT_TOO_SMALL -3
#define CMD_P_ARR 10
#define CMD_V_ARR 10
#define CMD_NUMERIC 1
#define CMD_VAR 2
#define CMD_PAR 3
typedef struct
{
uint32_t cmd;
uint32_t p1;
uint32_t p2;
union
{
uint32_t p3;
uint32_t ext_len;
uint32_t res;
};
} cmdCmd_t;
typedef struct
{
int eaten;
@ -68,7 +86,7 @@ typedef struct
typedef struct
{
uint32_t p[7];
uint32_t p[5];
int8_t opt[4];
} cmdInstr_t;
@ -92,7 +110,7 @@ extern cmdInfo_t cmdInfo[];
extern char *cmdUsage;
int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl);
int cmdParse(char *buf, uint32_t *p, unsigned ext_len, char *ext, cmdCtlParse_t *ctl);
int cmdParseScript(char *script, cmdScript_t *s, int diags);

1780
pigpio.c

File diff suppressed because it is too large Load Diff

3201
pigpio.h

File diff suppressed because it is too large Load Diff

3213
pigpio.py

File diff suppressed because it is too large Load Diff

View File

@ -107,7 +107,7 @@ static int pigpio_command(int fd, int command, int p1, int p2)
}
static int pigpio_command_ext
(int fd, int command, int p1, int p2, int extents, gpioExtent_t *ext)
(int fd, int command, int p1, int p2, int p3, int extents, gpioExtent_t *ext)
{
int i;
cmdCmd_t cmd;
@ -115,7 +115,7 @@ static int pigpio_command_ext
cmd.cmd = command;
cmd.p1 = p1;
cmd.p2 = p2;
cmd.res = 0;
cmd.p3 = p3;
if (send(fd, &cmd, sizeof(cmd), 0) != sizeof(cmd)) return pigif_bad_send;
@ -614,8 +614,9 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
gpioExtent_t ext[1];
/*
p1=numPulses
p1=0
p2=0
p3=pulses*sizeof(gpioPulse_t)
## extension ##
gpioPulse_t[] pulses
*/
@ -625,7 +626,8 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
ext[0].size = numPulses * sizeof(gpioPulse_t);
ext[0].ptr = pulses;
return pigpio_command_ext(gPigCommand, PI_CMD_WVAG, numPulses, 0, 1, ext);
return pigpio_command_ext(
gPigCommand, PI_CMD_WVAG, 0, 0, ext[0].size, 1, ext);
}
int wave_add_serial(
@ -635,25 +637,23 @@ int wave_add_serial(
/*
p1=gpio
p2=numChar
p2=baud
p3=len+4
## extension ##
unsigned baud
unsigned offset
char[] str
char[len] str
*/
if (!numChar) return 0;
ext[0].size = sizeof(unsigned);
ext[0].ptr = &baud;
ext[0].ptr = &offset;
ext[1].size = sizeof(unsigned);
ext[1].ptr = &offset;
ext[1].size = numChar;
ext[1].ptr = str;
ext[2].size = numChar;
ext[2].ptr = str;
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext);
return pigpio_command_ext(
gPigCommand, PI_CMD_WVAS, gpio, baud, numChar+4, 2, ext);
}
int wave_create(void)
@ -714,6 +714,7 @@ int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level)
/*
p1=gpio
p2=pulseLen
p3=4
## extension ##
unsigned level
*/
@ -721,7 +722,8 @@ int gpio_trigger(unsigned gpio, unsigned pulseLen, unsigned level)
ext[0].size = sizeof(level);
ext[0].ptr = &level;
return pigpio_command_ext(gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 1, ext);
return pigpio_command_ext(
gPigCommand, PI_CMD_TRIG, gpio, pulseLen, 4, 1, ext);
}
int store_script(char *script)
@ -730,18 +732,21 @@ int store_script(char *script)
gpioExtent_t ext[1];
/*
p1=script length
p1=0
p2=0
p3=len
## extension ##
char[] script
char[len] script
*/
len = strlen(script);
if (!len) return 0;
ext[0].size = len;
ext[0].ptr = script;
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, len, 0, 1, ext);
return pigpio_command_ext(gPigCommand, PI_CMD_PROC, 0, 0, len, 1, ext);
}
int run_script(unsigned script_id, unsigned numPar, uint32_t *param)
@ -750,16 +755,17 @@ int run_script(unsigned script_id, unsigned numPar, uint32_t *param)
/*
p1=script id
p2=number of parameters
p2=0
p3=numPar * 4
## extension ##
uint32_t[] parameters
uint32_t[numPar] pars
*/
ext[0].size = sizeof(uint32_t)*numPar;
ext[0].size = 4 * numPar;
ext[0].ptr = param;
return pigpio_command_ext
(gPigCommand, PI_CMD_PROCR, script_id, numPar, 1, ext);
(gPigCommand, PI_CMD_PROCR, script_id, 0, numPar*4, 1, ext);
}
int script_status(unsigned script_id, uint32_t *param)
@ -786,10 +792,10 @@ int stop_script(unsigned script_id)
int delete_script(unsigned script_id)
{return pigpio_command(gPigCommand, PI_CMD_PROCD, script_id, 0);}
int serial_read_open(unsigned gpio, unsigned baud)
int bb_serial_read_open(unsigned gpio, unsigned baud)
{return pigpio_command(gPigCommand, PI_CMD_SLRO, gpio, baud);}
int serial_read(unsigned gpio, void *buf, size_t bufSize)
int bb_serial_read(unsigned gpio, void *buf, size_t bufSize)
{
int bytes;
@ -803,9 +809,398 @@ int serial_read(unsigned gpio, void *buf, size_t bufSize)
return bytes;
}
int serial_read_close(unsigned gpio)
int bb_serial_read_close(unsigned gpio)
{return pigpio_command(gPigCommand, PI_CMD_SLRC, gpio, 0);}
int i2c_open(unsigned bus, unsigned addr, unsigned flags)
{
gpioExtent_t ext[1];
/*
p1=bus
p2=addr
p3=4
## extension ##
uint32_t flags
*/
ext[0].size = 4;
ext[0].ptr = &flags;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CO, bus, addr, 4, 1, ext);
}
int i2c_close(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_I2CC, handle, 0);}
int i2c_read_device(unsigned handle, char *buf, unsigned count)
{
int bytes;
bytes = pigpio_command(gPigCommand, PI_CMD_I2CRD, handle, count);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, buf, bytes, MSG_WAITALL);
}
return bytes;
}
int i2c_write_device(unsigned handle, char *buf, unsigned count)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=0
p3=count
## extension ##
char buf[count] flags
*/
ext[0].size = count;
ext[0].ptr = buf;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CWD, handle, 0, count, 1, ext);
}
int i2c_write_quick(unsigned handle, unsigned bit)
{return pigpio_command(gPigCommand, PI_CMD_I2CWQ, handle, bit);}
int i2c_write_byte(unsigned handle, unsigned val)
{return pigpio_command(gPigCommand, PI_CMD_I2CWS, handle, val);}
int i2c_read_byte(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_I2CRS, handle, 0);}
int i2c_write_byte_data(unsigned handle, unsigned reg, unsigned val)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=4
## extension ##
uint32_t val
*/
ext[0].size = 4;
ext[0].ptr = &val;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CWB, handle, reg, 4, 1, ext);
}
int i2c_write_word_data(unsigned handle, unsigned reg, unsigned val)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=4
## extension ##
uint32_t val
*/
ext[0].size = 4;
ext[0].ptr = &val;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CWW, handle, reg, 4, 1, ext);
}
int i2c_read_byte_data(unsigned handle, unsigned reg)
{return pigpio_command(gPigCommand, PI_CMD_I2CRB, handle, reg);}
int i2c_read_word_data(unsigned handle, unsigned reg)
{return pigpio_command(gPigCommand, PI_CMD_I2CRW, handle, reg);}
int i2c_process_call(unsigned handle, unsigned reg, unsigned val)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=4
## extension ##
uint32_t val
*/
ext[0].size = 4;
ext[0].ptr = &val;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CPK, handle, reg, 4, 1, ext);
}
int i2c_write_block_data(
unsigned handle, unsigned reg, char *buf, unsigned count)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=count
## extension ##
char buf[count]
*/
ext[0].size = count;
ext[0].ptr = buf;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CWK, handle, reg, count, 1, ext);
}
int i2c_read_block_data(unsigned handle, unsigned reg, char *buf)
{
int bytes;
bytes = pigpio_command(gPigCommand, PI_CMD_I2CRK, handle, reg);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, buf, bytes, MSG_WAITALL);
}
return bytes;
}
int i2c_block_process_call(
unsigned handle, unsigned reg, char *buf, unsigned count)
{
int bytes;
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=count
## extension ##
char buf[count]
*/
ext[0].size = count;
ext[0].ptr = buf;
bytes = pigpio_command_ext
(gPigCommand, PI_CMD_I2CPK, handle, reg, count, 1, ext);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, buf, bytes, MSG_WAITALL);
}
return bytes;
}
int i2c_read_i2c_block_data(
unsigned handle, unsigned reg, char *buf, unsigned count)
{
int bytes;
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=4
## extension ##
uint32_t count
*/
ext[0].size = 4;
ext[0].ptr = &count;
bytes = pigpio_command_ext
(gPigCommand, PI_CMD_I2CRI, handle, reg, 4, 1, ext);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, buf, bytes, MSG_WAITALL);
}
return bytes;
}
int i2c_write_i2c_block_data(
unsigned handle, unsigned reg, char *buf, unsigned count)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=reg
p3=count
## extension ##
char buf[count]
*/
ext[0].size = count;
ext[0].ptr = buf;
return pigpio_command_ext
(gPigCommand, PI_CMD_I2CWI, handle, reg, count, 1, ext);
}
int spi_open(unsigned channel, unsigned speed, unsigned flags)
{
gpioExtent_t ext[1];
/*
p1=channel
p2=speed
p3=4
## extension ##
uint32_t flags
*/
ext[0].size = 4;
ext[0].ptr = &flags;
return pigpio_command_ext
(gPigCommand, PI_CMD_SPIO, channel, speed, 4, 1, ext);
}
int spi_close(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_SPIC, handle, 0);}
int spi_read(unsigned handle, char *buf, unsigned count)
{
int bytes;
bytes = pigpio_command
(gPigCommand, PI_CMD_SPIR, handle, count);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, buf, bytes, MSG_WAITALL);
}
return bytes;
}
int spi_write(unsigned handle, char *buf, unsigned count)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=0
p3=count
## extension ##
char buf[count]
*/
ext[0].size = count;
ext[0].ptr = buf;
return pigpio_command_ext
(gPigCommand, PI_CMD_SPIW, handle, 0, count, 1, ext);
}
int spi_xfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)
{
int bytes;
gpioExtent_t ext[1];
/*
p1=handle
p2=0
p3=count
## extension ##
char buf[count]
*/
ext[0].size = count;
ext[0].ptr = txBuf;
bytes = pigpio_command_ext
(gPigCommand, PI_CMD_SPIX, handle, 0, count, 1, ext);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, rxBuf, bytes, MSG_WAITALL);
}
return bytes;
}
int serial_open(char *dev, unsigned baud, unsigned flags)
{
int len;
gpioExtent_t ext[1];
len = strlen(dev);
/*
p1=baud
p2=flags
p3=len
## extension ##
char dev[len]
*/
ext[0].size = len;
ext[0].ptr = dev;
return pigpio_command_ext
(gPigCommand, PI_CMD_SERO, baud, flags, len, 1, ext);
}
int serial_close(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_SERC, handle, 0);}
int serial_write_byte(unsigned handle, unsigned val)
{return pigpio_command(gPigCommand, PI_CMD_SERWB, handle, val);}
int serial_read_byte(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_SERRB, handle, 0);}
int serial_write(unsigned handle, char *buf, unsigned count)
{
gpioExtent_t ext[1];
/*
p1=handle
p2=0
p3=count
## extension ##
char buf[count]
*/
ext[0].size = count;
ext[0].ptr = buf;
return pigpio_command_ext
(gPigCommand, PI_CMD_SERW, handle, 0, count, 1, ext);
}
int serial_read(unsigned handle, char *buf, unsigned count)
{
int bytes;
bytes = pigpio_command
(gPigCommand, PI_CMD_SERR, handle, count);
if (bytes > 0)
{
/* get the data */
recv(gPigCommand, buf, bytes, MSG_WAITALL);
}
return bytes;
}
int serial_data_available(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_SERDA, handle, 0);}
int callback(unsigned gpio, unsigned edge, CBFunc_t f)
{return intCallback(gpio, edge, f, 0, 0);}

View File

@ -762,33 +762,221 @@ int delete_script(unsigned script_id);
The function returns 0 if OK, otherwise PI_BAD_SCRIPT_ID.
*/
int serial_read_open(unsigned user_gpio, unsigned baud);
/* This function opens a gpio for reading serial data.
int bb_serial_read_open(unsigned user_gpio, unsigned baud);
/* This function opens a gpio for bit-banged reading of 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
serial_read().
bb_serial_read().
It is the caller's responsibility to read data from the cyclic buffer
in a timely fashion.
*/
int serial_read(unsigned user_gpio, void *buf, size_t bufSize);
int bb_serial_read(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.
bit-bang 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 serial_read_close(unsigned user_gpio);
/* This function closes a gpio for reading serial data.
int bb_serial_read_close(unsigned user_gpio);
/* This function closes a gpio for bit-banged reading of serial data.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
*/
int i2c_open(unsigned bus, unsigned addr, unsigned flags);
/* This returns a handle for the device at address addr on I2C bus bus.
No flags are currently defined. This parameter should be set to zero.
*/
int i2c_close(unsigned handle);
/* This closes the I2C device associated with the handle.
*/
int i2c_read_device(unsigned handle, char *buf, unsigned count);
/* This reads count bytes from the raw device into buf.
*/
int i2c_write_device(unsigned handle, char *buf, unsigned count);
/* This writes count bytes from buf to the raw device.
*/
int i2c_write_quick(unsigned handle, unsigned bit);
/* This sends a single bit to the device (in the Rd/Wr bit).
Quick command. smbus 2.0 5.5.1
*/
int i2c_write_byte(unsigned handle, unsigned val);
/* This operation is the reverse of i2cReadByte: it sends a single byte
to a device.
Send byte. smbus 2.0 5.5.2
*/
int i2c_read_byte(unsigned handle);
/* This reads a single byte from a device, without specifying a device
register. Some devices are so simple that this interface is enough;
for others, it is a shorthand if you want to read the same register
as in the previous SMBus command.
Receive byte. smbus 2.0 5.5.3
*/
int i2c_write_byte_data(unsigned handle, unsigned reg, unsigned val);
/* This writes a single byte to a device, to a designated register.
This is the opposite of the i2cReadByte function.
Write byte. smbus 2.0 5.5.4
*/
int i2c_write_word_data(unsigned handle, unsigned reg, unsigned val);
/* This is the opposite of the i2cReadWordData operation. 16 bits
of data is written to a device, to the designated register.
Write word. smbus 2.0 5.5.4
*/
int i2c_read_byte_data(unsigned handle, unsigned reg);
/* This reads a single byte from a device, from a designated register.
Read byte. smbus 2.0 5.5.5
*/
int i2c_read_word_data(unsigned handle, unsigned reg);
/* This operation is very like i2cReadByte; again, data is read
from a device, from a designated register. But this time, the data
is a complete word (16 bits).
Read word. smbus 2.0 5.5.5
*/
int i2c_process_call(unsigned handle, unsigned reg, unsigned val);
/* This command selects a device register, sends 16 bits of data to it,
and reads 16 bits of data in return.
Process call. smbus 2.0 5.5.6
*/
int i2c_write_block_data(
unsigned handle, unsigned reg, char *buf, unsigned count);
/* The opposite of the i2cReadBlockData command, this writes up to
32 bytes to a device, to a designated register. The amount of data
is specified in the count byte.
Block write. smbus 2.0 5.5.7
*/
int i2c_read_block_data(unsigned handle, unsigned reg, char *buf);
/* This command reads a block of up to 32 bytes from a device, from a
designated register. The amount of returned data is set by the device.
Block read. smbus 2.0 5.5.7
*/
int i2c_block_process_call(
unsigned handle, unsigned reg, char *buf, unsigned count);
/* This command selects a device register, sends count bytes of data
to it, and reads a device specified number of bytes of data in return.
The smbus 2.0 documentation states that a minimum of 1 byte may be
sent and a minimum of 1 byte may be received. The total number of
bytes sent/received must be 32 or less.
Block write-block read. smbus 2.0 5.5.8
*/
int i2c_read_i2c_block_data(
unsigned handle, unsigned reg, char *buf, unsigned count);
/* This command reads a block of bytes from a device, from a
designated register. The count may be 1-32.
*/
int i2c_write_i2c_block_data(
unsigned handle, unsigned reg, char *buf, unsigned count);
/* The opposite of the i2cReadI2CBlockData command, this writes bytes to
a device, to a designated register.. Note that command lengths of 0, 2,
or more bytes are supported as they are indistinguishable from data.
Count may be 1-32.
*/
int spi_open(unsigned channel, unsigned speed, unsigned flags);
/* This function returns a handle for the SPI device on channel.
Data will be transferred at speed bits per second.
The bottom two bits of flags define the SPI mode as follows.
bit bit
1 0
Mode POL PHA
0 0 0
1 0 1
2 1 0
3 1 1
The other bits in flags should be set to zero.
*/
int spi_close(unsigned handle);
/* This functions closes the SPI device identified by the handle.
*/
int spi_read(unsigned handle, char *buf, unsigned count);
/* This function reads count bytes of data from the SPI
device associated with the handle.
*/
int spi_write(unsigned handle, char *buf, unsigned count);
/* This function writes count bytes of data from buf to the SPI
device associated with the handle.
*/
int spi_xfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count);
/* This function writes count bytes of data from txBuf to the SPI
device associated with the handle.
The data read from the device is written to rxBuf.
*/
int serial_open(char *dev, unsigned baud, unsigned flags);
/* This function open the serial device named dev at baud bits per second.
No flags are currently defined. This parameter should be set to zero.
*/
int serial_close(unsigned handle);
/* This function closes the serial device associated with handle.
*/
int serial_write_byte(unsigned handle, unsigned val);
/* This function writes val to the serial port associated with handle.
*/
int serial_read_byte(unsigned handle);
/* This function reads a byte from the serial port associated with handle.
*/
int serial_write(unsigned handle, char *buf, unsigned count);
/* This function writes count bytes from buf to the the serial port
associated with handle.
*/
int serial_read(unsigned handle, char *buf, unsigned count);
/* This function reads count bytes from the the serial port
associated with handle and writes them to buf.
*/
int serial_data_available(unsigned handle);
/* Returns the number of bytes available to be read from the
device associated with handle.
*/
int callback(unsigned gpio, unsigned edge, CBFunc_t f);
/*
This function initialises a new callback.

107
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 14+
This version is for pigpio version 16+
*/
#include <stdio.h>
@ -142,11 +142,11 @@ void print_result(int sock, int rv, cmdCmd_t cmd)
printf(cmdUsage);
break;
case 6: /* SLR */
case 6: /* SLR I2CRD */
if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
else if (r > 0)
{
printf("%s", response_buf);
write(1, response_buf, r);
}
break;
@ -173,7 +173,7 @@ void get_extensions(int sock, int command, int res)
{
switch (command)
{
case PI_CMD_PROCP: /* PROCP */
case PI_CMD_PROCP:
if (res >= 0)
{
recv(sock,
@ -183,7 +183,15 @@ void get_extensions(int sock, int command, int res)
}
break;
case PI_CMD_SLR: /* SLR */
case PI_CMD_I2CPK:
case PI_CMD_I2CRD:
case PI_CMD_I2CRI:
case PI_CMD_I2CRK:
case PI_CMD_SERR:
case PI_CMD_SLR:
case PI_CMD_SPIX:
case PI_CMD_SPIR:
if (res > 0)
{
recv(sock, response_buf, res, MSG_WAITALL);
@ -193,76 +201,15 @@ void get_extensions(int sock, int command, int res)
}
}
void put_extensions(int sock, int command, uint32_t *p, void *v[])
{
switch (command)
{
case PI_CMD_PROC:
/*
p1=script length w[1]
p2=0
## extension ##
char[] script v[1]
*/
send(sock, v[1], p[1], 0);
break;
case PI_CMD_PROCR:
/*
p1=script id w[1]
p2=numParam w[2]
## extension ##
int[] param v[1]
*/
if (p[2]) send(sock, v[1], p[2]*sizeof(uint32_t), 0);
break;
case PI_CMD_TRIG:
/*
p1=user_gpio w[1]
p2=pulseLen w[2]
## extension ##
unsigned level w[3]
*/
send(sock, &p[3], 4, 0);
break;
case PI_CMD_WVAG:
/*
p1=pulses w[1]
p2=0
## extension ##
int[] param v[1]
*/
if (p[1]) send(sock, v[1], p[1]*sizeof(gpioPulse_t), 0);
break;
case PI_CMD_WVAS:
/*
p1=user_gpio w[1]
p2=numChar w[4]
## extension ##
unsigned baud w[2]
unsigned offset w[3]
char[] str v[1]
*/
send(sock, &p[2], 4, 0);
send(sock, &p[3], 4, 0);
send(sock, v[1], p[4], 0);
break;
}
}
int main(int argc , char *argv[])
{
int sock, command;
int idx, i, pp, l, len;
cmdCmd_t cmd;
uint32_t p[10];
void *v[10];
uint32_t p[CMD_P_ARR];
cmdCtlParse_t ctl;
cmdScript_t s;
char v[CMD_MAX_EXTENSION];
sock = openSocket();
@ -286,7 +233,7 @@ int main(int argc , char *argv[])
while ((idx >= 0) && (ctl.eaten < len))
{
if ((idx=cmdParse(command_buf, p, v, &ctl)) >= 0)
if ((idx=cmdParse(command_buf, p, CMD_MAX_EXTENSION, v, &ctl)) >= 0)
{
command = p[0];
@ -298,7 +245,7 @@ int main(int argc , char *argv[])
}
else if (command == PI_CMD_PARSE)
{
cmdParseScript(v[1], &s, 1);
cmdParseScript(v, &s, 1);
if (s.par) free (s.par);
}
else
@ -306,24 +253,14 @@ int main(int argc , char *argv[])
cmd.cmd = command;
cmd.p1 = p[1];
cmd.p2 = p[2];
switch (command)
{
case PI_CMD_WVAS:
cmd.p2 = p[4];
break;
case PI_CMD_PROC:
cmd.p2 = 0;
break;
}
cmd.p3 = p[3];
if (sock != SOCKET_OPEN_FAILED)
{
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) ==
sizeof(cmdCmd_t))
{
put_extensions(sock, command, p, v);
if (p[3]) send(sock, v, p[3], 0); /* send extensions */
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
sizeof(cmdCmd_t))
@ -332,11 +269,11 @@ int main(int argc , char *argv[])
print_result(sock, cmdInfo[idx].rv, cmd);
}
else fatal("recv failed, %m");
else fatal("socket receive failed");
}
else fatal("send failed, %m");
else fatal("socket send failed");
}
else fatal("connect failed");
else fatal("socket connect failed");
}
}
else fatal("%s only allowed within a script", cmdInfo[idx].name);

View File

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

View File

@ -17,6 +17,7 @@ sudo ./x_pigpio
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "pigpio.h"
@ -623,10 +624,214 @@ void t9()
CHECK(9, 4, e, 0, 0, "delete script");
}
void ta()
{
int h, b, e;
char *TEXT;
char text[2048];
printf("Serial link tests.\n");
/* this test needs RXD and TXD to be connected */
h = serOpen("/dev/ttyAMA0", 57600, 0);
CHECK(10, 1, h, 0, 0, "serial open");
b = serRead(h, text, sizeof(text)); /* flush buffer */
b = serDataAvailable(h);
CHECK(10, 2, b, 0, 0, "serial data available");
TEXT = "\
To be, or not to be, that is the question-\
Whether 'tis Nobler in the mind to suffer\
The Slings and Arrows of outrageous Fortune,\
Or to take Arms against a Sea of troubles,\
";
e = serWrite(h, TEXT, strlen(TEXT));
CHECK(10, 3, e, 0, 0, "serial write");
e = serWriteByte(h, 0xAA);
e = serWriteByte(h, 0x55);
e = serWriteByte(h, 0x00);
e = serWriteByte(h, 0xFF);
CHECK(10, 4, e, 0, 0, "serial write byte");
time_sleep(0.1); /* allow time for transmission */
b = serDataAvailable(h);
CHECK(10, 5, b, strlen(TEXT)+4, 0, "serial data available");
b = serRead(h, text, strlen(TEXT));
CHECK(10, 6, b, strlen(TEXT), 0, "serial read");
if (b >= 0) text[b] = 0;
CHECK(10, 7, strcmp(TEXT, text), 0, 0, "serial read");
b = serReadByte(h);
CHECK(10, 8, b, 0xAA, 0, "serial read byte");
b = serReadByte(h);
CHECK(10, 9, b, 0x55, 0, "serial read byte");
b = serReadByte(h);
CHECK(10, 10, b, 0x00, 0, "serial read byte");
b = serReadByte(h);
CHECK(10, 11, b, 0xFF, 0, "serial read byte");
b = serDataAvailable(h);
CHECK(10, 12, b, 0, 0, "serial data availabe");
e = serClose(h);
CHECK(10, 13, e, 0, 0, "serial close");
}
void tb()
{
int h, e, b, len;
char *exp;
char buf[128];
printf("SMBus / I2C tests.");
/* this test requires an ADXL345 on I2C bus 1 addr 0x53 */
h = i2cOpen(1, 0x53, 0);
CHECK(11, 1, h, 0, 0, "i2cOpen");
e = i2cWriteDevice(h, "\x00", 1); /* move to known register */
CHECK(11, 2, e, 0, 0, "i2cWriteDevice");
b = i2cReadDevice(h, buf, 1);
CHECK(11, 3, b, 1, 0, "i2cReadDevice");
CHECK(11, 4, buf[0], 0xE5, 0, "i2cReadDevice");
b = i2cReadByte(h);
CHECK(11, 5, b, 0xE5, 0, "i2cReadByte");
b = i2cReadByteData(h, 0);
CHECK(11, 6, b, 0xE5, 0, "i2cReadByteData");
b = i2cReadByteData(h, 48);
CHECK(11, 7, b, 2, 0, "i2cReadByteData");
exp = "\x1D[aBcDeFgHjKM]";
len = strlen(exp);
e = i2cWriteDevice(h, exp, len);
CHECK(11, 8, e, 0, 0, "i2cWriteDevice");
e = i2cWriteDevice(h, "\x1D", 1);
b = i2cReadDevice(h, buf, len-1);
CHECK(11, 9, b, len-1, 0, "i2cReadDevice");
CHECK(11, 10, strncmp(buf, exp+1, len-1), 0, 0, "i2cReadDevice");
if (strncmp(buf, exp+1, len-1))
printf("got [%.*s] expected [%.*s]\n", len-1, buf, len-1, exp+1);
e = i2cWriteByteData(h, 0x1d, 0xAA);
CHECK(11, 11, e, 0, 0, "i2cWriteByteData");
b = i2cReadByteData(h, 0x1d);
CHECK(11, 12, b, 0xAA, 0, "i2cReadByteData");
e = i2cWriteByteData(h, 0x1d, 0x55);
CHECK(11, 13, e, 0, 0, "i2cWriteByteData");
b = i2cReadByteData(h, 0x1d);
CHECK(11, 14, b, 0x55, 0, "i2cReadByteData");
exp = "[1234567890#]";
len = strlen(exp);
e = i2cWriteBlockData(h, 0x1C, exp, len);
CHECK(11, 15, e, 0, 0, "i2c writeBlockData");
e = i2cWriteDevice(h, "\x1D", 1);
b = i2cReadDevice(h, buf, len);
CHECK(11, 16, b, len, 0, "i2cReadDevice");
CHECK(11, 17, strncmp(buf, exp, len), 0, 0, "i2cReadDevice");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
b = i2cReadI2CBlockData(h, 0x1D, buf, len);
CHECK(11, 18, b, len, 0, "i2cReadI2CBlockData");
CHECK(11, 19, strncmp(buf, exp, len), 0, 0, "i2cReadI2CBlockData");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
exp = "(-+=;:,<>!%)";
len = strlen(exp);
e = i2cWriteI2CBlockData(h, 0x1D, exp, len);
CHECK(11, 20, e, 0, 0, "i2cWriteI2CBlockData");
b = i2cReadI2CBlockData(h, 0x1D, buf, len);
CHECK(11, 21, b, len, 0, "i2cReadI2CBlockData");
CHECK(11, 22, strncmp(buf, exp, len), 0, 0, "i2cReadI2CBlockData");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
e = i2cClose(h);
CHECK(11, 23, e, 0, 0, "i2cClose");
}
void tc()
{
int h, x, b, e;
char txBuf[8], rxBuf[8];
printf("SPI tests.");
/* this test requires a MCP3202 on SPI channel 1 */
h = spiOpen(1, 50000, 0);
CHECK(12, 1, h, 0, 0, "spiOpen");
sprintf(txBuf, "\x01\x80");
for (x=0; x<5; x++)
{
b = spiXfer(h, txBuf, rxBuf, 3);
CHECK(12, 2, b, 3, 0, "spiXfer");
if (b == 3)
{
time_sleep(1.0);
printf("%d ", ((rxBuf[1]&0x0F)*256)|rxBuf[2]);
}
}
e = spiClose(h);
CHECK(12, 99, e, 0, 0, "spiClose");
}
int main(int argc, char *argv[])
{
int t, status;
void (*test[])(void) = {t0, t1, t2, t3, t4, t5, t6, t7, t8, t9};
int i, t, c, status;
char test[64];
if (argc > 1)
{
t = 0;
for (i=0; i<strlen(argv[1]); i++)
{
c = tolower(argv[1][i]);
if (!strchr(test, c))
{
test[t++] = c;
test[t] = 0;
}
}
}
else strcat(test, "0123456789");
status = gpioInitialise();
@ -636,7 +841,19 @@ int main(int argc, char *argv[])
return 1;
}
for (t=0; t<10; t++) test[t]();
if (strchr(test, '0')) t0();
if (strchr(test, '1')) t1();
if (strchr(test, '2')) t2();
if (strchr(test, '3')) t3();
if (strchr(test, '4')) t4();
if (strchr(test, '5')) t5();
if (strchr(test, '6')) t6();
if (strchr(test, '7')) t7();
if (strchr(test, '8')) t8();
if (strchr(test, '9')) t9();
if (strchr(test, 'a')) ta();
if (strchr(test, 'b')) tb();
if (strchr(test, 'c')) tc();
gpioTerminate();

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#*** WARNING ************************************************
#* *
@ -7,13 +7,22 @@
#* gpio 4 before running any of the tests. *
#************************************************************
import sys
import time
import codecs
import struct
import pigpio
GPIO=4
def STRCMP(r, s):
if r != codecs.latin_1_encode(s)[0]:
print(r, codecs.latin_1_encode(s)[0])
return 0
else:
return 1
def CHECK(t, st, got, expect, pc, desc):
if got >= (((1E2-pc)*expect)/1E2) and got <= (((1E2+pc)*expect)/1E2):
print("TEST {:2d}.{:<2d} PASS ({}: {:d})".format(t, st, desc, expect))
@ -22,37 +31,38 @@ def CHECK(t, st, got, expect, pc, desc):
format(t, st, got, desc, expect))
def t0():
print("Version.")
print("pigpio version {}.".format(pigpio.get_pigpio_version()))
print("pigpio version {}.".format(pi.get_pigpio_version()))
print("Hardware revision {}.".format(pigpio.get_hardware_revision()))
print("Hardware revision {}.".format(pi.get_hardware_revision()))
def t1():
print("Mode/PUD/read/write tests.")
pigpio.set_mode(GPIO, pigpio.INPUT)
v = pigpio.get_mode(GPIO)
pi.set_mode(GPIO, pigpio.INPUT)
v = pi.get_mode(GPIO)
CHECK(1, 1, v, 0, 0, "set mode, get mode")
pigpio.set_pull_up_down(GPIO, pigpio.PUD_UP)
v = pigpio.read(GPIO)
pi.set_pull_up_down(GPIO, pigpio.PUD_UP)
v = pi.read(GPIO)
CHECK(1, 2, v, 1, 0, "set pull up down, read")
pigpio.set_pull_up_down(GPIO, pigpio.PUD_DOWN)
v = pigpio.read(GPIO)
pi.set_pull_up_down(GPIO, pigpio.PUD_DOWN)
v = pi.read(GPIO)
CHECK(1, 3, v, 0, 0, "set pull up down, read")
pigpio.write(GPIO, pigpio.LOW)
v = pigpio.get_mode(GPIO)
pi.write(GPIO, pigpio.LOW)
v = pi.get_mode(GPIO)
CHECK(1, 4, v, 1, 0, "write, get mode")
v = pigpio.read(GPIO)
v = pi.read(GPIO)
CHECK(1, 5, v, 0, 0, "read")
pigpio.write(GPIO, pigpio.HIGH)
v = pigpio.read(GPIO)
pi.write(GPIO, pigpio.HIGH)
v = pi.read(GPIO)
CHECK(1, 6, v, 1, 0, "write, read")
t2_count=0
@ -62,33 +72,34 @@ def t2cbf(gpio, level, tick):
t2_count += 1
def t2():
global t2_count
print("PWM dutycycle/range/frequency tests.")
pigpio.set_PWM_range(GPIO, 255)
pigpio.set_PWM_frequency(GPIO,0)
f = pigpio.get_PWM_frequency(GPIO)
pi.set_PWM_range(GPIO, 255)
pi.set_PWM_frequency(GPIO,0)
f = pi.get_PWM_frequency(GPIO)
CHECK(2, 1, f, 10, 0, "set PWM range, set/get PWM frequency")
t2cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t2cbf)
t2cb = pi.callback(GPIO, pigpio.EITHER_EDGE, t2cbf)
pigpio.set_PWM_dutycycle(GPIO, 0)
pi.set_PWM_dutycycle(GPIO, 0)
time.sleep(0.5) # allow old notifications to flush
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback")
pigpio.set_PWM_dutycycle(GPIO, 128)
pi.set_PWM_dutycycle(GPIO, 128)
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 3, f, 40, 5, "set PWM dutycycle, callback")
pigpio.set_PWM_frequency(GPIO,100)
f = pigpio.get_PWM_frequency(GPIO)
pi.set_PWM_frequency(GPIO,100)
f = pi.get_PWM_frequency(GPIO)
CHECK(2, 4, f, 100, 0, "set/get PWM frequency")
time.sleep(1)
@ -97,8 +108,8 @@ def t2():
f = t2_count - oc
CHECK(2, 5, f, 400, 1, "callback")
pigpio.set_PWM_frequency(GPIO,1000)
f = pigpio.get_PWM_frequency(GPIO)
pi.set_PWM_frequency(GPIO,1000)
f = pi.get_PWM_frequency(GPIO)
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency")
time.sleep(1)
@ -107,20 +118,20 @@ def t2():
f = t2_count - oc
CHECK(2, 7, f, 4000, 1, "callback")
r = pigpio.get_PWM_range(GPIO)
r = pi.get_PWM_range(GPIO)
CHECK(2, 8, r, 255, 0, "get PWM range")
rr = pigpio.get_PWM_real_range(GPIO)
rr = pi.get_PWM_real_range(GPIO)
CHECK(2, 9, rr, 200, 0, "get PWM real range")
pigpio.set_PWM_range(GPIO, 2000)
r = pigpio.get_PWM_range(GPIO)
pi.set_PWM_range(GPIO, 2000)
r = pi.get_PWM_range(GPIO)
CHECK(2, 10, r, 2000, 0, "set/get PWM range")
rr = pigpio.get_PWM_real_range(GPIO)
rr = pi.get_PWM_real_range(GPIO)
CHECK(2, 11, rr, 200, 0, "get PWM real range")
pigpio.set_PWM_dutycycle(GPIO, 0)
pi.set_PWM_dutycycle(GPIO, 0)
t3_reset=True
t3_count=0
@ -148,6 +159,7 @@ def t3cbf(gpio, level, tick):
t3_tick = tick
def t3():
global t3_reset, t3_count, t3_on, t3_off
pw=[500.0, 1500.0, 2500.0]
@ -155,12 +167,12 @@ def t3():
print("PWM/Servo pulse accuracy tests.")
t3cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t3cbf)
t3cb = pi.callback(GPIO, pigpio.EITHER_EDGE, t3cbf)
t = 0
for x in pw:
t += 1
pigpio.set_servo_pulsewidth(GPIO, x)
pi.set_servo_pulsewidth(GPIO, x)
time.sleep(1)
t3_reset = True
time.sleep(4)
@ -170,18 +182,18 @@ def t3():
CHECK(3, t, int((1E3*(on+off))/on), int(2E7/x), 1, "set servo pulsewidth")
pigpio.set_servo_pulsewidth(GPIO, 0)
pigpio.set_PWM_frequency(GPIO, 1000)
f = pigpio.get_PWM_frequency(GPIO)
pi.set_servo_pulsewidth(GPIO, 0)
pi.set_PWM_frequency(GPIO, 1000)
f = pi.get_PWM_frequency(GPIO)
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency")
rr = pigpio.set_PWM_range(GPIO, 100)
rr = pi.set_PWM_range(GPIO, 100)
CHECK(3, 5, rr, 200, 0, "set PWM range")
t = 5
for x in dc:
t += 1
pigpio.set_PWM_dutycycle(GPIO, x*100)
pi.set_PWM_dutycycle(GPIO, x*100)
time.sleep(1)
t3_reset = True
time.sleep(2)
@ -190,34 +202,39 @@ def t3():
off = t3_off
CHECK(3, t, int((1E3*on)/(on+off)), int(1E3*x), 1, "set PWM dutycycle")
pigpio.set_PWM_dutycycle(GPIO, 0)
pi.set_PWM_dutycycle(GPIO, 0)
def t4():
print("Pipe notification tests.")
pigpio.set_PWM_frequency(GPIO, 0)
pigpio.set_PWM_dutycycle(GPIO, 0)
pigpio.set_PWM_range(GPIO, 100)
pi.set_PWM_frequency(GPIO, 0)
pi.set_PWM_dutycycle(GPIO, 0)
pi.set_PWM_range(GPIO, 100)
h = pigpio.notify_open()
e = pigpio.notify_begin(h, (1<<4))
h = pi.notify_open()
e = pi.notify_begin(h, (1<<4))
CHECK(4, 1, e, 0, 0, "notify open/begin")
time.sleep(1)
with open("/dev/pigpio"+ str(h), "rb") as f:
try:
f = open("/dev/pigpio"+ str(h), "rb")
except IOError:
f = None
pigpio.set_PWM_dutycycle(GPIO, 50)
pi.set_PWM_dutycycle(GPIO, 50)
time.sleep(4)
pigpio.set_PWM_dutycycle(GPIO, 0)
pi.set_PWM_dutycycle(GPIO, 0)
e = pigpio.notify_pause(h)
e = pi.notify_pause(h)
CHECK(4, 2, e, 0, 0, "notify pause")
e = pigpio.notify_close(h)
e = pi.notify_close(h)
CHECK(4, 3, e, 0, 0, "notify close")
if f is not None:
n = 0
s = 0
@ -234,7 +251,6 @@ def t4():
if s != S:
seq_ok = 0
L = v & (1<<4)
if n:
@ -249,19 +265,21 @@ def t4():
s += 1
n += 1
# print(S, fl, t, hex(v))
else:
break
f.close()
CHECK(4, 4, seq_ok, 1, 0, "sequence numbers ok")
CHECK(4, 5, toggle_ok, 1, 0, "gpio toggled ok")
CHECK(4, 6, n, 80, 10, "number of notifications")
else:
CHECK(4, 4, 0, 0, 0, "NOT APPLICABLE")
CHECK(4, 5, 0, 0, 0, "NOT APPLICABLE")
CHECK(4, 6, 0, 0, 0, "NOT APPLICABLE")
t5_count = 0
def t5cbf(gpio, level, tick):
@ -289,13 +307,13 @@ He capers nimbly in a lady's chamber
To the lascivious pleasing of a lute.
"""
print("Waveforms & serial read/write tests.")
print("Waveforms & bit bang serial read/write tests.")
t5cb = pigpio.callback(GPIO, pigpio.FALLING_EDGE, t5cbf)
t5cb = pi.callback(GPIO, pigpio.FALLING_EDGE, t5cbf)
pigpio.set_mode(GPIO, pigpio.OUTPUT)
pi.set_mode(GPIO, pigpio.OUTPUT)
e = pigpio.wave_clear()
e = pi.wave_clear()
CHECK(5, 1, e, 0, 0, "callback, set mode, wave clear")
wf = []
@ -305,10 +323,10 @@ To the lascivious pleasing of a lute.
wf.append(pigpio.pulse(1<<GPIO, 0, 60000))
wf.append(pigpio.pulse(0, 1<<GPIO, 100000))
e = pigpio.wave_add_generic(wf)
e = pi.wave_add_generic(wf)
CHECK(5, 2, e, 4, 0, "pulse, wave add generic")
e = pigpio.wave_tx_repeat()
e = pi.wave_tx_repeat()
CHECK(5, 3, e, 9, 0, "wave tx repeat")
oc = t5_count
@ -316,17 +334,17 @@ To the lascivious pleasing of a lute.
c = t5_count - oc
CHECK(5, 4, c, 50, 1, "callback")
e = pigpio.wave_tx_stop()
e = pi.wave_tx_stop()
CHECK(5, 5, e, 0, 0, "wave tx stop")
e = pigpio.serial_read_open(GPIO, BAUD)
e = pi.bb_serial_read_open(GPIO, BAUD)
CHECK(5, 6, e, 0, 0, "serial read open")
pigpio.wave_clear()
e = pigpio.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
pi.wave_clear()
e = pi.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial")
e = pigpio.wave_tx_start()
e = pi.wave_tx_start()
CHECK(5, 8, e, 6811, 0, "wave tx start")
oc = t5_count
@ -335,52 +353,52 @@ To the lascivious pleasing of a lute.
CHECK(5, 9, c, 0, 0, "callback")
oc = t5_count
while pigpio.wave_tx_busy():
while pi.wave_tx_busy():
time.sleep(0.1)
time.sleep(0.1)
c = t5_count - oc
CHECK(5, 10, c, 1702, 0, "wave tx busy, callback")
c, text = pigpio.serial_read(GPIO)
CHECK(5, 11, TEXT == text, True, 0, "wave tx busy, serial read");
c, text = pi.bb_serial_read(GPIO)
CHECK(5, 11, STRCMP(text, TEXT), True, 0, "wave tx busy, serial read");
e = pigpio.serial_read_close(GPIO)
e = pi.bb_serial_read_close(GPIO)
CHECK(5, 12, e, 0, 0, "serial read close")
c = pigpio.wave_get_micros()
c = pi.wave_get_micros()
CHECK(5, 13, c, 6158704, 0, "wave get micros")
CHECK(5, 14, 0, 0, 0, "NOT APPLICABLE")
c = pigpio.wave_get_max_micros()
c = pi.wave_get_max_micros()
CHECK(5, 15, c, 1800000000, 0, "wave get max micros")
c = pigpio.wave_get_pulses()
c = pi.wave_get_pulses()
CHECK(5, 16, c, 3405, 0, "wave get pulses")
CHECK(5, 17, 0, 0, 0, "NOT APPLICABLE")
c = pigpio.wave_get_max_pulses()
c = pi.wave_get_max_pulses()
CHECK(5, 18, c, 12000, 0, "wave get max pulses")
c = pigpio.wave_get_cbs()
c = pi.wave_get_cbs()
CHECK(5, 19, c, 6810, 0, "wave get cbs")
CHECK(5, 20, 0, 0, 0, "NOT APPLICABLE")
c = pigpio.wave_get_max_cbs()
c = pi.wave_get_max_cbs()
CHECK(5, 21, c, 25016, 0, "wave get max cbs")
e = pigpio.wave_clear()
e = pi.wave_clear()
CHECK(5, 22, e, 0, 0, "wave clear")
e = pigpio.wave_add_generic(wf)
e = pi.wave_add_generic(wf)
CHECK(5, 23, e, 4, 0, "pulse, wave add generic")
w1 = pigpio.wave_create()
w1 = pi.wave_create()
CHECK(5, 24, w1, 0, 0, "wave create")
e = pigpio.wave_send_repeat(w1)
e = pi.wave_send_repeat(w1)
CHECK(5, 25, e, 9, 0, "wave send repeat")
oc = t5_count
@ -388,16 +406,16 @@ To the lascivious pleasing of a lute.
c = t5_count - oc
CHECK(5, 26, c, 50, 1, "callback")
e = pigpio.wave_tx_stop()
e = pi.wave_tx_stop()
CHECK(5, 27, e, 0, 0, "wave tx stop")
e = pigpio.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
e = pi.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
CHECK(5, 28, e, 3405, 0, "wave add serial")
w2 = pigpio.wave_create()
w2 = pi.wave_create()
CHECK(5, 29, w2, 1, 0, "wave create")
e = pigpio.wave_send_once(w2)
e = pi.wave_send_once(w2)
CHECK(5, 30, e, 6811, 0, "wave send once")
oc = t5_count
@ -406,13 +424,13 @@ To the lascivious pleasing of a lute.
CHECK(5, 31, c, 0, 0, "callback")
oc = t5_count
while pigpio.wave_tx_busy():
while pi.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)
e = pi.wave_delete(0)
CHECK(5, 33, e, 0, 0, "wave delete")
t6_count=0
@ -433,17 +451,17 @@ def t6():
print("Trigger tests.")
pigpio.write(GPIO, pigpio.LOW)
pi.write(GPIO, pigpio.LOW)
tp = 0
t6cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t6cbf)
t6cb = pi.callback(GPIO, pigpio.EITHER_EDGE, t6cbf)
for t in range(5):
time.sleep(0.1)
p = 10 + (t*10)
tp += p;
pigpio.gpio_trigger(GPIO, p, 1)
pi.gpio_trigger(GPIO, p, 1)
time.sleep(0.5)
@ -464,16 +482,16 @@ def t7():
print("Watchdog tests.")
# type of edge shouldn't matter for watchdogs
t7cb = pigpio.callback(GPIO, pigpio.FALLING_EDGE, t7cbf)
t7cb = pi.callback(GPIO, pigpio.FALLING_EDGE, t7cbf)
pigpio.set_watchdog(GPIO, 10) # 10 ms, 100 per second
pi.set_watchdog(GPIO, 10) # 10 ms, 100 per second
time.sleep(0.5)
oc = t7_count
time.sleep(2)
c = t7_count - oc
CHECK(7, 1, c, 200, 1, "set watchdog on count")
pigpio.set_watchdog(GPIO, 0) # 0 switches watchdog off
pi.set_watchdog(GPIO, 0) # 0 switches watchdog off
time.sleep(0.5)
oc = t7_count
time.sleep(2)
@ -483,49 +501,49 @@ def t7():
def t8():
print("Bank read/write tests.")
pigpio.write(GPIO, 0)
v = pigpio.read_bank_1() & (1<<GPIO)
pi.write(GPIO, 0)
v = pi.read_bank_1() & (1<<GPIO)
CHECK(8, 1, v, 0, 0, "read bank 1")
pigpio.write(GPIO, 1)
v = pigpio.read_bank_1() & (1<<GPIO)
pi.write(GPIO, 1)
v = pi.read_bank_1() & (1<<GPIO)
CHECK(8, 2, v, (1<<GPIO), 0, "read bank 1")
pigpio.clear_bank_1(1<<GPIO)
v = pigpio.read(GPIO)
pi.clear_bank_1(1<<GPIO)
v = pi.read(GPIO)
CHECK(8, 3, v, 0, 0, "clear bank 1")
pigpio.set_bank_1(1<<GPIO)
v = pigpio.read(GPIO)
pi.set_bank_1(1<<GPIO)
v = pi.read(GPIO)
CHECK(8, 4, v, 1, 0, "set bank 1")
t = 0
v = (1<<16)
for i in range(100):
if pigpio.read_bank_2() & v:
if pi.read_bank_2() & v:
t += 1
CHECK(8, 5, t, 60, 75, "read bank 2")
v = pigpio.clear_bank_2(0)
v = pi.clear_bank_2(0)
CHECK(8, 6, v, 0, 0, "clear bank 2")
pigpio.exceptions = False
v = pigpio.clear_bank_2(0xffffff)
v = pi.clear_bank_2(0xffffff)
pigpio.exceptions = True
CHECK(8, 7, v, pigpio.PI_SOME_PERMITTED, 0, "clear bank 2")
v = pigpio.set_bank_2(0)
v = pi.set_bank_2(0)
CHECK(8, 8, v, 0, 0, "set bank 2")
pigpio.exceptions = False
v = pigpio.set_bank_2(0xffffff)
v = pi.set_bank_2(0xffffff)
pigpio.exceptions = True
CHECK(8, 9, v, pigpio.PI_SOME_PERMITTED, 0, "set bank 2")
def t9():
print("Script store/run/status/stop/delete tests.")
pigpio.write(GPIO, 0) # need known state
pi.write(GPIO, 0) # need known state
# 100 loops per second
# p0 number of loops
@ -543,19 +561,19 @@ def t9():
sta p9
jp 0"""
t9cb = pigpio.callback(GPIO)
t9cb = pi.callback(GPIO)
s = pigpio.store_script(script)
s = pi.store_script(script)
oc = t9cb.tally()
pigpio.run_script(s, [99, GPIO])
pi.run_script(s, [99, GPIO])
time.sleep(2)
c = t9cb.tally() - oc
CHECK(9, 1, c, 100, 0, "store/run script")
oc = t9cb.tally()
pigpio.run_script(s, [200, GPIO])
pi.run_script(s, [200, GPIO])
while True:
e, p = pigpio.script_status(s)
e, p = pi.script_status(s)
if e != pigpio.PI_SCRIPT_RUNNING:
break
time.sleep(0.5)
@ -564,28 +582,217 @@ def t9():
CHECK(9, 2, c, 201, 0, "run script/script status")
oc = t9cb.tally()
pigpio.run_script(s, [2000, GPIO])
pi.run_script(s, [2000, GPIO])
while True:
e, p = pigpio.script_status(s)
e, p = pi.script_status(s)
if e != pigpio.PI_SCRIPT_RUNNING:
break
if p[9] < 1900:
pigpio.stop_script(s)
pi.stop_script(s)
time.sleep(0.1)
c = t9cb.tally() - oc
time.sleep(0.1)
CHECK(9, 3, c, 110, 10, "run/stop script/script status")
e = pigpio.delete_script(s)
e = pi.delete_script(s)
CHECK(9, 4, e, 0, 0, "delete script")
if pigpio.start(''): # must run notification test on localhost
def ta():
print("Serial link tests.")
# this test needs RXD and TXD to be connected
h = pi.serial_open("/dev/ttyAMA0", 57600)
CHECK(10, 1, h, 0, 0, "serial open")
(b, s) = pi.serial_read(h, 1000) # flush buffer
b = pi.serial_data_available(h)
CHECK(10, 2, b, 0, 0, "serial data available")
TEXT = """
To be, or not to be, that is the question-
Whether 'tis Nobler in the mind to suffer
The Slings and Arrows of outrageous Fortune,
Or to take Arms against a Sea of troubles,
"""
e = pi.serial_write(h, TEXT)
CHECK(10, 3, e, 0, 0, "serial write")
e = pi.serial_write_byte(h, 0xAA)
e = pi.serial_write_byte(h, 0x55)
e = pi.serial_write_byte(h, 0x00)
e = pi.serial_write_byte(h, 0xFF)
CHECK(10, 4, e, 0, 0, "serial write byte")
time.sleep(0.1) # allow time for transmission
b = pi.serial_data_available(h)
CHECK(10, 5, b, len(TEXT)+4, 0, "serial data available")
(b, text) = pi.serial_read(h, len(TEXT))
CHECK(10, 6, b, len(TEXT), 0, "serial read")
CHECK(10, 7, STRCMP(text, TEXT), True, 0, "serial read")
b = pi.serial_read_byte(h)
CHECK(10, 8, b, 0xAA, 0, "serial read byte")
b = pi.serial_read_byte(h)
CHECK(10, 9, b, 0x55, 0, "serial read byte")
b = pi.serial_read_byte(h)
CHECK(10, 10, b, 0x00, 0, "serial read byte")
b = pi.serial_read_byte(h)
CHECK(10, 11, b, 0xFF, 0, "serial read byte")
b = pi.serial_data_available(h)
CHECK(10, 12, b, 0, 0, "serial data available")
e = pi.serial_close(h)
CHECK(10, 13, e, 0, 0, "serial close")
def tb():
print("SMBus / I2C tests.")
# this test requires an ADXL345 on I2C bus 1 addr 0x53
h = pi.i2c_open(1, 0x53)
CHECK(11, 1, h, 0, 0, "i2c open")
e = pi.i2c_write_device(h, "\x00") # move to known register
CHECK(11, 2, e, 0, 0, "i2c write device")
(b, d) = pi.i2c_read_device(h, 1)
CHECK(11, 3, b, 1, 0, "i2c read device")
CHECK(11, 4, ord(d), 0xE5, 0, "i2c read device")
b = pi.i2c_read_byte(h)
CHECK(11, 5, b, 0xE5, 0, "i2c read byte")
b = pi.i2c_read_byte_data(h, 0)
CHECK(11, 6, b, 0xE5, 0, "i2c read byte data")
b = pi.i2c_read_byte_data(h, 48)
CHECK(11, 7, b, 2, 0, "i2c read byte data")
exp = "[aB\x08cD\xAAgHj\xFD]"
e = pi.i2c_write_device(h, '\x1D' + exp)
CHECK(11, 8, e, 0, 0, "i2c write device")
e = pi.i2c_write_device(h, '\x1D')
(b, d) = pi.i2c_read_device(h, 12)
CHECK(11, 9, b, 12, 0, "i2c read device")
CHECK(11, 10, STRCMP(d, exp), True, 0, "i2c read device")
e = pi.i2c_write_byte_data(h, 0x1d, 0xAA)
CHECK(11, 11, e, 0, 0, "i2c write byte data")
b = pi.i2c_read_byte_data(h, 0x1d)
CHECK(11, 12, b, 0xAA, 0, "i2c read byte data")
e = pi.i2c_write_byte_data(h, 0x1d, 0x55)
CHECK(11, 13, e, 0, 0, "i2c write byte data")
b = pi.i2c_read_byte_data(h, 0x1d)
CHECK(11, 14, b, 0x55, 0, "i2c read byte data")
exps = b"[1234567890#]"
exp = "[1234567890#]"
e = pi.i2c_write_block_data(h, 0x1C, exps)
CHECK(11, 15, e, 0, 0, "i2c write block data")
e = pi.i2c_write_device(h, '\x1D')
(b, d) = pi.i2c_read_device(h, 13)
CHECK(11, 16, b, 13, 0, "i2c read device")
CHECK(11, 17, STRCMP(d, exp), True, 0, "i2c read device")
(b, d) = pi.i2c_read_i2c_block_data(h, 0x1D, 13)
CHECK(11, 18, b, 13, 0, "i2c read i2c block data")
CHECK(11, 19, STRCMP(d, exp), True, 0, "i2c read i2c block data")
expl = [0x01, 0x05, 0x06, 0x07, 0x09, 0x1B, 0x99, 0xAA, 0xBB, 0xCC]
exp = "\x01\x05\x06\x07\x09\x1B\x99\xAA\xBB\xCC"
e = pi.i2c_write_i2c_block_data(h, 0x1D, expl)
CHECK(11, 20, e, 0, 0, "i2c write i2c block data")
(b, d) = pi.i2c_read_i2c_block_data(h, 0x1D, 10)
CHECK(11, 21, b, 10, 0, "i2c read i2c block data")
CHECK(11, 22, STRCMP(d, exp), True, 0, "i2c read i2c block data")
e = pi.i2c_close(h)
CHECK(11, 23, e, 0, 0, "i2c close")
def tca(b, d):
if b == 3:
c1 = d[1] & 0x0F
c2 = d[2]
time.sleep(1.0)
print((c1*256)+c2)
def tc():
print("SPI tests.")
# this test requires a MCP3202 on SPI channel 1
h = pi.spi_open(1, 50000)
CHECK(12, 1, h, 0, 0, "spi open")
(b, d) = pi.spi_xfer(h, [1,128,0])
CHECK(12, 2, b, 3, 0, "spi xfer")
tca(b, d)
(b, d) = pi.spi_xfer(h, "\x01\x80\x00")
CHECK(12, 2, b, 3, 0, "spi xfer")
tca(b, d)
(b, d) = pi.spi_xfer(h, b"\x01\x80\x00")
CHECK(12, 2, b, 3, 0, "spi xfer")
tca(b, d)
(b, d) = pi.spi_xfer(h, '\x01\x80\x00')
CHECK(12, 2, b, 3, 0, "spi xfer")
tca(b, d)
(b, d) = pi.spi_xfer(h, b'\x01\x80\x00')
CHECK(12, 2, b, 3, 0, "spi xfer")
tca(b, d)
e = pi.spi_close(h)
CHECK(12, 99, e, 0, 0, "spi close")
if len(sys.argv) > 1:
tests = ""
for C in sys.argv[1]:
c = C.lower()
if c not in tests:
tests += c
else:
tests = "0123456789"
pi = pigpio.pi()
if pi.connected:
print("Connected to pigpio daemon.")
test = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9]
if '0' in tests: t0()
if '1' in tests: t1()
if '2' in tests: t2()
if '3' in tests: t3()
if '4' in tests: t4()
if '5' in tests: t5()
if '6' in tests: t6()
if '7' in tests: t7()
if '8' in tests: t8()
if '9' in tests: t9()
if 'a' in tests: ta()
if 'b' in tests: tb()
if 'c' in tests: tc()
for t in test:
t();
pigpio.stop()
pi.stop()

View File

@ -16,6 +16,7 @@ sudo ./x_pigpiod_if
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "pigpiod_if.h"
@ -349,7 +350,7 @@ To the lascivious pleasing of a lute.\n\
e = wave_tx_stop();
CHECK(5, 5, e, 0, 0, "wave tx stop");
e = serial_read_open(GPIO, BAUD);
e = bb_serial_read_open(GPIO, BAUD);
CHECK(5, 6, e, 0, 0, "serial read open");
wave_clear();
@ -370,11 +371,11 @@ To the lascivious pleasing of a lute.\n\
c = t5_count - oc;
CHECK(5, 10, c, 1702, 0, "wave tx busy, callback");
c = serial_read(GPIO, text, sizeof(text)-1);
c = bb_serial_read(GPIO, text, sizeof(text)-1);
if (c > 0) text[c] = 0; /* null terminate string */
CHECK(5, 11, strcmp(TEXT, text), 0, 0, "wave tx busy, serial read");
e = serial_read_close(GPIO);
e = bb_serial_read_close(GPIO);
CHECK(5, 12, e, 0, 0, "serial read close");
c = wave_get_micros();
@ -603,10 +604,217 @@ void t9()
CHECK(9, 4, e, 0, 0, "delete script");
}
void ta()
{
int h, b, e;
char *TEXT;
char text[2048];
printf("Serial link tests.\n");
/* this test needs RXD and TXD to be connected */
h = serial_open("/dev/ttyAMA0", 57600, 0);
CHECK(10, 1, h, 0, 0, "serial open");
time_sleep(0.1); /* allow time for transmission */
b = serial_read(h, text, sizeof(text)); /* flush buffer */
b = serial_data_available(h);
CHECK(10, 2, b, 0, 0, "serial data available");
TEXT = "\
To be, or not to be, that is the question-\
Whether 'tis Nobler in the mind to suffer\
The Slings and Arrows of outrageous Fortune,\
Or to take Arms against a Sea of troubles,\
";
e = serial_write(h, TEXT, strlen(TEXT));
CHECK(10, 3, e, 0, 0, "serial write");
e = serial_write_byte(h, 0xAA);
e = serial_write_byte(h, 0x55);
e = serial_write_byte(h, 0x00);
e = serial_write_byte(h, 0xFF);
CHECK(10, 4, e, 0, 0, "serial write byte");
time_sleep(0.1); /* allow time for transmission */
b = serial_data_available(h);
CHECK(10, 5, b, strlen(TEXT)+4, 0, "serial data available");
b = serial_read(h, text, strlen(TEXT));
CHECK(10, 6, b, strlen(TEXT), 0, "serial read");
if (b >= 0) text[b] = 0;
CHECK(10, 7, strcmp(TEXT, text), 0, 0, "serial read");
b = serial_read_byte(h);
CHECK(10, 8, b, 0xAA, 0, "serial read byte");
b = serial_read_byte(h);
CHECK(10, 9, b, 0x55, 0, "serial read byte");
b = serial_read_byte(h);
CHECK(10, 10, b, 0x00, 0, "serial read byte");
b = serial_read_byte(h);
CHECK(10, 11, b, 0xFF, 0, "serial read byte");
b = serial_data_available(h);
CHECK(10, 12, b, 0, 0, "serial data availabe");
e = serial_close(h);
CHECK(10, 13, e, 0, 0, "serial close");
}
void tb()
{
int h, e, b, len;
char *exp;
char buf[128];
printf("SMBus / I2C tests.");
/* this test requires an ADXL345 on I2C bus 1 addr 0x53 */
h = i2c_open(1, 0x53, 0);
CHECK(11, 1, h, 0, 0, "i2c open");
e = i2c_write_device(h, "\x00", 1); /* move to known register */
CHECK(11, 2, e, 0, 0, "i2c write device");
b = i2c_read_device(h, buf, 1);
CHECK(11, 3, b, 1, 0, "i2c read device");
CHECK(11, 4, buf[0], 0xE5, 0, "i2c read device");
b = i2c_read_byte(h);
CHECK(11, 5, b, 0xE5, 0, "i2c read byte");
b = i2c_read_byte_data(h, 0);
CHECK(11, 6, b, 0xE5, 0, "i2c read byte data");
b = i2c_read_byte_data(h, 48);
CHECK(11, 7, b, 2, 0, "i2c read byte data");
exp = "\x1D[aBcDeFgHjKM]";
len = strlen(exp);
e = i2c_write_device(h, exp, len);
CHECK(11, 8, e, 0, 0, "i2c write device");
e = i2c_write_device(h, "\x1D", 1);
b = i2c_read_device(h, buf, len-1);
CHECK(11, 9, b, len-1, 0, "i2c read device");
CHECK(11, 10, strncmp(buf, exp+1, len-1), 0, 0, "i2c read device");
if (strncmp(buf, exp+1, len-1))
printf("got [%.*s] expected [%.*s]\n", len-1, buf, len-1, exp+1);
e = i2c_write_byte_data(h, 0x1d, 0xAA);
CHECK(11, 11, e, 0, 0, "i2c write byte data");
b = i2c_read_byte_data(h, 0x1d);
CHECK(11, 12, b, 0xAA, 0, "i2c read byte data");
e = i2c_write_byte_data(h, 0x1d, 0x55);
CHECK(11, 13, e, 0, 0, "i2c write byte data");
b = i2c_read_byte_data(h, 0x1d);
CHECK(11, 14, b, 0x55, 0, "i2c read byte data");
exp = "[1234567890#]";
len = strlen(exp);
e = i2c_write_block_data(h, 0x1C, exp, len);
CHECK(11, 15, e, 0, 0, "i2c write block data");
e = i2c_write_device(h, "\x1D", 1);
b = i2c_read_device(h, buf, len);
CHECK(11, 16, b, len, 0, "i2c read device");
CHECK(11, 17, strncmp(buf, exp, len), 0, 0, "i2c read device");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
b = i2c_read_i2c_block_data(h, 0x1D, buf, len);
CHECK(11, 18, b, len, 0, "i2c read i2c block data");
CHECK(11, 19, strncmp(buf, exp, len), 0, 0, "i2c read i2c block data");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
exp = "(-+=;:,<>!%)";
len = strlen(exp);
e = i2c_write_i2c_block_data(h, 0x1D, exp, len);
CHECK(11, 20, e, 0, 0, "i2c write i2c block data");
b = i2c_read_i2c_block_data(h, 0x1D, buf, len);
CHECK(11, 21, b, len, 0, "i2c read i2c block data");
CHECK(11, 22, strncmp(buf, exp, len), 0, 0, "i2c read i2c block data");
if (strncmp(buf, exp, len))
printf("got [%.*s] expected [%.*s]\n", len, buf, len, exp);
e = i2c_close(h);
CHECK(11, 23, e, 0, 0, "i2c close");
}
void tc()
{
int h, x, b, e;
char buf[128];
printf("SPI tests.");
/* this test requires a MCP3202 on SPI channel 1 */
h = spi_open(1, 50000, 0);
CHECK(12, 1, h, 0, 0, "spi open");
for (x=0; x<5; x++)
{
sprintf(buf, "\x01\x80");
b = spi_xfer(h, buf, buf, 3);
CHECK(12, 2, b, 3, 0, "spi xfer");
if (b == 3)
{
time_sleep(1.0);
printf("%d ", ((buf[1]&0x0F)*256)|buf[2]);
}
}
e = spi_close(h);
CHECK(12, 99, e, 0, 0, "spi close");
}
int main(int argc, char *argv[])
{
int t, status;
void (*test[])(void) = {t0, t1, t2, t3, t4, t5, t6, t7, t8, t9};
int i, t, c, status;
char test[64];
if (argc > 1)
{
t = 0;
for (i=0; i<strlen(argv[1]); i++)
{
c = tolower(argv[1][i]);
if (!strchr(test, c))
{
test[t++] = c;
test[t] = 0;
}
}
}
else strcat(test, "0123456789");
status = pigpio_start(0, 0);
@ -618,7 +826,19 @@ int main(int argc, char *argv[])
printf("Connected to pigpio daemon.\n");
for (t=0; t<10; t++) test[t]();
if (strchr(test, '0')) t0();
if (strchr(test, '1')) t1();
if (strchr(test, '2')) t2();
if (strchr(test, '3')) t3();
if (strchr(test, '4')) t4();
if (strchr(test, '5')) t5();
if (strchr(test, '6')) t6();
if (strchr(test, '7')) t7();
if (strchr(test, '8')) t8();
if (strchr(test, '9')) t9();
if (strchr(test, 'a')) ta();
if (strchr(test, 'b')) tb();
if (strchr(test, 'c')) tc();
pigpio_stop();

12
x_pigs
View File

@ -40,7 +40,7 @@ s=$(pigs bs2 0)
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h)
if [[ ${#s} = 3315 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
if [[ ${#s} = 4684 ]]; 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
@ -86,7 +86,7 @@ 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 = 14 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
if [[ $s = 16 ]]; 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
@ -168,10 +168,10 @@ s=$(pigs w $GPIO 1)
if [[ $s = "" ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi
s=$(pigs wvclr)
if [[ $s = 0 ]]; then echo "SLR-a ok"; else echo "SLR-a fail ($s)"; fi
if [[ $s = "" ]]; then echo "SLR-a ok"; else echo "SLR-a fail ($s)"; fi
s=$(pigs slro $GPIO 1200)
if [[ $s = 0 ]]; then echo "SLR-b ok"; else echo "SLR-b fail ($s)"; fi
s=$(pigs wvas $GPIO 1200 0 "my name is joan")
s=$(pigs wvas $GPIO 1200 0 0x6d 0x79 0x20 0x6e 0x61 0x6d 0x65 0x20 0x69 0x73 0x20 0x6a 0x6f 0x61 0x6e)
if [[ $s = 95 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi
s=$(pigs m $GPIO w)
if [[ $s = "" ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi
@ -220,8 +220,8 @@ if [[ $s = 0 ]]; then echo "WRITE-d ok"; else echo "WRITE-d fail ($s)"; fi
s=$(pigs wvclr )
if [[ $s = 0 ]]; then echo "WVCLR ok"; else echo "WVCLR fail ($s)"; fi
s=$(pigs wvas $GPIO 300 0 "this is then winter of my discontent made glorious")
if [[ $s = "" ]]; then echo "WVCLR ok"; else echo "WVCLR fail ($s)"; fi
s=$(pigs wvas $GPIO 300 0 0x74 0x68 0x69 0x73 0x20 0x69 0x73 0x20 0x74 0x68 0x65 0x6e 0x20 0x77 0x69 0x6e 0x74 0x65 0x72 0x20 0x6f 0x66 0x20 0x6d 0x79 0x20 0x64 0x69 0x73 0x63 0x6f 0x6e 0x74 0x65 0x6e 0x74 0x20 0x6d 0x61 0x64 0x65 0x20 0x67 0x6c 0x6f 0x72 0x69 0x6f 0x75 0x73)
if [[ $s = 309 ]]; then echo "WVAS ok"; else echo "WVAS fail ($s)"; fi
s=$(pigs wvag 16 0 5000000 0 16 5000000)
if [[ $s = 310 ]]; then echo "WVAG ok"; else echo "WVAG fail ($s)"; fi

10
x_pipe
View File

@ -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/pigout
if [[ $s = "BC1 v Clear gpios specified by mask v in bank 1." ]]
if [[ $s = "BC1 bits Clear specified gpios in bank 1." ]]
then echo "HELP-a ok"
else echo "HELP-a fail ($s)"
fi
read -t 1 -N 9000 </dev/pigout # dump rest of help
echo "help" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = "BC1 v Clear gpios specified by mask v in bank 1." ]]
if [[ $s = "BC1 bits Clear specified gpios in bank 1." ]]
then echo "HELP-b ok"
else echo "HELP-b fail ($s)"
fi
@ -119,7 +119,7 @@ if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
echo "pigpv" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 14 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
if [[ $s = 16 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
echo "prs $GPIO 255" >/dev/pigpio
read -t 1 s </dev/pigout
@ -235,7 +235,7 @@ if [[ $s = 0 ]]; then echo "SLR-a ok"; else echo "SLR-a fail ($s)"; fi
echo "slro $GPIO 1200" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SLR-b ok"; else echo "SLR-b fail ($s)"; fi
echo "wvas $GPIO 1200 0 my name is joan¬" >/dev/pigpio
echo "wvas $GPIO 1200 0 0x6d 0x79 0x20 0x6e 0x61 0x6d 0x65 0x20 0x69 0x73 0x20 0x6a 0x6f 0x61 0x6e 0xc2 0xac" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 105 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi
echo "m $GPIO w" >/dev/pigpio
@ -303,7 +303,7 @@ if [[ $s = 0 ]]; then echo "WRITE-d ok"; else echo "WRITE-d fail ($s)"; fi
echo "wvclr" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "WVCLR ok"; else echo "WVCLR fail ($s)"; fi
echo "wvas $GPIO 300 0 this is the winter of my discontent" >/dev/pigpio
echo "wvas $GPIO 300 0 0x74 0x68 0x69 0x73 0x20 0x69 0x73 0x20 0x74 0x68 0x65 0x20 0x77 0x69 0x6e 0x74 0x65 0x72 0x20 0x6f 0x66 0x20 0x6d 0x79 0x20 0x64 0x69 0x73 0x63 0x6f 0x6e 0x74 0x65 0x6e 0x74" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 215 ]]; then echo "WVAS ok"; else echo "WVAS fail ($s)"; fi
echo "wvag 16 0 5000000 0 16 5000000" >/dev/pigpio