This commit is contained in:
joan 2014-04-19 12:19:29 +01:00
parent 78bbfe4668
commit 306b9ad30b
17 changed files with 2069 additions and 1380 deletions

11
README
View File

@ -22,11 +22,18 @@ o the Python module pigpio.py
TEST (optional)
*** WARNING ************************************************
* *
* All the tests make extensive use of gpio 4 (pin P1-7). *
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
************************************************************
To test the library do
sudo ./x_pigpio
To text the pigpio daemon do
To test the pigpio daemon do
sudo pigpiod
@ -41,7 +48,7 @@ x_pigpio.c, pig2vcd.c, and pigpiod.c show examples of interfacing
with the pigpio library.
pigs.c, pigpio.py, x_pigpiod_if.c, x_pigpio.py, x_pigs, and x_pipe
show examples of interfacing with the pigpiod daemon.
show examples of interfacing with the pigpio daemon.
DAEMON

949
command.c

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 13+
This version is for pigpio version 14+
*/
#ifndef COMMAND_H
@ -39,19 +39,18 @@ This version is for pigpio version 13+
#define MAX_PARAM 512
#define PARSE_FLAGS_PARAMS 1
#define PARSE_FLAGS_VARS 2
#define CMD_UNKNOWN_CMD -1
#define CMD_BAD_PARAMETER -2
#define CMD_NUMERIC 1
#define CMD_PARAM 2
#define CMD_VAR 3
#define CMD_VAR 2
#define CMD_PAR 3
typedef struct
{
int flags;
int eaten;
uint8_t opt[8];
} gpioCtlParse_t;
int eaten;
int8_t opt[4];
} cmdCtlParse_t;
typedef struct
{
@ -61,11 +60,41 @@ typedef struct
int rv; /* command return value type */
} cmdInfo_t;
typedef struct
{
uint32_t tag;
int step;
} cmdTagStep_t;
typedef struct
{
uint32_t p[7];
int8_t opt[4];
} cmdInstr_t;
typedef struct
{
/*
+-----------+---------+---------+----------------+
| PARAMS... | VARS... | CMDS... | STRING AREA... |
+-----------+---------+---------+----------------+
*/
int *par;
int *var;
cmdInstr_t *instr;
int instrs;
char *str_area;
int str_area_len;
int str_area_pos;
} cmdScript_t;
extern cmdInfo_t cmdInfo[];
extern char *cmdUsage;
int cmdParse(char *buf, uint32_t *p, void **v, gpioCtlParse_t *ctlParse);
int cmdParse(char *buf, uint32_t *p, void **v, cmdCtlParse_t *ctl);
int cmdParseScript(char *script, cmdScript_t *s, int diags);
char *cmdErrStr(int error);

1191
pigpio.c

File diff suppressed because it is too large Load Diff

