diff --git a/command.c b/command.c index ef15b5d..239ec2e 100644 --- a/command.c +++ b/command.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 53+ +This version is for pigpio version 55+ */ #include @@ -61,9 +61,19 @@ cmdInfo_t cmdInfo[]= {PI_CMD_CGI, "CGI", 101, 4}, // gpioCfgGetInternals {PI_CMD_CSI, "CSI", 111, 1}, // gpioCfgSetInternals + {PI_CMD_FC, "FC", 112, 0}, // fileClose + {PI_CMD_FG, "FG", 121, 0}, // gpioGlitchFilter + + {PI_CMD_FL, "FL", 127, 6}, // fileList + {PI_CMD_FN, "FN", 131, 0}, // gpioNoiseFilter + {PI_CMD_FO, "FO", 127, 2}, // fileOpen + {PI_CMD_FR, "FR", 121, 6}, // fileRead + {PI_CMD_FS, "FS", 133, 2}, // fileSeek + {PI_CMD_FW, "FW", 193, 0}, // fileWrite + {PI_CMD_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle {PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth @@ -112,6 +122,9 @@ cmdInfo_t cmdInfo[]= {PI_CMD_NO, "NO", 101, 2}, // gpioNotifyOpen {PI_CMD_NP, "NP", 112, 0}, // gpioNotifyPause + {PI_CMD_PADG, "PADG", 112, 2}, // gpioGetPad + {PI_CMD_PADS, "PADS", 121, 0}, // gpioSetPad + {PI_CMD_PARSE, "PARSE", 115, 0}, // cmdParseScript {PI_CMD_PFG, "PFG", 112, 2}, // gpioGetPWMfrequency @@ -149,6 +162,8 @@ cmdInfo_t cmdInfo[]= {PI_CMD_SERVO, "S", 121, 0}, // gpioServo {PI_CMD_SERVO, "SERVO", 121, 0}, // gpioServo + {PI_CMD_SHELL, "SHELL", 128, 2}, // shell + {PI_CMD_SLR, "SLR", 121, 6}, // gpioSerialRead {PI_CMD_SLRC, "SLRC", 112, 0}, // gpioSerialReadClose {PI_CMD_SLRO, "SLRO", 131, 0}, // gpioSerialReadOpen @@ -252,8 +267,14 @@ CF2 ... Custom function 2\n\ CGI Configuration get internals\n\ CSI v Configuration set internals\n\ \n\ +FC h Close file handle\n\ FG g steady Set glitch filter on GPIO\n\ +FL pat n List files which match pattern\n\ FN g steady active | Set noise filter on GPIO\n\ +FO file mode Open a file in mode\n\ +FR h n Read bytes from file handle\n\ +FS h n from Seek to file handle position\n\ +FW h ... Write bytes to file handle\n\ \n\ GDC g Get PWM dutycycle for GPIO\n\ GPW g Get servo pulsewidth for GPIO\n\ @@ -293,6 +314,8 @@ NO Request a notification\n\ NP h Pause notification\n\ \n\ P/PWM g v Set GPIO PWM value\n\ +PADG pad Get pad drive strength\n\ +PADS pad v Set pad drive strength\n\ PARSE text Validate script\n\ PFG g Get GPIO PWM frequency\n\ PFS g v Set GPIO PWM frequency\n\ @@ -316,7 +339,8 @@ SERO text baud flags | Open serial device at baud with flags\n\ SERR h n Read bytes from serial handle\n\ SERRB h Read byte from serial handle\n\ SERW h ... Write bytes to serial handle\n\ -SERWB h byte Write byte to serial handle\n\ +SERWB h byte Write byte to serial handle\n\ +SHELL name str Execute a shell command\n\ SLR g v Read bit bang serial data from GPIO\n\ SLRC g Close GPIO for bit bang serial data\n\ SLRO g baud bitlen | Open GPIO for bit bang serial data\n\ @@ -490,6 +514,21 @@ static errInfo_t errInfo[]= {PI_BAD_ISR_INIT , "bad ISR initialisation"}, {PI_BAD_FOREVER , "loop forever must be last chain command"}, {PI_BAD_FILTER , "bad filter parameter"}, + {PI_BAD_PAD , "bad pad number"}, + {PI_BAD_STRENGTH , "bad pad drive strength"}, + {PI_FIL_OPEN_FAILED , "file open failed"}, + {PI_BAD_FILE_MODE , "bad file mode"}, + {PI_BAD_FILE_FLAG , "bad file flag"}, + {PI_BAD_FILE_READ , "bad file read"}, + {PI_BAD_FILE_WRITE , "bad file write"}, + {PI_FILE_NOT_ROPEN , "file not open for read"}, + {PI_FILE_NOT_WOPEN , "file not open for write"}, + {PI_BAD_FILE_SEEK , "bad file seek"}, + {PI_NO_FILE_MATCH , "no files match pattern"}, + {PI_NO_FILE_ACCESS , "no permission to access file"}, + {PI_FILE_IS_A_DIR , "file is a directory"}, + {PI_BAD_SHELL_STATUS , "bad shell return status"}, + {PI_BAD_SCRIPT_NAME , "bad script name"}, }; @@ -507,14 +546,14 @@ static int cmdMatch(char *str) return CMD_UNKNOWN_CMD; } -static int getNum(char *str, unsigned *val, int8_t *opt) +static int getNum(char *str, uint32_t *val, int8_t *opt) { int f, n; - unsigned v; + intmax_t v; *opt = 0; - f = sscanf(str, " %i %n", &v, &n); + f = sscanf(str, " %ji %n", &v, &n); if (f == 1) { @@ -523,7 +562,7 @@ static int getNum(char *str, unsigned *val, int8_t *opt) return n; } - f = sscanf(str, " v%i %n", &v, &n); + f = sscanf(str, " v%ji %n", &v, &n); if (f == 1) { @@ -533,7 +572,7 @@ static int getNum(char *str, unsigned *val, int8_t *opt) return n; } - f = sscanf(str, " p%i %n", &v, &n); + f = sscanf(str, " p%ji %n", &v, &n); if (f == 1) { @@ -556,7 +595,7 @@ char *cmdStr(void) 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; + int f, valid, idx, val, pp, pars, n, n2; char *p8; int32_t *p32; char c; @@ -611,8 +650,8 @@ int cmdParse( break; - case 112: /* BI2CC GDC GPW I2CC - I2CRB MG MICS MILS MODEG NC NP PFG PRG + case 112: /* BI2CC FC GDC GPW I2CC I2CRB + MG MICS MILS MODEG NC NP PADG PFG PRG PROCD PROCP PROCS PRRG R READ SLRC SPIC WVDEL WVSC WVSM WVSP WVTX WVTXR @@ -656,37 +695,23 @@ int cmdParse( case 116: /* SYS - One parameter, a string of letters, digits, '-' and '_'. + One parameter, a string. */ f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2); if ((f >= 0) && n) { + p[3] = n; + ctl->opt[3] = CMD_NUMERIC; + memcpy(ext, buf+ctl->eaten, n); + ctl->eaten += n2; valid = 1; - - for (i=0; ieaten+i]; - - if ((!isalnum(c)) && (c != '_') && (c != '-')) - { - valid = 0; - break; - } - } - - if (valid) - { - p[3] = n; - ctl->opt[3] = CMD_NUMERIC; - memcpy(ext, buf+ctl->eaten, n); - ctl->eaten += n2; - } } break; - case 121: /* HC I2CRD I2CRR I2CRW I2CWB I2CWQ P PFS PRS - PWM S SERVO SLR SLRI W WDOG WRITE WVTXM + case 121: /* HC FR I2CRD I2CRR I2CRW I2CWB I2CWQ P + PADS PFS PRS PWM S SERVO SLR SLRI W + WDOG WRITE WVTXM Two positive parameters. */ @@ -782,8 +807,53 @@ int cmdParse( break; - case 131: /* BI2CO HP I2CO I2CPC I2CRI I2CWB I2CWW SLRO - SPIO TRIG + case 127: /* FL FO + + Two parameters, first a string, other positive. + */ + f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2); + if ((f >= 0) && n) + { + 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]); + + if ((ctl->opt[1] > 0) && ((int)p[1] >= 0)) + valid = 1; + } + + break; + + case 128: /* SHELL + + Two string parameters, the first space teminated. + The second arbitrary. + */ + f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2); + + if ((f >= 0) && n) + { + valid = 1; + + p[1] = n; + memcpy(ext, buf+ctl->eaten, n); + ctl->eaten += n; + ext[n] = 0; /* terminate first string */ + + n2 = strlen(buf+ctl->eaten+1); + memcpy(ext+n+1, buf+ctl->eaten+1, n2); + ctl->eaten += n2; + ctl->eaten ++; + p[3] = p[1] + n2 + 1; + } + + break; + + case 131: /* BI2CO HP I2CO I2CPC I2CRI I2CWB I2CWW + SLRO SPIO TRIG Three positive parameters. */ @@ -824,6 +894,26 @@ int cmdParse( break; + case 133: /* FS + + Three parameters. First and third positive. + Second may be negative when interpreted as an int. + */ + 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] > 0) && ((int)p[1] >= 0) && + (ctl->opt[2] > 0) && + (to1 == CMD_NUMERIC) && ((int)tp1 >= 0)) + { + p[3] = 4; + memcpy(ext, &tp1, 4); + valid = 1; + } + + break; + case 191: /* PROCR One to 11 parameters, first positive, @@ -880,7 +970,7 @@ int cmdParse( break; - case 193: /* BI2CZ I2CWD I2CZ SERW SPIW SPIX + case 193: /* BI2CZ FW I2CWD I2CZ SERW SPIW SPIX Two or more parameters, first >=0, rest 0-255. */ diff --git a/command.h b/command.h index 3c36bd1..7c6efcd 100644 --- a/command.h +++ b/command.h @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 53+ +This version is for pigpio version 55+ */ #ifndef COMMAND_H diff --git a/pig2vcd.1 b/pig2vcd.1 index 492ec68..24b5a6c 100644 --- a/pig2vcd.1 +++ b/pig2vcd.1 @@ -11,6 +11,10 @@ pig2vd - A utility to convert pigpio notifications to VCD. pig2vcd file.VCD .SH DESCRIPTION + +.ad l + +.nh pig2vcd is a utility which reads notifications on stdin and writes the output as a Value Change Dump (VCD) file on stdout. diff --git a/pigpio.3 b/pigpio.3 index 8bb1011..16b0ddf 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -17,6 +17,10 @@ sudo ./prog .SH DESCRIPTION +.ad l + +.nh + .br .br @@ -29,12 +33,12 @@ pigpio is a C library for the Raspberry which allows control of the GPIO. .br .br -o PWM on any of GPIO 0-31 +o hardware timed PWM on any of GPIO 0-31 .br .br -o servo pulses on any of GPIO 0-31 +o hardware timed servo pulses on any of GPIO 0-31 .br @@ -313,15 +317,15 @@ Arduino style: pinMode. .br .EX -gpioSetMode(17, PI_INPUT); // Set gpio17 as input. +gpioSetMode(17, PI_INPUT); // Set GPIO17 as input. .br .br -gpioSetMode(18, PI_OUTPUT); // Set gpio18 as output. +gpioSetMode(18, PI_OUTPUT); // Set GPIO18 as output. .br .br -gpioSetMode(22,PI_ALT0); // Set gpio22 to alternative mode 0. +gpioSetMode(22,PI_ALT0); // Set GPIO22 to alternative mode 0. .br .EE @@ -356,7 +360,7 @@ if (gpioGetMode(17) != PI_ALT0) .br { .br - gpioSetMode(17, PI_ALT0); // set gpio17 to ALT0 + gpioSetMode(17, PI_ALT0); // set GPIO17 to ALT0 .br } .br @@ -435,7 +439,7 @@ Arduino style: digitalRead. .br .EX -printf("gpio24 is level %d", gpioRead(24)); +printf("GPIO24 is level %d", gpioRead(24)); .br .EE @@ -478,7 +482,7 @@ Arduino style: digitalWrite .br .EX -gpioWrite(24, 1); // Set gpio24 high. +gpioWrite(24, 1); // Set GPIO24 high. .br .EE @@ -529,15 +533,15 @@ range of 255. .br .EX -gpioPWM(17, 255); // Sets gpio17 full on. +gpioPWM(17, 255); // Sets GPIO17 full on. .br .br -gpioPWM(18, 128); // Sets gpio18 half on. +gpioPWM(18, 128); // Sets GPIO18 half on. .br .br -gpioPWM(23, 0); // Sets gpio23 full off. +gpioPWM(23, 0); // Sets GPIO23 full off. .br .EE @@ -825,15 +829,15 @@ sample .br .EX -gpioSetPWMfrequency(23, 0); // Set gpio23 to lowest frequency. +gpioSetPWMfrequency(23, 0); // Set GPIO23 to lowest frequency. .br .br -gpioSetPWMfrequency(24, 500); // Set gpio24 to 500Hz. +gpioSetPWMfrequency(24, 500); // Set GPIO24 to 500Hz. .br .br -gpioSetPWMfrequency(25, 100000); // Set gpio25 to highest frequency. +gpioSetPWMfrequency(25, 100000); // Set GPIO25 to highest frequency. .br .EE @@ -878,7 +882,7 @@ will be that set by \fBgpioHardwarePWM\fP. .br .EX -f = gpioGetPWMfrequency(23); // Get frequency used for gpio23. +f = gpioGetPWMfrequency(23); // Get frequency used for GPIO23. .br .EE @@ -978,7 +982,7 @@ the servo pulsewidth. .br .br -E.g. If you want to update a servo connected to gpio25 at 400Hz +E.g. If you want to update a servo connected to GPIO25 at 400Hz .br @@ -1481,11 +1485,19 @@ by one for each report. .br flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. -If bit 5 is set (PI_NTFY_FLAGS_WDOG) then bits 0-4 of the flags -indicate a GPIO which has had a watchdog timeout; if bit 6 is set -(PI_NTFY_FLAGS_ALIVE) this indicates a keep alive signal on the -pipe/socket and is sent once a minute in the absence of other -notification activity. + +.br + +.br +PI_NTFY_FLAGS_WDOG, if bit 5 is set then bits 0-4 of the flags +indicate a GPIO which has had a watchdog timeout. + +.br + +.br +PI_NTFY_FLAGS_ALIVE, if bit 6 is set this indicates a keep alive +signal on the pipe/socket and is sent once a minute in the absence +of other notification activity. .br @@ -2095,19 +2107,14 @@ The following command codes are supported: .br Name Cmd & Data Meaning - .br Loop Start 255 0 Identify start of a wave block - .br Loop Repeat 255 1 x y loop x + y*256 times - .br Delay 255 2 x y delay x + y*256 microseconds - .br Loop Forever 255 3 loop forever - .br .br @@ -2362,7 +2369,7 @@ This function configures the level logic for bit bang serial reads. .br .br -Pass PI_BB_SER_INVERT to invert the serial logic. Pass PI_BB_SER_NORMAL for +Use PI_BB_SER_INVERT to invert the serial logic and PI_BB_SER_NORMAL for normal logic. Default is PI_BB_SER_NORMAL. .br @@ -3178,31 +3185,22 @@ The following command codes are supported: .br Name Cmd & Data Meaning - .br End 0 No more commands - .br Escape 1 Next P is two bytes - .br On 2 Switch combined flag on - .br Off 3 Switch combined flag off - .br Address 4 P Set I2C address to P - .br Flags 5 lsb msb Set I2C flags to lsb + (msb << 8) - .br Read 6 P Read P bytes of data - .br Write 7 P ... Write P bytes of data - .br .br @@ -3367,31 +3365,22 @@ The following command codes are supported: .br Name Cmd & Data Meaning - .br End 0 No more commands - .br Escape 1 Next P is two bytes - .br Start 2 Start condition - .br Stop 3 Stop condition - .br Address 4 P Set I2C address to P - .br Flags 5 lsb msb Set I2C flags to lsb + (msb << 8) - .br Read 6 P Read P bytes of data - .br Write 7 P ... Write P bytes of data - .br .br @@ -3719,14 +3708,15 @@ PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. .IP "\fBint serOpen(char *sertty, unsigned baud, unsigned serFlags)\fP" .IP "" 4 This function opens a serial device at a specified baud rate -with specified flags. +and with specified flags. The device name must start with +/dev/tty or /dev/serial. .br .br .EX - sertty: the serial device to open, /dev/tty* + sertty: the serial device to open .br baud: the baud rate in bits per second, see below .br @@ -3847,7 +3837,7 @@ associated with handle and writes them to buf. .br .EX -handle: >=0, as returned by a call to serial_open +handle: >=0, as returned by a call to \fBserOpen\fP .br buf: an array to receive the read data .br @@ -3860,7 +3850,7 @@ handle: >=0, as returned by a call to serial_open .br Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE, -PI_BAD_PARAM, PI_SER_READ_NO_DATA, or PI_SER_WRITE_FAILED. +PI_BAD_PARAM, or PI_SER_READ_NO_DATA. .IP "\fBint serDataAvailable(unsigned handle)\fP" .IP "" 4 @@ -5146,6 +5136,676 @@ for "Revision : 000g" the function returns 0. .IP "" 4 Returns the pigpio version. +.IP "\fBint gpioGetPad(unsigned pad)\fP" +.IP "" 4 +This function returns the pad drive strength in mA. + +.br + +.br + +.EX +pad: 0-2, the pad to get +.br + +.EE + +.br + +.br +Returns the pad drive strength if OK, otherwise PI_BAD_PAD. + +.br + +.br +Pad GPIO +.br +0 0-27 +.br +1 28-45 +.br +2 46-53 +.br + +.br + +.br +\fBExample\fP +.br + +.EX +strength = gpioGetPad(1); // get pad 1 strength +.br + +.EE + +.IP "\fBint gpioSetPad(unsigned pad, unsigned padStrength)\fP" +.IP "" 4 +This function sets the pad drive strength in mA. + +.br + +.br + +.EX + pad: 0-2, the pad to set +.br +padStrength: 1-16 mA +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_BAD_PAD, or PI_BAD_STRENGTH. + +.br + +.br +Pad GPIO +.br +0 0-27 +.br +1 28-45 +.br +2 46-53 +.br + +.br + +.br +\fBExample\fP +.br + +.EX +gpioSetPad(0, 16); // set pad 0 strength to 16 mA +.br + +.EE + +.IP "\fBint shell(char *scriptName, char *scriptString)\fP" +.IP "" 4 +This function uses the system call to execute a shell script +with the given string as its parameter. + +.br + +.br + +.EX + scriptName: the name of the script, only alphanumeric characters, +.br + '-' and '_' are allowed in the name +.br +scriptString: the string to pass to the script +.br + +.EE + +.br + +.br +The exit status of the system call is returned if OK, otherwise +PI_BAD_SHELL_STATUS. + +.br + +.br +scriptName must exist in /opt/pigpio/cgi and must be executable. + +.br + +.br +The returned exit status is normally 256 times that set by the +shell script exit function. If the script can't be found 32512 will +be returned. + +.br + +.br +The following table gives some example returned statuses. + +.br + +.br +Script exit status Returned system call status +.br +1 256 +.br +5 1280 +.br +10 2560 +.br +200 51200 +.br +script not found 32512 +.br + +.br + +.br +\fBExample\fP +.br + +.EX +// pass two parameters, hello and world +.br +status = shell("scr1", "hello world"); +.br + +.br +// pass three parameters, hello, string with spaces, and world +.br +status = shell("scr1", "hello 'string with spaces' world"); +.br + +.br +// pass one parameter, hello string with spaces world +.br +status = shell("scr1", "\"hello string with spaces world\""); +.br + +.EE + +.IP "\fBint fileOpen(char *file, unsigned mode)\fP" +.IP "" 4 +This function returns a handle to a file opened in a specified mode. + +.br + +.br + +.EX +file: the file to open +.br +mode: the file open mode +.br + +.EE + +.br + +.br +Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, PI_NO_FILE_ACCESS, +PI_BAD_FILE_MODE, PI_FILE_OPEN_FAILED, or PI_FILE_IS_A_DIR. + +.br + +.br +File + +.br + +.br +A file may only be opened if permission is granted by an entry in +/opt/pigpio/access. This is intended to allow remote access to files +in a more or less controlled manner. + +.br + +.br +Each entry in /opt/pigpio/access takes the form of a file path +which may contain wildcards followed by a single letter permission. +The permission may be R for read, W for write, U for read/write, +and N for no access. + +.br + +.br +Where more than one entry matches a file the most specific rule +applies. If no entry matches a file then access is denied. + +.br + +.br +Suppose /opt/pigpio/access contains the following entries + +.br + +.br + +.EX +/home/* n +.br +/home/pi/shared/dir_1/* w +.br +/home/pi/shared/dir_2/* r +.br +/home/pi/shared/dir_3/* u +.br +/home/pi/shared/dir_1/file.txt n +.br + +.EE + +.br + +.br +Files may be written in directory dir_1 with the exception +of file.txt. + +.br + +.br +Files may be read in directory dir_2. + +.br + +.br +Files may be read and written in directory dir_3. + +.br + +.br +If a directory allows read, write, or read/write access then files may +be created in that directory. + +.br + +.br +In an attempt to prevent risky permissions the following paths are +ignored in /opt/pigpio/access. + +.br + +.br + +.EX +a path containing .. +.br +a path containing only wildcards (*?) +.br +a path containing less than two non-wildcard parts +.br + +.EE + +.br + +.br +Mode + +.br + +.br +The mode may have the following values. + +.br + +.br +Macro Value Meaning +.br +PI_FILE_READ 1 open file for reading +.br +PI_FILE_WRITE 2 open file for writing +.br +PI_FILE_RW 3 open file for reading and writing +.br + +.br + +.br +The following values may be or'd into the mode. + +.br + +.br +Macro Value Meaning +.br +PI_FILE_APPEND 4 Writes append data to the end of the file +.br +PI_FILE_CREATE 8 The file is created if it doesn't exist +.br +PI_FILE_TRUNC 16 The file is truncated +.br + +.br + +.br +Newly created files are owned by root with permissions owner read and write. + +.br + +.br +\fBExample\fP +.br + +.EX +#include +.br +#include +.br + +.br +int main(int argc, char *argv[]) +.br +{ +.br + int handle, c; +.br + char buf[60000]; +.br + +.br + if (gpioInitialise() < 0) return 1; +.br + +.br + // assumes /opt/pigpio/access contains the following line +.br + // /ram/*.c r +.br + +.br + handle = fileOpen("/ram/pigpio.c", PI_FILE_READ); +.br + +.br + if (handle >= 0) +.br + { +.br + while ((c=fileRead(handle, buf, sizeof(buf)-1))) +.br + { +.br + buf[c] = 0; +.br + printf("%s", buf); +.br + } +.br + +.br + fileClose(handle); +.br + } +.br + +.br + gpioTerminate(); +.br +} +.br + +.EE + +.IP "\fBint fileClose(unsigned handle)\fP" +.IP "" 4 +This function closes the file associated with handle. + +.br + +.br + +.EX +handle: >=0, as returned by a call to \fBfileOpen\fP +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_BAD_HANDLE. + +.br + +.br +\fBExample\fP +.br + +.EX +fileClose(h); +.br + +.EE + +.IP "\fBint fileWrite(unsigned handle, char *buf, unsigned count)\fP" +.IP "" 4 +This function writes count bytes from buf to the the file +associated with handle. + +.br + +.br + +.EX +handle: >=0, as returned by a call to \fBfileOpen\fP +.br + buf: the array of bytes to write +.br + count: the number of bytes to write +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, +PI_FILE_NOT_WOPEN, or PI_BAD_FILE_WRITE. + +.br + +.br +\fBExample\fP +.br + +.EX +status = fileWrite(h, buf, count); +.br +if (status == 0) +.br +{ +.br + // okay +.br +} +.br +else +.br +{ +.br + // error +.br +} +.br + +.EE + +.IP "\fBint fileRead(unsigned handle, char *buf, unsigned count)\fP" +.IP "" 4 +This function reads up to count bytes from the the file +associated with handle and writes them to buf. + +.br + +.br + +.EX +handle: >=0, as returned by a call to \fBfileOpen\fP +.br + buf: an array to receive the read data +.br + count: the maximum number of bytes to read +.br + +.EE + +.br + +.br +Returns the number of bytes read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, PI_FILE_NOT_ROPEN, or PI_BAD_FILE_WRITE. + +.br + +.br +\fBExample\fP +.br + +.EX +if (fileRead(h, buf, sizeof(buf)) > 0) +.br +{ +.br + // process read data +.br +} +.br + +.EE + +.IP "\fBint fileSeek(unsigned handle, int32_t seekOffset, int seekFrom)\fP" +.IP "" 4 +This function seeks to a position within the file associated +with handle. + +.br + +.br + +.EX + handle: >=0, as returned by a call to \fBfileOpen\fP +.br +seekOffset: the number of bytes to move. Positive offsets +.br + move forward, negative offsets backwards. +.br + seekFrom: one of PI_FROM_START (0), PI_FROM_CURRENT (1), +.br + or PI_FROM_END (2) +.br + +.EE + +.br + +.br +Returns the new byte position within the file (>=0) if OK, otherwise PI_BAD_HANDLE, or PI_BAD_FILE_SEEK. + +.br + +.br +\fBExample\fP +.br + +.EX +fileSeek(0, 20, PI_FROM_START); // Seek to start plus 20 +.br + +.br +size = fileSeek(0, 0, PI_FROM_END); // Seek to end, return size +.br + +.br +pos = fileSeek(0, 0, PI_FROM_CURRENT); // Return current position +.br + +.EE + +.IP "\fBint fileList(char *fpat, char *buf, unsigned count)\fP" +.IP "" 4 +This function returns a list of files which match a pattern. The +pattern may contain wildcards. + +.br + +.br + +.EX + fpat: file pattern to match +.br + buf: an array to receive the matching file names +.br +count: the maximum number of bytes to read +.br + +.EE + +.br + +.br +Returns the number of returned bytes if OK, otherwise PI_NO_FILE_ACCESS, +or PI_NO_FILE_MATCH. + +.br + +.br +The pattern must match an entry in /opt/pigpio/access. The pattern +may contain wildcards. See \fBfileOpen\fP. + +.br + +.br +NOTE + +.br + +.br +The returned value is not the number of files, it is the number +of bytes in the buffer. The file names are separated by newline +characters. + +.br + +.br +\fBExample\fP +.br + +.EX +#include +.br +#include +.br + +.br +int main(int argc, char *argv[]) +.br +{ +.br + int c; +.br + char buf[1000]; +.br + +.br + if (gpioInitialise() < 0) return 1; +.br + +.br + // assumes /opt/pigpio/access contains the following line +.br + // /ram/*.c r +.br + +.br + c = fileList("/ram/p*.c", buf, sizeof(buf)); +.br + +.br + if (c >= 0) +.br + { +.br + // terminate string +.br + buf[c] = 0; +.br + printf("%s", buf); +.br + } +.br + +.br + gpioTerminate(); +.br +} +.br + +.EE + .IP "\fBint gpioCfgBufferSize(unsigned cfgMillis)\fP" .IP "" 4 Configures pigpio to buffer cfgMillis milliseconds of GPIO samples. @@ -5390,17 +6050,13 @@ If the board revision is not recognised then GPIO 0-31 are allowed. .br Unknown board PI_DEFAULT_UPDATE_MASK_UNKNOWN 0xFFFFFFFF .br - .br Type 1 board PI_DEFAULT_UPDATE_MASK_B1 0x03E6CF93 .br - .br Type 2 board PI_DEFAULT_UPDATE_MASK_A_B2 0xFBC6CF9C - .br Type 3 board PI_DEFAULT_UPDATE_MASK_R3 0x0FFFFFFC - .br .IP "\fBint gpioCfgSocketPort(unsigned port)\fP" @@ -6168,10 +6824,6 @@ PI_HW_CLK_MAX_FREQ 250000000 .br .IP "\fBcount\fP" 0 - -.br - -.br The number of bytes to be transferred in an I2C, SPI, or Serial command. @@ -6246,7 +6898,7 @@ The number may vary between 0 and range (default 255) where .br .IP "\fBedge\fP: 0-2" 0 -The type of GPIO edge to generate an intrrupt. See\fBgpioSetISRFunc\fP, +The type of GPIO edge to generate an intrrupt. See \fBgpioSetISRFunc\fP, and \fBgpioSetISRFuncEx\fP. .br @@ -6278,6 +6930,22 @@ A function. .br +.IP "\fB*file\fP" 0 +A full file path. To be accessible the path must match an entry in +/opt/pigpio/access. + +.br + +.br + +.IP "\fB*fpat\fP" 0 +A file path which may contain wildcards. To be accessible the path +must match an entry in /opt/pigpio/access. + +.br + +.br + .IP "\fBfrequency\fP: >=0" 0 .br @@ -6302,14 +6970,14 @@ A Broadcom numbered GPIO, in the range 0-53. .br .br -There are 54 General Purpose Input Outputs (GPIO) named gpio0 through -gpio53. +There are 54 General Purpose Input Outputs (GPIO) named GPIO0 through +GPIO53. .br .br -They are split into two banks. Bank 1 consists of gpio0 through -gpio31. Bank 2 consists of gpio32 through gpio53. +They are split into two banks. Bank 1 consists of GPIO0 through +GPIO31. Bank 2 consists of GPIO32 through GPIO53. .br @@ -6597,18 +7265,8 @@ One of .br .br -A number referencing an object opened by one of - -.br - -.br -\fBi2cOpen\fP -.br -\fBgpioNotifyOpen\fP -.br -\fBserOpen\fP -.br -\fBspiOpen\fP +A number referencing an object opened by one of \fBfileOpen\fP, +\fBgpioNotifyOpen\fP, \fBi2cOpen\fP, \fBserOpen\fP, \fBspiOpen\fP. .br @@ -6689,6 +7347,13 @@ A whole number, negative or positive. .br +.IP "\fBint32_t\fP" 0 +A 32-bit signed value. + +.br + +.br + .IP "\fBinvert\fP" 0 A flag used to set normal or inverted bit bang serial data level logic. @@ -6816,12 +7481,12 @@ A value representing milliseconds. .br -.IP "\fBmode\fP: 0-7" 0 +.IP "\fBmode\fP" 0 .br .br -The operational mode of a GPIO, normally INPUT or OUTPUT. +1. The operational mode of a GPIO, normally INPUT or OUTPUT. .br @@ -6849,6 +7514,44 @@ PI_ALT5 2 .br +.br +2. A file open mode. + +.br + +.br + +.EX +PI_FILE_READ 1 +.br +PI_FILE_WRITE 2 +.br +PI_FILE_RW 3 +.br + +.EE + +.br + +.br +The following values can be or'd into the mode. + +.br + +.br + +.EX +PI_FILE_APPEND 4 +.br +PI_FILE_CREATE 8 +.br +PI_FILE_TRUNC 16 +.br + +.EE + +.br + .br .IP "\fBnumBits\fP" 0 @@ -6914,6 +7617,33 @@ The size in bytes of an output buffer. .br +.IP "\fBpad\fP: 0-2" 0 +A set of GPIO which share common drivers. + +.br + +.br +Pad GPIO +.br +0 0-27 +.br +1 28-45 +.br +2 46-53 +.br + +.br + +.br + +.IP "\fBpadStrength\fP: 1-16" 0 +The mA which may be drawn from each GPIO whilst still guaranteeing the +high and low levels. + +.br + +.br + .IP "\fB*param\fP" 0 An array of script parameters. @@ -7251,10 +7981,6 @@ A pointer to a buffer to receive data. .br .IP "\fBSCL\fP" 0 - -.br - -.br The user GPIO to use for the clock when bit banging I2C. .br @@ -7262,10 +7988,6 @@ The user GPIO to use for the clock when bit banging I2C. .br .IP "\fB*script\fP" 0 - -.br - -.br A pointer to the text of a script. .br @@ -7273,21 +7995,28 @@ A pointer to the text of a script. .br .IP "\fBscript_id\fP" 0 - -.br - -.br An id of a stored script as returned by \fBgpioStoreScript\fP. .br .br +.IP "\fB*scriptName\fP" 0 +The name of a \fBshell\fP script to be executed. The script must be present in +/opt/pigpio/cgi and must have execute permission. + +.br + +.br + +.IP "\fB*scriptString\fP" 0 +The string to be passed to a \fBshell\fP script to be executed. + +.br + +.br + .IP "\fBSDA\fP" 0 - -.br - -.br The user GPIO to use for data when bit banging I2C. .br @@ -7318,21 +8047,41 @@ a returned time. .br .IP "\fBseconds\fP" 0 - -.br - -.br The number of seconds. .br .br +.IP "\fBseekFrom\fP" 0 + +.br + +.br + +.EX +PI_FROM_START 0 +.br +PI_FROM_CURRENT 1 +.br +PI_FROM_END 2 +.br + +.EE + +.br + +.br + +.IP "\fBseekOffset\fP" 0 +The number of bytes to move forward (positive) or backwards (negative) +from the seek position (start, current, or end of file). + +.br + +.br + .IP "\fB*segs\fP" 0 - -.br - -.br An array of segments which make up a combined I2C transaction. .br @@ -7623,10 +8372,6 @@ See \fBgpio\fP. .br .IP "\fB*userdata\fP" 0 - -.br - -.br A pointer to arbitrary user data. This may be used to identify the instance. .br @@ -7975,6 +8720,30 @@ A 16-bit word value. #define PI_CMD_WVTAT 101 .br +.br +#define PI_CMD_PADS 102 +.br +#define PI_CMD_PADG 103 +.br + +.br +#define PI_CMD_FO 104 +.br +#define PI_CMD_FC 105 +.br +#define PI_CMD_FR 106 +.br +#define PI_CMD_FW 107 +.br +#define PI_CMD_FS 108 +.br +#define PI_CMD_FL 109 +.br + +.br +#define PI_CMD_SHELL 110 +.br + .br .EE @@ -8061,7 +8830,7 @@ A 16-bit word value. .br #define PI_TOO_MANY_CHARS -37 // waveform has too many chars .br -#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read in progress on GPIO +#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read on GPIO .br #define PI_BAD_SERIAL_STRUC -39 // bad (null) serial structure parameter .br @@ -8235,10 +9004,40 @@ A 16-bit word value. .br #define PI_BAD_ISR_INIT -123 // bad ISR initialisation .br -#define PI_BAD_FOREVER -124 // loop forever must be last chain command +#define PI_BAD_FOREVER -124 // loop forever must be last command .br #define PI_BAD_FILTER -125 // bad filter parameter .br +#define PI_BAD_PAD -126 // bad pad number +.br +#define PI_BAD_STRENGTH -127 // bad pad drive strength +.br +#define PI_FIL_OPEN_FAILED -128 // file open failed +.br +#define PI_BAD_FILE_MODE -129 // bad file mode +.br +#define PI_BAD_FILE_FLAG -130 // bad file flag +.br +#define PI_BAD_FILE_READ -131 // bad file read +.br +#define PI_BAD_FILE_WRITE -132 // bad file write +.br +#define PI_FILE_NOT_ROPEN -133 // file not open for read +.br +#define PI_FILE_NOT_WOPEN -134 // file not open for write +.br +#define PI_BAD_FILE_SEEK -135 // bad file seek +.br +#define PI_NO_FILE_MATCH -136 // no files match pattern +.br +#define PI_NO_FILE_ACCESS -137 // no permission to access file +.br +#define PI_FILE_IS_A_DIR -138 // file is a directory +.br +#define PI_BAD_SHELL_STATUS -139 // bad shell return status +.br +#define PI_BAD_SCRIPT_NAME -140 // bad script name +.br .br #define PI_PIGIF_ERR_0 -2000 diff --git a/pigpio.c b/pigpio.c index 4588b38..3f0b2f8 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 54 */ +/* pigpio version 55 */ /* include ------------------------------------------------------- */ @@ -58,11 +58,14 @@ For more information, please refer to #include #include #include +#include +#include #include "pigpio.h" #include "command.h" + /* --------------------------------------------------------------- */ /* @@ -299,6 +302,7 @@ bit 0 READ_LAST_NOT_SET_ERROR #define DMA_BASE (pi_peri_phys + 0x00007000) #define DMA15_BASE (pi_peri_phys + 0x00E05000) #define GPIO_BASE (pi_peri_phys + 0x00200000) +#define PADS_BASE (pi_peri_phys + 0x00100000) #define PCM_BASE (pi_peri_phys + 0x00203000) #define PWM_BASE (pi_peri_phys + 0x0020C000) #define SPI_BASE (pi_peri_phys + 0x00204000) @@ -308,6 +312,7 @@ bit 0 READ_LAST_NOT_SET_ERROR #define CLK_LEN 0xA8 #define DMA_LEN 0x1000 /* allow access to all channels */ #define GPIO_LEN 0xB4 +#define PADS_LEN 0x38 #define PCM_LEN 0x24 #define PWM_LEN 0x28 #define SPI_LEN 0x18 @@ -474,7 +479,7 @@ bit 0 READ_LAST_NOT_SET_ERROR #define PCM_GRAY_CLR (1<<1) #define PCM_GRAY_EN (1<<0) -#define CLK_PASSWD (0x5A<<24) +#define BCM_PASSWD (0x5A<<24) #define CLK_CTL_MASH(x)((x)<<9) #define CLK_CTL_BUSY (1 <<7) @@ -734,6 +739,9 @@ Assumes two counters per block. Each counter 4 * 16 (16^4=65536) #define PI_SER_CLOSED 0 #define PI_SER_OPENED 1 +#define PI_FILE_CLOSED 0 +#define PI_FILE_OPENED 1 + #define PI_NOTIFY_CLOSED 0 #define PI_NOTIFY_CLOSING 1 #define PI_NOTIFY_OPENED 2 @@ -843,6 +851,8 @@ Assumes two counters per block. Each counter 4 * 16 (16^4=65536) #define PI_RUNNING 1 #define PI_ENDING 2 +#define PI_MAX_PATH 512 + /* typedef ------------------------------------------------------- */ typedef void (*callbk_t) (); @@ -975,6 +985,13 @@ typedef struct int max_emits; } gpioNotify_t; +typedef struct +{ + uint16_t state; + int16_t fd; + uint32_t mode; +} fileInfo_t; + typedef struct { uint16_t state; @@ -1202,6 +1219,7 @@ static gpioInfo_t gpioInfo [PI_MAX_GPIO+1]; static gpioNotify_t gpioNotify [PI_NOTIFY_SLOTS]; +static fileInfo_t fileInfo [PI_FILE_SLOTS]; static i2cInfo_t i2cInfo [PI_I2C_SLOTS]; static serInfo_t serInfo [PI_SER_SLOTS]; static spiInfo_t spiInfo [PI_SPI_SLOTS]; @@ -1242,6 +1260,7 @@ static volatile uint32_t * auxReg = MAP_FAILED; static volatile uint32_t * clkReg = MAP_FAILED; static volatile uint32_t * dmaReg = MAP_FAILED; static volatile uint32_t * gpioReg = MAP_FAILED; +static volatile uint32_t * padsReg = MAP_FAILED; static volatile uint32_t * pcmReg = MAP_FAILED; static volatile uint32_t * pwmReg = MAP_FAILED; static volatile uint32_t * spiReg = MAP_FAILED; @@ -1408,6 +1427,29 @@ static void closeOrphanedNotifications(int slot, int fd); /* ======================================================================= */ +int myScriptNameValid(char *name) +{ + int i, c, len, valid; + + len = strlen(name); + + valid = 1; + + for (i=0; i bufSize) p[1] = bufSize; + res = fileList(buf, buf, p[1]); + break; + case PI_CMD_FN: memcpy(&p[4], buf, 4); res = gpioNoiseFilter(p[1], p[2], p[4]); break; + case PI_CMD_FO: res = fileOpen(buf, p[1]); break; + + case PI_CMD_FR: + if (p[2] > bufSize) p[2] = bufSize; + res = fileRead(p[1], buf, p[2]); + break; + + case PI_CMD_FS: + memcpy(&p[4], buf, 4); + res = fileSeek(p[1], p[2], p[4]); + break; + + case PI_CMD_FW: res = fileWrite(p[1], buf, p[3]); break; + case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break; case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break; @@ -1923,6 +2027,10 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) case PI_CMD_NP: res = gpioNotifyPause(p[1]); break; + case PI_CMD_PADG: res = gpioGetPad(p[1]); break; + + case PI_CMD_PADS: res = gpioSetPad(p[1], p[2]); break; + case PI_CMD_PFG: res = gpioGetPWMfrequency(p[1]); break; case PI_CMD_PFS: @@ -2018,6 +2126,10 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) case PI_CMD_SERW: res = serWrite(p[1], buf, p[3]); break; + case PI_CMD_SHELL: + res = shell(buf, buf+p[1]+1); + break; + case PI_CMD_SLR: if (p[2] > bufSize) p[2] = bufSize; @@ -4477,7 +4589,7 @@ int serOpen(char *tty, unsigned serBaud, unsigned serFlags) SER_CHECK_INITED; - if (strncmp("/dev/tty", tty, 8)) + if (strncmp("/dev/tty", tty, 8) && strncmp("/dev/serial", tty, 11)) SOFT_ERROR(PI_BAD_SER_DEVICE, "bad device (%s)", tty); switch (serBaud) @@ -6022,17 +6134,21 @@ static int scrWait(gpioScript_t *s, uint32_t bits) static int scrSys(char *cmd, uint32_t p1, uint32_t p2) { - char buf[256]; - char pars[40]; + char buf[1024]; + int status; - sprintf(pars, " %u %u", p1, p2); - strcpy(buf, "/opt/pigpio/cgi/"); - strncat(buf, cmd, 200); - strcat(buf, pars); + if (!myScriptNameValid(cmd)) + SOFT_ERROR(PI_BAD_SCRIPT_NAME, "bad script name (%s)", cmd); - DBG(DBG_USER, "sys %s", buf); + snprintf(buf, sizeof(buf), "/opt/pigpio/cgi/%s %u %u", cmd, p1, p2); - return system(buf); + DBG(DBG_USER, "%s", buf); + + status = system(buf); + + if (status < 0) status = PI_BAD_SHELL_STATUS; + + return status; } /* ----------------------------------------------------------------------- */ @@ -6523,6 +6639,8 @@ static void *pthSocketThreadHandler(void *fdC) case PI_CMD_BI2CZ: case PI_CMD_CF2: + case PI_CMD_FL: + case PI_CMD_FR: case PI_CMD_I2CPK: case PI_CMD_I2CRD: case PI_CMD_I2CRI: @@ -6769,6 +6887,11 @@ static int initPeripherals(void) if (auxReg == MAP_FAILED) SOFT_ERROR(PI_INIT_FAILED, "mmap aux failed (%m)"); + padsReg = initMapMem(fdMem, PADS_BASE, PADS_LEN); + + if (padsReg == MAP_FAILED) + SOFT_ERROR(PI_INIT_FAILED, "mmap pads failed (%m)"); + return 0; } @@ -7170,20 +7293,20 @@ static void initHWClk { do { - clkReg[clkCtl] = CLK_PASSWD | CLK_CTL_KILL; + clkReg[clkCtl] = BCM_PASSWD | CLK_CTL_KILL; } while (clkReg[clkCtl] & CLK_CTL_BUSY); } - clkReg[clkDiv] = (CLK_PASSWD | CLK_DIV_DIVI(divI) | CLK_DIV_DIVF(divF)); + clkReg[clkDiv] = (BCM_PASSWD | CLK_DIV_DIVI(divI) | CLK_DIV_DIVF(divF)); usleep(10); - clkReg[clkCtl] = (CLK_PASSWD | CLK_CTL_MASH(MASH) | CLK_CTL_SRC(clkSrc)); + clkReg[clkCtl] = (BCM_PASSWD | CLK_CTL_MASH(MASH) | CLK_CTL_SRC(clkSrc)); usleep(10); - clkReg[clkCtl] |= (CLK_PASSWD | CLK_CTL_ENAB); + clkReg[clkCtl] |= (BCM_PASSWD | CLK_CTL_ENAB); } static void initClock(int mainClock) @@ -11345,7 +11468,7 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) else { /* frequency 0, stop clock */ - clkReg[cctl[clock]] = CLK_PASSWD | CLK_CTL_KILL; + clkReg[cctl[clock]] = BCM_PASSWD | CLK_CTL_KILL; if (gpioInfo[gpio].is == GPIO_HW_CLK) gpioInfo[gpio].is = GPIO_UNDEFINED; @@ -11470,6 +11593,403 @@ int gpioHardwarePWM( } +int gpioSetPad(unsigned pad, unsigned padStrength) +{ + DBG(DBG_USER, "pad=%d padStrength=%d", pad, padStrength); + + CHECK_INITED; + + if (pad > PI_MAX_PAD) + SOFT_ERROR(PI_BAD_PAD, "bad pad number (%d)", pad); + + if ((padStrength < PI_MIN_PAD_STRENGTH) || + (padStrength > PI_MAX_PAD_STRENGTH)) + SOFT_ERROR(PI_BAD_STRENGTH, "bad pad drive strength (%d)", pad); + + /* 1-16 -> 0-7 */ + + padStrength += 1; + padStrength /= 2; + padStrength -= 1; + + padsReg[11+pad] = BCM_PASSWD | 0x18 | (padStrength & 7) ; + + return 0; +} + +int gpioGetPad(unsigned pad) +{ + int strength; + + DBG(DBG_USER, "pad=%d", pad); + + CHECK_INITED; + + if (pad > PI_MAX_PAD) + SOFT_ERROR(PI_BAD_PAD, "bad pad (%d)", pad); + + strength = padsReg[11+pad] & 7; + + strength *= 2; + strength += 2; + + return strength; +} + +int shell(char *scriptName, char *scriptString) +{ + int status; + char buf[4096]; + + DBG(DBG_USER, "name=%s string=%s", scriptName, scriptString); + + CHECK_INITED; + + if (!myScriptNameValid(scriptName)) + SOFT_ERROR(PI_BAD_SCRIPT_NAME, "bad script name (%s)", scriptName); + + snprintf(buf, sizeof(buf), + "/opt/pigpio/cgi/%s %s", scriptName, scriptString); + + DBG(DBG_USER, "%s", buf); + + status = system(buf); + + if (status < 0) status = PI_BAD_SHELL_STATUS; + + return status; +} + + +int fileApprove(char *filename) +{ + char match[PI_MAX_PATH]; + char buffer[PI_MAX_PATH]; + char line[PI_MAX_PATH]; + char mperm; + char perm; + char term; + FILE *f; + + buffer[0] = 0; + match[0] = 0; + + f = fopen("/opt/pigpio/access", "r"); + + if (!f) return PI_FILE_NONE; + + while (!feof(f)) + { + buffer[0] = 0; + perm = 0; + term = 0; + if (fgets(line, sizeof(line), f)) + { + sscanf(line, " %511s %c%c", buffer, &perm, &term); + if (term == 10) + { + if (myPathBad(buffer)) continue; /* disallow risky lines */ + + if (fnmatch(buffer, filename, 0) == 0) + { + if (match[0]) + { + if (fnmatch(match, buffer, 0) == 0) + { + strcpy(match, buffer); + mperm = perm; + } + } + else + { + strcpy(match, buffer); + mperm = perm; + } + } + } + } + } + + fclose(f); + + if (match[0]) + { + switch (toupper(mperm)) + { + case 'R': return PI_FILE_READ; + case 'W': return PI_FILE_WRITE; + case 'U': return PI_FILE_RW; + default : return PI_FILE_NONE; + } + } + + return PI_FILE_NONE; +} + +int fileOpen(char *file, unsigned mode) +{ + int fd=-1; + int i, slot, oflag, omode; + struct stat statbuf; + + DBG(DBG_USER, "file=%s mode=%d", file, mode); + + CHECK_INITED; + + if ( (mode < PI_FILE_MIN) || + (mode > PI_FILE_MAX) || + ((mode & PI_FILE_RW) == 0) ) + SOFT_ERROR(PI_BAD_FILE_MODE, "bad mode (%d)", mode); + + if ((fileApprove(file) & mode) == PI_FILE_NONE) + SOFT_ERROR(PI_NO_FILE_ACCESS, "no permission to access file (%s)", file); + + slot = -1; + + for (i=0; i= PI_FILE_SLOTS) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (fileInfo[handle].state != PI_FILE_OPENED) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (fileInfo[handle].fd >= 0) close(fileInfo[handle].fd); + + fileInfo[handle].fd = -1; + fileInfo[handle].state = PI_FILE_CLOSED; + + return 0; +} + +int fileWrite(unsigned handle, char *buf, unsigned count) +{ + int w; + + DBG(DBG_USER, "handle=%d count=%d [%s]", + handle, count, myBuf2Str(count, buf)); + + CHECK_INITED; + + if (handle >= PI_FILE_SLOTS) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (fileInfo[handle].state != PI_FILE_OPENED) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (!count) + SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count); + + if (!(fileInfo[handle].mode & PI_FILE_WRITE)) + SOFT_ERROR(PI_FILE_NOT_WOPEN, "file not opened for write"); + + w = write(fileInfo[handle].fd, buf, count); + + if (w != count) + { + if (w == -1) DBG(DBG_USER, "write failed with errno %d", errno); + + return PI_BAD_FILE_WRITE; + } + return 0; +} + +int fileRead(unsigned handle, char *buf, unsigned count) +{ + int r; + + DBG(DBG_USER, "handle=%d count=%d buf=0x%X", handle, count, (unsigned)buf); + + CHECK_INITED; + + if (handle >= PI_FILE_SLOTS) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (fileInfo[handle].state != PI_FILE_OPENED) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (!count) + SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count); + + if (!(fileInfo[handle].mode & PI_FILE_READ)) + SOFT_ERROR(PI_FILE_NOT_ROPEN, "file not opened for read"); + + r = read(fileInfo[handle].fd, buf, count); + + if (r == -1) + { + DBG(DBG_USER, "read failed with errno %d", errno); + return PI_BAD_FILE_READ; + } + else + { + buf[r] = 0; + return r; + } +} + + +int fileSeek(unsigned handle, int32_t seekOffset, int seekFrom) +{ + int whence, s; + + DBG(DBG_USER, "handle=%d offset=%d from=%d", + handle, seekOffset, seekFrom); + + CHECK_INITED; + + if (handle >= PI_FILE_SLOTS) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (fileInfo[handle].state != PI_FILE_OPENED) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + switch (seekFrom) + { + case PI_FROM_START: + whence = SEEK_SET; + break; + + case PI_FROM_CURRENT: + whence = SEEK_CUR; + break; + + case PI_FROM_END: + whence = SEEK_END; + break; + + default: + SOFT_ERROR(PI_BAD_FILE_SEEK, "bad seek from (%d)", seekFrom); + } + + s = lseek(fileInfo[handle].fd, seekOffset, whence); + + if (s == -1) + { + DBG(DBG_USER, "seek failed with errno %d", errno); + return PI_BAD_FILE_SEEK; + } + + return s; +} + +int fileList(char *fpat, char *buf, unsigned count) +{ + int len, bufpos; + glob_t pglob; + int i; + + DBG(DBG_USER, "fpat=%s count=%d buf=%x", fpat, count, (unsigned)buf); + + CHECK_INITED; + + if (fileApprove(fpat) == PI_FILE_NONE) + SOFT_ERROR(PI_NO_FILE_ACCESS, "no permission to access file (%s)", fpat); + + bufpos = 0; + + if (glob(fpat, GLOB_MARK, NULL, &pglob) == 0) + { + for (i=0; i #include #include -#define PIGPIO_VERSION 54 +#define PIGPIO_VERSION 55 /*TEXT @@ -39,9 +39,9 @@ pigpio is a C library for the Raspberry which allows control of the GPIO. *Features* -o PWM on any of GPIO 0-31 +o hardware timed PWM on any of GPIO 0-31 -o servo pulses on any of GPIO 0-31 +o hardware timed servo pulses on any of GPIO 0-31 o callbacks when any of GPIO 0-31 change state @@ -198,6 +198,11 @@ gpioHardwarePWM Start hardware PWM on supported GPIO gpioGlitchFilter Set a glitch filter on a GPIO gpioNoiseFilter Set a noise filter on a GPIO +gpioGetPad Gets a pads drive strength +gpioSetPad Sets a pads drive strength + +shell Executes a shell command + SCRIPTS gpioStoreScript Store a script @@ -282,16 +287,25 @@ spiXfer Transfers bytes with a SPI device SERIAL -serOpen Opens a serial device (/dev/tty*) +serOpen Opens a serial device serClose Closes a serial device -serWriteByte Writes a byte to a serial device serReadByte Reads a byte from a serial device -serWrite Writes bytes to a serial device +serWriteByte Writes a byte to a serial device serRead Reads bytes from a serial device +serWrite Writes bytes to a serial device serDataAvailable Returns number of bytes ready to be read +FILES + +fileOpen Opens a file +fileClose Closes a file +fileRead Reads bytes from a file +fileWrite Writes bytes to a file +fileSeek Seeks to a position within a file +fileList List files which match a pattern + CONFIGURATION gpioCfgBufferSize Configure the GPIO sample buffer size @@ -617,8 +631,9 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_WAVE_NOT_FOUND 9998 /* Transmitted wave not found. */ #define PI_NO_TX_WAVE 9999 /* No wave being transmitted. */ -/* I2C, SPI, SER */ +/* Files, I2C, SPI, SER */ +#define PI_FILE_SLOTS 8 #define PI_I2C_SLOTS 32 #define PI_SPI_SLOTS 16 #define PI_SER_SLOTS 8 @@ -773,6 +788,29 @@ typedef void *(gpioThreadFunc_t) (void *); #define EITHER_EDGE 2 +/* pads */ + +#define PI_MAX_PAD 2 + +#define PI_MIN_PAD_STRENGTH 1 +#define PI_MAX_PAD_STRENGTH 16 + +/* files */ + +#define PI_FILE_NONE 0 +#define PI_FILE_MIN 1 +#define PI_FILE_READ 1 +#define PI_FILE_WRITE 2 +#define PI_FILE_RW 3 +#define PI_FILE_APPEND 4 +#define PI_FILE_CREATE 8 +#define PI_FILE_TRUNC 16 +#define PI_FILE_MAX 31 + +#define PI_FROM_START 0 +#define PI_FROM_CURRENT 1 +#define PI_FROM_END 2 + /*F*/ int gpioInitialise(void); /*D @@ -835,11 +873,11 @@ Returns 0 if OK, otherwise PI_BAD_GPIO or PI_BAD_MODE. Arduino style: pinMode. ... -gpioSetMode(17, PI_INPUT); // Set gpio17 as input. +gpioSetMode(17, PI_INPUT); // Set GPIO17 as input. -gpioSetMode(18, PI_OUTPUT); // Set gpio18 as output. +gpioSetMode(18, PI_OUTPUT); // Set GPIO18 as output. -gpioSetMode(22,PI_ALT0); // Set gpio22 to alternative mode 0. +gpioSetMode(22,PI_ALT0); // Set GPIO22 to alternative mode 0. ... D*/ @@ -858,7 +896,7 @@ Returns the GPIO mode if OK, otherwise PI_BAD_GPIO. ... if (gpioGetMode(17) != PI_ALT0) { - gpioSetMode(17, PI_ALT0); // set gpio17 to ALT0 + gpioSetMode(17, PI_ALT0); // set GPIO17 to ALT0 } ... D*/ @@ -900,7 +938,7 @@ Returns the GPIO level if OK, otherwise PI_BAD_GPIO. Arduino style: digitalRead. ... -printf("gpio24 is level %d", gpioRead(24)); +printf("GPIO24 is level %d", gpioRead(24)); ... D*/ @@ -922,7 +960,7 @@ If PWM or servo pulses are active on the GPIO they are switched off. Arduino style: digitalWrite ... -gpioWrite(24, 1); // Set gpio24 high. +gpioWrite(24, 1); // Set GPIO24 high. ... D*/ @@ -949,11 +987,11 @@ The [*gpioSetPWMrange*] function may be used to change the default range of 255. ... -gpioPWM(17, 255); // Sets gpio17 full on. +gpioPWM(17, 255); // Sets GPIO17 full on. -gpioPWM(18, 128); // Sets gpio18 half on. +gpioPWM(18, 128); // Sets GPIO18 half on. -gpioPWM(23, 0); // Sets gpio23 full off. +gpioPWM(23, 0); // Sets GPIO23 full off. ... D*/ @@ -1107,11 +1145,11 @@ sample . . ... -gpioSetPWMfrequency(23, 0); // Set gpio23 to lowest frequency. +gpioSetPWMfrequency(23, 0); // Set GPIO23 to lowest frequency. -gpioSetPWMfrequency(24, 500); // Set gpio24 to 500Hz. +gpioSetPWMfrequency(24, 500); // Set GPIO24 to 500Hz. -gpioSetPWMfrequency(25, 100000); // Set gpio25 to highest frequency. +gpioSetPWMfrequency(25, 100000); // Set GPIO25 to highest frequency. ... D*/ @@ -1136,7 +1174,7 @@ If hardware PWM is active on the GPIO the reported frequency will be that set by [*gpioHardwarePWM*]. ... -f = gpioGetPWMfrequency(23); // Get frequency used for gpio23. +f = gpioGetPWMfrequency(23); // Get frequency used for GPIO23. ... D*/ @@ -1187,7 +1225,7 @@ Then set the PWM range using [*gpioSetPWMrange*] to 1E6/frequency. Doing this allows you to use units of microseconds when setting the servo pulsewidth. -E.g. If you want to update a servo connected to gpio25 at 400Hz +E.g. If you want to update a servo connected to GPIO25 at 400Hz . . gpioSetPWMfrequency(25, 400); @@ -1474,11 +1512,13 @@ seqno: starts at 0 each time the handle is opened and then increments by one for each report. flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. -If bit 5 is set (PI_NTFY_FLAGS_WDOG) then bits 0-4 of the flags -indicate a GPIO which has had a watchdog timeout; if bit 6 is set -(PI_NTFY_FLAGS_ALIVE) this indicates a keep alive signal on the -pipe/socket and is sent once a minute in the absence of other -notification activity. + +PI_NTFY_FLAGS_WDOG, if bit 5 is set then bits 0-4 of the flags +indicate a GPIO which has had a watchdog timeout. + +PI_NTFY_FLAGS_ALIVE, if bit 6 is set this indicates a keep alive +signal on the pipe/socket and is sent once a minute in the absence +of other notification activity. tick: the number of microseconds since system boot. It wraps around after 1h12m. @@ -2011,7 +2051,7 @@ int gpioSerialReadInvert(unsigned user_gpio, unsigned invert); /*D This function configures the level logic for bit bang serial reads. -Pass PI_BB_SER_INVERT to invert the serial logic. Pass PI_BB_SER_NORMAL for +Use PI_BB_SER_INVERT to invert the serial logic and PI_BB_SER_NORMAL for normal logic. Default is PI_BB_SER_NORMAL. . . @@ -2798,10 +2838,11 @@ D*/ int serOpen(char *sertty, unsigned baud, unsigned serFlags); /*D This function opens a serial device at a specified baud rate -with specified flags. +and with specified flags. The device name must start with +/dev/tty or /dev/serial. . . - sertty: the serial device to open, /dev/tty* + sertty: the serial device to open baud: the baud rate in bits per second, see below serFlags: 0 . . @@ -2879,13 +2920,13 @@ This function reads up count bytes from the the serial port associated with handle and writes them to buf. . . -handle: >=0, as returned by a call to serial_open +handle: >=0, as returned by a call to [*serOpen*] buf: an array to receive the read data count: the maximum number of bytes to read . . Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE, -PI_BAD_PARAM, PI_SER_READ_NO_DATA, or PI_SER_WRITE_FAILED. +PI_BAD_PARAM, or PI_SER_READ_NO_DATA. D*/ @@ -3631,6 +3672,358 @@ Returns the pigpio version. D*/ +/*F*/ +int gpioGetPad(unsigned pad); +/*D +This function returns the pad drive strength in mA. + +. . +pad: 0-2, the pad to get +. . + +Returns the pad drive strength if OK, otherwise PI_BAD_PAD. + +Pad @ GPIO +0 @ 0-27 +1 @ 28-45 +2 @ 46-53 + +... +strength = gpioGetPad(1); // get pad 1 strength +... +D*/ + + +/*F*/ +int gpioSetPad(unsigned pad, unsigned padStrength); +/*D +This function sets the pad drive strength in mA. + +. . + pad: 0-2, the pad to set +padStrength: 1-16 mA +. . + +Returns 0 if OK, otherwise PI_BAD_PAD, or PI_BAD_STRENGTH. + +Pad @ GPIO +0 @ 0-27 +1 @ 28-45 +2 @ 46-53 + +... +gpioSetPad(0, 16); // set pad 0 strength to 16 mA +... +D*/ + + +/*F*/ +int shell(char *scriptName, char *scriptString); +/*D +This function uses the system call to execute a shell script +with the given string as its parameter. + +. . + scriptName: the name of the script, only alphanumeric characters, + '-' and '_' are allowed in the name +scriptString: the string to pass to the script +. . + +The exit status of the system call is returned if OK, otherwise +PI_BAD_SHELL_STATUS. + +scriptName must exist in /opt/pigpio/cgi and must be executable. + +The returned exit status is normally 256 times that set by the +shell script exit function. If the script can't be found 32512 will +be returned. + +The following table gives some example returned statuses. + +Script exit status @ Returned system call status +1 @ 256 +5 @ 1280 +10 @ 2560 +200 @ 51200 +script not found @ 32512 + +... +// pass two parameters, hello and world +status = shell("scr1", "hello world"); + +// pass three parameters, hello, string with spaces, and world +status = shell("scr1", "hello 'string with spaces' world"); + +// pass one parameter, hello string with spaces world +status = shell("scr1", "\"hello string with spaces world\""); +... +D*/ + +#pragma GCC diagnostic push + +#pragma GCC diagnostic ignored "-Wcomment" + +/*F*/ +int fileOpen(char *file, unsigned mode); +/*D +This function returns a handle to a file opened in a specified mode. + +. . +file: the file to open +mode: the file open mode +. . + +Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, PI_NO_FILE_ACCESS, +PI_BAD_FILE_MODE, PI_FILE_OPEN_FAILED, or PI_FILE_IS_A_DIR. + +File + +A file may only be opened if permission is granted by an entry in +/opt/pigpio/access. This is intended to allow remote access to files +in a more or less controlled manner. + +Each entry in /opt/pigpio/access takes the form of a file path +which may contain wildcards followed by a single letter permission. +The permission may be R for read, W for write, U for read/write, +and N for no access. + +Where more than one entry matches a file the most specific rule +applies. If no entry matches a file then access is denied. + +Suppose /opt/pigpio/access contains the following entries + +. . +/home/* n +/home/pi/shared/dir_1/* w +/home/pi/shared/dir_2/* r +/home/pi/shared/dir_3/* u +/home/pi/shared/dir_1/file.txt n +. . + +Files may be written in directory dir_1 with the exception +of file.txt. + +Files may be read in directory dir_2. + +Files may be read and written in directory dir_3. + +If a directory allows read, write, or read/write access then files may +be created in that directory. + +In an attempt to prevent risky permissions the following paths are +ignored in /opt/pigpio/access. + +. . +a path containing .. +a path containing only wildcards (*?) +a path containing less than two non-wildcard parts +. . + +Mode + +The mode may have the following values. + +Macro @ Value @ Meaning +PI_FILE_READ @ 1 @ open file for reading +PI_FILE_WRITE @ 2 @ open file for writing +PI_FILE_RW @ 3 @ open file for reading and writing + +The following values may be or'd into the mode. + +Macro @ Value @ Meaning +PI_FILE_APPEND @ 4 @ Writes append data to the end of the file +PI_FILE_CREATE @ 8 @ The file is created if it doesn't exist +PI_FILE_TRUNC @ 16 @ The file is truncated + +Newly created files are owned by root with permissions owner read and write. + +... +#include +#include + +int main(int argc, char *argv[]) +{ + int handle, c; + char buf[60000]; + + if (gpioInitialise() < 0) return 1; + + // assumes /opt/pigpio/access contains the following line + // /ram/*.c r + + handle = fileOpen("/ram/pigpio.c", PI_FILE_READ); + + if (handle >= 0) + { + while ((c=fileRead(handle, buf, sizeof(buf)-1))) + { + buf[c] = 0; + printf("%s", buf); + } + + fileClose(handle); + } + + gpioTerminate(); +} +... +D*/ + +#pragma GCC diagnostic pop + +/*F*/ +int fileClose(unsigned handle); +/*D +This function closes the file associated with handle. + +. . +handle: >=0, as returned by a call to [*fileOpen*] +. . + +Returns 0 if OK, otherwise PI_BAD_HANDLE. + +... +fileClose(h); +... +D*/ + + +/*F*/ +int fileWrite(unsigned handle, char *buf, unsigned count); +/*D +This function writes count bytes from buf to the the file +associated with handle. + +. . +handle: >=0, as returned by a call to [*fileOpen*] + buf: the array of bytes to write + count: the number of bytes to write +. . + +Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, +PI_FILE_NOT_WOPEN, or PI_BAD_FILE_WRITE. + +... +status = fileWrite(h, buf, count); +if (status == 0) +{ + // okay +} +else +{ + // error +} +... +D*/ + + +/*F*/ +int fileRead(unsigned handle, char *buf, unsigned count); +/*D +This function reads up to count bytes from the the file +associated with handle and writes them to buf. + +. . +handle: >=0, as returned by a call to [*fileOpen*] + buf: an array to receive the read data + count: the maximum number of bytes to read +. . + +Returns the number of bytes read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, PI_FILE_NOT_ROPEN, or PI_BAD_FILE_WRITE. + +... +if (fileRead(h, buf, sizeof(buf)) > 0) +{ + // process read data +} +... +D*/ + + +/*F*/ +int fileSeek(unsigned handle, int32_t seekOffset, int seekFrom); +/*D +This function seeks to a position within the file associated +with handle. + +. . + handle: >=0, as returned by a call to [*fileOpen*] +seekOffset: the number of bytes to move. Positive offsets + move forward, negative offsets backwards. + seekFrom: one of PI_FROM_START (0), PI_FROM_CURRENT (1), + or PI_FROM_END (2) +. . + +Returns the new byte position within the file (>=0) if OK, otherwise PI_BAD_HANDLE, or PI_BAD_FILE_SEEK. + +... +fileSeek(0, 20, PI_FROM_START); // Seek to start plus 20 + +size = fileSeek(0, 0, PI_FROM_END); // Seek to end, return size + +pos = fileSeek(0, 0, PI_FROM_CURRENT); // Return current position +... +D*/ + +#pragma GCC diagnostic push + +#pragma GCC diagnostic ignored "-Wcomment" + +/*F*/ +int fileList(char *fpat, char *buf, unsigned count); +/*D +This function returns a list of files which match a pattern. The +pattern may contain wildcards. + +. . + fpat: file pattern to match + buf: an array to receive the matching file names +count: the maximum number of bytes to read +. . + +Returns the number of returned bytes if OK, otherwise PI_NO_FILE_ACCESS, +or PI_NO_FILE_MATCH. + +The pattern must match an entry in /opt/pigpio/access. The pattern +may contain wildcards. See [*fileOpen*]. + +NOTE + +The returned value is not the number of files, it is the number +of bytes in the buffer. The file names are separated by newline +characters. + +... +#include +#include + +int main(int argc, char *argv[]) +{ + int c; + char buf[1000]; + + if (gpioInitialise() < 0) return 1; + + // assumes /opt/pigpio/access contains the following line + // /ram/*.c r + + c = fileList("/ram/p*.c", buf, sizeof(buf)); + + if (c >= 0) + { + // terminate string + buf[c] = 0; + printf("%s", buf); + } + + gpioTerminate(); +} +... +D*/ + +#pragma GCC diagnostic pop + + /*F*/ int gpioCfgBufferSize(unsigned cfgMillis); /*D @@ -4219,7 +4612,6 @@ PI_HW_CLK_MAX_FREQ 250000000 . . count:: - The number of bytes to be transferred in an I2C, SPI, or Serial command. @@ -4251,7 +4643,7 @@ The number may vary between 0 and range (default 255) where 0 is off and range is fully on. edge::0-2 -The type of GPIO edge to generate an intrrupt. See[*gpioSetISRFunc*], +The type of GPIO edge to generate an intrrupt. See [*gpioSetISRFunc*], and [*gpioSetISRFuncEx*]. . . @@ -4264,6 +4656,14 @@ f:: A function. +*file:: +A full file path. To be accessible the path must match an entry in +/opt/pigpio/access. + +*fpat:: +A file path which may contain wildcards. To be accessible the path +must match an entry in /opt/pigpio/access. + frequency::>=0 The number of times a GPIO is swiched on and off per second. This @@ -4275,11 +4675,11 @@ gpio:: A Broadcom numbered GPIO, in the range 0-53. -There are 54 General Purpose Input Outputs (GPIO) named gpio0 through -gpio53. +There are 54 General Purpose Input Outputs (GPIO) named GPIO0 through +GPIO53. -They are split into two banks. Bank 1 consists of gpio0 through -gpio31. Bank 2 consists of gpio32 through gpio53. +They are split into two banks. Bank 1 consists of GPIO0 through +GPIO31. Bank 2 consists of GPIO32 through GPIO53. All the GPIO which are safe for the user to read and write are in bank 1. Not all GPIO in bank 1 are safe though. Type 1 boards @@ -4403,12 +4803,8 @@ One of handle::>=0 -A number referencing an object opened by one of - -[*i2cOpen*] -[*gpioNotifyOpen*] -[*serOpen*] -[*spiOpen*] +A number referencing an object opened by one of [*fileOpen*], +[*gpioNotifyOpen*], [*i2cOpen*], [*serOpen*], [*spiOpen*]. i2cAddr:: 0-0x7F The address of a device on the I2C bus. @@ -4440,6 +4836,9 @@ The number of bytes of data in a buffer. int:: A whole number, negative or positive. +int32_t:: +A 32-bit signed value. + invert:: A flag used to set normal or inverted bit bang serial data level logic. @@ -4491,9 +4890,9 @@ millis:: A value representing milliseconds. -mode::0-7 +mode:: -The operational mode of a GPIO, normally INPUT or OUTPUT. +1. The operational mode of a GPIO, normally INPUT or OUTPUT. . . PI_INPUT 0 @@ -4506,6 +4905,22 @@ PI_ALT4 3 PI_ALT5 2 . . +2. A file open mode. + +. . +PI_FILE_READ 1 +PI_FILE_WRITE 2 +PI_FILE_RW 3 +. . + +The following values can be or'd into the mode. + +. . +PI_FILE_APPEND 4 +PI_FILE_CREATE 8 +PI_FILE_TRUNC 16 +. . + numBits:: The number of bits stored in a buffer. @@ -4534,6 +4949,18 @@ A buffer used to return data from a function. outLen:: The size in bytes of an output buffer. +pad:: 0-2 +A set of GPIO which share common drivers. + +Pad @ GPIO +0 @ 0-27 +1 @ 28-45 +2 @ 46-53 + +padStrength:: 1-16 +The mA which may be drawn from each GPIO whilst still guaranteeing the +high and low levels. + *param:: An array of script parameters. @@ -4680,19 +5107,22 @@ The maximum number of bytes a user customised function should return. A pointer to a buffer to receive data. SCL:: - The user GPIO to use for the clock when bit banging I2C. *script:: - A pointer to the text of a script. script_id:: - An id of a stored script as returned by [*gpioStoreScript*]. -SDA:: +*scriptName:: +The name of a [*shell*] script to be executed. The script must be present in +/opt/pigpio/cgi and must have execute permission. +*scriptString:: +The string to be passed to a [*shell*] script to be executed. + +SDA:: The user GPIO to use for data when bit banging I2C. secondaryChannel:: 0-6 @@ -4705,11 +5135,21 @@ A pointer to a uint32_t to store the second component of a returned time. seconds:: - The number of seconds. -*segs:: +seekFrom:: +. . +PI_FROM_START 0 +PI_FROM_CURRENT 1 +PI_FROM_END 2 +. . + +seekOffset:: +The number of bytes to move forward (positive) or backwards (negative) +from the seek position (start, current, or end of file). + +*segs:: An array of segments which make up a combined I2C transaction. serFlags:: @@ -4830,7 +5270,6 @@ user_gpio:: See [*gpio*]. *userdata:: - A pointer to arbitrary user data. This may be used to identify the instance. You must ensure that the pointer is in scope at the time it is processed. If @@ -4999,6 +5438,18 @@ PARAMS*/ #define PI_CMD_WVTXM 100 #define PI_CMD_WVTAT 101 +#define PI_CMD_PADS 102 +#define PI_CMD_PADG 103 + +#define PI_CMD_FO 104 +#define PI_CMD_FC 105 +#define PI_CMD_FR 106 +#define PI_CMD_FW 107 +#define PI_CMD_FS 108 +#define PI_CMD_FL 109 + +#define PI_CMD_SHELL 110 + /*DEF_E*/ /* @@ -5099,7 +5550,7 @@ after this command is issued. #define PI_BAD_WAVE_BAUD -35 // baud rate not 50-250K(RX)/50-1M(TX) #define PI_TOO_MANY_PULSES -36 // waveform has too many pulses #define PI_TOO_MANY_CHARS -37 // waveform has too many chars -#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read in progress on GPIO +#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read on GPIO #define PI_BAD_SERIAL_STRUC -39 // bad (null) serial structure parameter #define PI_BAD_SERIAL_BUF -40 // bad (null) serial buf parameter #define PI_NOT_PERMITTED -41 // GPIO operation not permitted @@ -5186,8 +5637,23 @@ after this command is issued. #define PI_BAD_SER_INVERT -121 // bit bang serial invert not 0 or 1 #define PI_BAD_EDGE -122 // bad ISR edge value, not 0-2 #define PI_BAD_ISR_INIT -123 // bad ISR initialisation -#define PI_BAD_FOREVER -124 // loop forever must be last chain command +#define PI_BAD_FOREVER -124 // loop forever must be last command #define PI_BAD_FILTER -125 // bad filter parameter +#define PI_BAD_PAD -126 // bad pad number +#define PI_BAD_STRENGTH -127 // bad pad drive strength +#define PI_FIL_OPEN_FAILED -128 // file open failed +#define PI_BAD_FILE_MODE -129 // bad file mode +#define PI_BAD_FILE_FLAG -130 // bad file flag +#define PI_BAD_FILE_READ -131 // bad file read +#define PI_BAD_FILE_WRITE -132 // bad file write +#define PI_FILE_NOT_ROPEN -133 // file not open for read +#define PI_FILE_NOT_WOPEN -134 // file not open for write +#define PI_BAD_FILE_SEEK -135 // bad file seek +#define PI_NO_FILE_MATCH -136 // no files match pattern +#define PI_NO_FILE_ACCESS -137 // no permission to access file +#define PI_FILE_IS_A_DIR -138 // file is a directory +#define PI_BAD_SHELL_STATUS -139 // bad shell return status +#define PI_BAD_SCRIPT_NAME -140 // bad script name #define PI_PIGIF_ERR_0 -2000 #define PI_PIGIF_ERR_99 -2099 diff --git a/pigpio.py b/pigpio.py index 55bdc75..0fdddba 100644 --- a/pigpio.py +++ b/pigpio.py @@ -11,9 +11,9 @@ o the pigpio Python module can run on Windows, Macs, or Linux o controls one or more Pi's -o independent PWM on any of GPIO 0-31 simultaneously +o hardware timed PWM on any of GPIO 0-31 -o independent servo pulses on any of GPIO 0-31 simultaneously +o hardware timed servo pulses on any of GPIO 0-31 o callbacks when any of GPIO 0-31 change state @@ -159,6 +159,11 @@ hardware_PWM Start hardware PWM on supported GPIO set_glitch_filter Set a glitch filter on a GPIO set_noise_filter Set a noise filter on a GPIO +get_pad_strength Gets a pads drive strength +set_pad_strength Sets a pads drive strength + +shell Executes a shell command + Scripts store_script Store a script @@ -235,7 +240,7 @@ spi_xfer Transfers bytes with a SPI device Serial -serial_open Opens a serial device (/dev/tty*) +serial_open Opens a serial device serial_close Closes a serial device serial_read Reads bytes from a serial device @@ -246,7 +251,16 @@ serial_write_byte Writes a byte to a serial device serial_data_available Returns number of bytes ready to be read -CUSTOM +Files + +file_open Opens a file +file_close Closes a file +file_read Reads bytes from a file +file_write Writes bytes to a file +file_seek Seeks to a position within a file +file_list List files which match a pattern + +Custom custom_1 User custom function 1 custom_2 User custom function 2 @@ -270,7 +284,7 @@ import threading import os import atexit -VERSION = "1.31" +VERSION = "1.32" exceptions = True @@ -333,6 +347,18 @@ WAVE_MODE_REPEAT_SYNC =3 WAVE_NOT_FOUND = 9998 # Transmitted wave not found. NO_TX_WAVE = 9999 # No wave being transmitted. +FILE_READ=1 +FILE_WRITE=2 +FILE_RW=3 + +FILE_APPEND=4 +FILE_CREATE=8 +FILE_TRUNC=16 + +FROM_START=0 +FROM_CURRENT=1 +FROM_END=2 + # pigpio command numbers _PI_CMD_MODES= 0 @@ -460,6 +486,17 @@ _PI_CMD_FN =98 _PI_CMD_WVTXM=100 _PI_CMD_WVTAT=101 +_PI_CMD_PADS =102 +_PI_CMD_PADG =103 + +_PI_CMD_FO =104 +_PI_CMD_FC =105 +_PI_CMD_FR =106 +_PI_CMD_FW =107 +_PI_CMD_FS =108 +_PI_CMD_FL =109 +_PI_CMD_SHELL=110 + # pigpio error numbers _PI_INIT_FAILED =-1 @@ -588,7 +625,21 @@ _PI_BAD_EDGE =-122 _PI_BAD_ISR_INIT =-123 PI_BAD_FOREVER =-124 PI_BAD_FILTER =-125 - +PI_BAD_PAD =-126 +PI_BAD_STRENGTH =-127 +PI_FIL_OPEN_FAILED =-128 +PI_BAD_FILE_MODE =-129 +PI_BAD_FILE_FLAG =-130 +PI_BAD_FILE_READ =-131 +PI_BAD_FILE_WRITE =-132 +PI_FILE_NOT_ROPEN =-133 +PI_FILE_NOT_WOPEN =-134 +PI_BAD_FILE_SEEK =-135 +PI_NO_FILE_MATCH =-136 +PI_NO_FILE_ACCESS =-137 +PI_FILE_IS_A_DIR =-138 +PI_BAD_SHELL_STATUS =-139 +PI_BAD_SCRIPT_NAME =-140 # pigpio error text @@ -716,6 +767,21 @@ _errors=[ [_PI_BAD_ISR_INIT , "bad ISR initialisation"], [PI_BAD_FOREVER , "loop forever must be last chain command"], [PI_BAD_FILTER , "bad filter parameter"], + [PI_BAD_PAD , "bad pad number"], + [PI_BAD_STRENGTH , "bad pad drive strength"], + [PI_FIL_OPEN_FAILED , "file open failed"], + [PI_BAD_FILE_MODE , "bad file mode"], + [PI_BAD_FILE_FLAG , "bad file flag"], + [PI_BAD_FILE_READ , "bad file read"], + [PI_BAD_FILE_WRITE , "bad file write"], + [PI_FILE_NOT_ROPEN , "file not open for read"], + [PI_FILE_NOT_WOPEN , "file not open for write"], + [PI_BAD_FILE_SEEK , "bad file seek"], + [PI_NO_FILE_MATCH , "no files match pattern"], + [PI_NO_FILE_ACCESS , "no permission to access file"], + [PI_FILE_IS_A_DIR , "file is a directory"], + [PI_BAD_SHELL_STATUS , "bad shell return status"], + [PI_BAD_SCRIPT_NAME , "bad script name"], ] @@ -1396,8 +1462,8 @@ class pi(): Notifications have the following structure. . . - I seqno - I flags + H seqno + H flags I tick I level . . @@ -1406,11 +1472,14 @@ class pi(): increments by one for each report. flags: two flags are defined, PI_NTFY_FLAGS_WDOG and - PI_NTFY_FLAGS_ALIVE. If bit 5 is set (PI_NTFY_FLAGS_WDOG) - then bits 0-4 of the flags indicate a GPIO which has had a - watchdog timeout; if bit 6 is set (PI_NTFY_FLAGS_ALIVE) this - indicates a keep alive signal on the pipe/socket and is sent - once a minute in the absence of other notification activity. + PI_NTFY_FLAGS_ALIVE. + + PI_NTFY_FLAGS_WDOG, if bit 5 is set then bits 0-4 of the + flags indicate a GPIO which has had a watchdog timeout. + + PI_NTFY_FLAGS_ALIVE, if bit 6 is set this indicates a keep + alive signal on the pipe/socket and is sent once a minute + in the absence of other notification activity. tick: the number of microseconds since system boot. It wraps around after 1h12m. @@ -3215,7 +3284,8 @@ class pi(): def serial_open(self, tty, baud, ser_flags=0): """ Returns a handle for the serial tty device opened - at baud bits per second. + at baud bits per second. The device name must start + with /dev/tty or /dev/serial. tty:= the serial device to open. baud:= baud rate in bits per second, see below. @@ -3234,6 +3304,8 @@ class pi(): h1 = pi.serial_open("/dev/ttyAMA0", 300) h2 = pi.serial_open("/dev/ttyUSB1", 19200, 0) + + h3 = pi.serial_open("/dev/serial0", 9600) ... """ # I p1 baud @@ -3646,6 +3718,7 @@ class pi(): """ return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRI, user_gpio, invert)) + def custom_1(self, arg1=0, arg2=0, argx=[]): """ Calls a pigpio function customised by the user. @@ -3721,6 +3794,360 @@ class pi(): self.sl.l.release() return bytes, data + def get_pad_strength(self, pad): + """ + This function returns the pad drive strength in mA. + + pad:= 0-2, the pad to get. + + Returns the pad drive strength if OK, otherwise PI_BAD_PAD. + + Pad @ GPIO + 0 @ 0-27 + 1 @ 28-45 + 2 @ 46-53 + + ... + strength = pi.get_pad_strength(0) # Get pad 0 strength. + ... + """ + return _u2i(_pigpio_command(self.sl, _PI_CMD_PADG, pad, 0)) + + def set_pad_strength(self, pad, pad_strength): + """ + This function sets the pad drive strength in mA. + + + pad:= 0-2, the pad to set. + pad_strength:= 1-16 mA. + + Returns 0 if OK, otherwise PI_BAD_PAD, or PI_BAD_STRENGTH. + + Pad @ GPIO + 0 @ 0-27 + 1 @ 28-45 + 2 @ 46-53 + + ... + pi.set_pad_strength(2, 14) # Set pad 2 to 14 mA. + ... + """ + return _u2i(_pigpio_command(self.sl, _PI_CMD_PADS, pad, pad_strength)) + + + def file_open(self, file_name, file_mode): + """ + This function returns a handle to a file opened in a specified mode. + + file_name:= the file to open. + file_mode:= the file open mode. + + Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, PI_NO_FILE_ACCESS, + PI_BAD_FILE_MODE, PI_FILE_OPEN_FAILED, or PI_FILE_IS_A_DIR. + + ... + h = pi.file_open("/home/pi/shared/dir_3/file.txt", + pigpio.FILE_WRITE | pigpio.FILE_CREATE) + + pi.file_write(h, "Hello world") + + pi.file_close(h) + ... + + File + + A file may only be opened if permission is granted by an entry in + /opt/pigpio/access. This is intended to allow remote access to files + in a more or less controlled manner. + + Each entry in /opt/pigpio/access takes the form of a file path + which may contain wildcards followed by a single letter permission. + The permission may be R for read, W for write, U for read/write, + and N for no access. + + Where more than one entry matches a file the most specific rule + applies. If no entry matches a file then access is denied. + + Suppose /opt/pigpio/access contains the following entries + + . . + /home/* n + /home/pi/shared/dir_1/* w + /home/pi/shared/dir_2/* r + /home/pi/shared/dir_3/* u + /home/pi/shared/dir_1/file.txt n + . . + + Files may be written in directory dir_1 with the exception + of file.txt. + + Files may be read in directory dir_2. + + Files may be read and written in directory dir_3. + + If a directory allows read, write, or read/write access then files + may be created in that directory. + + In an attempt to prevent risky permissions the following paths are + ignored in /opt/pigpio/access. + + . . + a path containing .. + a path containing only wildcards (*?) + a path containing less than two non-wildcard parts + . . + + Mode + + The mode may have the following values. + + Constant @ Value @ Meaning + FILE_READ @ 1 @ open file for reading + FILE_WRITE @ 2 @ open file for writing + FILE_RW @ 3 @ open file for reading and writing + + The following values may be or'd into the mode. + + Name @ Value @ Meaning + FILE_APPEND @ 4 @ All writes append data to the end of the file + FILE_CREATE @ 8 @ The file is created if it doesn't exist + FILE_TRUNC @ 16 @ The file is truncated + + Newly created files are owned by root with permissions owner + read and write. + + ... + #!/usr/bin/env python + + import pigpio + + pi = pigpio.pi() + + if not pi.connected: + exit() + + # Assumes /opt/pigpio/access contains the following line. + # /ram/*.c r + + handle = pi.file_open("/ram/pigpio.c", pigpio.FILE_READ) + + done = False + + while not done: + c, d = pi.file_read(handle, 60000) + if c > 0: + print(d) + else: + done = True + + pi.file_close(handle) + + pi.stop() + ... + """ + # I p1 file_mode + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_FO, file_mode, 0, len(file_name), [file_name])) + + def file_close(self, handle): + """ + Closes the file associated with handle. + + handle:= >=0 (as returned by a prior call to [*file_open*]). + + ... + pi.file_close(handle) + ... + """ + return _u2i(_pigpio_command(self.sl, _PI_CMD_FC, handle, 0)) + + def file_read(self, handle, count): + """ + Reads up to count bytes from the file associated with handle. + + handle:= >=0 (as returned by a prior call to [*file_open*]). + count:= >0, the number of bytes to read. + + The returned value is a tuple of the number of bytes read and a + bytearray containing the bytes. If there was an error the + number of bytes read will be less than zero (and will contain + the error code). + + ... + (b, d) = pi.file_read(h2, 100) + if b > 0: + # process read data + ... + """ + # Don't raise exception. Must release lock. + bytes = u2i( + _pigpio_command(self.sl, _PI_CMD_FR, handle, count, False)) + if bytes > 0: + data = self._rxbuf(bytes) + else: + data = "" + self.sl.l.release() + return bytes, data + + def file_write(self, handle, data): + """ + Writes the data bytes to the file associated with handle. + + handle:= >=0 (as returned by a prior call to [*file_open*]). + data:= the bytes to write. + + ... + pi.file_write(h1, b'\\x02\\x03\\x04') + + pi.file_write(h2, b'help') + + pi.file_write(h2, "hello") + + pi.file_write(h1, [2, 3, 4]) + ... + """ + # I p1 handle + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_FW, handle, 0, len(data), [data])) + + def file_seek(self, handle, seek_offset, seek_from): + """ + Seeks to a position relative to the start, current position, + or end of the file. Returns the new position. + + handle:= >=0 (as returned by a prior call to [*file_open*]). + seek_offset:= byte offset. + seek_from:= FROM_START, FROM_CURRENT, or FROM_END. + + ... + new_pos = pi.file_seek(h, 100, pigpio.FROM_START) + + cur_pos = pi.file_seek(h, 0, pigpio.FROM_CURRENT) + + file_size = pi.file_seek(h, 0, pigpio.FROM_END) + ... + """ + # I p1 handle + # I p2 seek_offset + # I p3 4 + ## extension ## + # I seek_from + extents = [struct.pack("I", seek_from)] + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_FS, handle, seek_offset, 4, extents)) + + def file_list(self, fpattern): + """ + Returns a list of files which match a pattern. + + fpattern:= file pattern to match. + + Returns the number of returned bytes if OK, otherwise + PI_NO_FILE_ACCESS, or PI_NO_FILE_MATCH. + + The pattern must match an entry in /opt/pigpio/access. The + pattern may contain wildcards. See [*file_open*]. + + NOTE + + The returned value is not the number of files, it is the number + of bytes in the buffer. The file names are separated by newline + characters. + + ... + #!/usr/bin/env python + + import pigpio + + pi = pigpio.pi() + + if not pi.connected: + exit() + + # Assumes /opt/pigpio/access contains the following line. + # /ram/*.c r + + c, d = pi.file_list("/ram/p*.c") + if c > 0: + print(d) + + pi.stop() + ... + """ + # I p1 60000 + # I p2 0 + # I p3 len + ## extension ## + # s len data bytes + + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_FL, 60000, 0, len(fpattern), [fpattern], False)) + if bytes > 0: + data = self._rxbuf(bytes) + else: + data = "" + self.sl.l.release() + return bytes, data + + def shell(self, shellscr, pstring=""): + """ + This function uses the system call to execute a shell script + with the given string as its parameter. + + shellscr:= the name of the script, only alphanumerics, + '-' and '_' are allowed in the name + pstring := the parameter string to pass to the script + + The exit status of the system call is returned if OK, + otherwise PI_BAD_SHELL_STATUS. + + [*shellscr*] must exist in /opt/pigpio/cgi and must be executable. + + The returned exit status is normally 256 times that set by + the shell script exit function. If the script can't be + found 32512 will be returned. + + The following table gives some example returned statuses. + + Script exit status @ Returned system call status + 1 @ 256 + 5 @ 1280 + 10 @ 2560 + 200 @ 51200 + script not found @ 32512 + + ... + // pass two parameters, hello and world + status = pi.shell("scr1", "hello world"); + + // pass three parameters, hello, string with spaces, and world + status = pi.shell("scr1", "hello 'string with spaces' world"); + + // pass one parameter, hello string with spaces world + status = pi.shell("scr1", "\\"hello string with spaces world\\""); + ... + """ + # I p1 len(shellscr) + # I p2 0 + # I p3 len(shellscr)+len(pstring)+1 + ## extension ## + # s len data bytes + + ls = len(shellscr) + lp = len(pstring) + return _u2i(_pigpio_command_ext( + self.sl, _PI_CMD_SHELL, ls, 0, ls+lp+1, [shellscr+'\x00'+pstring])) + def callback(self, user_gpio, edge=RISING_EDGE, func=None): """ Calls a user supplied function (a callback) whenever the @@ -4071,8 +4498,48 @@ def xref(): PI_BAD_SER_INVERT = -121 PI_BAD_FOREVER = -124 PI_BAD_FILTER = -125 + PI_BAD_PAD = -126 + PI_BAD_STRENGTH = -127 + PI_FIL_OPEN_FAILED = -128 + PI_BAD_FILE_MODE = -129 + PI_BAD_FILE_FLAG = -130 + PI_BAD_FILE_READ = -131 + PI_BAD_FILE_WRITE = -132 + PI_FILE_NOT_ROPEN = -133 + PI_FILE_NOT_WOPEN = -134 + PI_BAD_FILE_SEEK = -135 + PI_NO_FILE_MATCH = -136 + PI_NO_FILE_ACCESS = -137 + PI_FILE_IS_A_DIR = -138 + PI_BAD_SHELL_STATUS = -139 + PI_BAD_SCRIPT_NAME = -140 . . + file_mode: + The mode may have the following values. + + . . + FILE_READ 1 + FILE_WRITE 2 + FILE_RW 3 + . . + + The following values can be or'd into the file open mode. + + . . + FILE_APPEND 4 + FILE_CREATE 8 + FILE_TRUNC 16 + . . + + file_name: + A full file path. To be accessible the path must match + an entry in /opt/pigpio/access. + + fpattern: + A file path which may contain wildcards. To be accessible the path + must match an entry in /opt/pigpio/access. + frequency: 0-40000 Defines the frequency to be used for PWM on a GPIO. The closest permitted frequency will be used. @@ -4122,8 +4589,8 @@ def xref(): of a pulse. handle: >=0 - A number referencing an object opened by one of [*i2c_open*], - [*notify_open*], [*serial_open*], [*spi_open*]. + A number referencing an object opened by one of [*file_open*], + [*i2c_open*], [*notify_open*], [*serial_open*], [*spi_open*]. host: The name or IP address of the Pi running the pigpio daemon. @@ -4177,6 +4644,18 @@ def xref(): The offset wave data starts from the beginning of the waveform being currently defined. + pad: 0-2 + A set of GPIO which share common drivers. + + Pad @ GPIO + 0 @ 0-27 + 1 @ 28-45 + 2 @ 46-53 + + pad_strength: 1-16 + The mA which may be drawn from each GPIO whilst still guaranteeing the + high and low levels. + params: 32 bit number When scripts are started they can receive up to 10 parameters to define their operation. @@ -4184,6 +4663,9 @@ def xref(): port: The port used by the pigpio daemon, defaults to 8888. + pstring: + The string to be passed to a [*shell*] script to be executed. + pud: 0-2 PUD_DOWN = 1 PUD_OFF = 0 @@ -4230,12 +4712,27 @@ def xref(): SDA: The user GPIO to use for data when bit banging I2C. + seek_from: 0-2 + Direction to seek for [*file_seek*]. + + FROM_START=0 + FROM_CURRENT=1 + FROM_END=2 + + seek_offset: + The number of bytes to move forward (positive) or backwards + (negative) from the seek position (start, current, or end of file). + ser_flags: 32 bit No serial flags are currently defined. serial_*: One of the serial_ functions. + shellscr: + The name of a shell script. The script must exist + in /opt/pigpio/cgi and must be executable. + spi_*: One of the spi_ functions. diff --git a/pigpiod.1 b/pigpiod.1 index 2ce59b1..c32a4bb 100644 --- a/pigpiod.1 +++ b/pigpiod.1 @@ -11,6 +11,10 @@ pigpiod - A utility to start the pigpio library as a daemon. sudo pigpiod [OPTION]... .SH DESCRIPTION + +.ad l + +.nh pigpiod is a utility which launches the pigpio library as a daemon. .br diff --git a/pigpiod_if.3 b/pigpiod_if.3 index a5f0782..284a3ae 100644 --- a/pigpiod_if.3 +++ b/pigpiod_if.3 @@ -17,6 +17,10 @@ gcc -Wall -pthread -o prog prog.c -lpigpiod_if -lrt .SH DESCRIPTION +.ad l + +.nh + .br .br @@ -37,12 +41,12 @@ of the GPIO via the socket interface to the pigpio daemon. .br .br -o PWM on any of GPIO 0-31 +o hardware timed PWM on any of GPIO 0-31 .br .br -o servo pulses on any of GPIO 0-31 +o hardware timed servo pulses on any of GPIO 0-31 .br @@ -313,7 +317,7 @@ Set the GPIO mode. .EX gpio: 0-53. .br -mode: PI_INPUT, PI_OUTPUT, PI_ALT0, _ALT1, +mode: PI_INPUT, PI_OUTPUT, PI_ALT0, PI_ALT1, .br PI_ALT2, PI_ALT3, PI_ALT4, PI_ALT5. .br @@ -915,11 +919,6 @@ corresponding bit in bits is set. .br -.br -Notes - -.br - .br Each notification occupies 12 bytes in the fifo as follows: @@ -928,17 +927,59 @@ Each notification occupies 12 bytes in the fifo as follows: .br .EX -H (16 bit) seqno +typedef struct .br -H (16 bit) flags +{ .br -I (32 bit) tick + uint16_t seqno; .br -I (32 bit) level + uint16_t flags; +.br + uint32_t tick; +.br + uint32_t level; +.br +} gpioReport_t; .br .EE +.br + +.br +seqno: starts at 0 each time the handle is opened and then increments +by one for each report. + +.br + +.br +flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. + +.br + +.br +PI_NTFY_FLAGS_WDOG, if bit 5 is set then bits 0-4 of the flags +indicate a GPIO which has had a watchdog timeout. + +.br + +.br +PI_NTFY_FLAGS_ALIVE, if bit 6 is set this indicates a keep alive +signal on the pipe/socket and is sent once a minute in the absence +of other notification activity. + +.br + +.br +tick: the number of microseconds since system boot. It wraps around +after 1h12m. + +.br + +.br +level: indicates the level of each GPIO. If bit 1< */ -/* PIGPIOD_IF_VERSION 23 */ +/* PIGPIOD_IF_VERSION 25 */ #include #include diff --git a/pigpiod_if.h b/pigpiod_if.h index 0b80183..6706b9d 100644 --- a/pigpiod_if.h +++ b/pigpiod_if.h @@ -30,7 +30,7 @@ For more information, please refer to #include "pigpio.h" -#define PIGPIOD_IF_VERSION 23 +#define PIGPIOD_IF_VERSION 25 /*TEXT @@ -42,9 +42,9 @@ of the GPIO via the socket interface to the pigpio daemon. *Features* -o PWM on any of GPIO 0-31 +o hardware timed PWM on any of GPIO 0-31 -o servo pulses on any of GPIO 0-31 +o hardware timed servo pulses on any of GPIO 0-31 o callbacks when any of GPIO 0-31 change state @@ -251,7 +251,7 @@ spi_xfer Transfers bytes with a SPI device SERIAL -serial_open Opens a serial device (/dev/tty*) +serial_open Opens a serial device serial_close Closes a serial device serial_write_byte Writes a byte to a serial device @@ -389,7 +389,7 @@ Set the GPIO mode. . . gpio: 0-53. -mode: PI_INPUT, PI_OUTPUT, PI_ALT0, _ALT1, +mode: PI_INPUT, PI_OUTPUT, PI_ALT0, PI_ALT1, PI_ALT2, PI_ALT3, PI_ALT4, PI_ALT5. . . @@ -727,16 +727,35 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE. The notification sends state changes for each GPIO whose corresponding bit in bits is set. -Notes - Each notification occupies 12 bytes in the fifo as follows: . . -H (16 bit) seqno -H (16 bit) flags -I (32 bit) tick -I (32 bit) level +typedef struct +{ + uint16_t seqno; + uint16_t flags; + uint32_t tick; + uint32_t level; +} gpioReport_t; . . + +seqno: starts at 0 each time the handle is opened and then increments +by one for each report. + +flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. + +PI_NTFY_FLAGS_WDOG, if bit 5 is set then bits 0-4 of the flags +indicate a GPIO which has had a watchdog timeout. + +PI_NTFY_FLAGS_ALIVE, if bit 6 is set this indicates a keep alive +signal on the pipe/socket and is sent once a minute in the absence +of other notification activity. + +tick: the number of microseconds since system boot. It wraps around +after 1h12m. + +level: indicates the level of each GPIO. If bit 1<=0 (as returned by \fBpigpio_start\fP). .br - ser_tty: the serial device to open, /dev/tty*. + ser_tty: the serial device to open. .br baud: the baud rate in bits per second, see below. .br @@ -4255,6 +4278,701 @@ Returns >= 0 if OK, less than 0 indicates a user defined error. .br Note, the number of returned bytes will be retMax or less. +.IP "\fBint get_pad_strength(int pi, unsigned pad)\fP" +.IP "" 4 +This function returns the pad drive strength in mA. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br +pad: 0-2, the pad to get. +.br + +.EE + +.br + +.br +Returns the pad drive strength if OK, otherwise PI_BAD_PAD. + +.br + +.br +Pad GPIO +.br +0 0-27 +.br +1 28-45 +.br +2 46-53 +.br + +.br + +.br +\fBExample\fP +.br + +.EX +strength = get_pad_strength(pi, 0); // get pad 0 strength +.br + +.EE + +.IP "\fBint set_pad_strength(int pi, unsigned pad, unsigned padStrength)\fP" +.IP "" 4 +This function sets the pad drive strength in mA. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br + pad: 0-2, the pad to set. +.br +padStrength: 1-16 mA. +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_BAD_PAD, or PI_BAD_STRENGTH. + +.br + +.br +Pad GPIO +.br +0 0-27 +.br +1 28-45 +.br +2 46-53 +.br + +.br + +.br +\fBExample\fP +.br + +.EX +set_pad_strength(pi, 0, 10); // set pad 0 strength to 10 mA +.br + +.EE + +.IP "\fBint shell_(int pi, char *scriptName, char *scriptString)\fP" +.IP "" 4 +This function uses the system call to execute a shell script +with the given string as its parameter. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br + scriptName: the name of the script, only alphanumeric characters, +.br + '-' and '_' are allowed in the name. +.br +scriptString: the string to pass to the script. +.br + +.EE + +.br + +.br +The exit status of the system call is returned if OK, otherwise +PI_BAD_SHELL_STATUS. + +.br + +.br +scriptName must exist in /opt/pigpio/cgi and must be executable. + +.br + +.br +The returned exit status is normally 256 times that set by the +shell script exit function. If the script can't be found 32512 will +be returned. + +.br + +.br +The following table gives some example returned statuses. + +.br + +.br +Script exit status Returned system call status +.br +1 256 +.br +5 1280 +.br +10 2560 +.br +200 51200 +.br +script not found 32512 +.br + +.br + +.br +\fBExample\fP +.br + +.EX +// pass two parameters, hello and world +.br +status = shell_(pi, "scr1", "hello world"); +.br + +.br +// pass three parameters, hello, string with spaces, and world +.br +status = shell_(pi, "scr1", "hello 'string with spaces' world"); +.br + +.br +// pass one parameter, hello string with spaces world +.br +status = shell_(pi, "scr1", "\"hello string with spaces world\""); +.br + +.EE + +.IP "\fBint file_open(int pi, char *file, unsigned mode)\fP" +.IP "" 4 +This function returns a handle to a file opened in a specified mode. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br +file: the file to open. +.br +mode: the file open mode. +.br + +.EE + +.br + +.br +Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, PI_NO_FILE_ACCESS, +PI_BAD_FILE_MODE, PI_FILE_OPEN_FAILED, or PI_FILE_IS_A_DIR. + +.br + +.br +File + +.br + +.br +A file may only be opened if permission is granted by an entry in +/opt/pigpio/access. This is intended to allow remote access to files +in a more or less controlled manner. + +.br + +.br +Each entry in /opt/pigpio/access takes the form of a file path +which may contain wildcards followed by a single letter permission. +The permission may be R for read, W for write, U for read/write, +and N for no access. + +.br + +.br +Where more than one entry matches a file the most specific rule +applies. If no entry matches a file then access is denied. + +.br + +.br +Suppose /opt/pigpio/access contains the following entries + +.br + +.br + +.EX +/home/* n +.br +/home/pi/shared/dir_1/* w +.br +/home/pi/shared/dir_2/* r +.br +/home/pi/shared/dir_3/* u +.br +/home/pi/shared/dir_1/file.txt n +.br + +.EE + +.br + +.br +Files may be written in directory dir_1 with the exception +of file.txt. + +.br + +.br +Files may be read in directory dir_2. + +.br + +.br +Files may be read and written in directory dir_3. + +.br + +.br +If a directory allows read, write, or read/write access then files may +be created in that directory. + +.br + +.br +In an attempt to prevent risky permissions the following paths are +ignored in /opt/pigpio/access. + +.br + +.br + +.EX +a path containing .. +.br +a path containing only wildcards (*?) +.br +a path containing less than two non-wildcard parts +.br + +.EE + +.br + +.br +Mode + +.br + +.br +The mode may have the following values. + +.br + +.br +Macro Value Meaning +.br +PI_FILE_READ 1 open file for reading +.br +PI_FILE_WRITE 2 open file for writing +.br +PI_FILE_RW 3 open file for reading and writing +.br + +.br + +.br +The following values may be or'd into the mode. + +.br + +.br +Macro Value Meaning +.br +PI_FILE_APPEND 4 Writes append data to the end of the file +.br +PI_FILE_CREATE 8 The file is created if it doesn't exist +.br +PI_FILE_TRUNC 16 The file is truncated +.br + +.br + +.br +Newly created files are owned by root with permissions owner read and write. + +.br + +.br +\fBExample\fP +.br + +.EX +#include +.br +#include +.br + +.br +int main(int argc, char *argv[]) +.br +{ +.br + int pi, handle, c; +.br + char buf[60000]; +.br + +.br + pi = pigpio_start(NULL, NULL); +.br + +.br + if (pi < 0) return 1; +.br + +.br + // assumes /opt/pigpio/access contains the following line +.br + // /ram/*.c r +.br + +.br + handle = file_open(pi, "/ram/pigpio.c", PI_FILE_READ); +.br + +.br + if (handle >= 0) +.br + { +.br + while ((c=file_read(pi, handle, buf, sizeof(buf)-1))) +.br + { +.br + buf[c] = 0; +.br + printf("%s", buf); +.br + } +.br + +.br + file_close(pi, handle); +.br + } +.br + +.br + pigpio_stop(pi); +.br +} +.br + +.EE + +.IP "\fBint file_close(int pi, unsigned handle)\fP" +.IP "" 4 +This function closes the file associated with handle. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br +handle: >=0 (as returned by \fBfile_open\fP). +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_BAD_HANDLE. + +.br + +.br +\fBExample\fP +.br + +.EX +file_close(pi, handle); +.br + +.EE + +.IP "\fBint file_write(int pi, unsigned handle, char *buf, unsigned count)\fP" +.IP "" 4 +This function writes count bytes from buf to the the file +associated with handle. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br +handle: >=0 (as returned by \fBfile_open\fP). +.br + buf: the array of bytes to write. +.br + count: the number of bytes to write. +.br + +.EE + +.br + +.br +Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, +PI_FILE_NOT_WOPEN, or PI_BAD_FILE_WRITE. + +.br + +.br +\fBExample\fP +.br + +.EX +if (file_write(pi, handle, buf, 100) == 0) +.br +{ +.br + // file written okay +.br +} +.br +else +.br +{ +.br + // error +.br +} +.br + +.EE + +.IP "\fBint file_read(int pi, unsigned handle, char *buf, unsigned count)\fP" +.IP "" 4 +This function reads up to count bytes from the the file +associated with handle and writes them to buf. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br +handle: >=0 (as returned by \fBfile_open\fP). +.br + buf: an array to receive the read data. +.br + count: the maximum number of bytes to read. +.br + +.EE + +.br + +.br +Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, PI_FILE_NOT_ROPEN, or PI_BAD_FILE_WRITE. + +.br + +.br +\fBExample\fP +.br + +.EX + bytes = file_read(pi, handle, buf, sizeof(buf)); +.br + +.br + if (bytes >= 0) +.br + { +.br + // process read data +.br + } +.br + +.EE + +.IP "\fBint file_seek(int pi, unsigned handle, int32_t seekOffset, int seekFrom)\fP" +.IP "" 4 +This function seeks to a position within the file associated +with handle. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br + handle: >=0 (as returned by \fBfile_open\fP). +.br +seekOffset: the number of bytes to move. Positive offsets +.br + move forward, negative offsets backwards. +.br + seekFrom: one of PI_FROM_START (0), PI_FROM_CURRENT (1), +.br + or PI_FROM_END (2). +.br + +.EE + +.br + +.br +Returns the new byte position within the file (>=0) if OK, otherwise PI_BAD_HANDLE, or PI_BAD_FILE_SEEK. + +.br + +.br +\fBExample\fP +.br + +.EX +file_seek(pi, handle, 123, PI_FROM_START); // Start plus 123 +.br + +.br +size = file_seek(pi, handle, 0, PI_FROM_END); // End, return size +.br + +.br +pos = file_seek(pi, handle, 0, PI_FROM_CURRENT); // Current position +.br + +.EE + +.IP "\fBint file_list(int pi, char *fpat, char *buf, unsigned count)\fP" +.IP "" 4 +This function returns a list of files which match a pattern. + +.br + +.br + +.EX + pi: >=0 (as returned by \fBpigpio_start\fP). +.br + fpat: file pattern to match. +.br + buf: an array to receive the matching file names. +.br +count: the maximum number of bytes to read. +.br + +.EE + +.br + +.br +Returns the number of returned bytes if OK, otherwise PI_NO_FILE_ACCESS, +or PI_NO_FILE_MATCH. + +.br + +.br +The pattern must match an entry in /opt/pigpio/access. The pattern +may contain wildcards. See \fBfile_open\fP. + +.br + +.br +NOTE + +.br + +.br +The returned value is not the number of files, it is the number +of bytes in the buffer. The file names are separated by newline +characters. + +.br + +.br +\fBExample\fP +.br + +.EX +#include +.br +#include +.br + +.br +int main(int argc, char *argv[]) +.br +{ +.br + int pi, handle, c; +.br + char buf[60000]; +.br + +.br + pi = pigpio_start(NULL, NULL); +.br + +.br + if (pi < 0) return 1; +.br + +.br + // assumes /opt/pigpio/access contains the following line +.br + // /ram/*.c r +.br + +.br + c = file_list(pi, "/ram/p*.c", buf, sizeof(buf)); +.br + +.br + if (c >= 0) +.br + { +.br + buf[c] = 0; +.br + printf("%s", buf); +.br + } +.br + +.br + pigpio_stop(pi); +.br +} +.br + +.EE + .IP "\fBint callback(int pi, unsigned user_gpio, unsigned edge, CBFunc_t f)\fP" .IP "" 4 This function initialises a new callback. @@ -4547,7 +5265,7 @@ The hardware clock frequency. .br .IP "\fBcount\fP" 0 -The number of bytes to be transferred in an I2C, SPI, or Serial +The number of bytes to be transferred in a file, I2C, SPI, or serial command. .br @@ -4630,6 +5348,22 @@ A function. .br +.IP "\fB*file\fP" 0 +A full file path. To be accessible the path must match an entry in +/opt/pigpio/access. + +.br + +.br + +.IP "\fB*fpat\fP" 0 +A file path which may contain wildcards. To be accessible the path +must match an entry in /opt/pigpio/access. + +.br + +.br + .IP "\fBfrequency\fP: >=0" 0 The number of times a GPIO is swiched on and off per second. This can be set per GPIO and may be as little as 5Hz or as much as @@ -4640,24 +5374,20 @@ by its dutycycle. .br -.br - -.br - .IP "\fBgpio\fP" 0 A Broadcom numbered GPIO, in the range 0-53. .br .br -There are 54 General Purpose Input Outputs (GPIO) named gpio0 through -gpio53. +There are 54 General Purpose Input Outputs (GPIO) named GPIO0 through +GPIO53. .br .br -They are split into two banks. Bank 1 consists of gpio0 through -gpio31. Bank 2 consists of gpio32 through gpio53. +They are split into two banks. Bank 1 consists of GPIO0 through +GPIO31. Bank 2 consists of GPIO32 through GPIO53. .br @@ -4741,8 +5471,8 @@ typedef void *(gpioThreadFunc_t) (void *); .br .IP "\fBhandle\fP: >=0" 0 -A number referencing an object opened by one of \fBi2c_open\fP, \fBnotify_open\fP, -\fBserial_open\fP, and \fBspi_open\fP. +A number referencing an object opened by one of \fBfile_open\fP, +\fBi2c_open\fP, \fBnotify_open\fP, \fBserial_open\fP, and \fBspi_open\fP. .br @@ -4797,6 +5527,13 @@ A whole number, negative or positive. .br +.IP "\fBint32_t\fP" 0 +A 32-bit signed value. + +.br + +.br + .IP "\fBinvert\fP" 0 A flag used to set normal or inverted bit bang serial data level logic. @@ -4901,6 +5638,48 @@ PI_WAVE_MODE_REPEAT_SYNC 3 .br +.br +3. A file open mode. + +.br + +.br + +.EX +PI_FILE_READ 1 +.br +PI_FILE_WRITE 2 +.br +PI_FILE_RW 3 +.br + +.EE + +.br + +.br +The following values can be or'd into the mode. + +.br + +.br + +.EX +PI_FILE_APPEND 4 +.br +PI_FILE_CREATE 8 +.br +PI_FILE_TRUNC 16 +.br + +.EE + +.br + +.br + +.br + .br .IP "\fBnumBytes\fP" 0 @@ -4948,6 +5727,33 @@ The size in bytes of an output buffer. .br +.IP "\fBpad\fP: 0-2" 0 +A set of GPIO which share common drivers. + +.br + +.br +Pad GPIO +.br +0 0-27 +.br +1 28-45 +.br +2 46-53 +.br + +.br + +.br + +.IP "\fBpadStrength\fP: 1-16" 0 +The mA which may be drawn from each GPIO whilst still guaranteeing the +high and low levels. + +.br + +.br + .IP "\fB*param\fP" 0 An array of script parameters. @@ -5136,6 +5942,21 @@ An id of a stored script as returned by \fBstore_script\fP. .br +.IP "\fB*scriptName\fP" 0 +The name of a \fBshell_\fP script to be executed. The script must be present in +/opt/pigpio/cgi and must have execute permission. + +.br + +.br + +.IP "\fB*scriptString\fP" 0 +The string to be passed to a \fBshell_\fP script to be executed. + +.br + +.br + .IP "\fBSDA\fP" 0 The user GPIO to use for data when bit banging I2C. @@ -5150,6 +5971,34 @@ The number of seconds. .br +.IP "\fBseekFrom\fP" 0 + +.br + +.br + +.EX +PI_FROM_START 0 +.br +PI_FROM_CURRENT 1 +.br +PI_FROM_END 2 +.br + +.EE + +.br + +.br + +.IP "\fBseekOffset\fP" 0 +The number of bytes to move forward (positive) or backwards (negative) +from the seek position (start, current, or end of file). + +.br + +.br + .IP "\fBser_flags\fP" 0 Flags which modify a serial open command. None are currently defined. diff --git a/pigpiod_if2.c b/pigpiod_if2.c index ffaab49..bc3d496 100644 --- a/pigpiod_if2.c +++ b/pigpiod_if2.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* PIGPIOD_IF2_VERSION 6 */ +/* PIGPIOD_IF2_VERSION 8 */ #include #include @@ -1604,6 +1604,148 @@ int custom_2(int pi, unsigned arg1, char *argx, unsigned count, return bytes; } +int get_pad_strength(int pi, unsigned pad) + {return pigpio_command(pi, PI_CMD_PADG, pad, 0, 1);} + +int set_pad_strength(int pi, unsigned pad, unsigned padStrength) + {return pigpio_command(pi, PI_CMD_PADS, pad, padStrength, 1);} + +int shell_(int pi, char *scriptName, char *scriptString) +{ + int ln, ls; + gpioExtent_t ext[2]; + + ln = strlen(scriptName); + ls = strlen(scriptString); + /* + p1=len(scriptName) + p2=0 + p3=len(scriptName) + len(scriptString) + 1 + ## extension ## + char[] + */ + + ext[0].size = ln + 1; /* include null byte */ + ext[0].ptr = scriptName; + + ext[1].size = ls; + ext[1].ptr = scriptString; + + return pigpio_command_ext + (pi, PI_CMD_SHELL, ln, 0, ln+ls+1, 2, ext, 1); +} + +int file_open(int pi, char *file, unsigned mode) +{ + int len; + gpioExtent_t ext[1]; + + len = strlen(file); + + /* + p1=mode + p2=0 + p3=len + ## extension ## + char file[len] + */ + + ext[0].size = len; + ext[0].ptr = file; + + return pigpio_command_ext + (pi, PI_CMD_FO, mode, 0, len, 1, ext, 1); +} + +int file_close(int pi, unsigned handle) + {return pigpio_command(pi, PI_CMD_FC, handle, 0, 1);} + +int file_write(int pi, 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 + (pi, PI_CMD_FW, handle, 0, count, 1, ext, 1); +} + +int file_read(int pi, unsigned handle, char *buf, unsigned count) +{ + int bytes; + + bytes = pigpio_command + (pi, PI_CMD_FR, handle, count, 0); + + if (bytes > 0) + { + bytes = recvMax(pi, buf, count, bytes); + } + + _pmu(pi); + + return bytes; +} + +int file_seek(int pi, unsigned handle, int32_t seekOffset, int seekFrom) +{ + gpioExtent_t ext[1]; + + /* + p1=handle + p2=seekOffset + p3=4 + ## extension ## + uint32_t seekFrom + */ + + ext[0].size = sizeof(uint32_t); + ext[0].ptr = &seekFrom; + + return pigpio_command_ext + (pi, PI_CMD_FS, handle, seekOffset, 4, 1, ext, 1); +} + +int file_list(int pi, char *fpat, char *buf, unsigned count) +{ + int len; + int bytes; + gpioExtent_t ext[1]; + + len = strlen(fpat); + + /* + p1=60000 + p2=0 + p3=len + ## extension ## + char fpat[len] + */ + + ext[0].size = len; + ext[0].ptr = fpat; + + bytes = pigpio_command_ext(pi, PI_CMD_FL, 60000, 0, len, 1, ext, 0); + + if (bytes > 0) + { + bytes = recvMax(pi, buf, count, bytes); + } + + _pmu(pi); + + return bytes; +} + int callback(int pi, unsigned user_gpio, unsigned edge, CBFunc_t f) {return intCallback(pi, user_gpio, edge, f, 0, 0);} diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 95de307..c41d5a1 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -30,7 +30,7 @@ For more information, please refer to #include "pigpio.h" -#define PIGPIOD_IF2_VERSION 6 +#define PIGPIOD_IF2_VERSION 8 /*TEXT @@ -39,9 +39,9 @@ of the GPIO via the socket interface to the pigpio daemon. *Features* -o PWM on any of GPIO 0-31 +o hardware timed PWM on any of GPIO 0-31 -o servo pulses on any of GPIO 0-31 +o hardware timed servo pulses on any of GPIO 0-31 o callbacks when any of GPIO 0-31 change state @@ -166,8 +166,13 @@ bb_serial_invert Invert serial logic (1 invert, 0 normal) hardware_clock Start hardware clock on supported GPIO hardware_PWM Start hardware PWM on supported GPIO -set_glitch_filter Set a glitch filter on a GPIO -set_noise_filter Set a noise filter on a GPIO +set_glitch_filter Set a glitch filter on a GPIO +set_noise_filter Set a noise filter on a GPIO + +get_pad_strength Gets a pads drive strength +set_pad_strength Sets a pads drive strength + +shell_ Executes a shell command SCRIPTS @@ -250,7 +255,7 @@ spi_xfer Transfers bytes with a SPI device SERIAL -serial_open Opens a serial device (/dev/tty*) +serial_open Opens a serial device serial_close Closes a serial device serial_write_byte Writes a byte to a serial device @@ -260,6 +265,15 @@ serial_read Reads bytes from a serial device serial_data_available Returns number of bytes ready to be read +FILES + +file_open Opens a file +file_close Closes a file +file_read Reads bytes from a file +file_write Writes bytes to a file +file_seek Seeks to a position within a file +file_list List files which match a pattern + CUSTOM custom_1 User custom function 1 @@ -399,7 +413,7 @@ Set the GPIO mode. . . pi: >=0 (as returned by [*pigpio_start*]). gpio: 0-53. -mode: PI_INPUT, PI_OUTPUT, PI_ALT0, _ALT1, +mode: PI_INPUT, PI_OUTPUT, PI_ALT0, PI_ALT1, PI_ALT2, PI_ALT3, PI_ALT4, PI_ALT5. . . @@ -755,16 +769,35 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE. The notification sends state changes for each GPIO whose corresponding bit in bits is set. -Notes - Each notification occupies 12 bytes in the fifo as follows: . . -H (16 bit) seqno -H (16 bit) flags -I (32 bit) tick -I (32 bit) level +typedef struct +{ + uint16_t seqno; + uint16_t flags; + uint32_t tick; + uint32_t level; +} gpioReport_t; . . + +seqno: starts at 0 each time the handle is opened and then increments +by one for each report. + +flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. + +PI_NTFY_FLAGS_WDOG, if bit 5 is set then bits 0-4 of the flags +indicate a GPIO which has had a watchdog timeout. + +PI_NTFY_FLAGS_ALIVE, if bit 6 is set this indicates a keep alive +signal on the pipe/socket and is sent once a minute in the absence +of other notification activity. + +tick: the number of microseconds since system boot. It wraps around +after 1h12m. + +level: indicates the level of each GPIO. If bit 1<=0 (as returned by [*pigpio_start*]). - ser_tty: the serial device to open, /dev/tty*. + ser_tty: the serial device to open. baud: the baud rate in bits per second, see below. ser_flags: 0. . . @@ -2641,6 +2676,369 @@ Returns >= 0 if OK, less than 0 indicates a user defined error. Note, the number of returned bytes will be retMax or less. D*/ +/*F*/ +int get_pad_strength(int pi, unsigned pad); +/*D +This function returns the pad drive strength in mA. + +. . + pi: >=0 (as returned by [*pigpio_start*]). +pad: 0-2, the pad to get. +. . + +Returns the pad drive strength if OK, otherwise PI_BAD_PAD. + +Pad @ GPIO +0 @ 0-27 +1 @ 28-45 +2 @ 46-53 + +... +strength = get_pad_strength(pi, 0); // get pad 0 strength +... +D*/ + + +/*F*/ +int set_pad_strength(int pi, unsigned pad, unsigned padStrength); +/*D +This function sets the pad drive strength in mA. + +. . + pi: >=0 (as returned by [*pigpio_start*]). + pad: 0-2, the pad to set. +padStrength: 1-16 mA. +. . + +Returns 0 if OK, otherwise PI_BAD_PAD, or PI_BAD_STRENGTH. + +Pad @ GPIO +0 @ 0-27 +1 @ 28-45 +2 @ 46-53 + +... +set_pad_strength(pi, 0, 10); // set pad 0 strength to 10 mA +... +D*/ + + +/*F*/ +int shell_(int pi, char *scriptName, char *scriptString); +/*D +This function uses the system call to execute a shell script +with the given string as its parameter. + +. . + pi: >=0 (as returned by [*pigpio_start*]). + scriptName: the name of the script, only alphanumeric characters, + '-' and '_' are allowed in the name. +scriptString: the string to pass to the script. +. . + +The exit status of the system call is returned if OK, otherwise +PI_BAD_SHELL_STATUS. + +scriptName must exist in /opt/pigpio/cgi and must be executable. + +The returned exit status is normally 256 times that set by the +shell script exit function. If the script can't be found 32512 will +be returned. + +The following table gives some example returned statuses. + +Script exit status @ Returned system call status +1 @ 256 +5 @ 1280 +10 @ 2560 +200 @ 51200 +script not found @ 32512 + +... +// pass two parameters, hello and world +status = shell_(pi, "scr1", "hello world"); + +// pass three parameters, hello, string with spaces, and world +status = shell_(pi, "scr1", "hello 'string with spaces' world"); + +// pass one parameter, hello string with spaces world +status = shell_(pi, "scr1", "\"hello string with spaces world\""); +... +D*/ + +#pragma GCC diagnostic push + +#pragma GCC diagnostic ignored "-Wcomment" + +/*F*/ +int file_open(int pi, char *file, unsigned mode); +/*D +This function returns a handle to a file opened in a specified mode. + +. . + pi: >=0 (as returned by [*pigpio_start*]). +file: the file to open. +mode: the file open mode. +. . + +Returns a handle (>=0) if OK, otherwise PI_NO_HANDLE, PI_NO_FILE_ACCESS, +PI_BAD_FILE_MODE, PI_FILE_OPEN_FAILED, or PI_FILE_IS_A_DIR. + +File + +A file may only be opened if permission is granted by an entry in +/opt/pigpio/access. This is intended to allow remote access to files +in a more or less controlled manner. + +Each entry in /opt/pigpio/access takes the form of a file path +which may contain wildcards followed by a single letter permission. +The permission may be R for read, W for write, U for read/write, +and N for no access. + +Where more than one entry matches a file the most specific rule +applies. If no entry matches a file then access is denied. + +Suppose /opt/pigpio/access contains the following entries + +. . +/home/* n +/home/pi/shared/dir_1/* w +/home/pi/shared/dir_2/* r +/home/pi/shared/dir_3/* u +/home/pi/shared/dir_1/file.txt n +. . + +Files may be written in directory dir_1 with the exception +of file.txt. + +Files may be read in directory dir_2. + +Files may be read and written in directory dir_3. + +If a directory allows read, write, or read/write access then files may +be created in that directory. + +In an attempt to prevent risky permissions the following paths are +ignored in /opt/pigpio/access. + +. . +a path containing .. +a path containing only wildcards (*?) +a path containing less than two non-wildcard parts +. . + +Mode + +The mode may have the following values. + +Macro @ Value @ Meaning +PI_FILE_READ @ 1 @ open file for reading +PI_FILE_WRITE @ 2 @ open file for writing +PI_FILE_RW @ 3 @ open file for reading and writing + +The following values may be or'd into the mode. + +Macro @ Value @ Meaning +PI_FILE_APPEND @ 4 @ Writes append data to the end of the file +PI_FILE_CREATE @ 8 @ The file is created if it doesn't exist +PI_FILE_TRUNC @ 16 @ The file is truncated + +Newly created files are owned by root with permissions owner read and write. + +... +#include +#include + +int main(int argc, char *argv[]) +{ + int pi, handle, c; + char buf[60000]; + + pi = pigpio_start(NULL, NULL); + + if (pi < 0) return 1; + + // assumes /opt/pigpio/access contains the following line + // /ram/*.c r + + handle = file_open(pi, "/ram/pigpio.c", PI_FILE_READ); + + if (handle >= 0) + { + while ((c=file_read(pi, handle, buf, sizeof(buf)-1))) + { + buf[c] = 0; + printf("%s", buf); + } + + file_close(pi, handle); + } + + pigpio_stop(pi); +} +... +D*/ + +#pragma GCC diagnostic pop + +/*F*/ +int file_close(int pi, unsigned handle); +/*D +This function closes the file associated with handle. + +. . + pi: >=0 (as returned by [*pigpio_start*]). +handle: >=0 (as returned by [*file_open*]). +. . + +Returns 0 if OK, otherwise PI_BAD_HANDLE. + +... +file_close(pi, handle); +... +D*/ + + +/*F*/ +int file_write(int pi, unsigned handle, char *buf, unsigned count); +/*D +This function writes count bytes from buf to the the file +associated with handle. + +. . + pi: >=0 (as returned by [*pigpio_start*]). +handle: >=0 (as returned by [*file_open*]). + buf: the array of bytes to write. + count: the number of bytes to write. +. . + +Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, +PI_FILE_NOT_WOPEN, or PI_BAD_FILE_WRITE. + +... +if (file_write(pi, handle, buf, 100) == 0) +{ + // file written okay +} +else +{ + // error +} +... +D*/ + + +/*F*/ +int file_read(int pi, unsigned handle, char *buf, unsigned count); +/*D +This function reads up to count bytes from the the file +associated with handle and writes them to buf. + +. . + pi: >=0 (as returned by [*pigpio_start*]). +handle: >=0 (as returned by [*file_open*]). + buf: an array to receive the read data. + count: the maximum number of bytes to read. +. . + +Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, PI_FILE_NOT_ROPEN, or PI_BAD_FILE_WRITE. + +... + bytes = file_read(pi, handle, buf, sizeof(buf)); + + if (bytes >= 0) + { + // process read data + } +... +D*/ + + +/*F*/ +int file_seek(int pi, unsigned handle, int32_t seekOffset, int seekFrom); +/*D +This function seeks to a position within the file associated +with handle. + +. . + pi: >=0 (as returned by [*pigpio_start*]). + handle: >=0 (as returned by [*file_open*]). +seekOffset: the number of bytes to move. Positive offsets + move forward, negative offsets backwards. + seekFrom: one of PI_FROM_START (0), PI_FROM_CURRENT (1), + or PI_FROM_END (2). +. . + +Returns the new byte position within the file (>=0) if OK, otherwise PI_BAD_HANDLE, or PI_BAD_FILE_SEEK. + +... +file_seek(pi, handle, 123, PI_FROM_START); // Start plus 123 + +size = file_seek(pi, handle, 0, PI_FROM_END); // End, return size + +pos = file_seek(pi, handle, 0, PI_FROM_CURRENT); // Current position +... +D*/ + +#pragma GCC diagnostic push + +#pragma GCC diagnostic ignored "-Wcomment" + +/*F*/ +int file_list(int pi, char *fpat, char *buf, unsigned count); +/*D +This function returns a list of files which match a pattern. + +. . + pi: >=0 (as returned by [*pigpio_start*]). + fpat: file pattern to match. + buf: an array to receive the matching file names. +count: the maximum number of bytes to read. +. . + +Returns the number of returned bytes if OK, otherwise PI_NO_FILE_ACCESS, +or PI_NO_FILE_MATCH. + +The pattern must match an entry in /opt/pigpio/access. The pattern +may contain wildcards. See [*file_open*]. + +NOTE + +The returned value is not the number of files, it is the number +of bytes in the buffer. The file names are separated by newline +characters. + +... +#include +#include + +int main(int argc, char *argv[]) +{ + int pi, handle, c; + char buf[60000]; + + pi = pigpio_start(NULL, NULL); + + if (pi < 0) return 1; + + // assumes /opt/pigpio/access contains the following line + // /ram/*.c r + + c = file_list(pi, "/ram/p*.c", buf, sizeof(buf)); + + if (c >= 0) + { + buf[c] = 0; + printf("%s", buf); + } + + pigpio_stop(pi); +} +... +D*/ + +#pragma GCC diagnostic pop + /*F*/ int callback(int pi, unsigned user_gpio, unsigned edge, CBFunc_t f); @@ -2794,7 +3192,7 @@ clkfreq::4689-250000000 (250M) The hardware clock frequency. count:: -The number of bytes to be transferred in an I2C, SPI, or Serial +The number of bytes to be transferred in a file, I2C, SPI, or serial command. data_bits::1-32 @@ -2831,21 +3229,28 @@ of the error. f:: A function. +*file:: +A full file path. To be accessible the path must match an entry in +/opt/pigpio/access. + +*fpat:: +A file path which may contain wildcards. To be accessible the path +must match an entry in /opt/pigpio/access. + frequency::>=0 The number of times a GPIO is swiched on and off per second. This can be set per GPIO and may be as little as 5Hz or as much as 40KHz. The GPIO will be on for a proportion of the time as defined by its dutycycle. - gpio:: A Broadcom numbered GPIO, in the range 0-53. -There are 54 General Purpose Input Outputs (GPIO) named gpio0 through -gpio53. +There are 54 General Purpose Input Outputs (GPIO) named GPIO0 through +GPIO53. -They are split into two banks. Bank 1 consists of gpio0 through -gpio31. Bank 2 consists of gpio32 through gpio53. +They are split into two banks. Bank 1 consists of GPIO0 through +GPIO31. Bank 2 consists of GPIO32 through GPIO53. All the GPIO which are safe for the user to read and write are in bank 1. Not all GPIO in bank 1 are safe though. Type 1 boards @@ -2883,8 +3288,8 @@ typedef void *(gpioThreadFunc_t) (void *); . . handle::>=0 -A number referencing an object opened by one of [*i2c_open*], [*notify_open*], -[*serial_open*], and [*spi_open*]. +A number referencing an object opened by one of [*file_open*], +[*i2c_open*], [*notify_open*], [*serial_open*], and [*spi_open*]. i2c_addr::0-0x7F The address of a device on the I2C bus. @@ -2907,6 +3312,9 @@ The number of bytes of data in a buffer. int:: A whole number, negative or positive. +int32_t:: +A 32-bit signed value. + invert:: A flag used to set normal or inverted bit bang serial data level logic. @@ -2954,6 +3362,23 @@ PI_WAVE_MODE_ONE_SHOT_SYNC 2 PI_WAVE_MODE_REPEAT_SYNC 3 . . +3. A file open mode. + +. . +PI_FILE_READ 1 +PI_FILE_WRITE 2 +PI_FILE_RW 3 +. . + +The following values can be or'd into the mode. + +. . +PI_FILE_APPEND 4 +PI_FILE_CREATE 8 +PI_FILE_TRUNC 16 +. . + + numBytes:: The number of bytes used to store characters in a string. Depending on the number of bits per character there may be 1, 2, or 4 bytes @@ -2975,6 +3400,18 @@ A buffer used to return data from a function. outLen:: The size in bytes of an output buffer. +pad:: 0-2 +A set of GPIO which share common drivers. + +Pad @ GPIO +0 @ 0-27 +1 @ 28-45 +2 @ 46-53 + +padStrength:: 1-16 +The mA which may be drawn from each GPIO whilst still guaranteeing the +high and low levels. + *param:: An array of script parameters. @@ -3058,12 +3495,31 @@ A pointer to the text of a script. script_id:: An id of a stored script as returned by [*store_script*]. +*scriptName:: +The name of a [*shell_*] script to be executed. The script must be present in +/opt/pigpio/cgi and must have execute permission. + +*scriptString:: +The string to be passed to a [*shell_*] script to be executed. + SDA:: The user GPIO to use for data when bit banging I2C. seconds:: The number of seconds. +seekFrom:: + +. . +PI_FROM_START 0 +PI_FROM_CURRENT 1 +PI_FROM_END 2 +. . + +seekOffset:: +The number of bytes to move forward (positive) or backwards (negative) +from the seek position (start, current, or end of file). + ser_flags:: Flags which modify a serial open command. None are currently defined. diff --git a/pigs.1 b/pigs.1 index e55c554..28af561 100644 --- a/pigs.1 +++ b/pigs.1 @@ -22,6 +22,10 @@ or .SH DESCRIPTION +.ad l + +.nh + .br The socket and pipe interfaces allow control of the GPIO by passing @@ -45,10 +49,10 @@ whereas /dev/pigpio uses the pipe interface. .br .SS Features .br -o PWM on any of GPIO 0-31 +o hardware timed PWM on any of GPIO 0-31 .br -o servo pulses on any of GPIO 0-31 +o hardware timed servo pulses on any of GPIO 0-31 .br o reading/writing all of the GPIO in a bank as one operation @@ -514,11 +518,40 @@ configuration settings to \fBv\fP. .br +.IP "\fBFC h\fP - Close file handle" +.IP "" 4 +This command closes a file handle \fBh\fP previously opened with \fBFO\fP. + +.br +Upon success nothing is returned. On error a negative status code +will be returned. + +.br + +\fBExample\fP +.br + +.EX +$ pigs fc 0 # First close okay. +.br + +.br +$ pigs fc 0 # Second fails. +.br +-25 +.br +ERROR: unknown handle +.br + +.EE + +.br + .IP "\fBFG u stdy\fP - Set a glitch filter on a GPIO" .IP "" 4 .br -Level changes on the GPIO are not reported unless the level +Level changes on the GPIO \fBu\fP are not reported unless the level has been stable for at least \fBstdy\fP microseconds. The level is then reported. Level changes of less than \fBstdy\fP microseconds are ignored. @@ -529,11 +562,77 @@ after it was first detected. .br +\fBExample\fP +.br + +.EX +$ pigs fg 4 250 +.br + +.br +$ pigs fg 4 1000000 +.br +-125 +.br +ERROR: bad filter parameter +.br + +.EE + +.br + +.IP "\fBFL pat num\fP - List files which match pattern" +.IP "" 4 +This command returns a list of the files matching \fBpat\fP. Up +to \fBnum\fP bytes may be returned. + +.br +Upon success the count of returned bytes followed by the matching +files is returned. On error a negative status code will be returned. + +.br +A newline (0x0a) character separates each file name. + +.br +Only files which have a matching entry in /opt/pigpio/access may +be listed. + +.br +Suppose /opt/pigpio/access contains + +.br +/sys/bus/w1/devices/28*/w1_slave r + +.br + +\fBExample\fP +.br + +.EX +$ pigs -a fl "/sys/bus/w1/devices/28*/w1_slave" 5000 +.br +90 /sys/bus/w1/devices/28-000005d34cd2/w1_slave +.br +/sys/bus/w1/devices/28-001414abbeff/w1_slave +.br + +.br +$ pigs -a fl "/sys/bus/*" 5000 +.br +ERROR: no permission to access file +.br +-137 +.br + +.EE + +.br + .IP "\fBFN u stdy actv\fP - Set a noise filter on a GPIO" .IP "" 4 .br -Level changes on the GPIO are ignored until a level which has +Level changes on the GPIO \fBu\fP are ignored until a level which has been stable for \fBstdy\fP microseconds is detected. Level changes on the GPIO are then reported for \fBactv\fP microseconds after which the process repeats. @@ -545,6 +644,311 @@ such reports. .br +\fBExample\fP +.br + +.EX +$ pigs fn 7 250 1000 +.br + +.br +$ pigs fn 7 2500000 1000 +.br +-125 +.br +ERROR: bad filter parameter +.br + +.EE + +.br + +.IP "\fBFO file mode\fP - Open a file in mode" +.IP "" 4 +This function returns a handle to a file \fBfile\fP opened +in a specified mode \fBmode\fP. + +.br +Upon success a handle (>=0) is returned. On error a negative status code +will be returned. + +.br +File + +.br +A file may only be opened if permission is granted by an entry in +/opt/pigpio/access. This is intended to allow remote access to files +in a more or less controlled manner. + +.br +Each entry in /opt/pigpio/access takes the form of a file path +which may contain wildcards followed by a single letter permission. +The permission may be R for read, W for write, U for read/write, +and N for no access. + +.br +Where more than one entry matches a file the most specific rule +applies. If no entry matches a file then access is denied. + +.br +Suppose /opt/pigpio/access contains the following entries + +.br + +.EX +/home/* n +.br +/home/pi/shared/dir_1/* w +.br +/home/pi/shared/dir_2/* r +.br +/home/pi/shared/dir_3/* u +.br +/home/pi/shared/dir_1/file.txt n +.br + +.EE + +.br +Files may be written in directory dir_1 with the exception +of file.txt. + +.br +Files may be read in directory dir_2. + +.br +Files may be read and written in directory dir_3. + +.br +If a directory allows read, write, or read/write access then files may +be created in that directory. + +.br +In an attempt to prevent risky permissions the following paths are +ignored in /opt/pigpio/access. + +.br + +.EX +a path containing .. +.br +a path containing only wildcards (*?) +.br +a path containing less than two non-wildcard parts +.br + +.EE + +.br +Mode + +.br +The mode may have the following values. + +.br + +.EX + Value Meaning +READ 1 open file for reading +WRITE 2 open file for writing +RW 3 open file for reading and writing + +.EE + +.br +The following values may be or'd into the mode. + +.br + +.EX + Value Meaning +APPEND 4 All writes append data to the end of the file +CREATE 8 The file is created if it doesn't exist +TRUNC 16 The file is truncated + +.EE + +.br +Newly created files are owned by root with permissions owner read and write. + +.br + +\fBExample\fP +.br + +.EX +$ ls /ram/*.c +.br +/ram/command.c /ram/pigpiod.c /ram/pigs.c +.br +/ram/x_pigpiod_if.c /ram/pig2vcd.c /ram/pigpiod_if2.c +.br +/ram/x_pigpio.c /ram/x_repeat.c /ram/pigpio.c +.br +/ram/pigpiod_if.c /ram/x_pigpiod_if2.c +.br + +.br +# assumes /opt/pigpio/access contains the following line +.br +# /ram/*.c r +.br + +.br +$ pigs fo /ram/pigpio.c 1 +.br +0 +.br + +.br +$ pigs fo /ram/new.c 1 +.br +-128 +.br +ERROR: file open failed +.br + +.br +$ pigs fo /ram/new.c 9 +.br +1 +.br + +.br +$ ls /ram/*.c -l +.br +-rw-r--r-- 1 joan joan 42923 Jul 10 11:22 /ram/command.c +.br +-rw------- 1 root root 0 Jul 10 16:54 /ram/new.c +.br +-rw-r--r-- 1 joan joan 2971 Jul 10 11:22 /ram/pig2vcd.c +.br +-rw------- 1 joan joan 296235 Jul 10 11:22 /ram/pigpio.c +.br +-rw-r--r-- 1 joan joan 9266 Jul 10 11:22 /ram/pigpiod.c +.br +-rw-r--r-- 1 joan joan 37331 Jul 10 11:22 /ram/pigpiod_if2.c +.br +-rw-r--r-- 1 joan joan 33088 Jul 10 11:22 /ram/pigpiod_if.c +.br +-rw-r--r-- 1 joan joan 7990 Jul 10 11:22 /ram/pigs.c +.br +-rw-r--r-- 1 joan joan 19970 Jul 10 11:22 /ram/x_pigpio.c +.br +-rw-r--r-- 1 joan joan 20804 Jul 10 11:22 /ram/x_pigpiod_if2.c +.br +-rw-r--r-- 1 joan joan 19844 Jul 10 11:22 /ram/x_pigpiod_if.c +.br +-rw-r--r-- 1 joan joan 19907 Jul 10 11:22 /ram/x_repeat.c +.br + +.EE + +.br + +.IP "\fBFR h num\fP - Read bytes from file handle" +.IP "" 4 +This command returns up to \fBnum\fP bytes of data read from the +file associated with handle \fBh\fP. + +.br +Upon success the count of returned bytes followed by the bytes themselves +is returned. On error a negative status code will be returned. + +.br + +\fBExample\fP +.br + +.EX +$ pigs fr 0 10 +.br +5 48 49 128 144 255 +.br + +.br +$ pigs fr 0 10 +.br +0 +.br + +.EE + +.br + +.IP "\fBFS h num from\fP - Seek to file handle position" +.IP "" 4 +This command seeks to a position within the file associated +with handle \fBh\fP. + +.br +The number of bytes to move is \fBnum\fP. Positive offsets +move forward, negative offsets backwards. The move start +position is determined by \fBfrom\fP as follows. + +.br + +.EX + From +0 start +1 current position +2 end + +.EE + +.br +Upon success the new byte position within the file (>=0) is +returned. On error a negative status code will be returned. + +.br + +\fBExample\fP +.br + +.EX +$ pigs fs 0 0 0 # Seek to start of file plus 200 +.br +200 +.br + +.br +$ pigs fs 0 0 1 # Return current position +.br +200 +.br + +.br +$ pigs fs 0 0 2 # Seek to end of file, return size +.br +296235 +.br + +.EE + +.br + +.IP "\fBFW h bvs\fP - Write bytes to file handle" +.IP "" 4 +This command writes bytes \fBbvs\fP to the file +associated with handle \fBh\fP. + +.br +Upon success nothing is returned. On error a negative status code +will be returned. + +.br + +\fBExample\fP +.br + +.EX +$ pigs fw 0 23 45 67 89 +.br + +.EE + +.br + .IP "\fBGDC u\fP - Get GPIO PWM dutycycle" .IP "" 4 @@ -1710,6 +2114,96 @@ $ pigs p 4 255 # 100% .br +.IP "\fBPADG pad\fP - Get pad drive strength" +.IP "" 4 + +.br +This command gets the \fBpad\fP drive strength \fBpadma\fP in mA. + +.br +Returns the pad drive strength if OK. On error a negative status code +will be returned. + +.br + +.EX +Pad GPIO +0 0-27 +1 28-45 +2 46-53 + +.EE + +.br + +\fBExample\fP +.br + +.EX +$ pigs padg 0 +.br +8 +.br +$ pigs pads 0 16 +.br +$ pigs padg 0 +.br +16 +.br +pigs padg 3 +.br +-126 +.br +ERROR: bad pad number +.br + +.EE + +.br + +.IP "\fBPADS pad padma\fP - Set pad drive strength" +.IP "" 4 + +.br +This command sets the \fBpad\fP drive strength \fBpadma\fP in mA. + +.br +Upon success nothing is returned. On error a negative status code +will be returned. + +.br + +.EX +Pad GPIO +0 0-27 +1 28-45 +2 46-53 + +.EE + +.br + +\fBExample\fP +.br + +.EX +$ pigs pads 0 16 +.br +$ pigs padg 0 +.br +16 +.br +$ pigs pads 0 17 +.br +-127 +.br +ERROR: bad pad drive strength +.br + +.EE + +.br + .IP "\fBPARSE t\fP - Validate script" .IP "" 4 @@ -2447,8 +2941,9 @@ Upon success a handle (>=0) is returned. On error a negative status code will be returned. .br -The UART is /dev/ttyAMA0. The consoles are /dev/ttyx. The USB -devices are /dev/ttyUSBx. +The device name must start with /dev/tty or /dev/serial. + +.br .br The baud rate must be one of 50, 75, 110, 134, 150, @@ -2588,6 +3083,81 @@ $ pigs serwb 0 0xf0 .br +.IP "\fBSHELL name str\fP - Execute a shell command" +.IP "" 4 + +.br +This command uses the system call to execute a shell script \fBname\fP +with the given string \fBstr\fP as its parameter. + +.br +The exit status of the system call is returned if OK, otherwise +PI_BAD_SHELL_STATUS. + +.br +\fBname\fP must exist in /opt/pigpio/cgi and must be executable. + +.br +The returned exit status is normally 256 times that set +by the shell script exit function. If the script can't +be found 32512 will be returned. + +.br +The following table gives some example returned statuses. + +.br + +.EX +Script exit status Returned system call status +1 256 +5 1280 +10 2560 +200 51200 +script not found 32512 + +.EE + +.br + +\fBExample\fP +.br + +.EX +# pass two parameters, hello and world +.br +$ pigs shell scr1 hello world +.br +256 +.br + +.br +# pass three parameters, hello, string with spaces, and world +.br +$ pigs shell scr1 "hello 'string with spaces' world" +.br +256 +.br + +.br +# pass one parameter, hello string with spaces world +.br +$ pigs shell scr1 "\"hello string with spaces world\"" +.br +256 +.br + +.br +# non-existent script +.br +$ pigs shell scr78 par1 +.br +32512 +.br + +.EE + +.br + .IP "\fBSLR u num\fP - Read bit bang serial data from GPIO" .IP "" 4 @@ -3916,7 +4486,7 @@ The command expects the number of data bits per serial character. .br -.IP "\fBdev\fP - a tty serial device (/dev/tty*)" 0 +.IP "\fBdev\fP - a tty serial device (/dev/tty* or /dev/serial*)" 0 The command expects the name of a tty serial device, e.g. .br @@ -3928,6 +4498,28 @@ The command expects the name of a tty serial device, e.g. .br /dev/tty0 .br +/dev/serial0 +.br + +.EE + +.br + +.IP "\fBfile\fP - a file name" 0 +The file name must match an entry in /opt/pigpio/access. + +.br + +.IP "\fBfrom\fP - 0-2" 0 +Position to seek from \fBFS\fP. + +.br + +.EX + From +0 start +1 current position +2 end .EE @@ -3979,8 +4571,8 @@ of doing so range from no effect, to a crash, or corrupted data. The command expects a handle. .br -A handle is a number referencing an object opened by one of \fBI2CO\fP, \fBNO\fP, -\fBSERO\fP, \fBSPIO\fP. +A handle is a number referencing an object opened by one of \fBFO\fP, +\fBI2CO\fP, \fBNO\fP, \fBSERO\fP, \fBSPIO\fP. .br @@ -4020,24 +4612,58 @@ The value is returned by the mode get command. .br .EX -Mode Input Output ALT0 ALT1 ALT2 ALT3 ALT4 ALT5 -Code R W 0 1 2 3 4 5 -Value 0 1 4 5 6 7 3 2 +Mode Input Output ALT0 ALT1 ALT2 ALT3 ALT4 ALT5 +Code R W 0 1 2 3 4 5 +Value 0 1 4 5 6 7 3 2 .EE .br -.IP "\fBnum\fP - number of bytes to read (1-)" 0 -The command expects the number of bytes to read. +.IP "\fBmode\fP - file open mode" 0 +One of the following values. + +.br + +.EX + Value Meaning +READ 1 open file for reading +WRITE 2 open file for writing +RW 3 open file for reading and writing + +.EE + +.br +The following values can be or'd into the mode. + +.br + +.EX + Value Meaning +APPEND 4 All writes append data to the end of the file +CREATE 8 The file is created if it doesn't exist +TRUNC 16 The file is truncated + +.EE + +.br + +.IP "\fBname\fP - the name of a script" 0 +Only alphanumeric characters, '-' and '_' are allowed in the name. + +.br + +.IP "\fBnum\fP - maximum number of bytes to return (1-)" 0 +The command expects the maximum number of bytes to return. .br For the I2C and SPI commands the requested number of bytes will always be returned. .br -For the serial commands the smaller of the number of bytes available to be -read (which may be zero) and \fBnum\fP bytes will be returned. +For the serial and file commands the smaller of the number of +bytes available to be read (which may be zero) and \fBnum\fP bytes +will be returned. .br @@ -4075,11 +4701,38 @@ There is no mechanism to read the pull up down state. .br +.IP "\fBpad\fP - 0-2" 0 +A set of GPIO which share common drivers. + +.br + +.EX +Pad GPIO +0 0-27 +1 28-45 +2 46-53 + +.EE + +.br + +.IP "\fBpadma\fP - 1-16" 0 +The mA which may be drawn from each GPIO whilst still guaranteeing the +high and low levels. + +.br + .IP "\fBpars\fP - script parameters" 0 The command expects 0 to 10 numbers as parameters to be passed to the script. .br +.IP "\fBpat\fP - a file name pattern" 0 +A file path which may contain wildcards. To be accessible the path +must match an entry in /opt/pigpio/access. + +.br + .IP "\fBpdc\fP - hardware PWM dutycycle (0-1000000)" 0 The command expects a dutycycle. @@ -4141,8 +4794,13 @@ the active part of a noise filter (\fBFN\fP). .br -.IP "\fBt\fP - text (a string of text)" 0 -The command expects a text string. +.IP "\fBstr\fP - a string" 0 +The command expects a string. + +.br + +.IP "\fBt\fP - a string" 0 +The command expects a string. .br diff --git a/pigs.c b/pigs.c index 1e87d3c..d4c91d0 100644 --- a/pigs.c +++ b/pigs.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 34+ +This version is for pigpio version 55+ */ #include @@ -48,8 +48,8 @@ This program provides a socket interface to some of the commands available from pigpio. */ -char command_buf[8192]; -char response_buf[8192]; +char command_buf[CMD_MAX_EXTENSION]; +char response_buf[CMD_MAX_EXTENSION]; int printFlags = 0; @@ -171,7 +171,10 @@ void print_result(int sock, int rv, cmdCmd_t cmd) printf("%s", cmdUsage); break; - case 6: /* BI2CZ CF2 I2CPK I2CRD I2CRI I2CRK I2CZ SERR SLR SPIX SPIR */ + case 6: /* + BI2CZ CF2 FL FR I2CPK I2CRD I2CRI I2CRK I2CZ + SERR SLR SPIX SPIR + */ printf("%d", r); if (r < 0) fatal("ERROR: %s", cmdErrStr(r)); if (r > 0) @@ -186,7 +189,8 @@ void print_result(int sock, int rv, cmdCmd_t cmd) else if (printFlags & PRINT_ASCII) { - if ((ch > 31) && (ch < 127)) printf("%c", ch); + if (isprint(ch) || (ch == '\n') || (ch == '\r')) + printf("%c", ch); else printf("\\x%02hhx", ch); } else printf(" %hhu", response_buf[i]); @@ -221,6 +225,8 @@ void get_extensions(int sock, int command, int res) { case PI_CMD_BI2CZ: case PI_CMD_CF2: + case PI_CMD_FL: + case PI_CMD_FR: case PI_CMD_I2CPK: case PI_CMD_I2CRD: case PI_CMD_I2CRI: diff --git a/setup.py b/setup.py index 3e0a76d..a10af60 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='pigpio', - version='1.31', + version='1.32', author='joan', author_email='joan@abyz.co.uk', maintainer='joan', diff --git a/x_pigs b/x_pigs index 1435493..38fe120 100755 --- a/x_pigs +++ b/x_pigs @@ -50,7 +50,7 @@ s=$(pigs bs2 0) if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi s=$(pigs h) -if [[ ${#s} = 4593 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi +if [[ ${#s} = 4966 ]]; 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