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