409
pigpio.h
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 13
This version is for pigpio version 14
*/
#ifndef PIGPIO_H
@ -86,7 +86,7 @@ This version is for pigpio version 13
#include <stdint.h>
#include <pthread.h>
#define PIGPIO_VERSION 13
#define PIGPIO_VERSION 14
/*-------------------------------------------------------------------------*/
@ -125,18 +125,21 @@ gpioNotifyBegin Begin a gpio(s) changed notification.
gpioNotifyPause Pause a gpio(s) changed notification.
gpioNotifyClose Close a gpio(s) changed notification.
gpioWaveClear Initialises a new waveform.
gpioWaveClear Deletes all waveforms.
gpioWaveAddNew Starts a new waveform.
gpioWaveAddGeneric Adds a series of pulses to the waveform.
gpioWaveAddSerial Adds serial data to the waveform.
gpioWaveTxStart Transmits the waveform.
gpioWaveCreate Creates a waveform from added data.
gpioWaveDelete Deletes one or more waveforms.
gpioWaveTxStart Creates/transmits a waveform (DEPRECATED).
gpioWaveTxSend Transmits a waveform.
gpioWaveTxBusy Checks to see if the waveform has ended.
gpioWaveTxStop Aborts the current waveform.
gpioSerialReadOpen Opens a gpio for reading serial data.
gpioSerialRead Reads serial data from a gpio.
gpioSerialReadClose Closes a gpio for reading serial data.
gpioWaveGetMicros Length in microseconds of the current waveform.
gpioWaveGetHighMicros Length of longest waveform so far.
gpioWaveGetMaxMicros Absolute maximum allowed micros.
@ -149,6 +152,10 @@ gpioWaveGetCbs Length in cbs of the current waveform.
gpioWaveGetHighCbs Length of longest waveform so far.
gpioWaveGetMaxCbs Absolute maximum allowed cbs.
gpioSerialReadOpen Opens a gpio for reading serial data.
gpioSerialRead Reads serial data from a gpio.
gpioSerialReadClose Closes a gpio for reading serial data.
gpioTrigger Send a trigger pulse to a gpio.
gpioSetWatchdog Set a watchdog on a gpio.
@ -281,7 +288,17 @@ typedef struct
int clk_pol; /* clock off state */
int clk_pha; /* clock phase */
int clk_us; /* clock micros */
} gpioSPI_t;
} rawSPI_t;
typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */
unsigned long info;
unsigned long src;
unsigned long dst;
unsigned long length;
unsigned long stride;
unsigned long next;
unsigned long pad[2];
} rawCbs_t;
typedef void (*gpioAlertFunc_t) (int gpio,
int level,
@ -873,34 +890,26 @@ int gpioNotifyClose(unsigned handle);
/*-------------------------------------------------------------------------*/
int gpioWaveClear(void);
/*-------------------------------------------------------------------------*/
/* This function initialises a new waveform.
/* This function clears all waveforms and any data added by calls to the
gpioWaveAdd* functions.
Returns 0 if OK.
A waveform comprises one of more pulses. Each pulse consists of a
gpioPulse_t structure.
typedef struct
{
uint32_t gpioOn;
uint32_t gpioOff;
uint32_t usDelay;
} gpioPulse_t;
The fields specify
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense to
set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with the
specified delay between the pulse and the next.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveAddNew(void);
/*-------------------------------------------------------------------------*/
/* This function starts a new empty waveform. You wouldn't normally need
to call this function as it is automatically called after a waveform is
created with the gpioWaveCreate function.
Returns 0 if OK.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
/*-------------------------------------------------------------------------*/
@ -911,7 +920,7 @@ int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t * pulses);
NOTES:
The pulses are interleaved in time order within the existing waveform
The pulses are interleaved in time order within the existing waveform
(if any).
Merging allows the waveform to be built in parts, that is the settings
@ -956,16 +965,97 @@ int gpioWaveAddSerial(unsigned user_gpio,
#define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
#define PI_MAX_WAVES 100
/*-------------------------------------------------------------------------*/
int gpioWaveTxStart(unsigned mode);
int gpioWaveCreate(void);
/*-------------------------------------------------------------------------*/
/* This function transmits the current waveform. The mode determines
whether the waveform is sent once or cycles endlessly.
/* This function creates a waveform from the data provided by the prior
calls to the gpioWaveAdd* functions. Upon success a positive wave id
is returned.
The data provided by the gpioWaveAdd* functions is consumed by this
function.
As many waveforms may be created as there is space available. The
wave id is passed to gpioWaveTxSend to specify the waveform to transmit.
Normal usage would be
Step 1. gpioWaveClear to clear all waveforms and added data.
Step 2. gpioWaveAdd* calls to supply the waveform data.
Step 3. gpioWaveCreate to create the waveform and get a unique id
Repeat steps 2 and 3 as needed.
Step 4. gpioWaveTxSend with the id of the waveform to transmit.
A waveform comprises one of more pulses. Each pulse consists of a
gpioPulse_t structure.
typedef struct
{
uint32_t gpioOn;
uint32_t gpioOff;
uint32_t usDelay;
} gpioPulse_t;
The fields specify
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense to
set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with the
specified delay between the pulse and the next.
Returns the new waveform id if OK, otherwise PI_EMPTY_WAVEFORM,
PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveDelete(unsigned wave_id);
/*-------------------------------------------------------------------------*/
/* This function deletes all created waveforms with ids greater than or
equal to wave_id.
Wave ids are allocated in order, 0, 1, 2, etc.
Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveTxStart(unsigned mode); /* DEPRECATED */
/*-------------------------------------------------------------------------*/
/* This function creates and then transmits a waveform. The mode
determines whether the waveform is sent once or cycles endlessly.
This function is deprecated and should no longer be used. Use
gpioWaveCreate/gpioWaveTxSend instead.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveTxSend(unsigned wave_id, unsigned mode);
/*-------------------------------------------------------------------------*/
/* This function transmits the waveform with id wave_id. The mode
determines whether the waveform is sent once or cycles endlessly.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
*/
#define PI_WAVE_MODE_ONE_SHOT 0
#define PI_WAVE_MODE_REPEAT 1
@ -991,46 +1081,7 @@ int gpioWaveTxStop(void);
NOTES:
This function is intended to stop a waveform started with the repeat mode.
*/
/*-------------------------------------------------------------------------*/
int gpioSerialReadOpen(unsigned user_gpio, unsigned baud);
/*-------------------------------------------------------------------------*/
/* This function opens a gpio for reading serial data.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
or PI_GPIO_IN_USE.
The serial data is returned in a cyclic buffer and is read using
gpioSerialRead().
It is the caller's responsibility to read data from the cyclic buffer
in a timely fashion.
*/
/*-------------------------------------------------------------------------*/
int gpioSerialRead(unsigned user_gpio, void *buf, size_t bufSize);
/*-------------------------------------------------------------------------*/
/* This function copies up to bufSize bytes of data read from the
serial cyclic buffer to the buffer starting at buf.
Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
or PI_NOT_SERIAL_GPIO.
*/
/*-------------------------------------------------------------------------*/
int gpioSerialReadClose(unsigned user_gpio);
/*-------------------------------------------------------------------------*/
/* This function closes a gpio for reading serial data.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
This function is intended to stop a waveform started in repeat mode.
*/
@ -1114,6 +1165,45 @@ int gpioWaveGetMaxCbs(void);
/*-------------------------------------------------------------------------*/
int gpioSerialReadOpen(unsigned user_gpio, unsigned baud);
/*-------------------------------------------------------------------------*/
/* This function opens a gpio for reading serial data.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, PI_BAD_WAVE_BAUD,
or PI_GPIO_IN_USE.
The serial data is returned in a cyclic buffer and is read using
gpioSerialRead().
It is the caller's responsibility to read data from the cyclic buffer
in a timely fashion.
*/
/*-------------------------------------------------------------------------*/
int gpioSerialRead(unsigned user_gpio, void *buf, size_t bufSize);
/*-------------------------------------------------------------------------*/
/* This function copies up to bufSize bytes of data read from the
serial cyclic buffer to the buffer starting at buf.
Returns the number of bytes copied if OK, otherwise PI_BAD_USER_GPIO
or PI_NOT_SERIAL_GPIO.
*/
/*-------------------------------------------------------------------------*/
int gpioSerialReadClose(unsigned user_gpio);
/*-------------------------------------------------------------------------*/
/* This function closes a gpio for reading serial data.
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
*/
/*-------------------------------------------------------------------------*/
int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
/*-------------------------------------------------------------------------*/
@ -1124,7 +1214,7 @@ int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
or PI_BAD_PULSELEN.
*/
#define PI_MAX_PULSELEN 100
#define PI_MAX_PULSELEN 50
/*-------------------------------------------------------------------------*/
@ -1351,13 +1441,15 @@ int gpioStoreScript(char *script);
otherwise PI_BAD_SCRIPT.
*/
#define MAX_SCRIPT_LABELS 50
#define MAX_SCRIPT_VARS 150
#define MAX_SCRIPT_PARAMS 10
#define PI_MAX_SCRIPTS 32
#define PI_MAX_SCRIPT_TAGS 50
#define PI_MAX_SCRIPT_VARS 150
#define PI_MAX_SCRIPT_PARAMS 10
/* ----------------------------------------------------------------------- */
int gpioRunScript(int script_id, unsigned numParam, uint32_t *param);
int gpioRunScript(unsigned script_id, unsigned numParam, uint32_t *param);
/* ----------------------------------------------------------------------- */
/* This function runs a stored script.
@ -1371,7 +1463,7 @@ int gpioRunScript(int script_id, unsigned numParam, uint32_t *param);
/* ----------------------------------------------------------------------- */
int gpioScriptStatus(int script_id, uint32_t *param);
int gpioScriptStatus(unsigned script_id, uint32_t *param);
/* ----------------------------------------------------------------------- */
/* This function returns the run status of a stored script as well as
the current values of parameters 0 to 9.
@ -1399,7 +1491,7 @@ int gpioScriptStatus(int script_id, uint32_t *param);
/* ----------------------------------------------------------------------- */
int gpioStopScript(int script_id);
int gpioStopScript(unsigned script_id);
/* ----------------------------------------------------------------------- */
/* This function stops a running script.
@ -1409,7 +1501,7 @@ int gpioStopScript(int script_id);
/* ----------------------------------------------------------------------- */
int gpioDeleteScript(int script_id);
int gpioDeleteScript(unsigned script_id);
/* ----------------------------------------------------------------------- */
/* This function deletes a stored script.
@ -1615,7 +1707,8 @@ uint32_t gpioDelay(uint32_t micros);
Returns the actual length of the delay in microseconds.
*/
#define PI_MAX_MICS_DELAY 1000000 /* 1 second */
#define PI_MAX_MILS_DELAY 60000 /* 60 seconds */
/*-------------------------------------------------------------------------*/
uint32_t gpioTick(void);
@ -1860,12 +1953,13 @@ int gpioCfgInternals(unsigned what,
int value);
/*-------------------------------------------------------------------------*/
/* Used to tune internal settings.
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
int gpioWaveAddSPI(
gpioSPI_t *spi,
int rawWaveAddSPI(
rawSPI_t *spi,
unsigned offset,
unsigned ss,
uint8_t *tx_bits,
@ -1883,36 +1977,59 @@ int gpioWaveAddSPI(
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_BAD_USER_GPIO, PI_BAD_SER_OFFSET, or PI_TOO_MANY_PULSES.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
unsigned rawWaveCB(void);
/* ----------------------------------------------------------------------- */
/*
Returns the number of the cb being currently output.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
uint32_t waveGetRawOut(int pos);
rawCbs_t * rawWaveCBAdr(int n);
/* ----------------------------------------------------------------------- */
/*
Return the Linux address of contol block n.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
uint32_t rawWaveGetOut(int pos);
/* ----------------------------------------------------------------------- */
/* Gets the wave output parameter stored at pos.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
void waveSetRawOut(int pos, uint32_t value);
void rawWaveSetOut(int pos, uint32_t value);
/* ----------------------------------------------------------------------- */
/* Sets the wave output parameter stored at pos to value.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
uint32_t waveGetRawIn(int pos);
uint32_t rawWaveGetIn(int pos);
/* ----------------------------------------------------------------------- */
/* Gets the wave input value parameter stored at pos.
Not intended for general use.
*/
/* ----------------------------------------------------------------------- */
void waveSetRawIn(int pos, uint32_t value);
void rawWaveSetIn(int pos, uint32_t value);
/* ----------------------------------------------------------------------- */
/* Sets the wave input value stored at pos to value.
Not intended for general use.
*/
@ -1944,17 +2061,19 @@ void time_sleep(double seconds);
/*-------------------------------------------------------------------------*/
void gpioDumpWave(void);
void rawDumpWave(void);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of the current waveform to stderr.
Not intended for general use.
*/
/*-------------------------------------------------------------------------*/
void gpioDumpScript(int s);
void rawDumpScript(int s);
/*-------------------------------------------------------------------------*/
/* Used to print a readable version of a script to stderr.
Not intended for general use.
*/
@ -2011,8 +2130,14 @@ void gpioDumpScript(int s);
#define PI_CMD_SLR 43
#define PI_CMD_SLRC 44
#define PI_CMD_PROCP 45
#define PI_CMD_MICRO 46
#define PI_CMD_MILLI 47
#define PI_CMD_MICS 46
#define PI_CMD_MILS 47
#define PI_CMD_PARSE 48
#define PI_CMD_WVCRE 49
#define PI_CMD_WVDEL 50
#define PI_CMD_WVTX 51
#define PI_CMD_WVTXR 52
#define PI_CMD_WVNEW 53
/*
@ -2031,49 +2156,43 @@ after this command is issued.
#define PI_CMD_SCRIPT 800
#define PI_CMD_ADDI 800
#define PI_CMD_ADDV 801
#define PI_CMD_ANDI 802
#define PI_CMD_ANDV 803
#define PI_CMD_CALL 804
#define PI_CMD_CMPI 805
#define PI_CMD_CMPV 806
#define PI_CMD_DCRA 807
#define PI_CMD_DCRV 808
#define PI_CMD_HALT 809
#define PI_CMD_INRA 810
#define PI_CMD_INRV 811
#define PI_CMD_JM 812
#define PI_CMD_JMP 813
#define PI_CMD_JNZ 814
#define PI_CMD_JP 815
#define PI_CMD_JZ 816
#define PI_CMD_LABEL 817
#define PI_CMD_LDAI 818
#define PI_CMD_LDAP 819
#define PI_CMD_LDAV 820
#define PI_CMD_LDPA 821
#define PI_CMD_LDVA 822
#define PI_CMD_LDVI 823
#define PI_CMD_LDVV 824
#define PI_CMD_ORI 827
#define PI_CMD_ORV 828
#define PI_CMD_POPA 829
#define PI_CMD_POPV 830
#define PI_CMD_PUSHA 831
#define PI_CMD_PUSHV 832
#define PI_CMD_RET 833
#define PI_CMD_RAL 834
#define PI_CMD_RAR 835
#define PI_CMD_SUBI 836
#define PI_CMD_SUBV 837
#define PI_CMD_SWAPA 838
#define PI_CMD_SWAPV 839
#define PI_CMD_SYS 840
#define PI_CMD_WAITI 841
#define PI_CMD_WAITV 842
#define PI_CMD_XORI 843
#define PI_CMD_XORV 844
#define PI_CMD_ADD 800
#define PI_CMD_AND 801
#define PI_CMD_CALL 802
#define PI_CMD_CMP 803
#define PI_CMD_DCR 804
#define PI_CMD_DCRA 805
#define PI_CMD_DIV 806
#define PI_CMD_HALT 807
#define PI_CMD_INR 808
#define PI_CMD_INRA 809
#define PI_CMD_JM 810
#define PI_CMD_JMP 811
#define PI_CMD_JNZ 812
#define PI_CMD_JP 813
#define PI_CMD_JZ 814
#define PI_CMD_TAG 815
#define PI_CMD_LD 816
#define PI_CMD_LDA 817
#define PI_CMD_MLT 818
#define PI_CMD_MOD 819
#define PI_CMD_OR 820
#define PI_CMD_POP 821
#define PI_CMD_POPA 822
#define PI_CMD_PUSH 823
#define PI_CMD_PUSHA 824
#define PI_CMD_RET 825
#define PI_CMD_RL 826
#define PI_CMD_RLA 827
#define PI_CMD_RR 828
#define PI_CMD_RRA 829
#define PI_CMD_STA 830
#define PI_CMD_SUB 831
#define PI_CMD_SYS 832
#define PI_CMD_WAIT 833
#define PI_CMD_X 834
#define PI_CMD_XA 835
#define PI_CMD_XOR 836
/*-------------------------------------------------------------------------*/
@ -2126,15 +2245,15 @@ after this command is issued.
#define PI_BAD_WVSC_COMMND -43 /* bad WVSC subcommand */
#define PI_BAD_WVSM_COMMND -44 /* bad WVSM subcommand */
#define PI_BAD_WVSP_COMMND -45 /* bad WVSP subcommand */
#define PI_BAD_PULSELEN -46 /* trigger pulse length > 100 */
#define PI_BAD_PULSELEN -46 /* trigger pulse length > 50 */
#define PI_BAD_SCRIPT -47 /* invalid script */
#define PI_BAD_SCRIPT_ID -48 /* unknown script id */
#define PI_BAD_SER_OFFSET -49 /* add serial data offset > 30 minutes */
#define PI_GPIO_IN_USE -50 /* gpio already in use */
#define PI_BAD_SERIAL_COUNT -51 /* must read at least a byte at a time */
#define PI_BAD_PARAM_NUM -52 /* script parameter must be 0-9 */
#define PI_DUP_LABEL -53 /* script has duplicate label */
#define PI_TOO_MANY_LABELS -54 /* script has too many labels */
#define PI_DUP_TAG -53 /* script has duplicate tag */
#define PI_TOO_MANY_TAGS -54 /* script has too many tags */
#define PI_BAD_SCRIPT_CMD -55 /* illegal script command */
#define PI_BAD_VAR_NUM -56 /* script variable must be 0-149 */
#define PI_NO_SCRIPT_ROOM -57 /* no more room for scripts */
@ -2143,6 +2262,14 @@ after this command is issued.
#define PI_SOCK_WRIT_FAILED -60 /* socket write failed */
#define PI_TOO_MANY_PARAM -61 /* too many script parameters > 10 */
#define PI_NOT_HALTED -62 /* script already running or failed */
#define PI_BAD_TAG -63 /* script has unresolved tag */
#define PI_BAD_MICS_DELAY -64 /* bad MICS delay (too large) */
#define PI_BAD_MILS_DELAY -65 /* bad MILS delay (too large) */
#define PI_BAD_WAVE_ID -66 /* non existent wave id */
#define PI_TOO_MANY_CBS -67 /* No more CBs for waveform */
#define PI_TOO_MANY_OOL -68 /* No more OOL for waveform */
#define PI_EMPTY_WAVEFORM -69 /* attempt to create an empty waveform */
#define PI_NO_WAVEFORM_ID -70 /* no more waveforms */
/*-------------------------------------------------------------------------*/

322
pigpio.py
View File

@ -26,7 +26,8 @@ The pigpio module's main features are:
- provision of servo pulses on any number of gpios 0-31 simultaneously.
- callbacks when any of gpios 0-31 change state.
- callbacks when any of gpios 0-31 change state (callbacks receive the
time of the event accurate to a few microseconds).
- reading/writing gpios and setting their modes (typically input
or output).
@ -34,6 +35,11 @@ The pigpio module's main features are:
- reading/writing all of the gpios in a bank (0-31, 32-53) as a single
operation.
- creating and transmitting precisely timed waveforms (accurate
to a few microseconds).
- creating and running scripts on the pigpio daemon.
Notes
ALL gpios are identified by their Broadcom number.
@ -76,7 +82,7 @@ import threading
import os
import atexit
VERSION = "1.4"
VERSION = "1.5"
# gpio levels
@ -168,11 +174,16 @@ _PI_CMD_SLRO= 42
_PI_CMD_SLR= 43
_PI_CMD_SLRC= 44
_PI_CMD_PROCP=45
_PI_CMD_MICRO=46
_PI_CMD_MILLI=47
_PI_CMD_PARSE=48
_PI_CMD_WVCRE=49
_PI_CMD_WVDEL=50
_PI_CMD_WVTX =51
_PI_CMD_WVTXR=52
_PI_CMD_NOIB= 99
# pigpio error numbers
_PI_INIT_FAILED =-1
@ -228,8 +239,8 @@ PI_BAD_SER_OFFSET =-49
PI_GPIO_IN_USE =-50
PI_BAD_SERIAL_COUNT =-51
PI_BAD_PARAM_NUM =-52
PI_DUP_LABEL =-53
PI_TOO_MANY_LABELS =-54
PI_DUP_TAG =-53
PI_TOO_MANY_TAGS =-54
PI_BAD_SCRIPT_CMD =-55
PI_BAD_VAR_NUM =-56
PI_NO_SCRIPT_ROOM =-57
@ -238,6 +249,14 @@ PI_SOCK_READ_FAILED =-59
PI_SOCK_WRIT_FAILED =-60
PI_TOO_MANY_PARAM =-61
PI_NOT_HALTED =-62
PI_BAD_TAG =-63
PI_BAD_MICS_DELAY =-64
PI_BAD_MILS_DELAY =-65
PI_BAD_WAVE_ID =-66
PI_TOO_MANY_CBS =-67
PI_TOO_MANY_OOL =-68
PI_EMPTY_WAVEFORM =-69
PI_NO_WAVEFORM_ID =-70
# pigpio error text
@ -285,15 +304,15 @@ _errors=[
[PI_BAD_WVSC_COMMND , "bad WVSC subcommand"],
[PI_BAD_WVSM_COMMND , "bad WVSM subcommand"],
[PI_BAD_WVSP_COMMND , "bad WVSP subcommand"],
[PI_BAD_PULSELEN , "trigger pulse length > 100"],
[PI_BAD_PULSELEN , "trigger pulse length > 50"],
[PI_BAD_SCRIPT , "invalid script"],
[PI_BAD_SCRIPT_ID , "unknown script id"],
[PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"],
[PI_GPIO_IN_USE , "gpio already in use"],
[PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"],
[PI_BAD_PARAM_NUM , "script parameter must be 0-9"],
[PI_DUP_LABEL , "script has duplicate label"],
[PI_TOO_MANY_LABELS , "script has too many labels"],
[PI_DUP_TAG , "script has duplicate tag"],
[PI_TOO_MANY_TAGS , "script has too many tags"],
[PI_BAD_SCRIPT_CMD , "illegal script command"],
[PI_BAD_VAR_NUM , "script variable must be 0-149"],
[PI_NO_SCRIPT_ROOM , "no more room for scripts"],
@ -302,6 +321,14 @@ _errors=[
[PI_SOCK_WRIT_FAILED , "socket write failed"],
[PI_TOO_MANY_PARAM , "too many script parameters (> 10)"],
[PI_NOT_HALTED , "script already running or failed"],
[PI_BAD_TAG , "script has unresolved tag"],
[PI_BAD_MICS_DELAY , "bad MICS delay (too large)"],
[PI_BAD_MILS_DELAY , "bad MILS delay (too large)"],
[PI_BAD_WAVE_ID , "non existent wave id"],
[PI_TOO_MANY_CBS , "No more CBs for waveform"],
[PI_TOO_MANY_OOL , "No more OOL for waveform"],
[PI_EMPTY_WAVEFORM , "attempt to create an empty waveform"],
[PI_NO_WAVEFORM_ID , "No more waveform ids"],
]
@ -402,11 +429,9 @@ def _pigpio_command_ext(sock, cmd, p1, p2, extents):
extents: additional data blocks
"""
if sock is not None:
sock.send(struct.pack('IIII', cmd, p1, p2, 0))
for ext in extents:
sock.sendall(ext)
msg = struct.pack('IIII', cmd, p1, p2, 0)
for ext in extents: msg += ext
sock.sendall(msg)
x, y, z, res = struct.unpack('IIII', sock.recv(16))
return res
else:
@ -523,7 +548,7 @@ class _wait_for_edge:
_notify.append(self.callb)
self.start = time.time()
while (self.trigger == False) and ((time.time()-self.start) < timeout):
time.sleep(0.1)
time.sleep(0.05)
_notify.remove(self.callb)
def func(self, gpio, level, tick):
@ -916,7 +941,7 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
Example 1: standard 50 Hz hobby servo updates
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -943,7 +968,7 @@ def set_servo_pulsewidth(user_gpio, pulsewidth):
Example 2: 400 Hz ESC type servo updates
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -1102,7 +1127,7 @@ def set_watchdog(user_gpio, timeout):
Example
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -1189,7 +1214,7 @@ def clear_bank_1(levels):
Example
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
@ -1255,7 +1280,7 @@ def set_bank_1(levels):
Example
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
@ -1317,7 +1342,7 @@ def get_current_tick():
Example
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -1406,26 +1431,19 @@ class pulse:
def wave_clear():
"""
Initialises a new waveform.
Returns 0 if OK.
A waveform comprises one of more pulses.
A pulse specifies
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense
to set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with
the specified delay between the pulse and the next.
Clears all waveforms and any data added by calls to the
wave_add_* functions.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVCLR, 0, 0))
def wave_add_new():
"""
Starts a new empty waveform. You wouldn't normally need
to call this function as it is automatically called after a
waveform is created with the wave_create function.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVNEW, 0, 0))
def wave_add_generic(pulses):
"""
Adds a list of pulses to the current waveform.
@ -1447,62 +1465,54 @@ def wave_add_generic(pulses):
Example
#!/usr/bin/env python
import time
import pigpio
class stepper:
def __init__(self, g1, g2, g3, g4):
self.g1 = g1
self.g2 = g2
self.g3 = g3
self.g4 = g4
self.all = (1<<g1 | 1<<g2 | 1<<g3 | 1<<g4)
pigpio.set_mode(g1, pigpio.OUTPUT)
pigpio.set_mode(g2, pigpio.OUTPUT)
pigpio.set_mode(g3, pigpio.OUTPUT)
pigpio.set_mode(g4, pigpio.OUTPUT)
def step_on(self, pos):
if pos == 0: return (1<<self.g4)
elif pos == 1: return (1<<self.g3 | 1<<self.g4)
elif pos == 2: return (1<<self.g3)
elif pos == 3: return (1<<self.g2 | 1<<self.g3)
elif pos == 4: return (1<<self.g2)
elif pos == 5: return (1<<self.g1 | 1<<self.g2)
elif pos == 6: return (1<<self.g1)
elif pos == 7: return (1<<self.g1 | 1<<self.g4)
else: return 0
def step_off(self, pos):
return self.step_on(pos) ^ self.all
G1=4
G2=22
pigpio.start()
s1 = stepper(14, 15, 18, 17)
s2 = stepper(24, 25, 8, 7)
pigpio.set_mode(G1, pigpio.OUTPUT)
pigpio.set_mode(G2, pigpio.OUTPUT)
f1=[] # pulses to drive stepper 1 forward
b2=[] # pulses to drive stepper 2 backward
for i in range(8):
f1.append(pigpio.pulse(s1.step_on(i), s1.step_off(i), 1200))
b2.append(pigpio.pulse(s2.step_on(7-i), s2.step_off(7-i), 1200))
flash_500=[] # flash every 500 ms
flash_100=[] # flash every 100 ms
pigpio.wave_clear() # initialise a new waveform
# ON OFF DELAY
pigpio.wave_add_generic(f1) # add stepper 1 forward
pigpio.wave_add_generic(b2) # add stepper 2 backward
flash_500.append(pigpio.pulse(1<<G1, 1<<G2, 500000))
flash_500.append(pigpio.pulse(1<<G2, 1<<G1, 500000))
pigpio.wave_tx_repeat() # repeately transmit pulses
flash_100.append(pigpio.pulse(1<<G1, 1<<G2, 100000))
flash_100.append(pigpio.pulse(1<<G2, 1<<G1, 100000))
time.sleep(10)
pigpio.wave_clear() # clear any existing waveforms
pigpio.wave_add_generic(flash_500) # 500 ms flashes
f500 = pigpio.wave_create() # create and save id
pigpio.wave_add_generic(flash_100) # 100 ms flashes
f100 = pigpio.wave_create() # create and save id
pigpio.wave_send_repeat(f500)
time.sleep(4)
pigpio.wave_send_repeat(f100)
time.sleep(4)
pigpio.wave_send_repeat(f500)
time.sleep(4)
pigpio.wave_tx_stop() # stop waveform
pigpio.wave_clear() # clear all waveforms
pigpio.stop()
"""
# pigpio message format
@ -1511,12 +1521,15 @@ def wave_add_generic(pulses):
# I p2 0
## extension ##
# III on/off/delay * number of pulses
msg = ""
for p in pulses:
msg += struct.pack("III", p.gpio_on, p.gpio_off, p.delay)
extents = [msg]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_WVAG, len(pulses), 0, extents))
if len(pulses):
msg = ""
for p in pulses:
msg += struct.pack("III", p.gpio_on, p.gpio_off, p.delay)
extents = [msg]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_WVAG, len(pulses), 0, extents))
else:
return 0
def wave_add_serial(user_gpio, baud, offset, data):
"""
@ -1548,22 +1561,26 @@ def wave_add_serial(user_gpio, baud, offset, data):
import pigpio
GPIO=24
TX_GPIO=22
pigpio.start()
pigpio.set_mode(TX_GPIO, pigpio.OUTPUT)
pigpio.wave_clear() # initialise waveform
pigpio.wave_clear() # clear all waveforms
for i in range(10):
pigpio.wave_add_serial(
GPIO, 9600, i*2000000, "{} seconds in.\r\n".format(i*2))
TX_GPIO, 300, i*2000000, "{} seconds in.\r\n".format(i*2))
pigpio.wave_tx_start()
id = pigpio.wave_create()
pigpio.wave_send_once(id)
time.sleep(22)
pigpio.write(TX_GPIO, 0)
pigpio.stop()
"""
# pigpio message format
@ -1574,9 +1591,97 @@ def wave_add_serial(user_gpio, baud, offset, data):
# I baud
# I offset
# s data
extents = [struct.pack("I", baud),struct.pack("I", offset), data]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_WVAS, user_gpio, len(data), extents))
if len(data):
extents = [struct.pack("I", baud),struct.pack("I", offset), data]
return _u2i(_pigpio_command_ext(
_control, _PI_CMD_WVAS, user_gpio, len(data), extents))
else:
return 0
def wave_create():
"""
Creates a waveform from the data provided by the prior calls to the
wave_add_* functions. Upon success a positive wave id is returned.
The data provided by the wave_add_* functions is consumed by this
function.
As many waveforms may be created as there is space available. The
wave id is passed to wave_send_* to specify the waveform to transmit.
Normal usage would be
Step 1. wave_clear to clear all waveforms and added data.
Step 2. wave_add_* calls to supply the waveform data.
Step 3. wave_create to create the waveform and get a unique id
Repeat steps 2 and 3 as needed.
Step 4. wave_send_* with the id of the waveform to transmit.
A waveform comprises one or more pulses.
A pulse specifies
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense
to set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with
the specified delay between the pulse and the next.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVCRE, 0, 0))
def wave_delete(wave_id):
"""
Deletes all created waveforms with ids greater than or equal
to wave_id.
Wave ids are allocated in order, 0, 1, 2, etc.
Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVDEL, wave_id, 0))
def wave_tx_start():
"""
This function is deprecated and will be removed.
Use wave_create/wave_send_* instead.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVGO, 0, 0))
def wave_tx_repeat():
"""
This function is deprecated and will be removed.
Use wave_create/wave_send_* instead.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVGOR, 0, 0))
def wave_send_once(wave_id):
"""
Transmits the waveform with id wave_id. The waveform is sent once.
Returns the number of cbs in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVTX, wave_id, 0))
def wave_send_repeat(wave_id):
"""
Transmits the waveform with id wave_id. The waveform repeats until
wave_tx_stop is called or another call to wave_send_* is made.
Returns the number of cbs in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVTXR, wave_id, 0))
def wave_tx_busy():
"""
@ -1593,29 +1698,10 @@ def wave_tx_stop():
Returns 0 if OK.
This function is intended to stop a waveform started with
wave_tx_repeat().
wave_send_repeatedly.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVHLT, 0, 0))
def wave_tx_start():
"""
Transmits the current waveform. The waveform is sent once.
Returns the number of cbs in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVGO, 0, 0))
def wave_tx_repeat():
"""
Transmits the current waveform. The waveform repeats until
wave_tx_stop is called.
Returns the number of cbs in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
"""
return _u2i(_pigpio_command(_control, _PI_CMD_WVGOR, 0, 0))
def wave_get_micros():
"""
Returns the length in microseconds of the current waveform.
@ -1676,7 +1762,7 @@ def gpio_trigger(user_gpio, pulse_len=10, level=1):
pigpio.start()
for i in range(10):
for i in range(5):
pigpio.gpio_trigger(GPIO, (i*5)+10, 1)
time.sleep(1)
@ -1840,7 +1926,7 @@ class callback:
Example 1: user supplied edge and callback
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -1869,7 +1955,7 @@ class callback:
Example 2: user supplied edge, default (tally) callback
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -1904,7 +1990,7 @@ class callback:
Example 3: default edge and (tally) callback
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -1983,7 +2069,7 @@ def wait_for_edge(user_gpio, edge=RISING_EDGE, timeout=60.0):
Example 1: default edge and timeout
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time
@ -2007,7 +2093,7 @@ def wait_for_edge(user_gpio, edge=RISING_EDGE, timeout=60.0):
Example 2: user supplied edge and timeout
#!/usr/bin/python
#!/usr/bin/env python
import pigpio
import time

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 11+
This version is for pigpio version 14+
*/
#include <sys/types.h>
@ -59,6 +59,8 @@ static unsigned DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CHANNEL;
static unsigned socketPort = PI_DEFAULT_SOCKET_PORT;
static uint64_t updateMask = -1;
static int updateMaskSet = 0;
static FILE * errFifo;
void fatal(char *fmt, ...)
@ -183,7 +185,11 @@ static void initOpts(int argc, char *argv[])
case 'x':
mask = strtoll(optarg, &endptr, 0);
printf("mask=%llx\n", mask);
if (!*endptr) updateMask = mask;
if (!*endptr)
{
updateMask = mask;
updateMaskSet = 1;
}
else fatal("invalid -x option (%s)", optarg);
break;
@ -264,7 +270,7 @@ int main(int argc, char **argv)
gpioCfgSocketPort(socketPort);
if (updateMask != -1) gpioCfgPermissions(updateMask);
if (updateMaskSet) gpioCfgPermissions(updateMask);
/* start library */

