+#
CC = gcc
AR = ar
RANLIB = ranlib
# 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
*/
/*
-This version is for pigpio version 25+
+This version is for pigpio version 26+
*/
#include <stdio.h>
{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
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<<g) is set for each gpio g of interest.\n\
-bv = byte value (0-255).\n\
-bvs = one or more byte values (0-255).\n\
-cf = hardware clock frequency (4689-25M).\n\
-db = data bits (1-32).\n\
-g = any gpio (0-53).\n\
-h = handle (>=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<<g) is set for each gpio g of interest\n\
+bv = byte value (0-255)\n\
+bvs = one or more byte values (0-255)\n\
+cf = hardware clock frequency (4689-25M)\n\
+db = data bits (1-32)\n\
+g = any gpio (0-53)\n\
+h = handle (>=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
{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"},
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...
--- /dev/null
+/*
+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<count; i++) if (argx[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;
+}
+
For more information, please refer to <http://unlicense.org/>
*/
-/* pigpio version 25 */
+/* pigpio version 26 */
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <termios.h>
#include <signal.h>
#include <errno.h>
-#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define BIT (1<<(gpio&0x1F))
-
#define CHECK_INITED \
do \
{ \
#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
/* ----------------------------------------------------------------------- */
+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;
}
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;
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;
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);
}
/* ----------------------------------------------------------------------- */
+#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;
rawWave_t * waves;
+ int b, baseCB;
+ uint32_t def_next;
+
numWaves = wfc[wfcur];
waves = wf [wfcur];
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; b<PI_WAVE_COUNT_BLOCKS; b++)
+ rawWaveSetIn( (b*(PI_WAVE_COUNT_LENGTH+1))+1,
+ waveCbPOadr (baseCB+((b*PI_WAVE_COUNT_BLOCKS)+3)) | DMA_BUS_ADR);
+
+ rawWaveSetIn
+ (((PI_WAVE_COUNT_BLOCKS-1)*(PI_WAVE_COUNT_LENGTH+1))+7, 0);
+
+ for (b=0; b<PI_WAVE_COUNT_BLOCKS; b++)
+ {
+ /* copy BOTTOM to NEXT */
+
+ p = rawWaveCBAdr(botCB++);
+
+ p->info = 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;
--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;
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;
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)
{
}
}
+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;
mode = PI_SPI_FLAGS_GET_MODE (flags);
bitlen = PI_SPI_FLAGS_GET_BITLEN (flags);
+
if (!bitlen) bitlen = 8;
/* correct count for word size */
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<<channel) ^ bit_cs;
- bit_cs &= 7;
+ cs = PI_SPI_FLAGS_GET_CSPOLS(flags) & (1<<channel);
spiDefaults = AUXSPI_CNTL0_SPEED(125000000/speed) |
- AUXSPI_CNTL0_CS(bit_cs) |
AUXSPI_CNTL0_IN_RISING(bit_ir[mode]) |
AUXSPI_CNTL0_OUT_RISING(bit_or[mode]) |
AUXSPI_CNTL0_INVERT_CLK(bit_ic[mode]) |
AUXSPI_CNTL0_MSB_FIRST(txmsbf) |
AUXSPI_CNTL0_SHIFT_LEN(bitlen);
- auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE | AUXSPI_CNTL0_CLR_FIFOS;
+ if (!count)
+ {
+ auxReg[AUX_SPI0_CNTL0_REG] =
+ AUXSPI_CNTL0_ENABLE | AUXSPI_CNTL0_CLR_FIFOS;
+
+ usleep(10);
+
+ auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE | spiDefaults;
+
+ auxReg[AUX_SPI0_CNTL1_REG] = AUXSPI_CNTL1_MSB_FIRST(rxmsbf);
+
+ return;
+ }
+
+ auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE | spiDefaults;
- auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE | spiDefaults;
auxReg[AUX_SPI0_CNTL1_REG] = AUXSPI_CNTL1_MSB_FIRST(rxmsbf);
+ spiACS(channel, cs);
+
while ((txCnt < count) || (rxCnt < count))
{
statusReg = auxReg[AUX_SPI0_STAT_REG];
{
if (!rxEmpty)
{
- _spiRXBits(rxBuf, rxCnt++, bitlen, rxmsbf, auxReg[AUX_SPI0_IO_REG]);
+ _spiRXBits(
+ rxBuf, rxCnt++, bitlen, rxmsbf, auxReg[AUX_SPI0_IO_REG]);
}
}
while ((auxReg[AUX_SPI0_STAT_REG] & AUXSPI_STAT_BUSY)) ;
- auxReg[AUX_SPI0_CNTL0_REG] = spiDefaults; /* stop */
+ spiACS(channel, !cs);
}
static void spiGoS(
SPI_CS_CSPOL(cspol) |
SPI_CS_CLEAR(3);
+ spiReg[SPI_CS] = spiDefaults; /* stop */
+
+ if (!count) return;
+
if (flag3w)
{
if (ren3w < count)
char *rxBuf,
unsigned count)
{
+ DBG(0, "spiGo");
if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
+ {
+ DBG(0, "spiGoA");
spiGoA(speed, flags, txBuf, rxBuf, count);
+ }
else
+ {
+ DBG(0, "spiGoS");
spiGoS(speed, flags, txBuf, rxBuf, count);
+ }
}
static int spiAnyOpen(uint32_t flags)
return 0;
}
+static void spiInit(uint32_t flags)
+{
+ uint32_t resvd, cspols;
+
+ resvd = PI_SPI_FLAGS_GET_RESVD(flags);
+ cspols = PI_SPI_FLAGS_GET_CSPOLS(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];
+
+ /* manually control auxiliary SPI chip selects */
+
+ if (!(resvd&1))
+ {
+ gpioSetMode(PI_ASPI_CE0, PI_OUTPUT);
+ myGpioWrite(PI_ASPI_CE0, !(cspols&1));
+ }
+
+ if (!(resvd&2))
+ {
+ gpioSetMode(PI_ASPI_CE1, PI_OUTPUT);
+ myGpioWrite(PI_ASPI_CE1, !(cspols&2));
+ }
+
+ if (!(resvd&4))
+ {
+ gpioSetMode(PI_ASPI_CE2, PI_OUTPUT);
+ myGpioWrite(PI_ASPI_CE2, !(cspols&4));
+ }
+
+ /* set gpios to SPI mode */
+
+ 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))
+ {
+ /* disable module and access to registers */
+
+ auxReg[AUX_ENABLES] &= (~AUXENB_SPI1);
+
+ /* 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;
+ }
+}
+
int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)
{
int i, slot;
if (PI_SPI_FLAGS_GET_AUX_SPI(spiFlags))
{
if (gpioHardwareRevision() < 16)
- SOFT_ERROR(PI_NO_AUX_SPI, "no auxiliary SPI, need a B+");
+ SOFT_ERROR(PI_NO_AUX_SPI, "no auxiliary SPI, need a A+/B+");
i = PI_NUM_AUX_SPI_CHANNEL;
}
if (spiFlags > (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;
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);
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);
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);
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);
}
}
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);
}
}
}
{
/* extensions */
+ case PI_CMD_CF2:
case PI_CMD_I2CPK:
case PI_CMD_I2CRD:
case PI_CMD_I2CRI:
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);
{
/* 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 */
{
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;
}
}
}
return 0;
}
-
/* ----------------------------------------------------------------------- */
int gpioCfgSocketPort(unsigned port)
return retVal;
}
+/* include any user customisations */
+
+#include "custom.cext"
+
#include <stdint.h>
#include <pthread.h>
-#define PIGPIO_VERSION 25
+#define PIGPIO_VERSION 26
/*TEXT
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
{
} 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,
/* 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 */
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*/
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*/
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*/
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
The hardware PWM dutycycle.
. .
-#define PI_HW_PWM_RANGE 1000
+#define PI_HW_PWM_RANGE 5000
. .
PWMfreq::5-250K
. .
#define PI_HW_PWM_MIN_FREQ 5
-#define PI_HW_PWM_MAX_FREQ 250000
+#define PI_HW_PWM_MAX_FREQ 50000
. .
range::25-40000
#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*/
#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*/
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)
_PI_CMD_HC =85
_PI_CMD_HP =86
+_PI_CMD_CF1 =87
+_PI_CMD_CF2 =88
+
_PI_CMD_NOIB= 99
# pigpio error numbers
[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"],
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.
. .
...
- 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
"""
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
self.sl = _socklock()
self._notify = None
- self._host = ''
- self._port = 8888
-
self._host = host
self._port = int(port)
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);}
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)
. .
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,
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*/
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*/
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*/
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
*/
/*
-This version is for pigpio version 18+
+This version is for pigpio version 26+
*/
#include <stdio.h>
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)
{
switch (command)
{
+ case PI_CMD_CF2:
case PI_CMD_I2CPK:
case PI_CMD_I2CRD:
case PI_CMD_I2CRI:
#!/bin/bash
-VERSION=25
+VERSION=26
GPIO=4
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
#!/bin/bash
-VERSION=25
+VERSION=26
GPIO=4
echo "h" >/dev/pigpio
read -t 1 s </dev/pigout
-if [[ $s = "BC1 bits Clear specified gpios in bank 1." ]]
+if [[ $s = "BC1 bits Clear specified gpios in bank 1" ]]
then echo "HELP-a ok"
else echo "HELP-a fail ($s)"
fi
read -t 1 -N 9000 </dev/pigout # dump rest of help
echo "help" >/dev/pigpio
read -t 1 s </dev/pigout
-if [[ $s = "BC1 bits Clear specified gpios in bank 1." ]]
+if [[ $s = "BC1 bits Clear specified gpios in bank 1" ]]
then echo "HELP-b ok"
else echo "HELP-b fail ($s)"
fi