This commit is contained in:
joan 2015-02-02 21:11:28 +00:00
parent 84b06fca73
commit 624ecb6fb0
11 changed files with 858 additions and 343 deletions

View File

@ -1,3 +1,4 @@
#
CC = gcc CC = gcc
AR = ar AR = ar
RANLIB = ranlib RANLIB = ranlib
@ -80,12 +81,12 @@ $(LIB2): $(OBJ2)
# generated using gcc -MM *.c # 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 command.o: command.c pigpio.h command.h
pig2vcd.o: pig2vcd.c pigpio.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.o: pigpiod.c pigpio.h
pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
pigs.o: pigs.c pigpio.h command.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

305
command.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/ */
/* /*
This version is for pigpio version 25+ This version is for pigpio version 26+
*/ */
#include <stdio.h> #include <stdio.h>
@ -51,6 +51,9 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_BS1, "BS1", 111, 1}, // gpioWrite_Bits_0_31_Set {PI_CMD_BS1, "BS1", 111, 1}, // gpioWrite_Bits_0_31_Set
{PI_CMD_BS2, "BS2", 111, 1}, // gpioWrite_Bits_32_53_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_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle
{PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth {PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth
@ -217,163 +220,167 @@ cmdInfo_t cmdInfo[]=
char * cmdUsage = "\ char * cmdUsage = "\
BC1 bits Clear specified gpios in bank 1.\n\ BC1 bits Clear specified gpios in bank 1\n\
BC2 bits Clear specified gpios in bank 2.\n\ BC2 bits Clear specified gpios in bank 2\n\
BR1 Read bank 1 gpios.\n\ BR1 Read bank 1 gpios\n\
BR2 Read bank 2 gpios.\n\ BR2 Read bank 2 gpios\n\
BS1 bits Set specified gpios in bank 2.\n\ BS1 bits Set specified gpios in bank 2\n\
BS2 bits Set specified gpios in bank 2.\n\ BS2 bits Set specified gpios in bank 2\n\
\n\ \n\
GDC u Get PWM dutycycle for gpio.\n\ CF1 uvs Custom function 1\n\
GPW u Get servo pulsewidth for gpio.\n\ CF2 uvs Custom function 2\n\
\n\ \n\
H/HELP Display command help.\n\ GDC u Get PWM dutycycle for gpio\n\
GPW u Get servo pulsewidth for gpio\n\
\n\ \n\
HC g cf Set hardware clock frequency.\n\ H/HELP Display command help\n\
HP g pf pdc Set hardware PWM frequency and dutycycle.\n\
\n\ \n\
HWVER Get hardware version.\n\ HC g cf Set hardware clock frequency\n\
HP g pf pdc Set hardware PWM frequency and dutycycle\n\
\n\ \n\
I2CC h Close I2C handle.\n\ HWVER Get hardware version\n\
I2CO ib id if Open I2C bus and device with flags.\n\
\n\ \n\
I2CPC h r wv smb Process Call: exchange register with word.\n\ I2CC h Close I2C handle\n\
I2CPK h r bvs smb Block Process Call: exchange data bytes with register.\n\ I2CO ib id if Open I2C bus and device with flags\n\
\n\ \n\
I2CRB h r smb Read Byte Data: read byte from register.\n\ I2CPC h r wv smb Process Call: exchange register with word\n\
I2CRD h num i2c Read bytes.\n\ I2CPK h r bvs smb Block Process Call: exchange data bytes with register\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\ \n\
I2CWB h r bv smb Write Byte Data: write byte to register.\n\ I2CRB h r smb Read Byte Data: read byte from register\n\
I2CWD h bvs i2c Write data.\n\ I2CRD h num i2c Read bytes\n\
I2CWI h r bvs smb Write I2C Block Data.\n\ I2CRI h r num smb Read I2C Block Data: read bytes from register\n\
I2CWK h r bvs smb Write Block Data: write data to register.\n\ I2CRK h r smb Read Block Data: read data from register\n\
I2CWQ h bit smb Write Quick: write bit.\n\ I2CRS h smb Read Byte: read byte\n\
I2CWS h bv smb Write Byte: write byte.\n\ I2CRW h r smb Read Word Data: read word from register\n\
I2CWW h r wv smb Write Word Data: write word to register.\n\
\n\ \n\
M/MODES g m Set gpio mode.\n\ I2CWB h r bv smb Write Byte Data: write byte to register\n\
MG/MODEG g Get gpio mode.\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\ \n\
MICS v Delay for microseconds.\n\ M/MODES g m Set gpio mode\n\
MILS v Delay for milliseconds.\n\ MG/MODEG g Get gpio mode\n\
\n\ \n\
NB h bits Start notification.\n\ MICS v Delay for microseconds\n\
NC h Close notification.\n\ MILS v Delay for milliseconds\n\
NO Request a notification.\n\
NP h Pause notification.\n\
\n\ \n\
P/PWM u v Set gpio PWM value.\n\ NB h bits Start notification\n\
NC h Close notification\n\
NO Request a notification\n\
NP h Pause notification\n\
\n\ \n\
PARSE t Validate script.\n\ P/PWM u v Set gpio PWM value\n\
\n\ \n\
PFG u Get gpio PWM frequency.\n\ PARSE t Validate script\n\
PFS u v Set gpio PWM frequency.\n\
\n\ \n\
PIGPV Get pigpio library version.\n\ PFG u Get gpio PWM frequency\n\
PFS u v Set gpio PWM frequency\n\
\n\ \n\
PRG u Get gpio PWM range.\n\ PIGPV Get pigpio library version\n\
\n\ \n\
PROC t Store script.\n\ PRG u Get gpio PWM range\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\ \n\
PRRG u Get gpio PWM real range.\n\ PROC t Store script\n\
PRS u v Set gpio PWM range.\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\ \n\
PUD g p Set gpio pull up/down.\n\ PRRG u Get gpio PWM real range\n\
PRS u v Set gpio PWM range\n\
\n\ \n\
R/READ g Read gpio level.\n\ PUD g p Set gpio pull up/down\n\
\n\ \n\
S/SERVO u v Set gpio servo pulsewidth.\n\ R/READ g Read gpio level\n\
\n\ \n\
SERC h Close serial handle.\n\ S/SERVO u v Set gpio servo pulsewidth\n\
SERDA h Check for serial data ready to read.\n\
SERO srd srb srf Open serial device at baud with flags.\n\
\n\ \n\
SERR h num Read bytes from serial handle.\n\ SERC h Close serial handle\n\
SERRB Read byte from serial handle.\n\ SERDA h Check for serial data ready to read\n\
SERW h bvs Write bytes to serial handle.\n\ SERO srd srb srf Open serial device at baud with flags\n\
SERWB h bv Write byte to serial handle.\n\
\n\ \n\
SLR u num Read bit bang serial data from gpio.\n\ SERR h num Read bytes from serial handle\n\
SLRC u Close gpio for bit bang serial data.\n\ SERRB h Read byte from serial handle\n\
SLRO u b db Open gpio for bit bang serial data.\n\ SERW h bvs Write bytes to serial handle\n\
SERWB h bv Write byte to serial handle\n\
\n\ \n\
SPIC h SPI close handle.\n\ SLR u num Read bit bang serial data from gpio\n\
SPIO sc sb sf SPI open channel at baud with flags.\n\ SLRC u Close gpio for bit bang serial data\n\
SPIR h num SPI read bytes from handle.\n\ SLRO u b db Open gpio for bit bang serial data\n\
SPIW h bvs SPI write bytes to handle.\n\
SPIX h bvs SPI transfer bytes to handle.\n\
\n\ \n\
T/TICK Get current tick.\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\ \n\
TRIG u pl L Trigger level for micros on gpio.\n\ T/TICK Get current tick\n\
\n\ \n\
W/WRITE g L Write level to gpio.\n\ TRIG u pl L Trigger level for micros on gpio\n\
\n\ \n\
WDOG u v Set millisecond watchdog on gpio.\n\ W/WRITE g L Write level to gpio\n\
\n\ \n\
WVAG trips Wave add generic pulses.\n\ WDOG u v Set millisecond watchdog on gpio\n\
\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\ 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\ o bvs hb (half)stopbits, offset o micros from wave start\n\
WVBSY Check if wave busy.\n\ WVBSY Check if wave busy\n\
WVCLR Wave clear.\n\ WVCLR Wave clear\n\
WVCRE Create wave from added pulses.\n\ WVCRE Create wave from added pulses\n\
WVDEL wid Delete waves w and higher.\n\ WVDEL wid Delete waves w and higher\n\
WVGO Wave transmit (DEPRECATED).\n\ WVGO Wave transmit (DEPRECATED)\n\
WVGOR Wave transmit repeatedly (DEPRECATED).\n\ WVGOR Wave transmit repeatedly (DEPRECATED)\n\
WVHLT Wave stop.\n\ WVHLT Wave stop\n\
WVNEW Start a new empty wave.\n\ WVNEW Start a new empty wave\n\
WVSC ws Wave get DMA control block stats.\n\ WVSC ws Wave get DMA control block stats\n\
WVSM ws Wave get micros stats.\n\ WVSM ws Wave get micros stats\n\
WVSP ws Wave get pulses stats.\n\ WVSP ws Wave get pulses stats\n\
WVTX wid Transmit wave as one-shot.\n\ WVTX wid Transmit wave as one-shot\n\
WVTXR wid Transmit wave repeatedly.\n\ WVTXR wid Transmit wave repeatedly\n\
\n\ \n\
bits = a mask where (1<<g) is set for each gpio g of interest.\n\ bits = a mask where (1<<g) is set for each gpio g of interest\n\
bv = byte value (0-255).\n\ bv = byte value (0-255)\n\
bvs = one or more byte values (0-255).\n\ bvs = one or more byte values (0-255)\n\
cf = hardware clock frequency (4689-25M).\n\ cf = hardware clock frequency (4689-25M)\n\
db = data bits (1-32).\n\ db = data bits (1-32)\n\
g = any gpio (0-53).\n\ g = any gpio (0-53)\n\
h = handle (>=0).\n\ h = handle (>=0)\n\
hb = (half) stop bits (2-8).\n\ hb = (half) stop bits (2-8)\n\
ib = I2C bus (0-1).\n\ ib = I2C bus (0-1)\n\
id = I2C device (0-127).\n\ id = I2C device (0-127)\n\
if = I2C flags (0).\n\ if = I2C flags (0)\n\
L = level (0-1).\n\ L = level (0-1)\n\
m = mode (RW540123).\n\ m = mode (RW540123)\n\
num = number of bytes to read.\n\ num = number of bytes to read\n\
o = offset (>=0).\n\ o = offset (>=0)\n\
p = pud (ODU).\n\ p = pud (ODU)\n\
pars = 0 to 10 parameters for script.\n\ pars = 0 to 10 parameters for script\n\
pdc = hardware PWM dutycycle (0-1000).\n\ pdc = hardware PWM dutycycle (0-5000)\n\
pf = hardware PWM frequency (5-250K).\n\ pf = hardware PWM frequency (5-50K)\n\
pl = pulse length (1-100).\n\ pl = pulse length (1-100)\n\
r = register.\n\ r = register\n\
sid = script id (>=0).\n\ sid = script id (>=0)\n\
sb = SPI baud.\n\ sb = SPI baud\n\
sc = SPI channel (0-1).\n\ sc = SPI channel (0-1)\n\
sf = SPI flags (0-3).\n\ sf = SPI flags (0-3)\n\
srd = serial device (/dev/tty*).\n\ srd = serial device (/dev/tty*)\n\
srb = serial baud rate.\n\ srb = serial baud rate\n\
srf = serial flags (0).\n\ srf = serial flags (0)\n\
t = text.\n\ t = text\n\
trips = 1 or more triplets of gpios on, gpios off, delay.\n\ trips = 1 or more triplets of gpios on, gpios off, delay\n\
u = user gpio (0-31).\n\ u = user gpio (0-31)\n\
v = value.\n\ uvs = zero or more values >= 0, any after the first two must <= 255\n\
w = wave id (>=0).\n\ v = value\n\
ws = 0=now, 1=high, 2=max.\n\ w = wave id (>=0)\n\
wv = word value (0-65535).\n\ ws = 0=now, 1=high, 2=max\n\
wv = word value (0-65535)\n\
\n\ \n\
Numbers may be entered as hex (prefix 0x), octal (prefix 0),\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 typedef struct
@ -479,8 +486,8 @@ static errInfo_t errInfo[]=
{PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"}, {PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"},
{PI_NOT_HCLK_GPIO , "gpio has no hardware clock"}, {PI_NOT_HCLK_GPIO , "gpio has no hardware clock"},
{PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"}, {PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"},
{PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-250K"}, {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-50K"},
{PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1000"}, {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-5000"},
{PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"}, {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"},
{PI_BAD_HCLK_PASS , "need password to use hardware clock 1"}, {PI_BAD_HCLK_PASS , "need password to use hardware clock 1"},
{PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"}, {PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"},
@ -940,6 +947,52 @@ int cmdParse(
break; 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 case 196: /* WVAS
gpio baud offset char... gpio baud offset char...

54
custom.cext Normal file
View File

@ -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<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;
}

510
pigpio.c
View File

@ -25,10 +25,11 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/> For more information, please refer to <http://unlicense.org/>
*/ */
/* pigpio version 25 */ /* pigpio version 26 */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdarg.h> #include <stdarg.h>
@ -39,7 +40,6 @@ For more information, please refer to <http://unlicense.org/>
#include <termios.h> #include <termios.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include <time.h> #include <time.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -188,7 +188,6 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define BIT (1<<(gpio&0x1F)) #define BIT (1<<(gpio&0x1F))
#define CHECK_INITED \ #define CHECK_INITED \
do \ do \
{ \ { \
@ -286,15 +285,18 @@ bit 0 READ_LAST_NOT_SET_ERROR
#define DMA_BUS_ADR 0x40000000 #define DMA_BUS_ADR 0x40000000
#define AUX_BASE 0x20215000 static volatile unsigned int piModel = 1;
#define CLK_BASE 0x20101000 static volatile unsigned int PI_PERI_BASE = 0x20000000;
#define DMA_BASE 0x20007000
#define DMA15_BASE 0x20E05000 #define AUX_BASE (PI_PERI_BASE + 0x00215000)
#define GPIO_BASE 0x20200000 #define CLK_BASE (PI_PERI_BASE + 0x00101000)
#define PCM_BASE 0x20203000 #define DMA_BASE (PI_PERI_BASE + 0x00007000)
#define PWM_BASE 0x2020C000 #define DMA15_BASE (PI_PERI_BASE + 0x00E05000)
#define SPI_BASE 0x20204000 #define GPIO_BASE (PI_PERI_BASE + 0x00200000)
#define SYST_BASE 0x20003000 #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 AUX_LEN 0xD8
#define CLK_LEN 0xA8 #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) static void myGpioSleep(int seconds, int micros)
{ {
struct timespec ts, rem; struct timespec ts, rem;
@ -1441,6 +1451,18 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
} }
break; 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_GDC: res = gpioGetPWMdutycycle(p[1]); break;
case PI_CMD_GPW: res = gpioGetServoPulsewidth(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]); if (myPermit(p[1])) res = gpioServo(p[1], p[2]);
else 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; res = PI_NOT_PERMITTED;
} }
break; break;
@ -2072,7 +2095,7 @@ static void waveCbOPrint(int pos)
p = rawWaveCBAdr(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); 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) static int wave2Cbs(unsigned wave_mode)
{ {
int botCB=waveOutBotCB, botOOL=waveOutBotOOL, topOOL=waveOutTopOOL; int botCB=waveOutBotCB, botOOL=waveOutBotOOL, topOOL=waveOutTopOOL;
@ -2129,6 +2155,9 @@ static int wave2Cbs(unsigned wave_mode)
rawWave_t * waves; rawWave_t * waves;
int b, baseCB;
uint32_t def_next;
numWaves = wfc[wfcur]; numWaves = wfc[wfcur];
waves = wf [wfcur]; waves = wf [wfcur];
@ -2221,6 +2250,73 @@ static int wave2Cbs(unsigned wave_mode)
p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; 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 (waves[i].usDelay)
{ {
if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status; if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status;
@ -2458,6 +2554,12 @@ int rawWaveAddGeneric(unsigned numIn1, rawWave_t *in1)
--level; --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++; outPos++;
if (inPos1 >= numIn1) tNext1 = -1; 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_cntl0;
static uint32_t old_spi_cntl1; static uint32_t old_spi_cntl1;
static void spiInit(uint32_t flags) static uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf)
{
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)
{ {
uint32_t bits=0; uint32_t bits=0;
@ -3194,7 +3201,8 @@ uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf)
return bits; 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) 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 */ unsigned speed, /* bits per second */
uint32_t flags, /* flags */ uint32_t flags, /* flags */
char *txBuf, /* tx buffer */ char *txBuf, /* tx buffer */
char *rxBuf, /* rx buffer */ char *rxBuf, /* rx buffer */
unsigned count) /* number of bytes */ unsigned count) /* number of bytes */
{ {
char bit_cs; int cs;
char bit_ir[4] = {1, 0, 1, 0}; char bit_ir[4] = {1, 0, 0, 1}; /* read on rising edge */
char bit_or[4] = {0, 1, 0, 1}; char bit_or[4] = {0, 1, 1, 0}; /* write on rising edge */
char bit_ic[4] = {0, 0, 1, 1}; char bit_ic[4] = {0, 0, 1, 1}; /* invert clock */
int mode, bitlen, txmsbf, rxmsbf, channel; int mode, bitlen, txmsbf, rxmsbf, channel;
unsigned txCnt=0; unsigned txCnt=0;
@ -3230,6 +3250,7 @@ void spiGoA(
mode = PI_SPI_FLAGS_GET_MODE (flags); mode = PI_SPI_FLAGS_GET_MODE (flags);
bitlen = PI_SPI_FLAGS_GET_BITLEN (flags); bitlen = PI_SPI_FLAGS_GET_BITLEN (flags);
if (!bitlen) bitlen = 8; if (!bitlen) bitlen = 8;
/* correct count for word size */ /* correct count for word size */
@ -3240,23 +3261,35 @@ void spiGoA(
txmsbf = !PI_SPI_FLAGS_GET_TX_LSB (flags); txmsbf = !PI_SPI_FLAGS_GET_TX_LSB (flags);
rxmsbf = !PI_SPI_FLAGS_GET_RX_LSB (flags); rxmsbf = !PI_SPI_FLAGS_GET_RX_LSB (flags);
bit_cs = ~PI_SPI_FLAGS_GET_CSPOLS(flags); cs = PI_SPI_FLAGS_GET_CSPOLS(flags) & (1<<channel);
bit_cs = (1<<channel) ^ bit_cs;
bit_cs &= 7;
spiDefaults = AUXSPI_CNTL0_SPEED(125000000/speed) | spiDefaults = AUXSPI_CNTL0_SPEED(125000000/speed) |
AUXSPI_CNTL0_CS(bit_cs) |
AUXSPI_CNTL0_IN_RISING(bit_ir[mode]) | AUXSPI_CNTL0_IN_RISING(bit_ir[mode]) |
AUXSPI_CNTL0_OUT_RISING(bit_or[mode]) | AUXSPI_CNTL0_OUT_RISING(bit_or[mode]) |
AUXSPI_CNTL0_INVERT_CLK(bit_ic[mode]) | AUXSPI_CNTL0_INVERT_CLK(bit_ic[mode]) |
AUXSPI_CNTL0_MSB_FIRST(txmsbf) | AUXSPI_CNTL0_MSB_FIRST(txmsbf) |
AUXSPI_CNTL0_SHIFT_LEN(bitlen); 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); auxReg[AUX_SPI0_CNTL1_REG] = AUXSPI_CNTL1_MSB_FIRST(rxmsbf);
spiACS(channel, cs);
while ((txCnt < count) || (rxCnt < count)) while ((txCnt < count) || (rxCnt < count))
{ {
statusReg = auxReg[AUX_SPI0_STAT_REG]; statusReg = auxReg[AUX_SPI0_STAT_REG];
@ -3269,7 +3302,8 @@ void spiGoA(
{ {
if (!rxEmpty) if (!rxEmpty)
{ {
_spiRXBits(rxBuf, rxCnt++, bitlen, rxmsbf, auxReg[AUX_SPI0_IO_REG]); _spiRXBits(
rxBuf, rxCnt++, bitlen, rxmsbf, auxReg[AUX_SPI0_IO_REG]);
} }
} }
@ -3293,7 +3327,7 @@ void spiGoA(
while ((auxReg[AUX_SPI0_STAT_REG] & AUXSPI_STAT_BUSY)) ; while ((auxReg[AUX_SPI0_STAT_REG] & AUXSPI_STAT_BUSY)) ;
auxReg[AUX_SPI0_CNTL0_REG] = spiDefaults; /* stop */ spiACS(channel, !cs);
} }
static void spiGoS( static void spiGoS(
@ -3322,6 +3356,10 @@ static void spiGoS(
SPI_CS_CSPOL(cspol) | SPI_CS_CSPOL(cspol) |
SPI_CS_CLEAR(3); SPI_CS_CLEAR(3);
spiReg[SPI_CS] = spiDefaults; /* stop */
if (!count) return;
if (flag3w) if (flag3w)
{ {
if (ren3w < count) if (ren3w < count)
@ -3401,10 +3439,17 @@ static void spiGo(
char *rxBuf, char *rxBuf,
unsigned count) unsigned count)
{ {
DBG(0, "spiGo");
if (PI_SPI_FLAGS_GET_AUX_SPI(flags)) if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
{
DBG(0, "spiGoA");
spiGoA(speed, flags, txBuf, rxBuf, count); spiGoA(speed, flags, txBuf, rxBuf, count);
}
else else
{
DBG(0, "spiGoS");
spiGoS(speed, flags, txBuf, rxBuf, count); spiGoS(speed, flags, txBuf, rxBuf, count);
}
} }
static int spiAnyOpen(uint32_t flags) static int spiAnyOpen(uint32_t flags)
@ -3422,6 +3467,122 @@ static int spiAnyOpen(uint32_t flags)
return 0; 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 spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)
{ {
int i, slot; int i, slot;
@ -3434,7 +3595,7 @@ int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)
if (PI_SPI_FLAGS_GET_AUX_SPI(spiFlags)) if (PI_SPI_FLAGS_GET_AUX_SPI(spiFlags))
{ {
if (gpioHardwareRevision() < 16) 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; i = PI_NUM_AUX_SPI_CHANNEL;
} }
@ -3450,7 +3611,11 @@ int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)
if (spiFlags > (1<<22)) if (spiFlags > (1<<22))
SOFT_ERROR(PI_BAD_FLAGS, "bad spiFlags (0x%X)", spiFlags); 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; slot = -1;
@ -3506,7 +3671,7 @@ int spiRead(unsigned handle, char *buf, unsigned count)
if (spiInfo[handle].state != PI_SPI_OPENED) if (spiInfo[handle].state != PI_SPI_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
spiGo(spiInfo[handle].speed, spiInfo[handle].flags, NULL, buf, 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) if (spiInfo[handle].state != PI_SPI_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
spiGo(spiInfo[handle].speed, spiInfo[handle].flags, buf, NULL, 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) if (spiInfo[handle].state != PI_SPI_OPENED)
SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); 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); SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
spiGo(spiInfo[handle].speed, spiInfo[handle].flags, txBuf, rxBuf, count); spiGo(spiInfo[handle].speed, spiInfo[handle].flags, txBuf, rxBuf, count);
@ -3842,7 +4007,7 @@ static void dmaCbPrint(int pos)
p = dmaCB2adr(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); p->info, p->src, p->dst, p->length, p->stride, p->next);
} }
@ -4153,43 +4318,30 @@ static void sigHandler(int signum)
} }
else else
{ {
if (signum == SIGUSR1) switch(signum)
{ {
if (gpioCfg.dbgLevel > DBG_MIN_LEVEL) case SIGUSR1:
{
--gpioCfg.dbgLevel;
}
else gpioCfg.dbgLevel = DBG_MIN_LEVEL;
DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel); if (gpioCfg.dbgLevel > DBG_MIN_LEVEL) --gpioCfg.dbgLevel;
} else gpioCfg.dbgLevel = DBG_MIN_LEVEL;
else if (signum == SIGUSR2) DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel);
{ break;
if (gpioCfg.dbgLevel < DBG_MAX_LEVEL)
{
++gpioCfg.dbgLevel;
}
else gpioCfg.dbgLevel = DBG_MAX_LEVEL;
DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel); case SIGUSR2:
} if (gpioCfg.dbgLevel < DBG_MAX_LEVEL) ++gpioCfg.dbgLevel;
else if (signum == SIGPIPE) else gpioCfg.dbgLevel = DBG_MAX_LEVEL;
{ DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel);
/* can happen when pipe/socket is remote closed */ break;
DBG(DBG_USER, "SIGPIPE received");
}
else if (signum == SIGCHLD)
{
/* happens when system call is made */
DBG(DBG_USER, "SIGCHLD received");
}
else
{
/* exit */
DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum); case SIGPIPE:
case SIGCHLD:
case SIGWINCH:
DBG(DBG_USER, "signal %d ignored", signum);
break;
exit(-1); default:
DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum);
exit(-1);
} }
} }
} }
@ -5177,6 +5329,7 @@ static void *pthSocketThreadHandler(void *fdC)
{ {
/* extensions */ /* extensions */
case PI_CMD_CF2:
case PI_CMD_I2CPK: case PI_CMD_I2CPK:
case PI_CMD_I2CRD: case PI_CMD_I2CRD:
case PI_CMD_I2CRI: case PI_CMD_I2CRI:
@ -7090,7 +7243,8 @@ int rawWaveAddSPI(
uint32_t on_bits, off_bits; uint32_t on_bits, off_bits;
int tx_bit_pos; 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, (uint32_t)spi, offset, spiSS, (uint32_t)buf, spiTxBits,
spiBitFirst, spiBitLast, spiBits); spiBitFirst, spiBitLast, spiBits);
@ -8561,7 +8715,11 @@ int gpioHardwarePWM(
{ {
/* record the PWM frequency and dutycycle */ /* 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; hw_pwm_duty[pwm] = dutycycle;
/* Abort any waveform transmission in progress */ /* Abort any waveform transmission in progress */
@ -8768,12 +8926,25 @@ unsigned gpioHardwareRevision(void)
{ {
while (fgets(buf, sizeof(buf), filp) != NULL) 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 (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2)
{ {
if (term == '\n') break; if (term != '\n') rev = 0;
rev = 0;
} }
} }
} }
@ -8897,7 +9068,6 @@ int gpioCfgInterfaces(unsigned ifFlags)
return 0; return 0;
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
int gpioCfgSocketPort(unsigned port) int gpioCfgSocketPort(unsigned port)
@ -8968,3 +9138,7 @@ int gpioCfgInternals(unsigned cfgWhat, int cfgVal)
return retVal; return retVal;
} }
/* include any user customisations */
#include "custom.cext"