View File

@ -606,6 +606,9 @@ uint32_t get_pigpio_version(void)
int wave_clear(void)
{return pigpio_command(gPigCommand, PI_CMD_WVCLR, 0, 0);}
int wave_add_new(void)
{return pigpio_command(gPigCommand, PI_CMD_WVNEW, 0, 0);}
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
{
gpioExtent_t ext[1];
@ -617,6 +620,8 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses)
gpioPulse_t[] pulses
*/
if (!numPulses) return 0;
ext[0].size = numPulses * sizeof(gpioPulse_t);
ext[0].ptr = pulses;
@ -637,6 +642,8 @@ int wave_add_serial(
char[] str
*/
if (!numChar) return 0;
ext[0].size = sizeof(unsigned);
ext[0].ptr = &baud;
@ -649,18 +656,30 @@ int wave_add_serial(
return pigpio_command_ext(gPigCommand, PI_CMD_WVAS, gpio, numChar, 3, ext);
}
int wave_create(void)
{return pigpio_command(gPigCommand, PI_CMD_WVCRE, 0, 0);}
int wave_delete(unsigned wave_id)
{return pigpio_command(gPigCommand, PI_CMD_WVDEL, wave_id, 0);}
int wave_tx_start(void) /* DEPRECATED */
{return pigpio_command(gPigCommand, PI_CMD_WVGO, 0, 0);}
int wave_tx_repeat(void) /* DEPRECATED */
{return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0);}
int wave_send_once(unsigned wave_id)
{return pigpio_command(gPigCommand, PI_CMD_WVTX, 0, 0);}
int wave_send_repeat(unsigned wave_id)
{return pigpio_command(gPigCommand, PI_CMD_WVTXR, 0, 0);}
int wave_tx_busy(void)
{return pigpio_command(gPigCommand, PI_CMD_WVBSY, 0, 0);}
int wave_tx_stop(void)
{return pigpio_command(gPigCommand, PI_CMD_WVHLT, 0, 0);}
int wave_tx_start(void)
{return pigpio_command(gPigCommand, PI_CMD_WVGO, 0, 0);}
int wave_tx_repeat(void)
{return pigpio_command(gPigCommand, PI_CMD_WVGOR, 0, 0);}
int wave_get_micros(void)
{return pigpio_command(gPigCommand, PI_CMD_WVSM, 0, 0);}
@ -743,10 +762,10 @@ int run_script(unsigned script_id, unsigned numPar, uint32_t *param)
(gPigCommand, PI_CMD_PROCR, script_id, numPar, 1, ext);
}
int script_status(int script_id, uint32_t *param)
int script_status(unsigned script_id, uint32_t *param)
{
int status;
uint32_t p[MAX_SCRIPT_PARAMS];
uint32_t p[PI_MAX_SCRIPT_PARAMS];
status = pigpio_command(gPigCommand, PI_CMD_PROCP, script_id, 0);

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h"
#define PIGPIOD_IF_VERSION 4
#define PIGPIOD_IF_VERSION 5
typedef enum
{
@ -514,62 +514,18 @@ uint32_t get_pigpio_version(void);
int wave_clear(void);
/* This function initialises a new waveform.
/* This function clears all waveforms and any data added by calls to the
wave_add_* functions.
Returns 0 if OK.
A waveform comprises one of more pulses. Each pulse consists of a
gpioPulse_t structure.
typedef struct
{
uint32_t gpioOn;
uint32_t gpioOff;
uint32_t usDelay;
} gpioPulse_t;
The fields specify
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense to
set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with the
specified delay between the pulse and the next.
*/
int wave_tx_busy(void);
/* This function checks to see if a waveform is currently being
transmitted.
Returns 1 if a waveform is currently being transmitted, otherwise 0.
*/
int wave_tx_stop(void);
/* This function stops the transmission of the current waveform.
int wave_add_new(void);
/* This function starts a new empty waveform. You wouldn't normally need
to call this function as it is automatically called after a waveform is
created with the wave_create function.
Returns 0 if OK.
This function is intended to stop a waveform started with the repeat mode.
*/
int wave_tx_start(void);
/* This function transmits the current waveform. The waveform is
sent once.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
int wave_tx_repeat(void);
/* This function transmits the current waveform. The waveform repeats
endlessly until wave_tx_stop is called.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_MODE.
*/
int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses);
@ -578,7 +534,7 @@ int wave_add_generic(unsigned numPulses, gpioPulse_t *pulses);
Returns the new total number of pulses in the current waveform if OK,
otherwise PI_TOO_MANY_PULSES.
The pulses are interleaved in time order within the existing waveform
The pulses are interleaved in time order within the existing waveform
(if any).
Merging allows the waveform to be built in parts, that is the settings
@ -607,6 +563,108 @@ int wave_add_serial
the same waveform.
*/
int wave_create(void);
/* This function creates a waveform from the data provided by the prior
calls to the wave_add_* functions. Upon success a positive wave id
is returned.
The data provided by the wave_add_* functions is consumed by this
function.
As many waveforms may be created as there is space available. The
wave id is passed to wave_send_* to specify the waveform to transmit.
Normal usage would be
Step 1. wave_clear to clear all waveforms and added data.
Step 2. wave_add_* calls to supply the waveform data.
Step 3. wave_create to create the waveform and get a unique id
Repeat steps 2 and 3 as needed.
Step 4. wave_send_* with the id of the waveform to transmit.
A waveform comprises one or more pulses. Each pulse consists of a
gpioPulse_t structure.
typedef struct
{
uint32_t gpioOn;
uint32_t gpioOff;
uint32_t usDelay;
} gpioPulse_t;
The fields specify
1) the gpios to be switched on at the start of the pulse.
2) the gpios to be switched off at the start of the pulse.
3) the delay in microseconds before the next pulse.
Any or all the fields can be zero. It doesn't make any sense to
set all the fields to zero (the pulse will be ignored).
When a waveform is started each pulse is executed in order with the
specified delay between the pulse and the next.
Returns the new waveform id if OK, otherwise PI_EMPTY_WAVEFORM,
PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
*/
int wave_delete(unsigned wave_id);
/* This function deletes all created waveforms with ids greater than or
equal to wave_id.
Wave ids are allocated in order, 0, 1, 2, etc.
Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
*/
int wave_tx_start(void);
/* This function is deprecated and should no longer be used. Use
wave_create/wave_send_* instead.
*/
int wave_tx_repeat(void);
/* This function is deprecated and should no longer be used. Use
wave_create/wave_send_* instead.
*/
int wave_send_once(unsigned wave_id);
/* This function transmits the waveform with id wave_id. The waveform
is sent once.
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
*/
int wave_send_repeat(unsigned wave_id);
/* This function transmits the waveform with id wave_id. The waveform
cycles until cancelled (either by the sending of a new waveform or
by wave_tx_stop).
Returns the number of DMA control blocks in the waveform if OK,
otherwise PI_BAD_WAVE_ID, or PI_BAD_WAVE_MODE.
*/
int wave_tx_busy(void);
/* This function checks to see if a waveform is currently being
transmitted.
Returns 1 if a waveform is currently being transmitted, otherwise 0.
*/
int wave_tx_stop(void);
/* This function stops the transmission of the current waveform.
Returns 0 if OK.
This function is intended to stop a waveform started with the repeat mode.
*/
int wave_get_micros(void);
/* This function returns the length in microseconds of the current
waveform.
@ -675,7 +733,7 @@ int run_script(unsigned script_id, unsigned numPar, uint32_t *param);
the script as param 0 to param 9..
*/
int script_status(int script_id, uint32_t *param);
int script_status(unsigned script_id, uint32_t *param);
/* This function returns the run status of a stored script as well
as the current values of parameters 0 to 9.

105
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 13+
This version is for pigpio version 14+
*/
#include <stdio.h>
@ -50,6 +50,8 @@ the commands available from pigpio.
char command_buf[8192];
char response_buf[8192];
#define SOCKET_OPEN_FAILED -1
void fatal(char *fmt, ...)
{
char buf[128];
@ -88,7 +90,7 @@ static int openSocket(void)
err = getaddrinfo(addrStr, portStr, &hints, &res);
if (err) return -1;
if (err) return SOCKET_OPEN_FAILED;
for (rp=res; rp!=NULL; rp=rp->ai_next)
{
@ -101,7 +103,7 @@ static int openSocket(void)
freeaddrinfo(res);
if (rp == NULL) return -1;
if (rp == NULL) return SOCKET_OPEN_FAILED;
return sock;
}
@ -156,7 +158,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd)
p = (uint32_t *)response_buf;
for (i=0; i<MAX_SCRIPT_PARAMS; i++)
for (i=0; i<PI_MAX_SCRIPT_PARAMS; i++)
{
printf(" %d", p[i]);
}
@ -176,7 +178,7 @@ void get_extensions(int sock, int command, int res)
{
recv(sock,
response_buf,
sizeof(uint32_t)*MAX_SCRIPT_PARAMS,
sizeof(uint32_t)*PI_MAX_SCRIPT_PARAMS,
MSG_WAITALL);
}
break;
@ -259,38 +261,47 @@ int main(int argc , char *argv[])
cmdCmd_t cmd;
uint32_t p[10];
void *v[10];
gpioCtlParse_t ctl;
cmdCtlParse_t ctl;
cmdScript_t s;
sock = openSocket();
if (sock != -1)
command_buf[0] = 0;
l = 0;
pp = 0;
for (i=1; i<argc; i++)
{
command_buf[0] = 0;
l = 0;
pp = 0;
l += (strlen(argv[i]) + 1);
if (l < sizeof(command_buf))
{sprintf(command_buf+pp, "%s ", argv[i]); pp=l;}
}
for (i=1; i<argc; i++)
if (pp) {command_buf[--pp] = 0;}
ctl.eaten = 0;
len = strlen(command_buf);
idx = 0;
while ((idx >= 0) && (ctl.eaten < len))
{
if ((idx=cmdParse(command_buf, p, v, &ctl)) >= 0)
{
l += (strlen(argv[i]) + 1);
if (l < sizeof(command_buf))
{sprintf(command_buf+pp, "%s ", argv[i]); pp=l;}
}
command = p[0];
if (pp) {command_buf[--pp] = 0;}
ctl.flags = 0;
ctl.eaten = 0;
len = strlen(command_buf);
idx = 0;
while ((idx >= 0) && (ctl.eaten < len))
{
if ((idx=cmdParse(command_buf, p, v, &ctl)) >= 0)
if (command < PI_CMD_SCRIPT)
{
command = p[0];
if (command < PI_CMD_SCRIPT)
if (command == PI_CMD_HELP)
{
printf(cmdUsage);
}
else if (command == PI_CMD_PARSE)
{
cmdParseScript(v[1], &s, 1);
if (s.par) free (s.par);
}
else
{
cmd.cmd = command;
cmd.p1 = p[1];
@ -300,36 +311,46 @@ int main(int argc , char *argv[])
{
case PI_CMD_WVAS:
cmd.p2 = p[4];
break;
break;
case PI_CMD_PROC:
cmd.p2 = 0;
break;
}
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) == sizeof(cmdCmd_t))
if (sock != SOCKET_OPEN_FAILED)
{
put_extensions(sock, command, p, v);
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
if (send(sock, &cmd, sizeof(cmdCmd_t), 0) ==
sizeof(cmdCmd_t))
{
get_extensions(sock, command, cmd.res);
put_extensions(sock, command, p, v);
print_result(sock, cmdInfo[idx].rv, cmd);
if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
sizeof(cmdCmd_t))
{
get_extensions(sock, command, cmd.res);
print_result(sock, cmdInfo[idx].rv, cmd);
}
else fatal("recv failed, %m");
}
else fatal("recv failed, %m");
else fatal("send failed, %m");
}
else fatal("send failed, %m");
else fatal("connect failed");
}
else fatal("%s only allowed within a script", cmdInfo[idx].name);
}
else fatal("%s? pigs h for help", cmdStr());
else fatal("%s only allowed within a script", cmdInfo[idx].name);
}
else
{
if (idx == CMD_UNKNOWN_CMD)
fatal("%s? unknown command, pigs h for help", cmdStr());
else
fatal("%s: bad parameter, pigs h for help", cmdStr());
}
}
else fatal("connect failed, %m");
close(sock);
if (sock >= 0) close(sock);
return 0;
}

View File

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

29
tarball Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
#
rm -rf PIGPIO
mkdir PIGPIO
#
cp command.c PIGPIO
cp command.h PIGPIO
cp Makefile PIGPIO
cp MakeRemote PIGPIO
cp pig2vcd.c PIGPIO
cp pigpio.c PIGPIO
cp pigpio.h PIGPIO
cp pigpiod.c PIGPIO
cp pigpiod_if.c PIGPIO
cp pigpiod_if.h PIGPIO
cp pigpio.py PIGPIO
cp pigs.c PIGPIO
cp README PIGPIO
cp setup.py PIGPIO
cp UNLICENCE PIGPIO
cp x_pigpio.c PIGPIO
cp x_pigpio.py PIGPIO
cp x_pigpiod_if.c PIGPIO
cp x_pigs PIGPIO
cp x_pipe PIGPIO
#
zip -r pigpio-$1.zip PIGPIO
tar cvf pigpio-$1.tar PIGPIO

View File

@ -1,6 +1,13 @@
/*
gcc -o x_pigpio x_pigpio.c -lpigpio -lrt -lpthread
sudo ./x_pigpio
*** WARNING ************************************************
* *
* All the tests make extensive use of gpio 4 (pin P1-7). *
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
************************************************************
*/
#include <stdio.h>
@ -448,17 +455,17 @@ void t6()
gpioSetAlertFunc(GPIO, t6cbf);
for (t=0; t<10; t++)
for (t=0; t<5; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
gpioTrigger(4, p, 1);
gpioTrigger(GPIO, p, 1);
}
time_sleep(0.2);
CHECK(6, 1, t6_count, 10, 0, "gpio trigger count");
CHECK(6, 1, t6_count, 5, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
}
@ -553,16 +560,16 @@ void t9()
p1 GPIO
*/
char *script="\
ldap 0\
ldva 0\
label 0\
lda p0\
sta v0\
tag 0\
w p1 1\
milli 5\
mils 5\
w p1 0\
milli 5\
dcrv 0\
ldav 0\
ldpa 9\
mils 5\
dcr v0\
lda v0\
sta p9\
jp 0";
printf("Script store/run/status/stop/delete tests.\n");

