mirror of https://github.com/joan2937/pigpio
V26
This commit is contained in:
parent
84b06fca73
commit
624ecb6fb0
7
Makefile
7
Makefile
|
@ -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
305
command.c
|
@ -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...
|
||||||
|
|
|
@ -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
510
pigpio.c
|
@ -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"
|
||||||
|
|
||||||
|
|
97
pigpio.h
97
pigpio.h
|
@ -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*/
|
||||||
|
|
||||||
|
|
98
pigpio.py
98
pigpio.py
|
@ -234,6 +234,11 @@ serial_write_byte Writes a byte to a serial device
|
||||||
|
|
||||||
serial_data_available Returns number of bytes ready to be read
|
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)
|
||||||
|
|
||||||
|
|
52
pigpiod_if.c
52
pigpiod_if.c
|
@ -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);}
|
||||||
|
|
||||||
|
|
63
pigpiod_if.h
63
pigpiod_if.h
|
@ -248,6 +248,11 @@ serial_read Reads bytes from a serial device
|
||||||
|
|
||||||
serial_data_available Returns number of bytes ready to be read
|
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
5
pigs.c
|
@ -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
4
x_pigs
|
@ -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
6
x_pipe
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue