From 624ecb6fb0b4b759435d872b5aa3c48b898fea73 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 2 Feb 2015 21:11:28 +0000 Subject: [PATCH] V26 --- Makefile | 7 +- command.c | 305 +++++++++++++++++------------- custom.cext | 54 ++++++ pigpio.c | 518 ++++++++++++++++++++++++++++++++++----------------- pigpio.h | 97 +++++++--- pigpio.py | 98 +++++++++- pigpiod_if.c | 52 ++++++ pigpiod_if.h | 63 ++++++- pigs.c | 5 +- x_pigs | 4 +- x_pipe | 6 +- 11 files changed, 862 insertions(+), 347 deletions(-) create mode 100644 custom.cext diff --git a/Makefile b/Makefile index d2811f6..f7206a7 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +# CC = gcc AR = ar RANLIB = ranlib @@ -80,12 +81,12 @@ $(LIB2): $(OBJ2) # generated using gcc -MM *.c -x_pigpio.o: x_pigpio.c pigpio.h -x_pigpiod_if.o: x_pigpiod_if.c command.o: command.c pigpio.h command.h pig2vcd.o: pig2vcd.c pigpio.h -pigpio.o: pigpio.c pigpio.h command.h +pigpio.o: pigpio.c pigpio.h command.h custom.cext pigpiod.o: pigpiod.c pigpio.h pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h pigs.o: pigs.c pigpio.h command.h +x_pigpio.o: x_pigpio.c pigpio.h +x_pigpiod_if.o: x_pigpiod_if.c pigpiod_if.h pigpio.h diff --git a/command.c b/command.c index e5a94a5..53b8074 100644 --- a/command.c +++ b/command.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 25+ +This version is for pigpio version 26+ */ #include @@ -51,6 +51,9 @@ cmdInfo_t cmdInfo[]= {PI_CMD_BS1, "BS1", 111, 1}, // gpioWrite_Bits_0_31_Set {PI_CMD_BS2, "BS2", 111, 1}, // gpioWrite_Bits_32_53_Set + {PI_CMD_CF1, "CF1", 195, 2}, // gpioCustom1 + {PI_CMD_CF2, "CF2", 195, 6}, // gpioCustom2 + {PI_CMD_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle {PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth @@ -217,163 +220,167 @@ cmdInfo_t cmdInfo[]= char * cmdUsage = "\ -BC1 bits Clear specified gpios in bank 1.\n\ -BC2 bits Clear specified gpios in bank 2.\n\ -BR1 Read bank 1 gpios.\n\ -BR2 Read bank 2 gpios.\n\ -BS1 bits Set specified gpios in bank 2.\n\ -BS2 bits Set specified gpios in bank 2.\n\ +BC1 bits Clear specified gpios in bank 1\n\ +BC2 bits Clear specified gpios in bank 2\n\ +BR1 Read bank 1 gpios\n\ +BR2 Read bank 2 gpios\n\ +BS1 bits Set specified gpios in bank 2\n\ +BS2 bits Set specified gpios in bank 2\n\ +\n\ +CF1 uvs Custom function 1\n\ +CF2 uvs Custom function 2\n\ \n\ -GDC u Get PWM dutycycle for gpio.\n\ -GPW u Get servo pulsewidth for gpio.\n\ +GDC u Get PWM dutycycle for gpio\n\ +GPW u Get servo pulsewidth for gpio\n\ \n\ -H/HELP Display command help.\n\ +H/HELP Display command help\n\ \n\ -HC g cf Set hardware clock frequency.\n\ -HP g pf pdc Set hardware PWM frequency and dutycycle.\n\ +HC g cf Set hardware clock frequency\n\ +HP g pf pdc Set hardware PWM frequency and dutycycle\n\ \n\ -HWVER Get hardware version.\n\ +HWVER Get hardware version\n\ \n\ -I2CC h Close I2C handle.\n\ -I2CO ib id if Open I2C bus and device with flags.\n\ +I2CC h Close I2C handle\n\ +I2CO ib id if Open I2C bus and device with flags\n\ \n\ -I2CPC h r wv smb Process Call: exchange register with word.\n\ -I2CPK h r bvs smb Block Process Call: exchange data bytes with register.\n\ +I2CPC h r wv smb Process Call: exchange register with word\n\ +I2CPK h r bvs smb Block Process Call: exchange data bytes with register\n\ \n\ -I2CRB h r smb Read Byte Data: read byte from register.\n\ -I2CRD h num i2c Read bytes.\n\ -I2CRI h r num smb Read I2C Block Data: read bytes from register.\n\ -I2CRK h r smb Read Block Data: read data from register.\n\ -I2CRS h smb Read Byte: read byte.\n\ -I2CRW h r smb Read Word Data: read word from register.\n\ +I2CRB h r smb Read Byte Data: read byte from register\n\ +I2CRD h num i2c Read bytes\n\ +I2CRI h r num smb Read I2C Block Data: read bytes from register\n\ +I2CRK h r smb Read Block Data: read data from register\n\ +I2CRS h smb Read Byte: read byte\n\ +I2CRW h r smb Read Word Data: read word from register\n\ \n\ -I2CWB h r bv smb Write Byte Data: write byte to register.\n\ -I2CWD h bvs i2c Write data.\n\ -I2CWI h r bvs smb Write I2C Block Data.\n\ -I2CWK h r bvs smb Write Block Data: write data to register.\n\ -I2CWQ h bit smb Write Quick: write bit.\n\ -I2CWS h bv smb Write Byte: write byte.\n\ -I2CWW h r wv smb Write Word Data: write word to register.\n\ +I2CWB h r bv smb Write Byte Data: write byte to register\n\ +I2CWD h bvs i2c Write data\n\ +I2CWI h r bvs smb Write I2C Block Data\n\ +I2CWK h r bvs smb Write Block Data: write data to register\n\ +I2CWQ h bit smb Write Quick: write bit\n\ +I2CWS h bv smb Write Byte: write byte\n\ +I2CWW h r wv smb Write Word Data: write word to register\n\ \n\ -M/MODES g m Set gpio mode.\n\ -MG/MODEG g Get gpio mode.\n\ +M/MODES g m Set gpio mode\n\ +MG/MODEG g Get gpio mode\n\ \n\ -MICS v Delay for microseconds.\n\ -MILS v Delay for milliseconds.\n\ +MICS v Delay for microseconds\n\ +MILS v Delay for milliseconds\n\ \n\ -NB h bits Start notification.\n\ -NC h Close notification.\n\ -NO Request a notification.\n\ -NP h Pause notification.\n\ +NB h bits Start notification\n\ +NC h Close notification\n\ +NO Request a notification\n\ +NP h Pause notification\n\ \n\ -P/PWM u v Set gpio PWM value.\n\ +P/PWM u v Set gpio PWM value\n\ \n\ -PARSE t Validate script.\n\ +PARSE t Validate script\n\ \n\ -PFG u Get gpio PWM frequency.\n\ -PFS u v Set gpio PWM frequency.\n\ +PFG u Get gpio PWM frequency\n\ +PFS u v Set gpio PWM frequency\n\ \n\ -PIGPV Get pigpio library version.\n\ +PIGPV Get pigpio library version\n\ \n\ -PRG u Get gpio PWM range.\n\ +PRG u Get gpio PWM range\n\ \n\ -PROC t Store script.\n\ -PROCD sid Delete script.\n\ -PROCP sid Get script status and parameters.\n\ -PROCR sid pars Run script.\n\ -PROCS sid Stop script.\n\ +PROC t Store script\n\ +PROCD sid Delete script\n\ +PROCP sid Get script status and parameters\n\ +PROCR sid pars Run script\n\ +PROCS sid Stop script\n\ \n\ -PRRG u Get gpio PWM real range.\n\ -PRS u v Set gpio PWM range.\n\ +PRRG u Get gpio PWM real range\n\ +PRS u v Set gpio PWM range\n\ \n\ -PUD g p Set gpio pull up/down.\n\ +PUD g p Set gpio pull up/down\n\ \n\ -R/READ g Read gpio level.\n\ +R/READ g Read gpio level\n\ \n\ -S/SERVO u v Set gpio servo pulsewidth.\n\ +S/SERVO u v Set gpio servo pulsewidth\n\ \n\ -SERC h Close serial handle.\n\ -SERDA h Check for serial data ready to read.\n\ -SERO srd srb srf Open serial device at baud with flags.\n\ +SERC h Close serial handle\n\ +SERDA h Check for serial data ready to read\n\ +SERO srd srb srf Open serial device at baud with flags\n\ \n\ -SERR h num Read bytes from serial handle.\n\ -SERRB Read byte from serial handle.\n\ -SERW h bvs Write bytes to serial handle.\n\ -SERWB h bv Write byte to serial handle.\n\ +SERR h num Read bytes from serial handle\n\ +SERRB h Read byte from serial handle\n\ +SERW h bvs Write bytes to serial handle\n\ +SERWB h bv Write byte to serial handle\n\ \n\ -SLR u num Read bit bang serial data from gpio.\n\ -SLRC u Close gpio for bit bang serial data.\n\ -SLRO u b db Open gpio for bit bang serial data.\n\ +SLR u num Read bit bang serial data from gpio\n\ +SLRC u Close gpio for bit bang serial data\n\ +SLRO u b db Open gpio for bit bang serial data\n\ \n\ -SPIC h SPI close handle.\n\ -SPIO sc sb sf SPI open channel at baud with flags.\n\ -SPIR h num SPI read bytes from handle.\n\ -SPIW h bvs SPI write bytes to handle.\n\ -SPIX h bvs SPI transfer bytes to handle.\n\ +SPIC h SPI close handle\n\ +SPIO sc sb sf SPI open channel at baud with flags\n\ +SPIR h num SPI read bytes from handle\n\ +SPIW h bvs SPI write bytes to handle\n\ +SPIX h bvs SPI transfer bytes to handle\n\ \n\ -T/TICK Get current tick.\n\ +T/TICK Get current tick\n\ \n\ -TRIG u pl L Trigger level for micros on gpio.\n\ +TRIG u pl L Trigger level for micros on gpio\n\ \n\ -W/WRITE g L Write level to gpio.\n\ +W/WRITE g L Write level to gpio\n\ \n\ -WDOG u v Set millisecond watchdog on gpio.\n\ +WDOG u v Set millisecond watchdog on gpio\n\ \n\ -WVAG trips Wave add generic pulses.\n\ +WVAG trips Wave add generic pulses\n\ WVAS u b db hb Wave add serial data for gpio u at b baud, db databits,\n\ - o bvs hb (half)stopbits, offset o micros from wave start.\n\ -WVBSY Check if wave busy.\n\ -WVCLR Wave clear.\n\ -WVCRE Create wave from added pulses.\n\ -WVDEL wid Delete waves w and higher.\n\ -WVGO Wave transmit (DEPRECATED).\n\ -WVGOR Wave transmit repeatedly (DEPRECATED).\n\ -WVHLT Wave stop.\n\ -WVNEW Start a new empty wave.\n\ -WVSC ws Wave get DMA control block stats.\n\ -WVSM ws Wave get micros stats.\n\ -WVSP ws Wave get pulses stats.\n\ -WVTX wid Transmit wave as one-shot.\n\ -WVTXR wid Transmit wave repeatedly.\n\ + o bvs hb (half)stopbits, offset o micros from wave start\n\ +WVBSY Check if wave busy\n\ +WVCLR Wave clear\n\ +WVCRE Create wave from added pulses\n\ +WVDEL wid Delete waves w and higher\n\ +WVGO Wave transmit (DEPRECATED)\n\ +WVGOR Wave transmit repeatedly (DEPRECATED)\n\ +WVHLT Wave stop\n\ +WVNEW Start a new empty wave\n\ +WVSC ws Wave get DMA control block stats\n\ +WVSM ws Wave get micros stats\n\ +WVSP ws Wave get pulses stats\n\ +WVTX wid Transmit wave as one-shot\n\ +WVTXR wid Transmit wave repeatedly\n\ \n\ -bits = a mask where (1<=0).\n\ -hb = (half) stop bits (2-8).\n\ -ib = I2C bus (0-1).\n\ -id = I2C device (0-127).\n\ -if = I2C flags (0).\n\ -L = level (0-1).\n\ -m = mode (RW540123).\n\ -num = number of bytes to read.\n\ -o = offset (>=0).\n\ -p = pud (ODU).\n\ -pars = 0 to 10 parameters for script.\n\ -pdc = hardware PWM dutycycle (0-1000).\n\ -pf = hardware PWM frequency (5-250K).\n\ -pl = pulse length (1-100).\n\ -r = register.\n\ -sid = script id (>=0).\n\ -sb = SPI baud.\n\ -sc = SPI channel (0-1).\n\ -sf = SPI flags (0-3).\n\ -srd = serial device (/dev/tty*).\n\ -srb = serial baud rate.\n\ -srf = serial flags (0).\n\ -t = text.\n\ -trips = 1 or more triplets of gpios on, gpios off, delay.\n\ -u = user gpio (0-31).\n\ -v = value.\n\ -w = wave id (>=0).\n\ -ws = 0=now, 1=high, 2=max.\n\ -wv = word value (0-65535).\n\ +bits = a mask where (1<=0)\n\ +hb = (half) stop bits (2-8)\n\ +ib = I2C bus (0-1)\n\ +id = I2C device (0-127)\n\ +if = I2C flags (0)\n\ +L = level (0-1)\n\ +m = mode (RW540123)\n\ +num = number of bytes to read\n\ +o = offset (>=0)\n\ +p = pud (ODU)\n\ +pars = 0 to 10 parameters for script\n\ +pdc = hardware PWM dutycycle (0-5000)\n\ +pf = hardware PWM frequency (5-50K)\n\ +pl = pulse length (1-100)\n\ +r = register\n\ +sid = script id (>=0)\n\ +sb = SPI baud\n\ +sc = SPI channel (0-1)\n\ +sf = SPI flags (0-3)\n\ +srd = serial device (/dev/tty*)\n\ +srb = serial baud rate\n\ +srf = serial flags (0)\n\ +t = text\n\ +trips = 1 or more triplets of gpios on, gpios off, delay\n\ +u = user gpio (0-31)\n\ +uvs = zero or more values >= 0, any after the first two must <= 255\n\ +v = value\n\ +w = wave id (>=0)\n\ +ws = 0=now, 1=high, 2=max\n\ +wv = word value (0-65535)\n\ \n\ Numbers may be entered as hex (prefix 0x), octal (prefix 0),\n\ -otherwise they are assumed to be decimal.\n\ +otherwise they are assumed to be decimal\n\ "; typedef struct @@ -479,8 +486,8 @@ static errInfo_t errInfo[]= {PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"}, {PI_NOT_HCLK_GPIO , "gpio has no hardware clock"}, {PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"}, - {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-250K"}, - {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1000"}, + {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-50K"}, + {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-5000"}, {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"}, {PI_BAD_HCLK_PASS , "need password to use hardware clock 1"}, {PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"}, @@ -940,6 +947,52 @@ int cmdParse( break; + case 195: /* CF1 CF2 + + Zero or more parameters, first two >=0, rest 0-255. + */ + valid = 1; + + ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]); + + if (ctl->opt[1] == CMD_NUMERIC) + { + if ((int)p[1] >= 0) + { + ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]); + + if (ctl->opt[2] == CMD_NUMERIC) + { + if ((int)p[2] >= 0) + { + pars = 0; + p8 = ext; + + while (pars < CMD_MAX_PARAM) + { + ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1); + if (to1 == CMD_NUMERIC) + { + if (((int)tp1>=0) && ((int)tp1<=255)) + { + pars++; + *p8++ = tp1; + } + else valid = 0; + } + else break; + } + + p[3] = pars; + } + else valid = 0; + } + } + else valid = 0; + } + + break; + case 196: /* WVAS gpio baud offset char... diff --git a/custom.cext b/custom.cext new file mode 100644 index 0000000..905884d --- /dev/null +++ b/custom.cext @@ -0,0 +1,54 @@ +/* +This version is for pigpio version 26+ + +If you want customised functions replace this file with your own +definitions for gpioCustom1 and gpioCustom2. +*/ + +#include "pigpio.h" + +int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count) +{ + int i; + unsigned max; + + DBG(DBG_USER, "arg1=%d arg2=%d count=%d [%s]", + arg1, arg2, count, myBuf2Str(count, argx)); + + CHECK_INITED; + + /* for dummy just return max parameter */ + + if (arg1 > arg2) max = arg1; else max = arg2; + + for (i=0; i max) max = argx[i]; + + return max; +} + + +int gpioCustom2(unsigned arg1, char *argx, unsigned count, + char *retBuf, unsigned retMax) +{ + int i, j, t; + + DBG(DBG_USER, "arg1=%d count=%d [%s] retMax=%d", + arg1, count, myBuf2Str(count, argx), retMax); + + CHECK_INITED; + + /* for dummy just return argx reversed */ + + if (count > retMax) count = retMax; + + for (i=0, j=count-1; i<=j; i++, j--) + { + /* t used as argx and retBuf may be the same buffer */ + t = argx[i]; + retBuf[i] = argx[j]; + retBuf[j] = t; + } + + return count; +} + diff --git a/pigpio.c b/pigpio.c index d15fe2f..cabe56b 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,10 +25,11 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 25 */ +/* pigpio version 26 */ #include #include +#include #include #include #include @@ -39,7 +40,6 @@ For more information, please refer to #include #include #include -#include #include #include #include @@ -188,7 +188,6 @@ bit 0 READ_LAST_NOT_SET_ERROR #define BIT (1<<(gpio&0x1F)) - #define CHECK_INITED \ do \ { \ @@ -286,15 +285,18 @@ bit 0 READ_LAST_NOT_SET_ERROR #define DMA_BUS_ADR 0x40000000 -#define AUX_BASE 0x20215000 -#define CLK_BASE 0x20101000 -#define DMA_BASE 0x20007000 -#define DMA15_BASE 0x20E05000 -#define GPIO_BASE 0x20200000 -#define PCM_BASE 0x20203000 -#define PWM_BASE 0x2020C000 -#define SPI_BASE 0x20204000 -#define SYST_BASE 0x20003000 +static volatile unsigned int piModel = 1; +static volatile unsigned int PI_PERI_BASE = 0x20000000; + +#define AUX_BASE (PI_PERI_BASE + 0x00215000) +#define CLK_BASE (PI_PERI_BASE + 0x00101000) +#define DMA_BASE (PI_PERI_BASE + 0x00007000) +#define DMA15_BASE (PI_PERI_BASE + 0x00E05000) +#define GPIO_BASE (PI_PERI_BASE + 0x00200000) +#define PCM_BASE (PI_PERI_BASE + 0x00203000) +#define PWM_BASE (PI_PERI_BASE + 0x0020C000) +#define SPI_BASE (PI_PERI_BASE + 0x00204000) +#define SYST_BASE (PI_PERI_BASE + 0x00003000) #define AUX_LEN 0xD8 #define CLK_LEN 0xA8 @@ -1257,6 +1259,14 @@ static char *myBuf2Str(unsigned count, char *buf) /* ----------------------------------------------------------------------- */ +static void myGpioWrite(unsigned gpio, unsigned level) +{ + if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT; + else *(gpioReg + GPSET0 + BANK) = BIT; +} + +/* ----------------------------------------------------------------------- */ + static void myGpioSleep(int seconds, int micros) { struct timespec ts, rem; @@ -1441,6 +1451,18 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) } break; + case PI_CMD_CF1: + res = gpioCustom1(p[1], p[2], buf, p[3]); + break; + + + case PI_CMD_CF2: + /* a couple of extra precautions for untruested code */ + if (p[2] > bufSize) p[2] = bufSize; + res = gpioCustom2(p[1], buf, p[3], buf, p[2]); + if (res > p[2]) res = p[2]; + break; + case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break; case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break; @@ -1640,7 +1662,8 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf) if (myPermit(p[1])) res = gpioServo(p[1], p[2]); else { - DBG(DBG_USER, "gpioServo: gpio %d, no permission to update", p[1]); + DBG(DBG_USER, + "gpioServo: gpio %d, no permission to update", p[1]); res = PI_NOT_PERMITTED; } break; @@ -2072,7 +2095,7 @@ static void waveCbOPrint(int pos) p = rawWaveCBAdr(pos); - fprintf(stderr, "i=%lx s=%lx d=%lx len=%lx s=%lx nxt=%lx\n", + fprintf(stderr, "i=%x s=%x d=%x len=%x s=%x nxt=%x\n", p->info, p->src, p->dst, p->length, p->stride, p->next); } @@ -2115,6 +2138,9 @@ static int errCBsOOL(int cb, int botOOL, int topOOL) /* ----------------------------------------------------------------------- */ +#define PI_WAVE_COUNT_BLOCKS 3 +#define PI_WAVE_COUNT_LENGTH 10 + static int wave2Cbs(unsigned wave_mode) { int botCB=waveOutBotCB, botOOL=waveOutBotOOL, topOOL=waveOutTopOOL; @@ -2129,6 +2155,9 @@ static int wave2Cbs(unsigned wave_mode) rawWave_t * waves; + int b, baseCB; + uint32_t def_next; + numWaves = wfc[wfcur]; waves = wf [wfcur]; @@ -2221,6 +2250,73 @@ static int wave2Cbs(unsigned wave_mode) p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; } + if (waves[i].flags & WAVE_FLAG_COUNT) + { + if ((status = errCBsOOL(botCB+1, botOOL, topOOL-1))) return status; + + baseCB = botCB; + + def_next = waveCbPOadr(baseCB+(3*PI_WAVE_COUNT_BLOCKS)) | DMA_BUS_ADR; + + /* set up all the OOLs */ + for (b=0; b < (PI_WAVE_COUNT_BLOCKS*(PI_WAVE_COUNT_LENGTH+1)); b++) + rawWaveSetIn(b, def_next); + + for (b=0; binfo = NORMAL_DMA; + + p->src = waveOOLPOadr + (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1))) | DMA_BUS_ADR; + p->dst = (waveCbPOadr(botCB+1) + 20) | DMA_BUS_ADR; + + p->length = 4; + p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + + /* copy BOTTOM to TOP */ + + p = rawWaveCBAdr(botCB++); + + p->info = NORMAL_DMA; + + p->src = waveOOLPOadr + (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1))) | DMA_BUS_ADR; + p->dst = waveOOLPOadr + (topOOL-(1+(b*(PI_WAVE_COUNT_LENGTH+1)))) | DMA_BUS_ADR; + + p->length = 4; + p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + + /* shift all down one */ + + p = rawWaveCBAdr(botCB++); + + p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC; + + p->src = waveOOLPOadr + (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-1)) | DMA_BUS_ADR; + p->dst = waveOOLPOadr + (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-0)) | DMA_BUS_ADR; + + p->length = PI_WAVE_COUNT_LENGTH*4; + p->next = waveCbPOadr + (baseCB+(3*PI_WAVE_COUNT_BLOCKS)) | DMA_BUS_ADR; + } + + topOOL -= PI_WAVE_COUNT_BLOCKS * (PI_WAVE_COUNT_LENGTH+1); + } + if (waves[i].usDelay) { if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status; @@ -2458,6 +2554,12 @@ int rawWaveAddGeneric(unsigned numIn1, rawWave_t *in1) --level; } + if (out[outPos].flags & WAVE_FLAG_COUNT) + { + cbs += (3*PI_WAVE_COUNT_BLOCKS); + level -= (PI_WAVE_COUNT_BLOCKS*(PI_WAVE_COUNT_LENGTH+1)); + } + outPos++; if (inPos1 >= numIn1) tNext1 = -1; @@ -3083,102 +3185,7 @@ static unsigned old_mode_amosi; static uint32_t old_spi_cntl0; static uint32_t old_spi_cntl1; -static void spiInit(uint32_t flags) -{ - int resvd; - - resvd = PI_SPI_FLAGS_GET_RESVD(flags); - - if (PI_SPI_FLAGS_GET_AUX_SPI(flags)) - { - /* enable module and access to registers */ - - auxReg[AUX_ENABLES] |= AUXENB_SPI1; - - /* save original state */ - - old_mode_ace0 = gpioGetMode(PI_ASPI_CE0); - old_mode_ace1 = gpioGetMode(PI_ASPI_CE1); - old_mode_ace2 = gpioGetMode(PI_ASPI_CE2); - old_mode_asclk = gpioGetMode(PI_ASPI_SCLK); - old_mode_amiso = gpioGetMode(PI_ASPI_MISO); - old_mode_amosi = gpioGetMode(PI_ASPI_MOSI); - - old_spi_cntl0 = auxReg[AUX_SPI0_CNTL0_REG]; - old_spi_cntl1 = auxReg[AUX_SPI0_CNTL1_REG]; - - /* set gpios to SPI mode */ - - if (!(resvd&1)) gpioSetMode(PI_ASPI_CE0, PI_ALT4); - if (!(resvd&2)) gpioSetMode(PI_ASPI_CE1, PI_ALT4); - if (!(resvd&4)) gpioSetMode(PI_ASPI_CE2, PI_ALT4); - - gpioSetMode(PI_ASPI_SCLK, PI_ALT4); - gpioSetMode(PI_ASPI_MISO, PI_ALT4); - gpioSetMode(PI_ASPI_MOSI, PI_ALT4); - } - else - { - /* save original state */ - - old_mode_ce0 = gpioGetMode(PI_SPI_CE0); - old_mode_ce1 = gpioGetMode(PI_SPI_CE1); - old_mode_sclk = gpioGetMode(PI_SPI_SCLK); - old_mode_miso = gpioGetMode(PI_SPI_MISO); - old_mode_mosi = gpioGetMode(PI_SPI_MOSI); - - old_spi_cs = spiReg[SPI_CS]; - old_spi_clk = spiReg[SPI_CLK]; - - /* set gpios to SPI mode */ - - if (!(resvd&1)) gpioSetMode(PI_SPI_CE0, PI_ALT0); - if (!(resvd&2)) gpioSetMode(PI_SPI_CE1, PI_ALT0); - - gpioSetMode(PI_SPI_SCLK, PI_ALT0); - gpioSetMode(PI_SPI_MISO, PI_ALT0); - gpioSetMode(PI_SPI_MOSI, PI_ALT0); - } -} - -void spiTerm(uint32_t flags) -{ - int resvd; - - resvd = PI_SPI_FLAGS_GET_RESVD(flags); - - if (PI_SPI_FLAGS_GET_AUX_SPI(flags)) - { - /* restore original state */ - - if (!(resvd&1)) gpioSetMode(PI_ASPI_CE0, old_mode_ace0); - if (!(resvd&2)) gpioSetMode(PI_ASPI_CE1, old_mode_ace1); - if (!(resvd&4)) gpioSetMode(PI_ASPI_CE2, old_mode_ace2); - - gpioSetMode(PI_ASPI_SCLK, old_mode_asclk); - gpioSetMode(PI_ASPI_MISO, old_mode_amiso); - gpioSetMode(PI_ASPI_MOSI, old_mode_amosi); - - auxReg[AUX_SPI0_CNTL0_REG] = old_spi_cntl0; - auxReg[AUX_SPI0_CNTL1_REG] = old_spi_cntl1; - } - else - { - /* restore original state */ - - if (!(resvd&1)) gpioSetMode(PI_SPI_CE0, old_mode_ce0); - if (!(resvd&2)) gpioSetMode(PI_SPI_CE1, old_mode_ce1); - - gpioSetMode(PI_SPI_SCLK, old_mode_sclk); - gpioSetMode(PI_SPI_MISO, old_mode_miso); - gpioSetMode(PI_SPI_MOSI, old_mode_mosi); - - spiReg[SPI_CS] = old_spi_cs; - spiReg[SPI_CLK] = old_spi_clk; - } -} - -uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf) +static uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf) { uint32_t bits=0; @@ -3194,7 +3201,8 @@ uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf) return bits; } -void _spiRXBits(char *buf, int pos, int bitlen, int msbf, uint32_t bits) +static void _spiRXBits( + char *buf, int pos, int bitlen, int msbf, uint32_t bits) { if (buf) { @@ -3206,18 +3214,30 @@ void _spiRXBits(char *buf, int pos, int bitlen, int msbf, uint32_t bits) } } +static void spiACS(int channel, int on) +{ + int gpio; -void spiGoA( + switch (channel) + { + case 0: gpio = PI_ASPI_CE0; break; + case 1: gpio = PI_ASPI_CE1; break; + default: gpio = PI_ASPI_CE2; break; + } + myGpioWrite(gpio, on); +} + +static void spiGoA( unsigned speed, /* bits per second */ uint32_t flags, /* flags */ char *txBuf, /* tx buffer */ char *rxBuf, /* rx buffer */ unsigned count) /* number of bytes */ { - char bit_cs; - char bit_ir[4] = {1, 0, 1, 0}; - char bit_or[4] = {0, 1, 0, 1}; - char bit_ic[4] = {0, 0, 1, 1}; + int cs; + char bit_ir[4] = {1, 0, 0, 1}; /* read on rising edge */ + char bit_or[4] = {0, 1, 1, 0}; /* write on rising edge */ + char bit_ic[4] = {0, 0, 1, 1}; /* invert clock */ int mode, bitlen, txmsbf, rxmsbf, channel; unsigned txCnt=0; @@ -3230,6 +3250,7 @@ void spiGoA( mode = PI_SPI_FLAGS_GET_MODE (flags); bitlen = PI_SPI_FLAGS_GET_BITLEN (flags); + if (!bitlen) bitlen = 8; /* correct count for word size */ @@ -3240,23 +3261,35 @@ void spiGoA( txmsbf = !PI_SPI_FLAGS_GET_TX_LSB (flags); rxmsbf = !PI_SPI_FLAGS_GET_RX_LSB (flags); - bit_cs = ~PI_SPI_FLAGS_GET_CSPOLS(flags); - bit_cs = (1< (1<<22)) SOFT_ERROR(PI_BAD_FLAGS, "bad spiFlags (0x%X)", spiFlags); - if (!spiAnyOpen(spiFlags)) spiInit(spiFlags); /* initialise on first open */ + if (!spiAnyOpen(spiFlags)) /* initialise on first open */ + { + spiInit(spiFlags); + spiGo(spiBaud, spiFlags, NULL, NULL, 0); + } slot = -1; @@ -3506,7 +3671,7 @@ int spiRead(unsigned handle, char *buf, unsigned count) if (spiInfo[handle].state != PI_SPI_OPENED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); - if ((count < 1) || (count > PI_MAX_SPI_DEVICE_COUNT)) + if (count > PI_MAX_SPI_DEVICE_COUNT) SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count); spiGo(spiInfo[handle].speed, spiInfo[handle].flags, NULL, buf, count); @@ -3527,7 +3692,7 @@ int spiWrite(unsigned handle, char *buf, unsigned count) if (spiInfo[handle].state != PI_SPI_OPENED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); - if ((count < 1) || (count > PI_MAX_SPI_DEVICE_COUNT)) + if (count > PI_MAX_SPI_DEVICE_COUNT) SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count); spiGo(spiInfo[handle].speed, spiInfo[handle].flags, buf, NULL, count); @@ -3548,7 +3713,7 @@ int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count) if (spiInfo[handle].state != PI_SPI_OPENED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); - if ((count < 1) || (count > PI_MAX_SPI_DEVICE_COUNT)) + if (count > PI_MAX_SPI_DEVICE_COUNT) SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count); spiGo(spiInfo[handle].speed, spiInfo[handle].flags, txBuf, rxBuf, count); @@ -3842,7 +4007,7 @@ static void dmaCbPrint(int pos) p = dmaCB2adr(pos); - fprintf(stderr, "i=%lx s=%lx d=%lx len=%lx s=%lx nxt=%lx\n", + fprintf(stderr, "i=%x s=%x d=%x len=%x s=%x nxt=%x\n", p->info, p->src, p->dst, p->length, p->stride, p->next); } @@ -4153,43 +4318,30 @@ static void sigHandler(int signum) } else { - if (signum == SIGUSR1) - { - if (gpioCfg.dbgLevel > DBG_MIN_LEVEL) - { - --gpioCfg.dbgLevel; - } - else gpioCfg.dbgLevel = DBG_MIN_LEVEL; - - DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel); - } - else if (signum == SIGUSR2) - { - if (gpioCfg.dbgLevel < DBG_MAX_LEVEL) - { - ++gpioCfg.dbgLevel; - } - else gpioCfg.dbgLevel = DBG_MAX_LEVEL; - - DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel); - } - else if (signum == SIGPIPE) - { - /* can happen when pipe/socket is remote closed */ - DBG(DBG_USER, "SIGPIPE received"); - } - else if (signum == SIGCHLD) + switch(signum) { - /* happens when system call is made */ - DBG(DBG_USER, "SIGCHLD received"); - } - else - { - /* exit */ - - DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum); - - exit(-1); + case SIGUSR1: + + if (gpioCfg.dbgLevel > DBG_MIN_LEVEL) --gpioCfg.dbgLevel; + else gpioCfg.dbgLevel = DBG_MIN_LEVEL; + DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel); + break; + + case SIGUSR2: + if (gpioCfg.dbgLevel < DBG_MAX_LEVEL) ++gpioCfg.dbgLevel; + else gpioCfg.dbgLevel = DBG_MAX_LEVEL; + DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel); + break; + + case SIGPIPE: + case SIGCHLD: + case SIGWINCH: + DBG(DBG_USER, "signal %d ignored", signum); + break; + + default: + DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum); + exit(-1); } } } @@ -5177,6 +5329,7 @@ static void *pthSocketThreadHandler(void *fdC) { /* extensions */ + case PI_CMD_CF2: case PI_CMD_I2CPK: case PI_CMD_I2CRD: case PI_CMD_I2CRI: @@ -7090,7 +7243,8 @@ int rawWaveAddSPI( uint32_t on_bits, off_bits; int tx_bit_pos; - DBG(DBG_USER, "spi=%08X off=%d spiSS=%d tx=%08X, num=%d fb=%d lb=%d spiBits=%d", + DBG(DBG_USER, + "spi=%08X off=%d spiSS=%d tx=%08X, num=%d fb=%d lb=%d spiBits=%d", (uint32_t)spi, offset, spiSS, (uint32_t)buf, spiTxBits, spiBitFirst, spiBitLast, spiBits); @@ -8561,7 +8715,11 @@ int gpioHardwarePWM( { /* record the PWM frequency and dutycycle */ - hw_pwm_freq[pwm] = frequency / PI_HW_PWM_RANGE; + /* currently both channels must use the same update rate */ + + hw_pwm_freq[0] = frequency / PI_HW_PWM_RANGE; + hw_pwm_freq[1] = frequency / PI_HW_PWM_RANGE; + hw_pwm_duty[pwm] = dutycycle; /* Abort any waveform transmission in progress */ @@ -8768,12 +8926,25 @@ unsigned gpioHardwareRevision(void) { while (fgets(buf, sizeof(buf), filp) != NULL) { - if (!strncasecmp("revision\t", buf, 9)) + if (!strncmp("model name", buf, 10)) + { + if (strstr (buf, "ARMv6") != NULL) + { + piModel = 1; + PI_PERI_BASE = 0x20000000; + } + else if (strstr (buf, "ARMv7") != NULL) + { + piModel = 2; + PI_PERI_BASE = 0x3F000000; + } + } + + if (!strncmp("Revision", buf, 8)) { if (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2) { - if (term == '\n') break; - rev = 0; + if (term != '\n') rev = 0; } } } @@ -8897,7 +9068,6 @@ int gpioCfgInterfaces(unsigned ifFlags) return 0; } - /* ----------------------------------------------------------------------- */ int gpioCfgSocketPort(unsigned port) @@ -8968,3 +9138,7 @@ int gpioCfgInternals(unsigned cfgWhat, int cfgVal) return retVal; } +/* include any user customisations */ + +#include "custom.cext" + diff --git a/pigpio.h b/pigpio.h index 3f8edb8..3c2d456 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 25 +#define PIGPIO_VERSION 26 /*TEXT @@ -351,8 +351,9 @@ uint32_t gpioOff; uint32_t usDelay; } gpioPulse_t; -#define WAVE_FLAG_READ 1 -#define WAVE_FLAG_TICK 2 +#define WAVE_FLAG_READ 1 +#define WAVE_FLAG_TICK 2 +#define WAVE_FLAG_COUNT 4 typedef struct { @@ -383,13 +384,13 @@ int clk_us; /* clock micros */ } 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]; +uint32_t info; +uint32_t src; +uint32_t dst; +uint32_t length; +uint32_t stride; +uint32_t next; +uint32_t pad[2]; } rawCbs_t; typedef void (*gpioAlertFunc_t) (int gpio, @@ -479,8 +480,8 @@ typedef void *(gpioThreadFunc_t) (void *); /* hardware PWM */ #define PI_HW_PWM_MIN_FREQ 5 -#define PI_HW_PWM_MAX_FREQ 250000 -#define PI_HW_PWM_RANGE 1000 +#define PI_HW_PWM_MAX_FREQ 50000 +#define PI_HW_PWM_RANGE 5000 /* hardware clock */ @@ -2083,8 +2084,8 @@ handle: >=0, as returned by a call to [*spiOpen*] count: the number of bytes to read . . -Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or -PI_SPI_XFER_FAILED. +Returns the number of bytes transferred if OK, otherwise +PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. D*/ @@ -2100,8 +2101,8 @@ handle: >=0, as returned by a call to [*spiOpen*] count: the number of bytes to write . . -Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or -PI_SPI_XFER_FAILED. +Returns the number of bytes transferred if OK, otherwise +PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. D*/ /*F*/ @@ -2118,8 +2119,8 @@ handle: >=0, as returned by a call to [*spiOpen*] count: the number of bytes to transfer . . -Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or -PI_SPI_XFER_FAILED. +Returns the number of bytes transferred if OK, otherwise +PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. D*/ @@ -3052,6 +3053,48 @@ Or in PI_DISABLE_SOCK_IF to disable the socket interface. D*/ +/*F*/ +int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count); +/*D +This function is available for user customisation. + +It returns a single integer value. + +. . + arg1: >=0 + arg2: >=0 + argx: extra (byte) arguments +count: number of extra arguments +. . + +Returns >= 0 if OK, less than 0 indicates a user defined error. +D*/ + + +/*F*/ +int gpioCustom2(unsigned arg1, char *argx, unsigned count, + char *retBuf, unsigned retMax); +/*D +This function is available for user customisation. + +It differs from gpioCustom1 in that it returns an array of bytes +rather than just an integer. + +The returned value is an integer indicating the number of returned bytes. +. . + arg1: >=0 + argx: extra (byte) arguments + count: number of extra arguments +retBuf: buffer for returned bytes +retMax: maximum number of bytes to return +. . + +Returns >= 0 if OK, less than 0 indicates a user defined error. + +The number of returned bytes must be retMax or less. +D*/ + + /*F*/ int gpioCfgInternals(unsigned cfgWhat, int cfgVal); /*D @@ -3686,7 +3729,7 @@ PWMduty::0-1000 The hardware PWM dutycycle. . . -#define PI_HW_PWM_RANGE 1000 +#define PI_HW_PWM_RANGE 5000 . . PWMfreq::5-250K @@ -3694,7 +3737,7 @@ The hardware PWM frequency. . . #define PI_HW_PWM_MIN_FREQ 5 -#define PI_HW_PWM_MAX_FREQ 250000 +#define PI_HW_PWM_MAX_FREQ 50000 . . range::25-40000 @@ -4013,6 +4056,9 @@ PARAMS*/ #define PI_CMD_HC 85 #define PI_CMD_HP 86 +#define PI_CMD_CF1 87 +#define PI_CMD_CF2 88 + #define PI_CMD_NOIB 99 /*DEF_E*/ @@ -4173,13 +4219,20 @@ after this command is issued. #define PI_NOT_SERVO_GPIO -93 // gpio is not in use for servo pulses #define PI_NOT_HCLK_GPIO -94 // gpio has no hardware clock #define PI_NOT_HPWM_GPIO -95 // gpio has no hardware PWM -#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 5-250K -#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-1000 +#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 5-50K +#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-5000 #define PI_BAD_HCLK_FREQ -98 // hardware clock frequency not 4689-25M #define PI_BAD_HCLK_PASS -99 // need password to use hardware clock 1 #define PI_HPWM_ILLEGAL -100 // illegal, PWM in use for main clock #define PI_BAD_DATABITS -101 // serial data bits not 1-32 #define PI_BAD_STOPBITS -102 // serial (half) stop bits not 2-8 +#define PI_MSG_TOOBIG -103 // socket/pipe message too big + +#define PI_PIGIF_ERR_0 -2000 +#define PI_PIGIF_ERR_99 -2099 + +#define PI_CUSTOM_ERR_0 -3000 +#define PI_CUSTOM_ERR_999 -3999 /*DEF_E*/ diff --git a/pigpio.py b/pigpio.py index 5ca345f..a4f2061 100644 --- a/pigpio.py +++ b/pigpio.py @@ -234,6 +234,11 @@ serial_write_byte Writes a byte to a serial device serial_data_available Returns number of bytes ready to be read +CUSTOM + +custom_1 User custom function 1 +custom_2 User custom function 2 + Utility get_current_tick Get current tick (microseconds) @@ -402,6 +407,9 @@ _PI_CMD_GPW =84 _PI_CMD_HC =85 _PI_CMD_HP =86 +_PI_CMD_CF1 =87 +_PI_CMD_CF2 =88 + _PI_CMD_NOIB= 99 # pigpio error numbers @@ -606,8 +614,8 @@ _errors=[ [PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"], [PI_NOT_HCLK_GPIO , "gpio has no hardware clock"], [PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"], - [PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-250K"], - [PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1000"], + [PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-50K"], + [PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-5000"], [PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"], [PI_BAD_HCLK_PASS , "need password to use hardware clock 1"], [PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"], @@ -1486,8 +1494,8 @@ class pi(): pigpio daemon is started (option -t). gpio:= see descripton - PWMfreq:= 0 (off) or 5-250K - PWMduty:= 0 (off) to 1000 (fully on). + PWMfreq:= 0 (off) or 5-50K + PWMduty:= 0 (off) to 5000 (fully on). Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, PI_NOT_HPWM_GPIO, PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ. @@ -1514,9 +1522,9 @@ class pi(): . . ... - pi.hardware_PWM(18, 800, 250) # 800Hz 25% dutycycle + pi.hardware_PWM(18, 800, 1250) # 800Hz 25% dutycycle - pi.hardware_PWM(18, 2000, 750) # 2000Hz 75% dutycycle + pi.hardware_PWM(18, 2000, 3750) # 2000Hz 75% dutycycle ... """ # pigpio message format @@ -2953,6 +2961,81 @@ class pi(): """ return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRC, user_gpio, 0)) + def custom_1(self, arg1=0, arg2=0, argx=[]): + """ + Calls a pigpio function customised by the user. + + arg1:= >=0, default 0. + arg2:= >=0, default 0. + argx:= extra arguments (each 0-255), default empty. + + The returned value is an integer which by convention + should be >=0 for OK and <0 for error. + + ... + value = pi.custom_1() + + value = pi.custom_1(23) + + value = pi.custom_1(0, 55) + + value = pi.custom_1(23, 56, [1, 5, 7]) + + value = pi.custom_1(23, 56, b"hello") + + value = pi.custom_1(23, 56, "hello") + ... + """ + # I p1 arg1 + # I p2 arg2 + # I p3 len + ## extension ## + # s len argx bytes + + return u2i(_pigpio_command_ext( + self.sl, _PI_CMD_CF1, arg1, arg2, len(argx), [argx])) + + def custom_2(self, arg1=0, argx=[], retMax=8192): + """ + Calls a pigpio function customised by the user. + + arg1:= >=0, default 0. + argx:= extra arguments (each 0-255), default empty. + retMax:= >=0, maximum number of bytes to return, default 8192. + + The returned value is a tuple of the number of bytes + returned 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). + + ... + (count, data) = pi.custom_2() + + (count, data) = pi.custom_2(23) + + (count, data) = pi.custom_2(23, [1, 5, 7]) + + (count, data) = pi.custom_2(23, b"hello") + + (count, data) = pi.custom_2(23, "hello", 128) + ... + """ + # I p1 arg1 + # I p2 retMax + # I p3 len + ## extension ## + # s len argx bytes + + # Don't raise exception. Must release lock. + bytes = u2i(_pigpio_command_ext( + self.sl, _PI_CMD_CF2, arg1, retMax, len(argx), [argx], False)) + if bytes > 0: + data = self._rxbuf(bytes) + else: + data = "" + self.sl.l.release() + return bytes, data + def callback(self, user_gpio, edge=RISING_EDGE, func=None): """ Calls a user supplied function (a callback) whenever the @@ -3043,9 +3126,6 @@ class pi(): self.sl = _socklock() self._notify = None - self._host = '' - self._port = 8888 - self._host = host self._port = int(port) diff --git a/pigpiod_if.c b/pigpiod_if.c index c51e6a5..95866b2 100644 --- a/pigpiod_if.c +++ b/pigpiod_if.c @@ -1313,6 +1313,58 @@ int serial_read(unsigned handle, char *buf, unsigned count) int serial_data_available(unsigned handle) {return pigpio_command(gPigCommand, PI_CMD_SERDA, handle, 0, 1);} +int custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned count) +{ + gpioExtent_t ext[1]; + + /* + p1=arg1 + p2=arg2 + p3=count + ## extension ## + char argx[count] + */ + + ext[0].size = count; + ext[0].ptr = argx; + + return pigpio_command_ext( + gPigCommand, PI_CMD_CF1, arg1, arg2, count, 1, ext, 1); +} + + +int custom_2(unsigned arg1, char *argx, unsigned count, + char *retBuf, uint32_t retMax) +{ + int bytes; + gpioExtent_t ext[1]; + + /* + p1=arg1 + p2=retMax + p3=count + ## extension ## + char argx[count] + */ + + ext[0].size = count; + ext[0].ptr = argx; + + bytes = pigpio_command_ext + (gPigCommand, PI_CMD_CF2, arg1, retMax, count, 1, ext, 0); + + if (bytes > 0) + { + /* get the data */ + recv(gPigCommand, retBuf, bytes, MSG_WAITALL); + } + + pthread_mutex_unlock(&command_mutex); + + return bytes; +} + + int callback(unsigned user_gpio, unsigned edge, CBFunc_t f) {return intCallback(user_gpio, edge, f, 0, 0);} diff --git a/pigpiod_if.h b/pigpiod_if.h index 61596fa..b256d46 100644 --- a/pigpiod_if.h +++ b/pigpiod_if.h @@ -248,6 +248,11 @@ serial_read Reads bytes from a serial device serial_data_available Returns number of bytes ready to be read +CUSTOM + +custom_1 User custom function 1 +custom_2 User custom function 2 + UTILITIES get_current_tick Get current tick (microseconds) @@ -896,8 +901,8 @@ daemon is started (option -t). . . gpio: see descripton -PWMfreq: 0 (off) or 5-250K -PWMduty: 0 (off) to 1000 (fully on). +PWMfreq: 0 (off) or 5-50K +PWMduty: 0 (off) to 5000 (fully on). . . Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, @@ -1804,8 +1809,8 @@ handle: >=0, as returned by a call to [*spi_open*]. count: the number of bytes to read. . . -Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or -PI_SPI_XFER_FAILED. +Returns the number of bytes transferred if OK, otherwise +PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. D*/ /*F*/ @@ -1820,8 +1825,8 @@ handle: >=0, as returned by a call to [*spi_open*]. count: the number of bytes to write. . . -Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or -PI_SPI_XFER_FAILED. +Returns the number of bytes transferred if OK, otherwise +PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. D*/ /*F*/ @@ -1838,8 +1843,8 @@ handle: >=0, as returned by a call to [*spi_open*]. count: the number of bytes to transfer. . . -Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or -PI_SPI_XFER_FAILED. +Returns the number of bytes transferred if OK, otherwise +PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED. D*/ /*F*/ @@ -1944,6 +1949,48 @@ Returns the number of bytes of data available (>=0) if OK, otherwise PI_BAD_HANDLE. D*/ +/*F*/ +int custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned count); +/*D +This function is available for user customisation. + +It returns a single integer value. + +. . + arg1: >=0 + arg2: >=0 + argx: extra (byte) arguments +count: number of extra arguments +. . + +Returns >= 0 if OK, less than 0 indicates a user defined error. +D*/ + + +/*F*/ +int custom_2(unsigned arg1, char *argx, unsigned count, + char *retBuf, unsigned retMax); +/*D +This function is available for user customisation. + +It differs from custom_1 in that it returns an array of bytes +rather than just an integer. + +The return value is an integer indicating the number of returned bytes. +. . + arg1: >=0 + argx: extra (byte) arguments + count: number of extra arguments +retBuf: buffer for returned data +retMax: maximum number of bytes to return +. . + +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 callback(unsigned user_gpio, unsigned edge, CBFunc_t f); /*D diff --git a/pigs.c b/pigs.c index 23d9bfe..e4e2421 100644 --- a/pigs.c +++ b/pigs.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 18+ +This version is for pigpio version 26+ */ #include @@ -141,7 +141,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd) printf(cmdUsage); break; - case 6: /* I2CPK I2CRD I2CRI I2CRK SERR SLR SPIX SPIR */ + case 6: /* CF2 I2CPK I2CRD I2CRI I2CRK SERR SLR SPIX SPIR */ printf("%d", r); if (r < 0) fatal("ERROR: %s", cmdErrStr(r)); if (r > 0) @@ -178,6 +178,7 @@ void get_extensions(int sock, int command, int res) { switch (command) { + case PI_CMD_CF2: case PI_CMD_I2CPK: case PI_CMD_I2CRD: case PI_CMD_I2CRI: diff --git a/x_pigs b/x_pigs index 34c0642..9753cca 100755 --- a/x_pigs +++ b/x_pigs @@ -1,6 +1,6 @@ #!/bin/bash -VERSION=25 +VERSION=26 GPIO=4 @@ -46,7 +46,7 @@ s=$(pigs bs2 0) if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi s=$(pigs h) -if [[ ${#s} = 5150 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi +if [[ ${#s} = 5167 ]]; 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 diff --git a/x_pipe b/x_pipe index 744dee5..ba5341c 100755 --- a/x_pipe +++ b/x_pipe @@ -1,6 +1,6 @@ #!/bin/bash -VERSION=25 +VERSION=26 GPIO=4 @@ -52,14 +52,14 @@ if [[ $s = 0 ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi echo "h" >/dev/pigpio read -t 1 s /dev/pigpio read -t 1 s