View File

@ -1,5 +1,12 @@
#!/usr/bin/env python
#*** WARNING ************************************************
#* *
#* All the tests make extensive use of gpio 4 (pin P1-7). *
#* Ensure that either nothing or just a LED is connected to *
#* gpio 4 before running any of the tests. *
#************************************************************
import time
import struct
@ -364,6 +371,50 @@ To the lascivious pleasing of a lute.
c = pigpio.wave_get_max_cbs()
CHECK(5, 21, c, 25016, 0, "wave get max cbs")
e = pigpio.wave_clear()
CHECK(5, 22, e, 0, 0, "wave clear")
e = pigpio.wave_add_generic(wf)
CHECK(5, 23, e, 4, 0, "pulse, wave add generic")
w1 = pigpio.wave_create()
CHECK(5, 24, w1, 0, 0, "wave create")
e = pigpio.wave_send_repeat(w1)
CHECK(5, 25, e, 9, 0, "wave send repeat")
oc = t5_count
time.sleep(5)
c = t5_count - oc
CHECK(5, 26, c, 50, 1, "callback")
e = pigpio.wave_tx_stop()
CHECK(5, 27, e, 0, 0, "wave tx stop")
e = pigpio.wave_add_serial(GPIO, BAUD, 5000000, TEXT)
CHECK(5, 28, e, 3405, 0, "wave add serial")
w2 = pigpio.wave_create()
CHECK(5, 29, w2, 1, 0, "wave create")
e = pigpio.wave_send_once(w2)
CHECK(5, 30, e, 6811, 0, "wave send once")
oc = t5_count
time.sleep(3)
c = t5_count - oc
CHECK(5, 31, c, 0, 0, "callback")
oc = t5_count
while pigpio.wave_tx_busy():
time.sleep(0.1)
time.sleep(0.1)
c = t5_count - oc
CHECK(5, 32, c, 1702, 0, "wave tx busy, callback")
e = pigpio.wave_delete(0)
CHECK(5, 33, e, 0, 0, "wave delete")
t6_count=0
t6_on=0
t6_on_tick=None
@ -388,15 +439,15 @@ def t6():
t6cb = pigpio.callback(GPIO, pigpio.EITHER_EDGE, t6cbf)
for t in range(10):
for t in range(5):
time.sleep(0.1)
p = 10 + (t*10)
tp += p;
pigpio.gpio_trigger(4, p, 1)
pigpio.gpio_trigger(GPIO, p, 1)
time.sleep(0.5)
CHECK(6, 1, t6_count, 10, 0, "gpio trigger count")
CHECK(6, 1, t6_count, 5, 0, "gpio trigger count")
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length")
@ -480,16 +531,16 @@ def t9():
# p0 number of loops
# p1 GPIO
script="""
ldap 0
ldva 0
label 0
lda p0
sta v0
tag 0
w p1 1
milli 5
mils 5
w p1 0
milli 5
dcrv 0
ldav 0
ldpa 9
mils 5
dcr v0
lda v0
sta p9
jp 0"""
t9cb = pigpio.callback(GPIO)