View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#define PIGPIO_VERSION 25 #define PIGPIO_VERSION 26
/*TEXT /*TEXT
@ -351,8 +351,9 @@ uint32_t gpioOff;
uint32_t usDelay; uint32_t usDelay;
} gpioPulse_t; } gpioPulse_t;
#define WAVE_FLAG_READ 1 #define WAVE_FLAG_READ 1
#define WAVE_FLAG_TICK 2 #define WAVE_FLAG_TICK 2
#define WAVE_FLAG_COUNT 4
typedef struct typedef struct
{ {
@ -383,13 +384,13 @@ int clk_us; /* clock micros */
} rawSPI_t; } rawSPI_t;
typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */ typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */
unsigned long info; uint32_t info;
unsigned long src; uint32_t src;
unsigned long dst; uint32_t dst;
unsigned long length; uint32_t length;
unsigned long stride; uint32_t stride;
unsigned long next; uint32_t next;
unsigned long pad[2]; uint32_t pad[2];
} rawCbs_t; } rawCbs_t;
typedef void (*gpioAlertFunc_t) (int gpio, typedef void (*gpioAlertFunc_t) (int gpio,
@ -479,8 +480,8 @@ typedef void *(gpioThreadFunc_t) (void *);
/* hardware PWM */ /* hardware PWM */
#define PI_HW_PWM_MIN_FREQ 5 #define PI_HW_PWM_MIN_FREQ 5
#define PI_HW_PWM_MAX_FREQ 250000 #define PI_HW_PWM_MAX_FREQ 50000
#define PI_HW_PWM_RANGE 1000 #define PI_HW_PWM_RANGE 5000
/* hardware clock */ /* hardware clock */
@ -2083,8 +2084,8 @@ handle: >=0, as returned by a call to [*spiOpen*]
count: the number of bytes to read count: the number of bytes to read
. . . .
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or Returns the number of bytes transferred if OK, otherwise
PI_SPI_XFER_FAILED. PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
D*/ D*/
@ -2100,8 +2101,8 @@ handle: >=0, as returned by a call to [*spiOpen*]
count: the number of bytes to write count: the number of bytes to write
. . . .
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or Returns the number of bytes transferred if OK, otherwise
PI_SPI_XFER_FAILED. PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
D*/ D*/
/*F*/ /*F*/
@ -2118,8 +2119,8 @@ handle: >=0, as returned by a call to [*spiOpen*]
count: the number of bytes to transfer count: the number of bytes to transfer
. . . .
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or Returns the number of bytes transferred if OK, otherwise
PI_SPI_XFER_FAILED. PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
D*/ D*/
@ -3052,6 +3053,48 @@ Or in PI_DISABLE_SOCK_IF to disable the socket interface.
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*/ /*F*/
int gpioCfgInternals(unsigned cfgWhat, int cfgVal); int gpioCfgInternals(unsigned cfgWhat, int cfgVal);
/*D /*D
@ -3686,7 +3729,7 @@ PWMduty::0-1000
The hardware PWM dutycycle. The hardware PWM dutycycle.
. . . .
#define PI_HW_PWM_RANGE 1000 #define PI_HW_PWM_RANGE 5000
. . . .
PWMfreq::5-250K PWMfreq::5-250K
@ -3694,7 +3737,7 @@ The hardware PWM frequency.
. . . .
#define PI_HW_PWM_MIN_FREQ 5 #define PI_HW_PWM_MIN_FREQ 5
#define PI_HW_PWM_MAX_FREQ 250000 #define PI_HW_PWM_MAX_FREQ 50000
. . . .
range::25-40000 range::25-40000
@ -4013,6 +4056,9 @@ PARAMS*/
#define PI_CMD_HC 85 #define PI_CMD_HC 85
#define PI_CMD_HP 86 #define PI_CMD_HP 86
#define PI_CMD_CF1 87
#define PI_CMD_CF2 88
#define PI_CMD_NOIB 99 #define PI_CMD_NOIB 99
/*DEF_E*/ /*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_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_HCLK_GPIO -94 // gpio has no hardware clock
#define PI_NOT_HPWM_GPIO -95 // gpio has no hardware PWM #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_FREQ -96 // hardware PWM frequency not 5-50K
#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-1000 #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_FREQ -98 // hardware clock frequency not 4689-25M
#define PI_BAD_HCLK_PASS -99 // need password to use hardware clock 1 #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_HPWM_ILLEGAL -100 // illegal, PWM in use for main clock
#define PI_BAD_DATABITS -101 // serial data bits not 1-32 #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_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*/ /*DEF_E*/

View File

@ -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 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 Utility
get_current_tick Get current tick (microseconds) get_current_tick Get current tick (microseconds)
@ -402,6 +407,9 @@ _PI_CMD_GPW =84
_PI_CMD_HC =85 _PI_CMD_HC =85
_PI_CMD_HP =86 _PI_CMD_HP =86
_PI_CMD_CF1 =87
_PI_CMD_CF2 =88
_PI_CMD_NOIB= 99 _PI_CMD_NOIB= 99
# pigpio error numbers # pigpio error numbers
@ -606,8 +614,8 @@ _errors=[
[PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"], [PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"],
[PI_NOT_HCLK_GPIO , "gpio has no hardware clock"], [PI_NOT_HCLK_GPIO , "gpio has no hardware clock"],
[PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"], [PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"],
[PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-250K"], [PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-50K"],
[PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1000"], [PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-5000"],
[PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"], [PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"],
[PI_BAD_HCLK_PASS , "need password to use hardware clock 1"], [PI_BAD_HCLK_PASS , "need password to use hardware clock 1"],
[PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"], [PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"],
@ -1486,8 +1494,8 @@ class pi():
pigpio daemon is started (option -t). pigpio daemon is started (option -t).
gpio:= see descripton gpio:= see descripton
PWMfreq:= 0 (off) or 5-250K PWMfreq:= 0 (off) or 5-50K
PWMduty:= 0 (off) to 1000 (fully on). PWMduty:= 0 (off) to 5000 (fully on).
Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO,
PI_NOT_HPWM_GPIO, PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ. 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 # pigpio message format
@ -2953,6 +2961,81 @@ class pi():
""" """
return _u2i(_pigpio_command(self.sl, _PI_CMD_SLRC, user_gpio, 0)) 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): def callback(self, user_gpio, edge=RISING_EDGE, func=None):
""" """
Calls a user supplied function (a callback) whenever the Calls a user supplied function (a callback) whenever the
@ -3043,9 +3126,6 @@ class pi():
self.sl = _socklock() self.sl = _socklock()
self._notify = None self._notify = None
self._host = ''
self._port = 8888
self._host = host self._host = host
self._port = int(port) self._port = int(port)

View File

@ -1313,6 +1313,58 @@ int serial_read(unsigned handle, char *buf, unsigned count)
int serial_data_available(unsigned handle) int serial_data_available(unsigned handle)
{return pigpio_command(gPigCommand, PI_CMD_SERDA, handle, 0, 1);} {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) int callback(unsigned user_gpio, unsigned edge, CBFunc_t f)
{return intCallback(user_gpio, edge, f, 0, 0);} {return intCallback(user_gpio, edge, f, 0, 0);}

View File

@ -248,6 +248,11 @@ serial_read Reads bytes from a serial device
serial_data_available Returns number of bytes ready to be read 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 UTILITIES
get_current_tick Get current tick (microseconds) get_current_tick Get current tick (microseconds)
@ -896,8 +901,8 @@ daemon is started (option -t).
. . . .
gpio: see descripton gpio: see descripton
PWMfreq: 0 (off) or 5-250K PWMfreq: 0 (off) or 5-50K
PWMduty: 0 (off) to 1000 (fully on). PWMduty: 0 (off) to 5000 (fully on).
. . . .
Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, 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. count: the number of bytes to read.
. . . .
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or Returns the number of bytes transferred if OK, otherwise
PI_SPI_XFER_FAILED. PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
D*/ D*/
/*F*/ /*F*/
@ -1820,8 +1825,8 @@ handle: >=0, as returned by a call to [*spi_open*].
count: the number of bytes to write. count: the number of bytes to write.
. . . .
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or Returns the number of bytes transferred if OK, otherwise
PI_SPI_XFER_FAILED. PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
D*/ D*/
/*F*/ /*F*/
@ -1838,8 +1843,8 @@ handle: >=0, as returned by a call to [*spi_open*].
count: the number of bytes to transfer. count: the number of bytes to transfer.
. . . .
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or Returns the number of bytes transferred if OK, otherwise
PI_SPI_XFER_FAILED. PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
D*/ D*/
/*F*/ /*F*/
@ -1944,6 +1949,48 @@ Returns the number of bytes of data available (>=0) if OK,
otherwise PI_BAD_HANDLE. otherwise PI_BAD_HANDLE.
D*/ 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*/ /*F*/
int callback(unsigned user_gpio, unsigned edge, CBFunc_t f); int callback(unsigned user_gpio, unsigned edge, CBFunc_t f);
/*D /*D

5
pigs.c
View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/ */
/* /*
This version is for pigpio version 18+ This version is for pigpio version 26+
*/ */
#include <stdio.h> #include <stdio.h>
@ -141,7 +141,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd)
printf(cmdUsage); printf(cmdUsage);
break; 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); printf("%d", r);
if (r < 0) fatal("ERROR: %s", cmdErrStr(r)); if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
if (r > 0) if (r > 0)
@ -178,6 +178,7 @@ void get_extensions(int sock, int command, int res)
{ {
switch (command) switch (command)
{ {
case PI_CMD_CF2:
case PI_CMD_I2CPK: case PI_CMD_I2CPK:
case PI_CMD_I2CRD: case PI_CMD_I2CRD:
case PI_CMD_I2CRI: case PI_CMD_I2CRI:

4
x_pigs
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION=25 VERSION=26
GPIO=4 GPIO=4
@ -46,7 +46,7 @@ s=$(pigs bs2 0)
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h) 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) s=$(pigs hwver)
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi

6
x_pipe
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION=25 VERSION=26
GPIO=4 GPIO=4
@ -52,14 +52,14 @@ if [[ $s = 0 ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
echo "h" >/dev/pigpio echo "h" >/dev/pigpio
read -t 1 s </dev/pigout 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" then echo "HELP-a ok"
else echo "HELP-a fail ($s)" else echo "HELP-a fail ($s)"
fi fi
read -t 1 -N 9000 </dev/pigout # dump rest of help read -t 1 -N 9000 </dev/pigout # dump rest of help
echo "help" >/dev/pigpio echo "help" >/dev/pigpio
read -t 1 s </dev/pigout 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" then echo "HELP-b ok"
else echo "HELP-b fail ($s)" else echo "HELP-b fail ($s)"
fi fi