command.c
Go to the documentation of this file.
00001 /*
00002 This is free and unencumbered software released into the public domain.
00003 
00004 Anyone is free to copy, modify, publish, use, compile, sell, or
00005 distribute this software, either in source code form or as a compiled
00006 binary, for any purpose, commercial or non-commercial, and by any
00007 means.
00008 
00009 In jurisdictions that recognize copyright laws, the author or authors
00010 of this software dedicate any and all copyright interest in the
00011 software to the public domain. We make this dedication for the benefit
00012 of the public at large and to the detriment of our heirs and
00013 successors. We intend this dedication to be an overt act of
00014 relinquishment in perpetuity of all present and future rights to this
00015 software under copyright law.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00018 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00019 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
00021 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00022 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00023 OTHER DEALINGS IN THE SOFTWARE.
00024 
00025 For more information, please refer to <http://unlicense.org/>
00026 */
00027 
00028 /*
00029 This version is for pigpio version 67+
00030 */
00031 
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <stdarg.h>
00035 #include <stdlib.h>
00036 #include <ctype.h>
00037 
00038 #include "pigpio.h"
00039 #include "command.h"
00040 
00041 cmdInfo_t cmdInfo[]=
00042 {
00043    /* num          str    vfyt retv */
00044 
00045    {PI_CMD_BC1,   "BC1",   111, 1}, // gpioWrite_Bits_0_31_Clear
00046    {PI_CMD_BC2,   "BC2",   111, 1}, // gpioWrite_Bits_32_53_Clear
00047 
00048    {PI_CMD_BI2CC, "BI2CC", 112, 0}, // bbI2CClose
00049    {PI_CMD_BI2CO, "BI2CO", 131, 0}, // bbI2COpen
00050    {PI_CMD_BI2CZ, "BI2CZ", 193, 6}, // bbI2CZip
00051 
00052    {PI_CMD_BR1,   "BR1",   101, 3}, // gpioRead_Bits_0_31
00053    {PI_CMD_BR2,   "BR2",   101, 3}, // gpioRead_Bits_32_53
00054 
00055    {PI_CMD_BS1,   "BS1",   111, 1}, // gpioWrite_Bits_0_31_Set
00056    {PI_CMD_BS2,   "BS2",   111, 1}, // gpioWrite_Bits_32_53_Set
00057 
00058    {PI_CMD_BSCX,  "BSCX",  193, 8}, // bscXfer
00059 
00060    {PI_CMD_BSPIC, "BSPIC", 112, 0}, // bbSPIClose
00061    {PI_CMD_BSPIO, "BSPIO", 134, 0}, // bbSPIOpen
00062    {PI_CMD_BSPIX, "BSPIX", 193, 6}, // bbSPIXfer
00063 
00064    {PI_CMD_CF1,   "CF1",   195, 2}, // gpioCustom1
00065    {PI_CMD_CF2,   "CF2",   195, 6}, // gpioCustom2
00066 
00067    {PI_CMD_CGI,   "CGI",   101, 4}, // gpioCfgGetInternals
00068    {PI_CMD_CSI,   "CSI",   111, 1}, // gpioCfgSetInternals
00069 
00070    {PI_CMD_EVM,   "EVM",   122, 1}, // eventMonitor
00071    {PI_CMD_EVT,   "EVT",   112, 0}, // eventTrigger
00072 
00073    {PI_CMD_FC,    "FC",    112, 0}, // fileClose
00074 
00075    {PI_CMD_FG,    "FG",    121, 0}, // gpioGlitchFilter
00076 
00077    {PI_CMD_FL,    "FL",    127, 6}, // fileList
00078 
00079    {PI_CMD_FN,    "FN",    131, 0}, // gpioNoiseFilter
00080 
00081    {PI_CMD_FO,    "FO",    127, 2}, // fileOpen
00082    {PI_CMD_FR,    "FR",    121, 6}, // fileRead
00083    {PI_CMD_FS,    "FS",    133, 2}, // fileSeek
00084    {PI_CMD_FW,    "FW",    193, 0}, // fileWrite
00085 
00086    {PI_CMD_GDC,   "GDC",   112, 2}, // gpioGetPWMdutycycle
00087    {PI_CMD_GPW,   "GPW",   112, 2}, // gpioGetServoPulsewidth
00088 
00089    {PI_CMD_HELP,  "H",     101, 5}, // cmdUsage
00090    {PI_CMD_HELP,  "HELP",  101, 5}, // cmdUsage
00091 
00092    {PI_CMD_HC,    "HC",    121, 0}, // gpioHardwareClock
00093    {PI_CMD_HP,    "HP",    131, 0}, // gpioHardwarePWM
00094 
00095    {PI_CMD_HWVER, "HWVER", 101, 4}, // gpioHardwareRevision
00096 
00097    {PI_CMD_I2CC,  "I2CC",  112, 0}, // i2cClose
00098    {PI_CMD_I2CO,  "I2CO",  131, 2}, // i2cOpen
00099 
00100    {PI_CMD_I2CPC, "I2CPC", 131, 2}, // i2cProcessCall
00101    {PI_CMD_I2CPK, "I2CPK", 194, 6}, // i2cBlockProcessCall
00102 
00103    {PI_CMD_I2CRB, "I2CRB", 121, 2}, // i2cReadByteData
00104    {PI_CMD_I2CRD, "I2CRD", 121, 6}, // i2cReadDevice
00105    {PI_CMD_I2CRI, "I2CRI", 131, 6}, // i2cReadI2CBlockData
00106    {PI_CMD_I2CRK, "I2CRK", 121, 6}, // i2cReadBlockData
00107    {PI_CMD_I2CRS, "I2CRS", 112, 2}, // i2cReadByte
00108    {PI_CMD_I2CRW, "I2CRW", 121, 2}, // i2cReadWordData
00109 
00110    {PI_CMD_I2CWB, "I2CWB", 131, 0}, // i2cWriteByteData
00111    {PI_CMD_I2CWD, "I2CWD", 193, 0}, // i2cWriteDevice
00112    {PI_CMD_I2CWI, "I2CWI", 194, 0}, // i2cWriteI2CBlockData
00113    {PI_CMD_I2CWK, "I2CWK", 194, 0}, // i2cWriteBlockData
00114    {PI_CMD_I2CWQ, "I2CWQ", 121, 0}, // i2cWriteQuick
00115    {PI_CMD_I2CWS, "I2CWS", 121, 0}, // i2cWriteByte
00116    {PI_CMD_I2CWW, "I2CWW", 131, 0}, // i2cWriteWordData
00117 
00118    {PI_CMD_I2CZ,  "I2CZ",  193, 6}, // i2cZip
00119 
00120    {PI_CMD_MICS,  "MICS",  112, 0}, // gpioDelay
00121    {PI_CMD_MILS,  "MILS",  112, 0}, // gpioDelay
00122 
00123    {PI_CMD_MODEG, "MG"   , 112, 2}, // gpioGetMode
00124    {PI_CMD_MODEG, "MODEG", 112, 2}, // gpioGetMode
00125 
00126    {PI_CMD_MODES, "M",     125, 0}, // gpioSetMode
00127    {PI_CMD_MODES, "MODES", 125, 0}, // gpioSetMode
00128 
00129    {PI_CMD_NB,    "NB",    122, 0}, // gpioNotifyBegin
00130    {PI_CMD_NC,    "NC",    112, 0}, // gpioNotifyClose
00131    {PI_CMD_NO,    "NO",    101, 2}, // gpioNotifyOpen
00132    {PI_CMD_NP,    "NP",    112, 0}, // gpioNotifyPause
00133 
00134    {PI_CMD_PADG,  "PADG",  112, 2}, // gpioGetPad
00135    {PI_CMD_PADS,  "PADS",  121, 0}, // gpioSetPad
00136 
00137    {PI_CMD_PARSE, "PARSE", 115, 0}, // cmdParseScript
00138 
00139    {PI_CMD_PFG,   "PFG",   112, 2}, // gpioGetPWMfrequency
00140    {PI_CMD_PFS,   "PFS",   121, 2}, // gpioSetPWMfrequency
00141 
00142    {PI_CMD_PIGPV, "PIGPV", 101, 4}, // gpioVersion
00143 
00144    {PI_CMD_PRG,   "PRG",   112, 2}, // gpioGetPWMrange
00145 
00146    {PI_CMD_PROC,  "PROC",  115, 2}, // gpioStoreScript
00147    {PI_CMD_PROCD, "PROCD", 112, 0}, // gpioDeleteScript
00148    {PI_CMD_PROCP, "PROCP", 112, 7}, // gpioScriptStatus
00149    {PI_CMD_PROCR, "PROCR", 191, 0}, // gpioRunScript
00150    {PI_CMD_PROCS, "PROCS", 112, 0}, // gpioStopScript
00151    {PI_CMD_PROCU, "PROCU", 191, 0}, // gpioUpdateScript
00152 
00153    {PI_CMD_PRRG,  "PRRG",  112, 2}, // gpioGetPWMrealRange
00154    {PI_CMD_PRS,   "PRS",   121, 2}, // gpioSetPWMrange
00155 
00156    {PI_CMD_PUD,   "PUD",   126, 0}, // gpioSetPullUpDown
00157 
00158    {PI_CMD_PWM,   "P",     121, 0}, // gpioPWM
00159    {PI_CMD_PWM,   "PWM",   121, 0}, // gpioPWM
00160 
00161    {PI_CMD_READ,  "R",     112, 2}, // gpioRead
00162    {PI_CMD_READ,  "READ",  112, 2}, // gpioRead
00163 
00164    {PI_CMD_SERRB, "SERRB", 112, 2}, // serReadByte
00165    {PI_CMD_SERWB, "SERWB", 121, 0}, // serWriteByte
00166    {PI_CMD_SERC,  "SERC",  112, 0}, // serClose
00167    {PI_CMD_SERDA, "SERDA", 112, 2}, // serDataAvailable
00168    {PI_CMD_SERO,  "SERO",  132, 2}, // serOpen
00169    {PI_CMD_SERR,  "SERR",  121, 6}, // serRead
00170    {PI_CMD_SERW,  "SERW",  193, 0}, // serWrite
00171 
00172    {PI_CMD_SERVO, "S",     121, 0}, // gpioServo
00173    {PI_CMD_SERVO, "SERVO", 121, 0}, // gpioServo
00174 
00175    {PI_CMD_SHELL, "SHELL", 128, 2}, // shell
00176 
00177    {PI_CMD_SLR,   "SLR",   121, 6}, // gpioSerialRead
00178    {PI_CMD_SLRC,  "SLRC",  112, 0}, // gpioSerialReadClose
00179    {PI_CMD_SLRO,  "SLRO",  131, 0}, // gpioSerialReadOpen
00180    {PI_CMD_SLRI,  "SLRI",  121, 0}, // gpioSerialReadInvert
00181 
00182    {PI_CMD_SPIC,  "SPIC",  112, 0}, // spiClose
00183    {PI_CMD_SPIO,  "SPIO",  131, 2}, // spiOpen
00184    {PI_CMD_SPIR,  "SPIR",  121, 6}, // spiRead
00185    {PI_CMD_SPIW,  "SPIW",  193, 0}, // spiWrite
00186    {PI_CMD_SPIX,  "SPIX",  193, 6}, // spiXfer
00187 
00188    {PI_CMD_TICK,  "T",     101, 4}, // gpioTick
00189    {PI_CMD_TICK,  "TICK",  101, 4}, // gpioTick
00190 
00191    {PI_CMD_TRIG,  "TRIG",  131, 0}, // gpioTrigger
00192 
00193    {PI_CMD_WDOG,  "WDOG",  121, 0}, // gpioSetWatchdog
00194 
00195    {PI_CMD_WRITE, "W",     121, 0}, // gpioWrite
00196    {PI_CMD_WRITE, "WRITE", 121, 0}, // gpioWrite
00197 
00198    {PI_CMD_WVAG,  "WVAG",  192, 2}, // gpioWaveAddGeneric
00199    {PI_CMD_WVAS,  "WVAS",  196, 2}, // gpioWaveAddSerial
00200    {PI_CMD_WVTAT, "WVTAT", 101, 2}, // gpioWaveTxAt
00201    {PI_CMD_WVBSY, "WVBSY", 101, 2}, // gpioWaveTxBusy
00202    {PI_CMD_WVCHA, "WVCHA", 197, 0}, // gpioWaveChain
00203    {PI_CMD_WVCLR, "WVCLR", 101, 0}, // gpioWaveClear
00204    {PI_CMD_WVCRE, "WVCRE", 101, 2}, // gpioWaveCreate
00205    {PI_CMD_WVDEL, "WVDEL", 112, 0}, // gpioWaveDelete
00206    {PI_CMD_WVGO,  "WVGO" , 101, 2}, // gpioWaveTxStart
00207    {PI_CMD_WVGOR, "WVGOR", 101, 2}, // gpioWaveTxStart
00208    {PI_CMD_WVHLT, "WVHLT", 101, 0}, // gpioWaveTxStop
00209    {PI_CMD_WVNEW, "WVNEW", 101, 0}, // gpioWaveAddNew
00210    {PI_CMD_WVSC,  "WVSC",  112, 2}, // gpioWaveGet*Cbs
00211    {PI_CMD_WVSM,  "WVSM",  112, 2}, // gpioWaveGet*Micros
00212    {PI_CMD_WVSP,  "WVSP",  112, 2}, // gpioWaveGet*Pulses
00213    {PI_CMD_WVTX,  "WVTX",  112, 2}, // gpioWaveTxSend
00214    {PI_CMD_WVTXM, "WVTXM", 121, 2}, // gpioWaveTxSend
00215    {PI_CMD_WVTXR, "WVTXR", 112, 2}, // gpioWaveTxSend
00216 
00217    {PI_CMD_ADD  , "ADD"  , 111, 0},
00218    {PI_CMD_AND  , "AND"  , 111, 0},
00219    {PI_CMD_CALL , "CALL" , 114, 0},
00220    {PI_CMD_CMDR  ,"CMDR" , 111, 0},
00221    {PI_CMD_CMDW , "CMDW" , 111, 0},
00222    {PI_CMD_CMP  , "CMP"  , 111, 0},
00223    {PI_CMD_DCR  , "DCR"  , 113, 0},
00224    {PI_CMD_DCRA , "DCRA" , 101, 0},
00225    {PI_CMD_DIV  , "DIV"  , 111, 0},
00226    {PI_CMD_EVTWT, "EVTWT", 111, 0},
00227    {PI_CMD_HALT , "HALT" , 101, 0},
00228    {PI_CMD_INR  , "INR"  , 113, 0},
00229    {PI_CMD_INRA , "INRA" , 101, 0},
00230    {PI_CMD_JM   , "JM"   , 114, 0},
00231    {PI_CMD_JMP  , "JMP"  , 114, 0},
00232    {PI_CMD_JNZ  , "JNZ"  , 114, 0},
00233    {PI_CMD_JP   , "JP"   , 114, 0},
00234    {PI_CMD_JZ   , "JZ"   , 114, 0},
00235    {PI_CMD_LD   , "LD"   , 123, 0},
00236    {PI_CMD_LDA  , "LDA"  , 111, 0},
00237    {PI_CMD_LDAB , "LDAB" , 111, 0},
00238    {PI_CMD_MLT  , "MLT"  , 111, 0},
00239    {PI_CMD_MOD  , "MOD"  , 111, 0},
00240    {PI_CMD_NOP  , "NOP"  , 101, 0},
00241    {PI_CMD_OR   , "OR"   , 111, 0},
00242    {PI_CMD_POP  , "POP"  , 113, 0},
00243    {PI_CMD_POPA , "POPA" , 101, 0},
00244    {PI_CMD_PUSH , "PUSH" , 113, 0},
00245    {PI_CMD_PUSHA, "PUSHA", 101, 0},
00246    {PI_CMD_RET  , "RET"  , 101, 0},
00247    {PI_CMD_RL   , "RL"   , 123, 0},
00248    {PI_CMD_RLA  , "RLA"  , 111, 0},
00249    {PI_CMD_RR   , "RR"   , 123, 0},
00250    {PI_CMD_RRA  , "RRA"  , 111, 0},
00251    {PI_CMD_STA  , "STA"  , 113, 0},
00252    {PI_CMD_STAB , "STAB" , 111, 0},
00253    {PI_CMD_SUB  , "SUB"  , 111, 0},
00254    {PI_CMD_SYS  , "SYS"  , 116, 0},
00255    {PI_CMD_TAG  , "TAG"  , 114, 0},
00256    {PI_CMD_WAIT , "WAIT" , 111, 0},
00257    {PI_CMD_X    , "X"    , 124, 0},
00258    {PI_CMD_XA   , "XA"   , 113, 0},
00259    {PI_CMD_XOR  , "XOR"  , 111, 0},
00260 
00261 };
00262 
00263 
00264 char * cmdUsage = "\n\
00265 BC1 bits         Clear GPIO in bank 1\n\
00266 BC2 bits         Clear GPIO in bank 2\n\
00267 BI2CC sda        Close bit bang I2C\n\
00268 BI2CO sda scl baud | Open bit bang I2C\n\
00269 BI2CZ sda ...    I2C bit bang multiple transactions\n\
00270 \n\
00271 BSPIC cs        Close bit bang SPI\n\
00272 BSPIO cs miso mosi sclk baud flag | Open bit bang SPI\n\
00273 BSPIX cs ...    SPI bit bang transfer\n\
00274 \n\
00275 BR1              Read bank 1 GPIO\n\
00276 BR2              Read bank 2 GPIO\n\
00277 \n\
00278 BS1 bits         Set GPIO in bank 1\n\
00279 BS2 bits         Set GPIO in bank 2\n\
00280 \n\
00281 BSCX bctl bvs    BSC I2C/SPI transfer\n\
00282 \n\
00283 CF1 ...          Custom function 1\n\
00284 CF2 ...          Custom function 2\n\
00285 \n\
00286 CGI              Configuration get internals\n\
00287 CSI v            Configuration set internals\n\
00288 \n\
00289 EVM h bits       Set events to monitor\n\
00290 EVT n            Trigger event\n\
00291 \n\
00292 FC h             Close file handle\n\
00293 FG g steady      Set glitch filter on GPIO\n\
00294 FL pat n         List files which match pattern\n\
00295 FN g steady active | Set noise filter on GPIO\n\
00296 FO file mode     Open a file in mode\n\
00297 FR h n           Read bytes from file handle\n\
00298 FS h n from      Seek to file handle position\n\
00299 FW h ...         Write bytes to file handle\n\
00300 \n\
00301 GDC g            Get PWM dutycycle for GPIO\n\
00302 GPW g            Get servo pulsewidth for GPIO\n\
00303 \n\
00304 H/HELP           Display command help\n\
00305 HC g f           Set hardware clock frequency\n\
00306 HP g f dc        Set hardware PWM frequency and dutycycle\n\
00307 HWVER            Get hardware version\n\
00308 \n\
00309 I2CC h           Close I2C handle\n\
00310 I2CO bus device flags | Open I2C bus and device with flags\n\
00311 I2CPC h r word   SMBus Process Call: exchange register with word\n\
00312 I2CPK h r ...    SMBus Block Process Call: exchange data bytes with register\n\
00313 I2CRB h r        SMBus Read Byte Data: read byte from register\n\
00314 I2CRD h n        I2C Read bytes\n\
00315 I2CRI h r n      SMBus Read I2C Block Data: read bytes from register\n\
00316 I2CRK h r        SMBus Read Block Data: read data from register\n\
00317 I2CRS h          SMBus Read Byte: read byte\n\
00318 I2CRW h r        SMBus Read Word Data: read word from register\n\
00319 I2CWB h r byte   SMBus Write Byte Data: write byte to register\n\
00320 I2CWD h ...      I2C Write data\n\
00321 I2CWI h r ...    SMBus Write I2C Block Data\n\
00322 I2CWK h r ...    SMBus Write Block Data: write data to register\n\
00323 I2CWQ h b        SMBus Write Quick: write bit\n\
00324 I2CWS h b        SMBus Write Byte: write byte\n\
00325 I2CWW h r word   SMBus Write Word Data: write word to register\n\
00326 I2CZ  h ...      I2C multiple transactions\n\
00327 \n\
00328 M/MODES g mode   Set GPIO mode\n\
00329 MG/MODEG g       Get GPIO mode\n\
00330 MICS n           Delay for microseconds\n\
00331 MILS n           Delay for milliseconds\n\
00332 \n\
00333 NB h bits        Start notification\n\
00334 NC h             Close notification\n\
00335 NO               Request a notification\n\
00336 NP h             Pause notification\n\
00337 \n\
00338 P/PWM g v        Set GPIO PWM value\n\
00339 PADG pad         Get pad drive strength\n\
00340 PADS pad v       Set pad drive strength\n\
00341 PARSE text       Validate script\n\
00342 PFG g            Get GPIO PWM frequency\n\
00343 PFS g v          Set GPIO PWM frequency\n\
00344 PIGPV            Get pigpio library version\n\
00345 PRG g            Get GPIO PWM range\n\
00346 PROC text        Store script\n\
00347 PROCD sid        Delete script\n\
00348 PROCP sid        Get script status and parameters\n\
00349 PROCR sid ...    Run script\n\
00350 PROCS sid        Stop script\n\
00351 PROCU sid ...    Set script parameters\n\
00352 PRRG g           Get GPIO PWM real range\n\
00353 PRS g v          Set GPIO PWM range\n\
00354 PUD g pud        Set GPIO pull up/down\n\
00355 \n\
00356 R/READ g         Read GPIO level\n\
00357 \n\
00358 S/SERVO g v      Set GPIO servo pulsewidth\n\
00359 SERC h           Close serial handle\n\
00360 SERDA h          Check for serial data ready to read\n\
00361 SERO text baud flags | Open serial device at baud with flags\n\
00362 SERR h n         Read bytes from serial handle\n\
00363 SERRB h          Read byte from serial handle\n\
00364 SERW h ...       Write bytes to serial handle\n\
00365 SERWB h byte     Write byte to serial handle\n\
00366 SHELL name str   Execute a shell command\n\
00367 SLR g v          Read bit bang serial data from GPIO\n\
00368 SLRC g           Close GPIO for bit bang serial data\n\
00369 SLRO g baud bitlen | Open GPIO for bit bang serial data\n\
00370 SLRI g invert    Invert serial logic (1 invert, 0 normal)\n\
00371 SPIC h           SPI close handle\n\
00372 SPIO channel baud flags | SPI open channel at baud with flags\n\
00373 SPIR h v         SPI read bytes from handle\n\
00374 SPIW h ...       SPI write bytes to handle\n\
00375 SPIX h ...       SPI transfer bytes to handle\n\
00376 \n\
00377 T/TICK           Get current tick\n\
00378 TRIG g micros l  Trigger level for micros on GPIO\n\
00379 \n\
00380 W/WRITE g l      Write level to GPIO\n\
00381 WDOG g millis    Set millisecond watchdog on GPIO\n\
00382 WVAG triplets    Wave add generic pulses\n\
00383 WVAS g baud bitlen stopbits offset ... | Wave add serial data\n\
00384 WVBSY            Check if wave busy\n\
00385 WVCHA            Transmit a chain of waves\n\
00386 WVCLR            Wave clear\n\
00387 WVCRE            Create wave from added pulses\n\
00388 WVDEL wid        Delete waves w and higher\n\
00389 WVGO             Wave transmit (DEPRECATED)\n\
00390 WVGOR            Wave transmit repeatedly (DEPRECATED)\n\
00391 WVHLT            Wave stop\n\
00392 WVNEW            Start a new empty wave\n\
00393 WVSC 0,1,2       Wave get DMA control block stats\n\
00394 WVSM 0,1,2       Wave get micros stats\n\
00395 WVSP 0,1,2       Wave get pulses stats\n\
00396 WVTAT            Returns the current transmitting wave\n\
00397 WVTX wid         Transmit wave as one-shot\n\
00398 WVTXM wid wmde   Transmit wave using mode\n\
00399 WVTXR wid        Transmit wave repeatedly\n\
00400 \n\
00401 Numbers may be entered as hex (prefix 0x), octal (prefix 0),\n\
00402 otherwise they are assumed to be decimal.\n\
00403 \n\
00404 Examples\n\
00405 \n\
00406 pigs w 4 1         # set GPIO 4 high\n\
00407 pigs r 5           # read GPIO 5\n\
00408 pigs t             # get current tick\n\
00409 pigs i2co 1 0x20 0 # get handle to device 0x20 on I2C bus 1\n\
00410 \n\
00411 man pigs for full details.\n\
00412 \n";
00413 
00414 typedef struct
00415 {
00416    int error;
00417    char * str;
00418 } errInfo_t;
00419 
00420 static errInfo_t errInfo[]=
00421 {
00422    {PI_INIT_FAILED      , "pigpio initialisation failed"},
00423    {PI_BAD_USER_GPIO    , "GPIO not 0-31"},
00424    {PI_BAD_GPIO         , "GPIO not 0-53"},
00425    {PI_BAD_MODE         , "mode not 0-7"},
00426    {PI_BAD_LEVEL        , "level not 0-1"},
00427    {PI_BAD_PUD          , "pud not 0-2"},
00428    {PI_BAD_PULSEWIDTH   , "pulsewidth not 0 or 500-2500"},
00429    {PI_BAD_DUTYCYCLE    , "dutycycle not 0-range (default 255)"},
00430    {PI_BAD_TIMER        , "timer not 0-9"},
00431    {PI_BAD_MS           , "ms not 10-60000"},
00432    {PI_BAD_TIMETYPE     , "timetype not 0-1"},
00433    {PI_BAD_SECONDS      , "seconds < 0"},
00434    {PI_BAD_MICROS       , "micros not 0-999999"},
00435    {PI_TIMER_FAILED     , "gpioSetTimerFunc failed"},
00436    {PI_BAD_WDOG_TIMEOUT , "timeout not 0-60000"},
00437    {PI_NO_ALERT_FUNC    , "DEPRECATED"},
00438    {PI_BAD_CLK_PERIPH   , "clock peripheral not 0-1"},
00439    {PI_BAD_CLK_SOURCE   , "DEPRECATED"},
00440    {PI_BAD_CLK_MICROS   , "clock micros not 1, 2, 4, 5, 8, or 10"},
00441    {PI_BAD_BUF_MILLIS   , "buf millis not 100-10000"},
00442    {PI_BAD_DUTYRANGE    , "dutycycle range not 25-40000"},
00443    {PI_BAD_SIGNUM       , "signum not 0-63"},
00444    {PI_BAD_PATHNAME     , "can't open pathname"},
00445    {PI_NO_HANDLE        , "no handle available"},
00446    {PI_BAD_HANDLE       , "unknown handle"},
00447    {PI_BAD_IF_FLAGS     , "ifFlags > 4"},
00448    {PI_BAD_CHANNEL      , "DMA channel not 0-14"},
00449    {PI_BAD_SOCKET_PORT  , "socket port not 1024-30000"},
00450    {PI_BAD_FIFO_COMMAND , "unknown fifo command"},
00451    {PI_BAD_SECO_CHANNEL , "DMA secondary channel not 0-14"},
00452    {PI_NOT_INITIALISED  , "function called before gpioInitialise"},
00453    {PI_INITIALISED      , "function called after gpioInitialise"},
00454    {PI_BAD_WAVE_MODE    , "waveform mode not 0-1"},
00455    {PI_BAD_CFG_INTERNAL , "bad parameter in gpioCfgInternals call"},
00456    {PI_BAD_WAVE_BAUD    , "baud rate not 50-250K(RX)/50-1M(TX)"},
00457    {PI_TOO_MANY_PULSES  , "waveform has too many pulses"},
00458    {PI_TOO_MANY_CHARS   , "waveform has too many chars"},
00459    {PI_NOT_SERIAL_GPIO  , "no bit bang serial read in progress on GPIO"},
00460    {PI_BAD_SERIAL_STRUC , "bad (null) serial structure parameter"},
00461    {PI_BAD_SERIAL_BUF   , "bad (null) serial buf parameter"}, 
00462    {PI_NOT_PERMITTED    , "no permission to update GPIO"},
00463    {PI_SOME_PERMITTED   , "no permission to update one or more GPIO"},
00464    {PI_BAD_WVSC_COMMND  , "bad WVSC subcommand"},
00465    {PI_BAD_WVSM_COMMND  , "bad WVSM subcommand"},
00466    {PI_BAD_WVSP_COMMND  , "bad WVSP subcommand"},
00467    {PI_BAD_PULSELEN     , "trigger pulse length not 1-100"},
00468    {PI_BAD_SCRIPT       , "invalid script"},
00469    {PI_BAD_SCRIPT_ID    , "unknown script id"},
00470    {PI_BAD_SER_OFFSET   , "add serial data offset > 30 minute"},
00471    {PI_GPIO_IN_USE      , "GPIO already in use"},
00472    {PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"},
00473    {PI_BAD_PARAM_NUM    , "script parameter id not 0-9"},
00474    {PI_DUP_TAG          , "script has duplicate tag"},
00475    {PI_TOO_MANY_TAGS    , "script has too many tags"},
00476    {PI_BAD_SCRIPT_CMD   , "illegal script command"},
00477    {PI_BAD_VAR_NUM      , "script variable id not 0-149"},
00478    {PI_NO_SCRIPT_ROOM   , "no more room for scripts"},
00479    {PI_NO_MEMORY        , "can't allocate temporary memory"},
00480    {PI_SOCK_READ_FAILED , "socket read failed"},
00481    {PI_SOCK_WRIT_FAILED , "socket write failed"},
00482    {PI_TOO_MANY_PARAM   , "too many script parameters (> 10)"},
00483    {PI_SCRIPT_NOT_READY , "script initialising"},
00484    {PI_BAD_TAG          , "script has unresolved tag"},
00485    {PI_BAD_MICS_DELAY   , "bad MICS delay (too large)"},
00486    {PI_BAD_MILS_DELAY   , "bad MILS delay (too large)"},
00487    {PI_BAD_WAVE_ID      , "non existent wave id"},
00488    {PI_TOO_MANY_CBS     , "No more CBs for waveform"},
00489    {PI_TOO_MANY_OOL     , "No more OOL for waveform"},
00490    {PI_EMPTY_WAVEFORM   , "attempt to create an empty waveform"},
00491    {PI_NO_WAVEFORM_ID   , "no more waveform ids"},
00492    {PI_I2C_OPEN_FAILED  , "can't open I2C device"},
00493    {PI_SER_OPEN_FAILED  , "can't open serial device"},
00494    {PI_SPI_OPEN_FAILED  , "can't open SPI device"},
00495    {PI_BAD_I2C_BUS      , "bad I2C bus"},
00496    {PI_BAD_I2C_ADDR     , "bad I2C address"},
00497    {PI_BAD_SPI_CHANNEL  , "bad SPI channel"},
00498    {PI_BAD_FLAGS        , "bad i2c/spi/ser open flags"},
00499    {PI_BAD_SPI_SPEED    , "bad SPI speed"},
00500    {PI_BAD_SER_DEVICE   , "bad serial device name"},
00501    {PI_BAD_SER_SPEED    , "bad serial baud rate"},
00502    {PI_BAD_PARAM        , "bad i2c/spi/ser parameter"},
00503    {PI_I2C_WRITE_FAILED , "I2C write failed"},
00504    {PI_I2C_READ_FAILED  , "I2C read failed"},
00505    {PI_BAD_SPI_COUNT    , "bad SPI count"},
00506    {PI_SER_WRITE_FAILED , "ser write failed"},
00507    {PI_SER_READ_FAILED  , "ser read failed"},
00508    {PI_SER_READ_NO_DATA , "ser read no data available"},
00509    {PI_UNKNOWN_COMMAND  , "unknown command"},
00510    {PI_SPI_XFER_FAILED  , "spi xfer/read/write failed"},
00511    {PI_BAD_POINTER      , "bad (NULL) pointer"},
00512    {PI_NO_AUX_SPI       , "no auxiliary SPI on Pi A or B"},
00513    {PI_NOT_PWM_GPIO     , "GPIO is not in use for PWM"},
00514    {PI_NOT_SERVO_GPIO   , "GPIO is not in use for servo pulses"},
00515    {PI_NOT_HCLK_GPIO    , "GPIO has no hardware clock"},
00516    {PI_NOT_HPWM_GPIO    , "GPIO has no hardware PWM"},
00517    {PI_BAD_HPWM_FREQ    , "hardware PWM frequency not 1-125M"},
00518    {PI_BAD_HPWM_DUTY    , "hardware PWM dutycycle not 0-1M"},
00519    {PI_BAD_HCLK_FREQ    , "hardware clock frequency not 4689-250M"},
00520    {PI_BAD_HCLK_PASS    , "need password to use hardware clock 1"},
00521    {PI_HPWM_ILLEGAL     , "illegal, PWM in use for main clock"},
00522    {PI_BAD_DATABITS     , "serial data bits not 1-32"},
00523    {PI_BAD_STOPBITS     , "serial (half) stop bits not 2-8"},
00524    {PI_MSG_TOOBIG       , "socket/pipe message too big"},
00525    {PI_BAD_MALLOC_MODE  , "bad memory allocation mode"},
00526    {PI_TOO_MANY_SEGS    , "too many I2C transaction segments"},
00527    {PI_BAD_I2C_SEG      , "an I2C transaction segment failed"},
00528    {PI_BAD_SMBUS_CMD    , "SMBus command not supported by driver"},
00529    {PI_NOT_I2C_GPIO     , "no bit bang I2C in progress on GPIO"},
00530    {PI_BAD_I2C_WLEN     , "bad I2C write length"},
00531    {PI_BAD_I2C_RLEN     , "bad I2C read length"},
00532    {PI_BAD_I2C_CMD      , "bad I2C command"},
00533    {PI_BAD_I2C_BAUD     , "bad I2C baud rate, not 50-500k"},
00534    {PI_CHAIN_LOOP_CNT   , "bad chain loop count"},
00535    {PI_BAD_CHAIN_LOOP   , "empty chain loop"},
00536    {PI_CHAIN_COUNTER    , "too many chain counters"},
00537    {PI_BAD_CHAIN_CMD    , "bad chain command"},
00538    {PI_BAD_CHAIN_DELAY  , "bad chain delay micros"},
00539    {PI_CHAIN_NESTING    , "chain counters nested too deeply"},
00540    {PI_CHAIN_TOO_BIG    , "chain is too long"},
00541    {PI_DEPRECATED       , "deprecated function removed"},
00542    {PI_BAD_SER_INVERT   , "bit bang serial invert not 0 or 1"},
00543    {PI_BAD_EDGE         , "bad ISR edge, not 1, 1, or 2"},
00544    {PI_BAD_ISR_INIT     , "bad ISR initialisation"},
00545    {PI_BAD_FOREVER      , "loop forever must be last chain command"},
00546    {PI_BAD_FILTER       , "bad filter parameter"},
00547    {PI_BAD_PAD          , "bad pad number"},
00548    {PI_BAD_STRENGTH     , "bad pad drive strength"},
00549    {PI_FIL_OPEN_FAILED  , "file open failed"},
00550    {PI_BAD_FILE_MODE    , "bad file mode"},
00551    {PI_BAD_FILE_FLAG    , "bad file flag"},
00552    {PI_BAD_FILE_READ    , "bad file read"},
00553    {PI_BAD_FILE_WRITE   , "bad file write"},
00554    {PI_FILE_NOT_ROPEN   , "file not open for read"},
00555    {PI_FILE_NOT_WOPEN   , "file not open for write"},
00556    {PI_BAD_FILE_SEEK    , "bad file seek"},
00557    {PI_NO_FILE_MATCH    , "no files match pattern"},
00558    {PI_NO_FILE_ACCESS   , "no permission to access file"},
00559    {PI_FILE_IS_A_DIR    , "file is a directory"},
00560    {PI_BAD_SHELL_STATUS , "bad shell return status"},
00561    {PI_BAD_SCRIPT_NAME  , "bad script name"},
00562    {PI_BAD_SPI_BAUD     , "bad SPI baud rate, not 50-500k"},
00563    {PI_NOT_SPI_GPIO     , "no bit bang SPI in progress on GPIO"},
00564    {PI_BAD_EVENT_ID     , "bad event id"},
00565    {PI_CMD_INTERRUPTED  , "command interrupted, Python"},
00566 
00567 };
00568 
00569 static char * fmtMdeStr="RW540123";
00570 static char * fmtPudStr="ODU";
00571 
00572 static int cmdMatch(char *str)
00573 {
00574    int i;
00575 
00576    for (i=0; i<(sizeof(cmdInfo)/sizeof(cmdInfo_t)); i++)
00577    {
00578       if (strcasecmp(str, cmdInfo[i].name) == 0) return i;
00579    }
00580    return CMD_UNKNOWN_CMD;
00581 }
00582 
00583 static int getNum(char *str, uint32_t *val, int8_t *opt)
00584 {
00585    int f, n;
00586    intmax_t v;
00587 
00588    *opt = 0;
00589 
00590    f = sscanf(str, " %ji %n", &v, &n);
00591 
00592    if (f == 1)
00593    {
00594       *val = v;
00595       *opt = CMD_NUMERIC;
00596       return n;
00597    }
00598 
00599    f = sscanf(str, " v%ji %n", &v, &n);
00600 
00601    if (f == 1)
00602    {
00603       *val = v;
00604       if (v < PI_MAX_SCRIPT_VARS) *opt = CMD_VAR;
00605       else *opt = -CMD_VAR;
00606       return n;
00607    }
00608 
00609    f = sscanf(str, " p%ji %n", &v, &n);
00610 
00611    if (f == 1)
00612    {
00613       *val = v;
00614       if (v < PI_MAX_SCRIPT_PARAMS) *opt = CMD_PAR;
00615       else *opt = -CMD_PAR;
00616       return n;
00617    }
00618 
00619    return 0;
00620 }
00621 
00622 static char intCmdStr[32];
00623 
00624 char *cmdStr(void)
00625 {
00626    return intCmdStr;
00627 }
00628 
00629 int cmdParse(
00630    char *buf, uint32_t *p, unsigned ext_len, char *ext, cmdCtlParse_t *ctl)
00631 {
00632    int f, valid, idx, val, pp, pars, n, n2;
00633    char *p8;
00634    int32_t *p32;
00635    char c;
00636    uint32_t tp1=0, tp2=0, tp3=0, tp4=0, tp5=0;
00637    int8_t to1, to2, to3, to4, to5;
00638    int eaten;
00639 
00640    /* Check that ext is big enough for the largest message. */
00641    if (ext_len < (4 * CMD_MAX_PARAM)) return CMD_EXT_TOO_SMALL;
00642 
00643    bzero(&ctl->opt, sizeof(ctl->opt));
00644 
00645    sscanf(buf+ctl->eaten, " %31s %n", intCmdStr, &pp);
00646 
00647    ctl->eaten += pp;
00648 
00649    p[0] = -1;
00650 
00651    idx = cmdMatch(intCmdStr);
00652 
00653    if (idx < 0) return idx;
00654 
00655    valid = 0;
00656 
00657    p[0] = cmdInfo[idx].cmd;
00658    p[1] = 0;
00659    p[2] = 0;
00660    p[3] = 0;
00661 
00662    switch (cmdInfo[idx].vt)
00663    {
00664       case 101: /* BR1  BR2  CGI  H  HELP  HWVER
00665                    DCRA  HALT  INRA  NO
00666                    PIGPV  POPA  PUSHA  RET  T  TICK  WVBSY  WVCLR
00667                    WVCRE  WVGO  WVGOR  WVHLT  WVNEW
00668 
00669                    No parameters, always valid.
00670                 */
00671          valid = 1;
00672 
00673          break;
00674 
00675       case 111: /* ADD  AND  BC1  BC2  BS1  BS2  
00676                    CMP  CSI  DIV  LDA  LDAB  MLT
00677                    MOD  OR  RLA  RRA  STAB  SUB  WAIT  XOR
00678 
00679                    One parameter, any value.
00680                 */
00681          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00682 
00683          if (ctl->opt[1] > 0) valid = 1;
00684 
00685          break;
00686 
00687       case 112: /* BI2CC FC  GDC  GPW  I2CC  I2CRB
00688                    MG  MICS  MILS  MODEG  NC  NP  PADG PFG  PRG
00689                    PROCD  PROCP  PROCS  PRRG  R  READ  SLRC  SPIC
00690                    WVDEL  WVSC  WVSM  WVSP  WVTX  WVTXR  BSPIC
00691 
00692                    One positive parameter.
00693                 */
00694          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00695 
00696          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0)) valid = 1;
00697 
00698          break;
00699 
00700       case 113: /* DCR  INR  POP  PUSH  STA  XA
00701 
00702                    One register parameter.
00703                 */
00704          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00705 
00706          if ((ctl->opt[1] > 0) && (p[1] < PI_MAX_SCRIPT_VARS)) valid = 1;
00707 
00708          break;
00709 
00710       case 114: /* CALL  JM  JMP  JNZ  JP  JZ  TAG
00711 
00712                    One numeric parameter, any value.
00713                 */
00714          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00715          if (ctl->opt[1] == CMD_NUMERIC) valid = 1;
00716 
00717          break;
00718 
00719       case 115: /* PARSE  PROC
00720 
00721                    One parameter, string (rest of input).
00722                 */
00723          p[3] = strlen(buf+ctl->eaten);
00724          memcpy(ext, buf+ctl->eaten, p[3]);
00725          ctl->eaten += p[3];
00726          valid = 1;
00727 
00728          break;
00729 
00730       case 116: /* SYS
00731 
00732                    One parameter, a string.
00733                 */
00734          f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00735          if ((f >= 0) && n)
00736          {
00737             p[3] = n;
00738             ctl->opt[3] = CMD_NUMERIC;
00739             memcpy(ext, buf+ctl->eaten, n);
00740             ctl->eaten += n2;
00741             valid = 1;
00742          }
00743 
00744          break;
00745 
00746       case 121: /* HC  FR  I2CRD  I2CRR  I2CRW  I2CWB I2CWQ  P
00747                    PADS  PFS  PRS  PWM  S  SERVO  SLR  SLRI  W
00748                    WDOG  WRITE  WVTXM
00749 
00750                    Two positive parameters.
00751                 */
00752          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00753          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00754 
00755          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00756              (ctl->opt[2] > 0) && ((int)p[2] >= 0)) valid = 1;
00757 
00758          break;
00759 
00760       case 122: /* NB
00761 
00762                    Two parameters, first positive, second any value.
00763                 */
00764          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00765          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00766 
00767          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00768              (ctl->opt[2] > 0)) valid = 1;
00769 
00770          break;
00771 
00772       case 123: /* LD  RL  RR
00773 
00774                    Two parameters, first register, second any value.
00775                 */
00776          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00777          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00778 
00779          if ((ctl->opt[1] > 0) &&
00780              (p[1] < PI_MAX_SCRIPT_VARS) &&
00781              (ctl->opt[2] > 0)) valid = 1;
00782 
00783          break;
00784 
00785       case 124: /* X
00786 
00787                    Two register parameters.
00788                 */
00789          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00790          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00791 
00792          if ((ctl->opt[1] > 0) && (p[1] < PI_MAX_SCRIPT_VARS) &&
00793              (ctl->opt[2] > 0) && (p[2] < PI_MAX_SCRIPT_VARS)) valid = 1;
00794 
00795          break;
00796 
00797       case 125: /* M MODES
00798 
00799                    Two parameters, first positive, second in 'RW540123'.
00800                 */
00801          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00802 
00803          f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
00804 
00805          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) && (f >= 1))
00806          {
00807             ctl->eaten += n;
00808             val = toupper(c);
00809             p8 = strchr(fmtMdeStr, val);
00810 
00811             if (p8 != NULL)
00812             {
00813                val = p8 - fmtMdeStr;
00814                p[2] = val;
00815                valid = 1;
00816             }
00817          }
00818 
00819          break;
00820 
00821       case 126: /* PUD
00822 
00823                    Two parameters, first positive, second in 'ODU'.
00824                 */
00825          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00826 
00827          f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
00828 
00829          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0)  && (f >= 1))
00830          {
00831             ctl->eaten += n;
00832             val = toupper(c);
00833             p8 = strchr(fmtPudStr, val);
00834             if (p8 != NULL)
00835             {
00836                val = p8 - fmtPudStr;
00837                p[2] = val;
00838                valid = 1;
00839             }
00840          }
00841 
00842          break;
00843 
00844       case 127: /* FL  FO
00845 
00846                    Two parameters, first a string, other positive.
00847                 */
00848          f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00849          if ((f >= 0) && n)
00850          {
00851             p[3] = n;
00852             ctl->opt[2] = CMD_NUMERIC;
00853             memcpy(ext, buf+ctl->eaten, n);
00854             ctl->eaten += n2;
00855 
00856             ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00857 
00858             if ((ctl->opt[1] > 0) && ((int)p[1] >= 0))
00859                valid = 1;
00860          }
00861 
00862          break;
00863 
00864       case 128: /* SHELL
00865 
00866                    Two string parameters, the first space teminated.
00867                    The second arbitrary.
00868                 */
00869          f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00870 
00871          if ((f >= 0) && n)
00872          {
00873             valid = 1;
00874 
00875             p[1] = n;
00876             memcpy(ext, buf+ctl->eaten, n);
00877             ctl->eaten += n;
00878             ext[n] = 0; /* terminate first string */
00879 
00880             n2 = strlen(buf+ctl->eaten+1);
00881             memcpy(ext+n+1, buf+ctl->eaten+1, n2);
00882             ctl->eaten += n2;
00883             ctl->eaten ++;
00884             p[3] = p[1] + n2 + 1;
00885          }
00886 
00887          break;
00888 
00889       case 131: /* BI2CO  HP  I2CO  I2CPC  I2CRI  I2CWB  I2CWW
00890                    SLRO  SPIO  TRIG
00891 
00892                    Three positive parameters.
00893                 */
00894          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00895          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00896          ctl->eaten += getNum(buf+ctl->eaten, &tp1, &ctl->opt[3]);
00897 
00898          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00899              (ctl->opt[2] > 0) && ((int)p[2] >= 0) &&
00900              (ctl->opt[3] > 0) && ((int)tp1 >= 0))
00901          {
00902             p[3] = 4;
00903             memcpy(ext, &tp1, 4);
00904             valid = 1;
00905          }
00906 
00907          break;
00908 
00909       case 132: /* SERO
00910 
00911                    Three parameters, first a string, rest >=0
00912                 */
00913          f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00914          if ((f >= 0) && n)
00915          {
00916             p[3] = n;
00917             ctl->opt[2] = CMD_NUMERIC;
00918             memcpy(ext, buf+ctl->eaten, n);
00919             ctl->eaten += n2;
00920 
00921             ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00922             ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00923 
00924             if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00925                 (ctl->opt[2] > 0) && ((int)p[2] >= 0))
00926                valid = 1;
00927          }
00928 
00929          break;
00930 
00931       case 133: /* FS
00932 
00933                    Three parameters.  First and third positive.
00934                    Second may be negative when interpreted as an int.
00935                 */
00936          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00937          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00938          ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
00939 
00940          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00941              (ctl->opt[2] > 0) &&
00942              (to1 == CMD_NUMERIC) && ((int)tp1 >= 0))
00943          {
00944             p[3] = 4;
00945             memcpy(ext, &tp1, 4);
00946             valid = 1;
00947          }
00948 
00949          break;
00950 
00951       case 134: /* BSPIO
00952 
00953                    Six parameters.  First to Fifth positive.
00954                    Sixth may be negative when interpreted as an int.
00955                 */
00956          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00957          ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
00958          ctl->eaten += getNum(buf+ctl->eaten, &tp2, &to2);
00959          ctl->eaten += getNum(buf+ctl->eaten, &tp3, &to3);
00960          ctl->eaten += getNum(buf+ctl->eaten, &tp4, &to4);
00961          ctl->eaten += getNum(buf+ctl->eaten, &tp5, &to5);
00962                                     
00963          if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00964              (to1 == CMD_NUMERIC) && ((int)tp1 >= 0) &&
00965              (to2 == CMD_NUMERIC) && ((int)tp2 >= 0) &&
00966              (to3 == CMD_NUMERIC) && ((int)tp3 >= 0) &&
00967              (to4 == CMD_NUMERIC) && ((int)tp4 >= 0) &&
00968              (to5 == CMD_NUMERIC))
00969          {
00970             p[3] = 5 * 4;
00971             memcpy(ext+ 0, &tp1, 4);
00972             memcpy(ext+ 4, &tp2, 4);
00973             memcpy(ext+ 8, &tp3, 4);
00974             memcpy(ext+12, &tp4, 4);
00975             memcpy(ext+16, &tp5, 4);
00976             valid = 1;
00977          }
00978 
00979          break;
00980 
00981       case 191: /* PROCR PROCU
00982 
00983                    One to 11 parameters, first positive,
00984                    optional remainder, any value.
00985                 */
00986          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00987 
00988          if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0))
00989          {
00990             pars = 0;
00991             p32 = (int32_t *)ext;
00992 
00993             while (pars < PI_MAX_SCRIPT_PARAMS)
00994             {
00995                ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
00996                if (to1 == CMD_NUMERIC)
00997                {
00998                   pars++;
00999                   *p32++ = tp1;
01000                }
01001                else break;
01002             }
01003 
01004             p[3] = pars * 4;
01005 
01006             valid = 1;
01007          }
01008 
01009          break;
01010 
01011       case 192: /* WVAG
01012 
01013                    One or more triplets (gpios on, gpios off, delay),
01014                    any value.
01015                 */
01016 
01017          pars = 0;
01018          p32 = (int32_t *)ext;
01019 
01020          while (pars < CMD_MAX_PARAM)
01021          {
01022             ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
01023             if (to1 == CMD_NUMERIC)
01024             {
01025                pars++;
01026                *p32++ = tp1;
01027             }
01028             else break;
01029          }
01030 
01031          p[3] = pars * 4;
01032 
01033          if (pars && ((pars % 3) == 0)) valid = 1;
01034 
01035          break;
01036 
01037       case 193: /* BI2CZ  BSCX  BSPIX  FW  I2CWD  I2CZ  SERW
01038                    SPIW  SPIX
01039 
01040                    Two or more parameters, first >=0, rest 0-255.
01041 
01042                    BSCX is special case one or more.
01043                 */
01044          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01045 
01046          if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0))
01047          {
01048             pars = 0;
01049             p8 = ext;
01050 
01051             while (pars < CMD_MAX_PARAM)
01052             {
01053                eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01054                if (to1 == CMD_NUMERIC)
01055                {
01056                   if (((int)tp1>=0) && ((int)tp1<=255))
01057                   {
01058                      pars++;
01059                      *p8++ = tp1;
01060                      ctl->eaten += eaten;
01061                   }
01062                   else break; /* invalid number, end of command */
01063                }
01064                else break;
01065             }
01066 
01067             p[3] = pars;
01068 
01069             if (pars || (p[0]==PI_CMD_BSCX)) valid = 1;
01070          }
01071 
01072          break;
01073 
01074       case 194: /* I2CPK  I2CWI  I2CWK
01075 
01076                    Three to 34 parameters, all 0-255.
01077                 */
01078 
01079          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01080          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
01081 
01082          if ((ctl->opt[1] == CMD_NUMERIC) &&
01083              (ctl->opt[2] == CMD_NUMERIC) &&
01084              ((int)p[1]>=0) && ((int)p[2]>=0) && ((int)p[2]<=255))
01085          {
01086             pars = 0;
01087             p8 = ext;
01088 
01089             while (pars < 32)
01090             {
01091                eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01092                if (to1 == CMD_NUMERIC)
01093                {
01094                   if (((int)tp1>=0) && ((int)tp1<=255))
01095                   {
01096                      pars++;
01097                      *p8++ = tp1;
01098                      ctl->eaten += eaten;
01099                   }
01100                   else break; /* invalid number, end of command */
01101                }
01102                else break;
01103             }
01104 
01105             p[3] = pars;
01106 
01107             if (pars > 0) valid = 1;
01108          }
01109 
01110          break;
01111 
01112       case 195: /* CF1  CF2
01113 
01114                    Zero or more parameters, first two >=0, rest 0-255.
01115                 */
01116          valid = 1;
01117 
01118          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01119 
01120          if (ctl->opt[1] == CMD_NUMERIC)
01121          {
01122             if ((int)p[1] >= 0)
01123             {
01124                ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
01125 
01126                if (ctl->opt[2] == CMD_NUMERIC)
01127                {
01128                   if ((int)p[2] >= 0)
01129                   {
01130                      pars = 0;
01131                      p8 = ext;
01132 
01133                      while (pars < CMD_MAX_PARAM)
01134                      {
01135                         eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01136                         if (to1 == CMD_NUMERIC)
01137                         {
01138                            if (((int)tp1>=0) && ((int)tp1<=255))
01139                            {
01140                               pars++;
01141                               *p8++ = tp1;
01142                               ctl->eaten += eaten;
01143                            }
01144                            else break;
01145                         }
01146                         else break;
01147                      }
01148 
01149                      p[3] = pars;
01150                   }
01151                   else valid = 0;
01152                }
01153             }
01154             else valid = 0;
01155          }
01156 
01157          break;
01158 
01159       case 196: /* WVAS
01160 
01161                    gpio baud offset char...
01162 
01163                    p1 gpio
01164                    p2 baud
01165                    p3 len + 4
01166                    ---------
01167                    uint32_t databits
01168                    uint32_t stophalfbits
01169                    uint32_t offset
01170                    uint8_t[len]
01171                 */
01172          ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01173          ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
01174          ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
01175          ctl->eaten += getNum(buf+ctl->eaten, &tp2, &to2);
01176          ctl->eaten += getNum(buf+ctl->eaten, &tp3, &to3);
01177 
01178          if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0) &&
01179              (ctl->opt[2] == CMD_NUMERIC) && ((int)p[2] > 0) &&
01180              (to1 == CMD_NUMERIC) &&
01181              (to2 == CMD_NUMERIC) &&
01182              (to3 == CMD_NUMERIC))
01183          {
01184             pars = 0;
01185 
01186             memcpy(ext, &tp1, 4);
01187             memcpy(ext+4, &tp2, 4);
01188             memcpy(ext+8, &tp3, 4);
01189             p8 = ext + 12;
01190             while (pars < CMD_MAX_PARAM)
01191             {
01192                eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01193                if (to1 == CMD_NUMERIC)
01194                {
01195                   if (((int)tp1>=0) && ((int)tp1<=255))
01196                   {
01197                      *p8++ = tp1;
01198                      pars++;
01199                      ctl->eaten += eaten;
01200                   }
01201                   else break; /* invalid number, end of command */
01202                }
01203                else break;
01204             }
01205 
01206             p[3] = pars + 12;
01207 
01208             if (pars > 0) valid = 1;
01209          }
01210 
01211          break;
01212 
01213       case 197: /* WVCHA
01214 
01215                    One or more parameters, all 0-255.
01216                 */
01217          pars = 0;
01218          p8 = ext;
01219 
01220          while (pars < CMD_MAX_PARAM)
01221          {
01222             eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01223             if (to1 == CMD_NUMERIC)
01224             {
01225                if (((int)tp1>=0) && ((int)tp1<=255))
01226                {
01227                   pars++;
01228                   *p8++ = tp1;
01229                   ctl->eaten += eaten;
01230                }
01231                else break; /* invalid number, end of command */
01232             }
01233             else break;
01234          }
01235 
01236          p[3] = pars;
01237 
01238          if (pars) valid = 1;
01239 
01240          break;
01241 
01242 
01243    }
01244 
01245    if (valid) return idx; else return CMD_BAD_PARAMETER;
01246 }
01247 
01248 char * cmdErrStr(int error)
01249 {
01250    int i;
01251 
01252    for (i=0; i<(sizeof(errInfo)/sizeof(errInfo_t)); i++)
01253    {
01254       if (errInfo[i].error == error) return errInfo[i].str;
01255    }
01256    return "unknown error";
01257 }
01258 
01259 int cmdParseScript(char *script, cmdScript_t *s, int diags)
01260 {
01261    int idx, len, b, i, j, tags, resolved;
01262    int status;
01263    uint32_t p[10];
01264    cmdInstr_t instr;
01265    cmdCtlParse_t ctl;
01266    char v[CMD_MAX_EXTENSION];
01267 
01268    ctl.eaten = 0;
01269 
01270    status = 0;
01271 
01272    cmdTagStep_t tag_step[PI_MAX_SCRIPT_TAGS];
01273 
01274    len = strlen(script);
01275 
01276    /* calloc space for PARAMS, VARS, CMDS, and STRINGS */
01277 
01278    b = (sizeof(int) * (PI_MAX_SCRIPT_PARAMS + PI_MAX_SCRIPT_VARS)) +
01279        (sizeof(cmdInstr_t) * (len + 2) / 2) + len;
01280 
01281    s->par = calloc(1, b);
01282 
01283    if (s->par == NULL) return -1;
01284 
01285    s->var = s->par + PI_MAX_SCRIPT_PARAMS;
01286 
01287    s->instr = (cmdInstr_t *)(s->var + PI_MAX_SCRIPT_VARS);
01288 
01289    s->str_area = (char *)(s->instr + ((len + 2) / 2));
01290 
01291    s->str_area_len = len;
01292    s->str_area_pos = 0;
01293 
01294    s->instrs = 0;
01295 
01296    tags = 0;
01297 
01298    idx = 0;
01299 
01300    while (ctl.eaten<len)
01301    {
01302       idx = cmdParse(script, p, CMD_MAX_EXTENSION, v, &ctl);
01303 
01304       if (idx >= 0)
01305       {
01306          if (p[3])
01307          {
01308             memcpy(s->str_area + s->str_area_pos, v, p[3]);
01309             s->str_area[s->str_area_pos + p[3]] = 0;
01310             p[4] = (intptr_t) s->str_area + s->str_area_pos;
01311             s->str_area_pos += (p[3] + 1);
01312          }
01313 
01314          memcpy(&instr.p, p, sizeof(instr.p));
01315 
01316          if (instr.p[0] == PI_CMD_TAG)
01317          {
01318             if (tags < PI_MAX_SCRIPT_TAGS)
01319             {
01320                /* check tag not already used */
01321                for (j=0; j<tags; j++)
01322                {
01323                   if (tag_step[j].tag == instr.p[1])
01324                   {
01325                      if (diags)
01326                      {
01327                         fprintf(stderr, "Duplicate tag: %d\n", instr.p[1]);
01328                      }
01329 
01330                      if (!status) status = PI_DUP_TAG;
01331                      idx = -1;
01332                   }
01333                }
01334 
01335                tag_step[tags].tag = instr.p[1];
01336                tag_step[tags].step = s->instrs;
01337                tags++;
01338             }
01339             else
01340             {
01341                if (diags)
01342                {
01343                   fprintf(stderr, "Too many tags: %d\n", instr.p[1]);
01344                }
01345                if (!status) status = PI_TOO_MANY_TAGS;
01346                idx = -1;
01347             }
01348          }
01349       }
01350       else
01351       {
01352          if (diags)
01353          {
01354             if (idx == CMD_UNKNOWN_CMD)
01355                fprintf(stderr, "Unknown command: %s\n", cmdStr());
01356             else
01357                fprintf(stderr, "Bad parameter to %s\n", cmdStr());
01358          }
01359          if (!status) status = PI_BAD_SCRIPT_CMD;
01360       }
01361 
01362       if (idx >= 0)
01363       {
01364          if (instr.p[0] != PI_CMD_TAG)
01365          {
01366             memcpy(instr.opt, &ctl.opt, sizeof(instr.opt));
01367             s->instr[s->instrs++] = instr;
01368          }
01369       }
01370    }
01371 
01372    for (i=0; i<s->instrs; i++)
01373    {
01374       instr = s->instr[i];
01375 
01376       /* resolve jumps */
01377 
01378       if ((instr.p[0] == PI_CMD_JMP) || (instr.p[0] == PI_CMD_CALL) ||
01379           (instr.p[0] == PI_CMD_JZ)  || (instr.p[0] == PI_CMD_JNZ)  ||
01380           (instr.p[0] == PI_CMD_JM)  || (instr.p[0] == PI_CMD_JP))
01381       {
01382          resolved = 0;
01383 
01384          for (j=0; j<tags; j++)
01385          {
01386             if (instr.p[1] == tag_step[j].tag)
01387             {
01388                s->instr[i].p[1] = tag_step[j].step;
01389                resolved = 1;
01390                break;
01391             }
01392          }
01393 
01394          if (!resolved)
01395          {
01396             if (diags)
01397             {
01398                fprintf(stderr, "Can't resolve tag %d\n", instr.p[1]);
01399             }
01400             if (!status) status = PI_BAD_TAG;
01401          }
01402       }
01403    }
01404    return status;
01405 }
01406 


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:57