View File

@ -1,6 +1,13 @@
/*
gcc -o x_pigpiod_if x_pigpiod_if.c -lpigpiod_if -lrt -lpthread
sudo ./x_pigpiod_if
*** WARNING ************************************************
* *
* All the tests make extensive use of gpio 4 (pin P1-7). *
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
************************************************************
*/
#include <stdio.h>
@ -429,17 +436,17 @@ void t6()
time_sleep(0.2);
for (t=0; t<10; t++)
for (t=0; t<5; t++)
{
time_sleep(0.1);
p = 10 + (t*10);
tp += p;
gpio_trigger(4, p, 1);
gpio_trigger(GPIO, p, 1);
}
time_sleep(0.5);
CHECK(6, 1, t6_count, 10, 0, "gpio trigger count");
CHECK(6, 1, t6_count, 5, 0, "gpio trigger count");
CHECK(6, 2, t6_on, tp, 25, "gpio trigger pulse length");
}
@ -540,16 +547,16 @@ void t9()
p1 GPIO
*/
char *script="\
ldap 0\
ldva 0\
label 0\
lda p0\
sta v0\
tag 0\
w p1 1\
milli 5\
mils 5\
w p1 0\
milli 5\
dcrv 0\
ldav 0\
ldpa 9\
mils 5\
dcr v0\
lda v0\
sta p9\
jp 0";
callback(GPIO, RISING_EDGE, t9cbf);

22
x_pigs
View File

@ -40,16 +40,16 @@ s=$(pigs bs2 0)
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h)
if [[ ${#s} = 2999 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
if [[ ${#s} = 3315 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
s=$(pigs hwver)
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
s=$(pigs micro 1000)
if [[ $s = "" ]]; then echo "MICRO ok"; else echo "MICRO fail ($s)"; fi
s=$(pigs mics 1000)
if [[ $s = "" ]]; then echo "MICS ok"; else echo "MICS fail ($s)"; fi
s=$(pigs milli 10)
if [[ $s = "" ]]; then echo "MILLI ok"; else echo "MILLI fail ($s)"; fi
s=$(pigs mils 10)
if [[ $s = "" ]]; then echo "MILS ok"; else echo "MILS fail ($s)"; fi
s=$(pigs modes $GPIO 0)
s=$(pigs modeg $GPIO)
@ -86,14 +86,14 @@ s=$(pigs pfs $GPIO 800)
if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
s=$(pigs pigpv)
if [[ $s = 13 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
if [[ $s = 14 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
s=$(pigs prs $GPIO 255)
if [[ $s = 250 ]]; then echo "PRG-a ok"; else echo "PRG-a fail ($s)"; fi
s=$(pigs prg $GPIO)
if [[ $s = 255 ]]; then echo "PRG-b ok"; else echo "PRG-b fail ($s)"; fi
p=$(pigs proc ldap 0 ldpa 1 ldai 1234 ldpa 0 label 999 milli 1000 jmp 999)
p=$(pigs proc ld p1 p0 ld p0 1234 tag 999 mils 1000 jmp 999)
if [[ $p -ge 0 && $p -le 31 ]]
then echo "PROC($p) ok"
else echo "PROC($p) fail ($s)"
@ -186,10 +186,10 @@ fi
s=$(pigs slrc $GPIO)
if [[ $s = 0 ]]; then echo "SLR-g ok"; else echo "SLR-g fail ($s)"; fi
t1=$(pigs t)
t2=$(pigs tick)
s=$(($t2-$t1))
if [[ $s -gt 0 && $s -lt 20000 ]]
t=$(pigs t tick)
v=(${t// / })
s=$((v[1]-v[0]))
if [[ $s -gt 0 && $s -lt 2000 ]]
then echo "TICK ok"
else echo "TICK fail($s)"
fi

16
x_pipe
View File

@ -46,14 +46,14 @@ if [[ $s = 0 ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
echo "h" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = "BC1 v Clear gpios defined by mask v in bank 1." ]]
if [[ $s = "BC1 v Clear gpios specified by mask v in bank 1." ]]
then echo "HELP-a ok"
else echo "HELP-a fail ($s)"
fi
read -t 1 -N 9000 </dev/pigout # dump rest of help
echo "help" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = "BC1 v Clear gpios defined by mask v in bank 1." ]]
if [[ $s = "BC1 v Clear gpios specified by mask v in bank 1." ]]
then echo "HELP-b ok"
else echo "HELP-b fail ($s)"
fi
@ -63,13 +63,13 @@ echo "hwver" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
echo "micro 1000" >/dev/pigpio
echo "mics 1000" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "MICRO ok"; else echo "MICRO fail ($s)"; fi
if [[ $s = 0 ]]; then echo "MICS ok"; else echo "MICS fail ($s)"; fi
echo "milli 10" >/dev/pigpio
echo "mils 10" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "MILLI ok"; else echo "MILLI fail ($s)"; fi
if [[ $s = 0 ]]; then echo "MILS ok"; else echo "MILS fail ($s)"; fi
echo "modes $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
@ -119,7 +119,7 @@ if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi
echo "pigpv" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 13 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
if [[ $s = 14 ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi
echo "prs $GPIO 255" >/dev/pigpio
read -t 1 s </dev/pigout
@ -128,7 +128,7 @@ echo "prg $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 255 ]]; then echo "PRG-b ok"; else echo "PRG-b fail ($s)"; fi
echo "proc ldap 0 ldpa 1 ldai 29 ldpa 0 label 9 milli 1000 jmp 9" >/dev/pigpio
echo "proc ld p1 p0 ld p0 29 tag 9 mils 1000 jmp 9" >/dev/pigpio
read -t 1 p </dev/pigout
if [[ $p -ge 0 && $p -le 31 ]]
then echo "PROC($p) ok"